pax_global_header00006660000000000000000000000064135334220350014512gustar00rootroot0000000000000052 comment=14ea971be7e808b9c5099c7f404ed3cf341873c4 dlt-daemon-2.18.4/000077500000000000000000000000001353342203500136325ustar00rootroot00000000000000dlt-daemon-2.18.4/.gitignore000066400000000000000000000002271353342203500156230ustar00rootroot00000000000000Release/ Debug/ build/ automotive-dlt.spec automotive-dlt.pc config.h include/dlt/dlt_version.h .project .cproject .settings .idea/ cmake-build-debug/ dlt-daemon-2.18.4/.travis.yml000066400000000000000000000006521353342203500157460ustar00rootroot00000000000000language: c dist: xenial compiler: gcc script: - cmake -DWITH_DLT_TESTS=ON -DWITH_TESTSCRIPTS=ON -DWITH_DLT_UNIT_TESTS=ON -DWITH_SYSTEMD=ON -DWITH_SYSTEMD_JOURNAL=ON CMakeLists.txt - make - sudo make install - ./.travis/gtest_dlt_all.sh - ./src/tests/dlt-test-user addons: apt: packages: - cmake-data - cmake - libdbus-1-dev - build-essential - systemd - libsystemd-dev dlt-daemon-2.18.4/.travis/000077500000000000000000000000001353342203500152205ustar00rootroot00000000000000dlt-daemon-2.18.4/.travis/gtest_dlt_all.sh000077500000000000000000000032201353342203500203750ustar00rootroot00000000000000#!/bin/bash ################################################################################ # SPDX license identifier: MPL-2.0 # # Copyright (C) 2019, Advanced Driver Information Technology # This code is developed by Advanced Driver Information Technology. # Copyright of Advanced Driver Information Technology, Bosch and DENSO. # # This file is part of GENIVI Project DLT - Diagnostic Log and Trace. # # This Source Code Form is subject to the terms of the # Mozilla Public License (MPL), v. 2.0. # If a copy of the MPL was not distributed with this file, # You can obtain one at http://mozilla.org/MPL/2.0/. # # For further information see http://www.genivi.org/. ################################################################################ ################################################################################ #file : gtest_dlt_all.sh # #Description : Run all unit tests in Travis CI # #Author Name : Saya Sugiura ################################################################################ function gtest_run_test() { LOG="../.travis/$1.log" # Execute unit test ./$1 > $LOG # Check for result grep "FAILED TEST" $LOG if [ $? -eq 0 ] then cat $LOG exit 1 fi echo "$1 passed" } pushd tests > /dev/null gtest_run_test gtest_dlt_common gtest_run_test gtest_dlt_user gtest_run_test gtest_dlt_daemon_common gtest_run_test gtest_dlt_daemon_event_handler ./gtest_dlt_daemon_gateway.sh > /dev/null gtest_run_test gtest_dlt_daemon_gateway ./gtest_dlt_daemon_logstorage.sh > /dev/null gtest_run_test gtest_dlt_daemon_offline_log gtest_run_test dlt_env_ll_unit_test popd > /dev/null dlt-daemon-2.18.4/AUTHORS000066400000000000000000000010531353342203500147010ustar00rootroot00000000000000Copyright (C) 2015 BMW AG. Copying and distribution of this file, with or without modification, are permitted in any medium without royalty provided the copyright notice and this notice are preserved. Alexander Wenzel Christian Muck Mikko Rapeli Jeremiah C. Foster Stefan Seefeld Noor Ahsan Eckhard Diezel Mohammed AL Dardoun Lassi Marttala Simon Brandner dlt-daemon-2.18.4/CMakeLists.txt000066400000000000000000000257531353342203500164060ustar00rootroot00000000000000####### # SPDX license identifier: MPL-2.0 # # Copyright(C) 2011-2015, BMW AG # # This file is part of GENIVI Project DLT - Diagnostic Log and Trace. # # This Source Code Form is subject to the terms of the # Mozilla Public License(MPL), v. 2.0. # If a copy of the MPL was not distributed with this file, # You can obtain one at http://mozilla.org/MPL/2.0/. # # For further information see http://www.genivi.org/. ####### cmake_minimum_required(VERSION 2.8.5) project(automotive-dlt) mark_as_advanced(CMAKE_BACKWARDS_COMPATIBILITY) set(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS TRUE) include(GNUInstallDirs) # Set version parameters set(DLT_MAJOR_VERSION 2) set(DLT_MINOR_VERSION 18) set(DLT_PATCH_LEVEL 4) set(DLT_VERSION ${DLT_MAJOR_VERSION}.${DLT_MINOR_VERSION}.${DLT_PATCH_LEVEL}) set(DLT_VERSION_STATE STABLE) set(DLT_REVISION "") execute_process(COMMAND git describe --tags WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} OUTPUT_VARIABLE DLT_REVISION ERROR_VARIABLE GIT_ERROR OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_STRIP_TRAILING_WHITESPACE) if(DLT_REVISION MATCHES "^$") set(PRINT_REVISION "Git revision unavailable") else(DLT_REVISION MATCHES "") string(REPLACE "-" "_" DLT_REVISION ${DLT_REVISION}) set(PRINT_REVISION ${DLT_REVISION}) endif() # set default build type, if not defined by user if(NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING "Choose build type: Debug, Release, RelWithDebInfo, MinSizeRel." FORCE) message(STATUS "Build type not defined. Using default build type 'RelWithDebInfo'.") endif() # Set of indiviual options option(BUILD_SHARED_LIBS "Set to OFF to build static libraries" ON) option(WITH_SYSTEMD "Set to ON to create unit files and systemd check on dlt-daemon startup" OFF) option(WITH_SYSTEMD_WATCHDOG "Set to ON to use the systemd watchdog in dlt-daemon" OFF) option(WITH_SYSTEMD_JOURNAL "Set to ON to use the systemd journal in dlt-system" OFF) option(WITH_DOC "Set to ON to build documentation target" OFF) option(WITH_MAN "Set to ON to build man pages" OFF) option(WITH_CHECK_CONFIG_FILE "Set to ON to create a configure file of CheckIncludeFiles and CheckFunctionExists" OFF) option(WITH_TESTSCRIPTS "Set to ON to run CMakeLists.txt in testscripts" OFF) option(WITH_GPROF "Set -pg to compile flags" OFF) option(WITH_DLTTEST "Set to ON to build with modifications to test User-Daemon communication with corrupt messages" OFF) option(WITH_DLT_SHM_ENABLE "EXPERIMENTAL! Set to ON to use shared memory as IPC. EXPERIMENTAL!" OFF) option(WITH_DLT_ADAPTOR "Set to ON to build src/adaptor binaries" OFF) option(WITH_DLT_CONSOLE "Set to ON to build src/console binaries" ON) option(WITH_DLT_EXAMPLES "Set to ON to build src/examples binaries" ON) option(WITH_DLT_SYSTEM "Set to ON to build src/system binaries" OFF) option(WITH_DLT_DBUS "Set to ON to build src/dbus binaries" OFF) option(WITH_DLT_TESTS "Set to ON to build src/test binaries" ON) option(WITH_DLT_UNIT_TESTS "Set to ON to build gtest framework and tests/binaries" OFF) set(DLT_IPC "FIFO" CACHE STRING "UNIX_SOCKET,FIFO") set(DLT_USER "genivi" CACHE STRING "Set user for process not run as root") option(WITH_DLT_PKGCONFIG "Set to ON to generate pkgconfig .pc files" ON) option(WITH_DLT_CXX11_EXT "Set to ON to build C++11 extensions" OFF) option(WITH_DLT_COREDUMPHANDLER "EXPERIMENTAL! Set to ON to build src/core_dump_handler binaries. EXPERIMENTAL" OFF) option(WITH_DLT_LOGSTORAGE_CTRL_UDEV "PROTOTYPE! Set to ON to build logstorage control application with udev support" OFF) option(WITH_DLT_USE_IPv6 "Set to ON for IPv6 support" ON) option(WITH_DLT_KPI "Set to ON to build src/kpi binaries" OFF) option(WITH_DLT_FATAL_LOG_TRAP "Set to ON to enable DLT_LOG_FATAL trap(trigger segv inside dlt-user library)" OFF) option(WITH_UDP_CONNECTION "Set to ON to enable dlt UDP multicast SUPPORT" ON) # RPM settings set(GENIVI_RPM_RELEASE "1") # ${DLT_REVISION}") set(LICENSE "Mozilla Public License Version 2.0") # Build, project and include settings find_package(Threads REQUIRED) if(WITH_DLT_SYSTEM) set(ZLIB_LIBRARY "-lz") find_package(ZLIB REQUIRED) else() set(ZLIB_LIBRARY "") endif() if(WITH_DLT_DBUS) find_package(PkgConfig REQUIRED) pkg_check_modules(DBUS REQUIRED dbus-1) endif() include_directories( ${PROJECT_SOURCE_DIR} ${PROJECT_SOURCE_DIR}/include/dlt ${PROJECT_BINARY_DIR}/include/dlt ${PROJECT_SOURCE_DIR}/src/shared ${PROJECT_SOURCE_DIR}/src/core_dump_handler ${PROJECT_SOURCE_DIR}/src/offlinelogstorage ${PROJECT_SOURCE_DIR}/src/lib ${PROJECT_SOURCE_DIR}/src/daemon ${PROJECT_SOURCE_DIR}/src/console ${PROJECT_SOURCE_DIR}/src/gateway ${PROJECT_SOURCE_DIR}/systemd/3rdparty ) add_definitions(-D_GNU_SOURCE) if(DLT_IPC STREQUAL "UNIX_SOCKET") add_definitions(-DDLT_USE_UNIX_SOCKET_IPC) endif() if(NOT DLT_USER_IPC_PATH) set(DLT_USER_IPC_PATH "/tmp") endif() add_definitions(-DDLT_USER_IPC_PATH="${DLT_USER_IPC_PATH}") if(WITH_DLTTEST) add_definitions(-DDLT_TEST_ENABLE) endif() if(WITH_DLT_UNIT_TESTS) add_definitions(-DDLT_UNIT_TESTS) endif() if(WITH_DLT_SHM_ENABLE) add_definitions(-DDLT_SHM_ENABLE) endif() if(WITH_DLT_USE_IPv6) add_definitions(-DDLT_USE_IPv6) endif() if(WITH_GPROF) add_compile_options(-pg) endif() add_compile_options( $<$:-std=gnu99> $<$:-std=gnu++11> -Wall -Wextra # -pedantic -Wno-variadic-macros -Wno-strict-aliasing ) if(WITH_DOC STREQUAL "OFF") set(PACKAGE_DOC "#") else() set(PACKAGE_DOC "") endif() if(WITH_DLT_PKGCONFIG) configure_file(${PROJECT_SOURCE_DIR}/${PROJECT_NAME}.spec.in ${PROJECT_BINARY_DIR}/${PROJECT_NAME}.spec) configure_file(${PROJECT_SOURCE_DIR}/${PROJECT_NAME}.pc.in ${PROJECT_BINARY_DIR}/${PROJECT_NAME}.pc @ONLY) install(FILES ${PROJECT_BINARY_DIR}/${PROJECT_NAME}.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig COMPONENT devel) endif() if(WITH_DLT_CXX11_EXT AND WITH_DLT_PKGCONFIG) configure_file(${PROJECT_SOURCE_DIR}/${PROJECT_NAME}-c++.pc.in ${PROJECT_BINARY_DIR}/${PROJECT_NAME}-c++.pc @ONLY) install(FILES ${PROJECT_BINARY_DIR}/${PROJECT_NAME}-c++.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig COMPONENT devel) endif() if(CMAKE_INSTALL_PREFIX STREQUAL "/usr") set(CONFIGURATION_FILES_DIR "/etc") else() set(CONFIGURATION_FILES_DIR "${CMAKE_INSTALL_PREFIX}/etc") endif() add_definitions(-DCONFIGURATION_FILES_DIR="${CONFIGURATION_FILES_DIR}") add_subdirectory(cmake) if(WITH_SYSTEMD OR WITH_SYSTEMD_WATCHDOG OR WITH_SYSTEMD_JOURNAL) find_package(PkgConfig REQUIRED) execute_process(COMMAND pkg-config --modversion systemd OUTPUT_VARIABLE SYSTEMD_VERSION) string(REPLACE "\n" "" SYSTEMD_VERSION ${SYSTEMD_VERSION}) if(WITH_SYSTEMD) add_definitions(-DDLT_SYSTEMD_ENABLE) endif() if(WITH_SYSTEMD_WATCHDOG) add_definitions(-DDLT_SYSTEMD_WATCHDOG_ENABLE) endif() if(WITH_SYSTEMD_JOURNAL) add_definitions(-DDLT_SYSTEMD_JOURNAL_ENABLE) endif() set(systemd_SRCS ${PROJECT_SOURCE_DIR}/systemd/3rdparty/sd-daemon.c) set(SYSTEMD_UNITDIR "${CMAKE_INSTALL_PREFIX}/lib/systemd/system" CACHE PATH "Set directory to install systemd unit files") add_subdirectory(systemd) endif() if(WITH_DLT_LOGSTORAGE_CTRL_UDEV) add_definitions(-DDLT_LOGSTORAGE_CTRL_UDEV_ENABLE) endif() if(WITH_DLT_FATAL_LOG_TRAP) add_definitions(-DDLT_FATAL_LOG_RESET_ENABLE) endif() add_subdirectory(doc) add_subdirectory(src) add_subdirectory(include/dlt) add_subdirectory(testscripts) if(WITH_DLT_UNIT_TESTS) add_subdirectory( gtest-1.7.0 ) add_subdirectory(tests) endif() message(STATUS) message(STATUS "-------------------------------------------------------------------------------") message(STATUS "Build for Version ${DLT_VERSION} build ${DLT_REVISION} version state ${DLT_VERSION_STATE}") message(STATUS "WITH_SYSTEMD = ${WITH_SYSTEMD}") message(STATUS "WITH_SYSTEMD_WATCHDOG = ${WITH_SYSTEMD_WATCHDOG}") message(STATUS "WITH_SYSTEMD_JOURNAL = ${WITH_SYSTEMD_JOURNAL}") message(STATUS "WITH_DOC = ${WITH_DOC}") message(STATUS "WITH_MAN = ${WITH_MAN}") message(STATUS "WITH_DLT_ADAPTOR = ${WITH_DLT_ADAPTOR}") message(STATUS "WITH_DLT_CONSOLE = ${WITH_DLT_CONSOLE}") message(STATUS "WITH_DLT_EXAMPLES = ${WITH_DLT_EXAMPLES}") message(STATUS "WITH_DLT_SYSTEM = ${WITH_DLT_SYSTEM}") message(STATUS "WITH_DLT_DBUS = ${WITH_DLT_DBUS}") message(STATUS "WITH_DLT_TESTS = ${WITH_DLT_TESTS}") message(STATUS "WITH_DLT_UNIT_TESTS = ${WITH_DLT_UNIT_TESTS}") message(STATUS "WITH_DLT_SHM_ENABLE = ${WITH_DLT_SHM_ENABLE}") message(STATUS "WITH_DLTTEST = ${WITH_DLTTEST}") message(STATUS "WITH_DLT_PKGCONFIG = ${WITH_DLT_PKGCONFIG}") message(STATUS "WITH_DLT_CXX11_EXT = ${WITH_DLT_CXX11_EXT}") message(STATUS "WITH_DLT_COREDUMPHANDLER = ${WITH_DLT_COREDUMPHANDLER}") message(STATUS "WITH_DLT_KPI = ${WITH_DLT_KPI}") message(STATUS "WITH_DLT_FATAL_LOG_TRAP = ${WITH_DLT_FATAL_LOG_TRAP}") message(STATUS "WITH_CHECK_CONFIG_FILE = ${WITH_CHECK_CONFIG_FILE}") message(STATUS "WITH_TESTSCRIPTS = ${WITH_TESTSCRIPTS}") message(STATUS "WITH_GPROF = ${WITH_GPROF}") message(STATUS "WITH_DLT_USE_IPv6 = ${WITH_DLT_USE_IPv6}") message(STATUS "DLT_USER = ${DLT_USER}") message(STATUS "BUILD_SHARED_LIBS = ${BUILD_SHARED_LIBS}") message(STATUS "TARGET_CPU_NAME = ${TARGET_CPU_NAME}") if(WITH_SYSTEMD OR WITH_SYSTEMD_WATCHDOG OR WITH_SYSTEMD_JOURNAL) message(STATUS "SYSTEMD_VERSION = ${SYSTEMD_VERSION}") message(STATUS "SYSTEMD_UNITDIR = ${SYSTEMD_UNITDIR}") endif() message(STATUS "CMAKE_INSTALL_PREFIX = ${CMAKE_INSTALL_PREFIX}") message(STATUS "CMAKE_BUILD_TYPE = ${CMAKE_BUILD_TYPE}") message(STATUS "CMAKE_HOST_SYSTEM_PROCESSOR = ${CMAKE_HOST_SYSTEM_PROCESSOR}") message(STATUS "CMAKE_SYSTEM_PROCESSOR = ${CMAKE_SYSTEM_PROCESSOR}") message(STATUS "WITH_DLT_LOGSTORAGE_CTRL_UDEV = ${WITH_DLT_LOGSTORAGE_CTRL_UDEV}") message(STATUS "DLT_IPC = ${DLT_IPC}(Path: ${DLT_USER_IPC_PATH})") message(STATUS "WITH_UDP_CONNECTION = ${WITH_UDP_CONNECTION}") message(STATUS "Change a value with: cmake -D=") message(STATUS "-------------------------------------------------------------------------------") message(STATUS) dlt-daemon-2.18.4/COPYING000066400000000000000000000006441353342203500146710ustar00rootroot00000000000000 # SPDX license identifier: MPL-2.0 # # Copyright (C) 2011-2015, BMW AG # # This file is part of GENIVI Project DLT - Diagnostic Log and Trace. # # This Source Code Form is subject to the terms of the # Mozilla Public License (MPL), v. 2.0. # If a copy of the MPL was not distributed with this file, # You can obtain one at http://mozilla.org/MPL/2.0/. # # For further information see http://www.genivi.org/. dlt-daemon-2.18.4/LICENSE000066400000000000000000000405261353342203500146460ustar00rootroot00000000000000Mozilla Public License Version 2.0 ================================== 1. Definitions -------------- 1.1. "Contributor" means each individual or legal entity that creates, contributes to the creation of, or owns Covered Software. 1.2. "Contributor Version" means the combination of the Contributions of others (if any) used by a Contributor and that particular Contributor's Contribution. 1.3. "Contribution" means Covered Software of a particular Contributor. 1.4. "Covered Software" means Source Code Form to which the initial Contributor has attached the notice in Exhibit A, the Executable Form of such Source Code Form, and Modifications of such Source Code Form, in each case including portions thereof. 1.5. "Incompatible With Secondary Licenses" means (a) that the initial Contributor has attached the notice described in Exhibit B to the Covered Software; or (b) that the Covered Software was made available under the terms of version 1.1 or earlier of the License, but not also under the terms of a Secondary License. 1.6. "Executable Form" means any form of the work other than Source Code Form. 1.7. "Larger Work" means a work that combines Covered Software with other material, in a separate file or files, that is not Covered Software. 1.8. "License" means this document. 1.9. "Licensable" means having the right to grant, to the maximum extent possible, whether at the time of the initial grant or subsequently, any and all of the rights conveyed by this License. 1.10. "Modifications" means any of the following: (a) any file in Source Code Form that results from an addition to, deletion from, or modification of the contents of Covered Software; or (b) any new file in Source Code Form that contains any Covered Software. 1.11. "Patent Claims" of a Contributor means any patent claim(s), including without limitation, method, process, and apparatus claims, in any patent Licensable by such Contributor that would be infringed, but for the grant of the License, by the making, using, selling, offering for sale, having made, import, or transfer of either its Contributions or its Contributor Version. 1.12. "Secondary License" means either the GNU General Public License, Version 2.0, the GNU Lesser General Public License, Version 2.1, the GNU Affero General Public License, Version 3.0, or any later versions of those licenses. 1.13. "Source Code Form" means the form of the work preferred for making modifications. 1.14. "You" (or "Your") means an individual or a legal entity exercising rights under this License. For legal entities, "You" includes any entity that controls, is controlled by, or is under common control with You. For purposes of this definition, "control" means (a) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (b) ownership of more than fifty percent (50%) of the outstanding shares or beneficial ownership of such entity. 2. License Grants and Conditions -------------------------------- 2.1. Grants Each Contributor hereby grants You a world-wide, royalty-free, non-exclusive license: (a) under intellectual property rights (other than patent or trademark) Licensable by such Contributor to use, reproduce, make available, modify, display, perform, distribute, and otherwise exploit its Contributions, either on an unmodified basis, with Modifications, or as part of a Larger Work; and (b) under Patent Claims of such Contributor to make, use, sell, offer for sale, have made, import, and otherwise transfer either its Contributions or its Contributor Version. 2.2. Effective Date The licenses granted in Section 2.1 with respect to any Contribution become effective for each Contribution on the date the Contributor first distributes such Contribution. 2.3. Limitations on Grant Scope The licenses granted in this Section 2 are the only rights granted under this License. No additional rights or licenses will be implied from the distribution or licensing of Covered Software under this License. Notwithstanding Section 2.1(b) above, no patent license is granted by a Contributor: (a) for any code that a Contributor has removed from Covered Software; or (b) for infringements caused by: (i) Your and any other third party's modifications of Covered Software, or (ii) the combination of its Contributions with other software (except as part of its Contributor Version); or (c) under Patent Claims infringed by Covered Software in the absence of its Contributions. This License does not grant any rights in the trademarks, service marks, or logos of any Contributor (except as may be necessary to comply with the notice requirements in Section 3.4). 2.4. Subsequent Licenses No Contributor makes additional grants as a result of Your choice to distribute the Covered Software under a subsequent version of this License (see Section 10.2) or under the terms of a Secondary License (if permitted under the terms of Section 3.3). 2.5. Representation Each Contributor represents that the Contributor believes its Contributions are its original creation(s) or it has sufficient rights to grant the rights to its Contributions conveyed by this License. 2.6. Fair Use This License is not intended to limit any rights You have under applicable copyright doctrines of fair use, fair dealing, or other equivalents. 2.7. Conditions Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in Section 2.1. 3. Responsibilities ------------------- 3.1. Distribution of Source Form All distribution of Covered Software in Source Code Form, including any Modifications that You create or to which You contribute, must be under the terms of this License. You must inform recipients that the Source Code Form of the Covered Software is governed by the terms of this License, and how they can obtain a copy of this License. You may not attempt to alter or restrict the recipients' rights in the Source Code Form. 3.2. Distribution of Executable Form If You distribute Covered Software in Executable Form then: (a) such Covered Software must also be made available in Source Code Form, as described in Section 3.1, and You must inform recipients of the Executable Form how they can obtain a copy of such Source Code Form by reasonable means in a timely manner, at a charge no more than the cost of distribution to the recipient; and (b) You may distribute such Executable Form under the terms of this License, or sublicense it under different terms, provided that the license for the Executable Form does not attempt to limit or alter the recipients' rights in the Source Code Form under this License. 3.3. Distribution of a Larger Work You may create and distribute a Larger Work under terms of Your choice, provided that You also comply with the requirements of this License for the Covered Software. If the Larger Work is a combination of Covered Software with a work governed by one or more Secondary Licenses, and the Covered Software is not Incompatible With Secondary Licenses, this License permits You to additionally distribute such Covered Software under the terms of such Secondary License(s), so that the recipient of the Larger Work may, at their option, further distribute the Covered Software under the terms of either this License or such Secondary License(s). 3.4. Notices You may not remove or alter the substance of any license notices (including copyright notices, patent notices, disclaimers of warranty, or limitations of liability) contained within the Source Code Form of the Covered Software, except that You may alter any license notices to the extent required to remedy known factual inaccuracies. 3.5. Application of Additional Terms You may choose to offer, and to charge a fee for, warranty, support, indemnity or liability obligations to one or more recipients of Covered Software. However, You may do so only on Your own behalf, and not on behalf of any Contributor. You must make it absolutely clear that any such warranty, support, indemnity, or liability obligation is offered by You alone, and You hereby agree to indemnify every Contributor for any liability incurred by such Contributor as a result of warranty, support, indemnity or liability terms You offer. You may include additional disclaimers of warranty and limitations of liability specific to any jurisdiction. 4. Inability to Comply Due to Statute or Regulation --------------------------------------------------- If it is impossible for You to comply with any of the terms of this License with respect to some or all of the Covered Software due to statute, judicial order, or regulation then You must: (a) comply with the terms of this License to the maximum extent possible; and (b) describe the limitations and the code they affect. Such description must be placed in a text file included with all distributions of the Covered Software under this License. Except to the extent prohibited by statute or regulation, such description must be sufficiently detailed for a recipient of ordinary skill to be able to understand it. 5. Termination -------------- 5.1. The rights granted under this License will terminate automatically if You fail to comply with any of its terms. However, if You become compliant, then the rights granted under this License from a particular Contributor are reinstated (a) provisionally, unless and until such Contributor explicitly and finally terminates Your grants, and (b) on an ongoing basis, if such Contributor fails to notify You of the non-compliance by some reasonable means prior to 60 days after You have come back into compliance. Moreover, Your grants from a particular Contributor are reinstated on an ongoing basis if such Contributor notifies You of the non-compliance by some reasonable means, this is the first time You have received notice of non-compliance with this License from such Contributor, and You become compliant prior to 30 days after Your receipt of the notice. 5.2. If You initiate litigation against any entity by asserting a patent infringement claim (excluding declaratory judgment actions, counter-claims, and cross-claims) alleging that a Contributor Version directly or indirectly infringes any patent, then the rights granted to You by any and all Contributors for the Covered Software under Section 2.1 of this License shall terminate. 5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user license agreements (excluding distributors and resellers) which have been validly granted by You or Your distributors under this License prior to termination shall survive termination. ************************************************************************ * * * 6. Disclaimer of Warranty * * ------------------------- * * * * Covered Software is provided under this License on an "as is" * * basis, without warranty of any kind, either expressed, implied, or * * statutory, including, without limitation, warranties that the * * Covered Software is free of defects, merchantable, fit for a * * particular purpose or non-infringing. The entire risk as to the * * quality and performance of the Covered Software is with You. * * Should any Covered Software prove defective in any respect, You * * (not any Contributor) assume the cost of any necessary servicing, * * repair, or correction. This disclaimer of warranty constitutes an * * essential part of this License. No use of any Covered Software is * * authorized under this License except under this disclaimer. * * * ************************************************************************ ************************************************************************ * * * 7. Limitation of Liability * * -------------------------- * * * * Under no circumstances and under no legal theory, whether tort * * (including negligence), contract, or otherwise, shall any * * Contributor, or anyone who distributes Covered Software as * * permitted above, be liable to You for any direct, indirect, * * special, incidental, or consequential damages of any character * * including, without limitation, damages for lost profits, loss of * * goodwill, work stoppage, computer failure or malfunction, or any * * and all other commercial damages or losses, even if such party * * shall have been informed of the possibility of such damages. This * * limitation of liability shall not apply to liability for death or * * personal injury resulting from such party's negligence to the * * extent applicable law prohibits such limitation. Some * * jurisdictions do not allow the exclusion or limitation of * * incidental or consequential damages, so this exclusion and * * limitation may not apply to You. * * * ************************************************************************ 8. Litigation ------------- Any litigation relating to this License may be brought only in the courts of a jurisdiction where the defendant maintains its principal place of business and such litigation shall be governed by laws of that jurisdiction, without reference to its conflict-of-law provisions. Nothing in this Section shall prevent a party's ability to bring cross-claims or counter-claims. 9. Miscellaneous ---------------- This License represents the complete agreement concerning the subject matter hereof. If any provision of this License is held to be unenforceable, such provision shall be reformed only to the extent necessary to make it enforceable. Any law or regulation which provides that the language of a contract shall be construed against the drafter shall not be used to construe this License against a Contributor. 10. Versions of the License --------------------------- 10.1. New Versions Mozilla Foundation is the license steward. Except as provided in Section 10.3, no one other than the license steward has the right to modify or publish new versions of this License. Each version will be given a distinguishing version number. 10.2. Effect of New Versions You may distribute the Covered Software under the terms of the version of the License under which You originally received the Covered Software, or under the terms of any subsequent version published by the license steward. 10.3. Modified Versions If you create software not governed by this License, and you want to create a new license for such software, you may create and use a modified version of this License if you rename the license and remove any references to the name of the license steward (except to note that such modified license differs from this License). 10.4. Distributing Source Code Form that is Incompatible With Secondary Licenses If You choose to distribute Source Code Form that is Incompatible With Secondary Licenses under the terms of this version of the License, the notice described in Exhibit B of this License must be attached. Exhibit A - Source Code Form License Notice ------------------------------------------- This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. If it is not possible or desirable to put the notice in a particular file, then You may include the notice in a location (such as a LICENSE file in a relevant directory) where a recipient would be likely to look for such a notice. You may add additional accurate notices of copyright ownership. Exhibit B - "Incompatible With Secondary Licenses" Notice --------------------------------------------------------- This Source Code Form is "Incompatible With Secondary Licenses", as defined by the Mozilla Public License, v. 2.0. dlt-daemon-2.18.4/README.md000066400000000000000000000202631353342203500151140ustar00rootroot00000000000000# Diagnostic Log and Trace Build and Test status: [![build and test status](https://travis-ci.org/GENIVI/dlt-daemon.svg?branch=master)](https://travis-ci.org/GENIVI/dlt-daemon) Alerts: [![Total alerts](https://img.shields.io/lgtm/alerts/g/GENIVI/dlt-daemon.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/GENIVI/dlt-daemon/alerts/) Code quality: [![Language grade: C/C++](https://img.shields.io/lgtm/grade/cpp/g/GENIVI/dlt-daemon.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/GENIVI/dlt-daemon/context:cpp) ## Overview This component provides a log and trace interface, based on the standardised protocol specified in the AUTOSAR standard 4.0 DLT. This software can be used by GENIVI components and other applications as logging framework. DLT basically consists of 3 components: - **DLT Library**: Enables DLT logging for DLT user applications and temporary storage of log messages if daemon isn't available. - **DLT Daemon**: Receiving log messages from DLT user applications and temporary storage of log messages if client isn't available. Transmit log messages to DLT Client and response to control messages. - **DLT Client**: Receiving and storing log messages from DLT Daemon into one single trace file and sending control message ![alt text](doc/images/dlt_overview.png "DLT Overview") Furthermore, the repository contains several adaptors, console utilities as well as test applications. ## Build and install The following packages need to be installed in order to be able to build and install DLT daemon: - cmake - zlib - dbus On Ubuntu those dependencies can be installed with the following command: `sudo apt-get install cmake zlib1g-dev libdbus-glib-1-dev` To build and install the DLT daemon, follow these steps: ```bash mkdir build cd build cmake .. make optional: sudo make install optional: sudo ldconfig ``` ### Configuration #### General Options Option | Value | Comment :--- | :--- | :--- BUILD\_SHARED\_LIBS | ON | Set to OFF to build static libraries DLT\_IPC |"FIFO" | Set to either "UNIX\_SOCKET" or "FIFO" WITH\_DLT\_USE\_IPv6 | ON | Set to ON for IPv6 support WITH\_DLT\_EXAMPLES | ON | Set to ON to build src/examples binaries DLT\_USER | genivi | Set user for process not run as root WITH\_CHECK\_CONFIG\_FILE | OFF | Set to ON to create a configure file of CheckIncludeFiles and CheckFunctionExists CMAKE\_INSTALL\_PREFIX | /usr/local CMAKE\_BUILD\_TYPE | RelWithDebInfo WITH\_UDP\_CONNECTION | ON | Set to ON to enable dlt UDP multicast SUPPORT #### Command Line Tool Options Option | Value | Comment :--- | :--- | :--- WITH\_DLT\_ADAPTOR | OFF | Set to ON to build src/adaptor binaries WITH\_DLT\_CONSOLE | ON | Set to ON to build src/console binaries WITH\_DLT\_SYSTEM | OFF | Set to ON to build src/system binaries WITH\_DLT\_LOGSTORAGE\_CTRL\_UDEV | OFF | PROTOTYPE! Set to ON to build WITH\_DLT\_KPI | OFF | Set to ON to build src/kpi binaries #### Linux OS Integration Options Option | Value | Comment :--- | :--- | :--- WITH\_SYSTEMD | OFF | Set to ON to run CMakeLists.txt in systemd WITH\_SYSTEMD\_WATCHDOG | OFF | Set to ON to use the systemd watchdog in dlt-daemon WITH\_SYSTEMD\_JOURNAL | OFF | Set to ON to use the systemd journal in dlt-system WITH\_DLT\_DBUS | OFF | Set to ON to build src/dbus binaries #### Documentation Options Option | Value | Comment :--- | :--- | :--- WITH\_DOC | OFF | Set to ON to build documentation target WITH\_MAN | OFF | Set to OFF to skip building of man pages #### Test Options Option | Value | Comment :--- | :--- | :--- WITH\_TESTSCRIPTS | OFF | Set to ON to run CMakeLists.txt in test scripts WITH\_DLT\_TESTS | ON | Set to ON to build src/test binaries WITH\_DLTTEST | OFF | Set to ON to build with modifications to test User-Daemon communication with corrupt messages WITH\_DLT\_UNIT\_TESTS | OFF | Set to ON to build unit test binaries WITH\_GPROF | OFF | Set \-pg to compile flag #### Experimental Features Options Option | Value | Comment :--- | :--- | :--- WITH\_DLT\_SHM\_ENABLE | OFF | Set to OFF to use FIFO as IPC from user to daemon WITH\_DLT\_CXX11\_EXT | OFF | Set to ON to build C++11 extensions WITH\_DLT\_COREDUMPHANDLER | OFF | EXPERIMENTAL! Set to ON to build src/core\_dump\_handler binaries. EXPERIMENTAL In order to change these options, you can modify these values with cmake, do the appropriate changes in CmakeList.txt or via the commandline for cmake Change a value with: cmake -D\=\, E.g. ```bash cmake .. -DWITH_SYSTEMD=ON -DWITH_SYSTEMD_JOURNAL=ON -DCMAKE_INSTALL_PREFIX=/usr ``` ## Documentation Specific documentation can be found in the following files: - [ReleaseNotes](ReleaseNotes.md) - [Glossary](doc/dlt_glossary.md) - [For Developers](doc/dlt_for_developers.md) - [Logstorage](doc/dlt_offline_logstorage.md) - [MultiNode](doc/dlt_multinode.md) - [Extended Network Trace](doc/dlt_extended_network_trace.md) - [DLT Filetransfer](doc/dlt_filetransfer.md) - [DLT KPI](doc/dlt_kpi.md) - [DLT Core Dump Handler](/doc/dlt_cdh.md) All text based documentation will be replaced with by Markdown-based documentation for convinient access. Old documentation (not maintained - will be removed in future releases): - DLT Design Specification: doc/dlt\_design\_specification.txt ### API Documentation The API documentation is generated with _doxygen_. ```bash mkdir build cd build cmake -DWITH_DOC=ON .. make doc ``` ### Manpages - [dlt-daemon(1)](doc/dlt-daemon.1.md) - [dlt.conf(5)](doc/dlt.conf.5.md) - [dlt-system(1)](doc/dlt-system.1.md) - [dlt-system.conf(5)](doc/dlt-system.conf.5.md) - [dlt-convert(1)](doc/dlt-convert.1.md) - [dlt-sortbytimestamp(1)](doc/dlt-sortbytimestamp.1.md) - [dlt-receive(1)](doc/dlt-receive.1.md) - [dlt-control(1)](doc/dlt-control.1.md) - [dlt-logstorage-ctrl(1)](doc/dlt-logstorage-ctrl.1.md) - [dlt-passive-node-ctrl(1)](doc/dlt-passive-node-ctrl.1.md) - [dlt-adaptor-stdin(1)](doc/dlt-adaptor-stdin.1.md) - [dlt-adaptor-udp(1)](doc/dlt-adaptor-udp.1.md) The man pages are generated with *pandoc*. If the man pages are changed the following command must be executed. ```bash mkdir build cd build cmake -DWITH_MAN=ON .. make generate_man ``` The generated man pages overwrite the existing ones. ## Contribution Start working, best practice is to commit smaller, compilable pieces during the work that makes it easier to handle later on. If you want to commit your changes, create a [Pull Request](https://github.com/genivi/dlt-daemon/pulls) in Github. ### Coding Rules Before contributing code, run uncrustify to harmonize code style. Configuration: util/uncrustify.cfg uncrustify version: 0.68\_f ## Known issues List of open issues can be found on [Github](https://github.com/GENIVI/dlt-daemon/issues) - DLT library: Usage of dlt\_user\_log\_write\_float64() and DLT\_FLOAT64() leads to "Illegal instruction (core dumped)" on ARM target. - DLT library: Nested calls to DLT\_LOG\_ ... are not supported, and will lead to a deadlock. - For Non linux platforms [eg: QNX] IPC supported is UNIX\_SOCKET. For Linux Platforms both IPC FIFO and UNIX\_SOCKET are supported ## Software/Hardware Developed and tested with Ubuntu Linux 16 64-bit / Intel PC ## License Full information on the license for this software is available in the "LICENSE" file. Full information on the license for the cityhash code is available in "COPYING" file in src/core\_dump\_handler/cityhash\_c. ## Mailinglist https://lists.genivi.org/mailman/listinfo/genivi-diagnostic-log-and-trace_lists.genivi.org ## Contact Saya Sugiura , Quynh Le Hoang Ngoc ![alt text](doc/images/genivilogo.png "GENIVI") dlt-daemon-2.18.4/ReleaseNotes.md000066400000000000000000001141471353342203500165550ustar00rootroot00000000000000# Diagnostic Log and Trace - Release Notes Back to [README.md](../README.md) ## Version 2.18.4 STABLE ## Changes ### 2.18.4 * Update ReleaseNotes and version to v2.18.4 * dlt-daemon: correct errno usage * dlt-daemon: fix bug binding invalid ipv6 address as default * Add option in dlt.conf for bindAddress to specific IPs (#130) * protocol: Remove non supported user service ID (#159) * libdlt: truncate the log message if it is too long (#156) (#157) * UDP Multicast implementation (#155) * doc: Remove unused images * daemon: fix compile error with DLT_IPC="UNIX_SOCKET" (#153) * using POSIX shared memory APIs (#90) (#151) * Revert "Add option in dlt.conf for bindAddress to specific IPs (#130)" * Add option to set owner group of daemon FIFO (#122) * Add option in dlt.conf for bindAddress to specific IPs (#130) * dlt-system-journal: fixed localtime compile error * Correct sa findings * logstorage: fix compile error * doxygen: Align variable for apid and ctid * doxygen: Remove licence * doxygen: Get rid of warnings * doc: Use pandoc to generate HTML from markdown * doc: Improve README.md * doc: Create missing markdown documents * doc: Documentation update * cmake: Allow build as a subproject (#145) * fix config path for dlt-dbus * define DLT_PATH_MAX for max path buffer length * cmake-improvements (#135) * libdlt: Use posix nanosleep (#144) * doc: Improve markdown documents * doc: Improve dlt_for_developers.md * fix the warning of strncat size * fix warning of self assign * dlt-convert: fix warning of wrong conversion * Travis: Run Travis on Xenial 16.04 * Travis: Modify install package * cleanup: Use dlt_vlog() * Fix alerts from lgtm * lgtm: Add code analysis platform * dlt-test: Improve context ID * dlt-test: Add options * libdlt: Remove commented out code * Remove dlt_forward_msg * libdlt: compare dlt_ll_ts to NULL * network trace: Define package ID macro * daemon: Loop for client fds * daemon: Remove bytes_sent * daemon: Don't remove unregistered context * daemon: Don't assign fd after free * test: Add manual interruption in dlt-test-stress * gtest: Logstorage unit test update * Logstorage: Correct behavior in sync message cache * Logstorage: Sync behavior bug fix * Logstorage: Fix write msg cache ### 2.18.3 * Update ReleaseNotes and version to v2.18.3 * Travis CI: Run unit test (#132) * libdlt: Fix compiler warnings * Unit test: Fix compiler warnings * Unit test fix * Do not install systemd service files for binaries that are not built (#129) * lib: unlock buffer on termination * dlt-receive: Fix crash without arguments * dlt-control: Bug fix for broken get log info * Logging: Error message modification * dlt-daemon: fix internal logging to file after daemonize * Offline logstorage: Fix storage handle NULL check during cleanup * Fix compiler warnings * POSIX: Replace usleep with nanosleep * unix socket: IPC code isolation * lib: daemon: Fix sem lock potential issue * socket: Remove unnecessary header * dlt-daemon: unlink application socket * ipc: close socket if connect failed ### 2.18.2 * Update ReleaseNotes and version to v2.18.2 * Size of Resend buffer less than or equal to DLT_USER_BUF_MAX_SIZE res… (#116) * Fixed memory leak when receiving network traces of 0xFFFF length * Contact information update (#118) * lib: Add mq_close/mq_unlink conditions * doc: Do not allow DLT usage in forked child (#95) * doc: Raise an awareness of log level sync * dlt_offline_logstorage: fix multiple file creation error (#85, #94) * doc: Fix PANDOC_TOOL condition * Travis CI: Fix link in README.md (#106, #108) ### 2.18.1 * doc: Move all man pages to markdown files (#102) * Fix linking problem with tests when systemd enabled (#103) * libdlt: Do not allow DLT usage in forked child (#95) * Travis CI: build with systemd enabled (#97) * Make dlt-convert more responsive when watching a file * Travis CI: fix - add new line to .travis.yml * Build and test status added * Add the Travis CI script ### 2.18.0 * fix broken/missing links in documentation * CMake: Set default configuration * Code beautification using uncrustify * Documentation update * dlt-daemon: Output current number of connections as default * Remove unnecessary reference to zlib in .pc file * Cleanup of unit test fixes * gtest: Modification to offline logstorage * libdlt: Add error handling * exit DLT daemon if /dev/null open fails during fork * Improvement - use dup2 in place of dup in daemon fork * Remove one-instance-lock mechanism * daemon: Add exit trigger * UnitTest: Updates * Made socket send reliable * lib: socket: Flush all data before closing socket * buffer: Code cleanup * buffer: Improve logging * Removed log level change callback notification while context register done with ll_ts API * Logging: avoided missing of log level change callback * Injection: New callback with private data Added new injection callback with private data as argument * Fixed compiler error with previous commit * Dynamic allocation of msg buffer * cmake: systemd: fix hardcoded user in dlt-dbus.service (Issue #36) * rename #define STATIC to DLT_STATIC * Use poll in the dlt-daemon for POSIX compliance * dlt-client: logging: Extended the receiver buffer size * dlt-control: update get log info * Protocol: DLT Service ID Enum instead of defines * Gateway Improvements * Log storage - Updates (#82) * Fflush stdout in the intenal logger (#81) * dlt-daemon: per ECU list of user information (#80) * Add dlt-sortbytimestamp utility plus documentation (#73) * Fix compiler warning PR #77 * Fix compilation with glibc 2.28 (#77) * Fix gcc 8 build (#74) * dlt-daemon: fixed linked-list element remove (#71) * Update dlt_user.c (#66) * dlt-daemon: Fix no state transition to BUFFER state (#65) * file parser: Replace hash functions with list (#67) * libdlt: Avoid busy loop in error case of mq_receive() (#59) * dlt-daemon: Output signal number at exit (#68) * dlt-daemon: Improve error logging on accept() failure (#69) * dlt-daemon: Avoid to output duplicated application registration message (#63) * dlt-daemon: Not output Context un-/registration DLT message by default (#62) * dlt-daemon: Continue to send log level / connection status even if error occurs (#61) * IPC: Unix socket added (#43) * Introduce controlling entire system trace status feature from dlt-control (#57) * dlt-daemon: Lower log level of logs not to output unintentional warning (#58) * dlt-daemon: Fix infinite loop on set log level using wildcards (#55) * dlt-daemon: Fix repeated output of marker message (#54) * dlt-control: Fix Setting default trace status issue (#53) * Fix ForceContextLogLevelAndTraceStatus handling in dlt_daemon_client.c (#50) * minor compiler warning gcc 7.x (#30) * improve error reporting in dlt_daemon_socket (#41) * Fix SEGV dlt_offline_trace.c (#32) * fix PR #26 socket_sendreliable data_send update * Prevention for occasional corrupted messages (#26) * README: Update contact information ### 2.17.0 * Fix for initialization of buffer settings in DLT user library. * fix various memory leaks * some-minor-fixes * Minor fixes: corrected typo in CMakeLists.txt - WTIH_DLT_ADAPTOR, removed character from merge * Data stuck in receiver buffer when dlt_daemon_user_send_log_level() fails * Update dlt_user.h * Add short explanation for DLT log level * Prevent buffer overflow for mount point path in dlt_logstorage_open_log_file * journald adaptor: test with sudo privileges * cmake: fix unit tests compilation with systemd * Input parameter check & Error message modification * Tell cmake to use [README.md](README.md) instead of README to fix doc generation * dlt-system-process-handling: fix warning * dlt_daemon_connection_types: fix build warnings * Updated README * dlt-adaptor-udp, dlt-adaptor-stdin: implement get of verbosity level from input * Added Description in dlt-system.conf * dlt-client: fix dlt_client_cleanup memory handling * CMake Option: Trigger segmentation fault in case of FATAL log * Daemon connection handling fixes * Added Description in dlt-system.conf * dlt-client: fix dlt_client_cleanup memory handling * CMake Option: Trigger segmentation fault in case of FATAL log * dlt-daemon: Fix use after free potential issue * Event handling: Fix connection destroy bug * Remove duplicate README * daemon: check payload length before cast to struct * Added missing build steps to INSTALL * pkg-config: fix library directory. ### 2.16.0 * doc: Documenatation update * Systemd-journal-test: Add WITH_DLT_UNIT_TEST flag when building sources * Smoketest: Offline Logstorage * Smoketest: Multinode * Unit Test: Event handling * Provision to test static function * Unit Test: MultiNode * Unit Test: Multinode Unit test preparation script * CMake: Add option to build unit test binaries * dlt-system-filetransfer: fix bug caused by malloc assert * Environment variables for library ringbuffer * DLT_PTR macro: Improve implementation and function API added * MultiNode: Specify config file location in dlt.conf * dlt-client: Use correct port on connect * process user message: Fix bound handling * dlt-system-filetransfer: Fix compiler warnings * Remove C99 style comments in include directory * Dlt-Receive: Use PRIxxx macros for printf variables * Offine logstorage: Remove duplicated source file * Fix: Memory for context description is not freed * Fix: dlt-daemon overwrites ECU ID even if user log message already has the ECU ID that is not default value * Add: Configuration of option of get log info response during context registration * Add: Configuration of daemon FIFO size * Fix: Handle of /tmp/dlt never reset if dlt-daemon is killed during output user buffer * Add: Debug log for file transfer feature of dlt-system. * Fix: Segfault in checking buffer usage * Fix: File Transfer acceleration * Fix: File name is broken when file is transferred on 64 bit OS. * Fix: Memory leak issue in dlt-dbus * Add dlt_user_is_logLevel_enabled API * [README.md](README.md) formatting changes * Adding GitHub flavored markdown for README. * Fixed D-Bus tracing not working anymore * Fixed not working default log level. * Fixed not returning the correct number of lost messages at exit. * dlt-daemon: Free DltDaemon structure on exit * CommonControl: Fix for commands not working with unix socket * CommonControl: Unix socket path and ecuid parsing for control applications * dlt-control: Provision to control entire system log level * DLT_PTR: User macro to print pointers * dlt-daemon: Fix user log handler return value * dlt-daemon: Connection activation rework * dlt-daemon: receiver rework * Fix connection handling of serial interface * Offline trace: Make search more precise * MultiNode: Add support for mandatory configurations * MultiNode: Add support for SerialHeader conf * MultiNode: Add support for port configuration * MultiNode: Send control messages after connection * MultiNode: Send serialheader if specified in dlt.conf * Offline logstorage: On Demand triggering for syncing Logstorage cache and support long options * Offline logstorage: Fix to resetting of Syncbehavior value * Offline logstorage: Refactor filter storage functionality to support general properties * Offline logstorage: Fixed extended header size check condition * Offline logstorage: Fix invalid filter configuration handling * Added abnormal unit tests to check DLT_RETURN_USER_BUFFER_FULL * DLT_RETURN_USER_BUFFER_FULL is returned when user buffer full * Revert truncation of string or raw block ### 2.15.0 * Fixed bug with truncation of string or raw block * Updated man pages and README * Truncate string or raw block if length exceeds maximum message length * Fixed a bug in dlt-system filetransfer * dlt-system filetransfer waits for a client to connect * Fixed compilation for older versions of gcc * Fixed core pattern to use correct dlt-cdh install path * Fixed CMakeLists to build core dump handler * Replaced Type=Simple with Type=simple in cmkake files for .service files * Added systemd install dir parameter * Added option to specify user for non-root processes * Added dlt-kpi component to log various KPI information to dlt-daemon ### 2.14.1 * MultiNode: Reconnection after connection loss * Fix injection message handling ### 2.14.0 * Fix fork()-handler in libdlt * Set default log-levels in dlt.conf * Fix register context before application is registered * Fixed compiler warnings about format issues in dlt-system-journal.c by replacing llu with PRIu64 * Make IP version compile time configurable * Implemented Dlt MultiNode to connect DLT Daemons running on different operating systems * Daemon shutdown: fixed memory leaks and missing removal of created sockets * DltLogstorage: reduce writing to internal storage device as much as possible * Control appliction to support offline log storage trigger implemented * Offline log storage to internal and external devices implemented * Unix socket control interface implemented * Parse INI files for Offline Logstorage, Multinode and potentially other DLT extensions implmented * Linking library systemd instead of systemd-journal systemd-id128 if systemd version >= 209 * Event handling has been reworked in order to use epoll and restructure the code * Fixed include paths in dlt_user_manual.txt and dlt_cheatsheet.txt ### 2.13.0 * Added core dump handler code * Purged all warnings for -Wall -Wextra with gcc 4.9.1 * Set DLT_USER_BUF_MAX_SIZE to 1390 to prepare UDP message transport * dlt-test-client and dlt-test-filetransfer have global failed test counter so they can return 1 on failure * Using DLT_USER_BUF_MAX_SIZE in dlt-test-client.c truncated check * Set path to /usr/local/share/ in dlt-test-filetransfer.c * Added programme to test repeated calls of dlt_init and dlt_free * DLT daemon improvement - dlt_init()-check * DLT daemon improvement - parameter value range check * Adapt unit tests to check for enum return values * Changed C version to gnu99 and C++ version to gnu++0x * Fixed bug in INTERNAL-mode connection * Use the best possible timestamp for all system journal entries * Make timeout in at_exit handler configurable * Allow multiple instances of dlt-daemon * Add C++ extension which uses variadic templates from C++ 11 (disabled by default) * Allow registration of contexts before application is registered * Add env-var to set initial log-levels * Allow applications to fork() * Fixed file permissions * Added offline logstorage implementation which can be used instead of the already available offline trace functionality ### 2.12.1 * Removed all trailing whitespaces * Replaced all tabs with spaces in all files in include folder * Rework of addon tests filtetransfer, systemd-journal and system-logger * Fix compilation warnings and possible misuse of snprint * Rework of unit tests * Fix installation paths on x86_64 (lib64 instead of lib) ### 2.12.0 * Added unit and functional tests * Fixed copyright doxygen comments * Updated license headers to latest GENIVI license policy * Renamed and cleanup further files to comply with licensing requirements * dlt-control: Check for return values * dlt-daemon: Explicitly set the default loggingLevel to LOG_INFO * dlt-daemon: Explicitly set the default loggingMode to DLT_LOG_TO_CONSOLE * Fixing MIN and MAX defines for base integer types * Unified all line endings to UNIX style * Adding gtest framework v1.7.0 * Remove absolute installation paths so that DLT can be installed at any location (not only "/usr"). * Add Service ID Last entry to avoid further modifications in dependent code * Change daemon state handling to have all traces in online trace even when offline trace is active * Fix content of offline trace * Open daemon connection in atexit function * Change loglevel of Request-Resend message * Fix daemon state handling with offline trace * Fix watchdog timeout * Reworked internal output * DLT MISRA conform changes * Made zlib dependent on DLT_SYSTEM * Doxygen paths are now determined by CMake. * Add the IPv6 support * Workaround for duplicated log messages in offline trace file issue * Fix PREFIX. Works now with the default PREFIX (/usr/local/) and with the user PREFIX (e.g. /temp/test_with_pref). PREFIX Fix for filetransfer directory (PREFIX/share/) * Fixed typo in include guard * Resolves BUG-206: Install prefix should be configurable * Adding support for new macros to the daemon. New macros: DLT_HEX8(VAR) 8bits variable displayed in hexadecimal with "0x" prefix DLT_HEX16(VAR) 16bits displayed in hexadecimal with "0x" prefix DLT_HEX32(VAR) 32bits displayed in hexadecimal with "0x" prefix DLT_HEX64(VAR) 64bits displayed in hexadecimal with "0x" prefix DLT_BIN8(VAR) 8bits variable displayed in binary with "0b" prefix DLT_BIN16(VAR) 16bits variable displayed in binary with "0b" prefix * Fixed network trace test * Fix dlt_user_log_write_start_id return value * Added new API to send marker message from application. * New Callback function in DLT library, called when log level of context is changed ### 2.11.0 * New macros for Format of Hex and Binary. * Enable dbus trace when adaptor starts up. * Added configuration of dbus filter. * Fixed segmented messages arguments to standard. * First implementation of DLT DBus adapter. * DLT_CSTRING implementation non verbose mode. * Added new examples which can be manually build against DLt library. * Send ECU Id if enabled and added library API to change. * Send timestamp can be disabled by new API. * Send session/process id by default and add configuration API. * Send extended header in non verbose mode by default and add new API to change setting. * Make daemon buffer size configurable ### 2.10.0 * Bug 184 - /tmp/dltpipes directory does not exist before dlt-daemon is started, logging disabled * Updated authors information. * Fixed missing variable declaration when systemd not enabled. * Fixed: all possible malloc, sprintf and strcpy problems * Fixed: Creation of dltpipes directory is too late. * Cygwin port: cygwin patch, signal handling patch and cppcheck and install lib dll to correct location on Windows. * Fixed compiler warnings with 32Bit gcc compiler. * Fixed: Fixed offline trace and new send functions issues * Fixed: Bug 172 - DLT system crashes because of wrong journald adaptor implementation * DLT Common API Wrapper. * Removed dlt_free from example and test applications, already called from exit handler. * Fixed missing dlt_receiver_remove in dlt_daemon_process_user_xxx functions. * Use LIB_SUFFIX as lib installation path. * Fixed serial port not working anymore. * Added log output of created socket/port In init phase 2 - socket creation * Defined return value for dlt_message_read(). * Cleanup of send return values.Further cleanup of send restructure. * Moved daemon client functions to new source file. * Centralised send function to client.Introduced connection state to dlt daemon. * Removed check of double registration of contexts in user library, already checked by daemon. * When using DLT in console mode on a 64-bit machine, timestamps are corrupted due to an address of a 32-bit value being cast to a 64-bit pointer. * Bug 3 - Cmake does not check for zlib for dlt-daemon compilation. * Added new control message timezone. * Fixed deadlock after wrong merge.. * Fix potential buffer overflow in offline trace. * Fix deadlock in dlt_user_log_reattach_to_daemon(void). * Fixed possible crash when runtime configurations files are corrupted. * Environement variables added to configure internal logging in library. * Reduce Timeout between filetransfer packets. * Close socket when send fails. * Replace threads by timing fds for ecu version, timing packets and watchdog. * Added conntection info and unregister context control messages. * Configurable Timeout on send. * Added further checks to dlt_buffer. * atexit handler fix. * Add threadnames to libdlt threads. * Security fix on DLT pipes. * Reduce usage of SEM_LOCK in application library and reset pointers. * Fix: Systemd Journal Adapter provides corrupted output. * Fix: Install Example service file only when example enabled ### 2.9.1 * Implementation of command line tool dlt-control. * Fix file transfer bug. * Bug 44 - Don't print "Buffer full" message from DLT daemon for each trace. * Yocto fix in build builds. * Fixed: security issue in dlt-system-shell regarding strncpy. * Fixed: Security Issue by Command Injection in DLT System. * systemd/CMakeLists: Remove SYSTEMD_CONFIGURATIONS_FILES_DIR existance check. * Bug 85 - Include of dlt.h leads to compiler warning. * Bug 84 - Adding utf8 support to dlt-daemon, dlt-viewer. Modified patch, originally provided by Stefan Vacek. * systemd journal support added. * spec file does not package man files when cmake is run with -DWITH_DOC=OFF * added length check for paths of files to be transferred * Semaphores and Pointer passing insteasd by value and otehr coverity issue fixes * Fixed several issues in DLT filetransfer. * added creation date and a simple hash on the file name for to improve the uniqueness of getFileSerialNumber * modified filetransfer to be more robust in restarting transfers * Remove dangling DLT_SEM_FREE from dlt_user_queue_resend * Unifed ECU version sending functions * Refinements due to problems reported by static code analysis * Spec file does no more package man files when cmake is run with -DWITH_DOC=OFF * Made the APID strings in dlt-test-multi-process counting from 00-99 * Added creation date and a simple hash on the file name for to improve the uniqueness of getFileSerialNumber * File Transfer: improved robustness in case of restarted ECU/dlt-system with interrupted transfers ### 2.9.0 * Changed documentation and man pages into asciidoc format. * Increased buffer sizes for DLT user library and DLT daemon * [GDLT-120]: truncated and Segmented network tracing * [GDLT-137]: Automatically try resending of user buffer after FIFO full * [GSWD-85]: Added authors file ### 2.8.0 * [GDLT-115]: Encapsulate user macros * Fix register app and register context was not stored in buffer when FIFO is full. Other controll messages still not saved in buffer. * Create new fifo only when same application registers with different pid.' * Do not register appliction again, if already registered. * Fixed filetransfer not checking buffer fill level. ### 2.7.0 * [GDLT-24] Fixing compiler warnings * [GDLT-94] Optional sending periodic software version messages. See man pages for more informations * [GENDLT-26] Check for description length sanity * [GENDLT-24] Crash on invalid injection message fixed * [GDLT-93] Add -Wextra flags for compilation Fixed all the warnings that * [GDLT-90] Optional: systemd watchdog concept in dlt-system and dlt-daemon * [GDLT-67] Re-implemented dlt-system. Read full commit message for more information ### 2.6.2 * [GDLT-89] Fixed daemon doesn't sent the persistent log level * [GDLT-88] Fixed wrong initalization order using offline trace function ### 2.6.1 * Add _GNU_SOURCE Definition to be able to use O_CLOEXEC * Added important SEM_FREE in the daemon and closing fd in the filetransfer * [GDLT-3] Fixed missing semaphore around dlt_buffer_push3 * [GDLT-86] Fixed dlt_free uses absolute file path /tmp and not DLT_USER_DEFINE define * [D4099] Check for duplicate file handles, and clean them up if found * [GDLT-85] Pipes opened multiple times for the same application pid fixed * [GDLT-82] Child process inherits file descriptors openend by their parent fixed * [GDLT-84] Instead of calling the injection callback, store a pointer to it and the required parameter data fixed * [GDLT-70] Check for malloc failures and return errors where applicable * [GDLT-47] Avoid discarding old contexts if no new memory can be allocate * [GDLT-69] Fixed bug in dlt-test-multi-process shares context between threads ### 2.6.0 * [GDLT-75] Use old style directory check on startup * [GENDLT-21] Move mcnt from DltContextData to DltContext * [GENDLT-15] Fixes to previous integrations from review * [GENDLT-15] Safe re-allocations for databuffer * [GENDLT-15] use the correct TEXTBUFSIZE * [GENDLT-15] Optimize usege of strlen. Improved log level handling * [GENDLT-15] Avoid buffer overrun with snprintf() * [GENDLT-15] Check return value of dlt_user_log_write_start(_id) correctly * [GENDLT-15] Reduce the number of applications if allocation fails * [GENDLT-15] Make dlt_user_log_write_start inline * [GENDLT-15] Improve errore checking in dlt_user_log_write_start_id * [GENDLT-15] Use databussersize to avoid reallocations * [GENDLT-15] Rename buffer size constant to avoid confusion * [GENDLT-15] Better error handling when writing to FIFO * [GENDLT-15] Remove duplicate msg initialization. * [GENDLT-15] Optimize away multiple uses of strlen for one check * [GDLT-4] Improve queue handling, allow for other messages while transferring a large file * [GDLT-4] Limit maximum file queue to 256 files * [GDLT-4] First working version of inotify for file transfer * [GDLT-2] First test for filetransfer change * [GDLT-2] Change to gzip wrapper format. Change file signature creation to account for file size, as inode number maybe duplicate when deleting and creating new files * [GDLT-2] Fix bug while reading the options * [GDLT-2] Allow for enabling/disabling compression for the separate directories * [GDLT-2] Check if the file is already compressed * [GDLT-2] Link with libz, fix a typo * [GDLT-2] zlib based compression for dlt-system * Cleaned some warnings generated from removing stale old code ### 2.5.2 * Change to Mozilla Public License Version 2.0 ### 2.5.1 * Fixed bug with comparinson between signed and unsigned integer and protection for a buffer overflow. * Modified library for new test cases to corrupt data - related to the bug fix for testing signed and unsigned integer * [GENDLT-20] Fixed bug to use old cmake version for copy file * Replaced dlt-test-filetransfer-image.png with an own created image * [GENDLT-21] Fixed bug: Message Counter (MCNT) should be increased but is always 0 ### 2.5.0 * [GDLT-53] Man pages installation included * .cproject and .project file for Eclipse included * Update of doxygen documentation and generation * Rework of root CMake project file, e.g. structure and compile options * [GENDLT-16] Create variable in dlt-system.conf to configure the timeout of the filetransfer * [GDLT-37] Extend automated test tools for parallel process/threads tests * [GSW-138] API Extension to resend the log messages in the user buffer * [GDLT-36] Prefixing of dlt_version.h fixed * [GDLT-31] Tracefile content stored different under Ubuntu 64 bit version compared to Ubuntu/Win 32 Bit version fixed * [GDLT-35] Compile warnings fixed * [GSW-137] Wrong include gives error on compailing against dlt fixed ### 2.4.2 * Added dynamic increasable ringbuffers to user lib and daemon. * dlt-system filetransfer now recovers when file is deleted during filetransfer. * Added check of file size when starting and deleting files during filetransfer * Added chekc of shm buffer availability when push to shm * Create abstraction of shm buffer management. * Fixed buffer overflow problem in buffer library. * Disabled share memory by default - disabled completely shared memory if not enabled. ### 2.4.1 * Added dynamic increasable ringbuffers to user lib and dlt-daemon. * Created abstraction of shm buffer management. * dlt-system filetransfer now recovers when file is deleted during filetransfer. * Added check of file size when starting and deleting files during filetransfer. * Added check of shm buffer availability when push to shm. ### 2.4.1 * Added internal logging facility to stdout, syslog or local file, configurable in configuration file. * Added deamonise and signal handlers to dlt-system. * Added manual pages. * Added new API dlt_check_library_version() function. * Fifo or SHM mode can be changed by compiler switch. * Replaced SHM implementation. * Fixed shared memory problem in DLT library during startup, if application is started before daemon. * Fixed syslog adapter in dlt-system. * Reverted API changes in dlt_register_app() function. * DLT user library does not set the stack size of the receiver thread anymore. ### 2.4.0 * New config files /etc/dlt.conf and /etc/dlt-system.conf must be adapted to the needs * New DLT user lib API dlt_get_log_state() to get DLT client state * New DLT user lib API to manage flow control (needed for bulk data logging) * New DLT user lib API dlt_set_log_mode() to enable/disable internal/external trace * New application dlt-system (filtransfer, proc file system logger,syslog udp adapter included) * [GSW-66] File transfer over DLT. * [GSW-43] Performance improvement for bulk data over DLT. * [GSW-61] Replace command line parameter by configuration file * [GSW-13] Support for keep-alive messages as configuration parameter * [GSW-60] Extended offline DLT Trace memory handling. * Removed filter implementation ### 2.3.0 * [GSW-16] Systemd configuration for syslog to DLT dapater * [GSW-62] DLT Library version check * [GSW-28] Directory where persistent data is stored is not configurable * [GSW-59] Statically allocated large array * Added init script for Ubuntu * Optional adding of gprof compile flags * sprintf with float64 fails on ARM platform; disabled this function on QRM platform. ### 2.2.0 * Moved build process completely to cmake * Added commandline parameter -u to set ring buffer size * Reduced cpu consumption needed by applications using DLT library * Increased default ringbuffer size to 10024 bytes * Changed delay in receiver routine to 100ms ### 2.1.0 * DLT Viewer (QT) * New dlt viewer (QT-based) implementated * Moved to seperate project, see extra Release Notes for DLT Viewer (QT) * DLT Viewer (WX) - Deprecated * Old dlt viewer (WX) is removed now from package generation * Moved to seperate project * Removed filtering of messages during writing to a file * DLT library: * Functions dlt_file_read_raw() and dlt_file_read_header_raw() added * Added support for raw messages in nonverbose mode * Injection tables are now dynamically allocated * Contexts are now dynamically allocated * Added seperate file for platform float types (dlt_float_types.h) and used this types. Attention: This file must be adapted to each target platform. * Removed signal handlers from dlt_user.c; SIGPIPE signal is ignored; atexit() handler still exists * Function dlt_forward_msg() added * DLT daemon: * Small optimization in get_log_info() for one searched application with one searched context, which is existing in the context table of the dlt daemon * Optional syncing to serial header added * Support for keep-alive messages, realized as seperate thread * General: * Combined dlt-test-user-multi and dlt-test-many to dlt-test-stress * Extended dlt-test-client * Added stress test3 to dlt-test-stress * Added help to dlt-test-stress, printed if no test was selected * Added dlt-test-internal * Removed plugin support from dlt_receive and dlt_convert * Extended documentation * dlt viewer (wx): Fixed minor bug, it's possible now to compile the dlt viewer (wx) again under mingw under Windows * DLT test programs: Fixed minor bug in dlt-test-user, test3f: Wrong counter was used * Removed DLT_LOG calls in injection functions due to problems (application hangs) ### 2.0.5 * DLT viewer: * The default log level is now shown, if already known * Renamed Filter->New.. to Filter->Delete all filter * Enhanced performance * DLT library: * On crash or termination of application using the DLT library, the registered context and application IDs are removed properly (and are deregistered from DLT daemon) * dlt_register_context_ll_ts() and Macro therefore added * dlt_message_payload() has now additional type DLT_OUTPUT_ASCII_LIMITED * dlt_message_header_flags() added * DLT daemon: * Support for dlt_register_context_ll_ts() added * Enhanced support for get_log_info (all modes, 1 app all contexts, 1 app 1 context, all apps all contexts) * Added -r option, for automatic sending context information to dlt client; if no client connection is available, this information is stored in history buffer in dlt daemon * Several internal performance optimizations: * dlt_daemon_context_find(), dlt_daemon_application_find(): Now O(log n) instead O(n) * Several functions optimized * Unnecessary functions removed * General: * Moved definition of struct DltUser from dlt_user_private.h to dlt_user.h * dlt.h includes now dlt_common.h * Extended dlt-test-user and dlt-test-client applications * DLT daemon/DLT library: Fixed bug in Filter Delete * DLT daemon: Fixed bug in dlt daemon which leads to a crash, when starting/stoping application, then sending new log level to context of this (now not running) application. * DLT daemon: Fixed bug in unregister application * DLT daemon: Fixed bug in reattach to daemon * DLT library: Fixed bug in send function * DLT viewer: Fixed bug in set default log level ### 2.0.4 * License has changed from ADRLPD to ADRLRM * DLT viewer: * Support for non-verbose mode (as FIBEX plugin) * DLT library: * Support for non-verbose mode (as FIBEX plugin) * dlt_message_print_* functions added * Semaphore calls added to enable multi-threading * Changed injection interface from direct usage to callback * Requested log level and trace status is set immediately in dlt_set_application_ll_ts_limit() * Implemented receiver thread in DLT library (used for setting of log level/trace status and for injection handling) * Added signal-handler and atexit-handler for cleanup (calls dlt_free()) * General: * Added implementation of clientlib and testclient for Windows * Both adaptors sends now log messages with log level DLT_LOG_INFO * Multi-threading example in src/tests/dlt-test-user-multi added * DLT viewer: Right mouse button for loading plugin descriptions (MOST-/Fibex-XML File) is now working (also in Windows) * DLT library: Fixed bug in dlt_print_mixed_string() * DLT library: Fixed bug in dlt_daemon_contexts_get_next_con_id() * DLT daemon: dlt_daemon_process_user_message_unregister_application() also removes now all corresponding contexts * DLT daemon: Added security check to dlt_daemon_control_get_log_info() in order to avoid crash which occured under special circumstances * DLT daemon: Register app now opens the connection to the DLT library, unregister app closes the connection (was before in register context) * Added -lrt to package config file * Resolved dependency from dlt_client.h to dlt_common.h -> dlt_common.h is now public ### 2.0.3 * DLT viewer: * Reduced load if idle * Modified behaviour of settings in dlt-viewer * Always open tmpfile in dlt-viewer if nothing other is specified * File->Clear added * DLT daemon: * Added several checks within code * DLT library: * Added several checks within code * Enhanced local print modes: a environment variable now can be used to control local print mode: Variable: DLT_LOCAL_PRINT_MODE Values : "AUTOMATIC" (local print only, if dlt-daemon connection is not available at startup of program using DLT library) "FORCE_ON" (always do local print) "FORCE_OFF" (never do local print) * A client library for writing console client applications (Linux) is now available. dlt-receiver and dlt-test-client uses this new library code * General: * Added seperate file for DltMostMessageHeader type * Added seperate file for DLT protocol values * Relaxed checks for passing trace messages to plugin handler * Tested and improved MOST plugin * Support for float (32 Bit) and double (64 Bit) values * Code fragments for winclientlib and wintestclient added * DLT library: Fixed bug in DLT_IMPORT_CONTEXT * DLT library: Fixed bug in dlt_plugin_print() and dlt_most_payload() * DLT daemon and library: Fixed bug in handling of description strings * DLT viewer: Fixed bug in RMB Click for loading plugin description * General: Fixed parsing and printing of MOST messages * Several small bugs fixed ### 2.0.2 * DLT viewer: * Showing timestamp * Compiles now with MS Visual C++ * Support for loading multiple descriptions of plugins is now possible (*) * Plugin description can be loaded individually by Right-mouse-button (*) * DLT daemon: * Overflow message is now stored in history buffer, if necessary * DLT library: * Ring-buffer for injection messages implemented * History Buffer for Startup + Overflow implemented * Setting of maximum logged log level/trace status for application triggered by application is now possible * Optional local output of Log message is now possible * General: * Support for ARTIS Box implemented (all, without GUI) * Support for timestamp in standardheader extras added * Support for ECU ID in standardheader extras added; this value can be overwritten by the DLT daemon * DLT viewer: * Store and load application and context description fixed * Fixed crash on termination of Windows version * DLT console utilities: * Fixed printing of filter ids * General: * Big Endian/Little Endian support tested and fixed * Fixed writing and reading of locally created dlt files * Several smaller bugs fixed ### 2.0.1 * Full support for serial connection between DLT daemon and DLT Viewer * Several small bugs fixed in DLT Viewer ### 2.0.0 * Initial Release of new DLT daemon Version 2 including the new DLT Client DLT Viewer * Initial Release dlt-daemon-2.18.4/automotive-dlt-c++.pc.in000066400000000000000000000003211353342203500201020ustar00rootroot00000000000000exec_prefix=@CMAKE_INSTALL_PREFIX@ includedir=${exec_prefix}/include Name: DLT C++ Description: Diagnostic Log and Trace C++ extensions Version: @DLTCPP_VERSION@ Requires: automotive-dlt Cflags: -std=gnu++0x dlt-daemon-2.18.4/automotive-dlt.pc.in000066400000000000000000000014141353342203500175400ustar00rootroot00000000000000####### # SPDX license identifier: MPL-2.0 # # Copyright (C) 2011-2015, BMW AG # # This file is part of GENIVI Project DLT - Diagnostic Log and Trace. # # This Source Code Form is subject to the terms of the # Mozilla Public License (MPL), v. 2.0. # If a copy of the MPL was not distributed with this file, # You can obtain one at http://mozilla.org/MPL/2.0/. # # For further information see http://www.genivi.org/. ####### prefix=@CMAKE_INSTALL_PREFIX@ exec_prefix=@CMAKE_INSTALL_PREFIX@ libdir=${exec_prefix}/@CMAKE_INSTALL_LIBDIR@ includedir=${exec_prefix}/include Name: DLT Description: Diagnostic Log and Trace Version: @DLT_VERSION@ Requires: Libs: -L${libdir} -ldlt -lrt -lpthread @ZLIB_LIBRARY@ Cflags: -I${includedir}/dlt -DDLT_@DLT_MAJOR_VERSION@_@DLT_MINOR_VERSION@ dlt-daemon-2.18.4/automotive-dlt.spec.in000066400000000000000000000072341353342203500200760ustar00rootroot00000000000000####### # SPDX license identifier: MPL-2.0 # # Copyright (C) 2011-2015, BMW AG # # This file is part of GENIVI Project DLT - Diagnostic Log and Trace. # # This Source Code Form is subject to the terms of the # Mozilla Public License (MPL), v. 2.0. # If a copy of the MPL was not distributed with this file, # You can obtain one at http://mozilla.org/MPL/2.0/. # # For further information see http://www.genivi.org/. ####### Name: @PROJECT_NAME@ Version: @DLT_VERSION@ Release: @GENIVI_RPM_RELEASE@ Summary: %{name} - Diagnostic Log and Trace Group: System Environment/Base Vendor: BMW Group AG License: @LICENSE@ Source0: %{name}-%{version}.tar.gz BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root BuildRequires: pkg-configure BuildRequires: cmake %description This component provides a standardised log and trace interface, based on the standardised protocol specified in the AUTOSAR standard 4.0 DLT. This component can be used by GENIVI components and other applications as logging facility providing - the DLT shared library - the DLT daemon, including startup scripts - the DLT daemon adaptors - the DLT client console utilities - the DLT test applications %package doc Summary: %{name} - Diagnostic Log and Trace: Documentation Group: Documentation %description doc This component provides the documentation for %{name}. %package devel Summary: %{name} - Diagnostic Log and Trace: Development files Group: Development/Libraries Requires: %{name} = %{version}-%{release} Provides: pkgconfig(%{name}) %description devel This component provides the development libraries and includes for %{name}. %package c++-devel Summary: %{name} - Diagnostic Log and Trace: Development files Group: Development/Libraries Requires: %{name} = %{version}-%{release}-devel Provides: pkgconfig(%{name}-c++) %description c++devel This component adds a C++ extension for %{name}. %prep %setup -q %build rm -rf build mkdir -p build cd build #../configure --host=@HOST_TYPE@ --prefix=%{_prefix} #make cmake .. -DCMAKE_INSTALL_PREFIX=/usr make %install rm -rf $RPM_BUILD_ROOT cd build mkdir -p $RPM_BUILD_ROOT%{_bindir} make install DESTDIR=$RPM_BUILD_ROOT #/usr/bin/install -c -m 755 testscripts/Meego/dlt-daemon $RPM_BUILD_ROOT/etc/init.d %pre %post /sbin/ldconfig %postun /sbin/ldconfig %clean rm -rf $RPM_BUILD_ROOT %files #/etc/init.d/dlt-daemon /etc/dlt-system.conf /etc/dlt.conf /usr/share/dlt-filetransfer/dlt-test-filetransfer-file /usr/share/dlt-filetransfer/dlt-test-filetransfer-image.png %{_libdir}/libdlt.so.@DLT_MAJOR_VERSION@ %{_libdir}/libdlt.so.@DLT_VERSION@ %{_libdir}/libdlt.so %{_bindir}/dlt-system %{_bindir}/dlt-convert %{_bindir}/dlt-sortbytimestamp %{_bindir}/dlt-receive %{_bindir}/dlt-adaptor-stdin %{_bindir}/dlt-adaptor-udp %{_bindir}/dlt-test-client %{_bindir}/dlt-test-user %{_bindir}/dlt-test-stress %{_bindir}/dlt-test-stress-client %{_bindir}/dlt-test-stress-user %{_bindir}/dlt-test-filetransfer %{_bindir}/dlt-test-multi-process %{_bindir}/dlt-test-multi-process-client %attr(0755,root,root) %{_bindir}/dlt-daemon %{_bindir}/dlt-example-user %{_bindir}/dlt-example-user-func %{_bindir}/dlt-example-filetransfer %files doc @PACKAGE_DOC@%{_mandir}/man1/dlt-convert.1.gz @PACKAGE_DOC@%{_mandir}/man1/dlt-sortbytimestamp.1.gz @PACKAGE_DOC@%{_mandir}/man1/dlt-daemon.1.gz @PACKAGE_DOC@%{_mandir}/man1/dlt-receive.1.gz @PACKAGE_DOC@%{_mandir}/man1/dlt-system.1.gz @PACKAGE_DOC@%{_mandir}/man5/dlt-system.conf.5.gz @PACKAGE_DOC@%{_mandir}/man5/dlt.conf.5.gz %files devel %{_includedir}/dlt/*.h %{_libdir}/pkgconfig/@PROJECT_NAME@.pc %files c++-devel %{_includedir}/dlt/*.hpp %{_libdir}/pkgconfig/@PROJECT_NAME@-c++.pc dlt-daemon-2.18.4/cmake/000077500000000000000000000000001353342203500147125ustar00rootroot00000000000000dlt-daemon-2.18.4/cmake/CMakeLists.txt000066400000000000000000000061431353342203500174560ustar00rootroot00000000000000####### # SPDX license identifier: MPL-2.0 # # Copyright (C) 2011-2015, BMW AG # # This file is part of GENIVI Project DLT - Diagnostic Log and Trace. # # This Source Code Form is subject to the terms of the # Mozilla Public License (MPL), v. 2.0. # If a copy of the MPL was not distributed with this file, # You can obtain one at http://mozilla.org/MPL/2.0/. # # For further information see http://www.genivi.org/. ####### # Run CheckIncludeFiles and CheckFunctionExists include(TestBigEndian) TEST_BIG_ENDIAN( DLT_BIGENDIAN ) if( DLT_BIGENDIAN ) add_definitions( -DBYTE_ORDER=BIG_ENDIAN ) else ( DLT_BIGENDIAN ) add_definitions( -DBYTE_ORDER=LITTLE_ENDIAN ) endif ( DLT_BIGENDIAN ) INCLUDE(CheckIncludeFiles) CHECK_INCLUDE_FILES( arpa/inet.h HAVE_ARPAINET_H) CHECK_INCLUDE_FILES( fcntl.h HAVE_FCNTL_H) CHECK_INCLUDE_FILES( float.h HAVE_FLOAT_H) CHECK_INCLUDE_FILES( limits.h HAVE_LIMITS_H) CHECK_INCLUDE_FILES( netdb.h HAVE_NETDB_H) CHECK_INCLUDE_FILES( netinet/in.h HAVE_NETINETIN_H) CHECK_INCLUDE_FILES( stddef.h HAVE_STDDEF_H) CHECK_INCLUDE_FILES( stdint.h HAVE_STDINT_H) CHECK_INCLUDE_FILES( stdlib.h HAVE_STDLIB_H) CHECK_INCLUDE_FILES( string.h HAVE_STRING_H) CHECK_INCLUDE_FILES( sys/ioctl.h HAVE_SYSIOCTL_H) CHECK_INCLUDE_FILES( sys/socket.h HAVE_SYSSOCKET_H) CHECK_INCLUDE_FILES( sys/time.h HAVE_SYSTIME_H) if( WITH_SYSTEMD_WATCHDOG OR WITH_SYSTEMD ) set(CMAKE_REQUIRED_INCLUDES "${PROJECT_SOURCE_DIR}/systemd/3rdparty/") CHECK_INCLUDE_FILES( sd-daemon.h HAVE_SYSTEMD_H) endif ( WITH_SYSTEMD_WATCHDOG OR WITH_SYSTEMD ) CHECK_INCLUDE_FILES( unistd.h HAVE_UNISTD_H) CHECK_INCLUDE_FILES( sys/ipc.h HAVE_SYSIPC_H) CHECK_INCLUDE_FILES( netdb.h HAVE_NETDB_H) CHECK_INCLUDE_FILES( ctype.h HAVE_CTYPE_H) CHECK_INCLUDE_FILES( signal.h HAVE_SIGNAL_H) CHECK_INCLUDE_FILES( syslog.h HAVE_SYSLOG_H) CHECK_INCLUDE_FILES( sys/stat.h HAVE_SYSSTAT_H) CHECK_INCLUDE_FILES( linux/stat.h HAVE_LINUXSTAT_H) CHECK_INCLUDE_FILES( sys/uio.h HAVE_SYSUIO_H) CHECK_INCLUDE_FILES( termios.h HAVE_TERMIOS_H) CHECK_INCLUDE_FILES( unistd.h HAVE_UNISTD_H) INCLUDE(CheckFunctionExists) CHECK_FUNCTION_EXISTS( clock_gettime HAVE_FUNC_CLOCKGETTIME) CHECK_FUNCTION_EXISTS( floor HAVE_FUNC_FLOOR) CHECK_FUNCTION_EXISTS( fork HAVE_FUNC_FORK) CHECK_FUNCTION_EXISTS( gethostbyname HAVE_FUNC_GETHOSTBYNAME) CHECK_FUNCTION_EXISTS( gettimeofday HAVE_FUNC_GETTIMEBYDAY) CHECK_FUNCTION_EXISTS( inet_ntoa HAVE_FUNC_INETNTOA) CHECK_FUNCTION_EXISTS( malloc HAVE_FUNC_MALLOC) CHECK_FUNCTION_EXISTS( memmove HAVE_FUNC_MEMMOVE) CHECK_FUNCTION_EXISTS( memset HAVE_FUNC_MEMSET) CHECK_FUNCTION_EXISTS( mkfifo HAVE_FUNC_MKFIFO) CHECK_FUNCTION_EXISTS( select HAVE_FUNC_SELECT) CHECK_FUNCTION_EXISTS( socket HAVE_FUNC_SOCKET) CHECK_FUNCTION_EXISTS( strchr HAVE_FUNC_STRCHR) CHECK_FUNCTION_EXISTS( strerror HAVE_FUNC_STRERROR) CHECK_FUNCTION_EXISTS( strstr HAVE_FUNC_STRSTR) CHECK_FUNCTION_EXISTS( strtol HAVE_FUNC_STRTOL) if(WITH_CHECK_CONFIG_FILE) configure_file(${PROJECT_SOURCE_DIR}/cmake/config.h.cmake ${PROJECT_BINARY_DIR}/include/dlt/config.h) endif(WITH_CHECK_CONFIG_FILE) configure_file(${PROJECT_SOURCE_DIR}/cmake/dlt_version.h.cmake ${PROJECT_BINARY_DIR}/include/dlt/dlt_version.h @ONLY) dlt-daemon-2.18.4/cmake/config.h.cmake000066400000000000000000000037071353342203500174160ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2011-2015, BMW AG * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ // DO NOT EDIT! GENERATED AUTOMATICALLY! // cmakedefine01 sets #define [0|1] if variable is defined in cmake // variable is set by CHECK_INCLUDE_FILES and CHECK_FUNCTION_EXISTS #cmakedefine01 HAVE_SYSTEMD_H #cmakedefine01 HAVE_ARPAINET_H #cmakedefine01 HAVE_FCNTL_H #cmakedefine01 HAVE_FLOAT_H #cmakedefine01 HAVE_LIMITS_H #cmakedefine01 HAVE_NETDB_H #cmakedefine01 HAVE_NETINETIN_H #cmakedefine01 HAVE_STDDEF_H #cmakedefine01 HAVE_STDINT_H #cmakedefine01 HAVE_STDLIB_H #cmakedefine01 HAVE_STRING_H #cmakedefine01 HAVE_STRINGS_H #cmakedefine01 HAVE_SYSIOCTL_H #cmakedefine01 HAVE_SYSSOCKET_H #cmakedefine01 HAVE_SYSTIME_H #cmakedefine01 HAVE_SYSTEMD_H #cmakedefine01 HAVE_UNISTD_H #cmakedefine01 HAVE_SYSIPC_H #cmakedefine01 HAVE_NETDB_H #cmakedefine01 HAVE_CTYPE_H #cmakedefine01 HAVE_SIGNAL_H #cmakedefine01 HAVE_SYSLOG_H #cmakedefine01 HAVE_SYSSTAT_H #cmakedefine01 HAVE_LINUXSTAT_H #cmakedefine01 HAVE_SYSUIO_H #cmakedefine01 HAVE_TERMIOS_H #cmakedefine01 HAVE_UNISTD_H #cmakedefine01 HAVE_FUNC_BZERO #cmakedefine01 HAVE_FUNC_CLOCKGETTIME #cmakedefine01 HAVE_FUNC_FLOOR #cmakedefine01 HAVE_FUNC_FORK #cmakedefine01 HAVE_FUNC_GETHOSTBYNAME #cmakedefine01 HAVE_FUNC_GETTIMEBYDAY #cmakedefine01 HAVE_FUNC_INETNTOA #cmakedefine01 HAVE_FUNC_MALLOC #cmakedefine01 HAVE_FUNC_MEMMOVE #cmakedefine01 HAVE_FUNC_MEMSET #cmakedefine01 HAVE_FUNC_MKFIFO #cmakedefine01 HAVE_FUNC_SELECT #cmakedefine01 HAVE_FUNC_SOCKET #cmakedefine01 HAVE_FUNC_STRCHR #cmakedefine01 HAVE_FUNC_STRERROR #cmakedefine01 HAVE_FUNC_STRSTR #cmakedefine01 HAVE_FUNC_STRTOL dlt-daemon-2.18.4/cmake/dlt_version.h.cmake000066400000000000000000000024611353342203500204750ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2011-2015, BMW AG * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /* DO NOT EDIT! GENERATED AUTOMATICALLY! */ #ifndef __DLT_VERSION_H_ #define __DLT_VERSION_H_ #define _DLT_PACKAGE_VERSION_STATE "@DLT_VERSION_STATE@" #define _DLT_PACKAGE_VERSION "@DLT_VERSION@" #define _DLT_PACKAGE_MAJOR_VERSION "@DLT_MAJOR_VERSION@" #define _DLT_PACKAGE_MINOR_VERSION "@DLT_MINOR_VERSION@" #define _DLT_PACKAGE_PATCH_LEVEL "@DLT_PATCH_LEVEL@" #define _DLT_PACKAGE_REVISION "@DLT_REVISION@" #ifdef DLT_SYSTEMD_ENABLE #define _DLT_SYSTEMD_ENABLE "+SYSTEMD" #else #define _DLT_SYSTEMD_ENABLE "-SYSTEMD" #endif #ifdef DLT_SYSTEMD_WATCHDOG_ENABLE #define _DLT_SYSTEMD_WATCHDOG_ENABLE "+SYSTEMD_WATCHDOG" #else #define _DLT_SYSTEMD_WATCHDOG_ENABLE "-SYSTEMD_WATCHDOG" #endif #ifdef DLT_TEST_ENABLE #define _DLT_TEST_ENABLE "+TEST" #else #define _DLT_TEST_ENABLE "-TEST" #endif #ifdef DLT_SHM_ENABLE #define _DLT_SHM_ENABLE "+SHM" #else #define _DLT_SHM_ENABLE "-SHM" #endif #endif dlt-daemon-2.18.4/distfiles000066400000000000000000000006521353342203500155460ustar00rootroot00000000000000CMakeLists.txt (src|include|wxctb|testscripts|doc).*CMakeLists.txt (src|include|wxctb|testscripts).*\.(cpp|h|c|cxx) include/dlt/.*(\.h|\.cpp|\.cmake) #testscripts/Ubuntu/.*(\.h|\.cpp|\.cmake) #testscripts/Meego/.*(\.h|\.cpp|\.cmake) #systemd/.*(\.h|\.cpp|\.cmake) automotive-dlt.spec.in [^/]*\.cmake src/daemon/dlt.conf src/system/dlt-system.conf src/tests/dlt-test-filetransfer-file src/tests/dlt-test-filetransfer-image.png dlt-daemon-2.18.4/doc/000077500000000000000000000000001353342203500143775ustar00rootroot00000000000000dlt-daemon-2.18.4/doc/CMakeLists.txt000066400000000000000000000250021353342203500171360ustar00rootroot00000000000000####### # SPDX license identifier: MPL-2.0 # # Copyright (C) 2011-2015, BMW AG # # This file is part of GENIVI Project DLT - Diagnostic Log and Trace. # # This Source Code Form is subject to the terms of the # Mozilla Public License (MPL), v. 2.0. # If a copy of the MPL was not distributed with this file, # You can obtain one at http://mozilla.org/MPL/2.0/. # # For further information see http://www.genivi.org/. ####### if(WITH_DOC) # Markdown FIND_PROGRAM(PANDOC_TOOL NAMES pandoc PATHS /bin /usr/bin /usr/local/bin) if(NOT PANDOC_TOOL) MESSAGE(FATAL_ERROR "Could not find pandoc for man page generation.") endif(NOT PANDOC_TOOL) set(MAN_SRC_DIR ${CMAKE_SOURCE_DIR}) set(MAN_BUILD_DIR ${CMAKE_BINARY_DIR}) add_custom_target(generate_doc ALL COMMAND ${PANDOC_TOOL} -s -f markdown -t html5 ${MAN_SRC_DIR}/README.md -o ${MAN_BUILD_DIR}/README.html COMMAND ${PANDOC_TOOL} -s -f markdown -t html5 ${MAN_SRC_DIR}/doc/dlt_for_developers.md -o ${MAN_BUILD_DIR}/doc/dlt_for_developers.html COMMAND ${PANDOC_TOOL} -s -f markdown -t html5 ${MAN_SRC_DIR}/doc/dlt_glossary.md -o ${MAN_BUILD_DIR}/doc/dlt_glossary.html COMMAND ${PANDOC_TOOL} -s -f markdown -t html5 ${MAN_SRC_DIR}/doc/dlt_offline_logstorage.md -o ${MAN_BUILD_DIR}/doc/dlt_offline_logstorage.html COMMAND ${PANDOC_TOOL} -s -f markdown -t html5 ${MAN_SRC_DIR}/doc/dlt_multinode.md -o ${MAN_BUILD_DIR}/doc/dlt_multinode.html COMMAND ${PANDOC_TOOL} -s -f markdown -t html5 ${MAN_SRC_DIR}/doc/dlt_extended_network_trace.md -o ${MAN_BUILD_DIR}/doc/dlt_extended_network_trace.html COMMAND ${PANDOC_TOOL} -s -f markdown -t html5 ${MAN_SRC_DIR}/doc/dlt_filetransfer.md -o ${MAN_BUILD_DIR}/doc/dlt_filetransfer.html COMMAND ${PANDOC_TOOL} -s -f markdown -t html5 ${MAN_SRC_DIR}/doc/dlt_kpi.md -o ${MAN_BUILD_DIR}/doc/dlt_kpi.html COMMAND ${PANDOC_TOOL} -s -f markdown -t html5 ${MAN_SRC_DIR}/doc/dlt_cdh.md -o ${MAN_BUILD_DIR}/doc/dlt_cdh.html) # Doxygen find_package(Doxygen) configure_file(${PROJECT_SOURCE_DIR}/doc/doxygen.cfg.cmake ${PROJECT_BINARY_DIR}/doc/doxygen.cfg @ONLY) add_custom_target (doc ALL COMMAND ${DOXYGEN_EXECUTABLE} ${PROJECT_BINARY_DIR}/doc/doxygen.cfg WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/doc ) FIND_PROGRAM(ASCIIDOC_TOOL NAMES asciidoc PATHS /bin /usr/bin /usr/local/bin) if(NOT ASCIIDOC_TOOL) MESSAGE(FATAL_ERROR "Could not find asciidoc for doc-manuals generation.") endif(NOT ASCIIDOC_TOOL) add_custom_target (doc-manuals ALL COMMAND mkdir -p ${PROJECT_BINARY_DIR}/doc/manuals COMMAND mkdir -p ${PROJECT_BINARY_DIR}/doc/manuals/images COMMAND cp ${PROJECT_SOURCE_DIR}/doc/images/* ${PROJECT_BINARY_DIR}/doc/manuals/images COMMAND ${ASCIIDOC_TOOL} -a TOC1 -o ${PROJECT_BINARY_DIR}/doc/manuals/README.html ${PROJECT_SOURCE_DIR}/README.md COMMAND ${ASCIIDOC_TOOL} -a TOC1 -o ${PROJECT_BINARY_DIR}/doc/manuals/dlt_glossary.html ${CMAKE_SOURCE_DIR}/doc/dlt_glossary.md COMMAND ${ASCIIDOC_TOOL} -a TOC1 -o ${PROJECT_BINARY_DIR}/doc/manuals/dlt_for_developers.html ${CMAKE_SOURCE_DIR}/doc/dlt_for_developers.md COMMAND ${ASCIIDOC_TOOL} -a TOC1 -o ${PROJECT_BINARY_DIR}/doc/manuals/dlt_offline_logstorage.html ${CMAKE_SOURCE_DIR}/doc/dlt_offline_logstorage.md COMMAND ${ASCIIDOC_TOOL} -a TOC1 -o ${PROJECT_BINARY_DIR}/doc/manuals/dlt_multinode.html ${CMAKE_SOURCE_DIR}/doc/dlt_multinode.md COMMAND ${ASCIIDOC_TOOL} -a TOC1 -o ${PROJECT_BINARY_DIR}/doc/manuals/dlt_extended_network_trace.html ${CMAKE_SOURCE_DIR}/doc/dlt_extended_network_trace.md COMMAND ${ASCIIDOC_TOOL} -a TOC1 -o ${PROJECT_BINARY_DIR}/doc/manuals/dlt_filetransfer.html ${CMAKE_SOURCE_DIR}/doc/dlt_filetransfer.md COMMAND ${ASCIIDOC_TOOL} -a TOC1 -o ${PROJECT_BINARY_DIR}/doc/manuals/dlt_kpi.html ${CMAKE_SOURCE_DIR}/doc/dlt_kpi.md COMMAND ${ASCIIDOC_TOOL} -a TOC1 -o ${PROJECT_BINARY_DIR}/doc/manuals/dlt_cdh.html ${CMAKE_SOURCE_DIR}/doc/dlt_cdh.md COMMAND ${ASCIIDOC_TOOL} -a TOC1 -o ${PROJECT_BINARY_DIR}/doc/manuals/dlt_design_specification.html ${PROJECT_SOURCE_DIR}/doc/dlt_design_specification.txt WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/doc ) endif(WITH_DOC) if(WITH_MAN) # Compress the man pages and install to proper place FIND_PROGRAM(GZIP_TOOL NAMES gzip PATHS /bin /usr/bin /usr/local/bin) if(NOT GZIP_TOOL) MESSAGE(FATAL_ERROR "Could not find gzip for man page compression.") endif(NOT GZIP_TOOL) FIND_PROGRAM(PANDOC_TOOL NAMES pandoc PATHS /bin /usr/bin /usr/local/bin) if(NOT PANDOC_TOOL) MESSAGE(FATAL_ERROR "Could not find pandoc for man page generation.") endif(NOT PANDOC_TOOL) set(MAN_SRC_DIR ${CMAKE_CURRENT_SOURCE_DIR}) set(MAN_BUILD_DIR ${PROJECT_BINARY_DIR}/doc) set(MD_SRC ${MAN_SRC_DIR}/dlt.conf.5.md ${MAN_SRC_DIR}/dlt-system.conf.5.md ${MAN_SRC_DIR}/dlt-convert.1.md ${MAN_SRC_DIR}/dlt-sortbytimestamp.1.md ${MAN_SRC_DIR}/dlt-daemon.1.md ${MAN_SRC_DIR}/dlt-receive.1.md ${MAN_SRC_DIR}/dlt-system.1.md ${MAN_SRC_DIR}/dlt-control.1.md ${MAN_SRC_DIR}/dlt-logstorage-ctrl.1.md ${MAN_SRC_DIR}/dlt-passive-node-ctrl.1.md ${MAN_SRC_DIR}/dlt-adaptor-stdin.1.md ${MAN_SRC_DIR}/dlt-adaptor-udp.1.md) set(MAN_SRC ${MAN_SRC_DIR}/dlt.conf.5 ${MAN_SRC_DIR}/dlt-system.conf.5 ${MAN_SRC_DIR}/dlt-convert.1 ${MAN_SRC_DIR}/dlt-sortbytimestamp.1 ${MAN_SRC_DIR}/dlt-daemon.1 ${MAN_SRC_DIR}/dlt-receive.1 ${MAN_SRC_DIR}/dlt-system.1 ${MAN_SRC_DIR}/dlt-control.1 ${MAN_SRC_DIR}/dlt-logstorage-ctrl.1 ${MAN_SRC_DIR}/dlt-passive-node-ctrl.1 ${MAN_SRC_DIR}/dlt-adaptor-stdin.1 ${MAN_SRC_DIR}/dlt-adaptor-udp.1) set(MAN_BUILD_SRC ${MAN_BUILD_DIR}/dlt.conf.5 ${MAN_BUILD_DIR}/dlt-system.conf.5 ${MAN_BUILD_DIR}/dlt-convert.1 ${MAN_BUILD_DIR}/dlt-sortbytimestamp.1 ${MAN_BUILD_DIR}/dlt-daemon.1 ${MAN_BUILD_DIR}/dlt-receive.1 ${MAN_BUILD_DIR}/dlt-system.1 ${MAN_BUILD_DIR}/dlt-control.1 ${MAN_BUILD_DIR}/dlt-logstorage-ctrl.1 ${MAN_BUILD_DIR}/dlt-passive-node-ctrl.1 ${MAN_BUILD_DIR}/dlt-adaptor-stdin.1 ${MAN_BUILD_DIR}/dlt-adaptor-udp.1) set(MAN_BUILD_GZ ${MAN_BUILD_DIR}/dlt.conf.5.gz ${MAN_BUILD_DIR}/dlt-system.conf.5.gz ${MAN_BUILD_DIR}/dlt-convert.1.gz ${MAN_BUILD_DIR}/dlt-sortbytimestamp.1.gz ${MAN_BUILD_DIR}/dlt-daemon.1.gz ${MAN_BUILD_DIR}/dlt-receive.1.gz ${MAN_BUILD_DIR}/dlt-system.1.gz ${MAN_BUILD_DIR}/dlt-control.1.gz ${MAN_BUILD_DIR}/dlt-logstorage-ctrl.1.gz ${MAN_BUILD_DIR}/dlt-passive-node-ctrl.1.gz ${MAN_BUILD_DIR}/dlt-adaptor-stdin.1.gz ${MAN_BUILD_DIR}/dlt-adaptor-udp.1.gz) add_custom_target(generate_man ALL COMMAND ${PANDOC_TOOL} -s -t man ${MAN_SRC_DIR}/dlt.conf.5.md -o ${MAN_BUILD_DIR}/dlt.conf.5 COMMAND ${PANDOC_TOOL} -s -t man ${MAN_SRC_DIR}/dlt-system.conf.5.md -o ${MAN_BUILD_DIR}/dlt-system.conf.5 COMMAND ${PANDOC_TOOL} -s -t man ${MAN_SRC_DIR}/dlt-convert.1.md -o ${MAN_BUILD_DIR}/dlt-convert.1 COMMAND ${PANDOC_TOOL} -s -t man ${MAN_SRC_DIR}/dlt-sortbytimestamp.1.md -o ${MAN_BUILD_DIR}/dlt-sortbytimestamp.1 COMMAND ${PANDOC_TOOL} -s -t man ${MAN_SRC_DIR}/dlt-daemon.1.md -o ${MAN_BUILD_DIR}/dlt-daemon.1 COMMAND ${PANDOC_TOOL} -s -t man ${MAN_SRC_DIR}/dlt-receive.1.md -o ${MAN_BUILD_DIR}/dlt-receive.1 COMMAND ${PANDOC_TOOL} -s -t man ${MAN_SRC_DIR}/dlt-system.1.md -o ${MAN_BUILD_DIR}/dlt-system.1 COMMAND ${PANDOC_TOOL} -s -t man ${MAN_SRC_DIR}/dlt-control.1.md -o ${MAN_BUILD_DIR}/dlt-control.1 COMMAND ${PANDOC_TOOL} -s -t man ${MAN_SRC_DIR}/dlt-logstorage-ctrl.1.md -o ${MAN_BUILD_DIR}/dlt-logstorage-ctrl.1 COMMAND ${PANDOC_TOOL} -s -t man ${MAN_SRC_DIR}/dlt-passive-node-ctrl.1.md -o ${MAN_BUILD_DIR}/dlt-passive-node-ctrl.1 COMMAND ${PANDOC_TOOL} -s -t man ${MAN_SRC_DIR}/dlt-adaptor-stdin.1.md -o ${MAN_BUILD_DIR}/dlt-adaptor-stdin.1 COMMAND ${PANDOC_TOOL} -s -t man ${MAN_SRC_DIR}/dlt-adaptor-udp.1.md -o ${MAN_BUILD_DIR}/dlt-adaptor-udp.1 COMMAND ${GZIP_TOOL} -c ${MAN_BUILD_DIR}/dlt.conf.5 > ${MAN_BUILD_DIR}/dlt.conf.5.gz COMMAND ${GZIP_TOOL} -c ${MAN_BUILD_DIR}/dlt-system.conf.5 > ${MAN_BUILD_DIR}/dlt-system.conf.5.gz COMMAND ${GZIP_TOOL} -c ${MAN_BUILD_DIR}/dlt-convert.1 > ${MAN_BUILD_DIR}/dlt-convert.1.gz COMMAND ${GZIP_TOOL} -c ${MAN_BUILD_DIR}/dlt-sortbytimestamp.1 > ${MAN_BUILD_DIR}/dlt-sortbytimestamp.1.gz COMMAND ${GZIP_TOOL} -c ${MAN_BUILD_DIR}/dlt-daemon.1 > ${MAN_BUILD_DIR}/dlt-daemon.1.gz COMMAND ${GZIP_TOOL} -c ${MAN_BUILD_DIR}/dlt-receive.1 > ${MAN_BUILD_DIR}/dlt-receive.1.gz COMMAND ${GZIP_TOOL} -c ${MAN_BUILD_DIR}/dlt-system.1 > ${MAN_BUILD_DIR}/dlt-system.1.gz COMMAND ${GZIP_TOOL} -c ${MAN_BUILD_DIR}/dlt-control.1 > ${MAN_BUILD_DIR}/dlt-system.1.gz COMMAND ${GZIP_TOOL} -c ${MAN_BUILD_DIR}/dlt-logstorage-ctrl.1 > ${MAN_BUILD_DIR}/dlt-logstorage-ctrl.1.gz COMMAND ${GZIP_TOOL} -c ${MAN_BUILD_DIR}/dlt-passive-node-ctrl.1 > ${MAN_BUILD_DIR}/dlt-passive-node-ctrl.1.gz COMMAND ${GZIP_TOOL} -c ${MAN_BUILD_DIR}/dlt-adaptor-stdin.1 > ${MAN_BUILD_DIR}/dlt-adaptor-stdin.1.gz COMMAND ${GZIP_TOOL} -c ${MAN_BUILD_DIR}/dlt-adaptor-udp.1 > ${MAN_BUILD_DIR}/dlt-adaptor-udp.1.gz) # If user has not set the base dir for man pages, use a default location set(MAN_INSTALL_DIR ${CMAKE_INSTALL_PREFIX}/share/man) install(FILES ${MAN_BUILD_DIR}/dlt.conf.5.gz ${MAN_BUILD_DIR}/dlt-system.conf.5.gz DESTINATION ${MAN_INSTALL_DIR}/man5 ) install(FILES ${MAN_BUILD_DIR}/dlt-convert.1.gz ${MAN_BUILD_DIR}/dlt-sortbytimestamp.1.gz ${MAN_BUILD_DIR}/dlt-daemon.1.gz ${MAN_BUILD_DIR}/dlt-receive.1.gz ${MAN_BUILD_DIR}/dlt-system.1.gz ${MAN_BUILD_DIR}/dlt-control.1.gz ${MAN_BUILD_DIR}/dlt-logstorage-ctrl.1.gz ${MAN_BUILD_DIR}/dlt-passive-node-ctrl.1.gz ${MAN_BUILD_DIR}/dlt-adaptor-stdin.1.gz ${MAN_BUILD_DIR}/dlt-adaptor-udp.1.gz DESTINATION ${MAN_INSTALL_DIR}/man1 ) endif(WITH_MAN) dlt-daemon-2.18.4/doc/dlt-adaptor-stdin.1.md000066400000000000000000000023621353342203500204150ustar00rootroot00000000000000% DLT-ADAPTOR-STDIN(1) # NAME **dlt-adaptor-stdin** - Forward input from stdin to DLT Daemon # SYNOPSIS **dlt-adaptor-stdin** \[**-a** apid\] \[**-c** ctid\] \[**-b**\] \[**-s**\] \[**-t** timeout\] \[**-h**\] # DESCRIPTION This is a small external program for forwarding input from stdin to DLT Daemon. ## OPTIONS -a : Set application ID to apid (default: SINA) -c : Set context ID tp ctid (default: SINC) -b : To flush the buffered logs while unregistering app -s : Set socket to Blocking mode if unix socket is used -t : Set timeout when sending messages at exit, in ms (default: 10000 = 10sec) -h : Show help # EXAMPLES Forward all dmesg to DLT Daemon without discarding any messages **dmesg | dlt-adaptor-stdin -b -s** Send DBUS messages to DLT Daemon using the program dbus-monitor **dbus-monitor | dlt-adaptor-stdin** # EXIT STATUS Non zero is returned in case of failure. # AUTHOR Saya Sugiura (ssugiura (at) jp.adit-jv (dot) com) # COPYRIGHT Copyright (C) 2019 Advanced Driver Information Technology, Bosch and DENSO. License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. # BUGS See Github issue: # SEE ALSO **dlt-daemon(1)** dlt-daemon-2.18.4/doc/dlt-adaptor-udp.1.md000066400000000000000000000023231353342203500200610ustar00rootroot00000000000000% DLT-ADAPTOR-UDP(1) # NAME **dlt-adaptor-udp** - Forward received UDP messages to DLT Daemon # SYNOPSIS **dlt-adaptor-udp** \[**-a** apid\] \[**-c** ctid\] \[**-p**\] \[**-h**\] # DESCRIPTION This is a small external program for forwarding received UDP messages to DLT Daemon. This also can be used for e.g. sending syslog messages to the DLT daemon. Therefore a syslog daemon called *syslog-ng* is necessary. This syslog daemon must be configured to send the syslog messages to a specific UDP port. For configuration of this syslog daemon, see the documentation for *syslog-ng*. This tools is already integrated into *dlt-system*. ## OPTIONS -a : Set application ID to apid (default: UDPA) -c : Set context ID tp ctid (default: UDPC) -p : Set receive port number for UDP messages (default: 47111) -h : Show help # EXIT STATUS Non zero is returned in case of failure. # AUTHOR Saya Sugiura (ssugiura (at) jp.adit-jv (dot) com) # COPYRIGHT Copyright (C) 2019 Advanced Driver Information Technology, Bosch and DENSO. License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. # BUGS See Github issue: # SEE ALSO **dlt-daemon(1)** dlt-daemon-2.18.4/doc/dlt-control.1.md000066400000000000000000000067471353342203500173370ustar00rootroot00000000000000% DLT-CONTROL(1) # NAME **dlt-control** - Send control messages to DLT Daemon # SYNOPSIS **dlt-control** \[**-v**\] \[**-h**\] \[**-S**\] \[**-R**\] \[**-y**\] \[**-b** baudrate\] \[**-e** ecuid\] \[**-a** id\] \[**-c** id\] \[**-s** id\] \[**-m** message\] \[**-x** message\] \[**-t** milliseconds\] \[**-l** level\] \[**-r** tracestatus\] \[**-d** loglevel\] \[**-f** tracestatus\] \[**-i** enable\] \[**-o**\] \[**-g**\] \[**-j**\] \[**-u**\] hostname/serial\_device\_name # DESCRIPTION Send control messages to DLT Daemon. This is useful when there is no client (e.g. DLT Viewer) available. It supports several control messages including: - Setting log level/trace level - Setting default log level/default trace level - Enable timing packets - Store configuration - Reset to factory default - Get logging information **Note** Use -u option instead of hostname/serial\_device\_name if Unix Socket is used. See example for detail. ## OPTIONS -v : Verbose mode -h : Usage -S : Send message with serial header (Default: Without serial header) -R : Enable resync serial header -y : Serial device mode -b : Serial device baudrate (Default: 115200) -e : Set ECU ID (Default: RECV) -a : Control message application id -c : Control message context id -s : Control message injection service id -m : Control message injection in ASCII -x : Control message injection in Hex e.g. 'ad 01 24 ef' -t : Timeout to terminate application (Default:1000) -l Set the log level (0=off - 6=verbose, default= -1) supported options: -l level -a apid -c ctid -l level -a abc* (set level for all ctxts of apps name starts with abc) -l level -a apid (set level for all ctxts of this app) -l level -c xyz* (set level for all ctxts whose name starts with xyz) -l level -c ctid (set level for the particular ctxt) -l level (set level for all the registered contexts) -r : Set the trace status (0=off - 1=on, default=255) supported options: -r tracestatus -a apid -c ctid -r tracestatus -a abc* (set status for all ctxts of apps name starts with abc) -r tracestatus -a apid (set status for all ctxts of this app) -r tracestatus -c xyz* (set status for all ctxts whose name starts with xyz) -r tracestatus -c ctid (set status for the particular ctxt) -r tracestatus (set status for all the registered contexts) -d : Set the default log level (0=off - 5=verbose) -f : Set the default trace status (0=off - 1=on) -i : Enable timing packets (0=off - 1=on) -o : Store configuration -g : Reset to factory default -j : Get log info -u : unix port # EXAMPLES Change log level of application "APP1" to DEBUG with unix port **dlt-control -a APP1 -l 5 -u** Change log level of application "APP1" and context "CON1" to ERROR **dlt-control -a APP1 -c CON1 -l 2 localhost** Get logging information of current running applications with unix port (IPC: Unix Socket) **dlt-control -j -u** Get logging information of current running applications (IPC:FIFO) **dlt-control -j localhost** # EXIT STATUS Non zero is returned in case of failure. # AUTHOR Saya Sugiura (ssugiura (at) jp.adit-jv (dot) com) # COPYRIGHT Copyright (C) 2019 Advanced Driver Information Technology, Bosch and DENSO. License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. # BUGS See Github issue: # SEE ALSO **dlt-daemon(1)** dlt-daemon-2.18.4/doc/dlt-convert.1.md000066400000000000000000000032661353342203500173300ustar00rootroot00000000000000% DLT-CONVERT(1) # NAME **dlt-convert** - Convert DLT Logging files into ASCII # SYNOPSIS **dlt-convert** \[**-h**\] \[**-a**\] \[**-x**\] \[**-m**\] \[**-s**\] \[**-o** filename\] \[**-v**\] \[**-c**\] \[**-f** filterfile\] \[**-b** number\] \[**-e** number\] \[**-w**\] file1 \[file2\] \[file3\] # DESCRIPTION Read DLT files, print DLT messages as ASCII and store the messages again. Use Ranges and Output file to cut DLT files. Use two files and Output file to join DLT files. ## OPTIONS -h : Display a short help text. -a : Print DLT file; payload as ASCII. -x : Print DLT file; payload as hex. -m : Print DLT file; payload as hex and ASCII. -s Print DLT file; only headers. -o : Output messages in new DLT file. -v : Verbose mode. -c : Count number of messages. -f : Enable filtering of messages. -b : First messages to be handled. -e : Last message to be handled. -w : Follow dlt file while file is increasing. # EXAMPLES Convert DLT file into ASCII: **dlt-convert -a mylog.dlt** Cut a specific range, e.g. from message 1 to message 3 from a file called log.dlt and store the result to a file called newlog.dlt: **dlt-convert -b 1 -e 3 -o newlog.dlt log.dlt** Paste two dlt files log1.dlt and log2.dlt to a new file called newlog.dlt:: **dlt-convert -o newlog.dlt log1.dlt log2.dlt** # EXIT STATUS Non zero is returned in case of failure. # AUTHOR Alexander Wenzel (alexander.aw.wenzel (at) bmw (dot) de) # COPYRIGHT Copyright (C) 2015 BMW AG. License MPL-2.0: Mozilla Public License version 2.0 . # BUGS See Github issue: # SEE ALSO **dlt-daemon(1)** dlt-daemon-2.18.4/doc/dlt-daemon.1.md000066400000000000000000000034221353342203500171050ustar00rootroot00000000000000% DLT-DAEMON(1) # NAME **dlt-daemon** - Diagnostic Log and Trace daemon # SYNOPSIS **dlt-daemon** \[**-h**\] \[**-d**\] \[**-c** filename\] \[**-t** directory\] \[**-p** port\] # DESCRIPTION The DLT daemon is the central place where logs and traces are gathered from different applications, stored temporarily or permanently and transferred to a DLT client application, which can run directly on the GENIVI system or more likely on a external tester device. ## OPTIONS -h : Display a short help text. -d : Daemonize, needed in System V init systems. -c : Load an alternative configuration file. By default the configuration file /etc/dlt.conf is loaded. -t : Directory for local fifo and user-pipes (Default: /tmp). Applications wanting to connect to a daemon using a custom directory need to be started with the environment variable DLT_PIPE_DIR set appropriately. -p : Port to monitor for incoming requests (Default: 3490) Applications wanting to connect to a daemon using a custom port need to be started with the environment variable DLT_DAEMON_TCP_PORT set appropriately. # EXAMPLES Start DLT daemon in background mode: **dlt-daemon -d** Start DLT daemon with own configuration: **dlt-daemon -c ~/my-dlt-configuration.cfg** Start DLT daemon with custom pipes directory: **dlt-daemon -t ~/dlt_pipes** Start DLT daemon listening on custom port 3500: **dlt-daemon -p 3500** # EXIT STATUS Non zero is returned in case of failure. # AUTHOR Alexander Wenzel (alexander.aw.wenzel (at) bmw (dot) de) # COPYRIGHT Copyright (C) 2016 BMW AG. License MPL-2.0: Mozilla Public License version 2.0 . # BUGS See Github issue: # SEE ALSO **dlt.conf(5)**, **dlt-system(1)** dlt-daemon-2.18.4/doc/dlt-logstorage-ctrl.1.md000066400000000000000000000026531353342203500207570ustar00rootroot00000000000000% DLT-LOGSTORAGE-CTRL(1) # NAME **dlt-logstorage-ctrl** - Trigger DLT Daemon to start/stop using an offline logstorage device # SYNOPSIS **dlt-logstorage-ctrl** \[**-h**\] \[**-c** ctype\] \[**-p** path\] \[**-e** ecu\] \[**-p\**\] \[**-t** timeout\] \[**-v**\] # DESCRIPTION Send a trigger to DLT Daemon to connect/disconnect a certain offline logstorage device # OPTIONS -h : Display a short help text. -c : Specify connection type: connect = 1, disconnect = 0. -d : Run as daemon: prop = use proprietary handler -p : Mount point path. -e : Specify the ECU ID. Default is: ECU1. -t : Specify connection timeout. Default is: 10s. # EXAMPLES Activate the offline logstorage device mounted on /mnt/dltlog **dlt-logstorage-ctrl -c 1 -p /mnt/dltlog** Deactivate the offline logstorage device mounted on /mnt/dltlog **dlt-logstorage-ctrl -c 0 -p /mnt/dltlog** Run logstorage control application as daemon listen to udev events **dlt-logstorage-ctrl -d** # EXIT STATUS Non zero is returned in case of failure. # AUTHOR Christoph Lipka (clipka (at) jp.adit-jv (dot) com), Syed Hameed (shameed (at) jp.adit-jv (dot) com) # COPYRIGHT Copyright (C) 2015 Advanced Driver Information Technology, Bosch and DENSO. License MPL-2.0: Mozilla Public License version 2.0 . # BUGS See Github issue: # SEE ALSO **dlt-daemon(1)** dlt-daemon-2.18.4/doc/dlt-passive-node-ctrl.1.md000066400000000000000000000024641353342203500212060ustar00rootroot00000000000000% DLT-PASSIVE-NODE-CTRL(1) # NAME **dlt-passive-node-ctrl** - Send a trigger to DLT daemon to (dis)connect a passive node or get current passive node status # SYNOPSIS **dlt-passive-node-ctrl** \[**-h**\] \[**-c**\] \[**-n** ecu\] \[**-s**\] \[**-t** timeout\] \[-v\] # DESCRIPTION Send a trigger to DLT daemon to (dis)connect a passive node or get current passive node status ## OPTIONS -h : Usage -c : Connection status (1 - connect, 0 - disconnect) -n : Passive Node identifier (e.g. ECU2) -s : Show passive node(s) connection status -t : Specify connection timeout (Default: 10s) -v : Set verbose flag (Default:0) # EXAMPLES Get status about connected passives nodes **dlt-passive-node-ctrl -s** Connect to passive node ECU2 **dlt-passive-node-ctrl -c 1 -n ECU2** Disconnect to passive node ECU2 **dlt-passive-node-ctrl -c 0 -n ECU2** # EXIT STATUS Non zero is returned in case of failure. # AUTHOR Christoph Lipka (clipka (at) jp.adit-jv (dot) com), Syed Hameed (shameed (at) jp.adit-jv (dot) com) # COPYRIGHT Copyright (C) 2015 Advanced Driver Information Technology, Bosch and DENSO. License MPL-2.0: Mozilla Public License version 2.0 . # BUGS See Github issue: # SEE ALSO **dlt-daemon(1)** dlt-daemon-2.18.4/doc/dlt-receive.1.md000066400000000000000000000042741353342203500172720ustar00rootroot00000000000000% DLT-RECEIVE(1) # NAME **dlt-receive** - Console based client for DLT Logging # SYNOPSIS **dlt-receive** \[**-h**\] \[**-a**\] \[**-x**\] \[**-m**\] \[**-s**\] \[**-o** filename\] \[**-c** limit\] \[**-v**\] \[**-y**\] \[**-b** baudrate\] \[**-e** ecuid\] \[**-f** filterfile\] hostname/serial_device_name # DESCRIPTION Receive DLT messages from DLT daemon and print or store the messages. ## OPTIONS -h : Display a short help text. -a : Print DLT file; payload as ASCII. -x : Print DLT file; payload as hex. -m : Print DLT file; payload as hex and ASCII. -s : Print DLT file; only headers. -o : Output messages in new DLT file. -c : Set limit when storing messages in file. When limit is reached, a new file is opened. Use K,M,G as suffix to specify kilo-, mega-, giga-bytes respectively, e.g. 1M for one megabyte (Default: unlimited). -v : Verbose mode. -y : Serial device mode. -b : Serial device baudrate (Default: 115200). -e : Set ECU ID (Default: RECV). -f : Enable filtering of messages. # EXAMPLES Print received message headers received from a dlt-daemon running on localhost:: **dlt-receive -s localhost** Print received message headers received from a serila interface:: **dlt-receive -s -y /dev/ttySO** Store received message headers from a dlt-daemon to a log file called log.dlt and filter them for e.g. Application ID ABCD and Context ID EFGH (Write:ABCD EFGH as single line to a file called filter.txt):: **dlt-receive -s -o log.dlt -f filter.txt localhost** Store incoming messages in file(s) and restrict file sizes to 1 megabyte. If limit is reached, log.dlt will be renamed into log.0.dlt, log.1.dlt, ... No files will be overwritten in this mode:: **dlt-receive -o log.dlt -c 1M localhost** # EXIT STATUS Non zero is returned in case of failure. # NOTES Be aware that dlt-receive will never delete any files. Instead, it creates a new file. # AUTHOR Alexander Wenzel (alexander.aw.wenzel (at) bmw (dot) de) # COPYRIGHT Copyright (C) 2015 BMW AG. License MPL-2.0: Mozilla Public License version 2.0 . # BUGS See Github issue: # SEE ALSO **dlt-daemon(1)** dlt-daemon-2.18.4/doc/dlt-sortbytimestamp.1.md000066400000000000000000000046301353342203500211120ustar00rootroot00000000000000% DLT-SORTBYTIMESTAMP(1) # NAME **dlt-sortbytimestamp** - Re-order DLT Logging files according to message creation time # SYNOPSIS **dlt-sortbytimestamp** \[**-h**\] \[**-v**\] \[**-c**\] \[**-f** filterfile\] \[**-b** number\] \[**-e** number\] dltfile_in dltfile_out # DESCRIPTION By default messages in DLT files are ordered according to the time the logger received them. This can unhelpful when tracing a sequence of events on a busy multi-threaded/multi-core system, because thread pre-emption combined with multiple processes attempting to log messages simultaneously means that the order in which the messages are received may vary significantly from the order in which they were created. *dlt-sortbytimestamp* re-orders a DLT input file's messages according their creation timestamp, and writes them to an output DLT file. # IMPORTANT NOTE Message timestamps are recorded relative to boot time. DLT files can contain messages from more than one reboot cycle. Because timestamping is reset to zero at each boot, simply running *dlt-sortbytimestamp* against a multi-boot-cycle DLT input file will produce a tangled mess. Use the *-b* and/or *-e* options to specify a range of messages within a single reboot cycle and all will be well. Hint: use *dlt-viewer* to ascertain the endpoints of the range in question. # OPTIONS -h : Display a short help text. -v : Verbose mode. Repeat to give more information. -c : Count number of messages. -f : Enable filtering of messages. Incompatible with range options. -b : First message to be handled. Zero based index. -e : Last message to be handled. Zero based index. # EXAMPLES Sort an entire file by message timestamp: **dlt-sortbytimestamp input.dlt output.dlt** Sort a specific range, e.g. from message 1,000,000 to message 1,500,000 from a file called input.dlt and store the result in a file called output.dlt: **dlt-sortbytimestamp -b 1000000 -e 1500000 input.dlt output.dlt** # EXIT STATUS Non zero is returned in case of failure. # AUTHOR Jonathan Sambrook (jonathan.sambrook (at) codethink (dot) co (dot) uk) Alexander Wenzel (alexander.aw.wenzel (at) bmw (dot) de) # COPYRIGHT Copyright (C) 2018 Codethink Ltd. Copyright (C) 2015 BMW AG. License MPL-2.0: Mozilla Public License version 2.0 . # BUGS See Github issue: # SEE ALSO **dlt-daemon(1)**, **dlt-convert(1)** dlt-daemon-2.18.4/doc/dlt-system.1.md000066400000000000000000000023001353342203500171600ustar00rootroot00000000000000% DLT-SYSTEM(1) # NAME **dlt-system** - DLT system logging process # SYNOPSIS **dlt-system** \[**-h**\] \[**-d**\] \[**-c** filename\] #DESCRIPTION The DLT system logging process is the central application, which logs system information from the platform. It provides the features filetransfer, syslog adapater, logging of any kind of files and procfilesystem logger. The individual features can be enabled and disabled in the configuration file. dlt-system loads by default the configuration file /etc/dlt-system.conf. ## OPTIONS -h : Display a short help text. -d : Daemonize, needed in System V init systems. -c : Load an alternative configuration file. By default the configuration file /etc/dlt.conf is loaded. # EXAMPLES Start DLT system with custom configuration: **dlt-system -c ~/my-configuration.cfg** # EXIT STATUS Non zero is returned in case of failure. # AUTHOR Alexander Wenzel (alexander.aw.wenzel (at) bmw (dot) de) # COPYRIGHT Copyright (C) 2015 BMW AG. License MPL-2.0: Mozilla Public License version 2.0 . # BUGS See Github issue: # SEE ALSO **dlt-system.conf(5)**, **dlt-daemon(1)** dlt-daemon-2.18.4/doc/dlt-system.conf.5.md000066400000000000000000000132011353342203500201120ustar00rootroot00000000000000% DLT-SYSTEM.CONF(5) # NAME **dlt-system.conf** - DLT system process configuration file # DESCRIPTION The DLT system logging process is the central application, which logs system information from the platform. It provides the features filetransfer, syslog adapater, logging of any kind of files and procfilesystem logger. The individual features can be enabled and disabled in the configuration file. The configuration file dlt-system.conf allows to configure the different runtime behaviour of dlt-system. The configuration file is loaded during startup of dlt-system. dlt-system loads by default the configuration file /etc/dlt-system.conf. An alternative configuration file can be loaded with the option -c. # GENERAL OPTIONS ## ApplicationId The application Id used for the dlt-system process. Default: SYS # SHELL OPTIONS ## ShellEnable Enable the Shell for command line injections. Be careful when you enable this feature. The user can send any kind of shell commands. The commands are executed with the rights of the dlt-system process. Dlt-system is started by default as user genivi. Default: 0 # SYSLOG ADAPTER OPTIONS ## SyslogEnable If this option is set to 1, the syslog adapter feature is enabled. Default: 0 ## SyslogContextId This value defines context id of the syslog adapter. Default: SYSL ## SyslogPort This value defines the UDP port opened for receiving log messages from syslog. Default: 47111 # SYSTEMD JOURNAL ADAPTER OPTIONS ## JournalEnable Enable the Systemd Journal Adapter. This feature is only available, when dlt is compiled with the option "WITH_SYSTEMD_JOURNAL". Dlt-system is started by default as user genivi, see dlt-system.service file. The user genivi must be added to one of the groups 'adm', 'wheel' or 'systemd-journal' to have access to all journal entries. Default: 0 ## JournalContextId The Context Id of the journal adapter. Default: JOUR ## JournalCurrentBoot Show only log entries of current boot and follow. If JournalCurrentBoot and JournalFollow are not set all persistent journal entries will be logged. Default: 1 ## JournalFollow Show only the last 10 entries and follow. Default: 0 ## JournalMapLogLevels Map journal log levels to DLT log levels. - 0 Emergency DLT_LOG_FATAL - 1 Alert DLT_LOG_FATAL - 2 Critical DLT_LOG_FATAL - 3 Error DLT_LOG_ERROR - 4 Warning DLT_LOG_WARN - 5 Notice DLT_LOG_INFO - 6 Informational DLT_LOG_INFO - 7 Debug DLT_LOG_DEBUG Default: 1 # FILETRANSFER OPTIONS ## FiletransferEnable Enable the Filetransfer feature. 0 = disabled, 1 = enabled Default: 0 ## FiletransferContextId The Context Id of the filetransfer. Default: FILE ## FiletransferTimeStartup Time in seconds after startup of dlt-system when first file is transfered. Default: 0 ## FiletransferTimeDelay Time in seconds to wait between deletion of transferred file and start of next file transfer. Default: 10 ## FiletransferTimeoutBetweenLogs Time in seconds to wait between two file transfer logs of a single file to DLT. Default: 10 ## FiletransferDirectory You can define multiple file transfer directories. Define the directory to watch, whether to compress the file with zlib and the zlib compression level. For parsing purposes, FiletransferCompressionLevel must be the last one of three values. ## FiletransferCompression See FiletransferDirectory option for explanation. Default: 0 ## FiletransferCompressionLevel See FiletransferDirectory option for explanation. Default: 5 # LOG FILES OPTIONS ## LogFileEnable If this option is set to 1, the log files feature is enabled. Default: 0 ## LogFileFilename This value sets the full filename path to the file, which should be logged. ## LogFileMode This value defines in which operation mode the file is logged. In mode 1 the file is only logged once when dlt-system is started. In mode 2 the file is logged regularly every time LogFileTimeDelay timer elapses. 0 = off, 1 = startup only, 2 = regular ## LogFileTimeDelay This value is used in mode 3 and defines the number of seconds, after which the defined file is logged. ## LogFileContextId This value defines the context id, which is used for logging the file. # LOG PROCESSES OPTIONS ## LogProcessesEnable Enable the logging of processes. 0 = disabled, 1 = enabled Default: 0 ## LogProcessesContextId This value defines the context id, which is used for logging processes files. Default: PROC ## LogProcessName This value defines the name of the process to be logged, as used in the file stat of each process. If the value is defined as *, all processes are logged. ## LogProcessFilename This value sets the relative filename path to the file, which should be logged. The path is relative to the procfilesystem folder of the process. ## LogProcessMode This value the defines in which operation mode this process file is logged. In mode 1 the file is only logged once when dlt-system is started. In mode 2 the file is logged regularly every time LogFileTimeDelay timer elapses. 0 = off, 1 = startup only, 2 = regular. Default: 0 ## LogProcessTimeDelay This value is used in mode 3 and defines the number of seconds, after which the defined procfilesystem file is logged. Default: 0 # AUTHOR Alexander Wenzel (alexander.aw.wenzel (at) bmw (dot) de) # COPYRIGHT Copyright (C) 2015 BMW AG. License MPL-2.0: Mozilla Public License version 2.0 . # BUGS See Github issue: # SEE ALSO **dlt-system(1)**, **dlt-daemon(1)** dlt-daemon-2.18.4/doc/dlt.conf.5.md000066400000000000000000000234171353342203500166020ustar00rootroot00000000000000% DLT.CONF(5) # NAME **dlt.conf** - DLT daemon configuration file # DESCRIPTION The DLT daemon is the central application which gathers logs and traces from different applications, stores them temporarily or permanently and transfers them to a DLT client application, which could run directly on the GENIVI system or more likely on some external tester device. The configuration file dlt.conf allows to configure the different runtime behaviour of the dlt-daemon. It is loaded during startup of dlt-daemon. # GENERAL OPTIONS ## Verbose Start daemon in debug mode, so that all internal debug information is printed out on the console. Default: Off ## Daemonize If set to 1 DLT daemon is started in background as daemon. This option is only needed in System V init systems. In systemd based startup systems the daemon is started by spawning own process. Default: 0 ## SendSerialHeader If set to 1 DLT daemon sends each DLT message to the client with prepanding the serial header "DLS0x01". Default: 0 ## SendContextRegistration If set to 1 each context which is registered from an application in the DLT daemon generates a message to inform the DLT client about the new context. Default: 1 ## SendMessageTime If set to 1 DLt daemon sends each second a DLT control message to the client with the current timestamp from the system. Default: 0 ## ECUId This value sets the ECU Id, which is sent with each DLT message. Default: ECU1 ## SharedMemorySize This value sets the size of the shared memory, which is used to exchange DLT messages between applications and daemon. This value is defined in bytes. If this value is changed the system must be rebooted to take effect. Default: 100000 ## PersistanceStoragePath This is the directory path, where the DLT daemon stores its runtime configuration. Runtime configuration includes stored log levels, trace status and changed logging mode. Default: /tmp ## LoggingMode The logging console for internal logging of dlt-daemon. 0 = log to stdout, 1 = log to syslog, 2 = log to file (see LoggingFilename) Default: 0 ## LoggingLevel The internal log level, up to which logs are written. LOG_EMERG = 0, LOG_ALERT = 1, LOG_CRIT = 2, LOG_ERR = 3, LOG_WARNING = 4, LOG_NOTICE = 5, LOG_INFO = 6, LOG_DEBUG = 7 Default: 6 ## LoggingFilename If LoggingMode is set to 2 logs are written to the file path given here. Default: /tmp/dlt.log ## TimeOutOnSend Socket timeout in seconds for sending to clients. Default: 4 ## RingbufferMinSize The minimum size of the Ringbuffer, used for storing temporary DLT messages, until client is connected. Default: 500000 ## RingbufferMaxSize The max size of the Ringbuffer, used for storing temporary DLT messages, until client is connected. Default: 10000000 ## RingbufferStepSize The step size the Ringbuffer is increased, used for storing temporary DLT messages, until client is connected. Default: 500000 ## ContextLogLevel Initial log-level that is sent when an application registers. DLT_LOG_OFF = 0, DLT_LOG_FATAL = 1, DLT_LOG_ERROR = 2, DLT_LOG_WARN = 3, DLT_LOG_INFO = 4, DLT_LOG_DEBUG = 5, DLT_LOG_VERBOSE = 6 Default: 4 ## ContextTraceStatus Initial trace-status that is sent when an application registers. DLT_TRACE_STATUS_OFF = 0, DLT_TRACE_STATUS_ON = 1 Default: 0 ## ForceContextLogLevelAndTraceStatus Force log level and trace status of contexts to not exceed "ContextLogLevel" and "ContextTraceStatus". If set to 1 (ON) whenever a context registers or changes the log-level it has to be lower or equal to ContextLogLevel. Default: 0 # GATEWAY CONFIGURATION ## GatewayMode Enable Gateway mode Default: 0 ## GatewayConfigFile Read gateway configuration from another location Default: /etc/dlt_gateway.conf # Permission configuration DLT daemon runs with e.g. User: genivi_dlt Group: genivi_dlt DLT user applications run with different user and group than dlt-daemon but with supplimentory group: dlt_user_apps_group /dlt FIFO will be created by dlt-daemon with User: genivi_dlt Group: dlt_user_apps_group Permission: 620 so that only dlt-daemon can read and only processes in dlt_user_apps_group can write. /dltpipes will be created by dlt-daemon with User: genivi_dlt Group: genivi_dlt Permission: 3733 (i.e Sticky bit and SGID turned on) /dltpipes/dlt FIFO will be created by dlt application (user lib) with User: Group: genivi_dlt (inherited from dltpipes/ due to SGID) Permission: 620 Thus DLT user applications (and also or attackers) can create the dlt FIFO (for communication from dlt-daemon to DLT user application) under /dltpipes/. Since sticky bit is set the applications who creates the FIFO can only rename/delete it. Since SGID of /dltpipes is set the group of dlt FIFO will be genivi_dlt which enables dlt daemon to have write permission on all the dlt FIFO. One dlt user application cannot access dlt FIFO created by other dlt user application(if they run with different user). Owner group of daemon FIFO directory(Default: /tmp/dlt) (If not set, primary group of dlt-daemon process is used). Application should have write permission to this group for tracing into dlt. For this opton to work, dlt-daemon should have this group in it's supplementary group. ## DaemonFifoGroup Owner group of daemon FIFO directory (If not set, primary group of dlt-daemon process is used) Application should have write permission to this group for tracing into dlt For this opton to work, dlt-daemon should have this group in it's Supplementary group Default: group of dlt-daemon process (/tmp/dlt) # CONTROL APPLICATION OPTIONS ## ControlSocketPath Path to control socket. Default: /tmp/dlt-ctrl.sock # OFFLINE TRACE OPTIONS ## OfflineTraceDirectory Store DLT messages to local directory, if not set offline Trace is off. Default: /tmp ## OfflineTraceFileSize This value defines the max size of a offline trace file, if offline trace is enabled. This value is defined in bytes. If the files size of the current used log file is exceeded, a new log file is created. Default: 1000000 ## OfflineTraceMaxSize This value defines the max offline Trace memory size, if offline trace is enabled. This value is defined in bytes. If the overall offline trace size is excedded, the oldest log files are deleted, until a new trace file fits the overall offline trace max size. Default: 4000000 ## OfflineTraceFileNameTimestampBased Filename timestamp based or index based. 1 = timestamp based, 0 = index based Default: Function is disabled # LOCAL CONSOLE OUTPUT OPTIONS ## PrintASCII Prints each received DLT message from the application in ASCII to the local console. This option should only be anabled for debugging purpose. Default: Function is disabled ## PrintHex Prints each received DLT message from the application in ASCII to the local console. The payload is printed in Hex. This option should only be anabled for debugging purpose. Default: Function is disabled ## PrintHeadersOnly Prints each received DLT message from the application in ASCII to the local console. Only the header is printed. This option should only be anabled for debugging purpose. Default: Function is disabled # SERIAL CLIENT OPTIONS ## RS232DeviceName If this value is set to a serial device name, e.g. /dev/ttyS0, a serial port is used for logging to a client. Default: Serial port for logging is disabled ## RS232Baudrate The used serial baud rate, if serial loggin is enabled. The RS232DeviceName must be set to enable serial logging. Default: 115200 ## RS232SyncSerialHeader If serial logging is enabled, each received DLT message is checked to contain a serial header. If the DLT message contains no serial header, the message is ignored. Default: Function is disabled # TCP CLIENT OPTIONS ## TCPSyncSerialHeader Each received DLT message on a TCP connection is checked to contain a serial header. If the DLT message contains no serial header, the message is ignored. Default: Function is disabled # ECU SOFTWARE VERSION OPTIONS ## SendECUSoftwareVersion Periodically send ECU version info. 0 = disabled, 1 = enabled Default: Function is disabled # PathToECUSoftwareVersion Absolute path to file storing version information - if disabled the DLT version will be send. Default: Function is disabled. # TIMEZONE INFO OPTIONS # SendTimezone Periodically send timezone info. 0 = disabled, 1 = enabled Default: Function is disabled # OFFLINE LOGSTORAGE OPTIONS ## OfflineLogstorageMaxDevices Maximum devices to be used as offline logstorage devices. 0 = disabled, 1 .. DLT_OFFLINE_LOGSTORAGE_MAX_DEVICES Default: 0 (Function is disabled) ## OfflineLogstorageDirPath Path to store DLT offline log storage messages. Default: off ## OfflineLogstorageTimestamp Appends timestamp in log file name. 0 = disabled, 1 = enabled Default: 0 ## OfflineLogstorageDelimiter Appends delimiter in log file name, only punctuation characters allowed. Default: _ ## OfflineLogstorageMaxCounter Wrap around value for log file count in file name. Default: UINT_MAX ## OfflineLogstorageCacheSize Maximal used memory for log storage cache in KB. Default: 30000 KB ## UDPConnectionSetup Enable or disable UDP connection. 0 = disabled, 1 = enabled ## UDPMulticastIPAddress The address on which daemon multicasts the log messages ## UDPMulticastIPPort The Multicase IP port. Default: 3491 # AUTHOR Alexander Wenzel (alexander.aw.wenzel (at) bmw (dot) de) # COPYRIGHT Copyright (C) 2015 BMW AG. License MPL-2.0: Mozilla Public License version 2.0 . # BUGS See Github issue: # SEE ALSO **dlt-daemon(1)**, **dlt-system(1)** dlt-daemon-2.18.4/doc/dlt_cdh.md000066400000000000000000000056711353342203500163330ustar00rootroot00000000000000# DLT Core Dump Handler Back to [README.md](../README.md) ## Overview When a program crash occurs on the system, the Core Dump Handler is triggered to extract relevant information from the core dump generated by the system. It stores this extracted information in the ECU's file system as Core Dump Handler Files. These files are transported via the [DLT Filetransfer](dlt_filetransfer.md) mechanism. The transferred information can be combined and integrated into the developer toolchain (gdb, Release SW, etc.). ![alt text](images/dlt_core_dump_handler.png "DLT CDH") ## Integration ### To build the core dump handler Add `-DWITH_DLT_COREDUMPHANDLER=ON -DTARGET_CPU_NAME={i686|x86_64}` options to cmake. The core dump handler code currently supports the i686 and x86\_64 architecture. ### Temporary activation as replacement for default crash handler until next reboot As *root* (not sudo) execute the following: `echo "|/usr/local/bin/dlt-cdh %t %p %s %e" > /proc/sys/kernel/core_pattern` NOTE: replace */usr/local/bin* with the path dlt-cdh has been installed to. This instructs the kernel to pipe a core dump as standard input to dlt-cdh together with the following parameters: - %t time of dump - %p PID of dumped process - %s number of signal causing dump - %e executable filename See `man core` for details. ### Persistent activation as replacement for default crash handler In */usr/lib/sysctl.d/* the file *50-coredump.conf* has to be created which is done automatically by `make install` Unfortunately - at least on Fedora systems - abrt has to be removed with `yum remove abrtd*` because it ruthlessly overwrites our change at every boot. The core dump handler can be activated then without reboot by running `sysctl -p /usr/lib/sysctl.d/50-coredump.conf` ### Configuration of [DLT Filetransfer](dlt_filetransfer.md) for usage with dlt-cdh Make sure the following is set in the "Filetransfer Manager" section of */etc/dlt-system.conf*: ``` ... FiletransferEnable = 1 ... FiletransferDirectory = /var/core ... ``` ### Generation of core dump When a crash happens the kernel invokes dlt-cdh and passes it the core dump as standard input. dlt-cdh does the following tasks: - check if enough disk space available - create target directories if not existing: - /var/core - /var/core\_tmp - /tmp/.core\_locks - clean /var/core\_tmp - retrieve context data mainly from /proc fs of the crashed process to a temporary context file in text format - initialise core dump - read ELF headers and notes to temporary core dump output file - move context file and core dump to /var/core - create id which identifies the crash After the files have been moved to /var/core the [DLT Filetransfer](dlt_filetransfer.md) mechanism ensures that they are sent to connected clients. ## AUTHOR Lutz Helwing ## COPYRIGHT Copyright (C) 2011 - 2015 BMW AG. License MPL-2.0: Mozilla Public License version 2.0 . dlt-daemon-2.18.4/doc/dlt_design_specification.txt000066400000000000000000001107731353342203500221650ustar00rootroot00000000000000//// # SPDX license identifier: MPL-2.0 # # Copyright (C) 2011-2015, BMW AG # # This file is part of GENIVI Project DLT - Diagnostic Log and Trace. # # This Source Code Form is subject to the terms of the # Mozilla Public License (MPL), v. 2.0. # If a copy of the MPL was not distributed with this file, # You can obtain one at http://mozilla.org/MPL/2.0/. # # For further information see http://www.genivi.org/. //// DLT Design Specification ======================== Alexander Wenzel 0.0.1, 2012/10/10: Initial version image::images/genivilogo.png[width=128] *This document is not up to date* == Purpose This document specifies the usage of the DLT daemon v2 and also the internal functionality of the DLT daemon v2. The DLT daemon v2 is a complete rework of the DLT daemon v1, which is part of the GENIVI 1.0 release. The DLT daemon is the central place where logs and traces are gathered from different applications, stored temporarily or permanently and transferred to a DLT client application, which can run directly on the GENIVI system or more likely on a external tester device. The DLT client component is described in an extra document. The DLT daemon component is based on the AUTOSAR 4.0 standard DLT. == Overview .DLT Architecture image::images/dlt_overview.png[] The DLT daemon is the central component in GENIVI, which gathers all logs and traces from the DLT user applications. The logs and traces are stored optionally directly in a file in the ECU. The DLT daemon forwards all logs and traces to a connected DLT client. The DLT client can send control messages to the daemon, e.g. to set individual log levels of applications and contexts or get the list of applications and contexts registered in the DLT daemon. == Architecture === DLT daemon The DLT daemon is the central component between the DLT clients and one or more applications using the DLT user library. ==== Overview The DLT daemon communicates with the DLT clients over TCP/IP connections or over a serial line (the message format is specified in the DLT AUTOSAR Standard), with the applications using the DLT user library over named pipes (FIFOs) or UNIX_SOCKET based on compile time configuration. More details concerning the exchanged user messages and their content can be found in chapter chapter 6.3. The main time, the DLT daemon executes a main loop, in which file and socket descriptors are watched (via poll()). If a message is received, the DLT daemon reacts. Additionally, a thread is implemented, which if enabled sends each second a keep-alive message to all connected DLT clients. Here is a rough schematic, how the DLT daemon is structured: .DLT Overview image::images/dlt_architecture.png[] ==== Initialization During initialization of the DLT daemon, the following steps occur: * Option handling * Initialization of logging facility for the DLT daemon application. The DLT daemon application by itself prints to screen, if not in daemon mode. In daemon mode, it uses the syslog daemon for log messages of the DLT daemon application. * Then the daemon enters initialization phase 1: ** Enter daemon mode, if started as daemon ** Initialize output of messages to local file ** Parse filter file, if specified; then set filters for file storage ** Setup signal handler ** Open DLT output file, if specified * After phase 1, the daemon initializes the connection handling: ** Delete, create and open its own named FIFO /tmp/dlt or UNIX_SOCKET ** Open, bind and listen to TCP socket for incoming connections ** Setup and open serial device, if specified * Then the daemon enters initialization phase 2: ** Initialize daemon data structures ** Initialize ring buffer for client connection ** Check if a runtime configuration exists, if yes load all stored application and context ids, as well as all log levels and trace statuses. Store this information to a local array. ** Prepare main loop ** Initialize receiver objects for socket and serial connection ** Initialize binary semaphore ** Create and start thread for timing messages, sending of these messages is disabled at default. * Now, the initialization is finished, and the DLT daemon enters the main loop. ==== Main loop In the main loop, the following things occur: * Wait for event on the incoming named pipe or socket, the TCP connections (the one connection for new connections, and all TCP connections from clients), and possibly on the serial device, via poll() call. * Distinguish from which socket/file descriptor the connection came, and handle them: ** Event from TCP server socket (New DLT client to DLT daemon): *** Create new TCP connection *** If the newly created connection is the first TCP connection, send all log messages already stored in ring buffer to DLT client. ** Event from incoming named pipe or unix socket(DLT user library to DLT daemon): *** Use dlt receiver to read data *** As long as there are DLT messages available in received data: **** Handle user message: ***** DLT_USER_MESSAGE_REGISTER_APPLICATION ***** DLT_USER_MESSAGE_UNREGISTER_APPLICATION ***** DLT_USER_MESSAGE_REGISTER_CONTEXT ***** DLT_USER_MESSAGE_UNREGISTER_CONTEXT ***** DLT_USER_MESSAGE_OVERFLOW ***** DLT_USER_MESSAGE_LOG ***** DLT_USER_MESSAGE_APP_LL_TS *** Move rest of data in front of buffer for next read attempt ** Event from serial device (DLT client to DLT daemon via serial device) *** Use other dlt receiver to read data *** As long as there are DLT messages available in received data: **** Check for DLT message type control request, and if yes process the request *** Move rest of data in front of buffer for next read attempt ** Event from TCP socket (DLT client to DLT daemon via TCP connection) *** Use other dlt receiver to read data, and check for lost connection *** As long as there are DLT messages available in received data: **** Check for DLT message type control request, and if yes process the request *** Move rest of data in front of buffer for next read attempt How the received user messages and control messages are handled, is described in the Appendix. === DLT user library ==== Overview The DLT user library is linked to each application which wants to use DLT. It encapsulates the communication with the DLT daemon, and provides two interfaces: the DLT user macro interface and the DLT user functional interface. All macros from the DLT user macro interface are mapped to functions in the DLT user functional interface. The DLT user library has one additional thread, responsible for receiving messages from the DLT daemon. Parts of functions accessible by the user interface are protected by a semaphore, as well as parts of the function which is called within the thread. ==== Initialization During initialization, the following things are done: * Setup internal structure including Application ID and Description (textual) of application * Get value from environment variable "DLT_LOCAL_PRINT_MODE". This variable can be used to control the local printing mode of the DLT user library. If enabled (either via "AUTOMATIC" or via "FORCE_ON"), all messages, which are prepared to be sent to the DLT daemon will also be print out locally (as ASCII string). If the environment variable is set, this value overrides the local print mode which can be set with the API function dlt_enable_local_print() or with dlt_disable_local_print() from within the application using the DLT user library. The following values are allowed: *** "AUTOMATIC": Local printing is enabled, if NO DLT daemon is running. *** "FORCE_ON": Local printing is always enabled. *** "FORCE_OFF": Local printing is always disabled. * Clear internal context array (dynamically growing in step size DLT_USER_CONTEXT_ALLOC_SIZE, typically 500). The internal context array is NOT be kept sorted, as the DLT daemon stores for each registered context the offset position within this array, and sends this offset position for faster access of a context within this internal context array). The internal context array contains one entry for each context: ** Context ID ** Log level for this context ** Trace status for this context ** Initialize table (dynamically growing in step-size 1) with function pointers for callback functions used for injection messages ** Description (textual) of context * Initialize ringbuffer for local storage of not sent messages * Setup signal handler and atexit handler * Ignore all pipe signals * Create and open own named pipe with the name /tmp/dlt, where is the process id of the application using the DLT user library. * Open named pipe to the DLT daemon * Open local file for storage, if specified * Initialize receiver object * Start receiver thread ==== De-Initialization During de-initialization, the following things are done: * De-register application (and all contexts belonging to this application) from DLT daemon * Stop receiver thread * Close and remove own named pipe * Close named pipe to the DLT daemon * De-Initialize receiver object * De-Initialize ringbuffer ==== Register application and context During register of the application, the following things occur: * Auto-initialize DLT user library, if necessary * Store application id to internal structure * Store application description to internal structure * Send message DLT_REGISTER_APPLICATION to DLT daemon During register of a context of the application, the following things occur: * Auto-initialize DLT user library, if necessary * Check, if context was already registered, if not , dynamically increment if required, the context array in step size DLT_USER_CONTEXT_ALLOC_SIZE, typically 500. Then store one entry for the new context to internal context array. * Send message DLT_REGISTER_CONTEXT to DLT daemon ==== Unregister context and application During unregister of context, the following things occur: * Delete context from internal structures * Send message DLT_UNREGISTER_CONTEXT to DLT daemon During unregister of application, the following things occur: * Delete application from internal structures * Send message DLT_UNREGISTER_APPLICATION to DLT daemon ==== Handling of messages received from DLT daemon During receiver thread within the DLT user library checks for newly received messages from the DLT daemon, and handles them in the following way: * DLT_USER_MESSAGE_LOG_LEVEL ** Store received log level and trace status for the received context to the context array * DLT_USER_MESSAGE_INJECTION ** Check all registered callbacks for this context: *** Compare service id of registered callback with received service id, if they matches: **** Call registered callback function. ==== Overflow handling If the named pipe/socket of the DLT daemon is full, an overflow flag is set and the message stored in a ring buffer. The next time, a message could be send to the DLT daemon, an overflow message is send first, then the contents of the ring buffer. If sending of this message was possible, the overflow flag is reset. ==== Send log message During sending of a log message, the following things occur: * Auto-initialize DLT user library, if necessary * Initialize DLT log structure * Store log level of log message in DLT log structure * Check if log level is smaller than or equal than the stored log level of the context, under which the message should be sent. If yes continue, else don't send this log message. This is a kind of filtering on the DLT user library side. * In non-verbose mode, insert message id * Add values (int, string, raw, …) to DLT log structure: ** Set argument type (only in verbose mode) ** Copy content of argument to message ** Set length information of argument ** Set number of arguments and total length of message * Create new message with the help of the DLT log structure and handle this message: ** Initialize new message ** Add headers (standard header, extended header, storage header, ...) to this message ** If logging to a file is enabled, write the log message to file. Finished sending log. ** Print message locally, if requested by environment variable ** Check if connection to DLT daemon was lost and try to reattach to daemon. ** Check for overflow flag and try to send overflow message. ** Try to send message to DLT daemon, and check for return values. This can be: *** data could not be written *** handle not open or pipe/socket error *** other error condition *** no error, all right ** If sending failed, put this message in the ring buffer for later sending. ** Handle this error conditions. ==== Send network trace message During sending of a network trace message, the following things occur: * Auto-initialize DLT user library, if necessary * Check for trace status of network trace message to be send. * If Trace status equals on: ** Initialize DLT log structure ** Set trace status in DLT log structure to network trace type of message ** Copy length of network message header to DLT log structure ** Copy data of network message header to DLT log structure ** Copy length of network trace payload to DLT log structure ** Copy data of network trace payload to DLT log structure ** Create new message with the help of the DLT log structure and handle this message ==== Register callback function for injection message During registration of a callback function for a injection message, the following steps are executed: ** For the specified context, check if service id is already in the table of the registered callbacks (this table is dynamically growing in steps of one entry). *** If yes: **** Stored service id is set to service id to be registered **** Stored callback function pointer is set to callback function pointer to be registered *** If no: **** Increase nr of callbacks for this context **** Store service id in callback table **** Store function pointer in callback table === Communication between DLT daemon and DLT user library The communication mechanism(IPC) used between DLT daemon and DLT user library are named pipes (FIFOs) or UNIX_SOCKETS (based on compile time configuration). During startup of the DLT daemon, the DLT daemon creates and opens the IPC on configured path. If a DLT user application using the DLT user library wants to send something to the DLT daemon this IPC is used. During startup of the DLT user application using the DLT user library, it creates and opens the same IPC (a named pipe called /tmp/dlt, where is the process id of the DLT user application or an UNIX_SOCKET). If the DLT daemon wants to send something to the DLT user application, this IPC is used. The exchanged messages are described in the chapter 7.1. === Place of message creation The following table shows, where the DLT messages are created. The message types are described in more detail in the AUTOSAR Specification for Diagnostic Log and Trace. [options="header"] |============================================================================================== | Type of message | DLT client | DLT daemon | DLT library | Control request | X | X | | Control response | | X | | Log message | | | X | Trace message | | | X |============================================================================================== * "Get log info" request only, if enabled with \-r option in DLT daemon during start-up * "File generation" means, that the DLT client creates a file for testing purposes, containing multiple DLT messages. This functionality is only in the "old" DLT viewer (WX widget-based implementation) available. This table shows, that: ** DLT messages of message type control request (e.g. "Get Log Info"-Request) are created in the DLT client, and then sent to the DLT daemon. ** DLT messages of message type control response (to a control request) are created in the DLT daemon, and then sent to the DLT client. ** DLT messages of type log and of type trace are created in the DLT user library, then passed (via the named pipe of the DLT daemon) to the DLT daemon , which forwards them to the connected DLT clients. === Message flow The following figure shows the overall flow of messages. .DLT Message flow image::images/dlt_message_flow.png[] == Appendix === Messages exchanged between DLT daemon and DLT user library There are several user messages (each has its own message identifier DLT_USER_MESSAGE_*) which will are exchanged between DLT daemon and DLT user library, and will be described in the following sub-chapters. From DLT user library to DLT daemon: * DLT_USER_MESSAGE_REGISTER_APPLICATION * DLT_USER_MESSAGE_UNREGISTER_APPLICATION * DLT_USER_MESSAGE_REGISTER_CONTEXT * DLT_USER_MESSAGE_UNREGISTER_CONTEXT * DLT_USER_MESSAGE_LOG * DLT_USER_MESSAGE_OVERFLOW * DLT_USER_MESSAGE_APP_LL_TS From DLT daemon to DLT user library: * DLT_USER_MESSAGE_LOG_LEVEL * DLT_USER_MESSAGE_INJECTION Each of the following messages has a message header with the following information: * Pattern: DUH0x01 * Message identifier ==== User Message: Register Application This message is send by the DLT user library once per application to register the application to the DLT daemon. It contains the following information: * The application id of the application to be registered * The process id of the process using the DLT user library. This information is required, if the DLT daemon wants to send something to the DLT user library. * The length of the following description. * The application description. ==== User Message: Unregister Application This message is send by the DLT user library once per application to unregister the application from the DLT daemon. It contains the following information: * The application id of the application to be unregistered * The process id of the process using the DLT user library. ==== User Message: Register Context This message is send by the DLT user library once for each context which should be registered to the DLT daemon. It contains the following information: * The application id of the application to be registered * The context id of the application to be registered * Each created context is stored with its associated information in a dynamically growing array in the DLT user library. The index in this array is send. * The process id of the process using the DLT user library. This information is required, if the DLT daemon wants to send something to the DLT user library. * The initial log level of the context * The initial trace status of the context * The length of the following description. * The context description. ==== User Message: Unregister Context This message is send by the DLT user library once for each context which should be unregistered from the DLT daemon. It contains the following information: * The application id of the application to be unregistered * The context id of the application to be unregistered * The process id of the process using the DLT user library. ==== User Message: Log This is the standard log/trace message send by the DLT user library to the DLT daemon. It contains the following information: * A standard DLT message header as specified in the AUTOSAR R4.0 DLT standard. * An extended DLT message header as specified in the AUTOSAR R4.0 DLT standard. * The payload of the DLT message ==== User Message: Overflow This message is send from the DLT user library to the DLT daemon, if there was an overflow during writing to the DLT daemon named pipe. It contains no further information. ==== User Message: Application Log Level and Trace Status This message is send from the DLT user library to the DLT daemon, when the overall Log Level and Trace Status for the whole DLT application should be set from within the DLT application. It contains the following information: * The application id * The Log Level to be set for the whole application * The Trace Status to be set for the whole application ==== User Message: Log Level If the log level or trace status is changed, or initialized, this message is send from the DLT daemon to the DLT user library to store the current log level and trace status for filtering in the DLT user library. It contains the following information: * The new set log level * New set trace status. * Each created context is stored with its associated information in a dynamically growing array in the DLT user library. The index in this array is send. ==== User Message: Injection This message is send from the DLT daemon to the DLT user library, if an injection message was received by the DLT daemon from a DLT client. Via the context, the appropriate application and its named pipe can be identified. The injection message is then passed to this named pipe. It contains the following information: * Each created context is stored with its associated information in a dynamically growing array in the DLT user library. The index in this array is send. * Service ID of the injection message * Length of the following injection message * The contents of the injection message === DLT daemon: User message handling Following things occur for the received DLT user messages: * DLT_USER_MESSAGE_REGISTER_APPLICATION ** Add all information about application to a local application array (dynamically growing in a predefined step size (DLT_DAEMON_APPL_ALLOC_SIZE, typically 500)). The array is always being kept sorted (via qsort()). Finding entries in this array is done by a binary search (via bsearch()). ** Open named pipe to DLT application using the DLT user library with process id . The name of the pipe is /tmp/dlt * DLT_USER_MESSAGE_UNREGISTER_APPLICATION ** Remove all information about this application from local application array, and remove all information of all contexts belonging to this application from local context array. The arrays are always being kept sorted, without empty entries in between. Dynamically shrinking of this array is NOT implemented. * DLT_USER_MESSAGE_REGISTER_CONTEXT ** Add all information about context to local context array (dynamically growing in a predefined step size (DLT_DAEMON_CONTEXT_ALLOC_SIZE, typically 1000)). The array is always being kept sorted (via qsort()). Finding entries in this array is done by a binary search (via bsearch()). ** Send log level and trace status to DLT user library for this context. Therefore, the DLT_USER_MESSAGE_LOG_LEVEL is used. ** Create and send DLT control message response "get log info" for this application and context to all connected DLT clients, if requested (-r option during startup of DLT daemon). * DLT_USER_MESSAGE_UNREGISTER_CONTEXT ** Remove all information about this context from local context array. The array is always being kept sorted, without empty entries in between. Dynamically shrinking of this array is NOT implemented. * DLT_USER_MESSAGE_OVERFLOW ** Set internal flag for overflow. ** Create and send DLT control message response overflow to all connected TCP connections, and optionally to serial device, if connected. If the message was sent, reset the internal flag for overflow. * DLT_USER_MESSAGE_LOG ** Overwrite ECU id, if requested ** Set storage header ** Check for filters of message, if no filter is set, or filter is matching: *** Possibly display message as specified in the options. **** Whole message display in hex **** Whole message display in ASCII **** Show message headers only *** Store message to output file *** Set serial header in front of message, if specified. *** Create and try to send DLT message to all DLT clients connected via TCP connection, and optionally via serial device. *** If the message could not be sent, store the message to a local ring buffer. The ring buffer internally uses a variable length for the buffered elements, and therefore uses the memory available for the buffer the best way possible. If the buffer is full, the oldest messages are silently discarded, until there is enough space for the message to be stored in the ring buffer. * DLT_USER_MESSAGE_APP_LL_TS ** For all contexts belonging to the specified application: *** Set specified log level *** Set specified trace status *** Send specified log level and trace status to DLT client library === DLT daemon: Control message handling If the DLT daemon receives a control message request from a DLT client, it handles it in the following way. First the service id of the message is detected, and if it is no injection message, the following things occur: * DLT_SERVICE_ID_SET_LOG_LEVEL ** Check if received log level is other then already set log level. If yes: *** Store new log level to local array. *** Send new log level to DLT user library for this context. Therefore, the DLT_USER_MESSAGE_LOG_LEVEL is used. ** Send DLT control response to DLT client, with status of operation. * DLT_SERVICE_ID_SET_TRACE_STATUS ** Check if received trace status is other then already set trace status. If yes: *** Store new trace status to local array. *** Send new trace status to DLT user library for this context. Therefore, the DLT_USER_MESSAGE_LOG_LEVEL is used. ** Send DLT control response to DLT client, with status of operation. * DLT_SERVICE_ID_GET_LOG_INFO ** Create answer message for DLT control response. All kinds of requests are supported: *** Application/Context: **** All applications and all contexts **** One application and all of its contexts **** One application with one context. *** Request type (as specified in the AUTOSAR DLT Standard, 1 and 2 are not specified): **** 3: Application ID, Context ID **** 4: Application ID, Context ID, Log Level **** 5: Application ID, Context ID, Trace Status **** 6: Application ID, Context ID, Log Level, Trace Status **** 7: Application ID, Context ID, Log Level, Trace Status, Description ** Answer is of the corresponding type 3-7, or of type 8 (no matching context ids found), or of type 2 (error). ** Send DLT control response answer to DLT client. * DLT_SERVICE_ID_GET_DEFAULT_LOG_LEVEL ** Send DLT control response with default log level to DLT client. * DLT_SERVICE_ID_STORE_CONFIG ** Store configuration files with currently registered application ids and context ids as well as currently set log levels and trace statuses to configuration files. If these files exists, they will be read in when the DLT daemon is started next time. ** Send DLT control response to DLT client. * DLT_SERVICE_ID_RESET_TO_FACTORY_DEFAULT ** Delete the stored configuration files, if they exists. ** Set default log level and trace status to initial values, and inform all applications using the default log level and trace status about the new defaults. ** Send DLT control response to DLT client. * DLT_SERVICE_ID_SET_COM_INTERFACE_STATUS ** Send DLT control response "Not supported" to DLT client * DLT_SERVICE_ID_SET_COM_INTERFACE_MAX_BANDWIDTH ** Send DLT control response "Not supported" to DLT client * DLT_SERVICE_ID_SET_VERBOSE_MODE ** Send DLT control response "Not supported" to DLT client * DLT_SERVICE_ID_SET_MESSAGE_FILTERING ** Send DLT control response "Not supported" to DLT client * DLT_SERVICE_ID_SET_TIMING_PACKETS ** Set flag to start/stop sending of timing messages in thread. ** Send DLT control response to DLT client. * DLT_SERVICE_ID_GET_LOCAL_TIME ** Send DLT control response with local time to DLT client. * DLT_SERVICE_ID_USE_ECU_ID ** Send DLT control response "Not supported" to DLT client * DLT_SERVICE_ID_USE_SESSION_ID ** Send DLT control response "Not supported" to DLT client * DLT_SERVICE_ID_USE_TIMESTAMP ** Send DLT control response "Not supported" to DLT client * DLT_SERVICE_ID_USE_EXTENDED_HEADER ** Send DLT control response "Not supported" to DLT client * DLT_SERVICE_ID_SET_DEFAULT_LOG_LEVEL ** Check if received default log level is other than already stored default log level. If yes: *** Store new default log level to internal structure. *** Send a DLT_USER_MESSAGE_LOG_LEVEL to all DLT clients containing the new default log level, which uses a context which is set to default log level. ** Send DLT control response to DLT client, with status of operation. * DLT_SERVICE_ID_SET_DEFAULT_TRACE_STATUS ** Check if received default trace status is other than already stored default trace status. If yes: *** Store new default trace status to internal structure. *** Send a DLT_USER_MESSAGE_LOG_LEVEL to all DLT clients containing the new default trace status, which uses a context which is set to default trace status. ** Send DLT control response to DLT client, with status of operation. * DLT_SERVICE_ID_GET_SOFTWARE_VERSION ** Send DLT control response containing a software version string to DLT Client. ** The software version string contains: *** the package version of the package dltv2, e.g. "2.0.0" *** the package status of the package dltv2, e.g. "alpha, beta, final" *** the overall subversion revision number for the package dltv2, e.g. "2300" * DLT_SERVICE_ID_MESSAGE_BUFFER_OVERFLOW ** Try to send DLT control response containing the status of the internal flag for overflow. If the message could be send, reset the internal flag for overflow. For handling of the injection message, the following steps occur: * Create new user message DLT_USER_MESSAGE_INJECTION from received DLT control request message, and send this user message to the DLT application using the DLT user library. === Mapping to files Here is a description, how the whole project is structured and which files exists. The following table shows a top level view of the available Git repositories: [options="header"] |============================================================================================== | Directory | Description | dlt | DLT Daemon and Library implementation; command line utilities, examples and test programs | dlt_viewer | DLT Client GUI (DLT Viewer): QT based implementation |============================================================================================== As this document has the focus on the DLT Daemon and the DLT user library, only the "dlt" directory is introduced in more detail: [options="header"] |============================================================================================== | Directory | Description | doc | Documentation | include | Include files, installed on target | package | Packaging support files | src | Source Code | src/shared | Shared source code (between DLT daemon and DLT user library) | src/adaptor | Adaptors to DLT daemon:dlt-adaptor-stdin (for connection over stdin) dlt-adaptor-udp (for connection over UDP) | src/console | Console utilities: dlt-receive, dlt-convert, and dlt-sortbytimestamp | src/daemon | DLT Daemon | src/example | Examples for usage of the DLT user library:dlt-example-user (Macro IF) anddlt-example-user-func (Function IF) andwintestclient (MS Windows based test client) | src/lib | DLT library functions | src/tests | Test programs:dlt-test-client and dlt-test-user for automatic tests, dlt-test-stress for stress tests, dlt-test-internal for internal tests | src/winclientlib | MS Windows implementation of a client library | testscripts | Several supporting scripts |============================================================================================== The DLT daemon implementation uses the following files, besides DLT functions from files from the shared directory: [options="header"] |============================================================================================== | File | Description | dlt-daemon.c | DLT daemon implementation | dlt-daemon.h | Header file for dlt-daemon.c | dlt-daemon_cfg.h | Compile time configuration for DLT daemon, Part1 | dlt_daemon_common.c | Supporting functions for a DLT daemon implementation | dlt_daemon_common.h | Header file for dlt_daemon_common.c | dlt_daemon_common_cfg.h | Compile time configuration for DLT daemon, Part2 |============================================================================================== The DLT user library contains the following files: [options="header"] |============================================================================================== | File | Description | dlt_user.c | Implementation of functions, available via the DLT user library interface. | dlt_user_cfg.h | Compile time configuration for dlt_user.c | dlt_client.c | Functions required for DLT Client implementations | dlt_client_cfg.h | Compile time configuration for dlt_client.c |============================================================================================== The shared directory contains the following files: [options="header"] |============================================================================================== | File | Description | dlt_common.c | Common helper functions, such as: - Print functions for DLT messages - Functions for handling DLT Ids - Filter functions - DLT message handling functions - Functions for handling DLT files - DLT receiver functions - Log handling - Ringbuffer functions - Setting and checking of storage header | dlt_common_cfg.h | Compile time configuration for dlt_common.c | dlt_user_shared.c | Shared functions, required by the DLT daemon and the DLT user library, such as: - Setting and checking the user header - Sending DLT messages over named pipes (FIFOs) | dlt_user_shared.h | Header file for dlt_user_shared.c | dlt_user_shared_cfg.h | Compile time configuration for dlt_user_shared.c |============================================================================================== The public available include directory contains the following header files: |============================================================================================== | File | Description | dlt.h | Overall include file, includes dlt_common.h and dlt_user.h | dlt_common.h | Include file for dlt_common.c | dlt_user.h | Include file for dlt_user.c, contains the "User API" functions | dlt_user_macros.h | Include file for dlt_user.c, contains the "User API" macros | dlt_client.h | Include file for dlt_client.c | dlt_protocol.h | DLT protocol specfic definitions and macros | dlt_types.h | Definition of types, must be adapted to the target architecture and compiler toolchain. |============================================================================================== === Description of used structures in implementation The following important structures are used in the DLT Daemon and DLT User Library: [options="header"] |============================================================================================== | Structure | Description | DltDaemonFlags | Flags and values, set over command line during start-up of DLT daemon | DltDaemonLocal | Global variables of the DLT Daemon, grouped together in a struct | DltDaemon | Parameters of the DLT daemon | DltDaemonApplication | Parameters of an application, used within DLT daemon | DltDaemonContext | Parameters of a context, used within DLT daemon | DltUserControlMsg... | User control messages | DltContext | Each context is represented with this structure | DltContextData | Temorary used structure for constructing a log message | DltUserInjectionCallback | One entry in dynamic callback table for callback function | dlt_ll_ts_type | Table managing all contexts (and loglevels and trce statuses) within DLT user library, contains dynamicly growing array with "DltUserInjectionCallback" entries | DltUser | Parameters for DLT user library application, contains dynamically growing array with "dlt_ll_ts_type" entries | DltStorageHeader | Storage header | DltStandardHeader | Structure for standard header of a DLT message | | DltStandardHeaderExtra | Structure for standard header extra fields of a DLT message | DltExtendedHeader | Structure for extended header of a DLT message | DltService... | Structures for control messages (requests and responses) | DltFilter | Structure to store filter parameters | DltMessage | Structure to organize a DLT message, includes pointers to DltStorageHeader, DltStandardHeader, DltStandardHeaderExtra, and DltExtendedHeader, data of message is stored within a private buffer within this structure | DltFile | Structure to organize access to a DLT File | DltReceiver | Structure to organize the receiving of data | DltRingbuffer | Structure to organize a ring buffer |============================================================================================== ==== Implementation specifics * The following preconditions were given prior to implementation: ** C-only implementation for the DLT daemon and the DLT user library ** Implementation of common functions, which can be used in a command line utility as well as in an Graphical UI ** Implementation of C+\+ like classes in C, see dlt_common.c and dlt_common.h * The current implementation of the DLT daemon and DLT user library is only tested with gcc under Ubuntu 16.04 on Intel HW. * It is assumed that packed structs are always stored in memory in the order specified within the packed struct. * The implementation is multithread safe. * Initialize DLT application and contexts, then forking and using the forked process, will lead to unclear behavior (or in worst case to a crash), as the forked process uses another process id as the parent process. Instead, initialize the DLT application and contexts in the forked process. * Calling of DLT logging and tracing functions within a callback function for injections is not supported, and will lead to an unclear behavior. dlt-daemon-2.18.4/doc/dlt_extended_network_trace.md000066400000000000000000000067261353342203500223260ustar00rootroot00000000000000# Extended Network Trace Back to [README.md](../README.md) ## Introduction The extended network trace allows the user to send or truncate network trace messages that are larger than the normal maximum size of a DLT message. ## Protocol When truncation of messages is allowed, the truncated messages will be wrapped into a special message which indicates that a network trace message was truncated and what was the original size of the message. Segmented messages are sent in multiple packages. The package stream is prepended with a start message indicating which contains a unique handle for this stream, size of data to follow, count of segments to follow and segment size. Each segment contains the stream handle, segment sequence number, the data and data length. Finally after sending all the data segments, one more packet is sent to indicate the end of the stream. ## Truncated package Truncated message can be sent using the following function: ` int dlt_user_trace_network_truncated(DltContext *handle, DltNetworkTraceType nw_trace_type, uint16_t header_len, void *header, uint16_t payload_len, void *payload, int allow_truncate) ` This will send a packet in the following format: Value | Description | Type :--- | :--- | :--- NWTR | Package identifier | STRING header | nw_trace header and it's length | RAW size | Original size of the message | UINT payload | The truncated nw_trace payload | RAW ## Segmented messages User can send a segmented network trace message asynchronously using: ` void dlt_user_trace_network_segmented(DltContext *handle, DltNetworkTraceType nw_trace_type, uint16_t header_len, void *header, uint16_t payload_len, void *payload) ` This will start a background thread and return immediately. User can also send all the required packages one by one using: ` int dlt_user_trace_network_segmented_start(unsigned int *id, DltContext *handle, DltNetworkTraceType nw_trace_type, uint16_t header_len, void *header, uint16_t payload_len) ` ` int dlt_user_trace_network_segmented_segment(int id, DltContext *handle, DltNetworkTraceType nw_trace_type, int sequence, uint16_t payload_len, void *payload) ` ` int dlt_user_trace_network_segmented_end(int id, DltContext *handle, DltNetworkTraceType nw_trace_type) ` *NOTE*: It is not recommended to use these functions unless you really have to. ## Segmented start packet The first packet in the stream is the header: Value | Description | Type :--- | :--- | :--- NWST | Package identifier | STRING streamhandle | Unique identifier for all packages in the stream | UINT header | nw_trace header and it's length | RAW payloadsize | Size of the complete payload in this stream | UINT segmentcount | Number of segments to follow | UINT segmentlen | Size of one segment | UINT ## Data segment After the header, follows a stream of data segments. Value | Description | Type :--- | :--- | :--- NWCH | Package identifier | STRING streamhandle | Unique identifier for all packages in the stream | UINT sequence | Sequence number of this segment | UINT data | One segment of the original nw_trace | RAW ## End packet After all the segments have been sent, an End identifier is sent. Value | Description | Type :--- | :--- | :--- NWEN | Package identifier | STRING streamhandle | Unique identifier for all packages in the stream | UINT ## Author Lassi Marttala ## COPYRIGHT Copyright (C) 2011 - 2015 BMW AG. License MPL-2.0: Mozilla Public License version 2.0 . dlt-daemon-2.18.4/doc/dlt_filetransfer.md000066400000000000000000000214311353342203500202510ustar00rootroot00000000000000# DLT Filetransfer Back to [README.md](../README.md) ## Overview DLT is a reusable open source software component for standardized logging and tracing in infotainment ECUs based on the AUTOSAR 4.0 standard. The goal of DLT is the consolidation of the existing variety of logging and tracing protocols on one format. ## Introduction to DLT Filetransfer With DLT Filetransfer it is possible store the binary data of a file to the automotive dlt log. The file will be read in binary mode and put as several chunks to a DLT\_INFO log. With a special plugin of the dlt viewer, you can extract the embedded files from the trace and save them. It can be used for smaller files, e.g. HMI screenshots or little coredumps. ## Protocol The file transfer is at least one single transaction. This transaction consist of three main types of packages: - header package - one or more data packages - end package ## Header Package Every filetransfer must begin with the header package using: ` int dlt_user_log_file_header(DltContext *fileContext,const char *filename) ` Header Header Package Protocol: Value | Description :--- | :--- FLST | Package flag fileserialnumber | Inode of the file used as file serialnumber filename | Use the absolute filepath to the file filesize | Filesize of the file file creation date | Creation date of the file number of packages | Counted packages which will be transferred in the data packages BUFFER_SIZE | Defined buffer size to reconstruct the file FLST | Package flag ## Data Package After the header package was sent, at least one or more data packages can be sent using: ` int dlt_user_log_file_data(DltContext *fileContext,const char *filename,int packageToTransfer, int timeout) ` Data Data Package Protocol: Value | Description :--- | :--- FLDA | Package flag fileserialnumber | Inode of the file used as file serialnumber PackageNumber | Transferred package Data | Payload containing data FLDA | Package flag ## End Package After all data packages were sent, the end package must be sent to indicate that the filetransfer is over using: ` int dlt_user_log_file_end(DltContext *fileContext,const char *filename,int deleteFlag) ` End Package Protocol: Value | Description :--- | :--- FLFI | Package flag fileserialnumber | Inode of the file FLFI | Package flag ## File information The library offers the user the possibility to log informations about a file using the following method without transferring the file itself using: ` dlt_user_log_file_infoAbout(DltContext *fileContext, const char *filename) ` File Information Protocol: Value | Description :--- | :--- FLIF | Package flag fileserialnumber | Inode of the file used as file serialnumber filename | Use the absolute filepath to the file filesize | Filesize of the file file creation date | Creation date of the file number of packages | Counted packages which will be transferred in the data packages FLIF | Package flag ## File transfer error ```c //! Error code for dlt_user_log_file_complete #define ERROR_FILE_COMPLETE -300 //! Error code for dlt_user_log_file_complete #define ERROR_FILE_COMPLETE1 -301 //! Error code for dlt_user_log_file_complete #define ERROR_FILE_COMPLETE2 -302 //! Error code for dlt_user_log_file_complete #define ERROR_FILE_COMPLETE3 -303 //! Error code for dlt_user_log_file_head #define ERROR_FILE_HEAD -400 //! Error code for dlt_user_log_file_data #define ERROR_FILE_DATA -500 //! Error code for dlt_user_log_file_data #define DLT_FILETRANSFER_ERROR_FILE_DATA_USER_BUFFER_FAILED -501 //! Error code for dlt_user_log_file_end #define ERROR_FILE_END -600 //! Error code for dlt_user_log_file_infoAbout #define ERROR_INFO_ABOUT -700 //! Error code for dlt_user_log_file_packagesCount #define ERROR_PACKAGE_COUNT -800 ``` If an error happens during file transfer, the library will execute the method: ` void dlt_user_log_file_errorMessage(DltContext *fileContext, const char *filename, int errorCode) ` File transfer error Protocol: Value | Description :--- | :--- FLER | Package flag error code | see error codes above linux error code | standard linux error code fileserialnumber | Inode of the file used as file serialnumber filename | Use the absolute filepath to the file filesize | Filesize of the file file creation date | Creation date of the file number of packages | Counted packages which will be transferred in the data packages FLER | Package flag If the file doesn't exist, the content of the error package is a little bit different: Value | Description :--- | :--- FLER | Package flag error code | see error codes above linux error code | standard linux error code filename | Use the absolute filepath to the file FLER | Package flag ## Using Using DLT Filetransfer There are two ways to use the filetransfer - Automatic filetransfer in one step - Header, data and end package order handeld by the user ### Automatic Call - dlt\_user\_log\_file\_complete The method needs the following arguments: - fileContext -> Context for logging the file to dlt - filename -> Use the absolute file path to the file - deleteFlag -> Flag if the file will be deleted after transfer. 1->delete, 0->notDelete - timeout -> Deprecated. The order of the packages is to send at first the header, then one or more data packages (depends on the filesize) and in the end the end package. The advantage of this method is, that you must not handle the package ordering by your own. Within dlt\_user\_log\_file\_complete the free space of the user buffer will be checked. If the free space of the user buffer < 50% then the actual package won't be transferred and a timeout will be executed. If the daemon crashes and the user buffer is full, the automatic method is in an endless loop. ### Manual Manual starting filetransfer with the following commands: - dlt\_user\_log\_file\_head | Transfers only the header of the file - dlt\_user\_log\_file\_data | Transfers only one single package of a file - dlt\_user\_log\_file\_end | Tranfers only the end of the file This ordering is very important, so that you can save the transferred files to hard disk on client side with a dlt viewer plugin. The advantage of using several steps to transfer files by your own is, that you are very flexible to integrate the filetransfer in your code. An other difference to the automatic method is, that only a timeout will be done. There is no check of the user buffer. ## Important for integration You should care about blocking the main program when you intergrate filetransfer in your code. Maybe it's useful to extract the filetransfer in an extra thread. Another point is the filesize. The bigger the file is, the longer takes it to log the file to dlt. ## Example dlt filetransfer For an example file transfer you can use ```bash Usage: dlt-example-filetransfer \[options\] \ Filetransfer example with DLT Package Version: 2.2.0 , Package Revision: 1666, build on May 28 2011 02:18:19 Command: -f file - File to transfer (absolute path) Options: -a apid - Set application id to apid (default: FLTR) -c ctid - Set context id to ctid (default: FLTR) -t ms - Timeout between file packages in ms (minimum 20 ms) -d - Flag to delete the file after the transfer (default: false) -i - Flag to log file infos to DLT before transfer file (default: false) -h - This help ``` ## Testing dlt filetransfer When you call "sudo make install", some automatic tests will be installed. Start the test using the following command from bash: ` dlt-test-filetransfer ` It's important that the dlt-filetransfer example files are installed in /usr/share/dlt-filetransfer which will be done automatically by using "sudo make install". If not, use -t and -i options to specify the path to a text file and an image file. - testFile1Run1: Test the file transfer with the condition that the transferred file is smaller as the file transfer buffer using dlt\_user\_log\_file\_complete. - testFile1Run2: Test the file transfer with the condition that the transferred file is smaller as the file transfer buffer using single package transfer - testFile2Run1: Test the file transfer with the condition that the transferred file is bigger as the file transfer buffer using dlt\_user\_log\_file\_complete. - testFile2Run2: Test the file transfer with the condition that the transferred file is bigger as the file transfer buffer using single package transfer - testFile3Run1: Test the file transfer with the condition that the transferred file does not exist using dlt\_user\_log\_file\_complete. - testFile3Run2: Test the file transfer with the condition that the transferred file does not exist using single package transfer - testFile3Run3: Test which logs some information about the file. ## AUTHOR Christian Muck ## COPYRIGHT Copyright (C) 2012 - 2015 BMW AG. License MPL-2.0: Mozilla Public License version 2.0 . dlt-daemon-2.18.4/doc/dlt_for_developers.md000066400000000000000000000604261353342203500206120ustar00rootroot00000000000000# How to DLT for developers Back to [README.md](../README.md) Table of Contents 1. [Summary](#Summary) 2. [Example Application](#DLT-Example-Application) 3. [General Rules for Logging](#General-Rules-for-Logging) 4. [The use of Log Levels](#The-use-of-Log-Levels) 5. [DLT Library Runtime Configuration](#DLT-Library-Runtime-Configuration) 6. [DLT API Usage](#DLT-API-Usage) 7. [DLT injection messages](#DLT-Injection-Messages) 8. [Log level changed callback](#Log-level-changed-callback) ## DLT Example Application To use DLT from an application, it has to be linked against the DLT library. When the DLT daemon is installed on the system, there will be a shared library with the name libdlt.so which provides the interface for applications to get a connection to the DLT daemon. The library path and include path must be set in the build environment prior to building a program using the shared dlt library. By default, the header file "dlt.h" is located in a directory called "dlt/" within the standard include directory. This example gives an overview of DLT usage inside an application by using a minimal code example. Detailed information about the API can be found later in this document. ``` #include DLT_DECLARE_CONTEXT(ctx); /* declare context */ int main() { DLT_REGISTER_APP("TAPP", "Test Application for Logging"); DLT_REGISTER_CONTEXT(ctx, "TES1", "Test Context for Logging"); /* … */ DLT_LOG(ctx, DLT_LOG_ERROR, DLT_CSTRING("This is an error")); /* … */ DLT_UNREGISTER_CONTEXT(ctx); DLT_UNREGISTER_APP(); return 0; } ``` DLT is quite easy to use. The first thing a developer has to do is to include the dlt header file. DLT contexts can be statically declared using the macro shown in next line. Firstly, a DLT application has to be registered inside the main function. For this, an application identifier APID and application description has to be specified. Afterwards, one or more DLT contexts could be specified. To log messages in verbose mode, the DLT\_LOG macro can be used. As parameter, the logging context, the log level and a variable list of parameters have to be specified. DLT requires each parameter to be strongly typed using DLT type macros. In this example, DLT\_CSTRING is used to specify a constant string. On application cleanup, all DLT contexts, as well as the DLT application have to be unregistered. ### DLT with cmake To use DLT with cmake, the following lines are the important ones: ``` find_package(PkgConfig) pkg_check_modules(DLT REQUIRED automotive-dlt) ``` to INCLUDE\_DIRECTORIES, add ``` ${DLT_INCLUDE_DIRS} ``` and to TARGET\_LINK\_LIBRARIES: ``` ${DLT_LIBRARIES} ``` ## General Rules for Logging ### Be Smart Before implementing logging in code one should take a second to think about a concept first. Often strategic places in the software can be used as a central place for logging. Such places are often interfaces to other SW components. Use the solution with the smallest impact. Avoid logging the “good cases” but log e.g. in your error handling sections – you will need error handling anyway. In case an error occurred more logs don’t matter as long as your regular code produces little logs. Keep in mind that tracing comes with a price tag – you are working in an embedded environment where CPU, memory and Bandwidth are sparse. ### Avoid high frequency outputs Certain events occur very often in a system – some of them dozens of times per second. In such a case do not implement logging for each occurrence. One example is the screen frame rate. Instead of printing a log for each frame rate aggregate the information and print an average once every five seconds or – even better – report once a second if the frame rate is below a critical value. ### Combine multiple messages Please always consider that each Log message creates a certain overhead. In case of DLT as the way of logging each has a header of 20 bytes. Therefore please aggregate information. In this way all necessary information is always combined. Please always use a human readable format; use identifiers for the different values, be consistent with separators. This helps to work with the data, especially when log messages are processed by scripts. Such scripts often use regular expressions – make the job easier! For example don’t write log entries like this: > Total frames: 1000 > > Sync frames: 0 > > Reem frames: 0 > > Valid frames: 0 > > Urgent frames: 1 Better aggregate Information into a single message: > Frame info: total=1000, sync=0, reem=1000, valid=0, urgent=1 ### Do not use ASCII-art Information should be “on your fingertips”. Logging is a tool to ease crushing bugs, not to win a computer art contest. → Don’t use ASCII Art! ### Do not create charts using ASCII Charts can be a great help to visualize what is going on in the system. This type can be nicely done by a trace analysis or in case of usage of the DLT Viewer, in a Plugin. It certainly should always be done in a post processing step. Doing this on the target is a waste of resources. ### Avoid tracing in loops Bad example: ``` for(int index=0; index export DLT\_INITIAL\_LOG\_LEVEL=”EXA1:CON1:5;EXA1:CON2:6” ### Local print mode Sometimes it might be useful to print DLT messages for debugging directly to console. To force the library to do so, the following environment variable can be exported: > export DLT\_LOCAL\_PRINT\_MODE=FORCE\_ON ### Library buffer size The DLT library contains a message buffer in case the DLT Daemon is not started yet or the connection to DLT Daemon is temporarily lost. The buffer is allocated while library initialization with a minimum size. If more messages need to be stored, the buffer grows in defined steps up to a maximum size. In case messages are flushed to DLT Daemon, the buffer is reduced to its minimal size. The default values and the environment variable names to set these values are described below: | | Default value [in bytes] | Environment variable name --- | --- | --- Minimal size | 50000 | DLT\_USER\_BUFFER\_MIN Maximal size | 500000 | DLT\_USER\_BUFFER\_MAX Step size | 50000 | DLT\_USER\_BUFFER\_STEP For example, to limit the maximum buffer size to 250k bytes, the following can be exported: > export DLT\_USER\_BUFFER\_MAX=250000 ## DLT API Usage ### Register application **Important note** - DLT may not be used in a forked child until a variant of exec() is called, because DLT is using non async-signal-safe functions. - DLT\_REGISTER\_APP is asynchronous. It may take some milliseconds to establish the IPC channel. Because of this, you might lose messages if you log immediately after registration. Typically this is not a problem, but may arise especially with simple examples. The DLT application has to be registered as early as possible during the initialization of the application by calling DLT\_REGISTER\_APP(). It is only allowed to call DLT\_REGISTER\_APP() once per application. An application id (maximum four characters) has to be specified and must be unique within an ECU. In this example "MAPP" is used. And also a description for the application can be specified, here it is "Test Application for Logging". ``` int main(int argc, const char* argv[]) { DLT_REGISTER_APP("MAPP","Test Application for Logging"); } ``` DLT\_REGISTER\_APP is asynchronous. It may take some milliseconds to establish the IPC channel. Because of this, messages might be lost if logs are emitted immediately after registering. Typically this is not a problem, but may arise especially with simple examples. ### Define and register all logging contexts As many contexts as needed can be defined. These contexts can be declared as contexts in different C or CPP files. But each context is only allowed to be declared once. Therefore a unique variable name for each context has to be used. ``` DLT_DECLARE_CONTEXT(myContext1); DLT_DECLARE_CONTEXT(myContext2); DLT_DECLARE_CONTEXT(myContext3); ``` If contexts from another C or CPP file shall be used, these contexts can be imported by calling: ``` DLT_IMPORT_CONTEXT(myContext1); DLT_IMPORT_CONTEXT(myContext2); DLT_IMPORT_CONTEXT(myContext3); ``` After the application is registered and contexts are declared, contexts need to be registered early during initialization of the application. DLT\_REGISTER\_CONTEXT() shall not be called before DLT\_REGISTER\_APP(). During registration of each context, a context id must be provided (maximum four characters long). In this example "TESX" is used. Also a description for the context can be provided; here it is "Test Context X for Logging". A context can also be registered with a predefined Log Level and Trace Status by using the Macro DLT\_REGISTER\_CONTEXT\_LL\_TS. The third context is registered using this method. ``` int main(int argc, const char* argv[]) { DLT_REGISTER_APP("MAPP","Test Application for Logging"); DLT_REGISTER_CONTEXT(myContext1,"TES1","Test Context 1 for Logging"); DLT_REGISTER_CONTEXT(myContext2,"TES2","Test Context 2 for Logging"); DLT_REGISTER_CONTEXT_LL_TS(myContext3, "TES3","Test Context 3 for Logging", DLT_LOG_DEBUG, DLT_TRACE_STATUS_OFF); } ``` Note: Please be aware that it might be taken up to a second until the synchronization of loglevel between DLT Daemon and application is done. ### Unregister contexts and application Before terminating the application registered contexts and at last the application need to be unregistered. ``` int main(int argc, const char* argv[]) { /* business logic */ DLT_UNREGISTER_CONTEXT(myContext1); DLT_UNREGISTER_CONTEXT(myContext2); DLT_UNREGISTER_CONTEXT(myContext3); DLT_UNREGISTER_APP(); return 0; } ``` ### Logging command DLT provides functions and macros for logging, whereas the interface for Verbose and Non-Verbose differs. The following table shows an example of all 4 types for logging using a constant string and an integer. #### Verbose vs. Non-Verbose API The following sections show examples of all 4 types for logging e.g. a string and an integer. ##### MACRO ###### Verbose ``` DLT_LOG(ctx, DLT_LOG_INFO, DLT_STRING("ID: "), DLT_UINT32(123)); ``` ###### Non-Verbose ``` DLT_LOG_ID(ctx, DLT_LOG_INFO, 42 /* unique message ID */, DLT_STRING("ID: "), DLT_UINT32(123)); ``` ##### Function ###### Verbose ``` if (dlt_user_log_write_start(&ctx, &ctxdata, DLT_LOG_INFO) > 0) { dlt_user_log_write_string(&myctxdata, "ID: "); dlt_user_log_write_uint32(&myctxdata, 123); dlt_user_log_write_finish(&myctxdata); } ``` ###### Non-Verbose ``` if (dlt_user_log_write_start_id(&ctx, &ctxdata, DLT_LOG_INFO, 42) > 0) { dlt_user_log_write_string(&myctxdata, "ID: "); dlt_user_log_write_uint32(&myctxdata, 123); dlt_user_log_write_finish(&myctxdata); } ``` Drawback of that solution is that the developer has to decide during development if Verbose or Non-Verbose mode shall be used and the code most likely ends up as written in the dlt-example-user application: ``` if (gflag) { /* Non-verbose mode */ DLT_LOG_ID(ctx, DLT_LOG_INFO, 42 /* unique msg ID */, DLT_INT(num), DLT_STRING(text)); } else { /* Verbose mode */ DLT_LOG(ctx, DLT_LOG_INFO, DLT_INT(num), DLT_STRING(text)); } ``` ##### Switching Verbose and Non-Verbose To switch Verbose/Non-Verbose mode (Verbose mode is default), the following APIs are available: ``` DLT_VERBOSE_MODE(); DLT_NONVERBOSE_MODE(); ``` ### Logging parameters The following parameter types can be used. Multiple parameters can be added to a single log message. The size of all logging parameters together should not exceed 1390 bytes, including the DLT message header. Type | Description --- | --- DLT\_STRING(TEXT) | String DLT\_CSTRING(TEXT) | Constant String (not send in non-verbose mode) DLT\_UTF8 | Utf8-encoded string DLT\_RAW(BUF,LENGTH) | Raw buffer DLT\_INT(VAR) | Integer variable, dependent on platform DLT\_INT8(VAR) |Integer 8 Bit variable DLT\_INT16(VAR) | Integer 16 Bit variable DLT\_INT32(VAR) | Integer 32 Bit variable DLT\_INT64(VAR) | Integer 64 bit variable DLT\_UINT(VAR) | Unsigned integer variable DLT\_UINT8(VAR) | Unsigned 8 Bit integer variable DLT\_UINT16(VAR) |Unsigned 16 Bit integer variable DLT\_UINT32(VAR) | Unsigned 32 Bit integer variable DLT\_UINT64(VAR) | Unsigned 64 bit integer variable DLT\_BOOL(VAR) | Boolean variable DLT\_FLOAT32(VAR) | Float 32 Bit variable DLT\_FLOAT64(VAR) | Float 64 Bit variable DLT\_HEX8(UINT\_VAR) | 8 Bit hex value DLT\_HEX16(UINT\_VAR) | 16 Bit hex value DLT\_HEX32(UINT\_VAR) | 32 Bit hex value DLT\_HEX64(UINT\_VAR) | 64 Bit hex value DLT\_BIN8(UINT\_VAR) | 8 Bit binary value DLT\_BIN16(UINT\_VAR | 16 Bit binary value DLT\_PTR(PTR\_VAR) | Architecture independent macro to print pointers ### Network Trace It is also possible to trace network messages. The interface, here DLT\_NW\_TRACE\_CAN, the length of the header data and a pointer to the header data, the length of the payload data and a pointer to the payload data, must be specified. If no header or payload is available, the corresponding length must be set to 0, and the corresponding pointer must be set to NULL. ``` DLT_TRACE_NETWORK(mycontext, DLT_NW_TRACE_CAN, headerlen, header, payloadlen, payload); ``` ### DLT C++ Extension The DLT C++ extension was added to DLT in version 2.13. This approach solves the need to specify the type of each argument for applications written in C++ by using C++ templates and function overloading. The following shows the usage of this API extension: ``` #define DLT_LOG_CXX(CONTEXT, LOGLEVEL, ...) #define DLT_LOG_FCN_CXX(CONTEXT, LOGLEVEL, ...) DLT_LOG_CXX(ctx, DLT_LOG_WARN, 1.0, 65); DLT_LOG_FCN_CXX(ctx, DLT_LOG_WARN, "Test String", 145, 3.141); ``` This works as well with C++ standard containers like std::vector, std::map, std::list. Of course, the logToDlt function can be overloaded to print user defined structures or classes. ``` struct MyStruct { int64_t uuid; int32_t interfaceId; int32_t registrationState; }; template<> inline int logToDlt(DltContextData & log, MyStruct const & value) { int result = 0; result += dlt_user_log_write_string(&log, "("); result += logToDlt(log, value.uuid); result += dlt_user_log_write_string(&log, ","); result += logToDlt(log, value.interfaceId); result += dlt_user_log_write_string(&log, ","); result += logToDlt(log, value.registrationState); result += dlt_user_log_write_string(&log, ")"); if (result != 0) { result = -1; } return result; } ``` ### Check if a specific Log Level is enabled In some scenarios it might be necessary to check if a specific Log Level is enabled or not, before log data is send to DLT Library. The macro is defined as follows: ``` DLT_IS_LOG_LEVEL_ENABLED(CONTEXT,LOGLEVEL) ``` In general, there is no need to check the active Log Level to decide if a log message can be send to not. This is handled inside the DLT\_LOG macro. ## DLT Injection Messages DLT provides an interface to register injection callbacks which can be sent by a DLT Client (e.g. DLT Viewer) to the application. An injection message callback is always registered for a specific context. The API to register a callback is defined as follows: ``` DLT_REGISTER_INJECTION_CALLBACK(CONTEXT, SERVICEID, CALLBACK); ``` Injection message Service IDs must be bigger than 0xFFF, because IDs up to 0xFFF are reserved for DLT Daemon control messages. The callback function needs to have the following definition: ``` int injection_callback(uint32_t service_id, void *data, uint32_t length); ``` For example, registering a callback function for a specific context with the service ID 0x1000 might look like: ``` DLT_REGISTER_INJECTION_CALLBACK(mycontext, 0x1000, injection_callback); ``` From DLT Viewer, an injection message can be sent by right-clicking the corresponding context in the project view (“Send injection”). A dialog will pop up to specify the injection data as shown below. ![alt text](images/dlt-viewer-send-injection-dialog.png "DLT Viewer Send Injection Callback") ## Log level changed callback A callback function can be registered to be called whenever the Log Level of a context changed. The usage is similar to DLT\_REGISTER\_INJECTION\_CALLBACK. ``` DLT_REGISTER_LOG_LEVEL_CHANGED_CALLBACK(CONTEXT, CALLBACK) ``` dlt-daemon-2.18.4/doc/dlt_glossary.md000066400000000000000000000072421353342203500174340ustar00rootroot00000000000000# Glossary Throughout the documentation specific terms are used. Those are defined below. Back to [README.md](../README.md) Term | Definition ----- | ---- Application ID | Application Identifier is a unique identifier for an application registered at the DLT Daemon. It is defined as 8bit ASCII character. e.g. "APP1". Each Application can have several sub-components each having a unique context ID Context ID | This is a user defined ID to group log and trace messages produced by an application. Each Application ID can own several Context IDs and the Context IDs shall be unique within an Application ID. The identification of the source of a log and trace message is done with a pair of Application ID and Context ID. It is composed by four 8 bit ASCII characters. Control Message | A control message is send by a connected client application (e.g. Log Viewer) to the DLT Daemon that includes an action request. E.g. change the Log level of a certain application). DLT Daemon | The DLT Daemon is the central component which receives all logs and traces from the DLT user applications. The DLT Daemon forwards all logs and traces to a connected DLT client (e.g. Log Viewer) or stores them optionally in a file on the target. DLT Viewer | The DLT Viewer is the GENIVI Log Viewer implementation. It is a Qt-based desktop application able to run on Windows and Linux operating systems. Further information and source code can be found here: https://github.com/GENIVI/dlt-viewer Gateway DLT Daemon | In a Multi-Node system, the DLT Daemon running on the Node directly connected to a Log Viewer is called Gateway DLT Daemon (if configured as Gateway). It forwards log messages from Passive DLT Daemons to Log Viewers and command/control messages from Log Viewer(s) to Passive DLT Daemon(s). Injection Message | An injection message is a control message for a specific DLT application. Log Consumer | A log consumer is an application connected to the DLT Daemon (DLT Client) that receives log messages and stores (e.g. Logstorage) or displays them (e.g. Log Viewer). A log consumer can run on the same operating system or on a remote host pc. Log Level | A log level defines a classification for the severity grade of a log message. Log Viewer | A client application or tool used to view log information on a host pc. DLT-viewer is the supported Log Viewers. Multi-Node System | A system with more than one node. Node | A node represents an operating system, e.g. Linux, AUTOSAR or a container having its own DLT Daemon instance. Only one DLT Daemon should run on a node. In the context of DLT, Node and ECU describe the same thing. Node Identifier | Unique Identifier of a node (node ID). In DLT, the node ID is defined by __EcuID__ set in _dlt.conf_ configuration file. Passive DLT Daemon | A passive DLT Daemon runs on a node without direct connection to a Log Viewer. All communication between a passive DLT Daemon and a Log Viewer has to be send via the Gateway DLT Daemon. Trace Status | The trace status provides information if a trace message should be send. Supported States are ON or OFF Verbose / Non-Verbose Mode | The DLT supports Verbose and Non-Verbose Mode. In _Verbose_ mode, all logging data including a type description is provided within the payload. Furthermore, Application ID and Context ID are transferred as part of the message header. In _Non-Verbose_ mode, description about the sender (Application ID, Context ID) as well as static strings and data description is not part of the payload. Instead, this information is stored in a file that needs to be parsed by a Log Viewer. The log message contains a unique message ID instead which allows a mapping between received log message and information stored in the file.dlt-daemon-2.18.4/doc/dlt_kpi.md000066400000000000000000000115301353342203500163470ustar00rootroot00000000000000# DLT KPI Back to [README.md](../README.md) ## Overview *DLT KPI* is a tool to provide log messages about **K**ey **P**erformance **I**ndicators to the DLT Daemon. The log message format is designed to be both readable by humans and to be parsed by DLT Viewer plugins. The information source for the dlt-kpi tool is the /proc file system. ## Message format *DLT KPI* logs its messages as human readable ASCII messages, divided in multiple arguments. The tool will log messages in user defined intervals, which can be set in the configuration file dlt-kpi.conf. ## Identifiers and their datasets The logged messages always start with a three character long identifier as first argument. After this identifier, they can contain multiple datasets separated in the remaining arguments. The datasets contain information separated by semicolons. The order and meaning of those information chunks is defined below. The following will explain the meaning to each three-character-identifier and each information chunk of the datasets associated with this identifier. The example messages all contain only one dataset - in real use, many messages will contain multiple datasets (one per argument). *NOTE*: Arguments are delimited by spaces when shown in ASCII, but dlt-viewer plugins can easily access each argument separately by certain methods, which makes arguments useful for parsing. ### NEW This identifies a message that contains datasets describing newly created processes. The datasets in these messages have the following form: `[PID];[Parent PID];[Commandline]` Example message: `NEW 21226;1;/usr/libexec/nm-dispatcher` ### STP This identifies a message that contains datasets describing processes that have ended since the last interval. The datasets in these messages have the following form: `[PID]` Example message: `STP 20541` ### ACT This identifies a message that contains datasets describing active processes. These are processes that have consumed CPU time since the last interval. The datasets in these messages have the following form: `[PID];[CPU time in milliseconds per second];[RSS bytes];[CTX-switches since last interval];[I/O bytes];[I/O wait time in milliseconds per second]` Example message: `ACT 20503;10;389;3;1886649;0` *NOTE:* The *CPU time* value is the active time of a process in milliseconds, divided by the number of CPU cores. So this value should never get greater than 1000ms, which would mean 100% CPU usage. ### CHK This identifies a message that is logged for each process in a certain interval. These messages can be used to get a list of currently existing processes and to keep a plugin, that tracks running processes, up to date if messages were lost or if the commandlines have changed. The datasets in these messages have the following form: `[PID];[Commandline]` Example message: `CHK 660;/sbin/audispd` ### IRQ This identifies a message that contains datasets describing the numbers of interrupts that occurred on each CPU. The datasets in these messages have the following form: `[IRQ name];cpu[CPU number];[Number of total interrupts];` Example message: `IRQ 0;cpu0:133;cpu1:0; 1;cpu0:76827;cpu1:0;` ## Synchronization messages Because the messages can get too long for logging and segmented network messages don't allow for individually set arguments, the datasets can be splitted into multiple messages of the same type (i.e. they have the same identifier). This can make it difficult for an observer (human or machine) to keep track of currently valid information. For example, one can't be sure if a process is part of the list of currently active processes or not, or if this message was part of an older interval that simply arrived too late. So, to correctly associate these messages to each other, each group of potentially "segmented" messages is surrounded by two synchronization messages which start with the same identifier, followed by the codes _BEG_ (for the opening sync message) or _END_ (for the closing sync message). Synchronization messages do not contain datasets. Example (Messages have been shortened for simplicity): ```c ACT BEG ACT 21768;10;417;3;672075;0 19284;20;15857;303654;22932174;0 1826;20;39781;4404293;154392870;0 ACT 1635;10;10696;8412557;375710810;0 990;10;22027;1176631;0;0 ACT END ``` Only processes that are part of this group are active at this moment. *ACT* messages that came before this message-group are invalid now. It can also happen that, between a *BEG* and an *END* sync message, there are messages of other types. So, plugins should not expect these message groups to always be a "solid block", but react on each message individually and dynamically, and store the logged information until the closing *END* message arrives. ## AUTHOR Sven Hassler ## COPYRIGHT Copyright (C) 2015 BMW AG. License MPL-2.0: Mozilla Public License version 2.0 . dlt-daemon-2.18.4/doc/dlt_multinode.md000066400000000000000000000074221353342203500175710ustar00rootroot00000000000000# DLT MultiNode Back to [README.md](../README.md) ## Overview MultiNode allows to connect DLT Daemons running on different operating systems, e.g. in a virtualized environment. The central component is the Gateway DLT Daemon which connects external DLT Clients, like the DLT Viewer running on a host computer with Passive DLT Daemons running on nodes without a physical connection to external DLT clients. All communication between passive nodes and DLT Viewer has to be sent via the Gateway node. The Gateway node forwards log messages coming from passive nodes to all connected DLT clients. The Gateway DLT Daemon also forwards command and control requests coming from DLT clients to the corresponding passive node. ![alt text](images/dlt-multinode.png "DLT MultiNode") ## Precondition The dlt.conf configuration file which is read by each DLT Daemon on start-up contains an entry to specify the ECU identifier (node identifier). It has to be ensured, that **each DLT Daemon in the System has a unique ECU** identifier specified. The ECU identifier is included in every DLT Message and is used to distinguish if a DLT message has to be forwarded to a passive node or handled by the Gateway DLT Daemon itself. ## Configuration The dlt.conf configuration file provides an option to enable the Gateway functionality of a DLT Daemon. The default setting is 0 (Off), which means the Gateway functionality is not available. ``` # Enable Gateway mode (Default: 0) GatewayMode = 1 ``` ### Gateway Configuration File The MultiNode configuration file has to be loaded by the Gateway DLT Daemon during startup. ``` [PassiveNode1] ; IP Address. (Mandatory) IPaddress = 192.168.2.32 ; TCP port. Default 3490 is used if no port is specified Port = 3495 ; Passive node ECU identifier. (Mandatory) EcuID = ECU2 ; Connection to passive node only on demand. Default ‘OnStartup’ if not specified Connect = OnDemand ; timeout in seconds Timeout = 10 ; Send following control messages after connection is established SendControl=0x03, 0x13 ; Send SerialHeader with control messages. Value in dlt.conf is used ; as default if not specified SendSerialHeader=1 ``` The configuration file is written in an INI file format and contains information about different connected passive nodes. Each passive node’s connection parameters are specified in a unique numbered separate section ([PassiveNode{1,2, …N}]). Because TCP is the only supported communication channel, the IPaddress and Port of the Passive DLT Daemon has to be specified. With the Connect property it is possible to specify when the Gateway DLT Daemon shall connect to the passive node. The following values are allowed: - OnStartup - The Gateway DLT Daemon tries to connect to the Passive DLT Daemon immediately after the Gateway DLT Daemon is started. - OnDemand - The Gateway DLT Daemon tries to connect to the Passive DLT Daemon when it receives a connection request. The Timeout property specifies the time after which the Gateway DLT Daemon stops connecting attempts to a Passive DLT Daemon. If the connection is not established within the specified time, the Gateway DLT Daemon gives up connecting attempts and writes an error messages to its internal log. The following control messages are supported to be send to a passive node automatically after connection is established: - 0x03: Get Log Info - 0x13: Get Software Version ## Using DLT MultiNode ``` Usage: dlt-passive-node-ctrl [options] Send a trigger to DLT daemon to (dis)connect a passive node or get current passive node status. Options: -c Connection status (1 - connect, 0 - disconnect) -h Usage -n passive Node identifier (e.g. ECU2) -s Show passive node(s) connection status -t Specify connection timeout (Default: 10s) -v Set verbose flag (Default:0) ``` dlt-daemon-2.18.4/doc/dlt_offline_logstorage.md000066400000000000000000000201041353342203500214310ustar00rootroot00000000000000# DLT Offline Logstorage Back to [README.md](../README.md) ## Introduction to DLT Offline Logstorage Logstorage is a mechanism to store DLT logs on the target system or an external device (e.g. USB stick) connected to the target. It can be seen as an improvement of the Offline Trace functionality which is already part of DLT. Logstorage provides the following features: - Store logs in sets of log files defined by configuration files - Log file content is configurable - Configurable options are: - Application identifier (single entry, list, wildcard) - Context identifier (single entry, list, wildcard) - Log level - ECU identifier - Log files are configurable in terms of: - File name and naming scheme - File size - Number of files - Log message synchronization strategy is configurable - Trigger start and stop logging using a control application - Integration into Udev device management ## Configuration ### General Configuration General configuration is done inside dlt.conf. The following configuration options exist: ``` ############################################################################## # Offline logstorage # ############################################################################## # Store DLT log messages, if not set offline logstorage is off (Default: off) # Maximum devices to be used as offline logstorage devices # OfflineLogstorageMaxDevices = 1 # Path to store DLT offline log storage messages (Default: off) # OfflineLogstorageDirPath = /opt # File options # Appends timestamp in log file name, Disable by setting to 0 (Default: 1) # OfflineLogstorageTimestamp = 0 # Appends delimiter in log file name, allowed punctutations only (Default: _) # OfflineLogstorageDelimiter = _ # Wrap around value for log file count in file name (Default: UINT_MAX) # OfflineLogstorageMaxCounter = 999 # Maximal used memory for Logstorage Cache in KB (Default: 30000 KB) # OfflineLogstorageCacheSize = 30000 ``` ### Configuration file format For DLT daemon to store logs the configuration file named “dlt\_logstorage.conf” should be present in external storage or internal storage device (= given path in the file system). ``` [Filter] # filter configration name LogAppName= # Name of application to store logs from. Multiple applications can be separated by "," and ".*" denotes all applications ContextName= # Name or names of contexts to store logs from. Multiple contexts can be separated by "," and ".*" denotes all contexts of the application LogLevel= # Define log level, e.g. DLT_LOG_INFO or DLT_LOG_FATAL File= # Base name of the created files that containing the logs, e.g. "example". For further file naming scheme configurations see man dlt.conf FileSize= # Maximum file size in bytes NOFiles= # Number of created files before oldest is deleted and a new one is created SyncBehavior= # Specify sync strategy. Default: Sync'ed after every message. See Logstorage Rinbuffer Implementation below. EcuID= # Specify ECU identifier SpecificSize= # Store logs in storage devices after specific size is reached. ``` The Parameter "SyncBehavior","EcuID" and "SpecificSize" are optional - all others are mandatory. An configuration file might look like: ``` [FILTER1] LogAppName=APP1 ContextName=CON1,CON2 LogLevel=DLT_LOG_INFO File=App FileSize=10000 NOFiles=10 [FILTER2] LogAppName=TEST ContextName=.* LogLevel=DLT_LOG_ERROR File=Test FileSize=250000 NOFiles=5 EcuID=ECU1 SyncBehavior=ON_SPECIFIC_SIZE SpecificSize=5000 [FILTER3] LogAppName=TEST ContextName=.* LogLevel=DLT_LOG_ERROR File=Test FileSize=250000 NOFiles=5 SyncBehavior=ON_FILE_SIZE,ON_DEMAND EcuID=ECU1 ``` ## Usage DLT Offline Logstorage Enable OfflineLogstorage by setting ```OfflineLogstorageMaxDevices = 1``` in dlt.conf. Be aware that the performance of DLT may drop if multiple Logstorage devices are used; the performance depends on the write speed of the used device, too. Create the device folder: ```mkdir -p /var/dltlogs``` Create a configuration file and store it on into that folder or mount an external device containing a configuration file. Start the DLT Daemon. This is not necessary if the DLT Daemon was started already with Offline Logstorage enabled. Trigger DLT Daemon to use the new logstorage device: ```dlt-logstorage-ctrl -c 1 -p /var/dltlogs``` Afterwards, logs that match the filter configuration are stored onto the Logstorage device. ```dlt-logstorage-ctrl -c 0 -p /var/dltlogs``` The configured logstorage device is disconnected from the DLT Daemon. ### Using dlt-logstorage-ctrl application ``` Usage: dlt-logstorage-ctrl [options] Send a trigger to DLT daemon to connect/disconnect a certain logstorage device Options: -c Connection type: connect = 1, disconnect = 0 -d[prop] Run as daemon: prop = use proprietary handler 'prop' may be replaced by any meaningful word -e Set ECU ID (Default: ECU1) -h Usage -p Mount point path -s Sync Logstorage cache -t Specify connection timeout (Default: 10s) -v Set verbose flag (Default:0) ``` ## Testing DLT Offline Logstorage The following procedure can be used to test Offline Logstorage: - Enable OfflineLogstorage by setting OfflineLogstorageMaxDevices = 1 in dlt.conf - Start dlt-daemon - The default search path of logstorage is: /tmp/dltlogs/dltlogsdevX where X is a number in the range [1..OfflineLogstorageMaxDevices] - Create the device folder ```$ mkdir -p /var/dltlog``` - Create the configuration file "dlt\_logstorage.conf" in this folder and define filter configuration(s): ``` [FILTER1] LogAppName=LOG ContextName=TEST LogLevel=DLT_LOG_WARN File=example FileSize=50000 NOFiles=5 ``` - Trigger dlt-daemon to use a new device ```$ dlt-logstorage-ctrl -c 1 -p /var/dltlog``` - Start dlt-example-user ```$ dlt-example-user Hello123``` - After execution, a log file is created in /var/dltlogs e.g. example\_001\_20150512\_133344.dlt - To check the content of the file open it with dlt-convert or DLT Viewer. ## Logstorage Ring Buffer Implementation The DLT Logstorage is mainly used to store a configurable set of logs on an external mass storage device attached to the target. In this scenario, writing each incoming log message directly onto the external storage device is appreciate, because the storage device might be un-mounted/suddenly removed at any time. Writing each log message immediately avoids the problem of losing too many messages because the file system sync could not be finished before the device has been removed physically from the target. On the other hand the DLT Logstorage feature might be used as well to store a configurable set of logs on any internal, nonvolatile memory (e.g. FLASH storage device). Due to the reason of limited write cycles of a FLASH device the number of write cycles has to be reduced as much as possible. But the drawback of losing log messages in case of an unexpected operating system crash has to be taking into account as well. The obvious idea is to cache incoming log messages in memory and write the log data to disk based on a certain strategy. Incoming log messages are stored in a data cache with a specific size. Depending on user defined strategy, the data cache is written onto the storage device、without relying on the sync mechanism of the file system. The following strategies are implemented: - ON\_MSG - sync every message(Default) - ON\_DAEMON\_EXIT - sync on daemon exit - ON\_DEMAND - sync on demand - ON\_FILE\_SIZE - sync on file size reached - ON\_SPECIFIC\_SIZE - sync after specific size is reached Note : 1. Combinations (not allowed: combinations with ON_MSG,combination of ON\_FILE\_SIZE with ON\_SPECIFIC\_SIZE) 2. If on\_demand sync strategy alone is specified, it is advised to concatenate the log files in sequential order before viewing it on viewer. dlt-daemon-2.18.4/doc/doxygen.cfg.cmake000066400000000000000000001753631353342203500176330ustar00rootroot00000000000000####### # SPDX license identifier: MPL-2.0 # # Copyright (C) 2011-2015, BMW AG # # This file is part of GENIVI Project DLT - Diagnostic Log and Trace. # # This Source Code Form is subject to the terms of the # Mozilla Public License (MPL), v. 2.0. # If a copy of the MPL was not distributed with this file, # You can obtain one at http://mozilla.org/MPL/2.0/. # # For further information see http://www.genivi.org/. ####### # Doxyfile 1.5.8 # This file describes the settings to be used by the documentation system # doxygen (www.doxygen.org) for a project # # All text after a hash (#) is considered a comment and will be ignored # The format is: # TAG = value [value, ...] # For lists items can also be appended using: # TAG += value [value, ...] # Values that contain spaces should be placed between quotes (" ") #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- # This tag specifies the encoding used for all characters in the config file # that follow. The default is UTF-8 which is also the encoding used for all # text before the first occurrence of this tag. Doxygen uses libiconv (or the # iconv built into libc) for the transcoding. See # http://www.gnu.org/software/libiconv for the list of possible encodings. DOXYFILE_ENCODING = UTF-8 # The PROJECT_NAME tag is a single word (or a sequence of words surrounded # by quotes) that should identify the project. PROJECT_NAME = @PROJECT_NAME@ # The PROJECT_NUMBER tag can be used to enter a project or revision number. # This could be handy for archiving the generated documentation or # if some version control system is used. PROJECT_NUMBER = @GENIVI_PROJECT_VERSION@ # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) # base path where the generated documentation will be put. # If a relative path is entered, it will be relative to the location # where doxygen was started. If left blank the current directory will be used. OUTPUT_DIRECTORY = ./DOC_DLT # If the CREATE_SUBDIRS tag is set to YES, then doxygen will create # 4096 sub-directories (in 2 levels) under the output directory of each output # format and will distribute the generated files over these directories. # Enabling this option can be useful when feeding doxygen a huge amount of # source files, where putting all generated files in the same directory would # otherwise cause performance problems for the file system. CREATE_SUBDIRS = NO # The OUTPUT_LANGUAGE tag is used to specify the language in which all # documentation generated by doxygen is written. Doxygen will use this # information to generate all constant output in the proper language. # The default language is English, other supported languages are: # Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, # Croatian, Czech, Danish, Dutch, Farsi, Finnish, French, German, Greek, # Hungarian, Italian, Japanese, Japanese-en (Japanese with English messages), # Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, Polish, # Portuguese, Romanian, Russian, Serbian, Serbian-Cyrilic, Slovak, Slovene, # Spanish, Swedish, and Ukrainian. OUTPUT_LANGUAGE = English # If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will # include brief member descriptions after the members that are listed in # the file and class documentation (similar to JavaDoc). # Set to NO to disable this. BRIEF_MEMBER_DESC = YES # If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend # the brief description of a member or function before the detailed description. # Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the # brief descriptions will be completely suppressed. REPEAT_BRIEF = YES # This tag implements a quasi-intelligent brief description abbreviator # that is used to form the text in various listings. Each string # in this list, if found as the leading text of the brief description, will be # stripped from the text and the result after processing the whole list, is # used as the annotated text. Otherwise, the brief description is used as-is. # If left blank, the following values are used ("$name" is automatically # replaced with the name of the entity): "The $name class" "The $name widget" # "The $name file" "is" "provides" "specifies" "contains" # "represents" "a" "an" "the" ABBREVIATE_BRIEF = "The $name class" \ "The $name widget" \ "The $name file" \ is \ provides \ specifies \ contains \ represents \ a \ an \ the # If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then # Doxygen will generate a detailed section even if there is only a brief # description. ALWAYS_DETAILED_SEC = NO # If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all # inherited members of a class in the documentation of that class as if those # members were ordinary class members. Constructors, destructors and assignment # operators of the base classes will not be shown. INLINE_INHERITED_MEMB = NO # If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full # path before files name in the file list and in the header files. If set # to NO the shortest path that makes the file name unique will be used. FULL_PATH_NAMES = YES # If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag # can be used to strip a user-defined part of the path. Stripping is # only done if one of the specified strings matches the left-hand part of # the path. The tag can be used to show relative paths in the file list. # If left blank the directory from which doxygen is run is used as the # path to strip. STRIP_FROM_PATH = # The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of # the path mentioned in the documentation of a class, which tells # the reader which header file to include in order to use a class. # If left blank only the name of the header file containing the class # definition is used. Otherwise one should specify the include paths that # are normally passed to the compiler using the -I flag. STRIP_FROM_INC_PATH = # If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter # (but less readable) file names. This can be useful is your file systems # doesn't support long names like on DOS, Mac, or CD-ROM. SHORT_NAMES = NO # If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen # will interpret the first line (until the first dot) of a JavaDoc-style # comment as the brief description. If set to NO, the JavaDoc # comments will behave just like regular Qt-style comments # (thus requiring an explicit @brief command for a brief description.) JAVADOC_AUTOBRIEF = NO # If the QT_AUTOBRIEF tag is set to YES then Doxygen will # interpret the first line (until the first dot) of a Qt-style # comment as the brief description. If set to NO, the comments # will behave just like regular Qt-style comments (thus requiring # an explicit \brief command for a brief description.) QT_AUTOBRIEF = NO # The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen # treat a multi-line C++ special comment block (i.e. a block of //! or /// # comments) as a brief description. This used to be the default behaviour. # The new default is to treat a multi-line C++ comment block as a detailed # description. Set this tag to YES if you prefer the old behaviour instead. MULTILINE_CPP_IS_BRIEF = NO # If the INHERIT_DOCS tag is set to YES (the default) then an undocumented # member inherits the documentation from any documented member that it # re-implements. INHERIT_DOCS = YES # If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce # a new page for each member. If set to NO, the documentation of a member will # be part of the file/class/namespace that contains it. SEPARATE_MEMBER_PAGES = NO # The TAB_SIZE tag can be used to set the number of spaces in a tab. # Doxygen uses this value to replace tabs by spaces in code fragments. TAB_SIZE = 8 # This tag can be used to specify a number of aliases that acts # as commands in the documentation. An alias has the form "name=value". # For example adding "sideeffect=\par Side Effects:\n" will allow you to # put the command \sideeffect (or @sideeffect) in the documentation, which # will result in a user-defined paragraph with heading "Side Effects:". # You can put \n's in the value part of an alias to insert newlines. ALIASES = # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C # sources only. Doxygen will then generate output that is more tailored for C. # For instance, some of the names that are used will be different. The list # of all members will be omitted, etc. OPTIMIZE_OUTPUT_FOR_C = YES # Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java # sources only. Doxygen will then generate output that is more tailored for # Java. For instance, namespaces will be presented as packages, qualified # scopes will look different, etc. OPTIMIZE_OUTPUT_JAVA = NO # Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran # sources only. Doxygen will then generate output that is more tailored for # Fortran. OPTIMIZE_FOR_FORTRAN = NO # Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL # sources. Doxygen will then generate output that is tailored for # VHDL. OPTIMIZE_OUTPUT_VHDL = NO # Doxygen selects the parser to use depending on the extension of the files it parses. # With this tag you can assign which parser to use for a given extension. # Doxygen has a built-in mapping, but you can override or extend it using this tag. # The format is ext=language, where ext is a file extension, and language is one of # the parsers supported by doxygen: IDL, Java, Javascript, C#, C, C++, D, PHP, # Objective-C, Python, Fortran, VHDL, C, C++. For instance to make doxygen treat # .inc files as Fortran files (default is PHP), and .f files as C (default is Fortran), # use: inc=Fortran f=C EXTENSION_MAPPING = # If you use STL classes (i.e. std::string, std::vector, etc.) but do not want # to include (a tag file for) the STL sources as input, then you should # set this tag to YES in order to let doxygen match functions declarations and # definitions whose arguments contain STL classes (e.g. func(std::string); v.s. # func(std::string) {}). This also make the inheritance and collaboration # diagrams that involve STL classes more complete and accurate. BUILTIN_STL_SUPPORT = NO # If you use Microsoft's C++/CLI language, you should set this option to YES to # enable parsing support. CPP_CLI_SUPPORT = NO # Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. # Doxygen will parse them like normal C++ but will assume all classes use public # instead of private inheritance when no explicit protection keyword is present. SIP_SUPPORT = NO # For Microsoft's IDL there are propget and propput attributes to indicate getter # and setter methods for a property. Setting this option to YES (the default) # will make doxygen to replace the get and set methods by a property in the # documentation. This will only work if the methods are indeed getting or # setting a simple type. If this is not the case, or you want to show the # methods anyway, you should set this option to NO. IDL_PROPERTY_SUPPORT = NO # If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC # tag is set to YES, then doxygen will reuse the documentation of the first # member in the group (if any) for the other members of the group. By default # all members of a group must be documented explicitly. DISTRIBUTE_GROUP_DOC = NO # Set the SUBGROUPING tag to YES (the default) to allow class member groups of # the same type (for instance a group of public functions) to be put as a # subgroup of that type (e.g. under the Public Functions section). Set it to # NO to prevent subgrouping. Alternatively, this can be done per class using # the \nosubgrouping command. SUBGROUPING = YES # When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum # is documented as struct, union, or enum with the name of the typedef. So # typedef struct TypeS {} TypeT, will appear in the documentation as a struct # with name TypeT. When disabled the typedef will appear as a member of a file, # namespace, or class. And the struct will be named TypeS. This can typically # be useful for C code in case the coding convention dictates that all compound # types are typedef'ed and only the typedef is referenced, never the tag name. TYPEDEF_HIDES_STRUCT = NO # The SYMBOL_CACHE_SIZE determines the size of the internal cache use to # determine which symbols to keep in memory and which to flush to disk. # When the cache is full, less often used symbols will be written to disk. # For small to medium size projects (<1000 input files) the default value is # probably good enough. For larger projects a too small cache size can cause # doxygen to be busy swapping symbols to and from disk most of the time # causing a significant performance penality. # If the system has enough physical memory increasing the cache will improve the # performance by keeping more symbols in memory. Note that the value works on # a logarithmic scale so increasing the size by one will rougly double the # memory usage. The cache size is given by this formula: # 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, # corresponding to a cache size of 2^16 = 65536 symbols SYMBOL_CACHE_SIZE = 0 #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- # If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in # documentation are documented, even if no documentation was available. # Private class members and static file members will be hidden unless # the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES EXTRACT_ALL = YES # If the EXTRACT_PRIVATE tag is set to YES all private members of a class # will be included in the documentation. EXTRACT_PRIVATE = YES # If the EXTRACT_STATIC tag is set to YES all static members of a file # will be included in the documentation. EXTRACT_STATIC = YES # If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) # defined locally in source files will be included in the documentation. # If set to NO only classes defined in header files are included. EXTRACT_LOCAL_CLASSES = YES # This flag is only useful for Objective-C code. When set to YES local # methods, which are defined in the implementation section but not in # the interface are included in the documentation. # If set to NO (the default) only methods in the interface are included. EXTRACT_LOCAL_METHODS = NO # If this flag is set to YES, the members of anonymous namespaces will be # extracted and appear in the documentation as a namespace called # 'anonymous_namespace{file}', where file will be replaced with the base # name of the file that contains the anonymous namespace. By default # anonymous namespace are hidden. EXTRACT_ANON_NSPACES = NO # If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all # undocumented members of documented classes, files or namespaces. # If set to NO (the default) these members will be included in the # various overviews, but no documentation section is generated. # This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_MEMBERS = NO # If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all # undocumented classes that are normally visible in the class hierarchy. # If set to NO (the default) these classes will be included in the various # overviews. This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_CLASSES = NO # If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all # friend (class|struct|union) declarations. # If set to NO (the default) these declarations will be included in the # documentation. HIDE_FRIEND_COMPOUNDS = NO # If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any # documentation blocks found inside the body of a function. # If set to NO (the default) these blocks will be appended to the # function's detailed documentation block. HIDE_IN_BODY_DOCS = NO # The INTERNAL_DOCS tag determines if documentation # that is typed after a \internal command is included. If the tag is set # to NO (the default) then the documentation will be excluded. # Set it to YES to include the internal documentation. INTERNAL_DOCS = YES # If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate # file names in lower-case letters. If set to YES upper-case letters are also # allowed. This is useful if you have classes or files whose names only differ # in case and if your file system supports case sensitive file names. Windows # and Mac users are advised to set this option to NO. CASE_SENSE_NAMES = NO # If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen # will show members with their full class and namespace scopes in the # documentation. If set to YES the scope will be hidden. HIDE_SCOPE_NAMES = NO # If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen # will put a list of the files that are included by a file in the documentation # of that file. SHOW_INCLUDE_FILES = YES # If the INLINE_INFO tag is set to YES (the default) then a tag [inline] # is inserted in the documentation for inline members. INLINE_INFO = YES # If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen # will sort the (detailed) documentation of file and class members # alphabetically by member name. If set to NO the members will appear in # declaration order. SORT_MEMBER_DOCS = YES # If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the # brief documentation of file, namespace and class members alphabetically # by member name. If set to NO (the default) the members will appear in # declaration order. SORT_BRIEF_DOCS = NO # If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the # hierarchy of group names into alphabetical order. If set to NO (the default) # the group names will appear in their defined order. SORT_GROUP_NAMES = NO # If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be # sorted by fully-qualified names, including namespaces. If set to # NO (the default), the class list will be sorted only by class name, # not including the namespace part. # Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. # Note: This option applies only to the class list, not to the # alphabetical list. SORT_BY_SCOPE_NAME = NO # The GENERATE_TODOLIST tag can be used to enable (YES) or # disable (NO) the todo list. This list is created by putting \todo # commands in the documentation. GENERATE_TODOLIST = YES # The GENERATE_TESTLIST tag can be used to enable (YES) or # disable (NO) the test list. This list is created by putting \test # commands in the documentation. GENERATE_TESTLIST = YES # The GENERATE_BUGLIST tag can be used to enable (YES) or # disable (NO) the bug list. This list is created by putting \bug # commands in the documentation. GENERATE_BUGLIST = YES # The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or # disable (NO) the deprecated list. This list is created by putting # \deprecated commands in the documentation. GENERATE_DEPRECATEDLIST= YES # The ENABLED_SECTIONS tag can be used to enable conditional # documentation sections, marked by \if sectionname ... \endif. ENABLED_SECTIONS = # The MAX_INITIALIZER_LINES tag determines the maximum number of lines # the initial value of a variable or define consists of for it to appear in # the documentation. If the initializer consists of more lines than specified # here it will be hidden. Use a value of 0 to hide initializers completely. # The appearance of the initializer of individual variables and defines in the # documentation can be controlled using \showinitializer or \hideinitializer # command in the documentation regardless of this setting. MAX_INITIALIZER_LINES = 30 # Set the SHOW_USED_FILES tag to NO to disable the list of files generated # at the bottom of the documentation of classes and structs. If set to YES the # list will mention the files that were used to generate the documentation. SHOW_USED_FILES = YES # If the sources in your project are distributed over multiple directories # then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy # in the documentation. The default is NO. SHOW_DIRECTORIES = NO # Set the SHOW_FILES tag to NO to disable the generation of the Files page. # This will remove the Files entry from the Quick Index and from the # Folder Tree View (if specified). The default is YES. SHOW_FILES = YES # Set the SHOW_NAMESPACES tag to NO to disable the generation of the # Namespaces page. This will remove the Namespaces entry from the Quick Index # and from the Folder Tree View (if specified). The default is YES. SHOW_NAMESPACES = YES # The FILE_VERSION_FILTER tag can be used to specify a program or script that # doxygen should invoke to get the current version for each file (typically from # the version control system). Doxygen will invoke the program by executing (via # popen()) the command , where is the value of # the FILE_VERSION_FILTER tag, and is the name of an input file # provided by doxygen. Whatever the program writes to standard output # is used as the file version. See the manual for examples. FILE_VERSION_FILTER = # The LAYOUT_FILE tag can be used to specify a layout file which will be parsed by # doxygen. The layout file controls the global structure of the generated output files # in an output format independent way. The create the layout file that represents # doxygen's defaults, run doxygen with the -l option. You can optionally specify a # file name after the option, if omitted DoxygenLayout.xml will be used as the name # of the layout file. LAYOUT_FILE = #--------------------------------------------------------------------------- # configuration options related to warning and progress messages #--------------------------------------------------------------------------- # The QUIET tag can be used to turn on/off the messages that are generated # by doxygen. Possible values are YES and NO. If left blank NO is used. QUIET = NO # The WARNINGS tag can be used to turn on/off the warning messages that are # generated by doxygen. Possible values are YES and NO. If left blank # NO is used. WARNINGS = YES # If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings # for undocumented members. If EXTRACT_ALL is set to YES then this flag will # automatically be disabled. WARN_IF_UNDOCUMENTED = YES # If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for # potential errors in the documentation, such as not documenting some # parameters in a documented function, or documenting parameters that # don't exist or using markup commands wrongly. WARN_IF_DOC_ERROR = YES # This WARN_NO_PARAMDOC option can be abled to get warnings for # functions that are documented, but have no documentation for their parameters # or return value. If set to NO (the default) doxygen will only warn about # wrong or incomplete parameter documentation, but not about the absence of # documentation. WARN_NO_PARAMDOC = NO # The WARN_FORMAT tag determines the format of the warning messages that # doxygen can produce. The string should contain the $file, $line, and $text # tags, which will be replaced by the file and line number from which the # warning originated and the warning text. Optionally the format may contain # $version, which will be replaced by the version of the file (if it could # be obtained via FILE_VERSION_FILTER) WARN_FORMAT = "$file:$line: $text" # The WARN_LOGFILE tag can be used to specify a file to which warning # and error messages should be written. If left blank the output is written # to stderr. WARN_LOGFILE = #--------------------------------------------------------------------------- # configuration options related to the input files #--------------------------------------------------------------------------- # The INPUT tag can be used to specify the files and/or directories that contain # documented source files. You may enter file names like "myfile.cpp" or # directories like "/usr/src/myproject". Separate the files or directories # with spaces. INPUT = @PROJECT_SOURCE_DIR@/doc/mainpage.h \ @PROJECT_SOURCE_DIR@/src/ \ @PROJECT_SOURCE_DIR@/include # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is # also the default input encoding. Doxygen uses libiconv (or the iconv built # into libc) for the transcoding. See http://www.gnu.org/software/libiconv for # the list of possible encodings. INPUT_ENCODING = UTF-8 # If the value of the INPUT tag contains directories, you can use the # FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank the following patterns are tested: # *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx # *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90 FILE_PATTERNS = *.c \ *.cc \ *.cxx \ *.cpp \ *.c++ \ *.d \ *.java \ *.ii \ *.ixx \ *.ipp \ *.i++ \ *.inl \ *.h \ *.hh \ *.hxx \ *.hpp \ *.h++ # The RECURSIVE tag can be used to turn specify whether or not subdirectories # should be searched for input files as well. Possible values are YES and NO. # If left blank NO is used. RECURSIVE = YES # The EXCLUDE tag can be used to specify files and/or directories that should # excluded from the INPUT source files. This way you can easily exclude a # subdirectory from a directory tree whose root is specified with the INPUT tag. EXCLUDE = doc \ examples \ .git # The EXCLUDE_SYMLINKS tag can be used select whether or not files or # directories that are symbolic links (a Unix filesystem feature) are excluded # from the input. EXCLUDE_SYMLINKS = NO # If the value of the INPUT tag contains directories, you can use the # EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude # certain files from those directories. Note that the wildcards are matched # against the file with absolute path, so to exclude all test directories # for example use the pattern */test/* EXCLUDE_PATTERNS = # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names # (namespaces, classes, functions, etc.) that should be excluded from the # output. The symbol name can be a fully qualified name, a word, or if the # wildcard * is used, a substring. Examples: ANamespace, AClass, # AClass::ANamespace, ANamespace::*Test EXCLUDE_SYMBOLS = # The EXAMPLE_PATH tag can be used to specify one or more files or # directories that contain example code fragments that are included (see # the \include command). EXAMPLE_PATH = # If the value of the EXAMPLE_PATH tag contains directories, you can use the # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank all files are included. EXAMPLE_PATTERNS = * # If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be # searched for input files to be used with the \include or \dontinclude # commands irrespective of the value of the RECURSIVE tag. # Possible values are YES and NO. If left blank NO is used. EXAMPLE_RECURSIVE = NO # The IMAGE_PATH tag can be used to specify one or more files or # directories that contain image that are included in the documentation (see # the \image command). IMAGE_PATH = @PROJECT_SOURCE_DIR@/doc/images # The INPUT_FILTER tag can be used to specify a program that doxygen should # invoke to filter for each input file. Doxygen will invoke the filter program # by executing (via popen()) the command , where # is the value of the INPUT_FILTER tag, and is the name of an # input file. Doxygen will then use the output that the filter program writes # to standard output. If FILTER_PATTERNS is specified, this tag will be # ignored. INPUT_FILTER = # The FILTER_PATTERNS tag can be used to specify filters on a per file pattern # basis. Doxygen will compare the file name with each pattern and apply the # filter if there is a match. The filters are a list of the form: # pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further # info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER # is applied to all files. FILTER_PATTERNS = # If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using # INPUT_FILTER) will be used to filter the input files when producing source # files to browse (i.e. when SOURCE_BROWSER is set to YES). FILTER_SOURCE_FILES = NO #--------------------------------------------------------------------------- # configuration options related to source browsing #--------------------------------------------------------------------------- # If the SOURCE_BROWSER tag is set to YES then a list of source files will # be generated. Documented entities will be cross-referenced with these sources. # Note: To get rid of all source code in the generated output, make sure also # VERBATIM_HEADERS is set to NO. SOURCE_BROWSER = YES # Setting the INLINE_SOURCES tag to YES will include the body # of functions and classes directly in the documentation. INLINE_SOURCES = NO # Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct # doxygen to hide any special comment blocks from generated source code # fragments. Normal C and C++ comments will always remain visible. STRIP_CODE_COMMENTS = YES # If the REFERENCED_BY_RELATION tag is set to YES # then for each documented function all documented # functions referencing it will be listed. REFERENCED_BY_RELATION = YES # If the REFERENCES_RELATION tag is set to YES # then for each documented function all documented entities # called/used by that function will be listed. REFERENCES_RELATION = YES # If the REFERENCES_LINK_SOURCE tag is set to YES (the default) # and SOURCE_BROWSER tag is set to YES, then the hyperlinks from # functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will # link to the source code. Otherwise they will link to the documentation. REFERENCES_LINK_SOURCE = YES # If the USE_HTAGS tag is set to YES then the references to source code # will point to the HTML generated by the htags(1) tool instead of doxygen # built-in source browser. The htags tool is part of GNU's global source # tagging system (see http://www.gnu.org/software/global/global.html). You # will need version 4.8.6 or higher. USE_HTAGS = NO # If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen # will generate a verbatim copy of the header file for each class for # which an include is specified. Set to NO to disable this. VERBATIM_HEADERS = NO #--------------------------------------------------------------------------- # configuration options related to the alphabetical class index #--------------------------------------------------------------------------- # If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index # of all compounds will be generated. Enable this if the project # contains a lot of classes, structs, unions or interfaces. ALPHABETICAL_INDEX = NO # If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then # the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns # in which this list will be split (can be a number in the range [1..20]) COLS_IN_ALPHA_INDEX = 5 # In case all classes in a project start with a common prefix, all # classes will be put under the same header in the alphabetical index. # The IGNORE_PREFIX tag can be used to specify one or more prefixes that # should be ignored while generating the index headers. IGNORE_PREFIX = #--------------------------------------------------------------------------- # configuration options related to the HTML output #--------------------------------------------------------------------------- # If the GENERATE_HTML tag is set to YES (the default) Doxygen will # generate HTML output. GENERATE_HTML = YES # The HTML_OUTPUT tag is used to specify where the HTML docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `html' will be used as the default path. HTML_OUTPUT = html # The HTML_FILE_EXTENSION tag can be used to specify the file extension for # each generated HTML page (for example: .htm,.php,.asp). If it is left blank # doxygen will generate files with .html extension. HTML_FILE_EXTENSION = .html # The HTML_HEADER tag can be used to specify a personal HTML header for # each generated HTML page. If it is left blank doxygen will generate a # standard header. HTML_HEADER = # The HTML_FOOTER tag can be used to specify a personal HTML footer for # each generated HTML page. If it is left blank doxygen will generate a # standard footer. HTML_FOOTER = # The HTML_STYLESHEET tag can be used to specify a user-defined cascading # style sheet that is used by each HTML page. It can be used to # fine-tune the look of the HTML output. If the tag is left blank doxygen # will generate a default style sheet. Note that doxygen will try to copy # the style sheet file to the HTML output directory, so don't put your own # stylesheet in the HTML output directory as well, or it will be erased! HTML_STYLESHEET = # If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, # files or namespaces will be aligned in HTML using tables. If set to # NO a bullet list will be used. HTML_ALIGN_MEMBERS = YES # If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML # documentation will contain sections that can be hidden and shown after the # page has loaded. For this to work a browser that supports # JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox # Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). HTML_DYNAMIC_SECTIONS = NO # If the GENERATE_DOCSET tag is set to YES, additional index files # will be generated that can be used as input for Apple's Xcode 3 # integrated development environment, introduced with OSX 10.5 (Leopard). # To create a documentation set, doxygen will generate a Makefile in the # HTML output directory. Running make will produce the docset in that # directory and running "make install" will install the docset in # ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find # it at startup. # See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html for more information. GENERATE_DOCSET = NO # When GENERATE_DOCSET tag is set to YES, this tag determines the name of the # feed. A documentation feed provides an umbrella under which multiple # documentation sets from a single provider (such as a company or product suite) # can be grouped. DOCSET_FEEDNAME = "Doxygen generated docs" # When GENERATE_DOCSET tag is set to YES, this tag specifies a string that # should uniquely identify the documentation set bundle. This should be a # reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen # will append .docset to the name. DOCSET_BUNDLE_ID = org.doxygen.Project # If the GENERATE_HTMLHELP tag is set to YES, additional index files # will be generated that can be used as input for tools like the # Microsoft HTML help workshop to generate a compiled HTML help file (.chm) # of the generated HTML documentation. GENERATE_HTMLHELP = NO # If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can # be used to specify the file name of the resulting .chm file. You # can add a path in front of the file if the result should not be # written to the html output directory. CHM_FILE = # If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can # be used to specify the location (absolute path including file name) of # the HTML help compiler (hhc.exe). If non-empty doxygen will try to run # the HTML help compiler on the generated index.hhp. HHC_LOCATION = # If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag # controls if a separate .chi index file is generated (YES) or that # it should be included in the master .chm file (NO). GENERATE_CHI = NO # If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING # is used to encode HtmlHelp index (hhk), content (hhc) and project file # content. CHM_INDEX_ENCODING = # If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag # controls whether a binary table of contents is generated (YES) or a # normal table of contents (NO) in the .chm file. BINARY_TOC = NO # The TOC_EXPAND flag can be set to YES to add extra items for group members # to the contents of the HTML help documentation and to the tree view. TOC_EXPAND = YES # If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and QHP_VIRTUAL_FOLDER # are set, an additional index file will be generated that can be used as input for # Qt's qhelpgenerator to generate a Qt Compressed Help (.qch) of the generated # HTML documentation. GENERATE_QHP = NO # If the QHG_LOCATION tag is specified, the QCH_FILE tag can # be used to specify the file name of the resulting .qch file. # The path specified is relative to the HTML output folder. QCH_FILE = # The QHP_NAMESPACE tag specifies the namespace to use when generating # Qt Help Project output. For more information please see # http://doc.trolltech.com/qthelpproject.html#namespace QHP_NAMESPACE = # The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating # Qt Help Project output. For more information please see # http://doc.trolltech.com/qthelpproject.html#virtual-folders QHP_VIRTUAL_FOLDER = doc # If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to add. # For more information please see # http://doc.trolltech.com/qthelpproject.html#custom-filters QHP_CUST_FILTER_NAME = # The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the custom filter to add.For more information please see # Qt Help Project / Custom Filters. QHP_CUST_FILTER_ATTRS = # The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this project's # filter section matches. # Qt Help Project / Filter Attributes. QHP_SECT_FILTER_ATTRS = # If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can # be used to specify the location of Qt's qhelpgenerator. # If non-empty doxygen will try to run qhelpgenerator on the generated # .qhp file. QHG_LOCATION = # The DISABLE_INDEX tag can be used to turn on/off the condensed index at # top of each HTML page. The value NO (the default) enables the index and # the value YES disables it. DISABLE_INDEX = NO # This tag can be used to set the number of enum values (range [1..20]) # that doxygen will group on one line in the generated HTML documentation. ENUM_VALUES_PER_LINE = 4 # The GENERATE_TREEVIEW tag is used to specify whether a tree-like index # structure should be generated to display hierarchical information. # If the tag value is set to FRAME, a side panel will be generated # containing a tree-like index structure (just like the one that # is generated for HTML Help). For this to work a browser that supports # JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, # Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are # probably better off using the HTML help feature. Other possible values # for this tag are: HIERARCHIES, which will generate the Groups, Directories, # and Class Hierarchy pages using a tree view instead of an ordered list; # ALL, which combines the behavior of FRAME and HIERARCHIES; and NONE, which # disables this behavior completely. For backwards compatibility with previous # releases of Doxygen, the values YES and NO are equivalent to FRAME and NONE # respectively. GENERATE_TREEVIEW = ALL # If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be # used to set the initial width (in pixels) of the frame in which the tree # is shown. TREEVIEW_WIDTH = 250 # Use this tag to change the font size of Latex formulas included # as images in the HTML documentation. The default is 10. Note that # when you change the font size after a successful doxygen run you need # to manually remove any form_*.png images from the HTML output directory # to force them to be regenerated. FORMULA_FONTSIZE = 10 #--------------------------------------------------------------------------- # configuration options related to the LaTeX output #--------------------------------------------------------------------------- # If the GENERATE_LATEX tag is set to YES (the default) Doxygen will # generate Latex output. GENERATE_LATEX = YES # The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `latex' will be used as the default path. LATEX_OUTPUT = latex # The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be # invoked. If left blank `latex' will be used as the default command name. LATEX_CMD_NAME = latex # The MAKEINDEX_CMD_NAME tag can be used to specify the command name to # generate index for LaTeX. If left blank `makeindex' will be used as the # default command name. MAKEINDEX_CMD_NAME = makeindex # If the COMPACT_LATEX tag is set to YES Doxygen generates more compact # LaTeX documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_LATEX = NO # The PAPER_TYPE tag can be used to set the paper type that is used # by the printer. Possible values are: a4, a4wide, letter, legal and # executive. If left blank a4wide will be used. PAPER_TYPE = a4wide # The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX # packages that should be included in the LaTeX output. EXTRA_PACKAGES = # The LATEX_HEADER tag can be used to specify a personal LaTeX header for # the generated latex document. The header should contain everything until # the first chapter. If it is left blank doxygen will generate a # standard header. Notice: only use this tag if you know what you are doing! LATEX_HEADER = # If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated # is prepared for conversion to pdf (using ps2pdf). The pdf file will # contain links (just like the HTML output) instead of page references # This makes the output suitable for online browsing using a pdf viewer. PDF_HYPERLINKS = YES # If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of # plain latex in the generated Makefile. Set this option to YES to get a # higher quality PDF documentation. USE_PDFLATEX = YES # If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. # command to the generated LaTeX files. This will instruct LaTeX to keep # running if errors occur, instead of asking the user for help. # This option is also used when generating formulas in HTML. LATEX_BATCHMODE = NO # If LATEX_HIDE_INDICES is set to YES then doxygen will not # include the index chapters (such as File Index, Compound Index, etc.) # in the output. LATEX_HIDE_INDICES = NO #--------------------------------------------------------------------------- # configuration options related to the RTF output #--------------------------------------------------------------------------- # If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output # The RTF output is optimized for Word 97 and may not look very pretty with # other RTF readers or editors. GENERATE_RTF = YES # The RTF_OUTPUT tag is used to specify where the RTF docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `rtf' will be used as the default path. RTF_OUTPUT = rtf # If the COMPACT_RTF tag is set to YES Doxygen generates more compact # RTF documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_RTF = NO # If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated # will contain hyperlink fields. The RTF file will # contain links (just like the HTML output) instead of page references. # This makes the output suitable for online browsing using WORD or other # programs which support those fields. # Note: wordpad (write) and others do not support links. RTF_HYPERLINKS = NO # Load stylesheet definitions from file. Syntax is similar to doxygen's # config file, i.e. a series of assignments. You only have to provide # replacements, missing definitions are set to their default value. RTF_STYLESHEET_FILE = # Set optional variables used in the generation of an rtf document. # Syntax is similar to doxygen's config file. RTF_EXTENSIONS_FILE = #--------------------------------------------------------------------------- # configuration options related to the man page output #--------------------------------------------------------------------------- # If the GENERATE_MAN tag is set to YES (the default) Doxygen will # generate man pages GENERATE_MAN = NO # The MAN_OUTPUT tag is used to specify where the man pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `man' will be used as the default path. MAN_OUTPUT = man # The MAN_EXTENSION tag determines the extension that is added to # the generated man pages (default is the subroutine's section .3) MAN_EXTENSION = .3 # If the MAN_LINKS tag is set to YES and Doxygen generates man output, # then it will generate one additional man file for each entity # documented in the real man page(s). These additional files # only source the real man page, but without them the man command # would be unable to find the correct page. The default is NO. MAN_LINKS = NO #--------------------------------------------------------------------------- # configuration options related to the XML output #--------------------------------------------------------------------------- # If the GENERATE_XML tag is set to YES Doxygen will # generate an XML file that captures the structure of # the code including all documentation. GENERATE_XML = NO # The XML_OUTPUT tag is used to specify where the XML pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `xml' will be used as the default path. XML_OUTPUT = xml # The XML_SCHEMA tag can be used to specify an XML schema, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_SCHEMA = # The XML_DTD tag can be used to specify an XML DTD, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_DTD = # If the XML_PROGRAMLISTING tag is set to YES Doxygen will # dump the program listings (including syntax highlighting # and cross-referencing information) to the XML output. Note that # enabling this will significantly increase the size of the XML output. XML_PROGRAMLISTING = YES #--------------------------------------------------------------------------- # configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- # If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will # generate an AutoGen Definitions (see autogen.sf.net) file # that captures the structure of the code including all # documentation. Note that this feature is still experimental # and incomplete at the moment. GENERATE_AUTOGEN_DEF = NO #--------------------------------------------------------------------------- # configuration options related to the Perl module output #--------------------------------------------------------------------------- # If the GENERATE_PERLMOD tag is set to YES Doxygen will # generate a Perl module file that captures the structure of # the code including all documentation. Note that this # feature is still experimental and incomplete at the # moment. GENERATE_PERLMOD = NO # If the PERLMOD_LATEX tag is set to YES Doxygen will generate # the necessary Makefile rules, Perl scripts and LaTeX code to be able # to generate PDF and DVI output from the Perl module output. PERLMOD_LATEX = NO # If the PERLMOD_PRETTY tag is set to YES the Perl module output will be # nicely formatted so it can be parsed by a human reader. This is useful # if you want to understand what is going on. On the other hand, if this # tag is set to NO the size of the Perl module output will be much smaller # and Perl will parse it just the same. PERLMOD_PRETTY = YES # The names of the make variables in the generated doxyrules.make file # are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. # This is useful so different doxyrules.make files included by the same # Makefile don't overwrite each other's variables. PERLMOD_MAKEVAR_PREFIX = #--------------------------------------------------------------------------- # Configuration options related to the preprocessor #--------------------------------------------------------------------------- # If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will # evaluate all C-preprocessor directives found in the sources and include # files. ENABLE_PREPROCESSING = YES # If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro # names in the source code. If set to NO (the default) only conditional # compilation will be performed. Macro expansion can be done in a controlled # way by setting EXPAND_ONLY_PREDEF to YES. MACRO_EXPANSION = NO # If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES # then the macro expansion is limited to the macros specified with the # PREDEFINED and EXPAND_AS_DEFINED tags. EXPAND_ONLY_PREDEF = NO # If the SEARCH_INCLUDES tag is set to YES (the default) the includes files # in the INCLUDE_PATH (see below) will be search if a #include is found. SEARCH_INCLUDES = YES # The INCLUDE_PATH tag can be used to specify one or more directories that # contain include files that are not input files but should be processed by # the preprocessor. INCLUDE_PATH = # You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard # patterns (like *.h and *.hpp) to filter out the header-files in the # directories. If left blank, the patterns specified with FILE_PATTERNS will # be used. INCLUDE_FILE_PATTERNS = # The PREDEFINED tag can be used to specify one or more macro names that # are defined before the preprocessor is started (similar to the -D option of # gcc). The argument of the tag is a list of macros of the form: name # or name=definition (no spaces). If the definition and the = are # omitted =1 is assumed. To prevent a macro definition from being # undefined via #undef or recursively expanded use the := operator # instead of the = operator. PREDEFINED = # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then # this tag can be used to specify a list of macro names that should be expanded. # The macro definition that is found in the sources will be used. # Use the PREDEFINED tag if you want to use a different macro definition. EXPAND_AS_DEFINED = # If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then # doxygen's preprocessor will remove all function-like macros that are alone # on a line, have an all uppercase name, and do not end with a semicolon. Such # function macros are typically used for boiler-plate code, and will confuse # the parser if not removed. SKIP_FUNCTION_MACROS = NO #--------------------------------------------------------------------------- # Configuration::additions related to external references #--------------------------------------------------------------------------- # The TAGFILES option can be used to specify one or more tagfiles. # Optionally an initial location of the external documentation # can be added for each tagfile. The format of a tag file without # this location is as follows: # TAGFILES = file1 file2 ... # Adding location for the tag files is done as follows: # TAGFILES = file1=loc1 "file2 = loc2" ... # where "loc1" and "loc2" can be relative or absolute paths or # URLs. If a location is present for each tag, the installdox tool # does not have to be run to correct the links. # Note that each tag file must have a unique name # (where the name does NOT include the path) # If a tag file is not located in the directory in which doxygen # is run, you must also specify the path to the tagfile here. TAGFILES = # When a file name is specified after GENERATE_TAGFILE, doxygen will create # a tag file that is based on the input files it reads. GENERATE_TAGFILE = # If the ALLEXTERNALS tag is set to YES all external classes will be listed # in the class index. If set to NO only the inherited external classes # will be listed. ALLEXTERNALS = NO # If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed # in the modules index. If set to NO, only the current project's groups will # be listed. EXTERNAL_GROUPS = YES # The PERL_PATH should be the absolute path and name of the perl script # interpreter (i.e. the result of `which perl'). PERL_PATH = /usr/bin/perl #--------------------------------------------------------------------------- # Configuration options related to the dot tool #--------------------------------------------------------------------------- # If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will # generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base # or super classes. Setting the tag to NO turns the diagrams off. Note that # this option is superseded by the HAVE_DOT option below. This is only a # fallback. It is recommended to install and use dot, since it yields more # powerful graphs. CLASS_DIAGRAMS = NO # You can define message sequence charts within doxygen comments using the \msc # command. Doxygen will then run the mscgen tool (see # http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the # documentation. The MSCGEN_PATH tag allows you to specify the directory where # the mscgen tool resides. If left empty the tool is assumed to be found in the # default search path. MSCGEN_PATH = # If set to YES, the inheritance and collaboration graphs will hide # inheritance and usage relations if the target is undocumented # or is not a class. HIDE_UNDOC_RELATIONS = YES # If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is # available from the path. This tool is part of Graphviz, a graph visualization # toolkit from AT&T and Lucent Bell Labs. The other options in this section # have no effect if this option is set to NO (the default) HAVE_DOT = @HAVE_DOT@ # By default doxygen will write a font called FreeSans.ttf to the output # directory and reference it in all dot files that doxygen generates. This # font does not include all possible unicode characters however, so when you need # these (or just want a differently looking font) you can specify the font name # using DOT_FONTNAME. You need need to make sure dot is able to find the font, # which can be done by putting it in a standard location or by setting the # DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory # containing the font. DOT_FONTNAME = FreeSans # The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. # The default size is 10pt. DOT_FONTSIZE = 10 # By default doxygen will tell dot to use the output directory to look for the # FreeSans.ttf font (which doxygen will put there itself). If you specify a # different font using DOT_FONTNAME you can set the path where dot # can find it using this tag. DOT_FONTPATH = # If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect inheritance relations. Setting this tag to YES will force the # the CLASS_DIAGRAMS tag to NO. CLASS_GRAPH = YES # If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect implementation dependencies (inheritance, containment, and # class references variables) of the class with other documented classes. COLLABORATION_GRAPH = YES # If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen # will generate a graph for groups, showing the direct groups dependencies GROUP_GRAPHS = YES # If the UML_LOOK tag is set to YES doxygen will generate inheritance and # collaboration diagrams in a style similar to the OMG's Unified Modeling # Language. UML_LOOK = NO # If set to YES, the inheritance and collaboration graphs will show the # relations between templates and their instances. TEMPLATE_RELATIONS = NO # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT # tags are set to YES then doxygen will generate a graph for each documented # file showing the direct and indirect include dependencies of the file with # other documented files. INCLUDE_GRAPH = YES # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and # HAVE_DOT tags are set to YES then doxygen will generate a graph for each # documented header file showing the documented files that directly or # indirectly include this file. INCLUDED_BY_GRAPH = YES # If the CALL_GRAPH and HAVE_DOT options are set to YES then # doxygen will generate a call dependency graph for every global function # or class method. Note that enabling this option will significantly increase # the time of a run. So in most cases it will be better to enable call graphs # for selected functions only using the \callgraph command. CALL_GRAPH = NO # If the CALLER_GRAPH and HAVE_DOT tags are set to YES then # doxygen will generate a caller dependency graph for every global function # or class method. Note that enabling this option will significantly increase # the time of a run. So in most cases it will be better to enable caller # graphs for selected functions only using the \callergraph command. CALLER_GRAPH = NO # If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen # will graphical hierarchy of all classes instead of a textual one. GRAPHICAL_HIERARCHY = YES # If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES # then doxygen will show the dependencies a directory has on other directories # in a graphical way. The dependency relations are determined by the #include # relations between the files in the directories. DIRECTORY_GRAPH = YES # The DOT_IMAGE_FORMAT tag can be used to set the image format of the images # generated by dot. Possible values are png, jpg, or gif # If left blank png will be used. DOT_IMAGE_FORMAT = png # The tag DOT_PATH can be used to specify the path where the dot tool can be # found. If left blank, it is assumed the dot tool can be found in the path. DOT_PATH = # The DOTFILE_DIRS tag can be used to specify one or more directories that # contain dot files that are included in the documentation (see the # \dotfile command). DOTFILE_DIRS = # The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of # nodes that will be shown in the graph. If the number of nodes in a graph # becomes larger than this value, doxygen will truncate the graph, which is # visualized by representing a node as a red box. Note that doxygen if the # number of direct children of the root node in a graph is already larger than # DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note # that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. DOT_GRAPH_MAX_NODES = 50 # The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the # graphs generated by dot. A depth value of 3 means that only nodes reachable # from the root by following a path via at most 3 edges will be shown. Nodes # that lay further from the root node will be omitted. Note that setting this # option to 1 or 2 may greatly reduce the computation time needed for large # code bases. Also note that the size of a graph can be further restricted by # DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. MAX_DOT_GRAPH_DEPTH = 0 # Set the DOT_TRANSPARENT tag to YES to generate images with a transparent # background. This is disabled by default, because dot on Windows does not # seem to support this out of the box. Warning: Depending on the platform used, # enabling this option may lead to badly anti-aliased labels on the edges of # a graph (i.e. they become hard to read). DOT_TRANSPARENT = NO # Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output # files in one run (i.e. multiple -o and -T options on the command line). This # makes dot run faster, but since only newer versions of dot (>1.8.10) # support this, this feature is disabled by default. DOT_MULTI_TARGETS = NO # If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will # generate a legend page explaining the meaning of the various boxes and # arrows in the dot generated graphs. GENERATE_LEGEND = YES # If the DOT_CLEANUP tag is set to YES (the default) Doxygen will # remove the intermediate dot files that are used to generate # the various graphs. DOT_CLEANUP = YES #--------------------------------------------------------------------------- # Options related to the search engine #--------------------------------------------------------------------------- # The SEARCHENGINE tag specifies whether or not a search engine should be # used. If set to NO the values of all tags below this one will be ignored. SEARCHENGINE = NO dlt-daemon-2.18.4/doc/extended_network_trace_doxygen.cfg.cmake000066400000000000000000001754101353342203500244330ustar00rootroot00000000000000####### # SPDX license identifier: MPL-2.0 # # Copyright (C) 2011-2015, BMW AG # # This file is part of GENIVI Project DLT - Diagnostic Log and Trace. # # This Source Code Form is subject to the terms of the # Mozilla Public License (MPL), v. 2.0. # If a copy of the MPL was not distributed with this file, # You can obtain one at http://mozilla.org/MPL/2.0/. # # For further information see http://www.genivi.org/. ####### # Doxyfile 1.5.8 # This file describes the settings to be used by the documentation system # doxygen (www.doxygen.org) for a project # # All text after a hash (#) is considered a comment and will be ignored # The format is: # TAG = value [value, ...] # For lists items can also be appended using: # TAG += value [value, ...] # Values that contain spaces should be placed between quotes (" ") #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- # This tag specifies the encoding used for all characters in the config file # that follow. The default is UTF-8 which is also the encoding used for all # text before the first occurrence of this tag. Doxygen uses libiconv (or the # iconv built into libc) for the transcoding. See # http://www.gnu.org/software/libiconv for the list of possible encodings. DOXYFILE_ENCODING = UTF-8 # The PROJECT_NAME tag is a single word (or a sequence of words surrounded # by quotes) that should identify the project. PROJECT_NAME = @PROJECT_NAME@ - ExtendedNetworkTrace # The PROJECT_NUMBER tag can be used to enter a project or revision number. # This could be handy for archiving the generated documentation or # if some version control system is used. PROJECT_NUMBER = @GENIVI_PROJECT_VERSION@ # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) # base path where the generated documentation will be put. # If a relative path is entered, it will be relative to the location # where doxygen was started. If left blank the current directory will be used. OUTPUT_DIRECTORY = ./DOC_DLT_ExtendedNetworkTrace # If the CREATE_SUBDIRS tag is set to YES, then doxygen will create # 4096 sub-directories (in 2 levels) under the output directory of each output # format and will distribute the generated files over these directories. # Enabling this option can be useful when feeding doxygen a huge amount of # source files, where putting all generated files in the same directory would # otherwise cause performance problems for the file system. CREATE_SUBDIRS = NO # The OUTPUT_LANGUAGE tag is used to specify the language in which all # documentation generated by doxygen is written. Doxygen will use this # information to generate all constant output in the proper language. # The default language is English, other supported languages are: # Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, # Croatian, Czech, Danish, Dutch, Farsi, Finnish, French, German, Greek, # Hungarian, Italian, Japanese, Japanese-en (Japanese with English messages), # Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, Polish, # Portuguese, Romanian, Russian, Serbian, Serbian-Cyrilic, Slovak, Slovene, # Spanish, Swedish, and Ukrainian. OUTPUT_LANGUAGE = English # If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will # include brief member descriptions after the members that are listed in # the file and class documentation (similar to JavaDoc). # Set to NO to disable this. BRIEF_MEMBER_DESC = YES # If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend # the brief description of a member or function before the detailed description. # Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the # brief descriptions will be completely suppressed. REPEAT_BRIEF = YES # This tag implements a quasi-intelligent brief description abbreviator # that is used to form the text in various listings. Each string # in this list, if found as the leading text of the brief description, will be # stripped from the text and the result after processing the whole list, is # used as the annotated text. Otherwise, the brief description is used as-is. # If left blank, the following values are used ("$name" is automatically # replaced with the name of the entity): "The $name class" "The $name widget" # "The $name file" "is" "provides" "specifies" "contains" # "represents" "a" "an" "the" ABBREVIATE_BRIEF = "The $name class" \ "The $name widget" \ "The $name file" \ is \ provides \ specifies \ contains \ represents \ a \ an \ the # If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then # Doxygen will generate a detailed section even if there is only a brief # description. ALWAYS_DETAILED_SEC = NO # If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all # inherited members of a class in the documentation of that class as if those # members were ordinary class members. Constructors, destructors and assignment # operators of the base classes will not be shown. INLINE_INHERITED_MEMB = NO # If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full # path before files name in the file list and in the header files. If set # to NO the shortest path that makes the file name unique will be used. FULL_PATH_NAMES = YES # If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag # can be used to strip a user-defined part of the path. Stripping is # only done if one of the specified strings matches the left-hand part of # the path. The tag can be used to show relative paths in the file list. # If left blank the directory from which doxygen is run is used as the # path to strip. STRIP_FROM_PATH = # The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of # the path mentioned in the documentation of a class, which tells # the reader which header file to include in order to use a class. # If left blank only the name of the header file containing the class # definition is used. Otherwise one should specify the include paths that # are normally passed to the compiler using the -I flag. STRIP_FROM_INC_PATH = # If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter # (but less readable) file names. This can be useful is your file systems # doesn't support long names like on DOS, Mac, or CD-ROM. SHORT_NAMES = NO # If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen # will interpret the first line (until the first dot) of a JavaDoc-style # comment as the brief description. If set to NO, the JavaDoc # comments will behave just like regular Qt-style comments # (thus requiring an explicit @brief command for a brief description.) JAVADOC_AUTOBRIEF = NO # If the QT_AUTOBRIEF tag is set to YES then Doxygen will # interpret the first line (until the first dot) of a Qt-style # comment as the brief description. If set to NO, the comments # will behave just like regular Qt-style comments (thus requiring # an explicit \brief command for a brief description.) QT_AUTOBRIEF = NO # The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen # treat a multi-line C++ special comment block (i.e. a block of //! or /// # comments) as a brief description. This used to be the default behaviour. # The new default is to treat a multi-line C++ comment block as a detailed # description. Set this tag to YES if you prefer the old behaviour instead. MULTILINE_CPP_IS_BRIEF = NO # If the INHERIT_DOCS tag is set to YES (the default) then an undocumented # member inherits the documentation from any documented member that it # re-implements. INHERIT_DOCS = YES # If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce # a new page for each member. If set to NO, the documentation of a member will # be part of the file/class/namespace that contains it. SEPARATE_MEMBER_PAGES = NO # The TAB_SIZE tag can be used to set the number of spaces in a tab. # Doxygen uses this value to replace tabs by spaces in code fragments. TAB_SIZE = 8 # This tag can be used to specify a number of aliases that acts # as commands in the documentation. An alias has the form "name=value". # For example adding "sideeffect=\par Side Effects:\n" will allow you to # put the command \sideeffect (or @sideeffect) in the documentation, which # will result in a user-defined paragraph with heading "Side Effects:". # You can put \n's in the value part of an alias to insert newlines. ALIASES = # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C # sources only. Doxygen will then generate output that is more tailored for C. # For instance, some of the names that are used will be different. The list # of all members will be omitted, etc. OPTIMIZE_OUTPUT_FOR_C = YES # Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java # sources only. Doxygen will then generate output that is more tailored for # Java. For instance, namespaces will be presented as packages, qualified # scopes will look different, etc. OPTIMIZE_OUTPUT_JAVA = NO # Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran # sources only. Doxygen will then generate output that is more tailored for # Fortran. OPTIMIZE_FOR_FORTRAN = NO # Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL # sources. Doxygen will then generate output that is tailored for # VHDL. OPTIMIZE_OUTPUT_VHDL = NO # Doxygen selects the parser to use depending on the extension of the files it parses. # With this tag you can assign which parser to use for a given extension. # Doxygen has a built-in mapping, but you can override or extend it using this tag. # The format is ext=language, where ext is a file extension, and language is one of # the parsers supported by doxygen: IDL, Java, Javascript, C#, C, C++, D, PHP, # Objective-C, Python, Fortran, VHDL, C, C++. For instance to make doxygen treat # .inc files as Fortran files (default is PHP), and .f files as C (default is Fortran), # use: inc=Fortran f=C EXTENSION_MAPPING = # If you use STL classes (i.e. std::string, std::vector, etc.) but do not want # to include (a tag file for) the STL sources as input, then you should # set this tag to YES in order to let doxygen match functions declarations and # definitions whose arguments contain STL classes (e.g. func(std::string); v.s. # func(std::string) {}). This also make the inheritance and collaboration # diagrams that involve STL classes more complete and accurate. BUILTIN_STL_SUPPORT = NO # If you use Microsoft's C++/CLI language, you should set this option to YES to # enable parsing support. CPP_CLI_SUPPORT = NO # Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. # Doxygen will parse them like normal C++ but will assume all classes use public # instead of private inheritance when no explicit protection keyword is present. SIP_SUPPORT = NO # For Microsoft's IDL there are propget and propput attributes to indicate getter # and setter methods for a property. Setting this option to YES (the default) # will make doxygen to replace the get and set methods by a property in the # documentation. This will only work if the methods are indeed getting or # setting a simple type. If this is not the case, or you want to show the # methods anyway, you should set this option to NO. IDL_PROPERTY_SUPPORT = NO # If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC # tag is set to YES, then doxygen will reuse the documentation of the first # member in the group (if any) for the other members of the group. By default # all members of a group must be documented explicitly. DISTRIBUTE_GROUP_DOC = NO # Set the SUBGROUPING tag to YES (the default) to allow class member groups of # the same type (for instance a group of public functions) to be put as a # subgroup of that type (e.g. under the Public Functions section). Set it to # NO to prevent subgrouping. Alternatively, this can be done per class using # the \nosubgrouping command. SUBGROUPING = YES # When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum # is documented as struct, union, or enum with the name of the typedef. So # typedef struct TypeS {} TypeT, will appear in the documentation as a struct # with name TypeT. When disabled the typedef will appear as a member of a file, # namespace, or class. And the struct will be named TypeS. This can typically # be useful for C code in case the coding convention dictates that all compound # types are typedef'ed and only the typedef is referenced, never the tag name. TYPEDEF_HIDES_STRUCT = NO # The SYMBOL_CACHE_SIZE determines the size of the internal cache use to # determine which symbols to keep in memory and which to flush to disk. # When the cache is full, less often used symbols will be written to disk. # For small to medium size projects (<1000 input files) the default value is # probably good enough. For larger projects a too small cache size can cause # doxygen to be busy swapping symbols to and from disk most of the time # causing a significant performance penality. # If the system has enough physical memory increasing the cache will improve the # performance by keeping more symbols in memory. Note that the value works on # a logarithmic scale so increasing the size by one will rougly double the # memory usage. The cache size is given by this formula: # 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, # corresponding to a cache size of 2^16 = 65536 symbols SYMBOL_CACHE_SIZE = 0 #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- # If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in # documentation are documented, even if no documentation was available. # Private class members and static file members will be hidden unless # the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES EXTRACT_ALL = YES # If the EXTRACT_PRIVATE tag is set to YES all private members of a class # will be included in the documentation. EXTRACT_PRIVATE = YES # If the EXTRACT_STATIC tag is set to YES all static members of a file # will be included in the documentation. EXTRACT_STATIC = YES # If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) # defined locally in source files will be included in the documentation. # If set to NO only classes defined in header files are included. EXTRACT_LOCAL_CLASSES = YES # This flag is only useful for Objective-C code. When set to YES local # methods, which are defined in the implementation section but not in # the interface are included in the documentation. # If set to NO (the default) only methods in the interface are included. EXTRACT_LOCAL_METHODS = NO # If this flag is set to YES, the members of anonymous namespaces will be # extracted and appear in the documentation as a namespace called # 'anonymous_namespace{file}', where file will be replaced with the base # name of the file that contains the anonymous namespace. By default # anonymous namespace are hidden. EXTRACT_ANON_NSPACES = NO # If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all # undocumented members of documented classes, files or namespaces. # If set to NO (the default) these members will be included in the # various overviews, but no documentation section is generated. # This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_MEMBERS = NO # If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all # undocumented classes that are normally visible in the class hierarchy. # If set to NO (the default) these classes will be included in the various # overviews. This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_CLASSES = NO # If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all # friend (class|struct|union) declarations. # If set to NO (the default) these declarations will be included in the # documentation. HIDE_FRIEND_COMPOUNDS = NO # If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any # documentation blocks found inside the body of a function. # If set to NO (the default) these blocks will be appended to the # function's detailed documentation block. HIDE_IN_BODY_DOCS = NO # The INTERNAL_DOCS tag determines if documentation # that is typed after a \internal command is included. If the tag is set # to NO (the default) then the documentation will be excluded. # Set it to YES to include the internal documentation. INTERNAL_DOCS = YES # If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate # file names in lower-case letters. If set to YES upper-case letters are also # allowed. This is useful if you have classes or files whose names only differ # in case and if your file system supports case sensitive file names. Windows # and Mac users are advised to set this option to NO. CASE_SENSE_NAMES = NO # If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen # will show members with their full class and namespace scopes in the # documentation. If set to YES the scope will be hidden. HIDE_SCOPE_NAMES = NO # If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen # will put a list of the files that are included by a file in the documentation # of that file. SHOW_INCLUDE_FILES = YES # If the INLINE_INFO tag is set to YES (the default) then a tag [inline] # is inserted in the documentation for inline members. INLINE_INFO = YES # If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen # will sort the (detailed) documentation of file and class members # alphabetically by member name. If set to NO the members will appear in # declaration order. SORT_MEMBER_DOCS = YES # If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the # brief documentation of file, namespace and class members alphabetically # by member name. If set to NO (the default) the members will appear in # declaration order. SORT_BRIEF_DOCS = NO # If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the # hierarchy of group names into alphabetical order. If set to NO (the default) # the group names will appear in their defined order. SORT_GROUP_NAMES = NO # If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be # sorted by fully-qualified names, including namespaces. If set to # NO (the default), the class list will be sorted only by class name, # not including the namespace part. # Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. # Note: This option applies only to the class list, not to the # alphabetical list. SORT_BY_SCOPE_NAME = NO # The GENERATE_TODOLIST tag can be used to enable (YES) or # disable (NO) the todo list. This list is created by putting \todo # commands in the documentation. GENERATE_TODOLIST = YES # The GENERATE_TESTLIST tag can be used to enable (YES) or # disable (NO) the test list. This list is created by putting \test # commands in the documentation. GENERATE_TESTLIST = YES # The GENERATE_BUGLIST tag can be used to enable (YES) or # disable (NO) the bug list. This list is created by putting \bug # commands in the documentation. GENERATE_BUGLIST = YES # The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or # disable (NO) the deprecated list. This list is created by putting # \deprecated commands in the documentation. GENERATE_DEPRECATEDLIST= YES # The ENABLED_SECTIONS tag can be used to enable conditional # documentation sections, marked by \if sectionname ... \endif. ENABLED_SECTIONS = # The MAX_INITIALIZER_LINES tag determines the maximum number of lines # the initial value of a variable or define consists of for it to appear in # the documentation. If the initializer consists of more lines than specified # here it will be hidden. Use a value of 0 to hide initializers completely. # The appearance of the initializer of individual variables and defines in the # documentation can be controlled using \showinitializer or \hideinitializer # command in the documentation regardless of this setting. MAX_INITIALIZER_LINES = 30 # Set the SHOW_USED_FILES tag to NO to disable the list of files generated # at the bottom of the documentation of classes and structs. If set to YES the # list will mention the files that were used to generate the documentation. SHOW_USED_FILES = YES # If the sources in your project are distributed over multiple directories # then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy # in the documentation. The default is NO. SHOW_DIRECTORIES = NO # Set the SHOW_FILES tag to NO to disable the generation of the Files page. # This will remove the Files entry from the Quick Index and from the # Folder Tree View (if specified). The default is YES. SHOW_FILES = YES # Set the SHOW_NAMESPACES tag to NO to disable the generation of the # Namespaces page. This will remove the Namespaces entry from the Quick Index # and from the Folder Tree View (if specified). The default is YES. SHOW_NAMESPACES = YES # The FILE_VERSION_FILTER tag can be used to specify a program or script that # doxygen should invoke to get the current version for each file (typically from # the version control system). Doxygen will invoke the program by executing (via # popen()) the command , where is the value of # the FILE_VERSION_FILTER tag, and is the name of an input file # provided by doxygen. Whatever the program writes to standard output # is used as the file version. See the manual for examples. FILE_VERSION_FILTER = # The LAYOUT_FILE tag can be used to specify a layout file which will be parsed by # doxygen. The layout file controls the global structure of the generated output files # in an output format independent way. The create the layout file that represents # doxygen's defaults, run doxygen with the -l option. You can optionally specify a # file name after the option, if omitted DoxygenLayout.xml will be used as the name # of the layout file. LAYOUT_FILE = #--------------------------------------------------------------------------- # configuration options related to warning and progress messages #--------------------------------------------------------------------------- # The QUIET tag can be used to turn on/off the messages that are generated # by doxygen. Possible values are YES and NO. If left blank NO is used. QUIET = NO # The WARNINGS tag can be used to turn on/off the warning messages that are # generated by doxygen. Possible values are YES and NO. If left blank # NO is used. WARNINGS = YES # If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings # for undocumented members. If EXTRACT_ALL is set to YES then this flag will # automatically be disabled. WARN_IF_UNDOCUMENTED = YES # If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for # potential errors in the documentation, such as not documenting some # parameters in a documented function, or documenting parameters that # don't exist or using markup commands wrongly. WARN_IF_DOC_ERROR = YES # This WARN_NO_PARAMDOC option can be abled to get warnings for # functions that are documented, but have no documentation for their parameters # or return value. If set to NO (the default) doxygen will only warn about # wrong or incomplete parameter documentation, but not about the absence of # documentation. WARN_NO_PARAMDOC = NO # The WARN_FORMAT tag determines the format of the warning messages that # doxygen can produce. The string should contain the $file, $line, and $text # tags, which will be replaced by the file and line number from which the # warning originated and the warning text. Optionally the format may contain # $version, which will be replaced by the version of the file (if it could # be obtained via FILE_VERSION_FILTER) WARN_FORMAT = "$file:$line: $text" # The WARN_LOGFILE tag can be used to specify a file to which warning # and error messages should be written. If left blank the output is written # to stderr. WARN_LOGFILE = #--------------------------------------------------------------------------- # configuration options related to the input files #--------------------------------------------------------------------------- # The INPUT tag can be used to specify the files and/or directories that contain # documented source files. You may enter file names like "myfile.cpp" or # directories like "/usr/src/myproject". Separate the files or directories # with spaces. INPUT = ./../../doc/extended_network_trace_mainpage.h \ ./../src/lib/dlt_user.c \ ./../include/dlt_user.h # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is # also the default input encoding. Doxygen uses libiconv (or the iconv built # into libc) for the transcoding. See http://www.gnu.org/software/libiconv for # the list of possible encodings. INPUT_ENCODING = UTF-8 # If the value of the INPUT tag contains directories, you can use the # FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank the following patterns are tested: # *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx # *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90 FILE_PATTERNS = *.c \ *.cc \ *.cxx \ *.cpp \ *.c++ \ *.d \ *.java \ *.ii \ *.ixx \ *.ipp \ *.i++ \ *.inl \ *.h \ *.hh \ *.hxx \ *.hpp \ *.h++ # The RECURSIVE tag can be used to turn specify whether or not subdirectories # should be searched for input files as well. Possible values are YES and NO. # If left blank NO is used. RECURSIVE = YES # The EXCLUDE tag can be used to specify files and/or directories that should # excluded from the INPUT source files. This way you can easily exclude a # subdirectory from a directory tree whose root is specified with the INPUT tag. EXCLUDE = doc \ examples \ .git # The EXCLUDE_SYMLINKS tag can be used select whether or not files or # directories that are symbolic links (a Unix filesystem feature) are excluded # from the input. EXCLUDE_SYMLINKS = NO # If the value of the INPUT tag contains directories, you can use the # EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude # certain files from those directories. Note that the wildcards are matched # against the file with absolute path, so to exclude all test directories # for example use the pattern */test/* EXCLUDE_PATTERNS = # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names # (namespaces, classes, functions, etc.) that should be excluded from the # output. The symbol name can be a fully qualified name, a word, or if the # wildcard * is used, a substring. Examples: ANamespace, AClass, # AClass::ANamespace, ANamespace::*Test EXCLUDE_SYMBOLS = # The EXAMPLE_PATH tag can be used to specify one or more files or # directories that contain example code fragments that are included (see # the \include command). EXAMPLE_PATH = # If the value of the EXAMPLE_PATH tag contains directories, you can use the # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank all files are included. EXAMPLE_PATTERNS = * # If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be # searched for input files to be used with the \include or \dontinclude # commands irrespective of the value of the RECURSIVE tag. # Possible values are YES and NO. If left blank NO is used. EXAMPLE_RECURSIVE = NO # The IMAGE_PATH tag can be used to specify one or more files or # directories that contain image that are included in the documentation (see # the \image command). IMAGE_PATH = @PROJECT_SOURCE_DIR@/doc/images # The INPUT_FILTER tag can be used to specify a program that doxygen should # invoke to filter for each input file. Doxygen will invoke the filter program # by executing (via popen()) the command , where # is the value of the INPUT_FILTER tag, and is the name of an # input file. Doxygen will then use the output that the filter program writes # to standard output. If FILTER_PATTERNS is specified, this tag will be # ignored. INPUT_FILTER = # The FILTER_PATTERNS tag can be used to specify filters on a per file pattern # basis. Doxygen will compare the file name with each pattern and apply the # filter if there is a match. The filters are a list of the form: # pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further # info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER # is applied to all files. FILTER_PATTERNS = # If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using # INPUT_FILTER) will be used to filter the input files when producing source # files to browse (i.e. when SOURCE_BROWSER is set to YES). FILTER_SOURCE_FILES = NO #--------------------------------------------------------------------------- # configuration options related to source browsing #--------------------------------------------------------------------------- # If the SOURCE_BROWSER tag is set to YES then a list of source files will # be generated. Documented entities will be cross-referenced with these sources. # Note: To get rid of all source code in the generated output, make sure also # VERBATIM_HEADERS is set to NO. SOURCE_BROWSER = YES # Setting the INLINE_SOURCES tag to YES will include the body # of functions and classes directly in the documentation. INLINE_SOURCES = NO # Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct # doxygen to hide any special comment blocks from generated source code # fragments. Normal C and C++ comments will always remain visible. STRIP_CODE_COMMENTS = YES # If the REFERENCED_BY_RELATION tag is set to YES # then for each documented function all documented # functions referencing it will be listed. REFERENCED_BY_RELATION = YES # If the REFERENCES_RELATION tag is set to YES # then for each documented function all documented entities # called/used by that function will be listed. REFERENCES_RELATION = YES # If the REFERENCES_LINK_SOURCE tag is set to YES (the default) # and SOURCE_BROWSER tag is set to YES, then the hyperlinks from # functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will # link to the source code. Otherwise they will link to the documentation. REFERENCES_LINK_SOURCE = YES # If the USE_HTAGS tag is set to YES then the references to source code # will point to the HTML generated by the htags(1) tool instead of doxygen # built-in source browser. The htags tool is part of GNU's global source # tagging system (see http://www.gnu.org/software/global/global.html). You # will need version 4.8.6 or higher. USE_HTAGS = NO # If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen # will generate a verbatim copy of the header file for each class for # which an include is specified. Set to NO to disable this. VERBATIM_HEADERS = NO #--------------------------------------------------------------------------- # configuration options related to the alphabetical class index #--------------------------------------------------------------------------- # If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index # of all compounds will be generated. Enable this if the project # contains a lot of classes, structs, unions or interfaces. ALPHABETICAL_INDEX = NO # If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then # the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns # in which this list will be split (can be a number in the range [1..20]) COLS_IN_ALPHA_INDEX = 5 # In case all classes in a project start with a common prefix, all # classes will be put under the same header in the alphabetical index. # The IGNORE_PREFIX tag can be used to specify one or more prefixes that # should be ignored while generating the index headers. IGNORE_PREFIX = #--------------------------------------------------------------------------- # configuration options related to the HTML output #--------------------------------------------------------------------------- # If the GENERATE_HTML tag is set to YES (the default) Doxygen will # generate HTML output. GENERATE_HTML = YES # The HTML_OUTPUT tag is used to specify where the HTML docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `html' will be used as the default path. HTML_OUTPUT = html # The HTML_FILE_EXTENSION tag can be used to specify the file extension for # each generated HTML page (for example: .htm,.php,.asp). If it is left blank # doxygen will generate files with .html extension. HTML_FILE_EXTENSION = .html # The HTML_HEADER tag can be used to specify a personal HTML header for # each generated HTML page. If it is left blank doxygen will generate a # standard header. HTML_HEADER = # The HTML_FOOTER tag can be used to specify a personal HTML footer for # each generated HTML page. If it is left blank doxygen will generate a # standard footer. HTML_FOOTER = # The HTML_STYLESHEET tag can be used to specify a user-defined cascading # style sheet that is used by each HTML page. It can be used to # fine-tune the look of the HTML output. If the tag is left blank doxygen # will generate a default style sheet. Note that doxygen will try to copy # the style sheet file to the HTML output directory, so don't put your own # stylesheet in the HTML output directory as well, or it will be erased! HTML_STYLESHEET = # If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, # files or namespaces will be aligned in HTML using tables. If set to # NO a bullet list will be used. HTML_ALIGN_MEMBERS = YES # If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML # documentation will contain sections that can be hidden and shown after the # page has loaded. For this to work a browser that supports # JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox # Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). HTML_DYNAMIC_SECTIONS = NO # If the GENERATE_DOCSET tag is set to YES, additional index files # will be generated that can be used as input for Apple's Xcode 3 # integrated development environment, introduced with OSX 10.5 (Leopard). # To create a documentation set, doxygen will generate a Makefile in the # HTML output directory. Running make will produce the docset in that # directory and running "make install" will install the docset in # ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find # it at startup. # See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html for more information. GENERATE_DOCSET = NO # When GENERATE_DOCSET tag is set to YES, this tag determines the name of the # feed. A documentation feed provides an umbrella under which multiple # documentation sets from a single provider (such as a company or product suite) # can be grouped. DOCSET_FEEDNAME = "Doxygen generated docs" # When GENERATE_DOCSET tag is set to YES, this tag specifies a string that # should uniquely identify the documentation set bundle. This should be a # reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen # will append .docset to the name. DOCSET_BUNDLE_ID = org.doxygen.Project # If the GENERATE_HTMLHELP tag is set to YES, additional index files # will be generated that can be used as input for tools like the # Microsoft HTML help workshop to generate a compiled HTML help file (.chm) # of the generated HTML documentation. GENERATE_HTMLHELP = NO # If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can # be used to specify the file name of the resulting .chm file. You # can add a path in front of the file if the result should not be # written to the html output directory. CHM_FILE = # If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can # be used to specify the location (absolute path including file name) of # the HTML help compiler (hhc.exe). If non-empty doxygen will try to run # the HTML help compiler on the generated index.hhp. HHC_LOCATION = # If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag # controls if a separate .chi index file is generated (YES) or that # it should be included in the master .chm file (NO). GENERATE_CHI = NO # If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING # is used to encode HtmlHelp index (hhk), content (hhc) and project file # content. CHM_INDEX_ENCODING = # If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag # controls whether a binary table of contents is generated (YES) or a # normal table of contents (NO) in the .chm file. BINARY_TOC = NO # The TOC_EXPAND flag can be set to YES to add extra items for group members # to the contents of the HTML help documentation and to the tree view. TOC_EXPAND = YES # If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and QHP_VIRTUAL_FOLDER # are set, an additional index file will be generated that can be used as input for # Qt's qhelpgenerator to generate a Qt Compressed Help (.qch) of the generated # HTML documentation. GENERATE_QHP = NO # If the QHG_LOCATION tag is specified, the QCH_FILE tag can # be used to specify the file name of the resulting .qch file. # The path specified is relative to the HTML output folder. QCH_FILE = # The QHP_NAMESPACE tag specifies the namespace to use when generating # Qt Help Project output. For more information please see # http://doc.trolltech.com/qthelpproject.html#namespace QHP_NAMESPACE = # The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating # Qt Help Project output. For more information please see # http://doc.trolltech.com/qthelpproject.html#virtual-folders QHP_VIRTUAL_FOLDER = doc # If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to add. # For more information please see # http://doc.trolltech.com/qthelpproject.html#custom-filters QHP_CUST_FILTER_NAME = # The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the custom filter to add.For more information please see # Qt Help Project / Custom Filters. QHP_CUST_FILTER_ATTRS = # The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this project's # filter section matches. # Qt Help Project / Filter Attributes. QHP_SECT_FILTER_ATTRS = # If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can # be used to specify the location of Qt's qhelpgenerator. # If non-empty doxygen will try to run qhelpgenerator on the generated # .qhp file. QHG_LOCATION = # The DISABLE_INDEX tag can be used to turn on/off the condensed index at # top of each HTML page. The value NO (the default) enables the index and # the value YES disables it. DISABLE_INDEX = NO # This tag can be used to set the number of enum values (range [1..20]) # that doxygen will group on one line in the generated HTML documentation. ENUM_VALUES_PER_LINE = 4 # The GENERATE_TREEVIEW tag is used to specify whether a tree-like index # structure should be generated to display hierarchical information. # If the tag value is set to FRAME, a side panel will be generated # containing a tree-like index structure (just like the one that # is generated for HTML Help). For this to work a browser that supports # JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, # Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are # probably better off using the HTML help feature. Other possible values # for this tag are: HIERARCHIES, which will generate the Groups, Directories, # and Class Hierarchy pages using a tree view instead of an ordered list; # ALL, which combines the behavior of FRAME and HIERARCHIES; and NONE, which # disables this behavior completely. For backwards compatibility with previous # releases of Doxygen, the values YES and NO are equivalent to FRAME and NONE # respectively. GENERATE_TREEVIEW = ALL # If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be # used to set the initial width (in pixels) of the frame in which the tree # is shown. TREEVIEW_WIDTH = 250 # Use this tag to change the font size of Latex formulas included # as images in the HTML documentation. The default is 10. Note that # when you change the font size after a successful doxygen run you need # to manually remove any form_*.png images from the HTML output directory # to force them to be regenerated. FORMULA_FONTSIZE = 10 #--------------------------------------------------------------------------- # configuration options related to the LaTeX output #--------------------------------------------------------------------------- # If the GENERATE_LATEX tag is set to YES (the default) Doxygen will # generate Latex output. GENERATE_LATEX = YES # The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `latex' will be used as the default path. LATEX_OUTPUT = latex # The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be # invoked. If left blank `latex' will be used as the default command name. LATEX_CMD_NAME = latex # The MAKEINDEX_CMD_NAME tag can be used to specify the command name to # generate index for LaTeX. If left blank `makeindex' will be used as the # default command name. MAKEINDEX_CMD_NAME = makeindex # If the COMPACT_LATEX tag is set to YES Doxygen generates more compact # LaTeX documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_LATEX = NO # The PAPER_TYPE tag can be used to set the paper type that is used # by the printer. Possible values are: a4, a4wide, letter, legal and # executive. If left blank a4wide will be used. PAPER_TYPE = a4wide # The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX # packages that should be included in the LaTeX output. EXTRA_PACKAGES = # The LATEX_HEADER tag can be used to specify a personal LaTeX header for # the generated latex document. The header should contain everything until # the first chapter. If it is left blank doxygen will generate a # standard header. Notice: only use this tag if you know what you are doing! LATEX_HEADER = # If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated # is prepared for conversion to pdf (using ps2pdf). The pdf file will # contain links (just like the HTML output) instead of page references # This makes the output suitable for online browsing using a pdf viewer. PDF_HYPERLINKS = YES # If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of # plain latex in the generated Makefile. Set this option to YES to get a # higher quality PDF documentation. USE_PDFLATEX = YES # If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. # command to the generated LaTeX files. This will instruct LaTeX to keep # running if errors occur, instead of asking the user for help. # This option is also used when generating formulas in HTML. LATEX_BATCHMODE = NO # If LATEX_HIDE_INDICES is set to YES then doxygen will not # include the index chapters (such as File Index, Compound Index, etc.) # in the output. LATEX_HIDE_INDICES = NO #--------------------------------------------------------------------------- # configuration options related to the RTF output #--------------------------------------------------------------------------- # If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output # The RTF output is optimized for Word 97 and may not look very pretty with # other RTF readers or editors. GENERATE_RTF = YES # The RTF_OUTPUT tag is used to specify where the RTF docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `rtf' will be used as the default path. RTF_OUTPUT = rtf # If the COMPACT_RTF tag is set to YES Doxygen generates more compact # RTF documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_RTF = NO # If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated # will contain hyperlink fields. The RTF file will # contain links (just like the HTML output) instead of page references. # This makes the output suitable for online browsing using WORD or other # programs which support those fields. # Note: wordpad (write) and others do not support links. RTF_HYPERLINKS = NO # Load stylesheet definitions from file. Syntax is similar to doxygen's # config file, i.e. a series of assignments. You only have to provide # replacements, missing definitions are set to their default value. RTF_STYLESHEET_FILE = # Set optional variables used in the generation of an rtf document. # Syntax is similar to doxygen's config file. RTF_EXTENSIONS_FILE = #--------------------------------------------------------------------------- # configuration options related to the man page output #--------------------------------------------------------------------------- # If the GENERATE_MAN tag is set to YES (the default) Doxygen will # generate man pages GENERATE_MAN = NO # The MAN_OUTPUT tag is used to specify where the man pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `man' will be used as the default path. MAN_OUTPUT = man # The MAN_EXTENSION tag determines the extension that is added to # the generated man pages (default is the subroutine's section .3) MAN_EXTENSION = .3 # If the MAN_LINKS tag is set to YES and Doxygen generates man output, # then it will generate one additional man file for each entity # documented in the real man page(s). These additional files # only source the real man page, but without them the man command # would be unable to find the correct page. The default is NO. MAN_LINKS = NO #--------------------------------------------------------------------------- # configuration options related to the XML output #--------------------------------------------------------------------------- # If the GENERATE_XML tag is set to YES Doxygen will # generate an XML file that captures the structure of # the code including all documentation. GENERATE_XML = NO # The XML_OUTPUT tag is used to specify where the XML pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `xml' will be used as the default path. XML_OUTPUT = xml # The XML_SCHEMA tag can be used to specify an XML schema, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_SCHEMA = # The XML_DTD tag can be used to specify an XML DTD, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_DTD = # If the XML_PROGRAMLISTING tag is set to YES Doxygen will # dump the program listings (including syntax highlighting # and cross-referencing information) to the XML output. Note that # enabling this will significantly increase the size of the XML output. XML_PROGRAMLISTING = YES #--------------------------------------------------------------------------- # configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- # If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will # generate an AutoGen Definitions (see autogen.sf.net) file # that captures the structure of the code including all # documentation. Note that this feature is still experimental # and incomplete at the moment. GENERATE_AUTOGEN_DEF = NO #--------------------------------------------------------------------------- # configuration options related to the Perl module output #--------------------------------------------------------------------------- # If the GENERATE_PERLMOD tag is set to YES Doxygen will # generate a Perl module file that captures the structure of # the code including all documentation. Note that this # feature is still experimental and incomplete at the # moment. GENERATE_PERLMOD = NO # If the PERLMOD_LATEX tag is set to YES Doxygen will generate # the necessary Makefile rules, Perl scripts and LaTeX code to be able # to generate PDF and DVI output from the Perl module output. PERLMOD_LATEX = NO # If the PERLMOD_PRETTY tag is set to YES the Perl module output will be # nicely formatted so it can be parsed by a human reader. This is useful # if you want to understand what is going on. On the other hand, if this # tag is set to NO the size of the Perl module output will be much smaller # and Perl will parse it just the same. PERLMOD_PRETTY = YES # The names of the make variables in the generated doxyrules.make file # are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. # This is useful so different doxyrules.make files included by the same # Makefile don't overwrite each other's variables. PERLMOD_MAKEVAR_PREFIX = #--------------------------------------------------------------------------- # Configuration options related to the preprocessor #--------------------------------------------------------------------------- # If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will # evaluate all C-preprocessor directives found in the sources and include # files. ENABLE_PREPROCESSING = YES # If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro # names in the source code. If set to NO (the default) only conditional # compilation will be performed. Macro expansion can be done in a controlled # way by setting EXPAND_ONLY_PREDEF to YES. MACRO_EXPANSION = NO # If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES # then the macro expansion is limited to the macros specified with the # PREDEFINED and EXPAND_AS_DEFINED tags. EXPAND_ONLY_PREDEF = NO # If the SEARCH_INCLUDES tag is set to YES (the default) the includes files # in the INCLUDE_PATH (see below) will be search if a #include is found. SEARCH_INCLUDES = YES # The INCLUDE_PATH tag can be used to specify one or more directories that # contain include files that are not input files but should be processed by # the preprocessor. INCLUDE_PATH = # You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard # patterns (like *.h and *.hpp) to filter out the header-files in the # directories. If left blank, the patterns specified with FILE_PATTERNS will # be used. INCLUDE_FILE_PATTERNS = # The PREDEFINED tag can be used to specify one or more macro names that # are defined before the preprocessor is started (similar to the -D option of # gcc). The argument of the tag is a list of macros of the form: name # or name=definition (no spaces). If the definition and the = are # omitted =1 is assumed. To prevent a macro definition from being # undefined via #undef or recursively expanded use the := operator # instead of the = operator. PREDEFINED = # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then # this tag can be used to specify a list of macro names that should be expanded. # The macro definition that is found in the sources will be used. # Use the PREDEFINED tag if you want to use a different macro definition. EXPAND_AS_DEFINED = # If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then # doxygen's preprocessor will remove all function-like macros that are alone # on a line, have an all uppercase name, and do not end with a semicolon. Such # function macros are typically used for boiler-plate code, and will confuse # the parser if not removed. SKIP_FUNCTION_MACROS = NO #--------------------------------------------------------------------------- # Configuration::additions related to external references #--------------------------------------------------------------------------- # The TAGFILES option can be used to specify one or more tagfiles. # Optionally an initial location of the external documentation # can be added for each tagfile. The format of a tag file without # this location is as follows: # TAGFILES = file1 file2 ... # Adding location for the tag files is done as follows: # TAGFILES = file1=loc1 "file2 = loc2" ... # where "loc1" and "loc2" can be relative or absolute paths or # URLs. If a location is present for each tag, the installdox tool # does not have to be run to correct the links. # Note that each tag file must have a unique name # (where the name does NOT include the path) # If a tag file is not located in the directory in which doxygen # is run, you must also specify the path to the tagfile here. TAGFILES = # When a file name is specified after GENERATE_TAGFILE, doxygen will create # a tag file that is based on the input files it reads. GENERATE_TAGFILE = # If the ALLEXTERNALS tag is set to YES all external classes will be listed # in the class index. If set to NO only the inherited external classes # will be listed. ALLEXTERNALS = NO # If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed # in the modules index. If set to NO, only the current project's groups will # be listed. EXTERNAL_GROUPS = YES # The PERL_PATH should be the absolute path and name of the perl script # interpreter (i.e. the result of `which perl'). PERL_PATH = /usr/bin/perl #--------------------------------------------------------------------------- # Configuration options related to the dot tool #--------------------------------------------------------------------------- # If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will # generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base # or super classes. Setting the tag to NO turns the diagrams off. Note that # this option is superseded by the HAVE_DOT option below. This is only a # fallback. It is recommended to install and use dot, since it yields more # powerful graphs. CLASS_DIAGRAMS = NO # You can define message sequence charts within doxygen comments using the \msc # command. Doxygen will then run the mscgen tool (see # http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the # documentation. The MSCGEN_PATH tag allows you to specify the directory where # the mscgen tool resides. If left empty the tool is assumed to be found in the # default search path. MSCGEN_PATH = # If set to YES, the inheritance and collaboration graphs will hide # inheritance and usage relations if the target is undocumented # or is not a class. HIDE_UNDOC_RELATIONS = YES # If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is # available from the path. This tool is part of Graphviz, a graph visualization # toolkit from AT&T and Lucent Bell Labs. The other options in this section # have no effect if this option is set to NO (the default) HAVE_DOT = # By default doxygen will write a font called FreeSans.ttf to the output # directory and reference it in all dot files that doxygen generates. This # font does not include all possible unicode characters however, so when you need # these (or just want a differently looking font) you can specify the font name # using DOT_FONTNAME. You need need to make sure dot is able to find the font, # which can be done by putting it in a standard location or by setting the # DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory # containing the font. DOT_FONTNAME = FreeSans # The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. # The default size is 10pt. DOT_FONTSIZE = 10 # By default doxygen will tell dot to use the output directory to look for the # FreeSans.ttf font (which doxygen will put there itself). If you specify a # different font using DOT_FONTNAME you can set the path where dot # can find it using this tag. DOT_FONTPATH = # If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect inheritance relations. Setting this tag to YES will force the # the CLASS_DIAGRAMS tag to NO. CLASS_GRAPH = YES # If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect implementation dependencies (inheritance, containment, and # class references variables) of the class with other documented classes. COLLABORATION_GRAPH = YES # If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen # will generate a graph for groups, showing the direct groups dependencies GROUP_GRAPHS = YES # If the UML_LOOK tag is set to YES doxygen will generate inheritance and # collaboration diagrams in a style similar to the OMG's Unified Modeling # Language. UML_LOOK = NO # If set to YES, the inheritance and collaboration graphs will show the # relations between templates and their instances. TEMPLATE_RELATIONS = NO # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT # tags are set to YES then doxygen will generate a graph for each documented # file showing the direct and indirect include dependencies of the file with # other documented files. INCLUDE_GRAPH = YES # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and # HAVE_DOT tags are set to YES then doxygen will generate a graph for each # documented header file showing the documented files that directly or # indirectly include this file. INCLUDED_BY_GRAPH = YES # If the CALL_GRAPH and HAVE_DOT options are set to YES then # doxygen will generate a call dependency graph for every global function # or class method. Note that enabling this option will significantly increase # the time of a run. So in most cases it will be better to enable call graphs # for selected functions only using the \callgraph command. CALL_GRAPH = NO # If the CALLER_GRAPH and HAVE_DOT tags are set to YES then # doxygen will generate a caller dependency graph for every global function # or class method. Note that enabling this option will significantly increase # the time of a run. So in most cases it will be better to enable caller # graphs for selected functions only using the \callergraph command. CALLER_GRAPH = NO # If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen # will graphical hierarchy of all classes instead of a textual one. GRAPHICAL_HIERARCHY = YES # If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES # then doxygen will show the dependencies a directory has on other directories # in a graphical way. The dependency relations are determined by the #include # relations between the files in the directories. DIRECTORY_GRAPH = YES # The DOT_IMAGE_FORMAT tag can be used to set the image format of the images # generated by dot. Possible values are png, jpg, or gif # If left blank png will be used. DOT_IMAGE_FORMAT = png # The tag DOT_PATH can be used to specify the path where the dot tool can be # found. If left blank, it is assumed the dot tool can be found in the path. DOT_PATH = # The DOTFILE_DIRS tag can be used to specify one or more directories that # contain dot files that are included in the documentation (see the # \dotfile command). DOTFILE_DIRS = # The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of # nodes that will be shown in the graph. If the number of nodes in a graph # becomes larger than this value, doxygen will truncate the graph, which is # visualized by representing a node as a red box. Note that doxygen if the # number of direct children of the root node in a graph is already larger than # DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note # that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. DOT_GRAPH_MAX_NODES = 50 # The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the # graphs generated by dot. A depth value of 3 means that only nodes reachable # from the root by following a path via at most 3 edges will be shown. Nodes # that lay further from the root node will be omitted. Note that setting this # option to 1 or 2 may greatly reduce the computation time needed for large # code bases. Also note that the size of a graph can be further restricted by # DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. MAX_DOT_GRAPH_DEPTH = 0 # Set the DOT_TRANSPARENT tag to YES to generate images with a transparent # background. This is disabled by default, because dot on Windows does not # seem to support this out of the box. Warning: Depending on the platform used, # enabling this option may lead to badly anti-aliased labels on the edges of # a graph (i.e. they become hard to read). DOT_TRANSPARENT = NO # Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output # files in one run (i.e. multiple -o and -T options on the command line). This # makes dot run faster, but since only newer versions of dot (>1.8.10) # support this, this feature is disabled by default. DOT_MULTI_TARGETS = NO # If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will # generate a legend page explaining the meaning of the various boxes and # arrows in the dot generated graphs. GENERATE_LEGEND = YES # If the DOT_CLEANUP tag is set to YES (the default) Doxygen will # remove the intermediate dot files that are used to generate # the various graphs. DOT_CLEANUP = YES #--------------------------------------------------------------------------- # Options related to the search engine #--------------------------------------------------------------------------- # The SEARCHENGINE tag specifies whether or not a search engine should be # used. If set to NO the values of all tags below this one will be ignored. SEARCHENGINE = NO dlt-daemon-2.18.4/doc/images/000077500000000000000000000000001353342203500156445ustar00rootroot00000000000000dlt-daemon-2.18.4/doc/images/dlt-multinode.png000066400000000000000000000523521353342203500211420ustar00rootroot00000000000000PNG  IHDR*cJsRGBgAMA a pHYsodTIDATx^ mWyۈ;rAH؈H4qd\%`({uq%U!eb$aҕH,# XX2'88&=]{{{u:u|龧!B!B!B!B!r'< W/º` ֭^>B!jmZ_IZzB!r+6*IV/B!BnF4iC!Bȭبo~ƷC!BȫfQyDu~P=l:yhuFǥx:q4<'ݝ<[ Pڤ|uY/ 3B!k{~Mo!B"I5w{MyjiХn҆`f:M-1-16՛ú^vwK>+:7ܖxg7_Ǟs#B!T?'մcLjwQi7u;lTMoӹFoT|tWs~ҽy9= .=iO^*B!I5-q_$^hXM|sbm漸Y\J]nTG{gҪ>Ejss9׀ʿ~Szg!B8-'6Tug<`L!B'6*tWg}aB!J 7*h|OCa]Ψ!BbFŃ}xš]/ B!BEܥM3GzS/ B!BŋʜcU~zIB!Z 7* y6)!Bhݤ~8AB!$6*!Bى B!BhvbB!ب B!f'6*!Bى B!BhvbB!ب B!f'6*!Bى B!BhvbB!VQ9rz8OsLiى?Z!'.KR#TUwgC>SOwTW}.dx  +? h5_i/{ U՟|CU[>?xKgfyVS!' [ϓ\O@W: hk WCX| phC /_ U? U_-$4Eh(GﭪG=Uwx_U}^UU7pg۫s>{KC>sc>uk5}Zzj69F99fI'b#khqc!4 m9B~hJm92hBN]hʢ8Wr@5j4 mh Otbn5Rw04CjCׁڍʶм{A*>G6%KcΐnNtsΞ6Cb7uD+=\ͳmȑЀlˑЀ$s$4 r@Ekmsz9Q[ Db7*ڛ\Ijpp(hlA!ȡC!b7&FuKcrHz_w՛͛)6* +} 4S-%PˍEι |n=cUcۜL|,F%kh=իzK,棓 &Q!'ޤJR#U8 0Xw::!:޻ Dt ѿ&5zG{{iRBc=m$7Fsac @Lȅn=.up_gMi6Ru5rB۪'}nˍfxm`\sS|s@E,D:z[|nvo 9Cz$588B@T([6Kc1$n8t5%itX\{돩a}׏wSa} hZrƢ9V[72u;s ]`c: F8_2#Q!?xR-Gz5,5|;Uo㱟7u9g6fduܨhos%j c&by,B|,x3>;6 KpN XFER$oF#\SA3"l#X*CFn8RuS8&(fFb~5 X=QQˑЀlˑЀ9GZdCKތM$ꪟ=BN= kQ!'ОJR#T8w7 l4 ׄFy՜B~!UinW>crM{j+C}=s U6 FjzB~?y?%?Zjwx3VQ!'4IJ Qt8'\5"@LU?W A~ o˫sNrBNiJ|R XFSx8_kDyN^ȝ (!'VQ!'4F%>W 0穠nEx xۦ%EcІ@@Wm '>`h!_D((gDa~Qp4w1EDAҠ` cZ#TqNyUr@95F%ah4SYZ#M, AkDN]hm$yq%`(#O8p"?Q󃜘?DYd ٟ͟,+BGȃj.=W2@TsuvIȃj."dzXhoaz<2NjppL%po={{O>QG8Op<89_󄆣l,N ^̨9#<&cJGDOFm rܘyuȃj.SNhG4Yћ>mk8t}q/cXiٚO/mcfx^xΏh'O<c_(2=z&zZnba~^ L9!d Do/.}{B|nauмw/w%ܤw[&>{X0uw}ة}vq^ñ&5GFJGDOKBnS#yPe ͝&K zg z/}6u[?Zљ3G=Ofw"㉆>}[MRlwNmdzc?huW2=z&zZn}ba~^ L9!d DoER5~OCc mwL/qpt~dcq3ܽ8h8}ּ7O{@8ib:gpǟ՟B16*dzLԩ.150?L/\I i7_鼐w_tK@%[}}U#{V!tz_߼NgFevDO5<697Za~^ L9!d DoaWUzy=\W=y#<6W2=z&zTXhWaz<2NjppL%EyjE7cj6K Gx\cJGDO5<697Za~^ L9!d DozA5 Vcc͋6/-WWoڼMWV'71iب3S~ 7 a~^ L9!d Doz5Vcb]G==-䆁: A5)'4wR#d,M/Ss24Vcbm~ޡLkx r@^˔;2M@ߩ-4Vcb]ez2=z&zZ) 7 yuȃj.SNhG4Y[;5Vcb]ez2=z&zX`2_^ L9!d Dozj"b]ez2=z&zZߩ 7ȍ%a~^ L9!d Dozpp\g\36*dzL\SAnKȫ0@TsrBs'588BB;h8v(r(ӣg rXB^˔;2M@־NX׆#<6W2=z&zjkej rc yuȃj.SNhG4Yћ^\ 6ȣF#%ӣgnN An,!yPe ͝&K z cdž#<&W2=z&z0?L/\I i7xflT\[SBnKȫ0@TsrBs'588Bԩcdž#<W2=z&zjbj rc yuȃj.SNhG4Yћ^HXX׆#<W2=z&zX`2_^ L9!d DoEtr /Vcbp[5cJGDO r0Waz<2NjppL% otjn5)ִ}kب3ԫߩ 7 yuȃj.SNhG4Y_4n5)ֲ_ӚQq%ӣgWSAn0?L/\I i-`NEj,Rcá}iب3ԫߩ 7 yuȃj.SNhG4YxXEum8}hب3xOAnXȫ0@TsrBs'588B"919pflT\yT䆅: A5)'4wR#d,y/H nflT\yT䆅: A5)'4wR#d,y/Sr-vS16¼Z36*dzA[[BqqË́5MEKh"j2"m~zB6*dz An՜0@Tsr~st\0?j6n#lT|r-0?L/\I i4/dzy|xOk՜F#%c)x͍'Fja~^ L9F%g>O/lsFc/_|!s-5uhdz,Be/sEk0?L/\I iDtcXKfCkHXs#:^ oRa~^ L9!$֧<L0OX/h ˔;2M<`}CkHa~^ L9!$֧<L0OX/h ˔;2M<`}CkHa~^ L9!$֧<L0OX/h ˔;2M<`}CkHa~^ L9!$֧<L0OX/h ˔;2M<`}CkHa~^ L9!$֧<L0OX/h ˔;2M<`}CkHa~^ L9!$֧<L0OX/h ˔;2M<`}CkHa~^ L9!$֧<L0OX/h ˔;2M<`}CkHa~^ L9!$֧<L0OX/h ˔;2M<`}CkHa~^ L9!$֧<L0OX/h ˔;2M<`}CkHa~^ L9!$֧<L0OX/h ˔;2M<`}CkHa~^ L9!$֧<L0OX/h ˔;2M<`}CkHa~^ L9!$֧<L0OX/h ˔;2M4|˟y~TǞM񏼠ͯ㏚ׁL0ȓ: A5)'4wR#dsuT%6j.oJPz$6)azȓ2Q9 A5)'ب#zWSMg3i˹0OTsL0I٨˔lT 5 >zjW-uz?wja<)՜0@Tsrʺw3ۦ}w?Xֿ{uu\V?HtG8y6@5H@ja~^ L9FxWakl_x{uU'ͱSGb#:zEo_|侻owNw,8W_Z܆shdzC9az<2S"Fe_/hZ]ufCEͅ Σzt 79FJGX-sȃj.SNQ9%6*'2~j~m:Sx`x'*񾾧:ιԵ6x>y^/_Vo_]̥w@Nh{捞#LnqYd}P9 A5)'4wR#dtEeIi9~窇=l4~zS:}ݜtVX~b?.h{ja-7*y O՜0@Tsr)h.ydq,l\h7,O?RǷmTzy+YN/~:IO\̥k|aި6)2QOgy>y0?L/\I i"OT^w, l",kH0_TsLnYu6'%5uhdzyzGk0?L/\I iSZSFJG'yPe ͝&a>5uhdzyzGk0?L/\I iSZSFJG'yPe ͝&a>5uhdzyzGk0?L/\I iSZSFJG'yPe ͝&a>5uhdzyzGk0?L/\I iSZSFJG'yPe ͝&a>5uhdzyzGk0?L/\I iSZSFJG'yPe ͝&a>5uhdzyzGk0?L/\I iSZSFJG'yPe ͝&a>5uhdzyzGk0?L/\I iSZSFJG'yPe ͝&a>5uhdzyzGk0?L/\I iSZSFJG'yPe ͝&a>5uhdzyzGk0?L/\I iSZSFJG'yPe ͝&a>5uhdzyzGk0?L/\I iSZSFJG'yPe ͝&a>5uhdzyzGk0?L/\I iSZSFJG'yPe ͝&a>5uhdzyzGk0?L/\I iSZSFJG'yPe ͝&a>5uhdzyzGk0?L/\I iSZSFJG'yPe ͝&a>5uhdzyzGk0?L/\I is 7\Ґ_FJG>Xhoazŭ.d ͝&KR{VxkU}࣎x9iUuGj߿~o}U^;Ň'nq"*6oi|wﯹIڼ w\-ugu-wT=5:?X%shdzL Ȍ܈yBnF50?L/(9)B5)'ب'~/(ڙ@iCd#E E0B(T! U(J > ^"BqG=YUל6ڼ궚+Sm^qk[j.w;n6/|GͷPmjj͋6/-WWoڼMWV'6x\'1ײ$TsL!7ȍ9so dTsr~YE;w-TpyUyصfg% L;|s]qb FћUsg C%rq'<շYs]#lTKd!7hﲾC6 ^o6*ެnjc{P9~:g5X{vu?P_Ϙyd2_'.CnhﲾY{!)|Qq@fq*7쿩Ia%c/ G?is]#lTKdwQ}ܝ78z~QYVF>V]vRVlèu{ڨ414#XjFe;NUKuVlHѫ=Nu[ޜݝGhg?Q|Qq@% N~9#ͻ8\kԽG7\X9xlJsǻ^9P Acńm?s،7*M&DoSb۹͆nۜFcn13B3zׅ`t~ ٰ5s*5/ar䛍7Kڍ[hXuwCȡCա& 㡐ƺMO^b]ʾ)7*oyn3_lTvO57 s9ح!b6p9Sޭo5vh6gg#.6*۲#Femr]qb )z۩[[{F],ސhn{ݘyzq7Do9wA/ mCx@aY~c3rhq^ǦcńJZE;~ϥKq1v~^ Ǻn[Q_WyT:7VVm3ԑ96|}s.6*۲#FEy9DXѹ)Ӌ7OHuK2[6ߜ׽nL$d~nT4G:.4E٨8 z0wI/bv sN/d;&[ǗfqNxJTkƿJxP9U-mJq%7:d6wKF^sPՁ8^7;f.̈׆KCe6*ȼQ!7Q裭SW{뺵gZ4\-k:=`zoNO˝}ܨ o6*Tcb=ΫdcX4apޝsoT:buWw,ΟiJPcńʩʤ9\ClUwr#֠hñfcvjl3o溆x^~ubvdب{G^٨LCT{%Y{K՞zB,^+Ot=E~ǵaFћ^Fq($Be7ﺯ:٨)%7yVE lT!X)G٨8 zk pJFa%q*~?^lo y}^?TcӚ*Ѹ,pogr[S1"7wCwcɍr}ʏUfGFbdCghG4Yћ ojϛ硲wU 7^i?TX"D:'p,GjBri:FS~2+L/ވ>t Ȇm };S!d Do*QXᑢPټjk y曯6/hxӕ+֬PLbI #pL;a #gV^}tkt*a;SNhG4Yћ mjVxXPY! />|EgœñWC PEO==-䆁ȏcNl v@h!d Do*9 k*oOrƷ=嬛^pw] e'P8Ψ>ϤLkx r@^O!? Ӌ7:lާ>cY;2M@HO vϻ-)5Tn3r֙_x_/XYw-UhN}V}I_Lr8Uu10x#T d>4wR#d,-Lnwy\+vmqql,ƶP_ߥ?lX/'6*dCg Hs'588BTL5ygT{b6 AX5""ӾKB%qpǥE"cg<NѰ/~zOFst|rLAn*QV^}45<9lTȆ{L1 ͝&K zk )Ccsi,@NwF7i`'>ןfa_|q[ڮ̹fQ+ 7ȍU@V?zm<:90 LFeDo*/ /cl5 <cu󱛆cϚn8㒧CES|=7^}hXU\Jc?dzLw. rTnj裩aB6 c ~%d Do*9p7cǤ5+=TqdgF7֙g#%͝&K zSBeP GkVz9Sl6|?=+?eezLԭ)!7ȍ%u10x#甐 d=HIs'588Bڢ{ C%<Y" 4wR#d,M2H֬P} cO9̯]G^uշSȑ#?ќ5"ӣgnN)ȍhFc0x#XlXl"g,Ks'588BBLuxHnfz5:dٰI imQ *>fDj*aNY"L^ OAn$Waz|t awI i->'$Cc\nf<:l4R2=zF5<B^ѭ) Ȇ ߙrBs'588BVp њ*HyF yuoGNl v|g ͝&K@}*B*aY"L^r@^ѫUC6 D3NjppL% o'\ XPp֬PGFJG<1:Ӌ7c|l%)'4wR#d,yOn nNXNkVzȣF#%ӣg[ǫ 7Waz|tkuՐ dnL9!d [|rOA(VhĺJFkVzȣF#%ӣgW˫ 7v@^ѫUB6 {@3NjppL% o=8 *ך*Hy*!7D^ѫUB6aWwI im^1 *C6 {A3NjppL% oj.+0v:ZCE6)=#Oz^ a~^!]dٰG;SNhG4YxXVXu p\kVzȣF#%ӣgi<]!a~^! !Ȇ"ߙrBs'588B]% 1|u pLkVzȣF#%ӣgWӫ 7v:Ӌ7Wl NΔ;2M'* h^XP<nkJythdzĴB!2F!B!4;QA!BNlTB!BB!F!B!4;QA!BNlTB!BB!F!B!4;QA!BNlTB!BB!F!B!4;QA!BNlTB!BB!F!B!4; E UB!B!B!B!B!:tK>IENDB`dlt-daemon-2.18.4/doc/images/dlt-viewer-send-injection-dialog.png000066400000000000000000000301521353342203500246010ustar00rootroot00000000000000PNG  IHDRsRGBgAMA a pHYsod/IDATx^ypםfmyccWywklvWbVeک֎]IeWh[6eَMId[(RQIKZ"CV-RI.^ 9 E|~} j_=z;iϿ kmmȠ*nݢ+6.6@-3>+Aм=!K@8JaKۿ?ϸ77&MV[lA5w#D[$z8cި嘱eYzF>ID|tUa{)~B3*xMGWKQQ)yaʴ* >W Q 5XY1Pӯ[S8Z`hn%*-axx`` fgg% 1[[!ez8 >FyἅϸR*3i[+^л8ׯ^ {+{O%̌g|^:wddq1x8Ƥ $ճP]8?xS'O<{Ǐ(oH$pƈ$ss'fk;"*R~nʥl&z5;Ecrn|&=4ۏJ |ȈЌocUa΅I#WkNS)+ԢۍK顥[1i"[)gLΘ5r|@4lq thy #MxC2>z ӣ= 3v" gg r|@4,WsxMgػw ',4[vR9`t+$5OqU`.P\2G^;^;22=q<44ok*~={ol/^OMMٟwwm``*m ~3… ": "Ӡnt(9iUw)T6? ߱~PP>19~Y?~dov}I^͛#Muop,6tnYŷU'Z؍Bc-4xzxcJa~5YK zV|Z\b,}o$@%K\B8.?89I.NjBκubLEpAb Y⒳XD䐂XX{/O:u6(NGGX}ٷɹq_sv*ϼW_}u|| !l2^77r Vt>jOUȬ2VٳX.JTT\Οm޹fUԺfVuR/u i`<$KJJfiKfOz|G;n޼}{ ?eu%Xeٟ߶:qj:x]zK%+4O* r XbuϻxgÝ%؅32K%/</x o˖-^nKQ vY{C-1-FnuAAv%FAD,K\Z%W%>d';Mp<w\c0B-1T%UfA,%%qV&$B8K"6uO91?-ϻ8e]bIKL hۜh1X]B?Z6*0K f9>hVrGQrrG%W%DyBspXb.S!>J(Q+Uў%ɔoSAEX%.&YXƿ~Æ<~޽\sT905{lnK!OOO=O<++A#ẗ5kM/Jz}1HzoXcl"[K" suJR˱Ģx%W%N}q=x._0{/ޚ% }]|98ZŲđKT˷ĵIjb-O˹ECM,17"y=ѾX,+Vcwp-9W5fggkAb[իW󿡘wʕ\ݡ&dKN䲖7tn Fn8ny2xN.K~<K_qڵiP%ZRz߿u<Σ}}}OՊ.~BcJD!KT%$K,/+:H Z bq[Wu p pLlZqm6&Q/^FyI$ڲe r\.cEE s.\@+ A6;;J(|7%籠񢦚~M8ۺu+2{z#H[[7AZ((N(`]]] mOzLMM9xo?|ua#?|_gnnNh64elhD1A BŢĀ|hr8ACCC e1J :q`/t|w駹FMmVuܼaowwZmUMl`ա޷idZXjƞXM\ZXhz֭4e;x/=V[u튂rN`-A˴du7(g# A|ZAZ0Q [ _{|ӻ??gV?} u:bno;=;x7a Vb{1AL]^]Z؍ V- ,uZ)Q.3k?J FO<~o~ͯ|zG'~{ )g `0n~xaD ~D! C.e;. ?!-Bč ,A,8Y_<&;5w,D4Ale][*-qA .l;ó1$wSakU8vt$H<vu 7xf,\.=1(T̪_xB 2ۉґ . ґ "JQn'J'vb%E7(U25.;PeAF*Qw "@u b 7);G:6mܫ`Ve- ?pp׉TC1Kg]u4dۃ\2܃ul׍4P.\AܲkS>?O.nkkz]qZLf||sccc*w( P]21,`psJtկ<ˎnbX WA,]ɏ!T::xKbvT%~t y1Z.Y/T;|[$ ?hZ) $GPlǙNT%~t ĢFHē k֬/ Oʕ/^RYp.>Azrh\*=sIW11144sСv!yQDKp)-9<00lٲVd~_BXYXزe !h-qXΈnt#P@>= @MhN&-e (*E sdddzz 9A={P14?yܧYsx2Tx9)-WK-iR6^')aGr {)- ⦦cǎ]p!+Ǒ5?/}z׺e>#G;~/m.{~ުCYUKmǪ%Z:hK: :n~~BjRBZdjos/]v n"<bKA`#PcY(v7G Qϕpӧyc b*_ޱ_~hw?=`w VUvxx#eU3N5d18Uߤ6+7!lVcWVfb! b5B9\bRKsn % W\@Fr%:m۶ */dg~Ͽ}OqΆLg2R&NL&Fy#۳bTя4<#KGKeQ#AK=yuEGm^xg/v4~ggˆ" l-1E`ۋ/dc~t߲/~O| zlZ>/ K,n;f.x .uwA$PA\ |Ѿ*<Ոa>(:Ph;(v$jh21Ϧ;gi`PѻI ~K/߸"Dl:s1v?">"$EIē WA7aD%*b6Q 1 A, KeY\TkK5c D7:fY8f5$6 G]%hXU*~g9{q)tm f "hK1+tTOPW0ǰ{ڂ\%Ȃtm%B&J8 kKUģ%*bQ $EIī G>T>tmxc@X8#) ]I.GUK#쨊5G5*tm&Kڅ^,QYP=f_{L8 Kd/q &\!muA5/SS1k3qTEN1e](^ %*bPH< bxUʇM/q H@AɟA[GW@Ak#bVu]~xc LbF-f @FhE-Ka墼XWuAQ%1b[魃nt518B1r_㪸.QP=l@]K.]~xc 96Q 1 A, KUIĢHē 'A,/ xn5k׶sS`VfyrSY W*'sp 7w#2۲gO[?19~Ȩec>-{<=8x^Y$#-^]lw4E?M^۽o+myZ:00⩠D,5|v=yw`p-w3fT0-ev1ѫ! bGWn{綏}ܑ׈Oz9Qt3( }1j78%Ko`2[<,;~c>/>^ܹe.Ƞk6# Bajj R)߃{N # =I@/ې`^~C1ླvvN50 s}~=?8c~t35ĢHē 'A,Ozʕx`΂sY5kp_D|JqX|t\|V%) X%8͛7Tb' ,rl7npGD|Jq@`ḀA.S[.(<ï_.As#*ᢏLu*.ά8 A\=XBC8yqիW#>]@8ҐGq!#gggp">Az z333Qb8 A\=V\922pϪ^J 'S$EIē 'A,OX$^ noo q#GGG ~/ ޱcǑ|9]666oP>)T Veƻ)| <& dA^t ыphZl4ZъǏI9@gAk e}^u 38qݭt!CVM={ DF*剉N ڹsgss3n $nw}SNi$_bg##HԸ3^ 'OEƽV A>Fn5pˌ BƮO6㦟"_IqVd8YAp+1Xެ!CV b!HX!*LBT$b!0g"e~~>%KE 71wf/v<;;;333===Bᇲ%&'R())}`r,'\cT7/vƱ/\J[7BB:wGGG'&&TZ͌LNTBn1)|ll {BGGǫ, XGQ<̑#G>|Ѿt:t\d[v"FݶmҥK[[[HyQoD~%VA[r):mmm\?սgÖ-[[dQ׷={wȴȷȺN,F"C,|ԩW^y;qQqSSざ ~pE =;TGaO2gNe?'o8#""};Sq<>>>44с}Ё\LQD/\r0~Ləydl Na);Z#ȫ---KRcccȺf1zD<55$=00p=)tq.Wy훿;>Ã\Hs*{"B9%̏n;/s%gH5D ȫ;vhoo?y$n/^o1غq/Dߏqf"vņ_wflC_}=~⁽ݽg;>wYٰ%IZS۷HS}D`5p%'Z#FRߜVk^j2H7-iʭ\8BGT;GIoMP.:߳P"& jss3yرA;[Sem{Owx=¶^Պ/`/3AkU۱!l7.반FkUG*͎UV Uc &^t^## HhV=;Gg,2n36DB-ΐ ^FVf ל@}D mtḍܱGe2Sr̙I΂He:5=v1qG6DԴ~J.\(0}y?=?p~/o㷾V~'_Ǐn&޵n;ݮ)y!L)mف3ߤyoF70`~ؑJ\}[ߚn3oM3>G"VlNv.{k"\"bF}>klLĨ 76iFF֥v[E U=䦢3ԓˆ2.W."Q&⹹'V?=w޵ܷ_Μ9_wC!Tv GP;h a^*r᧖BFwdDa8#9rَ=zih8 BGZ nuY?yFQh8ő C e| ?&B*LGc%1PspxHBXSG~|UɎm4KpU/E=BSD?1B!![R$ !DYI"B D,&X!*LBT$:4:~4!?IID̏!S\1}WBӻ/)lG{Y-w"d3k!JGX$bG!|Ǔrs$#g"vTZڅ(IĞbunq5!HX$b(\//>wEvF'nѨKI"TDg;2- ~uc@/';b̙K SpED)vTV7EM 7噦FA}$bO1#6Z< Bs"_"u$bONĄ4W$J,C]bzc;bp7Rn"B="%b!L'II%X$$bOJG~#_IBT$b!0IBQa|H?J>5!H'bkWؾtR0@DWɷ晈 \+LD‰m.Uc&TuO/̄1a &F͝1Qcp Da${>c&Jw`ntw7{G]Ϋf-L"jf^!H-^epW h=U>x&b!bN'II%X$$bOJG~#_IBT$b!(1) $b!IBTXĉX _jZAU4ZP|⭰ n Y7<%/t^d4nR)[]]9;z-&^4pSQ~*ۑ8F/g;emGP<~8^;_Gv9.F" >`ȃBN7Y5F:V*׬]4ȸI XDHL"%S܉åp/(@$bZun1 By}J٨2nv B䋞\uC#&sF-=b.׳QBD.XFNDD\$ djȏOU~D,&X!*LBT$b!G}衇W \ G ^&XYbťKD\Х/$XASW+tK6I""v(+]. uŬ:duA6G_Ig/eQCBRn{@pEK|K6I""vSLԐP[PpF W 0Ӧ1Wo_YW%"K軞!XbPV:5$.e*D(8+|~ei!l #M<{^z4V (8sl\WI*.NU^|ɦ$bD,D읝=Z]pE.$XYbŹsǻW9Zd$b!?)ø\_dMBT$b!0IBQa$ !DGGG% !Dqss3t)#1C:8+HV(PLrYg_Ww؁;ݓ'O{$⹹ѣGn݊}|9 Gz6ᇧhFCkpĬpvQ) QJȨO<ݻ;::R.t<|x,"w^aRnx"xRN1A{8* K—l0qD>s's FFL;/L=\zҟܝ {J~1/vdC#B@@0땫 @OygMdxԑ/}fA&Řm|#Zs= ~|9:(+ Ͽ34,|鲌{<ۋQÚdOY9IrF&ݶl|w[G> ŋ.'3WLvޢxSrPF5I@9X*xPǾXn_~PZcݟgЦmA"_yY6Oijs6w=7!S$W#7-+n~0p޵%e>Z>&e ߗq Ǵ Gwg.Ww>{s7+P`Tג.rέA Aez# #K{oTc}PqgW@  +@az}w琰dHP{A)y9G >,8 O@H {K0V{=ki1J!@@#_cP&  ߹|5L3(=#@ 5g@}0>{$? jb_?x4@5e4?bw*.*=eg>dfL;+!Z$SC4RKپl~+|V<7 WҟOLuٿ"^䋕 cC{U=C !@W &J2}o|ҔO>)[duwыTu$˝{?)źSfB){sg<ޕݝr'@o#7GiBFG  U6#t%?V}ݻݛ_&;Xcfٹ"XS z'?]`kAV V Uݻ>mw,79g+Τo׮WM˕?L]k7(ި&goEmR]T@UU @yHy @ @ @<( ~/wr{ӠA@_W}P H?O H? t@uҏ!|1%O]~]Ai #H?1D 4hEUH?;Mͽ@i ү>( ~'  @G>zA.H4@~"~4"J B|흦P 4hEUH?ҏAO]~]Ai #|A=z}eӠA@_W}P H?O H? t@uҏ!|NSnso(~4"JG bA.H4@ ss=澲Di ү>( ~'  @G>_{)7H? t@uҏ#@1ӠA@_W}P _Gs_Y"4hEUH?ҏAO]~]Ai #|AӔ   @G~b @i ү>( ~—J?0O3P ,TN$$`"7s޷ )bT>|#|_ii;Z$ !-_t&ȷ肞 Uus@BboK!0?@$]sQ@n.7H[\^|9~);@h~ѝ|#ߢ z.8*HTF AB|YKo>/e4H4B-@B/So[tAGE鏪X !Ho1sy7FFCEHbEwj|. QU7$ -f}./F wH ABZ NMo=?b}# !Ŭ%7㗲C`! !HHݩ7-炣"GU\o$ķsRvL#O#!"$ i1;5FE\pT>|#|_ii;Z$ !-_t&ȷ肞 Uus@BboK!0?@$]sQ@n.7H[\^|9~);@h~ѝ|#ߢ z.8*HTF AB|YKo>/e4H4B-@B/So[tAGE鏪X !Ho1sy7FFCEHbEwj|. QU7$ -f}./F wH ABZ NMo=?b}# !bvG2w$?rdeSvk(7-jc#V\W%ll&{?sesF\ó2slL}X| 9~PVK28]vegND/^Ӈox<|kXL$ PL Q"!ea6eaSII)ɷz^H?!%bJ;6?/+[1=0P͵?<ZD)7g1ʉ ?j=#(ҿ+O&C%3' ߔgi _ 匒DBFI>T'dE6ons2 J~{q[>MY[8@WZ6ćdB2.,50F~DO2$v:[_wo]e;+/l/_?Ƶt<< "Wd!!;.n}fG"GJ{ߕc#u55Cz3cB)ɷwLv&@(&(RoLj!?yr]!=CiHWdQ:LCnPP]}cQH$ߓ)|&\{=xH $CQT~{,SvZͦ?N;f{l^:^z .(  f妶$!<5qÛg*ےtǭoBC @uwdpܺ{({̯3b{ŹW3rSL|oZmwNp%%vhҏI>־oS{r? z%;o@'< ҏx|{?shXOzsr~}Z9:bUϘ~~\~ō EesѾ@~7?T8NԖp{|~ @}ii(g,Xj;?~Ĕçe7?}2%]s)̕ײpT6%i>/tJJXW}s쏞S$V>O0;_Z& {P W.?m-+CΝ[ߓ걳 9nEނ]oť^yU9*_-29l ևdVM$ye]n JBU{[yo#-êY8ظy)7{+KVv67]H㪺"o+?JVTPv{v үv([$$$p|#sHs !HHha˦7i ?4@5eDopTpNwB<$ )-lٔF5!fHڡl@B!|sn  ΑsB' !壅- ȷ1L\;-zH}8@oÍSA99rN$|eS4 kEO ABO7aq*8';G !PlJ|#ߚC@3_sP !HHIF9 7N~9!@B–M o[bh&k=$ >  7Ʃ 9'@yHR>Zز)|kC~͵C٢' !'C08@#(O ABG [6%@oMc!үv([$$$p|#sHs !HHha˦7i ?4@5eDopTpNwB<$ )-lٔF5!fHڡl@B!|sn  ΑsB' !壅- ȷ1L\;-zH}8@oÍSA99rN$|eS4 kEO ABO7aq*8';G !PlJ|#ߚC@3_sP !HHIF9 7N~9!@B–M o[bh&k=$ >  7Ʃ 9'@yHy Iq1m6b>^ʘd$"#`#lO]~]Ai G!Cl Y~\bcH? t@u %a# A.H4@~pH?  Q\腥֖1r[z)6$Y\T(~̅>Ǐ3JKuB& qʒKI&ƈ1[,qQ@=<> !%d !\Vwi@+J!1s!fcz#ld~Cb')K.%#l{ k#k !%d !\7t@@_O]P @3bf?8F  @,dboH? t@ujNWcE~q@gSBfKOl-OoA@V.*H?bBl %:B!R\G8eɥ$cĘxCl( WEB2[.b+4W %ҏ3q1=6Z\jHp@%Lc 鏽@@B2[.b: ү.(  1}gO]~]Ai GS\J21Fي7  @gE^V%O8 q3W)za酵%d'\Ė^ AV+ 1s!fcq@CI#HHR1bV!A6K\~+O!Cl {-]+?~ꊒFHG\sp8㘞-.Y5_uP qʒKI&ƈ1[ނq j@@!Cl {- CSC~̅>Ǐ3Q.H4#)K.%#lO]~]Ai X~@8ꙫB2[.b[/ņ@ ҏ3q1{BiP $$?NYr)1f+ސ %.cHǕG'!d=Ė .BH?uEI#$#f.98~qLOүz(\8eɥ$cĘxCco~m~m5By P !d=Ė! J!H?bBlӨA@_W}P@%[oI?~^}U`1  @gE^cr} #}+"ޮӠA@_W}P H1~gH?nL.sӠA@_W}P H165ć=ʳ/H? t@uҏTah_A.H4@~tC{~ a@èG"Pރp|C|C ֍Azm,o Vҏp~u0kH ߧڢ@&ҕ[wC{&Gdq +MGHW!> !w#Jj"]M0k{H?t@u@j*^u0k{H? t@uϔF;ć=H?O a'WzUgC{;qGO` =*B&#_&w&u|$Xk9H?eBahqg"h*.H'E1$#_&sb鏳@ % )+;ć=ĜCi ү>(  )+;ć=ĜCi ү>( ~2eg!> AM z  @GK> C{~F@í[, ALJش!> !L=4B\BP ҏIC|C5?{ R i7C{5ӱ!H?o.4f 7ՆU- 7G|/".'GmFl#ڰٽEf3/R]E#Hͻ|cHm$\TV9H|#le6\sh~yoxl j*g o#ƗK!wq.ҏ#6 M#apqSmX"|~ėr!.}B~]i$6.n [$@o6Ï2_.Ź\OH?ҏۼ7<6FMa{7f_f˅< G~wǦ0H6rvoF ?l|rr>!H?o.4f 7ՆU- 7G|/".'GmFl#ڰٽEf3/R]E#Hͻ|cHm$\TV9H|#le6\sh~yoxl j*g o#ƗK!wq.ҏ#6 M#apqSmX"|~ėr!.}B~]i$6.n [$@o6||#~A̤GԹeyrcx?бe捱p;܃\Vw7C`G+.KN}B=O"mm|#aQOي0K?oya-n\{Si/.]_ΝI"\]߻$WoLT?*o=jBYXc$se 9 7㲿dyM'"_~~žb4]TEB|.zUD|k_{KtSԏ9v NGmߤHʍŶ4S ABl7Fk5w8o^S07 yx ;Y]xҏo.HMa{7fYҿ1CCb,] f`xύ/-|?^tu}J%ۜw rc,]}[RKǒ(:d T~Lcv7s[ǶHDęH o3WvPZ' ]ɿ!o^yB}O#;8hY^=\c(=%o$b-#{\#qfSi?6o3W>l(w# :?ɇͧ.foΥQqG韔,ւ=:>fIt!_@Ɛ~qGTF;/""ʞ|S!oJH)YJ b\]}JΝ:|x3УW\W5kdӟ/}Knm\$rG|dy.mmmM~~rgΧ?iYZZ~z[ ^Řl|%YܩЁ5~Q3a: 2=m.2V롡+n?Y}x2??~lOg#pʮ aڦHԨ$ 7e䑾2g2[x;9;w^6wvl3rxTMM$GGI.+R3Xnt|ӥ&|X+<]cT|MOL5e{\elZ.):4@'+QV0%Dߖz07HTպ 6,RGeeGݔ#݇ۏ<_ᷬ#b7`~^krVwjfLos2-CN~mu)Eɘ.4a.ǘ\yLC%GIPO>+sVK373S!yr^>|;0jRM7ik,L>Xk$"}hg^-HD~Vl>N/ߝJ{tVG1MM_S}XEM*493:xFAle<)W?z[W/-{`+1)њIu~6fxO\}^c>Sr)r2p+MKWߤq#MM?*Y2'r:nIY=Fwߑ#ݷH*oME\+UD}zP%H=ܫt L&8?)Hߨہ=k;Cc:$W(H|>d7Kt)kcj*ZiZ}~zUo0-*~v_/9a*KKEϓ/Jՙ|Ϙ!o^3N!q7$wo,r~sA`8&,o$ߘ7LzYMYO*@7' {l8;grG޻7d>ge֊I%x{9Y\ې[ !a|GG oDT or_o"Ui 4c.'f/?=&u+6EI`K'=Hm$\Thz'dYxt>Q*'޿apcXayߴ725{2h~/uzGF۸OjƝ4~+VIYf_7U+>Z~PVfLް?HPyh|u21yb}m?@\s\6S?a.Zccf).!]|nUߐMoZ҇!HK##(/H\rU+]hsѦeI,/&eMʐls\XL(>y8};/ohcf^V7ΎS{bg1O3-ߎYc::ji$>?=^`ęm/uQҟL;-uLnvCK5oMb~[Uu]wo&hE(FY{CU+$d=B~kmiUHS;]ŧ{1c;gZl.˪K_V5M80.'| U2oB56GH)pݛ~rn" k[@+s*Y+?7Oy-[k'pVoL:;2oVddwdm5*\uk-rWc눾9>cg5AnH?үVOj4LIiH y('vH`?>TOo*ut~o$KG ;À]"7J~e˃bpzJIFjP) }&ಝ*> dg(7)#hLъ~HT:aɡrμWUf0l h7ȹ}]ї^zZKl>(ѯ|;IuW86|R{9}ҟά: 5[7ZuIθAq>Z1z(sUZMK9LzP3giiI~Rk{M,]VqY}uOzcH3Jg#ӡE.wE׺KFf#-wB@Ki)o$Htfkܻ$Wo xF6C?hq,}ҟ u{ה7Cr խjwHk!ВoZQ~Ak^S~l>n=t2cӏmǷʱZ;r}SPб%YZh93э/Sk='ב36邦v N:Z>>pŢ\xzCl5 \w7/kɢNk%k[FY 6~G5oFHF&ߡyrHP4ZОow?jaB,}T,^z+٢Zz ԥ͞+x99Գew 1d+r8]/UJb?ҙJo8|0ӟI*PS\4Yt4mɏ)Y]4yظ.j B~}ь6 b7ZL)-vA~{sw!1JCidLW* zɡ5zgʥD}W? ҿ I/~ŜJe~9hOwz{b;^{oU^UtK!6TG}36Ha na Aw >eKU+ HԽʆF>eœ%oL NTVʗ?Ҏe,gTR#H}3"*޸#\K;k e2mRAW._9H0JɡHyUVϝʾ9|tT3Q-_)%E9IQ[J32ח7;lGl_rO,C_d}}3ܔyEyb>\K_gZ E_I=BzHo/W^CO aL?oTMWl}z+t~ۿ=Y;t'Qs|^2 |i?].v=FnZnȷ?c}>Eܳ/)%Ӓ7H QN@K-I|^퓃6\&ou;o}wu RnJڂ| ~6 [23{L,yY3C|\O}"=X7gH _?v[%|Ba֜Q=_],hu ڛ_?u=ɛW 7}Qn=ޛ7(+-67[-_>O |r3Ecַ+՘=y02Ajʷ;v𔀖v !`U[~!ENwE>"96?_jG+$+^<[ޭ(̽1ŕho.}JZKE%YJ*|scr>M=>@2M'MuZw7]; '.2_m_m;V;_*R~_E &&s,韜CnhT_Ϧhqzҟ 7ޕ|7CLE|!*~_EX~7ega+g;ڃy8+ߨTHYqK>{O:~ٝ''A.Ys_dCܿV6k[6T';-?_=ɾVKo>;J/_ ȷ@lҳZv2ή7.?VoɅ/S$s}['p٘I\ A~ڿҫ߿)[kd㫯ɍQ/UXf精v=l .F~KۍD檩,uoY!Zb<~!ҨpZ>h~otFBSY6>.nv#$%Ƒ~ޱW'!`,'#26:4卦ԍw-; 8fiOq.'z駧_qTphShq?P_uLn=.b8+}ˎrC-fi/ZQ\OOOES#,u7UDwz'.{h{/Mp/N? ~`0.0a Meۀ=w]IOlOߑ7G3~"?/7/؇nA!t曖{:o;9:=3rǷG^؛{q]OlXP2>t>k4 mߧ{Jt`$D-->{Ld׮I|=x3(zsrx~AኬܿO}nvZCMg!S@>w卿}0awd|fv.kqٝ|sڼȇ%[uu~_^w%o \~SlGK1KW)3DOtځ޷^ك=|v<&ZE*I;1.9k|oEum'%s}灞'-CMAϣ8Fۓ_E߿c@EyQf@ RT!WŶJ lW {95CPazD#Uc(v$z6v@f+i=ߋ==J[3~t9 K?^Jӟ6NA"aR:딞bO2;/Lw'߼',l~i%{z, -fHڡl#t^}ĻtO 4^IOD0W`"$m]rݛVJFd!7Y oxo.nN'<.4[E_޴I9 7w=g=]3އ?L48̥\/r0Xڇ`W_}a= 4{ Hi CeH!0&){G_F~br H?-#l@mP0D9"^iM SʇL[g6g 1q U(MRFOx ˄,r?[8WU~UAa O@!H(R:~Z@U CD[pj/M\. oa >H?4I==hE[~7e WE&)C~MbrY\! AsB$?<$K˂A P_ C-MRFOx mt~}A H,5uzI@!H&1,/_4|?@@2RO]P @mM")4qi,H?  `o(ǃA@4WۢH(z~ h2$!W|ShqQ ቶ&Y_]?{;W6 mP(I@%4 =>ӌ/yd3@<<+sg23gA&Ôu麌?%y_|EyWB lHyN@[^m~~M);=o(~pઔ RV]4̈򬈫꬐Z#%H5K).YyfWyVUuVHM)ӊq@ʪrVUqUG;UC(iꢁgF|gE\UgGhqɪ N).YyfWyVUuVH-ׯүF( ꢁgF|gE\UgӜA@_W}P@ʪrVUqUO]~]Ai oW 377  @G-*W$'  @G~bY |Ai ү>( ~ϙ_ۦ(tl  @G~bY |@i ү>( ~ϙOO?Ox 5W! )-e6ϱ_z=lt(r4ٖfcH-Zr=A@ʐR/˴4mΆս^ӗ+HP?J%_ĉƏ˗/#|kR9p&OHF#!#u2}Y#ʲWV#4T\7~oHK\J[oeD{1^Z1jq͚ kEOG<(bn "7aPFWV!EH?UWah$~3"J>H?Dah$~4"JӵO&C|ڃ#4JN]r%j"]M0k{(qI^@> :j*^u0k{H-߷Q@_gC{G\q@=$/j*^u03wHmWү^(2H?eBahqg"~2"J>H?eBahqg"~4"J);Nٙ[مڃH? t@uҏ[C|ڃ#4DfrU`xfJah1g*!2!S\H~̔Ň=ěxCCl& >eҏiC|C7?& YQܸ HI 6ć=ěxCjZ~uD #&#a&%lkc 鏸U@UV @ҏqC|C5  @ҏqC|C5  @g~+np. Źh үN(zGlg6⌞~3"Jz?8ć=H?O 1W1z12VŇ=ĘƇIZP -!ˇ0cH(- ?:$#d,bV!A6K\~+O7+d)O~`0)l pEoB ~o^# !.|.l  Um_+F6 6rl4$ ! C+ ȷ ¦]Q !HHLo[1!`o.dž@CH0ؽ|.l  Um_+F6 6rl4$ ! C+ ȷ ¦]Q !HHLo[1!`o.dž@CH0ؽ|.l  Um_+F6 6rl4$ ! C+ ȷ ¦]Q !HHLo[1!`o.dž@CH0ؽ|.l  Um_+F6 6rl4$ ! C+ ȷ ¦]Q !HHLo[1!`o.dž@CH0ؽ|.l  Um_+F6 6rl4$ ! C+ ȷ ¦]Q !HHLo[1!`o.dž@CH0ؽ|.l  Um_+F6 6rl4$ ! C+ ȷ ¦]Q !HHLo[1!`o.dž@CH0ؽ|.l  Um_+F6 6rl4$ ! C+ ȷ ¦]Q !HHLo[1!`o.dž@CH0ؽ|.l  Um_+F6 6rl4$ !"y^fgdf&9*+[6,vE|# Lv6 !aJ yn,|.gdquMַdr$鷕[f+^8.|#Vc7*HHhr[6We6鱟[Aْeq.9"[pG>ZYN ^U?+O B?ػ[+rw[H<|8!@Wd"ɟ=)'ez]>N >e|([+G rNDX >Mϲ{뚜_8 AvgpvY9weuq.šltXvo|qqd[ecY%=o[H`I^@ !HHOEHE.;{3dhL~{I90uv󻞴>+]~}#~sq+;({!}.uF"RCޓ@71ؽuUΦ,}孇^[ 4@X.+ HH a= UN=p?POHZ??o<wr v{z=M?H-|3 !@CU)HH(bcџ?[=ȷP-& QHQ f !HHoR!?GSc#bEҟ*lFo#C_HuG# $!͵c1krs\XkԔ;d1p.{^н| ) @@*K ܖX<[S [jg^' sN.pײѝs?H9Bg.;[L)ۂ#t7{-U<7 i9d!{p9-}w[h>8#4@5el}>5Y{ncO7\m:na1.^7\aqa#;YYߔ: fŠʾe3YolzkeJW]Ml!w󲲙K#, <[N8qV# =HN>@o䛦x,0M7MA $ 1N- 6ڏ޿!@F J!HYIBBL2_.fqn @ (&#óbѐ~RxHasX&[!Єҏ75#kwu>~3 )o䛞h$0O7ϔ#B$ 1Lh*|$l WEz|#D#%yHy !H`@S o axL(z$$(s') @30F ABJ|#ߦ @cHǕG' !G+$7=HI `o)G1Hb,8T65H@=<>$ ?\!FFJ~L9"@Bcā ȷAqQ !HHQ 7MO4R'g!` &4FM 6~+O ABr=WHoz@<$ļL6s1/e?@@2RO]P @k;~5"J>H҃R1O]~]Ai 3BbE=%  @G~b @i ү>( ~/>uӠA@_W}P H?O H? t@uҏ!|u{/7H? t@uҏ#@1ӠA@_W}P _G}8=uA.H4@~"~4"J B_8o~4"JG bA.H4@ pz%O]~]Ai #H?1D 4hEUH?fp 4hEUH?ҏAO]~]Ai #|A=׭K  @`HӆĀ1-CS @V VrP@ ! J@ +~+X9( @@% @H @z zꂒ@ @  V @ =~=uAI @ `o+ @H$ @B鷂B @@_O]P@ X![A!@ ү.(  @@` @CS @V VrP@ ! J@ +~+X9( @@% @H @z zꂒ@ @  V @ =~=uAI @ `o+ @H$ @B鷂B @@_O]P@ X![A!@ ү.(  @㮖dTWIENDB`dlt-daemon-2.18.4/doc/images/dlt_core_dump_handler.png000066400000000000000000005112741353342203500227010ustar00rootroot00000000000000PNG  IHDRD pHYs   IDATxKlU;Ɯk|3Qt:N߿Oկ~9"/}n7c/wފ W @Ru۵^}t:N~~~~pppZ8<_8/ [ENyq,J-L59jiJNt1\(wowpp@2s/wޢ >")l;t:N\I-G[0<:::;;t:N4Mqxxg}嗛au zZ,3iGt:;[nH|?2>lhNt:w;w46.[}k_[<xgw:N8>>n-Iv MmQ 1W_}=vt:;&߿rrrA|Wnbi&t:NNfsݎ]4okgqf ^y̭3zä>ޣ'`X)\7^y|kl;Ny %$/h $/F!3|uvE߾9O7 zL-G?JH֭=ڗk^k>z)qg7|?o|:NtxSN <|B.B8t1BO}C{5~ϛt:N DxS:h`7>UCݨˆoH?i4GS{[v:N鼽lѕ A$@B!T/!5t!K(CYȪ>rۼ<Gc~vyjwj?.=Wuv;N穳n|l/Qk(vW?mzj1kוy)]gܯFGuK R7n7ء$ /Ÿ$ )y2`+ɼ6o75u_bzq]n̴G,Jay6l٬Viq?:N)2 C)MRLzqyn뵻꫷o&F޿sDy3sZG4NWOn,Q)eq6+/KKO{y4ԊԕłXa;ɇJK Hqq : 8&~]w=mkzk=Pl|P_wH^s͹$8#t. %V1nGvanܸѮ}Wv}nv'''=gggGGGw}g|]ڊ[zpp}ۢP: dE-5[*L\LaT0rib]@TDEKk.5Q+j,F%B@|EM^H8E @D~"/k.ךz(($xiА\=˓zRG_+9^Ããã;wԘG@<]^yGGGGGGf;;>ɉ$ /| '''/w}__|tt$- d~|w|w{[7)&_\XgKq}?BQ}}]UȀWksjTq%5;:Cև+NWY0I"R HhtPmOqu#BFrҀ-Euukt!u%VČ]4n'  ~fX+J{{mFdVfsqejuppj4}_#t.>,n7MӍ7{9IG;h{5 '''_>O>O|"3/__W~}ð^2s_|~w?vfa}׻u*lE(Ҽe N0$I 0RMEi~r CCfFBRCR5 ^Sʭ!IDBH2zP['E"H 0A W2^!xo -2wr2m}=f*F:~GI o<끒Nԑ3fC>R$(/~~#ȅk_//ݾ}ޚo-|tM5~|`uxӄ?y}m6+ #ITRiZ >4mSxć 4Vi23WL8ض2 c"^tCv.XRLJV$Md{H Rl `LG̫[*Ra2 )hnn BkGh%xH&6^׿yRW\\ ŵ4E|`~嗎{ #t~.sZ֊-n[׭޽{8~ _8==g>?#bw]ꫯfiij<NWO&ar p]0ьt@u}U ڊ'_+a͙\VZUk _5|'"W230 ʸJYfK`4+  Ue,K*!1,n NIv\>W>ve Wr(fS9 ۷Ǩ_ NށKOl˶22;7={;޹{rv^t:E4M$a888~_G^x_2%/EğOfy?{EL޺ukN,4ժ=J釽4MfVJi'5jg/+qPtI!(s-Asha眓urL>Ј476?@3Δ S$jsLRd=ySY{yif)TD#feCevKp9wH#y' ȄP3ì`B&QIDh 4X:QBB fMEI `6&)5 hgC![dBɠ$!"oEpN" K-k.@HD(&GWG "-&, NgX" H 5V5t:oԧ><nkzJ4R. meZܽ}|+n7ol0-At [Be\>Dy6L Vn?:38WsdJZA$ 0h(II^cRXlnYIr֜Kt%ա)%i0,aIʐ@\EDдdp2i&S@ ,Y!ThMdMہMb@њo 6b+Ѫ~)vu. ]9qBR̬40)i&'gj rmlv̼Gx Y۟4nD2Rdbb oS ޖ;h`FFJ߅||-̦iZVwyWy.{A-~Iw6Mvd/bAt~EAaq[F@fiGE4Nyn:]9;;kg>'' ڼ[ny{ /о۾2ۿ}Dēy:w7Z?/3SC>y=^#aټ֧"b4nb4yZWb LY}]N7KHnZ'efVZ)!u3hU)qRiL!$a_qo fcly,@ `JBIѬ".hɴq0b)$]BQ"iemd*PVeDJL䜑ВSZVf_Γ(a 1Zn<%@3ȔB\oѨ}eX;ae:{KgRI+PTJFB("##SsM[vMU-ZeAM̖DJm]&ꄡgt:ΛASW `f8~S?O~{>򑏬6K_o}ݼys܏R+ %86g7=0|#""!h "Y4<86ӘX V!ǚ0FjIT,IBxi5B I\Zf43@ʄM`3/WYa#I ZCZ6:7 3D)a4N*B-ݐHL$OIXjB"1 U|\lkD"sd].Y.IڀP@y($9nYUcr[l_\~}sP@:p 0h`찫[cp\52 >0ԑs @4^ҬN :!UhǫNsD,etpy^ly̖{VJ)w/Z[g3^g&sɨi^%ĔQʼnn&eVFwYA 9Ss, 1`f2SH1EifN{т\Ӵ :M[e˾&O>dR}"$7cjHkB]2SfAL"́M/a82^4 ^L2Qcf֌l]a2%pX eώmQZ ײެ2m?p ^t:F;9j~aw͛74?c?O~}oˀ?}sW'"~g~7~776im?RR_tf } PL5~ ;"Hn?]OR1da4V^F:F(HWhJ7E>yPڧ|K?,17-ЙYXq2 5!#rD4:IX[U=KzoއHYldr`2e̗m?P)NID&kE~+mTH7Ęm!a M RdB I J =eB3r# 9a0T{P2v4E%؇b .CunKFQD5jև~0/q Vk||m͛$ȯ\u?~Qb@`PTaќ{ˤ@K +# 'ڷ~U6_Vd{V϶z$@Tlyz.iD&3/`4@$$Ku}Y4%߲z)ѴJdesɜ˩ZkbzR$Aff%YVW@4 h 0,fAwt:N Q ]{KԵhr8=b4ȐR . D% 532m "ԢFM٫w4RY-`q錤I8WR-amNK\ͺDZ %%J>0j^n*(dJʴ7>I&[>3s5M1ƃ%msL&K貶?RM'Kř IDAT-fТeAqvAnKY4hϤ9o(kQ[k4O lmÑBeH1%dDYd99#gM ̈INtcte}Y#GNhf.Xxo숌@fP@E6UJ8ޕE#7apRnKiif2]5ޔӑpaD`~\N7[FX-rcL(6LBEŒdbWl.4$ (Pc@lt "CRlPs$r*0y5'=fϝT$7B A[&^aǕ*UTf l԰!ksP1dwt:N :> RtzGC ,Fr!W9h`Fbf.ݖyъN 0Ml#"ߍ[:#Is & h.@ޢERdIM ,0#`aޖͪN2*P۷ e Fэh,YK >W|fFo! iF >%3IٴQ,$՚08連}bER!i;ڈ\3';CBpL܈(&o " EIQA *US&b3@sI󌨘*ª,)Km[t:NWwAK0\xQ ,gn,4S99FbJ•+@R@aenXb@g\tCF>RVܬif S$y]ZZJde,h9097Q~SZ]Iv_<46M# aLʠyaQ$B̓qHE̶vTgOy^mZ"o;#h?ت-.P(dvf¾s@bUĄ+33SVP e\DP"BDWѤsp+M=t:NWo K],@MջfAH& b^l 4:q ‡$HPSD&wOf}4+(i[?t;Z: 餣 TBs `%}<FsRo(LYfTHhL@3 >ËNv `Bt0'Z̎0N7Zj![i^D͐ͮlڏe El]ĩd55LT$SN͠0b'bjřC9#BQ[,N{Č*"J8Q^a;ivBft[^h3"a!-:NtZ)VQ W5MZ#(3Vā㤠F75Z@ p:,d1:T,L4y@2`J#V\$a^Ҧ2AB@E"CfJIeͨ-V"W.T2Lc,[ )䫐UY)Jbi6L ݸ"2jvxtbu21SCfaY--91"6Ӓ+@jIf6x1fa.w(H8Lmdt֌ٚM dJdTz *bgjբ&BJ1 eS,ߠ9sf4H<4Sai@Jt:NWףbh.N@k}4hf@OV5q5+[+p&Z`&He6 Мn(ƒȉڌ5)BZ{K$2D.:\+ 0\0;؀q@y aEĦhVJR1cdkY[6sdbhHPeL2.b'3ryq0(؆-2"'9۰EUj%ږZ^fvxp@x43h6;d"cW D.i 3qw1CR-O)ʜ\ 6h@,xJC6 98L*5(+p(3}_2$ &ҍ5l8%YqyNƅ[ϝLI$ͬfگvUK[)[9篜 L_QkڐB")Z j(b@"r2sԪVVL󄩢V@VԊtDr}dv2)$V̶q-qkU[Y8Q433NL&D8!t:N+-NTd Øy}O@{M.UeQr>&P9IQ/j& kVbUaapb5,ޒ C&J8atC.h܆bw7je9\ X$]! bfa\Tfaۤya5i`UV\ *LS瑃7N?>=ߎnmܭK'ÃʹeqݼRJƲ(QZ$`b&MݼMDU5̚ 9ҧD%m&"j0Dbm]>+"U͠ql_N`'cf;t`A@()$|nwPl;NtT_ϚkM%!\HPT$LSm'´ĮM41uop.b TK81 '7((|fU<, w%ƍo3ry5Yl+kdn7'8\G8;/L$P lP^="z'8>䝗x`Gہx6Li8;}vTH?,t5ޚ{\A9L[jS5Yvg'y7S) BzjBfb"D!o*A"sK`-RTrmm4WtZAZ|4P׾ۤ{휯^7t0r1m^ hR7\'m9Iݘߙ;LrxϮt) = H@H--YLdt"!IEwP5B+B]4=======q] ^\y߯tۊ0 d tJ<@tf S{D35V#FeoQA&cH t1S3^|ijY?{'׋x+M(m'^ t/YI+$ dΦw*ryW[{D'Fw%$㝻SP"r";NIH&mV Ζ;$o z+կ *)J#`` -kx h`lHF#AxVrW֙4PttU/E]QPHT ݚ- 'XWؤaqs0?6˯}-NO~\WM(/eA28IŶ*9J&7[h:^_-_~8|tҖo½N[8nkȊYz%-|#49Dh~wZ&'R.&(9$G |\cy;@d=۶t r",%(f W?+b-Љi y둄L",4ՍaB`zR isřSqZsF򖭛 H;s-$tզ<}fwזҿ_4hlrhJy*XŴ[Φ!G24T"VH@[v9s($%Aeu<{wE@Na̗be/{zzzd{7Oj],W^Y5'E躩NT+HN$ARyN0"\ɲ%@#xMв4nsBν$BH ='A F(f|~_߼_OZDU+5m&CӢ(V//giaêmroض٦6!m/]nV?vxy^V V`4rx"l>oyM}nNW %X;Mmս^9 RRn@K4&VmwJ &6BrT>%t1`wD> .[chTgϐ========N_ZkIyc[ԃ#* G?]"u?̫Ji*;[7d[@F&,/uDYU{Of`Yʥw(pd1hWO_TiQ!Fv~hݬ6b16a>[Q N2ڸj`YEs8ŷV矜`<8T9.CdSrpIL,p(d4d!Gq t"@H \?u;=e^"p}]~|z>W🱂.d9S>@W G2.?o2o*/çR H֥@ 2&<7 95R]D:|خ@a IDATcZb^P'۞F(uݶmKͧ&5ު6.q$t4 o~{6m[ P41ͧںQ,_j'!N_٧/[[(j;\V\FG壳:nb( CDiR%QwMd631' d|/7ˇˣ_z!9qvWQUO ?sܟ՛eiu&o^~0ᆭxBG{] 7virhBH)ӀP뽢9.KmͦVjmNް0&/^,ruiOΕ0 ,!6* m{z'^. Ej[MEgok$Rںew1f26 \ruKנ.H~52Ohs覮"E9[ݛ_+ :gn"!CCumOOOOOOOO9~e 뿂~8ήsB t9aUڡY磖ȫ 4ȏ2yʃ^)3SJ`pÊCUC%oTFNi]mۈ^yk1)6ӏn-.&3pZ6ɽiǘb"Nrz|Ǿޗ'?(`~8;Mbs'cy{=}`7O^ܼqyt|`\7#PDUԤ(I1ɪU^7RkN ÁUMٮC9ߟۺج-jy5C. sc ham&W޶;vP@ .+E EY4 ꗜ.nSJ1ƜKW43d# k7&7"HQ׎( Ev.OE BA0D)B00U tn%k0PN7juP=;w/j]]VG`w|xswoԷ|~qqq/X.ܛgpoHg &XNN^ oW9P0f yy5(( R):P"O(D]yNl~0 kAc, l(ణf0ۻqo݂ 8;__ m@ڶ>r>>Y==SQ-.ӓ}ptxvzMVpjAYza!Vmڴ^%8c rbƆs}lbeiip7Y5'?#Wx2y~B1eYzDp>6L6uy*P0YàPԪnEF ]7+8JHd\ݲn*VRΓZȍ붕%$ɂ 1QTt"-dC@Iy%D04NʫK`aMOOOOOOOOc >;gv%R hFiNG1c1wJ= q;c7‡1{&(W># @!Q2R(aP&y~эxoor4z.>}8ǃaTk7g\6 :1+55ۺG `>ĈY7pnM[yˆ XQr}i%!BÑ A\;l%)ٿDQ&nh2v" F;ۋZ8'#tPf@fY9svomaO{zzzzzzz7U Y3)9A %<#=XV ]F ?U0o-&k JbJ"B n1)p )facKjCۼM{]֢dhd<ojw V`|[ǯnN?{u1l{ýEHMKq:d |^_\N,TcZXz[mT(bq`[oC0Ӏ:$ΟbD$u`9vS%-` 1PvnyZ8`B63[-ʻ-!߫3 gՃ.mW y2J+u|8c.>"D<,7Z4.=Ǻ+PYǃi %<"{ .UZ] N@N 91o+vzȡ4e҃X0,Ęw[#of4* F(BAE@rk QmJML~^g;bc=gҠ a'g7 7p"a;mx>;σC̦?B# K%`hڢu0BA"/#R9*o;_o+C b8D9Ru" "cgCqB).J=AwyI]?%@Z1DIPVxf `tP#N 4]'kΟ6צW0_f;󚅆9:P dP"hRj` ]ռʞϾy(RvfAn 0Z!H -napz];<nhW\ IeYjyZ߻?XmZf~हXm_põmfYomMQ(QokmQNe|00Q4 yϰ/bUjjÙ|r}aXn (3@\JT-HZ9}rQA ;-]ݕ^%#*4B$kb~cK4W 3ш 3HrL#hL`P%dye!.OQ,PRrGYYp8bBlĐ$ݺ,a,ǏOONO'lg'ťfo|ݡ[Ӌ;o=|뇟ظ?'Na.4kl"i8(m`VjAy(Z|46TUYJ)`T,l8B(Z-bm !@!e$ $a@ %w` %@E% d;vOf9WH >W 8ASD ========Eǝy2t= 5.E  (9Vn cî s;)#i g  ;~E1+eUw_X_>䃓O>}b|p;{MT[lry<>>x6Ov8c>|WEXU(m0.Y=ܸ8rmjvXzP=3RHq<ͧ:۞_<~y{_lOi: o KL#, r1!Atxzu =ߐltAhQޒR0%)9Bވ]dZ] \nО"d o`BgH:d.(\,A (@ٹ\`I&%,̓xD!\Ŋ|@ e/ (BQ,Q!BXN7Z#s0w !X,XhT\j(G|=َ;|B{uooޟܻsߚ'(g{}6?8qwh_ͯjX>Y_Lp?D%(T# ,zdd"V1 X>n?I|^N5;;ytj`~Νލ[->GO("X k.&OsRɉHB r;Sr@ ^ &9'&})dޔؕ*s`|ogHȕ?p0hUMsӪ"WPRnV*B($eMd{JҲ Ü<e1kw3s\!56pܶ]#dC 8MjGMֻxe,?xѭ8[~޳ýںMp|x:+?~Xmy`V Y/L<b7hn a9m!EҜ 㨁&30&ȥV˙LB~CC;B@OOOOOOO1Evyu()w(կVZa YQ @7p˱*Tn  G )3Fnܺ{o}xxk_z[_~M|etVUϷvwtX3,?oVO~f|'ɽ ~iנlws34 #E15Aq@ǧ'pqKm7fC./Λo|ý|ɓN7>lc"o a:)`p$26)7J` s!m.iFSl+N $rDAe67B sbOOOOOOOOQxC iX@fS0@@[lW$#Xw2T>N)y*i" #dfGY!$`Jq6Ynaxm|Gѭ>x8?kPfmSx>?;}/)0߲7g b09oˈuX}yXJ7o(a?4ɏ~ n~Y6 mxMEWrzy曈l?|O.Ƣ[E6$Ly`f*[Y\s:g^E#@0shN1Pr:$`̾v8d "8w:۬=======;G2t,`iF0d+<Ȃ@""nnP GD  Z,.d @"kyoQ$#;A2BYLIpgO7.f'w~a,Zo`DU d03?|c熳|h> IDATz3 _} Wm)N/ibzݠcYIu|ŢYrq^SU+m jjYHz2(ɣũo.w7~ aa`{p?ڑ+%6C> o-ðy.t] !kMLߢ@JWm^ⵉ{i?{9Mt2 ne #ab` $Q#AofYs`]f~ʦk-ɁxsNmDZOge{я?ܳ/9&(j_>{}7ˢG`2ZV3 0og7tP_Vv87Q00퍧mQm؛ ½]6O"?x'x㗿%S~4X.Y#Wb|1LAU|wWQmȝV#).~FNus8!k@% RWU0عs\dA|${ha)؞e9Af]d:h%Ad 3 ǐHB4RH5ow~<%+Hs/ESNxAS "0;> pPO)ǜ)r!W|8}㹵.ßhoޮסz(omfyvΝIVGɠᶙ-byޝ%a8YfRGqv{tڈgf7/NOϞ|0o|O~'?^q[-LM@khC]A&G_ij ޑ:ULO@]96usteM+)N,6˒&.\8\*.3$ Jsznq,AN Aɳp$rߓp%DVmZmV/I8lu[Np(\?VqN > bjoɋG7n(}Sg%u_'+9ojߜLfOLJl:Zu{M/=G=o0(f/N.zy?]!kڶjBme̩0IHIJBvdy |׵H:'_#yc uuA.$ݑ!2K=======yJQ/씀I $C.0A^Tit%"  H: AˊpA:QNX@Lr@.xrXG`/\\T%nUUi^o'A[f??>ؿS*uCON^ ޽VN:L1PRURZ1aHݸVftۮʻz:ȫĠa'<"M>Blڇ_ڃ?ߟmXT&ZޛXmyk}vEF6*DD$$ hi X$@TY23oKs=^kJ& ޛuY{o2=tqH̄^L.%@&/ty!\lk:^bk .PtizE(5O퐶i+ z,$.cїċ%W"A;gkqſ2534@Eٺ5u{̈{*8 -Z'S[h@]k(mR2# 9&伊̐٦L |8+_>n4mnva^uM5-᪡u||vl݁7(}1d7̰®٬&OO2Wemγy?:[^OSofao>So_}qv_?2dJz x7C`J0ĕRWZEF*hJR(2 )$c k|jMTB"v!(e*SLh&'S҂HƬu 2˝f o(x>.1hIvDRD .I T$ ׂfjvKPBel fR]-opZmIRB Uc&u1~fSu^ܹ,|ڟwws^8~BD|5`5Q90 WD 犒|Oomݡ/\? ð:_|O_=mYfb! uyh¥;7"/4 L1/F)ez4Ka*_lfW轢 c\ОwKqƖ0;|sZXXXXXXXǤ/0& P d2RY@P J3H(/F%z>(E# k˫l~vd;1Tx[S5Ým72C`xmYX>Χ0wWOw?k7}gLqZz粮[[pG<=`ūۛ~*/:t0H+>k޿W_û7ws|CL~瓟:,W|Ͽ7_v'M|^mY)`H)2 +"% b[r&!223.^&``K!D}8N1|7T A'HI0)j@_6ZiOE:eV_nGH8BtXE &adf 2\:3qF%/]1$lޡ2ˤE7a^*F t%I#a0GgOzu[׫jXHi<|YlD9G7ۿӟhWۇo⫿;s]N_}/q}_~|~z>}{%џa2De3-A%jNvrR[`&3SD fa˴i//Ql-\ /yyړQEY)@faaaaaaaQ𿁖~|4͇ԗDkYf$$Z.F9i8BiO[k 57 7,ů_kXz.Q-̀W)42C )I# p*qaX:ᘪmʋ] `ha՗ae?0N{{9}Uvu4oaZn{z3q+4wu?~m1 z(@R#DRh2bODG#ږ^9(0.a?a?D #&c+$׊(9.' /`> a2ϗ?^!7d4BLjMV<̰Ah=)0Bi%t8p"~5`t2Gkb% Ha$ ՛9·d`Hw7538^?' f[r q&~1:~^ zӆخl>LW1q~^aZt~~Sn= ]тA_Œ.q0'/-BdL p)Q_ p _nlnT2l$4CVʥ[;?$s7eﭱ{^y EtXi)#\r r?L.Z`-̼tҐ&"zhxɂRA߻!*6>%-fDqxi2"㛇nxz՚S}f~qNӏ;)Yȡ2IX1w Y ETB26?K2SSTFok dUmgXD’H*= ֧vb^@`$mɢYXXXXXXXoȦ{/ yA $I#YW(шYH\k7DIyHjŒQZ E.}y9He+ʡˤ5ʈНr6Nc``":s jXdz rȐ4ԡ<ݟ>|~>{uu]o?_~O:pV˶R*âΝL8Zu3Qa\?8Սf *\4 qvq#u&Tн iBZ p(DvPP(b͓8NSqhdis:vz=ξ^\)msZXXXXXXXoA[T 嚀 Jʜ@ dD9s3W4&Q.SXEWȕؑ =ىy1W:SFN9 ӹ͍w!)"["Ġ*IYV}mP*tXW@lL)MY,a=b\yx]v{Eg?ɗ?seSZB9G.06^\OE^J4+@VD4]o.k'(fFdUdHf8QA͵‰ zؾkSm] Qr<#HìD(e!(@̈xd]qF?,2~aaaaaaaQ"sBw "Q"벉.s+`Gh&obZo ޠ/w/x[Z|d0tf9X336zSeAQjHd)uگlD Lvq:ܤ\8 3Z"[e4#t]w4Env7kF)e"#PιTsTk[8UkJ(Jf0H L~x/G-nLD-.t  DJ+wWLyZzZ+^r-@;y?ܬN￾E)t|?gƿrz]T2y kc"S Tqj2-!HZ&/eYypq.G\Ľ}(~9WBPl5beBĘ \@ T#S`aaaaaaaQ_^/,DK"<;wOlo) )ifNrtZVh ˗y*fVMٗ2*/ >?\)Xs8MjJhR  :X<#gZFo(I;SMh,$A^IE8Y|{^c톧| ͦ~tm뫬qU0q:2 C y)8#j.UYvI% E)[&L2u?45OjRI=.i&d[P 8k*3_}N1ju1k{٢^XXXXXXXX_ ݷQjVx}9ͽ4 h+ itD_<^h~7!ݭb"%[租rl/Ex1|x,pu d1i|ߛ0L7T:z Q^ulK-\`!]qsfuz:m7~8Tá6*eU"uwKF9K0Y׺>@$:cNsDNcR)E tNtǩ֚YH>(x<LRgZ.'Izdi3 AC(iujUCT#caaaaaaaaQ.rS`0?l^IRdR$Tf}]da 6MD=H)%5yh%P0fv:.ڑI6?N/4"jBR2vt03 b =lH ̹ZґŲ,@J 3+*jJ Vz/áz]3u?է۟{GltU00MM42mj9TLQ.PȒYͰa,JobM#2)EJ*;@hΌZ%MIʹƨd:aJS4دrXƚ#`aaaaaaaQJ:@E&̚"àtj鈄쳂dfB\L5UE"H$MG_ݗ.?gr:GvZ 1Էi}g~\gczIh:GIEhg,"ղfZ~s["㌈6p`Pmy>yzؘ`Rwb0#ɸ,7;ݎ,B.XAd;5!_л̌_0!CtQ@5bpdyc{ lɒ\XXXXXXX  M̤Vzm x[d"bVtYf晦"&%GeBJ]d$,-CJBv-B'f g Db3F˱``&x~)~>]A9sCV}2xv콰VGn.be¤tp^65pRE zeP&tp_iK$G{\-vD0NveL)YdY*#D%C͜/8,4w*),aFʂrÔH 7pЃ%JraaaaaaaQ./~ofjh ٲJd@JZMMF&Ada2R>إW0ORf%DI٢yʌTM\*ff_/ IDATc!XXET'Z| SB!wD>n6ʺ8NyhzX]^q<;=oz{4՜F |<%2hU {Z :NGV~;p"G<5h8xNny?٩9YOfvꕌa{;͛{͹y3k# =NGY,Pf Fr3zG)6)bSkOS)|֛8t^?x<i!ӸZ@RzXħsE/,,,,,,, deY!osꈚDCZq*XϱZ <='aJ`ĜC=c1 :PxUקxxN]pG`א`(`=%Θg k\m}XuR 339itB#N*(7OD0 a(;t3BXm0l0͘Htkhe;OǽFY?p`Si2jbep`]@@LT1bvgll蹦 ,Oft(-D/ޕ!j=q>(ժT1lx< &3 x b{I¹̿z?xy\wfp8H(}C?xZwߏs%0qRsi3C4ei- I;Y n4~<# J_VRJ=2]mno'Ӆ~ebt/I4>Xug4u6)k"*:q< 1Y ۢ&p/O`W hQu8)X?{w#LouIpS,\1RAba]G9T3ͤ0B8\Ys̚D:@j=?N*R_ԭOzwU<q>9`14*08۟ϵ+_<T+ns;Ly.})8fzp1%pÈaitZXXXXXXXoA/7J|DqX6nB ~(hff ǟͣQ.K1_%,x??ї_9~ u=;;X ~Zq~:ke_yJYq(MsՀ_~,,,,,,,, ȯ f)d*Em}N8g UwW޺8H6͊L6"cQH y{{ U4Ȁbxuk7֊鬹52AY~z(ٯfuOMG;$֜gvf)5E !Oo}0Z|ܮuN"޾mןO|߿ TkI33+@fV \~ ,,,,,,,, ?H7 !F$ hN \\߾2>Cy_SNg7~5wW4S]äyՔnJ~]wytj7YyU9=1\w}ASgz8;VXkK_w#j^}zs?!\wmqNoWcNc=Gf{w͛߮w?sګoʰ|tۿݫ[_or<=i;$8%D5x ЕjakY*]CDa)KCz>Zq^~u;Z?fv֙n⫛ҟgW<رl1uNG2b߬z[;m7zx~?~}>Ͽ~oo}|ni?{hΪ;7H!$!B*%DBƫ^"؆mxիrzQ@( Z @zNr=Ϝk}jШWp}묽~;tѨX pA`%˅2yjPJ7,gP @c@ؔ-"R 2"6AQ/h5ny+j?ch7` e,̏?g{_:]ۯ~oCilW={>{K{z(Z֩O{S.yg@>>s}P̜٪K`ڧzelr\$NC>_ao'߀Z"\~vV+Xz+29uK_W О7u-~l˯?3 s3D[vx7|^(^pg5~q=ؠxrz{h˅_}U˱ka0/-ܷ{G`n70 >t͍KAO'``4?ő_w;/{k^_ٽw2SS\gX#x >qHb,F"1]kXʆO )ltrP5BDȊ, q%m [Kgg`3%t{^7T,1h.K}h`qa]Lq~e nn1;O9mSفW:qMϼOwV3Y6|o.xtB=R`7θ5Y+&1Bcdx9WtIAPc,ٝW_]fxpa۶I35>ѿh8ؼ}pSx3uG/Lvj/Fa>?Q4Ogn~؛d0L#:\tHi<3Ͽ>}p)0Zf-S=߳oa>̥+Z: YΦ~3ZÕ47n$s++8EM vڳpy9݅pyWlOR8 mͼ Ʈ( GIVTTTTTTT 8dMăΑ@V c’ %(`<8e30X )К|;g3SO{s [߼>n0 SG@[uwML֐._pӵ|gN}0?z+W\w3@wO7|XVZ;w6v;w'/LNS8_hK#@-wmj;nZB=Y2NN`z Ltv]wیD+E]Ba-aSW߹3 w/GTCG>lƣMן7xGa[^O?>/kfO~~qg#0pGl\x&ı-z:_{LywwN߉- \~ݾ_Rbh!(h c_ziaka8mPFqAaGRCUxi0=w÷|akq3ngh&&sY:Ιglܬ7Qfބn߾} .yZݴِ'&?o?;YӃtގ-fi֌|q:(  D#H:b8$%^f^E#h &IkS:3w#j)h<F1qBRpAHVL̏3P;lZ4 @e2ߚͽGD|+ߊ<^|#&:;(OxXؚD2|s7 aq8 wގ0Rhf0#Q%V떛+"#wgwuK]nX8ꑎ"Йͽfp8 QGUæήQKg=-?w?4Y` ʡaIk!︭a#sނ&݆T_޺e@k\ԥ1Qnw߹h mT5`-~ m峮b! {{3׈K9af38XС/|u W]=73EMш)c?nl> w< ~a_)7JP|8v.lPMުq|'2*Ҩ+H IDATɓ4`+ +I: k0Q)Θ_}̵O|j_3w7(˃Z4Sw!WZB7>/=dp?q˳˿o~>w}w_?\ykw0qGX0O~> CXı,X곫ϘN, =8x'JY6B%Mm!+=XXť7I)TGp ~`vLYq'kQP/SZW +CL ʳ;0p j(|n}ϯ,Ll GpA0Vo5mnn Ҹ0GVg y",Cs#2y)F{ z ͅ~_`lacp1p _ "PU ufrKFc{P wTٽљ8º C8YlO"m^f ~M^ GAp oܻxq:V\,DC>3xmԛFq< H>xM_zߜ(r|kwl8DLM\ C  {xxOS3rkv4쪌8PK/q1`G^f3_z+F{^w+.[V!fom<  3_»~vE%w'䞴>.v`:ՊF_/6Ÿ?/ީ+\<̾/ - g@ :#r(Hr@A%+******hcKz"*kk2qC~L0g6Ȃ8 ydf^4;o>}t挙liK7:nZßk678}3~5z_ H ?{Z7zq(btgn  _g_~1&.2|1[. Њ@D[Ĵ^x+߀U㗿'{ꖁ 3n ia HXsl f &`m J! .2f2A+2&Z ?q[@_ᩩ[O~3[_" 0(;[plS?oܜ~.1!P84%}iϺ|KқoB~zpqhm9GeCɃ l(2>cxW KQ$Co-o}/[W} CA?ń9x,4.a &LB=:x=iv0ABI}aEGa@ʔ[SEKI5)3Ff7j~ .hחƖf^2*FE׿կ.;r%WچGoxѕWw\16>[_LgE?߮~{zgl'O91!_fSl&MR$3?Z t]Z4fj g 3H:[.z_9W_}'ﴙтhս=;vţ_E+b_ 3j#'rr >pIm$wttݙ_.{`t}ks}ܿ9 W>%FcG?u?uIϽ@Z/O_|(ɩ=dKOO}䣯ʫ~z, }޳K΋wr}QHFpS,E#96M9~_sO<Ⱦ뭿?] KGPT+r _QQQQQQQ)Bs*(@sIXU,"JAi°{x4LuZKL5i8iHx+GgVf|{q_~Шuo|U/$- :g-o#Z;^Ҹ]4y3XQG衙zk96`~\c4>럍]2s+o޳R_cң@{y(:rg]9vn] up´;~_}S{F0FU_‡ TbMZ{Ͻ W\e7~=D!+crཏmQ 6z+vCMϹ6![^V\p`~;?ܵffV{=xdaiڟz]=>>?٠P&H7IO{Ƶ~!:I~S҇aG>IaSA1Vr\j 05}snzZAZ][s'Z`>λO}C,g`l؛R؅jp`?nG9uHr@u0i>m?|KgTrQn.޹=L?E;1l(y-n-=%۳Q?h7I)4?t۝F@tciq\0EA;H4ٖz;̯:OL)ruC}Nɳn2>b̠QwR8NO  ?ʜR֘AZ41Qd3Brh/vvn.M&5,\^tUIRgZ#.ڨVh? DyrlG4Vj;ҞGEMenPNx8(fv(Ɩj1kaKgta9'k}is-/EahȄdFAwbGZR&g!9D /, 4|EEEAU-?nW6<03!Y0 ecZjpFyZMw$xdmq5 6M0UoIK;bð1ma p5ɹiͭ f#d 79+ Sۍ&<;kd<^Ig'=D5 ,-Ia0j''I I(`0yҬ-:3ȌbDǛSl)F:j4 uಋL?#h0.&xֈ >( ,yk3 &FJhƘ~8asb-?Xjwú 8H>-&XD6l9?uSW 0;-$~8X VaPgVIǵLaJǃY `v(ϳ8=0^<"6MO4a0pI T֋ReY[c xLPC Eg0zpl:bGlh4[9pl7[.%\Y 84:ԱS4:Nxxg(insb7AL޶| 0vzsy_( ;vzxqF a:NhBfRp`W5OA2NC7.jĜ'&ý3)zJHp x(ByR&jh֛J uLX/0 U8G9RvbHVf_#0ٮ 6 eQ22i W@=,-/1C̦QwT}դx*ʝ[a"6-63S7"/fL *M \}q<61=xpmեz 84Φ~{U o. НCäL\X|JXIpJ@DH *19PPh*******hu`HC JCb@mTsRNٓPy69棤ùh&E~&0m͚;:Jd|ǺIr7V6^/Рz2>I9D?20cyg(5NGRǡyiZ,kjȳ(؏tf'\n p2(|\gF HظNӦɠGPa&$xy7;qjV֎D( RR-aT3Cݨ&bBJ10@ZJ~PUca>%J$d="D$=QPWu !戁&F (~֢ l,PI|{X4"Mƌ:4F5ń "19V Q並AxU B.#XA0TBV( V5e;"e607 "aK,L8"1qNYUHXUTsH"Ug^$d@L`4SK&c+vLpw* Cd^T=q@^2T^JF:"VPUĹD Rw QY"b*FY-8} c`WTTTT RO,  XBlElwp'ʢĪjDUYaZ- Y60`U@ըF l} )[Q⋢POb}fL,iXFBk*!iݘ) 2!%%xٔHKU @C b  ,CT~k0C`@F3IUPU9NDPVBEPT3$ +INTDՐ sS!z0dȩ^ QAD^)6lj99*@ȫzكCp5@DlLfޱx|*/J=8zҥP6(*~}R@Lr)$Hu}jÀHˈB`"%#^2q.GYs\}reCKle`񅊊C)U{xgbbY6zFA-ET3,!3*)D|h]ƃe.A%R"QWWQ9U!WN QQCǓ=g1y6L^EbL/-=u@u2.PjW/-:8B8_IzUP%RC^IBăHI|7""eCT J(x0䃓-R@!B (6< "RB7<V HO@D9E%EqyRxaEaE8LN C1C̺zV:U+01P8Qv y*!pDeL_+;()KWa8"E U쀂1yLr'ޫ_ ADS=CHe""%^PQ-(QHDTET Pjw@ RZhaRDcJoX𨀰TTTTTTTT FY8`2 ]3dxJ(K!A;!U* %6 yn, g 1z!u^3U-(Ψ9c H-C V@S"CL  k-BA`J`\`bH=\J PE D2PE!!(@ANJ3RR'N X_1y@ ꅄP_0eB(/ev\@Ot2u;;A@)Kzцyq E9 t7nr crܒrj5ݾ.-%BkNjb`a02HDfE q"H9 2Ď)Pr"9 P&PKdH@1({D0D QVNrtYf&ˬ70BKiOWe+ TUSГcBUx┵`S$$9SnIJ c {#yvb ^֬P(aCDFկgT1^$ IDATr (@TDWc{ UTTTTTTTT Κ(VN7ױSk\(֜E֍`Xò=JEaad"c-3DT(/(P&F6`* HQ@`J6B4* '2afd4dВdm 2Dʎ! ڈODEZ.'WQA;AWuB2Tz9B) UG:u9dBVe)ul^J2Rf"CGʂcVUP07n%Oʘ7G'0 K X|EEEEEEEEeyaQAybIvr|Yx"t< ĵIVؘl D^>_Ә$kV @Qu 5egzQ6jJp jF%JBިQv-qaBKX/֯)u23!f;':^ȣwnAIHK/"nDQg#YWKey'D%.-' Ȁ6:Q5 P>cO+^n/я\wV_9ִ;o.a .#u “ ɾqeCNjcCcvI$"\v-PQQQQ)JW<=a?Nh8<q>^OmK(56`qs :V/mKkʕqj'׶{~S9N38 0 ]a'l޲I 1|G9w^Q^Zee7M;~LCLJǯڑO߿3[k^T򽢢ESZ7&O,=SYGXeHMF5EMz\1(l<  (`N˾kkqa̱(NPr>J , qёZvsNim#f> ( 9p'5M؜4M08*EnpB0s'.7|b9z=ވW$!wWWW'&&DTJ?>>2cLEes1+YJ7cYe7&ÔOf58z @֓`t|<@X!ˣ0 &ULhWIH(3N BqC6( CzsG #"=X _ J|M+~ &[`G:0Ck?𘪿ap8********/,"dzƘk!z|^wє]JG+?*6(e.'ڍ!cYf=&X0륨kjQdʾFYԈHUꑾ9|D6jl\QB&@G:E9$i{$IV+_NNNfYVO $y̆%wO][N&uhtHl:C&gx'2fCP/_D;*{\5@U!PPX%1*;twTL:mb;$jǡ $(1 TQc{남C<_眻{oqq=eү_&ql'C$,J-aozˡGt2c=/Ay0c1 1c1 1c1N c1c1c1'x1cqg1cqg1c>EѮ]^״m6rqp1n7MS)Y/z=+0,yw0cqgp8t]7/˗\r֭[}};Pf1j~+`ַ֚izȑ/~8o0 Y1cqgk.첥"K_׿|;ox.2V%PJc0cqg1"p7A066~4Vz;wn޼yii+'>l61Ƽ//d>O}S'|_}XҵDZR(R]Wx(8Ac:TvT*_~] x^juz_?֯~] ࢋ.曳,V7&=c1'xvzֳ?я.ݻj[n0LNN>OСCe:?묳Fr ={r)V}.n- CezF4MӴ( ugggGFF z^P hnn'y^Q8f1'xvs]w8a|:t(w7m۶{7iͽ=yK_JDexEe;wV_[F1c?gOy[gS1Mp|1`0P夔RE,繜c18c͠ZJ)u9v7c1'x#NCDEQT*J: |oIb1MI(ͦ6㲡}8j~0,Zc18GYYYk1Q "u[VA`ֺ[1c<{4y^T*En;4O+ 1c<{y`+Ϥij)$дe{1'5  $P1=x(pc0~Ygc| bcL#$Ya?֢ܟs<$Y^ks-S^rC$4~W!:-qZ~ٝD^5ϬdC6 *$0<%ǠP-/VN+V[ FxcԻ=OШV<ǛްY3l hG#Cf6.! `\I!`.4 D7ՊJ3וGBVN;c1N;%=7˕ou:~O6oL'FeWB!|<`r/hnH"ID [#cRр0q1JE03=?55g %a'}G YΒ1|V6|MC^,6h߽e^7U M,'x4-['̋X0 y\{8W:u(PwPR# C+VF1'Փtyҁ $Ŷg="JeYEQxC0YiEQiJ, )|H@ϯFYхtz u P@Ths aE@Q$dN#B3 SSh/ [#5y.@X"DZ뺮 cO_3ꬊT@ O:$JdX$'x{9Dy^dà2OL͑h8Ȣj0 =;$@mpBwĨ5*RG\aY*NŏRd[<QT^uP>ah+Em4QhۍF cU_X ZN-|!+!1~ ({0*J%I8NZVg1PxA4zc\g w~fV:ʔn"*h-*SdsYv`cu<- 35t a8=bÆQk!PFVŻ105X呞iՐBB1~kxmZ6 ,u]@ݮU+>8X [' }R)A]˖KDXB*+r@> 9DRYY6&h&M*#4\ @ Qx2t7-fiхZ{755UI1o ^,ZX m\+ , Kʐx:ㆲE0 $ ðZ4V+Xj'Ñ BlNN5izT۝n̄eR'kAd)B8%k˜enp=D Z0{wJtS CX/~x^9jRJމ1'O IDAT7 ~u !BU4ZSU-쥼aXZZi&aN6՜saN7S5 LH;*@Z2X6( @ ?L.:9\U.|[ [>sq+ˋfu)Zt =7ڬR1Bzyy2{<%2!}$ @̀Vf a4\Jdl7XkGFFxGD&``cJw^]NoNw B E>"x BxEQdbeH=RhW^UC`0dQVXTVP2$AN3qºpd'n 'Ʀg撴nk~ FxwsϺ MgOn4/g'lҩ "'WkރfyYwygȱ( 7w83oc-7߷}Ԓq\*LY9U("qy.h4,   ul+n+Q (pRmEؘI :͋ttֈ5Kd:.wyY:z`j4O8raoJlV| OaVfc<cFDd(p({Y=Zl0 tn#fEfE  /Y=Wjӗ_9 #պ KkUk<@ZXҚ(FY=hTxn%gJFUjBP0yT΅tBPuJ##8_)͊n?::wpja$ ֏:sOm߾=ҹ1"ϊ=O^XaPMsd~j?/ v}ȅ54>6joҗ:z k\/_~s=PPv|WӬVK^k.hLժ[O"Mc(sڝ~*)(s]_+3(‚17=,T8A璱*(3panSUwǝ3$ެkI+ PE{y4p3W=hur _П Q1 B xSޖs'[k˧xscͱ %@5Z峡rQ8-KI7@@lh7w%Jv7G,_=[sqyAŅbʪjm8Ҏ28Tl-Bxyn(eZgnnyu |>N04A<=q۞xkcBN3ӻݠRiQis)9Gy!o\[wvcQ z[O~ۏu)s-dXFm8?NLlLmTO L-3[0 mȔ[ߒp#,9fU,voi᠟,;a i Y&ht5jnnwZbIjk`R k8paE3l&Y7cao :\JZҠeثzK[t6 +'WǁYeŚ~6AAcd [t{ ͺwxR3c~@8|:p3H O: B"h@1Aʯ InD!Zsp#4$3 'p{p!HU4! XjEbSe U;o;x>מɉV^T;~zχ>6.u眷-v>p8e'ͧz.:֜O_ԛ;>7h|:Bjj~#^Ė;{OyۮzKfvzx//?b{ ٯ7o-%d\~p?8xO>^zv5:82 yCꦛPsfz~ _t/h=gAL_Zȇ>TEnX?Xu22Q :$-r=Kdj\̎ZQ^T!^ vlK3|ajbjvNz_N,`55u{K ƫrz&gOD˪6 w`W%c)9c,G!Hh@@("P2S,B 팦nX@%?a%̝.2KUa_i mw}뛷q;B'''2Vx#놱woy v}&jZRoxFN?_^_~cSN|fw󝟪UM|{x_{*\?شqQV[Зk|=?sY/xa2WpYgM¬_}u۟{g^go~֫z[ _⤓OL6>'_g菾?{R'w^{W g=}黶MLT=xuo}_{[#sBhXkrv_.)xNPm4N82ә|{6x 2[{np "a<&jOg:HgǠSϓSEǣa1v'x Z2#!! VLW^;.(fU+@y/<Dz2(Z/}BGkmzMǃ$v'67~\wix{NٱutbR&Tl׿,;'EY9ӿy- _ff'~V}_.|#/CޭᓟͰM/&w3vnZ%H.towMQkvGp|sdΨJ0tSN;9g[dN3g _rᗮ/=9nxy{0:2򶷾yfhb_~t˝W}i<3&6񲷼[~?s?w/f#0H吚(|fbp-~.prK>Ԧ~A0.X4i;5f=~9ě_u7- A _ A8~klLQbky3;`BYVU "0=! e%1͚_xkb-dHvՊOaQKKi)~;w{]PBtzLLēZyZ g뵱F6W}doÑY,,.FEugu'49hwgC8abf{zGZ6a&&w,/* 97oݰ斎[af3զm`?'!b%yR&1vd JsFhwA~rݙ/L%@<@Q(\)oڴ[Rl޺'1HRB>b5qd뉵;\B4HX);16-Â\LNWɼNXN6O( X1&ݧq @j95hY΃eC n@a >q#fERjʳǫ@:Jt]m\c,'#&!- X!,\cc0 EB,#_~uՉ>oxG755sxEƦ]ӟW~rb-GKN; r׎'>-V'wt穲-mS`Tfn?j;ם}Ξ}+:dzqRZ#78{knrrw:>mŅC_x+~&IC!﫿}*xť;r{"Uk7\: 95p0 2a?Ra:2{@k]E<+,3k^'RAeJ&^ى^+_muk0 ,+yˈOD-Yn2qr5)eAq#PZ8'A$6ddzL5Z  k 1$9?Bck|#(QP)\1"߀%:(*'G2c?xl3pI֜W_d3w@|C$vyN hM,p)L CFu @j8vl: _/C>_qROdat %"ZZ:{FZ(l9Zk<*pe #c7lprfm<vwxi;' xggq>|Ƈbj~ .i$o3Ә[['OV9?}[ߙ}wM[>_p*>'~'HK[Ǧs_pU_1FJ4Xo$elz/['e.pRZkAB^:`dz,֮okz-nh$IVZ}7bP!Z?ָ?2}Z t\z' )Zx{4(gZd^YI7(?6Z ,4 *7@@Nd~Nc~N3Y<<R+ >pɐܑګ_%UgHEߓ0 5i!+u;J#AJJa)P*D=!F,t /h_0TȪ.`,B<o n(]W:7\ #O ww9n^2/UFeL<691ώL4!TBV (N{5p8<=j}ȁ͛7VUլE&H, X2 4 ZC@Z{%W|.rW 'xuYBWt/~OR\-)yy^y-Zc1U.eYN0,/ʯ)λ!`!m. ~V lyH/XȒ;7pNFP_Z=cQ<#c{ hMsrRC$  J $5AЄJ V%i Y ke!VZ#ճ,'tUX%5V5.03m- HrAu9S%i֡u]υX!a %[éY}QG4Bwi0sI).fO=iaaIazdjOA''fuv:a:2B =ɽJU=rMI{AiԪ&aon9>=s]guϝמ9ifvݛ޲i|f^csbZؓDm}&l;6?F4@cJԡKYP5kf@S FVKhhVeE{3N滞;+a+:2޲uG*RzZFDeCrl6Wp8#UBSQR{4-գ(*t[+,<5'IRVtZy^W R NZY+(y0,`0(ߢNv IDAT#8V ZҨ"-`L-2wC2V;AX8u:Ll^?p~F,4lҐVZhǥw8BM+ծ)6xcCrs4Achr@ Kd_mҖm09: eɬ%YfA˧sKuN 0dCd!{oT FyBIctkn]j J4ɒ@ H tݙ5rx##n^qܺciFp\T膭 ^w|WZ릦yn7ly^M'R% T8U".Y\h؁ʒxk0;V!G,iQ ܸ;jIzD\%p(|)DD_1@[0/#D5$ Q:LOO_zk' SOMWթsjꜽoZkNXm,R:lfqEk5)Ql'Q4JL1,˔RD8mkՏ 2ĔTB$Ib۶eYa>5!C있 q\* )El6Mu]C7 i~LmF8H oHEaY&( SPv!ƵtLݐD|RšzsEJO>= Ԟ86,q )ɝP$_ڿ[ASŐ10%J(Qao] H@si!!*6iTҊi46g E S'hb@Y .4j6cPs[io`,׆*4=sñZ]+"S8ͤ9̗W6 MݵAo5^-VSqH@M1Z6-l5y幘߿@#w̬,zQbO'y;̓ـ`-7 ),y SW~X MNR4WJ4z -[68Zu Vxpo; Π燾cdSy$ewЍ'&6YSBBZU\ghiLLuJ)뵱ZGIMl_a%X1x d6K|LFNv6_9V\>c[Om{8 >4[x(9 BfckѝP߂'gؖU @4 J(Q[n4 @ra˖6\mK [ R#SHH*Gi R_rŹ\xt\+0UsCcT"'.`#,Ǔ I}!@ATdAau2t']%TP(/<RbQ I;U[q-ru㬣yTAj2mv-~MҰ2 2;cz۶ D^ 2Y-'Ts'Qv7WTaIf3p B3˼^MԯR3ϯJrIBI )U n[ fy"f+ b s^PZ9g&i! ^ݏoO߾}O~8?|BbvFn^$(8G$U1=V*K/tiiiyy_+^6,ֶm#81cَqm6MSG ͳy^Yy1erSt:^yhkXRfgl~Z58hJ`1&44fvx!j/8vv_r%'pBEZjٟٸh EGŴb倝 .œ**)?`| __(Y߽yL4֏Yƈa,Z |S.gTKm:#stS Ҋ:pZD%J8 jJ;.lިv$|˭eba1.qKDɠ2T3fq׵,^Z:5^kkdZZK)ϤU8lP0ETz~$'6MKP.a}6M' R5g\WxֈIWvk(`zv$wȯyvh"RwZ7dl=J}0BH"H+f&Cuם T 1?عu:۠Vk6 Ԇn{fi{x;~8S,ZZZzްk׮??سg۷};ӞԧxwU*۷{ "(:1_T*Fc׮]W_}qw%[l[or0Ї>tgqOyS?-[\qs1I's9'|.4r['I繑 ih4Fe]uU;v[n?n{ꩧ| _xGuY~ѷZE6mڵku]g۶Q̬U*8 . "Ge/{ٶm4KA8cYVZ/~`ioYu{ݑGID~0v#NZ!.R7dkB7E~Jo'׭nOzw;؞'c(NJPP^i)ENPwܕvowJX$_L!E 17.6`K(QDÃ+bJ(u2C/EWJaXoQ_W_xų{箻ky7Zap]wmmm0:-2 4ՏؘmEQO~򓫫emݺ6m27/;}_<ΞJ388sϭz76,^_pf7m,_<0==G?f$%\yfIj5d8gg\ś&''F177'ܶmM7i;/OO[yAضm2h+T[smfGEB⇃BYtgAsq䣞?)w`!pL@>T*)Ÿ"RJ1hA 4J{+b%J(g4 UIp&$ЎKp$ Sxn98<2^S)*>| q\9CAiAjxIj`Im1H\Aye;~[? <MEotue5Ϯ>\/glݲYH]m۝|fIv{:psy$7kǗSx+'_g{Zݾa2vC q٬`ffjE,;7{ff&s9ꨣ(l6iZI{glfƂ& 0 oS')8pB؉'hhmneYyOMMEzlllqqNx' 5j /|ӛޔeQG{>v|W_}UW޽})={l߾=9۶8<$In߾lyqm۶v]Tl>#9rKz7t:-[q< Rfoivy5M"^[[3 A^oڴ)˲ZV8'?֦̔<}'BSbuNO%w'";[BP60(/› K hۂbS"@xL+̩Q̌h*^D%J ^t!tfOSSsv_2BT@+@ `Zs&?` I֒l4Ki)L @&i  RkZЦL5Bm} n-{rv7Ղ 5t 1 _w9.?7_I'.(ͪձ4cZ/ VOHn۶}{UW]UVWWW'&& Ϟ<99ib,Y\\ݻ״lNOO{vI"2Mq;u믿/~q^_ZZںu}wG'I9OԶɻ|q;v$In߾}wqivqEQtxEy&Eak1)Oy x|vvvrrP(w/PƯxb[곟?')dzq&Xʬ*qBp9]v٥^-oyKZ;;O:߽7 oxfff0ڵ0͛7?Yzk_{|Q5͍BEݻ?}{߻馛R6m:cqJ3g0n!D}$uwݱ1CU򕯜z'|G?Q)gi:G+aQ !86Jj?SN9RdW?,-s3iv`b]we+9=v*%tcMKKIGE( z'~2x!Ĺ'?c9F)5;;Wc/o~ۉϿˌbV[\\4->ϼow}ر/x ^cb϶m+>|BڵYzw;v%\r|󟟘8Ӯ:Ȟ1q7!J09@~߶텅 ..ۏ=o~JIJz2/ebbwqAܹ/|*[NcvF|s{O: WU8>>jo>//z{;쳅&նmE)lmۮV_q7x 4غ`m+b2RȢ>Tʲpl1 M8cX\\4SQ)Zǵu$ILV5]T0fV6dzl6_ڶ4=P ,\ZZ&}wKˇoEVPİɛ6#+0G/; =t4'z(lBd' bUD%JƸǙF̽>P*Ȇ (Ӱ%lb.bϪ 7ZeĕP4|V7|.ֹ>SǛ_i,ML߷^X^WkZkjuhRӳ[WWDkuiێ$W]i9B+)~'icl*'$#7I=t8';F?kVbhFH979h(vFKy& x0Xެ̬J%XZf<^I?}A d?\EC|SFAKMJod4bJAuGsbx#Ck $ _ 6h.n f%*Daǟ<2T!٩6y(-.8#YfqCP"L 9H̠s{ H(궫FZ$j)͌yj}xZZemeٱyo&i?ZTY5=Uݻ+D{W]4=;Vukm;m;+O޵46VԆ4N;ڶm(͵R #6+{('q'i9TVEDf45z` kcnwlw ^??$ @@ iعGȁ m\F . _D% ~}"ŠLbӆPĠRז!L8fuFnj0HP6zZGltJ^]IyumH%rx-*tiZZYVuu~oXZB#3̴T4,2ք" 'gshOEg2&:*soZs"Jdllt>i8NQK !͛wۍy;II@ZAsGͪMhU3M X3x2o\?Fz /{%J8, S0 gJCqFI<4Ć#&  Y`bbdR.= w85ꐘ)E&M/XW'so,K3=NӼZm42[LܲQ Cf[~.6\FѨ,,;;?stNNU B.w9m^O=l^WNkNMHh9j(2j"!U*(v{ԥmֺQJ9dflP#Lev- Hhk`a=j/0ӒmfBԲoxW!k^R?SD%N7M[V hAiƪh]XJ z\KdAr,BRG%.պTΘ" i,,RچfN96I<#88X䦹vO͙msׯdIt^\YZDD3ܽiv.^%ˊFōzwT1kw4&FVWVV\}O0AvƓ.NfYf軩.zZM_. pƘ&V)e|~?zZh,V85o ݩH3@pAN )Ä)ozd a)6,m(&64C ogL'auA>H>Lr  lXn-PwZb BH m8Tj0B!B?"r`|lQU"ɧay"mK(@D&뭬A((Vaj:o:yR  D#@G#mi>Vkh`PL͏}̵-p 4c馩ݹoIGc$HչU)b0XD&wD!z";d }][H``3+Di(S\cRH)C]xG!Y[j-.-ޕM|O}kyQl*Opگݭ“~>`ʶN*Zρ*k%J(Qpc PdP( Ĺ1hԪ"v8H,M644H)i4:ˁn,E) BKm;(a5bv\6sG ehyBSiGS/v CkϠh zM=|dUƠpƑQ4Z 1ej]ν96nyw~5YVj뽧Lm}wե_w~>>7ԟ#ƗZ-q)xuJE:N⨣p[秲b=GuH3B!4q6R eeD%J T #(W dIҐF"hR64F$I4sjf=)(bҊA) -4A1%1P>(aXOX/Q!B}l@H;]B<'Je`α\n5 }K3y%_?yO>|oݽ/Og6NcOWm Bo_{~×>u~aiC6MiWUYkkkZQT[AAposi|c_S0]놧5.ءNֲ_D%Ո8#&E2FfLDLA3 KÆrma;q Wخ]ars%\\)\)l[uf!tfV['و-$!eK=t?Ն38'U!SNC;>8*~Wf3aop8,Lݗ}^{?NqB6f{n2Hv/|}TpVjD?HEc'/[_t֯s㍿}wWa/9 +6J(^ Y(QD?LV'<`B Lӡuqkdz>4b'E빆hRrH+iAC<&i1Fѡe${Ui _!g n!  *d,뜡+mh: VOqTU{ʴ[iOI hN_DXRYxl2x_;t<ŝwu,׀$ 9s%%y/QDйm=qQH3 fI@ \ .%P'5 9R%iƤp AiƈH 4c1pV0#a=q̦D }wפy@~.cX)BI$]jd҃,`p9BϮVSi qOft;oy$&V>$P-{H(MW^+ &._rщΏT. -*^))QD>W]3G$H@ ARBB$5)c `)X  iEbbf4c1M4cɸzXlT}({]o` kk+"+ ;?~Yq/|Xܗ֪O**$Z^tlW3++HcY gy;pn|m?zZe?{wmYUߋ;~(sA1JS{GAHy& KL& rd\:\QcT)9uݮ~6ϮSeEF }{u^9|RcZBy*ϱ6<|]G56aE1Va km1FIa0@or=;Ark1hnz2B֯3g+O.@!Ss*ϋL DQ[~ oy۵:E@H|S݋{>֘1UxO\~?u|s0 (:Ga\lxL]*`ZZl#b|Nzh =5?vMB!Ւmea T@.lleLpH k``-fw7?iGgd,3EtSxͭa0kE(9 Y,0n4faX-VBkf[ˍPr//.Ưt74hW(?sy,f팪o?~ a}IYe3S|v(+8 &D=fO/jm,䅭PEa,˟2=K@XozOx LmQu:`me@&du/P=!d45CYQ'<?/v\ @I50 LF96 sZ|cdsƼk@p pjE#{߹s17X]WJCs6I5 pVsȌe &r&8-C`a[~a>ka$A,8(\YF^ IDAT,J20>ceb|,Tb<۔[c1ʀI0s ;]Edo!h ( X\vNҺ<a{4(F&נ3]X>XFTwI?MGƖaAL?05P`/ LݢfX:>:[qg$SCYq :Z q}U'+B!Z<dY6??...t}7 dxf*`v\VTWSm&l,WVdyRT@ɲdۛk !B,OX<@ZE}x <v2 z ~k'a2!6c/= o4#1@Sxos-)ٮ1+RfYyB!<<)^hcN-,[38YeTEрucL"e\c=,Vg s qjRZ-RJ=O!B }t\Lt:'O0`[Mc0XcXUl؛Z{T1-3OdÂqc*MY16b[gfxB!I@[̬L+ *n0Ϩ86{3I !B%6b 9``(9b=ŧX2;)gаӯn5o5 +ovufH^`0ZNOWH1 턧3,'=Ŵأɍ'I&LљBٶ/&5 n* Y 0XX;?$8,-ToE9ni̠P X4Yl{oBr0VNݪ;[d-e* !Lg\&qjcZS)@Biqn1j){|4N~R9F:s(VGՍX:hBu^WylrV81cm)>UӱO*ø)DUֻ􉦿fZ=Ux5&BLҬI 7߬iדUӿ?9:r,(|\ATa*u_ >_^-UԜφ}6ӀӮև 6ĩfw7vu&эe߻Qڇ7zҫߜBiiSjx>D',6Æ4 |/+K#XlnvlOC&Oذ*[ fìj)@1k&U֍˷;ֆ 6Xn-ޮՔ3X7쮍ϰvL/ 2jџBQHJ#-a`ن`),3|/S2:c/p@z/ l\D:gO+ݝKzyPOKOj20 P |)lk67VM[xπcdVfڻ(8Ciڤc@Uk]N!No 8iR4C{;ZA;+}r2^d;f7zF[ʸiZ QiVU_j;9a緳o ƟaNqɝ1ce2!e :Vc%4K`qpn&=yf .Pi <BcZ7lRJJi|~pd5df}oNިBe,P2T;I-K)$ W,0NQBD-h_Wi;:x̫{XIcY%ʪg-j!FcZ@`2%ê6R[j&c\ö!hrA 5 g'u6wEJd+@<4Mک_H3?rty}x" b3>P9f*JBz5%gE*ZI0f,S5HVgC7C!@jaYۺ(`lB9.6xS +Bxɰ3pmz;+3)/a!9!`e X{e7hܳ/KZQA =-jc Q|;Hrx:L7shm+<XG۾m5AЀa÷B '%ǞfUBȎ~o{?1[=I<J]e^C_޿S4u,..~_.BJ>~߈|cLY z=8yvı]v˲,r<{7]O^oeYp 뿾Zs]wug2333wcF.x[VGeu ^{4ݜCדRc5M5y Rn馗v0x+_}m^/cG6!lo߾|#w7^ZgϞZ6;;v|0L7mnm\~u8t<˲ԝw97771]vG>򑪪=pwwu^uU(\|'ֹꪫ{1vQןO܏yt C!O˕/"YZZڽ{7c <5A033zOϻeY<nfOt]RRJ<Ct% nze)r׮]Zt}&:e)ܿ\gq \s7nj1c5\$It:?>î'Q߷okZc<{]c5\ReYrxv}4M[Vܷo7+quMyK)Z!DuUU5 ׭W^yuWAg}6= !;%xByc:$gffw.p .jiiiffs7ƴh*Uܰ_W BL]q-pEgyTJ})7f|=t_F$." !F[aZk׃s}[__^oϞ=EQc\{PWQsYgo=zRʷ-+++]K/]^^BLgSB\|t]W)t.gYzZȺS!>;2 C7̮]܈:BUU)"7f) IDAT-o1hzBBu LlZ>_^^.oo~ _h??zo|Im7yw5׼oeyY1ƤRJRri~__}s7tS}K.g>d?~.ryyh1"GQ4`e >33W oxÃ> O~z[k]ݼ&c(EQeͪlNwޗrˁ=z;@B BN? /{>O_߿/.jza^uU_~{˓$v@)~6s=\{(2ƌc`0p4oNn-///--]uU裏/ˮEמjfffRnvR37A 77{{u+rz=tJzay{=.~~G~5wv+5{{{ ^Ƽ㏷,8{޽{o8w/ZrQ7mÐs~,,VVVdR2CJFtyO}Sfu{]W^ywWB¦ӃS}NJB'JyUUskv'Lkp38xynMߥn|IF>(wWId>iy*B BtdOȳC@!B%xB!B%xB!B(! B!8RN$Iz!gBȄߪKBh4 M kkki#=!B BMRJcJ(cfZey:\B(BȳU$Ibֺ:N|j4^OANJBȳ !d,˲,6fyizn*VTӱNj%B=Q$O! !;VYBznͲ,yX}Z] G4ٹ9Bx;9ZhUx@H$'2!k 7"(;Mִ[7քA9)@Q1H.5kmh,UӐ UJw(<ι4 *jg'Z>`eUҲ'&x><Os=) !%Yc"y[oMoę_R|YZ0)$*/v~qfU~ޅzU2h4Bz}{:O! !;!e$Z-IzGc`q:-syܘ,Q4'5;w-*w1V &ZB EQ 6 L Tޚ}T(aT*vr5 UT!! 'B rܞcќeJV1}҇u BO9!<K!og1hf՗ ;a[P|'Jӎ 3N{+ M[ 06 B(BN#5XEb` U-`̺ X+B rj-v ɸ`#P4B r:b!<:;#3T*&-jb:96`'? B \K+p\I23ǯL9YgR.,3U, a=]6bn-#s >i'Zfpl@ l6s|(5W̸Spf,ߚtL:rh00k&X,3iGR.,[۶m%+̬Ma[0Y5oXzD~nByϻ ywmP?edRm` I}|7ZY^Y,/+Y)LG#T!F%d{%XLRxV#)tOa ܏a2 de diF9lu$(Is e ܳM.==1SU&Ÿmqdy9J{ʄc!Zi$lxVb8kV(*V(V"UF1 E)y #<.}a)meb0ٶ0 x@MJh!{يO B%xBȿ"g{;dIf;Yրqi #i!`Cks0͑2c5i[DX[1ΙI6=/d}?,re/[eQ7פq?rve`5jZ2J~{a?z3յߗJ)n*gG6vH釢S5e+jIudFl6I&f;=̜i0upTzܘ)J57g3t]T 6#cƮ5TK]tyyinfWLx333f'7I4segi>Jr2C[,6r$!JpcM줫Ĺ{/[\3GjzT LyVF O0{ A dk&^8\UEf$/Kͼhs8BͦeQӮ\-Ri>*rvv.η7}g]0q."kN1lfY}_ Tp]gCβ^ltWև{^ q- 7J:2v,`e3mųz<^$\Ǿ3wc^ku jćai593~?WZ87:ˊUX=/b.-vgQ@J7.L2&9837UQzB%xBsއu[Kv~b̧hu}59h@JhZ $ n ؘA @p΍`(*fM a7+y5LVVr;\p:QYʦ\^|=*-<.eJY&uw~eJAy*Xd\ 588I^#n6<7Pu֋~[Z75 .^])_?\i-_ϯ5P ~wŋW8WUwaj8,uey,Jvi!Cҕ\]]m7E27xD\U !F2}X결,W!P' s'Zpp!h`yiQ0h*O4JH!Jn9L0Q(]A( |46YsmU75ad9C9?UUUd!76p<8s_Z?m-,n6zIVV /f'V$͸` <(lEJٍ"Ծ:08rڵr1 Z5evfg6c: c \=IUS a!0Pq 3OT"Sކfr&^9 YZ>Z>^x+_přcfvoa8k~b .E]t;ꓟ1ˮśez\W^-{^2/#o/~'?}Q;ny_3x#4~OO,]9#;oGs_̟Vn~K~H,{o͟ᢗX|/\MREQ : _+G{9ڋ_vչ147xc淖n/G~?ug[FP(VTOkB(BvFIrwk`!x&Z7n8a[mHa[.Q|D $cLOeQ@BD.n@ 2LOKm<?jo-]szLxGnwL| [q\1m;j!lBÛx#æ_xx,[|>+?zQ[w_5׮[y7|O8cu_+O]H$`®5|Z4?ɿ,ؿ !S{_7/yIqʎ{l;C?`:ò{ mdA1 ! P j 7-KADpfm`Fw~7ozz>X=Ugt* 6sIy͈LˏiW0ù-_4\p9雡6}K^1]?>+x7>n靕J) Ʒ^|ӛ/ΏMn~ |+ͼ]:pݶ;!Jb+lc IGua2]oHf5fͪsu֠Y>3EottڱL}W⦛.Z|vVUf5 ]|x^p$we^Wǃ>3sxg dnd B r`iBp@0d?3I C_^x JmA]d[<ݫ={=}Ʋks%PRӴ|xrϮٙ6Vꪖ QԘiԼ@߲e\ƅ(F2Hb ͎/䬗;n9$gp0Kǯں4L GLǭY<&$;pWE hP* ɱ.]OIDk2sakgk=Pرm1Oi5P,9vnߓ-zB^h3aK |;y _g:^ AcO9TUjF nڙ(na Ӥ?BO9c춯뻆1d$'{sͦu'<ȃ~`^|.8bcoӝ ꣏ә,8NCzG?;#/<ᘣRsN9~[gwcٙX.88(1&-J! !@|\\[n".ˁ@ + <z!?85 * %̮LȒ7lw ^3͓ IDATskyb4mpj+XRyϷ{[6Ч'}oW>l?=~|];p~yUH/Wy*zW9#65?/8|[vjo~0' q [sk]5R1U-[O9jұfZ4v9|% VV;ȣN6D3>84Skz}ڵ}*N~^Z~owzzo9G볊I˔o{ދkʗ̕/ִnkQ44]1ʮ?Mr@3ƔRJ)qk&&3W&`L hH|:tw?Dl%m!RhX/sI;#~5y")x!)uq]d;UXvDuGKV_Wݶuw_LN;dr2xmiÞBov`0tvچ}p锬[j]'^9qx[w#.{heߞA;أ6 n/]2육k?+O{tjGqz70<^j?/}w<Ϧ@q97mZ51YaLL'[e aK_RP(ڮhv>)N wLܹA,_2 eIΥ'nn6kKuu8jh Ŕ>ae.Bq1=[)~.B GLr>c! `@Ŵ|݉%cMY:†i.'f~K>k_{c?c:3RLXӌз ҭ$-갬L.M3䋙Ќzmzdl :2I| ' RI,WJQtwwB$ f'׮Y9:>"Q,PٕJyKQRS*1f1TJ&gU\1t6ۘL tGatH拥O 3j6`q͌XBzm䫺ɰ=l`r˖REGm P잞+FTxf0Bd Kk48g-Ѕy&v;(A[Q(aZ-δU)J:;Jq `%Kv'`L!a`5ˆlCqbqd̬^8J2G 3 #["t;qrOi1k5'*rXۭ FѕBG~v om`Ɍຑٻ=5z[?X.-әf\*=0ivF\ʴթ+J74'F\z Z3 QW\u|/0FN-%Hzzm[Zdel׌ WVT|Ɗe2&&d4׳*ծb.w\.\6LFA P Hia'8g\|w2uwzGB OΏs\50 ! ;&uW"ZOLPbVfb"+źbyJ3hfi\)".KlllPmy2mh4Lfs/ƚ{ҞmOwXJu\Cefw{w-_Omv`a2;nu2A0e7S#yqV.f>8355Ņb/lw'l0m\.7"oEImjRۅQ]>1Z\mh<#)%d8 ˥hmqY'S*fff4 ynQTT4lTY$}J#I0(H$BIQ% !U%ϣB,30ڮ0B֧'MۚL٬.#gQ4P XlٚNr)pTԀezZ>oH6^ .I"ٚtJP=:qPUyFZПXPn^Se][̨;`*)BJ.g([REmrV3tDĝטa[dqB'fymap0bZ$4tڝ8oV`0+M(息,Ia+0B 0 "M҂-ڎL0 l;\lLXb|yȒ|Ɇ0F>a9mCYنo7K3Z+W*̂bZ!_1v$R\>-4'fQXhLN,_b˖-evwWXz^yed3]Ip&Y3k5ZC+x⁁Ctf]M3Ni7 `[*rhH`i~I.Wsa_kt-!g*tu9fܱZ}rhpYެk(tjnOw.[0Ȟ5vӲ2bhNyn=_SIr<;N!Y3DSM/WcO̶J!xَFFGE$zkxj z{f޶ .g:p ۉaZn뮽RwXi 32nfXO|>l)F/BOȡ٢9!$#?zJldҫr;!X>x7h/iy M%۴ m(8bhّU:׷i>[oZ驆 ݪ1S$r LVvЊZB ;[ADr{fgk^ж6$@SPq ɕc5i5gϯ[Cl͝*HٳͤD%ߌ,]u3\)aQÁ^FO@B! !G` ]4rl0VSn:C.H aHxiS!MLЀLNF'Gumݏo;=^r΋mr&W@]wmpuǏ> /}ͦ 2W\O੭i׼oߴwםo-w3;W<|^ohM7]LOq {Jupx5(n-/dbr&k O!>5|UO=sd~5\xg>2;vpppG~tb0 箹ډY\|_??P۹z;Xw_뿾/\;v\>gk'͖O!wϗɧU^s:^pKμS?y[jGlX+=7_}7ttdĨd` Chh7#Ϡ\,3yѡ~D~8xqBO|ן%iyzI Qg  4(Kp:SLh94:QٺdW\g.cݝ~kwcR1LSVݳ@WfV}/{KGծrcuos ׏q+[#<-lV{2-ڵ_uh{5WҗNTA;M08`qe5g{MOzz^* q,aJq"Σ0|!?ڌC?k^O{/!4944%-bG$P`Jq)LI'>T>kǔ`Y,i=bp>ı`n5kSWvX6`<5Ɠ{]swk^ly]DT˕ fK;]q/-7>m.f ' :WȞs: YS ֜Ew9eX&W !P C[9z.bV_OX(C"R DW Czd$ymw}#бnغ9 S#f*u}otq]W'Ggp٪(F M]so3'r1 7 }D/e;yKNYjÙ?y][67yםCOnF^XqZz"9hƛ\)_ " BcL)DZiRJΩ6OFAJ$81tsԨkg6%8B)D߸0F=CXDYwĚ'hyٻǷl1ǔizmbhLΙ8vO=kt%{vQGQ*NPZ. M_~]/(&=eY=|͏T3JE^քn~b0P+W]o'2ʴ-w4{m6п^ێ,' jG]Yz>03R'Xsf8PL} -9hpґ1@)~.򧆞R䢌:Shn&x8g8ǐb.3m>Ml#ILCs[3j.IG~/%$,2&v9$T0fcFf!ض﹦i=OyL͌/[qƋz{O/V* Q+cŪ-;V6|SOZGceܟw $|¶5VGmx,( !vA. PǦ2,ai W .yqnO@kD,`!X$-P\$"3#ڝcw`-=V*IC컓c|fdx@`BeiPlw תz*]S;3cxí_p@Arj|q,%nkja4b<7 O0>YIi\ByS{l>tr^gԕU}vIdhq=!AP !ܲ1% -`1Їaf0=-!*FWWoҞ;ߘŮ@j›PR.s34u8N| PH$WK!$%@H2H#&ž"`\ǾҠ0xUŎ?q)5K@-,Z~M⨋II!xJ>VC뵳f&`H34p z{jA)hRem&\m-,XRR R @*@PW2?GI-j)| s`o\Vv&ܧy⾣ͱKu !P'PҀWkV۫4ɣhx0083Y(=0(#]uްxq}+Ffr"h4Pf E1B! !Z|~Jfz\'DZA[5[ `vM;h&]ђ& M:5wm;-hs$@ڠ !J3m8nV să\ fƶ0 d@X&M&|la)E uf84.**BOȡ%(a(Gq.p@6QϢnޚrYL!TmR4f?#o!B C;s_DVQd,[>RݘNT" ahfGq*2đƸvs&R{]Tue\y]ׄLϔ8dB! 9$|_ L3yUT/d]Y gWNܓ˄,C_ONNZSLg;gpP\ #nJ PjnB!KBHjj!b Wap X(@pfHb 0t\1M%TK;&Jb߶-K/5 !B C[ӹ`8dd}6292x h1琀B3$LI07,t]X +pN!P'9ssI}ھ"|rK D,) ibxB!틧Y !.%PǞu(@wdr0RFS` Lq&l_|_xRiLqZưShH?&%;r3\~sUc`jsO*&Q2<G3gZ8@q00#0SX8JHNʢE?!BO#?̏ [wWL'|晒9|B<.m !\. N4L^*@"-CPR b 1VpLsq|_ O4B rfa 5JhXmq)Vl(M\0fd8}T f[" `\BBC! !80fayEQk:L!/$l9 lyF>wW8+;DCF8FY !ƁwB%xB¡iLB8בOXdn1pqPd쬂y k0w+ !?!?2hB!JB!JB!JB!P'B!P'B!P'B!pEa*$7^,TA,Rjᖦ], {_W{I)3 nf(RJ)uꩧ2L4-ϿUzы^tm޴iӗ;vAѠ1!vm۶R*ydLӜxF>w޻/>$}qRdYVVU(iLO!?я{g׬YcYƍ/:WNK@P(r-'x ~_]vejϷmB0FRJ4wuq۶8.J>h~!D64׾v':s1Ǵkfpppʕ_hnݺgqivQG=csyi4Ͳ(<3 @ZmŊMOO_uU~zZ=?FQdf^_~>6lx^v=mr| '|l6Mai^?{{{7mtڵӟivg/41 R?=!,SJEQ׬YS(.&''LO!'xb˖-z׻8Lێ(9sӟtϞ=|;$Inݺ뮻޼ygq饗>;wn]}P(0ƒ$)r4W◿e$J%Ƙv{pp}>zzzzڵ'|r۶m'>q饗wݯ{0zץBL&c ˲<PT暩믿o뮻}{vۖ-[^]y啙L&s=4͇~zGӏ#c7 !%\iڮ]vi{ oo}[<Ȇ ȲjAii( Bڍ3000::^FVApyuww3rIgi[GB^̅JԽ8tOno7oޜFGGo~iqZzM7ݔzðjMOO lݺ5VAN:`zfPJ}Mv^~?8Ij38O[tn60Bުfgg{{{ZqR~87Zߟf<-oyߥeGB<#/lE07n۔R۷og Aڽ{듓֭?4J: ʕ+lT/~q'ziƍرC)TJH\ > !~lٽ{w.qM\׵m{||r9VO,kxxxŊ祥t˲Ҵz +fqnBaAeY|<,✧oۙLP((8bqddBUYhCOlֶ^J900`fG V^׾/n6Bj]pۯ|w8333p]Nh6ib裏.I4l6jR###LzXZfi==Hs. p/{rvߟd2[EёG~P(6B, !iӦ+Wu]sL9lV)uGj4+V\.8NR,k˖-Ad2 $I$i(8|zym? _0 ٰa}79-Nسgϲe˒$)馎 Jj}}}^訔2 i C p||#_|yv500`jj{'{'x"-OMM"Bf~4niwRe]scT*x衇l$v;˹kfzߦǭ.< s/_T*ݻ۸q#͛7J8ӍY܆B O!$I}cfff(zGַ>uY]tQ:{K.$]8f0<#N9唋/}0fggyzLgǺg24v:V{/Gꪫ,jZ+VxMz_(-[Emۚu:FqZVTwNGӴ8?߱cmݶlٲtt 4M\jqO}*>W*t]RQ?.zӛ !<׿Vփ H̕lۖRFQٻh[ϺN<3wMrdDh%R8kKe[8tI*V.))U؅R b!Ҡ(`0!$$qxܓ^@n:>=;|o#l6'湹NW"{禛nl=QcO#DDѿ]ETȇ1<8=mڀx8O?[EE'nwvvr{}m4UUn>}}_[.=c~q<`EsW?̇1'{_q} L?(]k8]t|!c)ALHj4!V|.҇~<ϫx<7(e$I|ߠl_*u8j$I~}}ݗ}˴HTeǃ MS>=iN&ӻo}p8;;wVy>}a4( _ ' C1ccyMՓɤ*}i0O>{"I|Y1fZ&"“$VkuT>[5t(t¾ OcnwEh4|'t0vcyy3YAiW vVck4Xz^^G|<P%afs4Ɔ?Bv폃']4#a+ܻ꾸OGm?ﳩҷ`'0 y>OgWZ}} l"PRJ_HʲVLvzK|;PUU+?Eg}~-4t'}~IZKDDznSOR>~5 h'x4$}gN?O.(mZWͧ4 | sO/dY&9|G4{ -hmmmee-g&4}/>o| Z-\>z`0S&ˀ/'qCQyy/n4% <c_ >J8?!&N,il":hۏ;˲,`Z1p1fvvVk'Lw5sbzxӬ?nH)5GTʲL|e~?EQ|Վ?>7L&Zk8\b93N1v %xO1>OE°ʝ`:;eZQvLM?L{ZwFmL Ƙ,$gYoOK)UhEѴ/2n9wx}wcz?1H?_]%wqA <cJgqg)x!`1c1cqg1cqg1c<c183c183c1 cyZ,x/y.ZH*/_0ad1 1ƾDRafYVRjvvVWWa"Z\\$"!M0 04Xk#cgYJ@  9Fc_TcyUUukB)/ ,Qq< Z`0pt:Z0 <&c/3._>Y $Izy'Ijup9;gR183ؗV$v4eY6L00L| ---/?Lsac1N1ŵ04Z !ͦs^k6uEι O?Zy^wcqg/4Mf4V眵v2Xk(B)EDAH)qGQ3t$c1 1ƾ|2Fqo }{^A(cqg/$Iֺj={R,{Ec1N1(9o}<Zx2kٴr;c1N1ooo.(_yF镌1'x{jƘy!ֺV884M>a183Sϟ : (<ҫ2 IDATGZaH2c_zDD9zB1v *KD] k*JX8!hZ3cc$I 5A{q<ǡWrTD&DVԊka汌vM;l c] @ Yc{设x+ e-H*@HwA #uF*GFg֕ DA($dei(Hñj9׻AU2z}ϭg$nΎG=&ןZ/,t33?xOF.Io+r~ç/)zГ M%YcN*CI^dH,iaΞ><µJqZXgghg#Y~25hc}~ awۘ.'jٻ`hi,!&at& h ʐt$e@-J2f 7EGuW`}(fZ3MKeoa)O-Yӟ{(=}W7ß sk3Zv#筓R8ΜZX<i ZDjs$gBRj"(X&!byjQzv]k'qH&hєM*[zNsUUքm[TvFp 1v@J{qq%l- A( r‘ h,V$$+Xm*H$Nqsfج ]٭ BTqԛɰFIDRfZkΗoeY;Cn摝ѵWf3jʰ9WR'RU%lmg+++07UoMt!J^Vjčf [_.I*։#YV$֢Е B183Ʈm:,`uin?s 2Y NXWj`ǐ&qM.E9RbՍ|˾9G.-"C(ZI5wgA]Ꮪϧ:xkxC.*2%[o綇<{;,&k_:vL=x 3 UR#z7,w~_} >:;Bӛo?n'tAʵw'q~g1N1N>M껆s@  Dː~9^-)-Y"p学PC g$D@"6hS g?~=?ϴyw7ݲZ@QU?`y /n{ ' ZVVm^qw_xɳn[y[~uB=g VrrOݿ8o\]9rUo_~wG#ǒ?|W߉0kw||}o|o:/~3kۋȇ?~^'|^™g ++0[m-2'xصtژ8C(,!&% دGFUP#"'^cY)Y&q; ?<\م۟w}RNs?y߻u|mxՖ (εx0 bPwvvsx7^w 7 k^OϷvkkyJknI&d8zW2bg4kӟ/O[|nn}wӽxÿ΢g-}#|ɓIJ4wy೧>GUDhm0߆ҩiLݳQkn?oG?gxoߟ÷=7jLFM@F[Aӏ>4 U,|b8={r7Ͽџɻ/3gh4h2"\D:@^ozz=WZŒ9}s|͕)&FLS'Cɓ7ݸl><+cqgX^ b t{b=> Q `?2dnBUA(K2lk8Ivw|K^Ui:TJ>$Or\>w~nhףͺQTR4RSGH&^_eY`Ժ;Μىzu=*Zm,5zQU[v\/{/B0O~-:z׿,jruusW/>)y73F{" lm3c،wمH%E> -2:#nwjc183ƮqvT*A ($(ø P J@=1 NLP {q=ŢҝJDg0Mq}TITXV`\v {xQM@:Z8Rs'_ 2>[NC!m[\X8g_x),{U? Qݹ"uE7qb;!wxç[٤F#8qPYhQڍxgљkť&PIl[zzT'l(mHI𙬌1 1v-# gqxB[4 mfb 'a\5 rfx 8+n-VET@3iPc]Vai]G]2jZ^ ,@z+xrӵF{qvI;#&i8\T<VVp4>x~mk2XO>G??33M'_[;.J6ihFOf F{Ni P Z:t;H?'?q Npsj83Xh4ZT #(Hǣvh,EqRR5ֺJPE$,B[cvot! UF"DĔEu{dCNcI [PU9k%HRt8dZG@P Hg`E,^o0Uf[p<. Х:Nj8V,uBت'HB8X;} dVgFNlY%g:xkKei;y8*HGYtj]*=3jePZ= ,'QԒdB3uܬp 183UÉYTXїȬYiDA{nf#F+]ں 7v6YfG|PvjX#-̬ V֙Vx0 HP(6zxuu:ˆzRVyULPXk,H eId()H9Ii2%aQ{_g? gұDd(HRA8fȪ4֩Wee1N1}]I N4&dlMTE4 O }2@Ð UAZflbK-UogQrHkQfpր $5;EcG9Hʼn2,Bkk,/[[[\XYklm[z=YZ?\PJ$8Xҏ{d kX$o9 >f̅Z%Lϸ}cqg]7@Z 8"( 8eV9Pﲹ`ApѕFxh~R ұjD(h%vwc(rdդl E>l z33UըAE;ݝ(hլ//.fREijōdckImf9gέ/agv]%Bcqg]]|MGR# `,UaGRUqH+*+“&)Ic@]bL44ZueuKgZfe7rⓟ~`av!I\)Nzr|xGGy9Ѐ Vk l3]XXHd0%.-/{;#yi!cc[;@}Ma X;Tq+4ctčSf8Gn H ~0ՒFVt4TÁgV ?ӛ}͡~Z,Z)@?߳oVޜ9]h{VچPoeYicO 3Ʈi wX@]Xs|',Uvt4ABP/bԃ.ct"r][8{DN{dp]sqhb0O>| ?o8~C\w~wg߫%M~t0.ؓzpup@o@#`xmJl:ؖdn[OƓC$ 4ZpK@늚qivv8?m;goIBo}R[g[Ǐs8zC/'nOuoo=zqjG}Tk!?c=% _;NHJep(! "KdaVP@~mmp$r [(\%Z͔[E,&eC%I(;cePZZۂgLU?$ΞÛFqѷ|_/˲ Zloom"yn4MgIccWY+9mW Dp ww F5i%{ŭ!i(),Q@D(˼,IiSV%24m4Py:nHVt_ ;ۭǏwyaADr8hk6gy jOaUFJq1'xU}^8[@xop <`A( Ep^q JX!M$*LGɲHBF;Im]X4g77ѨK3vR)[aXfӮ$ӓv=JnCkg=~x=ul;nc=1v ەq IDATH.̇ e/ېlhH&'ȑ@餀NI: kᖂ 0ol>ᝳ/z;џ&~׽Ks'. l5>(ufڝxjv1c)5xݕS^NPF*M!Т. X`m+0ꖛ07 ld+:qfaH{_>"NQ$ w폼Qg>#:bgPF Stg;a6>ʯ=7[q(~ e1 "r9hRZ!6صZ?&鉮bwJKLt$`4!?޺[;BbbdL.lԒɨ'ʑ$,54ӡSǭrrkqMS;Vm<٩%FBV#(!ougnq$$cǎmuߗ0VVTդR9K_}W%h2Ʈ9BK%"9)>\jJ20n7%uBJ BjYhpWl("ai49)JQhO˽Sny @Xho|"(  8qmma-U<=f jD1*lX[^iQ~ @טI3ITa +Iw cccAL+ M6[.:o*{.mfUYDD Dg4dm|fmФs^ZKW r H9"Fxcc\ܛuJƐ, oNǻ3I\.PJ9h61!;ըKYkx#Kc1 1vxd\@ FG 2Ue |otZa e'PL -̵ '/ XrEcqg] ~_%>M>CtLq#TK8HDIuuNkv{`d,Gه7s._~;c1Nkq.Bp@ḨGd :*ݿD-HzǍZ5Ěp+nKJEe94k.t7GA-ٝsQ1'xصk-V hDZ3dZ ] ! E$oMZ F(C:P$tG!$lnOYOZ41ؗ3&{Ĵ/@ZXyZy`2N\ DElQ( HG@[z"e'͵X*vMNw91ؗ+3ƞ8_w`PX A2]( `4Bf-@8Rs!kNQO8v{KM~5ycl7 ""RQ@(|ZZAY bP, Kɬr\3O&!(3p_yL<˙y>~AcHz'J0'{Jh@I@{q` !VLQv 0>̟yB! !d')-JTJUs! ^s8|j#p*&u 4׀c} bLWB! !d'Y16hk7n*L\gq̼)\OAx=oarSB%xBkr,˂;ZwBkA0+a90Ѐ$8XǿS !P'g6 !dJ38!B! !B! !B! !BO!BO!BO!B%xB!B%xB!B%xB!B(B!B(B!B(B!B B!B B!B B!JB!JB!JB!P'B!P'B!P'B!Y|j?I,wk߯RjϢ}#kLZc πxRR*8dO!;<c1&IbY" Cq86M1h4LtwnZRDQJ1peij !D$s)e$xOj~ J%8-jċ,<B@AnָgyB1V׫jEm+0Y1qezzz6{mP(?><c]leYs?(CGh8?mgE&/0ByeY !,hhYj !+[lBtww{׎q;!.!DSQ6M0 )%~y휁i5N4q˲8N3A |x/x9~ 8ގIx{p42P(Z)yaYi*RzGGGc|j5M>22$IDžB{ [qc2, w*[%JLrh BOGǘq=52;-qާlv&3pR{^/xFCJ7spZ3'"NnoѨT*qK)1s'Ib&Hx,<}/xkw$H)oP(o EQxGCx󡡡. GR_e o1?&?hYӯ LB^00l6a$I0 `a ZMn^}F\4Mqh $===X㺮i(pԼT*jV%Ķ08F)6M4M$)x#׷y ؋ 8*0^ٯR:n}`` ƍB`$jYV\жml\7ok9z|yvaR) 4MGGG<ϟ{s=uE]|8 Gy5\rʥK>7o .]hѢ .jZV,1 !k}{o}[/)eZ{<0}t{hѢo|zigqƆ /.\K_^ZXSq!O=yx]0wݮHIRۿ>8*1/_K.9̙|(0Xj뺇r?l6ZZVT믿{iZ㌎ڶ]<ϻKkZ__'LSZ ! !Cc=>*>p8<:1m۶z>jtMwqǺu<~~_E,,Qy;]sI'=裎`[I,ZJ%֝3Ʈo~Iض}{Ou]gׯ_ovk}?c]šn Zrj"0M; oWrwcʯj?Oo'|SO?Q裏^xqѸ馛zBؼy>822瞫<;\fͣ>z!J%ιy]eYq1xy~׭[3l޼}o{-BN&VlE!;i`|9-[h7o [n?OplxdddժUW^y%i&q֭[5٣㌌࿶euQWn444y3֬YG}}b1c5\޸q-ܲ`ٳg{Zޯi6 þ;[8 ^{%Vbq|;Zm۶JfSkzo/ _=~~z|T>( QbA̞=W8_{h>R+(3g}?MnLcRʁ͛7/Zhٞq<r\T>u$Lrt"WhddCJ9snCF j,FQ|٫ؗZb>uc c fÄ톌X?Ro}ʕRۋZɏT*  !m6m4(xw]l6׮]dɒ0dEr\.O6Z%Kg_CIꫯO˦bv?< r֭STm)N;ϿkZǍFGk]kFGGvgⲵ/X`Μ9q{,Z6 B<3J% C4M6::bC%-BD!PGGFիWvmWT*7n?~~˖-?8::^xyavTX=wc=sq]Wk]o4Mqvn0p {˖-~k& VXq뭷@R馛yejS穧>ӦMÊT?ڵk(7׷~Eǩ8m۶m}_J5gƞ9ַ,Xy?qA%)yz/BP 뺵ZmttO=9묳6mdY0֭[WV NP꽽(OXT*|{~xxjF$ B(B"Is=oGN>ꨣ0[/^kG?twwoڴ ڠA{*eYfhgg'pro~r|muvvuQe-oyJ$ qK4ɌM\nth!OiI0ưb;9v 1|EPh`-MAJO&-YޮYbnx=^" {$I`o{,>r۶zzzI###bfY.dk{~wzAi6R {OiH!l?QB?q 'c[L1q ysΙ]ӧF -6NeB^;t:&P8V'tgq˖$7]H^N(P|؉/94M!DoooJ(4u]P(qy^Z-2Ƙ8Zk{4cZ<4MTaaB,d1 2s?)؅8- `C;Ps`sYTMXrȕe6%%xBZaB!˲;džέ<嵶q%SNWef{`IR' sP @1|Ta1! c3Z8ka ¨*ix:;ΘA˕L@K ]]]CͲ["_C<$֮Sczgq۶ϗB>2$IOOO LimX&< S%-/+aCJ#IxҹmpT)A]Y]azgOWpS1_ZPƾjZ{mf 厮W}/gaToi0hV&icȈi o׺55}iQKJϙO{`-)VS Z.\YJe'7{NM"W:ʓ4RSraZgm $A `*muJG1&WOl{bm=]iZk|{vN~u]܎:2qlYE (I)%!O% Cq#MS0 NXf6QfRAP<*i 3tn( ALNME>vCZh]>틍‹bwd`pU)$l2eLP' D(1VnLSjIAתhyʤs߂HS P.@M[Y}i3+yDQ E,UE^1Z-wڶ5btz&JF +Z*:aO i߽-/߼ô JUf\Lȁ? >ozac{7|O@ >K.uGo~~뷿r|;뎻y¿;oM\;~ p3;S{\|}^Y?^w .>7?km]]p֭/D@ xad^}ܹs̰%sn^Ѓcx{Oe˦oW^Yb͝MlJ% [_a+a}7o>ck]rz0w>kR 'jպ=1Ci9}B:,Lę x׾[EQX4 Ckl6+Je1y+ T*x8n_'܈'6ӸĘeY "~$IErNS,ăAjbXqd90#RBs͔bj?_(2;gkX4lֻztڵk|ʒ^}Ŷw˅ok.:MC_qg4●S2f0pGo%Y)@ϬaG/y'O8a/:QbԦ>tKO|k͘}I'D=6>у.5W^->a_idsÇܿ߯񋏘=w9^k,\{A<`Zʏ9߬}{Ï|V}옷-]~b˵A&Y!eE`6.@eK4*R*fPdLcd18ҏ&Ry>)y\w(Rn|NGhdYiRc3M&^aL2ڞ'~qW|& IDAT#bN?87|i`_C6oZ*Qm'xyVup_}zY|{~vmO8{nh}تc8/7=7a{w_=g'I}R5r}$-貃I`HZů`nQlى}ÛY׫ժFFF:::}o?ݻ.|hhX,.^CͲ ڏybE9ɤ}A\wR%mgEg !*mZfHiwVoWȼ3r !@b2=h!0%0MY8O\Bg"Ds3o0j4=),gJg apf̀TjqGHwoh>ZZ~~FӁA3Lݳ.w{_;j;s[G͂ ]|]CCW(' 7nX,ZAM#S°zvɚ1k߭7aņ-[Zgx05~r?Onay Kw(4[MV(\0 .P.ํ[L#VT3 /zz͖oZ{I xgE+ /z~ ֓\$ 8c?V%p] q=X{ ft -cMLr wtt8Smqs|X"߾PJQ|'q56Ok=1TEʾ񁁁JbYTmwttL47}]0>{"9cLkXB&=(6V>22t6uW:Ŷ}ؖi4fqLj(U{?U 5͔bvsPc-w<ӮYkyq:5a('ys[ P(zaHӦMS*3Lɹ<@@g$~P.g;~CjA `r/]W98׾rC ]kSha 8p9sqQie^o?a}c>ksG]q Xrum^sLS>LհbGOs=9B_ EU.W;9F6nY,~>uBG7ᨷ™yHGuwWkUn;’ndv c22mXP5BWp+^uu 5p _ޚ>wy### ,8]:ov{}ї^ziV+9cl6JZj /TK.?g] eqznZGqg>38cnGq|gq0> .{?wqZcyO~rʏhp[v{v>keuLpf 6gLÎTLh23h٩nP^4 [GLJwhj$8Ps"d<0 W^}EٶeY\ꪫ8ZtksĹVZLINp>njaFqR,Iî;T97˒$ S@ )y%Zk!*B5|狵2_yk'䍉fzzA(!rC(l2qUVL1 xxYx 8dbcSs\I0e0-L -["wD@ .Xn2Y+ Qߪ3XҨ(צwLs87tlЩ HKO4 ^557s4MIΤΥ%Z|3ԉPBKBKT\XB$x`йԩd# :6U,Y]C_x[K Z7Υ3c< PLhnB(0:7t. 742S(n :u/S{i#<s9碋.+ }[֜9sׯ :;;g͚zQT՚;w>w˖->M>OlZ8ghfBeˮC= /m{۶m,',ryhhh7| Š+bx뭷h… /SN9eʕVz衇0ׇZK)q(96\5֯0y}f.;#,Yr'?###R?sޛIRY7ȭ*ki@dEPDCTTaQEqqCdDYQYeꪮ=rX}?nV7?i~y|Ɋʈ̾q{{?"Rضm9眳zO?}ddDJr /c]rSO=jL{eYfEQP}?8VI2z%K'lXq?[0e9Q(r5vD$oXEl[Q0]qBjz-"MIfbfxy>\t_7v!R"mo,c!CI/=, %B[ (T,J%4% l]iTZHI2ɪFd4D.]`Lof1ͬI*i(DОh)ؓ:"0.1m³u[ [Ic5fl a{+dA Z88YJZm!XHfCķ!9Ԕ$G*RHTB"bVҬXjKYRY $XKiJrHI]b$yRtQGr_T(>>3=د~;tnkof͚SO=utt'YjՉ'hgĎn;8׭[$I___0nTJJi,???}gff&&&}ؼyz뭗^z>xMo230 ޔ;==544dvmo9뮻я~dN@qwr-=qwGt҉_W\qd$I&''MYsΙ]nݖ-[,:34 2dTj6Zka呑(e`.)s=W0K,Ix\G=Ly7n摑6m/z衹\. Ã>c$Dk}盷ᇟ{̼yf~Ţagu9pXZ_o߲eKOO]tEK.Vy{#dX4/n055}kT*BaڵI阏_vO?mYVE7xc:x^A1BZmybmZÂ6ФsSpYA~`bPAДRAfm#$3g(}l!$ORl2-˚=ٸqcX4ofNaVU!DoooR/ -^XJi;ѷ-Zl6[T|75{Rc7tm]]]D$1?WL&322y1s=1gX(8^`LP>lQz衧zjwww&:ꨣkk׮Kr?oV$&''M+i٬b]]]bќcNi]v1ͼ=sއGaÆ(VXat8======F_VRb .xoz mjL<44GADjuB066;woss(L5leÿ7m ϛf8۶xZfYFxg.]:xj,3DTa;~fAk i kaurCK! USVEȄbqc-Xw1/VڏnahjdҚ]f)ֲɤ4$sF4+D̢Y-+b1[lͲhjhYgޭ*H%C%늠RV)+*(gJV=쒲JhE"GP2QVESW*JŸL_><#}{>Ć .첓O>9R5k|CqzѾZFax93~>'3~_R.Z`֭+WZQ^m6qAi&Rj˖-_c=N?я.]# 4zn404l6NT*566zj믿~ٲeDqƮ(&&&FOO)59TUOdȴeYfB)^{<#ILLL\{J+V,X\Fa8FE^V(2_gff$YhqwW_:Q۞ @d29߮])fs]Y?ӟSVsB>_ IlݷV*L=/.]uA-;" 鐂2l6qw 1r3 AlBb ZBt莹;B6!W9)-bаX6o+뽿Z)xGi^oXSࢱ`ɰ=~BnOODgy߿l23 K֮]}W6l`۶ilێh]vjRʮwݧzj__߃>x 7msg4SVJ6(,YrtA׿vҥFyԼ7|=Yf}9Ec./c=֬Y߿?R-[+?`f83fo)/38+,Y#$A6!7!7yOUUUH!!a'J1LUSHK{t(&?LLn,ܘXZp-myfgJ\O=9x|9Sgv?;螄 D@8PU:o$퇹P_u~]Ex|NSt&'{{])Mj)NҎtVU-3lP$ؖakmҐlLWRYOT~TO)NN/Y=9U\ӹ73]/8唯>@Y=dHaM#UzzW՛QЕ:Ru׿=Hxl ZOk%7j<߲pd|h`FA)e-zj⪨ETCD,#5rմZťrEZWiVg{ I[6P`hJXmI5N6=9K@CmUK?DhZӟ'85n؄P&:)86MFewƬZfcĒ$WEb$u0/:83i5H`H3z*R_@+ƪTa8J%ʓJ*h3[ z#gWq^Fvi*.|쉇ڟ5^UzV숳>^-E}S/w#罝-#H^HMn߿G$˗m||{z'?M7|-|KE~\qR< '~!,cc.:l?qAoW[Vkjq+4+%3eI)%IԦ[׵ۃ=^Poͨ/H7Zoeo|cU߼egGUp֑_>x~{[dfg&p=?aY1~^^}yw⬳׼0+삏_zpo߀իpo'?[Z!|Lӏ$l:>x߿#u{S{1ǭoݳ#c>dɂT6͊`üA`&m=ܶ"뻭K_!uEBa1=N\sMֶu]I%cVI2l?11 ~5lAdfGiⅯcT3öm&!vubkH"%S~+jj7W%45H$1XF'h޺\\UWPzz }~O&|3_=WLU7t-|iR}ߝyg>㫮:FՇٿo?V*'/(չL__=c|bA}߰#>)-cgl' E'|=^qY|Ŝ/9Glzqsi-4X󮍟K{#_C-]=6 'b u[]uw被?QUo?__t ?E qa {E3\C|g>mo~C'i&][H; :RJaj<"fztbn?1||2f`zZ,vޒF*A.@SOf]h4q*NL|롁޶eh?݃ӦY©B9oYۛ?UI(pQTiTOڽ\v3=Vc3SyеxQyx࢞F\[6m5ן]o./_ӯ^vPyr K:e [O߹Ǟ֗C?+w~|}Tfݧ\Cpş^wOy~|q뮹]jWhv;T!0fKN|o0z_+9|: :}0 YmԚiun%K,SB&3,6dK'-8UEdgj$q5gtq)-mnÙg9+(MOdH9n\a h泾lML&P3q\|;aM/_Ó?{%VwQ8vtG۴r<'q[C(:=l+vJ-\P,[5k8='94߻u ͖¿pXWzǻwG?ܞl#e+7m|c{oڴq\ت [$Xt_s3q[ա'xur. ?2agnZ)FWHRQ ǘA]V(>97|FtكHx1vu*zRVZo5D#łw5DC[L:ӕmFjj\u5UkX(qw~tP.en:Ͽ.G̔3uO󮰛fes8ӓS*tЕtR)lؒ 7]-߿š?+ZVhVڃ ˖8W bѪR8-@<ʥQe:t;z`oU-/fsI^7<4j?սe[Gleӆ}+gatAI$IR.3Ks\O׫[s餐sZjSd؀X B[ʵ%zr9{ji$ܴ͆4Z<>>V5rl ޺X5P\:99]A -߼ax?Yo7-O/s%lKa^Y^|Ow+|`S?hTp)zv}$hEkpS[skf3}D1wMz ǟ|v]}nb_B YN\yq;%=]B\7u.1RaDZye]ut_~U8hojy<.V*~;7pmNaJ[&+eIp5*3o `ij'InVbQ:k jZDm[ w1۲^}˗c{ߝݔNg[O87O=gWz{3,n|wwqiը82{x`S?5;9rLڙb]/UGXrIR3$/vgtALO!n[z^ݰū| v?KC՛)ZYk=uQ˗&yr~mb v8ر\ 7ɸkl8u~ ;~xN7I"մ}*ͯ_O`=q \+íVwAVltwwHHJ`)T Y/M-l*%-EfXiJ2%٬'f&ْd>.4%ԛUխ[|? ls Y'$N{ߢ7o;n%d9NLJxArA80jl6kֱ^M۷Mf5- vT\D9+Y&0$` &g|=L2Z۶źeUoV =FլxY?5R˖ᮻtS(vJ%9R{+†xLe&ߕכd9,{k0:4qIP[lI`ⅎt~Wr.s:C}Ϟ۴i333^oe8%B73A<3Vشij{hpŷoe+uRnQ-B֝a"dRiʳra;(K#,2, sm^>󴓮ƫ.O9xAXp-uYS7k M}Sjuqȡ珼첵SF]]=;]x/K- ]1Ww|5;]w% )o8찥W|иc~LgmzI}׺yN%-K›{L*vovv'uB(NK9m/sSv JU'ǘ+w$;蠃6,BLBFQ.zhRT3TJ)8" ڲu*妫f=Cp↤ز(caYdKBMǾu7BGV;tZE^C*o-FGGO",[/䨝fͲ c#җoH`םw9uӭ'Δ&swp$E: k%_ RF)k{ࡈߝ7R?˓Nź-Gy׍~/]伏\=p;x|l{sOsX}騾#ϵ3μU[PuZ$?^@7 eqâ^[ex<3w|$r43ym$5Ms>6M|/e1GNJu&UtL }L B}ϭUT3bX;\oxWj"X10j1K,Nl[T+I("6TVʔtˍzpъd+ꍪlyЕ cLjF63=U4(T]]=VKsN{Z< úNʞ)ٮzX8R,p4==hq_T旅Vd۶c$l6ƃ 4A:;Qz]'h]jᢁ~`pqdAщÌ*m?y:IrDDeYiǗk[uG:\N#2t9j8t~dwAZ'IblZk˲*X Zq_>&34?*όӞnyX$4iH9Di:缴_)*B4VlMF a~|}4;턠4 ]茆dhXDP`׼ RpBT H[ A $ EHHBe@V@&bv`MY&h*še@sU5 (a(h~AnNfU Ѱ##Oev>5Kk2jY$qLRD⾛OJch;'BkFbPۃ&"abM HKbN\XUz;zpiMd,miXh&M\g3tzbb±\IjUXqR)ND-zٮB6lVZa$@M`-* ȹcrv$EIaO >5q(``QEHL -ia5"!|t (q$!"",(d9߿m`_dU]- !HĉyJ*I:AبM H$,($R9-C(ԭA  f -beҠY60.cClhҮ k脅H43f@\4QCpȤ$CH61sYKh#T?-aOlWPE;ž{L|- ]ޖS?͏?sb855eMٔZ,b!ډon53k$E!- le/j$ X  [ Dx>IZ\*%5,lʥ3QD0b͎oVQOJ:miJ{r)v?Iͪ눰5%֭ZBms8nEyqR]hd (abDCywq\ժUıVM& &/$X@ J(iX` %D BH3G{|، @X)bLhS_Ab~:KmÓ5SF,։ZXk JpT 9M IDAT |;NvFS,- KST{8!X|fC!XHR`@ t $L 4(dA 5(ЂfL@v XCO{@ 2&0BIc[)|{fAQ6D72u0 su fjfVf+FB3998t^S IV\p{I`&Wx69J4)Ps5"baC @ohiY8h?V\IB{TAh.Z4exYDc=AfjrMu+ϔ[Ҿ_vf˕ *$J(J9]zh\ϮjA*tgq9Jў`%q:7cK;U:2 S 9cKKLwجmZ[ԦNJB;POZt]A jjTm3sm C[BmKFJBBP]`b;蠃W){3K)M amŒS|4 ɩQM\7ٌ#%,K%X2YB dR&F8.!idCn/}$$@Z2R `Z 15+MER 51Q̭L,f@B NUЊ;*\ݼys&\|Q#WISCXk;fqip$I2Lٌx=Z-hZe"db"n''h@ bh/@w4M NXʳͫV 볕r;Sƍ+W:1Vloٌ#jյa8J˜/dGIYRŅe%jXIJ;*0֬,RmWCO^VRyWJ ]8ÖhC͋έi1I{YB@6X֜@H atvA)2TtMmٲyѢb&J P2]%RJÄS\"˖flД!J hh ÖAte H<]>KD:R6 XUNH r@M$ e8Qdm_Iɰ`f/\F ]a 㟮M.m$46vض]ՌWY{4Ǝ9(Z-r7MGSSSbѬ|ZuM@|$ay% Gqᇞz?rB38wpN RK5{=2>Y28 [X~A}k:[~=2] buȶ@~ӗh ۨGW_KҾF`B #d˶LzQ枴23L 4J Am/39!#b!ZvuE:ݳ`XG'%[HBmGsrL9W!%b!\p872H heMs^V3֤E{4J0K%#ؚ_"Q&iBCshiH /%ڶOx^lCf8/o;:Bۻ I>~̬gfO-ˮ$YF1"pV8dB!a?q`#0p`F8؆XĮvgg賮<~_Vu3x=>Q[[]=]Sٓ7b=ފ@ǦnWU96|~ne(a9fEEE&YK , bX^X(6%2&ډy%ZbƤq&5д%o;G??>~w{}}'xpΥvJ7;TU5Mv.^Tu?c?Ӈorh7?[e@iƇoOՏ(ꂳt Kʊi/249!M+P[ߑPeFag%^,m58>l8]S ZtVXL@XW$7Dn4d1w]/-mX@4N_klPOn:h˽KP5t@@Vp.Ŵ xլ~"EH,xY3cj-Y*$)  \[+@F1_ ]Tijpl!u01)> ,T/]&˿+_%Vʁ@m-g5gxȩ/'-;;>_y|9gT5/,g_5nѤtPE!%DmoԌ@ A\ʺ[p8s99MMQ'W?>~fGx-?&fNd7j{Xg+GIgsw}õ'gģ%ݾNǗygsE?'^ꪚȏ=>ǫwfox.]S:۾Տ>g;7?s=__OxZprxXy ETx rxg‰q)b=Kq,7.$j.xƬ9\% '+'mg٢zsN$m,dý{wL+xFÁHLJLqb&ssqyBӰ(Knq|svʉ`Ԙ93{{{^/eךx`4;wnoo j\+O$8OL.^O?fOif&0OT;+>ͨ)vѭS?fU=/2t)~K[~>[?7˚+&7vT]uyg?iyx${{\}{#kx{?/__u=o~8%6"xnc5Ig7}o1v5<:Mp@g)+3< &Z/F}[ ~mElacdo_/f;;sMk (AIO2ƘE~_D ߱gKp8|c [9 $" Uݫ͎XTEDR,i1hIҕtJR*"Ias\v\Tj;sutʲd8R;;;/+,e;/ُ -*e5fJ gd@2il[ ŠJ]*]O=_mIUU^>~OO_p!^֦4^ٞGGGW98z߅f2rEsW r2,n*IQYts ~J"(NiKz_%qRNN檦 `>W77us'kg$Ii^$|cE~Y {z\A3/:cq5I!&]XJ]H)(%2FHԢW^9_)~5uh|t:DMB̨v6}~C7xu]ý4˷ϟk<{C=( _#)]*n6>f>Gѵ+O31lms][d1wʓ0ҕ4|5:cH z^0f7Mm_<-v/V)N8$'Ь: zye̤L VKcf1^׵$I"+eM~4_H[0PH#&@B#Ko23/X"Q!(GsMZS41w]Ged^-/_4Ɉ'cto&j6I1:ko{>p=K~kKևkG~ÏM7/Dl~|;uOO} zOߝ%B:v܃tUfrAI /]ڹY}Szhl()qT3o\/\S{ow|g~g=Rs|xpP2Sjr<+i[?U<xǹa`秣k%$48ܻCk^~ׯ=ikƝDҲ~Gs4|F;SP8^ei_K\}jf~<:`Oy*a:om_P7`{nol f1NN OS"][[s.gQ#4gt4MYAtz}[EcYpLRKqi7z|lʍOhrpmCNXʦTü*f[ b:\Gy UUn ;!Z׺),! s@ TÁiQõ W%:+IyO^D&ZW ''#2DswynUA P֠]蕫H Ly^} ~eHY,Lv(ǒ%{y?fU/1klFl1wX`12k%CAfb+A a$WĵLU4I}b}&q(5tQM L"41IɉIA`VaA8eOƁ̨ :д ȾEtuJޘ&s2^Bpt:s(Fxg/ffC|SWt^?H*҄KPX47ZAWTča1'hPJ}k1E)2g=BWztpM9̕մIg0 5M֩3/JJV|┠h (D%Nb4 ;9HY a4tQ  HB `@h#xFXN3%>lNhX&ܡ"P~%ߐ$n` =$@p-(ܹ~._ln<_kp`9SaRp`Z Uee!1uiVUI]o) π*; Tv H ԓ%]f/7v*́m`MvaV AҮq:A jbiRtbBdYEU ,8g- @Лlzf1w |L>S qp S[r:pfN&yM,c~sgsw6\?xt֓a[o M&s[Q$InuyPnL.RVBBiS­LtR()RWQ04jᆄI9 (@8 8ֻĖ78@p"g$"@@$m'eq/KbO_?qʠ;rEE;[#`mM/#%k+e p bV4A]u娻'660+0/j,i3%$Pe1wu{ykK`UhTB;͵m'<L]hXX9dЌ$@T2MAG3¤kUR bS$0zmLJԬ&H%aeRVZ@=ssiπŰޘ.ox:NBfO$C'eYCTfpi üwa4fS,/Ң#.zGH!pqO_z9&~ 7ƘJb?x":::zG) ?wqTmdB  /n9#]E~IDATP*@* !HI \N$p̅3k*C}eXJ^yAB@ _9_0LE&yN|EƘ;_$AX'bYuJn/=5AMZO=w>>j y36έ= ;BuS^jvWc!mͲ,.]][[<|s HIp'8:B!D+ m NEFf9r[HA3@,Lp|a !9.\CC `^)Z| 1c$J(}pT ,b<@et8$8TpmEc1ƼBR\Ke2>Hq.*L _ԝy|1^J,c1VP# YFDt-XYYImEc1(P;)o:v҆cwuh*ů ( R. PiaJH@۹|b;,7c1/CF",Ax<D D`U ʕ {/j{a O Ec1@Q^o>TyZ=4UQ2{( A "$%*Y?E)[<4'AzPSc1c]i^ n OĬKo͵A箜<\h$(teage]m_TJY|'<qUĿ1cm{`<E If @In?<Φ 2%U$qLqrf\ڠw):eġ/c1`( B 1 /Uhr8YsPλ d^l't?^ġveVaup6 w ro9 A rbw1w 0|lri%iǯ$D  m/ OO3{Qo}1Vq $c1l#P#W_Rd E]VYzTw'" d; Z"zcs !MB] M@rjXHx f,1-jB>kcEƘF 5gQf{NBaH A )0>p9'u ',zщ&csCwkn/Yȹe L|d@N .S@ >Nf1Xo9{dVM4W/_&i1 ~c^fx!ad  K! AB'mOc+Xh"C q+7c1c^ ddPi loD 5Rbwcs q|m_- #+;E~Vn1c*ZY' eND꫱9ŝsQ\yc̩:xcR0Ux H@ ifmOi @v4&.cMXrPPbhxPr' Oi矨 ?cx1Xo9S(^hpUG-^i E/bǰ['_ܹ;U@1yawtym-mTI ebOjd*.6,t<&pC1/[ܮk}mc{9NҴ{ ;NB8YEW8.8$iq>n4g^4 *i"lTc1Ɯݔ?qKDT5~ E':)U$,Fi}RwfUc1Ɯq&4_{ܭd] PKF1mb.eSfkVEc1sB44 _50Ne /p VB [~JdxYFi >^c1ƜmMGՕ{+u=X rhXk A @} @8,q}*F>$~f9xc1ƘMe?M2崗hjQEñv "۾[ƜDi.y  YocU+YMA+ wyweYgYE^H~;e&ݬuneSv|g^U7c9!C1\ ftVtahN q;NAq֊*v"xc1Ƙ3\FWVf>~ܶH+0`1c6YD\!( 8Yٲ,޶I :M%Xo1s1t]'_FV4icy:Qm,7c9;yJL(ڛvz-mN'Cy,7c9hEZy+/31c6Dۼx%A|5lm 'jc1gX5 @!>Xd|.}ŷF Aj"faEciZe?L~>w:89@DT5>r'P ހNgYVEu]'IۇEcĴzai"t:LUbz>Ěxc,7c95<9$I !n׫*iUc1c) yf3""$IDdkk ay'I37c;p4]vmkk*}b<,,wv cj\ǖ;0c]g0Lpx;cVe1ƘVUBv4 !XsGY5 mIENDB`dlt-daemon-2.18.4/doc/images/dlt_message_flow.png000066400000000000000000001465451353342203500217070ustar00rootroot00000000000000PNG  IHDRo5;$sRGBgAMA a pHYsodIDATx^ui@qh$Ųe Ġd83Ә1]g -qx3ӄt%aW V<'g 7!1Dq+Aȳ>( Ѕ =@+у.g !9Dq @!X! @A6 .]q/ X t< H #O 9ʴt!(B{!JA AEDNQy} Vȁ>g}P @ Dqz  V] <.B rCBA<2m@] ^@@=yAp@GtrYiBQ܅B A38@} L@.@D,k.mxm\<"((X &bH@2$m)@ݠ&;}<4@m RܖA @x7$LҖpG4 0\Jx>I晤H#@-Dq[r@ 0 ݐ3I[c=@Ga\$p1*$g#M mq!$w@@{$\I t3I[Dx 7Fy&i >VݏB(QO g :D?&XRˋjaa>>ۗ’ZxƚZYl#򺺼]m{^VK3mS%LҖSpJQl?C>F*W7Ե T/+{ʓjꍉ6ₚn:>@I晤-# W ]~@F(Na]Z@]ɭEUuqpR$"|WIٯ_VjN.e_橕djuRr嚕3I[ D+X"'fe]Q|C]QV*<kjZxb)uvju]jqȨ{꯫SW}I晤-w 7DqipZ`ŪgEqV#]Uo,Dnj"y3P_f(}J?D|F\ѝdj;%,@6 mҧm8@@R`8\pdjQ$( *-0A9 5$EO؁'(?hq|F f..F ` (  ]HwzAQ,)d%mE9iDQP0 O ջR5Eu^UO5XuyZNoW Tw|-ɕެn Cޢٶ+?nwZx[-InEQfxr #Dqi .KjeWڣQ!.wݡn[7}Vu{@D*7ZPw-WxSQ[ A(vqL `wZ3ʒZw]̗+l/6j'U_TZ޳jhB\KkvWR-r?p)+cZvBh+S;[~ܮ,Z^>@@:DUYSǾ'uϞe|bK}q(P'֦WT/-{z|(Q1ݻW6&#vK9lⅼ8#'VzуsKj%ib ~@?@g}I:Z=UmkjwqysKw1?(~'.3qܿ(NjN}o(~u[?ùzDy0bJQl?C>8)IÞC๴a\PVPU r%FEkź-Nz{wRߛmփv wU# QlBQJ$ȉ'GXV7ޱBJlޢxNK'꘻'N?{ۤ %3'MiDEG W!`(.&5gOU:Qڢ8m/+wWw]{S姓ڪEYS=/KKV%ib ~@?@gD^}U=Nҕ;FL֪+JV|Bxpk8S78U59@tkZ8Ym?(:F @V q'`VlvtL̦MlӦ{Nz}F%W>w0P:ћ(~&ƃw$e$ŇfOocKosQ/^Q DH@WEq":7_T?7/8W8](?tZ<78#1B7Pp#; ۶Mj4+ž` Hb]\~㐳SB1ϒC I؂~!ЙPrs$-aCQl;Bs<'S?tR;TRJ&^CD1=ڻwo;w?r,tNhFQ܌WCsH^{m\ʧTR?^q% 2D7xH@Bd҉ΙI /(]BK"2FBN :Dq^D1%׿+%-?i5 0 @|D&)!L3 5BfC X)nώ;!]Kt)'tzkV ؇(#<"UdK'(hxO?pǫZ| (!JHNPB,1l&)d%m5WC@҉LXס@%Q*@ FN!`@RV: '~%L9kK9)@[@ ,]K^^I5@̷ +] ^@`@[')pzo^z^6ʺ*iC  I@ yz }[6I!+i^t p<%Vd:3( E9*@p  Ȅg^ :B8Ma ʶz_u)Nmc5M.eY;RmK6$MlAobG?ZęXkz^9?]eE,Xr~B Dqz [&%vW(ўt9JW,b1~v@,űD~BQ ".|]E**/ (& g tf*qVvK(ھo.AEQl8#C0udt0pt$;m۲o۞b-  }B 2mK*qEL>7=$K6}LXcl}@M Y^?j;zڰwLb駏gMQ7qڃjh*Xk{1,ܵy5eߦ  DK@`@Sa6oXۋ.۲5ekO_Oڴ4"DY%b:YC@ű1' NA@Rg8{.u=qm蚰9[c1wEQiځDl&kKχuJ\3ALOߊmϻǕ'&7@A@V:0]Ż{'D/|yM |;:mVʵ$ %(b0B0k[6PHYͲOX?dkzϷCvMs= `yڅ">`VtJI枲4@bG4.LBvMkat.Hاh+"#EuWcζ_+z ^mJ|xΧ,W@QL@h+̴mZ"ZB+qnmoӮO\8xE0BwOVtMOk>ϥ O\8xE0BbN! L꽅Զu9HSM/lF!6mq ¬vl:mZE#g-뾺k K]?DI@ P;^Z5Ж}]JX j@׀%mYR}[:;DڷKJwu_mm]]\BQJ$"FyLb8-\MWn۰3!;2!D198K0ӫZ}idy􄸶H״Ʒ Wv > M[@#mYYr-W>}M4i>cT7J . `XB fRZDsֿ'>1\EmXG &#-{a@=z @0ZꟐ^z[yaogjaaaϒ7^57_R jק7_-׏]Tw}:R_@@{:@6ԫ>ʊ&۲u!L>V^蕢I WV]jķD(o!up.uק~ !LKڀ A1K꼚lʰYo_Rv={??/,w>ŊqxHQaph*lVƲG %!Mg}yȮOQ7~F-.[UK?ԗbWs Ѕ =h*̚Y2u}aɇ!;mƃr6ڍOWkbJ(@Gb֗ϩd;/9Vw>_VSn{q@SaAbm'W]u+r]^+iH[8\_hJQܔXLgv 2C׺_;Wa=X $ugt$ 3 AO5šnYה%]ߢPs~A)DqSb1]߳(~zh;{/+D_ю`V7Էa|Oצ¬e|$7a)]ߢ8َmkU-io̞6ҫ(fkl+Ϩ箏D/'l)nt[cbZ>F׵=iI#ݒ-7Ll_M*}~pOQ/"Vxb.^ZO0X "e]r}ͅ߄}f*QSԕT;mQoUDuݎ-SR@ss ! =QY ۦ#-#5m5J:BoKz.+DMk%Wz@CJ IjAtKS_Wj׮_R'^{߮_Q_Fq]W- )ve}֥&b>/YžF{;oUޱkAu:q?Vw}ξSw۴6 fu0S[}f[!;<" :u(zMxuL1?>hOċ50Z\gwye]HA_ /Dqp@]aVgsVgc[sI]k|  =Dq)K0RϪޟ8p]Ymքˇ1~~$d=?W߻jioYw_셮 ھcD:znzrOO}j,Qa:c8 t0y?"` ]?:l^@ױbW0t{mCv5ģU2Q<\5h][Nfs^X<2>sħl.?-ݲO" `E{i.Ru}v!ƝJ79`w7 _x3=NWs_f)vef^4n3%Epvm(21(ٟޅrDq|=ثppԵ͇]E7&aV[_NQӟFNWO?lo?}R ~p#˿T_?~L%,Sʆ̬7]qDq蝘wR<:="[kAxM&(* 3 |i#Q%?,ܻU]u{-vW&vR~wfjQ/)[Ej"f-N] _Pp 93:ה1j+C=Ws?yQR ɉD^?+gjꕧկ7y*#{(*&zkL`'VV@GK~UST lQ*o!ǫNUO?~R>'W\#S,f=$7e!oE[…)bb&+;b-,,N*>2"Z`_Yado;?|B==|bJn`P;#qkZ0{0k[)vŬ[2<SM;%Cx "rCOKC-t7(cb@ZĞ~c*K xm,y]ʅ}SQ<ږiXS܃rVr`>,A-ْovd+R{Gʶ}?XîQG8yqDq ͤЍ0W>BN3ŬUNZ5o+&|6ۖJ쪶 >| 3OT(_O}+w>Y)W?Ľ'vH7~.}mɄ8 B>#+SǺ5ӱh)so)pَ-Sį׼bsv WnC48KQlhl;VCeMqqC|b\<% q},fmDqR燓դbyO 2A7k|]Dq3۰}Da FQZD  jj*C7.%QaW(>P' Oq~p+)veYZ_<e DF Doߊ$OlɦWh=-*,=2oK4ʼnvU}Z Ϥ[p7ۙ%f=$V՛UIGƫyCv2}kQ<@ F^SƑ|kg)٧(~鯫?M~z`FC7 Hɟ]ODwjݬt%s4Y=dWcn@ M\\\Y¬MM׫b[u,^?dg#f! =@{%ִ̚r]u8K -ih@Kอ;Dqw[%̚)v٢Y/$) (#^Qezuz0 XѦ"׎Znl[Y|)C0@Q@@@0ӫZ}qlRz]hY)!YuožE !*Qt;6;UDy(0#y.̠8x[xEJYӧi1ǫ@هY싫p DqQ@0G?:uNe%U1u Dq @,aW7)v^ YW!;2 8/@@Bq]D%&eyȮK$(3nx (T&۱Y/UeeyȮK$(3nx ( cˀhW@y'P<6} (v#x(fFXjyq]JkeyȮ>O#(/fx ht],;8x ;Zܖ=( r9 DWYEL#4lE@=|@n0N <[ZX#t@Gh  Eq#:l~up];:^B (!(:Gp]dX-@  Dq(@Qk6o;6N]W^B!(%(:;Op]DhSFQp% v: 0@^}])vIŚ5/@!@MEqNN;G4ݚM] Dqh?@^M]/<)vd-1.@}bc@^;fSڧIb`kϙ;! ݎA jyQ욵uK:jy@O yQ<@NJuVقc&(v;>x EAb` o C |e!^-[Jhc 6X%(v76x dX Z;T)[-f 69X%(v76x dX Yp\|J C02Qӫe/N>(f 6yX$(v3.x$2Q;fMgf5 e@=1?^=ֵ %O֛|OF(-Ss?e{+x$,B5 }@DĨK'NSӿ{#oWm)KZ\$`kA  QQ늋gyF^fzS2B>5 }|@dzʺK/kM *[Ռ/@`R\DŰ'e7%s=2 [ؗ ODH ).v}֎b2e[oJF:Q@+DWiveElom)!ؚůj}noEFeTnwEJZH͇lG8B ے-[oJV  ؚŋkjZ^nT}Z\\Q6N ׹ ƚZ\XR/̓T7u.FOw~2֛R?@eOEqkjkP";*}U]T+ ^r%ZoI5#/l:36y[5u©q[+ԅŁ:wF˗CP呆o^cpN'ޔ@.5x.,)pBW^UOP Cue 3]V-u} ɋO6qQa W~B@E\9ŮzSꯇJ( ^TԮ;v$BKv.(^bW*Nb_m)CZ\%`k @O_Zg<3VK ԡ|bYu1)TEq0ŮjN ?1r]wM,zSj#Ba5/oOؕ)ߪqm +]^J,b0'{9ŮhzS귗H(NwrprK2*DjpHoVĎ:uCj%Qb|Hb5a|=2i#|#o[oJ  ؚ<Ź{¹uVWg6jmՅGԡ#hrlKla}qviVKd+\4b)9ŮhzS꿧F(.{,94Wf\z d#I}Ԗ7{Jkl?b2 1lb֛R=E@5Dk?(;; aMNoipQR  0A@Obg')l)-B.5 ]|D1I [oJvzKKl?b_ )QyO֛R=E@5Dk?x $S4&?Ν3! cL~Ў9/R#Ac@D)؅$)vMm]) `$]l;O l̻gحsMۆSP96%c(ʼnsIUc7*74B )?PP:!E;@[s?ڑlM1X|Рc<ƨﳭ@Ϗ W@k4сy^[P?U.lq2@N5P](^YA~yv~S>L'+%öjQsOfښۭ< cwQjFy֯f  =L7]NKd])Uv!1|Q|RTH `eڰbr%H (NS8-P0/&5gŬ8)[)/wvK\)Fx@{حAB2_K:X"ݬQ,N\( a9EFvBׯU tT B,91j[zN8IS-N@[c Ql)4;I(y z#. :xE58>Y)m͕b4L Qw~pW=hA!um#fۉY)nji,zGEQEzd0-3!jmhՅGԡ#.zl {5ʼn/ْ횺|QPN?O/<R#0k+m8 s@NdP8OqjyE{hY-,#P~tUݽAsC-Y*mkj5u۩X>wHwKc5FP,puV^ B!҉LSBa;"D(|j޵P`LV_l+NWἨX%s{Z;c+jSڰͭj/d>WRzdkrUz#6Ҹ5BI t"ŔPJ(~'ԥK:w'fD;ٳOl=*P}5ezCjҚ:<a-N粕]Q=K=HsD~V LO QS]WLJ:'g`YzrV^ { 0&uK'('ۺEvZسO0-/c+KjʆG_Q\Zs- jbv(-|Y2_fX8O[c Q[9߮X:A nV׼BWk/2(U6[ZEqYo&FBJxk(}_UqIJd6*^3oCgq[y(6VEX:A E_͵-,Ղ+J^8_& P߭bYBQgqo2<"\%LKDVJ:lK@ؕ ܏.t *)Zކ! "1ف3vjt믶V⩇JA.14k߯4㿭@'V-LYD&)?(ֵM:P3sO#![c Q^.QG]St"ŔPt Jۻƒ D06X$ 97 -5F@rtU,XKD1Q[~<[y(& 9ت[:A E&znk7.-^' gdF[y(& 9\hϜg].쭇 ȳ(ܸQ8T:$iun.{Q= ؚűg#rWnHҫ;,B.gEmEEpՖ<-J2|Z=,O Ȍ2QL>:A@rj О9!KϺn][AgQq'mq-B)YߥKԹs~4߽ m>L`0H@re>Jsn@[s?+Ŧ"F$!XkH{xA@c\bx6l8\GU[^ƲӒk {_~ū/omLU[@slz(׆@+x<`EsfmxWjbJ'@ [s?I-c6,ˀ1t+)A8PFV^ G'HWm93'$cY{wN %UmUIpՖ4I2^]X҉.ץA6[s?$]J((7 ؚ1g]}Lm[7w J'A f~DqYP%+*ػw/vXKM3Cn Dqq -A\јe4:v'h!PN1Nfb U[N XzukP\tɚ?46xm;[y(n1s`,0)P ^$`kGeڪ$ 9\Ee#_BADyG}P [y(/WXrj+d, | Aֹ0Ɲ  D -ܜd,Y @_=gEگvlد<$sI.tZ@l☳.оK&I[6-;Ӹ.tXZfffqjC$ ڬt,=~``2:'9 IKlRivp1oN@:/* Ld6-~3?fk[y(6Y" 9\U M)1]|e*Y,nO[y(n'`:\m!^&s@2_8 KLS$sұ4);`gL{m+/Ŧ#Z$j"'{vE_re*Y,nO[y(n'6D@rjJǒ\VsMd=sY,nO[y(n'`:\OM1ؤ A; -5F@rj KҴ(~[2_JbaC?m%Dq A%<s.Jh5|un0rfznV^ =OPܗ %V}C:Eݒ8lwm[y(v7'Lrj+ uV:ָEKr ̜mJi$$idC-ɟĈPg ɹ DqZ\kpՖ1xiQd<'X"ݬQ,N\mpՖ!tA%5nj:ufDY?mY-C6+KӢqn| z`#c o~K!FW H&I[r/I-Xs,]%A4ɹ&-c6,>m+5=$xG[y(%pՖ!p=X&Xw-,w=X!67{½f3AZ~U^I:_NI2v s DŠ-ݜt,EE770GupSh}j#[❾+O_<{Z{.If D19$i+8=tHxMX'ruuR($.BRzxd·ͫjUuuW}80ӁpR.YU~Euʘr5+=)اqKMH"Zc$ ذt,5{R+'eW6&V!3WND\&vۊb-2ؒL޵bK}q5#=Ggo Ed(~;a?Etfj\@(@?wFݳgY-|=~bmzUMuҒo^7t,w׀kbKm8 sU[IcH=+_VGP 99j'K'Dq"?4P˯]Eq*V31>(UBP,UI?lV?qFw:$x7O%QRDpVmuXT.N _)ڵ<-jV0y^MgNRϥ㒇2E;÷_kt8(̣nQLjG@r0I to8-|Q\ GRZ`DqwJgyj爬ypwH#cYo*dgߓ۵joQ<-){^4g HM:(nBk2/`ұl*rf^?.}mP +5EtMnf]'\mi{Y HdD4 %6wMY b飭@ǒaSrj8t,Eф(/X Q9E2\ALVO9dRW՚^:ֆD#&UsE`WU:_NI2v s DŠ-ݜt,;%ùR(zh-}[U>Q#FAV?hCEL_hQUߴ,rCCGx!+_SDP:(n>c"[y(v1$iS"YњLȯN৞}{Z&n+2mJxݒ-9TIkCnC`HXBLC$"D@p"<͛;㷶&vGx:PvERqRCq)rkpAHھ|^Q,= Mր"V^ #M8׺-9\s引P.}|s(\LC:_}]}dw@Q{"9\u[v^:E+2M)-WI28;@NrgNHDzzD1ؗ.9}3~'`+/cL<脻kmbE' `ߤ &-c6,K_W~ێm]:_I2W,}X2~JWm9'ݓeS~QW$NJa$ 9lbizpnN@:'SlKk=Wbr28IVp{$jvDd0h5ΦD\IWmQJhG,]:_eFV$SkBV^ Dk2/`ұEO;_:_I2W,}X2~JWm9'ݓ%bюXt:9(d&,bAU[Ļ9X"/GwϸV^ MGLz@yΎPIKk×.@5[c Q:d(I@rjKW,c@ƹ$xG[y(%pՖ!p=X"11W'S̄]ÜEQl14C@rjx7' ˘}t61!̿q[y(&'# 9$mI׶aX' 97(nBk2/`Ò FcK?k ltpՖ=sB2]w/(Ir̦]ZGV#EB@rj5"KI4E% صC!˭DYoU[SsW{}gUl?bsH&I[97g&uHvܸ+ QFx -dtU$b1M8~&Zbr%H% NIRUWڊ!vsm?嬈7ભ)UX9ꖫ%貭XOsEllN$NfWdGI^؂ؚr1RU[D{d,زo NXOƌ@GbnwTrjd,%{_Q][1&K?f DǒU[Ap$c)骫~GIvmŐcb9rQrV[+IVD~]M<3պ&?Νk@E(.`CW|HKY~,4-YrIWmyNKR+նw_mae@h9VE,~ϘZHWmyKRYY,;(RטhNE~5iږYWm:]_QK9O-C{t8դ G@) [y($L{-txb&`kGǜu]rj!޸"Ko:m'xb(;U$Ƹ$pl Dq89uO$%%ci 4{ҥ o鍣qoBիQkipoN@2[Y%Nė}1eڰbrL\soάJ((B{!&l&QZc$ ذd,$ֵY%NaPct(#`+/$-+tZ8o1|[uV^ [ HWmI3d,c%Dz J'$båA6[s?;ભh)QX  J'1ƭwq[y(v6%p-$imbv/tN h15#c:.9\no\7v| ŹsB%5e+/B$PEeF2Q| +Cc(#`+/$%>u?p l۶wQ6b,$iY`;{%ϟ-C5#M9:.9\q? L#/%Ǹ;“lk_pՖȌHEX:bt~ Dq8q!U[mV:v:$5聝bt~ Dq8q!U[mV:Wīנ6 `:$_2)M@Yٔ1ભ"*[X"\&s@2_eFV`~lxh+/6MS${sұ4);`gL{m+/Ŧ#Z$j ұD"\Md2,H7맭@7W{@@r0Is.JZS޻]W7/c+K}j޵Ȗzʉm^Wy@-,<^ Om F2_8 KLS$sұ]%ܼ>{{,GڤpCw&EOd6-~3?fk[y(6Y" 9\U yQ>o1IujS7V*+]Q GfZre*Y,nO[y(n'6D@rjJRdxEuC @}"ž#7Fbp,Vk羞[]ޫy[.c=+ӫ'N{+ߺ8.y(+V_vc|ԣujgv>x&ȏ⇅S/GW|& RRn2.?Umw<=/W6R߿pzM޳}sp6o>IV^ @@r0IХho/US<W5{RG2LԲ硁:`8->u{%w@ĻG7s"Uv@"@T9ŷ%ċ*uQgm]3]㜉⻖VzCL`_SO%;BMuCRq_SԾ=ɇGU;I5YS\LXU~xbT#{KkC !`k,!IH&I[CeDqZte1ƫV.pE3/HK/7):A?;\Dq~EutKj˩ٟb|Jm*ufU+rA0is Hs](nBk2/`ұ^>n7E{UB/kC T$9+-}bC>e %$U|Kz:MrF2_]Y,nO[y(n'6D@rjJDz)ְ(x7lW쿙 btD-]2|Q(Q7_jqC=~vPح#>mj<Ӣvە8[e"A\r:/ Kgrn Wm7ewQ\Wf]) _#+;XLj.yVD]Q/*?>wHR(R:$)䙆`V^ C`8[H).-kcvmuEqe@C63y0vq%UQZ>Q㐏J^I=upJeEb|e@l%DqYP%+ұRWmɶtJ w(Ѯ[ͫ)jqs۹G;ZQfmڝX[Qvţ&q Cr+o(¿f9IݼWoiGGa` Dq [$| JDz{p4-W;[Vkp׈-c[+[gym-'çdK~d8-ߒ|b;9m|ua_Q_pV3)X%_W56jOt9c␏3ṳdkO49-ux|q^=^-o;[8C"Rؒne쇿KhgDqI@rw]"`+/.eLD:IR5Ţº'ΙdF6.&Kb U[N XEoZ$ճ]FQtZ9-Ꭷұ Axwd3 z3|}n+/žfL`~KWm^#K2Hk/́F`@tV^ L]ڊ1],}pWKkױ0%Ri+/ƙz 9$mσvPd75 ĥHWmeX"臛_2_Փ=Y,nO[y(n'6D@rjJ1馘 %.ufDY?mY-C6+PpSKkQKx[XB7J@r0Ir~I1!9r".K|itd_pV-\4A@:u ,!#ct@SϋKH_ A.uʹ_eB3J;a7Y_SQSꞇrmխ}k/%Ȁr( . D$ssұ4!TL٪PDߙ+LWgiu:8x}$ oO ջؗ`g r6'Vv'F8e}sD~6Cۯ< Hx(nBk 9$my1'%?hW*F+*^[YO[H% ub5UBoZiIT}aJR1>T(.!p'Bs|&-c6,K#+Dx5jwmc]O:Bnkj9_ϻ^mQ>WbSjooժxqŻo>1ާߴe@+kڪrc(nxI P{Vտ~|U.>`8~.ym|k/%Uda5Ş&LhnKWm>#:}xd{C=~xaKl5ux/q:dG,2noHf#[UnlɖnTIK2:Al?%%$Cw/>أtKǙ'+dk[(Kk˅6`BV^ ˅(=ڊ2;-˶bNx*ZA|C9]39}niU3J?N8]`]AV9U[r$xuK/4ŔNt牅jq@NrgNHҳ[wSNXC0ƃq Dqpq$-EFPP:a?-C f~DqYP%+ұd^y .Gt 7 D@0ѝpVwJYJS9 vffqjC$ ڬt,M!"uHk;9ffqjH&I[sEIj2$չC葀(14UM@rj7' Kn|m>Zf~ʹ׶Ql:دE@rj. K+dHk,Sbt~ Dq8q!U[mV:&ܒufDY?mY-C6+K+dHkQKx[XB7J@r0Ir~IA;IA.$ɹIMhq1U[lX:E-uEPWst`G ׀D`KV^ ʼn 2.hұX&]W7'Wy:>ccg>HkXۺuȸQpՖ$XlI2Q<77EGSC:jaϚ:z9?o7g~ty٫;+jSZAx^SOl%lzͅUueb{ j u9_%,#`k,!H&I[C)R<wl/L⏨Oέ o/=bV*Hzx6KKꞇN'Ě{u٬TzCjҚ:)٧}{wvUQfPa,= /l%D)cU[qETұjq(Z)^ȉR̗ձ%0.V_8v5{ntzupznwͧ] n[Խc|A[1ᡭ@ۈ6mN" H2Q\2;.()˝rQH^M,#/TgVU|bBR\V.d6-~3?fk[y(6Y" 9\U Mt ]w嫳ؒT9F((#x9-'-v dݯ_,u!vTX"ݬQ,N\mpՖ!tAj򉩇zť++W_[V?}~(YuIͱ׋.uKkA`[c QLjG@r0I t܃v5E.'vjhzmP;q$X8M@Yٔ1ભ"*[XƸR\]+\!.}nw^}ݿu޾mj=]pb+ F@l%DqAjU[Ŀ9X")E1V|yimtd_pV-\DULEo>K=L0%i+/ՆHWmBYX&ׯm| z`:X"ݬQ,N\$itι(ɟb$չC葀(14$iއՊ$D1شЖװF2@3Y-C6+KӢq o| z`S>Kx[XB7Jڒ-X"ZG'-w=5y\<}ytďK}Wφjkwa]7 Dqig$8ѭג)NEG=+#1VKxʆ„ԧ}Y`}I7 xh/..,iFwC}s"Zc$ ذt,bzcԱon=]QRܖ:[=>s8}GCLh?u:saaY-??mֳѳݜ8yͫjIupE]裝coڞ}I-~y1 S;m$GL?ppɤ@׀D`KV^ ʼn 2.h:?fE5{udu(vN۩auG]]H|Q^= m@k^M]%G>Cݙw+]#ی}9^ɶZWԱN5U\lIř'dXV?}eMs}+GUNegde-r8Rhދ(=<pՖ'M3j۵Y(V>V8cܳ%ۚ9}s]ف_78y҇찍NM|IuL^M뭗VAx8N-է'Byt4uv:'Cb|WPF@2/\E0#e2eQە5q{쎖ZY}jV^RSpVkbQ<ܛZrbP 8 3).I&I[vňbbC"`QP-bD1ؽ,9_;5 }|E@r0Iڪ<A# DH(0B`:wr?xD()K$a^S?zjEpD|#`kA+x<`jk+/Amsߗ' .[ݜ$SS[.]RO<ڻwX#[۬hVq@ (DqPiDg4TC5 ޤqDqZ\+Sx NB ! 9+/$`kA*05Yk"Q `jp["=l?bQŶ}  @ }nqE3zI^0I(6Ul[!`j"Q 8j"L@NdߌQB3Ț5 #Kkk0ir cl0 ]:bJ(‹K=5 ]|!`k0/"z 8ꡫ4Q@V:bJ(j@l?!FW LxdUf"QG _:A 8ҲQKEO[)"t5ܠ J(Vl?V& L.374%8jJ,닥PkWzfkA!F` ƑApą J( NnؚŁ&Tݲ5bfN#8 /m{TV:A E[WQ\':\[+H8 9G&PU:A aQl2ضB`Y@G~xG=[v_*—(秭qDǬp#O&MKbcmJ'|yyGQ]pU<  o9y{[KE;5#hH@[W?3 sNdyCIQvo[b7:5:̭JI VCkuJ'(5$4f}QMQ[)4DuJ((1}u=Ȯ"0S[bӑ~l ;J$P AME1%#l#=J\G`WAMuJ((p3v&pܹ=^^0 6#$`}Qae[)t/|J((?uzZt%`+]#5ChH`V  az9ku[ QX"NwSwϱfPP:a76J$V!Ϋ({gk0E NG҉ܺC̯qc Q H\[:x J(( k2̯BlFl ^;Ic0D C=4a&uˇHDs^$o##j#oT6%p-`~m[g6w L3ix\& Wwzty[J>~;׼oVoJWiwiդA/)sHWVެnJzf37>?0𳷨7ݟGXQҎ(n4<_le]DL1Q+]E6uޜ 7&eoS ަ|lcoVouz ԝеI򜒌:x(t5W?SݹaIErߑ7E?},~0(n4<_le]DL1Q[y}#UxrVO b9x(֫?OkũpP.ǵjlQhx06- 3Dqˀql &w4QQ&+s5բ8B;|.-g>SB{3LDDmQ a_wJ$7DqF%[y(n0ns.<&NW&oV b-\e?FʹҌFqQ,ݳ1;l8֌ ߶SHZ@;Q\I2c׉DqUM7OTtO#̯5[y(50RfDkꖒ>={|n\aZDw*E/X[gX3.~L#kDq8BgQ jU'KvTQgl%zrGFN3N@;<_kk Qko[)`tͤ(N~6R-9(m?S:j|dj'F{gT&۽kڽoL'-u'G[!-ye~5I[y(&#`k0U)ΉLPN5M7>ޚpqKͣg>;}wq'oUoI‘6:裱(+͵@5\_"w; Qw{[)Ht@SQ<*p'S%ؒ(g~m[g6w L3ib]pz6S"(n4<_le]DL8ԛ>;bTNQ]Ax:J^ODq$`+-m5%g] +ҥKܹsJh}YoR[Q ~_ Nbck>;[y(;,8F`r $k^xa,ݫZr3%s[ԏ}MG[<<.SS,7ߥ"~G;v|Vw8-\MQ 9 D1F'NMqED~xm*QO1wO?W%LXOYyz80qsr FΏے=KxےQ|>uݔq{z-ɉtnQ%=yoxO"~o~㎷''y{NJ^i?Ӣ8Z,b~u)b+T=5\k|VQ֪Q+KjMu=EY?P*/|}~#&ѝ^>aPzTOD ~V}P{~ >я@A5NZKfEѢYZ:^ z1B$(1iCQW3xAؐ}ݮ} ChoP1/@#2QL W,CQN,#]h@d^ C@Nds,%2LD[҉l0@@t R#TP#YلM EdI@w!cPÌaŖ@2٤M _@qȗNPBw.{Dqэo J(" >](+(r["(fNPB!K@J'(;'B=8Fԯ J("J #PV:A 1HQl>M*B/V x S>[]?yěQZD#Ϭ J("K Mg9C;-@[O2Lzf X"08=rG\9ro!G7ՙA$]D &](Dc2D|{M&lhϙ;!8 &8#^#Cj$}j2aSBIRM@@@o(C!Ŗ@ 4)hϙ;!4&##Clj3aSBxR=@@@o(C!Ӵzr@_bwb'B@b@+)2DqэoLڑnC 0GL -§i3p* Wr d␣iߘ# <݆`~5,@[Of0iU@̯@!G7Ҿ1iGx 'j1 X$(`6_Ɂ Cn}cҎ4t0N8bHQl>M!m+V!0!@HƤi6 `q4`"|6CI WB`~%B&(9I;m@8Wi"DE4mX JLQrt#vq̯ӀEbi &m3\ @8F7&HO!_#ӴLfb+92DqэoLڑnC 0GL -§i3p* Wr d␣iߘ# <݆`~5,@[Of0iU@̯@!G7Ҿ>iooEΧ7Q{6ϩR v!"Wߪ˿juu?\6%TL%fdR~/}oD;EvW.KDo< QRt%0׿Z]ϩU_"Ķ^?%sr&:xBƋН]P= XS@QѤ5ԕڽX3pcl~ja:mBEOx?;fhh:NK?̩kKS5/'b(fs²o 'rgD\G5{X7Dq80fv:VMjU&_WOlrקH}F$+&(ЫտkQJ:G[˅(N6а͡%;u'&VbWTr|^o9v|R "ZJW/|DۇWUW׿%Бj5eS]K5gf?.Ǒ7K$ڢ#ɄNh6o!/?X"}rb*gܒ✨gշvґҹw7'\]c>Ԝso5^h[S7?Nk?_*/3ofz>B!kL٤=G߫vWԉ痢ןSJt&Vf>P'j^E㯪ީ9D_*K&Z[?~xV??<\= SK~w@|5y=j~G޸FU~?d6SV~)ڞ}Z~vBA:c{0֓k;}OU#cfXƉ @(#Z5?cth>کb,+ҫ8Uh>8OgDqŷPEM( +SŶḟי7fJ f>V{&^?8_ީ>3&Fxw Fn/뭴TtUkyQQd]ύ:x(t_uebRnpZza2\sbYsRA슋ln!)тvy(n0o"tS&D>m=9R['?tXRԟhR\?5[I՚ŞS@uJqkݼ}sw5o"2c+<#lN=c/d렺v}oV;Y/^WWU:׀{6qoעwDq3%=Lv|Be{wzGgBJ/(Qy(n0oR0='hi?%&]!p+8{0? /MvW`f?6C5YU/$z[wE}tʙBh\%FXe[w򙰓0(xxrynrOm&vIjq;ՙ7/s}аRz1fv5Y>٦{'ES -[ޫ~zL'՗CBF{SGCv6%UNԶ=e[=R&n7Zvp }ڳTؖl-4c՘/ fko5DeXrU^;{686ޝ9q|0H1%[h&S.=˶3oNnQ6ל7Y)e\ 4H˥<41_7tCtWno6|"]vx 7J#[$CvCz/@>li|jb}K1!IC+NCke-Qc7&xնw"F9|VK}Ρ[5'\OsV]5&mn7@k4(vÎ/`~Ǟ@gL =`8A`~&QvQe4vw=̯ӲybigL=9@ ̯ф:ʎ" {؝f;G{Z6OQl1-LIg4DC5PGQDqaLaǗA0cO 3 0i h0F(;(2awI;;@W{i<Dyƴ3&힁  hBeGQ=N3i_z#j=-'(6Ϙz&3p!M(8ʰi&K {_eB{Ns@4_ uEG;ͤv| `=lG/ro]Aӓ p0_4/`֜ư(D(Nycz1t:9O Q\NJxp t55:nI ʁa &{XA qcMXMP\(v bǃ{L؁$@ c G˱4bd+Fs1!fX?%ZAKP4hd.1!fX?%ZAKP4hd.@cO1@4cd+VwcdCOɱ~8K(h \LRLDO9603XDJ3Lfbbrs,y`9f}DK#LFb4G#b&@~NYDE6LbzH#b&@~NYDE6LbQLDO9603XDJ3Lfbu9F6L9뇳D+b m0 4+@cO1@4cdRGloE.oj={1X̧ۗ¢Z^RM6?ϺP0 83agB"$?jjqY]/A9堯mŢͲkenU_9>VgQYfsJ:c= HʲoYk%nڸV&3յ|8c}U]禎+{sYCL+i(vp/̱ʲU~VG.aX9.dd]Q<\PYJrAqr3-aŘ6weޚF;:g@ Q=d>/ּ ˼J=0W~!rW:5}m%Jy2"Fq1̷!S^2$mŎG͙(.NuZgxVmhK'C,:A9]Q\jF(.̣y %ڲQ\3B\VBQxZ2aO+u&I;M'48k<(v|$ 2֙+ŕesnmDq?[ʄ]KK y[Mi*۴RkCDqF$;,[h0Ge>Ѣ"Sr78 +js̚lQlmg+yɇ1OEHEq-^UOQg6-Јbl';s؁B-kcQ\sfΚ:mVGЈbDq?sέ[qež+w jlKmJJdSjʚ+9fAG;Fgӌ" G_ysj(ǰN`]^|"3\:Xez|&39fX@)Wg}XЗg\z<_JCoQ>1Wy&37*H-=(k!ZT-9ؐ1I[yDac8#"]hMok1I[5ݏ2Df8#"]hMok1I[5ݏ2Df8#"]hMok1I[5ݏ2Df8#"]hMok1m/.]{jv!ŎZz09]ܳ@&!@;`1Wm4 x,Y8rJ]$)敪'Y!~Wb {VN*İ+.kK5qI nX_N' D]bڻv$D{@x_g^' VboI昫gW 迫sڮ_V ISAQ$ϲ3;(\^i!=;jZ @x_5OOσu^=&]jKvha]_'cqD{1PwA 5_QÇ7t}Zl͞.xe(~ I]w\|*JqjIUp5޺G u-yش(׿Z}"Ko˕I昤 >D{Ņ $;PleMZ|= dQ=%[=QdΝrssUr_XI~'mĪw}.y3Fթ7)+8&ps)Q=0WCPڮ~Xyemb[MDtL$sU[ ے>Г˹fj3\}T}pdb-nZJwPD:|W|jJns$H )N"= ] =t ;u'`} s̅}{;fplVe# L`^cKhpxGԢ|tCvjjq;>Hpx?ǖ}]h1_+4]D!!Ȗou5\f6h wS#\9%dvo6vWsUQ,SXI;<:#PW7TVlAsփ1sx80N4 g!1Wm9RAwǭH'6y֮)AvvFaG6ܗJp*jKԡgE|I昤Qw3BCq+gּ#"h=[gumq{09N@}ZKw҃ u ½#6ձ[Aގ(v< {XA qcM昫~j2DrFIZ9X*'@1 c~?}1WmC|+b; 9:9 ǂ -AK:1Wmu͈bQpg9f <:Aw" A;!c޲sx!==W' Lp5\te0BΆ&$sLV(šD~@ 4I!+i+P"I? @*DUQ4N 3,_C@$,b7%sLҖE$M#Eqb b%Ȉ5~|\k@"# )d%mDq( `"*('̆Ql/!@ HmYb|@@D@INQHr @Ka K昤P#C$ @ hBVV(šD~@U h3fDYX Hh~ڎenoɡ(0lA X bb&r Q 8O|wC{t'` ?=O< #Oo v @ {G ,5AqYkup# @/H9(79 xCMp4 L@+uk @V X⏢qr QEI@=9(!O"'`<[N jb4rb9}@ <D1$A@0MC1C:Ђ%-WN7}E;uqY)W]msfJw @@7g @@P@ М93 @8@ ͙q @@`Ł@ 4'(nΌ; @#(,t @9Dqsf@ Dq`; @ 3@   (݁ @hNQܜw@ FQX@ @@s̸ @ 0Jw @, MIENDB`dlt-daemon-2.18.4/doc/images/dlt_overview.png000066400000000000000000000370031353342203500210660ustar00rootroot00000000000000PNG  IHDR]bH IDATxy\w?Xz=]$A@jv]ģ`aJmZ+_R>zAkQDZ"".K+u~L¡Lf&s}d&ΰ{& q=11Qvs{w0YgeS[k9Bm޶G0e6TV 9st"Xnj/?*:ROdȐi%󙰇JM< -3E񹄭쨂S{5盖݅dZcG.: hFm4/^v-""׿ս׾25PDԶ.TiYE?xSԺ#"4UFk_g7lq=\}}}nna'ck'm2'6prʳg=z Mn c7n| $u, m۶CjDŽL޺u>{WXT9G=ZXR2 #m( }=z <ʄ2!2!2!2!2!2!2!2!2!2!2!2!Bq־$&&&&&B,B,=A޽w`)(<5IIIBWdD2TLn #Np ,ATLghy9:t[/OekYߛ=%{#o![rrbS5kCz 5hU/,[o=ǨdX$̘5j&KkZjfiȠP5WM($;AN"""5{|;o!+77eF6u}٦!VM]_iO~ǹno n,+CS*]iW>:~ ZoZ:{83;Lϫ $nJRZn$"~qq$ G˱THz~kNo,R+d[V` f< *S&d2LJUBC3-Wǯ:R,C"F7GF?̒˯e&ϐXVsk͕|M8UXd@" } [)7+afjjS5Jz)\B^ +@2{2!]@v=B@d:; ̻b#dD)@# n #e@&0V=.8I@+ HAXa{4^"u!g^,!3?x^m~D:~"3 Iv aU).*H @QlG*S+;+ -+Ӣ"~9n 'PB[j9؜9=B@xMiD얜,eBG8Y:pP39StM!]@G#d! x)ttPAj}x &8"taLLH鹏?kyVRL/FWm)QmUId8KDuT9ԣqTADV6C㸣ւ.W n=wWA_~b-xޯ~^pO=ܲV{0(N#^Uc:= xDDtVGk@,?}8}ܹs0 hz>W&" >vI'njepQh,[KDkϵzz,!Z{_;@\+AG>SARODDgm<lmMm!HN 5^ sS%7984d71P !5Z¶,V "SklՎ#ҪH'}ёeή΃F8/+jGoSӷ O{|3/SH !PH'^^@hil>3 a)5 TaMϦύO,D5;7ҮkWjPj5DD¿g^6s- #(o͹LZQ)Ck]hޠ2զMM9t>grxVЮgw2B$x}I&""u\NM{kOڰ`},[g^}1m3erX鈔%tDJj{""*>j)%[9Ĺզr`੡ N\:[jolz|z4viٜ*""ӿ;J=ܼk?/_q3iޑJ!Ԏ<4Ɵu&ܘ*)O6___6urv%m]ٔ{tS%y9hnN&NI~`wj"h3~ 3[!tRuBT'\!%'&ݲ7n ś /2e]w4k,#lÆ .\t'O˓:"L2Ee/ZjÆ !8&T /.\Xzڠ22o<UVIH!"M:l櫩jdR[fw-ܞ_DEEIHIܽU'~fRBnvs%5Ccnhd]  gϞ-¼ul^ C}T6_$ou؍}#[oަa`a{WgWn+}C-G[ny+5#=1ѱ$}! Iϝ zu5?H !V?pzbd<|Ӷ-iTF}S'm/H%'x'kg.\oQWjRs- :uX_3+ Y=*G޿|wo3%轨OSKUKHInv~ U'Dd''vL/xk<((Y:q%l ADA uӈ,s}g''|vh܉sRG 6/寐SӃChHV{\}5զMpz푥gזcx[ED4kxGk*[oUWW/K(:Bګ8M0I>c9txmvŹw))b[oWPXGf>Iz8r~}VQE䩞ϻϱ3";<({MLL\j륎!kzN*'8ͦƔNt*ܔ_^ {&Nث GAɖ/_n4=<YRRrBe j .ϥd !`6l.u $#!݄{t ͛ʤW\ٲeQ0b^CCԁ27tӧݻW@@^fA f'հ 8 .^acIJJ8WGYqQ!~4a#?--mʔ)={r OӃJȈ)XUXTHDEEEӦM:%ۤzJ!+S fhhhpsskllTT*J):B $CImeeeEEEVΖ:;}tiiQ,!6P\\",,QjRGN*`ҭ ,UT...(NEQYYyY[o沔(NEЧO KHOݼ -gԒ,5/Aq*?OAAA:2wCG%sYJ0XhQffQĄLQᚵ)BGũ88믇*u +St/Ky(N0 RR(FxxV}ꩧGxٸ*#D.]f/c駟>S ħ~b%ɉ*""I@&[c><77W@&#|T-ZuVi#ڵknnnRBG(|MBG@wՍ;… ::B ηHh999}:nb&#IntGF.]tJn(~QF}RAG8FFFرC@ 2L#8rg͚5_Y/g3رcD&M8\v*sLjTWjcbp999cǎuss:-̻CZ@js|M38rs޽{KX :uQm!# Gk<#Π2˗/k4e,u,` EGG\R@&0&M7nH :BĀ]ƏzV ;44T@en #w3L !vc#D$82rqÇ?RBBe @FJKK: :B͜9󫯾:}ԁ:BmܸjR782ߎ9UX:B jvCCCw-u 8q>xWP&TX vnBG%%%eeeRbgpEEEE```]]Ա8(t؄Q8 u K .!f@-ZoHꯎؑ&www^?zhc[-'' !b/ ,())?ɴ2P7nF8g `[Hm _!:B =o333t wG?w}R7 n8pOv!n 7rȐ!*J@K4" =. ܴ/RGLŋz-%GƷ; !vy_a.\uV顺~I=Tb@WiӦ/'N0/;~G Cp֫WX;# 38%==}رDtʕ#F?&@C /W_kdd;0v!'=عs""" /KnBAG4^|EOOs7rȉ'ˑ݄;-0̎;Xݰard7¼0U} "~7d7r #pCə1cG}wߍ5/:.%VCE|e˲}-[999RebgP*c=C}gLc71+qs̹tҷ~ۧO?\L^{vM~s 8ҥKR&g7 wGFپ+wwӕ^^^ƍ6l0RG砐D#x{;ww9nhgj5HU@G8;X쵔/s%MО!vG&Th#W$tLNrKƉrp oGMgu:B FqyO~aejY7'M 8,1M7=/nĠfSM/ʭW_8tQlM_~i@G5](98NO:YZ#qADdeIk=qMure:}1{n{`|F=B`+b"L%fHDLY%k,/R7/ "jkj/nLTYY2*++o@2FP{e)r2Iel"K:^^^ƪ.އ#D JR c1PY(3BHGůC1DdeI'\yܸqο?qܸq) :B T,FLmvK:9[~6+sY {r#䏦7g=WXzs\vFt&>i%7y5\?+oj7Joߝ/A.Fc;X#۾y W7v֜~|cAwdoړDAއLq2U}z֬Y~q?aM*n"֡Ap t:B P={tM LI .tC[pT$82n9(:Bl⡇jhhRCCC=$r<BwĤٽޛkOx셀 CejZ6;;KYYYQQQ"l",,jå @1rp!T*"7λږ(KD~7[ihhpss7/E!6dYm]dIDAT=B<pVSOIzBR̥͆ˏ?A'p$`Y,t S-λa@_666T*r┈P !6je)@wȴ29|ݑrdE>PH2AxͿ-"u!g^,!3?x^m~D:~"3V da)i䮤 [ Q1 `f_c"3(ow}93=B@>PB+w;_Bq"+.*|n ;'uh|v9vÕXNINa3G#{rrP)eKI 8:Yq|&X1 <'0RSLrU)ݩPtFj^D&;:B@xAvpt#.#Įg^@LHf@Gh䎎!FV#wt| ZH>rpK)!]2:BDu$}'k݁ˋ[/x]kE @NdZbҭ+?:yp i oԚ}`oD!`vL7}БYit$~ɾK 2gWA#5EշߩvG{ǧ=>l cU qd7XUDZ(?!WZK'ަԠ+PՎgU475WD>flGRw?7>|SH]C[6 z٘C-.ج 12/ߜˤUK249f_uvxCA)!RGjӦDT39K~3[VҾ~6z2?}tDV:"%|mtyGDy=7"&Oё> *h碣Ddut͎;B O6$""{bJ0%qDiܨòu;X+xj@A~.VDDw9^7lZx6R7<~bL/|w'ު]XXKa#;_nG.ÆKqV_DDUyQT;UsJ=ks~IXUjԙsc",0'<9;d{(=*Y>}]ު$""۸8u*hsswt2w:W46y5}.h^ =`؂1=ٴLN(2:Ҿi8J R~to_BD 9%& "1oYKDDc_#" KA˷z+2-Ŵ? Bx`W5!w7?BRR-^^q9MqDD6+XdzMLcGW›_[t$eU#zxw5Պ_^5wsDO#i_! $E?;^@7_Md8jnaߘ5^;G-k/nX`yf->| xs~Icٹ}G)>F{ӧ,U?Fz1΍s=.=g '"6?J6<%q0̓ 1 # Xlrqn>sӚ-n٫;ݼ+ RTXƀ%Wv}30wR՛QO0CGBx.̾}VAG@p[ǚڍ c[QmaVhsƜ\ALRlܗo:4ƽ~X76ȴ2UԼgpy=޼0V5[oL?:̽GuDTf탣Q>X}[B4}ύ{ǻ=>/!":4`HҒ~ u!|5w>2+U}X}Dap8ߣN! JopsĦG~ЕkWv2]cH4;wC oyq© [@T6brybbWsc=`M𭍘qÇKF.Z٭3hz!~Xo޳?#z;De GjLmgPVCDDÞO!<""*G4 6!|3jSi~~llwF{{oOWSɿѼ#72wSDG[aLʘ$[.6*y9t2ŭ*RkyƮ.N<y潈{ B@D=· )iiYrM;5}b1DD1>=b8V[FQN.Eõ 45[Xf|zJScJkq=,̾#"z_]]4W+~}b)I?o89*zDB >KL+M^j4zŲs=xe '=u ;KhCN{>nڝ'%f>N6ݩZ:S.Nўse$heŀ.~}|4]}39S;Pd'Ư0`fJ%uD!k:tHpN .!+S fjO=<(uD󚀅V__R,K1 ԆTR8;;8bCYYYQQQDrUV-uP&L;B4h˲vS 8QVe)ƍ...(NDf+沔8:B!C|C Sq\[c,R8 *S,KhŊ 8:BlҥKaaa+V0.^(Q\rP&ttM 7o漏[c̖-[._,uv@֌;B@4Lŀ >t bgx{>R w3M :{: ;{tʄy7P,taΝuuuRG`bg&OaÆ~X@!v!*za[b!0.\0g7X(υ$Tb^jԩSQ0LŁ@|nb@vz)OOOp,w¼((˥ !++ٳRGXĀ! @|nb@vć&d79IC5kQ8\ +@@pSNIcAv^?yQ8d71#@|nb@vć&d7! @|K ӦMׯQ8\ +@@PTTTXX(uM n"Cv:Bćs@8g ʄ&0aT֠ctpdn2djpxnB2B3)3͠cLt"6՟ՠcSY"2A!L*$CC1z.#PsqBuLmYȐS6ʍD2L5 O ? ׸WleYL)ׅDĔU|zc+IF[c}Gz R"WQ{eFcL?/5gjG 4ҬFҬHo=ܚ,qMWHBiPgzJKMj/,&"6_Sƨ -_B @V M w: ǂ& @|N,1< : ǂs@8g ʄ&w}W( Ο?{IcAv:Bć&d7! @|nb@vć&Z=gp, Wbb!B5)'DD~XXWW}vYX(=Aλa#?|ii ¼H >!yl m O얔$) @7 FP z+d71  餎{ :5-RSn93lS;'=:B*ɉ2B+qӻtz_c79n1QZs ҥjlC(0~CδbSSY[?mt@W P{(Zg CN&#qJ ɘ~5"*[u<T{Y}=blǦFgiqQ~fw*u,P~YZZVɆfiawMt~^j+DdRh,'L>٩R=CGrJZZQ"$~qW:8q²պ`J^6 Y,GSieqƷefiM:B}wd)X4viҥTj5&!ޟ3eef=Q#Ä㺵GpXp~e7n܏??qss3?7NdM{9vpH{onn.-77(.Yüj6-+++**J:Bl%,,ZgpIP>t؊K@@Ch+VT*I)ˆߟ}A˅Z**9Pd7jhhpss7/Kf7T6dYPtN{tڵk/l)@Wd: =-//9rŋQC!#Gnܸ@Lw9V޸qe)@dZU|q믿e)@dzrqqyᇛP e)@1 M@LaIkj:5"|=ym؆8:{y#lUh[2@G(@E?W2 xAL@Zw;_Bq"eLI(;B'$s='I5BsEEK==LBoGHM.sR *BG(@FfOp#lrU)ݩWp(L@Fb t@[@G(@F:B&Jd!vI!2;x oe¼:B@AveBe*#;Y/\+A?^||bn)R Ww!tM7jMO >X7"LW2MVo#ҪH'}ёeή΃F8/+jGoSӷ O{|3/S(:B(UEU?h/%hil>3 a)5 TaMϦύO,D5;7ҮkWjPj5DD¿g^6s ,6+H_972iՒcD MίV:"e m+6G@dLm dO""R'$Ν6M~XnkuO (04OpjV{c#릱۟M VQQ=^Ǐ~XO4Gmx/iJ:nLDڙ%SV2'gGLwe#R6+ԧO+2[DDDsr7NV%ynnN&N|:&EU "?!gl[pr޻=g>6bߔI 3R&U'\7 G&UIII*qWћ':S\E6 `=Bă a0ʄP&t# W~DŚ.j/myLDiSY[vLV akjv j?VtLiN.߲{&lvDZUܗo:4ƽ~>}z+U;&I{zÅghU@S=űYzAd gpy߂=1>iF.}c垷V>XfQ?+F{dnkYDg^07P*̻IxtwVz3{8={L]|_\Y=;tlZ1/"[y%tLA9vgDu; lk{8,̻ݤfw '^O2T|ex;iF?٫ [Y @P0d$sxn֕Vx/9T6{Xochcqy7Z _}9jCv[9oAD0&י י:SpX^dD{#D<=B@02P&# L@Fb tb# n #eBG@P#.#@4BG(@Fʄ.2AG]BGhP&̻Fw 0R7n z.3bi#dD!fT  dnnȈ;Ba 8Q+@P8JGAe P&̻# !]@e 2Π2BG(@Fʄiy-11  pB THL@@@@@@@@@@@@@@@@@@@@@@]H-K74\IENDB`dlt-daemon-2.18.4/doc/images/genivilogo.png000066400000000000000000000225011353342203500205140ustar00rootroot00000000000000PNG  IHDRB+VbKGD IDATxytTE7n @$Ed  0(*Q~cQta\8*Q"2 P@ [$$$}%No]sN#<]JQUU2$''ȑ#b tM&fEdP_ӧ6l`p6Da!$a111(..}AAիg`FDq ˠla!$!EEEg@&Dڱ.y ȄH;#$a͛7Ç}~vr ̈(0Cn,dy,$ȑ#+ݻ1m42" !I( >#Zi׮_mmEQ*}f͚sD=B27~U9D2pDHY̙3x ̈#B2M׮]?zOQ !?)Jz1tB2c=V1dBvKc2Um999hԨAِ]qDHx<>;|0 #B矇#pכ !gÓ-[`PUFǎN(`&ozj?>ƎkpFDڱRu-[xL߾}_>5̘1"| >#2"!iqz:fC$G쀎WU'"XoBؼyBH~% XoZ+k=ĉUWݺuӒ&Q"aӧkի(PR@222>v͚5>_~P&  ![omVqƀAݺuxb|p8>_}.]}BB~8YS[! 9y$> h֬_#=\$m ! 42{1"mxiLZrp{JȄ,d(-c2! !͛B2T׮]ctIB&DSc2pDHAef@!#B2\nn.nb2"㈐ רQ#M  !n~ױPU /nX4{:uj+SN!//nxW_a޽p8ܹ3zavJD\cWu뢠aaafE?^_~.pY^3(+"cҘ={歷>yرcpD=B+**BllP -޽{Ѯ];@aa!n8"ƍ /PRW\:͝;wS^76:th}]uAg,Nh9mdՆƄ}E`6mV9sXDpDH?~8uTů9N4k SwMxڒL|*ILLD~~Ԙ ,<\.$G;=6]ÇKK{^}US!Nm8y,RP۷)Pa!$K9g1ɾXIw˗//IwwnDDTE[vXDGd O֭+,џqDhCeee(((@AA?~\}DD 邅&f͚h(!..@Q\y啺аaCjnCQ3g|CQC|bccj@}|yt{!,22R(ªzrݸˑ]&LٳuBt aJJJBnnP d4Aݺu.gBv*^СCfG& 3-[H*.)Eػwoك-Z@Qߟ#aqLz\7t-¨Q$gDVa]`ڴic_~ u]ܹČXCHff.qgϞK\\uUolݺY/Cȥ^;w;XN˗K/^[$ka! !M4ct,^StdC6;j]HOOGiin 8Pwyn|6m~%vɘ1cxKNgG%tqDBzN:~O?AQZ vmp\x<ٝu@0L2E{^x]t (vyyy@֗7xC8Fm^ s8qy)uVDH,0d۷O>%կ_߯d|ܪU+mX0//O>,!fРAp\>|cx)}:teeeRbt鄅0zfƍ~[Jp7jj,-_tBϞ=={gJ}Du?|۷}9$TEAii):B}a;}4n݊uz/ wM6'MFN t %%%PUäI0f3+VPU>h6lCL͛'O:t+3,7өG1,G/-jРAnlp //ME\r%طo_pI2LUUš6v]aEX"¤ 6 666s׋8,]T8_n7ET //3LQiii>s87oTUe4G7|pV,5ܶm 8K.^<¤=ھ};:v(%?^/<O0;wF\廁"33Sj27?}j1OX"ZzXn]HզMoRb]r~"#$@iifgϞ a/A tM}c7Ǝk|>^}] z'O xN 3`C!kb!$K[h!h}/6ӧOGƍQ^=ԯ_M6… u鋴c!W_} 6(JJ'VcCtV^]g5yd(,,ѣGqCQDFF{Ռ-oĪUj=hѢpVGh d(hרi 9~(oFM/B(FDD^(--?ᥱ(ʕ+1tP~'O,ޗ{G}f$0E -T tEsL;vLs{ ٳq \\SN6lX?^[ę3g=.::Zx_~Őܮ111Rs)++CXXԘT3B;7vO ފ.qɨ5eٳ'6n(5&Ռ!O}Z={CF\hG HKKÇ5Ζ^`ɒ%c5[nlyfbSU,TMBUU̝;Gͧ3n##FRS^=mrss%fSYNNn*N5?~<ƏRZ YYYFjj*v튫ڰ'7mڄݻK-HCC -*++ 2e}_-1+ v4߻t\8p UBHA)** EEEz2dH^uU8un7ZliPLxiLAMQJ,pN:&fFB4; 24&"c!$"c!jy<̝;.R8q4=B"--;wDbb"N'йsg##BEQZ]tAjj鋅 4߽{7֭+1#"ҘaUVȐt"??_J, ,66o>HB"cjBH$`ǎcN2EzL !ÁqIJEc!$ot ǹK0zh QX$x]̈BHU̝;bǎ曫|߰aC,[ ]a) &:te˖8"$"c!$kܸ)Xr .3?BWiԨ(f'AgOtt4 鋬#B{Y !Yk{IIICKc,/oߎ;ɲnnX !Yš5kǍ/=./Bb%$$H]BRp89]G%KḦBG4^//v (,,d$X)L:bݺuhҤ"##1|p'O"66,)Ҙl#B"=B"=B"=B"=B"=B"=B"=B"=B"=B"=B"=B"=B"=B"=B"=B"=쀧N©S*mjlߩSgTT%;e" a~~>fΜO>χ+ZEDD !!z´iӐ"FIi!C`b]sټy37ok/"fΜmnn~=z~z)L8"_ ceqWkn_ӟIQQڶm)?5_.]ӧOu׮]5[oկ瘘Cۚ5k -33Ss?=\>KB#99c#z Crr2~o۷ĉ'N|[N,X ^g _~D|RWX ۭkFzHLLwmv*TO>eeefay>3Ѯ:4kL^2q=z7|aѢE?ivTS U?%fRJiӦwhiӦ!''4On7̙cv%/s-$f{L^*)* 5X$''Ut_mKKKQTT$1+>3~׆thS_!u&kI`V^-_IX6'O6;Ƒ#Gev[oinKȿ0}t:4ۋ/hv CZZxl3BE[8HZZ7c;w = )[nh۶-222^|EL4IRf%++KhRDDDH̨^s[iZ8D꧟~ҥK5xIt}/_.'Qhj֬5ڵlZnP{WR&sJL%0"CatMRΉ 6hnsNx^T6h m{EQ$f+T;ӧhu1SyǏq9E޽P{Wq|9~8JJJ4ߴilk$cDDD{## #=쳚uN]K$0 wyhRTTӳgOSwyGJ;JjӅڿr7J$0 =:Y5}N٩Fvvp_~+ =Ń>(1r} BئMyEQ,Сi)))hݺpY lΝz<MD^ȐΓt'zJJPp8pldeÆ VҷSå_K9dffP3f㭍?Y~KdUUxDf3FoLft[>waj>C ADDJKKGaaPPӮ];wyХi^^P .j/-/9?0pi]VB6eժU.YDo###-- !#22Ǐ3p@QD/={涿VY 5w\)qd/- IDAT Dպ50ee!Y>|X8FVVN>-!{in[^^iE>Ls|液ٲɊ6m*|$dZD^ݻw@gff -&8l,d>Qx<HdI^:t澬$ !/1uTK&4ԫWOh=zH7[uCB$C9{l@_wuZ 4h`Vm6lRS͛7CUZoS]ta1- ka5ZN:B/ĵ^+'T.7gL8crss57kh.۷oܩR>\.]J>}H Diep6oެ47|Sfh]k[ω'clܸ'OMhׯC E$;tIs{=i.<4ѺYuF$gB4h ew J&4_^sۢj5j易'OVo aYYi,ѬIeԩS 6mڴ\jSLVoBO ^5 )IN8Ƴ>+JDϯ*99Ys,?wL^CÆ ?銋_ kիbccԩSo-111HHH@BBЂ˗/Co#Gj'ORujjj&.r_ùgH[V}uCdnQ -vޭy3gW*3D,]Hٳk}#c 0=cɊov(y'Mnݺ/q'a[ ^0oLh|"x\.14B3oƎkxZ8`ǎfaiyB7k ODfh+zAۻw):u";=z4_YHJJ2׶m[ӟ|m۶Ot: KJo?~ܬv뭴|^E8ÇǸqt듈AS!$" %^8IENDB`dlt-daemon-2.18.4/doc/mainpage.h000066400000000000000000000017651353342203500163420ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2011-2015, BMW AG * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! \mainpage \author Alexander Wenzel \copyright Copyright © 2011-2015 BMW AG. \n License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. \par More information can be found at http://projects.genivi.org/diagnostic-log-trace/ \n \par About DLT DLT is a reusable open source software component for standardized logging and tracing in infotainment ECUs based on the AUTOSAR 4.0 standard. The goal of DLT is the consolidation of the existing variety of logging and tracing protocols on one format. \image html genivilogo.png */ dlt-daemon-2.18.4/examples/000077500000000000000000000000001353342203500154505ustar00rootroot00000000000000dlt-daemon-2.18.4/examples/README.txt000066400000000000000000000010751353342203500171510ustar00rootroot00000000000000Copyright (C) 2015 BMW AG. Copying and distribution of this file, with or without modification, are permitted in any medium without royalty provided the copyright notice and this notice are preserved. This folder contains several examples of applications using the DLT library. These examples will be extended in the future to show different Use Cases. Example1: Minimal DLT Example Example2: Non Verbose Mode Examples with different AppIdds and normal Strings Example3: Non Verbose Mode Examples with different AppIdds and constant strings Example4: Different RAW data dlt-daemon-2.18.4/examples/example1/000077500000000000000000000000001353342203500171645ustar00rootroot00000000000000dlt-daemon-2.18.4/examples/example1/CMakeLists.txt000066400000000000000000000017571353342203500217360ustar00rootroot00000000000000####### # SPDX license identifier: MPL-2.0 # # Copyright (C) 2011-2015, BMW AG # # This file is part of GENIVI Project DLT - Diagnostic Log and Trace. # # This Source Code Form is subject to the terms of the # Mozilla Public License (MPL), v. 2.0. # If a copy of the MPL was not distributed with this file, # You can obtain one at http://mozilla.org/MPL/2.0/. # # For further information see http://www.genivi.org/. ####### # # DLT example implementation # cmake_minimum_required( VERSION 2.6 ) project( automotive-dlt-example1 ) # # find dependency packages # find_package(PkgConfig) pkg_check_modules(DLT REQUIRED automotive-dlt) # # include directories # include_directories( ${DLT_INCLUDE_DIRS} ) # # build project # set(dlt_example1_SRCS example1.c) add_executable(dlt-example1 ${dlt_example1_SRCS}) target_link_libraries(dlt-example1 ${DLT_LIBRARIES}) set_target_properties(dlt-example1 PROPERTIES LINKER_LANGUAGE C) install(TARGETS dlt-example1 RUNTIME DESTINATION bin COMPONENT base) dlt-daemon-2.18.4/examples/example1/example1.c000066400000000000000000000052211353342203500210440ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2011-2015, BMW AG * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author Alexander Wenzel * * \copyright Copyright © 2011-2015 BMW AG. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file example1.c */ /******************************************************************************* ** ** ** SRC-MODULE: example1.c ** ** ** ** TARGET : linux ** ** ** ** PROJECT : DLT ** ** ** ** AUTHOR : Alexander Wenzel Alexander.AW.Wenzel@bmw.de ** ** ** ** PURPOSE : ** ** ** ** REMARKS : ** ** ** ** PLATFORM DEPENDANT [yes/no]: yes ** ** ** ** TO BE CHANGED BY USER [yes/no]: no ** ** ** *******************************************************************************/ #include /* for printf() and fprintf() */ #include /* for atoi() and exit() */ #include DLT_DECLARE_CONTEXT(con_exa1); int main() { struct timespec ts; DLT_REGISTER_APP("EXA1", "First Example"); DLT_REGISTER_CONTEXT(con_exa1, "CON", "First context"); DLT_LOG(con_exa1, DLT_LOG_INFO, DLT_STRING("Hello world!")); ts.tv_sec = 0; ts.tv_nsec = 1000000; nanosleep(&ts, NULL); DLT_UNREGISTER_CONTEXT(con_exa1); DLT_UNREGISTER_APP(); } dlt-daemon-2.18.4/examples/example2/000077500000000000000000000000001353342203500171655ustar00rootroot00000000000000dlt-daemon-2.18.4/examples/example2/CMakeLists.txt000066400000000000000000000017571353342203500217370ustar00rootroot00000000000000####### # SPDX license identifier: MPL-2.0 # # Copyright (C) 2011-2015, BMW AG # # This file is part of GENIVI Project DLT - Diagnostic Log and Trace. # # This Source Code Form is subject to the terms of the # Mozilla Public License (MPL), v. 2.0. # If a copy of the MPL was not distributed with this file, # You can obtain one at http://mozilla.org/MPL/2.0/. # # For further information see http://www.genivi.org/. ####### # # DLT example implementation # cmake_minimum_required( VERSION 2.6 ) project( automotive-dlt-example2 ) # # find dependency packages # find_package(PkgConfig) pkg_check_modules(DLT REQUIRED automotive-dlt) # # include directories # include_directories( ${DLT_INCLUDE_DIRS} ) # # build project # set(dlt_example2_SRCS example2.c) add_executable(dlt-example2 ${dlt_example2_SRCS}) target_link_libraries(dlt-example2 ${DLT_LIBRARIES}) set_target_properties(dlt-example2 PROPERTIES LINKER_LANGUAGE C) install(TARGETS dlt-example2 RUNTIME DESTINATION bin COMPONENT base) dlt-daemon-2.18.4/examples/example2/dlt_id.h000066400000000000000000000011621353342203500205750ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2011-2015, BMW AG * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /* generated file, do not edit */ #ifndef DLT_ID_H #define DLT_ID_H #define DLT_EXA2_CON_EXA2_ID1 1000 #define DLT_EXA2_CON_EXA2_ID2 1001 #define DLT_EXA2_CON_EXA2_ID3 1002 #endif /* DLT_ID_H */ dlt-daemon-2.18.4/examples/example2/example2.c000066400000000000000000000060461353342203500210540ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2011-2015, BMW AG * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author Alexander Wenzel * * \copyright Copyright © 2011-2015 BMW AG. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file example2.c */ /******************************************************************************* ** ** ** SRC-MODULE: example2.c ** ** ** ** TARGET : linux ** ** ** ** PROJECT : DLT ** ** ** ** AUTHOR : Alexander Wenzel Alexander.AW.Wenzel@bmw.de ** ** ** ** PURPOSE : ** ** ** ** REMARKS : ** ** ** ** PLATFORM DEPENDANT [yes/no]: yes ** ** ** ** TO BE CHANGED BY USER [yes/no]: no ** ** ** *******************************************************************************/ #include /* for printf() and fprintf() */ #include /* for atoi() and exit() */ #include #include "dlt_id.h" DLT_DECLARE_CONTEXT(con_exa2); int main() { int num; struct timespec ts; DLT_REGISTER_APP("EXA2", "Third Example"); DLT_REGISTER_CONTEXT(con_exa2, "CON", "First context"); DLT_NONVERBOSE_MODE(); for (num = 0; num < 10; num++) { DLT_LOG_ID(con_exa2, DLT_LOG_INFO, DLT_EXA2_CON_EXA2_ID1, DLT_INT32(12345678), DLT_STRING("Hello world 1!")); DLT_LOG_ID(con_exa2, DLT_LOG_ERROR, DLT_EXA2_CON_EXA2_ID2, DLT_INT32(87654321), DLT_STRING("Hello world 2!")); DLT_LOG_ID(con_exa2, DLT_LOG_WARN, DLT_EXA2_CON_EXA2_ID3, DLT_INT32(11223344), DLT_STRING("Hello world 3!")); ts.tv_sec = 0; ts.tv_nsec = 1000000; nanosleep(&ts, NULL); } DLT_UNREGISTER_CONTEXT(con_exa2); DLT_UNREGISTER_APP(); } dlt-daemon-2.18.4/examples/example2/example2.xml000066400000000000000000000176471353342203500214430ustar00rootroot00000000000000 projectEntry Entry unknown EXA2 Third Example CON First context PDU_1000_0 4 OTHER 0 PDU_1000_1 0 OTHER 0 PDU_1001_0 4 OTHER 0 PDU_1001_1 0 OTHER 0 PDU_1002_0 4 OTHER 0 PDU_1002_1 0 OTHER 0 ID_1000 4 OTHER 0 1 DLT_TYPE_LOG DLT_LOG_INFO EXA2 CON /home/alex/workspace/ascgit/dlt-daemon/examples/example2/example2.c 64 ID_1001 4 OTHER 0 1 DLT_TYPE_LOG DLT_LOG_ERROR EXA2 CON /home/alex/workspace/ascgit/dlt-daemon/examples/example2/example2.c 65 ID_1002 4 OTHER 0 1 DLT_TYPE_LOG DLT_LOG_WARN EXA2 CON /home/alex/workspace/ascgit/dlt-daemon/examples/example2/example2.c 66 dlt-daemon-2.18.4/examples/example3/000077500000000000000000000000001353342203500171665ustar00rootroot00000000000000dlt-daemon-2.18.4/examples/example3/CMakeLists.txt000066400000000000000000000017571353342203500217400ustar00rootroot00000000000000####### # SPDX license identifier: MPL-2.0 # # Copyright (C) 2011-2015, BMW AG # # This file is part of GENIVI Project DLT - Diagnostic Log and Trace. # # This Source Code Form is subject to the terms of the # Mozilla Public License (MPL), v. 2.0. # If a copy of the MPL was not distributed with this file, # You can obtain one at http://mozilla.org/MPL/2.0/. # # For further information see http://www.genivi.org/. ####### # # DLT example implementation # cmake_minimum_required( VERSION 2.6 ) project( automotive-dlt-example3 ) # # find dependency packages # find_package(PkgConfig) pkg_check_modules(DLT REQUIRED automotive-dlt) # # include directories # include_directories( ${DLT_INCLUDE_DIRS} ) # # build project # set(dlt_example3_SRCS example3.c) add_executable(dlt-example3 ${dlt_example3_SRCS}) target_link_libraries(dlt-example3 ${DLT_LIBRARIES}) set_target_properties(dlt-example3 PROPERTIES LINKER_LANGUAGE C) install(TARGETS dlt-example3 RUNTIME DESTINATION bin COMPONENT base) dlt-daemon-2.18.4/examples/example3/dlt_id.h000066400000000000000000000011621353342203500205760ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2011-2015, BMW AG * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /* generated file, do not edit */ #ifndef DLT_ID_H #define DLT_ID_H #define DLT_EXA3_CON_EXA3_ID1 1000 #define DLT_EXA3_CON_EXA3_ID2 1001 #define DLT_EXA3_CON_EXA3_ID3 1002 #endif /* DLT_ID_H */ dlt-daemon-2.18.4/examples/example3/example3.c000066400000000000000000000060511353342203500210520ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2011-2015, BMW AG * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author Alexander Wenzel * * \copyright Copyright © 2011-2015 BMW AG. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file example3.c */ /******************************************************************************* ** ** ** SRC-MODULE: example3.c ** ** ** ** TARGET : linux ** ** ** ** PROJECT : DLT ** ** ** ** AUTHOR : Alexander Wenzel Alexander.AW.Wenzel@bmw.de ** ** ** ** PURPOSE : ** ** ** ** REMARKS : ** ** ** ** PLATFORM DEPENDANT [yes/no]: yes ** ** ** ** TO BE CHANGED BY USER [yes/no]: no ** ** ** *******************************************************************************/ #include /* for printf() and fprintf() */ #include /* for atoi() and exit() */ #include #include "dlt_id.h" DLT_DECLARE_CONTEXT(con_exa3); int main() { int num; struct timespec ts; DLT_REGISTER_APP("EXA3", "Third Example"); DLT_REGISTER_CONTEXT(con_exa3, "CON", "First context"); DLT_NONVERBOSE_MODE(); for (num = 0; num < 10; num++) { DLT_LOG_ID(con_exa3, DLT_LOG_INFO, DLT_EXA3_CON_EXA3_ID1, DLT_INT32(12345678), DLT_CSTRING("Hello world 1!")); DLT_LOG_ID(con_exa3, DLT_LOG_ERROR, DLT_EXA3_CON_EXA3_ID2, DLT_INT32(87654321), DLT_CSTRING("Hello world 2!")); DLT_LOG_ID(con_exa3, DLT_LOG_WARN, DLT_EXA3_CON_EXA3_ID3, DLT_INT32(11223344), DLT_CSTRING("Hello world 3!")); ts.tv_sec = 0; ts.tv_nsec = 1000000; nanosleep(&ts, NULL); } DLT_UNREGISTER_CONTEXT(con_exa3); DLT_UNREGISTER_APP(); } dlt-daemon-2.18.4/examples/example3/example3.xml000066400000000000000000000162551353342203500214370ustar00rootroot00000000000000 projectEntry Entry unknown EXA3 Third Example CON First context PDU_1000_0 4 OTHER 0 PDU_1000_1 Hello world 1! 0 OTHER PDU_1001_0 4 OTHER 0 PDU_1001_1 Hello world 2! 0 OTHER PDU_1002_0 4 OTHER 0 PDU_1002_1 Hello world 3! 0 OTHER ID_1000 4 OTHER 0 1 DLT_TYPE_LOG DLT_LOG_INFO EXA3 CON /home/alex/workspace/ascgit/dlt-daemon/examples/example3/example3.c 64 ID_1001 4 OTHER 0 1 DLT_TYPE_LOG DLT_LOG_ERROR EXA3 CON /home/alex/workspace/ascgit/dlt-daemon/examples/example3/example3.c 65 ID_1002 4 OTHER 0 1 DLT_TYPE_LOG DLT_LOG_WARN EXA3 CON /home/alex/workspace/ascgit/dlt-daemon/examples/example3/example3.c 66 dlt-daemon-2.18.4/examples/example4/000077500000000000000000000000001353342203500171675ustar00rootroot00000000000000dlt-daemon-2.18.4/examples/example4/CMakeLists.txt000066400000000000000000000020451353342203500217300ustar00rootroot00000000000000####### # SPDX license identifier: MPL-2.0 # # Copyright (C) 2011-2015, BMW AG # # This file is part of GENIVI Project DLT - Diagnostic Log and Trace. # # This Source Code Form is subject to the terms of the # Mozilla Public License (MPL), v. 2.0. # If a copy of the MPL was not distributed with this file, # You can obtain one at http://mozilla.org/MPL/2.0/. # # For further information see http://www.genivi.org/. ####### # # DLT example implementation # cmake_minimum_required( VERSION 2.6 ) project( automotive-dlt-example4 ) # # set prefix # set( CMAKE_INSTALL_PREFIX "/usr" ) # # find dependency packages # find_package(PkgConfig) pkg_check_modules(DLT REQUIRED automotive-dlt) # # include directories # include_directories( ${DLT_INCLUDE_DIRS} ) # # build project # set(dlt_example4_SRCS example4.c) add_executable(dlt-example4 ${dlt_example4_SRCS}) target_link_libraries(dlt-example4 ${DLT_LIBRARIES}) set_target_properties(dlt-example4 PROPERTIES LINKER_LANGUAGE C) install(TARGETS dlt-example4 RUNTIME DESTINATION bin COMPONENT base) dlt-daemon-2.18.4/examples/example4/example4.c000066400000000000000000000077731353342203500210700ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2011-2015, BMW AG * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author Alexander Wenzel * * \copyright Copyright © 2011-2015 BMW AG. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file example4.c */ /******************************************************************************* ** ** ** SRC-MODULE: example4.c ** ** ** ** TARGET : linux ** ** ** ** PROJECT : DLT ** ** ** ** AUTHOR : Alexander Wenzel Alexander.AW.Wenzel@bmw.de ** ** ** ** PURPOSE : ** ** ** ** REMARKS : ** ** ** ** PLATFORM DEPENDANT [yes/no]: yes ** ** ** ** TO BE CHANGED BY USER [yes/no]: no ** ** ** *******************************************************************************/ #include /* for printf() and fprintf() */ #include /* for atoi() and exit() */ #include DLT_DECLARE_CONTEXT(con_exa1); int main() { unsigned char buffer[256]; int num; struct timespec ts; DLT_REGISTER_APP("EXA4", "Fourth Example"); DLT_REGISTER_CONTEXT(con_exa1, "CON", "First context"); for (num = 0; num < 256; num++) buffer[num] = num; DLT_LOG(con_exa1, DLT_LOG_INFO, DLT_STRING("DLT_RAW")); DLT_LOG(con_exa1, DLT_LOG_INFO, DLT_RAW(buffer, 256)); uint8_t uint8data = 0x2a; DLT_LOG(con_exa1, DLT_LOG_INFO, DLT_STRING("DLT_UINT8")); DLT_LOG(con_exa1, DLT_LOG_INFO, DLT_UINT8(uint8data)); uint8_t hex8data = 0x1a; DLT_LOG(con_exa1, DLT_LOG_INFO, DLT_STRING("DLT_HEX8")); DLT_LOG(con_exa1, DLT_LOG_INFO, DLT_HEX8(hex8data)); uint16_t hex16data = 0x1ad3; DLT_LOG(con_exa1, DLT_LOG_INFO, DLT_STRING("DLT_HEX16")); DLT_LOG(con_exa1, DLT_LOG_INFO, DLT_HEX16(hex16data)); uint32_t hex32data = 0x1abcd3e4; DLT_LOG(con_exa1, DLT_LOG_INFO, DLT_STRING("DLT_HEX32")); DLT_LOG(con_exa1, DLT_LOG_INFO, DLT_HEX32(hex32data)); uint64_t hex64data = 0x17b4ddcf34eabb2a; DLT_LOG(con_exa1, DLT_LOG_INFO, DLT_STRING("DLT_HEX64")); DLT_LOG(con_exa1, DLT_LOG_INFO, DLT_HEX64(hex64data)); uint8_t bin8data = 0xe2; DLT_LOG(con_exa1, DLT_LOG_INFO, DLT_STRING("DLT_BIN8")); DLT_LOG(con_exa1, DLT_LOG_INFO, DLT_BIN8(bin8data)); bin8data = 0x01; DLT_LOG(con_exa1, DLT_LOG_INFO, DLT_STRING("DLT_BIN8")); DLT_LOG(con_exa1, DLT_LOG_INFO, DLT_BIN8(bin8data)); uint16_t bin16data = 0x1234; DLT_LOG(con_exa1, DLT_LOG_INFO, DLT_STRING("DLT_BIN16")); DLT_LOG(con_exa1, DLT_LOG_INFO, DLT_BIN16(bin16data)); ts.tv_sec = 0; ts.tv_nsec = 1000000; nanosleep(&ts, NULL); DLT_UNREGISTER_CONTEXT(con_exa1); DLT_UNREGISTER_APP(); } dlt-daemon-2.18.4/gtest-1.7.0/000077500000000000000000000000001353342203500154215ustar00rootroot00000000000000dlt-daemon-2.18.4/gtest-1.7.0/CHANGES000066400000000000000000000147651353342203500164310ustar00rootroot00000000000000Changes for 1.7.0: * New feature: death tests are supported on OpenBSD and in iOS simulator now. * New feature: Google Test now implements a protocol to allow a test runner to detect that a test program has exited prematurely and report it as a failure (before it would be falsely reported as a success if the exit code is 0). * New feature: Test::RecordProperty() can now be used outside of the lifespan of a test method, in which case it will be attributed to the current test case or the test program in the XML report. * New feature (potentially breaking): --gtest_list_tests now prints the type parameters and value parameters for each test. * Improvement: char pointers and char arrays are now escaped properly in failure messages. * Improvement: failure summary in XML reports now includes file and line information. * Improvement: the XML element now has a timestamp attribute. * Improvement: When --gtest_filter is specified, XML report now doesn't contain information about tests that are filtered out. * Fixed the bug where long --gtest_filter flag values are truncated in death tests. * Potentially breaking change: RUN_ALL_TESTS() is now implemented as a function instead of a macro in order to work better with Clang. * Compatibility fixes with C++ 11 and various platforms. * Bug/warning fixes. Changes for 1.6.0: * New feature: ADD_FAILURE_AT() for reporting a test failure at the given source location -- useful for writing testing utilities. * New feature: the universal value printer is moved from Google Mock to Google Test. * New feature: type parameters and value parameters are reported in the XML report now. * A gtest_disable_pthreads CMake option. * Colored output works in GNU Screen sessions now. * Parameters of value-parameterized tests are now printed in the textual output. * Failures from ad hoc test assertions run before RUN_ALL_TESTS() are now correctly reported. * Arguments of ASSERT_XY and EXPECT_XY no longer need to support << to ostream. * More complete handling of exceptions. * GTEST_ASSERT_XY can be used instead of ASSERT_XY in case the latter name is already used by another library. * --gtest_catch_exceptions is now true by default, allowing a test program to continue after an exception is thrown. * Value-parameterized test fixtures can now derive from Test and WithParamInterface separately, easing conversion of legacy tests. * Death test messages are clearly marked to make them more distinguishable from other messages. * Compatibility fixes for Android, Google Native Client, MinGW, HP UX, PowerPC, Lucid autotools, libCStd, Sun C++, Borland C++ Builder (Code Gear), IBM XL C++ (Visual Age C++), and C++0x. * Bug fixes and implementation clean-ups. * Potentially incompatible changes: disables the harmful 'make install' command in autotools. Changes for 1.5.0: * New feature: assertions can be safely called in multiple threads where the pthreads library is available. * New feature: predicates used inside EXPECT_TRUE() and friends can now generate custom failure messages. * New feature: Google Test can now be compiled as a DLL. * New feature: fused source files are included. * New feature: prints help when encountering unrecognized Google Test flags. * Experimental feature: CMake build script (requires CMake 2.6.4+). * Experimental feature: the Pump script for meta programming. * double values streamed to an assertion are printed with enough precision to differentiate any two different values. * Google Test now works on Solaris and AIX. * Build and test script improvements. * Bug fixes and implementation clean-ups. Potentially breaking changes: * Stopped supporting VC++ 7.1 with exceptions disabled. * Dropped support for 'make install'. Changes for 1.4.0: * New feature: the event listener API * New feature: test shuffling * New feature: the XML report format is closer to junitreport and can be parsed by Hudson now. * New feature: when a test runs under Visual Studio, its failures are integrated in the IDE. * New feature: /MD(d) versions of VC++ projects. * New feature: elapsed time for the tests is printed by default. * New feature: comes with a TR1 tuple implementation such that Boost is no longer needed for Combine(). * New feature: EXPECT_DEATH_IF_SUPPORTED macro and friends. * New feature: the Xcode project can now produce static gtest libraries in addition to a framework. * Compatibility fixes for Solaris, Cygwin, minGW, Windows Mobile, Symbian, gcc, and C++Builder. * Bug fixes and implementation clean-ups. Changes for 1.3.0: * New feature: death tests on Windows, Cygwin, and Mac. * New feature: ability to use Google Test assertions in other testing frameworks. * New feature: ability to run disabled test via --gtest_also_run_disabled_tests. * New feature: the --help flag for printing the usage. * New feature: access to Google Test flag values in user code. * New feature: a script that packs Google Test into one .h and one .cc file for easy deployment. * New feature: support for distributing test functions to multiple machines (requires support from the test runner). * Bug fixes and implementation clean-ups. Changes for 1.2.1: * Compatibility fixes for Linux IA-64 and IBM z/OS. * Added support for using Boost and other TR1 implementations. * Changes to the build scripts to support upcoming release of Google C++ Mocking Framework. * Added Makefile to the distribution package. * Improved build instructions in README. Changes for 1.2.0: * New feature: value-parameterized tests. * New feature: the ASSERT/EXPECT_(NON)FATAL_FAILURE(_ON_ALL_THREADS) macros. * Changed the XML report format to match JUnit/Ant's. * Added tests to the Xcode project. * Added scons/SConscript for building with SCons. * Added src/gtest-all.cc for building Google Test from a single file. * Fixed compatibility with Solaris and z/OS. * Enabled running Python tests on systems with python 2.3 installed, e.g. Mac OS X 10.4. * Bug fixes. Changes for 1.1.0: * New feature: type-parameterized tests. * New feature: exception assertions. * New feature: printing elapsed time of tests. * Improved the robustness of death tests. * Added an Xcode project and samples. * Adjusted the output format on Windows to be understandable by Visual Studio. * Minor bug fixes. Changes for 1.0.1: * Added project files for Visual Studio 7.1. * Fixed issues with compiling on Mac OS X. * Fixed issues with compiling on Cygwin. Changes for 1.0.0: * Initial Open Source release of Google Test dlt-daemon-2.18.4/gtest-1.7.0/CMakeLists.txt000066400000000000000000000216401353342203500201640ustar00rootroot00000000000000######################################################################## # CMake build script for Google Test. # # To run the tests for Google Test itself on Linux, use 'make test' or # ctest. You can select which tests to run using 'ctest -R regex'. # For more options, run 'ctest --help'. # BUILD_SHARED_LIBS is a standard CMake variable, but we declare it here to # make it prominent in the GUI. option(BUILD_SHARED_LIBS "Build shared libraries (DLLs)." OFF) # When other libraries are using a shared version of runtime libraries, # Google Test also has to use one. option( gtest_force_shared_crt "Use shared (DLL) run-time lib even when Google Test is built as static lib." OFF) option(gtest_build_tests "Build all of gtest's own tests." OFF) option(gtest_build_samples "Build gtest's sample programs." OFF) option(gtest_disable_pthreads "Disable uses of pthreads in gtest." OFF) # Defines pre_project_set_up_hermetic_build() and set_up_hermetic_build(). include(cmake/hermetic_build.cmake OPTIONAL) if (COMMAND pre_project_set_up_hermetic_build) pre_project_set_up_hermetic_build() endif() ######################################################################## # # Project-wide settings # Name of the project. # # CMake files in this project can refer to the root source directory # as ${gtest_SOURCE_DIR} and to the root binary directory as # ${gtest_BINARY_DIR}. # Language "C" is required for find_package(Threads). project(gtest CXX C) cmake_minimum_required(VERSION 2.6.2) if (COMMAND set_up_hermetic_build) set_up_hermetic_build() endif() # Define helper functions and macros used by Google Test. include(cmake/internal_utils.cmake) config_compiler_and_linker() # Defined in internal_utils.cmake. # Where Google Test's .h files can be found. include_directories( ${gtest_SOURCE_DIR}/include ${gtest_SOURCE_DIR}) # Where Google Test's libraries can be found. link_directories(${gtest_BINARY_DIR}/src) ######################################################################## # # Defines the gtest & gtest_main libraries. User tests should link # with one of them. # Google Test libraries. We build them using more strict warnings than what # are used for other targets, to ensure that gtest can be compiled by a user # aggressive about warnings. cxx_library(gtest "${cxx_strict}" src/gtest-all.cc) cxx_library(gtest_main "${cxx_strict}" src/gtest_main.cc) target_link_libraries(gtest_main gtest) ######################################################################## # # Samples on how to link user tests with gtest or gtest_main. # # They are not built by default. To build them, set the # gtest_build_samples option to ON. You can do it by running ccmake # or specifying the -Dgtest_build_samples=ON flag when running cmake. if (gtest_build_samples) cxx_executable(sample1_unittest samples gtest_main samples/sample1.cc) cxx_executable(sample2_unittest samples gtest_main samples/sample2.cc) cxx_executable(sample3_unittest samples gtest_main) cxx_executable(sample4_unittest samples gtest_main samples/sample4.cc) cxx_executable(sample5_unittest samples gtest_main samples/sample1.cc) cxx_executable(sample6_unittest samples gtest_main) cxx_executable(sample7_unittest samples gtest_main) cxx_executable(sample8_unittest samples gtest_main) cxx_executable(sample9_unittest samples gtest) cxx_executable(sample10_unittest samples gtest) endif() ######################################################################## # # Google Test's own tests. # # You can skip this section if you aren't interested in testing # Google Test itself. # # The tests are not built by default. To build them, set the # gtest_build_tests option to ON. You can do it by running ccmake # or specifying the -Dgtest_build_tests=ON flag when running cmake. if (gtest_build_tests) # This must be set in the root directory for the tests to be run by # 'make test' or ctest. enable_testing() ############################################################ # C++ tests built with standard compiler flags. cxx_test(gtest-death-test_test gtest_main) cxx_test(gtest_environment_test gtest) cxx_test(gtest-filepath_test gtest_main) cxx_test(gtest-linked_ptr_test gtest_main) cxx_test(gtest-listener_test gtest_main) cxx_test(gtest_main_unittest gtest_main) cxx_test(gtest-message_test gtest_main) cxx_test(gtest_no_test_unittest gtest) cxx_test(gtest-options_test gtest_main) cxx_test(gtest-param-test_test gtest test/gtest-param-test2_test.cc) cxx_test(gtest-port_test gtest_main) cxx_test(gtest_pred_impl_unittest gtest_main) cxx_test(gtest_premature_exit_test gtest test/gtest_premature_exit_test.cc) cxx_test(gtest-printers_test gtest_main) cxx_test(gtest_prod_test gtest_main test/production.cc) cxx_test(gtest_repeat_test gtest) cxx_test(gtest_sole_header_test gtest_main) cxx_test(gtest_stress_test gtest) cxx_test(gtest-test-part_test gtest_main) cxx_test(gtest_throw_on_failure_ex_test gtest) cxx_test(gtest-typed-test_test gtest_main test/gtest-typed-test2_test.cc) cxx_test(gtest_unittest gtest_main) cxx_test(gtest-unittest-api_test gtest) ############################################################ # C++ tests built with non-standard compiler flags. # MSVC 7.1 does not support STL with exceptions disabled. if (NOT MSVC OR MSVC_VERSION GREATER 1310) cxx_library(gtest_no_exception "${cxx_no_exception}" src/gtest-all.cc) cxx_library(gtest_main_no_exception "${cxx_no_exception}" src/gtest-all.cc src/gtest_main.cc) endif() cxx_library(gtest_main_no_rtti "${cxx_no_rtti}" src/gtest-all.cc src/gtest_main.cc) cxx_test_with_flags(gtest-death-test_ex_nocatch_test "${cxx_exception} -DGTEST_ENABLE_CATCH_EXCEPTIONS_=0" gtest test/gtest-death-test_ex_test.cc) cxx_test_with_flags(gtest-death-test_ex_catch_test "${cxx_exception} -DGTEST_ENABLE_CATCH_EXCEPTIONS_=1" gtest test/gtest-death-test_ex_test.cc) cxx_test_with_flags(gtest_no_rtti_unittest "${cxx_no_rtti}" gtest_main_no_rtti test/gtest_unittest.cc) cxx_shared_library(gtest_dll "${cxx_default}" src/gtest-all.cc src/gtest_main.cc) cxx_executable_with_flags(gtest_dll_test_ "${cxx_default}" gtest_dll test/gtest_all_test.cc) set_target_properties(gtest_dll_test_ PROPERTIES COMPILE_DEFINITIONS "GTEST_LINKED_AS_SHARED_LIBRARY=1") if (NOT MSVC OR NOT MSVC_VERSION EQUAL 1600) # The C++ Standard specifies tuple_element. # Yet MSVC 10's declares tuple_element. # That declaration conflicts with our own standard-conforming # tuple implementation. Therefore using our own tuple with # MSVC 10 doesn't compile. cxx_library(gtest_main_use_own_tuple "${cxx_use_own_tuple}" src/gtest-all.cc src/gtest_main.cc) cxx_test_with_flags(gtest-tuple_test "${cxx_use_own_tuple}" gtest_main_use_own_tuple test/gtest-tuple_test.cc) cxx_test_with_flags(gtest_use_own_tuple_test "${cxx_use_own_tuple}" gtest_main_use_own_tuple test/gtest-param-test_test.cc test/gtest-param-test2_test.cc) endif() ############################################################ # Python tests. cxx_executable(gtest_break_on_failure_unittest_ test gtest) py_test(gtest_break_on_failure_unittest) # MSVC 7.1 does not support STL with exceptions disabled. if (NOT MSVC OR MSVC_VERSION GREATER 1310) cxx_executable_with_flags( gtest_catch_exceptions_no_ex_test_ "${cxx_no_exception}" gtest_main_no_exception test/gtest_catch_exceptions_test_.cc) endif() cxx_executable_with_flags( gtest_catch_exceptions_ex_test_ "${cxx_exception}" gtest_main test/gtest_catch_exceptions_test_.cc) py_test(gtest_catch_exceptions_test) cxx_executable(gtest_color_test_ test gtest) py_test(gtest_color_test) cxx_executable(gtest_env_var_test_ test gtest) py_test(gtest_env_var_test) cxx_executable(gtest_filter_unittest_ test gtest) py_test(gtest_filter_unittest) cxx_executable(gtest_help_test_ test gtest_main) py_test(gtest_help_test) cxx_executable(gtest_list_tests_unittest_ test gtest) py_test(gtest_list_tests_unittest) cxx_executable(gtest_output_test_ test gtest) py_test(gtest_output_test) cxx_executable(gtest_shuffle_test_ test gtest) py_test(gtest_shuffle_test) # MSVC 7.1 does not support STL with exceptions disabled. if (NOT MSVC OR MSVC_VERSION GREATER 1310) cxx_executable(gtest_throw_on_failure_test_ test gtest_no_exception) set_target_properties(gtest_throw_on_failure_test_ PROPERTIES COMPILE_FLAGS "${cxx_no_exception}") py_test(gtest_throw_on_failure_test) endif() cxx_executable(gtest_uninitialized_test_ test gtest) py_test(gtest_uninitialized_test) cxx_executable(gtest_xml_outfile1_test_ test gtest_main) cxx_executable(gtest_xml_outfile2_test_ test gtest_main) py_test(gtest_xml_outfiles_test) cxx_executable(gtest_xml_output_unittest_ test gtest) py_test(gtest_xml_output_unittest) endif() dlt-daemon-2.18.4/gtest-1.7.0/CONTRIBUTORS000066400000000000000000000025161353342203500173050ustar00rootroot00000000000000# This file contains a list of people who've made non-trivial # contribution to the Google C++ Testing Framework project. People # who commit code to the project are encouraged to add their names # here. Please keep the list sorted by first names. Ajay Joshi Balázs Dán Bharat Mediratta Chandler Carruth Chris Prince Chris Taylor Dan Egnor Eric Roman Hady Zalek Jeffrey Yasskin Jói Sigurðsson Keir Mierle Keith Ray Kenton Varda Manuel Klimek Markus Heule Mika Raento Miklós Fazekas Pasi Valminen Patrick Hanna Patrick Riley Peter Kaminski Preston Jackson Rainer Klaffenboeck Russ Cox Russ Rufer Sean Mcafee Sigurður Ásgeirsson Tracy Bialik Vadim Berman Vlad Losev Zhanyong Wan dlt-daemon-2.18.4/gtest-1.7.0/LICENSE000066400000000000000000000027031353342203500164300ustar00rootroot00000000000000Copyright 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. dlt-daemon-2.18.4/gtest-1.7.0/Makefile000066400000000000000000001570061353342203500170720ustar00rootroot00000000000000# Makefile.in generated by automake 1.11.3 from Makefile.am. # Makefile. Generated from Makefile.in by configure. # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software # Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. # Automake file pkgdatadir = $(datadir)/gtest pkgincludedir = $(includedir)/gtest pkglibdir = $(libdir)/gtest pkglibexecdir = $(libexecdir)/gtest am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = i686-pc-linux-gnu host_triplet = i686-pc-linux-gnu TESTS = samples/sample1_unittest$(EXEEXT) \ samples/sample10_unittest$(EXEEXT) \ test/gtest_all_test$(EXEEXT) $(am__EXEEXT_1) check_PROGRAMS = samples/sample1_unittest$(EXEEXT) \ samples/sample10_unittest$(EXEEXT) \ test/gtest_all_test$(EXEEXT) $(am__EXEEXT_1) am__append_1 = test/fused_gtest_test am__append_2 = test/fused_gtest_test subdir = . DIST_COMMON = README $(am__configure_deps) $(pkginclude_HEADERS) \ $(pkginclude_internal_HEADERS) $(srcdir)/Makefile.am \ $(srcdir)/Makefile.in $(top_srcdir)/build-aux/config.h.in \ $(top_srcdir)/configure $(top_srcdir)/scripts/gtest-config.in \ build-aux/config.guess build-aux/config.sub build-aux/depcomp \ build-aux/install-sh build-aux/ltmain.sh build-aux/missing ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/acx_pthread.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ configure.lineno config.status.lineno mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/build-aux/config.h CONFIG_CLEAN_FILES = scripts/gtest-config CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(m4datadir)" \ "$(DESTDIR)$(pkgincludedir)" \ "$(DESTDIR)$(pkginclude_internaldir)" LTLIBRARIES = $(lib_LTLIBRARIES) $(noinst_LTLIBRARIES) lib_libgtest_la_LIBADD = am__dirstamp = $(am__leading_dot)dirstamp am_lib_libgtest_la_OBJECTS = src/gtest-all.lo lib_libgtest_la_OBJECTS = $(am_lib_libgtest_la_OBJECTS) lib_libgtest_main_la_DEPENDENCIES = lib/libgtest.la am_lib_libgtest_main_la_OBJECTS = src/gtest_main.lo lib_libgtest_main_la_OBJECTS = $(am_lib_libgtest_main_la_OBJECTS) samples_libsamples_la_LIBADD = am_samples_libsamples_la_OBJECTS = samples/sample1.lo \ samples/sample2.lo samples/sample4.lo samples_libsamples_la_OBJECTS = $(am_samples_libsamples_la_OBJECTS) am__EXEEXT_1 = test/fused_gtest_test$(EXEEXT) am_samples_sample10_unittest_OBJECTS = \ samples/sample10_unittest.$(OBJEXT) samples_sample10_unittest_OBJECTS = \ $(am_samples_sample10_unittest_OBJECTS) samples_sample10_unittest_DEPENDENCIES = lib/libgtest.la am_samples_sample1_unittest_OBJECTS = \ samples/sample1_unittest.$(OBJEXT) samples_sample1_unittest_OBJECTS = \ $(am_samples_sample1_unittest_OBJECTS) samples_sample1_unittest_DEPENDENCIES = lib/libgtest_main.la \ lib/libgtest.la samples/libsamples.la am__test_fused_gtest_test_SOURCES_DIST = fused-src/gtest/gtest-all.cc \ fused-src/gtest/gtest.h fused-src/gtest/gtest_main.cc \ samples/sample1.cc samples/sample1_unittest.cc am__objects_1 = \ fused-src/gtest/test_fused_gtest_test-gtest-all.$(OBJEXT) \ fused-src/gtest/test_fused_gtest_test-gtest_main.$(OBJEXT) am_test_fused_gtest_test_OBJECTS = $(am__objects_1) \ samples/test_fused_gtest_test-sample1.$(OBJEXT) \ samples/test_fused_gtest_test-sample1_unittest.$(OBJEXT) test_fused_gtest_test_OBJECTS = $(am_test_fused_gtest_test_OBJECTS) test_fused_gtest_test_LDADD = $(LDADD) am_test_gtest_all_test_OBJECTS = test/gtest_all_test.$(OBJEXT) test_gtest_all_test_OBJECTS = $(am_test_gtest_all_test_OBJECTS) test_gtest_all_test_DEPENDENCIES = lib/libgtest_main.la \ lib/libgtest.la DEFAULT_INCLUDES = -I. -I$(top_builddir)/build-aux depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__depfiles_maybe = depfiles am__mv = mv -f CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) CXXLD = $(CXX) CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ SOURCES = $(lib_libgtest_la_SOURCES) $(lib_libgtest_main_la_SOURCES) \ $(samples_libsamples_la_SOURCES) \ $(samples_sample10_unittest_SOURCES) \ $(samples_sample1_unittest_SOURCES) \ $(test_fused_gtest_test_SOURCES) \ $(test_gtest_all_test_SOURCES) DIST_SOURCES = $(lib_libgtest_la_SOURCES) \ $(lib_libgtest_main_la_SOURCES) \ $(samples_libsamples_la_SOURCES) \ $(samples_sample10_unittest_SOURCES) \ $(samples_sample1_unittest_SOURCES) \ $(am__test_fused_gtest_test_SOURCES_DIST) \ $(test_gtest_all_test_SOURCES) DATA = $(m4data_DATA) HEADERS = $(pkginclude_HEADERS) $(pkginclude_internal_HEADERS) ETAGS = etags CTAGS = ctags am__tty_colors = \ red=; grn=; lgn=; blu=; std= DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) distdir = $(PACKAGE)-$(VERSION) top_distdir = $(distdir) am__remove_distdir = \ if test -d "$(distdir)"; then \ find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ && rm -rf "$(distdir)" \ || { sleep 5 && rm -rf "$(distdir)"; }; \ else :; fi DIST_ARCHIVES = $(distdir).tar.gz $(distdir).tar.bz2 $(distdir).zip GZIP_ENV = --best distuninstallcheck_listfiles = find . -type f -print am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \ | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$' distcleancheck_listfiles = find . -type f -print ACLOCAL = ${SHELL} /home/user/projects/ascgit/ascgit003.dlt-daemon/build/gtest-1.7.0/build-aux/missing --run aclocal-1.11 AMTAR = $${TAR-tar} AR = ar AUTOCONF = ${SHELL} /home/user/projects/ascgit/ascgit003.dlt-daemon/build/gtest-1.7.0/build-aux/missing --run autoconf AUTOHEADER = ${SHELL} /home/user/projects/ascgit/ascgit003.dlt-daemon/build/gtest-1.7.0/build-aux/missing --run autoheader AUTOMAKE = ${SHELL} /home/user/projects/ascgit/ascgit003.dlt-daemon/build/gtest-1.7.0/build-aux/missing --run automake-1.11 AWK = gawk CC = gcc CCDEPMODE = depmode=gcc3 CFLAGS = -g -O2 CPP = gcc -E CPPFLAGS = CXX = g++ CXXCPP = g++ -E CXXDEPMODE = depmode=gcc3 CXXFLAGS = -g -O2 CYGPATH_W = echo DEFS = -DHAVE_CONFIG_H DEPDIR = .deps DLLTOOL = false DSYMUTIL = DUMPBIN = ECHO_C = ECHO_N = -n ECHO_T = EGREP = /usr/bin/grep -E EXEEXT = FGREP = /usr/bin/grep -F GREP = /usr/bin/grep INSTALL = /usr/bin/install -c INSTALL_DATA = ${INSTALL} -m 644 INSTALL_PROGRAM = ${INSTALL} INSTALL_SCRIPT = ${INSTALL} INSTALL_STRIP_PROGRAM = $(install_sh) -c -s LD = /usr/bin/ld LDFLAGS = LIBOBJS = LIBS = LIBTOOL = $(SHELL) $(top_builddir)/libtool LIPO = LN_S = ln -s LTLIBOBJS = MAKEINFO = ${SHELL} /home/user/projects/ascgit/ascgit003.dlt-daemon/build/gtest-1.7.0/build-aux/missing --run makeinfo MANIFEST_TOOL = : MKDIR_P = /usr/bin/mkdir -p NM = /usr/bin/nm -B NMEDIT = OBJDUMP = objdump OBJEXT = o OTOOL = OTOOL64 = PACKAGE = gtest PACKAGE_BUGREPORT = googletestframework@googlegroups.com PACKAGE_NAME = Google C++ Testing Framework PACKAGE_STRING = Google C++ Testing Framework 1.7.0 PACKAGE_TARNAME = gtest PACKAGE_URL = PACKAGE_VERSION = 1.7.0 PATH_SEPARATOR = : PTHREAD_CC = gcc PTHREAD_CFLAGS = -pthread PTHREAD_LIBS = PYTHON = /usr/bin/python RANLIB = ranlib SED = /usr/bin/sed SET_MAKE = SHELL = /bin/sh STRIP = strip VERSION = 1.7.0 abs_builddir = /home/user/projects/ascgit/ascgit003.dlt-daemon/build/gtest-1.7.0 abs_srcdir = /home/user/projects/ascgit/ascgit003.dlt-daemon/build/gtest-1.7.0 abs_top_builddir = /home/user/projects/ascgit/ascgit003.dlt-daemon/build/gtest-1.7.0 abs_top_srcdir = /home/user/projects/ascgit/ascgit003.dlt-daemon/build/gtest-1.7.0 ac_ct_AR = ar ac_ct_CC = gcc ac_ct_CXX = g++ ac_ct_DUMPBIN = acx_pthread_config = am__include = include am__leading_dot = . am__quote = am__tar = $${TAR-tar} chof - "$$tardir" am__untar = $${TAR-tar} xf - bindir = ${exec_prefix}/bin build = i686-pc-linux-gnu build_alias = build_cpu = i686 build_os = linux-gnu build_vendor = pc builddir = . datadir = ${datarootdir} datarootdir = ${prefix}/share docdir = ${datarootdir}/doc/${PACKAGE_TARNAME} dvidir = ${docdir} exec_prefix = ${prefix} host = i686-pc-linux-gnu host_alias = host_cpu = i686 host_os = linux-gnu host_vendor = pc htmldir = ${docdir} includedir = ${prefix}/include infodir = ${datarootdir}/info install_sh = ${SHELL} /home/user/projects/ascgit/ascgit003.dlt-daemon/build/gtest-1.7.0/build-aux/install-sh libdir = ${exec_prefix}/lib libexecdir = ${exec_prefix}/libexec localedir = ${datarootdir}/locale localstatedir = ${prefix}/var mandir = ${datarootdir}/man mkdir_p = /usr/bin/mkdir -p oldincludedir = /usr/include pdfdir = ${docdir} prefix = /usr/local program_transform_name = s,x,x, psdir = ${docdir} sbindir = ${exec_prefix}/sbin sharedstatedir = ${prefix}/com srcdir = . sysconfdir = ${prefix}/etc target_alias = top_build_prefix = top_builddir = . top_srcdir = . ACLOCAL_AMFLAGS = -I m4 # Nonstandard package files for distribution # Sample files that we don't compile. # C++ test files that we don't compile directly. # Python tests that we don't run. # CMake script # MSVC project files # xcode project files # xcode sample files # C++Builder project files EXTRA_DIST = CHANGES CONTRIBUTORS LICENSE \ include/gtest/gtest-param-test.h.pump \ include/gtest/internal/gtest-param-util-generated.h.pump \ include/gtest/internal/gtest-tuple.h.pump \ include/gtest/internal/gtest-type-util.h.pump make/Makefile \ scripts/fuse_gtest_files.py scripts/gen_gtest_pred_impl.py \ scripts/pump.py scripts/test/Makefile $(GTEST_SRC) \ samples/prime_tables.h samples/sample2_unittest.cc \ samples/sample3_unittest.cc samples/sample4_unittest.cc \ samples/sample5_unittest.cc samples/sample6_unittest.cc \ samples/sample7_unittest.cc samples/sample8_unittest.cc \ samples/sample9_unittest.cc test/gtest-death-test_ex_test.cc \ test/gtest-death-test_test.cc test/gtest-filepath_test.cc \ test/gtest-linked_ptr_test.cc test/gtest-listener_test.cc \ test/gtest-message_test.cc test/gtest-options_test.cc \ test/gtest-param-test2_test.cc test/gtest-param-test2_test.cc \ test/gtest-param-test_test.cc test/gtest-param-test_test.cc \ test/gtest-param-test_test.h test/gtest-port_test.cc \ test/gtest_premature_exit_test.cc test/gtest-printers_test.cc \ test/gtest-test-part_test.cc test/gtest-tuple_test.cc \ test/gtest-typed-test2_test.cc test/gtest-typed-test_test.cc \ test/gtest-typed-test_test.h test/gtest-unittest-api_test.cc \ test/gtest_break_on_failure_unittest_.cc \ test/gtest_catch_exceptions_test_.cc test/gtest_color_test_.cc \ test/gtest_env_var_test_.cc test/gtest_environment_test.cc \ test/gtest_filter_unittest_.cc test/gtest_help_test_.cc \ test/gtest_list_tests_unittest_.cc test/gtest_main_unittest.cc \ test/gtest_no_test_unittest.cc test/gtest_output_test_.cc \ test/gtest_pred_impl_unittest.cc test/gtest_prod_test.cc \ test/gtest_repeat_test.cc test/gtest_shuffle_test_.cc \ test/gtest_sole_header_test.cc test/gtest_stress_test.cc \ test/gtest_throw_on_failure_ex_test.cc \ test/gtest_throw_on_failure_test_.cc \ test/gtest_uninitialized_test_.cc test/gtest_unittest.cc \ test/gtest_unittest.cc test/gtest_xml_outfile1_test_.cc \ test/gtest_xml_outfile2_test_.cc \ test/gtest_xml_output_unittest_.cc test/production.cc \ test/production.h test/gtest_break_on_failure_unittest.py \ test/gtest_catch_exceptions_test.py test/gtest_color_test.py \ test/gtest_env_var_test.py test/gtest_filter_unittest.py \ test/gtest_help_test.py test/gtest_list_tests_unittest.py \ test/gtest_output_test.py \ test/gtest_output_test_golden_lin.txt \ test/gtest_shuffle_test.py test/gtest_test_utils.py \ test/gtest_throw_on_failure_test.py \ test/gtest_uninitialized_test.py \ test/gtest_xml_outfiles_test.py \ test/gtest_xml_output_unittest.py test/gtest_xml_test_utils.py \ CMakeLists.txt cmake/internal_utils.cmake msvc/gtest-md.sln \ msvc/gtest-md.vcproj msvc/gtest.sln msvc/gtest.vcproj \ msvc/gtest_main-md.vcproj msvc/gtest_main.vcproj \ msvc/gtest_prod_test-md.vcproj msvc/gtest_prod_test.vcproj \ msvc/gtest_unittest-md.vcproj msvc/gtest_unittest.vcproj \ xcode/Config/DebugProject.xcconfig \ xcode/Config/FrameworkTarget.xcconfig \ xcode/Config/General.xcconfig \ xcode/Config/ReleaseProject.xcconfig \ xcode/Config/StaticLibraryTarget.xcconfig \ xcode/Config/TestTarget.xcconfig xcode/Resources/Info.plist \ xcode/Scripts/runtests.sh xcode/Scripts/versiongenerate.py \ xcode/gtest.xcodeproj/project.pbxproj \ xcode/Samples/FrameworkSample/Info.plist \ xcode/Samples/FrameworkSample/WidgetFramework.xcodeproj/project.pbxproj \ xcode/Samples/FrameworkSample/runtests.sh \ xcode/Samples/FrameworkSample/widget.cc \ xcode/Samples/FrameworkSample/widget.h \ xcode/Samples/FrameworkSample/widget_test.cc \ codegear/gtest.cbproj codegear/gtest.groupproj \ codegear/gtest_all.cc codegear/gtest_link.cc \ codegear/gtest_main.cbproj codegear/gtest_unittest.cbproj \ $(m4data_DATA) # gtest source files that we don't compile directly. They are # #included by gtest-all.cc. GTEST_SRC = \ src/gtest-death-test.cc \ src/gtest-filepath.cc \ src/gtest-internal-inl.h \ src/gtest-port.cc \ src/gtest-printers.cc \ src/gtest-test-part.cc \ src/gtest-typed-test.cc \ src/gtest.cc # Distribute and install M4 macro m4datadir = $(datadir)/aclocal m4data_DATA = m4/gtest.m4 # We define the global AM_CPPFLAGS as everything we compile includes from these # directories. AM_CPPFLAGS = -I$(srcdir) -I$(srcdir)/include #AM_CXXFLAGS = -DGTEST_HAS_PTHREAD=0 # Modifies compiler and linker flags for pthreads compatibility. AM_CXXFLAGS = -pthread -DGTEST_HAS_PTHREAD=1 AM_LIBS = # Build rules for libraries. lib_LTLIBRARIES = lib/libgtest.la lib/libgtest_main.la lib_libgtest_la_SOURCES = src/gtest-all.cc pkginclude_HEADERS = \ include/gtest/gtest-death-test.h \ include/gtest/gtest-message.h \ include/gtest/gtest-param-test.h \ include/gtest/gtest-printers.h \ include/gtest/gtest-spi.h \ include/gtest/gtest-test-part.h \ include/gtest/gtest-typed-test.h \ include/gtest/gtest.h \ include/gtest/gtest_pred_impl.h \ include/gtest/gtest_prod.h pkginclude_internaldir = $(pkgincludedir)/internal pkginclude_internal_HEADERS = \ include/gtest/internal/gtest-death-test-internal.h \ include/gtest/internal/gtest-filepath.h \ include/gtest/internal/gtest-internal.h \ include/gtest/internal/gtest-linked_ptr.h \ include/gtest/internal/gtest-param-util-generated.h \ include/gtest/internal/gtest-param-util.h \ include/gtest/internal/gtest-port.h \ include/gtest/internal/gtest-string.h \ include/gtest/internal/gtest-tuple.h \ include/gtest/internal/gtest-type-util.h lib_libgtest_main_la_SOURCES = src/gtest_main.cc lib_libgtest_main_la_LIBADD = lib/libgtest.la # Bulid rules for samples and tests. Automake's naming for some of # these variables isn't terribly obvious, so this is a brief # reference: # # TESTS -- Programs run automatically by "make check" # check_PROGRAMS -- Programs built by "make check" but not necessarily run noinst_LTLIBRARIES = samples/libsamples.la samples_libsamples_la_SOURCES = \ samples/sample1.cc \ samples/sample1.h \ samples/sample2.cc \ samples/sample2.h \ samples/sample3-inl.h \ samples/sample4.cc \ samples/sample4.h TESTS_ENVIRONMENT = GTEST_SOURCE_DIR="$(srcdir)/test" \ GTEST_BUILD_DIR="$(top_builddir)/test" samples_sample1_unittest_SOURCES = samples/sample1_unittest.cc samples_sample1_unittest_LDADD = lib/libgtest_main.la \ lib/libgtest.la \ samples/libsamples.la samples_sample10_unittest_SOURCES = samples/sample10_unittest.cc samples_sample10_unittest_LDADD = lib/libgtest.la test_gtest_all_test_SOURCES = test/gtest_all_test.cc test_gtest_all_test_LDADD = lib/libgtest_main.la \ lib/libgtest.la # Tests that fused gtest files compile and work. FUSED_GTEST_SRC = \ fused-src/gtest/gtest-all.cc \ fused-src/gtest/gtest.h \ fused-src/gtest/gtest_main.cc test_fused_gtest_test_SOURCES = $(FUSED_GTEST_SRC) \ samples/sample1.cc samples/sample1_unittest.cc test_fused_gtest_test_CPPFLAGS = -I"$(srcdir)/fused-src" # Death tests may produce core dumps in the build directory. In case # this happens, clean them to keep distcleancheck happy. CLEANFILES = core all: all-am .SUFFIXES: .SUFFIXES: .cc .lo .o .obj am--refresh: Makefile @: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ echo ' cd $(srcdir) && $(AUTOMAKE) --foreign'; \ $(am__cd) $(srcdir) && $(AUTOMAKE) --foreign \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ echo ' $(SHELL) ./config.status'; \ $(SHELL) ./config.status;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) $(SHELL) ./config.status --recheck $(top_srcdir)/configure: $(am__configure_deps) $(am__cd) $(srcdir) && $(AUTOCONF) $(ACLOCAL_M4): $(am__aclocal_m4_deps) $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) $(am__aclocal_m4_deps): build-aux/config.h: build-aux/stamp-h1 @if test ! -f $@; then rm -f build-aux/stamp-h1; else :; fi @if test ! -f $@; then $(MAKE) $(AM_MAKEFLAGS) build-aux/stamp-h1; else :; fi build-aux/stamp-h1: $(top_srcdir)/build-aux/config.h.in $(top_builddir)/config.status @rm -f build-aux/stamp-h1 cd $(top_builddir) && $(SHELL) ./config.status build-aux/config.h $(top_srcdir)/build-aux/config.h.in: $(am__configure_deps) ($(am__cd) $(top_srcdir) && $(AUTOHEADER)) rm -f build-aux/stamp-h1 touch $@ distclean-hdr: -rm -f build-aux/config.h build-aux/stamp-h1 scripts/gtest-config: $(top_builddir)/config.status $(top_srcdir)/scripts/gtest-config.in cd $(top_builddir) && $(SHELL) ./config.status $@ install-libLTLIBRARIES: $(lib_LTLIBRARIES) @$(NORMAL_INSTALL) test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)" @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ } uninstall-libLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ done clean-libLTLIBRARIES: -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ test "$$dir" != "$$p" || dir=.; \ echo "rm -f \"$${dir}/so_locations\""; \ rm -f "$${dir}/so_locations"; \ done clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ test "$$dir" != "$$p" || dir=.; \ echo "rm -f \"$${dir}/so_locations\""; \ rm -f "$${dir}/so_locations"; \ done src/$(am__dirstamp): @$(MKDIR_P) src @: > src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) src/$(DEPDIR) @: > src/$(DEPDIR)/$(am__dirstamp) src/gtest-all.lo: src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp) lib/$(am__dirstamp): @$(MKDIR_P) lib @: > lib/$(am__dirstamp) lib/libgtest.la: $(lib_libgtest_la_OBJECTS) $(lib_libgtest_la_DEPENDENCIES) $(EXTRA_lib_libgtest_la_DEPENDENCIES) lib/$(am__dirstamp) $(CXXLINK) -rpath $(libdir) $(lib_libgtest_la_OBJECTS) $(lib_libgtest_la_LIBADD) $(LIBS) src/gtest_main.lo: src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp) lib/libgtest_main.la: $(lib_libgtest_main_la_OBJECTS) $(lib_libgtest_main_la_DEPENDENCIES) $(EXTRA_lib_libgtest_main_la_DEPENDENCIES) lib/$(am__dirstamp) $(CXXLINK) -rpath $(libdir) $(lib_libgtest_main_la_OBJECTS) $(lib_libgtest_main_la_LIBADD) $(LIBS) samples/$(am__dirstamp): @$(MKDIR_P) samples @: > samples/$(am__dirstamp) samples/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) samples/$(DEPDIR) @: > samples/$(DEPDIR)/$(am__dirstamp) samples/sample1.lo: samples/$(am__dirstamp) \ samples/$(DEPDIR)/$(am__dirstamp) samples/sample2.lo: samples/$(am__dirstamp) \ samples/$(DEPDIR)/$(am__dirstamp) samples/sample4.lo: samples/$(am__dirstamp) \ samples/$(DEPDIR)/$(am__dirstamp) samples/libsamples.la: $(samples_libsamples_la_OBJECTS) $(samples_libsamples_la_DEPENDENCIES) $(EXTRA_samples_libsamples_la_DEPENDENCIES) samples/$(am__dirstamp) $(CXXLINK) $(samples_libsamples_la_OBJECTS) $(samples_libsamples_la_LIBADD) $(LIBS) clean-checkPROGRAMS: @list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list samples/sample10_unittest.$(OBJEXT): samples/$(am__dirstamp) \ samples/$(DEPDIR)/$(am__dirstamp) samples/sample10_unittest$(EXEEXT): $(samples_sample10_unittest_OBJECTS) $(samples_sample10_unittest_DEPENDENCIES) $(EXTRA_samples_sample10_unittest_DEPENDENCIES) samples/$(am__dirstamp) @rm -f samples/sample10_unittest$(EXEEXT) $(CXXLINK) $(samples_sample10_unittest_OBJECTS) $(samples_sample10_unittest_LDADD) $(LIBS) samples/sample1_unittest.$(OBJEXT): samples/$(am__dirstamp) \ samples/$(DEPDIR)/$(am__dirstamp) samples/sample1_unittest$(EXEEXT): $(samples_sample1_unittest_OBJECTS) $(samples_sample1_unittest_DEPENDENCIES) $(EXTRA_samples_sample1_unittest_DEPENDENCIES) samples/$(am__dirstamp) @rm -f samples/sample1_unittest$(EXEEXT) $(CXXLINK) $(samples_sample1_unittest_OBJECTS) $(samples_sample1_unittest_LDADD) $(LIBS) fused-src/gtest/$(am__dirstamp): @$(MKDIR_P) fused-src/gtest @: > fused-src/gtest/$(am__dirstamp) fused-src/gtest/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) fused-src/gtest/$(DEPDIR) @: > fused-src/gtest/$(DEPDIR)/$(am__dirstamp) fused-src/gtest/test_fused_gtest_test-gtest-all.$(OBJEXT): \ fused-src/gtest/$(am__dirstamp) \ fused-src/gtest/$(DEPDIR)/$(am__dirstamp) fused-src/gtest/test_fused_gtest_test-gtest_main.$(OBJEXT): \ fused-src/gtest/$(am__dirstamp) \ fused-src/gtest/$(DEPDIR)/$(am__dirstamp) samples/test_fused_gtest_test-sample1.$(OBJEXT): \ samples/$(am__dirstamp) samples/$(DEPDIR)/$(am__dirstamp) samples/test_fused_gtest_test-sample1_unittest.$(OBJEXT): \ samples/$(am__dirstamp) samples/$(DEPDIR)/$(am__dirstamp) test/$(am__dirstamp): @$(MKDIR_P) test @: > test/$(am__dirstamp) test/fused_gtest_test$(EXEEXT): $(test_fused_gtest_test_OBJECTS) $(test_fused_gtest_test_DEPENDENCIES) $(EXTRA_test_fused_gtest_test_DEPENDENCIES) test/$(am__dirstamp) @rm -f test/fused_gtest_test$(EXEEXT) $(CXXLINK) $(test_fused_gtest_test_OBJECTS) $(test_fused_gtest_test_LDADD) $(LIBS) test/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) test/$(DEPDIR) @: > test/$(DEPDIR)/$(am__dirstamp) test/gtest_all_test.$(OBJEXT): test/$(am__dirstamp) \ test/$(DEPDIR)/$(am__dirstamp) test/gtest_all_test$(EXEEXT): $(test_gtest_all_test_OBJECTS) $(test_gtest_all_test_DEPENDENCIES) $(EXTRA_test_gtest_all_test_DEPENDENCIES) test/$(am__dirstamp) @rm -f test/gtest_all_test$(EXEEXT) $(CXXLINK) $(test_gtest_all_test_OBJECTS) $(test_gtest_all_test_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) -rm -f fused-src/gtest/test_fused_gtest_test-gtest-all.$(OBJEXT) -rm -f fused-src/gtest/test_fused_gtest_test-gtest_main.$(OBJEXT) -rm -f samples/sample1.$(OBJEXT) -rm -f samples/sample1.lo -rm -f samples/sample10_unittest.$(OBJEXT) -rm -f samples/sample1_unittest.$(OBJEXT) -rm -f samples/sample2.$(OBJEXT) -rm -f samples/sample2.lo -rm -f samples/sample4.$(OBJEXT) -rm -f samples/sample4.lo -rm -f samples/test_fused_gtest_test-sample1.$(OBJEXT) -rm -f samples/test_fused_gtest_test-sample1_unittest.$(OBJEXT) -rm -f src/gtest-all.$(OBJEXT) -rm -f src/gtest-all.lo -rm -f src/gtest_main.$(OBJEXT) -rm -f src/gtest_main.lo -rm -f test/gtest_all_test.$(OBJEXT) distclean-compile: -rm -f *.tab.c include fused-src/gtest/$(DEPDIR)/test_fused_gtest_test-gtest-all.Po include fused-src/gtest/$(DEPDIR)/test_fused_gtest_test-gtest_main.Po include samples/$(DEPDIR)/sample1.Plo include samples/$(DEPDIR)/sample10_unittest.Po include samples/$(DEPDIR)/sample1_unittest.Po include samples/$(DEPDIR)/sample2.Plo include samples/$(DEPDIR)/sample4.Plo include samples/$(DEPDIR)/test_fused_gtest_test-sample1.Po include samples/$(DEPDIR)/test_fused_gtest_test-sample1_unittest.Po include src/$(DEPDIR)/gtest-all.Plo include src/$(DEPDIR)/gtest_main.Plo include test/$(DEPDIR)/gtest_all_test.Po .cc.o: depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ $(am__mv) $$depbase.Tpo $$depbase.Po # source='$<' object='$@' libtool=no \ # DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \ # $(CXXCOMPILE) -c -o $@ $< .cc.obj: depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ $(am__mv) $$depbase.Tpo $$depbase.Po # source='$<' object='$@' libtool=no \ # DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \ # $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .cc.lo: depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ $(am__mv) $$depbase.Tpo $$depbase.Plo # source='$<' object='$@' libtool=yes \ # DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \ # $(LTCXXCOMPILE) -c -o $@ $< fused-src/gtest/test_fused_gtest_test-gtest-all.o: fused-src/gtest/gtest-all.cc $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_fused_gtest_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT fused-src/gtest/test_fused_gtest_test-gtest-all.o -MD -MP -MF fused-src/gtest/$(DEPDIR)/test_fused_gtest_test-gtest-all.Tpo -c -o fused-src/gtest/test_fused_gtest_test-gtest-all.o `test -f 'fused-src/gtest/gtest-all.cc' || echo '$(srcdir)/'`fused-src/gtest/gtest-all.cc $(am__mv) fused-src/gtest/$(DEPDIR)/test_fused_gtest_test-gtest-all.Tpo fused-src/gtest/$(DEPDIR)/test_fused_gtest_test-gtest-all.Po # source='fused-src/gtest/gtest-all.cc' object='fused-src/gtest/test_fused_gtest_test-gtest-all.o' libtool=no \ # DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \ # $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_fused_gtest_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o fused-src/gtest/test_fused_gtest_test-gtest-all.o `test -f 'fused-src/gtest/gtest-all.cc' || echo '$(srcdir)/'`fused-src/gtest/gtest-all.cc fused-src/gtest/test_fused_gtest_test-gtest-all.obj: fused-src/gtest/gtest-all.cc $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_fused_gtest_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT fused-src/gtest/test_fused_gtest_test-gtest-all.obj -MD -MP -MF fused-src/gtest/$(DEPDIR)/test_fused_gtest_test-gtest-all.Tpo -c -o fused-src/gtest/test_fused_gtest_test-gtest-all.obj `if test -f 'fused-src/gtest/gtest-all.cc'; then $(CYGPATH_W) 'fused-src/gtest/gtest-all.cc'; else $(CYGPATH_W) '$(srcdir)/fused-src/gtest/gtest-all.cc'; fi` $(am__mv) fused-src/gtest/$(DEPDIR)/test_fused_gtest_test-gtest-all.Tpo fused-src/gtest/$(DEPDIR)/test_fused_gtest_test-gtest-all.Po # source='fused-src/gtest/gtest-all.cc' object='fused-src/gtest/test_fused_gtest_test-gtest-all.obj' libtool=no \ # DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \ # $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_fused_gtest_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o fused-src/gtest/test_fused_gtest_test-gtest-all.obj `if test -f 'fused-src/gtest/gtest-all.cc'; then $(CYGPATH_W) 'fused-src/gtest/gtest-all.cc'; else $(CYGPATH_W) '$(srcdir)/fused-src/gtest/gtest-all.cc'; fi` fused-src/gtest/test_fused_gtest_test-gtest_main.o: fused-src/gtest/gtest_main.cc $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_fused_gtest_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT fused-src/gtest/test_fused_gtest_test-gtest_main.o -MD -MP -MF fused-src/gtest/$(DEPDIR)/test_fused_gtest_test-gtest_main.Tpo -c -o fused-src/gtest/test_fused_gtest_test-gtest_main.o `test -f 'fused-src/gtest/gtest_main.cc' || echo '$(srcdir)/'`fused-src/gtest/gtest_main.cc $(am__mv) fused-src/gtest/$(DEPDIR)/test_fused_gtest_test-gtest_main.Tpo fused-src/gtest/$(DEPDIR)/test_fused_gtest_test-gtest_main.Po # source='fused-src/gtest/gtest_main.cc' object='fused-src/gtest/test_fused_gtest_test-gtest_main.o' libtool=no \ # DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \ # $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_fused_gtest_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o fused-src/gtest/test_fused_gtest_test-gtest_main.o `test -f 'fused-src/gtest/gtest_main.cc' || echo '$(srcdir)/'`fused-src/gtest/gtest_main.cc fused-src/gtest/test_fused_gtest_test-gtest_main.obj: fused-src/gtest/gtest_main.cc $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_fused_gtest_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT fused-src/gtest/test_fused_gtest_test-gtest_main.obj -MD -MP -MF fused-src/gtest/$(DEPDIR)/test_fused_gtest_test-gtest_main.Tpo -c -o fused-src/gtest/test_fused_gtest_test-gtest_main.obj `if test -f 'fused-src/gtest/gtest_main.cc'; then $(CYGPATH_W) 'fused-src/gtest/gtest_main.cc'; else $(CYGPATH_W) '$(srcdir)/fused-src/gtest/gtest_main.cc'; fi` $(am__mv) fused-src/gtest/$(DEPDIR)/test_fused_gtest_test-gtest_main.Tpo fused-src/gtest/$(DEPDIR)/test_fused_gtest_test-gtest_main.Po # source='fused-src/gtest/gtest_main.cc' object='fused-src/gtest/test_fused_gtest_test-gtest_main.obj' libtool=no \ # DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \ # $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_fused_gtest_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o fused-src/gtest/test_fused_gtest_test-gtest_main.obj `if test -f 'fused-src/gtest/gtest_main.cc'; then $(CYGPATH_W) 'fused-src/gtest/gtest_main.cc'; else $(CYGPATH_W) '$(srcdir)/fused-src/gtest/gtest_main.cc'; fi` samples/test_fused_gtest_test-sample1.o: samples/sample1.cc $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_fused_gtest_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT samples/test_fused_gtest_test-sample1.o -MD -MP -MF samples/$(DEPDIR)/test_fused_gtest_test-sample1.Tpo -c -o samples/test_fused_gtest_test-sample1.o `test -f 'samples/sample1.cc' || echo '$(srcdir)/'`samples/sample1.cc $(am__mv) samples/$(DEPDIR)/test_fused_gtest_test-sample1.Tpo samples/$(DEPDIR)/test_fused_gtest_test-sample1.Po # source='samples/sample1.cc' object='samples/test_fused_gtest_test-sample1.o' libtool=no \ # DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \ # $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_fused_gtest_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o samples/test_fused_gtest_test-sample1.o `test -f 'samples/sample1.cc' || echo '$(srcdir)/'`samples/sample1.cc samples/test_fused_gtest_test-sample1.obj: samples/sample1.cc $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_fused_gtest_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT samples/test_fused_gtest_test-sample1.obj -MD -MP -MF samples/$(DEPDIR)/test_fused_gtest_test-sample1.Tpo -c -o samples/test_fused_gtest_test-sample1.obj `if test -f 'samples/sample1.cc'; then $(CYGPATH_W) 'samples/sample1.cc'; else $(CYGPATH_W) '$(srcdir)/samples/sample1.cc'; fi` $(am__mv) samples/$(DEPDIR)/test_fused_gtest_test-sample1.Tpo samples/$(DEPDIR)/test_fused_gtest_test-sample1.Po # source='samples/sample1.cc' object='samples/test_fused_gtest_test-sample1.obj' libtool=no \ # DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \ # $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_fused_gtest_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o samples/test_fused_gtest_test-sample1.obj `if test -f 'samples/sample1.cc'; then $(CYGPATH_W) 'samples/sample1.cc'; else $(CYGPATH_W) '$(srcdir)/samples/sample1.cc'; fi` samples/test_fused_gtest_test-sample1_unittest.o: samples/sample1_unittest.cc $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_fused_gtest_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT samples/test_fused_gtest_test-sample1_unittest.o -MD -MP -MF samples/$(DEPDIR)/test_fused_gtest_test-sample1_unittest.Tpo -c -o samples/test_fused_gtest_test-sample1_unittest.o `test -f 'samples/sample1_unittest.cc' || echo '$(srcdir)/'`samples/sample1_unittest.cc $(am__mv) samples/$(DEPDIR)/test_fused_gtest_test-sample1_unittest.Tpo samples/$(DEPDIR)/test_fused_gtest_test-sample1_unittest.Po # source='samples/sample1_unittest.cc' object='samples/test_fused_gtest_test-sample1_unittest.o' libtool=no \ # DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \ # $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_fused_gtest_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o samples/test_fused_gtest_test-sample1_unittest.o `test -f 'samples/sample1_unittest.cc' || echo '$(srcdir)/'`samples/sample1_unittest.cc samples/test_fused_gtest_test-sample1_unittest.obj: samples/sample1_unittest.cc $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_fused_gtest_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT samples/test_fused_gtest_test-sample1_unittest.obj -MD -MP -MF samples/$(DEPDIR)/test_fused_gtest_test-sample1_unittest.Tpo -c -o samples/test_fused_gtest_test-sample1_unittest.obj `if test -f 'samples/sample1_unittest.cc'; then $(CYGPATH_W) 'samples/sample1_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/samples/sample1_unittest.cc'; fi` $(am__mv) samples/$(DEPDIR)/test_fused_gtest_test-sample1_unittest.Tpo samples/$(DEPDIR)/test_fused_gtest_test-sample1_unittest.Po # source='samples/sample1_unittest.cc' object='samples/test_fused_gtest_test-sample1_unittest.obj' libtool=no \ # DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \ # $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_fused_gtest_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o samples/test_fused_gtest_test-sample1_unittest.obj `if test -f 'samples/sample1_unittest.cc'; then $(CYGPATH_W) 'samples/sample1_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/samples/sample1_unittest.cc'; fi` mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs -rm -rf lib/.libs lib/_libs -rm -rf samples/.libs samples/_libs -rm -rf src/.libs src/_libs -rm -rf test/.libs test/_libs distclean-libtool: -rm -f libtool config.lt install-m4dataDATA: $(m4data_DATA) @$(NORMAL_INSTALL) test -z "$(m4datadir)" || $(MKDIR_P) "$(DESTDIR)$(m4datadir)" @list='$(m4data_DATA)'; test -n "$(m4datadir)" || list=; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(m4datadir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(m4datadir)" || exit $$?; \ done uninstall-m4dataDATA: @$(NORMAL_UNINSTALL) @list='$(m4data_DATA)'; test -n "$(m4datadir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(m4datadir)'; $(am__uninstall_files_from_dir) install-pkgincludeHEADERS: $(pkginclude_HEADERS) @$(NORMAL_INSTALL) test -z "$(pkgincludedir)" || $(MKDIR_P) "$(DESTDIR)$(pkgincludedir)" @list='$(pkginclude_HEADERS)'; test -n "$(pkgincludedir)" || list=; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(pkgincludedir)'"; \ $(INSTALL_HEADER) $$files "$(DESTDIR)$(pkgincludedir)" || exit $$?; \ done uninstall-pkgincludeHEADERS: @$(NORMAL_UNINSTALL) @list='$(pkginclude_HEADERS)'; test -n "$(pkgincludedir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(pkgincludedir)'; $(am__uninstall_files_from_dir) install-pkginclude_internalHEADERS: $(pkginclude_internal_HEADERS) @$(NORMAL_INSTALL) test -z "$(pkginclude_internaldir)" || $(MKDIR_P) "$(DESTDIR)$(pkginclude_internaldir)" @list='$(pkginclude_internal_HEADERS)'; test -n "$(pkginclude_internaldir)" || list=; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(pkginclude_internaldir)'"; \ $(INSTALL_HEADER) $$files "$(DESTDIR)$(pkginclude_internaldir)" || exit $$?; \ done uninstall-pkginclude_internalHEADERS: @$(NORMAL_UNINSTALL) @list='$(pkginclude_internal_HEADERS)'; test -n "$(pkginclude_internaldir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(pkginclude_internaldir)'; $(am__uninstall_files_from_dir) ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags check-TESTS: $(TESTS) @failed=0; all=0; xfail=0; xpass=0; skip=0; \ srcdir=$(srcdir); export srcdir; \ list=' $(TESTS) '; \ $(am__tty_colors); \ if test -n "$$list"; then \ for tst in $$list; do \ if test -f ./$$tst; then dir=./; \ elif test -f $$tst; then dir=; \ else dir="$(srcdir)/"; fi; \ if $(TESTS_ENVIRONMENT) $${dir}$$tst; then \ all=`expr $$all + 1`; \ case " $(XFAIL_TESTS) " in \ *[\ \ ]$$tst[\ \ ]*) \ xpass=`expr $$xpass + 1`; \ failed=`expr $$failed + 1`; \ col=$$red; res=XPASS; \ ;; \ *) \ col=$$grn; res=PASS; \ ;; \ esac; \ elif test $$? -ne 77; then \ all=`expr $$all + 1`; \ case " $(XFAIL_TESTS) " in \ *[\ \ ]$$tst[\ \ ]*) \ xfail=`expr $$xfail + 1`; \ col=$$lgn; res=XFAIL; \ ;; \ *) \ failed=`expr $$failed + 1`; \ col=$$red; res=FAIL; \ ;; \ esac; \ else \ skip=`expr $$skip + 1`; \ col=$$blu; res=SKIP; \ fi; \ echo "$${col}$$res$${std}: $$tst"; \ done; \ if test "$$all" -eq 1; then \ tests="test"; \ All=""; \ else \ tests="tests"; \ All="All "; \ fi; \ if test "$$failed" -eq 0; then \ if test "$$xfail" -eq 0; then \ banner="$$All$$all $$tests passed"; \ else \ if test "$$xfail" -eq 1; then failures=failure; else failures=failures; fi; \ banner="$$All$$all $$tests behaved as expected ($$xfail expected $$failures)"; \ fi; \ else \ if test "$$xpass" -eq 0; then \ banner="$$failed of $$all $$tests failed"; \ else \ if test "$$xpass" -eq 1; then passes=pass; else passes=passes; fi; \ banner="$$failed of $$all $$tests did not behave as expected ($$xpass unexpected $$passes)"; \ fi; \ fi; \ dashes="$$banner"; \ skipped=""; \ if test "$$skip" -ne 0; then \ if test "$$skip" -eq 1; then \ skipped="($$skip test was not run)"; \ else \ skipped="($$skip tests were not run)"; \ fi; \ test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \ dashes="$$skipped"; \ fi; \ report=""; \ if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \ report="Please report to $(PACKAGE_BUGREPORT)"; \ test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \ dashes="$$report"; \ fi; \ dashes=`echo "$$dashes" | sed s/./=/g`; \ if test "$$failed" -eq 0; then \ col="$$grn"; \ else \ col="$$red"; \ fi; \ echo "$${col}$$dashes$${std}"; \ echo "$${col}$$banner$${std}"; \ test -z "$$skipped" || echo "$${col}$$skipped$${std}"; \ test -z "$$report" || echo "$${col}$$report$${std}"; \ echo "$${col}$$dashes$${std}"; \ test "$$failed" -eq 0; \ else :; fi distdir: $(DISTFILES) $(am__remove_distdir) test -d "$(distdir)" || mkdir "$(distdir)" @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done -test -n "$(am__skip_mode_fix)" \ || find "$(distdir)" -type d ! -perm -755 \ -exec chmod u+rwx,go+rx {} \; -o \ ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ || chmod -R a+r "$(distdir)" dist-gzip: distdir tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz $(am__remove_distdir) dist-bzip2: distdir tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2 $(am__remove_distdir) dist-lzip: distdir tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz $(am__remove_distdir) dist-lzma: distdir tardir=$(distdir) && $(am__tar) | lzma -9 -c >$(distdir).tar.lzma $(am__remove_distdir) dist-xz: distdir tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz $(am__remove_distdir) dist-tarZ: distdir tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z $(am__remove_distdir) dist-shar: distdir shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz $(am__remove_distdir) dist-zip: distdir -rm -f $(distdir).zip zip -rq $(distdir).zip $(distdir) $(am__remove_distdir) dist dist-all: distdir tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2 -rm -f $(distdir).zip zip -rq $(distdir).zip $(distdir) $(am__remove_distdir) # This target untars the dist file and tries a VPATH configuration. Then # it guarantees that the distribution is self-contained by making another # tarfile. distcheck: dist case '$(DIST_ARCHIVES)' in \ *.tar.gz*) \ GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\ *.tar.bz2*) \ bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ *.tar.lzma*) \ lzma -dc $(distdir).tar.lzma | $(am__untar) ;;\ *.tar.lz*) \ lzip -dc $(distdir).tar.lz | $(am__untar) ;;\ *.tar.xz*) \ xz -dc $(distdir).tar.xz | $(am__untar) ;;\ *.tar.Z*) \ uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ *.shar.gz*) \ GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\ *.zip*) \ unzip $(distdir).zip ;;\ esac chmod -R a-w $(distdir); chmod a+w $(distdir) mkdir $(distdir)/_build mkdir $(distdir)/_inst chmod a-w $(distdir) test -d $(distdir)/_build || exit 0; \ dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ && am__cwd=`pwd` \ && $(am__cd) $(distdir)/_build \ && ../configure --srcdir=.. --prefix="$$dc_install_base" \ $(AM_DISTCHECK_CONFIGURE_FLAGS) \ $(DISTCHECK_CONFIGURE_FLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) dvi \ && $(MAKE) $(AM_MAKEFLAGS) check \ && $(MAKE) $(AM_MAKEFLAGS) install \ && $(MAKE) $(AM_MAKEFLAGS) installcheck \ && $(MAKE) $(AM_MAKEFLAGS) uninstall \ && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ distuninstallcheck \ && chmod -R a-w "$$dc_install_base" \ && ({ \ (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ } || { rm -rf "$$dc_destdir"; exit 1; }) \ && rm -rf "$$dc_destdir" \ && $(MAKE) $(AM_MAKEFLAGS) dist \ && rm -rf $(DIST_ARCHIVES) \ && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ && cd "$$am__cwd" \ || exit 1 $(am__remove_distdir) @(echo "$(distdir) archives ready for distribution: "; \ list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' distuninstallcheck: @test -n '$(distuninstallcheck_dir)' || { \ echo 'ERROR: trying to run $@ with an empty' \ '$$(distuninstallcheck_dir)' >&2; \ exit 1; \ }; \ $(am__cd) '$(distuninstallcheck_dir)' || { \ echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \ exit 1; \ }; \ test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \ || { echo "ERROR: files left after uninstall:" ; \ if test -n "$(DESTDIR)"; then \ echo " (check DESTDIR support)"; \ fi ; \ $(distuninstallcheck_listfiles) ; \ exit 1; } >&2 distcleancheck: distclean @if test '$(srcdir)' = . ; then \ echo "ERROR: distcleancheck can only run from a VPATH build" ; \ exit 1 ; \ fi @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ || { echo "ERROR: files left in build directory after distclean:" ; \ $(distcleancheck_listfiles) ; \ exit 1; } >&2 check-am: all-am $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) $(MAKE) $(AM_MAKEFLAGS) check-TESTS check: check-am all-am: Makefile $(LTLIBRARIES) $(DATA) $(HEADERS) installdirs: for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(m4datadir)" "$(DESTDIR)$(pkgincludedir)" "$(DESTDIR)$(pkginclude_internaldir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) -rm -f fused-src/gtest/$(DEPDIR)/$(am__dirstamp) -rm -f fused-src/gtest/$(am__dirstamp) -rm -f lib/$(am__dirstamp) -rm -f samples/$(DEPDIR)/$(am__dirstamp) -rm -f samples/$(am__dirstamp) -rm -f src/$(DEPDIR)/$(am__dirstamp) -rm -f src/$(am__dirstamp) -rm -f test/$(DEPDIR)/$(am__dirstamp) -rm -f test/$(am__dirstamp) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." #maintainer-clean-local: clean: clean-am clean-am: clean-checkPROGRAMS clean-generic clean-libLTLIBRARIES \ clean-libtool clean-noinstLTLIBRARIES mostlyclean-am distclean: distclean-am -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -rf fused-src/gtest/$(DEPDIR) samples/$(DEPDIR) src/$(DEPDIR) test/$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-hdr distclean-libtool distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-data-local install-m4dataDATA \ install-pkgincludeHEADERS install-pkginclude_internalHEADERS install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-exec-local install-libLTLIBRARIES install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -rf $(top_srcdir)/autom4te.cache -rm -rf fused-src/gtest/$(DEPDIR) samples/$(DEPDIR) src/$(DEPDIR) test/$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic \ maintainer-clean-local mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-libLTLIBRARIES uninstall-m4dataDATA \ uninstall-pkgincludeHEADERS \ uninstall-pkginclude_internalHEADERS .MAKE: check-am install-am install-strip .PHONY: CTAGS GTAGS all all-am am--refresh check check-TESTS check-am \ clean clean-checkPROGRAMS clean-generic clean-libLTLIBRARIES \ clean-libtool clean-noinstLTLIBRARIES ctags dist dist-all \ dist-bzip2 dist-gzip dist-lzip dist-lzma dist-shar dist-tarZ \ dist-xz dist-zip distcheck distclean distclean-compile \ distclean-generic distclean-hdr distclean-libtool \ distclean-tags distcleancheck distdir distuninstallcheck dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-data-local install-dvi \ install-dvi-am install-exec install-exec-am install-exec-local \ install-html install-html-am install-info install-info-am \ install-libLTLIBRARIES install-m4dataDATA install-man \ install-pdf install-pdf-am install-pkgincludeHEADERS \ install-pkginclude_internalHEADERS install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic \ maintainer-clean-local mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags uninstall uninstall-am uninstall-libLTLIBRARIES \ uninstall-m4dataDATA uninstall-pkgincludeHEADERS \ uninstall-pkginclude_internalHEADERS # Build rules for putting fused Google Test files into the distribution # package. The user can also create those files by manually running # scripts/fuse_gtest_files.py. $(test_fused_gtest_test_SOURCES): fused-gtest fused-gtest: $(pkginclude_HEADERS) $(pkginclude_internal_HEADERS) \ $(GTEST_SRC) src/gtest-all.cc src/gtest_main.cc \ scripts/fuse_gtest_files.py mkdir -p "$(srcdir)/fused-src" chmod -R u+w "$(srcdir)/fused-src" rm -f "$(srcdir)/fused-src/gtest/gtest-all.cc" rm -f "$(srcdir)/fused-src/gtest/gtest.h" "$(srcdir)/scripts/fuse_gtest_files.py" "$(srcdir)/fused-src" cp -f "$(srcdir)/src/gtest_main.cc" "$(srcdir)/fused-src/gtest/" maintainer-clean-local: rm -rf "$(srcdir)/fused-src" # Disables 'make install' as installing a compiled version of Google # Test can lead to undefined behavior due to violation of the # One-Definition Rule. install-exec-local: echo "'make install' is dangerous and not supported. Instead, see README for how to integrate Google Test into your build system." false install-data-local: echo "'make install' is dangerous and not supported. Instead, see README for how to integrate Google Test into your build system." false # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: dlt-daemon-2.18.4/gtest-1.7.0/Makefile.am000066400000000000000000000230131353342203500174540ustar00rootroot00000000000000# Automake file ACLOCAL_AMFLAGS = -I m4 # Nonstandard package files for distribution EXTRA_DIST = \ CHANGES \ CONTRIBUTORS \ LICENSE \ include/gtest/gtest-param-test.h.pump \ include/gtest/internal/gtest-param-util-generated.h.pump \ include/gtest/internal/gtest-tuple.h.pump \ include/gtest/internal/gtest-type-util.h.pump \ make/Makefile \ scripts/fuse_gtest_files.py \ scripts/gen_gtest_pred_impl.py \ scripts/pump.py \ scripts/test/Makefile # gtest source files that we don't compile directly. They are # #included by gtest-all.cc. GTEST_SRC = \ src/gtest-death-test.cc \ src/gtest-filepath.cc \ src/gtest-internal-inl.h \ src/gtest-port.cc \ src/gtest-printers.cc \ src/gtest-test-part.cc \ src/gtest-typed-test.cc \ src/gtest.cc EXTRA_DIST += $(GTEST_SRC) # Sample files that we don't compile. EXTRA_DIST += \ samples/prime_tables.h \ samples/sample2_unittest.cc \ samples/sample3_unittest.cc \ samples/sample4_unittest.cc \ samples/sample5_unittest.cc \ samples/sample6_unittest.cc \ samples/sample7_unittest.cc \ samples/sample8_unittest.cc \ samples/sample9_unittest.cc # C++ test files that we don't compile directly. EXTRA_DIST += \ test/gtest-death-test_ex_test.cc \ test/gtest-death-test_test.cc \ test/gtest-filepath_test.cc \ test/gtest-linked_ptr_test.cc \ test/gtest-listener_test.cc \ test/gtest-message_test.cc \ test/gtest-options_test.cc \ test/gtest-param-test2_test.cc \ test/gtest-param-test2_test.cc \ test/gtest-param-test_test.cc \ test/gtest-param-test_test.cc \ test/gtest-param-test_test.h \ test/gtest-port_test.cc \ test/gtest_premature_exit_test.cc \ test/gtest-printers_test.cc \ test/gtest-test-part_test.cc \ test/gtest-tuple_test.cc \ test/gtest-typed-test2_test.cc \ test/gtest-typed-test_test.cc \ test/gtest-typed-test_test.h \ test/gtest-unittest-api_test.cc \ test/gtest_break_on_failure_unittest_.cc \ test/gtest_catch_exceptions_test_.cc \ test/gtest_color_test_.cc \ test/gtest_env_var_test_.cc \ test/gtest_environment_test.cc \ test/gtest_filter_unittest_.cc \ test/gtest_help_test_.cc \ test/gtest_list_tests_unittest_.cc \ test/gtest_main_unittest.cc \ test/gtest_no_test_unittest.cc \ test/gtest_output_test_.cc \ test/gtest_pred_impl_unittest.cc \ test/gtest_prod_test.cc \ test/gtest_repeat_test.cc \ test/gtest_shuffle_test_.cc \ test/gtest_sole_header_test.cc \ test/gtest_stress_test.cc \ test/gtest_throw_on_failure_ex_test.cc \ test/gtest_throw_on_failure_test_.cc \ test/gtest_uninitialized_test_.cc \ test/gtest_unittest.cc \ test/gtest_unittest.cc \ test/gtest_xml_outfile1_test_.cc \ test/gtest_xml_outfile2_test_.cc \ test/gtest_xml_output_unittest_.cc \ test/production.cc \ test/production.h # Python tests that we don't run. EXTRA_DIST += \ test/gtest_break_on_failure_unittest.py \ test/gtest_catch_exceptions_test.py \ test/gtest_color_test.py \ test/gtest_env_var_test.py \ test/gtest_filter_unittest.py \ test/gtest_help_test.py \ test/gtest_list_tests_unittest.py \ test/gtest_output_test.py \ test/gtest_output_test_golden_lin.txt \ test/gtest_shuffle_test.py \ test/gtest_test_utils.py \ test/gtest_throw_on_failure_test.py \ test/gtest_uninitialized_test.py \ test/gtest_xml_outfiles_test.py \ test/gtest_xml_output_unittest.py \ test/gtest_xml_test_utils.py # CMake script EXTRA_DIST += \ CMakeLists.txt \ cmake/internal_utils.cmake # MSVC project files EXTRA_DIST += \ msvc/gtest-md.sln \ msvc/gtest-md.vcproj \ msvc/gtest.sln \ msvc/gtest.vcproj \ msvc/gtest_main-md.vcproj \ msvc/gtest_main.vcproj \ msvc/gtest_prod_test-md.vcproj \ msvc/gtest_prod_test.vcproj \ msvc/gtest_unittest-md.vcproj \ msvc/gtest_unittest.vcproj # xcode project files EXTRA_DIST += \ xcode/Config/DebugProject.xcconfig \ xcode/Config/FrameworkTarget.xcconfig \ xcode/Config/General.xcconfig \ xcode/Config/ReleaseProject.xcconfig \ xcode/Config/StaticLibraryTarget.xcconfig \ xcode/Config/TestTarget.xcconfig \ xcode/Resources/Info.plist \ xcode/Scripts/runtests.sh \ xcode/Scripts/versiongenerate.py \ xcode/gtest.xcodeproj/project.pbxproj # xcode sample files EXTRA_DIST += \ xcode/Samples/FrameworkSample/Info.plist \ xcode/Samples/FrameworkSample/WidgetFramework.xcodeproj/project.pbxproj \ xcode/Samples/FrameworkSample/runtests.sh \ xcode/Samples/FrameworkSample/widget.cc \ xcode/Samples/FrameworkSample/widget.h \ xcode/Samples/FrameworkSample/widget_test.cc # C++Builder project files EXTRA_DIST += \ codegear/gtest.cbproj \ codegear/gtest.groupproj \ codegear/gtest_all.cc \ codegear/gtest_link.cc \ codegear/gtest_main.cbproj \ codegear/gtest_unittest.cbproj # Distribute and install M4 macro m4datadir = $(datadir)/aclocal m4data_DATA = m4/gtest.m4 EXTRA_DIST += $(m4data_DATA) # We define the global AM_CPPFLAGS as everything we compile includes from these # directories. AM_CPPFLAGS = -I$(srcdir) -I$(srcdir)/include # Modifies compiler and linker flags for pthreads compatibility. if HAVE_PTHREADS AM_CXXFLAGS = @PTHREAD_CFLAGS@ -DGTEST_HAS_PTHREAD=1 AM_LIBS = @PTHREAD_LIBS@ else AM_CXXFLAGS = -DGTEST_HAS_PTHREAD=0 endif # Build rules for libraries. lib_LTLIBRARIES = lib/libgtest.la lib/libgtest_main.la lib_libgtest_la_SOURCES = src/gtest-all.cc pkginclude_HEADERS = \ include/gtest/gtest-death-test.h \ include/gtest/gtest-message.h \ include/gtest/gtest-param-test.h \ include/gtest/gtest-printers.h \ include/gtest/gtest-spi.h \ include/gtest/gtest-test-part.h \ include/gtest/gtest-typed-test.h \ include/gtest/gtest.h \ include/gtest/gtest_pred_impl.h \ include/gtest/gtest_prod.h pkginclude_internaldir = $(pkgincludedir)/internal pkginclude_internal_HEADERS = \ include/gtest/internal/gtest-death-test-internal.h \ include/gtest/internal/gtest-filepath.h \ include/gtest/internal/gtest-internal.h \ include/gtest/internal/gtest-linked_ptr.h \ include/gtest/internal/gtest-param-util-generated.h \ include/gtest/internal/gtest-param-util.h \ include/gtest/internal/gtest-port.h \ include/gtest/internal/gtest-string.h \ include/gtest/internal/gtest-tuple.h \ include/gtest/internal/gtest-type-util.h lib_libgtest_main_la_SOURCES = src/gtest_main.cc lib_libgtest_main_la_LIBADD = lib/libgtest.la # Bulid rules for samples and tests. Automake's naming for some of # these variables isn't terribly obvious, so this is a brief # reference: # # TESTS -- Programs run automatically by "make check" # check_PROGRAMS -- Programs built by "make check" but not necessarily run noinst_LTLIBRARIES = samples/libsamples.la samples_libsamples_la_SOURCES = \ samples/sample1.cc \ samples/sample1.h \ samples/sample2.cc \ samples/sample2.h \ samples/sample3-inl.h \ samples/sample4.cc \ samples/sample4.h TESTS= TESTS_ENVIRONMENT = GTEST_SOURCE_DIR="$(srcdir)/test" \ GTEST_BUILD_DIR="$(top_builddir)/test" check_PROGRAMS= # A simple sample on using gtest. TESTS += samples/sample1_unittest check_PROGRAMS += samples/sample1_unittest samples_sample1_unittest_SOURCES = samples/sample1_unittest.cc samples_sample1_unittest_LDADD = lib/libgtest_main.la \ lib/libgtest.la \ samples/libsamples.la # Another sample. It also verifies that libgtest works. TESTS += samples/sample10_unittest check_PROGRAMS += samples/sample10_unittest samples_sample10_unittest_SOURCES = samples/sample10_unittest.cc samples_sample10_unittest_LDADD = lib/libgtest.la # This tests most constructs of gtest and verifies that libgtest_main # and libgtest work. TESTS += test/gtest_all_test check_PROGRAMS += test/gtest_all_test test_gtest_all_test_SOURCES = test/gtest_all_test.cc test_gtest_all_test_LDADD = lib/libgtest_main.la \ lib/libgtest.la # Tests that fused gtest files compile and work. FUSED_GTEST_SRC = \ fused-src/gtest/gtest-all.cc \ fused-src/gtest/gtest.h \ fused-src/gtest/gtest_main.cc if HAVE_PYTHON TESTS += test/fused_gtest_test check_PROGRAMS += test/fused_gtest_test test_fused_gtest_test_SOURCES = $(FUSED_GTEST_SRC) \ samples/sample1.cc samples/sample1_unittest.cc test_fused_gtest_test_CPPFLAGS = -I"$(srcdir)/fused-src" # Build rules for putting fused Google Test files into the distribution # package. The user can also create those files by manually running # scripts/fuse_gtest_files.py. $(test_fused_gtest_test_SOURCES): fused-gtest fused-gtest: $(pkginclude_HEADERS) $(pkginclude_internal_HEADERS) \ $(GTEST_SRC) src/gtest-all.cc src/gtest_main.cc \ scripts/fuse_gtest_files.py mkdir -p "$(srcdir)/fused-src" chmod -R u+w "$(srcdir)/fused-src" rm -f "$(srcdir)/fused-src/gtest/gtest-all.cc" rm -f "$(srcdir)/fused-src/gtest/gtest.h" "$(srcdir)/scripts/fuse_gtest_files.py" "$(srcdir)/fused-src" cp -f "$(srcdir)/src/gtest_main.cc" "$(srcdir)/fused-src/gtest/" maintainer-clean-local: rm -rf "$(srcdir)/fused-src" endif # Death tests may produce core dumps in the build directory. In case # this happens, clean them to keep distcleancheck happy. CLEANFILES = core # Disables 'make install' as installing a compiled version of Google # Test can lead to undefined behavior due to violation of the # One-Definition Rule. install-exec-local: echo "'make install' is dangerous and not supported. Instead, see README for how to integrate Google Test into your build system." false install-data-local: echo "'make install' is dangerous and not supported. Instead, see README for how to integrate Google Test into your build system." false dlt-daemon-2.18.4/gtest-1.7.0/Makefile.in000066400000000000000000001632441353342203500175000ustar00rootroot00000000000000# Makefile.in generated by automake 1.11.3 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software # Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # Automake file VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ TESTS = samples/sample1_unittest$(EXEEXT) \ samples/sample10_unittest$(EXEEXT) \ test/gtest_all_test$(EXEEXT) $(am__EXEEXT_1) check_PROGRAMS = samples/sample1_unittest$(EXEEXT) \ samples/sample10_unittest$(EXEEXT) \ test/gtest_all_test$(EXEEXT) $(am__EXEEXT_1) @HAVE_PYTHON_TRUE@am__append_1 = test/fused_gtest_test @HAVE_PYTHON_TRUE@am__append_2 = test/fused_gtest_test subdir = . DIST_COMMON = README $(am__configure_deps) $(pkginclude_HEADERS) \ $(pkginclude_internal_HEADERS) $(srcdir)/Makefile.am \ $(srcdir)/Makefile.in $(top_srcdir)/build-aux/config.h.in \ $(top_srcdir)/configure $(top_srcdir)/scripts/gtest-config.in \ build-aux/config.guess build-aux/config.sub build-aux/depcomp \ build-aux/install-sh build-aux/ltmain.sh build-aux/missing ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/acx_pthread.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ configure.lineno config.status.lineno mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/build-aux/config.h CONFIG_CLEAN_FILES = scripts/gtest-config CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(m4datadir)" \ "$(DESTDIR)$(pkgincludedir)" \ "$(DESTDIR)$(pkginclude_internaldir)" LTLIBRARIES = $(lib_LTLIBRARIES) $(noinst_LTLIBRARIES) lib_libgtest_la_LIBADD = am__dirstamp = $(am__leading_dot)dirstamp am_lib_libgtest_la_OBJECTS = src/gtest-all.lo lib_libgtest_la_OBJECTS = $(am_lib_libgtest_la_OBJECTS) lib_libgtest_main_la_DEPENDENCIES = lib/libgtest.la am_lib_libgtest_main_la_OBJECTS = src/gtest_main.lo lib_libgtest_main_la_OBJECTS = $(am_lib_libgtest_main_la_OBJECTS) samples_libsamples_la_LIBADD = am_samples_libsamples_la_OBJECTS = samples/sample1.lo \ samples/sample2.lo samples/sample4.lo samples_libsamples_la_OBJECTS = $(am_samples_libsamples_la_OBJECTS) @HAVE_PYTHON_TRUE@am__EXEEXT_1 = test/fused_gtest_test$(EXEEXT) am_samples_sample10_unittest_OBJECTS = \ samples/sample10_unittest.$(OBJEXT) samples_sample10_unittest_OBJECTS = \ $(am_samples_sample10_unittest_OBJECTS) samples_sample10_unittest_DEPENDENCIES = lib/libgtest.la am_samples_sample1_unittest_OBJECTS = \ samples/sample1_unittest.$(OBJEXT) samples_sample1_unittest_OBJECTS = \ $(am_samples_sample1_unittest_OBJECTS) samples_sample1_unittest_DEPENDENCIES = lib/libgtest_main.la \ lib/libgtest.la samples/libsamples.la am__test_fused_gtest_test_SOURCES_DIST = fused-src/gtest/gtest-all.cc \ fused-src/gtest/gtest.h fused-src/gtest/gtest_main.cc \ samples/sample1.cc samples/sample1_unittest.cc am__objects_1 = \ fused-src/gtest/test_fused_gtest_test-gtest-all.$(OBJEXT) \ fused-src/gtest/test_fused_gtest_test-gtest_main.$(OBJEXT) @HAVE_PYTHON_TRUE@am_test_fused_gtest_test_OBJECTS = $(am__objects_1) \ @HAVE_PYTHON_TRUE@ samples/test_fused_gtest_test-sample1.$(OBJEXT) \ @HAVE_PYTHON_TRUE@ samples/test_fused_gtest_test-sample1_unittest.$(OBJEXT) test_fused_gtest_test_OBJECTS = $(am_test_fused_gtest_test_OBJECTS) test_fused_gtest_test_LDADD = $(LDADD) am_test_gtest_all_test_OBJECTS = test/gtest_all_test.$(OBJEXT) test_gtest_all_test_OBJECTS = $(am_test_gtest_all_test_OBJECTS) test_gtest_all_test_DEPENDENCIES = lib/libgtest_main.la \ lib/libgtest.la DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/build-aux depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__depfiles_maybe = depfiles am__mv = mv -f CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) CXXLD = $(CXX) CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ SOURCES = $(lib_libgtest_la_SOURCES) $(lib_libgtest_main_la_SOURCES) \ $(samples_libsamples_la_SOURCES) \ $(samples_sample10_unittest_SOURCES) \ $(samples_sample1_unittest_SOURCES) \ $(test_fused_gtest_test_SOURCES) \ $(test_gtest_all_test_SOURCES) DIST_SOURCES = $(lib_libgtest_la_SOURCES) \ $(lib_libgtest_main_la_SOURCES) \ $(samples_libsamples_la_SOURCES) \ $(samples_sample10_unittest_SOURCES) \ $(samples_sample1_unittest_SOURCES) \ $(am__test_fused_gtest_test_SOURCES_DIST) \ $(test_gtest_all_test_SOURCES) DATA = $(m4data_DATA) HEADERS = $(pkginclude_HEADERS) $(pkginclude_internal_HEADERS) ETAGS = etags CTAGS = ctags am__tty_colors = \ red=; grn=; lgn=; blu=; std= DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) distdir = $(PACKAGE)-$(VERSION) top_distdir = $(distdir) am__remove_distdir = \ if test -d "$(distdir)"; then \ find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ && rm -rf "$(distdir)" \ || { sleep 5 && rm -rf "$(distdir)"; }; \ else :; fi DIST_ARCHIVES = $(distdir).tar.gz $(distdir).tar.bz2 $(distdir).zip GZIP_ENV = --best distuninstallcheck_listfiles = find . -type f -print am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \ | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$' distcleancheck_listfiles = find . -type f -print ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON = @PYTHON@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ acx_pthread_config = @acx_pthread_config@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ ACLOCAL_AMFLAGS = -I m4 # Nonstandard package files for distribution # Sample files that we don't compile. # C++ test files that we don't compile directly. # Python tests that we don't run. # CMake script # MSVC project files # xcode project files # xcode sample files # C++Builder project files EXTRA_DIST = CHANGES CONTRIBUTORS LICENSE \ include/gtest/gtest-param-test.h.pump \ include/gtest/internal/gtest-param-util-generated.h.pump \ include/gtest/internal/gtest-tuple.h.pump \ include/gtest/internal/gtest-type-util.h.pump make/Makefile \ scripts/fuse_gtest_files.py scripts/gen_gtest_pred_impl.py \ scripts/pump.py scripts/test/Makefile $(GTEST_SRC) \ samples/prime_tables.h samples/sample2_unittest.cc \ samples/sample3_unittest.cc samples/sample4_unittest.cc \ samples/sample5_unittest.cc samples/sample6_unittest.cc \ samples/sample7_unittest.cc samples/sample8_unittest.cc \ samples/sample9_unittest.cc test/gtest-death-test_ex_test.cc \ test/gtest-death-test_test.cc test/gtest-filepath_test.cc \ test/gtest-linked_ptr_test.cc test/gtest-listener_test.cc \ test/gtest-message_test.cc test/gtest-options_test.cc \ test/gtest-param-test2_test.cc test/gtest-param-test2_test.cc \ test/gtest-param-test_test.cc test/gtest-param-test_test.cc \ test/gtest-param-test_test.h test/gtest-port_test.cc \ test/gtest_premature_exit_test.cc test/gtest-printers_test.cc \ test/gtest-test-part_test.cc test/gtest-tuple_test.cc \ test/gtest-typed-test2_test.cc test/gtest-typed-test_test.cc \ test/gtest-typed-test_test.h test/gtest-unittest-api_test.cc \ test/gtest_break_on_failure_unittest_.cc \ test/gtest_catch_exceptions_test_.cc test/gtest_color_test_.cc \ test/gtest_env_var_test_.cc test/gtest_environment_test.cc \ test/gtest_filter_unittest_.cc test/gtest_help_test_.cc \ test/gtest_list_tests_unittest_.cc test/gtest_main_unittest.cc \ test/gtest_no_test_unittest.cc test/gtest_output_test_.cc \ test/gtest_pred_impl_unittest.cc test/gtest_prod_test.cc \ test/gtest_repeat_test.cc test/gtest_shuffle_test_.cc \ test/gtest_sole_header_test.cc test/gtest_stress_test.cc \ test/gtest_throw_on_failure_ex_test.cc \ test/gtest_throw_on_failure_test_.cc \ test/gtest_uninitialized_test_.cc test/gtest_unittest.cc \ test/gtest_unittest.cc test/gtest_xml_outfile1_test_.cc \ test/gtest_xml_outfile2_test_.cc \ test/gtest_xml_output_unittest_.cc test/production.cc \ test/production.h test/gtest_break_on_failure_unittest.py \ test/gtest_catch_exceptions_test.py test/gtest_color_test.py \ test/gtest_env_var_test.py test/gtest_filter_unittest.py \ test/gtest_help_test.py test/gtest_list_tests_unittest.py \ test/gtest_output_test.py \ test/gtest_output_test_golden_lin.txt \ test/gtest_shuffle_test.py test/gtest_test_utils.py \ test/gtest_throw_on_failure_test.py \ test/gtest_uninitialized_test.py \ test/gtest_xml_outfiles_test.py \ test/gtest_xml_output_unittest.py test/gtest_xml_test_utils.py \ CMakeLists.txt cmake/internal_utils.cmake msvc/gtest-md.sln \ msvc/gtest-md.vcproj msvc/gtest.sln msvc/gtest.vcproj \ msvc/gtest_main-md.vcproj msvc/gtest_main.vcproj \ msvc/gtest_prod_test-md.vcproj msvc/gtest_prod_test.vcproj \ msvc/gtest_unittest-md.vcproj msvc/gtest_unittest.vcproj \ xcode/Config/DebugProject.xcconfig \ xcode/Config/FrameworkTarget.xcconfig \ xcode/Config/General.xcconfig \ xcode/Config/ReleaseProject.xcconfig \ xcode/Config/StaticLibraryTarget.xcconfig \ xcode/Config/TestTarget.xcconfig xcode/Resources/Info.plist \ xcode/Scripts/runtests.sh xcode/Scripts/versiongenerate.py \ xcode/gtest.xcodeproj/project.pbxproj \ xcode/Samples/FrameworkSample/Info.plist \ xcode/Samples/FrameworkSample/WidgetFramework.xcodeproj/project.pbxproj \ xcode/Samples/FrameworkSample/runtests.sh \ xcode/Samples/FrameworkSample/widget.cc \ xcode/Samples/FrameworkSample/widget.h \ xcode/Samples/FrameworkSample/widget_test.cc \ codegear/gtest.cbproj codegear/gtest.groupproj \ codegear/gtest_all.cc codegear/gtest_link.cc \ codegear/gtest_main.cbproj codegear/gtest_unittest.cbproj \ $(m4data_DATA) # gtest source files that we don't compile directly. They are # #included by gtest-all.cc. GTEST_SRC = \ src/gtest-death-test.cc \ src/gtest-filepath.cc \ src/gtest-internal-inl.h \ src/gtest-port.cc \ src/gtest-printers.cc \ src/gtest-test-part.cc \ src/gtest-typed-test.cc \ src/gtest.cc # Distribute and install M4 macro m4datadir = $(datadir)/aclocal m4data_DATA = m4/gtest.m4 # We define the global AM_CPPFLAGS as everything we compile includes from these # directories. AM_CPPFLAGS = -I$(srcdir) -I$(srcdir)/include @HAVE_PTHREADS_FALSE@AM_CXXFLAGS = -DGTEST_HAS_PTHREAD=0 # Modifies compiler and linker flags for pthreads compatibility. @HAVE_PTHREADS_TRUE@AM_CXXFLAGS = @PTHREAD_CFLAGS@ -DGTEST_HAS_PTHREAD=1 @HAVE_PTHREADS_TRUE@AM_LIBS = @PTHREAD_LIBS@ # Build rules for libraries. lib_LTLIBRARIES = lib/libgtest.la lib/libgtest_main.la lib_libgtest_la_SOURCES = src/gtest-all.cc pkginclude_HEADERS = \ include/gtest/gtest-death-test.h \ include/gtest/gtest-message.h \ include/gtest/gtest-param-test.h \ include/gtest/gtest-printers.h \ include/gtest/gtest-spi.h \ include/gtest/gtest-test-part.h \ include/gtest/gtest-typed-test.h \ include/gtest/gtest.h \ include/gtest/gtest_pred_impl.h \ include/gtest/gtest_prod.h pkginclude_internaldir = $(pkgincludedir)/internal pkginclude_internal_HEADERS = \ include/gtest/internal/gtest-death-test-internal.h \ include/gtest/internal/gtest-filepath.h \ include/gtest/internal/gtest-internal.h \ include/gtest/internal/gtest-linked_ptr.h \ include/gtest/internal/gtest-param-util-generated.h \ include/gtest/internal/gtest-param-util.h \ include/gtest/internal/gtest-port.h \ include/gtest/internal/gtest-string.h \ include/gtest/internal/gtest-tuple.h \ include/gtest/internal/gtest-type-util.h lib_libgtest_main_la_SOURCES = src/gtest_main.cc lib_libgtest_main_la_LIBADD = lib/libgtest.la # Bulid rules for samples and tests. Automake's naming for some of # these variables isn't terribly obvious, so this is a brief # reference: # # TESTS -- Programs run automatically by "make check" # check_PROGRAMS -- Programs built by "make check" but not necessarily run noinst_LTLIBRARIES = samples/libsamples.la samples_libsamples_la_SOURCES = \ samples/sample1.cc \ samples/sample1.h \ samples/sample2.cc \ samples/sample2.h \ samples/sample3-inl.h \ samples/sample4.cc \ samples/sample4.h TESTS_ENVIRONMENT = GTEST_SOURCE_DIR="$(srcdir)/test" \ GTEST_BUILD_DIR="$(top_builddir)/test" samples_sample1_unittest_SOURCES = samples/sample1_unittest.cc samples_sample1_unittest_LDADD = lib/libgtest_main.la \ lib/libgtest.la \ samples/libsamples.la samples_sample10_unittest_SOURCES = samples/sample10_unittest.cc samples_sample10_unittest_LDADD = lib/libgtest.la test_gtest_all_test_SOURCES = test/gtest_all_test.cc test_gtest_all_test_LDADD = lib/libgtest_main.la \ lib/libgtest.la # Tests that fused gtest files compile and work. FUSED_GTEST_SRC = \ fused-src/gtest/gtest-all.cc \ fused-src/gtest/gtest.h \ fused-src/gtest/gtest_main.cc @HAVE_PYTHON_TRUE@test_fused_gtest_test_SOURCES = $(FUSED_GTEST_SRC) \ @HAVE_PYTHON_TRUE@ samples/sample1.cc samples/sample1_unittest.cc @HAVE_PYTHON_TRUE@test_fused_gtest_test_CPPFLAGS = -I"$(srcdir)/fused-src" # Death tests may produce core dumps in the build directory. In case # this happens, clean them to keep distcleancheck happy. CLEANFILES = core all: all-am .SUFFIXES: .SUFFIXES: .cc .lo .o .obj am--refresh: Makefile @: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ echo ' cd $(srcdir) && $(AUTOMAKE) --foreign'; \ $(am__cd) $(srcdir) && $(AUTOMAKE) --foreign \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ echo ' $(SHELL) ./config.status'; \ $(SHELL) ./config.status;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) $(SHELL) ./config.status --recheck $(top_srcdir)/configure: $(am__configure_deps) $(am__cd) $(srcdir) && $(AUTOCONF) $(ACLOCAL_M4): $(am__aclocal_m4_deps) $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) $(am__aclocal_m4_deps): build-aux/config.h: build-aux/stamp-h1 @if test ! -f $@; then rm -f build-aux/stamp-h1; else :; fi @if test ! -f $@; then $(MAKE) $(AM_MAKEFLAGS) build-aux/stamp-h1; else :; fi build-aux/stamp-h1: $(top_srcdir)/build-aux/config.h.in $(top_builddir)/config.status @rm -f build-aux/stamp-h1 cd $(top_builddir) && $(SHELL) ./config.status build-aux/config.h $(top_srcdir)/build-aux/config.h.in: $(am__configure_deps) ($(am__cd) $(top_srcdir) && $(AUTOHEADER)) rm -f build-aux/stamp-h1 touch $@ distclean-hdr: -rm -f build-aux/config.h build-aux/stamp-h1 scripts/gtest-config: $(top_builddir)/config.status $(top_srcdir)/scripts/gtest-config.in cd $(top_builddir) && $(SHELL) ./config.status $@ install-libLTLIBRARIES: $(lib_LTLIBRARIES) @$(NORMAL_INSTALL) test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)" @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ } uninstall-libLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ done clean-libLTLIBRARIES: -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ test "$$dir" != "$$p" || dir=.; \ echo "rm -f \"$${dir}/so_locations\""; \ rm -f "$${dir}/so_locations"; \ done clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ test "$$dir" != "$$p" || dir=.; \ echo "rm -f \"$${dir}/so_locations\""; \ rm -f "$${dir}/so_locations"; \ done src/$(am__dirstamp): @$(MKDIR_P) src @: > src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) src/$(DEPDIR) @: > src/$(DEPDIR)/$(am__dirstamp) src/gtest-all.lo: src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp) lib/$(am__dirstamp): @$(MKDIR_P) lib @: > lib/$(am__dirstamp) lib/libgtest.la: $(lib_libgtest_la_OBJECTS) $(lib_libgtest_la_DEPENDENCIES) $(EXTRA_lib_libgtest_la_DEPENDENCIES) lib/$(am__dirstamp) $(CXXLINK) -rpath $(libdir) $(lib_libgtest_la_OBJECTS) $(lib_libgtest_la_LIBADD) $(LIBS) src/gtest_main.lo: src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp) lib/libgtest_main.la: $(lib_libgtest_main_la_OBJECTS) $(lib_libgtest_main_la_DEPENDENCIES) $(EXTRA_lib_libgtest_main_la_DEPENDENCIES) lib/$(am__dirstamp) $(CXXLINK) -rpath $(libdir) $(lib_libgtest_main_la_OBJECTS) $(lib_libgtest_main_la_LIBADD) $(LIBS) samples/$(am__dirstamp): @$(MKDIR_P) samples @: > samples/$(am__dirstamp) samples/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) samples/$(DEPDIR) @: > samples/$(DEPDIR)/$(am__dirstamp) samples/sample1.lo: samples/$(am__dirstamp) \ samples/$(DEPDIR)/$(am__dirstamp) samples/sample2.lo: samples/$(am__dirstamp) \ samples/$(DEPDIR)/$(am__dirstamp) samples/sample4.lo: samples/$(am__dirstamp) \ samples/$(DEPDIR)/$(am__dirstamp) samples/libsamples.la: $(samples_libsamples_la_OBJECTS) $(samples_libsamples_la_DEPENDENCIES) $(EXTRA_samples_libsamples_la_DEPENDENCIES) samples/$(am__dirstamp) $(CXXLINK) $(samples_libsamples_la_OBJECTS) $(samples_libsamples_la_LIBADD) $(LIBS) clean-checkPROGRAMS: @list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list samples/sample10_unittest.$(OBJEXT): samples/$(am__dirstamp) \ samples/$(DEPDIR)/$(am__dirstamp) samples/sample10_unittest$(EXEEXT): $(samples_sample10_unittest_OBJECTS) $(samples_sample10_unittest_DEPENDENCIES) $(EXTRA_samples_sample10_unittest_DEPENDENCIES) samples/$(am__dirstamp) @rm -f samples/sample10_unittest$(EXEEXT) $(CXXLINK) $(samples_sample10_unittest_OBJECTS) $(samples_sample10_unittest_LDADD) $(LIBS) samples/sample1_unittest.$(OBJEXT): samples/$(am__dirstamp) \ samples/$(DEPDIR)/$(am__dirstamp) samples/sample1_unittest$(EXEEXT): $(samples_sample1_unittest_OBJECTS) $(samples_sample1_unittest_DEPENDENCIES) $(EXTRA_samples_sample1_unittest_DEPENDENCIES) samples/$(am__dirstamp) @rm -f samples/sample1_unittest$(EXEEXT) $(CXXLINK) $(samples_sample1_unittest_OBJECTS) $(samples_sample1_unittest_LDADD) $(LIBS) fused-src/gtest/$(am__dirstamp): @$(MKDIR_P) fused-src/gtest @: > fused-src/gtest/$(am__dirstamp) fused-src/gtest/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) fused-src/gtest/$(DEPDIR) @: > fused-src/gtest/$(DEPDIR)/$(am__dirstamp) fused-src/gtest/test_fused_gtest_test-gtest-all.$(OBJEXT): \ fused-src/gtest/$(am__dirstamp) \ fused-src/gtest/$(DEPDIR)/$(am__dirstamp) fused-src/gtest/test_fused_gtest_test-gtest_main.$(OBJEXT): \ fused-src/gtest/$(am__dirstamp) \ fused-src/gtest/$(DEPDIR)/$(am__dirstamp) samples/test_fused_gtest_test-sample1.$(OBJEXT): \ samples/$(am__dirstamp) samples/$(DEPDIR)/$(am__dirstamp) samples/test_fused_gtest_test-sample1_unittest.$(OBJEXT): \ samples/$(am__dirstamp) samples/$(DEPDIR)/$(am__dirstamp) test/$(am__dirstamp): @$(MKDIR_P) test @: > test/$(am__dirstamp) test/fused_gtest_test$(EXEEXT): $(test_fused_gtest_test_OBJECTS) $(test_fused_gtest_test_DEPENDENCIES) $(EXTRA_test_fused_gtest_test_DEPENDENCIES) test/$(am__dirstamp) @rm -f test/fused_gtest_test$(EXEEXT) $(CXXLINK) $(test_fused_gtest_test_OBJECTS) $(test_fused_gtest_test_LDADD) $(LIBS) test/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) test/$(DEPDIR) @: > test/$(DEPDIR)/$(am__dirstamp) test/gtest_all_test.$(OBJEXT): test/$(am__dirstamp) \ test/$(DEPDIR)/$(am__dirstamp) test/gtest_all_test$(EXEEXT): $(test_gtest_all_test_OBJECTS) $(test_gtest_all_test_DEPENDENCIES) $(EXTRA_test_gtest_all_test_DEPENDENCIES) test/$(am__dirstamp) @rm -f test/gtest_all_test$(EXEEXT) $(CXXLINK) $(test_gtest_all_test_OBJECTS) $(test_gtest_all_test_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) -rm -f fused-src/gtest/test_fused_gtest_test-gtest-all.$(OBJEXT) -rm -f fused-src/gtest/test_fused_gtest_test-gtest_main.$(OBJEXT) -rm -f samples/sample1.$(OBJEXT) -rm -f samples/sample1.lo -rm -f samples/sample10_unittest.$(OBJEXT) -rm -f samples/sample1_unittest.$(OBJEXT) -rm -f samples/sample2.$(OBJEXT) -rm -f samples/sample2.lo -rm -f samples/sample4.$(OBJEXT) -rm -f samples/sample4.lo -rm -f samples/test_fused_gtest_test-sample1.$(OBJEXT) -rm -f samples/test_fused_gtest_test-sample1_unittest.$(OBJEXT) -rm -f src/gtest-all.$(OBJEXT) -rm -f src/gtest-all.lo -rm -f src/gtest_main.$(OBJEXT) -rm -f src/gtest_main.lo -rm -f test/gtest_all_test.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@fused-src/gtest/$(DEPDIR)/test_fused_gtest_test-gtest-all.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@fused-src/gtest/$(DEPDIR)/test_fused_gtest_test-gtest_main.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@samples/$(DEPDIR)/sample1.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@samples/$(DEPDIR)/sample10_unittest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@samples/$(DEPDIR)/sample1_unittest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@samples/$(DEPDIR)/sample2.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@samples/$(DEPDIR)/sample4.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@samples/$(DEPDIR)/test_fused_gtest_test-sample1.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@samples/$(DEPDIR)/test_fused_gtest_test-sample1_unittest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/gtest-all.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/gtest_main.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@test/$(DEPDIR)/gtest_all_test.Po@am__quote@ .cc.o: @am__fastdepCXX_TRUE@ depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< .cc.obj: @am__fastdepCXX_TRUE@ depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .cc.lo: @am__fastdepCXX_TRUE@ depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $< fused-src/gtest/test_fused_gtest_test-gtest-all.o: fused-src/gtest/gtest-all.cc @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_fused_gtest_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT fused-src/gtest/test_fused_gtest_test-gtest-all.o -MD -MP -MF fused-src/gtest/$(DEPDIR)/test_fused_gtest_test-gtest-all.Tpo -c -o fused-src/gtest/test_fused_gtest_test-gtest-all.o `test -f 'fused-src/gtest/gtest-all.cc' || echo '$(srcdir)/'`fused-src/gtest/gtest-all.cc @am__fastdepCXX_TRUE@ $(am__mv) fused-src/gtest/$(DEPDIR)/test_fused_gtest_test-gtest-all.Tpo fused-src/gtest/$(DEPDIR)/test_fused_gtest_test-gtest-all.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='fused-src/gtest/gtest-all.cc' object='fused-src/gtest/test_fused_gtest_test-gtest-all.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_fused_gtest_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o fused-src/gtest/test_fused_gtest_test-gtest-all.o `test -f 'fused-src/gtest/gtest-all.cc' || echo '$(srcdir)/'`fused-src/gtest/gtest-all.cc fused-src/gtest/test_fused_gtest_test-gtest-all.obj: fused-src/gtest/gtest-all.cc @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_fused_gtest_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT fused-src/gtest/test_fused_gtest_test-gtest-all.obj -MD -MP -MF fused-src/gtest/$(DEPDIR)/test_fused_gtest_test-gtest-all.Tpo -c -o fused-src/gtest/test_fused_gtest_test-gtest-all.obj `if test -f 'fused-src/gtest/gtest-all.cc'; then $(CYGPATH_W) 'fused-src/gtest/gtest-all.cc'; else $(CYGPATH_W) '$(srcdir)/fused-src/gtest/gtest-all.cc'; fi` @am__fastdepCXX_TRUE@ $(am__mv) fused-src/gtest/$(DEPDIR)/test_fused_gtest_test-gtest-all.Tpo fused-src/gtest/$(DEPDIR)/test_fused_gtest_test-gtest-all.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='fused-src/gtest/gtest-all.cc' object='fused-src/gtest/test_fused_gtest_test-gtest-all.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_fused_gtest_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o fused-src/gtest/test_fused_gtest_test-gtest-all.obj `if test -f 'fused-src/gtest/gtest-all.cc'; then $(CYGPATH_W) 'fused-src/gtest/gtest-all.cc'; else $(CYGPATH_W) '$(srcdir)/fused-src/gtest/gtest-all.cc'; fi` fused-src/gtest/test_fused_gtest_test-gtest_main.o: fused-src/gtest/gtest_main.cc @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_fused_gtest_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT fused-src/gtest/test_fused_gtest_test-gtest_main.o -MD -MP -MF fused-src/gtest/$(DEPDIR)/test_fused_gtest_test-gtest_main.Tpo -c -o fused-src/gtest/test_fused_gtest_test-gtest_main.o `test -f 'fused-src/gtest/gtest_main.cc' || echo '$(srcdir)/'`fused-src/gtest/gtest_main.cc @am__fastdepCXX_TRUE@ $(am__mv) fused-src/gtest/$(DEPDIR)/test_fused_gtest_test-gtest_main.Tpo fused-src/gtest/$(DEPDIR)/test_fused_gtest_test-gtest_main.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='fused-src/gtest/gtest_main.cc' object='fused-src/gtest/test_fused_gtest_test-gtest_main.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_fused_gtest_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o fused-src/gtest/test_fused_gtest_test-gtest_main.o `test -f 'fused-src/gtest/gtest_main.cc' || echo '$(srcdir)/'`fused-src/gtest/gtest_main.cc fused-src/gtest/test_fused_gtest_test-gtest_main.obj: fused-src/gtest/gtest_main.cc @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_fused_gtest_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT fused-src/gtest/test_fused_gtest_test-gtest_main.obj -MD -MP -MF fused-src/gtest/$(DEPDIR)/test_fused_gtest_test-gtest_main.Tpo -c -o fused-src/gtest/test_fused_gtest_test-gtest_main.obj `if test -f 'fused-src/gtest/gtest_main.cc'; then $(CYGPATH_W) 'fused-src/gtest/gtest_main.cc'; else $(CYGPATH_W) '$(srcdir)/fused-src/gtest/gtest_main.cc'; fi` @am__fastdepCXX_TRUE@ $(am__mv) fused-src/gtest/$(DEPDIR)/test_fused_gtest_test-gtest_main.Tpo fused-src/gtest/$(DEPDIR)/test_fused_gtest_test-gtest_main.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='fused-src/gtest/gtest_main.cc' object='fused-src/gtest/test_fused_gtest_test-gtest_main.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_fused_gtest_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o fused-src/gtest/test_fused_gtest_test-gtest_main.obj `if test -f 'fused-src/gtest/gtest_main.cc'; then $(CYGPATH_W) 'fused-src/gtest/gtest_main.cc'; else $(CYGPATH_W) '$(srcdir)/fused-src/gtest/gtest_main.cc'; fi` samples/test_fused_gtest_test-sample1.o: samples/sample1.cc @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_fused_gtest_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT samples/test_fused_gtest_test-sample1.o -MD -MP -MF samples/$(DEPDIR)/test_fused_gtest_test-sample1.Tpo -c -o samples/test_fused_gtest_test-sample1.o `test -f 'samples/sample1.cc' || echo '$(srcdir)/'`samples/sample1.cc @am__fastdepCXX_TRUE@ $(am__mv) samples/$(DEPDIR)/test_fused_gtest_test-sample1.Tpo samples/$(DEPDIR)/test_fused_gtest_test-sample1.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='samples/sample1.cc' object='samples/test_fused_gtest_test-sample1.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_fused_gtest_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o samples/test_fused_gtest_test-sample1.o `test -f 'samples/sample1.cc' || echo '$(srcdir)/'`samples/sample1.cc samples/test_fused_gtest_test-sample1.obj: samples/sample1.cc @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_fused_gtest_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT samples/test_fused_gtest_test-sample1.obj -MD -MP -MF samples/$(DEPDIR)/test_fused_gtest_test-sample1.Tpo -c -o samples/test_fused_gtest_test-sample1.obj `if test -f 'samples/sample1.cc'; then $(CYGPATH_W) 'samples/sample1.cc'; else $(CYGPATH_W) '$(srcdir)/samples/sample1.cc'; fi` @am__fastdepCXX_TRUE@ $(am__mv) samples/$(DEPDIR)/test_fused_gtest_test-sample1.Tpo samples/$(DEPDIR)/test_fused_gtest_test-sample1.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='samples/sample1.cc' object='samples/test_fused_gtest_test-sample1.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_fused_gtest_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o samples/test_fused_gtest_test-sample1.obj `if test -f 'samples/sample1.cc'; then $(CYGPATH_W) 'samples/sample1.cc'; else $(CYGPATH_W) '$(srcdir)/samples/sample1.cc'; fi` samples/test_fused_gtest_test-sample1_unittest.o: samples/sample1_unittest.cc @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_fused_gtest_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT samples/test_fused_gtest_test-sample1_unittest.o -MD -MP -MF samples/$(DEPDIR)/test_fused_gtest_test-sample1_unittest.Tpo -c -o samples/test_fused_gtest_test-sample1_unittest.o `test -f 'samples/sample1_unittest.cc' || echo '$(srcdir)/'`samples/sample1_unittest.cc @am__fastdepCXX_TRUE@ $(am__mv) samples/$(DEPDIR)/test_fused_gtest_test-sample1_unittest.Tpo samples/$(DEPDIR)/test_fused_gtest_test-sample1_unittest.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='samples/sample1_unittest.cc' object='samples/test_fused_gtest_test-sample1_unittest.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_fused_gtest_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o samples/test_fused_gtest_test-sample1_unittest.o `test -f 'samples/sample1_unittest.cc' || echo '$(srcdir)/'`samples/sample1_unittest.cc samples/test_fused_gtest_test-sample1_unittest.obj: samples/sample1_unittest.cc @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_fused_gtest_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT samples/test_fused_gtest_test-sample1_unittest.obj -MD -MP -MF samples/$(DEPDIR)/test_fused_gtest_test-sample1_unittest.Tpo -c -o samples/test_fused_gtest_test-sample1_unittest.obj `if test -f 'samples/sample1_unittest.cc'; then $(CYGPATH_W) 'samples/sample1_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/samples/sample1_unittest.cc'; fi` @am__fastdepCXX_TRUE@ $(am__mv) samples/$(DEPDIR)/test_fused_gtest_test-sample1_unittest.Tpo samples/$(DEPDIR)/test_fused_gtest_test-sample1_unittest.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='samples/sample1_unittest.cc' object='samples/test_fused_gtest_test-sample1_unittest.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_fused_gtest_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o samples/test_fused_gtest_test-sample1_unittest.obj `if test -f 'samples/sample1_unittest.cc'; then $(CYGPATH_W) 'samples/sample1_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/samples/sample1_unittest.cc'; fi` mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs -rm -rf lib/.libs lib/_libs -rm -rf samples/.libs samples/_libs -rm -rf src/.libs src/_libs -rm -rf test/.libs test/_libs distclean-libtool: -rm -f libtool config.lt install-m4dataDATA: $(m4data_DATA) @$(NORMAL_INSTALL) test -z "$(m4datadir)" || $(MKDIR_P) "$(DESTDIR)$(m4datadir)" @list='$(m4data_DATA)'; test -n "$(m4datadir)" || list=; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(m4datadir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(m4datadir)" || exit $$?; \ done uninstall-m4dataDATA: @$(NORMAL_UNINSTALL) @list='$(m4data_DATA)'; test -n "$(m4datadir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(m4datadir)'; $(am__uninstall_files_from_dir) install-pkgincludeHEADERS: $(pkginclude_HEADERS) @$(NORMAL_INSTALL) test -z "$(pkgincludedir)" || $(MKDIR_P) "$(DESTDIR)$(pkgincludedir)" @list='$(pkginclude_HEADERS)'; test -n "$(pkgincludedir)" || list=; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(pkgincludedir)'"; \ $(INSTALL_HEADER) $$files "$(DESTDIR)$(pkgincludedir)" || exit $$?; \ done uninstall-pkgincludeHEADERS: @$(NORMAL_UNINSTALL) @list='$(pkginclude_HEADERS)'; test -n "$(pkgincludedir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(pkgincludedir)'; $(am__uninstall_files_from_dir) install-pkginclude_internalHEADERS: $(pkginclude_internal_HEADERS) @$(NORMAL_INSTALL) test -z "$(pkginclude_internaldir)" || $(MKDIR_P) "$(DESTDIR)$(pkginclude_internaldir)" @list='$(pkginclude_internal_HEADERS)'; test -n "$(pkginclude_internaldir)" || list=; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(pkginclude_internaldir)'"; \ $(INSTALL_HEADER) $$files "$(DESTDIR)$(pkginclude_internaldir)" || exit $$?; \ done uninstall-pkginclude_internalHEADERS: @$(NORMAL_UNINSTALL) @list='$(pkginclude_internal_HEADERS)'; test -n "$(pkginclude_internaldir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(pkginclude_internaldir)'; $(am__uninstall_files_from_dir) ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags check-TESTS: $(TESTS) @failed=0; all=0; xfail=0; xpass=0; skip=0; \ srcdir=$(srcdir); export srcdir; \ list=' $(TESTS) '; \ $(am__tty_colors); \ if test -n "$$list"; then \ for tst in $$list; do \ if test -f ./$$tst; then dir=./; \ elif test -f $$tst; then dir=; \ else dir="$(srcdir)/"; fi; \ if $(TESTS_ENVIRONMENT) $${dir}$$tst; then \ all=`expr $$all + 1`; \ case " $(XFAIL_TESTS) " in \ *[\ \ ]$$tst[\ \ ]*) \ xpass=`expr $$xpass + 1`; \ failed=`expr $$failed + 1`; \ col=$$red; res=XPASS; \ ;; \ *) \ col=$$grn; res=PASS; \ ;; \ esac; \ elif test $$? -ne 77; then \ all=`expr $$all + 1`; \ case " $(XFAIL_TESTS) " in \ *[\ \ ]$$tst[\ \ ]*) \ xfail=`expr $$xfail + 1`; \ col=$$lgn; res=XFAIL; \ ;; \ *) \ failed=`expr $$failed + 1`; \ col=$$red; res=FAIL; \ ;; \ esac; \ else \ skip=`expr $$skip + 1`; \ col=$$blu; res=SKIP; \ fi; \ echo "$${col}$$res$${std}: $$tst"; \ done; \ if test "$$all" -eq 1; then \ tests="test"; \ All=""; \ else \ tests="tests"; \ All="All "; \ fi; \ if test "$$failed" -eq 0; then \ if test "$$xfail" -eq 0; then \ banner="$$All$$all $$tests passed"; \ else \ if test "$$xfail" -eq 1; then failures=failure; else failures=failures; fi; \ banner="$$All$$all $$tests behaved as expected ($$xfail expected $$failures)"; \ fi; \ else \ if test "$$xpass" -eq 0; then \ banner="$$failed of $$all $$tests failed"; \ else \ if test "$$xpass" -eq 1; then passes=pass; else passes=passes; fi; \ banner="$$failed of $$all $$tests did not behave as expected ($$xpass unexpected $$passes)"; \ fi; \ fi; \ dashes="$$banner"; \ skipped=""; \ if test "$$skip" -ne 0; then \ if test "$$skip" -eq 1; then \ skipped="($$skip test was not run)"; \ else \ skipped="($$skip tests were not run)"; \ fi; \ test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \ dashes="$$skipped"; \ fi; \ report=""; \ if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \ report="Please report to $(PACKAGE_BUGREPORT)"; \ test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \ dashes="$$report"; \ fi; \ dashes=`echo "$$dashes" | sed s/./=/g`; \ if test "$$failed" -eq 0; then \ col="$$grn"; \ else \ col="$$red"; \ fi; \ echo "$${col}$$dashes$${std}"; \ echo "$${col}$$banner$${std}"; \ test -z "$$skipped" || echo "$${col}$$skipped$${std}"; \ test -z "$$report" || echo "$${col}$$report$${std}"; \ echo "$${col}$$dashes$${std}"; \ test "$$failed" -eq 0; \ else :; fi distdir: $(DISTFILES) $(am__remove_distdir) test -d "$(distdir)" || mkdir "$(distdir)" @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done -test -n "$(am__skip_mode_fix)" \ || find "$(distdir)" -type d ! -perm -755 \ -exec chmod u+rwx,go+rx {} \; -o \ ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ || chmod -R a+r "$(distdir)" dist-gzip: distdir tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz $(am__remove_distdir) dist-bzip2: distdir tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2 $(am__remove_distdir) dist-lzip: distdir tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz $(am__remove_distdir) dist-lzma: distdir tardir=$(distdir) && $(am__tar) | lzma -9 -c >$(distdir).tar.lzma $(am__remove_distdir) dist-xz: distdir tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz $(am__remove_distdir) dist-tarZ: distdir tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z $(am__remove_distdir) dist-shar: distdir shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz $(am__remove_distdir) dist-zip: distdir -rm -f $(distdir).zip zip -rq $(distdir).zip $(distdir) $(am__remove_distdir) dist dist-all: distdir tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2 -rm -f $(distdir).zip zip -rq $(distdir).zip $(distdir) $(am__remove_distdir) # This target untars the dist file and tries a VPATH configuration. Then # it guarantees that the distribution is self-contained by making another # tarfile. distcheck: dist case '$(DIST_ARCHIVES)' in \ *.tar.gz*) \ GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\ *.tar.bz2*) \ bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ *.tar.lzma*) \ lzma -dc $(distdir).tar.lzma | $(am__untar) ;;\ *.tar.lz*) \ lzip -dc $(distdir).tar.lz | $(am__untar) ;;\ *.tar.xz*) \ xz -dc $(distdir).tar.xz | $(am__untar) ;;\ *.tar.Z*) \ uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ *.shar.gz*) \ GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\ *.zip*) \ unzip $(distdir).zip ;;\ esac chmod -R a-w $(distdir); chmod a+w $(distdir) mkdir $(distdir)/_build mkdir $(distdir)/_inst chmod a-w $(distdir) test -d $(distdir)/_build || exit 0; \ dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ && am__cwd=`pwd` \ && $(am__cd) $(distdir)/_build \ && ../configure --srcdir=.. --prefix="$$dc_install_base" \ $(AM_DISTCHECK_CONFIGURE_FLAGS) \ $(DISTCHECK_CONFIGURE_FLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) dvi \ && $(MAKE) $(AM_MAKEFLAGS) check \ && $(MAKE) $(AM_MAKEFLAGS) install \ && $(MAKE) $(AM_MAKEFLAGS) installcheck \ && $(MAKE) $(AM_MAKEFLAGS) uninstall \ && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ distuninstallcheck \ && chmod -R a-w "$$dc_install_base" \ && ({ \ (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ } || { rm -rf "$$dc_destdir"; exit 1; }) \ && rm -rf "$$dc_destdir" \ && $(MAKE) $(AM_MAKEFLAGS) dist \ && rm -rf $(DIST_ARCHIVES) \ && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ && cd "$$am__cwd" \ || exit 1 $(am__remove_distdir) @(echo "$(distdir) archives ready for distribution: "; \ list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' distuninstallcheck: @test -n '$(distuninstallcheck_dir)' || { \ echo 'ERROR: trying to run $@ with an empty' \ '$$(distuninstallcheck_dir)' >&2; \ exit 1; \ }; \ $(am__cd) '$(distuninstallcheck_dir)' || { \ echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \ exit 1; \ }; \ test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \ || { echo "ERROR: files left after uninstall:" ; \ if test -n "$(DESTDIR)"; then \ echo " (check DESTDIR support)"; \ fi ; \ $(distuninstallcheck_listfiles) ; \ exit 1; } >&2 distcleancheck: distclean @if test '$(srcdir)' = . ; then \ echo "ERROR: distcleancheck can only run from a VPATH build" ; \ exit 1 ; \ fi @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ || { echo "ERROR: files left in build directory after distclean:" ; \ $(distcleancheck_listfiles) ; \ exit 1; } >&2 check-am: all-am $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) $(MAKE) $(AM_MAKEFLAGS) check-TESTS check: check-am all-am: Makefile $(LTLIBRARIES) $(DATA) $(HEADERS) installdirs: for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(m4datadir)" "$(DESTDIR)$(pkgincludedir)" "$(DESTDIR)$(pkginclude_internaldir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) -rm -f fused-src/gtest/$(DEPDIR)/$(am__dirstamp) -rm -f fused-src/gtest/$(am__dirstamp) -rm -f lib/$(am__dirstamp) -rm -f samples/$(DEPDIR)/$(am__dirstamp) -rm -f samples/$(am__dirstamp) -rm -f src/$(DEPDIR)/$(am__dirstamp) -rm -f src/$(am__dirstamp) -rm -f test/$(DEPDIR)/$(am__dirstamp) -rm -f test/$(am__dirstamp) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." @HAVE_PYTHON_FALSE@maintainer-clean-local: clean: clean-am clean-am: clean-checkPROGRAMS clean-generic clean-libLTLIBRARIES \ clean-libtool clean-noinstLTLIBRARIES mostlyclean-am distclean: distclean-am -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -rf fused-src/gtest/$(DEPDIR) samples/$(DEPDIR) src/$(DEPDIR) test/$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-hdr distclean-libtool distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-data-local install-m4dataDATA \ install-pkgincludeHEADERS install-pkginclude_internalHEADERS install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-exec-local install-libLTLIBRARIES install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -rf $(top_srcdir)/autom4te.cache -rm -rf fused-src/gtest/$(DEPDIR) samples/$(DEPDIR) src/$(DEPDIR) test/$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic \ maintainer-clean-local mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-libLTLIBRARIES uninstall-m4dataDATA \ uninstall-pkgincludeHEADERS \ uninstall-pkginclude_internalHEADERS .MAKE: check-am install-am install-strip .PHONY: CTAGS GTAGS all all-am am--refresh check check-TESTS check-am \ clean clean-checkPROGRAMS clean-generic clean-libLTLIBRARIES \ clean-libtool clean-noinstLTLIBRARIES ctags dist dist-all \ dist-bzip2 dist-gzip dist-lzip dist-lzma dist-shar dist-tarZ \ dist-xz dist-zip distcheck distclean distclean-compile \ distclean-generic distclean-hdr distclean-libtool \ distclean-tags distcleancheck distdir distuninstallcheck dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-data-local install-dvi \ install-dvi-am install-exec install-exec-am install-exec-local \ install-html install-html-am install-info install-info-am \ install-libLTLIBRARIES install-m4dataDATA install-man \ install-pdf install-pdf-am install-pkgincludeHEADERS \ install-pkginclude_internalHEADERS install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic \ maintainer-clean-local mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags uninstall uninstall-am uninstall-libLTLIBRARIES \ uninstall-m4dataDATA uninstall-pkgincludeHEADERS \ uninstall-pkginclude_internalHEADERS # Build rules for putting fused Google Test files into the distribution # package. The user can also create those files by manually running # scripts/fuse_gtest_files.py. @HAVE_PYTHON_TRUE@$(test_fused_gtest_test_SOURCES): fused-gtest @HAVE_PYTHON_TRUE@fused-gtest: $(pkginclude_HEADERS) $(pkginclude_internal_HEADERS) \ @HAVE_PYTHON_TRUE@ $(GTEST_SRC) src/gtest-all.cc src/gtest_main.cc \ @HAVE_PYTHON_TRUE@ scripts/fuse_gtest_files.py @HAVE_PYTHON_TRUE@ mkdir -p "$(srcdir)/fused-src" @HAVE_PYTHON_TRUE@ chmod -R u+w "$(srcdir)/fused-src" @HAVE_PYTHON_TRUE@ rm -f "$(srcdir)/fused-src/gtest/gtest-all.cc" @HAVE_PYTHON_TRUE@ rm -f "$(srcdir)/fused-src/gtest/gtest.h" @HAVE_PYTHON_TRUE@ "$(srcdir)/scripts/fuse_gtest_files.py" "$(srcdir)/fused-src" @HAVE_PYTHON_TRUE@ cp -f "$(srcdir)/src/gtest_main.cc" "$(srcdir)/fused-src/gtest/" @HAVE_PYTHON_TRUE@maintainer-clean-local: @HAVE_PYTHON_TRUE@ rm -rf "$(srcdir)/fused-src" # Disables 'make install' as installing a compiled version of Google # Test can lead to undefined behavior due to violation of the # One-Definition Rule. install-exec-local: echo "'make install' is dangerous and not supported. Instead, see README for how to integrate Google Test into your build system." false install-data-local: echo "'make install' is dangerous and not supported. Instead, see README for how to integrate Google Test into your build system." false # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: dlt-daemon-2.18.4/gtest-1.7.0/README000066400000000000000000000373321353342203500163110ustar00rootroot00000000000000Google C++ Testing Framework ============================ http://code.google.com/p/googletest/ Overview -------- Google's framework for writing C++ tests on a variety of platforms (Linux, Mac OS X, Windows, Windows CE, Symbian, etc). Based on the xUnit architecture. Supports automatic test discovery, a rich set of assertions, user-defined assertions, death tests, fatal and non-fatal failures, various options for running the tests, and XML test report generation. Please see the project page above for more information as well as the mailing list for questions, discussions, and development. There is also an IRC channel on OFTC (irc.oftc.net) #gtest available. Please join us! Requirements for End Users -------------------------- Google Test is designed to have fairly minimal requirements to build and use with your projects, but there are some. Currently, we support Linux, Windows, Mac OS X, and Cygwin. We will also make our best effort to support other platforms (e.g. Solaris, AIX, and z/OS). However, since core members of the Google Test project have no access to these platforms, Google Test may have outstanding issues there. If you notice any problems on your platform, please notify googletestframework@googlegroups.com. Patches for fixing them are even more welcome! ### Linux Requirements ### These are the base requirements to build and use Google Test from a source package (as described below): * GNU-compatible Make or gmake * POSIX-standard shell * POSIX(-2) Regular Expressions (regex.h) * A C++98-standard-compliant compiler ### Windows Requirements ### * Microsoft Visual C++ 7.1 or newer ### Cygwin Requirements ### * Cygwin 1.5.25-14 or newer ### Mac OS X Requirements ### * Mac OS X 10.4 Tiger or newer * Developer Tools Installed Also, you'll need CMake 2.6.4 or higher if you want to build the samples using the provided CMake script, regardless of the platform. Requirements for Contributors ----------------------------- We welcome patches. If you plan to contribute a patch, you need to build Google Test and its own tests from an SVN checkout (described below), which has further requirements: * Python version 2.3 or newer (for running some of the tests and re-generating certain source files from templates) * CMake 2.6.4 or newer Getting the Source ------------------ There are two primary ways of getting Google Test's source code: you can download a stable source release in your preferred archive format, or directly check out the source from our Subversion (SVN) repositary. The SVN checkout requires a few extra steps and some extra software packages on your system, but lets you track the latest development and make patches much more easily, so we highly encourage it. ### Source Package ### Google Test is released in versioned source packages which can be downloaded from the download page [1]. Several different archive formats are provided, but the only difference is the tools used to manipulate them, and the size of the resulting file. Download whichever you are most comfortable with. [1] http://code.google.com/p/googletest/downloads/list Once the package is downloaded, expand it using whichever tools you prefer for that type. This will result in a new directory with the name "gtest-X.Y.Z" which contains all of the source code. Here are some examples on Linux: tar -xvzf gtest-X.Y.Z.tar.gz tar -xvjf gtest-X.Y.Z.tar.bz2 unzip gtest-X.Y.Z.zip ### SVN Checkout ### To check out the main branch (also known as the "trunk") of Google Test, run the following Subversion command: svn checkout http://googletest.googlecode.com/svn/trunk/ gtest-svn Setting up the Build -------------------- To build Google Test and your tests that use it, you need to tell your build system where to find its headers and source files. The exact way to do it depends on which build system you use, and is usually straightforward. ### Generic Build Instructions ### Suppose you put Google Test in directory ${GTEST_DIR}. To build it, create a library build target (or a project as called by Visual Studio and Xcode) to compile ${GTEST_DIR}/src/gtest-all.cc with ${GTEST_DIR}/include in the system header search path and ${GTEST_DIR} in the normal header search path. Assuming a Linux-like system and gcc, something like the following will do: g++ -isystem ${GTEST_DIR}/include -I${GTEST_DIR} \ -pthread -c ${GTEST_DIR}/src/gtest-all.cc ar -rv libgtest.a gtest-all.o (We need -pthread as Google Test uses threads.) Next, you should compile your test source file with ${GTEST_DIR}/include in the system header search path, and link it with gtest and any other necessary libraries: g++ -isystem ${GTEST_DIR}/include -pthread path/to/your_test.cc libgtest.a \ -o your_test As an example, the make/ directory contains a Makefile that you can use to build Google Test on systems where GNU make is available (e.g. Linux, Mac OS X, and Cygwin). It doesn't try to build Google Test's own tests. Instead, it just builds the Google Test library and a sample test. You can use it as a starting point for your own build script. If the default settings are correct for your environment, the following commands should succeed: cd ${GTEST_DIR}/make make ./sample1_unittest If you see errors, try to tweak the contents of make/Makefile to make them go away. There are instructions in make/Makefile on how to do it. ### Using CMake ### Google Test comes with a CMake build script (CMakeLists.txt) that can be used on a wide range of platforms ("C" stands for cross-platofrm.). If you don't have CMake installed already, you can download it for free from http://www.cmake.org/. CMake works by generating native makefiles or build projects that can be used in the compiler environment of your choice. The typical workflow starts with: mkdir mybuild # Create a directory to hold the build output. cd mybuild cmake ${GTEST_DIR} # Generate native build scripts. If you want to build Google Test's samples, you should replace the last command with cmake -Dgtest_build_samples=ON ${GTEST_DIR} If you are on a *nix system, you should now see a Makefile in the current directory. Just type 'make' to build gtest. If you use Windows and have Vistual Studio installed, a gtest.sln file and several .vcproj files will be created. You can then build them using Visual Studio. On Mac OS X with Xcode installed, a .xcodeproj file will be generated. ### Legacy Build Scripts ### Before settling on CMake, we have been providing hand-maintained build projects/scripts for Visual Studio, Xcode, and Autotools. While we continue to provide them for convenience, they are not actively maintained any more. We highly recommend that you follow the instructions in the previous two sections to integrate Google Test with your existing build system. If you still need to use the legacy build scripts, here's how: The msvc\ folder contains two solutions with Visual C++ projects. Open the gtest.sln or gtest-md.sln file using Visual Studio, and you are ready to build Google Test the same way you build any Visual Studio project. Files that have names ending with -md use DLL versions of Microsoft runtime libraries (the /MD or the /MDd compiler option). Files without that suffix use static versions of the runtime libraries (the /MT or the /MTd option). Please note that one must use the same option to compile both gtest and the test code. If you use Visual Studio 2005 or above, we recommend the -md version as /MD is the default for new projects in these versions of Visual Studio. On Mac OS X, open the gtest.xcodeproj in the xcode/ folder using Xcode. Build the "gtest" target. The universal binary framework will end up in your selected build directory (selected in the Xcode "Preferences..." -> "Building" pane and defaults to xcode/build). Alternatively, at the command line, enter: xcodebuild This will build the "Release" configuration of gtest.framework in your default build location. See the "xcodebuild" man page for more information about building different configurations and building in different locations. If you wish to use the Google Test Xcode project with Xcode 4.x and above, you need to either: * update the SDK configuration options in xcode/Config/General.xconfig. Comment options SDKROOT, MACOS_DEPLOYMENT_TARGET, and GCC_VERSION. If you choose this route you lose the ability to target earlier versions of MacOS X. * Install an SDK for an earlier version. This doesn't appear to be supported by Apple, but has been reported to work (http://stackoverflow.com/questions/5378518). Tweaking Google Test -------------------- Google Test can be used in diverse environments. The default configuration may not work (or may not work well) out of the box in some environments. However, you can easily tweak Google Test by defining control macros on the compiler command line. Generally, these macros are named like GTEST_XYZ and you define them to either 1 or 0 to enable or disable a certain feature. We list the most frequently used macros below. For a complete list, see file include/gtest/internal/gtest-port.h. ### Choosing a TR1 Tuple Library ### Some Google Test features require the C++ Technical Report 1 (TR1) tuple library, which is not yet available with all compilers. The good news is that Google Test implements a subset of TR1 tuple that's enough for its own need, and will automatically use this when the compiler doesn't provide TR1 tuple. Usually you don't need to care about which tuple library Google Test uses. However, if your project already uses TR1 tuple, you need to tell Google Test to use the same TR1 tuple library the rest of your project uses, or the two tuple implementations will clash. To do that, add -DGTEST_USE_OWN_TR1_TUPLE=0 to the compiler flags while compiling Google Test and your tests. If you want to force Google Test to use its own tuple library, just add -DGTEST_USE_OWN_TR1_TUPLE=1 to the compiler flags instead. If you don't want Google Test to use tuple at all, add -DGTEST_HAS_TR1_TUPLE=0 and all features using tuple will be disabled. ### Multi-threaded Tests ### Google Test is thread-safe where the pthread library is available. After #include "gtest/gtest.h", you can check the GTEST_IS_THREADSAFE macro to see whether this is the case (yes if the macro is #defined to 1, no if it's undefined.). If Google Test doesn't correctly detect whether pthread is available in your environment, you can force it with -DGTEST_HAS_PTHREAD=1 or -DGTEST_HAS_PTHREAD=0 When Google Test uses pthread, you may need to add flags to your compiler and/or linker to select the pthread library, or you'll get link errors. If you use the CMake script or the deprecated Autotools script, this is taken care of for you. If you use your own build script, you'll need to read your compiler and linker's manual to figure out what flags to add. ### As a Shared Library (DLL) ### Google Test is compact, so most users can build and link it as a static library for the simplicity. You can choose to use Google Test as a shared library (known as a DLL on Windows) if you prefer. To compile *gtest* as a shared library, add -DGTEST_CREATE_SHARED_LIBRARY=1 to the compiler flags. You'll also need to tell the linker to produce a shared library instead - consult your linker's manual for how to do it. To compile your *tests* that use the gtest shared library, add -DGTEST_LINKED_AS_SHARED_LIBRARY=1 to the compiler flags. Note: while the above steps aren't technically necessary today when using some compilers (e.g. GCC), they may become necessary in the future, if we decide to improve the speed of loading the library (see http://gcc.gnu.org/wiki/Visibility for details). Therefore you are recommended to always add the above flags when using Google Test as a shared library. Otherwise a future release of Google Test may break your build script. ### Avoiding Macro Name Clashes ### In C++, macros don't obey namespaces. Therefore two libraries that both define a macro of the same name will clash if you #include both definitions. In case a Google Test macro clashes with another library, you can force Google Test to rename its macro to avoid the conflict. Specifically, if both Google Test and some other code define macro FOO, you can add -DGTEST_DONT_DEFINE_FOO=1 to the compiler flags to tell Google Test to change the macro's name from FOO to GTEST_FOO. Currently FOO can be FAIL, SUCCEED, or TEST. For example, with -DGTEST_DONT_DEFINE_TEST=1, you'll need to write GTEST_TEST(SomeTest, DoesThis) { ... } instead of TEST(SomeTest, DoesThis) { ... } in order to define a test. Upgrating from an Earlier Version --------------------------------- We strive to keep Google Test releases backward compatible. Sometimes, though, we have to make some breaking changes for the users' long-term benefits. This section describes what you'll need to do if you are upgrading from an earlier version of Google Test. ### Upgrading from 1.3.0 or Earlier ### You may need to explicitly enable or disable Google Test's own TR1 tuple library. See the instructions in section "Choosing a TR1 Tuple Library". ### Upgrading from 1.4.0 or Earlier ### The Autotools build script (configure + make) is no longer officially supportted. You are encouraged to migrate to your own build system or use CMake. If you still need to use Autotools, you can find instructions in the README file from Google Test 1.4.0. On platforms where the pthread library is available, Google Test uses it in order to be thread-safe. See the "Multi-threaded Tests" section for what this means to your build script. If you use Microsoft Visual C++ 7.1 with exceptions disabled, Google Test will no longer compile. This should affect very few people, as a large portion of STL (including ) doesn't compile in this mode anyway. We decided to stop supporting it in order to greatly simplify Google Test's implementation. Developing Google Test ---------------------- This section discusses how to make your own changes to Google Test. ### Testing Google Test Itself ### To make sure your changes work as intended and don't break existing functionality, you'll want to compile and run Google Test's own tests. For that you can use CMake: mkdir mybuild cd mybuild cmake -Dgtest_build_tests=ON ${GTEST_DIR} Make sure you have Python installed, as some of Google Test's tests are written in Python. If the cmake command complains about not being able to find Python ("Could NOT find PythonInterp (missing: PYTHON_EXECUTABLE)"), try telling it explicitly where your Python executable can be found: cmake -DPYTHON_EXECUTABLE=path/to/python -Dgtest_build_tests=ON ${GTEST_DIR} Next, you can build Google Test and all of its own tests. On *nix, this is usually done by 'make'. To run the tests, do make test All tests should pass. ### Regenerating Source Files ### Some of Google Test's source files are generated from templates (not in the C++ sense) using a script. A template file is named FOO.pump, where FOO is the name of the file it will generate. For example, the file include/gtest/internal/gtest-type-util.h.pump is used to generate gtest-type-util.h in the same directory. Normally you don't need to worry about regenerating the source files, unless you need to modify them. In that case, you should modify the corresponding .pump files instead and run the pump.py Python script to regenerate them. You can find pump.py in the scripts/ directory. Read the Pump manual [2] for how to use it. [2] http://code.google.com/p/googletest/wiki/PumpManual ### Contributing a Patch ### We welcome patches. Please read the Google Test developer's guide [3] for how you can contribute. In particular, make sure you have signed the Contributor License Agreement, or we won't be able to accept the patch. [3] http://code.google.com/p/googletest/wiki/GoogleTestDevGuide Happy testing! dlt-daemon-2.18.4/gtest-1.7.0/aclocal.m4000066400000000000000000001253711353342203500172720ustar00rootroot00000000000000# generated automatically by aclocal 1.11.3 -*- Autoconf -*- # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, # 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, # Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.68],, [m4_warning([this file was generated for autoconf 2.68. You have another version of autoconf. It may work, but is not guaranteed to. If you have problems, you may need to regenerate the build system entirely. To do so, use the procedure documented by the package, typically `autoreconf'.])]) # Copyright (C) 2002, 2003, 2005, 2006, 2007, 2008, 2011 Free Software # Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 1 # AM_AUTOMAKE_VERSION(VERSION) # ---------------------------- # Automake X.Y traces this macro to ensure aclocal.m4 has been # generated from the m4 files accompanying Automake X.Y. # (This private macro should not be called outside this file.) AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version='1.11' dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to dnl require some minimum version. Point them to the right macro. m4_if([$1], [1.11.3], [], [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl ]) # _AM_AUTOCONF_VERSION(VERSION) # ----------------------------- # aclocal traces this macro to find the Autoconf version. # This is a private macro too. Using m4_define simplifies # the logic in aclocal, which can simply ignore this definition. m4_define([_AM_AUTOCONF_VERSION], []) # AM_SET_CURRENT_AUTOMAKE_VERSION # ------------------------------- # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. # This function is AC_REQUIREd by AM_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], [AM_AUTOMAKE_VERSION([1.11.3])dnl m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) # AM_AUX_DIR_EXPAND -*- Autoconf -*- # Copyright (C) 2001, 2003, 2005, 2011 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 1 # For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets # $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to # `$srcdir', `$srcdir/..', or `$srcdir/../..'. # # Of course, Automake must honor this variable whenever it calls a # tool from the auxiliary directory. The problem is that $srcdir (and # therefore $ac_aux_dir as well) can be either absolute or relative, # depending on how configure is run. This is pretty annoying, since # it makes $ac_aux_dir quite unusable in subdirectories: in the top # source directory, any form will work fine, but in subdirectories a # relative path needs to be adjusted first. # # $ac_aux_dir/missing # fails when called from a subdirectory if $ac_aux_dir is relative # $top_srcdir/$ac_aux_dir/missing # fails if $ac_aux_dir is absolute, # fails when called from a subdirectory in a VPATH build with # a relative $ac_aux_dir # # The reason of the latter failure is that $top_srcdir and $ac_aux_dir # are both prefixed by $srcdir. In an in-source build this is usually # harmless because $srcdir is `.', but things will broke when you # start a VPATH build or use an absolute $srcdir. # # So we could use something similar to $top_srcdir/$ac_aux_dir/missing, # iff we strip the leading $srcdir from $ac_aux_dir. That would be: # am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` # and then we would define $MISSING as # MISSING="\${SHELL} $am_aux_dir/missing" # This will work as long as MISSING is not called from configure, because # unfortunately $(top_srcdir) has no meaning in configure. # However there are other variables, like CC, which are often used in # configure, and could therefore not use this "fixed" $ac_aux_dir. # # Another solution, used here, is to always expand $ac_aux_dir to an # absolute PATH. The drawback is that using absolute paths prevent a # configured tree to be moved without reconfiguration. AC_DEFUN([AM_AUX_DIR_EXPAND], [dnl Rely on autoconf to set up CDPATH properly. AC_PREREQ([2.50])dnl # expand $ac_aux_dir to an absolute path am_aux_dir=`cd $ac_aux_dir && pwd` ]) # AM_CONDITIONAL -*- Autoconf -*- # Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005, 2006, 2008 # Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 9 # AM_CONDITIONAL(NAME, SHELL-CONDITION) # ------------------------------------- # Define a conditional. AC_DEFUN([AM_CONDITIONAL], [AC_PREREQ(2.52)dnl ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl AC_SUBST([$1_TRUE])dnl AC_SUBST([$1_FALSE])dnl _AM_SUBST_NOTMAKE([$1_TRUE])dnl _AM_SUBST_NOTMAKE([$1_FALSE])dnl m4_define([_AM_COND_VALUE_$1], [$2])dnl if $2; then $1_TRUE= $1_FALSE='#' else $1_TRUE='#' $1_FALSE= fi AC_CONFIG_COMMANDS_PRE( [if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then AC_MSG_ERROR([[conditional "$1" was never defined. Usually this means the macro was only invoked conditionally.]]) fi])]) # Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2009, # 2010, 2011 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 12 # There are a few dirty hacks below to avoid letting `AC_PROG_CC' be # written in clear, in which case automake, when reading aclocal.m4, # will think it sees a *use*, and therefore will trigger all it's # C support machinery. Also note that it means that autoscan, seeing # CC etc. in the Makefile, will ask for an AC_PROG_CC use... # _AM_DEPENDENCIES(NAME) # ---------------------- # See how the compiler implements dependency checking. # NAME is "CC", "CXX", "GCJ", or "OBJC". # We try a few techniques and use that to set a single cache variable. # # We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was # modified to invoke _AM_DEPENDENCIES(CC); we would have a circular # dependency, and given that the user is not expected to run this macro, # just rely on AC_PROG_CC. AC_DEFUN([_AM_DEPENDENCIES], [AC_REQUIRE([AM_SET_DEPDIR])dnl AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl AC_REQUIRE([AM_MAKE_INCLUDE])dnl AC_REQUIRE([AM_DEP_TRACK])dnl ifelse([$1], CC, [depcc="$CC" am_compiler_list=], [$1], CXX, [depcc="$CXX" am_compiler_list=], [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'], [$1], UPC, [depcc="$UPC" am_compiler_list=], [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'], [depcc="$$1" am_compiler_list=]) AC_CACHE_CHECK([dependency style of $depcc], [am_cv_$1_dependencies_compiler_type], [if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named `D' -- because `-MD' means `put the output # in D'. rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_$1_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` fi am__universal=false m4_case([$1], [CC], [case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac], [CXX], [case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac]) for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with # Solaris 8's {/usr,}/bin/sh. touch sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with `-c' and `-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle `-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # after this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) # This compiler won't grok `-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_$1_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_$1_dependencies_compiler_type=none fi ]) AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) AM_CONDITIONAL([am__fastdep$1], [ test "x$enable_dependency_tracking" != xno \ && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) ]) # AM_SET_DEPDIR # ------------- # Choose a directory name for dependency files. # This macro is AC_REQUIREd in _AM_DEPENDENCIES AC_DEFUN([AM_SET_DEPDIR], [AC_REQUIRE([AM_SET_LEADING_DOT])dnl AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl ]) # AM_DEP_TRACK # ------------ AC_DEFUN([AM_DEP_TRACK], [AC_ARG_ENABLE(dependency-tracking, [ --disable-dependency-tracking speeds up one-time build --enable-dependency-tracking do not reject slow dependency extractors]) if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' am__nodep='_no' fi AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) AC_SUBST([AMDEPBACKSLASH])dnl _AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl AC_SUBST([am__nodep])dnl _AM_SUBST_NOTMAKE([am__nodep])dnl ]) # Generate code to set up dependency tracking. -*- Autoconf -*- # Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2008 # Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. #serial 5 # _AM_OUTPUT_DEPENDENCY_COMMANDS # ------------------------------ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], [{ # Autoconf 2.62 quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. case $CONFIG_FILES in *\'*) eval set x "$CONFIG_FILES" ;; *) set x $CONFIG_FILES ;; esac shift for mf do # Strip MF so we end up with the name of the file. mf=`echo "$mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile or not. # We used to match only the files named `Makefile.in', but # some people rename them; so instead we look at the file content. # Grep'ing the first line is not enough: some people post-process # each Makefile.in and add a new line on top of each file to say so. # Grep'ing the whole file is not good either: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then dirpart=`AS_DIRNAME("$mf")` else continue fi # Extract the definition of DEPDIR, am__include, and am__quote # from the Makefile without running `make'. DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` test -z "$DEPDIR" && continue am__include=`sed -n 's/^am__include = //p' < "$mf"` test -z "am__include" && continue am__quote=`sed -n 's/^am__quote = //p' < "$mf"` # When using ansi2knr, U may be empty or an underscore; expand it U=`sed -n 's/^U = //p' < "$mf"` # Find all dependency output files, they are included files with # $(DEPDIR) in their names. We invoke sed twice because it is the # simplest approach to changing $(DEPDIR) to its actual value in the # expansion. for file in `sed -n " s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do # Make sure the directory exists. test -f "$dirpart/$file" && continue fdir=`AS_DIRNAME(["$file"])` AS_MKDIR_P([$dirpart/$fdir]) # echo "creating $dirpart/$file" echo '# dummy' > "$dirpart/$file" done done } ])# _AM_OUTPUT_DEPENDENCY_COMMANDS # AM_OUTPUT_DEPENDENCY_COMMANDS # ----------------------------- # This macro should only be invoked once -- use via AC_REQUIRE. # # This code is only required when automatic dependency tracking # is enabled. FIXME. This creates each `.P' file that we will # need in order to bootstrap the dependency handling code. AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], [AC_CONFIG_COMMANDS([depfiles], [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) ]) # Do all the work for Automake. -*- Autoconf -*- # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, # 2005, 2006, 2008, 2009 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 16 # This macro actually does too much. Some checks are only needed if # your package does certain things. But this isn't really a big deal. # AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) # AM_INIT_AUTOMAKE([OPTIONS]) # ----------------------------------------------- # The call with PACKAGE and VERSION arguments is the old style # call (pre autoconf-2.50), which is being phased out. PACKAGE # and VERSION should now be passed to AC_INIT and removed from # the call to AM_INIT_AUTOMAKE. # We support both call styles for the transition. After # the next Automake release, Autoconf can make the AC_INIT # arguments mandatory, and then we can depend on a new Autoconf # release and drop the old call support. AC_DEFUN([AM_INIT_AUTOMAKE], [AC_PREREQ([2.62])dnl dnl Autoconf wants to disallow AM_ names. We explicitly allow dnl the ones we care about. m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl AC_REQUIRE([AC_PROG_INSTALL])dnl if test "`cd $srcdir && pwd`" != "`pwd`"; then # Use -I$(srcdir) only when $(srcdir) != ., so that make's output # is not polluted with repeated "-I." AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl # test to see if srcdir already configured if test -f $srcdir/config.status; then AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) fi fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi AC_SUBST([CYGPATH_W]) # Define the identity of the package. dnl Distinguish between old-style and new-style calls. m4_ifval([$2], [m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl AC_SUBST([PACKAGE], [$1])dnl AC_SUBST([VERSION], [$2])], [_AM_SET_OPTIONS([$1])dnl dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. m4_if(m4_ifdef([AC_PACKAGE_NAME], 1)m4_ifdef([AC_PACKAGE_VERSION], 1), 11,, [m4_fatal([AC_INIT should be called with package and version arguments])])dnl AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl _AM_IF_OPTION([no-define],, [AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl # Some tools Automake needs. AC_REQUIRE([AM_SANITY_CHECK])dnl AC_REQUIRE([AC_ARG_PROGRAM])dnl AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version}) AM_MISSING_PROG(AUTOCONF, autoconf) AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version}) AM_MISSING_PROG(AUTOHEADER, autoheader) AM_MISSING_PROG(MAKEINFO, makeinfo) AC_REQUIRE([AM_PROG_INSTALL_SH])dnl AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl AC_REQUIRE([AM_PROG_MKDIR_P])dnl # We need awk for the "check" target. The system "awk" is bad on # some platforms. AC_REQUIRE([AC_PROG_AWK])dnl AC_REQUIRE([AC_PROG_MAKE_SET])dnl AC_REQUIRE([AM_SET_LEADING_DOT])dnl _AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], [_AM_PROG_TAR([v7])])]) _AM_IF_OPTION([no-dependencies],, [AC_PROVIDE_IFELSE([AC_PROG_CC], [_AM_DEPENDENCIES(CC)], [define([AC_PROG_CC], defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl AC_PROVIDE_IFELSE([AC_PROG_CXX], [_AM_DEPENDENCIES(CXX)], [define([AC_PROG_CXX], defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl AC_PROVIDE_IFELSE([AC_PROG_OBJC], [_AM_DEPENDENCIES(OBJC)], [define([AC_PROG_OBJC], defn([AC_PROG_OBJC])[_AM_DEPENDENCIES(OBJC)])])dnl ]) _AM_IF_OPTION([silent-rules], [AC_REQUIRE([AM_SILENT_RULES])])dnl dnl The `parallel-tests' driver may need to know about EXEEXT, so add the dnl `am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This macro dnl is hooked onto _AC_COMPILER_EXEEXT early, see below. AC_CONFIG_COMMANDS_PRE(dnl [m4_provide_if([_AM_COMPILER_EXEEXT], [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl ]) dnl Hook into `_AC_COMPILER_EXEEXT' early to learn its expansion. Do not dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further dnl mangled by Autoconf and run in a shell conditional statement. m4_define([_AC_COMPILER_EXEEXT], m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])]) # When config.status generates a header, we must update the stamp-h file. # This file resides in the same directory as the config header # that is generated. The stamp files are numbered to have different names. # Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the # loop where config.status creates the headers, so we can generate # our stamp files there. AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], [# Compute $1's index in $config_headers. _am_arg=$1 _am_stamp_count=1 for _am_header in $config_headers :; do case $_am_header in $_am_arg | $_am_arg:* ) break ;; * ) _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) # Copyright (C) 2001, 2003, 2005, 2008, 2011 Free Software Foundation, # Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 1 # AM_PROG_INSTALL_SH # ------------------ # Define $install_sh. AC_DEFUN([AM_PROG_INSTALL_SH], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl if test x"${install_sh}" != xset; then case $am_aux_dir in *\ * | *\ *) install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; *) install_sh="\${SHELL} $am_aux_dir/install-sh" esac fi AC_SUBST(install_sh)]) # Copyright (C) 2003, 2005 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 2 # Check whether the underlying file-system supports filenames # with a leading dot. For instance MS-DOS doesn't. AC_DEFUN([AM_SET_LEADING_DOT], [rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null AC_SUBST([am__leading_dot])]) # Check to see how 'make' treats includes. -*- Autoconf -*- # Copyright (C) 2001, 2002, 2003, 2005, 2009 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 4 # AM_MAKE_INCLUDE() # ----------------- # Check to see how make treats includes. AC_DEFUN([AM_MAKE_INCLUDE], [am_make=${MAKE-make} cat > confinc << 'END' am__doit: @echo this is the am__doit target .PHONY: am__doit END # If we don't find an include directive, just comment out the code. AC_MSG_CHECKING([for style of include used by $am_make]) am__include="#" am__quote= _am_result=none # First try GNU make style include. echo "include confinc" > confmf # Ignore all kinds of additional output from `make'. case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=include am__quote= _am_result=GNU ;; esac # Now try BSD make style include. if test "$am__include" = "#"; then echo '.include "confinc"' > confmf case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=.include am__quote="\"" _am_result=BSD ;; esac fi AC_SUBST([am__include]) AC_SUBST([am__quote]) AC_MSG_RESULT([$_am_result]) rm -f confinc confmf ]) # Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- # Copyright (C) 1997, 1999, 2000, 2001, 2003, 2004, 2005, 2008 # Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 6 # AM_MISSING_PROG(NAME, PROGRAM) # ------------------------------ AC_DEFUN([AM_MISSING_PROG], [AC_REQUIRE([AM_MISSING_HAS_RUN]) $1=${$1-"${am_missing_run}$2"} AC_SUBST($1)]) # AM_MISSING_HAS_RUN # ------------------ # Define MISSING if not defined so far and test if it supports --run. # If it does, set am_missing_run to use it, otherwise, to nothing. AC_DEFUN([AM_MISSING_HAS_RUN], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl AC_REQUIRE_AUX_FILE([missing])dnl if test x"${MISSING+set}" != xset; then case $am_aux_dir in *\ * | *\ *) MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; *) MISSING="\${SHELL} $am_aux_dir/missing" ;; esac fi # Use eval to expand $SHELL if eval "$MISSING --run true"; then am_missing_run="$MISSING --run " else am_missing_run= AC_MSG_WARN([`missing' script is too old or missing]) fi ]) # Copyright (C) 2003, 2004, 2005, 2006, 2011 Free Software Foundation, # Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 1 # AM_PROG_MKDIR_P # --------------- # Check for `mkdir -p'. AC_DEFUN([AM_PROG_MKDIR_P], [AC_PREREQ([2.60])dnl AC_REQUIRE([AC_PROG_MKDIR_P])dnl dnl Automake 1.8 to 1.9.6 used to define mkdir_p. We now use MKDIR_P, dnl while keeping a definition of mkdir_p for backward compatibility. dnl @MKDIR_P@ is magic: AC_OUTPUT adjusts its value for each Makefile. dnl However we cannot define mkdir_p as $(MKDIR_P) for the sake of dnl Makefile.ins that do not define MKDIR_P, so we do our own dnl adjustment using top_builddir (which is defined more often than dnl MKDIR_P). AC_SUBST([mkdir_p], ["$MKDIR_P"])dnl case $mkdir_p in [[\\/$]]* | ?:[[\\/]]*) ;; */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; esac ]) # Helper functions for option handling. -*- Autoconf -*- # Copyright (C) 2001, 2002, 2003, 2005, 2008, 2010 Free Software # Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 5 # _AM_MANGLE_OPTION(NAME) # ----------------------- AC_DEFUN([_AM_MANGLE_OPTION], [[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) # _AM_SET_OPTION(NAME) # -------------------- # Set option NAME. Presently that only means defining a flag for this option. AC_DEFUN([_AM_SET_OPTION], [m4_define(_AM_MANGLE_OPTION([$1]), 1)]) # _AM_SET_OPTIONS(OPTIONS) # ------------------------ # OPTIONS is a space-separated list of Automake options. AC_DEFUN([_AM_SET_OPTIONS], [m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) # _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) # ------------------------------------------- # Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. AC_DEFUN([_AM_IF_OPTION], [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) # Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009, # 2011 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 2 # AM_PATH_PYTHON([MINIMUM-VERSION], [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) # --------------------------------------------------------------------------- # Adds support for distributing Python modules and packages. To # install modules, copy them to $(pythondir), using the python_PYTHON # automake variable. To install a package with the same name as the # automake package, install to $(pkgpythondir), or use the # pkgpython_PYTHON automake variable. # # The variables $(pyexecdir) and $(pkgpyexecdir) are provided as # locations to install python extension modules (shared libraries). # Another macro is required to find the appropriate flags to compile # extension modules. # # If your package is configured with a different prefix to python, # users will have to add the install directory to the PYTHONPATH # environment variable, or create a .pth file (see the python # documentation for details). # # If the MINIMUM-VERSION argument is passed, AM_PATH_PYTHON will # cause an error if the version of python installed on the system # doesn't meet the requirement. MINIMUM-VERSION should consist of # numbers and dots only. AC_DEFUN([AM_PATH_PYTHON], [ dnl Find a Python interpreter. Python versions prior to 2.0 are not dnl supported. (2.0 was released on October 16, 2000). m4_define_default([_AM_PYTHON_INTERPRETER_LIST], [python python2 python3 python3.2 python3.1 python3.0 python2.7 dnl python2.6 python2.5 python2.4 python2.3 python2.2 python2.1 python2.0]) AC_ARG_VAR([PYTHON], [the Python interpreter]) m4_if([$1],[],[ dnl No version check is needed. # Find any Python interpreter. if test -z "$PYTHON"; then AC_PATH_PROGS([PYTHON], _AM_PYTHON_INTERPRETER_LIST, :) fi am_display_PYTHON=python ], [ dnl A version check is needed. if test -n "$PYTHON"; then # If the user set $PYTHON, use it and don't search something else. AC_MSG_CHECKING([whether $PYTHON version >= $1]) AM_PYTHON_CHECK_VERSION([$PYTHON], [$1], [AC_MSG_RESULT(yes)], [AC_MSG_ERROR(too old)]) am_display_PYTHON=$PYTHON else # Otherwise, try each interpreter until we find one that satisfies # VERSION. AC_CACHE_CHECK([for a Python interpreter with version >= $1], [am_cv_pathless_PYTHON],[ for am_cv_pathless_PYTHON in _AM_PYTHON_INTERPRETER_LIST none; do test "$am_cv_pathless_PYTHON" = none && break AM_PYTHON_CHECK_VERSION([$am_cv_pathless_PYTHON], [$1], [break]) done]) # Set $PYTHON to the absolute path of $am_cv_pathless_PYTHON. if test "$am_cv_pathless_PYTHON" = none; then PYTHON=: else AC_PATH_PROG([PYTHON], [$am_cv_pathless_PYTHON]) fi am_display_PYTHON=$am_cv_pathless_PYTHON fi ]) if test "$PYTHON" = :; then dnl Run any user-specified action, or abort. m4_default([$3], [AC_MSG_ERROR([no suitable Python interpreter found])]) else dnl Query Python for its version number. Getting [:3] seems to be dnl the best way to do this; it's what "site.py" does in the standard dnl library. AC_CACHE_CHECK([for $am_display_PYTHON version], [am_cv_python_version], [am_cv_python_version=`$PYTHON -c "import sys; sys.stdout.write(sys.version[[:3]])"`]) AC_SUBST([PYTHON_VERSION], [$am_cv_python_version]) dnl Use the values of $prefix and $exec_prefix for the corresponding dnl values of PYTHON_PREFIX and PYTHON_EXEC_PREFIX. These are made dnl distinct variables so they can be overridden if need be. However, dnl general consensus is that you shouldn't need this ability. AC_SUBST([PYTHON_PREFIX], ['${prefix}']) AC_SUBST([PYTHON_EXEC_PREFIX], ['${exec_prefix}']) dnl At times (like when building shared libraries) you may want dnl to know which OS platform Python thinks this is. AC_CACHE_CHECK([for $am_display_PYTHON platform], [am_cv_python_platform], [am_cv_python_platform=`$PYTHON -c "import sys; sys.stdout.write(sys.platform)"`]) AC_SUBST([PYTHON_PLATFORM], [$am_cv_python_platform]) dnl Set up 4 directories: dnl pythondir -- where to install python scripts. This is the dnl site-packages directory, not the python standard library dnl directory like in previous automake betas. This behavior dnl is more consistent with lispdir.m4 for example. dnl Query distutils for this directory. AC_CACHE_CHECK([for $am_display_PYTHON script directory], [am_cv_python_pythondir], [if test "x$prefix" = xNONE then am_py_prefix=$ac_default_prefix else am_py_prefix=$prefix fi am_cv_python_pythondir=`$PYTHON -c "import sys; from distutils import sysconfig; sys.stdout.write(sysconfig.get_python_lib(0,0,prefix='$am_py_prefix'))" 2>/dev/null` case $am_cv_python_pythondir in $am_py_prefix*) am__strip_prefix=`echo "$am_py_prefix" | sed 's|.|.|g'` am_cv_python_pythondir=`echo "$am_cv_python_pythondir" | sed "s,^$am__strip_prefix,$PYTHON_PREFIX,"` ;; *) case $am_py_prefix in /usr|/System*) ;; *) am_cv_python_pythondir=$PYTHON_PREFIX/lib/python$PYTHON_VERSION/site-packages ;; esac ;; esac ]) AC_SUBST([pythondir], [$am_cv_python_pythondir]) dnl pkgpythondir -- $PACKAGE directory under pythondir. Was dnl PYTHON_SITE_PACKAGE in previous betas, but this naming is dnl more consistent with the rest of automake. AC_SUBST([pkgpythondir], [\${pythondir}/$PACKAGE]) dnl pyexecdir -- directory for installing python extension modules dnl (shared libraries) dnl Query distutils for this directory. AC_CACHE_CHECK([for $am_display_PYTHON extension module directory], [am_cv_python_pyexecdir], [if test "x$exec_prefix" = xNONE then am_py_exec_prefix=$am_py_prefix else am_py_exec_prefix=$exec_prefix fi am_cv_python_pyexecdir=`$PYTHON -c "import sys; from distutils import sysconfig; sys.stdout.write(sysconfig.get_python_lib(1,0,prefix='$am_py_exec_prefix'))" 2>/dev/null` case $am_cv_python_pyexecdir in $am_py_exec_prefix*) am__strip_prefix=`echo "$am_py_exec_prefix" | sed 's|.|.|g'` am_cv_python_pyexecdir=`echo "$am_cv_python_pyexecdir" | sed "s,^$am__strip_prefix,$PYTHON_EXEC_PREFIX,"` ;; *) case $am_py_exec_prefix in /usr|/System*) ;; *) am_cv_python_pyexecdir=$PYTHON_EXEC_PREFIX/lib/python$PYTHON_VERSION/site-packages ;; esac ;; esac ]) AC_SUBST([pyexecdir], [$am_cv_python_pyexecdir]) dnl pkgpyexecdir -- $(pyexecdir)/$(PACKAGE) AC_SUBST([pkgpyexecdir], [\${pyexecdir}/$PACKAGE]) dnl Run any user-specified action. $2 fi ]) # AM_PYTHON_CHECK_VERSION(PROG, VERSION, [ACTION-IF-TRUE], [ACTION-IF-FALSE]) # --------------------------------------------------------------------------- # Run ACTION-IF-TRUE if the Python interpreter PROG has version >= VERSION. # Run ACTION-IF-FALSE otherwise. # This test uses sys.hexversion instead of the string equivalent (first # word of sys.version), in order to cope with versions such as 2.2c1. # This supports Python 2.0 or higher. (2.0 was released on October 16, 2000). AC_DEFUN([AM_PYTHON_CHECK_VERSION], [prog="import sys # split strings by '.' and convert to numeric. Append some zeros # because we need at least 4 digits for the hex conversion. # map returns an iterator in Python 3.0 and a list in 2.x minver = list(map(int, '$2'.split('.'))) + [[0, 0, 0]] minverhex = 0 # xrange is not present in Python 3.0 and range returns an iterator for i in list(range(0, 4)): minverhex = (minverhex << 8) + minver[[i]] sys.exit(sys.hexversion < minverhex)" AS_IF([AM_RUN_LOG([$1 -c "$prog"])], [$3], [$4])]) # Copyright (C) 2001, 2003, 2005, 2011 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 1 # AM_RUN_LOG(COMMAND) # ------------------- # Run COMMAND, save the exit status in ac_status, and log it. # (This has been adapted from Autoconf's _AC_RUN_LOG macro.) AC_DEFUN([AM_RUN_LOG], [{ echo "$as_me:$LINENO: $1" >&AS_MESSAGE_LOG_FD ($1) >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD (exit $ac_status); }]) # Check to make sure that the build environment is sane. -*- Autoconf -*- # Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005, 2008 # Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 5 # AM_SANITY_CHECK # --------------- AC_DEFUN([AM_SANITY_CHECK], [AC_MSG_CHECKING([whether build environment is sane]) # Just in case sleep 1 echo timestamp > conftest.file # Reject unsafe characters in $srcdir or the absolute working directory # name. Accept space and tab only in the latter. am_lf=' ' case `pwd` in *[[\\\"\#\$\&\'\`$am_lf]]*) AC_MSG_ERROR([unsafe absolute working directory name]);; esac case $srcdir in *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) AC_MSG_ERROR([unsafe srcdir value: `$srcdir']);; esac # Do `set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` if test "$[*]" = "X"; then # -L didn't work. set X `ls -t "$srcdir/configure" conftest.file` fi rm -f conftest.file if test "$[*]" != "X $srcdir/configure conftest.file" \ && test "$[*]" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken alias in your environment]) fi test "$[2]" = conftest.file ) then # Ok. : else AC_MSG_ERROR([newly created file is older than distributed files! Check your system clock]) fi AC_MSG_RESULT(yes)]) # Copyright (C) 2001, 2003, 2005, 2011 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 1 # AM_PROG_INSTALL_STRIP # --------------------- # One issue with vendor `install' (even GNU) is that you can't # specify the program used to strip binaries. This is especially # annoying in cross-compiling environments, where the build's strip # is unlikely to handle the host's binaries. # Fortunately install-sh will honor a STRIPPROG variable, so we # always use install-sh in `make install-strip', and initialize # STRIPPROG with the value of the STRIP variable (set by the user). AC_DEFUN([AM_PROG_INSTALL_STRIP], [AC_REQUIRE([AM_PROG_INSTALL_SH])dnl # Installed binaries are usually stripped using `strip' when the user # run `make install-strip'. However `strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the `STRIP' environment variable to overrule this program. dnl Don't test for $cross_compiling = yes, because it might be `maybe'. if test "$cross_compiling" != no; then AC_CHECK_TOOL([STRIP], [strip], :) fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" AC_SUBST([INSTALL_STRIP_PROGRAM])]) # Copyright (C) 2006, 2008, 2010 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 3 # _AM_SUBST_NOTMAKE(VARIABLE) # --------------------------- # Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. # This macro is traced by Automake. AC_DEFUN([_AM_SUBST_NOTMAKE]) # AM_SUBST_NOTMAKE(VARIABLE) # -------------------------- # Public sister of _AM_SUBST_NOTMAKE. AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) # Check how to create a tarball. -*- Autoconf -*- # Copyright (C) 2004, 2005, 2012 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 2 # _AM_PROG_TAR(FORMAT) # -------------------- # Check how to create a tarball in format FORMAT. # FORMAT should be one of `v7', `ustar', or `pax'. # # Substitute a variable $(am__tar) that is a command # writing to stdout a FORMAT-tarball containing the directory # $tardir. # tardir=directory && $(am__tar) > result.tar # # Substitute a variable $(am__untar) that extract such # a tarball read from stdin. # $(am__untar) < result.tar AC_DEFUN([_AM_PROG_TAR], [# Always define AMTAR for backward compatibility. Yes, it's still used # in the wild :-( We should find a proper way to deprecate it ... AC_SUBST([AMTAR], ['$${TAR-tar}']) m4_if([$1], [v7], [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'], [m4_case([$1], [ustar],, [pax],, [m4_fatal([Unknown tar format])]) AC_MSG_CHECKING([how to create a $1 tar archive]) # Loop over all known methods to create a tar archive until one works. _am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' _am_tools=${am_cv_prog_tar_$1-$_am_tools} # Do not fold the above two line into one, because Tru64 sh and # Solaris sh will not grok spaces in the rhs of `-'. for _am_tool in $_am_tools do case $_am_tool in gnutar) for _am_tar in tar gnutar gtar; do AM_RUN_LOG([$_am_tar --version]) && break done am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' am__untar="$_am_tar -xf -" ;; plaintar) # Must skip GNU tar: if it does not support --format= it doesn't create # ustar tarball either. (tar --version) >/dev/null 2>&1 && continue am__tar='tar chf - "$$tardir"' am__tar_='tar chf - "$tardir"' am__untar='tar xf -' ;; pax) am__tar='pax -L -x $1 -w "$$tardir"' am__tar_='pax -L -x $1 -w "$tardir"' am__untar='pax -r' ;; cpio) am__tar='find "$$tardir" -print | cpio -o -H $1 -L' am__tar_='find "$tardir" -print | cpio -o -H $1 -L' am__untar='cpio -i -H $1 -d' ;; none) am__tar=false am__tar_=false am__untar=false ;; esac # If the value was cached, stop now. We just wanted to have am__tar # and am__untar set. test -n "${am_cv_prog_tar_$1}" && break # tar/untar a dummy directory, and stop if the command works rm -rf conftest.dir mkdir conftest.dir echo GrepMe > conftest.dir/file AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) rm -rf conftest.dir if test -s conftest.tar; then AM_RUN_LOG([$am__untar /dev/null 2>&1 && break fi done rm -rf conftest.dir AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) AC_MSG_RESULT([$am_cv_prog_tar_$1])]) AC_SUBST([am__tar]) AC_SUBST([am__untar]) ]) # _AM_PROG_TAR m4_include([m4/libtool.m4]) m4_include([m4/ltoptions.m4]) m4_include([m4/ltsugar.m4]) m4_include([m4/ltversion.m4]) m4_include([m4/lt~obsolete.m4]) dlt-daemon-2.18.4/gtest-1.7.0/build-aux/000077500000000000000000000000001353342203500173135ustar00rootroot00000000000000dlt-daemon-2.18.4/gtest-1.7.0/build-aux/config.guess000077500000000000000000001274321353342203500216440ustar00rootroot00000000000000#! /bin/sh # Attempt to guess a canonical system name. # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, # 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, # 2011, 2012 Free Software Foundation, Inc. timestamp='2012-02-10' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, see . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Originally written by Per Bothner. Please send patches (context # diff format) to and include a ChangeLog # entry. # # This script attempts to guess a canonical system name similar to # config.sub. If it succeeds, it prints the system name on stdout, and # exits with 0. Otherwise, it exits with 1. # # You can get the latest version of this script from: # http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] Output the configuration name of the system \`$me' is run on. Operation modes: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" >&2 exit 1 ;; * ) break ;; esac done if test $# != 0; then echo "$me: too many arguments$help" >&2 exit 1 fi trap 'exit 1' 1 2 15 # CC_FOR_BUILD -- compiler used by this script. Note that the use of a # compiler to aid in system detection is discouraged as it requires # temporary files to be created and, as you can see below, it is a # headache to deal with in a portable fashion. # Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still # use `HOST_CC' if defined, but it is deprecated. # Portable tmp directory creation inspired by the Autoconf team. set_cc_for_build=' trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; : ${TMPDIR=/tmp} ; { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; dummy=$tmp/dummy ; tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; case $CC_FOR_BUILD,$HOST_CC,$CC in ,,) echo "int x;" > $dummy.c ; for c in cc gcc c89 c99 ; do if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then CC_FOR_BUILD="$c"; break ; fi ; done ; if test x"$CC_FOR_BUILD" = x ; then CC_FOR_BUILD=no_compiler_found ; fi ;; ,,*) CC_FOR_BUILD=$CC ;; ,*,*) CC_FOR_BUILD=$HOST_CC ;; esac ; set_cc_for_build= ;' # This is needed to find uname on a Pyramid OSx when run in the BSD universe. # (ghazi@noc.rutgers.edu 1994-08-24) if (test -f /.attbin/uname) >/dev/null 2>&1 ; then PATH=$PATH:/.attbin ; export PATH fi UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown # Note: order is significant - the case branches are not exclusive. case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in *:NetBSD:*:*) # NetBSD (nbsd) targets should (where applicable) match one or # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently # switched to ELF, *-*-netbsd* would select the old # object file format. This provides both forward # compatibility and a consistent mechanism for selecting the # object file format. # # Note: NetBSD doesn't particularly care about the vendor # portion of the name. We always set it to "unknown". sysctl="sysctl -n hw.machine_arch" UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ /usr/sbin/$sysctl 2>/dev/null || echo unknown)` case "${UNAME_MACHINE_ARCH}" in armeb) machine=armeb-unknown ;; arm*) machine=arm-unknown ;; sh3el) machine=shl-unknown ;; sh3eb) machine=sh-unknown ;; sh5el) machine=sh5le-unknown ;; *) machine=${UNAME_MACHINE_ARCH}-unknown ;; esac # The Operating System including object format, if it has switched # to ELF recently, or will in the future. case "${UNAME_MACHINE_ARCH}" in arm*|i386|m68k|ns32k|sh3*|sparc|vax) eval $set_cc_for_build if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ELF__ then # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). # Return netbsd for either. FIX? os=netbsd else os=netbsdelf fi ;; *) os=netbsd ;; esac # The OS release # Debian GNU/NetBSD machines have a different userland, and # thus, need a distinct triplet. However, they do not need # kernel version information, so it can be replaced with a # suitable tag, in the style of linux-gnu. case "${UNAME_VERSION}" in Debian*) release='-gnu' ;; *) release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` ;; esac # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: # contains redundant information, the shorter form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. echo "${machine}-${os}${release}" exit ;; *:OpenBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} exit ;; *:ekkoBSD:*:*) echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} exit ;; *:SolidBSD:*:*) echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} exit ;; macppc:MirBSD:*:*) echo powerpc-unknown-mirbsd${UNAME_RELEASE} exit ;; *:MirBSD:*:*) echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} exit ;; alpha:OSF1:*:*) case $UNAME_RELEASE in *4.0) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` ;; *5.*) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` ;; esac # According to Compaq, /usr/sbin/psrinfo has been available on # OSF/1 and Tru64 systems produced since 1995. I hope that # covers most systems running today. This code pipes the CPU # types through head -n 1, so we only detect the type of CPU 0. ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` case "$ALPHA_CPU_TYPE" in "EV4 (21064)") UNAME_MACHINE="alpha" ;; "EV4.5 (21064)") UNAME_MACHINE="alpha" ;; "LCA4 (21066/21068)") UNAME_MACHINE="alpha" ;; "EV5 (21164)") UNAME_MACHINE="alphaev5" ;; "EV5.6 (21164A)") UNAME_MACHINE="alphaev56" ;; "EV5.6 (21164PC)") UNAME_MACHINE="alphapca56" ;; "EV5.7 (21164PC)") UNAME_MACHINE="alphapca57" ;; "EV6 (21264)") UNAME_MACHINE="alphaev6" ;; "EV6.7 (21264A)") UNAME_MACHINE="alphaev67" ;; "EV6.8CB (21264C)") UNAME_MACHINE="alphaev68" ;; "EV6.8AL (21264B)") UNAME_MACHINE="alphaev68" ;; "EV6.8CX (21264D)") UNAME_MACHINE="alphaev68" ;; "EV6.9A (21264/EV69A)") UNAME_MACHINE="alphaev69" ;; "EV7 (21364)") UNAME_MACHINE="alphaev7" ;; "EV7.9 (21364A)") UNAME_MACHINE="alphaev79" ;; esac # A Pn.n version is a patched version. # A Vn.n version is a released version. # A Tn.n version is a released field test version. # A Xn.n version is an unreleased experimental baselevel. # 1.2 uses "1.2" for uname -r. echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` # Reset EXIT trap before exiting to avoid spurious non-zero exit code. exitcode=$? trap '' 0 exit $exitcode ;; Alpha\ *:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # Should we change UNAME_MACHINE based on the output of uname instead # of the specific Alpha model? echo alpha-pc-interix exit ;; 21064:Windows_NT:50:3) echo alpha-dec-winnt3.5 exit ;; Amiga*:UNIX_System_V:4.0:*) echo m68k-unknown-sysv4 exit ;; *:[Aa]miga[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-amigaos exit ;; *:[Mm]orph[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-morphos exit ;; *:OS/390:*:*) echo i370-ibm-openedition exit ;; *:z/VM:*:*) echo s390-ibm-zvmoe exit ;; *:OS400:*:*) echo powerpc-ibm-os400 exit ;; arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) echo arm-acorn-riscix${UNAME_RELEASE} exit ;; arm:riscos:*:*|arm:RISCOS:*:*) echo arm-unknown-riscos exit ;; SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) echo hppa1.1-hitachi-hiuxmpp exit ;; Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. if test "`(/bin/universe) 2>/dev/null`" = att ; then echo pyramid-pyramid-sysv3 else echo pyramid-pyramid-bsd fi exit ;; NILE*:*:*:dcosx) echo pyramid-pyramid-svr4 exit ;; DRS?6000:unix:4.0:6*) echo sparc-icl-nx6 exit ;; DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) case `/usr/bin/uname -p` in sparc) echo sparc-icl-nx7; exit ;; esac ;; s390x:SunOS:*:*) echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4H:SunOS:5.*:*) echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) echo i386-pc-auroraux${UNAME_RELEASE} exit ;; i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) eval $set_cc_for_build SUN_ARCH="i386" # If there is a compiler, see if it is configured for 64-bit objects. # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. # This test works for both compilers. if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then SUN_ARCH="x86_64" fi fi echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:6*:*) # According to config.sub, this is the proper way to canonicalize # SunOS6. Hard to guess exactly what SunOS6 will be like, but # it's likely to be more like Solaris than SunOS4. echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:*:*) case "`/usr/bin/arch -k`" in Series*|S4*) UNAME_RELEASE=`uname -v` ;; esac # Japanese Language versions have a version number like `4.1.3-JL'. echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` exit ;; sun3*:SunOS:*:*) echo m68k-sun-sunos${UNAME_RELEASE} exit ;; sun*:*:4.2BSD:*) UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 case "`/bin/arch`" in sun3) echo m68k-sun-sunos${UNAME_RELEASE} ;; sun4) echo sparc-sun-sunos${UNAME_RELEASE} ;; esac exit ;; aushp:SunOS:*:*) echo sparc-auspex-sunos${UNAME_RELEASE} exit ;; # The situation for MiNT is a little confusing. The machine name # can be virtually everything (everything which is not # "atarist" or "atariste" at least should have a processor # > m68000). The system name ranges from "MiNT" over "FreeMiNT" # to the lowercase version "mint" (or "freemint"). Finally # the system name "TOS" denotes a system which is actually not # MiNT. But MiNT is downward compatible to TOS, so this should # be no problem. atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) echo m68k-milan-mint${UNAME_RELEASE} exit ;; hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) echo m68k-hades-mint${UNAME_RELEASE} exit ;; *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) echo m68k-unknown-mint${UNAME_RELEASE} exit ;; m68k:machten:*:*) echo m68k-apple-machten${UNAME_RELEASE} exit ;; powerpc:machten:*:*) echo powerpc-apple-machten${UNAME_RELEASE} exit ;; RISC*:Mach:*:*) echo mips-dec-mach_bsd4.3 exit ;; RISC*:ULTRIX:*:*) echo mips-dec-ultrix${UNAME_RELEASE} exit ;; VAX*:ULTRIX*:*:*) echo vax-dec-ultrix${UNAME_RELEASE} exit ;; 2020:CLIX:*:* | 2430:CLIX:*:*) echo clipper-intergraph-clix${UNAME_RELEASE} exit ;; mips:*:*:UMIPS | mips:*:*:RISCos) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #ifdef __cplusplus #include /* for printf() prototype */ int main (int argc, char *argv[]) { #else int main (argc, argv) int argc; char *argv[]; { #endif #if defined (host_mips) && defined (MIPSEB) #if defined (SYSTYPE_SYSV) printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_SVR4) printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); #endif #endif exit (-1); } EOF $CC_FOR_BUILD -o $dummy $dummy.c && dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && SYSTEM_NAME=`$dummy $dummyarg` && { echo "$SYSTEM_NAME"; exit; } echo mips-mips-riscos${UNAME_RELEASE} exit ;; Motorola:PowerMAX_OS:*:*) echo powerpc-motorola-powermax exit ;; Motorola:*:4.3:PL8-*) echo powerpc-harris-powermax exit ;; Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) echo powerpc-harris-powermax exit ;; Night_Hawk:Power_UNIX:*:*) echo powerpc-harris-powerunix exit ;; m88k:CX/UX:7*:*) echo m88k-harris-cxux7 exit ;; m88k:*:4*:R4*) echo m88k-motorola-sysv4 exit ;; m88k:*:3*:R3*) echo m88k-motorola-sysv3 exit ;; AViiON:dgux:*:*) # DG/UX returns AViiON for all architectures UNAME_PROCESSOR=`/usr/bin/uname -p` if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] then if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ [ ${TARGET_BINARY_INTERFACE}x = x ] then echo m88k-dg-dgux${UNAME_RELEASE} else echo m88k-dg-dguxbcs${UNAME_RELEASE} fi else echo i586-dg-dgux${UNAME_RELEASE} fi exit ;; M88*:DolphinOS:*:*) # DolphinOS (SVR3) echo m88k-dolphin-sysv3 exit ;; M88*:*:R3*:*) # Delta 88k system running SVR3 echo m88k-motorola-sysv3 exit ;; XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) echo m88k-tektronix-sysv3 exit ;; Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) echo m68k-tektronix-bsd exit ;; *:IRIX*:*:*) echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` exit ;; ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' i*86:AIX:*:*) echo i386-ibm-aix exit ;; ia64:AIX:*:*) if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} exit ;; *:AIX:2:3) if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include main() { if (!__power_pc()) exit(1); puts("powerpc-ibm-aix3.2.5"); exit(0); } EOF if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` then echo "$SYSTEM_NAME" else echo rs6000-ibm-aix3.2.5 fi elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then echo rs6000-ibm-aix3.2.4 else echo rs6000-ibm-aix3.2 fi exit ;; *:AIX:*:[4567]) IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then IBM_ARCH=rs6000 else IBM_ARCH=powerpc fi if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi echo ${IBM_ARCH}-ibm-aix${IBM_REV} exit ;; *:AIX:*:*) echo rs6000-ibm-aix exit ;; ibmrt:4.4BSD:*|romp-ibm:BSD:*) echo romp-ibm-bsd4.4 exit ;; ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to exit ;; # report: romp-ibm BSD 4.3 *:BOSX:*:*) echo rs6000-bull-bosx exit ;; DPX/2?00:B.O.S.:*:*) echo m68k-bull-sysv3 exit ;; 9000/[34]??:4.3bsd:1.*:*) echo m68k-hp-bsd exit ;; hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) echo m68k-hp-bsd4.4 exit ;; 9000/[34678]??:HP-UX:*:*) HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` case "${UNAME_MACHINE}" in 9000/31? ) HP_ARCH=m68000 ;; 9000/[34]?? ) HP_ARCH=m68k ;; 9000/[678][0-9][0-9]) if [ -x /usr/bin/getconf ]; then sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` case "${sc_cpu_version}" in 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 532) # CPU_PA_RISC2_0 case "${sc_kernel_bits}" in 32) HP_ARCH="hppa2.0n" ;; 64) HP_ARCH="hppa2.0w" ;; '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 esac ;; esac fi if [ "${HP_ARCH}" = "" ]; then eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #define _HPUX_SOURCE #include #include int main () { #if defined(_SC_KERNEL_BITS) long bits = sysconf(_SC_KERNEL_BITS); #endif long cpu = sysconf (_SC_CPU_VERSION); switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0"); break; case CPU_PA_RISC1_1: puts ("hppa1.1"); break; case CPU_PA_RISC2_0: #if defined(_SC_KERNEL_BITS) switch (bits) { case 64: puts ("hppa2.0w"); break; case 32: puts ("hppa2.0n"); break; default: puts ("hppa2.0"); break; } break; #else /* !defined(_SC_KERNEL_BITS) */ puts ("hppa2.0"); break; #endif default: puts ("hppa1.0"); break; } exit (0); } EOF (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` test -z "$HP_ARCH" && HP_ARCH=hppa fi ;; esac if [ ${HP_ARCH} = "hppa2.0w" ] then eval $set_cc_for_build # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler # generating 64-bit code. GNU and HP use different nomenclature: # # $ CC_FOR_BUILD=cc ./config.guess # => hppa2.0w-hp-hpux11.23 # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess # => hppa64-hp-hpux11.23 if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | grep -q __LP64__ then HP_ARCH="hppa2.0w" else HP_ARCH="hppa64" fi fi echo ${HP_ARCH}-hp-hpux${HPUX_REV} exit ;; ia64:HP-UX:*:*) HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` echo ia64-hp-hpux${HPUX_REV} exit ;; 3050*:HI-UX:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include int main () { long cpu = sysconf (_SC_CPU_VERSION); /* The order matters, because CPU_IS_HP_MC68K erroneously returns true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct results, however. */ if (CPU_IS_PA_RISC (cpu)) { switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; default: puts ("hppa-hitachi-hiuxwe2"); break; } } else if (CPU_IS_HP_MC68K (cpu)) puts ("m68k-hitachi-hiuxwe2"); else puts ("unknown-hitachi-hiuxwe2"); exit (0); } EOF $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && { echo "$SYSTEM_NAME"; exit; } echo unknown-hitachi-hiuxwe2 exit ;; 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) echo hppa1.1-hp-bsd exit ;; 9000/8??:4.3bsd:*:*) echo hppa1.0-hp-bsd exit ;; *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) echo hppa1.0-hp-mpeix exit ;; hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) echo hppa1.1-hp-osf exit ;; hp8??:OSF1:*:*) echo hppa1.0-hp-osf exit ;; i*86:OSF1:*:*) if [ -x /usr/sbin/sysversion ] ; then echo ${UNAME_MACHINE}-unknown-osf1mk else echo ${UNAME_MACHINE}-unknown-osf1 fi exit ;; parisc*:Lites*:*:*) echo hppa1.1-hp-lites exit ;; C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) echo c1-convex-bsd exit ;; C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit ;; C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) echo c34-convex-bsd exit ;; C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) echo c38-convex-bsd exit ;; C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) echo c4-convex-bsd exit ;; CRAY*Y-MP:*:*:*) echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*[A-Z]90:*:*:*) echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ -e 's/\.[^.]*$/.X/' exit ;; CRAY*TS:*:*:*) echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*T3E:*:*:*) echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*SV1:*:*:*) echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; *:UNICOS/mp:*:*) echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; 5000:UNIX_System_V:4.*:*) FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} exit ;; sparc*:BSD/OS:*:*) echo sparc-unknown-bsdi${UNAME_RELEASE} exit ;; *:BSD/OS:*:*) echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} exit ;; *:FreeBSD:*:*) UNAME_PROCESSOR=`/usr/bin/uname -p` case ${UNAME_PROCESSOR} in amd64) echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; *) echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; esac exit ;; i*:CYGWIN*:*) echo ${UNAME_MACHINE}-pc-cygwin exit ;; *:MINGW*:*) echo ${UNAME_MACHINE}-pc-mingw32 exit ;; i*:MSYS*:*) echo ${UNAME_MACHINE}-pc-msys exit ;; i*:windows32*:*) # uname -m includes "-pc" on this system. echo ${UNAME_MACHINE}-mingw32 exit ;; i*:PW*:*) echo ${UNAME_MACHINE}-pc-pw32 exit ;; *:Interix*:*) case ${UNAME_MACHINE} in x86) echo i586-pc-interix${UNAME_RELEASE} exit ;; authenticamd | genuineintel | EM64T) echo x86_64-unknown-interix${UNAME_RELEASE} exit ;; IA64) echo ia64-unknown-interix${UNAME_RELEASE} exit ;; esac ;; [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) echo i${UNAME_MACHINE}-pc-mks exit ;; 8664:Windows_NT:*) echo x86_64-pc-mks exit ;; i*:Windows_NT*:* | Pentium*:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we # UNAME_MACHINE based on the output of uname instead of i386? echo i586-pc-interix exit ;; i*:UWIN*:*) echo ${UNAME_MACHINE}-pc-uwin exit ;; amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) echo x86_64-unknown-cygwin exit ;; p*:CYGWIN*:*) echo powerpcle-unknown-cygwin exit ;; prep*:SunOS:5.*:*) echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; *:GNU:*:*) # the GNU system echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` exit ;; *:GNU/*:*:*) # other systems with GNU libc and userland echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu exit ;; i*86:Minix:*:*) echo ${UNAME_MACHINE}-pc-minix exit ;; aarch64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; aarch64_be:Linux:*:*) UNAME_MACHINE=aarch64_be echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; alpha:Linux:*:*) case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in EV5) UNAME_MACHINE=alphaev5 ;; EV56) UNAME_MACHINE=alphaev56 ;; PCA56) UNAME_MACHINE=alphapca56 ;; PCA57) UNAME_MACHINE=alphapca56 ;; EV6) UNAME_MACHINE=alphaev6 ;; EV67) UNAME_MACHINE=alphaev67 ;; EV68*) UNAME_MACHINE=alphaev68 ;; esac objdump --private-headers /bin/sh | grep -q ld.so.1 if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} exit ;; arm*:Linux:*:*) eval $set_cc_for_build if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_EABI__ then echo ${UNAME_MACHINE}-unknown-linux-gnu else if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_PCS_VFP then echo ${UNAME_MACHINE}-unknown-linux-gnueabi else echo ${UNAME_MACHINE}-unknown-linux-gnueabihf fi fi exit ;; avr32*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; cris:Linux:*:*) echo ${UNAME_MACHINE}-axis-linux-gnu exit ;; crisv32:Linux:*:*) echo ${UNAME_MACHINE}-axis-linux-gnu exit ;; frv:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; hexagon:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; i*86:Linux:*:*) LIBC=gnu eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #ifdef __dietlibc__ LIBC=dietlibc #endif EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'` echo "${UNAME_MACHINE}-pc-linux-${LIBC}" exit ;; ia64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; m32r*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; m68*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; mips:Linux:*:* | mips64:Linux:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #undef CPU #undef ${UNAME_MACHINE} #undef ${UNAME_MACHINE}el #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) CPU=${UNAME_MACHINE}el #else #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) CPU=${UNAME_MACHINE} #else CPU= #endif #endif EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } ;; or32:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; padre:Linux:*:*) echo sparc-unknown-linux-gnu exit ;; parisc64:Linux:*:* | hppa64:Linux:*:*) echo hppa64-unknown-linux-gnu exit ;; parisc:Linux:*:* | hppa:Linux:*:*) # Look for CPU level case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in PA7*) echo hppa1.1-unknown-linux-gnu ;; PA8*) echo hppa2.0-unknown-linux-gnu ;; *) echo hppa-unknown-linux-gnu ;; esac exit ;; ppc64:Linux:*:*) echo powerpc64-unknown-linux-gnu exit ;; ppc:Linux:*:*) echo powerpc-unknown-linux-gnu exit ;; s390:Linux:*:* | s390x:Linux:*:*) echo ${UNAME_MACHINE}-ibm-linux exit ;; sh64*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; sh*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; sparc:Linux:*:* | sparc64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; tile*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; vax:Linux:*:*) echo ${UNAME_MACHINE}-dec-linux-gnu exit ;; x86_64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; xtensa*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; i*86:DYNIX/ptx:4*:*) # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. # earlier versions are messed up and put the nodename in both # sysname and nodename. echo i386-sequent-sysv4 exit ;; i*86:UNIX_SV:4.2MP:2.*) # Unixware is an offshoot of SVR4, but it has its own version # number series starting with 2... # I am not positive that other SVR4 systems won't match this, # I just have to hope. -- rms. # Use sysv4.2uw... so that sysv4* matches it. echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} exit ;; i*86:OS/2:*:*) # If we were able to find `uname', then EMX Unix compatibility # is probably installed. echo ${UNAME_MACHINE}-pc-os2-emx exit ;; i*86:XTS-300:*:STOP) echo ${UNAME_MACHINE}-unknown-stop exit ;; i*86:atheos:*:*) echo ${UNAME_MACHINE}-unknown-atheos exit ;; i*86:syllable:*:*) echo ${UNAME_MACHINE}-pc-syllable exit ;; i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) echo i386-unknown-lynxos${UNAME_RELEASE} exit ;; i*86:*DOS:*:*) echo ${UNAME_MACHINE}-pc-msdosdjgpp exit ;; i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} else echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} fi exit ;; i*86:*:5:[678]*) # UnixWare 7.x, OpenUNIX and OpenServer 6. case `/bin/uname -X | grep "^Machine"` in *486*) UNAME_MACHINE=i486 ;; *Pentium) UNAME_MACHINE=i586 ;; *Pent*|*Celeron) UNAME_MACHINE=i686 ;; esac echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} exit ;; i*86:*:3.2:*) if test -f /usr/options/cb.name; then UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ && UNAME_MACHINE=i586 (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ && UNAME_MACHINE=i686 (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ && UNAME_MACHINE=i686 echo ${UNAME_MACHINE}-pc-sco$UNAME_REL else echo ${UNAME_MACHINE}-pc-sysv32 fi exit ;; pc:*:*:*) # Left here for compatibility: # uname -m prints for DJGPP always 'pc', but it prints nothing about # the processor, so we play safe by assuming i586. # Note: whatever this is, it MUST be the same as what config.sub # prints for the "djgpp" host, or else GDB configury will decide that # this is a cross-build. echo i586-pc-msdosdjgpp exit ;; Intel:Mach:3*:*) echo i386-pc-mach3 exit ;; paragon:*:*:*) echo i860-intel-osf1 exit ;; i860:*:4.*:*) # i860-SVR4 if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 else # Add other i860-SVR4 vendors below as they are discovered. echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 fi exit ;; mini*:CTIX:SYS*5:*) # "miniframe" echo m68010-convergent-sysv exit ;; mc68k:UNIX:SYSTEM5:3.51m) echo m68k-convergent-sysv exit ;; M680?0:D-NIX:5.3:*) echo m68k-diab-dnix exit ;; M68*:*:R3V[5678]*:*) test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) OS_REL='' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4; exit; } ;; NCR*:*:4.2:* | MPRAS*:*:4.2:*) OS_REL='.3' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) echo m68k-unknown-lynxos${UNAME_RELEASE} exit ;; mc68030:UNIX_System_V:4.*:*) echo m68k-atari-sysv4 exit ;; TSUNAMI:LynxOS:2.*:*) echo sparc-unknown-lynxos${UNAME_RELEASE} exit ;; rs6000:LynxOS:2.*:*) echo rs6000-unknown-lynxos${UNAME_RELEASE} exit ;; PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) echo powerpc-unknown-lynxos${UNAME_RELEASE} exit ;; SM[BE]S:UNIX_SV:*:*) echo mips-dde-sysv${UNAME_RELEASE} exit ;; RM*:ReliantUNIX-*:*:*) echo mips-sni-sysv4 exit ;; RM*:SINIX-*:*:*) echo mips-sni-sysv4 exit ;; *:SINIX-*:*:*) if uname -p 2>/dev/null >/dev/null ; then UNAME_MACHINE=`(uname -p) 2>/dev/null` echo ${UNAME_MACHINE}-sni-sysv4 else echo ns32k-sni-sysv fi exit ;; PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort # says echo i586-unisys-sysv4 exit ;; *:UNIX_System_V:4*:FTX*) # From Gerald Hewes . # How about differentiating between stratus architectures? -djm echo hppa1.1-stratus-sysv4 exit ;; *:*:*:FTX*) # From seanf@swdc.stratus.com. echo i860-stratus-sysv4 exit ;; i*86:VOS:*:*) # From Paul.Green@stratus.com. echo ${UNAME_MACHINE}-stratus-vos exit ;; *:VOS:*:*) # From Paul.Green@stratus.com. echo hppa1.1-stratus-vos exit ;; mc68*:A/UX:*:*) echo m68k-apple-aux${UNAME_RELEASE} exit ;; news*:NEWS-OS:6*:*) echo mips-sony-newsos6 exit ;; R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) if [ -d /usr/nec ]; then echo mips-nec-sysv${UNAME_RELEASE} else echo mips-unknown-sysv${UNAME_RELEASE} fi exit ;; BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. echo powerpc-be-beos exit ;; BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. echo powerpc-apple-beos exit ;; BePC:BeOS:*:*) # BeOS running on Intel PC compatible. echo i586-pc-beos exit ;; BePC:Haiku:*:*) # Haiku running on Intel PC compatible. echo i586-pc-haiku exit ;; SX-4:SUPER-UX:*:*) echo sx4-nec-superux${UNAME_RELEASE} exit ;; SX-5:SUPER-UX:*:*) echo sx5-nec-superux${UNAME_RELEASE} exit ;; SX-6:SUPER-UX:*:*) echo sx6-nec-superux${UNAME_RELEASE} exit ;; SX-7:SUPER-UX:*:*) echo sx7-nec-superux${UNAME_RELEASE} exit ;; SX-8:SUPER-UX:*:*) echo sx8-nec-superux${UNAME_RELEASE} exit ;; SX-8R:SUPER-UX:*:*) echo sx8r-nec-superux${UNAME_RELEASE} exit ;; Power*:Rhapsody:*:*) echo powerpc-apple-rhapsody${UNAME_RELEASE} exit ;; *:Rhapsody:*:*) echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} exit ;; *:Darwin:*:*) UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown case $UNAME_PROCESSOR in i386) eval $set_cc_for_build if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then UNAME_PROCESSOR="x86_64" fi fi ;; unknown) UNAME_PROCESSOR=powerpc ;; esac echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} exit ;; *:procnto*:*:* | *:QNX:[0123456789]*:*) UNAME_PROCESSOR=`uname -p` if test "$UNAME_PROCESSOR" = "x86"; then UNAME_PROCESSOR=i386 UNAME_MACHINE=pc fi echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} exit ;; *:QNX:*:4*) echo i386-pc-qnx exit ;; NEO-?:NONSTOP_KERNEL:*:*) echo neo-tandem-nsk${UNAME_RELEASE} exit ;; NSE-?:NONSTOP_KERNEL:*:*) echo nse-tandem-nsk${UNAME_RELEASE} exit ;; NSR-?:NONSTOP_KERNEL:*:*) echo nsr-tandem-nsk${UNAME_RELEASE} exit ;; *:NonStop-UX:*:*) echo mips-compaq-nonstopux exit ;; BS2000:POSIX*:*:*) echo bs2000-siemens-sysv exit ;; DS/*:UNIX_System_V:*:*) echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} exit ;; *:Plan9:*:*) # "uname -m" is not consistent, so use $cputype instead. 386 # is converted to i386 for consistency with other x86 # operating systems. if test "$cputype" = "386"; then UNAME_MACHINE=i386 else UNAME_MACHINE="$cputype" fi echo ${UNAME_MACHINE}-unknown-plan9 exit ;; *:TOPS-10:*:*) echo pdp10-unknown-tops10 exit ;; *:TENEX:*:*) echo pdp10-unknown-tenex exit ;; KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) echo pdp10-dec-tops20 exit ;; XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) echo pdp10-xkl-tops20 exit ;; *:TOPS-20:*:*) echo pdp10-unknown-tops20 exit ;; *:ITS:*:*) echo pdp10-unknown-its exit ;; SEI:*:*:SEIUX) echo mips-sei-seiux${UNAME_RELEASE} exit ;; *:DragonFly:*:*) echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` exit ;; *:*VMS:*:*) UNAME_MACHINE=`(uname -p) 2>/dev/null` case "${UNAME_MACHINE}" in A*) echo alpha-dec-vms ; exit ;; I*) echo ia64-dec-vms ; exit ;; V*) echo vax-dec-vms ; exit ;; esac ;; *:XENIX:*:SysV) echo i386-pc-xenix exit ;; i*86:skyos:*:*) echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' exit ;; i*86:rdos:*:*) echo ${UNAME_MACHINE}-pc-rdos exit ;; i*86:AROS:*:*) echo ${UNAME_MACHINE}-pc-aros exit ;; x86_64:VMkernel:*:*) echo ${UNAME_MACHINE}-unknown-esx exit ;; esac #echo '(No uname command or uname output not recognized.)' 1>&2 #echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 eval $set_cc_for_build cat >$dummy.c < # include #endif main () { #if defined (sony) #if defined (MIPSEB) /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, I don't know.... */ printf ("mips-sony-bsd\n"); exit (0); #else #include printf ("m68k-sony-newsos%s\n", #ifdef NEWSOS4 "4" #else "" #endif ); exit (0); #endif #endif #if defined (__arm) && defined (__acorn) && defined (__unix) printf ("arm-acorn-riscix\n"); exit (0); #endif #if defined (hp300) && !defined (hpux) printf ("m68k-hp-bsd\n"); exit (0); #endif #if defined (NeXT) #if !defined (__ARCHITECTURE__) #define __ARCHITECTURE__ "m68k" #endif int version; version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; if (version < 4) printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); else printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); exit (0); #endif #if defined (MULTIMAX) || defined (n16) #if defined (UMAXV) printf ("ns32k-encore-sysv\n"); exit (0); #else #if defined (CMU) printf ("ns32k-encore-mach\n"); exit (0); #else printf ("ns32k-encore-bsd\n"); exit (0); #endif #endif #endif #if defined (__386BSD__) printf ("i386-pc-bsd\n"); exit (0); #endif #if defined (sequent) #if defined (i386) printf ("i386-sequent-dynix\n"); exit (0); #endif #if defined (ns32000) printf ("ns32k-sequent-dynix\n"); exit (0); #endif #endif #if defined (_SEQUENT_) struct utsname un; uname(&un); if (strncmp(un.version, "V2", 2) == 0) { printf ("i386-sequent-ptx2\n"); exit (0); } if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ printf ("i386-sequent-ptx1\n"); exit (0); } printf ("i386-sequent-ptx\n"); exit (0); #endif #if defined (vax) # if !defined (ultrix) # include # if defined (BSD) # if BSD == 43 printf ("vax-dec-bsd4.3\n"); exit (0); # else # if BSD == 199006 printf ("vax-dec-bsd4.3reno\n"); exit (0); # else printf ("vax-dec-bsd\n"); exit (0); # endif # endif # else printf ("vax-dec-bsd\n"); exit (0); # endif # else printf ("vax-dec-ultrix\n"); exit (0); # endif #endif #if defined (alliant) && defined (i860) printf ("i860-alliant-bsd\n"); exit (0); #endif exit (1); } EOF $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && { echo "$SYSTEM_NAME"; exit; } # Apollos put the system type in the environment. test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } # Convex versions that predate uname can use getsysinfo(1) if [ -x /usr/convex/getsysinfo ] then case `getsysinfo -f cpu_type` in c1*) echo c1-convex-bsd exit ;; c2*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit ;; c34*) echo c34-convex-bsd exit ;; c38*) echo c38-convex-bsd exit ;; c4*) echo c4-convex-bsd exit ;; esac fi cat >&2 < in order to provide the needed information to handle your system. config.guess timestamp = $timestamp uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` /bin/uname -X = `(/bin/uname -X) 2>/dev/null` hostinfo = `(hostinfo) 2>/dev/null` /bin/universe = `(/bin/universe) 2>/dev/null` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` /bin/arch = `(/bin/arch) 2>/dev/null` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` UNAME_MACHINE = ${UNAME_MACHINE} UNAME_RELEASE = ${UNAME_RELEASE} UNAME_SYSTEM = ${UNAME_SYSTEM} UNAME_VERSION = ${UNAME_VERSION} EOF exit 1 # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: dlt-daemon-2.18.4/gtest-1.7.0/build-aux/config.h.in000066400000000000000000000034611353342203500213420ustar00rootroot00000000000000/* build-aux/config.h.in. Generated from configure.ac by autoheader. */ /* Define to 1 if you have the header file. */ #undef HAVE_DLFCN_H /* Define to 1 if you have the header file. */ #undef HAVE_INTTYPES_H /* Define to 1 if you have the header file. */ #undef HAVE_MEMORY_H /* Define if you have POSIX threads libraries and header files. */ #undef HAVE_PTHREAD /* Define to 1 if you have the header file. */ #undef HAVE_STDINT_H /* Define to 1 if you have the header file. */ #undef HAVE_STDLIB_H /* Define to 1 if you have the header file. */ #undef HAVE_STRINGS_H /* Define to 1 if you have the header file. */ #undef HAVE_STRING_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_STAT_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TYPES_H /* Define to 1 if you have the header file. */ #undef HAVE_UNISTD_H /* Define to the sub-directory in which libtool stores uninstalled libraries. */ #undef LT_OBJDIR /* Name of package */ #undef PACKAGE /* Define to the address where bug reports for this package should be sent. */ #undef PACKAGE_BUGREPORT /* Define to the full name of this package. */ #undef PACKAGE_NAME /* Define to the full name and version of this package. */ #undef PACKAGE_STRING /* Define to the one symbol short name of this package. */ #undef PACKAGE_TARNAME /* Define to the home page for this package. */ #undef PACKAGE_URL /* Define to the version of this package. */ #undef PACKAGE_VERSION /* Define to necessary symbol if this constant uses a non-standard name on your system. */ #undef PTHREAD_CREATE_JOINABLE /* Define to 1 if you have the ANSI C header files. */ #undef STDC_HEADERS /* Version number of package */ #undef VERSION dlt-daemon-2.18.4/gtest-1.7.0/build-aux/config.sub000077500000000000000000001051761353342203500213100ustar00rootroot00000000000000#! /bin/sh # Configuration validation subroutine script. # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, # 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, # 2011, 2012 Free Software Foundation, Inc. timestamp='2012-02-10' # This file is (in principle) common to ALL GNU software. # The presence of a machine in this file suggests that SOME GNU software # can handle that machine. It does not imply ALL GNU software can. # # This file is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, see . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Please send patches to . Submit a context # diff and a properly formatted GNU ChangeLog entry. # # Configuration subroutine to validate and canonicalize a configuration type. # Supply the specified configuration type as an argument. # If it is invalid, we print an error message on stderr and exit with code 1. # Otherwise, we print the canonical config type on stdout and succeed. # You can get the latest version of this script from: # http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD # This file is supposed to be the same for all GNU packages # and recognize all the CPU types, system types and aliases # that are meaningful with *any* GNU software. # Each package is responsible for reporting which valid configurations # it does not support. The user should be able to distinguish # a failure to support a valid configuration from a meaningless # configuration. # The goal of this file is to map all the various variations of a given # machine specification into a single specification in the form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM # or in some cases, the newer four-part form: # CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM # It is wrong to echo any other type of specification. me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] CPU-MFR-OPSYS $0 [OPTION] ALIAS Canonicalize a configuration name. Operation modes: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.sub ($timestamp) Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" exit 1 ;; *local*) # First pass through any local machine types. echo $1 exit ;; * ) break ;; esac done case $# in 0) echo "$me: missing argument$help" >&2 exit 1;; 1) ;; *) echo "$me: too many arguments$help" >&2 exit 1;; esac # Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). # Here we must recognize all the valid KERNEL-OS combinations. maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` case $maybe_os in nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ knetbsd*-gnu* | netbsd*-gnu* | \ kopensolaris*-gnu* | \ storm-chaos* | os2-emx* | rtmk-nova*) os=-$maybe_os basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` ;; android-linux) os=-linux-android basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown ;; *) basic_machine=`echo $1 | sed 's/-[^-]*$//'` if [ $basic_machine != $1 ] then os=`echo $1 | sed 's/.*-/-/'` else os=; fi ;; esac ### Let's recognize common machines as not being operating systems so ### that things like config.sub decstation-3100 work. We also ### recognize some manufacturers as not being operating systems, so we ### can provide default operating systems below. case $os in -sun*os*) # Prevent following clause from handling this invalid input. ;; -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ -apple | -axis | -knuth | -cray | -microblaze) os= basic_machine=$1 ;; -bluegene*) os=-cnk ;; -sim | -cisco | -oki | -wec | -winbond) os= basic_machine=$1 ;; -scout) ;; -wrs) os=-vxworks basic_machine=$1 ;; -chorusos*) os=-chorusos basic_machine=$1 ;; -chorusrdb) os=-chorusrdb basic_machine=$1 ;; -hiux*) os=-hiuxwe2 ;; -sco6) os=-sco5v6 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco5) os=-sco3.2v5 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco4) os=-sco3.2v4 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2.[4-9]*) os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2v[4-9]*) # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco5v6*) # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco*) os=-sco3.2v2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -udk*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -isc) os=-isc2.2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -clix*) basic_machine=clipper-intergraph ;; -isc*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -lynx*) os=-lynxos ;; -ptx*) basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` ;; -windowsnt*) os=`echo $os | sed -e 's/windowsnt/winnt/'` ;; -psos*) os=-psos ;; -mint | -mint[0-9]*) basic_machine=m68k-atari os=-mint ;; esac # Decode aliases for certain CPU-COMPANY combinations. case $basic_machine in # Recognize the basic CPU types without company name. # Some are omitted here because they have special meanings below. 1750a | 580 \ | a29k \ | aarch64 | aarch64_be \ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ | am33_2.0 \ | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \ | be32 | be64 \ | bfin \ | c4x | clipper \ | d10v | d30v | dlx | dsp16xx \ | epiphany \ | fido | fr30 | frv \ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ | hexagon \ | i370 | i860 | i960 | ia64 \ | ip2k | iq2000 \ | le32 | le64 \ | lm32 \ | m32c | m32r | m32rle | m68000 | m68k | m88k \ | maxq | mb | microblaze | mcore | mep | metag \ | mips | mipsbe | mipseb | mipsel | mipsle \ | mips16 \ | mips64 | mips64el \ | mips64octeon | mips64octeonel \ | mips64orion | mips64orionel \ | mips64r5900 | mips64r5900el \ | mips64vr | mips64vrel \ | mips64vr4100 | mips64vr4100el \ | mips64vr4300 | mips64vr4300el \ | mips64vr5000 | mips64vr5000el \ | mips64vr5900 | mips64vr5900el \ | mipsisa32 | mipsisa32el \ | mipsisa32r2 | mipsisa32r2el \ | mipsisa64 | mipsisa64el \ | mipsisa64r2 | mipsisa64r2el \ | mipsisa64sb1 | mipsisa64sb1el \ | mipsisa64sr71k | mipsisa64sr71kel \ | mipstx39 | mipstx39el \ | mn10200 | mn10300 \ | moxie \ | mt \ | msp430 \ | nds32 | nds32le | nds32be \ | nios | nios2 \ | ns16k | ns32k \ | open8 \ | or32 \ | pdp10 | pdp11 | pj | pjl \ | powerpc | powerpc64 | powerpc64le | powerpcle \ | pyramid \ | rl78 | rx \ | score \ | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ | sh64 | sh64le \ | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ | spu \ | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ | ubicom32 \ | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ | we32k \ | x86 | xc16x | xstormy16 | xtensa \ | z8k | z80) basic_machine=$basic_machine-unknown ;; c54x) basic_machine=tic54x-unknown ;; c55x) basic_machine=tic55x-unknown ;; c6x) basic_machine=tic6x-unknown ;; m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | picochip) basic_machine=$basic_machine-unknown os=-none ;; m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) ;; ms1) basic_machine=mt-unknown ;; strongarm | thumb | xscale) basic_machine=arm-unknown ;; xgate) basic_machine=$basic_machine-unknown os=-none ;; xscaleeb) basic_machine=armeb-unknown ;; xscaleel) basic_machine=armel-unknown ;; # We use `pc' rather than `unknown' # because (1) that's what they normally are, and # (2) the word "unknown" tends to confuse beginning users. i*86 | x86_64) basic_machine=$basic_machine-pc ;; # Object if more than one company name word. *-*-*) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; # Recognize the basic CPU types with company name. 580-* \ | a29k-* \ | aarch64-* | aarch64_be-* \ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ | avr-* | avr32-* \ | be32-* | be64-* \ | bfin-* | bs2000-* \ | c[123]* | c30-* | [cjt]90-* | c4x-* \ | clipper-* | craynv-* | cydra-* \ | d10v-* | d30v-* | dlx-* \ | elxsi-* \ | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ | h8300-* | h8500-* \ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ | hexagon-* \ | i*86-* | i860-* | i960-* | ia64-* \ | ip2k-* | iq2000-* \ | le32-* | le64-* \ | lm32-* \ | m32c-* | m32r-* | m32rle-* \ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ | m88110-* | m88k-* | maxq-* | mcore-* | metag-* | microblaze-* \ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ | mips16-* \ | mips64-* | mips64el-* \ | mips64octeon-* | mips64octeonel-* \ | mips64orion-* | mips64orionel-* \ | mips64r5900-* | mips64r5900el-* \ | mips64vr-* | mips64vrel-* \ | mips64vr4100-* | mips64vr4100el-* \ | mips64vr4300-* | mips64vr4300el-* \ | mips64vr5000-* | mips64vr5000el-* \ | mips64vr5900-* | mips64vr5900el-* \ | mipsisa32-* | mipsisa32el-* \ | mipsisa32r2-* | mipsisa32r2el-* \ | mipsisa64-* | mipsisa64el-* \ | mipsisa64r2-* | mipsisa64r2el-* \ | mipsisa64sb1-* | mipsisa64sb1el-* \ | mipsisa64sr71k-* | mipsisa64sr71kel-* \ | mipstx39-* | mipstx39el-* \ | mmix-* \ | mt-* \ | msp430-* \ | nds32-* | nds32le-* | nds32be-* \ | nios-* | nios2-* \ | none-* | np1-* | ns16k-* | ns32k-* \ | open8-* \ | orion-* \ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ | pyramid-* \ | rl78-* | romp-* | rs6000-* | rx-* \ | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ | sparclite-* \ | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \ | tahoe-* \ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ | tile*-* \ | tron-* \ | ubicom32-* \ | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ | vax-* \ | we32k-* \ | x86-* | x86_64-* | xc16x-* | xps100-* \ | xstormy16-* | xtensa*-* \ | ymp-* \ | z8k-* | z80-*) ;; # Recognize the basic CPU types without company name, with glob match. xtensa*) basic_machine=$basic_machine-unknown ;; # Recognize the various machine names and aliases which stand # for a CPU type and a company and sometimes even an OS. 386bsd) basic_machine=i386-unknown os=-bsd ;; 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) basic_machine=m68000-att ;; 3b*) basic_machine=we32k-att ;; a29khif) basic_machine=a29k-amd os=-udi ;; abacus) basic_machine=abacus-unknown ;; adobe68k) basic_machine=m68010-adobe os=-scout ;; alliant | fx80) basic_machine=fx80-alliant ;; altos | altos3068) basic_machine=m68k-altos ;; am29k) basic_machine=a29k-none os=-bsd ;; amd64) basic_machine=x86_64-pc ;; amd64-*) basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; amdahl) basic_machine=580-amdahl os=-sysv ;; amiga | amiga-*) basic_machine=m68k-unknown ;; amigaos | amigados) basic_machine=m68k-unknown os=-amigaos ;; amigaunix | amix) basic_machine=m68k-unknown os=-sysv4 ;; apollo68) basic_machine=m68k-apollo os=-sysv ;; apollo68bsd) basic_machine=m68k-apollo os=-bsd ;; aros) basic_machine=i386-pc os=-aros ;; aux) basic_machine=m68k-apple os=-aux ;; balance) basic_machine=ns32k-sequent os=-dynix ;; blackfin) basic_machine=bfin-unknown os=-linux ;; blackfin-*) basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; bluegene*) basic_machine=powerpc-ibm os=-cnk ;; c54x-*) basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'` ;; c55x-*) basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'` ;; c6x-*) basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'` ;; c90) basic_machine=c90-cray os=-unicos ;; cegcc) basic_machine=arm-unknown os=-cegcc ;; convex-c1) basic_machine=c1-convex os=-bsd ;; convex-c2) basic_machine=c2-convex os=-bsd ;; convex-c32) basic_machine=c32-convex os=-bsd ;; convex-c34) basic_machine=c34-convex os=-bsd ;; convex-c38) basic_machine=c38-convex os=-bsd ;; cray | j90) basic_machine=j90-cray os=-unicos ;; craynv) basic_machine=craynv-cray os=-unicosmp ;; cr16 | cr16-*) basic_machine=cr16-unknown os=-elf ;; crds | unos) basic_machine=m68k-crds ;; crisv32 | crisv32-* | etraxfs*) basic_machine=crisv32-axis ;; cris | cris-* | etrax*) basic_machine=cris-axis ;; crx) basic_machine=crx-unknown os=-elf ;; da30 | da30-*) basic_machine=m68k-da30 ;; decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) basic_machine=mips-dec ;; decsystem10* | dec10*) basic_machine=pdp10-dec os=-tops10 ;; decsystem20* | dec20*) basic_machine=pdp10-dec os=-tops20 ;; delta | 3300 | motorola-3300 | motorola-delta \ | 3300-motorola | delta-motorola) basic_machine=m68k-motorola ;; delta88) basic_machine=m88k-motorola os=-sysv3 ;; dicos) basic_machine=i686-pc os=-dicos ;; djgpp) basic_machine=i586-pc os=-msdosdjgpp ;; dpx20 | dpx20-*) basic_machine=rs6000-bull os=-bosx ;; dpx2* | dpx2*-bull) basic_machine=m68k-bull os=-sysv3 ;; ebmon29k) basic_machine=a29k-amd os=-ebmon ;; elxsi) basic_machine=elxsi-elxsi os=-bsd ;; encore | umax | mmax) basic_machine=ns32k-encore ;; es1800 | OSE68k | ose68k | ose | OSE) basic_machine=m68k-ericsson os=-ose ;; fx2800) basic_machine=i860-alliant ;; genix) basic_machine=ns32k-ns ;; gmicro) basic_machine=tron-gmicro os=-sysv ;; go32) basic_machine=i386-pc os=-go32 ;; h3050r* | hiux*) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; h8300hms) basic_machine=h8300-hitachi os=-hms ;; h8300xray) basic_machine=h8300-hitachi os=-xray ;; h8500hms) basic_machine=h8500-hitachi os=-hms ;; harris) basic_machine=m88k-harris os=-sysv3 ;; hp300-*) basic_machine=m68k-hp ;; hp300bsd) basic_machine=m68k-hp os=-bsd ;; hp300hpux) basic_machine=m68k-hp os=-hpux ;; hp3k9[0-9][0-9] | hp9[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k2[0-9][0-9] | hp9k31[0-9]) basic_machine=m68000-hp ;; hp9k3[2-9][0-9]) basic_machine=m68k-hp ;; hp9k6[0-9][0-9] | hp6[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k7[0-79][0-9] | hp7[0-79][0-9]) basic_machine=hppa1.1-hp ;; hp9k78[0-9] | hp78[0-9]) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[0-9][13679] | hp8[0-9][13679]) basic_machine=hppa1.1-hp ;; hp9k8[0-9][0-9] | hp8[0-9][0-9]) basic_machine=hppa1.0-hp ;; hppa-next) os=-nextstep3 ;; hppaosf) basic_machine=hppa1.1-hp os=-osf ;; hppro) basic_machine=hppa1.1-hp os=-proelf ;; i370-ibm* | ibm*) basic_machine=i370-ibm ;; i*86v32) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv32 ;; i*86v4*) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv4 ;; i*86v) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv ;; i*86sol2) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-solaris2 ;; i386mach) basic_machine=i386-mach os=-mach ;; i386-vsta | vsta) basic_machine=i386-unknown os=-vsta ;; iris | iris4d) basic_machine=mips-sgi case $os in -irix*) ;; *) os=-irix4 ;; esac ;; isi68 | isi) basic_machine=m68k-isi os=-sysv ;; m68knommu) basic_machine=m68k-unknown os=-linux ;; m68knommu-*) basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; m88k-omron*) basic_machine=m88k-omron ;; magnum | m3230) basic_machine=mips-mips os=-sysv ;; merlin) basic_machine=ns32k-utek os=-sysv ;; microblaze) basic_machine=microblaze-xilinx ;; mingw32) basic_machine=i386-pc os=-mingw32 ;; mingw32ce) basic_machine=arm-unknown os=-mingw32ce ;; miniframe) basic_machine=m68000-convergent ;; *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) basic_machine=m68k-atari os=-mint ;; mips3*-*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` ;; mips3*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown ;; monitor) basic_machine=m68k-rom68k os=-coff ;; morphos) basic_machine=powerpc-unknown os=-morphos ;; msdos) basic_machine=i386-pc os=-msdos ;; ms1-*) basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` ;; msys) basic_machine=i386-pc os=-msys ;; mvs) basic_machine=i370-ibm os=-mvs ;; nacl) basic_machine=le32-unknown os=-nacl ;; ncr3000) basic_machine=i486-ncr os=-sysv4 ;; netbsd386) basic_machine=i386-unknown os=-netbsd ;; netwinder) basic_machine=armv4l-rebel os=-linux ;; news | news700 | news800 | news900) basic_machine=m68k-sony os=-newsos ;; news1000) basic_machine=m68030-sony os=-newsos ;; news-3600 | risc-news) basic_machine=mips-sony os=-newsos ;; necv70) basic_machine=v70-nec os=-sysv ;; next | m*-next ) basic_machine=m68k-next case $os in -nextstep* ) ;; -ns2*) os=-nextstep2 ;; *) os=-nextstep3 ;; esac ;; nh3000) basic_machine=m68k-harris os=-cxux ;; nh[45]000) basic_machine=m88k-harris os=-cxux ;; nindy960) basic_machine=i960-intel os=-nindy ;; mon960) basic_machine=i960-intel os=-mon960 ;; nonstopux) basic_machine=mips-compaq os=-nonstopux ;; np1) basic_machine=np1-gould ;; neo-tandem) basic_machine=neo-tandem ;; nse-tandem) basic_machine=nse-tandem ;; nsr-tandem) basic_machine=nsr-tandem ;; op50n-* | op60c-*) basic_machine=hppa1.1-oki os=-proelf ;; openrisc | openrisc-*) basic_machine=or32-unknown ;; os400) basic_machine=powerpc-ibm os=-os400 ;; OSE68000 | ose68000) basic_machine=m68000-ericsson os=-ose ;; os68k) basic_machine=m68k-none os=-os68k ;; pa-hitachi) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; paragon) basic_machine=i860-intel os=-osf ;; parisc) basic_machine=hppa-unknown os=-linux ;; parisc-*) basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; pbd) basic_machine=sparc-tti ;; pbb) basic_machine=m68k-tti ;; pc532 | pc532-*) basic_machine=ns32k-pc532 ;; pc98) basic_machine=i386-pc ;; pc98-*) basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentium | p5 | k5 | k6 | nexgen | viac3) basic_machine=i586-pc ;; pentiumpro | p6 | 6x86 | athlon | athlon_*) basic_machine=i686-pc ;; pentiumii | pentium2 | pentiumiii | pentium3) basic_machine=i686-pc ;; pentium4) basic_machine=i786-pc ;; pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumpro-* | p6-* | 6x86-* | athlon-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentium4-*) basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pn) basic_machine=pn-gould ;; power) basic_machine=power-ibm ;; ppc | ppcbe) basic_machine=powerpc-unknown ;; ppc-* | ppcbe-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppcle | powerpclittle | ppc-le | powerpc-little) basic_machine=powerpcle-unknown ;; ppcle-* | powerpclittle-*) basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64) basic_machine=powerpc64-unknown ;; ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64le | powerpc64little | ppc64-le | powerpc64-little) basic_machine=powerpc64le-unknown ;; ppc64le-* | powerpc64little-*) basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ps2) basic_machine=i386-ibm ;; pw32) basic_machine=i586-unknown os=-pw32 ;; rdos) basic_machine=i386-pc os=-rdos ;; rom68k) basic_machine=m68k-rom68k os=-coff ;; rm[46]00) basic_machine=mips-siemens ;; rtpc | rtpc-*) basic_machine=romp-ibm ;; s390 | s390-*) basic_machine=s390-ibm ;; s390x | s390x-*) basic_machine=s390x-ibm ;; sa29200) basic_machine=a29k-amd os=-udi ;; sb1) basic_machine=mipsisa64sb1-unknown ;; sb1el) basic_machine=mipsisa64sb1el-unknown ;; sde) basic_machine=mipsisa32-sde os=-elf ;; sei) basic_machine=mips-sei os=-seiux ;; sequent) basic_machine=i386-sequent ;; sh) basic_machine=sh-hitachi os=-hms ;; sh5el) basic_machine=sh5le-unknown ;; sh64) basic_machine=sh64-unknown ;; sparclite-wrs | simso-wrs) basic_machine=sparclite-wrs os=-vxworks ;; sps7) basic_machine=m68k-bull os=-sysv2 ;; spur) basic_machine=spur-unknown ;; st2000) basic_machine=m68k-tandem ;; stratus) basic_machine=i860-stratus os=-sysv4 ;; strongarm-* | thumb-*) basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'` ;; sun2) basic_machine=m68000-sun ;; sun2os3) basic_machine=m68000-sun os=-sunos3 ;; sun2os4) basic_machine=m68000-sun os=-sunos4 ;; sun3os3) basic_machine=m68k-sun os=-sunos3 ;; sun3os4) basic_machine=m68k-sun os=-sunos4 ;; sun4os3) basic_machine=sparc-sun os=-sunos3 ;; sun4os4) basic_machine=sparc-sun os=-sunos4 ;; sun4sol2) basic_machine=sparc-sun os=-solaris2 ;; sun3 | sun3-*) basic_machine=m68k-sun ;; sun4) basic_machine=sparc-sun ;; sun386 | sun386i | roadrunner) basic_machine=i386-sun ;; sv1) basic_machine=sv1-cray os=-unicos ;; symmetry) basic_machine=i386-sequent os=-dynix ;; t3e) basic_machine=alphaev5-cray os=-unicos ;; t90) basic_machine=t90-cray os=-unicos ;; tile*) basic_machine=$basic_machine-unknown os=-linux-gnu ;; tx39) basic_machine=mipstx39-unknown ;; tx39el) basic_machine=mipstx39el-unknown ;; toad1) basic_machine=pdp10-xkl os=-tops20 ;; tower | tower-32) basic_machine=m68k-ncr ;; tpf) basic_machine=s390x-ibm os=-tpf ;; udi29k) basic_machine=a29k-amd os=-udi ;; ultra3) basic_machine=a29k-nyu os=-sym1 ;; v810 | necv810) basic_machine=v810-nec os=-none ;; vaxv) basic_machine=vax-dec os=-sysv ;; vms) basic_machine=vax-dec os=-vms ;; vpp*|vx|vx-*) basic_machine=f301-fujitsu ;; vxworks960) basic_machine=i960-wrs os=-vxworks ;; vxworks68) basic_machine=m68k-wrs os=-vxworks ;; vxworks29k) basic_machine=a29k-wrs os=-vxworks ;; w65*) basic_machine=w65-wdc os=-none ;; w89k-*) basic_machine=hppa1.1-winbond os=-proelf ;; xbox) basic_machine=i686-pc os=-mingw32 ;; xps | xps100) basic_machine=xps100-honeywell ;; xscale-* | xscalee[bl]-*) basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'` ;; ymp) basic_machine=ymp-cray os=-unicos ;; z8k-*-coff) basic_machine=z8k-unknown os=-sim ;; z80-*-coff) basic_machine=z80-unknown os=-sim ;; none) basic_machine=none-none os=-none ;; # Here we handle the default manufacturer of certain CPU types. It is in # some cases the only manufacturer, in others, it is the most popular. w89k) basic_machine=hppa1.1-winbond ;; op50n) basic_machine=hppa1.1-oki ;; op60c) basic_machine=hppa1.1-oki ;; romp) basic_machine=romp-ibm ;; mmix) basic_machine=mmix-knuth ;; rs6000) basic_machine=rs6000-ibm ;; vax) basic_machine=vax-dec ;; pdp10) # there are many clones, so DEC is not a safe bet basic_machine=pdp10-unknown ;; pdp11) basic_machine=pdp11-dec ;; we32k) basic_machine=we32k-att ;; sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) basic_machine=sh-unknown ;; sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) basic_machine=sparc-sun ;; cydra) basic_machine=cydra-cydrome ;; orion) basic_machine=orion-highlevel ;; orion105) basic_machine=clipper-highlevel ;; mac | mpw | mac-mpw) basic_machine=m68k-apple ;; pmac | pmac-mpw) basic_machine=powerpc-apple ;; *-unknown) # Make sure to match an already-canonicalized machine name. ;; *) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; esac # Here we canonicalize certain aliases for manufacturers. case $basic_machine in *-digital*) basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` ;; *-commodore*) basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` ;; *) ;; esac # Decode manufacturer-specific aliases for certain operating systems. if [ x"$os" != x"" ] then case $os in # First match some system type aliases # that might get confused with valid system types. # -solaris* is a basic system type, with this one exception. -auroraux) os=-auroraux ;; -solaris1 | -solaris1.*) os=`echo $os | sed -e 's|solaris1|sunos4|'` ;; -solaris) os=-solaris2 ;; -svr4*) os=-sysv4 ;; -unixware*) os=-sysv4.2uw ;; -gnu/linux*) os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` ;; # First accept the basic system types. # The portable systems comes first. # Each alternative MUST END IN A *, to match a version number. # -sysv* is not here because it comes later, after sysvr4. -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ | -sym* | -kopensolaris* \ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ | -aos* | -aros* \ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ | -openbsd* | -solidbsd* \ | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ | -chorusos* | -chorusrdb* | -cegcc* \ | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ | -mingw32* | -linux-gnu* | -linux-android* \ | -linux-newlib* | -linux-uclibc* \ | -uxpv* | -beos* | -mpeix* | -udk* \ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*) # Remember, each alternative MUST END IN *, to match a version number. ;; -qnx*) case $basic_machine in x86-* | i*86-*) ;; *) os=-nto$os ;; esac ;; -nto-qnx*) ;; -nto*) os=`echo $os | sed -e 's|nto|nto-qnx|'` ;; -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) ;; -mac*) os=`echo $os | sed -e 's|mac|macos|'` ;; -linux-dietlibc) os=-linux-dietlibc ;; -linux*) os=`echo $os | sed -e 's|linux|linux-gnu|'` ;; -sunos5*) os=`echo $os | sed -e 's|sunos5|solaris2|'` ;; -sunos6*) os=`echo $os | sed -e 's|sunos6|solaris3|'` ;; -opened*) os=-openedition ;; -os400*) os=-os400 ;; -wince*) os=-wince ;; -osfrose*) os=-osfrose ;; -osf*) os=-osf ;; -utek*) os=-bsd ;; -dynix*) os=-bsd ;; -acis*) os=-aos ;; -atheos*) os=-atheos ;; -syllable*) os=-syllable ;; -386bsd) os=-bsd ;; -ctix* | -uts*) os=-sysv ;; -nova*) os=-rtmk-nova ;; -ns2 ) os=-nextstep2 ;; -nsk*) os=-nsk ;; # Preserve the version number of sinix5. -sinix5.*) os=`echo $os | sed -e 's|sinix|sysv|'` ;; -sinix*) os=-sysv4 ;; -tpf*) os=-tpf ;; -triton*) os=-sysv3 ;; -oss*) os=-sysv3 ;; -svr4) os=-sysv4 ;; -svr3) os=-sysv3 ;; -sysvr4) os=-sysv4 ;; # This must come after -sysvr4. -sysv*) ;; -ose*) os=-ose ;; -es1800*) os=-ose ;; -xenix) os=-xenix ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) os=-mint ;; -aros*) os=-aros ;; -kaos*) os=-kaos ;; -zvmoe) os=-zvmoe ;; -dicos*) os=-dicos ;; -nacl*) ;; -none) ;; *) # Get rid of the `-' at the beginning of $os. os=`echo $os | sed 's/[^-]*-//'` echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 exit 1 ;; esac else # Here we handle the default operating systems that come with various machines. # The value should be what the vendor currently ships out the door with their # machine or put another way, the most popular os provided with the machine. # Note that if you're going to try to match "-MANUFACTURER" here (say, # "-sun"), then you have to tell the case statement up towards the top # that MANUFACTURER isn't an operating system. Otherwise, code above # will signal an error saying that MANUFACTURER isn't an operating # system, and we'll never get to this point. case $basic_machine in score-*) os=-elf ;; spu-*) os=-elf ;; *-acorn) os=-riscix1.2 ;; arm*-rebel) os=-linux ;; arm*-semi) os=-aout ;; c4x-* | tic4x-*) os=-coff ;; tic54x-*) os=-coff ;; tic55x-*) os=-coff ;; tic6x-*) os=-coff ;; # This must come before the *-dec entry. pdp10-*) os=-tops20 ;; pdp11-*) os=-none ;; *-dec | vax-*) os=-ultrix4.2 ;; m68*-apollo) os=-domain ;; i386-sun) os=-sunos4.0.2 ;; m68000-sun) os=-sunos3 ;; m68*-cisco) os=-aout ;; mep-*) os=-elf ;; mips*-cisco) os=-elf ;; mips*-*) os=-elf ;; or32-*) os=-coff ;; *-tti) # must be before sparc entry or we get the wrong os. os=-sysv3 ;; sparc-* | *-sun) os=-sunos4.1.1 ;; *-be) os=-beos ;; *-haiku) os=-haiku ;; *-ibm) os=-aix ;; *-knuth) os=-mmixware ;; *-wec) os=-proelf ;; *-winbond) os=-proelf ;; *-oki) os=-proelf ;; *-hp) os=-hpux ;; *-hitachi) os=-hiux ;; i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) os=-sysv ;; *-cbm) os=-amigaos ;; *-dg) os=-dgux ;; *-dolphin) os=-sysv3 ;; m68k-ccur) os=-rtu ;; m88k-omron*) os=-luna ;; *-next ) os=-nextstep ;; *-sequent) os=-ptx ;; *-crds) os=-unos ;; *-ns) os=-genix ;; i370-*) os=-mvs ;; *-next) os=-nextstep3 ;; *-gould) os=-sysv ;; *-highlevel) os=-bsd ;; *-encore) os=-bsd ;; *-sgi) os=-irix ;; *-siemens) os=-sysv4 ;; *-masscomp) os=-rtu ;; f30[01]-fujitsu | f700-fujitsu) os=-uxpv ;; *-rom68k) os=-coff ;; *-*bug) os=-coff ;; *-apple) os=-macos ;; *-atari*) os=-mint ;; *) os=-none ;; esac fi # Here we handle the case where we know the os, and the CPU type, but not the # manufacturer. We pick the logical manufacturer. vendor=unknown case $basic_machine in *-unknown) case $os in -riscix*) vendor=acorn ;; -sunos*) vendor=sun ;; -cnk*|-aix*) vendor=ibm ;; -beos*) vendor=be ;; -hpux*) vendor=hp ;; -mpeix*) vendor=hp ;; -hiux*) vendor=hitachi ;; -unos*) vendor=crds ;; -dgux*) vendor=dg ;; -luna*) vendor=omron ;; -genix*) vendor=ns ;; -mvs* | -opened*) vendor=ibm ;; -os400*) vendor=ibm ;; -ptx*) vendor=sequent ;; -tpf*) vendor=ibm ;; -vxsim* | -vxworks* | -windiss*) vendor=wrs ;; -aux*) vendor=apple ;; -hms*) vendor=hitachi ;; -mpw* | -macos*) vendor=apple ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) vendor=atari ;; -vos*) vendor=stratus ;; esac basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` ;; esac echo $basic_machine$os exit # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: dlt-daemon-2.18.4/gtest-1.7.0/build-aux/depcomp000077500000000000000000000475561353342203500207110ustar00rootroot00000000000000#! /bin/sh # depcomp - compile a program generating dependencies as side-effects scriptversion=2011-12-04.11; # UTC # Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006, 2007, 2009, 2010, # 2011 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Originally written by Alexandre Oliva . case $1 in '') echo "$0: No command. Try \`$0 --help' for more information." 1>&2 exit 1; ;; -h | --h*) cat <<\EOF Usage: depcomp [--help] [--version] PROGRAM [ARGS] Run PROGRAMS ARGS to compile a file, generating dependencies as side-effects. Environment variables: depmode Dependency tracking mode. source Source file read by `PROGRAMS ARGS'. object Object file output by `PROGRAMS ARGS'. DEPDIR directory where to store dependencies. depfile Dependency file to output. tmpdepfile Temporary file to use when outputting dependencies. libtool Whether libtool is used (yes/no). Report bugs to . EOF exit $? ;; -v | --v*) echo "depcomp $scriptversion" exit $? ;; esac if test -z "$depmode" || test -z "$source" || test -z "$object"; then echo "depcomp: Variables source, object and depmode must be set" 1>&2 exit 1 fi # Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po. depfile=${depfile-`echo "$object" | sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`} tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} rm -f "$tmpdepfile" # Some modes work just like other modes, but use different flags. We # parameterize here, but still list the modes in the big case below, # to make depend.m4 easier to write. Note that we *cannot* use a case # here, because this file can only contain one case statement. if test "$depmode" = hp; then # HP compiler uses -M and no extra arg. gccflag=-M depmode=gcc fi if test "$depmode" = dashXmstdout; then # This is just like dashmstdout with a different argument. dashmflag=-xM depmode=dashmstdout fi cygpath_u="cygpath -u -f -" if test "$depmode" = msvcmsys; then # This is just like msvisualcpp but w/o cygpath translation. # Just convert the backslash-escaped backslashes to single forward # slashes to satisfy depend.m4 cygpath_u='sed s,\\\\,/,g' depmode=msvisualcpp fi if test "$depmode" = msvc7msys; then # This is just like msvc7 but w/o cygpath translation. # Just convert the backslash-escaped backslashes to single forward # slashes to satisfy depend.m4 cygpath_u='sed s,\\\\,/,g' depmode=msvc7 fi case "$depmode" in gcc3) ## gcc 3 implements dependency tracking that does exactly what ## we want. Yay! Note: for some reason libtool 1.4 doesn't like ## it if -MD -MP comes after the -MF stuff. Hmm. ## Unfortunately, FreeBSD c89 acceptance of flags depends upon ## the command line argument order; so add the flags where they ## appear in depend2.am. Note that the slowdown incurred here ## affects only configure: in makefiles, %FASTDEP% shortcuts this. for arg do case $arg in -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;; *) set fnord "$@" "$arg" ;; esac shift # fnord shift # $arg done "$@" stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi mv "$tmpdepfile" "$depfile" ;; gcc) ## There are various ways to get dependency output from gcc. Here's ## why we pick this rather obscure method: ## - Don't want to use -MD because we'd like the dependencies to end ## up in a subdir. Having to rename by hand is ugly. ## (We might end up doing this anyway to support other compilers.) ## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like ## -MM, not -M (despite what the docs say). ## - Using -M directly means running the compiler twice (even worse ## than renaming). if test -z "$gccflag"; then gccflag=-MD, fi "$@" -Wp,"$gccflag$tmpdepfile" stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" echo "$object : \\" > "$depfile" alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz ## The second -e expression handles DOS-style file names with drive letters. sed -e 's/^[^:]*: / /' \ -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" ## This next piece of magic avoids the `deleted header file' problem. ## The problem is that when a header file which appears in a .P file ## is deleted, the dependency causes make to die (because there is ## typically no way to rebuild the header). We avoid this by adding ## dummy dependencies for each header file. Too bad gcc doesn't do ## this for us directly. tr ' ' ' ' < "$tmpdepfile" | ## Some versions of gcc put a space before the `:'. On the theory ## that the space means something, we add a space to the output as ## well. hp depmode also adds that space, but also prefixes the VPATH ## to the object. Take care to not repeat it in the output. ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \ | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; hp) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; sgi) if test "$libtool" = yes; then "$@" "-Wp,-MDupdate,$tmpdepfile" else "$@" -MDupdate "$tmpdepfile" fi stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files echo "$object : \\" > "$depfile" # Clip off the initial element (the dependent). Don't try to be # clever and replace this with sed code, as IRIX sed won't handle # lines with more than a fixed number of characters (4096 in # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; # the IRIX cc adds comments like `#:fec' to the end of the # dependency line. tr ' ' ' ' < "$tmpdepfile" \ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \ tr ' ' ' ' >> "$depfile" echo >> "$depfile" # The second pass generates a dummy entry for each header file. tr ' ' ' ' < "$tmpdepfile" \ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ >> "$depfile" else # The sourcefile does not contain any dependencies, so just # store a dummy comment line, to avoid errors with the Makefile # "include basename.Plo" scheme. echo "#dummy" > "$depfile" fi rm -f "$tmpdepfile" ;; aix) # The C for AIX Compiler uses -M and outputs the dependencies # in a .u file. In older versions, this file always lives in the # current directory. Also, the AIX compiler puts `$object:' at the # start of each line; $object doesn't have directory information. # Version 6 uses the directory in both cases. dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` test "x$dir" = "x$object" && dir= base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` if test "$libtool" = yes; then tmpdepfile1=$dir$base.u tmpdepfile2=$base.u tmpdepfile3=$dir.libs/$base.u "$@" -Wc,-M else tmpdepfile1=$dir$base.u tmpdepfile2=$dir$base.u tmpdepfile3=$dir$base.u "$@" -M fi stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" exit $stat fi for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" do test -f "$tmpdepfile" && break done if test -f "$tmpdepfile"; then # Each line is of the form `foo.o: dependent.h'. # Do two passes, one to just change these to # `$object: dependent.h' and one to simply `dependent.h:'. sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" # That's a tab and a space in the []. sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" else # The sourcefile does not contain any dependencies, so just # store a dummy comment line, to avoid errors with the Makefile # "include basename.Plo" scheme. echo "#dummy" > "$depfile" fi rm -f "$tmpdepfile" ;; icc) # Intel's C compiler understands `-MD -MF file'. However on # icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c # ICC 7.0 will fill foo.d with something like # foo.o: sub/foo.c # foo.o: sub/foo.h # which is wrong. We want: # sub/foo.o: sub/foo.c # sub/foo.o: sub/foo.h # sub/foo.c: # sub/foo.h: # ICC 7.1 will output # foo.o: sub/foo.c sub/foo.h # and will wrap long lines using \ : # foo.o: sub/foo.c ... \ # sub/foo.h ... \ # ... "$@" -MD -MF "$tmpdepfile" stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" # Each line is of the form `foo.o: dependent.h', # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. # Do two passes, one to just change these to # `$object: dependent.h' and one to simply `dependent.h:'. sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" # Some versions of the HPUX 10.20 sed can't process this invocation # correctly. Breaking it into two sed invocations is a workaround. sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; hp2) # The "hp" stanza above does not work with aCC (C++) and HP's ia64 # compilers, which have integrated preprocessors. The correct option # to use with these is +Maked; it writes dependencies to a file named # 'foo.d', which lands next to the object file, wherever that # happens to be. # Much of this is similar to the tru64 case; see comments there. dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` test "x$dir" = "x$object" && dir= base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` if test "$libtool" = yes; then tmpdepfile1=$dir$base.d tmpdepfile2=$dir.libs/$base.d "$@" -Wc,+Maked else tmpdepfile1=$dir$base.d tmpdepfile2=$dir$base.d "$@" +Maked fi stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile1" "$tmpdepfile2" exit $stat fi for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" do test -f "$tmpdepfile" && break done if test -f "$tmpdepfile"; then sed -e "s,^.*\.[a-z]*:,$object:," "$tmpdepfile" > "$depfile" # Add `dependent.h:' lines. sed -ne '2,${ s/^ *// s/ \\*$// s/$/:/ p }' "$tmpdepfile" >> "$depfile" else echo "#dummy" > "$depfile" fi rm -f "$tmpdepfile" "$tmpdepfile2" ;; tru64) # The Tru64 compiler uses -MD to generate dependencies as a side # effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'. # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put # dependencies in `foo.d' instead, so we check for that too. # Subdirectories are respected. dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` test "x$dir" = "x$object" && dir= base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` if test "$libtool" = yes; then # With Tru64 cc, shared objects can also be used to make a # static library. This mechanism is used in libtool 1.4 series to # handle both shared and static libraries in a single compilation. # With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d. # # With libtool 1.5 this exception was removed, and libtool now # generates 2 separate objects for the 2 libraries. These two # compilations output dependencies in $dir.libs/$base.o.d and # in $dir$base.o.d. We have to check for both files, because # one of the two compilations can be disabled. We should prefer # $dir$base.o.d over $dir.libs/$base.o.d because the latter is # automatically cleaned when .libs/ is deleted, while ignoring # the former would cause a distcleancheck panic. tmpdepfile1=$dir.libs/$base.lo.d # libtool 1.4 tmpdepfile2=$dir$base.o.d # libtool 1.5 tmpdepfile3=$dir.libs/$base.o.d # libtool 1.5 tmpdepfile4=$dir.libs/$base.d # Compaq CCC V6.2-504 "$@" -Wc,-MD else tmpdepfile1=$dir$base.o.d tmpdepfile2=$dir$base.d tmpdepfile3=$dir$base.d tmpdepfile4=$dir$base.d "$@" -MD fi stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" exit $stat fi for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" do test -f "$tmpdepfile" && break done if test -f "$tmpdepfile"; then sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" # That's a tab and a space in the []. sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" else echo "#dummy" > "$depfile" fi rm -f "$tmpdepfile" ;; msvc7) if test "$libtool" = yes; then showIncludes=-Wc,-showIncludes else showIncludes=-showIncludes fi "$@" $showIncludes > "$tmpdepfile" stat=$? grep -v '^Note: including file: ' "$tmpdepfile" if test "$stat" = 0; then : else rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" echo "$object : \\" > "$depfile" # The first sed program below extracts the file names and escapes # backslashes for cygpath. The second sed program outputs the file # name when reading, but also accumulates all include files in the # hold buffer in order to output them again at the end. This only # works with sed implementations that can handle large buffers. sed < "$tmpdepfile" -n ' /^Note: including file: *\(.*\)/ { s//\1/ s/\\/\\\\/g p }' | $cygpath_u | sort -u | sed -n ' s/ /\\ /g s/\(.*\)/ \1 \\/p s/.\(.*\) \\/\1:/ H $ { s/.*/ / G p }' >> "$depfile" rm -f "$tmpdepfile" ;; msvc7msys) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; #nosideeffect) # This comment above is used by automake to tell side-effect # dependency tracking mechanisms from slower ones. dashmstdout) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout, regardless of -o. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi # Remove `-o $object'. IFS=" " for arg do case $arg in -o) shift ;; $object) shift ;; *) set fnord "$@" "$arg" shift # fnord shift # $arg ;; esac done test -z "$dashmflag" && dashmflag=-M # Require at least two characters before searching for `:' # in the target name. This is to cope with DOS-style filenames: # a dependency such as `c:/foo/bar' could be seen as target `c' otherwise. "$@" $dashmflag | sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile" rm -f "$depfile" cat < "$tmpdepfile" > "$depfile" tr ' ' ' ' < "$tmpdepfile" | \ ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; dashXmstdout) # This case only exists to satisfy depend.m4. It is never actually # run, as this mode is specially recognized in the preamble. exit 1 ;; makedepend) "$@" || exit $? # Remove any Libtool call if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi # X makedepend shift cleared=no eat=no for arg do case $cleared in no) set ""; shift cleared=yes ;; esac if test $eat = yes; then eat=no continue fi case "$arg" in -D*|-I*) set fnord "$@" "$arg"; shift ;; # Strip any option that makedepend may not understand. Remove # the object too, otherwise makedepend will parse it as a source file. -arch) eat=yes ;; -*|$object) ;; *) set fnord "$@" "$arg"; shift ;; esac done obj_suffix=`echo "$object" | sed 's/^.*\././'` touch "$tmpdepfile" ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" rm -f "$depfile" # makedepend may prepend the VPATH from the source file name to the object. # No need to regex-escape $object, excess matching of '.' is harmless. sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile" sed '1,2d' "$tmpdepfile" | tr ' ' ' ' | \ ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" "$tmpdepfile".bak ;; cpp) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi # Remove `-o $object'. IFS=" " for arg do case $arg in -o) shift ;; $object) shift ;; *) set fnord "$@" "$arg" shift # fnord shift # $arg ;; esac done "$@" -E | sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' | sed '$ s: \\$::' > "$tmpdepfile" rm -f "$depfile" echo "$object : \\" > "$depfile" cat < "$tmpdepfile" >> "$depfile" sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; msvisualcpp) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi IFS=" " for arg do case "$arg" in -o) shift ;; $object) shift ;; "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") set fnord "$@" shift shift ;; *) set fnord "$@" "$arg" shift shift ;; esac done "$@" -E 2>/dev/null | sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile" rm -f "$depfile" echo "$object : \\" > "$depfile" sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile" echo " " >> "$depfile" sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile" rm -f "$tmpdepfile" ;; msvcmsys) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; none) exec "$@" ;; *) echo "Unknown depmode $depmode" 1>&2 exit 1 ;; esac exit 0 # Local Variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: dlt-daemon-2.18.4/gtest-1.7.0/build-aux/install-sh000077500000000000000000000332561353342203500213300ustar00rootroot00000000000000#!/bin/sh # install - install a program, script, or datafile scriptversion=2011-01-19.21; # UTC # This originates from X11R5 (mit/util/scripts/install.sh), which was # later released in X11R6 (xc/config/util/install.sh) with the # following copyright and license. # # Copyright (C) 1994 X Consortium # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to # deal in the Software without restriction, including without limitation the # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or # sell copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN # AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- # TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # # Except as contained in this notice, the name of the X Consortium shall not # be used in advertising or otherwise to promote the sale, use or other deal- # ings in this Software without prior written authorization from the X Consor- # tium. # # # FSF changes to this file are in the public domain. # # Calling this script install-sh is preferred over install.sh, to prevent # `make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written # from scratch. nl=' ' IFS=" "" $nl" # set DOITPROG to echo to test this script # Don't use :- since 4.3BSD and earlier shells don't like it. doit=${DOITPROG-} if test -z "$doit"; then doit_exec=exec else doit_exec=$doit fi # Put in absolute file names if you don't have them in your path; # or use environment vars. chgrpprog=${CHGRPPROG-chgrp} chmodprog=${CHMODPROG-chmod} chownprog=${CHOWNPROG-chown} cmpprog=${CMPPROG-cmp} cpprog=${CPPROG-cp} mkdirprog=${MKDIRPROG-mkdir} mvprog=${MVPROG-mv} rmprog=${RMPROG-rm} stripprog=${STRIPPROG-strip} posix_glob='?' initialize_posix_glob=' test "$posix_glob" != "?" || { if (set -f) 2>/dev/null; then posix_glob= else posix_glob=: fi } ' posix_mkdir= # Desired mode of installed file. mode=0755 chgrpcmd= chmodcmd=$chmodprog chowncmd= mvcmd=$mvprog rmcmd="$rmprog -f" stripcmd= src= dst= dir_arg= dst_arg= copy_on_change=false no_target_directory= usage="\ Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE or: $0 [OPTION]... SRCFILES... DIRECTORY or: $0 [OPTION]... -t DIRECTORY SRCFILES... or: $0 [OPTION]... -d DIRECTORIES... In the 1st form, copy SRCFILE to DSTFILE. In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. In the 4th, create DIRECTORIES. Options: --help display this help and exit. --version display version info and exit. -c (ignored) -C install only if different (preserve the last data modification time) -d create directories instead of installing files. -g GROUP $chgrpprog installed files to GROUP. -m MODE $chmodprog installed files to MODE. -o USER $chownprog installed files to USER. -s $stripprog installed files. -t DIRECTORY install into DIRECTORY. -T report an error if DSTFILE is a directory. Environment variables override the default commands: CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG " while test $# -ne 0; do case $1 in -c) ;; -C) copy_on_change=true;; -d) dir_arg=true;; -g) chgrpcmd="$chgrpprog $2" shift;; --help) echo "$usage"; exit $?;; -m) mode=$2 case $mode in *' '* | *' '* | *' '* | *'*'* | *'?'* | *'['*) echo "$0: invalid mode: $mode" >&2 exit 1;; esac shift;; -o) chowncmd="$chownprog $2" shift;; -s) stripcmd=$stripprog;; -t) dst_arg=$2 # Protect names problematic for `test' and other utilities. case $dst_arg in -* | [=\(\)!]) dst_arg=./$dst_arg;; esac shift;; -T) no_target_directory=true;; --version) echo "$0 $scriptversion"; exit $?;; --) shift break;; -*) echo "$0: invalid option: $1" >&2 exit 1;; *) break;; esac shift done if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then # When -d is used, all remaining arguments are directories to create. # When -t is used, the destination is already specified. # Otherwise, the last argument is the destination. Remove it from $@. for arg do if test -n "$dst_arg"; then # $@ is not empty: it contains at least $arg. set fnord "$@" "$dst_arg" shift # fnord fi shift # arg dst_arg=$arg # Protect names problematic for `test' and other utilities. case $dst_arg in -* | [=\(\)!]) dst_arg=./$dst_arg;; esac done fi if test $# -eq 0; then if test -z "$dir_arg"; then echo "$0: no input file specified." >&2 exit 1 fi # It's OK to call `install-sh -d' without argument. # This can happen when creating conditional directories. exit 0 fi if test -z "$dir_arg"; then do_exit='(exit $ret); exit $ret' trap "ret=129; $do_exit" 1 trap "ret=130; $do_exit" 2 trap "ret=141; $do_exit" 13 trap "ret=143; $do_exit" 15 # Set umask so as not to create temps with too-generous modes. # However, 'strip' requires both read and write access to temps. case $mode in # Optimize common cases. *644) cp_umask=133;; *755) cp_umask=22;; *[0-7]) if test -z "$stripcmd"; then u_plus_rw= else u_plus_rw='% 200' fi cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; *) if test -z "$stripcmd"; then u_plus_rw= else u_plus_rw=,u+rw fi cp_umask=$mode$u_plus_rw;; esac fi for src do # Protect names problematic for `test' and other utilities. case $src in -* | [=\(\)!]) src=./$src;; esac if test -n "$dir_arg"; then dst=$src dstdir=$dst test -d "$dstdir" dstdir_status=$? else # Waiting for this to be detected by the "$cpprog $src $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if test ! -f "$src" && test ! -d "$src"; then echo "$0: $src does not exist." >&2 exit 1 fi if test -z "$dst_arg"; then echo "$0: no destination specified." >&2 exit 1 fi dst=$dst_arg # If destination is a directory, append the input filename; won't work # if double slashes aren't ignored. if test -d "$dst"; then if test -n "$no_target_directory"; then echo "$0: $dst_arg: Is a directory" >&2 exit 1 fi dstdir=$dst dst=$dstdir/`basename "$src"` dstdir_status=0 else # Prefer dirname, but fall back on a substitute if dirname fails. dstdir=` (dirname "$dst") 2>/dev/null || expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$dst" : 'X\(//\)[^/]' \| \ X"$dst" : 'X\(//\)$' \| \ X"$dst" : 'X\(/\)' \| . 2>/dev/null || echo X"$dst" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q' ` test -d "$dstdir" dstdir_status=$? fi fi obsolete_mkdir_used=false if test $dstdir_status != 0; then case $posix_mkdir in '') # Create intermediate dirs using mode 755 as modified by the umask. # This is like FreeBSD 'install' as of 1997-10-28. umask=`umask` case $stripcmd.$umask in # Optimize common cases. *[2367][2367]) mkdir_umask=$umask;; .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; *[0-7]) mkdir_umask=`expr $umask + 22 \ - $umask % 100 % 40 + $umask % 20 \ - $umask % 10 % 4 + $umask % 2 `;; *) mkdir_umask=$umask,go-w;; esac # With -d, create the new directory with the user-specified mode. # Otherwise, rely on $mkdir_umask. if test -n "$dir_arg"; then mkdir_mode=-m$mode else mkdir_mode= fi posix_mkdir=false case $umask in *[123567][0-7][0-7]) # POSIX mkdir -p sets u+wx bits regardless of umask, which # is incompatible with FreeBSD 'install' when (umask & 300) != 0. ;; *) tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 if (umask $mkdir_umask && exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 then if test -z "$dir_arg" || { # Check for POSIX incompatibilities with -m. # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or # other-writeable bit of parent directory when it shouldn't. # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. ls_ld_tmpdir=`ls -ld "$tmpdir"` case $ls_ld_tmpdir in d????-?r-*) different_mode=700;; d????-?--*) different_mode=755;; *) false;; esac && $mkdirprog -m$different_mode -p -- "$tmpdir" && { ls_ld_tmpdir_1=`ls -ld "$tmpdir"` test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" } } then posix_mkdir=: fi rmdir "$tmpdir/d" "$tmpdir" else # Remove any dirs left behind by ancient mkdir implementations. rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null fi trap '' 0;; esac;; esac if $posix_mkdir && ( umask $mkdir_umask && $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" ) then : else # The umask is ridiculous, or mkdir does not conform to POSIX, # or it failed possibly due to a race condition. Create the # directory the slow way, step by step, checking for races as we go. case $dstdir in /*) prefix='/';; [-=\(\)!]*) prefix='./';; *) prefix='';; esac eval "$initialize_posix_glob" oIFS=$IFS IFS=/ $posix_glob set -f set fnord $dstdir shift $posix_glob set +f IFS=$oIFS prefixes= for d do test X"$d" = X && continue prefix=$prefix$d if test -d "$prefix"; then prefixes= else if $posix_mkdir; then (umask=$mkdir_umask && $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break # Don't fail if two instances are running concurrently. test -d "$prefix" || exit 1 else case $prefix in *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; *) qprefix=$prefix;; esac prefixes="$prefixes '$qprefix'" fi fi prefix=$prefix/ done if test -n "$prefixes"; then # Don't fail if two instances are running concurrently. (umask $mkdir_umask && eval "\$doit_exec \$mkdirprog $prefixes") || test -d "$dstdir" || exit 1 obsolete_mkdir_used=true fi fi fi if test -n "$dir_arg"; then { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 else # Make a couple of temp file names in the proper directory. dsttmp=$dstdir/_inst.$$_ rmtmp=$dstdir/_rm.$$_ # Trap to clean up those temp files at exit. trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 # Copy the file name to the temp name. (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && # and set any options; do chmod last to preserve setuid bits. # # If any of these fail, we abort the whole thing. If we want to # ignore errors from any of these, just make sure not to ignore # errors from the above "$doit $cpprog $src $dsttmp" command. # { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && # If -C, don't bother to copy if it wouldn't change the file. if $copy_on_change && old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && eval "$initialize_posix_glob" && $posix_glob set -f && set X $old && old=:$2:$4:$5:$6 && set X $new && new=:$2:$4:$5:$6 && $posix_glob set +f && test "$old" = "$new" && $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 then rm -f "$dsttmp" else # Rename the file to the real destination. $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || # The rename failed, perhaps because mv can't rename something else # to itself, or perhaps because mv is so ancient that it does not # support -f. { # Now remove or move aside any old file at destination location. # We try this two ways since rm can't unlink itself on some # systems and the destination file might be busy for other # reasons. In this case, the final cleanup might fail but the new # file should still install successfully. { test ! -f "$dst" || $doit $rmcmd -f "$dst" 2>/dev/null || { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } } || { echo "$0: cannot unlink or rename $dst" >&2 (exit 1); exit 1 } } && # Now rename the file to the real destination. $doit $mvcmd "$dsttmp" "$dst" } fi || exit 1 trap '' 0 fi done # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: dlt-daemon-2.18.4/gtest-1.7.0/build-aux/ltmain.sh000066400000000000000000010520401353342203500211350ustar00rootroot00000000000000 # libtool (GNU libtool) 2.4.2 # Written by Gordon Matzigkeit , 1996 # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006, # 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. # This is free software; see the source for copying conditions. There is NO # warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # GNU Libtool is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # As a special exception to the GNU General Public License, # if you distribute this file as part of a program or library that # is built using GNU Libtool, you may include this file under the # same distribution terms that you use for the rest of that program. # # GNU Libtool is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with GNU Libtool; see the file COPYING. If not, a copy # can be downloaded from http://www.gnu.org/licenses/gpl.html, # or obtained by writing to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # Usage: $progname [OPTION]... [MODE-ARG]... # # Provide generalized library-building support services. # # --config show all configuration variables # --debug enable verbose shell tracing # -n, --dry-run display commands without modifying any files # --features display basic configuration information and exit # --mode=MODE use operation mode MODE # --preserve-dup-deps don't remove duplicate dependency libraries # --quiet, --silent don't print informational messages # --no-quiet, --no-silent # print informational messages (default) # --no-warn don't display warning messages # --tag=TAG use configuration variables from tag TAG # -v, --verbose print more informational messages than default # --no-verbose don't print the extra informational messages # --version print version information # -h, --help, --help-all print short, long, or detailed help message # # MODE must be one of the following: # # clean remove files from the build directory # compile compile a source file into a libtool object # execute automatically set library path, then run a program # finish complete the installation of libtool libraries # install install libraries or executables # link create a library or an executable # uninstall remove libraries from an installed directory # # MODE-ARGS vary depending on the MODE. When passed as first option, # `--mode=MODE' may be abbreviated as `MODE' or a unique abbreviation of that. # Try `$progname --help --mode=MODE' for a more detailed description of MODE. # # When reporting a bug, please describe a test case to reproduce it and # include the following information: # # host-triplet: $host # shell: $SHELL # compiler: $LTCC # compiler flags: $LTCFLAGS # linker: $LD (gnu? $with_gnu_ld) # $progname: (GNU libtool) 2.4.2 Debian-2.4.2-1ubuntu1 # automake: $automake_version # autoconf: $autoconf_version # # Report bugs to . # GNU libtool home page: . # General help using GNU software: . PROGRAM=libtool PACKAGE=libtool VERSION="2.4.2 Debian-2.4.2-1ubuntu1" TIMESTAMP="" package_revision=1.3337 # Be Bourne compatible if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac fi BIN_SH=xpg4; export BIN_SH # for Tru64 DUALCASE=1; export DUALCASE # for MKS sh # A function that is used when there is no print builtin or printf. func_fallback_echo () { eval 'cat <<_LTECHO_EOF $1 _LTECHO_EOF' } # NLS nuisances: We save the old values to restore during execute mode. lt_user_locale= lt_safe_locale= for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES do eval "if test \"\${$lt_var+set}\" = set; then save_$lt_var=\$$lt_var $lt_var=C export $lt_var lt_user_locale=\"$lt_var=\\\$save_\$lt_var; \$lt_user_locale\" lt_safe_locale=\"$lt_var=C; \$lt_safe_locale\" fi" done LC_ALL=C LANGUAGE=C export LANGUAGE LC_ALL $lt_unset CDPATH # Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh # is ksh but when the shell is invoked as "sh" and the current value of # the _XPG environment variable is not equal to 1 (one), the special # positional parameter $0, within a function call, is the name of the # function. progpath="$0" : ${CP="cp -f"} test "${ECHO+set}" = set || ECHO=${as_echo-'printf %s\n'} : ${MAKE="make"} : ${MKDIR="mkdir"} : ${MV="mv -f"} : ${RM="rm -f"} : ${SHELL="${CONFIG_SHELL-/bin/sh}"} : ${Xsed="$SED -e 1s/^X//"} # Global variables: EXIT_SUCCESS=0 EXIT_FAILURE=1 EXIT_MISMATCH=63 # $? = 63 is used to indicate version mismatch to missing. EXIT_SKIP=77 # $? = 77 is used to indicate a skipped test to automake. exit_status=$EXIT_SUCCESS # Make sure IFS has a sensible default lt_nl=' ' IFS=" $lt_nl" dirname="s,/[^/]*$,," basename="s,^.*/,," # func_dirname file append nondir_replacement # Compute the dirname of FILE. If nonempty, add APPEND to the result, # otherwise set result to NONDIR_REPLACEMENT. func_dirname () { func_dirname_result=`$ECHO "${1}" | $SED "$dirname"` if test "X$func_dirname_result" = "X${1}"; then func_dirname_result="${3}" else func_dirname_result="$func_dirname_result${2}" fi } # func_dirname may be replaced by extended shell implementation # func_basename file func_basename () { func_basename_result=`$ECHO "${1}" | $SED "$basename"` } # func_basename may be replaced by extended shell implementation # func_dirname_and_basename file append nondir_replacement # perform func_basename and func_dirname in a single function # call: # dirname: Compute the dirname of FILE. If nonempty, # add APPEND to the result, otherwise set result # to NONDIR_REPLACEMENT. # value returned in "$func_dirname_result" # basename: Compute filename of FILE. # value retuned in "$func_basename_result" # Implementation must be kept synchronized with func_dirname # and func_basename. For efficiency, we do not delegate to # those functions but instead duplicate the functionality here. func_dirname_and_basename () { # Extract subdirectory from the argument. func_dirname_result=`$ECHO "${1}" | $SED -e "$dirname"` if test "X$func_dirname_result" = "X${1}"; then func_dirname_result="${3}" else func_dirname_result="$func_dirname_result${2}" fi func_basename_result=`$ECHO "${1}" | $SED -e "$basename"` } # func_dirname_and_basename may be replaced by extended shell implementation # func_stripname prefix suffix name # strip PREFIX and SUFFIX off of NAME. # PREFIX and SUFFIX must not contain globbing or regex special # characters, hashes, percent signs, but SUFFIX may contain a leading # dot (in which case that matches only a dot). # func_strip_suffix prefix name func_stripname () { case ${2} in .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;; *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;; esac } # func_stripname may be replaced by extended shell implementation # These SED scripts presuppose an absolute path with a trailing slash. pathcar='s,^/\([^/]*\).*$,\1,' pathcdr='s,^/[^/]*,,' removedotparts=':dotsl s@/\./@/@g t dotsl s,/\.$,/,' collapseslashes='s@/\{1,\}@/@g' finalslash='s,/*$,/,' # func_normal_abspath PATH # Remove doubled-up and trailing slashes, "." path components, # and cancel out any ".." path components in PATH after making # it an absolute path. # value returned in "$func_normal_abspath_result" func_normal_abspath () { # Start from root dir and reassemble the path. func_normal_abspath_result= func_normal_abspath_tpath=$1 func_normal_abspath_altnamespace= case $func_normal_abspath_tpath in "") # Empty path, that just means $cwd. func_stripname '' '/' "`pwd`" func_normal_abspath_result=$func_stripname_result return ;; # The next three entries are used to spot a run of precisely # two leading slashes without using negated character classes; # we take advantage of case's first-match behaviour. ///*) # Unusual form of absolute path, do nothing. ;; //*) # Not necessarily an ordinary path; POSIX reserves leading '//' # and for example Cygwin uses it to access remote file shares # over CIFS/SMB, so we conserve a leading double slash if found. func_normal_abspath_altnamespace=/ ;; /*) # Absolute path, do nothing. ;; *) # Relative path, prepend $cwd. func_normal_abspath_tpath=`pwd`/$func_normal_abspath_tpath ;; esac # Cancel out all the simple stuff to save iterations. We also want # the path to end with a slash for ease of parsing, so make sure # there is one (and only one) here. func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ -e "$removedotparts" -e "$collapseslashes" -e "$finalslash"` while :; do # Processed it all yet? if test "$func_normal_abspath_tpath" = / ; then # If we ascended to the root using ".." the result may be empty now. if test -z "$func_normal_abspath_result" ; then func_normal_abspath_result=/ fi break fi func_normal_abspath_tcomponent=`$ECHO "$func_normal_abspath_tpath" | $SED \ -e "$pathcar"` func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ -e "$pathcdr"` # Figure out what to do with it case $func_normal_abspath_tcomponent in "") # Trailing empty path component, ignore it. ;; ..) # Parent dir; strip last assembled component from result. func_dirname "$func_normal_abspath_result" func_normal_abspath_result=$func_dirname_result ;; *) # Actual path component, append it. func_normal_abspath_result=$func_normal_abspath_result/$func_normal_abspath_tcomponent ;; esac done # Restore leading double-slash if one was found on entry. func_normal_abspath_result=$func_normal_abspath_altnamespace$func_normal_abspath_result } # func_relative_path SRCDIR DSTDIR # generates a relative path from SRCDIR to DSTDIR, with a trailing # slash if non-empty, suitable for immediately appending a filename # without needing to append a separator. # value returned in "$func_relative_path_result" func_relative_path () { func_relative_path_result= func_normal_abspath "$1" func_relative_path_tlibdir=$func_normal_abspath_result func_normal_abspath "$2" func_relative_path_tbindir=$func_normal_abspath_result # Ascend the tree starting from libdir while :; do # check if we have found a prefix of bindir case $func_relative_path_tbindir in $func_relative_path_tlibdir) # found an exact match func_relative_path_tcancelled= break ;; $func_relative_path_tlibdir*) # found a matching prefix func_stripname "$func_relative_path_tlibdir" '' "$func_relative_path_tbindir" func_relative_path_tcancelled=$func_stripname_result if test -z "$func_relative_path_result"; then func_relative_path_result=. fi break ;; *) func_dirname $func_relative_path_tlibdir func_relative_path_tlibdir=${func_dirname_result} if test "x$func_relative_path_tlibdir" = x ; then # Have to descend all the way to the root! func_relative_path_result=../$func_relative_path_result func_relative_path_tcancelled=$func_relative_path_tbindir break fi func_relative_path_result=../$func_relative_path_result ;; esac done # Now calculate path; take care to avoid doubling-up slashes. func_stripname '' '/' "$func_relative_path_result" func_relative_path_result=$func_stripname_result func_stripname '/' '/' "$func_relative_path_tcancelled" if test "x$func_stripname_result" != x ; then func_relative_path_result=${func_relative_path_result}/${func_stripname_result} fi # Normalisation. If bindir is libdir, return empty string, # else relative path ending with a slash; either way, target # file name can be directly appended. if test ! -z "$func_relative_path_result"; then func_stripname './' '' "$func_relative_path_result/" func_relative_path_result=$func_stripname_result fi } # The name of this program: func_dirname_and_basename "$progpath" progname=$func_basename_result # Make sure we have an absolute path for reexecution: case $progpath in [\\/]*|[A-Za-z]:\\*) ;; *[\\/]*) progdir=$func_dirname_result progdir=`cd "$progdir" && pwd` progpath="$progdir/$progname" ;; *) save_IFS="$IFS" IFS=${PATH_SEPARATOR-:} for progdir in $PATH; do IFS="$save_IFS" test -x "$progdir/$progname" && break done IFS="$save_IFS" test -n "$progdir" || progdir=`pwd` progpath="$progdir/$progname" ;; esac # Sed substitution that helps us do robust quoting. It backslashifies # metacharacters that are still active within double-quoted strings. Xsed="${SED}"' -e 1s/^X//' sed_quote_subst='s/\([`"$\\]\)/\\\1/g' # Same as above, but do not quote variable references. double_quote_subst='s/\(["`\\]\)/\\\1/g' # Sed substitution that turns a string into a regex matching for the # string literally. sed_make_literal_regex='s,[].[^$\\*\/],\\&,g' # Sed substitution that converts a w32 file name or path # which contains forward slashes, into one that contains # (escaped) backslashes. A very naive implementation. lt_sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g' # Re-`\' parameter expansions in output of double_quote_subst that were # `\'-ed in input to the same. If an odd number of `\' preceded a '$' # in input to double_quote_subst, that '$' was protected from expansion. # Since each input `\' is now two `\'s, look for any number of runs of # four `\'s followed by two `\'s and then a '$'. `\' that '$'. bs='\\' bs2='\\\\' bs4='\\\\\\\\' dollar='\$' sed_double_backslash="\ s/$bs4/&\\ /g s/^$bs2$dollar/$bs&/ s/\\([^$bs]\\)$bs2$dollar/\\1$bs2$bs$dollar/g s/\n//g" # Standard options: opt_dry_run=false opt_help=false opt_quiet=false opt_verbose=false opt_warning=: # func_echo arg... # Echo program name prefixed message, along with the current mode # name if it has been set yet. func_echo () { $ECHO "$progname: ${opt_mode+$opt_mode: }$*" } # func_verbose arg... # Echo program name prefixed message in verbose mode only. func_verbose () { $opt_verbose && func_echo ${1+"$@"} # A bug in bash halts the script if the last line of a function # fails when set -e is in force, so we need another command to # work around that: : } # func_echo_all arg... # Invoke $ECHO with all args, space-separated. func_echo_all () { $ECHO "$*" } # func_error arg... # Echo program name prefixed message to standard error. func_error () { $ECHO "$progname: ${opt_mode+$opt_mode: }"${1+"$@"} 1>&2 } # func_warning arg... # Echo program name prefixed warning message to standard error. func_warning () { $opt_warning && $ECHO "$progname: ${opt_mode+$opt_mode: }warning: "${1+"$@"} 1>&2 # bash bug again: : } # func_fatal_error arg... # Echo program name prefixed message to standard error, and exit. func_fatal_error () { func_error ${1+"$@"} exit $EXIT_FAILURE } # func_fatal_help arg... # Echo program name prefixed message to standard error, followed by # a help hint, and exit. func_fatal_help () { func_error ${1+"$@"} func_fatal_error "$help" } help="Try \`$progname --help' for more information." ## default # func_grep expression filename # Check whether EXPRESSION matches any line of FILENAME, without output. func_grep () { $GREP "$1" "$2" >/dev/null 2>&1 } # func_mkdir_p directory-path # Make sure the entire path to DIRECTORY-PATH is available. func_mkdir_p () { my_directory_path="$1" my_dir_list= if test -n "$my_directory_path" && test "$opt_dry_run" != ":"; then # Protect directory names starting with `-' case $my_directory_path in -*) my_directory_path="./$my_directory_path" ;; esac # While some portion of DIR does not yet exist... while test ! -d "$my_directory_path"; do # ...make a list in topmost first order. Use a colon delimited # list incase some portion of path contains whitespace. my_dir_list="$my_directory_path:$my_dir_list" # If the last portion added has no slash in it, the list is done case $my_directory_path in */*) ;; *) break ;; esac # ...otherwise throw away the child directory and loop my_directory_path=`$ECHO "$my_directory_path" | $SED -e "$dirname"` done my_dir_list=`$ECHO "$my_dir_list" | $SED 's,:*$,,'` save_mkdir_p_IFS="$IFS"; IFS=':' for my_dir in $my_dir_list; do IFS="$save_mkdir_p_IFS" # mkdir can fail with a `File exist' error if two processes # try to create one of the directories concurrently. Don't # stop in that case! $MKDIR "$my_dir" 2>/dev/null || : done IFS="$save_mkdir_p_IFS" # Bail out if we (or some other process) failed to create a directory. test -d "$my_directory_path" || \ func_fatal_error "Failed to create \`$1'" fi } # func_mktempdir [string] # Make a temporary directory that won't clash with other running # libtool processes, and avoids race conditions if possible. If # given, STRING is the basename for that directory. func_mktempdir () { my_template="${TMPDIR-/tmp}/${1-$progname}" if test "$opt_dry_run" = ":"; then # Return a directory name, but don't create it in dry-run mode my_tmpdir="${my_template}-$$" else # If mktemp works, use that first and foremost my_tmpdir=`mktemp -d "${my_template}-XXXXXXXX" 2>/dev/null` if test ! -d "$my_tmpdir"; then # Failing that, at least try and use $RANDOM to avoid a race my_tmpdir="${my_template}-${RANDOM-0}$$" save_mktempdir_umask=`umask` umask 0077 $MKDIR "$my_tmpdir" umask $save_mktempdir_umask fi # If we're not in dry-run mode, bomb out on failure test -d "$my_tmpdir" || \ func_fatal_error "cannot create temporary directory \`$my_tmpdir'" fi $ECHO "$my_tmpdir" } # func_quote_for_eval arg # Aesthetically quote ARG to be evaled later. # This function returns two values: FUNC_QUOTE_FOR_EVAL_RESULT # is double-quoted, suitable for a subsequent eval, whereas # FUNC_QUOTE_FOR_EVAL_UNQUOTED_RESULT has merely all characters # which are still active within double quotes backslashified. func_quote_for_eval () { case $1 in *[\\\`\"\$]*) func_quote_for_eval_unquoted_result=`$ECHO "$1" | $SED "$sed_quote_subst"` ;; *) func_quote_for_eval_unquoted_result="$1" ;; esac case $func_quote_for_eval_unquoted_result in # Double-quote args containing shell metacharacters to delay # word splitting, command substitution and and variable # expansion for a subsequent eval. # Many Bourne shells cannot handle close brackets correctly # in scan sets, so we specify it separately. *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") func_quote_for_eval_result="\"$func_quote_for_eval_unquoted_result\"" ;; *) func_quote_for_eval_result="$func_quote_for_eval_unquoted_result" esac } # func_quote_for_expand arg # Aesthetically quote ARG to be evaled later; same as above, # but do not quote variable references. func_quote_for_expand () { case $1 in *[\\\`\"]*) my_arg=`$ECHO "$1" | $SED \ -e "$double_quote_subst" -e "$sed_double_backslash"` ;; *) my_arg="$1" ;; esac case $my_arg in # Double-quote args containing shell metacharacters to delay # word splitting and command substitution for a subsequent eval. # Many Bourne shells cannot handle close brackets correctly # in scan sets, so we specify it separately. *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") my_arg="\"$my_arg\"" ;; esac func_quote_for_expand_result="$my_arg" } # func_show_eval cmd [fail_exp] # Unless opt_silent is true, then output CMD. Then, if opt_dryrun is # not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP # is given, then evaluate it. func_show_eval () { my_cmd="$1" my_fail_exp="${2-:}" ${opt_silent-false} || { func_quote_for_expand "$my_cmd" eval "func_echo $func_quote_for_expand_result" } if ${opt_dry_run-false}; then :; else eval "$my_cmd" my_status=$? if test "$my_status" -eq 0; then :; else eval "(exit $my_status); $my_fail_exp" fi fi } # func_show_eval_locale cmd [fail_exp] # Unless opt_silent is true, then output CMD. Then, if opt_dryrun is # not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP # is given, then evaluate it. Use the saved locale for evaluation. func_show_eval_locale () { my_cmd="$1" my_fail_exp="${2-:}" ${opt_silent-false} || { func_quote_for_expand "$my_cmd" eval "func_echo $func_quote_for_expand_result" } if ${opt_dry_run-false}; then :; else eval "$lt_user_locale $my_cmd" my_status=$? eval "$lt_safe_locale" if test "$my_status" -eq 0; then :; else eval "(exit $my_status); $my_fail_exp" fi fi } # func_tr_sh # Turn $1 into a string suitable for a shell variable name. # Result is stored in $func_tr_sh_result. All characters # not in the set a-zA-Z0-9_ are replaced with '_'. Further, # if $1 begins with a digit, a '_' is prepended as well. func_tr_sh () { case $1 in [0-9]* | *[!a-zA-Z0-9_]*) func_tr_sh_result=`$ECHO "$1" | $SED 's/^\([0-9]\)/_\1/; s/[^a-zA-Z0-9_]/_/g'` ;; * ) func_tr_sh_result=$1 ;; esac } # func_version # Echo version message to standard output and exit. func_version () { $opt_debug $SED -n '/(C)/!b go :more /\./!{ N s/\n# / / b more } :go /^# '$PROGRAM' (GNU /,/# warranty; / { s/^# // s/^# *$// s/\((C)\)[ 0-9,-]*\( [1-9][0-9]*\)/\1\2/ p }' < "$progpath" exit $? } # func_usage # Echo short help message to standard output and exit. func_usage () { $opt_debug $SED -n '/^# Usage:/,/^# *.*--help/ { s/^# // s/^# *$// s/\$progname/'$progname'/ p }' < "$progpath" echo $ECHO "run \`$progname --help | more' for full usage" exit $? } # func_help [NOEXIT] # Echo long help message to standard output and exit, # unless 'noexit' is passed as argument. func_help () { $opt_debug $SED -n '/^# Usage:/,/# Report bugs to/ { :print s/^# // s/^# *$// s*\$progname*'$progname'* s*\$host*'"$host"'* s*\$SHELL*'"$SHELL"'* s*\$LTCC*'"$LTCC"'* s*\$LTCFLAGS*'"$LTCFLAGS"'* s*\$LD*'"$LD"'* s/\$with_gnu_ld/'"$with_gnu_ld"'/ s/\$automake_version/'"`(${AUTOMAKE-automake} --version) 2>/dev/null |$SED 1q`"'/ s/\$autoconf_version/'"`(${AUTOCONF-autoconf} --version) 2>/dev/null |$SED 1q`"'/ p d } /^# .* home page:/b print /^# General help using/b print ' < "$progpath" ret=$? if test -z "$1"; then exit $ret fi } # func_missing_arg argname # Echo program name prefixed message to standard error and set global # exit_cmd. func_missing_arg () { $opt_debug func_error "missing argument for $1." exit_cmd=exit } # func_split_short_opt shortopt # Set func_split_short_opt_name and func_split_short_opt_arg shell # variables after splitting SHORTOPT after the 2nd character. func_split_short_opt () { my_sed_short_opt='1s/^\(..\).*$/\1/;q' my_sed_short_rest='1s/^..\(.*\)$/\1/;q' func_split_short_opt_name=`$ECHO "$1" | $SED "$my_sed_short_opt"` func_split_short_opt_arg=`$ECHO "$1" | $SED "$my_sed_short_rest"` } # func_split_short_opt may be replaced by extended shell implementation # func_split_long_opt longopt # Set func_split_long_opt_name and func_split_long_opt_arg shell # variables after splitting LONGOPT at the `=' sign. func_split_long_opt () { my_sed_long_opt='1s/^\(--[^=]*\)=.*/\1/;q' my_sed_long_arg='1s/^--[^=]*=//' func_split_long_opt_name=`$ECHO "$1" | $SED "$my_sed_long_opt"` func_split_long_opt_arg=`$ECHO "$1" | $SED "$my_sed_long_arg"` } # func_split_long_opt may be replaced by extended shell implementation exit_cmd=: magic="%%%MAGIC variable%%%" magic_exe="%%%MAGIC EXE variable%%%" # Global variables. nonopt= preserve_args= lo2o="s/\\.lo\$/.${objext}/" o2lo="s/\\.${objext}\$/.lo/" extracted_archives= extracted_serial=0 # If this variable is set in any of the actions, the command in it # will be execed at the end. This prevents here-documents from being # left over by shells. exec_cmd= # func_append var value # Append VALUE to the end of shell variable VAR. func_append () { eval "${1}=\$${1}\${2}" } # func_append may be replaced by extended shell implementation # func_append_quoted var value # Quote VALUE and append to the end of shell variable VAR, separated # by a space. func_append_quoted () { func_quote_for_eval "${2}" eval "${1}=\$${1}\\ \$func_quote_for_eval_result" } # func_append_quoted may be replaced by extended shell implementation # func_arith arithmetic-term... func_arith () { func_arith_result=`expr "${@}"` } # func_arith may be replaced by extended shell implementation # func_len string # STRING may not start with a hyphen. func_len () { func_len_result=`expr "${1}" : ".*" 2>/dev/null || echo $max_cmd_len` } # func_len may be replaced by extended shell implementation # func_lo2o object func_lo2o () { func_lo2o_result=`$ECHO "${1}" | $SED "$lo2o"` } # func_lo2o may be replaced by extended shell implementation # func_xform libobj-or-source func_xform () { func_xform_result=`$ECHO "${1}" | $SED 's/\.[^.]*$/.lo/'` } # func_xform may be replaced by extended shell implementation # func_fatal_configuration arg... # Echo program name prefixed message to standard error, followed by # a configuration failure hint, and exit. func_fatal_configuration () { func_error ${1+"$@"} func_error "See the $PACKAGE documentation for more information." func_fatal_error "Fatal configuration error." } # func_config # Display the configuration for all the tags in this script. func_config () { re_begincf='^# ### BEGIN LIBTOOL' re_endcf='^# ### END LIBTOOL' # Default configuration. $SED "1,/$re_begincf CONFIG/d;/$re_endcf CONFIG/,\$d" < "$progpath" # Now print the configurations for the tags. for tagname in $taglist; do $SED -n "/$re_begincf TAG CONFIG: $tagname\$/,/$re_endcf TAG CONFIG: $tagname\$/p" < "$progpath" done exit $? } # func_features # Display the features supported by this script. func_features () { echo "host: $host" if test "$build_libtool_libs" = yes; then echo "enable shared libraries" else echo "disable shared libraries" fi if test "$build_old_libs" = yes; then echo "enable static libraries" else echo "disable static libraries" fi exit $? } # func_enable_tag tagname # Verify that TAGNAME is valid, and either flag an error and exit, or # enable the TAGNAME tag. We also add TAGNAME to the global $taglist # variable here. func_enable_tag () { # Global variable: tagname="$1" re_begincf="^# ### BEGIN LIBTOOL TAG CONFIG: $tagname\$" re_endcf="^# ### END LIBTOOL TAG CONFIG: $tagname\$" sed_extractcf="/$re_begincf/,/$re_endcf/p" # Validate tagname. case $tagname in *[!-_A-Za-z0-9,/]*) func_fatal_error "invalid tag name: $tagname" ;; esac # Don't test for the "default" C tag, as we know it's # there but not specially marked. case $tagname in CC) ;; *) if $GREP "$re_begincf" "$progpath" >/dev/null 2>&1; then taglist="$taglist $tagname" # Evaluate the configuration. Be careful to quote the path # and the sed script, to avoid splitting on whitespace, but # also don't use non-portable quotes within backquotes within # quotes we have to do it in 2 steps: extractedcf=`$SED -n -e "$sed_extractcf" < "$progpath"` eval "$extractedcf" else func_error "ignoring unknown tag $tagname" fi ;; esac } # func_check_version_match # Ensure that we are using m4 macros, and libtool script from the same # release of libtool. func_check_version_match () { if test "$package_revision" != "$macro_revision"; then if test "$VERSION" != "$macro_version"; then if test -z "$macro_version"; then cat >&2 <<_LT_EOF $progname: Version mismatch error. This is $PACKAGE $VERSION, but the $progname: definition of this LT_INIT comes from an older release. $progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION $progname: and run autoconf again. _LT_EOF else cat >&2 <<_LT_EOF $progname: Version mismatch error. This is $PACKAGE $VERSION, but the $progname: definition of this LT_INIT comes from $PACKAGE $macro_version. $progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION $progname: and run autoconf again. _LT_EOF fi else cat >&2 <<_LT_EOF $progname: Version mismatch error. This is $PACKAGE $VERSION, revision $package_revision, $progname: but the definition of this LT_INIT comes from revision $macro_revision. $progname: You should recreate aclocal.m4 with macros from revision $package_revision $progname: of $PACKAGE $VERSION and run autoconf again. _LT_EOF fi exit $EXIT_MISMATCH fi } # Shorthand for --mode=foo, only valid as the first argument case $1 in clean|clea|cle|cl) shift; set dummy --mode clean ${1+"$@"}; shift ;; compile|compil|compi|comp|com|co|c) shift; set dummy --mode compile ${1+"$@"}; shift ;; execute|execut|execu|exec|exe|ex|e) shift; set dummy --mode execute ${1+"$@"}; shift ;; finish|finis|fini|fin|fi|f) shift; set dummy --mode finish ${1+"$@"}; shift ;; install|instal|insta|inst|ins|in|i) shift; set dummy --mode install ${1+"$@"}; shift ;; link|lin|li|l) shift; set dummy --mode link ${1+"$@"}; shift ;; uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u) shift; set dummy --mode uninstall ${1+"$@"}; shift ;; esac # Option defaults: opt_debug=: opt_dry_run=false opt_config=false opt_preserve_dup_deps=false opt_features=false opt_finish=false opt_help=false opt_help_all=false opt_silent=: opt_warning=: opt_verbose=: opt_silent=false opt_verbose=false # Parse options once, thoroughly. This comes as soon as possible in the # script to make things like `--version' happen as quickly as we can. { # this just eases exit handling while test $# -gt 0; do opt="$1" shift case $opt in --debug|-x) opt_debug='set -x' func_echo "enabling shell trace mode" $opt_debug ;; --dry-run|--dryrun|-n) opt_dry_run=: ;; --config) opt_config=: func_config ;; --dlopen|-dlopen) optarg="$1" opt_dlopen="${opt_dlopen+$opt_dlopen }$optarg" shift ;; --preserve-dup-deps) opt_preserve_dup_deps=: ;; --features) opt_features=: func_features ;; --finish) opt_finish=: set dummy --mode finish ${1+"$@"}; shift ;; --help) opt_help=: ;; --help-all) opt_help_all=: opt_help=': help-all' ;; --mode) test $# = 0 && func_missing_arg $opt && break optarg="$1" opt_mode="$optarg" case $optarg in # Valid mode arguments: clean|compile|execute|finish|install|link|relink|uninstall) ;; # Catch anything else as an error *) func_error "invalid argument for $opt" exit_cmd=exit break ;; esac shift ;; --no-silent|--no-quiet) opt_silent=false func_append preserve_args " $opt" ;; --no-warning|--no-warn) opt_warning=false func_append preserve_args " $opt" ;; --no-verbose) opt_verbose=false func_append preserve_args " $opt" ;; --silent|--quiet) opt_silent=: func_append preserve_args " $opt" opt_verbose=false ;; --verbose|-v) opt_verbose=: func_append preserve_args " $opt" opt_silent=false ;; --tag) test $# = 0 && func_missing_arg $opt && break optarg="$1" opt_tag="$optarg" func_append preserve_args " $opt $optarg" func_enable_tag "$optarg" shift ;; -\?|-h) func_usage ;; --help) func_help ;; --version) func_version ;; # Separate optargs to long options: --*=*) func_split_long_opt "$opt" set dummy "$func_split_long_opt_name" "$func_split_long_opt_arg" ${1+"$@"} shift ;; # Separate non-argument short options: -\?*|-h*|-n*|-v*) func_split_short_opt "$opt" set dummy "$func_split_short_opt_name" "-$func_split_short_opt_arg" ${1+"$@"} shift ;; --) break ;; -*) func_fatal_help "unrecognized option \`$opt'" ;; *) set dummy "$opt" ${1+"$@"}; shift; break ;; esac done # Validate options: # save first non-option argument if test "$#" -gt 0; then nonopt="$opt" shift fi # preserve --debug test "$opt_debug" = : || func_append preserve_args " --debug" case $host in *cygwin* | *mingw* | *pw32* | *cegcc*) # don't eliminate duplications in $postdeps and $predeps opt_duplicate_compiler_generated_deps=: ;; *) opt_duplicate_compiler_generated_deps=$opt_preserve_dup_deps ;; esac $opt_help || { # Sanity checks first: func_check_version_match if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then func_fatal_configuration "not configured to build any kind of library" fi # Darwin sucks eval std_shrext=\"$shrext_cmds\" # Only execute mode is allowed to have -dlopen flags. if test -n "$opt_dlopen" && test "$opt_mode" != execute; then func_error "unrecognized option \`-dlopen'" $ECHO "$help" 1>&2 exit $EXIT_FAILURE fi # Change the help message to a mode-specific one. generic_help="$help" help="Try \`$progname --help --mode=$opt_mode' for more information." } # Bail if the options were screwed $exit_cmd $EXIT_FAILURE } ## ----------- ## ## Main. ## ## ----------- ## # func_lalib_p file # True iff FILE is a libtool `.la' library or `.lo' object file. # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_lalib_p () { test -f "$1" && $SED -e 4q "$1" 2>/dev/null \ | $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1 } # func_lalib_unsafe_p file # True iff FILE is a libtool `.la' library or `.lo' object file. # This function implements the same check as func_lalib_p without # resorting to external programs. To this end, it redirects stdin and # closes it afterwards, without saving the original file descriptor. # As a safety measure, use it only where a negative result would be # fatal anyway. Works if `file' does not exist. func_lalib_unsafe_p () { lalib_p=no if test -f "$1" && test -r "$1" && exec 5<&0 <"$1"; then for lalib_p_l in 1 2 3 4 do read lalib_p_line case "$lalib_p_line" in \#\ Generated\ by\ *$PACKAGE* ) lalib_p=yes; break;; esac done exec 0<&5 5<&- fi test "$lalib_p" = yes } # func_ltwrapper_script_p file # True iff FILE is a libtool wrapper script # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_ltwrapper_script_p () { func_lalib_p "$1" } # func_ltwrapper_executable_p file # True iff FILE is a libtool wrapper executable # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_ltwrapper_executable_p () { func_ltwrapper_exec_suffix= case $1 in *.exe) ;; *) func_ltwrapper_exec_suffix=.exe ;; esac $GREP "$magic_exe" "$1$func_ltwrapper_exec_suffix" >/dev/null 2>&1 } # func_ltwrapper_scriptname file # Assumes file is an ltwrapper_executable # uses $file to determine the appropriate filename for a # temporary ltwrapper_script. func_ltwrapper_scriptname () { func_dirname_and_basename "$1" "" "." func_stripname '' '.exe' "$func_basename_result" func_ltwrapper_scriptname_result="$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper" } # func_ltwrapper_p file # True iff FILE is a libtool wrapper script or wrapper executable # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_ltwrapper_p () { func_ltwrapper_script_p "$1" || func_ltwrapper_executable_p "$1" } # func_execute_cmds commands fail_cmd # Execute tilde-delimited COMMANDS. # If FAIL_CMD is given, eval that upon failure. # FAIL_CMD may read-access the current command in variable CMD! func_execute_cmds () { $opt_debug save_ifs=$IFS; IFS='~' for cmd in $1; do IFS=$save_ifs eval cmd=\"$cmd\" func_show_eval "$cmd" "${2-:}" done IFS=$save_ifs } # func_source file # Source FILE, adding directory component if necessary. # Note that it is not necessary on cygwin/mingw to append a dot to # FILE even if both FILE and FILE.exe exist: automatic-append-.exe # behavior happens only for exec(3), not for open(2)! Also, sourcing # `FILE.' does not work on cygwin managed mounts. func_source () { $opt_debug case $1 in */* | *\\*) . "$1" ;; *) . "./$1" ;; esac } # func_resolve_sysroot PATH # Replace a leading = in PATH with a sysroot. Store the result into # func_resolve_sysroot_result func_resolve_sysroot () { func_resolve_sysroot_result=$1 case $func_resolve_sysroot_result in =*) func_stripname '=' '' "$func_resolve_sysroot_result" func_resolve_sysroot_result=$lt_sysroot$func_stripname_result ;; esac } # func_replace_sysroot PATH # If PATH begins with the sysroot, replace it with = and # store the result into func_replace_sysroot_result. func_replace_sysroot () { case "$lt_sysroot:$1" in ?*:"$lt_sysroot"*) func_stripname "$lt_sysroot" '' "$1" func_replace_sysroot_result="=$func_stripname_result" ;; *) # Including no sysroot. func_replace_sysroot_result=$1 ;; esac } # func_infer_tag arg # Infer tagged configuration to use if any are available and # if one wasn't chosen via the "--tag" command line option. # Only attempt this if the compiler in the base compile # command doesn't match the default compiler. # arg is usually of the form 'gcc ...' func_infer_tag () { $opt_debug if test -n "$available_tags" && test -z "$tagname"; then CC_quoted= for arg in $CC; do func_append_quoted CC_quoted "$arg" done CC_expanded=`func_echo_all $CC` CC_quoted_expanded=`func_echo_all $CC_quoted` case $@ in # Blanks in the command may have been stripped by the calling shell, # but not from the CC environment variable when configure was run. " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \ " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) ;; # Blanks at the start of $base_compile will cause this to fail # if we don't check for them as well. *) for z in $available_tags; do if $GREP "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then # Evaluate the configuration. eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`" CC_quoted= for arg in $CC; do # Double-quote args containing other shell metacharacters. func_append_quoted CC_quoted "$arg" done CC_expanded=`func_echo_all $CC` CC_quoted_expanded=`func_echo_all $CC_quoted` case "$@ " in " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \ " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) # The compiler in the base compile command matches # the one in the tagged configuration. # Assume this is the tagged configuration we want. tagname=$z break ;; esac fi done # If $tagname still isn't set, then no tagged configuration # was found and let the user know that the "--tag" command # line option must be used. if test -z "$tagname"; then func_echo "unable to infer tagged configuration" func_fatal_error "specify a tag with \`--tag'" # else # func_verbose "using $tagname tagged configuration" fi ;; esac fi } # func_write_libtool_object output_name pic_name nonpic_name # Create a libtool object file (analogous to a ".la" file), # but don't create it if we're doing a dry run. func_write_libtool_object () { write_libobj=${1} if test "$build_libtool_libs" = yes; then write_lobj=\'${2}\' else write_lobj=none fi if test "$build_old_libs" = yes; then write_oldobj=\'${3}\' else write_oldobj=none fi $opt_dry_run || { cat >${write_libobj}T </dev/null` if test "$?" -eq 0 && test -n "${func_convert_core_file_wine_to_w32_tmp}"; then func_convert_core_file_wine_to_w32_result=`$ECHO "$func_convert_core_file_wine_to_w32_tmp" | $SED -e "$lt_sed_naive_backslashify"` else func_convert_core_file_wine_to_w32_result= fi fi } # end: func_convert_core_file_wine_to_w32 # func_convert_core_path_wine_to_w32 ARG # Helper function used by path conversion functions when $build is *nix, and # $host is mingw, cygwin, or some other w32 environment. Relies on a correctly # configured wine environment available, with the winepath program in $build's # $PATH. Assumes ARG has no leading or trailing path separator characters. # # ARG is path to be converted from $build format to win32. # Result is available in $func_convert_core_path_wine_to_w32_result. # Unconvertible file (directory) names in ARG are skipped; if no directory names # are convertible, then the result may be empty. func_convert_core_path_wine_to_w32 () { $opt_debug # unfortunately, winepath doesn't convert paths, only file names func_convert_core_path_wine_to_w32_result="" if test -n "$1"; then oldIFS=$IFS IFS=: for func_convert_core_path_wine_to_w32_f in $1; do IFS=$oldIFS func_convert_core_file_wine_to_w32 "$func_convert_core_path_wine_to_w32_f" if test -n "$func_convert_core_file_wine_to_w32_result" ; then if test -z "$func_convert_core_path_wine_to_w32_result"; then func_convert_core_path_wine_to_w32_result="$func_convert_core_file_wine_to_w32_result" else func_append func_convert_core_path_wine_to_w32_result ";$func_convert_core_file_wine_to_w32_result" fi fi done IFS=$oldIFS fi } # end: func_convert_core_path_wine_to_w32 # func_cygpath ARGS... # Wrapper around calling the cygpath program via LT_CYGPATH. This is used when # when (1) $build is *nix and Cygwin is hosted via a wine environment; or (2) # $build is MSYS and $host is Cygwin, or (3) $build is Cygwin. In case (1) or # (2), returns the Cygwin file name or path in func_cygpath_result (input # file name or path is assumed to be in w32 format, as previously converted # from $build's *nix or MSYS format). In case (3), returns the w32 file name # or path in func_cygpath_result (input file name or path is assumed to be in # Cygwin format). Returns an empty string on error. # # ARGS are passed to cygpath, with the last one being the file name or path to # be converted. # # Specify the absolute *nix (or w32) name to cygpath in the LT_CYGPATH # environment variable; do not put it in $PATH. func_cygpath () { $opt_debug if test -n "$LT_CYGPATH" && test -f "$LT_CYGPATH"; then func_cygpath_result=`$LT_CYGPATH "$@" 2>/dev/null` if test "$?" -ne 0; then # on failure, ensure result is empty func_cygpath_result= fi else func_cygpath_result= func_error "LT_CYGPATH is empty or specifies non-existent file: \`$LT_CYGPATH'" fi } #end: func_cygpath # func_convert_core_msys_to_w32 ARG # Convert file name or path ARG from MSYS format to w32 format. Return # result in func_convert_core_msys_to_w32_result. func_convert_core_msys_to_w32 () { $opt_debug # awkward: cmd appends spaces to result func_convert_core_msys_to_w32_result=`( cmd //c echo "$1" ) 2>/dev/null | $SED -e 's/[ ]*$//' -e "$lt_sed_naive_backslashify"` } #end: func_convert_core_msys_to_w32 # func_convert_file_check ARG1 ARG2 # Verify that ARG1 (a file name in $build format) was converted to $host # format in ARG2. Otherwise, emit an error message, but continue (resetting # func_to_host_file_result to ARG1). func_convert_file_check () { $opt_debug if test -z "$2" && test -n "$1" ; then func_error "Could not determine host file name corresponding to" func_error " \`$1'" func_error "Continuing, but uninstalled executables may not work." # Fallback: func_to_host_file_result="$1" fi } # end func_convert_file_check # func_convert_path_check FROM_PATHSEP TO_PATHSEP FROM_PATH TO_PATH # Verify that FROM_PATH (a path in $build format) was converted to $host # format in TO_PATH. Otherwise, emit an error message, but continue, resetting # func_to_host_file_result to a simplistic fallback value (see below). func_convert_path_check () { $opt_debug if test -z "$4" && test -n "$3"; then func_error "Could not determine the host path corresponding to" func_error " \`$3'" func_error "Continuing, but uninstalled executables may not work." # Fallback. This is a deliberately simplistic "conversion" and # should not be "improved". See libtool.info. if test "x$1" != "x$2"; then lt_replace_pathsep_chars="s|$1|$2|g" func_to_host_path_result=`echo "$3" | $SED -e "$lt_replace_pathsep_chars"` else func_to_host_path_result="$3" fi fi } # end func_convert_path_check # func_convert_path_front_back_pathsep FRONTPAT BACKPAT REPL ORIG # Modifies func_to_host_path_result by prepending REPL if ORIG matches FRONTPAT # and appending REPL if ORIG matches BACKPAT. func_convert_path_front_back_pathsep () { $opt_debug case $4 in $1 ) func_to_host_path_result="$3$func_to_host_path_result" ;; esac case $4 in $2 ) func_append func_to_host_path_result "$3" ;; esac } # end func_convert_path_front_back_pathsep ################################################## # $build to $host FILE NAME CONVERSION FUNCTIONS # ################################################## # invoked via `$to_host_file_cmd ARG' # # In each case, ARG is the path to be converted from $build to $host format. # Result will be available in $func_to_host_file_result. # func_to_host_file ARG # Converts the file name ARG from $build format to $host format. Return result # in func_to_host_file_result. func_to_host_file () { $opt_debug $to_host_file_cmd "$1" } # end func_to_host_file # func_to_tool_file ARG LAZY # converts the file name ARG from $build format to toolchain format. Return # result in func_to_tool_file_result. If the conversion in use is listed # in (the comma separated) LAZY, no conversion takes place. func_to_tool_file () { $opt_debug case ,$2, in *,"$to_tool_file_cmd",*) func_to_tool_file_result=$1 ;; *) $to_tool_file_cmd "$1" func_to_tool_file_result=$func_to_host_file_result ;; esac } # end func_to_tool_file # func_convert_file_noop ARG # Copy ARG to func_to_host_file_result. func_convert_file_noop () { func_to_host_file_result="$1" } # end func_convert_file_noop # func_convert_file_msys_to_w32 ARG # Convert file name ARG from (mingw) MSYS to (mingw) w32 format; automatic # conversion to w32 is not available inside the cwrapper. Returns result in # func_to_host_file_result. func_convert_file_msys_to_w32 () { $opt_debug func_to_host_file_result="$1" if test -n "$1"; then func_convert_core_msys_to_w32 "$1" func_to_host_file_result="$func_convert_core_msys_to_w32_result" fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_msys_to_w32 # func_convert_file_cygwin_to_w32 ARG # Convert file name ARG from Cygwin to w32 format. Returns result in # func_to_host_file_result. func_convert_file_cygwin_to_w32 () { $opt_debug func_to_host_file_result="$1" if test -n "$1"; then # because $build is cygwin, we call "the" cygpath in $PATH; no need to use # LT_CYGPATH in this case. func_to_host_file_result=`cygpath -m "$1"` fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_cygwin_to_w32 # func_convert_file_nix_to_w32 ARG # Convert file name ARG from *nix to w32 format. Requires a wine environment # and a working winepath. Returns result in func_to_host_file_result. func_convert_file_nix_to_w32 () { $opt_debug func_to_host_file_result="$1" if test -n "$1"; then func_convert_core_file_wine_to_w32 "$1" func_to_host_file_result="$func_convert_core_file_wine_to_w32_result" fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_nix_to_w32 # func_convert_file_msys_to_cygwin ARG # Convert file name ARG from MSYS to Cygwin format. Requires LT_CYGPATH set. # Returns result in func_to_host_file_result. func_convert_file_msys_to_cygwin () { $opt_debug func_to_host_file_result="$1" if test -n "$1"; then func_convert_core_msys_to_w32 "$1" func_cygpath -u "$func_convert_core_msys_to_w32_result" func_to_host_file_result="$func_cygpath_result" fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_msys_to_cygwin # func_convert_file_nix_to_cygwin ARG # Convert file name ARG from *nix to Cygwin format. Requires Cygwin installed # in a wine environment, working winepath, and LT_CYGPATH set. Returns result # in func_to_host_file_result. func_convert_file_nix_to_cygwin () { $opt_debug func_to_host_file_result="$1" if test -n "$1"; then # convert from *nix to w32, then use cygpath to convert from w32 to cygwin. func_convert_core_file_wine_to_w32 "$1" func_cygpath -u "$func_convert_core_file_wine_to_w32_result" func_to_host_file_result="$func_cygpath_result" fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_nix_to_cygwin ############################################# # $build to $host PATH CONVERSION FUNCTIONS # ############################################# # invoked via `$to_host_path_cmd ARG' # # In each case, ARG is the path to be converted from $build to $host format. # The result will be available in $func_to_host_path_result. # # Path separators are also converted from $build format to $host format. If # ARG begins or ends with a path separator character, it is preserved (but # converted to $host format) on output. # # All path conversion functions are named using the following convention: # file name conversion function : func_convert_file_X_to_Y () # path conversion function : func_convert_path_X_to_Y () # where, for any given $build/$host combination the 'X_to_Y' value is the # same. If conversion functions are added for new $build/$host combinations, # the two new functions must follow this pattern, or func_init_to_host_path_cmd # will break. # func_init_to_host_path_cmd # Ensures that function "pointer" variable $to_host_path_cmd is set to the # appropriate value, based on the value of $to_host_file_cmd. to_host_path_cmd= func_init_to_host_path_cmd () { $opt_debug if test -z "$to_host_path_cmd"; then func_stripname 'func_convert_file_' '' "$to_host_file_cmd" to_host_path_cmd="func_convert_path_${func_stripname_result}" fi } # func_to_host_path ARG # Converts the path ARG from $build format to $host format. Return result # in func_to_host_path_result. func_to_host_path () { $opt_debug func_init_to_host_path_cmd $to_host_path_cmd "$1" } # end func_to_host_path # func_convert_path_noop ARG # Copy ARG to func_to_host_path_result. func_convert_path_noop () { func_to_host_path_result="$1" } # end func_convert_path_noop # func_convert_path_msys_to_w32 ARG # Convert path ARG from (mingw) MSYS to (mingw) w32 format; automatic # conversion to w32 is not available inside the cwrapper. Returns result in # func_to_host_path_result. func_convert_path_msys_to_w32 () { $opt_debug func_to_host_path_result="$1" if test -n "$1"; then # Remove leading and trailing path separator characters from ARG. MSYS # behavior is inconsistent here; cygpath turns them into '.;' and ';.'; # and winepath ignores them completely. func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" func_to_host_path_result="$func_convert_core_msys_to_w32_result" func_convert_path_check : ";" \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" fi } # end func_convert_path_msys_to_w32 # func_convert_path_cygwin_to_w32 ARG # Convert path ARG from Cygwin to w32 format. Returns result in # func_to_host_file_result. func_convert_path_cygwin_to_w32 () { $opt_debug func_to_host_path_result="$1" if test -n "$1"; then # See func_convert_path_msys_to_w32: func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_to_host_path_result=`cygpath -m -p "$func_to_host_path_tmp1"` func_convert_path_check : ";" \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" fi } # end func_convert_path_cygwin_to_w32 # func_convert_path_nix_to_w32 ARG # Convert path ARG from *nix to w32 format. Requires a wine environment and # a working winepath. Returns result in func_to_host_file_result. func_convert_path_nix_to_w32 () { $opt_debug func_to_host_path_result="$1" if test -n "$1"; then # See func_convert_path_msys_to_w32: func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" func_to_host_path_result="$func_convert_core_path_wine_to_w32_result" func_convert_path_check : ";" \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" fi } # end func_convert_path_nix_to_w32 # func_convert_path_msys_to_cygwin ARG # Convert path ARG from MSYS to Cygwin format. Requires LT_CYGPATH set. # Returns result in func_to_host_file_result. func_convert_path_msys_to_cygwin () { $opt_debug func_to_host_path_result="$1" if test -n "$1"; then # See func_convert_path_msys_to_w32: func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" func_cygpath -u -p "$func_convert_core_msys_to_w32_result" func_to_host_path_result="$func_cygpath_result" func_convert_path_check : : \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" : "$1" fi } # end func_convert_path_msys_to_cygwin # func_convert_path_nix_to_cygwin ARG # Convert path ARG from *nix to Cygwin format. Requires Cygwin installed in a # a wine environment, working winepath, and LT_CYGPATH set. Returns result in # func_to_host_file_result. func_convert_path_nix_to_cygwin () { $opt_debug func_to_host_path_result="$1" if test -n "$1"; then # Remove leading and trailing path separator characters from # ARG. msys behavior is inconsistent here, cygpath turns them # into '.;' and ';.', and winepath ignores them completely. func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" func_cygpath -u -p "$func_convert_core_path_wine_to_w32_result" func_to_host_path_result="$func_cygpath_result" func_convert_path_check : : \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" : "$1" fi } # end func_convert_path_nix_to_cygwin # func_mode_compile arg... func_mode_compile () { $opt_debug # Get the compilation command and the source file. base_compile= srcfile="$nonopt" # always keep a non-empty value in "srcfile" suppress_opt=yes suppress_output= arg_mode=normal libobj= later= pie_flag= for arg do case $arg_mode in arg ) # do not "continue". Instead, add this to base_compile lastarg="$arg" arg_mode=normal ;; target ) libobj="$arg" arg_mode=normal continue ;; normal ) # Accept any command-line options. case $arg in -o) test -n "$libobj" && \ func_fatal_error "you cannot specify \`-o' more than once" arg_mode=target continue ;; -pie | -fpie | -fPIE) func_append pie_flag " $arg" continue ;; -shared | -static | -prefer-pic | -prefer-non-pic) func_append later " $arg" continue ;; -no-suppress) suppress_opt=no continue ;; -Xcompiler) arg_mode=arg # the next one goes into the "base_compile" arg list continue # The current "srcfile" will either be retained or ;; # replaced later. I would guess that would be a bug. -Wc,*) func_stripname '-Wc,' '' "$arg" args=$func_stripname_result lastarg= save_ifs="$IFS"; IFS=',' for arg in $args; do IFS="$save_ifs" func_append_quoted lastarg "$arg" done IFS="$save_ifs" func_stripname ' ' '' "$lastarg" lastarg=$func_stripname_result # Add the arguments to base_compile. func_append base_compile " $lastarg" continue ;; *) # Accept the current argument as the source file. # The previous "srcfile" becomes the current argument. # lastarg="$srcfile" srcfile="$arg" ;; esac # case $arg ;; esac # case $arg_mode # Aesthetically quote the previous argument. func_append_quoted base_compile "$lastarg" done # for arg case $arg_mode in arg) func_fatal_error "you must specify an argument for -Xcompile" ;; target) func_fatal_error "you must specify a target with \`-o'" ;; *) # Get the name of the library object. test -z "$libobj" && { func_basename "$srcfile" libobj="$func_basename_result" } ;; esac # Recognize several different file suffixes. # If the user specifies -o file.o, it is replaced with file.lo case $libobj in *.[cCFSifmso] | \ *.ada | *.adb | *.ads | *.asm | \ *.c++ | *.cc | *.ii | *.class | *.cpp | *.cxx | \ *.[fF][09]? | *.for | *.java | *.go | *.obj | *.sx | *.cu | *.cup) func_xform "$libobj" libobj=$func_xform_result ;; esac case $libobj in *.lo) func_lo2o "$libobj"; obj=$func_lo2o_result ;; *) func_fatal_error "cannot determine name of library object from \`$libobj'" ;; esac func_infer_tag $base_compile for arg in $later; do case $arg in -shared) test "$build_libtool_libs" != yes && \ func_fatal_configuration "can not build a shared library" build_old_libs=no continue ;; -static) build_libtool_libs=no build_old_libs=yes continue ;; -prefer-pic) pic_mode=yes continue ;; -prefer-non-pic) pic_mode=no continue ;; esac done func_quote_for_eval "$libobj" test "X$libobj" != "X$func_quote_for_eval_result" \ && $ECHO "X$libobj" | $GREP '[]~#^*{};<>?"'"'"' &()|`$[]' \ && func_warning "libobj name \`$libobj' may not contain shell special characters." func_dirname_and_basename "$obj" "/" "" objname="$func_basename_result" xdir="$func_dirname_result" lobj=${xdir}$objdir/$objname test -z "$base_compile" && \ func_fatal_help "you must specify a compilation command" # Delete any leftover library objects. if test "$build_old_libs" = yes; then removelist="$obj $lobj $libobj ${libobj}T" else removelist="$lobj $libobj ${libobj}T" fi # On Cygwin there's no "real" PIC flag so we must build both object types case $host_os in cygwin* | mingw* | pw32* | os2* | cegcc*) pic_mode=default ;; esac if test "$pic_mode" = no && test "$deplibs_check_method" != pass_all; then # non-PIC code in shared libraries is not supported pic_mode=default fi # Calculate the filename of the output object if compiler does # not support -o with -c if test "$compiler_c_o" = no; then output_obj=`$ECHO "$srcfile" | $SED 's%^.*/%%; s%\.[^.]*$%%'`.${objext} lockfile="$output_obj.lock" else output_obj= need_locks=no lockfile= fi # Lock this critical section if it is needed # We use this script file to make the link, it avoids creating a new file if test "$need_locks" = yes; then until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do func_echo "Waiting for $lockfile to be removed" sleep 2 done elif test "$need_locks" = warn; then if test -f "$lockfile"; then $ECHO "\ *** ERROR, $lockfile exists and contains: `cat $lockfile 2>/dev/null` This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because your compiler does not support \`-c' and \`-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." $opt_dry_run || $RM $removelist exit $EXIT_FAILURE fi func_append removelist " $output_obj" $ECHO "$srcfile" > "$lockfile" fi $opt_dry_run || $RM $removelist func_append removelist " $lockfile" trap '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' 1 2 15 func_to_tool_file "$srcfile" func_convert_file_msys_to_w32 srcfile=$func_to_tool_file_result func_quote_for_eval "$srcfile" qsrcfile=$func_quote_for_eval_result # Only build a PIC object if we are building libtool libraries. if test "$build_libtool_libs" = yes; then # Without this assignment, base_compile gets emptied. fbsd_hideous_sh_bug=$base_compile if test "$pic_mode" != no; then command="$base_compile $qsrcfile $pic_flag" else # Don't build PIC code command="$base_compile $qsrcfile" fi func_mkdir_p "$xdir$objdir" if test -z "$output_obj"; then # Place PIC objects in $objdir func_append command " -o $lobj" fi func_show_eval_locale "$command" \ 'test -n "$output_obj" && $RM $removelist; exit $EXIT_FAILURE' if test "$need_locks" = warn && test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then $ECHO "\ *** ERROR, $lockfile contains: `cat $lockfile 2>/dev/null` but it should contain: $srcfile This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because your compiler does not support \`-c' and \`-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." $opt_dry_run || $RM $removelist exit $EXIT_FAILURE fi # Just move the object if needed, then go on to compile the next one if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then func_show_eval '$MV "$output_obj" "$lobj"' \ 'error=$?; $opt_dry_run || $RM $removelist; exit $error' fi # Allow error messages only from the first compilation. if test "$suppress_opt" = yes; then suppress_output=' >/dev/null 2>&1' fi fi # Only build a position-dependent object if we build old libraries. if test "$build_old_libs" = yes; then if test "$pic_mode" != yes; then # Don't build PIC code command="$base_compile $qsrcfile$pie_flag" else command="$base_compile $qsrcfile $pic_flag" fi if test "$compiler_c_o" = yes; then func_append command " -o $obj" fi # Suppress compiler output if we already did a PIC compilation. func_append command "$suppress_output" func_show_eval_locale "$command" \ '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' if test "$need_locks" = warn && test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then $ECHO "\ *** ERROR, $lockfile contains: `cat $lockfile 2>/dev/null` but it should contain: $srcfile This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because your compiler does not support \`-c' and \`-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." $opt_dry_run || $RM $removelist exit $EXIT_FAILURE fi # Just move the object if needed if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then func_show_eval '$MV "$output_obj" "$obj"' \ 'error=$?; $opt_dry_run || $RM $removelist; exit $error' fi fi $opt_dry_run || { func_write_libtool_object "$libobj" "$objdir/$objname" "$objname" # Unlock the critical section if it was locked if test "$need_locks" != no; then removelist=$lockfile $RM "$lockfile" fi } exit $EXIT_SUCCESS } $opt_help || { test "$opt_mode" = compile && func_mode_compile ${1+"$@"} } func_mode_help () { # We need to display help for each of the modes. case $opt_mode in "") # Generic help is extracted from the usage comments # at the start of this file. func_help ;; clean) $ECHO \ "Usage: $progname [OPTION]... --mode=clean RM [RM-OPTION]... FILE... Remove files from the build directory. RM is the name of the program to use to delete files associated with each FILE (typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed to RM. If FILE is a libtool library, object or program, all the files associated with it are deleted. Otherwise, only FILE itself is deleted using RM." ;; compile) $ECHO \ "Usage: $progname [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE Compile a source file into a libtool library object. This mode accepts the following additional options: -o OUTPUT-FILE set the output file name to OUTPUT-FILE -no-suppress do not suppress compiler output for multiple passes -prefer-pic try to build PIC objects only -prefer-non-pic try to build non-PIC objects only -shared do not build a \`.o' file suitable for static linking -static only build a \`.o' file suitable for static linking -Wc,FLAG pass FLAG directly to the compiler COMPILE-COMMAND is a command to be used in creating a \`standard' object file from the given SOURCEFILE. The output file name is determined by removing the directory component from SOURCEFILE, then substituting the C source code suffix \`.c' with the library object suffix, \`.lo'." ;; execute) $ECHO \ "Usage: $progname [OPTION]... --mode=execute COMMAND [ARGS]... Automatically set library path, then run a program. This mode accepts the following additional options: -dlopen FILE add the directory containing FILE to the library path This mode sets the library path environment variable according to \`-dlopen' flags. If any of the ARGS are libtool executable wrappers, then they are translated into their corresponding uninstalled binary, and any of their required library directories are added to the library path. Then, COMMAND is executed, with ARGS as arguments." ;; finish) $ECHO \ "Usage: $progname [OPTION]... --mode=finish [LIBDIR]... Complete the installation of libtool libraries. Each LIBDIR is a directory that contains libtool libraries. The commands that this mode executes may require superuser privileges. Use the \`--dry-run' option if you just want to see what would be executed." ;; install) $ECHO \ "Usage: $progname [OPTION]... --mode=install INSTALL-COMMAND... Install executables or libraries. INSTALL-COMMAND is the installation command. The first component should be either the \`install' or \`cp' program. The following components of INSTALL-COMMAND are treated specially: -inst-prefix-dir PREFIX-DIR Use PREFIX-DIR as a staging area for installation The rest of the components are interpreted as arguments to that command (only BSD-compatible install options are recognized)." ;; link) $ECHO \ "Usage: $progname [OPTION]... --mode=link LINK-COMMAND... Link object files or libraries together to form another library, or to create an executable program. LINK-COMMAND is a command using the C compiler that you would use to create a program from several object files. The following components of LINK-COMMAND are treated specially: -all-static do not do any dynamic linking at all -avoid-version do not add a version suffix if possible -bindir BINDIR specify path to binaries directory (for systems where libraries must be found in the PATH setting at runtime) -dlopen FILE \`-dlpreopen' FILE if it cannot be dlopened at runtime -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3) -export-symbols SYMFILE try to export only the symbols listed in SYMFILE -export-symbols-regex REGEX try to export only the symbols matching REGEX -LLIBDIR search LIBDIR for required installed libraries -lNAME OUTPUT-FILE requires the installed library libNAME -module build a library that can dlopened -no-fast-install disable the fast-install mode -no-install link a not-installable executable -no-undefined declare that a library does not refer to external symbols -o OUTPUT-FILE create OUTPUT-FILE from the specified objects -objectlist FILE Use a list of object files found in FILE to specify objects -precious-files-regex REGEX don't remove output files matching REGEX -release RELEASE specify package release information -rpath LIBDIR the created library will eventually be installed in LIBDIR -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries -shared only do dynamic linking of libtool libraries -shrext SUFFIX override the standard shared library file extension -static do not do any dynamic linking of uninstalled libtool libraries -static-libtool-libs do not do any dynamic linking of libtool libraries -version-info CURRENT[:REVISION[:AGE]] specify library version info [each variable defaults to 0] -weak LIBNAME declare that the target provides the LIBNAME interface -Wc,FLAG -Xcompiler FLAG pass linker-specific FLAG directly to the compiler -Wl,FLAG -Xlinker FLAG pass linker-specific FLAG directly to the linker -XCClinker FLAG pass link-specific FLAG to the compiler driver (CC) All other options (arguments beginning with \`-') are ignored. Every other argument is treated as a filename. Files ending in \`.la' are treated as uninstalled libtool libraries, other files are standard or library object files. If the OUTPUT-FILE ends in \`.la', then a libtool library is created, only library objects (\`.lo' files) may be specified, and \`-rpath' is required, except when creating a convenience library. If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created using \`ar' and \`ranlib', or on Windows using \`lib'. If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file is created, otherwise an executable program is created." ;; uninstall) $ECHO \ "Usage: $progname [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE... Remove libraries from an installation directory. RM is the name of the program to use to delete files associated with each FILE (typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed to RM. If FILE is a libtool library, all the files associated with it are deleted. Otherwise, only FILE itself is deleted using RM." ;; *) func_fatal_help "invalid operation mode \`$opt_mode'" ;; esac echo $ECHO "Try \`$progname --help' for more information about other modes." } # Now that we've collected a possible --mode arg, show help if necessary if $opt_help; then if test "$opt_help" = :; then func_mode_help else { func_help noexit for opt_mode in compile link execute install finish uninstall clean; do func_mode_help done } | sed -n '1p; 2,$s/^Usage:/ or: /p' { func_help noexit for opt_mode in compile link execute install finish uninstall clean; do echo func_mode_help done } | sed '1d /^When reporting/,/^Report/{ H d } $x /information about other modes/d /more detailed .*MODE/d s/^Usage:.*--mode=\([^ ]*\) .*/Description of \1 mode:/' fi exit $? fi # func_mode_execute arg... func_mode_execute () { $opt_debug # The first argument is the command name. cmd="$nonopt" test -z "$cmd" && \ func_fatal_help "you must specify a COMMAND" # Handle -dlopen flags immediately. for file in $opt_dlopen; do test -f "$file" \ || func_fatal_help "\`$file' is not a file" dir= case $file in *.la) func_resolve_sysroot "$file" file=$func_resolve_sysroot_result # Check to see that this really is a libtool archive. func_lalib_unsafe_p "$file" \ || func_fatal_help "\`$lib' is not a valid libtool archive" # Read the libtool library. dlname= library_names= func_source "$file" # Skip this library if it cannot be dlopened. if test -z "$dlname"; then # Warn if it was a shared library. test -n "$library_names" && \ func_warning "\`$file' was not linked with \`-export-dynamic'" continue fi func_dirname "$file" "" "." dir="$func_dirname_result" if test -f "$dir/$objdir/$dlname"; then func_append dir "/$objdir" else if test ! -f "$dir/$dlname"; then func_fatal_error "cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" fi fi ;; *.lo) # Just add the directory containing the .lo file. func_dirname "$file" "" "." dir="$func_dirname_result" ;; *) func_warning "\`-dlopen' is ignored for non-libtool libraries and objects" continue ;; esac # Get the absolute pathname. absdir=`cd "$dir" && pwd` test -n "$absdir" && dir="$absdir" # Now add the directory to shlibpath_var. if eval "test -z \"\$$shlibpath_var\""; then eval "$shlibpath_var=\"\$dir\"" else eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\"" fi done # This variable tells wrapper scripts just to set shlibpath_var # rather than running their programs. libtool_execute_magic="$magic" # Check if any of the arguments is a wrapper script. args= for file do case $file in -* | *.la | *.lo ) ;; *) # Do a test to see if this is really a libtool program. if func_ltwrapper_script_p "$file"; then func_source "$file" # Transform arg to wrapped name. file="$progdir/$program" elif func_ltwrapper_executable_p "$file"; then func_ltwrapper_scriptname "$file" func_source "$func_ltwrapper_scriptname_result" # Transform arg to wrapped name. file="$progdir/$program" fi ;; esac # Quote arguments (to preserve shell metacharacters). func_append_quoted args "$file" done if test "X$opt_dry_run" = Xfalse; then if test -n "$shlibpath_var"; then # Export the shlibpath_var. eval "export $shlibpath_var" fi # Restore saved environment variables for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES do eval "if test \"\${save_$lt_var+set}\" = set; then $lt_var=\$save_$lt_var; export $lt_var else $lt_unset $lt_var fi" done # Now prepare to actually exec the command. exec_cmd="\$cmd$args" else # Display what would be done. if test -n "$shlibpath_var"; then eval "\$ECHO \"\$shlibpath_var=\$$shlibpath_var\"" echo "export $shlibpath_var" fi $ECHO "$cmd$args" exit $EXIT_SUCCESS fi } test "$opt_mode" = execute && func_mode_execute ${1+"$@"} # func_mode_finish arg... func_mode_finish () { $opt_debug libs= libdirs= admincmds= for opt in "$nonopt" ${1+"$@"} do if test -d "$opt"; then func_append libdirs " $opt" elif test -f "$opt"; then if func_lalib_unsafe_p "$opt"; then func_append libs " $opt" else func_warning "\`$opt' is not a valid libtool archive" fi else func_fatal_error "invalid argument \`$opt'" fi done if test -n "$libs"; then if test -n "$lt_sysroot"; then sysroot_regex=`$ECHO "$lt_sysroot" | $SED "$sed_make_literal_regex"` sysroot_cmd="s/\([ ']\)$sysroot_regex/\1/g;" else sysroot_cmd= fi # Remove sysroot references if $opt_dry_run; then for lib in $libs; do echo "removing references to $lt_sysroot and \`=' prefixes from $lib" done else tmpdir=`func_mktempdir` for lib in $libs; do sed -e "${sysroot_cmd} s/\([ ']-[LR]\)=/\1/g; s/\([ ']\)=/\1/g" $lib \ > $tmpdir/tmp-la mv -f $tmpdir/tmp-la $lib done ${RM}r "$tmpdir" fi fi if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then for libdir in $libdirs; do if test -n "$finish_cmds"; then # Do each command in the finish commands. func_execute_cmds "$finish_cmds" 'admincmds="$admincmds '"$cmd"'"' fi if test -n "$finish_eval"; then # Do the single finish_eval. eval cmds=\"$finish_eval\" $opt_dry_run || eval "$cmds" || func_append admincmds " $cmds" fi done fi # Exit here if they wanted silent mode. $opt_silent && exit $EXIT_SUCCESS if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then echo "----------------------------------------------------------------------" echo "Libraries have been installed in:" for libdir in $libdirs; do $ECHO " $libdir" done echo echo "If you ever happen to want to link against installed libraries" echo "in a given directory, LIBDIR, you must either use libtool, and" echo "specify the full pathname of the library, or use the \`-LLIBDIR'" echo "flag during linking and do at least one of the following:" if test -n "$shlibpath_var"; then echo " - add LIBDIR to the \`$shlibpath_var' environment variable" echo " during execution" fi if test -n "$runpath_var"; then echo " - add LIBDIR to the \`$runpath_var' environment variable" echo " during linking" fi if test -n "$hardcode_libdir_flag_spec"; then libdir=LIBDIR eval flag=\"$hardcode_libdir_flag_spec\" $ECHO " - use the \`$flag' linker flag" fi if test -n "$admincmds"; then $ECHO " - have your system administrator run these commands:$admincmds" fi if test -f /etc/ld.so.conf; then echo " - have your system administrator add LIBDIR to \`/etc/ld.so.conf'" fi echo echo "See any operating system documentation about shared libraries for" case $host in solaris2.[6789]|solaris2.1[0-9]) echo "more information, such as the ld(1), crle(1) and ld.so(8) manual" echo "pages." ;; *) echo "more information, such as the ld(1) and ld.so(8) manual pages." ;; esac echo "----------------------------------------------------------------------" fi exit $EXIT_SUCCESS } test "$opt_mode" = finish && func_mode_finish ${1+"$@"} # func_mode_install arg... func_mode_install () { $opt_debug # There may be an optional sh(1) argument at the beginning of # install_prog (especially on Windows NT). if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh || # Allow the use of GNU shtool's install command. case $nonopt in *shtool*) :;; *) false;; esac; then # Aesthetically quote it. func_quote_for_eval "$nonopt" install_prog="$func_quote_for_eval_result " arg=$1 shift else install_prog= arg=$nonopt fi # The real first argument should be the name of the installation program. # Aesthetically quote it. func_quote_for_eval "$arg" func_append install_prog "$func_quote_for_eval_result" install_shared_prog=$install_prog case " $install_prog " in *[\\\ /]cp\ *) install_cp=: ;; *) install_cp=false ;; esac # We need to accept at least all the BSD install flags. dest= files= opts= prev= install_type= isdir=no stripme= no_mode=: for arg do arg2= if test -n "$dest"; then func_append files " $dest" dest=$arg continue fi case $arg in -d) isdir=yes ;; -f) if $install_cp; then :; else prev=$arg fi ;; -g | -m | -o) prev=$arg ;; -s) stripme=" -s" continue ;; -*) ;; *) # If the previous option needed an argument, then skip it. if test -n "$prev"; then if test "x$prev" = x-m && test -n "$install_override_mode"; then arg2=$install_override_mode no_mode=false fi prev= else dest=$arg continue fi ;; esac # Aesthetically quote the argument. func_quote_for_eval "$arg" func_append install_prog " $func_quote_for_eval_result" if test -n "$arg2"; then func_quote_for_eval "$arg2" fi func_append install_shared_prog " $func_quote_for_eval_result" done test -z "$install_prog" && \ func_fatal_help "you must specify an install program" test -n "$prev" && \ func_fatal_help "the \`$prev' option requires an argument" if test -n "$install_override_mode" && $no_mode; then if $install_cp; then :; else func_quote_for_eval "$install_override_mode" func_append install_shared_prog " -m $func_quote_for_eval_result" fi fi if test -z "$files"; then if test -z "$dest"; then func_fatal_help "no file or destination specified" else func_fatal_help "you must specify a destination" fi fi # Strip any trailing slash from the destination. func_stripname '' '/' "$dest" dest=$func_stripname_result # Check to see that the destination is a directory. test -d "$dest" && isdir=yes if test "$isdir" = yes; then destdir="$dest" destname= else func_dirname_and_basename "$dest" "" "." destdir="$func_dirname_result" destname="$func_basename_result" # Not a directory, so check to see that there is only one file specified. set dummy $files; shift test "$#" -gt 1 && \ func_fatal_help "\`$dest' is not a directory" fi case $destdir in [\\/]* | [A-Za-z]:[\\/]*) ;; *) for file in $files; do case $file in *.lo) ;; *) func_fatal_help "\`$destdir' must be an absolute directory name" ;; esac done ;; esac # This variable tells wrapper scripts just to set variables rather # than running their programs. libtool_install_magic="$magic" staticlibs= future_libdirs= current_libdirs= for file in $files; do # Do each installation. case $file in *.$libext) # Do the static libraries later. func_append staticlibs " $file" ;; *.la) func_resolve_sysroot "$file" file=$func_resolve_sysroot_result # Check to see that this really is a libtool archive. func_lalib_unsafe_p "$file" \ || func_fatal_help "\`$file' is not a valid libtool archive" library_names= old_library= relink_command= func_source "$file" # Add the libdir to current_libdirs if it is the destination. if test "X$destdir" = "X$libdir"; then case "$current_libdirs " in *" $libdir "*) ;; *) func_append current_libdirs " $libdir" ;; esac else # Note the libdir as a future libdir. case "$future_libdirs " in *" $libdir "*) ;; *) func_append future_libdirs " $libdir" ;; esac fi func_dirname "$file" "/" "" dir="$func_dirname_result" func_append dir "$objdir" if test -n "$relink_command"; then # Determine the prefix the user has applied to our future dir. inst_prefix_dir=`$ECHO "$destdir" | $SED -e "s%$libdir\$%%"` # Don't allow the user to place us outside of our expected # location b/c this prevents finding dependent libraries that # are installed to the same prefix. # At present, this check doesn't affect windows .dll's that # are installed into $libdir/../bin (currently, that works fine) # but it's something to keep an eye on. test "$inst_prefix_dir" = "$destdir" && \ func_fatal_error "error: cannot install \`$file' to a directory not ending in $libdir" if test -n "$inst_prefix_dir"; then # Stick the inst_prefix_dir data into the link command. relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"` else relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%%"` fi func_warning "relinking \`$file'" func_show_eval "$relink_command" \ 'func_fatal_error "error: relink \`$file'\'' with the above command before installing it"' fi # See the names of the shared library. set dummy $library_names; shift if test -n "$1"; then realname="$1" shift srcname="$realname" test -n "$relink_command" && srcname="$realname"T # Install the shared library and build the symlinks. func_show_eval "$install_shared_prog $dir/$srcname $destdir/$realname" \ 'exit $?' tstripme="$stripme" case $host_os in cygwin* | mingw* | pw32* | cegcc*) case $realname in *.dll.a) tstripme="" ;; esac ;; esac if test -n "$tstripme" && test -n "$striplib"; then func_show_eval "$striplib $destdir/$realname" 'exit $?' fi if test "$#" -gt 0; then # Delete the old symlinks, and create new ones. # Try `ln -sf' first, because the `ln' binary might depend on # the symlink we replace! Solaris /bin/ln does not understand -f, # so we also need to try rm && ln -s. for linkname do test "$linkname" != "$realname" \ && func_show_eval "(cd $destdir && { $LN_S -f $realname $linkname || { $RM $linkname && $LN_S $realname $linkname; }; })" done fi # Do each command in the postinstall commands. lib="$destdir/$realname" func_execute_cmds "$postinstall_cmds" 'exit $?' fi # Install the pseudo-library for information purposes. func_basename "$file" name="$func_basename_result" instname="$dir/$name"i func_show_eval "$install_prog $instname $destdir/$name" 'exit $?' # Maybe install the static library, too. test -n "$old_library" && func_append staticlibs " $dir/$old_library" ;; *.lo) # Install (i.e. copy) a libtool object. # Figure out destination file name, if it wasn't already specified. if test -n "$destname"; then destfile="$destdir/$destname" else func_basename "$file" destfile="$func_basename_result" destfile="$destdir/$destfile" fi # Deduce the name of the destination old-style object file. case $destfile in *.lo) func_lo2o "$destfile" staticdest=$func_lo2o_result ;; *.$objext) staticdest="$destfile" destfile= ;; *) func_fatal_help "cannot copy a libtool object to \`$destfile'" ;; esac # Install the libtool object if requested. test -n "$destfile" && \ func_show_eval "$install_prog $file $destfile" 'exit $?' # Install the old object if enabled. if test "$build_old_libs" = yes; then # Deduce the name of the old-style object file. func_lo2o "$file" staticobj=$func_lo2o_result func_show_eval "$install_prog \$staticobj \$staticdest" 'exit $?' fi exit $EXIT_SUCCESS ;; *) # Figure out destination file name, if it wasn't already specified. if test -n "$destname"; then destfile="$destdir/$destname" else func_basename "$file" destfile="$func_basename_result" destfile="$destdir/$destfile" fi # If the file is missing, and there is a .exe on the end, strip it # because it is most likely a libtool script we actually want to # install stripped_ext="" case $file in *.exe) if test ! -f "$file"; then func_stripname '' '.exe' "$file" file=$func_stripname_result stripped_ext=".exe" fi ;; esac # Do a test to see if this is really a libtool program. case $host in *cygwin* | *mingw*) if func_ltwrapper_executable_p "$file"; then func_ltwrapper_scriptname "$file" wrapper=$func_ltwrapper_scriptname_result else func_stripname '' '.exe' "$file" wrapper=$func_stripname_result fi ;; *) wrapper=$file ;; esac if func_ltwrapper_script_p "$wrapper"; then notinst_deplibs= relink_command= func_source "$wrapper" # Check the variables that should have been set. test -z "$generated_by_libtool_version" && \ func_fatal_error "invalid libtool wrapper script \`$wrapper'" finalize=yes for lib in $notinst_deplibs; do # Check to see that each library is installed. libdir= if test -f "$lib"; then func_source "$lib" fi libfile="$libdir/"`$ECHO "$lib" | $SED 's%^.*/%%g'` ### testsuite: skip nested quoting test if test -n "$libdir" && test ! -f "$libfile"; then func_warning "\`$lib' has not been installed in \`$libdir'" finalize=no fi done relink_command= func_source "$wrapper" outputname= if test "$fast_install" = no && test -n "$relink_command"; then $opt_dry_run || { if test "$finalize" = yes; then tmpdir=`func_mktempdir` func_basename "$file$stripped_ext" file="$func_basename_result" outputname="$tmpdir/$file" # Replace the output file specification. relink_command=`$ECHO "$relink_command" | $SED 's%@OUTPUT@%'"$outputname"'%g'` $opt_silent || { func_quote_for_expand "$relink_command" eval "func_echo $func_quote_for_expand_result" } if eval "$relink_command"; then : else func_error "error: relink \`$file' with the above command before installing it" $opt_dry_run || ${RM}r "$tmpdir" continue fi file="$outputname" else func_warning "cannot relink \`$file'" fi } else # Install the binary that we compiled earlier. file=`$ECHO "$file$stripped_ext" | $SED "s%\([^/]*\)$%$objdir/\1%"` fi fi # remove .exe since cygwin /usr/bin/install will append another # one anyway case $install_prog,$host in */usr/bin/install*,*cygwin*) case $file:$destfile in *.exe:*.exe) # this is ok ;; *.exe:*) destfile=$destfile.exe ;; *:*.exe) func_stripname '' '.exe' "$destfile" destfile=$func_stripname_result ;; esac ;; esac func_show_eval "$install_prog\$stripme \$file \$destfile" 'exit $?' $opt_dry_run || if test -n "$outputname"; then ${RM}r "$tmpdir" fi ;; esac done for file in $staticlibs; do func_basename "$file" name="$func_basename_result" # Set up the ranlib parameters. oldlib="$destdir/$name" func_to_tool_file "$oldlib" func_convert_file_msys_to_w32 tool_oldlib=$func_to_tool_file_result func_show_eval "$install_prog \$file \$oldlib" 'exit $?' if test -n "$stripme" && test -n "$old_striplib"; then func_show_eval "$old_striplib $tool_oldlib" 'exit $?' fi # Do each command in the postinstall commands. func_execute_cmds "$old_postinstall_cmds" 'exit $?' done test -n "$future_libdirs" && \ func_warning "remember to run \`$progname --finish$future_libdirs'" if test -n "$current_libdirs"; then # Maybe just do a dry run. $opt_dry_run && current_libdirs=" -n$current_libdirs" exec_cmd='$SHELL $progpath $preserve_args --finish$current_libdirs' else exit $EXIT_SUCCESS fi } test "$opt_mode" = install && func_mode_install ${1+"$@"} # func_generate_dlsyms outputname originator pic_p # Extract symbols from dlprefiles and create ${outputname}S.o with # a dlpreopen symbol table. func_generate_dlsyms () { $opt_debug my_outputname="$1" my_originator="$2" my_pic_p="${3-no}" my_prefix=`$ECHO "$my_originator" | sed 's%[^a-zA-Z0-9]%_%g'` my_dlsyms= if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then if test -n "$NM" && test -n "$global_symbol_pipe"; then my_dlsyms="${my_outputname}S.c" else func_error "not configured to extract global symbols from dlpreopened files" fi fi if test -n "$my_dlsyms"; then case $my_dlsyms in "") ;; *.c) # Discover the nlist of each of the dlfiles. nlist="$output_objdir/${my_outputname}.nm" func_show_eval "$RM $nlist ${nlist}S ${nlist}T" # Parse the name list into a source file. func_verbose "creating $output_objdir/$my_dlsyms" $opt_dry_run || $ECHO > "$output_objdir/$my_dlsyms" "\ /* $my_dlsyms - symbol resolution table for \`$my_outputname' dlsym emulation. */ /* Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION */ #ifdef __cplusplus extern \"C\" { #endif #if defined(__GNUC__) && (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 4)) #pragma GCC diagnostic ignored \"-Wstrict-prototypes\" #endif /* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ #if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) /* DATA imports from DLLs on WIN32 con't be const, because runtime relocations are performed -- see ld's documentation on pseudo-relocs. */ # define LT_DLSYM_CONST #elif defined(__osf__) /* This system does not cope well with relocations in const data. */ # define LT_DLSYM_CONST #else # define LT_DLSYM_CONST const #endif /* External symbol declarations for the compiler. */\ " if test "$dlself" = yes; then func_verbose "generating symbol list for \`$output'" $opt_dry_run || echo ': @PROGRAM@ ' > "$nlist" # Add our own program objects to the symbol list. progfiles=`$ECHO "$objs$old_deplibs" | $SP2NL | $SED "$lo2o" | $NL2SP` for progfile in $progfiles; do func_to_tool_file "$progfile" func_convert_file_msys_to_w32 func_verbose "extracting global C symbols from \`$func_to_tool_file_result'" $opt_dry_run || eval "$NM $func_to_tool_file_result | $global_symbol_pipe >> '$nlist'" done if test -n "$exclude_expsyms"; then $opt_dry_run || { eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T' eval '$MV "$nlist"T "$nlist"' } fi if test -n "$export_symbols_regex"; then $opt_dry_run || { eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T' eval '$MV "$nlist"T "$nlist"' } fi # Prepare the list of exported symbols if test -z "$export_symbols"; then export_symbols="$output_objdir/$outputname.exp" $opt_dry_run || { $RM $export_symbols eval "${SED} -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' case $host in *cygwin* | *mingw* | *cegcc* ) eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"' ;; esac } else $opt_dry_run || { eval "${SED} -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"' eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T' eval '$MV "$nlist"T "$nlist"' case $host in *cygwin* | *mingw* | *cegcc* ) eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' eval 'cat "$nlist" >> "$output_objdir/$outputname.def"' ;; esac } fi fi for dlprefile in $dlprefiles; do func_verbose "extracting global C symbols from \`$dlprefile'" func_basename "$dlprefile" name="$func_basename_result" case $host in *cygwin* | *mingw* | *cegcc* ) # if an import library, we need to obtain dlname if func_win32_import_lib_p "$dlprefile"; then func_tr_sh "$dlprefile" eval "curr_lafile=\$libfile_$func_tr_sh_result" dlprefile_dlbasename="" if test -n "$curr_lafile" && func_lalib_p "$curr_lafile"; then # Use subshell, to avoid clobbering current variable values dlprefile_dlname=`source "$curr_lafile" && echo "$dlname"` if test -n "$dlprefile_dlname" ; then func_basename "$dlprefile_dlname" dlprefile_dlbasename="$func_basename_result" else # no lafile. user explicitly requested -dlpreopen . $sharedlib_from_linklib_cmd "$dlprefile" dlprefile_dlbasename=$sharedlib_from_linklib_result fi fi $opt_dry_run || { if test -n "$dlprefile_dlbasename" ; then eval '$ECHO ": $dlprefile_dlbasename" >> "$nlist"' else func_warning "Could not compute DLL name from $name" eval '$ECHO ": $name " >> "$nlist"' fi func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe | $SED -e '/I __imp/d' -e 's/I __nm_/D /;s/_nm__//' >> '$nlist'" } else # not an import lib $opt_dry_run || { eval '$ECHO ": $name " >> "$nlist"' func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'" } fi ;; *) $opt_dry_run || { eval '$ECHO ": $name " >> "$nlist"' func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'" } ;; esac done $opt_dry_run || { # Make sure we have at least an empty file. test -f "$nlist" || : > "$nlist" if test -n "$exclude_expsyms"; then $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T $MV "$nlist"T "$nlist" fi # Try sorting and uniquifying the output. if $GREP -v "^: " < "$nlist" | if sort -k 3 /dev/null 2>&1; then sort -k 3 else sort +2 fi | uniq > "$nlist"S; then : else $GREP -v "^: " < "$nlist" > "$nlist"S fi if test -f "$nlist"S; then eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$my_dlsyms"' else echo '/* NONE */' >> "$output_objdir/$my_dlsyms" fi echo >> "$output_objdir/$my_dlsyms" "\ /* The mapping between symbol names and symbols. */ typedef struct { const char *name; void *address; } lt_dlsymlist; extern LT_DLSYM_CONST lt_dlsymlist lt_${my_prefix}_LTX_preloaded_symbols[]; LT_DLSYM_CONST lt_dlsymlist lt_${my_prefix}_LTX_preloaded_symbols[] = {\ { \"$my_originator\", (void *) 0 }," case $need_lib_prefix in no) eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$my_dlsyms" ;; *) eval "$global_symbol_to_c_name_address_lib_prefix" < "$nlist" >> "$output_objdir/$my_dlsyms" ;; esac echo >> "$output_objdir/$my_dlsyms" "\ {0, (void *) 0} }; /* This works around a problem in FreeBSD linker */ #ifdef FREEBSD_WORKAROUND static const void *lt_preloaded_setup() { return lt_${my_prefix}_LTX_preloaded_symbols; } #endif #ifdef __cplusplus } #endif\ " } # !$opt_dry_run pic_flag_for_symtable= case "$compile_command " in *" -static "*) ;; *) case $host in # compiling the symbol table file with pic_flag works around # a FreeBSD bug that causes programs to crash when -lm is # linked before any other PIC object. But we must not use # pic_flag when linking with -static. The problem exists in # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1. *-*-freebsd2.*|*-*-freebsd3.0*|*-*-freebsdelf3.0*) pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND" ;; *-*-hpux*) pic_flag_for_symtable=" $pic_flag" ;; *) if test "X$my_pic_p" != Xno; then pic_flag_for_symtable=" $pic_flag" fi ;; esac ;; esac symtab_cflags= for arg in $LTCFLAGS; do case $arg in -pie | -fpie | -fPIE) ;; *) func_append symtab_cflags " $arg" ;; esac done # Now compile the dynamic symbol file. func_show_eval '(cd $output_objdir && $LTCC$symtab_cflags -c$no_builtin_flag$pic_flag_for_symtable "$my_dlsyms")' 'exit $?' # Clean up the generated files. func_show_eval '$RM "$output_objdir/$my_dlsyms" "$nlist" "${nlist}S" "${nlist}T"' # Transform the symbol file into the correct name. symfileobj="$output_objdir/${my_outputname}S.$objext" case $host in *cygwin* | *mingw* | *cegcc* ) if test -f "$output_objdir/$my_outputname.def"; then compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` else compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"` finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"` fi ;; *) compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"` finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"` ;; esac ;; *) func_fatal_error "unknown suffix for \`$my_dlsyms'" ;; esac else # We keep going just in case the user didn't refer to # lt_preloaded_symbols. The linker will fail if global_symbol_pipe # really was required. # Nullify the symbol file. compile_command=`$ECHO "$compile_command" | $SED "s% @SYMFILE@%%"` finalize_command=`$ECHO "$finalize_command" | $SED "s% @SYMFILE@%%"` fi } # func_win32_libid arg # return the library type of file 'arg' # # Need a lot of goo to handle *both* DLLs and import libs # Has to be a shell function in order to 'eat' the argument # that is supplied when $file_magic_command is called. # Despite the name, also deal with 64 bit binaries. func_win32_libid () { $opt_debug win32_libid_type="unknown" win32_fileres=`file -L $1 2>/dev/null` case $win32_fileres in *ar\ archive\ import\ library*) # definitely import win32_libid_type="x86 archive import" ;; *ar\ archive*) # could be an import, or static # Keep the egrep pattern in sync with the one in _LT_CHECK_MAGIC_METHOD. if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null | $EGREP 'file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' >/dev/null; then func_to_tool_file "$1" func_convert_file_msys_to_w32 win32_nmres=`eval $NM -f posix -A \"$func_to_tool_file_result\" | $SED -n -e ' 1,100{ / I /{ s,.*,import, p q } }'` case $win32_nmres in import*) win32_libid_type="x86 archive import";; *) win32_libid_type="x86 archive static";; esac fi ;; *DLL*) win32_libid_type="x86 DLL" ;; *executable*) # but shell scripts are "executable" too... case $win32_fileres in *MS\ Windows\ PE\ Intel*) win32_libid_type="x86 DLL" ;; esac ;; esac $ECHO "$win32_libid_type" } # func_cygming_dll_for_implib ARG # # Platform-specific function to extract the # name of the DLL associated with the specified # import library ARG. # Invoked by eval'ing the libtool variable # $sharedlib_from_linklib_cmd # Result is available in the variable # $sharedlib_from_linklib_result func_cygming_dll_for_implib () { $opt_debug sharedlib_from_linklib_result=`$DLLTOOL --identify-strict --identify "$1"` } # func_cygming_dll_for_implib_fallback_core SECTION_NAME LIBNAMEs # # The is the core of a fallback implementation of a # platform-specific function to extract the name of the # DLL associated with the specified import library LIBNAME. # # SECTION_NAME is either .idata$6 or .idata$7, depending # on the platform and compiler that created the implib. # # Echos the name of the DLL associated with the # specified import library. func_cygming_dll_for_implib_fallback_core () { $opt_debug match_literal=`$ECHO "$1" | $SED "$sed_make_literal_regex"` $OBJDUMP -s --section "$1" "$2" 2>/dev/null | $SED '/^Contents of section '"$match_literal"':/{ # Place marker at beginning of archive member dllname section s/.*/====MARK====/ p d } # These lines can sometimes be longer than 43 characters, but # are always uninteresting /:[ ]*file format pe[i]\{,1\}-/d /^In archive [^:]*:/d # Ensure marker is printed /^====MARK====/p # Remove all lines with less than 43 characters /^.\{43\}/!d # From remaining lines, remove first 43 characters s/^.\{43\}//' | $SED -n ' # Join marker and all lines until next marker into a single line /^====MARK====/ b para H $ b para b :para x s/\n//g # Remove the marker s/^====MARK====// # Remove trailing dots and whitespace s/[\. \t]*$// # Print /./p' | # we now have a list, one entry per line, of the stringified # contents of the appropriate section of all members of the # archive which possess that section. Heuristic: eliminate # all those which have a first or second character that is # a '.' (that is, objdump's representation of an unprintable # character.) This should work for all archives with less than # 0x302f exports -- but will fail for DLLs whose name actually # begins with a literal '.' or a single character followed by # a '.'. # # Of those that remain, print the first one. $SED -e '/^\./d;/^.\./d;q' } # func_cygming_gnu_implib_p ARG # This predicate returns with zero status (TRUE) if # ARG is a GNU/binutils-style import library. Returns # with nonzero status (FALSE) otherwise. func_cygming_gnu_implib_p () { $opt_debug func_to_tool_file "$1" func_convert_file_msys_to_w32 func_cygming_gnu_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $EGREP ' (_head_[A-Za-z0-9_]+_[ad]l*|[A-Za-z0-9_]+_[ad]l*_iname)$'` test -n "$func_cygming_gnu_implib_tmp" } # func_cygming_ms_implib_p ARG # This predicate returns with zero status (TRUE) if # ARG is an MS-style import library. Returns # with nonzero status (FALSE) otherwise. func_cygming_ms_implib_p () { $opt_debug func_to_tool_file "$1" func_convert_file_msys_to_w32 func_cygming_ms_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $GREP '_NULL_IMPORT_DESCRIPTOR'` test -n "$func_cygming_ms_implib_tmp" } # func_cygming_dll_for_implib_fallback ARG # Platform-specific function to extract the # name of the DLL associated with the specified # import library ARG. # # This fallback implementation is for use when $DLLTOOL # does not support the --identify-strict option. # Invoked by eval'ing the libtool variable # $sharedlib_from_linklib_cmd # Result is available in the variable # $sharedlib_from_linklib_result func_cygming_dll_for_implib_fallback () { $opt_debug if func_cygming_gnu_implib_p "$1" ; then # binutils import library sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$7' "$1"` elif func_cygming_ms_implib_p "$1" ; then # ms-generated import library sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$6' "$1"` else # unknown sharedlib_from_linklib_result="" fi } # func_extract_an_archive dir oldlib func_extract_an_archive () { $opt_debug f_ex_an_ar_dir="$1"; shift f_ex_an_ar_oldlib="$1" if test "$lock_old_archive_extraction" = yes; then lockfile=$f_ex_an_ar_oldlib.lock until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do func_echo "Waiting for $lockfile to be removed" sleep 2 done fi func_show_eval "(cd \$f_ex_an_ar_dir && $AR x \"\$f_ex_an_ar_oldlib\")" \ 'stat=$?; rm -f "$lockfile"; exit $stat' if test "$lock_old_archive_extraction" = yes; then $opt_dry_run || rm -f "$lockfile" fi if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then : else func_fatal_error "object name conflicts in archive: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib" fi } # func_extract_archives gentop oldlib ... func_extract_archives () { $opt_debug my_gentop="$1"; shift my_oldlibs=${1+"$@"} my_oldobjs="" my_xlib="" my_xabs="" my_xdir="" for my_xlib in $my_oldlibs; do # Extract the objects. case $my_xlib in [\\/]* | [A-Za-z]:[\\/]*) my_xabs="$my_xlib" ;; *) my_xabs=`pwd`"/$my_xlib" ;; esac func_basename "$my_xlib" my_xlib="$func_basename_result" my_xlib_u=$my_xlib while :; do case " $extracted_archives " in *" $my_xlib_u "*) func_arith $extracted_serial + 1 extracted_serial=$func_arith_result my_xlib_u=lt$extracted_serial-$my_xlib ;; *) break ;; esac done extracted_archives="$extracted_archives $my_xlib_u" my_xdir="$my_gentop/$my_xlib_u" func_mkdir_p "$my_xdir" case $host in *-darwin*) func_verbose "Extracting $my_xabs" # Do not bother doing anything if just a dry run $opt_dry_run || { darwin_orig_dir=`pwd` cd $my_xdir || exit $? darwin_archive=$my_xabs darwin_curdir=`pwd` darwin_base_archive=`basename "$darwin_archive"` darwin_arches=`$LIPO -info "$darwin_archive" 2>/dev/null | $GREP Architectures 2>/dev/null || true` if test -n "$darwin_arches"; then darwin_arches=`$ECHO "$darwin_arches" | $SED -e 's/.*are://'` darwin_arch= func_verbose "$darwin_base_archive has multiple architectures $darwin_arches" for darwin_arch in $darwin_arches ; do func_mkdir_p "unfat-$$/${darwin_base_archive}-${darwin_arch}" $LIPO -thin $darwin_arch -output "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" "${darwin_archive}" cd "unfat-$$/${darwin_base_archive}-${darwin_arch}" func_extract_an_archive "`pwd`" "${darwin_base_archive}" cd "$darwin_curdir" $RM "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" done # $darwin_arches ## Okay now we've a bunch of thin objects, gotta fatten them up :) darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print | $SED -e "$basename" | sort -u` darwin_file= darwin_files= for darwin_file in $darwin_filelist; do darwin_files=`find unfat-$$ -name $darwin_file -print | sort | $NL2SP` $LIPO -create -output "$darwin_file" $darwin_files done # $darwin_filelist $RM -rf unfat-$$ cd "$darwin_orig_dir" else cd $darwin_orig_dir func_extract_an_archive "$my_xdir" "$my_xabs" fi # $darwin_arches } # !$opt_dry_run ;; *) func_extract_an_archive "$my_xdir" "$my_xabs" ;; esac my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | sort | $NL2SP` done func_extract_archives_result="$my_oldobjs" } # func_emit_wrapper [arg=no] # # Emit a libtool wrapper script on stdout. # Don't directly open a file because we may want to # incorporate the script contents within a cygwin/mingw # wrapper executable. Must ONLY be called from within # func_mode_link because it depends on a number of variables # set therein. # # ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR # variable will take. If 'yes', then the emitted script # will assume that the directory in which it is stored is # the $objdir directory. This is a cygwin/mingw-specific # behavior. func_emit_wrapper () { func_emit_wrapper_arg1=${1-no} $ECHO "\ #! $SHELL # $output - temporary wrapper script for $objdir/$outputname # Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION # # The $output program cannot be directly executed until all the libtool # libraries that it depends on are installed. # # This wrapper script should never be moved out of the build directory. # If it is, it will not operate correctly. # Sed substitution that helps us do robust quoting. It backslashifies # metacharacters that are still active within double-quoted strings. sed_quote_subst='$sed_quote_subst' # Be Bourne compatible if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on \${1+\"\$@\"}, which # is contrary to our usage. Disable this feature. alias -g '\${1+\"\$@\"}'='\"\$@\"' setopt NO_GLOB_SUBST else case \`(set -o) 2>/dev/null\` in *posix*) set -o posix;; esac fi BIN_SH=xpg4; export BIN_SH # for Tru64 DUALCASE=1; export DUALCASE # for MKS sh # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH relink_command=\"$relink_command\" # This environment variable determines our operation mode. if test \"\$libtool_install_magic\" = \"$magic\"; then # install mode needs the following variables: generated_by_libtool_version='$macro_version' notinst_deplibs='$notinst_deplibs' else # When we are sourced in execute mode, \$file and \$ECHO are already set. if test \"\$libtool_execute_magic\" != \"$magic\"; then file=\"\$0\"" qECHO=`$ECHO "$ECHO" | $SED "$sed_quote_subst"` $ECHO "\ # A function that is used when there is no print builtin or printf. func_fallback_echo () { eval 'cat <<_LTECHO_EOF \$1 _LTECHO_EOF' } ECHO=\"$qECHO\" fi # Very basic option parsing. These options are (a) specific to # the libtool wrapper, (b) are identical between the wrapper # /script/ and the wrapper /executable/ which is used only on # windows platforms, and (c) all begin with the string "--lt-" # (application programs are unlikely to have options which match # this pattern). # # There are only two supported options: --lt-debug and # --lt-dump-script. There is, deliberately, no --lt-help. # # The first argument to this parsing function should be the # script's $0 value, followed by "$@". lt_option_debug= func_parse_lt_options () { lt_script_arg0=\$0 shift for lt_opt do case \"\$lt_opt\" in --lt-debug) lt_option_debug=1 ;; --lt-dump-script) lt_dump_D=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%/[^/]*$%%'\` test \"X\$lt_dump_D\" = \"X\$lt_script_arg0\" && lt_dump_D=. lt_dump_F=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%^.*/%%'\` cat \"\$lt_dump_D/\$lt_dump_F\" exit 0 ;; --lt-*) \$ECHO \"Unrecognized --lt- option: '\$lt_opt'\" 1>&2 exit 1 ;; esac done # Print the debug banner immediately: if test -n \"\$lt_option_debug\"; then echo \"${outputname}:${output}:\${LINENO}: libtool wrapper (GNU $PACKAGE$TIMESTAMP) $VERSION\" 1>&2 fi } # Used when --lt-debug. Prints its arguments to stdout # (redirection is the responsibility of the caller) func_lt_dump_args () { lt_dump_args_N=1; for lt_arg do \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[\$lt_dump_args_N]: \$lt_arg\" lt_dump_args_N=\`expr \$lt_dump_args_N + 1\` done } # Core function for launching the target application func_exec_program_core () { " case $host in # Backslashes separate directories on plain windows *-*-mingw | *-*-os2* | *-cegcc*) $ECHO "\ if test -n \"\$lt_option_debug\"; then \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[0]: \$progdir\\\\\$program\" 1>&2 func_lt_dump_args \${1+\"\$@\"} 1>&2 fi exec \"\$progdir\\\\\$program\" \${1+\"\$@\"} " ;; *) $ECHO "\ if test -n \"\$lt_option_debug\"; then \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[0]: \$progdir/\$program\" 1>&2 func_lt_dump_args \${1+\"\$@\"} 1>&2 fi exec \"\$progdir/\$program\" \${1+\"\$@\"} " ;; esac $ECHO "\ \$ECHO \"\$0: cannot exec \$program \$*\" 1>&2 exit 1 } # A function to encapsulate launching the target application # Strips options in the --lt-* namespace from \$@ and # launches target application with the remaining arguments. func_exec_program () { case \" \$* \" in *\\ --lt-*) for lt_wr_arg do case \$lt_wr_arg in --lt-*) ;; *) set x \"\$@\" \"\$lt_wr_arg\"; shift;; esac shift done ;; esac func_exec_program_core \${1+\"\$@\"} } # Parse options func_parse_lt_options \"\$0\" \${1+\"\$@\"} # Find the directory that this script lives in. thisdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*$%%'\` test \"x\$thisdir\" = \"x\$file\" && thisdir=. # Follow symbolic links until we get to the real thisdir. file=\`ls -ld \"\$file\" | $SED -n 's/.*-> //p'\` while test -n \"\$file\"; do destdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*\$%%'\` # If there was a directory component, then change thisdir. if test \"x\$destdir\" != \"x\$file\"; then case \"\$destdir\" in [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;; *) thisdir=\"\$thisdir/\$destdir\" ;; esac fi file=\`\$ECHO \"\$file\" | $SED 's%^.*/%%'\` file=\`ls -ld \"\$thisdir/\$file\" | $SED -n 's/.*-> //p'\` done # Usually 'no', except on cygwin/mingw when embedded into # the cwrapper. WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=$func_emit_wrapper_arg1 if test \"\$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\" = \"yes\"; then # special case for '.' if test \"\$thisdir\" = \".\"; then thisdir=\`pwd\` fi # remove .libs from thisdir case \"\$thisdir\" in *[\\\\/]$objdir ) thisdir=\`\$ECHO \"\$thisdir\" | $SED 's%[\\\\/][^\\\\/]*$%%'\` ;; $objdir ) thisdir=. ;; esac fi # Try to get the absolute directory name. absdir=\`cd \"\$thisdir\" && pwd\` test -n \"\$absdir\" && thisdir=\"\$absdir\" " if test "$fast_install" = yes; then $ECHO "\ program=lt-'$outputname'$exeext progdir=\"\$thisdir/$objdir\" if test ! -f \"\$progdir/\$program\" || { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | ${SED} 1q\`; \\ test \"X\$file\" != \"X\$progdir/\$program\"; }; then file=\"\$\$-\$program\" if test ! -d \"\$progdir\"; then $MKDIR \"\$progdir\" else $RM \"\$progdir/\$file\" fi" $ECHO "\ # relink executable if necessary if test -n \"\$relink_command\"; then if relink_command_output=\`eval \$relink_command 2>&1\`; then : else $ECHO \"\$relink_command_output\" >&2 $RM \"\$progdir/\$file\" exit 1 fi fi $MV \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null || { $RM \"\$progdir/\$program\"; $MV \"\$progdir/\$file\" \"\$progdir/\$program\"; } $RM \"\$progdir/\$file\" fi" else $ECHO "\ program='$outputname' progdir=\"\$thisdir/$objdir\" " fi $ECHO "\ if test -f \"\$progdir/\$program\"; then" # fixup the dll searchpath if we need to. # # Fix the DLL searchpath if we need to. Do this before prepending # to shlibpath, because on Windows, both are PATH and uninstalled # libraries must come first. if test -n "$dllsearchpath"; then $ECHO "\ # Add the dll search path components to the executable PATH PATH=$dllsearchpath:\$PATH " fi # Export our shlibpath_var if we have one. if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then $ECHO "\ # Add our own library path to $shlibpath_var $shlibpath_var=\"$temp_rpath\$$shlibpath_var\" # Some systems cannot cope with colon-terminated $shlibpath_var # The second colon is a workaround for a bug in BeOS R4 sed $shlibpath_var=\`\$ECHO \"\$$shlibpath_var\" | $SED 's/::*\$//'\` export $shlibpath_var " fi $ECHO "\ if test \"\$libtool_execute_magic\" != \"$magic\"; then # Run the actual program with our arguments. func_exec_program \${1+\"\$@\"} fi else # The program doesn't exist. \$ECHO \"\$0: error: \\\`\$progdir/\$program' does not exist\" 1>&2 \$ECHO \"This script is just a wrapper for \$program.\" 1>&2 \$ECHO \"See the $PACKAGE documentation for more information.\" 1>&2 exit 1 fi fi\ " } # func_emit_cwrapperexe_src # emit the source code for a wrapper executable on stdout # Must ONLY be called from within func_mode_link because # it depends on a number of variable set therein. func_emit_cwrapperexe_src () { cat < #include #ifdef _MSC_VER # include # include # include #else # include # include # ifdef __CYGWIN__ # include # endif #endif #include #include #include #include #include #include #include #include /* declarations of non-ANSI functions */ #if defined(__MINGW32__) # ifdef __STRICT_ANSI__ int _putenv (const char *); # endif #elif defined(__CYGWIN__) # ifdef __STRICT_ANSI__ char *realpath (const char *, char *); int putenv (char *); int setenv (const char *, const char *, int); # endif /* #elif defined (other platforms) ... */ #endif /* portability defines, excluding path handling macros */ #if defined(_MSC_VER) # define setmode _setmode # define stat _stat # define chmod _chmod # define getcwd _getcwd # define putenv _putenv # define S_IXUSR _S_IEXEC # ifndef _INTPTR_T_DEFINED # define _INTPTR_T_DEFINED # define intptr_t int # endif #elif defined(__MINGW32__) # define setmode _setmode # define stat _stat # define chmod _chmod # define getcwd _getcwd # define putenv _putenv #elif defined(__CYGWIN__) # define HAVE_SETENV # define FOPEN_WB "wb" /* #elif defined (other platforms) ... */ #endif #if defined(PATH_MAX) # define LT_PATHMAX PATH_MAX #elif defined(MAXPATHLEN) # define LT_PATHMAX MAXPATHLEN #else # define LT_PATHMAX 1024 #endif #ifndef S_IXOTH # define S_IXOTH 0 #endif #ifndef S_IXGRP # define S_IXGRP 0 #endif /* path handling portability macros */ #ifndef DIR_SEPARATOR # define DIR_SEPARATOR '/' # define PATH_SEPARATOR ':' #endif #if defined (_WIN32) || defined (__MSDOS__) || defined (__DJGPP__) || \ defined (__OS2__) # define HAVE_DOS_BASED_FILE_SYSTEM # define FOPEN_WB "wb" # ifndef DIR_SEPARATOR_2 # define DIR_SEPARATOR_2 '\\' # endif # ifndef PATH_SEPARATOR_2 # define PATH_SEPARATOR_2 ';' # endif #endif #ifndef DIR_SEPARATOR_2 # define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR) #else /* DIR_SEPARATOR_2 */ # define IS_DIR_SEPARATOR(ch) \ (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2)) #endif /* DIR_SEPARATOR_2 */ #ifndef PATH_SEPARATOR_2 # define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR) #else /* PATH_SEPARATOR_2 */ # define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2) #endif /* PATH_SEPARATOR_2 */ #ifndef FOPEN_WB # define FOPEN_WB "w" #endif #ifndef _O_BINARY # define _O_BINARY 0 #endif #define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type))) #define XFREE(stale) do { \ if (stale) { free ((void *) stale); stale = 0; } \ } while (0) #if defined(LT_DEBUGWRAPPER) static int lt_debug = 1; #else static int lt_debug = 0; #endif const char *program_name = "libtool-wrapper"; /* in case xstrdup fails */ void *xmalloc (size_t num); char *xstrdup (const char *string); const char *base_name (const char *name); char *find_executable (const char *wrapper); char *chase_symlinks (const char *pathspec); int make_executable (const char *path); int check_executable (const char *path); char *strendzap (char *str, const char *pat); void lt_debugprintf (const char *file, int line, const char *fmt, ...); void lt_fatal (const char *file, int line, const char *message, ...); static const char *nonnull (const char *s); static const char *nonempty (const char *s); void lt_setenv (const char *name, const char *value); char *lt_extend_str (const char *orig_value, const char *add, int to_end); void lt_update_exe_path (const char *name, const char *value); void lt_update_lib_path (const char *name, const char *value); char **prepare_spawn (char **argv); void lt_dump_script (FILE *f); EOF cat <= 0) && (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))) return 1; else return 0; } int make_executable (const char *path) { int rval = 0; struct stat st; lt_debugprintf (__FILE__, __LINE__, "(make_executable): %s\n", nonempty (path)); if ((!path) || (!*path)) return 0; if (stat (path, &st) >= 0) { rval = chmod (path, st.st_mode | S_IXOTH | S_IXGRP | S_IXUSR); } return rval; } /* Searches for the full path of the wrapper. Returns newly allocated full path name if found, NULL otherwise Does not chase symlinks, even on platforms that support them. */ char * find_executable (const char *wrapper) { int has_slash = 0; const char *p; const char *p_next; /* static buffer for getcwd */ char tmp[LT_PATHMAX + 1]; int tmp_len; char *concat_name; lt_debugprintf (__FILE__, __LINE__, "(find_executable): %s\n", nonempty (wrapper)); if ((wrapper == NULL) || (*wrapper == '\0')) return NULL; /* Absolute path? */ #if defined (HAVE_DOS_BASED_FILE_SYSTEM) if (isalpha ((unsigned char) wrapper[0]) && wrapper[1] == ':') { concat_name = xstrdup (wrapper); if (check_executable (concat_name)) return concat_name; XFREE (concat_name); } else { #endif if (IS_DIR_SEPARATOR (wrapper[0])) { concat_name = xstrdup (wrapper); if (check_executable (concat_name)) return concat_name; XFREE (concat_name); } #if defined (HAVE_DOS_BASED_FILE_SYSTEM) } #endif for (p = wrapper; *p; p++) if (*p == '/') { has_slash = 1; break; } if (!has_slash) { /* no slashes; search PATH */ const char *path = getenv ("PATH"); if (path != NULL) { for (p = path; *p; p = p_next) { const char *q; size_t p_len; for (q = p; *q; q++) if (IS_PATH_SEPARATOR (*q)) break; p_len = q - p; p_next = (*q == '\0' ? q : q + 1); if (p_len == 0) { /* empty path: current directory */ if (getcwd (tmp, LT_PATHMAX) == NULL) lt_fatal (__FILE__, __LINE__, "getcwd failed: %s", nonnull (strerror (errno))); tmp_len = strlen (tmp); concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); memcpy (concat_name, tmp, tmp_len); concat_name[tmp_len] = '/'; strcpy (concat_name + tmp_len + 1, wrapper); } else { concat_name = XMALLOC (char, p_len + 1 + strlen (wrapper) + 1); memcpy (concat_name, p, p_len); concat_name[p_len] = '/'; strcpy (concat_name + p_len + 1, wrapper); } if (check_executable (concat_name)) return concat_name; XFREE (concat_name); } } /* not found in PATH; assume curdir */ } /* Relative path | not found in path: prepend cwd */ if (getcwd (tmp, LT_PATHMAX) == NULL) lt_fatal (__FILE__, __LINE__, "getcwd failed: %s", nonnull (strerror (errno))); tmp_len = strlen (tmp); concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); memcpy (concat_name, tmp, tmp_len); concat_name[tmp_len] = '/'; strcpy (concat_name + tmp_len + 1, wrapper); if (check_executable (concat_name)) return concat_name; XFREE (concat_name); return NULL; } char * chase_symlinks (const char *pathspec) { #ifndef S_ISLNK return xstrdup (pathspec); #else char buf[LT_PATHMAX]; struct stat s; char *tmp_pathspec = xstrdup (pathspec); char *p; int has_symlinks = 0; while (strlen (tmp_pathspec) && !has_symlinks) { lt_debugprintf (__FILE__, __LINE__, "checking path component for symlinks: %s\n", tmp_pathspec); if (lstat (tmp_pathspec, &s) == 0) { if (S_ISLNK (s.st_mode) != 0) { has_symlinks = 1; break; } /* search backwards for last DIR_SEPARATOR */ p = tmp_pathspec + strlen (tmp_pathspec) - 1; while ((p > tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) p--; if ((p == tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) { /* no more DIR_SEPARATORS left */ break; } *p = '\0'; } else { lt_fatal (__FILE__, __LINE__, "error accessing file \"%s\": %s", tmp_pathspec, nonnull (strerror (errno))); } } XFREE (tmp_pathspec); if (!has_symlinks) { return xstrdup (pathspec); } tmp_pathspec = realpath (pathspec, buf); if (tmp_pathspec == 0) { lt_fatal (__FILE__, __LINE__, "could not follow symlinks for %s", pathspec); } return xstrdup (tmp_pathspec); #endif } char * strendzap (char *str, const char *pat) { size_t len, patlen; assert (str != NULL); assert (pat != NULL); len = strlen (str); patlen = strlen (pat); if (patlen <= len) { str += len - patlen; if (strcmp (str, pat) == 0) *str = '\0'; } return str; } void lt_debugprintf (const char *file, int line, const char *fmt, ...) { va_list args; if (lt_debug) { (void) fprintf (stderr, "%s:%s:%d: ", program_name, file, line); va_start (args, fmt); (void) vfprintf (stderr, fmt, args); va_end (args); } } static void lt_error_core (int exit_status, const char *file, int line, const char *mode, const char *message, va_list ap) { fprintf (stderr, "%s:%s:%d: %s: ", program_name, file, line, mode); vfprintf (stderr, message, ap); fprintf (stderr, ".\n"); if (exit_status >= 0) exit (exit_status); } void lt_fatal (const char *file, int line, const char *message, ...) { va_list ap; va_start (ap, message); lt_error_core (EXIT_FAILURE, file, line, "FATAL", message, ap); va_end (ap); } static const char * nonnull (const char *s) { return s ? s : "(null)"; } static const char * nonempty (const char *s) { return (s && !*s) ? "(empty)" : nonnull (s); } void lt_setenv (const char *name, const char *value) { lt_debugprintf (__FILE__, __LINE__, "(lt_setenv) setting '%s' to '%s'\n", nonnull (name), nonnull (value)); { #ifdef HAVE_SETENV /* always make a copy, for consistency with !HAVE_SETENV */ char *str = xstrdup (value); setenv (name, str, 1); #else int len = strlen (name) + 1 + strlen (value) + 1; char *str = XMALLOC (char, len); sprintf (str, "%s=%s", name, value); if (putenv (str) != EXIT_SUCCESS) { XFREE (str); } #endif } } char * lt_extend_str (const char *orig_value, const char *add, int to_end) { char *new_value; if (orig_value && *orig_value) { int orig_value_len = strlen (orig_value); int add_len = strlen (add); new_value = XMALLOC (char, add_len + orig_value_len + 1); if (to_end) { strcpy (new_value, orig_value); strcpy (new_value + orig_value_len, add); } else { strcpy (new_value, add); strcpy (new_value + add_len, orig_value); } } else { new_value = xstrdup (add); } return new_value; } void lt_update_exe_path (const char *name, const char *value) { lt_debugprintf (__FILE__, __LINE__, "(lt_update_exe_path) modifying '%s' by prepending '%s'\n", nonnull (name), nonnull (value)); if (name && *name && value && *value) { char *new_value = lt_extend_str (getenv (name), value, 0); /* some systems can't cope with a ':'-terminated path #' */ int len = strlen (new_value); while (((len = strlen (new_value)) > 0) && IS_PATH_SEPARATOR (new_value[len-1])) { new_value[len-1] = '\0'; } lt_setenv (name, new_value); XFREE (new_value); } } void lt_update_lib_path (const char *name, const char *value) { lt_debugprintf (__FILE__, __LINE__, "(lt_update_lib_path) modifying '%s' by prepending '%s'\n", nonnull (name), nonnull (value)); if (name && *name && value && *value) { char *new_value = lt_extend_str (getenv (name), value, 0); lt_setenv (name, new_value); XFREE (new_value); } } EOF case $host_os in mingw*) cat <<"EOF" /* Prepares an argument vector before calling spawn(). Note that spawn() does not by itself call the command interpreter (getenv ("COMSPEC") != NULL ? getenv ("COMSPEC") : ({ OSVERSIONINFO v; v.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); GetVersionEx(&v); v.dwPlatformId == VER_PLATFORM_WIN32_NT; }) ? "cmd.exe" : "command.com"). Instead it simply concatenates the arguments, separated by ' ', and calls CreateProcess(). We must quote the arguments since Win32 CreateProcess() interprets characters like ' ', '\t', '\\', '"' (but not '<' and '>') in a special way: - Space and tab are interpreted as delimiters. They are not treated as delimiters if they are surrounded by double quotes: "...". - Unescaped double quotes are removed from the input. Their only effect is that within double quotes, space and tab are treated like normal characters. - Backslashes not followed by double quotes are not special. - But 2*n+1 backslashes followed by a double quote become n backslashes followed by a double quote (n >= 0): \" -> " \\\" -> \" \\\\\" -> \\" */ #define SHELL_SPECIAL_CHARS "\"\\ \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" #define SHELL_SPACE_CHARS " \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" char ** prepare_spawn (char **argv) { size_t argc; char **new_argv; size_t i; /* Count number of arguments. */ for (argc = 0; argv[argc] != NULL; argc++) ; /* Allocate new argument vector. */ new_argv = XMALLOC (char *, argc + 1); /* Put quoted arguments into the new argument vector. */ for (i = 0; i < argc; i++) { const char *string = argv[i]; if (string[0] == '\0') new_argv[i] = xstrdup ("\"\""); else if (strpbrk (string, SHELL_SPECIAL_CHARS) != NULL) { int quote_around = (strpbrk (string, SHELL_SPACE_CHARS) != NULL); size_t length; unsigned int backslashes; const char *s; char *quoted_string; char *p; length = 0; backslashes = 0; if (quote_around) length++; for (s = string; *s != '\0'; s++) { char c = *s; if (c == '"') length += backslashes + 1; length++; if (c == '\\') backslashes++; else backslashes = 0; } if (quote_around) length += backslashes + 1; quoted_string = XMALLOC (char, length + 1); p = quoted_string; backslashes = 0; if (quote_around) *p++ = '"'; for (s = string; *s != '\0'; s++) { char c = *s; if (c == '"') { unsigned int j; for (j = backslashes + 1; j > 0; j--) *p++ = '\\'; } *p++ = c; if (c == '\\') backslashes++; else backslashes = 0; } if (quote_around) { unsigned int j; for (j = backslashes; j > 0; j--) *p++ = '\\'; *p++ = '"'; } *p = '\0'; new_argv[i] = quoted_string; } else new_argv[i] = (char *) string; } new_argv[argc] = NULL; return new_argv; } EOF ;; esac cat <<"EOF" void lt_dump_script (FILE* f) { EOF func_emit_wrapper yes | $SED -n -e ' s/^\(.\{79\}\)\(..*\)/\1\ \2/ h s/\([\\"]\)/\\\1/g s/$/\\n/ s/\([^\n]*\).*/ fputs ("\1", f);/p g D' cat <<"EOF" } EOF } # end: func_emit_cwrapperexe_src # func_win32_import_lib_p ARG # True if ARG is an import lib, as indicated by $file_magic_cmd func_win32_import_lib_p () { $opt_debug case `eval $file_magic_cmd \"\$1\" 2>/dev/null | $SED -e 10q` in *import*) : ;; *) false ;; esac } # func_mode_link arg... func_mode_link () { $opt_debug case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) # It is impossible to link a dll without this setting, and # we shouldn't force the makefile maintainer to figure out # which system we are compiling for in order to pass an extra # flag for every libtool invocation. # allow_undefined=no # FIXME: Unfortunately, there are problems with the above when trying # to make a dll which has undefined symbols, in which case not # even a static library is built. For now, we need to specify # -no-undefined on the libtool link line when we can be certain # that all symbols are satisfied, otherwise we get a static library. allow_undefined=yes ;; *) allow_undefined=yes ;; esac libtool_args=$nonopt base_compile="$nonopt $@" compile_command=$nonopt finalize_command=$nonopt compile_rpath= finalize_rpath= compile_shlibpath= finalize_shlibpath= convenience= old_convenience= deplibs= old_deplibs= compiler_flags= linker_flags= dllsearchpath= lib_search_path=`pwd` inst_prefix_dir= new_inherited_linker_flags= avoid_version=no bindir= dlfiles= dlprefiles= dlself=no export_dynamic=no export_symbols= export_symbols_regex= generated= libobjs= ltlibs= module=no no_install=no objs= non_pic_objects= precious_files_regex= prefer_static_libs=no preload=no prev= prevarg= release= rpath= xrpath= perm_rpath= temp_rpath= thread_safe=no vinfo= vinfo_number=no weak_libs= single_module="${wl}-single_module" func_infer_tag $base_compile # We need to know -static, to get the right output filenames. for arg do case $arg in -shared) test "$build_libtool_libs" != yes && \ func_fatal_configuration "can not build a shared library" build_old_libs=no break ;; -all-static | -static | -static-libtool-libs) case $arg in -all-static) if test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then func_warning "complete static linking is impossible in this configuration" fi if test -n "$link_static_flag"; then dlopen_self=$dlopen_self_static fi prefer_static_libs=yes ;; -static) if test -z "$pic_flag" && test -n "$link_static_flag"; then dlopen_self=$dlopen_self_static fi prefer_static_libs=built ;; -static-libtool-libs) if test -z "$pic_flag" && test -n "$link_static_flag"; then dlopen_self=$dlopen_self_static fi prefer_static_libs=yes ;; esac build_libtool_libs=no build_old_libs=yes break ;; esac done # See if our shared archives depend on static archives. test -n "$old_archive_from_new_cmds" && build_old_libs=yes # Go through the arguments, transforming them on the way. while test "$#" -gt 0; do arg="$1" shift func_quote_for_eval "$arg" qarg=$func_quote_for_eval_unquoted_result func_append libtool_args " $func_quote_for_eval_result" # If the previous option needs an argument, assign it. if test -n "$prev"; then case $prev in output) func_append compile_command " @OUTPUT@" func_append finalize_command " @OUTPUT@" ;; esac case $prev in bindir) bindir="$arg" prev= continue ;; dlfiles|dlprefiles) if test "$preload" = no; then # Add the symbol object into the linking commands. func_append compile_command " @SYMFILE@" func_append finalize_command " @SYMFILE@" preload=yes fi case $arg in *.la | *.lo) ;; # We handle these cases below. force) if test "$dlself" = no; then dlself=needless export_dynamic=yes fi prev= continue ;; self) if test "$prev" = dlprefiles; then dlself=yes elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then dlself=yes else dlself=needless export_dynamic=yes fi prev= continue ;; *) if test "$prev" = dlfiles; then func_append dlfiles " $arg" else func_append dlprefiles " $arg" fi prev= continue ;; esac ;; expsyms) export_symbols="$arg" test -f "$arg" \ || func_fatal_error "symbol file \`$arg' does not exist" prev= continue ;; expsyms_regex) export_symbols_regex="$arg" prev= continue ;; framework) case $host in *-*-darwin*) case "$deplibs " in *" $qarg.ltframework "*) ;; *) func_append deplibs " $qarg.ltframework" # this is fixed later ;; esac ;; esac prev= continue ;; inst_prefix) inst_prefix_dir="$arg" prev= continue ;; objectlist) if test -f "$arg"; then save_arg=$arg moreargs= for fil in `cat "$save_arg"` do # func_append moreargs " $fil" arg=$fil # A libtool-controlled object. # Check to see that this really is a libtool object. if func_lalib_unsafe_p "$arg"; then pic_object= non_pic_object= # Read the .lo file func_source "$arg" if test -z "$pic_object" || test -z "$non_pic_object" || test "$pic_object" = none && test "$non_pic_object" = none; then func_fatal_error "cannot find name of object for \`$arg'" fi # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir="$func_dirname_result" if test "$pic_object" != none; then # Prepend the subdirectory the object is found in. pic_object="$xdir$pic_object" if test "$prev" = dlfiles; then if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then func_append dlfiles " $pic_object" prev= continue else # If libtool objects are unsupported, then we need to preload. prev=dlprefiles fi fi # CHECK ME: I think I busted this. -Ossama if test "$prev" = dlprefiles; then # Preload the old-style object. func_append dlprefiles " $pic_object" prev= fi # A PIC object. func_append libobjs " $pic_object" arg="$pic_object" fi # Non-PIC object. if test "$non_pic_object" != none; then # Prepend the subdirectory the object is found in. non_pic_object="$xdir$non_pic_object" # A standard non-PIC object func_append non_pic_objects " $non_pic_object" if test -z "$pic_object" || test "$pic_object" = none ; then arg="$non_pic_object" fi else # If the PIC object exists, use it instead. # $xdir was prepended to $pic_object above. non_pic_object="$pic_object" func_append non_pic_objects " $non_pic_object" fi else # Only an error if not doing a dry-run. if $opt_dry_run; then # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir="$func_dirname_result" func_lo2o "$arg" pic_object=$xdir$objdir/$func_lo2o_result non_pic_object=$xdir$func_lo2o_result func_append libobjs " $pic_object" func_append non_pic_objects " $non_pic_object" else func_fatal_error "\`$arg' is not a valid libtool object" fi fi done else func_fatal_error "link input file \`$arg' does not exist" fi arg=$save_arg prev= continue ;; precious_regex) precious_files_regex="$arg" prev= continue ;; release) release="-$arg" prev= continue ;; rpath | xrpath) # We need an absolute path. case $arg in [\\/]* | [A-Za-z]:[\\/]*) ;; *) func_fatal_error "only absolute run-paths are allowed" ;; esac if test "$prev" = rpath; then case "$rpath " in *" $arg "*) ;; *) func_append rpath " $arg" ;; esac else case "$xrpath " in *" $arg "*) ;; *) func_append xrpath " $arg" ;; esac fi prev= continue ;; shrext) shrext_cmds="$arg" prev= continue ;; weak) func_append weak_libs " $arg" prev= continue ;; xcclinker) func_append linker_flags " $qarg" func_append compiler_flags " $qarg" prev= func_append compile_command " $qarg" func_append finalize_command " $qarg" continue ;; xcompiler) func_append compiler_flags " $qarg" prev= func_append compile_command " $qarg" func_append finalize_command " $qarg" continue ;; xlinker) func_append linker_flags " $qarg" func_append compiler_flags " $wl$qarg" prev= func_append compile_command " $wl$qarg" func_append finalize_command " $wl$qarg" continue ;; *) eval "$prev=\"\$arg\"" prev= continue ;; esac fi # test -n "$prev" prevarg="$arg" case $arg in -all-static) if test -n "$link_static_flag"; then # See comment for -static flag below, for more details. func_append compile_command " $link_static_flag" func_append finalize_command " $link_static_flag" fi continue ;; -allow-undefined) # FIXME: remove this flag sometime in the future. func_fatal_error "\`-allow-undefined' must not be used because it is the default" ;; -avoid-version) avoid_version=yes continue ;; -bindir) prev=bindir continue ;; -dlopen) prev=dlfiles continue ;; -dlpreopen) prev=dlprefiles continue ;; -export-dynamic) export_dynamic=yes continue ;; -export-symbols | -export-symbols-regex) if test -n "$export_symbols" || test -n "$export_symbols_regex"; then func_fatal_error "more than one -exported-symbols argument is not allowed" fi if test "X$arg" = "X-export-symbols"; then prev=expsyms else prev=expsyms_regex fi continue ;; -framework) prev=framework continue ;; -inst-prefix-dir) prev=inst_prefix continue ;; # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:* # so, if we see these flags be careful not to treat them like -L -L[A-Z][A-Z]*:*) case $with_gcc/$host in no/*-*-irix* | /*-*-irix*) func_append compile_command " $arg" func_append finalize_command " $arg" ;; esac continue ;; -L*) func_stripname "-L" '' "$arg" if test -z "$func_stripname_result"; then if test "$#" -gt 0; then func_fatal_error "require no space between \`-L' and \`$1'" else func_fatal_error "need path for \`-L' option" fi fi func_resolve_sysroot "$func_stripname_result" dir=$func_resolve_sysroot_result # We need an absolute path. case $dir in [\\/]* | [A-Za-z]:[\\/]*) ;; *) absdir=`cd "$dir" && pwd` test -z "$absdir" && \ func_fatal_error "cannot determine absolute directory name of \`$dir'" dir="$absdir" ;; esac case "$deplibs " in *" -L$dir "* | *" $arg "*) # Will only happen for absolute or sysroot arguments ;; *) # Preserve sysroot, but never include relative directories case $dir in [\\/]* | [A-Za-z]:[\\/]* | =*) func_append deplibs " $arg" ;; *) func_append deplibs " -L$dir" ;; esac func_append lib_search_path " $dir" ;; esac case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) testbindir=`$ECHO "$dir" | $SED 's*/lib$*/bin*'` case :$dllsearchpath: in *":$dir:"*) ;; ::) dllsearchpath=$dir;; *) func_append dllsearchpath ":$dir";; esac case :$dllsearchpath: in *":$testbindir:"*) ;; ::) dllsearchpath=$testbindir;; *) func_append dllsearchpath ":$testbindir";; esac ;; esac continue ;; -l*) if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc* | *-*-haiku*) # These systems don't actually have a C or math library (as such) continue ;; *-*-os2*) # These systems don't actually have a C library (as such) test "X$arg" = "X-lc" && continue ;; *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) # Do not include libc due to us having libc/libc_r. test "X$arg" = "X-lc" && continue ;; *-*-rhapsody* | *-*-darwin1.[012]) # Rhapsody C and math libraries are in the System framework func_append deplibs " System.ltframework" continue ;; *-*-sco3.2v5* | *-*-sco5v6*) # Causes problems with __ctype test "X$arg" = "X-lc" && continue ;; *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) # Compiler inserts libc in the correct place for threads to work test "X$arg" = "X-lc" && continue ;; esac elif test "X$arg" = "X-lc_r"; then case $host in *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) # Do not include libc_r directly, use -pthread flag. continue ;; esac fi func_append deplibs " $arg" continue ;; -module) module=yes continue ;; # Tru64 UNIX uses -model [arg] to determine the layout of C++ # classes, name mangling, and exception handling. # Darwin uses the -arch flag to determine output architecture. -model|-arch|-isysroot|--sysroot) func_append compiler_flags " $arg" func_append compile_command " $arg" func_append finalize_command " $arg" prev=xcompiler continue ;; -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \ |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*) func_append compiler_flags " $arg" func_append compile_command " $arg" func_append finalize_command " $arg" case "$new_inherited_linker_flags " in *" $arg "*) ;; * ) func_append new_inherited_linker_flags " $arg" ;; esac continue ;; -multi_module) single_module="${wl}-multi_module" continue ;; -no-fast-install) fast_install=no continue ;; -no-install) case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*) # The PATH hackery in wrapper scripts is required on Windows # and Darwin in order for the loader to find any dlls it needs. func_warning "\`-no-install' is ignored for $host" func_warning "assuming \`-no-fast-install' instead" fast_install=no ;; *) no_install=yes ;; esac continue ;; -no-undefined) allow_undefined=no continue ;; -objectlist) prev=objectlist continue ;; -o) prev=output ;; -precious-files-regex) prev=precious_regex continue ;; -release) prev=release continue ;; -rpath) prev=rpath continue ;; -R) prev=xrpath continue ;; -R*) func_stripname '-R' '' "$arg" dir=$func_stripname_result # We need an absolute path. case $dir in [\\/]* | [A-Za-z]:[\\/]*) ;; =*) func_stripname '=' '' "$dir" dir=$lt_sysroot$func_stripname_result ;; *) func_fatal_error "only absolute run-paths are allowed" ;; esac case "$xrpath " in *" $dir "*) ;; *) func_append xrpath " $dir" ;; esac continue ;; -shared) # The effects of -shared are defined in a previous loop. continue ;; -shrext) prev=shrext continue ;; -static | -static-libtool-libs) # The effects of -static are defined in a previous loop. # We used to do the same as -all-static on platforms that # didn't have a PIC flag, but the assumption that the effects # would be equivalent was wrong. It would break on at least # Digital Unix and AIX. continue ;; -thread-safe) thread_safe=yes continue ;; -version-info) prev=vinfo continue ;; -version-number) prev=vinfo vinfo_number=yes continue ;; -weak) prev=weak continue ;; -Wc,*) func_stripname '-Wc,' '' "$arg" args=$func_stripname_result arg= save_ifs="$IFS"; IFS=',' for flag in $args; do IFS="$save_ifs" func_quote_for_eval "$flag" func_append arg " $func_quote_for_eval_result" func_append compiler_flags " $func_quote_for_eval_result" done IFS="$save_ifs" func_stripname ' ' '' "$arg" arg=$func_stripname_result ;; -Wl,*) func_stripname '-Wl,' '' "$arg" args=$func_stripname_result arg= save_ifs="$IFS"; IFS=',' for flag in $args; do IFS="$save_ifs" func_quote_for_eval "$flag" func_append arg " $wl$func_quote_for_eval_result" func_append compiler_flags " $wl$func_quote_for_eval_result" func_append linker_flags " $func_quote_for_eval_result" done IFS="$save_ifs" func_stripname ' ' '' "$arg" arg=$func_stripname_result ;; -Xcompiler) prev=xcompiler continue ;; -Xlinker) prev=xlinker continue ;; -XCClinker) prev=xcclinker continue ;; # -msg_* for osf cc -msg_*) func_quote_for_eval "$arg" arg="$func_quote_for_eval_result" ;; # Flags to be passed through unchanged, with rationale: # -64, -mips[0-9] enable 64-bit mode for the SGI compiler # -r[0-9][0-9]* specify processor for the SGI compiler # -xarch=*, -xtarget=* enable 64-bit mode for the Sun compiler # +DA*, +DD* enable 64-bit mode for the HP compiler # -q* compiler args for the IBM compiler # -m*, -t[45]*, -txscale* architecture-specific flags for GCC # -F/path path to uninstalled frameworks, gcc on darwin # -p, -pg, --coverage, -fprofile-* profiling flags for GCC # @file GCC response files # -tp=* Portland pgcc target processor selection # --sysroot=* for sysroot support # -O*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \ -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \ -O*|-flto*|-fwhopr*|-fuse-linker-plugin) func_quote_for_eval "$arg" arg="$func_quote_for_eval_result" func_append compile_command " $arg" func_append finalize_command " $arg" func_append compiler_flags " $arg" continue ;; # Some other compiler flag. -* | +*) func_quote_for_eval "$arg" arg="$func_quote_for_eval_result" ;; *.$objext) # A standard object. func_append objs " $arg" ;; *.lo) # A libtool-controlled object. # Check to see that this really is a libtool object. if func_lalib_unsafe_p "$arg"; then pic_object= non_pic_object= # Read the .lo file func_source "$arg" if test -z "$pic_object" || test -z "$non_pic_object" || test "$pic_object" = none && test "$non_pic_object" = none; then func_fatal_error "cannot find name of object for \`$arg'" fi # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir="$func_dirname_result" if test "$pic_object" != none; then # Prepend the subdirectory the object is found in. pic_object="$xdir$pic_object" if test "$prev" = dlfiles; then if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then func_append dlfiles " $pic_object" prev= continue else # If libtool objects are unsupported, then we need to preload. prev=dlprefiles fi fi # CHECK ME: I think I busted this. -Ossama if test "$prev" = dlprefiles; then # Preload the old-style object. func_append dlprefiles " $pic_object" prev= fi # A PIC object. func_append libobjs " $pic_object" arg="$pic_object" fi # Non-PIC object. if test "$non_pic_object" != none; then # Prepend the subdirectory the object is found in. non_pic_object="$xdir$non_pic_object" # A standard non-PIC object func_append non_pic_objects " $non_pic_object" if test -z "$pic_object" || test "$pic_object" = none ; then arg="$non_pic_object" fi else # If the PIC object exists, use it instead. # $xdir was prepended to $pic_object above. non_pic_object="$pic_object" func_append non_pic_objects " $non_pic_object" fi else # Only an error if not doing a dry-run. if $opt_dry_run; then # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir="$func_dirname_result" func_lo2o "$arg" pic_object=$xdir$objdir/$func_lo2o_result non_pic_object=$xdir$func_lo2o_result func_append libobjs " $pic_object" func_append non_pic_objects " $non_pic_object" else func_fatal_error "\`$arg' is not a valid libtool object" fi fi ;; *.$libext) # An archive. func_append deplibs " $arg" func_append old_deplibs " $arg" continue ;; *.la) # A libtool-controlled library. func_resolve_sysroot "$arg" if test "$prev" = dlfiles; then # This library was specified with -dlopen. func_append dlfiles " $func_resolve_sysroot_result" prev= elif test "$prev" = dlprefiles; then # The library was specified with -dlpreopen. func_append dlprefiles " $func_resolve_sysroot_result" prev= else func_append deplibs " $func_resolve_sysroot_result" fi continue ;; # Some other compiler argument. *) # Unknown arguments in both finalize_command and compile_command need # to be aesthetically quoted because they are evaled later. func_quote_for_eval "$arg" arg="$func_quote_for_eval_result" ;; esac # arg # Now actually substitute the argument into the commands. if test -n "$arg"; then func_append compile_command " $arg" func_append finalize_command " $arg" fi done # argument parsing loop test -n "$prev" && \ func_fatal_help "the \`$prevarg' option requires an argument" if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then eval arg=\"$export_dynamic_flag_spec\" func_append compile_command " $arg" func_append finalize_command " $arg" fi oldlibs= # calculate the name of the file, without its directory func_basename "$output" outputname="$func_basename_result" libobjs_save="$libobjs" if test -n "$shlibpath_var"; then # get the directories listed in $shlibpath_var eval shlib_search_path=\`\$ECHO \"\${$shlibpath_var}\" \| \$SED \'s/:/ /g\'\` else shlib_search_path= fi eval sys_lib_search_path=\"$sys_lib_search_path_spec\" eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\" func_dirname "$output" "/" "" output_objdir="$func_dirname_result$objdir" func_to_tool_file "$output_objdir/" tool_output_objdir=$func_to_tool_file_result # Create the object directory. func_mkdir_p "$output_objdir" # Determine the type of output case $output in "") func_fatal_help "you must specify an output file" ;; *.$libext) linkmode=oldlib ;; *.lo | *.$objext) linkmode=obj ;; *.la) linkmode=lib ;; *) linkmode=prog ;; # Anything else should be a program. esac specialdeplibs= libs= # Find all interdependent deplibs by searching for libraries # that are linked more than once (e.g. -la -lb -la) for deplib in $deplibs; do if $opt_preserve_dup_deps ; then case "$libs " in *" $deplib "*) func_append specialdeplibs " $deplib" ;; esac fi func_append libs " $deplib" done if test "$linkmode" = lib; then libs="$predeps $libs $compiler_lib_search_path $postdeps" # Compute libraries that are listed more than once in $predeps # $postdeps and mark them as special (i.e., whose duplicates are # not to be eliminated). pre_post_deps= if $opt_duplicate_compiler_generated_deps; then for pre_post_dep in $predeps $postdeps; do case "$pre_post_deps " in *" $pre_post_dep "*) func_append specialdeplibs " $pre_post_deps" ;; esac func_append pre_post_deps " $pre_post_dep" done fi pre_post_deps= fi deplibs= newdependency_libs= newlib_search_path= need_relink=no # whether we're linking any uninstalled libtool libraries notinst_deplibs= # not-installed libtool libraries notinst_path= # paths that contain not-installed libtool libraries case $linkmode in lib) passes="conv dlpreopen link" for file in $dlfiles $dlprefiles; do case $file in *.la) ;; *) func_fatal_help "libraries can \`-dlopen' only libtool libraries: $file" ;; esac done ;; prog) compile_deplibs= finalize_deplibs= alldeplibs=no newdlfiles= newdlprefiles= passes="conv scan dlopen dlpreopen link" ;; *) passes="conv" ;; esac for pass in $passes; do # The preopen pass in lib mode reverses $deplibs; put it back here # so that -L comes before libs that need it for instance... if test "$linkmode,$pass" = "lib,link"; then ## FIXME: Find the place where the list is rebuilt in the wrong ## order, and fix it there properly tmp_deplibs= for deplib in $deplibs; do tmp_deplibs="$deplib $tmp_deplibs" done deplibs="$tmp_deplibs" fi if test "$linkmode,$pass" = "lib,link" || test "$linkmode,$pass" = "prog,scan"; then libs="$deplibs" deplibs= fi if test "$linkmode" = prog; then case $pass in dlopen) libs="$dlfiles" ;; dlpreopen) libs="$dlprefiles" ;; link) libs="$deplibs %DEPLIBS%" test "X$link_all_deplibs" != Xno && libs="$libs $dependency_libs" ;; esac fi if test "$linkmode,$pass" = "lib,dlpreopen"; then # Collect and forward deplibs of preopened libtool libs for lib in $dlprefiles; do # Ignore non-libtool-libs dependency_libs= func_resolve_sysroot "$lib" case $lib in *.la) func_source "$func_resolve_sysroot_result" ;; esac # Collect preopened libtool deplibs, except any this library # has declared as weak libs for deplib in $dependency_libs; do func_basename "$deplib" deplib_base=$func_basename_result case " $weak_libs " in *" $deplib_base "*) ;; *) func_append deplibs " $deplib" ;; esac done done libs="$dlprefiles" fi if test "$pass" = dlopen; then # Collect dlpreopened libraries save_deplibs="$deplibs" deplibs= fi for deplib in $libs; do lib= found=no case $deplib in -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \ |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*) if test "$linkmode,$pass" = "prog,link"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else func_append compiler_flags " $deplib" if test "$linkmode" = lib ; then case "$new_inherited_linker_flags " in *" $deplib "*) ;; * ) func_append new_inherited_linker_flags " $deplib" ;; esac fi fi continue ;; -l*) if test "$linkmode" != lib && test "$linkmode" != prog; then func_warning "\`-l' is ignored for archives/objects" continue fi func_stripname '-l' '' "$deplib" name=$func_stripname_result if test "$linkmode" = lib; then searchdirs="$newlib_search_path $lib_search_path $compiler_lib_search_dirs $sys_lib_search_path $shlib_search_path" else searchdirs="$newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path" fi for searchdir in $searchdirs; do for search_ext in .la $std_shrext .so .a; do # Search the libtool library lib="$searchdir/lib${name}${search_ext}" if test -f "$lib"; then if test "$search_ext" = ".la"; then found=yes else found=no fi break 2 fi done done if test "$found" != yes; then # deplib doesn't seem to be a libtool library if test "$linkmode,$pass" = "prog,link"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else deplibs="$deplib $deplibs" test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" fi continue else # deplib is a libtool library # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib, # We need to do some special things here, and not later. if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then case " $predeps $postdeps " in *" $deplib "*) if func_lalib_p "$lib"; then library_names= old_library= func_source "$lib" for l in $old_library $library_names; do ll="$l" done if test "X$ll" = "X$old_library" ; then # only static version available found=no func_dirname "$lib" "" "." ladir="$func_dirname_result" lib=$ladir/$old_library if test "$linkmode,$pass" = "prog,link"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else deplibs="$deplib $deplibs" test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" fi continue fi fi ;; *) ;; esac fi fi ;; # -l *.ltframework) if test "$linkmode,$pass" = "prog,link"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else deplibs="$deplib $deplibs" if test "$linkmode" = lib ; then case "$new_inherited_linker_flags " in *" $deplib "*) ;; * ) func_append new_inherited_linker_flags " $deplib" ;; esac fi fi continue ;; -L*) case $linkmode in lib) deplibs="$deplib $deplibs" test "$pass" = conv && continue newdependency_libs="$deplib $newdependency_libs" func_stripname '-L' '' "$deplib" func_resolve_sysroot "$func_stripname_result" func_append newlib_search_path " $func_resolve_sysroot_result" ;; prog) if test "$pass" = conv; then deplibs="$deplib $deplibs" continue fi if test "$pass" = scan; then deplibs="$deplib $deplibs" else compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" fi func_stripname '-L' '' "$deplib" func_resolve_sysroot "$func_stripname_result" func_append newlib_search_path " $func_resolve_sysroot_result" ;; *) func_warning "\`-L' is ignored for archives/objects" ;; esac # linkmode continue ;; # -L -R*) if test "$pass" = link; then func_stripname '-R' '' "$deplib" func_resolve_sysroot "$func_stripname_result" dir=$func_resolve_sysroot_result # Make sure the xrpath contains only unique directories. case "$xrpath " in *" $dir "*) ;; *) func_append xrpath " $dir" ;; esac fi deplibs="$deplib $deplibs" continue ;; *.la) func_resolve_sysroot "$deplib" lib=$func_resolve_sysroot_result ;; *.$libext) if test "$pass" = conv; then deplibs="$deplib $deplibs" continue fi case $linkmode in lib) # Linking convenience modules into shared libraries is allowed, # but linking other static libraries is non-portable. case " $dlpreconveniencelibs " in *" $deplib "*) ;; *) valid_a_lib=no case $deplibs_check_method in match_pattern*) set dummy $deplibs_check_method; shift match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` if eval "\$ECHO \"$deplib\"" 2>/dev/null | $SED 10q \ | $EGREP "$match_pattern_regex" > /dev/null; then valid_a_lib=yes fi ;; pass_all) valid_a_lib=yes ;; esac if test "$valid_a_lib" != yes; then echo $ECHO "*** Warning: Trying to link with static lib archive $deplib." echo "*** I have the capability to make that library automatically link in when" echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have" echo "*** because the file extensions .$libext of this argument makes me believe" echo "*** that it is just a static archive that I should not use here." else echo $ECHO "*** Warning: Linking the shared library $output against the" $ECHO "*** static library $deplib is not portable!" deplibs="$deplib $deplibs" fi ;; esac continue ;; prog) if test "$pass" != link; then deplibs="$deplib $deplibs" else compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" fi continue ;; esac # linkmode ;; # *.$libext *.lo | *.$objext) if test "$pass" = conv; then deplibs="$deplib $deplibs" elif test "$linkmode" = prog; then if test "$pass" = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then # If there is no dlopen support or we're linking statically, # we need to preload. func_append newdlprefiles " $deplib" compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else func_append newdlfiles " $deplib" fi fi continue ;; %DEPLIBS%) alldeplibs=yes continue ;; esac # case $deplib if test "$found" = yes || test -f "$lib"; then : else func_fatal_error "cannot find the library \`$lib' or unhandled argument \`$deplib'" fi # Check to see that this really is a libtool archive. func_lalib_unsafe_p "$lib" \ || func_fatal_error "\`$lib' is not a valid libtool archive" func_dirname "$lib" "" "." ladir="$func_dirname_result" dlname= dlopen= dlpreopen= libdir= library_names= old_library= inherited_linker_flags= # If the library was installed with an old release of libtool, # it will not redefine variables installed, or shouldnotlink installed=yes shouldnotlink=no avoidtemprpath= # Read the .la file func_source "$lib" # Convert "-framework foo" to "foo.ltframework" if test -n "$inherited_linker_flags"; then tmp_inherited_linker_flags=`$ECHO "$inherited_linker_flags" | $SED 's/-framework \([^ $]*\)/\1.ltframework/g'` for tmp_inherited_linker_flag in $tmp_inherited_linker_flags; do case " $new_inherited_linker_flags " in *" $tmp_inherited_linker_flag "*) ;; *) func_append new_inherited_linker_flags " $tmp_inherited_linker_flag";; esac done fi dependency_libs=`$ECHO " $dependency_libs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` if test "$linkmode,$pass" = "lib,link" || test "$linkmode,$pass" = "prog,scan" || { test "$linkmode" != prog && test "$linkmode" != lib; }; then test -n "$dlopen" && func_append dlfiles " $dlopen" test -n "$dlpreopen" && func_append dlprefiles " $dlpreopen" fi if test "$pass" = conv; then # Only check for convenience libraries deplibs="$lib $deplibs" if test -z "$libdir"; then if test -z "$old_library"; then func_fatal_error "cannot find name of link library for \`$lib'" fi # It is a libtool convenience library, so add in its objects. func_append convenience " $ladir/$objdir/$old_library" func_append old_convenience " $ladir/$objdir/$old_library" tmp_libs= for deplib in $dependency_libs; do deplibs="$deplib $deplibs" if $opt_preserve_dup_deps ; then case "$tmp_libs " in *" $deplib "*) func_append specialdeplibs " $deplib" ;; esac fi func_append tmp_libs " $deplib" done elif test "$linkmode" != prog && test "$linkmode" != lib; then func_fatal_error "\`$lib' is not a convenience library" fi continue fi # $pass = conv # Get the name of the library we link against. linklib= if test -n "$old_library" && { test "$prefer_static_libs" = yes || test "$prefer_static_libs,$installed" = "built,no"; }; then linklib=$old_library else for l in $old_library $library_names; do linklib="$l" done fi if test -z "$linklib"; then func_fatal_error "cannot find name of link library for \`$lib'" fi # This library was specified with -dlopen. if test "$pass" = dlopen; then if test -z "$libdir"; then func_fatal_error "cannot -dlopen a convenience library: \`$lib'" fi if test -z "$dlname" || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then # If there is no dlname, no dlopen support or we're linking # statically, we need to preload. We also need to preload any # dependent libraries so libltdl's deplib preloader doesn't # bomb out in the load deplibs phase. func_append dlprefiles " $lib $dependency_libs" else func_append newdlfiles " $lib" fi continue fi # $pass = dlopen # We need an absolute path. case $ladir in [\\/]* | [A-Za-z]:[\\/]*) abs_ladir="$ladir" ;; *) abs_ladir=`cd "$ladir" && pwd` if test -z "$abs_ladir"; then func_warning "cannot determine absolute directory name of \`$ladir'" func_warning "passing it literally to the linker, although it might fail" abs_ladir="$ladir" fi ;; esac func_basename "$lib" laname="$func_basename_result" # Find the relevant object directory and library name. if test "X$installed" = Xyes; then if test ! -f "$lt_sysroot$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then func_warning "library \`$lib' was moved." dir="$ladir" absdir="$abs_ladir" libdir="$abs_ladir" else dir="$lt_sysroot$libdir" absdir="$lt_sysroot$libdir" fi test "X$hardcode_automatic" = Xyes && avoidtemprpath=yes else if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then dir="$ladir" absdir="$abs_ladir" # Remove this search path later func_append notinst_path " $abs_ladir" else dir="$ladir/$objdir" absdir="$abs_ladir/$objdir" # Remove this search path later func_append notinst_path " $abs_ladir" fi fi # $installed = yes func_stripname 'lib' '.la' "$laname" name=$func_stripname_result # This library was specified with -dlpreopen. if test "$pass" = dlpreopen; then if test -z "$libdir" && test "$linkmode" = prog; then func_fatal_error "only libraries may -dlpreopen a convenience library: \`$lib'" fi case "$host" in # special handling for platforms with PE-DLLs. *cygwin* | *mingw* | *cegcc* ) # Linker will automatically link against shared library if both # static and shared are present. Therefore, ensure we extract # symbols from the import library if a shared library is present # (otherwise, the dlopen module name will be incorrect). We do # this by putting the import library name into $newdlprefiles. # We recover the dlopen module name by 'saving' the la file # name in a special purpose variable, and (later) extracting the # dlname from the la file. if test -n "$dlname"; then func_tr_sh "$dir/$linklib" eval "libfile_$func_tr_sh_result=\$abs_ladir/\$laname" func_append newdlprefiles " $dir/$linklib" else func_append newdlprefiles " $dir/$old_library" # Keep a list of preopened convenience libraries to check # that they are being used correctly in the link pass. test -z "$libdir" && \ func_append dlpreconveniencelibs " $dir/$old_library" fi ;; * ) # Prefer using a static library (so that no silly _DYNAMIC symbols # are required to link). if test -n "$old_library"; then func_append newdlprefiles " $dir/$old_library" # Keep a list of preopened convenience libraries to check # that they are being used correctly in the link pass. test -z "$libdir" && \ func_append dlpreconveniencelibs " $dir/$old_library" # Otherwise, use the dlname, so that lt_dlopen finds it. elif test -n "$dlname"; then func_append newdlprefiles " $dir/$dlname" else func_append newdlprefiles " $dir/$linklib" fi ;; esac fi # $pass = dlpreopen if test -z "$libdir"; then # Link the convenience library if test "$linkmode" = lib; then deplibs="$dir/$old_library $deplibs" elif test "$linkmode,$pass" = "prog,link"; then compile_deplibs="$dir/$old_library $compile_deplibs" finalize_deplibs="$dir/$old_library $finalize_deplibs" else deplibs="$lib $deplibs" # used for prog,scan pass fi continue fi if test "$linkmode" = prog && test "$pass" != link; then func_append newlib_search_path " $ladir" deplibs="$lib $deplibs" linkalldeplibs=no if test "$link_all_deplibs" != no || test -z "$library_names" || test "$build_libtool_libs" = no; then linkalldeplibs=yes fi tmp_libs= for deplib in $dependency_libs; do case $deplib in -L*) func_stripname '-L' '' "$deplib" func_resolve_sysroot "$func_stripname_result" func_append newlib_search_path " $func_resolve_sysroot_result" ;; esac # Need to link against all dependency_libs? if test "$linkalldeplibs" = yes; then deplibs="$deplib $deplibs" else # Need to hardcode shared library paths # or/and link against static libraries newdependency_libs="$deplib $newdependency_libs" fi if $opt_preserve_dup_deps ; then case "$tmp_libs " in *" $deplib "*) func_append specialdeplibs " $deplib" ;; esac fi func_append tmp_libs " $deplib" done # for deplib continue fi # $linkmode = prog... if test "$linkmode,$pass" = "prog,link"; then if test -n "$library_names" && { { test "$prefer_static_libs" = no || test "$prefer_static_libs,$installed" = "built,yes"; } || test -z "$old_library"; }; then # We need to hardcode the library path if test -n "$shlibpath_var" && test -z "$avoidtemprpath" ; then # Make sure the rpath contains only unique directories. case "$temp_rpath:" in *"$absdir:"*) ;; *) func_append temp_rpath "$absdir:" ;; esac fi # Hardcode the library path. # Skip directories that are in the system default run-time # search path. case " $sys_lib_dlsearch_path " in *" $absdir "*) ;; *) case "$compile_rpath " in *" $absdir "*) ;; *) func_append compile_rpath " $absdir" ;; esac ;; esac case " $sys_lib_dlsearch_path " in *" $libdir "*) ;; *) case "$finalize_rpath " in *" $libdir "*) ;; *) func_append finalize_rpath " $libdir" ;; esac ;; esac fi # $linkmode,$pass = prog,link... if test "$alldeplibs" = yes && { test "$deplibs_check_method" = pass_all || { test "$build_libtool_libs" = yes && test -n "$library_names"; }; }; then # We only need to search for static libraries continue fi fi link_static=no # Whether the deplib will be linked statically use_static_libs=$prefer_static_libs if test "$use_static_libs" = built && test "$installed" = yes; then use_static_libs=no fi if test -n "$library_names" && { test "$use_static_libs" = no || test -z "$old_library"; }; then case $host in *cygwin* | *mingw* | *cegcc*) # No point in relinking DLLs because paths are not encoded func_append notinst_deplibs " $lib" need_relink=no ;; *) if test "$installed" = no; then func_append notinst_deplibs " $lib" need_relink=yes fi ;; esac # This is a shared library # Warn about portability, can't link against -module's on some # systems (darwin). Don't bleat about dlopened modules though! dlopenmodule="" for dlpremoduletest in $dlprefiles; do if test "X$dlpremoduletest" = "X$lib"; then dlopenmodule="$dlpremoduletest" break fi done if test -z "$dlopenmodule" && test "$shouldnotlink" = yes && test "$pass" = link; then echo if test "$linkmode" = prog; then $ECHO "*** Warning: Linking the executable $output against the loadable module" else $ECHO "*** Warning: Linking the shared library $output against the loadable module" fi $ECHO "*** $linklib is not portable!" fi if test "$linkmode" = lib && test "$hardcode_into_libs" = yes; then # Hardcode the library path. # Skip directories that are in the system default run-time # search path. case " $sys_lib_dlsearch_path " in *" $absdir "*) ;; *) case "$compile_rpath " in *" $absdir "*) ;; *) func_append compile_rpath " $absdir" ;; esac ;; esac case " $sys_lib_dlsearch_path " in *" $libdir "*) ;; *) case "$finalize_rpath " in *" $libdir "*) ;; *) func_append finalize_rpath " $libdir" ;; esac ;; esac fi if test -n "$old_archive_from_expsyms_cmds"; then # figure out the soname set dummy $library_names shift realname="$1" shift libname=`eval "\\$ECHO \"$libname_spec\""` # use dlname if we got it. it's perfectly good, no? if test -n "$dlname"; then soname="$dlname" elif test -n "$soname_spec"; then # bleh windows case $host in *cygwin* | mingw* | *cegcc*) func_arith $current - $age major=$func_arith_result versuffix="-$major" ;; esac eval soname=\"$soname_spec\" else soname="$realname" fi # Make a new name for the extract_expsyms_cmds to use soroot="$soname" func_basename "$soroot" soname="$func_basename_result" func_stripname 'lib' '.dll' "$soname" newlib=libimp-$func_stripname_result.a # If the library has no export list, then create one now if test -f "$output_objdir/$soname-def"; then : else func_verbose "extracting exported symbol list from \`$soname'" func_execute_cmds "$extract_expsyms_cmds" 'exit $?' fi # Create $newlib if test -f "$output_objdir/$newlib"; then :; else func_verbose "generating import library for \`$soname'" func_execute_cmds "$old_archive_from_expsyms_cmds" 'exit $?' fi # make sure the library variables are pointing to the new library dir=$output_objdir linklib=$newlib fi # test -n "$old_archive_from_expsyms_cmds" if test "$linkmode" = prog || test "$opt_mode" != relink; then add_shlibpath= add_dir= add= lib_linked=yes case $hardcode_action in immediate | unsupported) if test "$hardcode_direct" = no; then add="$dir/$linklib" case $host in *-*-sco3.2v5.0.[024]*) add_dir="-L$dir" ;; *-*-sysv4*uw2*) add_dir="-L$dir" ;; *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \ *-*-unixware7*) add_dir="-L$dir" ;; *-*-darwin* ) # if the lib is a (non-dlopened) module then we can not # link against it, someone is ignoring the earlier warnings if /usr/bin/file -L $add 2> /dev/null | $GREP ": [^:]* bundle" >/dev/null ; then if test "X$dlopenmodule" != "X$lib"; then $ECHO "*** Warning: lib $linklib is a module, not a shared library" if test -z "$old_library" ; then echo echo "*** And there doesn't seem to be a static archive available" echo "*** The link will probably fail, sorry" else add="$dir/$old_library" fi elif test -n "$old_library"; then add="$dir/$old_library" fi fi esac elif test "$hardcode_minus_L" = no; then case $host in *-*-sunos*) add_shlibpath="$dir" ;; esac add_dir="-L$dir" add="-l$name" elif test "$hardcode_shlibpath_var" = no; then add_shlibpath="$dir" add="-l$name" else lib_linked=no fi ;; relink) if test "$hardcode_direct" = yes && test "$hardcode_direct_absolute" = no; then add="$dir/$linklib" elif test "$hardcode_minus_L" = yes; then add_dir="-L$absdir" # Try looking first in the location we're being installed to. if test -n "$inst_prefix_dir"; then case $libdir in [\\/]*) func_append add_dir " -L$inst_prefix_dir$libdir" ;; esac fi add="-l$name" elif test "$hardcode_shlibpath_var" = yes; then add_shlibpath="$dir" add="-l$name" else lib_linked=no fi ;; *) lib_linked=no ;; esac if test "$lib_linked" != yes; then func_fatal_configuration "unsupported hardcode properties" fi if test -n "$add_shlibpath"; then case :$compile_shlibpath: in *":$add_shlibpath:"*) ;; *) func_append compile_shlibpath "$add_shlibpath:" ;; esac fi if test "$linkmode" = prog; then test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs" test -n "$add" && compile_deplibs="$add $compile_deplibs" else test -n "$add_dir" && deplibs="$add_dir $deplibs" test -n "$add" && deplibs="$add $deplibs" if test "$hardcode_direct" != yes && test "$hardcode_minus_L" != yes && test "$hardcode_shlibpath_var" = yes; then case :$finalize_shlibpath: in *":$libdir:"*) ;; *) func_append finalize_shlibpath "$libdir:" ;; esac fi fi fi if test "$linkmode" = prog || test "$opt_mode" = relink; then add_shlibpath= add_dir= add= # Finalize command for both is simple: just hardcode it. if test "$hardcode_direct" = yes && test "$hardcode_direct_absolute" = no; then add="$libdir/$linklib" elif test "$hardcode_minus_L" = yes; then add_dir="-L$libdir" add="-l$name" elif test "$hardcode_shlibpath_var" = yes; then case :$finalize_shlibpath: in *":$libdir:"*) ;; *) func_append finalize_shlibpath "$libdir:" ;; esac add="-l$name" elif test "$hardcode_automatic" = yes; then if test -n "$inst_prefix_dir" && test -f "$inst_prefix_dir$libdir/$linklib" ; then add="$inst_prefix_dir$libdir/$linklib" else add="$libdir/$linklib" fi else # We cannot seem to hardcode it, guess we'll fake it. add_dir="-L$libdir" # Try looking first in the location we're being installed to. if test -n "$inst_prefix_dir"; then case $libdir in [\\/]*) func_append add_dir " -L$inst_prefix_dir$libdir" ;; esac fi add="-l$name" fi if test "$linkmode" = prog; then test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs" test -n "$add" && finalize_deplibs="$add $finalize_deplibs" else test -n "$add_dir" && deplibs="$add_dir $deplibs" test -n "$add" && deplibs="$add $deplibs" fi fi elif test "$linkmode" = prog; then # Here we assume that one of hardcode_direct or hardcode_minus_L # is not unsupported. This is valid on all known static and # shared platforms. if test "$hardcode_direct" != unsupported; then test -n "$old_library" && linklib="$old_library" compile_deplibs="$dir/$linklib $compile_deplibs" finalize_deplibs="$dir/$linklib $finalize_deplibs" else compile_deplibs="-l$name -L$dir $compile_deplibs" finalize_deplibs="-l$name -L$dir $finalize_deplibs" fi elif test "$build_libtool_libs" = yes; then # Not a shared library if test "$deplibs_check_method" != pass_all; then # We're trying link a shared library against a static one # but the system doesn't support it. # Just print a warning and add the library to dependency_libs so # that the program can be linked against the static library. echo $ECHO "*** Warning: This system can not link to static lib archive $lib." echo "*** I have the capability to make that library automatically link in when" echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have." if test "$module" = yes; then echo "*** But as you try to build a module library, libtool will still create " echo "*** a static module, that should work as long as the dlopening application" echo "*** is linked with the -dlopen flag to resolve symbols at runtime." if test -z "$global_symbol_pipe"; then echo echo "*** However, this would only work if libtool was able to extract symbol" echo "*** lists from a program, using \`nm' or equivalent, but libtool could" echo "*** not find such a program. So, this module is probably useless." echo "*** \`nm' from GNU binutils and a full rebuild may help." fi if test "$build_old_libs" = no; then build_libtool_libs=module build_old_libs=yes else build_libtool_libs=no fi fi else deplibs="$dir/$old_library $deplibs" link_static=yes fi fi # link shared/static library? if test "$linkmode" = lib; then if test -n "$dependency_libs" && { test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes || test "$link_static" = yes; }; then # Extract -R from dependency_libs temp_deplibs= for libdir in $dependency_libs; do case $libdir in -R*) func_stripname '-R' '' "$libdir" temp_xrpath=$func_stripname_result case " $xrpath " in *" $temp_xrpath "*) ;; *) func_append xrpath " $temp_xrpath";; esac;; *) func_append temp_deplibs " $libdir";; esac done dependency_libs="$temp_deplibs" fi func_append newlib_search_path " $absdir" # Link against this library test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs" # ... and its dependency_libs tmp_libs= for deplib in $dependency_libs; do newdependency_libs="$deplib $newdependency_libs" case $deplib in -L*) func_stripname '-L' '' "$deplib" func_resolve_sysroot "$func_stripname_result";; *) func_resolve_sysroot "$deplib" ;; esac if $opt_preserve_dup_deps ; then case "$tmp_libs " in *" $func_resolve_sysroot_result "*) func_append specialdeplibs " $func_resolve_sysroot_result" ;; esac fi func_append tmp_libs " $func_resolve_sysroot_result" done if test "$link_all_deplibs" != no; then # Add the search paths of all dependency libraries for deplib in $dependency_libs; do path= case $deplib in -L*) path="$deplib" ;; *.la) func_resolve_sysroot "$deplib" deplib=$func_resolve_sysroot_result func_dirname "$deplib" "" "." dir=$func_dirname_result # We need an absolute path. case $dir in [\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;; *) absdir=`cd "$dir" && pwd` if test -z "$absdir"; then func_warning "cannot determine absolute directory name of \`$dir'" absdir="$dir" fi ;; esac if $GREP "^installed=no" $deplib > /dev/null; then case $host in *-*-darwin*) depdepl= eval deplibrary_names=`${SED} -n -e 's/^library_names=\(.*\)$/\1/p' $deplib` if test -n "$deplibrary_names" ; then for tmp in $deplibrary_names ; do depdepl=$tmp done if test -f "$absdir/$objdir/$depdepl" ; then depdepl="$absdir/$objdir/$depdepl" darwin_install_name=`${OTOOL} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` if test -z "$darwin_install_name"; then darwin_install_name=`${OTOOL64} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` fi func_append compiler_flags " ${wl}-dylib_file ${wl}${darwin_install_name}:${depdepl}" func_append linker_flags " -dylib_file ${darwin_install_name}:${depdepl}" path= fi fi ;; *) path="-L$absdir/$objdir" ;; esac else eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` test -z "$libdir" && \ func_fatal_error "\`$deplib' is not a valid libtool archive" test "$absdir" != "$libdir" && \ func_warning "\`$deplib' seems to be moved" path="-L$absdir" fi ;; esac case " $deplibs " in *" $path "*) ;; *) deplibs="$path $deplibs" ;; esac done fi # link_all_deplibs != no fi # linkmode = lib done # for deplib in $libs if test "$pass" = link; then if test "$linkmode" = "prog"; then compile_deplibs="$new_inherited_linker_flags $compile_deplibs" finalize_deplibs="$new_inherited_linker_flags $finalize_deplibs" else compiler_flags="$compiler_flags "`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` fi fi dependency_libs="$newdependency_libs" if test "$pass" = dlpreopen; then # Link the dlpreopened libraries before other libraries for deplib in $save_deplibs; do deplibs="$deplib $deplibs" done fi if test "$pass" != dlopen; then if test "$pass" != conv; then # Make sure lib_search_path contains only unique directories. lib_search_path= for dir in $newlib_search_path; do case "$lib_search_path " in *" $dir "*) ;; *) func_append lib_search_path " $dir" ;; esac done newlib_search_path= fi if test "$linkmode,$pass" != "prog,link"; then vars="deplibs" else vars="compile_deplibs finalize_deplibs" fi for var in $vars dependency_libs; do # Add libraries to $var in reverse order eval tmp_libs=\"\$$var\" new_libs= for deplib in $tmp_libs; do # FIXME: Pedantically, this is the right thing to do, so # that some nasty dependency loop isn't accidentally # broken: #new_libs="$deplib $new_libs" # Pragmatically, this seems to cause very few problems in # practice: case $deplib in -L*) new_libs="$deplib $new_libs" ;; -R*) ;; *) # And here is the reason: when a library appears more # than once as an explicit dependence of a library, or # is implicitly linked in more than once by the # compiler, it is considered special, and multiple # occurrences thereof are not removed. Compare this # with having the same library being listed as a # dependency of multiple other libraries: in this case, # we know (pedantically, we assume) the library does not # need to be listed more than once, so we keep only the # last copy. This is not always right, but it is rare # enough that we require users that really mean to play # such unportable linking tricks to link the library # using -Wl,-lname, so that libtool does not consider it # for duplicate removal. case " $specialdeplibs " in *" $deplib "*) new_libs="$deplib $new_libs" ;; *) case " $new_libs " in *" $deplib "*) ;; *) new_libs="$deplib $new_libs" ;; esac ;; esac ;; esac done tmp_libs= for deplib in $new_libs; do case $deplib in -L*) case " $tmp_libs " in *" $deplib "*) ;; *) func_append tmp_libs " $deplib" ;; esac ;; *) func_append tmp_libs " $deplib" ;; esac done eval $var=\"$tmp_libs\" done # for var fi # Last step: remove runtime libs from dependency_libs # (they stay in deplibs) tmp_libs= for i in $dependency_libs ; do case " $predeps $postdeps $compiler_lib_search_path " in *" $i "*) i="" ;; esac if test -n "$i" ; then func_append tmp_libs " $i" fi done dependency_libs=$tmp_libs done # for pass if test "$linkmode" = prog; then dlfiles="$newdlfiles" fi if test "$linkmode" = prog || test "$linkmode" = lib; then dlprefiles="$newdlprefiles" fi case $linkmode in oldlib) if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then func_warning "\`-dlopen' is ignored for archives" fi case " $deplibs" in *\ -l* | *\ -L*) func_warning "\`-l' and \`-L' are ignored for archives" ;; esac test -n "$rpath" && \ func_warning "\`-rpath' is ignored for archives" test -n "$xrpath" && \ func_warning "\`-R' is ignored for archives" test -n "$vinfo" && \ func_warning "\`-version-info/-version-number' is ignored for archives" test -n "$release" && \ func_warning "\`-release' is ignored for archives" test -n "$export_symbols$export_symbols_regex" && \ func_warning "\`-export-symbols' is ignored for archives" # Now set the variables for building old libraries. build_libtool_libs=no oldlibs="$output" func_append objs "$old_deplibs" ;; lib) # Make sure we only generate libraries of the form `libNAME.la'. case $outputname in lib*) func_stripname 'lib' '.la' "$outputname" name=$func_stripname_result eval shared_ext=\"$shrext_cmds\" eval libname=\"$libname_spec\" ;; *) test "$module" = no && \ func_fatal_help "libtool library \`$output' must begin with \`lib'" if test "$need_lib_prefix" != no; then # Add the "lib" prefix for modules if required func_stripname '' '.la' "$outputname" name=$func_stripname_result eval shared_ext=\"$shrext_cmds\" eval libname=\"$libname_spec\" else func_stripname '' '.la' "$outputname" libname=$func_stripname_result fi ;; esac if test -n "$objs"; then if test "$deplibs_check_method" != pass_all; then func_fatal_error "cannot build libtool library \`$output' from non-libtool objects on this host:$objs" else echo $ECHO "*** Warning: Linking the shared library $output against the non-libtool" $ECHO "*** objects $objs is not portable!" func_append libobjs " $objs" fi fi test "$dlself" != no && \ func_warning "\`-dlopen self' is ignored for libtool libraries" set dummy $rpath shift test "$#" -gt 1 && \ func_warning "ignoring multiple \`-rpath's for a libtool library" install_libdir="$1" oldlibs= if test -z "$rpath"; then if test "$build_libtool_libs" = yes; then # Building a libtool convenience library. # Some compilers have problems with a `.al' extension so # convenience libraries should have the same extension an # archive normally would. oldlibs="$output_objdir/$libname.$libext $oldlibs" build_libtool_libs=convenience build_old_libs=yes fi test -n "$vinfo" && \ func_warning "\`-version-info/-version-number' is ignored for convenience libraries" test -n "$release" && \ func_warning "\`-release' is ignored for convenience libraries" else # Parse the version information argument. save_ifs="$IFS"; IFS=':' set dummy $vinfo 0 0 0 shift IFS="$save_ifs" test -n "$7" && \ func_fatal_help "too many parameters to \`-version-info'" # convert absolute version numbers to libtool ages # this retains compatibility with .la files and attempts # to make the code below a bit more comprehensible case $vinfo_number in yes) number_major="$1" number_minor="$2" number_revision="$3" # # There are really only two kinds -- those that # use the current revision as the major version # and those that subtract age and use age as # a minor version. But, then there is irix # which has an extra 1 added just for fun # case $version_type in # correct linux to gnu/linux during the next big refactor darwin|linux|osf|windows|none) func_arith $number_major + $number_minor current=$func_arith_result age="$number_minor" revision="$number_revision" ;; freebsd-aout|freebsd-elf|qnx|sunos) current="$number_major" revision="$number_minor" age="0" ;; irix|nonstopux) func_arith $number_major + $number_minor current=$func_arith_result age="$number_minor" revision="$number_minor" lt_irix_increment=no ;; *) func_fatal_configuration "$modename: unknown library version type \`$version_type'" ;; esac ;; no) current="$1" revision="$2" age="$3" ;; esac # Check that each of the things are valid numbers. case $current in 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; *) func_error "CURRENT \`$current' must be a nonnegative integer" func_fatal_error "\`$vinfo' is not valid version information" ;; esac case $revision in 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; *) func_error "REVISION \`$revision' must be a nonnegative integer" func_fatal_error "\`$vinfo' is not valid version information" ;; esac case $age in 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; *) func_error "AGE \`$age' must be a nonnegative integer" func_fatal_error "\`$vinfo' is not valid version information" ;; esac if test "$age" -gt "$current"; then func_error "AGE \`$age' is greater than the current interface number \`$current'" func_fatal_error "\`$vinfo' is not valid version information" fi # Calculate the version variables. major= versuffix= verstring= case $version_type in none) ;; darwin) # Like Linux, but with the current version available in # verstring for coding it into the library header func_arith $current - $age major=.$func_arith_result versuffix="$major.$age.$revision" # Darwin ld doesn't like 0 for these options... func_arith $current + 1 minor_current=$func_arith_result xlcverstring="${wl}-compatibility_version ${wl}$minor_current ${wl}-current_version ${wl}$minor_current.$revision" verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" ;; freebsd-aout) major=".$current" versuffix=".$current.$revision"; ;; freebsd-elf) major=".$current" versuffix=".$current" ;; irix | nonstopux) if test "X$lt_irix_increment" = "Xno"; then func_arith $current - $age else func_arith $current - $age + 1 fi major=$func_arith_result case $version_type in nonstopux) verstring_prefix=nonstopux ;; *) verstring_prefix=sgi ;; esac verstring="$verstring_prefix$major.$revision" # Add in all the interfaces that we are compatible with. loop=$revision while test "$loop" -ne 0; do func_arith $revision - $loop iface=$func_arith_result func_arith $loop - 1 loop=$func_arith_result verstring="$verstring_prefix$major.$iface:$verstring" done # Before this point, $major must not contain `.'. major=.$major versuffix="$major.$revision" ;; linux) # correct to gnu/linux during the next big refactor func_arith $current - $age major=.$func_arith_result versuffix="$major.$age.$revision" ;; osf) func_arith $current - $age major=.$func_arith_result versuffix=".$current.$age.$revision" verstring="$current.$age.$revision" # Add in all the interfaces that we are compatible with. loop=$age while test "$loop" -ne 0; do func_arith $current - $loop iface=$func_arith_result func_arith $loop - 1 loop=$func_arith_result verstring="$verstring:${iface}.0" done # Make executables depend on our current version. func_append verstring ":${current}.0" ;; qnx) major=".$current" versuffix=".$current" ;; sunos) major=".$current" versuffix=".$current.$revision" ;; windows) # Use '-' rather than '.', since we only want one # extension on DOS 8.3 filesystems. func_arith $current - $age major=$func_arith_result versuffix="-$major" ;; *) func_fatal_configuration "unknown library version type \`$version_type'" ;; esac # Clear the version info if we defaulted, and they specified a release. if test -z "$vinfo" && test -n "$release"; then major= case $version_type in darwin) # we can't check for "0.0" in archive_cmds due to quoting # problems, so we reset it completely verstring= ;; *) verstring="0.0" ;; esac if test "$need_version" = no; then versuffix= else versuffix=".0.0" fi fi # Remove version info from name if versioning should be avoided if test "$avoid_version" = yes && test "$need_version" = no; then major= versuffix= verstring="" fi # Check to see if the archive will have undefined symbols. if test "$allow_undefined" = yes; then if test "$allow_undefined_flag" = unsupported; then func_warning "undefined symbols not allowed in $host shared libraries" build_libtool_libs=no build_old_libs=yes fi else # Don't allow undefined symbols. allow_undefined_flag="$no_undefined_flag" fi fi func_generate_dlsyms "$libname" "$libname" "yes" func_append libobjs " $symfileobj" test "X$libobjs" = "X " && libobjs= if test "$opt_mode" != relink; then # Remove our outputs, but don't remove object files since they # may have been created when compiling PIC objects. removelist= tempremovelist=`$ECHO "$output_objdir/*"` for p in $tempremovelist; do case $p in *.$objext | *.gcno) ;; $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/${libname}${release}.*) if test "X$precious_files_regex" != "X"; then if $ECHO "$p" | $EGREP -e "$precious_files_regex" >/dev/null 2>&1 then continue fi fi func_append removelist " $p" ;; *) ;; esac done test -n "$removelist" && \ func_show_eval "${RM}r \$removelist" fi # Now set the variables for building old libraries. if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then func_append oldlibs " $output_objdir/$libname.$libext" # Transform .lo files to .o files. oldobjs="$objs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.${libext}$/d; $lo2o" | $NL2SP` fi # Eliminate all temporary directories. #for path in $notinst_path; do # lib_search_path=`$ECHO "$lib_search_path " | $SED "s% $path % %g"` # deplibs=`$ECHO "$deplibs " | $SED "s% -L$path % %g"` # dependency_libs=`$ECHO "$dependency_libs " | $SED "s% -L$path % %g"` #done if test -n "$xrpath"; then # If the user specified any rpath flags, then add them. temp_xrpath= for libdir in $xrpath; do func_replace_sysroot "$libdir" func_append temp_xrpath " -R$func_replace_sysroot_result" case "$finalize_rpath " in *" $libdir "*) ;; *) func_append finalize_rpath " $libdir" ;; esac done if test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes; then dependency_libs="$temp_xrpath $dependency_libs" fi fi # Make sure dlfiles contains only unique files that won't be dlpreopened old_dlfiles="$dlfiles" dlfiles= for lib in $old_dlfiles; do case " $dlprefiles $dlfiles " in *" $lib "*) ;; *) func_append dlfiles " $lib" ;; esac done # Make sure dlprefiles contains only unique files old_dlprefiles="$dlprefiles" dlprefiles= for lib in $old_dlprefiles; do case "$dlprefiles " in *" $lib "*) ;; *) func_append dlprefiles " $lib" ;; esac done if test "$build_libtool_libs" = yes; then if test -n "$rpath"; then case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc* | *-*-haiku*) # these systems don't actually have a c library (as such)! ;; *-*-rhapsody* | *-*-darwin1.[012]) # Rhapsody C library is in the System framework func_append deplibs " System.ltframework" ;; *-*-netbsd*) # Don't link with libc until the a.out ld.so is fixed. ;; *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) # Do not include libc due to us having libc/libc_r. ;; *-*-sco3.2v5* | *-*-sco5v6*) # Causes problems with __ctype ;; *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) # Compiler inserts libc in the correct place for threads to work ;; *) # Add libc to deplibs on all other systems if necessary. if test "$build_libtool_need_lc" = "yes"; then func_append deplibs " -lc" fi ;; esac fi # Transform deplibs into only deplibs that can be linked in shared. name_save=$name libname_save=$libname release_save=$release versuffix_save=$versuffix major_save=$major # I'm not sure if I'm treating the release correctly. I think # release should show up in the -l (ie -lgmp5) so we don't want to # add it in twice. Is that correct? release="" versuffix="" major="" newdeplibs= droppeddeps=no case $deplibs_check_method in pass_all) # Don't check for shared/static. Everything works. # This might be a little naive. We might want to check # whether the library exists or not. But this is on # osf3 & osf4 and I'm not really sure... Just # implementing what was already the behavior. newdeplibs=$deplibs ;; test_compile) # This code stresses the "libraries are programs" paradigm to its # limits. Maybe even breaks it. We compile a program, linking it # against the deplibs as a proxy for the library. Then we can check # whether they linked in statically or dynamically with ldd. $opt_dry_run || $RM conftest.c cat > conftest.c </dev/null` $nocaseglob else potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null` fi for potent_lib in $potential_libs; do # Follow soft links. if ls -lLd "$potent_lib" 2>/dev/null | $GREP " -> " >/dev/null; then continue fi # The statement above tries to avoid entering an # endless loop below, in case of cyclic links. # We might still enter an endless loop, since a link # loop can be closed while we follow links, # but so what? potlib="$potent_lib" while test -h "$potlib" 2>/dev/null; do potliblink=`ls -ld $potlib | ${SED} 's/.* -> //'` case $potliblink in [\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";; *) potlib=`$ECHO "$potlib" | $SED 's,[^/]*$,,'`"$potliblink";; esac done if eval $file_magic_cmd \"\$potlib\" 2>/dev/null | $SED -e 10q | $EGREP "$file_magic_regex" > /dev/null; then func_append newdeplibs " $a_deplib" a_deplib="" break 2 fi done done fi if test -n "$a_deplib" ; then droppeddeps=yes echo $ECHO "*** Warning: linker path does not have real file for library $a_deplib." echo "*** I have the capability to make that library automatically link in when" echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have" echo "*** because I did check the linker path looking for a file starting" if test -z "$potlib" ; then $ECHO "*** with $libname but no candidates were found. (...for file magic test)" else $ECHO "*** with $libname and none of the candidates passed a file format test" $ECHO "*** using a file magic. Last file checked: $potlib" fi fi ;; *) # Add a -L argument. func_append newdeplibs " $a_deplib" ;; esac done # Gone through all deplibs. ;; match_pattern*) set dummy $deplibs_check_method; shift match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` for a_deplib in $deplibs; do case $a_deplib in -l*) func_stripname -l '' "$a_deplib" name=$func_stripname_result if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then case " $predeps $postdeps " in *" $a_deplib "*) func_append newdeplibs " $a_deplib" a_deplib="" ;; esac fi if test -n "$a_deplib" ; then libname=`eval "\\$ECHO \"$libname_spec\""` for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do potential_libs=`ls $i/$libname[.-]* 2>/dev/null` for potent_lib in $potential_libs; do potlib="$potent_lib" # see symlink-check above in file_magic test if eval "\$ECHO \"$potent_lib\"" 2>/dev/null | $SED 10q | \ $EGREP "$match_pattern_regex" > /dev/null; then func_append newdeplibs " $a_deplib" a_deplib="" break 2 fi done done fi if test -n "$a_deplib" ; then droppeddeps=yes echo $ECHO "*** Warning: linker path does not have real file for library $a_deplib." echo "*** I have the capability to make that library automatically link in when" echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have" echo "*** because I did check the linker path looking for a file starting" if test -z "$potlib" ; then $ECHO "*** with $libname but no candidates were found. (...for regex pattern test)" else $ECHO "*** with $libname and none of the candidates passed a file format test" $ECHO "*** using a regex pattern. Last file checked: $potlib" fi fi ;; *) # Add a -L argument. func_append newdeplibs " $a_deplib" ;; esac done # Gone through all deplibs. ;; none | unknown | *) newdeplibs="" tmp_deplibs=`$ECHO " $deplibs" | $SED 's/ -lc$//; s/ -[LR][^ ]*//g'` if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then for i in $predeps $postdeps ; do # can't use Xsed below, because $i might contain '/' tmp_deplibs=`$ECHO " $tmp_deplibs" | $SED "s,$i,,"` done fi case $tmp_deplibs in *[!\ \ ]*) echo if test "X$deplibs_check_method" = "Xnone"; then echo "*** Warning: inter-library dependencies are not supported in this platform." else echo "*** Warning: inter-library dependencies are not known to be supported." fi echo "*** All declared inter-library dependencies are being dropped." droppeddeps=yes ;; esac ;; esac versuffix=$versuffix_save major=$major_save release=$release_save libname=$libname_save name=$name_save case $host in *-*-rhapsody* | *-*-darwin1.[012]) # On Rhapsody replace the C library with the System framework newdeplibs=`$ECHO " $newdeplibs" | $SED 's/ -lc / System.ltframework /'` ;; esac if test "$droppeddeps" = yes; then if test "$module" = yes; then echo echo "*** Warning: libtool could not satisfy all declared inter-library" $ECHO "*** dependencies of module $libname. Therefore, libtool will create" echo "*** a static module, that should work as long as the dlopening" echo "*** application is linked with the -dlopen flag." if test -z "$global_symbol_pipe"; then echo echo "*** However, this would only work if libtool was able to extract symbol" echo "*** lists from a program, using \`nm' or equivalent, but libtool could" echo "*** not find such a program. So, this module is probably useless." echo "*** \`nm' from GNU binutils and a full rebuild may help." fi if test "$build_old_libs" = no; then oldlibs="$output_objdir/$libname.$libext" build_libtool_libs=module build_old_libs=yes else build_libtool_libs=no fi else echo "*** The inter-library dependencies that have been dropped here will be" echo "*** automatically added whenever a program is linked with this library" echo "*** or is declared to -dlopen it." if test "$allow_undefined" = no; then echo echo "*** Since this library must not contain undefined symbols," echo "*** because either the platform does not support them or" echo "*** it was explicitly requested with -no-undefined," echo "*** libtool will only create a static version of it." if test "$build_old_libs" = no; then oldlibs="$output_objdir/$libname.$libext" build_libtool_libs=module build_old_libs=yes else build_libtool_libs=no fi fi fi fi # Done checking deplibs! deplibs=$newdeplibs fi # Time to change all our "foo.ltframework" stuff back to "-framework foo" case $host in *-*-darwin*) newdeplibs=`$ECHO " $newdeplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` new_inherited_linker_flags=`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` deplibs=`$ECHO " $deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` ;; esac # move library search paths that coincide with paths to not yet # installed libraries to the beginning of the library search list new_libs= for path in $notinst_path; do case " $new_libs " in *" -L$path/$objdir "*) ;; *) case " $deplibs " in *" -L$path/$objdir "*) func_append new_libs " -L$path/$objdir" ;; esac ;; esac done for deplib in $deplibs; do case $deplib in -L*) case " $new_libs " in *" $deplib "*) ;; *) func_append new_libs " $deplib" ;; esac ;; *) func_append new_libs " $deplib" ;; esac done deplibs="$new_libs" # All the library-specific variables (install_libdir is set above). library_names= old_library= dlname= # Test again, we may have decided not to build it any more if test "$build_libtool_libs" = yes; then # Remove ${wl} instances when linking with ld. # FIXME: should test the right _cmds variable. case $archive_cmds in *\$LD\ *) wl= ;; esac if test "$hardcode_into_libs" = yes; then # Hardcode the library paths hardcode_libdirs= dep_rpath= rpath="$finalize_rpath" test "$opt_mode" != relink && rpath="$compile_rpath$rpath" for libdir in $rpath; do if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then func_replace_sysroot "$libdir" libdir=$func_replace_sysroot_result if test -z "$hardcode_libdirs"; then hardcode_libdirs="$libdir" else # Just accumulate the unique libdirs. case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ;; *) func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" ;; esac fi else eval flag=\"$hardcode_libdir_flag_spec\" func_append dep_rpath " $flag" fi elif test -n "$runpath_var"; then case "$perm_rpath " in *" $libdir "*) ;; *) func_append perm_rpath " $libdir" ;; esac fi done # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then libdir="$hardcode_libdirs" eval "dep_rpath=\"$hardcode_libdir_flag_spec\"" fi if test -n "$runpath_var" && test -n "$perm_rpath"; then # We should set the runpath_var. rpath= for dir in $perm_rpath; do func_append rpath "$dir:" done eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var" fi test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs" fi shlibpath="$finalize_shlibpath" test "$opt_mode" != relink && shlibpath="$compile_shlibpath$shlibpath" if test -n "$shlibpath"; then eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var" fi # Get the real and link names of the library. eval shared_ext=\"$shrext_cmds\" eval library_names=\"$library_names_spec\" set dummy $library_names shift realname="$1" shift if test -n "$soname_spec"; then eval soname=\"$soname_spec\" else soname="$realname" fi if test -z "$dlname"; then dlname=$soname fi lib="$output_objdir/$realname" linknames= for link do func_append linknames " $link" done # Use standard objects if they are pic test -z "$pic_flag" && libobjs=`$ECHO "$libobjs" | $SP2NL | $SED "$lo2o" | $NL2SP` test "X$libobjs" = "X " && libobjs= delfiles= if test -n "$export_symbols" && test -n "$include_expsyms"; then $opt_dry_run || cp "$export_symbols" "$output_objdir/$libname.uexp" export_symbols="$output_objdir/$libname.uexp" func_append delfiles " $export_symbols" fi orig_export_symbols= case $host_os in cygwin* | mingw* | cegcc*) if test -n "$export_symbols" && test -z "$export_symbols_regex"; then # exporting using user supplied symfile if test "x`$SED 1q $export_symbols`" != xEXPORTS; then # and it's NOT already a .def file. Must figure out # which of the given symbols are data symbols and tag # them as such. So, trigger use of export_symbols_cmds. # export_symbols gets reassigned inside the "prepare # the list of exported symbols" if statement, so the # include_expsyms logic still works. orig_export_symbols="$export_symbols" export_symbols= always_export_symbols=yes fi fi ;; esac # Prepare the list of exported symbols if test -z "$export_symbols"; then if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then func_verbose "generating symbol list for \`$libname.la'" export_symbols="$output_objdir/$libname.exp" $opt_dry_run || $RM $export_symbols cmds=$export_symbols_cmds save_ifs="$IFS"; IFS='~' for cmd1 in $cmds; do IFS="$save_ifs" # Take the normal branch if the nm_file_list_spec branch # doesn't work or if tool conversion is not needed. case $nm_file_list_spec~$to_tool_file_cmd in *~func_convert_file_noop | *~func_convert_file_msys_to_w32 | ~*) try_normal_branch=yes eval cmd=\"$cmd1\" func_len " $cmd" len=$func_len_result ;; *) try_normal_branch=no ;; esac if test "$try_normal_branch" = yes \ && { test "$len" -lt "$max_cmd_len" \ || test "$max_cmd_len" -le -1; } then func_show_eval "$cmd" 'exit $?' skipped_export=false elif test -n "$nm_file_list_spec"; then func_basename "$output" output_la=$func_basename_result save_libobjs=$libobjs save_output=$output output=${output_objdir}/${output_la}.nm func_to_tool_file "$output" libobjs=$nm_file_list_spec$func_to_tool_file_result func_append delfiles " $output" func_verbose "creating $NM input file list: $output" for obj in $save_libobjs; do func_to_tool_file "$obj" $ECHO "$func_to_tool_file_result" done > "$output" eval cmd=\"$cmd1\" func_show_eval "$cmd" 'exit $?' output=$save_output libobjs=$save_libobjs skipped_export=false else # The command line is too long to execute in one step. func_verbose "using reloadable object file for export list..." skipped_export=: # Break out early, otherwise skipped_export may be # set to false by a later but shorter cmd. break fi done IFS="$save_ifs" if test -n "$export_symbols_regex" && test "X$skipped_export" != "X:"; then func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' func_show_eval '$MV "${export_symbols}T" "$export_symbols"' fi fi fi if test -n "$export_symbols" && test -n "$include_expsyms"; then tmp_export_symbols="$export_symbols" test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols" $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' fi if test "X$skipped_export" != "X:" && test -n "$orig_export_symbols"; then # The given exports_symbols file has to be filtered, so filter it. func_verbose "filter symbol list for \`$libname.la' to tag DATA exports" # FIXME: $output_objdir/$libname.filter potentially contains lots of # 's' commands which not all seds can handle. GNU sed should be fine # though. Also, the filter scales superlinearly with the number of # global variables. join(1) would be nice here, but unfortunately # isn't a blessed tool. $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter func_append delfiles " $export_symbols $output_objdir/$libname.filter" export_symbols=$output_objdir/$libname.def $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols fi tmp_deplibs= for test_deplib in $deplibs; do case " $convenience " in *" $test_deplib "*) ;; *) func_append tmp_deplibs " $test_deplib" ;; esac done deplibs="$tmp_deplibs" if test -n "$convenience"; then if test -n "$whole_archive_flag_spec" && test "$compiler_needs_object" = yes && test -z "$libobjs"; then # extract the archives, so we have objects to list. # TODO: could optimize this to just extract one archive. whole_archive_flag_spec= fi if test -n "$whole_archive_flag_spec"; then save_libobjs=$libobjs eval libobjs=\"\$libobjs $whole_archive_flag_spec\" test "X$libobjs" = "X " && libobjs= else gentop="$output_objdir/${outputname}x" func_append generated " $gentop" func_extract_archives $gentop $convenience func_append libobjs " $func_extract_archives_result" test "X$libobjs" = "X " && libobjs= fi fi if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then eval flag=\"$thread_safe_flag_spec\" func_append linker_flags " $flag" fi # Make a backup of the uninstalled library when relinking if test "$opt_mode" = relink; then $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}U && $MV $realname ${realname}U)' || exit $? fi # Do each of the archive commands. if test "$module" = yes && test -n "$module_cmds" ; then if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then eval test_cmds=\"$module_expsym_cmds\" cmds=$module_expsym_cmds else eval test_cmds=\"$module_cmds\" cmds=$module_cmds fi else if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then eval test_cmds=\"$archive_expsym_cmds\" cmds=$archive_expsym_cmds else eval test_cmds=\"$archive_cmds\" cmds=$archive_cmds fi fi if test "X$skipped_export" != "X:" && func_len " $test_cmds" && len=$func_len_result && test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then : else # The command line is too long to link in one step, link piecewise # or, if using GNU ld and skipped_export is not :, use a linker # script. # Save the value of $output and $libobjs because we want to # use them later. If we have whole_archive_flag_spec, we # want to use save_libobjs as it was before # whole_archive_flag_spec was expanded, because we can't # assume the linker understands whole_archive_flag_spec. # This may have to be revisited, in case too many # convenience libraries get linked in and end up exceeding # the spec. if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then save_libobjs=$libobjs fi save_output=$output func_basename "$output" output_la=$func_basename_result # Clear the reloadable object creation command queue and # initialize k to one. test_cmds= concat_cmds= objlist= last_robj= k=1 if test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "$with_gnu_ld" = yes; then output=${output_objdir}/${output_la}.lnkscript func_verbose "creating GNU ld script: $output" echo 'INPUT (' > $output for obj in $save_libobjs do func_to_tool_file "$obj" $ECHO "$func_to_tool_file_result" >> $output done echo ')' >> $output func_append delfiles " $output" func_to_tool_file "$output" output=$func_to_tool_file_result elif test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "X$file_list_spec" != X; then output=${output_objdir}/${output_la}.lnk func_verbose "creating linker input file list: $output" : > $output set x $save_libobjs shift firstobj= if test "$compiler_needs_object" = yes; then firstobj="$1 " shift fi for obj do func_to_tool_file "$obj" $ECHO "$func_to_tool_file_result" >> $output done func_append delfiles " $output" func_to_tool_file "$output" output=$firstobj\"$file_list_spec$func_to_tool_file_result\" else if test -n "$save_libobjs"; then func_verbose "creating reloadable object files..." output=$output_objdir/$output_la-${k}.$objext eval test_cmds=\"$reload_cmds\" func_len " $test_cmds" len0=$func_len_result len=$len0 # Loop over the list of objects to be linked. for obj in $save_libobjs do func_len " $obj" func_arith $len + $func_len_result len=$func_arith_result if test "X$objlist" = X || test "$len" -lt "$max_cmd_len"; then func_append objlist " $obj" else # The command $test_cmds is almost too long, add a # command to the queue. if test "$k" -eq 1 ; then # The first file doesn't have a previous command to add. reload_objs=$objlist eval concat_cmds=\"$reload_cmds\" else # All subsequent reloadable object files will link in # the last one created. reload_objs="$objlist $last_robj" eval concat_cmds=\"\$concat_cmds~$reload_cmds~\$RM $last_robj\" fi last_robj=$output_objdir/$output_la-${k}.$objext func_arith $k + 1 k=$func_arith_result output=$output_objdir/$output_la-${k}.$objext objlist=" $obj" func_len " $last_robj" func_arith $len0 + $func_len_result len=$func_arith_result fi done # Handle the remaining objects by creating one last # reloadable object file. All subsequent reloadable object # files will link in the last one created. test -z "$concat_cmds" || concat_cmds=$concat_cmds~ reload_objs="$objlist $last_robj" eval concat_cmds=\"\${concat_cmds}$reload_cmds\" if test -n "$last_robj"; then eval concat_cmds=\"\${concat_cmds}~\$RM $last_robj\" fi func_append delfiles " $output" else output= fi if ${skipped_export-false}; then func_verbose "generating symbol list for \`$libname.la'" export_symbols="$output_objdir/$libname.exp" $opt_dry_run || $RM $export_symbols libobjs=$output # Append the command to create the export file. test -z "$concat_cmds" || concat_cmds=$concat_cmds~ eval concat_cmds=\"\$concat_cmds$export_symbols_cmds\" if test -n "$last_robj"; then eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\" fi fi test -n "$save_libobjs" && func_verbose "creating a temporary reloadable object file: $output" # Loop through the commands generated above and execute them. save_ifs="$IFS"; IFS='~' for cmd in $concat_cmds; do IFS="$save_ifs" $opt_silent || { func_quote_for_expand "$cmd" eval "func_echo $func_quote_for_expand_result" } $opt_dry_run || eval "$cmd" || { lt_exit=$? # Restore the uninstalled library and exit if test "$opt_mode" = relink; then ( cd "$output_objdir" && \ $RM "${realname}T" && \ $MV "${realname}U" "$realname" ) fi exit $lt_exit } done IFS="$save_ifs" if test -n "$export_symbols_regex" && ${skipped_export-false}; then func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' func_show_eval '$MV "${export_symbols}T" "$export_symbols"' fi fi if ${skipped_export-false}; then if test -n "$export_symbols" && test -n "$include_expsyms"; then tmp_export_symbols="$export_symbols" test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols" $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' fi if test -n "$orig_export_symbols"; then # The given exports_symbols file has to be filtered, so filter it. func_verbose "filter symbol list for \`$libname.la' to tag DATA exports" # FIXME: $output_objdir/$libname.filter potentially contains lots of # 's' commands which not all seds can handle. GNU sed should be fine # though. Also, the filter scales superlinearly with the number of # global variables. join(1) would be nice here, but unfortunately # isn't a blessed tool. $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter func_append delfiles " $export_symbols $output_objdir/$libname.filter" export_symbols=$output_objdir/$libname.def $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols fi fi libobjs=$output # Restore the value of output. output=$save_output if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then eval libobjs=\"\$libobjs $whole_archive_flag_spec\" test "X$libobjs" = "X " && libobjs= fi # Expand the library linking commands again to reset the # value of $libobjs for piecewise linking. # Do each of the archive commands. if test "$module" = yes && test -n "$module_cmds" ; then if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then cmds=$module_expsym_cmds else cmds=$module_cmds fi else if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then cmds=$archive_expsym_cmds else cmds=$archive_cmds fi fi fi if test -n "$delfiles"; then # Append the command to remove temporary files to $cmds. eval cmds=\"\$cmds~\$RM $delfiles\" fi # Add any objects from preloaded convenience libraries if test -n "$dlprefiles"; then gentop="$output_objdir/${outputname}x" func_append generated " $gentop" func_extract_archives $gentop $dlprefiles func_append libobjs " $func_extract_archives_result" test "X$libobjs" = "X " && libobjs= fi save_ifs="$IFS"; IFS='~' for cmd in $cmds; do IFS="$save_ifs" eval cmd=\"$cmd\" $opt_silent || { func_quote_for_expand "$cmd" eval "func_echo $func_quote_for_expand_result" } $opt_dry_run || eval "$cmd" || { lt_exit=$? # Restore the uninstalled library and exit if test "$opt_mode" = relink; then ( cd "$output_objdir" && \ $RM "${realname}T" && \ $MV "${realname}U" "$realname" ) fi exit $lt_exit } done IFS="$save_ifs" # Restore the uninstalled library and exit if test "$opt_mode" = relink; then $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}T && $MV $realname ${realname}T && $MV ${realname}U $realname)' || exit $? if test -n "$convenience"; then if test -z "$whole_archive_flag_spec"; then func_show_eval '${RM}r "$gentop"' fi fi exit $EXIT_SUCCESS fi # Create links to the real library. for linkname in $linknames; do if test "$realname" != "$linkname"; then func_show_eval '(cd "$output_objdir" && $RM "$linkname" && $LN_S "$realname" "$linkname")' 'exit $?' fi done # If -module or -export-dynamic was specified, set the dlname. if test "$module" = yes || test "$export_dynamic" = yes; then # On all known operating systems, these are identical. dlname="$soname" fi fi ;; obj) if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then func_warning "\`-dlopen' is ignored for objects" fi case " $deplibs" in *\ -l* | *\ -L*) func_warning "\`-l' and \`-L' are ignored for objects" ;; esac test -n "$rpath" && \ func_warning "\`-rpath' is ignored for objects" test -n "$xrpath" && \ func_warning "\`-R' is ignored for objects" test -n "$vinfo" && \ func_warning "\`-version-info' is ignored for objects" test -n "$release" && \ func_warning "\`-release' is ignored for objects" case $output in *.lo) test -n "$objs$old_deplibs" && \ func_fatal_error "cannot build library object \`$output' from non-libtool objects" libobj=$output func_lo2o "$libobj" obj=$func_lo2o_result ;; *) libobj= obj="$output" ;; esac # Delete the old objects. $opt_dry_run || $RM $obj $libobj # Objects from convenience libraries. This assumes # single-version convenience libraries. Whenever we create # different ones for PIC/non-PIC, this we'll have to duplicate # the extraction. reload_conv_objs= gentop= # reload_cmds runs $LD directly, so let us get rid of # -Wl from whole_archive_flag_spec and hope we can get by with # turning comma into space.. wl= if test -n "$convenience"; then if test -n "$whole_archive_flag_spec"; then eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\" reload_conv_objs=$reload_objs\ `$ECHO "$tmp_whole_archive_flags" | $SED 's|,| |g'` else gentop="$output_objdir/${obj}x" func_append generated " $gentop" func_extract_archives $gentop $convenience reload_conv_objs="$reload_objs $func_extract_archives_result" fi fi # If we're not building shared, we need to use non_pic_objs test "$build_libtool_libs" != yes && libobjs="$non_pic_objects" # Create the old-style object. reload_objs="$objs$old_deplibs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.${libext}$/d; /\.lib$/d; $lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test output="$obj" func_execute_cmds "$reload_cmds" 'exit $?' # Exit if we aren't doing a library object file. if test -z "$libobj"; then if test -n "$gentop"; then func_show_eval '${RM}r "$gentop"' fi exit $EXIT_SUCCESS fi if test "$build_libtool_libs" != yes; then if test -n "$gentop"; then func_show_eval '${RM}r "$gentop"' fi # Create an invalid libtool object if no PIC, so that we don't # accidentally link it into a program. # $show "echo timestamp > $libobj" # $opt_dry_run || eval "echo timestamp > $libobj" || exit $? exit $EXIT_SUCCESS fi if test -n "$pic_flag" || test "$pic_mode" != default; then # Only do commands if we really have different PIC objects. reload_objs="$libobjs $reload_conv_objs" output="$libobj" func_execute_cmds "$reload_cmds" 'exit $?' fi if test -n "$gentop"; then func_show_eval '${RM}r "$gentop"' fi exit $EXIT_SUCCESS ;; prog) case $host in *cygwin*) func_stripname '' '.exe' "$output" output=$func_stripname_result.exe;; esac test -n "$vinfo" && \ func_warning "\`-version-info' is ignored for programs" test -n "$release" && \ func_warning "\`-release' is ignored for programs" test "$preload" = yes \ && test "$dlopen_support" = unknown \ && test "$dlopen_self" = unknown \ && test "$dlopen_self_static" = unknown && \ func_warning "\`LT_INIT([dlopen])' not used. Assuming no dlopen support." case $host in *-*-rhapsody* | *-*-darwin1.[012]) # On Rhapsody replace the C library is the System framework compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's/ -lc / System.ltframework /'` finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's/ -lc / System.ltframework /'` ;; esac case $host in *-*-darwin*) # Don't allow lazy linking, it breaks C++ global constructors # But is supposedly fixed on 10.4 or later (yay!). if test "$tagname" = CXX ; then case ${MACOSX_DEPLOYMENT_TARGET-10.0} in 10.[0123]) func_append compile_command " ${wl}-bind_at_load" func_append finalize_command " ${wl}-bind_at_load" ;; esac fi # Time to change all our "foo.ltframework" stuff back to "-framework foo" compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` ;; esac # move library search paths that coincide with paths to not yet # installed libraries to the beginning of the library search list new_libs= for path in $notinst_path; do case " $new_libs " in *" -L$path/$objdir "*) ;; *) case " $compile_deplibs " in *" -L$path/$objdir "*) func_append new_libs " -L$path/$objdir" ;; esac ;; esac done for deplib in $compile_deplibs; do case $deplib in -L*) case " $new_libs " in *" $deplib "*) ;; *) func_append new_libs " $deplib" ;; esac ;; *) func_append new_libs " $deplib" ;; esac done compile_deplibs="$new_libs" func_append compile_command " $compile_deplibs" func_append finalize_command " $finalize_deplibs" if test -n "$rpath$xrpath"; then # If the user specified any rpath flags, then add them. for libdir in $rpath $xrpath; do # This is the magic to use -rpath. case "$finalize_rpath " in *" $libdir "*) ;; *) func_append finalize_rpath " $libdir" ;; esac done fi # Now hardcode the library paths rpath= hardcode_libdirs= for libdir in $compile_rpath $finalize_rpath; do if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then if test -z "$hardcode_libdirs"; then hardcode_libdirs="$libdir" else # Just accumulate the unique libdirs. case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ;; *) func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" ;; esac fi else eval flag=\"$hardcode_libdir_flag_spec\" func_append rpath " $flag" fi elif test -n "$runpath_var"; then case "$perm_rpath " in *" $libdir "*) ;; *) func_append perm_rpath " $libdir" ;; esac fi case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) testbindir=`${ECHO} "$libdir" | ${SED} -e 's*/lib$*/bin*'` case :$dllsearchpath: in *":$libdir:"*) ;; ::) dllsearchpath=$libdir;; *) func_append dllsearchpath ":$libdir";; esac case :$dllsearchpath: in *":$testbindir:"*) ;; ::) dllsearchpath=$testbindir;; *) func_append dllsearchpath ":$testbindir";; esac ;; esac done # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then libdir="$hardcode_libdirs" eval rpath=\" $hardcode_libdir_flag_spec\" fi compile_rpath="$rpath" rpath= hardcode_libdirs= for libdir in $finalize_rpath; do if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then if test -z "$hardcode_libdirs"; then hardcode_libdirs="$libdir" else # Just accumulate the unique libdirs. case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ;; *) func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" ;; esac fi else eval flag=\"$hardcode_libdir_flag_spec\" func_append rpath " $flag" fi elif test -n "$runpath_var"; then case "$finalize_perm_rpath " in *" $libdir "*) ;; *) func_append finalize_perm_rpath " $libdir" ;; esac fi done # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then libdir="$hardcode_libdirs" eval rpath=\" $hardcode_libdir_flag_spec\" fi finalize_rpath="$rpath" if test -n "$libobjs" && test "$build_old_libs" = yes; then # Transform all the library objects into standard objects. compile_command=`$ECHO "$compile_command" | $SP2NL | $SED "$lo2o" | $NL2SP` finalize_command=`$ECHO "$finalize_command" | $SP2NL | $SED "$lo2o" | $NL2SP` fi func_generate_dlsyms "$outputname" "@PROGRAM@" "no" # template prelinking step if test -n "$prelink_cmds"; then func_execute_cmds "$prelink_cmds" 'exit $?' fi wrappers_required=yes case $host in *cegcc* | *mingw32ce*) # Disable wrappers for cegcc and mingw32ce hosts, we are cross compiling anyway. wrappers_required=no ;; *cygwin* | *mingw* ) if test "$build_libtool_libs" != yes; then wrappers_required=no fi ;; *) if test "$need_relink" = no || test "$build_libtool_libs" != yes; then wrappers_required=no fi ;; esac if test "$wrappers_required" = no; then # Replace the output file specification. compile_command=`$ECHO "$compile_command" | $SED 's%@OUTPUT@%'"$output"'%g'` link_command="$compile_command$compile_rpath" # We have no uninstalled library dependencies, so finalize right now. exit_status=0 func_show_eval "$link_command" 'exit_status=$?' if test -n "$postlink_cmds"; then func_to_tool_file "$output" postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` func_execute_cmds "$postlink_cmds" 'exit $?' fi # Delete the generated files. if test -f "$output_objdir/${outputname}S.${objext}"; then func_show_eval '$RM "$output_objdir/${outputname}S.${objext}"' fi exit $exit_status fi if test -n "$compile_shlibpath$finalize_shlibpath"; then compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command" fi if test -n "$finalize_shlibpath"; then finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command" fi compile_var= finalize_var= if test -n "$runpath_var"; then if test -n "$perm_rpath"; then # We should set the runpath_var. rpath= for dir in $perm_rpath; do func_append rpath "$dir:" done compile_var="$runpath_var=\"$rpath\$$runpath_var\" " fi if test -n "$finalize_perm_rpath"; then # We should set the runpath_var. rpath= for dir in $finalize_perm_rpath; do func_append rpath "$dir:" done finalize_var="$runpath_var=\"$rpath\$$runpath_var\" " fi fi if test "$no_install" = yes; then # We don't need to create a wrapper script. link_command="$compile_var$compile_command$compile_rpath" # Replace the output file specification. link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output"'%g'` # Delete the old output file. $opt_dry_run || $RM $output # Link the executable and exit func_show_eval "$link_command" 'exit $?' if test -n "$postlink_cmds"; then func_to_tool_file "$output" postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` func_execute_cmds "$postlink_cmds" 'exit $?' fi exit $EXIT_SUCCESS fi if test "$hardcode_action" = relink; then # Fast installation is not supported link_command="$compile_var$compile_command$compile_rpath" relink_command="$finalize_var$finalize_command$finalize_rpath" func_warning "this platform does not like uninstalled shared libraries" func_warning "\`$output' will be relinked during installation" else if test "$fast_install" != no; then link_command="$finalize_var$compile_command$finalize_rpath" if test "$fast_install" = yes; then relink_command=`$ECHO "$compile_var$compile_command$compile_rpath" | $SED 's%@OUTPUT@%\$progdir/\$file%g'` else # fast_install is set to needless relink_command= fi else link_command="$compile_var$compile_command$compile_rpath" relink_command="$finalize_var$finalize_command$finalize_rpath" fi fi # Replace the output file specification. link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'` # Delete the old output files. $opt_dry_run || $RM $output $output_objdir/$outputname $output_objdir/lt-$outputname func_show_eval "$link_command" 'exit $?' if test -n "$postlink_cmds"; then func_to_tool_file "$output_objdir/$outputname" postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` func_execute_cmds "$postlink_cmds" 'exit $?' fi # Now create the wrapper script. func_verbose "creating $output" # Quote the relink command for shipping. if test -n "$relink_command"; then # Preserve any variables that may affect compiler behavior for var in $variables_saved_for_relink; do if eval test -z \"\${$var+set}\"; then relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" elif eval var_value=\$$var; test -z "$var_value"; then relink_command="$var=; export $var; $relink_command" else func_quote_for_eval "$var_value" relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" fi done relink_command="(cd `pwd`; $relink_command)" relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"` fi # Only actually do things if not in dry run mode. $opt_dry_run || { # win32 will think the script is a binary if it has # a .exe suffix, so we strip it off here. case $output in *.exe) func_stripname '' '.exe' "$output" output=$func_stripname_result ;; esac # test for cygwin because mv fails w/o .exe extensions case $host in *cygwin*) exeext=.exe func_stripname '' '.exe' "$outputname" outputname=$func_stripname_result ;; *) exeext= ;; esac case $host in *cygwin* | *mingw* ) func_dirname_and_basename "$output" "" "." output_name=$func_basename_result output_path=$func_dirname_result cwrappersource="$output_path/$objdir/lt-$output_name.c" cwrapper="$output_path/$output_name.exe" $RM $cwrappersource $cwrapper trap "$RM $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15 func_emit_cwrapperexe_src > $cwrappersource # The wrapper executable is built using the $host compiler, # because it contains $host paths and files. If cross- # compiling, it, like the target executable, must be # executed on the $host or under an emulation environment. $opt_dry_run || { $LTCC $LTCFLAGS -o $cwrapper $cwrappersource $STRIP $cwrapper } # Now, create the wrapper script for func_source use: func_ltwrapper_scriptname $cwrapper $RM $func_ltwrapper_scriptname_result trap "$RM $func_ltwrapper_scriptname_result; exit $EXIT_FAILURE" 1 2 15 $opt_dry_run || { # note: this script will not be executed, so do not chmod. if test "x$build" = "x$host" ; then $cwrapper --lt-dump-script > $func_ltwrapper_scriptname_result else func_emit_wrapper no > $func_ltwrapper_scriptname_result fi } ;; * ) $RM $output trap "$RM $output; exit $EXIT_FAILURE" 1 2 15 func_emit_wrapper no > $output chmod +x $output ;; esac } exit $EXIT_SUCCESS ;; esac # See if we need to build an old-fashioned archive. for oldlib in $oldlibs; do if test "$build_libtool_libs" = convenience; then oldobjs="$libobjs_save $symfileobj" addlibs="$convenience" build_libtool_libs=no else if test "$build_libtool_libs" = module; then oldobjs="$libobjs_save" build_libtool_libs=no else oldobjs="$old_deplibs $non_pic_objects" if test "$preload" = yes && test -f "$symfileobj"; then func_append oldobjs " $symfileobj" fi fi addlibs="$old_convenience" fi if test -n "$addlibs"; then gentop="$output_objdir/${outputname}x" func_append generated " $gentop" func_extract_archives $gentop $addlibs func_append oldobjs " $func_extract_archives_result" fi # Do each command in the archive commands. if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then cmds=$old_archive_from_new_cmds else # Add any objects from preloaded convenience libraries if test -n "$dlprefiles"; then gentop="$output_objdir/${outputname}x" func_append generated " $gentop" func_extract_archives $gentop $dlprefiles func_append oldobjs " $func_extract_archives_result" fi # POSIX demands no paths to be encoded in archives. We have # to avoid creating archives with duplicate basenames if we # might have to extract them afterwards, e.g., when creating a # static archive out of a convenience library, or when linking # the entirety of a libtool archive into another (currently # not supported by libtool). if (for obj in $oldobjs do func_basename "$obj" $ECHO "$func_basename_result" done | sort | sort -uc >/dev/null 2>&1); then : else echo "copying selected object files to avoid basename conflicts..." gentop="$output_objdir/${outputname}x" func_append generated " $gentop" func_mkdir_p "$gentop" save_oldobjs=$oldobjs oldobjs= counter=1 for obj in $save_oldobjs do func_basename "$obj" objbase="$func_basename_result" case " $oldobjs " in " ") oldobjs=$obj ;; *[\ /]"$objbase "*) while :; do # Make sure we don't pick an alternate name that also # overlaps. newobj=lt$counter-$objbase func_arith $counter + 1 counter=$func_arith_result case " $oldobjs " in *[\ /]"$newobj "*) ;; *) if test ! -f "$gentop/$newobj"; then break; fi ;; esac done func_show_eval "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj" func_append oldobjs " $gentop/$newobj" ;; *) func_append oldobjs " $obj" ;; esac done fi func_to_tool_file "$oldlib" func_convert_file_msys_to_w32 tool_oldlib=$func_to_tool_file_result eval cmds=\"$old_archive_cmds\" func_len " $cmds" len=$func_len_result if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then cmds=$old_archive_cmds elif test -n "$archiver_list_spec"; then func_verbose "using command file archive linking..." for obj in $oldobjs do func_to_tool_file "$obj" $ECHO "$func_to_tool_file_result" done > $output_objdir/$libname.libcmd func_to_tool_file "$output_objdir/$libname.libcmd" oldobjs=" $archiver_list_spec$func_to_tool_file_result" cmds=$old_archive_cmds else # the command line is too long to link in one step, link in parts func_verbose "using piecewise archive linking..." save_RANLIB=$RANLIB RANLIB=: objlist= concat_cmds= save_oldobjs=$oldobjs oldobjs= # Is there a better way of finding the last object in the list? for obj in $save_oldobjs do last_oldobj=$obj done eval test_cmds=\"$old_archive_cmds\" func_len " $test_cmds" len0=$func_len_result len=$len0 for obj in $save_oldobjs do func_len " $obj" func_arith $len + $func_len_result len=$func_arith_result func_append objlist " $obj" if test "$len" -lt "$max_cmd_len"; then : else # the above command should be used before it gets too long oldobjs=$objlist if test "$obj" = "$last_oldobj" ; then RANLIB=$save_RANLIB fi test -z "$concat_cmds" || concat_cmds=$concat_cmds~ eval concat_cmds=\"\${concat_cmds}$old_archive_cmds\" objlist= len=$len0 fi done RANLIB=$save_RANLIB oldobjs=$objlist if test "X$oldobjs" = "X" ; then eval cmds=\"\$concat_cmds\" else eval cmds=\"\$concat_cmds~\$old_archive_cmds\" fi fi fi func_execute_cmds "$cmds" 'exit $?' done test -n "$generated" && \ func_show_eval "${RM}r$generated" # Now create the libtool archive. case $output in *.la) old_library= test "$build_old_libs" = yes && old_library="$libname.$libext" func_verbose "creating $output" # Preserve any variables that may affect compiler behavior for var in $variables_saved_for_relink; do if eval test -z \"\${$var+set}\"; then relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" elif eval var_value=\$$var; test -z "$var_value"; then relink_command="$var=; export $var; $relink_command" else func_quote_for_eval "$var_value" relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" fi done # Quote the link command for shipping. relink_command="(cd `pwd`; $SHELL $progpath $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)" relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"` if test "$hardcode_automatic" = yes ; then relink_command= fi # Only create the output if not a dry run. $opt_dry_run || { for installed in no yes; do if test "$installed" = yes; then if test -z "$install_libdir"; then break fi output="$output_objdir/$outputname"i # Replace all uninstalled libtool libraries with the installed ones newdependency_libs= for deplib in $dependency_libs; do case $deplib in *.la) func_basename "$deplib" name="$func_basename_result" func_resolve_sysroot "$deplib" eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $func_resolve_sysroot_result` test -z "$libdir" && \ func_fatal_error "\`$deplib' is not a valid libtool archive" func_append newdependency_libs " ${lt_sysroot:+=}$libdir/$name" ;; -L*) func_stripname -L '' "$deplib" func_replace_sysroot "$func_stripname_result" func_append newdependency_libs " -L$func_replace_sysroot_result" ;; -R*) func_stripname -R '' "$deplib" func_replace_sysroot "$func_stripname_result" func_append newdependency_libs " -R$func_replace_sysroot_result" ;; *) func_append newdependency_libs " $deplib" ;; esac done dependency_libs="$newdependency_libs" newdlfiles= for lib in $dlfiles; do case $lib in *.la) func_basename "$lib" name="$func_basename_result" eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` test -z "$libdir" && \ func_fatal_error "\`$lib' is not a valid libtool archive" func_append newdlfiles " ${lt_sysroot:+=}$libdir/$name" ;; *) func_append newdlfiles " $lib" ;; esac done dlfiles="$newdlfiles" newdlprefiles= for lib in $dlprefiles; do case $lib in *.la) # Only pass preopened files to the pseudo-archive (for # eventual linking with the app. that links it) if we # didn't already link the preopened objects directly into # the library: func_basename "$lib" name="$func_basename_result" eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` test -z "$libdir" && \ func_fatal_error "\`$lib' is not a valid libtool archive" func_append newdlprefiles " ${lt_sysroot:+=}$libdir/$name" ;; esac done dlprefiles="$newdlprefiles" else newdlfiles= for lib in $dlfiles; do case $lib in [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; *) abs=`pwd`"/$lib" ;; esac func_append newdlfiles " $abs" done dlfiles="$newdlfiles" newdlprefiles= for lib in $dlprefiles; do case $lib in [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; *) abs=`pwd`"/$lib" ;; esac func_append newdlprefiles " $abs" done dlprefiles="$newdlprefiles" fi $RM $output # place dlname in correct position for cygwin # In fact, it would be nice if we could use this code for all target # systems that can't hard-code library paths into their executables # and that have no shared library path variable independent of PATH, # but it turns out we can't easily determine that from inspecting # libtool variables, so we have to hard-code the OSs to which it # applies here; at the moment, that means platforms that use the PE # object format with DLL files. See the long comment at the top of # tests/bindir.at for full details. tdlname=$dlname case $host,$output,$installed,$module,$dlname in *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll) # If a -bindir argument was supplied, place the dll there. if test "x$bindir" != x ; then func_relative_path "$install_libdir" "$bindir" tdlname=$func_relative_path_result$dlname else # Otherwise fall back on heuristic. tdlname=../bin/$dlname fi ;; esac $ECHO > $output "\ # $outputname - a libtool library file # Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION # # Please DO NOT delete this file! # It is necessary for linking the library. # The name that we can dlopen(3). dlname='$tdlname' # Names of this library. library_names='$library_names' # The name of the static archive. old_library='$old_library' # Linker flags that can not go in dependency_libs. inherited_linker_flags='$new_inherited_linker_flags' # Libraries that this one depends upon. dependency_libs='$dependency_libs' # Names of additional weak libraries provided by this library weak_library_names='$weak_libs' # Version information for $libname. current=$current age=$age revision=$revision # Is this an already installed library? installed=$installed # Should we warn about portability when linking against -modules? shouldnotlink=$module # Files to dlopen/dlpreopen dlopen='$dlfiles' dlpreopen='$dlprefiles' # Directory that this library needs to be installed in: libdir='$install_libdir'" if test "$installed" = no && test "$need_relink" = yes; then $ECHO >> $output "\ relink_command=\"$relink_command\"" fi done } # Do a symbolic link so that the libtool archive can be found in # LD_LIBRARY_PATH before the program is installed. func_show_eval '( cd "$output_objdir" && $RM "$outputname" && $LN_S "../$outputname" "$outputname" )' 'exit $?' ;; esac exit $EXIT_SUCCESS } { test "$opt_mode" = link || test "$opt_mode" = relink; } && func_mode_link ${1+"$@"} # func_mode_uninstall arg... func_mode_uninstall () { $opt_debug RM="$nonopt" files= rmforce= exit_status=0 # This variable tells wrapper scripts just to set variables rather # than running their programs. libtool_install_magic="$magic" for arg do case $arg in -f) func_append RM " $arg"; rmforce=yes ;; -*) func_append RM " $arg" ;; *) func_append files " $arg" ;; esac done test -z "$RM" && \ func_fatal_help "you must specify an RM program" rmdirs= for file in $files; do func_dirname "$file" "" "." dir="$func_dirname_result" if test "X$dir" = X.; then odir="$objdir" else odir="$dir/$objdir" fi func_basename "$file" name="$func_basename_result" test "$opt_mode" = uninstall && odir="$dir" # Remember odir for removal later, being careful to avoid duplicates if test "$opt_mode" = clean; then case " $rmdirs " in *" $odir "*) ;; *) func_append rmdirs " $odir" ;; esac fi # Don't error if the file doesn't exist and rm -f was used. if { test -L "$file"; } >/dev/null 2>&1 || { test -h "$file"; } >/dev/null 2>&1 || test -f "$file"; then : elif test -d "$file"; then exit_status=1 continue elif test "$rmforce" = yes; then continue fi rmfiles="$file" case $name in *.la) # Possibly a libtool archive, so verify it. if func_lalib_p "$file"; then func_source $dir/$name # Delete the libtool libraries and symlinks. for n in $library_names; do func_append rmfiles " $odir/$n" done test -n "$old_library" && func_append rmfiles " $odir/$old_library" case "$opt_mode" in clean) case " $library_names " in *" $dlname "*) ;; *) test -n "$dlname" && func_append rmfiles " $odir/$dlname" ;; esac test -n "$libdir" && func_append rmfiles " $odir/$name $odir/${name}i" ;; uninstall) if test -n "$library_names"; then # Do each command in the postuninstall commands. func_execute_cmds "$postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1' fi if test -n "$old_library"; then # Do each command in the old_postuninstall commands. func_execute_cmds "$old_postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1' fi # FIXME: should reinstall the best remaining shared library. ;; esac fi ;; *.lo) # Possibly a libtool object, so verify it. if func_lalib_p "$file"; then # Read the .lo file func_source $dir/$name # Add PIC object to the list of files to remove. if test -n "$pic_object" && test "$pic_object" != none; then func_append rmfiles " $dir/$pic_object" fi # Add non-PIC object to the list of files to remove. if test -n "$non_pic_object" && test "$non_pic_object" != none; then func_append rmfiles " $dir/$non_pic_object" fi fi ;; *) if test "$opt_mode" = clean ; then noexename=$name case $file in *.exe) func_stripname '' '.exe' "$file" file=$func_stripname_result func_stripname '' '.exe' "$name" noexename=$func_stripname_result # $file with .exe has already been added to rmfiles, # add $file without .exe func_append rmfiles " $file" ;; esac # Do a test to see if this is a libtool program. if func_ltwrapper_p "$file"; then if func_ltwrapper_executable_p "$file"; then func_ltwrapper_scriptname "$file" relink_command= func_source $func_ltwrapper_scriptname_result func_append rmfiles " $func_ltwrapper_scriptname_result" else relink_command= func_source $dir/$noexename fi # note $name still contains .exe if it was in $file originally # as does the version of $file that was added into $rmfiles func_append rmfiles " $odir/$name $odir/${name}S.${objext}" if test "$fast_install" = yes && test -n "$relink_command"; then func_append rmfiles " $odir/lt-$name" fi if test "X$noexename" != "X$name" ; then func_append rmfiles " $odir/lt-${noexename}.c" fi fi fi ;; esac func_show_eval "$RM $rmfiles" 'exit_status=1' done # Try to remove the ${objdir}s in the directories where we deleted files for dir in $rmdirs; do if test -d "$dir"; then func_show_eval "rmdir $dir >/dev/null 2>&1" fi done exit $exit_status } { test "$opt_mode" = uninstall || test "$opt_mode" = clean; } && func_mode_uninstall ${1+"$@"} test -z "$opt_mode" && { help="$generic_help" func_fatal_help "you must specify a MODE" } test -z "$exec_cmd" && \ func_fatal_help "invalid operation mode \`$opt_mode'" if test -n "$exec_cmd"; then eval exec "$exec_cmd" exit $EXIT_FAILURE fi exit $exit_status # The TAGs below are defined such that we never get into a situation # in which we disable both kinds of libraries. Given conflicting # choices, we go for a static library, that is the most portable, # since we can't tell whether shared libraries were disabled because # the user asked for that or because the platform doesn't support # them. This is particularly important on AIX, because we don't # support having both static and shared libraries enabled at the same # time on that platform, so we default to a shared-only configuration. # If a disable-shared tag is given, we'll fallback to a static-only # configuration. But we'll never go from static-only to shared-only. # ### BEGIN LIBTOOL TAG CONFIG: disable-shared build_libtool_libs=no build_old_libs=yes # ### END LIBTOOL TAG CONFIG: disable-shared # ### BEGIN LIBTOOL TAG CONFIG: disable-static build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac` # ### END LIBTOOL TAG CONFIG: disable-static # Local Variables: # mode:shell-script # sh-indentation:2 # End: # vi:sw=2 dlt-daemon-2.18.4/gtest-1.7.0/build-aux/missing000077500000000000000000000241521353342203500207160ustar00rootroot00000000000000#! /bin/sh # Common stub for a few missing GNU programs while installing. scriptversion=2012-01-06.13; # UTC # Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2006, # 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc. # Originally by Fran,cois Pinard , 1996. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. if test $# -eq 0; then echo 1>&2 "Try \`$0 --help' for more information" exit 1 fi run=: sed_output='s/.* --output[ =]\([^ ]*\).*/\1/p' sed_minuso='s/.* -o \([^ ]*\).*/\1/p' # In the cases where this matters, `missing' is being run in the # srcdir already. if test -f configure.ac; then configure_ac=configure.ac else configure_ac=configure.in fi msg="missing on your system" case $1 in --run) # Try to run requested program, and just exit if it succeeds. run= shift "$@" && exit 0 # Exit code 63 means version mismatch. This often happens # when the user try to use an ancient version of a tool on # a file that requires a minimum version. In this case we # we should proceed has if the program had been absent, or # if --run hadn't been passed. if test $? = 63; then run=: msg="probably too old" fi ;; -h|--h|--he|--hel|--help) echo "\ $0 [OPTION]... PROGRAM [ARGUMENT]... Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an error status if there is no known handling for PROGRAM. Options: -h, --help display this help and exit -v, --version output version information and exit --run try to run the given command, and emulate it if it fails Supported PROGRAM values: aclocal touch file \`aclocal.m4' autoconf touch file \`configure' autoheader touch file \`config.h.in' autom4te touch the output file, or create a stub one automake touch all \`Makefile.in' files bison create \`y.tab.[ch]', if possible, from existing .[ch] flex create \`lex.yy.c', if possible, from existing .c help2man touch the output file lex create \`lex.yy.c', if possible, from existing .c makeinfo touch the output file yacc create \`y.tab.[ch]', if possible, from existing .[ch] Version suffixes to PROGRAM as well as the prefixes \`gnu-', \`gnu', and \`g' are ignored when checking the name. Send bug reports to ." exit $? ;; -v|--v|--ve|--ver|--vers|--versi|--versio|--version) echo "missing $scriptversion (GNU Automake)" exit $? ;; -*) echo 1>&2 "$0: Unknown \`$1' option" echo 1>&2 "Try \`$0 --help' for more information" exit 1 ;; esac # normalize program name to check for. program=`echo "$1" | sed ' s/^gnu-//; t s/^gnu//; t s/^g//; t'` # Now exit if we have it, but it failed. Also exit now if we # don't have it and --version was passed (most likely to detect # the program). This is about non-GNU programs, so use $1 not # $program. case $1 in lex*|yacc*) # Not GNU programs, they don't have --version. ;; *) if test -z "$run" && ($1 --version) > /dev/null 2>&1; then # We have it, but it failed. exit 1 elif test "x$2" = "x--version" || test "x$2" = "x--help"; then # Could not run --version or --help. This is probably someone # running `$TOOL --version' or `$TOOL --help' to check whether # $TOOL exists and not knowing $TOOL uses missing. exit 1 fi ;; esac # If it does not exist, or fails to run (possibly an outdated version), # try to emulate it. case $program in aclocal*) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified \`acinclude.m4' or \`${configure_ac}'. You might want to install the \`Automake' and \`Perl' packages. Grab them from any GNU archive site." touch aclocal.m4 ;; autoconf*) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified \`${configure_ac}'. You might want to install the \`Autoconf' and \`GNU m4' packages. Grab them from any GNU archive site." touch configure ;; autoheader*) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified \`acconfig.h' or \`${configure_ac}'. You might want to install the \`Autoconf' and \`GNU m4' packages. Grab them from any GNU archive site." files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}` test -z "$files" && files="config.h" touch_files= for f in $files; do case $f in *:*) touch_files="$touch_files "`echo "$f" | sed -e 's/^[^:]*://' -e 's/:.*//'`;; *) touch_files="$touch_files $f.in";; esac done touch $touch_files ;; automake*) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'. You might want to install the \`Automake' and \`Perl' packages. Grab them from any GNU archive site." find . -type f -name Makefile.am -print | sed 's/\.am$/.in/' | while read f; do touch "$f"; done ;; autom4te*) echo 1>&2 "\ WARNING: \`$1' is needed, but is $msg. You might have modified some files without having the proper tools for further handling them. You can get \`$1' as part of \`Autoconf' from any GNU archive site." file=`echo "$*" | sed -n "$sed_output"` test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` if test -f "$file"; then touch $file else test -z "$file" || exec >$file echo "#! /bin/sh" echo "# Created by GNU Automake missing as a replacement of" echo "# $ $@" echo "exit 0" chmod +x $file exit 1 fi ;; bison*|yacc*) echo 1>&2 "\ WARNING: \`$1' $msg. You should only need it if you modified a \`.y' file. You may need the \`Bison' package in order for those modifications to take effect. You can get \`Bison' from any GNU archive site." rm -f y.tab.c y.tab.h if test $# -ne 1; then eval LASTARG=\${$#} case $LASTARG in *.y) SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` if test -f "$SRCFILE"; then cp "$SRCFILE" y.tab.c fi SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` if test -f "$SRCFILE"; then cp "$SRCFILE" y.tab.h fi ;; esac fi if test ! -f y.tab.h; then echo >y.tab.h fi if test ! -f y.tab.c; then echo 'main() { return 0; }' >y.tab.c fi ;; lex*|flex*) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified a \`.l' file. You may need the \`Flex' package in order for those modifications to take effect. You can get \`Flex' from any GNU archive site." rm -f lex.yy.c if test $# -ne 1; then eval LASTARG=\${$#} case $LASTARG in *.l) SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` if test -f "$SRCFILE"; then cp "$SRCFILE" lex.yy.c fi ;; esac fi if test ! -f lex.yy.c; then echo 'main() { return 0; }' >lex.yy.c fi ;; help2man*) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified a dependency of a manual page. You may need the \`Help2man' package in order for those modifications to take effect. You can get \`Help2man' from any GNU archive site." file=`echo "$*" | sed -n "$sed_output"` test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` if test -f "$file"; then touch $file else test -z "$file" || exec >$file echo ".ab help2man is required to generate this page" exit $? fi ;; makeinfo*) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified a \`.texi' or \`.texinfo' file, or any other file indirectly affecting the aspect of the manual. The spurious call might also be the consequence of using a buggy \`make' (AIX, DU, IRIX). You might want to install the \`Texinfo' package or the \`GNU make' package. Grab either from any GNU archive site." # The file to touch is that specified with -o ... file=`echo "$*" | sed -n "$sed_output"` test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` if test -z "$file"; then # ... or it is the one specified with @setfilename ... infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` file=`sed -n ' /^@setfilename/{ s/.* \([^ ]*\) *$/\1/ p q }' $infile` # ... or it is derived from the source name (dir/f.texi becomes f.info) test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info fi # If the file does not exist, the user really needs makeinfo; # let's fail without touching anything. test -f $file || exit 1 touch $file ;; *) echo 1>&2 "\ WARNING: \`$1' is needed, and is $msg. You might have modified some files without having the proper tools for further handling them. Check the \`README' file, it often tells you about the needed prerequisites for installing this package. You may also peek at any GNU archive site, in case some other package would contain this missing \`$1' program." exit 1 ;; esac exit 0 # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: dlt-daemon-2.18.4/gtest-1.7.0/build-aux/stamp-h1000066400000000000000000000000411353342203500206630ustar00rootroot00000000000000timestamp for build-aux/config.h dlt-daemon-2.18.4/gtest-1.7.0/cmake/000077500000000000000000000000001353342203500165015ustar00rootroot00000000000000dlt-daemon-2.18.4/gtest-1.7.0/cmake/internal_utils.cmake000066400000000000000000000225141353342203500225430ustar00rootroot00000000000000# Defines functions and macros useful for building Google Test and # Google Mock. # # Note: # # - This file will be run twice when building Google Mock (once via # Google Test's CMakeLists.txt, and once via Google Mock's). # Therefore it shouldn't have any side effects other than defining # the functions and macros. # # - The functions/macros defined in this file may depend on Google # Test and Google Mock's option() definitions, and thus must be # called *after* the options have been defined. # Tweaks CMake's default compiler/linker settings to suit Google Test's needs. # # This must be a macro(), as inside a function string() can only # update variables in the function scope. macro(fix_default_compiler_settings_) if (MSVC) # For MSVC, CMake sets certain flags to defaults we want to override. # This replacement code is taken from sample in the CMake Wiki at # http://www.cmake.org/Wiki/CMake_FAQ#Dynamic_Replace. foreach (flag_var CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO) if (NOT BUILD_SHARED_LIBS AND NOT gtest_force_shared_crt) # When Google Test is built as a shared library, it should also use # shared runtime libraries. Otherwise, it may end up with multiple # copies of runtime library data in different modules, resulting in # hard-to-find crashes. When it is built as a static library, it is # preferable to use CRT as static libraries, as we don't have to rely # on CRT DLLs being available. CMake always defaults to using shared # CRT libraries, so we override that default here. string(REPLACE "/MD" "-MT" ${flag_var} "${${flag_var}}") endif() # We prefer more strict warning checking for building Google Test. # Replaces /W3 with /W4 in defaults. string(REPLACE "/W3" "-W4" ${flag_var} "${${flag_var}}") endforeach() endif() endmacro() # Defines the compiler/linker flags used to build Google Test and # Google Mock. You can tweak these definitions to suit your need. A # variable's value is empty before it's explicitly assigned to. macro(config_compiler_and_linker) if (NOT gtest_disable_pthreads) # Defines CMAKE_USE_PTHREADS_INIT and CMAKE_THREAD_LIBS_INIT. find_package(Threads) endif() fix_default_compiler_settings_() if (MSVC) # Newlines inside flags variables break CMake's NMake generator. # TODO(vladl@google.com): Add -RTCs and -RTCu to debug builds. set(cxx_base_flags "-GS -W4 -WX -wd4127 -wd4251 -wd4275 -nologo -J -Zi") if (MSVC_VERSION LESS 1400) # Suppress spurious warnings MSVC 7.1 sometimes issues. # Forcing value to bool. set(cxx_base_flags "${cxx_base_flags} -wd4800") # Copy constructor and assignment operator could not be generated. set(cxx_base_flags "${cxx_base_flags} -wd4511 -wd4512") # Compatibility warnings not applicable to Google Test. # Resolved overload was found by argument-dependent lookup. set(cxx_base_flags "${cxx_base_flags} -wd4675") endif() set(cxx_base_flags "${cxx_base_flags} -D_UNICODE -DUNICODE -DWIN32 -D_WIN32") set(cxx_base_flags "${cxx_base_flags} -DSTRICT -DWIN32_LEAN_AND_MEAN") set(cxx_exception_flags "-EHsc -D_HAS_EXCEPTIONS=1") set(cxx_no_exception_flags "-D_HAS_EXCEPTIONS=0") set(cxx_no_rtti_flags "-GR-") elseif (CMAKE_COMPILER_IS_GNUCXX) set(cxx_base_flags "-Wall -Wshadow") set(cxx_exception_flags "-fexceptions") set(cxx_no_exception_flags "-fno-exceptions") # Until version 4.3.2, GCC doesn't define a macro to indicate # whether RTTI is enabled. Therefore we define GTEST_HAS_RTTI # explicitly. set(cxx_no_rtti_flags "-fno-rtti -DGTEST_HAS_RTTI=0") set(cxx_strict_flags "-Wextra -Wno-unused-parameter -Wno-missing-field-initializers") elseif (CMAKE_CXX_COMPILER_ID STREQUAL "SunPro") set(cxx_exception_flags "-features=except") # Sun Pro doesn't provide macros to indicate whether exceptions and # RTTI are enabled, so we define GTEST_HAS_* explicitly. set(cxx_no_exception_flags "-features=no%except -DGTEST_HAS_EXCEPTIONS=0") set(cxx_no_rtti_flags "-features=no%rtti -DGTEST_HAS_RTTI=0") elseif (CMAKE_CXX_COMPILER_ID STREQUAL "VisualAge" OR CMAKE_CXX_COMPILER_ID STREQUAL "XL") # CMake 2.8 changes Visual Age's compiler ID to "XL". set(cxx_exception_flags "-qeh") set(cxx_no_exception_flags "-qnoeh") # Until version 9.0, Visual Age doesn't define a macro to indicate # whether RTTI is enabled. Therefore we define GTEST_HAS_RTTI # explicitly. set(cxx_no_rtti_flags "-qnortti -DGTEST_HAS_RTTI=0") elseif (CMAKE_CXX_COMPILER_ID STREQUAL "HP") set(cxx_base_flags "-AA -mt") set(cxx_exception_flags "-DGTEST_HAS_EXCEPTIONS=1") set(cxx_no_exception_flags "+noeh -DGTEST_HAS_EXCEPTIONS=0") # RTTI can not be disabled in HP aCC compiler. set(cxx_no_rtti_flags "") endif() if (CMAKE_USE_PTHREADS_INIT) # The pthreads library is available and allowed. set(cxx_base_flags "${cxx_base_flags} -DGTEST_HAS_PTHREAD=1") else() set(cxx_base_flags "${cxx_base_flags} -DGTEST_HAS_PTHREAD=0") endif() # For building gtest's own tests and samples. set(cxx_exception "${CMAKE_CXX_FLAGS} ${cxx_base_flags} ${cxx_exception_flags}") set(cxx_no_exception "${CMAKE_CXX_FLAGS} ${cxx_base_flags} ${cxx_no_exception_flags}") set(cxx_default "${cxx_exception}") set(cxx_no_rtti "${cxx_default} ${cxx_no_rtti_flags}") set(cxx_use_own_tuple "${cxx_default} -DGTEST_USE_OWN_TR1_TUPLE=1") # For building the gtest libraries. set(cxx_strict "${cxx_default} ${cxx_strict_flags}") endmacro() # Defines the gtest & gtest_main libraries. User tests should link # with one of them. function(cxx_library_with_type name type cxx_flags) # type can be either STATIC or SHARED to denote a static or shared library. # ARGN refers to additional arguments after 'cxx_flags'. add_library(${name} ${type} ${ARGN}) set_target_properties(${name} PROPERTIES COMPILE_FLAGS "${cxx_flags}") if (BUILD_SHARED_LIBS OR type STREQUAL "SHARED") set_target_properties(${name} PROPERTIES COMPILE_DEFINITIONS "GTEST_CREATE_SHARED_LIBRARY=1") endif() if (CMAKE_USE_PTHREADS_INIT) target_link_libraries(${name} ${CMAKE_THREAD_LIBS_INIT}) endif() endfunction() ######################################################################## # # Helper functions for creating build targets. function(cxx_shared_library name cxx_flags) cxx_library_with_type(${name} SHARED "${cxx_flags}" ${ARGN}) endfunction() function(cxx_library name cxx_flags) cxx_library_with_type(${name} "" "${cxx_flags}" ${ARGN}) endfunction() # cxx_executable_with_flags(name cxx_flags libs srcs...) # # creates a named C++ executable that depends on the given libraries and # is built from the given source files with the given compiler flags. function(cxx_executable_with_flags name cxx_flags libs) add_executable(${name} ${ARGN}) if (cxx_flags) set_target_properties(${name} PROPERTIES COMPILE_FLAGS "${cxx_flags}") endif() if (BUILD_SHARED_LIBS) set_target_properties(${name} PROPERTIES COMPILE_DEFINITIONS "GTEST_LINKED_AS_SHARED_LIBRARY=1") endif() # To support mixing linking in static and dynamic libraries, link each # library in with an extra call to target_link_libraries. foreach (lib "${libs}") target_link_libraries(${name} ${lib}) endforeach() endfunction() # cxx_executable(name dir lib srcs...) # # creates a named target that depends on the given libs and is built # from the given source files. dir/name.cc is implicitly included in # the source file list. function(cxx_executable name dir libs) cxx_executable_with_flags( ${name} "${cxx_default}" "${libs}" "${dir}/${name}.cc" ${ARGN}) endfunction() # Sets PYTHONINTERP_FOUND and PYTHON_EXECUTABLE. find_package(PythonInterp) # cxx_test_with_flags(name cxx_flags libs srcs...) # # creates a named C++ test that depends on the given libs and is built # from the given source files with the given compiler flags. function(cxx_test_with_flags name cxx_flags libs) cxx_executable_with_flags(${name} "${cxx_flags}" "${libs}" ${ARGN}) add_test(${name} ${name}) endfunction() # cxx_test(name libs srcs...) # # creates a named test target that depends on the given libs and is # built from the given source files. Unlike cxx_test_with_flags, # test/name.cc is already implicitly included in the source file list. function(cxx_test name libs) cxx_test_with_flags("${name}" "${cxx_default}" "${libs}" "test/${name}.cc" ${ARGN}) endfunction() # py_test(name) # # creates a Python test with the given name whose main module is in # test/name.py. It does nothing if Python is not installed. function(py_test name) # We are not supporting Python tests on Linux yet as they consider # all Linux environments to be google3 and try to use google3 features. if (PYTHONINTERP_FOUND) # ${CMAKE_BINARY_DIR} is known at configuration time, so we can # directly bind it from cmake. ${CTEST_CONFIGURATION_TYPE} is known # only at ctest runtime (by calling ctest -c ), so # we have to escape $ to delay variable substitution here. add_test(${name} ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test/${name}.py --build_dir=${CMAKE_CURRENT_BINARY_DIR}/\${CTEST_CONFIGURATION_TYPE}) endif() endfunction() dlt-daemon-2.18.4/gtest-1.7.0/codegear/000077500000000000000000000000001353342203500171725ustar00rootroot00000000000000dlt-daemon-2.18.4/gtest-1.7.0/codegear/gtest.cbproj000066400000000000000000000243661353342203500215340ustar00rootroot00000000000000 {bca37a72-5b07-46cf-b44e-89f8e06451a2} Release true true true Base true true Base true lib JPHNE NO_STRICT true true CppStaticLibrary true rtl.bpi;vcl.bpi;bcbie.bpi;vclx.bpi;vclactnband.bpi;xmlrtl.bpi;bcbsmp.bpi;dbrtl.bpi;vcldb.bpi;bdertl.bpi;vcldbx.bpi;dsnap.bpi;dsnapcon.bpi;vclib.bpi;ibxpress.bpi;adortl.bpi;dbxcds.bpi;dbexpress.bpi;DbxCommonDriver.bpi;websnap.bpi;vclie.bpi;webdsnap.bpi;inet.bpi;inetdbbde.bpi;inetdbxpress.bpi;soaprtl.bpi;Rave75VCL.bpi;teeUI.bpi;tee.bpi;teedb.bpi;IndyCore.bpi;IndySystem.bpi;IndyProtocols.bpi;IntrawebDB_90_100.bpi;Intraweb_90_100.bpi;dclZipForged11.bpi;vclZipForged11.bpi;GR32_BDS2006.bpi;GR32_DSGN_BDS2006.bpi;Jcl.bpi;JclVcl.bpi;JvCoreD11R.bpi;JvSystemD11R.bpi;JvStdCtrlsD11R.bpi;JvAppFrmD11R.bpi;JvBandsD11R.bpi;JvDBD11R.bpi;JvDlgsD11R.bpi;JvBDED11R.bpi;JvCmpD11R.bpi;JvCryptD11R.bpi;JvCtrlsD11R.bpi;JvCustomD11R.bpi;JvDockingD11R.bpi;JvDotNetCtrlsD11R.bpi;JvEDID11R.bpi;JvGlobusD11R.bpi;JvHMID11R.bpi;JvInterpreterD11R.bpi;JvJansD11R.bpi;JvManagedThreadsD11R.bpi;JvMMD11R.bpi;JvNetD11R.bpi;JvPageCompsD11R.bpi;JvPluginD11R.bpi;JvPrintPreviewD11R.bpi;JvRuntimeDesignD11R.bpi;JvTimeFrameworkD11R.bpi;JvValidatorsD11R.bpi;JvWizardD11R.bpi;JvXPCtrlsD11R.bpi;VclSmp.bpi;CExceptionExpert11.bpi false $(BDS)\include;$(BDS)\include\dinkumware;$(BDS)\include\vcl;..\src;..\include;.. rtl.lib;vcl.lib 32 $(BDS)\lib;$(BDS)\lib\obj;$(BDS)\lib\psdk false false true _DEBUG;$(Defines) true false true None DEBUG true Debug true true true $(BDS)\lib\debug;$(ILINK_LibraryPath) Full true NDEBUG;$(Defines) Release $(BDS)\lib\release;$(ILINK_LibraryPath) None CPlusPlusBuilder.Personality CppStaticLibrary FalseFalse1000FalseFalseFalseFalseFalse103312521.0.0.01.0.0.0FalseFalseFalseTrueFalse CodeGear C++Builder Office 2000 Servers Package CodeGear C++Builder Office XP Servers Package FalseTrueTrue3$(BDS)\include;$(BDS)\include\dinkumware;$(BDS)\include\vcl;..\src;..\include;..$(BDS)\include;$(BDS)\include\dinkumware;$(BDS)\include\vcl;..\src;..\include;..$(BDS)\include;$(BDS)\include\dinkumware;$(BDS)\include\vcl;..\src;..\src;..\include1$(BDS)\lib;$(BDS)\lib\obj;$(BDS)\lib\psdk1NO_STRICT13216 3 4 5 6 7 8 0 1 2 9 10 11 12 14 13 15 16 17 18 Cfg_1 Cfg_2 dlt-daemon-2.18.4/gtest-1.7.0/codegear/gtest.groupproj000066400000000000000000000037301353342203500222740ustar00rootroot00000000000000 {c1d923e0-6cba-4332-9b6f-3420acbf5091} Default.Personality dlt-daemon-2.18.4/gtest-1.7.0/codegear/gtest_all.cc000066400000000000000000000035111353342203500214570ustar00rootroot00000000000000// Copyright 2009, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: Josh Kelley (joshkel@gmail.com) // // Google C++ Testing Framework (Google Test) // // C++Builder's IDE cannot build a static library from files with hyphens // in their name. See http://qc.codegear.com/wc/qcmain.aspx?d=70977 . // This file serves as a workaround. #include "src/gtest-all.cc" dlt-daemon-2.18.4/gtest-1.7.0/codegear/gtest_link.cc000066400000000000000000000037111353342203500216460ustar00rootroot00000000000000// Copyright 2009, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: Josh Kelley (joshkel@gmail.com) // // Google C++ Testing Framework (Google Test) // // Links gtest.lib and gtest_main.lib into the current project in C++Builder. // This means that these libraries can't be renamed, but it's the only way to // ensure that Debug versus Release test builds are linked against the // appropriate Debug or Release build of the libraries. #pragma link "gtest.lib" #pragma link "gtest_main.lib" dlt-daemon-2.18.4/gtest-1.7.0/codegear/gtest_main.cbproj000066400000000000000000000206041353342203500225270ustar00rootroot00000000000000 {bca37a72-5b07-46cf-b44e-89f8e06451a2} Release true true true Base true true Base true lib JPHNE NO_STRICT true true CppStaticLibrary true rtl.bpi;vcl.bpi;bcbie.bpi;vclx.bpi;vclactnband.bpi;xmlrtl.bpi;bcbsmp.bpi;dbrtl.bpi;vcldb.bpi;bdertl.bpi;vcldbx.bpi;dsnap.bpi;dsnapcon.bpi;vclib.bpi;ibxpress.bpi;adortl.bpi;dbxcds.bpi;dbexpress.bpi;DbxCommonDriver.bpi;websnap.bpi;vclie.bpi;webdsnap.bpi;inet.bpi;inetdbbde.bpi;inetdbxpress.bpi;soaprtl.bpi;Rave75VCL.bpi;teeUI.bpi;tee.bpi;teedb.bpi;IndyCore.bpi;IndySystem.bpi;IndyProtocols.bpi;IntrawebDB_90_100.bpi;Intraweb_90_100.bpi;dclZipForged11.bpi;vclZipForged11.bpi;GR32_BDS2006.bpi;GR32_DSGN_BDS2006.bpi;Jcl.bpi;JclVcl.bpi;JvCoreD11R.bpi;JvSystemD11R.bpi;JvStdCtrlsD11R.bpi;JvAppFrmD11R.bpi;JvBandsD11R.bpi;JvDBD11R.bpi;JvDlgsD11R.bpi;JvBDED11R.bpi;JvCmpD11R.bpi;JvCryptD11R.bpi;JvCtrlsD11R.bpi;JvCustomD11R.bpi;JvDockingD11R.bpi;JvDotNetCtrlsD11R.bpi;JvEDID11R.bpi;JvGlobusD11R.bpi;JvHMID11R.bpi;JvInterpreterD11R.bpi;JvJansD11R.bpi;JvManagedThreadsD11R.bpi;JvMMD11R.bpi;JvNetD11R.bpi;JvPageCompsD11R.bpi;JvPluginD11R.bpi;JvPrintPreviewD11R.bpi;JvRuntimeDesignD11R.bpi;JvTimeFrameworkD11R.bpi;JvValidatorsD11R.bpi;JvWizardD11R.bpi;JvXPCtrlsD11R.bpi;VclSmp.bpi;CExceptionExpert11.bpi false $(BDS)\include;$(BDS)\include\dinkumware;$(BDS)\include\vcl;..\src;..\include;.. rtl.lib;vcl.lib 32 $(BDS)\lib;$(BDS)\lib\obj;$(BDS)\lib\psdk false false true _DEBUG;$(Defines) true false true None DEBUG true Debug true true true $(BDS)\lib\debug;$(ILINK_LibraryPath) Full true NDEBUG;$(Defines) Release $(BDS)\lib\release;$(ILINK_LibraryPath) None CPlusPlusBuilder.Personality CppStaticLibrary FalseFalse1000FalseFalseFalseFalseFalse103312521.0.0.01.0.0.0FalseFalseFalseTrueFalse CodeGear C++Builder Office 2000 Servers Package CodeGear C++Builder Office XP Servers Package FalseTrueTrue3$(BDS)\include;$(BDS)\include\dinkumware;$(BDS)\include\vcl;..\src;..\include;..$(BDS)\include;$(BDS)\include\dinkumware;$(BDS)\include\vcl;..\src;..\include;..$(BDS)\include;$(BDS)\include\dinkumware;$(BDS)\include\vcl;..\src;..\src;..\include1$(BDS)\lib;$(BDS)\lib\obj;$(BDS)\lib\psdk1NO_STRICT13216 0 Cfg_1 Cfg_2 dlt-daemon-2.18.4/gtest-1.7.0/codegear/gtest_unittest.cbproj000066400000000000000000000207631353342203500234700ustar00rootroot00000000000000 {eea63393-5ac5-4b9c-8909-d75fef2daa41} Release true true true Base true true Base exe true NO_STRICT JPHNE true ..\test true CppConsoleApplication true true rtl.bpi;vcl.bpi;bcbie.bpi;vclx.bpi;vclactnband.bpi;xmlrtl.bpi;bcbsmp.bpi;dbrtl.bpi;vcldb.bpi;bdertl.bpi;vcldbx.bpi;dsnap.bpi;dsnapcon.bpi;vclib.bpi;ibxpress.bpi;adortl.bpi;dbxcds.bpi;dbexpress.bpi;DbxCommonDriver.bpi;websnap.bpi;vclie.bpi;webdsnap.bpi;inet.bpi;inetdbbde.bpi;inetdbxpress.bpi;soaprtl.bpi;Rave75VCL.bpi;teeUI.bpi;tee.bpi;teedb.bpi;IndyCore.bpi;IndySystem.bpi;IndyProtocols.bpi;IntrawebDB_90_100.bpi;Intraweb_90_100.bpi;Jcl.bpi;JclVcl.bpi;JvCoreD11R.bpi;JvSystemD11R.bpi;JvStdCtrlsD11R.bpi;JvAppFrmD11R.bpi;JvBandsD11R.bpi;JvDBD11R.bpi;JvDlgsD11R.bpi;JvBDED11R.bpi;JvCmpD11R.bpi;JvCryptD11R.bpi;JvCtrlsD11R.bpi;JvCustomD11R.bpi;JvDockingD11R.bpi;JvDotNetCtrlsD11R.bpi;JvEDID11R.bpi;JvGlobusD11R.bpi;JvHMID11R.bpi;JvInterpreterD11R.bpi;JvJansD11R.bpi;JvManagedThreadsD11R.bpi;JvMMD11R.bpi;JvNetD11R.bpi;JvPageCompsD11R.bpi;JvPluginD11R.bpi;JvPrintPreviewD11R.bpi;JvRuntimeDesignD11R.bpi;JvTimeFrameworkD11R.bpi;JvValidatorsD11R.bpi;JvWizardD11R.bpi;JvXPCtrlsD11R.bpi;VclSmp.bpi false $(BDS)\include;$(BDS)\include\dinkumware;$(BDS)\include\vcl;..\include;..\test;.. $(BDS)\lib;$(BDS)\lib\obj;$(BDS)\lib\psdk;..\test true false false true _DEBUG;$(Defines) true false true None DEBUG true Debug true true true $(BDS)\lib\debug;$(ILINK_LibraryPath) Full true NDEBUG;$(Defines) Release $(BDS)\lib\release;$(ILINK_LibraryPath) None CPlusPlusBuilder.Personality CppConsoleApplication FalseFalse1000FalseFalseFalseFalseFalse103312521.0.0.01.0.0.0FalseFalseFalseTrueFalse CodeGear C++Builder Office 2000 Servers Package CodeGear C++Builder Office XP Servers Package FalseTrueTrue3$(BDS)\include;$(BDS)\include\dinkumware;$(BDS)\include\vcl;..\include;..\test;..$(BDS)\include;$(BDS)\include\dinkumware;$(BDS)\include\vcl;..\include;..\test$(BDS)\include;$(BDS)\include\dinkumware;$(BDS)\include\vcl;..\include1$(BDS)\lib;$(BDS)\lib\obj;$(BDS)\lib\psdk;..\test$(BDS)\lib;$(BDS)\lib\obj;$(BDS)\lib\psdk;..\test$(BDS)\lib;$(BDS)\lib\obj;$(BDS)\lib\psdk;$(OUTPUTDIR);..\test2NO_STRICTSTRICT 0 1 Cfg_1 Cfg_2 dlt-daemon-2.18.4/gtest-1.7.0/config.log000066400000000000000000001050201353342203500173670ustar00rootroot00000000000000This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by Google C++ Testing Framework configure 1.7.0, which was generated by GNU Autoconf 2.68. Invocation command line was $ ./configure ## --------- ## ## Platform. ## ## --------- ## hostname = localhost.localdomain uname -m = i686 uname -r = 3.19.3-200.fc21.i686 uname -s = Linux uname -v = #1 SMP Thu Mar 26 22:12:19 UTC 2015 /usr/bin/uname -p = i686 /bin/uname -X = unknown /bin/arch = i686 /usr/bin/arch -k = unknown /usr/convex/getsysinfo = unknown /usr/bin/hostinfo = unknown /bin/machine = unknown /usr/bin/oslevel = unknown /bin/universe = unknown PATH: /usr/local/bin PATH: /usr/local/sbin PATH: /usr/bin PATH: /usr/sbin PATH: /bin PATH: /sbin PATH: /home/user/.local/bin PATH: /home/user/bin ## ----------- ## ## Core tests. ## ## ----------- ## configure:2293: checking for a BSD-compatible install configure:2361: result: /usr/bin/install -c configure:2372: checking whether build environment is sane configure:2422: result: yes configure:2563: checking for a thread-safe mkdir -p configure:2602: result: /usr/bin/mkdir -p configure:2615: checking for gawk configure:2631: found /usr/bin/gawk configure:2642: result: gawk configure:2653: checking whether make sets $(MAKE) configure:2675: result: yes configure:2805: checking for gcc configure:2821: found /usr/bin/gcc configure:2832: result: gcc configure:3061: checking for C compiler version configure:3070: gcc --version >&5 gcc (GCC) 4.9.2 20150212 (Red Hat 4.9.2-6) Copyright (C) 2014 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. configure:3081: $? = 0 configure:3070: gcc -v >&5 Using built-in specs. COLLECT_GCC=gcc COLLECT_LTO_WRAPPER=/usr/libexec/gcc/i686-redhat-linux/4.9.2/lto-wrapper Target: i686-redhat-linux Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-bootstrap --enable-shared --enable-threads=posix --enable-checking=release --enable-multilib --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-linker-build-id --with-linker-hash-style=gnu --enable-languages=c,c++,objc,obj-c++,fortran,ada,go,lto --enable-plugin --enable-initfini-array --disable-libgcj --with-isl=/builddir/build/BUILD/gcc-4.9.2-20150212/obj-i686-redhat-linux/isl-install --with-cloog=/builddir/build/BUILD/gcc-4.9.2-20150212/obj-i686-redhat-linux/cloog-install --enable-gnu-indirect-function --with-tune=generic --with-arch=i686 --build=i686-redhat-linux Thread model: posix gcc version 4.9.2 20150212 (Red Hat 4.9.2-6) (GCC) configure:3081: $? = 0 configure:3070: gcc -V >&5 gcc: error: unrecognized command line option '-V' gcc: fatal error: no input files compilation terminated. configure:3081: $? = 4 configure:3070: gcc -qversion >&5 gcc: error: unrecognized command line option '-qversion' gcc: fatal error: no input files compilation terminated. configure:3081: $? = 4 configure:3101: checking whether the C compiler works configure:3123: gcc conftest.c >&5 configure:3127: $? = 0 configure:3175: result: yes configure:3178: checking for C compiler default output file name configure:3180: result: a.out configure:3186: checking for suffix of executables configure:3193: gcc -o conftest conftest.c >&5 configure:3197: $? = 0 configure:3219: result: configure:3241: checking whether we are cross compiling configure:3249: gcc -o conftest conftest.c >&5 configure:3253: $? = 0 configure:3260: ./conftest configure:3264: $? = 0 configure:3279: result: no configure:3284: checking for suffix of object files configure:3306: gcc -c conftest.c >&5 configure:3310: $? = 0 configure:3331: result: o configure:3335: checking whether we are using the GNU C compiler configure:3354: gcc -c conftest.c >&5 configure:3354: $? = 0 configure:3363: result: yes configure:3372: checking whether gcc accepts -g configure:3392: gcc -c -g conftest.c >&5 configure:3392: $? = 0 configure:3433: result: yes configure:3450: checking for gcc option to accept ISO C89 configure:3514: gcc -c -g -O2 conftest.c >&5 configure:3514: $? = 0 configure:3527: result: none needed configure:3558: checking for style of include used by make configure:3586: result: GNU configure:3612: checking dependency style of gcc configure:3723: result: gcc3 configure:3796: checking for g++ configure:3812: found /usr/bin/g++ configure:3823: result: g++ configure:3850: checking for C++ compiler version configure:3859: g++ --version >&5 g++ (GCC) 4.9.2 20150212 (Red Hat 4.9.2-6) Copyright (C) 2014 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. configure:3870: $? = 0 configure:3859: g++ -v >&5 Using built-in specs. COLLECT_GCC=g++ COLLECT_LTO_WRAPPER=/usr/libexec/gcc/i686-redhat-linux/4.9.2/lto-wrapper Target: i686-redhat-linux Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-bootstrap --enable-shared --enable-threads=posix --enable-checking=release --enable-multilib --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-linker-build-id --with-linker-hash-style=gnu --enable-languages=c,c++,objc,obj-c++,fortran,ada,go,lto --enable-plugin --enable-initfini-array --disable-libgcj --with-isl=/builddir/build/BUILD/gcc-4.9.2-20150212/obj-i686-redhat-linux/isl-install --with-cloog=/builddir/build/BUILD/gcc-4.9.2-20150212/obj-i686-redhat-linux/cloog-install --enable-gnu-indirect-function --with-tune=generic --with-arch=i686 --build=i686-redhat-linux Thread model: posix gcc version 4.9.2 20150212 (Red Hat 4.9.2-6) (GCC) configure:3870: $? = 0 configure:3859: g++ -V >&5 g++: error: unrecognized command line option '-V' g++: fatal error: no input files compilation terminated. configure:3870: $? = 4 configure:3859: g++ -qversion >&5 g++: error: unrecognized command line option '-qversion' g++: fatal error: no input files compilation terminated. configure:3870: $? = 4 configure:3874: checking whether we are using the GNU C++ compiler configure:3893: g++ -c conftest.cpp >&5 configure:3893: $? = 0 configure:3902: result: yes configure:3911: checking whether g++ accepts -g configure:3931: g++ -c -g conftest.cpp >&5 configure:3931: $? = 0 configure:3972: result: yes configure:3997: checking dependency style of g++ configure:4108: result: gcc3 configure:4158: checking build system type configure:4172: result: i686-pc-linux-gnu configure:4192: checking host system type configure:4205: result: i686-pc-linux-gnu configure:4246: checking how to print strings configure:4273: result: printf configure:4294: checking for a sed that does not truncate output configure:4358: result: /usr/bin/sed configure:4376: checking for grep that handles long lines and -e configure:4434: result: /usr/bin/grep configure:4439: checking for egrep configure:4501: result: /usr/bin/grep -E configure:4506: checking for fgrep configure:4568: result: /usr/bin/grep -F configure:4603: checking for ld used by gcc configure:4670: result: /usr/bin/ld configure:4677: checking if the linker (/usr/bin/ld) is GNU ld configure:4692: result: yes configure:4704: checking for BSD- or MS-compatible name lister (nm) configure:4753: result: /usr/bin/nm -B configure:4883: checking the name lister (/usr/bin/nm -B) interface configure:4890: g++ -c -g -O2 conftest.cpp >&5 configure:4893: /usr/bin/nm -B "conftest.o" configure:4896: output 00000000 B some_variable configure:4903: result: BSD nm configure:4906: checking whether ln -s works configure:4910: result: yes configure:4918: checking the maximum length of command line arguments configure:5048: result: 1572864 configure:5065: checking whether the shell understands some XSI constructs configure:5075: result: yes configure:5079: checking whether the shell understands "+=" configure:5085: result: yes configure:5120: checking how to convert i686-pc-linux-gnu file names to i686-pc-linux-gnu format configure:5160: result: func_convert_file_noop configure:5167: checking how to convert i686-pc-linux-gnu file names to toolchain format configure:5187: result: func_convert_file_noop configure:5194: checking for /usr/bin/ld option to reload object files configure:5201: result: -r configure:5275: checking for objdump configure:5291: found /usr/bin/objdump configure:5302: result: objdump configure:5334: checking how to recognize dependent libraries configure:5536: result: pass_all configure:5621: checking for dlltool configure:5651: result: no configure:5681: checking how to associate runtime and link libraries configure:5708: result: printf %s\n configure:5769: checking for ar configure:5785: found /usr/bin/ar configure:5796: result: ar configure:5833: checking for archiver @FILE support configure:5850: g++ -c -g -O2 conftest.cpp >&5 configure:5850: $? = 0 configure:5853: ar cru libconftest.a @conftest.lst >&5 configure:5856: $? = 0 configure:5861: ar cru libconftest.a @conftest.lst >&5 ar: conftest.o: No such file or directory configure:5864: $? = 1 configure:5876: result: @ configure:5934: checking for strip configure:5950: found /usr/bin/strip configure:5961: result: strip configure:6033: checking for ranlib configure:6049: found /usr/bin/ranlib configure:6060: result: ranlib configure:6162: checking command to parse /usr/bin/nm -B output from gcc object configure:6282: g++ -c -g -O2 conftest.cpp >&5 configure:6285: $? = 0 configure:6289: /usr/bin/nm -B conftest.o \| sed -n -e 's/^.*[ ]\([ABCDGIRSTW][ABCDGIRSTW]*\)[ ][ ]*\([_A-Za-z][_A-Za-z0-9]*\)$/\1 \2 \2/p' | sed '/ __gnu_lto/d' \> conftest.nm configure:6292: $? = 0 configure:6358: g++ -o conftest -g -O2 conftest.cpp conftstm.o >&5 configure:6361: $? = 0 configure:6399: result: ok configure:6436: checking for sysroot configure:6466: result: no configure:6723: checking for mt configure:6753: result: no configure:6773: checking if : is a manifest tool configure:6779: : '-?' configure:6787: result: no configure:7429: checking how to run the C preprocessor configure:7460: gcc -E conftest.c configure:7460: $? = 0 configure:7474: gcc -E conftest.c conftest.c:11:28: fatal error: ac_nonexistent.h: No such file or directory #include ^ compilation terminated. configure:7474: $? = 1 configure: failed program was: | /* confdefs.h */ | #define PACKAGE_NAME "Google C++ Testing Framework" | #define PACKAGE_TARNAME "gtest" | #define PACKAGE_VERSION "1.7.0" | #define PACKAGE_STRING "Google C++ Testing Framework 1.7.0" | #define PACKAGE_BUGREPORT "googletestframework@googlegroups.com" | #define PACKAGE_URL "" | #define PACKAGE "gtest" | #define VERSION "1.7.0" | /* end confdefs.h. */ | #include configure:7499: result: gcc -E configure:7519: gcc -E conftest.c configure:7519: $? = 0 configure:7533: gcc -E conftest.c conftest.c:11:28: fatal error: ac_nonexistent.h: No such file or directory #include ^ compilation terminated. configure:7533: $? = 1 configure: failed program was: | /* confdefs.h */ | #define PACKAGE_NAME "Google C++ Testing Framework" | #define PACKAGE_TARNAME "gtest" | #define PACKAGE_VERSION "1.7.0" | #define PACKAGE_STRING "Google C++ Testing Framework 1.7.0" | #define PACKAGE_BUGREPORT "googletestframework@googlegroups.com" | #define PACKAGE_URL "" | #define PACKAGE "gtest" | #define VERSION "1.7.0" | /* end confdefs.h. */ | #include configure:7562: checking for ANSI C header files configure:7582: gcc -c -g -O2 conftest.c >&5 configure:7582: $? = 0 configure:7655: gcc -o conftest -g -O2 conftest.c >&5 configure:7655: $? = 0 configure:7655: ./conftest configure:7655: $? = 0 configure:7666: result: yes configure:7679: checking for sys/types.h configure:7679: gcc -c -g -O2 conftest.c >&5 configure:7679: $? = 0 configure:7679: result: yes configure:7679: checking for sys/stat.h configure:7679: gcc -c -g -O2 conftest.c >&5 configure:7679: $? = 0 configure:7679: result: yes configure:7679: checking for stdlib.h configure:7679: gcc -c -g -O2 conftest.c >&5 configure:7679: $? = 0 configure:7679: result: yes configure:7679: checking for string.h configure:7679: gcc -c -g -O2 conftest.c >&5 configure:7679: $? = 0 configure:7679: result: yes configure:7679: checking for memory.h configure:7679: gcc -c -g -O2 conftest.c >&5 configure:7679: $? = 0 configure:7679: result: yes configure:7679: checking for strings.h configure:7679: gcc -c -g -O2 conftest.c >&5 configure:7679: $? = 0 configure:7679: result: yes configure:7679: checking for inttypes.h configure:7679: gcc -c -g -O2 conftest.c >&5 configure:7679: $? = 0 configure:7679: result: yes configure:7679: checking for stdint.h configure:7679: gcc -c -g -O2 conftest.c >&5 configure:7679: $? = 0 configure:7679: result: yes configure:7679: checking for unistd.h configure:7679: gcc -c -g -O2 conftest.c >&5 configure:7679: $? = 0 configure:7679: result: yes configure:7693: checking for dlfcn.h configure:7693: gcc -c -g -O2 conftest.c >&5 configure:7693: $? = 0 configure:7693: result: yes configure:7909: checking for objdir configure:7924: result: .libs configure:8195: checking if gcc supports -fno-rtti -fno-exceptions configure:8213: gcc -c -g -O2 -fno-rtti -fno-exceptions conftest.c >&5 cc1: warning: command line option '-fno-rtti' is valid for C++/ObjC++ but not for C configure:8217: $? = 0 configure:8230: result: no configure:8557: checking for gcc option to produce PIC configure:8564: result: -fPIC -DPIC configure:8572: checking if gcc PIC flag -fPIC -DPIC works configure:8590: gcc -c -g -O2 -fPIC -DPIC -DPIC conftest.c >&5 configure:8594: $? = 0 configure:8607: result: yes configure:8636: checking if gcc static flag -static works configure:8664: result: no configure:8679: checking if gcc supports -c -o file.o configure:8700: gcc -c -g -O2 -o out/conftest2.o conftest.c >&5 configure:8704: $? = 0 configure:8726: result: yes configure:8734: checking if gcc supports -c -o file.o configure:8781: result: yes configure:8814: checking whether the gcc linker (/usr/bin/ld) supports shared libraries configure:9971: result: yes configure:10008: checking whether -lc should be explicitly linked in configure:10016: gcc -c -g -O2 conftest.c >&5 configure:10019: $? = 0 configure:10034: gcc -shared -fPIC -DPIC conftest.o -v -Wl,-soname -Wl,conftest -o conftest 2\>\&1 \| /usr/bin/grep -lc \>/dev/null 2\>\&1 configure:10037: $? = 0 configure:10051: result: no configure:10211: checking dynamic linker characteristics configure:10722: gcc -o conftest -g -O2 -Wl,-rpath -Wl,/foo conftest.c >&5 configure:10722: $? = 0 configure:10956: result: GNU/Linux ld.so configure:11063: checking how to hardcode library paths into programs configure:11088: result: immediate configure:11628: checking whether stripping libraries is possible configure:11633: result: yes configure:11668: checking if libtool supports shared libraries configure:11670: result: yes configure:11673: checking whether to build shared libraries configure:11694: result: yes configure:11697: checking whether to build static libraries configure:11701: result: yes configure:11724: checking how to run the C++ preprocessor configure:11751: g++ -E conftest.cpp configure:11751: $? = 0 configure:11765: g++ -E conftest.cpp conftest.cpp:23:28: fatal error: ac_nonexistent.h: No such file or directory #include ^ compilation terminated. configure:11765: $? = 1 configure: failed program was: | /* confdefs.h */ | #define PACKAGE_NAME "Google C++ Testing Framework" | #define PACKAGE_TARNAME "gtest" | #define PACKAGE_VERSION "1.7.0" | #define PACKAGE_STRING "Google C++ Testing Framework 1.7.0" | #define PACKAGE_BUGREPORT "googletestframework@googlegroups.com" | #define PACKAGE_URL "" | #define PACKAGE "gtest" | #define VERSION "1.7.0" | #define STDC_HEADERS 1 | #define HAVE_SYS_TYPES_H 1 | #define HAVE_SYS_STAT_H 1 | #define HAVE_STDLIB_H 1 | #define HAVE_STRING_H 1 | #define HAVE_MEMORY_H 1 | #define HAVE_STRINGS_H 1 | #define HAVE_INTTYPES_H 1 | #define HAVE_STDINT_H 1 | #define HAVE_UNISTD_H 1 | #define HAVE_DLFCN_H 1 | #define LT_OBJDIR ".libs/" | /* end confdefs.h. */ | #include configure:11790: result: g++ -E configure:11810: g++ -E conftest.cpp configure:11810: $? = 0 configure:11824: g++ -E conftest.cpp conftest.cpp:23:28: fatal error: ac_nonexistent.h: No such file or directory #include ^ compilation terminated. configure:11824: $? = 1 configure: failed program was: | /* confdefs.h */ | #define PACKAGE_NAME "Google C++ Testing Framework" | #define PACKAGE_TARNAME "gtest" | #define PACKAGE_VERSION "1.7.0" | #define PACKAGE_STRING "Google C++ Testing Framework 1.7.0" | #define PACKAGE_BUGREPORT "googletestframework@googlegroups.com" | #define PACKAGE_URL "" | #define PACKAGE "gtest" | #define VERSION "1.7.0" | #define STDC_HEADERS 1 | #define HAVE_SYS_TYPES_H 1 | #define HAVE_SYS_STAT_H 1 | #define HAVE_STDLIB_H 1 | #define HAVE_STRING_H 1 | #define HAVE_MEMORY_H 1 | #define HAVE_STRINGS_H 1 | #define HAVE_INTTYPES_H 1 | #define HAVE_STDINT_H 1 | #define HAVE_UNISTD_H 1 | #define HAVE_DLFCN_H 1 | #define LT_OBJDIR ".libs/" | /* end confdefs.h. */ | #include configure:11993: checking for ld used by g++ configure:12060: result: /usr/bin/ld configure:12067: checking if the linker (/usr/bin/ld) is GNU ld configure:12082: result: yes configure:12137: checking whether the g++ linker (/usr/bin/ld) supports shared libraries configure:13142: result: yes configure:13178: g++ -c -g -O2 conftest.cpp >&5 configure:13181: $? = 0 configure:13701: checking for g++ option to produce PIC configure:13708: result: -fPIC -DPIC configure:13716: checking if g++ PIC flag -fPIC -DPIC works configure:13734: g++ -c -g -O2 -fPIC -DPIC -DPIC conftest.cpp >&5 configure:13738: $? = 0 configure:13751: result: yes configure:13774: checking if g++ static flag -static works configure:13802: result: no configure:13814: checking if g++ supports -c -o file.o configure:13835: g++ -c -g -O2 -o out/conftest2.o conftest.cpp >&5 configure:13839: $? = 0 configure:13861: result: yes configure:13866: checking if g++ supports -c -o file.o configure:13913: result: yes configure:13943: checking whether the g++ linker (/usr/bin/ld) supports shared libraries configure:13982: result: yes configure:14123: checking dynamic linker characteristics configure:14802: result: GNU/Linux ld.so configure:14855: checking how to hardcode library paths into programs configure:14880: result: immediate configure:14950: checking for python configure:14968: found /usr/bin/python configure:14981: result: /usr/bin/python configure:14999: /usr/bin/python -c import sys # split strings by '.' and convert to numeric. Append some zeros # because we need at least 4 digits for the hex conversion. # map returns an iterator in Python 3.0 and a list in 2.x minver = list(map(int, '2.3'.split('.'))) + [0, 0, 0] minverhex = 0 # xrange is not present in Python 3.0 and range returns an iterator for i in list(range(0, 4)): minverhex = (minverhex << 8) + minver[i] sys.exit(sys.hexversion < minverhex) configure:15002: $? = 0 configure:15195: checking for the pthreads library -lpthreads configure:15228: gcc -o conftest -g -O2 conftest.c -lpthreads >&5 /usr/bin/ld: cannot find -lpthreads collect2: error: ld returned 1 exit status configure:15228: $? = 1 configure: failed program was: | /* confdefs.h */ | #define PACKAGE_NAME "Google C++ Testing Framework" | #define PACKAGE_TARNAME "gtest" | #define PACKAGE_VERSION "1.7.0" | #define PACKAGE_STRING "Google C++ Testing Framework 1.7.0" | #define PACKAGE_BUGREPORT "googletestframework@googlegroups.com" | #define PACKAGE_URL "" | #define PACKAGE "gtest" | #define VERSION "1.7.0" | #define STDC_HEADERS 1 | #define HAVE_SYS_TYPES_H 1 | #define HAVE_SYS_STAT_H 1 | #define HAVE_STDLIB_H 1 | #define HAVE_STRING_H 1 | #define HAVE_MEMORY_H 1 | #define HAVE_STRINGS_H 1 | #define HAVE_INTTYPES_H 1 | #define HAVE_STDINT_H 1 | #define HAVE_UNISTD_H 1 | #define HAVE_DLFCN_H 1 | #define LT_OBJDIR ".libs/" | /* end confdefs.h. */ | #include | int | main () | { | pthread_t th; pthread_join(th, 0); | pthread_attr_init(0); pthread_cleanup_push(0, 0); | pthread_create(0,0,0,0); pthread_cleanup_pop(0); | ; | return 0; | } configure:15237: result: no configure:15140: checking whether pthreads work without any flags configure:15228: gcc -o conftest -g -O2 conftest.c >&5 /tmp/ccDg1tDT.o: In function `main': /home/user/projects/ascgit/ascgit003.dlt-daemon/build/gtest-1.7.0/conftest.c:27: undefined reference to `pthread_join' /home/user/projects/ascgit/ascgit003.dlt-daemon/build/gtest-1.7.0/conftest.c:28: undefined reference to `__pthread_register_cancel' /home/user/projects/ascgit/ascgit003.dlt-daemon/build/gtest-1.7.0/conftest.c:29: undefined reference to `pthread_create' /home/user/projects/ascgit/ascgit003.dlt-daemon/build/gtest-1.7.0/conftest.c:29: undefined reference to `__pthread_unregister_cancel' collect2: error: ld returned 1 exit status configure:15228: $? = 1 configure: failed program was: | /* confdefs.h */ | #define PACKAGE_NAME "Google C++ Testing Framework" | #define PACKAGE_TARNAME "gtest" | #define PACKAGE_VERSION "1.7.0" | #define PACKAGE_STRING "Google C++ Testing Framework 1.7.0" | #define PACKAGE_BUGREPORT "googletestframework@googlegroups.com" | #define PACKAGE_URL "" | #define PACKAGE "gtest" | #define VERSION "1.7.0" | #define STDC_HEADERS 1 | #define HAVE_SYS_TYPES_H 1 | #define HAVE_SYS_STAT_H 1 | #define HAVE_STDLIB_H 1 | #define HAVE_STRING_H 1 | #define HAVE_MEMORY_H 1 | #define HAVE_STRINGS_H 1 | #define HAVE_INTTYPES_H 1 | #define HAVE_STDINT_H 1 | #define HAVE_UNISTD_H 1 | #define HAVE_DLFCN_H 1 | #define LT_OBJDIR ".libs/" | /* end confdefs.h. */ | #include | int | main () | { | pthread_t th; pthread_join(th, 0); | pthread_attr_init(0); pthread_cleanup_push(0, 0); | pthread_create(0,0,0,0); pthread_cleanup_pop(0); | ; | return 0; | } configure:15237: result: no configure:15145: checking whether pthreads work with -Kthread configure:15228: gcc -o conftest -g -O2 -Kthread conftest.c >&5 gcc: error: unrecognized command line option '-Kthread' configure:15228: $? = 1 configure: failed program was: | /* confdefs.h */ | #define PACKAGE_NAME "Google C++ Testing Framework" | #define PACKAGE_TARNAME "gtest" | #define PACKAGE_VERSION "1.7.0" | #define PACKAGE_STRING "Google C++ Testing Framework 1.7.0" | #define PACKAGE_BUGREPORT "googletestframework@googlegroups.com" | #define PACKAGE_URL "" | #define PACKAGE "gtest" | #define VERSION "1.7.0" | #define STDC_HEADERS 1 | #define HAVE_SYS_TYPES_H 1 | #define HAVE_SYS_STAT_H 1 | #define HAVE_STDLIB_H 1 | #define HAVE_STRING_H 1 | #define HAVE_MEMORY_H 1 | #define HAVE_STRINGS_H 1 | #define HAVE_INTTYPES_H 1 | #define HAVE_STDINT_H 1 | #define HAVE_UNISTD_H 1 | #define HAVE_DLFCN_H 1 | #define LT_OBJDIR ".libs/" | /* end confdefs.h. */ | #include | int | main () | { | pthread_t th; pthread_join(th, 0); | pthread_attr_init(0); pthread_cleanup_push(0, 0); | pthread_create(0,0,0,0); pthread_cleanup_pop(0); | ; | return 0; | } configure:15237: result: no configure:15145: checking whether pthreads work with -kthread configure:15228: gcc -o conftest -g -O2 -kthread conftest.c >&5 gcc: error: unrecognized command line option '-kthread' configure:15228: $? = 1 configure: failed program was: | /* confdefs.h */ | #define PACKAGE_NAME "Google C++ Testing Framework" | #define PACKAGE_TARNAME "gtest" | #define PACKAGE_VERSION "1.7.0" | #define PACKAGE_STRING "Google C++ Testing Framework 1.7.0" | #define PACKAGE_BUGREPORT "googletestframework@googlegroups.com" | #define PACKAGE_URL "" | #define PACKAGE "gtest" | #define VERSION "1.7.0" | #define STDC_HEADERS 1 | #define HAVE_SYS_TYPES_H 1 | #define HAVE_SYS_STAT_H 1 | #define HAVE_STDLIB_H 1 | #define HAVE_STRING_H 1 | #define HAVE_MEMORY_H 1 | #define HAVE_STRINGS_H 1 | #define HAVE_INTTYPES_H 1 | #define HAVE_STDINT_H 1 | #define HAVE_UNISTD_H 1 | #define HAVE_DLFCN_H 1 | #define LT_OBJDIR ".libs/" | /* end confdefs.h. */ | #include | int | main () | { | pthread_t th; pthread_join(th, 0); | pthread_attr_init(0); pthread_cleanup_push(0, 0); | pthread_create(0,0,0,0); pthread_cleanup_pop(0); | ; | return 0; | } configure:15237: result: no configure:15195: checking for the pthreads library -llthread configure:15228: gcc -o conftest -g -O2 conftest.c -llthread >&5 /usr/bin/ld: cannot find -llthread collect2: error: ld returned 1 exit status configure:15228: $? = 1 configure: failed program was: | /* confdefs.h */ | #define PACKAGE_NAME "Google C++ Testing Framework" | #define PACKAGE_TARNAME "gtest" | #define PACKAGE_VERSION "1.7.0" | #define PACKAGE_STRING "Google C++ Testing Framework 1.7.0" | #define PACKAGE_BUGREPORT "googletestframework@googlegroups.com" | #define PACKAGE_URL "" | #define PACKAGE "gtest" | #define VERSION "1.7.0" | #define STDC_HEADERS 1 | #define HAVE_SYS_TYPES_H 1 | #define HAVE_SYS_STAT_H 1 | #define HAVE_STDLIB_H 1 | #define HAVE_STRING_H 1 | #define HAVE_MEMORY_H 1 | #define HAVE_STRINGS_H 1 | #define HAVE_INTTYPES_H 1 | #define HAVE_STDINT_H 1 | #define HAVE_UNISTD_H 1 | #define HAVE_DLFCN_H 1 | #define LT_OBJDIR ".libs/" | /* end confdefs.h. */ | #include | int | main () | { | pthread_t th; pthread_join(th, 0); | pthread_attr_init(0); pthread_cleanup_push(0, 0); | pthread_create(0,0,0,0); pthread_cleanup_pop(0); | ; | return 0; | } configure:15237: result: no configure:15145: checking whether pthreads work with -pthread configure:15228: gcc -o conftest -g -O2 -pthread conftest.c >&5 configure:15228: $? = 0 configure:15237: result: yes configure:15256: checking for joinable pthread attribute configure:15271: gcc -o conftest -g -O2 -pthread conftest.c >&5 configure:15271: $? = 0 configure:15277: result: PTHREAD_CREATE_JOINABLE configure:15287: checking if more special flags are required for pthreads configure:15294: result: no configure:15383: checking whether to check for GCC pthread/shared inconsistencies configure:15396: gcc -o conftest -shared -fPIC -Wl,-z,defs -g -O2 -pthread conftest.c >&5 configure:15396: $? = 0 configure:15408: result: yes configure:15414: checking whether -pthread is sufficient with -shared configure:15429: gcc -o conftest -shared -fPIC -Wl,-z,defs -g -O2 -pthread conftest.c >&5 configure:15429: $? = 0 configure:15436: result: yes configure:15718: creating ./config.status ## ---------------------- ## ## Running config.status. ## ## ---------------------- ## This file was extended by Google C++ Testing Framework config.status 1.7.0, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = CONFIG_HEADERS = CONFIG_LINKS = CONFIG_COMMANDS = $ ./config.status on localhost.localdomain config.status:1162: creating Makefile config.status:1162: creating scripts/gtest-config config.status:1162: creating build-aux/config.h config.status:1391: executing depfiles commands config.status:1391: executing libtool commands ## ---------------- ## ## Cache variables. ## ## ---------------- ## ac_cv_build=i686-pc-linux-gnu ac_cv_c_compiler_gnu=yes ac_cv_cxx_compiler_gnu=yes ac_cv_env_CCC_set= ac_cv_env_CCC_value= ac_cv_env_CC_set= ac_cv_env_CC_value= ac_cv_env_CFLAGS_set= ac_cv_env_CFLAGS_value= ac_cv_env_CPPFLAGS_set= ac_cv_env_CPPFLAGS_value= ac_cv_env_CPP_set= ac_cv_env_CPP_value= ac_cv_env_CXXCPP_set= ac_cv_env_CXXCPP_value= ac_cv_env_CXXFLAGS_set= ac_cv_env_CXXFLAGS_value= ac_cv_env_CXX_set= ac_cv_env_CXX_value= ac_cv_env_LDFLAGS_set= ac_cv_env_LDFLAGS_value= ac_cv_env_LIBS_set= ac_cv_env_LIBS_value= ac_cv_env_build_alias_set= ac_cv_env_build_alias_value= ac_cv_env_host_alias_set= ac_cv_env_host_alias_value= ac_cv_env_target_alias_set= ac_cv_env_target_alias_value= ac_cv_header_dlfcn_h=yes ac_cv_header_inttypes_h=yes ac_cv_header_memory_h=yes ac_cv_header_stdc=yes ac_cv_header_stdint_h=yes ac_cv_header_stdlib_h=yes ac_cv_header_string_h=yes ac_cv_header_strings_h=yes ac_cv_header_sys_stat_h=yes ac_cv_header_sys_types_h=yes ac_cv_header_unistd_h=yes ac_cv_host=i686-pc-linux-gnu ac_cv_objext=o ac_cv_path_EGREP='/usr/bin/grep -E' ac_cv_path_FGREP='/usr/bin/grep -F' ac_cv_path_GREP=/usr/bin/grep ac_cv_path_PYTHON=/usr/bin/python ac_cv_path_SED=/usr/bin/sed ac_cv_path_install='/usr/bin/install -c' ac_cv_path_mkdir=/usr/bin/mkdir ac_cv_prog_AWK=gawk ac_cv_prog_CPP='gcc -E' ac_cv_prog_CXXCPP='g++ -E' ac_cv_prog_ac_ct_AR=ar ac_cv_prog_ac_ct_CC=gcc ac_cv_prog_ac_ct_CXX=g++ ac_cv_prog_ac_ct_OBJDUMP=objdump ac_cv_prog_ac_ct_RANLIB=ranlib ac_cv_prog_ac_ct_STRIP=strip ac_cv_prog_cc_c89= ac_cv_prog_cc_g=yes ac_cv_prog_cxx_g=yes ac_cv_prog_make_make_set=yes am_cv_CC_dependencies_compiler_type=gcc3 am_cv_CXX_dependencies_compiler_type=gcc3 lt_cv_ar_at_file=@ lt_cv_archive_cmds_need_lc=no lt_cv_deplibs_check_method=pass_all lt_cv_file_magic_cmd='$MAGIC_CMD' lt_cv_file_magic_test_file= lt_cv_ld_reload_flag=-r lt_cv_nm_interface='BSD nm' lt_cv_objdir=.libs lt_cv_path_LD=/usr/bin/ld lt_cv_path_LDCXX=/usr/bin/ld lt_cv_path_NM='/usr/bin/nm -B' lt_cv_path_mainfest_tool=no lt_cv_prog_compiler_c_o=yes lt_cv_prog_compiler_c_o_CXX=yes lt_cv_prog_compiler_pic='-fPIC -DPIC' lt_cv_prog_compiler_pic_CXX='-fPIC -DPIC' lt_cv_prog_compiler_pic_works=yes lt_cv_prog_compiler_pic_works_CXX=yes lt_cv_prog_compiler_rtti_exceptions=no lt_cv_prog_compiler_static_works=no lt_cv_prog_compiler_static_works_CXX=no lt_cv_prog_gnu_ld=yes lt_cv_prog_gnu_ldcxx=yes lt_cv_sharedlib_from_linklib_cmd='printf %s\n' lt_cv_shlibpath_overrides_runpath=no lt_cv_sys_global_symbol_pipe='sed -n -e '\''s/^.*[ ]\([ABCDGIRSTW][ABCDGIRSTW]*\)[ ][ ]*\([_A-Za-z][_A-Za-z0-9]*\)$/\1 \2 \2/p'\'' | sed '\''/ __gnu_lto/d'\''' lt_cv_sys_global_symbol_to_c_name_address='sed -n -e '\''s/^: \([^ ]*\)[ ]*$/ {\"\1\", (void *) 0},/p'\'' -e '\''s/^[ABCDGIRSTW]* \([^ ]*\) \([^ ]*\)$/ {"\2", (void *) \&\2},/p'\''' lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='sed -n -e '\''s/^: \([^ ]*\)[ ]*$/ {\"\1\", (void *) 0},/p'\'' -e '\''s/^[ABCDGIRSTW]* \([^ ]*\) \(lib[^ ]*\)$/ {"\2", (void *) \&\2},/p'\'' -e '\''s/^[ABCDGIRSTW]* \([^ ]*\) \([^ ]*\)$/ {"lib\2", (void *) \&\2},/p'\''' lt_cv_sys_global_symbol_to_cdecl='sed -n -e '\''s/^T .* \(.*\)$/extern int \1();/p'\'' -e '\''s/^[ABCDGIRSTW]* .* \(.*\)$/extern char \1;/p'\''' lt_cv_sys_max_cmd_len=1572864 lt_cv_to_host_file_cmd=func_convert_file_noop lt_cv_to_tool_file_cmd=func_convert_file_noop ## ----------------- ## ## Output variables. ## ## ----------------- ## ACLOCAL='${SHELL} /home/user/projects/ascgit/ascgit003.dlt-daemon/build/gtest-1.7.0/build-aux/missing --run aclocal-1.11' AMDEPBACKSLASH='\' AMDEP_FALSE='#' AMDEP_TRUE='' AMTAR='$${TAR-tar}' AR='ar' AUTOCONF='${SHELL} /home/user/projects/ascgit/ascgit003.dlt-daemon/build/gtest-1.7.0/build-aux/missing --run autoconf' AUTOHEADER='${SHELL} /home/user/projects/ascgit/ascgit003.dlt-daemon/build/gtest-1.7.0/build-aux/missing --run autoheader' AUTOMAKE='${SHELL} /home/user/projects/ascgit/ascgit003.dlt-daemon/build/gtest-1.7.0/build-aux/missing --run automake-1.11' AWK='gawk' CC='gcc' CCDEPMODE='depmode=gcc3' CFLAGS='-g -O2' CPP='gcc -E' CPPFLAGS='' CXX='g++' CXXCPP='g++ -E' CXXDEPMODE='depmode=gcc3' CXXFLAGS='-g -O2' CYGPATH_W='echo' DEFS='-DHAVE_CONFIG_H' DEPDIR='.deps' DLLTOOL='false' DSYMUTIL='' DUMPBIN='' ECHO_C='' ECHO_N='-n' ECHO_T='' EGREP='/usr/bin/grep -E' EXEEXT='' FGREP='/usr/bin/grep -F' GREP='/usr/bin/grep' HAVE_PTHREADS_FALSE='#' HAVE_PTHREADS_TRUE='' HAVE_PYTHON_FALSE='#' HAVE_PYTHON_TRUE='' INSTALL_DATA='${INSTALL} -m 644' INSTALL_PROGRAM='${INSTALL}' INSTALL_SCRIPT='${INSTALL}' INSTALL_STRIP_PROGRAM='$(install_sh) -c -s' LD='/usr/bin/ld' LDFLAGS='' LIBOBJS='' LIBS='' LIBTOOL='$(SHELL) $(top_builddir)/libtool' LIPO='' LN_S='ln -s' LTLIBOBJS='' MAKEINFO='${SHELL} /home/user/projects/ascgit/ascgit003.dlt-daemon/build/gtest-1.7.0/build-aux/missing --run makeinfo' MANIFEST_TOOL=':' MKDIR_P='/usr/bin/mkdir -p' NM='/usr/bin/nm -B' NMEDIT='' OBJDUMP='objdump' OBJEXT='o' OTOOL64='' OTOOL='' PACKAGE='gtest' PACKAGE_BUGREPORT='googletestframework@googlegroups.com' PACKAGE_NAME='Google C++ Testing Framework' PACKAGE_STRING='Google C++ Testing Framework 1.7.0' PACKAGE_TARNAME='gtest' PACKAGE_URL='' PACKAGE_VERSION='1.7.0' PATH_SEPARATOR=':' PTHREAD_CC='gcc' PTHREAD_CFLAGS='-pthread' PTHREAD_LIBS='' PYTHON='/usr/bin/python' RANLIB='ranlib' SED='/usr/bin/sed' SET_MAKE='' SHELL='/bin/sh' STRIP='strip' VERSION='1.7.0' ac_ct_AR='ar' ac_ct_CC='gcc' ac_ct_CXX='g++' ac_ct_DUMPBIN='' acx_pthread_config='' am__EXEEXT_FALSE='' am__EXEEXT_TRUE='#' am__fastdepCC_FALSE='#' am__fastdepCC_TRUE='' am__fastdepCXX_FALSE='#' am__fastdepCXX_TRUE='' am__include='include' am__isrc='' am__leading_dot='.' am__nodep='_no' am__quote='' am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -' bindir='${exec_prefix}/bin' build='i686-pc-linux-gnu' build_alias='' build_cpu='i686' build_os='linux-gnu' build_vendor='pc' datadir='${datarootdir}' datarootdir='${prefix}/share' docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' dvidir='${docdir}' exec_prefix='${prefix}' host='i686-pc-linux-gnu' host_alias='' host_cpu='i686' host_os='linux-gnu' host_vendor='pc' htmldir='${docdir}' includedir='${prefix}/include' infodir='${datarootdir}/info' install_sh='${SHELL} /home/user/projects/ascgit/ascgit003.dlt-daemon/build/gtest-1.7.0/build-aux/install-sh' libdir='${exec_prefix}/lib' libexecdir='${exec_prefix}/libexec' localedir='${datarootdir}/locale' localstatedir='${prefix}/var' mandir='${datarootdir}/man' mkdir_p='/usr/bin/mkdir -p' oldincludedir='/usr/include' pdfdir='${docdir}' prefix='/usr/local' program_transform_name='s,x,x,' psdir='${docdir}' sbindir='${exec_prefix}/sbin' sharedstatedir='${prefix}/com' sysconfdir='${prefix}/etc' target_alias='' ## ----------- ## ## confdefs.h. ## ## ----------- ## /* confdefs.h */ #define PACKAGE_NAME "Google C++ Testing Framework" #define PACKAGE_TARNAME "gtest" #define PACKAGE_VERSION "1.7.0" #define PACKAGE_STRING "Google C++ Testing Framework 1.7.0" #define PACKAGE_BUGREPORT "googletestframework@googlegroups.com" #define PACKAGE_URL "" #define PACKAGE "gtest" #define VERSION "1.7.0" #define STDC_HEADERS 1 #define HAVE_SYS_TYPES_H 1 #define HAVE_SYS_STAT_H 1 #define HAVE_STDLIB_H 1 #define HAVE_STRING_H 1 #define HAVE_MEMORY_H 1 #define HAVE_STRINGS_H 1 #define HAVE_INTTYPES_H 1 #define HAVE_STDINT_H 1 #define HAVE_UNISTD_H 1 #define HAVE_DLFCN_H 1 #define LT_OBJDIR ".libs/" #define HAVE_PTHREAD 1 configure: exit 0 dlt-daemon-2.18.4/gtest-1.7.0/config.status000077500000000000000000002140351353342203500201430ustar00rootroot00000000000000#! /bin/sh # Generated by configure. # Run this file to recreate the current configuration. # Compiler output produced by configure, useful for debugging # configure, is in config.log if it exists. debug=false ac_cs_recheck=false ac_cs_silent=false SHELL=${CONFIG_SHELL-/bin/sh} export SHELL ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -p'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -p' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' fi else as_ln_s='cp -p' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi if test -x / >/dev/null 2>&1; then as_test_x='test -x' else if ls -dL / >/dev/null 2>&1; then as_ls_L_option=L else as_ls_L_option= fi as_test_x=' eval sh -c '\'' if test -d "$1"; then test -d "$1/."; else case $1 in #( -*)set "./$1";; esac; case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( ???[sx]*):;;*)false;;esac;fi '\'' sh ' fi as_executable_p=$as_test_x # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" exec 6>&1 ## ----------------------------------- ## ## Main body of $CONFIG_STATUS script. ## ## ----------------------------------- ## # Save the log message, to keep $0 and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" This file was extended by Google C++ Testing Framework $as_me 1.7.0, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS CONFIG_LINKS = $CONFIG_LINKS CONFIG_COMMANDS = $CONFIG_COMMANDS $ $0 $@ on `(hostname || uname -n) 2>/dev/null | sed 1q` " # Files that config.status was made for. config_files=" Makefile scripts/gtest-config" config_headers=" build-aux/config.h" config_commands=" depfiles libtool" ac_cs_usage="\ \`$as_me' instantiates files and other configuration actions from templates according to the current configuration. Unless the files and actions are specified as TAGs, all are instantiated by default. Usage: $0 [OPTION]... [TAG]... -h, --help print this help, then exit -V, --version print version number and configuration settings, then exit --config print configuration, then exit -q, --quiet, --silent do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions --file=FILE[:TEMPLATE] instantiate the configuration file FILE --header=FILE[:TEMPLATE] instantiate the configuration header FILE Configuration files: $config_files Configuration headers: $config_headers Configuration commands: $config_commands Report bugs to ." ac_cs_config="" ac_cs_version="\ Google C++ Testing Framework config.status 1.7.0 configured by ./configure, generated by GNU Autoconf 2.68, with options \"$ac_cs_config\" Copyright (C) 2010 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." ac_pwd='/home/user/projects/ascgit/ascgit003.dlt-daemon/build/gtest-1.7.0' srcdir='.' INSTALL='/usr/bin/install -c' MKDIR_P='/usr/bin/mkdir -p' AWK='gawk' test -n "$AWK" || AWK=awk # The default lists apply if the user does not specify any file. ac_need_defaults=: while test $# != 0 do case $1 in --*=?*) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` ac_shift=: ;; --*=) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg= ac_shift=: ;; *) ac_option=$1 ac_optarg=$2 ac_shift=shift ;; esac case $ac_option in # Handling of the options. -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) $as_echo "$ac_cs_version"; exit ;; --config | --confi | --conf | --con | --co | --c ) $as_echo "$ac_cs_config"; exit ;; --debug | --debu | --deb | --de | --d | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; '') as_fn_error $? "missing file argument" ;; esac as_fn_append CONFIG_FILES " '$ac_optarg'" ac_need_defaults=false;; --header | --heade | --head | --hea ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; esac as_fn_append CONFIG_HEADERS " '$ac_optarg'" ac_need_defaults=false;; --he | --h) # Conflict between --help and --header as_fn_error $? "ambiguous option: \`$1' Try \`$0 --help' for more information.";; --help | --hel | -h ) $as_echo "$ac_cs_usage"; exit ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; # This is an error. -*) as_fn_error $? "unrecognized option: \`$1' Try \`$0 --help' for more information." ;; *) as_fn_append ac_config_targets " $1" ac_need_defaults=false ;; esac shift done ac_configure_extra_args= if $ac_cs_silent; then exec 6>/dev/null ac_configure_extra_args="$ac_configure_extra_args --silent" fi if $ac_cs_recheck; then set X '/bin/sh' './configure' $ac_configure_extra_args --no-create --no-recursion shift $as_echo "running CONFIG_SHELL=/bin/sh $*" >&6 CONFIG_SHELL='/bin/sh' export CONFIG_SHELL exec "$@" fi exec 5>>config.log { echo sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX $as_echo "$ac_log" } >&5 # # INIT-COMMANDS # AMDEP_TRUE="" ac_aux_dir="build-aux" # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH sed_quote_subst='s/\(["`$\\]\)/\\\1/g' double_quote_subst='s/\(["`\\]\)/\\\1/g' delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' macro_version='2.4.2' macro_revision='1.3337' enable_shared='yes' enable_static='yes' pic_mode='default' enable_fast_install='yes' SHELL='/bin/sh' ECHO='printf %s\n' PATH_SEPARATOR=':' host_alias='' host='i686-pc-linux-gnu' host_os='linux-gnu' build_alias='' build='i686-pc-linux-gnu' build_os='linux-gnu' SED='/usr/bin/sed' Xsed='/usr/bin/sed -e 1s/^X//' GREP='/usr/bin/grep' EGREP='/usr/bin/grep -E' FGREP='/usr/bin/grep -F' LD='/usr/bin/ld' NM='/usr/bin/nm -B' LN_S='ln -s' max_cmd_len='1572864' ac_objext='o' exeext='' lt_unset='unset' lt_SP2NL='tr \040 \012' lt_NL2SP='tr \015\012 \040\040' lt_cv_to_host_file_cmd='func_convert_file_noop' lt_cv_to_tool_file_cmd='func_convert_file_noop' reload_flag=' -r' reload_cmds='$LD$reload_flag -o $output$reload_objs' OBJDUMP='objdump' deplibs_check_method='pass_all' file_magic_cmd='$MAGIC_CMD' file_magic_glob='' want_nocaseglob='no' DLLTOOL='false' sharedlib_from_linklib_cmd='printf %s\n' AR='ar' AR_FLAGS='cru' archiver_list_spec='@' STRIP='strip' RANLIB='ranlib' old_postinstall_cmds='chmod 644 $oldlib~$RANLIB $tool_oldlib' old_postuninstall_cmds='' old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs~$RANLIB $tool_oldlib' lock_old_archive_extraction='no' CC='gcc' CFLAGS='-g -O2' compiler='g++' GCC='yes' lt_cv_sys_global_symbol_pipe='sed -n -e '\''s/^.*[ ]\([ABCDGIRSTW][ABCDGIRSTW]*\)[ ][ ]*\([_A-Za-z][_A-Za-z0-9]*\)$/\1 \2 \2/p'\'' | sed '\''/ __gnu_lto/d'\''' lt_cv_sys_global_symbol_to_cdecl='sed -n -e '\''s/^T .* \(.*\)$/extern int \1();/p'\'' -e '\''s/^[ABCDGIRSTW]* .* \(.*\)$/extern char \1;/p'\''' lt_cv_sys_global_symbol_to_c_name_address='sed -n -e '\''s/^: \([^ ]*\)[ ]*$/ {\"\1\", (void *) 0},/p'\'' -e '\''s/^[ABCDGIRSTW]* \([^ ]*\) \([^ ]*\)$/ {"\2", (void *) \&\2},/p'\''' lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='sed -n -e '\''s/^: \([^ ]*\)[ ]*$/ {\"\1\", (void *) 0},/p'\'' -e '\''s/^[ABCDGIRSTW]* \([^ ]*\) \(lib[^ ]*\)$/ {"\2", (void *) \&\2},/p'\'' -e '\''s/^[ABCDGIRSTW]* \([^ ]*\) \([^ ]*\)$/ {"lib\2", (void *) \&\2},/p'\''' nm_file_list_spec='@' lt_sysroot='' objdir='.libs' MAGIC_CMD='file' lt_prog_compiler_no_builtin_flag=' -fno-builtin' lt_prog_compiler_pic=' -fPIC -DPIC' lt_prog_compiler_wl='-Wl,' lt_prog_compiler_static='' lt_cv_prog_compiler_c_o='yes' need_locks='no' MANIFEST_TOOL=':' DSYMUTIL='' NMEDIT='' LIPO='' OTOOL='' OTOOL64='' libext='a' shrext_cmds='.so' extract_expsyms_cmds='' archive_cmds_need_lc='no' enable_shared_with_static_runtimes='no' export_dynamic_flag_spec='${wl}--export-dynamic' whole_archive_flag_spec='${wl}--whole-archive$convenience ${wl}--no-whole-archive' compiler_needs_object='no' old_archive_from_new_cmds='' old_archive_from_expsyms_cmds='' archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' module_cmds='' module_expsym_cmds='' with_gnu_ld='yes' allow_undefined_flag='' no_undefined_flag='' hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator='' hardcode_direct='no' hardcode_direct_absolute='no' hardcode_minus_L='no' hardcode_shlibpath_var='unsupported' hardcode_automatic='no' inherit_rpath='no' link_all_deplibs='no' always_export_symbols='no' export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' include_expsyms='' prelink_cmds='' postlink_cmds='' file_list_spec='' variables_saved_for_relink='PATH LD_LIBRARY_PATH LD_RUN_PATH GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH' need_lib_prefix='no' need_version='no' version_type='linux' runpath_var='LD_RUN_PATH' shlibpath_var='LD_LIBRARY_PATH' shlibpath_overrides_runpath='no' libname_spec='lib$name' library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' install_override_mode='' postinstall_cmds='' postuninstall_cmds='' finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' finish_eval='' hardcode_into_libs='yes' sys_lib_search_path_spec='/usr/lib/gcc/i686-redhat-linux/4.9.2 /usr/lib /lib ' sys_lib_dlsearch_path_spec='/lib /usr/lib /usr/lib/dyninst /usr/lib/iscsi /usr/lib/llvm /usr/lib/vmware-tools/lib32/libvmGuestLib.so /usr/lib/vmware-tools/lib64/libvmGuestLib.so /usr/lib/vmware-tools/lib32/libvmGuestLibJava.so /usr/lib/vmware-tools/lib64/libvmGuestLibJava.so /usr/lib/vmware-tools/lib32/libDeployPkg.so /usr/lib/vmware-tools/lib64/libDeployPkg.so ' hardcode_action='immediate' enable_dlopen='unknown' enable_dlopen_self='unknown' enable_dlopen_self_static='unknown' old_striplib='strip --strip-debug' striplib='strip --strip-unneeded' compiler_lib_search_dirs='' predep_objects='' postdep_objects='' predeps='' postdeps='' compiler_lib_search_path='' LD_CXX='/usr/bin/ld' reload_flag_CXX=' -r' reload_cmds_CXX='$LD$reload_flag -o $output$reload_objs' old_archive_cmds_CXX='$AR $AR_FLAGS $oldlib$oldobjs~$RANLIB $tool_oldlib' compiler_CXX='g++' GCC_CXX='yes' lt_prog_compiler_no_builtin_flag_CXX=' -fno-builtin' lt_prog_compiler_pic_CXX=' -fPIC -DPIC' lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_static_CXX='' lt_cv_prog_compiler_c_o_CXX='yes' archive_cmds_need_lc_CXX='no' enable_shared_with_static_runtimes_CXX='no' export_dynamic_flag_spec_CXX='${wl}--export-dynamic' whole_archive_flag_spec_CXX='${wl}--whole-archive$convenience ${wl}--no-whole-archive' compiler_needs_object_CXX='no' old_archive_from_new_cmds_CXX='' old_archive_from_expsyms_cmds_CXX='' archive_cmds_CXX='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds_CXX='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' module_cmds_CXX='' module_expsym_cmds_CXX='' with_gnu_ld_CXX='yes' allow_undefined_flag_CXX='' no_undefined_flag_CXX='' hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator_CXX='' hardcode_direct_CXX='no' hardcode_direct_absolute_CXX='no' hardcode_minus_L_CXX='no' hardcode_shlibpath_var_CXX='unsupported' hardcode_automatic_CXX='no' inherit_rpath_CXX='no' link_all_deplibs_CXX='no' always_export_symbols_CXX='no' export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' exclude_expsyms_CXX='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' include_expsyms_CXX='' prelink_cmds_CXX='' postlink_cmds_CXX='' file_list_spec_CXX='' hardcode_action_CXX='immediate' compiler_lib_search_dirs_CXX='/usr/lib/gcc/i686-redhat-linux/4.9.2 /usr/lib/gcc/i686-redhat-linux/4.9.2/../../..' predep_objects_CXX='/usr/lib/gcc/i686-redhat-linux/4.9.2/../../../crti.o /usr/lib/gcc/i686-redhat-linux/4.9.2/crtbeginS.o' postdep_objects_CXX='/usr/lib/gcc/i686-redhat-linux/4.9.2/crtendS.o /usr/lib/gcc/i686-redhat-linux/4.9.2/../../../crtn.o' predeps_CXX='' postdeps_CXX='-lstdc++ -lm -lgcc_s -lc -lgcc_s' compiler_lib_search_path_CXX='-L/usr/lib/gcc/i686-redhat-linux/4.9.2 -L/usr/lib/gcc/i686-redhat-linux/4.9.2/../../..' LTCC='gcc' LTCFLAGS='-g -O2' compiler='gcc' # A function that is used when there is no print builtin or printf. func_fallback_echo () { eval 'cat <<_LTECHO_EOF $1 _LTECHO_EOF' } # Quote evaled strings. for var in SHELL ECHO PATH_SEPARATOR SED GREP EGREP FGREP LD NM LN_S lt_SP2NL lt_NL2SP reload_flag OBJDUMP deplibs_check_method file_magic_cmd file_magic_glob want_nocaseglob DLLTOOL sharedlib_from_linklib_cmd AR AR_FLAGS archiver_list_spec STRIP RANLIB CC CFLAGS compiler lt_cv_sys_global_symbol_pipe lt_cv_sys_global_symbol_to_cdecl lt_cv_sys_global_symbol_to_c_name_address lt_cv_sys_global_symbol_to_c_name_address_lib_prefix nm_file_list_spec lt_prog_compiler_no_builtin_flag lt_prog_compiler_pic lt_prog_compiler_wl lt_prog_compiler_static lt_cv_prog_compiler_c_o need_locks MANIFEST_TOOL DSYMUTIL NMEDIT LIPO OTOOL OTOOL64 shrext_cmds export_dynamic_flag_spec whole_archive_flag_spec compiler_needs_object with_gnu_ld allow_undefined_flag no_undefined_flag hardcode_libdir_flag_spec hardcode_libdir_separator exclude_expsyms include_expsyms file_list_spec variables_saved_for_relink libname_spec library_names_spec soname_spec install_override_mode finish_eval old_striplib striplib compiler_lib_search_dirs predep_objects postdep_objects predeps postdeps compiler_lib_search_path LD_CXX reload_flag_CXX compiler_CXX lt_prog_compiler_no_builtin_flag_CXX lt_prog_compiler_pic_CXX lt_prog_compiler_wl_CXX lt_prog_compiler_static_CXX lt_cv_prog_compiler_c_o_CXX export_dynamic_flag_spec_CXX whole_archive_flag_spec_CXX compiler_needs_object_CXX with_gnu_ld_CXX allow_undefined_flag_CXX no_undefined_flag_CXX hardcode_libdir_flag_spec_CXX hardcode_libdir_separator_CXX exclude_expsyms_CXX include_expsyms_CXX file_list_spec_CXX compiler_lib_search_dirs_CXX predep_objects_CXX postdep_objects_CXX predeps_CXX postdeps_CXX compiler_lib_search_path_CXX; do case `eval \\$ECHO \\""\\$$var"\\"` in *[\\\`\"\$]*) eval "lt_$var=\\\"\`\$ECHO \"\$$var\" | \$SED \"\$sed_quote_subst\"\`\\\"" ;; *) eval "lt_$var=\\\"\$$var\\\"" ;; esac done # Double-quote double-evaled strings. for var in reload_cmds old_postinstall_cmds old_postuninstall_cmds old_archive_cmds extract_expsyms_cmds old_archive_from_new_cmds old_archive_from_expsyms_cmds archive_cmds archive_expsym_cmds module_cmds module_expsym_cmds export_symbols_cmds prelink_cmds postlink_cmds postinstall_cmds postuninstall_cmds finish_cmds sys_lib_search_path_spec sys_lib_dlsearch_path_spec reload_cmds_CXX old_archive_cmds_CXX old_archive_from_new_cmds_CXX old_archive_from_expsyms_cmds_CXX archive_cmds_CXX archive_expsym_cmds_CXX module_cmds_CXX module_expsym_cmds_CXX export_symbols_cmds_CXX prelink_cmds_CXX postlink_cmds_CXX; do case `eval \\$ECHO \\""\\$$var"\\"` in *[\\\`\"\$]*) eval "lt_$var=\\\"\`\$ECHO \"\$$var\" | \$SED -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\"" ;; *) eval "lt_$var=\\\"\$$var\\\"" ;; esac done ac_aux_dir='build-aux' xsi_shell='yes' lt_shell_append='yes' # See if we are running on zsh, and set the options which allow our # commands through without removal of \ escapes INIT. if test -n "${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi PACKAGE='gtest' VERSION='1.7.0' TIMESTAMP='' RM='rm -f' ofile='libtool' # Handling of arguments. for ac_config_target in $ac_config_targets do case $ac_config_target in "build-aux/config.h") CONFIG_HEADERS="$CONFIG_HEADERS build-aux/config.h" ;; "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; "scripts/gtest-config") CONFIG_FILES="$CONFIG_FILES scripts/gtest-config" ;; "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;; *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; esac done # If the user did not use the arguments to specify the items to instantiate, # then the envvar interface is used. Set only those that are not. # We use the long form for the default assignment because of an extremely # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands fi # Have a temporary directory for convenience. Make it in the build tree # simply because there is no reason against having it here, and in addition, # creating and moving files from /tmp can sometimes cause problems. # Hook for its removal unless debugging. # Note that there is a small window in which the directory will not be cleaned: # after its creation but before its name has been assigned to `$tmp'. $debug || { tmp= ac_tmp= trap 'exit_status=$? : "${ac_tmp:=$tmp}" { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status ' 0 trap 'as_fn_exit 1' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. { tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && test -d "$tmp" } || { tmp=./conf$$-$RANDOM (umask 077 && mkdir "$tmp") } || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 ac_tmp=$tmp # Set up the scripts for CONFIG_FILES section. # No need to generate them if there are no CONFIG_FILES. # This happens for instance with `./config.status config.h'. if test -n "$CONFIG_FILES"; then ac_cr=`echo X | tr X '\015'` # On cygwin, bash can eat \r inside `` if the user requested igncr. # But we know of no other shell where ac_cr would be empty at this # point, so we can use a bashism as a fallback. if test "x$ac_cr" = x; then eval ac_cr=\$\'\\r\' fi ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then ac_cs_awk_cr='\\r' else ac_cs_awk_cr=$ac_cr fi echo 'BEGIN {' >"$ac_tmp/subs1.awk" && cat >>"$ac_tmp/subs1.awk" <<\_ACAWK && S["am__EXEEXT_FALSE"]="" S["am__EXEEXT_TRUE"]="#" S["LTLIBOBJS"]="" S["LIBOBJS"]="" S["HAVE_PTHREADS_FALSE"]="#" S["HAVE_PTHREADS_TRUE"]="" S["PTHREAD_CFLAGS"]="-pthread" S["PTHREAD_LIBS"]="" S["PTHREAD_CC"]="gcc" S["acx_pthread_config"]="" S["HAVE_PYTHON_FALSE"]="#" S["HAVE_PYTHON_TRUE"]="" S["PYTHON"]="/usr/bin/python" S["CXXCPP"]="g++ -E" S["CPP"]="gcc -E" S["OTOOL64"]="" S["OTOOL"]="" S["LIPO"]="" S["NMEDIT"]="" S["DSYMUTIL"]="" S["MANIFEST_TOOL"]=":" S["RANLIB"]="ranlib" S["ac_ct_AR"]="ar" S["AR"]="ar" S["DLLTOOL"]="false" S["OBJDUMP"]="objdump" S["LN_S"]="ln -s" S["NM"]="/usr/bin/nm -B" S["ac_ct_DUMPBIN"]="" S["DUMPBIN"]="" S["LD"]="/usr/bin/ld" S["FGREP"]="/usr/bin/grep -F" S["EGREP"]="/usr/bin/grep -E" S["GREP"]="/usr/bin/grep" S["SED"]="/usr/bin/sed" S["host_os"]="linux-gnu" S["host_vendor"]="pc" S["host_cpu"]="i686" S["host"]="i686-pc-linux-gnu" S["build_os"]="linux-gnu" S["build_vendor"]="pc" S["build_cpu"]="i686" S["build"]="i686-pc-linux-gnu" S["LIBTOOL"]="$(SHELL) $(top_builddir)/libtool" S["am__fastdepCXX_FALSE"]="#" S["am__fastdepCXX_TRUE"]="" S["CXXDEPMODE"]="depmode=gcc3" S["ac_ct_CXX"]="g++" S["CXXFLAGS"]="-g -O2" S["CXX"]="g++" S["am__fastdepCC_FALSE"]="#" S["am__fastdepCC_TRUE"]="" S["CCDEPMODE"]="depmode=gcc3" S["am__nodep"]="_no" S["AMDEPBACKSLASH"]="\\" S["AMDEP_FALSE"]="#" S["AMDEP_TRUE"]="" S["am__quote"]="" S["am__include"]="include" S["DEPDIR"]=".deps" S["OBJEXT"]="o" S["EXEEXT"]="" S["ac_ct_CC"]="gcc" S["CPPFLAGS"]="" S["LDFLAGS"]="" S["CFLAGS"]="-g -O2" S["CC"]="gcc" S["am__untar"]="$${TAR-tar} xf -" S["am__tar"]="$${TAR-tar} chof - \"$$tardir\"" S["AMTAR"]="$${TAR-tar}" S["am__leading_dot"]="." S["SET_MAKE"]="" S["AWK"]="gawk" S["mkdir_p"]="/usr/bin/mkdir -p" S["MKDIR_P"]="/usr/bin/mkdir -p" S["INSTALL_STRIP_PROGRAM"]="$(install_sh) -c -s" S["STRIP"]="strip" S["install_sh"]="${SHELL} /home/user/projects/ascgit/ascgit003.dlt-daemon/build/gtest-1.7.0/build-aux/install-sh" S["MAKEINFO"]="${SHELL} /home/user/projects/ascgit/ascgit003.dlt-daemon/build/gtest-1.7.0/build-aux/missing --run makeinfo" S["AUTOHEADER"]="${SHELL} /home/user/projects/ascgit/ascgit003.dlt-daemon/build/gtest-1.7.0/build-aux/missing --run autoheader" S["AUTOMAKE"]="${SHELL} /home/user/projects/ascgit/ascgit003.dlt-daemon/build/gtest-1.7.0/build-aux/missing --run automake-1.11" S["AUTOCONF"]="${SHELL} /home/user/projects/ascgit/ascgit003.dlt-daemon/build/gtest-1.7.0/build-aux/missing --run autoconf" S["ACLOCAL"]="${SHELL} /home/user/projects/ascgit/ascgit003.dlt-daemon/build/gtest-1.7.0/build-aux/missing --run aclocal-1.11" S["VERSION"]="1.7.0" S["PACKAGE"]="gtest" S["CYGPATH_W"]="echo" S["am__isrc"]="" S["INSTALL_DATA"]="${INSTALL} -m 644" S["INSTALL_SCRIPT"]="${INSTALL}" S["INSTALL_PROGRAM"]="${INSTALL}" S["target_alias"]="" S["host_alias"]="" S["build_alias"]="" S["LIBS"]="" S["ECHO_T"]="" S["ECHO_N"]="-n" S["ECHO_C"]="" S["DEFS"]="-DHAVE_CONFIG_H" S["mandir"]="${datarootdir}/man" S["localedir"]="${datarootdir}/locale" S["libdir"]="${exec_prefix}/lib" S["psdir"]="${docdir}" S["pdfdir"]="${docdir}" S["dvidir"]="${docdir}" S["htmldir"]="${docdir}" S["infodir"]="${datarootdir}/info" S["docdir"]="${datarootdir}/doc/${PACKAGE_TARNAME}" S["oldincludedir"]="/usr/include" S["includedir"]="${prefix}/include" S["localstatedir"]="${prefix}/var" S["sharedstatedir"]="${prefix}/com" S["sysconfdir"]="${prefix}/etc" S["datadir"]="${datarootdir}" S["datarootdir"]="${prefix}/share" S["libexecdir"]="${exec_prefix}/libexec" S["sbindir"]="${exec_prefix}/sbin" S["bindir"]="${exec_prefix}/bin" S["program_transform_name"]="s,x,x," S["prefix"]="/usr/local" S["exec_prefix"]="${prefix}" S["PACKAGE_URL"]="" S["PACKAGE_BUGREPORT"]="googletestframework@googlegroups.com" S["PACKAGE_STRING"]="Google C++ Testing Framework 1.7.0" S["PACKAGE_VERSION"]="1.7.0" S["PACKAGE_TARNAME"]="gtest" S["PACKAGE_NAME"]="Google C++ Testing Framework" S["PATH_SEPARATOR"]=":" S["SHELL"]="/bin/sh" _ACAWK cat >>"$ac_tmp/subs1.awk" <<_ACAWK && for (key in S) S_is_set[key] = 1 FS = "" } { line = $ 0 nfields = split(line, field, "@") substed = 0 len = length(field[1]) for (i = 2; i < nfields; i++) { key = field[i] keylen = length(key) if (S_is_set[key]) { value = S[key] line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) len += length(value) + length(field[++i]) substed = 1 } else len += 1 + keylen } print line } _ACAWK if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" else cat fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 fi # test -n "$CONFIG_FILES" # Set up the scripts for CONFIG_HEADERS section. # No need to generate them if there are no CONFIG_HEADERS. # This happens for instance with `./config.status Makefile'. if test -n "$CONFIG_HEADERS"; then cat >"$ac_tmp/defines.awk" <<\_ACAWK || BEGIN { D["PACKAGE_NAME"]=" \"Google C++ Testing Framework\"" D["PACKAGE_TARNAME"]=" \"gtest\"" D["PACKAGE_VERSION"]=" \"1.7.0\"" D["PACKAGE_STRING"]=" \"Google C++ Testing Framework 1.7.0\"" D["PACKAGE_BUGREPORT"]=" \"googletestframework@googlegroups.com\"" D["PACKAGE_URL"]=" \"\"" D["PACKAGE"]=" \"gtest\"" D["VERSION"]=" \"1.7.0\"" D["STDC_HEADERS"]=" 1" D["HAVE_SYS_TYPES_H"]=" 1" D["HAVE_SYS_STAT_H"]=" 1" D["HAVE_STDLIB_H"]=" 1" D["HAVE_STRING_H"]=" 1" D["HAVE_MEMORY_H"]=" 1" D["HAVE_STRINGS_H"]=" 1" D["HAVE_INTTYPES_H"]=" 1" D["HAVE_STDINT_H"]=" 1" D["HAVE_UNISTD_H"]=" 1" D["HAVE_DLFCN_H"]=" 1" D["LT_OBJDIR"]=" \".libs/\"" D["HAVE_PTHREAD"]=" 1" for (key in D) D_is_set[key] = 1 FS = "" } /^[\t ]*#[\t ]*(define|undef)[\t ]+[_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ][_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789]*([\t (]|$)/ { line = $ 0 split(line, arg, " ") if (arg[1] == "#") { defundef = arg[2] mac1 = arg[3] } else { defundef = substr(arg[1], 2) mac1 = arg[2] } split(mac1, mac2, "(") #) macro = mac2[1] prefix = substr(line, 1, index(line, defundef) - 1) if (D_is_set[macro]) { # Preserve the white space surrounding the "#". print prefix "define", macro P[macro] D[macro] next } else { # Replace #undef with comments. This is necessary, for example, # in the case of _POSIX_SOURCE, which is predefined and required # on some systems where configure will not decide to define it. if (defundef == "undef") { print "/*", prefix defundef, macro, "*/" next } } } { print } _ACAWK as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 fi # test -n "$CONFIG_HEADERS" eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS" shift for ac_tag do case $ac_tag in :[FHLC]) ac_mode=$ac_tag; continue;; esac case $ac_mode$ac_tag in :[FHL]*:*);; :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; :[FH]-) ac_tag=-:-;; :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; esac ac_save_IFS=$IFS IFS=: set x $ac_tag IFS=$ac_save_IFS shift ac_file=$1 shift case $ac_mode in :L) ac_source=$1;; :[FH]) ac_file_inputs= for ac_f do case $ac_f in -) ac_f="$ac_tmp/stdin";; *) # Look for the file first in the build tree, then in the source tree # (if the path is not absolute). The absolute path cannot be DOS-style, # because $ac_f cannot contain `:'. test -f "$ac_f" || case $ac_f in [\\/$]*) false;; *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; esac || as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; esac case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac as_fn_append ac_file_inputs " '$ac_f'" done # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ configure_input='Generated from '` $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' `' by configure.' if test x"$ac_file" != x-; then configure_input="$ac_file. $configure_input" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 $as_echo "$as_me: creating $ac_file" >&6;} fi # Neutralize special characters interpreted by sed in replacement strings. case $configure_input in #( *\&* | *\|* | *\\* ) ac_sed_conf_input=`$as_echo "$configure_input" | sed 's/[\\\\&|]/\\\\&/g'`;; #( *) ac_sed_conf_input=$configure_input;; esac case $ac_tag in *:-:* | *:-) cat >"$ac_tmp/stdin" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; esac ;; esac ac_dir=`$as_dirname -- "$ac_file" || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` as_dir="$ac_dir"; as_fn_mkdir_p ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix case $ac_mode in :F) # # CONFIG_FILE # case $INSTALL in [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; esac ac_MKDIR_P=$MKDIR_P case $MKDIR_P in [\\/$]* | ?:[\\/]* ) ;; */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; esac # If the template does not know about datarootdir, expand it. # FIXME: This hack should be removed a few years after 2.60. ac_datarootdir_hack=; ac_datarootdir_seen= ac_sed_dataroot=' /datarootdir/ { p q } /@datadir@/p /@docdir@/p /@infodir@/p /@localedir@/p /@mandir@/p' case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in *datarootdir*) ac_datarootdir_seen=yes;; *@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 $as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} ac_datarootdir_hack=' s&@datadir@&${datarootdir}&g s&@docdir@&${datarootdir}/doc/${PACKAGE_TARNAME}&g s&@infodir@&${datarootdir}/info&g s&@localedir@&${datarootdir}/locale&g s&@mandir@&${datarootdir}/man&g s&\${datarootdir}&${prefix}/share&g' ;; esac ac_sed_extra="/^[ ]*VPATH[ ]*=[ ]*/{ h s/// s/^/:/ s/[ ]*$/:/ s/:\$(srcdir):/:/g s/:\${srcdir}:/:/g s/:@srcdir@:/:/g s/^:*// s/:*$// x s/\(=[ ]*\).*/\1/ G s/\n// s/^[^=]*=[ ]*$// } :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b s|@configure_input@|$ac_sed_conf_input|;t t s&@top_builddir@&$ac_top_builddir_sub&;t t s&@top_build_prefix@&$ac_top_build_prefix&;t t s&@srcdir@&$ac_srcdir&;t t s&@abs_srcdir@&$ac_abs_srcdir&;t t s&@top_srcdir@&$ac_top_srcdir&;t t s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t s&@builddir@&$ac_builddir&;t t s&@abs_builddir@&$ac_abs_builddir&;t t s&@abs_top_builddir@&$ac_abs_top_builddir&;t t s&@INSTALL@&$ac_INSTALL&;t t s&@MKDIR_P@&$ac_MKDIR_P&;t t $ac_datarootdir_hack " eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ "$ac_tmp/out"`; test -z "$ac_out"; } && { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&5 $as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&2;} rm -f "$ac_tmp/stdin" case $ac_file in -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; esac \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; :H) # # CONFIG_HEADER # if test x"$ac_file" != x-; then { $as_echo "/* $configure_input */" \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" } >"$ac_tmp/config.h" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 $as_echo "$as_me: $ac_file is unchanged" >&6;} else rm -f "$ac_file" mv "$ac_tmp/config.h" "$ac_file" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 fi else $as_echo "/* $configure_input */" \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ || as_fn_error $? "could not create -" "$LINENO" 5 fi # Compute "$ac_file"'s index in $config_headers. _am_arg="$ac_file" _am_stamp_count=1 for _am_header in $config_headers :; do case $_am_header in $_am_arg | $_am_arg:* ) break ;; * ) _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" || $as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$_am_arg" : 'X\(//\)[^/]' \| \ X"$_am_arg" : 'X\(//\)$' \| \ X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$_am_arg" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'`/stamp-h$_am_stamp_count ;; :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 $as_echo "$as_me: executing $ac_file commands" >&6;} ;; esac case $ac_file$ac_mode in "scripts/gtest-config":F) chmod +x scripts/gtest-config ;; "depfiles":C) test x"$AMDEP_TRUE" != x"" || { # Autoconf 2.62 quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. case $CONFIG_FILES in *\'*) eval set x "$CONFIG_FILES" ;; *) set x $CONFIG_FILES ;; esac shift for mf do # Strip MF so we end up with the name of the file. mf=`echo "$mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile or not. # We used to match only the files named `Makefile.in', but # some people rename them; so instead we look at the file content. # Grep'ing the first line is not enough: some people post-process # each Makefile.in and add a new line on top of each file to say so. # Grep'ing the whole file is not good either: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then dirpart=`$as_dirname -- "$mf" || $as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$mf" : 'X\(//\)[^/]' \| \ X"$mf" : 'X\(//\)$' \| \ X"$mf" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$mf" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` else continue fi # Extract the definition of DEPDIR, am__include, and am__quote # from the Makefile without running `make'. DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` test -z "$DEPDIR" && continue am__include=`sed -n 's/^am__include = //p' < "$mf"` test -z "am__include" && continue am__quote=`sed -n 's/^am__quote = //p' < "$mf"` # When using ansi2knr, U may be empty or an underscore; expand it U=`sed -n 's/^U = //p' < "$mf"` # Find all dependency output files, they are included files with # $(DEPDIR) in their names. We invoke sed twice because it is the # simplest approach to changing $(DEPDIR) to its actual value in the # expansion. for file in `sed -n " s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do # Make sure the directory exists. test -f "$dirpart/$file" && continue fdir=`$as_dirname -- "$file" || $as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$file" : 'X\(//\)[^/]' \| \ X"$file" : 'X\(//\)$' \| \ X"$file" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` as_dir=$dirpart/$fdir; as_fn_mkdir_p # echo "creating $dirpart/$file" echo '# dummy' > "$dirpart/$file" done done } ;; "libtool":C) # See if we are running on zsh, and set the options which allow our # commands through without removal of \ escapes. if test -n "${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi cfgfile="${ofile}T" trap "$RM \"$cfgfile\"; exit 1" 1 2 15 $RM "$cfgfile" cat <<_LT_EOF >> "$cfgfile" #! $SHELL # `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. # Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION # Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: # NOTE: Changes made to this file will be lost: look at ltmain.sh. # # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, # 2006, 2007, 2008, 2009, 2010, 2011 Free Software # Foundation, Inc. # Written by Gordon Matzigkeit, 1996 # # This file is part of GNU Libtool. # # GNU Libtool is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as # published by the Free Software Foundation; either version 2 of # the License, or (at your option) any later version. # # As a special exception to the GNU General Public License, # if you distribute this file as part of a program or library that # is built using GNU Libtool, you may include this file under the # same distribution terms that you use for the rest of that program. # # GNU Libtool is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with GNU Libtool; see the file COPYING. If not, a copy # can be downloaded from http://www.gnu.org/licenses/gpl.html, or # obtained by writing to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # The names of the tagged configurations supported by this script. available_tags="CXX " # ### BEGIN LIBTOOL CONFIG # Which release of libtool.m4 was used? macro_version=$macro_version macro_revision=$macro_revision # Whether or not to build shared libraries. build_libtool_libs=$enable_shared # Whether or not to build static libraries. build_old_libs=$enable_static # What type of objects to build. pic_mode=$pic_mode # Whether or not to optimize for fast installation. fast_install=$enable_fast_install # Shell to use when invoking shell scripts. SHELL=$lt_SHELL # An echo program that protects backslashes. ECHO=$lt_ECHO # The PATH separator for the build system. PATH_SEPARATOR=$lt_PATH_SEPARATOR # The host system. host_alias=$host_alias host=$host host_os=$host_os # The build system. build_alias=$build_alias build=$build build_os=$build_os # A sed program that does not truncate output. SED=$lt_SED # Sed that helps us avoid accidentally triggering echo(1) options like -n. Xsed="\$SED -e 1s/^X//" # A grep program that handles long lines. GREP=$lt_GREP # An ERE matcher. EGREP=$lt_EGREP # A literal string matcher. FGREP=$lt_FGREP # A BSD- or MS-compatible name lister. NM=$lt_NM # Whether we need soft or hard links. LN_S=$lt_LN_S # What is the maximum length of a command? max_cmd_len=$max_cmd_len # Object file suffix (normally "o"). objext=$ac_objext # Executable file suffix (normally ""). exeext=$exeext # whether the shell understands "unset". lt_unset=$lt_unset # turn spaces into newlines. SP2NL=$lt_lt_SP2NL # turn newlines into spaces. NL2SP=$lt_lt_NL2SP # convert \$build file names to \$host format. to_host_file_cmd=$lt_cv_to_host_file_cmd # convert \$build files to toolchain format. to_tool_file_cmd=$lt_cv_to_tool_file_cmd # An object symbol dumper. OBJDUMP=$lt_OBJDUMP # Method to check whether dependent libraries are shared objects. deplibs_check_method=$lt_deplibs_check_method # Command to use when deplibs_check_method = "file_magic". file_magic_cmd=$lt_file_magic_cmd # How to find potential files when deplibs_check_method = "file_magic". file_magic_glob=$lt_file_magic_glob # Find potential files using nocaseglob when deplibs_check_method = "file_magic". want_nocaseglob=$lt_want_nocaseglob # DLL creation program. DLLTOOL=$lt_DLLTOOL # Command to associate shared and link libraries. sharedlib_from_linklib_cmd=$lt_sharedlib_from_linklib_cmd # The archiver. AR=$lt_AR # Flags to create an archive. AR_FLAGS=$lt_AR_FLAGS # How to feed a file listing to the archiver. archiver_list_spec=$lt_archiver_list_spec # A symbol stripping program. STRIP=$lt_STRIP # Commands used to install an old-style archive. RANLIB=$lt_RANLIB old_postinstall_cmds=$lt_old_postinstall_cmds old_postuninstall_cmds=$lt_old_postuninstall_cmds # Whether to use a lock for old archive extraction. lock_old_archive_extraction=$lock_old_archive_extraction # A C compiler. LTCC=$lt_CC # LTCC compiler flags. LTCFLAGS=$lt_CFLAGS # Take the output of nm and produce a listing of raw symbols and C names. global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe # Transform the output of nm in a proper C declaration. global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl # Transform the output of nm in a C name address pair. global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address # Transform the output of nm in a C name address pair when lib prefix is needed. global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix # Specify filename containing input files for \$NM. nm_file_list_spec=$lt_nm_file_list_spec # The root where to search for dependent libraries,and in which our libraries should be installed. lt_sysroot=$lt_sysroot # The name of the directory that contains temporary libtool files. objdir=$objdir # Used to examine libraries when file_magic_cmd begins with "file". MAGIC_CMD=$MAGIC_CMD # Must we lock files when doing compilation? need_locks=$lt_need_locks # Manifest tool. MANIFEST_TOOL=$lt_MANIFEST_TOOL # Tool to manipulate archived DWARF debug symbol files on Mac OS X. DSYMUTIL=$lt_DSYMUTIL # Tool to change global to local symbols on Mac OS X. NMEDIT=$lt_NMEDIT # Tool to manipulate fat objects and archives on Mac OS X. LIPO=$lt_LIPO # ldd/readelf like tool for Mach-O binaries on Mac OS X. OTOOL=$lt_OTOOL # ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4. OTOOL64=$lt_OTOOL64 # Old archive suffix (normally "a"). libext=$libext # Shared library suffix (normally ".so"). shrext_cmds=$lt_shrext_cmds # The commands to extract the exported symbol list from a shared archive. extract_expsyms_cmds=$lt_extract_expsyms_cmds # Variables whose values should be saved in libtool wrapper scripts and # restored at link time. variables_saved_for_relink=$lt_variables_saved_for_relink # Do we need the "lib" prefix for modules? need_lib_prefix=$need_lib_prefix # Do we need a version for libraries? need_version=$need_version # Library versioning type. version_type=$version_type # Shared library runtime path variable. runpath_var=$runpath_var # Shared library path variable. shlibpath_var=$shlibpath_var # Is shlibpath searched before the hard-coded library search path? shlibpath_overrides_runpath=$shlibpath_overrides_runpath # Format of library name prefix. libname_spec=$lt_libname_spec # List of archive names. First name is the real one, the rest are links. # The last name is the one that the linker finds with -lNAME library_names_spec=$lt_library_names_spec # The coded name of the library, if different from the real name. soname_spec=$lt_soname_spec # Permission mode override for installation of shared libraries. install_override_mode=$lt_install_override_mode # Command to use after installation of a shared archive. postinstall_cmds=$lt_postinstall_cmds # Command to use after uninstallation of a shared archive. postuninstall_cmds=$lt_postuninstall_cmds # Commands used to finish a libtool library installation in a directory. finish_cmds=$lt_finish_cmds # As "finish_cmds", except a single script fragment to be evaled but # not shown. finish_eval=$lt_finish_eval # Whether we should hardcode library paths into libraries. hardcode_into_libs=$hardcode_into_libs # Compile-time system search path for libraries. sys_lib_search_path_spec=$lt_sys_lib_search_path_spec # Run-time system search path for libraries. sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec # Whether dlopen is supported. dlopen_support=$enable_dlopen # Whether dlopen of programs is supported. dlopen_self=$enable_dlopen_self # Whether dlopen of statically linked programs is supported. dlopen_self_static=$enable_dlopen_self_static # Commands to strip libraries. old_striplib=$lt_old_striplib striplib=$lt_striplib # The linker used to build libraries. LD=$lt_LD # How to create reloadable object files. reload_flag=$lt_reload_flag reload_cmds=$lt_reload_cmds # Commands used to build an old-style archive. old_archive_cmds=$lt_old_archive_cmds # A language specific compiler. CC=$lt_compiler # Is the compiler the GNU compiler? with_gcc=$GCC # Compiler flag to turn off builtin functions. no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag # Additional compiler flags for building library objects. pic_flag=$lt_lt_prog_compiler_pic # How to pass a linker flag through the compiler. wl=$lt_lt_prog_compiler_wl # Compiler flag to prevent dynamic linking. link_static_flag=$lt_lt_prog_compiler_static # Does compiler simultaneously support -c and -o options? compiler_c_o=$lt_lt_cv_prog_compiler_c_o # Whether or not to add -lc for building shared libraries. build_libtool_need_lc=$archive_cmds_need_lc # Whether or not to disallow shared libs when runtime libs are static. allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes # Compiler flag to allow reflexive dlopens. export_dynamic_flag_spec=$lt_export_dynamic_flag_spec # Compiler flag to generate shared objects directly from archives. whole_archive_flag_spec=$lt_whole_archive_flag_spec # Whether the compiler copes with passing no objects directly. compiler_needs_object=$lt_compiler_needs_object # Create an old-style archive from a shared archive. old_archive_from_new_cmds=$lt_old_archive_from_new_cmds # Create a temporary old-style archive to link instead of a shared archive. old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds # Commands used to build a shared archive. archive_cmds=$lt_archive_cmds archive_expsym_cmds=$lt_archive_expsym_cmds # Commands used to build a loadable module if different from building # a shared archive. module_cmds=$lt_module_cmds module_expsym_cmds=$lt_module_expsym_cmds # Whether we are building with GNU ld or not. with_gnu_ld=$lt_with_gnu_ld # Flag that allows shared libraries with undefined symbols to be built. allow_undefined_flag=$lt_allow_undefined_flag # Flag that enforces no undefined symbols. no_undefined_flag=$lt_no_undefined_flag # Flag to hardcode \$libdir into a binary during linking. # This must work even if \$libdir does not exist hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec # Whether we need a single "-rpath" flag with a separated argument. hardcode_libdir_separator=$lt_hardcode_libdir_separator # Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes # DIR into the resulting binary. hardcode_direct=$hardcode_direct # Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes # DIR into the resulting binary and the resulting library dependency is # "absolute",i.e impossible to change by setting \${shlibpath_var} if the # library is relocated. hardcode_direct_absolute=$hardcode_direct_absolute # Set to "yes" if using the -LDIR flag during linking hardcodes DIR # into the resulting binary. hardcode_minus_L=$hardcode_minus_L # Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR # into the resulting binary. hardcode_shlibpath_var=$hardcode_shlibpath_var # Set to "yes" if building a shared library automatically hardcodes DIR # into the library and all subsequent libraries and executables linked # against it. hardcode_automatic=$hardcode_automatic # Set to yes if linker adds runtime paths of dependent libraries # to runtime path list. inherit_rpath=$inherit_rpath # Whether libtool must link a program against all its dependency libraries. link_all_deplibs=$link_all_deplibs # Set to "yes" if exported symbols are required. always_export_symbols=$always_export_symbols # The commands to list exported symbols. export_symbols_cmds=$lt_export_symbols_cmds # Symbols that should not be listed in the preloaded symbols. exclude_expsyms=$lt_exclude_expsyms # Symbols that must always be exported. include_expsyms=$lt_include_expsyms # Commands necessary for linking programs (against libraries) with templates. prelink_cmds=$lt_prelink_cmds # Commands necessary for finishing linking programs. postlink_cmds=$lt_postlink_cmds # Specify filename containing input files. file_list_spec=$lt_file_list_spec # How to hardcode a shared library path into an executable. hardcode_action=$hardcode_action # The directories searched by this compiler when creating a shared library. compiler_lib_search_dirs=$lt_compiler_lib_search_dirs # Dependencies to place before and after the objects being linked to # create a shared library. predep_objects=$lt_predep_objects postdep_objects=$lt_postdep_objects predeps=$lt_predeps postdeps=$lt_postdeps # The library search path used internally by the compiler when linking # a shared library. compiler_lib_search_path=$lt_compiler_lib_search_path # ### END LIBTOOL CONFIG _LT_EOF case $host_os in aix3*) cat <<\_LT_EOF >> "$cfgfile" # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test "X${COLLECT_NAMES+set}" != Xset; then COLLECT_NAMES= export COLLECT_NAMES fi _LT_EOF ;; esac ltmain="$ac_aux_dir/ltmain.sh" # We use sed instead of cat because bash on DJGPP gets confused if # if finds mixed CR/LF and LF-only lines. Since sed operates in # text mode, it properly converts lines to CR/LF. This bash problem # is reportedly fixed, but why not run on old versions too? sed '$q' "$ltmain" >> "$cfgfile" \ || (rm -f "$cfgfile"; exit 1) if test x"$xsi_shell" = xyes; then sed -e '/^func_dirname ()$/,/^} # func_dirname /c\ func_dirname ()\ {\ \ case ${1} in\ \ */*) func_dirname_result="${1%/*}${2}" ;;\ \ * ) func_dirname_result="${3}" ;;\ \ esac\ } # Extended-shell func_dirname implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_basename ()$/,/^} # func_basename /c\ func_basename ()\ {\ \ func_basename_result="${1##*/}"\ } # Extended-shell func_basename implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_dirname_and_basename ()$/,/^} # func_dirname_and_basename /c\ func_dirname_and_basename ()\ {\ \ case ${1} in\ \ */*) func_dirname_result="${1%/*}${2}" ;;\ \ * ) func_dirname_result="${3}" ;;\ \ esac\ \ func_basename_result="${1##*/}"\ } # Extended-shell func_dirname_and_basename implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_stripname ()$/,/^} # func_stripname /c\ func_stripname ()\ {\ \ # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are\ \ # positional parameters, so assign one to ordinary parameter first.\ \ func_stripname_result=${3}\ \ func_stripname_result=${func_stripname_result#"${1}"}\ \ func_stripname_result=${func_stripname_result%"${2}"}\ } # Extended-shell func_stripname implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_split_long_opt ()$/,/^} # func_split_long_opt /c\ func_split_long_opt ()\ {\ \ func_split_long_opt_name=${1%%=*}\ \ func_split_long_opt_arg=${1#*=}\ } # Extended-shell func_split_long_opt implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_split_short_opt ()$/,/^} # func_split_short_opt /c\ func_split_short_opt ()\ {\ \ func_split_short_opt_arg=${1#??}\ \ func_split_short_opt_name=${1%"$func_split_short_opt_arg"}\ } # Extended-shell func_split_short_opt implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_lo2o ()$/,/^} # func_lo2o /c\ func_lo2o ()\ {\ \ case ${1} in\ \ *.lo) func_lo2o_result=${1%.lo}.${objext} ;;\ \ *) func_lo2o_result=${1} ;;\ \ esac\ } # Extended-shell func_lo2o implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_xform ()$/,/^} # func_xform /c\ func_xform ()\ {\ func_xform_result=${1%.*}.lo\ } # Extended-shell func_xform implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_arith ()$/,/^} # func_arith /c\ func_arith ()\ {\ func_arith_result=$(( $* ))\ } # Extended-shell func_arith implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_len ()$/,/^} # func_len /c\ func_len ()\ {\ func_len_result=${#1}\ } # Extended-shell func_len implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: fi if test x"$lt_shell_append" = xyes; then sed -e '/^func_append ()$/,/^} # func_append /c\ func_append ()\ {\ eval "${1}+=\\${2}"\ } # Extended-shell func_append implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_append_quoted ()$/,/^} # func_append_quoted /c\ func_append_quoted ()\ {\ \ func_quote_for_eval "${2}"\ \ eval "${1}+=\\\\ \\$func_quote_for_eval_result"\ } # Extended-shell func_append_quoted implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: # Save a `func_append' function call where possible by direct use of '+=' sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: else # Save a `func_append' function call even when '+=' is not available sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: fi if test x"$_lt_function_replace_fail" = x":"; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Unable to substitute extended shell functions in $ofile" >&5 $as_echo "$as_me: WARNING: Unable to substitute extended shell functions in $ofile" >&2;} fi mv -f "$cfgfile" "$ofile" || (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") chmod +x "$ofile" cat <<_LT_EOF >> "$ofile" # ### BEGIN LIBTOOL TAG CONFIG: CXX # The linker used to build libraries. LD=$lt_LD_CXX # How to create reloadable object files. reload_flag=$lt_reload_flag_CXX reload_cmds=$lt_reload_cmds_CXX # Commands used to build an old-style archive. old_archive_cmds=$lt_old_archive_cmds_CXX # A language specific compiler. CC=$lt_compiler_CXX # Is the compiler the GNU compiler? with_gcc=$GCC_CXX # Compiler flag to turn off builtin functions. no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_CXX # Additional compiler flags for building library objects. pic_flag=$lt_lt_prog_compiler_pic_CXX # How to pass a linker flag through the compiler. wl=$lt_lt_prog_compiler_wl_CXX # Compiler flag to prevent dynamic linking. link_static_flag=$lt_lt_prog_compiler_static_CXX # Does compiler simultaneously support -c and -o options? compiler_c_o=$lt_lt_cv_prog_compiler_c_o_CXX # Whether or not to add -lc for building shared libraries. build_libtool_need_lc=$archive_cmds_need_lc_CXX # Whether or not to disallow shared libs when runtime libs are static. allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_CXX # Compiler flag to allow reflexive dlopens. export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_CXX # Compiler flag to generate shared objects directly from archives. whole_archive_flag_spec=$lt_whole_archive_flag_spec_CXX # Whether the compiler copes with passing no objects directly. compiler_needs_object=$lt_compiler_needs_object_CXX # Create an old-style archive from a shared archive. old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_CXX # Create a temporary old-style archive to link instead of a shared archive. old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_CXX # Commands used to build a shared archive. archive_cmds=$lt_archive_cmds_CXX archive_expsym_cmds=$lt_archive_expsym_cmds_CXX # Commands used to build a loadable module if different from building # a shared archive. module_cmds=$lt_module_cmds_CXX module_expsym_cmds=$lt_module_expsym_cmds_CXX # Whether we are building with GNU ld or not. with_gnu_ld=$lt_with_gnu_ld_CXX # Flag that allows shared libraries with undefined symbols to be built. allow_undefined_flag=$lt_allow_undefined_flag_CXX # Flag that enforces no undefined symbols. no_undefined_flag=$lt_no_undefined_flag_CXX # Flag to hardcode \$libdir into a binary during linking. # This must work even if \$libdir does not exist hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_CXX # Whether we need a single "-rpath" flag with a separated argument. hardcode_libdir_separator=$lt_hardcode_libdir_separator_CXX # Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes # DIR into the resulting binary. hardcode_direct=$hardcode_direct_CXX # Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes # DIR into the resulting binary and the resulting library dependency is # "absolute",i.e impossible to change by setting \${shlibpath_var} if the # library is relocated. hardcode_direct_absolute=$hardcode_direct_absolute_CXX # Set to "yes" if using the -LDIR flag during linking hardcodes DIR # into the resulting binary. hardcode_minus_L=$hardcode_minus_L_CXX # Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR # into the resulting binary. hardcode_shlibpath_var=$hardcode_shlibpath_var_CXX # Set to "yes" if building a shared library automatically hardcodes DIR # into the library and all subsequent libraries and executables linked # against it. hardcode_automatic=$hardcode_automatic_CXX # Set to yes if linker adds runtime paths of dependent libraries # to runtime path list. inherit_rpath=$inherit_rpath_CXX # Whether libtool must link a program against all its dependency libraries. link_all_deplibs=$link_all_deplibs_CXX # Set to "yes" if exported symbols are required. always_export_symbols=$always_export_symbols_CXX # The commands to list exported symbols. export_symbols_cmds=$lt_export_symbols_cmds_CXX # Symbols that should not be listed in the preloaded symbols. exclude_expsyms=$lt_exclude_expsyms_CXX # Symbols that must always be exported. include_expsyms=$lt_include_expsyms_CXX # Commands necessary for linking programs (against libraries) with templates. prelink_cmds=$lt_prelink_cmds_CXX # Commands necessary for finishing linking programs. postlink_cmds=$lt_postlink_cmds_CXX # Specify filename containing input files. file_list_spec=$lt_file_list_spec_CXX # How to hardcode a shared library path into an executable. hardcode_action=$hardcode_action_CXX # The directories searched by this compiler when creating a shared library. compiler_lib_search_dirs=$lt_compiler_lib_search_dirs_CXX # Dependencies to place before and after the objects being linked to # create a shared library. predep_objects=$lt_predep_objects_CXX postdep_objects=$lt_postdep_objects_CXX predeps=$lt_predeps_CXX postdeps=$lt_postdeps_CXX # The library search path used internally by the compiler when linking # a shared library. compiler_lib_search_path=$lt_compiler_lib_search_path_CXX # ### END LIBTOOL TAG CONFIG: CXX _LT_EOF ;; esac done # for ac_tag as_fn_exit 0 dlt-daemon-2.18.4/gtest-1.7.0/configure000077500000000000000000021163601353342203500173410ustar00rootroot00000000000000#! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.68 for Google C++ Testing Framework 1.7.0. # # Report bugs to . # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, # 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software # Foundation, Inc. # # # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH if test "x$CONFIG_SHELL" = x; then as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which # is contrary to our usage. Disable this feature. alias -g '\${1+\"\$@\"}'='\"\$@\"' setopt NO_GLOB_SUBST else case \`(set -o) 2>/dev/null\` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi " as_required="as_fn_return () { (exit \$1); } as_fn_success () { as_fn_return 0; } as_fn_failure () { as_fn_return 1; } as_fn_ret_success () { return 0; } as_fn_ret_failure () { return 1; } exitcode=0 as_fn_success || { exitcode=1; echo as_fn_success failed.; } as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : else exitcode=1; echo positional parameters were not saved. fi test x\$exitcode = x0 || exit 1" as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 test -n \"\${ZSH_VERSION+set}\${BASH_VERSION+set}\" || ( ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO PATH=/empty FPATH=/empty; export PATH FPATH test \"X\`printf %s \$ECHO\`\" = \"X\$ECHO\" \\ || test \"X\`print -r -- \$ECHO\`\" = \"X\$ECHO\" ) || exit 1 test \$(( 1 + 1 )) = 2 || exit 1" if (eval "$as_required") 2>/dev/null; then : as_have_required=yes else as_have_required=no fi if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_found=false for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. as_found=: case $as_dir in #( /*) for as_base in sh bash ksh sh5; do # Try only shells that exist, to save several forks. as_shell=$as_dir/$as_base if { test -f "$as_shell" || test -f "$as_shell.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : CONFIG_SHELL=$as_shell as_have_required=yes if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : break 2 fi fi done;; esac as_found=false done $as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : CONFIG_SHELL=$SHELL as_have_required=yes fi; } IFS=$as_save_IFS if test "x$CONFIG_SHELL" != x; then : # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV export CONFIG_SHELL case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec "$CONFIG_SHELL" $as_opts "$as_myself" ${1+"$@"} fi if test x$as_have_required = xno; then : $as_echo "$0: This script requires a shell more modern than all" $as_echo "$0: the shells that I found on your system." if test x${ZSH_VERSION+set} = xset ; then $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" $as_echo "$0: be upgraded to zsh 4.3.4 or later." else $as_echo "$0: Please tell bug-autoconf@gnu.org and $0: googletestframework@googlegroups.com about your system, $0: including any error possibly output before this $0: message. Then install a modern shell, or manually run $0: the script under such a shell if you do have one." fi exit 1 fi fi fi SHELL=${CONFIG_SHELL-/bin/sh} export SHELL # Unset more variables known to interfere with behavior of common tools. CLICOLOR_FORCE= GREP_OPTIONS= unset CLICOLOR_FORCE GREP_OPTIONS ## --------------------- ## ## M4sh Shell Functions. ## ## --------------------- ## # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits as_lineno_1=$LINENO as_lineno_1a=$LINENO as_lineno_2=$LINENO as_lineno_2a=$LINENO eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) sed -n ' p /[$]LINENO/= ' <$as_myself | sed ' s/[$]LINENO.*/&-/ t lineno b :lineno N :loop s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ t loop s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). . "./$as_me.lineno" # Exit status is that of the last command. exit } ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -p'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -p' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' fi else as_ln_s='cp -p' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi if test -x / >/dev/null 2>&1; then as_test_x='test -x' else if ls -dL / >/dev/null 2>&1; then as_ls_L_option=L else as_ls_L_option= fi as_test_x=' eval sh -c '\'' if test -d "$1"; then test -d "$1/."; else case $1 in #( -*)set "./$1";; esac; case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( ???[sx]*):;;*)false;;esac;fi '\'' sh ' fi as_executable_p=$as_test_x # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" SHELL=${CONFIG_SHELL-/bin/sh} test -n "$DJDIR" || exec 7<&0 &1 # Name of the host. # hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` # # Initializations. # ac_default_prefix=/usr/local ac_clean_files= ac_config_libobj_dir=. LIBOBJS= cross_compiling=no subdirs= MFLAGS= MAKEFLAGS= # Identity of this package. PACKAGE_NAME='Google C++ Testing Framework' PACKAGE_TARNAME='gtest' PACKAGE_VERSION='1.7.0' PACKAGE_STRING='Google C++ Testing Framework 1.7.0' PACKAGE_BUGREPORT='googletestframework@googlegroups.com' PACKAGE_URL='' ac_unique_file="./LICENSE" # Factoring default headers for most tests. ac_includes_default="\ #include #ifdef HAVE_SYS_TYPES_H # include #endif #ifdef HAVE_SYS_STAT_H # include #endif #ifdef STDC_HEADERS # include # include #else # ifdef HAVE_STDLIB_H # include # endif #endif #ifdef HAVE_STRING_H # if !defined STDC_HEADERS && defined HAVE_MEMORY_H # include # endif # include #endif #ifdef HAVE_STRINGS_H # include #endif #ifdef HAVE_INTTYPES_H # include #endif #ifdef HAVE_STDINT_H # include #endif #ifdef HAVE_UNISTD_H # include #endif" ac_subst_vars='am__EXEEXT_FALSE am__EXEEXT_TRUE LTLIBOBJS LIBOBJS HAVE_PTHREADS_FALSE HAVE_PTHREADS_TRUE PTHREAD_CFLAGS PTHREAD_LIBS PTHREAD_CC acx_pthread_config HAVE_PYTHON_FALSE HAVE_PYTHON_TRUE PYTHON CXXCPP CPP OTOOL64 OTOOL LIPO NMEDIT DSYMUTIL MANIFEST_TOOL RANLIB ac_ct_AR AR DLLTOOL OBJDUMP LN_S NM ac_ct_DUMPBIN DUMPBIN LD FGREP EGREP GREP SED host_os host_vendor host_cpu host build_os build_vendor build_cpu build LIBTOOL am__fastdepCXX_FALSE am__fastdepCXX_TRUE CXXDEPMODE ac_ct_CXX CXXFLAGS CXX am__fastdepCC_FALSE am__fastdepCC_TRUE CCDEPMODE am__nodep AMDEPBACKSLASH AMDEP_FALSE AMDEP_TRUE am__quote am__include DEPDIR OBJEXT EXEEXT ac_ct_CC CPPFLAGS LDFLAGS CFLAGS CC am__untar am__tar AMTAR am__leading_dot SET_MAKE AWK mkdir_p MKDIR_P INSTALL_STRIP_PROGRAM STRIP install_sh MAKEINFO AUTOHEADER AUTOMAKE AUTOCONF ACLOCAL VERSION PACKAGE CYGPATH_W am__isrc INSTALL_DATA INSTALL_SCRIPT INSTALL_PROGRAM target_alias host_alias build_alias LIBS ECHO_T ECHO_N ECHO_C DEFS mandir localedir libdir psdir pdfdir dvidir htmldir infodir docdir oldincludedir includedir localstatedir sharedstatedir sysconfdir datadir datarootdir libexecdir sbindir bindir program_transform_name prefix exec_prefix PACKAGE_URL PACKAGE_BUGREPORT PACKAGE_STRING PACKAGE_VERSION PACKAGE_TARNAME PACKAGE_NAME PATH_SEPARATOR SHELL' ac_subst_files='' ac_user_opts=' enable_option_checking enable_dependency_tracking enable_shared enable_static with_pic enable_fast_install with_gnu_ld with_sysroot enable_libtool_lock with_pthreads ' ac_precious_vars='build_alias host_alias target_alias CC CFLAGS LDFLAGS LIBS CPPFLAGS CXX CXXFLAGS CCC CPP CXXCPP' # Initialize some variables set by options. ac_init_help= ac_init_version=false ac_unrecognized_opts= ac_unrecognized_sep= # The variables have the same names as the options, with # dashes changed to underlines. cache_file=/dev/null exec_prefix=NONE no_create= no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= verbose= x_includes=NONE x_libraries=NONE # Installation directory options. # These are left unexpanded so users can "make install exec_prefix=/foo" # and all the variables that are supposed to be based on exec_prefix # by default will actually change. # Use braces instead of parens because sh, perl, etc. also accept them. # (The list follows the same order as the GNU Coding Standards.) bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datarootdir='${prefix}/share' datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' infodir='${datarootdir}/info' htmldir='${docdir}' dvidir='${docdir}' pdfdir='${docdir}' psdir='${docdir}' libdir='${exec_prefix}/lib' localedir='${datarootdir}/locale' mandir='${datarootdir}/man' ac_prev= ac_dashdash= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval $ac_prev=\$ac_option ac_prev= continue fi case $ac_option in *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; *=) ac_optarg= ;; *) ac_optarg=yes ;; esac # Accept the important Cygnus configure options, so we can diagnose typos. case $ac_dashdash$ac_option in --) ac_dashdash=yes ;; -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir=$ac_optarg ;; -build | --build | --buil | --bui | --bu) ac_prev=build_alias ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build_alias=$ac_optarg ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file=$ac_optarg ;; --config-cache | -C) cache_file=config.cache ;; -datadir | --datadir | --datadi | --datad) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=*) datadir=$ac_optarg ;; -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ | --dataroo | --dataro | --datar) ac_prev=datarootdir ;; -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) datarootdir=$ac_optarg ;; -disable-* | --disable-*) ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=no ;; -docdir | --docdir | --docdi | --doc | --do) ac_prev=docdir ;; -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) docdir=$ac_optarg ;; -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) ac_prev=dvidir ;; -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) dvidir=$ac_optarg ;; -enable-* | --enable-*) ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=\$ac_optarg ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix=$ac_optarg ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he | -h) ac_init_help=long ;; -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) ac_init_help=recursive ;; -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) ac_init_help=short ;; -host | --host | --hos | --ho) ac_prev=host_alias ;; -host=* | --host=* | --hos=* | --ho=*) host_alias=$ac_optarg ;; -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) ac_prev=htmldir ;; -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ | --ht=*) htmldir=$ac_optarg ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir=$ac_optarg ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir=$ac_optarg ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir=$ac_optarg ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir=$ac_optarg ;; -localedir | --localedir | --localedi | --localed | --locale) ac_prev=localedir ;; -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) localedir=$ac_optarg ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst | --locals) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) localstatedir=$ac_optarg ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir=$ac_optarg ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c | -n) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir=$ac_optarg ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix=$ac_optarg ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix=$ac_optarg ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix=$ac_optarg ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name=$ac_optarg ;; -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) ac_prev=pdfdir ;; -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) pdfdir=$ac_optarg ;; -psdir | --psdir | --psdi | --psd | --ps) ac_prev=psdir ;; -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) psdir=$ac_optarg ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir=$ac_optarg ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir=$ac_optarg ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site=$ac_optarg ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir=$ac_optarg ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir=$ac_optarg ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target_alias ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target_alias=$ac_optarg ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers | -V) ac_init_version=: ;; -with-* | --with-*) ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=\$ac_optarg ;; -without-* | --without-*) ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=no ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes=$ac_optarg ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries=$ac_optarg ;; -*) as_fn_error $? "unrecognized option: \`$ac_option' Try \`$0 --help' for more information" ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. case $ac_envvar in #( '' | [0-9]* | *[!_$as_cr_alnum]* ) as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; esac eval $ac_envvar=\$ac_optarg export $ac_envvar ;; *) # FIXME: should be removed in autoconf 3.0. $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" ;; esac done if test -n "$ac_prev"; then ac_option=--`echo $ac_prev | sed 's/_/-/g'` as_fn_error $? "missing argument to $ac_option" fi if test -n "$ac_unrecognized_opts"; then case $enable_option_checking in no) ;; fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; esac fi # Check all directory arguments for consistency. for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ libdir localedir mandir do eval ac_val=\$$ac_var # Remove trailing slashes. case $ac_val in */ ) ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` eval $ac_var=\$ac_val;; esac # Be sure to have absolute directory names. case $ac_val in [\\/$]* | ?:[\\/]* ) continue;; NONE | '' ) case $ac_var in *prefix ) continue;; esac;; esac as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" done # There might be people who depend on the old broken behavior: `$host' # used to hold the argument of --host etc. # FIXME: To remove some day. build=$build_alias host=$host_alias target=$target_alias # FIXME: To remove some day. if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe $as_echo "$as_me: WARNING: if you wanted to set the --build type, don't use --host. If a cross compiler is detected then cross compile mode will be used" >&2 elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi fi ac_tool_prefix= test -n "$host_alias" && ac_tool_prefix=$host_alias- test "$silent" = yes && exec 6>/dev/null ac_pwd=`pwd` && test -n "$ac_pwd" && ac_ls_di=`ls -di .` && ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || as_fn_error $? "working directory cannot be determined" test "X$ac_ls_di" = "X$ac_pwd_ls_di" || as_fn_error $? "pwd does not report name of working directory" # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then the parent directory. ac_confdir=`$as_dirname -- "$as_myself" || $as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_myself" : 'X\(//\)[^/]' \| \ X"$as_myself" : 'X\(//\)$' \| \ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_myself" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` srcdir=$ac_confdir if test ! -r "$srcdir/$ac_unique_file"; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r "$srcdir/$ac_unique_file"; then test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" fi ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" ac_abs_confdir=`( cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" pwd)` # When building in place, set srcdir=. if test "$ac_abs_confdir" = "$ac_pwd"; then srcdir=. fi # Remove unnecessary trailing slashes from srcdir. # Double slashes in file names in object file debugging info # mess up M-x gdb in Emacs. case $srcdir in */) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; esac for ac_var in $ac_precious_vars; do eval ac_env_${ac_var}_set=\${${ac_var}+set} eval ac_env_${ac_var}_value=\$${ac_var} eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} eval ac_cv_env_${ac_var}_value=\$${ac_var} done # # Report the --help message. # if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF \`configure' configures Google C++ Testing Framework 1.7.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... To assign environment variables (e.g., CC, CFLAGS...), specify them as VAR=VALUE. See below for descriptions of some of the useful variables. Defaults for the options are specified in brackets. Configuration: -h, --help display this help and exit --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit -q, --quiet, --silent do not print \`checking ...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for \`--cache-file=config.cache' -n, --no-create do not create output files --srcdir=DIR find the sources in DIR [configure dir or \`..'] Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [PREFIX] By default, \`make install' will install all the files in \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify an installation prefix other than \`$ac_default_prefix' using \`--prefix', for instance \`--prefix=\$HOME'. For better control, use the options below. Fine tuning of the installation directories: --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] --datadir=DIR read-only architecture-independent data [DATAROOTDIR] --infodir=DIR info documentation [DATAROOTDIR/info] --localedir=DIR locale-dependent data [DATAROOTDIR/locale] --mandir=DIR man documentation [DATAROOTDIR/man] --docdir=DIR documentation root [DATAROOTDIR/doc/gtest] --htmldir=DIR html documentation [DOCDIR] --dvidir=DIR dvi documentation [DOCDIR] --pdfdir=DIR pdf documentation [DOCDIR] --psdir=DIR ps documentation [DOCDIR] _ACEOF cat <<\_ACEOF Program names: --program-prefix=PREFIX prepend PREFIX to installed program names --program-suffix=SUFFIX append SUFFIX to installed program names --program-transform-name=PROGRAM run sed PROGRAM on installed program names System types: --build=BUILD configure for building on BUILD [guessed] --host=HOST cross-compile to build programs to run on HOST [BUILD] _ACEOF fi if test -n "$ac_init_help"; then case $ac_init_help in short | recursive ) echo "Configuration of Google C++ Testing Framework 1.7.0:";; esac cat <<\_ACEOF Optional Features: --disable-option-checking ignore unrecognized --enable/--with options --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --disable-dependency-tracking speeds up one-time build --enable-dependency-tracking do not reject slow dependency extractors --enable-shared[=PKGS] build shared libraries [default=yes] --enable-static[=PKGS] build static libraries [default=yes] --enable-fast-install[=PKGS] optimize for fast installation [default=yes] --disable-libtool-lock avoid locking (might break parallel builds) Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --with-pic[=PKGS] try to use only PIC/non-PIC objects [default=use both] --with-gnu-ld assume the C compiler uses GNU ld [default=no] --with-sysroot=DIR Search for dependent libraries within DIR (or the compiler's sysroot if not specified). --with-pthreads use pthreads (default is yes) Some influential environment variables: CC C compiler command CFLAGS C compiler flags LDFLAGS linker flags, e.g. -L if you have libraries in a nonstandard directory LIBS libraries to pass to the linker, e.g. -l CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if you have headers in a nonstandard directory CXX C++ compiler command CXXFLAGS C++ compiler flags CPP C preprocessor CXXCPP C++ preprocessor Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. Report bugs to . _ACEOF ac_status=$? fi if test "$ac_init_help" = "recursive"; then # If there are subdirs, report their specific --help. for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue test -d "$ac_dir" || { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || continue ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix cd "$ac_dir" || { ac_status=$?; continue; } # Check for guested configure. if test -f "$ac_srcdir/configure.gnu"; then echo && $SHELL "$ac_srcdir/configure.gnu" --help=recursive elif test -f "$ac_srcdir/configure"; then echo && $SHELL "$ac_srcdir/configure" --help=recursive else $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 fi || ac_status=$? cd "$ac_pwd" || { ac_status=$?; break; } done fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF Google C++ Testing Framework configure 1.7.0 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF exit fi ## ------------------------ ## ## Autoconf initialization. ## ## ------------------------ ## # ac_fn_c_try_compile LINENO # -------------------------- # Try to compile conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_compile # ac_fn_cxx_try_compile LINENO # ---------------------------- # Try to compile conftest.$ac_ext, and return whether this succeeded. ac_fn_cxx_try_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_cxx_try_compile # ac_fn_c_try_link LINENO # ----------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_link () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext conftest$ac_exeext if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would # interfere with the next link command; also delete a directory that is # left behind by Apple's compiler. We do this before executing the actions. rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_link # ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES # ------------------------------------------------------- # Tests whether HEADER exists and can be compiled using the include files in # INCLUDES, setting the cache variable VAR accordingly. ac_fn_c_check_header_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_c_try_compile "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_header_compile # ac_fn_c_try_cpp LINENO # ---------------------- # Try to preprocess conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_cpp () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } > conftest.i && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_cpp # ac_fn_c_try_run LINENO # ---------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. Assumes # that executables *can* be run. ac_fn_c_try_run () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then : ac_retval=0 else $as_echo "$as_me: program exited with status $ac_status" >&5 $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=$ac_status fi rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_run # ac_fn_c_check_func LINENO FUNC VAR # ---------------------------------- # Tests whether FUNC exists, setting the cache variable VAR accordingly ac_fn_c_check_func () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Define $2 to an innocuous variant, in case declares $2. For example, HP-UX 11i declares gettimeofday. */ #define $2 innocuous_$2 /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $2 (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $2 /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $2 (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$2 || defined __stub___$2 choke me #endif int main () { return $2 (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_func # ac_fn_cxx_try_cpp LINENO # ------------------------ # Try to preprocess conftest.$ac_ext, and return whether this succeeded. ac_fn_cxx_try_cpp () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } > conftest.i && { test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || test ! -s conftest.err }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_cxx_try_cpp # ac_fn_cxx_try_link LINENO # ------------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. ac_fn_cxx_try_link () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext conftest$ac_exeext if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would # interfere with the next link command; also delete a directory that is # left behind by Apple's compiler. We do this before executing the actions. rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_cxx_try_link cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by Google C++ Testing Framework $as_me 1.7.0, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ _ACEOF exec 5>>config.log { cat <<_ASUNAME ## --------- ## ## Platform. ## ## --------- ## hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` /bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` /bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` /usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` /bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` /bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` _ASUNAME as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. $as_echo "PATH: $as_dir" done IFS=$as_save_IFS } >&5 cat >&5 <<_ACEOF ## ----------- ## ## Core tests. ## ## ----------- ## _ACEOF # Keep a trace of the command line. # Strip out --no-create and --no-recursion so they do not pile up. # Strip out --silent because we don't want to record it for future runs. # Also quote any args containing shell meta-characters. # Make two passes to allow for proper duplicate-argument suppression. ac_configure_args= ac_configure_args0= ac_configure_args1= ac_must_keep_next=false for ac_pass in 1 2 do for ac_arg do case $ac_arg in -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) continue ;; *\'*) ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; 2) as_fn_append ac_configure_args1 " '$ac_arg'" if test $ac_must_keep_next = true; then ac_must_keep_next=false # Got value, back to normal. else case $ac_arg in *=* | --config-cache | -C | -disable-* | --disable-* \ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ | -with-* | --with-* | -without-* | --without-* | --x) case "$ac_configure_args0 " in "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; esac ;; -* ) ac_must_keep_next=true ;; esac fi as_fn_append ac_configure_args " '$ac_arg'" ;; esac done done { ac_configure_args0=; unset ac_configure_args0;} { ac_configure_args1=; unset ac_configure_args1;} # When interrupted or exit'd, cleanup temporary files, and complete # config.log. We remove comments because anyway the quotes in there # would cause problems or look ugly. # WARNING: Use '\'' to represent an apostrophe within the trap. # WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. trap 'exit_status=$? # Save into config.log some information that might help in debugging. { echo $as_echo "## ---------------- ## ## Cache variables. ## ## ---------------- ##" echo # The following way of writing the cache mishandles newlines in values, ( for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( *${as_nl}ac_space=\ *) sed -n \ "s/'\''/'\''\\\\'\'''\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" ;; #( *) sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) echo $as_echo "## ----------------- ## ## Output variables. ## ## ----------------- ##" echo for ac_var in $ac_subst_vars do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo if test -n "$ac_subst_files"; then $as_echo "## ------------------- ## ## File substitutions. ## ## ------------------- ##" echo for ac_var in $ac_subst_files do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo fi if test -s confdefs.h; then $as_echo "## ----------- ## ## confdefs.h. ## ## ----------- ##" echo cat confdefs.h echo fi test "$ac_signal" != 0 && $as_echo "$as_me: caught signal $ac_signal" $as_echo "$as_me: exit $exit_status" } >&5 rm -f core *.core core.conftest.* && rm -f -r conftest* confdefs* conf$$* $ac_clean_files && exit $exit_status ' 0 for ac_signal in 1 2 13 15; do trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal done ac_signal=0 # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -f -r conftest* confdefs.h $as_echo "/* confdefs.h */" > confdefs.h # Predefined preprocessor variables. cat >>confdefs.h <<_ACEOF #define PACKAGE_NAME "$PACKAGE_NAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_TARNAME "$PACKAGE_TARNAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_VERSION "$PACKAGE_VERSION" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_STRING "$PACKAGE_STRING" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_URL "$PACKAGE_URL" _ACEOF # Let the site file select an alternate cache file if it wants to. # Prefer an explicitly selected file to automatically selected ones. ac_site_file1=NONE ac_site_file2=NONE if test -n "$CONFIG_SITE"; then # We do not want a PATH search for config.site. case $CONFIG_SITE in #(( -*) ac_site_file1=./$CONFIG_SITE;; */*) ac_site_file1=$CONFIG_SITE;; *) ac_site_file1=./$CONFIG_SITE;; esac elif test "x$prefix" != xNONE; then ac_site_file1=$prefix/share/config.site ac_site_file2=$prefix/etc/config.site else ac_site_file1=$ac_default_prefix/share/config.site ac_site_file2=$ac_default_prefix/etc/config.site fi for ac_site_file in "$ac_site_file1" "$ac_site_file2" do test "x$ac_site_file" = xNONE && continue if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 $as_echo "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" \ || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "failed to load site script $ac_site_file See \`config.log' for more details" "$LINENO" 5; } fi done if test -r "$cache_file"; then # Some versions of bash will fail to source /dev/null (special files # actually), so we avoid doing that. DJGPP emulates it as a regular file. if test /dev/null != "$cache_file" && test -f "$cache_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 $as_echo "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . "$cache_file";; *) . "./$cache_file";; esac fi else { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 $as_echo "$as_me: creating cache $cache_file" >&6;} >$cache_file fi # Check that the precious variables saved in the cache have kept the same # value. ac_cache_corrupted=false for ac_var in $ac_precious_vars; do eval ac_old_set=\$ac_cv_env_${ac_var}_set eval ac_new_set=\$ac_env_${ac_var}_set eval ac_old_val=\$ac_cv_env_${ac_var}_value eval ac_new_val=\$ac_env_${ac_var}_value case $ac_old_set,$ac_new_set in set,) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ac_cache_corrupted=: ;; ,);; *) if test "x$ac_old_val" != "x$ac_new_val"; then # differences in whitespace do not lead to failure. ac_old_val_w=`echo x $ac_old_val` ac_new_val_w=`echo x $ac_new_val` if test "$ac_old_val_w" != "$ac_new_val_w"; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 $as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} ac_cache_corrupted=: else { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 $as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} eval $ac_var=\$ac_old_val fi { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 $as_echo "$as_me: former value: \`$ac_old_val'" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 $as_echo "$as_me: current value: \`$ac_new_val'" >&2;} fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; *) ac_arg=$ac_var=$ac_new_val ;; esac case " $ac_configure_args " in *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. *) as_fn_append ac_configure_args " '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 $as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 fi ## -------------------- ## ## Main body of script. ## ## -------------------- ## ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu # Provide various options to initialize the Autoconf and configure processes. ac_aux_dir= for ac_dir in build-aux "$srcdir"/build-aux; do if test -f "$ac_dir/install-sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install-sh -c" break elif test -f "$ac_dir/install.sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install.sh -c" break elif test -f "$ac_dir/shtool"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/shtool install -c" break fi done if test -z "$ac_aux_dir"; then as_fn_error $? "cannot find install-sh, install.sh, or shtool in build-aux \"$srcdir\"/build-aux" "$LINENO" 5 fi # These three variables are undocumented and unsupported, # and are intended to be withdrawn in a future Autoconf release. # They can cause serious problems if a builder's source tree is in a directory # whose full name contains unusual characters. ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. ac_config_headers="$ac_config_headers build-aux/config.h" ac_config_files="$ac_config_files Makefile" ac_config_files="$ac_config_files scripts/gtest-config" # Initialize Automake with various options. We require at least v1.9, prevent # pedantic complaints about package files, and enable various distribution # targets. am__api_version='1.11' # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or # incompatible versions: # SysV /etc/install, /usr/sbin/install # SunOS /usr/etc/install # IRIX /sbin/install # AIX /bin/install # AmigaOS /C/install, which installs bootblocks on floppy discs # AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag # AFS /usr/afsws/bin/install, which mishandles nonexistent args # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # OS/2's system install, which has a completely different semantic # ./install, which can be erroneously created by make from ./install.sh. # Reject install programs that cannot install multiple files. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 $as_echo_n "checking for a BSD-compatible install... " >&6; } if test -z "$INSTALL"; then if ${ac_cv_path_install+:} false; then : $as_echo_n "(cached) " >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. # Account for people who put trailing slashes in PATH elements. case $as_dir/ in #(( ./ | .// | /[cC]/* | \ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ /usr/ucb/* ) ;; *) # OSF1 and SCO ODT 3.0 have their own names for install. # Don't use installbsd from OSF since it installs stuff as root # by default. for ac_prog in ginstall scoinst install; do for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then if test $ac_prog = install && grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. : elif test $ac_prog = install && grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # program-specific install script used by HP pwplus--don't use. : else rm -rf conftest.one conftest.two conftest.dir echo one > conftest.one echo two > conftest.two mkdir conftest.dir if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && test -s conftest.one && test -s conftest.two && test -s conftest.dir/conftest.one && test -s conftest.dir/conftest.two then ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" break 3 fi fi fi done done ;; esac done IFS=$as_save_IFS rm -rf conftest.one conftest.two conftest.dir fi if test "${ac_cv_path_install+set}" = set; then INSTALL=$ac_cv_path_install else # As a last resort, use the slow shell script. Don't cache a # value for INSTALL within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. INSTALL=$ac_install_sh fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 $as_echo "$INSTALL" >&6; } # Use test -z because SunOS4 sh mishandles braces in ${var-val}. # It thinks the first close brace ends the variable substitution. test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 $as_echo_n "checking whether build environment is sane... " >&6; } # Just in case sleep 1 echo timestamp > conftest.file # Reject unsafe characters in $srcdir or the absolute working directory # name. Accept space and tab only in the latter. am_lf=' ' case `pwd` in *[\\\"\#\$\&\'\`$am_lf]*) as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;; esac case $srcdir in *[\\\"\#\$\&\'\`$am_lf\ \ ]*) as_fn_error $? "unsafe srcdir value: \`$srcdir'" "$LINENO" 5;; esac # Do `set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` if test "$*" = "X"; then # -L didn't work. set X `ls -t "$srcdir/configure" conftest.file` fi rm -f conftest.file if test "$*" != "X $srcdir/configure conftest.file" \ && test "$*" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". as_fn_error $? "ls -t appears to fail. Make sure there is not a broken alias in your environment" "$LINENO" 5 fi test "$2" = conftest.file ) then # Ok. : else as_fn_error $? "newly created file is older than distributed files! Check your system clock" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } test "$program_prefix" != NONE && program_transform_name="s&^&$program_prefix&;$program_transform_name" # Use a double $ so make ignores it. test "$program_suffix" != NONE && program_transform_name="s&\$&$program_suffix&;$program_transform_name" # Double any \ or $. # By default was `s,x,x', remove it if useless. ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` # expand $ac_aux_dir to an absolute path am_aux_dir=`cd $ac_aux_dir && pwd` if test x"${MISSING+set}" != xset; then case $am_aux_dir in *\ * | *\ *) MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; *) MISSING="\${SHELL} $am_aux_dir/missing" ;; esac fi # Use eval to expand $SHELL if eval "$MISSING --run true"; then am_missing_run="$MISSING --run " else am_missing_run= { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`missing' script is too old or missing" >&5 $as_echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;} fi if test x"${install_sh}" != xset; then case $am_aux_dir in *\ * | *\ *) install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; *) install_sh="\${SHELL} $am_aux_dir/install-sh" esac fi # Installed binaries are usually stripped using `strip' when the user # run `make install-strip'. However `strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the `STRIP' environment variable to overrule this program. if test "$cross_compiling" != no; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. set dummy ${ac_tool_prefix}strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$STRIP"; then ac_cv_prog_STRIP="$STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_STRIP="${ac_tool_prefix}strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi STRIP=$ac_cv_prog_STRIP if test -n "$STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 $as_echo "$STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_STRIP"; then ac_ct_STRIP=$STRIP # Extract the first word of "strip", so it can be a program name with args. set dummy strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_STRIP"; then ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_STRIP="strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP if test -n "$ac_ct_STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 $as_echo "$ac_ct_STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_STRIP" = x; then STRIP=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac STRIP=$ac_ct_STRIP fi else STRIP="$ac_cv_prog_STRIP" fi fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5 $as_echo_n "checking for a thread-safe mkdir -p... " >&6; } if test -z "$MKDIR_P"; then if ${ac_cv_path_mkdir+:} false; then : $as_echo_n "(cached) " >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in mkdir gmkdir; do for ac_exec_ext in '' $ac_executable_extensions; do { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; } || continue case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( 'mkdir (GNU coreutils) '* | \ 'mkdir (coreutils) '* | \ 'mkdir (fileutils) '4.1*) ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext break 3;; esac done done done IFS=$as_save_IFS fi test -d ./--version && rmdir ./--version if test "${ac_cv_path_mkdir+set}" = set; then MKDIR_P="$ac_cv_path_mkdir -p" else # As a last resort, use the slow shell script. Don't cache a # value for MKDIR_P within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. MKDIR_P="$ac_install_sh -d" fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 $as_echo "$MKDIR_P" >&6; } mkdir_p="$MKDIR_P" case $mkdir_p in [\\/$]* | ?:[\\/]*) ;; */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; esac for ac_prog in gawk mawk nawk awk do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_AWK+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$AWK"; then ac_cv_prog_AWK="$AWK" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_AWK="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AWK=$ac_cv_prog_AWK if test -n "$AWK"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 $as_echo "$AWK" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$AWK" && break done { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 $as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } set x ${MAKE-make} ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : $as_echo_n "(cached) " >&6 else cat >conftest.make <<\_ACEOF SHELL = /bin/sh all: @echo '@@@%%%=$(MAKE)=@@@%%%' _ACEOF # GNU make sometimes prints "make[1]: Entering ...", which would confuse us. case `${MAKE-make} -f conftest.make 2>/dev/null` in *@@@%%%=?*=@@@%%%*) eval ac_cv_prog_make_${ac_make}_set=yes;; *) eval ac_cv_prog_make_${ac_make}_set=no;; esac rm -f conftest.make fi if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } SET_MAKE= else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } SET_MAKE="MAKE=${MAKE-make}" fi rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null if test "`cd $srcdir && pwd`" != "`pwd`"; then # Use -I$(srcdir) only when $(srcdir) != ., so that make's output # is not polluted with repeated "-I." am__isrc=' -I$(srcdir)' # test to see if srcdir already configured if test -f $srcdir/config.status; then as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 fi fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi # Define the identity of the package. PACKAGE='gtest' VERSION='1.7.0' cat >>confdefs.h <<_ACEOF #define PACKAGE "$PACKAGE" _ACEOF cat >>confdefs.h <<_ACEOF #define VERSION "$VERSION" _ACEOF # Some tools Automake needs. ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} # We need awk for the "check" target. The system "awk" is bad on # some platforms. # Always define AMTAR for backward compatibility. Yes, it's still used # in the wild :-( We should find a proper way to deprecate it ... AMTAR='$${TAR-tar}' am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -' # Check for programs used in building Google Test. ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="${ac_tool_prefix}gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CC="gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi else CC="$ac_cv_prog_CC" fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="${ac_tool_prefix}cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else ac_prog_rejected=no as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# != 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" fi fi fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then for ac_prog in cl.exe do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$CC" && break done fi if test -z "$CC"; then ac_ct_CC=$CC for ac_prog in cl.exe do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CC="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_CC" && break done if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi fi fi test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "no acceptable C compiler found in \$PATH See \`config.log' for more details" "$LINENO" 5; } # Provide some information about the compiler. $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" # Try to create an executable without -o first, disregard a.out. # It will help us diagnose broken compilers, and finding out an intuition # of exeext. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 $as_echo_n "checking whether the C compiler works... " >&6; } ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` # The possible output files: ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" ac_rmfiles= for ac_file in $ac_files do case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; * ) ac_rmfiles="$ac_rmfiles $ac_file";; esac done rm -f $ac_rmfiles if { { ac_try="$ac_link_default" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link_default") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. # So ignore a value of `no', otherwise this would lead to `EXEEXT = no' # in a Makefile. We should not override ac_cv_exeext if it was cached, # so that the user can short-circuit this test for compilers unknown to # Autoconf. for ac_file in $ac_files '' do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; [ab].out ) # We found the default executable, but exeext='' is most # certainly right. break;; *.* ) if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; then :; else ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` fi # We set ac_cv_exeext here because the later test for it is not # safe: cross compilers may not add the suffix if given an `-o' # argument, so we may need to know it at that point already. # Even if this section looks crufty: it has the advantage of # actually working. break;; * ) break;; esac done test "$ac_cv_exeext" = no && ac_cv_exeext= else ac_file='' fi if test -z "$ac_file"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "C compiler cannot create executables See \`config.log' for more details" "$LINENO" 5; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 $as_echo_n "checking for C compiler default output file name... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 $as_echo "$ac_file" >&6; } ac_exeext=$ac_cv_exeext rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 $as_echo_n "checking for suffix of executables... " >&6; } if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : # If both `conftest.exe' and `conftest' are `present' (well, observable) # catch `conftest.exe'. For instance with Cygwin, `ls conftest' will # work properly (i.e., refer to `conftest.exe'), while it won't with # `rm'. for ac_file in conftest.exe conftest conftest.*; do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` break;; * ) break;; esac done else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of executables: cannot compile and link See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest conftest$ac_cv_exeext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 $as_echo "$ac_cv_exeext" >&6; } rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext ac_exeext=$EXEEXT cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { FILE *f = fopen ("conftest.out", "w"); return ferror (f) || fclose (f) != 0; ; return 0; } _ACEOF ac_clean_files="$ac_clean_files conftest.out" # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 $as_echo_n "checking whether we are cross compiling... " >&6; } if test "$cross_compiling" != yes; then { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if { ac_try='./conftest$ac_cv_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then cross_compiling=no else if test "$cross_compiling" = maybe; then cross_compiling=yes else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details" "$LINENO" 5; } fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 $as_echo "$cross_compiling" >&6; } rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 $as_echo_n "checking for suffix of object files... " >&6; } if ${ac_cv_objext+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.o conftest.obj if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : for ac_file in conftest.o conftest.obj conftest.*; do test -f "$ac_file" || continue; case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` break;; esac done else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of object files: cannot compile See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 $as_echo "$ac_cv_objext" >&6; } OBJEXT=$ac_cv_objext ac_objext=$OBJEXT { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 $as_echo_n "checking whether we are using the GNU C compiler... " >&6; } if ${ac_cv_c_compiler_gnu+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_compiler_gnu=yes else ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 $as_echo "$ac_cv_c_compiler_gnu" >&6; } if test $ac_compiler_gnu = yes; then GCC=yes else GCC= fi ac_test_CFLAGS=${CFLAGS+set} ac_save_CFLAGS=$CFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 $as_echo_n "checking whether $CC accepts -g... " >&6; } if ${ac_cv_prog_cc_g+:} false; then : $as_echo_n "(cached) " >&6 else ac_save_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes ac_cv_prog_cc_g=no CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes else CFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : else ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_c_werror_flag=$ac_save_c_werror_flag fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 $as_echo "$ac_cv_prog_cc_g" >&6; } if test "$ac_test_CFLAGS" = set; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 $as_echo_n "checking for $CC option to accept ISO C89... " >&6; } if ${ac_cv_prog_cc_c89+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_prog_cc_c89=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has function prototypes and stuff, but not '\xHH' hex character constants. These don't provoke an error unfortunately, instead are silently treated as 'x'. The following induces an error, until -std is added to get proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an array size at least. It's necessary to write '\x00'==0 to get something that's true only with -std. */ int osf4_cc_array ['\x00' == 0 ? 1 : -1]; /* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters inside strings and character constants. */ #define FOO(x) 'x' int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); int argc; char **argv; int main () { return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; ; return 0; } _ACEOF for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_c89=$ac_arg fi rm -f core conftest.err conftest.$ac_objext test "x$ac_cv_prog_cc_c89" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi # AC_CACHE_VAL case "x$ac_cv_prog_cc_c89" in x) { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 $as_echo "none needed" >&6; } ;; xno) { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 $as_echo "unsupported" >&6; } ;; *) CC="$CC $ac_cv_prog_cc_c89" { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 $as_echo "$ac_cv_prog_cc_c89" >&6; } ;; esac if test "x$ac_cv_prog_cc_c89" != xno; then : fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu DEPDIR="${am__leading_dot}deps" ac_config_commands="$ac_config_commands depfiles" am_make=${MAKE-make} cat > confinc << 'END' am__doit: @echo this is the am__doit target .PHONY: am__doit END # If we don't find an include directive, just comment out the code. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5 $as_echo_n "checking for style of include used by $am_make... " >&6; } am__include="#" am__quote= _am_result=none # First try GNU make style include. echo "include confinc" > confmf # Ignore all kinds of additional output from `make'. case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=include am__quote= _am_result=GNU ;; esac # Now try BSD make style include. if test "$am__include" = "#"; then echo '.include "confinc"' > confmf case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=.include am__quote="\"" _am_result=BSD ;; esac fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5 $as_echo "$_am_result" >&6; } rm -f confinc confmf # Check whether --enable-dependency-tracking was given. if test "${enable_dependency_tracking+set}" = set; then : enableval=$enable_dependency_tracking; fi if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' am__nodep='_no' fi if test "x$enable_dependency_tracking" != xno; then AMDEP_TRUE= AMDEP_FALSE='#' else AMDEP_TRUE='#' AMDEP_FALSE= fi depcc="$CC" am_compiler_list= { $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 $as_echo_n "checking dependency style of $depcc... " >&6; } if ${am_cv_CC_dependencies_compiler_type+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named `D' -- because `-MD' means `put the output # in D'. rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_CC_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` fi am__universal=false case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with # Solaris 8's {/usr,}/bin/sh. touch sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with `-c' and `-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle `-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # after this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) # This compiler won't grok `-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_CC_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_CC_dependencies_compiler_type=none fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 $as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type if test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then am__fastdepCC_TRUE= am__fastdepCC_FALSE='#' else am__fastdepCC_TRUE='#' am__fastdepCC_FALSE= fi ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu if test -z "$CXX"; then if test -n "$CCC"; then CXX=$CCC else if test -n "$ac_tool_prefix"; then for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CXX+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CXX"; then ac_cv_prog_CXX="$CXX" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CXX=$ac_cv_prog_CXX if test -n "$CXX"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5 $as_echo "$CXX" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$CXX" && break done fi if test -z "$CXX"; then ac_ct_CXX=$CXX for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CXX+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CXX"; then ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CXX="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CXX=$ac_cv_prog_ac_ct_CXX if test -n "$ac_ct_CXX"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5 $as_echo "$ac_ct_CXX" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_CXX" && break done if test "x$ac_ct_CXX" = x; then CXX="g++" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CXX=$ac_ct_CXX fi fi fi fi # Provide some information about the compiler. $as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C++ compiler" >&5 $as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; } if ${ac_cv_cxx_compiler_gnu+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_compiler_gnu=yes else ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_cxx_compiler_gnu=$ac_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5 $as_echo "$ac_cv_cxx_compiler_gnu" >&6; } if test $ac_compiler_gnu = yes; then GXX=yes else GXX= fi ac_test_CXXFLAGS=${CXXFLAGS+set} ac_save_CXXFLAGS=$CXXFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5 $as_echo_n "checking whether $CXX accepts -g... " >&6; } if ${ac_cv_prog_cxx_g+:} false; then : $as_echo_n "(cached) " >&6 else ac_save_cxx_werror_flag=$ac_cxx_werror_flag ac_cxx_werror_flag=yes ac_cv_prog_cxx_g=no CXXFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_cv_prog_cxx_g=yes else CXXFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : else ac_cxx_werror_flag=$ac_save_cxx_werror_flag CXXFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_cv_prog_cxx_g=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cxx_werror_flag=$ac_save_cxx_werror_flag fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5 $as_echo "$ac_cv_prog_cxx_g" >&6; } if test "$ac_test_CXXFLAGS" = set; then CXXFLAGS=$ac_save_CXXFLAGS elif test $ac_cv_prog_cxx_g = yes; then if test "$GXX" = yes; then CXXFLAGS="-g -O2" else CXXFLAGS="-g" fi else if test "$GXX" = yes; then CXXFLAGS="-O2" else CXXFLAGS= fi fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu depcc="$CXX" am_compiler_list= { $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 $as_echo_n "checking dependency style of $depcc... " >&6; } if ${am_cv_CXX_dependencies_compiler_type+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named `D' -- because `-MD' means `put the output # in D'. rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_CXX_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` fi am__universal=false case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with # Solaris 8's {/usr,}/bin/sh. touch sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with `-c' and `-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle `-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # after this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) # This compiler won't grok `-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_CXX_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_CXX_dependencies_compiler_type=none fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CXX_dependencies_compiler_type" >&5 $as_echo "$am_cv_CXX_dependencies_compiler_type" >&6; } CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type if test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then am__fastdepCXX_TRUE= am__fastdepCXX_FALSE='#' else am__fastdepCXX_TRUE='#' am__fastdepCXX_FALSE= fi ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu case `pwd` in *\ * | *\ *) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5 $as_echo "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;; esac macro_version='2.4.2' macro_revision='1.3337' ltmain="$ac_aux_dir/ltmain.sh" # Make sure we can run config.sub. $SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 { $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 $as_echo_n "checking build system type... " >&6; } if ${ac_cv_build+:} false; then : $as_echo_n "(cached) " >&6 else ac_build_alias=$build_alias test "x$ac_build_alias" = x && ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` test "x$ac_build_alias" = x && as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 $as_echo "$ac_cv_build" >&6; } case $ac_cv_build in *-*-*) ;; *) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; esac build=$ac_cv_build ac_save_IFS=$IFS; IFS='-' set x $ac_cv_build shift build_cpu=$1 build_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: build_os=$* IFS=$ac_save_IFS case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 $as_echo_n "checking host system type... " >&6; } if ${ac_cv_host+:} false; then : $as_echo_n "(cached) " >&6 else if test "x$host_alias" = x; then ac_cv_host=$ac_cv_build else ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 $as_echo "$ac_cv_host" >&6; } case $ac_cv_host in *-*-*) ;; *) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; esac host=$ac_cv_host ac_save_IFS=$IFS; IFS='-' set x $ac_cv_host shift host_cpu=$1 host_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: host_os=$* IFS=$ac_save_IFS case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac # Backslashify metacharacters that are still active within # double-quoted strings. sed_quote_subst='s/\(["`$\\]\)/\\\1/g' # Same as above, but do not quote variable references. double_quote_subst='s/\(["`\\]\)/\\\1/g' # Sed substitution to delay expansion of an escaped shell variable in a # double_quote_subst'ed string. delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' # Sed substitution to delay expansion of an escaped single quote. delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' # Sed substitution to avoid accidental globbing in evaled expressions no_glob_subst='s/\*/\\\*/g' ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5 $as_echo_n "checking how to print strings... " >&6; } # Test print first, because it will be a builtin if present. if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='print -r --' elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='printf %s\n' else # Use this function as a fallback that always works. func_fallback_echo () { eval 'cat <<_LTECHO_EOF $1 _LTECHO_EOF' } ECHO='func_fallback_echo' fi # func_echo_all arg... # Invoke $ECHO with all args, space-separated. func_echo_all () { $ECHO "" } case "$ECHO" in printf*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: printf" >&5 $as_echo "printf" >&6; } ;; print*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: print -r" >&5 $as_echo "print -r" >&6; } ;; *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: cat" >&5 $as_echo "cat" >&6; } ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 $as_echo_n "checking for a sed that does not truncate output... " >&6; } if ${ac_cv_path_SED+:} false; then : $as_echo_n "(cached) " >&6 else ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ for ac_i in 1 2 3 4 5 6 7; do ac_script="$ac_script$as_nl$ac_script" done echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed { ac_script=; unset ac_script;} if test -z "$SED"; then ac_path_SED_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in sed gsed; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_SED="$as_dir/$ac_prog$ac_exec_ext" { test -f "$ac_path_SED" && $as_test_x "$ac_path_SED"; } || continue # Check for GNU ac_path_SED and select it if it is found. # Check for GNU $ac_path_SED case `"$ac_path_SED" --version 2>&1` in *GNU*) ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo '' >> "conftest.nl" "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_SED_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_SED="$ac_path_SED" ac_path_SED_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_SED_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_SED"; then as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5 fi else ac_cv_path_SED=$SED fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5 $as_echo "$ac_cv_path_SED" >&6; } SED="$ac_cv_path_SED" rm -f conftest.sed test -z "$SED" && SED=sed Xsed="$SED -e 1s/^X//" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 $as_echo_n "checking for grep that handles long lines and -e... " >&6; } if ${ac_cv_path_GREP+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$GREP"; then ac_path_GREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in grep ggrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue # Check for GNU ac_path_GREP and select it if it is found. # Check for GNU $ac_path_GREP case `"$ac_path_GREP" --version 2>&1` in *GNU*) ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'GREP' >> "conftest.nl" "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_GREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_GREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_GREP"; then as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_GREP=$GREP fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 $as_echo "$ac_cv_path_GREP" >&6; } GREP="$ac_cv_path_GREP" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 $as_echo_n "checking for egrep... " >&6; } if ${ac_cv_path_EGREP+:} false; then : $as_echo_n "(cached) " >&6 else if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 then ac_cv_path_EGREP="$GREP -E" else if test -z "$EGREP"; then ac_path_EGREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in egrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue # Check for GNU ac_path_EGREP and select it if it is found. # Check for GNU $ac_path_EGREP case `"$ac_path_EGREP" --version 2>&1` in *GNU*) ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'EGREP' >> "conftest.nl" "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_EGREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_EGREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_EGREP"; then as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_EGREP=$EGREP fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 $as_echo "$ac_cv_path_EGREP" >&6; } EGREP="$ac_cv_path_EGREP" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5 $as_echo_n "checking for fgrep... " >&6; } if ${ac_cv_path_FGREP+:} false; then : $as_echo_n "(cached) " >&6 else if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1 then ac_cv_path_FGREP="$GREP -F" else if test -z "$FGREP"; then ac_path_FGREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in fgrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext" { test -f "$ac_path_FGREP" && $as_test_x "$ac_path_FGREP"; } || continue # Check for GNU ac_path_FGREP and select it if it is found. # Check for GNU $ac_path_FGREP case `"$ac_path_FGREP" --version 2>&1` in *GNU*) ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'FGREP' >> "conftest.nl" "$ac_path_FGREP" FGREP < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_FGREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_FGREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_FGREP"; then as_fn_error $? "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_FGREP=$FGREP fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5 $as_echo "$ac_cv_path_FGREP" >&6; } FGREP="$ac_cv_path_FGREP" test -z "$GREP" && GREP=grep # Check whether --with-gnu-ld was given. if test "${with_gnu_ld+set}" = set; then : withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes else with_gnu_ld=no fi ac_prog=ld if test "$GCC" = yes; then # Check if gcc -print-prog-name=ld gives a path. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 $as_echo_n "checking for ld used by $CC... " >&6; } case $host in *-*-mingw*) # gcc leaves a trailing carriage return which upsets mingw ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; *) ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; esac case $ac_prog in # Accept absolute paths. [\\/]* | ?:[\\/]*) re_direlt='/[^/][^/]*/\.\./' # Canonicalize the pathname of ld ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` done test -z "$LD" && LD="$ac_prog" ;; "") # If it fails, then pretend we aren't using GCC. ac_prog=ld ;; *) # If it is relative, then search for the first ld in PATH. with_gnu_ld=unknown ;; esac elif test "$with_gnu_ld" = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 $as_echo_n "checking for GNU ld... " >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 $as_echo_n "checking for non-GNU ld... " >&6; } fi if ${lt_cv_path_LD+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$LD"; then lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR for ac_dir in $PATH; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then lt_cv_path_LD="$ac_dir/$ac_prog" # Check to see if the program is GNU ld. I'd rather use --version, # but apparently some variants of GNU ld only accept -v. # Break only if it was the GNU/non-GNU ld that we prefer. case `"$lt_cv_path_LD" -v 2>&1 &5 $as_echo "$LD" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 { $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 $as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } if ${lt_cv_prog_gnu_ld+:} false; then : $as_echo_n "(cached) " >&6 else # I'd rather use --version here, but apparently some GNU lds only accept -v. case `$LD -v 2>&1 &5 $as_echo "$lt_cv_prog_gnu_ld" >&6; } with_gnu_ld=$lt_cv_prog_gnu_ld { $as_echo "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5 $as_echo_n "checking for BSD- or MS-compatible name lister (nm)... " >&6; } if ${lt_cv_path_NM+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$NM"; then # Let the user override the test. lt_cv_path_NM="$NM" else lt_nm_to_check="${ac_tool_prefix}nm" if test -n "$ac_tool_prefix" && test "$build" = "$host"; then lt_nm_to_check="$lt_nm_to_check nm" fi for lt_tmp_nm in $lt_nm_to_check; do lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. tmp_nm="$ac_dir/$lt_tmp_nm" if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then # Check to see if the nm accepts a BSD-compat flag. # Adding the `sed 1q' prevents false positives on HP-UX, which says: # nm: unknown option "B" ignored # Tru64's nm complains that /dev/null is an invalid object file case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in */dev/null* | *'Invalid file or object type'*) lt_cv_path_NM="$tmp_nm -B" break ;; *) case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in */dev/null*) lt_cv_path_NM="$tmp_nm -p" break ;; *) lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but continue # so that we can try to find one that supports BSD flags ;; esac ;; esac fi done IFS="$lt_save_ifs" done : ${lt_cv_path_NM=no} fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5 $as_echo "$lt_cv_path_NM" >&6; } if test "$lt_cv_path_NM" != "no"; then NM="$lt_cv_path_NM" else # Didn't find any BSD compatible name lister, look for dumpbin. if test -n "$DUMPBIN"; then : # Let the user override the test. else if test -n "$ac_tool_prefix"; then for ac_prog in dumpbin "link -dump" do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_DUMPBIN+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$DUMPBIN"; then ac_cv_prog_DUMPBIN="$DUMPBIN" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi DUMPBIN=$ac_cv_prog_DUMPBIN if test -n "$DUMPBIN"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DUMPBIN" >&5 $as_echo "$DUMPBIN" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$DUMPBIN" && break done fi if test -z "$DUMPBIN"; then ac_ct_DUMPBIN=$DUMPBIN for ac_prog in dumpbin "link -dump" do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_DUMPBIN+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_DUMPBIN"; then ac_cv_prog_ac_ct_DUMPBIN="$ac_ct_DUMPBIN" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_DUMPBIN="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN if test -n "$ac_ct_DUMPBIN"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN" >&5 $as_echo "$ac_ct_DUMPBIN" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_DUMPBIN" && break done if test "x$ac_ct_DUMPBIN" = x; then DUMPBIN=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac DUMPBIN=$ac_ct_DUMPBIN fi fi case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in *COFF*) DUMPBIN="$DUMPBIN -symbols" ;; *) DUMPBIN=: ;; esac fi if test "$DUMPBIN" != ":"; then NM="$DUMPBIN" fi fi test -z "$NM" && NM=nm { $as_echo "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5 $as_echo_n "checking the name lister ($NM) interface... " >&6; } if ${lt_cv_nm_interface+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_nm_interface="BSD nm" echo "int some_variable = 0;" > conftest.$ac_ext (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&5) (eval "$ac_compile" 2>conftest.err) cat conftest.err >&5 (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&5) (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) cat conftest.err >&5 (eval echo "\"\$as_me:$LINENO: output\"" >&5) cat conftest.out >&5 if $GREP 'External.*some_variable' conftest.out > /dev/null; then lt_cv_nm_interface="MS dumpbin" fi rm -f conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5 $as_echo "$lt_cv_nm_interface" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5 $as_echo_n "checking whether ln -s works... " >&6; } LN_S=$as_ln_s if test "$LN_S" = "ln -s"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5 $as_echo "no, using $LN_S" >&6; } fi # find the maximum length of command line arguments { $as_echo "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5 $as_echo_n "checking the maximum length of command line arguments... " >&6; } if ${lt_cv_sys_max_cmd_len+:} false; then : $as_echo_n "(cached) " >&6 else i=0 teststring="ABCD" case $build_os in msdosdjgpp*) # On DJGPP, this test can blow up pretty badly due to problems in libc # (any single argument exceeding 2000 bytes causes a buffer overrun # during glob expansion). Even if it were fixed, the result of this # check would be larger than it should be. lt_cv_sys_max_cmd_len=12288; # 12K is about right ;; gnu*) # Under GNU Hurd, this test is not required because there is # no limit to the length of command line arguments. # Libtool will interpret -1 as no limit whatsoever lt_cv_sys_max_cmd_len=-1; ;; cygwin* | mingw* | cegcc*) # On Win9x/ME, this test blows up -- it succeeds, but takes # about 5 minutes as the teststring grows exponentially. # Worse, since 9x/ME are not pre-emptively multitasking, # you end up with a "frozen" computer, even though with patience # the test eventually succeeds (with a max line length of 256k). # Instead, let's just punt: use the minimum linelength reported by # all of the supported platforms: 8192 (on NT/2K/XP). lt_cv_sys_max_cmd_len=8192; ;; mint*) # On MiNT this can take a long time and run out of memory. lt_cv_sys_max_cmd_len=8192; ;; amigaos*) # On AmigaOS with pdksh, this test takes hours, literally. # So we just punt and use a minimum line length of 8192. lt_cv_sys_max_cmd_len=8192; ;; netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) # This has been around since 386BSD, at least. Likely further. if test -x /sbin/sysctl; then lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` elif test -x /usr/sbin/sysctl; then lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` else lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs fi # And add a safety zone lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` ;; interix*) # We know the value 262144 and hardcode it with a safety zone (like BSD) lt_cv_sys_max_cmd_len=196608 ;; os2*) # The test takes a long time on OS/2. lt_cv_sys_max_cmd_len=8192 ;; osf*) # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not # nice to cause kernel panics so lets avoid the loop below. # First set a reasonable default. lt_cv_sys_max_cmd_len=16384 # if test -x /sbin/sysconfig; then case `/sbin/sysconfig -q proc exec_disable_arg_limit` in *1*) lt_cv_sys_max_cmd_len=-1 ;; esac fi ;; sco3.2v5*) lt_cv_sys_max_cmd_len=102400 ;; sysv5* | sco5v6* | sysv4.2uw2*) kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` if test -n "$kargmax"; then lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[ ]//'` else lt_cv_sys_max_cmd_len=32768 fi ;; *) lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` if test -n "$lt_cv_sys_max_cmd_len"; then lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` else # Make teststring a little bigger before we do anything with it. # a 1K string should be a reasonable start. for i in 1 2 3 4 5 6 7 8 ; do teststring=$teststring$teststring done SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} # If test is not a shell built-in, we'll probably end up computing a # maximum length that is only half of the actual maximum length, but # we can't tell. while { test "X"`env echo "$teststring$teststring" 2>/dev/null` \ = "X$teststring$teststring"; } >/dev/null 2>&1 && test $i != 17 # 1/2 MB should be enough do i=`expr $i + 1` teststring=$teststring$teststring done # Only check the string length outside the loop. lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` teststring= # Add a significant safety factor because C++ compilers can tack on # massive amounts of additional arguments before passing them to the # linker. It appears as though 1/2 is a usable value. lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` fi ;; esac fi if test -n $lt_cv_sys_max_cmd_len ; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5 $as_echo "$lt_cv_sys_max_cmd_len" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5 $as_echo "none" >&6; } fi max_cmd_len=$lt_cv_sys_max_cmd_len : ${CP="cp -f"} : ${MV="mv -f"} : ${RM="rm -f"} { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands some XSI constructs" >&5 $as_echo_n "checking whether the shell understands some XSI constructs... " >&6; } # Try some XSI features xsi_shell=no ( _lt_dummy="a/b/c" test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \ = c,a/b,b/c, \ && eval 'test $(( 1 + 1 )) -eq 2 \ && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \ && xsi_shell=yes { $as_echo "$as_me:${as_lineno-$LINENO}: result: $xsi_shell" >&5 $as_echo "$xsi_shell" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands \"+=\"" >&5 $as_echo_n "checking whether the shell understands \"+=\"... " >&6; } lt_shell_append=no ( foo=bar; set foo baz; eval "$1+=\$2" && test "$foo" = barbaz ) \ >/dev/null 2>&1 \ && lt_shell_append=yes { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_shell_append" >&5 $as_echo "$lt_shell_append" >&6; } if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then lt_unset=unset else lt_unset=false fi # test EBCDIC or ASCII case `echo X|tr X '\101'` in A) # ASCII based system # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr lt_SP2NL='tr \040 \012' lt_NL2SP='tr \015\012 \040\040' ;; *) # EBCDIC based system lt_SP2NL='tr \100 \n' lt_NL2SP='tr \r\n \100\100' ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to $host format" >&5 $as_echo_n "checking how to convert $build file names to $host format... " >&6; } if ${lt_cv_to_host_file_cmd+:} false; then : $as_echo_n "(cached) " >&6 else case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 ;; esac ;; *-*-cygwin* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_noop ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin ;; esac ;; * ) # unhandled hosts (and "normal" native builds) lt_cv_to_host_file_cmd=func_convert_file_noop ;; esac fi to_host_file_cmd=$lt_cv_to_host_file_cmd { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_host_file_cmd" >&5 $as_echo "$lt_cv_to_host_file_cmd" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to toolchain format" >&5 $as_echo_n "checking how to convert $build file names to toolchain format... " >&6; } if ${lt_cv_to_tool_file_cmd+:} false; then : $as_echo_n "(cached) " >&6 else #assume ordinary cross tools, or native build. lt_cv_to_tool_file_cmd=func_convert_file_noop case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 ;; esac ;; esac fi to_tool_file_cmd=$lt_cv_to_tool_file_cmd { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_tool_file_cmd" >&5 $as_echo "$lt_cv_to_tool_file_cmd" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5 $as_echo_n "checking for $LD option to reload object files... " >&6; } if ${lt_cv_ld_reload_flag+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_ld_reload_flag='-r' fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag" >&5 $as_echo "$lt_cv_ld_reload_flag" >&6; } reload_flag=$lt_cv_ld_reload_flag case $reload_flag in "" | " "*) ;; *) reload_flag=" $reload_flag" ;; esac reload_cmds='$LD$reload_flag -o $output$reload_objs' case $host_os in cygwin* | mingw* | pw32* | cegcc*) if test "$GCC" != yes; then reload_cmds=false fi ;; darwin*) if test "$GCC" = yes; then reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs' else reload_cmds='$LD$reload_flag -o $output$reload_objs' fi ;; esac if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args. set dummy ${ac_tool_prefix}objdump; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_OBJDUMP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$OBJDUMP"; then ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi OBJDUMP=$ac_cv_prog_OBJDUMP if test -n "$OBJDUMP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5 $as_echo "$OBJDUMP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_OBJDUMP"; then ac_ct_OBJDUMP=$OBJDUMP # Extract the first word of "objdump", so it can be a program name with args. set dummy objdump; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_OBJDUMP"; then ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_OBJDUMP="objdump" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP if test -n "$ac_ct_OBJDUMP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5 $as_echo "$ac_ct_OBJDUMP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_OBJDUMP" = x; then OBJDUMP="false" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac OBJDUMP=$ac_ct_OBJDUMP fi else OBJDUMP="$ac_cv_prog_OBJDUMP" fi test -z "$OBJDUMP" && OBJDUMP=objdump { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5 $as_echo_n "checking how to recognize dependent libraries... " >&6; } if ${lt_cv_deplibs_check_method+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_file_magic_cmd='$MAGIC_CMD' lt_cv_file_magic_test_file= lt_cv_deplibs_check_method='unknown' # Need to set the preceding variable on all platforms that support # interlibrary dependencies. # 'none' -- dependencies not supported. # `unknown' -- same as none, but documents that we really don't know. # 'pass_all' -- all dependencies passed with no checks. # 'test_compile' -- check by making test program. # 'file_magic [[regex]]' -- check by looking for files in library path # which responds to the $file_magic_cmd with a given extended regex. # If you have `file' or equivalent on your system and you're not sure # whether `pass_all' will *always* work, you probably want this one. case $host_os in aix[4-9]*) lt_cv_deplibs_check_method=pass_all ;; beos*) lt_cv_deplibs_check_method=pass_all ;; bsdi[45]*) lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)' lt_cv_file_magic_cmd='/usr/bin/file -L' lt_cv_file_magic_test_file=/shlib/libc.so ;; cygwin*) # func_win32_libid is a shell function defined in ltmain.sh lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' ;; mingw* | pw32*) # Base MSYS/MinGW do not provide the 'file' command needed by # func_win32_libid shell function, so use a weaker test based on 'objdump', # unless we find 'file', for example because we are cross-compiling. # func_win32_libid assumes BSD nm, so disallow it if using MS dumpbin. if ( test "$lt_cv_nm_interface" = "BSD nm" && file / ) >/dev/null 2>&1; then lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' else # Keep this pattern in sync with the one in func_win32_libid. lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' lt_cv_file_magic_cmd='$OBJDUMP -f' fi ;; cegcc*) # use the weaker test based on 'objdump'. See mingw*. lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' lt_cv_file_magic_cmd='$OBJDUMP -f' ;; darwin* | rhapsody*) lt_cv_deplibs_check_method=pass_all ;; freebsd* | dragonfly*) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then case $host_cpu in i*86 ) # Not sure whether the presence of OpenBSD here was a mistake. # Let's accept both of them until this is cleared up. lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library' lt_cv_file_magic_cmd=/usr/bin/file lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` ;; esac else lt_cv_deplibs_check_method=pass_all fi ;; gnu*) lt_cv_deplibs_check_method=pass_all ;; haiku*) lt_cv_deplibs_check_method=pass_all ;; hpux10.20* | hpux11*) lt_cv_file_magic_cmd=/usr/bin/file case $host_cpu in ia64*) lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64' lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so ;; hppa*64*) lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]' lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl ;; *) lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9]\.[0-9]) shared library' lt_cv_file_magic_test_file=/usr/lib/libc.sl ;; esac ;; interix[3-9]*) # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$' ;; irix5* | irix6* | nonstopux*) case $LD in *-32|*"-32 ") libmagic=32-bit;; *-n32|*"-n32 ") libmagic=N32;; *-64|*"-64 ") libmagic=64-bit;; *) libmagic=never-match;; esac lt_cv_deplibs_check_method=pass_all ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu) lt_cv_deplibs_check_method=pass_all ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$' fi ;; newos6*) lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)' lt_cv_file_magic_cmd=/usr/bin/file lt_cv_file_magic_test_file=/usr/lib/libnls.so ;; *nto* | *qnx*) lt_cv_deplibs_check_method=pass_all ;; openbsd*) if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' fi ;; osf3* | osf4* | osf5*) lt_cv_deplibs_check_method=pass_all ;; rdos*) lt_cv_deplibs_check_method=pass_all ;; solaris*) lt_cv_deplibs_check_method=pass_all ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) lt_cv_deplibs_check_method=pass_all ;; sysv4 | sysv4.3*) case $host_vendor in motorola) lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]' lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` ;; ncr) lt_cv_deplibs_check_method=pass_all ;; sequent) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' ;; sni) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib" lt_cv_file_magic_test_file=/lib/libc.so ;; siemens) lt_cv_deplibs_check_method=pass_all ;; pc) lt_cv_deplibs_check_method=pass_all ;; esac ;; tpf*) lt_cv_deplibs_check_method=pass_all ;; esac fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5 $as_echo "$lt_cv_deplibs_check_method" >&6; } file_magic_glob= want_nocaseglob=no if test "$build" = "$host"; then case $host_os in mingw* | pw32*) if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then want_nocaseglob=yes else file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[\1]\/[\1]\/g;/g"` fi ;; esac fi file_magic_cmd=$lt_cv_file_magic_cmd deplibs_check_method=$lt_cv_deplibs_check_method test -z "$deplibs_check_method" && deplibs_check_method=unknown if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args. set dummy ${ac_tool_prefix}dlltool; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_DLLTOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$DLLTOOL"; then ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi DLLTOOL=$ac_cv_prog_DLLTOOL if test -n "$DLLTOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5 $as_echo "$DLLTOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_DLLTOOL"; then ac_ct_DLLTOOL=$DLLTOOL # Extract the first word of "dlltool", so it can be a program name with args. set dummy dlltool; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_DLLTOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_DLLTOOL"; then ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_DLLTOOL="dlltool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL if test -n "$ac_ct_DLLTOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5 $as_echo "$ac_ct_DLLTOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_DLLTOOL" = x; then DLLTOOL="false" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac DLLTOOL=$ac_ct_DLLTOOL fi else DLLTOOL="$ac_cv_prog_DLLTOOL" fi test -z "$DLLTOOL" && DLLTOOL=dlltool { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to associate runtime and link libraries" >&5 $as_echo_n "checking how to associate runtime and link libraries... " >&6; } if ${lt_cv_sharedlib_from_linklib_cmd+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_sharedlib_from_linklib_cmd='unknown' case $host_os in cygwin* | mingw* | pw32* | cegcc*) # two different shell functions defined in ltmain.sh # decide which to use based on capabilities of $DLLTOOL case `$DLLTOOL --help 2>&1` in *--identify-strict*) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib ;; *) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback ;; esac ;; *) # fallback: assume linklib IS sharedlib lt_cv_sharedlib_from_linklib_cmd="$ECHO" ;; esac fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sharedlib_from_linklib_cmd" >&5 $as_echo "$lt_cv_sharedlib_from_linklib_cmd" >&6; } sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO if test -n "$ac_tool_prefix"; then for ac_prog in ar do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_AR+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$AR"; then ac_cv_prog_AR="$AR" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_AR="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AR=$ac_cv_prog_AR if test -n "$AR"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 $as_echo "$AR" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$AR" && break done fi if test -z "$AR"; then ac_ct_AR=$AR for ac_prog in ar do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_AR+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_AR"; then ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_AR="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_AR=$ac_cv_prog_ac_ct_AR if test -n "$ac_ct_AR"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 $as_echo "$ac_ct_AR" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_AR" && break done if test "x$ac_ct_AR" = x; then AR="false" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac AR=$ac_ct_AR fi fi : ${AR=ar} : ${AR_FLAGS=cru} { $as_echo "$as_me:${as_lineno-$LINENO}: checking for archiver @FILE support" >&5 $as_echo_n "checking for archiver @FILE support... " >&6; } if ${lt_cv_ar_at_file+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_ar_at_file=no cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : echo conftest.$ac_objext > conftest.lst lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&5' { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 (eval $lt_ar_try) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if test "$ac_status" -eq 0; then # Ensure the archiver fails upon bogus file names. rm -f conftest.$ac_objext libconftest.a { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 (eval $lt_ar_try) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if test "$ac_status" -ne 0; then lt_cv_ar_at_file=@ fi fi rm -f conftest.* libconftest.a fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ar_at_file" >&5 $as_echo "$lt_cv_ar_at_file" >&6; } if test "x$lt_cv_ar_at_file" = xno; then archiver_list_spec= else archiver_list_spec=$lt_cv_ar_at_file fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. set dummy ${ac_tool_prefix}strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$STRIP"; then ac_cv_prog_STRIP="$STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_STRIP="${ac_tool_prefix}strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi STRIP=$ac_cv_prog_STRIP if test -n "$STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 $as_echo "$STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_STRIP"; then ac_ct_STRIP=$STRIP # Extract the first word of "strip", so it can be a program name with args. set dummy strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_STRIP"; then ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_STRIP="strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP if test -n "$ac_ct_STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 $as_echo "$ac_ct_STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_STRIP" = x; then STRIP=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac STRIP=$ac_ct_STRIP fi else STRIP="$ac_cv_prog_STRIP" fi test -z "$STRIP" && STRIP=: if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. set dummy ${ac_tool_prefix}ranlib; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_RANLIB+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$RANLIB"; then ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi RANLIB=$ac_cv_prog_RANLIB if test -n "$RANLIB"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 $as_echo "$RANLIB" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_RANLIB"; then ac_ct_RANLIB=$RANLIB # Extract the first word of "ranlib", so it can be a program name with args. set dummy ranlib; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_RANLIB+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_RANLIB"; then ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_RANLIB="ranlib" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB if test -n "$ac_ct_RANLIB"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 $as_echo "$ac_ct_RANLIB" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_RANLIB" = x; then RANLIB=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac RANLIB=$ac_ct_RANLIB fi else RANLIB="$ac_cv_prog_RANLIB" fi test -z "$RANLIB" && RANLIB=: # Determine commands to create old-style static archives. old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' old_postinstall_cmds='chmod 644 $oldlib' old_postuninstall_cmds= if test -n "$RANLIB"; then case $host_os in openbsd*) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" ;; *) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" ;; esac old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" fi case $host_os in darwin*) lock_old_archive_extraction=yes ;; *) lock_old_archive_extraction=no ;; esac # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC # Check for command to grab the raw symbol name followed by C symbol from nm. { $as_echo "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5 $as_echo_n "checking command to parse $NM output from $compiler object... " >&6; } if ${lt_cv_sys_global_symbol_pipe+:} false; then : $as_echo_n "(cached) " >&6 else # These are sane defaults that work on at least a few old systems. # [They come from Ultrix. What could be older than Ultrix?!! ;)] # Character class describing NM global symbol codes. symcode='[BCDEGRST]' # Regexp to match symbols that can be accessed directly from C. sympat='\([_A-Za-z][_A-Za-z0-9]*\)' # Define system-specific variables. case $host_os in aix*) symcode='[BCDT]' ;; cygwin* | mingw* | pw32* | cegcc*) symcode='[ABCDGISTW]' ;; hpux*) if test "$host_cpu" = ia64; then symcode='[ABCDEGRST]' fi ;; irix* | nonstopux*) symcode='[BCDEGRST]' ;; osf*) symcode='[BCDEGQRST]' ;; solaris*) symcode='[BDRT]' ;; sco3.2v5*) symcode='[DT]' ;; sysv4.2uw2*) symcode='[DT]' ;; sysv5* | sco5v6* | unixware* | OpenUNIX*) symcode='[ABDT]' ;; sysv4) symcode='[DFNSTU]' ;; esac # If we're using GNU nm, then use its standard symbol codes. case `$NM -V 2>&1` in *GNU* | *'with BFD'*) symcode='[ABCDGIRSTW]' ;; esac # Transform an extracted symbol line into a proper C declaration. # Some systems (esp. on ia64) link data and code symbols differently, # so use this general approach. lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" # Transform an extracted symbol line into symbol name and symbol address lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\)[ ]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"\2\", (void *) \&\2},/p'" lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([^ ]*\)[ ]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \(lib[^ ]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"lib\2\", (void *) \&\2},/p'" # Handle CRLF in mingw tool chain opt_cr= case $build_os in mingw*) opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp ;; esac # Try without a prefix underscore, then with it. for ac_symprfx in "" "_"; do # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. symxfrm="\\1 $ac_symprfx\\2 \\2" # Write the raw and C identifiers. if test "$lt_cv_nm_interface" = "MS dumpbin"; then # Fake it for dumpbin and say T for any non-static function # and D for any global variable. # Also find C++ and __fastcall symbols from MSVC++, # which start with @ or ?. lt_cv_sys_global_symbol_pipe="$AWK '"\ " {last_section=section; section=\$ 3};"\ " /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ " /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ " \$ 0!~/External *\|/{next};"\ " / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ " {if(hide[section]) next};"\ " {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\ " {split(\$ 0, a, /\||\r/); split(a[2], s)};"\ " s[1]~/^[@?]/{print s[1], s[1]; next};"\ " s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\ " ' prfx=^$ac_symprfx" else lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" fi lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" # Check to see that the pipe works correctly. pipe_works=no rm -f conftest* cat > conftest.$ac_ext <<_LT_EOF #ifdef __cplusplus extern "C" { #endif char nm_test_var; void nm_test_func(void); void nm_test_func(void){} #ifdef __cplusplus } #endif int main(){nm_test_var='a';nm_test_func();return(0);} _LT_EOF if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then # Now try to grab the symbols. nlist=conftest.nm if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist\""; } >&5 (eval $NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s "$nlist"; then # Try sorting and uniquifying the output. if sort "$nlist" | uniq > "$nlist"T; then mv -f "$nlist"T "$nlist" else rm -f "$nlist"T fi # Make sure that we snagged all the symbols we need. if $GREP ' nm_test_var$' "$nlist" >/dev/null; then if $GREP ' nm_test_func$' "$nlist" >/dev/null; then cat <<_LT_EOF > conftest.$ac_ext /* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ #if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) /* DATA imports from DLLs on WIN32 con't be const, because runtime relocations are performed -- see ld's documentation on pseudo-relocs. */ # define LT_DLSYM_CONST #elif defined(__osf__) /* This system does not cope well with relocations in const data. */ # define LT_DLSYM_CONST #else # define LT_DLSYM_CONST const #endif #ifdef __cplusplus extern "C" { #endif _LT_EOF # Now generate the symbol file. eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' cat <<_LT_EOF >> conftest.$ac_ext /* The mapping between symbol names and symbols. */ LT_DLSYM_CONST struct { const char *name; void *address; } lt__PROGRAM__LTX_preloaded_symbols[] = { { "@PROGRAM@", (void *) 0 }, _LT_EOF $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext cat <<\_LT_EOF >> conftest.$ac_ext {0, (void *) 0} }; /* This works around a problem in FreeBSD linker */ #ifdef FREEBSD_WORKAROUND static const void *lt_preloaded_setup() { return lt__PROGRAM__LTX_preloaded_symbols; } #endif #ifdef __cplusplus } #endif _LT_EOF # Now try linking the two files. mv conftest.$ac_objext conftstm.$ac_objext lt_globsym_save_LIBS=$LIBS lt_globsym_save_CFLAGS=$CFLAGS LIBS="conftstm.$ac_objext" CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag" if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 (eval $ac_link) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s conftest${ac_exeext}; then pipe_works=yes fi LIBS=$lt_globsym_save_LIBS CFLAGS=$lt_globsym_save_CFLAGS else echo "cannot find nm_test_func in $nlist" >&5 fi else echo "cannot find nm_test_var in $nlist" >&5 fi else echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5 fi else echo "$progname: failed program was:" >&5 cat conftest.$ac_ext >&5 fi rm -rf conftest* conftst* # Do not use the global_symbol_pipe unless it works. if test "$pipe_works" = yes; then break else lt_cv_sys_global_symbol_pipe= fi done fi if test -z "$lt_cv_sys_global_symbol_pipe"; then lt_cv_sys_global_symbol_to_cdecl= fi if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5 $as_echo "failed" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5 $as_echo "ok" >&6; } fi # Response file support. if test "$lt_cv_nm_interface" = "MS dumpbin"; then nm_file_list_spec='@' elif $NM --help 2>/dev/null | grep '[@]FILE' >/dev/null; then nm_file_list_spec='@' fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sysroot" >&5 $as_echo_n "checking for sysroot... " >&6; } # Check whether --with-sysroot was given. if test "${with_sysroot+set}" = set; then : withval=$with_sysroot; else with_sysroot=no fi lt_sysroot= case ${with_sysroot} in #( yes) if test "$GCC" = yes; then lt_sysroot=`$CC --print-sysroot 2>/dev/null` fi ;; #( /*) lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` ;; #( no|'') ;; #( *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${with_sysroot}" >&5 $as_echo "${with_sysroot}" >&6; } as_fn_error $? "The sysroot must be an absolute path." "$LINENO" 5 ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${lt_sysroot:-no}" >&5 $as_echo "${lt_sysroot:-no}" >&6; } # Check whether --enable-libtool-lock was given. if test "${enable_libtool_lock+set}" = set; then : enableval=$enable_libtool_lock; fi test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes # Some flags need to be propagated to the compiler or linker for good # libtool support. case $host in ia64-*-hpux*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then case `/usr/bin/file conftest.$ac_objext` in *ELF-32*) HPUX_IA64_MODE="32" ;; *ELF-64*) HPUX_IA64_MODE="64" ;; esac fi rm -rf conftest* ;; *-*-irix6*) # Find out which ABI we are using. echo '#line '$LINENO' "configure"' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then if test "$lt_cv_prog_gnu_ld" = yes; then case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -melf32bsmip" ;; *N32*) LD="${LD-ld} -melf32bmipn32" ;; *64-bit*) LD="${LD-ld} -melf64bmip" ;; esac else case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -32" ;; *N32*) LD="${LD-ld} -n32" ;; *64-bit*) LD="${LD-ld} -64" ;; esac fi fi rm -rf conftest* ;; x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then case `/usr/bin/file conftest.o` in *32-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_i386_fbsd" ;; x86_64-*linux*) LD="${LD-ld} -m elf_i386" ;; ppc64-*linux*|powerpc64-*linux*) LD="${LD-ld} -m elf32ppclinux" ;; s390x-*linux*) LD="${LD-ld} -m elf_s390" ;; sparc64-*linux*) LD="${LD-ld} -m elf32_sparc" ;; esac ;; *64-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_x86_64_fbsd" ;; x86_64-*linux*) LD="${LD-ld} -m elf_x86_64" ;; ppc*-*linux*|powerpc*-*linux*) LD="${LD-ld} -m elf64ppc" ;; s390*-*linux*|s390*-*tpf*) LD="${LD-ld} -m elf64_s390" ;; sparc*-*linux*) LD="${LD-ld} -m elf64_sparc" ;; esac ;; esac fi rm -rf conftest* ;; *-*-sco3.2v5*) # On SCO OpenServer 5, we need -belf to get full-featured binaries. SAVE_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -belf" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5 $as_echo_n "checking whether the C compiler needs -belf... " >&6; } if ${lt_cv_cc_needs_belf+:} false; then : $as_echo_n "(cached) " >&6 else ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_cv_cc_needs_belf=yes else lt_cv_cc_needs_belf=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5 $as_echo "$lt_cv_cc_needs_belf" >&6; } if test x"$lt_cv_cc_needs_belf" != x"yes"; then # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf CFLAGS="$SAVE_CFLAGS" fi ;; *-*solaris*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then case `/usr/bin/file conftest.o` in *64-bit*) case $lt_cv_prog_gnu_ld in yes*) case $host in i?86-*-solaris*) LD="${LD-ld} -m elf_x86_64" ;; sparc*-*-solaris*) LD="${LD-ld} -m elf64_sparc" ;; esac # GNU ld 2.21 introduced _sol2 emulations. Use them if available. if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then LD="${LD-ld}_sol2" fi ;; *) if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then LD="${LD-ld} -64" fi ;; esac ;; esac fi rm -rf conftest* ;; esac need_locks="$enable_libtool_lock" if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}mt", so it can be a program name with args. set dummy ${ac_tool_prefix}mt; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_MANIFEST_TOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$MANIFEST_TOOL"; then ac_cv_prog_MANIFEST_TOOL="$MANIFEST_TOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_MANIFEST_TOOL="${ac_tool_prefix}mt" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi MANIFEST_TOOL=$ac_cv_prog_MANIFEST_TOOL if test -n "$MANIFEST_TOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MANIFEST_TOOL" >&5 $as_echo "$MANIFEST_TOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_MANIFEST_TOOL"; then ac_ct_MANIFEST_TOOL=$MANIFEST_TOOL # Extract the first word of "mt", so it can be a program name with args. set dummy mt; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_MANIFEST_TOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_MANIFEST_TOOL"; then ac_cv_prog_ac_ct_MANIFEST_TOOL="$ac_ct_MANIFEST_TOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_MANIFEST_TOOL="mt" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_MANIFEST_TOOL=$ac_cv_prog_ac_ct_MANIFEST_TOOL if test -n "$ac_ct_MANIFEST_TOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_MANIFEST_TOOL" >&5 $as_echo "$ac_ct_MANIFEST_TOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_MANIFEST_TOOL" = x; then MANIFEST_TOOL=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac MANIFEST_TOOL=$ac_ct_MANIFEST_TOOL fi else MANIFEST_TOOL="$ac_cv_prog_MANIFEST_TOOL" fi test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $MANIFEST_TOOL is a manifest tool" >&5 $as_echo_n "checking if $MANIFEST_TOOL is a manifest tool... " >&6; } if ${lt_cv_path_mainfest_tool+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_path_mainfest_tool=no echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&5 $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out cat conftest.err >&5 if $GREP 'Manifest Tool' conftest.out > /dev/null; then lt_cv_path_mainfest_tool=yes fi rm -f conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_mainfest_tool" >&5 $as_echo "$lt_cv_path_mainfest_tool" >&6; } if test "x$lt_cv_path_mainfest_tool" != xyes; then MANIFEST_TOOL=: fi case $host_os in rhapsody* | darwin*) if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}dsymutil", so it can be a program name with args. set dummy ${ac_tool_prefix}dsymutil; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_DSYMUTIL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$DSYMUTIL"; then ac_cv_prog_DSYMUTIL="$DSYMUTIL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi DSYMUTIL=$ac_cv_prog_DSYMUTIL if test -n "$DSYMUTIL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL" >&5 $as_echo "$DSYMUTIL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_DSYMUTIL"; then ac_ct_DSYMUTIL=$DSYMUTIL # Extract the first word of "dsymutil", so it can be a program name with args. set dummy dsymutil; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_DSYMUTIL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_DSYMUTIL"; then ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_DSYMUTIL="dsymutil" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL if test -n "$ac_ct_DSYMUTIL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL" >&5 $as_echo "$ac_ct_DSYMUTIL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_DSYMUTIL" = x; then DSYMUTIL=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac DSYMUTIL=$ac_ct_DSYMUTIL fi else DSYMUTIL="$ac_cv_prog_DSYMUTIL" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}nmedit", so it can be a program name with args. set dummy ${ac_tool_prefix}nmedit; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_NMEDIT+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$NMEDIT"; then ac_cv_prog_NMEDIT="$NMEDIT" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi NMEDIT=$ac_cv_prog_NMEDIT if test -n "$NMEDIT"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NMEDIT" >&5 $as_echo "$NMEDIT" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_NMEDIT"; then ac_ct_NMEDIT=$NMEDIT # Extract the first word of "nmedit", so it can be a program name with args. set dummy nmedit; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_NMEDIT+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_NMEDIT"; then ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_NMEDIT="nmedit" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT if test -n "$ac_ct_NMEDIT"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT" >&5 $as_echo "$ac_ct_NMEDIT" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_NMEDIT" = x; then NMEDIT=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac NMEDIT=$ac_ct_NMEDIT fi else NMEDIT="$ac_cv_prog_NMEDIT" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}lipo", so it can be a program name with args. set dummy ${ac_tool_prefix}lipo; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_LIPO+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$LIPO"; then ac_cv_prog_LIPO="$LIPO" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_LIPO="${ac_tool_prefix}lipo" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi LIPO=$ac_cv_prog_LIPO if test -n "$LIPO"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIPO" >&5 $as_echo "$LIPO" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_LIPO"; then ac_ct_LIPO=$LIPO # Extract the first word of "lipo", so it can be a program name with args. set dummy lipo; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_LIPO+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_LIPO"; then ac_cv_prog_ac_ct_LIPO="$ac_ct_LIPO" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_LIPO="lipo" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_LIPO=$ac_cv_prog_ac_ct_LIPO if test -n "$ac_ct_LIPO"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO" >&5 $as_echo "$ac_ct_LIPO" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_LIPO" = x; then LIPO=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac LIPO=$ac_ct_LIPO fi else LIPO="$ac_cv_prog_LIPO" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}otool", so it can be a program name with args. set dummy ${ac_tool_prefix}otool; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_OTOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$OTOOL"; then ac_cv_prog_OTOOL="$OTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_OTOOL="${ac_tool_prefix}otool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi OTOOL=$ac_cv_prog_OTOOL if test -n "$OTOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5 $as_echo "$OTOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_OTOOL"; then ac_ct_OTOOL=$OTOOL # Extract the first word of "otool", so it can be a program name with args. set dummy otool; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_OTOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_OTOOL"; then ac_cv_prog_ac_ct_OTOOL="$ac_ct_OTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_OTOOL="otool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_OTOOL=$ac_cv_prog_ac_ct_OTOOL if test -n "$ac_ct_OTOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL" >&5 $as_echo "$ac_ct_OTOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_OTOOL" = x; then OTOOL=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac OTOOL=$ac_ct_OTOOL fi else OTOOL="$ac_cv_prog_OTOOL" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}otool64", so it can be a program name with args. set dummy ${ac_tool_prefix}otool64; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_OTOOL64+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$OTOOL64"; then ac_cv_prog_OTOOL64="$OTOOL64" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi OTOOL64=$ac_cv_prog_OTOOL64 if test -n "$OTOOL64"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL64" >&5 $as_echo "$OTOOL64" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_OTOOL64"; then ac_ct_OTOOL64=$OTOOL64 # Extract the first word of "otool64", so it can be a program name with args. set dummy otool64; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_OTOOL64+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_OTOOL64"; then ac_cv_prog_ac_ct_OTOOL64="$ac_ct_OTOOL64" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_OTOOL64="otool64" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64 if test -n "$ac_ct_OTOOL64"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64" >&5 $as_echo "$ac_ct_OTOOL64" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_OTOOL64" = x; then OTOOL64=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac OTOOL64=$ac_ct_OTOOL64 fi else OTOOL64="$ac_cv_prog_OTOOL64" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5 $as_echo_n "checking for -single_module linker flag... " >&6; } if ${lt_cv_apple_cc_single_mod+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_apple_cc_single_mod=no if test -z "${LT_MULTI_MODULE}"; then # By default we will add the -single_module flag. You can override # by either setting the environment variable LT_MULTI_MODULE # non-empty at configure time, or by adding -multi_module to the # link flags. rm -rf libconftest.dylib* echo "int foo(void){return 1;}" > conftest.c echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c" >&5 $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c 2>conftest.err _lt_result=$? # If there is a non-empty error log, and "single_module" # appears in it, assume the flag caused a linker warning if test -s conftest.err && $GREP single_module conftest.err; then cat conftest.err >&5 # Otherwise, if the output was created with a 0 exit code from # the compiler, it worked. elif test -f libconftest.dylib && test $_lt_result -eq 0; then lt_cv_apple_cc_single_mod=yes else cat conftest.err >&5 fi rm -rf libconftest.dylib* rm -f conftest.* fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5 $as_echo "$lt_cv_apple_cc_single_mod" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5 $as_echo_n "checking for -exported_symbols_list linker flag... " >&6; } if ${lt_cv_ld_exported_symbols_list+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_ld_exported_symbols_list=no save_LDFLAGS=$LDFLAGS echo "_main" > conftest.sym LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_cv_ld_exported_symbols_list=yes else lt_cv_ld_exported_symbols_list=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LDFLAGS="$save_LDFLAGS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5 $as_echo "$lt_cv_ld_exported_symbols_list" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5 $as_echo_n "checking for -force_load linker flag... " >&6; } if ${lt_cv_ld_force_load+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_ld_force_load=no cat > conftest.c << _LT_EOF int forced_loaded() { return 2;} _LT_EOF echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5 $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5 echo "$AR cru libconftest.a conftest.o" >&5 $AR cru libconftest.a conftest.o 2>&5 echo "$RANLIB libconftest.a" >&5 $RANLIB libconftest.a 2>&5 cat > conftest.c << _LT_EOF int main() { return 0;} _LT_EOF echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&5 $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err _lt_result=$? if test -s conftest.err && $GREP force_load conftest.err; then cat conftest.err >&5 elif test -f conftest && test $_lt_result -eq 0 && $GREP forced_load conftest >/dev/null 2>&1 ; then lt_cv_ld_force_load=yes else cat conftest.err >&5 fi rm -f conftest.err libconftest.a conftest conftest.c rm -rf conftest.dSYM fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5 $as_echo "$lt_cv_ld_force_load" >&6; } case $host_os in rhapsody* | darwin1.[012]) _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; darwin1.*) _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; darwin*) # darwin 5.x on # if running on 10.5 or later, the deployment target defaults # to the OS version, if on x86, and 10.4, the deployment # target defaults to 10.4. Don't you love it? case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in 10.0,*86*-darwin8*|10.0,*-darwin[91]*) _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; 10.[012]*) _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; 10.*) _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; esac ;; esac if test "$lt_cv_apple_cc_single_mod" = "yes"; then _lt_dar_single_mod='$single_module' fi if test "$lt_cv_ld_exported_symbols_list" = "yes"; then _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym' else _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}' fi if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then _lt_dsymutil='~$DSYMUTIL $lib || :' else _lt_dsymutil= fi ;; esac ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 $as_echo_n "checking how to run the C preprocessor... " >&6; } # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then if ${ac_cv_prog_CPP+:} false; then : $as_echo_n "(cached) " >&6 else # Double quotes because CPP needs to be expanded for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" do ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : break fi done ac_cv_prog_CPP=$CPP fi CPP=$ac_cv_prog_CPP else ac_cv_prog_CPP=$CPP fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 $as_echo "$CPP" >&6; } ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details" "$LINENO" 5; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 $as_echo_n "checking for ANSI C header files... " >&6; } if ${ac_cv_header_stdc+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_header_stdc=yes else ac_cv_header_stdc=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "memchr" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "free" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : : else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #if ((' ' & 0x0FF) == 0x020) # define ISLOWER(c) ('a' <= (c) && (c) <= 'z') # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #else # define ISLOWER(c) \ (('a' <= (c) && (c) <= 'i') \ || ('j' <= (c) && (c) <= 'r') \ || ('s' <= (c) && (c) <= 'z')) # define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) #endif #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) return 2; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : else ac_cv_header_stdc=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 $as_echo "$ac_cv_header_stdc" >&6; } if test $ac_cv_header_stdc = yes; then $as_echo "#define STDC_HEADERS 1" >>confdefs.h fi # On IRIX 5.3, sys/types and inttypes.h are conflicting. for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ inttypes.h stdint.h unistd.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default " if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_header in dlfcn.h do : ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default " if test "x$ac_cv_header_dlfcn_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_DLFCN_H 1 _ACEOF fi done func_stripname_cnf () { case ${2} in .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;; *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;; esac } # func_stripname_cnf # Set options enable_dlopen=no enable_win32_dll=no # Check whether --enable-shared was given. if test "${enable_shared+set}" = set; then : enableval=$enable_shared; p=${PACKAGE-default} case $enableval in yes) enable_shared=yes ;; no) enable_shared=no ;; *) enable_shared=no # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for pkg in $enableval; do IFS="$lt_save_ifs" if test "X$pkg" = "X$p"; then enable_shared=yes fi done IFS="$lt_save_ifs" ;; esac else enable_shared=yes fi # Check whether --enable-static was given. if test "${enable_static+set}" = set; then : enableval=$enable_static; p=${PACKAGE-default} case $enableval in yes) enable_static=yes ;; no) enable_static=no ;; *) enable_static=no # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for pkg in $enableval; do IFS="$lt_save_ifs" if test "X$pkg" = "X$p"; then enable_static=yes fi done IFS="$lt_save_ifs" ;; esac else enable_static=yes fi # Check whether --with-pic was given. if test "${with_pic+set}" = set; then : withval=$with_pic; lt_p=${PACKAGE-default} case $withval in yes|no) pic_mode=$withval ;; *) pic_mode=default # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for lt_pkg in $withval; do IFS="$lt_save_ifs" if test "X$lt_pkg" = "X$lt_p"; then pic_mode=yes fi done IFS="$lt_save_ifs" ;; esac else pic_mode=default fi test -z "$pic_mode" && pic_mode=default # Check whether --enable-fast-install was given. if test "${enable_fast_install+set}" = set; then : enableval=$enable_fast_install; p=${PACKAGE-default} case $enableval in yes) enable_fast_install=yes ;; no) enable_fast_install=no ;; *) enable_fast_install=no # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for pkg in $enableval; do IFS="$lt_save_ifs" if test "X$pkg" = "X$p"; then enable_fast_install=yes fi done IFS="$lt_save_ifs" ;; esac else enable_fast_install=yes fi # This can be used to rebuild libtool when needed LIBTOOL_DEPS="$ltmain" # Always use our own libtool. LIBTOOL='$(SHELL) $(top_builddir)/libtool' test -z "$LN_S" && LN_S="ln -s" if test -n "${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5 $as_echo_n "checking for objdir... " >&6; } if ${lt_cv_objdir+:} false; then : $as_echo_n "(cached) " >&6 else rm -f .libs 2>/dev/null mkdir .libs 2>/dev/null if test -d .libs; then lt_cv_objdir=.libs else # MS-DOS does not allow filenames that begin with a dot. lt_cv_objdir=_libs fi rmdir .libs 2>/dev/null fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir" >&5 $as_echo "$lt_cv_objdir" >&6; } objdir=$lt_cv_objdir cat >>confdefs.h <<_ACEOF #define LT_OBJDIR "$lt_cv_objdir/" _ACEOF case $host_os in aix3*) # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test "X${COLLECT_NAMES+set}" != Xset; then COLLECT_NAMES= export COLLECT_NAMES fi ;; esac # Global variables: ofile=libtool can_build_shared=yes # All known linkers require a `.a' archive for static linking (except MSVC, # which needs '.lib'). libext=a with_gnu_ld="$lt_cv_prog_gnu_ld" old_CC="$CC" old_CFLAGS="$CFLAGS" # Set sane defaults for various variables test -z "$CC" && CC=cc test -z "$LTCC" && LTCC=$CC test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS test -z "$LD" && LD=ld test -z "$ac_objext" && ac_objext=o for cc_temp in $compiler""; do case $cc_temp in compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; \-*) ;; *) break;; esac done cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` # Only perform the check for file, if the check method requires it test -z "$MAGIC_CMD" && MAGIC_CMD=file case $deplibs_check_method in file_magic*) if test "$file_magic_cmd" = '$MAGIC_CMD'; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5 $as_echo_n "checking for ${ac_tool_prefix}file... " >&6; } if ${lt_cv_path_MAGIC_CMD+:} false; then : $as_echo_n "(cached) " >&6 else case $MAGIC_CMD in [\\/*] | ?:[\\/]*) lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. ;; *) lt_save_MAGIC_CMD="$MAGIC_CMD" lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" for ac_dir in $ac_dummy; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/${ac_tool_prefix}file; then lt_cv_path_MAGIC_CMD="$ac_dir/${ac_tool_prefix}file" if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then : else cat <<_LT_EOF 1>&2 *** Warning: the command libtool uses to detect shared libraries, *** $file_magic_cmd, produces output that libtool cannot recognize. *** The result is that libtool may fail to recognize shared libraries *** as such. This will affect the creation of libtool libraries that *** depend on shared libraries, but programs linked with such libtool *** libraries will work regardless of this problem. Nevertheless, you *** may want to report the problem to your system manager and/or to *** bug-libtool@gnu.org _LT_EOF fi ;; esac fi break fi done IFS="$lt_save_ifs" MAGIC_CMD="$lt_save_MAGIC_CMD" ;; esac fi MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if test -n "$MAGIC_CMD"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 $as_echo "$MAGIC_CMD" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test -z "$lt_cv_path_MAGIC_CMD"; then if test -n "$ac_tool_prefix"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for file" >&5 $as_echo_n "checking for file... " >&6; } if ${lt_cv_path_MAGIC_CMD+:} false; then : $as_echo_n "(cached) " >&6 else case $MAGIC_CMD in [\\/*] | ?:[\\/]*) lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. ;; *) lt_save_MAGIC_CMD="$MAGIC_CMD" lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" for ac_dir in $ac_dummy; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/file; then lt_cv_path_MAGIC_CMD="$ac_dir/file" if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then : else cat <<_LT_EOF 1>&2 *** Warning: the command libtool uses to detect shared libraries, *** $file_magic_cmd, produces output that libtool cannot recognize. *** The result is that libtool may fail to recognize shared libraries *** as such. This will affect the creation of libtool libraries that *** depend on shared libraries, but programs linked with such libtool *** libraries will work regardless of this problem. Nevertheless, you *** may want to report the problem to your system manager and/or to *** bug-libtool@gnu.org _LT_EOF fi ;; esac fi break fi done IFS="$lt_save_ifs" MAGIC_CMD="$lt_save_MAGIC_CMD" ;; esac fi MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if test -n "$MAGIC_CMD"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 $as_echo "$MAGIC_CMD" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi else MAGIC_CMD=: fi fi fi ;; esac # Use C for the default configuration in the libtool script lt_save_CC="$CC" ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu # Source file extension for C test sources. ac_ext=c # Object file extension for compiled C test sources. objext=o objext=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests lt_simple_link_test_code='int main(){return(0);}' # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC # Save the default compiler, since it gets overwritten when the other # tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. compiler_DEFAULT=$CC # save warnings/boilerplate of simple test code ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" >conftest.$ac_ext eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_compiler_boilerplate=`cat conftest.err` $RM conftest* ac_outfile=conftest.$ac_objext echo "$lt_simple_link_test_code" >conftest.$ac_ext eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_linker_boilerplate=`cat conftest.err` $RM -r conftest* ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... if test -n "$compiler"; then lt_prog_compiler_no_builtin_flag= if test "$GCC" = yes; then case $cc_basename in nvcc*) lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;; *) lt_prog_compiler_no_builtin_flag=' -fno-builtin' ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 $as_echo_n "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; } if ${lt_cv_prog_compiler_rtti_exceptions+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_rtti_exceptions=no ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-fno-rtti -fno-exceptions" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_rtti_exceptions=yes fi fi $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5 $as_echo "$lt_cv_prog_compiler_rtti_exceptions" >&6; } if test x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; then lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions" else : fi fi lt_prog_compiler_wl= lt_prog_compiler_pic= lt_prog_compiler_static= if test "$GCC" = yes; then lt_prog_compiler_wl='-Wl,' lt_prog_compiler_static='-static' case $host_os in aix*) # All AIX code is PIC. if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor lt_prog_compiler_static='-Bstatic' fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support lt_prog_compiler_pic='-fPIC' ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but # adding the `-m68020' flag to GCC prevents building anything better, # like `-m68040'. lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4' ;; esac ;; beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style # (--disable-auto-import) libraries lt_prog_compiler_pic='-DDLL_EXPORT' ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files lt_prog_compiler_pic='-fno-common' ;; haiku*) # PIC is the default for Haiku. # The "-static" flag exists, but is broken. lt_prog_compiler_static= ;; hpux*) # PIC is the default for 64-bit PA HP-UX, but not for 32-bit # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag # sets the default TLS model and affects inlining. case $host_cpu in hppa*64*) # +Z the default ;; *) lt_prog_compiler_pic='-fPIC' ;; esac ;; interix[3-9]*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; msdosdjgpp*) # Just because we use GCC doesn't mean we suddenly get shared libraries # on systems that don't support them. lt_prog_compiler_can_build_shared=no enable_shared=no ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. lt_prog_compiler_pic='-fPIC -shared' ;; sysv4*MP*) if test -d /usr/nec; then lt_prog_compiler_pic=-Kconform_pic fi ;; *) lt_prog_compiler_pic='-fPIC' ;; esac case $cc_basename in nvcc*) # Cuda Compiler Driver 2.2 lt_prog_compiler_wl='-Xlinker ' if test -n "$lt_prog_compiler_pic"; then lt_prog_compiler_pic="-Xcompiler $lt_prog_compiler_pic" fi ;; esac else # PORTME Check for flag to pass linker flags through the system compiler. case $host_os in aix*) lt_prog_compiler_wl='-Wl,' if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor lt_prog_compiler_static='-Bstatic' else lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp' fi ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). lt_prog_compiler_pic='-DDLL_EXPORT' ;; hpux9* | hpux10* | hpux11*) lt_prog_compiler_wl='-Wl,' # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but # not for PA HP-UX. case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) lt_prog_compiler_pic='+Z' ;; esac # Is there a better lt_prog_compiler_static that works with the bundled CC? lt_prog_compiler_static='${wl}-a ${wl}archive' ;; irix5* | irix6* | nonstopux*) lt_prog_compiler_wl='-Wl,' # PIC (with -KPIC) is the default. lt_prog_compiler_static='-non_shared' ;; linux* | k*bsd*-gnu | kopensolaris*-gnu) case $cc_basename in # old Intel for x86_64 which still supported -KPIC. ecc*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-static' ;; # icc used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. icc* | ifort*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fPIC' lt_prog_compiler_static='-static' ;; # Lahey Fortran 8.1. lf95*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='--shared' lt_prog_compiler_static='--static' ;; nagfor*) # NAG Fortran compiler lt_prog_compiler_wl='-Wl,-Wl,,' lt_prog_compiler_pic='-PIC' lt_prog_compiler_static='-Bstatic' ;; pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group compilers (*not* the Pentium gcc compiler, # which looks to be a dead project) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fpic' lt_prog_compiler_static='-Bstatic' ;; ccc*) lt_prog_compiler_wl='-Wl,' # All Alpha code is PIC. lt_prog_compiler_static='-non_shared' ;; xl* | bgxl* | bgf* | mpixl*) # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-qpic' lt_prog_compiler_static='-qstaticlink' ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [1-7].* | *Sun*Fortran*\ 8.[0-3]*) # Sun Fortran 8.3 passes all unrecognized flags to the linker lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' lt_prog_compiler_wl='' ;; *Sun\ F* | *Sun*Fortran*) lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' lt_prog_compiler_wl='-Qoption ld ' ;; *Sun\ C*) # Sun C 5.9 lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' lt_prog_compiler_wl='-Wl,' ;; *Intel*\ [CF]*Compiler*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fPIC' lt_prog_compiler_static='-static' ;; *Portland\ Group*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fpic' lt_prog_compiler_static='-Bstatic' ;; esac ;; esac ;; newsos6) lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. lt_prog_compiler_pic='-fPIC -shared' ;; osf3* | osf4* | osf5*) lt_prog_compiler_wl='-Wl,' # All OSF/1 code is PIC. lt_prog_compiler_static='-non_shared' ;; rdos*) lt_prog_compiler_static='-non_shared' ;; solaris*) lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' case $cc_basename in f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) lt_prog_compiler_wl='-Qoption ld ';; *) lt_prog_compiler_wl='-Wl,';; esac ;; sunos4*) lt_prog_compiler_wl='-Qoption ld ' lt_prog_compiler_pic='-PIC' lt_prog_compiler_static='-Bstatic' ;; sysv4 | sysv4.2uw2* | sysv4.3*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' ;; sysv4*MP*) if test -d /usr/nec ;then lt_prog_compiler_pic='-Kconform_pic' lt_prog_compiler_static='-Bstatic' fi ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' ;; unicos*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_can_build_shared=no ;; uts4*) lt_prog_compiler_pic='-pic' lt_prog_compiler_static='-Bstatic' ;; *) lt_prog_compiler_can_build_shared=no ;; esac fi case $host_os in # For platforms which do not support PIC, -DPIC is meaningless: *djgpp*) lt_prog_compiler_pic= ;; *) lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC" ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 $as_echo_n "checking for $compiler option to produce PIC... " >&6; } if ${lt_cv_prog_compiler_pic+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_pic=$lt_prog_compiler_pic fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic" >&5 $as_echo "$lt_cv_prog_compiler_pic" >&6; } lt_prog_compiler_pic=$lt_cv_prog_compiler_pic # # Check to make sure the PIC flag actually works. # if test -n "$lt_prog_compiler_pic"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5 $as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; } if ${lt_cv_prog_compiler_pic_works+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_pic_works=no ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="$lt_prog_compiler_pic -DPIC" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_pic_works=yes fi fi $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5 $as_echo "$lt_cv_prog_compiler_pic_works" >&6; } if test x"$lt_cv_prog_compiler_pic_works" = xyes; then case $lt_prog_compiler_pic in "" | " "*) ;; *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;; esac else lt_prog_compiler_pic= lt_prog_compiler_can_build_shared=no fi fi # # Check to make sure the static flag actually works. # wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\" { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 $as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } if ${lt_cv_prog_compiler_static_works+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_static_works=no save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS $lt_tmp_static_flag" echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then # The linker can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&5 $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_static_works=yes fi else lt_cv_prog_compiler_static_works=yes fi fi $RM -r conftest* LDFLAGS="$save_LDFLAGS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5 $as_echo "$lt_cv_prog_compiler_static_works" >&6; } if test x"$lt_cv_prog_compiler_static_works" = xyes; then : else lt_prog_compiler_static= fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 $as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } if ${lt_cv_prog_compiler_c_o+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_c_o=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then lt_cv_prog_compiler_c_o=yes fi fi chmod u+w . 2>&5 $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 $as_echo "$lt_cv_prog_compiler_c_o" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 $as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } if ${lt_cv_prog_compiler_c_o+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_c_o=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then lt_cv_prog_compiler_c_o=yes fi fi chmod u+w . 2>&5 $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 $as_echo "$lt_cv_prog_compiler_c_o" >&6; } hard_links="nottested" if test "$lt_cv_prog_compiler_c_o" = no && test "$need_locks" != no; then # do not overwrite the value of need_locks provided by the user { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 $as_echo_n "checking if we can lock with hard links... " >&6; } hard_links=yes $RM conftest* ln conftest.a conftest.b 2>/dev/null && hard_links=no touch conftest.a ln conftest.a conftest.b 2>&5 || hard_links=no ln conftest.a conftest.b 2>/dev/null && hard_links=no { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 $as_echo "$hard_links" >&6; } if test "$hard_links" = no; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 $as_echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} need_locks=warn fi else need_locks=no fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 $as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } runpath_var= allow_undefined_flag= always_export_symbols=no archive_cmds= archive_expsym_cmds= compiler_needs_object=no enable_shared_with_static_runtimes=no export_dynamic_flag_spec= export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' hardcode_automatic=no hardcode_direct=no hardcode_direct_absolute=no hardcode_libdir_flag_spec= hardcode_libdir_separator= hardcode_minus_L=no hardcode_shlibpath_var=unsupported inherit_rpath=no link_all_deplibs=unknown module_cmds= module_expsym_cmds= old_archive_from_new_cmds= old_archive_from_expsyms_cmds= thread_safe_flag_spec= whole_archive_flag_spec= # include_expsyms should be a list of space-separated symbols to be *always* # included in the symbol list include_expsyms= # exclude_expsyms can be an extended regexp of symbols to exclude # it will be wrapped by ` (' and `)$', so one must not match beginning or # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', # as well as any symbol that contains `d'. exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out # platforms (ab)use it in PIC code, but their linkers get confused if # the symbol is explicitly referenced. Since portable code cannot # rely on this symbol name, it's probably fine to never include it in # preloaded symbol tables. # Exclude shared library initialization/finalization symbols. extract_expsyms_cmds= case $host_os in cygwin* | mingw* | pw32* | cegcc*) # FIXME: the MSVC++ port hasn't been tested in a loooong time # When not using gcc, we currently assume that we are using # Microsoft Visual C++. if test "$GCC" != yes; then with_gnu_ld=no fi ;; interix*) # we just hope/assume this is gcc and not c89 (= MSVC++) with_gnu_ld=yes ;; openbsd*) with_gnu_ld=no ;; linux* | k*bsd*-gnu | gnu*) link_all_deplibs=no ;; esac ld_shlibs=yes # On some targets, GNU ld is compatible enough with the native linker # that we're better off using the native interface for both. lt_use_gnu_ld_interface=no if test "$with_gnu_ld" = yes; then case $host_os in aix*) # The AIX port of GNU ld has always aspired to compatibility # with the native linker. However, as the warning in the GNU ld # block says, versions before 2.19.5* couldn't really create working # shared libraries, regardless of the interface used. case `$LD -v 2>&1` in *\ \(GNU\ Binutils\)\ 2.19.5*) ;; *\ \(GNU\ Binutils\)\ 2.[2-9]*) ;; *\ \(GNU\ Binutils\)\ [3-9]*) ;; *) lt_use_gnu_ld_interface=yes ;; esac ;; *) lt_use_gnu_ld_interface=yes ;; esac fi if test "$lt_use_gnu_ld_interface" = yes; then # If archive_cmds runs LD, not CC, wlarc should be empty wlarc='${wl}' # Set some defaults for GNU ld with shared library support. These # are reset later if shared libraries are not supported. Putting them # here allows them to be overridden if necessary. runpath_var=LD_RUN_PATH hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' export_dynamic_flag_spec='${wl}--export-dynamic' # ancient GNU ld didn't support --whole-archive et. al. if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' else whole_archive_flag_spec= fi supports_anon_versioning=no case `$LD -v 2>&1` in *GNU\ gold*) supports_anon_versioning=yes ;; *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... *\ 2.11.*) ;; # other 2.11 versions *) supports_anon_versioning=yes ;; esac # See if GNU ld supports shared libraries. case $host_os in aix[3-9]*) # On AIX/PPC, the GNU linker is very broken if test "$host_cpu" != ia64; then ld_shlibs=no cat <<_LT_EOF 1>&2 *** Warning: the GNU linker, at least up to release 2.19, is reported *** to be unable to reliably create shared libraries on AIX. *** Therefore, libtool is disabling shared libraries support. If you *** really care for shared libraries, you may want to install binutils *** 2.20 or above, or modify your PATH so that a non-GNU linker is found. *** You will then need to restart the configuration process. _LT_EOF fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds='' ;; m68k) archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes ;; esac ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then allow_undefined_flag=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' else ld_shlibs=no fi ;; cygwin* | mingw* | pw32* | cegcc*) # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless, # as there is no search path for DLLs. hardcode_libdir_flag_spec='-L$libdir' export_dynamic_flag_spec='${wl}--export-all-symbols' allow_undefined_flag=unsupported always_export_symbols=no enable_shared_with_static_runtimes=yes export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols' exclude_expsyms='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname' if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file (1st line # is EXPORTS), use it as is; otherwise, prepend... archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else ld_shlibs=no fi ;; haiku*) archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' link_all_deplibs=yes ;; interix[3-9]*) hardcode_direct=no hardcode_shlibpath_var=no hardcode_libdir_flag_spec='${wl}-rpath,$libdir' export_dynamic_flag_spec='${wl}-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' archive_expsym_cmds='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) tmp_diet=no if test "$host_os" = linux-dietlibc; then case $cc_basename in diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) esac fi if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ && test "$tmp_diet" = no then tmp_addflag=' $pic_flag' tmp_sharedflag='-shared' case $cc_basename,$host_cpu in pgcc*) # Portland Group C compiler whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' tmp_addflag=' $pic_flag' ;; pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group f77 and f90 compilers whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' tmp_addflag=' $pic_flag -Mnomain' ;; ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 tmp_addflag=' -i_dynamic' ;; efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 tmp_addflag=' -i_dynamic -nofor_main' ;; ifc* | ifort*) # Intel Fortran compiler tmp_addflag=' -nofor_main' ;; lf95*) # Lahey Fortran 8.1 whole_archive_flag_spec= tmp_sharedflag='--shared' ;; xl[cC]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below) tmp_sharedflag='-qmkshrobj' tmp_addflag= ;; nvcc*) # Cuda Compiler Driver 2.2 whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' compiler_needs_object=yes ;; esac case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C 5.9 whole_archive_flag_spec='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' compiler_needs_object=yes tmp_sharedflag='-G' ;; *Sun\ F*) # Sun Fortran 8.3 tmp_sharedflag='-G' ;; esac archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' if test "x$supports_anon_versioning" = xyes; then archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' fi case $cc_basename in xlf* | bgf* | bgxlf* | mpixlf*) # IBM XL Fortran 10.1 on PPC cannot create shared libs itself whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive' hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' if test "x$supports_anon_versioning" = xyes; then archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' fi ;; esac else ld_shlibs=no fi ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' wlarc= else archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' fi ;; solaris*) if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then ld_shlibs=no cat <<_LT_EOF 1>&2 *** Warning: The releases 2.8.* of the GNU linker cannot reliably *** create shared libraries on Solaris systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.9.1 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs=no fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) case `$LD -v 2>&1` in *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) ld_shlibs=no cat <<_LT_EOF 1>&2 *** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not *** reliably create shared libraries on SCO systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.16.91.0.3 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF ;; *) # For security reasons, it is highly recommended that you always # use absolute paths for naming shared libraries, and exclude the # DT_RUNPATH tag from executables and libraries. But doing so # requires that you compile everything twice, which is a pain. if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs=no fi ;; esac ;; sunos4*) archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' wlarc= hardcode_direct=yes hardcode_shlibpath_var=no ;; *) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs=no fi ;; esac if test "$ld_shlibs" = no; then runpath_var= hardcode_libdir_flag_spec= export_dynamic_flag_spec= whole_archive_flag_spec= fi else # PORTME fill in a description of your system's linker (not GNU ld) case $host_os in aix3*) allow_undefined_flag=unsupported always_export_symbols=yes archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' # Note: this linker hardcodes the directories in LIBPATH if there # are no directories specified by -L. hardcode_minus_L=yes if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then # Neither direct hardcoding nor static linking is supported with a # broken collect2. hardcode_direct=unsupported fi ;; aix[4-9]*) if test "$host_cpu" = ia64; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag="" else # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to AIX nm, but means don't demangle with GNU nm # Also, AIX nm treats weak defined symbols like other global # defined symbols, whereas GNU nm marks them as "W". if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' else export_symbols_cmds='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' fi aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # need to do runtime linking. case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) for ld_flag in $LDFLAGS; do if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then aix_use_runtimelinking=yes break fi done ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. archive_cmds='' hardcode_direct=yes hardcode_direct_absolute=yes hardcode_libdir_separator=':' link_all_deplibs=yes file_list_spec='${wl}-f,' if test "$GCC" = yes; then case $host_os in aix4.[012]|aix4.[012].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`${CC} -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then # We have reworked collect2 : else # We have old collect2 hardcode_direct=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking hardcode_minus_L=yes hardcode_libdir_flag_spec='-L$libdir' hardcode_libdir_separator= fi ;; esac shared_flag='-shared' if test "$aix_use_runtimelinking" = yes; then shared_flag="$shared_flag "'${wl}-G' fi link_all_deplibs=no else # not using gcc if test "$host_cpu" = ia64; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test "$aix_use_runtimelinking" = yes; then shared_flag='${wl}-G' else shared_flag='${wl}-bM:SRE' fi fi fi export_dynamic_flag_spec='${wl}-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to export. always_export_symbols=yes if test "$aix_use_runtimelinking" = yes; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. allow_undefined_flag='-berok' # Determine the default libpath from the value encoded in an # empty executable. if test "${lt_cv_aix_libpath+set}" = set; then aix_libpath=$lt_cv_aix_libpath else if ${lt_cv_aix_libpath_+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_aix_libpath_sed=' /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }' lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_="/usr/lib:/lib" fi fi aix_libpath=$lt_cv_aix_libpath_ fi hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" else if test "$host_cpu" = ia64; then hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib' allow_undefined_flag="-z nodefs" archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. if test "${lt_cv_aix_libpath+set}" = set; then aix_libpath=$lt_cv_aix_libpath else if ${lt_cv_aix_libpath_+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_aix_libpath_sed=' /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }' lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_="/usr/lib:/lib" fi fi aix_libpath=$lt_cv_aix_libpath_ fi hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. no_undefined_flag=' ${wl}-bernotok' allow_undefined_flag=' ${wl}-berok' if test "$with_gnu_ld" = yes; then # We only use this code for GNU lds that support --whole-archive. whole_archive_flag_spec='${wl}--whole-archive$convenience ${wl}--no-whole-archive' else # Exported symbols can be pulled into shared objects from archives whole_archive_flag_spec='$convenience' fi archive_cmds_need_lc=yes # This is similar to how AIX traditionally builds its shared libraries. archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' fi fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds='' ;; m68k) archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes ;; esac ;; bsdi[45]*) export_dynamic_flag_spec=-rdynamic ;; cygwin* | mingw* | pw32* | cegcc*) # When not using gcc, we currently assume that we are using # Microsoft Visual C++. # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. case $cc_basename in cl*) # Native MSVC hardcode_libdir_flag_spec=' ' allow_undefined_flag=unsupported always_export_symbols=yes file_list_spec='@' # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=".dll" # FIXME: Setting linknames here is a bad hack. archive_cmds='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; else sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; fi~ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, )='true' enable_shared_with_static_runtimes=yes exclude_expsyms='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1,DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols' # Don't use ranlib old_postinstall_cmds='chmod 644 $oldlib' postlink_cmds='lt_outputfile="@OUTPUT@"~ lt_tool_outputfile="@TOOL_OUTPUT@"~ case $lt_outputfile in *.exe|*.EXE) ;; *) lt_outputfile="$lt_outputfile.exe" lt_tool_outputfile="$lt_tool_outputfile.exe" ;; esac~ if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; $RM "$lt_outputfile.manifest"; fi' ;; *) # Assume MSVC wrapper hardcode_libdir_flag_spec=' ' allow_undefined_flag=unsupported # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=".dll" # FIXME: Setting linknames here is a bad hack. archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' # The linker will automatically build a .lib file if we build a DLL. old_archive_from_new_cmds='true' # FIXME: Should let the user specify the lib program. old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs' enable_shared_with_static_runtimes=yes ;; esac ;; darwin* | rhapsody*) archive_cmds_need_lc=no hardcode_direct=no hardcode_automatic=yes hardcode_shlibpath_var=unsupported if test "$lt_cv_ld_force_load" = "yes"; then whole_archive_flag_spec='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' else whole_archive_flag_spec='' fi link_all_deplibs=yes allow_undefined_flag="$_lt_dar_allow_undefined" case $cc_basename in ifort*) _lt_dar_can_shared=yes ;; *) _lt_dar_can_shared=$GCC ;; esac if test "$_lt_dar_can_shared" = "yes"; then output_verbose_link_cmd=func_echo_all archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" else ld_shlibs=no fi ;; dgux*) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_libdir_flag_spec='-L$libdir' hardcode_shlibpath_var=no ;; # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor # support. Future versions do this automatically, but an explicit c++rt0.o # does not break anything, and helps significantly (at the cost of a little # extra space). freebsd2.2*) archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes hardcode_shlibpath_var=no ;; # Unfortunately, older versions of FreeBSD 2 do not have this feature. freebsd2.*) archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=yes hardcode_minus_L=yes hardcode_shlibpath_var=no ;; # FreeBSD 3 and greater uses gcc -shared to do shared libraries. freebsd* | dragonfly*) archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes hardcode_shlibpath_var=no ;; hpux9*) if test "$GCC" = yes; then archive_cmds='$RM $output_objdir/$soname~$CC -shared $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' else archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' fi hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' hardcode_libdir_separator=: hardcode_direct=yes # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes export_dynamic_flag_spec='${wl}-E' ;; hpux10*) if test "$GCC" = yes && test "$with_gnu_ld" = no; then archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' fi if test "$with_gnu_ld" = no; then hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' hardcode_libdir_separator=: hardcode_direct=yes hardcode_direct_absolute=yes export_dynamic_flag_spec='${wl}-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes fi ;; hpux11*) if test "$GCC" = yes && test "$with_gnu_ld" = no; then case $host_cpu in hppa*64*) archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ;; esac else case $host_cpu in hppa*64*) archive_cmds='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) # Older versions of the 11.00 compiler do not understand -b yet # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC understands -b" >&5 $as_echo_n "checking if $CC understands -b... " >&6; } if ${lt_cv_prog_compiler__b+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler__b=no save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS -b" echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then # The linker can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&5 $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler__b=yes fi else lt_cv_prog_compiler__b=yes fi fi $RM -r conftest* LDFLAGS="$save_LDFLAGS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5 $as_echo "$lt_cv_prog_compiler__b" >&6; } if test x"$lt_cv_prog_compiler__b" = xyes; then archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' fi ;; esac fi if test "$with_gnu_ld" = no; then hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' hardcode_libdir_separator=: case $host_cpu in hppa*64*|ia64*) hardcode_direct=no hardcode_shlibpath_var=no ;; *) hardcode_direct=yes hardcode_direct_absolute=yes export_dynamic_flag_spec='${wl}-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes ;; esac fi ;; irix5* | irix6* | nonstopux*) if test "$GCC" = yes; then archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' # Try to use the -exported_symbol ld option, if it does not # work, assume that -exports_file does not work either and # implicitly export all symbols. # This should be the same for all languages, so no per-tag cache variable. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $host_os linker accepts -exported_symbol" >&5 $as_echo_n "checking whether the $host_os linker accepts -exported_symbol... " >&6; } if ${lt_cv_irix_exported_symbol+:} false; then : $as_echo_n "(cached) " >&6 else save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int foo (void) { return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_cv_irix_exported_symbol=yes else lt_cv_irix_exported_symbol=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LDFLAGS="$save_LDFLAGS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_irix_exported_symbol" >&5 $as_echo "$lt_cv_irix_exported_symbol" >&6; } if test "$lt_cv_irix_exported_symbol" = yes; then archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' fi else archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib' fi archive_cmds_need_lc='no' hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator=: inherit_rpath=yes link_all_deplibs=yes ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out else archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF fi hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes hardcode_shlibpath_var=no ;; newsos6) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=yes hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator=: hardcode_shlibpath_var=no ;; *nto* | *qnx*) ;; openbsd*) if test -f /usr/libexec/ld.so; then hardcode_direct=yes hardcode_shlibpath_var=no hardcode_direct_absolute=yes if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' hardcode_libdir_flag_spec='${wl}-rpath,$libdir' export_dynamic_flag_spec='${wl}-E' else case $host_os in openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' hardcode_libdir_flag_spec='-R$libdir' ;; *) archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' hardcode_libdir_flag_spec='${wl}-rpath,$libdir' ;; esac fi else ld_shlibs=no fi ;; os2*) hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes allow_undefined_flag=unsupported archive_cmds='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' old_archive_from_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' ;; osf3*) if test "$GCC" = yes; then allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' else allow_undefined_flag=' -expect_unresolved \*' archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' fi archive_cmds_need_lc='no' hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator=: ;; osf4* | osf5*) # as osf3* with the addition of -msym flag if test "$GCC" = yes; then allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' archive_cmds='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' else allow_undefined_flag=' -expect_unresolved \*' archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp' # Both c and cxx compiler support -rpath directly hardcode_libdir_flag_spec='-rpath $libdir' fi archive_cmds_need_lc='no' hardcode_libdir_separator=: ;; solaris*) no_undefined_flag=' -z defs' if test "$GCC" = yes; then wlarc='${wl}' archive_cmds='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' else case `$CC -V 2>&1` in *"Compilers 5.0"*) wlarc='' archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' ;; *) wlarc='${wl}' archive_cmds='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' ;; esac fi hardcode_libdir_flag_spec='-R$libdir' hardcode_shlibpath_var=no case $host_os in solaris2.[0-5] | solaris2.[0-5].*) ;; *) # The compiler driver will combine and reorder linker options, # but understands `-z linker_flag'. GCC discards it without `$wl', # but is careful enough not to reorder. # Supported since Solaris 2.6 (maybe 2.5.1?) if test "$GCC" = yes; then whole_archive_flag_spec='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' else whole_archive_flag_spec='-z allextract$convenience -z defaultextract' fi ;; esac link_all_deplibs=yes ;; sunos4*) if test "x$host_vendor" = xsequent; then # Use $CC to link under sequent, because it throws in some extra .o # files that make .init and .fini sections work. archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' fi hardcode_libdir_flag_spec='-L$libdir' hardcode_direct=yes hardcode_minus_L=yes hardcode_shlibpath_var=no ;; sysv4) case $host_vendor in sni) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=yes # is this really true??? ;; siemens) ## LD is ld it makes a PLAMLIB ## CC just makes a GrossModule. archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' reload_cmds='$CC -r -o $output$reload_objs' hardcode_direct=no ;; motorola) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=no #Motorola manual says yes, but my tests say they lie ;; esac runpath_var='LD_RUN_PATH' hardcode_shlibpath_var=no ;; sysv4.3*) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_shlibpath_var=no export_dynamic_flag_spec='-Bexport' ;; sysv4*MP*) if test -d /usr/nec; then archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_shlibpath_var=no runpath_var=LD_RUN_PATH hardcode_runpath_var=yes ld_shlibs=yes fi ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) no_undefined_flag='${wl}-z,text' archive_cmds_need_lc=no hardcode_shlibpath_var=no runpath_var='LD_RUN_PATH' if test "$GCC" = yes; then archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We can NOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. no_undefined_flag='${wl}-z,text' allow_undefined_flag='${wl}-z,nodefs' archive_cmds_need_lc=no hardcode_shlibpath_var=no hardcode_libdir_flag_spec='${wl}-R,$libdir' hardcode_libdir_separator=':' link_all_deplibs=yes export_dynamic_flag_spec='${wl}-Bexport' runpath_var='LD_RUN_PATH' if test "$GCC" = yes; then archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; uts4*) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_libdir_flag_spec='-L$libdir' hardcode_shlibpath_var=no ;; *) ld_shlibs=no ;; esac if test x$host_vendor = xsni; then case $host in sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) export_dynamic_flag_spec='${wl}-Blargedynsym' ;; esac fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5 $as_echo "$ld_shlibs" >&6; } test "$ld_shlibs" = no && can_build_shared=no with_gnu_ld=$with_gnu_ld # # Do we need to explicitly link libc? # case "x$archive_cmds_need_lc" in x|xyes) # Assume -lc should be added archive_cmds_need_lc=yes if test "$enable_shared" = yes && test "$GCC" = yes; then case $archive_cmds in *'~'*) # FIXME: we may have to deal with multi-command sequences. ;; '$CC '*) # Test whether the compiler implicitly links with -lc since on some # systems, -lgcc has to come before -lc. If gcc already passes -lc # to ld, don't add -lc before -lgcc. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 $as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } if ${lt_cv_archive_cmds_need_lc+:} false; then : $as_echo_n "(cached) " >&6 else $RM conftest* echo "$lt_simple_compile_test_code" > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } 2>conftest.err; then soname=conftest lib=conftest libobjs=conftest.$ac_objext deplibs= wl=$lt_prog_compiler_wl pic_flag=$lt_prog_compiler_pic compiler_flags=-v linker_flags=-v verstring= output_objdir=. libname=conftest lt_save_allow_undefined_flag=$allow_undefined_flag allow_undefined_flag= if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } then lt_cv_archive_cmds_need_lc=no else lt_cv_archive_cmds_need_lc=yes fi allow_undefined_flag=$lt_save_allow_undefined_flag else cat conftest.err 1>&5 fi $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc" >&5 $as_echo "$lt_cv_archive_cmds_need_lc" >&6; } archive_cmds_need_lc=$lt_cv_archive_cmds_need_lc ;; esac fi ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 $as_echo_n "checking dynamic linker characteristics... " >&6; } if test "$GCC" = yes; then case $host_os in darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; *) lt_awk_arg="/^libraries:/" ;; esac case $host_os in mingw* | cegcc*) lt_sed_strip_eq="s,=\([A-Za-z]:\),\1,g" ;; *) lt_sed_strip_eq="s,=/,/,g" ;; esac lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` case $lt_search_path_spec in *\;*) # if the path contains ";" then we assume it to be the separator # otherwise default to the standard path separator (i.e. ":") - it is # assumed that no part of a normal pathname contains ";" but that should # okay in the real world where ";" in dirpaths is itself problematic. lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` ;; *) lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` ;; esac # Ok, now we have the path, separated by spaces, we can step through it # and add multilib dir if necessary. lt_tmp_lt_search_path_spec= lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` for lt_sys_path in $lt_search_path_spec; do if test -d "$lt_sys_path/$lt_multi_os_dir"; then lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir" else test -d "$lt_sys_path" && \ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" fi done lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' BEGIN {RS=" "; FS="/|\n";} { lt_foo=""; lt_count=0; for (lt_i = NF; lt_i > 0; lt_i--) { if ($lt_i != "" && $lt_i != ".") { if ($lt_i == "..") { lt_count++; } else { if (lt_count == 0) { lt_foo="/" $lt_i lt_foo; } else { lt_count--; } } } } if (lt_foo != "") { lt_freq[lt_foo]++; } if (lt_freq[lt_foo] == 1) { print lt_foo; } }'` # AWK program above erroneously prepends '/' to C:/dos/paths # for these hosts. case $host_os in mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ $SED 's,/\([A-Za-z]:\),\1,g'` ;; esac sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` else sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" fi library_names_spec= libname_spec='lib$name' soname_spec= shrext_cmds=".so" postinstall_cmds= postuninstall_cmds= finish_cmds= finish_eval= shlibpath_var= shlibpath_overrides_runpath=unknown version_type=none dynamic_linker="$host_os ld.so" sys_lib_dlsearch_path_spec="/lib /usr/lib" need_lib_prefix=unknown hardcode_into_libs=no # when you set need_version to no, make sure it does not cause -set_version # flags to be left without arguments need_version=unknown case $host_os in aix3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' shlibpath_var=LIBPATH # AIX 3 has no versioning support, so we append a major version to the name. soname_spec='${libname}${release}${shared_ext}$major' ;; aix[4-9]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no hardcode_into_libs=yes if test "$host_cpu" = ia64; then # AIX 5 supports IA64 library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH else # With GCC up to 2.95.x, collect2 would create an import file # for dependence libraries. The import file would start with # the line `#! .'. This would cause the generated library to # depend on `.', always an invalid library. This was fixed in # development snapshots of GCC prior to 3.0. case $host_os in aix4 | aix4.[01] | aix4.[01].*) if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' echo ' yes ' echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then : else can_build_shared=no fi ;; esac # AIX (on Power*) has no versioning support, so currently we can not hardcode correct # soname into executable. Probably we can add versioning support to # collect2, so additional links can be useful in future. if test "$aix_use_runtimelinking" = yes; then # If using run time linking (on AIX 4.2 or later) use lib.so # instead of lib.a to let people know that these are not # typical AIX shared libraries. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' else # We preserve .a as extension for shared libraries through AIX4.2 # and later when we are not doing run time linking. library_names_spec='${libname}${release}.a $libname.a' soname_spec='${libname}${release}${shared_ext}$major' fi shlibpath_var=LIBPATH fi ;; amigaos*) case $host_cpu in powerpc) # Since July 2007 AmigaOS4 officially supports .so libraries. # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ;; m68k) library_names_spec='$libname.ixlibrary $libname.a' # Create ${libname}_ixlibrary.a entries in /sys/libs. finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' ;; esac ;; beos*) library_names_spec='${libname}${shared_ext}' dynamic_linker="$host_os ld.so" shlibpath_var=LIBRARY_PATH ;; bsdi[45]*) version_type=linux # correct to gnu/linux during the next big refactor need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" # the default ld.so.conf also contains /usr/contrib/lib and # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow # libtool to hard-code these into programs ;; cygwin* | mingw* | pw32* | cegcc*) version_type=windows shrext_cmds=".dll" need_version=no need_lib_prefix=no case $GCC,$cc_basename in yes,*) # gcc library_names_spec='$libname.dll.a' # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \${file}`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes case $host_os in cygwin*) # Cygwin DLLs use 'cyg' prefix rather than 'lib' soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api" ;; mingw* | cegcc*) # MinGW DLLs use traditional 'lib' prefix soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' ;; pw32*) # pw32 DLLs use 'pw' prefix rather than 'lib' library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' ;; esac dynamic_linker='Win32 ld.exe' ;; *,cl*) # Native MSVC libname_spec='$name' soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' library_names_spec='${libname}.dll.lib' case $build_os in mingw*) sys_lib_search_path_spec= lt_save_ifs=$IFS IFS=';' for lt_path in $LIB do IFS=$lt_save_ifs # Let DOS variable expansion print the short 8.3 style file name. lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" done IFS=$lt_save_ifs # Convert to MSYS style. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'` ;; cygwin*) # Convert to unix form, then to dos form, then back to unix form # but this time dos style (no spaces!) so that the unix form looks # like /cygdrive/c/PROGRA~1:/cygdr... sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ;; *) sys_lib_search_path_spec="$LIB" if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then # It is most probably a Windows format PATH. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` else sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` fi # FIXME: find the short name or the path components, as spaces are # common. (e.g. "Program Files" -> "PROGRA~1") ;; esac # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \${file}`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes dynamic_linker='Win32 link.exe' ;; *) # Assume MSVC wrapper library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' dynamic_linker='Win32 ld.exe' ;; esac # FIXME: first we should search . and the directory the executable is in shlibpath_var=PATH ;; darwin* | rhapsody*) dynamic_linker="$host_os dyld" version_type=darwin need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' soname_spec='${libname}${release}${major}$shared_ext' shlibpath_overrides_runpath=yes shlibpath_var=DYLD_LIBRARY_PATH shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib" sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' ;; dgux*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH ;; freebsd* | dragonfly*) # DragonFly does not have aout. When/if they implement a new # versioning mechanism, adjust this. if test -x /usr/bin/objformat; then objformat=`/usr/bin/objformat` else case $host_os in freebsd[23].*) objformat=aout ;; *) objformat=elf ;; esac fi version_type=freebsd-$objformat case $version_type in freebsd-elf*) library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' need_version=no need_lib_prefix=no ;; freebsd-*) library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' need_version=yes ;; esac shlibpath_var=LD_LIBRARY_PATH case $host_os in freebsd2.*) shlibpath_overrides_runpath=yes ;; freebsd3.[01]* | freebsdelf3.[01]*) shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; *) # from 4.6 on, and DragonFly shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; esac ;; gnu*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; haiku*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no dynamic_linker="$host_os runtime_loader" library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LIBRARY_PATH shlibpath_overrides_runpath=yes sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' hardcode_into_libs=yes ;; hpux9* | hpux10* | hpux11*) # Give a soname corresponding to the major version so that dld.sl refuses to # link against other versions. version_type=sunos need_lib_prefix=no need_version=no case $host_cpu in ia64*) shrext_cmds='.so' hardcode_into_libs=yes dynamic_linker="$host_os dld.so" shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' if test "X$HPUX_IA64_MODE" = X32; then sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" else sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" fi sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; hppa*64*) shrext_cmds='.sl' hardcode_into_libs=yes dynamic_linker="$host_os dld.sl" shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; *) shrext_cmds='.sl' dynamic_linker="$host_os dld.sl" shlibpath_var=SHLIB_PATH shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' ;; esac # HP-UX runs *really* slowly unless shared libraries are mode 555, ... postinstall_cmds='chmod 555 $lib' # or fails outright, so override atomically: install_override_mode=555 ;; interix[3-9]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; irix5* | irix6* | nonstopux*) case $host_os in nonstopux*) version_type=nonstopux ;; *) if test "$lt_cv_prog_gnu_ld" = yes; then version_type=linux # correct to gnu/linux during the next big refactor else version_type=irix fi ;; esac need_lib_prefix=no need_version=no soname_spec='${libname}${release}${shared_ext}$major' library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' case $host_os in irix5* | nonstopux*) libsuff= shlibsuff= ;; *) case $LD in # libtool.m4 will add one of these switches to LD *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= libmagic=32-bit;; *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 libmagic=N32;; *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 libmagic=64-bit;; *) libsuff= shlibsuff= libmagic=never-match;; esac ;; esac shlibpath_var=LD_LIBRARY${shlibsuff}_PATH shlibpath_overrides_runpath=no sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" hardcode_into_libs=yes ;; # No shared lib support for Linux oldld, aout, or coff. linux*oldld* | linux*aout* | linux*coff*) dynamic_linker=no ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no # Some binutils ld are patched to set DT_RUNPATH if ${lt_cv_shlibpath_overrides_runpath+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_shlibpath_overrides_runpath=no save_LDFLAGS=$LDFLAGS save_libdir=$libdir eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \ LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\"" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then : lt_cv_shlibpath_overrides_runpath=yes fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LDFLAGS=$save_LDFLAGS libdir=$save_libdir fi shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes # Append ld.so.conf contents to the search path if test -f /etc/ld.so.conf; then lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" fi # We used to test for /lib/ld.so.1 and disable shared libraries on # powerpc, because MkLinux only supported shared libraries with the # GNU dynamic linker. Since this was broken with cross compilers, # most powerpc-linux boxes support dynamic linking these days and # people can always --disable-shared, the test was removed, and we # assume the GNU/Linux dynamic linker is in use. dynamic_linker='GNU/Linux ld.so' ;; netbsdelf*-gnu) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='NetBSD ld.elf_so' ;; netbsd*) version_type=sunos need_lib_prefix=no need_version=no if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' dynamic_linker='NetBSD (a.out) ld.so' else library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' dynamic_linker='NetBSD ld.elf_so' fi shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; newsos6) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; *nto* | *qnx*) version_type=qnx need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='ldqnx.so' ;; openbsd*) version_type=sunos sys_lib_dlsearch_path_spec="/usr/lib" need_lib_prefix=no # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. case $host_os in openbsd3.3 | openbsd3.3.*) need_version=yes ;; *) need_version=no ;; esac library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' shlibpath_var=LD_LIBRARY_PATH if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then case $host_os in openbsd2.[89] | openbsd2.[89].*) shlibpath_overrides_runpath=no ;; *) shlibpath_overrides_runpath=yes ;; esac else shlibpath_overrides_runpath=yes fi ;; os2*) libname_spec='$name' shrext_cmds=".dll" need_lib_prefix=no library_names_spec='$libname${shared_ext} $libname.a' dynamic_linker='OS/2 ld.exe' shlibpath_var=LIBPATH ;; osf3* | osf4* | osf5*) version_type=osf need_lib_prefix=no need_version=no soname_spec='${libname}${release}${shared_ext}$major' library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" ;; rdos*) dynamic_linker=no ;; solaris*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes # ldd complains unless libraries are executable postinstall_cmds='chmod +x $lib' ;; sunos4*) version_type=sunos library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes if test "$with_gnu_ld" = yes; then need_lib_prefix=no fi need_version=yes ;; sysv4 | sysv4.3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH case $host_vendor in sni) shlibpath_overrides_runpath=no need_lib_prefix=no runpath_var=LD_RUN_PATH ;; siemens) need_lib_prefix=no ;; motorola) need_lib_prefix=no need_version=no shlibpath_overrides_runpath=no sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' ;; esac ;; sysv4*MP*) if test -d /usr/nec ;then version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' soname_spec='$libname${shared_ext}.$major' shlibpath_var=LD_LIBRARY_PATH fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) version_type=freebsd-elf need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes if test "$with_gnu_ld" = yes; then sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' else sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' case $host_os in sco3.2v5*) sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" ;; esac fi sys_lib_dlsearch_path_spec='/usr/lib' ;; tpf*) # TPF is a cross-target only. Preferred cross-host = GNU/Linux. version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; uts4*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH ;; *) dynamic_linker=no ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 $as_echo "$dynamic_linker" >&6; } test "$dynamic_linker" = no && can_build_shared=no variables_saved_for_relink="PATH $shlibpath_var $runpath_var" if test "$GCC" = yes; then variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" fi if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" fi if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 $as_echo_n "checking how to hardcode library paths into programs... " >&6; } hardcode_action= if test -n "$hardcode_libdir_flag_spec" || test -n "$runpath_var" || test "X$hardcode_automatic" = "Xyes" ; then # We can hardcode non-existent directories. if test "$hardcode_direct" != no && # If the only mechanism to avoid hardcoding is shlibpath_var, we # have to relink, otherwise we might link with an installed library # when we should be linking with a yet-to-be-installed one ## test "$_LT_TAGVAR(hardcode_shlibpath_var, )" != no && test "$hardcode_minus_L" != no; then # Linking always hardcodes the temporary library directory. hardcode_action=relink else # We can link without hardcoding, and we can hardcode nonexisting dirs. hardcode_action=immediate fi else # We cannot hardcode anything, or else we can only hardcode existing # directories. hardcode_action=unsupported fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5 $as_echo "$hardcode_action" >&6; } if test "$hardcode_action" = relink || test "$inherit_rpath" = yes; then # Fast installation is not supported enable_fast_install=no elif test "$shlibpath_overrides_runpath" = yes || test "$enable_shared" = no; then # Fast installation is not necessary enable_fast_install=needless fi if test "x$enable_dlopen" != xyes; then enable_dlopen=unknown enable_dlopen_self=unknown enable_dlopen_self_static=unknown else lt_cv_dlopen=no lt_cv_dlopen_libs= case $host_os in beos*) lt_cv_dlopen="load_add_on" lt_cv_dlopen_libs= lt_cv_dlopen_self=yes ;; mingw* | pw32* | cegcc*) lt_cv_dlopen="LoadLibrary" lt_cv_dlopen_libs= ;; cygwin*) lt_cv_dlopen="dlopen" lt_cv_dlopen_libs= ;; darwin*) # if libdl is installed we need to link against it { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 $as_echo_n "checking for dlopen in -ldl... " >&6; } if ${ac_cv_lib_dl_dlopen+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dlopen (); int main () { return dlopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dl_dlopen=yes else ac_cv_lib_dl_dlopen=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 $as_echo "$ac_cv_lib_dl_dlopen" >&6; } if test "x$ac_cv_lib_dl_dlopen" = xyes; then : lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" else lt_cv_dlopen="dyld" lt_cv_dlopen_libs= lt_cv_dlopen_self=yes fi ;; *) ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load" if test "x$ac_cv_func_shl_load" = xyes; then : lt_cv_dlopen="shl_load" else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5 $as_echo_n "checking for shl_load in -ldld... " >&6; } if ${ac_cv_lib_dld_shl_load+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldld $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char shl_load (); int main () { return shl_load (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dld_shl_load=yes else ac_cv_lib_dld_shl_load=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5 $as_echo "$ac_cv_lib_dld_shl_load" >&6; } if test "x$ac_cv_lib_dld_shl_load" = xyes; then : lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld" else ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen" if test "x$ac_cv_func_dlopen" = xyes; then : lt_cv_dlopen="dlopen" else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 $as_echo_n "checking for dlopen in -ldl... " >&6; } if ${ac_cv_lib_dl_dlopen+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dlopen (); int main () { return dlopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dl_dlopen=yes else ac_cv_lib_dl_dlopen=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 $as_echo "$ac_cv_lib_dl_dlopen" >&6; } if test "x$ac_cv_lib_dl_dlopen" = xyes; then : lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5 $as_echo_n "checking for dlopen in -lsvld... " >&6; } if ${ac_cv_lib_svld_dlopen+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lsvld $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dlopen (); int main () { return dlopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_svld_dlopen=yes else ac_cv_lib_svld_dlopen=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5 $as_echo "$ac_cv_lib_svld_dlopen" >&6; } if test "x$ac_cv_lib_svld_dlopen" = xyes; then : lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld" else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5 $as_echo_n "checking for dld_link in -ldld... " >&6; } if ${ac_cv_lib_dld_dld_link+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldld $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dld_link (); int main () { return dld_link (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dld_dld_link=yes else ac_cv_lib_dld_dld_link=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5 $as_echo "$ac_cv_lib_dld_dld_link" >&6; } if test "x$ac_cv_lib_dld_dld_link" = xyes; then : lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld" fi fi fi fi fi fi ;; esac if test "x$lt_cv_dlopen" != xno; then enable_dlopen=yes else enable_dlopen=no fi case $lt_cv_dlopen in dlopen) save_CPPFLAGS="$CPPFLAGS" test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" save_LDFLAGS="$LDFLAGS" wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" save_LIBS="$LIBS" LIBS="$lt_cv_dlopen_libs $LIBS" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5 $as_echo_n "checking whether a program can dlopen itself... " >&6; } if ${lt_cv_dlopen_self+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : lt_cv_dlopen_self=cross else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF #line $LINENO "configure" #include "confdefs.h" #if HAVE_DLFCN_H #include #endif #include #ifdef RTLD_GLOBAL # define LT_DLGLOBAL RTLD_GLOBAL #else # ifdef DL_GLOBAL # define LT_DLGLOBAL DL_GLOBAL # else # define LT_DLGLOBAL 0 # endif #endif /* We may have to define LT_DLLAZY_OR_NOW in the command line if we find out it does not work in some platform. */ #ifndef LT_DLLAZY_OR_NOW # ifdef RTLD_LAZY # define LT_DLLAZY_OR_NOW RTLD_LAZY # else # ifdef DL_LAZY # define LT_DLLAZY_OR_NOW DL_LAZY # else # ifdef RTLD_NOW # define LT_DLLAZY_OR_NOW RTLD_NOW # else # ifdef DL_NOW # define LT_DLLAZY_OR_NOW DL_NOW # else # define LT_DLLAZY_OR_NOW 0 # endif # endif # endif # endif #endif /* When -fvisbility=hidden is used, assume the code has been annotated correspondingly for the symbols needed. */ #if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) int fnord () __attribute__((visibility("default"))); #endif int fnord () { return 42; } int main () { void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); int status = $lt_dlunknown; if (self) { if (dlsym (self,"fnord")) status = $lt_dlno_uscore; else { if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; else puts (dlerror ()); } /* dlclose (self); */ } else puts (dlerror ()); return status; } _LT_EOF if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 (eval $ac_link) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then (./conftest; exit; ) >&5 2>/dev/null lt_status=$? case x$lt_status in x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;; x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;; x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;; esac else : # compilation failed lt_cv_dlopen_self=no fi fi rm -fr conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5 $as_echo "$lt_cv_dlopen_self" >&6; } if test "x$lt_cv_dlopen_self" = xyes; then wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5 $as_echo_n "checking whether a statically linked program can dlopen itself... " >&6; } if ${lt_cv_dlopen_self_static+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : lt_cv_dlopen_self_static=cross else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF #line $LINENO "configure" #include "confdefs.h" #if HAVE_DLFCN_H #include #endif #include #ifdef RTLD_GLOBAL # define LT_DLGLOBAL RTLD_GLOBAL #else # ifdef DL_GLOBAL # define LT_DLGLOBAL DL_GLOBAL # else # define LT_DLGLOBAL 0 # endif #endif /* We may have to define LT_DLLAZY_OR_NOW in the command line if we find out it does not work in some platform. */ #ifndef LT_DLLAZY_OR_NOW # ifdef RTLD_LAZY # define LT_DLLAZY_OR_NOW RTLD_LAZY # else # ifdef DL_LAZY # define LT_DLLAZY_OR_NOW DL_LAZY # else # ifdef RTLD_NOW # define LT_DLLAZY_OR_NOW RTLD_NOW # else # ifdef DL_NOW # define LT_DLLAZY_OR_NOW DL_NOW # else # define LT_DLLAZY_OR_NOW 0 # endif # endif # endif # endif #endif /* When -fvisbility=hidden is used, assume the code has been annotated correspondingly for the symbols needed. */ #if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) int fnord () __attribute__((visibility("default"))); #endif int fnord () { return 42; } int main () { void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); int status = $lt_dlunknown; if (self) { if (dlsym (self,"fnord")) status = $lt_dlno_uscore; else { if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; else puts (dlerror ()); } /* dlclose (self); */ } else puts (dlerror ()); return status; } _LT_EOF if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 (eval $ac_link) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then (./conftest; exit; ) >&5 2>/dev/null lt_status=$? case x$lt_status in x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;; x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;; x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;; esac else : # compilation failed lt_cv_dlopen_self_static=no fi fi rm -fr conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5 $as_echo "$lt_cv_dlopen_self_static" >&6; } fi CPPFLAGS="$save_CPPFLAGS" LDFLAGS="$save_LDFLAGS" LIBS="$save_LIBS" ;; esac case $lt_cv_dlopen_self in yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; *) enable_dlopen_self=unknown ;; esac case $lt_cv_dlopen_self_static in yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; *) enable_dlopen_self_static=unknown ;; esac fi striplib= old_striplib= { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5 $as_echo_n "checking whether stripping libraries is possible... " >&6; } if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" test -z "$striplib" && striplib="$STRIP --strip-unneeded" { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else # FIXME - insert some real tests, host_os isn't really good enough case $host_os in darwin*) if test -n "$STRIP" ; then striplib="$STRIP -x" old_striplib="$STRIP -S" { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi ;; *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } ;; esac fi # Report which library types will actually be built { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5 $as_echo_n "checking if libtool supports shared libraries... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5 $as_echo "$can_build_shared" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5 $as_echo_n "checking whether to build shared libraries... " >&6; } test "$can_build_shared" = "no" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test "$enable_shared" = yes && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[4-9]*) if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then test "$enable_shared" = yes && enable_static=no fi ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5 $as_echo "$enable_shared" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5 $as_echo_n "checking whether to build static libraries... " >&6; } # Make sure either enable_shared or enable_static is yes. test "$enable_shared" = yes || enable_static=yes { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5 $as_echo "$enable_static" >&6; } fi ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu CC="$lt_save_CC" if test -n "$CXX" && ( test "X$CXX" != "Xno" && ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || (test "X$CXX" != "Xg++"))) ; then ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C++ preprocessor" >&5 $as_echo_n "checking how to run the C++ preprocessor... " >&6; } if test -z "$CXXCPP"; then if ${ac_cv_prog_CXXCPP+:} false; then : $as_echo_n "(cached) " >&6 else # Double quotes because CXXCPP needs to be expanded for CXXCPP in "$CXX -E" "/lib/cpp" do ac_preproc_ok=false for ac_cxx_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_cxx_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_cxx_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : break fi done ac_cv_prog_CXXCPP=$CXXCPP fi CXXCPP=$ac_cv_prog_CXXCPP else ac_cv_prog_CXXCPP=$CXXCPP fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXXCPP" >&5 $as_echo "$CXXCPP" >&6; } ac_preproc_ok=false for ac_cxx_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_cxx_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_cxx_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "C++ preprocessor \"$CXXCPP\" fails sanity check See \`config.log' for more details" "$LINENO" 5; } fi ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu else _lt_caught_CXX_error=yes fi ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu archive_cmds_need_lc_CXX=no allow_undefined_flag_CXX= always_export_symbols_CXX=no archive_expsym_cmds_CXX= compiler_needs_object_CXX=no export_dynamic_flag_spec_CXX= hardcode_direct_CXX=no hardcode_direct_absolute_CXX=no hardcode_libdir_flag_spec_CXX= hardcode_libdir_separator_CXX= hardcode_minus_L_CXX=no hardcode_shlibpath_var_CXX=unsupported hardcode_automatic_CXX=no inherit_rpath_CXX=no module_cmds_CXX= module_expsym_cmds_CXX= link_all_deplibs_CXX=unknown old_archive_cmds_CXX=$old_archive_cmds reload_flag_CXX=$reload_flag reload_cmds_CXX=$reload_cmds no_undefined_flag_CXX= whole_archive_flag_spec_CXX= enable_shared_with_static_runtimes_CXX=no # Source file extension for C++ test sources. ac_ext=cpp # Object file extension for compiled C++ test sources. objext=o objext_CXX=$objext # No sense in running all these tests if we already determined that # the CXX compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. if test "$_lt_caught_CXX_error" != yes; then # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests lt_simple_link_test_code='int main(int, char *[]) { return(0); }' # ltmain only uses $CC for tagged configurations so make sure $CC is set. # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC # save warnings/boilerplate of simple test code ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" >conftest.$ac_ext eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_compiler_boilerplate=`cat conftest.err` $RM conftest* ac_outfile=conftest.$ac_objext echo "$lt_simple_link_test_code" >conftest.$ac_ext eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_linker_boilerplate=`cat conftest.err` $RM -r conftest* # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_CFLAGS=$CFLAGS lt_save_LD=$LD lt_save_GCC=$GCC GCC=$GXX lt_save_with_gnu_ld=$with_gnu_ld lt_save_path_LD=$lt_cv_path_LD if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx else $as_unset lt_cv_prog_gnu_ld fi if test -n "${lt_cv_path_LDCXX+set}"; then lt_cv_path_LD=$lt_cv_path_LDCXX else $as_unset lt_cv_path_LD fi test -z "${LDCXX+set}" || LD=$LDCXX CC=${CXX-"c++"} CFLAGS=$CXXFLAGS compiler=$CC compiler_CXX=$CC for cc_temp in $compiler""; do case $cc_temp in compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; \-*) ;; *) break;; esac done cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` if test -n "$compiler"; then # We don't want -fno-exception when compiling C++ code, so set the # no_builtin_flag separately if test "$GXX" = yes; then lt_prog_compiler_no_builtin_flag_CXX=' -fno-builtin' else lt_prog_compiler_no_builtin_flag_CXX= fi if test "$GXX" = yes; then # Set up default GNU C++ configuration # Check whether --with-gnu-ld was given. if test "${with_gnu_ld+set}" = set; then : withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes else with_gnu_ld=no fi ac_prog=ld if test "$GCC" = yes; then # Check if gcc -print-prog-name=ld gives a path. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 $as_echo_n "checking for ld used by $CC... " >&6; } case $host in *-*-mingw*) # gcc leaves a trailing carriage return which upsets mingw ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; *) ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; esac case $ac_prog in # Accept absolute paths. [\\/]* | ?:[\\/]*) re_direlt='/[^/][^/]*/\.\./' # Canonicalize the pathname of ld ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` done test -z "$LD" && LD="$ac_prog" ;; "") # If it fails, then pretend we aren't using GCC. ac_prog=ld ;; *) # If it is relative, then search for the first ld in PATH. with_gnu_ld=unknown ;; esac elif test "$with_gnu_ld" = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 $as_echo_n "checking for GNU ld... " >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 $as_echo_n "checking for non-GNU ld... " >&6; } fi if ${lt_cv_path_LD+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$LD"; then lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR for ac_dir in $PATH; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then lt_cv_path_LD="$ac_dir/$ac_prog" # Check to see if the program is GNU ld. I'd rather use --version, # but apparently some variants of GNU ld only accept -v. # Break only if it was the GNU/non-GNU ld that we prefer. case `"$lt_cv_path_LD" -v 2>&1 &5 $as_echo "$LD" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 { $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 $as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } if ${lt_cv_prog_gnu_ld+:} false; then : $as_echo_n "(cached) " >&6 else # I'd rather use --version here, but apparently some GNU lds only accept -v. case `$LD -v 2>&1 &5 $as_echo "$lt_cv_prog_gnu_ld" >&6; } with_gnu_ld=$lt_cv_prog_gnu_ld # Check if GNU C++ uses GNU ld as the underlying linker, since the # archiving commands below assume that GNU ld is being used. if test "$with_gnu_ld" = yes; then archive_cmds_CXX='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds_CXX='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' export_dynamic_flag_spec_CXX='${wl}--export-dynamic' # If archive_cmds runs LD, not CC, wlarc should be empty # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to # investigate it a little bit more. (MM) wlarc='${wl}' # ancient GNU ld didn't support --whole-archive et. al. if eval "`$CC -print-prog-name=ld` --help 2>&1" | $GREP 'no-whole-archive' > /dev/null; then whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' else whole_archive_flag_spec_CXX= fi else with_gnu_ld=no wlarc= # A generic and very simple default shared library creation # command for GNU C++ for the case where it uses the native # linker, instead of GNU ld. If possible, this setting should # overridden to take advantage of the native linker features on # the platform it is being used on. archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' fi # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' else GXX=no with_gnu_ld=no wlarc= fi # PORTME: fill in a description of your system's C++ link characteristics { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 $as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } ld_shlibs_CXX=yes case $host_os in aix3*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; aix[4-9]*) if test "$host_cpu" = ia64; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag="" else aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # need to do runtime linking. case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) for ld_flag in $LDFLAGS; do case $ld_flag in *-brtl*) aix_use_runtimelinking=yes break ;; esac done ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. archive_cmds_CXX='' hardcode_direct_CXX=yes hardcode_direct_absolute_CXX=yes hardcode_libdir_separator_CXX=':' link_all_deplibs_CXX=yes file_list_spec_CXX='${wl}-f,' if test "$GXX" = yes; then case $host_os in aix4.[012]|aix4.[012].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`${CC} -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then # We have reworked collect2 : else # We have old collect2 hardcode_direct_CXX=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking hardcode_minus_L_CXX=yes hardcode_libdir_flag_spec_CXX='-L$libdir' hardcode_libdir_separator_CXX= fi esac shared_flag='-shared' if test "$aix_use_runtimelinking" = yes; then shared_flag="$shared_flag "'${wl}-G' fi else # not using gcc if test "$host_cpu" = ia64; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test "$aix_use_runtimelinking" = yes; then shared_flag='${wl}-G' else shared_flag='${wl}-bM:SRE' fi fi fi export_dynamic_flag_spec_CXX='${wl}-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to # export. always_export_symbols_CXX=yes if test "$aix_use_runtimelinking" = yes; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. allow_undefined_flag_CXX='-berok' # Determine the default libpath from the value encoded in an empty # executable. if test "${lt_cv_aix_libpath+set}" = set; then aix_libpath=$lt_cv_aix_libpath else if ${lt_cv_aix_libpath__CXX+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : lt_aix_libpath_sed=' /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }' lt_cv_aix_libpath__CXX=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$lt_cv_aix_libpath__CXX"; then lt_cv_aix_libpath__CXX=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test -z "$lt_cv_aix_libpath__CXX"; then lt_cv_aix_libpath__CXX="/usr/lib:/lib" fi fi aix_libpath=$lt_cv_aix_libpath__CXX fi hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath" archive_expsym_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" else if test "$host_cpu" = ia64; then hardcode_libdir_flag_spec_CXX='${wl}-R $libdir:/usr/lib:/lib' allow_undefined_flag_CXX="-z nodefs" archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. if test "${lt_cv_aix_libpath+set}" = set; then aix_libpath=$lt_cv_aix_libpath else if ${lt_cv_aix_libpath__CXX+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : lt_aix_libpath_sed=' /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }' lt_cv_aix_libpath__CXX=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$lt_cv_aix_libpath__CXX"; then lt_cv_aix_libpath__CXX=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test -z "$lt_cv_aix_libpath__CXX"; then lt_cv_aix_libpath__CXX="/usr/lib:/lib" fi fi aix_libpath=$lt_cv_aix_libpath__CXX fi hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. no_undefined_flag_CXX=' ${wl}-bernotok' allow_undefined_flag_CXX=' ${wl}-berok' if test "$with_gnu_ld" = yes; then # We only use this code for GNU lds that support --whole-archive. whole_archive_flag_spec_CXX='${wl}--whole-archive$convenience ${wl}--no-whole-archive' else # Exported symbols can be pulled into shared objects from archives whole_archive_flag_spec_CXX='$convenience' fi archive_cmds_need_lc_CXX=yes # This is similar to how AIX traditionally builds its shared # libraries. archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' fi fi ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then allow_undefined_flag_CXX=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME archive_cmds_CXX='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' else ld_shlibs_CXX=no fi ;; chorus*) case $cc_basename in *) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; esac ;; cygwin* | mingw* | pw32* | cegcc*) case $GXX,$cc_basename in ,cl* | no,cl*) # Native MSVC # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. hardcode_libdir_flag_spec_CXX=' ' allow_undefined_flag_CXX=unsupported always_export_symbols_CXX=yes file_list_spec_CXX='@' # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=".dll" # FIXME: Setting linknames here is a bad hack. archive_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' archive_expsym_cmds_CXX='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then $SED -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; else $SED -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; fi~ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, CXX)='true' enable_shared_with_static_runtimes_CXX=yes # Don't use ranlib old_postinstall_cmds_CXX='chmod 644 $oldlib' postlink_cmds_CXX='lt_outputfile="@OUTPUT@"~ lt_tool_outputfile="@TOOL_OUTPUT@"~ case $lt_outputfile in *.exe|*.EXE) ;; *) lt_outputfile="$lt_outputfile.exe" lt_tool_outputfile="$lt_tool_outputfile.exe" ;; esac~ func_to_tool_file "$lt_outputfile"~ if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; $RM "$lt_outputfile.manifest"; fi' ;; *) # g++ # _LT_TAGVAR(hardcode_libdir_flag_spec, CXX) is actually meaningless, # as there is no search path for DLLs. hardcode_libdir_flag_spec_CXX='-L$libdir' export_dynamic_flag_spec_CXX='${wl}--export-all-symbols' allow_undefined_flag_CXX=unsupported always_export_symbols_CXX=no enable_shared_with_static_runtimes_CXX=yes if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file (1st line # is EXPORTS), use it as is; otherwise, prepend... archive_expsym_cmds_CXX='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else ld_shlibs_CXX=no fi ;; esac ;; darwin* | rhapsody*) archive_cmds_need_lc_CXX=no hardcode_direct_CXX=no hardcode_automatic_CXX=yes hardcode_shlibpath_var_CXX=unsupported if test "$lt_cv_ld_force_load" = "yes"; then whole_archive_flag_spec_CXX='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' else whole_archive_flag_spec_CXX='' fi link_all_deplibs_CXX=yes allow_undefined_flag_CXX="$_lt_dar_allow_undefined" case $cc_basename in ifort*) _lt_dar_can_shared=yes ;; *) _lt_dar_can_shared=$GCC ;; esac if test "$_lt_dar_can_shared" = "yes"; then output_verbose_link_cmd=func_echo_all archive_cmds_CXX="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" module_cmds_CXX="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" module_expsym_cmds_CXX="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" if test "$lt_cv_apple_cc_single_mod" != "yes"; then archive_cmds_CXX="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}" archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}" fi else ld_shlibs_CXX=no fi ;; dgux*) case $cc_basename in ec++*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; ghcx*) # Green Hills C++ Compiler # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; *) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; esac ;; freebsd2.*) # C++ shared libraries reported to be fairly broken before # switch to ELF ld_shlibs_CXX=no ;; freebsd-elf*) archive_cmds_need_lc_CXX=no ;; freebsd* | dragonfly*) # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF # conventions ld_shlibs_CXX=yes ;; gnu*) ;; haiku*) archive_cmds_CXX='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' link_all_deplibs_CXX=yes ;; hpux9*) hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir' hardcode_libdir_separator_CXX=: export_dynamic_flag_spec_CXX='${wl}-E' hardcode_direct_CXX=yes hardcode_minus_L_CXX=yes # Not in the search PATH, # but as the default # location of the library. case $cc_basename in CC*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; aCC*) archive_cmds_CXX='$RM $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test "$GXX" = yes; then archive_cmds_CXX='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' else # FIXME: insert proper C++ library support ld_shlibs_CXX=no fi ;; esac ;; hpux10*|hpux11*) if test $with_gnu_ld = no; then hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir' hardcode_libdir_separator_CXX=: case $host_cpu in hppa*64*|ia64*) ;; *) export_dynamic_flag_spec_CXX='${wl}-E' ;; esac fi case $host_cpu in hppa*64*|ia64*) hardcode_direct_CXX=no hardcode_shlibpath_var_CXX=no ;; *) hardcode_direct_CXX=yes hardcode_direct_absolute_CXX=yes hardcode_minus_L_CXX=yes # Not in the search PATH, # but as the default # location of the library. ;; esac case $cc_basename in CC*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; aCC*) case $host_cpu in hppa*64*) archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; ia64*) archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; esac # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test "$GXX" = yes; then if test $with_gnu_ld = no; then case $host_cpu in hppa*64*) archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; ia64*) archive_cmds_CXX='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) archive_cmds_CXX='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; esac fi else # FIXME: insert proper C++ library support ld_shlibs_CXX=no fi ;; esac ;; interix[3-9]*) hardcode_direct_CXX=no hardcode_shlibpath_var_CXX=no hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' export_dynamic_flag_spec_CXX='${wl}-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. archive_cmds_CXX='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' archive_expsym_cmds_CXX='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; irix5* | irix6*) case $cc_basename in CC*) # SGI C++ archive_cmds_CXX='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' # Archives containing C++ object files must be created using # "CC -ar", where "CC" is the IRIX C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. old_archive_cmds_CXX='$CC -ar -WR,-u -o $oldlib $oldobjs' ;; *) if test "$GXX" = yes; then if test "$with_gnu_ld" = no; then archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' else archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` -o $lib' fi fi link_all_deplibs_CXX=yes ;; esac hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator_CXX=: inherit_rpath_CXX=yes ;; linux* | k*bsd*-gnu | kopensolaris*-gnu) case $cc_basename in KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' archive_expsym_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' export_dynamic_flag_spec_CXX='${wl}--export-dynamic' # Archives containing C++ object files must be created using # "CC -Bstatic", where "CC" is the KAI C++ compiler. old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' ;; icpc* | ecpc* ) # Intel C++ with_gnu_ld=yes # version 8.0 and above of icpc choke on multiply defined symbols # if we add $predep_objects and $postdep_objects, however 7.1 and # earlier do not add the objects themselves. case `$CC -V 2>&1` in *"Version 7."*) archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' ;; *) # Version 8.0 or newer tmp_idyn= case $host_cpu in ia64*) tmp_idyn=' -i_dynamic';; esac archive_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' ;; esac archive_cmds_need_lc_CXX=no hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' export_dynamic_flag_spec_CXX='${wl}--export-dynamic' whole_archive_flag_spec_CXX='${wl}--whole-archive$convenience ${wl}--no-whole-archive' ;; pgCC* | pgcpp*) # Portland Group C++ compiler case `$CC -V` in *pgCC\ [1-5].* | *pgcpp\ [1-5].*) prelink_cmds_CXX='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"' old_archive_cmds_CXX='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~ $RANLIB $oldlib' archive_cmds_CXX='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' archive_expsym_cmds_CXX='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' ;; *) # Version 6 and above use weak symbols archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' ;; esac hardcode_libdir_flag_spec_CXX='${wl}--rpath ${wl}$libdir' export_dynamic_flag_spec_CXX='${wl}--export-dynamic' whole_archive_flag_spec_CXX='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' ;; cxx*) # Compaq C++ archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols' runpath_var=LD_RUN_PATH hardcode_libdir_flag_spec_CXX='-rpath $libdir' hardcode_libdir_separator_CXX=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed' ;; xl* | mpixl* | bgxl*) # IBM XL 8.0 on PPC, with GNU ld hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' export_dynamic_flag_spec_CXX='${wl}--export-dynamic' archive_cmds_CXX='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' if test "x$supports_anon_versioning" = xyes; then archive_expsym_cmds_CXX='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' fi ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C++ 5.9 no_undefined_flag_CXX=' -zdefs' archive_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' archive_expsym_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols' hardcode_libdir_flag_spec_CXX='-R$libdir' whole_archive_flag_spec_CXX='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' compiler_needs_object_CXX=yes # Not sure whether something based on # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 # would be better. output_verbose_link_cmd='func_echo_all' # Archives containing C++ object files must be created using # "CC -xar", where "CC" is the Sun C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs' ;; esac ;; esac ;; lynxos*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; m88k*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; mvs*) case $cc_basename in cxx*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; *) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; esac ;; netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then archive_cmds_CXX='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' wlarc= hardcode_libdir_flag_spec_CXX='-R$libdir' hardcode_direct_CXX=yes hardcode_shlibpath_var_CXX=no fi # Workaround some broken pre-1.5 toolchains output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' ;; *nto* | *qnx*) ld_shlibs_CXX=yes ;; openbsd2*) # C++ shared libraries are fairly broken ld_shlibs_CXX=no ;; openbsd*) if test -f /usr/libexec/ld.so; then hardcode_direct_CXX=yes hardcode_shlibpath_var_CXX=no hardcode_direct_absolute_CXX=yes archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib' export_dynamic_flag_spec_CXX='${wl}-E' whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' fi output_verbose_link_cmd=func_echo_all else ld_shlibs_CXX=no fi ;; osf3* | osf4* | osf5*) case $cc_basename in KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' hardcode_libdir_separator_CXX=: # Archives containing C++ object files must be created using # the KAI C++ compiler. case $host in osf3*) old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' ;; *) old_archive_cmds_CXX='$CC -o $oldlib $oldobjs' ;; esac ;; RCC*) # Rational C++ 2.4.1 # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; cxx*) case $host in osf3*) allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*' archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && func_echo_all "${wl}-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' ;; *) allow_undefined_flag_CXX=' -expect_unresolved \*' archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' archive_expsym_cmds_CXX='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ echo "-hidden">> $lib.exp~ $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~ $RM $lib.exp' hardcode_libdir_flag_spec_CXX='-rpath $libdir' ;; esac hardcode_libdir_separator_CXX=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test "$GXX" = yes && test "$with_gnu_ld" = no; then allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*' case $host in osf3*) archive_cmds_CXX='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ;; *) archive_cmds_CXX='$CC -shared $pic_flag -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ;; esac hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator_CXX=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' else # FIXME: insert proper C++ library support ld_shlibs_CXX=no fi ;; esac ;; psos*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; sunos4*) case $cc_basename in CC*) # Sun C++ 4.x # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; lcc*) # Lucid # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; *) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; esac ;; solaris*) case $cc_basename in CC* | sunCC*) # Sun C++ 4.2, 5.x and Centerline C++ archive_cmds_need_lc_CXX=yes no_undefined_flag_CXX=' -zdefs' archive_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' hardcode_libdir_flag_spec_CXX='-R$libdir' hardcode_shlibpath_var_CXX=no case $host_os in solaris2.[0-5] | solaris2.[0-5].*) ;; *) # The compiler driver will combine and reorder linker options, # but understands `-z linker_flag'. # Supported since Solaris 2.6 (maybe 2.5.1?) whole_archive_flag_spec_CXX='-z allextract$convenience -z defaultextract' ;; esac link_all_deplibs_CXX=yes output_verbose_link_cmd='func_echo_all' # Archives containing C++ object files must be created using # "CC -xar", where "CC" is the Sun C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs' ;; gcx*) # Green Hills C++ Compiler archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' # The C++ compiler must be used to create the archive. old_archive_cmds_CXX='$CC $LDFLAGS -archive -o $oldlib $oldobjs' ;; *) # GNU C++ compiler with Solaris linker if test "$GXX" = yes && test "$with_gnu_ld" = no; then no_undefined_flag_CXX=' ${wl}-z ${wl}defs' if $CC --version | $GREP -v '^2\.7' > /dev/null; then archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -shared $pic_flag -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' else # g++ 2.7 appears to require `-G' NOT `-shared' on this # platform. archive_cmds_CXX='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' fi hardcode_libdir_flag_spec_CXX='${wl}-R $wl$libdir' case $host_os in solaris2.[0-5] | solaris2.[0-5].*) ;; *) whole_archive_flag_spec_CXX='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' ;; esac fi ;; esac ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) no_undefined_flag_CXX='${wl}-z,text' archive_cmds_need_lc_CXX=no hardcode_shlibpath_var_CXX=no runpath_var='LD_RUN_PATH' case $cc_basename in CC*) archive_cmds_CXX='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds_CXX='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; *) archive_cmds_CXX='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds_CXX='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We can NOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. no_undefined_flag_CXX='${wl}-z,text' allow_undefined_flag_CXX='${wl}-z,nodefs' archive_cmds_need_lc_CXX=no hardcode_shlibpath_var_CXX=no hardcode_libdir_flag_spec_CXX='${wl}-R,$libdir' hardcode_libdir_separator_CXX=':' link_all_deplibs_CXX=yes export_dynamic_flag_spec_CXX='${wl}-Bexport' runpath_var='LD_RUN_PATH' case $cc_basename in CC*) archive_cmds_CXX='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds_CXX='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' old_archive_cmds_CXX='$CC -Tprelink_objects $oldobjs~ '"$old_archive_cmds_CXX" reload_cmds_CXX='$CC -Tprelink_objects $reload_objs~ '"$reload_cmds_CXX" ;; *) archive_cmds_CXX='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds_CXX='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; tandem*) case $cc_basename in NCC*) # NonStop-UX NCC 3.20 # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; *) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; esac ;; vxworks*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; *) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5 $as_echo "$ld_shlibs_CXX" >&6; } test "$ld_shlibs_CXX" = no && can_build_shared=no GCC_CXX="$GXX" LD_CXX="$LD" ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... # Dependencies to place before and after the object being linked: predep_objects_CXX= postdep_objects_CXX= predeps_CXX= postdeps_CXX= compiler_lib_search_path_CXX= cat > conftest.$ac_ext <<_LT_EOF class Foo { public: Foo (void) { a = 0; } private: int a; }; _LT_EOF _lt_libdeps_save_CFLAGS=$CFLAGS case "$CC $CFLAGS " in #( *\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;; *\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;; *\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;; esac if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then # Parse the compiler output and extract the necessary # objects, libraries and library flags. # Sentinel used to keep track of whether or not we are before # the conftest object file. pre_test_object_deps_done=no for p in `eval "$output_verbose_link_cmd"`; do case ${prev}${p} in -L* | -R* | -l*) # Some compilers place space between "-{L,R}" and the path. # Remove the space. if test $p = "-L" || test $p = "-R"; then prev=$p continue fi # Expand the sysroot to ease extracting the directories later. if test -z "$prev"; then case $p in -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;; -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;; -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;; esac fi case $p in =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;; esac if test "$pre_test_object_deps_done" = no; then case ${prev} in -L | -R) # Internal compiler library paths should come after those # provided the user. The postdeps already come after the # user supplied libs so there is no need to process them. if test -z "$compiler_lib_search_path_CXX"; then compiler_lib_search_path_CXX="${prev}${p}" else compiler_lib_search_path_CXX="${compiler_lib_search_path_CXX} ${prev}${p}" fi ;; # The "-l" case would never come before the object being # linked, so don't bother handling this case. esac else if test -z "$postdeps_CXX"; then postdeps_CXX="${prev}${p}" else postdeps_CXX="${postdeps_CXX} ${prev}${p}" fi fi prev= ;; *.lto.$objext) ;; # Ignore GCC LTO objects *.$objext) # This assumes that the test object file only shows up # once in the compiler output. if test "$p" = "conftest.$objext"; then pre_test_object_deps_done=yes continue fi if test "$pre_test_object_deps_done" = no; then if test -z "$predep_objects_CXX"; then predep_objects_CXX="$p" else predep_objects_CXX="$predep_objects_CXX $p" fi else if test -z "$postdep_objects_CXX"; then postdep_objects_CXX="$p" else postdep_objects_CXX="$postdep_objects_CXX $p" fi fi ;; *) ;; # Ignore the rest. esac done # Clean up. rm -f a.out a.exe else echo "libtool.m4: error: problem compiling CXX test program" fi $RM -f confest.$objext CFLAGS=$_lt_libdeps_save_CFLAGS # PORTME: override above test on systems where it is broken case $host_os in interix[3-9]*) # Interix 3.5 installs completely hosed .la files for C++, so rather than # hack all around it, let's just trust "g++" to DTRT. predep_objects_CXX= postdep_objects_CXX= postdeps_CXX= ;; linux*) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C++ 5.9 # The more standards-conforming stlport4 library is # incompatible with the Cstd library. Avoid specifying # it if it's in CXXFLAGS. Ignore libCrun as # -library=stlport4 depends on it. case " $CXX $CXXFLAGS " in *" -library=stlport4 "*) solaris_use_stlport4=yes ;; esac if test "$solaris_use_stlport4" != yes; then postdeps_CXX='-library=Cstd -library=Crun' fi ;; esac ;; solaris*) case $cc_basename in CC* | sunCC*) # The more standards-conforming stlport4 library is # incompatible with the Cstd library. Avoid specifying # it if it's in CXXFLAGS. Ignore libCrun as # -library=stlport4 depends on it. case " $CXX $CXXFLAGS " in *" -library=stlport4 "*) solaris_use_stlport4=yes ;; esac # Adding this requires a known-good setup of shared libraries for # Sun compiler versions before 5.6, else PIC objects from an old # archive will be linked into the output, leading to subtle bugs. if test "$solaris_use_stlport4" != yes; then postdeps_CXX='-library=Cstd -library=Crun' fi ;; esac ;; esac case " $postdeps_CXX " in *" -lc "*) archive_cmds_need_lc_CXX=no ;; esac compiler_lib_search_dirs_CXX= if test -n "${compiler_lib_search_path_CXX}"; then compiler_lib_search_dirs_CXX=`echo " ${compiler_lib_search_path_CXX}" | ${SED} -e 's! -L! !g' -e 's!^ !!'` fi lt_prog_compiler_wl_CXX= lt_prog_compiler_pic_CXX= lt_prog_compiler_static_CXX= # C++ specific cases for pic, static, wl, etc. if test "$GXX" = yes; then lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_static_CXX='-static' case $host_os in aix*) # All AIX code is PIC. if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor lt_prog_compiler_static_CXX='-Bstatic' fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support lt_prog_compiler_pic_CXX='-fPIC' ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but # adding the `-m68020' flag to GCC prevents building anything better, # like `-m68040'. lt_prog_compiler_pic_CXX='-m68020 -resident32 -malways-restore-a4' ;; esac ;; beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | cygwin* | os2* | pw32* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style # (--disable-auto-import) libraries lt_prog_compiler_pic_CXX='-DDLL_EXPORT' ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files lt_prog_compiler_pic_CXX='-fno-common' ;; *djgpp*) # DJGPP does not support shared libraries at all lt_prog_compiler_pic_CXX= ;; haiku*) # PIC is the default for Haiku. # The "-static" flag exists, but is broken. lt_prog_compiler_static_CXX= ;; interix[3-9]*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; sysv4*MP*) if test -d /usr/nec; then lt_prog_compiler_pic_CXX=-Kconform_pic fi ;; hpux*) # PIC is the default for 64-bit PA HP-UX, but not for 32-bit # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag # sets the default TLS model and affects inlining. case $host_cpu in hppa*64*) ;; *) lt_prog_compiler_pic_CXX='-fPIC' ;; esac ;; *qnx* | *nto*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. lt_prog_compiler_pic_CXX='-fPIC -shared' ;; *) lt_prog_compiler_pic_CXX='-fPIC' ;; esac else case $host_os in aix[4-9]*) # All AIX code is PIC. if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor lt_prog_compiler_static_CXX='-Bstatic' else lt_prog_compiler_static_CXX='-bnso -bI:/lib/syscalls.exp' fi ;; chorus*) case $cc_basename in cxch68*) # Green Hills C++ Compiler # _LT_TAGVAR(lt_prog_compiler_static, CXX)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" ;; esac ;; mingw* | cygwin* | os2* | pw32* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). lt_prog_compiler_pic_CXX='-DDLL_EXPORT' ;; dgux*) case $cc_basename in ec++*) lt_prog_compiler_pic_CXX='-KPIC' ;; ghcx*) # Green Hills C++ Compiler lt_prog_compiler_pic_CXX='-pic' ;; *) ;; esac ;; freebsd* | dragonfly*) # FreeBSD uses GNU C++ ;; hpux9* | hpux10* | hpux11*) case $cc_basename in CC*) lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_static_CXX='${wl}-a ${wl}archive' if test "$host_cpu" != ia64; then lt_prog_compiler_pic_CXX='+Z' fi ;; aCC*) lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_static_CXX='${wl}-a ${wl}archive' case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) lt_prog_compiler_pic_CXX='+Z' ;; esac ;; *) ;; esac ;; interix*) # This is c89, which is MS Visual C++ (no shared libs) # Anyone wants to do a port? ;; irix5* | irix6* | nonstopux*) case $cc_basename in CC*) lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_static_CXX='-non_shared' # CC pic flag -KPIC is the default. ;; *) ;; esac ;; linux* | k*bsd*-gnu | kopensolaris*-gnu) case $cc_basename in KCC*) # KAI C++ Compiler lt_prog_compiler_wl_CXX='--backend -Wl,' lt_prog_compiler_pic_CXX='-fPIC' ;; ecpc* ) # old Intel C++ for x86_64 which still supported -KPIC. lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_pic_CXX='-KPIC' lt_prog_compiler_static_CXX='-static' ;; icpc* ) # Intel C++, used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_pic_CXX='-fPIC' lt_prog_compiler_static_CXX='-static' ;; pgCC* | pgcpp*) # Portland Group C++ compiler lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_pic_CXX='-fpic' lt_prog_compiler_static_CXX='-Bstatic' ;; cxx*) # Compaq C++ # Make sure the PIC flag is empty. It appears that all Alpha # Linux and Compaq Tru64 Unix objects are PIC. lt_prog_compiler_pic_CXX= lt_prog_compiler_static_CXX='-non_shared' ;; xlc* | xlC* | bgxl[cC]* | mpixl[cC]*) # IBM XL 8.0, 9.0 on PPC and BlueGene lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_pic_CXX='-qpic' lt_prog_compiler_static_CXX='-qstaticlink' ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C++ 5.9 lt_prog_compiler_pic_CXX='-KPIC' lt_prog_compiler_static_CXX='-Bstatic' lt_prog_compiler_wl_CXX='-Qoption ld ' ;; esac ;; esac ;; lynxos*) ;; m88k*) ;; mvs*) case $cc_basename in cxx*) lt_prog_compiler_pic_CXX='-W c,exportall' ;; *) ;; esac ;; netbsd* | netbsdelf*-gnu) ;; *qnx* | *nto*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. lt_prog_compiler_pic_CXX='-fPIC -shared' ;; osf3* | osf4* | osf5*) case $cc_basename in KCC*) lt_prog_compiler_wl_CXX='--backend -Wl,' ;; RCC*) # Rational C++ 2.4.1 lt_prog_compiler_pic_CXX='-pic' ;; cxx*) # Digital/Compaq C++ lt_prog_compiler_wl_CXX='-Wl,' # Make sure the PIC flag is empty. It appears that all Alpha # Linux and Compaq Tru64 Unix objects are PIC. lt_prog_compiler_pic_CXX= lt_prog_compiler_static_CXX='-non_shared' ;; *) ;; esac ;; psos*) ;; solaris*) case $cc_basename in CC* | sunCC*) # Sun C++ 4.2, 5.x and Centerline C++ lt_prog_compiler_pic_CXX='-KPIC' lt_prog_compiler_static_CXX='-Bstatic' lt_prog_compiler_wl_CXX='-Qoption ld ' ;; gcx*) # Green Hills C++ Compiler lt_prog_compiler_pic_CXX='-PIC' ;; *) ;; esac ;; sunos4*) case $cc_basename in CC*) # Sun C++ 4.x lt_prog_compiler_pic_CXX='-pic' lt_prog_compiler_static_CXX='-Bstatic' ;; lcc*) # Lucid lt_prog_compiler_pic_CXX='-pic' ;; *) ;; esac ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) case $cc_basename in CC*) lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_pic_CXX='-KPIC' lt_prog_compiler_static_CXX='-Bstatic' ;; esac ;; tandem*) case $cc_basename in NCC*) # NonStop-UX NCC 3.20 lt_prog_compiler_pic_CXX='-KPIC' ;; *) ;; esac ;; vxworks*) ;; *) lt_prog_compiler_can_build_shared_CXX=no ;; esac fi case $host_os in # For platforms which do not support PIC, -DPIC is meaningless: *djgpp*) lt_prog_compiler_pic_CXX= ;; *) lt_prog_compiler_pic_CXX="$lt_prog_compiler_pic_CXX -DPIC" ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 $as_echo_n "checking for $compiler option to produce PIC... " >&6; } if ${lt_cv_prog_compiler_pic_CXX+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_pic_CXX=$lt_prog_compiler_pic_CXX fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_CXX" >&5 $as_echo "$lt_cv_prog_compiler_pic_CXX" >&6; } lt_prog_compiler_pic_CXX=$lt_cv_prog_compiler_pic_CXX # # Check to make sure the PIC flag actually works. # if test -n "$lt_prog_compiler_pic_CXX"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works" >&5 $as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works... " >&6; } if ${lt_cv_prog_compiler_pic_works_CXX+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_pic_works_CXX=no ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="$lt_prog_compiler_pic_CXX -DPIC" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_pic_works_CXX=yes fi fi $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works_CXX" >&5 $as_echo "$lt_cv_prog_compiler_pic_works_CXX" >&6; } if test x"$lt_cv_prog_compiler_pic_works_CXX" = xyes; then case $lt_prog_compiler_pic_CXX in "" | " "*) ;; *) lt_prog_compiler_pic_CXX=" $lt_prog_compiler_pic_CXX" ;; esac else lt_prog_compiler_pic_CXX= lt_prog_compiler_can_build_shared_CXX=no fi fi # # Check to make sure the static flag actually works. # wl=$lt_prog_compiler_wl_CXX eval lt_tmp_static_flag=\"$lt_prog_compiler_static_CXX\" { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 $as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } if ${lt_cv_prog_compiler_static_works_CXX+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_static_works_CXX=no save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS $lt_tmp_static_flag" echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then # The linker can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&5 $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_static_works_CXX=yes fi else lt_cv_prog_compiler_static_works_CXX=yes fi fi $RM -r conftest* LDFLAGS="$save_LDFLAGS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works_CXX" >&5 $as_echo "$lt_cv_prog_compiler_static_works_CXX" >&6; } if test x"$lt_cv_prog_compiler_static_works_CXX" = xyes; then : else lt_prog_compiler_static_CXX= fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 $as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } if ${lt_cv_prog_compiler_c_o_CXX+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_c_o_CXX=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then lt_cv_prog_compiler_c_o_CXX=yes fi fi chmod u+w . 2>&5 $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_CXX" >&5 $as_echo "$lt_cv_prog_compiler_c_o_CXX" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 $as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } if ${lt_cv_prog_compiler_c_o_CXX+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_c_o_CXX=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then lt_cv_prog_compiler_c_o_CXX=yes fi fi chmod u+w . 2>&5 $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_CXX" >&5 $as_echo "$lt_cv_prog_compiler_c_o_CXX" >&6; } hard_links="nottested" if test "$lt_cv_prog_compiler_c_o_CXX" = no && test "$need_locks" != no; then # do not overwrite the value of need_locks provided by the user { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 $as_echo_n "checking if we can lock with hard links... " >&6; } hard_links=yes $RM conftest* ln conftest.a conftest.b 2>/dev/null && hard_links=no touch conftest.a ln conftest.a conftest.b 2>&5 || hard_links=no ln conftest.a conftest.b 2>/dev/null && hard_links=no { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 $as_echo "$hard_links" >&6; } if test "$hard_links" = no; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 $as_echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} need_locks=warn fi else need_locks=no fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 $as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' exclude_expsyms_CXX='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' case $host_os in aix[4-9]*) # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to AIX nm, but means don't demangle with GNU nm # Also, AIX nm treats weak defined symbols like other global defined # symbols, whereas GNU nm marks them as "W". if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then export_symbols_cmds_CXX='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' else export_symbols_cmds_CXX='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' fi ;; pw32*) export_symbols_cmds_CXX="$ltdll_cmds" ;; cygwin* | mingw* | cegcc*) case $cc_basename in cl*) exclude_expsyms_CXX='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' ;; *) export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols' exclude_expsyms_CXX='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname' ;; esac ;; linux* | k*bsd*-gnu | gnu*) link_all_deplibs_CXX=no ;; *) export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5 $as_echo "$ld_shlibs_CXX" >&6; } test "$ld_shlibs_CXX" = no && can_build_shared=no with_gnu_ld_CXX=$with_gnu_ld # # Do we need to explicitly link libc? # case "x$archive_cmds_need_lc_CXX" in x|xyes) # Assume -lc should be added archive_cmds_need_lc_CXX=yes if test "$enable_shared" = yes && test "$GCC" = yes; then case $archive_cmds_CXX in *'~'*) # FIXME: we may have to deal with multi-command sequences. ;; '$CC '*) # Test whether the compiler implicitly links with -lc since on some # systems, -lgcc has to come before -lc. If gcc already passes -lc # to ld, don't add -lc before -lgcc. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 $as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } if ${lt_cv_archive_cmds_need_lc_CXX+:} false; then : $as_echo_n "(cached) " >&6 else $RM conftest* echo "$lt_simple_compile_test_code" > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } 2>conftest.err; then soname=conftest lib=conftest libobjs=conftest.$ac_objext deplibs= wl=$lt_prog_compiler_wl_CXX pic_flag=$lt_prog_compiler_pic_CXX compiler_flags=-v linker_flags=-v verstring= output_objdir=. libname=conftest lt_save_allow_undefined_flag=$allow_undefined_flag_CXX allow_undefined_flag_CXX= if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds_CXX 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 (eval $archive_cmds_CXX 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } then lt_cv_archive_cmds_need_lc_CXX=no else lt_cv_archive_cmds_need_lc_CXX=yes fi allow_undefined_flag_CXX=$lt_save_allow_undefined_flag else cat conftest.err 1>&5 fi $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc_CXX" >&5 $as_echo "$lt_cv_archive_cmds_need_lc_CXX" >&6; } archive_cmds_need_lc_CXX=$lt_cv_archive_cmds_need_lc_CXX ;; esac fi ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 $as_echo_n "checking dynamic linker characteristics... " >&6; } library_names_spec= libname_spec='lib$name' soname_spec= shrext_cmds=".so" postinstall_cmds= postuninstall_cmds= finish_cmds= finish_eval= shlibpath_var= shlibpath_overrides_runpath=unknown version_type=none dynamic_linker="$host_os ld.so" sys_lib_dlsearch_path_spec="/lib /usr/lib" need_lib_prefix=unknown hardcode_into_libs=no # when you set need_version to no, make sure it does not cause -set_version # flags to be left without arguments need_version=unknown case $host_os in aix3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' shlibpath_var=LIBPATH # AIX 3 has no versioning support, so we append a major version to the name. soname_spec='${libname}${release}${shared_ext}$major' ;; aix[4-9]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no hardcode_into_libs=yes if test "$host_cpu" = ia64; then # AIX 5 supports IA64 library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH else # With GCC up to 2.95.x, collect2 would create an import file # for dependence libraries. The import file would start with # the line `#! .'. This would cause the generated library to # depend on `.', always an invalid library. This was fixed in # development snapshots of GCC prior to 3.0. case $host_os in aix4 | aix4.[01] | aix4.[01].*) if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' echo ' yes ' echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then : else can_build_shared=no fi ;; esac # AIX (on Power*) has no versioning support, so currently we can not hardcode correct # soname into executable. Probably we can add versioning support to # collect2, so additional links can be useful in future. if test "$aix_use_runtimelinking" = yes; then # If using run time linking (on AIX 4.2 or later) use lib.so # instead of lib.a to let people know that these are not # typical AIX shared libraries. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' else # We preserve .a as extension for shared libraries through AIX4.2 # and later when we are not doing run time linking. library_names_spec='${libname}${release}.a $libname.a' soname_spec='${libname}${release}${shared_ext}$major' fi shlibpath_var=LIBPATH fi ;; amigaos*) case $host_cpu in powerpc) # Since July 2007 AmigaOS4 officially supports .so libraries. # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ;; m68k) library_names_spec='$libname.ixlibrary $libname.a' # Create ${libname}_ixlibrary.a entries in /sys/libs. finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' ;; esac ;; beos*) library_names_spec='${libname}${shared_ext}' dynamic_linker="$host_os ld.so" shlibpath_var=LIBRARY_PATH ;; bsdi[45]*) version_type=linux # correct to gnu/linux during the next big refactor need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" # the default ld.so.conf also contains /usr/contrib/lib and # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow # libtool to hard-code these into programs ;; cygwin* | mingw* | pw32* | cegcc*) version_type=windows shrext_cmds=".dll" need_version=no need_lib_prefix=no case $GCC,$cc_basename in yes,*) # gcc library_names_spec='$libname.dll.a' # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \${file}`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes case $host_os in cygwin*) # Cygwin DLLs use 'cyg' prefix rather than 'lib' soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' ;; mingw* | cegcc*) # MinGW DLLs use traditional 'lib' prefix soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' ;; pw32*) # pw32 DLLs use 'pw' prefix rather than 'lib' library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' ;; esac dynamic_linker='Win32 ld.exe' ;; *,cl*) # Native MSVC libname_spec='$name' soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' library_names_spec='${libname}.dll.lib' case $build_os in mingw*) sys_lib_search_path_spec= lt_save_ifs=$IFS IFS=';' for lt_path in $LIB do IFS=$lt_save_ifs # Let DOS variable expansion print the short 8.3 style file name. lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" done IFS=$lt_save_ifs # Convert to MSYS style. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'` ;; cygwin*) # Convert to unix form, then to dos form, then back to unix form # but this time dos style (no spaces!) so that the unix form looks # like /cygdrive/c/PROGRA~1:/cygdr... sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ;; *) sys_lib_search_path_spec="$LIB" if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then # It is most probably a Windows format PATH. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` else sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` fi # FIXME: find the short name or the path components, as spaces are # common. (e.g. "Program Files" -> "PROGRA~1") ;; esac # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \${file}`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes dynamic_linker='Win32 link.exe' ;; *) # Assume MSVC wrapper library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' dynamic_linker='Win32 ld.exe' ;; esac # FIXME: first we should search . and the directory the executable is in shlibpath_var=PATH ;; darwin* | rhapsody*) dynamic_linker="$host_os dyld" version_type=darwin need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' soname_spec='${libname}${release}${major}$shared_ext' shlibpath_overrides_runpath=yes shlibpath_var=DYLD_LIBRARY_PATH shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' ;; dgux*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH ;; freebsd* | dragonfly*) # DragonFly does not have aout. When/if they implement a new # versioning mechanism, adjust this. if test -x /usr/bin/objformat; then objformat=`/usr/bin/objformat` else case $host_os in freebsd[23].*) objformat=aout ;; *) objformat=elf ;; esac fi version_type=freebsd-$objformat case $version_type in freebsd-elf*) library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' need_version=no need_lib_prefix=no ;; freebsd-*) library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' need_version=yes ;; esac shlibpath_var=LD_LIBRARY_PATH case $host_os in freebsd2.*) shlibpath_overrides_runpath=yes ;; freebsd3.[01]* | freebsdelf3.[01]*) shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; *) # from 4.6 on, and DragonFly shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; esac ;; gnu*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; haiku*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no dynamic_linker="$host_os runtime_loader" library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LIBRARY_PATH shlibpath_overrides_runpath=yes sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' hardcode_into_libs=yes ;; hpux9* | hpux10* | hpux11*) # Give a soname corresponding to the major version so that dld.sl refuses to # link against other versions. version_type=sunos need_lib_prefix=no need_version=no case $host_cpu in ia64*) shrext_cmds='.so' hardcode_into_libs=yes dynamic_linker="$host_os dld.so" shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' if test "X$HPUX_IA64_MODE" = X32; then sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" else sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" fi sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; hppa*64*) shrext_cmds='.sl' hardcode_into_libs=yes dynamic_linker="$host_os dld.sl" shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; *) shrext_cmds='.sl' dynamic_linker="$host_os dld.sl" shlibpath_var=SHLIB_PATH shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' ;; esac # HP-UX runs *really* slowly unless shared libraries are mode 555, ... postinstall_cmds='chmod 555 $lib' # or fails outright, so override atomically: install_override_mode=555 ;; interix[3-9]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; irix5* | irix6* | nonstopux*) case $host_os in nonstopux*) version_type=nonstopux ;; *) if test "$lt_cv_prog_gnu_ld" = yes; then version_type=linux # correct to gnu/linux during the next big refactor else version_type=irix fi ;; esac need_lib_prefix=no need_version=no soname_spec='${libname}${release}${shared_ext}$major' library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' case $host_os in irix5* | nonstopux*) libsuff= shlibsuff= ;; *) case $LD in # libtool.m4 will add one of these switches to LD *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= libmagic=32-bit;; *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 libmagic=N32;; *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 libmagic=64-bit;; *) libsuff= shlibsuff= libmagic=never-match;; esac ;; esac shlibpath_var=LD_LIBRARY${shlibsuff}_PATH shlibpath_overrides_runpath=no sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" hardcode_into_libs=yes ;; # No shared lib support for Linux oldld, aout, or coff. linux*oldld* | linux*aout* | linux*coff*) dynamic_linker=no ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no # Some binutils ld are patched to set DT_RUNPATH if ${lt_cv_shlibpath_overrides_runpath+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_shlibpath_overrides_runpath=no save_LDFLAGS=$LDFLAGS save_libdir=$libdir eval "libdir=/foo; wl=\"$lt_prog_compiler_wl_CXX\"; \ LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec_CXX\"" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then : lt_cv_shlibpath_overrides_runpath=yes fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LDFLAGS=$save_LDFLAGS libdir=$save_libdir fi shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes # Append ld.so.conf contents to the search path if test -f /etc/ld.so.conf; then lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" fi # We used to test for /lib/ld.so.1 and disable shared libraries on # powerpc, because MkLinux only supported shared libraries with the # GNU dynamic linker. Since this was broken with cross compilers, # most powerpc-linux boxes support dynamic linking these days and # people can always --disable-shared, the test was removed, and we # assume the GNU/Linux dynamic linker is in use. dynamic_linker='GNU/Linux ld.so' ;; netbsdelf*-gnu) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='NetBSD ld.elf_so' ;; netbsd*) version_type=sunos need_lib_prefix=no need_version=no if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' dynamic_linker='NetBSD (a.out) ld.so' else library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' dynamic_linker='NetBSD ld.elf_so' fi shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; newsos6) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; *nto* | *qnx*) version_type=qnx need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='ldqnx.so' ;; openbsd*) version_type=sunos sys_lib_dlsearch_path_spec="/usr/lib" need_lib_prefix=no # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. case $host_os in openbsd3.3 | openbsd3.3.*) need_version=yes ;; *) need_version=no ;; esac library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' shlibpath_var=LD_LIBRARY_PATH if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then case $host_os in openbsd2.[89] | openbsd2.[89].*) shlibpath_overrides_runpath=no ;; *) shlibpath_overrides_runpath=yes ;; esac else shlibpath_overrides_runpath=yes fi ;; os2*) libname_spec='$name' shrext_cmds=".dll" need_lib_prefix=no library_names_spec='$libname${shared_ext} $libname.a' dynamic_linker='OS/2 ld.exe' shlibpath_var=LIBPATH ;; osf3* | osf4* | osf5*) version_type=osf need_lib_prefix=no need_version=no soname_spec='${libname}${release}${shared_ext}$major' library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" ;; rdos*) dynamic_linker=no ;; solaris*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes # ldd complains unless libraries are executable postinstall_cmds='chmod +x $lib' ;; sunos4*) version_type=sunos library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes if test "$with_gnu_ld" = yes; then need_lib_prefix=no fi need_version=yes ;; sysv4 | sysv4.3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH case $host_vendor in sni) shlibpath_overrides_runpath=no need_lib_prefix=no runpath_var=LD_RUN_PATH ;; siemens) need_lib_prefix=no ;; motorola) need_lib_prefix=no need_version=no shlibpath_overrides_runpath=no sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' ;; esac ;; sysv4*MP*) if test -d /usr/nec ;then version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' soname_spec='$libname${shared_ext}.$major' shlibpath_var=LD_LIBRARY_PATH fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) version_type=freebsd-elf need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes if test "$with_gnu_ld" = yes; then sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' else sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' case $host_os in sco3.2v5*) sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" ;; esac fi sys_lib_dlsearch_path_spec='/usr/lib' ;; tpf*) # TPF is a cross-target only. Preferred cross-host = GNU/Linux. version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; uts4*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH ;; *) dynamic_linker=no ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 $as_echo "$dynamic_linker" >&6; } test "$dynamic_linker" = no && can_build_shared=no variables_saved_for_relink="PATH $shlibpath_var $runpath_var" if test "$GCC" = yes; then variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" fi if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" fi if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 $as_echo_n "checking how to hardcode library paths into programs... " >&6; } hardcode_action_CXX= if test -n "$hardcode_libdir_flag_spec_CXX" || test -n "$runpath_var_CXX" || test "X$hardcode_automatic_CXX" = "Xyes" ; then # We can hardcode non-existent directories. if test "$hardcode_direct_CXX" != no && # If the only mechanism to avoid hardcoding is shlibpath_var, we # have to relink, otherwise we might link with an installed library # when we should be linking with a yet-to-be-installed one ## test "$_LT_TAGVAR(hardcode_shlibpath_var, CXX)" != no && test "$hardcode_minus_L_CXX" != no; then # Linking always hardcodes the temporary library directory. hardcode_action_CXX=relink else # We can link without hardcoding, and we can hardcode nonexisting dirs. hardcode_action_CXX=immediate fi else # We cannot hardcode anything, or else we can only hardcode existing # directories. hardcode_action_CXX=unsupported fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action_CXX" >&5 $as_echo "$hardcode_action_CXX" >&6; } if test "$hardcode_action_CXX" = relink || test "$inherit_rpath_CXX" = yes; then # Fast installation is not supported enable_fast_install=no elif test "$shlibpath_overrides_runpath" = yes || test "$enable_shared" = no; then # Fast installation is not necessary enable_fast_install=needless fi fi # test -n "$compiler" CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS LDCXX=$LD LD=$lt_save_LD GCC=$lt_save_GCC with_gnu_ld=$lt_save_with_gnu_ld lt_cv_path_LDCXX=$lt_cv_path_LD lt_cv_path_LD=$lt_save_path_LD lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld fi # test "$_lt_caught_CXX_error" != yes ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu ac_config_commands="$ac_config_commands libtool" # Only expand once: # TODO(chandlerc@google.com): Currently we aren't running the Python tests # against the interpreter detected by AM_PATH_PYTHON, and so we condition # HAVE_PYTHON by requiring "python" to be in the PATH, and that interpreter's # version to be >= 2.3. This will allow the scripts to use a "/usr/bin/env" # hashbang. PYTHON= # We *do not* allow the user to specify a python interpreter # Extract the first word of "python", so it can be a program name with args. set dummy python; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_PYTHON+:} false; then : $as_echo_n "(cached) " >&6 else case $PYTHON in [\\/]* | ?:[\\/]*) ac_cv_path_PYTHON="$PYTHON" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_PYTHON="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_PYTHON" && ac_cv_path_PYTHON=":" ;; esac fi PYTHON=$ac_cv_path_PYTHON if test -n "$PYTHON"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PYTHON" >&5 $as_echo "$PYTHON" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "$PYTHON" != ":"; then : prog="import sys # split strings by '.' and convert to numeric. Append some zeros # because we need at least 4 digits for the hex conversion. # map returns an iterator in Python 3.0 and a list in 2.x minver = list(map(int, '2.3'.split('.'))) + [0, 0, 0] minverhex = 0 # xrange is not present in Python 3.0 and range returns an iterator for i in list(range(0, 4)): minverhex = (minverhex << 8) + minver[i] sys.exit(sys.hexversion < minverhex)" if { echo "$as_me:$LINENO: $PYTHON -c "$prog"" >&5 ($PYTHON -c "$prog") >&5 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then : : else PYTHON=":" fi fi if test "$PYTHON" != ":"; then HAVE_PYTHON_TRUE= HAVE_PYTHON_FALSE='#' else HAVE_PYTHON_TRUE='#' HAVE_PYTHON_FALSE= fi # Configure pthreads. # Check whether --with-pthreads was given. if test "${with_pthreads+set}" = set; then : withval=$with_pthreads; with_pthreads=$withval else with_pthreads=check fi have_pthreads=no if test "x$with_pthreads" != "xno"; then : ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu acx_pthread_ok=no # We used to check for pthread.h first, but this fails if pthread.h # requires special compiler flags (e.g. on True64 or Sequent). # It gets checked for in the link test anyway. # First of all, check if the user has set any of the PTHREAD_LIBS, # etcetera environment variables, and if threads linking works using # them: if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $PTHREAD_CFLAGS" save_LIBS="$LIBS" LIBS="$PTHREAD_LIBS $LIBS" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS" >&5 $as_echo_n "checking for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char pthread_join (); int main () { return pthread_join (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : acx_pthread_ok=yes fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $acx_pthread_ok" >&5 $as_echo "$acx_pthread_ok" >&6; } if test x"$acx_pthread_ok" = xno; then PTHREAD_LIBS="" PTHREAD_CFLAGS="" fi LIBS="$save_LIBS" CFLAGS="$save_CFLAGS" fi # We must check for the threads library under a number of different # names; the ordering is very important because some systems # (e.g. DEC) have both -lpthread and -lpthreads, where one of the # libraries is broken (non-POSIX). # Create a list of thread flags to try. Items starting with a "-" are # C compiler flags, and other items are library names, except for "none" # which indicates that we try without any flags at all, and "pthread-config" # which is a program returning the flags for the Pth emulation library. acx_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config" # The ordering *is* (sometimes) important. Some notes on the # individual items follow: # pthreads: AIX (must check this before -lpthread) # none: in case threads are in libc; should be tried before -Kthread and # other compiler flags to prevent continual compiler warnings # -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h) # -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able) # lthread: LinuxThreads port on FreeBSD (also preferred to -pthread) # -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads) # -pthreads: Solaris/gcc # -mthreads: Mingw32/gcc, Lynx/gcc # -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it # doesn't hurt to check since this sometimes defines pthreads too; # also defines -D_REENTRANT) # ... -mt is also the pthreads flag for HP/aCC # pthread: Linux, etcetera # --thread-safe: KAI C++ # pthread-config: use pthread-config program (for GNU Pth library) case "${host_cpu}-${host_os}" in *solaris*) # On Solaris (at least, for some versions), libc contains stubbed # (non-functional) versions of the pthreads routines, so link-based # tests will erroneously succeed. (We need to link with -pthreads/-mt/ # -lpthread.) (The stubs are missing pthread_cleanup_push, or rather # a function called by this macro, so we could check for that, but # who knows whether they'll stub that too in a future libc.) So, # we'll just look for -pthreads and -lpthread first: acx_pthread_flags="-pthreads pthread -mt -pthread $acx_pthread_flags" ;; esac if test x"$acx_pthread_ok" = xno; then for flag in $acx_pthread_flags; do case $flag in none) { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether pthreads work without any flags" >&5 $as_echo_n "checking whether pthreads work without any flags... " >&6; } ;; -*) { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether pthreads work with $flag" >&5 $as_echo_n "checking whether pthreads work with $flag... " >&6; } PTHREAD_CFLAGS="$flag" ;; pthread-config) # Extract the first word of "pthread-config", so it can be a program name with args. set dummy pthread-config; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_acx_pthread_config+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$acx_pthread_config"; then ac_cv_prog_acx_pthread_config="$acx_pthread_config" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_acx_pthread_config="yes" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_prog_acx_pthread_config" && ac_cv_prog_acx_pthread_config="no" fi fi acx_pthread_config=$ac_cv_prog_acx_pthread_config if test -n "$acx_pthread_config"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $acx_pthread_config" >&5 $as_echo "$acx_pthread_config" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test x"$acx_pthread_config" = xno; then continue; fi PTHREAD_CFLAGS="`pthread-config --cflags`" PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`" ;; *) { $as_echo "$as_me:${as_lineno-$LINENO}: checking for the pthreads library -l$flag" >&5 $as_echo_n "checking for the pthreads library -l$flag... " >&6; } PTHREAD_LIBS="-l$flag" ;; esac save_LIBS="$LIBS" save_CFLAGS="$CFLAGS" LIBS="$PTHREAD_LIBS $LIBS" CFLAGS="$CFLAGS $PTHREAD_CFLAGS" # Check for various functions. We must include pthread.h, # since some functions may be macros. (On the Sequent, we # need a special flag -Kthread to make this header compile.) # We check for pthread_join because it is in -lpthread on IRIX # while pthread_create is in libc. We check for pthread_attr_init # due to DEC craziness with -lpthreads. We check for # pthread_cleanup_push because it is one of the few pthread # functions on Solaris that doesn't have a non-functional libc stub. # We try pthread_create on general principles. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { pthread_t th; pthread_join(th, 0); pthread_attr_init(0); pthread_cleanup_push(0, 0); pthread_create(0,0,0,0); pthread_cleanup_pop(0); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : acx_pthread_ok=yes fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS="$save_LIBS" CFLAGS="$save_CFLAGS" { $as_echo "$as_me:${as_lineno-$LINENO}: result: $acx_pthread_ok" >&5 $as_echo "$acx_pthread_ok" >&6; } if test "x$acx_pthread_ok" = xyes; then break; fi PTHREAD_LIBS="" PTHREAD_CFLAGS="" done fi # Various other checks: if test "x$acx_pthread_ok" = xyes; then save_LIBS="$LIBS" LIBS="$PTHREAD_LIBS $LIBS" save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $PTHREAD_CFLAGS" # Detect AIX lossage: JOINABLE attribute is called UNDETACHED. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for joinable pthread attribute" >&5 $as_echo_n "checking for joinable pthread attribute... " >&6; } attr_name=unknown for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { int attr=$attr; return attr; ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : attr_name=$attr; break fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext done { $as_echo "$as_me:${as_lineno-$LINENO}: result: $attr_name" >&5 $as_echo "$attr_name" >&6; } if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then cat >>confdefs.h <<_ACEOF #define PTHREAD_CREATE_JOINABLE $attr_name _ACEOF fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking if more special flags are required for pthreads" >&5 $as_echo_n "checking if more special flags are required for pthreads... " >&6; } flag=no case "${host_cpu}-${host_os}" in *-aix* | *-freebsd* | *-darwin*) flag="-D_THREAD_SAFE";; *solaris* | *-osf* | *-hpux*) flag="-D_REENTRANT";; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${flag}" >&5 $as_echo "${flag}" >&6; } if test "x$flag" != xno; then PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS" fi LIBS="$save_LIBS" CFLAGS="$save_CFLAGS" # More AIX lossage: must compile with xlc_r or cc_r if test x"$GCC" != xyes; then for ac_prog in xlc_r cc_r do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_PTHREAD_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$PTHREAD_CC"; then ac_cv_prog_PTHREAD_CC="$PTHREAD_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_PTHREAD_CC="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi PTHREAD_CC=$ac_cv_prog_PTHREAD_CC if test -n "$PTHREAD_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PTHREAD_CC" >&5 $as_echo "$PTHREAD_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$PTHREAD_CC" && break done test -n "$PTHREAD_CC" || PTHREAD_CC="${CC}" else PTHREAD_CC=$CC fi # The next part tries to detect GCC inconsistency with -shared on some # architectures and systems. The problem is that in certain # configurations, when -shared is specified, GCC "forgets" to # internally use various flags which are still necessary. # # Prepare the flags # save_CFLAGS="$CFLAGS" save_LIBS="$LIBS" save_CC="$CC" # Try with the flags determined by the earlier checks. # # -Wl,-z,defs forces link-time symbol resolution, so that the # linking checks with -shared actually have any value # # FIXME: -fPIC is required for -shared on many architectures, # so we specify it here, but the right way would probably be to # properly detect whether it is actually required. CFLAGS="-shared -fPIC -Wl,-z,defs $CFLAGS $PTHREAD_CFLAGS" LIBS="$PTHREAD_LIBS $LIBS" CC="$PTHREAD_CC" # In order not to create several levels of indentation, we test # the value of "$done" until we find the cure or run out of ideas. done="no" # First, make sure the CFLAGS we added are actually accepted by our # compiler. If not (and OS X's ld, for instance, does not accept -z), # then we can't do this test. if test x"$done" = xno; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to check for GCC pthread/shared inconsistencies" >&5 $as_echo_n "checking whether to check for GCC pthread/shared inconsistencies... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : else done=yes fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test "x$done" = xyes ; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi fi if test x"$done" = xno; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -pthread is sufficient with -shared" >&5 $as_echo_n "checking whether -pthread is sufficient with -shared... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { pthread_t th; pthread_join(th, 0); pthread_attr_init(0); pthread_cleanup_push(0, 0); pthread_create(0,0,0,0); pthread_cleanup_pop(0); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : done=yes fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test "x$done" = xyes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi # # Linux gcc on some architectures such as mips/mipsel forgets # about -lpthread # if test x"$done" = xno; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lpthread fixes that" >&5 $as_echo_n "checking whether -lpthread fixes that... " >&6; } LIBS="-lpthread $PTHREAD_LIBS $save_LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { pthread_t th; pthread_join(th, 0); pthread_attr_init(0); pthread_cleanup_push(0, 0); pthread_create(0,0,0,0); pthread_cleanup_pop(0); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : done=yes fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test "x$done" = xyes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } PTHREAD_LIBS="-lpthread $PTHREAD_LIBS" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi # # FreeBSD 4.10 gcc forgets to use -lc_r instead of -lc # if test x"$done" = xno; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc_r fixes that" >&5 $as_echo_n "checking whether -lc_r fixes that... " >&6; } LIBS="-lc_r $PTHREAD_LIBS $save_LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { pthread_t th; pthread_join(th, 0); pthread_attr_init(0); pthread_cleanup_push(0, 0); pthread_create(0,0,0,0); pthread_cleanup_pop(0); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : done=yes fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test "x$done" = xyes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } PTHREAD_LIBS="-lc_r $PTHREAD_LIBS" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test x"$done" = xno; then # OK, we have run out of ideas { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Impossible to determine how to use pthreads with shared libraries" >&5 $as_echo "$as_me: WARNING: Impossible to determine how to use pthreads with shared libraries" >&2;} # so it's not safe to assume that we may use pthreads acx_pthread_ok=no fi CFLAGS="$save_CFLAGS" LIBS="$save_LIBS" CC="$save_CC" else PTHREAD_CC="$CC" fi # Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND: if test x"$acx_pthread_ok" = xyes; then $as_echo "#define HAVE_PTHREAD 1" >>confdefs.h : else acx_pthread_ok=no if test "x$with_pthreads" != "xcheck"; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "--with-pthreads was specified, but unable to be used See \`config.log' for more details" "$LINENO" 5; } fi fi ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu have_pthreads="$acx_pthread_ok" fi if test "x$have_pthreads" = "xyes"; then HAVE_PTHREADS_TRUE= HAVE_PTHREADS_FALSE='#' else HAVE_PTHREADS_TRUE='#' HAVE_PTHREADS_FALSE= fi # TODO(chandlerc@google.com) Check for the necessary system headers. # TODO(chandlerc@google.com) Check the types, structures, and other compiler # and architecture characteristics. # Output the generated files. No further autoconf macros may be used. cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs, see configure's option --config-cache. # It is not useful on other systems. If it contains results you don't # want to keep, you may remove or edit it. # # config.status only pays attention to the cache file if you give it # the --recheck option to rerun configure. # # `ac_cv_env_foo' variables (set or unset) will be overridden when # loading this file, other *unset* `ac_cv_foo' will be assigned the # following values. _ACEOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, we kill variables containing newlines. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. ( for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space=' '; set) 2>&1` in #( *${as_nl}ac_space=\ *) # `set' does not quote correctly, so add quotes: double-quote # substitution turns \\\\ into \\, and sed turns \\ into \. sed -n \ "s/'/'\\\\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" ;; #( *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) | sed ' /^ac_cv_env_/b end t clear :clear s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ t end s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ :end' >>confcache if diff "$cache_file" confcache >/dev/null 2>&1; then :; else if test -w "$cache_file"; then if test "x$cache_file" != "x/dev/null"; then { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 $as_echo "$as_me: updating cache $cache_file" >&6;} if test ! -f "$cache_file" || test -h "$cache_file"; then cat confcache >"$cache_file" else case $cache_file in #( */* | ?:*) mv -f confcache "$cache_file"$$ && mv -f "$cache_file"$$ "$cache_file" ;; #( *) mv -f confcache "$cache_file" ;; esac fi fi else { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 $as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} fi fi rm -f confcache test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' DEFS=-DHAVE_CONFIG_H ac_libobjs= ac_ltlibobjs= U= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' ac_i=`$as_echo "$ac_i" | sed "$ac_script"` # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR # will be set to the directory where LIBOBJS objects are built. as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' done LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs if test -n "$EXEEXT"; then am__EXEEXT_TRUE= am__EXEEXT_FALSE='#' else am__EXEEXT_TRUE='#' am__EXEEXT_FALSE= fi if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then as_fn_error $? "conditional \"AMDEP\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then as_fn_error $? "conditional \"am__fastdepCC\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then as_fn_error $? "conditional \"am__fastdepCXX\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_PYTHON_TRUE}" && test -z "${HAVE_PYTHON_FALSE}"; then as_fn_error $? "conditional \"HAVE_PYTHON\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_PTHREADS_TRUE}" && test -z "${HAVE_PTHREADS_FALSE}"; then as_fn_error $? "conditional \"HAVE_PTHREADS\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi : "${CONFIG_STATUS=./config.status}" ac_write_fail=0 ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 $as_echo "$as_me: creating $CONFIG_STATUS" >&6;} as_write_fail=0 cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 #! $SHELL # Generated by $as_me. # Run this file to recreate the current configuration. # Compiler output produced by configure, useful for debugging # configure, is in config.log if it exists. debug=false ac_cs_recheck=false ac_cs_silent=false SHELL=\${CONFIG_SHELL-$SHELL} export SHELL _ASEOF cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -p'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -p' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' fi else as_ln_s='cp -p' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi if test -x / >/dev/null 2>&1; then as_test_x='test -x' else if ls -dL / >/dev/null 2>&1; then as_ls_L_option=L else as_ls_L_option= fi as_test_x=' eval sh -c '\'' if test -d "$1"; then test -d "$1/."; else case $1 in #( -*)set "./$1";; esac; case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( ???[sx]*):;;*)false;;esac;fi '\'' sh ' fi as_executable_p=$as_test_x # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" exec 6>&1 ## ----------------------------------- ## ## Main body of $CONFIG_STATUS script. ## ## ----------------------------------- ## _ASEOF test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Save the log message, to keep $0 and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" This file was extended by Google C++ Testing Framework $as_me 1.7.0, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS CONFIG_LINKS = $CONFIG_LINKS CONFIG_COMMANDS = $CONFIG_COMMANDS $ $0 $@ on `(hostname || uname -n) 2>/dev/null | sed 1q` " _ACEOF case $ac_config_files in *" "*) set x $ac_config_files; shift; ac_config_files=$*;; esac case $ac_config_headers in *" "*) set x $ac_config_headers; shift; ac_config_headers=$*;; esac cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # Files that config.status was made for. config_files="$ac_config_files" config_headers="$ac_config_headers" config_commands="$ac_config_commands" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 ac_cs_usage="\ \`$as_me' instantiates files and other configuration actions from templates according to the current configuration. Unless the files and actions are specified as TAGs, all are instantiated by default. Usage: $0 [OPTION]... [TAG]... -h, --help print this help, then exit -V, --version print version number and configuration settings, then exit --config print configuration, then exit -q, --quiet, --silent do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions --file=FILE[:TEMPLATE] instantiate the configuration file FILE --header=FILE[:TEMPLATE] instantiate the configuration header FILE Configuration files: $config_files Configuration headers: $config_headers Configuration commands: $config_commands Report bugs to ." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ Google C++ Testing Framework config.status 1.7.0 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" Copyright (C) 2010 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." ac_pwd='$ac_pwd' srcdir='$srcdir' INSTALL='$INSTALL' MKDIR_P='$MKDIR_P' AWK='$AWK' test -n "\$AWK" || AWK=awk _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # The default lists apply if the user does not specify any file. ac_need_defaults=: while test $# != 0 do case $1 in --*=?*) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` ac_shift=: ;; --*=) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg= ac_shift=: ;; *) ac_option=$1 ac_optarg=$2 ac_shift=shift ;; esac case $ac_option in # Handling of the options. -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) $as_echo "$ac_cs_version"; exit ;; --config | --confi | --conf | --con | --co | --c ) $as_echo "$ac_cs_config"; exit ;; --debug | --debu | --deb | --de | --d | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; '') as_fn_error $? "missing file argument" ;; esac as_fn_append CONFIG_FILES " '$ac_optarg'" ac_need_defaults=false;; --header | --heade | --head | --hea ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; esac as_fn_append CONFIG_HEADERS " '$ac_optarg'" ac_need_defaults=false;; --he | --h) # Conflict between --help and --header as_fn_error $? "ambiguous option: \`$1' Try \`$0 --help' for more information.";; --help | --hel | -h ) $as_echo "$ac_cs_usage"; exit ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; # This is an error. -*) as_fn_error $? "unrecognized option: \`$1' Try \`$0 --help' for more information." ;; *) as_fn_append ac_config_targets " $1" ac_need_defaults=false ;; esac shift done ac_configure_extra_args= if $ac_cs_silent; then exec 6>/dev/null ac_configure_extra_args="$ac_configure_extra_args --silent" fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 if \$ac_cs_recheck; then set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion shift \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 CONFIG_SHELL='$SHELL' export CONFIG_SHELL exec "\$@" fi _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 exec 5>>config.log { echo sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX $as_echo "$ac_log" } >&5 _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # # INIT-COMMANDS # AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH sed_quote_subst='$sed_quote_subst' double_quote_subst='$double_quote_subst' delay_variable_subst='$delay_variable_subst' macro_version='`$ECHO "$macro_version" | $SED "$delay_single_quote_subst"`' macro_revision='`$ECHO "$macro_revision" | $SED "$delay_single_quote_subst"`' enable_shared='`$ECHO "$enable_shared" | $SED "$delay_single_quote_subst"`' enable_static='`$ECHO "$enable_static" | $SED "$delay_single_quote_subst"`' pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`' enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`' SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`' ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`' PATH_SEPARATOR='`$ECHO "$PATH_SEPARATOR" | $SED "$delay_single_quote_subst"`' host_alias='`$ECHO "$host_alias" | $SED "$delay_single_quote_subst"`' host='`$ECHO "$host" | $SED "$delay_single_quote_subst"`' host_os='`$ECHO "$host_os" | $SED "$delay_single_quote_subst"`' build_alias='`$ECHO "$build_alias" | $SED "$delay_single_quote_subst"`' build='`$ECHO "$build" | $SED "$delay_single_quote_subst"`' build_os='`$ECHO "$build_os" | $SED "$delay_single_quote_subst"`' SED='`$ECHO "$SED" | $SED "$delay_single_quote_subst"`' Xsed='`$ECHO "$Xsed" | $SED "$delay_single_quote_subst"`' GREP='`$ECHO "$GREP" | $SED "$delay_single_quote_subst"`' EGREP='`$ECHO "$EGREP" | $SED "$delay_single_quote_subst"`' FGREP='`$ECHO "$FGREP" | $SED "$delay_single_quote_subst"`' LD='`$ECHO "$LD" | $SED "$delay_single_quote_subst"`' NM='`$ECHO "$NM" | $SED "$delay_single_quote_subst"`' LN_S='`$ECHO "$LN_S" | $SED "$delay_single_quote_subst"`' max_cmd_len='`$ECHO "$max_cmd_len" | $SED "$delay_single_quote_subst"`' ac_objext='`$ECHO "$ac_objext" | $SED "$delay_single_quote_subst"`' exeext='`$ECHO "$exeext" | $SED "$delay_single_quote_subst"`' lt_unset='`$ECHO "$lt_unset" | $SED "$delay_single_quote_subst"`' lt_SP2NL='`$ECHO "$lt_SP2NL" | $SED "$delay_single_quote_subst"`' lt_NL2SP='`$ECHO "$lt_NL2SP" | $SED "$delay_single_quote_subst"`' lt_cv_to_host_file_cmd='`$ECHO "$lt_cv_to_host_file_cmd" | $SED "$delay_single_quote_subst"`' lt_cv_to_tool_file_cmd='`$ECHO "$lt_cv_to_tool_file_cmd" | $SED "$delay_single_quote_subst"`' reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`' reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`' OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`' deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`' file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`' file_magic_glob='`$ECHO "$file_magic_glob" | $SED "$delay_single_quote_subst"`' want_nocaseglob='`$ECHO "$want_nocaseglob" | $SED "$delay_single_quote_subst"`' DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`' sharedlib_from_linklib_cmd='`$ECHO "$sharedlib_from_linklib_cmd" | $SED "$delay_single_quote_subst"`' AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`' AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`' archiver_list_spec='`$ECHO "$archiver_list_spec" | $SED "$delay_single_quote_subst"`' STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`' RANLIB='`$ECHO "$RANLIB" | $SED "$delay_single_quote_subst"`' old_postinstall_cmds='`$ECHO "$old_postinstall_cmds" | $SED "$delay_single_quote_subst"`' old_postuninstall_cmds='`$ECHO "$old_postuninstall_cmds" | $SED "$delay_single_quote_subst"`' old_archive_cmds='`$ECHO "$old_archive_cmds" | $SED "$delay_single_quote_subst"`' lock_old_archive_extraction='`$ECHO "$lock_old_archive_extraction" | $SED "$delay_single_quote_subst"`' CC='`$ECHO "$CC" | $SED "$delay_single_quote_subst"`' CFLAGS='`$ECHO "$CFLAGS" | $SED "$delay_single_quote_subst"`' compiler='`$ECHO "$compiler" | $SED "$delay_single_quote_subst"`' GCC='`$ECHO "$GCC" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`' nm_file_list_spec='`$ECHO "$nm_file_list_spec" | $SED "$delay_single_quote_subst"`' lt_sysroot='`$ECHO "$lt_sysroot" | $SED "$delay_single_quote_subst"`' objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`' MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_static='`$ECHO "$lt_prog_compiler_static" | $SED "$delay_single_quote_subst"`' lt_cv_prog_compiler_c_o='`$ECHO "$lt_cv_prog_compiler_c_o" | $SED "$delay_single_quote_subst"`' need_locks='`$ECHO "$need_locks" | $SED "$delay_single_quote_subst"`' MANIFEST_TOOL='`$ECHO "$MANIFEST_TOOL" | $SED "$delay_single_quote_subst"`' DSYMUTIL='`$ECHO "$DSYMUTIL" | $SED "$delay_single_quote_subst"`' NMEDIT='`$ECHO "$NMEDIT" | $SED "$delay_single_quote_subst"`' LIPO='`$ECHO "$LIPO" | $SED "$delay_single_quote_subst"`' OTOOL='`$ECHO "$OTOOL" | $SED "$delay_single_quote_subst"`' OTOOL64='`$ECHO "$OTOOL64" | $SED "$delay_single_quote_subst"`' libext='`$ECHO "$libext" | $SED "$delay_single_quote_subst"`' shrext_cmds='`$ECHO "$shrext_cmds" | $SED "$delay_single_quote_subst"`' extract_expsyms_cmds='`$ECHO "$extract_expsyms_cmds" | $SED "$delay_single_quote_subst"`' archive_cmds_need_lc='`$ECHO "$archive_cmds_need_lc" | $SED "$delay_single_quote_subst"`' enable_shared_with_static_runtimes='`$ECHO "$enable_shared_with_static_runtimes" | $SED "$delay_single_quote_subst"`' export_dynamic_flag_spec='`$ECHO "$export_dynamic_flag_spec" | $SED "$delay_single_quote_subst"`' whole_archive_flag_spec='`$ECHO "$whole_archive_flag_spec" | $SED "$delay_single_quote_subst"`' compiler_needs_object='`$ECHO "$compiler_needs_object" | $SED "$delay_single_quote_subst"`' old_archive_from_new_cmds='`$ECHO "$old_archive_from_new_cmds" | $SED "$delay_single_quote_subst"`' old_archive_from_expsyms_cmds='`$ECHO "$old_archive_from_expsyms_cmds" | $SED "$delay_single_quote_subst"`' archive_cmds='`$ECHO "$archive_cmds" | $SED "$delay_single_quote_subst"`' archive_expsym_cmds='`$ECHO "$archive_expsym_cmds" | $SED "$delay_single_quote_subst"`' module_cmds='`$ECHO "$module_cmds" | $SED "$delay_single_quote_subst"`' module_expsym_cmds='`$ECHO "$module_expsym_cmds" | $SED "$delay_single_quote_subst"`' with_gnu_ld='`$ECHO "$with_gnu_ld" | $SED "$delay_single_quote_subst"`' allow_undefined_flag='`$ECHO "$allow_undefined_flag" | $SED "$delay_single_quote_subst"`' no_undefined_flag='`$ECHO "$no_undefined_flag" | $SED "$delay_single_quote_subst"`' hardcode_libdir_flag_spec='`$ECHO "$hardcode_libdir_flag_spec" | $SED "$delay_single_quote_subst"`' hardcode_libdir_separator='`$ECHO "$hardcode_libdir_separator" | $SED "$delay_single_quote_subst"`' hardcode_direct='`$ECHO "$hardcode_direct" | $SED "$delay_single_quote_subst"`' hardcode_direct_absolute='`$ECHO "$hardcode_direct_absolute" | $SED "$delay_single_quote_subst"`' hardcode_minus_L='`$ECHO "$hardcode_minus_L" | $SED "$delay_single_quote_subst"`' hardcode_shlibpath_var='`$ECHO "$hardcode_shlibpath_var" | $SED "$delay_single_quote_subst"`' hardcode_automatic='`$ECHO "$hardcode_automatic" | $SED "$delay_single_quote_subst"`' inherit_rpath='`$ECHO "$inherit_rpath" | $SED "$delay_single_quote_subst"`' link_all_deplibs='`$ECHO "$link_all_deplibs" | $SED "$delay_single_quote_subst"`' always_export_symbols='`$ECHO "$always_export_symbols" | $SED "$delay_single_quote_subst"`' export_symbols_cmds='`$ECHO "$export_symbols_cmds" | $SED "$delay_single_quote_subst"`' exclude_expsyms='`$ECHO "$exclude_expsyms" | $SED "$delay_single_quote_subst"`' include_expsyms='`$ECHO "$include_expsyms" | $SED "$delay_single_quote_subst"`' prelink_cmds='`$ECHO "$prelink_cmds" | $SED "$delay_single_quote_subst"`' postlink_cmds='`$ECHO "$postlink_cmds" | $SED "$delay_single_quote_subst"`' file_list_spec='`$ECHO "$file_list_spec" | $SED "$delay_single_quote_subst"`' variables_saved_for_relink='`$ECHO "$variables_saved_for_relink" | $SED "$delay_single_quote_subst"`' need_lib_prefix='`$ECHO "$need_lib_prefix" | $SED "$delay_single_quote_subst"`' need_version='`$ECHO "$need_version" | $SED "$delay_single_quote_subst"`' version_type='`$ECHO "$version_type" | $SED "$delay_single_quote_subst"`' runpath_var='`$ECHO "$runpath_var" | $SED "$delay_single_quote_subst"`' shlibpath_var='`$ECHO "$shlibpath_var" | $SED "$delay_single_quote_subst"`' shlibpath_overrides_runpath='`$ECHO "$shlibpath_overrides_runpath" | $SED "$delay_single_quote_subst"`' libname_spec='`$ECHO "$libname_spec" | $SED "$delay_single_quote_subst"`' library_names_spec='`$ECHO "$library_names_spec" | $SED "$delay_single_quote_subst"`' soname_spec='`$ECHO "$soname_spec" | $SED "$delay_single_quote_subst"`' install_override_mode='`$ECHO "$install_override_mode" | $SED "$delay_single_quote_subst"`' postinstall_cmds='`$ECHO "$postinstall_cmds" | $SED "$delay_single_quote_subst"`' postuninstall_cmds='`$ECHO "$postuninstall_cmds" | $SED "$delay_single_quote_subst"`' finish_cmds='`$ECHO "$finish_cmds" | $SED "$delay_single_quote_subst"`' finish_eval='`$ECHO "$finish_eval" | $SED "$delay_single_quote_subst"`' hardcode_into_libs='`$ECHO "$hardcode_into_libs" | $SED "$delay_single_quote_subst"`' sys_lib_search_path_spec='`$ECHO "$sys_lib_search_path_spec" | $SED "$delay_single_quote_subst"`' sys_lib_dlsearch_path_spec='`$ECHO "$sys_lib_dlsearch_path_spec" | $SED "$delay_single_quote_subst"`' hardcode_action='`$ECHO "$hardcode_action" | $SED "$delay_single_quote_subst"`' enable_dlopen='`$ECHO "$enable_dlopen" | $SED "$delay_single_quote_subst"`' enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_subst"`' enable_dlopen_self_static='`$ECHO "$enable_dlopen_self_static" | $SED "$delay_single_quote_subst"`' old_striplib='`$ECHO "$old_striplib" | $SED "$delay_single_quote_subst"`' striplib='`$ECHO "$striplib" | $SED "$delay_single_quote_subst"`' compiler_lib_search_dirs='`$ECHO "$compiler_lib_search_dirs" | $SED "$delay_single_quote_subst"`' predep_objects='`$ECHO "$predep_objects" | $SED "$delay_single_quote_subst"`' postdep_objects='`$ECHO "$postdep_objects" | $SED "$delay_single_quote_subst"`' predeps='`$ECHO "$predeps" | $SED "$delay_single_quote_subst"`' postdeps='`$ECHO "$postdeps" | $SED "$delay_single_quote_subst"`' compiler_lib_search_path='`$ECHO "$compiler_lib_search_path" | $SED "$delay_single_quote_subst"`' LD_CXX='`$ECHO "$LD_CXX" | $SED "$delay_single_quote_subst"`' reload_flag_CXX='`$ECHO "$reload_flag_CXX" | $SED "$delay_single_quote_subst"`' reload_cmds_CXX='`$ECHO "$reload_cmds_CXX" | $SED "$delay_single_quote_subst"`' old_archive_cmds_CXX='`$ECHO "$old_archive_cmds_CXX" | $SED "$delay_single_quote_subst"`' compiler_CXX='`$ECHO "$compiler_CXX" | $SED "$delay_single_quote_subst"`' GCC_CXX='`$ECHO "$GCC_CXX" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_no_builtin_flag_CXX='`$ECHO "$lt_prog_compiler_no_builtin_flag_CXX" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_pic_CXX='`$ECHO "$lt_prog_compiler_pic_CXX" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_wl_CXX='`$ECHO "$lt_prog_compiler_wl_CXX" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_static_CXX='`$ECHO "$lt_prog_compiler_static_CXX" | $SED "$delay_single_quote_subst"`' lt_cv_prog_compiler_c_o_CXX='`$ECHO "$lt_cv_prog_compiler_c_o_CXX" | $SED "$delay_single_quote_subst"`' archive_cmds_need_lc_CXX='`$ECHO "$archive_cmds_need_lc_CXX" | $SED "$delay_single_quote_subst"`' enable_shared_with_static_runtimes_CXX='`$ECHO "$enable_shared_with_static_runtimes_CXX" | $SED "$delay_single_quote_subst"`' export_dynamic_flag_spec_CXX='`$ECHO "$export_dynamic_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' whole_archive_flag_spec_CXX='`$ECHO "$whole_archive_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' compiler_needs_object_CXX='`$ECHO "$compiler_needs_object_CXX" | $SED "$delay_single_quote_subst"`' old_archive_from_new_cmds_CXX='`$ECHO "$old_archive_from_new_cmds_CXX" | $SED "$delay_single_quote_subst"`' old_archive_from_expsyms_cmds_CXX='`$ECHO "$old_archive_from_expsyms_cmds_CXX" | $SED "$delay_single_quote_subst"`' archive_cmds_CXX='`$ECHO "$archive_cmds_CXX" | $SED "$delay_single_quote_subst"`' archive_expsym_cmds_CXX='`$ECHO "$archive_expsym_cmds_CXX" | $SED "$delay_single_quote_subst"`' module_cmds_CXX='`$ECHO "$module_cmds_CXX" | $SED "$delay_single_quote_subst"`' module_expsym_cmds_CXX='`$ECHO "$module_expsym_cmds_CXX" | $SED "$delay_single_quote_subst"`' with_gnu_ld_CXX='`$ECHO "$with_gnu_ld_CXX" | $SED "$delay_single_quote_subst"`' allow_undefined_flag_CXX='`$ECHO "$allow_undefined_flag_CXX" | $SED "$delay_single_quote_subst"`' no_undefined_flag_CXX='`$ECHO "$no_undefined_flag_CXX" | $SED "$delay_single_quote_subst"`' hardcode_libdir_flag_spec_CXX='`$ECHO "$hardcode_libdir_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' hardcode_libdir_separator_CXX='`$ECHO "$hardcode_libdir_separator_CXX" | $SED "$delay_single_quote_subst"`' hardcode_direct_CXX='`$ECHO "$hardcode_direct_CXX" | $SED "$delay_single_quote_subst"`' hardcode_direct_absolute_CXX='`$ECHO "$hardcode_direct_absolute_CXX" | $SED "$delay_single_quote_subst"`' hardcode_minus_L_CXX='`$ECHO "$hardcode_minus_L_CXX" | $SED "$delay_single_quote_subst"`' hardcode_shlibpath_var_CXX='`$ECHO "$hardcode_shlibpath_var_CXX" | $SED "$delay_single_quote_subst"`' hardcode_automatic_CXX='`$ECHO "$hardcode_automatic_CXX" | $SED "$delay_single_quote_subst"`' inherit_rpath_CXX='`$ECHO "$inherit_rpath_CXX" | $SED "$delay_single_quote_subst"`' link_all_deplibs_CXX='`$ECHO "$link_all_deplibs_CXX" | $SED "$delay_single_quote_subst"`' always_export_symbols_CXX='`$ECHO "$always_export_symbols_CXX" | $SED "$delay_single_quote_subst"`' export_symbols_cmds_CXX='`$ECHO "$export_symbols_cmds_CXX" | $SED "$delay_single_quote_subst"`' exclude_expsyms_CXX='`$ECHO "$exclude_expsyms_CXX" | $SED "$delay_single_quote_subst"`' include_expsyms_CXX='`$ECHO "$include_expsyms_CXX" | $SED "$delay_single_quote_subst"`' prelink_cmds_CXX='`$ECHO "$prelink_cmds_CXX" | $SED "$delay_single_quote_subst"`' postlink_cmds_CXX='`$ECHO "$postlink_cmds_CXX" | $SED "$delay_single_quote_subst"`' file_list_spec_CXX='`$ECHO "$file_list_spec_CXX" | $SED "$delay_single_quote_subst"`' hardcode_action_CXX='`$ECHO "$hardcode_action_CXX" | $SED "$delay_single_quote_subst"`' compiler_lib_search_dirs_CXX='`$ECHO "$compiler_lib_search_dirs_CXX" | $SED "$delay_single_quote_subst"`' predep_objects_CXX='`$ECHO "$predep_objects_CXX" | $SED "$delay_single_quote_subst"`' postdep_objects_CXX='`$ECHO "$postdep_objects_CXX" | $SED "$delay_single_quote_subst"`' predeps_CXX='`$ECHO "$predeps_CXX" | $SED "$delay_single_quote_subst"`' postdeps_CXX='`$ECHO "$postdeps_CXX" | $SED "$delay_single_quote_subst"`' compiler_lib_search_path_CXX='`$ECHO "$compiler_lib_search_path_CXX" | $SED "$delay_single_quote_subst"`' LTCC='$LTCC' LTCFLAGS='$LTCFLAGS' compiler='$compiler_DEFAULT' # A function that is used when there is no print builtin or printf. func_fallback_echo () { eval 'cat <<_LTECHO_EOF \$1 _LTECHO_EOF' } # Quote evaled strings. for var in SHELL \ ECHO \ PATH_SEPARATOR \ SED \ GREP \ EGREP \ FGREP \ LD \ NM \ LN_S \ lt_SP2NL \ lt_NL2SP \ reload_flag \ OBJDUMP \ deplibs_check_method \ file_magic_cmd \ file_magic_glob \ want_nocaseglob \ DLLTOOL \ sharedlib_from_linklib_cmd \ AR \ AR_FLAGS \ archiver_list_spec \ STRIP \ RANLIB \ CC \ CFLAGS \ compiler \ lt_cv_sys_global_symbol_pipe \ lt_cv_sys_global_symbol_to_cdecl \ lt_cv_sys_global_symbol_to_c_name_address \ lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \ nm_file_list_spec \ lt_prog_compiler_no_builtin_flag \ lt_prog_compiler_pic \ lt_prog_compiler_wl \ lt_prog_compiler_static \ lt_cv_prog_compiler_c_o \ need_locks \ MANIFEST_TOOL \ DSYMUTIL \ NMEDIT \ LIPO \ OTOOL \ OTOOL64 \ shrext_cmds \ export_dynamic_flag_spec \ whole_archive_flag_spec \ compiler_needs_object \ with_gnu_ld \ allow_undefined_flag \ no_undefined_flag \ hardcode_libdir_flag_spec \ hardcode_libdir_separator \ exclude_expsyms \ include_expsyms \ file_list_spec \ variables_saved_for_relink \ libname_spec \ library_names_spec \ soname_spec \ install_override_mode \ finish_eval \ old_striplib \ striplib \ compiler_lib_search_dirs \ predep_objects \ postdep_objects \ predeps \ postdeps \ compiler_lib_search_path \ LD_CXX \ reload_flag_CXX \ compiler_CXX \ lt_prog_compiler_no_builtin_flag_CXX \ lt_prog_compiler_pic_CXX \ lt_prog_compiler_wl_CXX \ lt_prog_compiler_static_CXX \ lt_cv_prog_compiler_c_o_CXX \ export_dynamic_flag_spec_CXX \ whole_archive_flag_spec_CXX \ compiler_needs_object_CXX \ with_gnu_ld_CXX \ allow_undefined_flag_CXX \ no_undefined_flag_CXX \ hardcode_libdir_flag_spec_CXX \ hardcode_libdir_separator_CXX \ exclude_expsyms_CXX \ include_expsyms_CXX \ file_list_spec_CXX \ compiler_lib_search_dirs_CXX \ predep_objects_CXX \ postdep_objects_CXX \ predeps_CXX \ postdeps_CXX \ compiler_lib_search_path_CXX; do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[\\\\\\\`\\"\\\$]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done # Double-quote double-evaled strings. for var in reload_cmds \ old_postinstall_cmds \ old_postuninstall_cmds \ old_archive_cmds \ extract_expsyms_cmds \ old_archive_from_new_cmds \ old_archive_from_expsyms_cmds \ archive_cmds \ archive_expsym_cmds \ module_cmds \ module_expsym_cmds \ export_symbols_cmds \ prelink_cmds \ postlink_cmds \ postinstall_cmds \ postuninstall_cmds \ finish_cmds \ sys_lib_search_path_spec \ sys_lib_dlsearch_path_spec \ reload_cmds_CXX \ old_archive_cmds_CXX \ old_archive_from_new_cmds_CXX \ old_archive_from_expsyms_cmds_CXX \ archive_cmds_CXX \ archive_expsym_cmds_CXX \ module_cmds_CXX \ module_expsym_cmds_CXX \ export_symbols_cmds_CXX \ prelink_cmds_CXX \ postlink_cmds_CXX; do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[\\\\\\\`\\"\\\$]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done ac_aux_dir='$ac_aux_dir' xsi_shell='$xsi_shell' lt_shell_append='$lt_shell_append' # See if we are running on zsh, and set the options which allow our # commands through without removal of \ escapes INIT. if test -n "\${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi PACKAGE='$PACKAGE' VERSION='$VERSION' TIMESTAMP='$TIMESTAMP' RM='$RM' ofile='$ofile' _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Handling of arguments. for ac_config_target in $ac_config_targets do case $ac_config_target in "build-aux/config.h") CONFIG_HEADERS="$CONFIG_HEADERS build-aux/config.h" ;; "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; "scripts/gtest-config") CONFIG_FILES="$CONFIG_FILES scripts/gtest-config" ;; "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;; *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; esac done # If the user did not use the arguments to specify the items to instantiate, # then the envvar interface is used. Set only those that are not. # We use the long form for the default assignment because of an extremely # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands fi # Have a temporary directory for convenience. Make it in the build tree # simply because there is no reason against having it here, and in addition, # creating and moving files from /tmp can sometimes cause problems. # Hook for its removal unless debugging. # Note that there is a small window in which the directory will not be cleaned: # after its creation but before its name has been assigned to `$tmp'. $debug || { tmp= ac_tmp= trap 'exit_status=$? : "${ac_tmp:=$tmp}" { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status ' 0 trap 'as_fn_exit 1' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. { tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && test -d "$tmp" } || { tmp=./conf$$-$RANDOM (umask 077 && mkdir "$tmp") } || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 ac_tmp=$tmp # Set up the scripts for CONFIG_FILES section. # No need to generate them if there are no CONFIG_FILES. # This happens for instance with `./config.status config.h'. if test -n "$CONFIG_FILES"; then ac_cr=`echo X | tr X '\015'` # On cygwin, bash can eat \r inside `` if the user requested igncr. # But we know of no other shell where ac_cr would be empty at this # point, so we can use a bashism as a fallback. if test "x$ac_cr" = x; then eval ac_cr=\$\'\\r\' fi ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then ac_cs_awk_cr='\\r' else ac_cs_awk_cr=$ac_cr fi echo 'BEGIN {' >"$ac_tmp/subs1.awk" && _ACEOF { echo "cat >conf$$subs.awk <<_ACEOF" && echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && echo "_ACEOF" } >conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` ac_delim='%!_!# ' for ac_last_try in false false false false false :; do . ./conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` if test $ac_delim_n = $ac_delim_num; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done rm -f conf$$subs.sh cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && _ACEOF sed -n ' h s/^/S["/; s/!.*/"]=/ p g s/^[^!]*!// :repl t repl s/'"$ac_delim"'$// t delim :nl h s/\(.\{148\}\)..*/\1/ t more1 s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ p n b repl :more1 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t nl :delim h s/\(.\{148\}\)..*/\1/ t more2 s/["\\]/\\&/g; s/^/"/; s/$/"/ p b :more2 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t delim ' >$CONFIG_STATUS || ac_write_fail=1 rm -f conf$$subs.awk cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACAWK cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && for (key in S) S_is_set[key] = 1 FS = "" } { line = $ 0 nfields = split(line, field, "@") substed = 0 len = length(field[1]) for (i = 2; i < nfields; i++) { key = field[i] keylen = length(key) if (S_is_set[key]) { value = S[key] line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) len += length(value) + length(field[++i]) substed = 1 } else len += 1 + keylen } print line } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" else cat fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 _ACEOF # VPATH may cause trouble with some makes, so we remove sole $(srcdir), # ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and # trailing colons and then remove the whole line if VPATH becomes empty # (actually we leave an empty line to preserve line numbers). if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ h s/// s/^/:/ s/[ ]*$/:/ s/:\$(srcdir):/:/g s/:\${srcdir}:/:/g s/:@srcdir@:/:/g s/^:*// s/:*$// x s/\(=[ ]*\).*/\1/ G s/\n// s/^[^=]*=[ ]*$// }' fi cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 fi # test -n "$CONFIG_FILES" # Set up the scripts for CONFIG_HEADERS section. # No need to generate them if there are no CONFIG_HEADERS. # This happens for instance with `./config.status Makefile'. if test -n "$CONFIG_HEADERS"; then cat >"$ac_tmp/defines.awk" <<\_ACAWK || BEGIN { _ACEOF # Transform confdefs.h into an awk script `defines.awk', embedded as # here-document in config.status, that substitutes the proper values into # config.h.in to produce config.h. # Create a delimiter string that does not exist in confdefs.h, to ease # handling of long lines. ac_delim='%!_!# ' for ac_last_try in false false :; do ac_tt=`sed -n "/$ac_delim/p" confdefs.h` if test -z "$ac_tt"; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done # For the awk script, D is an array of macro values keyed by name, # likewise P contains macro parameters if any. Preserve backslash # newline sequences. ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* sed -n ' s/.\{148\}/&'"$ac_delim"'/g t rset :rset s/^[ ]*#[ ]*define[ ][ ]*/ / t def d :def s/\\$// t bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3"/p s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p d :bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3\\\\\\n"\\/p t cont s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p t cont d :cont n s/.\{148\}/&'"$ac_delim"'/g t clear :clear s/\\$// t bsnlc s/["\\]/\\&/g; s/^/"/; s/$/"/p d :bsnlc s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p b cont ' >$CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 for (key in D) D_is_set[key] = 1 FS = "" } /^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { line = \$ 0 split(line, arg, " ") if (arg[1] == "#") { defundef = arg[2] mac1 = arg[3] } else { defundef = substr(arg[1], 2) mac1 = arg[2] } split(mac1, mac2, "(") #) macro = mac2[1] prefix = substr(line, 1, index(line, defundef) - 1) if (D_is_set[macro]) { # Preserve the white space surrounding the "#". print prefix "define", macro P[macro] D[macro] next } else { # Replace #undef with comments. This is necessary, for example, # in the case of _POSIX_SOURCE, which is predefined and required # on some systems where configure will not decide to define it. if (defundef == "undef") { print "/*", prefix defundef, macro, "*/" next } } } { print } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 fi # test -n "$CONFIG_HEADERS" eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS" shift for ac_tag do case $ac_tag in :[FHLC]) ac_mode=$ac_tag; continue;; esac case $ac_mode$ac_tag in :[FHL]*:*);; :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; :[FH]-) ac_tag=-:-;; :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; esac ac_save_IFS=$IFS IFS=: set x $ac_tag IFS=$ac_save_IFS shift ac_file=$1 shift case $ac_mode in :L) ac_source=$1;; :[FH]) ac_file_inputs= for ac_f do case $ac_f in -) ac_f="$ac_tmp/stdin";; *) # Look for the file first in the build tree, then in the source tree # (if the path is not absolute). The absolute path cannot be DOS-style, # because $ac_f cannot contain `:'. test -f "$ac_f" || case $ac_f in [\\/$]*) false;; *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; esac || as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; esac case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac as_fn_append ac_file_inputs " '$ac_f'" done # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ configure_input='Generated from '` $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' `' by configure.' if test x"$ac_file" != x-; then configure_input="$ac_file. $configure_input" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 $as_echo "$as_me: creating $ac_file" >&6;} fi # Neutralize special characters interpreted by sed in replacement strings. case $configure_input in #( *\&* | *\|* | *\\* ) ac_sed_conf_input=`$as_echo "$configure_input" | sed 's/[\\\\&|]/\\\\&/g'`;; #( *) ac_sed_conf_input=$configure_input;; esac case $ac_tag in *:-:* | *:-) cat >"$ac_tmp/stdin" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; esac ;; esac ac_dir=`$as_dirname -- "$ac_file" || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` as_dir="$ac_dir"; as_fn_mkdir_p ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix case $ac_mode in :F) # # CONFIG_FILE # case $INSTALL in [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; esac ac_MKDIR_P=$MKDIR_P case $MKDIR_P in [\\/$]* | ?:[\\/]* ) ;; */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; esac _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # If the template does not know about datarootdir, expand it. # FIXME: This hack should be removed a few years after 2.60. ac_datarootdir_hack=; ac_datarootdir_seen= ac_sed_dataroot=' /datarootdir/ { p q } /@datadir@/p /@docdir@/p /@infodir@/p /@localedir@/p /@mandir@/p' case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in *datarootdir*) ac_datarootdir_seen=yes;; *@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 $as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_datarootdir_hack=' s&@datadir@&$datadir&g s&@docdir@&$docdir&g s&@infodir@&$infodir&g s&@localedir@&$localedir&g s&@mandir@&$mandir&g s&\\\${datarootdir}&$datarootdir&g' ;; esac _ACEOF # Neutralize VPATH when `$srcdir' = `.'. # Shell code in configure.ac might set extrasub. # FIXME: do we really want to maintain this feature? cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_sed_extra="$ac_vpsub $extrasub _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b s|@configure_input@|$ac_sed_conf_input|;t t s&@top_builddir@&$ac_top_builddir_sub&;t t s&@top_build_prefix@&$ac_top_build_prefix&;t t s&@srcdir@&$ac_srcdir&;t t s&@abs_srcdir@&$ac_abs_srcdir&;t t s&@top_srcdir@&$ac_top_srcdir&;t t s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t s&@builddir@&$ac_builddir&;t t s&@abs_builddir@&$ac_abs_builddir&;t t s&@abs_top_builddir@&$ac_abs_top_builddir&;t t s&@INSTALL@&$ac_INSTALL&;t t s&@MKDIR_P@&$ac_MKDIR_P&;t t $ac_datarootdir_hack " eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ "$ac_tmp/out"`; test -z "$ac_out"; } && { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&5 $as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&2;} rm -f "$ac_tmp/stdin" case $ac_file in -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; esac \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; :H) # # CONFIG_HEADER # if test x"$ac_file" != x-; then { $as_echo "/* $configure_input */" \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" } >"$ac_tmp/config.h" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 $as_echo "$as_me: $ac_file is unchanged" >&6;} else rm -f "$ac_file" mv "$ac_tmp/config.h" "$ac_file" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 fi else $as_echo "/* $configure_input */" \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ || as_fn_error $? "could not create -" "$LINENO" 5 fi # Compute "$ac_file"'s index in $config_headers. _am_arg="$ac_file" _am_stamp_count=1 for _am_header in $config_headers :; do case $_am_header in $_am_arg | $_am_arg:* ) break ;; * ) _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" || $as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$_am_arg" : 'X\(//\)[^/]' \| \ X"$_am_arg" : 'X\(//\)$' \| \ X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$_am_arg" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'`/stamp-h$_am_stamp_count ;; :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 $as_echo "$as_me: executing $ac_file commands" >&6;} ;; esac case $ac_file$ac_mode in "scripts/gtest-config":F) chmod +x scripts/gtest-config ;; "depfiles":C) test x"$AMDEP_TRUE" != x"" || { # Autoconf 2.62 quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. case $CONFIG_FILES in *\'*) eval set x "$CONFIG_FILES" ;; *) set x $CONFIG_FILES ;; esac shift for mf do # Strip MF so we end up with the name of the file. mf=`echo "$mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile or not. # We used to match only the files named `Makefile.in', but # some people rename them; so instead we look at the file content. # Grep'ing the first line is not enough: some people post-process # each Makefile.in and add a new line on top of each file to say so. # Grep'ing the whole file is not good either: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then dirpart=`$as_dirname -- "$mf" || $as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$mf" : 'X\(//\)[^/]' \| \ X"$mf" : 'X\(//\)$' \| \ X"$mf" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$mf" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` else continue fi # Extract the definition of DEPDIR, am__include, and am__quote # from the Makefile without running `make'. DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` test -z "$DEPDIR" && continue am__include=`sed -n 's/^am__include = //p' < "$mf"` test -z "am__include" && continue am__quote=`sed -n 's/^am__quote = //p' < "$mf"` # When using ansi2knr, U may be empty or an underscore; expand it U=`sed -n 's/^U = //p' < "$mf"` # Find all dependency output files, they are included files with # $(DEPDIR) in their names. We invoke sed twice because it is the # simplest approach to changing $(DEPDIR) to its actual value in the # expansion. for file in `sed -n " s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do # Make sure the directory exists. test -f "$dirpart/$file" && continue fdir=`$as_dirname -- "$file" || $as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$file" : 'X\(//\)[^/]' \| \ X"$file" : 'X\(//\)$' \| \ X"$file" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` as_dir=$dirpart/$fdir; as_fn_mkdir_p # echo "creating $dirpart/$file" echo '# dummy' > "$dirpart/$file" done done } ;; "libtool":C) # See if we are running on zsh, and set the options which allow our # commands through without removal of \ escapes. if test -n "${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi cfgfile="${ofile}T" trap "$RM \"$cfgfile\"; exit 1" 1 2 15 $RM "$cfgfile" cat <<_LT_EOF >> "$cfgfile" #! $SHELL # `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. # Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION # Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: # NOTE: Changes made to this file will be lost: look at ltmain.sh. # # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, # 2006, 2007, 2008, 2009, 2010, 2011 Free Software # Foundation, Inc. # Written by Gordon Matzigkeit, 1996 # # This file is part of GNU Libtool. # # GNU Libtool is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as # published by the Free Software Foundation; either version 2 of # the License, or (at your option) any later version. # # As a special exception to the GNU General Public License, # if you distribute this file as part of a program or library that # is built using GNU Libtool, you may include this file under the # same distribution terms that you use for the rest of that program. # # GNU Libtool is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with GNU Libtool; see the file COPYING. If not, a copy # can be downloaded from http://www.gnu.org/licenses/gpl.html, or # obtained by writing to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # The names of the tagged configurations supported by this script. available_tags="CXX " # ### BEGIN LIBTOOL CONFIG # Which release of libtool.m4 was used? macro_version=$macro_version macro_revision=$macro_revision # Whether or not to build shared libraries. build_libtool_libs=$enable_shared # Whether or not to build static libraries. build_old_libs=$enable_static # What type of objects to build. pic_mode=$pic_mode # Whether or not to optimize for fast installation. fast_install=$enable_fast_install # Shell to use when invoking shell scripts. SHELL=$lt_SHELL # An echo program that protects backslashes. ECHO=$lt_ECHO # The PATH separator for the build system. PATH_SEPARATOR=$lt_PATH_SEPARATOR # The host system. host_alias=$host_alias host=$host host_os=$host_os # The build system. build_alias=$build_alias build=$build build_os=$build_os # A sed program that does not truncate output. SED=$lt_SED # Sed that helps us avoid accidentally triggering echo(1) options like -n. Xsed="\$SED -e 1s/^X//" # A grep program that handles long lines. GREP=$lt_GREP # An ERE matcher. EGREP=$lt_EGREP # A literal string matcher. FGREP=$lt_FGREP # A BSD- or MS-compatible name lister. NM=$lt_NM # Whether we need soft or hard links. LN_S=$lt_LN_S # What is the maximum length of a command? max_cmd_len=$max_cmd_len # Object file suffix (normally "o"). objext=$ac_objext # Executable file suffix (normally ""). exeext=$exeext # whether the shell understands "unset". lt_unset=$lt_unset # turn spaces into newlines. SP2NL=$lt_lt_SP2NL # turn newlines into spaces. NL2SP=$lt_lt_NL2SP # convert \$build file names to \$host format. to_host_file_cmd=$lt_cv_to_host_file_cmd # convert \$build files to toolchain format. to_tool_file_cmd=$lt_cv_to_tool_file_cmd # An object symbol dumper. OBJDUMP=$lt_OBJDUMP # Method to check whether dependent libraries are shared objects. deplibs_check_method=$lt_deplibs_check_method # Command to use when deplibs_check_method = "file_magic". file_magic_cmd=$lt_file_magic_cmd # How to find potential files when deplibs_check_method = "file_magic". file_magic_glob=$lt_file_magic_glob # Find potential files using nocaseglob when deplibs_check_method = "file_magic". want_nocaseglob=$lt_want_nocaseglob # DLL creation program. DLLTOOL=$lt_DLLTOOL # Command to associate shared and link libraries. sharedlib_from_linklib_cmd=$lt_sharedlib_from_linklib_cmd # The archiver. AR=$lt_AR # Flags to create an archive. AR_FLAGS=$lt_AR_FLAGS # How to feed a file listing to the archiver. archiver_list_spec=$lt_archiver_list_spec # A symbol stripping program. STRIP=$lt_STRIP # Commands used to install an old-style archive. RANLIB=$lt_RANLIB old_postinstall_cmds=$lt_old_postinstall_cmds old_postuninstall_cmds=$lt_old_postuninstall_cmds # Whether to use a lock for old archive extraction. lock_old_archive_extraction=$lock_old_archive_extraction # A C compiler. LTCC=$lt_CC # LTCC compiler flags. LTCFLAGS=$lt_CFLAGS # Take the output of nm and produce a listing of raw symbols and C names. global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe # Transform the output of nm in a proper C declaration. global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl # Transform the output of nm in a C name address pair. global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address # Transform the output of nm in a C name address pair when lib prefix is needed. global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix # Specify filename containing input files for \$NM. nm_file_list_spec=$lt_nm_file_list_spec # The root where to search for dependent libraries,and in which our libraries should be installed. lt_sysroot=$lt_sysroot # The name of the directory that contains temporary libtool files. objdir=$objdir # Used to examine libraries when file_magic_cmd begins with "file". MAGIC_CMD=$MAGIC_CMD # Must we lock files when doing compilation? need_locks=$lt_need_locks # Manifest tool. MANIFEST_TOOL=$lt_MANIFEST_TOOL # Tool to manipulate archived DWARF debug symbol files on Mac OS X. DSYMUTIL=$lt_DSYMUTIL # Tool to change global to local symbols on Mac OS X. NMEDIT=$lt_NMEDIT # Tool to manipulate fat objects and archives on Mac OS X. LIPO=$lt_LIPO # ldd/readelf like tool for Mach-O binaries on Mac OS X. OTOOL=$lt_OTOOL # ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4. OTOOL64=$lt_OTOOL64 # Old archive suffix (normally "a"). libext=$libext # Shared library suffix (normally ".so"). shrext_cmds=$lt_shrext_cmds # The commands to extract the exported symbol list from a shared archive. extract_expsyms_cmds=$lt_extract_expsyms_cmds # Variables whose values should be saved in libtool wrapper scripts and # restored at link time. variables_saved_for_relink=$lt_variables_saved_for_relink # Do we need the "lib" prefix for modules? need_lib_prefix=$need_lib_prefix # Do we need a version for libraries? need_version=$need_version # Library versioning type. version_type=$version_type # Shared library runtime path variable. runpath_var=$runpath_var # Shared library path variable. shlibpath_var=$shlibpath_var # Is shlibpath searched before the hard-coded library search path? shlibpath_overrides_runpath=$shlibpath_overrides_runpath # Format of library name prefix. libname_spec=$lt_libname_spec # List of archive names. First name is the real one, the rest are links. # The last name is the one that the linker finds with -lNAME library_names_spec=$lt_library_names_spec # The coded name of the library, if different from the real name. soname_spec=$lt_soname_spec # Permission mode override for installation of shared libraries. install_override_mode=$lt_install_override_mode # Command to use after installation of a shared archive. postinstall_cmds=$lt_postinstall_cmds # Command to use after uninstallation of a shared archive. postuninstall_cmds=$lt_postuninstall_cmds # Commands used to finish a libtool library installation in a directory. finish_cmds=$lt_finish_cmds # As "finish_cmds", except a single script fragment to be evaled but # not shown. finish_eval=$lt_finish_eval # Whether we should hardcode library paths into libraries. hardcode_into_libs=$hardcode_into_libs # Compile-time system search path for libraries. sys_lib_search_path_spec=$lt_sys_lib_search_path_spec # Run-time system search path for libraries. sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec # Whether dlopen is supported. dlopen_support=$enable_dlopen # Whether dlopen of programs is supported. dlopen_self=$enable_dlopen_self # Whether dlopen of statically linked programs is supported. dlopen_self_static=$enable_dlopen_self_static # Commands to strip libraries. old_striplib=$lt_old_striplib striplib=$lt_striplib # The linker used to build libraries. LD=$lt_LD # How to create reloadable object files. reload_flag=$lt_reload_flag reload_cmds=$lt_reload_cmds # Commands used to build an old-style archive. old_archive_cmds=$lt_old_archive_cmds # A language specific compiler. CC=$lt_compiler # Is the compiler the GNU compiler? with_gcc=$GCC # Compiler flag to turn off builtin functions. no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag # Additional compiler flags for building library objects. pic_flag=$lt_lt_prog_compiler_pic # How to pass a linker flag through the compiler. wl=$lt_lt_prog_compiler_wl # Compiler flag to prevent dynamic linking. link_static_flag=$lt_lt_prog_compiler_static # Does compiler simultaneously support -c and -o options? compiler_c_o=$lt_lt_cv_prog_compiler_c_o # Whether or not to add -lc for building shared libraries. build_libtool_need_lc=$archive_cmds_need_lc # Whether or not to disallow shared libs when runtime libs are static. allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes # Compiler flag to allow reflexive dlopens. export_dynamic_flag_spec=$lt_export_dynamic_flag_spec # Compiler flag to generate shared objects directly from archives. whole_archive_flag_spec=$lt_whole_archive_flag_spec # Whether the compiler copes with passing no objects directly. compiler_needs_object=$lt_compiler_needs_object # Create an old-style archive from a shared archive. old_archive_from_new_cmds=$lt_old_archive_from_new_cmds # Create a temporary old-style archive to link instead of a shared archive. old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds # Commands used to build a shared archive. archive_cmds=$lt_archive_cmds archive_expsym_cmds=$lt_archive_expsym_cmds # Commands used to build a loadable module if different from building # a shared archive. module_cmds=$lt_module_cmds module_expsym_cmds=$lt_module_expsym_cmds # Whether we are building with GNU ld or not. with_gnu_ld=$lt_with_gnu_ld # Flag that allows shared libraries with undefined symbols to be built. allow_undefined_flag=$lt_allow_undefined_flag # Flag that enforces no undefined symbols. no_undefined_flag=$lt_no_undefined_flag # Flag to hardcode \$libdir into a binary during linking. # This must work even if \$libdir does not exist hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec # Whether we need a single "-rpath" flag with a separated argument. hardcode_libdir_separator=$lt_hardcode_libdir_separator # Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes # DIR into the resulting binary. hardcode_direct=$hardcode_direct # Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes # DIR into the resulting binary and the resulting library dependency is # "absolute",i.e impossible to change by setting \${shlibpath_var} if the # library is relocated. hardcode_direct_absolute=$hardcode_direct_absolute # Set to "yes" if using the -LDIR flag during linking hardcodes DIR # into the resulting binary. hardcode_minus_L=$hardcode_minus_L # Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR # into the resulting binary. hardcode_shlibpath_var=$hardcode_shlibpath_var # Set to "yes" if building a shared library automatically hardcodes DIR # into the library and all subsequent libraries and executables linked # against it. hardcode_automatic=$hardcode_automatic # Set to yes if linker adds runtime paths of dependent libraries # to runtime path list. inherit_rpath=$inherit_rpath # Whether libtool must link a program against all its dependency libraries. link_all_deplibs=$link_all_deplibs # Set to "yes" if exported symbols are required. always_export_symbols=$always_export_symbols # The commands to list exported symbols. export_symbols_cmds=$lt_export_symbols_cmds # Symbols that should not be listed in the preloaded symbols. exclude_expsyms=$lt_exclude_expsyms # Symbols that must always be exported. include_expsyms=$lt_include_expsyms # Commands necessary for linking programs (against libraries) with templates. prelink_cmds=$lt_prelink_cmds # Commands necessary for finishing linking programs. postlink_cmds=$lt_postlink_cmds # Specify filename containing input files. file_list_spec=$lt_file_list_spec # How to hardcode a shared library path into an executable. hardcode_action=$hardcode_action # The directories searched by this compiler when creating a shared library. compiler_lib_search_dirs=$lt_compiler_lib_search_dirs # Dependencies to place before and after the objects being linked to # create a shared library. predep_objects=$lt_predep_objects postdep_objects=$lt_postdep_objects predeps=$lt_predeps postdeps=$lt_postdeps # The library search path used internally by the compiler when linking # a shared library. compiler_lib_search_path=$lt_compiler_lib_search_path # ### END LIBTOOL CONFIG _LT_EOF case $host_os in aix3*) cat <<\_LT_EOF >> "$cfgfile" # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test "X${COLLECT_NAMES+set}" != Xset; then COLLECT_NAMES= export COLLECT_NAMES fi _LT_EOF ;; esac ltmain="$ac_aux_dir/ltmain.sh" # We use sed instead of cat because bash on DJGPP gets confused if # if finds mixed CR/LF and LF-only lines. Since sed operates in # text mode, it properly converts lines to CR/LF. This bash problem # is reportedly fixed, but why not run on old versions too? sed '$q' "$ltmain" >> "$cfgfile" \ || (rm -f "$cfgfile"; exit 1) if test x"$xsi_shell" = xyes; then sed -e '/^func_dirname ()$/,/^} # func_dirname /c\ func_dirname ()\ {\ \ case ${1} in\ \ */*) func_dirname_result="${1%/*}${2}" ;;\ \ * ) func_dirname_result="${3}" ;;\ \ esac\ } # Extended-shell func_dirname implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_basename ()$/,/^} # func_basename /c\ func_basename ()\ {\ \ func_basename_result="${1##*/}"\ } # Extended-shell func_basename implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_dirname_and_basename ()$/,/^} # func_dirname_and_basename /c\ func_dirname_and_basename ()\ {\ \ case ${1} in\ \ */*) func_dirname_result="${1%/*}${2}" ;;\ \ * ) func_dirname_result="${3}" ;;\ \ esac\ \ func_basename_result="${1##*/}"\ } # Extended-shell func_dirname_and_basename implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_stripname ()$/,/^} # func_stripname /c\ func_stripname ()\ {\ \ # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are\ \ # positional parameters, so assign one to ordinary parameter first.\ \ func_stripname_result=${3}\ \ func_stripname_result=${func_stripname_result#"${1}"}\ \ func_stripname_result=${func_stripname_result%"${2}"}\ } # Extended-shell func_stripname implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_split_long_opt ()$/,/^} # func_split_long_opt /c\ func_split_long_opt ()\ {\ \ func_split_long_opt_name=${1%%=*}\ \ func_split_long_opt_arg=${1#*=}\ } # Extended-shell func_split_long_opt implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_split_short_opt ()$/,/^} # func_split_short_opt /c\ func_split_short_opt ()\ {\ \ func_split_short_opt_arg=${1#??}\ \ func_split_short_opt_name=${1%"$func_split_short_opt_arg"}\ } # Extended-shell func_split_short_opt implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_lo2o ()$/,/^} # func_lo2o /c\ func_lo2o ()\ {\ \ case ${1} in\ \ *.lo) func_lo2o_result=${1%.lo}.${objext} ;;\ \ *) func_lo2o_result=${1} ;;\ \ esac\ } # Extended-shell func_lo2o implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_xform ()$/,/^} # func_xform /c\ func_xform ()\ {\ func_xform_result=${1%.*}.lo\ } # Extended-shell func_xform implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_arith ()$/,/^} # func_arith /c\ func_arith ()\ {\ func_arith_result=$(( $* ))\ } # Extended-shell func_arith implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_len ()$/,/^} # func_len /c\ func_len ()\ {\ func_len_result=${#1}\ } # Extended-shell func_len implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: fi if test x"$lt_shell_append" = xyes; then sed -e '/^func_append ()$/,/^} # func_append /c\ func_append ()\ {\ eval "${1}+=\\${2}"\ } # Extended-shell func_append implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_append_quoted ()$/,/^} # func_append_quoted /c\ func_append_quoted ()\ {\ \ func_quote_for_eval "${2}"\ \ eval "${1}+=\\\\ \\$func_quote_for_eval_result"\ } # Extended-shell func_append_quoted implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: # Save a `func_append' function call where possible by direct use of '+=' sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: else # Save a `func_append' function call even when '+=' is not available sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: fi if test x"$_lt_function_replace_fail" = x":"; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Unable to substitute extended shell functions in $ofile" >&5 $as_echo "$as_me: WARNING: Unable to substitute extended shell functions in $ofile" >&2;} fi mv -f "$cfgfile" "$ofile" || (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") chmod +x "$ofile" cat <<_LT_EOF >> "$ofile" # ### BEGIN LIBTOOL TAG CONFIG: CXX # The linker used to build libraries. LD=$lt_LD_CXX # How to create reloadable object files. reload_flag=$lt_reload_flag_CXX reload_cmds=$lt_reload_cmds_CXX # Commands used to build an old-style archive. old_archive_cmds=$lt_old_archive_cmds_CXX # A language specific compiler. CC=$lt_compiler_CXX # Is the compiler the GNU compiler? with_gcc=$GCC_CXX # Compiler flag to turn off builtin functions. no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_CXX # Additional compiler flags for building library objects. pic_flag=$lt_lt_prog_compiler_pic_CXX # How to pass a linker flag through the compiler. wl=$lt_lt_prog_compiler_wl_CXX # Compiler flag to prevent dynamic linking. link_static_flag=$lt_lt_prog_compiler_static_CXX # Does compiler simultaneously support -c and -o options? compiler_c_o=$lt_lt_cv_prog_compiler_c_o_CXX # Whether or not to add -lc for building shared libraries. build_libtool_need_lc=$archive_cmds_need_lc_CXX # Whether or not to disallow shared libs when runtime libs are static. allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_CXX # Compiler flag to allow reflexive dlopens. export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_CXX # Compiler flag to generate shared objects directly from archives. whole_archive_flag_spec=$lt_whole_archive_flag_spec_CXX # Whether the compiler copes with passing no objects directly. compiler_needs_object=$lt_compiler_needs_object_CXX # Create an old-style archive from a shared archive. old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_CXX # Create a temporary old-style archive to link instead of a shared archive. old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_CXX # Commands used to build a shared archive. archive_cmds=$lt_archive_cmds_CXX archive_expsym_cmds=$lt_archive_expsym_cmds_CXX # Commands used to build a loadable module if different from building # a shared archive. module_cmds=$lt_module_cmds_CXX module_expsym_cmds=$lt_module_expsym_cmds_CXX # Whether we are building with GNU ld or not. with_gnu_ld=$lt_with_gnu_ld_CXX # Flag that allows shared libraries with undefined symbols to be built. allow_undefined_flag=$lt_allow_undefined_flag_CXX # Flag that enforces no undefined symbols. no_undefined_flag=$lt_no_undefined_flag_CXX # Flag to hardcode \$libdir into a binary during linking. # This must work even if \$libdir does not exist hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_CXX # Whether we need a single "-rpath" flag with a separated argument. hardcode_libdir_separator=$lt_hardcode_libdir_separator_CXX # Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes # DIR into the resulting binary. hardcode_direct=$hardcode_direct_CXX # Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes # DIR into the resulting binary and the resulting library dependency is # "absolute",i.e impossible to change by setting \${shlibpath_var} if the # library is relocated. hardcode_direct_absolute=$hardcode_direct_absolute_CXX # Set to "yes" if using the -LDIR flag during linking hardcodes DIR # into the resulting binary. hardcode_minus_L=$hardcode_minus_L_CXX # Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR # into the resulting binary. hardcode_shlibpath_var=$hardcode_shlibpath_var_CXX # Set to "yes" if building a shared library automatically hardcodes DIR # into the library and all subsequent libraries and executables linked # against it. hardcode_automatic=$hardcode_automatic_CXX # Set to yes if linker adds runtime paths of dependent libraries # to runtime path list. inherit_rpath=$inherit_rpath_CXX # Whether libtool must link a program against all its dependency libraries. link_all_deplibs=$link_all_deplibs_CXX # Set to "yes" if exported symbols are required. always_export_symbols=$always_export_symbols_CXX # The commands to list exported symbols. export_symbols_cmds=$lt_export_symbols_cmds_CXX # Symbols that should not be listed in the preloaded symbols. exclude_expsyms=$lt_exclude_expsyms_CXX # Symbols that must always be exported. include_expsyms=$lt_include_expsyms_CXX # Commands necessary for linking programs (against libraries) with templates. prelink_cmds=$lt_prelink_cmds_CXX # Commands necessary for finishing linking programs. postlink_cmds=$lt_postlink_cmds_CXX # Specify filename containing input files. file_list_spec=$lt_file_list_spec_CXX # How to hardcode a shared library path into an executable. hardcode_action=$hardcode_action_CXX # The directories searched by this compiler when creating a shared library. compiler_lib_search_dirs=$lt_compiler_lib_search_dirs_CXX # Dependencies to place before and after the objects being linked to # create a shared library. predep_objects=$lt_predep_objects_CXX postdep_objects=$lt_postdep_objects_CXX predeps=$lt_predeps_CXX postdeps=$lt_postdeps_CXX # The library search path used internally by the compiler when linking # a shared library. compiler_lib_search_path=$lt_compiler_lib_search_path_CXX # ### END LIBTOOL TAG CONFIG: CXX _LT_EOF ;; esac done # for ac_tag as_fn_exit 0 _ACEOF ac_clean_files=$ac_clean_files_save test $ac_write_fail = 0 || as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 # configure is writing to config.log, and then calls config.status. # config.status does its own redirection, appending to config.log. # Unfortunately, on DOS this fails, as config.log is still kept open # by configure, so config.status won't be able to write to it; its # output is simply discarded. So we exec the FD to /dev/null, # effectively closing config.log, so it can be properly (re)opened and # appended to by config.status. When coming back to configure, we # need to make the FD available again. if test "$no_create" != yes; then ac_cs_success=: ac_config_status_args= test "$silent" = yes && ac_config_status_args="$ac_config_status_args --quiet" exec 5>/dev/null $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false exec 5>>config.log # Use ||, not &&, to avoid exiting from the if with $? = 1, which # would make configure fail if this is the last instruction. $ac_cs_success || as_fn_exit 1 fi if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} fi dlt-daemon-2.18.4/gtest-1.7.0/configure.ac000066400000000000000000000050161353342203500177110ustar00rootroot00000000000000m4_include(m4/acx_pthread.m4) # At this point, the Xcode project assumes the version string will be three # integers separated by periods and surrounded by square brackets (e.g. # "[1.0.1]"). It also asumes that there won't be any closing parenthesis # between "AC_INIT(" and the closing ")" including comments and strings. AC_INIT([Google C++ Testing Framework], [1.7.0], [googletestframework@googlegroups.com], [gtest]) # Provide various options to initialize the Autoconf and configure processes. AC_PREREQ([2.59]) AC_CONFIG_SRCDIR([./LICENSE]) AC_CONFIG_MACRO_DIR([m4]) AC_CONFIG_AUX_DIR([build-aux]) AC_CONFIG_HEADERS([build-aux/config.h]) AC_CONFIG_FILES([Makefile]) AC_CONFIG_FILES([scripts/gtest-config], [chmod +x scripts/gtest-config]) # Initialize Automake with various options. We require at least v1.9, prevent # pedantic complaints about package files, and enable various distribution # targets. AM_INIT_AUTOMAKE([1.9 dist-bzip2 dist-zip foreign subdir-objects]) # Check for programs used in building Google Test. AC_PROG_CC AC_PROG_CXX AC_LANG([C++]) AC_PROG_LIBTOOL # TODO(chandlerc@google.com): Currently we aren't running the Python tests # against the interpreter detected by AM_PATH_PYTHON, and so we condition # HAVE_PYTHON by requiring "python" to be in the PATH, and that interpreter's # version to be >= 2.3. This will allow the scripts to use a "/usr/bin/env" # hashbang. PYTHON= # We *do not* allow the user to specify a python interpreter AC_PATH_PROG([PYTHON],[python],[:]) AS_IF([test "$PYTHON" != ":"], [AM_PYTHON_CHECK_VERSION([$PYTHON],[2.3],[:],[PYTHON=":"])]) AM_CONDITIONAL([HAVE_PYTHON],[test "$PYTHON" != ":"]) # Configure pthreads. AC_ARG_WITH([pthreads], [AS_HELP_STRING([--with-pthreads], [use pthreads (default is yes)])], [with_pthreads=$withval], [with_pthreads=check]) have_pthreads=no AS_IF([test "x$with_pthreads" != "xno"], [ACX_PTHREAD( [], [AS_IF([test "x$with_pthreads" != "xcheck"], [AC_MSG_FAILURE( [--with-pthreads was specified, but unable to be used])])]) have_pthreads="$acx_pthread_ok"]) AM_CONDITIONAL([HAVE_PTHREADS],[test "x$have_pthreads" = "xyes"]) AC_SUBST(PTHREAD_CFLAGS) AC_SUBST(PTHREAD_LIBS) # TODO(chandlerc@google.com) Check for the necessary system headers. # TODO(chandlerc@google.com) Check the types, structures, and other compiler # and architecture characteristics. # Output the generated files. No further autoconf macros may be used. AC_OUTPUT dlt-daemon-2.18.4/gtest-1.7.0/fused-src/000077500000000000000000000000001353342203500173145ustar00rootroot00000000000000dlt-daemon-2.18.4/gtest-1.7.0/fused-src/gtest/000077500000000000000000000000001353342203500204425ustar00rootroot00000000000000dlt-daemon-2.18.4/gtest-1.7.0/fused-src/gtest/.deps/000077500000000000000000000000001353342203500214535ustar00rootroot00000000000000dlt-daemon-2.18.4/gtest-1.7.0/fused-src/gtest/.deps/test_fused_gtest_test-gtest-all.Po000066400000000000000000000000101353342203500302460ustar00rootroot00000000000000# dummy dlt-daemon-2.18.4/gtest-1.7.0/fused-src/gtest/.deps/test_fused_gtest_test-gtest_main.Po000066400000000000000000000000101353342203500305040ustar00rootroot00000000000000# dummy dlt-daemon-2.18.4/gtest-1.7.0/fused-src/gtest/gtest-all.cc000066400000000000000000012640701353342203500226570ustar00rootroot00000000000000// Copyright 2008, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: mheule@google.com (Markus Heule) // // Google C++ Testing Framework (Google Test) // // Sometimes it's desirable to build Google Test by compiling a single file. // This file serves this purpose. // This line ensures that gtest.h can be compiled on its own, even // when it's fused. #include "gtest/gtest.h" // The following lines pull in the real gtest *.cc files. // Copyright 2005, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: wan@google.com (Zhanyong Wan) // // The Google C++ Testing Framework (Google Test) // Copyright 2007, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: wan@google.com (Zhanyong Wan) // // Utilities for testing Google Test itself and code that uses Google Test // (e.g. frameworks built on top of Google Test). #ifndef GTEST_INCLUDE_GTEST_GTEST_SPI_H_ #define GTEST_INCLUDE_GTEST_GTEST_SPI_H_ namespace testing { // This helper class can be used to mock out Google Test failure reporting // so that we can test Google Test or code that builds on Google Test. // // An object of this class appends a TestPartResult object to the // TestPartResultArray object given in the constructor whenever a Google Test // failure is reported. It can either intercept only failures that are // generated in the same thread that created this object or it can intercept // all generated failures. The scope of this mock object can be controlled with // the second argument to the two arguments constructor. class GTEST_API_ ScopedFakeTestPartResultReporter : public TestPartResultReporterInterface { public: // The two possible mocking modes of this object. enum InterceptMode { INTERCEPT_ONLY_CURRENT_THREAD, // Intercepts only thread local failures. INTERCEPT_ALL_THREADS // Intercepts all failures. }; // The c'tor sets this object as the test part result reporter used // by Google Test. The 'result' parameter specifies where to report the // results. This reporter will only catch failures generated in the current // thread. DEPRECATED explicit ScopedFakeTestPartResultReporter(TestPartResultArray* result); // Same as above, but you can choose the interception scope of this object. ScopedFakeTestPartResultReporter(InterceptMode intercept_mode, TestPartResultArray* result); // The d'tor restores the previous test part result reporter. virtual ~ScopedFakeTestPartResultReporter(); // Appends the TestPartResult object to the TestPartResultArray // received in the constructor. // // This method is from the TestPartResultReporterInterface // interface. virtual void ReportTestPartResult(const TestPartResult& result); private: void Init(); const InterceptMode intercept_mode_; TestPartResultReporterInterface* old_reporter_; TestPartResultArray* const result_; GTEST_DISALLOW_COPY_AND_ASSIGN_(ScopedFakeTestPartResultReporter); }; namespace internal { // A helper class for implementing EXPECT_FATAL_FAILURE() and // EXPECT_NONFATAL_FAILURE(). Its destructor verifies that the given // TestPartResultArray contains exactly one failure that has the given // type and contains the given substring. If that's not the case, a // non-fatal failure will be generated. class GTEST_API_ SingleFailureChecker { public: // The constructor remembers the arguments. SingleFailureChecker(const TestPartResultArray* results, TestPartResult::Type type, const string& substr); ~SingleFailureChecker(); private: const TestPartResultArray* const results_; const TestPartResult::Type type_; const string substr_; GTEST_DISALLOW_COPY_AND_ASSIGN_(SingleFailureChecker); }; } // namespace internal } // namespace testing // A set of macros for testing Google Test assertions or code that's expected // to generate Google Test fatal failures. It verifies that the given // statement will cause exactly one fatal Google Test failure with 'substr' // being part of the failure message. // // There are two different versions of this macro. EXPECT_FATAL_FAILURE only // affects and considers failures generated in the current thread and // EXPECT_FATAL_FAILURE_ON_ALL_THREADS does the same but for all threads. // // The verification of the assertion is done correctly even when the statement // throws an exception or aborts the current function. // // Known restrictions: // - 'statement' cannot reference local non-static variables or // non-static members of the current object. // - 'statement' cannot return a value. // - You cannot stream a failure message to this macro. // // Note that even though the implementations of the following two // macros are much alike, we cannot refactor them to use a common // helper macro, due to some peculiarity in how the preprocessor // works. The AcceptsMacroThatExpandsToUnprotectedComma test in // gtest_unittest.cc will fail to compile if we do that. #define EXPECT_FATAL_FAILURE(statement, substr) \ do { \ class GTestExpectFatalFailureHelper {\ public:\ static void Execute() { statement; }\ };\ ::testing::TestPartResultArray gtest_failures;\ ::testing::internal::SingleFailureChecker gtest_checker(\ >est_failures, ::testing::TestPartResult::kFatalFailure, (substr));\ {\ ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\ ::testing::ScopedFakeTestPartResultReporter:: \ INTERCEPT_ONLY_CURRENT_THREAD, >est_failures);\ GTestExpectFatalFailureHelper::Execute();\ }\ } while (::testing::internal::AlwaysFalse()) #define EXPECT_FATAL_FAILURE_ON_ALL_THREADS(statement, substr) \ do { \ class GTestExpectFatalFailureHelper {\ public:\ static void Execute() { statement; }\ };\ ::testing::TestPartResultArray gtest_failures;\ ::testing::internal::SingleFailureChecker gtest_checker(\ >est_failures, ::testing::TestPartResult::kFatalFailure, (substr));\ {\ ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\ ::testing::ScopedFakeTestPartResultReporter:: \ INTERCEPT_ALL_THREADS, >est_failures);\ GTestExpectFatalFailureHelper::Execute();\ }\ } while (::testing::internal::AlwaysFalse()) // A macro for testing Google Test assertions or code that's expected to // generate Google Test non-fatal failures. It asserts that the given // statement will cause exactly one non-fatal Google Test failure with 'substr' // being part of the failure message. // // There are two different versions of this macro. EXPECT_NONFATAL_FAILURE only // affects and considers failures generated in the current thread and // EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS does the same but for all threads. // // 'statement' is allowed to reference local variables and members of // the current object. // // The verification of the assertion is done correctly even when the statement // throws an exception or aborts the current function. // // Known restrictions: // - You cannot stream a failure message to this macro. // // Note that even though the implementations of the following two // macros are much alike, we cannot refactor them to use a common // helper macro, due to some peculiarity in how the preprocessor // works. If we do that, the code won't compile when the user gives // EXPECT_NONFATAL_FAILURE() a statement that contains a macro that // expands to code containing an unprotected comma. The // AcceptsMacroThatExpandsToUnprotectedComma test in gtest_unittest.cc // catches that. // // For the same reason, we have to write // if (::testing::internal::AlwaysTrue()) { statement; } // instead of // GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement) // to avoid an MSVC warning on unreachable code. #define EXPECT_NONFATAL_FAILURE(statement, substr) \ do {\ ::testing::TestPartResultArray gtest_failures;\ ::testing::internal::SingleFailureChecker gtest_checker(\ >est_failures, ::testing::TestPartResult::kNonFatalFailure, \ (substr));\ {\ ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\ ::testing::ScopedFakeTestPartResultReporter:: \ INTERCEPT_ONLY_CURRENT_THREAD, >est_failures);\ if (::testing::internal::AlwaysTrue()) { statement; }\ }\ } while (::testing::internal::AlwaysFalse()) #define EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS(statement, substr) \ do {\ ::testing::TestPartResultArray gtest_failures;\ ::testing::internal::SingleFailureChecker gtest_checker(\ >est_failures, ::testing::TestPartResult::kNonFatalFailure, \ (substr));\ {\ ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\ ::testing::ScopedFakeTestPartResultReporter::INTERCEPT_ALL_THREADS, \ >est_failures);\ if (::testing::internal::AlwaysTrue()) { statement; }\ }\ } while (::testing::internal::AlwaysFalse()) #endif // GTEST_INCLUDE_GTEST_GTEST_SPI_H_ #include #include #include #include #include #include #include #include #include #include #include #include // NOLINT #include #include #if GTEST_OS_LINUX // TODO(kenton@google.com): Use autoconf to detect availability of // gettimeofday(). # define GTEST_HAS_GETTIMEOFDAY_ 1 # include // NOLINT # include // NOLINT # include // NOLINT // Declares vsnprintf(). This header is not available on Windows. # include // NOLINT # include // NOLINT # include // NOLINT # include // NOLINT # include #elif GTEST_OS_SYMBIAN # define GTEST_HAS_GETTIMEOFDAY_ 1 # include // NOLINT #elif GTEST_OS_ZOS # define GTEST_HAS_GETTIMEOFDAY_ 1 # include // NOLINT // On z/OS we additionally need strings.h for strcasecmp. # include // NOLINT #elif GTEST_OS_WINDOWS_MOBILE // We are on Windows CE. # include // NOLINT #elif GTEST_OS_WINDOWS // We are on Windows proper. # include // NOLINT # include // NOLINT # include // NOLINT # include // NOLINT # if GTEST_OS_WINDOWS_MINGW // MinGW has gettimeofday() but not _ftime64(). // TODO(kenton@google.com): Use autoconf to detect availability of // gettimeofday(). // TODO(kenton@google.com): There are other ways to get the time on // Windows, like GetTickCount() or GetSystemTimeAsFileTime(). MinGW // supports these. consider using them instead. # define GTEST_HAS_GETTIMEOFDAY_ 1 # include // NOLINT # endif // GTEST_OS_WINDOWS_MINGW // cpplint thinks that the header is already included, so we want to // silence it. # include // NOLINT #else // Assume other platforms have gettimeofday(). // TODO(kenton@google.com): Use autoconf to detect availability of // gettimeofday(). # define GTEST_HAS_GETTIMEOFDAY_ 1 // cpplint thinks that the header is already included, so we want to // silence it. # include // NOLINT # include // NOLINT #endif // GTEST_OS_LINUX #if GTEST_HAS_EXCEPTIONS # include #endif #if GTEST_CAN_STREAM_RESULTS_ # include // NOLINT # include // NOLINT #endif // Indicates that this translation unit is part of Google Test's // implementation. It must come before gtest-internal-inl.h is // included, or there will be a compiler error. This trick is to // prevent a user from accidentally including gtest-internal-inl.h in // his code. #define GTEST_IMPLEMENTATION_ 1 // Copyright 2005, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // Utility functions and classes used by the Google C++ testing framework. // // Author: wan@google.com (Zhanyong Wan) // // This file contains purely Google Test's internal implementation. Please // DO NOT #INCLUDE IT IN A USER PROGRAM. #ifndef GTEST_SRC_GTEST_INTERNAL_INL_H_ #define GTEST_SRC_GTEST_INTERNAL_INL_H_ // GTEST_IMPLEMENTATION_ is defined to 1 iff the current translation unit is // part of Google Test's implementation; otherwise it's undefined. #if !GTEST_IMPLEMENTATION_ // A user is trying to include this from his code - just say no. # error "gtest-internal-inl.h is part of Google Test's internal implementation." # error "It must not be included except by Google Test itself." #endif // GTEST_IMPLEMENTATION_ #ifndef _WIN32_WCE # include #endif // !_WIN32_WCE #include #include // For strtoll/_strtoul64/malloc/free. #include // For memmove. #include #include #include #if GTEST_CAN_STREAM_RESULTS_ # include // NOLINT # include // NOLINT #endif #if GTEST_OS_WINDOWS # include // NOLINT #endif // GTEST_OS_WINDOWS namespace testing { // Declares the flags. // // We don't want the users to modify this flag in the code, but want // Google Test's own unit tests to be able to access it. Therefore we // declare it here as opposed to in gtest.h. GTEST_DECLARE_bool_(death_test_use_fork); namespace internal { // The value of GetTestTypeId() as seen from within the Google Test // library. This is solely for testing GetTestTypeId(). GTEST_API_ extern const TypeId kTestTypeIdInGoogleTest; // Names of the flags (needed for parsing Google Test flags). const char kAlsoRunDisabledTestsFlag[] = "also_run_disabled_tests"; const char kBreakOnFailureFlag[] = "break_on_failure"; const char kCatchExceptionsFlag[] = "catch_exceptions"; const char kColorFlag[] = "color"; const char kFilterFlag[] = "filter"; const char kListTestsFlag[] = "list_tests"; const char kOutputFlag[] = "output"; const char kPrintTimeFlag[] = "print_time"; const char kRandomSeedFlag[] = "random_seed"; const char kRepeatFlag[] = "repeat"; const char kShuffleFlag[] = "shuffle"; const char kStackTraceDepthFlag[] = "stack_trace_depth"; const char kStreamResultToFlag[] = "stream_result_to"; const char kThrowOnFailureFlag[] = "throw_on_failure"; // A valid random seed must be in [1, kMaxRandomSeed]. const int kMaxRandomSeed = 99999; // g_help_flag is true iff the --help flag or an equivalent form is // specified on the command line. GTEST_API_ extern bool g_help_flag; // Returns the current time in milliseconds. GTEST_API_ TimeInMillis GetTimeInMillis(); // Returns true iff Google Test should use colors in the output. GTEST_API_ bool ShouldUseColor(bool stdout_is_tty); // Formats the given time in milliseconds as seconds. GTEST_API_ std::string FormatTimeInMillisAsSeconds(TimeInMillis ms); // Converts the given time in milliseconds to a date string in the ISO 8601 // format, without the timezone information. N.B.: due to the use the // non-reentrant localtime() function, this function is not thread safe. Do // not use it in any code that can be called from multiple threads. GTEST_API_ std::string FormatEpochTimeInMillisAsIso8601(TimeInMillis ms); // Parses a string for an Int32 flag, in the form of "--flag=value". // // On success, stores the value of the flag in *value, and returns // true. On failure, returns false without changing *value. GTEST_API_ bool ParseInt32Flag( const char* str, const char* flag, Int32* value); // Returns a random seed in range [1, kMaxRandomSeed] based on the // given --gtest_random_seed flag value. inline int GetRandomSeedFromFlag(Int32 random_seed_flag) { const unsigned int raw_seed = (random_seed_flag == 0) ? static_cast(GetTimeInMillis()) : static_cast(random_seed_flag); // Normalizes the actual seed to range [1, kMaxRandomSeed] such that // it's easy to type. const int normalized_seed = static_cast((raw_seed - 1U) % static_cast(kMaxRandomSeed)) + 1; return normalized_seed; } // Returns the first valid random seed after 'seed'. The behavior is // undefined if 'seed' is invalid. The seed after kMaxRandomSeed is // considered to be 1. inline int GetNextRandomSeed(int seed) { GTEST_CHECK_(1 <= seed && seed <= kMaxRandomSeed) << "Invalid random seed " << seed << " - must be in [1, " << kMaxRandomSeed << "]."; const int next_seed = seed + 1; return (next_seed > kMaxRandomSeed) ? 1 : next_seed; } // This class saves the values of all Google Test flags in its c'tor, and // restores them in its d'tor. class GTestFlagSaver { public: // The c'tor. GTestFlagSaver() { also_run_disabled_tests_ = GTEST_FLAG(also_run_disabled_tests); break_on_failure_ = GTEST_FLAG(break_on_failure); catch_exceptions_ = GTEST_FLAG(catch_exceptions); color_ = GTEST_FLAG(color); death_test_style_ = GTEST_FLAG(death_test_style); death_test_use_fork_ = GTEST_FLAG(death_test_use_fork); filter_ = GTEST_FLAG(filter); internal_run_death_test_ = GTEST_FLAG(internal_run_death_test); list_tests_ = GTEST_FLAG(list_tests); output_ = GTEST_FLAG(output); print_time_ = GTEST_FLAG(print_time); random_seed_ = GTEST_FLAG(random_seed); repeat_ = GTEST_FLAG(repeat); shuffle_ = GTEST_FLAG(shuffle); stack_trace_depth_ = GTEST_FLAG(stack_trace_depth); stream_result_to_ = GTEST_FLAG(stream_result_to); throw_on_failure_ = GTEST_FLAG(throw_on_failure); } // The d'tor is not virtual. DO NOT INHERIT FROM THIS CLASS. ~GTestFlagSaver() { GTEST_FLAG(also_run_disabled_tests) = also_run_disabled_tests_; GTEST_FLAG(break_on_failure) = break_on_failure_; GTEST_FLAG(catch_exceptions) = catch_exceptions_; GTEST_FLAG(color) = color_; GTEST_FLAG(death_test_style) = death_test_style_; GTEST_FLAG(death_test_use_fork) = death_test_use_fork_; GTEST_FLAG(filter) = filter_; GTEST_FLAG(internal_run_death_test) = internal_run_death_test_; GTEST_FLAG(list_tests) = list_tests_; GTEST_FLAG(output) = output_; GTEST_FLAG(print_time) = print_time_; GTEST_FLAG(random_seed) = random_seed_; GTEST_FLAG(repeat) = repeat_; GTEST_FLAG(shuffle) = shuffle_; GTEST_FLAG(stack_trace_depth) = stack_trace_depth_; GTEST_FLAG(stream_result_to) = stream_result_to_; GTEST_FLAG(throw_on_failure) = throw_on_failure_; } private: // Fields for saving the original values of flags. bool also_run_disabled_tests_; bool break_on_failure_; bool catch_exceptions_; std::string color_; std::string death_test_style_; bool death_test_use_fork_; std::string filter_; std::string internal_run_death_test_; bool list_tests_; std::string output_; bool print_time_; internal::Int32 random_seed_; internal::Int32 repeat_; bool shuffle_; internal::Int32 stack_trace_depth_; std::string stream_result_to_; bool throw_on_failure_; } GTEST_ATTRIBUTE_UNUSED_; // Converts a Unicode code point to a narrow string in UTF-8 encoding. // code_point parameter is of type UInt32 because wchar_t may not be // wide enough to contain a code point. // If the code_point is not a valid Unicode code point // (i.e. outside of Unicode range U+0 to U+10FFFF) it will be converted // to "(Invalid Unicode 0xXXXXXXXX)". GTEST_API_ std::string CodePointToUtf8(UInt32 code_point); // Converts a wide string to a narrow string in UTF-8 encoding. // The wide string is assumed to have the following encoding: // UTF-16 if sizeof(wchar_t) == 2 (on Windows, Cygwin, Symbian OS) // UTF-32 if sizeof(wchar_t) == 4 (on Linux) // Parameter str points to a null-terminated wide string. // Parameter num_chars may additionally limit the number // of wchar_t characters processed. -1 is used when the entire string // should be processed. // If the string contains code points that are not valid Unicode code points // (i.e. outside of Unicode range U+0 to U+10FFFF) they will be output // as '(Invalid Unicode 0xXXXXXXXX)'. If the string is in UTF16 encoding // and contains invalid UTF-16 surrogate pairs, values in those pairs // will be encoded as individual Unicode characters from Basic Normal Plane. GTEST_API_ std::string WideStringToUtf8(const wchar_t* str, int num_chars); // Reads the GTEST_SHARD_STATUS_FILE environment variable, and creates the file // if the variable is present. If a file already exists at this location, this // function will write over it. If the variable is present, but the file cannot // be created, prints an error and exits. void WriteToShardStatusFileIfNeeded(); // Checks whether sharding is enabled by examining the relevant // environment variable values. If the variables are present, // but inconsistent (e.g., shard_index >= total_shards), prints // an error and exits. If in_subprocess_for_death_test, sharding is // disabled because it must only be applied to the original test // process. Otherwise, we could filter out death tests we intended to execute. GTEST_API_ bool ShouldShard(const char* total_shards_str, const char* shard_index_str, bool in_subprocess_for_death_test); // Parses the environment variable var as an Int32. If it is unset, // returns default_val. If it is not an Int32, prints an error and // and aborts. GTEST_API_ Int32 Int32FromEnvOrDie(const char* env_var, Int32 default_val); // Given the total number of shards, the shard index, and the test id, // returns true iff the test should be run on this shard. The test id is // some arbitrary but unique non-negative integer assigned to each test // method. Assumes that 0 <= shard_index < total_shards. GTEST_API_ bool ShouldRunTestOnShard( int total_shards, int shard_index, int test_id); // STL container utilities. // Returns the number of elements in the given container that satisfy // the given predicate. template inline int CountIf(const Container& c, Predicate predicate) { // Implemented as an explicit loop since std::count_if() in libCstd on // Solaris has a non-standard signature. int count = 0; for (typename Container::const_iterator it = c.begin(); it != c.end(); ++it) { if (predicate(*it)) ++count; } return count; } // Applies a function/functor to each element in the container. template void ForEach(const Container& c, Functor functor) { std::for_each(c.begin(), c.end(), functor); } // Returns the i-th element of the vector, or default_value if i is not // in range [0, v.size()). template inline E GetElementOr(const std::vector& v, int i, E default_value) { return (i < 0 || i >= static_cast(v.size())) ? default_value : v[i]; } // Performs an in-place shuffle of a range of the vector's elements. // 'begin' and 'end' are element indices as an STL-style range; // i.e. [begin, end) are shuffled, where 'end' == size() means to // shuffle to the end of the vector. template void ShuffleRange(internal::Random* random, int begin, int end, std::vector* v) { const int size = static_cast(v->size()); GTEST_CHECK_(0 <= begin && begin <= size) << "Invalid shuffle range start " << begin << ": must be in range [0, " << size << "]."; GTEST_CHECK_(begin <= end && end <= size) << "Invalid shuffle range finish " << end << ": must be in range [" << begin << ", " << size << "]."; // Fisher-Yates shuffle, from // http://en.wikipedia.org/wiki/Fisher-Yates_shuffle for (int range_width = end - begin; range_width >= 2; range_width--) { const int last_in_range = begin + range_width - 1; const int selected = begin + random->Generate(range_width); std::swap((*v)[selected], (*v)[last_in_range]); } } // Performs an in-place shuffle of the vector's elements. template inline void Shuffle(internal::Random* random, std::vector* v) { ShuffleRange(random, 0, static_cast(v->size()), v); } // A function for deleting an object. Handy for being used as a // functor. template static void Delete(T* x) { delete x; } // A predicate that checks the key of a TestProperty against a known key. // // TestPropertyKeyIs is copyable. class TestPropertyKeyIs { public: // Constructor. // // TestPropertyKeyIs has NO default constructor. explicit TestPropertyKeyIs(const std::string& key) : key_(key) {} // Returns true iff the test name of test property matches on key_. bool operator()(const TestProperty& test_property) const { return test_property.key() == key_; } private: std::string key_; }; // Class UnitTestOptions. // // This class contains functions for processing options the user // specifies when running the tests. It has only static members. // // In most cases, the user can specify an option using either an // environment variable or a command line flag. E.g. you can set the // test filter using either GTEST_FILTER or --gtest_filter. If both // the variable and the flag are present, the latter overrides the // former. class GTEST_API_ UnitTestOptions { public: // Functions for processing the gtest_output flag. // Returns the output format, or "" for normal printed output. static std::string GetOutputFormat(); // Returns the absolute path of the requested output file, or the // default (test_detail.xml in the original working directory) if // none was explicitly specified. static std::string GetAbsolutePathToOutputFile(); // Functions for processing the gtest_filter flag. // Returns true iff the wildcard pattern matches the string. The // first ':' or '\0' character in pattern marks the end of it. // // This recursive algorithm isn't very efficient, but is clear and // works well enough for matching test names, which are short. static bool PatternMatchesString(const char *pattern, const char *str); // Returns true iff the user-specified filter matches the test case // name and the test name. static bool FilterMatchesTest(const std::string &test_case_name, const std::string &test_name); #if GTEST_OS_WINDOWS // Function for supporting the gtest_catch_exception flag. // Returns EXCEPTION_EXECUTE_HANDLER if Google Test should handle the // given SEH exception, or EXCEPTION_CONTINUE_SEARCH otherwise. // This function is useful as an __except condition. static int GTestShouldProcessSEH(DWORD exception_code); #endif // GTEST_OS_WINDOWS // Returns true if "name" matches the ':' separated list of glob-style // filters in "filter". static bool MatchesFilter(const std::string& name, const char* filter); }; // Returns the current application's name, removing directory path if that // is present. Used by UnitTestOptions::GetOutputFile. GTEST_API_ FilePath GetCurrentExecutableName(); // The role interface for getting the OS stack trace as a string. class OsStackTraceGetterInterface { public: OsStackTraceGetterInterface() {} virtual ~OsStackTraceGetterInterface() {} // Returns the current OS stack trace as 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. virtual string CurrentStackTrace(int max_depth, int skip_count) = 0; // UponLeavingGTest() should be called immediately before Google Test calls // user code. It saves some information about the current stack that // CurrentStackTrace() will use to find and hide Google Test stack frames. virtual void UponLeavingGTest() = 0; private: GTEST_DISALLOW_COPY_AND_ASSIGN_(OsStackTraceGetterInterface); }; // A working implementation of the OsStackTraceGetterInterface interface. class OsStackTraceGetter : public OsStackTraceGetterInterface { public: OsStackTraceGetter() : caller_frame_(NULL) {} virtual string CurrentStackTrace(int max_depth, int skip_count) 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; private: Mutex mutex_; // protects all internal state // We save the stack frame below the frame that calls user code. // We do this because the address of the frame immediately below // the user code changes between the call to UponLeavingGTest() // and any calls to CurrentStackTrace() from within the user code. void* caller_frame_; GTEST_DISALLOW_COPY_AND_ASSIGN_(OsStackTraceGetter); }; // Information about a Google Test trace point. struct TraceInfo { const char* file; int line; std::string message; }; // This is the default global test part result reporter used in UnitTestImpl. // This class should only be used by UnitTestImpl. class DefaultGlobalTestPartResultReporter : public TestPartResultReporterInterface { public: explicit DefaultGlobalTestPartResultReporter(UnitTestImpl* unit_test); // Implements the TestPartResultReporterInterface. Reports the test part // result in the current test. virtual void ReportTestPartResult(const TestPartResult& result); private: UnitTestImpl* const unit_test_; GTEST_DISALLOW_COPY_AND_ASSIGN_(DefaultGlobalTestPartResultReporter); }; // This is the default per thread test part result reporter used in // UnitTestImpl. This class should only be used by UnitTestImpl. class DefaultPerThreadTestPartResultReporter : public TestPartResultReporterInterface { public: explicit DefaultPerThreadTestPartResultReporter(UnitTestImpl* unit_test); // Implements the TestPartResultReporterInterface. The implementation just // delegates to the current global test part result reporter of *unit_test_. virtual void ReportTestPartResult(const TestPartResult& result); private: UnitTestImpl* const unit_test_; GTEST_DISALLOW_COPY_AND_ASSIGN_(DefaultPerThreadTestPartResultReporter); }; // The private implementation of the UnitTest class. We don't protect // the methods under a mutex, as this class is not accessible by a // user and the UnitTest class that delegates work to this class does // proper locking. class GTEST_API_ UnitTestImpl { public: explicit UnitTestImpl(UnitTest* parent); virtual ~UnitTestImpl(); // There are two different ways to register your own TestPartResultReporter. // You can register your own repoter to listen either only for test results // from the current thread or for results from all threads. // By default, each per-thread test result repoter just passes a new // TestPartResult to the global test result reporter, which registers the // test part result for the currently running test. // Returns the global test part result reporter. TestPartResultReporterInterface* GetGlobalTestPartResultReporter(); // Sets the global test part result reporter. void SetGlobalTestPartResultReporter( TestPartResultReporterInterface* reporter); // Returns the test part result reporter for the current thread. TestPartResultReporterInterface* GetTestPartResultReporterForCurrentThread(); // Sets the test part result reporter for the current thread. void SetTestPartResultReporterForCurrentThread( TestPartResultReporterInterface* reporter); // Gets the number of successful test cases. int successful_test_case_count() const; // Gets the number of failed test cases. int failed_test_case_count() const; // Gets the number of all test cases. int total_test_case_count() const; // Gets the number of all test cases that contain at least one test // that should run. int test_case_to_run_count() const; // Gets the number of successful tests. int successful_test_count() const; // Gets the number of failed tests. int failed_test_count() const; // Gets the number of disabled tests that will be reported in the XML report. int reportable_disabled_test_count() const; // Gets the number of disabled tests. int disabled_test_count() const; // Gets the number of tests to be printed in the XML report. int reportable_test_count() const; // Gets the number of all tests. int total_test_count() const; // Gets the number of tests that should run. int test_to_run_count() const; // Gets the time of the test program start, in ms from the start of the // UNIX epoch. TimeInMillis start_timestamp() const { return start_timestamp_; } // Gets the elapsed time, in milliseconds. TimeInMillis elapsed_time() const { return elapsed_time_; } // Returns true iff the unit test passed (i.e. all test cases passed). bool Passed() const { return !Failed(); } // Returns true iff the unit test failed (i.e. some test case failed // or something outside of all tests failed). bool Failed() const { return failed_test_case_count() > 0 || ad_hoc_test_result()->Failed(); } // Gets the i-th test case among all the test cases. i can range from 0 to // total_test_case_count() - 1. If i is not in that range, returns NULL. const TestCase* GetTestCase(int i) const { const int index = GetElementOr(test_case_indices_, i, -1); return index < 0 ? NULL : test_cases_[i]; } // Gets the i-th test case among all the test cases. i can range from 0 to // total_test_case_count() - 1. If i is not in that range, returns NULL. TestCase* GetMutableTestCase(int i) { const int index = GetElementOr(test_case_indices_, i, -1); return index < 0 ? NULL : test_cases_[index]; } // Provides access to the event listener list. TestEventListeners* listeners() { return &listeners_; } // Returns the TestResult for the test that's currently running, or // the TestResult for the ad hoc test if no test is running. TestResult* current_test_result(); // Returns the TestResult for the ad hoc test. const TestResult* ad_hoc_test_result() const { return &ad_hoc_test_result_; } // Sets the OS stack trace getter. // // Does nothing if the input and the current OS stack trace getter // are the same; otherwise, deletes the old getter and makes the // input the current getter. void set_os_stack_trace_getter(OsStackTraceGetterInterface* getter); // Returns the current OS stack trace getter if it is not NULL; // otherwise, creates an OsStackTraceGetter, makes it the current // getter, and returns it. OsStackTraceGetterInterface* os_stack_trace_getter(); // Returns the current OS stack trace as an std::string. // // The maximum number of stack frames to be included is specified by // the gtest_stack_trace_depth flag. The skip_count parameter // specifies the number of top frames to be skipped, which doesn't // count against the number of frames to be included. // // For example, if Foo() calls Bar(), which in turn calls // CurrentOsStackTraceExceptTop(1), Foo() will be included in the // trace but Bar() and CurrentOsStackTraceExceptTop() won't. std::string CurrentOsStackTraceExceptTop(int skip_count) GTEST_NO_INLINE_; // Finds and returns a TestCase with the given name. If one doesn't // exist, creates one and returns it. // // Arguments: // // test_case_name: name of the test case // type_param: the name of the test's type parameter, or NULL if // this is not a typed or a type-parameterized test. // set_up_tc: pointer to the function that sets up the test case // tear_down_tc: pointer to the function that tears down the test case TestCase* GetTestCase(const char* test_case_name, const char* type_param, Test::SetUpTestCaseFunc set_up_tc, Test::TearDownTestCaseFunc tear_down_tc); // Adds a TestInfo to the unit test. // // Arguments: // // set_up_tc: pointer to the function that sets up the test case // tear_down_tc: pointer to the function that tears down the test case // test_info: the TestInfo object void AddTestInfo(Test::SetUpTestCaseFunc set_up_tc, Test::TearDownTestCaseFunc tear_down_tc, TestInfo* test_info) { // In order to support thread-safe death tests, we need to // remember the original working directory when the test program // was first invoked. We cannot do this in RUN_ALL_TESTS(), as // the user may have changed the current directory before calling // RUN_ALL_TESTS(). Therefore we capture the current directory in // AddTestInfo(), which is called to register a TEST or TEST_F // before main() is reached. if (original_working_dir_.IsEmpty()) { original_working_dir_.Set(FilePath::GetCurrentDir()); GTEST_CHECK_(!original_working_dir_.IsEmpty()) << "Failed to get the current working directory."; } GetTestCase(test_info->test_case_name(), test_info->type_param(), set_up_tc, tear_down_tc)->AddTestInfo(test_info); } #if GTEST_HAS_PARAM_TEST // Returns ParameterizedTestCaseRegistry object used to keep track of // value-parameterized tests and instantiate and register them. internal::ParameterizedTestCaseRegistry& parameterized_test_registry() { return parameterized_test_registry_; } #endif // GTEST_HAS_PARAM_TEST // Sets the TestCase object for the test that's currently running. void set_current_test_case(TestCase* a_current_test_case) { current_test_case_ = a_current_test_case; } // Sets the TestInfo object for the test that's currently running. If // current_test_info is NULL, the assertion results will be stored in // ad_hoc_test_result_. void set_current_test_info(TestInfo* a_current_test_info) { current_test_info_ = a_current_test_info; } // Registers all parameterized tests defined using TEST_P and // INSTANTIATE_TEST_CASE_P, creating regular tests for each test/parameter // combination. This method can be called more then once; it has guards // protecting from registering the tests more then once. If // value-parameterized tests are disabled, RegisterParameterizedTests is // present but does nothing. void RegisterParameterizedTests(); // Runs all tests in this UnitTest object, prints the result, and // returns true if all tests are successful. If any exception is // thrown during a test, this test is considered to be failed, but // the rest of the tests will still be run. bool RunAllTests(); // Clears the results of all tests, except the ad hoc tests. void ClearNonAdHocTestResult() { ForEach(test_cases_, TestCase::ClearTestCaseResult); } // Clears the results of ad-hoc test assertions. void ClearAdHocTestResult() { ad_hoc_test_result_.Clear(); } // Adds a TestProperty to the current TestResult object when invoked in a // context of a test or a test case, or to the global property set. If the // result already contains a property with the same key, the value will be // updated. void RecordProperty(const TestProperty& test_property); enum ReactionToSharding { HONOR_SHARDING_PROTOCOL, IGNORE_SHARDING_PROTOCOL }; // Matches the full name of each test against the user-specified // filter to decide whether the test should run, then records the // result in each TestCase and TestInfo object. // If shard_tests == HONOR_SHARDING_PROTOCOL, further filters tests // based on sharding variables in the environment. // Returns the number of tests that should run. int FilterTests(ReactionToSharding shard_tests); // Prints the names of the tests matching the user-specified filter flag. void ListTestsMatchingFilter(); const TestCase* current_test_case() const { return current_test_case_; } TestInfo* current_test_info() { return current_test_info_; } const TestInfo* current_test_info() const { return current_test_info_; } // Returns the vector of environments that need to be set-up/torn-down // before/after the tests are run. std::vector& environments() { return environments_; } // Getters for the per-thread Google Test trace stack. std::vector& gtest_trace_stack() { return *(gtest_trace_stack_.pointer()); } const std::vector& gtest_trace_stack() const { return gtest_trace_stack_.get(); } #if GTEST_HAS_DEATH_TEST void InitDeathTestSubprocessControlInfo() { internal_run_death_test_flag_.reset(ParseInternalRunDeathTestFlag()); } // Returns a pointer to the parsed --gtest_internal_run_death_test // flag, or NULL if that flag was not specified. // This information is useful only in a death test child process. // Must not be called before a call to InitGoogleTest. const InternalRunDeathTestFlag* internal_run_death_test_flag() const { return internal_run_death_test_flag_.get(); } // Returns a pointer to the current death test factory. internal::DeathTestFactory* death_test_factory() { return death_test_factory_.get(); } void SuppressTestEventsIfInSubprocess(); friend class ReplaceDeathTestFactory; #endif // GTEST_HAS_DEATH_TEST // Initializes the event listener performing XML output as specified by // UnitTestOptions. Must not be called before InitGoogleTest. void ConfigureXmlOutput(); #if GTEST_CAN_STREAM_RESULTS_ // Initializes the event listener for streaming test results to a socket. // Must not be called before InitGoogleTest. void ConfigureStreamingOutput(); #endif // Performs initialization dependent upon flag values obtained in // ParseGoogleTestFlagsOnly. Is called from InitGoogleTest after the call to // ParseGoogleTestFlagsOnly. In case a user neglects to call InitGoogleTest // this function is also called from RunAllTests. Since this function can be // called more than once, it has to be idempotent. void PostFlagParsingInit(); // Gets the random seed used at the start of the current test iteration. int random_seed() const { return random_seed_; } // Gets the random number generator. internal::Random* random() { return &random_; } // Shuffles all test cases, and the tests within each test case, // making sure that death tests are still run first. void ShuffleTests(); // Restores the test cases and tests to their order before the first shuffle. void UnshuffleTests(); // Returns the value of GTEST_FLAG(catch_exceptions) at the moment // UnitTest::Run() starts. bool catch_exceptions() const { return catch_exceptions_; } private: friend class ::testing::UnitTest; // Used by UnitTest::Run() to capture the state of // GTEST_FLAG(catch_exceptions) at the moment it starts. void set_catch_exceptions(bool value) { catch_exceptions_ = value; } // The UnitTest object that owns this implementation object. UnitTest* const parent_; // The working directory when the first TEST() or TEST_F() was // executed. internal::FilePath original_working_dir_; // The default test part result reporters. DefaultGlobalTestPartResultReporter default_global_test_part_result_reporter_; DefaultPerThreadTestPartResultReporter default_per_thread_test_part_result_reporter_; // Points to (but doesn't own) the global test part result reporter. TestPartResultReporterInterface* global_test_part_result_repoter_; // Protects read and write access to global_test_part_result_reporter_. internal::Mutex global_test_part_result_reporter_mutex_; // Points to (but doesn't own) the per-thread test part result reporter. internal::ThreadLocal per_thread_test_part_result_reporter_; // The vector of environments that need to be set-up/torn-down // before/after the tests are run. std::vector environments_; // The vector of TestCases in their original order. It owns the // elements in the vector. std::vector test_cases_; // Provides a level of indirection for the test case list to allow // easy shuffling and restoring the test case order. The i-th // element of this vector is the index of the i-th test case in the // shuffled order. std::vector test_case_indices_; #if GTEST_HAS_PARAM_TEST // ParameterizedTestRegistry object used to register value-parameterized // tests. internal::ParameterizedTestCaseRegistry parameterized_test_registry_; // Indicates whether RegisterParameterizedTests() has been called already. bool parameterized_tests_registered_; #endif // GTEST_HAS_PARAM_TEST // Index of the last death test case registered. Initially -1. int last_death_test_case_; // This points to the TestCase for the currently running test. It // changes as Google Test goes through one test case after another. // When no test is running, this is set to NULL and Google Test // stores assertion results in ad_hoc_test_result_. Initially NULL. TestCase* current_test_case_; // This points to the TestInfo for the currently running test. It // changes as Google Test goes through one test after another. When // no test is running, this is set to NULL and Google Test stores // assertion results in ad_hoc_test_result_. Initially NULL. TestInfo* current_test_info_; // Normally, a user only writes assertions inside a TEST or TEST_F, // or inside a function called by a TEST or TEST_F. Since Google // Test keeps track of which test is current running, it can // associate such an assertion with the test it belongs to. // // If an assertion is encountered when no TEST or TEST_F is running, // Google Test attributes the assertion result to an imaginary "ad hoc" // test, and records the result in ad_hoc_test_result_. TestResult ad_hoc_test_result_; // The list of event listeners that can be used to track events inside // Google Test. TestEventListeners listeners_; // The OS stack trace getter. Will be deleted when the UnitTest // object is destructed. By default, an OsStackTraceGetter is used, // but the user can set this field to use a custom getter if that is // desired. OsStackTraceGetterInterface* os_stack_trace_getter_; // True iff PostFlagParsingInit() has been called. bool post_flag_parse_init_performed_; // The random number seed used at the beginning of the test run. int random_seed_; // Our random number generator. internal::Random random_; // The time of the test program start, in ms from the start of the // UNIX epoch. TimeInMillis start_timestamp_; // How long the test took to run, in milliseconds. TimeInMillis elapsed_time_; #if GTEST_HAS_DEATH_TEST // The decomposed components of the gtest_internal_run_death_test flag, // parsed when RUN_ALL_TESTS is called. internal::scoped_ptr internal_run_death_test_flag_; internal::scoped_ptr death_test_factory_; #endif // GTEST_HAS_DEATH_TEST // A per-thread stack of traces created by the SCOPED_TRACE() macro. internal::ThreadLocal > gtest_trace_stack_; // The value of GTEST_FLAG(catch_exceptions) at the moment RunAllTests() // starts. bool catch_exceptions_; GTEST_DISALLOW_COPY_AND_ASSIGN_(UnitTestImpl); }; // class UnitTestImpl // Convenience function for accessing the global UnitTest // implementation object. inline UnitTestImpl* GetUnitTestImpl() { return UnitTest::GetInstance()->impl(); } #if GTEST_USES_SIMPLE_RE // Internal helper functions for implementing the simple regular // expression matcher. GTEST_API_ bool IsInSet(char ch, const char* str); GTEST_API_ bool IsAsciiDigit(char ch); GTEST_API_ bool IsAsciiPunct(char ch); GTEST_API_ bool IsRepeat(char ch); GTEST_API_ bool IsAsciiWhiteSpace(char ch); GTEST_API_ bool IsAsciiWordChar(char ch); GTEST_API_ bool IsValidEscape(char ch); GTEST_API_ bool AtomMatchesChar(bool escaped, char pattern, char ch); GTEST_API_ bool ValidateRegex(const char* regex); GTEST_API_ bool MatchRegexAtHead(const char* regex, const char* str); GTEST_API_ bool MatchRepetitionAndRegexAtHead( bool escaped, char ch, char repeat, const char* regex, const char* str); GTEST_API_ bool MatchRegexAnywhere(const char* regex, const char* str); #endif // GTEST_USES_SIMPLE_RE // Parses the command line for Google Test flags, without initializing // other parts of Google Test. GTEST_API_ void ParseGoogleTestFlagsOnly(int* argc, char** argv); GTEST_API_ void ParseGoogleTestFlagsOnly(int* argc, wchar_t** argv); #if GTEST_HAS_DEATH_TEST // Returns the message describing the last system error, regardless of the // platform. GTEST_API_ 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 // it here. template bool ParseNaturalNumber(const ::std::string& str, Integer* number) { // Fail fast if the given string does not begin with a digit; // this bypasses strtoXXX's "optional leading whitespace and plus // or minus sign" semantics, which are undesirable here. if (str.empty() || !IsDigit(str[0])) { return false; } errno = 0; char* end; // BiggestConvertible is the largest integer type that system-provided // string-to-number conversion routines can return. # if GTEST_OS_WINDOWS && !defined(__GNUC__) // MSVC and C++ Builder define __int64 instead of the standard long long. typedef unsigned __int64 BiggestConvertible; const BiggestConvertible parsed = _strtoui64(str.c_str(), &end, 10); # else typedef unsigned long long BiggestConvertible; // NOLINT const BiggestConvertible parsed = strtoull(str.c_str(), &end, 10); # endif // GTEST_OS_WINDOWS && !defined(__GNUC__) const bool parse_success = *end == '\0' && errno == 0; // TODO(vladl@google.com): Convert this to compile time assertion when it is // available. GTEST_CHECK_(sizeof(Integer) <= sizeof(parsed)); const Integer result = static_cast(parsed); if (parse_success && static_cast(result) == parsed) { *number = result; return true; } return false; } #endif // GTEST_HAS_DEATH_TEST // TestResult contains some private methods that should be hidden from // Google Test user but are required for testing. This class allow our tests // to access them. // // This class is supplied only for the purpose of testing Google Test's own // constructs. Do not use it in user tests, either directly or indirectly. class TestResultAccessor { public: static void RecordProperty(TestResult* test_result, const std::string& xml_element, const TestProperty& property) { test_result->RecordProperty(xml_element, property); } static void ClearTestPartResults(TestResult* test_result) { test_result->ClearTestPartResults(); } static const std::vector& test_part_results( const TestResult& test_result) { return test_result.test_part_results(); } }; #if GTEST_CAN_STREAM_RESULTS_ // Streams test results to the given port on the given host machine. class StreamingListener : public EmptyTestEventListener { public: // Abstract base class for writing strings to a socket. class AbstractSocketWriter { public: virtual ~AbstractSocketWriter() {} // Sends a string to the socket. virtual void Send(const string& message) = 0; // Closes the socket. virtual void CloseConnection() {} // Sends a string and a newline to the socket. void SendLn(const string& message) { Send(message + "\n"); } }; // Concrete class for actually writing strings to a socket. class SocketWriter : public AbstractSocketWriter { public: SocketWriter(const string& host, const string& port) : sockfd_(-1), host_name_(host), port_num_(port) { MakeConnection(); } virtual ~SocketWriter() { if (sockfd_ != -1) CloseConnection(); } // Sends a string to the socket. virtual void Send(const string& message) { GTEST_CHECK_(sockfd_ != -1) << "Send() can be called only when there is a connection."; const int len = static_cast(message.length()); if (write(sockfd_, message.c_str(), len) != len) { GTEST_LOG_(WARNING) << "stream_result_to: failed to stream to " << host_name_ << ":" << port_num_; } } private: // Creates a client socket and connects to the server. void MakeConnection(); // Closes the socket. void CloseConnection() { GTEST_CHECK_(sockfd_ != -1) << "CloseConnection() can be called only when there is a connection."; close(sockfd_); sockfd_ = -1; } int sockfd_; // socket file descriptor const string host_name_; const string port_num_; GTEST_DISALLOW_COPY_AND_ASSIGN_(SocketWriter); }; // class SocketWriter // Escapes '=', '&', '%', and '\n' characters in str as "%xx". static string UrlEncode(const char* str); StreamingListener(const string& host, const string& port) : socket_writer_(new SocketWriter(host, port)) { Start(); } explicit StreamingListener(AbstractSocketWriter* socket_writer) : socket_writer_(socket_writer) { Start(); } void OnTestProgramStart(const UnitTest& /* unit_test */) { SendLn("event=TestProgramStart"); } void OnTestProgramEnd(const UnitTest& unit_test) { // Note that Google Test current only report elapsed time for each // test iteration, not for the entire test program. SendLn("event=TestProgramEnd&passed=" + FormatBool(unit_test.Passed())); // Notify the streaming server to stop. socket_writer_->CloseConnection(); } void OnTestIterationStart(const UnitTest& /* unit_test */, int iteration) { SendLn("event=TestIterationStart&iteration=" + StreamableToString(iteration)); } void OnTestIterationEnd(const UnitTest& unit_test, int /* iteration */) { SendLn("event=TestIterationEnd&passed=" + FormatBool(unit_test.Passed()) + "&elapsed_time=" + StreamableToString(unit_test.elapsed_time()) + "ms"); } void OnTestCaseStart(const TestCase& test_case) { SendLn(std::string("event=TestCaseStart&name=") + test_case.name()); } void OnTestCaseEnd(const TestCase& test_case) { SendLn("event=TestCaseEnd&passed=" + FormatBool(test_case.Passed()) + "&elapsed_time=" + StreamableToString(test_case.elapsed_time()) + "ms"); } void OnTestStart(const TestInfo& test_info) { SendLn(std::string("event=TestStart&name=") + test_info.name()); } void OnTestEnd(const TestInfo& test_info) { SendLn("event=TestEnd&passed=" + FormatBool((test_info.result())->Passed()) + "&elapsed_time=" + StreamableToString((test_info.result())->elapsed_time()) + "ms"); } void OnTestPartResult(const TestPartResult& test_part_result) { const char* file_name = test_part_result.file_name(); if (file_name == NULL) file_name = ""; SendLn("event=TestPartResult&file=" + UrlEncode(file_name) + "&line=" + StreamableToString(test_part_result.line_number()) + "&message=" + UrlEncode(test_part_result.message())); } private: // Sends the given message and a newline to the socket. void SendLn(const string& message) { socket_writer_->SendLn(message); } // Called at the start of streaming to notify the receiver what // protocol we are using. void Start() { SendLn("gtest_streaming_protocol_version=1.0"); } string FormatBool(bool value) { return value ? "1" : "0"; } const scoped_ptr socket_writer_; GTEST_DISALLOW_COPY_AND_ASSIGN_(StreamingListener); }; // class StreamingListener #endif // GTEST_CAN_STREAM_RESULTS_ } // namespace internal } // namespace testing #endif // GTEST_SRC_GTEST_INTERNAL_INL_H_ #undef GTEST_IMPLEMENTATION_ #if GTEST_OS_WINDOWS # define vsnprintf _vsnprintf #endif // GTEST_OS_WINDOWS namespace testing { using internal::CountIf; using internal::ForEach; using internal::GetElementOr; using internal::Shuffle; // Constants. // A test whose test case name or test name matches this filter is // disabled and not run. static const char kDisableTestFilter[] = "DISABLED_*:*/DISABLED_*"; // A test case whose name matches this filter is considered a death // test case and will be run before test cases whose name doesn't // match this filter. static const char kDeathTestCaseFilter[] = "*DeathTest:*DeathTest/*"; // A test filter that matches everything. static const char kUniversalFilter[] = "*"; // The default output file for XML output. static const char kDefaultOutputFile[] = "test_detail.xml"; // The environment variable name for the test shard index. static const char kTestShardIndex[] = "GTEST_SHARD_INDEX"; // The environment variable name for the total number of test shards. static const char kTestTotalShards[] = "GTEST_TOTAL_SHARDS"; // The environment variable name for the test shard status file. static const char kTestShardStatusFile[] = "GTEST_SHARD_STATUS_FILE"; namespace internal { // The text used in failure messages to indicate the start of the // stack trace. const char kStackTraceMarker[] = "\nStack trace:\n"; // g_help_flag is true iff the --help flag or an equivalent form is // specified on the command line. bool g_help_flag = false; } // namespace internal static const char* GetDefaultFilter() { return kUniversalFilter; } GTEST_DEFINE_bool_( also_run_disabled_tests, internal::BoolFromGTestEnv("also_run_disabled_tests", false), "Run disabled tests too, in addition to the tests normally being run."); GTEST_DEFINE_bool_( break_on_failure, internal::BoolFromGTestEnv("break_on_failure", false), "True iff a failed assertion should be a debugger break-point."); GTEST_DEFINE_bool_( catch_exceptions, internal::BoolFromGTestEnv("catch_exceptions", true), "True iff " GTEST_NAME_ " should catch exceptions and treat them as test failures."); GTEST_DEFINE_string_( color, internal::StringFromGTestEnv("color", "auto"), "Whether to use colors in the output. Valid values: yes, no, " "and auto. 'auto' means to use colors if the output is " "being sent to a terminal and the TERM environment variable " "is set to a terminal type that supports colors."); GTEST_DEFINE_string_( filter, internal::StringFromGTestEnv("filter", GetDefaultFilter()), "A colon-separated list of glob (not regex) patterns " "for filtering the tests to run, optionally followed by a " "'-' and a : separated list of negative patterns (tests to " "exclude). A test is run if it matches one of the positive " "patterns and does not match any of the negative patterns."); GTEST_DEFINE_bool_(list_tests, false, "List all tests without running them."); GTEST_DEFINE_string_( output, internal::StringFromGTestEnv("output", ""), "A format (currently must be \"xml\"), optionally followed " "by a colon and an output file name or directory. A directory " "is indicated by a trailing pathname separator. " "Examples: \"xml:filename.xml\", \"xml::directoryname/\". " "If a directory is specified, output files will be created " "within that directory, with file-names based on the test " "executable's name and, if necessary, made unique by adding " "digits."); GTEST_DEFINE_bool_( print_time, internal::BoolFromGTestEnv("print_time", true), "True iff " GTEST_NAME_ " should display elapsed time in text output."); GTEST_DEFINE_int32_( random_seed, internal::Int32FromGTestEnv("random_seed", 0), "Random number seed to use when shuffling test orders. Must be in range " "[1, 99999], or 0 to use a seed based on the current time."); GTEST_DEFINE_int32_( repeat, internal::Int32FromGTestEnv("repeat", 1), "How many times to repeat each test. Specify a negative number " "for repeating forever. Useful for shaking out flaky tests."); GTEST_DEFINE_bool_( show_internal_stack_frames, false, "True iff " GTEST_NAME_ " should include internal stack frames when " "printing test failure stack traces."); GTEST_DEFINE_bool_( shuffle, internal::BoolFromGTestEnv("shuffle", false), "True iff " GTEST_NAME_ " should randomize tests' order on every run."); GTEST_DEFINE_int32_( stack_trace_depth, internal::Int32FromGTestEnv("stack_trace_depth", kMaxStackTraceDepth), "The maximum number of stack frames to print when an " "assertion fails. The valid range is 0 through 100, inclusive."); GTEST_DEFINE_string_( stream_result_to, internal::StringFromGTestEnv("stream_result_to", ""), "This flag specifies the host name and the port number on which to stream " "test results. Example: \"localhost:555\". The flag is effective only on " "Linux."); GTEST_DEFINE_bool_( throw_on_failure, internal::BoolFromGTestEnv("throw_on_failure", false), "When this flag is specified, a failed assertion will throw an exception " "if exceptions are enabled or exit the program with a non-zero code " "otherwise."); namespace internal { // Generates a random number from [0, range), using a Linear // Congruential Generator (LCG). Crashes if 'range' is 0 or greater // than kMaxRange. UInt32 Random::Generate(UInt32 range) { // These constants are the same as are used in glibc's rand(3). state_ = (1103515245U*state_ + 12345U) % kMaxRange; GTEST_CHECK_(range > 0) << "Cannot generate a number in the range [0, 0)."; GTEST_CHECK_(range <= kMaxRange) << "Generation of a number in [0, " << range << ") was requested, " << "but this can only generate numbers in [0, " << kMaxRange << ")."; // Converting via modulus introduces a bit of downward bias, but // it's simple, and a linear congruential generator isn't too good // to begin with. return state_ % range; } // GTestIsInitialized() returns true iff the user has initialized // Google Test. Useful for catching the user mistake of not initializing // Google Test before calling RUN_ALL_TESTS(). // // A user must call testing::InitGoogleTest() to initialize Google // Test. g_init_gtest_count is set to the number of times // InitGoogleTest() has been called. We don't protect this variable // under a mutex as it is only accessed in the main thread. GTEST_API_ int g_init_gtest_count = 0; static bool GTestIsInitialized() { return g_init_gtest_count != 0; } // Iterates over a vector of TestCases, keeping a running sum of the // results of calling a given int-returning method on each. // Returns the sum. static int SumOverTestCaseList(const std::vector& case_list, int (TestCase::*method)() const) { int sum = 0; for (size_t i = 0; i < case_list.size(); i++) { sum += (case_list[i]->*method)(); } return sum; } // Returns true iff the test case passed. static bool TestCasePassed(const TestCase* test_case) { return test_case->should_run() && test_case->Passed(); } // Returns true iff the test case failed. static bool TestCaseFailed(const TestCase* test_case) { return test_case->should_run() && test_case->Failed(); } // Returns true iff test_case contains at least one test that should // run. static bool ShouldRunTestCase(const TestCase* test_case) { return test_case->should_run(); } // AssertHelper constructor. AssertHelper::AssertHelper(TestPartResult::Type type, const char* file, int line, const char* message) : data_(new AssertHelperData(type, file, line, message)) { } AssertHelper::~AssertHelper() { delete data_; } // Message assignment, for assertion streaming support. void AssertHelper::operator=(const Message& message) const { UnitTest::GetInstance()-> AddTestPartResult(data_->type, data_->file, data_->line, AppendUserMessage(data_->message, message), UnitTest::GetInstance()->impl() ->CurrentOsStackTraceExceptTop(1) // Skips the stack frame for this function itself. ); // NOLINT } // Mutex for linked pointers. GTEST_API_ GTEST_DEFINE_STATIC_MUTEX_(g_linked_ptr_mutex); // Application pathname gotten in InitGoogleTest. std::string g_executable_path; // Returns the current application's name, removing directory path if that // is present. FilePath GetCurrentExecutableName() { FilePath result; #if GTEST_OS_WINDOWS result.Set(FilePath(g_executable_path).RemoveExtension("exe")); #else result.Set(FilePath(g_executable_path)); #endif // GTEST_OS_WINDOWS return result.RemoveDirectoryName(); } // Functions for processing the gtest_output flag. // Returns the output format, or "" for normal printed output. std::string UnitTestOptions::GetOutputFormat() { const char* const gtest_output_flag = GTEST_FLAG(output).c_str(); if (gtest_output_flag == NULL) return std::string(""); const char* const colon = strchr(gtest_output_flag, ':'); return (colon == NULL) ? std::string(gtest_output_flag) : std::string(gtest_output_flag, colon - gtest_output_flag); } // Returns the name of the requested output file, or the default if none // was explicitly specified. std::string UnitTestOptions::GetAbsolutePathToOutputFile() { const char* const gtest_output_flag = GTEST_FLAG(output).c_str(); if (gtest_output_flag == NULL) return ""; const char* const colon = strchr(gtest_output_flag, ':'); if (colon == NULL) return internal::FilePath::ConcatPaths( internal::FilePath( UnitTest::GetInstance()->original_working_dir()), internal::FilePath(kDefaultOutputFile)).string(); internal::FilePath output_name(colon + 1); if (!output_name.IsAbsolutePath()) // TODO(wan@google.com): on Windows \some\path is not an absolute // path (as its meaning depends on the current drive), yet the // following logic for turning it into an absolute path is wrong. // Fix it. output_name = internal::FilePath::ConcatPaths( internal::FilePath(UnitTest::GetInstance()->original_working_dir()), internal::FilePath(colon + 1)); if (!output_name.IsDirectory()) return output_name.string(); internal::FilePath result(internal::FilePath::GenerateUniqueFileName( output_name, internal::GetCurrentExecutableName(), GetOutputFormat().c_str())); return result.string(); } // Returns true iff the wildcard pattern matches the string. The // first ':' or '\0' character in pattern marks the end of it. // // This recursive algorithm isn't very efficient, but is clear and // works well enough for matching test names, which are short. bool UnitTestOptions::PatternMatchesString(const char *pattern, const char *str) { switch (*pattern) { case '\0': case ':': // Either ':' or '\0' marks the end of the pattern. return *str == '\0'; case '?': // Matches any single character. return *str != '\0' && PatternMatchesString(pattern + 1, str + 1); case '*': // Matches any string (possibly empty) of characters. return (*str != '\0' && PatternMatchesString(pattern, str + 1)) || PatternMatchesString(pattern + 1, str); default: // Non-special character. Matches itself. return *pattern == *str && PatternMatchesString(pattern + 1, str + 1); } } bool UnitTestOptions::MatchesFilter( const std::string& name, const char* filter) { const char *cur_pattern = filter; for (;;) { if (PatternMatchesString(cur_pattern, name.c_str())) { return true; } // Finds the next pattern in the filter. cur_pattern = strchr(cur_pattern, ':'); // Returns if no more pattern can be found. if (cur_pattern == NULL) { return false; } // Skips the pattern separater (the ':' character). cur_pattern++; } } // Returns true iff the user-specified filter matches the test case // name and the test name. bool UnitTestOptions::FilterMatchesTest(const std::string &test_case_name, const std::string &test_name) { const std::string& full_name = test_case_name + "." + test_name.c_str(); // Split --gtest_filter at '-', if there is one, to separate into // positive filter and negative filter portions const char* const p = GTEST_FLAG(filter).c_str(); const char* const dash = strchr(p, '-'); std::string positive; std::string negative; if (dash == NULL) { positive = GTEST_FLAG(filter).c_str(); // Whole string is a positive filter negative = ""; } else { positive = std::string(p, dash); // Everything up to the dash negative = std::string(dash + 1); // Everything after the dash if (positive.empty()) { // Treat '-test1' as the same as '*-test1' positive = kUniversalFilter; } } // A filter is a colon-separated list of patterns. It matches a // test if any pattern in it matches the test. return (MatchesFilter(full_name, positive.c_str()) && !MatchesFilter(full_name, negative.c_str())); } #if GTEST_HAS_SEH // Returns EXCEPTION_EXECUTE_HANDLER if Google Test should handle the // given SEH exception, or EXCEPTION_CONTINUE_SEARCH otherwise. // This function is useful as an __except condition. int UnitTestOptions::GTestShouldProcessSEH(DWORD exception_code) { // Google Test should handle a SEH exception if: // 1. the user wants it to, AND // 2. this is not a breakpoint exception, AND // 3. this is not a C++ exception (VC++ implements them via SEH, // apparently). // // SEH exception code for C++ exceptions. // (see http://support.microsoft.com/kb/185294 for more information). const DWORD kCxxExceptionCode = 0xe06d7363; bool should_handle = true; if (!GTEST_FLAG(catch_exceptions)) should_handle = false; else if (exception_code == EXCEPTION_BREAKPOINT) should_handle = false; else if (exception_code == kCxxExceptionCode) should_handle = false; return should_handle ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH; } #endif // GTEST_HAS_SEH } // namespace internal // The c'tor sets this object as the test part result reporter used by // Google Test. The 'result' parameter specifies where to report the // results. Intercepts only failures from the current thread. ScopedFakeTestPartResultReporter::ScopedFakeTestPartResultReporter( TestPartResultArray* result) : intercept_mode_(INTERCEPT_ONLY_CURRENT_THREAD), result_(result) { Init(); } // The c'tor sets this object as the test part result reporter used by // Google Test. The 'result' parameter specifies where to report the // results. ScopedFakeTestPartResultReporter::ScopedFakeTestPartResultReporter( InterceptMode intercept_mode, TestPartResultArray* result) : intercept_mode_(intercept_mode), result_(result) { Init(); } void ScopedFakeTestPartResultReporter::Init() { internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); if (intercept_mode_ == INTERCEPT_ALL_THREADS) { old_reporter_ = impl->GetGlobalTestPartResultReporter(); impl->SetGlobalTestPartResultReporter(this); } else { old_reporter_ = impl->GetTestPartResultReporterForCurrentThread(); impl->SetTestPartResultReporterForCurrentThread(this); } } // The d'tor restores the test part result reporter used by Google Test // before. ScopedFakeTestPartResultReporter::~ScopedFakeTestPartResultReporter() { internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); if (intercept_mode_ == INTERCEPT_ALL_THREADS) { impl->SetGlobalTestPartResultReporter(old_reporter_); } else { impl->SetTestPartResultReporterForCurrentThread(old_reporter_); } } // Increments the test part result count and remembers the result. // This method is from the TestPartResultReporterInterface interface. void ScopedFakeTestPartResultReporter::ReportTestPartResult( const TestPartResult& result) { result_->Append(result); } namespace internal { // Returns the type ID of ::testing::Test. We should always call this // instead of GetTypeId< ::testing::Test>() to get the type ID of // testing::Test. This is to work around a suspected linker bug when // using Google Test as a framework on Mac OS X. The bug causes // GetTypeId< ::testing::Test>() to return different values depending // on whether the call is from the Google Test framework itself or // from user test code. GetTestTypeId() is guaranteed to always // return the same value, as it always calls GetTypeId<>() from the // gtest.cc, which is within the Google Test framework. TypeId GetTestTypeId() { return GetTypeId(); } // The value of GetTestTypeId() as seen from within the Google Test // library. This is solely for testing GetTestTypeId(). extern const TypeId kTestTypeIdInGoogleTest = GetTestTypeId(); // This predicate-formatter checks that 'results' contains a test part // failure of the given type and that the failure message contains the // given substring. AssertionResult HasOneFailure(const char* /* results_expr */, const char* /* type_expr */, const char* /* substr_expr */, const TestPartResultArray& results, TestPartResult::Type type, const string& substr) { const std::string expected(type == TestPartResult::kFatalFailure ? "1 fatal failure" : "1 non-fatal failure"); Message msg; if (results.size() != 1) { msg << "Expected: " << expected << "\n" << " Actual: " << results.size() << " failures"; for (int i = 0; i < results.size(); i++) { msg << "\n" << results.GetTestPartResult(i); } return AssertionFailure() << msg; } const TestPartResult& r = results.GetTestPartResult(0); if (r.type() != type) { return AssertionFailure() << "Expected: " << expected << "\n" << " Actual:\n" << r; } if (strstr(r.message(), substr.c_str()) == NULL) { return AssertionFailure() << "Expected: " << expected << " containing \"" << substr << "\"\n" << " Actual:\n" << r; } return AssertionSuccess(); } // The constructor of SingleFailureChecker remembers where to look up // test part results, what type of failure we expect, and what // substring the failure message should contain. SingleFailureChecker:: SingleFailureChecker( const TestPartResultArray* results, TestPartResult::Type type, const string& substr) : results_(results), type_(type), substr_(substr) {} // The destructor of SingleFailureChecker verifies that the given // TestPartResultArray contains exactly one failure that has the given // type and contains the given substring. If that's not the case, a // non-fatal failure will be generated. SingleFailureChecker::~SingleFailureChecker() { EXPECT_PRED_FORMAT3(HasOneFailure, *results_, type_, substr_); } DefaultGlobalTestPartResultReporter::DefaultGlobalTestPartResultReporter( UnitTestImpl* unit_test) : unit_test_(unit_test) {} void DefaultGlobalTestPartResultReporter::ReportTestPartResult( const TestPartResult& result) { unit_test_->current_test_result()->AddTestPartResult(result); unit_test_->listeners()->repeater()->OnTestPartResult(result); } DefaultPerThreadTestPartResultReporter::DefaultPerThreadTestPartResultReporter( UnitTestImpl* unit_test) : unit_test_(unit_test) {} void DefaultPerThreadTestPartResultReporter::ReportTestPartResult( const TestPartResult& result) { unit_test_->GetGlobalTestPartResultReporter()->ReportTestPartResult(result); } // Returns the global test part result reporter. TestPartResultReporterInterface* UnitTestImpl::GetGlobalTestPartResultReporter() { internal::MutexLock lock(&global_test_part_result_reporter_mutex_); return global_test_part_result_repoter_; } // Sets the global test part result reporter. void UnitTestImpl::SetGlobalTestPartResultReporter( TestPartResultReporterInterface* reporter) { internal::MutexLock lock(&global_test_part_result_reporter_mutex_); global_test_part_result_repoter_ = reporter; } // Returns the test part result reporter for the current thread. TestPartResultReporterInterface* UnitTestImpl::GetTestPartResultReporterForCurrentThread() { return per_thread_test_part_result_reporter_.get(); } // Sets the test part result reporter for the current thread. void UnitTestImpl::SetTestPartResultReporterForCurrentThread( TestPartResultReporterInterface* reporter) { per_thread_test_part_result_reporter_.set(reporter); } // Gets the number of successful test cases. int UnitTestImpl::successful_test_case_count() const { return CountIf(test_cases_, TestCasePassed); } // Gets the number of failed test cases. int UnitTestImpl::failed_test_case_count() const { return CountIf(test_cases_, TestCaseFailed); } // Gets the number of all test cases. int UnitTestImpl::total_test_case_count() const { return static_cast(test_cases_.size()); } // Gets the number of all test cases that contain at least one test // that should run. int UnitTestImpl::test_case_to_run_count() const { return CountIf(test_cases_, ShouldRunTestCase); } // Gets the number of successful tests. int UnitTestImpl::successful_test_count() const { return SumOverTestCaseList(test_cases_, &TestCase::successful_test_count); } // Gets the number of failed tests. int UnitTestImpl::failed_test_count() const { return SumOverTestCaseList(test_cases_, &TestCase::failed_test_count); } // Gets the number of disabled tests that will be reported in the XML report. int UnitTestImpl::reportable_disabled_test_count() const { return SumOverTestCaseList(test_cases_, &TestCase::reportable_disabled_test_count); } // Gets the number of disabled tests. int UnitTestImpl::disabled_test_count() const { return SumOverTestCaseList(test_cases_, &TestCase::disabled_test_count); } // Gets the number of tests to be printed in the XML report. int UnitTestImpl::reportable_test_count() const { return SumOverTestCaseList(test_cases_, &TestCase::reportable_test_count); } // Gets the number of all tests. int UnitTestImpl::total_test_count() const { return SumOverTestCaseList(test_cases_, &TestCase::total_test_count); } // Gets the number of tests that should run. int UnitTestImpl::test_to_run_count() const { return SumOverTestCaseList(test_cases_, &TestCase::test_to_run_count); } // Returns the current OS stack trace as an std::string. // // The maximum number of stack frames to be included is specified by // the gtest_stack_trace_depth flag. The skip_count parameter // specifies the number of top frames to be skipped, which doesn't // count against the number of frames to be included. // // For example, if Foo() calls Bar(), which in turn calls // CurrentOsStackTraceExceptTop(1), Foo() will be included in the // trace but Bar() and CurrentOsStackTraceExceptTop() won't. std::string UnitTestImpl::CurrentOsStackTraceExceptTop(int skip_count) { (void)skip_count; return ""; } // Returns the current time in milliseconds. TimeInMillis GetTimeInMillis() { #if GTEST_OS_WINDOWS_MOBILE || defined(__BORLANDC__) // Difference between 1970-01-01 and 1601-01-01 in milliseconds. // http://analogous.blogspot.com/2005/04/epoch.html const TimeInMillis kJavaEpochToWinFileTimeDelta = static_cast(116444736UL) * 100000UL; const DWORD kTenthMicrosInMilliSecond = 10000; SYSTEMTIME now_systime; FILETIME now_filetime; ULARGE_INTEGER now_int64; // TODO(kenton@google.com): Shouldn't this just use // GetSystemTimeAsFileTime()? GetSystemTime(&now_systime); if (SystemTimeToFileTime(&now_systime, &now_filetime)) { now_int64.LowPart = now_filetime.dwLowDateTime; now_int64.HighPart = now_filetime.dwHighDateTime; now_int64.QuadPart = (now_int64.QuadPart / kTenthMicrosInMilliSecond) - kJavaEpochToWinFileTimeDelta; return now_int64.QuadPart; } return 0; #elif GTEST_OS_WINDOWS && !GTEST_HAS_GETTIMEOFDAY_ __timeb64 now; # ifdef _MSC_VER // MSVC 8 deprecates _ftime64(), so we want to suppress warning 4996 // (deprecated function) there. // TODO(kenton@google.com): Use GetTickCount()? Or use // SystemTimeToFileTime() # pragma warning(push) // Saves the current warning state. # pragma warning(disable:4996) // Temporarily disables warning 4996. _ftime64(&now); # pragma warning(pop) // Restores the warning state. # else _ftime64(&now); # endif // _MSC_VER return static_cast(now.time) * 1000 + now.millitm; #elif GTEST_HAS_GETTIMEOFDAY_ struct timeval now; gettimeofday(&now, NULL); return static_cast(now.tv_sec) * 1000 + now.tv_usec / 1000; #else # error "Don't know how to get the current time on your system." #endif } // Utilities // class String. #if GTEST_OS_WINDOWS_MOBILE // Creates a UTF-16 wide string from the given ANSI string, allocating // memory using new. The caller is responsible for deleting the return // value using delete[]. Returns the wide string, or NULL if the // input is NULL. LPCWSTR String::AnsiToUtf16(const char* ansi) { if (!ansi) return NULL; const int length = strlen(ansi); const int unicode_length = MultiByteToWideChar(CP_ACP, 0, ansi, length, NULL, 0); WCHAR* unicode = new WCHAR[unicode_length + 1]; MultiByteToWideChar(CP_ACP, 0, ansi, length, unicode, unicode_length); unicode[unicode_length] = 0; return unicode; } // Creates an ANSI string from the given wide string, allocating // memory using new. The caller is responsible for deleting the return // value using delete[]. Returns the ANSI string, or NULL if the // input is NULL. const char* String::Utf16ToAnsi(LPCWSTR utf16_str) { if (!utf16_str) return NULL; const int ansi_length = WideCharToMultiByte(CP_ACP, 0, utf16_str, -1, NULL, 0, NULL, NULL); char* ansi = new char[ansi_length + 1]; WideCharToMultiByte(CP_ACP, 0, utf16_str, -1, ansi, ansi_length, NULL, NULL); ansi[ansi_length] = 0; return ansi; } #endif // GTEST_OS_WINDOWS_MOBILE // Compares two C strings. Returns true iff they have the same content. // // Unlike strcmp(), this function can handle NULL argument(s). A NULL // C string is considered different to any non-NULL C string, // including the empty string. bool String::CStringEquals(const char * lhs, const char * rhs) { if ( lhs == NULL ) return rhs == NULL; if ( rhs == NULL ) return false; return strcmp(lhs, rhs) == 0; } #if GTEST_HAS_STD_WSTRING || GTEST_HAS_GLOBAL_WSTRING // Converts an array of wide chars to a narrow string using the UTF-8 // encoding, and streams the result to the given Message object. static void StreamWideCharsToMessage(const wchar_t* wstr, size_t length, Message* msg) { for (size_t i = 0; i != length; ) { // NOLINT if (wstr[i] != L'\0') { *msg << WideStringToUtf8(wstr + i, static_cast(length - i)); while (i != length && wstr[i] != L'\0') i++; } else { *msg << '\0'; i++; } } } #endif // GTEST_HAS_STD_WSTRING || GTEST_HAS_GLOBAL_WSTRING } // namespace internal // Constructs an empty Message. // We allocate the stringstream separately because otherwise each use of // ASSERT/EXPECT in a procedure adds over 200 bytes to the procedure's // stack frame leading to huge stack frames in some cases; gcc does not reuse // the stack space. Message::Message() : ss_(new ::std::stringstream) { // By default, we want there to be enough precision when printing // a double to a Message. *ss_ << std::setprecision(std::numeric_limits::digits10 + 2); } // These two overloads allow streaming a wide C string to a Message // using the UTF-8 encoding. Message& Message::operator <<(const wchar_t* wide_c_str) { return *this << internal::String::ShowWideCString(wide_c_str); } Message& Message::operator <<(wchar_t* wide_c_str) { return *this << internal::String::ShowWideCString(wide_c_str); } #if GTEST_HAS_STD_WSTRING // Converts the given wide string to a narrow string using the UTF-8 // encoding, and streams the result to this Message object. Message& Message::operator <<(const ::std::wstring& wstr) { internal::StreamWideCharsToMessage(wstr.c_str(), wstr.length(), this); return *this; } #endif // GTEST_HAS_STD_WSTRING #if GTEST_HAS_GLOBAL_WSTRING // Converts the given wide string to a narrow string using the UTF-8 // encoding, and streams the result to this Message object. Message& Message::operator <<(const ::wstring& wstr) { internal::StreamWideCharsToMessage(wstr.c_str(), wstr.length(), this); return *this; } #endif // GTEST_HAS_GLOBAL_WSTRING // Gets the text streamed to this object so far as an std::string. // Each '\0' character in the buffer is replaced with "\\0". std::string Message::GetString() const { return internal::StringStreamToString(ss_.get()); } // AssertionResult constructors. // Used in EXPECT_TRUE/FALSE(assertion_result). AssertionResult::AssertionResult(const AssertionResult& other) : success_(other.success_), message_(other.message_.get() != NULL ? new ::std::string(*other.message_) : static_cast< ::std::string*>(NULL)) { } // Returns the assertion's negation. Used with EXPECT/ASSERT_FALSE. AssertionResult AssertionResult::operator!() const { AssertionResult negation(!success_); if (message_.get() != NULL) negation << *message_; return negation; } // Makes a successful assertion result. AssertionResult AssertionSuccess() { return AssertionResult(true); } // Makes a failed assertion result. AssertionResult AssertionFailure() { return AssertionResult(false); } // Makes a failed assertion result with the given failure message. // Deprecated; use AssertionFailure() << message. AssertionResult AssertionFailure(const Message& message) { return AssertionFailure() << message; } namespace internal { // Constructs and returns the message for an equality assertion // (e.g. ASSERT_EQ, EXPECT_STREQ, etc) failure. // // The first four parameters are the expressions used in the assertion // and their values, as strings. For example, for ASSERT_EQ(foo, bar) // where foo is 5 and bar is 6, we have: // // expected_expression: "foo" // actual_expression: "bar" // expected_value: "5" // actual_value: "6" // // The ignoring_case parameter is true iff the assertion is a // *_STRCASEEQ*. When it's true, the string " (ignoring case)" will // be inserted into the message. AssertionResult EqFailure(const char* expected_expression, const char* actual_expression, const std::string& expected_value, const std::string& actual_value, bool ignoring_case) { Message msg; msg << "Value of: " << actual_expression; if (actual_value != actual_expression) { msg << "\n Actual: " << actual_value; } msg << "\nExpected: " << expected_expression; if (ignoring_case) { msg << " (ignoring case)"; } if (expected_value != expected_expression) { msg << "\nWhich is: " << expected_value; } return AssertionFailure() << msg; } // Constructs a failure message for Boolean assertions such as EXPECT_TRUE. std::string GetBoolAssertionFailureMessage( const AssertionResult& assertion_result, const char* expression_text, const char* actual_predicate_value, const char* expected_predicate_value) { const char* actual_message = assertion_result.message(); Message msg; msg << "Value of: " << expression_text << "\n Actual: " << actual_predicate_value; if (actual_message[0] != '\0') msg << " (" << actual_message << ")"; msg << "\nExpected: " << expected_predicate_value; return msg.GetString(); } // Helper function for implementing ASSERT_NEAR. AssertionResult DoubleNearPredFormat(const char* expr1, const char* expr2, const char* abs_error_expr, double val1, double val2, double abs_error) { const double diff = fabs(val1 - val2); if (diff <= abs_error) return AssertionSuccess(); // TODO(wan): do not print the value of an expression if it's // already a literal. return AssertionFailure() << "The difference between " << expr1 << " and " << expr2 << " is " << diff << ", which exceeds " << abs_error_expr << ", where\n" << expr1 << " evaluates to " << val1 << ",\n" << expr2 << " evaluates to " << val2 << ", and\n" << abs_error_expr << " evaluates to " << abs_error << "."; } // Helper template for implementing FloatLE() and DoubleLE(). template AssertionResult FloatingPointLE(const char* expr1, const char* expr2, RawType val1, RawType val2) { // Returns success if val1 is less than val2, if (val1 < val2) { return AssertionSuccess(); } // or if val1 is almost equal to val2. const FloatingPoint lhs(val1), rhs(val2); if (lhs.AlmostEquals(rhs)) { return AssertionSuccess(); } // Note that the above two checks will both fail if either val1 or // val2 is NaN, as the IEEE floating-point standard requires that // any predicate involving a NaN must return false. ::std::stringstream val1_ss; val1_ss << std::setprecision(std::numeric_limits::digits10 + 2) << val1; ::std::stringstream val2_ss; val2_ss << std::setprecision(std::numeric_limits::digits10 + 2) << val2; return AssertionFailure() << "Expected: (" << expr1 << ") <= (" << expr2 << ")\n" << " Actual: " << StringStreamToString(&val1_ss) << " vs " << StringStreamToString(&val2_ss); } } // namespace internal // Asserts that val1 is less than, or almost equal to, val2. Fails // otherwise. In particular, it fails if either val1 or val2 is NaN. AssertionResult FloatLE(const char* expr1, const char* expr2, float val1, float val2) { return internal::FloatingPointLE(expr1, expr2, val1, val2); } // Asserts that val1 is less than, or almost equal to, val2. Fails // otherwise. In particular, it fails if either val1 or val2 is NaN. AssertionResult DoubleLE(const char* expr1, const char* expr2, double val1, double val2) { return internal::FloatingPointLE(expr1, expr2, val1, val2); } namespace internal { // The helper function for {ASSERT|EXPECT}_EQ with int or enum // arguments. AssertionResult CmpHelperEQ(const char* expected_expression, const char* actual_expression, BiggestInt expected, BiggestInt actual) { if (expected == actual) { return AssertionSuccess(); } return EqFailure(expected_expression, actual_expression, FormatForComparisonFailureMessage(expected, actual), FormatForComparisonFailureMessage(actual, expected), false); } // A macro for implementing the helper functions needed to implement // ASSERT_?? and EXPECT_?? with integer or enum arguments. It is here // just to avoid copy-and-paste of similar code. #define GTEST_IMPL_CMP_HELPER_(op_name, op)\ AssertionResult CmpHelper##op_name(const char* expr1, const char* expr2, \ BiggestInt val1, BiggestInt val2) {\ if (val1 op val2) {\ return AssertionSuccess();\ } else {\ return AssertionFailure() \ << "Expected: (" << expr1 << ") " #op " (" << expr2\ << "), actual: " << FormatForComparisonFailureMessage(val1, val2)\ << " vs " << FormatForComparisonFailureMessage(val2, val1);\ }\ } // Implements the helper function for {ASSERT|EXPECT}_NE with int or // enum arguments. GTEST_IMPL_CMP_HELPER_(NE, !=) // Implements the helper function for {ASSERT|EXPECT}_LE with int or // enum arguments. GTEST_IMPL_CMP_HELPER_(LE, <=) // Implements the helper function for {ASSERT|EXPECT}_LT with int or // enum arguments. GTEST_IMPL_CMP_HELPER_(LT, < ) // Implements the helper function for {ASSERT|EXPECT}_GE with int or // enum arguments. GTEST_IMPL_CMP_HELPER_(GE, >=) // Implements the helper function for {ASSERT|EXPECT}_GT with int or // enum arguments. GTEST_IMPL_CMP_HELPER_(GT, > ) #undef GTEST_IMPL_CMP_HELPER_ // The helper function for {ASSERT|EXPECT}_STREQ. AssertionResult CmpHelperSTREQ(const char* expected_expression, const char* actual_expression, const char* expected, const char* actual) { if (String::CStringEquals(expected, actual)) { return AssertionSuccess(); } return EqFailure(expected_expression, actual_expression, PrintToString(expected), PrintToString(actual), false); } // The helper function for {ASSERT|EXPECT}_STRCASEEQ. AssertionResult CmpHelperSTRCASEEQ(const char* expected_expression, const char* actual_expression, const char* expected, const char* actual) { if (String::CaseInsensitiveCStringEquals(expected, actual)) { return AssertionSuccess(); } return EqFailure(expected_expression, actual_expression, PrintToString(expected), PrintToString(actual), true); } // The helper function for {ASSERT|EXPECT}_STRNE. AssertionResult CmpHelperSTRNE(const char* s1_expression, const char* s2_expression, const char* s1, const char* s2) { if (!String::CStringEquals(s1, s2)) { return AssertionSuccess(); } else { return AssertionFailure() << "Expected: (" << s1_expression << ") != (" << s2_expression << "), actual: \"" << s1 << "\" vs \"" << s2 << "\""; } } // The helper function for {ASSERT|EXPECT}_STRCASENE. AssertionResult CmpHelperSTRCASENE(const char* s1_expression, const char* s2_expression, const char* s1, const char* s2) { if (!String::CaseInsensitiveCStringEquals(s1, s2)) { return AssertionSuccess(); } else { return AssertionFailure() << "Expected: (" << s1_expression << ") != (" << s2_expression << ") (ignoring case), actual: \"" << s1 << "\" vs \"" << s2 << "\""; } } } // namespace internal namespace { // Helper functions for implementing IsSubString() and IsNotSubstring(). // This group of overloaded functions return true iff needle is a // substring of haystack. NULL is considered a substring of itself // only. bool IsSubstringPred(const char* needle, const char* haystack) { if (needle == NULL || haystack == NULL) return needle == haystack; return strstr(haystack, needle) != NULL; } bool IsSubstringPred(const wchar_t* needle, const wchar_t* haystack) { if (needle == NULL || haystack == NULL) return needle == haystack; return wcsstr(haystack, needle) != NULL; } // StringType here can be either ::std::string or ::std::wstring. template bool IsSubstringPred(const StringType& needle, const StringType& haystack) { return haystack.find(needle) != StringType::npos; } // This function implements either IsSubstring() or IsNotSubstring(), // depending on the value of the expected_to_be_substring parameter. // StringType here can be const char*, const wchar_t*, ::std::string, // or ::std::wstring. template AssertionResult IsSubstringImpl( bool expected_to_be_substring, const char* needle_expr, const char* haystack_expr, const StringType& needle, const StringType& haystack) { if (IsSubstringPred(needle, haystack) == expected_to_be_substring) return AssertionSuccess(); const bool is_wide_string = sizeof(needle[0]) > 1; const char* const begin_string_quote = is_wide_string ? "L\"" : "\""; return AssertionFailure() << "Value of: " << needle_expr << "\n" << " Actual: " << begin_string_quote << needle << "\"\n" << "Expected: " << (expected_to_be_substring ? "" : "not ") << "a substring of " << haystack_expr << "\n" << "Which is: " << begin_string_quote << haystack << "\""; } } // namespace // IsSubstring() and IsNotSubstring() check whether needle is a // substring of haystack (NULL is considered a substring of itself // only), and return an appropriate error message when they fail. AssertionResult IsSubstring( const char* needle_expr, const char* haystack_expr, const char* needle, const char* haystack) { return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack); } AssertionResult IsSubstring( const char* needle_expr, const char* haystack_expr, const wchar_t* needle, const wchar_t* haystack) { return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack); } AssertionResult IsNotSubstring( const char* needle_expr, const char* haystack_expr, const char* needle, const char* haystack) { return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack); } AssertionResult IsNotSubstring( const char* needle_expr, const char* haystack_expr, const wchar_t* needle, const wchar_t* haystack) { return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack); } AssertionResult IsSubstring( const char* needle_expr, const char* haystack_expr, const ::std::string& needle, const ::std::string& haystack) { return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack); } AssertionResult IsNotSubstring( const char* needle_expr, const char* haystack_expr, const ::std::string& needle, const ::std::string& haystack) { return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack); } #if GTEST_HAS_STD_WSTRING AssertionResult IsSubstring( const char* needle_expr, const char* haystack_expr, const ::std::wstring& needle, const ::std::wstring& haystack) { return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack); } AssertionResult IsNotSubstring( const char* needle_expr, const char* haystack_expr, const ::std::wstring& needle, const ::std::wstring& haystack) { return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack); } #endif // GTEST_HAS_STD_WSTRING namespace internal { #if GTEST_OS_WINDOWS namespace { // Helper function for IsHRESULT{SuccessFailure} predicates AssertionResult HRESULTFailureHelper(const char* expr, const char* expected, long hr) { // NOLINT # if GTEST_OS_WINDOWS_MOBILE // Windows CE doesn't support FormatMessage. const char error_text[] = ""; # else // Looks up the human-readable system message for the HRESULT code // and since we're not passing any params to FormatMessage, we don't // want inserts expanded. const DWORD kFlags = FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS; const DWORD kBufSize = 4096; // Gets the system's human readable message string for this HRESULT. char error_text[kBufSize] = { '\0' }; DWORD message_length = ::FormatMessageA(kFlags, 0, // no source, we're asking system hr, // the error 0, // no line width restrictions error_text, // output buffer kBufSize, // buf size NULL); // no arguments for inserts // Trims tailing white space (FormatMessage leaves a trailing CR-LF) for (; message_length && IsSpace(error_text[message_length - 1]); --message_length) { error_text[message_length - 1] = '\0'; } # endif // GTEST_OS_WINDOWS_MOBILE const std::string error_hex("0x" + String::FormatHexInt(hr)); return ::testing::AssertionFailure() << "Expected: " << expr << " " << expected << ".\n" << " Actual: " << error_hex << " " << error_text << "\n"; } } // namespace AssertionResult IsHRESULTSuccess(const char* expr, long hr) { // NOLINT if (SUCCEEDED(hr)) { return AssertionSuccess(); } return HRESULTFailureHelper(expr, "succeeds", hr); } AssertionResult IsHRESULTFailure(const char* expr, long hr) { // NOLINT if (FAILED(hr)) { return AssertionSuccess(); } return HRESULTFailureHelper(expr, "fails", hr); } #endif // GTEST_OS_WINDOWS // Utility functions for encoding Unicode text (wide strings) in // UTF-8. // A Unicode code-point can have upto 21 bits, and is encoded in UTF-8 // like this: // // Code-point length Encoding // 0 - 7 bits 0xxxxxxx // 8 - 11 bits 110xxxxx 10xxxxxx // 12 - 16 bits 1110xxxx 10xxxxxx 10xxxxxx // 17 - 21 bits 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx // The maximum code-point a one-byte UTF-8 sequence can represent. const UInt32 kMaxCodePoint1 = (static_cast(1) << 7) - 1; // The maximum code-point a two-byte UTF-8 sequence can represent. const UInt32 kMaxCodePoint2 = (static_cast(1) << (5 + 6)) - 1; // The maximum code-point a three-byte UTF-8 sequence can represent. const UInt32 kMaxCodePoint3 = (static_cast(1) << (4 + 2*6)) - 1; // The maximum code-point a four-byte UTF-8 sequence can represent. const UInt32 kMaxCodePoint4 = (static_cast(1) << (3 + 3*6)) - 1; // Chops off the n lowest bits from a bit pattern. Returns the n // lowest bits. As a side effect, the original bit pattern will be // shifted to the right by n bits. inline UInt32 ChopLowBits(UInt32* bits, int n) { const UInt32 low_bits = *bits & ((static_cast(1) << n) - 1); *bits >>= n; return low_bits; } // Converts a Unicode code point to a narrow string in UTF-8 encoding. // code_point parameter is of type UInt32 because wchar_t may not be // wide enough to contain a code point. // If the code_point is not a valid Unicode code point // (i.e. outside of Unicode range U+0 to U+10FFFF) it will be converted // to "(Invalid Unicode 0xXXXXXXXX)". std::string CodePointToUtf8(UInt32 code_point) { if (code_point > kMaxCodePoint4) { return "(Invalid Unicode 0x" + String::FormatHexInt(code_point) + ")"; } char str[5]; // Big enough for the largest valid code point. if (code_point <= kMaxCodePoint1) { str[1] = '\0'; str[0] = static_cast(code_point); // 0xxxxxxx } else if (code_point <= kMaxCodePoint2) { str[2] = '\0'; str[1] = static_cast(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx str[0] = static_cast(0xC0 | code_point); // 110xxxxx } else if (code_point <= kMaxCodePoint3) { str[3] = '\0'; str[2] = static_cast(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx str[1] = static_cast(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx str[0] = static_cast(0xE0 | code_point); // 1110xxxx } else { // code_point <= kMaxCodePoint4 str[4] = '\0'; str[3] = static_cast(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx str[2] = static_cast(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx str[1] = static_cast(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx str[0] = static_cast(0xF0 | code_point); // 11110xxx } return str; } // The following two functions only make sense if the the system // uses UTF-16 for wide string encoding. All supported systems // with 16 bit wchar_t (Windows, Cygwin, Symbian OS) do use UTF-16. // Determines if the arguments constitute UTF-16 surrogate pair // and thus should be combined into a single Unicode code point // using CreateCodePointFromUtf16SurrogatePair. inline bool IsUtf16SurrogatePair(wchar_t first, wchar_t second) { return sizeof(wchar_t) == 2 && (first & 0xFC00) == 0xD800 && (second & 0xFC00) == 0xDC00; } // Creates a Unicode code point from UTF16 surrogate pair. inline UInt32 CreateCodePointFromUtf16SurrogatePair(wchar_t first, wchar_t second) { const UInt32 mask = (1 << 10) - 1; return (sizeof(wchar_t) == 2) ? (((first & mask) << 10) | (second & mask)) + 0x10000 : // This function should not be called when the condition is // false, but we provide a sensible default in case it is. static_cast(first); } // Converts a wide string to a narrow string in UTF-8 encoding. // The wide string is assumed to have the following encoding: // UTF-16 if sizeof(wchar_t) == 2 (on Windows, Cygwin, Symbian OS) // UTF-32 if sizeof(wchar_t) == 4 (on Linux) // Parameter str points to a null-terminated wide string. // Parameter num_chars may additionally limit the number // of wchar_t characters processed. -1 is used when the entire string // should be processed. // If the string contains code points that are not valid Unicode code points // (i.e. outside of Unicode range U+0 to U+10FFFF) they will be output // as '(Invalid Unicode 0xXXXXXXXX)'. If the string is in UTF16 encoding // and contains invalid UTF-16 surrogate pairs, values in those pairs // will be encoded as individual Unicode characters from Basic Normal Plane. std::string WideStringToUtf8(const wchar_t* str, int num_chars) { if (num_chars == -1) num_chars = static_cast(wcslen(str)); ::std::stringstream stream; for (int i = 0; i < num_chars; ++i) { UInt32 unicode_code_point; if (str[i] == L'\0') { break; } else if (i + 1 < num_chars && IsUtf16SurrogatePair(str[i], str[i + 1])) { unicode_code_point = CreateCodePointFromUtf16SurrogatePair(str[i], str[i + 1]); i++; } else { unicode_code_point = static_cast(str[i]); } stream << CodePointToUtf8(unicode_code_point); } return StringStreamToString(&stream); } // Converts a wide C string to an std::string using the UTF-8 encoding. // NULL will be converted to "(null)". std::string String::ShowWideCString(const wchar_t * wide_c_str) { if (wide_c_str == NULL) return "(null)"; return internal::WideStringToUtf8(wide_c_str, -1); } // Compares two wide C strings. Returns true iff they have the same // content. // // Unlike wcscmp(), this function can handle NULL argument(s). A NULL // C string is considered different to any non-NULL C string, // including the empty string. bool String::WideCStringEquals(const wchar_t * lhs, const wchar_t * rhs) { if (lhs == NULL) return rhs == NULL; if (rhs == NULL) return false; return wcscmp(lhs, rhs) == 0; } // Helper function for *_STREQ on wide strings. AssertionResult CmpHelperSTREQ(const char* expected_expression, const char* actual_expression, const wchar_t* expected, const wchar_t* actual) { if (String::WideCStringEquals(expected, actual)) { return AssertionSuccess(); } return EqFailure(expected_expression, actual_expression, PrintToString(expected), PrintToString(actual), false); } // Helper function for *_STRNE on wide strings. AssertionResult CmpHelperSTRNE(const char* s1_expression, const char* s2_expression, const wchar_t* s1, const wchar_t* s2) { if (!String::WideCStringEquals(s1, s2)) { return AssertionSuccess(); } return AssertionFailure() << "Expected: (" << s1_expression << ") != (" << s2_expression << "), actual: " << PrintToString(s1) << " vs " << PrintToString(s2); } // Compares two C strings, ignoring case. Returns true iff they have // the same content. // // Unlike strcasecmp(), this function can handle NULL argument(s). A // NULL C string is considered different to any non-NULL C string, // including the empty string. bool String::CaseInsensitiveCStringEquals(const char * lhs, const char * rhs) { if (lhs == NULL) return rhs == NULL; if (rhs == NULL) return false; return posix::StrCaseCmp(lhs, rhs) == 0; } // Compares two wide C strings, ignoring case. Returns true iff they // have the same content. // // Unlike wcscasecmp(), this function can handle NULL argument(s). // A NULL C string is considered different to any non-NULL wide C string, // including the empty string. // NB: The implementations on different platforms slightly differ. // On windows, this method uses _wcsicmp which compares according to LC_CTYPE // environment variable. On GNU platform this method uses wcscasecmp // which compares according to LC_CTYPE category of the current locale. // On MacOS X, it uses towlower, which also uses LC_CTYPE category of the // current locale. bool String::CaseInsensitiveWideCStringEquals(const wchar_t* lhs, const wchar_t* rhs) { if (lhs == NULL) return rhs == NULL; if (rhs == NULL) return false; #if GTEST_OS_WINDOWS return _wcsicmp(lhs, rhs) == 0; #elif GTEST_OS_LINUX && !GTEST_OS_LINUX_ANDROID return wcscasecmp(lhs, rhs) == 0; #else // Android, Mac OS X and Cygwin don't define wcscasecmp. // Other unknown OSes may not define it either. wint_t left, right; do { left = towlower(*lhs++); right = towlower(*rhs++); } while (left && left == right); return left == right; #endif // OS selector } // Returns true iff str ends with the given suffix, ignoring case. // Any string is considered to end with an empty suffix. bool String::EndsWithCaseInsensitive( const std::string& str, const std::string& suffix) { const size_t str_len = str.length(); const size_t suffix_len = suffix.length(); return (str_len >= suffix_len) && CaseInsensitiveCStringEquals(str.c_str() + str_len - suffix_len, suffix.c_str()); } // Formats an int value as "%02d". std::string String::FormatIntWidth2(int value) { std::stringstream ss; ss << std::setfill('0') << std::setw(2) << value; return ss.str(); } // Formats an int value as "%X". std::string String::FormatHexInt(int value) { std::stringstream ss; ss << std::hex << std::uppercase << value; return ss.str(); } // Formats a byte as "%02X". std::string String::FormatByte(unsigned char value) { std::stringstream ss; ss << std::setfill('0') << std::setw(2) << std::hex << std::uppercase << static_cast(value); return ss.str(); } // Converts the buffer in a stringstream to an std::string, converting NUL // bytes to "\\0" along the way. std::string StringStreamToString(::std::stringstream* ss) { const ::std::string& str = ss->str(); const char* const start = str.c_str(); const char* const end = start + str.length(); std::string result; result.reserve(2 * (end - start)); for (const char* ch = start; ch != end; ++ch) { if (*ch == '\0') { result += "\\0"; // Replaces NUL with "\\0"; } else { result += *ch; } } return result; } // Appends the user-supplied message to the Google-Test-generated message. std::string AppendUserMessage(const std::string& gtest_msg, const Message& user_msg) { // Appends the user message if it's non-empty. const std::string user_msg_string = user_msg.GetString(); if (user_msg_string.empty()) { return gtest_msg; } return gtest_msg + "\n" + user_msg_string; } } // namespace internal // class TestResult // Creates an empty TestResult. TestResult::TestResult() : death_test_count_(0), elapsed_time_(0) { } // D'tor. TestResult::~TestResult() { } // Returns the i-th test part result among all the results. i can // range from 0 to total_part_count() - 1. If i is not in that range, // aborts the program. const TestPartResult& TestResult::GetTestPartResult(int i) const { if (i < 0 || i >= total_part_count()) internal::posix::Abort(); return test_part_results_.at(i); } // Returns the i-th test property. i can range from 0 to // test_property_count() - 1. If i is not in that range, aborts the // program. const TestProperty& TestResult::GetTestProperty(int i) const { if (i < 0 || i >= test_property_count()) internal::posix::Abort(); return test_properties_.at(i); } // Clears the test part results. void TestResult::ClearTestPartResults() { test_part_results_.clear(); } // Adds a test part result to the list. void TestResult::AddTestPartResult(const TestPartResult& test_part_result) { test_part_results_.push_back(test_part_result); } // Adds a test property to the list. If a property with the same key as the // supplied property is already represented, the value of this test_property // replaces the old value for that key. void TestResult::RecordProperty(const std::string& xml_element, const TestProperty& test_property) { if (!ValidateTestProperty(xml_element, test_property)) { return; } internal::MutexLock lock(&test_properites_mutex_); const std::vector::iterator property_with_matching_key = std::find_if(test_properties_.begin(), test_properties_.end(), internal::TestPropertyKeyIs(test_property.key())); if (property_with_matching_key == test_properties_.end()) { test_properties_.push_back(test_property); return; } property_with_matching_key->SetValue(test_property.value()); } // The list of reserved attributes used in the element of XML // output. static const char* const kReservedTestSuitesAttributes[] = { "disabled", "errors", "failures", "name", "random_seed", "tests", "time", "timestamp" }; // The list of reserved attributes used in the element of XML // output. static const char* const kReservedTestSuiteAttributes[] = { "disabled", "errors", "failures", "name", "tests", "time" }; // The list of reserved attributes used in the element of XML output. static const char* const kReservedTestCaseAttributes[] = { "classname", "name", "status", "time", "type_param", "value_param" }; template std::vector ArrayAsVector(const char* const (&array)[kSize]) { return std::vector(array, array + kSize); } static std::vector GetReservedAttributesForElement( const std::string& xml_element) { if (xml_element == "testsuites") { return ArrayAsVector(kReservedTestSuitesAttributes); } else if (xml_element == "testsuite") { return ArrayAsVector(kReservedTestSuiteAttributes); } else if (xml_element == "testcase") { return ArrayAsVector(kReservedTestCaseAttributes); } else { GTEST_CHECK_(false) << "Unrecognized xml_element provided: " << xml_element; } // This code is unreachable but some compilers may not realizes that. return std::vector(); } static std::string FormatWordList(const std::vector& words) { Message word_list; for (size_t i = 0; i < words.size(); ++i) { if (i > 0 && words.size() > 2) { word_list << ", "; } if (i == words.size() - 1) { word_list << "and "; } word_list << "'" << words[i] << "'"; } return word_list.GetString(); } bool ValidateTestPropertyName(const std::string& property_name, const std::vector& reserved_names) { if (std::find(reserved_names.begin(), reserved_names.end(), property_name) != reserved_names.end()) { ADD_FAILURE() << "Reserved key used in RecordProperty(): " << property_name << " (" << FormatWordList(reserved_names) << " are reserved by " << GTEST_NAME_ << ")"; return false; } return true; } // Adds a failure if the key is a reserved attribute of the element named // xml_element. Returns true if the property is valid. bool TestResult::ValidateTestProperty(const std::string& xml_element, const TestProperty& test_property) { return ValidateTestPropertyName(test_property.key(), GetReservedAttributesForElement(xml_element)); } // Clears the object. void TestResult::Clear() { test_part_results_.clear(); test_properties_.clear(); death_test_count_ = 0; elapsed_time_ = 0; } // Returns true iff the test failed. bool TestResult::Failed() const { for (int i = 0; i < total_part_count(); ++i) { if (GetTestPartResult(i).failed()) return true; } return false; } // Returns true iff the test part fatally failed. static bool TestPartFatallyFailed(const TestPartResult& result) { return result.fatally_failed(); } // Returns true iff the test fatally failed. bool TestResult::HasFatalFailure() const { return CountIf(test_part_results_, TestPartFatallyFailed) > 0; } // Returns true iff the test part non-fatally failed. static bool TestPartNonfatallyFailed(const TestPartResult& result) { return result.nonfatally_failed(); } // Returns true iff the test has a non-fatal failure. bool TestResult::HasNonfatalFailure() const { return CountIf(test_part_results_, TestPartNonfatallyFailed) > 0; } // Gets the number of all test parts. This is the sum of the number // of successful test parts and the number of failed test parts. int TestResult::total_part_count() const { return static_cast(test_part_results_.size()); } // Returns the number of the test properties. int TestResult::test_property_count() const { return static_cast(test_properties_.size()); } // class Test // Creates a Test object. // The c'tor saves the values of all Google Test flags. Test::Test() : gtest_flag_saver_(new internal::GTestFlagSaver) { } // The d'tor restores the values of all Google Test flags. Test::~Test() { delete gtest_flag_saver_; } // Sets up the test fixture. // // A sub-class may override this. void Test::SetUp() { } // Tears down the test fixture. // // A sub-class may override this. void Test::TearDown() { } // Allows user supplied key value pairs to be recorded for later output. void Test::RecordProperty(const std::string& key, const std::string& value) { UnitTest::GetInstance()->RecordProperty(key, value); } // Allows user supplied key value pairs to be recorded for later output. void Test::RecordProperty(const std::string& key, int value) { Message value_message; value_message << value; RecordProperty(key, value_message.GetString().c_str()); } namespace internal { void ReportFailureInUnknownLocation(TestPartResult::Type result_type, const std::string& message) { // This function is a friend of UnitTest and as such has access to // AddTestPartResult. UnitTest::GetInstance()->AddTestPartResult( result_type, NULL, // No info about the source file where the exception occurred. -1, // We have no info on which line caused the exception. message, ""); // No stack trace, either. } } // namespace internal // Google Test requires all tests in the same test case to use the same test // fixture class. This function checks if the current test has the // same fixture class as the first test in the current test case. If // yes, it returns true; otherwise it generates a Google Test failure and // returns false. bool Test::HasSameFixtureClass() { internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); const TestCase* const test_case = impl->current_test_case(); // Info about the first test in the current test case. const TestInfo* const first_test_info = test_case->test_info_list()[0]; const internal::TypeId first_fixture_id = first_test_info->fixture_class_id_; const char* const first_test_name = first_test_info->name(); // Info about the current test. const TestInfo* const this_test_info = impl->current_test_info(); const internal::TypeId this_fixture_id = this_test_info->fixture_class_id_; const char* const this_test_name = this_test_info->name(); if (this_fixture_id != first_fixture_id) { // Is the first test defined using TEST? const bool first_is_TEST = first_fixture_id == internal::GetTestTypeId(); // Is this test defined using TEST? const bool this_is_TEST = this_fixture_id == internal::GetTestTypeId(); if (first_is_TEST || this_is_TEST) { // The user mixed TEST and TEST_F in this test case - we'll tell // him/her how to fix it. // Gets the name of the TEST and the name of the TEST_F. Note // that first_is_TEST and this_is_TEST cannot both be true, as // the fixture IDs are different for the two tests. const char* const TEST_name = first_is_TEST ? first_test_name : this_test_name; const char* const TEST_F_name = first_is_TEST ? this_test_name : first_test_name; ADD_FAILURE() << "All tests in the same test case must use the same test fixture\n" << "class, so mixing TEST_F and TEST in the same test case is\n" << "illegal. In test case " << this_test_info->test_case_name() << ",\n" << "test " << TEST_F_name << " is defined using TEST_F but\n" << "test " << TEST_name << " is defined using TEST. You probably\n" << "want to change the TEST to TEST_F or move it to another test\n" << "case."; } else { // The user defined two fixture classes with the same name in // two namespaces - we'll tell him/her how to fix it. ADD_FAILURE() << "All tests in the same test case must use the same test fixture\n" << "class. However, in test case " << this_test_info->test_case_name() << ",\n" << "you defined test " << first_test_name << " and test " << this_test_name << "\n" << "using two different test fixture classes. This can happen if\n" << "the two classes are from different namespaces or translation\n" << "units and have the same name. You should probably rename one\n" << "of the classes to put the tests into different test cases."; } return false; } return true; } #if GTEST_HAS_SEH // Adds an "exception thrown" fatal failure to the current test. This // function returns its result via an output parameter pointer because VC++ // prohibits creation of objects with destructors on stack in functions // using __try (see error C2712). static std::string* FormatSehExceptionMessage(DWORD exception_code, const char* location) { Message message; message << "SEH exception with code 0x" << std::setbase(16) << exception_code << std::setbase(10) << " thrown in " << location << "."; return new std::string(message.GetString()); } #endif // GTEST_HAS_SEH namespace internal { #if GTEST_HAS_EXCEPTIONS // Adds an "exception thrown" fatal failure to the current test. static std::string FormatCxxExceptionMessage(const char* description, const char* location) { Message message; if (description != NULL) { message << "C++ exception with description \"" << description << "\""; } else { message << "Unknown C++ exception"; } message << " thrown in " << location << "."; return message.GetString(); } static std::string PrintTestPartResultToString( const TestPartResult& test_part_result); GoogleTestFailureException::GoogleTestFailureException( const TestPartResult& failure) : ::std::runtime_error(PrintTestPartResultToString(failure).c_str()) {} #endif // GTEST_HAS_EXCEPTIONS // We put these helper functions in the internal namespace as IBM's xlC // compiler rejects the code if they were declared static. // Runs the given method and handles SEH exceptions it throws, when // SEH is supported; returns the 0-value for type Result in case of an // SEH exception. (Microsoft compilers cannot handle SEH and C++ // exceptions in the same function. Therefore, we provide a separate // wrapper function for handling SEH exceptions.) template Result HandleSehExceptionsInMethodIfSupported( T* object, Result (T::*method)(), const char* location) { #if GTEST_HAS_SEH __try { return (object->*method)(); } __except (internal::UnitTestOptions::GTestShouldProcessSEH( // NOLINT GetExceptionCode())) { // We create the exception message on the heap because VC++ prohibits // creation of objects with destructors on stack in functions using __try // (see error C2712). std::string* exception_message = FormatSehExceptionMessage( GetExceptionCode(), location); internal::ReportFailureInUnknownLocation(TestPartResult::kFatalFailure, *exception_message); delete exception_message; return static_cast(0); } #else (void)location; return (object->*method)(); #endif // GTEST_HAS_SEH } // Runs the given method and catches and reports C++ and/or SEH-style // exceptions, if they are supported; returns the 0-value for type // Result in case of an SEH exception. template Result HandleExceptionsInMethodIfSupported( T* object, Result (T::*method)(), const char* location) { // NOTE: The user code can affect the way in which Google Test handles // exceptions by setting GTEST_FLAG(catch_exceptions), but only before // RUN_ALL_TESTS() starts. It is technically possible to check the flag // after the exception is caught and either report or re-throw the // exception based on the flag's value: // // try { // // Perform the test method. // } catch (...) { // if (GTEST_FLAG(catch_exceptions)) // // Report the exception as failure. // else // throw; // Re-throws the original exception. // } // // However, the purpose of this flag is to allow the program to drop into // the debugger when the exception is thrown. On most platforms, once the // control enters the catch block, the exception origin information is // lost and the debugger will stop the program at the point of the // re-throw in this function -- instead of at the point of the original // throw statement in the code under test. For this reason, we perform // the check early, sacrificing the ability to affect Google Test's // exception handling in the method where the exception is thrown. if (internal::GetUnitTestImpl()->catch_exceptions()) { #if GTEST_HAS_EXCEPTIONS try { return HandleSehExceptionsInMethodIfSupported(object, method, location); } catch (const internal::GoogleTestFailureException&) { // NOLINT // This exception type can only be thrown by a failed Google // Test assertion with the intention of letting another testing // framework catch it. Therefore we just re-throw it. throw; } catch (const std::exception& e) { // NOLINT internal::ReportFailureInUnknownLocation( TestPartResult::kFatalFailure, FormatCxxExceptionMessage(e.what(), location)); } catch (...) { // NOLINT internal::ReportFailureInUnknownLocation( TestPartResult::kFatalFailure, FormatCxxExceptionMessage(NULL, location)); } return static_cast(0); #else return HandleSehExceptionsInMethodIfSupported(object, method, location); #endif // GTEST_HAS_EXCEPTIONS } else { return (object->*method)(); } } } // namespace internal // Runs the test and updates the test result. void Test::Run() { if (!HasSameFixtureClass()) return; internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); impl->os_stack_trace_getter()->UponLeavingGTest(); internal::HandleExceptionsInMethodIfSupported(this, &Test::SetUp, "SetUp()"); // We will run the test only if SetUp() was successful. if (!HasFatalFailure()) { impl->os_stack_trace_getter()->UponLeavingGTest(); internal::HandleExceptionsInMethodIfSupported( this, &Test::TestBody, "the test body"); } // However, we want to clean up as much as possible. Hence we will // always call TearDown(), even if SetUp() or the test body has // failed. impl->os_stack_trace_getter()->UponLeavingGTest(); internal::HandleExceptionsInMethodIfSupported( this, &Test::TearDown, "TearDown()"); } // Returns true iff the current test has a fatal failure. bool Test::HasFatalFailure() { return internal::GetUnitTestImpl()->current_test_result()->HasFatalFailure(); } // Returns true iff the current test has a non-fatal failure. bool Test::HasNonfatalFailure() { return internal::GetUnitTestImpl()->current_test_result()-> HasNonfatalFailure(); } // class TestInfo // Constructs a TestInfo object. It assumes ownership of the test factory // object. 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::TypeId fixture_class_id, internal::TestFactoryBase* factory) : test_case_name_(a_test_case_name), name_(a_name), type_param_(a_type_param ? new std::string(a_type_param) : NULL), value_param_(a_value_param ? new std::string(a_value_param) : NULL), fixture_class_id_(fixture_class_id), should_run_(false), is_disabled_(false), matches_filter_(false), factory_(factory), result_() {} // Destructs a TestInfo object. TestInfo::~TestInfo() { delete factory_; } namespace internal { // Creates a new TestInfo object and registers it with Google Test; // returns the created object. // // Arguments: // // test_case_name: name of the test case // name: name of the test // type_param: the name of the test's type parameter, or NULL if // this is not a typed or a type-parameterized test. // value_param: text representation of the test's value parameter, // or NULL if this is not a value-parameterized test. // fixture_class_id: ID of the test fixture class // set_up_tc: pointer to the function that sets up the test case // tear_down_tc: pointer to the function that tears down the test case // factory: pointer to the factory that creates a test object. // The newly created TestInfo instance will assume // ownership of the factory object. TestInfo* MakeAndRegisterTestInfo( const char* test_case_name, const char* name, const char* type_param, const char* value_param, TypeId fixture_class_id, SetUpTestCaseFunc set_up_tc, TearDownTestCaseFunc tear_down_tc, TestFactoryBase* factory) { TestInfo* const test_info = new TestInfo(test_case_name, name, type_param, value_param, fixture_class_id, factory); GetUnitTestImpl()->AddTestInfo(set_up_tc, tear_down_tc, test_info); return test_info; } #if GTEST_HAS_PARAM_TEST void ReportInvalidTestCaseType(const char* test_case_name, const char* file, int line) { Message errors; errors << "Attempted redefinition of test case " << test_case_name << ".\n" << "All tests in the same test case must use the same test fixture\n" << "class. However, in test case " << test_case_name << ", you tried\n" << "to define a test using a fixture class different from the one\n" << "used earlier. This can happen if the two fixture classes are\n" << "from different namespaces and have the same name. You should\n" << "probably rename one of the classes to put the tests into different\n" << "test cases."; fprintf(stderr, "%s %s", FormatFileLocation(file, line).c_str(), errors.GetString().c_str()); } #endif // GTEST_HAS_PARAM_TEST } // namespace internal namespace { // A predicate that checks the test name of a TestInfo against a known // value. // // This is used for implementation of the TestCase class only. We put // it in the anonymous namespace to prevent polluting the outer // namespace. // // TestNameIs is copyable. class TestNameIs { public: // Constructor. // // TestNameIs has NO default constructor. explicit TestNameIs(const char* name) : name_(name) {} // Returns true iff the test name of test_info matches name_. bool operator()(const TestInfo * test_info) const { return test_info && test_info->name() == name_; } private: std::string name_; }; } // namespace namespace internal { // This method expands all parameterized tests registered with macros TEST_P // and INSTANTIATE_TEST_CASE_P into regular tests and registers those. // This will be done just once during the program runtime. void UnitTestImpl::RegisterParameterizedTests() { #if GTEST_HAS_PARAM_TEST if (!parameterized_tests_registered_) { parameterized_test_registry_.RegisterTests(); parameterized_tests_registered_ = true; } #endif } } // namespace internal // Creates the test object, runs it, records its result, and then // deletes it. void TestInfo::Run() { if (!should_run_) return; // Tells UnitTest where to store test result. internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); impl->set_current_test_info(this); TestEventListener* repeater = UnitTest::GetInstance()->listeners().repeater(); // Notifies the unit test event listeners that a test is about to start. repeater->OnTestStart(*this); const TimeInMillis start = internal::GetTimeInMillis(); impl->os_stack_trace_getter()->UponLeavingGTest(); // Creates the test object. Test* const test = internal::HandleExceptionsInMethodIfSupported( factory_, &internal::TestFactoryBase::CreateTest, "the test fixture's constructor"); // Runs the test only if the test object was created and its // constructor didn't generate a fatal failure. if ((test != NULL) && !Test::HasFatalFailure()) { // This doesn't throw as all user code that can throw are wrapped into // exception handling code. test->Run(); } // Deletes the test object. impl->os_stack_trace_getter()->UponLeavingGTest(); internal::HandleExceptionsInMethodIfSupported( test, &Test::DeleteSelf_, "the test fixture's destructor"); result_.set_elapsed_time(internal::GetTimeInMillis() - start); // Notifies the unit test event listener that a test has just finished. repeater->OnTestEnd(*this); // Tells UnitTest to stop associating assertion results to this // test. impl->set_current_test_info(NULL); } // class TestCase // Gets the number of successful tests in this test case. int TestCase::successful_test_count() const { return CountIf(test_info_list_, TestPassed); } // Gets the number of failed tests in this test case. int TestCase::failed_test_count() const { return CountIf(test_info_list_, TestFailed); } // Gets the number of disabled tests that will be reported in the XML report. int TestCase::reportable_disabled_test_count() const { return CountIf(test_info_list_, TestReportableDisabled); } // Gets the number of disabled tests in this test case. int TestCase::disabled_test_count() const { return CountIf(test_info_list_, TestDisabled); } // Gets the number of tests to be printed in the XML report. int TestCase::reportable_test_count() const { return CountIf(test_info_list_, TestReportable); } // Get the number of tests in this test case that should run. int TestCase::test_to_run_count() const { return CountIf(test_info_list_, ShouldRunTest); } // Gets the number of all tests. int TestCase::total_test_count() const { return static_cast(test_info_list_.size()); } // Creates a TestCase with the given name. // // Arguments: // // name: name of the test case // a_type_param: the name of the test case's type parameter, or NULL if // this is not a typed or a type-parameterized test case. // set_up_tc: pointer to the function that sets up the test case // tear_down_tc: pointer to the function that tears down the test case TestCase::TestCase(const char* a_name, const char* a_type_param, Test::SetUpTestCaseFunc set_up_tc, Test::TearDownTestCaseFunc tear_down_tc) : name_(a_name), type_param_(a_type_param ? new std::string(a_type_param) : NULL), set_up_tc_(set_up_tc), tear_down_tc_(tear_down_tc), should_run_(false), elapsed_time_(0) { } // Destructor of TestCase. TestCase::~TestCase() { // Deletes every Test in the collection. ForEach(test_info_list_, internal::Delete); } // Returns the i-th test among all the tests. i can range from 0 to // total_test_count() - 1. If i is not in that range, returns NULL. const TestInfo* TestCase::GetTestInfo(int i) const { const int index = GetElementOr(test_indices_, i, -1); return index < 0 ? NULL : test_info_list_[index]; } // Returns the i-th test among all the tests. i can range from 0 to // total_test_count() - 1. If i is not in that range, returns NULL. TestInfo* TestCase::GetMutableTestInfo(int i) { const int index = GetElementOr(test_indices_, i, -1); return index < 0 ? NULL : test_info_list_[index]; } // Adds a test to this test case. Will delete the test upon // destruction of the TestCase object. void TestCase::AddTestInfo(TestInfo * test_info) { test_info_list_.push_back(test_info); test_indices_.push_back(static_cast(test_indices_.size())); } // Runs every test in this TestCase. void TestCase::Run() { if (!should_run_) return; internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); impl->set_current_test_case(this); TestEventListener* repeater = UnitTest::GetInstance()->listeners().repeater(); repeater->OnTestCaseStart(*this); impl->os_stack_trace_getter()->UponLeavingGTest(); internal::HandleExceptionsInMethodIfSupported( this, &TestCase::RunSetUpTestCase, "SetUpTestCase()"); const internal::TimeInMillis start = internal::GetTimeInMillis(); for (int i = 0; i < total_test_count(); i++) { GetMutableTestInfo(i)->Run(); } elapsed_time_ = internal::GetTimeInMillis() - start; impl->os_stack_trace_getter()->UponLeavingGTest(); internal::HandleExceptionsInMethodIfSupported( this, &TestCase::RunTearDownTestCase, "TearDownTestCase()"); repeater->OnTestCaseEnd(*this); impl->set_current_test_case(NULL); } // Clears the results of all tests in this test case. void TestCase::ClearResult() { ad_hoc_test_result_.Clear(); ForEach(test_info_list_, TestInfo::ClearTestResult); } // Shuffles the tests in this test case. void TestCase::ShuffleTests(internal::Random* random) { Shuffle(random, &test_indices_); } // Restores the test order to before the first shuffle. void TestCase::UnshuffleTests() { for (size_t i = 0; i < test_indices_.size(); i++) { test_indices_[i] = static_cast(i); } } // Formats a countable noun. Depending on its quantity, either the // singular form or the plural form is used. e.g. // // FormatCountableNoun(1, "formula", "formuli") returns "1 formula". // FormatCountableNoun(5, "book", "books") returns "5 books". static std::string FormatCountableNoun(int count, const char * singular_form, const char * plural_form) { return internal::StreamableToString(count) + " " + (count == 1 ? singular_form : plural_form); } // Formats the count of tests. static std::string FormatTestCount(int test_count) { return FormatCountableNoun(test_count, "test", "tests"); } // Formats the count of test cases. static std::string FormatTestCaseCount(int test_case_count) { return FormatCountableNoun(test_case_count, "test case", "test cases"); } // Converts a TestPartResult::Type enum to human-friendly string // representation. Both kNonFatalFailure and kFatalFailure are translated // to "Failure", as the user usually doesn't care about the difference // between the two when viewing the test result. static const char * TestPartResultTypeToString(TestPartResult::Type type) { switch (type) { case TestPartResult::kSuccess: return "Success"; case TestPartResult::kNonFatalFailure: case TestPartResult::kFatalFailure: #ifdef _MSC_VER return "error: "; #else return "Failure\n"; #endif default: return "Unknown result type"; } } namespace internal { // Prints a TestPartResult to an std::string. static std::string PrintTestPartResultToString( const TestPartResult& test_part_result) { return (Message() << internal::FormatFileLocation(test_part_result.file_name(), test_part_result.line_number()) << " " << TestPartResultTypeToString(test_part_result.type()) << test_part_result.message()).GetString(); } // Prints a TestPartResult. static void PrintTestPartResult(const TestPartResult& test_part_result) { const std::string& result = PrintTestPartResultToString(test_part_result); printf("%s\n", result.c_str()); fflush(stdout); // If the test program runs in Visual Studio or a debugger, the // following statements add the test part result message to the Output // window such that the user can double-click on it to jump to the // corresponding source code location; otherwise they do nothing. #if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE // We don't call OutputDebugString*() on Windows Mobile, as printing // to stdout is done by OutputDebugString() there already - we don't // want the same message printed twice. ::OutputDebugStringA(result.c_str()); ::OutputDebugStringA("\n"); #endif } // class PrettyUnitTestResultPrinter enum GTestColor { COLOR_DEFAULT, COLOR_RED, COLOR_GREEN, COLOR_YELLOW }; #if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE // Returns the character attribute for the given color. WORD GetColorAttribute(GTestColor color) { switch (color) { case COLOR_RED: return FOREGROUND_RED; case COLOR_GREEN: return FOREGROUND_GREEN; case COLOR_YELLOW: return FOREGROUND_RED | FOREGROUND_GREEN; default: return 0; } } #else // Returns the ANSI color code for the given color. COLOR_DEFAULT is // an invalid input. const char* GetAnsiColorCode(GTestColor color) { switch (color) { case COLOR_RED: return "1"; case COLOR_GREEN: return "2"; case COLOR_YELLOW: return "3"; default: return NULL; }; } #endif // GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE // Returns true iff Google Test should use colors in the output. bool ShouldUseColor(bool stdout_is_tty) { const char* const gtest_color = GTEST_FLAG(color).c_str(); if (String::CaseInsensitiveCStringEquals(gtest_color, "auto")) { #if GTEST_OS_WINDOWS // On Windows the TERM variable is usually not set, but the // console there does support colors. return stdout_is_tty; #else // On non-Windows platforms, we rely on the TERM variable. const char* const term = posix::GetEnv("TERM"); const bool term_supports_color = String::CStringEquals(term, "xterm") || String::CStringEquals(term, "xterm-color") || String::CStringEquals(term, "xterm-256color") || String::CStringEquals(term, "screen") || String::CStringEquals(term, "screen-256color") || String::CStringEquals(term, "linux") || String::CStringEquals(term, "cygwin"); return stdout_is_tty && term_supports_color; #endif // GTEST_OS_WINDOWS } return String::CaseInsensitiveCStringEquals(gtest_color, "yes") || String::CaseInsensitiveCStringEquals(gtest_color, "true") || String::CaseInsensitiveCStringEquals(gtest_color, "t") || String::CStringEquals(gtest_color, "1"); // We take "yes", "true", "t", and "1" as meaning "yes". If the // value is neither one of these nor "auto", we treat it as "no" to // be conservative. } // Helpers for printing colored strings to stdout. Note that on Windows, we // cannot simply emit special characters and have the terminal change colors. // This routine must actually emit the characters rather than return a string // that would be colored when printed, as can be done on Linux. void ColoredPrintf(GTestColor color, const char* fmt, ...) { va_list args; va_start(args, fmt); #if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_SYMBIAN || GTEST_OS_ZOS || GTEST_OS_IOS const bool use_color = false; #else static const bool in_color_mode = ShouldUseColor(posix::IsATTY(posix::FileNo(stdout)) != 0); const bool use_color = in_color_mode && (color != COLOR_DEFAULT); #endif // GTEST_OS_WINDOWS_MOBILE || GTEST_OS_SYMBIAN || GTEST_OS_ZOS // The '!= 0' comparison is necessary to satisfy MSVC 7.1. if (!use_color) { vprintf(fmt, args); va_end(args); return; } #if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE const HANDLE stdout_handle = GetStdHandle(STD_OUTPUT_HANDLE); // Gets the current text color. CONSOLE_SCREEN_BUFFER_INFO buffer_info; GetConsoleScreenBufferInfo(stdout_handle, &buffer_info); const WORD old_color_attrs = buffer_info.wAttributes; // We need to flush the stream buffers into the console before each // SetConsoleTextAttribute call lest it affect the text that is already // printed but has not yet reached the console. fflush(stdout); SetConsoleTextAttribute(stdout_handle, GetColorAttribute(color) | FOREGROUND_INTENSITY); vprintf(fmt, args); fflush(stdout); // Restores the text color. SetConsoleTextAttribute(stdout_handle, old_color_attrs); #else printf("\033[0;3%sm", GetAnsiColorCode(color)); vprintf(fmt, args); printf("\033[m"); // Resets the terminal to default. #endif // GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE va_end(args); } // Text printed in Google Test's text output and --gunit_list_tests // output to label the type parameter and value parameter for a test. static const char kTypeParamLabel[] = "TypeParam"; static const char kValueParamLabel[] = "GetParam()"; void PrintFullTestCommentIfPresent(const TestInfo& test_info) { const char* const type_param = test_info.type_param(); const char* const value_param = test_info.value_param(); if (type_param != NULL || value_param != NULL) { printf(", where "); if (type_param != NULL) { printf("%s = %s", kTypeParamLabel, type_param); if (value_param != NULL) printf(" and "); } if (value_param != NULL) { printf("%s = %s", kValueParamLabel, value_param); } } } // This class implements the TestEventListener interface. // // Class PrettyUnitTestResultPrinter is copyable. class PrettyUnitTestResultPrinter : public TestEventListener { public: PrettyUnitTestResultPrinter() {} static void PrintTestName(const char * test_case, const char * test) { printf("%s.%s", test_case, test); } // The following methods override what's in the TestEventListener class. virtual void OnTestProgramStart(const UnitTest& /*unit_test*/) {} virtual void OnTestIterationStart(const UnitTest& unit_test, int iteration); virtual void OnEnvironmentsSetUpStart(const UnitTest& unit_test); virtual void OnEnvironmentsSetUpEnd(const UnitTest& /*unit_test*/) {} virtual void OnTestCaseStart(const TestCase& test_case); virtual void OnTestStart(const TestInfo& test_info); virtual void OnTestPartResult(const TestPartResult& result); virtual void OnTestEnd(const TestInfo& test_info); virtual void OnTestCaseEnd(const TestCase& test_case); virtual void OnEnvironmentsTearDownStart(const UnitTest& unit_test); virtual void OnEnvironmentsTearDownEnd(const UnitTest& /*unit_test*/) {} virtual void OnTestIterationEnd(const UnitTest& unit_test, int iteration); virtual void OnTestProgramEnd(const UnitTest& /*unit_test*/) {} private: static void PrintFailedTests(const UnitTest& unit_test); }; // Fired before each iteration of tests starts. void PrettyUnitTestResultPrinter::OnTestIterationStart( const UnitTest& unit_test, int iteration) { if (GTEST_FLAG(repeat) != 1) printf("\nRepeating all tests (iteration %d) . . .\n\n", iteration + 1); const char* const filter = GTEST_FLAG(filter).c_str(); // Prints the filter if it's not *. This reminds the user that some // tests may be skipped. if (!String::CStringEquals(filter, kUniversalFilter)) { ColoredPrintf(COLOR_YELLOW, "Note: %s filter = %s\n", GTEST_NAME_, filter); } if (internal::ShouldShard(kTestTotalShards, kTestShardIndex, false)) { const Int32 shard_index = Int32FromEnvOrDie(kTestShardIndex, -1); ColoredPrintf(COLOR_YELLOW, "Note: This is test shard %d of %s.\n", static_cast(shard_index) + 1, internal::posix::GetEnv(kTestTotalShards)); } if (GTEST_FLAG(shuffle)) { ColoredPrintf(COLOR_YELLOW, "Note: Randomizing tests' orders with a seed of %d .\n", unit_test.random_seed()); } ColoredPrintf(COLOR_GREEN, "[==========] "); printf("Running %s from %s.\n", FormatTestCount(unit_test.test_to_run_count()).c_str(), FormatTestCaseCount(unit_test.test_case_to_run_count()).c_str()); fflush(stdout); } void PrettyUnitTestResultPrinter::OnEnvironmentsSetUpStart( const UnitTest& /*unit_test*/) { ColoredPrintf(COLOR_GREEN, "[----------] "); printf("Global test environment set-up.\n"); fflush(stdout); } void PrettyUnitTestResultPrinter::OnTestCaseStart(const TestCase& test_case) { const std::string counts = FormatCountableNoun(test_case.test_to_run_count(), "test", "tests"); ColoredPrintf(COLOR_GREEN, "[----------] "); printf("%s from %s", counts.c_str(), test_case.name()); if (test_case.type_param() == NULL) { printf("\n"); } else { printf(", where %s = %s\n", kTypeParamLabel, test_case.type_param()); } fflush(stdout); } void PrettyUnitTestResultPrinter::OnTestStart(const TestInfo& test_info) { ColoredPrintf(COLOR_GREEN, "[ RUN ] "); PrintTestName(test_info.test_case_name(), test_info.name()); printf("\n"); fflush(stdout); } // Called after an assertion failure. void PrettyUnitTestResultPrinter::OnTestPartResult( const TestPartResult& result) { // If the test part succeeded, we don't need to do anything. if (result.type() == TestPartResult::kSuccess) return; // Print failure message from the assertion (e.g. expected this and got that). PrintTestPartResult(result); fflush(stdout); } void PrettyUnitTestResultPrinter::OnTestEnd(const TestInfo& test_info) { if (test_info.result()->Passed()) { ColoredPrintf(COLOR_GREEN, "[ OK ] "); } else { ColoredPrintf(COLOR_RED, "[ FAILED ] "); } PrintTestName(test_info.test_case_name(), test_info.name()); if (test_info.result()->Failed()) PrintFullTestCommentIfPresent(test_info); if (GTEST_FLAG(print_time)) { printf(" (%s ms)\n", internal::StreamableToString( test_info.result()->elapsed_time()).c_str()); } else { printf("\n"); } fflush(stdout); } void PrettyUnitTestResultPrinter::OnTestCaseEnd(const TestCase& test_case) { if (!GTEST_FLAG(print_time)) return; const std::string counts = FormatCountableNoun(test_case.test_to_run_count(), "test", "tests"); ColoredPrintf(COLOR_GREEN, "[----------] "); printf("%s from %s (%s ms total)\n\n", counts.c_str(), test_case.name(), internal::StreamableToString(test_case.elapsed_time()).c_str()); fflush(stdout); } void PrettyUnitTestResultPrinter::OnEnvironmentsTearDownStart( const UnitTest& /*unit_test*/) { ColoredPrintf(COLOR_GREEN, "[----------] "); printf("Global test environment tear-down\n"); fflush(stdout); } // Internal helper for printing the list of failed tests. void PrettyUnitTestResultPrinter::PrintFailedTests(const UnitTest& unit_test) { const int failed_test_count = unit_test.failed_test_count(); if (failed_test_count == 0) { return; } for (int i = 0; i < unit_test.total_test_case_count(); ++i) { const TestCase& test_case = *unit_test.GetTestCase(i); if (!test_case.should_run() || (test_case.failed_test_count() == 0)) { continue; } for (int j = 0; j < test_case.total_test_count(); ++j) { const TestInfo& test_info = *test_case.GetTestInfo(j); if (!test_info.should_run() || test_info.result()->Passed()) { continue; } ColoredPrintf(COLOR_RED, "[ FAILED ] "); printf("%s.%s", test_case.name(), test_info.name()); PrintFullTestCommentIfPresent(test_info); printf("\n"); } } } void PrettyUnitTestResultPrinter::OnTestIterationEnd(const UnitTest& unit_test, int /*iteration*/) { ColoredPrintf(COLOR_GREEN, "[==========] "); printf("%s from %s ran.", FormatTestCount(unit_test.test_to_run_count()).c_str(), FormatTestCaseCount(unit_test.test_case_to_run_count()).c_str()); if (GTEST_FLAG(print_time)) { printf(" (%s ms total)", internal::StreamableToString(unit_test.elapsed_time()).c_str()); } printf("\n"); ColoredPrintf(COLOR_GREEN, "[ PASSED ] "); printf("%s.\n", FormatTestCount(unit_test.successful_test_count()).c_str()); int num_failures = unit_test.failed_test_count(); if (!unit_test.Passed()) { const int failed_test_count = unit_test.failed_test_count(); ColoredPrintf(COLOR_RED, "[ FAILED ] "); printf("%s, listed below:\n", FormatTestCount(failed_test_count).c_str()); PrintFailedTests(unit_test); printf("\n%2d FAILED %s\n", num_failures, num_failures == 1 ? "TEST" : "TESTS"); } int num_disabled = unit_test.reportable_disabled_test_count(); if (num_disabled && !GTEST_FLAG(also_run_disabled_tests)) { if (!num_failures) { printf("\n"); // Add a spacer if no FAILURE banner is displayed. } ColoredPrintf(COLOR_YELLOW, " YOU HAVE %d DISABLED %s\n\n", num_disabled, num_disabled == 1 ? "TEST" : "TESTS"); } // Ensure that Google Test output is printed before, e.g., heapchecker output. fflush(stdout); } // End PrettyUnitTestResultPrinter // class TestEventRepeater // // This class forwards events to other event listeners. class TestEventRepeater : public TestEventListener { public: TestEventRepeater() : forwarding_enabled_(true) {} virtual ~TestEventRepeater(); void Append(TestEventListener *listener); TestEventListener* Release(TestEventListener* listener); // Controls whether events will be forwarded to listeners_. Set to false // in death test child processes. bool forwarding_enabled() const { return forwarding_enabled_; } void set_forwarding_enabled(bool enable) { forwarding_enabled_ = enable; } virtual void OnTestProgramStart(const UnitTest& unit_test); virtual void OnTestIterationStart(const UnitTest& unit_test, int iteration); virtual void OnEnvironmentsSetUpStart(const UnitTest& unit_test); virtual void OnEnvironmentsSetUpEnd(const UnitTest& unit_test); virtual void OnTestCaseStart(const TestCase& test_case); virtual void OnTestStart(const TestInfo& test_info); virtual void OnTestPartResult(const TestPartResult& result); virtual void OnTestEnd(const TestInfo& test_info); virtual void OnTestCaseEnd(const TestCase& test_case); virtual void OnEnvironmentsTearDownStart(const UnitTest& unit_test); virtual void OnEnvironmentsTearDownEnd(const UnitTest& unit_test); virtual void OnTestIterationEnd(const UnitTest& unit_test, int iteration); virtual void OnTestProgramEnd(const UnitTest& unit_test); private: // Controls whether events will be forwarded to listeners_. Set to false // in death test child processes. bool forwarding_enabled_; // The list of listeners that receive events. std::vector listeners_; GTEST_DISALLOW_COPY_AND_ASSIGN_(TestEventRepeater); }; TestEventRepeater::~TestEventRepeater() { ForEach(listeners_, Delete); } void TestEventRepeater::Append(TestEventListener *listener) { listeners_.push_back(listener); } // TODO(vladl@google.com): Factor the search functionality into Vector::Find. TestEventListener* TestEventRepeater::Release(TestEventListener *listener) { for (size_t i = 0; i < listeners_.size(); ++i) { if (listeners_[i] == listener) { listeners_.erase(listeners_.begin() + i); return listener; } } return NULL; } // Since most methods are very similar, use macros to reduce boilerplate. // This defines a member that forwards the call to all listeners. #define GTEST_REPEATER_METHOD_(Name, Type) \ void TestEventRepeater::Name(const Type& parameter) { \ if (forwarding_enabled_) { \ for (size_t i = 0; i < listeners_.size(); i++) { \ listeners_[i]->Name(parameter); \ } \ } \ } // This defines a member that forwards the call to all listeners in reverse // order. #define GTEST_REVERSE_REPEATER_METHOD_(Name, Type) \ void TestEventRepeater::Name(const Type& parameter) { \ if (forwarding_enabled_) { \ for (int i = static_cast(listeners_.size()) - 1; i >= 0; i--) { \ listeners_[i]->Name(parameter); \ } \ } \ } GTEST_REPEATER_METHOD_(OnTestProgramStart, UnitTest) GTEST_REPEATER_METHOD_(OnEnvironmentsSetUpStart, UnitTest) GTEST_REPEATER_METHOD_(OnTestCaseStart, TestCase) GTEST_REPEATER_METHOD_(OnTestStart, TestInfo) GTEST_REPEATER_METHOD_(OnTestPartResult, TestPartResult) GTEST_REPEATER_METHOD_(OnEnvironmentsTearDownStart, UnitTest) GTEST_REVERSE_REPEATER_METHOD_(OnEnvironmentsSetUpEnd, UnitTest) GTEST_REVERSE_REPEATER_METHOD_(OnEnvironmentsTearDownEnd, UnitTest) GTEST_REVERSE_REPEATER_METHOD_(OnTestEnd, TestInfo) GTEST_REVERSE_REPEATER_METHOD_(OnTestCaseEnd, TestCase) GTEST_REVERSE_REPEATER_METHOD_(OnTestProgramEnd, UnitTest) #undef GTEST_REPEATER_METHOD_ #undef GTEST_REVERSE_REPEATER_METHOD_ void TestEventRepeater::OnTestIterationStart(const UnitTest& unit_test, int iteration) { if (forwarding_enabled_) { for (size_t i = 0; i < listeners_.size(); i++) { listeners_[i]->OnTestIterationStart(unit_test, iteration); } } } void TestEventRepeater::OnTestIterationEnd(const UnitTest& unit_test, int iteration) { if (forwarding_enabled_) { for (int i = static_cast(listeners_.size()) - 1; i >= 0; i--) { listeners_[i]->OnTestIterationEnd(unit_test, iteration); } } } // End TestEventRepeater // This class generates an XML output file. class XmlUnitTestResultPrinter : public EmptyTestEventListener { public: explicit XmlUnitTestResultPrinter(const char* output_file); virtual void OnTestIterationEnd(const UnitTest& unit_test, int iteration); private: // Is c a whitespace character that is normalized to a space character // when it appears in an XML attribute value? static bool IsNormalizableWhitespace(char c) { return c == 0x9 || c == 0xA || c == 0xD; } // May c appear in a well-formed XML document? static bool IsValidXmlCharacter(char c) { return IsNormalizableWhitespace(c) || c >= 0x20; } // Returns an XML-escaped copy of the input string str. If // is_attribute is true, the text is meant to appear as an attribute // value, and normalizable whitespace is preserved by replacing it // with character references. static std::string EscapeXml(const std::string& str, bool is_attribute); // Returns the given string with all characters invalid in XML removed. static std::string RemoveInvalidXmlCharacters(const std::string& str); // Convenience wrapper around EscapeXml when str is an attribute value. static std::string EscapeXmlAttribute(const std::string& str) { return EscapeXml(str, true); } // Convenience wrapper around EscapeXml when str is not an attribute value. static std::string EscapeXmlText(const char* str) { return EscapeXml(str, false); } // Verifies that the given attribute belongs to the given element and // streams the attribute as XML. static void OutputXmlAttribute(std::ostream* stream, const std::string& element_name, const std::string& name, const std::string& value); // Streams an XML CDATA section, escaping invalid CDATA sequences as needed. static void OutputXmlCDataSection(::std::ostream* stream, const char* data); // Streams an XML representation of a TestInfo object. static void OutputXmlTestInfo(::std::ostream* stream, const char* test_case_name, const TestInfo& test_info); // Prints an XML representation of a TestCase object static void PrintXmlTestCase(::std::ostream* stream, const TestCase& test_case); // Prints an XML summary of unit_test to output stream out. static void PrintXmlUnitTest(::std::ostream* stream, const UnitTest& unit_test); // Produces a string representing the test properties in a result as space // delimited XML attributes based on the property key="value" pairs. // When the std::string is not empty, it includes a space at the beginning, // to delimit this attribute from prior attributes. static std::string TestPropertiesAsXmlAttributes(const TestResult& result); // The output file. const std::string output_file_; GTEST_DISALLOW_COPY_AND_ASSIGN_(XmlUnitTestResultPrinter); }; // Creates a new XmlUnitTestResultPrinter. XmlUnitTestResultPrinter::XmlUnitTestResultPrinter(const char* output_file) : output_file_(output_file) { if (output_file_.c_str() == NULL || output_file_.empty()) { fprintf(stderr, "XML output file may not be null\n"); fflush(stderr); exit(EXIT_FAILURE); } } // Called after the unit test ends. void XmlUnitTestResultPrinter::OnTestIterationEnd(const UnitTest& unit_test, int /*iteration*/) { FILE* xmlout = NULL; FilePath output_file(output_file_); FilePath output_dir(output_file.RemoveFileName()); if (output_dir.CreateDirectoriesRecursively()) { xmlout = posix::FOpen(output_file_.c_str(), "w"); } if (xmlout == NULL) { // TODO(wan): report the reason of the failure. // // We don't do it for now as: // // 1. There is no urgent need for it. // 2. It's a bit involved to make the errno variable thread-safe on // all three operating systems (Linux, Windows, and Mac OS). // 3. To interpret the meaning of errno in a thread-safe way, // we need the strerror_r() function, which is not available on // Windows. fprintf(stderr, "Unable to open file \"%s\"\n", output_file_.c_str()); fflush(stderr); exit(EXIT_FAILURE); } std::stringstream stream; PrintXmlUnitTest(&stream, unit_test); fprintf(xmlout, "%s", StringStreamToString(&stream).c_str()); fclose(xmlout); } // Returns an XML-escaped copy of the input string str. If is_attribute // is true, the text is meant to appear as an attribute value, and // normalizable whitespace is preserved by replacing it with character // references. // // Invalid XML characters in str, if any, are stripped from the output. // It is expected that most, if not all, of the text processed by this // module will consist of ordinary English text. // If this module is ever modified to produce version 1.1 XML output, // most invalid characters can be retained using character references. // TODO(wan): It might be nice to have a minimally invasive, human-readable // escaping scheme for invalid characters, rather than dropping them. std::string XmlUnitTestResultPrinter::EscapeXml( const std::string& str, bool is_attribute) { Message m; for (size_t i = 0; i < str.size(); ++i) { const char ch = str[i]; switch (ch) { case '<': m << "<"; break; case '>': m << ">"; break; case '&': m << "&"; break; case '\'': if (is_attribute) m << "'"; else m << '\''; break; case '"': if (is_attribute) m << """; else m << '"'; break; default: if (IsValidXmlCharacter(ch)) { if (is_attribute && IsNormalizableWhitespace(ch)) m << "&#x" << String::FormatByte(static_cast(ch)) << ";"; else m << ch; } break; } } return m.GetString(); } // Returns the given string with all characters invalid in XML removed. // Currently invalid characters are dropped from the string. An // alternative is to replace them with certain characters such as . or ?. std::string XmlUnitTestResultPrinter::RemoveInvalidXmlCharacters( const std::string& str) { std::string output; output.reserve(str.size()); for (std::string::const_iterator it = str.begin(); it != str.end(); ++it) if (IsValidXmlCharacter(*it)) output.push_back(*it); return output; } // The following routines generate an XML representation of a UnitTest // object. // // This is how Google Test concepts map to the DTD: // // <-- corresponds to a UnitTest object // <-- corresponds to a TestCase object // <-- corresponds to a TestInfo object // ... // ... // ... // <-- individual assertion failures // // // // Formats the given time in milliseconds as seconds. std::string FormatTimeInMillisAsSeconds(TimeInMillis ms) { ::std::stringstream ss; ss << ms/1000.0; return ss.str(); } // 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 // 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); } // Streams an XML CDATA section, escaping invalid CDATA sequences as needed. void XmlUnitTestResultPrinter::OutputXmlCDataSection(::std::ostream* stream, const char* data) { const char* segment = data; *stream << ""); if (next_segment != NULL) { stream->write( segment, static_cast(next_segment - segment)); *stream << "]]>]]>"); } else { *stream << segment; break; } } *stream << "]]>"; } void XmlUnitTestResultPrinter::OutputXmlAttribute( std::ostream* stream, const std::string& element_name, const std::string& name, const std::string& value) { const std::vector& allowed_names = GetReservedAttributesForElement(element_name); GTEST_CHECK_(std::find(allowed_names.begin(), allowed_names.end(), name) != allowed_names.end()) << "Attribute " << name << " is not allowed for element <" << element_name << ">."; *stream << " " << name << "=\"" << EscapeXmlAttribute(value) << "\""; } // Prints an XML representation of a TestInfo object. // TODO(wan): There is also value in printing properties with the plain printer. void XmlUnitTestResultPrinter::OutputXmlTestInfo(::std::ostream* stream, const char* test_case_name, const TestInfo& test_info) { const TestResult& result = *test_info.result(); const std::string kTestcase = "testcase"; *stream << " \n"; } const string location = internal::FormatCompilerIndependentFileLocation( part.file_name(), part.line_number()); const string summary = location + "\n" + part.summary(); *stream << " "; const string detail = location + "\n" + part.message(); OutputXmlCDataSection(stream, RemoveInvalidXmlCharacters(detail).c_str()); *stream << "\n"; } } if (failures == 0) *stream << " />\n"; else *stream << " \n"; } // Prints an XML representation of a TestCase object void XmlUnitTestResultPrinter::PrintXmlTestCase(std::ostream* stream, const TestCase& test_case) { const std::string kTestsuite = "testsuite"; *stream << " <" << kTestsuite; OutputXmlAttribute(stream, kTestsuite, "name", test_case.name()); OutputXmlAttribute(stream, kTestsuite, "tests", StreamableToString(test_case.reportable_test_count())); OutputXmlAttribute(stream, kTestsuite, "failures", StreamableToString(test_case.failed_test_count())); OutputXmlAttribute( stream, kTestsuite, "disabled", StreamableToString(test_case.reportable_disabled_test_count())); OutputXmlAttribute(stream, kTestsuite, "errors", "0"); OutputXmlAttribute(stream, kTestsuite, "time", FormatTimeInMillisAsSeconds(test_case.elapsed_time())); *stream << TestPropertiesAsXmlAttributes(test_case.ad_hoc_test_result()) << ">\n"; for (int i = 0; i < test_case.total_test_count(); ++i) { if (test_case.GetTestInfo(i)->is_reportable()) OutputXmlTestInfo(stream, test_case.name(), *test_case.GetTestInfo(i)); } *stream << " \n"; } // Prints an XML summary of unit_test to output stream out. void XmlUnitTestResultPrinter::PrintXmlUnitTest(std::ostream* stream, const UnitTest& unit_test) { const std::string kTestsuites = "testsuites"; *stream << "\n"; *stream << "<" << kTestsuites; OutputXmlAttribute(stream, kTestsuites, "tests", StreamableToString(unit_test.reportable_test_count())); OutputXmlAttribute(stream, kTestsuites, "failures", StreamableToString(unit_test.failed_test_count())); OutputXmlAttribute( stream, kTestsuites, "disabled", StreamableToString(unit_test.reportable_disabled_test_count())); OutputXmlAttribute(stream, kTestsuites, "errors", "0"); OutputXmlAttribute( stream, kTestsuites, "timestamp", FormatEpochTimeInMillisAsIso8601(unit_test.start_timestamp())); OutputXmlAttribute(stream, kTestsuites, "time", FormatTimeInMillisAsSeconds(unit_test.elapsed_time())); if (GTEST_FLAG(shuffle)) { OutputXmlAttribute(stream, kTestsuites, "random_seed", StreamableToString(unit_test.random_seed())); } *stream << TestPropertiesAsXmlAttributes(unit_test.ad_hoc_test_result()); OutputXmlAttribute(stream, kTestsuites, "name", "AllTests"); *stream << ">\n"; for (int i = 0; i < unit_test.total_test_case_count(); ++i) { if (unit_test.GetTestCase(i)->reportable_test_count() > 0) PrintXmlTestCase(stream, *unit_test.GetTestCase(i)); } *stream << "\n"; } // Produces a string representing the test properties in a result as space // delimited XML attributes based on the property key="value" pairs. std::string XmlUnitTestResultPrinter::TestPropertiesAsXmlAttributes( const TestResult& result) { Message attributes; for (int i = 0; i < result.test_property_count(); ++i) { const TestProperty& property = result.GetTestProperty(i); attributes << " " << property.key() << "=" << "\"" << EscapeXmlAttribute(property.value()) << "\""; } return attributes.GetString(); } // End XmlUnitTestResultPrinter #if GTEST_CAN_STREAM_RESULTS_ // Checks if str contains '=', '&', '%' or '\n' characters. If yes, // replaces them by "%xx" where xx is their hexadecimal value. For // example, replaces "=" with "%3D". This algorithm is O(strlen(str)) // in both time and space -- important as the input str may contain an // arbitrarily long test failure message and stack trace. string StreamingListener::UrlEncode(const char* str) { string result; result.reserve(strlen(str) + 1); for (char ch = *str; ch != '\0'; ch = *++str) { switch (ch) { case '%': case '=': case '&': case '\n': result.append("%" + String::FormatByte(static_cast(ch))); break; default: result.push_back(ch); break; } } return result; } void StreamingListener::SocketWriter::MakeConnection() { GTEST_CHECK_(sockfd_ == -1) << "MakeConnection() can't be called when there is already a connection."; addrinfo hints; memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_UNSPEC; // To allow both IPv4 and IPv6 addresses. hints.ai_socktype = SOCK_STREAM; addrinfo* servinfo = NULL; // Use the getaddrinfo() to get a linked list of IP addresses for // the given host name. const int error_num = getaddrinfo( host_name_.c_str(), port_num_.c_str(), &hints, &servinfo); if (error_num != 0) { GTEST_LOG_(WARNING) << "stream_result_to: getaddrinfo() failed: " << gai_strerror(error_num); } // Loop through all the results and connect to the first we can. for (addrinfo* cur_addr = servinfo; sockfd_ == -1 && cur_addr != NULL; cur_addr = cur_addr->ai_next) { sockfd_ = socket( cur_addr->ai_family, cur_addr->ai_socktype, cur_addr->ai_protocol); if (sockfd_ != -1) { // Connect the client socket to the server socket. if (connect(sockfd_, cur_addr->ai_addr, cur_addr->ai_addrlen) == -1) { close(sockfd_); sockfd_ = -1; } } } freeaddrinfo(servinfo); // all done with this structure if (sockfd_ == -1) { GTEST_LOG_(WARNING) << "stream_result_to: failed to connect to " << host_name_ << ":" << port_num_; } } // End of class Streaming Listener #endif // GTEST_CAN_STREAM_RESULTS__ // Class ScopedTrace // Pushes the given source file location and message onto a per-thread // trace stack maintained by Google Test. ScopedTrace::ScopedTrace(const char* file, int line, const Message& message) GTEST_LOCK_EXCLUDED_(&UnitTest::mutex_) { TraceInfo trace; trace.file = file; trace.line = line; trace.message = message.GetString(); UnitTest::GetInstance()->PushGTestTrace(trace); } // Pops the info pushed by the c'tor. ScopedTrace::~ScopedTrace() GTEST_LOCK_EXCLUDED_(&UnitTest::mutex_) { UnitTest::GetInstance()->PopGTestTrace(); } // 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_) { return ""; } void OsStackTraceGetter::UponLeavingGTest() GTEST_LOCK_EXCLUDED_(mutex_) { } const char* const OsStackTraceGetter::kElidedFramesMarker = "... " GTEST_NAME_ " internal frames ..."; // A helper class that creates the premature-exit file in its // constructor and deletes the file in its destructor. class ScopedPrematureExitFile { public: explicit ScopedPrematureExitFile(const char* premature_exit_filepath) : premature_exit_filepath_(premature_exit_filepath) { // If a path to the premature-exit file is specified... if (premature_exit_filepath != NULL && *premature_exit_filepath != '\0') { // create the file with a single "0" character in it. I/O // errors are ignored as there's nothing better we can do and we // don't want to fail the test because of this. FILE* pfile = posix::FOpen(premature_exit_filepath, "w"); fwrite("0", 1, 1, pfile); fclose(pfile); } } ~ScopedPrematureExitFile() { if (premature_exit_filepath_ != NULL && *premature_exit_filepath_ != '\0') { remove(premature_exit_filepath_); } } private: const char* const premature_exit_filepath_; GTEST_DISALLOW_COPY_AND_ASSIGN_(ScopedPrematureExitFile); }; } // namespace internal // class TestEventListeners TestEventListeners::TestEventListeners() : repeater_(new internal::TestEventRepeater()), default_result_printer_(NULL), default_xml_generator_(NULL) { } TestEventListeners::~TestEventListeners() { delete repeater_; } // Returns the standard listener responsible for the default console // output. Can be removed from the listeners list to shut down default // console output. Note that removing this object from the listener list // with Release transfers its ownership to the user. void TestEventListeners::Append(TestEventListener* listener) { repeater_->Append(listener); } // Removes the given event listener from the list and returns it. It then // becomes the caller's responsibility to delete the listener. Returns // NULL if the listener is not found in the list. TestEventListener* TestEventListeners::Release(TestEventListener* listener) { if (listener == default_result_printer_) default_result_printer_ = NULL; else if (listener == default_xml_generator_) default_xml_generator_ = NULL; return repeater_->Release(listener); } // Returns repeater that broadcasts the TestEventListener events to all // subscribers. TestEventListener* TestEventListeners::repeater() { return repeater_; } // Sets the default_result_printer attribute to the provided listener. // The listener is also added to the listener list and previous // default_result_printer is removed from it and deleted. The listener can // also be NULL in which case it will not be added to the list. Does // nothing if the previous and the current listener objects are the same. void TestEventListeners::SetDefaultResultPrinter(TestEventListener* listener) { if (default_result_printer_ != listener) { // It is an error to pass this method a listener that is already in the // list. delete Release(default_result_printer_); default_result_printer_ = listener; if (listener != NULL) Append(listener); } } // Sets the default_xml_generator attribute to the provided listener. The // listener is also added to the listener list and previous // default_xml_generator is removed from it and deleted. The listener can // also be NULL in which case it will not be added to the list. Does // nothing if the previous and the current listener objects are the same. void TestEventListeners::SetDefaultXmlGenerator(TestEventListener* listener) { if (default_xml_generator_ != listener) { // It is an error to pass this method a listener that is already in the // list. delete Release(default_xml_generator_); default_xml_generator_ = listener; if (listener != NULL) Append(listener); } } // Controls whether events will be forwarded by the repeater to the // listeners in the list. bool TestEventListeners::EventForwardingEnabled() const { return repeater_->forwarding_enabled(); } void TestEventListeners::SuppressEventForwarding() { repeater_->set_forwarding_enabled(false); } // class UnitTest // Gets the singleton UnitTest object. The first time this method is // called, a UnitTest object is constructed and returned. Consecutive // calls will return the same object. // // We don't protect this under mutex_ as a user is not supposed to // call this before main() starts, from which point on the return // value will never change. UnitTest* UnitTest::GetInstance() { // When compiled with MSVC 7.1 in optimized mode, destroying the // UnitTest object upon exiting the program messes up the exit code, // causing successful tests to appear failed. We have to use a // different implementation in this case to bypass the compiler bug. // This implementation makes the compiler happy, at the cost of // leaking the UnitTest object. // CodeGear C++Builder insists on a public destructor for the // default implementation. Use this implementation to keep good OO // design with private destructor. #if (_MSC_VER == 1310 && !defined(_DEBUG)) || defined(__BORLANDC__) static UnitTest* const instance = new UnitTest; return instance; #else static UnitTest instance; return &instance; #endif // (_MSC_VER == 1310 && !defined(_DEBUG)) || defined(__BORLANDC__) } // Gets the number of successful test cases. int UnitTest::successful_test_case_count() const { return impl()->successful_test_case_count(); } // Gets the number of failed test cases. int UnitTest::failed_test_case_count() const { return impl()->failed_test_case_count(); } // Gets the number of all test cases. int UnitTest::total_test_case_count() const { return impl()->total_test_case_count(); } // Gets the number of all test cases that contain at least one test // that should run. int UnitTest::test_case_to_run_count() const { return impl()->test_case_to_run_count(); } // Gets the number of successful tests. int UnitTest::successful_test_count() const { return impl()->successful_test_count(); } // Gets the number of failed tests. int UnitTest::failed_test_count() const { return impl()->failed_test_count(); } // Gets the number of disabled tests that will be reported in the XML report. int UnitTest::reportable_disabled_test_count() const { return impl()->reportable_disabled_test_count(); } // Gets the number of disabled tests. int UnitTest::disabled_test_count() const { return impl()->disabled_test_count(); } // Gets the number of tests to be printed in the XML report. int UnitTest::reportable_test_count() const { return impl()->reportable_test_count(); } // Gets the number of all tests. int UnitTest::total_test_count() const { return impl()->total_test_count(); } // Gets the number of tests that should run. int UnitTest::test_to_run_count() const { return impl()->test_to_run_count(); } // Gets the time of the test program start, in ms from the start of the // UNIX epoch. internal::TimeInMillis UnitTest::start_timestamp() const { return impl()->start_timestamp(); } // Gets the elapsed time, in milliseconds. internal::TimeInMillis UnitTest::elapsed_time() const { return impl()->elapsed_time(); } // Returns true iff the unit test passed (i.e. all test cases passed). bool UnitTest::Passed() const { return impl()->Passed(); } // Returns true iff the unit test failed (i.e. some test case failed // or something outside of all tests failed). bool UnitTest::Failed() const { return impl()->Failed(); } // Gets the i-th test case among all the test cases. i can range from 0 to // total_test_case_count() - 1. If i is not in that range, returns NULL. const TestCase* UnitTest::GetTestCase(int i) const { return impl()->GetTestCase(i); } // Returns the TestResult containing information on test failures and // properties logged outside of individual test cases. const TestResult& UnitTest::ad_hoc_test_result() const { return *impl()->ad_hoc_test_result(); } // Gets the i-th test case among all the test cases. i can range from 0 to // total_test_case_count() - 1. If i is not in that range, returns NULL. TestCase* UnitTest::GetMutableTestCase(int i) { return impl()->GetMutableTestCase(i); } // Returns the list of event listeners that can be used to track events // inside Google Test. TestEventListeners& UnitTest::listeners() { return *impl()->listeners(); } // Registers and returns a global test environment. When a test // program is run, all global test environments will be set-up in the // order they were registered. After all tests in the program have // finished, all global test environments will be torn-down in the // *reverse* order they were registered. // // The UnitTest object takes ownership of the given environment. // // We don't protect this under mutex_, as we only support calling it // from the main thread. Environment* UnitTest::AddEnvironment(Environment* env) { if (env == NULL) { return NULL; } impl_->environments().push_back(env); return env; } // Adds a TestPartResult to the current TestResult object. All Google Test // assertion macros (e.g. ASSERT_TRUE, EXPECT_EQ, etc) eventually call // this to report their results. The user code should use the // assertion macros instead of calling this directly. void UnitTest::AddTestPartResult( TestPartResult::Type result_type, const char* file_name, int line_number, const std::string& message, const std::string& os_stack_trace) GTEST_LOCK_EXCLUDED_(mutex_) { Message msg; msg << message; internal::MutexLock lock(&mutex_); if (impl_->gtest_trace_stack().size() > 0) { msg << "\n" << GTEST_NAME_ << " trace:"; for (int i = static_cast(impl_->gtest_trace_stack().size()); i > 0; --i) { const internal::TraceInfo& trace = impl_->gtest_trace_stack()[i - 1]; msg << "\n" << internal::FormatFileLocation(trace.file, trace.line) << " " << trace.message; } } if (os_stack_trace.c_str() != NULL && !os_stack_trace.empty()) { msg << internal::kStackTraceMarker << os_stack_trace; } const TestPartResult result = TestPartResult(result_type, file_name, line_number, msg.GetString().c_str()); impl_->GetTestPartResultReporterForCurrentThread()-> ReportTestPartResult(result); if (result_type != TestPartResult::kSuccess) { // gtest_break_on_failure takes precedence over // gtest_throw_on_failure. This allows a user to set the latter // in the code (perhaps in order to use Google Test assertions // with another testing framework) and specify the former on the // command line for debugging. if (GTEST_FLAG(break_on_failure)) { #if GTEST_OS_WINDOWS // Using DebugBreak on Windows allows gtest to still break into a debugger // when a failure happens and both the --gtest_break_on_failure and // the --gtest_catch_exceptions flags are specified. DebugBreak(); #else // Dereference NULL through a volatile pointer to prevent the compiler // from removing. We use this rather than abort() or __builtin_trap() for // portability: Symbian doesn't implement abort() well, and some debuggers // don't correctly trap abort(). *static_cast(NULL) = 1; #endif // GTEST_OS_WINDOWS } else if (GTEST_FLAG(throw_on_failure)) { #if GTEST_HAS_EXCEPTIONS throw internal::GoogleTestFailureException(result); #else // We cannot call abort() as it generates a pop-up in debug mode // that cannot be suppressed in VC 7.1 or below. exit(1); #endif } } } // Adds a TestProperty to the current TestResult object when invoked from // inside a test, to current TestCase's ad_hoc_test_result_ when invoked // from SetUpTestCase or TearDownTestCase, or to the global property set // when invoked elsewhere. If the result already contains a property with // the same key, the value will be updated. void UnitTest::RecordProperty(const std::string& key, const std::string& value) { impl_->RecordProperty(TestProperty(key, value)); } // Runs all tests in this UnitTest object and prints the result. // Returns 0 if successful, or 1 otherwise. // // We don't protect this under mutex_, as we only support calling it // from the main thread. int UnitTest::Run() { const bool in_death_test_child_process = internal::GTEST_FLAG(internal_run_death_test).length() > 0; // Google Test implements this protocol for catching that a test // program exits before returning control to Google Test: // // 1. Upon start, Google Test creates a file whose absolute path // is specified by the environment variable // TEST_PREMATURE_EXIT_FILE. // 2. When Google Test has finished its work, it deletes the file. // // This allows a test runner to set TEST_PREMATURE_EXIT_FILE before // running a Google-Test-based test program and check the existence // of the file at the end of the test execution to see if it has // exited prematurely. // If we are in the child process of a death test, don't // create/delete the premature exit file, as doing so is unnecessary // and will confuse the parent process. Otherwise, create/delete // the file upon entering/leaving this function. If the program // somehow exits before this function has a chance to return, the // premature-exit file will be left undeleted, causing a test runner // that understands the premature-exit-file protocol to report the // test as having failed. const internal::ScopedPrematureExitFile premature_exit_file( in_death_test_child_process ? NULL : internal::posix::GetEnv("TEST_PREMATURE_EXIT_FILE")); // Captures the value of GTEST_FLAG(catch_exceptions). This value will be // used for the duration of the program. impl()->set_catch_exceptions(GTEST_FLAG(catch_exceptions)); #if GTEST_HAS_SEH // Either the user wants Google Test to catch exceptions thrown by the // tests or this is executing in the context of death test child // process. In either case the user does not want to see pop-up dialogs // about crashes - they are expected. if (impl()->catch_exceptions() || in_death_test_child_process) { # if !GTEST_OS_WINDOWS_MOBILE // SetErrorMode doesn't exist on CE. SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOALIGNMENTFAULTEXCEPT | SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX); # endif // !GTEST_OS_WINDOWS_MOBILE # if (defined(_MSC_VER) || GTEST_OS_WINDOWS_MINGW) && !GTEST_OS_WINDOWS_MOBILE // Death test children can be terminated with _abort(). On Windows, // _abort() can show a dialog with a warning message. This forces the // abort message to go to stderr instead. _set_error_mode(_OUT_TO_STDERR); # endif # if _MSC_VER >= 1400 && !GTEST_OS_WINDOWS_MOBILE // In the debug version, Visual Studio pops up a separate dialog // offering a choice to debug the aborted program. We need to suppress // this dialog or it will pop up for every EXPECT/ASSERT_DEATH statement // executed. Google Test will notify the user of any unexpected // failure via stderr. // // VC++ doesn't define _set_abort_behavior() prior to the version 8.0. // Users of prior VC versions shall suffer the agony and pain of // clicking through the countless debug dialogs. // TODO(vladl@google.com): find a way to suppress the abort dialog() in the // debug mode when compiled with VC 7.1 or lower. if (!GTEST_FLAG(break_on_failure)) _set_abort_behavior( 0x0, // Clear the following flags: _WRITE_ABORT_MSG | _CALL_REPORTFAULT); // pop-up window, core dump. # endif } #endif // GTEST_HAS_SEH return internal::HandleExceptionsInMethodIfSupported( impl(), &internal::UnitTestImpl::RunAllTests, "auxiliary test code (environments or event listeners)") ? 0 : 1; } // Returns the working directory when the first TEST() or TEST_F() was // executed. const char* UnitTest::original_working_dir() const { return impl_->original_working_dir_.c_str(); } // Returns the TestCase object for the test that's currently running, // or NULL if no test is running. const TestCase* UnitTest::current_test_case() const GTEST_LOCK_EXCLUDED_(mutex_) { internal::MutexLock lock(&mutex_); return impl_->current_test_case(); } // Returns the TestInfo object for the test that's currently running, // or NULL if no test is running. const TestInfo* UnitTest::current_test_info() const GTEST_LOCK_EXCLUDED_(mutex_) { internal::MutexLock lock(&mutex_); return impl_->current_test_info(); } // Returns the random seed used at the start of the current test run. int UnitTest::random_seed() const { return impl_->random_seed(); } #if GTEST_HAS_PARAM_TEST // Returns ParameterizedTestCaseRegistry object used to keep track of // value-parameterized tests and instantiate and register them. internal::ParameterizedTestCaseRegistry& UnitTest::parameterized_test_registry() GTEST_LOCK_EXCLUDED_(mutex_) { return impl_->parameterized_test_registry(); } #endif // GTEST_HAS_PARAM_TEST // Creates an empty UnitTest. UnitTest::UnitTest() { impl_ = new internal::UnitTestImpl(this); } // Destructor of UnitTest. UnitTest::~UnitTest() { delete impl_; } // Pushes a trace defined by SCOPED_TRACE() on to the per-thread // Google Test trace stack. void UnitTest::PushGTestTrace(const internal::TraceInfo& trace) GTEST_LOCK_EXCLUDED_(mutex_) { internal::MutexLock lock(&mutex_); impl_->gtest_trace_stack().push_back(trace); } // Pops a trace from the per-thread Google Test trace stack. void UnitTest::PopGTestTrace() GTEST_LOCK_EXCLUDED_(mutex_) { internal::MutexLock lock(&mutex_); impl_->gtest_trace_stack().pop_back(); } namespace internal { UnitTestImpl::UnitTestImpl(UnitTest* parent) : parent_(parent), #ifdef _MSC_VER # pragma warning(push) // Saves the current warning state. # pragma warning(disable:4355) // Temporarily disables warning 4355 // (using this in initializer). default_global_test_part_result_reporter_(this), default_per_thread_test_part_result_reporter_(this), # pragma warning(pop) // Restores the warning state again. #else default_global_test_part_result_reporter_(this), default_per_thread_test_part_result_reporter_(this), #endif // _MSC_VER global_test_part_result_repoter_( &default_global_test_part_result_reporter_), per_thread_test_part_result_reporter_( &default_per_thread_test_part_result_reporter_), #if GTEST_HAS_PARAM_TEST parameterized_test_registry_(), parameterized_tests_registered_(false), #endif // GTEST_HAS_PARAM_TEST last_death_test_case_(-1), current_test_case_(NULL), current_test_info_(NULL), ad_hoc_test_result_(), os_stack_trace_getter_(NULL), post_flag_parse_init_performed_(false), random_seed_(0), // Will be overridden by the flag before first use. random_(0), // Will be reseeded before first use. start_timestamp_(0), elapsed_time_(0), #if GTEST_HAS_DEATH_TEST death_test_factory_(new DefaultDeathTestFactory), #endif // Will be overridden by the flag before first use. catch_exceptions_(false) { listeners()->SetDefaultResultPrinter(new PrettyUnitTestResultPrinter); } UnitTestImpl::~UnitTestImpl() { // Deletes every TestCase. ForEach(test_cases_, internal::Delete); // Deletes every Environment. ForEach(environments_, internal::Delete); delete os_stack_trace_getter_; } // Adds a TestProperty to the current TestResult object when invoked in a // context of a test, to current test case's ad_hoc_test_result when invoke // from SetUpTestCase/TearDownTestCase, or to the global property set // otherwise. If the result already contains a property with the same key, // the value will be updated. void UnitTestImpl::RecordProperty(const TestProperty& test_property) { std::string xml_element; TestResult* test_result; // TestResult appropriate for property recording. if (current_test_info_ != NULL) { xml_element = "testcase"; test_result = &(current_test_info_->result_); } else if (current_test_case_ != NULL) { xml_element = "testsuite"; test_result = &(current_test_case_->ad_hoc_test_result_); } else { xml_element = "testsuites"; test_result = &ad_hoc_test_result_; } test_result->RecordProperty(xml_element, test_property); } #if GTEST_HAS_DEATH_TEST // Disables event forwarding if the control is currently in a death test // subprocess. Must not be called before InitGoogleTest. void UnitTestImpl::SuppressTestEventsIfInSubprocess() { if (internal_run_death_test_flag_.get() != NULL) listeners()->SuppressEventForwarding(); } #endif // GTEST_HAS_DEATH_TEST // Initializes event listeners performing XML output as specified by // UnitTestOptions. Must not be called before InitGoogleTest. void UnitTestImpl::ConfigureXmlOutput() { const std::string& output_format = UnitTestOptions::GetOutputFormat(); if (output_format == "xml") { listeners()->SetDefaultXmlGenerator(new XmlUnitTestResultPrinter( UnitTestOptions::GetAbsolutePathToOutputFile().c_str())); } else if (output_format != "") { printf("WARNING: unrecognized output format \"%s\" ignored.\n", output_format.c_str()); fflush(stdout); } } #if GTEST_CAN_STREAM_RESULTS_ // Initializes event listeners for streaming test results in string form. // Must not be called before InitGoogleTest. void UnitTestImpl::ConfigureStreamingOutput() { const std::string& target = GTEST_FLAG(stream_result_to); if (!target.empty()) { const size_t pos = target.find(':'); if (pos != std::string::npos) { listeners()->Append(new StreamingListener(target.substr(0, pos), target.substr(pos+1))); } else { printf("WARNING: unrecognized streaming target \"%s\" ignored.\n", target.c_str()); fflush(stdout); } } } #endif // GTEST_CAN_STREAM_RESULTS_ // Performs initialization dependent upon flag values obtained in // ParseGoogleTestFlagsOnly. Is called from InitGoogleTest after the call to // ParseGoogleTestFlagsOnly. In case a user neglects to call InitGoogleTest // this function is also called from RunAllTests. Since this function can be // called more than once, it has to be idempotent. void UnitTestImpl::PostFlagParsingInit() { // Ensures that this function does not execute more than once. if (!post_flag_parse_init_performed_) { post_flag_parse_init_performed_ = true; #if GTEST_HAS_DEATH_TEST InitDeathTestSubprocessControlInfo(); SuppressTestEventsIfInSubprocess(); #endif // GTEST_HAS_DEATH_TEST // Registers parameterized tests. This makes parameterized tests // available to the UnitTest reflection API without running // RUN_ALL_TESTS. RegisterParameterizedTests(); // Configures listeners for XML output. This makes it possible for users // to shut down the default XML output before invoking RUN_ALL_TESTS. ConfigureXmlOutput(); #if GTEST_CAN_STREAM_RESULTS_ // Configures listeners for streaming test results to the specified server. ConfigureStreamingOutput(); #endif // GTEST_CAN_STREAM_RESULTS_ } } // A predicate that checks the name of a TestCase against a known // value. // // This is used for implementation of the UnitTest class only. We put // it in the anonymous namespace to prevent polluting the outer // namespace. // // TestCaseNameIs is copyable. class TestCaseNameIs { public: // Constructor. explicit TestCaseNameIs(const std::string& name) : name_(name) {} // Returns true iff the name of test_case matches name_. bool operator()(const TestCase* test_case) const { return test_case != NULL && strcmp(test_case->name(), name_.c_str()) == 0; } private: std::string name_; }; // Finds and returns a TestCase with the given name. If one doesn't // exist, creates one and returns it. It's the CALLER'S // RESPONSIBILITY to ensure that this function is only called WHEN THE // TESTS ARE NOT SHUFFLED. // // Arguments: // // test_case_name: name of the test case // type_param: the name of the test case's type parameter, or NULL if // this is not a typed or a type-parameterized test case. // set_up_tc: pointer to the function that sets up the test case // tear_down_tc: pointer to the function that tears down the test case TestCase* UnitTestImpl::GetTestCase(const char* test_case_name, const char* type_param, Test::SetUpTestCaseFunc set_up_tc, Test::TearDownTestCaseFunc tear_down_tc) { // Can we find a TestCase with the given name? const std::vector::const_iterator test_case = std::find_if(test_cases_.begin(), test_cases_.end(), TestCaseNameIs(test_case_name)); if (test_case != test_cases_.end()) return *test_case; // No. Let's create one. TestCase* const new_test_case = new TestCase(test_case_name, type_param, set_up_tc, tear_down_tc); // Is this a death test case? if (internal::UnitTestOptions::MatchesFilter(test_case_name, kDeathTestCaseFilter)) { // Yes. Inserts the test case after the last death test case // defined so far. This only works when the test cases haven't // been shuffled. Otherwise we may end up running a death test // after a non-death test. ++last_death_test_case_; test_cases_.insert(test_cases_.begin() + last_death_test_case_, new_test_case); } else { // No. Appends to the end of the list. test_cases_.push_back(new_test_case); } test_case_indices_.push_back(static_cast(test_case_indices_.size())); return new_test_case; } // Helpers for setting up / tearing down the given environment. They // are for use in the ForEach() function. static void SetUpEnvironment(Environment* env) { env->SetUp(); } static void TearDownEnvironment(Environment* env) { env->TearDown(); } // Runs all tests in this UnitTest object, prints the result, and // returns true if all tests are successful. If any exception is // thrown during a test, the test is considered to be failed, but the // rest of the tests will still be run. // // When parameterized tests are enabled, it expands and registers // parameterized tests first in RegisterParameterizedTests(). // All other functions called from RunAllTests() may safely assume that // parameterized tests are ready to be counted and run. bool UnitTestImpl::RunAllTests() { // Makes sure InitGoogleTest() was called. if (!GTestIsInitialized()) { printf("%s", "\nThis test program did NOT call ::testing::InitGoogleTest " "before calling RUN_ALL_TESTS(). Please fix it.\n"); return false; } // Do not run any test if the --help flag was specified. if (g_help_flag) return true; // Repeats the call to the post-flag parsing initialization in case the // user didn't call InitGoogleTest. PostFlagParsingInit(); // Even if sharding is not on, test runners may want to use the // GTEST_SHARD_STATUS_FILE to query whether the test supports the sharding // protocol. internal::WriteToShardStatusFileIfNeeded(); // True iff we are in a subprocess for running a thread-safe-style // death test. bool in_subprocess_for_death_test = false; #if GTEST_HAS_DEATH_TEST in_subprocess_for_death_test = (internal_run_death_test_flag_.get() != NULL); #endif // GTEST_HAS_DEATH_TEST const bool should_shard = ShouldShard(kTestTotalShards, kTestShardIndex, in_subprocess_for_death_test); // Compares the full test names with the filter to decide which // tests to run. const bool has_tests_to_run = FilterTests(should_shard ? HONOR_SHARDING_PROTOCOL : IGNORE_SHARDING_PROTOCOL) > 0; // Lists the tests and exits if the --gtest_list_tests flag was specified. if (GTEST_FLAG(list_tests)) { // This must be called *after* FilterTests() has been called. ListTestsMatchingFilter(); return true; } random_seed_ = GTEST_FLAG(shuffle) ? GetRandomSeedFromFlag(GTEST_FLAG(random_seed)) : 0; // True iff at least one test has failed. bool failed = false; TestEventListener* repeater = listeners()->repeater(); start_timestamp_ = GetTimeInMillis(); repeater->OnTestProgramStart(*parent_); // How many times to repeat the tests? We don't want to repeat them // when we are inside the subprocess of a death test. const int repeat = in_subprocess_for_death_test ? 1 : GTEST_FLAG(repeat); // Repeats forever if the repeat count is negative. const bool forever = repeat < 0; for (int i = 0; forever || i != repeat; i++) { // We want to preserve failures generated by ad-hoc test // assertions executed before RUN_ALL_TESTS(). ClearNonAdHocTestResult(); const TimeInMillis start = GetTimeInMillis(); // Shuffles test cases and tests if requested. if (has_tests_to_run && GTEST_FLAG(shuffle)) { random()->Reseed(random_seed_); // This should be done before calling OnTestIterationStart(), // such that a test event listener can see the actual test order // in the event. ShuffleTests(); } // Tells the unit test event listeners that the tests are about to start. repeater->OnTestIterationStart(*parent_, i); // Runs each test case if there is at least one test to run. if (has_tests_to_run) { // Sets up all environments beforehand. repeater->OnEnvironmentsSetUpStart(*parent_); ForEach(environments_, SetUpEnvironment); repeater->OnEnvironmentsSetUpEnd(*parent_); // Runs the tests only if there was no fatal failure during global // set-up. if (!Test::HasFatalFailure()) { for (int test_index = 0; test_index < total_test_case_count(); test_index++) { GetMutableTestCase(test_index)->Run(); } } // Tears down all environments in reverse order afterwards. repeater->OnEnvironmentsTearDownStart(*parent_); std::for_each(environments_.rbegin(), environments_.rend(), TearDownEnvironment); repeater->OnEnvironmentsTearDownEnd(*parent_); } elapsed_time_ = GetTimeInMillis() - start; // Tells the unit test event listener that the tests have just finished. repeater->OnTestIterationEnd(*parent_, i); // Gets the result and clears it. if (!Passed()) { failed = true; } // Restores the original test order after the iteration. This // allows the user to quickly repro a failure that happens in the // N-th iteration without repeating the first (N - 1) iterations. // This is not enclosed in "if (GTEST_FLAG(shuffle)) { ... }", in // case the user somehow changes the value of the flag somewhere // (it's always safe to unshuffle the tests). UnshuffleTests(); if (GTEST_FLAG(shuffle)) { // Picks a new random seed for each iteration. random_seed_ = GetNextRandomSeed(random_seed_); } } repeater->OnTestProgramEnd(*parent_); return !failed; } // Reads the GTEST_SHARD_STATUS_FILE environment variable, and creates the file // if the variable is present. If a file already exists at this location, this // function will write over it. If the variable is present, but the file cannot // be created, prints an error and exits. void WriteToShardStatusFileIfNeeded() { const char* const test_shard_file = posix::GetEnv(kTestShardStatusFile); if (test_shard_file != NULL) { FILE* const file = posix::FOpen(test_shard_file, "w"); if (file == NULL) { ColoredPrintf(COLOR_RED, "Could not write to the test shard status file \"%s\" " "specified by the %s environment variable.\n", test_shard_file, kTestShardStatusFile); fflush(stdout); exit(EXIT_FAILURE); } fclose(file); } } // Checks whether sharding is enabled by examining the relevant // environment variable values. If the variables are present, // but inconsistent (i.e., shard_index >= total_shards), prints // an error and exits. If in_subprocess_for_death_test, sharding is // disabled because it must only be applied to the original test // process. Otherwise, we could filter out death tests we intended to execute. bool ShouldShard(const char* total_shards_env, const char* shard_index_env, bool in_subprocess_for_death_test) { if (in_subprocess_for_death_test) { return false; } const Int32 total_shards = Int32FromEnvOrDie(total_shards_env, -1); const Int32 shard_index = Int32FromEnvOrDie(shard_index_env, -1); if (total_shards == -1 && shard_index == -1) { return false; } else if (total_shards == -1 && shard_index != -1) { const Message msg = Message() << "Invalid environment variables: you have " << kTestShardIndex << " = " << shard_index << ", but have left " << kTestTotalShards << " unset.\n"; ColoredPrintf(COLOR_RED, msg.GetString().c_str()); fflush(stdout); exit(EXIT_FAILURE); } else if (total_shards != -1 && shard_index == -1) { const Message msg = Message() << "Invalid environment variables: you have " << kTestTotalShards << " = " << total_shards << ", but have left " << kTestShardIndex << " unset.\n"; ColoredPrintf(COLOR_RED, msg.GetString().c_str()); fflush(stdout); exit(EXIT_FAILURE); } else if (shard_index < 0 || shard_index >= total_shards) { const Message msg = Message() << "Invalid environment variables: we require 0 <= " << kTestShardIndex << " < " << kTestTotalShards << ", but you have " << kTestShardIndex << "=" << shard_index << ", " << kTestTotalShards << "=" << total_shards << ".\n"; ColoredPrintf(COLOR_RED, msg.GetString().c_str()); fflush(stdout); exit(EXIT_FAILURE); } return total_shards > 1; } // Parses the environment variable var as an Int32. If it is unset, // returns default_val. If it is not an Int32, prints an error // and aborts. Int32 Int32FromEnvOrDie(const char* var, Int32 default_val) { const char* str_val = posix::GetEnv(var); if (str_val == NULL) { return default_val; } Int32 result; if (!ParseInt32(Message() << "The value of environment variable " << var, str_val, &result)) { exit(EXIT_FAILURE); } return result; } // Given the total number of shards, the shard index, and the test id, // returns true iff the test should be run on this shard. The test id is // some arbitrary but unique non-negative integer assigned to each test // method. Assumes that 0 <= shard_index < total_shards. bool ShouldRunTestOnShard(int total_shards, int shard_index, int test_id) { return (test_id % total_shards) == shard_index; } // Compares the name of each test with the user-specified filter to // decide whether the test should be run, then records the result in // each TestCase and TestInfo object. // If shard_tests == true, further filters tests based on sharding // variables in the environment - see // http://code.google.com/p/googletest/wiki/GoogleTestAdvancedGuide. // Returns the number of tests that should run. int UnitTestImpl::FilterTests(ReactionToSharding shard_tests) { const Int32 total_shards = shard_tests == HONOR_SHARDING_PROTOCOL ? Int32FromEnvOrDie(kTestTotalShards, -1) : -1; const Int32 shard_index = shard_tests == HONOR_SHARDING_PROTOCOL ? Int32FromEnvOrDie(kTestShardIndex, -1) : -1; // num_runnable_tests are the number of tests that will // run across all shards (i.e., match filter and are not disabled). // num_selected_tests are the number of tests to be run on // this shard. int num_runnable_tests = 0; int num_selected_tests = 0; for (size_t i = 0; i < test_cases_.size(); i++) { TestCase* const test_case = test_cases_[i]; const std::string &test_case_name = test_case->name(); test_case->set_should_run(false); for (size_t j = 0; j < test_case->test_info_list().size(); j++) { TestInfo* const test_info = test_case->test_info_list()[j]; const std::string test_name(test_info->name()); // A test is disabled if test case name or test name matches // kDisableTestFilter. const bool is_disabled = internal::UnitTestOptions::MatchesFilter(test_case_name, kDisableTestFilter) || internal::UnitTestOptions::MatchesFilter(test_name, kDisableTestFilter); test_info->is_disabled_ = is_disabled; const bool matches_filter = internal::UnitTestOptions::FilterMatchesTest(test_case_name, test_name); test_info->matches_filter_ = matches_filter; const bool is_runnable = (GTEST_FLAG(also_run_disabled_tests) || !is_disabled) && matches_filter; const bool is_selected = is_runnable && (shard_tests == IGNORE_SHARDING_PROTOCOL || ShouldRunTestOnShard(total_shards, shard_index, num_runnable_tests)); num_runnable_tests += is_runnable; num_selected_tests += is_selected; test_info->should_run_ = is_selected; test_case->set_should_run(test_case->should_run() || is_selected); } } return num_selected_tests; } // Prints the given C-string on a single line by replacing all '\n' // characters with string "\\n". If the output takes more than // max_length characters, only prints the first max_length characters // and "...". static void PrintOnOneLine(const char* str, int max_length) { if (str != NULL) { for (int i = 0; *str != '\0'; ++str) { if (i >= max_length) { printf("..."); break; } if (*str == '\n') { printf("\\n"); i += 2; } else { printf("%c", *str); ++i; } } } } // Prints the names of the tests matching the user-specified filter flag. void UnitTestImpl::ListTestsMatchingFilter() { // Print at most this many characters for each type/value parameter. const int kMaxParamLength = 250; for (size_t i = 0; i < test_cases_.size(); i++) { const TestCase* const test_case = test_cases_[i]; bool printed_test_case_name = false; for (size_t j = 0; j < test_case->test_info_list().size(); j++) { const TestInfo* const test_info = test_case->test_info_list()[j]; if (test_info->matches_filter_) { if (!printed_test_case_name) { printed_test_case_name = true; printf("%s.", test_case->name()); if (test_case->type_param() != NULL) { printf(" # %s = ", kTypeParamLabel); // We print the type parameter on a single line to make // the output easy to parse by a program. PrintOnOneLine(test_case->type_param(), kMaxParamLength); } printf("\n"); } printf(" %s", test_info->name()); if (test_info->value_param() != NULL) { printf(" # %s = ", kValueParamLabel); // We print the value parameter on a single line to make the // output easy to parse by a program. PrintOnOneLine(test_info->value_param(), kMaxParamLength); } printf("\n"); } } } fflush(stdout); } // Sets the OS stack trace getter. // // Does nothing if the input and the current OS stack trace getter are // the same; otherwise, deletes the old getter and makes the input the // current getter. void UnitTestImpl::set_os_stack_trace_getter( OsStackTraceGetterInterface* getter) { if (os_stack_trace_getter_ != getter) { delete os_stack_trace_getter_; os_stack_trace_getter_ = getter; } } // Returns the current OS stack trace getter if it is not NULL; // otherwise, creates an OsStackTraceGetter, makes it the current // getter, and returns it. OsStackTraceGetterInterface* UnitTestImpl::os_stack_trace_getter() { if (os_stack_trace_getter_ == NULL) { os_stack_trace_getter_ = new OsStackTraceGetter; } return os_stack_trace_getter_; } // Returns the TestResult for the test that's currently running, or // the TestResult for the ad hoc test if no test is running. TestResult* UnitTestImpl::current_test_result() { return current_test_info_ ? &(current_test_info_->result_) : &ad_hoc_test_result_; } // Shuffles all test cases, and the tests within each test case, // making sure that death tests are still run first. void UnitTestImpl::ShuffleTests() { // Shuffles the death test cases. ShuffleRange(random(), 0, last_death_test_case_ + 1, &test_case_indices_); // Shuffles the non-death test cases. ShuffleRange(random(), last_death_test_case_ + 1, static_cast(test_cases_.size()), &test_case_indices_); // Shuffles the tests inside each test case. for (size_t i = 0; i < test_cases_.size(); i++) { test_cases_[i]->ShuffleTests(random()); } } // Restores the test cases and tests to their order before the first shuffle. void UnitTestImpl::UnshuffleTests() { for (size_t i = 0; i < test_cases_.size(); i++) { // Unshuffles the tests in each test case. test_cases_[i]->UnshuffleTests(); // Resets the index of each test case. test_case_indices_[i] = static_cast(i); } } // Returns the current OS stack trace as an std::string. // // The maximum number of stack frames to be included is specified by // the gtest_stack_trace_depth flag. The skip_count parameter // specifies the number of top frames to be skipped, which doesn't // count against the number of frames to be included. // // For example, if Foo() calls Bar(), which in turn calls // GetCurrentOsStackTraceExceptTop(..., 1), Foo() will be included in // the trace but Bar() and GetCurrentOsStackTraceExceptTop() won't. std::string GetCurrentOsStackTraceExceptTop(UnitTest* /*unit_test*/, int skip_count) { // We pass skip_count + 1 to skip this wrapper function in addition // to what the user really wants to skip. return GetUnitTestImpl()->CurrentOsStackTraceExceptTop(skip_count + 1); } // Used by the GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_ macro to // suppress unreachable code warnings. namespace { class ClassUniqueToAlwaysTrue {}; } bool IsTrue(bool condition) { return condition; } bool AlwaysTrue() { #if GTEST_HAS_EXCEPTIONS // This condition is always false so AlwaysTrue() never actually throws, // but it makes the compiler think that it may throw. if (IsTrue(false)) throw ClassUniqueToAlwaysTrue(); #endif // GTEST_HAS_EXCEPTIONS return true; } // If *pstr starts with the given prefix, modifies *pstr to be right // past the prefix and returns true; otherwise leaves *pstr unchanged // and returns false. None of pstr, *pstr, and prefix can be NULL. bool SkipPrefix(const char* prefix, const char** pstr) { const size_t prefix_len = strlen(prefix); if (strncmp(*pstr, prefix, prefix_len) == 0) { *pstr += prefix_len; return true; } return false; } // Parses a string as a command line flag. The string should have // the format "--flag=value". When def_optional is true, the "=value" // part can be omitted. // // Returns the value of the flag, or NULL if the parsing failed. const char* ParseFlagValue(const char* str, const char* flag, bool def_optional) { // str and flag must not be NULL. if (str == NULL || flag == NULL) return NULL; // The flag must start with "--" followed by GTEST_FLAG_PREFIX_. const std::string flag_str = std::string("--") + GTEST_FLAG_PREFIX_ + flag; const size_t flag_len = flag_str.length(); if (strncmp(str, flag_str.c_str(), flag_len) != 0) return NULL; // Skips the flag name. const char* flag_end = str + flag_len; // When def_optional is true, it's OK to not have a "=value" part. if (def_optional && (flag_end[0] == '\0')) { return flag_end; } // If def_optional is true and there are more characters after the // flag name, or if def_optional is false, there must be a '=' after // the flag name. if (flag_end[0] != '=') return NULL; // Returns the string after "=". return flag_end + 1; } // Parses a string for a bool flag, in the form of either // "--flag=value" or "--flag". // // In the former case, the value is taken as true as long as it does // not start with '0', 'f', or 'F'. // // In the latter case, the value is taken as true. // // On success, stores the value of the flag in *value, and returns // true. On failure, returns false without changing *value. bool ParseBoolFlag(const char* str, const char* flag, bool* value) { // Gets the value of the flag as a string. const char* const value_str = ParseFlagValue(str, flag, true); // Aborts if the parsing failed. if (value_str == NULL) return false; // Converts the string value to a bool. *value = !(*value_str == '0' || *value_str == 'f' || *value_str == 'F'); return true; } // Parses a string for an Int32 flag, in the form of // "--flag=value". // // On success, stores the value of the flag in *value, and returns // true. On failure, returns false without changing *value. bool ParseInt32Flag(const char* str, const char* flag, Int32* value) { // Gets the value of the flag as a string. const char* const value_str = ParseFlagValue(str, flag, false); // Aborts if the parsing failed. if (value_str == NULL) return false; // Sets *value to the value of the flag. return ParseInt32(Message() << "The value of flag --" << flag, value_str, value); } // Parses a string for a string flag, in the form of // "--flag=value". // // On success, stores the value of the flag in *value, and returns // true. On failure, returns false without changing *value. bool ParseStringFlag(const char* str, const char* flag, std::string* value) { // Gets the value of the flag as a string. const char* const value_str = ParseFlagValue(str, flag, false); // Aborts if the parsing failed. if (value_str == NULL) return false; // Sets *value to the value of the flag. *value = value_str; return true; } // Determines whether a string has a prefix that Google Test uses for its // flags, i.e., starts with GTEST_FLAG_PREFIX_ or GTEST_FLAG_PREFIX_DASH_. // If Google Test detects that a command line flag has its prefix but is not // recognized, it will print its help message. Flags starting with // GTEST_INTERNAL_PREFIX_ followed by "internal_" are considered Google Test // internal flags and do not trigger the help message. static bool HasGoogleTestFlagPrefix(const char* str) { return (SkipPrefix("--", &str) || SkipPrefix("-", &str) || SkipPrefix("/", &str)) && !SkipPrefix(GTEST_FLAG_PREFIX_ "internal_", &str) && (SkipPrefix(GTEST_FLAG_PREFIX_, &str) || SkipPrefix(GTEST_FLAG_PREFIX_DASH_, &str)); } // Prints a string containing code-encoded text. The following escape // sequences can be used in the string to control the text color: // // @@ prints a single '@' character. // @R changes the color to red. // @G changes the color to green. // @Y changes the color to yellow. // @D changes to the default terminal text color. // // TODO(wan@google.com): Write tests for this once we add stdout // capturing to Google Test. static void PrintColorEncoded(const char* str) { GTestColor color = COLOR_DEFAULT; // The current color. // Conceptually, we split the string into segments divided by escape // sequences. Then we print one segment at a time. At the end of // each iteration, the str pointer advances to the beginning of the // next segment. for (;;) { const char* p = strchr(str, '@'); if (p == NULL) { ColoredPrintf(color, "%s", str); return; } ColoredPrintf(color, "%s", std::string(str, p).c_str()); const char ch = p[1]; str = p + 2; if (ch == '@') { ColoredPrintf(color, "@"); } else if (ch == 'D') { color = COLOR_DEFAULT; } else if (ch == 'R') { color = COLOR_RED; } else if (ch == 'G') { color = COLOR_GREEN; } else if (ch == 'Y') { color = COLOR_YELLOW; } else { --str; } } } static const char kColorEncodedHelpMessage[] = "This program contains tests written using " GTEST_NAME_ ". You can use the\n" "following command line flags to control its behavior:\n" "\n" "Test Selection:\n" " @G--" GTEST_FLAG_PREFIX_ "list_tests@D\n" " List the names of all tests instead of running them. The name of\n" " TEST(Foo, Bar) is \"Foo.Bar\".\n" " @G--" GTEST_FLAG_PREFIX_ "filter=@YPOSTIVE_PATTERNS" "[@G-@YNEGATIVE_PATTERNS]@D\n" " Run only the tests whose name matches one of the positive patterns but\n" " none of the negative patterns. '?' matches any single character; '*'\n" " matches any substring; ':' separates two patterns.\n" " @G--" GTEST_FLAG_PREFIX_ "also_run_disabled_tests@D\n" " Run all disabled tests too.\n" "\n" "Test Execution:\n" " @G--" GTEST_FLAG_PREFIX_ "repeat=@Y[COUNT]@D\n" " Run the tests repeatedly; use a negative count to repeat forever.\n" " @G--" GTEST_FLAG_PREFIX_ "shuffle@D\n" " Randomize tests' orders on every iteration.\n" " @G--" GTEST_FLAG_PREFIX_ "random_seed=@Y[NUMBER]@D\n" " Random number seed to use for shuffling test orders (between 1 and\n" " 99999, or 0 to use a seed based on the current time).\n" "\n" "Test Output:\n" " @G--" GTEST_FLAG_PREFIX_ "color=@Y(@Gyes@Y|@Gno@Y|@Gauto@Y)@D\n" " Enable/disable colored output. The default is @Gauto@D.\n" " -@G-" GTEST_FLAG_PREFIX_ "print_time=0@D\n" " Don't print the elapsed time of each test.\n" " @G--" GTEST_FLAG_PREFIX_ "output=xml@Y[@G:@YDIRECTORY_PATH@G" GTEST_PATH_SEP_ "@Y|@G:@YFILE_PATH]@D\n" " Generate an XML report in the given directory or with the given file\n" " name. @YFILE_PATH@D defaults to @Gtest_details.xml@D.\n" #if GTEST_CAN_STREAM_RESULTS_ " @G--" GTEST_FLAG_PREFIX_ "stream_result_to=@YHOST@G:@YPORT@D\n" " Stream test results to the given server.\n" #endif // GTEST_CAN_STREAM_RESULTS_ "\n" "Assertion Behavior:\n" #if GTEST_HAS_DEATH_TEST && !GTEST_OS_WINDOWS " @G--" GTEST_FLAG_PREFIX_ "death_test_style=@Y(@Gfast@Y|@Gthreadsafe@Y)@D\n" " Set the default death test style.\n" #endif // GTEST_HAS_DEATH_TEST && !GTEST_OS_WINDOWS " @G--" GTEST_FLAG_PREFIX_ "break_on_failure@D\n" " Turn assertion failures into debugger break-points.\n" " @G--" GTEST_FLAG_PREFIX_ "throw_on_failure@D\n" " Turn assertion failures into C++ exceptions.\n" " @G--" GTEST_FLAG_PREFIX_ "catch_exceptions=0@D\n" " Do not report exceptions as test failures. Instead, allow them\n" " to crash the program or throw a pop-up (on Windows).\n" "\n" "Except for @G--" GTEST_FLAG_PREFIX_ "list_tests@D, you can alternatively set " "the corresponding\n" "environment variable of a flag (all letters in upper-case). For example, to\n" "disable colored text output, you can either specify @G--" GTEST_FLAG_PREFIX_ "color=no@D or set\n" "the @G" GTEST_FLAG_PREFIX_UPPER_ "COLOR@D environment variable to @Gno@D.\n" "\n" "For more information, please read the " GTEST_NAME_ " documentation at\n" "@G" GTEST_PROJECT_URL_ "@D. If you find a bug in " GTEST_NAME_ "\n" "(not one in your own code or tests), please report it to\n" "@G<" GTEST_DEV_EMAIL_ ">@D.\n"; // Parses the command line for Google Test flags, without initializing // other parts of Google Test. The type parameter CharType can be // instantiated to either char or wchar_t. template void ParseGoogleTestFlagsOnlyImpl(int* argc, CharType** argv) { for (int i = 1; i < *argc; i++) { const std::string arg_string = StreamableToString(argv[i]); const char* const arg = arg_string.c_str(); using internal::ParseBoolFlag; using internal::ParseInt32Flag; using internal::ParseStringFlag; // Do we see a Google Test flag? if (ParseBoolFlag(arg, kAlsoRunDisabledTestsFlag, >EST_FLAG(also_run_disabled_tests)) || ParseBoolFlag(arg, kBreakOnFailureFlag, >EST_FLAG(break_on_failure)) || ParseBoolFlag(arg, kCatchExceptionsFlag, >EST_FLAG(catch_exceptions)) || ParseStringFlag(arg, kColorFlag, >EST_FLAG(color)) || ParseStringFlag(arg, kDeathTestStyleFlag, >EST_FLAG(death_test_style)) || ParseBoolFlag(arg, kDeathTestUseFork, >EST_FLAG(death_test_use_fork)) || ParseStringFlag(arg, kFilterFlag, >EST_FLAG(filter)) || ParseStringFlag(arg, kInternalRunDeathTestFlag, >EST_FLAG(internal_run_death_test)) || ParseBoolFlag(arg, kListTestsFlag, >EST_FLAG(list_tests)) || ParseStringFlag(arg, kOutputFlag, >EST_FLAG(output)) || ParseBoolFlag(arg, kPrintTimeFlag, >EST_FLAG(print_time)) || ParseInt32Flag(arg, kRandomSeedFlag, >EST_FLAG(random_seed)) || ParseInt32Flag(arg, kRepeatFlag, >EST_FLAG(repeat)) || ParseBoolFlag(arg, kShuffleFlag, >EST_FLAG(shuffle)) || ParseInt32Flag(arg, kStackTraceDepthFlag, >EST_FLAG(stack_trace_depth)) || ParseStringFlag(arg, kStreamResultToFlag, >EST_FLAG(stream_result_to)) || ParseBoolFlag(arg, kThrowOnFailureFlag, >EST_FLAG(throw_on_failure)) ) { // Yes. Shift the remainder of the argv list left by one. Note // that argv has (*argc + 1) elements, the last one always being // NULL. The following loop moves the trailing NULL element as // well. for (int j = i; j != *argc; j++) { argv[j] = argv[j + 1]; } // Decrements the argument count. (*argc)--; // We also need to decrement the iterator as we just removed // an element. i--; } else if (arg_string == "--help" || arg_string == "-h" || arg_string == "-?" || arg_string == "/?" || HasGoogleTestFlagPrefix(arg)) { // Both help flag and unrecognized Google Test flags (excluding // internal ones) trigger help display. g_help_flag = true; } } if (g_help_flag) { // We print the help here instead of in RUN_ALL_TESTS(), as the // latter may not be called at all if the user is using Google // Test with another testing framework. PrintColorEncoded(kColorEncodedHelpMessage); } } // Parses the command line for Google Test flags, without initializing // other parts of Google Test. void ParseGoogleTestFlagsOnly(int* argc, char** argv) { ParseGoogleTestFlagsOnlyImpl(argc, argv); } void ParseGoogleTestFlagsOnly(int* argc, wchar_t** argv) { ParseGoogleTestFlagsOnlyImpl(argc, argv); } // The internal implementation of InitGoogleTest(). // // The type parameter CharType can be instantiated to either char or // wchar_t. template void InitGoogleTestImpl(int* argc, CharType** argv) { g_init_gtest_count++; // We don't want to run the initialization code twice. if (g_init_gtest_count != 1) return; if (*argc <= 0) return; internal::g_executable_path = internal::StreamableToString(argv[0]); #if GTEST_HAS_DEATH_TEST g_argvs.clear(); for (int i = 0; i != *argc; i++) { g_argvs.push_back(StreamableToString(argv[i])); } #endif // GTEST_HAS_DEATH_TEST ParseGoogleTestFlagsOnly(argc, argv); GetUnitTestImpl()->PostFlagParsingInit(); } } // namespace internal // Initializes Google Test. This must be called before calling // RUN_ALL_TESTS(). In particular, it parses a command line for the // flags that Google Test recognizes. Whenever a Google Test flag is // seen, it is removed from argv, and *argc is decremented. // // No value is returned. Instead, the Google Test flag variables are // updated. // // Calling the function for the second time has no user-visible effect. void InitGoogleTest(int* argc, char** argv) { internal::InitGoogleTestImpl(argc, argv); } // This overloaded version can be used in Windows programs compiled in // UNICODE mode. void InitGoogleTest(int* argc, wchar_t** argv) { internal::InitGoogleTestImpl(argc, argv); } } // namespace testing // Copyright 2005, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: wan@google.com (Zhanyong Wan), vladl@google.com (Vlad Losev) // // This file implements death tests. #if GTEST_HAS_DEATH_TEST # if GTEST_OS_MAC # include # endif // GTEST_OS_MAC # include # include # include # if GTEST_OS_LINUX # include # endif // GTEST_OS_LINUX # include # if GTEST_OS_WINDOWS # include # else # include # include # endif // GTEST_OS_WINDOWS # if GTEST_OS_QNX # include # endif // GTEST_OS_QNX #endif // GTEST_HAS_DEATH_TEST // Indicates that this translation unit is part of Google Test's // implementation. It must come before gtest-internal-inl.h is // included, or there will be a compiler error. This trick is to // prevent a user from accidentally including gtest-internal-inl.h in // his code. #define GTEST_IMPLEMENTATION_ 1 #undef GTEST_IMPLEMENTATION_ namespace testing { // Constants. // The default death test style. static const char kDefaultDeathTestStyle[] = "fast"; GTEST_DEFINE_string_( death_test_style, internal::StringFromGTestEnv("death_test_style", kDefaultDeathTestStyle), "Indicates how to run a death test in a forked child process: " "\"threadsafe\" (child process re-executes the test binary " "from the beginning, running only the specific death test) or " "\"fast\" (child process runs the death test immediately " "after forking)."); GTEST_DEFINE_bool_( death_test_use_fork, internal::BoolFromGTestEnv("death_test_use_fork", false), "Instructs to use fork()/_exit() instead of clone() in death tests. " "Ignored and always uses fork() on POSIX systems where clone() is not " "implemented. Useful when running under valgrind or similar tools if " "those do not support clone(). Valgrind 3.3.1 will just fail if " "it sees an unsupported combination of clone() flags. " "It is not recommended to use this flag w/o valgrind though it will " "work in 99% of the cases. Once valgrind is fixed, this flag will " "most likely be removed."); namespace internal { GTEST_DEFINE_string_( internal_run_death_test, "", "Indicates the file, line number, temporal index of " "the single death test to run, and a file descriptor to " "which a success code may be sent, all separated by " "the '|' characters. This flag is specified if and only if the current " "process is a sub-process launched for running a thread-safe " "death test. FOR INTERNAL USE ONLY."); } // namespace internal #if GTEST_HAS_DEATH_TEST namespace internal { // Valid only for fast death tests. Indicates the code is running in the // child process of a fast style death test. static bool g_in_fast_death_test_child = false; // Returns a Boolean value indicating whether the caller is currently // executing in the context of the death test child process. Tools such as // Valgrind heap checkers may need this to modify their behavior in death // tests. IMPORTANT: This is an internal utility. Using it may break the // implementation of death tests. User code MUST NOT use it. bool InDeathTestChild() { # if GTEST_OS_WINDOWS // On Windows, death tests are thread-safe regardless of the value of the // death_test_style flag. return !GTEST_FLAG(internal_run_death_test).empty(); # else if (GTEST_FLAG(death_test_style) == "threadsafe") return !GTEST_FLAG(internal_run_death_test).empty(); else return g_in_fast_death_test_child; #endif } } // namespace internal // ExitedWithCode constructor. ExitedWithCode::ExitedWithCode(int exit_code) : exit_code_(exit_code) { } // ExitedWithCode function-call operator. bool ExitedWithCode::operator()(int exit_status) const { # if GTEST_OS_WINDOWS return exit_status == exit_code_; # else return WIFEXITED(exit_status) && WEXITSTATUS(exit_status) == exit_code_; # endif // GTEST_OS_WINDOWS } # if !GTEST_OS_WINDOWS // KilledBySignal constructor. KilledBySignal::KilledBySignal(int signum) : signum_(signum) { } // KilledBySignal function-call operator. bool KilledBySignal::operator()(int exit_status) const { return WIFSIGNALED(exit_status) && WTERMSIG(exit_status) == signum_; } # endif // !GTEST_OS_WINDOWS namespace internal { // Utilities needed for death tests. // Generates a textual description of a given exit code, in the format // specified by wait(2). static std::string ExitSummary(int exit_code) { Message m; # if GTEST_OS_WINDOWS m << "Exited with exit status " << exit_code; # else if (WIFEXITED(exit_code)) { m << "Exited with exit status " << WEXITSTATUS(exit_code); } else if (WIFSIGNALED(exit_code)) { m << "Terminated by signal " << WTERMSIG(exit_code); } # ifdef WCOREDUMP if (WCOREDUMP(exit_code)) { m << " (core dumped)"; } # endif # endif // GTEST_OS_WINDOWS return m.GetString(); } // Returns true if exit_status describes a process that was terminated // by a signal, or exited normally with a nonzero exit code. bool ExitedUnsuccessfully(int exit_status) { return !ExitedWithCode(0)(exit_status); } # if !GTEST_OS_WINDOWS // Generates a textual failure message when a death test finds more than // one thread running, or cannot determine the number of threads, prior // to executing the given statement. It is the responsibility of the // caller not to pass a thread_count of 1. static std::string DeathTestThreadWarning(size_t thread_count) { Message msg; msg << "Death tests use fork(), which is unsafe particularly" << " in a threaded context. For this test, " << GTEST_NAME_ << " "; if (thread_count == 0) msg << "couldn't detect the number of threads."; else msg << "detected " << thread_count << " threads."; return msg.GetString(); } # endif // !GTEST_OS_WINDOWS // Flag characters for reporting a death test that did not die. static const char kDeathTestLived = 'L'; static const char kDeathTestReturned = 'R'; static const char kDeathTestThrew = 'T'; static const char kDeathTestInternalError = 'I'; // An enumeration describing all of the possible ways that a death test can // conclude. DIED means that the process died while executing the test // code; LIVED means that process lived beyond the end of the test code; // RETURNED means that the test statement attempted to execute a return // statement, which is not allowed; THREW means that the test statement // returned control by throwing an exception. IN_PROGRESS means the test // has not yet concluded. // TODO(vladl@google.com): Unify names and possibly values for // AbortReason, DeathTestOutcome, and flag characters above. enum DeathTestOutcome { IN_PROGRESS, DIED, LIVED, RETURNED, THREW }; // Routine for aborting the program which is safe to call from an // exec-style death test child process, in which case the error // message is propagated back to the parent process. Otherwise, the // message is simply printed to stderr. In either case, the program // then exits with status 1. void DeathTestAbort(const std::string& message) { // On a POSIX system, this function may be called from a threadsafe-style // death test child process, which operates on a very small stack. Use // the heap for any additional non-minuscule memory requirements. const InternalRunDeathTestFlag* const flag = GetUnitTestImpl()->internal_run_death_test_flag(); if (flag != NULL) { FILE* parent = posix::FDOpen(flag->write_fd(), "w"); fputc(kDeathTestInternalError, parent); fprintf(parent, "%s", message.c_str()); fflush(parent); _exit(1); } else { fprintf(stderr, "%s", message.c_str()); fflush(stderr); posix::Abort(); } } // A replacement for CHECK that calls DeathTestAbort if the assertion // fails. # define GTEST_DEATH_TEST_CHECK_(expression) \ do { \ if (!::testing::internal::IsTrue(expression)) { \ DeathTestAbort( \ ::std::string("CHECK failed: File ") + __FILE__ + ", line " \ + ::testing::internal::StreamableToString(__LINE__) + ": " \ + #expression); \ } \ } while (::testing::internal::AlwaysFalse()) // This macro is similar to GTEST_DEATH_TEST_CHECK_, but it is meant for // evaluating any system call that fulfills two conditions: it must return // -1 on failure, and set errno to EINTR when it is interrupted and // should be tried again. The macro expands to a loop that repeatedly // evaluates the expression as long as it evaluates to -1 and sets // errno to EINTR. If the expression evaluates to -1 but errno is // something other than EINTR, DeathTestAbort is called. # define GTEST_DEATH_TEST_CHECK_SYSCALL_(expression) \ do { \ int gtest_retval; \ do { \ gtest_retval = (expression); \ } while (gtest_retval == -1 && errno == EINTR); \ if (gtest_retval == -1) { \ DeathTestAbort( \ ::std::string("CHECK failed: File ") + __FILE__ + ", line " \ + ::testing::internal::StreamableToString(__LINE__) + ": " \ + #expression + " != -1"); \ } \ } while (::testing::internal::AlwaysFalse()) // Returns the message describing the last system error in errno. std::string GetLastErrnoDescription() { return errno == 0 ? "" : posix::StrError(errno); } // This is called from a death test parent process to read a failure // message from the death test child process and log it with the FATAL // severity. On Windows, the message is read from a pipe handle. On other // platforms, it is read from a file descriptor. static void FailFromInternalError(int fd) { Message error; char buffer[256]; int num_read; do { while ((num_read = posix::Read(fd, buffer, 255)) > 0) { buffer[num_read] = '\0'; error << buffer; } } while (num_read == -1 && errno == EINTR); if (num_read == 0) { GTEST_LOG_(FATAL) << error.GetString(); } else { const int last_error = errno; GTEST_LOG_(FATAL) << "Error while reading death test internal: " << GetLastErrnoDescription() << " [" << last_error << "]"; } } // Death test constructor. Increments the running death test count // for the current test. DeathTest::DeathTest() { TestInfo* const info = GetUnitTestImpl()->current_test_info(); if (info == NULL) { DeathTestAbort("Cannot run a death test outside of a TEST or " "TEST_F construct"); } } // Creates and returns a death test by dispatching to the current // death test factory. bool DeathTest::Create(const char* statement, const RE* regex, const char* file, int line, DeathTest** test) { return GetUnitTestImpl()->death_test_factory()->Create( statement, regex, file, line, test); } const char* DeathTest::LastMessage() { return last_death_test_message_.c_str(); } void DeathTest::set_last_death_test_message(const std::string& message) { last_death_test_message_ = message; } std::string DeathTest::last_death_test_message_; // Provides cross platform implementation for some death functionality. class DeathTestImpl : public DeathTest { protected: DeathTestImpl(const char* a_statement, const RE* a_regex) : statement_(a_statement), regex_(a_regex), spawned_(false), status_(-1), outcome_(IN_PROGRESS), read_fd_(-1), write_fd_(-1) {} // read_fd_ is expected to be closed and cleared by a derived class. ~DeathTestImpl() { GTEST_DEATH_TEST_CHECK_(read_fd_ == -1); } void Abort(AbortReason reason); virtual bool Passed(bool status_ok); const char* statement() const { return statement_; } const RE* regex() const { return regex_; } bool spawned() const { return spawned_; } void set_spawned(bool is_spawned) { spawned_ = is_spawned; } int status() const { return status_; } void set_status(int a_status) { status_ = a_status; } DeathTestOutcome outcome() const { return outcome_; } void set_outcome(DeathTestOutcome an_outcome) { outcome_ = an_outcome; } int read_fd() const { return read_fd_; } void set_read_fd(int fd) { read_fd_ = fd; } int write_fd() const { return write_fd_; } void set_write_fd(int fd) { write_fd_ = fd; } // Called in the parent process only. Reads the result code of the death // test child process via a pipe, interprets it to set the outcome_ // member, and closes read_fd_. Outputs diagnostics and terminates in // case of unexpected codes. void ReadAndInterpretStatusByte(); private: // The textual content of the code this object is testing. This class // doesn't own this string and should not attempt to delete it. const char* const statement_; // The regular expression which test output must match. DeathTestImpl // doesn't own this object and should not attempt to delete it. const RE* const regex_; // True if the death test child process has been successfully spawned. bool spawned_; // The exit status of the child process. int status_; // How the death test concluded. DeathTestOutcome outcome_; // Descriptor to the read end of the pipe to the child process. It is // always -1 in the child process. The child keeps its write end of the // pipe in write_fd_. int read_fd_; // Descriptor to the child's write end of the pipe to the parent process. // It is always -1 in the parent process. The parent keeps its end of the // pipe in read_fd_. int write_fd_; }; // Called in the parent process only. Reads the result code of the death // test child process via a pipe, interprets it to set the outcome_ // member, and closes read_fd_. Outputs diagnostics and terminates in // case of unexpected codes. void DeathTestImpl::ReadAndInterpretStatusByte() { char flag; int bytes_read; // The read() here blocks until data is available (signifying the // failure of the death test) or until the pipe is closed (signifying // its success), so it's okay to call this in the parent before // the child process has exited. do { bytes_read = posix::Read(read_fd(), &flag, 1); } while (bytes_read == -1 && errno == EINTR); if (bytes_read == 0) { set_outcome(DIED); } else if (bytes_read == 1) { switch (flag) { case kDeathTestReturned: set_outcome(RETURNED); break; case kDeathTestThrew: set_outcome(THREW); break; case kDeathTestLived: set_outcome(LIVED); break; case kDeathTestInternalError: FailFromInternalError(read_fd()); // Does not return. break; default: GTEST_LOG_(FATAL) << "Death test child process reported " << "unexpected status byte (" << static_cast(flag) << ")"; } } else { GTEST_LOG_(FATAL) << "Read from death test child process failed: " << GetLastErrnoDescription(); } GTEST_DEATH_TEST_CHECK_SYSCALL_(posix::Close(read_fd())); set_read_fd(-1); } // Signals that the death test code which should have exited, didn't. // Should be called only in a death test child process. // Writes a status byte to the child's status file descriptor, then // calls _exit(1). void DeathTestImpl::Abort(AbortReason reason) { // The parent process considers the death test to be a failure if // it finds any data in our pipe. So, here we write a single flag byte // to the pipe, then exit. const char status_ch = reason == TEST_DID_NOT_DIE ? kDeathTestLived : reason == TEST_THREW_EXCEPTION ? kDeathTestThrew : kDeathTestReturned; GTEST_DEATH_TEST_CHECK_SYSCALL_(posix::Write(write_fd(), &status_ch, 1)); // We are leaking the descriptor here because on some platforms (i.e., // when built as Windows DLL), destructors of global objects will still // run after calling _exit(). On such systems, write_fd_ will be // indirectly closed from the destructor of UnitTestImpl, causing double // close if it is also closed here. On debug configurations, double close // may assert. As there are no in-process buffers to flush here, we are // relying on the OS to close the descriptor after the process terminates // when the destructors are not run. _exit(1); // Exits w/o any normal exit hooks (we were supposed to crash) } // Returns an indented copy of stderr output for a death test. // This makes distinguishing death test output lines from regular log lines // much easier. static ::std::string FormatDeathTestOutput(const ::std::string& output) { ::std::string ret; for (size_t at = 0; ; ) { const size_t line_end = output.find('\n', at); ret += "[ DEATH ] "; if (line_end == ::std::string::npos) { ret += output.substr(at); break; } ret += output.substr(at, line_end + 1 - at); at = line_end + 1; } return ret; } // Assesses the success or failure of a death test, using both private // members which have previously been set, and one argument: // // Private data members: // outcome: An enumeration describing how the death test // concluded: DIED, LIVED, THREW, or RETURNED. The death test // fails in the latter three cases. // status: The exit status of the child process. On *nix, it is in the // in the format specified by wait(2). On Windows, this is the // value supplied to the ExitProcess() API or a numeric code // of the exception that terminated the program. // regex: A regular expression object to be applied to // the test's captured standard error output; the death test // fails if it does not match. // // Argument: // status_ok: true if exit_status is acceptable in the context of // this particular death test, which fails if it is false // // Returns true iff all of the above conditions are met. Otherwise, the // first failing condition, in the order given above, is the one that is // reported. Also sets the last death test message string. bool DeathTestImpl::Passed(bool status_ok) { if (!spawned()) return false; const std::string error_message = GetCapturedStderr(); bool success = false; Message buffer; buffer << "Death test: " << statement() << "\n"; switch (outcome()) { case LIVED: buffer << " Result: failed to die.\n" << " Error msg:\n" << FormatDeathTestOutput(error_message); break; case THREW: buffer << " Result: threw an exception.\n" << " Error msg:\n" << FormatDeathTestOutput(error_message); break; case RETURNED: buffer << " Result: illegal return in test statement.\n" << " Error msg:\n" << FormatDeathTestOutput(error_message); break; case DIED: if (status_ok) { const bool matched = RE::PartialMatch(error_message.c_str(), *regex()); if (matched) { success = true; } else { buffer << " Result: died but not with expected error.\n" << " Expected: " << regex()->pattern() << "\n" << "Actual msg:\n" << FormatDeathTestOutput(error_message); } } else { buffer << " Result: died but not with expected exit code:\n" << " " << ExitSummary(status()) << "\n" << "Actual msg:\n" << FormatDeathTestOutput(error_message); } break; case IN_PROGRESS: default: GTEST_LOG_(FATAL) << "DeathTest::Passed somehow called before conclusion of test"; } DeathTest::set_last_death_test_message(buffer.GetString()); return success; } # if GTEST_OS_WINDOWS // WindowsDeathTest implements death tests on Windows. Due to the // specifics of starting new processes on Windows, death tests there are // always threadsafe, and Google Test considers the // --gtest_death_test_style=fast setting to be equivalent to // --gtest_death_test_style=threadsafe there. // // A few implementation notes: Like the Linux version, the Windows // implementation uses pipes for child-to-parent communication. But due to // the specifics of pipes on Windows, some extra steps are required: // // 1. The parent creates a communication pipe and stores handles to both // ends of it. // 2. The parent starts the child and provides it with the information // necessary to acquire the handle to the write end of the pipe. // 3. The child acquires the write end of the pipe and signals the parent // using a Windows event. // 4. Now the parent can release the write end of the pipe on its side. If // this is done before step 3, the object's reference count goes down to // 0 and it is destroyed, preventing the child from acquiring it. The // parent now has to release it, or read operations on the read end of // the pipe will not return when the child terminates. // 5. The parent reads child's output through the pipe (outcome code and // any possible error messages) from the pipe, and its stderr and then // determines whether to fail the test. // // Note: to distinguish Win32 API calls from the local method and function // calls, the former are explicitly resolved in the global namespace. // class WindowsDeathTest : public DeathTestImpl { public: WindowsDeathTest(const char* a_statement, const RE* a_regex, const char* file, int line) : DeathTestImpl(a_statement, a_regex), file_(file), line_(line) {} // All of these virtual functions are inherited from DeathTest. virtual int Wait(); virtual TestRole AssumeRole(); private: // The name of the file in which the death test is located. const char* const file_; // The line number on which the death test is located. const int line_; // Handle to the write end of the pipe to the child process. AutoHandle write_handle_; // Child process handle. AutoHandle child_handle_; // Event the child process uses to signal the parent that it has // acquired the handle to the write end of the pipe. After seeing this // event the parent can release its own handles to make sure its // ReadFile() calls return when the child terminates. AutoHandle event_handle_; }; // Waits for the child in a death test to exit, returning its exit // status, or 0 if no child process exists. As a side effect, sets the // outcome data member. int WindowsDeathTest::Wait() { if (!spawned()) return 0; // Wait until the child either signals that it has acquired the write end // of the pipe or it dies. const HANDLE wait_handles[2] = { child_handle_.Get(), event_handle_.Get() }; switch (::WaitForMultipleObjects(2, wait_handles, FALSE, // Waits for any of the handles. INFINITE)) { case WAIT_OBJECT_0: case WAIT_OBJECT_0 + 1: break; default: GTEST_DEATH_TEST_CHECK_(false); // Should not get here. } // The child has acquired the write end of the pipe or exited. // We release the handle on our side and continue. write_handle_.Reset(); event_handle_.Reset(); ReadAndInterpretStatusByte(); // Waits for the child process to exit if it haven't already. This // returns immediately if the child has already exited, regardless of // whether previous calls to WaitForMultipleObjects synchronized on this // handle or not. GTEST_DEATH_TEST_CHECK_( WAIT_OBJECT_0 == ::WaitForSingleObject(child_handle_.Get(), INFINITE)); DWORD status_code; GTEST_DEATH_TEST_CHECK_( ::GetExitCodeProcess(child_handle_.Get(), &status_code) != FALSE); child_handle_.Reset(); set_status(static_cast(status_code)); return status(); } // The AssumeRole process for a Windows death test. It creates a child // process with the same executable as the current process to run the // death test. The child process is given the --gtest_filter and // --gtest_internal_run_death_test flags such that it knows to run the // current death test only. DeathTest::TestRole WindowsDeathTest::AssumeRole() { const UnitTestImpl* const impl = GetUnitTestImpl(); const InternalRunDeathTestFlag* const flag = impl->internal_run_death_test_flag(); const TestInfo* const info = impl->current_test_info(); const int death_test_index = info->result()->death_test_count(); if (flag != NULL) { // ParseInternalRunDeathTestFlag() has performed all the necessary // processing. set_write_fd(flag->write_fd()); return EXECUTE_TEST; } // WindowsDeathTest uses an anonymous pipe to communicate results of // a death test. SECURITY_ATTRIBUTES handles_are_inheritable = { sizeof(SECURITY_ATTRIBUTES), NULL, TRUE }; HANDLE read_handle, write_handle; GTEST_DEATH_TEST_CHECK_( ::CreatePipe(&read_handle, &write_handle, &handles_are_inheritable, 0) // Default buffer size. != FALSE); set_read_fd(::_open_osfhandle(reinterpret_cast(read_handle), O_RDONLY)); write_handle_.Reset(write_handle); event_handle_.Reset(::CreateEvent( &handles_are_inheritable, TRUE, // The event will automatically reset to non-signaled state. FALSE, // The initial state is non-signalled. NULL)); // The even is unnamed. GTEST_DEATH_TEST_CHECK_(event_handle_.Get() != NULL); const std::string filter_flag = std::string("--") + GTEST_FLAG_PREFIX_ + kFilterFlag + "=" + info->test_case_name() + "." + info->name(); const std::string internal_flag = std::string("--") + GTEST_FLAG_PREFIX_ + kInternalRunDeathTestFlag + "=" + file_ + "|" + StreamableToString(line_) + "|" + StreamableToString(death_test_index) + "|" + StreamableToString(static_cast(::GetCurrentProcessId())) + // size_t has the same width as pointers on both 32-bit and 64-bit // Windows platforms. // See http://msdn.microsoft.com/en-us/library/tcxf1dw6.aspx. "|" + StreamableToString(reinterpret_cast(write_handle)) + "|" + StreamableToString(reinterpret_cast(event_handle_.Get())); char executable_path[_MAX_PATH + 1]; // NOLINT GTEST_DEATH_TEST_CHECK_( _MAX_PATH + 1 != ::GetModuleFileNameA(NULL, executable_path, _MAX_PATH)); std::string command_line = std::string(::GetCommandLineA()) + " " + filter_flag + " \"" + internal_flag + "\""; DeathTest::set_last_death_test_message(""); CaptureStderr(); // Flush the log buffers since the log streams are shared with the child. FlushInfoLog(); // The child process will share the standard handles with the parent. STARTUPINFOA startup_info; memset(&startup_info, 0, sizeof(STARTUPINFO)); startup_info.dwFlags = STARTF_USESTDHANDLES; startup_info.hStdInput = ::GetStdHandle(STD_INPUT_HANDLE); startup_info.hStdOutput = ::GetStdHandle(STD_OUTPUT_HANDLE); startup_info.hStdError = ::GetStdHandle(STD_ERROR_HANDLE); PROCESS_INFORMATION process_info; GTEST_DEATH_TEST_CHECK_(::CreateProcessA( executable_path, const_cast(command_line.c_str()), NULL, // Retuned process handle is not inheritable. NULL, // Retuned thread handle is not inheritable. TRUE, // Child inherits all inheritable handles (for write_handle_). 0x0, // Default creation flags. NULL, // Inherit the parent's environment. UnitTest::GetInstance()->original_working_dir(), &startup_info, &process_info) != FALSE); child_handle_.Reset(process_info.hProcess); ::CloseHandle(process_info.hThread); set_spawned(true); return OVERSEE_TEST; } # else // We are not on Windows. // ForkingDeathTest provides implementations for most of the abstract // methods of the DeathTest interface. Only the AssumeRole method is // left undefined. class ForkingDeathTest : public DeathTestImpl { public: ForkingDeathTest(const char* statement, const RE* regex); // All of these virtual functions are inherited from DeathTest. virtual int Wait(); protected: void set_child_pid(pid_t child_pid) { child_pid_ = child_pid; } private: // PID of child process during death test; 0 in the child process itself. pid_t child_pid_; }; // Constructs a ForkingDeathTest. ForkingDeathTest::ForkingDeathTest(const char* a_statement, const RE* a_regex) : DeathTestImpl(a_statement, a_regex), child_pid_(-1) {} // Waits for the child in a death test to exit, returning its exit // status, or 0 if no child process exists. As a side effect, sets the // outcome data member. int ForkingDeathTest::Wait() { if (!spawned()) return 0; ReadAndInterpretStatusByte(); int status_value; GTEST_DEATH_TEST_CHECK_SYSCALL_(waitpid(child_pid_, &status_value, 0)); set_status(status_value); return status_value; } // A concrete death test class that forks, then immediately runs the test // in the child process. class NoExecDeathTest : public ForkingDeathTest { public: NoExecDeathTest(const char* a_statement, const RE* a_regex) : ForkingDeathTest(a_statement, a_regex) { } virtual TestRole AssumeRole(); }; // The AssumeRole process for a fork-and-run death test. It implements a // straightforward fork, with a simple pipe to transmit the status byte. DeathTest::TestRole NoExecDeathTest::AssumeRole() { const size_t thread_count = GetThreadCount(); if (thread_count != 1) { GTEST_LOG_(WARNING) << DeathTestThreadWarning(thread_count); } int pipe_fd[2]; GTEST_DEATH_TEST_CHECK_(pipe(pipe_fd) != -1); DeathTest::set_last_death_test_message(""); CaptureStderr(); // When we fork the process below, the log file buffers are copied, but the // file descriptors are shared. We flush all log files here so that closing // the file descriptors in the child process doesn't throw off the // synchronization between descriptors and buffers in the parent process. // This is as close to the fork as possible to avoid a race condition in case // there are multiple threads running before the death test, and another // thread writes to the log file. FlushInfoLog(); const pid_t child_pid = fork(); GTEST_DEATH_TEST_CHECK_(child_pid != -1); set_child_pid(child_pid); if (child_pid == 0) { GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[0])); set_write_fd(pipe_fd[1]); // Redirects all logging to stderr in the child process to prevent // concurrent writes to the log files. We capture stderr in the parent // process and append the child process' output to a log. LogToStderr(); // Event forwarding to the listeners of event listener API mush be shut // down in death test subprocesses. GetUnitTestImpl()->listeners()->SuppressEventForwarding(); g_in_fast_death_test_child = true; return EXECUTE_TEST; } else { GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[1])); set_read_fd(pipe_fd[0]); set_spawned(true); return OVERSEE_TEST; } } // A concrete death test class that forks and re-executes the main // program from the beginning, with command-line flags set that cause // only this specific death test to be run. class ExecDeathTest : public ForkingDeathTest { public: ExecDeathTest(const char* a_statement, const RE* a_regex, const char* file, int line) : ForkingDeathTest(a_statement, a_regex), file_(file), line_(line) { } virtual TestRole AssumeRole(); private: static ::std::vector GetArgvsForDeathTestChildProcess() { ::std::vector args = GetInjectableArgvs(); return args; } // The name of the file in which the death test is located. const char* const file_; // The line number on which the death test is located. const int line_; }; // Utility class for accumulating command-line arguments. class Arguments { public: Arguments() { args_.push_back(NULL); } ~Arguments() { for (std::vector::iterator i = args_.begin(); i != args_.end(); ++i) { free(*i); } } void AddArgument(const char* argument) { args_.insert(args_.end() - 1, posix::StrDup(argument)); } template void AddArguments(const ::std::vector& arguments) { for (typename ::std::vector::const_iterator i = arguments.begin(); i != arguments.end(); ++i) { args_.insert(args_.end() - 1, posix::StrDup(i->c_str())); } } char* const* Argv() { return &args_[0]; } private: std::vector args_; }; // A struct that encompasses the arguments to the child process of a // threadsafe-style death test process. struct ExecDeathTestArgs { char* const* argv; // Command-line arguments for the child's call to exec int close_fd; // File descriptor to close; the read end of a pipe }; # if GTEST_OS_MAC inline char** GetEnviron() { // When Google Test is built as a framework on MacOS X, the environ variable // is unavailable. Apple's documentation (man environ) recommends using // _NSGetEnviron() instead. return *_NSGetEnviron(); } # else // Some POSIX platforms expect you to declare environ. extern "C" makes // it reside in the global namespace. extern "C" char** environ; inline char** GetEnviron() { return environ; } # endif // GTEST_OS_MAC # if !GTEST_OS_QNX // The main function for a threadsafe-style death test child process. // This function is called in a clone()-ed process and thus must avoid // any potentially unsafe operations like malloc or libc functions. static int ExecDeathTestChildMain(void* child_arg) { ExecDeathTestArgs* const args = static_cast(child_arg); GTEST_DEATH_TEST_CHECK_SYSCALL_(close(args->close_fd)); // We need to execute the test program in the same environment where // it was originally invoked. Therefore we change to the original // working directory first. const char* const original_dir = UnitTest::GetInstance()->original_working_dir(); // We can safely call chdir() as it's a direct system call. if (chdir(original_dir) != 0) { DeathTestAbort(std::string("chdir(\"") + original_dir + "\") failed: " + GetLastErrnoDescription()); return EXIT_FAILURE; } // We can safely call execve() as it's a direct system call. We // cannot use execvp() as it's a libc function and thus potentially // unsafe. Since execve() doesn't search the PATH, the user must // invoke the test program via a valid path that contains at least // one path separator. execve(args->argv[0], args->argv, GetEnviron()); DeathTestAbort(std::string("execve(") + args->argv[0] + ", ...) in " + original_dir + " failed: " + GetLastErrnoDescription()); return EXIT_FAILURE; } # endif // !GTEST_OS_QNX // Two utility routines that together determine the direction the stack // grows. // This could be accomplished more elegantly by a single recursive // function, but we want to guard against the unlikely possibility of // a smart compiler optimizing the recursion away. // // GTEST_NO_INLINE_ is required to prevent GCC 4.6 from inlining // StackLowerThanAddress into StackGrowsDown, which then doesn't give // correct answer. void StackLowerThanAddress(const void* ptr, bool* result) GTEST_NO_INLINE_; void StackLowerThanAddress(const void* ptr, bool* result) { int dummy; *result = (&dummy < ptr); } bool StackGrowsDown() { int dummy; bool result; StackLowerThanAddress(&dummy, &result); return result; } // Spawns a child process with the same executable as the current process in // a thread-safe manner and instructs it to run the death test. The // implementation uses fork(2) + exec. On systems where clone(2) is // available, it is used instead, being slightly more thread-safe. On QNX, // fork supports only single-threaded environments, so this function uses // spawn(2) there instead. The function dies with an error message if // anything goes wrong. static pid_t ExecDeathTestSpawnChild(char* const* argv, int close_fd) { ExecDeathTestArgs args = { argv, close_fd }; pid_t child_pid = -1; # if GTEST_OS_QNX // Obtains the current directory and sets it to be closed in the child // process. const int cwd_fd = open(".", O_RDONLY); GTEST_DEATH_TEST_CHECK_(cwd_fd != -1); GTEST_DEATH_TEST_CHECK_SYSCALL_(fcntl(cwd_fd, F_SETFD, FD_CLOEXEC)); // We need to execute the test program in the same environment where // it was originally invoked. Therefore we change to the original // working directory first. const char* const original_dir = UnitTest::GetInstance()->original_working_dir(); // We can safely call chdir() as it's a direct system call. if (chdir(original_dir) != 0) { DeathTestAbort(std::string("chdir(\"") + original_dir + "\") failed: " + GetLastErrnoDescription()); return EXIT_FAILURE; } int fd_flags; // Set close_fd to be closed after spawn. GTEST_DEATH_TEST_CHECK_SYSCALL_(fd_flags = fcntl(close_fd, F_GETFD)); GTEST_DEATH_TEST_CHECK_SYSCALL_(fcntl(close_fd, F_SETFD, fd_flags | FD_CLOEXEC)); struct inheritance inherit = {0}; // spawn is a system call. child_pid = spawn(args.argv[0], 0, NULL, &inherit, args.argv, GetEnviron()); // Restores the current working directory. GTEST_DEATH_TEST_CHECK_(fchdir(cwd_fd) != -1); GTEST_DEATH_TEST_CHECK_SYSCALL_(close(cwd_fd)); # else // GTEST_OS_QNX # if GTEST_OS_LINUX // When a SIGPROF signal is received while fork() or clone() are executing, // the process may hang. To avoid this, we ignore SIGPROF here and re-enable // it after the call to fork()/clone() is complete. struct sigaction saved_sigprof_action; struct sigaction ignore_sigprof_action; memset(&ignore_sigprof_action, 0, sizeof(ignore_sigprof_action)); sigemptyset(&ignore_sigprof_action.sa_mask); ignore_sigprof_action.sa_handler = SIG_IGN; GTEST_DEATH_TEST_CHECK_SYSCALL_(sigaction( SIGPROF, &ignore_sigprof_action, &saved_sigprof_action)); # endif // GTEST_OS_LINUX # if GTEST_HAS_CLONE const bool use_fork = GTEST_FLAG(death_test_use_fork); if (!use_fork) { static const bool stack_grows_down = StackGrowsDown(); const size_t stack_size = getpagesize(); // MMAP_ANONYMOUS is not defined on Mac, so we use MAP_ANON instead. void* const stack = mmap(NULL, stack_size, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0); GTEST_DEATH_TEST_CHECK_(stack != MAP_FAILED); // Maximum stack alignment in bytes: For a downward-growing stack, this // amount is subtracted from size of the stack space to get an address // that is within the stack space and is aligned on all systems we care // about. As far as I know there is no ABI with stack alignment greater // than 64. We assume stack and stack_size already have alignment of // kMaxStackAlignment. const size_t kMaxStackAlignment = 64; void* const stack_top = static_cast(stack) + (stack_grows_down ? stack_size - kMaxStackAlignment : 0); GTEST_DEATH_TEST_CHECK_(stack_size > kMaxStackAlignment && reinterpret_cast(stack_top) % kMaxStackAlignment == 0); child_pid = clone(&ExecDeathTestChildMain, stack_top, SIGCHLD, &args); GTEST_DEATH_TEST_CHECK_(munmap(stack, stack_size) != -1); } # else const bool use_fork = true; # endif // GTEST_HAS_CLONE if (use_fork && (child_pid = fork()) == 0) { ExecDeathTestChildMain(&args); _exit(0); } # endif // GTEST_OS_QNX # if GTEST_OS_LINUX GTEST_DEATH_TEST_CHECK_SYSCALL_( sigaction(SIGPROF, &saved_sigprof_action, NULL)); # endif // GTEST_OS_LINUX GTEST_DEATH_TEST_CHECK_(child_pid != -1); return child_pid; } // The AssumeRole process for a fork-and-exec death test. It re-executes the // main program from the beginning, setting the --gtest_filter // and --gtest_internal_run_death_test flags to cause only the current // death test to be re-run. DeathTest::TestRole ExecDeathTest::AssumeRole() { const UnitTestImpl* const impl = GetUnitTestImpl(); const InternalRunDeathTestFlag* const flag = impl->internal_run_death_test_flag(); const TestInfo* const info = impl->current_test_info(); const int death_test_index = info->result()->death_test_count(); if (flag != NULL) { set_write_fd(flag->write_fd()); return EXECUTE_TEST; } int pipe_fd[2]; GTEST_DEATH_TEST_CHECK_(pipe(pipe_fd) != -1); // Clear the close-on-exec flag on the write end of the pipe, lest // it be closed when the child process does an exec: GTEST_DEATH_TEST_CHECK_(fcntl(pipe_fd[1], F_SETFD, 0) != -1); const std::string filter_flag = std::string("--") + GTEST_FLAG_PREFIX_ + kFilterFlag + "=" + info->test_case_name() + "." + info->name(); const std::string internal_flag = std::string("--") + GTEST_FLAG_PREFIX_ + kInternalRunDeathTestFlag + "=" + file_ + "|" + StreamableToString(line_) + "|" + StreamableToString(death_test_index) + "|" + StreamableToString(pipe_fd[1]); Arguments args; args.AddArguments(GetArgvsForDeathTestChildProcess()); args.AddArgument(filter_flag.c_str()); args.AddArgument(internal_flag.c_str()); DeathTest::set_last_death_test_message(""); CaptureStderr(); // See the comment in NoExecDeathTest::AssumeRole for why the next line // is necessary. FlushInfoLog(); const pid_t child_pid = ExecDeathTestSpawnChild(args.Argv(), pipe_fd[0]); GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[1])); set_child_pid(child_pid); set_read_fd(pipe_fd[0]); set_spawned(true); return OVERSEE_TEST; } # endif // !GTEST_OS_WINDOWS // Creates a concrete DeathTest-derived class that depends on the // --gtest_death_test_style flag, and sets the pointer pointed to // by the "test" argument to its address. If the test should be // skipped, sets that pointer to NULL. Returns true, unless the // flag is set to an invalid value. bool DefaultDeathTestFactory::Create(const char* statement, const RE* regex, const char* file, int line, DeathTest** test) { UnitTestImpl* const impl = GetUnitTestImpl(); const InternalRunDeathTestFlag* const flag = impl->internal_run_death_test_flag(); const int death_test_index = impl->current_test_info() ->increment_death_test_count(); if (flag != NULL) { if (death_test_index > flag->index()) { DeathTest::set_last_death_test_message( "Death test count (" + StreamableToString(death_test_index) + ") somehow exceeded expected maximum (" + StreamableToString(flag->index()) + ")"); return false; } if (!(flag->file() == file && flag->line() == line && flag->index() == death_test_index)) { *test = NULL; return true; } } # if GTEST_OS_WINDOWS if (GTEST_FLAG(death_test_style) == "threadsafe" || GTEST_FLAG(death_test_style) == "fast") { *test = new WindowsDeathTest(statement, regex, file, line); } # else if (GTEST_FLAG(death_test_style) == "threadsafe") { *test = new ExecDeathTest(statement, regex, file, line); } else if (GTEST_FLAG(death_test_style) == "fast") { *test = new NoExecDeathTest(statement, regex); } # endif // GTEST_OS_WINDOWS else { // NOLINT - this is more readable than unbalanced brackets inside #if. DeathTest::set_last_death_test_message( "Unknown death test style \"" + GTEST_FLAG(death_test_style) + "\" encountered"); return false; } return true; } // Splits a given string on a given delimiter, populating a given // vector with the fields. GTEST_HAS_DEATH_TEST implies that we have // ::std::string, so we can use it here. static void SplitString(const ::std::string& str, char delimiter, ::std::vector< ::std::string>* dest) { ::std::vector< ::std::string> parsed; ::std::string::size_type pos = 0; while (::testing::internal::AlwaysTrue()) { const ::std::string::size_type colon = str.find(delimiter, pos); if (colon == ::std::string::npos) { parsed.push_back(str.substr(pos)); break; } else { parsed.push_back(str.substr(pos, colon - pos)); pos = colon + 1; } } dest->swap(parsed); } # if GTEST_OS_WINDOWS // Recreates the pipe and event handles from the provided parameters, // signals the event, and returns a file descriptor wrapped around the pipe // handle. This function is called in the child process only. int GetStatusFileDescriptor(unsigned int parent_process_id, size_t write_handle_as_size_t, size_t event_handle_as_size_t) { AutoHandle parent_process_handle(::OpenProcess(PROCESS_DUP_HANDLE, FALSE, // Non-inheritable. parent_process_id)); if (parent_process_handle.Get() == INVALID_HANDLE_VALUE) { DeathTestAbort("Unable to open parent process " + StreamableToString(parent_process_id)); } // TODO(vladl@google.com): Replace the following check with a // compile-time assertion when available. GTEST_CHECK_(sizeof(HANDLE) <= sizeof(size_t)); const HANDLE write_handle = reinterpret_cast(write_handle_as_size_t); HANDLE dup_write_handle; // The newly initialized handle is accessible only in in the parent // process. To obtain one accessible within the child, we need to use // DuplicateHandle. if (!::DuplicateHandle(parent_process_handle.Get(), write_handle, ::GetCurrentProcess(), &dup_write_handle, 0x0, // Requested privileges ignored since // DUPLICATE_SAME_ACCESS is used. FALSE, // Request non-inheritable handler. DUPLICATE_SAME_ACCESS)) { DeathTestAbort("Unable to duplicate the pipe handle " + StreamableToString(write_handle_as_size_t) + " from the parent process " + StreamableToString(parent_process_id)); } const HANDLE event_handle = reinterpret_cast(event_handle_as_size_t); HANDLE dup_event_handle; if (!::DuplicateHandle(parent_process_handle.Get(), event_handle, ::GetCurrentProcess(), &dup_event_handle, 0x0, FALSE, DUPLICATE_SAME_ACCESS)) { DeathTestAbort("Unable to duplicate the event handle " + StreamableToString(event_handle_as_size_t) + " from the parent process " + StreamableToString(parent_process_id)); } const int write_fd = ::_open_osfhandle(reinterpret_cast(dup_write_handle), O_APPEND); if (write_fd == -1) { DeathTestAbort("Unable to convert pipe handle " + StreamableToString(write_handle_as_size_t) + " to a file descriptor"); } // Signals the parent that the write end of the pipe has been acquired // so the parent can release its own write end. ::SetEvent(dup_event_handle); return write_fd; } # endif // GTEST_OS_WINDOWS // Returns a newly created InternalRunDeathTestFlag object with fields // initialized from the GTEST_FLAG(internal_run_death_test) flag if // the flag is specified; otherwise returns NULL. InternalRunDeathTestFlag* ParseInternalRunDeathTestFlag() { if (GTEST_FLAG(internal_run_death_test) == "") return NULL; // GTEST_HAS_DEATH_TEST implies that we have ::std::string, so we // can use it here. int line = -1; int index = -1; ::std::vector< ::std::string> fields; SplitString(GTEST_FLAG(internal_run_death_test).c_str(), '|', &fields); int write_fd = -1; # if GTEST_OS_WINDOWS unsigned int parent_process_id = 0; size_t write_handle_as_size_t = 0; size_t event_handle_as_size_t = 0; if (fields.size() != 6 || !ParseNaturalNumber(fields[1], &line) || !ParseNaturalNumber(fields[2], &index) || !ParseNaturalNumber(fields[3], &parent_process_id) || !ParseNaturalNumber(fields[4], &write_handle_as_size_t) || !ParseNaturalNumber(fields[5], &event_handle_as_size_t)) { DeathTestAbort("Bad --gtest_internal_run_death_test flag: " + GTEST_FLAG(internal_run_death_test)); } write_fd = GetStatusFileDescriptor(parent_process_id, write_handle_as_size_t, event_handle_as_size_t); # else if (fields.size() != 4 || !ParseNaturalNumber(fields[1], &line) || !ParseNaturalNumber(fields[2], &index) || !ParseNaturalNumber(fields[3], &write_fd)) { DeathTestAbort("Bad --gtest_internal_run_death_test flag: " + GTEST_FLAG(internal_run_death_test)); } # endif // GTEST_OS_WINDOWS return new InternalRunDeathTestFlag(fields[0], line, index, write_fd); } } // namespace internal #endif // GTEST_HAS_DEATH_TEST } // namespace testing // Copyright 2008, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Authors: keith.ray@gmail.com (Keith Ray) #include #if GTEST_OS_WINDOWS_MOBILE # include #elif GTEST_OS_WINDOWS # include # include #elif GTEST_OS_SYMBIAN // Symbian OpenC has PATH_MAX in sys/syslimits.h # include #else # include # include // Some Linux distributions define PATH_MAX here. #endif // GTEST_OS_WINDOWS_MOBILE #if GTEST_OS_WINDOWS # define GTEST_PATH_MAX_ _MAX_PATH #elif defined(PATH_MAX) # define GTEST_PATH_MAX_ PATH_MAX #elif defined(_XOPEN_PATH_MAX) # define GTEST_PATH_MAX_ _XOPEN_PATH_MAX #else # define GTEST_PATH_MAX_ _POSIX_PATH_MAX #endif // GTEST_OS_WINDOWS namespace testing { namespace internal { #if GTEST_OS_WINDOWS // On Windows, '\\' is the standard path separator, but many tools and the // Windows API also accept '/' as an alternate path separator. Unless otherwise // noted, a file path can contain either kind of path separators, or a mixture // of them. const char kPathSeparator = '\\'; const char kAlternatePathSeparator = '/'; const char kPathSeparatorString[] = "\\"; const char kAlternatePathSeparatorString[] = "/"; # if GTEST_OS_WINDOWS_MOBILE // Windows CE doesn't have a current directory. You should not use // the current directory in tests on Windows CE, but this at least // provides a reasonable fallback. const char kCurrentDirectoryString[] = "\\"; // Windows CE doesn't define INVALID_FILE_ATTRIBUTES const DWORD kInvalidFileAttributes = 0xffffffff; # else const char kCurrentDirectoryString[] = ".\\"; # endif // GTEST_OS_WINDOWS_MOBILE #else const char kPathSeparator = '/'; const char kPathSeparatorString[] = "/"; const char kCurrentDirectoryString[] = "./"; #endif // GTEST_OS_WINDOWS // Returns whether the given character is a valid path separator. static bool IsPathSeparator(char c) { #if GTEST_HAS_ALT_PATH_SEP_ return (c == kPathSeparator) || (c == kAlternatePathSeparator); #else return c == kPathSeparator; #endif } // Returns the current working directory, or "" if unsuccessful. FilePath FilePath::GetCurrentDir() { #if GTEST_OS_WINDOWS_MOBILE // Windows CE doesn't have a current directory, so we just return // something reasonable. return FilePath(kCurrentDirectoryString); #elif GTEST_OS_WINDOWS char cwd[GTEST_PATH_MAX_ + 1] = { '\0' }; return FilePath(_getcwd(cwd, sizeof(cwd)) == NULL ? "" : cwd); #else char cwd[GTEST_PATH_MAX_ + 1] = { '\0' }; return FilePath(getcwd(cwd, sizeof(cwd)) == NULL ? "" : cwd); #endif // GTEST_OS_WINDOWS_MOBILE } // Returns a copy of the FilePath with the case-insensitive extension removed. // Example: FilePath("dir/file.exe").RemoveExtension("EXE") returns // FilePath("dir/file"). If a case-insensitive extension is not // found, returns a copy of the original FilePath. FilePath FilePath::RemoveExtension(const char* extension) const { const std::string dot_extension = std::string(".") + extension; if (String::EndsWithCaseInsensitive(pathname_, dot_extension)) { return FilePath(pathname_.substr( 0, pathname_.length() - dot_extension.length())); } return *this; } // Returns a pointer to the last occurence of a valid path separator in // the FilePath. On Windows, for example, both '/' and '\' are valid path // separators. Returns NULL if no path separator was found. const char* FilePath::FindLastPathSeparator() const { const char* const last_sep = strrchr(c_str(), kPathSeparator); #if GTEST_HAS_ALT_PATH_SEP_ const char* const last_alt_sep = strrchr(c_str(), kAlternatePathSeparator); // Comparing two pointers of which only one is NULL is undefined. if (last_alt_sep != NULL && (last_sep == NULL || last_alt_sep > last_sep)) { return last_alt_sep; } #endif return last_sep; } // Returns a copy of the FilePath with the directory part removed. // Example: FilePath("path/to/file").RemoveDirectoryName() returns // FilePath("file"). If there is no directory part ("just_a_file"), it returns // the FilePath unmodified. If there is no file part ("just_a_dir/") it // returns an empty FilePath (""). // On Windows platform, '\' is the path separator, otherwise it is '/'. FilePath FilePath::RemoveDirectoryName() const { const char* const last_sep = FindLastPathSeparator(); return last_sep ? FilePath(last_sep + 1) : *this; } // RemoveFileName returns the directory path with the filename removed. // Example: FilePath("path/to/file").RemoveFileName() returns "path/to/". // If the FilePath is "a_file" or "/a_file", RemoveFileName returns // FilePath("./") or, on Windows, FilePath(".\\"). If the filepath does // not have a file, like "just/a/dir/", it returns the FilePath unmodified. // On Windows platform, '\' is the path separator, otherwise it is '/'. FilePath FilePath::RemoveFileName() const { const char* const last_sep = FindLastPathSeparator(); std::string dir; if (last_sep) { dir = std::string(c_str(), last_sep + 1 - c_str()); } else { dir = kCurrentDirectoryString; } return FilePath(dir); } // Helper functions for naming files in a directory for xml output. // Given directory = "dir", base_name = "test", number = 0, // extension = "xml", returns "dir/test.xml". If number is greater // than zero (e.g., 12), returns "dir/test_12.xml". // On Windows platform, uses \ as the separator rather than /. FilePath FilePath::MakeFileName(const FilePath& directory, const FilePath& base_name, int number, const char* extension) { std::string file; if (number == 0) { file = base_name.string() + "." + extension; } else { file = base_name.string() + "_" + StreamableToString(number) + "." + extension; } return ConcatPaths(directory, FilePath(file)); } // Given directory = "dir", relative_path = "test.xml", returns "dir/test.xml". // On Windows, uses \ as the separator rather than /. FilePath FilePath::ConcatPaths(const FilePath& directory, const FilePath& relative_path) { if (directory.IsEmpty()) return relative_path; const FilePath dir(directory.RemoveTrailingPathSeparator()); return FilePath(dir.string() + kPathSeparator + relative_path.string()); } // Returns true if pathname describes something findable in the file-system, // either a file, directory, or whatever. bool FilePath::FileOrDirectoryExists() const { #if GTEST_OS_WINDOWS_MOBILE LPCWSTR unicode = String::AnsiToUtf16(pathname_.c_str()); const DWORD attributes = GetFileAttributes(unicode); delete [] unicode; return attributes != kInvalidFileAttributes; #else posix::StatStruct file_stat; return posix::Stat(pathname_.c_str(), &file_stat) == 0; #endif // GTEST_OS_WINDOWS_MOBILE } // Returns true if pathname describes a directory in the file-system // that exists. bool FilePath::DirectoryExists() const { bool result = false; #if GTEST_OS_WINDOWS // Don't strip off trailing separator if path is a root directory on // Windows (like "C:\\"). const FilePath& path(IsRootDirectory() ? *this : RemoveTrailingPathSeparator()); #else const FilePath& path(*this); #endif #if GTEST_OS_WINDOWS_MOBILE LPCWSTR unicode = String::AnsiToUtf16(path.c_str()); const DWORD attributes = GetFileAttributes(unicode); delete [] unicode; if ((attributes != kInvalidFileAttributes) && (attributes & FILE_ATTRIBUTE_DIRECTORY)) { result = true; } #else posix::StatStruct file_stat; result = posix::Stat(path.c_str(), &file_stat) == 0 && posix::IsDir(file_stat); #endif // GTEST_OS_WINDOWS_MOBILE return result; } // Returns true if pathname describes a root directory. (Windows has one // root directory per disk drive.) bool FilePath::IsRootDirectory() const { #if GTEST_OS_WINDOWS // TODO(wan@google.com): on Windows a network share like // \\server\share can be a root directory, although it cannot be the // current directory. Handle this properly. return pathname_.length() == 3 && IsAbsolutePath(); #else return pathname_.length() == 1 && IsPathSeparator(pathname_.c_str()[0]); #endif } // Returns true if pathname describes an absolute path. bool FilePath::IsAbsolutePath() const { const char* const name = pathname_.c_str(); #if GTEST_OS_WINDOWS return pathname_.length() >= 3 && ((name[0] >= 'a' && name[0] <= 'z') || (name[0] >= 'A' && name[0] <= 'Z')) && name[1] == ':' && IsPathSeparator(name[2]); #else return IsPathSeparator(name[0]); #endif } // Returns a pathname for a file that does not currently exist. The pathname // will be directory/base_name.extension or // directory/base_name_.extension if directory/base_name.extension // already exists. The number will be incremented until a pathname is found // that does not already exist. // Examples: 'dir/foo_test.xml' or 'dir/foo_test_1.xml'. // There could be a race condition if two or more processes are calling this // function at the same time -- they could both pick the same filename. FilePath FilePath::GenerateUniqueFileName(const FilePath& directory, const FilePath& base_name, const char* extension) { FilePath full_pathname; int number = 0; do { full_pathname.Set(MakeFileName(directory, base_name, number++, extension)); } while (full_pathname.FileOrDirectoryExists()); return full_pathname; } // Returns true if FilePath ends with a path separator, which indicates that // it is intended to represent a directory. Returns false otherwise. // This does NOT check that a directory (or file) actually exists. bool FilePath::IsDirectory() const { return !pathname_.empty() && IsPathSeparator(pathname_.c_str()[pathname_.length() - 1]); } // Create directories so that path exists. Returns true if successful or if // the directories already exist; returns false if unable to create directories // for any reason. bool FilePath::CreateDirectoriesRecursively() const { if (!this->IsDirectory()) { return false; } if (pathname_.length() == 0 || this->DirectoryExists()) { return true; } const FilePath parent(this->RemoveTrailingPathSeparator().RemoveFileName()); return parent.CreateDirectoriesRecursively() && this->CreateFolder(); } // Create the directory so that path exists. Returns true if successful or // if the directory already exists; returns false if unable to create the // directory for any reason, including if the parent directory does not // exist. Not named "CreateDirectory" because that's a macro on Windows. bool FilePath::CreateFolder() const { #if GTEST_OS_WINDOWS_MOBILE FilePath removed_sep(this->RemoveTrailingPathSeparator()); LPCWSTR unicode = String::AnsiToUtf16(removed_sep.c_str()); int result = CreateDirectory(unicode, NULL) ? 0 : -1; delete [] unicode; #elif GTEST_OS_WINDOWS int result = _mkdir(pathname_.c_str()); #else int result = mkdir(pathname_.c_str(), 0777); #endif // GTEST_OS_WINDOWS_MOBILE if (result == -1) { return this->DirectoryExists(); // An error is OK if the directory exists. } return true; // No error. } // If input name has a trailing separator character, remove it and return the // name, otherwise return the name string unmodified. // On Windows platform, uses \ as the separator, other platforms use /. FilePath FilePath::RemoveTrailingPathSeparator() const { return IsDirectory() ? FilePath(pathname_.substr(0, pathname_.length() - 1)) : *this; } // Removes any redundant separators that might be in the pathname. // For example, "bar///foo" becomes "bar/foo". Does not eliminate other // redundancies that might be in a pathname involving "." or "..". // TODO(wan@google.com): handle Windows network shares (e.g. \\server\share). void FilePath::Normalize() { if (pathname_.c_str() == NULL) { pathname_ = ""; return; } const char* src = pathname_.c_str(); char* const dest = new char[pathname_.length() + 1]; char* dest_ptr = dest; memset(dest_ptr, 0, pathname_.length() + 1); while (*src != '\0') { *dest_ptr = *src; if (!IsPathSeparator(*src)) { src++; } else { #if GTEST_HAS_ALT_PATH_SEP_ if (*dest_ptr == kAlternatePathSeparator) { *dest_ptr = kPathSeparator; } #endif while (IsPathSeparator(*src)) src++; } dest_ptr++; } *dest_ptr = '\0'; pathname_ = dest; delete[] dest; } } // namespace internal } // namespace testing // Copyright 2008, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: wan@google.com (Zhanyong Wan) #include #include #include #include #if GTEST_OS_WINDOWS_MOBILE # include // For TerminateProcess() #elif GTEST_OS_WINDOWS # include # include #else # include #endif // GTEST_OS_WINDOWS_MOBILE #if GTEST_OS_MAC # include # include # include #endif // GTEST_OS_MAC #if GTEST_OS_QNX # include # include #endif // GTEST_OS_QNX // Indicates that this translation unit is part of Google Test's // implementation. It must come before gtest-internal-inl.h is // included, or there will be a compiler error. This trick is to // prevent a user from accidentally including gtest-internal-inl.h in // his code. #define GTEST_IMPLEMENTATION_ 1 #undef GTEST_IMPLEMENTATION_ namespace testing { namespace internal { #if defined(_MSC_VER) || defined(__BORLANDC__) // MSVC and C++Builder do not provide a definition of STDERR_FILENO. const int kStdOutFileno = 1; const int kStdErrFileno = 2; #else const int kStdOutFileno = STDOUT_FILENO; const int kStdErrFileno = STDERR_FILENO; #endif // _MSC_VER #if GTEST_OS_MAC // Returns the number of threads running in the process, or 0 to indicate that // we cannot detect it. size_t GetThreadCount() { const task_t task = mach_task_self(); mach_msg_type_number_t thread_count; thread_act_array_t thread_list; const kern_return_t status = task_threads(task, &thread_list, &thread_count); if (status == KERN_SUCCESS) { // task_threads allocates resources in thread_list and we need to free them // to avoid leaks. vm_deallocate(task, reinterpret_cast(thread_list), sizeof(thread_t) * thread_count); return static_cast(thread_count); } else { return 0; } } #elif GTEST_OS_QNX // Returns the number of threads running in the process, or 0 to indicate that // we cannot detect it. size_t GetThreadCount() { const int fd = open("/proc/self/as", O_RDONLY); if (fd < 0) { return 0; } procfs_info process_info; const int status = devctl(fd, DCMD_PROC_INFO, &process_info, sizeof(process_info), NULL); close(fd); if (status == EOK) { return static_cast(process_info.num_threads); } else { return 0; } } #else size_t GetThreadCount() { // There's no portable way to detect the number of threads, so we just // return 0 to indicate that we cannot detect it. return 0; } #endif // GTEST_OS_MAC #if GTEST_USES_POSIX_RE // Implements RE. Currently only needed for death tests. RE::~RE() { if (is_valid_) { // regfree'ing an invalid regex might crash because the content // of the regex is undefined. Since the regex's are essentially // the same, one cannot be valid (or invalid) without the other // being so too. regfree(&partial_regex_); regfree(&full_regex_); } free(const_cast(pattern_)); } // Returns true iff regular expression re matches the entire str. bool RE::FullMatch(const char* str, const RE& re) { if (!re.is_valid_) return false; regmatch_t match; return regexec(&re.full_regex_, str, 1, &match, 0) == 0; } // Returns true iff regular expression re matches a substring of str // (including str itself). bool RE::PartialMatch(const char* str, const RE& re) { if (!re.is_valid_) return false; regmatch_t match; return regexec(&re.partial_regex_, str, 1, &match, 0) == 0; } // Initializes an RE from its string representation. void RE::Init(const char* regex) { pattern_ = posix::StrDup(regex); // Reserves enough bytes to hold the regular expression used for a // full match. const size_t full_regex_len = strlen(regex) + 10; char* const full_pattern = new char[full_regex_len]; snprintf(full_pattern, full_regex_len, "^(%s)$", regex); is_valid_ = regcomp(&full_regex_, full_pattern, REG_EXTENDED) == 0; // We want to call regcomp(&partial_regex_, ...) even if the // previous expression returns false. Otherwise partial_regex_ may // not be properly initialized can may cause trouble when it's // freed. // // Some implementation of POSIX regex (e.g. on at least some // versions of Cygwin) doesn't accept the empty string as a valid // regex. We change it to an equivalent form "()" to be safe. if (is_valid_) { const char* const partial_regex = (*regex == '\0') ? "()" : regex; is_valid_ = regcomp(&partial_regex_, partial_regex, REG_EXTENDED) == 0; } EXPECT_TRUE(is_valid_) << "Regular expression \"" << regex << "\" is not a valid POSIX Extended regular expression."; delete[] full_pattern; } #elif GTEST_USES_SIMPLE_RE // Returns true iff ch appears anywhere in str (excluding the // terminating '\0' character). bool IsInSet(char ch, const char* str) { return ch != '\0' && strchr(str, ch) != NULL; } // Returns true iff ch belongs to the given classification. Unlike // similar functions in , these aren't affected by the // current locale. bool IsAsciiDigit(char ch) { return '0' <= ch && ch <= '9'; } bool IsAsciiPunct(char ch) { return IsInSet(ch, "^-!\"#$%&'()*+,./:;<=>?@[\\]_`{|}~"); } bool IsRepeat(char ch) { return IsInSet(ch, "?*+"); } bool IsAsciiWhiteSpace(char ch) { return IsInSet(ch, " \f\n\r\t\v"); } bool IsAsciiWordChar(char ch) { return ('a' <= ch && ch <= 'z') || ('A' <= ch && ch <= 'Z') || ('0' <= ch && ch <= '9') || ch == '_'; } // Returns true iff "\\c" is a supported escape sequence. bool IsValidEscape(char c) { return (IsAsciiPunct(c) || IsInSet(c, "dDfnrsStvwW")); } // Returns true iff the given atom (specified by escaped and pattern) // matches ch. The result is undefined if the atom is invalid. bool AtomMatchesChar(bool escaped, char pattern_char, char ch) { if (escaped) { // "\\p" where p is pattern_char. switch (pattern_char) { case 'd': return IsAsciiDigit(ch); case 'D': return !IsAsciiDigit(ch); case 'f': return ch == '\f'; case 'n': return ch == '\n'; case 'r': return ch == '\r'; case 's': return IsAsciiWhiteSpace(ch); case 'S': return !IsAsciiWhiteSpace(ch); case 't': return ch == '\t'; case 'v': return ch == '\v'; case 'w': return IsAsciiWordChar(ch); case 'W': return !IsAsciiWordChar(ch); } return IsAsciiPunct(pattern_char) && pattern_char == ch; } return (pattern_char == '.' && ch != '\n') || pattern_char == ch; } // Helper function used by ValidateRegex() to format error messages. std::string FormatRegexSyntaxError(const char* regex, int index) { return (Message() << "Syntax error at index " << index << " in simple regular expression \"" << regex << "\": ").GetString(); } // Generates non-fatal failures and returns false if regex is invalid; // otherwise returns true. bool ValidateRegex(const char* regex) { if (regex == NULL) { // TODO(wan@google.com): fix the source file location in the // assertion failures to match where the regex is used in user // code. ADD_FAILURE() << "NULL is not a valid simple regular expression."; return false; } bool is_valid = true; // True iff ?, *, or + can follow the previous atom. bool prev_repeatable = false; for (int i = 0; regex[i]; i++) { if (regex[i] == '\\') { // An escape sequence i++; if (regex[i] == '\0') { ADD_FAILURE() << FormatRegexSyntaxError(regex, i - 1) << "'\\' cannot appear at the end."; return false; } if (!IsValidEscape(regex[i])) { ADD_FAILURE() << FormatRegexSyntaxError(regex, i - 1) << "invalid escape sequence \"\\" << regex[i] << "\"."; is_valid = false; } prev_repeatable = true; } else { // Not an escape sequence. const char ch = regex[i]; if (ch == '^' && i > 0) { ADD_FAILURE() << FormatRegexSyntaxError(regex, i) << "'^' can only appear at the beginning."; is_valid = false; } else if (ch == '$' && regex[i + 1] != '\0') { ADD_FAILURE() << FormatRegexSyntaxError(regex, i) << "'$' can only appear at the end."; is_valid = false; } else if (IsInSet(ch, "()[]{}|")) { ADD_FAILURE() << FormatRegexSyntaxError(regex, i) << "'" << ch << "' is unsupported."; is_valid = false; } else if (IsRepeat(ch) && !prev_repeatable) { ADD_FAILURE() << FormatRegexSyntaxError(regex, i) << "'" << ch << "' can only follow a repeatable token."; is_valid = false; } prev_repeatable = !IsInSet(ch, "^$?*+"); } } return is_valid; } // Matches a repeated regex atom followed by a valid simple regular // expression. The regex atom is defined as c if escaped is false, // or \c otherwise. repeat is the repetition meta character (?, *, // or +). The behavior is undefined if str contains too many // characters to be indexable by size_t, in which case the test will // probably time out anyway. We are fine with this limitation as // std::string has it too. bool MatchRepetitionAndRegexAtHead( bool escaped, char c, char repeat, const char* regex, const char* str) { const size_t min_count = (repeat == '+') ? 1 : 0; const size_t max_count = (repeat == '?') ? 1 : static_cast(-1) - 1; // We cannot call numeric_limits::max() as it conflicts with the // max() macro on Windows. for (size_t i = 0; i <= max_count; ++i) { // We know that the atom matches each of the first i characters in str. if (i >= min_count && MatchRegexAtHead(regex, str + i)) { // We have enough matches at the head, and the tail matches too. // Since we only care about *whether* the pattern matches str // (as opposed to *how* it matches), there is no need to find a // greedy match. return true; } if (str[i] == '\0' || !AtomMatchesChar(escaped, c, str[i])) return false; } return false; } // Returns true iff regex matches a prefix of str. regex must be a // valid simple regular expression and not start with "^", or the // result is undefined. bool MatchRegexAtHead(const char* regex, const char* str) { if (*regex == '\0') // An empty regex matches a prefix of anything. return true; // "$" only matches the end of a string. Note that regex being // valid guarantees that there's nothing after "$" in it. if (*regex == '$') return *str == '\0'; // Is the first thing in regex an escape sequence? const bool escaped = *regex == '\\'; if (escaped) ++regex; if (IsRepeat(regex[1])) { // MatchRepetitionAndRegexAtHead() calls MatchRegexAtHead(), so // here's an indirect recursion. It terminates as the regex gets // shorter in each recursion. return MatchRepetitionAndRegexAtHead( escaped, regex[0], regex[1], regex + 2, str); } else { // regex isn't empty, isn't "$", and doesn't start with a // repetition. We match the first atom of regex with the first // character of str and recurse. return (*str != '\0') && AtomMatchesChar(escaped, *regex, *str) && MatchRegexAtHead(regex + 1, str + 1); } } // Returns true iff regex matches any substring of str. regex must be // a valid simple regular expression, or the result is undefined. // // The algorithm is recursive, but the recursion depth doesn't exceed // the regex length, so we won't need to worry about running out of // stack space normally. In rare cases the time complexity can be // exponential with respect to the regex length + the string length, // but usually it's must faster (often close to linear). bool MatchRegexAnywhere(const char* regex, const char* str) { if (regex == NULL || str == NULL) return false; if (*regex == '^') return MatchRegexAtHead(regex + 1, str); // A successful match can be anywhere in str. do { if (MatchRegexAtHead(regex, str)) return true; } while (*str++ != '\0'); return false; } // Implements the RE class. RE::~RE() { free(const_cast(pattern_)); free(const_cast(full_pattern_)); } // Returns true iff regular expression re matches the entire str. bool RE::FullMatch(const char* str, const RE& re) { return re.is_valid_ && MatchRegexAnywhere(re.full_pattern_, str); } // Returns true iff regular expression re matches a substring of str // (including str itself). bool RE::PartialMatch(const char* str, const RE& re) { return re.is_valid_ && MatchRegexAnywhere(re.pattern_, str); } // Initializes an RE from its string representation. void RE::Init(const char* regex) { pattern_ = full_pattern_ = NULL; if (regex != NULL) { pattern_ = posix::StrDup(regex); } is_valid_ = ValidateRegex(regex); if (!is_valid_) { // No need to calculate the full pattern when the regex is invalid. return; } const size_t len = strlen(regex); // Reserves enough bytes to hold the regular expression used for a // full match: we need space to prepend a '^', append a '$', and // terminate the string with '\0'. char* buffer = static_cast(malloc(len + 3)); full_pattern_ = buffer; if (*regex != '^') *buffer++ = '^'; // Makes sure full_pattern_ starts with '^'. // We don't use snprintf or strncpy, as they trigger a warning when // compiled with VC++ 8.0. memcpy(buffer, regex, len); buffer += len; if (len == 0 || regex[len - 1] != '$') *buffer++ = '$'; // Makes sure full_pattern_ ends with '$'. *buffer = '\0'; } #endif // GTEST_USES_POSIX_RE const char kUnknownFile[] = "unknown file"; // Formats a source file path and a line number as they would appear // in an error message from the compiler used to compile this code. GTEST_API_ ::std::string FormatFileLocation(const char* file, int line) { const std::string file_name(file == NULL ? kUnknownFile : file); if (line < 0) { return file_name + ":"; } #ifdef _MSC_VER return file_name + "(" + StreamableToString(line) + "):"; #else return file_name + ":" + StreamableToString(line) + ":"; #endif // _MSC_VER } // Formats a file location for compiler-independent XML output. // Although this function is not platform dependent, we put it next to // FormatFileLocation in order to contrast the two functions. // Note that FormatCompilerIndependentFileLocation() does NOT append colon // to the file location it produces, unlike FormatFileLocation(). GTEST_API_ ::std::string FormatCompilerIndependentFileLocation( const char* file, int line) { const std::string file_name(file == NULL ? kUnknownFile : file); if (line < 0) return file_name; else return file_name + ":" + StreamableToString(line); } GTestLog::GTestLog(GTestLogSeverity severity, const char* file, int line) : severity_(severity) { const char* const marker = severity == GTEST_INFO ? "[ INFO ]" : severity == GTEST_WARNING ? "[WARNING]" : severity == GTEST_ERROR ? "[ ERROR ]" : "[ FATAL ]"; GetStream() << ::std::endl << marker << " " << FormatFileLocation(file, line).c_str() << ": "; } // Flushes the buffers and, if severity is GTEST_FATAL, aborts the program. GTestLog::~GTestLog() { GetStream() << ::std::endl; if (severity_ == GTEST_FATAL) { fflush(stderr); posix::Abort(); } } // Disable Microsoft deprecation warnings for POSIX functions called from // this class (creat, dup, dup2, and close) #ifdef _MSC_VER # pragma warning(push) # pragma warning(disable: 4996) #endif // _MSC_VER #if GTEST_HAS_STREAM_REDIRECTION // Object that captures an output stream (stdout/stderr). class CapturedStream { public: // The ctor redirects the stream to a temporary file. explicit CapturedStream(int fd) : fd_(fd), uncaptured_fd_(dup(fd)) { # if GTEST_OS_WINDOWS char temp_dir_path[MAX_PATH + 1] = { '\0' }; // NOLINT char temp_file_path[MAX_PATH + 1] = { '\0' }; // NOLINT ::GetTempPathA(sizeof(temp_dir_path), temp_dir_path); const UINT success = ::GetTempFileNameA(temp_dir_path, "gtest_redir", 0, // Generate unique file name. temp_file_path); GTEST_CHECK_(success != 0) << "Unable to create a temporary file in " << temp_dir_path; const int captured_fd = creat(temp_file_path, _S_IREAD | _S_IWRITE); GTEST_CHECK_(captured_fd != -1) << "Unable to open temporary file " << temp_file_path; filename_ = temp_file_path; # else // There's no guarantee that a test has write access to the current // directory, so we create the temporary file in the /tmp directory // instead. We use /tmp on most systems, and /sdcard on Android. // That's because Android doesn't have /tmp. # if GTEST_OS_LINUX_ANDROID // Note: Android applications are expected to call the framework's // Context.getExternalStorageDirectory() method through JNI to get // the location of the world-writable SD Card directory. However, // this requires a Context handle, which cannot be retrieved // globally from native code. Doing so also precludes running the // code as part of a regular standalone executable, which doesn't // run in a Dalvik process (e.g. when running it through 'adb shell'). // // The location /sdcard is directly accessible from native code // and is the only location (unofficially) supported by the Android // team. It's generally a symlink to the real SD Card mount point // which can be /mnt/sdcard, /mnt/sdcard0, /system/media/sdcard, or // other OEM-customized locations. Never rely on these, and always // use /sdcard. char name_template[] = "/sdcard/gtest_captured_stream.XXXXXX"; # else char name_template[] = "/tmp/captured_stream.XXXXXX"; # endif // GTEST_OS_LINUX_ANDROID const int captured_fd = mkstemp(name_template); filename_ = name_template; # endif // GTEST_OS_WINDOWS fflush(NULL); dup2(captured_fd, fd_); close(captured_fd); } ~CapturedStream() { remove(filename_.c_str()); } std::string GetCapturedString() { if (uncaptured_fd_ != -1) { // Restores the original stream. fflush(NULL); dup2(uncaptured_fd_, fd_); close(uncaptured_fd_); uncaptured_fd_ = -1; } FILE* const file = posix::FOpen(filename_.c_str(), "r"); const std::string content = ReadEntireFile(file); posix::FClose(file); return content; } 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. ::std::string filename_; GTEST_DISALLOW_COPY_AND_ASSIGN_(CapturedStream); }; // Returns the size (in bytes) of a file. size_t CapturedStream::GetFileSize(FILE* file) { fseek(file, 0, SEEK_END); return static_cast(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 static CapturedStream* g_captured_stderr = NULL; static CapturedStream* g_captured_stdout = NULL; // Starts capturing an output stream (stdout/stderr). void CaptureStream(int fd, const char* stream_name, CapturedStream** stream) { if (*stream != NULL) { GTEST_LOG_(FATAL) << "Only one " << stream_name << " capturer can exist at a time."; } *stream = new CapturedStream(fd); } // Stops capturing the output stream and returns the captured string. std::string GetCapturedStream(CapturedStream** captured_stream) { const std::string content = (*captured_stream)->GetCapturedString(); delete *captured_stream; *captured_stream = NULL; return content; } // Starts capturing stdout. void CaptureStdout() { CaptureStream(kStdOutFileno, "stdout", &g_captured_stdout); } // Starts capturing stderr. void CaptureStderr() { CaptureStream(kStdErrFileno, "stderr", &g_captured_stderr); } // Stops capturing stdout and returns the captured string. std::string GetCapturedStdout() { return GetCapturedStream(&g_captured_stdout); } // Stops capturing stderr and returns the captured string. std::string GetCapturedStderr() { return GetCapturedStream(&g_captured_stderr); } #endif // GTEST_HAS_STREAM_REDIRECTION #if GTEST_HAS_DEATH_TEST // A copy of all command line arguments. Set by InitGoogleTest(). ::std::vector g_argvs; static const ::std::vector* g_injected_test_argvs = NULL; // Owned. void SetInjectableArgvs(const ::std::vector* argvs) { if (g_injected_test_argvs != argvs) delete g_injected_test_argvs; g_injected_test_argvs = argvs; } const ::std::vector& GetInjectableArgvs() { if (g_injected_test_argvs != NULL) { return *g_injected_test_argvs; } return g_argvs; } #endif // GTEST_HAS_DEATH_TEST #if GTEST_OS_WINDOWS_MOBILE namespace posix { void Abort() { DebugBreak(); TerminateProcess(GetCurrentProcess(), 1); } } // namespace posix #endif // GTEST_OS_WINDOWS_MOBILE // Returns the name of the environment variable corresponding to the // given flag. For example, FlagToEnvVar("foo") will return // "GTEST_FOO" in the open-source version. static std::string FlagToEnvVar(const char* flag) { const std::string full_flag = (Message() << GTEST_FLAG_PREFIX_ << flag).GetString(); Message env_var; for (size_t i = 0; i != full_flag.length(); i++) { env_var << ToUpper(full_flag.c_str()[i]); } return env_var.GetString(); } // Parses 'str' for a 32-bit signed integer. If successful, writes // the result to *value and returns true; otherwise leaves *value // unchanged and returns false. bool ParseInt32(const Message& src_text, const char* str, Int32* value) { // Parses the environment variable as a decimal integer. char* end = NULL; const long long_value = strtol(str, &end, 10); // NOLINT // Has strtol() consumed all characters in the string? if (*end != '\0') { // No - an invalid character was encountered. Message msg; msg << "WARNING: " << src_text << " is expected to be a 32-bit integer, but actually" << " has value \"" << str << "\".\n"; printf("%s", msg.GetString().c_str()); fflush(stdout); return false; } // Is the parsed value in the range of an Int32? const Int32 result = static_cast(long_value); if (long_value == LONG_MAX || long_value == LONG_MIN || // The parsed value overflows as a long. (strtol() returns // LONG_MAX or LONG_MIN when the input overflows.) result != long_value // The parsed value overflows as an Int32. ) { Message msg; msg << "WARNING: " << src_text << " is expected to be a 32-bit integer, but actually" << " has value " << str << ", which overflows.\n"; printf("%s", msg.GetString().c_str()); fflush(stdout); return false; } *value = result; return true; } // Reads and returns the Boolean environment variable corresponding to // the given flag; if it's not set, returns default_value. // // The value is considered true iff it's not "0". bool BoolFromGTestEnv(const char* flag, bool default_value) { const std::string env_var = FlagToEnvVar(flag); const char* const string_value = posix::GetEnv(env_var.c_str()); return string_value == NULL ? default_value : strcmp(string_value, "0") != 0; } // Reads and returns a 32-bit integer stored in the environment // variable corresponding to the given flag; if it isn't set or // doesn't represent a valid 32-bit integer, returns default_value. Int32 Int32FromGTestEnv(const char* flag, Int32 default_value) { const std::string env_var = FlagToEnvVar(flag); const char* const string_value = posix::GetEnv(env_var.c_str()); if (string_value == NULL) { // The environment variable is not set. return default_value; } Int32 result = default_value; if (!ParseInt32(Message() << "Environment variable " << env_var, string_value, &result)) { printf("The default value %s is used.\n", (Message() << default_value).GetString().c_str()); fflush(stdout); return default_value; } return result; } // Reads and returns the string environment variable corresponding to // the given flag; if it's not set, returns default_value. const char* StringFromGTestEnv(const char* flag, const char* default_value) { const std::string env_var = FlagToEnvVar(flag); const char* const value = posix::GetEnv(env_var.c_str()); return value == NULL ? default_value : value; } } // namespace internal } // namespace testing // Copyright 2007, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: wan@google.com (Zhanyong Wan) // Google Test - The Google C++ Testing Framework // // This file implements a universal value printer that can print a // value of any type T: // // void ::testing::internal::UniversalPrinter::Print(value, ostream_ptr); // // It uses the << operator when possible, and prints the bytes in the // object otherwise. A user can override its behavior for a class // type Foo by defining either operator<<(::std::ostream&, const Foo&) // or void PrintTo(const Foo&, ::std::ostream*) in the namespace that // defines Foo. #include #include #include // NOLINT #include namespace testing { namespace { using ::std::ostream; // Prints a segment of bytes in the given object. void PrintByteSegmentInObjectTo(const unsigned char* obj_bytes, size_t start, size_t count, ostream* os) { char text[5] = ""; for (size_t i = 0; i != count; i++) { const size_t j = start + i; if (i != 0) { // Organizes the bytes into groups of 2 for easy parsing by // human. if ((j % 2) == 0) *os << ' '; else *os << '-'; } GTEST_SNPRINTF_(text, sizeof(text), "%02X", obj_bytes[j]); *os << text; } } // Prints the bytes in the given value to the given ostream. void PrintBytesInObjectToImpl(const unsigned char* obj_bytes, size_t count, ostream* os) { // Tells the user how big the object is. *os << count << "-byte object <"; const size_t kThreshold = 132; const size_t kChunkSize = 64; // If the object size is bigger than kThreshold, we'll have to omit // some details by printing only the first and the last kChunkSize // bytes. // TODO(wan): let the user control the threshold using a flag. if (count < kThreshold) { PrintByteSegmentInObjectTo(obj_bytes, 0, count, os); } else { PrintByteSegmentInObjectTo(obj_bytes, 0, kChunkSize, os); *os << " ... "; // Rounds up to 2-byte boundary. const size_t resume_pos = (count - kChunkSize + 1)/2*2; PrintByteSegmentInObjectTo(obj_bytes, resume_pos, count - resume_pos, os); } *os << ">"; } } // namespace namespace internal2 { // Delegates to PrintBytesInObjectToImpl() to print the bytes in the // given object. The delegation simplifies the implementation, which // uses the << operator and thus is easier done outside of the // ::testing::internal namespace, which contains a << operator that // sometimes conflicts with the one in STL. void PrintBytesInObjectTo(const unsigned char* obj_bytes, size_t count, ostream* os) { PrintBytesInObjectToImpl(obj_bytes, count, os); } } // namespace internal2 namespace internal { // Depending on the value of a char (or wchar_t), we print it in one // of three formats: // - as is if it's a printable ASCII (e.g. 'a', '2', ' '), // - as a hexidecimal escape sequence (e.g. '\x7F'), or // - as a special escape sequence (e.g. '\r', '\n'). enum CharFormat { kAsIs, kHexEscape, kSpecialEscape }; // Returns true if c is a printable ASCII character. We test the // value of c directly instead of calling isprint(), which is buggy on // Windows Mobile. inline bool IsPrintableAscii(wchar_t c) { return 0x20 <= c && c <= 0x7E; } // Prints a wide or narrow char c as a character literal without the // quotes, escaping it when necessary; returns how c was formatted. // The template argument UnsignedChar is the unsigned version of Char, // which is the type of c. template static CharFormat PrintAsCharLiteralTo(Char c, ostream* os) { switch (static_cast(c)) { case L'\0': *os << "\\0"; break; case L'\'': *os << "\\'"; break; case L'\\': *os << "\\\\"; break; case L'\a': *os << "\\a"; break; case L'\b': *os << "\\b"; break; case L'\f': *os << "\\f"; break; case L'\n': *os << "\\n"; break; case L'\r': *os << "\\r"; break; case L'\t': *os << "\\t"; break; case L'\v': *os << "\\v"; break; default: if (IsPrintableAscii(c)) { *os << static_cast(c); return kAsIs; } else { *os << "\\x" + String::FormatHexInt(static_cast(c)); return kHexEscape; } } return kSpecialEscape; } // Prints a wchar_t c as if it's part of a string literal, escaping it when // necessary; returns how c was formatted. static CharFormat PrintAsStringLiteralTo(wchar_t c, ostream* os) { switch (c) { case L'\'': *os << "'"; return kAsIs; case L'"': *os << "\\\""; return kSpecialEscape; default: return PrintAsCharLiteralTo(c, os); } } // Prints a char c as if it's part of a string literal, escaping it when // necessary; returns how c was formatted. static CharFormat PrintAsStringLiteralTo(char c, ostream* os) { return PrintAsStringLiteralTo( static_cast(static_cast(c)), os); } // Prints a wide or narrow character c and its code. '\0' is printed // as "'\\0'", other unprintable characters are also properly escaped // using the standard C++ escape sequence. The template argument // UnsignedChar is the unsigned version of Char, which is the type of c. template void PrintCharAndCodeTo(Char c, ostream* os) { // First, print c as a literal in the most readable form we can find. *os << ((sizeof(c) > 1) ? "L'" : "'"); const CharFormat format = PrintAsCharLiteralTo(c, os); *os << "'"; // To aid user debugging, we also print c's code in decimal, unless // it's 0 (in which case c was printed as '\\0', making the code // obvious). if (c == 0) return; *os << " (" << static_cast(c); // For more convenience, we print c's code again in hexidecimal, // unless c was already printed in the form '\x##' or the code is in // [1, 9]. if (format == kHexEscape || (1 <= c && c <= 9)) { // Do nothing. } else { *os << ", 0x" << String::FormatHexInt(static_cast(c)); } *os << ")"; } void PrintTo(unsigned char c, ::std::ostream* os) { PrintCharAndCodeTo(c, os); } void PrintTo(signed char c, ::std::ostream* os) { PrintCharAndCodeTo(c, os); } // Prints a wchar_t as a symbol if it is printable or as its internal // code otherwise and also as its code. L'\0' is printed as "L'\\0'". void PrintTo(wchar_t wc, ostream* os) { PrintCharAndCodeTo(wc, os); } // Prints the given array of characters to the ostream. CharType must be either // char or wchar_t. // The array starts at begin, the length is len, it may include '\0' characters // and may not be NUL-terminated. template static void PrintCharsAsStringTo( const CharType* begin, size_t len, ostream* os) { const char* const kQuoteBegin = sizeof(CharType) == 1 ? "\"" : "L\""; *os << kQuoteBegin; bool is_previous_hex = false; for (size_t index = 0; index < len; ++index) { const CharType cur = begin[index]; if (is_previous_hex && IsXDigit(cur)) { // Previous character is of '\x..' form and this character can be // interpreted as another hexadecimal digit in its number. Break string to // disambiguate. *os << "\" " << kQuoteBegin; } is_previous_hex = PrintAsStringLiteralTo(cur, os) == kHexEscape; } *os << "\""; } // Prints a (const) char/wchar_t array of 'len' elements, starting at address // 'begin'. CharType must be either char or wchar_t. template static void UniversalPrintCharArray( const CharType* begin, size_t len, ostream* os) { // The code // const char kFoo[] = "foo"; // generates an array of 4, not 3, elements, with the last one being '\0'. // // Therefore when printing a char array, we don't print the last element if // it's '\0', such that the output matches the string literal as it's // written in the source code. if (len > 0 && begin[len - 1] == '\0') { PrintCharsAsStringTo(begin, len - 1, os); return; } // If, however, the last element in the array is not '\0', e.g. // const char kFoo[] = { 'f', 'o', 'o' }; // we must print the entire array. We also print a message to indicate // that the array is not NUL-terminated. PrintCharsAsStringTo(begin, len, os); *os << " (no terminating NUL)"; } // Prints a (const) char array of 'len' elements, starting at address 'begin'. void UniversalPrintArray(const char* begin, size_t len, ostream* os) { UniversalPrintCharArray(begin, len, os); } // Prints a (const) wchar_t array of 'len' elements, starting at address // 'begin'. void UniversalPrintArray(const wchar_t* begin, size_t len, ostream* os) { UniversalPrintCharArray(begin, len, os); } // Prints the given C string to the ostream. void PrintTo(const char* s, ostream* os) { if (s == NULL) { *os << "NULL"; } else { *os << ImplicitCast_(s) << " pointing to "; PrintCharsAsStringTo(s, strlen(s), os); } } // MSVC compiler can be configured to define whar_t as a typedef // of unsigned short. Defining an overload for const wchar_t* in that case // would cause pointers to unsigned shorts be printed as wide strings, // possibly accessing more memory than intended and causing invalid // memory accesses. MSVC defines _NATIVE_WCHAR_T_DEFINED symbol when // wchar_t is implemented as a native type. #if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED) // Prints the given wide C string to the ostream. void PrintTo(const wchar_t* s, ostream* os) { if (s == NULL) { *os << "NULL"; } else { *os << ImplicitCast_(s) << " pointing to "; PrintCharsAsStringTo(s, wcslen(s), os); } } #endif // wchar_t is native // Prints a ::string object. #if GTEST_HAS_GLOBAL_STRING void PrintStringTo(const ::string& s, ostream* os) { PrintCharsAsStringTo(s.data(), s.size(), os); } #endif // GTEST_HAS_GLOBAL_STRING void PrintStringTo(const ::std::string& s, ostream* os) { PrintCharsAsStringTo(s.data(), s.size(), os); } // Prints a ::wstring object. #if GTEST_HAS_GLOBAL_WSTRING void PrintWideStringTo(const ::wstring& s, ostream* os) { PrintCharsAsStringTo(s.data(), s.size(), os); } #endif // GTEST_HAS_GLOBAL_WSTRING #if GTEST_HAS_STD_WSTRING void PrintWideStringTo(const ::std::wstring& s, ostream* os) { PrintCharsAsStringTo(s.data(), s.size(), os); } #endif // GTEST_HAS_STD_WSTRING } // namespace internal } // namespace testing // Copyright 2008, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: mheule@google.com (Markus Heule) // // The Google C++ Testing Framework (Google Test) // Indicates that this translation unit is part of Google Test's // implementation. It must come before gtest-internal-inl.h is // included, or there will be a compiler error. This trick is to // prevent a user from accidentally including gtest-internal-inl.h in // his code. #define GTEST_IMPLEMENTATION_ 1 #undef GTEST_IMPLEMENTATION_ namespace testing { using internal::GetUnitTestImpl; // Gets the summary of the failure message by omitting the stack trace // in it. std::string TestPartResult::ExtractSummary(const char* message) { const char* const stack_trace = strstr(message, internal::kStackTraceMarker); return stack_trace == NULL ? message : std::string(message, stack_trace); } // Prints a TestPartResult object. std::ostream& operator<<(std::ostream& os, const TestPartResult& result) { return os << result.file_name() << ":" << result.line_number() << ": " << (result.type() == TestPartResult::kSuccess ? "Success" : result.type() == TestPartResult::kFatalFailure ? "Fatal failure" : "Non-fatal failure") << ":\n" << result.message() << std::endl; } // Appends a TestPartResult to the array. void TestPartResultArray::Append(const TestPartResult& result) { array_.push_back(result); } // Returns the TestPartResult at the given index (0-based). const TestPartResult& TestPartResultArray::GetTestPartResult(int index) const { if (index < 0 || index >= size()) { printf("\nInvalid index (%d) into TestPartResultArray.\n", index); internal::posix::Abort(); } return array_[index]; } // Returns the number of TestPartResult objects in the array. int TestPartResultArray::size() const { return static_cast(array_.size()); } namespace internal { HasNewFatalFailureHelper::HasNewFatalFailureHelper() : has_new_fatal_failure_(false), original_reporter_(GetUnitTestImpl()-> GetTestPartResultReporterForCurrentThread()) { GetUnitTestImpl()->SetTestPartResultReporterForCurrentThread(this); } HasNewFatalFailureHelper::~HasNewFatalFailureHelper() { GetUnitTestImpl()->SetTestPartResultReporterForCurrentThread( original_reporter_); } void HasNewFatalFailureHelper::ReportTestPartResult( const TestPartResult& result) { if (result.fatally_failed()) has_new_fatal_failure_ = true; original_reporter_->ReportTestPartResult(result); } } // namespace internal } // namespace testing // Copyright 2008 Google Inc. // All Rights Reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: wan@google.com (Zhanyong Wan) namespace testing { namespace internal { #if GTEST_HAS_TYPED_TEST_P // Skips to the first non-space char in str. Returns an empty string if str // contains only whitespace characters. static const char* SkipSpaces(const char* str) { while (IsSpace(*str)) str++; return str; } // Verifies that registered_tests match the test names in // defined_test_names_; returns registered_tests if successful, or // aborts the program otherwise. const char* TypedTestCasePState::VerifyRegisteredTestNames( const char* file, int line, const char* registered_tests) { typedef ::std::set::const_iterator DefinedTestIter; registered_ = true; // Skip initial whitespace in registered_tests since some // preprocessors prefix stringizied literals with whitespace. registered_tests = SkipSpaces(registered_tests); Message errors; ::std::set tests; for (const char* names = registered_tests; names != NULL; names = SkipComma(names)) { const std::string name = GetPrefixUntilComma(names); if (tests.count(name) != 0) { errors << "Test " << name << " is listed more than once.\n"; continue; } bool found = false; for (DefinedTestIter it = defined_test_names_.begin(); it != defined_test_names_.end(); ++it) { if (name == *it) { found = true; break; } } if (found) { tests.insert(name); } else { errors << "No test named " << name << " can be found in this test case.\n"; } } for (DefinedTestIter it = defined_test_names_.begin(); it != defined_test_names_.end(); ++it) { if (tests.count(*it) == 0) { errors << "You forgot to list test " << *it << ".\n"; } } const std::string& errors_str = errors.GetString(); if (errors_str != "") { fprintf(stderr, "%s %s", FormatFileLocation(file, line).c_str(), errors_str.c_str()); fflush(stderr); posix::Abort(); } return registered_tests; } #endif // GTEST_HAS_TYPED_TEST_P } // namespace internal } // namespace testing dlt-daemon-2.18.4/gtest-1.7.0/fused-src/gtest/gtest.h000066400000000000000000031261431353342203500217530ustar00rootroot00000000000000// Copyright 2005, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: wan@google.com (Zhanyong Wan) // // The Google C++ Testing Framework (Google Test) // // This header file defines the public API for Google Test. It should be // included by any test program that uses Google Test. // // IMPORTANT NOTE: Due to limitation of the C++ language, we have to // leave some internal implementation details in this header file. // They are clearly marked by comments like this: // // // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. // // Such code is NOT meant to be used by a user directly, and is subject // to CHANGE WITHOUT NOTICE. Therefore DO NOT DEPEND ON IT in a user // program! // // Acknowledgment: Google Test borrowed the idea of automatic test // registration from Barthelemy Dagenais' (barthelemy@prologique.com) // easyUnit framework. #ifndef GTEST_INCLUDE_GTEST_GTEST_H_ #define GTEST_INCLUDE_GTEST_GTEST_H_ #include #include #include // Copyright 2005, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Authors: wan@google.com (Zhanyong Wan), eefacm@gmail.com (Sean Mcafee) // // The Google C++ Testing Framework (Google Test) // // This header file declares functions and macros used internally by // Google Test. They are subject to change without notice. #ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_ #define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_ // Copyright 2005, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Authors: wan@google.com (Zhanyong Wan) // // Low-level types and utilities for porting Google Test to various // platforms. They are subject to change without notice. DO NOT USE // THEM IN USER CODE. // // This file is fundamental to Google Test. All other Google Test source // files are expected to #include this. Therefore, it cannot #include // any other Google Test header. #ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_ #define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_ // The user can define the following macros in the build script to // control Google Test's behavior. If the user doesn't define a macro // in this list, Google Test will define it. // // GTEST_HAS_CLONE - Define it to 1/0 to indicate that clone(2) // is/isn't available. // GTEST_HAS_EXCEPTIONS - Define it to 1/0 to indicate that exceptions // are enabled. // GTEST_HAS_GLOBAL_STRING - Define it to 1/0 to indicate that ::string // is/isn't available (some systems define // ::string, which is different to std::string). // GTEST_HAS_GLOBAL_WSTRING - Define it to 1/0 to indicate that ::string // is/isn't available (some systems define // ::wstring, which is different to std::wstring). // GTEST_HAS_POSIX_RE - Define it to 1/0 to indicate that POSIX regular // expressions are/aren't available. // GTEST_HAS_PTHREAD - Define it to 1/0 to indicate that // is/isn't available. // GTEST_HAS_RTTI - Define it to 1/0 to indicate that RTTI is/isn't // enabled. // GTEST_HAS_STD_WSTRING - Define it to 1/0 to indicate that // std::wstring does/doesn't work (Google Test can // be used where std::wstring is unavailable). // GTEST_HAS_TR1_TUPLE - Define it to 1/0 to indicate tr1::tuple // is/isn't available. // GTEST_HAS_SEH - Define it to 1/0 to indicate whether the // compiler supports Microsoft's "Structured // Exception Handling". // GTEST_HAS_STREAM_REDIRECTION // - Define it to 1/0 to indicate whether the // platform supports I/O stream redirection using // dup() and dup2(). // GTEST_USE_OWN_TR1_TUPLE - Define it to 1/0 to indicate whether Google // Test's own tr1 tuple implementation should be // used. Unused when the user sets // GTEST_HAS_TR1_TUPLE to 0. // GTEST_LANG_CXX11 - Define it to 1/0 to indicate that Google Test // is building in C++11/C++98 mode. // GTEST_LINKED_AS_SHARED_LIBRARY // - Define to 1 when compiling tests that use // Google Test as a shared library (known as // DLL on Windows). // GTEST_CREATE_SHARED_LIBRARY // - Define to 1 when compiling Google Test itself // as a shared library. // This header defines the following utilities: // // Macros indicating the current platform (defined to 1 if compiled on // the given platform; otherwise undefined): // GTEST_OS_AIX - IBM AIX // GTEST_OS_CYGWIN - Cygwin // GTEST_OS_HPUX - HP-UX // GTEST_OS_LINUX - Linux // GTEST_OS_LINUX_ANDROID - Google Android // GTEST_OS_MAC - Mac OS X // GTEST_OS_IOS - iOS // GTEST_OS_IOS_SIMULATOR - iOS simulator // GTEST_OS_NACL - Google Native Client (NaCl) // GTEST_OS_OPENBSD - OpenBSD // GTEST_OS_QNX - QNX // GTEST_OS_SOLARIS - Sun Solaris // GTEST_OS_SYMBIAN - Symbian // GTEST_OS_WINDOWS - Windows (Desktop, MinGW, or Mobile) // GTEST_OS_WINDOWS_DESKTOP - Windows Desktop // GTEST_OS_WINDOWS_MINGW - MinGW // GTEST_OS_WINDOWS_MOBILE - Windows Mobile // GTEST_OS_ZOS - z/OS // // Among the platforms, Cygwin, Linux, Max OS X, and Windows have the // most stable support. Since core members of the Google Test project // don't have access to other platforms, support for them may be less // stable. If you notice any problems on your platform, please notify // googletestframework@googlegroups.com (patches for fixing them are // even more welcome!). // // Note that it is possible that none of the GTEST_OS_* macros are defined. // // Macros indicating available Google Test features (defined to 1 if // the corresponding feature is supported; otherwise undefined): // GTEST_HAS_COMBINE - the Combine() function (for value-parameterized // tests) // GTEST_HAS_DEATH_TEST - death tests // GTEST_HAS_PARAM_TEST - value-parameterized tests // GTEST_HAS_TYPED_TEST - typed tests // GTEST_HAS_TYPED_TEST_P - type-parameterized tests // GTEST_USES_POSIX_RE - enhanced POSIX regex is used. Do not confuse with // GTEST_HAS_POSIX_RE (see above) which users can // define themselves. // GTEST_USES_SIMPLE_RE - our own simple regex is used; // the above two are mutually exclusive. // GTEST_CAN_COMPARE_NULL - accepts untyped NULL in EXPECT_EQ(). // // Macros for basic C++ coding: // GTEST_AMBIGUOUS_ELSE_BLOCKER_ - for disabling a gcc warning. // GTEST_ATTRIBUTE_UNUSED_ - declares that a class' instances or a // variable don't have to be used. // GTEST_DISALLOW_ASSIGN_ - disables operator=. // GTEST_DISALLOW_COPY_AND_ASSIGN_ - disables copy ctor and operator=. // GTEST_MUST_USE_RESULT_ - declares that a function's result must be used. // // Synchronization: // Mutex, MutexLock, ThreadLocal, GetThreadCount() // - synchronization primitives. // GTEST_IS_THREADSAFE - defined to 1 to indicate that the above // synchronization primitives have real implementations // and Google Test is thread-safe; or 0 otherwise. // // Template meta programming: // is_pointer - as in TR1; needed on Symbian and IBM XL C/C++ only. // IteratorTraits - partial implementation of std::iterator_traits, which // is not available in libCstd when compiled with Sun C++. // // Smart pointers: // scoped_ptr - as in TR2. // // Regular expressions: // RE - a simple regular expression class using the POSIX // Extended Regular Expression syntax on UNIX-like // platforms, or a reduced regular exception syntax on // other platforms, including Windows. // // Logging: // GTEST_LOG_() - logs messages at the specified severity level. // LogToStderr() - directs all log messages to stderr. // FlushInfoLog() - flushes informational log messages. // // Stdout and stderr capturing: // CaptureStdout() - starts capturing stdout. // GetCapturedStdout() - stops capturing stdout and returns the captured // string. // CaptureStderr() - starts capturing stderr. // GetCapturedStderr() - stops capturing stderr and returns the captured // string. // // Integer types: // TypeWithSize - maps an integer to a int type. // Int32, UInt32, Int64, UInt64, TimeInMillis // - integers of known sizes. // BiggestInt - the biggest signed integer type. // // Command-line utilities: // GTEST_FLAG() - references a flag. // GTEST_DECLARE_*() - declares a flag. // GTEST_DEFINE_*() - defines a flag. // GetInjectableArgvs() - returns the command line as a vector of strings. // // Environment variable utilities: // GetEnv() - gets the value of an environment variable. // BoolFromGTestEnv() - parses a bool environment variable. // Int32FromGTestEnv() - parses an Int32 environment variable. // StringFromGTestEnv() - parses a string environment variable. #include // for isspace, etc #include // for ptrdiff_t #include #include #include #ifndef _WIN32_WCE # include # include #endif // !_WIN32_WCE #if defined __APPLE__ # include # include #endif #include // NOLINT #include // NOLINT #include // NOLINT #define GTEST_DEV_EMAIL_ "googletestframework@@googlegroups.com" #define GTEST_FLAG_PREFIX_ "gtest_" #define GTEST_FLAG_PREFIX_DASH_ "gtest-" #define GTEST_FLAG_PREFIX_UPPER_ "GTEST_" #define GTEST_NAME_ "Google Test" #define GTEST_PROJECT_URL_ "http://code.google.com/p/googletest/" // Determines the version of gcc that is used to compile this. #ifdef __GNUC__ // 40302 means version 4.3.2. # define GTEST_GCC_VER_ \ (__GNUC__*10000 + __GNUC_MINOR__*100 + __GNUC_PATCHLEVEL__) #endif // __GNUC__ // Determines the platform on which Google Test is compiled. #ifdef __CYGWIN__ # define GTEST_OS_CYGWIN 1 #elif defined __SYMBIAN32__ # define GTEST_OS_SYMBIAN 1 #elif defined _WIN32 # define GTEST_OS_WINDOWS 1 # ifdef _WIN32_WCE # define GTEST_OS_WINDOWS_MOBILE 1 # elif defined(__MINGW__) || defined(__MINGW32__) # define GTEST_OS_WINDOWS_MINGW 1 # else # define GTEST_OS_WINDOWS_DESKTOP 1 # endif // _WIN32_WCE #elif defined __APPLE__ # define GTEST_OS_MAC 1 # 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__ #ifndef GTEST_LANG_CXX11 // gcc and clang define __GXX_EXPERIMENTAL_CXX0X__ when // -std={c,gnu}++{0x,11} is passed. The C++11 standard specifies a // value for __cplusplus, and recent versions of clang, gcc, and // probably other compilers set that too in C++11 mode. # if __GXX_EXPERIMENTAL_CXX0X__ || __cplusplus >= 201103L // Compiling in at least C++11 mode. # define GTEST_LANG_CXX11 1 # else # define GTEST_LANG_CXX11 0 # endif #endif // Brings in definitions for functions used in the testing::internal::posix // namespace (read, write, close, chdir, isatty, stat). We do not currently // use them on Windows Mobile. #if !GTEST_OS_WINDOWS // This assumes that non-Windows OSes provide unistd.h. For OSes where this // is not the case, we need to include headers that provide the functions // mentioned above. # include # include #elif !GTEST_OS_WINDOWS_MOBILE # include # include #endif #if GTEST_OS_LINUX_ANDROID // Used to define __ANDROID_API__ matching the target NDK API level. # include // NOLINT #endif // Defines this to true iff Google Test can use POSIX regular expressions. #ifndef GTEST_HAS_POSIX_RE # if GTEST_OS_LINUX_ANDROID // On Android, is only available starting with Gingerbread. # define GTEST_HAS_POSIX_RE (__ANDROID_API__ >= 9) # else # define GTEST_HAS_POSIX_RE (!GTEST_OS_WINDOWS) # endif #endif #if 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 // included , which is guaranteed to define size_t through // . # include // NOLINT # define GTEST_USES_POSIX_RE 1 #elif GTEST_OS_WINDOWS // is not available on Windows. Use our own simple regex // implementation instead. # define GTEST_USES_SIMPLE_RE 1 #else // may not be available on this platform. Use our own // simple regex implementation instead. # define GTEST_USES_SIMPLE_RE 1 #endif // GTEST_HAS_POSIX_RE #ifndef GTEST_HAS_EXCEPTIONS // The user didn't tell us whether exceptions are enabled, so we need // to figure it out. # if defined(_MSC_VER) || defined(__BORLANDC__) // MSVC's and C++Builder's implementations of the STL use the _HAS_EXCEPTIONS // macro to enable exceptions, so we'll do the same. // Assumes that exceptions are enabled by default. # ifndef _HAS_EXCEPTIONS # define _HAS_EXCEPTIONS 1 # endif // _HAS_EXCEPTIONS # define GTEST_HAS_EXCEPTIONS _HAS_EXCEPTIONS # elif defined(__GNUC__) && __EXCEPTIONS // gcc defines __EXCEPTIONS to 1 iff exceptions are enabled. # define GTEST_HAS_EXCEPTIONS 1 # elif defined(__SUNPRO_CC) // Sun Pro CC supports exceptions. However, there is no compile-time way of // detecting whether they are enabled or not. Therefore, we assume that // they are enabled unless the user tells us otherwise. # define GTEST_HAS_EXCEPTIONS 1 # elif defined(__IBMCPP__) && __EXCEPTIONS // xlC defines __EXCEPTIONS to 1 iff exceptions are enabled. # define GTEST_HAS_EXCEPTIONS 1 # elif defined(__HP_aCC) // Exception handling is in effect by default in HP aCC compiler. It has to // be turned of by +noeh compiler option if desired. # define GTEST_HAS_EXCEPTIONS 1 # else // For other compilers, we assume exceptions are disabled to be // conservative. # define GTEST_HAS_EXCEPTIONS 0 # endif // defined(_MSC_VER) || defined(__BORLANDC__) #endif // GTEST_HAS_EXCEPTIONS #if !defined(GTEST_HAS_STD_STRING) // Even though we don't use this macro any longer, we keep it in case // some clients still depend on it. # define GTEST_HAS_STD_STRING 1 #elif !GTEST_HAS_STD_STRING // The user told us that ::std::string isn't available. # error "Google Test cannot be used where ::std::string isn't available." #endif // !defined(GTEST_HAS_STD_STRING) #ifndef GTEST_HAS_GLOBAL_STRING // The user didn't tell us whether ::string is available, so we need // to figure it out. # define GTEST_HAS_GLOBAL_STRING 0 #endif // GTEST_HAS_GLOBAL_STRING #ifndef GTEST_HAS_STD_WSTRING // The user didn't tell us whether ::std::wstring is available, so we need // to figure it out. // TODO(wan@google.com): uses autoconf to detect whether ::std::wstring // is available. // Cygwin 1.7 and below doesn't support ::std::wstring. // Solaris' libc++ doesn't support it either. Android has // no support for it at least as recent as Froyo (2.2). # define GTEST_HAS_STD_WSTRING \ (!(GTEST_OS_LINUX_ANDROID || GTEST_OS_CYGWIN || GTEST_OS_SOLARIS)) #endif // GTEST_HAS_STD_WSTRING #ifndef GTEST_HAS_GLOBAL_WSTRING // The user didn't tell us whether ::wstring is available, so we need // to figure it out. # define GTEST_HAS_GLOBAL_WSTRING \ (GTEST_HAS_STD_WSTRING && GTEST_HAS_GLOBAL_STRING) #endif // GTEST_HAS_GLOBAL_WSTRING // Determines whether RTTI is available. #ifndef GTEST_HAS_RTTI // The user didn't tell us whether RTTI is enabled, so we need to // figure it out. # ifdef _MSC_VER # ifdef _CPPRTTI // MSVC defines this macro iff RTTI is enabled. # define GTEST_HAS_RTTI 1 # else # define GTEST_HAS_RTTI 0 # endif // Starting with version 4.3.2, gcc defines __GXX_RTTI iff RTTI is enabled. # elif defined(__GNUC__) && (GTEST_GCC_VER_ >= 40302) # ifdef __GXX_RTTI // When building against STLport with the Android NDK and with // -frtti -fno-exceptions, the build fails at link time with undefined // references to __cxa_bad_typeid. Note sure if STL or toolchain bug, // so disable RTTI when detected. # if GTEST_OS_LINUX_ANDROID && defined(_STLPORT_MAJOR) && \ !defined(__EXCEPTIONS) # define GTEST_HAS_RTTI 0 # else # define GTEST_HAS_RTTI 1 # endif // GTEST_OS_LINUX_ANDROID && __STLPORT_MAJOR && !__EXCEPTIONS # else # define GTEST_HAS_RTTI 0 # endif // __GXX_RTTI // Clang defines __GXX_RTTI starting with version 3.0, but its manual recommends // using has_feature instead. has_feature(cxx_rtti) is supported since 2.7, the // first version with C++ support. # elif defined(__clang__) # define GTEST_HAS_RTTI __has_feature(cxx_rtti) // Starting with version 9.0 IBM Visual Age defines __RTTI_ALL__ to 1 if // both the typeid and dynamic_cast features are present. # elif defined(__IBMCPP__) && (__IBMCPP__ >= 900) # ifdef __RTTI_ALL__ # define GTEST_HAS_RTTI 1 # else # define GTEST_HAS_RTTI 0 # endif # else // For all other compilers, we assume RTTI is enabled. # define GTEST_HAS_RTTI 1 # endif // _MSC_VER #endif // GTEST_HAS_RTTI // It's this header's responsibility to #include when RTTI // is enabled. #if GTEST_HAS_RTTI # include #endif // Determines whether Google Test can use the pthreads library. #ifndef GTEST_HAS_PTHREAD // The user didn't tell us explicitly, so we assume pthreads support is // available on Linux and Mac. // // To disable threading support in Google Test, add -DGTEST_HAS_PTHREAD=0 // to your compiler flags. # define GTEST_HAS_PTHREAD (GTEST_OS_LINUX || GTEST_OS_MAC || GTEST_OS_HPUX \ || GTEST_OS_QNX) #endif // GTEST_HAS_PTHREAD #if GTEST_HAS_PTHREAD // gtest-port.h guarantees to #include when GTEST_HAS_PTHREAD is // true. # include // NOLINT // For timespec and nanosleep, used below. # include // NOLINT #endif // Determines whether Google Test can use tr1/tuple. You can define // this macro to 0 to prevent Google Test from using tuple (any // feature depending on tuple with be disabled in this mode). #ifndef GTEST_HAS_TR1_TUPLE # if GTEST_OS_LINUX_ANDROID && defined(_STLPORT_MAJOR) // STLport, provided with the Android NDK, has neither or . # define GTEST_HAS_TR1_TUPLE 0 # else // The user didn't tell us not to do it, so we assume it's OK. # define GTEST_HAS_TR1_TUPLE 1 # endif #endif // GTEST_HAS_TR1_TUPLE // Determines whether Google Test's own tr1 tuple implementation // should be used. #ifndef GTEST_USE_OWN_TR1_TUPLE // The user didn't tell us, so we need to figure it out. // We use our own TR1 tuple if we aren't sure the user has an // implementation of it already. At this time, libstdc++ 4.0.0+ and // MSVC 2010 are the only mainstream standard libraries that come // with a TR1 tuple implementation. NVIDIA's CUDA NVCC compiler // pretends to be GCC by defining __GNUC__ and friends, but cannot // compile GCC's tuple implementation. MSVC 2008 (9.0) provides TR1 // tuple in a 323 MB Feature Pack download, which we cannot assume the // user has. QNX's QCC compiler is a modified GCC but it doesn't // support TR1 tuple. libc++ only provides std::tuple, in C++11 mode, // and it can be used with some compilers that define __GNUC__. # if (defined(__GNUC__) && !defined(__CUDACC__) && (GTEST_GCC_VER_ >= 40000) \ && !GTEST_OS_QNX && !defined(_LIBCPP_VERSION)) || _MSC_VER >= 1600 # define GTEST_ENV_HAS_TR1_TUPLE_ 1 # endif // C++11 specifies that provides std::tuple. 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) # define GTEST_ENV_HAS_STD_TUPLE_ 1 # endif # if GTEST_ENV_HAS_TR1_TUPLE_ || GTEST_ENV_HAS_STD_TUPLE_ # define GTEST_USE_OWN_TR1_TUPLE 0 # else # define GTEST_USE_OWN_TR1_TUPLE 1 # endif #endif // GTEST_USE_OWN_TR1_TUPLE // To avoid conditional compilation everywhere, we make it // gtest-port.h's responsibility to #include the header implementing // tr1/tuple. #if GTEST_HAS_TR1_TUPLE # if GTEST_USE_OWN_TR1_TUPLE // This file was GENERATED by command: // pump.py gtest-tuple.h.pump // DO NOT EDIT BY HAND!!! // Copyright 2009 Google Inc. // All Rights Reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: wan@google.com (Zhanyong Wan) // Implements a subset of TR1 tuple needed by Google Test and Google Mock. #ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_ #define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_ #include // For ::std::pair. // The compiler used in Symbian has a bug that prevents us from declaring the // tuple template as a friend (it complains that tuple is redefined). This // hack bypasses the bug by declaring the members that should otherwise be // private as public. // Sun Studio versions < 12 also have the above bug. #if defined(__SYMBIAN32__) || (defined(__SUNPRO_CC) && __SUNPRO_CC < 0x590) # define GTEST_DECLARE_TUPLE_AS_FRIEND_ public: #else # define GTEST_DECLARE_TUPLE_AS_FRIEND_ \ template friend class tuple; \ private: #endif // GTEST_n_TUPLE_(T) is the type of an n-tuple. #define GTEST_0_TUPLE_(T) tuple<> #define GTEST_1_TUPLE_(T) tuple #define GTEST_2_TUPLE_(T) tuple #define GTEST_3_TUPLE_(T) tuple #define GTEST_4_TUPLE_(T) tuple #define GTEST_5_TUPLE_(T) tuple #define GTEST_6_TUPLE_(T) tuple #define GTEST_7_TUPLE_(T) tuple #define GTEST_8_TUPLE_(T) tuple #define GTEST_9_TUPLE_(T) tuple #define GTEST_10_TUPLE_(T) tuple // GTEST_n_TYPENAMES_(T) declares a list of n typenames. #define GTEST_0_TYPENAMES_(T) #define GTEST_1_TYPENAMES_(T) typename T##0 #define GTEST_2_TYPENAMES_(T) typename T##0, typename T##1 #define GTEST_3_TYPENAMES_(T) typename T##0, typename T##1, typename T##2 #define GTEST_4_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \ typename T##3 #define GTEST_5_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \ typename T##3, typename T##4 #define GTEST_6_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \ typename T##3, typename T##4, typename T##5 #define GTEST_7_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \ typename T##3, typename T##4, typename T##5, typename T##6 #define GTEST_8_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \ typename T##3, typename T##4, typename T##5, typename T##6, typename T##7 #define GTEST_9_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \ typename T##3, typename T##4, typename T##5, typename T##6, \ typename T##7, typename T##8 #define GTEST_10_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \ typename T##3, typename T##4, typename T##5, typename T##6, \ typename T##7, typename T##8, typename T##9 // In theory, defining stuff in the ::std namespace is undefined // behavior. We can do this as we are playing the role of a standard // library vendor. namespace std { namespace tr1 { template class tuple; // Anything in namespace gtest_internal is Google Test's INTERNAL // IMPLEMENTATION DETAIL and MUST NOT BE USED DIRECTLY in user code. namespace gtest_internal { // ByRef::type is T if T is a reference; otherwise it's const T&. template struct ByRef { typedef const T& type; }; // NOLINT template struct ByRef { typedef T& type; }; // NOLINT // A handy wrapper for ByRef. #define GTEST_BY_REF_(T) typename ::std::tr1::gtest_internal::ByRef::type // AddRef::type is T if T is a reference; otherwise it's T&. This // is the same as tr1::add_reference::type. template struct AddRef { typedef T& type; }; // NOLINT template struct AddRef { typedef T& type; }; // NOLINT // A handy wrapper for AddRef. #define GTEST_ADD_REF_(T) typename ::std::tr1::gtest_internal::AddRef::type // A helper for implementing get(). template class Get; // A helper for implementing tuple_element. kIndexValid is true // iff k < the number of fields in tuple type T. template struct TupleElement; template struct TupleElement { typedef T0 type; }; template struct TupleElement { typedef T1 type; }; template struct TupleElement { typedef T2 type; }; template struct TupleElement { typedef T3 type; }; template struct TupleElement { typedef T4 type; }; template struct TupleElement { typedef T5 type; }; template struct TupleElement { typedef T6 type; }; template struct TupleElement { typedef T7 type; }; template struct TupleElement { typedef T8 type; }; template struct TupleElement { typedef T9 type; }; } // namespace gtest_internal template <> class tuple<> { public: tuple() {} tuple(const tuple& /* t */) {} tuple& operator=(const tuple& /* t */) { return *this; } }; template class GTEST_1_TUPLE_(T) { public: template friend class gtest_internal::Get; tuple() : f0_() {} explicit tuple(GTEST_BY_REF_(T0) f0) : f0_(f0) {} tuple(const tuple& t) : f0_(t.f0_) {} template tuple(const GTEST_1_TUPLE_(U)& t) : f0_(t.f0_) {} tuple& operator=(const tuple& t) { return CopyFrom(t); } template tuple& operator=(const GTEST_1_TUPLE_(U)& t) { return CopyFrom(t); } GTEST_DECLARE_TUPLE_AS_FRIEND_ template tuple& CopyFrom(const GTEST_1_TUPLE_(U)& t) { f0_ = t.f0_; return *this; } T0 f0_; }; template class GTEST_2_TUPLE_(T) { public: template friend class gtest_internal::Get; tuple() : f0_(), f1_() {} explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1) : f0_(f0), f1_(f1) {} tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_) {} template tuple(const GTEST_2_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_) {} template tuple(const ::std::pair& p) : f0_(p.first), f1_(p.second) {} tuple& operator=(const tuple& t) { return CopyFrom(t); } template tuple& operator=(const GTEST_2_TUPLE_(U)& t) { return CopyFrom(t); } template tuple& operator=(const ::std::pair& p) { f0_ = p.first; f1_ = p.second; return *this; } GTEST_DECLARE_TUPLE_AS_FRIEND_ template tuple& CopyFrom(const GTEST_2_TUPLE_(U)& t) { f0_ = t.f0_; f1_ = t.f1_; return *this; } T0 f0_; T1 f1_; }; template class GTEST_3_TUPLE_(T) { public: template friend class gtest_internal::Get; tuple() : f0_(), f1_(), f2_() {} explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, GTEST_BY_REF_(T2) f2) : f0_(f0), f1_(f1), f2_(f2) {} tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_) {} template tuple(const GTEST_3_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_) {} tuple& operator=(const tuple& t) { return CopyFrom(t); } template tuple& operator=(const GTEST_3_TUPLE_(U)& t) { return CopyFrom(t); } GTEST_DECLARE_TUPLE_AS_FRIEND_ template tuple& CopyFrom(const GTEST_3_TUPLE_(U)& t) { f0_ = t.f0_; f1_ = t.f1_; f2_ = t.f2_; return *this; } T0 f0_; T1 f1_; T2 f2_; }; template class GTEST_4_TUPLE_(T) { public: template friend class gtest_internal::Get; tuple() : f0_(), f1_(), f2_(), f3_() {} explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3) : f0_(f0), f1_(f1), f2_(f2), f3_(f3) {} tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_) {} template tuple(const GTEST_4_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_) {} tuple& operator=(const tuple& t) { return CopyFrom(t); } template tuple& operator=(const GTEST_4_TUPLE_(U)& t) { return CopyFrom(t); } GTEST_DECLARE_TUPLE_AS_FRIEND_ template tuple& CopyFrom(const GTEST_4_TUPLE_(U)& t) { f0_ = t.f0_; f1_ = t.f1_; f2_ = t.f2_; f3_ = t.f3_; return *this; } T0 f0_; T1 f1_; T2 f2_; T3 f3_; }; template class GTEST_5_TUPLE_(T) { public: template friend class gtest_internal::Get; tuple() : f0_(), f1_(), f2_(), f3_(), f4_() {} explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4) {} tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), f4_(t.f4_) {} template tuple(const GTEST_5_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), f4_(t.f4_) {} tuple& operator=(const tuple& t) { return CopyFrom(t); } template tuple& operator=(const GTEST_5_TUPLE_(U)& t) { return CopyFrom(t); } GTEST_DECLARE_TUPLE_AS_FRIEND_ template tuple& CopyFrom(const GTEST_5_TUPLE_(U)& t) { f0_ = t.f0_; f1_ = t.f1_; f2_ = t.f2_; f3_ = t.f3_; f4_ = t.f4_; return *this; } T0 f0_; T1 f1_; T2 f2_; T3 f3_; T4 f4_; }; template class GTEST_6_TUPLE_(T) { public: template friend class gtest_internal::Get; tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_() {} explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4, GTEST_BY_REF_(T5) f5) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4), f5_(f5) {} tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), f4_(t.f4_), f5_(t.f5_) {} template tuple(const GTEST_6_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), f4_(t.f4_), f5_(t.f5_) {} tuple& operator=(const tuple& t) { return CopyFrom(t); } template tuple& operator=(const GTEST_6_TUPLE_(U)& t) { return CopyFrom(t); } GTEST_DECLARE_TUPLE_AS_FRIEND_ template tuple& CopyFrom(const GTEST_6_TUPLE_(U)& t) { f0_ = t.f0_; f1_ = t.f1_; f2_ = t.f2_; f3_ = t.f3_; f4_ = t.f4_; f5_ = t.f5_; return *this; } T0 f0_; T1 f1_; T2 f2_; T3 f3_; T4 f4_; T5 f5_; }; template class GTEST_7_TUPLE_(T) { public: template friend class gtest_internal::Get; tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_(), f6_() {} explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4, GTEST_BY_REF_(T5) f5, GTEST_BY_REF_(T6) f6) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4), f5_(f5), f6_(f6) {} tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_) {} template tuple(const GTEST_7_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_) {} tuple& operator=(const tuple& t) { return CopyFrom(t); } template tuple& operator=(const GTEST_7_TUPLE_(U)& t) { return CopyFrom(t); } GTEST_DECLARE_TUPLE_AS_FRIEND_ template tuple& CopyFrom(const GTEST_7_TUPLE_(U)& t) { f0_ = t.f0_; f1_ = t.f1_; f2_ = t.f2_; f3_ = t.f3_; f4_ = t.f4_; f5_ = t.f5_; f6_ = t.f6_; return *this; } T0 f0_; T1 f1_; T2 f2_; T3 f3_; T4 f4_; T5 f5_; T6 f6_; }; template class GTEST_8_TUPLE_(T) { public: template friend class gtest_internal::Get; tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_(), f6_(), f7_() {} explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4, GTEST_BY_REF_(T5) f5, GTEST_BY_REF_(T6) f6, GTEST_BY_REF_(T7) f7) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4), f5_(f5), f6_(f6), f7_(f7) {} tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_) {} template tuple(const GTEST_8_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_) {} tuple& operator=(const tuple& t) { return CopyFrom(t); } template tuple& operator=(const GTEST_8_TUPLE_(U)& t) { return CopyFrom(t); } GTEST_DECLARE_TUPLE_AS_FRIEND_ template tuple& CopyFrom(const GTEST_8_TUPLE_(U)& t) { f0_ = t.f0_; f1_ = t.f1_; f2_ = t.f2_; f3_ = t.f3_; f4_ = t.f4_; f5_ = t.f5_; f6_ = t.f6_; f7_ = t.f7_; return *this; } T0 f0_; T1 f1_; T2 f2_; T3 f3_; T4 f4_; T5 f5_; T6 f6_; T7 f7_; }; template class GTEST_9_TUPLE_(T) { public: template friend class gtest_internal::Get; tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_(), f6_(), f7_(), f8_() {} explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4, GTEST_BY_REF_(T5) f5, GTEST_BY_REF_(T6) f6, GTEST_BY_REF_(T7) f7, GTEST_BY_REF_(T8) f8) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4), f5_(f5), f6_(f6), f7_(f7), f8_(f8) {} tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_), f8_(t.f8_) {} template tuple(const GTEST_9_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_), f8_(t.f8_) {} tuple& operator=(const tuple& t) { return CopyFrom(t); } template tuple& operator=(const GTEST_9_TUPLE_(U)& t) { return CopyFrom(t); } GTEST_DECLARE_TUPLE_AS_FRIEND_ template tuple& CopyFrom(const GTEST_9_TUPLE_(U)& t) { f0_ = t.f0_; f1_ = t.f1_; f2_ = t.f2_; f3_ = t.f3_; f4_ = t.f4_; f5_ = t.f5_; f6_ = t.f6_; f7_ = t.f7_; f8_ = t.f8_; return *this; } T0 f0_; T1 f1_; T2 f2_; T3 f3_; T4 f4_; T5 f5_; T6 f6_; T7 f7_; T8 f8_; }; template class tuple { public: template friend class gtest_internal::Get; tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_(), f6_(), f7_(), f8_(), f9_() {} explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4, GTEST_BY_REF_(T5) f5, GTEST_BY_REF_(T6) f6, GTEST_BY_REF_(T7) f7, GTEST_BY_REF_(T8) f8, GTEST_BY_REF_(T9) f9) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4), f5_(f5), f6_(f6), f7_(f7), f8_(f8), f9_(f9) {} tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_), f8_(t.f8_), f9_(t.f9_) {} template tuple(const GTEST_10_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_), f8_(t.f8_), f9_(t.f9_) {} tuple& operator=(const tuple& t) { return CopyFrom(t); } template tuple& operator=(const GTEST_10_TUPLE_(U)& t) { return CopyFrom(t); } GTEST_DECLARE_TUPLE_AS_FRIEND_ template tuple& CopyFrom(const GTEST_10_TUPLE_(U)& t) { f0_ = t.f0_; f1_ = t.f1_; f2_ = t.f2_; f3_ = t.f3_; f4_ = t.f4_; f5_ = t.f5_; f6_ = t.f6_; f7_ = t.f7_; f8_ = t.f8_; f9_ = t.f9_; return *this; } T0 f0_; T1 f1_; T2 f2_; T3 f3_; T4 f4_; T5 f5_; T6 f6_; T7 f7_; T8 f8_; T9 f9_; }; // 6.1.3.2 Tuple creation functions. // Known limitations: we don't support passing an // std::tr1::reference_wrapper to make_tuple(). And we don't // implement tie(). inline tuple<> make_tuple() { return tuple<>(); } template inline GTEST_1_TUPLE_(T) make_tuple(const T0& f0) { return GTEST_1_TUPLE_(T)(f0); } template inline GTEST_2_TUPLE_(T) make_tuple(const T0& f0, const T1& f1) { return GTEST_2_TUPLE_(T)(f0, f1); } template inline GTEST_3_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2) { return GTEST_3_TUPLE_(T)(f0, f1, f2); } template inline GTEST_4_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2, const T3& f3) { return GTEST_4_TUPLE_(T)(f0, f1, f2, f3); } template inline GTEST_5_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2, const T3& f3, const T4& f4) { return GTEST_5_TUPLE_(T)(f0, f1, f2, f3, f4); } template inline GTEST_6_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2, const T3& f3, const T4& f4, const T5& f5) { return GTEST_6_TUPLE_(T)(f0, f1, f2, f3, f4, f5); } template inline GTEST_7_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2, const T3& f3, const T4& f4, const T5& f5, const T6& f6) { return GTEST_7_TUPLE_(T)(f0, f1, f2, f3, f4, f5, f6); } template inline GTEST_8_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2, const T3& f3, const T4& f4, const T5& f5, const T6& f6, const T7& f7) { return GTEST_8_TUPLE_(T)(f0, f1, f2, f3, f4, f5, f6, f7); } template inline GTEST_9_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2, const T3& f3, const T4& f4, const T5& f5, const T6& f6, const T7& f7, const T8& f8) { return GTEST_9_TUPLE_(T)(f0, f1, f2, f3, f4, f5, f6, f7, f8); } template inline GTEST_10_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2, const T3& f3, const T4& f4, const T5& f5, const T6& f6, const T7& f7, const T8& f8, const T9& f9) { return GTEST_10_TUPLE_(T)(f0, f1, f2, f3, f4, f5, f6, f7, f8, f9); } // 6.1.3.3 Tuple helper classes. template struct tuple_size; template struct tuple_size { static const int value = 0; }; template struct tuple_size { static const int value = 1; }; template struct tuple_size { static const int value = 2; }; template struct tuple_size { static const int value = 3; }; template struct tuple_size { static const int value = 4; }; template struct tuple_size { static const int value = 5; }; template struct tuple_size { static const int value = 6; }; template struct tuple_size { static const int value = 7; }; template struct tuple_size { static const int value = 8; }; template struct tuple_size { static const int value = 9; }; template struct tuple_size { static const int value = 10; }; template struct tuple_element { typedef typename gtest_internal::TupleElement< k < (tuple_size::value), k, Tuple>::type type; }; #define GTEST_TUPLE_ELEMENT_(k, Tuple) typename tuple_element::type // 6.1.3.4 Element access. namespace gtest_internal { template <> class Get<0> { public: template static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(0, Tuple)) Field(Tuple& t) { return t.f0_; } // NOLINT template static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(0, Tuple)) ConstField(const Tuple& t) { return t.f0_; } }; template <> class Get<1> { public: template static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(1, Tuple)) Field(Tuple& t) { return t.f1_; } // NOLINT template static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(1, Tuple)) ConstField(const Tuple& t) { return t.f1_; } }; template <> class Get<2> { public: template static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(2, Tuple)) Field(Tuple& t) { return t.f2_; } // NOLINT template static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(2, Tuple)) ConstField(const Tuple& t) { return t.f2_; } }; template <> class Get<3> { public: template static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(3, Tuple)) Field(Tuple& t) { return t.f3_; } // NOLINT template static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(3, Tuple)) ConstField(const Tuple& t) { return t.f3_; } }; template <> class Get<4> { public: template static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(4, Tuple)) Field(Tuple& t) { return t.f4_; } // NOLINT template static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(4, Tuple)) ConstField(const Tuple& t) { return t.f4_; } }; template <> class Get<5> { public: template static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(5, Tuple)) Field(Tuple& t) { return t.f5_; } // NOLINT template static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(5, Tuple)) ConstField(const Tuple& t) { return t.f5_; } }; template <> class Get<6> { public: template static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(6, Tuple)) Field(Tuple& t) { return t.f6_; } // NOLINT template static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(6, Tuple)) ConstField(const Tuple& t) { return t.f6_; } }; template <> class Get<7> { public: template static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(7, Tuple)) Field(Tuple& t) { return t.f7_; } // NOLINT template static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(7, Tuple)) ConstField(const Tuple& t) { return t.f7_; } }; template <> class Get<8> { public: template static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(8, Tuple)) Field(Tuple& t) { return t.f8_; } // NOLINT template static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(8, Tuple)) ConstField(const Tuple& t) { return t.f8_; } }; template <> class Get<9> { public: template static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(9, Tuple)) Field(Tuple& t) { return t.f9_; } // NOLINT template static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(9, Tuple)) ConstField(const Tuple& t) { return t.f9_; } }; } // namespace gtest_internal template GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(k, GTEST_10_TUPLE_(T))) get(GTEST_10_TUPLE_(T)& t) { return gtest_internal::Get::Field(t); } template GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(k, GTEST_10_TUPLE_(T))) get(const GTEST_10_TUPLE_(T)& t) { return gtest_internal::Get::ConstField(t); } // 6.1.3.5 Relational operators // We only implement == and !=, as we don't have a need for the rest yet. namespace gtest_internal { // SameSizeTuplePrefixComparator::Eq(t1, t2) returns true if the // first k fields of t1 equals the first k fields of t2. // SameSizeTuplePrefixComparator(k1, k2) would be a compiler error if // k1 != k2. template struct SameSizeTuplePrefixComparator; template <> struct SameSizeTuplePrefixComparator<0, 0> { template static bool Eq(const Tuple1& /* t1 */, const Tuple2& /* t2 */) { return true; } }; template struct SameSizeTuplePrefixComparator { template static bool Eq(const Tuple1& t1, const Tuple2& t2) { return SameSizeTuplePrefixComparator::Eq(t1, t2) && ::std::tr1::get(t1) == ::std::tr1::get(t2); } }; } // namespace gtest_internal template inline bool operator==(const GTEST_10_TUPLE_(T)& t, const GTEST_10_TUPLE_(U)& u) { return gtest_internal::SameSizeTuplePrefixComparator< tuple_size::value, tuple_size::value>::Eq(t, u); } template inline bool operator!=(const GTEST_10_TUPLE_(T)& t, const GTEST_10_TUPLE_(U)& u) { return !(t == u); } // 6.1.4 Pairs. // Unimplemented. } // namespace tr1 } // namespace std #undef GTEST_0_TUPLE_ #undef GTEST_1_TUPLE_ #undef GTEST_2_TUPLE_ #undef GTEST_3_TUPLE_ #undef GTEST_4_TUPLE_ #undef GTEST_5_TUPLE_ #undef GTEST_6_TUPLE_ #undef GTEST_7_TUPLE_ #undef GTEST_8_TUPLE_ #undef GTEST_9_TUPLE_ #undef GTEST_10_TUPLE_ #undef GTEST_0_TYPENAMES_ #undef GTEST_1_TYPENAMES_ #undef GTEST_2_TYPENAMES_ #undef GTEST_3_TYPENAMES_ #undef GTEST_4_TYPENAMES_ #undef GTEST_5_TYPENAMES_ #undef GTEST_6_TYPENAMES_ #undef GTEST_7_TYPENAMES_ #undef GTEST_8_TYPENAMES_ #undef GTEST_9_TYPENAMES_ #undef GTEST_10_TYPENAMES_ #undef GTEST_DECLARE_TUPLE_AS_FRIEND_ #undef GTEST_BY_REF_ #undef GTEST_ADD_REF_ #undef GTEST_TUPLE_ELEMENT_ #endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_ # elif GTEST_ENV_HAS_STD_TUPLE_ # include // C++11 puts its tuple into the ::std namespace rather than // ::std::tr1. gtest expects tuple to live in ::std::tr1, so put it there. // This causes undefined behavior, but supported compilers react in // the way we intend. namespace std { namespace tr1 { using ::std::get; using ::std::make_tuple; using ::std::tuple; using ::std::tuple_element; using ::std::tuple_size; } } # elif GTEST_OS_SYMBIAN // On Symbian, BOOST_HAS_TR1_TUPLE causes Boost's TR1 tuple library to // use STLport's tuple implementation, which unfortunately doesn't // work as the copy of STLport distributed with Symbian is incomplete. // By making sure BOOST_HAS_TR1_TUPLE is undefined, we force Boost to // use its own tuple implementation. # ifdef BOOST_HAS_TR1_TUPLE # undef BOOST_HAS_TR1_TUPLE # endif // BOOST_HAS_TR1_TUPLE // This prevents , which defines // BOOST_HAS_TR1_TUPLE, from being #included by Boost's . # define BOOST_TR1_DETAIL_CONFIG_HPP_INCLUDED # include # elif defined(__GNUC__) && (GTEST_GCC_VER_ >= 40000) // GCC 4.0+ implements tr1/tuple in the header. This does // not conform to the TR1 spec, which requires the header to be . # if !GTEST_HAS_RTTI && GTEST_GCC_VER_ < 40302 // Until version 4.3.2, gcc has a bug that causes , // which is #included by , to not compile when RTTI is // disabled. _TR1_FUNCTIONAL is the header guard for // . Hence the following #define is a hack to prevent // from being included. # define _TR1_FUNCTIONAL 1 # include # undef _TR1_FUNCTIONAL // Allows the user to #include // if he chooses to. # else # include // NOLINT # endif // !GTEST_HAS_RTTI && GTEST_GCC_VER_ < 40302 # else // If the compiler is not GCC 4.0+, we assume the user is using a // spec-conforming TR1 implementation. # include // NOLINT # endif // GTEST_USE_OWN_TR1_TUPLE #endif // GTEST_HAS_TR1_TUPLE // Determines whether clone(2) is supported. // Usually it will only be available on Linux, excluding // Linux on the Itanium architecture. // Also see http://linux.die.net/man/2/clone. #ifndef GTEST_HAS_CLONE // The user didn't tell us, so we need to figure it out. # if GTEST_OS_LINUX && !defined(__ia64__) # if GTEST_OS_LINUX_ANDROID // On Android, clone() is only available on ARM starting with Gingerbread. # if defined(__arm__) && __ANDROID_API__ >= 9 # define GTEST_HAS_CLONE 1 # else # define GTEST_HAS_CLONE 0 # endif # else # define GTEST_HAS_CLONE 1 # endif # else # define GTEST_HAS_CLONE 0 # endif // GTEST_OS_LINUX && !defined(__ia64__) #endif // GTEST_HAS_CLONE // Determines whether to support stream redirection. This is used to test // output correctness and to implement death tests. #ifndef GTEST_HAS_STREAM_REDIRECTION // By default, we assume that stream redirection is supported on all // platforms except known mobile ones. # if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_SYMBIAN # define GTEST_HAS_STREAM_REDIRECTION 0 # else # define GTEST_HAS_STREAM_REDIRECTION 1 # endif // !GTEST_OS_WINDOWS_MOBILE && !GTEST_OS_SYMBIAN #endif // GTEST_HAS_STREAM_REDIRECTION // Determines whether to support death tests. // Google Test does not support death tests for VC 7.1 and earlier as // abort() in a VC 7.1 application compiled as GUI in debug config // pops up a dialog window that cannot be suppressed programmatically. #if (GTEST_OS_LINUX || GTEST_OS_CYGWIN || GTEST_OS_SOLARIS || \ (GTEST_OS_MAC && !GTEST_OS_IOS) || GTEST_OS_IOS_SIMULATOR || \ (GTEST_OS_WINDOWS_DESKTOP && _MSC_VER >= 1400) || \ GTEST_OS_WINDOWS_MINGW || GTEST_OS_AIX || GTEST_OS_HPUX || \ GTEST_OS_OPENBSD || GTEST_OS_QNX) # define GTEST_HAS_DEATH_TEST 1 # include // NOLINT #endif // We don't support MSVC 7.1 with exceptions disabled now. Therefore // all the compilers we care about are adequate for supporting // value-parameterized tests. #define GTEST_HAS_PARAM_TEST 1 // Determines whether to support type-driven tests. // Typed tests need and variadic macros, which GCC, VC++ 8.0, // Sun Pro CC, IBM Visual Age, and HP aCC support. #if defined(__GNUC__) || (_MSC_VER >= 1400) || defined(__SUNPRO_CC) || \ defined(__IBMCPP__) || defined(__HP_aCC) # define GTEST_HAS_TYPED_TEST 1 # define GTEST_HAS_TYPED_TEST_P 1 #endif // Determines whether to support Combine(). This only makes sense when // value-parameterized tests are enabled. The implementation doesn't // work on Sun Studio since it doesn't understand templated conversion // operators. #if GTEST_HAS_PARAM_TEST && GTEST_HAS_TR1_TUPLE && !defined(__SUNPRO_CC) # define GTEST_HAS_COMBINE 1 #endif // Determines whether the system compiler uses UTF-16 for encoding wide strings. #define GTEST_WIDE_STRING_USES_UTF16_ \ (GTEST_OS_WINDOWS || GTEST_OS_CYGWIN || GTEST_OS_SYMBIAN || GTEST_OS_AIX) // Determines whether test results can be streamed to a socket. #if GTEST_OS_LINUX # define GTEST_CAN_STREAM_RESULTS_ 1 #endif // Defines some utility macros. // The GNU compiler emits a warning if nested "if" statements are followed by // an "else" statement and braces are not used to explicitly disambiguate the // "else" binding. This leads to problems with code like: // // if (gate) // ASSERT_*(condition) << "Some message"; // // The "switch (0) case 0:" idiom is used to suppress this. #ifdef __INTEL_COMPILER # define GTEST_AMBIGUOUS_ELSE_BLOCKER_ #else # define GTEST_AMBIGUOUS_ELSE_BLOCKER_ switch (0) case 0: default: // NOLINT #endif // Use this annotation at the end of a struct/class definition to // prevent the compiler from optimizing away instances that are never // used. This is useful when all interesting logic happens inside the // c'tor and / or d'tor. Example: // // struct Foo { // Foo() { ... } // } GTEST_ATTRIBUTE_UNUSED_; // // Also use it after a variable or parameter declaration to tell the // compiler the variable/parameter does not have to be used. #if defined(__GNUC__) && !defined(COMPILER_ICC) # define GTEST_ATTRIBUTE_UNUSED_ __attribute__ ((unused)) #else # define GTEST_ATTRIBUTE_UNUSED_ #endif // A macro to disallow operator= // This should be used in the private: declarations for a class. #define GTEST_DISALLOW_ASSIGN_(type)\ void operator=(type const &) // A macro to disallow copy constructor and operator= // This should be used in the private: declarations for a class. #define GTEST_DISALLOW_COPY_AND_ASSIGN_(type)\ type(type const &);\ GTEST_DISALLOW_ASSIGN_(type) // Tell the compiler to warn about unused return values for functions declared // with this macro. The macro should be used on function declarations // following the argument list: // // Sprocket* AllocateSprocket() GTEST_MUST_USE_RESULT_; #if defined(__GNUC__) && (GTEST_GCC_VER_ >= 30400) && !defined(COMPILER_ICC) # define GTEST_MUST_USE_RESULT_ __attribute__ ((warn_unused_result)) #else # define GTEST_MUST_USE_RESULT_ #endif // __GNUC__ && (GTEST_GCC_VER_ >= 30400) && !COMPILER_ICC // Determine whether the compiler supports Microsoft's Structured Exception // Handling. This is supported by several Windows compilers but generally // does not exist on any other system. #ifndef GTEST_HAS_SEH // The user didn't tell us, so we need to figure it out. # if defined(_MSC_VER) || defined(__BORLANDC__) // These two compilers are known to support SEH. # define GTEST_HAS_SEH 1 # else // Assume no SEH. # define GTEST_HAS_SEH 0 # endif #endif // GTEST_HAS_SEH #ifdef _MSC_VER # if GTEST_LINKED_AS_SHARED_LIBRARY # define GTEST_API_ __declspec(dllimport) # elif GTEST_CREATE_SHARED_LIBRARY # define GTEST_API_ __declspec(dllexport) # endif #endif // _MSC_VER #ifndef GTEST_API_ # define GTEST_API_ #endif #ifdef __GNUC__ // Ask the compiler to never inline a given function. # define GTEST_NO_INLINE_ __attribute__((noinline)) #else # define GTEST_NO_INLINE_ #endif // _LIBCPP_VERSION is defined by the libc++ library from the LLVM project. #if defined(__GLIBCXX__) || defined(_LIBCPP_VERSION) # define GTEST_HAS_CXXABI_H_ 1 #else # define GTEST_HAS_CXXABI_H_ 0 #endif namespace testing { class Message; namespace internal { // A secret type that Google Test users don't know about. It has no // definition on purpose. Therefore it's impossible to create a // Secret object, which is what we want. class Secret; // The GTEST_COMPILE_ASSERT_ macro can be used to verify that a compile time // expression is true. For example, you could use it to verify the // size of a static array: // // GTEST_COMPILE_ASSERT_(ARRAYSIZE(content_type_names) == CONTENT_NUM_TYPES, // content_type_names_incorrect_size); // // or to make sure a struct is smaller than a certain size: // // GTEST_COMPILE_ASSERT_(sizeof(foo) < 128, foo_too_large); // // The second argument to the macro is the name of the variable. If // the expression is false, most compilers will issue a warning/error // containing the name of the variable. template struct CompileAssert { }; #define GTEST_COMPILE_ASSERT_(expr, msg) \ typedef ::testing::internal::CompileAssert<(static_cast(expr))> \ msg[static_cast(expr) ? 1 : -1] GTEST_ATTRIBUTE_UNUSED_ // Implementation details of GTEST_COMPILE_ASSERT_: // // - GTEST_COMPILE_ASSERT_ works by defining an array type that has -1 // elements (and thus is invalid) when the expression is false. // // - The simpler definition // // #define GTEST_COMPILE_ASSERT_(expr, msg) typedef char msg[(expr) ? 1 : -1] // // does not work, as gcc supports variable-length arrays whose sizes // are determined at run-time (this is gcc's extension and not part // of the C++ standard). As a result, gcc fails to reject the // following code with the simple definition: // // int foo; // GTEST_COMPILE_ASSERT_(foo, msg); // not supposed to compile as foo is // // not a compile-time constant. // // - By using the type CompileAssert<(bool(expr))>, we ensures that // expr is a compile-time constant. (Template arguments must be // determined at compile-time.) // // - The outter parentheses in CompileAssert<(bool(expr))> are necessary // to work around a bug in gcc 3.4.4 and 4.0.1. If we had written // // CompileAssert // // instead, these compilers will refuse to compile // // GTEST_COMPILE_ASSERT_(5 > 0, some_message); // // (They seem to think the ">" in "5 > 0" marks the end of the // template argument list.) // // - The array size is (bool(expr) ? 1 : -1), instead of simply // // ((expr) ? 1 : -1). // // This is to avoid running into a bug in MS VC 7.1, which // causes ((0.0) ? 1 : -1) to incorrectly evaluate to 1. // StaticAssertTypeEqHelper is used by StaticAssertTypeEq defined in gtest.h. // // This template is declared, but intentionally undefined. template struct StaticAssertTypeEqHelper; template struct StaticAssertTypeEqHelper {}; #if GTEST_HAS_GLOBAL_STRING typedef ::string string; #else typedef ::std::string string; #endif // GTEST_HAS_GLOBAL_STRING #if GTEST_HAS_GLOBAL_WSTRING typedef ::wstring wstring; #elif GTEST_HAS_STD_WSTRING typedef ::std::wstring wstring; #endif // GTEST_HAS_GLOBAL_WSTRING // A helper for suppressing warnings on constant condition. It just // returns 'condition'. GTEST_API_ bool IsTrue(bool condition); // Defines scoped_ptr. // This implementation of scoped_ptr is PARTIAL - it only contains // enough stuff to satisfy Google Test's need. template class scoped_ptr { public: typedef T element_type; explicit scoped_ptr(T* p = NULL) : ptr_(p) {} ~scoped_ptr() { reset(); } T& operator*() const { return *ptr_; } T* operator->() const { return ptr_; } T* get() const { return ptr_; } T* release() { T* const ptr = ptr_; ptr_ = NULL; return ptr; } void reset(T* p = NULL) { if (p != ptr_) { if (IsTrue(sizeof(T) > 0)) { // Makes sure T is a complete type. delete ptr_; } ptr_ = p; } } private: T* ptr_; GTEST_DISALLOW_COPY_AND_ASSIGN_(scoped_ptr); }; // Defines RE. // A simple C++ wrapper for . It uses the POSIX Extended // Regular Expression syntax. class GTEST_API_ RE { public: // A copy constructor is required by the Standard to initialize object // references from r-values. RE(const RE& other) { Init(other.pattern()); } // Constructs an RE from a string. RE(const ::std::string& regex) { Init(regex.c_str()); } // NOLINT #if GTEST_HAS_GLOBAL_STRING RE(const ::string& regex) { Init(regex.c_str()); } // NOLINT #endif // GTEST_HAS_GLOBAL_STRING RE(const char* regex) { Init(regex); } // NOLINT ~RE(); // Returns the string representation of the regex. const char* pattern() const { return pattern_; } // FullMatch(str, re) returns true iff regular expression re matches // the entire str. // PartialMatch(str, re) returns true iff regular expression re // matches a substring of str (including str itself). // // TODO(wan@google.com): make FullMatch() and PartialMatch() work // when str contains NUL characters. static bool FullMatch(const ::std::string& str, const RE& re) { return FullMatch(str.c_str(), re); } static bool PartialMatch(const ::std::string& str, const RE& re) { return PartialMatch(str.c_str(), re); } #if GTEST_HAS_GLOBAL_STRING static bool FullMatch(const ::string& str, const RE& re) { return FullMatch(str.c_str(), re); } static bool PartialMatch(const ::string& str, const RE& re) { return PartialMatch(str.c_str(), re); } #endif // GTEST_HAS_GLOBAL_STRING static bool FullMatch(const char* str, const RE& re); static bool PartialMatch(const char* str, const RE& re); private: void Init(const char* regex); // We use a const char* instead of an std::string, as Google Test used to be // used where std::string is not available. TODO(wan@google.com): change to // std::string. const char* pattern_; bool is_valid_; #if GTEST_USES_POSIX_RE regex_t full_regex_; // For FullMatch(). regex_t partial_regex_; // For PartialMatch(). #else // GTEST_USES_SIMPLE_RE const char* full_pattern_; // For FullMatch(); #endif GTEST_DISALLOW_ASSIGN_(RE); }; // Formats a source file path and a line number as they would appear // in an error message from the compiler used to compile this code. GTEST_API_ ::std::string FormatFileLocation(const char* file, int line); // Formats a file location for compiler-independent XML output. // Although this function is not platform dependent, we put it next to // FormatFileLocation in order to contrast the two functions. GTEST_API_ ::std::string FormatCompilerIndependentFileLocation(const char* file, int line); // Defines logging utilities: // GTEST_LOG_(severity) - logs messages at the specified severity level. The // message itself is streamed into the macro. // LogToStderr() - directs all log messages to stderr. // FlushInfoLog() - flushes informational log messages. enum GTestLogSeverity { GTEST_INFO, GTEST_WARNING, GTEST_ERROR, GTEST_FATAL }; // Formats log entry severity, provides a stream object for streaming the // log message, and terminates the message with a newline when going out of // scope. class GTEST_API_ GTestLog { public: GTestLog(GTestLogSeverity severity, const char* file, int line); // Flushes the buffers and, if severity is GTEST_FATAL, aborts the program. ~GTestLog(); ::std::ostream& GetStream() { return ::std::cerr; } private: const GTestLogSeverity severity_; GTEST_DISALLOW_COPY_AND_ASSIGN_(GTestLog); }; #define GTEST_LOG_(severity) \ ::testing::internal::GTestLog(::testing::internal::GTEST_##severity, \ __FILE__, __LINE__).GetStream() inline void LogToStderr() {} inline void FlushInfoLog() { fflush(NULL); } // INTERNAL IMPLEMENTATION - DO NOT USE. // // GTEST_CHECK_ is an all-mode assert. It aborts the program if the condition // is not satisfied. // Synopsys: // GTEST_CHECK_(boolean_condition); // or // GTEST_CHECK_(boolean_condition) << "Additional message"; // // This checks the condition and if the condition is not satisfied // it prints message about the condition violation, including the // condition itself, plus additional message streamed into it, if any, // and then it aborts the program. It aborts the program irrespective of // whether it is built in the debug mode or not. #define GTEST_CHECK_(condition) \ GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ if (::testing::internal::IsTrue(condition)) \ ; \ else \ GTEST_LOG_(FATAL) << "Condition " #condition " failed. " // An all-mode assert to verify that the given POSIX-style function // call returns 0 (indicating success). Known limitation: this // doesn't expand to a balanced 'if' statement, so enclose the macro // in {} if you need to use it as the only statement in an 'if' // branch. #define GTEST_CHECK_POSIX_SUCCESS_(posix_call) \ if (const int gtest_error = (posix_call)) \ GTEST_LOG_(FATAL) << #posix_call << "failed with error " \ << gtest_error // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. // // Use ImplicitCast_ as a safe version of static_cast for upcasting in // the type hierarchy (e.g. casting a Foo* to a SuperclassOfFoo* or a // const Foo*). When you use ImplicitCast_, the compiler checks that // the cast is safe. Such explicit ImplicitCast_s are necessary in // surprisingly many situations where C++ demands an exact type match // instead of an argument type convertable to a target type. // // The syntax for using ImplicitCast_ is the same as for static_cast: // // ImplicitCast_(expr) // // ImplicitCast_ would have been part of the C++ standard library, // but the proposal was submitted too late. It will probably make // its way into the language in the future. // // This relatively ugly name is intentional. It prevents clashes with // similar functions users may have (e.g., implicit_cast). The internal // namespace alone is not enough because the function can be found by ADL. template inline To ImplicitCast_(To x) { return x; } // When you upcast (that is, cast a pointer from type Foo to type // SuperclassOfFoo), it's fine to use ImplicitCast_<>, since upcasts // always succeed. When you downcast (that is, cast a pointer from // type Foo to type SubclassOfFoo), static_cast<> isn't safe, because // how do you know the pointer is really of type SubclassOfFoo? It // could be a bare Foo, or of type DifferentSubclassOfFoo. Thus, // when you downcast, you should use this macro. In debug mode, we // use dynamic_cast<> to double-check the downcast is legal (we die // if it's not). In normal mode, we do the efficient static_cast<> // instead. Thus, it's important to test in debug mode to make sure // the cast is legal! // This is the only place in the code we should use dynamic_cast<>. // In particular, you SHOULDN'T be using dynamic_cast<> in order to // do RTTI (eg code like this: // if (dynamic_cast(foo)) HandleASubclass1Object(foo); // if (dynamic_cast(foo)) HandleASubclass2Object(foo); // You should design the code some other way not to need this. // // This relatively ugly name is intentional. It prevents clashes with // similar functions users may have (e.g., down_cast). The internal // namespace alone is not enough because the function can be found by ADL. template // use like this: DownCast_(foo); inline To DownCast_(From* f) { // so we only accept pointers // Ensures that To is a sub-type of From *. This test is here only // for compile-time type checking, and has no overhead in an // optimized build at run-time, as it will be optimized away // completely. if (false) { const To to = NULL; ::testing::internal::ImplicitCast_(to); } #if GTEST_HAS_RTTI // RTTI: debug mode only! GTEST_CHECK_(f == NULL || dynamic_cast(f) != NULL); #endif return static_cast(f); } // Downcasts the pointer of type Base to Derived. // Derived must be a subclass of Base. The parameter MUST // point to a class of type Derived, not any subclass of it. // When RTTI is available, the function performs a runtime // check to enforce this. template Derived* CheckedDowncastToActualType(Base* base) { #if GTEST_HAS_RTTI GTEST_CHECK_(typeid(*base) == typeid(Derived)); return dynamic_cast(base); // NOLINT #else return static_cast(base); // Poor man's downcast. #endif } #if GTEST_HAS_STREAM_REDIRECTION // Defines the stderr capturer: // CaptureStdout - starts capturing stdout. // GetCapturedStdout - stops capturing stdout and returns the captured string. // CaptureStderr - starts capturing stderr. // GetCapturedStderr - stops capturing stderr and returns the captured string. // GTEST_API_ void CaptureStdout(); GTEST_API_ std::string GetCapturedStdout(); GTEST_API_ void CaptureStderr(); GTEST_API_ std::string GetCapturedStderr(); #endif // GTEST_HAS_STREAM_REDIRECTION #if GTEST_HAS_DEATH_TEST const ::std::vector& GetInjectableArgvs(); void SetInjectableArgvs(const ::std::vector* new_argvs); // A copy of all command line arguments. Set by InitGoogleTest(). 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. inline void SleepMilliseconds(int n) { const timespec time = { 0, // 0 seconds. n * 1000L * 1000L, // And n ms. }; nanosleep(&time, NULL); } // Allows a controller thread to pause execution of newly created // threads until notified. Instances of this class must be created // and destroyed in the controller thread. // // This class is only for testing Google Test's own constructs. Do not // use it in user tests, either directly or indirectly. class Notification { public: Notification() : notified_(false) { GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_init(&mutex_, NULL)); } ~Notification() { pthread_mutex_destroy(&mutex_); } // Notifies all threads created with this notification to start. Must // be called from the controller thread. void Notify() { pthread_mutex_lock(&mutex_); notified_ = true; pthread_mutex_unlock(&mutex_); } // Blocks until the controller thread notifies. Must be called from a test // thread. void WaitForNotification() { for (;;) { pthread_mutex_lock(&mutex_); const bool notified = notified_; pthread_mutex_unlock(&mutex_); if (notified) break; SleepMilliseconds(10); } } private: pthread_mutex_t mutex_; bool notified_; GTEST_DISALLOW_COPY_AND_ASSIGN_(Notification); }; // As a C-function, ThreadFuncWithCLinkage cannot be templated itself. // Consequently, it cannot select a correct instantiation of ThreadWithParam // in order to call its Run(). Introducing ThreadWithParamBase as a // non-templated base class for ThreadWithParam allows us to bypass this // problem. class ThreadWithParamBase { public: virtual ~ThreadWithParamBase() {} virtual void Run() = 0; }; // pthread_create() accepts a pointer to a function type with the C linkage. // According to the Standard (7.5/1), function types with different linkages // are different even if they are otherwise identical. Some compilers (for // example, SunStudio) treat them as different types. Since class methods // cannot be defined with C-linkage we need to define a free C-function to // pass into pthread_create(). extern "C" inline void* ThreadFuncWithCLinkage(void* thread) { static_cast(thread)->Run(); return NULL; } // Helper class for testing Google Test's multi-threading constructs. // To use it, write: // // void ThreadFunc(int param) { /* Do things with param */ } // Notification thread_can_start; // ... // // The thread_can_start parameter is optional; you can supply NULL. // ThreadWithParam thread(&ThreadFunc, 5, &thread_can_start); // thread_can_start.Notify(); // // These classes are only for testing Google Test's own constructs. Do // not use them in user tests, either directly or indirectly. template class ThreadWithParam : public ThreadWithParamBase { public: typedef void (*UserThreadFunc)(T); ThreadWithParam( UserThreadFunc func, T param, Notification* thread_can_start) : func_(func), param_(param), thread_can_start_(thread_can_start), finished_(false) { ThreadWithParamBase* const base = this; // The thread can be created only after all fields except thread_ // have been initialized. GTEST_CHECK_POSIX_SUCCESS_( pthread_create(&thread_, 0, &ThreadFuncWithCLinkage, base)); } ~ThreadWithParam() { Join(); } void Join() { if (!finished_) { GTEST_CHECK_POSIX_SUCCESS_(pthread_join(thread_, 0)); finished_ = true; } } virtual void Run() { if (thread_can_start_ != NULL) thread_can_start_->WaitForNotification(); func_(param_); } private: const UserThreadFunc func_; // User-supplied thread function. const T param_; // User-supplied parameter to the thread function. // When non-NULL, used to block execution until the controller thread // notifies. Notification* const thread_can_start_; bool finished_; // true iff we know that the thread function has finished. pthread_t thread_; // The native thread object. GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadWithParam); }; // MutexBase and Mutex implement mutex on pthreads-based platforms. They // are used in conjunction with class MutexLock: // // Mutex mutex; // ... // MutexLock lock(&mutex); // Acquires the mutex and releases it at the end // // of the current scope. // // MutexBase implements behavior for both statically and dynamically // allocated mutexes. Do not use MutexBase directly. Instead, write // the following to define a static mutex: // // GTEST_DEFINE_STATIC_MUTEX_(g_some_mutex); // // You can forward declare a static mutex like this: // // GTEST_DECLARE_STATIC_MUTEX_(g_some_mutex); // // To create a dynamic mutex, just define an object of type Mutex. class MutexBase { public: // Acquires this mutex. void Lock() { GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_lock(&mutex_)); owner_ = pthread_self(); has_owner_ = true; } // Releases this mutex. void Unlock() { // Since the lock is being released the owner_ field should no longer be // considered valid. We don't protect writing to has_owner_ here, as it's // the caller's responsibility to ensure that the current thread holds the // mutex when this is called. has_owner_ = false; GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_unlock(&mutex_)); } // Does nothing if the current thread holds the mutex. Otherwise, crashes // with high probability. void AssertHeld() const { GTEST_CHECK_(has_owner_ && pthread_equal(owner_, pthread_self())) << "The current thread is not holding the mutex @" << this; } // A static mutex may be used before main() is entered. It may even // be used before the dynamic initialization stage. Therefore we // must be able to initialize a static mutex object at link time. // This means MutexBase has to be a POD and its member variables // have to be public. public: pthread_mutex_t mutex_; // The underlying pthread mutex. // has_owner_ indicates whether the owner_ field below contains a valid thread // ID and is therefore safe to inspect (e.g., to use in pthread_equal()). All // accesses to the owner_ field should be protected by a check of this field. // An alternative might be to memset() owner_ to all zeros, but there's no // guarantee that a zero'd pthread_t is necessarily invalid or even different // from pthread_self(). bool has_owner_; pthread_t owner_; // The thread holding the mutex. }; // Forward-declares a static mutex. # define GTEST_DECLARE_STATIC_MUTEX_(mutex) \ extern ::testing::internal::MutexBase mutex // Defines and statically (i.e. at link time) initializes a static mutex. // The initialization list here does not explicitly initialize each field, // instead relying on default initialization for the unspecified fields. In // 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 } // The Mutex class can only be used for mutexes created at runtime. It // shares its API with MutexBase otherwise. class Mutex : public MutexBase { public: Mutex() { GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_init(&mutex_, NULL)); has_owner_ = false; } ~Mutex() { GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_destroy(&mutex_)); } private: GTEST_DISALLOW_COPY_AND_ASSIGN_(Mutex); }; // We cannot name this class MutexLock as the ctor declaration would // conflict with a macro named MutexLock, which is defined on some // platforms. Hence the typedef trick below. class GTestMutexLock { public: explicit GTestMutexLock(MutexBase* mutex) : mutex_(mutex) { mutex_->Lock(); } ~GTestMutexLock() { mutex_->Unlock(); } private: MutexBase* const mutex_; GTEST_DISALLOW_COPY_AND_ASSIGN_(GTestMutexLock); }; typedef GTestMutexLock MutexLock; // Helpers for ThreadLocal. // pthread_key_create() requires DeleteThreadLocalValue() to have // C-linkage. Therefore it cannot be templatized to access // ThreadLocal. Hence the need for class // ThreadLocalValueHolderBase. class ThreadLocalValueHolderBase { public: virtual ~ThreadLocalValueHolderBase() {} }; // Called by pthread to delete thread-local data stored by // pthread_setspecific(). extern "C" inline void DeleteThreadLocalValue(void* value_holder) { delete static_cast(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() { // Destroys the managed object for the current thread, if any. DeleteThreadLocalValue(pthread_getspecific(key_)); // Releases resources associated with the key. This will *not* // delete managed objects for other threads. GTEST_CHECK_POSIX_SUCCESS_(pthread_key_delete(key_)); } T* pointer() { return GetOrCreateValue(); } const T* pointer() const { return GetOrCreateValue(); } const T& get() const { return *pointer(); } void set(const T& value) { *pointer() = value; } private: // Holds a value of type T. class ValueHolder : public ThreadLocalValueHolderBase { public: explicit ValueHolder(const T& value) : value_(value) {} T* pointer() { return &value_; } private: T value_; GTEST_DISALLOW_COPY_AND_ASSIGN_(ValueHolder); }; static pthread_key_t CreateKey() { pthread_key_t key; // When a thread exits, DeleteThreadLocalValue() will be called on // the object managed for that thread. GTEST_CHECK_POSIX_SUCCESS_( pthread_key_create(&key, &DeleteThreadLocalValue)); return key; } T* GetOrCreateValue() const { ThreadLocalValueHolderBase* const holder = static_cast(pthread_getspecific(key_)); if (holder != NULL) { return CheckedDowncastToActualType(holder)->pointer(); } ValueHolder* const new_holder = new ValueHolder(default_); ThreadLocalValueHolderBase* const holder_base = new_holder; GTEST_CHECK_POSIX_SUCCESS_(pthread_setspecific(key_, holder_base)); return new_holder->pointer(); } // A key pthreads uses for looking up per-thread values. const pthread_key_t key_; const T default_; // The default value for each thread. GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadLocal); }; # define GTEST_IS_THREADSAFE 1 #else // GTEST_HAS_PTHREAD // A dummy implementation of synchronization primitives (mutex, lock, // and thread-local variable). Necessary for compiling Google Test where // mutex is not supported - using Google Test in multiple threads is not // supported on such platforms. class Mutex { public: Mutex() {} void Lock() {} void Unlock() {} void AssertHeld() const {} }; # define GTEST_DECLARE_STATIC_MUTEX_(mutex) \ extern ::testing::internal::Mutex mutex # define GTEST_DEFINE_STATIC_MUTEX_(mutex) ::testing::internal::Mutex mutex class GTestMutexLock { public: explicit GTestMutexLock(Mutex*) {} // NOLINT }; typedef GTestMutexLock MutexLock; template class ThreadLocal { public: ThreadLocal() : value_() {} explicit ThreadLocal(const T& value) : value_(value) {} T* pointer() { return &value_; } const T* pointer() const { return &value_; } const T& get() const { return value_; } void set(const T& value) { value_ = value; } private: T value_; }; // The above synchronization primitives have dummy implementations. // Therefore Google Test is not thread-safe. # define GTEST_IS_THREADSAFE 0 #endif // GTEST_HAS_PTHREAD // Returns the number of threads running in the process, or 0 to indicate that // we cannot detect it. GTEST_API_ size_t GetThreadCount(); // Passing non-POD classes through ellipsis (...) crashes the ARM // compiler and generates a warning in Sun Studio. The Nokia Symbian // and the IBM XL C/C++ compiler try to instantiate a copy constructor // for objects passed through ellipsis (...), failing for uncopyable // objects. We define this to ensure that only POD is passed through // ellipsis on these systems. #if defined(__SYMBIAN32__) || defined(__IBMCPP__) || defined(__SUNPRO_CC) // We lose support for NULL detection where the compiler doesn't like // passing non-POD classes through ellipsis (...). # define GTEST_ELLIPSIS_NEEDS_POD_ 1 #else # define GTEST_CAN_COMPARE_NULL 1 #endif // The Nokia Symbian and IBM XL C/C++ compilers cannot decide between // const T& and const T* in a function template. These compilers // _can_ decide between class template specializations for T and T*, // so a tr1::type_traits-like is_pointer works. #if defined(__SYMBIAN32__) || defined(__IBMCPP__) # define GTEST_NEEDS_IS_POINTER_ 1 #endif template struct bool_constant { typedef bool_constant type; static const bool value = bool_value; }; template const bool bool_constant::value; typedef bool_constant false_type; typedef bool_constant true_type; template struct is_pointer : public false_type {}; template struct is_pointer : public true_type {}; template struct IteratorTraits { typedef typename Iterator::value_type value_type; }; template struct IteratorTraits { typedef T value_type; }; template struct IteratorTraits { typedef T value_type; }; #if GTEST_OS_WINDOWS # define GTEST_PATH_SEP_ "\\" # define GTEST_HAS_ALT_PATH_SEP_ 1 // The biggest signed integer type the compiler supports. typedef __int64 BiggestInt; #else # define GTEST_PATH_SEP_ "/" # define GTEST_HAS_ALT_PATH_SEP_ 0 typedef long long BiggestInt; // NOLINT #endif // GTEST_OS_WINDOWS // Utilities for char. // isspace(int ch) and friends accept an unsigned char or EOF. char // may be signed, depending on the compiler (or compiler flags). // Therefore we need to cast a char to unsigned char before calling // isspace(), etc. inline bool IsAlpha(char ch) { return isalpha(static_cast(ch)) != 0; } inline bool IsAlNum(char ch) { return isalnum(static_cast(ch)) != 0; } inline bool IsDigit(char ch) { return isdigit(static_cast(ch)) != 0; } inline bool IsLower(char ch) { return islower(static_cast(ch)) != 0; } inline bool IsSpace(char ch) { return isspace(static_cast(ch)) != 0; } inline bool IsUpper(char ch) { return isupper(static_cast(ch)) != 0; } inline bool IsXDigit(char ch) { return isxdigit(static_cast(ch)) != 0; } inline bool IsXDigit(wchar_t ch) { const unsigned char low_byte = static_cast(ch); return ch == low_byte && isxdigit(low_byte) != 0; } inline char ToLower(char ch) { return static_cast(tolower(static_cast(ch))); } inline char ToUpper(char ch) { return static_cast(toupper(static_cast(ch))); } // The testing::internal::posix namespace holds wrappers for common // POSIX functions. These wrappers hide the differences between // Windows/MSVC and POSIX systems. Since some compilers define these // standard functions as macros, the wrapper cannot have the same name // as the wrapped function. namespace posix { // Functions with a different name on Windows. #if GTEST_OS_WINDOWS typedef struct _stat StatStruct; # ifdef __BORLANDC__ inline int IsATTY(int fd) { return isatty(fd); } inline int StrCaseCmp(const char* s1, const char* s2) { return stricmp(s1, s2); } inline char* StrDup(const char* src) { return strdup(src); } # else // !__BORLANDC__ # if GTEST_OS_WINDOWS_MOBILE inline int IsATTY(int /* fd */) { return 0; } # else inline int IsATTY(int fd) { return _isatty(fd); } # endif // GTEST_OS_WINDOWS_MOBILE inline int StrCaseCmp(const char* s1, const char* s2) { return _stricmp(s1, s2); } inline char* StrDup(const char* src) { return _strdup(src); } # endif // __BORLANDC__ # if GTEST_OS_WINDOWS_MOBILE inline int FileNo(FILE* file) { return reinterpret_cast(_fileno(file)); } // Stat(), RmDir(), and IsDir() are not needed on Windows CE at this // time and thus not defined there. # else inline int FileNo(FILE* file) { return _fileno(file); } inline int Stat(const char* path, StatStruct* buf) { return _stat(path, buf); } inline int RmDir(const char* dir) { return _rmdir(dir); } inline bool IsDir(const StatStruct& st) { return (_S_IFDIR & st.st_mode) != 0; } # endif // GTEST_OS_WINDOWS_MOBILE #else typedef struct stat StatStruct; inline int FileNo(FILE* file) { return fileno(file); } inline int IsATTY(int fd) { return isatty(fd); } inline int Stat(const char* path, StatStruct* buf) { return stat(path, buf); } inline int StrCaseCmp(const char* s1, const char* s2) { return strcasecmp(s1, s2); } inline char* StrDup(const char* src) { return strdup(src); } inline int RmDir(const char* dir) { return rmdir(dir); } inline bool IsDir(const StatStruct& st) { return S_ISDIR(st.st_mode); } #endif // GTEST_OS_WINDOWS // Functions deprecated by MSVC 8.0. #ifdef _MSC_VER // Temporarily disable warning 4996 (deprecated function). # pragma warning(push) # pragma warning(disable:4996) #endif inline const char* StrNCpy(char* dest, const char* src, size_t n) { return strncpy(dest, src, n); } // ChDir(), FReopen(), FDOpen(), Read(), Write(), Close(), and // StrError() aren't needed on Windows CE at this time and thus not // defined there. #if !GTEST_OS_WINDOWS_MOBILE inline int ChDir(const char* dir) { return chdir(dir); } #endif inline FILE* FOpen(const char* path, const char* mode) { return fopen(path, mode); } #if !GTEST_OS_WINDOWS_MOBILE inline FILE *FReopen(const char* path, const char* mode, FILE* stream) { return freopen(path, mode, stream); } inline FILE* FDOpen(int fd, const char* mode) { return fdopen(fd, mode); } #endif inline int FClose(FILE* fp) { return fclose(fp); } #if !GTEST_OS_WINDOWS_MOBILE inline int Read(int fd, void* buf, unsigned int count) { return static_cast(read(fd, buf, count)); } inline int Write(int fd, const void* buf, unsigned int count) { return static_cast(write(fd, buf, count)); } inline int Close(int fd) { return close(fd); } inline const char* StrError(int errnum) { return strerror(errnum); } #endif inline const char* GetEnv(const char* name) { #if GTEST_OS_WINDOWS_MOBILE // We are on Windows CE, which has no environment variables. return NULL; #elif defined(__BORLANDC__) || defined(__SunOS_5_8) || defined(__SunOS_5_9) // Environment variables which we programmatically clear will be set to the // empty string rather than unset (NULL). Handle that case. const char* const env = getenv(name); return (env != NULL && env[0] != '\0') ? env : NULL; #else return getenv(name); #endif } #ifdef _MSC_VER # pragma warning(pop) // Restores the warning state. #endif #if GTEST_OS_WINDOWS_MOBILE // Windows CE has no C library. The abort() function is used in // several places in Google Test. This implementation provides a reasonable // imitation of standard behaviour. void Abort(); #else inline void Abort() { abort(); } #endif // GTEST_OS_WINDOWS_MOBILE } // namespace posix // MSVC "deprecates" snprintf and issues warnings wherever it is used. In // order to avoid these warnings, we need to use _snprintf or _snprintf_s on // MSVC-based platforms. We map the GTEST_SNPRINTF_ macro to the appropriate // function in order to achieve that. We use macro definition here because // snprintf is a variadic function. #if _MSC_VER >= 1400 && !GTEST_OS_WINDOWS_MOBILE // MSVC 2005 and above support variadic macros. # define GTEST_SNPRINTF_(buffer, size, format, ...) \ _snprintf_s(buffer, size, size, format, __VA_ARGS__) #elif defined(_MSC_VER) // Windows CE does not define _snprintf_s and MSVC prior to 2005 doesn't // complain about _snprintf. # define GTEST_SNPRINTF_ _snprintf #else # define GTEST_SNPRINTF_ snprintf #endif // The maximum number a BiggestInt can represent. This definition // works no matter BiggestInt is represented in one's complement or // two's complement. // // We cannot rely on numeric_limits in STL, as __int64 and long long // are not part of standard C++ and numeric_limits doesn't need to be // defined for them. const BiggestInt kMaxBiggestInt = ~(static_cast(1) << (8*sizeof(BiggestInt) - 1)); // This template class serves as a compile-time function from size to // type. It maps a size in bytes to a primitive type with that // size. e.g. // // TypeWithSize<4>::UInt // // is typedef-ed to be unsigned int (unsigned integer made up of 4 // bytes). // // Such functionality should belong to STL, but I cannot find it // there. // // Google Test uses this class in the implementation of floating-point // comparison. // // For now it only handles UInt (unsigned int) as that's all Google Test // needs. Other types can be easily added in the future if need // arises. template class TypeWithSize { public: // This prevents the user from using TypeWithSize with incorrect // values of N. typedef void UInt; }; // The specialization for size 4. template <> class TypeWithSize<4> { public: // unsigned int has size 4 in both gcc and MSVC. // // As base/basictypes.h doesn't compile on Windows, we cannot use // uint32, uint64, and etc here. typedef int Int; typedef unsigned int UInt; }; // The specialization for size 8. template <> class TypeWithSize<8> { public: #if GTEST_OS_WINDOWS typedef __int64 Int; typedef unsigned __int64 UInt; #else typedef long long Int; // NOLINT typedef unsigned long long UInt; // NOLINT #endif // GTEST_OS_WINDOWS }; // Integer types of known sizes. typedef TypeWithSize<4>::Int Int32; typedef TypeWithSize<4>::UInt UInt32; typedef TypeWithSize<8>::Int Int64; typedef TypeWithSize<8>::UInt UInt64; typedef TypeWithSize<8>::Int TimeInMillis; // Represents time in milliseconds. // Utilities for command line flags and environment variables. // Macro for referencing flags. #define GTEST_FLAG(name) FLAGS_gtest_##name // Macros for declaring flags. #define GTEST_DECLARE_bool_(name) GTEST_API_ extern bool GTEST_FLAG(name) #define GTEST_DECLARE_int32_(name) \ GTEST_API_ extern ::testing::internal::Int32 GTEST_FLAG(name) #define GTEST_DECLARE_string_(name) \ GTEST_API_ extern ::std::string GTEST_FLAG(name) // Macros for defining flags. #define GTEST_DEFINE_bool_(name, default_val, doc) \ GTEST_API_ bool GTEST_FLAG(name) = (default_val) #define GTEST_DEFINE_int32_(name, default_val, doc) \ GTEST_API_ ::testing::internal::Int32 GTEST_FLAG(name) = (default_val) #define GTEST_DEFINE_string_(name, default_val, doc) \ GTEST_API_ ::std::string GTEST_FLAG(name) = (default_val) // Thread annotations #define GTEST_EXCLUSIVE_LOCK_REQUIRED_(locks) #define GTEST_LOCK_EXCLUDED_(locks) // Parses 'str' for a 32-bit signed integer. If successful, writes the result // to *value and returns true; otherwise leaves *value unchanged and returns // false. // TODO(chandlerc): Find a better way to refactor flag and environment parsing // out of both gtest-port.cc and gtest.cc to avoid exporting this utility // function. bool ParseInt32(const Message& src_text, const char* str, Int32* value); // Parses a bool/Int32/string from the environment variable // corresponding to the given Google Test flag. bool BoolFromGTestEnv(const char* flag, bool default_val); GTEST_API_ Int32 Int32FromGTestEnv(const char* flag, Int32 default_val); const char* StringFromGTestEnv(const char* flag, const char* default_val); } // namespace internal } // namespace testing #endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_ #if GTEST_OS_LINUX # include # include # include # include #endif // GTEST_OS_LINUX #if GTEST_HAS_EXCEPTIONS # include #endif #include #include #include #include #include #include // Copyright 2005, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: wan@google.com (Zhanyong Wan) // // The Google C++ Testing Framework (Google Test) // // This header file defines the Message class. // // IMPORTANT NOTE: Due to limitation of the C++ language, we have to // leave some internal implementation details in this header file. // They are clearly marked by comments like this: // // // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. // // Such code is NOT meant to be used by a user directly, and is subject // to CHANGE WITHOUT NOTICE. Therefore DO NOT DEPEND ON IT in a user // program! #ifndef GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_ #define GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_ #include // Ensures that there is at least one operator<< in the global namespace. // See Message& operator<<(...) below for why. void operator<<(const testing::internal::Secret&, int); namespace testing { // The Message class works like an ostream repeater. // // Typical usage: // // 1. You stream a bunch of values to a Message object. // It will remember the text in a stringstream. // 2. Then you stream the Message object to an ostream. // This causes the text in the Message to be streamed // to the ostream. // // For example; // // testing::Message foo; // foo << 1 << " != " << 2; // std::cout << foo; // // will print "1 != 2". // // Message is not intended to be inherited from. In particular, its // destructor is not virtual. // // Note that stringstream behaves differently in gcc and in MSVC. You // can stream a NULL char pointer to it in the former, but not in the // latter (it causes an access violation if you do). The Message // class hides this difference by treating a NULL char pointer as // "(null)". class GTEST_API_ Message { private: // The type of basic IO manipulators (endl, ends, and flush) for // narrow streams. typedef std::ostream& (*BasicNarrowIoManip)(std::ostream&); public: // Constructs an empty Message. Message(); // Copy constructor. Message(const Message& msg) : ss_(new ::std::stringstream) { // NOLINT *ss_ << msg.GetString(); } // Constructs a Message from a C-string. explicit Message(const char* str) : ss_(new ::std::stringstream) { *ss_ << str; } #if GTEST_OS_SYMBIAN // Streams a value (either a pointer or not) to this object. template inline Message& operator <<(const T& value) { StreamHelper(typename internal::is_pointer::type(), value); return *this; } #else // Streams a non-pointer value to this object. template inline Message& operator <<(const T& val) { // Some libraries overload << for STL containers. These // overloads are defined in the global namespace instead of ::std. // // C++'s symbol lookup rule (i.e. Koenig lookup) says that these // overloads are visible in either the std namespace or the global // namespace, but not other namespaces, including the testing // namespace which Google Test's Message class is in. // // To allow STL containers (and other types that has a << operator // defined in the global namespace) to be used in Google Test // assertions, testing::Message must access the custom << operator // from the global namespace. With this using declaration, // overloads of << defined in the global namespace and those // visible via Koenig lookup are both exposed in this function. using ::operator <<; *ss_ << val; return *this; } // Streams a pointer value to this object. // // This function is an overload of the previous one. When you // stream a pointer to a Message, this definition will be used as it // is more specialized. (The C++ Standard, section // [temp.func.order].) If you stream a non-pointer, then the // previous definition will be used. // // The reason for this overload is that streaming a NULL pointer to // ostream is undefined behavior. Depending on the compiler, you // may get "0", "(nil)", "(null)", or an access violation. To // ensure consistent result across compilers, we always treat NULL // as "(null)". template inline Message& operator <<(T* const& pointer) { // NOLINT if (pointer == NULL) { *ss_ << "(null)"; } else { *ss_ << pointer; } return *this; } #endif // GTEST_OS_SYMBIAN // Since the basic IO manipulators are overloaded for both narrow // and wide streams, we have to provide this specialized definition // of operator <<, even though its body is the same as the // templatized version above. Without this definition, streaming // endl or other basic IO manipulators to Message will confuse the // compiler. Message& operator <<(BasicNarrowIoManip val) { *ss_ << val; return *this; } // Instead of 1/0, we want to see true/false for bool values. Message& operator <<(bool b) { return *this << (b ? "true" : "false"); } // These two overloads allow streaming a wide C string to a Message // using the UTF-8 encoding. Message& operator <<(const wchar_t* wide_c_str); Message& operator <<(wchar_t* wide_c_str); #if GTEST_HAS_STD_WSTRING // Converts the given wide string to a narrow string using the UTF-8 // encoding, and streams the result to this Message object. Message& operator <<(const ::std::wstring& wstr); #endif // GTEST_HAS_STD_WSTRING #if GTEST_HAS_GLOBAL_WSTRING // Converts the given wide string to a narrow string using the UTF-8 // encoding, and streams the result to this Message object. Message& operator <<(const ::wstring& wstr); #endif // GTEST_HAS_GLOBAL_WSTRING // Gets the text streamed to this object so far as an std::string. // Each '\0' character in the buffer is replaced with "\\0". // // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. std::string GetString() const; private: #if GTEST_OS_SYMBIAN // These are needed as the Nokia Symbian Compiler cannot decide between // const T& and const T* in a function template. The Nokia compiler _can_ // decide between class template specializations for T and T*, so a // tr1::type_traits-like is_pointer works, and we can overload on that. template inline void StreamHelper(internal::true_type /*is_pointer*/, T* pointer) { if (pointer == NULL) { *ss_ << "(null)"; } else { *ss_ << pointer; } } template inline void StreamHelper(internal::false_type /*is_pointer*/, const T& value) { // See the comments in Message& operator <<(const T&) above for why // we need this using statement. using ::operator <<; *ss_ << value; } #endif // GTEST_OS_SYMBIAN // We'll hold the text streamed to this object here. const internal::scoped_ptr< ::std::stringstream> ss_; // We declare (but don't implement) this to prevent the compiler // from implementing the assignment operator. void operator=(const Message&); }; // Streams a Message to an ostream. inline std::ostream& operator <<(std::ostream& os, const Message& sb) { return os << sb.GetString(); } namespace internal { // Converts a streamable value to an std::string. A NULL pointer is // converted to "(null)". When the input value is a ::string, // ::std::string, ::wstring, or ::std::wstring object, each NUL // character in it is replaced with "\\0". template std::string StreamableToString(const T& streamable) { return (Message() << streamable).GetString(); } } // namespace internal } // namespace testing #endif // GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_ // Copyright 2005, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Authors: wan@google.com (Zhanyong Wan), eefacm@gmail.com (Sean Mcafee) // // The Google C++ Testing Framework (Google Test) // // This header file declares the String class and functions used internally by // Google Test. They are subject to change without notice. They should not used // by code external to Google Test. // // This header file is #included by . // It should not be #included by other files. #ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_ #define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_ #ifdef __BORLANDC__ // string.h is not guaranteed to provide strcpy on C++ Builder. # include #endif #include #include namespace testing { namespace internal { // String - an abstract class holding static string utilities. class GTEST_API_ String { public: // Static utility methods // Clones a 0-terminated C string, allocating memory using new. The // caller is responsible for deleting the return value using // delete[]. Returns the cloned string, or NULL if the input is // NULL. // // This is different from strdup() in string.h, which allocates // memory using malloc(). static const char* CloneCString(const char* c_str); #if GTEST_OS_WINDOWS_MOBILE // Windows CE does not have the 'ANSI' versions of Win32 APIs. To be // able to pass strings to Win32 APIs on CE we need to convert them // to 'Unicode', UTF-16. // Creates a UTF-16 wide string from the given ANSI string, allocating // memory using new. The caller is responsible for deleting the return // value using delete[]. Returns the wide string, or NULL if the // input is NULL. // // The wide string is created using the ANSI codepage (CP_ACP) to // match the behaviour of the ANSI versions of Win32 calls and the // C runtime. static LPCWSTR AnsiToUtf16(const char* c_str); // Creates an ANSI string from the given wide string, allocating // memory using new. The caller is responsible for deleting the return // value using delete[]. Returns the ANSI string, or NULL if the // input is NULL. // // The returned string is created using the ANSI codepage (CP_ACP) to // match the behaviour of the ANSI versions of Win32 calls and the // C runtime. static const char* Utf16ToAnsi(LPCWSTR utf16_str); #endif // Compares two C strings. Returns true iff they have the same content. // // Unlike strcmp(), this function can handle NULL argument(s). A // NULL C string is considered different to any non-NULL C string, // including the empty string. static bool CStringEquals(const char* lhs, const char* rhs); // Converts a wide C string to a String using the UTF-8 encoding. // NULL will be converted to "(null)". If an error occurred during // the conversion, "(failed to convert from wide string)" is // returned. static std::string ShowWideCString(const wchar_t* wide_c_str); // Compares two wide C strings. Returns true iff they have the same // content. // // Unlike wcscmp(), this function can handle NULL argument(s). A // NULL C string is considered different to any non-NULL C string, // including the empty string. static bool WideCStringEquals(const wchar_t* lhs, const wchar_t* rhs); // Compares two C strings, ignoring case. Returns true iff they // have the same content. // // Unlike strcasecmp(), this function can handle NULL argument(s). // A NULL C string is considered different to any non-NULL C string, // including the empty string. static bool CaseInsensitiveCStringEquals(const char* lhs, const char* rhs); // Compares two wide C strings, ignoring case. Returns true iff they // have the same content. // // Unlike wcscasecmp(), this function can handle NULL argument(s). // A NULL C string is considered different to any non-NULL wide C string, // including the empty string. // NB: The implementations on different platforms slightly differ. // On windows, this method uses _wcsicmp which compares according to LC_CTYPE // environment variable. On GNU platform this method uses wcscasecmp // which compares according to LC_CTYPE category of the current locale. // On MacOS X, it uses towlower, which also uses LC_CTYPE category of the // current locale. static bool CaseInsensitiveWideCStringEquals(const wchar_t* lhs, const wchar_t* rhs); // Returns true iff the given string ends with the given suffix, ignoring // case. Any string is considered to end with an empty suffix. static bool EndsWithCaseInsensitive( const std::string& str, const std::string& suffix); // Formats an int value as "%02d". static std::string FormatIntWidth2(int value); // "%02d" for width == 2 // Formats an int value as "%X". static std::string FormatHexInt(int value); // Formats a byte as "%02X". static std::string FormatByte(unsigned char value); private: String(); // Not meant to be instantiated. }; // class String // Gets the content of the stringstream's buffer as an std::string. Each '\0' // character in the buffer is replaced with "\\0". GTEST_API_ std::string StringStreamToString(::std::stringstream* stream); } // namespace internal } // namespace testing #endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_ // Copyright 2008, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: keith.ray@gmail.com (Keith Ray) // // Google Test filepath utilities // // This header file declares classes and functions used internally by // Google Test. They are subject to change without notice. // // This file is #included in . // Do not include this header file separately! #ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_ #define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_ namespace testing { namespace internal { // FilePath - a class for file and directory pathname manipulation which // handles platform-specific conventions (like the pathname separator). // Used for helper functions for naming files in a directory for xml output. // Except for Set methods, all methods are const or static, which provides an // "immutable value object" -- useful for peace of mind. // A FilePath with a value ending in a path separator ("like/this/") represents // a directory, otherwise it is assumed to represent a file. In either case, // it may or may not represent an actual file or directory in the file system. // Names are NOT checked for syntax correctness -- no checking for illegal // characters, malformed paths, etc. class GTEST_API_ FilePath { public: FilePath() : pathname_("") { } FilePath(const FilePath& rhs) : pathname_(rhs.pathname_) { } explicit FilePath(const std::string& pathname) : pathname_(pathname) { Normalize(); } FilePath& operator=(const FilePath& rhs) { Set(rhs); return *this; } void Set(const FilePath& rhs) { pathname_ = rhs.pathname_; } const std::string& string() const { return pathname_; } const char* c_str() const { return pathname_.c_str(); } // Returns the current working directory, or "" if unsuccessful. static FilePath GetCurrentDir(); // Given directory = "dir", base_name = "test", number = 0, // extension = "xml", returns "dir/test.xml". If number is greater // than zero (e.g., 12), returns "dir/test_12.xml". // On Windows platform, uses \ as the separator rather than /. static FilePath MakeFileName(const FilePath& directory, const FilePath& base_name, int number, const char* extension); // Given directory = "dir", relative_path = "test.xml", // returns "dir/test.xml". // On Windows, uses \ as the separator rather than /. static FilePath ConcatPaths(const FilePath& directory, const FilePath& relative_path); // Returns a pathname for a file that does not currently exist. The pathname // will be directory/base_name.extension or // directory/base_name_.extension if directory/base_name.extension // already exists. The number will be incremented until a pathname is found // that does not already exist. // Examples: 'dir/foo_test.xml' or 'dir/foo_test_1.xml'. // There could be a race condition if two or more processes are calling this // function at the same time -- they could both pick the same filename. static FilePath GenerateUniqueFileName(const FilePath& directory, const FilePath& base_name, const char* extension); // Returns true iff the path is "". bool IsEmpty() const { return pathname_.empty(); } // If input name has a trailing separator character, removes it and returns // the name, otherwise return the name string unmodified. // On Windows platform, uses \ as the separator, other platforms use /. FilePath RemoveTrailingPathSeparator() const; // Returns a copy of the FilePath with the directory part removed. // Example: FilePath("path/to/file").RemoveDirectoryName() returns // FilePath("file"). If there is no directory part ("just_a_file"), it returns // the FilePath unmodified. If there is no file part ("just_a_dir/") it // returns an empty FilePath (""). // On Windows platform, '\' is the path separator, otherwise it is '/'. FilePath RemoveDirectoryName() const; // RemoveFileName returns the directory path with the filename removed. // Example: FilePath("path/to/file").RemoveFileName() returns "path/to/". // If the FilePath is "a_file" or "/a_file", RemoveFileName returns // FilePath("./") or, on Windows, FilePath(".\\"). If the filepath does // not have a file, like "just/a/dir/", it returns the FilePath unmodified. // On Windows platform, '\' is the path separator, otherwise it is '/'. FilePath RemoveFileName() const; // Returns a copy of the FilePath with the case-insensitive extension removed. // Example: FilePath("dir/file.exe").RemoveExtension("EXE") returns // FilePath("dir/file"). If a case-insensitive extension is not // found, returns a copy of the original FilePath. FilePath RemoveExtension(const char* extension) const; // Creates directories so that path exists. Returns true if successful or if // the directories already exist; returns false if unable to create // directories for any reason. Will also return false if the FilePath does // not represent a directory (that is, it doesn't end with a path separator). bool CreateDirectoriesRecursively() const; // Create the directory so that path exists. Returns true if successful or // if the directory already exists; returns false if unable to create the // directory for any reason, including if the parent directory does not // exist. Not named "CreateDirectory" because that's a macro on Windows. bool CreateFolder() const; // Returns true if FilePath describes something in the file-system, // either a file, directory, or whatever, and that something exists. bool FileOrDirectoryExists() const; // Returns true if pathname describes a directory in the file-system // that exists. bool DirectoryExists() const; // Returns true if FilePath ends with a path separator, which indicates that // it is intended to represent a directory. Returns false otherwise. // This does NOT check that a directory (or file) actually exists. bool IsDirectory() const; // Returns true if pathname describes a root directory. (Windows has one // root directory per disk drive.) bool IsRootDirectory() const; // Returns true if pathname describes an absolute path. bool IsAbsolutePath() const; private: // Replaces multiple consecutive separators with a single separator. // For example, "bar///foo" becomes "bar/foo". Does not eliminate other // redundancies that might be in a pathname involving "." or "..". // // A pathname with multiple consecutive separators may occur either through // user error or as a result of some scripts or APIs that generate a pathname // with a trailing separator. On other platforms the same API or script // may NOT generate a pathname with a trailing "/". Then elsewhere that // pathname may have another "/" and pathname components added to it, // without checking for the separator already being there. // The script language and operating system may allow paths like "foo//bar" // but some of the functions in FilePath will not handle that correctly. In // particular, RemoveTrailingPathSeparator() only removes one separator, and // it is called in CreateDirectoriesRecursively() assuming that it will change // a pathname from directory syntax (trailing separator) to filename syntax. // // On Windows this method also replaces the alternate path separator '/' with // the primary path separator '\\', so that for example "bar\\/\\foo" becomes // "bar\\foo". void Normalize(); // Returns a pointer to the last occurence of a valid path separator in // the FilePath. On Windows, for example, both '/' and '\' are valid path // separators. Returns NULL if no path separator was found. const char* FindLastPathSeparator() const; std::string pathname_; }; // class FilePath } // namespace internal } // namespace testing #endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_ // This file was GENERATED by command: // pump.py gtest-type-util.h.pump // DO NOT EDIT BY HAND!!! // Copyright 2008 Google Inc. // All Rights Reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: wan@google.com (Zhanyong Wan) // Type utilities needed for implementing typed and type-parameterized // tests. This file is generated by a SCRIPT. DO NOT EDIT BY HAND! // // Currently we support at most 50 types in a list, and at most 50 // type-parameterized tests in one type-parameterized test case. // Please contact googletestframework@googlegroups.com if you need // more. #ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_ #define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_ // #ifdef __GNUC__ is too general here. It is possible to use gcc without using // libstdc++ (which is where cxxabi.h comes from). # if GTEST_HAS_CXXABI_H_ # include # elif defined(__HP_aCC) # include # endif // GTEST_HASH_CXXABI_H_ namespace testing { namespace internal { // GetTypeName() returns a human-readable name of type T. // NB: This function is also used in Google Mock, so don't move it inside of // the typed-test-only section below. template std::string GetTypeName() { # if GTEST_HAS_RTTI const char* const name = typeid(T).name(); # if GTEST_HAS_CXXABI_H_ || defined(__HP_aCC) int status = 0; // gcc's implementation of typeid(T).name() mangles the type name, // so we have to demangle it. # if GTEST_HAS_CXXABI_H_ using abi::__cxa_demangle; # endif // GTEST_HAS_CXXABI_H_ char* const readable_name = __cxa_demangle(name, 0, 0, &status); const std::string name_str(status == 0 ? readable_name : name); free(readable_name); return name_str; # else return name; # endif // GTEST_HAS_CXXABI_H_ || __HP_aCC # else return ""; # endif // GTEST_HAS_RTTI } #if GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P // AssertyTypeEq::type is defined iff T1 and T2 are the same // type. This can be used as a compile-time assertion to ensure that // two types are equal. template struct AssertTypeEq; template struct AssertTypeEq { typedef bool type; }; // A unique type used as the default value for the arguments of class // template Types. This allows us to simulate variadic templates // (e.g. Types, Type, and etc), which C++ doesn't // support directly. struct None {}; // The following family of struct and struct templates are used to // represent type lists. In particular, TypesN // represents a type list with N types (T1, T2, ..., and TN) in it. // Except for Types0, every struct in the family has two member types: // Head for the first type in the list, and Tail for the rest of the // list. // The empty type list. struct Types0 {}; // Type lists of length 1, 2, 3, and so on. template struct Types1 { typedef T1 Head; typedef Types0 Tail; }; template struct Types2 { typedef T1 Head; typedef Types1 Tail; }; template struct Types3 { typedef T1 Head; typedef Types2 Tail; }; template struct Types4 { typedef T1 Head; typedef Types3 Tail; }; template struct Types5 { typedef T1 Head; typedef Types4 Tail; }; template struct Types6 { typedef T1 Head; typedef Types5 Tail; }; template struct Types7 { typedef T1 Head; typedef Types6 Tail; }; template struct Types8 { typedef T1 Head; typedef Types7 Tail; }; template struct Types9 { typedef T1 Head; typedef Types8 Tail; }; template struct Types10 { typedef T1 Head; typedef Types9 Tail; }; template struct Types11 { typedef T1 Head; typedef Types10 Tail; }; template struct Types12 { typedef T1 Head; typedef Types11 Tail; }; template struct Types13 { typedef T1 Head; typedef Types12 Tail; }; template struct Types14 { typedef T1 Head; typedef Types13 Tail; }; template struct Types15 { typedef T1 Head; typedef Types14 Tail; }; template struct Types16 { typedef T1 Head; typedef Types15 Tail; }; template struct Types17 { typedef T1 Head; typedef Types16 Tail; }; template struct Types18 { typedef T1 Head; typedef Types17 Tail; }; template struct Types19 { typedef T1 Head; typedef Types18 Tail; }; template struct Types20 { typedef T1 Head; typedef Types19 Tail; }; template struct Types21 { typedef T1 Head; typedef Types20 Tail; }; template struct Types22 { typedef T1 Head; typedef Types21 Tail; }; template struct Types23 { typedef T1 Head; typedef Types22 Tail; }; template struct Types24 { typedef T1 Head; typedef Types23 Tail; }; template struct Types25 { typedef T1 Head; typedef Types24 Tail; }; template struct Types26 { typedef T1 Head; typedef Types25 Tail; }; template struct Types27 { typedef T1 Head; typedef Types26 Tail; }; template struct Types28 { typedef T1 Head; typedef Types27 Tail; }; template struct Types29 { typedef T1 Head; typedef Types28 Tail; }; template struct Types30 { typedef T1 Head; typedef Types29 Tail; }; template struct Types31 { typedef T1 Head; typedef Types30 Tail; }; template struct Types32 { typedef T1 Head; typedef Types31 Tail; }; template struct Types33 { typedef T1 Head; typedef Types32 Tail; }; template struct Types34 { typedef T1 Head; typedef Types33 Tail; }; template struct Types35 { typedef T1 Head; typedef Types34 Tail; }; template struct Types36 { typedef T1 Head; typedef Types35 Tail; }; template struct Types37 { typedef T1 Head; typedef Types36 Tail; }; template struct Types38 { typedef T1 Head; typedef Types37 Tail; }; template struct Types39 { typedef T1 Head; typedef Types38 Tail; }; template struct Types40 { typedef T1 Head; typedef Types39 Tail; }; template struct Types41 { typedef T1 Head; typedef Types40 Tail; }; template struct Types42 { typedef T1 Head; typedef Types41 Tail; }; template struct Types43 { typedef T1 Head; typedef Types42 Tail; }; template struct Types44 { typedef T1 Head; typedef Types43 Tail; }; template struct Types45 { typedef T1 Head; typedef Types44 Tail; }; template struct Types46 { typedef T1 Head; typedef Types45 Tail; }; template struct Types47 { typedef T1 Head; typedef Types46 Tail; }; template struct Types48 { typedef T1 Head; typedef Types47 Tail; }; template struct Types49 { typedef T1 Head; typedef Types48 Tail; }; template struct Types50 { typedef T1 Head; typedef Types49 Tail; }; } // namespace internal // We don't want to require the users to write TypesN<...> directly, // as that would require them to count the length. Types<...> is much // easier to write, but generates horrible messages when there is a // compiler error, as gcc insists on printing out each template // argument, even if it has the default value (this means Types // will appear as Types in the compiler // errors). // // Our solution is to combine the best part of the two approaches: a // user would write Types, and Google Test will translate // that to TypesN internally to make error messages // readable. The translation is done by the 'type' member of the // Types template. template struct Types { typedef internal::Types50 type; }; template <> struct Types { typedef internal::Types0 type; }; template struct Types { typedef internal::Types1 type; }; template struct Types { typedef internal::Types2 type; }; template struct Types { typedef internal::Types3 type; }; template struct Types { typedef internal::Types4 type; }; template struct Types { typedef internal::Types5 type; }; template struct Types { typedef internal::Types6 type; }; template struct Types { typedef internal::Types7 type; }; template struct Types { typedef internal::Types8 type; }; template struct Types { typedef internal::Types9 type; }; template struct Types { typedef internal::Types10 type; }; template struct Types { typedef internal::Types11 type; }; template struct Types { typedef internal::Types12 type; }; template struct Types { typedef internal::Types13 type; }; template struct Types { typedef internal::Types14 type; }; template struct Types { typedef internal::Types15 type; }; template struct Types { typedef internal::Types16 type; }; template struct Types { typedef internal::Types17 type; }; template struct Types { typedef internal::Types18 type; }; template struct Types { typedef internal::Types19 type; }; template struct Types { typedef internal::Types20 type; }; template struct Types { typedef internal::Types21 type; }; template struct Types { typedef internal::Types22 type; }; template struct Types { typedef internal::Types23 type; }; template struct Types { typedef internal::Types24 type; }; template struct Types { typedef internal::Types25 type; }; template struct Types { typedef internal::Types26 type; }; template struct Types { typedef internal::Types27 type; }; template struct Types { typedef internal::Types28 type; }; template struct Types { typedef internal::Types29 type; }; template struct Types { typedef internal::Types30 type; }; template struct Types { typedef internal::Types31 type; }; template struct Types { typedef internal::Types32 type; }; template struct Types { typedef internal::Types33 type; }; template struct Types { typedef internal::Types34 type; }; template struct Types { typedef internal::Types35 type; }; template struct Types { typedef internal::Types36 type; }; template struct Types { typedef internal::Types37 type; }; template struct Types { typedef internal::Types38 type; }; template struct Types { typedef internal::Types39 type; }; template struct Types { typedef internal::Types40 type; }; template struct Types { typedef internal::Types41 type; }; template struct Types { typedef internal::Types42 type; }; template struct Types { typedef internal::Types43 type; }; template struct Types { typedef internal::Types44 type; }; template struct Types { typedef internal::Types45 type; }; template struct Types { typedef internal::Types46 type; }; template struct Types { typedef internal::Types47 type; }; template struct Types { typedef internal::Types48 type; }; template struct Types { typedef internal::Types49 type; }; namespace internal { # define GTEST_TEMPLATE_ template class // The template "selector" struct TemplateSel is used to // represent Tmpl, which must be a class template with one type // parameter, as a type. TemplateSel::Bind::type is defined // as the type Tmpl. This allows us to actually instantiate the // template "selected" by TemplateSel. // // This trick is necessary for simulating typedef for class templates, // which C++ doesn't support directly. template struct TemplateSel { template struct Bind { typedef Tmpl type; }; }; # define GTEST_BIND_(TmplSel, T) \ TmplSel::template Bind::type // A unique struct template used as the default value for the // arguments of class template Templates. This allows us to simulate // variadic templates (e.g. Templates, Templates, // and etc), which C++ doesn't support directly. template struct NoneT {}; // The following family of struct and struct templates are used to // represent template lists. In particular, TemplatesN represents a list of N templates (T1, T2, ..., and TN). Except // for Templates0, every struct in the family has two member types: // Head for the selector of the first template in the list, and Tail // for the rest of the list. // The empty template list. struct Templates0 {}; // Template lists of length 1, 2, 3, and so on. template struct Templates1 { typedef TemplateSel Head; typedef Templates0 Tail; }; template struct Templates2 { typedef TemplateSel Head; typedef Templates1 Tail; }; template struct Templates3 { typedef TemplateSel Head; typedef Templates2 Tail; }; template struct Templates4 { typedef TemplateSel Head; typedef Templates3 Tail; }; template struct Templates5 { typedef TemplateSel Head; typedef Templates4 Tail; }; template struct Templates6 { typedef TemplateSel Head; typedef Templates5 Tail; }; template struct Templates7 { typedef TemplateSel Head; typedef Templates6 Tail; }; template struct Templates8 { typedef TemplateSel Head; typedef Templates7 Tail; }; template struct Templates9 { typedef TemplateSel Head; typedef Templates8 Tail; }; template struct Templates10 { typedef TemplateSel Head; typedef Templates9 Tail; }; template struct Templates11 { typedef TemplateSel Head; typedef Templates10 Tail; }; template struct Templates12 { typedef TemplateSel Head; typedef Templates11 Tail; }; template struct Templates13 { typedef TemplateSel Head; typedef Templates12 Tail; }; template struct Templates14 { typedef TemplateSel Head; typedef Templates13 Tail; }; template struct Templates15 { typedef TemplateSel Head; typedef Templates14 Tail; }; template struct Templates16 { typedef TemplateSel Head; typedef Templates15 Tail; }; template struct Templates17 { typedef TemplateSel Head; typedef Templates16 Tail; }; template struct Templates18 { typedef TemplateSel Head; typedef Templates17 Tail; }; template struct Templates19 { typedef TemplateSel Head; typedef Templates18 Tail; }; template struct Templates20 { typedef TemplateSel Head; typedef Templates19 Tail; }; template struct Templates21 { typedef TemplateSel Head; typedef Templates20 Tail; }; template struct Templates22 { typedef TemplateSel Head; typedef Templates21 Tail; }; template struct Templates23 { typedef TemplateSel Head; typedef Templates22 Tail; }; template struct Templates24 { typedef TemplateSel Head; typedef Templates23 Tail; }; template struct Templates25 { typedef TemplateSel Head; typedef Templates24 Tail; }; template struct Templates26 { typedef TemplateSel Head; typedef Templates25 Tail; }; template struct Templates27 { typedef TemplateSel Head; typedef Templates26 Tail; }; template struct Templates28 { typedef TemplateSel Head; typedef Templates27 Tail; }; template struct Templates29 { typedef TemplateSel Head; typedef Templates28 Tail; }; template struct Templates30 { typedef TemplateSel Head; typedef Templates29 Tail; }; template struct Templates31 { typedef TemplateSel Head; typedef Templates30 Tail; }; template struct Templates32 { typedef TemplateSel Head; typedef Templates31 Tail; }; template struct Templates33 { typedef TemplateSel Head; typedef Templates32 Tail; }; template struct Templates34 { typedef TemplateSel Head; typedef Templates33 Tail; }; template struct Templates35 { typedef TemplateSel Head; typedef Templates34 Tail; }; template struct Templates36 { typedef TemplateSel Head; typedef Templates35 Tail; }; template struct Templates37 { typedef TemplateSel Head; typedef Templates36 Tail; }; template struct Templates38 { typedef TemplateSel Head; typedef Templates37 Tail; }; template struct Templates39 { typedef TemplateSel Head; typedef Templates38 Tail; }; template struct Templates40 { typedef TemplateSel Head; typedef Templates39 Tail; }; template struct Templates41 { typedef TemplateSel Head; typedef Templates40 Tail; }; template struct Templates42 { typedef TemplateSel Head; typedef Templates41 Tail; }; template struct Templates43 { typedef TemplateSel Head; typedef Templates42 Tail; }; template struct Templates44 { typedef TemplateSel Head; typedef Templates43 Tail; }; template struct Templates45 { typedef TemplateSel Head; typedef Templates44 Tail; }; template struct Templates46 { typedef TemplateSel Head; typedef Templates45 Tail; }; template struct Templates47 { typedef TemplateSel Head; typedef Templates46 Tail; }; template struct Templates48 { typedef TemplateSel Head; typedef Templates47 Tail; }; template struct Templates49 { typedef TemplateSel Head; typedef Templates48 Tail; }; template struct Templates50 { typedef TemplateSel Head; typedef Templates49 Tail; }; // We don't want to require the users to write TemplatesN<...> directly, // as that would require them to count the length. Templates<...> is much // easier to write, but generates horrible messages when there is a // compiler error, as gcc insists on printing out each template // argument, even if it has the default value (this means Templates // will appear as Templates in the compiler // errors). // // Our solution is to combine the best part of the two approaches: a // user would write Templates, and Google Test will translate // that to TemplatesN internally to make error messages // readable. The translation is done by the 'type' member of the // Templates template. template struct Templates { typedef Templates50 type; }; template <> struct Templates { typedef Templates0 type; }; template struct Templates { typedef Templates1 type; }; template struct Templates { typedef Templates2 type; }; template struct Templates { typedef Templates3 type; }; template struct Templates { typedef Templates4 type; }; template struct Templates { typedef Templates5 type; }; template struct Templates { typedef Templates6 type; }; template struct Templates { typedef Templates7 type; }; template struct Templates { typedef Templates8 type; }; template struct Templates { typedef Templates9 type; }; template struct Templates { typedef Templates10 type; }; template struct Templates { typedef Templates11 type; }; template struct Templates { typedef Templates12 type; }; template struct Templates { typedef Templates13 type; }; template struct Templates { typedef Templates14 type; }; template struct Templates { typedef Templates15 type; }; template struct Templates { typedef Templates16 type; }; template struct Templates { typedef Templates17 type; }; template struct Templates { typedef Templates18 type; }; template struct Templates { typedef Templates19 type; }; template struct Templates { typedef Templates20 type; }; template struct Templates { typedef Templates21 type; }; template struct Templates { typedef Templates22 type; }; template struct Templates { typedef Templates23 type; }; template struct Templates { typedef Templates24 type; }; template struct Templates { typedef Templates25 type; }; template struct Templates { typedef Templates26 type; }; template struct Templates { typedef Templates27 type; }; template struct Templates { typedef Templates28 type; }; template struct Templates { typedef Templates29 type; }; template struct Templates { typedef Templates30 type; }; template struct Templates { typedef Templates31 type; }; template struct Templates { typedef Templates32 type; }; template struct Templates { typedef Templates33 type; }; template struct Templates { typedef Templates34 type; }; template struct Templates { typedef Templates35 type; }; template struct Templates { typedef Templates36 type; }; template struct Templates { typedef Templates37 type; }; template struct Templates { typedef Templates38 type; }; template struct Templates { typedef Templates39 type; }; template struct Templates { typedef Templates40 type; }; template struct Templates { typedef Templates41 type; }; template struct Templates { typedef Templates42 type; }; template struct Templates { typedef Templates43 type; }; template struct Templates { typedef Templates44 type; }; template struct Templates { typedef Templates45 type; }; template struct Templates { typedef Templates46 type; }; template struct Templates { typedef Templates47 type; }; template struct Templates { typedef Templates48 type; }; template struct Templates { typedef Templates49 type; }; // The TypeList template makes it possible to use either a single type // or a Types<...> list in TYPED_TEST_CASE() and // INSTANTIATE_TYPED_TEST_CASE_P(). template struct TypeList { typedef Types1 type; }; template struct TypeList > { typedef typename Types::type type; }; #endif // GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P } // namespace internal } // namespace testing #endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_ // Due to C++ preprocessor weirdness, we need double indirection to // concatenate two tokens when one of them is __LINE__. Writing // // foo ## __LINE__ // // will result in the token foo__LINE__, instead of foo followed by // the current line number. For more details, see // http://www.parashift.com/c++-faq-lite/misc-technical-issues.html#faq-39.6 #define GTEST_CONCAT_TOKEN_(foo, bar) GTEST_CONCAT_TOKEN_IMPL_(foo, bar) #define GTEST_CONCAT_TOKEN_IMPL_(foo, bar) foo ## bar class ProtocolMessage; namespace proto2 { class Message; } namespace testing { // Forward declarations. class AssertionResult; // Result of an assertion. class Message; // Represents a failure message. class Test; // Represents a test. class TestInfo; // Information about a test. class TestPartResult; // Result of a test part. class UnitTest; // A collection of test cases. template ::std::string PrintToString(const T& value); namespace internal { struct TraceInfo; // Information about a trace point. class ScopedTrace; // Implements scoped trace. class TestInfoImpl; // Opaque implementation of TestInfo class UnitTestImpl; // Opaque implementation of UnitTest // How many times InitGoogleTest() has been called. GTEST_API_ extern int g_init_gtest_count; // The text used in failure messages to indicate the start of the // stack trace. GTEST_API_ extern const char kStackTraceMarker[]; // Two overloaded helpers for checking at compile time whether an // expression is a null pointer literal (i.e. NULL or any 0-valued // compile-time integral constant). Their return values have // different sizes, so we can use sizeof() to test which version is // picked by the compiler. These helpers have no implementations, as // we only need their signatures. // // Given IsNullLiteralHelper(x), the compiler will pick the first // version if x can be implicitly converted to Secret*, and pick the // second version otherwise. Since Secret is a secret and incomplete // type, the only expression a user can write that has type Secret* is // a null pointer literal. Therefore, we know that x is a null // pointer literal if and only if the first version is picked by the // compiler. char IsNullLiteralHelper(Secret* p); char (&IsNullLiteralHelper(...))[2]; // NOLINT // A compile-time bool constant that is true if and only if x is a // null pointer literal (i.e. NULL or any 0-valued compile-time // integral constant). #ifdef GTEST_ELLIPSIS_NEEDS_POD_ // We lose support for NULL detection where the compiler doesn't like // passing non-POD classes through ellipsis (...). # define GTEST_IS_NULL_LITERAL_(x) false #else # define GTEST_IS_NULL_LITERAL_(x) \ (sizeof(::testing::internal::IsNullLiteralHelper(x)) == 1) #endif // GTEST_ELLIPSIS_NEEDS_POD_ // Appends the user-supplied message to the Google-Test-generated message. GTEST_API_ std::string AppendUserMessage( const std::string& gtest_msg, const Message& user_msg); #if GTEST_HAS_EXCEPTIONS // This exception is thrown by (and only by) a failed Google Test // assertion when GTEST_FLAG(throw_on_failure) is true (if exceptions // are enabled). We derive it from std::runtime_error, which is for // errors presumably detectable only at run time. Since // std::runtime_error inherits from std::exception, many testing // frameworks know how to extract and print the message inside it. class GTEST_API_ GoogleTestFailureException : public ::std::runtime_error { public: explicit GoogleTestFailureException(const TestPartResult& failure); }; #endif // GTEST_HAS_EXCEPTIONS // A helper class for creating scoped traces in user programs. class GTEST_API_ ScopedTrace { public: // The c'tor pushes the given source file location and message onto // a trace stack maintained by Google Test. ScopedTrace(const char* file, int line, const Message& message); // The d'tor pops the info pushed by the c'tor. // // Note that the d'tor is not virtual in order to be efficient. // Don't inherit from ScopedTrace! ~ScopedTrace(); private: GTEST_DISALLOW_COPY_AND_ASSIGN_(ScopedTrace); } GTEST_ATTRIBUTE_UNUSED_; // A ScopedTrace object does its job in its // c'tor and d'tor. Therefore it doesn't // need to be used otherwise. // Constructs and returns the message for an equality assertion // (e.g. ASSERT_EQ, EXPECT_STREQ, etc) failure. // // The first four parameters are the expressions used in the assertion // and their values, as strings. For example, for ASSERT_EQ(foo, bar) // where foo is 5 and bar is 6, we have: // // expected_expression: "foo" // actual_expression: "bar" // expected_value: "5" // actual_value: "6" // // The ignoring_case parameter is true iff the assertion is a // *_STRCASEEQ*. When it's true, the string " (ignoring case)" will // be inserted into the message. GTEST_API_ AssertionResult EqFailure(const char* expected_expression, const char* actual_expression, const std::string& expected_value, const std::string& actual_value, bool ignoring_case); // Constructs a failure message for Boolean assertions such as EXPECT_TRUE. GTEST_API_ std::string GetBoolAssertionFailureMessage( const AssertionResult& assertion_result, const char* expression_text, const char* actual_predicate_value, const char* expected_predicate_value); // This template class represents an IEEE floating-point number // (either single-precision or double-precision, depending on the // template parameters). // // The purpose of this class is to do more sophisticated number // comparison. (Due to round-off error, etc, it's very unlikely that // two floating-points will be equal exactly. Hence a naive // comparison by the == operation often doesn't work.) // // Format of IEEE floating-point: // // The most-significant bit being the leftmost, an IEEE // floating-point looks like // // sign_bit exponent_bits fraction_bits // // Here, sign_bit is a single bit that designates the sign of the // number. // // For float, there are 8 exponent bits and 23 fraction bits. // // For double, there are 11 exponent bits and 52 fraction bits. // // More details can be found at // http://en.wikipedia.org/wiki/IEEE_floating-point_standard. // // Template parameter: // // RawType: the raw floating-point type (either float or double) template class FloatingPoint { public: // Defines the unsigned integer type that has the same size as the // floating point number. typedef typename TypeWithSize::UInt Bits; // Constants. // # of bits in a number. static const size_t kBitCount = 8*sizeof(RawType); // # of fraction bits in a number. static const size_t kFractionBitCount = std::numeric_limits::digits - 1; // # of exponent bits in a number. static const size_t kExponentBitCount = kBitCount - 1 - kFractionBitCount; // The mask for the sign bit. static const Bits kSignBitMask = static_cast(1) << (kBitCount - 1); // The mask for the fraction bits. static const Bits kFractionBitMask = ~static_cast(0) >> (kExponentBitCount + 1); // The mask for the exponent bits. static const Bits kExponentBitMask = ~(kSignBitMask | kFractionBitMask); // How many ULP's (Units in the Last Place) we want to tolerate when // comparing two numbers. The larger the value, the more error we // allow. A 0 value means that two numbers must be exactly the same // to be considered equal. // // The maximum error of a single floating-point operation is 0.5 // units in the last place. On Intel CPU's, all floating-point // calculations are done with 80-bit precision, while double has 64 // bits. Therefore, 4 should be enough for ordinary use. // // See the following article for more details on ULP: // http://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/ static const size_t kMaxUlps = 4; // Constructs a FloatingPoint from a raw floating-point number. // // On an Intel CPU, passing a non-normalized NAN (Not a Number) // around may change its bits, although the new value is guaranteed // to be also a NAN. Therefore, don't expect this constructor to // preserve the bits in x when x is a NAN. explicit FloatingPoint(const RawType& x) { u_.value_ = x; } // Static methods // Reinterprets a bit pattern as a floating-point number. // // This function is needed to test the AlmostEquals() method. static RawType ReinterpretBits(const Bits bits) { FloatingPoint fp(0); fp.u_.bits_ = bits; return fp.u_.value_; } // Returns the floating-point number that represent positive infinity. static RawType Infinity() { return ReinterpretBits(kExponentBitMask); } // Returns the maximum representable finite floating-point number. static RawType Max(); // Non-static methods // Returns the bits that represents this number. const Bits &bits() const { return u_.bits_; } // Returns the exponent bits of this number. Bits exponent_bits() const { return kExponentBitMask & u_.bits_; } // Returns the fraction bits of this number. Bits fraction_bits() const { return kFractionBitMask & u_.bits_; } // Returns the sign bit of this number. Bits sign_bit() const { return kSignBitMask & u_.bits_; } // Returns true iff this is NAN (not a number). bool is_nan() const { // It's a NAN if the exponent bits are all ones and the fraction // bits are not entirely zeros. return (exponent_bits() == kExponentBitMask) && (fraction_bits() != 0); } // Returns true iff this number is at most kMaxUlps ULP's away from // rhs. In particular, this function: // // - returns false if either number is (or both are) NAN. // - treats really large numbers as almost equal to infinity. // - thinks +0.0 and -0.0 are 0 DLP's apart. bool AlmostEquals(const FloatingPoint& rhs) const { // The IEEE standard says that any comparison operation involving // a NAN must return false. if (is_nan() || rhs.is_nan()) return false; return DistanceBetweenSignAndMagnitudeNumbers(u_.bits_, rhs.u_.bits_) <= kMaxUlps; } private: // The data type used to store the actual floating-point number. union FloatingPointUnion { RawType value_; // The raw floating-point number. Bits bits_; // The bits that represent the number. }; // Converts an integer from the sign-and-magnitude representation to // the biased representation. More precisely, let N be 2 to the // power of (kBitCount - 1), an integer x is represented by the // unsigned number x + N. // // For instance, // // -N + 1 (the most negative number representable using // sign-and-magnitude) is represented by 1; // 0 is represented by N; and // N - 1 (the biggest number representable using // sign-and-magnitude) is represented by 2N - 1. // // Read http://en.wikipedia.org/wiki/Signed_number_representations // for more details on signed number representations. static Bits SignAndMagnitudeToBiased(const Bits &sam) { if (kSignBitMask & sam) { // sam represents a negative number. return ~sam + 1; } else { // sam represents a positive number. return kSignBitMask | sam; } } // Given two numbers in the sign-and-magnitude representation, // returns the distance between them as an unsigned number. static Bits DistanceBetweenSignAndMagnitudeNumbers(const Bits &sam1, const Bits &sam2) { const Bits biased1 = SignAndMagnitudeToBiased(sam1); const Bits biased2 = SignAndMagnitudeToBiased(sam2); return (biased1 >= biased2) ? (biased1 - biased2) : (biased2 - biased1); } FloatingPointUnion u_; }; // We cannot use std::numeric_limits::max() as it clashes with the max() // macro defined by . template <> inline float FloatingPoint::Max() { return FLT_MAX; } template <> inline double FloatingPoint::Max() { return DBL_MAX; } // Typedefs the instances of the FloatingPoint template class that we // care to use. typedef FloatingPoint Float; typedef FloatingPoint Double; // In order to catch the mistake of putting tests that use different // test fixture classes in the same test case, we need to assign // unique IDs to fixture classes and compare them. The TypeId type is // used to hold such IDs. The user should treat TypeId as an opaque // type: the only operation allowed on TypeId values is to compare // them for equality using the == operator. typedef const void* TypeId; template class TypeIdHelper { public: // dummy_ must not have a const type. Otherwise an overly eager // compiler (e.g. MSVC 7.1 & 8.0) may try to merge // TypeIdHelper::dummy_ for different Ts as an "optimization". static bool dummy_; }; template bool TypeIdHelper::dummy_ = false; // GetTypeId() returns the ID of type T. Different values will be // returned for different types. Calling the function twice with the // same type argument is guaranteed to return the same ID. template TypeId GetTypeId() { // The compiler is required to allocate a different // TypeIdHelper::dummy_ variable for each T used to instantiate // the template. Therefore, the address of dummy_ is guaranteed to // be unique. return &(TypeIdHelper::dummy_); } // Returns the type ID of ::testing::Test. Always call this instead // of GetTypeId< ::testing::Test>() to get the type ID of // ::testing::Test, as the latter may give the wrong result due to a // suspected linker bug when compiling Google Test as a Mac OS X // framework. GTEST_API_ TypeId GetTestTypeId(); // Defines the abstract factory interface that creates instances // of a Test object. class TestFactoryBase { public: virtual ~TestFactoryBase() {} // Creates a test instance to run. The instance is both created and destroyed // within TestInfoImpl::Run() virtual Test* CreateTest() = 0; protected: TestFactoryBase() {} private: GTEST_DISALLOW_COPY_AND_ASSIGN_(TestFactoryBase); }; // This class provides implementation of TeastFactoryBase interface. // It is used in TEST and TEST_F macros. template class TestFactoryImpl : public TestFactoryBase { public: virtual Test* CreateTest() { return new TestClass; } }; #if GTEST_OS_WINDOWS // Predicate-formatters for implementing the HRESULT checking macros // {ASSERT|EXPECT}_HRESULT_{SUCCEEDED|FAILED} // We pass a long instead of HRESULT to avoid causing an // include dependency for the HRESULT type. GTEST_API_ AssertionResult IsHRESULTSuccess(const char* expr, long hr); // NOLINT GTEST_API_ AssertionResult IsHRESULTFailure(const char* expr, long hr); // NOLINT #endif // GTEST_OS_WINDOWS // Types of SetUpTestCase() and TearDownTestCase() functions. typedef void (*SetUpTestCaseFunc)(); typedef void (*TearDownTestCaseFunc)(); // Creates a new TestInfo object and registers it with Google Test; // returns the created object. // // Arguments: // // test_case_name: name of the test case // name: name of the test // type_param the name of the test's type parameter, or NULL if // this is not a typed or a type-parameterized test. // value_param text representation of the test's value parameter, // or NULL if this is not a type-parameterized test. // fixture_class_id: ID of the test fixture class // set_up_tc: pointer to the function that sets up the test case // tear_down_tc: pointer to the function that tears down the test case // factory: pointer to the factory that creates a test object. // The newly created TestInfo instance will assume // ownership of the factory object. GTEST_API_ TestInfo* MakeAndRegisterTestInfo( const char* test_case_name, const char* name, const char* type_param, const char* value_param, TypeId fixture_class_id, SetUpTestCaseFunc set_up_tc, TearDownTestCaseFunc tear_down_tc, TestFactoryBase* factory); // If *pstr starts with the given prefix, modifies *pstr to be right // past the prefix and returns true; otherwise leaves *pstr unchanged // and returns false. None of pstr, *pstr, and prefix can be NULL. GTEST_API_ bool SkipPrefix(const char* prefix, const char** pstr); #if GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P // State of the definition of a type-parameterized test case. class GTEST_API_ TypedTestCasePState { public: TypedTestCasePState() : registered_(false) {} // Adds the given test name to defined_test_names_ and return true // if the test case hasn't been registered; otherwise aborts the // program. bool AddTestName(const char* file, int line, const char* case_name, const char* test_name) { if (registered_) { fprintf(stderr, "%s Test %s must be defined before " "REGISTER_TYPED_TEST_CASE_P(%s, ...).\n", FormatFileLocation(file, line).c_str(), test_name, case_name); fflush(stderr); posix::Abort(); } defined_test_names_.insert(test_name); return true; } // Verifies that registered_tests match the test names in // defined_test_names_; returns registered_tests if successful, or // aborts the program otherwise. const char* VerifyRegisteredTestNames( const char* file, int line, const char* registered_tests); private: bool registered_; ::std::set defined_test_names_; }; // Skips to the first non-space char after the first comma in 'str'; // returns NULL if no comma is found in 'str'. inline const char* SkipComma(const char* str) { const char* comma = strchr(str, ','); if (comma == NULL) { return NULL; } while (IsSpace(*(++comma))) {} return comma; } // Returns the prefix of 'str' before the first comma in it; returns // the entire string if it contains no comma. inline std::string GetPrefixUntilComma(const char* str) { const char* comma = strchr(str, ','); return comma == NULL ? str : std::string(str, comma); } // TypeParameterizedTest::Register() // registers a list of type-parameterized tests with Google Test. The // return value is insignificant - we just need to return something // such that we can call this function in a namespace scope. // // Implementation note: The GTEST_TEMPLATE_ macro declares a template // template parameter. It's defined in gtest-type-util.h. template class TypeParameterizedTest { public: // 'index' is the index of the test in the type list 'Types' // specified in INSTANTIATE_TYPED_TEST_CASE_P(Prefix, TestCase, // Types). Valid values for 'index' are [0, N - 1] where N is the // length of Types. static bool Register(const char* prefix, const char* case_name, const char* test_names, int index) { typedef typename Types::Head Type; typedef Fixture FixtureClass; typedef typename GTEST_BIND_(TestSel, Type) TestClass; // First, registers the first type-parameterized test in the type // list. MakeAndRegisterTestInfo( (std::string(prefix) + (prefix[0] == '\0' ? "" : "/") + case_name + "/" + StreamableToString(index)).c_str(), GetPrefixUntilComma(test_names).c_str(), GetTypeName().c_str(), NULL, // No value parameter. GetTypeId(), TestClass::SetUpTestCase, TestClass::TearDownTestCase, new TestFactoryImpl); // Next, recurses (at compile time) with the tail of the type list. return TypeParameterizedTest ::Register(prefix, case_name, test_names, index + 1); } }; // The base case for the compile time recursion. template class TypeParameterizedTest { public: static bool Register(const char* /*prefix*/, const char* /*case_name*/, const char* /*test_names*/, int /*index*/) { return true; } }; // TypeParameterizedTestCase::Register() // registers *all combinations* of 'Tests' and 'Types' with Google // Test. The return value is insignificant - we just need to return // something such that we can call this function in a namespace scope. template class TypeParameterizedTestCase { public: static bool Register(const char* prefix, const char* case_name, const char* test_names) { typedef typename Tests::Head Head; // First, register the first test in 'Test' for each type in 'Types'. TypeParameterizedTest::Register( prefix, 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)); } }; // The base case for the compile time recursion. template class TypeParameterizedTestCase { public: static bool Register(const char* /*prefix*/, const char* /*case_name*/, const char* /*test_names*/) { return true; } }; #endif // GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P // Returns the current OS stack trace as an std::string. // // The maximum number of stack frames to be included is specified by // the gtest_stack_trace_depth flag. The skip_count parameter // specifies the number of top frames to be skipped, which doesn't // count against the number of frames to be included. // // For example, if Foo() calls Bar(), which in turn calls // GetCurrentOsStackTraceExceptTop(..., 1), Foo() will be included in // the trace but Bar() and GetCurrentOsStackTraceExceptTop() won't. GTEST_API_ std::string GetCurrentOsStackTraceExceptTop( UnitTest* unit_test, int skip_count); // Helpers for suppressing warnings on unreachable code or constant // condition. // Always returns true. GTEST_API_ bool AlwaysTrue(); // Always returns false. inline bool AlwaysFalse() { return !AlwaysTrue(); } // Helper for suppressing false warning from Clang on a const char* // variable declared in a conditional expression always being NULL in // the else branch. struct GTEST_API_ ConstCharPtr { ConstCharPtr(const char* str) : value(str) {} operator bool() const { return true; } const char* value; }; // A simple Linear Congruential Generator for generating random // numbers with a uniform distribution. Unlike rand() and srand(), it // doesn't use global state (and therefore can't interfere with user // code). Unlike rand_r(), it's portable. An LCG isn't very random, // but it's good enough for our purposes. class GTEST_API_ Random { public: static const UInt32 kMaxRange = 1u << 31; explicit Random(UInt32 seed) : state_(seed) {} void Reseed(UInt32 seed) { state_ = seed; } // Generates a random number from [0, range). Crashes if 'range' is // 0 or greater than kMaxRange. UInt32 Generate(UInt32 range); private: UInt32 state_; GTEST_DISALLOW_COPY_AND_ASSIGN_(Random); }; // Defining a variable of type CompileAssertTypesEqual will cause a // compiler error iff T1 and T2 are different types. template struct CompileAssertTypesEqual; template struct CompileAssertTypesEqual { }; // Removes the reference from a type if it is a reference type, // otherwise leaves it unchanged. This is the same as // tr1::remove_reference, which is not widely available yet. template struct RemoveReference { typedef T type; }; // NOLINT template struct RemoveReference { typedef T type; }; // NOLINT // A handy wrapper around RemoveReference that works when the argument // T depends on template parameters. #define GTEST_REMOVE_REFERENCE_(T) \ typename ::testing::internal::RemoveReference::type // Removes const from a type if it is a const type, otherwise leaves // it unchanged. This is the same as tr1::remove_const, which is not // widely available yet. template struct RemoveConst { typedef T type; }; // NOLINT template struct RemoveConst { typedef T type; }; // NOLINT // MSVC 8.0, Sun C++, and IBM XL C++ have a bug which causes the above // definition to fail to remove the const in 'const int[3]' and 'const // char[3][4]'. The following specialization works around the bug. template struct RemoveConst { typedef typename RemoveConst::type type[N]; }; #if defined(_MSC_VER) && _MSC_VER < 1400 // This is the only specialization that allows VC++ 7.1 to remove const in // 'const int[3] and 'const int[3][4]'. However, it causes trouble with GCC // and thus needs to be conditionally compiled. template struct RemoveConst { typedef typename RemoveConst::type type[N]; }; #endif // A handy wrapper around RemoveConst that works when the argument // T depends on template parameters. #define GTEST_REMOVE_CONST_(T) \ typename ::testing::internal::RemoveConst::type // Turns const U&, U&, const U, and U all into U. #define GTEST_REMOVE_REFERENCE_AND_CONST_(T) \ GTEST_REMOVE_CONST_(GTEST_REMOVE_REFERENCE_(T)) // Adds reference to a type if it is not a reference type, // otherwise leaves it unchanged. This is the same as // tr1::add_reference, which is not widely available yet. template struct AddReference { typedef T& type; }; // NOLINT template struct AddReference { typedef T& type; }; // NOLINT // A handy wrapper around AddReference that works when the argument T // depends on template parameters. #define GTEST_ADD_REFERENCE_(T) \ typename ::testing::internal::AddReference::type // Adds a reference to const on top of T as necessary. For example, // it transforms // // char ==> const char& // const char ==> const char& // char& ==> const char& // const char& ==> const char& // // The argument T must depend on some template parameters. #define GTEST_REFERENCE_TO_CONST_(T) \ GTEST_ADD_REFERENCE_(const GTEST_REMOVE_REFERENCE_(T)) // ImplicitlyConvertible::value is a compile-time bool // constant that's true iff type From can be implicitly converted to // type To. template class ImplicitlyConvertible { private: // We need the following helper functions only for their types. // They have no implementations. // MakeFrom() is an expression whose type is From. We cannot simply // use From(), as the type From may not have a public default // constructor. static From MakeFrom(); // These two functions are overloaded. Given an expression // Helper(x), the compiler will pick the first version if x can be // implicitly converted to type To; otherwise it will pick the // second version. // // The first version returns a value of size 1, and the second // version returns a value of size 2. Therefore, by checking the // size of Helper(x), which can be done at compile time, we can tell // which version of Helper() is used, and hence whether x can be // implicitly converted to type To. static char Helper(To); static char (&Helper(...))[2]; // NOLINT // We have to put the 'public' section after the 'private' section, // or MSVC refuses to compile the code. public: // MSVC warns about implicitly converting from double to int for // possible loss of data, so we need to temporarily disable the // warning. #ifdef _MSC_VER # pragma warning(push) // Saves the current warning state. # pragma warning(disable:4244) // Temporarily disables warning 4244. static const bool value = sizeof(Helper(ImplicitlyConvertible::MakeFrom())) == 1; # pragma warning(pop) // Restores the warning state. #elif defined(__BORLANDC__) // C++Builder cannot use member overload resolution during template // instantiation. The simplest workaround is to use its C++0x type traits // functions (C++Builder 2009 and above only). static const bool value = __is_convertible(From, To); #else static const bool value = sizeof(Helper(ImplicitlyConvertible::MakeFrom())) == 1; #endif // _MSV_VER }; template const bool ImplicitlyConvertible::value; // IsAProtocolMessage::value is a compile-time bool constant that's // true iff T is type ProtocolMessage, proto2::Message, or a subclass // of those. template struct IsAProtocolMessage : public bool_constant< ImplicitlyConvertible::value || ImplicitlyConvertible::value> { }; // When the compiler sees expression IsContainerTest(0), if C is an // STL-style container class, the first overload of IsContainerTest // will be viable (since both C::iterator* and C::const_iterator* are // valid types and NULL can be implicitly converted to them). It will // be picked over the second overload as 'int' is a perfect match for // the type of argument 0. If C::iterator or C::const_iterator is not // a valid type, the first overload is not viable, and the second // overload will be picked. Therefore, we can determine whether C is // a container class by checking the type of IsContainerTest(0). // The value of the expression is insignificant. // // Note that we look for both C::iterator and C::const_iterator. The // reason is that C++ injects the name of a class as a member of the // class itself (e.g. you can refer to class iterator as either // 'iterator' or 'iterator::iterator'). If we look for C::iterator // only, for example, we would mistakenly think that a class named // iterator is an STL container. // // Also note that the simpler approach of overloading // IsContainerTest(typename C::const_iterator*) and // IsContainerTest(...) doesn't work with Visual Age C++ and Sun C++. typedef int IsContainer; template IsContainer IsContainerTest(int /* dummy */, typename C::iterator* /* it */ = NULL, typename C::const_iterator* /* const_it */ = NULL) { return 0; } typedef char IsNotContainer; template IsNotContainer IsContainerTest(long /* dummy */) { return '\0'; } // EnableIf::type is void when 'Cond' is true, and // undefined when 'Cond' is false. To use SFINAE to make a function // overload only apply when a particular expression is true, add // "typename EnableIf::type* = 0" as the last parameter. template struct EnableIf; template<> struct EnableIf { typedef void type; }; // NOLINT // Utilities for native arrays. // ArrayEq() compares two k-dimensional native arrays using the // elements' operator==, where k can be any integer >= 0. When k is // 0, ArrayEq() degenerates into comparing a single pair of values. template bool ArrayEq(const T* lhs, size_t size, const U* rhs); // This generic version is used when k is 0. template inline bool ArrayEq(const T& lhs, const U& rhs) { return lhs == rhs; } // This overload is used when k >= 1. template inline bool ArrayEq(const T(&lhs)[N], const U(&rhs)[N]) { return internal::ArrayEq(lhs, N, rhs); } // This helper reduces code bloat. If we instead put its logic inside // the previous ArrayEq() function, arrays with different sizes would // lead to different copies of the template code. template bool ArrayEq(const T* lhs, size_t size, const U* rhs) { for (size_t i = 0; i != size; i++) { if (!internal::ArrayEq(lhs[i], rhs[i])) return false; } return true; } // Finds the first element in the iterator range [begin, end) that // equals elem. Element may be a native array type itself. template Iter ArrayAwareFind(Iter begin, Iter end, const Element& elem) { for (Iter it = begin; it != end; ++it) { if (internal::ArrayEq(*it, elem)) return it; } return end; } // CopyArray() copies a k-dimensional native array using the elements' // operator=, where k can be any integer >= 0. When k is 0, // CopyArray() degenerates into copying a single value. template void CopyArray(const T* from, size_t size, U* to); // This generic version is used when k is 0. template inline void CopyArray(const T& from, U* to) { *to = from; } // This overload is used when k >= 1. template inline void CopyArray(const T(&from)[N], U(*to)[N]) { internal::CopyArray(from, N, *to); } // This helper reduces code bloat. If we instead put its logic inside // the previous CopyArray() function, arrays with different sizes // would lead to different copies of the template code. template void CopyArray(const T* from, size_t size, U* to) { for (size_t i = 0; i != size; i++) { internal::CopyArray(from[i], to + i); } } // The relation between an NativeArray object (see below) and the // native array it represents. enum RelationToSource { kReference, // The NativeArray references the native array. kCopy // The NativeArray makes a copy of the native array and // owns the copy. }; // Adapts a native array to a read-only STL-style container. Instead // of the complete STL container concept, this adaptor only implements // members useful for Google Mock's container matchers. New members // should be added as needed. To simplify the implementation, we only // support Element being a raw type (i.e. having no top-level const or // reference modifier). It's the client's responsibility to satisfy // this requirement. Element can be an array type itself (hence // multi-dimensional arrays are supported). template class NativeArray { public: // STL-style container typedefs. typedef Element value_type; typedef Element* iterator; typedef const Element* const_iterator; // Constructs from a native array. NativeArray(const Element* array, size_t count, RelationToSource relation) { Init(array, count, relation); } // Copy constructor. NativeArray(const NativeArray& rhs) { Init(rhs.array_, rhs.size_, rhs.relation_to_source_); } ~NativeArray() { // Ensures that the user doesn't instantiate NativeArray with a // const or reference type. static_cast(StaticAssertTypeEqHelper()); if (relation_to_source_ == kCopy) delete[] array_; } // STL-style container methods. size_t size() const { return size_; } const_iterator begin() const { return array_; } const_iterator end() const { return array_ + size_; } bool operator==(const NativeArray& rhs) const { return size() == rhs.size() && ArrayEq(begin(), size(), rhs.begin()); } private: // Initializes this object; makes a copy of the input array if // 'relation' is kCopy. void Init(const Element* array, size_t a_size, RelationToSource relation) { if (relation == kReference) { array_ = array; } else { Element* const copy = new Element[a_size]; CopyArray(array, a_size, copy); array_ = copy; } size_ = a_size; relation_to_source_ = relation; } const Element* array_; size_t size_; RelationToSource relation_to_source_; GTEST_DISALLOW_ASSIGN_(NativeArray); }; } // namespace internal } // namespace testing #define GTEST_MESSAGE_AT_(file, line, message, result_type) \ ::testing::internal::AssertHelper(result_type, file, line, message) \ = ::testing::Message() #define GTEST_MESSAGE_(message, result_type) \ GTEST_MESSAGE_AT_(__FILE__, __LINE__, message, result_type) #define GTEST_FATAL_FAILURE_(message) \ return GTEST_MESSAGE_(message, ::testing::TestPartResult::kFatalFailure) #define GTEST_NONFATAL_FAILURE_(message) \ GTEST_MESSAGE_(message, ::testing::TestPartResult::kNonFatalFailure) #define GTEST_SUCCESS_(message) \ GTEST_MESSAGE_(message, ::testing::TestPartResult::kSuccess) // Suppresses MSVC warnings 4072 (unreachable code) for the code following // statement if it returns or throws (or doesn't return or throw in some // situations). #define GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement) \ if (::testing::internal::AlwaysTrue()) { statement; } #define GTEST_TEST_THROW_(statement, expected_exception, fail) \ GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ if (::testing::internal::ConstCharPtr gtest_msg = "") { \ bool gtest_caught_expected = false; \ try { \ GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ } \ catch (expected_exception const&) { \ gtest_caught_expected = true; \ } \ catch (...) { \ gtest_msg.value = \ "Expected: " #statement " throws an exception of type " \ #expected_exception ".\n Actual: it throws a different type."; \ goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__); \ } \ if (!gtest_caught_expected) { \ gtest_msg.value = \ "Expected: " #statement " throws an exception of type " \ #expected_exception ".\n Actual: it throws nothing."; \ goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__); \ } \ } else \ GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__): \ fail(gtest_msg.value) #define GTEST_TEST_NO_THROW_(statement, fail) \ GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ if (::testing::internal::AlwaysTrue()) { \ try { \ GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ } \ catch (...) { \ goto GTEST_CONCAT_TOKEN_(gtest_label_testnothrow_, __LINE__); \ } \ } else \ GTEST_CONCAT_TOKEN_(gtest_label_testnothrow_, __LINE__): \ fail("Expected: " #statement " doesn't throw an exception.\n" \ " Actual: it throws.") #define GTEST_TEST_ANY_THROW_(statement, fail) \ GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ if (::testing::internal::AlwaysTrue()) { \ bool gtest_caught_any = false; \ try { \ GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ } \ catch (...) { \ gtest_caught_any = true; \ } \ if (!gtest_caught_any) { \ goto GTEST_CONCAT_TOKEN_(gtest_label_testanythrow_, __LINE__); \ } \ } else \ GTEST_CONCAT_TOKEN_(gtest_label_testanythrow_, __LINE__): \ fail("Expected: " #statement " throws an exception.\n" \ " Actual: it doesn't.") // Implements Boolean test assertions such as EXPECT_TRUE. expression can be // either a boolean expression or an AssertionResult. text is a textual // represenation of expression as it was passed into the EXPECT_TRUE. #define GTEST_TEST_BOOLEAN_(expression, text, actual, expected, fail) \ GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ if (const ::testing::AssertionResult gtest_ar_ = \ ::testing::AssertionResult(expression)) \ ; \ else \ fail(::testing::internal::GetBoolAssertionFailureMessage(\ gtest_ar_, text, #actual, #expected).c_str()) #define GTEST_TEST_NO_FATAL_FAILURE_(statement, fail) \ GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ if (::testing::internal::AlwaysTrue()) { \ ::testing::internal::HasNewFatalFailureHelper gtest_fatal_failure_checker; \ GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ if (gtest_fatal_failure_checker.has_new_fatal_failure()) { \ goto GTEST_CONCAT_TOKEN_(gtest_label_testnofatal_, __LINE__); \ } \ } else \ GTEST_CONCAT_TOKEN_(gtest_label_testnofatal_, __LINE__): \ fail("Expected: " #statement " doesn't generate new fatal " \ "failures in the current thread.\n" \ " Actual: it does.") // Expands to the name of the class that implements the given test. #define GTEST_TEST_CLASS_NAME_(test_case_name, test_name) \ test_case_name##_##test_name##_Test // Helper macro for defining tests. #define GTEST_TEST_(test_case_name, test_name, parent_class, parent_id)\ class GTEST_TEST_CLASS_NAME_(test_case_name, test_name) : public parent_class {\ public:\ GTEST_TEST_CLASS_NAME_(test_case_name, test_name)() {}\ private:\ virtual void TestBody();\ static ::testing::TestInfo* const test_info_ GTEST_ATTRIBUTE_UNUSED_;\ GTEST_DISALLOW_COPY_AND_ASSIGN_(\ GTEST_TEST_CLASS_NAME_(test_case_name, test_name));\ };\ \ ::testing::TestInfo* const GTEST_TEST_CLASS_NAME_(test_case_name, test_name)\ ::test_info_ =\ ::testing::internal::MakeAndRegisterTestInfo(\ #test_case_name, #test_name, NULL, NULL, \ (parent_id), \ parent_class::SetUpTestCase, \ parent_class::TearDownTestCase, \ new ::testing::internal::TestFactoryImpl<\ GTEST_TEST_CLASS_NAME_(test_case_name, test_name)>);\ void GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::TestBody() #endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_ // Copyright 2005, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: wan@google.com (Zhanyong Wan) // // The Google C++ Testing Framework (Google Test) // // This header file defines the public API for death tests. It is // #included by gtest.h so a user doesn't need to include this // directly. #ifndef GTEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_ #define GTEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_ // Copyright 2005, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Authors: wan@google.com (Zhanyong Wan), eefacm@gmail.com (Sean Mcafee) // // The Google C++ Testing Framework (Google Test) // // This header file defines internal utilities needed for implementing // death tests. They are subject to change without notice. #ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_ #define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_ #include namespace testing { namespace internal { GTEST_DECLARE_string_(internal_run_death_test); // Names of the flags (needed for parsing Google Test flags). const char kDeathTestStyleFlag[] = "death_test_style"; const char kDeathTestUseFork[] = "death_test_use_fork"; const char kInternalRunDeathTestFlag[] = "internal_run_death_test"; #if GTEST_HAS_DEATH_TEST // DeathTest is a class that hides much of the complexity of the // GTEST_DEATH_TEST_ macro. It is abstract; its static Create method // returns a concrete class that depends on the prevailing death test // style, as defined by the --gtest_death_test_style and/or // --gtest_internal_run_death_test flags. // In describing the results of death tests, these terms are used with // the corresponding definitions: // // exit status: The integer exit information in the format specified // by wait(2) // exit code: The integer code passed to exit(3), _exit(2), or // returned from main() class GTEST_API_ DeathTest { public: // Create returns false if there was an error determining the // appropriate action to take for the current death test; for example, // if the gtest_death_test_style flag is set to an invalid value. // The LastMessage method will return a more detailed message in that // case. Otherwise, the DeathTest pointer pointed to by the "test" // argument is set. If the death test should be skipped, the pointer // is set to NULL; otherwise, it is set to the address of a new concrete // DeathTest object that controls the execution of the current test. static bool Create(const char* statement, const RE* regex, const char* file, int line, DeathTest** test); DeathTest(); virtual ~DeathTest() { } // A helper class that aborts a death test when it's deleted. class ReturnSentinel { public: explicit ReturnSentinel(DeathTest* test) : test_(test) { } ~ReturnSentinel() { test_->Abort(TEST_ENCOUNTERED_RETURN_STATEMENT); } private: DeathTest* const test_; GTEST_DISALLOW_COPY_AND_ASSIGN_(ReturnSentinel); } GTEST_ATTRIBUTE_UNUSED_; // An enumeration of possible roles that may be taken when a death // test is encountered. EXECUTE means that the death test logic should // be executed immediately. OVERSEE means that the program should prepare // the appropriate environment for a child process to execute the death // test, then wait for it to complete. enum TestRole { OVERSEE_TEST, EXECUTE_TEST }; // An enumeration of the three reasons that a test might be aborted. enum AbortReason { TEST_ENCOUNTERED_RETURN_STATEMENT, TEST_THREW_EXCEPTION, TEST_DID_NOT_DIE }; // Assumes one of the above roles. virtual TestRole AssumeRole() = 0; // Waits for the death test to finish and returns its status. virtual int Wait() = 0; // Returns true if the death test passed; that is, the test process // exited during the test, its exit status matches a user-supplied // predicate, and its stderr output matches a user-supplied regular // expression. // The user-supplied predicate may be a macro expression rather // than a function pointer or functor, or else Wait and Passed could // be combined. virtual bool Passed(bool exit_status_ok) = 0; // Signals that the death test did not die as expected. virtual void Abort(AbortReason reason) = 0; // Returns a human-readable outcome message regarding the outcome of // the last death test. static const char* LastMessage(); static void set_last_death_test_message(const std::string& message); private: // A string containing a description of the outcome of the last death test. static std::string last_death_test_message_; GTEST_DISALLOW_COPY_AND_ASSIGN_(DeathTest); }; // Factory interface for death tests. May be mocked out for testing. class DeathTestFactory { public: virtual ~DeathTestFactory() { } virtual bool Create(const char* statement, const RE* regex, const char* file, int line, DeathTest** test) = 0; }; // A concrete DeathTestFactory implementation for normal use. class DefaultDeathTestFactory : public DeathTestFactory { public: virtual bool Create(const char* statement, const RE* regex, const char* file, int line, DeathTest** test); }; // Returns true if exit_status describes a process that was terminated // by a signal, or exited normally with a nonzero exit code. GTEST_API_ bool ExitedUnsuccessfully(int exit_status); // Traps C++ exceptions escaping statement and reports them as test // failures. Note that trapping SEH exceptions is not implemented here. # if GTEST_HAS_EXCEPTIONS # define GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, death_test) \ try { \ GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ } catch (const ::std::exception& gtest_exception) { \ fprintf(\ stderr, \ "\n%s: Caught std::exception-derived exception escaping the " \ "death test statement. Exception message: %s\n", \ ::testing::internal::FormatFileLocation(__FILE__, __LINE__).c_str(), \ gtest_exception.what()); \ fflush(stderr); \ death_test->Abort(::testing::internal::DeathTest::TEST_THREW_EXCEPTION); \ } catch (...) { \ death_test->Abort(::testing::internal::DeathTest::TEST_THREW_EXCEPTION); \ } # else # define GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, death_test) \ GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement) # endif // This macro is for implementing ASSERT_DEATH*, EXPECT_DEATH*, // ASSERT_EXIT*, and EXPECT_EXIT*. # define GTEST_DEATH_TEST_(statement, predicate, regex, fail) \ GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ if (::testing::internal::AlwaysTrue()) { \ const ::testing::internal::RE& gtest_regex = (regex); \ ::testing::internal::DeathTest* gtest_dt; \ if (!::testing::internal::DeathTest::Create(#statement, >est_regex, \ __FILE__, __LINE__, >est_dt)) { \ goto GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__); \ } \ if (gtest_dt != NULL) { \ ::testing::internal::scoped_ptr< ::testing::internal::DeathTest> \ gtest_dt_ptr(gtest_dt); \ switch (gtest_dt->AssumeRole()) { \ case ::testing::internal::DeathTest::OVERSEE_TEST: \ if (!gtest_dt->Passed(predicate(gtest_dt->Wait()))) { \ goto GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__); \ } \ break; \ case ::testing::internal::DeathTest::EXECUTE_TEST: { \ ::testing::internal::DeathTest::ReturnSentinel \ gtest_sentinel(gtest_dt); \ GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, gtest_dt); \ gtest_dt->Abort(::testing::internal::DeathTest::TEST_DID_NOT_DIE); \ break; \ } \ default: \ break; \ } \ } \ } else \ GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__): \ fail(::testing::internal::DeathTest::LastMessage()) // The symbol "fail" here expands to something into which a message // can be streamed. // This macro is for implementing ASSERT/EXPECT_DEBUG_DEATH when compiled in // NDEBUG mode. In this case we need the statements to be executed, the regex is // ignored, and the macro must accept a streamed message even though the message // is never printed. # define GTEST_EXECUTE_STATEMENT_(statement, regex) \ GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ if (::testing::internal::AlwaysTrue()) { \ GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ } else \ ::testing::Message() // A class representing the parsed contents of the // --gtest_internal_run_death_test flag, as it existed when // RUN_ALL_TESTS was called. class InternalRunDeathTestFlag { public: InternalRunDeathTestFlag(const std::string& a_file, int a_line, int an_index, int a_write_fd) : file_(a_file), line_(a_line), index_(an_index), write_fd_(a_write_fd) {} ~InternalRunDeathTestFlag() { if (write_fd_ >= 0) posix::Close(write_fd_); } const std::string& file() const { return file_; } int line() const { return line_; } int index() const { return index_; } int write_fd() const { return write_fd_; } private: std::string file_; int line_; int index_; int write_fd_; GTEST_DISALLOW_COPY_AND_ASSIGN_(InternalRunDeathTestFlag); }; // Returns a newly created InternalRunDeathTestFlag object with fields // initialized from the GTEST_FLAG(internal_run_death_test) flag if // the flag is specified; otherwise returns NULL. InternalRunDeathTestFlag* ParseInternalRunDeathTestFlag(); #else // GTEST_HAS_DEATH_TEST // This macro is used for implementing macros such as // EXPECT_DEATH_IF_SUPPORTED and ASSERT_DEATH_IF_SUPPORTED on systems where // death tests are not supported. Those macros must compile on such systems // iff EXPECT_DEATH and ASSERT_DEATH compile with the same parameters on // systems that support death tests. This allows one to write such a macro // on a system that does not support death tests and be sure that it will // compile on a death-test supporting system. // // Parameters: // statement - A statement that a macro such as EXPECT_DEATH would test // for program termination. This macro has to make sure this // statement is compiled but not executed, to ensure that // EXPECT_DEATH_IF_SUPPORTED compiles with a certain // parameter iff EXPECT_DEATH compiles with it. // regex - A regex that a macro such as EXPECT_DEATH would use to test // the output of statement. This parameter has to be // compiled but not evaluated by this macro, to ensure that // this macro only accepts expressions that a macro such as // EXPECT_DEATH would accept. // terminator - Must be an empty statement for EXPECT_DEATH_IF_SUPPORTED // and a return statement for ASSERT_DEATH_IF_SUPPORTED. // This ensures that ASSERT_DEATH_IF_SUPPORTED will not // compile inside functions where ASSERT_DEATH doesn't // compile. // // The branch that has an always false condition is used to ensure that // statement and regex are compiled (and thus syntactically correct) but // never executed. The unreachable code macro protects the terminator // statement from generating an 'unreachable code' warning in case // statement unconditionally returns or throws. The Message constructor at // the end allows the syntax of streaming additional messages into the // macro, for compilational compatibility with EXPECT_DEATH/ASSERT_DEATH. # define GTEST_UNSUPPORTED_DEATH_TEST_(statement, regex, terminator) \ GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ if (::testing::internal::AlwaysTrue()) { \ GTEST_LOG_(WARNING) \ << "Death tests are not supported on this platform.\n" \ << "Statement '" #statement "' cannot be verified."; \ } else if (::testing::internal::AlwaysFalse()) { \ ::testing::internal::RE::PartialMatch(".*", (regex)); \ GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ terminator; \ } else \ ::testing::Message() #endif // GTEST_HAS_DEATH_TEST } // namespace internal } // namespace testing #endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_ namespace testing { // This flag controls the style of death tests. Valid values are "threadsafe", // meaning that the death test child process will re-execute the test binary // from the start, running only a single death test, or "fast", // meaning that the child process will execute the test logic immediately // after forking. GTEST_DECLARE_string_(death_test_style); #if GTEST_HAS_DEATH_TEST namespace internal { // Returns a Boolean value indicating whether the caller is currently // executing in the context of the death test child process. Tools such as // Valgrind heap checkers may need this to modify their behavior in death // tests. IMPORTANT: This is an internal utility. Using it may break the // implementation of death tests. User code MUST NOT use it. GTEST_API_ bool InDeathTestChild(); } // namespace internal // The following macros are useful for writing death tests. // Here's what happens when an ASSERT_DEATH* or EXPECT_DEATH* is // executed: // // 1. It generates a warning if there is more than one active // thread. This is because it's safe to fork() or clone() only // when there is a single thread. // // 2. The parent process clone()s a sub-process and runs the death // test in it; the sub-process exits with code 0 at the end of the // death test, if it hasn't exited already. // // 3. The parent process waits for the sub-process to terminate. // // 4. The parent process checks the exit code and error message of // the sub-process. // // Examples: // // ASSERT_DEATH(server.SendMessage(56, "Hello"), "Invalid port number"); // for (int i = 0; i < 5; i++) { // EXPECT_DEATH(server.ProcessRequest(i), // "Invalid request .* in ProcessRequest()") // << "Failed to die on request " << i; // } // // ASSERT_EXIT(server.ExitNow(), ::testing::ExitedWithCode(0), "Exiting"); // // bool KilledBySIGHUP(int exit_code) { // return WIFSIGNALED(exit_code) && WTERMSIG(exit_code) == SIGHUP; // } // // ASSERT_EXIT(client.HangUpServer(), KilledBySIGHUP, "Hanging up!"); // // On the regular expressions used in death tests: // // On POSIX-compliant systems (*nix), we use the library, // which uses the POSIX extended regex syntax. // // On other platforms (e.g. Windows), we only support a simple regex // syntax implemented as part of Google Test. This limited // implementation should be enough most of the time when writing // death tests; though it lacks many features you can find in PCRE // or POSIX extended regex syntax. For example, we don't support // union ("x|y"), grouping ("(xy)"), brackets ("[xy]"), and // repetition count ("x{5,7}"), among others. // // Below is the syntax that we do support. We chose it to be a // subset of both PCRE and POSIX extended regex, so it's easy to // learn wherever you come from. In the following: 'A' denotes a // literal character, period (.), or a single \\ escape sequence; // 'x' and 'y' denote regular expressions; 'm' and 'n' are for // natural numbers. // // c matches any literal character c // \\d matches any decimal digit // \\D matches any character that's not a decimal digit // \\f matches \f // \\n matches \n // \\r matches \r // \\s matches any ASCII whitespace, including \n // \\S matches any character that's not a whitespace // \\t matches \t // \\v matches \v // \\w matches any letter, _, or decimal digit // \\W matches any character that \\w doesn't match // \\c matches any literal character c, which must be a punctuation // . matches any single character except \n // A? matches 0 or 1 occurrences of A // A* matches 0 or many occurrences of A // A+ matches 1 or many occurrences of A // ^ matches the beginning of a string (not that of each line) // $ matches the end of a string (not that of each line) // xy matches x followed by y // // If you accidentally use PCRE or POSIX extended regex features // not implemented by us, you will get a run-time failure. In that // case, please try to rewrite your regular expression within the // above syntax. // // This implementation is *not* meant to be as highly tuned or robust // as a compiled regex library, but should perform well enough for a // death test, which already incurs significant overhead by launching // a child process. // // Known caveats: // // A "threadsafe" style death test obtains the path to the test // program from argv[0] and re-executes it in the sub-process. For // simplicity, the current implementation doesn't search the PATH // when launching the sub-process. This means that the user must // invoke the test program via a path that contains at least one // path separator (e.g. path/to/foo_test and // /absolute/path/to/bar_test are fine, but foo_test is not). This // is rarely a problem as people usually don't put the test binary // directory in PATH. // // TODO(wan@google.com): make thread-safe death tests search the PATH. // Asserts that a given statement causes the program to exit, with an // integer exit status that satisfies predicate, and emitting error output // that matches regex. # define ASSERT_EXIT(statement, predicate, regex) \ GTEST_DEATH_TEST_(statement, predicate, regex, GTEST_FATAL_FAILURE_) // Like ASSERT_EXIT, but continues on to successive tests in the // test case, if any: # define EXPECT_EXIT(statement, predicate, regex) \ GTEST_DEATH_TEST_(statement, predicate, regex, GTEST_NONFATAL_FAILURE_) // Asserts that a given statement causes the program to exit, either by // explicitly exiting with a nonzero exit code or being killed by a // signal, and emitting error output that matches regex. # define ASSERT_DEATH(statement, regex) \ ASSERT_EXIT(statement, ::testing::internal::ExitedUnsuccessfully, regex) // Like ASSERT_DEATH, but continues on to successive tests in the // test case, if any: # define EXPECT_DEATH(statement, regex) \ EXPECT_EXIT(statement, ::testing::internal::ExitedUnsuccessfully, regex) // Two predicate classes that can be used in {ASSERT,EXPECT}_EXIT*: // Tests that an exit code describes a normal exit with a given exit code. class GTEST_API_ ExitedWithCode { public: explicit ExitedWithCode(int exit_code); bool operator()(int exit_status) const; private: // No implementation - assignment is unsupported. void operator=(const ExitedWithCode& other); const int exit_code_; }; # if !GTEST_OS_WINDOWS // Tests that an exit code describes an exit due to termination by a // given signal. class GTEST_API_ KilledBySignal { public: explicit KilledBySignal(int signum); bool operator()(int exit_status) const; private: const int signum_; }; # endif // !GTEST_OS_WINDOWS // EXPECT_DEBUG_DEATH asserts that the given statements die in debug mode. // The death testing framework causes this to have interesting semantics, // since the sideeffects of the call are only visible in opt mode, and not // in debug mode. // // In practice, this can be used to test functions that utilize the // LOG(DFATAL) macro using the following style: // // int DieInDebugOr12(int* sideeffect) { // if (sideeffect) { // *sideeffect = 12; // } // LOG(DFATAL) << "death"; // return 12; // } // // TEST(TestCase, TestDieOr12WorksInDgbAndOpt) { // int sideeffect = 0; // // Only asserts in dbg. // EXPECT_DEBUG_DEATH(DieInDebugOr12(&sideeffect), "death"); // // #ifdef NDEBUG // // opt-mode has sideeffect visible. // EXPECT_EQ(12, sideeffect); // #else // // dbg-mode no visible sideeffect. // EXPECT_EQ(0, sideeffect); // #endif // } // // This will assert that DieInDebugReturn12InOpt() crashes in debug // mode, usually due to a DCHECK or LOG(DFATAL), but returns the // appropriate fallback value (12 in this case) in opt mode. If you // need to test that a function has appropriate side-effects in opt // mode, include assertions against the side-effects. A general // pattern for this is: // // EXPECT_DEBUG_DEATH({ // // Side-effects here will have an effect after this statement in // // opt mode, but none in debug mode. // EXPECT_EQ(12, DieInDebugOr12(&sideeffect)); // }, "death"); // # ifdef NDEBUG # define EXPECT_DEBUG_DEATH(statement, regex) \ GTEST_EXECUTE_STATEMENT_(statement, regex) # define ASSERT_DEBUG_DEATH(statement, regex) \ GTEST_EXECUTE_STATEMENT_(statement, regex) # else # define EXPECT_DEBUG_DEATH(statement, regex) \ EXPECT_DEATH(statement, regex) # define ASSERT_DEBUG_DEATH(statement, regex) \ ASSERT_DEATH(statement, regex) # endif // NDEBUG for EXPECT_DEBUG_DEATH #endif // GTEST_HAS_DEATH_TEST // EXPECT_DEATH_IF_SUPPORTED(statement, regex) and // ASSERT_DEATH_IF_SUPPORTED(statement, regex) expand to real death tests if // death tests are supported; otherwise they just issue a warning. This is // useful when you are combining death test assertions with normal test // assertions in one test. #if GTEST_HAS_DEATH_TEST # define EXPECT_DEATH_IF_SUPPORTED(statement, regex) \ EXPECT_DEATH(statement, regex) # define ASSERT_DEATH_IF_SUPPORTED(statement, regex) \ ASSERT_DEATH(statement, regex) #else # define EXPECT_DEATH_IF_SUPPORTED(statement, regex) \ GTEST_UNSUPPORTED_DEATH_TEST_(statement, regex, ) # define ASSERT_DEATH_IF_SUPPORTED(statement, regex) \ GTEST_UNSUPPORTED_DEATH_TEST_(statement, regex, return) #endif } // namespace testing #endif // GTEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_ // This file was GENERATED by command: // pump.py gtest-param-test.h.pump // DO NOT EDIT BY HAND!!! // Copyright 2008, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Authors: vladl@google.com (Vlad Losev) // // Macros and functions for implementing parameterized tests // in Google C++ Testing Framework (Google Test) // // This file is generated by a SCRIPT. DO NOT EDIT BY HAND! // #ifndef GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_ #define GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_ // Value-parameterized tests allow you to test your code with different // parameters without writing multiple copies of the same test. // // Here is how you use value-parameterized tests: #if 0 // To write value-parameterized tests, first you should define a fixture // class. It is usually derived from testing::TestWithParam (see below for // another inheritance scheme that's sometimes useful in more complicated // class hierarchies), where the type of your parameter values. // TestWithParam is itself derived from testing::Test. T can be any // copyable type. If it's a raw pointer, you are responsible for managing the // lifespan of the pointed values. class FooTest : public ::testing::TestWithParam { // You can implement all the usual class fixture members here. }; // Then, use the TEST_P macro to define as many parameterized tests // for this fixture as you want. The _P suffix is for "parameterized" // or "pattern", whichever you prefer to think. TEST_P(FooTest, DoesBlah) { // Inside a test, access the test parameter with the GetParam() method // of the TestWithParam class: EXPECT_TRUE(foo.Blah(GetParam())); ... } TEST_P(FooTest, HasBlahBlah) { ... } // Finally, you can use INSTANTIATE_TEST_CASE_P to instantiate the test // case with any set of parameters you want. Google Test defines a number // of functions for generating test parameters. They return what we call // (surprise!) parameter generators. Here is a summary of them, which // are all in the testing namespace: // // // Range(begin, end [, step]) - Yields values {begin, begin+step, // begin+step+step, ...}. The values do not // include end. step defaults to 1. // Values(v1, v2, ..., vN) - Yields values {v1, v2, ..., vN}. // ValuesIn(container) - Yields values from a C-style array, an STL // ValuesIn(begin,end) container, or an iterator range [begin, end). // Bool() - Yields sequence {false, true}. // Combine(g1, g2, ..., gN) - Yields all combinations (the Cartesian product // for the math savvy) of the values generated // by the N generators. // // For more details, see comments at the definitions of these functions below // in this file. // // The following statement will instantiate tests from the FooTest test case // each with parameter values "meeny", "miny", and "moe". INSTANTIATE_TEST_CASE_P(InstantiationName, FooTest, Values("meeny", "miny", "moe")); // To distinguish different instances of the pattern, (yes, you // can instantiate it more then once) the first argument to the // INSTANTIATE_TEST_CASE_P macro is a prefix that will be added to the // actual test case name. Remember to pick unique prefixes for different // instantiations. The tests from the instantiation above will have // these names: // // * InstantiationName/FooTest.DoesBlah/0 for "meeny" // * InstantiationName/FooTest.DoesBlah/1 for "miny" // * InstantiationName/FooTest.DoesBlah/2 for "moe" // * InstantiationName/FooTest.HasBlahBlah/0 for "meeny" // * InstantiationName/FooTest.HasBlahBlah/1 for "miny" // * InstantiationName/FooTest.HasBlahBlah/2 for "moe" // // You can use these names in --gtest_filter. // // This statement will instantiate all tests from FooTest again, each // with parameter values "cat" and "dog": const char* pets[] = {"cat", "dog"}; INSTANTIATE_TEST_CASE_P(AnotherInstantiationName, FooTest, ValuesIn(pets)); // The tests from the instantiation above will have these names: // // * AnotherInstantiationName/FooTest.DoesBlah/0 for "cat" // * AnotherInstantiationName/FooTest.DoesBlah/1 for "dog" // * AnotherInstantiationName/FooTest.HasBlahBlah/0 for "cat" // * AnotherInstantiationName/FooTest.HasBlahBlah/1 for "dog" // // Please note that INSTANTIATE_TEST_CASE_P will instantiate all tests // in the given test case, whether their definitions come before or // AFTER the INSTANTIATE_TEST_CASE_P statement. // // Please also note that generator expressions (including parameters to the // generators) are evaluated in InitGoogleTest(), after main() has started. // This allows the user on one hand, to adjust generator parameters in order // to dynamically determine a set of tests to run and on the other hand, // give the user a chance to inspect the generated tests with Google Test // reflection API before RUN_ALL_TESTS() is executed. // // You can see samples/sample7_unittest.cc and samples/sample8_unittest.cc // for more examples. // // In the future, we plan to publish the API for defining new parameter // generators. But for now this interface remains part of the internal // implementation and is subject to change. // // // A parameterized test fixture must be derived from testing::Test and from // testing::WithParamInterface, where T is the type of the parameter // values. Inheriting from TestWithParam satisfies that requirement because // TestWithParam inherits from both Test and WithParamInterface. In more // complicated hierarchies, however, it is occasionally useful to inherit // separately from Test and WithParamInterface. For example: class BaseTest : public ::testing::Test { // You can inherit all the usual members for a non-parameterized test // fixture here. }; class DerivedTest : public BaseTest, public ::testing::WithParamInterface { // The usual test fixture members go here too. }; TEST_F(BaseTest, HasFoo) { // This is an ordinary non-parameterized test. } TEST_P(DerivedTest, DoesBlah) { // GetParam works just the same here as if you inherit from TestWithParam. EXPECT_TRUE(foo.Blah(GetParam())); } #endif // 0 #if !GTEST_OS_SYMBIAN # include #endif // scripts/fuse_gtest.py depends on gtest's own header being #included // *unconditionally*. Therefore these #includes cannot be moved // inside #if GTEST_HAS_PARAM_TEST. // Copyright 2008 Google Inc. // All Rights Reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: vladl@google.com (Vlad Losev) // Type and function utilities for implementing parameterized tests. #ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_ #define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_ #include #include #include // scripts/fuse_gtest.py depends on gtest's own header being #included // *unconditionally*. Therefore these #includes cannot be moved // inside #if GTEST_HAS_PARAM_TEST. // Copyright 2003 Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Authors: Dan Egnor (egnor@google.com) // // A "smart" pointer type with reference tracking. Every pointer to a // particular object is kept on a circular linked list. When the last pointer // to an object is destroyed or reassigned, the object is deleted. // // Used properly, this deletes the object when the last reference goes away. // There are several caveats: // - Like all reference counting schemes, cycles lead to leaks. // - Each smart pointer is actually two pointers (8 bytes instead of 4). // - Every time a pointer is assigned, the entire list of pointers to that // object is traversed. This class is therefore NOT SUITABLE when there // will often be more than two or three pointers to a particular object. // - References are only tracked as long as linked_ptr<> objects are copied. // If a linked_ptr<> is converted to a raw pointer and back, BAD THINGS // will happen (double deletion). // // A good use of this class is storing object references in STL containers. // You can safely put linked_ptr<> in a vector<>. // Other uses may not be as good. // // Note: If you use an incomplete type with linked_ptr<>, the class // *containing* linked_ptr<> must have a constructor and destructor (even // if they do nothing!). // // Bill Gibbons suggested we use something like this. // // Thread Safety: // Unlike other linked_ptr implementations, in this implementation // a linked_ptr object is thread-safe in the sense that: // - it's safe to copy linked_ptr objects concurrently, // - it's safe to copy *from* a linked_ptr and read its underlying // raw pointer (e.g. via get()) concurrently, and // - it's safe to write to two linked_ptrs that point to the same // shared object concurrently. // TODO(wan@google.com): rename this to safe_linked_ptr to avoid // confusion with normal linked_ptr. #ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_LINKED_PTR_H_ #define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_LINKED_PTR_H_ #include #include namespace testing { namespace internal { // Protects copying of all linked_ptr objects. GTEST_API_ GTEST_DECLARE_STATIC_MUTEX_(g_linked_ptr_mutex); // This is used internally by all instances of linked_ptr<>. It needs to be // a non-template class because different types of linked_ptr<> can refer to // the same object (linked_ptr(obj) vs linked_ptr(obj)). // So, it needs to be possible for different types of linked_ptr to participate // in the same circular linked list, so we need a single class type here. // // DO NOT USE THIS CLASS DIRECTLY YOURSELF. Use linked_ptr. class linked_ptr_internal { public: // Create a new circle that includes only this instance. void join_new() { next_ = this; } // Many linked_ptr operations may change p.link_ for some linked_ptr // variable p in the same circle as this object. Therefore we need // to prevent two such operations from occurring concurrently. // // Note that different types of linked_ptr objects can coexist in a // circle (e.g. linked_ptr, linked_ptr, and // linked_ptr). Therefore we must use a single mutex to // protect all linked_ptr objects. This can create serious // contention in production code, but is acceptable in a testing // framework. // Join an existing circle. void join(linked_ptr_internal const* ptr) GTEST_LOCK_EXCLUDED_(g_linked_ptr_mutex) { MutexLock lock(&g_linked_ptr_mutex); linked_ptr_internal const* p = ptr; while (p->next_ != ptr) p = p->next_; p->next_ = this; next_ = ptr; } // Leave whatever circle we're part of. Returns true if we were the // last member of the circle. Once this is done, you can join() another. bool depart() GTEST_LOCK_EXCLUDED_(g_linked_ptr_mutex) { MutexLock lock(&g_linked_ptr_mutex); if (next_ == this) return true; linked_ptr_internal const* p = next_; while (p->next_ != this) p = p->next_; p->next_ = next_; return false; } private: mutable linked_ptr_internal const* next_; }; template class linked_ptr { public: typedef T element_type; // Take over ownership of a raw pointer. This should happen as soon as // possible after the object is created. explicit linked_ptr(T* ptr = NULL) { capture(ptr); } ~linked_ptr() { depart(); } // Copy an existing linked_ptr<>, adding ourselves to the list of references. template linked_ptr(linked_ptr const& ptr) { copy(&ptr); } linked_ptr(linked_ptr const& ptr) { // NOLINT assert(&ptr != this); copy(&ptr); } // Assignment releases the old value and acquires the new. template linked_ptr& operator=(linked_ptr const& ptr) { depart(); copy(&ptr); return *this; } linked_ptr& operator=(linked_ptr const& ptr) { if (&ptr != this) { depart(); copy(&ptr); } return *this; } // Smart pointer members. void reset(T* ptr = NULL) { depart(); capture(ptr); } T* get() const { return value_; } T* operator->() const { return value_; } T& operator*() const { return *value_; } bool operator==(T* p) const { return value_ == p; } bool operator!=(T* p) const { return value_ != p; } template bool operator==(linked_ptr const& ptr) const { return value_ == ptr.get(); } template bool operator!=(linked_ptr const& ptr) const { return value_ != ptr.get(); } private: template friend class linked_ptr; T* value_; linked_ptr_internal link_; void depart() { if (link_.depart()) delete value_; } void capture(T* ptr) { value_ = ptr; link_.join_new(); } template void copy(linked_ptr const* ptr) { value_ = ptr->get(); if (value_) link_.join(&ptr->link_); else link_.join_new(); } }; template inline bool operator==(T* ptr, const linked_ptr& x) { return ptr == x.get(); } template inline bool operator!=(T* ptr, const linked_ptr& x) { return ptr != x.get(); } // A function to convert T* into linked_ptr // Doing e.g. make_linked_ptr(new FooBarBaz(arg)) is a shorter notation // for linked_ptr >(new FooBarBaz(arg)) template linked_ptr make_linked_ptr(T* ptr) { return linked_ptr(ptr); } } // namespace internal } // namespace testing #endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_LINKED_PTR_H_ // Copyright 2007, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: wan@google.com (Zhanyong Wan) // Google Test - The Google C++ Testing Framework // // This file implements a universal value printer that can print a // value of any type T: // // void ::testing::internal::UniversalPrinter::Print(value, ostream_ptr); // // A user can teach this function how to print a class type T by // defining either operator<<() or PrintTo() in the namespace that // defines T. More specifically, the FIRST defined function in the // following list will be used (assuming T is defined in namespace // foo): // // 1. foo::PrintTo(const T&, ostream*) // 2. operator<<(ostream&, const T&) defined in either foo or the // global namespace. // // If none of the above is defined, it will print the debug string of // the value if it is a protocol buffer, or print the raw bytes in the // value otherwise. // // To aid debugging: when T is a reference type, the address of the // value is also printed; when T is a (const) char pointer, both the // pointer value and the NUL-terminated string it points to are // printed. // // We also provide some convenient wrappers: // // // Prints a value to a string. For a (const or not) char // // pointer, the NUL-terminated string (but not the pointer) is // // printed. // std::string ::testing::PrintToString(const T& value); // // // Prints a value tersely: for a reference type, the referenced // // value (but not the address) is printed; for a (const or not) char // // pointer, the NUL-terminated string (but not the pointer) is // // printed. // void ::testing::internal::UniversalTersePrint(const T& value, ostream*); // // // Prints value using the type inferred by the compiler. The difference // // from UniversalTersePrint() is that this function prints both the // // pointer and the NUL-terminated string for a (const or not) char pointer. // void ::testing::internal::UniversalPrint(const T& value, ostream*); // // // Prints the fields of a tuple tersely to a string vector, one // // element for each field. Tuple support must be enabled in // // gtest-port.h. // std::vector UniversalTersePrintTupleFieldsToStrings( // const Tuple& value); // // Known limitation: // // The print primitives print the elements of an STL-style container // using the compiler-inferred type of *iter where iter is a // const_iterator of the container. When const_iterator is an input // iterator but not a forward iterator, this inferred type may not // match value_type, and the print output may be incorrect. In // practice, this is rarely a problem as for most containers // const_iterator is a forward iterator. We'll fix this if there's an // actual need for it. Note that this fix cannot rely on value_type // being defined as many user-defined container types don't have // value_type. #ifndef GTEST_INCLUDE_GTEST_GTEST_PRINTERS_H_ #define GTEST_INCLUDE_GTEST_GTEST_PRINTERS_H_ #include // NOLINT #include #include #include #include namespace testing { // Definitions in the 'internal' and 'internal2' name spaces are // subject to change without notice. DO NOT USE THEM IN USER CODE! namespace internal2 { // Prints the given number of bytes in the given object to the given // ostream. GTEST_API_ void PrintBytesInObjectTo(const unsigned char* obj_bytes, size_t count, ::std::ostream* os); // For selecting which printer to use when a given type has neither << // nor PrintTo(). enum TypeKind { kProtobuf, // a protobuf type kConvertibleToInteger, // a type implicitly convertible to BiggestInt // (e.g. a named or unnamed enum type) kOtherType // anything else }; // TypeWithoutFormatter::PrintValue(value, os) is called // by the universal printer to print a value of type T when neither // operator<< nor PrintTo() is defined for T, where kTypeKind is the // "kind" of T as defined by enum TypeKind. template class TypeWithoutFormatter { public: // This default version is called when kTypeKind is kOtherType. static void PrintValue(const T& value, ::std::ostream* os) { PrintBytesInObjectTo(reinterpret_cast(&value), sizeof(value), os); } }; // We print a protobuf using its ShortDebugString() when the string // doesn't exceed this many characters; otherwise we print it using // DebugString() for better readability. const size_t kProtobufOneLinerMaxLength = 50; template class TypeWithoutFormatter { public: static void PrintValue(const T& value, ::std::ostream* os) { const ::testing::internal::string short_str = value.ShortDebugString(); const ::testing::internal::string pretty_str = short_str.length() <= kProtobufOneLinerMaxLength ? short_str : ("\n" + value.DebugString()); *os << ("<" + pretty_str + ">"); } }; template class TypeWithoutFormatter { public: // Since T has no << operator or PrintTo() but can be implicitly // converted to BiggestInt, we print it as a BiggestInt. // // Most likely T is an enum type (either named or unnamed), in which // case printing it as an integer is the desired behavior. In case // T is not an enum, printing it as an integer is the best we can do // given that it has no user-defined printer. static void PrintValue(const T& value, ::std::ostream* os) { const internal::BiggestInt kBigInt = value; *os << kBigInt; } }; // Prints the given value to the given ostream. If the value is a // protocol message, its debug string is printed; if it's an enum or // of a type implicitly convertible to BiggestInt, it's printed as an // integer; otherwise the bytes in the value are printed. This is // what UniversalPrinter::Print() does when it knows nothing about // type T and T has neither << operator nor PrintTo(). // // A user can override this behavior for a class type Foo by defining // a << operator in the namespace where Foo is defined. // // We put this operator in namespace 'internal2' instead of 'internal' // to simplify the implementation, as much code in 'internal' needs to // use << in STL, which would conflict with our own << were it defined // in 'internal'. // // Note that this operator<< takes a generic std::basic_ostream type instead of the more restricted std::ostream. If // we define it to take an std::ostream instead, we'll get an // "ambiguous overloads" compiler error when trying to print a type // Foo that supports streaming to std::basic_ostream, as the compiler cannot tell whether // operator<<(std::ostream&, const T&) or // operator<<(std::basic_stream, const Foo&) is more // specific. template ::std::basic_ostream& operator<<( ::std::basic_ostream& os, const T& x) { TypeWithoutFormatter::value ? kProtobuf : internal::ImplicitlyConvertible::value ? kConvertibleToInteger : kOtherType)>::PrintValue(x, &os); return os; } } // namespace internal2 } // namespace testing // This namespace MUST NOT BE NESTED IN ::testing, or the name look-up // magic needed for implementing UniversalPrinter won't work. namespace testing_internal { // Used to print a value that is not an STL-style container when the // user doesn't define PrintTo() for it. template void DefaultPrintNonContainerTo(const T& value, ::std::ostream* os) { // With the following statement, during unqualified name lookup, // testing::internal2::operator<< appears as if it was declared in // the nearest enclosing namespace that contains both // ::testing_internal and ::testing::internal2, i.e. the global // namespace. For more details, refer to the C++ Standard section // 7.3.4-1 [namespace.udir]. This allows us to fall back onto // testing::internal2::operator<< in case T doesn't come with a << // operator. // // We cannot write 'using ::testing::internal2::operator<<;', which // gcc 3.3 fails to compile due to a compiler bug. using namespace ::testing::internal2; // NOLINT // Assuming T is defined in namespace foo, in the next statement, // the compiler will consider all of: // // 1. foo::operator<< (thanks to Koenig look-up), // 2. ::operator<< (as the current namespace is enclosed in ::), // 3. testing::internal2::operator<< (thanks to the using statement above). // // The operator<< whose type matches T best will be picked. // // We deliberately allow #2 to be a candidate, as sometimes it's // impossible to define #1 (e.g. when foo is ::std, defining // anything in it is undefined behavior unless you are a compiler // vendor.). *os << value; } } // namespace testing_internal namespace testing { namespace internal { // UniversalPrinter::Print(value, ostream_ptr) prints the given // value to the given ostream. The caller must ensure that // 'ostream_ptr' is not NULL, or the behavior is undefined. // // We define UniversalPrinter as a class template (as opposed to a // function template), as we need to partially specialize it for // reference types, which cannot be done with function templates. template class UniversalPrinter; template void UniversalPrint(const T& value, ::std::ostream* os); // Used to print an STL-style container when the user doesn't define // a PrintTo() for it. template void DefaultPrintTo(IsContainer /* dummy */, false_type /* is not a pointer */, const C& container, ::std::ostream* os) { const size_t kMaxCount = 32; // The maximum number of elements to print. *os << '{'; size_t count = 0; for (typename C::const_iterator it = container.begin(); it != container.end(); ++it, ++count) { if (count > 0) { *os << ','; if (count == kMaxCount) { // Enough has been printed. *os << " ..."; break; } } *os << ' '; // We cannot call PrintTo(*it, os) here as PrintTo() doesn't // handle *it being a native array. internal::UniversalPrint(*it, os); } if (count > 0) { *os << ' '; } *os << '}'; } // Used to print a pointer that is neither a char pointer nor a member // pointer, when the user doesn't define PrintTo() for it. (A member // variable pointer or member function pointer doesn't really point to // a location in the address space. Their representation is // implementation-defined. Therefore they will be printed as raw // bytes.) template void DefaultPrintTo(IsNotContainer /* dummy */, true_type /* is a pointer */, T* p, ::std::ostream* os) { if (p == NULL) { *os << "NULL"; } else { // C++ doesn't allow casting from a function pointer to any object // pointer. // // IsTrue() silences warnings: "Condition is always true", // "unreachable code". if (IsTrue(ImplicitlyConvertible::value)) { // T is not a function type. We just call << to print p, // relying on ADL to pick up user-defined << for their pointer // types, if any. *os << p; } else { // T is a function type, so '*os << p' doesn't do what we want // (it just prints p as bool). We want to print p as a const // void*. However, we cannot cast it to const void* directly, // even using reinterpret_cast, as earlier versions of gcc // (e.g. 3.4.5) cannot compile the cast when p is a function // pointer. Casting to UInt64 first solves the problem. *os << reinterpret_cast( reinterpret_cast(p)); } } } // Used to print a non-container, non-pointer value when the user // doesn't define PrintTo() for it. template void DefaultPrintTo(IsNotContainer /* dummy */, false_type /* is not a pointer */, const T& value, ::std::ostream* os) { ::testing_internal::DefaultPrintNonContainerTo(value, os); } // Prints the given value using the << operator if it has one; // otherwise prints the bytes in it. This is what // UniversalPrinter::Print() does when PrintTo() is not specialized // or overloaded for type T. // // A user can override this behavior for a class type Foo by defining // an overload of PrintTo() in the namespace where Foo is defined. We // give the user this option as sometimes defining a << operator for // Foo is not desirable (e.g. the coding style may prevent doing it, // or there is already a << operator but it doesn't do what the user // wants). template void PrintTo(const T& value, ::std::ostream* os) { // DefaultPrintTo() is overloaded. The type of its first two // arguments determine which version will be picked. If T is an // STL-style container, the version for container will be called; if // T is a pointer, the pointer version will be called; otherwise the // generic version will be called. // // Note that we check for container types here, prior to we check // for protocol message types in our operator<<. The rationale is: // // For protocol messages, we want to give people a chance to // override Google Mock's format by defining a PrintTo() or // operator<<. For STL containers, other formats can be // incompatible with Google Mock's format for the container // elements; therefore we check for container types here to ensure // that our format is used. // // The second argument of DefaultPrintTo() is needed to bypass a bug // in Symbian's C++ compiler that prevents it from picking the right // overload between: // // PrintTo(const T& x, ...); // PrintTo(T* x, ...); DefaultPrintTo(IsContainerTest(0), is_pointer(), value, os); } // The following list of PrintTo() overloads tells // UniversalPrinter::Print() how to print standard types (built-in // types, strings, plain arrays, and pointers). // Overloads for various char types. GTEST_API_ void PrintTo(unsigned char c, ::std::ostream* os); GTEST_API_ void PrintTo(signed char c, ::std::ostream* os); inline void PrintTo(char c, ::std::ostream* os) { // When printing a plain char, we always treat it as unsigned. This // way, the output won't be affected by whether the compiler thinks // char is signed or not. PrintTo(static_cast(c), os); } // Overloads for other simple built-in types. inline void PrintTo(bool x, ::std::ostream* os) { *os << (x ? "true" : "false"); } // Overload for wchar_t type. // Prints a wchar_t as a symbol if it is printable or as its internal // code otherwise and also as its decimal code (except for L'\0'). // The L'\0' char is printed as "L'\\0'". The decimal code is printed // as signed integer when wchar_t is implemented by the compiler // as a signed type and is printed as an unsigned integer when wchar_t // is implemented as an unsigned type. GTEST_API_ void PrintTo(wchar_t wc, ::std::ostream* os); // Overloads for C strings. GTEST_API_ void PrintTo(const char* s, ::std::ostream* os); inline void PrintTo(char* s, ::std::ostream* os) { PrintTo(ImplicitCast_(s), os); } // signed/unsigned char is often used for representing binary data, so // we print pointers to it as void* to be safe. inline void PrintTo(const signed char* s, ::std::ostream* os) { PrintTo(ImplicitCast_(s), os); } inline void PrintTo(signed char* s, ::std::ostream* os) { PrintTo(ImplicitCast_(s), os); } inline void PrintTo(const unsigned char* s, ::std::ostream* os) { PrintTo(ImplicitCast_(s), os); } inline void PrintTo(unsigned char* s, ::std::ostream* os) { PrintTo(ImplicitCast_(s), os); } // MSVC can be configured to define wchar_t as a typedef of unsigned // short. It defines _NATIVE_WCHAR_T_DEFINED when wchar_t is a native // type. When wchar_t is a typedef, defining an overload for const // wchar_t* would cause unsigned short* be printed as a wide string, // possibly causing invalid memory accesses. #if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED) // Overloads for wide C strings GTEST_API_ void PrintTo(const wchar_t* s, ::std::ostream* os); inline void PrintTo(wchar_t* s, ::std::ostream* os) { PrintTo(ImplicitCast_(s), os); } #endif // Overload for C arrays. Multi-dimensional arrays are printed // properly. // Prints the given number of elements in an array, without printing // the curly braces. template void PrintRawArrayTo(const T a[], size_t count, ::std::ostream* os) { UniversalPrint(a[0], os); for (size_t i = 1; i != count; i++) { *os << ", "; UniversalPrint(a[i], os); } } // Overloads for ::string and ::std::string. #if GTEST_HAS_GLOBAL_STRING GTEST_API_ void PrintStringTo(const ::string&s, ::std::ostream* os); inline void PrintTo(const ::string& s, ::std::ostream* os) { PrintStringTo(s, os); } #endif // GTEST_HAS_GLOBAL_STRING GTEST_API_ void PrintStringTo(const ::std::string&s, ::std::ostream* os); inline void PrintTo(const ::std::string& s, ::std::ostream* os) { PrintStringTo(s, os); } // Overloads for ::wstring and ::std::wstring. #if GTEST_HAS_GLOBAL_WSTRING GTEST_API_ void PrintWideStringTo(const ::wstring&s, ::std::ostream* os); inline void PrintTo(const ::wstring& s, ::std::ostream* os) { PrintWideStringTo(s, os); } #endif // GTEST_HAS_GLOBAL_WSTRING #if GTEST_HAS_STD_WSTRING GTEST_API_ void PrintWideStringTo(const ::std::wstring&s, ::std::ostream* os); inline void PrintTo(const ::std::wstring& s, ::std::ostream* os) { PrintWideStringTo(s, os); } #endif // GTEST_HAS_STD_WSTRING #if GTEST_HAS_TR1_TUPLE // Overload for ::std::tr1::tuple. Needed for printing function arguments, // which are packed as tuples. // Helper function for printing a tuple. T must be instantiated with // a tuple type. template void PrintTupleTo(const T& t, ::std::ostream* os); // Overloaded PrintTo() for tuples of various arities. We support // tuples of up-to 10 fields. The following implementation works // regardless of whether tr1::tuple is implemented using the // non-standard variadic template feature or not. inline void PrintTo(const ::std::tr1::tuple<>& t, ::std::ostream* os) { PrintTupleTo(t, os); } template void PrintTo(const ::std::tr1::tuple& t, ::std::ostream* os) { PrintTupleTo(t, os); } template void PrintTo(const ::std::tr1::tuple& t, ::std::ostream* os) { PrintTupleTo(t, os); } template void PrintTo(const ::std::tr1::tuple& t, ::std::ostream* os) { PrintTupleTo(t, os); } template void PrintTo(const ::std::tr1::tuple& t, ::std::ostream* os) { PrintTupleTo(t, os); } template void PrintTo(const ::std::tr1::tuple& t, ::std::ostream* os) { PrintTupleTo(t, os); } template void PrintTo(const ::std::tr1::tuple& t, ::std::ostream* os) { PrintTupleTo(t, os); } template void PrintTo(const ::std::tr1::tuple& t, ::std::ostream* os) { PrintTupleTo(t, os); } template void PrintTo(const ::std::tr1::tuple& t, ::std::ostream* os) { PrintTupleTo(t, os); } template void PrintTo(const ::std::tr1::tuple& t, ::std::ostream* os) { PrintTupleTo(t, os); } template void PrintTo( const ::std::tr1::tuple& t, ::std::ostream* os) { PrintTupleTo(t, os); } #endif // GTEST_HAS_TR1_TUPLE // Overload for std::pair. template void PrintTo(const ::std::pair& value, ::std::ostream* os) { *os << '('; // We cannot use UniversalPrint(value.first, os) here, as T1 may be // a reference type. The same for printing value.second. UniversalPrinter::Print(value.first, os); *os << ", "; UniversalPrinter::Print(value.second, os); *os << ')'; } // Implements printing a non-reference type T by letting the compiler // pick the right overload of PrintTo() for T. template class UniversalPrinter { public: // MSVC warns about adding const to a function type, so we want to // disable the warning. #ifdef _MSC_VER # pragma warning(push) // Saves the current warning state. # pragma warning(disable:4180) // Temporarily disables warning 4180. #endif // _MSC_VER // Note: we deliberately don't call this PrintTo(), as that name // conflicts with ::testing::internal::PrintTo in the body of the // function. static void Print(const T& value, ::std::ostream* os) { // By default, ::testing::internal::PrintTo() is used for printing // the value. // // Thanks to Koenig look-up, if T is a class and has its own // PrintTo() function defined in its namespace, that function will // be visible here. Since it is more specific than the generic ones // in ::testing::internal, it will be picked by the compiler in the // following statement - exactly what we want. PrintTo(value, os); } #ifdef _MSC_VER # pragma warning(pop) // Restores the warning state. #endif // _MSC_VER }; // UniversalPrintArray(begin, len, os) prints an array of 'len' // elements, starting at address 'begin'. template void UniversalPrintArray(const T* begin, size_t len, ::std::ostream* os) { if (len == 0) { *os << "{}"; } else { *os << "{ "; const size_t kThreshold = 18; const size_t kChunkSize = 8; // If the array has more than kThreshold elements, we'll have to // omit some details by printing only the first and the last // kChunkSize elements. // TODO(wan@google.com): let the user control the threshold using a flag. if (len <= kThreshold) { PrintRawArrayTo(begin, len, os); } else { PrintRawArrayTo(begin, kChunkSize, os); *os << ", ..., "; PrintRawArrayTo(begin + len - kChunkSize, kChunkSize, os); } *os << " }"; } } // This overload prints a (const) char array compactly. GTEST_API_ void UniversalPrintArray( const char* begin, size_t len, ::std::ostream* os); // This overload prints a (const) wchar_t array compactly. GTEST_API_ void UniversalPrintArray( const wchar_t* begin, size_t len, ::std::ostream* os); // Implements printing an array type T[N]. template class UniversalPrinter { public: // Prints the given array, omitting some elements when there are too // many. static void Print(const T (&a)[N], ::std::ostream* os) { UniversalPrintArray(a, N, os); } }; // Implements printing a reference type T&. template 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 static void Print(const T& value, ::std::ostream* os) { // Prints the address of the value. We use reinterpret_cast here // as static_cast doesn't compile when T is a function type. *os << "@" << reinterpret_cast(&value) << " "; // Then prints the value itself. UniversalPrint(value, os); } #ifdef _MSC_VER # pragma warning(pop) // Restores the warning state. #endif // _MSC_VER }; // Prints a value tersely: for a reference type, the referenced value // (but not the address) is printed; for a (const) char pointer, the // NUL-terminated string (but not the pointer) is printed. template class UniversalTersePrinter { public: static void Print(const T& value, ::std::ostream* os) { UniversalPrint(value, os); } }; template class UniversalTersePrinter { public: static void Print(const T& value, ::std::ostream* os) { UniversalPrint(value, os); } }; template class UniversalTersePrinter { public: static void Print(const T (&value)[N], ::std::ostream* os) { UniversalPrinter::Print(value, os); } }; template <> class UniversalTersePrinter { public: static void Print(const char* str, ::std::ostream* os) { if (str == NULL) { *os << "NULL"; } else { UniversalPrint(string(str), os); } } }; template <> class UniversalTersePrinter { public: static void Print(char* str, ::std::ostream* os) { UniversalTersePrinter::Print(str, os); } }; #if GTEST_HAS_STD_WSTRING template <> class UniversalTersePrinter { public: static void Print(const wchar_t* str, ::std::ostream* os) { if (str == NULL) { *os << "NULL"; } else { UniversalPrint(::std::wstring(str), os); } } }; #endif template <> class UniversalTersePrinter { public: static void Print(wchar_t* str, ::std::ostream* os) { UniversalTersePrinter::Print(str, os); } }; template void UniversalTersePrint(const T& value, ::std::ostream* os) { UniversalTersePrinter::Print(value, os); } // Prints a value using the type inferred by the compiler. The // difference between this and UniversalTersePrint() is that for a // (const) char pointer, this prints both the pointer and the // NUL-terminated string. template void UniversalPrint(const T& value, ::std::ostream* os) { // A workarond for the bug in VC++ 7.1 that prevents us from instantiating // UniversalPrinter with T directly. typedef T T1; UniversalPrinter::Print(value, os); } #if GTEST_HAS_TR1_TUPLE typedef ::std::vector Strings; // This helper template allows PrintTo() for tuples and // UniversalTersePrintTupleFieldsToStrings() to be defined by // induction on the number of tuple fields. The idea is that // TuplePrefixPrinter::PrintPrefixTo(t, os) prints the first N // fields in tuple t, and can be defined in terms of // TuplePrefixPrinter. // The inductive case. template struct TuplePrefixPrinter { // Prints the first N fields of a tuple. template static void PrintPrefixTo(const Tuple& t, ::std::ostream* os) { TuplePrefixPrinter::PrintPrefixTo(t, os); *os << ", "; UniversalPrinter::type> ::Print(::std::tr1::get(t), os); } // Tersely prints the first N fields of a tuple to a string vector, // one element for each field. template static void TersePrintPrefixToStrings(const Tuple& t, Strings* strings) { TuplePrefixPrinter::TersePrintPrefixToStrings(t, strings); ::std::stringstream ss; UniversalTersePrint(::std::tr1::get(t), &ss); strings->push_back(ss.str()); } }; // Base cases. template <> struct TuplePrefixPrinter<0> { template static void PrintPrefixTo(const Tuple&, ::std::ostream*) {} template static void TersePrintPrefixToStrings(const Tuple&, Strings*) {} }; // We have to specialize the entire TuplePrefixPrinter<> class // template here, even though the definition of // TersePrintPrefixToStrings() is the same as the generic version, as // Embarcadero (formerly CodeGear, formerly Borland) C++ doesn't // support specializing a method template of a class template. template <> struct TuplePrefixPrinter<1> { template static void PrintPrefixTo(const Tuple& t, ::std::ostream* os) { UniversalPrinter::type>:: Print(::std::tr1::get<0>(t), os); } template static void TersePrintPrefixToStrings(const Tuple& t, Strings* strings) { ::std::stringstream ss; UniversalTersePrint(::std::tr1::get<0>(t), &ss); strings->push_back(ss.str()); } }; // Helper function for printing a tuple. T must be instantiated with // a tuple type. template void PrintTupleTo(const T& t, ::std::ostream* os) { *os << "("; TuplePrefixPrinter< ::std::tr1::tuple_size::value>:: PrintPrefixTo(t, os); *os << ")"; } // Prints the fields of a tuple tersely to a string vector, one // element for each field. See the comment before // UniversalTersePrint() for how we define "tersely". template Strings UniversalTersePrintTupleFieldsToStrings(const Tuple& value) { Strings result; TuplePrefixPrinter< ::std::tr1::tuple_size::value>:: TersePrintPrefixToStrings(value, &result); return result; } #endif // GTEST_HAS_TR1_TUPLE } // namespace internal template ::std::string PrintToString(const T& value) { ::std::stringstream ss; internal::UniversalTersePrinter::Print(value, &ss); return ss.str(); } } // namespace testing #endif // GTEST_INCLUDE_GTEST_GTEST_PRINTERS_H_ #if GTEST_HAS_PARAM_TEST namespace testing { namespace internal { // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. // // Outputs a message explaining invalid registration of different // fixture class for the same test case. This may happen when // TEST_P macro is used to define two tests with the same name // but in different namespaces. GTEST_API_ void ReportInvalidTestCaseType(const char* test_case_name, const char* file, int line); template class ParamGeneratorInterface; template class ParamGenerator; // Interface for iterating over elements provided by an implementation // of ParamGeneratorInterface. template class ParamIteratorInterface { public: virtual ~ParamIteratorInterface() {} // A pointer to the base generator instance. // Used only for the purposes of iterator comparison // to make sure that two iterators belong to the same generator. virtual const ParamGeneratorInterface* BaseGenerator() const = 0; // Advances iterator to point to the next element // provided by the generator. The caller is responsible // for not calling Advance() on an iterator equal to // BaseGenerator()->End(). virtual void Advance() = 0; // Clones the iterator object. Used for implementing copy semantics // of ParamIterator. virtual ParamIteratorInterface* Clone() const = 0; // Dereferences the current iterator and provides (read-only) access // to the pointed value. It is the caller's responsibility not to call // Current() on an iterator equal to BaseGenerator()->End(). // Used for implementing ParamGenerator::operator*(). virtual const T* Current() const = 0; // Determines whether the given iterator and other point to the same // element in the sequence generated by the generator. // Used for implementing ParamGenerator::operator==(). virtual bool Equals(const ParamIteratorInterface& other) const = 0; }; // Class iterating over elements provided by an implementation of // ParamGeneratorInterface. It wraps ParamIteratorInterface // and implements the const forward iterator concept. template class ParamIterator { public: typedef T value_type; typedef const T& reference; typedef ptrdiff_t difference_type; // ParamIterator assumes ownership of the impl_ pointer. ParamIterator(const ParamIterator& other) : impl_(other.impl_->Clone()) {} ParamIterator& operator=(const ParamIterator& other) { if (this != &other) impl_.reset(other.impl_->Clone()); return *this; } const T& operator*() const { return *impl_->Current(); } const T* operator->() const { return impl_->Current(); } // Prefix version of operator++. ParamIterator& operator++() { impl_->Advance(); return *this; } // Postfix version of operator++. ParamIterator operator++(int /*unused*/) { ParamIteratorInterface* clone = impl_->Clone(); impl_->Advance(); return ParamIterator(clone); } bool operator==(const ParamIterator& other) const { return impl_.get() == other.impl_.get() || impl_->Equals(*other.impl_); } bool operator!=(const ParamIterator& other) const { return !(*this == other); } private: friend class ParamGenerator; explicit ParamIterator(ParamIteratorInterface* impl) : impl_(impl) {} scoped_ptr > impl_; }; // ParamGeneratorInterface is the binary interface to access generators // defined in other translation units. template class ParamGeneratorInterface { public: typedef T ParamType; virtual ~ParamGeneratorInterface() {} // Generator interface definition virtual ParamIteratorInterface* Begin() const = 0; virtual ParamIteratorInterface* End() const = 0; }; // Wraps ParamGeneratorInterface and provides general generator syntax // compatible with the STL Container concept. // This class implements copy initialization semantics and the contained // ParamGeneratorInterface instance is shared among all copies // of the original object. This is possible because that instance is immutable. template class ParamGenerator { public: typedef ParamIterator iterator; explicit ParamGenerator(ParamGeneratorInterface* impl) : impl_(impl) {} ParamGenerator(const ParamGenerator& other) : impl_(other.impl_) {} ParamGenerator& operator=(const ParamGenerator& other) { impl_ = other.impl_; return *this; } iterator begin() const { return iterator(impl_->Begin()); } iterator end() const { return iterator(impl_->End()); } private: linked_ptr > impl_; }; // Generates values from a range of two comparable values. Can be used to // generate sequences of user-defined types that implement operator+() and // operator<(). // This class is used in the Range() function. template class RangeGenerator : public ParamGeneratorInterface { public: RangeGenerator(T begin, T end, IncrementT step) : begin_(begin), end_(end), step_(step), end_index_(CalculateEndIndex(begin, end, step)) {} virtual ~RangeGenerator() {} virtual ParamIteratorInterface* Begin() const { return new Iterator(this, begin_, 0, step_); } virtual ParamIteratorInterface* End() const { return new Iterator(this, end_, end_index_, step_); } private: class Iterator : public ParamIteratorInterface { public: Iterator(const ParamGeneratorInterface* base, T value, int index, IncrementT step) : base_(base), value_(value), index_(index), step_(step) {} virtual ~Iterator() {} virtual const ParamGeneratorInterface* BaseGenerator() const { return base_; } virtual void Advance() { value_ = value_ + step_; index_++; } virtual ParamIteratorInterface* Clone() const { return new Iterator(*this); } virtual const T* Current() const { return &value_; } virtual bool Equals(const ParamIteratorInterface& other) const { // Having the same base generator guarantees that the other // iterator is of the same type and we can downcast. GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) << "The program attempted to compare iterators " << "from different generators." << std::endl; const int other_index = CheckedDowncastToActualType(&other)->index_; return index_ == other_index; } private: Iterator(const Iterator& other) : ParamIteratorInterface(), base_(other.base_), value_(other.value_), index_(other.index_), step_(other.step_) {} // No implementation - assignment is unsupported. void operator=(const Iterator& other); const ParamGeneratorInterface* const base_; T value_; int index_; const IncrementT step_; }; // class RangeGenerator::Iterator static int CalculateEndIndex(const T& begin, const T& end, const IncrementT& step) { int end_index = 0; for (T i = begin; i < end; i = i + step) end_index++; return end_index; } // No implementation - assignment is unsupported. void operator=(const RangeGenerator& other); const T begin_; const T end_; const IncrementT step_; // The index for the end() iterator. All the elements in the generated // sequence are indexed (0-based) to aid iterator comparison. const int end_index_; }; // class RangeGenerator // Generates values from a pair of STL-style iterators. Used in the // ValuesIn() function. The elements are copied from the source range // since the source can be located on the stack, and the generator // is likely to persist beyond that stack frame. template class ValuesInIteratorRangeGenerator : public ParamGeneratorInterface { public: template ValuesInIteratorRangeGenerator(ForwardIterator begin, ForwardIterator end) : container_(begin, end) {} virtual ~ValuesInIteratorRangeGenerator() {} virtual ParamIteratorInterface* Begin() const { return new Iterator(this, container_.begin()); } virtual ParamIteratorInterface* End() const { return new Iterator(this, container_.end()); } private: typedef typename ::std::vector ContainerType; class Iterator : public ParamIteratorInterface { public: Iterator(const ParamGeneratorInterface* base, typename ContainerType::const_iterator iterator) : base_(base), iterator_(iterator) {} virtual ~Iterator() {} virtual const ParamGeneratorInterface* BaseGenerator() const { return base_; } virtual void Advance() { ++iterator_; value_.reset(); } virtual ParamIteratorInterface* Clone() const { return new Iterator(*this); } // We need to use cached value referenced by iterator_ because *iterator_ // can return a temporary object (and of type other then T), so just // having "return &*iterator_;" doesn't work. // value_ is updated here and not in Advance() because Advance() // can advance iterator_ beyond the end of the range, and we cannot // detect that fact. The client code, on the other hand, is // responsible for not calling Current() on an out-of-range iterator. virtual const T* Current() const { if (value_.get() == NULL) value_.reset(new T(*iterator_)); return value_.get(); } virtual bool Equals(const ParamIteratorInterface& other) const { // Having the same base generator guarantees that the other // iterator is of the same type and we can downcast. GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) << "The program attempted to compare iterators " << "from different generators." << std::endl; return iterator_ == CheckedDowncastToActualType(&other)->iterator_; } private: Iterator(const Iterator& other) // The explicit constructor call suppresses a false warning // emitted by gcc when supplied with the -Wextra option. : ParamIteratorInterface(), base_(other.base_), iterator_(other.iterator_) {} const ParamGeneratorInterface* const base_; typename ContainerType::const_iterator iterator_; // A cached value of *iterator_. We keep it here to allow access by // pointer in the wrapping iterator's operator->(). // value_ needs to be mutable to be accessed in Current(). // Use of scoped_ptr helps manage cached value's lifetime, // which is bound by the lifespan of the iterator itself. mutable scoped_ptr value_; }; // class ValuesInIteratorRangeGenerator::Iterator // No implementation - assignment is unsupported. void operator=(const ValuesInIteratorRangeGenerator& other); const ContainerType container_; }; // class ValuesInIteratorRangeGenerator // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. // // Stores a parameter value and later creates tests parameterized with that // value. template class ParameterizedTestFactory : public TestFactoryBase { public: typedef typename TestClass::ParamType ParamType; explicit ParameterizedTestFactory(ParamType parameter) : parameter_(parameter) {} virtual Test* CreateTest() { TestClass::SetParam(¶meter_); return new TestClass(); } private: const ParamType parameter_; GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestFactory); }; // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. // // TestMetaFactoryBase is a base class for meta-factories that create // test factories for passing into MakeAndRegisterTestInfo function. template class TestMetaFactoryBase { public: virtual ~TestMetaFactoryBase() {} virtual TestFactoryBase* CreateTestFactory(ParamType parameter) = 0; }; // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. // // TestMetaFactory creates test factories for passing into // MakeAndRegisterTestInfo function. Since MakeAndRegisterTestInfo receives // ownership of test factory pointer, same factory object cannot be passed // into that method twice. But ParameterizedTestCaseInfo is going to call // it for each Test/Parameter value combination. Thus it needs meta factory // creator class. template class TestMetaFactory : public TestMetaFactoryBase { public: typedef typename TestCase::ParamType ParamType; TestMetaFactory() {} virtual TestFactoryBase* CreateTestFactory(ParamType parameter) { return new ParameterizedTestFactory(parameter); } private: GTEST_DISALLOW_COPY_AND_ASSIGN_(TestMetaFactory); }; // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. // // ParameterizedTestCaseInfoBase is a generic interface // to ParameterizedTestCaseInfo classes. ParameterizedTestCaseInfoBase // accumulates test information provided by TEST_P macro invocations // and generators provided by INSTANTIATE_TEST_CASE_P macro invocations // and uses that information to register all resulting test instances // in RegisterTests method. The ParameterizeTestCaseRegistry class holds // a collection of pointers to the ParameterizedTestCaseInfo objects // and calls RegisterTests() on each of them when asked. class ParameterizedTestCaseInfoBase { public: virtual ~ParameterizedTestCaseInfoBase() {} // Base part of test case name for display purposes. virtual const string& GetTestCaseName() const = 0; // Test case id to verify identity. virtual TypeId GetTestCaseTypeId() const = 0; // UnitTest class invokes this method to register tests in this // test case right before running them in RUN_ALL_TESTS macro. // This method should not be called more then once on any single // instance of a ParameterizedTestCaseInfoBase derived class. virtual void RegisterTests() = 0; protected: ParameterizedTestCaseInfoBase() {} private: GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestCaseInfoBase); }; // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. // // ParameterizedTestCaseInfo accumulates tests obtained from TEST_P // macro invocations for a particular test case and generators // obtained from INSTANTIATE_TEST_CASE_P macro invocations for that // test case. It registers tests with all values generated by all // generators when asked. template class ParameterizedTestCaseInfo : public ParameterizedTestCaseInfoBase { public: // ParamType and GeneratorCreationFunc are private types but are required // for declarations of public methods AddTestPattern() and // AddTestCaseInstantiation(). typedef typename TestCase::ParamType ParamType; // A function that returns an instance of appropriate generator type. typedef ParamGenerator(GeneratorCreationFunc)(); explicit ParameterizedTestCaseInfo(const char* name) : test_case_name_(name) {} // Test case base name for display purposes. virtual const string& GetTestCaseName() const { return test_case_name_; } // Test case id to verify identity. virtual TypeId GetTestCaseTypeId() const { return GetTypeId(); } // TEST_P macro uses AddTestPattern() to record information // about a single test in a LocalTestInfo structure. // test_case_name is the base name of the test case (without invocation // prefix). test_base_name is the name of an individual test without // parameter index. For the test SequenceA/FooTest.DoBar/1 FooTest is // test case base name and DoBar is test base name. void AddTestPattern(const char* test_case_name, const char* test_base_name, TestMetaFactoryBase* meta_factory) { tests_.push_back(linked_ptr(new TestInfo(test_case_name, test_base_name, meta_factory))); } // INSTANTIATE_TEST_CASE_P macro uses AddGenerator() to record information // about a generator. int AddTestCaseInstantiation(const string& instantiation_name, GeneratorCreationFunc* func, const char* /* file */, int /* line */) { instantiations_.push_back(::std::make_pair(instantiation_name, func)); return 0; // Return value used only to run this method in namespace scope. } // UnitTest class invokes this method to register tests in this test case // test cases right before running tests in RUN_ALL_TESTS macro. // This method should not be called more then once on any single // instance of a ParameterizedTestCaseInfoBase derived class. // UnitTest has a guard to prevent from calling this method more then once. virtual void RegisterTests() { for (typename TestInfoContainer::iterator test_it = tests_.begin(); test_it != tests_.end(); ++test_it) { linked_ptr test_info = *test_it; for (typename InstantiationContainer::iterator gen_it = instantiations_.begin(); gen_it != instantiations_.end(); ++gen_it) { const string& instantiation_name = gen_it->first; ParamGenerator generator((*gen_it->second)()); string test_case_name; if ( !instantiation_name.empty() ) test_case_name = instantiation_name + "/"; test_case_name += test_info->test_case_base_name; int i = 0; for (typename ParamGenerator::iterator param_it = generator.begin(); param_it != generator.end(); ++param_it, ++i) { Message test_name_stream; test_name_stream << test_info->test_base_name << "/" << i; MakeAndRegisterTestInfo( test_case_name.c_str(), test_name_stream.GetString().c_str(), NULL, // No type parameter. PrintToString(*param_it).c_str(), GetTestCaseTypeId(), TestCase::SetUpTestCase, TestCase::TearDownTestCase, test_info->test_meta_factory->CreateTestFactory(*param_it)); } // for param_it } // for gen_it } // for test_it } // RegisterTests private: // LocalTestInfo structure keeps information about a single test registered // with TEST_P macro. struct TestInfo { TestInfo(const char* a_test_case_base_name, const char* a_test_base_name, TestMetaFactoryBase* a_test_meta_factory) : test_case_base_name(a_test_case_base_name), test_base_name(a_test_base_name), test_meta_factory(a_test_meta_factory) {} const string test_case_base_name; const string test_base_name; const scoped_ptr > test_meta_factory; }; typedef ::std::vector > TestInfoContainer; // Keeps pairs of // received from INSTANTIATE_TEST_CASE_P macros. typedef ::std::vector > InstantiationContainer; const string test_case_name_; TestInfoContainer tests_; InstantiationContainer instantiations_; GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestCaseInfo); }; // class ParameterizedTestCaseInfo // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. // // ParameterizedTestCaseRegistry contains a map of ParameterizedTestCaseInfoBase // classes accessed by test case names. TEST_P and INSTANTIATE_TEST_CASE_P // macros use it to locate their corresponding ParameterizedTestCaseInfo // descriptors. class ParameterizedTestCaseRegistry { public: ParameterizedTestCaseRegistry() {} ~ParameterizedTestCaseRegistry() { for (TestCaseInfoContainer::iterator it = test_case_infos_.begin(); it != test_case_infos_.end(); ++it) { delete *it; } } // Looks up or creates and returns a structure containing information about // tests and instantiations of a particular test case. template ParameterizedTestCaseInfo* GetTestCasePatternHolder( const char* test_case_name, const char* file, int line) { ParameterizedTestCaseInfo* typed_test_info = NULL; for (TestCaseInfoContainer::iterator it = test_case_infos_.begin(); it != test_case_infos_.end(); ++it) { if ((*it)->GetTestCaseName() == test_case_name) { if ((*it)->GetTestCaseTypeId() != GetTypeId()) { // Complain about incorrect usage of Google Test facilities // and terminate the program since we cannot guaranty correct // test case setup and tear-down in this case. ReportInvalidTestCaseType(test_case_name, file, line); posix::Abort(); } else { // At this point we are sure that the object we found is of the same // type we are looking for, so we downcast it to that type // without further checks. typed_test_info = CheckedDowncastToActualType< ParameterizedTestCaseInfo >(*it); } break; } } if (typed_test_info == NULL) { typed_test_info = new ParameterizedTestCaseInfo(test_case_name); test_case_infos_.push_back(typed_test_info); } return typed_test_info; } void RegisterTests() { for (TestCaseInfoContainer::iterator it = test_case_infos_.begin(); it != test_case_infos_.end(); ++it) { (*it)->RegisterTests(); } } private: typedef ::std::vector TestCaseInfoContainer; TestCaseInfoContainer test_case_infos_; GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestCaseRegistry); }; } // namespace internal } // namespace testing #endif // GTEST_HAS_PARAM_TEST #endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_ // This file was GENERATED by command: // pump.py gtest-param-util-generated.h.pump // DO NOT EDIT BY HAND!!! // Copyright 2008 Google Inc. // All Rights Reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: vladl@google.com (Vlad Losev) // Type and function utilities for implementing parameterized tests. // This file is generated by a SCRIPT. DO NOT EDIT BY HAND! // // Currently Google Test supports at most 50 arguments in Values, // and at most 10 arguments in Combine. Please contact // googletestframework@googlegroups.com if you need more. // Please note that the number of arguments to Combine is limited // by the maximum arity of the implementation of tr1::tuple which is // currently set at 10. #ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_ #define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_ // scripts/fuse_gtest.py depends on gtest's own header being #included // *unconditionally*. Therefore these #includes cannot be moved // inside #if GTEST_HAS_PARAM_TEST. #if GTEST_HAS_PARAM_TEST namespace testing { // Forward declarations of ValuesIn(), which is implemented in // include/gtest/gtest-param-test.h. template internal::ParamGenerator< typename ::testing::internal::IteratorTraits::value_type> ValuesIn(ForwardIterator begin, ForwardIterator end); template internal::ParamGenerator ValuesIn(const T (&array)[N]); template internal::ParamGenerator ValuesIn( const Container& container); 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_; }; template class ValueArray2 { public: ValueArray2(T1 v1, T2 v2) : v1_(v1), v2_(v2) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray2& other); const T1 v1_; const T2 v2_; }; template class ValueArray3 { public: ValueArray3(T1 v1, T2 v2, T3 v3) : v1_(v1), v2_(v2), v3_(v3) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray3& other); const T1 v1_; const T2 v2_; const T3 v3_; }; template class ValueArray4 { public: ValueArray4(T1 v1, T2 v2, T3 v3, T4 v4) : v1_(v1), v2_(v2), v3_(v3), v4_(v4) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray4& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; }; template class ValueArray5 { public: ValueArray5(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray5& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; }; template class ValueArray6 { public: ValueArray6(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray6& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; }; template class ValueArray7 { public: ValueArray7(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray7& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; }; template class ValueArray8 { public: ValueArray8(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray8& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; }; template class ValueArray9 { public: ValueArray9(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray9& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; }; template class ValueArray10 { public: ValueArray10(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray10& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; }; template class ValueArray11 { public: ValueArray11(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray11& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; }; template class ValueArray12 { public: ValueArray12(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray12& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; }; template class ValueArray13 { public: ValueArray13(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray13& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; }; template class ValueArray14 { public: ValueArray14(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray14& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; }; template class ValueArray15 { public: ValueArray15(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray15& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; }; template class ValueArray16 { public: ValueArray16(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray16& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; }; template class ValueArray17 { public: ValueArray17(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray17& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; }; template class ValueArray18 { public: ValueArray18(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray18& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; }; template class ValueArray19 { public: ValueArray19(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray19& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; }; template class ValueArray20 { public: ValueArray20(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray20& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; }; template class ValueArray21 { public: ValueArray21(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray21& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; }; template class ValueArray22 { public: ValueArray22(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_), static_cast(v22_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray22& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; const T22 v22_; }; template class ValueArray23 { public: ValueArray23(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_), static_cast(v22_), static_cast(v23_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray23& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; const T22 v22_; const T23 v23_; }; template class ValueArray24 { public: ValueArray24(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_), static_cast(v22_), static_cast(v23_), static_cast(v24_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray24& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; const T22 v22_; const T23 v23_; const T24 v24_; }; template class ValueArray25 { public: ValueArray25(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_), static_cast(v22_), static_cast(v23_), static_cast(v24_), static_cast(v25_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray25& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; const T22 v22_; const T23 v23_; const T24 v24_; const T25 v25_; }; template class ValueArray26 { public: ValueArray26(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_), static_cast(v22_), static_cast(v23_), static_cast(v24_), static_cast(v25_), static_cast(v26_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray26& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; const T22 v22_; const T23 v23_; const T24 v24_; const T25 v25_; const T26 v26_; }; template class ValueArray27 { public: ValueArray27(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_), static_cast(v22_), static_cast(v23_), static_cast(v24_), static_cast(v25_), static_cast(v26_), static_cast(v27_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray27& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; const T22 v22_; const T23 v23_; const T24 v24_; const T25 v25_; const T26 v26_; const T27 v27_; }; template class ValueArray28 { public: ValueArray28(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_), static_cast(v22_), static_cast(v23_), static_cast(v24_), static_cast(v25_), static_cast(v26_), static_cast(v27_), static_cast(v28_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray28& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; const T22 v22_; const T23 v23_; const T24 v24_; const T25 v25_; const T26 v26_; const T27 v27_; const T28 v28_; }; template class ValueArray29 { public: ValueArray29(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_), static_cast(v22_), static_cast(v23_), static_cast(v24_), static_cast(v25_), static_cast(v26_), static_cast(v27_), static_cast(v28_), static_cast(v29_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray29& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; const T22 v22_; const T23 v23_; const T24 v24_; const T25 v25_; const T26 v26_; const T27 v27_; const T28 v28_; const T29 v29_; }; template class ValueArray30 { public: ValueArray30(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_), static_cast(v22_), static_cast(v23_), static_cast(v24_), static_cast(v25_), static_cast(v26_), static_cast(v27_), static_cast(v28_), static_cast(v29_), static_cast(v30_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray30& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; const T22 v22_; const T23 v23_; const T24 v24_; const T25 v25_; const T26 v26_; const T27 v27_; const T28 v28_; const T29 v29_; const T30 v30_; }; template class ValueArray31 { public: ValueArray31(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_), static_cast(v22_), static_cast(v23_), static_cast(v24_), static_cast(v25_), static_cast(v26_), static_cast(v27_), static_cast(v28_), static_cast(v29_), static_cast(v30_), static_cast(v31_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray31& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; const T22 v22_; const T23 v23_; const T24 v24_; const T25 v25_; const T26 v26_; const T27 v27_; const T28 v28_; const T29 v29_; const T30 v30_; const T31 v31_; }; template class ValueArray32 { public: ValueArray32(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_), static_cast(v22_), static_cast(v23_), static_cast(v24_), static_cast(v25_), static_cast(v26_), static_cast(v27_), static_cast(v28_), static_cast(v29_), static_cast(v30_), static_cast(v31_), static_cast(v32_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray32& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; const T22 v22_; const T23 v23_; const T24 v24_; const T25 v25_; const T26 v26_; const T27 v27_; const T28 v28_; const T29 v29_; const T30 v30_; const T31 v31_; const T32 v32_; }; template class ValueArray33 { public: ValueArray33(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_), static_cast(v22_), static_cast(v23_), static_cast(v24_), static_cast(v25_), static_cast(v26_), static_cast(v27_), static_cast(v28_), static_cast(v29_), static_cast(v30_), static_cast(v31_), static_cast(v32_), static_cast(v33_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray33& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; const T22 v22_; const T23 v23_; const T24 v24_; const T25 v25_; const T26 v26_; const T27 v27_; const T28 v28_; const T29 v29_; const T30 v30_; const T31 v31_; const T32 v32_; const T33 v33_; }; template class ValueArray34 { public: ValueArray34(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_), static_cast(v22_), static_cast(v23_), static_cast(v24_), static_cast(v25_), static_cast(v26_), static_cast(v27_), static_cast(v28_), static_cast(v29_), static_cast(v30_), static_cast(v31_), static_cast(v32_), static_cast(v33_), static_cast(v34_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray34& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; const T22 v22_; const T23 v23_; const T24 v24_; const T25 v25_; const T26 v26_; const T27 v27_; const T28 v28_; const T29 v29_; const T30 v30_; const T31 v31_; const T32 v32_; const T33 v33_; const T34 v34_; }; template class ValueArray35 { public: ValueArray35(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_), static_cast(v22_), static_cast(v23_), static_cast(v24_), static_cast(v25_), static_cast(v26_), static_cast(v27_), static_cast(v28_), static_cast(v29_), static_cast(v30_), static_cast(v31_), static_cast(v32_), static_cast(v33_), static_cast(v34_), static_cast(v35_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray35& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; const T22 v22_; const T23 v23_; const T24 v24_; const T25 v25_; const T26 v26_; const T27 v27_; const T28 v28_; const T29 v29_; const T30 v30_; const T31 v31_; const T32 v32_; const T33 v33_; const T34 v34_; const T35 v35_; }; template class ValueArray36 { public: ValueArray36(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_), static_cast(v22_), static_cast(v23_), static_cast(v24_), static_cast(v25_), static_cast(v26_), static_cast(v27_), static_cast(v28_), static_cast(v29_), static_cast(v30_), static_cast(v31_), static_cast(v32_), static_cast(v33_), static_cast(v34_), static_cast(v35_), static_cast(v36_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray36& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; const T22 v22_; const T23 v23_; const T24 v24_; const T25 v25_; const T26 v26_; const T27 v27_; const T28 v28_; const T29 v29_; const T30 v30_; const T31 v31_; const T32 v32_; const T33 v33_; const T34 v34_; const T35 v35_; const T36 v36_; }; template class ValueArray37 { public: ValueArray37(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_), static_cast(v22_), static_cast(v23_), static_cast(v24_), static_cast(v25_), static_cast(v26_), static_cast(v27_), static_cast(v28_), static_cast(v29_), static_cast(v30_), static_cast(v31_), static_cast(v32_), static_cast(v33_), static_cast(v34_), static_cast(v35_), static_cast(v36_), static_cast(v37_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray37& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; const T22 v22_; const T23 v23_; const T24 v24_; const T25 v25_; const T26 v26_; const T27 v27_; const T28 v28_; const T29 v29_; const T30 v30_; const T31 v31_; const T32 v32_; const T33 v33_; const T34 v34_; const T35 v35_; const T36 v36_; const T37 v37_; }; template class ValueArray38 { public: ValueArray38(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_), static_cast(v22_), static_cast(v23_), static_cast(v24_), static_cast(v25_), static_cast(v26_), static_cast(v27_), static_cast(v28_), static_cast(v29_), static_cast(v30_), static_cast(v31_), static_cast(v32_), static_cast(v33_), static_cast(v34_), static_cast(v35_), static_cast(v36_), static_cast(v37_), static_cast(v38_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray38& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; const T22 v22_; const T23 v23_; const T24 v24_; const T25 v25_; const T26 v26_; const T27 v27_; const T28 v28_; const T29 v29_; const T30 v30_; const T31 v31_; const T32 v32_; const T33 v33_; const T34 v34_; const T35 v35_; const T36 v36_; const T37 v37_; const T38 v38_; }; template class ValueArray39 { public: ValueArray39(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_), static_cast(v22_), static_cast(v23_), static_cast(v24_), static_cast(v25_), static_cast(v26_), static_cast(v27_), static_cast(v28_), static_cast(v29_), static_cast(v30_), static_cast(v31_), static_cast(v32_), static_cast(v33_), static_cast(v34_), static_cast(v35_), static_cast(v36_), static_cast(v37_), static_cast(v38_), static_cast(v39_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray39& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; const T22 v22_; const T23 v23_; const T24 v24_; const T25 v25_; const T26 v26_; const T27 v27_; const T28 v28_; const T29 v29_; const T30 v30_; const T31 v31_; const T32 v32_; const T33 v33_; const T34 v34_; const T35 v35_; const T36 v36_; const T37 v37_; const T38 v38_; const T39 v39_; }; template class ValueArray40 { public: ValueArray40(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39), v40_(v40) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_), static_cast(v22_), static_cast(v23_), static_cast(v24_), static_cast(v25_), static_cast(v26_), static_cast(v27_), static_cast(v28_), static_cast(v29_), static_cast(v30_), static_cast(v31_), static_cast(v32_), static_cast(v33_), static_cast(v34_), static_cast(v35_), static_cast(v36_), static_cast(v37_), static_cast(v38_), static_cast(v39_), static_cast(v40_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray40& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; const T22 v22_; const T23 v23_; const T24 v24_; const T25 v25_; const T26 v26_; const T27 v27_; const T28 v28_; const T29 v29_; const T30 v30_; const T31 v31_; const T32 v32_; const T33 v33_; const T34 v34_; const T35 v35_; const T36 v36_; const T37 v37_; const T38 v38_; const T39 v39_; const T40 v40_; }; template class ValueArray41 { public: ValueArray41(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39), v40_(v40), v41_(v41) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_), static_cast(v22_), static_cast(v23_), static_cast(v24_), static_cast(v25_), static_cast(v26_), static_cast(v27_), static_cast(v28_), static_cast(v29_), static_cast(v30_), static_cast(v31_), static_cast(v32_), static_cast(v33_), static_cast(v34_), static_cast(v35_), static_cast(v36_), static_cast(v37_), static_cast(v38_), static_cast(v39_), static_cast(v40_), static_cast(v41_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray41& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; const T22 v22_; const T23 v23_; const T24 v24_; const T25 v25_; const T26 v26_; const T27 v27_; const T28 v28_; const T29 v29_; const T30 v30_; const T31 v31_; const T32 v32_; const T33 v33_; const T34 v34_; const T35 v35_; const T36 v36_; const T37 v37_; const T38 v38_; const T39 v39_; const T40 v40_; const T41 v41_; }; template class ValueArray42 { public: ValueArray42(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, T42 v42) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39), v40_(v40), v41_(v41), v42_(v42) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_), static_cast(v22_), static_cast(v23_), static_cast(v24_), static_cast(v25_), static_cast(v26_), static_cast(v27_), static_cast(v28_), static_cast(v29_), static_cast(v30_), static_cast(v31_), static_cast(v32_), static_cast(v33_), static_cast(v34_), static_cast(v35_), static_cast(v36_), static_cast(v37_), static_cast(v38_), static_cast(v39_), static_cast(v40_), static_cast(v41_), static_cast(v42_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray42& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; const T22 v22_; const T23 v23_; const T24 v24_; const T25 v25_; const T26 v26_; const T27 v27_; const T28 v28_; const T29 v29_; const T30 v30_; const T31 v31_; const T32 v32_; const T33 v33_; const T34 v34_; const T35 v35_; const T36 v36_; const T37 v37_; const T38 v38_; const T39 v39_; const T40 v40_; const T41 v41_; const T42 v42_; }; template class ValueArray43 { public: ValueArray43(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, T42 v42, T43 v43) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39), v40_(v40), v41_(v41), v42_(v42), v43_(v43) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_), static_cast(v22_), static_cast(v23_), static_cast(v24_), static_cast(v25_), static_cast(v26_), static_cast(v27_), static_cast(v28_), static_cast(v29_), static_cast(v30_), static_cast(v31_), static_cast(v32_), static_cast(v33_), static_cast(v34_), static_cast(v35_), static_cast(v36_), static_cast(v37_), static_cast(v38_), static_cast(v39_), static_cast(v40_), static_cast(v41_), static_cast(v42_), static_cast(v43_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray43& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; const T22 v22_; const T23 v23_; const T24 v24_; const T25 v25_; const T26 v26_; const T27 v27_; const T28 v28_; const T29 v29_; const T30 v30_; const T31 v31_; const T32 v32_; const T33 v33_; const T34 v34_; const T35 v35_; const T36 v36_; const T37 v37_; const T38 v38_; const T39 v39_; const T40 v40_; const T41 v41_; const T42 v42_; const T43 v43_; }; template class ValueArray44 { public: ValueArray44(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, T42 v42, T43 v43, T44 v44) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39), v40_(v40), v41_(v41), v42_(v42), v43_(v43), v44_(v44) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_), static_cast(v22_), static_cast(v23_), static_cast(v24_), static_cast(v25_), static_cast(v26_), static_cast(v27_), static_cast(v28_), static_cast(v29_), static_cast(v30_), static_cast(v31_), static_cast(v32_), static_cast(v33_), static_cast(v34_), static_cast(v35_), static_cast(v36_), static_cast(v37_), static_cast(v38_), static_cast(v39_), static_cast(v40_), static_cast(v41_), static_cast(v42_), static_cast(v43_), static_cast(v44_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray44& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; const T22 v22_; const T23 v23_; const T24 v24_; const T25 v25_; const T26 v26_; const T27 v27_; const T28 v28_; const T29 v29_; const T30 v30_; const T31 v31_; const T32 v32_; const T33 v33_; const T34 v34_; const T35 v35_; const T36 v36_; const T37 v37_; const T38 v38_; const T39 v39_; const T40 v40_; const T41 v41_; const T42 v42_; const T43 v43_; const T44 v44_; }; template class ValueArray45 { public: ValueArray45(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39), v40_(v40), v41_(v41), v42_(v42), v43_(v43), v44_(v44), v45_(v45) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_), static_cast(v22_), static_cast(v23_), static_cast(v24_), static_cast(v25_), static_cast(v26_), static_cast(v27_), static_cast(v28_), static_cast(v29_), static_cast(v30_), static_cast(v31_), static_cast(v32_), static_cast(v33_), static_cast(v34_), static_cast(v35_), static_cast(v36_), static_cast(v37_), static_cast(v38_), static_cast(v39_), static_cast(v40_), static_cast(v41_), static_cast(v42_), static_cast(v43_), static_cast(v44_), static_cast(v45_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray45& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; const T22 v22_; const T23 v23_; const T24 v24_; const T25 v25_; const T26 v26_; const T27 v27_; const T28 v28_; const T29 v29_; const T30 v30_; const T31 v31_; const T32 v32_; const T33 v33_; const T34 v34_; const T35 v35_; const T36 v36_; const T37 v37_; const T38 v38_; const T39 v39_; const T40 v40_; const T41 v41_; const T42 v42_; const T43 v43_; const T44 v44_; const T45 v45_; }; template class ValueArray46 { public: ValueArray46(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39), v40_(v40), v41_(v41), v42_(v42), v43_(v43), v44_(v44), v45_(v45), v46_(v46) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_), static_cast(v22_), static_cast(v23_), static_cast(v24_), static_cast(v25_), static_cast(v26_), static_cast(v27_), static_cast(v28_), static_cast(v29_), static_cast(v30_), static_cast(v31_), static_cast(v32_), static_cast(v33_), static_cast(v34_), static_cast(v35_), static_cast(v36_), static_cast(v37_), static_cast(v38_), static_cast(v39_), static_cast(v40_), static_cast(v41_), static_cast(v42_), static_cast(v43_), static_cast(v44_), static_cast(v45_), static_cast(v46_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray46& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; const T22 v22_; const T23 v23_; const T24 v24_; const T25 v25_; const T26 v26_; const T27 v27_; const T28 v28_; const T29 v29_; const T30 v30_; const T31 v31_; const T32 v32_; const T33 v33_; const T34 v34_; const T35 v35_; const T36 v36_; const T37 v37_; const T38 v38_; const T39 v39_; const T40 v40_; const T41 v41_; const T42 v42_; const T43 v43_; const T44 v44_; const T45 v45_; const T46 v46_; }; template class ValueArray47 { public: ValueArray47(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39), v40_(v40), v41_(v41), v42_(v42), v43_(v43), v44_(v44), v45_(v45), v46_(v46), v47_(v47) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_), static_cast(v22_), static_cast(v23_), static_cast(v24_), static_cast(v25_), static_cast(v26_), static_cast(v27_), static_cast(v28_), static_cast(v29_), static_cast(v30_), static_cast(v31_), static_cast(v32_), static_cast(v33_), static_cast(v34_), static_cast(v35_), static_cast(v36_), static_cast(v37_), static_cast(v38_), static_cast(v39_), static_cast(v40_), static_cast(v41_), static_cast(v42_), static_cast(v43_), static_cast(v44_), static_cast(v45_), static_cast(v46_), static_cast(v47_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray47& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; const T22 v22_; const T23 v23_; const T24 v24_; const T25 v25_; const T26 v26_; const T27 v27_; const T28 v28_; const T29 v29_; const T30 v30_; const T31 v31_; const T32 v32_; const T33 v33_; const T34 v34_; const T35 v35_; const T36 v36_; const T37 v37_; const T38 v38_; const T39 v39_; const T40 v40_; const T41 v41_; const T42 v42_; const T43 v43_; const T44 v44_; const T45 v45_; const T46 v46_; const T47 v47_; }; template class ValueArray48 { public: ValueArray48(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47, T48 v48) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39), v40_(v40), v41_(v41), v42_(v42), v43_(v43), v44_(v44), v45_(v45), v46_(v46), v47_(v47), v48_(v48) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_), static_cast(v22_), static_cast(v23_), static_cast(v24_), static_cast(v25_), static_cast(v26_), static_cast(v27_), static_cast(v28_), static_cast(v29_), static_cast(v30_), static_cast(v31_), static_cast(v32_), static_cast(v33_), static_cast(v34_), static_cast(v35_), static_cast(v36_), static_cast(v37_), static_cast(v38_), static_cast(v39_), static_cast(v40_), static_cast(v41_), static_cast(v42_), static_cast(v43_), static_cast(v44_), static_cast(v45_), static_cast(v46_), static_cast(v47_), static_cast(v48_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray48& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; const T22 v22_; const T23 v23_; const T24 v24_; const T25 v25_; const T26 v26_; const T27 v27_; const T28 v28_; const T29 v29_; const T30 v30_; const T31 v31_; const T32 v32_; const T33 v33_; const T34 v34_; const T35 v35_; const T36 v36_; const T37 v37_; const T38 v38_; const T39 v39_; const T40 v40_; const T41 v41_; const T42 v42_; const T43 v43_; const T44 v44_; const T45 v45_; const T46 v46_; const T47 v47_; const T48 v48_; }; template class ValueArray49 { public: ValueArray49(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47, T48 v48, T49 v49) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39), v40_(v40), v41_(v41), v42_(v42), v43_(v43), v44_(v44), v45_(v45), v46_(v46), v47_(v47), v48_(v48), v49_(v49) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_), static_cast(v22_), static_cast(v23_), static_cast(v24_), static_cast(v25_), static_cast(v26_), static_cast(v27_), static_cast(v28_), static_cast(v29_), static_cast(v30_), static_cast(v31_), static_cast(v32_), static_cast(v33_), static_cast(v34_), static_cast(v35_), static_cast(v36_), static_cast(v37_), static_cast(v38_), static_cast(v39_), static_cast(v40_), static_cast(v41_), static_cast(v42_), static_cast(v43_), static_cast(v44_), static_cast(v45_), static_cast(v46_), static_cast(v47_), static_cast(v48_), static_cast(v49_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray49& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; const T22 v22_; const T23 v23_; const T24 v24_; const T25 v25_; const T26 v26_; const T27 v27_; const T28 v28_; const T29 v29_; const T30 v30_; const T31 v31_; const T32 v32_; const T33 v33_; const T34 v34_; const T35 v35_; const T36 v36_; const T37 v37_; const T38 v38_; const T39 v39_; const T40 v40_; const T41 v41_; const T42 v42_; const T43 v43_; const T44 v44_; const T45 v45_; const T46 v46_; const T47 v47_; const T48 v48_; const T49 v49_; }; template class ValueArray50 { public: ValueArray50(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47, T48 v48, T49 v49, T50 v50) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39), v40_(v40), v41_(v41), v42_(v42), v43_(v43), v44_(v44), v45_(v45), v46_(v46), v47_(v47), v48_(v48), v49_(v49), v50_(v50) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_), static_cast(v22_), static_cast(v23_), static_cast(v24_), static_cast(v25_), static_cast(v26_), static_cast(v27_), static_cast(v28_), static_cast(v29_), static_cast(v30_), static_cast(v31_), static_cast(v32_), static_cast(v33_), static_cast(v34_), static_cast(v35_), static_cast(v36_), static_cast(v37_), static_cast(v38_), static_cast(v39_), static_cast(v40_), static_cast(v41_), static_cast(v42_), static_cast(v43_), static_cast(v44_), static_cast(v45_), static_cast(v46_), static_cast(v47_), static_cast(v48_), static_cast(v49_), static_cast(v50_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray50& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; const T22 v22_; const T23 v23_; const T24 v24_; const T25 v25_; const T26 v26_; const T27 v27_; const T28 v28_; const T29 v29_; const T30 v30_; const T31 v31_; const T32 v32_; const T33 v33_; const T34 v34_; const T35 v35_; const T36 v36_; const T37 v37_; const T38 v38_; const T39 v39_; const T40 v40_; const T41 v41_; const T42 v42_; const T43 v43_; const T44 v44_; const T45 v45_; const T46 v46_; const T47 v47_; const T48 v48_; const T49 v49_; const T50 v50_; }; # if GTEST_HAS_COMBINE // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. // // Generates values from the Cartesian product of values produced // by the argument generators. // template class CartesianProductGenerator2 : public ParamGeneratorInterface< ::std::tr1::tuple > { public: typedef ::std::tr1::tuple ParamType; CartesianProductGenerator2(const ParamGenerator& g1, const ParamGenerator& g2) : g1_(g1), g2_(g2) {} virtual ~CartesianProductGenerator2() {} virtual ParamIteratorInterface* Begin() const { return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin()); } virtual ParamIteratorInterface* End() const { return new Iterator(this, g1_, g1_.end(), g2_, g2_.end()); } private: class Iterator : public ParamIteratorInterface { public: Iterator(const ParamGeneratorInterface* base, const ParamGenerator& g1, const typename ParamGenerator::iterator& current1, const ParamGenerator& g2, const typename ParamGenerator::iterator& current2) : base_(base), begin1_(g1.begin()), end1_(g1.end()), current1_(current1), begin2_(g2.begin()), end2_(g2.end()), current2_(current2) { ComputeCurrentValue(); } virtual ~Iterator() {} virtual const ParamGeneratorInterface* BaseGenerator() const { return base_; } // Advance should not be called on beyond-of-range iterators // so no component iterators must be beyond end of range, either. virtual void Advance() { assert(!AtEnd()); ++current2_; if (current2_ == end2_) { current2_ = begin2_; ++current1_; } ComputeCurrentValue(); } virtual ParamIteratorInterface* Clone() const { return new Iterator(*this); } virtual const ParamType* Current() const { return ¤t_value_; } virtual bool Equals(const ParamIteratorInterface& other) const { // Having the same base generator guarantees that the other // iterator is of the same type and we can downcast. GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) << "The program attempted to compare iterators " << "from different generators." << std::endl; const Iterator* typed_other = CheckedDowncastToActualType(&other); // We must report iterators equal if they both point beyond their // respective ranges. That can happen in a variety of fashions, // so we have to consult AtEnd(). return (AtEnd() && typed_other->AtEnd()) || ( current1_ == typed_other->current1_ && current2_ == typed_other->current2_); } private: Iterator(const Iterator& other) : base_(other.base_), begin1_(other.begin1_), end1_(other.end1_), current1_(other.current1_), begin2_(other.begin2_), end2_(other.end2_), current2_(other.current2_) { ComputeCurrentValue(); } void ComputeCurrentValue() { if (!AtEnd()) current_value_ = ParamType(*current1_, *current2_); } bool AtEnd() const { // We must report iterator past the end of the range when either of the // component iterators has reached the end of its range. return current1_ == end1_ || current2_ == end2_; } // No implementation - assignment is unsupported. void operator=(const Iterator& other); const ParamGeneratorInterface* const base_; // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. // current[i]_ is the actual traversing iterator. const typename ParamGenerator::iterator begin1_; const typename ParamGenerator::iterator end1_; typename ParamGenerator::iterator current1_; const typename ParamGenerator::iterator begin2_; const typename ParamGenerator::iterator end2_; typename ParamGenerator::iterator current2_; ParamType current_value_; }; // class CartesianProductGenerator2::Iterator // No implementation - assignment is unsupported. void operator=(const CartesianProductGenerator2& other); const ParamGenerator g1_; const ParamGenerator g2_; }; // class CartesianProductGenerator2 template class CartesianProductGenerator3 : public ParamGeneratorInterface< ::std::tr1::tuple > { public: typedef ::std::tr1::tuple ParamType; CartesianProductGenerator3(const ParamGenerator& g1, const ParamGenerator& g2, const ParamGenerator& g3) : g1_(g1), g2_(g2), g3_(g3) {} virtual ~CartesianProductGenerator3() {} virtual ParamIteratorInterface* Begin() const { return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, g3_.begin()); } virtual ParamIteratorInterface* End() const { return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end()); } private: class Iterator : public ParamIteratorInterface { public: Iterator(const ParamGeneratorInterface* base, const ParamGenerator& g1, const typename ParamGenerator::iterator& current1, const ParamGenerator& g2, const typename ParamGenerator::iterator& current2, const ParamGenerator& g3, const typename ParamGenerator::iterator& current3) : base_(base), begin1_(g1.begin()), end1_(g1.end()), current1_(current1), begin2_(g2.begin()), end2_(g2.end()), current2_(current2), begin3_(g3.begin()), end3_(g3.end()), current3_(current3) { ComputeCurrentValue(); } virtual ~Iterator() {} virtual const ParamGeneratorInterface* BaseGenerator() const { return base_; } // Advance should not be called on beyond-of-range iterators // so no component iterators must be beyond end of range, either. virtual void Advance() { assert(!AtEnd()); ++current3_; if (current3_ == end3_) { current3_ = begin3_; ++current2_; } if (current2_ == end2_) { current2_ = begin2_; ++current1_; } ComputeCurrentValue(); } virtual ParamIteratorInterface* Clone() const { return new Iterator(*this); } virtual const ParamType* Current() const { return ¤t_value_; } virtual bool Equals(const ParamIteratorInterface& other) const { // Having the same base generator guarantees that the other // iterator is of the same type and we can downcast. GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) << "The program attempted to compare iterators " << "from different generators." << std::endl; const Iterator* typed_other = CheckedDowncastToActualType(&other); // We must report iterators equal if they both point beyond their // respective ranges. That can happen in a variety of fashions, // so we have to consult AtEnd(). return (AtEnd() && typed_other->AtEnd()) || ( current1_ == typed_other->current1_ && current2_ == typed_other->current2_ && current3_ == typed_other->current3_); } private: Iterator(const Iterator& other) : base_(other.base_), begin1_(other.begin1_), end1_(other.end1_), current1_(other.current1_), begin2_(other.begin2_), end2_(other.end2_), current2_(other.current2_), begin3_(other.begin3_), end3_(other.end3_), current3_(other.current3_) { ComputeCurrentValue(); } void ComputeCurrentValue() { if (!AtEnd()) current_value_ = ParamType(*current1_, *current2_, *current3_); } bool AtEnd() const { // We must report iterator past the end of the range when either of the // component iterators has reached the end of its range. return current1_ == end1_ || current2_ == end2_ || current3_ == end3_; } // No implementation - assignment is unsupported. void operator=(const Iterator& other); const ParamGeneratorInterface* const base_; // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. // current[i]_ is the actual traversing iterator. const typename ParamGenerator::iterator begin1_; const typename ParamGenerator::iterator end1_; typename ParamGenerator::iterator current1_; const typename ParamGenerator::iterator begin2_; const typename ParamGenerator::iterator end2_; typename ParamGenerator::iterator current2_; const typename ParamGenerator::iterator begin3_; const typename ParamGenerator::iterator end3_; typename ParamGenerator::iterator current3_; ParamType current_value_; }; // class CartesianProductGenerator3::Iterator // No implementation - assignment is unsupported. void operator=(const CartesianProductGenerator3& other); const ParamGenerator g1_; const ParamGenerator g2_; const ParamGenerator g3_; }; // class CartesianProductGenerator3 template class CartesianProductGenerator4 : public ParamGeneratorInterface< ::std::tr1::tuple > { public: typedef ::std::tr1::tuple ParamType; CartesianProductGenerator4(const ParamGenerator& g1, const ParamGenerator& g2, const ParamGenerator& g3, const ParamGenerator& g4) : g1_(g1), g2_(g2), g3_(g3), g4_(g4) {} virtual ~CartesianProductGenerator4() {} virtual ParamIteratorInterface* Begin() const { return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, g3_.begin(), g4_, g4_.begin()); } virtual ParamIteratorInterface* End() const { return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(), g4_, g4_.end()); } private: class Iterator : public ParamIteratorInterface { public: Iterator(const ParamGeneratorInterface* base, const ParamGenerator& g1, const typename ParamGenerator::iterator& current1, const ParamGenerator& g2, const typename ParamGenerator::iterator& current2, const ParamGenerator& g3, const typename ParamGenerator::iterator& current3, const ParamGenerator& g4, const typename ParamGenerator::iterator& current4) : base_(base), begin1_(g1.begin()), end1_(g1.end()), current1_(current1), begin2_(g2.begin()), end2_(g2.end()), current2_(current2), begin3_(g3.begin()), end3_(g3.end()), current3_(current3), begin4_(g4.begin()), end4_(g4.end()), current4_(current4) { ComputeCurrentValue(); } virtual ~Iterator() {} virtual const ParamGeneratorInterface* BaseGenerator() const { return base_; } // Advance should not be called on beyond-of-range iterators // so no component iterators must be beyond end of range, either. virtual void Advance() { assert(!AtEnd()); ++current4_; if (current4_ == end4_) { current4_ = begin4_; ++current3_; } if (current3_ == end3_) { current3_ = begin3_; ++current2_; } if (current2_ == end2_) { current2_ = begin2_; ++current1_; } ComputeCurrentValue(); } virtual ParamIteratorInterface* Clone() const { return new Iterator(*this); } virtual const ParamType* Current() const { return ¤t_value_; } virtual bool Equals(const ParamIteratorInterface& other) const { // Having the same base generator guarantees that the other // iterator is of the same type and we can downcast. GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) << "The program attempted to compare iterators " << "from different generators." << std::endl; const Iterator* typed_other = CheckedDowncastToActualType(&other); // We must report iterators equal if they both point beyond their // respective ranges. That can happen in a variety of fashions, // so we have to consult AtEnd(). return (AtEnd() && typed_other->AtEnd()) || ( current1_ == typed_other->current1_ && current2_ == typed_other->current2_ && current3_ == typed_other->current3_ && current4_ == typed_other->current4_); } private: Iterator(const Iterator& other) : base_(other.base_), begin1_(other.begin1_), end1_(other.end1_), current1_(other.current1_), begin2_(other.begin2_), end2_(other.end2_), current2_(other.current2_), begin3_(other.begin3_), end3_(other.end3_), current3_(other.current3_), begin4_(other.begin4_), end4_(other.end4_), current4_(other.current4_) { ComputeCurrentValue(); } void ComputeCurrentValue() { if (!AtEnd()) current_value_ = ParamType(*current1_, *current2_, *current3_, *current4_); } bool AtEnd() const { // We must report iterator past the end of the range when either of the // component iterators has reached the end of its range. return current1_ == end1_ || current2_ == end2_ || current3_ == end3_ || current4_ == end4_; } // No implementation - assignment is unsupported. void operator=(const Iterator& other); const ParamGeneratorInterface* const base_; // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. // current[i]_ is the actual traversing iterator. const typename ParamGenerator::iterator begin1_; const typename ParamGenerator::iterator end1_; typename ParamGenerator::iterator current1_; const typename ParamGenerator::iterator begin2_; const typename ParamGenerator::iterator end2_; typename ParamGenerator::iterator current2_; const typename ParamGenerator::iterator begin3_; const typename ParamGenerator::iterator end3_; typename ParamGenerator::iterator current3_; const typename ParamGenerator::iterator begin4_; const typename ParamGenerator::iterator end4_; typename ParamGenerator::iterator current4_; ParamType current_value_; }; // class CartesianProductGenerator4::Iterator // No implementation - assignment is unsupported. void operator=(const CartesianProductGenerator4& other); const ParamGenerator g1_; const ParamGenerator g2_; const ParamGenerator g3_; const ParamGenerator g4_; }; // class CartesianProductGenerator4 template class CartesianProductGenerator5 : public ParamGeneratorInterface< ::std::tr1::tuple > { public: typedef ::std::tr1::tuple ParamType; CartesianProductGenerator5(const ParamGenerator& g1, const ParamGenerator& g2, const ParamGenerator& g3, const ParamGenerator& g4, const ParamGenerator& g5) : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5) {} virtual ~CartesianProductGenerator5() {} virtual ParamIteratorInterface* Begin() const { return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin()); } virtual ParamIteratorInterface* End() const { return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(), g4_, g4_.end(), g5_, g5_.end()); } private: class Iterator : public ParamIteratorInterface { public: Iterator(const ParamGeneratorInterface* base, const ParamGenerator& g1, const typename ParamGenerator::iterator& current1, const ParamGenerator& g2, const typename ParamGenerator::iterator& current2, const ParamGenerator& g3, const typename ParamGenerator::iterator& current3, const ParamGenerator& g4, const typename ParamGenerator::iterator& current4, const ParamGenerator& g5, const typename ParamGenerator::iterator& current5) : base_(base), begin1_(g1.begin()), end1_(g1.end()), current1_(current1), begin2_(g2.begin()), end2_(g2.end()), current2_(current2), begin3_(g3.begin()), end3_(g3.end()), current3_(current3), begin4_(g4.begin()), end4_(g4.end()), current4_(current4), begin5_(g5.begin()), end5_(g5.end()), current5_(current5) { ComputeCurrentValue(); } virtual ~Iterator() {} virtual const ParamGeneratorInterface* BaseGenerator() const { return base_; } // Advance should not be called on beyond-of-range iterators // so no component iterators must be beyond end of range, either. virtual void Advance() { assert(!AtEnd()); ++current5_; if (current5_ == end5_) { current5_ = begin5_; ++current4_; } if (current4_ == end4_) { current4_ = begin4_; ++current3_; } if (current3_ == end3_) { current3_ = begin3_; ++current2_; } if (current2_ == end2_) { current2_ = begin2_; ++current1_; } ComputeCurrentValue(); } virtual ParamIteratorInterface* Clone() const { return new Iterator(*this); } virtual const ParamType* Current() const { return ¤t_value_; } virtual bool Equals(const ParamIteratorInterface& other) const { // Having the same base generator guarantees that the other // iterator is of the same type and we can downcast. GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) << "The program attempted to compare iterators " << "from different generators." << std::endl; const Iterator* typed_other = CheckedDowncastToActualType(&other); // We must report iterators equal if they both point beyond their // respective ranges. That can happen in a variety of fashions, // so we have to consult AtEnd(). return (AtEnd() && typed_other->AtEnd()) || ( current1_ == typed_other->current1_ && current2_ == typed_other->current2_ && current3_ == typed_other->current3_ && current4_ == typed_other->current4_ && current5_ == typed_other->current5_); } private: Iterator(const Iterator& other) : base_(other.base_), begin1_(other.begin1_), end1_(other.end1_), current1_(other.current1_), begin2_(other.begin2_), end2_(other.end2_), current2_(other.current2_), begin3_(other.begin3_), end3_(other.end3_), current3_(other.current3_), begin4_(other.begin4_), end4_(other.end4_), current4_(other.current4_), begin5_(other.begin5_), end5_(other.end5_), current5_(other.current5_) { ComputeCurrentValue(); } void ComputeCurrentValue() { if (!AtEnd()) current_value_ = ParamType(*current1_, *current2_, *current3_, *current4_, *current5_); } bool AtEnd() const { // We must report iterator past the end of the range when either of the // component iterators has reached the end of its range. return current1_ == end1_ || current2_ == end2_ || current3_ == end3_ || current4_ == end4_ || current5_ == end5_; } // No implementation - assignment is unsupported. void operator=(const Iterator& other); const ParamGeneratorInterface* const base_; // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. // current[i]_ is the actual traversing iterator. const typename ParamGenerator::iterator begin1_; const typename ParamGenerator::iterator end1_; typename ParamGenerator::iterator current1_; const typename ParamGenerator::iterator begin2_; const typename ParamGenerator::iterator end2_; typename ParamGenerator::iterator current2_; const typename ParamGenerator::iterator begin3_; const typename ParamGenerator::iterator end3_; typename ParamGenerator::iterator current3_; const typename ParamGenerator::iterator begin4_; const typename ParamGenerator::iterator end4_; typename ParamGenerator::iterator current4_; const typename ParamGenerator::iterator begin5_; const typename ParamGenerator::iterator end5_; typename ParamGenerator::iterator current5_; ParamType current_value_; }; // class CartesianProductGenerator5::Iterator // No implementation - assignment is unsupported. void operator=(const CartesianProductGenerator5& other); const ParamGenerator g1_; const ParamGenerator g2_; const ParamGenerator g3_; const ParamGenerator g4_; const ParamGenerator g5_; }; // class CartesianProductGenerator5 template class CartesianProductGenerator6 : public ParamGeneratorInterface< ::std::tr1::tuple > { public: typedef ::std::tr1::tuple ParamType; CartesianProductGenerator6(const ParamGenerator& g1, const ParamGenerator& g2, const ParamGenerator& g3, const ParamGenerator& g4, const ParamGenerator& g5, const ParamGenerator& g6) : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6) {} virtual ~CartesianProductGenerator6() {} virtual ParamIteratorInterface* Begin() const { return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin()); } virtual ParamIteratorInterface* End() const { return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(), g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end()); } private: class Iterator : public ParamIteratorInterface { public: Iterator(const ParamGeneratorInterface* base, const ParamGenerator& g1, const typename ParamGenerator::iterator& current1, const ParamGenerator& g2, const typename ParamGenerator::iterator& current2, const ParamGenerator& g3, const typename ParamGenerator::iterator& current3, const ParamGenerator& g4, const typename ParamGenerator::iterator& current4, const ParamGenerator& g5, const typename ParamGenerator::iterator& current5, const ParamGenerator& g6, const typename ParamGenerator::iterator& current6) : base_(base), begin1_(g1.begin()), end1_(g1.end()), current1_(current1), begin2_(g2.begin()), end2_(g2.end()), current2_(current2), begin3_(g3.begin()), end3_(g3.end()), current3_(current3), begin4_(g4.begin()), end4_(g4.end()), current4_(current4), begin5_(g5.begin()), end5_(g5.end()), current5_(current5), begin6_(g6.begin()), end6_(g6.end()), current6_(current6) { ComputeCurrentValue(); } virtual ~Iterator() {} virtual const ParamGeneratorInterface* BaseGenerator() const { return base_; } // Advance should not be called on beyond-of-range iterators // so no component iterators must be beyond end of range, either. virtual void Advance() { assert(!AtEnd()); ++current6_; if (current6_ == end6_) { current6_ = begin6_; ++current5_; } if (current5_ == end5_) { current5_ = begin5_; ++current4_; } if (current4_ == end4_) { current4_ = begin4_; ++current3_; } if (current3_ == end3_) { current3_ = begin3_; ++current2_; } if (current2_ == end2_) { current2_ = begin2_; ++current1_; } ComputeCurrentValue(); } virtual ParamIteratorInterface* Clone() const { return new Iterator(*this); } virtual const ParamType* Current() const { return ¤t_value_; } virtual bool Equals(const ParamIteratorInterface& other) const { // Having the same base generator guarantees that the other // iterator is of the same type and we can downcast. GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) << "The program attempted to compare iterators " << "from different generators." << std::endl; const Iterator* typed_other = CheckedDowncastToActualType(&other); // We must report iterators equal if they both point beyond their // respective ranges. That can happen in a variety of fashions, // so we have to consult AtEnd(). return (AtEnd() && typed_other->AtEnd()) || ( current1_ == typed_other->current1_ && current2_ == typed_other->current2_ && current3_ == typed_other->current3_ && current4_ == typed_other->current4_ && current5_ == typed_other->current5_ && current6_ == typed_other->current6_); } private: Iterator(const Iterator& other) : base_(other.base_), begin1_(other.begin1_), end1_(other.end1_), current1_(other.current1_), begin2_(other.begin2_), end2_(other.end2_), current2_(other.current2_), begin3_(other.begin3_), end3_(other.end3_), current3_(other.current3_), begin4_(other.begin4_), end4_(other.end4_), current4_(other.current4_), begin5_(other.begin5_), end5_(other.end5_), current5_(other.current5_), begin6_(other.begin6_), end6_(other.end6_), current6_(other.current6_) { ComputeCurrentValue(); } void ComputeCurrentValue() { if (!AtEnd()) current_value_ = ParamType(*current1_, *current2_, *current3_, *current4_, *current5_, *current6_); } bool AtEnd() const { // We must report iterator past the end of the range when either of the // component iterators has reached the end of its range. return current1_ == end1_ || current2_ == end2_ || current3_ == end3_ || current4_ == end4_ || current5_ == end5_ || current6_ == end6_; } // No implementation - assignment is unsupported. void operator=(const Iterator& other); const ParamGeneratorInterface* const base_; // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. // current[i]_ is the actual traversing iterator. const typename ParamGenerator::iterator begin1_; const typename ParamGenerator::iterator end1_; typename ParamGenerator::iterator current1_; const typename ParamGenerator::iterator begin2_; const typename ParamGenerator::iterator end2_; typename ParamGenerator::iterator current2_; const typename ParamGenerator::iterator begin3_; const typename ParamGenerator::iterator end3_; typename ParamGenerator::iterator current3_; const typename ParamGenerator::iterator begin4_; const typename ParamGenerator::iterator end4_; typename ParamGenerator::iterator current4_; const typename ParamGenerator::iterator begin5_; const typename ParamGenerator::iterator end5_; typename ParamGenerator::iterator current5_; const typename ParamGenerator::iterator begin6_; const typename ParamGenerator::iterator end6_; typename ParamGenerator::iterator current6_; ParamType current_value_; }; // class CartesianProductGenerator6::Iterator // No implementation - assignment is unsupported. void operator=(const CartesianProductGenerator6& other); const ParamGenerator g1_; const ParamGenerator g2_; const ParamGenerator g3_; const ParamGenerator g4_; const ParamGenerator g5_; const ParamGenerator g6_; }; // class CartesianProductGenerator6 template class CartesianProductGenerator7 : public ParamGeneratorInterface< ::std::tr1::tuple > { public: typedef ::std::tr1::tuple ParamType; CartesianProductGenerator7(const ParamGenerator& g1, const ParamGenerator& g2, const ParamGenerator& g3, const ParamGenerator& g4, const ParamGenerator& g5, const ParamGenerator& g6, const ParamGenerator& g7) : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7) {} virtual ~CartesianProductGenerator7() {} virtual ParamIteratorInterface* Begin() const { return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin(), g7_, g7_.begin()); } virtual ParamIteratorInterface* End() const { return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(), g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end(), g7_, g7_.end()); } private: class Iterator : public ParamIteratorInterface { public: Iterator(const ParamGeneratorInterface* base, const ParamGenerator& g1, const typename ParamGenerator::iterator& current1, const ParamGenerator& g2, const typename ParamGenerator::iterator& current2, const ParamGenerator& g3, const typename ParamGenerator::iterator& current3, const ParamGenerator& g4, const typename ParamGenerator::iterator& current4, const ParamGenerator& g5, const typename ParamGenerator::iterator& current5, const ParamGenerator& g6, const typename ParamGenerator::iterator& current6, const ParamGenerator& g7, const typename ParamGenerator::iterator& current7) : base_(base), begin1_(g1.begin()), end1_(g1.end()), current1_(current1), begin2_(g2.begin()), end2_(g2.end()), current2_(current2), begin3_(g3.begin()), end3_(g3.end()), current3_(current3), begin4_(g4.begin()), end4_(g4.end()), current4_(current4), begin5_(g5.begin()), end5_(g5.end()), current5_(current5), begin6_(g6.begin()), end6_(g6.end()), current6_(current6), begin7_(g7.begin()), end7_(g7.end()), current7_(current7) { ComputeCurrentValue(); } virtual ~Iterator() {} virtual const ParamGeneratorInterface* BaseGenerator() const { return base_; } // Advance should not be called on beyond-of-range iterators // so no component iterators must be beyond end of range, either. virtual void Advance() { assert(!AtEnd()); ++current7_; if (current7_ == end7_) { current7_ = begin7_; ++current6_; } if (current6_ == end6_) { current6_ = begin6_; ++current5_; } if (current5_ == end5_) { current5_ = begin5_; ++current4_; } if (current4_ == end4_) { current4_ = begin4_; ++current3_; } if (current3_ == end3_) { current3_ = begin3_; ++current2_; } if (current2_ == end2_) { current2_ = begin2_; ++current1_; } ComputeCurrentValue(); } virtual ParamIteratorInterface* Clone() const { return new Iterator(*this); } virtual const ParamType* Current() const { return ¤t_value_; } virtual bool Equals(const ParamIteratorInterface& other) const { // Having the same base generator guarantees that the other // iterator is of the same type and we can downcast. GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) << "The program attempted to compare iterators " << "from different generators." << std::endl; const Iterator* typed_other = CheckedDowncastToActualType(&other); // We must report iterators equal if they both point beyond their // respective ranges. That can happen in a variety of fashions, // so we have to consult AtEnd(). return (AtEnd() && typed_other->AtEnd()) || ( current1_ == typed_other->current1_ && current2_ == typed_other->current2_ && current3_ == typed_other->current3_ && current4_ == typed_other->current4_ && current5_ == typed_other->current5_ && current6_ == typed_other->current6_ && current7_ == typed_other->current7_); } private: Iterator(const Iterator& other) : base_(other.base_), begin1_(other.begin1_), end1_(other.end1_), current1_(other.current1_), begin2_(other.begin2_), end2_(other.end2_), current2_(other.current2_), begin3_(other.begin3_), end3_(other.end3_), current3_(other.current3_), begin4_(other.begin4_), end4_(other.end4_), current4_(other.current4_), begin5_(other.begin5_), end5_(other.end5_), current5_(other.current5_), begin6_(other.begin6_), end6_(other.end6_), current6_(other.current6_), begin7_(other.begin7_), end7_(other.end7_), current7_(other.current7_) { ComputeCurrentValue(); } void ComputeCurrentValue() { if (!AtEnd()) current_value_ = ParamType(*current1_, *current2_, *current3_, *current4_, *current5_, *current6_, *current7_); } bool AtEnd() const { // We must report iterator past the end of the range when either of the // component iterators has reached the end of its range. return current1_ == end1_ || current2_ == end2_ || current3_ == end3_ || current4_ == end4_ || current5_ == end5_ || current6_ == end6_ || current7_ == end7_; } // No implementation - assignment is unsupported. void operator=(const Iterator& other); const ParamGeneratorInterface* const base_; // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. // current[i]_ is the actual traversing iterator. const typename ParamGenerator::iterator begin1_; const typename ParamGenerator::iterator end1_; typename ParamGenerator::iterator current1_; const typename ParamGenerator::iterator begin2_; const typename ParamGenerator::iterator end2_; typename ParamGenerator::iterator current2_; const typename ParamGenerator::iterator begin3_; const typename ParamGenerator::iterator end3_; typename ParamGenerator::iterator current3_; const typename ParamGenerator::iterator begin4_; const typename ParamGenerator::iterator end4_; typename ParamGenerator::iterator current4_; const typename ParamGenerator::iterator begin5_; const typename ParamGenerator::iterator end5_; typename ParamGenerator::iterator current5_; const typename ParamGenerator::iterator begin6_; const typename ParamGenerator::iterator end6_; typename ParamGenerator::iterator current6_; const typename ParamGenerator::iterator begin7_; const typename ParamGenerator::iterator end7_; typename ParamGenerator::iterator current7_; ParamType current_value_; }; // class CartesianProductGenerator7::Iterator // No implementation - assignment is unsupported. void operator=(const CartesianProductGenerator7& other); const ParamGenerator g1_; const ParamGenerator g2_; const ParamGenerator g3_; const ParamGenerator g4_; const ParamGenerator g5_; const ParamGenerator g6_; const ParamGenerator g7_; }; // class CartesianProductGenerator7 template class CartesianProductGenerator8 : public ParamGeneratorInterface< ::std::tr1::tuple > { public: typedef ::std::tr1::tuple ParamType; CartesianProductGenerator8(const ParamGenerator& g1, const ParamGenerator& g2, const ParamGenerator& g3, const ParamGenerator& g4, const ParamGenerator& g5, const ParamGenerator& g6, const ParamGenerator& g7, const ParamGenerator& g8) : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), g8_(g8) {} virtual ~CartesianProductGenerator8() {} virtual ParamIteratorInterface* Begin() const { return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin(), g7_, g7_.begin(), g8_, g8_.begin()); } virtual ParamIteratorInterface* End() const { return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(), g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end(), g7_, g7_.end(), g8_, g8_.end()); } private: class Iterator : public ParamIteratorInterface { public: Iterator(const ParamGeneratorInterface* base, const ParamGenerator& g1, const typename ParamGenerator::iterator& current1, const ParamGenerator& g2, const typename ParamGenerator::iterator& current2, const ParamGenerator& g3, const typename ParamGenerator::iterator& current3, const ParamGenerator& g4, const typename ParamGenerator::iterator& current4, const ParamGenerator& g5, const typename ParamGenerator::iterator& current5, const ParamGenerator& g6, const typename ParamGenerator::iterator& current6, const ParamGenerator& g7, const typename ParamGenerator::iterator& current7, const ParamGenerator& g8, const typename ParamGenerator::iterator& current8) : base_(base), begin1_(g1.begin()), end1_(g1.end()), current1_(current1), begin2_(g2.begin()), end2_(g2.end()), current2_(current2), begin3_(g3.begin()), end3_(g3.end()), current3_(current3), begin4_(g4.begin()), end4_(g4.end()), current4_(current4), begin5_(g5.begin()), end5_(g5.end()), current5_(current5), begin6_(g6.begin()), end6_(g6.end()), current6_(current6), begin7_(g7.begin()), end7_(g7.end()), current7_(current7), begin8_(g8.begin()), end8_(g8.end()), current8_(current8) { ComputeCurrentValue(); } virtual ~Iterator() {} virtual const ParamGeneratorInterface* BaseGenerator() const { return base_; } // Advance should not be called on beyond-of-range iterators // so no component iterators must be beyond end of range, either. virtual void Advance() { assert(!AtEnd()); ++current8_; if (current8_ == end8_) { current8_ = begin8_; ++current7_; } if (current7_ == end7_) { current7_ = begin7_; ++current6_; } if (current6_ == end6_) { current6_ = begin6_; ++current5_; } if (current5_ == end5_) { current5_ = begin5_; ++current4_; } if (current4_ == end4_) { current4_ = begin4_; ++current3_; } if (current3_ == end3_) { current3_ = begin3_; ++current2_; } if (current2_ == end2_) { current2_ = begin2_; ++current1_; } ComputeCurrentValue(); } virtual ParamIteratorInterface* Clone() const { return new Iterator(*this); } virtual const ParamType* Current() const { return ¤t_value_; } virtual bool Equals(const ParamIteratorInterface& other) const { // Having the same base generator guarantees that the other // iterator is of the same type and we can downcast. GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) << "The program attempted to compare iterators " << "from different generators." << std::endl; const Iterator* typed_other = CheckedDowncastToActualType(&other); // We must report iterators equal if they both point beyond their // respective ranges. That can happen in a variety of fashions, // so we have to consult AtEnd(). return (AtEnd() && typed_other->AtEnd()) || ( current1_ == typed_other->current1_ && current2_ == typed_other->current2_ && current3_ == typed_other->current3_ && current4_ == typed_other->current4_ && current5_ == typed_other->current5_ && current6_ == typed_other->current6_ && current7_ == typed_other->current7_ && current8_ == typed_other->current8_); } private: Iterator(const Iterator& other) : base_(other.base_), begin1_(other.begin1_), end1_(other.end1_), current1_(other.current1_), begin2_(other.begin2_), end2_(other.end2_), current2_(other.current2_), begin3_(other.begin3_), end3_(other.end3_), current3_(other.current3_), begin4_(other.begin4_), end4_(other.end4_), current4_(other.current4_), begin5_(other.begin5_), end5_(other.end5_), current5_(other.current5_), begin6_(other.begin6_), end6_(other.end6_), current6_(other.current6_), begin7_(other.begin7_), end7_(other.end7_), current7_(other.current7_), begin8_(other.begin8_), end8_(other.end8_), current8_(other.current8_) { ComputeCurrentValue(); } void ComputeCurrentValue() { if (!AtEnd()) current_value_ = ParamType(*current1_, *current2_, *current3_, *current4_, *current5_, *current6_, *current7_, *current8_); } bool AtEnd() const { // We must report iterator past the end of the range when either of the // component iterators has reached the end of its range. return current1_ == end1_ || current2_ == end2_ || current3_ == end3_ || current4_ == end4_ || current5_ == end5_ || current6_ == end6_ || current7_ == end7_ || current8_ == end8_; } // No implementation - assignment is unsupported. void operator=(const Iterator& other); const ParamGeneratorInterface* const base_; // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. // current[i]_ is the actual traversing iterator. const typename ParamGenerator::iterator begin1_; const typename ParamGenerator::iterator end1_; typename ParamGenerator::iterator current1_; const typename ParamGenerator::iterator begin2_; const typename ParamGenerator::iterator end2_; typename ParamGenerator::iterator current2_; const typename ParamGenerator::iterator begin3_; const typename ParamGenerator::iterator end3_; typename ParamGenerator::iterator current3_; const typename ParamGenerator::iterator begin4_; const typename ParamGenerator::iterator end4_; typename ParamGenerator::iterator current4_; const typename ParamGenerator::iterator begin5_; const typename ParamGenerator::iterator end5_; typename ParamGenerator::iterator current5_; const typename ParamGenerator::iterator begin6_; const typename ParamGenerator::iterator end6_; typename ParamGenerator::iterator current6_; const typename ParamGenerator::iterator begin7_; const typename ParamGenerator::iterator end7_; typename ParamGenerator::iterator current7_; const typename ParamGenerator::iterator begin8_; const typename ParamGenerator::iterator end8_; typename ParamGenerator::iterator current8_; ParamType current_value_; }; // class CartesianProductGenerator8::Iterator // No implementation - assignment is unsupported. void operator=(const CartesianProductGenerator8& other); const ParamGenerator g1_; const ParamGenerator g2_; const ParamGenerator g3_; const ParamGenerator g4_; const ParamGenerator g5_; const ParamGenerator g6_; const ParamGenerator g7_; const ParamGenerator g8_; }; // class CartesianProductGenerator8 template class CartesianProductGenerator9 : public ParamGeneratorInterface< ::std::tr1::tuple > { public: typedef ::std::tr1::tuple ParamType; CartesianProductGenerator9(const ParamGenerator& g1, const ParamGenerator& g2, const ParamGenerator& g3, const ParamGenerator& g4, const ParamGenerator& g5, const ParamGenerator& g6, const ParamGenerator& g7, const ParamGenerator& g8, const ParamGenerator& g9) : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), g8_(g8), g9_(g9) {} virtual ~CartesianProductGenerator9() {} virtual ParamIteratorInterface* Begin() const { return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin(), g7_, g7_.begin(), g8_, g8_.begin(), g9_, g9_.begin()); } virtual ParamIteratorInterface* End() const { return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(), g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end(), g7_, g7_.end(), g8_, g8_.end(), g9_, g9_.end()); } private: class Iterator : public ParamIteratorInterface { public: Iterator(const ParamGeneratorInterface* base, const ParamGenerator& g1, const typename ParamGenerator::iterator& current1, const ParamGenerator& g2, const typename ParamGenerator::iterator& current2, const ParamGenerator& g3, const typename ParamGenerator::iterator& current3, const ParamGenerator& g4, const typename ParamGenerator::iterator& current4, const ParamGenerator& g5, const typename ParamGenerator::iterator& current5, const ParamGenerator& g6, const typename ParamGenerator::iterator& current6, const ParamGenerator& g7, const typename ParamGenerator::iterator& current7, const ParamGenerator& g8, const typename ParamGenerator::iterator& current8, const ParamGenerator& g9, const typename ParamGenerator::iterator& current9) : base_(base), begin1_(g1.begin()), end1_(g1.end()), current1_(current1), begin2_(g2.begin()), end2_(g2.end()), current2_(current2), begin3_(g3.begin()), end3_(g3.end()), current3_(current3), begin4_(g4.begin()), end4_(g4.end()), current4_(current4), begin5_(g5.begin()), end5_(g5.end()), current5_(current5), begin6_(g6.begin()), end6_(g6.end()), current6_(current6), begin7_(g7.begin()), end7_(g7.end()), current7_(current7), begin8_(g8.begin()), end8_(g8.end()), current8_(current8), begin9_(g9.begin()), end9_(g9.end()), current9_(current9) { ComputeCurrentValue(); } virtual ~Iterator() {} virtual const ParamGeneratorInterface* BaseGenerator() const { return base_; } // Advance should not be called on beyond-of-range iterators // so no component iterators must be beyond end of range, either. virtual void Advance() { assert(!AtEnd()); ++current9_; if (current9_ == end9_) { current9_ = begin9_; ++current8_; } if (current8_ == end8_) { current8_ = begin8_; ++current7_; } if (current7_ == end7_) { current7_ = begin7_; ++current6_; } if (current6_ == end6_) { current6_ = begin6_; ++current5_; } if (current5_ == end5_) { current5_ = begin5_; ++current4_; } if (current4_ == end4_) { current4_ = begin4_; ++current3_; } if (current3_ == end3_) { current3_ = begin3_; ++current2_; } if (current2_ == end2_) { current2_ = begin2_; ++current1_; } ComputeCurrentValue(); } virtual ParamIteratorInterface* Clone() const { return new Iterator(*this); } virtual const ParamType* Current() const { return ¤t_value_; } virtual bool Equals(const ParamIteratorInterface& other) const { // Having the same base generator guarantees that the other // iterator is of the same type and we can downcast. GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) << "The program attempted to compare iterators " << "from different generators." << std::endl; const Iterator* typed_other = CheckedDowncastToActualType(&other); // We must report iterators equal if they both point beyond their // respective ranges. That can happen in a variety of fashions, // so we have to consult AtEnd(). return (AtEnd() && typed_other->AtEnd()) || ( current1_ == typed_other->current1_ && current2_ == typed_other->current2_ && current3_ == typed_other->current3_ && current4_ == typed_other->current4_ && current5_ == typed_other->current5_ && current6_ == typed_other->current6_ && current7_ == typed_other->current7_ && current8_ == typed_other->current8_ && current9_ == typed_other->current9_); } private: Iterator(const Iterator& other) : base_(other.base_), begin1_(other.begin1_), end1_(other.end1_), current1_(other.current1_), begin2_(other.begin2_), end2_(other.end2_), current2_(other.current2_), begin3_(other.begin3_), end3_(other.end3_), current3_(other.current3_), begin4_(other.begin4_), end4_(other.end4_), current4_(other.current4_), begin5_(other.begin5_), end5_(other.end5_), current5_(other.current5_), begin6_(other.begin6_), end6_(other.end6_), current6_(other.current6_), begin7_(other.begin7_), end7_(other.end7_), current7_(other.current7_), begin8_(other.begin8_), end8_(other.end8_), current8_(other.current8_), begin9_(other.begin9_), end9_(other.end9_), current9_(other.current9_) { ComputeCurrentValue(); } void ComputeCurrentValue() { if (!AtEnd()) current_value_ = ParamType(*current1_, *current2_, *current3_, *current4_, *current5_, *current6_, *current7_, *current8_, *current9_); } bool AtEnd() const { // We must report iterator past the end of the range when either of the // component iterators has reached the end of its range. return current1_ == end1_ || current2_ == end2_ || current3_ == end3_ || current4_ == end4_ || current5_ == end5_ || current6_ == end6_ || current7_ == end7_ || current8_ == end8_ || current9_ == end9_; } // No implementation - assignment is unsupported. void operator=(const Iterator& other); const ParamGeneratorInterface* const base_; // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. // current[i]_ is the actual traversing iterator. const typename ParamGenerator::iterator begin1_; const typename ParamGenerator::iterator end1_; typename ParamGenerator::iterator current1_; const typename ParamGenerator::iterator begin2_; const typename ParamGenerator::iterator end2_; typename ParamGenerator::iterator current2_; const typename ParamGenerator::iterator begin3_; const typename ParamGenerator::iterator end3_; typename ParamGenerator::iterator current3_; const typename ParamGenerator::iterator begin4_; const typename ParamGenerator::iterator end4_; typename ParamGenerator::iterator current4_; const typename ParamGenerator::iterator begin5_; const typename ParamGenerator::iterator end5_; typename ParamGenerator::iterator current5_; const typename ParamGenerator::iterator begin6_; const typename ParamGenerator::iterator end6_; typename ParamGenerator::iterator current6_; const typename ParamGenerator::iterator begin7_; const typename ParamGenerator::iterator end7_; typename ParamGenerator::iterator current7_; const typename ParamGenerator::iterator begin8_; const typename ParamGenerator::iterator end8_; typename ParamGenerator::iterator current8_; const typename ParamGenerator::iterator begin9_; const typename ParamGenerator::iterator end9_; typename ParamGenerator::iterator current9_; ParamType current_value_; }; // class CartesianProductGenerator9::Iterator // No implementation - assignment is unsupported. void operator=(const CartesianProductGenerator9& other); const ParamGenerator g1_; const ParamGenerator g2_; const ParamGenerator g3_; const ParamGenerator g4_; const ParamGenerator g5_; const ParamGenerator g6_; const ParamGenerator g7_; const ParamGenerator g8_; const ParamGenerator g9_; }; // class CartesianProductGenerator9 template class CartesianProductGenerator10 : public ParamGeneratorInterface< ::std::tr1::tuple > { public: typedef ::std::tr1::tuple ParamType; CartesianProductGenerator10(const ParamGenerator& g1, const ParamGenerator& g2, const ParamGenerator& g3, const ParamGenerator& g4, const ParamGenerator& g5, const ParamGenerator& g6, const ParamGenerator& g7, const ParamGenerator& g8, const ParamGenerator& g9, const ParamGenerator& g10) : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), g8_(g8), g9_(g9), g10_(g10) {} virtual ~CartesianProductGenerator10() {} virtual ParamIteratorInterface* Begin() const { return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin(), g7_, g7_.begin(), g8_, g8_.begin(), g9_, g9_.begin(), g10_, g10_.begin()); } virtual ParamIteratorInterface* End() const { return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(), g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end(), g7_, g7_.end(), g8_, g8_.end(), g9_, g9_.end(), g10_, g10_.end()); } private: class Iterator : public ParamIteratorInterface { public: Iterator(const ParamGeneratorInterface* base, const ParamGenerator& g1, const typename ParamGenerator::iterator& current1, const ParamGenerator& g2, const typename ParamGenerator::iterator& current2, const ParamGenerator& g3, const typename ParamGenerator::iterator& current3, const ParamGenerator& g4, const typename ParamGenerator::iterator& current4, const ParamGenerator& g5, const typename ParamGenerator::iterator& current5, const ParamGenerator& g6, const typename ParamGenerator::iterator& current6, const ParamGenerator& g7, const typename ParamGenerator::iterator& current7, const ParamGenerator& g8, const typename ParamGenerator::iterator& current8, const ParamGenerator& g9, const typename ParamGenerator::iterator& current9, const ParamGenerator& g10, const typename ParamGenerator::iterator& current10) : base_(base), begin1_(g1.begin()), end1_(g1.end()), current1_(current1), begin2_(g2.begin()), end2_(g2.end()), current2_(current2), begin3_(g3.begin()), end3_(g3.end()), current3_(current3), begin4_(g4.begin()), end4_(g4.end()), current4_(current4), begin5_(g5.begin()), end5_(g5.end()), current5_(current5), begin6_(g6.begin()), end6_(g6.end()), current6_(current6), begin7_(g7.begin()), end7_(g7.end()), current7_(current7), begin8_(g8.begin()), end8_(g8.end()), current8_(current8), begin9_(g9.begin()), end9_(g9.end()), current9_(current9), begin10_(g10.begin()), end10_(g10.end()), current10_(current10) { ComputeCurrentValue(); } virtual ~Iterator() {} virtual const ParamGeneratorInterface* BaseGenerator() const { return base_; } // Advance should not be called on beyond-of-range iterators // so no component iterators must be beyond end of range, either. virtual void Advance() { assert(!AtEnd()); ++current10_; if (current10_ == end10_) { current10_ = begin10_; ++current9_; } if (current9_ == end9_) { current9_ = begin9_; ++current8_; } if (current8_ == end8_) { current8_ = begin8_; ++current7_; } if (current7_ == end7_) { current7_ = begin7_; ++current6_; } if (current6_ == end6_) { current6_ = begin6_; ++current5_; } if (current5_ == end5_) { current5_ = begin5_; ++current4_; } if (current4_ == end4_) { current4_ = begin4_; ++current3_; } if (current3_ == end3_) { current3_ = begin3_; ++current2_; } if (current2_ == end2_) { current2_ = begin2_; ++current1_; } ComputeCurrentValue(); } virtual ParamIteratorInterface* Clone() const { return new Iterator(*this); } virtual const ParamType* Current() const { return ¤t_value_; } virtual bool Equals(const ParamIteratorInterface& other) const { // Having the same base generator guarantees that the other // iterator is of the same type and we can downcast. GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) << "The program attempted to compare iterators " << "from different generators." << std::endl; const Iterator* typed_other = CheckedDowncastToActualType(&other); // We must report iterators equal if they both point beyond their // respective ranges. That can happen in a variety of fashions, // so we have to consult AtEnd(). return (AtEnd() && typed_other->AtEnd()) || ( current1_ == typed_other->current1_ && current2_ == typed_other->current2_ && current3_ == typed_other->current3_ && current4_ == typed_other->current4_ && current5_ == typed_other->current5_ && current6_ == typed_other->current6_ && current7_ == typed_other->current7_ && current8_ == typed_other->current8_ && current9_ == typed_other->current9_ && current10_ == typed_other->current10_); } private: Iterator(const Iterator& other) : base_(other.base_), begin1_(other.begin1_), end1_(other.end1_), current1_(other.current1_), begin2_(other.begin2_), end2_(other.end2_), current2_(other.current2_), begin3_(other.begin3_), end3_(other.end3_), current3_(other.current3_), begin4_(other.begin4_), end4_(other.end4_), current4_(other.current4_), begin5_(other.begin5_), end5_(other.end5_), current5_(other.current5_), begin6_(other.begin6_), end6_(other.end6_), current6_(other.current6_), begin7_(other.begin7_), end7_(other.end7_), current7_(other.current7_), begin8_(other.begin8_), end8_(other.end8_), current8_(other.current8_), begin9_(other.begin9_), end9_(other.end9_), current9_(other.current9_), begin10_(other.begin10_), end10_(other.end10_), current10_(other.current10_) { ComputeCurrentValue(); } void ComputeCurrentValue() { if (!AtEnd()) current_value_ = ParamType(*current1_, *current2_, *current3_, *current4_, *current5_, *current6_, *current7_, *current8_, *current9_, *current10_); } bool AtEnd() const { // We must report iterator past the end of the range when either of the // component iterators has reached the end of its range. return current1_ == end1_ || current2_ == end2_ || current3_ == end3_ || current4_ == end4_ || current5_ == end5_ || current6_ == end6_ || current7_ == end7_ || current8_ == end8_ || current9_ == end9_ || current10_ == end10_; } // No implementation - assignment is unsupported. void operator=(const Iterator& other); const ParamGeneratorInterface* const base_; // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. // current[i]_ is the actual traversing iterator. const typename ParamGenerator::iterator begin1_; const typename ParamGenerator::iterator end1_; typename ParamGenerator::iterator current1_; const typename ParamGenerator::iterator begin2_; const typename ParamGenerator::iterator end2_; typename ParamGenerator::iterator current2_; const typename ParamGenerator::iterator begin3_; const typename ParamGenerator::iterator end3_; typename ParamGenerator::iterator current3_; const typename ParamGenerator::iterator begin4_; const typename ParamGenerator::iterator end4_; typename ParamGenerator::iterator current4_; const typename ParamGenerator::iterator begin5_; const typename ParamGenerator::iterator end5_; typename ParamGenerator::iterator current5_; const typename ParamGenerator::iterator begin6_; const typename ParamGenerator::iterator end6_; typename ParamGenerator::iterator current6_; const typename ParamGenerator::iterator begin7_; const typename ParamGenerator::iterator end7_; typename ParamGenerator::iterator current7_; const typename ParamGenerator::iterator begin8_; const typename ParamGenerator::iterator end8_; typename ParamGenerator::iterator current8_; const typename ParamGenerator::iterator begin9_; const typename ParamGenerator::iterator end9_; typename ParamGenerator::iterator current9_; const typename ParamGenerator::iterator begin10_; const typename ParamGenerator::iterator end10_; typename ParamGenerator::iterator current10_; ParamType current_value_; }; // class CartesianProductGenerator10::Iterator // No implementation - assignment is unsupported. void operator=(const CartesianProductGenerator10& other); const ParamGenerator g1_; const ParamGenerator g2_; const ParamGenerator g3_; const ParamGenerator g4_; const ParamGenerator g5_; const ParamGenerator g6_; const ParamGenerator g7_; const ParamGenerator g8_; const ParamGenerator g9_; const ParamGenerator g10_; }; // class CartesianProductGenerator10 // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. // // Helper classes providing Combine() with polymorphic features. They allow // casting CartesianProductGeneratorN to ParamGenerator if T is // convertible to U. // template class CartesianProductHolder2 { public: CartesianProductHolder2(const Generator1& g1, const Generator2& g2) : g1_(g1), g2_(g2) {} template operator ParamGenerator< ::std::tr1::tuple >() const { return ParamGenerator< ::std::tr1::tuple >( new CartesianProductGenerator2( static_cast >(g1_), static_cast >(g2_))); } private: // No implementation - assignment is unsupported. void operator=(const CartesianProductHolder2& other); const Generator1 g1_; const Generator2 g2_; }; // class CartesianProductHolder2 template class CartesianProductHolder3 { public: 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 >( new CartesianProductGenerator3( static_cast >(g1_), static_cast >(g2_), static_cast >(g3_))); } private: // No implementation - assignment is unsupported. void operator=(const CartesianProductHolder3& other); const Generator1 g1_; const Generator2 g2_; const Generator3 g3_; }; // class CartesianProductHolder3 template class CartesianProductHolder4 { public: 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 >( new CartesianProductGenerator4( static_cast >(g1_), static_cast >(g2_), static_cast >(g3_), static_cast >(g4_))); } private: // No implementation - assignment is unsupported. void operator=(const CartesianProductHolder4& other); const Generator1 g1_; const Generator2 g2_; const Generator3 g3_; const Generator4 g4_; }; // class CartesianProductHolder4 template class CartesianProductHolder5 { public: CartesianProductHolder5(const Generator1& g1, const Generator2& g2, const Generator3& g3, const Generator4& g4, const Generator5& g5) : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5) {} template operator ParamGenerator< ::std::tr1::tuple >() const { return ParamGenerator< ::std::tr1::tuple >( new CartesianProductGenerator5( static_cast >(g1_), static_cast >(g2_), static_cast >(g3_), static_cast >(g4_), static_cast >(g5_))); } private: // No implementation - assignment is unsupported. void operator=(const CartesianProductHolder5& other); const Generator1 g1_; const Generator2 g2_; const Generator3 g3_; const Generator4 g4_; const Generator5 g5_; }; // class CartesianProductHolder5 template class CartesianProductHolder6 { public: CartesianProductHolder6(const Generator1& g1, const Generator2& g2, const Generator3& g3, const Generator4& g4, const Generator5& g5, const Generator6& g6) : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6) {} template operator ParamGenerator< ::std::tr1::tuple >() const { return ParamGenerator< ::std::tr1::tuple >( new CartesianProductGenerator6( static_cast >(g1_), static_cast >(g2_), static_cast >(g3_), static_cast >(g4_), static_cast >(g5_), static_cast >(g6_))); } private: // No implementation - assignment is unsupported. void operator=(const CartesianProductHolder6& other); const Generator1 g1_; const Generator2 g2_; const Generator3 g3_; const Generator4 g4_; const Generator5 g5_; const Generator6 g6_; }; // class CartesianProductHolder6 template class CartesianProductHolder7 { public: CartesianProductHolder7(const Generator1& g1, const Generator2& g2, const Generator3& g3, const Generator4& g4, const Generator5& g5, const Generator6& g6, const Generator7& g7) : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7) {} template operator ParamGenerator< ::std::tr1::tuple >() const { return ParamGenerator< ::std::tr1::tuple >( new CartesianProductGenerator7( static_cast >(g1_), static_cast >(g2_), static_cast >(g3_), static_cast >(g4_), static_cast >(g5_), static_cast >(g6_), static_cast >(g7_))); } private: // No implementation - assignment is unsupported. void operator=(const CartesianProductHolder7& other); const Generator1 g1_; const Generator2 g2_; const Generator3 g3_; const Generator4 g4_; const Generator5 g5_; const Generator6 g6_; const Generator7 g7_; }; // class CartesianProductHolder7 template class CartesianProductHolder8 { public: CartesianProductHolder8(const Generator1& g1, const Generator2& g2, const Generator3& g3, const Generator4& g4, const Generator5& g5, const Generator6& g6, const Generator7& g7, const Generator8& g8) : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), g8_(g8) {} template operator ParamGenerator< ::std::tr1::tuple >() const { return ParamGenerator< ::std::tr1::tuple >( new CartesianProductGenerator8( static_cast >(g1_), static_cast >(g2_), static_cast >(g3_), static_cast >(g4_), static_cast >(g5_), static_cast >(g6_), static_cast >(g7_), static_cast >(g8_))); } private: // No implementation - assignment is unsupported. void operator=(const CartesianProductHolder8& other); const Generator1 g1_; const Generator2 g2_; const Generator3 g3_; const Generator4 g4_; const Generator5 g5_; const Generator6 g6_; const Generator7 g7_; const Generator8 g8_; }; // class CartesianProductHolder8 template class CartesianProductHolder9 { public: CartesianProductHolder9(const Generator1& g1, const Generator2& g2, const Generator3& g3, const Generator4& g4, const Generator5& g5, const Generator6& g6, const Generator7& g7, const Generator8& g8, const Generator9& g9) : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), g8_(g8), g9_(g9) {} template operator ParamGenerator< ::std::tr1::tuple >() const { return ParamGenerator< ::std::tr1::tuple >( new CartesianProductGenerator9( static_cast >(g1_), static_cast >(g2_), static_cast >(g3_), static_cast >(g4_), static_cast >(g5_), static_cast >(g6_), static_cast >(g7_), static_cast >(g8_), static_cast >(g9_))); } private: // No implementation - assignment is unsupported. void operator=(const CartesianProductHolder9& other); const Generator1 g1_; const Generator2 g2_; const Generator3 g3_; const Generator4 g4_; const Generator5 g5_; const Generator6 g6_; const Generator7 g7_; const Generator8 g8_; const Generator9 g9_; }; // class CartesianProductHolder9 template class CartesianProductHolder10 { public: CartesianProductHolder10(const Generator1& g1, const Generator2& g2, const Generator3& g3, const Generator4& g4, const Generator5& g5, const Generator6& g6, const Generator7& g7, const Generator8& g8, const Generator9& g9, const Generator10& g10) : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), g8_(g8), g9_(g9), g10_(g10) {} template operator ParamGenerator< ::std::tr1::tuple >() const { return ParamGenerator< ::std::tr1::tuple >( new CartesianProductGenerator10( static_cast >(g1_), static_cast >(g2_), static_cast >(g3_), static_cast >(g4_), static_cast >(g5_), static_cast >(g6_), static_cast >(g7_), static_cast >(g8_), static_cast >(g9_), static_cast >(g10_))); } private: // No implementation - assignment is unsupported. void operator=(const CartesianProductHolder10& other); const Generator1 g1_; const Generator2 g2_; const Generator3 g3_; const Generator4 g4_; const Generator5 g5_; const Generator6 g6_; const Generator7 g7_; const Generator8 g8_; const Generator9 g9_; const Generator10 g10_; }; // class CartesianProductHolder10 # endif // GTEST_HAS_COMBINE } // namespace internal } // namespace testing #endif // GTEST_HAS_PARAM_TEST #endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_ #if GTEST_HAS_PARAM_TEST namespace testing { // Functions producing parameter generators. // // Google Test uses these generators to produce parameters for value- // parameterized tests. When a parameterized test case is instantiated // with a particular generator, Google Test creates and runs tests // for each element in the sequence produced by the generator. // // In the following sample, tests from test case FooTest are instantiated // each three times with parameter values 3, 5, and 8: // // class FooTest : public TestWithParam { ... }; // // TEST_P(FooTest, TestThis) { // } // TEST_P(FooTest, TestThat) { // } // INSTANTIATE_TEST_CASE_P(TestSequence, FooTest, Values(3, 5, 8)); // // Range() returns generators providing sequences of values in a range. // // Synopsis: // Range(start, end) // - returns a generator producing a sequence of values {start, start+1, // start+2, ..., }. // Range(start, end, step) // - returns a generator producing a sequence of values {start, start+step, // start+step+step, ..., }. // Notes: // * The generated sequences never include end. For example, Range(1, 5) // returns a generator producing a sequence {1, 2, 3, 4}. Range(1, 9, 2) // returns a generator producing {1, 3, 5, 7}. // * start and end must have the same type. That type may be any integral or // floating-point type or a user defined type satisfying these conditions: // * It must be assignable (have operator=() defined). // * It must have operator+() (operator+(int-compatible type) for // two-operand version). // * It must have operator<() defined. // Elements in the resulting sequences will also have that type. // * Condition start < end must be satisfied in order for resulting sequences // to contain any elements. // template internal::ParamGenerator Range(T start, T end, IncrementT step) { return internal::ParamGenerator( new internal::RangeGenerator(start, end, step)); } template internal::ParamGenerator Range(T start, T end) { return Range(start, end, 1); } // ValuesIn() function allows generation of tests with parameters coming from // a container. // // Synopsis: // ValuesIn(const T (&array)[N]) // - returns a generator producing sequences with elements from // a C-style array. // ValuesIn(const Container& container) // - returns a generator producing sequences with elements from // an STL-style container. // ValuesIn(Iterator begin, Iterator end) // - returns a generator producing sequences with elements from // a range [begin, end) defined by a pair of STL-style iterators. These // iterators can also be plain C pointers. // // Please note that ValuesIn copies the values from the containers // passed in and keeps them to generate tests in RUN_ALL_TESTS(). // // Examples: // // This instantiates tests from test case StringTest // each with C-string values of "foo", "bar", and "baz": // // const char* strings[] = {"foo", "bar", "baz"}; // INSTANTIATE_TEST_CASE_P(StringSequence, SrtingTest, ValuesIn(strings)); // // This instantiates tests from test case StlStringTest // each with STL strings with values "a" and "b": // // ::std::vector< ::std::string> GetParameterStrings() { // ::std::vector< ::std::string> v; // v.push_back("a"); // v.push_back("b"); // return v; // } // // INSTANTIATE_TEST_CASE_P(CharSequence, // StlStringTest, // ValuesIn(GetParameterStrings())); // // // This will also instantiate tests from CharTest // each with parameter values 'a' and 'b': // // ::std::list GetParameterChars() { // ::std::list list; // list.push_back('a'); // list.push_back('b'); // return list; // } // ::std::list l = GetParameterChars(); // INSTANTIATE_TEST_CASE_P(CharSequence2, // CharTest, // ValuesIn(l.begin(), l.end())); // template internal::ParamGenerator< typename ::testing::internal::IteratorTraits::value_type> ValuesIn(ForwardIterator begin, ForwardIterator end) { typedef typename ::testing::internal::IteratorTraits ::value_type ParamType; return internal::ParamGenerator( new internal::ValuesInIteratorRangeGenerator(begin, end)); } template internal::ParamGenerator ValuesIn(const T (&array)[N]) { return ValuesIn(array, array + N); } template internal::ParamGenerator ValuesIn( const Container& container) { return ValuesIn(container.begin(), container.end()); } // Values() allows generating tests from explicitly specified list of // parameters. // // Synopsis: // Values(T v1, T v2, ..., T vN) // - returns a generator producing sequences with elements v1, v2, ..., vN. // // For example, this instantiates tests from test case BarTest each // with values "one", "two", and "three": // // INSTANTIATE_TEST_CASE_P(NumSequence, BarTest, Values("one", "two", "three")); // // This instantiates tests from test case BazTest each with values 1, 2, 3.5. // The exact type of values will depend on the type of parameter in BazTest. // // INSTANTIATE_TEST_CASE_P(FloatingNumbers, BazTest, Values(1, 2, 3.5)); // // Currently, Values() supports from 1 to 50 parameters. // template internal::ValueArray1 Values(T1 v1) { return internal::ValueArray1(v1); } template internal::ValueArray2 Values(T1 v1, T2 v2) { return internal::ValueArray2(v1, v2); } template internal::ValueArray3 Values(T1 v1, T2 v2, T3 v3) { return internal::ValueArray3(v1, v2, v3); } template internal::ValueArray4 Values(T1 v1, T2 v2, T3 v3, T4 v4) { return internal::ValueArray4(v1, v2, v3, v4); } template internal::ValueArray5 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5) { return internal::ValueArray5(v1, v2, v3, v4, v5); } template internal::ValueArray6 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6) { return internal::ValueArray6(v1, v2, v3, v4, v5, v6); } template internal::ValueArray7 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7) { return internal::ValueArray7(v1, v2, v3, v4, v5, v6, v7); } template internal::ValueArray8 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8) { return internal::ValueArray8(v1, v2, v3, v4, v5, v6, v7, v8); } template internal::ValueArray9 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9) { return internal::ValueArray9(v1, v2, v3, v4, v5, v6, v7, v8, v9); } template internal::ValueArray10 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10) { return internal::ValueArray10(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10); } template internal::ValueArray11 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11) { return internal::ValueArray11(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11); } template internal::ValueArray12 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12) { return internal::ValueArray12(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12); } template internal::ValueArray13 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13) { return internal::ValueArray13(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13); } template internal::ValueArray14 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14) { return internal::ValueArray14(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14); } template internal::ValueArray15 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15) { return internal::ValueArray15(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15); } template internal::ValueArray16 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16) { return internal::ValueArray16(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16); } template internal::ValueArray17 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17) { return internal::ValueArray17(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17); } template internal::ValueArray18 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18) { return internal::ValueArray18(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18); } template internal::ValueArray19 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19) { return internal::ValueArray19(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19); } template internal::ValueArray20 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20) { return internal::ValueArray20(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20); } template internal::ValueArray21 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21) { return internal::ValueArray21(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21); } template internal::ValueArray22 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22) { return internal::ValueArray22(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22); } template internal::ValueArray23 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23) { return internal::ValueArray23(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23); } template internal::ValueArray24 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24) { return internal::ValueArray24(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24); } template internal::ValueArray25 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25) { return internal::ValueArray25(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25); } template internal::ValueArray26 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26) { return internal::ValueArray26(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26); } template internal::ValueArray27 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27) { return internal::ValueArray27(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27); } template internal::ValueArray28 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28) { return internal::ValueArray28(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28); } template internal::ValueArray29 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29) { return internal::ValueArray29(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29); } template internal::ValueArray30 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30) { return internal::ValueArray30(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30); } template internal::ValueArray31 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31) { return internal::ValueArray31(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31); } template internal::ValueArray32 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32) { return internal::ValueArray32(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32); } template internal::ValueArray33 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33) { return internal::ValueArray33(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33); } template internal::ValueArray34 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34) { return internal::ValueArray34(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34); } template internal::ValueArray35 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35) { return internal::ValueArray35(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35); } template internal::ValueArray36 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36) { return internal::ValueArray36(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36); } template internal::ValueArray37 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37) { return internal::ValueArray37(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37); } template internal::ValueArray38 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38) { return internal::ValueArray38(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38); } template internal::ValueArray39 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39) { return internal::ValueArray39(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39); } template internal::ValueArray40 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40) { return internal::ValueArray40(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40); } template internal::ValueArray41 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41) { return internal::ValueArray41(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41); } template internal::ValueArray42 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, T42 v42) { return internal::ValueArray42(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42); } template internal::ValueArray43 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, T42 v42, T43 v43) { return internal::ValueArray43(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43); } template internal::ValueArray44 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, T42 v42, T43 v43, T44 v44) { return internal::ValueArray44(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44); } template internal::ValueArray45 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45) { return internal::ValueArray45(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45); } template internal::ValueArray46 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46) { return internal::ValueArray46(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46); } template internal::ValueArray47 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47) { return internal::ValueArray47(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47); } template internal::ValueArray48 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47, T48 v48) { return internal::ValueArray48(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48); } template internal::ValueArray49 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47, T48 v48, T49 v49) { return internal::ValueArray49(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49); } template internal::ValueArray50 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47, T48 v48, T49 v49, T50 v50) { return internal::ValueArray50(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50); } // Bool() allows generating tests with parameters in a set of (false, true). // // Synopsis: // Bool() // - returns a generator producing sequences with elements {false, true}. // // It is useful when testing code that depends on Boolean flags. Combinations // of multiple flags can be tested when several Bool()'s are combined using // Combine() function. // // In the following example all tests in the test case FlagDependentTest // will be instantiated twice with parameters false and true. // // class FlagDependentTest : public testing::TestWithParam { // virtual void SetUp() { // external_flag = GetParam(); // } // } // INSTANTIATE_TEST_CASE_P(BoolSequence, FlagDependentTest, Bool()); // inline internal::ParamGenerator Bool() { return Values(false, true); } # if GTEST_HAS_COMBINE // Combine() allows the user to combine two or more sequences to produce // values of a Cartesian product of those sequences' elements. // // Synopsis: // Combine(gen1, gen2, ..., genN) // - returns a generator producing sequences with elements coming from // the Cartesian product of elements from the sequences generated by // gen1, gen2, ..., genN. The sequence elements will have a type of // tuple where T1, T2, ..., TN are the types // of elements from sequences produces by gen1, gen2, ..., genN. // // Combine can have up to 10 arguments. This number is currently limited // by the maximum number of elements in the tuple implementation used by Google // Test. // // Example: // // This will instantiate tests in test case AnimalTest each one with // the parameter values tuple("cat", BLACK), tuple("cat", WHITE), // tuple("dog", BLACK), and tuple("dog", WHITE): // // enum Color { BLACK, GRAY, WHITE }; // class AnimalTest // : public testing::TestWithParam > {...}; // // TEST_P(AnimalTest, AnimalLooksNice) {...} // // INSTANTIATE_TEST_CASE_P(AnimalVariations, AnimalTest, // Combine(Values("cat", "dog"), // Values(BLACK, WHITE))); // // This will instantiate tests in FlagDependentTest with all variations of two // Boolean flags: // // class FlagDependentTest // : public testing::TestWithParam > { // virtual void SetUp() { // // Assigns external_flag_1 and external_flag_2 values from the tuple. // tie(external_flag_1, external_flag_2) = GetParam(); // } // }; // // TEST_P(FlagDependentTest, TestFeature1) { // // Test your code using external_flag_1 and external_flag_2 here. // } // INSTANTIATE_TEST_CASE_P(TwoBoolSequence, FlagDependentTest, // Combine(Bool(), Bool())); // template internal::CartesianProductHolder2 Combine( const Generator1& g1, const Generator2& g2) { return internal::CartesianProductHolder2( g1, g2); } template internal::CartesianProductHolder3 Combine( const Generator1& g1, const Generator2& g2, const Generator3& g3) { return internal::CartesianProductHolder3( g1, g2, g3); } template internal::CartesianProductHolder4 Combine( const Generator1& g1, const Generator2& g2, const Generator3& g3, const Generator4& g4) { return internal::CartesianProductHolder4( g1, g2, g3, g4); } template internal::CartesianProductHolder5 Combine( const Generator1& g1, const Generator2& g2, const Generator3& g3, const Generator4& g4, const Generator5& g5) { return internal::CartesianProductHolder5( g1, g2, g3, g4, g5); } template internal::CartesianProductHolder6 Combine( const Generator1& g1, const Generator2& g2, const Generator3& g3, const Generator4& g4, const Generator5& g5, const Generator6& g6) { return internal::CartesianProductHolder6( g1, g2, g3, g4, g5, g6); } template internal::CartesianProductHolder7 Combine( const Generator1& g1, const Generator2& g2, const Generator3& g3, const Generator4& g4, const Generator5& g5, const Generator6& g6, const Generator7& g7) { return internal::CartesianProductHolder7( g1, g2, g3, g4, g5, g6, g7); } template internal::CartesianProductHolder8 Combine( const Generator1& g1, const Generator2& g2, const Generator3& g3, const Generator4& g4, const Generator5& g5, const Generator6& g6, const Generator7& g7, const Generator8& g8) { return internal::CartesianProductHolder8( g1, g2, g3, g4, g5, g6, g7, g8); } template internal::CartesianProductHolder9 Combine( const Generator1& g1, const Generator2& g2, const Generator3& g3, const Generator4& g4, const Generator5& g5, const Generator6& g6, const Generator7& g7, const Generator8& g8, const Generator9& g9) { return internal::CartesianProductHolder9( g1, g2, g3, g4, g5, g6, g7, g8, g9); } template internal::CartesianProductHolder10 Combine( const Generator1& g1, const Generator2& g2, const Generator3& g3, const Generator4& g4, const Generator5& g5, const Generator6& g6, const Generator7& g7, const Generator8& g8, const Generator9& g9, const Generator10& g10) { return internal::CartesianProductHolder10( g1, g2, g3, g4, g5, g6, g7, g8, g9, g10); } # endif // GTEST_HAS_COMBINE # define TEST_P(test_case_name, test_name) \ class GTEST_TEST_CLASS_NAME_(test_case_name, test_name) \ : public test_case_name { \ public: \ GTEST_TEST_CLASS_NAME_(test_case_name, test_name)() {} \ virtual void TestBody(); \ private: \ static int AddToRegistry() { \ ::testing::UnitTest::GetInstance()->parameterized_test_registry(). \ GetTestCasePatternHolder(\ #test_case_name, __FILE__, __LINE__)->AddTestPattern(\ #test_case_name, \ #test_name, \ new ::testing::internal::TestMetaFactory< \ GTEST_TEST_CLASS_NAME_(test_case_name, test_name)>()); \ return 0; \ } \ static int gtest_registering_dummy_; \ GTEST_DISALLOW_COPY_AND_ASSIGN_(\ GTEST_TEST_CLASS_NAME_(test_case_name, test_name)); \ }; \ int GTEST_TEST_CLASS_NAME_(test_case_name, \ test_name)::gtest_registering_dummy_ = \ GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::AddToRegistry(); \ void GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::TestBody() # define INSTANTIATE_TEST_CASE_P(prefix, test_case_name, generator) \ ::testing::internal::ParamGenerator \ gtest_##prefix##test_case_name##_EvalGenerator_() { return generator; } \ int gtest_##prefix##test_case_name##_dummy_ = \ ::testing::UnitTest::GetInstance()->parameterized_test_registry(). \ GetTestCasePatternHolder(\ #test_case_name, __FILE__, __LINE__)->AddTestCaseInstantiation(\ #prefix, \ >est_##prefix##test_case_name##_EvalGenerator_, \ __FILE__, __LINE__) } // namespace testing #endif // GTEST_HAS_PARAM_TEST #endif // GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_ // Copyright 2006, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: wan@google.com (Zhanyong Wan) // // Google C++ Testing Framework definitions useful in production code. #ifndef GTEST_INCLUDE_GTEST_GTEST_PROD_H_ #define GTEST_INCLUDE_GTEST_GTEST_PROD_H_ // When you need to test the private or protected members of a class, // use the FRIEND_TEST macro to declare your tests as friends of the // class. For example: // // class MyClass { // private: // void MyMethod(); // FRIEND_TEST(MyClassTest, MyMethod); // }; // // class MyClassTest : public testing::Test { // // ... // }; // // TEST_F(MyClassTest, MyMethod) { // // Can call MyClass::MyMethod() here. // } #define FRIEND_TEST(test_case_name, test_name)\ friend class test_case_name##_##test_name##_Test #endif // GTEST_INCLUDE_GTEST_GTEST_PROD_H_ // Copyright 2008, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: mheule@google.com (Markus Heule) // #ifndef GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_ #define GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_ #include #include namespace testing { // A copyable object representing the result of a test part (i.e. an // assertion or an explicit FAIL(), ADD_FAILURE(), or SUCCESS()). // // Don't inherit from TestPartResult as its destructor is not virtual. class GTEST_API_ TestPartResult { public: // The possible outcomes of a test part (i.e. an assertion or an // explicit SUCCEED(), FAIL(), or ADD_FAILURE()). enum Type { kSuccess, // Succeeded. kNonFatalFailure, // Failed but the test can continue. kFatalFailure // Failed and the test should be terminated. }; // C'tor. TestPartResult does NOT have a default constructor. // Always use this constructor (with parameters) to create a // TestPartResult object. TestPartResult(Type a_type, const char* a_file_name, int a_line_number, const char* a_message) : type_(a_type), file_name_(a_file_name == NULL ? "" : a_file_name), line_number_(a_line_number), summary_(ExtractSummary(a_message)), message_(a_message) { } // Gets the outcome of the test part. Type type() const { return type_; } // Gets the name of the source file where the test part took place, or // NULL if it's unknown. const char* file_name() const { return file_name_.empty() ? NULL : file_name_.c_str(); } // Gets the line in the source file where the test part took place, // or -1 if it's unknown. int line_number() const { return line_number_; } // Gets the summary of the failure message. const char* summary() const { return summary_.c_str(); } // Gets the message associated with the test part. const char* message() const { return message_.c_str(); } // Returns true iff the test part passed. bool passed() const { return type_ == kSuccess; } // Returns true iff the test part failed. bool failed() const { return type_ != kSuccess; } // Returns true iff the test part non-fatally failed. bool nonfatally_failed() const { return type_ == kNonFatalFailure; } // Returns true iff the test part fatally failed. bool fatally_failed() const { return type_ == kFatalFailure; } private: Type type_; // Gets the summary of the failure message by omitting the stack // trace in it. static std::string ExtractSummary(const char* message); // The name of the source file where the test part took place, or // "" if the source file is unknown. std::string file_name_; // The line in the source file where the test part took place, or -1 // if the line number is unknown. int line_number_; std::string summary_; // The test failure summary. std::string message_; // The test failure message. }; // Prints a TestPartResult object. std::ostream& operator<<(std::ostream& os, const TestPartResult& result); // An array of TestPartResult objects. // // Don't inherit from TestPartResultArray as its destructor is not // virtual. class GTEST_API_ TestPartResultArray { public: TestPartResultArray() {} // Appends the given TestPartResult to the array. void Append(const TestPartResult& result); // Returns the TestPartResult at the given index (0-based). const TestPartResult& GetTestPartResult(int index) const; // Returns the number of TestPartResult objects in the array. int size() const; private: std::vector array_; GTEST_DISALLOW_COPY_AND_ASSIGN_(TestPartResultArray); }; // This interface knows how to report a test part result. class TestPartResultReporterInterface { public: virtual ~TestPartResultReporterInterface() {} virtual void ReportTestPartResult(const TestPartResult& result) = 0; }; namespace internal { // This helper class is used by {ASSERT|EXPECT}_NO_FATAL_FAILURE to check if a // statement generates new fatal failures. To do so it registers itself as the // current test part result reporter. Besides checking if fatal failures were // reported, it only delegates the reporting to the former result reporter. // The original result reporter is restored in the destructor. // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. class GTEST_API_ HasNewFatalFailureHelper : public TestPartResultReporterInterface { public: HasNewFatalFailureHelper(); virtual ~HasNewFatalFailureHelper(); virtual void ReportTestPartResult(const TestPartResult& result); bool has_new_fatal_failure() const { return has_new_fatal_failure_; } private: bool has_new_fatal_failure_; TestPartResultReporterInterface* original_reporter_; GTEST_DISALLOW_COPY_AND_ASSIGN_(HasNewFatalFailureHelper); }; } // namespace internal } // namespace testing #endif // GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_ // Copyright 2008 Google Inc. // All Rights Reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: wan@google.com (Zhanyong Wan) #ifndef GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_ #define GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_ // This header implements typed tests and type-parameterized tests. // Typed (aka type-driven) tests repeat the same test for types in a // list. You must know which types you want to test with when writing // typed tests. Here's how you do it: #if 0 // First, define a fixture class template. It should be parameterized // by a type. Remember to derive it from testing::Test. template class FooTest : public testing::Test { public: ... typedef std::list List; static T shared_; T value_; }; // Next, associate a list of types with the test case, which will be // repeated for each type in the list. The typedef is necessary for // the macro to parse correctly. typedef testing::Types MyTypes; TYPED_TEST_CASE(FooTest, MyTypes); // If the type list contains only one type, you can write that type // directly without Types<...>: // TYPED_TEST_CASE(FooTest, int); // Then, use TYPED_TEST() instead of TEST_F() to define as many typed // tests for this test case as you want. TYPED_TEST(FooTest, DoesBlah) { // Inside a test, refer to TypeParam to get the type parameter. // Since we are inside a derived class template, C++ requires use to // visit the members of FooTest via 'this'. TypeParam n = this->value_; // To visit static members of the fixture, add the TestFixture:: // prefix. n += TestFixture::shared_; // To refer to typedefs in the fixture, add the "typename // TestFixture::" prefix. typename TestFixture::List values; values.push_back(n); ... } TYPED_TEST(FooTest, HasPropertyA) { ... } #endif // 0 // Type-parameterized tests are abstract test patterns parameterized // by a type. Compared with typed tests, type-parameterized tests // allow you to define the test pattern without knowing what the type // parameters are. The defined pattern can be instantiated with // different types any number of times, in any number of translation // units. // // If you are designing an interface or concept, you can define a // suite of type-parameterized tests to verify properties that any // valid implementation of the interface/concept should have. Then, // each implementation can easily instantiate the test suite to verify // that it conforms to the requirements, without having to write // similar tests repeatedly. Here's an example: #if 0 // First, define a fixture class template. It should be parameterized // by a type. Remember to derive it from testing::Test. template class FooTest : public testing::Test { ... }; // Next, declare that you will define a type-parameterized test case // (the _P suffix is for "parameterized" or "pattern", whichever you // prefer): TYPED_TEST_CASE_P(FooTest); // Then, use TYPED_TEST_P() to define as many type-parameterized tests // for this type-parameterized test case as you want. TYPED_TEST_P(FooTest, DoesBlah) { // Inside a test, refer to TypeParam to get the type parameter. TypeParam n = 0; ... } TYPED_TEST_P(FooTest, HasPropertyA) { ... } // Now the tricky part: you need to register all test patterns before // you can instantiate them. The first argument of the macro is the // test case name; the rest are the names of the tests in this test // case. REGISTER_TYPED_TEST_CASE_P(FooTest, DoesBlah, HasPropertyA); // Finally, you are free to instantiate the pattern with the types you // want. If you put the above code in a header file, you can #include // it in multiple C++ source files and instantiate it multiple times. // // To distinguish different instances of the pattern, the first // argument to the INSTANTIATE_* macro is a prefix that will be added // to the actual test case name. Remember to pick unique prefixes for // different instances. typedef testing::Types MyTypes; INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, MyTypes); // If the type list contains only one type, you can write that type // directly without Types<...>: // INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, int); #endif // 0 // Implements typed tests. #if GTEST_HAS_TYPED_TEST // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. // // Expands to the name of the typedef for the type parameters of the // given test case. # define GTEST_TYPE_PARAMS_(TestCaseName) gtest_type_params_##TestCaseName##_ // The 'Types' template argument below must have spaces around it // since some compilers may choke on '>>' when passing a template // instance (e.g. Types) # define TYPED_TEST_CASE(CaseName, Types) \ typedef ::testing::internal::TypeList< Types >::type \ GTEST_TYPE_PARAMS_(CaseName) # define TYPED_TEST(CaseName, TestName) \ template \ class GTEST_TEST_CLASS_NAME_(CaseName, TestName) \ : public CaseName { \ private: \ typedef CaseName TestFixture; \ typedef gtest_TypeParam_ TypeParam; \ virtual void TestBody(); \ }; \ bool gtest_##CaseName##_##TestName##_registered_ GTEST_ATTRIBUTE_UNUSED_ = \ ::testing::internal::TypeParameterizedTest< \ CaseName, \ ::testing::internal::TemplateSel< \ GTEST_TEST_CLASS_NAME_(CaseName, TestName)>, \ GTEST_TYPE_PARAMS_(CaseName)>::Register(\ "", #CaseName, #TestName, 0); \ template \ void GTEST_TEST_CLASS_NAME_(CaseName, TestName)::TestBody() #endif // GTEST_HAS_TYPED_TEST // Implements type-parameterized tests. #if GTEST_HAS_TYPED_TEST_P // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. // // Expands to the namespace name that the type-parameterized tests for // the given type-parameterized test case are defined in. The exact // name of the namespace is subject to change without notice. # define GTEST_CASE_NAMESPACE_(TestCaseName) \ gtest_case_##TestCaseName##_ // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. // // Expands to the name of the variable used to remember the names of // the defined tests in the given test case. # define GTEST_TYPED_TEST_CASE_P_STATE_(TestCaseName) \ gtest_typed_test_case_p_state_##TestCaseName##_ // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE DIRECTLY. // // Expands to the name of the variable used to remember the names of // the registered tests in the given test case. # define GTEST_REGISTERED_TEST_NAMES_(TestCaseName) \ gtest_registered_test_names_##TestCaseName##_ // The variables defined in the type-parameterized test macros are // static as typically these macros are used in a .h file that can be // #included in multiple translation units linked together. # define TYPED_TEST_CASE_P(CaseName) \ static ::testing::internal::TypedTestCasePState \ GTEST_TYPED_TEST_CASE_P_STATE_(CaseName) # define TYPED_TEST_P(CaseName, TestName) \ namespace GTEST_CASE_NAMESPACE_(CaseName) { \ template \ class TestName : public CaseName { \ private: \ typedef CaseName TestFixture; \ typedef gtest_TypeParam_ TypeParam; \ virtual void TestBody(); \ }; \ static bool gtest_##TestName##_defined_ GTEST_ATTRIBUTE_UNUSED_ = \ GTEST_TYPED_TEST_CASE_P_STATE_(CaseName).AddTestName(\ __FILE__, __LINE__, #CaseName, #TestName); \ } \ template \ void GTEST_CASE_NAMESPACE_(CaseName)::TestName::TestBody() # define REGISTER_TYPED_TEST_CASE_P(CaseName, ...) \ namespace GTEST_CASE_NAMESPACE_(CaseName) { \ typedef ::testing::internal::Templates<__VA_ARGS__>::type gtest_AllTests_; \ } \ static const char* const GTEST_REGISTERED_TEST_NAMES_(CaseName) = \ GTEST_TYPED_TEST_CASE_P_STATE_(CaseName).VerifyRegisteredTestNames(\ __FILE__, __LINE__, #__VA_ARGS__) // The 'Types' template argument below must have spaces around it // since some compilers may choke on '>>' when passing a template // instance (e.g. Types) # define INSTANTIATE_TYPED_TEST_CASE_P(Prefix, CaseName, Types) \ bool gtest_##Prefix##_##CaseName GTEST_ATTRIBUTE_UNUSED_ = \ ::testing::internal::TypeParameterizedTestCase::type>::Register(\ #Prefix, #CaseName, GTEST_REGISTERED_TEST_NAMES_(CaseName)) #endif // GTEST_HAS_TYPED_TEST_P #endif // GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_ // Depending on the platform, different string classes are available. // On Linux, in addition to ::std::string, Google also makes use of // class ::string, which has the same interface as ::std::string, but // has a different implementation. // // The user can define GTEST_HAS_GLOBAL_STRING to 1 to indicate that // ::string is available AND is a distinct type to ::std::string, or // define it to 0 to indicate otherwise. // // If the user's ::std::string and ::string are the same class due to // aliasing, he should define GTEST_HAS_GLOBAL_STRING to 0. // // If the user doesn't define GTEST_HAS_GLOBAL_STRING, it is defined // heuristically. namespace testing { // Declares the flags. // This flag temporary enables the disabled tests. GTEST_DECLARE_bool_(also_run_disabled_tests); // This flag brings the debugger on an assertion failure. GTEST_DECLARE_bool_(break_on_failure); // This flag controls whether Google Test catches all test-thrown exceptions // and logs them as failures. GTEST_DECLARE_bool_(catch_exceptions); // This flag enables using colors in terminal output. Available values are // "yes" to enable colors, "no" (disable colors), or "auto" (the default) // to let Google Test decide. GTEST_DECLARE_string_(color); // This flag sets up the filter to select by name using a glob pattern // the tests to run. If the filter is not given all tests are executed. GTEST_DECLARE_string_(filter); // This flag causes the Google Test to list tests. None of the tests listed // are actually run if the flag is provided. GTEST_DECLARE_bool_(list_tests); // This flag controls whether Google Test emits a detailed XML report to a file // in addition to its normal textual output. GTEST_DECLARE_string_(output); // This flags control whether Google Test prints the elapsed time for each // test. GTEST_DECLARE_bool_(print_time); // This flag specifies the random number seed. GTEST_DECLARE_int32_(random_seed); // This flag sets how many times the tests are repeated. The default value // is 1. If the value is -1 the tests are repeating forever. GTEST_DECLARE_int32_(repeat); // This flag controls whether Google Test includes Google Test internal // stack frames in failure stack traces. GTEST_DECLARE_bool_(show_internal_stack_frames); // When this flag is specified, tests' order is randomized on every iteration. GTEST_DECLARE_bool_(shuffle); // This flag specifies the maximum number of stack frames to be // printed in a failure message. GTEST_DECLARE_int32_(stack_trace_depth); // When this flag is specified, a failed assertion will throw an // exception if exceptions are enabled, or exit the program with a // non-zero code otherwise. GTEST_DECLARE_bool_(throw_on_failure); // When this flag is set with a "host:port" string, on supported // platforms test results are streamed to the specified port on // the specified host machine. GTEST_DECLARE_string_(stream_result_to); // The upper limit for valid stack trace depths. const int kMaxStackTraceDepth = 100; namespace internal { class AssertHelper; class DefaultGlobalTestPartResultReporter; class ExecDeathTest; class NoExecDeathTest; class FinalSuccessChecker; class GTestFlagSaver; class StreamingListenerTest; class TestResultAccessor; class TestEventListenersAccessor; class TestEventRepeater; class UnitTestRecordPropertyTestHelper; class WindowsDeathTest; class UnitTestImpl* GetUnitTestImpl(); void ReportFailureInUnknownLocation(TestPartResult::Type result_type, const std::string& message); } // namespace internal // The friend relationship of some of these classes is cyclic. // If we don't forward declare them the compiler might confuse the classes // in friendship clauses with same named classes on the scope. class Test; class TestCase; class TestInfo; class UnitTest; // A class for indicating whether an assertion was successful. When // the assertion wasn't successful, the AssertionResult object // remembers a non-empty message that describes how it failed. // // To create an instance of this class, use one of the factory functions // (AssertionSuccess() and AssertionFailure()). // // This class is useful for two purposes: // 1. Defining predicate functions to be used with Boolean test assertions // EXPECT_TRUE/EXPECT_FALSE and their ASSERT_ counterparts // 2. Defining predicate-format functions to be // used with predicate assertions (ASSERT_PRED_FORMAT*, etc). // // For example, if you define IsEven predicate: // // testing::AssertionResult IsEven(int n) { // if ((n % 2) == 0) // return testing::AssertionSuccess(); // else // return testing::AssertionFailure() << n << " is odd"; // } // // Then the failed expectation EXPECT_TRUE(IsEven(Fib(5))) // will print the message // // Value of: IsEven(Fib(5)) // Actual: false (5 is odd) // Expected: true // // instead of a more opaque // // Value of: IsEven(Fib(5)) // Actual: false // Expected: true // // in case IsEven is a simple Boolean predicate. // // If you expect your predicate to be reused and want to support informative // messages in EXPECT_FALSE and ASSERT_FALSE (negative assertions show up // about half as often as positive ones in our tests), supply messages for // both success and failure cases: // // testing::AssertionResult IsEven(int n) { // if ((n % 2) == 0) // return testing::AssertionSuccess() << n << " is even"; // else // return testing::AssertionFailure() << n << " is odd"; // } // // Then a statement EXPECT_FALSE(IsEven(Fib(6))) will print // // Value of: IsEven(Fib(6)) // Actual: true (8 is even) // Expected: false // // NB: Predicates that support negative Boolean assertions have reduced // performance in positive ones so be careful not to use them in tests // that have lots (tens of thousands) of positive Boolean assertions. // // To use this class with EXPECT_PRED_FORMAT assertions such as: // // // Verifies that Foo() returns an even number. // EXPECT_PRED_FORMAT1(IsEven, Foo()); // // you need to define: // // testing::AssertionResult IsEven(const char* expr, int n) { // if ((n % 2) == 0) // return testing::AssertionSuccess(); // else // return testing::AssertionFailure() // << "Expected: " << expr << " is even\n Actual: it's " << n; // } // // If Foo() returns 5, you will see the following message: // // Expected: Foo() is even // Actual: it's 5 // class GTEST_API_ AssertionResult { public: // Copy constructor. // Used in EXPECT_TRUE/FALSE(assertion_result). AssertionResult(const AssertionResult& other); // Used in the EXPECT_TRUE/FALSE(bool_expression). explicit AssertionResult(bool success) : success_(success) {} // Returns true iff the assertion succeeded. operator bool() const { return success_; } // NOLINT // Returns the assertion's negation. Used with EXPECT/ASSERT_FALSE. AssertionResult operator!() const; // Returns the text streamed into this AssertionResult. Test assertions // use it when they fail (i.e., the predicate's outcome doesn't match the // assertion's expectation). When nothing has been streamed into the // object, returns an empty string. const char* message() const { return message_.get() != NULL ? message_->c_str() : ""; } // TODO(vladl@google.com): Remove this after making sure no clients use it. // Deprecated; please use message() instead. const char* failure_message() const { return message(); } // Streams a custom failure message into this object. template AssertionResult& operator<<(const T& value) { AppendMessage(Message() << value); return *this; } // Allows streaming basic output manipulators such as endl or flush into // this object. AssertionResult& operator<<( ::std::ostream& (*basic_manipulator)(::std::ostream& stream)) { AppendMessage(Message() << basic_manipulator); return *this; } private: // Appends the contents of message to message_. void AppendMessage(const Message& a_message) { if (message_.get() == NULL) message_.reset(new ::std::string); message_->append(a_message.GetString().c_str()); } // Stores result of the assertion predicate. bool success_; // Stores the message describing the condition in case the expectation // construct is not satisfied with the predicate's outcome. // Referenced via a pointer to avoid taking too much stack frame space // with test assertions. internal::scoped_ptr< ::std::string> message_; GTEST_DISALLOW_ASSIGN_(AssertionResult); }; // Makes a successful assertion result. GTEST_API_ AssertionResult AssertionSuccess(); // Makes a failed assertion result. GTEST_API_ AssertionResult AssertionFailure(); // Makes a failed assertion result with the given failure message. // Deprecated; use AssertionFailure() << msg. GTEST_API_ AssertionResult AssertionFailure(const Message& msg); // The abstract class that all tests inherit from. // // In Google Test, a unit test program contains one or many TestCases, and // each TestCase contains one or many Tests. // // When you define a test using the TEST macro, you don't need to // explicitly derive from Test - the TEST macro automatically does // this for you. // // The only time you derive from Test is when defining a test fixture // to be used a TEST_F. For example: // // class FooTest : public testing::Test { // protected: // virtual void SetUp() { ... } // virtual void TearDown() { ... } // ... // }; // // TEST_F(FooTest, Bar) { ... } // TEST_F(FooTest, Baz) { ... } // // Test is not copyable. class GTEST_API_ Test { public: friend class TestInfo; // Defines types for pointers to functions that set up and tear down // a test case. typedef internal::SetUpTestCaseFunc SetUpTestCaseFunc; typedef internal::TearDownTestCaseFunc TearDownTestCaseFunc; // The d'tor is virtual as we intend to inherit from Test. virtual ~Test(); // Sets up the stuff shared by all tests in this test case. // // Google Test will call Foo::SetUpTestCase() before running the first // test in test case Foo. Hence a sub-class can define its own // SetUpTestCase() method to shadow the one defined in the super // class. static void SetUpTestCase() {} // Tears down the stuff shared by all tests in this test case. // // Google Test will call Foo::TearDownTestCase() after running the last // test in test case Foo. Hence a sub-class can define its own // TearDownTestCase() method to shadow the one defined in the super // class. static void TearDownTestCase() {} // Returns true iff the current test has a fatal failure. static bool HasFatalFailure(); // Returns true iff the current test has a non-fatal failure. static bool HasNonfatalFailure(); // Returns true iff the current test has a (either fatal or // non-fatal) failure. static bool HasFailure() { return HasFatalFailure() || HasNonfatalFailure(); } // Logs a property for the current test, test case, or for the entire // invocation of the test program when used outside of the context of a // test case. Only the last value for a given key is remembered. These // are public static so they can be called from utility functions that are // not members of the test fixture. Calls to RecordProperty made during // lifespan of the test (from the moment its constructor starts to the // moment its destructor finishes) will be output in XML as attributes of // the element. Properties recorded from fixture's // SetUpTestCase or TearDownTestCase are logged as attributes of the // corresponding element. Calls to RecordProperty made in the // global context (before or after invocation of RUN_ALL_TESTS and from // SetUp/TearDown method of Environment objects registered with Google // Test) will be output as attributes of the element. static void RecordProperty(const std::string& key, const std::string& value); static void RecordProperty(const std::string& key, int value); protected: // Creates a Test object. Test(); // Sets up the test fixture. virtual void SetUp(); // Tears down the test fixture. virtual void TearDown(); private: // Returns true iff the current test has the same fixture class as // the first test in the current test case. static bool HasSameFixtureClass(); // Runs the test after the test fixture has been set up. // // A sub-class must implement this to define the test logic. // // DO NOT OVERRIDE THIS FUNCTION DIRECTLY IN A USER PROGRAM. // Instead, use the TEST or TEST_F macro. virtual void TestBody() = 0; // Sets up, executes, and tears down the test. void Run(); // Deletes self. We deliberately pick an unusual name for this // internal method to avoid clashing with names used in user TESTs. void DeleteSelf_() { delete this; } // Uses a GTestFlagSaver to save and restore all Google Test flags. const internal::GTestFlagSaver* const gtest_flag_saver_; // Often a user mis-spells SetUp() as Setup() and spends a long time // wondering why it is never called by Google Test. The declaration of // the following method is solely for catching such an error at // compile time: // // - The return type is deliberately chosen to be not void, so it // will be a conflict if a user declares void Setup() in his test // fixture. // // - This method is private, so it will be another compiler error // if a user calls it from his test fixture. // // DO NOT OVERRIDE THIS FUNCTION. // // If you see an error about overriding the following function or // about it being private, you have mis-spelled SetUp() as Setup(). struct Setup_should_be_spelled_SetUp {}; virtual Setup_should_be_spelled_SetUp* Setup() { return NULL; } // We disallow copying Tests. GTEST_DISALLOW_COPY_AND_ASSIGN_(Test); }; typedef internal::TimeInMillis TimeInMillis; // A copyable object representing a user specified test property which can be // output as a key/value string pair. // // Don't inherit from TestProperty as its destructor is not virtual. class TestProperty { public: // C'tor. TestProperty does NOT have a default constructor. // Always use this constructor (with parameters) to create a // TestProperty object. TestProperty(const std::string& a_key, const std::string& a_value) : key_(a_key), value_(a_value) { } // Gets the user supplied key. const char* key() const { return key_.c_str(); } // Gets the user supplied value. const char* value() const { return value_.c_str(); } // Sets a new value, overriding the one supplied in the constructor. void SetValue(const std::string& new_value) { value_ = new_value; } private: // The key supplied by the user. std::string key_; // The value supplied by the user. std::string value_; }; // The result of a single Test. This includes a list of // TestPartResults, a list of TestProperties, a count of how many // death tests there are in the Test, and how much time it took to run // the Test. // // TestResult is not copyable. class GTEST_API_ TestResult { public: // Creates an empty TestResult. TestResult(); // D'tor. Do not inherit from TestResult. ~TestResult(); // Gets the number of all test parts. This is the sum of the number // of successful test parts and the number of failed test parts. int total_part_count() const; // Returns the number of the test properties. int test_property_count() const; // Returns true iff the test passed (i.e. no test part failed). bool Passed() const { return !Failed(); } // Returns true iff the test failed. bool Failed() const; // Returns true iff the test fatally failed. bool HasFatalFailure() const; // Returns true iff the test has a non-fatal failure. bool HasNonfatalFailure() const; // Returns the elapsed time, in milliseconds. TimeInMillis elapsed_time() const { return elapsed_time_; } // Returns the i-th test part result among all the results. i can range // from 0 to test_property_count() - 1. If i is not in that range, aborts // the program. const TestPartResult& GetTestPartResult(int i) const; // Returns the i-th test property. i can range from 0 to // test_property_count() - 1. If i is not in that range, aborts the // program. const TestProperty& GetTestProperty(int i) const; private: friend class TestInfo; friend class TestCase; friend class UnitTest; friend class internal::DefaultGlobalTestPartResultReporter; friend class internal::ExecDeathTest; friend class internal::TestResultAccessor; friend class internal::UnitTestImpl; friend class internal::WindowsDeathTest; // Gets the vector of TestPartResults. const std::vector& test_part_results() const { return test_part_results_; } // Gets the vector of TestProperties. const std::vector& test_properties() const { return test_properties_; } // Sets the elapsed time. void set_elapsed_time(TimeInMillis elapsed) { elapsed_time_ = elapsed; } // Adds a test property to the list. The property is validated and may add // a non-fatal failure if invalid (e.g., if it conflicts with reserved // key names). If a property is already recorded for the same key, the // value will be updated, rather than storing multiple values for the same // key. xml_element specifies the element for which the property is being // recorded and is used for validation. void RecordProperty(const std::string& xml_element, const TestProperty& test_property); // Adds a failure if the key is a reserved attribute of Google Test // testcase tags. Returns true if the property is valid. // TODO(russr): Validate attribute names are legal and human readable. static bool ValidateTestProperty(const std::string& xml_element, const TestProperty& test_property); // Adds a test part result to the list. void AddTestPartResult(const TestPartResult& test_part_result); // Returns the death test count. int death_test_count() const { return death_test_count_; } // Increments the death test count, returning the new count. int increment_death_test_count() { return ++death_test_count_; } // Clears the test part results. void ClearTestPartResults(); // Clears the object. void Clear(); // Protects mutable state of the property vector and of owned // properties, whose values may be updated. internal::Mutex test_properites_mutex_; // The vector of TestPartResults std::vector test_part_results_; // The vector of TestProperties std::vector test_properties_; // Running count of death tests. int death_test_count_; // The elapsed time, in milliseconds. TimeInMillis elapsed_time_; // We disallow copying TestResult. GTEST_DISALLOW_COPY_AND_ASSIGN_(TestResult); }; // class TestResult // A TestInfo object stores the following information about a test: // // Test case name // Test name // Whether the test should be run // A function pointer that creates the test object when invoked // Test result // // The constructor of TestInfo registers itself with the UnitTest // singleton such that the RUN_ALL_TESTS() macro knows which tests to // run. class GTEST_API_ TestInfo { public: // Destructs a TestInfo object. This function is not virtual, so // don't inherit from TestInfo. ~TestInfo(); // Returns the test case name. const char* test_case_name() const { return test_case_name_.c_str(); } // Returns the test name. const char* name() const { return name_.c_str(); } // Returns the name of the parameter type, or NULL if this is not a typed // or a type-parameterized test. const char* type_param() const { if (type_param_.get() != NULL) return type_param_->c_str(); return NULL; } // Returns the text representation of the value parameter, or NULL if this // is not a value-parameterized test. const char* value_param() const { if (value_param_.get() != NULL) return value_param_->c_str(); return NULL; } // Returns true if this test should run, that is if the test is not // disabled (or it is disabled but the also_run_disabled_tests flag has // been specified) and its full name matches the user-specified filter. // // Google Test allows the user to filter the tests by their full names. // The full name of a test Bar in test case Foo is defined as // "Foo.Bar". Only the tests that match the filter will run. // // A filter is a colon-separated list of glob (not regex) patterns, // optionally followed by a '-' and a colon-separated list of // negative patterns (tests to exclude). A test is run if it // matches one of the positive patterns and does not match any of // the negative patterns. // // For example, *A*:Foo.* is a filter that matches any string that // contains the character 'A' or starts with "Foo.". bool should_run() const { return should_run_; } // Returns true iff this test will appear in the XML report. bool is_reportable() const { // For now, the XML report includes all tests matching the filter. // In the future, we may trim tests that are excluded because of // sharding. return matches_filter_; } // Returns the result of the test. const TestResult* result() const { return &result_; } private: #if GTEST_HAS_DEATH_TEST friend class internal::DefaultDeathTestFactory; #endif // GTEST_HAS_DEATH_TEST friend class Test; friend class TestCase; friend class internal::UnitTestImpl; friend class internal::StreamingListenerTest; friend TestInfo* internal::MakeAndRegisterTestInfo( const char* test_case_name, const char* name, const char* type_param, const char* value_param, internal::TypeId fixture_class_id, Test::SetUpTestCaseFunc set_up_tc, Test::TearDownTestCaseFunc tear_down_tc, internal::TestFactoryBase* factory); // Constructs a TestInfo object. The newly constructed instance assumes // ownership of the factory object. TestInfo(const std::string& test_case_name, 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::TypeId fixture_class_id, internal::TestFactoryBase* factory); // Increments the number of death tests encountered in this test so // far. int increment_death_test_count() { return result_.increment_death_test_count(); } // Creates the test object, runs it, records its result, and then // deletes it. void Run(); static void ClearTestResult(TestInfo* test_info) { test_info->result_.Clear(); } // These fields are immutable properties of the test. const std::string test_case_name_; // Test case name const std::string name_; // Test name // Name of the parameter type, or NULL if this is not a typed or a // type-parameterized test. const internal::scoped_ptr type_param_; // Text representation of the value parameter, or NULL if this is not a // value-parameterized test. const internal::scoped_ptr value_param_; const internal::TypeId fixture_class_id_; // ID of the test fixture class bool should_run_; // True iff this test should run bool is_disabled_; // True iff this test is disabled bool matches_filter_; // True if this test matches the // user-specified filter. internal::TestFactoryBase* const factory_; // The factory that creates // the test object // This field is mutable and needs to be reset before running the // test for the second time. TestResult result_; GTEST_DISALLOW_COPY_AND_ASSIGN_(TestInfo); }; // A test case, which consists of a vector of TestInfos. // // TestCase is not copyable. class GTEST_API_ TestCase { public: // Creates a TestCase with the given name. // // TestCase does NOT have a default constructor. Always use this // constructor to create a TestCase object. // // Arguments: // // name: name of the test case // a_type_param: the name of the test's type parameter, or NULL if // this is not a type-parameterized test. // set_up_tc: pointer to the function that sets up the test case // tear_down_tc: pointer to the function that tears down the test case TestCase(const char* name, const char* a_type_param, Test::SetUpTestCaseFunc set_up_tc, Test::TearDownTestCaseFunc tear_down_tc); // Destructor of TestCase. virtual ~TestCase(); // Gets the name of the TestCase. const char* name() const { return name_.c_str(); } // Returns the name of the parameter type, or NULL if this is not a // type-parameterized test case. const char* type_param() const { if (type_param_.get() != NULL) return type_param_->c_str(); return NULL; } // Returns true if any test in this test case should run. bool should_run() const { return should_run_; } // Gets the number of successful tests in this test case. int successful_test_count() const; // Gets the number of failed tests in this test case. int failed_test_count() const; // Gets the number of disabled tests that will be reported in the XML report. int reportable_disabled_test_count() const; // Gets the number of disabled tests in this test case. int disabled_test_count() const; // Gets the number of tests to be printed in the XML report. int reportable_test_count() const; // Get the number of tests in this test case that should run. int test_to_run_count() const; // Gets the number of all tests in this test case. int total_test_count() const; // Returns true iff the test case passed. bool Passed() const { return !Failed(); } // Returns true iff the test case failed. bool Failed() const { return failed_test_count() > 0; } // Returns the elapsed time, in milliseconds. TimeInMillis elapsed_time() const { return elapsed_time_; } // Returns the i-th test among all the tests. i can range from 0 to // total_test_count() - 1. If i is not in that range, returns NULL. const TestInfo* GetTestInfo(int i) const; // Returns the TestResult that holds test properties recorded during // execution of SetUpTestCase and TearDownTestCase. const TestResult& ad_hoc_test_result() const { return ad_hoc_test_result_; } private: friend class Test; friend class internal::UnitTestImpl; // Gets the (mutable) vector of TestInfos in this TestCase. std::vector& test_info_list() { return test_info_list_; } // Gets the (immutable) vector of TestInfos in this TestCase. const std::vector& test_info_list() const { return test_info_list_; } // Returns the i-th test among all the tests. i can range from 0 to // total_test_count() - 1. If i is not in that range, returns NULL. TestInfo* GetMutableTestInfo(int i); // Sets the should_run member. void set_should_run(bool should) { should_run_ = should; } // Adds a TestInfo to this test case. Will delete the TestInfo upon // destruction of the TestCase object. void AddTestInfo(TestInfo * test_info); // Clears the results of all tests in this test case. void ClearResult(); // Clears the results of all tests in the given test case. static void ClearTestCaseResult(TestCase* test_case) { test_case->ClearResult(); } // Runs every test in this TestCase. void Run(); // Runs SetUpTestCase() for this TestCase. This wrapper is needed // for catching exceptions thrown from SetUpTestCase(). void RunSetUpTestCase() { (*set_up_tc_)(); } // Runs TearDownTestCase() for this TestCase. This wrapper is // needed for catching exceptions thrown from TearDownTestCase(). void RunTearDownTestCase() { (*tear_down_tc_)(); } // Returns true iff test passed. static bool TestPassed(const TestInfo* test_info) { return test_info->should_run() && test_info->result()->Passed(); } // Returns true iff test failed. static bool TestFailed(const TestInfo* test_info) { return test_info->should_run() && test_info->result()->Failed(); } // Returns true iff the test is disabled and will be reported in the XML // report. static bool TestReportableDisabled(const TestInfo* test_info) { return test_info->is_reportable() && test_info->is_disabled_; } // Returns true iff test is disabled. static bool TestDisabled(const TestInfo* test_info) { return test_info->is_disabled_; } // Returns true iff this test will appear in the XML report. static bool TestReportable(const TestInfo* test_info) { return test_info->is_reportable(); } // Returns true if the given test should run. static bool ShouldRunTest(const TestInfo* test_info) { return test_info->should_run(); } // Shuffles the tests in this test case. void ShuffleTests(internal::Random* random); // Restores the test order to before the first shuffle. void UnshuffleTests(); // Name of the test case. std::string name_; // Name of the parameter type, or NULL if this is not a typed or a // type-parameterized test. const internal::scoped_ptr type_param_; // The vector of TestInfos in their original order. It owns the // elements in the vector. std::vector test_info_list_; // Provides a level of indirection for the test list to allow easy // shuffling and restoring the test order. The i-th element in this // vector is the index of the i-th test in the shuffled test list. std::vector test_indices_; // Pointer to the function that sets up the test case. Test::SetUpTestCaseFunc set_up_tc_; // Pointer to the function that tears down the test case. Test::TearDownTestCaseFunc tear_down_tc_; // True iff any test in this test case should run. bool should_run_; // Elapsed time, in milliseconds. TimeInMillis elapsed_time_; // Holds test properties recorded during execution of SetUpTestCase and // TearDownTestCase. TestResult ad_hoc_test_result_; // We disallow copying TestCases. GTEST_DISALLOW_COPY_AND_ASSIGN_(TestCase); }; // An Environment object is capable of setting up and tearing down an // environment. The user should subclass this to define his own // environment(s). // // An Environment object does the set-up and tear-down in virtual // methods SetUp() and TearDown() instead of the constructor and the // destructor, as: // // 1. You cannot safely throw from a destructor. This is a problem // as in some cases Google Test is used where exceptions are enabled, and // we may want to implement ASSERT_* using exceptions where they are // available. // 2. You cannot use ASSERT_* directly in a constructor or // destructor. class Environment { public: // The d'tor is virtual as we need to subclass Environment. virtual ~Environment() {} // Override this to define how to set up the environment. virtual void SetUp() {} // Override this to define how to tear down the environment. virtual void TearDown() {} private: // If you see an error about overriding the following function or // about it being private, you have mis-spelled SetUp() as Setup(). struct Setup_should_be_spelled_SetUp {}; virtual Setup_should_be_spelled_SetUp* Setup() { return NULL; } }; // The interface for tracing execution of tests. The methods are organized in // the order the corresponding events are fired. class TestEventListener { public: virtual ~TestEventListener() {} // Fired before any test activity starts. virtual void OnTestProgramStart(const UnitTest& unit_test) = 0; // Fired before each iteration of tests starts. There may be more than // one iteration if GTEST_FLAG(repeat) is set. iteration is the iteration // index, starting from 0. virtual void OnTestIterationStart(const UnitTest& unit_test, int iteration) = 0; // Fired before environment set-up for each iteration of tests starts. virtual void OnEnvironmentsSetUpStart(const UnitTest& unit_test) = 0; // Fired after environment set-up for each iteration of tests ends. virtual void OnEnvironmentsSetUpEnd(const UnitTest& unit_test) = 0; // Fired before the test case starts. virtual void OnTestCaseStart(const TestCase& test_case) = 0; // Fired before the test starts. virtual void OnTestStart(const TestInfo& test_info) = 0; // Fired after a failed assertion or a SUCCEED() invocation. virtual void OnTestPartResult(const TestPartResult& test_part_result) = 0; // Fired after the test ends. virtual void OnTestEnd(const TestInfo& test_info) = 0; // Fired after the test case ends. virtual void OnTestCaseEnd(const TestCase& test_case) = 0; // Fired before environment tear-down for each iteration of tests starts. virtual void OnEnvironmentsTearDownStart(const UnitTest& unit_test) = 0; // Fired after environment tear-down for each iteration of tests ends. virtual void OnEnvironmentsTearDownEnd(const UnitTest& unit_test) = 0; // Fired after each iteration of tests finishes. virtual void OnTestIterationEnd(const UnitTest& unit_test, int iteration) = 0; // Fired after all test activities have ended. virtual void OnTestProgramEnd(const UnitTest& unit_test) = 0; }; // The convenience class for users who need to override just one or two // methods and are not concerned that a possible change to a signature of // the methods they override will not be caught during the build. For // comments about each method please see the definition of TestEventListener // above. class EmptyTestEventListener : public TestEventListener { public: virtual void OnTestProgramStart(const UnitTest& /*unit_test*/) {} virtual void OnTestIterationStart(const UnitTest& /*unit_test*/, int /*iteration*/) {} virtual void OnEnvironmentsSetUpStart(const UnitTest& /*unit_test*/) {} virtual void OnEnvironmentsSetUpEnd(const UnitTest& /*unit_test*/) {} virtual void OnTestCaseStart(const TestCase& /*test_case*/) {} virtual void OnTestStart(const TestInfo& /*test_info*/) {} virtual void OnTestPartResult(const TestPartResult& /*test_part_result*/) {} virtual void OnTestEnd(const TestInfo& /*test_info*/) {} virtual void OnTestCaseEnd(const TestCase& /*test_case*/) {} virtual void OnEnvironmentsTearDownStart(const UnitTest& /*unit_test*/) {} virtual void OnEnvironmentsTearDownEnd(const UnitTest& /*unit_test*/) {} virtual void OnTestIterationEnd(const UnitTest& /*unit_test*/, int /*iteration*/) {} virtual void OnTestProgramEnd(const UnitTest& /*unit_test*/) {} }; // TestEventListeners lets users add listeners to track events in Google Test. class GTEST_API_ TestEventListeners { public: TestEventListeners(); ~TestEventListeners(); // Appends an event listener to the end of the list. Google Test assumes // the ownership of the listener (i.e. it will delete the listener when // the test program finishes). void Append(TestEventListener* listener); // Removes the given event listener from the list and returns it. It then // becomes the caller's responsibility to delete the listener. Returns // NULL if the listener is not found in the list. TestEventListener* Release(TestEventListener* listener); // Returns the standard listener responsible for the default console // output. Can be removed from the listeners list to shut down default // console output. Note that removing this object from the listener list // with Release transfers its ownership to the caller and makes this // function return NULL the next time. TestEventListener* default_result_printer() const { return default_result_printer_; } // Returns the standard listener responsible for the default XML output // controlled by the --gtest_output=xml flag. Can be removed from the // listeners list by users who want to shut down the default XML output // controlled by this flag and substitute it with custom one. Note that // removing this object from the listener list with Release transfers its // ownership to the caller and makes this function return NULL the next // time. TestEventListener* default_xml_generator() const { return default_xml_generator_; } private: friend class TestCase; friend class TestInfo; friend class internal::DefaultGlobalTestPartResultReporter; friend class internal::NoExecDeathTest; friend class internal::TestEventListenersAccessor; friend class internal::UnitTestImpl; // Returns repeater that broadcasts the TestEventListener events to all // subscribers. TestEventListener* repeater(); // Sets the default_result_printer attribute to the provided listener. // The listener is also added to the listener list and previous // default_result_printer is removed from it and deleted. The listener can // also be NULL in which case it will not be added to the list. Does // nothing if the previous and the current listener objects are the same. void SetDefaultResultPrinter(TestEventListener* listener); // Sets the default_xml_generator attribute to the provided listener. The // listener is also added to the listener list and previous // default_xml_generator is removed from it and deleted. The listener can // also be NULL in which case it will not be added to the list. Does // nothing if the previous and the current listener objects are the same. void SetDefaultXmlGenerator(TestEventListener* listener); // Controls whether events will be forwarded by the repeater to the // listeners in the list. bool EventForwardingEnabled() const; void SuppressEventForwarding(); // The actual list of listeners. internal::TestEventRepeater* repeater_; // Listener responsible for the standard result output. TestEventListener* default_result_printer_; // Listener responsible for the creation of the XML output file. TestEventListener* default_xml_generator_; // We disallow copying TestEventListeners. GTEST_DISALLOW_COPY_AND_ASSIGN_(TestEventListeners); }; // A UnitTest consists of a vector of TestCases. // // This is a singleton class. The only instance of UnitTest is // created when UnitTest::GetInstance() is first called. This // instance is never deleted. // // UnitTest is not copyable. // // This class is thread-safe as long as the methods are called // according to their specification. class GTEST_API_ UnitTest { public: // Gets the singleton UnitTest object. The first time this method // is called, a UnitTest object is constructed and returned. // Consecutive calls will return the same object. static UnitTest* GetInstance(); // Runs all tests in this UnitTest object and prints the result. // Returns 0 if successful, or 1 otherwise. // // This method can only be called from the main thread. // // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. int Run() GTEST_MUST_USE_RESULT_; // Returns the working directory when the first TEST() or TEST_F() // was executed. The UnitTest object owns the string. const char* original_working_dir() const; // Returns the TestCase object for the test that's currently running, // or NULL if no test is running. const TestCase* current_test_case() const GTEST_LOCK_EXCLUDED_(mutex_); // Returns the TestInfo object for the test that's currently running, // or NULL if no test is running. const TestInfo* current_test_info() const GTEST_LOCK_EXCLUDED_(mutex_); // Returns the random seed used at the start of the current test run. int random_seed() const; #if GTEST_HAS_PARAM_TEST // Returns the ParameterizedTestCaseRegistry object used to keep track of // value-parameterized tests and instantiate and register them. // // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. internal::ParameterizedTestCaseRegistry& parameterized_test_registry() GTEST_LOCK_EXCLUDED_(mutex_); #endif // GTEST_HAS_PARAM_TEST // Gets the number of successful test cases. int successful_test_case_count() const; // Gets the number of failed test cases. int failed_test_case_count() const; // Gets the number of all test cases. int total_test_case_count() const; // Gets the number of all test cases that contain at least one test // that should run. int test_case_to_run_count() const; // Gets the number of successful tests. int successful_test_count() const; // Gets the number of failed tests. int failed_test_count() const; // Gets the number of disabled tests that will be reported in the XML report. int reportable_disabled_test_count() const; // Gets the number of disabled tests. int disabled_test_count() const; // Gets the number of tests to be printed in the XML report. int reportable_test_count() const; // Gets the number of all tests. int total_test_count() const; // Gets the number of tests that should run. int test_to_run_count() const; // Gets the time of the test program start, in ms from the start of the // UNIX epoch. TimeInMillis start_timestamp() const; // Gets the elapsed time, in milliseconds. TimeInMillis elapsed_time() const; // Returns true iff the unit test passed (i.e. all test cases passed). bool Passed() const; // Returns true iff the unit test failed (i.e. some test case failed // or something outside of all tests failed). bool Failed() const; // Gets the i-th test case among all the test cases. i can range from 0 to // total_test_case_count() - 1. If i is not in that range, returns NULL. const TestCase* GetTestCase(int i) const; // Returns the TestResult containing information on test failures and // properties logged outside of individual test cases. const TestResult& ad_hoc_test_result() const; // Returns the list of event listeners that can be used to track events // inside Google Test. TestEventListeners& listeners(); private: // Registers and returns a global test environment. When a test // program is run, all global test environments will be set-up in // the order they were registered. After all tests in the program // have finished, all global test environments will be torn-down in // the *reverse* order they were registered. // // The UnitTest object takes ownership of the given environment. // // This method can only be called from the main thread. Environment* AddEnvironment(Environment* env); // Adds a TestPartResult to the current TestResult object. All // Google Test assertion macros (e.g. ASSERT_TRUE, EXPECT_EQ, etc) // eventually call this to report their results. The user code // should use the assertion macros instead of calling this directly. void AddTestPartResult(TestPartResult::Type result_type, const char* file_name, int line_number, const std::string& message, const std::string& os_stack_trace) GTEST_LOCK_EXCLUDED_(mutex_); // Adds a TestProperty to the current TestResult object when invoked from // inside a test, to current TestCase's ad_hoc_test_result_ when invoked // from SetUpTestCase or TearDownTestCase, or to the global property set // when invoked elsewhere. If the result already contains a property with // the same key, the value will be updated. void RecordProperty(const std::string& key, const std::string& value); // Gets the i-th test case among all the test cases. i can range from 0 to // total_test_case_count() - 1. If i is not in that range, returns NULL. TestCase* GetMutableTestCase(int i); // Accessors for the implementation object. internal::UnitTestImpl* impl() { return impl_; } const internal::UnitTestImpl* impl() const { return impl_; } // These classes and funcions are friends as they need to access private // members of UnitTest. friend class Test; friend class internal::AssertHelper; friend class internal::ScopedTrace; friend class internal::StreamingListenerTest; friend class internal::UnitTestRecordPropertyTestHelper; friend Environment* AddGlobalTestEnvironment(Environment* env); friend internal::UnitTestImpl* internal::GetUnitTestImpl(); friend void internal::ReportFailureInUnknownLocation( TestPartResult::Type result_type, const std::string& message); // Creates an empty UnitTest. UnitTest(); // D'tor virtual ~UnitTest(); // Pushes a trace defined by SCOPED_TRACE() on to the per-thread // Google Test trace stack. void PushGTestTrace(const internal::TraceInfo& trace) GTEST_LOCK_EXCLUDED_(mutex_); // Pops a trace from the per-thread Google Test trace stack. void PopGTestTrace() GTEST_LOCK_EXCLUDED_(mutex_); // Protects mutable state in *impl_. This is mutable as some const // methods need to lock it too. mutable internal::Mutex mutex_; // Opaque implementation object. This field is never changed once // the object is constructed. We don't mark it as const here, as // doing so will cause a warning in the constructor of UnitTest. // Mutable state in *impl_ is protected by mutex_. internal::UnitTestImpl* impl_; // We disallow copying UnitTest. GTEST_DISALLOW_COPY_AND_ASSIGN_(UnitTest); }; // A convenient wrapper for adding an environment for the test // program. // // You should call this before RUN_ALL_TESTS() is called, probably in // main(). If you use gtest_main, you need to call this before main() // starts for it to take effect. For example, you can define a global // variable like this: // // testing::Environment* const foo_env = // testing::AddGlobalTestEnvironment(new FooEnvironment); // // However, we strongly recommend you to write your own main() and // call AddGlobalTestEnvironment() there, as relying on initialization // of global variables makes the code harder to read and may cause // problems when you register multiple environments from different // translation units and the environments have dependencies among them // (remember that the compiler doesn't guarantee the order in which // global variables from different translation units are initialized). inline Environment* AddGlobalTestEnvironment(Environment* env) { return UnitTest::GetInstance()->AddEnvironment(env); } // Initializes Google Test. This must be called before calling // RUN_ALL_TESTS(). In particular, it parses a command line for the // flags that Google Test recognizes. Whenever a Google Test flag is // seen, it is removed from argv, and *argc is decremented. // // No value is returned. Instead, the Google Test flag variables are // updated. // // Calling the function for the second time has no user-visible effect. GTEST_API_ void InitGoogleTest(int* argc, char** argv); // This overloaded version can be used in Windows programs compiled in // UNICODE mode. GTEST_API_ void InitGoogleTest(int* argc, wchar_t** argv); namespace internal { // FormatForComparison::Format(value) formats a // value of type ToPrint that is an operand of a comparison assertion // (e.g. ASSERT_EQ). OtherOperand is the type of the other operand in // the comparison, and is used to help determine the best way to // format the value. In particular, when the value is a C string // (char pointer) and the other operand is an STL string object, we // want to format the C string as a string, since we know it is // compared by value with the string object. If the value is a char // pointer but the other operand is not an STL string object, we don't // know whether the pointer is supposed to point to a NUL-terminated // string, and thus want to print it as a pointer to be safe. // // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. // The default case. template class FormatForComparison { public: static ::std::string Format(const ToPrint& value) { return ::testing::PrintToString(value); } }; // Array. template class FormatForComparison { public: static ::std::string Format(const ToPrint* value) { return FormatForComparison::Format(value); } }; // By default, print C string as pointers to be safe, as we don't know // whether they actually point to a NUL-terminated string. #define GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(CharType) \ template \ class FormatForComparison { \ public: \ static ::std::string Format(CharType* value) { \ return ::testing::PrintToString(static_cast(value)); \ } \ } GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(char); GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(const char); GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(wchar_t); GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(const wchar_t); #undef GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_ // If a C string is compared with an STL string object, we know it's meant // to point to a NUL-terminated string, and thus can print it as a string. #define GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(CharType, OtherStringType) \ template <> \ class FormatForComparison { \ public: \ static ::std::string Format(CharType* value) { \ return ::testing::PrintToString(value); \ } \ } GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(char, ::std::string); GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const char, ::std::string); #if GTEST_HAS_GLOBAL_STRING GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(char, ::string); GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const char, ::string); #endif #if GTEST_HAS_GLOBAL_WSTRING GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(wchar_t, ::wstring); GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const wchar_t, ::wstring); #endif #if GTEST_HAS_STD_WSTRING GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(wchar_t, ::std::wstring); GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const wchar_t, ::std::wstring); #endif #undef GTEST_IMPL_FORMAT_C_STRING_AS_STRING_ // Formats a comparison assertion (e.g. ASSERT_EQ, EXPECT_LT, and etc) // operand to be used in a failure message. The type (but not value) // of the other operand may affect the format. This allows us to // print a char* as a raw pointer when it is compared against another // char* or void*, and print it as a C string when it is compared // against an std::string object, for example. // // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. template std::string FormatForComparisonFailureMessage( const T1& value, const T2& /* other_operand */) { return FormatForComparison::Format(value); } // 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 if (expected == actual) { return AssertionSuccess(); } #ifdef _MSC_VER # pragma warning(pop) // Restores the warning state. #endif return EqFailure(expected_expression, actual_expression, FormatForComparisonFailureMessage(expected, actual), FormatForComparisonFailureMessage(actual, expected), false); } // With this overloaded version, we allow anonymous enums to be used // in {ASSERT|EXPECT}_EQ when compiled with gcc 4, as anonymous enums // can be implicitly cast to BiggestInt. GTEST_API_ AssertionResult CmpHelperEQ(const char* expected_expression, const char* actual_expression, BiggestInt expected, BiggestInt actual); // The helper class for {ASSERT|EXPECT}_EQ. The template argument // lhs_is_null_literal is true iff the first argument to ASSERT_EQ() // is a null pointer literal. The following default implementation is // for lhs_is_null_literal being false. template class EqHelper { public: // This templatized version is for the general case. template static AssertionResult Compare(const char* expected_expression, const char* actual_expression, const T1& expected, const T2& actual) { return CmpHelperEQ(expected_expression, actual_expression, expected, actual); } // With this overloaded version, we allow anonymous enums to be used // in {ASSERT|EXPECT}_EQ when compiled with gcc 4, as anonymous // enums can be implicitly cast to BiggestInt. // // Even though its body looks the same as the above version, we // cannot merge the two, as it will make anonymous enums unhappy. static AssertionResult Compare(const char* expected_expression, const char* actual_expression, BiggestInt expected, BiggestInt actual) { return CmpHelperEQ(expected_expression, actual_expression, expected, actual); } }; // This specialization is used when the first argument to ASSERT_EQ() // is a null pointer literal, like NULL, false, or 0. template <> class EqHelper { public: // We define two overloaded versions of Compare(). The first // version will be picked when the second argument to ASSERT_EQ() is // NOT a pointer, e.g. ASSERT_EQ(0, AnIntFunction()) or // EXPECT_EQ(false, a_bool). template static AssertionResult Compare( const char* expected_expression, const char* actual_expression, const T1& expected, const T2& actual, // The following line prevents this overload from being considered if T2 // is not a pointer type. We need this because ASSERT_EQ(NULL, my_ptr) // expands to Compare("", "", NULL, my_ptr), which requires a conversion // to match the Secret* in the other overload, which would otherwise make // this template match better. typename EnableIf::value>::type* = 0) { return CmpHelperEQ(expected_expression, actual_expression, expected, actual); } // This version will be picked when the second argument to ASSERT_EQ() is a // pointer, e.g. ASSERT_EQ(NULL, a_pointer). template static AssertionResult Compare( const char* expected_expression, const char* actual_expression, // We used to have a second template parameter instead of Secret*. That // template parameter would deduce to 'long', making this a better match // than the first overload even without the first overload's EnableIf. // Unfortunately, gcc with -Wconversion-null warns when "passing NULL to // non-pointer argument" (even a deduced integral argument), so the old // implementation caused warnings in user code. Secret* /* expected (NULL) */, T* actual) { // We already know that 'expected' is a null pointer. return CmpHelperEQ(expected_expression, actual_expression, static_cast(NULL), actual); } }; // A macro for implementing the helper functions needed to implement // ASSERT_?? and EXPECT_??. It is here just to avoid copy-and-paste // of similar code. // // For each templatized helper function, we also define an overloaded // version for BiggestInt in order to reduce code bloat and allow // anonymous enums to be used with {ASSERT|EXPECT}_?? when compiled // with gcc 4. // // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. #define GTEST_IMPL_CMP_HELPER_(op_name, op)\ template \ AssertionResult CmpHelper##op_name(const char* expr1, const char* expr2, \ const T1& val1, const T2& val2) {\ if (val1 op val2) {\ return AssertionSuccess();\ } else {\ return AssertionFailure() \ << "Expected: (" << expr1 << ") " #op " (" << expr2\ << "), actual: " << FormatForComparisonFailureMessage(val1, val2)\ << " vs " << FormatForComparisonFailureMessage(val2, val1);\ }\ }\ GTEST_API_ AssertionResult CmpHelper##op_name(\ const char* expr1, const char* expr2, BiggestInt val1, BiggestInt val2) // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. // Implements the helper function for {ASSERT|EXPECT}_NE GTEST_IMPL_CMP_HELPER_(NE, !=); // Implements the helper function for {ASSERT|EXPECT}_LE GTEST_IMPL_CMP_HELPER_(LE, <=); // Implements the helper function for {ASSERT|EXPECT}_LT GTEST_IMPL_CMP_HELPER_(LT, <); // Implements the helper function for {ASSERT|EXPECT}_GE GTEST_IMPL_CMP_HELPER_(GE, >=); // Implements the helper function for {ASSERT|EXPECT}_GT GTEST_IMPL_CMP_HELPER_(GT, >); #undef GTEST_IMPL_CMP_HELPER_ // The helper function for {ASSERT|EXPECT}_STREQ. // // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. GTEST_API_ AssertionResult CmpHelperSTREQ(const char* expected_expression, const char* actual_expression, const char* expected, const char* actual); // The helper function for {ASSERT|EXPECT}_STRCASEEQ. // // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. GTEST_API_ AssertionResult CmpHelperSTRCASEEQ(const char* expected_expression, const char* actual_expression, const char* expected, const char* actual); // The helper function for {ASSERT|EXPECT}_STRNE. // // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. GTEST_API_ AssertionResult CmpHelperSTRNE(const char* s1_expression, const char* s2_expression, const char* s1, const char* s2); // The helper function for {ASSERT|EXPECT}_STRCASENE. // // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. GTEST_API_ AssertionResult CmpHelperSTRCASENE(const char* s1_expression, const char* s2_expression, const char* s1, const char* s2); // Helper function for *_STREQ on wide strings. // // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. GTEST_API_ AssertionResult CmpHelperSTREQ(const char* expected_expression, const char* actual_expression, const wchar_t* expected, const wchar_t* actual); // Helper function for *_STRNE on wide strings. // // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. GTEST_API_ AssertionResult CmpHelperSTRNE(const char* s1_expression, const char* s2_expression, const wchar_t* s1, const wchar_t* s2); } // namespace internal // IsSubstring() and IsNotSubstring() are intended to be used as the // first argument to {EXPECT,ASSERT}_PRED_FORMAT2(), not by // themselves. They check whether needle is a substring of haystack // (NULL is considered a substring of itself only), and return an // appropriate error message when they fail. // // The {needle,haystack}_expr arguments are the stringified // expressions that generated the two real arguments. GTEST_API_ AssertionResult IsSubstring( const char* needle_expr, const char* haystack_expr, const char* needle, const char* haystack); GTEST_API_ AssertionResult IsSubstring( const char* needle_expr, const char* haystack_expr, const wchar_t* needle, const wchar_t* haystack); GTEST_API_ AssertionResult IsNotSubstring( const char* needle_expr, const char* haystack_expr, const char* needle, const char* haystack); GTEST_API_ AssertionResult IsNotSubstring( const char* needle_expr, const char* haystack_expr, const wchar_t* needle, const wchar_t* haystack); GTEST_API_ AssertionResult IsSubstring( const char* needle_expr, const char* haystack_expr, const ::std::string& needle, const ::std::string& haystack); GTEST_API_ AssertionResult IsNotSubstring( const char* needle_expr, const char* haystack_expr, const ::std::string& needle, const ::std::string& haystack); #if GTEST_HAS_STD_WSTRING GTEST_API_ AssertionResult IsSubstring( const char* needle_expr, const char* haystack_expr, const ::std::wstring& needle, const ::std::wstring& haystack); GTEST_API_ AssertionResult IsNotSubstring( const char* needle_expr, const char* haystack_expr, const ::std::wstring& needle, const ::std::wstring& haystack); #endif // GTEST_HAS_STD_WSTRING namespace internal { // Helper template function for comparing floating-points. // // Template parameter: // // RawType: the raw floating-point type (either float or double) // // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. template AssertionResult CmpHelperFloatingPointEQ(const char* expected_expression, const char* actual_expression, RawType expected, RawType actual) { const FloatingPoint lhs(expected), rhs(actual); if (lhs.AlmostEquals(rhs)) { return AssertionSuccess(); } ::std::stringstream expected_ss; expected_ss << std::setprecision(std::numeric_limits::digits10 + 2) << expected; ::std::stringstream actual_ss; actual_ss << std::setprecision(std::numeric_limits::digits10 + 2) << actual; return EqFailure(expected_expression, actual_expression, StringStreamToString(&expected_ss), StringStreamToString(&actual_ss), false); } // Helper function for implementing ASSERT_NEAR. // // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. GTEST_API_ AssertionResult DoubleNearPredFormat(const char* expr1, const char* expr2, const char* abs_error_expr, double val1, double val2, double abs_error); // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. // A class that enables one to stream messages to assertion macros class GTEST_API_ AssertHelper { public: // Constructor. AssertHelper(TestPartResult::Type type, const char* file, int line, const char* message); ~AssertHelper(); // Message assignment is a semantic trick to enable assertion // streaming; see the GTEST_MESSAGE_ macro below. void operator=(const Message& message) const; private: // We put our data in a struct so that the size of the AssertHelper class can // be as small as possible. This is important because gcc is incapable of // re-using stack space even for temporary variables, so every EXPECT_EQ // reserves stack space for another AssertHelper. struct AssertHelperData { AssertHelperData(TestPartResult::Type t, const char* srcfile, int line_num, const char* msg) : type(t), file(srcfile), line(line_num), message(msg) { } TestPartResult::Type const type; const char* const file; int const line; std::string const message; private: GTEST_DISALLOW_COPY_AND_ASSIGN_(AssertHelperData); }; AssertHelperData* const data_; GTEST_DISALLOW_COPY_AND_ASSIGN_(AssertHelper); }; } // namespace internal #if GTEST_HAS_PARAM_TEST // The pure interface class that all value-parameterized tests inherit from. // A value-parameterized class must inherit from both ::testing::Test and // ::testing::WithParamInterface. In most cases that just means inheriting // from ::testing::TestWithParam, but more complicated test hierarchies // may need to inherit from Test and WithParamInterface at different levels. // // This interface has support for accessing the test parameter value via // the GetParam() method. // // Use it with one of the parameter generator defining functions, like Range(), // Values(), ValuesIn(), Bool(), and Combine(). // // class FooTest : public ::testing::TestWithParam { // protected: // FooTest() { // // Can use GetParam() here. // } // virtual ~FooTest() { // // Can use GetParam() here. // } // virtual void SetUp() { // // Can use GetParam() here. // } // virtual void TearDown { // // Can use GetParam() here. // } // }; // TEST_P(FooTest, DoesBar) { // // Can use GetParam() method here. // Foo foo; // ASSERT_TRUE(foo.DoesBar(GetParam())); // } // INSTANTIATE_TEST_CASE_P(OneToTenRange, FooTest, ::testing::Range(1, 10)); template class WithParamInterface { public: typedef T ParamType; virtual ~WithParamInterface() {} // The current parameter value. Is also available in the test fixture's // constructor. This member function is non-static, even though it only // references static data, to reduce the opportunity for incorrect uses // like writing 'WithParamInterface::GetParam()' for a test that // uses a fixture whose parameter type is int. const ParamType& GetParam() const { GTEST_CHECK_(parameter_ != NULL) << "GetParam() can only be called inside a value-parameterized test " << "-- did you intend to write TEST_P instead of TEST_F?"; return *parameter_; } private: // Sets parameter value. The caller is responsible for making sure the value // remains alive and unchanged throughout the current test. static void SetParam(const ParamType* parameter) { parameter_ = parameter; } // Static value used for accessing parameter during a test lifetime. static const ParamType* parameter_; // TestClass must be a subclass of WithParamInterface and Test. template friend class internal::ParameterizedTestFactory; }; template const T* WithParamInterface::parameter_ = NULL; // Most value-parameterized classes can ignore the existence of // WithParamInterface, and can just inherit from ::testing::TestWithParam. template class TestWithParam : public Test, public WithParamInterface { }; #endif // GTEST_HAS_PARAM_TEST // Macros for indicating success/failure in test code. // ADD_FAILURE unconditionally adds a failure to the current test. // SUCCEED generates a success - it doesn't automatically make the // current test successful, as a test is only successful when it has // no failure. // // EXPECT_* verifies that a certain condition is satisfied. If not, // it behaves like ADD_FAILURE. In particular: // // EXPECT_TRUE verifies that a Boolean condition is true. // EXPECT_FALSE verifies that a Boolean condition is false. // // FAIL and ASSERT_* are similar to ADD_FAILURE and EXPECT_*, except // that they will also abort the current function on failure. People // usually want the fail-fast behavior of FAIL and ASSERT_*, but those // writing data-driven tests often find themselves using ADD_FAILURE // and EXPECT_* more. // Generates a nonfatal failure with a generic message. #define ADD_FAILURE() GTEST_NONFATAL_FAILURE_("Failed") // Generates a nonfatal failure at the given source file location with // a generic message. #define ADD_FAILURE_AT(file, line) \ GTEST_MESSAGE_AT_(file, line, "Failed", \ ::testing::TestPartResult::kNonFatalFailure) // Generates a fatal failure with a generic message. #define GTEST_FAIL() GTEST_FATAL_FAILURE_("Failed") // Define this macro to 1 to omit the definition of FAIL(), which is a // generic name and clashes with some other libraries. #if !GTEST_DONT_DEFINE_FAIL # define FAIL() GTEST_FAIL() #endif // Generates a success with a generic message. #define GTEST_SUCCEED() GTEST_SUCCESS_("Succeeded") // Define this macro to 1 to omit the definition of SUCCEED(), which // is a generic name and clashes with some other libraries. #if !GTEST_DONT_DEFINE_SUCCEED # define SUCCEED() GTEST_SUCCEED() #endif // Macros for testing exceptions. // // * {ASSERT|EXPECT}_THROW(statement, expected_exception): // Tests that the statement throws the expected exception. // * {ASSERT|EXPECT}_NO_THROW(statement): // Tests that the statement doesn't throw any exception. // * {ASSERT|EXPECT}_ANY_THROW(statement): // Tests that the statement throws an exception. #define EXPECT_THROW(statement, expected_exception) \ GTEST_TEST_THROW_(statement, expected_exception, GTEST_NONFATAL_FAILURE_) #define EXPECT_NO_THROW(statement) \ GTEST_TEST_NO_THROW_(statement, GTEST_NONFATAL_FAILURE_) #define EXPECT_ANY_THROW(statement) \ GTEST_TEST_ANY_THROW_(statement, GTEST_NONFATAL_FAILURE_) #define ASSERT_THROW(statement, expected_exception) \ GTEST_TEST_THROW_(statement, expected_exception, GTEST_FATAL_FAILURE_) #define ASSERT_NO_THROW(statement) \ GTEST_TEST_NO_THROW_(statement, GTEST_FATAL_FAILURE_) #define ASSERT_ANY_THROW(statement) \ GTEST_TEST_ANY_THROW_(statement, GTEST_FATAL_FAILURE_) // Boolean assertions. Condition can be either a Boolean expression or an // AssertionResult. For more information on how to use AssertionResult with // these macros see comments on that class. #define EXPECT_TRUE(condition) \ GTEST_TEST_BOOLEAN_(condition, #condition, false, true, \ GTEST_NONFATAL_FAILURE_) #define EXPECT_FALSE(condition) \ GTEST_TEST_BOOLEAN_(!(condition), #condition, true, false, \ GTEST_NONFATAL_FAILURE_) #define ASSERT_TRUE(condition) \ GTEST_TEST_BOOLEAN_(condition, #condition, false, true, \ GTEST_FATAL_FAILURE_) #define ASSERT_FALSE(condition) \ GTEST_TEST_BOOLEAN_(!(condition), #condition, true, false, \ GTEST_FATAL_FAILURE_) // Includes the auto-generated header that implements a family of // generic predicate assertion macros. // Copyright 2006, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // This file is AUTOMATICALLY GENERATED on 10/31/2011 by command // 'gen_gtest_pred_impl.py 5'. DO NOT EDIT BY HAND! // // Implements a family of generic predicate assertion macros. #ifndef GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_ #define GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_ // Makes sure this header is not included before gtest.h. #ifndef GTEST_INCLUDE_GTEST_GTEST_H_ # error Do not include gtest_pred_impl.h directly. Include gtest.h instead. #endif // GTEST_INCLUDE_GTEST_GTEST_H_ // This header implements a family of generic predicate assertion // macros: // // ASSERT_PRED_FORMAT1(pred_format, v1) // ASSERT_PRED_FORMAT2(pred_format, v1, v2) // ... // // where pred_format is a function or functor that takes n (in the // case of ASSERT_PRED_FORMATn) values and their source expression // text, and returns a testing::AssertionResult. See the definition // of ASSERT_EQ in gtest.h for an example. // // If you don't care about formatting, you can use the more // restrictive version: // // ASSERT_PRED1(pred, v1) // ASSERT_PRED2(pred, v1, v2) // ... // // where pred is an n-ary function or functor that returns bool, // and the values v1, v2, ..., must support the << operator for // streaming to std::ostream. // // We also define the EXPECT_* variations. // // For now we only support predicates whose arity is at most 5. // Please email googletestframework@googlegroups.com if you need // support for higher arities. // GTEST_ASSERT_ is the basic statement to which all of the assertions // in this file reduce. Don't use this in your code. #define GTEST_ASSERT_(expression, on_failure) \ GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ if (const ::testing::AssertionResult gtest_ar = (expression)) \ ; \ else \ on_failure(gtest_ar.failure_message()) // Helper function for implementing {EXPECT|ASSERT}_PRED1. Don't use // this in your code. template AssertionResult AssertPred1Helper(const char* pred_text, const char* e1, Pred pred, const T1& v1) { if (pred(v1)) return AssertionSuccess(); return AssertionFailure() << pred_text << "(" << e1 << ") evaluates to false, where" << "\n" << e1 << " evaluates to " << v1; } // Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT1. // Don't use this in your code. #define GTEST_PRED_FORMAT1_(pred_format, v1, on_failure)\ GTEST_ASSERT_(pred_format(#v1, v1), \ on_failure) // Internal macro for implementing {EXPECT|ASSERT}_PRED1. Don't use // this in your code. #define GTEST_PRED1_(pred, v1, on_failure)\ GTEST_ASSERT_(::testing::AssertPred1Helper(#pred, \ #v1, \ pred, \ v1), on_failure) // Unary predicate assertion macros. #define EXPECT_PRED_FORMAT1(pred_format, v1) \ GTEST_PRED_FORMAT1_(pred_format, v1, GTEST_NONFATAL_FAILURE_) #define EXPECT_PRED1(pred, v1) \ GTEST_PRED1_(pred, v1, GTEST_NONFATAL_FAILURE_) #define ASSERT_PRED_FORMAT1(pred_format, v1) \ GTEST_PRED_FORMAT1_(pred_format, v1, GTEST_FATAL_FAILURE_) #define ASSERT_PRED1(pred, v1) \ GTEST_PRED1_(pred, v1, GTEST_FATAL_FAILURE_) // Helper function for implementing {EXPECT|ASSERT}_PRED2. Don't use // this in your code. template AssertionResult AssertPred2Helper(const char* pred_text, const char* e1, const char* e2, Pred pred, const T1& v1, const T2& v2) { if (pred(v1, v2)) return AssertionSuccess(); return AssertionFailure() << pred_text << "(" << e1 << ", " << e2 << ") evaluates to false, where" << "\n" << e1 << " evaluates to " << v1 << "\n" << e2 << " evaluates to " << v2; } // Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT2. // Don't use this in your code. #define GTEST_PRED_FORMAT2_(pred_format, v1, v2, on_failure)\ GTEST_ASSERT_(pred_format(#v1, #v2, v1, v2), \ on_failure) // Internal macro for implementing {EXPECT|ASSERT}_PRED2. Don't use // this in your code. #define GTEST_PRED2_(pred, v1, v2, on_failure)\ GTEST_ASSERT_(::testing::AssertPred2Helper(#pred, \ #v1, \ #v2, \ pred, \ v1, \ v2), on_failure) // Binary predicate assertion macros. #define EXPECT_PRED_FORMAT2(pred_format, v1, v2) \ GTEST_PRED_FORMAT2_(pred_format, v1, v2, GTEST_NONFATAL_FAILURE_) #define EXPECT_PRED2(pred, v1, v2) \ GTEST_PRED2_(pred, v1, v2, GTEST_NONFATAL_FAILURE_) #define ASSERT_PRED_FORMAT2(pred_format, v1, v2) \ GTEST_PRED_FORMAT2_(pred_format, v1, v2, GTEST_FATAL_FAILURE_) #define ASSERT_PRED2(pred, v1, v2) \ GTEST_PRED2_(pred, v1, v2, GTEST_FATAL_FAILURE_) // Helper function for implementing {EXPECT|ASSERT}_PRED3. Don't use // this in your code. template AssertionResult AssertPred3Helper(const char* pred_text, const char* e1, const char* e2, const char* e3, Pred pred, const T1& v1, const T2& v2, const T3& v3) { if (pred(v1, v2, v3)) return AssertionSuccess(); return AssertionFailure() << pred_text << "(" << e1 << ", " << e2 << ", " << e3 << ") evaluates to false, where" << "\n" << e1 << " evaluates to " << v1 << "\n" << e2 << " evaluates to " << v2 << "\n" << e3 << " evaluates to " << v3; } // Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT3. // Don't use this in your code. #define GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, on_failure)\ GTEST_ASSERT_(pred_format(#v1, #v2, #v3, v1, v2, v3), \ on_failure) // Internal macro for implementing {EXPECT|ASSERT}_PRED3. Don't use // this in your code. #define GTEST_PRED3_(pred, v1, v2, v3, on_failure)\ GTEST_ASSERT_(::testing::AssertPred3Helper(#pred, \ #v1, \ #v2, \ #v3, \ pred, \ v1, \ v2, \ v3), on_failure) // Ternary predicate assertion macros. #define EXPECT_PRED_FORMAT3(pred_format, v1, v2, v3) \ GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, GTEST_NONFATAL_FAILURE_) #define EXPECT_PRED3(pred, v1, v2, v3) \ GTEST_PRED3_(pred, v1, v2, v3, GTEST_NONFATAL_FAILURE_) #define ASSERT_PRED_FORMAT3(pred_format, v1, v2, v3) \ GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, GTEST_FATAL_FAILURE_) #define ASSERT_PRED3(pred, v1, v2, v3) \ GTEST_PRED3_(pred, v1, v2, v3, GTEST_FATAL_FAILURE_) // Helper function for implementing {EXPECT|ASSERT}_PRED4. Don't use // this in your code. template AssertionResult AssertPred4Helper(const char* pred_text, const char* e1, const char* e2, const char* e3, const char* e4, Pred pred, const T1& v1, const T2& v2, const T3& v3, const T4& v4) { if (pred(v1, v2, v3, v4)) return AssertionSuccess(); return AssertionFailure() << pred_text << "(" << e1 << ", " << e2 << ", " << e3 << ", " << e4 << ") evaluates to false, where" << "\n" << e1 << " evaluates to " << v1 << "\n" << e2 << " evaluates to " << v2 << "\n" << e3 << " evaluates to " << v3 << "\n" << e4 << " evaluates to " << v4; } // Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT4. // Don't use this in your code. #define GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, on_failure)\ GTEST_ASSERT_(pred_format(#v1, #v2, #v3, #v4, v1, v2, v3, v4), \ on_failure) // Internal macro for implementing {EXPECT|ASSERT}_PRED4. Don't use // this in your code. #define GTEST_PRED4_(pred, v1, v2, v3, v4, on_failure)\ GTEST_ASSERT_(::testing::AssertPred4Helper(#pred, \ #v1, \ #v2, \ #v3, \ #v4, \ pred, \ v1, \ v2, \ v3, \ v4), on_failure) // 4-ary predicate assertion macros. #define EXPECT_PRED_FORMAT4(pred_format, v1, v2, v3, v4) \ GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, GTEST_NONFATAL_FAILURE_) #define EXPECT_PRED4(pred, v1, v2, v3, v4) \ GTEST_PRED4_(pred, v1, v2, v3, v4, GTEST_NONFATAL_FAILURE_) #define ASSERT_PRED_FORMAT4(pred_format, v1, v2, v3, v4) \ GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, GTEST_FATAL_FAILURE_) #define ASSERT_PRED4(pred, v1, v2, v3, v4) \ GTEST_PRED4_(pred, v1, v2, v3, v4, GTEST_FATAL_FAILURE_) // Helper function for implementing {EXPECT|ASSERT}_PRED5. Don't use // this in your code. template AssertionResult AssertPred5Helper(const char* pred_text, const char* e1, const char* e2, const char* e3, const char* e4, const char* e5, Pred pred, const T1& v1, const T2& v2, const T3& v3, const T4& v4, const T5& v5) { if (pred(v1, v2, v3, v4, v5)) return AssertionSuccess(); return AssertionFailure() << pred_text << "(" << e1 << ", " << e2 << ", " << e3 << ", " << e4 << ", " << e5 << ") evaluates to false, where" << "\n" << e1 << " evaluates to " << v1 << "\n" << e2 << " evaluates to " << v2 << "\n" << e3 << " evaluates to " << v3 << "\n" << e4 << " evaluates to " << v4 << "\n" << e5 << " evaluates to " << v5; } // Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT5. // Don't use this in your code. #define GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, on_failure)\ GTEST_ASSERT_(pred_format(#v1, #v2, #v3, #v4, #v5, v1, v2, v3, v4, v5), \ on_failure) // Internal macro for implementing {EXPECT|ASSERT}_PRED5. Don't use // this in your code. #define GTEST_PRED5_(pred, v1, v2, v3, v4, v5, on_failure)\ GTEST_ASSERT_(::testing::AssertPred5Helper(#pred, \ #v1, \ #v2, \ #v3, \ #v4, \ #v5, \ pred, \ v1, \ v2, \ v3, \ v4, \ v5), on_failure) // 5-ary predicate assertion macros. #define EXPECT_PRED_FORMAT5(pred_format, v1, v2, v3, v4, v5) \ GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, GTEST_NONFATAL_FAILURE_) #define EXPECT_PRED5(pred, v1, v2, v3, v4, v5) \ GTEST_PRED5_(pred, v1, v2, v3, v4, v5, GTEST_NONFATAL_FAILURE_) #define ASSERT_PRED_FORMAT5(pred_format, v1, v2, v3, v4, v5) \ GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, GTEST_FATAL_FAILURE_) #define ASSERT_PRED5(pred, v1, v2, v3, v4, v5) \ GTEST_PRED5_(pred, v1, v2, v3, v4, v5, GTEST_FATAL_FAILURE_) #endif // GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_ // Macros for testing equalities and inequalities. // // * {ASSERT|EXPECT}_EQ(expected, actual): Tests that expected == actual // * {ASSERT|EXPECT}_NE(v1, v2): Tests that v1 != v2 // * {ASSERT|EXPECT}_LT(v1, v2): Tests that v1 < v2 // * {ASSERT|EXPECT}_LE(v1, v2): Tests that v1 <= v2 // * {ASSERT|EXPECT}_GT(v1, v2): Tests that v1 > v2 // * {ASSERT|EXPECT}_GE(v1, v2): Tests that v1 >= v2 // // When they are not, Google Test prints both the tested expressions and // their actual values. The values must be compatible built-in types, // or you will get a compiler error. By "compatible" we mean that the // values can be compared by the respective operator. // // Note: // // 1. It is possible to make a user-defined type work with // {ASSERT|EXPECT}_??(), but that requires overloading the // comparison operators and is thus discouraged by the Google C++ // Usage Guide. Therefore, you are advised to use the // {ASSERT|EXPECT}_TRUE() macro to assert that two objects are // equal. // // 2. The {ASSERT|EXPECT}_??() macros do pointer comparisons on // pointers (in particular, C strings). Therefore, if you use it // with two C strings, you are testing how their locations in memory // are related, not how their content is related. To compare two C // strings by content, use {ASSERT|EXPECT}_STR*(). // // 3. {ASSERT|EXPECT}_EQ(expected, actual) is preferred to // {ASSERT|EXPECT}_TRUE(expected == actual), as the former tells you // what the actual value is when it fails, and similarly for the // other comparisons. // // 4. Do not depend on the order in which {ASSERT|EXPECT}_??() // evaluate their arguments, which is undefined. // // 5. These macros evaluate their arguments exactly once. // // Examples: // // EXPECT_NE(5, Foo()); // EXPECT_EQ(NULL, a_pointer); // ASSERT_LT(i, array_size); // ASSERT_GT(records.size(), 0) << "There is no record left."; #define EXPECT_EQ(expected, actual) \ EXPECT_PRED_FORMAT2(::testing::internal:: \ EqHelper::Compare, \ expected, actual) #define EXPECT_NE(expected, actual) \ EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperNE, expected, actual) #define EXPECT_LE(val1, val2) \ EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperLE, val1, val2) #define EXPECT_LT(val1, val2) \ EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperLT, val1, val2) #define EXPECT_GE(val1, val2) \ EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperGE, val1, val2) #define EXPECT_GT(val1, val2) \ EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperGT, val1, val2) #define GTEST_ASSERT_EQ(expected, actual) \ ASSERT_PRED_FORMAT2(::testing::internal:: \ EqHelper::Compare, \ expected, actual) #define GTEST_ASSERT_NE(val1, val2) \ ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperNE, val1, val2) #define GTEST_ASSERT_LE(val1, val2) \ ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperLE, val1, val2) #define GTEST_ASSERT_LT(val1, val2) \ ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperLT, val1, val2) #define GTEST_ASSERT_GE(val1, val2) \ ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperGE, val1, val2) #define GTEST_ASSERT_GT(val1, val2) \ ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperGT, val1, val2) // Define macro GTEST_DONT_DEFINE_ASSERT_XY to 1 to omit the definition of // ASSERT_XY(), which clashes with some users' own code. #if !GTEST_DONT_DEFINE_ASSERT_EQ # define ASSERT_EQ(val1, val2) GTEST_ASSERT_EQ(val1, val2) #endif #if !GTEST_DONT_DEFINE_ASSERT_NE # define ASSERT_NE(val1, val2) GTEST_ASSERT_NE(val1, val2) #endif #if !GTEST_DONT_DEFINE_ASSERT_LE # define ASSERT_LE(val1, val2) GTEST_ASSERT_LE(val1, val2) #endif #if !GTEST_DONT_DEFINE_ASSERT_LT # define ASSERT_LT(val1, val2) GTEST_ASSERT_LT(val1, val2) #endif #if !GTEST_DONT_DEFINE_ASSERT_GE # define ASSERT_GE(val1, val2) GTEST_ASSERT_GE(val1, val2) #endif #if !GTEST_DONT_DEFINE_ASSERT_GT # define ASSERT_GT(val1, val2) GTEST_ASSERT_GT(val1, val2) #endif // C-string Comparisons. All tests treat NULL and any non-NULL string // as different. Two NULLs are equal. // // * {ASSERT|EXPECT}_STREQ(s1, s2): Tests that s1 == s2 // * {ASSERT|EXPECT}_STRNE(s1, s2): Tests that s1 != s2 // * {ASSERT|EXPECT}_STRCASEEQ(s1, s2): Tests that s1 == s2, ignoring case // * {ASSERT|EXPECT}_STRCASENE(s1, s2): Tests that s1 != s2, ignoring case // // For wide or narrow string objects, you can use the // {ASSERT|EXPECT}_??() macros. // // Don't depend on the order in which the arguments are evaluated, // which is undefined. // // These macros evaluate their arguments exactly once. #define EXPECT_STREQ(expected, actual) \ EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTREQ, expected, actual) #define EXPECT_STRNE(s1, s2) \ EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTRNE, s1, s2) #define EXPECT_STRCASEEQ(expected, actual) \ EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASEEQ, expected, actual) #define EXPECT_STRCASENE(s1, s2)\ EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASENE, s1, s2) #define ASSERT_STREQ(expected, actual) \ ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTREQ, expected, actual) #define ASSERT_STRNE(s1, s2) \ ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTRNE, s1, s2) #define ASSERT_STRCASEEQ(expected, actual) \ ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASEEQ, expected, actual) #define ASSERT_STRCASENE(s1, s2)\ ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASENE, s1, s2) // Macros for comparing floating-point numbers. // // * {ASSERT|EXPECT}_FLOAT_EQ(expected, actual): // Tests that two float values are almost equal. // * {ASSERT|EXPECT}_DOUBLE_EQ(expected, actual): // Tests that two double values are almost equal. // * {ASSERT|EXPECT}_NEAR(v1, v2, abs_error): // Tests that v1 and v2 are within the given distance to each other. // // Google Test uses ULP-based comparison to automatically pick a default // error bound that is appropriate for the operands. See the // FloatingPoint template class in gtest-internal.h if you are // interested in the implementation details. #define EXPECT_FLOAT_EQ(expected, actual)\ EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ, \ expected, actual) #define EXPECT_DOUBLE_EQ(expected, actual)\ EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ, \ expected, actual) #define ASSERT_FLOAT_EQ(expected, actual)\ ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ, \ expected, actual) #define ASSERT_DOUBLE_EQ(expected, actual)\ ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ, \ expected, actual) #define EXPECT_NEAR(val1, val2, abs_error)\ EXPECT_PRED_FORMAT3(::testing::internal::DoubleNearPredFormat, \ val1, val2, abs_error) #define ASSERT_NEAR(val1, val2, abs_error)\ ASSERT_PRED_FORMAT3(::testing::internal::DoubleNearPredFormat, \ val1, val2, abs_error) // These predicate format functions work on floating-point values, and // can be used in {ASSERT|EXPECT}_PRED_FORMAT2*(), e.g. // // EXPECT_PRED_FORMAT2(testing::DoubleLE, Foo(), 5.0); // Asserts that val1 is less than, or almost equal to, val2. Fails // otherwise. In particular, it fails if either val1 or val2 is NaN. GTEST_API_ AssertionResult FloatLE(const char* expr1, const char* expr2, float val1, float val2); GTEST_API_ AssertionResult DoubleLE(const char* expr1, const char* expr2, double val1, double val2); #if GTEST_OS_WINDOWS // Macros that test for HRESULT failure and success, these are only useful // on Windows, and rely on Windows SDK macros and APIs to compile. // // * {ASSERT|EXPECT}_HRESULT_{SUCCEEDED|FAILED}(expr) // // When expr unexpectedly fails or succeeds, Google Test prints the // expected result and the actual result with both a human-readable // string representation of the error, if available, as well as the // hex result code. # define EXPECT_HRESULT_SUCCEEDED(expr) \ EXPECT_PRED_FORMAT1(::testing::internal::IsHRESULTSuccess, (expr)) # define ASSERT_HRESULT_SUCCEEDED(expr) \ ASSERT_PRED_FORMAT1(::testing::internal::IsHRESULTSuccess, (expr)) # define EXPECT_HRESULT_FAILED(expr) \ EXPECT_PRED_FORMAT1(::testing::internal::IsHRESULTFailure, (expr)) # define ASSERT_HRESULT_FAILED(expr) \ ASSERT_PRED_FORMAT1(::testing::internal::IsHRESULTFailure, (expr)) #endif // GTEST_OS_WINDOWS // Macros that execute statement and check that it doesn't generate new fatal // failures in the current thread. // // * {ASSERT|EXPECT}_NO_FATAL_FAILURE(statement); // // Examples: // // EXPECT_NO_FATAL_FAILURE(Process()); // ASSERT_NO_FATAL_FAILURE(Process()) << "Process() failed"; // #define ASSERT_NO_FATAL_FAILURE(statement) \ GTEST_TEST_NO_FATAL_FAILURE_(statement, GTEST_FATAL_FAILURE_) #define EXPECT_NO_FATAL_FAILURE(statement) \ GTEST_TEST_NO_FATAL_FAILURE_(statement, GTEST_NONFATAL_FAILURE_) // Causes a trace (including the source file path, the current line // number, and the given message) to be included in every test failure // message generated by code in the current scope. The effect is // undone when the control leaves the current scope. // // The message argument can be anything streamable to std::ostream. // // In the implementation, we include the current line number as part // of the dummy variable name, thus allowing multiple SCOPED_TRACE()s // to appear in the same block - as long as they are on different // lines. #define SCOPED_TRACE(message) \ ::testing::internal::ScopedTrace GTEST_CONCAT_TOKEN_(gtest_trace_, __LINE__)(\ __FILE__, __LINE__, ::testing::Message() << (message)) // Compile-time assertion for type equality. // StaticAssertTypeEq() compiles iff type1 and type2 are // the same type. The value it returns is not interesting. // // Instead of making StaticAssertTypeEq a class template, we make it a // function template that invokes a helper class template. This // prevents a user from misusing StaticAssertTypeEq by // defining objects of that type. // // CAVEAT: // // When used inside a method of a class template, // StaticAssertTypeEq() is effective ONLY IF the method is // instantiated. For example, given: // // template class Foo { // public: // void Bar() { testing::StaticAssertTypeEq(); } // }; // // the code: // // void Test1() { Foo foo; } // // will NOT generate a compiler error, as Foo::Bar() is never // actually instantiated. Instead, you need: // // void Test2() { Foo foo; foo.Bar(); } // // to cause a compiler error. template bool StaticAssertTypeEq() { (void)internal::StaticAssertTypeEqHelper(); return true; } // Defines a test. // // The first parameter is the name of the test case, and the second // parameter is the name of the test within the test case. // // The convention is to end the test case name with "Test". For // example, a test case for the Foo class can be named FooTest. // // The user should put his test code between braces after using this // macro. Example: // // TEST(FooTest, InitializesCorrectly) { // Foo foo; // EXPECT_TRUE(foo.StatusIsOK()); // } // Note that we call GetTestTypeId() instead of GetTypeId< // ::testing::Test>() here to get the type ID of testing::Test. This // is to work around a suspected linker bug when using Google Test as // a framework on Mac OS X. The bug causes GetTypeId< // ::testing::Test>() to return different values depending on whether // the call is from the Google Test framework itself or from user test // code. GetTestTypeId() is guaranteed to always return the same // value, as it always calls GetTypeId<>() from the Google Test // framework. #define GTEST_TEST(test_case_name, test_name)\ GTEST_TEST_(test_case_name, test_name, \ ::testing::Test, ::testing::internal::GetTestTypeId()) // Define this macro to 1 to omit the definition of TEST(), which // is a generic name and clashes with some other libraries. #if !GTEST_DONT_DEFINE_TEST # define TEST(test_case_name, test_name) GTEST_TEST(test_case_name, test_name) #endif // Defines a test that uses a test fixture. // // The first parameter is the name of the test fixture class, which // also doubles as the test case name. The second parameter is the // name of the test within the test case. // // A test fixture class must be declared earlier. The user should put // his test code between braces after using this macro. Example: // // class FooTest : public testing::Test { // protected: // virtual void SetUp() { b_.AddElement(3); } // // Foo a_; // Foo b_; // }; // // TEST_F(FooTest, InitializesCorrectly) { // EXPECT_TRUE(a_.StatusIsOK()); // } // // TEST_F(FooTest, ReturnsElementCountCorrectly) { // EXPECT_EQ(0, a_.size()); // EXPECT_EQ(1, b_.size()); // } #define TEST_F(test_fixture, test_name)\ GTEST_TEST_(test_fixture, test_name, test_fixture, \ ::testing::internal::GetTypeId()) } // namespace testing // Use this function in main() to run all tests. It returns 0 if all // tests are successful, or 1 otherwise. // // RUN_ALL_TESTS() should be invoked after the command line has been // parsed by InitGoogleTest(). // // This function was formerly a macro; thus, it is in the global // namespace and has an all-caps name. int RUN_ALL_TESTS() GTEST_MUST_USE_RESULT_; inline int RUN_ALL_TESTS() { return ::testing::UnitTest::GetInstance()->Run(); } #endif // GTEST_INCLUDE_GTEST_GTEST_H_ dlt-daemon-2.18.4/gtest-1.7.0/fused-src/gtest/gtest_main.cc000066400000000000000000000033451353342203500231100ustar00rootroot00000000000000// Copyright 2006, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include "gtest/gtest.h" GTEST_API_ int main(int argc, char **argv) { printf("Running main() from gtest_main.cc\n"); testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } dlt-daemon-2.18.4/gtest-1.7.0/include/000077500000000000000000000000001353342203500170445ustar00rootroot00000000000000dlt-daemon-2.18.4/gtest-1.7.0/include/gtest/000077500000000000000000000000001353342203500201725ustar00rootroot00000000000000dlt-daemon-2.18.4/gtest-1.7.0/include/gtest/gtest-death-test.h000066400000000000000000000264031353342203500235360ustar00rootroot00000000000000// Copyright 2005, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: wan@google.com (Zhanyong Wan) // // The Google C++ Testing Framework (Google Test) // // This header file defines the public API for death tests. It is // #included by gtest.h so a user doesn't need to include this // directly. #ifndef GTEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_ #define GTEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_ #include "gtest/internal/gtest-death-test-internal.h" namespace testing { // This flag controls the style of death tests. Valid values are "threadsafe", // meaning that the death test child process will re-execute the test binary // from the start, running only a single death test, or "fast", // meaning that the child process will execute the test logic immediately // after forking. GTEST_DECLARE_string_(death_test_style); #if GTEST_HAS_DEATH_TEST namespace internal { // Returns a Boolean value indicating whether the caller is currently // executing in the context of the death test child process. Tools such as // Valgrind heap checkers may need this to modify their behavior in death // tests. IMPORTANT: This is an internal utility. Using it may break the // implementation of death tests. User code MUST NOT use it. GTEST_API_ bool InDeathTestChild(); } // namespace internal // The following macros are useful for writing death tests. // Here's what happens when an ASSERT_DEATH* or EXPECT_DEATH* is // executed: // // 1. It generates a warning if there is more than one active // thread. This is because it's safe to fork() or clone() only // when there is a single thread. // // 2. The parent process clone()s a sub-process and runs the death // test in it; the sub-process exits with code 0 at the end of the // death test, if it hasn't exited already. // // 3. The parent process waits for the sub-process to terminate. // // 4. The parent process checks the exit code and error message of // the sub-process. // // Examples: // // ASSERT_DEATH(server.SendMessage(56, "Hello"), "Invalid port number"); // for (int i = 0; i < 5; i++) { // EXPECT_DEATH(server.ProcessRequest(i), // "Invalid request .* in ProcessRequest()") // << "Failed to die on request " << i; // } // // ASSERT_EXIT(server.ExitNow(), ::testing::ExitedWithCode(0), "Exiting"); // // bool KilledBySIGHUP(int exit_code) { // return WIFSIGNALED(exit_code) && WTERMSIG(exit_code) == SIGHUP; // } // // ASSERT_EXIT(client.HangUpServer(), KilledBySIGHUP, "Hanging up!"); // // On the regular expressions used in death tests: // // On POSIX-compliant systems (*nix), we use the library, // which uses the POSIX extended regex syntax. // // On other platforms (e.g. Windows), we only support a simple regex // syntax implemented as part of Google Test. This limited // implementation should be enough most of the time when writing // death tests; though it lacks many features you can find in PCRE // or POSIX extended regex syntax. For example, we don't support // union ("x|y"), grouping ("(xy)"), brackets ("[xy]"), and // repetition count ("x{5,7}"), among others. // // Below is the syntax that we do support. We chose it to be a // subset of both PCRE and POSIX extended regex, so it's easy to // learn wherever you come from. In the following: 'A' denotes a // literal character, period (.), or a single \\ escape sequence; // 'x' and 'y' denote regular expressions; 'm' and 'n' are for // natural numbers. // // c matches any literal character c // \\d matches any decimal digit // \\D matches any character that's not a decimal digit // \\f matches \f // \\n matches \n // \\r matches \r // \\s matches any ASCII whitespace, including \n // \\S matches any character that's not a whitespace // \\t matches \t // \\v matches \v // \\w matches any letter, _, or decimal digit // \\W matches any character that \\w doesn't match // \\c matches any literal character c, which must be a punctuation // . matches any single character except \n // A? matches 0 or 1 occurrences of A // A* matches 0 or many occurrences of A // A+ matches 1 or many occurrences of A // ^ matches the beginning of a string (not that of each line) // $ matches the end of a string (not that of each line) // xy matches x followed by y // // If you accidentally use PCRE or POSIX extended regex features // not implemented by us, you will get a run-time failure. In that // case, please try to rewrite your regular expression within the // above syntax. // // This implementation is *not* meant to be as highly tuned or robust // as a compiled regex library, but should perform well enough for a // death test, which already incurs significant overhead by launching // a child process. // // Known caveats: // // A "threadsafe" style death test obtains the path to the test // program from argv[0] and re-executes it in the sub-process. For // simplicity, the current implementation doesn't search the PATH // when launching the sub-process. This means that the user must // invoke the test program via a path that contains at least one // path separator (e.g. path/to/foo_test and // /absolute/path/to/bar_test are fine, but foo_test is not). This // is rarely a problem as people usually don't put the test binary // directory in PATH. // // TODO(wan@google.com): make thread-safe death tests search the PATH. // Asserts that a given statement causes the program to exit, with an // integer exit status that satisfies predicate, and emitting error output // that matches regex. # define ASSERT_EXIT(statement, predicate, regex) \ GTEST_DEATH_TEST_(statement, predicate, regex, GTEST_FATAL_FAILURE_) // Like ASSERT_EXIT, but continues on to successive tests in the // test case, if any: # define EXPECT_EXIT(statement, predicate, regex) \ GTEST_DEATH_TEST_(statement, predicate, regex, GTEST_NONFATAL_FAILURE_) // Asserts that a given statement causes the program to exit, either by // explicitly exiting with a nonzero exit code or being killed by a // signal, and emitting error output that matches regex. # define ASSERT_DEATH(statement, regex) \ ASSERT_EXIT(statement, ::testing::internal::ExitedUnsuccessfully, regex) // Like ASSERT_DEATH, but continues on to successive tests in the // test case, if any: # define EXPECT_DEATH(statement, regex) \ EXPECT_EXIT(statement, ::testing::internal::ExitedUnsuccessfully, regex) // Two predicate classes that can be used in {ASSERT,EXPECT}_EXIT*: // Tests that an exit code describes a normal exit with a given exit code. class GTEST_API_ ExitedWithCode { public: explicit ExitedWithCode(int exit_code); bool operator()(int exit_status) const; private: // No implementation - assignment is unsupported. void operator=(const ExitedWithCode& other); const int exit_code_; }; # if !GTEST_OS_WINDOWS // Tests that an exit code describes an exit due to termination by a // given signal. class GTEST_API_ KilledBySignal { public: explicit KilledBySignal(int signum); bool operator()(int exit_status) const; private: const int signum_; }; # endif // !GTEST_OS_WINDOWS // EXPECT_DEBUG_DEATH asserts that the given statements die in debug mode. // The death testing framework causes this to have interesting semantics, // since the sideeffects of the call are only visible in opt mode, and not // in debug mode. // // In practice, this can be used to test functions that utilize the // LOG(DFATAL) macro using the following style: // // int DieInDebugOr12(int* sideeffect) { // if (sideeffect) { // *sideeffect = 12; // } // LOG(DFATAL) << "death"; // return 12; // } // // TEST(TestCase, TestDieOr12WorksInDgbAndOpt) { // int sideeffect = 0; // // Only asserts in dbg. // EXPECT_DEBUG_DEATH(DieInDebugOr12(&sideeffect), "death"); // // #ifdef NDEBUG // // opt-mode has sideeffect visible. // EXPECT_EQ(12, sideeffect); // #else // // dbg-mode no visible sideeffect. // EXPECT_EQ(0, sideeffect); // #endif // } // // This will assert that DieInDebugReturn12InOpt() crashes in debug // mode, usually due to a DCHECK or LOG(DFATAL), but returns the // appropriate fallback value (12 in this case) in opt mode. If you // need to test that a function has appropriate side-effects in opt // mode, include assertions against the side-effects. A general // pattern for this is: // // EXPECT_DEBUG_DEATH({ // // Side-effects here will have an effect after this statement in // // opt mode, but none in debug mode. // EXPECT_EQ(12, DieInDebugOr12(&sideeffect)); // }, "death"); // # ifdef NDEBUG # define EXPECT_DEBUG_DEATH(statement, regex) \ GTEST_EXECUTE_STATEMENT_(statement, regex) # define ASSERT_DEBUG_DEATH(statement, regex) \ GTEST_EXECUTE_STATEMENT_(statement, regex) # else # define EXPECT_DEBUG_DEATH(statement, regex) \ EXPECT_DEATH(statement, regex) # define ASSERT_DEBUG_DEATH(statement, regex) \ ASSERT_DEATH(statement, regex) # endif // NDEBUG for EXPECT_DEBUG_DEATH #endif // GTEST_HAS_DEATH_TEST // EXPECT_DEATH_IF_SUPPORTED(statement, regex) and // ASSERT_DEATH_IF_SUPPORTED(statement, regex) expand to real death tests if // death tests are supported; otherwise they just issue a warning. This is // useful when you are combining death test assertions with normal test // assertions in one test. #if GTEST_HAS_DEATH_TEST # define EXPECT_DEATH_IF_SUPPORTED(statement, regex) \ EXPECT_DEATH(statement, regex) # define ASSERT_DEATH_IF_SUPPORTED(statement, regex) \ ASSERT_DEATH(statement, regex) #else # define EXPECT_DEATH_IF_SUPPORTED(statement, regex) \ GTEST_UNSUPPORTED_DEATH_TEST_(statement, regex, ) # define ASSERT_DEATH_IF_SUPPORTED(statement, regex) \ GTEST_UNSUPPORTED_DEATH_TEST_(statement, regex, return) #endif } // namespace testing #endif // GTEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_ dlt-daemon-2.18.4/gtest-1.7.0/include/gtest/gtest-message.h000066400000000000000000000217421353342203500231210ustar00rootroot00000000000000// Copyright 2005, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: wan@google.com (Zhanyong Wan) // // The Google C++ Testing Framework (Google Test) // // This header file defines the Message class. // // IMPORTANT NOTE: Due to limitation of the C++ language, we have to // leave some internal implementation details in this header file. // They are clearly marked by comments like this: // // // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. // // Such code is NOT meant to be used by a user directly, and is subject // to CHANGE WITHOUT NOTICE. Therefore DO NOT DEPEND ON IT in a user // program! #ifndef GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_ #define GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_ #include #include "gtest/internal/gtest-port.h" // Ensures that there is at least one operator<< in the global namespace. // See Message& operator<<(...) below for why. void operator<<(const testing::internal::Secret&, int); namespace testing { // The Message class works like an ostream repeater. // // Typical usage: // // 1. You stream a bunch of values to a Message object. // It will remember the text in a stringstream. // 2. Then you stream the Message object to an ostream. // This causes the text in the Message to be streamed // to the ostream. // // For example; // // testing::Message foo; // foo << 1 << " != " << 2; // std::cout << foo; // // will print "1 != 2". // // Message is not intended to be inherited from. In particular, its // destructor is not virtual. // // Note that stringstream behaves differently in gcc and in MSVC. You // can stream a NULL char pointer to it in the former, but not in the // latter (it causes an access violation if you do). The Message // class hides this difference by treating a NULL char pointer as // "(null)". class GTEST_API_ Message { private: // The type of basic IO manipulators (endl, ends, and flush) for // narrow streams. typedef std::ostream& (*BasicNarrowIoManip)(std::ostream&); public: // Constructs an empty Message. Message(); // Copy constructor. Message(const Message& msg) : ss_(new ::std::stringstream) { // NOLINT *ss_ << msg.GetString(); } // Constructs a Message from a C-string. explicit Message(const char* str) : ss_(new ::std::stringstream) { *ss_ << str; } #if GTEST_OS_SYMBIAN // Streams a value (either a pointer or not) to this object. template inline Message& operator <<(const T& value) { StreamHelper(typename internal::is_pointer::type(), value); return *this; } #else // Streams a non-pointer value to this object. template inline Message& operator <<(const T& val) { // Some libraries overload << for STL containers. These // overloads are defined in the global namespace instead of ::std. // // C++'s symbol lookup rule (i.e. Koenig lookup) says that these // overloads are visible in either the std namespace or the global // namespace, but not other namespaces, including the testing // namespace which Google Test's Message class is in. // // To allow STL containers (and other types that has a << operator // defined in the global namespace) to be used in Google Test // assertions, testing::Message must access the custom << operator // from the global namespace. With this using declaration, // overloads of << defined in the global namespace and those // visible via Koenig lookup are both exposed in this function. using ::operator <<; *ss_ << val; return *this; } // Streams a pointer value to this object. // // This function is an overload of the previous one. When you // stream a pointer to a Message, this definition will be used as it // is more specialized. (The C++ Standard, section // [temp.func.order].) If you stream a non-pointer, then the // previous definition will be used. // // The reason for this overload is that streaming a NULL pointer to // ostream is undefined behavior. Depending on the compiler, you // may get "0", "(nil)", "(null)", or an access violation. To // ensure consistent result across compilers, we always treat NULL // as "(null)". template inline Message& operator <<(T* const& pointer) { // NOLINT if (pointer == NULL) { *ss_ << "(null)"; } else { *ss_ << pointer; } return *this; } #endif // GTEST_OS_SYMBIAN // Since the basic IO manipulators are overloaded for both narrow // and wide streams, we have to provide this specialized definition // of operator <<, even though its body is the same as the // templatized version above. Without this definition, streaming // endl or other basic IO manipulators to Message will confuse the // compiler. Message& operator <<(BasicNarrowIoManip val) { *ss_ << val; return *this; } // Instead of 1/0, we want to see true/false for bool values. Message& operator <<(bool b) { return *this << (b ? "true" : "false"); } // These two overloads allow streaming a wide C string to a Message // using the UTF-8 encoding. Message& operator <<(const wchar_t* wide_c_str); Message& operator <<(wchar_t* wide_c_str); #if GTEST_HAS_STD_WSTRING // Converts the given wide string to a narrow string using the UTF-8 // encoding, and streams the result to this Message object. Message& operator <<(const ::std::wstring& wstr); #endif // GTEST_HAS_STD_WSTRING #if GTEST_HAS_GLOBAL_WSTRING // Converts the given wide string to a narrow string using the UTF-8 // encoding, and streams the result to this Message object. Message& operator <<(const ::wstring& wstr); #endif // GTEST_HAS_GLOBAL_WSTRING // Gets the text streamed to this object so far as an std::string. // Each '\0' character in the buffer is replaced with "\\0". // // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. std::string GetString() const; private: #if GTEST_OS_SYMBIAN // These are needed as the Nokia Symbian Compiler cannot decide between // const T& and const T* in a function template. The Nokia compiler _can_ // decide between class template specializations for T and T*, so a // tr1::type_traits-like is_pointer works, and we can overload on that. template inline void StreamHelper(internal::true_type /*is_pointer*/, T* pointer) { if (pointer == NULL) { *ss_ << "(null)"; } else { *ss_ << pointer; } } template inline void StreamHelper(internal::false_type /*is_pointer*/, const T& value) { // See the comments in Message& operator <<(const T&) above for why // we need this using statement. using ::operator <<; *ss_ << value; } #endif // GTEST_OS_SYMBIAN // We'll hold the text streamed to this object here. const internal::scoped_ptr< ::std::stringstream> ss_; // We declare (but don't implement) this to prevent the compiler // from implementing the assignment operator. void operator=(const Message&); }; // Streams a Message to an ostream. inline std::ostream& operator <<(std::ostream& os, const Message& sb) { return os << sb.GetString(); } namespace internal { // Converts a streamable value to an std::string. A NULL pointer is // converted to "(null)". When the input value is a ::string, // ::std::string, ::wstring, or ::std::wstring object, each NUL // character in it is replaced with "\\0". template std::string StreamableToString(const T& streamable) { return (Message() << streamable).GetString(); } } // namespace internal } // namespace testing #endif // GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_ dlt-daemon-2.18.4/gtest-1.7.0/include/gtest/gtest-param-test.h000066400000000000000000002241301353342203500235460ustar00rootroot00000000000000// This file was GENERATED by command: // pump.py gtest-param-test.h.pump // DO NOT EDIT BY HAND!!! // Copyright 2008, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Authors: vladl@google.com (Vlad Losev) // // Macros and functions for implementing parameterized tests // in Google C++ Testing Framework (Google Test) // // This file is generated by a SCRIPT. DO NOT EDIT BY HAND! // #ifndef GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_ #define GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_ // Value-parameterized tests allow you to test your code with different // parameters without writing multiple copies of the same test. // // Here is how you use value-parameterized tests: #if 0 // To write value-parameterized tests, first you should define a fixture // class. It is usually derived from testing::TestWithParam (see below for // another inheritance scheme that's sometimes useful in more complicated // class hierarchies), where the type of your parameter values. // TestWithParam is itself derived from testing::Test. T can be any // copyable type. If it's a raw pointer, you are responsible for managing the // lifespan of the pointed values. class FooTest : public ::testing::TestWithParam { // You can implement all the usual class fixture members here. }; // Then, use the TEST_P macro to define as many parameterized tests // for this fixture as you want. The _P suffix is for "parameterized" // or "pattern", whichever you prefer to think. TEST_P(FooTest, DoesBlah) { // Inside a test, access the test parameter with the GetParam() method // of the TestWithParam class: EXPECT_TRUE(foo.Blah(GetParam())); ... } TEST_P(FooTest, HasBlahBlah) { ... } // Finally, you can use INSTANTIATE_TEST_CASE_P to instantiate the test // case with any set of parameters you want. Google Test defines a number // of functions for generating test parameters. They return what we call // (surprise!) parameter generators. Here is a summary of them, which // are all in the testing namespace: // // // Range(begin, end [, step]) - Yields values {begin, begin+step, // begin+step+step, ...}. The values do not // include end. step defaults to 1. // Values(v1, v2, ..., vN) - Yields values {v1, v2, ..., vN}. // ValuesIn(container) - Yields values from a C-style array, an STL // ValuesIn(begin,end) container, or an iterator range [begin, end). // Bool() - Yields sequence {false, true}. // Combine(g1, g2, ..., gN) - Yields all combinations (the Cartesian product // for the math savvy) of the values generated // by the N generators. // // For more details, see comments at the definitions of these functions below // in this file. // // The following statement will instantiate tests from the FooTest test case // each with parameter values "meeny", "miny", and "moe". INSTANTIATE_TEST_CASE_P(InstantiationName, FooTest, Values("meeny", "miny", "moe")); // To distinguish different instances of the pattern, (yes, you // can instantiate it more then once) the first argument to the // INSTANTIATE_TEST_CASE_P macro is a prefix that will be added to the // actual test case name. Remember to pick unique prefixes for different // instantiations. The tests from the instantiation above will have // these names: // // * InstantiationName/FooTest.DoesBlah/0 for "meeny" // * InstantiationName/FooTest.DoesBlah/1 for "miny" // * InstantiationName/FooTest.DoesBlah/2 for "moe" // * InstantiationName/FooTest.HasBlahBlah/0 for "meeny" // * InstantiationName/FooTest.HasBlahBlah/1 for "miny" // * InstantiationName/FooTest.HasBlahBlah/2 for "moe" // // You can use these names in --gtest_filter. // // This statement will instantiate all tests from FooTest again, each // with parameter values "cat" and "dog": const char* pets[] = {"cat", "dog"}; INSTANTIATE_TEST_CASE_P(AnotherInstantiationName, FooTest, ValuesIn(pets)); // The tests from the instantiation above will have these names: // // * AnotherInstantiationName/FooTest.DoesBlah/0 for "cat" // * AnotherInstantiationName/FooTest.DoesBlah/1 for "dog" // * AnotherInstantiationName/FooTest.HasBlahBlah/0 for "cat" // * AnotherInstantiationName/FooTest.HasBlahBlah/1 for "dog" // // Please note that INSTANTIATE_TEST_CASE_P will instantiate all tests // in the given test case, whether their definitions come before or // AFTER the INSTANTIATE_TEST_CASE_P statement. // // Please also note that generator expressions (including parameters to the // generators) are evaluated in InitGoogleTest(), after main() has started. // This allows the user on one hand, to adjust generator parameters in order // to dynamically determine a set of tests to run and on the other hand, // give the user a chance to inspect the generated tests with Google Test // reflection API before RUN_ALL_TESTS() is executed. // // You can see samples/sample7_unittest.cc and samples/sample8_unittest.cc // for more examples. // // In the future, we plan to publish the API for defining new parameter // generators. But for now this interface remains part of the internal // implementation and is subject to change. // // // A parameterized test fixture must be derived from testing::Test and from // testing::WithParamInterface, where T is the type of the parameter // values. Inheriting from TestWithParam satisfies that requirement because // TestWithParam inherits from both Test and WithParamInterface. In more // complicated hierarchies, however, it is occasionally useful to inherit // separately from Test and WithParamInterface. For example: class BaseTest : public ::testing::Test { // You can inherit all the usual members for a non-parameterized test // fixture here. }; class DerivedTest : public BaseTest, public ::testing::WithParamInterface { // The usual test fixture members go here too. }; TEST_F(BaseTest, HasFoo) { // This is an ordinary non-parameterized test. } TEST_P(DerivedTest, DoesBlah) { // GetParam works just the same here as if you inherit from TestWithParam. EXPECT_TRUE(foo.Blah(GetParam())); } #endif // 0 #include "gtest/internal/gtest-port.h" #if !GTEST_OS_SYMBIAN # include #endif // scripts/fuse_gtest.py depends on gtest's own header being #included // *unconditionally*. Therefore these #includes cannot be moved // inside #if GTEST_HAS_PARAM_TEST. #include "gtest/internal/gtest-internal.h" #include "gtest/internal/gtest-param-util.h" #include "gtest/internal/gtest-param-util-generated.h" #if GTEST_HAS_PARAM_TEST namespace testing { // Functions producing parameter generators. // // Google Test uses these generators to produce parameters for value- // parameterized tests. When a parameterized test case is instantiated // with a particular generator, Google Test creates and runs tests // for each element in the sequence produced by the generator. // // In the following sample, tests from test case FooTest are instantiated // each three times with parameter values 3, 5, and 8: // // class FooTest : public TestWithParam { ... }; // // TEST_P(FooTest, TestThis) { // } // TEST_P(FooTest, TestThat) { // } // INSTANTIATE_TEST_CASE_P(TestSequence, FooTest, Values(3, 5, 8)); // // Range() returns generators providing sequences of values in a range. // // Synopsis: // Range(start, end) // - returns a generator producing a sequence of values {start, start+1, // start+2, ..., }. // Range(start, end, step) // - returns a generator producing a sequence of values {start, start+step, // start+step+step, ..., }. // Notes: // * The generated sequences never include end. For example, Range(1, 5) // returns a generator producing a sequence {1, 2, 3, 4}. Range(1, 9, 2) // returns a generator producing {1, 3, 5, 7}. // * start and end must have the same type. That type may be any integral or // floating-point type or a user defined type satisfying these conditions: // * It must be assignable (have operator=() defined). // * It must have operator+() (operator+(int-compatible type) for // two-operand version). // * It must have operator<() defined. // Elements in the resulting sequences will also have that type. // * Condition start < end must be satisfied in order for resulting sequences // to contain any elements. // template internal::ParamGenerator Range(T start, T end, IncrementT step) { return internal::ParamGenerator( new internal::RangeGenerator(start, end, step)); } template internal::ParamGenerator Range(T start, T end) { return Range(start, end, 1); } // ValuesIn() function allows generation of tests with parameters coming from // a container. // // Synopsis: // ValuesIn(const T (&array)[N]) // - returns a generator producing sequences with elements from // a C-style array. // ValuesIn(const Container& container) // - returns a generator producing sequences with elements from // an STL-style container. // ValuesIn(Iterator begin, Iterator end) // - returns a generator producing sequences with elements from // a range [begin, end) defined by a pair of STL-style iterators. These // iterators can also be plain C pointers. // // Please note that ValuesIn copies the values from the containers // passed in and keeps them to generate tests in RUN_ALL_TESTS(). // // Examples: // // This instantiates tests from test case StringTest // each with C-string values of "foo", "bar", and "baz": // // const char* strings[] = {"foo", "bar", "baz"}; // INSTANTIATE_TEST_CASE_P(StringSequence, SrtingTest, ValuesIn(strings)); // // This instantiates tests from test case StlStringTest // each with STL strings with values "a" and "b": // // ::std::vector< ::std::string> GetParameterStrings() { // ::std::vector< ::std::string> v; // v.push_back("a"); // v.push_back("b"); // return v; // } // // INSTANTIATE_TEST_CASE_P(CharSequence, // StlStringTest, // ValuesIn(GetParameterStrings())); // // // This will also instantiate tests from CharTest // each with parameter values 'a' and 'b': // // ::std::list GetParameterChars() { // ::std::list list; // list.push_back('a'); // list.push_back('b'); // return list; // } // ::std::list l = GetParameterChars(); // INSTANTIATE_TEST_CASE_P(CharSequence2, // CharTest, // ValuesIn(l.begin(), l.end())); // template internal::ParamGenerator< typename ::testing::internal::IteratorTraits::value_type> ValuesIn(ForwardIterator begin, ForwardIterator end) { typedef typename ::testing::internal::IteratorTraits ::value_type ParamType; return internal::ParamGenerator( new internal::ValuesInIteratorRangeGenerator(begin, end)); } template internal::ParamGenerator ValuesIn(const T (&array)[N]) { return ValuesIn(array, array + N); } template internal::ParamGenerator ValuesIn( const Container& container) { return ValuesIn(container.begin(), container.end()); } // Values() allows generating tests from explicitly specified list of // parameters. // // Synopsis: // Values(T v1, T v2, ..., T vN) // - returns a generator producing sequences with elements v1, v2, ..., vN. // // For example, this instantiates tests from test case BarTest each // with values "one", "two", and "three": // // INSTANTIATE_TEST_CASE_P(NumSequence, BarTest, Values("one", "two", "three")); // // This instantiates tests from test case BazTest each with values 1, 2, 3.5. // The exact type of values will depend on the type of parameter in BazTest. // // INSTANTIATE_TEST_CASE_P(FloatingNumbers, BazTest, Values(1, 2, 3.5)); // // Currently, Values() supports from 1 to 50 parameters. // template internal::ValueArray1 Values(T1 v1) { return internal::ValueArray1(v1); } template internal::ValueArray2 Values(T1 v1, T2 v2) { return internal::ValueArray2(v1, v2); } template internal::ValueArray3 Values(T1 v1, T2 v2, T3 v3) { return internal::ValueArray3(v1, v2, v3); } template internal::ValueArray4 Values(T1 v1, T2 v2, T3 v3, T4 v4) { return internal::ValueArray4(v1, v2, v3, v4); } template internal::ValueArray5 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5) { return internal::ValueArray5(v1, v2, v3, v4, v5); } template internal::ValueArray6 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6) { return internal::ValueArray6(v1, v2, v3, v4, v5, v6); } template internal::ValueArray7 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7) { return internal::ValueArray7(v1, v2, v3, v4, v5, v6, v7); } template internal::ValueArray8 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8) { return internal::ValueArray8(v1, v2, v3, v4, v5, v6, v7, v8); } template internal::ValueArray9 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9) { return internal::ValueArray9(v1, v2, v3, v4, v5, v6, v7, v8, v9); } template internal::ValueArray10 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10) { return internal::ValueArray10(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10); } template internal::ValueArray11 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11) { return internal::ValueArray11(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11); } template internal::ValueArray12 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12) { return internal::ValueArray12(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12); } template internal::ValueArray13 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13) { return internal::ValueArray13(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13); } template internal::ValueArray14 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14) { return internal::ValueArray14(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14); } template internal::ValueArray15 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15) { return internal::ValueArray15(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15); } template internal::ValueArray16 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16) { return internal::ValueArray16(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16); } template internal::ValueArray17 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17) { return internal::ValueArray17(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17); } template internal::ValueArray18 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18) { return internal::ValueArray18(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18); } template internal::ValueArray19 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19) { return internal::ValueArray19(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19); } template internal::ValueArray20 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20) { return internal::ValueArray20(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20); } template internal::ValueArray21 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21) { return internal::ValueArray21(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21); } template internal::ValueArray22 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22) { return internal::ValueArray22(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22); } template internal::ValueArray23 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23) { return internal::ValueArray23(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23); } template internal::ValueArray24 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24) { return internal::ValueArray24(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24); } template internal::ValueArray25 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25) { return internal::ValueArray25(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25); } template internal::ValueArray26 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26) { return internal::ValueArray26(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26); } template internal::ValueArray27 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27) { return internal::ValueArray27(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27); } template internal::ValueArray28 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28) { return internal::ValueArray28(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28); } template internal::ValueArray29 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29) { return internal::ValueArray29(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29); } template internal::ValueArray30 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30) { return internal::ValueArray30(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30); } template internal::ValueArray31 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31) { return internal::ValueArray31(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31); } template internal::ValueArray32 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32) { return internal::ValueArray32(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32); } template internal::ValueArray33 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33) { return internal::ValueArray33(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33); } template internal::ValueArray34 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34) { return internal::ValueArray34(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34); } template internal::ValueArray35 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35) { return internal::ValueArray35(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35); } template internal::ValueArray36 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36) { return internal::ValueArray36(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36); } template internal::ValueArray37 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37) { return internal::ValueArray37(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37); } template internal::ValueArray38 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38) { return internal::ValueArray38(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38); } template internal::ValueArray39 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39) { return internal::ValueArray39(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39); } template internal::ValueArray40 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40) { return internal::ValueArray40(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40); } template internal::ValueArray41 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41) { return internal::ValueArray41(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41); } template internal::ValueArray42 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, T42 v42) { return internal::ValueArray42(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42); } template internal::ValueArray43 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, T42 v42, T43 v43) { return internal::ValueArray43(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43); } template internal::ValueArray44 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, T42 v42, T43 v43, T44 v44) { return internal::ValueArray44(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44); } template internal::ValueArray45 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45) { return internal::ValueArray45(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45); } template internal::ValueArray46 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46) { return internal::ValueArray46(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46); } template internal::ValueArray47 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47) { return internal::ValueArray47(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47); } template internal::ValueArray48 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47, T48 v48) { return internal::ValueArray48(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48); } template internal::ValueArray49 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47, T48 v48, T49 v49) { return internal::ValueArray49(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49); } template internal::ValueArray50 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47, T48 v48, T49 v49, T50 v50) { return internal::ValueArray50(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50); } // Bool() allows generating tests with parameters in a set of (false, true). // // Synopsis: // Bool() // - returns a generator producing sequences with elements {false, true}. // // It is useful when testing code that depends on Boolean flags. Combinations // of multiple flags can be tested when several Bool()'s are combined using // Combine() function. // // In the following example all tests in the test case FlagDependentTest // will be instantiated twice with parameters false and true. // // class FlagDependentTest : public testing::TestWithParam { // virtual void SetUp() { // external_flag = GetParam(); // } // } // INSTANTIATE_TEST_CASE_P(BoolSequence, FlagDependentTest, Bool()); // inline internal::ParamGenerator Bool() { return Values(false, true); } # if GTEST_HAS_COMBINE // Combine() allows the user to combine two or more sequences to produce // values of a Cartesian product of those sequences' elements. // // Synopsis: // Combine(gen1, gen2, ..., genN) // - returns a generator producing sequences with elements coming from // the Cartesian product of elements from the sequences generated by // gen1, gen2, ..., genN. The sequence elements will have a type of // tuple where T1, T2, ..., TN are the types // of elements from sequences produces by gen1, gen2, ..., genN. // // Combine can have up to 10 arguments. This number is currently limited // by the maximum number of elements in the tuple implementation used by Google // Test. // // Example: // // This will instantiate tests in test case AnimalTest each one with // the parameter values tuple("cat", BLACK), tuple("cat", WHITE), // tuple("dog", BLACK), and tuple("dog", WHITE): // // enum Color { BLACK, GRAY, WHITE }; // class AnimalTest // : public testing::TestWithParam > {...}; // // TEST_P(AnimalTest, AnimalLooksNice) {...} // // INSTANTIATE_TEST_CASE_P(AnimalVariations, AnimalTest, // Combine(Values("cat", "dog"), // Values(BLACK, WHITE))); // // This will instantiate tests in FlagDependentTest with all variations of two // Boolean flags: // // class FlagDependentTest // : public testing::TestWithParam > { // virtual void SetUp() { // // Assigns external_flag_1 and external_flag_2 values from the tuple. // tie(external_flag_1, external_flag_2) = GetParam(); // } // }; // // TEST_P(FlagDependentTest, TestFeature1) { // // Test your code using external_flag_1 and external_flag_2 here. // } // INSTANTIATE_TEST_CASE_P(TwoBoolSequence, FlagDependentTest, // Combine(Bool(), Bool())); // template internal::CartesianProductHolder2 Combine( const Generator1& g1, const Generator2& g2) { return internal::CartesianProductHolder2( g1, g2); } template internal::CartesianProductHolder3 Combine( const Generator1& g1, const Generator2& g2, const Generator3& g3) { return internal::CartesianProductHolder3( g1, g2, g3); } template internal::CartesianProductHolder4 Combine( const Generator1& g1, const Generator2& g2, const Generator3& g3, const Generator4& g4) { return internal::CartesianProductHolder4( g1, g2, g3, g4); } template internal::CartesianProductHolder5 Combine( const Generator1& g1, const Generator2& g2, const Generator3& g3, const Generator4& g4, const Generator5& g5) { return internal::CartesianProductHolder5( g1, g2, g3, g4, g5); } template internal::CartesianProductHolder6 Combine( const Generator1& g1, const Generator2& g2, const Generator3& g3, const Generator4& g4, const Generator5& g5, const Generator6& g6) { return internal::CartesianProductHolder6( g1, g2, g3, g4, g5, g6); } template internal::CartesianProductHolder7 Combine( const Generator1& g1, const Generator2& g2, const Generator3& g3, const Generator4& g4, const Generator5& g5, const Generator6& g6, const Generator7& g7) { return internal::CartesianProductHolder7( g1, g2, g3, g4, g5, g6, g7); } template internal::CartesianProductHolder8 Combine( const Generator1& g1, const Generator2& g2, const Generator3& g3, const Generator4& g4, const Generator5& g5, const Generator6& g6, const Generator7& g7, const Generator8& g8) { return internal::CartesianProductHolder8( g1, g2, g3, g4, g5, g6, g7, g8); } template internal::CartesianProductHolder9 Combine( const Generator1& g1, const Generator2& g2, const Generator3& g3, const Generator4& g4, const Generator5& g5, const Generator6& g6, const Generator7& g7, const Generator8& g8, const Generator9& g9) { return internal::CartesianProductHolder9( g1, g2, g3, g4, g5, g6, g7, g8, g9); } template internal::CartesianProductHolder10 Combine( const Generator1& g1, const Generator2& g2, const Generator3& g3, const Generator4& g4, const Generator5& g5, const Generator6& g6, const Generator7& g7, const Generator8& g8, const Generator9& g9, const Generator10& g10) { return internal::CartesianProductHolder10( g1, g2, g3, g4, g5, g6, g7, g8, g9, g10); } # endif // GTEST_HAS_COMBINE # define TEST_P(test_case_name, test_name) \ class GTEST_TEST_CLASS_NAME_(test_case_name, test_name) \ : public test_case_name { \ public: \ GTEST_TEST_CLASS_NAME_(test_case_name, test_name)() {} \ virtual void TestBody(); \ private: \ static int AddToRegistry() { \ ::testing::UnitTest::GetInstance()->parameterized_test_registry(). \ GetTestCasePatternHolder(\ #test_case_name, __FILE__, __LINE__)->AddTestPattern(\ #test_case_name, \ #test_name, \ new ::testing::internal::TestMetaFactory< \ GTEST_TEST_CLASS_NAME_(test_case_name, test_name)>()); \ return 0; \ } \ static int gtest_registering_dummy_; \ GTEST_DISALLOW_COPY_AND_ASSIGN_(\ GTEST_TEST_CLASS_NAME_(test_case_name, test_name)); \ }; \ int GTEST_TEST_CLASS_NAME_(test_case_name, \ test_name)::gtest_registering_dummy_ = \ GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::AddToRegistry(); \ void GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::TestBody() # define INSTANTIATE_TEST_CASE_P(prefix, test_case_name, generator) \ ::testing::internal::ParamGenerator \ gtest_##prefix##test_case_name##_EvalGenerator_() { return generator; } \ int gtest_##prefix##test_case_name##_dummy_ = \ ::testing::UnitTest::GetInstance()->parameterized_test_registry(). \ GetTestCasePatternHolder(\ #test_case_name, __FILE__, __LINE__)->AddTestCaseInstantiation(\ #prefix, \ >est_##prefix##test_case_name##_EvalGenerator_, \ __FILE__, __LINE__) } // namespace testing #endif // GTEST_HAS_PARAM_TEST #endif // GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_ dlt-daemon-2.18.4/gtest-1.7.0/include/gtest/gtest-param-test.h.pump000066400000000000000000000445541353342203500245400ustar00rootroot00000000000000$$ -*- mode: c++; -*- $var n = 50 $$ Maximum length of Values arguments we want to support. $var maxtuple = 10 $$ Maximum number of Combine arguments we want to support. // Copyright 2008, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Authors: vladl@google.com (Vlad Losev) // // Macros and functions for implementing parameterized tests // in Google C++ Testing Framework (Google Test) // // This file is generated by a SCRIPT. DO NOT EDIT BY HAND! // #ifndef GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_ #define GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_ // Value-parameterized tests allow you to test your code with different // parameters without writing multiple copies of the same test. // // Here is how you use value-parameterized tests: #if 0 // To write value-parameterized tests, first you should define a fixture // class. It is usually derived from testing::TestWithParam (see below for // another inheritance scheme that's sometimes useful in more complicated // class hierarchies), where the type of your parameter values. // TestWithParam is itself derived from testing::Test. T can be any // copyable type. If it's a raw pointer, you are responsible for managing the // lifespan of the pointed values. class FooTest : public ::testing::TestWithParam { // You can implement all the usual class fixture members here. }; // Then, use the TEST_P macro to define as many parameterized tests // for this fixture as you want. The _P suffix is for "parameterized" // or "pattern", whichever you prefer to think. TEST_P(FooTest, DoesBlah) { // Inside a test, access the test parameter with the GetParam() method // of the TestWithParam class: EXPECT_TRUE(foo.Blah(GetParam())); ... } TEST_P(FooTest, HasBlahBlah) { ... } // Finally, you can use INSTANTIATE_TEST_CASE_P to instantiate the test // case with any set of parameters you want. Google Test defines a number // of functions for generating test parameters. They return what we call // (surprise!) parameter generators. Here is a summary of them, which // are all in the testing namespace: // // // Range(begin, end [, step]) - Yields values {begin, begin+step, // begin+step+step, ...}. The values do not // include end. step defaults to 1. // Values(v1, v2, ..., vN) - Yields values {v1, v2, ..., vN}. // ValuesIn(container) - Yields values from a C-style array, an STL // ValuesIn(begin,end) container, or an iterator range [begin, end). // Bool() - Yields sequence {false, true}. // Combine(g1, g2, ..., gN) - Yields all combinations (the Cartesian product // for the math savvy) of the values generated // by the N generators. // // For more details, see comments at the definitions of these functions below // in this file. // // The following statement will instantiate tests from the FooTest test case // each with parameter values "meeny", "miny", and "moe". INSTANTIATE_TEST_CASE_P(InstantiationName, FooTest, Values("meeny", "miny", "moe")); // To distinguish different instances of the pattern, (yes, you // can instantiate it more then once) the first argument to the // INSTANTIATE_TEST_CASE_P macro is a prefix that will be added to the // actual test case name. Remember to pick unique prefixes for different // instantiations. The tests from the instantiation above will have // these names: // // * InstantiationName/FooTest.DoesBlah/0 for "meeny" // * InstantiationName/FooTest.DoesBlah/1 for "miny" // * InstantiationName/FooTest.DoesBlah/2 for "moe" // * InstantiationName/FooTest.HasBlahBlah/0 for "meeny" // * InstantiationName/FooTest.HasBlahBlah/1 for "miny" // * InstantiationName/FooTest.HasBlahBlah/2 for "moe" // // You can use these names in --gtest_filter. // // This statement will instantiate all tests from FooTest again, each // with parameter values "cat" and "dog": const char* pets[] = {"cat", "dog"}; INSTANTIATE_TEST_CASE_P(AnotherInstantiationName, FooTest, ValuesIn(pets)); // The tests from the instantiation above will have these names: // // * AnotherInstantiationName/FooTest.DoesBlah/0 for "cat" // * AnotherInstantiationName/FooTest.DoesBlah/1 for "dog" // * AnotherInstantiationName/FooTest.HasBlahBlah/0 for "cat" // * AnotherInstantiationName/FooTest.HasBlahBlah/1 for "dog" // // Please note that INSTANTIATE_TEST_CASE_P will instantiate all tests // in the given test case, whether their definitions come before or // AFTER the INSTANTIATE_TEST_CASE_P statement. // // Please also note that generator expressions (including parameters to the // generators) are evaluated in InitGoogleTest(), after main() has started. // This allows the user on one hand, to adjust generator parameters in order // to dynamically determine a set of tests to run and on the other hand, // give the user a chance to inspect the generated tests with Google Test // reflection API before RUN_ALL_TESTS() is executed. // // You can see samples/sample7_unittest.cc and samples/sample8_unittest.cc // for more examples. // // In the future, we plan to publish the API for defining new parameter // generators. But for now this interface remains part of the internal // implementation and is subject to change. // // // A parameterized test fixture must be derived from testing::Test and from // testing::WithParamInterface, where T is the type of the parameter // values. Inheriting from TestWithParam satisfies that requirement because // TestWithParam inherits from both Test and WithParamInterface. In more // complicated hierarchies, however, it is occasionally useful to inherit // separately from Test and WithParamInterface. For example: class BaseTest : public ::testing::Test { // You can inherit all the usual members for a non-parameterized test // fixture here. }; class DerivedTest : public BaseTest, public ::testing::WithParamInterface { // The usual test fixture members go here too. }; TEST_F(BaseTest, HasFoo) { // This is an ordinary non-parameterized test. } TEST_P(DerivedTest, DoesBlah) { // GetParam works just the same here as if you inherit from TestWithParam. EXPECT_TRUE(foo.Blah(GetParam())); } #endif // 0 #include "gtest/internal/gtest-port.h" #if !GTEST_OS_SYMBIAN # include #endif // scripts/fuse_gtest.py depends on gtest's own header being #included // *unconditionally*. Therefore these #includes cannot be moved // inside #if GTEST_HAS_PARAM_TEST. #include "gtest/internal/gtest-internal.h" #include "gtest/internal/gtest-param-util.h" #include "gtest/internal/gtest-param-util-generated.h" #if GTEST_HAS_PARAM_TEST namespace testing { // Functions producing parameter generators. // // Google Test uses these generators to produce parameters for value- // parameterized tests. When a parameterized test case is instantiated // with a particular generator, Google Test creates and runs tests // for each element in the sequence produced by the generator. // // In the following sample, tests from test case FooTest are instantiated // each three times with parameter values 3, 5, and 8: // // class FooTest : public TestWithParam { ... }; // // TEST_P(FooTest, TestThis) { // } // TEST_P(FooTest, TestThat) { // } // INSTANTIATE_TEST_CASE_P(TestSequence, FooTest, Values(3, 5, 8)); // // Range() returns generators providing sequences of values in a range. // // Synopsis: // Range(start, end) // - returns a generator producing a sequence of values {start, start+1, // start+2, ..., }. // Range(start, end, step) // - returns a generator producing a sequence of values {start, start+step, // start+step+step, ..., }. // Notes: // * The generated sequences never include end. For example, Range(1, 5) // returns a generator producing a sequence {1, 2, 3, 4}. Range(1, 9, 2) // returns a generator producing {1, 3, 5, 7}. // * start and end must have the same type. That type may be any integral or // floating-point type or a user defined type satisfying these conditions: // * It must be assignable (have operator=() defined). // * It must have operator+() (operator+(int-compatible type) for // two-operand version). // * It must have operator<() defined. // Elements in the resulting sequences will also have that type. // * Condition start < end must be satisfied in order for resulting sequences // to contain any elements. // template internal::ParamGenerator Range(T start, T end, IncrementT step) { return internal::ParamGenerator( new internal::RangeGenerator(start, end, step)); } template internal::ParamGenerator Range(T start, T end) { return Range(start, end, 1); } // ValuesIn() function allows generation of tests with parameters coming from // a container. // // Synopsis: // ValuesIn(const T (&array)[N]) // - returns a generator producing sequences with elements from // a C-style array. // ValuesIn(const Container& container) // - returns a generator producing sequences with elements from // an STL-style container. // ValuesIn(Iterator begin, Iterator end) // - returns a generator producing sequences with elements from // a range [begin, end) defined by a pair of STL-style iterators. These // iterators can also be plain C pointers. // // Please note that ValuesIn copies the values from the containers // passed in and keeps them to generate tests in RUN_ALL_TESTS(). // // Examples: // // This instantiates tests from test case StringTest // each with C-string values of "foo", "bar", and "baz": // // const char* strings[] = {"foo", "bar", "baz"}; // INSTANTIATE_TEST_CASE_P(StringSequence, SrtingTest, ValuesIn(strings)); // // This instantiates tests from test case StlStringTest // each with STL strings with values "a" and "b": // // ::std::vector< ::std::string> GetParameterStrings() { // ::std::vector< ::std::string> v; // v.push_back("a"); // v.push_back("b"); // return v; // } // // INSTANTIATE_TEST_CASE_P(CharSequence, // StlStringTest, // ValuesIn(GetParameterStrings())); // // // This will also instantiate tests from CharTest // each with parameter values 'a' and 'b': // // ::std::list GetParameterChars() { // ::std::list list; // list.push_back('a'); // list.push_back('b'); // return list; // } // ::std::list l = GetParameterChars(); // INSTANTIATE_TEST_CASE_P(CharSequence2, // CharTest, // ValuesIn(l.begin(), l.end())); // template internal::ParamGenerator< typename ::testing::internal::IteratorTraits::value_type> ValuesIn(ForwardIterator begin, ForwardIterator end) { typedef typename ::testing::internal::IteratorTraits ::value_type ParamType; return internal::ParamGenerator( new internal::ValuesInIteratorRangeGenerator(begin, end)); } template internal::ParamGenerator ValuesIn(const T (&array)[N]) { return ValuesIn(array, array + N); } template internal::ParamGenerator ValuesIn( const Container& container) { return ValuesIn(container.begin(), container.end()); } // Values() allows generating tests from explicitly specified list of // parameters. // // Synopsis: // Values(T v1, T v2, ..., T vN) // - returns a generator producing sequences with elements v1, v2, ..., vN. // // For example, this instantiates tests from test case BarTest each // with values "one", "two", and "three": // // INSTANTIATE_TEST_CASE_P(NumSequence, BarTest, Values("one", "two", "three")); // // This instantiates tests from test case BazTest each with values 1, 2, 3.5. // The exact type of values will depend on the type of parameter in BazTest. // // INSTANTIATE_TEST_CASE_P(FloatingNumbers, BazTest, Values(1, 2, 3.5)); // // Currently, Values() supports from 1 to $n parameters. // $range i 1..n $for i [[ $range j 1..i template <$for j, [[typename T$j]]> internal::ValueArray$i<$for j, [[T$j]]> Values($for j, [[T$j v$j]]) { return internal::ValueArray$i<$for j, [[T$j]]>($for j, [[v$j]]); } ]] // Bool() allows generating tests with parameters in a set of (false, true). // // Synopsis: // Bool() // - returns a generator producing sequences with elements {false, true}. // // It is useful when testing code that depends on Boolean flags. Combinations // of multiple flags can be tested when several Bool()'s are combined using // Combine() function. // // In the following example all tests in the test case FlagDependentTest // will be instantiated twice with parameters false and true. // // class FlagDependentTest : public testing::TestWithParam { // virtual void SetUp() { // external_flag = GetParam(); // } // } // INSTANTIATE_TEST_CASE_P(BoolSequence, FlagDependentTest, Bool()); // inline internal::ParamGenerator Bool() { return Values(false, true); } # if GTEST_HAS_COMBINE // Combine() allows the user to combine two or more sequences to produce // values of a Cartesian product of those sequences' elements. // // Synopsis: // Combine(gen1, gen2, ..., genN) // - returns a generator producing sequences with elements coming from // the Cartesian product of elements from the sequences generated by // gen1, gen2, ..., genN. The sequence elements will have a type of // tuple where T1, T2, ..., TN are the types // of elements from sequences produces by gen1, gen2, ..., genN. // // Combine can have up to $maxtuple arguments. This number is currently limited // by the maximum number of elements in the tuple implementation used by Google // Test. // // Example: // // This will instantiate tests in test case AnimalTest each one with // the parameter values tuple("cat", BLACK), tuple("cat", WHITE), // tuple("dog", BLACK), and tuple("dog", WHITE): // // enum Color { BLACK, GRAY, WHITE }; // class AnimalTest // : public testing::TestWithParam > {...}; // // TEST_P(AnimalTest, AnimalLooksNice) {...} // // INSTANTIATE_TEST_CASE_P(AnimalVariations, AnimalTest, // Combine(Values("cat", "dog"), // Values(BLACK, WHITE))); // // This will instantiate tests in FlagDependentTest with all variations of two // Boolean flags: // // class FlagDependentTest // : public testing::TestWithParam > { // virtual void SetUp() { // // Assigns external_flag_1 and external_flag_2 values from the tuple. // tie(external_flag_1, external_flag_2) = GetParam(); // } // }; // // TEST_P(FlagDependentTest, TestFeature1) { // // Test your code using external_flag_1 and external_flag_2 here. // } // INSTANTIATE_TEST_CASE_P(TwoBoolSequence, FlagDependentTest, // Combine(Bool(), Bool())); // $range i 2..maxtuple $for i [[ $range j 1..i template <$for j, [[typename Generator$j]]> internal::CartesianProductHolder$i<$for j, [[Generator$j]]> Combine( $for j, [[const Generator$j& g$j]]) { return internal::CartesianProductHolder$i<$for j, [[Generator$j]]>( $for j, [[g$j]]); } ]] # endif // GTEST_HAS_COMBINE # define TEST_P(test_case_name, test_name) \ class GTEST_TEST_CLASS_NAME_(test_case_name, test_name) \ : public test_case_name { \ public: \ GTEST_TEST_CLASS_NAME_(test_case_name, test_name)() {} \ virtual void TestBody(); \ private: \ static int AddToRegistry() { \ ::testing::UnitTest::GetInstance()->parameterized_test_registry(). \ GetTestCasePatternHolder(\ #test_case_name, __FILE__, __LINE__)->AddTestPattern(\ #test_case_name, \ #test_name, \ new ::testing::internal::TestMetaFactory< \ GTEST_TEST_CLASS_NAME_(test_case_name, test_name)>()); \ return 0; \ } \ static int gtest_registering_dummy_; \ GTEST_DISALLOW_COPY_AND_ASSIGN_(\ GTEST_TEST_CLASS_NAME_(test_case_name, test_name)); \ }; \ int GTEST_TEST_CLASS_NAME_(test_case_name, \ test_name)::gtest_registering_dummy_ = \ GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::AddToRegistry(); \ void GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::TestBody() # define INSTANTIATE_TEST_CASE_P(prefix, test_case_name, generator) \ ::testing::internal::ParamGenerator \ gtest_##prefix##test_case_name##_EvalGenerator_() { return generator; } \ int gtest_##prefix##test_case_name##_dummy_ = \ ::testing::UnitTest::GetInstance()->parameterized_test_registry(). \ GetTestCasePatternHolder(\ #test_case_name, __FILE__, __LINE__)->AddTestCaseInstantiation(\ #prefix, \ >est_##prefix##test_case_name##_EvalGenerator_, \ __FILE__, __LINE__) } // namespace testing #endif // GTEST_HAS_PARAM_TEST #endif // GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_ dlt-daemon-2.18.4/gtest-1.7.0/include/gtest/gtest-printers.h000066400000000000000000000755711353342203500233540ustar00rootroot00000000000000// Copyright 2007, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: wan@google.com (Zhanyong Wan) // Google Test - The Google C++ Testing Framework // // This file implements a universal value printer that can print a // value of any type T: // // void ::testing::internal::UniversalPrinter::Print(value, ostream_ptr); // // A user can teach this function how to print a class type T by // defining either operator<<() or PrintTo() in the namespace that // defines T. More specifically, the FIRST defined function in the // following list will be used (assuming T is defined in namespace // foo): // // 1. foo::PrintTo(const T&, ostream*) // 2. operator<<(ostream&, const T&) defined in either foo or the // global namespace. // // If none of the above is defined, it will print the debug string of // the value if it is a protocol buffer, or print the raw bytes in the // value otherwise. // // To aid debugging: when T is a reference type, the address of the // value is also printed; when T is a (const) char pointer, both the // pointer value and the NUL-terminated string it points to are // printed. // // We also provide some convenient wrappers: // // // Prints a value to a string. For a (const or not) char // // pointer, the NUL-terminated string (but not the pointer) is // // printed. // std::string ::testing::PrintToString(const T& value); // // // Prints a value tersely: for a reference type, the referenced // // value (but not the address) is printed; for a (const or not) char // // pointer, the NUL-terminated string (but not the pointer) is // // printed. // void ::testing::internal::UniversalTersePrint(const T& value, ostream*); // // // Prints value using the type inferred by the compiler. The difference // // from UniversalTersePrint() is that this function prints both the // // pointer and the NUL-terminated string for a (const or not) char pointer. // void ::testing::internal::UniversalPrint(const T& value, ostream*); // // // Prints the fields of a tuple tersely to a string vector, one // // element for each field. Tuple support must be enabled in // // gtest-port.h. // std::vector UniversalTersePrintTupleFieldsToStrings( // const Tuple& value); // // Known limitation: // // The print primitives print the elements of an STL-style container // using the compiler-inferred type of *iter where iter is a // const_iterator of the container. When const_iterator is an input // iterator but not a forward iterator, this inferred type may not // match value_type, and the print output may be incorrect. In // practice, this is rarely a problem as for most containers // const_iterator is a forward iterator. We'll fix this if there's an // actual need for it. Note that this fix cannot rely on value_type // being defined as many user-defined container types don't have // value_type. #ifndef GTEST_INCLUDE_GTEST_GTEST_PRINTERS_H_ #define GTEST_INCLUDE_GTEST_GTEST_PRINTERS_H_ #include // NOLINT #include #include #include #include #include "gtest/internal/gtest-port.h" #include "gtest/internal/gtest-internal.h" namespace testing { // Definitions in the 'internal' and 'internal2' name spaces are // subject to change without notice. DO NOT USE THEM IN USER CODE! namespace internal2 { // Prints the given number of bytes in the given object to the given // ostream. GTEST_API_ void PrintBytesInObjectTo(const unsigned char* obj_bytes, size_t count, ::std::ostream* os); // For selecting which printer to use when a given type has neither << // nor PrintTo(). enum TypeKind { kProtobuf, // a protobuf type kConvertibleToInteger, // a type implicitly convertible to BiggestInt // (e.g. a named or unnamed enum type) kOtherType // anything else }; // TypeWithoutFormatter::PrintValue(value, os) is called // by the universal printer to print a value of type T when neither // operator<< nor PrintTo() is defined for T, where kTypeKind is the // "kind" of T as defined by enum TypeKind. template class TypeWithoutFormatter { public: // This default version is called when kTypeKind is kOtherType. static void PrintValue(const T& value, ::std::ostream* os) { PrintBytesInObjectTo(reinterpret_cast(&value), sizeof(value), os); } }; // We print a protobuf using its ShortDebugString() when the string // doesn't exceed this many characters; otherwise we print it using // DebugString() for better readability. const size_t kProtobufOneLinerMaxLength = 50; template class TypeWithoutFormatter { public: static void PrintValue(const T& value, ::std::ostream* os) { const ::testing::internal::string short_str = value.ShortDebugString(); const ::testing::internal::string pretty_str = short_str.length() <= kProtobufOneLinerMaxLength ? short_str : ("\n" + value.DebugString()); *os << ("<" + pretty_str + ">"); } }; template class TypeWithoutFormatter { public: // Since T has no << operator or PrintTo() but can be implicitly // converted to BiggestInt, we print it as a BiggestInt. // // Most likely T is an enum type (either named or unnamed), in which // case printing it as an integer is the desired behavior. In case // T is not an enum, printing it as an integer is the best we can do // given that it has no user-defined printer. static void PrintValue(const T& value, ::std::ostream* os) { const internal::BiggestInt kBigInt = value; *os << kBigInt; } }; // Prints the given value to the given ostream. If the value is a // protocol message, its debug string is printed; if it's an enum or // of a type implicitly convertible to BiggestInt, it's printed as an // integer; otherwise the bytes in the value are printed. This is // what UniversalPrinter::Print() does when it knows nothing about // type T and T has neither << operator nor PrintTo(). // // A user can override this behavior for a class type Foo by defining // a << operator in the namespace where Foo is defined. // // We put this operator in namespace 'internal2' instead of 'internal' // to simplify the implementation, as much code in 'internal' needs to // use << in STL, which would conflict with our own << were it defined // in 'internal'. // // Note that this operator<< takes a generic std::basic_ostream type instead of the more restricted std::ostream. If // we define it to take an std::ostream instead, we'll get an // "ambiguous overloads" compiler error when trying to print a type // Foo that supports streaming to std::basic_ostream, as the compiler cannot tell whether // operator<<(std::ostream&, const T&) or // operator<<(std::basic_stream, const Foo&) is more // specific. template ::std::basic_ostream& operator<<( ::std::basic_ostream& os, const T& x) { TypeWithoutFormatter::value ? kProtobuf : internal::ImplicitlyConvertible::value ? kConvertibleToInteger : kOtherType)>::PrintValue(x, &os); return os; } } // namespace internal2 } // namespace testing // This namespace MUST NOT BE NESTED IN ::testing, or the name look-up // magic needed for implementing UniversalPrinter won't work. namespace testing_internal { // Used to print a value that is not an STL-style container when the // user doesn't define PrintTo() for it. template void DefaultPrintNonContainerTo(const T& value, ::std::ostream* os) { // With the following statement, during unqualified name lookup, // testing::internal2::operator<< appears as if it was declared in // the nearest enclosing namespace that contains both // ::testing_internal and ::testing::internal2, i.e. the global // namespace. For more details, refer to the C++ Standard section // 7.3.4-1 [namespace.udir]. This allows us to fall back onto // testing::internal2::operator<< in case T doesn't come with a << // operator. // // We cannot write 'using ::testing::internal2::operator<<;', which // gcc 3.3 fails to compile due to a compiler bug. using namespace ::testing::internal2; // NOLINT // Assuming T is defined in namespace foo, in the next statement, // the compiler will consider all of: // // 1. foo::operator<< (thanks to Koenig look-up), // 2. ::operator<< (as the current namespace is enclosed in ::), // 3. testing::internal2::operator<< (thanks to the using statement above). // // The operator<< whose type matches T best will be picked. // // We deliberately allow #2 to be a candidate, as sometimes it's // impossible to define #1 (e.g. when foo is ::std, defining // anything in it is undefined behavior unless you are a compiler // vendor.). *os << value; } } // namespace testing_internal namespace testing { namespace internal { // UniversalPrinter::Print(value, ostream_ptr) prints the given // value to the given ostream. The caller must ensure that // 'ostream_ptr' is not NULL, or the behavior is undefined. // // We define UniversalPrinter as a class template (as opposed to a // function template), as we need to partially specialize it for // reference types, which cannot be done with function templates. template class UniversalPrinter; template void UniversalPrint(const T& value, ::std::ostream* os); // Used to print an STL-style container when the user doesn't define // a PrintTo() for it. template void DefaultPrintTo(IsContainer /* dummy */, false_type /* is not a pointer */, const C& container, ::std::ostream* os) { const size_t kMaxCount = 32; // The maximum number of elements to print. *os << '{'; size_t count = 0; for (typename C::const_iterator it = container.begin(); it != container.end(); ++it, ++count) { if (count > 0) { *os << ','; if (count == kMaxCount) { // Enough has been printed. *os << " ..."; break; } } *os << ' '; // We cannot call PrintTo(*it, os) here as PrintTo() doesn't // handle *it being a native array. internal::UniversalPrint(*it, os); } if (count > 0) { *os << ' '; } *os << '}'; } // Used to print a pointer that is neither a char pointer nor a member // pointer, when the user doesn't define PrintTo() for it. (A member // variable pointer or member function pointer doesn't really point to // a location in the address space. Their representation is // implementation-defined. Therefore they will be printed as raw // bytes.) template void DefaultPrintTo(IsNotContainer /* dummy */, true_type /* is a pointer */, T* p, ::std::ostream* os) { if (p == NULL) { *os << "NULL"; } else { // C++ doesn't allow casting from a function pointer to any object // pointer. // // IsTrue() silences warnings: "Condition is always true", // "unreachable code". if (IsTrue(ImplicitlyConvertible::value)) { // T is not a function type. We just call << to print p, // relying on ADL to pick up user-defined << for their pointer // types, if any. *os << p; } else { // T is a function type, so '*os << p' doesn't do what we want // (it just prints p as bool). We want to print p as a const // void*. However, we cannot cast it to const void* directly, // even using reinterpret_cast, as earlier versions of gcc // (e.g. 3.4.5) cannot compile the cast when p is a function // pointer. Casting to UInt64 first solves the problem. *os << reinterpret_cast( reinterpret_cast(p)); } } } // Used to print a non-container, non-pointer value when the user // doesn't define PrintTo() for it. template void DefaultPrintTo(IsNotContainer /* dummy */, false_type /* is not a pointer */, const T& value, ::std::ostream* os) { ::testing_internal::DefaultPrintNonContainerTo(value, os); } // Prints the given value using the << operator if it has one; // otherwise prints the bytes in it. This is what // UniversalPrinter::Print() does when PrintTo() is not specialized // or overloaded for type T. // // A user can override this behavior for a class type Foo by defining // an overload of PrintTo() in the namespace where Foo is defined. We // give the user this option as sometimes defining a << operator for // Foo is not desirable (e.g. the coding style may prevent doing it, // or there is already a << operator but it doesn't do what the user // wants). template void PrintTo(const T& value, ::std::ostream* os) { // DefaultPrintTo() is overloaded. The type of its first two // arguments determine which version will be picked. If T is an // STL-style container, the version for container will be called; if // T is a pointer, the pointer version will be called; otherwise the // generic version will be called. // // Note that we check for container types here, prior to we check // for protocol message types in our operator<<. The rationale is: // // For protocol messages, we want to give people a chance to // override Google Mock's format by defining a PrintTo() or // operator<<. For STL containers, other formats can be // incompatible with Google Mock's format for the container // elements; therefore we check for container types here to ensure // that our format is used. // // The second argument of DefaultPrintTo() is needed to bypass a bug // in Symbian's C++ compiler that prevents it from picking the right // overload between: // // PrintTo(const T& x, ...); // PrintTo(T* x, ...); DefaultPrintTo(IsContainerTest(0), is_pointer(), value, os); } // The following list of PrintTo() overloads tells // UniversalPrinter::Print() how to print standard types (built-in // types, strings, plain arrays, and pointers). // Overloads for various char types. GTEST_API_ void PrintTo(unsigned char c, ::std::ostream* os); GTEST_API_ void PrintTo(signed char c, ::std::ostream* os); inline void PrintTo(char c, ::std::ostream* os) { // When printing a plain char, we always treat it as unsigned. This // way, the output won't be affected by whether the compiler thinks // char is signed or not. PrintTo(static_cast(c), os); } // Overloads for other simple built-in types. inline void PrintTo(bool x, ::std::ostream* os) { *os << (x ? "true" : "false"); } // Overload for wchar_t type. // Prints a wchar_t as a symbol if it is printable or as its internal // code otherwise and also as its decimal code (except for L'\0'). // The L'\0' char is printed as "L'\\0'". The decimal code is printed // as signed integer when wchar_t is implemented by the compiler // as a signed type and is printed as an unsigned integer when wchar_t // is implemented as an unsigned type. GTEST_API_ void PrintTo(wchar_t wc, ::std::ostream* os); // Overloads for C strings. GTEST_API_ void PrintTo(const char* s, ::std::ostream* os); inline void PrintTo(char* s, ::std::ostream* os) { PrintTo(ImplicitCast_(s), os); } // signed/unsigned char is often used for representing binary data, so // we print pointers to it as void* to be safe. inline void PrintTo(const signed char* s, ::std::ostream* os) { PrintTo(ImplicitCast_(s), os); } inline void PrintTo(signed char* s, ::std::ostream* os) { PrintTo(ImplicitCast_(s), os); } inline void PrintTo(const unsigned char* s, ::std::ostream* os) { PrintTo(ImplicitCast_(s), os); } inline void PrintTo(unsigned char* s, ::std::ostream* os) { PrintTo(ImplicitCast_(s), os); } // MSVC can be configured to define wchar_t as a typedef of unsigned // short. It defines _NATIVE_WCHAR_T_DEFINED when wchar_t is a native // type. When wchar_t is a typedef, defining an overload for const // wchar_t* would cause unsigned short* be printed as a wide string, // possibly causing invalid memory accesses. #if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED) // Overloads for wide C strings GTEST_API_ void PrintTo(const wchar_t* s, ::std::ostream* os); inline void PrintTo(wchar_t* s, ::std::ostream* os) { PrintTo(ImplicitCast_(s), os); } #endif // Overload for C arrays. Multi-dimensional arrays are printed // properly. // Prints the given number of elements in an array, without printing // the curly braces. template void PrintRawArrayTo(const T a[], size_t count, ::std::ostream* os) { UniversalPrint(a[0], os); for (size_t i = 1; i != count; i++) { *os << ", "; UniversalPrint(a[i], os); } } // Overloads for ::string and ::std::string. #if GTEST_HAS_GLOBAL_STRING GTEST_API_ void PrintStringTo(const ::string&s, ::std::ostream* os); inline void PrintTo(const ::string& s, ::std::ostream* os) { PrintStringTo(s, os); } #endif // GTEST_HAS_GLOBAL_STRING GTEST_API_ void PrintStringTo(const ::std::string&s, ::std::ostream* os); inline void PrintTo(const ::std::string& s, ::std::ostream* os) { PrintStringTo(s, os); } // Overloads for ::wstring and ::std::wstring. #if GTEST_HAS_GLOBAL_WSTRING GTEST_API_ void PrintWideStringTo(const ::wstring&s, ::std::ostream* os); inline void PrintTo(const ::wstring& s, ::std::ostream* os) { PrintWideStringTo(s, os); } #endif // GTEST_HAS_GLOBAL_WSTRING #if GTEST_HAS_STD_WSTRING GTEST_API_ void PrintWideStringTo(const ::std::wstring&s, ::std::ostream* os); inline void PrintTo(const ::std::wstring& s, ::std::ostream* os) { PrintWideStringTo(s, os); } #endif // GTEST_HAS_STD_WSTRING #if GTEST_HAS_TR1_TUPLE // Overload for ::std::tr1::tuple. Needed for printing function arguments, // which are packed as tuples. // Helper function for printing a tuple. T must be instantiated with // a tuple type. template void PrintTupleTo(const T& t, ::std::ostream* os); // Overloaded PrintTo() for tuples of various arities. We support // tuples of up-to 10 fields. The following implementation works // regardless of whether tr1::tuple is implemented using the // non-standard variadic template feature or not. inline void PrintTo(const ::std::tr1::tuple<>& t, ::std::ostream* os) { PrintTupleTo(t, os); } template void PrintTo(const ::std::tr1::tuple& t, ::std::ostream* os) { PrintTupleTo(t, os); } template void PrintTo(const ::std::tr1::tuple& t, ::std::ostream* os) { PrintTupleTo(t, os); } template void PrintTo(const ::std::tr1::tuple& t, ::std::ostream* os) { PrintTupleTo(t, os); } template void PrintTo(const ::std::tr1::tuple& t, ::std::ostream* os) { PrintTupleTo(t, os); } template void PrintTo(const ::std::tr1::tuple& t, ::std::ostream* os) { PrintTupleTo(t, os); } template void PrintTo(const ::std::tr1::tuple& t, ::std::ostream* os) { PrintTupleTo(t, os); } template void PrintTo(const ::std::tr1::tuple& t, ::std::ostream* os) { PrintTupleTo(t, os); } template void PrintTo(const ::std::tr1::tuple& t, ::std::ostream* os) { PrintTupleTo(t, os); } template void PrintTo(const ::std::tr1::tuple& t, ::std::ostream* os) { PrintTupleTo(t, os); } template void PrintTo( const ::std::tr1::tuple& t, ::std::ostream* os) { PrintTupleTo(t, os); } #endif // GTEST_HAS_TR1_TUPLE // Overload for std::pair. template void PrintTo(const ::std::pair& value, ::std::ostream* os) { *os << '('; // We cannot use UniversalPrint(value.first, os) here, as T1 may be // a reference type. The same for printing value.second. UniversalPrinter::Print(value.first, os); *os << ", "; UniversalPrinter::Print(value.second, os); *os << ')'; } // Implements printing a non-reference type T by letting the compiler // pick the right overload of PrintTo() for T. template class UniversalPrinter { public: // MSVC warns about adding const to a function type, so we want to // disable the warning. #ifdef _MSC_VER # pragma warning(push) // Saves the current warning state. # pragma warning(disable:4180) // Temporarily disables warning 4180. #endif // _MSC_VER // Note: we deliberately don't call this PrintTo(), as that name // conflicts with ::testing::internal::PrintTo in the body of the // function. static void Print(const T& value, ::std::ostream* os) { // By default, ::testing::internal::PrintTo() is used for printing // the value. // // Thanks to Koenig look-up, if T is a class and has its own // PrintTo() function defined in its namespace, that function will // be visible here. Since it is more specific than the generic ones // in ::testing::internal, it will be picked by the compiler in the // following statement - exactly what we want. PrintTo(value, os); } #ifdef _MSC_VER # pragma warning(pop) // Restores the warning state. #endif // _MSC_VER }; // UniversalPrintArray(begin, len, os) prints an array of 'len' // elements, starting at address 'begin'. template void UniversalPrintArray(const T* begin, size_t len, ::std::ostream* os) { if (len == 0) { *os << "{}"; } else { *os << "{ "; const size_t kThreshold = 18; const size_t kChunkSize = 8; // If the array has more than kThreshold elements, we'll have to // omit some details by printing only the first and the last // kChunkSize elements. // TODO(wan@google.com): let the user control the threshold using a flag. if (len <= kThreshold) { PrintRawArrayTo(begin, len, os); } else { PrintRawArrayTo(begin, kChunkSize, os); *os << ", ..., "; PrintRawArrayTo(begin + len - kChunkSize, kChunkSize, os); } *os << " }"; } } // This overload prints a (const) char array compactly. GTEST_API_ void UniversalPrintArray( const char* begin, size_t len, ::std::ostream* os); // This overload prints a (const) wchar_t array compactly. GTEST_API_ void UniversalPrintArray( const wchar_t* begin, size_t len, ::std::ostream* os); // Implements printing an array type T[N]. template class UniversalPrinter { public: // Prints the given array, omitting some elements when there are too // many. static void Print(const T (&a)[N], ::std::ostream* os) { UniversalPrintArray(a, N, os); } }; // Implements printing a reference type T&. template 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 static void Print(const T& value, ::std::ostream* os) { // Prints the address of the value. We use reinterpret_cast here // as static_cast doesn't compile when T is a function type. *os << "@" << reinterpret_cast(&value) << " "; // Then prints the value itself. UniversalPrint(value, os); } #ifdef _MSC_VER # pragma warning(pop) // Restores the warning state. #endif // _MSC_VER }; // Prints a value tersely: for a reference type, the referenced value // (but not the address) is printed; for a (const) char pointer, the // NUL-terminated string (but not the pointer) is printed. template class UniversalTersePrinter { public: static void Print(const T& value, ::std::ostream* os) { UniversalPrint(value, os); } }; template class UniversalTersePrinter { public: static void Print(const T& value, ::std::ostream* os) { UniversalPrint(value, os); } }; template class UniversalTersePrinter { public: static void Print(const T (&value)[N], ::std::ostream* os) { UniversalPrinter::Print(value, os); } }; template <> class UniversalTersePrinter { public: static void Print(const char* str, ::std::ostream* os) { if (str == NULL) { *os << "NULL"; } else { UniversalPrint(string(str), os); } } }; template <> class UniversalTersePrinter { public: static void Print(char* str, ::std::ostream* os) { UniversalTersePrinter::Print(str, os); } }; #if GTEST_HAS_STD_WSTRING template <> class UniversalTersePrinter { public: static void Print(const wchar_t* str, ::std::ostream* os) { if (str == NULL) { *os << "NULL"; } else { UniversalPrint(::std::wstring(str), os); } } }; #endif template <> class UniversalTersePrinter { public: static void Print(wchar_t* str, ::std::ostream* os) { UniversalTersePrinter::Print(str, os); } }; template void UniversalTersePrint(const T& value, ::std::ostream* os) { UniversalTersePrinter::Print(value, os); } // Prints a value using the type inferred by the compiler. The // difference between this and UniversalTersePrint() is that for a // (const) char pointer, this prints both the pointer and the // NUL-terminated string. template void UniversalPrint(const T& value, ::std::ostream* os) { // A workarond for the bug in VC++ 7.1 that prevents us from instantiating // UniversalPrinter with T directly. typedef T T1; UniversalPrinter::Print(value, os); } #if GTEST_HAS_TR1_TUPLE typedef ::std::vector Strings; // This helper template allows PrintTo() for tuples and // UniversalTersePrintTupleFieldsToStrings() to be defined by // induction on the number of tuple fields. The idea is that // TuplePrefixPrinter::PrintPrefixTo(t, os) prints the first N // fields in tuple t, and can be defined in terms of // TuplePrefixPrinter. // The inductive case. template struct TuplePrefixPrinter { // Prints the first N fields of a tuple. template static void PrintPrefixTo(const Tuple& t, ::std::ostream* os) { TuplePrefixPrinter::PrintPrefixTo(t, os); *os << ", "; UniversalPrinter::type> ::Print(::std::tr1::get(t), os); } // Tersely prints the first N fields of a tuple to a string vector, // one element for each field. template static void TersePrintPrefixToStrings(const Tuple& t, Strings* strings) { TuplePrefixPrinter::TersePrintPrefixToStrings(t, strings); ::std::stringstream ss; UniversalTersePrint(::std::tr1::get(t), &ss); strings->push_back(ss.str()); } }; // Base cases. template <> struct TuplePrefixPrinter<0> { template static void PrintPrefixTo(const Tuple&, ::std::ostream*) {} template static void TersePrintPrefixToStrings(const Tuple&, Strings*) {} }; // We have to specialize the entire TuplePrefixPrinter<> class // template here, even though the definition of // TersePrintPrefixToStrings() is the same as the generic version, as // Embarcadero (formerly CodeGear, formerly Borland) C++ doesn't // support specializing a method template of a class template. template <> struct TuplePrefixPrinter<1> { template static void PrintPrefixTo(const Tuple& t, ::std::ostream* os) { UniversalPrinter::type>:: Print(::std::tr1::get<0>(t), os); } template static void TersePrintPrefixToStrings(const Tuple& t, Strings* strings) { ::std::stringstream ss; UniversalTersePrint(::std::tr1::get<0>(t), &ss); strings->push_back(ss.str()); } }; // Helper function for printing a tuple. T must be instantiated with // a tuple type. template void PrintTupleTo(const T& t, ::std::ostream* os) { *os << "("; TuplePrefixPrinter< ::std::tr1::tuple_size::value>:: PrintPrefixTo(t, os); *os << ")"; } // Prints the fields of a tuple tersely to a string vector, one // element for each field. See the comment before // UniversalTersePrint() for how we define "tersely". template Strings UniversalTersePrintTupleFieldsToStrings(const Tuple& value) { Strings result; TuplePrefixPrinter< ::std::tr1::tuple_size::value>:: TersePrintPrefixToStrings(value, &result); return result; } #endif // GTEST_HAS_TR1_TUPLE } // namespace internal template ::std::string PrintToString(const T& value) { ::std::stringstream ss; internal::UniversalTersePrinter::Print(value, &ss); return ss.str(); } } // namespace testing #endif // GTEST_INCLUDE_GTEST_GTEST_PRINTERS_H_ dlt-daemon-2.18.4/gtest-1.7.0/include/gtest/gtest-spi.h000066400000000000000000000233401353342203500222640ustar00rootroot00000000000000// Copyright 2007, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: wan@google.com (Zhanyong Wan) // // Utilities for testing Google Test itself and code that uses Google Test // (e.g. frameworks built on top of Google Test). #ifndef GTEST_INCLUDE_GTEST_GTEST_SPI_H_ #define GTEST_INCLUDE_GTEST_GTEST_SPI_H_ #include "gtest/gtest.h" namespace testing { // This helper class can be used to mock out Google Test failure reporting // so that we can test Google Test or code that builds on Google Test. // // An object of this class appends a TestPartResult object to the // TestPartResultArray object given in the constructor whenever a Google Test // failure is reported. It can either intercept only failures that are // generated in the same thread that created this object or it can intercept // all generated failures. The scope of this mock object can be controlled with // the second argument to the two arguments constructor. class GTEST_API_ ScopedFakeTestPartResultReporter : public TestPartResultReporterInterface { public: // The two possible mocking modes of this object. enum InterceptMode { INTERCEPT_ONLY_CURRENT_THREAD, // Intercepts only thread local failures. INTERCEPT_ALL_THREADS // Intercepts all failures. }; // The c'tor sets this object as the test part result reporter used // by Google Test. The 'result' parameter specifies where to report the // results. This reporter will only catch failures generated in the current // thread. DEPRECATED explicit ScopedFakeTestPartResultReporter(TestPartResultArray* result); // Same as above, but you can choose the interception scope of this object. ScopedFakeTestPartResultReporter(InterceptMode intercept_mode, TestPartResultArray* result); // The d'tor restores the previous test part result reporter. virtual ~ScopedFakeTestPartResultReporter(); // Appends the TestPartResult object to the TestPartResultArray // received in the constructor. // // This method is from the TestPartResultReporterInterface // interface. virtual void ReportTestPartResult(const TestPartResult& result); private: void Init(); const InterceptMode intercept_mode_; TestPartResultReporterInterface* old_reporter_; TestPartResultArray* const result_; GTEST_DISALLOW_COPY_AND_ASSIGN_(ScopedFakeTestPartResultReporter); }; namespace internal { // A helper class for implementing EXPECT_FATAL_FAILURE() and // EXPECT_NONFATAL_FAILURE(). Its destructor verifies that the given // TestPartResultArray contains exactly one failure that has the given // type and contains the given substring. If that's not the case, a // non-fatal failure will be generated. class GTEST_API_ SingleFailureChecker { public: // The constructor remembers the arguments. SingleFailureChecker(const TestPartResultArray* results, TestPartResult::Type type, const string& substr); ~SingleFailureChecker(); private: const TestPartResultArray* const results_; const TestPartResult::Type type_; const string substr_; GTEST_DISALLOW_COPY_AND_ASSIGN_(SingleFailureChecker); }; } // namespace internal } // namespace testing // A set of macros for testing Google Test assertions or code that's expected // to generate Google Test fatal failures. It verifies that the given // statement will cause exactly one fatal Google Test failure with 'substr' // being part of the failure message. // // There are two different versions of this macro. EXPECT_FATAL_FAILURE only // affects and considers failures generated in the current thread and // EXPECT_FATAL_FAILURE_ON_ALL_THREADS does the same but for all threads. // // The verification of the assertion is done correctly even when the statement // throws an exception or aborts the current function. // // Known restrictions: // - 'statement' cannot reference local non-static variables or // non-static members of the current object. // - 'statement' cannot return a value. // - You cannot stream a failure message to this macro. // // Note that even though the implementations of the following two // macros are much alike, we cannot refactor them to use a common // helper macro, due to some peculiarity in how the preprocessor // works. The AcceptsMacroThatExpandsToUnprotectedComma test in // gtest_unittest.cc will fail to compile if we do that. #define EXPECT_FATAL_FAILURE(statement, substr) \ do { \ class GTestExpectFatalFailureHelper {\ public:\ static void Execute() { statement; }\ };\ ::testing::TestPartResultArray gtest_failures;\ ::testing::internal::SingleFailureChecker gtest_checker(\ >est_failures, ::testing::TestPartResult::kFatalFailure, (substr));\ {\ ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\ ::testing::ScopedFakeTestPartResultReporter:: \ INTERCEPT_ONLY_CURRENT_THREAD, >est_failures);\ GTestExpectFatalFailureHelper::Execute();\ }\ } while (::testing::internal::AlwaysFalse()) #define EXPECT_FATAL_FAILURE_ON_ALL_THREADS(statement, substr) \ do { \ class GTestExpectFatalFailureHelper {\ public:\ static void Execute() { statement; }\ };\ ::testing::TestPartResultArray gtest_failures;\ ::testing::internal::SingleFailureChecker gtest_checker(\ >est_failures, ::testing::TestPartResult::kFatalFailure, (substr));\ {\ ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\ ::testing::ScopedFakeTestPartResultReporter:: \ INTERCEPT_ALL_THREADS, >est_failures);\ GTestExpectFatalFailureHelper::Execute();\ }\ } while (::testing::internal::AlwaysFalse()) // A macro for testing Google Test assertions or code that's expected to // generate Google Test non-fatal failures. It asserts that the given // statement will cause exactly one non-fatal Google Test failure with 'substr' // being part of the failure message. // // There are two different versions of this macro. EXPECT_NONFATAL_FAILURE only // affects and considers failures generated in the current thread and // EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS does the same but for all threads. // // 'statement' is allowed to reference local variables and members of // the current object. // // The verification of the assertion is done correctly even when the statement // throws an exception or aborts the current function. // // Known restrictions: // - You cannot stream a failure message to this macro. // // Note that even though the implementations of the following two // macros are much alike, we cannot refactor them to use a common // helper macro, due to some peculiarity in how the preprocessor // works. If we do that, the code won't compile when the user gives // EXPECT_NONFATAL_FAILURE() a statement that contains a macro that // expands to code containing an unprotected comma. The // AcceptsMacroThatExpandsToUnprotectedComma test in gtest_unittest.cc // catches that. // // For the same reason, we have to write // if (::testing::internal::AlwaysTrue()) { statement; } // instead of // GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement) // to avoid an MSVC warning on unreachable code. #define EXPECT_NONFATAL_FAILURE(statement, substr) \ do {\ ::testing::TestPartResultArray gtest_failures;\ ::testing::internal::SingleFailureChecker gtest_checker(\ >est_failures, ::testing::TestPartResult::kNonFatalFailure, \ (substr));\ {\ ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\ ::testing::ScopedFakeTestPartResultReporter:: \ INTERCEPT_ONLY_CURRENT_THREAD, >est_failures);\ if (::testing::internal::AlwaysTrue()) { statement; }\ }\ } while (::testing::internal::AlwaysFalse()) #define EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS(statement, substr) \ do {\ ::testing::TestPartResultArray gtest_failures;\ ::testing::internal::SingleFailureChecker gtest_checker(\ >est_failures, ::testing::TestPartResult::kNonFatalFailure, \ (substr));\ {\ ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\ ::testing::ScopedFakeTestPartResultReporter::INTERCEPT_ALL_THREADS, \ >est_failures);\ if (::testing::internal::AlwaysTrue()) { statement; }\ }\ } while (::testing::internal::AlwaysFalse()) #endif // GTEST_INCLUDE_GTEST_GTEST_SPI_H_ dlt-daemon-2.18.4/gtest-1.7.0/include/gtest/gtest-test-part.h000066400000000000000000000145551353342203500234240ustar00rootroot00000000000000// Copyright 2008, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: mheule@google.com (Markus Heule) // #ifndef GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_ #define GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_ #include #include #include "gtest/internal/gtest-internal.h" #include "gtest/internal/gtest-string.h" namespace testing { // A copyable object representing the result of a test part (i.e. an // assertion or an explicit FAIL(), ADD_FAILURE(), or SUCCESS()). // // Don't inherit from TestPartResult as its destructor is not virtual. class GTEST_API_ TestPartResult { public: // The possible outcomes of a test part (i.e. an assertion or an // explicit SUCCEED(), FAIL(), or ADD_FAILURE()). enum Type { kSuccess, // Succeeded. kNonFatalFailure, // Failed but the test can continue. kFatalFailure // Failed and the test should be terminated. }; // C'tor. TestPartResult does NOT have a default constructor. // Always use this constructor (with parameters) to create a // TestPartResult object. TestPartResult(Type a_type, const char* a_file_name, int a_line_number, const char* a_message) : type_(a_type), file_name_(a_file_name == NULL ? "" : a_file_name), line_number_(a_line_number), summary_(ExtractSummary(a_message)), message_(a_message) { } // Gets the outcome of the test part. Type type() const { return type_; } // Gets the name of the source file where the test part took place, or // NULL if it's unknown. const char* file_name() const { return file_name_.empty() ? NULL : file_name_.c_str(); } // Gets the line in the source file where the test part took place, // or -1 if it's unknown. int line_number() const { return line_number_; } // Gets the summary of the failure message. const char* summary() const { return summary_.c_str(); } // Gets the message associated with the test part. const char* message() const { return message_.c_str(); } // Returns true iff the test part passed. bool passed() const { return type_ == kSuccess; } // Returns true iff the test part failed. bool failed() const { return type_ != kSuccess; } // Returns true iff the test part non-fatally failed. bool nonfatally_failed() const { return type_ == kNonFatalFailure; } // Returns true iff the test part fatally failed. bool fatally_failed() const { return type_ == kFatalFailure; } private: Type type_; // Gets the summary of the failure message by omitting the stack // trace in it. static std::string ExtractSummary(const char* message); // The name of the source file where the test part took place, or // "" if the source file is unknown. std::string file_name_; // The line in the source file where the test part took place, or -1 // if the line number is unknown. int line_number_; std::string summary_; // The test failure summary. std::string message_; // The test failure message. }; // Prints a TestPartResult object. std::ostream& operator<<(std::ostream& os, const TestPartResult& result); // An array of TestPartResult objects. // // Don't inherit from TestPartResultArray as its destructor is not // virtual. class GTEST_API_ TestPartResultArray { public: TestPartResultArray() {} // Appends the given TestPartResult to the array. void Append(const TestPartResult& result); // Returns the TestPartResult at the given index (0-based). const TestPartResult& GetTestPartResult(int index) const; // Returns the number of TestPartResult objects in the array. int size() const; private: std::vector array_; GTEST_DISALLOW_COPY_AND_ASSIGN_(TestPartResultArray); }; // This interface knows how to report a test part result. class TestPartResultReporterInterface { public: virtual ~TestPartResultReporterInterface() {} virtual void ReportTestPartResult(const TestPartResult& result) = 0; }; namespace internal { // This helper class is used by {ASSERT|EXPECT}_NO_FATAL_FAILURE to check if a // statement generates new fatal failures. To do so it registers itself as the // current test part result reporter. Besides checking if fatal failures were // reported, it only delegates the reporting to the former result reporter. // The original result reporter is restored in the destructor. // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. class GTEST_API_ HasNewFatalFailureHelper : public TestPartResultReporterInterface { public: HasNewFatalFailureHelper(); virtual ~HasNewFatalFailureHelper(); virtual void ReportTestPartResult(const TestPartResult& result); bool has_new_fatal_failure() const { return has_new_fatal_failure_; } private: bool has_new_fatal_failure_; TestPartResultReporterInterface* original_reporter_; GTEST_DISALLOW_COPY_AND_ASSIGN_(HasNewFatalFailureHelper); }; } // namespace internal } // namespace testing #endif // GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_ dlt-daemon-2.18.4/gtest-1.7.0/include/gtest/gtest-typed-test.h000066400000000000000000000240021353342203500235670ustar00rootroot00000000000000// Copyright 2008 Google Inc. // All Rights Reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: wan@google.com (Zhanyong Wan) #ifndef GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_ #define GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_ // This header implements typed tests and type-parameterized tests. // Typed (aka type-driven) tests repeat the same test for types in a // list. You must know which types you want to test with when writing // typed tests. Here's how you do it: #if 0 // First, define a fixture class template. It should be parameterized // by a type. Remember to derive it from testing::Test. template class FooTest : public testing::Test { public: ... typedef std::list List; static T shared_; T value_; }; // Next, associate a list of types with the test case, which will be // repeated for each type in the list. The typedef is necessary for // the macro to parse correctly. typedef testing::Types MyTypes; TYPED_TEST_CASE(FooTest, MyTypes); // If the type list contains only one type, you can write that type // directly without Types<...>: // TYPED_TEST_CASE(FooTest, int); // Then, use TYPED_TEST() instead of TEST_F() to define as many typed // tests for this test case as you want. TYPED_TEST(FooTest, DoesBlah) { // Inside a test, refer to TypeParam to get the type parameter. // Since we are inside a derived class template, C++ requires use to // visit the members of FooTest via 'this'. TypeParam n = this->value_; // To visit static members of the fixture, add the TestFixture:: // prefix. n += TestFixture::shared_; // To refer to typedefs in the fixture, add the "typename // TestFixture::" prefix. typename TestFixture::List values; values.push_back(n); ... } TYPED_TEST(FooTest, HasPropertyA) { ... } #endif // 0 // Type-parameterized tests are abstract test patterns parameterized // by a type. Compared with typed tests, type-parameterized tests // allow you to define the test pattern without knowing what the type // parameters are. The defined pattern can be instantiated with // different types any number of times, in any number of translation // units. // // If you are designing an interface or concept, you can define a // suite of type-parameterized tests to verify properties that any // valid implementation of the interface/concept should have. Then, // each implementation can easily instantiate the test suite to verify // that it conforms to the requirements, without having to write // similar tests repeatedly. Here's an example: #if 0 // First, define a fixture class template. It should be parameterized // by a type. Remember to derive it from testing::Test. template class FooTest : public testing::Test { ... }; // Next, declare that you will define a type-parameterized test case // (the _P suffix is for "parameterized" or "pattern", whichever you // prefer): TYPED_TEST_CASE_P(FooTest); // Then, use TYPED_TEST_P() to define as many type-parameterized tests // for this type-parameterized test case as you want. TYPED_TEST_P(FooTest, DoesBlah) { // Inside a test, refer to TypeParam to get the type parameter. TypeParam n = 0; ... } TYPED_TEST_P(FooTest, HasPropertyA) { ... } // Now the tricky part: you need to register all test patterns before // you can instantiate them. The first argument of the macro is the // test case name; the rest are the names of the tests in this test // case. REGISTER_TYPED_TEST_CASE_P(FooTest, DoesBlah, HasPropertyA); // Finally, you are free to instantiate the pattern with the types you // want. If you put the above code in a header file, you can #include // it in multiple C++ source files and instantiate it multiple times. // // To distinguish different instances of the pattern, the first // argument to the INSTANTIATE_* macro is a prefix that will be added // to the actual test case name. Remember to pick unique prefixes for // different instances. typedef testing::Types MyTypes; INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, MyTypes); // If the type list contains only one type, you can write that type // directly without Types<...>: // INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, int); #endif // 0 #include "gtest/internal/gtest-port.h" #include "gtest/internal/gtest-type-util.h" // Implements typed tests. #if GTEST_HAS_TYPED_TEST // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. // // Expands to the name of the typedef for the type parameters of the // given test case. # define GTEST_TYPE_PARAMS_(TestCaseName) gtest_type_params_##TestCaseName##_ // The 'Types' template argument below must have spaces around it // since some compilers may choke on '>>' when passing a template // instance (e.g. Types) # define TYPED_TEST_CASE(CaseName, Types) \ typedef ::testing::internal::TypeList< Types >::type \ GTEST_TYPE_PARAMS_(CaseName) # define TYPED_TEST(CaseName, TestName) \ template \ class GTEST_TEST_CLASS_NAME_(CaseName, TestName) \ : public CaseName { \ private: \ typedef CaseName TestFixture; \ typedef gtest_TypeParam_ TypeParam; \ virtual void TestBody(); \ }; \ bool gtest_##CaseName##_##TestName##_registered_ GTEST_ATTRIBUTE_UNUSED_ = \ ::testing::internal::TypeParameterizedTest< \ CaseName, \ ::testing::internal::TemplateSel< \ GTEST_TEST_CLASS_NAME_(CaseName, TestName)>, \ GTEST_TYPE_PARAMS_(CaseName)>::Register(\ "", #CaseName, #TestName, 0); \ template \ void GTEST_TEST_CLASS_NAME_(CaseName, TestName)::TestBody() #endif // GTEST_HAS_TYPED_TEST // Implements type-parameterized tests. #if GTEST_HAS_TYPED_TEST_P // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. // // Expands to the namespace name that the type-parameterized tests for // the given type-parameterized test case are defined in. The exact // name of the namespace is subject to change without notice. # define GTEST_CASE_NAMESPACE_(TestCaseName) \ gtest_case_##TestCaseName##_ // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. // // Expands to the name of the variable used to remember the names of // the defined tests in the given test case. # define GTEST_TYPED_TEST_CASE_P_STATE_(TestCaseName) \ gtest_typed_test_case_p_state_##TestCaseName##_ // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE DIRECTLY. // // Expands to the name of the variable used to remember the names of // the registered tests in the given test case. # define GTEST_REGISTERED_TEST_NAMES_(TestCaseName) \ gtest_registered_test_names_##TestCaseName##_ // The variables defined in the type-parameterized test macros are // static as typically these macros are used in a .h file that can be // #included in multiple translation units linked together. # define TYPED_TEST_CASE_P(CaseName) \ static ::testing::internal::TypedTestCasePState \ GTEST_TYPED_TEST_CASE_P_STATE_(CaseName) # define TYPED_TEST_P(CaseName, TestName) \ namespace GTEST_CASE_NAMESPACE_(CaseName) { \ template \ class TestName : public CaseName { \ private: \ typedef CaseName TestFixture; \ typedef gtest_TypeParam_ TypeParam; \ virtual void TestBody(); \ }; \ static bool gtest_##TestName##_defined_ GTEST_ATTRIBUTE_UNUSED_ = \ GTEST_TYPED_TEST_CASE_P_STATE_(CaseName).AddTestName(\ __FILE__, __LINE__, #CaseName, #TestName); \ } \ template \ void GTEST_CASE_NAMESPACE_(CaseName)::TestName::TestBody() # define REGISTER_TYPED_TEST_CASE_P(CaseName, ...) \ namespace GTEST_CASE_NAMESPACE_(CaseName) { \ typedef ::testing::internal::Templates<__VA_ARGS__>::type gtest_AllTests_; \ } \ static const char* const GTEST_REGISTERED_TEST_NAMES_(CaseName) = \ GTEST_TYPED_TEST_CASE_P_STATE_(CaseName).VerifyRegisteredTestNames(\ __FILE__, __LINE__, #__VA_ARGS__) // The 'Types' template argument below must have spaces around it // since some compilers may choke on '>>' when passing a template // instance (e.g. Types) # define INSTANTIATE_TYPED_TEST_CASE_P(Prefix, CaseName, Types) \ bool gtest_##Prefix##_##CaseName GTEST_ATTRIBUTE_UNUSED_ = \ ::testing::internal::TypeParameterizedTestCase::type>::Register(\ #Prefix, #CaseName, GTEST_REGISTERED_TEST_NAMES_(CaseName)) #endif // GTEST_HAS_TYPED_TEST_P #endif // GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_ dlt-daemon-2.18.4/gtest-1.7.0/include/gtest/gtest.h000066400000000000000000002545621353342203500215070ustar00rootroot00000000000000// Copyright 2005, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: wan@google.com (Zhanyong Wan) // // The Google C++ Testing Framework (Google Test) // // This header file defines the public API for Google Test. It should be // included by any test program that uses Google Test. // // IMPORTANT NOTE: Due to limitation of the C++ language, we have to // leave some internal implementation details in this header file. // They are clearly marked by comments like this: // // // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. // // Such code is NOT meant to be used by a user directly, and is subject // to CHANGE WITHOUT NOTICE. Therefore DO NOT DEPEND ON IT in a user // program! // // Acknowledgment: Google Test borrowed the idea of automatic test // registration from Barthelemy Dagenais' (barthelemy@prologique.com) // easyUnit framework. #ifndef GTEST_INCLUDE_GTEST_GTEST_H_ #define GTEST_INCLUDE_GTEST_GTEST_H_ #include #include #include #include "gtest/internal/gtest-internal.h" #include "gtest/internal/gtest-string.h" #include "gtest/gtest-death-test.h" #include "gtest/gtest-message.h" #include "gtest/gtest-param-test.h" #include "gtest/gtest-printers.h" #include "gtest/gtest_prod.h" #include "gtest/gtest-test-part.h" #include "gtest/gtest-typed-test.h" // Depending on the platform, different string classes are available. // On Linux, in addition to ::std::string, Google also makes use of // class ::string, which has the same interface as ::std::string, but // has a different implementation. // // The user can define GTEST_HAS_GLOBAL_STRING to 1 to indicate that // ::string is available AND is a distinct type to ::std::string, or // define it to 0 to indicate otherwise. // // If the user's ::std::string and ::string are the same class due to // aliasing, he should define GTEST_HAS_GLOBAL_STRING to 0. // // If the user doesn't define GTEST_HAS_GLOBAL_STRING, it is defined // heuristically. namespace testing { // Declares the flags. // This flag temporary enables the disabled tests. GTEST_DECLARE_bool_(also_run_disabled_tests); // This flag brings the debugger on an assertion failure. GTEST_DECLARE_bool_(break_on_failure); // This flag controls whether Google Test catches all test-thrown exceptions // and logs them as failures. GTEST_DECLARE_bool_(catch_exceptions); // This flag enables using colors in terminal output. Available values are // "yes" to enable colors, "no" (disable colors), or "auto" (the default) // to let Google Test decide. GTEST_DECLARE_string_(color); // This flag sets up the filter to select by name using a glob pattern // the tests to run. If the filter is not given all tests are executed. GTEST_DECLARE_string_(filter); // This flag causes the Google Test to list tests. None of the tests listed // are actually run if the flag is provided. GTEST_DECLARE_bool_(list_tests); // This flag controls whether Google Test emits a detailed XML report to a file // in addition to its normal textual output. GTEST_DECLARE_string_(output); // This flags control whether Google Test prints the elapsed time for each // test. GTEST_DECLARE_bool_(print_time); // This flag specifies the random number seed. GTEST_DECLARE_int32_(random_seed); // This flag sets how many times the tests are repeated. The default value // is 1. If the value is -1 the tests are repeating forever. GTEST_DECLARE_int32_(repeat); // This flag controls whether Google Test includes Google Test internal // stack frames in failure stack traces. GTEST_DECLARE_bool_(show_internal_stack_frames); // When this flag is specified, tests' order is randomized on every iteration. GTEST_DECLARE_bool_(shuffle); // This flag specifies the maximum number of stack frames to be // printed in a failure message. GTEST_DECLARE_int32_(stack_trace_depth); // When this flag is specified, a failed assertion will throw an // exception if exceptions are enabled, or exit the program with a // non-zero code otherwise. GTEST_DECLARE_bool_(throw_on_failure); // When this flag is set with a "host:port" string, on supported // platforms test results are streamed to the specified port on // the specified host machine. GTEST_DECLARE_string_(stream_result_to); // The upper limit for valid stack trace depths. const int kMaxStackTraceDepth = 100; namespace internal { class AssertHelper; class DefaultGlobalTestPartResultReporter; class ExecDeathTest; class NoExecDeathTest; class FinalSuccessChecker; class GTestFlagSaver; class StreamingListenerTest; class TestResultAccessor; class TestEventListenersAccessor; class TestEventRepeater; class UnitTestRecordPropertyTestHelper; class WindowsDeathTest; class UnitTestImpl* GetUnitTestImpl(); void ReportFailureInUnknownLocation(TestPartResult::Type result_type, const std::string& message); } // namespace internal // The friend relationship of some of these classes is cyclic. // If we don't forward declare them the compiler might confuse the classes // in friendship clauses with same named classes on the scope. class Test; class TestCase; class TestInfo; class UnitTest; // A class for indicating whether an assertion was successful. When // the assertion wasn't successful, the AssertionResult object // remembers a non-empty message that describes how it failed. // // To create an instance of this class, use one of the factory functions // (AssertionSuccess() and AssertionFailure()). // // This class is useful for two purposes: // 1. Defining predicate functions to be used with Boolean test assertions // EXPECT_TRUE/EXPECT_FALSE and their ASSERT_ counterparts // 2. Defining predicate-format functions to be // used with predicate assertions (ASSERT_PRED_FORMAT*, etc). // // For example, if you define IsEven predicate: // // testing::AssertionResult IsEven(int n) { // if ((n % 2) == 0) // return testing::AssertionSuccess(); // else // return testing::AssertionFailure() << n << " is odd"; // } // // Then the failed expectation EXPECT_TRUE(IsEven(Fib(5))) // will print the message // // Value of: IsEven(Fib(5)) // Actual: false (5 is odd) // Expected: true // // instead of a more opaque // // Value of: IsEven(Fib(5)) // Actual: false // Expected: true // // in case IsEven is a simple Boolean predicate. // // If you expect your predicate to be reused and want to support informative // messages in EXPECT_FALSE and ASSERT_FALSE (negative assertions show up // about half as often as positive ones in our tests), supply messages for // both success and failure cases: // // testing::AssertionResult IsEven(int n) { // if ((n % 2) == 0) // return testing::AssertionSuccess() << n << " is even"; // else // return testing::AssertionFailure() << n << " is odd"; // } // // Then a statement EXPECT_FALSE(IsEven(Fib(6))) will print // // Value of: IsEven(Fib(6)) // Actual: true (8 is even) // Expected: false // // NB: Predicates that support negative Boolean assertions have reduced // performance in positive ones so be careful not to use them in tests // that have lots (tens of thousands) of positive Boolean assertions. // // To use this class with EXPECT_PRED_FORMAT assertions such as: // // // Verifies that Foo() returns an even number. // EXPECT_PRED_FORMAT1(IsEven, Foo()); // // you need to define: // // testing::AssertionResult IsEven(const char* expr, int n) { // if ((n % 2) == 0) // return testing::AssertionSuccess(); // else // return testing::AssertionFailure() // << "Expected: " << expr << " is even\n Actual: it's " << n; // } // // If Foo() returns 5, you will see the following message: // // Expected: Foo() is even // Actual: it's 5 // class GTEST_API_ AssertionResult { public: // Copy constructor. // Used in EXPECT_TRUE/FALSE(assertion_result). AssertionResult(const AssertionResult& other); // Used in the EXPECT_TRUE/FALSE(bool_expression). explicit AssertionResult(bool success) : success_(success) {} // Returns true iff the assertion succeeded. operator bool() const { return success_; } // NOLINT // Returns the assertion's negation. Used with EXPECT/ASSERT_FALSE. AssertionResult operator!() const; // Returns the text streamed into this AssertionResult. Test assertions // use it when they fail (i.e., the predicate's outcome doesn't match the // assertion's expectation). When nothing has been streamed into the // object, returns an empty string. const char* message() const { return message_.get() != NULL ? message_->c_str() : ""; } // TODO(vladl@google.com): Remove this after making sure no clients use it. // Deprecated; please use message() instead. const char* failure_message() const { return message(); } // Streams a custom failure message into this object. template AssertionResult& operator<<(const T& value) { AppendMessage(Message() << value); return *this; } // Allows streaming basic output manipulators such as endl or flush into // this object. AssertionResult& operator<<( ::std::ostream& (*basic_manipulator)(::std::ostream& stream)) { AppendMessage(Message() << basic_manipulator); return *this; } private: // Appends the contents of message to message_. void AppendMessage(const Message& a_message) { if (message_.get() == NULL) message_.reset(new ::std::string); message_->append(a_message.GetString().c_str()); } // Stores result of the assertion predicate. bool success_; // Stores the message describing the condition in case the expectation // construct is not satisfied with the predicate's outcome. // Referenced via a pointer to avoid taking too much stack frame space // with test assertions. internal::scoped_ptr< ::std::string> message_; GTEST_DISALLOW_ASSIGN_(AssertionResult); }; // Makes a successful assertion result. GTEST_API_ AssertionResult AssertionSuccess(); // Makes a failed assertion result. GTEST_API_ AssertionResult AssertionFailure(); // Makes a failed assertion result with the given failure message. // Deprecated; use AssertionFailure() << msg. GTEST_API_ AssertionResult AssertionFailure(const Message& msg); // The abstract class that all tests inherit from. // // In Google Test, a unit test program contains one or many TestCases, and // each TestCase contains one or many Tests. // // When you define a test using the TEST macro, you don't need to // explicitly derive from Test - the TEST macro automatically does // this for you. // // The only time you derive from Test is when defining a test fixture // to be used a TEST_F. For example: // // class FooTest : public testing::Test { // protected: // virtual void SetUp() { ... } // virtual void TearDown() { ... } // ... // }; // // TEST_F(FooTest, Bar) { ... } // TEST_F(FooTest, Baz) { ... } // // Test is not copyable. class GTEST_API_ Test { public: friend class TestInfo; // Defines types for pointers to functions that set up and tear down // a test case. typedef internal::SetUpTestCaseFunc SetUpTestCaseFunc; typedef internal::TearDownTestCaseFunc TearDownTestCaseFunc; // The d'tor is virtual as we intend to inherit from Test. virtual ~Test(); // Sets up the stuff shared by all tests in this test case. // // Google Test will call Foo::SetUpTestCase() before running the first // test in test case Foo. Hence a sub-class can define its own // SetUpTestCase() method to shadow the one defined in the super // class. static void SetUpTestCase() {} // Tears down the stuff shared by all tests in this test case. // // Google Test will call Foo::TearDownTestCase() after running the last // test in test case Foo. Hence a sub-class can define its own // TearDownTestCase() method to shadow the one defined in the super // class. static void TearDownTestCase() {} // Returns true iff the current test has a fatal failure. static bool HasFatalFailure(); // Returns true iff the current test has a non-fatal failure. static bool HasNonfatalFailure(); // Returns true iff the current test has a (either fatal or // non-fatal) failure. static bool HasFailure() { return HasFatalFailure() || HasNonfatalFailure(); } // Logs a property for the current test, test case, or for the entire // invocation of the test program when used outside of the context of a // test case. Only the last value for a given key is remembered. These // are public static so they can be called from utility functions that are // not members of the test fixture. Calls to RecordProperty made during // lifespan of the test (from the moment its constructor starts to the // moment its destructor finishes) will be output in XML as attributes of // the element. Properties recorded from fixture's // SetUpTestCase or TearDownTestCase are logged as attributes of the // corresponding element. Calls to RecordProperty made in the // global context (before or after invocation of RUN_ALL_TESTS and from // SetUp/TearDown method of Environment objects registered with Google // Test) will be output as attributes of the element. static void RecordProperty(const std::string& key, const std::string& value); static void RecordProperty(const std::string& key, int value); protected: // Creates a Test object. Test(); // Sets up the test fixture. virtual void SetUp(); // Tears down the test fixture. virtual void TearDown(); private: // Returns true iff the current test has the same fixture class as // the first test in the current test case. static bool HasSameFixtureClass(); // Runs the test after the test fixture has been set up. // // A sub-class must implement this to define the test logic. // // DO NOT OVERRIDE THIS FUNCTION DIRECTLY IN A USER PROGRAM. // Instead, use the TEST or TEST_F macro. virtual void TestBody() = 0; // Sets up, executes, and tears down the test. void Run(); // Deletes self. We deliberately pick an unusual name for this // internal method to avoid clashing with names used in user TESTs. void DeleteSelf_() { delete this; } // Uses a GTestFlagSaver to save and restore all Google Test flags. const internal::GTestFlagSaver* const gtest_flag_saver_; // Often a user mis-spells SetUp() as Setup() and spends a long time // wondering why it is never called by Google Test. The declaration of // the following method is solely for catching such an error at // compile time: // // - The return type is deliberately chosen to be not void, so it // will be a conflict if a user declares void Setup() in his test // fixture. // // - This method is private, so it will be another compiler error // if a user calls it from his test fixture. // // DO NOT OVERRIDE THIS FUNCTION. // // If you see an error about overriding the following function or // about it being private, you have mis-spelled SetUp() as Setup(). struct Setup_should_be_spelled_SetUp {}; virtual Setup_should_be_spelled_SetUp* Setup() { return NULL; } // We disallow copying Tests. GTEST_DISALLOW_COPY_AND_ASSIGN_(Test); }; typedef internal::TimeInMillis TimeInMillis; // A copyable object representing a user specified test property which can be // output as a key/value string pair. // // Don't inherit from TestProperty as its destructor is not virtual. class TestProperty { public: // C'tor. TestProperty does NOT have a default constructor. // Always use this constructor (with parameters) to create a // TestProperty object. TestProperty(const std::string& a_key, const std::string& a_value) : key_(a_key), value_(a_value) { } // Gets the user supplied key. const char* key() const { return key_.c_str(); } // Gets the user supplied value. const char* value() const { return value_.c_str(); } // Sets a new value, overriding the one supplied in the constructor. void SetValue(const std::string& new_value) { value_ = new_value; } private: // The key supplied by the user. std::string key_; // The value supplied by the user. std::string value_; }; // The result of a single Test. This includes a list of // TestPartResults, a list of TestProperties, a count of how many // death tests there are in the Test, and how much time it took to run // the Test. // // TestResult is not copyable. class GTEST_API_ TestResult { public: // Creates an empty TestResult. TestResult(); // D'tor. Do not inherit from TestResult. ~TestResult(); // Gets the number of all test parts. This is the sum of the number // of successful test parts and the number of failed test parts. int total_part_count() const; // Returns the number of the test properties. int test_property_count() const; // Returns true iff the test passed (i.e. no test part failed). bool Passed() const { return !Failed(); } // Returns true iff the test failed. bool Failed() const; // Returns true iff the test fatally failed. bool HasFatalFailure() const; // Returns true iff the test has a non-fatal failure. bool HasNonfatalFailure() const; // Returns the elapsed time, in milliseconds. TimeInMillis elapsed_time() const { return elapsed_time_; } // Returns the i-th test part result among all the results. i can range // from 0 to test_property_count() - 1. If i is not in that range, aborts // the program. const TestPartResult& GetTestPartResult(int i) const; // Returns the i-th test property. i can range from 0 to // test_property_count() - 1. If i is not in that range, aborts the // program. const TestProperty& GetTestProperty(int i) const; private: friend class TestInfo; friend class TestCase; friend class UnitTest; friend class internal::DefaultGlobalTestPartResultReporter; friend class internal::ExecDeathTest; friend class internal::TestResultAccessor; friend class internal::UnitTestImpl; friend class internal::WindowsDeathTest; // Gets the vector of TestPartResults. const std::vector& test_part_results() const { return test_part_results_; } // Gets the vector of TestProperties. const std::vector& test_properties() const { return test_properties_; } // Sets the elapsed time. void set_elapsed_time(TimeInMillis elapsed) { elapsed_time_ = elapsed; } // Adds a test property to the list. The property is validated and may add // a non-fatal failure if invalid (e.g., if it conflicts with reserved // key names). If a property is already recorded for the same key, the // value will be updated, rather than storing multiple values for the same // key. xml_element specifies the element for which the property is being // recorded and is used for validation. void RecordProperty(const std::string& xml_element, const TestProperty& test_property); // Adds a failure if the key is a reserved attribute of Google Test // testcase tags. Returns true if the property is valid. // TODO(russr): Validate attribute names are legal and human readable. static bool ValidateTestProperty(const std::string& xml_element, const TestProperty& test_property); // Adds a test part result to the list. void AddTestPartResult(const TestPartResult& test_part_result); // Returns the death test count. int death_test_count() const { return death_test_count_; } // Increments the death test count, returning the new count. int increment_death_test_count() { return ++death_test_count_; } // Clears the test part results. void ClearTestPartResults(); // Clears the object. void Clear(); // Protects mutable state of the property vector and of owned // properties, whose values may be updated. internal::Mutex test_properites_mutex_; // The vector of TestPartResults std::vector test_part_results_; // The vector of TestProperties std::vector test_properties_; // Running count of death tests. int death_test_count_; // The elapsed time, in milliseconds. TimeInMillis elapsed_time_; // We disallow copying TestResult. GTEST_DISALLOW_COPY_AND_ASSIGN_(TestResult); }; // class TestResult // A TestInfo object stores the following information about a test: // // Test case name // Test name // Whether the test should be run // A function pointer that creates the test object when invoked // Test result // // The constructor of TestInfo registers itself with the UnitTest // singleton such that the RUN_ALL_TESTS() macro knows which tests to // run. class GTEST_API_ TestInfo { public: // Destructs a TestInfo object. This function is not virtual, so // don't inherit from TestInfo. ~TestInfo(); // Returns the test case name. const char* test_case_name() const { return test_case_name_.c_str(); } // Returns the test name. const char* name() const { return name_.c_str(); } // Returns the name of the parameter type, or NULL if this is not a typed // or a type-parameterized test. const char* type_param() const { if (type_param_.get() != NULL) return type_param_->c_str(); return NULL; } // Returns the text representation of the value parameter, or NULL if this // is not a value-parameterized test. const char* value_param() const { if (value_param_.get() != NULL) return value_param_->c_str(); return NULL; } // Returns true if this test should run, that is if the test is not // disabled (or it is disabled but the also_run_disabled_tests flag has // been specified) and its full name matches the user-specified filter. // // Google Test allows the user to filter the tests by their full names. // The full name of a test Bar in test case Foo is defined as // "Foo.Bar". Only the tests that match the filter will run. // // A filter is a colon-separated list of glob (not regex) patterns, // optionally followed by a '-' and a colon-separated list of // negative patterns (tests to exclude). A test is run if it // matches one of the positive patterns and does not match any of // the negative patterns. // // For example, *A*:Foo.* is a filter that matches any string that // contains the character 'A' or starts with "Foo.". bool should_run() const { return should_run_; } // Returns true iff this test will appear in the XML report. bool is_reportable() const { // For now, the XML report includes all tests matching the filter. // In the future, we may trim tests that are excluded because of // sharding. return matches_filter_; } // Returns the result of the test. const TestResult* result() const { return &result_; } private: #if GTEST_HAS_DEATH_TEST friend class internal::DefaultDeathTestFactory; #endif // GTEST_HAS_DEATH_TEST friend class Test; friend class TestCase; friend class internal::UnitTestImpl; friend class internal::StreamingListenerTest; friend TestInfo* internal::MakeAndRegisterTestInfo( const char* test_case_name, const char* name, const char* type_param, const char* value_param, internal::TypeId fixture_class_id, Test::SetUpTestCaseFunc set_up_tc, Test::TearDownTestCaseFunc tear_down_tc, internal::TestFactoryBase* factory); // Constructs a TestInfo object. The newly constructed instance assumes // ownership of the factory object. TestInfo(const std::string& test_case_name, 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::TypeId fixture_class_id, internal::TestFactoryBase* factory); // Increments the number of death tests encountered in this test so // far. int increment_death_test_count() { return result_.increment_death_test_count(); } // Creates the test object, runs it, records its result, and then // deletes it. void Run(); static void ClearTestResult(TestInfo* test_info) { test_info->result_.Clear(); } // These fields are immutable properties of the test. const std::string test_case_name_; // Test case name const std::string name_; // Test name // Name of the parameter type, or NULL if this is not a typed or a // type-parameterized test. const internal::scoped_ptr type_param_; // Text representation of the value parameter, or NULL if this is not a // value-parameterized test. const internal::scoped_ptr value_param_; const internal::TypeId fixture_class_id_; // ID of the test fixture class bool should_run_; // True iff this test should run bool is_disabled_; // True iff this test is disabled bool matches_filter_; // True if this test matches the // user-specified filter. internal::TestFactoryBase* const factory_; // The factory that creates // the test object // This field is mutable and needs to be reset before running the // test for the second time. TestResult result_; GTEST_DISALLOW_COPY_AND_ASSIGN_(TestInfo); }; // A test case, which consists of a vector of TestInfos. // // TestCase is not copyable. class GTEST_API_ TestCase { public: // Creates a TestCase with the given name. // // TestCase does NOT have a default constructor. Always use this // constructor to create a TestCase object. // // Arguments: // // name: name of the test case // a_type_param: the name of the test's type parameter, or NULL if // this is not a type-parameterized test. // set_up_tc: pointer to the function that sets up the test case // tear_down_tc: pointer to the function that tears down the test case TestCase(const char* name, const char* a_type_param, Test::SetUpTestCaseFunc set_up_tc, Test::TearDownTestCaseFunc tear_down_tc); // Destructor of TestCase. virtual ~TestCase(); // Gets the name of the TestCase. const char* name() const { return name_.c_str(); } // Returns the name of the parameter type, or NULL if this is not a // type-parameterized test case. const char* type_param() const { if (type_param_.get() != NULL) return type_param_->c_str(); return NULL; } // Returns true if any test in this test case should run. bool should_run() const { return should_run_; } // Gets the number of successful tests in this test case. int successful_test_count() const; // Gets the number of failed tests in this test case. int failed_test_count() const; // Gets the number of disabled tests that will be reported in the XML report. int reportable_disabled_test_count() const; // Gets the number of disabled tests in this test case. int disabled_test_count() const; // Gets the number of tests to be printed in the XML report. int reportable_test_count() const; // Get the number of tests in this test case that should run. int test_to_run_count() const; // Gets the number of all tests in this test case. int total_test_count() const; // Returns true iff the test case passed. bool Passed() const { return !Failed(); } // Returns true iff the test case failed. bool Failed() const { return failed_test_count() > 0; } // Returns the elapsed time, in milliseconds. TimeInMillis elapsed_time() const { return elapsed_time_; } // Returns the i-th test among all the tests. i can range from 0 to // total_test_count() - 1. If i is not in that range, returns NULL. const TestInfo* GetTestInfo(int i) const; // Returns the TestResult that holds test properties recorded during // execution of SetUpTestCase and TearDownTestCase. const TestResult& ad_hoc_test_result() const { return ad_hoc_test_result_; } private: friend class Test; friend class internal::UnitTestImpl; // Gets the (mutable) vector of TestInfos in this TestCase. std::vector& test_info_list() { return test_info_list_; } // Gets the (immutable) vector of TestInfos in this TestCase. const std::vector& test_info_list() const { return test_info_list_; } // Returns the i-th test among all the tests. i can range from 0 to // total_test_count() - 1. If i is not in that range, returns NULL. TestInfo* GetMutableTestInfo(int i); // Sets the should_run member. void set_should_run(bool should) { should_run_ = should; } // Adds a TestInfo to this test case. Will delete the TestInfo upon // destruction of the TestCase object. void AddTestInfo(TestInfo * test_info); // Clears the results of all tests in this test case. void ClearResult(); // Clears the results of all tests in the given test case. static void ClearTestCaseResult(TestCase* test_case) { test_case->ClearResult(); } // Runs every test in this TestCase. void Run(); // Runs SetUpTestCase() for this TestCase. This wrapper is needed // for catching exceptions thrown from SetUpTestCase(). void RunSetUpTestCase() { (*set_up_tc_)(); } // Runs TearDownTestCase() for this TestCase. This wrapper is // needed for catching exceptions thrown from TearDownTestCase(). void RunTearDownTestCase() { (*tear_down_tc_)(); } // Returns true iff test passed. static bool TestPassed(const TestInfo* test_info) { return test_info->should_run() && test_info->result()->Passed(); } // Returns true iff test failed. static bool TestFailed(const TestInfo* test_info) { return test_info->should_run() && test_info->result()->Failed(); } // Returns true iff the test is disabled and will be reported in the XML // report. static bool TestReportableDisabled(const TestInfo* test_info) { return test_info->is_reportable() && test_info->is_disabled_; } // Returns true iff test is disabled. static bool TestDisabled(const TestInfo* test_info) { return test_info->is_disabled_; } // Returns true iff this test will appear in the XML report. static bool TestReportable(const TestInfo* test_info) { return test_info->is_reportable(); } // Returns true if the given test should run. static bool ShouldRunTest(const TestInfo* test_info) { return test_info->should_run(); } // Shuffles the tests in this test case. void ShuffleTests(internal::Random* random); // Restores the test order to before the first shuffle. void UnshuffleTests(); // Name of the test case. std::string name_; // Name of the parameter type, or NULL if this is not a typed or a // type-parameterized test. const internal::scoped_ptr type_param_; // The vector of TestInfos in their original order. It owns the // elements in the vector. std::vector test_info_list_; // Provides a level of indirection for the test list to allow easy // shuffling and restoring the test order. The i-th element in this // vector is the index of the i-th test in the shuffled test list. std::vector test_indices_; // Pointer to the function that sets up the test case. Test::SetUpTestCaseFunc set_up_tc_; // Pointer to the function that tears down the test case. Test::TearDownTestCaseFunc tear_down_tc_; // True iff any test in this test case should run. bool should_run_; // Elapsed time, in milliseconds. TimeInMillis elapsed_time_; // Holds test properties recorded during execution of SetUpTestCase and // TearDownTestCase. TestResult ad_hoc_test_result_; // We disallow copying TestCases. GTEST_DISALLOW_COPY_AND_ASSIGN_(TestCase); }; // An Environment object is capable of setting up and tearing down an // environment. The user should subclass this to define his own // environment(s). // // An Environment object does the set-up and tear-down in virtual // methods SetUp() and TearDown() instead of the constructor and the // destructor, as: // // 1. You cannot safely throw from a destructor. This is a problem // as in some cases Google Test is used where exceptions are enabled, and // we may want to implement ASSERT_* using exceptions where they are // available. // 2. You cannot use ASSERT_* directly in a constructor or // destructor. class Environment { public: // The d'tor is virtual as we need to subclass Environment. virtual ~Environment() {} // Override this to define how to set up the environment. virtual void SetUp() {} // Override this to define how to tear down the environment. virtual void TearDown() {} private: // If you see an error about overriding the following function or // about it being private, you have mis-spelled SetUp() as Setup(). struct Setup_should_be_spelled_SetUp {}; virtual Setup_should_be_spelled_SetUp* Setup() { return NULL; } }; // The interface for tracing execution of tests. The methods are organized in // the order the corresponding events are fired. class TestEventListener { public: virtual ~TestEventListener() {} // Fired before any test activity starts. virtual void OnTestProgramStart(const UnitTest& unit_test) = 0; // Fired before each iteration of tests starts. There may be more than // one iteration if GTEST_FLAG(repeat) is set. iteration is the iteration // index, starting from 0. virtual void OnTestIterationStart(const UnitTest& unit_test, int iteration) = 0; // Fired before environment set-up for each iteration of tests starts. virtual void OnEnvironmentsSetUpStart(const UnitTest& unit_test) = 0; // Fired after environment set-up for each iteration of tests ends. virtual void OnEnvironmentsSetUpEnd(const UnitTest& unit_test) = 0; // Fired before the test case starts. virtual void OnTestCaseStart(const TestCase& test_case) = 0; // Fired before the test starts. virtual void OnTestStart(const TestInfo& test_info) = 0; // Fired after a failed assertion or a SUCCEED() invocation. virtual void OnTestPartResult(const TestPartResult& test_part_result) = 0; // Fired after the test ends. virtual void OnTestEnd(const TestInfo& test_info) = 0; // Fired after the test case ends. virtual void OnTestCaseEnd(const TestCase& test_case) = 0; // Fired before environment tear-down for each iteration of tests starts. virtual void OnEnvironmentsTearDownStart(const UnitTest& unit_test) = 0; // Fired after environment tear-down for each iteration of tests ends. virtual void OnEnvironmentsTearDownEnd(const UnitTest& unit_test) = 0; // Fired after each iteration of tests finishes. virtual void OnTestIterationEnd(const UnitTest& unit_test, int iteration) = 0; // Fired after all test activities have ended. virtual void OnTestProgramEnd(const UnitTest& unit_test) = 0; }; // The convenience class for users who need to override just one or two // methods and are not concerned that a possible change to a signature of // the methods they override will not be caught during the build. For // comments about each method please see the definition of TestEventListener // above. class EmptyTestEventListener : public TestEventListener { public: virtual void OnTestProgramStart(const UnitTest& /*unit_test*/) {} virtual void OnTestIterationStart(const UnitTest& /*unit_test*/, int /*iteration*/) {} virtual void OnEnvironmentsSetUpStart(const UnitTest& /*unit_test*/) {} virtual void OnEnvironmentsSetUpEnd(const UnitTest& /*unit_test*/) {} virtual void OnTestCaseStart(const TestCase& /*test_case*/) {} virtual void OnTestStart(const TestInfo& /*test_info*/) {} virtual void OnTestPartResult(const TestPartResult& /*test_part_result*/) {} virtual void OnTestEnd(const TestInfo& /*test_info*/) {} virtual void OnTestCaseEnd(const TestCase& /*test_case*/) {} virtual void OnEnvironmentsTearDownStart(const UnitTest& /*unit_test*/) {} virtual void OnEnvironmentsTearDownEnd(const UnitTest& /*unit_test*/) {} virtual void OnTestIterationEnd(const UnitTest& /*unit_test*/, int /*iteration*/) {} virtual void OnTestProgramEnd(const UnitTest& /*unit_test*/) {} }; // TestEventListeners lets users add listeners to track events in Google Test. class GTEST_API_ TestEventListeners { public: TestEventListeners(); ~TestEventListeners(); // Appends an event listener to the end of the list. Google Test assumes // the ownership of the listener (i.e. it will delete the listener when // the test program finishes). void Append(TestEventListener* listener); // Removes the given event listener from the list and returns it. It then // becomes the caller's responsibility to delete the listener. Returns // NULL if the listener is not found in the list. TestEventListener* Release(TestEventListener* listener); // Returns the standard listener responsible for the default console // output. Can be removed from the listeners list to shut down default // console output. Note that removing this object from the listener list // with Release transfers its ownership to the caller and makes this // function return NULL the next time. TestEventListener* default_result_printer() const { return default_result_printer_; } // Returns the standard listener responsible for the default XML output // controlled by the --gtest_output=xml flag. Can be removed from the // listeners list by users who want to shut down the default XML output // controlled by this flag and substitute it with custom one. Note that // removing this object from the listener list with Release transfers its // ownership to the caller and makes this function return NULL the next // time. TestEventListener* default_xml_generator() const { return default_xml_generator_; } private: friend class TestCase; friend class TestInfo; friend class internal::DefaultGlobalTestPartResultReporter; friend class internal::NoExecDeathTest; friend class internal::TestEventListenersAccessor; friend class internal::UnitTestImpl; // Returns repeater that broadcasts the TestEventListener events to all // subscribers. TestEventListener* repeater(); // Sets the default_result_printer attribute to the provided listener. // The listener is also added to the listener list and previous // default_result_printer is removed from it and deleted. The listener can // also be NULL in which case it will not be added to the list. Does // nothing if the previous and the current listener objects are the same. void SetDefaultResultPrinter(TestEventListener* listener); // Sets the default_xml_generator attribute to the provided listener. The // listener is also added to the listener list and previous // default_xml_generator is removed from it and deleted. The listener can // also be NULL in which case it will not be added to the list. Does // nothing if the previous and the current listener objects are the same. void SetDefaultXmlGenerator(TestEventListener* listener); // Controls whether events will be forwarded by the repeater to the // listeners in the list. bool EventForwardingEnabled() const; void SuppressEventForwarding(); // The actual list of listeners. internal::TestEventRepeater* repeater_; // Listener responsible for the standard result output. TestEventListener* default_result_printer_; // Listener responsible for the creation of the XML output file. TestEventListener* default_xml_generator_; // We disallow copying TestEventListeners. GTEST_DISALLOW_COPY_AND_ASSIGN_(TestEventListeners); }; // A UnitTest consists of a vector of TestCases. // // This is a singleton class. The only instance of UnitTest is // created when UnitTest::GetInstance() is first called. This // instance is never deleted. // // UnitTest is not copyable. // // This class is thread-safe as long as the methods are called // according to their specification. class GTEST_API_ UnitTest { public: // Gets the singleton UnitTest object. The first time this method // is called, a UnitTest object is constructed and returned. // Consecutive calls will return the same object. static UnitTest* GetInstance(); // Runs all tests in this UnitTest object and prints the result. // Returns 0 if successful, or 1 otherwise. // // This method can only be called from the main thread. // // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. int Run() GTEST_MUST_USE_RESULT_; // Returns the working directory when the first TEST() or TEST_F() // was executed. The UnitTest object owns the string. const char* original_working_dir() const; // Returns the TestCase object for the test that's currently running, // or NULL if no test is running. const TestCase* current_test_case() const GTEST_LOCK_EXCLUDED_(mutex_); // Returns the TestInfo object for the test that's currently running, // or NULL if no test is running. const TestInfo* current_test_info() const GTEST_LOCK_EXCLUDED_(mutex_); // Returns the random seed used at the start of the current test run. int random_seed() const; #if GTEST_HAS_PARAM_TEST // Returns the ParameterizedTestCaseRegistry object used to keep track of // value-parameterized tests and instantiate and register them. // // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. internal::ParameterizedTestCaseRegistry& parameterized_test_registry() GTEST_LOCK_EXCLUDED_(mutex_); #endif // GTEST_HAS_PARAM_TEST // Gets the number of successful test cases. int successful_test_case_count() const; // Gets the number of failed test cases. int failed_test_case_count() const; // Gets the number of all test cases. int total_test_case_count() const; // Gets the number of all test cases that contain at least one test // that should run. int test_case_to_run_count() const; // Gets the number of successful tests. int successful_test_count() const; // Gets the number of failed tests. int failed_test_count() const; // Gets the number of disabled tests that will be reported in the XML report. int reportable_disabled_test_count() const; // Gets the number of disabled tests. int disabled_test_count() const; // Gets the number of tests to be printed in the XML report. int reportable_test_count() const; // Gets the number of all tests. int total_test_count() const; // Gets the number of tests that should run. int test_to_run_count() const; // Gets the time of the test program start, in ms from the start of the // UNIX epoch. TimeInMillis start_timestamp() const; // Gets the elapsed time, in milliseconds. TimeInMillis elapsed_time() const; // Returns true iff the unit test passed (i.e. all test cases passed). bool Passed() const; // Returns true iff the unit test failed (i.e. some test case failed // or something outside of all tests failed). bool Failed() const; // Gets the i-th test case among all the test cases. i can range from 0 to // total_test_case_count() - 1. If i is not in that range, returns NULL. const TestCase* GetTestCase(int i) const; // Returns the TestResult containing information on test failures and // properties logged outside of individual test cases. const TestResult& ad_hoc_test_result() const; // Returns the list of event listeners that can be used to track events // inside Google Test. TestEventListeners& listeners(); private: // Registers and returns a global test environment. When a test // program is run, all global test environments will be set-up in // the order they were registered. After all tests in the program // have finished, all global test environments will be torn-down in // the *reverse* order they were registered. // // The UnitTest object takes ownership of the given environment. // // This method can only be called from the main thread. Environment* AddEnvironment(Environment* env); // Adds a TestPartResult to the current TestResult object. All // Google Test assertion macros (e.g. ASSERT_TRUE, EXPECT_EQ, etc) // eventually call this to report their results. The user code // should use the assertion macros instead of calling this directly. void AddTestPartResult(TestPartResult::Type result_type, const char* file_name, int line_number, const std::string& message, const std::string& os_stack_trace) GTEST_LOCK_EXCLUDED_(mutex_); // Adds a TestProperty to the current TestResult object when invoked from // inside a test, to current TestCase's ad_hoc_test_result_ when invoked // from SetUpTestCase or TearDownTestCase, or to the global property set // when invoked elsewhere. If the result already contains a property with // the same key, the value will be updated. void RecordProperty(const std::string& key, const std::string& value); // Gets the i-th test case among all the test cases. i can range from 0 to // total_test_case_count() - 1. If i is not in that range, returns NULL. TestCase* GetMutableTestCase(int i); // Accessors for the implementation object. internal::UnitTestImpl* impl() { return impl_; } const internal::UnitTestImpl* impl() const { return impl_; } // These classes and funcions are friends as they need to access private // members of UnitTest. friend class Test; friend class internal::AssertHelper; friend class internal::ScopedTrace; friend class internal::StreamingListenerTest; friend class internal::UnitTestRecordPropertyTestHelper; friend Environment* AddGlobalTestEnvironment(Environment* env); friend internal::UnitTestImpl* internal::GetUnitTestImpl(); friend void internal::ReportFailureInUnknownLocation( TestPartResult::Type result_type, const std::string& message); // Creates an empty UnitTest. UnitTest(); // D'tor virtual ~UnitTest(); // Pushes a trace defined by SCOPED_TRACE() on to the per-thread // Google Test trace stack. void PushGTestTrace(const internal::TraceInfo& trace) GTEST_LOCK_EXCLUDED_(mutex_); // Pops a trace from the per-thread Google Test trace stack. void PopGTestTrace() GTEST_LOCK_EXCLUDED_(mutex_); // Protects mutable state in *impl_. This is mutable as some const // methods need to lock it too. mutable internal::Mutex mutex_; // Opaque implementation object. This field is never changed once // the object is constructed. We don't mark it as const here, as // doing so will cause a warning in the constructor of UnitTest. // Mutable state in *impl_ is protected by mutex_. internal::UnitTestImpl* impl_; // We disallow copying UnitTest. GTEST_DISALLOW_COPY_AND_ASSIGN_(UnitTest); }; // A convenient wrapper for adding an environment for the test // program. // // You should call this before RUN_ALL_TESTS() is called, probably in // main(). If you use gtest_main, you need to call this before main() // starts for it to take effect. For example, you can define a global // variable like this: // // testing::Environment* const foo_env = // testing::AddGlobalTestEnvironment(new FooEnvironment); // // However, we strongly recommend you to write your own main() and // call AddGlobalTestEnvironment() there, as relying on initialization // of global variables makes the code harder to read and may cause // problems when you register multiple environments from different // translation units and the environments have dependencies among them // (remember that the compiler doesn't guarantee the order in which // global variables from different translation units are initialized). inline Environment* AddGlobalTestEnvironment(Environment* env) { return UnitTest::GetInstance()->AddEnvironment(env); } // Initializes Google Test. This must be called before calling // RUN_ALL_TESTS(). In particular, it parses a command line for the // flags that Google Test recognizes. Whenever a Google Test flag is // seen, it is removed from argv, and *argc is decremented. // // No value is returned. Instead, the Google Test flag variables are // updated. // // Calling the function for the second time has no user-visible effect. GTEST_API_ void InitGoogleTest(int* argc, char** argv); // This overloaded version can be used in Windows programs compiled in // UNICODE mode. GTEST_API_ void InitGoogleTest(int* argc, wchar_t** argv); namespace internal { // FormatForComparison::Format(value) formats a // value of type ToPrint that is an operand of a comparison assertion // (e.g. ASSERT_EQ). OtherOperand is the type of the other operand in // the comparison, and is used to help determine the best way to // format the value. In particular, when the value is a C string // (char pointer) and the other operand is an STL string object, we // want to format the C string as a string, since we know it is // compared by value with the string object. If the value is a char // pointer but the other operand is not an STL string object, we don't // know whether the pointer is supposed to point to a NUL-terminated // string, and thus want to print it as a pointer to be safe. // // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. // The default case. template class FormatForComparison { public: static ::std::string Format(const ToPrint& value) { return ::testing::PrintToString(value); } }; // Array. template class FormatForComparison { public: static ::std::string Format(const ToPrint* value) { return FormatForComparison::Format(value); } }; // By default, print C string as pointers to be safe, as we don't know // whether they actually point to a NUL-terminated string. #define GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(CharType) \ template \ class FormatForComparison { \ public: \ static ::std::string Format(CharType* value) { \ return ::testing::PrintToString(static_cast(value)); \ } \ } GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(char); GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(const char); GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(wchar_t); GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(const wchar_t); #undef GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_ // If a C string is compared with an STL string object, we know it's meant // to point to a NUL-terminated string, and thus can print it as a string. #define GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(CharType, OtherStringType) \ template <> \ class FormatForComparison { \ public: \ static ::std::string Format(CharType* value) { \ return ::testing::PrintToString(value); \ } \ } GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(char, ::std::string); GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const char, ::std::string); #if GTEST_HAS_GLOBAL_STRING GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(char, ::string); GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const char, ::string); #endif #if GTEST_HAS_GLOBAL_WSTRING GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(wchar_t, ::wstring); GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const wchar_t, ::wstring); #endif #if GTEST_HAS_STD_WSTRING GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(wchar_t, ::std::wstring); GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const wchar_t, ::std::wstring); #endif #undef GTEST_IMPL_FORMAT_C_STRING_AS_STRING_ // Formats a comparison assertion (e.g. ASSERT_EQ, EXPECT_LT, and etc) // operand to be used in a failure message. The type (but not value) // of the other operand may affect the format. This allows us to // print a char* as a raw pointer when it is compared against another // char* or void*, and print it as a C string when it is compared // against an std::string object, for example. // // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. template std::string FormatForComparisonFailureMessage( const T1& value, const T2& /* other_operand */) { return FormatForComparison::Format(value); } // 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 if (expected == actual) { return AssertionSuccess(); } #ifdef _MSC_VER # pragma warning(pop) // Restores the warning state. #endif return EqFailure(expected_expression, actual_expression, FormatForComparisonFailureMessage(expected, actual), FormatForComparisonFailureMessage(actual, expected), false); } // With this overloaded version, we allow anonymous enums to be used // in {ASSERT|EXPECT}_EQ when compiled with gcc 4, as anonymous enums // can be implicitly cast to BiggestInt. GTEST_API_ AssertionResult CmpHelperEQ(const char* expected_expression, const char* actual_expression, BiggestInt expected, BiggestInt actual); // The helper class for {ASSERT|EXPECT}_EQ. The template argument // lhs_is_null_literal is true iff the first argument to ASSERT_EQ() // is a null pointer literal. The following default implementation is // for lhs_is_null_literal being false. template class EqHelper { public: // This templatized version is for the general case. template static AssertionResult Compare(const char* expected_expression, const char* actual_expression, const T1& expected, const T2& actual) { return CmpHelperEQ(expected_expression, actual_expression, expected, actual); } // With this overloaded version, we allow anonymous enums to be used // in {ASSERT|EXPECT}_EQ when compiled with gcc 4, as anonymous // enums can be implicitly cast to BiggestInt. // // Even though its body looks the same as the above version, we // cannot merge the two, as it will make anonymous enums unhappy. static AssertionResult Compare(const char* expected_expression, const char* actual_expression, BiggestInt expected, BiggestInt actual) { return CmpHelperEQ(expected_expression, actual_expression, expected, actual); } }; // This specialization is used when the first argument to ASSERT_EQ() // is a null pointer literal, like NULL, false, or 0. template <> class EqHelper { public: // We define two overloaded versions of Compare(). The first // version will be picked when the second argument to ASSERT_EQ() is // NOT a pointer, e.g. ASSERT_EQ(0, AnIntFunction()) or // EXPECT_EQ(false, a_bool). template static AssertionResult Compare( const char* expected_expression, const char* actual_expression, const T1& expected, const T2& actual, // The following line prevents this overload from being considered if T2 // is not a pointer type. We need this because ASSERT_EQ(NULL, my_ptr) // expands to Compare("", "", NULL, my_ptr), which requires a conversion // to match the Secret* in the other overload, which would otherwise make // this template match better. typename EnableIf::value>::type* = 0) { return CmpHelperEQ(expected_expression, actual_expression, expected, actual); } // This version will be picked when the second argument to ASSERT_EQ() is a // pointer, e.g. ASSERT_EQ(NULL, a_pointer). template static AssertionResult Compare( const char* expected_expression, const char* actual_expression, // We used to have a second template parameter instead of Secret*. That // template parameter would deduce to 'long', making this a better match // than the first overload even without the first overload's EnableIf. // Unfortunately, gcc with -Wconversion-null warns when "passing NULL to // non-pointer argument" (even a deduced integral argument), so the old // implementation caused warnings in user code. Secret* /* expected (NULL) */, T* actual) { // We already know that 'expected' is a null pointer. return CmpHelperEQ(expected_expression, actual_expression, static_cast(NULL), actual); } }; // A macro for implementing the helper functions needed to implement // ASSERT_?? and EXPECT_??. It is here just to avoid copy-and-paste // of similar code. // // For each templatized helper function, we also define an overloaded // version for BiggestInt in order to reduce code bloat and allow // anonymous enums to be used with {ASSERT|EXPECT}_?? when compiled // with gcc 4. // // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. #define GTEST_IMPL_CMP_HELPER_(op_name, op)\ template \ AssertionResult CmpHelper##op_name(const char* expr1, const char* expr2, \ const T1& val1, const T2& val2) {\ if (val1 op val2) {\ return AssertionSuccess();\ } else {\ return AssertionFailure() \ << "Expected: (" << expr1 << ") " #op " (" << expr2\ << "), actual: " << FormatForComparisonFailureMessage(val1, val2)\ << " vs " << FormatForComparisonFailureMessage(val2, val1);\ }\ }\ GTEST_API_ AssertionResult CmpHelper##op_name(\ const char* expr1, const char* expr2, BiggestInt val1, BiggestInt val2) // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. // Implements the helper function for {ASSERT|EXPECT}_NE GTEST_IMPL_CMP_HELPER_(NE, !=); // Implements the helper function for {ASSERT|EXPECT}_LE GTEST_IMPL_CMP_HELPER_(LE, <=); // Implements the helper function for {ASSERT|EXPECT}_LT GTEST_IMPL_CMP_HELPER_(LT, <); // Implements the helper function for {ASSERT|EXPECT}_GE GTEST_IMPL_CMP_HELPER_(GE, >=); // Implements the helper function for {ASSERT|EXPECT}_GT GTEST_IMPL_CMP_HELPER_(GT, >); #undef GTEST_IMPL_CMP_HELPER_ // The helper function for {ASSERT|EXPECT}_STREQ. // // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. GTEST_API_ AssertionResult CmpHelperSTREQ(const char* expected_expression, const char* actual_expression, const char* expected, const char* actual); // The helper function for {ASSERT|EXPECT}_STRCASEEQ. // // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. GTEST_API_ AssertionResult CmpHelperSTRCASEEQ(const char* expected_expression, const char* actual_expression, const char* expected, const char* actual); // The helper function for {ASSERT|EXPECT}_STRNE. // // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. GTEST_API_ AssertionResult CmpHelperSTRNE(const char* s1_expression, const char* s2_expression, const char* s1, const char* s2); // The helper function for {ASSERT|EXPECT}_STRCASENE. // // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. GTEST_API_ AssertionResult CmpHelperSTRCASENE(const char* s1_expression, const char* s2_expression, const char* s1, const char* s2); // Helper function for *_STREQ on wide strings. // // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. GTEST_API_ AssertionResult CmpHelperSTREQ(const char* expected_expression, const char* actual_expression, const wchar_t* expected, const wchar_t* actual); // Helper function for *_STRNE on wide strings. // // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. GTEST_API_ AssertionResult CmpHelperSTRNE(const char* s1_expression, const char* s2_expression, const wchar_t* s1, const wchar_t* s2); } // namespace internal // IsSubstring() and IsNotSubstring() are intended to be used as the // first argument to {EXPECT,ASSERT}_PRED_FORMAT2(), not by // themselves. They check whether needle is a substring of haystack // (NULL is considered a substring of itself only), and return an // appropriate error message when they fail. // // The {needle,haystack}_expr arguments are the stringified // expressions that generated the two real arguments. GTEST_API_ AssertionResult IsSubstring( const char* needle_expr, const char* haystack_expr, const char* needle, const char* haystack); GTEST_API_ AssertionResult IsSubstring( const char* needle_expr, const char* haystack_expr, const wchar_t* needle, const wchar_t* haystack); GTEST_API_ AssertionResult IsNotSubstring( const char* needle_expr, const char* haystack_expr, const char* needle, const char* haystack); GTEST_API_ AssertionResult IsNotSubstring( const char* needle_expr, const char* haystack_expr, const wchar_t* needle, const wchar_t* haystack); GTEST_API_ AssertionResult IsSubstring( const char* needle_expr, const char* haystack_expr, const ::std::string& needle, const ::std::string& haystack); GTEST_API_ AssertionResult IsNotSubstring( const char* needle_expr, const char* haystack_expr, const ::std::string& needle, const ::std::string& haystack); #if GTEST_HAS_STD_WSTRING GTEST_API_ AssertionResult IsSubstring( const char* needle_expr, const char* haystack_expr, const ::std::wstring& needle, const ::std::wstring& haystack); GTEST_API_ AssertionResult IsNotSubstring( const char* needle_expr, const char* haystack_expr, const ::std::wstring& needle, const ::std::wstring& haystack); #endif // GTEST_HAS_STD_WSTRING namespace internal { // Helper template function for comparing floating-points. // // Template parameter: // // RawType: the raw floating-point type (either float or double) // // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. template AssertionResult CmpHelperFloatingPointEQ(const char* expected_expression, const char* actual_expression, RawType expected, RawType actual) { const FloatingPoint lhs(expected), rhs(actual); if (lhs.AlmostEquals(rhs)) { return AssertionSuccess(); } ::std::stringstream expected_ss; expected_ss << std::setprecision(std::numeric_limits::digits10 + 2) << expected; ::std::stringstream actual_ss; actual_ss << std::setprecision(std::numeric_limits::digits10 + 2) << actual; return EqFailure(expected_expression, actual_expression, StringStreamToString(&expected_ss), StringStreamToString(&actual_ss), false); } // Helper function for implementing ASSERT_NEAR. // // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. GTEST_API_ AssertionResult DoubleNearPredFormat(const char* expr1, const char* expr2, const char* abs_error_expr, double val1, double val2, double abs_error); // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. // A class that enables one to stream messages to assertion macros class GTEST_API_ AssertHelper { public: // Constructor. AssertHelper(TestPartResult::Type type, const char* file, int line, const char* message); ~AssertHelper(); // Message assignment is a semantic trick to enable assertion // streaming; see the GTEST_MESSAGE_ macro below. void operator=(const Message& message) const; private: // We put our data in a struct so that the size of the AssertHelper class can // be as small as possible. This is important because gcc is incapable of // re-using stack space even for temporary variables, so every EXPECT_EQ // reserves stack space for another AssertHelper. struct AssertHelperData { AssertHelperData(TestPartResult::Type t, const char* srcfile, int line_num, const char* msg) : type(t), file(srcfile), line(line_num), message(msg) { } TestPartResult::Type const type; const char* const file; int const line; std::string const message; private: GTEST_DISALLOW_COPY_AND_ASSIGN_(AssertHelperData); }; AssertHelperData* const data_; GTEST_DISALLOW_COPY_AND_ASSIGN_(AssertHelper); }; } // namespace internal #if GTEST_HAS_PARAM_TEST // The pure interface class that all value-parameterized tests inherit from. // A value-parameterized class must inherit from both ::testing::Test and // ::testing::WithParamInterface. In most cases that just means inheriting // from ::testing::TestWithParam, but more complicated test hierarchies // may need to inherit from Test and WithParamInterface at different levels. // // This interface has support for accessing the test parameter value via // the GetParam() method. // // Use it with one of the parameter generator defining functions, like Range(), // Values(), ValuesIn(), Bool(), and Combine(). // // class FooTest : public ::testing::TestWithParam { // protected: // FooTest() { // // Can use GetParam() here. // } // virtual ~FooTest() { // // Can use GetParam() here. // } // virtual void SetUp() { // // Can use GetParam() here. // } // virtual void TearDown { // // Can use GetParam() here. // } // }; // TEST_P(FooTest, DoesBar) { // // Can use GetParam() method here. // Foo foo; // ASSERT_TRUE(foo.DoesBar(GetParam())); // } // INSTANTIATE_TEST_CASE_P(OneToTenRange, FooTest, ::testing::Range(1, 10)); template class WithParamInterface { public: typedef T ParamType; virtual ~WithParamInterface() {} // The current parameter value. Is also available in the test fixture's // constructor. This member function is non-static, even though it only // references static data, to reduce the opportunity for incorrect uses // like writing 'WithParamInterface::GetParam()' for a test that // uses a fixture whose parameter type is int. const ParamType& GetParam() const { GTEST_CHECK_(parameter_ != NULL) << "GetParam() can only be called inside a value-parameterized test " << "-- did you intend to write TEST_P instead of TEST_F?"; return *parameter_; } private: // Sets parameter value. The caller is responsible for making sure the value // remains alive and unchanged throughout the current test. static void SetParam(const ParamType* parameter) { parameter_ = parameter; } // Static value used for accessing parameter during a test lifetime. static const ParamType* parameter_; // TestClass must be a subclass of WithParamInterface and Test. template friend class internal::ParameterizedTestFactory; }; template const T* WithParamInterface::parameter_ = NULL; // Most value-parameterized classes can ignore the existence of // WithParamInterface, and can just inherit from ::testing::TestWithParam. template class TestWithParam : public Test, public WithParamInterface { }; #endif // GTEST_HAS_PARAM_TEST // Macros for indicating success/failure in test code. // ADD_FAILURE unconditionally adds a failure to the current test. // SUCCEED generates a success - it doesn't automatically make the // current test successful, as a test is only successful when it has // no failure. // // EXPECT_* verifies that a certain condition is satisfied. If not, // it behaves like ADD_FAILURE. In particular: // // EXPECT_TRUE verifies that a Boolean condition is true. // EXPECT_FALSE verifies that a Boolean condition is false. // // FAIL and ASSERT_* are similar to ADD_FAILURE and EXPECT_*, except // that they will also abort the current function on failure. People // usually want the fail-fast behavior of FAIL and ASSERT_*, but those // writing data-driven tests often find themselves using ADD_FAILURE // and EXPECT_* more. // Generates a nonfatal failure with a generic message. #define ADD_FAILURE() GTEST_NONFATAL_FAILURE_("Failed") // Generates a nonfatal failure at the given source file location with // a generic message. #define ADD_FAILURE_AT(file, line) \ GTEST_MESSAGE_AT_(file, line, "Failed", \ ::testing::TestPartResult::kNonFatalFailure) // Generates a fatal failure with a generic message. #define GTEST_FAIL() GTEST_FATAL_FAILURE_("Failed") // Define this macro to 1 to omit the definition of FAIL(), which is a // generic name and clashes with some other libraries. #if !GTEST_DONT_DEFINE_FAIL # define FAIL() GTEST_FAIL() #endif // Generates a success with a generic message. #define GTEST_SUCCEED() GTEST_SUCCESS_("Succeeded") // Define this macro to 1 to omit the definition of SUCCEED(), which // is a generic name and clashes with some other libraries. #if !GTEST_DONT_DEFINE_SUCCEED # define SUCCEED() GTEST_SUCCEED() #endif // Macros for testing exceptions. // // * {ASSERT|EXPECT}_THROW(statement, expected_exception): // Tests that the statement throws the expected exception. // * {ASSERT|EXPECT}_NO_THROW(statement): // Tests that the statement doesn't throw any exception. // * {ASSERT|EXPECT}_ANY_THROW(statement): // Tests that the statement throws an exception. #define EXPECT_THROW(statement, expected_exception) \ GTEST_TEST_THROW_(statement, expected_exception, GTEST_NONFATAL_FAILURE_) #define EXPECT_NO_THROW(statement) \ GTEST_TEST_NO_THROW_(statement, GTEST_NONFATAL_FAILURE_) #define EXPECT_ANY_THROW(statement) \ GTEST_TEST_ANY_THROW_(statement, GTEST_NONFATAL_FAILURE_) #define ASSERT_THROW(statement, expected_exception) \ GTEST_TEST_THROW_(statement, expected_exception, GTEST_FATAL_FAILURE_) #define ASSERT_NO_THROW(statement) \ GTEST_TEST_NO_THROW_(statement, GTEST_FATAL_FAILURE_) #define ASSERT_ANY_THROW(statement) \ GTEST_TEST_ANY_THROW_(statement, GTEST_FATAL_FAILURE_) // Boolean assertions. Condition can be either a Boolean expression or an // AssertionResult. For more information on how to use AssertionResult with // these macros see comments on that class. #define EXPECT_TRUE(condition) \ GTEST_TEST_BOOLEAN_(condition, #condition, false, true, \ GTEST_NONFATAL_FAILURE_) #define EXPECT_FALSE(condition) \ GTEST_TEST_BOOLEAN_(!(condition), #condition, true, false, \ GTEST_NONFATAL_FAILURE_) #define ASSERT_TRUE(condition) \ GTEST_TEST_BOOLEAN_(condition, #condition, false, true, \ GTEST_FATAL_FAILURE_) #define ASSERT_FALSE(condition) \ GTEST_TEST_BOOLEAN_(!(condition), #condition, true, false, \ GTEST_FATAL_FAILURE_) // Includes the auto-generated header that implements a family of // generic predicate assertion macros. #include "gtest/gtest_pred_impl.h" // Macros for testing equalities and inequalities. // // * {ASSERT|EXPECT}_EQ(expected, actual): Tests that expected == actual // * {ASSERT|EXPECT}_NE(v1, v2): Tests that v1 != v2 // * {ASSERT|EXPECT}_LT(v1, v2): Tests that v1 < v2 // * {ASSERT|EXPECT}_LE(v1, v2): Tests that v1 <= v2 // * {ASSERT|EXPECT}_GT(v1, v2): Tests that v1 > v2 // * {ASSERT|EXPECT}_GE(v1, v2): Tests that v1 >= v2 // // When they are not, Google Test prints both the tested expressions and // their actual values. The values must be compatible built-in types, // or you will get a compiler error. By "compatible" we mean that the // values can be compared by the respective operator. // // Note: // // 1. It is possible to make a user-defined type work with // {ASSERT|EXPECT}_??(), but that requires overloading the // comparison operators and is thus discouraged by the Google C++ // Usage Guide. Therefore, you are advised to use the // {ASSERT|EXPECT}_TRUE() macro to assert that two objects are // equal. // // 2. The {ASSERT|EXPECT}_??() macros do pointer comparisons on // pointers (in particular, C strings). Therefore, if you use it // with two C strings, you are testing how their locations in memory // are related, not how their content is related. To compare two C // strings by content, use {ASSERT|EXPECT}_STR*(). // // 3. {ASSERT|EXPECT}_EQ(expected, actual) is preferred to // {ASSERT|EXPECT}_TRUE(expected == actual), as the former tells you // what the actual value is when it fails, and similarly for the // other comparisons. // // 4. Do not depend on the order in which {ASSERT|EXPECT}_??() // evaluate their arguments, which is undefined. // // 5. These macros evaluate their arguments exactly once. // // Examples: // // EXPECT_NE(5, Foo()); // EXPECT_EQ(NULL, a_pointer); // ASSERT_LT(i, array_size); // ASSERT_GT(records.size(), 0) << "There is no record left."; #define EXPECT_EQ(expected, actual) \ EXPECT_PRED_FORMAT2(::testing::internal:: \ EqHelper::Compare, \ expected, actual) #define EXPECT_NE(expected, actual) \ EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperNE, expected, actual) #define EXPECT_LE(val1, val2) \ EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperLE, val1, val2) #define EXPECT_LT(val1, val2) \ EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperLT, val1, val2) #define EXPECT_GE(val1, val2) \ EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperGE, val1, val2) #define EXPECT_GT(val1, val2) \ EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperGT, val1, val2) #define GTEST_ASSERT_EQ(expected, actual) \ ASSERT_PRED_FORMAT2(::testing::internal:: \ EqHelper::Compare, \ expected, actual) #define GTEST_ASSERT_NE(val1, val2) \ ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperNE, val1, val2) #define GTEST_ASSERT_LE(val1, val2) \ ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperLE, val1, val2) #define GTEST_ASSERT_LT(val1, val2) \ ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperLT, val1, val2) #define GTEST_ASSERT_GE(val1, val2) \ ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperGE, val1, val2) #define GTEST_ASSERT_GT(val1, val2) \ ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperGT, val1, val2) // Define macro GTEST_DONT_DEFINE_ASSERT_XY to 1 to omit the definition of // ASSERT_XY(), which clashes with some users' own code. #if !GTEST_DONT_DEFINE_ASSERT_EQ # define ASSERT_EQ(val1, val2) GTEST_ASSERT_EQ(val1, val2) #endif #if !GTEST_DONT_DEFINE_ASSERT_NE # define ASSERT_NE(val1, val2) GTEST_ASSERT_NE(val1, val2) #endif #if !GTEST_DONT_DEFINE_ASSERT_LE # define ASSERT_LE(val1, val2) GTEST_ASSERT_LE(val1, val2) #endif #if !GTEST_DONT_DEFINE_ASSERT_LT # define ASSERT_LT(val1, val2) GTEST_ASSERT_LT(val1, val2) #endif #if !GTEST_DONT_DEFINE_ASSERT_GE # define ASSERT_GE(val1, val2) GTEST_ASSERT_GE(val1, val2) #endif #if !GTEST_DONT_DEFINE_ASSERT_GT # define ASSERT_GT(val1, val2) GTEST_ASSERT_GT(val1, val2) #endif // C-string Comparisons. All tests treat NULL and any non-NULL string // as different. Two NULLs are equal. // // * {ASSERT|EXPECT}_STREQ(s1, s2): Tests that s1 == s2 // * {ASSERT|EXPECT}_STRNE(s1, s2): Tests that s1 != s2 // * {ASSERT|EXPECT}_STRCASEEQ(s1, s2): Tests that s1 == s2, ignoring case // * {ASSERT|EXPECT}_STRCASENE(s1, s2): Tests that s1 != s2, ignoring case // // For wide or narrow string objects, you can use the // {ASSERT|EXPECT}_??() macros. // // Don't depend on the order in which the arguments are evaluated, // which is undefined. // // These macros evaluate their arguments exactly once. #define EXPECT_STREQ(expected, actual) \ EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTREQ, expected, actual) #define EXPECT_STRNE(s1, s2) \ EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTRNE, s1, s2) #define EXPECT_STRCASEEQ(expected, actual) \ EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASEEQ, expected, actual) #define EXPECT_STRCASENE(s1, s2)\ EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASENE, s1, s2) #define ASSERT_STREQ(expected, actual) \ ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTREQ, expected, actual) #define ASSERT_STRNE(s1, s2) \ ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTRNE, s1, s2) #define ASSERT_STRCASEEQ(expected, actual) \ ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASEEQ, expected, actual) #define ASSERT_STRCASENE(s1, s2)\ ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASENE, s1, s2) // Macros for comparing floating-point numbers. // // * {ASSERT|EXPECT}_FLOAT_EQ(expected, actual): // Tests that two float values are almost equal. // * {ASSERT|EXPECT}_DOUBLE_EQ(expected, actual): // Tests that two double values are almost equal. // * {ASSERT|EXPECT}_NEAR(v1, v2, abs_error): // Tests that v1 and v2 are within the given distance to each other. // // Google Test uses ULP-based comparison to automatically pick a default // error bound that is appropriate for the operands. See the // FloatingPoint template class in gtest-internal.h if you are // interested in the implementation details. #define EXPECT_FLOAT_EQ(expected, actual)\ EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ, \ expected, actual) #define EXPECT_DOUBLE_EQ(expected, actual)\ EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ, \ expected, actual) #define ASSERT_FLOAT_EQ(expected, actual)\ ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ, \ expected, actual) #define ASSERT_DOUBLE_EQ(expected, actual)\ ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ, \ expected, actual) #define EXPECT_NEAR(val1, val2, abs_error)\ EXPECT_PRED_FORMAT3(::testing::internal::DoubleNearPredFormat, \ val1, val2, abs_error) #define ASSERT_NEAR(val1, val2, abs_error)\ ASSERT_PRED_FORMAT3(::testing::internal::DoubleNearPredFormat, \ val1, val2, abs_error) // These predicate format functions work on floating-point values, and // can be used in {ASSERT|EXPECT}_PRED_FORMAT2*(), e.g. // // EXPECT_PRED_FORMAT2(testing::DoubleLE, Foo(), 5.0); // Asserts that val1 is less than, or almost equal to, val2. Fails // otherwise. In particular, it fails if either val1 or val2 is NaN. GTEST_API_ AssertionResult FloatLE(const char* expr1, const char* expr2, float val1, float val2); GTEST_API_ AssertionResult DoubleLE(const char* expr1, const char* expr2, double val1, double val2); #if GTEST_OS_WINDOWS // Macros that test for HRESULT failure and success, these are only useful // on Windows, and rely on Windows SDK macros and APIs to compile. // // * {ASSERT|EXPECT}_HRESULT_{SUCCEEDED|FAILED}(expr) // // When expr unexpectedly fails or succeeds, Google Test prints the // expected result and the actual result with both a human-readable // string representation of the error, if available, as well as the // hex result code. # define EXPECT_HRESULT_SUCCEEDED(expr) \ EXPECT_PRED_FORMAT1(::testing::internal::IsHRESULTSuccess, (expr)) # define ASSERT_HRESULT_SUCCEEDED(expr) \ ASSERT_PRED_FORMAT1(::testing::internal::IsHRESULTSuccess, (expr)) # define EXPECT_HRESULT_FAILED(expr) \ EXPECT_PRED_FORMAT1(::testing::internal::IsHRESULTFailure, (expr)) # define ASSERT_HRESULT_FAILED(expr) \ ASSERT_PRED_FORMAT1(::testing::internal::IsHRESULTFailure, (expr)) #endif // GTEST_OS_WINDOWS // Macros that execute statement and check that it doesn't generate new fatal // failures in the current thread. // // * {ASSERT|EXPECT}_NO_FATAL_FAILURE(statement); // // Examples: // // EXPECT_NO_FATAL_FAILURE(Process()); // ASSERT_NO_FATAL_FAILURE(Process()) << "Process() failed"; // #define ASSERT_NO_FATAL_FAILURE(statement) \ GTEST_TEST_NO_FATAL_FAILURE_(statement, GTEST_FATAL_FAILURE_) #define EXPECT_NO_FATAL_FAILURE(statement) \ GTEST_TEST_NO_FATAL_FAILURE_(statement, GTEST_NONFATAL_FAILURE_) // Causes a trace (including the source file path, the current line // number, and the given message) to be included in every test failure // message generated by code in the current scope. The effect is // undone when the control leaves the current scope. // // The message argument can be anything streamable to std::ostream. // // In the implementation, we include the current line number as part // of the dummy variable name, thus allowing multiple SCOPED_TRACE()s // to appear in the same block - as long as they are on different // lines. #define SCOPED_TRACE(message) \ ::testing::internal::ScopedTrace GTEST_CONCAT_TOKEN_(gtest_trace_, __LINE__)(\ __FILE__, __LINE__, ::testing::Message() << (message)) // Compile-time assertion for type equality. // StaticAssertTypeEq() compiles iff type1 and type2 are // the same type. The value it returns is not interesting. // // Instead of making StaticAssertTypeEq a class template, we make it a // function template that invokes a helper class template. This // prevents a user from misusing StaticAssertTypeEq by // defining objects of that type. // // CAVEAT: // // When used inside a method of a class template, // StaticAssertTypeEq() is effective ONLY IF the method is // instantiated. For example, given: // // template class Foo { // public: // void Bar() { testing::StaticAssertTypeEq(); } // }; // // the code: // // void Test1() { Foo foo; } // // will NOT generate a compiler error, as Foo::Bar() is never // actually instantiated. Instead, you need: // // void Test2() { Foo foo; foo.Bar(); } // // to cause a compiler error. template bool StaticAssertTypeEq() { (void)internal::StaticAssertTypeEqHelper(); return true; } // Defines a test. // // The first parameter is the name of the test case, and the second // parameter is the name of the test within the test case. // // The convention is to end the test case name with "Test". For // example, a test case for the Foo class can be named FooTest. // // The user should put his test code between braces after using this // macro. Example: // // TEST(FooTest, InitializesCorrectly) { // Foo foo; // EXPECT_TRUE(foo.StatusIsOK()); // } // Note that we call GetTestTypeId() instead of GetTypeId< // ::testing::Test>() here to get the type ID of testing::Test. This // is to work around a suspected linker bug when using Google Test as // a framework on Mac OS X. The bug causes GetTypeId< // ::testing::Test>() to return different values depending on whether // the call is from the Google Test framework itself or from user test // code. GetTestTypeId() is guaranteed to always return the same // value, as it always calls GetTypeId<>() from the Google Test // framework. #define GTEST_TEST(test_case_name, test_name)\ GTEST_TEST_(test_case_name, test_name, \ ::testing::Test, ::testing::internal::GetTestTypeId()) // Define this macro to 1 to omit the definition of TEST(), which // is a generic name and clashes with some other libraries. #if !GTEST_DONT_DEFINE_TEST # define TEST(test_case_name, test_name) GTEST_TEST(test_case_name, test_name) #endif // Defines a test that uses a test fixture. // // The first parameter is the name of the test fixture class, which // also doubles as the test case name. The second parameter is the // name of the test within the test case. // // A test fixture class must be declared earlier. The user should put // his test code between braces after using this macro. Example: // // class FooTest : public testing::Test { // protected: // virtual void SetUp() { b_.AddElement(3); } // // Foo a_; // Foo b_; // }; // // TEST_F(FooTest, InitializesCorrectly) { // EXPECT_TRUE(a_.StatusIsOK()); // } // // TEST_F(FooTest, ReturnsElementCountCorrectly) { // EXPECT_EQ(0, a_.size()); // EXPECT_EQ(1, b_.size()); // } #define TEST_F(test_fixture, test_name)\ GTEST_TEST_(test_fixture, test_name, test_fixture, \ ::testing::internal::GetTypeId()) } // namespace testing // Use this function in main() to run all tests. It returns 0 if all // tests are successful, or 1 otherwise. // // RUN_ALL_TESTS() should be invoked after the command line has been // parsed by InitGoogleTest(). // // This function was formerly a macro; thus, it is in the global // namespace and has an all-caps name. int RUN_ALL_TESTS() GTEST_MUST_USE_RESULT_; inline int RUN_ALL_TESTS() { return ::testing::UnitTest::GetInstance()->Run(); } #endif // GTEST_INCLUDE_GTEST_GTEST_H_ dlt-daemon-2.18.4/gtest-1.7.0/include/gtest/gtest_pred_impl.h000066400000000000000000000354511353342203500235340ustar00rootroot00000000000000// Copyright 2006, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // This file is AUTOMATICALLY GENERATED on 10/31/2011 by command // 'gen_gtest_pred_impl.py 5'. DO NOT EDIT BY HAND! // // Implements a family of generic predicate assertion macros. #ifndef GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_ #define GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_ // Makes sure this header is not included before gtest.h. #ifndef GTEST_INCLUDE_GTEST_GTEST_H_ # error Do not include gtest_pred_impl.h directly. Include gtest.h instead. #endif // GTEST_INCLUDE_GTEST_GTEST_H_ // This header implements a family of generic predicate assertion // macros: // // ASSERT_PRED_FORMAT1(pred_format, v1) // ASSERT_PRED_FORMAT2(pred_format, v1, v2) // ... // // where pred_format is a function or functor that takes n (in the // case of ASSERT_PRED_FORMATn) values and their source expression // text, and returns a testing::AssertionResult. See the definition // of ASSERT_EQ in gtest.h for an example. // // If you don't care about formatting, you can use the more // restrictive version: // // ASSERT_PRED1(pred, v1) // ASSERT_PRED2(pred, v1, v2) // ... // // where pred is an n-ary function or functor that returns bool, // and the values v1, v2, ..., must support the << operator for // streaming to std::ostream. // // We also define the EXPECT_* variations. // // For now we only support predicates whose arity is at most 5. // Please email googletestframework@googlegroups.com if you need // support for higher arities. // GTEST_ASSERT_ is the basic statement to which all of the assertions // in this file reduce. Don't use this in your code. #define GTEST_ASSERT_(expression, on_failure) \ GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ if (const ::testing::AssertionResult gtest_ar = (expression)) \ ; \ else \ on_failure(gtest_ar.failure_message()) // Helper function for implementing {EXPECT|ASSERT}_PRED1. Don't use // this in your code. template AssertionResult AssertPred1Helper(const char* pred_text, const char* e1, Pred pred, const T1& v1) { if (pred(v1)) return AssertionSuccess(); return AssertionFailure() << pred_text << "(" << e1 << ") evaluates to false, where" << "\n" << e1 << " evaluates to " << v1; } // Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT1. // Don't use this in your code. #define GTEST_PRED_FORMAT1_(pred_format, v1, on_failure)\ GTEST_ASSERT_(pred_format(#v1, v1), \ on_failure) // Internal macro for implementing {EXPECT|ASSERT}_PRED1. Don't use // this in your code. #define GTEST_PRED1_(pred, v1, on_failure)\ GTEST_ASSERT_(::testing::AssertPred1Helper(#pred, \ #v1, \ pred, \ v1), on_failure) // Unary predicate assertion macros. #define EXPECT_PRED_FORMAT1(pred_format, v1) \ GTEST_PRED_FORMAT1_(pred_format, v1, GTEST_NONFATAL_FAILURE_) #define EXPECT_PRED1(pred, v1) \ GTEST_PRED1_(pred, v1, GTEST_NONFATAL_FAILURE_) #define ASSERT_PRED_FORMAT1(pred_format, v1) \ GTEST_PRED_FORMAT1_(pred_format, v1, GTEST_FATAL_FAILURE_) #define ASSERT_PRED1(pred, v1) \ GTEST_PRED1_(pred, v1, GTEST_FATAL_FAILURE_) // Helper function for implementing {EXPECT|ASSERT}_PRED2. Don't use // this in your code. template AssertionResult AssertPred2Helper(const char* pred_text, const char* e1, const char* e2, Pred pred, const T1& v1, const T2& v2) { if (pred(v1, v2)) return AssertionSuccess(); return AssertionFailure() << pred_text << "(" << e1 << ", " << e2 << ") evaluates to false, where" << "\n" << e1 << " evaluates to " << v1 << "\n" << e2 << " evaluates to " << v2; } // Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT2. // Don't use this in your code. #define GTEST_PRED_FORMAT2_(pred_format, v1, v2, on_failure)\ GTEST_ASSERT_(pred_format(#v1, #v2, v1, v2), \ on_failure) // Internal macro for implementing {EXPECT|ASSERT}_PRED2. Don't use // this in your code. #define GTEST_PRED2_(pred, v1, v2, on_failure)\ GTEST_ASSERT_(::testing::AssertPred2Helper(#pred, \ #v1, \ #v2, \ pred, \ v1, \ v2), on_failure) // Binary predicate assertion macros. #define EXPECT_PRED_FORMAT2(pred_format, v1, v2) \ GTEST_PRED_FORMAT2_(pred_format, v1, v2, GTEST_NONFATAL_FAILURE_) #define EXPECT_PRED2(pred, v1, v2) \ GTEST_PRED2_(pred, v1, v2, GTEST_NONFATAL_FAILURE_) #define ASSERT_PRED_FORMAT2(pred_format, v1, v2) \ GTEST_PRED_FORMAT2_(pred_format, v1, v2, GTEST_FATAL_FAILURE_) #define ASSERT_PRED2(pred, v1, v2) \ GTEST_PRED2_(pred, v1, v2, GTEST_FATAL_FAILURE_) // Helper function for implementing {EXPECT|ASSERT}_PRED3. Don't use // this in your code. template AssertionResult AssertPred3Helper(const char* pred_text, const char* e1, const char* e2, const char* e3, Pred pred, const T1& v1, const T2& v2, const T3& v3) { if (pred(v1, v2, v3)) return AssertionSuccess(); return AssertionFailure() << pred_text << "(" << e1 << ", " << e2 << ", " << e3 << ") evaluates to false, where" << "\n" << e1 << " evaluates to " << v1 << "\n" << e2 << " evaluates to " << v2 << "\n" << e3 << " evaluates to " << v3; } // Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT3. // Don't use this in your code. #define GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, on_failure)\ GTEST_ASSERT_(pred_format(#v1, #v2, #v3, v1, v2, v3), \ on_failure) // Internal macro for implementing {EXPECT|ASSERT}_PRED3. Don't use // this in your code. #define GTEST_PRED3_(pred, v1, v2, v3, on_failure)\ GTEST_ASSERT_(::testing::AssertPred3Helper(#pred, \ #v1, \ #v2, \ #v3, \ pred, \ v1, \ v2, \ v3), on_failure) // Ternary predicate assertion macros. #define EXPECT_PRED_FORMAT3(pred_format, v1, v2, v3) \ GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, GTEST_NONFATAL_FAILURE_) #define EXPECT_PRED3(pred, v1, v2, v3) \ GTEST_PRED3_(pred, v1, v2, v3, GTEST_NONFATAL_FAILURE_) #define ASSERT_PRED_FORMAT3(pred_format, v1, v2, v3) \ GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, GTEST_FATAL_FAILURE_) #define ASSERT_PRED3(pred, v1, v2, v3) \ GTEST_PRED3_(pred, v1, v2, v3, GTEST_FATAL_FAILURE_) // Helper function for implementing {EXPECT|ASSERT}_PRED4. Don't use // this in your code. template AssertionResult AssertPred4Helper(const char* pred_text, const char* e1, const char* e2, const char* e3, const char* e4, Pred pred, const T1& v1, const T2& v2, const T3& v3, const T4& v4) { if (pred(v1, v2, v3, v4)) return AssertionSuccess(); return AssertionFailure() << pred_text << "(" << e1 << ", " << e2 << ", " << e3 << ", " << e4 << ") evaluates to false, where" << "\n" << e1 << " evaluates to " << v1 << "\n" << e2 << " evaluates to " << v2 << "\n" << e3 << " evaluates to " << v3 << "\n" << e4 << " evaluates to " << v4; } // Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT4. // Don't use this in your code. #define GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, on_failure)\ GTEST_ASSERT_(pred_format(#v1, #v2, #v3, #v4, v1, v2, v3, v4), \ on_failure) // Internal macro for implementing {EXPECT|ASSERT}_PRED4. Don't use // this in your code. #define GTEST_PRED4_(pred, v1, v2, v3, v4, on_failure)\ GTEST_ASSERT_(::testing::AssertPred4Helper(#pred, \ #v1, \ #v2, \ #v3, \ #v4, \ pred, \ v1, \ v2, \ v3, \ v4), on_failure) // 4-ary predicate assertion macros. #define EXPECT_PRED_FORMAT4(pred_format, v1, v2, v3, v4) \ GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, GTEST_NONFATAL_FAILURE_) #define EXPECT_PRED4(pred, v1, v2, v3, v4) \ GTEST_PRED4_(pred, v1, v2, v3, v4, GTEST_NONFATAL_FAILURE_) #define ASSERT_PRED_FORMAT4(pred_format, v1, v2, v3, v4) \ GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, GTEST_FATAL_FAILURE_) #define ASSERT_PRED4(pred, v1, v2, v3, v4) \ GTEST_PRED4_(pred, v1, v2, v3, v4, GTEST_FATAL_FAILURE_) // Helper function for implementing {EXPECT|ASSERT}_PRED5. Don't use // this in your code. template AssertionResult AssertPred5Helper(const char* pred_text, const char* e1, const char* e2, const char* e3, const char* e4, const char* e5, Pred pred, const T1& v1, const T2& v2, const T3& v3, const T4& v4, const T5& v5) { if (pred(v1, v2, v3, v4, v5)) return AssertionSuccess(); return AssertionFailure() << pred_text << "(" << e1 << ", " << e2 << ", " << e3 << ", " << e4 << ", " << e5 << ") evaluates to false, where" << "\n" << e1 << " evaluates to " << v1 << "\n" << e2 << " evaluates to " << v2 << "\n" << e3 << " evaluates to " << v3 << "\n" << e4 << " evaluates to " << v4 << "\n" << e5 << " evaluates to " << v5; } // Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT5. // Don't use this in your code. #define GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, on_failure)\ GTEST_ASSERT_(pred_format(#v1, #v2, #v3, #v4, #v5, v1, v2, v3, v4, v5), \ on_failure) // Internal macro for implementing {EXPECT|ASSERT}_PRED5. Don't use // this in your code. #define GTEST_PRED5_(pred, v1, v2, v3, v4, v5, on_failure)\ GTEST_ASSERT_(::testing::AssertPred5Helper(#pred, \ #v1, \ #v2, \ #v3, \ #v4, \ #v5, \ pred, \ v1, \ v2, \ v3, \ v4, \ v5), on_failure) // 5-ary predicate assertion macros. #define EXPECT_PRED_FORMAT5(pred_format, v1, v2, v3, v4, v5) \ GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, GTEST_NONFATAL_FAILURE_) #define EXPECT_PRED5(pred, v1, v2, v3, v4, v5) \ GTEST_PRED5_(pred, v1, v2, v3, v4, v5, GTEST_NONFATAL_FAILURE_) #define ASSERT_PRED_FORMAT5(pred_format, v1, v2, v3, v4, v5) \ GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, GTEST_FATAL_FAILURE_) #define ASSERT_PRED5(pred, v1, v2, v3, v4, v5) \ GTEST_PRED5_(pred, v1, v2, v3, v4, v5, GTEST_FATAL_FAILURE_) #endif // GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_ dlt-daemon-2.18.4/gtest-1.7.0/include/gtest/gtest_prod.h000066400000000000000000000044241353342203500225210ustar00rootroot00000000000000// Copyright 2006, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: wan@google.com (Zhanyong Wan) // // Google C++ Testing Framework definitions useful in production code. #ifndef GTEST_INCLUDE_GTEST_GTEST_PROD_H_ #define GTEST_INCLUDE_GTEST_GTEST_PROD_H_ // When you need to test the private or protected members of a class, // use the FRIEND_TEST macro to declare your tests as friends of the // class. For example: // // class MyClass { // private: // void MyMethod(); // FRIEND_TEST(MyClassTest, MyMethod); // }; // // class MyClassTest : public testing::Test { // // ... // }; // // TEST_F(MyClassTest, MyMethod) { // // Can call MyClass::MyMethod() here. // } #define FRIEND_TEST(test_case_name, test_name)\ friend class test_case_name##_##test_name##_Test #endif // GTEST_INCLUDE_GTEST_GTEST_PROD_H_ dlt-daemon-2.18.4/gtest-1.7.0/include/gtest/internal/000077500000000000000000000000001353342203500220065ustar00rootroot00000000000000dlt-daemon-2.18.4/gtest-1.7.0/include/gtest/internal/gtest-death-test-internal.h000066400000000000000000000321651353342203500271660ustar00rootroot00000000000000// Copyright 2005, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Authors: wan@google.com (Zhanyong Wan), eefacm@gmail.com (Sean Mcafee) // // The Google C++ Testing Framework (Google Test) // // This header file defines internal utilities needed for implementing // death tests. They are subject to change without notice. #ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_ #define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_ #include "gtest/internal/gtest-internal.h" #include namespace testing { namespace internal { GTEST_DECLARE_string_(internal_run_death_test); // Names of the flags (needed for parsing Google Test flags). const char kDeathTestStyleFlag[] = "death_test_style"; const char kDeathTestUseFork[] = "death_test_use_fork"; const char kInternalRunDeathTestFlag[] = "internal_run_death_test"; #if GTEST_HAS_DEATH_TEST // DeathTest is a class that hides much of the complexity of the // GTEST_DEATH_TEST_ macro. It is abstract; its static Create method // returns a concrete class that depends on the prevailing death test // style, as defined by the --gtest_death_test_style and/or // --gtest_internal_run_death_test flags. // In describing the results of death tests, these terms are used with // the corresponding definitions: // // exit status: The integer exit information in the format specified // by wait(2) // exit code: The integer code passed to exit(3), _exit(2), or // returned from main() class GTEST_API_ DeathTest { public: // Create returns false if there was an error determining the // appropriate action to take for the current death test; for example, // if the gtest_death_test_style flag is set to an invalid value. // The LastMessage method will return a more detailed message in that // case. Otherwise, the DeathTest pointer pointed to by the "test" // argument is set. If the death test should be skipped, the pointer // is set to NULL; otherwise, it is set to the address of a new concrete // DeathTest object that controls the execution of the current test. static bool Create(const char* statement, const RE* regex, const char* file, int line, DeathTest** test); DeathTest(); virtual ~DeathTest() { } // A helper class that aborts a death test when it's deleted. class ReturnSentinel { public: explicit ReturnSentinel(DeathTest* test) : test_(test) { } ~ReturnSentinel() { test_->Abort(TEST_ENCOUNTERED_RETURN_STATEMENT); } private: DeathTest* const test_; GTEST_DISALLOW_COPY_AND_ASSIGN_(ReturnSentinel); } GTEST_ATTRIBUTE_UNUSED_; // An enumeration of possible roles that may be taken when a death // test is encountered. EXECUTE means that the death test logic should // be executed immediately. OVERSEE means that the program should prepare // the appropriate environment for a child process to execute the death // test, then wait for it to complete. enum TestRole { OVERSEE_TEST, EXECUTE_TEST }; // An enumeration of the three reasons that a test might be aborted. enum AbortReason { TEST_ENCOUNTERED_RETURN_STATEMENT, TEST_THREW_EXCEPTION, TEST_DID_NOT_DIE }; // Assumes one of the above roles. virtual TestRole AssumeRole() = 0; // Waits for the death test to finish and returns its status. virtual int Wait() = 0; // Returns true if the death test passed; that is, the test process // exited during the test, its exit status matches a user-supplied // predicate, and its stderr output matches a user-supplied regular // expression. // The user-supplied predicate may be a macro expression rather // than a function pointer or functor, or else Wait and Passed could // be combined. virtual bool Passed(bool exit_status_ok) = 0; // Signals that the death test did not die as expected. virtual void Abort(AbortReason reason) = 0; // Returns a human-readable outcome message regarding the outcome of // the last death test. static const char* LastMessage(); static void set_last_death_test_message(const std::string& message); private: // A string containing a description of the outcome of the last death test. static std::string last_death_test_message_; GTEST_DISALLOW_COPY_AND_ASSIGN_(DeathTest); }; // Factory interface for death tests. May be mocked out for testing. class DeathTestFactory { public: virtual ~DeathTestFactory() { } virtual bool Create(const char* statement, const RE* regex, const char* file, int line, DeathTest** test) = 0; }; // A concrete DeathTestFactory implementation for normal use. class DefaultDeathTestFactory : public DeathTestFactory { public: virtual bool Create(const char* statement, const RE* regex, const char* file, int line, DeathTest** test); }; // Returns true if exit_status describes a process that was terminated // by a signal, or exited normally with a nonzero exit code. GTEST_API_ bool ExitedUnsuccessfully(int exit_status); // Traps C++ exceptions escaping statement and reports them as test // failures. Note that trapping SEH exceptions is not implemented here. # if GTEST_HAS_EXCEPTIONS # define GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, death_test) \ try { \ GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ } catch (const ::std::exception& gtest_exception) { \ fprintf(\ stderr, \ "\n%s: Caught std::exception-derived exception escaping the " \ "death test statement. Exception message: %s\n", \ ::testing::internal::FormatFileLocation(__FILE__, __LINE__).c_str(), \ gtest_exception.what()); \ fflush(stderr); \ death_test->Abort(::testing::internal::DeathTest::TEST_THREW_EXCEPTION); \ } catch (...) { \ death_test->Abort(::testing::internal::DeathTest::TEST_THREW_EXCEPTION); \ } # else # define GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, death_test) \ GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement) # endif // This macro is for implementing ASSERT_DEATH*, EXPECT_DEATH*, // ASSERT_EXIT*, and EXPECT_EXIT*. # define GTEST_DEATH_TEST_(statement, predicate, regex, fail) \ GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ if (::testing::internal::AlwaysTrue()) { \ const ::testing::internal::RE& gtest_regex = (regex); \ ::testing::internal::DeathTest* gtest_dt; \ if (!::testing::internal::DeathTest::Create(#statement, >est_regex, \ __FILE__, __LINE__, >est_dt)) { \ goto GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__); \ } \ if (gtest_dt != NULL) { \ ::testing::internal::scoped_ptr< ::testing::internal::DeathTest> \ gtest_dt_ptr(gtest_dt); \ switch (gtest_dt->AssumeRole()) { \ case ::testing::internal::DeathTest::OVERSEE_TEST: \ if (!gtest_dt->Passed(predicate(gtest_dt->Wait()))) { \ goto GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__); \ } \ break; \ case ::testing::internal::DeathTest::EXECUTE_TEST: { \ ::testing::internal::DeathTest::ReturnSentinel \ gtest_sentinel(gtest_dt); \ GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, gtest_dt); \ gtest_dt->Abort(::testing::internal::DeathTest::TEST_DID_NOT_DIE); \ break; \ } \ default: \ break; \ } \ } \ } else \ GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__): \ fail(::testing::internal::DeathTest::LastMessage()) // The symbol "fail" here expands to something into which a message // can be streamed. // This macro is for implementing ASSERT/EXPECT_DEBUG_DEATH when compiled in // NDEBUG mode. In this case we need the statements to be executed, the regex is // ignored, and the macro must accept a streamed message even though the message // is never printed. # define GTEST_EXECUTE_STATEMENT_(statement, regex) \ GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ if (::testing::internal::AlwaysTrue()) { \ GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ } else \ ::testing::Message() // A class representing the parsed contents of the // --gtest_internal_run_death_test flag, as it existed when // RUN_ALL_TESTS was called. class InternalRunDeathTestFlag { public: InternalRunDeathTestFlag(const std::string& a_file, int a_line, int an_index, int a_write_fd) : file_(a_file), line_(a_line), index_(an_index), write_fd_(a_write_fd) {} ~InternalRunDeathTestFlag() { if (write_fd_ >= 0) posix::Close(write_fd_); } const std::string& file() const { return file_; } int line() const { return line_; } int index() const { return index_; } int write_fd() const { return write_fd_; } private: std::string file_; int line_; int index_; int write_fd_; GTEST_DISALLOW_COPY_AND_ASSIGN_(InternalRunDeathTestFlag); }; // Returns a newly created InternalRunDeathTestFlag object with fields // initialized from the GTEST_FLAG(internal_run_death_test) flag if // the flag is specified; otherwise returns NULL. InternalRunDeathTestFlag* ParseInternalRunDeathTestFlag(); #else // GTEST_HAS_DEATH_TEST // This macro is used for implementing macros such as // EXPECT_DEATH_IF_SUPPORTED and ASSERT_DEATH_IF_SUPPORTED on systems where // death tests are not supported. Those macros must compile on such systems // iff EXPECT_DEATH and ASSERT_DEATH compile with the same parameters on // systems that support death tests. This allows one to write such a macro // on a system that does not support death tests and be sure that it will // compile on a death-test supporting system. // // Parameters: // statement - A statement that a macro such as EXPECT_DEATH would test // for program termination. This macro has to make sure this // statement is compiled but not executed, to ensure that // EXPECT_DEATH_IF_SUPPORTED compiles with a certain // parameter iff EXPECT_DEATH compiles with it. // regex - A regex that a macro such as EXPECT_DEATH would use to test // the output of statement. This parameter has to be // compiled but not evaluated by this macro, to ensure that // this macro only accepts expressions that a macro such as // EXPECT_DEATH would accept. // terminator - Must be an empty statement for EXPECT_DEATH_IF_SUPPORTED // and a return statement for ASSERT_DEATH_IF_SUPPORTED. // This ensures that ASSERT_DEATH_IF_SUPPORTED will not // compile inside functions where ASSERT_DEATH doesn't // compile. // // The branch that has an always false condition is used to ensure that // statement and regex are compiled (and thus syntactically correct) but // never executed. The unreachable code macro protects the terminator // statement from generating an 'unreachable code' warning in case // statement unconditionally returns or throws. The Message constructor at // the end allows the syntax of streaming additional messages into the // macro, for compilational compatibility with EXPECT_DEATH/ASSERT_DEATH. # define GTEST_UNSUPPORTED_DEATH_TEST_(statement, regex, terminator) \ GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ if (::testing::internal::AlwaysTrue()) { \ GTEST_LOG_(WARNING) \ << "Death tests are not supported on this platform.\n" \ << "Statement '" #statement "' cannot be verified."; \ } else if (::testing::internal::AlwaysFalse()) { \ ::testing::internal::RE::PartialMatch(".*", (regex)); \ GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ terminator; \ } else \ ::testing::Message() #endif // GTEST_HAS_DEATH_TEST } // namespace internal } // namespace testing #endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_ dlt-daemon-2.18.4/gtest-1.7.0/include/gtest/internal/gtest-filepath.h000066400000000000000000000226031353342203500251020ustar00rootroot00000000000000// Copyright 2008, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: keith.ray@gmail.com (Keith Ray) // // Google Test filepath utilities // // This header file declares classes and functions used internally by // Google Test. They are subject to change without notice. // // This file is #included in . // Do not include this header file separately! #ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_ #define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_ #include "gtest/internal/gtest-string.h" namespace testing { namespace internal { // FilePath - a class for file and directory pathname manipulation which // handles platform-specific conventions (like the pathname separator). // Used for helper functions for naming files in a directory for xml output. // Except for Set methods, all methods are const or static, which provides an // "immutable value object" -- useful for peace of mind. // A FilePath with a value ending in a path separator ("like/this/") represents // a directory, otherwise it is assumed to represent a file. In either case, // it may or may not represent an actual file or directory in the file system. // Names are NOT checked for syntax correctness -- no checking for illegal // characters, malformed paths, etc. class GTEST_API_ FilePath { public: FilePath() : pathname_("") { } FilePath(const FilePath& rhs) : pathname_(rhs.pathname_) { } explicit FilePath(const std::string& pathname) : pathname_(pathname) { Normalize(); } FilePath& operator=(const FilePath& rhs) { Set(rhs); return *this; } void Set(const FilePath& rhs) { pathname_ = rhs.pathname_; } const std::string& string() const { return pathname_; } const char* c_str() const { return pathname_.c_str(); } // Returns the current working directory, or "" if unsuccessful. static FilePath GetCurrentDir(); // Given directory = "dir", base_name = "test", number = 0, // extension = "xml", returns "dir/test.xml". If number is greater // than zero (e.g., 12), returns "dir/test_12.xml". // On Windows platform, uses \ as the separator rather than /. static FilePath MakeFileName(const FilePath& directory, const FilePath& base_name, int number, const char* extension); // Given directory = "dir", relative_path = "test.xml", // returns "dir/test.xml". // On Windows, uses \ as the separator rather than /. static FilePath ConcatPaths(const FilePath& directory, const FilePath& relative_path); // Returns a pathname for a file that does not currently exist. The pathname // will be directory/base_name.extension or // directory/base_name_.extension if directory/base_name.extension // already exists. The number will be incremented until a pathname is found // that does not already exist. // Examples: 'dir/foo_test.xml' or 'dir/foo_test_1.xml'. // There could be a race condition if two or more processes are calling this // function at the same time -- they could both pick the same filename. static FilePath GenerateUniqueFileName(const FilePath& directory, const FilePath& base_name, const char* extension); // Returns true iff the path is "". bool IsEmpty() const { return pathname_.empty(); } // If input name has a trailing separator character, removes it and returns // the name, otherwise return the name string unmodified. // On Windows platform, uses \ as the separator, other platforms use /. FilePath RemoveTrailingPathSeparator() const; // Returns a copy of the FilePath with the directory part removed. // Example: FilePath("path/to/file").RemoveDirectoryName() returns // FilePath("file"). If there is no directory part ("just_a_file"), it returns // the FilePath unmodified. If there is no file part ("just_a_dir/") it // returns an empty FilePath (""). // On Windows platform, '\' is the path separator, otherwise it is '/'. FilePath RemoveDirectoryName() const; // RemoveFileName returns the directory path with the filename removed. // Example: FilePath("path/to/file").RemoveFileName() returns "path/to/". // If the FilePath is "a_file" or "/a_file", RemoveFileName returns // FilePath("./") or, on Windows, FilePath(".\\"). If the filepath does // not have a file, like "just/a/dir/", it returns the FilePath unmodified. // On Windows platform, '\' is the path separator, otherwise it is '/'. FilePath RemoveFileName() const; // Returns a copy of the FilePath with the case-insensitive extension removed. // Example: FilePath("dir/file.exe").RemoveExtension("EXE") returns // FilePath("dir/file"). If a case-insensitive extension is not // found, returns a copy of the original FilePath. FilePath RemoveExtension(const char* extension) const; // Creates directories so that path exists. Returns true if successful or if // the directories already exist; returns false if unable to create // directories for any reason. Will also return false if the FilePath does // not represent a directory (that is, it doesn't end with a path separator). bool CreateDirectoriesRecursively() const; // Create the directory so that path exists. Returns true if successful or // if the directory already exists; returns false if unable to create the // directory for any reason, including if the parent directory does not // exist. Not named "CreateDirectory" because that's a macro on Windows. bool CreateFolder() const; // Returns true if FilePath describes something in the file-system, // either a file, directory, or whatever, and that something exists. bool FileOrDirectoryExists() const; // Returns true if pathname describes a directory in the file-system // that exists. bool DirectoryExists() const; // Returns true if FilePath ends with a path separator, which indicates that // it is intended to represent a directory. Returns false otherwise. // This does NOT check that a directory (or file) actually exists. bool IsDirectory() const; // Returns true if pathname describes a root directory. (Windows has one // root directory per disk drive.) bool IsRootDirectory() const; // Returns true if pathname describes an absolute path. bool IsAbsolutePath() const; private: // Replaces multiple consecutive separators with a single separator. // For example, "bar///foo" becomes "bar/foo". Does not eliminate other // redundancies that might be in a pathname involving "." or "..". // // A pathname with multiple consecutive separators may occur either through // user error or as a result of some scripts or APIs that generate a pathname // with a trailing separator. On other platforms the same API or script // may NOT generate a pathname with a trailing "/". Then elsewhere that // pathname may have another "/" and pathname components added to it, // without checking for the separator already being there. // The script language and operating system may allow paths like "foo//bar" // but some of the functions in FilePath will not handle that correctly. In // particular, RemoveTrailingPathSeparator() only removes one separator, and // it is called in CreateDirectoriesRecursively() assuming that it will change // a pathname from directory syntax (trailing separator) to filename syntax. // // On Windows this method also replaces the alternate path separator '/' with // the primary path separator '\\', so that for example "bar\\/\\foo" becomes // "bar\\foo". void Normalize(); // Returns a pointer to the last occurence of a valid path separator in // the FilePath. On Windows, for example, both '/' and '\' are valid path // separators. Returns NULL if no path separator was found. const char* FindLastPathSeparator() const; std::string pathname_; }; // class FilePath } // namespace internal } // namespace testing #endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_ dlt-daemon-2.18.4/gtest-1.7.0/include/gtest/internal/gtest-internal.h000066400000000000000000001261611353342203500251260ustar00rootroot00000000000000// Copyright 2005, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Authors: wan@google.com (Zhanyong Wan), eefacm@gmail.com (Sean Mcafee) // // The Google C++ Testing Framework (Google Test) // // This header file declares functions and macros used internally by // Google Test. They are subject to change without notice. #ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_ #define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_ #include "gtest/internal/gtest-port.h" #if GTEST_OS_LINUX # include # include # include # include #endif // GTEST_OS_LINUX #if GTEST_HAS_EXCEPTIONS # include #endif #include #include #include #include #include #include #include "gtest/gtest-message.h" #include "gtest/internal/gtest-string.h" #include "gtest/internal/gtest-filepath.h" #include "gtest/internal/gtest-type-util.h" // Due to C++ preprocessor weirdness, we need double indirection to // concatenate two tokens when one of them is __LINE__. Writing // // foo ## __LINE__ // // will result in the token foo__LINE__, instead of foo followed by // the current line number. For more details, see // http://www.parashift.com/c++-faq-lite/misc-technical-issues.html#faq-39.6 #define GTEST_CONCAT_TOKEN_(foo, bar) GTEST_CONCAT_TOKEN_IMPL_(foo, bar) #define GTEST_CONCAT_TOKEN_IMPL_(foo, bar) foo ## bar class ProtocolMessage; namespace proto2 { class Message; } namespace testing { // Forward declarations. class AssertionResult; // Result of an assertion. class Message; // Represents a failure message. class Test; // Represents a test. class TestInfo; // Information about a test. class TestPartResult; // Result of a test part. class UnitTest; // A collection of test cases. template ::std::string PrintToString(const T& value); namespace internal { struct TraceInfo; // Information about a trace point. class ScopedTrace; // Implements scoped trace. class TestInfoImpl; // Opaque implementation of TestInfo class UnitTestImpl; // Opaque implementation of UnitTest // How many times InitGoogleTest() has been called. GTEST_API_ extern int g_init_gtest_count; // The text used in failure messages to indicate the start of the // stack trace. GTEST_API_ extern const char kStackTraceMarker[]; // Two overloaded helpers for checking at compile time whether an // expression is a null pointer literal (i.e. NULL or any 0-valued // compile-time integral constant). Their return values have // different sizes, so we can use sizeof() to test which version is // picked by the compiler. These helpers have no implementations, as // we only need their signatures. // // Given IsNullLiteralHelper(x), the compiler will pick the first // version if x can be implicitly converted to Secret*, and pick the // second version otherwise. Since Secret is a secret and incomplete // type, the only expression a user can write that has type Secret* is // a null pointer literal. Therefore, we know that x is a null // pointer literal if and only if the first version is picked by the // compiler. char IsNullLiteralHelper(Secret* p); char (&IsNullLiteralHelper(...))[2]; // NOLINT // A compile-time bool constant that is true if and only if x is a // null pointer literal (i.e. NULL or any 0-valued compile-time // integral constant). #ifdef GTEST_ELLIPSIS_NEEDS_POD_ // We lose support for NULL detection where the compiler doesn't like // passing non-POD classes through ellipsis (...). # define GTEST_IS_NULL_LITERAL_(x) false #else # define GTEST_IS_NULL_LITERAL_(x) \ (sizeof(::testing::internal::IsNullLiteralHelper(x)) == 1) #endif // GTEST_ELLIPSIS_NEEDS_POD_ // Appends the user-supplied message to the Google-Test-generated message. GTEST_API_ std::string AppendUserMessage( const std::string& gtest_msg, const Message& user_msg); #if GTEST_HAS_EXCEPTIONS // This exception is thrown by (and only by) a failed Google Test // assertion when GTEST_FLAG(throw_on_failure) is true (if exceptions // are enabled). We derive it from std::runtime_error, which is for // errors presumably detectable only at run time. Since // std::runtime_error inherits from std::exception, many testing // frameworks know how to extract and print the message inside it. class GTEST_API_ GoogleTestFailureException : public ::std::runtime_error { public: explicit GoogleTestFailureException(const TestPartResult& failure); }; #endif // GTEST_HAS_EXCEPTIONS // A helper class for creating scoped traces in user programs. class GTEST_API_ ScopedTrace { public: // The c'tor pushes the given source file location and message onto // a trace stack maintained by Google Test. ScopedTrace(const char* file, int line, const Message& message); // The d'tor pops the info pushed by the c'tor. // // Note that the d'tor is not virtual in order to be efficient. // Don't inherit from ScopedTrace! ~ScopedTrace(); private: GTEST_DISALLOW_COPY_AND_ASSIGN_(ScopedTrace); } GTEST_ATTRIBUTE_UNUSED_; // A ScopedTrace object does its job in its // c'tor and d'tor. Therefore it doesn't // need to be used otherwise. // Constructs and returns the message for an equality assertion // (e.g. ASSERT_EQ, EXPECT_STREQ, etc) failure. // // The first four parameters are the expressions used in the assertion // and their values, as strings. For example, for ASSERT_EQ(foo, bar) // where foo is 5 and bar is 6, we have: // // expected_expression: "foo" // actual_expression: "bar" // expected_value: "5" // actual_value: "6" // // The ignoring_case parameter is true iff the assertion is a // *_STRCASEEQ*. When it's true, the string " (ignoring case)" will // be inserted into the message. GTEST_API_ AssertionResult EqFailure(const char* expected_expression, const char* actual_expression, const std::string& expected_value, const std::string& actual_value, bool ignoring_case); // Constructs a failure message for Boolean assertions such as EXPECT_TRUE. GTEST_API_ std::string GetBoolAssertionFailureMessage( const AssertionResult& assertion_result, const char* expression_text, const char* actual_predicate_value, const char* expected_predicate_value); // This template class represents an IEEE floating-point number // (either single-precision or double-precision, depending on the // template parameters). // // The purpose of this class is to do more sophisticated number // comparison. (Due to round-off error, etc, it's very unlikely that // two floating-points will be equal exactly. Hence a naive // comparison by the == operation often doesn't work.) // // Format of IEEE floating-point: // // The most-significant bit being the leftmost, an IEEE // floating-point looks like // // sign_bit exponent_bits fraction_bits // // Here, sign_bit is a single bit that designates the sign of the // number. // // For float, there are 8 exponent bits and 23 fraction bits. // // For double, there are 11 exponent bits and 52 fraction bits. // // More details can be found at // http://en.wikipedia.org/wiki/IEEE_floating-point_standard. // // Template parameter: // // RawType: the raw floating-point type (either float or double) template class FloatingPoint { public: // Defines the unsigned integer type that has the same size as the // floating point number. typedef typename TypeWithSize::UInt Bits; // Constants. // # of bits in a number. static const size_t kBitCount = 8*sizeof(RawType); // # of fraction bits in a number. static const size_t kFractionBitCount = std::numeric_limits::digits - 1; // # of exponent bits in a number. static const size_t kExponentBitCount = kBitCount - 1 - kFractionBitCount; // The mask for the sign bit. static const Bits kSignBitMask = static_cast(1) << (kBitCount - 1); // The mask for the fraction bits. static const Bits kFractionBitMask = ~static_cast(0) >> (kExponentBitCount + 1); // The mask for the exponent bits. static const Bits kExponentBitMask = ~(kSignBitMask | kFractionBitMask); // How many ULP's (Units in the Last Place) we want to tolerate when // comparing two numbers. The larger the value, the more error we // allow. A 0 value means that two numbers must be exactly the same // to be considered equal. // // The maximum error of a single floating-point operation is 0.5 // units in the last place. On Intel CPU's, all floating-point // calculations are done with 80-bit precision, while double has 64 // bits. Therefore, 4 should be enough for ordinary use. // // See the following article for more details on ULP: // http://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/ static const size_t kMaxUlps = 4; // Constructs a FloatingPoint from a raw floating-point number. // // On an Intel CPU, passing a non-normalized NAN (Not a Number) // around may change its bits, although the new value is guaranteed // to be also a NAN. Therefore, don't expect this constructor to // preserve the bits in x when x is a NAN. explicit FloatingPoint(const RawType& x) { u_.value_ = x; } // Static methods // Reinterprets a bit pattern as a floating-point number. // // This function is needed to test the AlmostEquals() method. static RawType ReinterpretBits(const Bits bits) { FloatingPoint fp(0); fp.u_.bits_ = bits; return fp.u_.value_; } // Returns the floating-point number that represent positive infinity. static RawType Infinity() { return ReinterpretBits(kExponentBitMask); } // Returns the maximum representable finite floating-point number. static RawType Max(); // Non-static methods // Returns the bits that represents this number. const Bits &bits() const { return u_.bits_; } // Returns the exponent bits of this number. Bits exponent_bits() const { return kExponentBitMask & u_.bits_; } // Returns the fraction bits of this number. Bits fraction_bits() const { return kFractionBitMask & u_.bits_; } // Returns the sign bit of this number. Bits sign_bit() const { return kSignBitMask & u_.bits_; } // Returns true iff this is NAN (not a number). bool is_nan() const { // It's a NAN if the exponent bits are all ones and the fraction // bits are not entirely zeros. return (exponent_bits() == kExponentBitMask) && (fraction_bits() != 0); } // Returns true iff this number is at most kMaxUlps ULP's away from // rhs. In particular, this function: // // - returns false if either number is (or both are) NAN. // - treats really large numbers as almost equal to infinity. // - thinks +0.0 and -0.0 are 0 DLP's apart. bool AlmostEquals(const FloatingPoint& rhs) const { // The IEEE standard says that any comparison operation involving // a NAN must return false. if (is_nan() || rhs.is_nan()) return false; return DistanceBetweenSignAndMagnitudeNumbers(u_.bits_, rhs.u_.bits_) <= kMaxUlps; } private: // The data type used to store the actual floating-point number. union FloatingPointUnion { RawType value_; // The raw floating-point number. Bits bits_; // The bits that represent the number. }; // Converts an integer from the sign-and-magnitude representation to // the biased representation. More precisely, let N be 2 to the // power of (kBitCount - 1), an integer x is represented by the // unsigned number x + N. // // For instance, // // -N + 1 (the most negative number representable using // sign-and-magnitude) is represented by 1; // 0 is represented by N; and // N - 1 (the biggest number representable using // sign-and-magnitude) is represented by 2N - 1. // // Read http://en.wikipedia.org/wiki/Signed_number_representations // for more details on signed number representations. static Bits SignAndMagnitudeToBiased(const Bits &sam) { if (kSignBitMask & sam) { // sam represents a negative number. return ~sam + 1; } else { // sam represents a positive number. return kSignBitMask | sam; } } // Given two numbers in the sign-and-magnitude representation, // returns the distance between them as an unsigned number. static Bits DistanceBetweenSignAndMagnitudeNumbers(const Bits &sam1, const Bits &sam2) { const Bits biased1 = SignAndMagnitudeToBiased(sam1); const Bits biased2 = SignAndMagnitudeToBiased(sam2); return (biased1 >= biased2) ? (biased1 - biased2) : (biased2 - biased1); } FloatingPointUnion u_; }; // We cannot use std::numeric_limits::max() as it clashes with the max() // macro defined by . template <> inline float FloatingPoint::Max() { return FLT_MAX; } template <> inline double FloatingPoint::Max() { return DBL_MAX; } // Typedefs the instances of the FloatingPoint template class that we // care to use. typedef FloatingPoint Float; typedef FloatingPoint Double; // In order to catch the mistake of putting tests that use different // test fixture classes in the same test case, we need to assign // unique IDs to fixture classes and compare them. The TypeId type is // used to hold such IDs. The user should treat TypeId as an opaque // type: the only operation allowed on TypeId values is to compare // them for equality using the == operator. typedef const void* TypeId; template class TypeIdHelper { public: // dummy_ must not have a const type. Otherwise an overly eager // compiler (e.g. MSVC 7.1 & 8.0) may try to merge // TypeIdHelper::dummy_ for different Ts as an "optimization". static bool dummy_; }; template bool TypeIdHelper::dummy_ = false; // GetTypeId() returns the ID of type T. Different values will be // returned for different types. Calling the function twice with the // same type argument is guaranteed to return the same ID. template TypeId GetTypeId() { // The compiler is required to allocate a different // TypeIdHelper::dummy_ variable for each T used to instantiate // the template. Therefore, the address of dummy_ is guaranteed to // be unique. return &(TypeIdHelper::dummy_); } // Returns the type ID of ::testing::Test. Always call this instead // of GetTypeId< ::testing::Test>() to get the type ID of // ::testing::Test, as the latter may give the wrong result due to a // suspected linker bug when compiling Google Test as a Mac OS X // framework. GTEST_API_ TypeId GetTestTypeId(); // Defines the abstract factory interface that creates instances // of a Test object. class TestFactoryBase { public: virtual ~TestFactoryBase() {} // Creates a test instance to run. The instance is both created and destroyed // within TestInfoImpl::Run() virtual Test* CreateTest() = 0; protected: TestFactoryBase() {} private: GTEST_DISALLOW_COPY_AND_ASSIGN_(TestFactoryBase); }; // This class provides implementation of TeastFactoryBase interface. // It is used in TEST and TEST_F macros. template class TestFactoryImpl : public TestFactoryBase { public: virtual Test* CreateTest() { return new TestClass; } }; #if GTEST_OS_WINDOWS // Predicate-formatters for implementing the HRESULT checking macros // {ASSERT|EXPECT}_HRESULT_{SUCCEEDED|FAILED} // We pass a long instead of HRESULT to avoid causing an // include dependency for the HRESULT type. GTEST_API_ AssertionResult IsHRESULTSuccess(const char* expr, long hr); // NOLINT GTEST_API_ AssertionResult IsHRESULTFailure(const char* expr, long hr); // NOLINT #endif // GTEST_OS_WINDOWS // Types of SetUpTestCase() and TearDownTestCase() functions. typedef void (*SetUpTestCaseFunc)(); typedef void (*TearDownTestCaseFunc)(); // Creates a new TestInfo object and registers it with Google Test; // returns the created object. // // Arguments: // // test_case_name: name of the test case // name: name of the test // type_param the name of the test's type parameter, or NULL if // this is not a typed or a type-parameterized test. // value_param text representation of the test's value parameter, // or NULL if this is not a type-parameterized test. // fixture_class_id: ID of the test fixture class // set_up_tc: pointer to the function that sets up the test case // tear_down_tc: pointer to the function that tears down the test case // factory: pointer to the factory that creates a test object. // The newly created TestInfo instance will assume // ownership of the factory object. GTEST_API_ TestInfo* MakeAndRegisterTestInfo( const char* test_case_name, const char* name, const char* type_param, const char* value_param, TypeId fixture_class_id, SetUpTestCaseFunc set_up_tc, TearDownTestCaseFunc tear_down_tc, TestFactoryBase* factory); // If *pstr starts with the given prefix, modifies *pstr to be right // past the prefix and returns true; otherwise leaves *pstr unchanged // and returns false. None of pstr, *pstr, and prefix can be NULL. GTEST_API_ bool SkipPrefix(const char* prefix, const char** pstr); #if GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P // State of the definition of a type-parameterized test case. class GTEST_API_ TypedTestCasePState { public: TypedTestCasePState() : registered_(false) {} // Adds the given test name to defined_test_names_ and return true // if the test case hasn't been registered; otherwise aborts the // program. bool AddTestName(const char* file, int line, const char* case_name, const char* test_name) { if (registered_) { fprintf(stderr, "%s Test %s must be defined before " "REGISTER_TYPED_TEST_CASE_P(%s, ...).\n", FormatFileLocation(file, line).c_str(), test_name, case_name); fflush(stderr); posix::Abort(); } defined_test_names_.insert(test_name); return true; } // Verifies that registered_tests match the test names in // defined_test_names_; returns registered_tests if successful, or // aborts the program otherwise. const char* VerifyRegisteredTestNames( const char* file, int line, const char* registered_tests); private: bool registered_; ::std::set defined_test_names_; }; // Skips to the first non-space char after the first comma in 'str'; // returns NULL if no comma is found in 'str'. inline const char* SkipComma(const char* str) { const char* comma = strchr(str, ','); if (comma == NULL) { return NULL; } while (IsSpace(*(++comma))) {} return comma; } // Returns the prefix of 'str' before the first comma in it; returns // the entire string if it contains no comma. inline std::string GetPrefixUntilComma(const char* str) { const char* comma = strchr(str, ','); return comma == NULL ? str : std::string(str, comma); } // TypeParameterizedTest::Register() // registers a list of type-parameterized tests with Google Test. The // return value is insignificant - we just need to return something // such that we can call this function in a namespace scope. // // Implementation note: The GTEST_TEMPLATE_ macro declares a template // template parameter. It's defined in gtest-type-util.h. template class TypeParameterizedTest { public: // 'index' is the index of the test in the type list 'Types' // specified in INSTANTIATE_TYPED_TEST_CASE_P(Prefix, TestCase, // Types). Valid values for 'index' are [0, N - 1] where N is the // length of Types. static bool Register(const char* prefix, const char* case_name, const char* test_names, int index) { typedef typename Types::Head Type; typedef Fixture FixtureClass; typedef typename GTEST_BIND_(TestSel, Type) TestClass; // First, registers the first type-parameterized test in the type // list. MakeAndRegisterTestInfo( (std::string(prefix) + (prefix[0] == '\0' ? "" : "/") + case_name + "/" + StreamableToString(index)).c_str(), GetPrefixUntilComma(test_names).c_str(), GetTypeName().c_str(), NULL, // No value parameter. GetTypeId(), TestClass::SetUpTestCase, TestClass::TearDownTestCase, new TestFactoryImpl); // Next, recurses (at compile time) with the tail of the type list. return TypeParameterizedTest ::Register(prefix, case_name, test_names, index + 1); } }; // The base case for the compile time recursion. template class TypeParameterizedTest { public: static bool Register(const char* /*prefix*/, const char* /*case_name*/, const char* /*test_names*/, int /*index*/) { return true; } }; // TypeParameterizedTestCase::Register() // registers *all combinations* of 'Tests' and 'Types' with Google // Test. The return value is insignificant - we just need to return // something such that we can call this function in a namespace scope. template class TypeParameterizedTestCase { public: static bool Register(const char* prefix, const char* case_name, const char* test_names) { typedef typename Tests::Head Head; // First, register the first test in 'Test' for each type in 'Types'. TypeParameterizedTest::Register( prefix, 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)); } }; // The base case for the compile time recursion. template class TypeParameterizedTestCase { public: static bool Register(const char* /*prefix*/, const char* /*case_name*/, const char* /*test_names*/) { return true; } }; #endif // GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P // Returns the current OS stack trace as an std::string. // // The maximum number of stack frames to be included is specified by // the gtest_stack_trace_depth flag. The skip_count parameter // specifies the number of top frames to be skipped, which doesn't // count against the number of frames to be included. // // For example, if Foo() calls Bar(), which in turn calls // GetCurrentOsStackTraceExceptTop(..., 1), Foo() will be included in // the trace but Bar() and GetCurrentOsStackTraceExceptTop() won't. GTEST_API_ std::string GetCurrentOsStackTraceExceptTop( UnitTest* unit_test, int skip_count); // Helpers for suppressing warnings on unreachable code or constant // condition. // Always returns true. GTEST_API_ bool AlwaysTrue(); // Always returns false. inline bool AlwaysFalse() { return !AlwaysTrue(); } // Helper for suppressing false warning from Clang on a const char* // variable declared in a conditional expression always being NULL in // the else branch. struct GTEST_API_ ConstCharPtr { ConstCharPtr(const char* str) : value(str) {} operator bool() const { return true; } const char* value; }; // A simple Linear Congruential Generator for generating random // numbers with a uniform distribution. Unlike rand() and srand(), it // doesn't use global state (and therefore can't interfere with user // code). Unlike rand_r(), it's portable. An LCG isn't very random, // but it's good enough for our purposes. class GTEST_API_ Random { public: static const UInt32 kMaxRange = 1u << 31; explicit Random(UInt32 seed) : state_(seed) {} void Reseed(UInt32 seed) { state_ = seed; } // Generates a random number from [0, range). Crashes if 'range' is // 0 or greater than kMaxRange. UInt32 Generate(UInt32 range); private: UInt32 state_; GTEST_DISALLOW_COPY_AND_ASSIGN_(Random); }; // Defining a variable of type CompileAssertTypesEqual will cause a // compiler error iff T1 and T2 are different types. template struct CompileAssertTypesEqual; template struct CompileAssertTypesEqual { }; // Removes the reference from a type if it is a reference type, // otherwise leaves it unchanged. This is the same as // tr1::remove_reference, which is not widely available yet. template struct RemoveReference { typedef T type; }; // NOLINT template struct RemoveReference { typedef T type; }; // NOLINT // A handy wrapper around RemoveReference that works when the argument // T depends on template parameters. #define GTEST_REMOVE_REFERENCE_(T) \ typename ::testing::internal::RemoveReference::type // Removes const from a type if it is a const type, otherwise leaves // it unchanged. This is the same as tr1::remove_const, which is not // widely available yet. template struct RemoveConst { typedef T type; }; // NOLINT template struct RemoveConst { typedef T type; }; // NOLINT // MSVC 8.0, Sun C++, and IBM XL C++ have a bug which causes the above // definition to fail to remove the const in 'const int[3]' and 'const // char[3][4]'. The following specialization works around the bug. template struct RemoveConst { typedef typename RemoveConst::type type[N]; }; #if defined(_MSC_VER) && _MSC_VER < 1400 // This is the only specialization that allows VC++ 7.1 to remove const in // 'const int[3] and 'const int[3][4]'. However, it causes trouble with GCC // and thus needs to be conditionally compiled. template struct RemoveConst { typedef typename RemoveConst::type type[N]; }; #endif // A handy wrapper around RemoveConst that works when the argument // T depends on template parameters. #define GTEST_REMOVE_CONST_(T) \ typename ::testing::internal::RemoveConst::type // Turns const U&, U&, const U, and U all into U. #define GTEST_REMOVE_REFERENCE_AND_CONST_(T) \ GTEST_REMOVE_CONST_(GTEST_REMOVE_REFERENCE_(T)) // Adds reference to a type if it is not a reference type, // otherwise leaves it unchanged. This is the same as // tr1::add_reference, which is not widely available yet. template struct AddReference { typedef T& type; }; // NOLINT template struct AddReference { typedef T& type; }; // NOLINT // A handy wrapper around AddReference that works when the argument T // depends on template parameters. #define GTEST_ADD_REFERENCE_(T) \ typename ::testing::internal::AddReference::type // Adds a reference to const on top of T as necessary. For example, // it transforms // // char ==> const char& // const char ==> const char& // char& ==> const char& // const char& ==> const char& // // The argument T must depend on some template parameters. #define GTEST_REFERENCE_TO_CONST_(T) \ GTEST_ADD_REFERENCE_(const GTEST_REMOVE_REFERENCE_(T)) // ImplicitlyConvertible::value is a compile-time bool // constant that's true iff type From can be implicitly converted to // type To. template class ImplicitlyConvertible { private: // We need the following helper functions only for their types. // They have no implementations. // MakeFrom() is an expression whose type is From. We cannot simply // use From(), as the type From may not have a public default // constructor. static From MakeFrom(); // These two functions are overloaded. Given an expression // Helper(x), the compiler will pick the first version if x can be // implicitly converted to type To; otherwise it will pick the // second version. // // The first version returns a value of size 1, and the second // version returns a value of size 2. Therefore, by checking the // size of Helper(x), which can be done at compile time, we can tell // which version of Helper() is used, and hence whether x can be // implicitly converted to type To. static char Helper(To); static char (&Helper(...))[2]; // NOLINT // We have to put the 'public' section after the 'private' section, // or MSVC refuses to compile the code. public: // MSVC warns about implicitly converting from double to int for // possible loss of data, so we need to temporarily disable the // warning. #ifdef _MSC_VER # pragma warning(push) // Saves the current warning state. # pragma warning(disable:4244) // Temporarily disables warning 4244. static const bool value = sizeof(Helper(ImplicitlyConvertible::MakeFrom())) == 1; # pragma warning(pop) // Restores the warning state. #elif defined(__BORLANDC__) // C++Builder cannot use member overload resolution during template // instantiation. The simplest workaround is to use its C++0x type traits // functions (C++Builder 2009 and above only). static const bool value = __is_convertible(From, To); #else static const bool value = sizeof(Helper(ImplicitlyConvertible::MakeFrom())) == 1; #endif // _MSV_VER }; template const bool ImplicitlyConvertible::value; // IsAProtocolMessage::value is a compile-time bool constant that's // true iff T is type ProtocolMessage, proto2::Message, or a subclass // of those. template struct IsAProtocolMessage : public bool_constant< ImplicitlyConvertible::value || ImplicitlyConvertible::value> { }; // When the compiler sees expression IsContainerTest(0), if C is an // STL-style container class, the first overload of IsContainerTest // will be viable (since both C::iterator* and C::const_iterator* are // valid types and NULL can be implicitly converted to them). It will // be picked over the second overload as 'int' is a perfect match for // the type of argument 0. If C::iterator or C::const_iterator is not // a valid type, the first overload is not viable, and the second // overload will be picked. Therefore, we can determine whether C is // a container class by checking the type of IsContainerTest(0). // The value of the expression is insignificant. // // Note that we look for both C::iterator and C::const_iterator. The // reason is that C++ injects the name of a class as a member of the // class itself (e.g. you can refer to class iterator as either // 'iterator' or 'iterator::iterator'). If we look for C::iterator // only, for example, we would mistakenly think that a class named // iterator is an STL container. // // Also note that the simpler approach of overloading // IsContainerTest(typename C::const_iterator*) and // IsContainerTest(...) doesn't work with Visual Age C++ and Sun C++. typedef int IsContainer; template IsContainer IsContainerTest(int /* dummy */, typename C::iterator* /* it */ = NULL, typename C::const_iterator* /* const_it */ = NULL) { return 0; } typedef char IsNotContainer; template IsNotContainer IsContainerTest(long /* dummy */) { return '\0'; } // EnableIf::type is void when 'Cond' is true, and // undefined when 'Cond' is false. To use SFINAE to make a function // overload only apply when a particular expression is true, add // "typename EnableIf::type* = 0" as the last parameter. template struct EnableIf; template<> struct EnableIf { typedef void type; }; // NOLINT // Utilities for native arrays. // ArrayEq() compares two k-dimensional native arrays using the // elements' operator==, where k can be any integer >= 0. When k is // 0, ArrayEq() degenerates into comparing a single pair of values. template bool ArrayEq(const T* lhs, size_t size, const U* rhs); // This generic version is used when k is 0. template inline bool ArrayEq(const T& lhs, const U& rhs) { return lhs == rhs; } // This overload is used when k >= 1. template inline bool ArrayEq(const T(&lhs)[N], const U(&rhs)[N]) { return internal::ArrayEq(lhs, N, rhs); } // This helper reduces code bloat. If we instead put its logic inside // the previous ArrayEq() function, arrays with different sizes would // lead to different copies of the template code. template bool ArrayEq(const T* lhs, size_t size, const U* rhs) { for (size_t i = 0; i != size; i++) { if (!internal::ArrayEq(lhs[i], rhs[i])) return false; } return true; } // Finds the first element in the iterator range [begin, end) that // equals elem. Element may be a native array type itself. template Iter ArrayAwareFind(Iter begin, Iter end, const Element& elem) { for (Iter it = begin; it != end; ++it) { if (internal::ArrayEq(*it, elem)) return it; } return end; } // CopyArray() copies a k-dimensional native array using the elements' // operator=, where k can be any integer >= 0. When k is 0, // CopyArray() degenerates into copying a single value. template void CopyArray(const T* from, size_t size, U* to); // This generic version is used when k is 0. template inline void CopyArray(const T& from, U* to) { *to = from; } // This overload is used when k >= 1. template inline void CopyArray(const T(&from)[N], U(*to)[N]) { internal::CopyArray(from, N, *to); } // This helper reduces code bloat. If we instead put its logic inside // the previous CopyArray() function, arrays with different sizes // would lead to different copies of the template code. template void CopyArray(const T* from, size_t size, U* to) { for (size_t i = 0; i != size; i++) { internal::CopyArray(from[i], to + i); } } // The relation between an NativeArray object (see below) and the // native array it represents. enum RelationToSource { kReference, // The NativeArray references the native array. kCopy // The NativeArray makes a copy of the native array and // owns the copy. }; // Adapts a native array to a read-only STL-style container. Instead // of the complete STL container concept, this adaptor only implements // members useful for Google Mock's container matchers. New members // should be added as needed. To simplify the implementation, we only // support Element being a raw type (i.e. having no top-level const or // reference modifier). It's the client's responsibility to satisfy // this requirement. Element can be an array type itself (hence // multi-dimensional arrays are supported). template class NativeArray { public: // STL-style container typedefs. typedef Element value_type; typedef Element* iterator; typedef const Element* const_iterator; // Constructs from a native array. NativeArray(const Element* array, size_t count, RelationToSource relation) { Init(array, count, relation); } // Copy constructor. NativeArray(const NativeArray& rhs) { Init(rhs.array_, rhs.size_, rhs.relation_to_source_); } ~NativeArray() { // Ensures that the user doesn't instantiate NativeArray with a // const or reference type. static_cast(StaticAssertTypeEqHelper()); if (relation_to_source_ == kCopy) delete[] array_; } // STL-style container methods. size_t size() const { return size_; } const_iterator begin() const { return array_; } const_iterator end() const { return array_ + size_; } bool operator==(const NativeArray& rhs) const { return size() == rhs.size() && ArrayEq(begin(), size(), rhs.begin()); } private: // Initializes this object; makes a copy of the input array if // 'relation' is kCopy. void Init(const Element* array, size_t a_size, RelationToSource relation) { if (relation == kReference) { array_ = array; } else { Element* const copy = new Element[a_size]; CopyArray(array, a_size, copy); array_ = copy; } size_ = a_size; relation_to_source_ = relation; } const Element* array_; size_t size_; RelationToSource relation_to_source_; GTEST_DISALLOW_ASSIGN_(NativeArray); }; } // namespace internal } // namespace testing #define GTEST_MESSAGE_AT_(file, line, message, result_type) \ ::testing::internal::AssertHelper(result_type, file, line, message) \ = ::testing::Message() #define GTEST_MESSAGE_(message, result_type) \ GTEST_MESSAGE_AT_(__FILE__, __LINE__, message, result_type) #define GTEST_FATAL_FAILURE_(message) \ return GTEST_MESSAGE_(message, ::testing::TestPartResult::kFatalFailure) #define GTEST_NONFATAL_FAILURE_(message) \ GTEST_MESSAGE_(message, ::testing::TestPartResult::kNonFatalFailure) #define GTEST_SUCCESS_(message) \ GTEST_MESSAGE_(message, ::testing::TestPartResult::kSuccess) // Suppresses MSVC warnings 4072 (unreachable code) for the code following // statement if it returns or throws (or doesn't return or throw in some // situations). #define GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement) \ if (::testing::internal::AlwaysTrue()) { statement; } #define GTEST_TEST_THROW_(statement, expected_exception, fail) \ GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ if (::testing::internal::ConstCharPtr gtest_msg = "") { \ bool gtest_caught_expected = false; \ try { \ GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ } \ catch (expected_exception const&) { \ gtest_caught_expected = true; \ } \ catch (...) { \ gtest_msg.value = \ "Expected: " #statement " throws an exception of type " \ #expected_exception ".\n Actual: it throws a different type."; \ goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__); \ } \ if (!gtest_caught_expected) { \ gtest_msg.value = \ "Expected: " #statement " throws an exception of type " \ #expected_exception ".\n Actual: it throws nothing."; \ goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__); \ } \ } else \ GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__): \ fail(gtest_msg.value) #define GTEST_TEST_NO_THROW_(statement, fail) \ GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ if (::testing::internal::AlwaysTrue()) { \ try { \ GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ } \ catch (...) { \ goto GTEST_CONCAT_TOKEN_(gtest_label_testnothrow_, __LINE__); \ } \ } else \ GTEST_CONCAT_TOKEN_(gtest_label_testnothrow_, __LINE__): \ fail("Expected: " #statement " doesn't throw an exception.\n" \ " Actual: it throws.") #define GTEST_TEST_ANY_THROW_(statement, fail) \ GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ if (::testing::internal::AlwaysTrue()) { \ bool gtest_caught_any = false; \ try { \ GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ } \ catch (...) { \ gtest_caught_any = true; \ } \ if (!gtest_caught_any) { \ goto GTEST_CONCAT_TOKEN_(gtest_label_testanythrow_, __LINE__); \ } \ } else \ GTEST_CONCAT_TOKEN_(gtest_label_testanythrow_, __LINE__): \ fail("Expected: " #statement " throws an exception.\n" \ " Actual: it doesn't.") // Implements Boolean test assertions such as EXPECT_TRUE. expression can be // either a boolean expression or an AssertionResult. text is a textual // represenation of expression as it was passed into the EXPECT_TRUE. #define GTEST_TEST_BOOLEAN_(expression, text, actual, expected, fail) \ GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ if (const ::testing::AssertionResult gtest_ar_ = \ ::testing::AssertionResult(expression)) \ ; \ else \ fail(::testing::internal::GetBoolAssertionFailureMessage(\ gtest_ar_, text, #actual, #expected).c_str()) #define GTEST_TEST_NO_FATAL_FAILURE_(statement, fail) \ GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ if (::testing::internal::AlwaysTrue()) { \ ::testing::internal::HasNewFatalFailureHelper gtest_fatal_failure_checker; \ GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ if (gtest_fatal_failure_checker.has_new_fatal_failure()) { \ goto GTEST_CONCAT_TOKEN_(gtest_label_testnofatal_, __LINE__); \ } \ } else \ GTEST_CONCAT_TOKEN_(gtest_label_testnofatal_, __LINE__): \ fail("Expected: " #statement " doesn't generate new fatal " \ "failures in the current thread.\n" \ " Actual: it does.") // Expands to the name of the class that implements the given test. #define GTEST_TEST_CLASS_NAME_(test_case_name, test_name) \ test_case_name##_##test_name##_Test // Helper macro for defining tests. #define GTEST_TEST_(test_case_name, test_name, parent_class, parent_id)\ class GTEST_TEST_CLASS_NAME_(test_case_name, test_name) : public parent_class {\ public:\ GTEST_TEST_CLASS_NAME_(test_case_name, test_name)() {}\ private:\ virtual void TestBody();\ static ::testing::TestInfo* const test_info_ GTEST_ATTRIBUTE_UNUSED_;\ GTEST_DISALLOW_COPY_AND_ASSIGN_(\ GTEST_TEST_CLASS_NAME_(test_case_name, test_name));\ };\ \ ::testing::TestInfo* const GTEST_TEST_CLASS_NAME_(test_case_name, test_name)\ ::test_info_ =\ ::testing::internal::MakeAndRegisterTestInfo(\ #test_case_name, #test_name, NULL, NULL, \ (parent_id), \ parent_class::SetUpTestCase, \ parent_class::TearDownTestCase, \ new ::testing::internal::TestFactoryImpl<\ GTEST_TEST_CLASS_NAME_(test_case_name, test_name)>);\ void GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::TestBody() #endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_ dlt-daemon-2.18.4/gtest-1.7.0/include/gtest/internal/gtest-linked_ptr.h000066400000000000000000000176451353342203500254530ustar00rootroot00000000000000// Copyright 2003 Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Authors: Dan Egnor (egnor@google.com) // // A "smart" pointer type with reference tracking. Every pointer to a // particular object is kept on a circular linked list. When the last pointer // to an object is destroyed or reassigned, the object is deleted. // // Used properly, this deletes the object when the last reference goes away. // There are several caveats: // - Like all reference counting schemes, cycles lead to leaks. // - Each smart pointer is actually two pointers (8 bytes instead of 4). // - Every time a pointer is assigned, the entire list of pointers to that // object is traversed. This class is therefore NOT SUITABLE when there // will often be more than two or three pointers to a particular object. // - References are only tracked as long as linked_ptr<> objects are copied. // If a linked_ptr<> is converted to a raw pointer and back, BAD THINGS // will happen (double deletion). // // A good use of this class is storing object references in STL containers. // You can safely put linked_ptr<> in a vector<>. // Other uses may not be as good. // // Note: If you use an incomplete type with linked_ptr<>, the class // *containing* linked_ptr<> must have a constructor and destructor (even // if they do nothing!). // // Bill Gibbons suggested we use something like this. // // Thread Safety: // Unlike other linked_ptr implementations, in this implementation // a linked_ptr object is thread-safe in the sense that: // - it's safe to copy linked_ptr objects concurrently, // - it's safe to copy *from* a linked_ptr and read its underlying // raw pointer (e.g. via get()) concurrently, and // - it's safe to write to two linked_ptrs that point to the same // shared object concurrently. // TODO(wan@google.com): rename this to safe_linked_ptr to avoid // confusion with normal linked_ptr. #ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_LINKED_PTR_H_ #define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_LINKED_PTR_H_ #include #include #include "gtest/internal/gtest-port.h" namespace testing { namespace internal { // Protects copying of all linked_ptr objects. GTEST_API_ GTEST_DECLARE_STATIC_MUTEX_(g_linked_ptr_mutex); // This is used internally by all instances of linked_ptr<>. It needs to be // a non-template class because different types of linked_ptr<> can refer to // the same object (linked_ptr(obj) vs linked_ptr(obj)). // So, it needs to be possible for different types of linked_ptr to participate // in the same circular linked list, so we need a single class type here. // // DO NOT USE THIS CLASS DIRECTLY YOURSELF. Use linked_ptr. class linked_ptr_internal { public: // Create a new circle that includes only this instance. void join_new() { next_ = this; } // Many linked_ptr operations may change p.link_ for some linked_ptr // variable p in the same circle as this object. Therefore we need // to prevent two such operations from occurring concurrently. // // Note that different types of linked_ptr objects can coexist in a // circle (e.g. linked_ptr, linked_ptr, and // linked_ptr). Therefore we must use a single mutex to // protect all linked_ptr objects. This can create serious // contention in production code, but is acceptable in a testing // framework. // Join an existing circle. void join(linked_ptr_internal const* ptr) GTEST_LOCK_EXCLUDED_(g_linked_ptr_mutex) { MutexLock lock(&g_linked_ptr_mutex); linked_ptr_internal const* p = ptr; while (p->next_ != ptr) p = p->next_; p->next_ = this; next_ = ptr; } // Leave whatever circle we're part of. Returns true if we were the // last member of the circle. Once this is done, you can join() another. bool depart() GTEST_LOCK_EXCLUDED_(g_linked_ptr_mutex) { MutexLock lock(&g_linked_ptr_mutex); if (next_ == this) return true; linked_ptr_internal const* p = next_; while (p->next_ != this) p = p->next_; p->next_ = next_; return false; } private: mutable linked_ptr_internal const* next_; }; template class linked_ptr { public: typedef T element_type; // Take over ownership of a raw pointer. This should happen as soon as // possible after the object is created. explicit linked_ptr(T* ptr = NULL) { capture(ptr); } ~linked_ptr() { depart(); } // Copy an existing linked_ptr<>, adding ourselves to the list of references. template linked_ptr(linked_ptr const& ptr) { copy(&ptr); } linked_ptr(linked_ptr const& ptr) { // NOLINT assert(&ptr != this); copy(&ptr); } // Assignment releases the old value and acquires the new. template linked_ptr& operator=(linked_ptr const& ptr) { depart(); copy(&ptr); return *this; } linked_ptr& operator=(linked_ptr const& ptr) { if (&ptr != this) { depart(); copy(&ptr); } return *this; } // Smart pointer members. void reset(T* ptr = NULL) { depart(); capture(ptr); } T* get() const { return value_; } T* operator->() const { return value_; } T& operator*() const { return *value_; } bool operator==(T* p) const { return value_ == p; } bool operator!=(T* p) const { return value_ != p; } template bool operator==(linked_ptr const& ptr) const { return value_ == ptr.get(); } template bool operator!=(linked_ptr const& ptr) const { return value_ != ptr.get(); } private: template friend class linked_ptr; T* value_; linked_ptr_internal link_; void depart() { if (link_.depart()) delete value_; } void capture(T* ptr) { value_ = ptr; link_.join_new(); } template void copy(linked_ptr const* ptr) { value_ = ptr->get(); if (value_) link_.join(&ptr->link_); else link_.join_new(); } }; template inline bool operator==(T* ptr, const linked_ptr& x) { return ptr == x.get(); } template inline bool operator!=(T* ptr, const linked_ptr& x) { return ptr != x.get(); } // A function to convert T* into linked_ptr // Doing e.g. make_linked_ptr(new FooBarBaz(arg)) is a shorter notation // for linked_ptr >(new FooBarBaz(arg)) template linked_ptr make_linked_ptr(T* ptr) { return linked_ptr(ptr); } } // namespace internal } // namespace testing #endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_LINKED_PTR_H_ dlt-daemon-2.18.4/gtest-1.7.0/include/gtest/internal/gtest-param-util-generated.h000066400000000000000000005672601353342203500273320ustar00rootroot00000000000000// This file was GENERATED by command: // pump.py gtest-param-util-generated.h.pump // DO NOT EDIT BY HAND!!! // Copyright 2008 Google Inc. // All Rights Reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: vladl@google.com (Vlad Losev) // Type and function utilities for implementing parameterized tests. // This file is generated by a SCRIPT. DO NOT EDIT BY HAND! // // Currently Google Test supports at most 50 arguments in Values, // and at most 10 arguments in Combine. Please contact // googletestframework@googlegroups.com if you need more. // Please note that the number of arguments to Combine is limited // by the maximum arity of the implementation of tr1::tuple which is // currently set at 10. #ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_ #define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_ // scripts/fuse_gtest.py depends on gtest's own header being #included // *unconditionally*. Therefore these #includes cannot be moved // inside #if GTEST_HAS_PARAM_TEST. #include "gtest/internal/gtest-param-util.h" #include "gtest/internal/gtest-port.h" #if GTEST_HAS_PARAM_TEST namespace testing { // Forward declarations of ValuesIn(), which is implemented in // include/gtest/gtest-param-test.h. template internal::ParamGenerator< typename ::testing::internal::IteratorTraits::value_type> ValuesIn(ForwardIterator begin, ForwardIterator end); template internal::ParamGenerator ValuesIn(const T (&array)[N]); template internal::ParamGenerator ValuesIn( const Container& container); 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_; }; template class ValueArray2 { public: ValueArray2(T1 v1, T2 v2) : v1_(v1), v2_(v2) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray2& other); const T1 v1_; const T2 v2_; }; template class ValueArray3 { public: ValueArray3(T1 v1, T2 v2, T3 v3) : v1_(v1), v2_(v2), v3_(v3) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray3& other); const T1 v1_; const T2 v2_; const T3 v3_; }; template class ValueArray4 { public: ValueArray4(T1 v1, T2 v2, T3 v3, T4 v4) : v1_(v1), v2_(v2), v3_(v3), v4_(v4) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray4& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; }; template class ValueArray5 { public: ValueArray5(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray5& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; }; template class ValueArray6 { public: ValueArray6(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray6& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; }; template class ValueArray7 { public: ValueArray7(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray7& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; }; template class ValueArray8 { public: ValueArray8(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray8& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; }; template class ValueArray9 { public: ValueArray9(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray9& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; }; template class ValueArray10 { public: ValueArray10(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray10& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; }; template class ValueArray11 { public: ValueArray11(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray11& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; }; template class ValueArray12 { public: ValueArray12(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray12& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; }; template class ValueArray13 { public: ValueArray13(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray13& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; }; template class ValueArray14 { public: ValueArray14(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray14& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; }; template class ValueArray15 { public: ValueArray15(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray15& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; }; template class ValueArray16 { public: ValueArray16(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray16& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; }; template class ValueArray17 { public: ValueArray17(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray17& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; }; template class ValueArray18 { public: ValueArray18(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray18& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; }; template class ValueArray19 { public: ValueArray19(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray19& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; }; template class ValueArray20 { public: ValueArray20(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray20& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; }; template class ValueArray21 { public: ValueArray21(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray21& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; }; template class ValueArray22 { public: ValueArray22(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_), static_cast(v22_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray22& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; const T22 v22_; }; template class ValueArray23 { public: ValueArray23(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_), static_cast(v22_), static_cast(v23_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray23& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; const T22 v22_; const T23 v23_; }; template class ValueArray24 { public: ValueArray24(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_), static_cast(v22_), static_cast(v23_), static_cast(v24_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray24& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; const T22 v22_; const T23 v23_; const T24 v24_; }; template class ValueArray25 { public: ValueArray25(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_), static_cast(v22_), static_cast(v23_), static_cast(v24_), static_cast(v25_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray25& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; const T22 v22_; const T23 v23_; const T24 v24_; const T25 v25_; }; template class ValueArray26 { public: ValueArray26(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_), static_cast(v22_), static_cast(v23_), static_cast(v24_), static_cast(v25_), static_cast(v26_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray26& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; const T22 v22_; const T23 v23_; const T24 v24_; const T25 v25_; const T26 v26_; }; template class ValueArray27 { public: ValueArray27(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_), static_cast(v22_), static_cast(v23_), static_cast(v24_), static_cast(v25_), static_cast(v26_), static_cast(v27_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray27& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; const T22 v22_; const T23 v23_; const T24 v24_; const T25 v25_; const T26 v26_; const T27 v27_; }; template class ValueArray28 { public: ValueArray28(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_), static_cast(v22_), static_cast(v23_), static_cast(v24_), static_cast(v25_), static_cast(v26_), static_cast(v27_), static_cast(v28_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray28& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; const T22 v22_; const T23 v23_; const T24 v24_; const T25 v25_; const T26 v26_; const T27 v27_; const T28 v28_; }; template class ValueArray29 { public: ValueArray29(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_), static_cast(v22_), static_cast(v23_), static_cast(v24_), static_cast(v25_), static_cast(v26_), static_cast(v27_), static_cast(v28_), static_cast(v29_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray29& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; const T22 v22_; const T23 v23_; const T24 v24_; const T25 v25_; const T26 v26_; const T27 v27_; const T28 v28_; const T29 v29_; }; template class ValueArray30 { public: ValueArray30(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_), static_cast(v22_), static_cast(v23_), static_cast(v24_), static_cast(v25_), static_cast(v26_), static_cast(v27_), static_cast(v28_), static_cast(v29_), static_cast(v30_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray30& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; const T22 v22_; const T23 v23_; const T24 v24_; const T25 v25_; const T26 v26_; const T27 v27_; const T28 v28_; const T29 v29_; const T30 v30_; }; template class ValueArray31 { public: ValueArray31(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_), static_cast(v22_), static_cast(v23_), static_cast(v24_), static_cast(v25_), static_cast(v26_), static_cast(v27_), static_cast(v28_), static_cast(v29_), static_cast(v30_), static_cast(v31_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray31& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; const T22 v22_; const T23 v23_; const T24 v24_; const T25 v25_; const T26 v26_; const T27 v27_; const T28 v28_; const T29 v29_; const T30 v30_; const T31 v31_; }; template class ValueArray32 { public: ValueArray32(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_), static_cast(v22_), static_cast(v23_), static_cast(v24_), static_cast(v25_), static_cast(v26_), static_cast(v27_), static_cast(v28_), static_cast(v29_), static_cast(v30_), static_cast(v31_), static_cast(v32_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray32& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; const T22 v22_; const T23 v23_; const T24 v24_; const T25 v25_; const T26 v26_; const T27 v27_; const T28 v28_; const T29 v29_; const T30 v30_; const T31 v31_; const T32 v32_; }; template class ValueArray33 { public: ValueArray33(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_), static_cast(v22_), static_cast(v23_), static_cast(v24_), static_cast(v25_), static_cast(v26_), static_cast(v27_), static_cast(v28_), static_cast(v29_), static_cast(v30_), static_cast(v31_), static_cast(v32_), static_cast(v33_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray33& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; const T22 v22_; const T23 v23_; const T24 v24_; const T25 v25_; const T26 v26_; const T27 v27_; const T28 v28_; const T29 v29_; const T30 v30_; const T31 v31_; const T32 v32_; const T33 v33_; }; template class ValueArray34 { public: ValueArray34(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_), static_cast(v22_), static_cast(v23_), static_cast(v24_), static_cast(v25_), static_cast(v26_), static_cast(v27_), static_cast(v28_), static_cast(v29_), static_cast(v30_), static_cast(v31_), static_cast(v32_), static_cast(v33_), static_cast(v34_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray34& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; const T22 v22_; const T23 v23_; const T24 v24_; const T25 v25_; const T26 v26_; const T27 v27_; const T28 v28_; const T29 v29_; const T30 v30_; const T31 v31_; const T32 v32_; const T33 v33_; const T34 v34_; }; template class ValueArray35 { public: ValueArray35(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_), static_cast(v22_), static_cast(v23_), static_cast(v24_), static_cast(v25_), static_cast(v26_), static_cast(v27_), static_cast(v28_), static_cast(v29_), static_cast(v30_), static_cast(v31_), static_cast(v32_), static_cast(v33_), static_cast(v34_), static_cast(v35_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray35& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; const T22 v22_; const T23 v23_; const T24 v24_; const T25 v25_; const T26 v26_; const T27 v27_; const T28 v28_; const T29 v29_; const T30 v30_; const T31 v31_; const T32 v32_; const T33 v33_; const T34 v34_; const T35 v35_; }; template class ValueArray36 { public: ValueArray36(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_), static_cast(v22_), static_cast(v23_), static_cast(v24_), static_cast(v25_), static_cast(v26_), static_cast(v27_), static_cast(v28_), static_cast(v29_), static_cast(v30_), static_cast(v31_), static_cast(v32_), static_cast(v33_), static_cast(v34_), static_cast(v35_), static_cast(v36_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray36& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; const T22 v22_; const T23 v23_; const T24 v24_; const T25 v25_; const T26 v26_; const T27 v27_; const T28 v28_; const T29 v29_; const T30 v30_; const T31 v31_; const T32 v32_; const T33 v33_; const T34 v34_; const T35 v35_; const T36 v36_; }; template class ValueArray37 { public: ValueArray37(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_), static_cast(v22_), static_cast(v23_), static_cast(v24_), static_cast(v25_), static_cast(v26_), static_cast(v27_), static_cast(v28_), static_cast(v29_), static_cast(v30_), static_cast(v31_), static_cast(v32_), static_cast(v33_), static_cast(v34_), static_cast(v35_), static_cast(v36_), static_cast(v37_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray37& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; const T22 v22_; const T23 v23_; const T24 v24_; const T25 v25_; const T26 v26_; const T27 v27_; const T28 v28_; const T29 v29_; const T30 v30_; const T31 v31_; const T32 v32_; const T33 v33_; const T34 v34_; const T35 v35_; const T36 v36_; const T37 v37_; }; template class ValueArray38 { public: ValueArray38(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_), static_cast(v22_), static_cast(v23_), static_cast(v24_), static_cast(v25_), static_cast(v26_), static_cast(v27_), static_cast(v28_), static_cast(v29_), static_cast(v30_), static_cast(v31_), static_cast(v32_), static_cast(v33_), static_cast(v34_), static_cast(v35_), static_cast(v36_), static_cast(v37_), static_cast(v38_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray38& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; const T22 v22_; const T23 v23_; const T24 v24_; const T25 v25_; const T26 v26_; const T27 v27_; const T28 v28_; const T29 v29_; const T30 v30_; const T31 v31_; const T32 v32_; const T33 v33_; const T34 v34_; const T35 v35_; const T36 v36_; const T37 v37_; const T38 v38_; }; template class ValueArray39 { public: ValueArray39(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_), static_cast(v22_), static_cast(v23_), static_cast(v24_), static_cast(v25_), static_cast(v26_), static_cast(v27_), static_cast(v28_), static_cast(v29_), static_cast(v30_), static_cast(v31_), static_cast(v32_), static_cast(v33_), static_cast(v34_), static_cast(v35_), static_cast(v36_), static_cast(v37_), static_cast(v38_), static_cast(v39_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray39& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; const T22 v22_; const T23 v23_; const T24 v24_; const T25 v25_; const T26 v26_; const T27 v27_; const T28 v28_; const T29 v29_; const T30 v30_; const T31 v31_; const T32 v32_; const T33 v33_; const T34 v34_; const T35 v35_; const T36 v36_; const T37 v37_; const T38 v38_; const T39 v39_; }; template class ValueArray40 { public: ValueArray40(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39), v40_(v40) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_), static_cast(v22_), static_cast(v23_), static_cast(v24_), static_cast(v25_), static_cast(v26_), static_cast(v27_), static_cast(v28_), static_cast(v29_), static_cast(v30_), static_cast(v31_), static_cast(v32_), static_cast(v33_), static_cast(v34_), static_cast(v35_), static_cast(v36_), static_cast(v37_), static_cast(v38_), static_cast(v39_), static_cast(v40_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray40& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; const T22 v22_; const T23 v23_; const T24 v24_; const T25 v25_; const T26 v26_; const T27 v27_; const T28 v28_; const T29 v29_; const T30 v30_; const T31 v31_; const T32 v32_; const T33 v33_; const T34 v34_; const T35 v35_; const T36 v36_; const T37 v37_; const T38 v38_; const T39 v39_; const T40 v40_; }; template class ValueArray41 { public: ValueArray41(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39), v40_(v40), v41_(v41) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_), static_cast(v22_), static_cast(v23_), static_cast(v24_), static_cast(v25_), static_cast(v26_), static_cast(v27_), static_cast(v28_), static_cast(v29_), static_cast(v30_), static_cast(v31_), static_cast(v32_), static_cast(v33_), static_cast(v34_), static_cast(v35_), static_cast(v36_), static_cast(v37_), static_cast(v38_), static_cast(v39_), static_cast(v40_), static_cast(v41_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray41& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; const T22 v22_; const T23 v23_; const T24 v24_; const T25 v25_; const T26 v26_; const T27 v27_; const T28 v28_; const T29 v29_; const T30 v30_; const T31 v31_; const T32 v32_; const T33 v33_; const T34 v34_; const T35 v35_; const T36 v36_; const T37 v37_; const T38 v38_; const T39 v39_; const T40 v40_; const T41 v41_; }; template class ValueArray42 { public: ValueArray42(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, T42 v42) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39), v40_(v40), v41_(v41), v42_(v42) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_), static_cast(v22_), static_cast(v23_), static_cast(v24_), static_cast(v25_), static_cast(v26_), static_cast(v27_), static_cast(v28_), static_cast(v29_), static_cast(v30_), static_cast(v31_), static_cast(v32_), static_cast(v33_), static_cast(v34_), static_cast(v35_), static_cast(v36_), static_cast(v37_), static_cast(v38_), static_cast(v39_), static_cast(v40_), static_cast(v41_), static_cast(v42_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray42& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; const T22 v22_; const T23 v23_; const T24 v24_; const T25 v25_; const T26 v26_; const T27 v27_; const T28 v28_; const T29 v29_; const T30 v30_; const T31 v31_; const T32 v32_; const T33 v33_; const T34 v34_; const T35 v35_; const T36 v36_; const T37 v37_; const T38 v38_; const T39 v39_; const T40 v40_; const T41 v41_; const T42 v42_; }; template class ValueArray43 { public: ValueArray43(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, T42 v42, T43 v43) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39), v40_(v40), v41_(v41), v42_(v42), v43_(v43) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_), static_cast(v22_), static_cast(v23_), static_cast(v24_), static_cast(v25_), static_cast(v26_), static_cast(v27_), static_cast(v28_), static_cast(v29_), static_cast(v30_), static_cast(v31_), static_cast(v32_), static_cast(v33_), static_cast(v34_), static_cast(v35_), static_cast(v36_), static_cast(v37_), static_cast(v38_), static_cast(v39_), static_cast(v40_), static_cast(v41_), static_cast(v42_), static_cast(v43_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray43& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; const T22 v22_; const T23 v23_; const T24 v24_; const T25 v25_; const T26 v26_; const T27 v27_; const T28 v28_; const T29 v29_; const T30 v30_; const T31 v31_; const T32 v32_; const T33 v33_; const T34 v34_; const T35 v35_; const T36 v36_; const T37 v37_; const T38 v38_; const T39 v39_; const T40 v40_; const T41 v41_; const T42 v42_; const T43 v43_; }; template class ValueArray44 { public: ValueArray44(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, T42 v42, T43 v43, T44 v44) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39), v40_(v40), v41_(v41), v42_(v42), v43_(v43), v44_(v44) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_), static_cast(v22_), static_cast(v23_), static_cast(v24_), static_cast(v25_), static_cast(v26_), static_cast(v27_), static_cast(v28_), static_cast(v29_), static_cast(v30_), static_cast(v31_), static_cast(v32_), static_cast(v33_), static_cast(v34_), static_cast(v35_), static_cast(v36_), static_cast(v37_), static_cast(v38_), static_cast(v39_), static_cast(v40_), static_cast(v41_), static_cast(v42_), static_cast(v43_), static_cast(v44_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray44& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; const T22 v22_; const T23 v23_; const T24 v24_; const T25 v25_; const T26 v26_; const T27 v27_; const T28 v28_; const T29 v29_; const T30 v30_; const T31 v31_; const T32 v32_; const T33 v33_; const T34 v34_; const T35 v35_; const T36 v36_; const T37 v37_; const T38 v38_; const T39 v39_; const T40 v40_; const T41 v41_; const T42 v42_; const T43 v43_; const T44 v44_; }; template class ValueArray45 { public: ValueArray45(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39), v40_(v40), v41_(v41), v42_(v42), v43_(v43), v44_(v44), v45_(v45) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_), static_cast(v22_), static_cast(v23_), static_cast(v24_), static_cast(v25_), static_cast(v26_), static_cast(v27_), static_cast(v28_), static_cast(v29_), static_cast(v30_), static_cast(v31_), static_cast(v32_), static_cast(v33_), static_cast(v34_), static_cast(v35_), static_cast(v36_), static_cast(v37_), static_cast(v38_), static_cast(v39_), static_cast(v40_), static_cast(v41_), static_cast(v42_), static_cast(v43_), static_cast(v44_), static_cast(v45_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray45& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; const T22 v22_; const T23 v23_; const T24 v24_; const T25 v25_; const T26 v26_; const T27 v27_; const T28 v28_; const T29 v29_; const T30 v30_; const T31 v31_; const T32 v32_; const T33 v33_; const T34 v34_; const T35 v35_; const T36 v36_; const T37 v37_; const T38 v38_; const T39 v39_; const T40 v40_; const T41 v41_; const T42 v42_; const T43 v43_; const T44 v44_; const T45 v45_; }; template class ValueArray46 { public: ValueArray46(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39), v40_(v40), v41_(v41), v42_(v42), v43_(v43), v44_(v44), v45_(v45), v46_(v46) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_), static_cast(v22_), static_cast(v23_), static_cast(v24_), static_cast(v25_), static_cast(v26_), static_cast(v27_), static_cast(v28_), static_cast(v29_), static_cast(v30_), static_cast(v31_), static_cast(v32_), static_cast(v33_), static_cast(v34_), static_cast(v35_), static_cast(v36_), static_cast(v37_), static_cast(v38_), static_cast(v39_), static_cast(v40_), static_cast(v41_), static_cast(v42_), static_cast(v43_), static_cast(v44_), static_cast(v45_), static_cast(v46_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray46& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; const T22 v22_; const T23 v23_; const T24 v24_; const T25 v25_; const T26 v26_; const T27 v27_; const T28 v28_; const T29 v29_; const T30 v30_; const T31 v31_; const T32 v32_; const T33 v33_; const T34 v34_; const T35 v35_; const T36 v36_; const T37 v37_; const T38 v38_; const T39 v39_; const T40 v40_; const T41 v41_; const T42 v42_; const T43 v43_; const T44 v44_; const T45 v45_; const T46 v46_; }; template class ValueArray47 { public: ValueArray47(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39), v40_(v40), v41_(v41), v42_(v42), v43_(v43), v44_(v44), v45_(v45), v46_(v46), v47_(v47) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_), static_cast(v22_), static_cast(v23_), static_cast(v24_), static_cast(v25_), static_cast(v26_), static_cast(v27_), static_cast(v28_), static_cast(v29_), static_cast(v30_), static_cast(v31_), static_cast(v32_), static_cast(v33_), static_cast(v34_), static_cast(v35_), static_cast(v36_), static_cast(v37_), static_cast(v38_), static_cast(v39_), static_cast(v40_), static_cast(v41_), static_cast(v42_), static_cast(v43_), static_cast(v44_), static_cast(v45_), static_cast(v46_), static_cast(v47_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray47& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; const T22 v22_; const T23 v23_; const T24 v24_; const T25 v25_; const T26 v26_; const T27 v27_; const T28 v28_; const T29 v29_; const T30 v30_; const T31 v31_; const T32 v32_; const T33 v33_; const T34 v34_; const T35 v35_; const T36 v36_; const T37 v37_; const T38 v38_; const T39 v39_; const T40 v40_; const T41 v41_; const T42 v42_; const T43 v43_; const T44 v44_; const T45 v45_; const T46 v46_; const T47 v47_; }; template class ValueArray48 { public: ValueArray48(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47, T48 v48) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39), v40_(v40), v41_(v41), v42_(v42), v43_(v43), v44_(v44), v45_(v45), v46_(v46), v47_(v47), v48_(v48) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_), static_cast(v22_), static_cast(v23_), static_cast(v24_), static_cast(v25_), static_cast(v26_), static_cast(v27_), static_cast(v28_), static_cast(v29_), static_cast(v30_), static_cast(v31_), static_cast(v32_), static_cast(v33_), static_cast(v34_), static_cast(v35_), static_cast(v36_), static_cast(v37_), static_cast(v38_), static_cast(v39_), static_cast(v40_), static_cast(v41_), static_cast(v42_), static_cast(v43_), static_cast(v44_), static_cast(v45_), static_cast(v46_), static_cast(v47_), static_cast(v48_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray48& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; const T22 v22_; const T23 v23_; const T24 v24_; const T25 v25_; const T26 v26_; const T27 v27_; const T28 v28_; const T29 v29_; const T30 v30_; const T31 v31_; const T32 v32_; const T33 v33_; const T34 v34_; const T35 v35_; const T36 v36_; const T37 v37_; const T38 v38_; const T39 v39_; const T40 v40_; const T41 v41_; const T42 v42_; const T43 v43_; const T44 v44_; const T45 v45_; const T46 v46_; const T47 v47_; const T48 v48_; }; template class ValueArray49 { public: ValueArray49(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47, T48 v48, T49 v49) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39), v40_(v40), v41_(v41), v42_(v42), v43_(v43), v44_(v44), v45_(v45), v46_(v46), v47_(v47), v48_(v48), v49_(v49) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_), static_cast(v22_), static_cast(v23_), static_cast(v24_), static_cast(v25_), static_cast(v26_), static_cast(v27_), static_cast(v28_), static_cast(v29_), static_cast(v30_), static_cast(v31_), static_cast(v32_), static_cast(v33_), static_cast(v34_), static_cast(v35_), static_cast(v36_), static_cast(v37_), static_cast(v38_), static_cast(v39_), static_cast(v40_), static_cast(v41_), static_cast(v42_), static_cast(v43_), static_cast(v44_), static_cast(v45_), static_cast(v46_), static_cast(v47_), static_cast(v48_), static_cast(v49_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray49& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; const T22 v22_; const T23 v23_; const T24 v24_; const T25 v25_; const T26 v26_; const T27 v27_; const T28 v28_; const T29 v29_; const T30 v30_; const T31 v31_; const T32 v32_; const T33 v33_; const T34 v34_; const T35 v35_; const T36 v36_; const T37 v37_; const T38 v38_; const T39 v39_; const T40 v40_; const T41 v41_; const T42 v42_; const T43 v43_; const T44 v44_; const T45 v45_; const T46 v46_; const T47 v47_; const T48 v48_; const T49 v49_; }; template class ValueArray50 { public: ValueArray50(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47, T48 v48, T49 v49, T50 v50) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39), v40_(v40), v41_(v41), v42_(v42), v43_(v43), v44_(v44), v45_(v45), v46_(v46), v47_(v47), v48_(v48), v49_(v49), v50_(v50) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_), static_cast(v22_), static_cast(v23_), static_cast(v24_), static_cast(v25_), static_cast(v26_), static_cast(v27_), static_cast(v28_), static_cast(v29_), static_cast(v30_), static_cast(v31_), static_cast(v32_), static_cast(v33_), static_cast(v34_), static_cast(v35_), static_cast(v36_), static_cast(v37_), static_cast(v38_), static_cast(v39_), static_cast(v40_), static_cast(v41_), static_cast(v42_), static_cast(v43_), static_cast(v44_), static_cast(v45_), static_cast(v46_), static_cast(v47_), static_cast(v48_), static_cast(v49_), static_cast(v50_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray50& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; const T22 v22_; const T23 v23_; const T24 v24_; const T25 v25_; const T26 v26_; const T27 v27_; const T28 v28_; const T29 v29_; const T30 v30_; const T31 v31_; const T32 v32_; const T33 v33_; const T34 v34_; const T35 v35_; const T36 v36_; const T37 v37_; const T38 v38_; const T39 v39_; const T40 v40_; const T41 v41_; const T42 v42_; const T43 v43_; const T44 v44_; const T45 v45_; const T46 v46_; const T47 v47_; const T48 v48_; const T49 v49_; const T50 v50_; }; # if GTEST_HAS_COMBINE // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. // // Generates values from the Cartesian product of values produced // by the argument generators. // template class CartesianProductGenerator2 : public ParamGeneratorInterface< ::std::tr1::tuple > { public: typedef ::std::tr1::tuple ParamType; CartesianProductGenerator2(const ParamGenerator& g1, const ParamGenerator& g2) : g1_(g1), g2_(g2) {} virtual ~CartesianProductGenerator2() {} virtual ParamIteratorInterface* Begin() const { return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin()); } virtual ParamIteratorInterface* End() const { return new Iterator(this, g1_, g1_.end(), g2_, g2_.end()); } private: class Iterator : public ParamIteratorInterface { public: Iterator(const ParamGeneratorInterface* base, const ParamGenerator& g1, const typename ParamGenerator::iterator& current1, const ParamGenerator& g2, const typename ParamGenerator::iterator& current2) : base_(base), begin1_(g1.begin()), end1_(g1.end()), current1_(current1), begin2_(g2.begin()), end2_(g2.end()), current2_(current2) { ComputeCurrentValue(); } virtual ~Iterator() {} virtual const ParamGeneratorInterface* BaseGenerator() const { return base_; } // Advance should not be called on beyond-of-range iterators // so no component iterators must be beyond end of range, either. virtual void Advance() { assert(!AtEnd()); ++current2_; if (current2_ == end2_) { current2_ = begin2_; ++current1_; } ComputeCurrentValue(); } virtual ParamIteratorInterface* Clone() const { return new Iterator(*this); } virtual const ParamType* Current() const { return ¤t_value_; } virtual bool Equals(const ParamIteratorInterface& other) const { // Having the same base generator guarantees that the other // iterator is of the same type and we can downcast. GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) << "The program attempted to compare iterators " << "from different generators." << std::endl; const Iterator* typed_other = CheckedDowncastToActualType(&other); // We must report iterators equal if they both point beyond their // respective ranges. That can happen in a variety of fashions, // so we have to consult AtEnd(). return (AtEnd() && typed_other->AtEnd()) || ( current1_ == typed_other->current1_ && current2_ == typed_other->current2_); } private: Iterator(const Iterator& other) : base_(other.base_), begin1_(other.begin1_), end1_(other.end1_), current1_(other.current1_), begin2_(other.begin2_), end2_(other.end2_), current2_(other.current2_) { ComputeCurrentValue(); } void ComputeCurrentValue() { if (!AtEnd()) current_value_ = ParamType(*current1_, *current2_); } bool AtEnd() const { // We must report iterator past the end of the range when either of the // component iterators has reached the end of its range. return current1_ == end1_ || current2_ == end2_; } // No implementation - assignment is unsupported. void operator=(const Iterator& other); const ParamGeneratorInterface* const base_; // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. // current[i]_ is the actual traversing iterator. const typename ParamGenerator::iterator begin1_; const typename ParamGenerator::iterator end1_; typename ParamGenerator::iterator current1_; const typename ParamGenerator::iterator begin2_; const typename ParamGenerator::iterator end2_; typename ParamGenerator::iterator current2_; ParamType current_value_; }; // class CartesianProductGenerator2::Iterator // No implementation - assignment is unsupported. void operator=(const CartesianProductGenerator2& other); const ParamGenerator g1_; const ParamGenerator g2_; }; // class CartesianProductGenerator2 template class CartesianProductGenerator3 : public ParamGeneratorInterface< ::std::tr1::tuple > { public: typedef ::std::tr1::tuple ParamType; CartesianProductGenerator3(const ParamGenerator& g1, const ParamGenerator& g2, const ParamGenerator& g3) : g1_(g1), g2_(g2), g3_(g3) {} virtual ~CartesianProductGenerator3() {} virtual ParamIteratorInterface* Begin() const { return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, g3_.begin()); } virtual ParamIteratorInterface* End() const { return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end()); } private: class Iterator : public ParamIteratorInterface { public: Iterator(const ParamGeneratorInterface* base, const ParamGenerator& g1, const typename ParamGenerator::iterator& current1, const ParamGenerator& g2, const typename ParamGenerator::iterator& current2, const ParamGenerator& g3, const typename ParamGenerator::iterator& current3) : base_(base), begin1_(g1.begin()), end1_(g1.end()), current1_(current1), begin2_(g2.begin()), end2_(g2.end()), current2_(current2), begin3_(g3.begin()), end3_(g3.end()), current3_(current3) { ComputeCurrentValue(); } virtual ~Iterator() {} virtual const ParamGeneratorInterface* BaseGenerator() const { return base_; } // Advance should not be called on beyond-of-range iterators // so no component iterators must be beyond end of range, either. virtual void Advance() { assert(!AtEnd()); ++current3_; if (current3_ == end3_) { current3_ = begin3_; ++current2_; } if (current2_ == end2_) { current2_ = begin2_; ++current1_; } ComputeCurrentValue(); } virtual ParamIteratorInterface* Clone() const { return new Iterator(*this); } virtual const ParamType* Current() const { return ¤t_value_; } virtual bool Equals(const ParamIteratorInterface& other) const { // Having the same base generator guarantees that the other // iterator is of the same type and we can downcast. GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) << "The program attempted to compare iterators " << "from different generators." << std::endl; const Iterator* typed_other = CheckedDowncastToActualType(&other); // We must report iterators equal if they both point beyond their // respective ranges. That can happen in a variety of fashions, // so we have to consult AtEnd(). return (AtEnd() && typed_other->AtEnd()) || ( current1_ == typed_other->current1_ && current2_ == typed_other->current2_ && current3_ == typed_other->current3_); } private: Iterator(const Iterator& other) : base_(other.base_), begin1_(other.begin1_), end1_(other.end1_), current1_(other.current1_), begin2_(other.begin2_), end2_(other.end2_), current2_(other.current2_), begin3_(other.begin3_), end3_(other.end3_), current3_(other.current3_) { ComputeCurrentValue(); } void ComputeCurrentValue() { if (!AtEnd()) current_value_ = ParamType(*current1_, *current2_, *current3_); } bool AtEnd() const { // We must report iterator past the end of the range when either of the // component iterators has reached the end of its range. return current1_ == end1_ || current2_ == end2_ || current3_ == end3_; } // No implementation - assignment is unsupported. void operator=(const Iterator& other); const ParamGeneratorInterface* const base_; // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. // current[i]_ is the actual traversing iterator. const typename ParamGenerator::iterator begin1_; const typename ParamGenerator::iterator end1_; typename ParamGenerator::iterator current1_; const typename ParamGenerator::iterator begin2_; const typename ParamGenerator::iterator end2_; typename ParamGenerator::iterator current2_; const typename ParamGenerator::iterator begin3_; const typename ParamGenerator::iterator end3_; typename ParamGenerator::iterator current3_; ParamType current_value_; }; // class CartesianProductGenerator3::Iterator // No implementation - assignment is unsupported. void operator=(const CartesianProductGenerator3& other); const ParamGenerator g1_; const ParamGenerator g2_; const ParamGenerator g3_; }; // class CartesianProductGenerator3 template class CartesianProductGenerator4 : public ParamGeneratorInterface< ::std::tr1::tuple > { public: typedef ::std::tr1::tuple ParamType; CartesianProductGenerator4(const ParamGenerator& g1, const ParamGenerator& g2, const ParamGenerator& g3, const ParamGenerator& g4) : g1_(g1), g2_(g2), g3_(g3), g4_(g4) {} virtual ~CartesianProductGenerator4() {} virtual ParamIteratorInterface* Begin() const { return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, g3_.begin(), g4_, g4_.begin()); } virtual ParamIteratorInterface* End() const { return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(), g4_, g4_.end()); } private: class Iterator : public ParamIteratorInterface { public: Iterator(const ParamGeneratorInterface* base, const ParamGenerator& g1, const typename ParamGenerator::iterator& current1, const ParamGenerator& g2, const typename ParamGenerator::iterator& current2, const ParamGenerator& g3, const typename ParamGenerator::iterator& current3, const ParamGenerator& g4, const typename ParamGenerator::iterator& current4) : base_(base), begin1_(g1.begin()), end1_(g1.end()), current1_(current1), begin2_(g2.begin()), end2_(g2.end()), current2_(current2), begin3_(g3.begin()), end3_(g3.end()), current3_(current3), begin4_(g4.begin()), end4_(g4.end()), current4_(current4) { ComputeCurrentValue(); } virtual ~Iterator() {} virtual const ParamGeneratorInterface* BaseGenerator() const { return base_; } // Advance should not be called on beyond-of-range iterators // so no component iterators must be beyond end of range, either. virtual void Advance() { assert(!AtEnd()); ++current4_; if (current4_ == end4_) { current4_ = begin4_; ++current3_; } if (current3_ == end3_) { current3_ = begin3_; ++current2_; } if (current2_ == end2_) { current2_ = begin2_; ++current1_; } ComputeCurrentValue(); } virtual ParamIteratorInterface* Clone() const { return new Iterator(*this); } virtual const ParamType* Current() const { return ¤t_value_; } virtual bool Equals(const ParamIteratorInterface& other) const { // Having the same base generator guarantees that the other // iterator is of the same type and we can downcast. GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) << "The program attempted to compare iterators " << "from different generators." << std::endl; const Iterator* typed_other = CheckedDowncastToActualType(&other); // We must report iterators equal if they both point beyond their // respective ranges. That can happen in a variety of fashions, // so we have to consult AtEnd(). return (AtEnd() && typed_other->AtEnd()) || ( current1_ == typed_other->current1_ && current2_ == typed_other->current2_ && current3_ == typed_other->current3_ && current4_ == typed_other->current4_); } private: Iterator(const Iterator& other) : base_(other.base_), begin1_(other.begin1_), end1_(other.end1_), current1_(other.current1_), begin2_(other.begin2_), end2_(other.end2_), current2_(other.current2_), begin3_(other.begin3_), end3_(other.end3_), current3_(other.current3_), begin4_(other.begin4_), end4_(other.end4_), current4_(other.current4_) { ComputeCurrentValue(); } void ComputeCurrentValue() { if (!AtEnd()) current_value_ = ParamType(*current1_, *current2_, *current3_, *current4_); } bool AtEnd() const { // We must report iterator past the end of the range when either of the // component iterators has reached the end of its range. return current1_ == end1_ || current2_ == end2_ || current3_ == end3_ || current4_ == end4_; } // No implementation - assignment is unsupported. void operator=(const Iterator& other); const ParamGeneratorInterface* const base_; // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. // current[i]_ is the actual traversing iterator. const typename ParamGenerator::iterator begin1_; const typename ParamGenerator::iterator end1_; typename ParamGenerator::iterator current1_; const typename ParamGenerator::iterator begin2_; const typename ParamGenerator::iterator end2_; typename ParamGenerator::iterator current2_; const typename ParamGenerator::iterator begin3_; const typename ParamGenerator::iterator end3_; typename ParamGenerator::iterator current3_; const typename ParamGenerator::iterator begin4_; const typename ParamGenerator::iterator end4_; typename ParamGenerator::iterator current4_; ParamType current_value_; }; // class CartesianProductGenerator4::Iterator // No implementation - assignment is unsupported. void operator=(const CartesianProductGenerator4& other); const ParamGenerator g1_; const ParamGenerator g2_; const ParamGenerator g3_; const ParamGenerator g4_; }; // class CartesianProductGenerator4 template class CartesianProductGenerator5 : public ParamGeneratorInterface< ::std::tr1::tuple > { public: typedef ::std::tr1::tuple ParamType; CartesianProductGenerator5(const ParamGenerator& g1, const ParamGenerator& g2, const ParamGenerator& g3, const ParamGenerator& g4, const ParamGenerator& g5) : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5) {} virtual ~CartesianProductGenerator5() {} virtual ParamIteratorInterface* Begin() const { return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin()); } virtual ParamIteratorInterface* End() const { return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(), g4_, g4_.end(), g5_, g5_.end()); } private: class Iterator : public ParamIteratorInterface { public: Iterator(const ParamGeneratorInterface* base, const ParamGenerator& g1, const typename ParamGenerator::iterator& current1, const ParamGenerator& g2, const typename ParamGenerator::iterator& current2, const ParamGenerator& g3, const typename ParamGenerator::iterator& current3, const ParamGenerator& g4, const typename ParamGenerator::iterator& current4, const ParamGenerator& g5, const typename ParamGenerator::iterator& current5) : base_(base), begin1_(g1.begin()), end1_(g1.end()), current1_(current1), begin2_(g2.begin()), end2_(g2.end()), current2_(current2), begin3_(g3.begin()), end3_(g3.end()), current3_(current3), begin4_(g4.begin()), end4_(g4.end()), current4_(current4), begin5_(g5.begin()), end5_(g5.end()), current5_(current5) { ComputeCurrentValue(); } virtual ~Iterator() {} virtual const ParamGeneratorInterface* BaseGenerator() const { return base_; } // Advance should not be called on beyond-of-range iterators // so no component iterators must be beyond end of range, either. virtual void Advance() { assert(!AtEnd()); ++current5_; if (current5_ == end5_) { current5_ = begin5_; ++current4_; } if (current4_ == end4_) { current4_ = begin4_; ++current3_; } if (current3_ == end3_) { current3_ = begin3_; ++current2_; } if (current2_ == end2_) { current2_ = begin2_; ++current1_; } ComputeCurrentValue(); } virtual ParamIteratorInterface* Clone() const { return new Iterator(*this); } virtual const ParamType* Current() const { return ¤t_value_; } virtual bool Equals(const ParamIteratorInterface& other) const { // Having the same base generator guarantees that the other // iterator is of the same type and we can downcast. GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) << "The program attempted to compare iterators " << "from different generators." << std::endl; const Iterator* typed_other = CheckedDowncastToActualType(&other); // We must report iterators equal if they both point beyond their // respective ranges. That can happen in a variety of fashions, // so we have to consult AtEnd(). return (AtEnd() && typed_other->AtEnd()) || ( current1_ == typed_other->current1_ && current2_ == typed_other->current2_ && current3_ == typed_other->current3_ && current4_ == typed_other->current4_ && current5_ == typed_other->current5_); } private: Iterator(const Iterator& other) : base_(other.base_), begin1_(other.begin1_), end1_(other.end1_), current1_(other.current1_), begin2_(other.begin2_), end2_(other.end2_), current2_(other.current2_), begin3_(other.begin3_), end3_(other.end3_), current3_(other.current3_), begin4_(other.begin4_), end4_(other.end4_), current4_(other.current4_), begin5_(other.begin5_), end5_(other.end5_), current5_(other.current5_) { ComputeCurrentValue(); } void ComputeCurrentValue() { if (!AtEnd()) current_value_ = ParamType(*current1_, *current2_, *current3_, *current4_, *current5_); } bool AtEnd() const { // We must report iterator past the end of the range when either of the // component iterators has reached the end of its range. return current1_ == end1_ || current2_ == end2_ || current3_ == end3_ || current4_ == end4_ || current5_ == end5_; } // No implementation - assignment is unsupported. void operator=(const Iterator& other); const ParamGeneratorInterface* const base_; // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. // current[i]_ is the actual traversing iterator. const typename ParamGenerator::iterator begin1_; const typename ParamGenerator::iterator end1_; typename ParamGenerator::iterator current1_; const typename ParamGenerator::iterator begin2_; const typename ParamGenerator::iterator end2_; typename ParamGenerator::iterator current2_; const typename ParamGenerator::iterator begin3_; const typename ParamGenerator::iterator end3_; typename ParamGenerator::iterator current3_; const typename ParamGenerator::iterator begin4_; const typename ParamGenerator::iterator end4_; typename ParamGenerator::iterator current4_; const typename ParamGenerator::iterator begin5_; const typename ParamGenerator::iterator end5_; typename ParamGenerator::iterator current5_; ParamType current_value_; }; // class CartesianProductGenerator5::Iterator // No implementation - assignment is unsupported. void operator=(const CartesianProductGenerator5& other); const ParamGenerator g1_; const ParamGenerator g2_; const ParamGenerator g3_; const ParamGenerator g4_; const ParamGenerator g5_; }; // class CartesianProductGenerator5 template class CartesianProductGenerator6 : public ParamGeneratorInterface< ::std::tr1::tuple > { public: typedef ::std::tr1::tuple ParamType; CartesianProductGenerator6(const ParamGenerator& g1, const ParamGenerator& g2, const ParamGenerator& g3, const ParamGenerator& g4, const ParamGenerator& g5, const ParamGenerator& g6) : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6) {} virtual ~CartesianProductGenerator6() {} virtual ParamIteratorInterface* Begin() const { return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin()); } virtual ParamIteratorInterface* End() const { return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(), g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end()); } private: class Iterator : public ParamIteratorInterface { public: Iterator(const ParamGeneratorInterface* base, const ParamGenerator& g1, const typename ParamGenerator::iterator& current1, const ParamGenerator& g2, const typename ParamGenerator::iterator& current2, const ParamGenerator& g3, const typename ParamGenerator::iterator& current3, const ParamGenerator& g4, const typename ParamGenerator::iterator& current4, const ParamGenerator& g5, const typename ParamGenerator::iterator& current5, const ParamGenerator& g6, const typename ParamGenerator::iterator& current6) : base_(base), begin1_(g1.begin()), end1_(g1.end()), current1_(current1), begin2_(g2.begin()), end2_(g2.end()), current2_(current2), begin3_(g3.begin()), end3_(g3.end()), current3_(current3), begin4_(g4.begin()), end4_(g4.end()), current4_(current4), begin5_(g5.begin()), end5_(g5.end()), current5_(current5), begin6_(g6.begin()), end6_(g6.end()), current6_(current6) { ComputeCurrentValue(); } virtual ~Iterator() {} virtual const ParamGeneratorInterface* BaseGenerator() const { return base_; } // Advance should not be called on beyond-of-range iterators // so no component iterators must be beyond end of range, either. virtual void Advance() { assert(!AtEnd()); ++current6_; if (current6_ == end6_) { current6_ = begin6_; ++current5_; } if (current5_ == end5_) { current5_ = begin5_; ++current4_; } if (current4_ == end4_) { current4_ = begin4_; ++current3_; } if (current3_ == end3_) { current3_ = begin3_; ++current2_; } if (current2_ == end2_) { current2_ = begin2_; ++current1_; } ComputeCurrentValue(); } virtual ParamIteratorInterface* Clone() const { return new Iterator(*this); } virtual const ParamType* Current() const { return ¤t_value_; } virtual bool Equals(const ParamIteratorInterface& other) const { // Having the same base generator guarantees that the other // iterator is of the same type and we can downcast. GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) << "The program attempted to compare iterators " << "from different generators." << std::endl; const Iterator* typed_other = CheckedDowncastToActualType(&other); // We must report iterators equal if they both point beyond their // respective ranges. That can happen in a variety of fashions, // so we have to consult AtEnd(). return (AtEnd() && typed_other->AtEnd()) || ( current1_ == typed_other->current1_ && current2_ == typed_other->current2_ && current3_ == typed_other->current3_ && current4_ == typed_other->current4_ && current5_ == typed_other->current5_ && current6_ == typed_other->current6_); } private: Iterator(const Iterator& other) : base_(other.base_), begin1_(other.begin1_), end1_(other.end1_), current1_(other.current1_), begin2_(other.begin2_), end2_(other.end2_), current2_(other.current2_), begin3_(other.begin3_), end3_(other.end3_), current3_(other.current3_), begin4_(other.begin4_), end4_(other.end4_), current4_(other.current4_), begin5_(other.begin5_), end5_(other.end5_), current5_(other.current5_), begin6_(other.begin6_), end6_(other.end6_), current6_(other.current6_) { ComputeCurrentValue(); } void ComputeCurrentValue() { if (!AtEnd()) current_value_ = ParamType(*current1_, *current2_, *current3_, *current4_, *current5_, *current6_); } bool AtEnd() const { // We must report iterator past the end of the range when either of the // component iterators has reached the end of its range. return current1_ == end1_ || current2_ == end2_ || current3_ == end3_ || current4_ == end4_ || current5_ == end5_ || current6_ == end6_; } // No implementation - assignment is unsupported. void operator=(const Iterator& other); const ParamGeneratorInterface* const base_; // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. // current[i]_ is the actual traversing iterator. const typename ParamGenerator::iterator begin1_; const typename ParamGenerator::iterator end1_; typename ParamGenerator::iterator current1_; const typename ParamGenerator::iterator begin2_; const typename ParamGenerator::iterator end2_; typename ParamGenerator::iterator current2_; const typename ParamGenerator::iterator begin3_; const typename ParamGenerator::iterator end3_; typename ParamGenerator::iterator current3_; const typename ParamGenerator::iterator begin4_; const typename ParamGenerator::iterator end4_; typename ParamGenerator::iterator current4_; const typename ParamGenerator::iterator begin5_; const typename ParamGenerator::iterator end5_; typename ParamGenerator::iterator current5_; const typename ParamGenerator::iterator begin6_; const typename ParamGenerator::iterator end6_; typename ParamGenerator::iterator current6_; ParamType current_value_; }; // class CartesianProductGenerator6::Iterator // No implementation - assignment is unsupported. void operator=(const CartesianProductGenerator6& other); const ParamGenerator g1_; const ParamGenerator g2_; const ParamGenerator g3_; const ParamGenerator g4_; const ParamGenerator g5_; const ParamGenerator g6_; }; // class CartesianProductGenerator6 template class CartesianProductGenerator7 : public ParamGeneratorInterface< ::std::tr1::tuple > { public: typedef ::std::tr1::tuple ParamType; CartesianProductGenerator7(const ParamGenerator& g1, const ParamGenerator& g2, const ParamGenerator& g3, const ParamGenerator& g4, const ParamGenerator& g5, const ParamGenerator& g6, const ParamGenerator& g7) : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7) {} virtual ~CartesianProductGenerator7() {} virtual ParamIteratorInterface* Begin() const { return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin(), g7_, g7_.begin()); } virtual ParamIteratorInterface* End() const { return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(), g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end(), g7_, g7_.end()); } private: class Iterator : public ParamIteratorInterface { public: Iterator(const ParamGeneratorInterface* base, const ParamGenerator& g1, const typename ParamGenerator::iterator& current1, const ParamGenerator& g2, const typename ParamGenerator::iterator& current2, const ParamGenerator& g3, const typename ParamGenerator::iterator& current3, const ParamGenerator& g4, const typename ParamGenerator::iterator& current4, const ParamGenerator& g5, const typename ParamGenerator::iterator& current5, const ParamGenerator& g6, const typename ParamGenerator::iterator& current6, const ParamGenerator& g7, const typename ParamGenerator::iterator& current7) : base_(base), begin1_(g1.begin()), end1_(g1.end()), current1_(current1), begin2_(g2.begin()), end2_(g2.end()), current2_(current2), begin3_(g3.begin()), end3_(g3.end()), current3_(current3), begin4_(g4.begin()), end4_(g4.end()), current4_(current4), begin5_(g5.begin()), end5_(g5.end()), current5_(current5), begin6_(g6.begin()), end6_(g6.end()), current6_(current6), begin7_(g7.begin()), end7_(g7.end()), current7_(current7) { ComputeCurrentValue(); } virtual ~Iterator() {} virtual const ParamGeneratorInterface* BaseGenerator() const { return base_; } // Advance should not be called on beyond-of-range iterators // so no component iterators must be beyond end of range, either. virtual void Advance() { assert(!AtEnd()); ++current7_; if (current7_ == end7_) { current7_ = begin7_; ++current6_; } if (current6_ == end6_) { current6_ = begin6_; ++current5_; } if (current5_ == end5_) { current5_ = begin5_; ++current4_; } if (current4_ == end4_) { current4_ = begin4_; ++current3_; } if (current3_ == end3_) { current3_ = begin3_; ++current2_; } if (current2_ == end2_) { current2_ = begin2_; ++current1_; } ComputeCurrentValue(); } virtual ParamIteratorInterface* Clone() const { return new Iterator(*this); } virtual const ParamType* Current() const { return ¤t_value_; } virtual bool Equals(const ParamIteratorInterface& other) const { // Having the same base generator guarantees that the other // iterator is of the same type and we can downcast. GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) << "The program attempted to compare iterators " << "from different generators." << std::endl; const Iterator* typed_other = CheckedDowncastToActualType(&other); // We must report iterators equal if they both point beyond their // respective ranges. That can happen in a variety of fashions, // so we have to consult AtEnd(). return (AtEnd() && typed_other->AtEnd()) || ( current1_ == typed_other->current1_ && current2_ == typed_other->current2_ && current3_ == typed_other->current3_ && current4_ == typed_other->current4_ && current5_ == typed_other->current5_ && current6_ == typed_other->current6_ && current7_ == typed_other->current7_); } private: Iterator(const Iterator& other) : base_(other.base_), begin1_(other.begin1_), end1_(other.end1_), current1_(other.current1_), begin2_(other.begin2_), end2_(other.end2_), current2_(other.current2_), begin3_(other.begin3_), end3_(other.end3_), current3_(other.current3_), begin4_(other.begin4_), end4_(other.end4_), current4_(other.current4_), begin5_(other.begin5_), end5_(other.end5_), current5_(other.current5_), begin6_(other.begin6_), end6_(other.end6_), current6_(other.current6_), begin7_(other.begin7_), end7_(other.end7_), current7_(other.current7_) { ComputeCurrentValue(); } void ComputeCurrentValue() { if (!AtEnd()) current_value_ = ParamType(*current1_, *current2_, *current3_, *current4_, *current5_, *current6_, *current7_); } bool AtEnd() const { // We must report iterator past the end of the range when either of the // component iterators has reached the end of its range. return current1_ == end1_ || current2_ == end2_ || current3_ == end3_ || current4_ == end4_ || current5_ == end5_ || current6_ == end6_ || current7_ == end7_; } // No implementation - assignment is unsupported. void operator=(const Iterator& other); const ParamGeneratorInterface* const base_; // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. // current[i]_ is the actual traversing iterator. const typename ParamGenerator::iterator begin1_; const typename ParamGenerator::iterator end1_; typename ParamGenerator::iterator current1_; const typename ParamGenerator::iterator begin2_; const typename ParamGenerator::iterator end2_; typename ParamGenerator::iterator current2_; const typename ParamGenerator::iterator begin3_; const typename ParamGenerator::iterator end3_; typename ParamGenerator::iterator current3_; const typename ParamGenerator::iterator begin4_; const typename ParamGenerator::iterator end4_; typename ParamGenerator::iterator current4_; const typename ParamGenerator::iterator begin5_; const typename ParamGenerator::iterator end5_; typename ParamGenerator::iterator current5_; const typename ParamGenerator::iterator begin6_; const typename ParamGenerator::iterator end6_; typename ParamGenerator::iterator current6_; const typename ParamGenerator::iterator begin7_; const typename ParamGenerator::iterator end7_; typename ParamGenerator::iterator current7_; ParamType current_value_; }; // class CartesianProductGenerator7::Iterator // No implementation - assignment is unsupported. void operator=(const CartesianProductGenerator7& other); const ParamGenerator g1_; const ParamGenerator g2_; const ParamGenerator g3_; const ParamGenerator g4_; const ParamGenerator g5_; const ParamGenerator g6_; const ParamGenerator g7_; }; // class CartesianProductGenerator7 template class CartesianProductGenerator8 : public ParamGeneratorInterface< ::std::tr1::tuple > { public: typedef ::std::tr1::tuple ParamType; CartesianProductGenerator8(const ParamGenerator& g1, const ParamGenerator& g2, const ParamGenerator& g3, const ParamGenerator& g4, const ParamGenerator& g5, const ParamGenerator& g6, const ParamGenerator& g7, const ParamGenerator& g8) : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), g8_(g8) {} virtual ~CartesianProductGenerator8() {} virtual ParamIteratorInterface* Begin() const { return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin(), g7_, g7_.begin(), g8_, g8_.begin()); } virtual ParamIteratorInterface* End() const { return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(), g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end(), g7_, g7_.end(), g8_, g8_.end()); } private: class Iterator : public ParamIteratorInterface { public: Iterator(const ParamGeneratorInterface* base, const ParamGenerator& g1, const typename ParamGenerator::iterator& current1, const ParamGenerator& g2, const typename ParamGenerator::iterator& current2, const ParamGenerator& g3, const typename ParamGenerator::iterator& current3, const ParamGenerator& g4, const typename ParamGenerator::iterator& current4, const ParamGenerator& g5, const typename ParamGenerator::iterator& current5, const ParamGenerator& g6, const typename ParamGenerator::iterator& current6, const ParamGenerator& g7, const typename ParamGenerator::iterator& current7, const ParamGenerator& g8, const typename ParamGenerator::iterator& current8) : base_(base), begin1_(g1.begin()), end1_(g1.end()), current1_(current1), begin2_(g2.begin()), end2_(g2.end()), current2_(current2), begin3_(g3.begin()), end3_(g3.end()), current3_(current3), begin4_(g4.begin()), end4_(g4.end()), current4_(current4), begin5_(g5.begin()), end5_(g5.end()), current5_(current5), begin6_(g6.begin()), end6_(g6.end()), current6_(current6), begin7_(g7.begin()), end7_(g7.end()), current7_(current7), begin8_(g8.begin()), end8_(g8.end()), current8_(current8) { ComputeCurrentValue(); } virtual ~Iterator() {} virtual const ParamGeneratorInterface* BaseGenerator() const { return base_; } // Advance should not be called on beyond-of-range iterators // so no component iterators must be beyond end of range, either. virtual void Advance() { assert(!AtEnd()); ++current8_; if (current8_ == end8_) { current8_ = begin8_; ++current7_; } if (current7_ == end7_) { current7_ = begin7_; ++current6_; } if (current6_ == end6_) { current6_ = begin6_; ++current5_; } if (current5_ == end5_) { current5_ = begin5_; ++current4_; } if (current4_ == end4_) { current4_ = begin4_; ++current3_; } if (current3_ == end3_) { current3_ = begin3_; ++current2_; } if (current2_ == end2_) { current2_ = begin2_; ++current1_; } ComputeCurrentValue(); } virtual ParamIteratorInterface* Clone() const { return new Iterator(*this); } virtual const ParamType* Current() const { return ¤t_value_; } virtual bool Equals(const ParamIteratorInterface& other) const { // Having the same base generator guarantees that the other // iterator is of the same type and we can downcast. GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) << "The program attempted to compare iterators " << "from different generators." << std::endl; const Iterator* typed_other = CheckedDowncastToActualType(&other); // We must report iterators equal if they both point beyond their // respective ranges. That can happen in a variety of fashions, // so we have to consult AtEnd(). return (AtEnd() && typed_other->AtEnd()) || ( current1_ == typed_other->current1_ && current2_ == typed_other->current2_ && current3_ == typed_other->current3_ && current4_ == typed_other->current4_ && current5_ == typed_other->current5_ && current6_ == typed_other->current6_ && current7_ == typed_other->current7_ && current8_ == typed_other->current8_); } private: Iterator(const Iterator& other) : base_(other.base_), begin1_(other.begin1_), end1_(other.end1_), current1_(other.current1_), begin2_(other.begin2_), end2_(other.end2_), current2_(other.current2_), begin3_(other.begin3_), end3_(other.end3_), current3_(other.current3_), begin4_(other.begin4_), end4_(other.end4_), current4_(other.current4_), begin5_(other.begin5_), end5_(other.end5_), current5_(other.current5_), begin6_(other.begin6_), end6_(other.end6_), current6_(other.current6_), begin7_(other.begin7_), end7_(other.end7_), current7_(other.current7_), begin8_(other.begin8_), end8_(other.end8_), current8_(other.current8_) { ComputeCurrentValue(); } void ComputeCurrentValue() { if (!AtEnd()) current_value_ = ParamType(*current1_, *current2_, *current3_, *current4_, *current5_, *current6_, *current7_, *current8_); } bool AtEnd() const { // We must report iterator past the end of the range when either of the // component iterators has reached the end of its range. return current1_ == end1_ || current2_ == end2_ || current3_ == end3_ || current4_ == end4_ || current5_ == end5_ || current6_ == end6_ || current7_ == end7_ || current8_ == end8_; } // No implementation - assignment is unsupported. void operator=(const Iterator& other); const ParamGeneratorInterface* const base_; // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. // current[i]_ is the actual traversing iterator. const typename ParamGenerator::iterator begin1_; const typename ParamGenerator::iterator end1_; typename ParamGenerator::iterator current1_; const typename ParamGenerator::iterator begin2_; const typename ParamGenerator::iterator end2_; typename ParamGenerator::iterator current2_; const typename ParamGenerator::iterator begin3_; const typename ParamGenerator::iterator end3_; typename ParamGenerator::iterator current3_; const typename ParamGenerator::iterator begin4_; const typename ParamGenerator::iterator end4_; typename ParamGenerator::iterator current4_; const typename ParamGenerator::iterator begin5_; const typename ParamGenerator::iterator end5_; typename ParamGenerator::iterator current5_; const typename ParamGenerator::iterator begin6_; const typename ParamGenerator::iterator end6_; typename ParamGenerator::iterator current6_; const typename ParamGenerator::iterator begin7_; const typename ParamGenerator::iterator end7_; typename ParamGenerator::iterator current7_; const typename ParamGenerator::iterator begin8_; const typename ParamGenerator::iterator end8_; typename ParamGenerator::iterator current8_; ParamType current_value_; }; // class CartesianProductGenerator8::Iterator // No implementation - assignment is unsupported. void operator=(const CartesianProductGenerator8& other); const ParamGenerator g1_; const ParamGenerator g2_; const ParamGenerator g3_; const ParamGenerator g4_; const ParamGenerator g5_; const ParamGenerator g6_; const ParamGenerator g7_; const ParamGenerator g8_; }; // class CartesianProductGenerator8 template class CartesianProductGenerator9 : public ParamGeneratorInterface< ::std::tr1::tuple > { public: typedef ::std::tr1::tuple ParamType; CartesianProductGenerator9(const ParamGenerator& g1, const ParamGenerator& g2, const ParamGenerator& g3, const ParamGenerator& g4, const ParamGenerator& g5, const ParamGenerator& g6, const ParamGenerator& g7, const ParamGenerator& g8, const ParamGenerator& g9) : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), g8_(g8), g9_(g9) {} virtual ~CartesianProductGenerator9() {} virtual ParamIteratorInterface* Begin() const { return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin(), g7_, g7_.begin(), g8_, g8_.begin(), g9_, g9_.begin()); } virtual ParamIteratorInterface* End() const { return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(), g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end(), g7_, g7_.end(), g8_, g8_.end(), g9_, g9_.end()); } private: class Iterator : public ParamIteratorInterface { public: Iterator(const ParamGeneratorInterface* base, const ParamGenerator& g1, const typename ParamGenerator::iterator& current1, const ParamGenerator& g2, const typename ParamGenerator::iterator& current2, const ParamGenerator& g3, const typename ParamGenerator::iterator& current3, const ParamGenerator& g4, const typename ParamGenerator::iterator& current4, const ParamGenerator& g5, const typename ParamGenerator::iterator& current5, const ParamGenerator& g6, const typename ParamGenerator::iterator& current6, const ParamGenerator& g7, const typename ParamGenerator::iterator& current7, const ParamGenerator& g8, const typename ParamGenerator::iterator& current8, const ParamGenerator& g9, const typename ParamGenerator::iterator& current9) : base_(base), begin1_(g1.begin()), end1_(g1.end()), current1_(current1), begin2_(g2.begin()), end2_(g2.end()), current2_(current2), begin3_(g3.begin()), end3_(g3.end()), current3_(current3), begin4_(g4.begin()), end4_(g4.end()), current4_(current4), begin5_(g5.begin()), end5_(g5.end()), current5_(current5), begin6_(g6.begin()), end6_(g6.end()), current6_(current6), begin7_(g7.begin()), end7_(g7.end()), current7_(current7), begin8_(g8.begin()), end8_(g8.end()), current8_(current8), begin9_(g9.begin()), end9_(g9.end()), current9_(current9) { ComputeCurrentValue(); } virtual ~Iterator() {} virtual const ParamGeneratorInterface* BaseGenerator() const { return base_; } // Advance should not be called on beyond-of-range iterators // so no component iterators must be beyond end of range, either. virtual void Advance() { assert(!AtEnd()); ++current9_; if (current9_ == end9_) { current9_ = begin9_; ++current8_; } if (current8_ == end8_) { current8_ = begin8_; ++current7_; } if (current7_ == end7_) { current7_ = begin7_; ++current6_; } if (current6_ == end6_) { current6_ = begin6_; ++current5_; } if (current5_ == end5_) { current5_ = begin5_; ++current4_; } if (current4_ == end4_) { current4_ = begin4_; ++current3_; } if (current3_ == end3_) { current3_ = begin3_; ++current2_; } if (current2_ == end2_) { current2_ = begin2_; ++current1_; } ComputeCurrentValue(); } virtual ParamIteratorInterface* Clone() const { return new Iterator(*this); } virtual const ParamType* Current() const { return ¤t_value_; } virtual bool Equals(const ParamIteratorInterface& other) const { // Having the same base generator guarantees that the other // iterator is of the same type and we can downcast. GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) << "The program attempted to compare iterators " << "from different generators." << std::endl; const Iterator* typed_other = CheckedDowncastToActualType(&other); // We must report iterators equal if they both point beyond their // respective ranges. That can happen in a variety of fashions, // so we have to consult AtEnd(). return (AtEnd() && typed_other->AtEnd()) || ( current1_ == typed_other->current1_ && current2_ == typed_other->current2_ && current3_ == typed_other->current3_ && current4_ == typed_other->current4_ && current5_ == typed_other->current5_ && current6_ == typed_other->current6_ && current7_ == typed_other->current7_ && current8_ == typed_other->current8_ && current9_ == typed_other->current9_); } private: Iterator(const Iterator& other) : base_(other.base_), begin1_(other.begin1_), end1_(other.end1_), current1_(other.current1_), begin2_(other.begin2_), end2_(other.end2_), current2_(other.current2_), begin3_(other.begin3_), end3_(other.end3_), current3_(other.current3_), begin4_(other.begin4_), end4_(other.end4_), current4_(other.current4_), begin5_(other.begin5_), end5_(other.end5_), current5_(other.current5_), begin6_(other.begin6_), end6_(other.end6_), current6_(other.current6_), begin7_(other.begin7_), end7_(other.end7_), current7_(other.current7_), begin8_(other.begin8_), end8_(other.end8_), current8_(other.current8_), begin9_(other.begin9_), end9_(other.end9_), current9_(other.current9_) { ComputeCurrentValue(); } void ComputeCurrentValue() { if (!AtEnd()) current_value_ = ParamType(*current1_, *current2_, *current3_, *current4_, *current5_, *current6_, *current7_, *current8_, *current9_); } bool AtEnd() const { // We must report iterator past the end of the range when either of the // component iterators has reached the end of its range. return current1_ == end1_ || current2_ == end2_ || current3_ == end3_ || current4_ == end4_ || current5_ == end5_ || current6_ == end6_ || current7_ == end7_ || current8_ == end8_ || current9_ == end9_; } // No implementation - assignment is unsupported. void operator=(const Iterator& other); const ParamGeneratorInterface* const base_; // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. // current[i]_ is the actual traversing iterator. const typename ParamGenerator::iterator begin1_; const typename ParamGenerator::iterator end1_; typename ParamGenerator::iterator current1_; const typename ParamGenerator::iterator begin2_; const typename ParamGenerator::iterator end2_; typename ParamGenerator::iterator current2_; const typename ParamGenerator::iterator begin3_; const typename ParamGenerator::iterator end3_; typename ParamGenerator::iterator current3_; const typename ParamGenerator::iterator begin4_; const typename ParamGenerator::iterator end4_; typename ParamGenerator::iterator current4_; const typename ParamGenerator::iterator begin5_; const typename ParamGenerator::iterator end5_; typename ParamGenerator::iterator current5_; const typename ParamGenerator::iterator begin6_; const typename ParamGenerator::iterator end6_; typename ParamGenerator::iterator current6_; const typename ParamGenerator::iterator begin7_; const typename ParamGenerator::iterator end7_; typename ParamGenerator::iterator current7_; const typename ParamGenerator::iterator begin8_; const typename ParamGenerator::iterator end8_; typename ParamGenerator::iterator current8_; const typename ParamGenerator::iterator begin9_; const typename ParamGenerator::iterator end9_; typename ParamGenerator::iterator current9_; ParamType current_value_; }; // class CartesianProductGenerator9::Iterator // No implementation - assignment is unsupported. void operator=(const CartesianProductGenerator9& other); const ParamGenerator g1_; const ParamGenerator g2_; const ParamGenerator g3_; const ParamGenerator g4_; const ParamGenerator g5_; const ParamGenerator g6_; const ParamGenerator g7_; const ParamGenerator g8_; const ParamGenerator g9_; }; // class CartesianProductGenerator9 template class CartesianProductGenerator10 : public ParamGeneratorInterface< ::std::tr1::tuple > { public: typedef ::std::tr1::tuple ParamType; CartesianProductGenerator10(const ParamGenerator& g1, const ParamGenerator& g2, const ParamGenerator& g3, const ParamGenerator& g4, const ParamGenerator& g5, const ParamGenerator& g6, const ParamGenerator& g7, const ParamGenerator& g8, const ParamGenerator& g9, const ParamGenerator& g10) : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), g8_(g8), g9_(g9), g10_(g10) {} virtual ~CartesianProductGenerator10() {} virtual ParamIteratorInterface* Begin() const { return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin(), g7_, g7_.begin(), g8_, g8_.begin(), g9_, g9_.begin(), g10_, g10_.begin()); } virtual ParamIteratorInterface* End() const { return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(), g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end(), g7_, g7_.end(), g8_, g8_.end(), g9_, g9_.end(), g10_, g10_.end()); } private: class Iterator : public ParamIteratorInterface { public: Iterator(const ParamGeneratorInterface* base, const ParamGenerator& g1, const typename ParamGenerator::iterator& current1, const ParamGenerator& g2, const typename ParamGenerator::iterator& current2, const ParamGenerator& g3, const typename ParamGenerator::iterator& current3, const ParamGenerator& g4, const typename ParamGenerator::iterator& current4, const ParamGenerator& g5, const typename ParamGenerator::iterator& current5, const ParamGenerator& g6, const typename ParamGenerator::iterator& current6, const ParamGenerator& g7, const typename ParamGenerator::iterator& current7, const ParamGenerator& g8, const typename ParamGenerator::iterator& current8, const ParamGenerator& g9, const typename ParamGenerator::iterator& current9, const ParamGenerator& g10, const typename ParamGenerator::iterator& current10) : base_(base), begin1_(g1.begin()), end1_(g1.end()), current1_(current1), begin2_(g2.begin()), end2_(g2.end()), current2_(current2), begin3_(g3.begin()), end3_(g3.end()), current3_(current3), begin4_(g4.begin()), end4_(g4.end()), current4_(current4), begin5_(g5.begin()), end5_(g5.end()), current5_(current5), begin6_(g6.begin()), end6_(g6.end()), current6_(current6), begin7_(g7.begin()), end7_(g7.end()), current7_(current7), begin8_(g8.begin()), end8_(g8.end()), current8_(current8), begin9_(g9.begin()), end9_(g9.end()), current9_(current9), begin10_(g10.begin()), end10_(g10.end()), current10_(current10) { ComputeCurrentValue(); } virtual ~Iterator() {} virtual const ParamGeneratorInterface* BaseGenerator() const { return base_; } // Advance should not be called on beyond-of-range iterators // so no component iterators must be beyond end of range, either. virtual void Advance() { assert(!AtEnd()); ++current10_; if (current10_ == end10_) { current10_ = begin10_; ++current9_; } if (current9_ == end9_) { current9_ = begin9_; ++current8_; } if (current8_ == end8_) { current8_ = begin8_; ++current7_; } if (current7_ == end7_) { current7_ = begin7_; ++current6_; } if (current6_ == end6_) { current6_ = begin6_; ++current5_; } if (current5_ == end5_) { current5_ = begin5_; ++current4_; } if (current4_ == end4_) { current4_ = begin4_; ++current3_; } if (current3_ == end3_) { current3_ = begin3_; ++current2_; } if (current2_ == end2_) { current2_ = begin2_; ++current1_; } ComputeCurrentValue(); } virtual ParamIteratorInterface* Clone() const { return new Iterator(*this); } virtual const ParamType* Current() const { return ¤t_value_; } virtual bool Equals(const ParamIteratorInterface& other) const { // Having the same base generator guarantees that the other // iterator is of the same type and we can downcast. GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) << "The program attempted to compare iterators " << "from different generators." << std::endl; const Iterator* typed_other = CheckedDowncastToActualType(&other); // We must report iterators equal if they both point beyond their // respective ranges. That can happen in a variety of fashions, // so we have to consult AtEnd(). return (AtEnd() && typed_other->AtEnd()) || ( current1_ == typed_other->current1_ && current2_ == typed_other->current2_ && current3_ == typed_other->current3_ && current4_ == typed_other->current4_ && current5_ == typed_other->current5_ && current6_ == typed_other->current6_ && current7_ == typed_other->current7_ && current8_ == typed_other->current8_ && current9_ == typed_other->current9_ && current10_ == typed_other->current10_); } private: Iterator(const Iterator& other) : base_(other.base_), begin1_(other.begin1_), end1_(other.end1_), current1_(other.current1_), begin2_(other.begin2_), end2_(other.end2_), current2_(other.current2_), begin3_(other.begin3_), end3_(other.end3_), current3_(other.current3_), begin4_(other.begin4_), end4_(other.end4_), current4_(other.current4_), begin5_(other.begin5_), end5_(other.end5_), current5_(other.current5_), begin6_(other.begin6_), end6_(other.end6_), current6_(other.current6_), begin7_(other.begin7_), end7_(other.end7_), current7_(other.current7_), begin8_(other.begin8_), end8_(other.end8_), current8_(other.current8_), begin9_(other.begin9_), end9_(other.end9_), current9_(other.current9_), begin10_(other.begin10_), end10_(other.end10_), current10_(other.current10_) { ComputeCurrentValue(); } void ComputeCurrentValue() { if (!AtEnd()) current_value_ = ParamType(*current1_, *current2_, *current3_, *current4_, *current5_, *current6_, *current7_, *current8_, *current9_, *current10_); } bool AtEnd() const { // We must report iterator past the end of the range when either of the // component iterators has reached the end of its range. return current1_ == end1_ || current2_ == end2_ || current3_ == end3_ || current4_ == end4_ || current5_ == end5_ || current6_ == end6_ || current7_ == end7_ || current8_ == end8_ || current9_ == end9_ || current10_ == end10_; } // No implementation - assignment is unsupported. void operator=(const Iterator& other); const ParamGeneratorInterface* const base_; // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. // current[i]_ is the actual traversing iterator. const typename ParamGenerator::iterator begin1_; const typename ParamGenerator::iterator end1_; typename ParamGenerator::iterator current1_; const typename ParamGenerator::iterator begin2_; const typename ParamGenerator::iterator end2_; typename ParamGenerator::iterator current2_; const typename ParamGenerator::iterator begin3_; const typename ParamGenerator::iterator end3_; typename ParamGenerator::iterator current3_; const typename ParamGenerator::iterator begin4_; const typename ParamGenerator::iterator end4_; typename ParamGenerator::iterator current4_; const typename ParamGenerator::iterator begin5_; const typename ParamGenerator::iterator end5_; typename ParamGenerator::iterator current5_; const typename ParamGenerator::iterator begin6_; const typename ParamGenerator::iterator end6_; typename ParamGenerator::iterator current6_; const typename ParamGenerator::iterator begin7_; const typename ParamGenerator::iterator end7_; typename ParamGenerator::iterator current7_; const typename ParamGenerator::iterator begin8_; const typename ParamGenerator::iterator end8_; typename ParamGenerator::iterator current8_; const typename ParamGenerator::iterator begin9_; const typename ParamGenerator::iterator end9_; typename ParamGenerator::iterator current9_; const typename ParamGenerator::iterator begin10_; const typename ParamGenerator::iterator end10_; typename ParamGenerator::iterator current10_; ParamType current_value_; }; // class CartesianProductGenerator10::Iterator // No implementation - assignment is unsupported. void operator=(const CartesianProductGenerator10& other); const ParamGenerator g1_; const ParamGenerator g2_; const ParamGenerator g3_; const ParamGenerator g4_; const ParamGenerator g5_; const ParamGenerator g6_; const ParamGenerator g7_; const ParamGenerator g8_; const ParamGenerator g9_; const ParamGenerator g10_; }; // class CartesianProductGenerator10 // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. // // Helper classes providing Combine() with polymorphic features. They allow // casting CartesianProductGeneratorN to ParamGenerator if T is // convertible to U. // template class CartesianProductHolder2 { public: CartesianProductHolder2(const Generator1& g1, const Generator2& g2) : g1_(g1), g2_(g2) {} template operator ParamGenerator< ::std::tr1::tuple >() const { return ParamGenerator< ::std::tr1::tuple >( new CartesianProductGenerator2( static_cast >(g1_), static_cast >(g2_))); } private: // No implementation - assignment is unsupported. void operator=(const CartesianProductHolder2& other); const Generator1 g1_; const Generator2 g2_; }; // class CartesianProductHolder2 template class CartesianProductHolder3 { public: 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 >( new CartesianProductGenerator3( static_cast >(g1_), static_cast >(g2_), static_cast >(g3_))); } private: // No implementation - assignment is unsupported. void operator=(const CartesianProductHolder3& other); const Generator1 g1_; const Generator2 g2_; const Generator3 g3_; }; // class CartesianProductHolder3 template class CartesianProductHolder4 { public: 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 >( new CartesianProductGenerator4( static_cast >(g1_), static_cast >(g2_), static_cast >(g3_), static_cast >(g4_))); } private: // No implementation - assignment is unsupported. void operator=(const CartesianProductHolder4& other); const Generator1 g1_; const Generator2 g2_; const Generator3 g3_; const Generator4 g4_; }; // class CartesianProductHolder4 template class CartesianProductHolder5 { public: CartesianProductHolder5(const Generator1& g1, const Generator2& g2, const Generator3& g3, const Generator4& g4, const Generator5& g5) : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5) {} template operator ParamGenerator< ::std::tr1::tuple >() const { return ParamGenerator< ::std::tr1::tuple >( new CartesianProductGenerator5( static_cast >(g1_), static_cast >(g2_), static_cast >(g3_), static_cast >(g4_), static_cast >(g5_))); } private: // No implementation - assignment is unsupported. void operator=(const CartesianProductHolder5& other); const Generator1 g1_; const Generator2 g2_; const Generator3 g3_; const Generator4 g4_; const Generator5 g5_; }; // class CartesianProductHolder5 template class CartesianProductHolder6 { public: CartesianProductHolder6(const Generator1& g1, const Generator2& g2, const Generator3& g3, const Generator4& g4, const Generator5& g5, const Generator6& g6) : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6) {} template operator ParamGenerator< ::std::tr1::tuple >() const { return ParamGenerator< ::std::tr1::tuple >( new CartesianProductGenerator6( static_cast >(g1_), static_cast >(g2_), static_cast >(g3_), static_cast >(g4_), static_cast >(g5_), static_cast >(g6_))); } private: // No implementation - assignment is unsupported. void operator=(const CartesianProductHolder6& other); const Generator1 g1_; const Generator2 g2_; const Generator3 g3_; const Generator4 g4_; const Generator5 g5_; const Generator6 g6_; }; // class CartesianProductHolder6 template class CartesianProductHolder7 { public: CartesianProductHolder7(const Generator1& g1, const Generator2& g2, const Generator3& g3, const Generator4& g4, const Generator5& g5, const Generator6& g6, const Generator7& g7) : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7) {} template operator ParamGenerator< ::std::tr1::tuple >() const { return ParamGenerator< ::std::tr1::tuple >( new CartesianProductGenerator7( static_cast >(g1_), static_cast >(g2_), static_cast >(g3_), static_cast >(g4_), static_cast >(g5_), static_cast >(g6_), static_cast >(g7_))); } private: // No implementation - assignment is unsupported. void operator=(const CartesianProductHolder7& other); const Generator1 g1_; const Generator2 g2_; const Generator3 g3_; const Generator4 g4_; const Generator5 g5_; const Generator6 g6_; const Generator7 g7_; }; // class CartesianProductHolder7 template class CartesianProductHolder8 { public: CartesianProductHolder8(const Generator1& g1, const Generator2& g2, const Generator3& g3, const Generator4& g4, const Generator5& g5, const Generator6& g6, const Generator7& g7, const Generator8& g8) : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), g8_(g8) {} template operator ParamGenerator< ::std::tr1::tuple >() const { return ParamGenerator< ::std::tr1::tuple >( new CartesianProductGenerator8( static_cast >(g1_), static_cast >(g2_), static_cast >(g3_), static_cast >(g4_), static_cast >(g5_), static_cast >(g6_), static_cast >(g7_), static_cast >(g8_))); } private: // No implementation - assignment is unsupported. void operator=(const CartesianProductHolder8& other); const Generator1 g1_; const Generator2 g2_; const Generator3 g3_; const Generator4 g4_; const Generator5 g5_; const Generator6 g6_; const Generator7 g7_; const Generator8 g8_; }; // class CartesianProductHolder8 template class CartesianProductHolder9 { public: CartesianProductHolder9(const Generator1& g1, const Generator2& g2, const Generator3& g3, const Generator4& g4, const Generator5& g5, const Generator6& g6, const Generator7& g7, const Generator8& g8, const Generator9& g9) : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), g8_(g8), g9_(g9) {} template operator ParamGenerator< ::std::tr1::tuple >() const { return ParamGenerator< ::std::tr1::tuple >( new CartesianProductGenerator9( static_cast >(g1_), static_cast >(g2_), static_cast >(g3_), static_cast >(g4_), static_cast >(g5_), static_cast >(g6_), static_cast >(g7_), static_cast >(g8_), static_cast >(g9_))); } private: // No implementation - assignment is unsupported. void operator=(const CartesianProductHolder9& other); const Generator1 g1_; const Generator2 g2_; const Generator3 g3_; const Generator4 g4_; const Generator5 g5_; const Generator6 g6_; const Generator7 g7_; const Generator8 g8_; const Generator9 g9_; }; // class CartesianProductHolder9 template class CartesianProductHolder10 { public: CartesianProductHolder10(const Generator1& g1, const Generator2& g2, const Generator3& g3, const Generator4& g4, const Generator5& g5, const Generator6& g6, const Generator7& g7, const Generator8& g8, const Generator9& g9, const Generator10& g10) : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), g8_(g8), g9_(g9), g10_(g10) {} template operator ParamGenerator< ::std::tr1::tuple >() const { return ParamGenerator< ::std::tr1::tuple >( new CartesianProductGenerator10( static_cast >(g1_), static_cast >(g2_), static_cast >(g3_), static_cast >(g4_), static_cast >(g5_), static_cast >(g6_), static_cast >(g7_), static_cast >(g8_), static_cast >(g9_), static_cast >(g10_))); } private: // No implementation - assignment is unsupported. void operator=(const CartesianProductHolder10& other); const Generator1 g1_; const Generator2 g2_; const Generator3 g3_; const Generator4 g4_; const Generator5 g5_; const Generator6 g6_; const Generator7 g7_; const Generator8 g8_; const Generator9 g9_; const Generator10 g10_; }; // class CartesianProductHolder10 # endif // GTEST_HAS_COMBINE } // namespace internal } // namespace testing #endif // GTEST_HAS_PARAM_TEST #endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_ dlt-daemon-2.18.4/gtest-1.7.0/include/gtest/internal/gtest-param-util-generated.h.pump000066400000000000000000000223101353342203500302700ustar00rootroot00000000000000$$ -*- mode: c++; -*- $var n = 50 $$ Maximum length of Values arguments we want to support. $var maxtuple = 10 $$ Maximum number of Combine arguments we want to support. // Copyright 2008 Google Inc. // All Rights Reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: vladl@google.com (Vlad Losev) // Type and function utilities for implementing parameterized tests. // This file is generated by a SCRIPT. DO NOT EDIT BY HAND! // // Currently Google Test supports at most $n arguments in Values, // and at most $maxtuple arguments in Combine. Please contact // googletestframework@googlegroups.com if you need more. // Please note that the number of arguments to Combine is limited // by the maximum arity of the implementation of tr1::tuple which is // currently set at $maxtuple. #ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_ #define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_ // scripts/fuse_gtest.py depends on gtest's own header being #included // *unconditionally*. Therefore these #includes cannot be moved // inside #if GTEST_HAS_PARAM_TEST. #include "gtest/internal/gtest-param-util.h" #include "gtest/internal/gtest-port.h" #if GTEST_HAS_PARAM_TEST namespace testing { // Forward declarations of ValuesIn(), which is implemented in // include/gtest/gtest-param-test.h. template internal::ParamGenerator< typename ::testing::internal::IteratorTraits::value_type> ValuesIn(ForwardIterator begin, ForwardIterator end); template internal::ParamGenerator ValuesIn(const T (&array)[N]); template internal::ParamGenerator ValuesIn( const Container& container); 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 $for i [[ $range j 1..i template <$for j, [[typename T$j]]> class ValueArray$i { public: ValueArray$i($for j, [[T$j v$j]]) : $for j, [[v$(j)_(v$j)]] {} template operator ParamGenerator() const { const T array[] = {$for j, [[static_cast(v$(j)_)]]}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray$i& other); $for j [[ const T$j v$(j)_; ]] }; ]] # if GTEST_HAS_COMBINE // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. // // Generates values from the Cartesian product of values produced // by the argument generators. // $range i 2..maxtuple $for i [[ $range j 1..i $range k 2..i template <$for j, [[typename T$j]]> class CartesianProductGenerator$i : public ParamGeneratorInterface< ::std::tr1::tuple<$for j, [[T$j]]> > { public: typedef ::std::tr1::tuple<$for j, [[T$j]]> ParamType; CartesianProductGenerator$i($for j, [[const ParamGenerator& g$j]]) : $for j, [[g$(j)_(g$j)]] {} virtual ~CartesianProductGenerator$i() {} virtual ParamIteratorInterface* Begin() const { return new Iterator(this, $for j, [[g$(j)_, g$(j)_.begin()]]); } virtual ParamIteratorInterface* End() const { return new Iterator(this, $for j, [[g$(j)_, g$(j)_.end()]]); } private: class Iterator : public ParamIteratorInterface { public: Iterator(const ParamGeneratorInterface* base, $for j, [[ const ParamGenerator& g$j, const typename ParamGenerator::iterator& current$(j)]]) : base_(base), $for j, [[ begin$(j)_(g$j.begin()), end$(j)_(g$j.end()), current$(j)_(current$j) ]] { ComputeCurrentValue(); } virtual ~Iterator() {} virtual const ParamGeneratorInterface* BaseGenerator() const { return base_; } // Advance should not be called on beyond-of-range iterators // so no component iterators must be beyond end of range, either. virtual void Advance() { assert(!AtEnd()); ++current$(i)_; $for k [[ if (current$(i+2-k)_ == end$(i+2-k)_) { current$(i+2-k)_ = begin$(i+2-k)_; ++current$(i+2-k-1)_; } ]] ComputeCurrentValue(); } virtual ParamIteratorInterface* Clone() const { return new Iterator(*this); } virtual const ParamType* Current() const { return ¤t_value_; } virtual bool Equals(const ParamIteratorInterface& other) const { // Having the same base generator guarantees that the other // iterator is of the same type and we can downcast. GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) << "The program attempted to compare iterators " << "from different generators." << std::endl; const Iterator* typed_other = CheckedDowncastToActualType(&other); // We must report iterators equal if they both point beyond their // respective ranges. That can happen in a variety of fashions, // so we have to consult AtEnd(). return (AtEnd() && typed_other->AtEnd()) || ($for j && [[ current$(j)_ == typed_other->current$(j)_ ]]); } private: Iterator(const Iterator& other) : base_(other.base_), $for j, [[ begin$(j)_(other.begin$(j)_), end$(j)_(other.end$(j)_), current$(j)_(other.current$(j)_) ]] { ComputeCurrentValue(); } void ComputeCurrentValue() { if (!AtEnd()) current_value_ = ParamType($for j, [[*current$(j)_]]); } bool AtEnd() const { // We must report iterator past the end of the range when either of the // component iterators has reached the end of its range. return $for j || [[ current$(j)_ == end$(j)_ ]]; } // No implementation - assignment is unsupported. void operator=(const Iterator& other); const ParamGeneratorInterface* const base_; // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. // current[i]_ is the actual traversing iterator. $for j [[ const typename ParamGenerator::iterator begin$(j)_; const typename ParamGenerator::iterator end$(j)_; typename ParamGenerator::iterator current$(j)_; ]] ParamType current_value_; }; // class CartesianProductGenerator$i::Iterator // No implementation - assignment is unsupported. void operator=(const CartesianProductGenerator$i& other); $for j [[ const ParamGenerator g$(j)_; ]] }; // class CartesianProductGenerator$i ]] // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. // // Helper classes providing Combine() with polymorphic features. They allow // casting CartesianProductGeneratorN to ParamGenerator if T is // convertible to U. // $range i 2..maxtuple $for i [[ $range j 1..i template <$for j, [[class Generator$j]]> class CartesianProductHolder$i { public: CartesianProductHolder$i($for j, [[const Generator$j& g$j]]) : $for j, [[g$(j)_(g$j)]] {} template <$for j, [[typename T$j]]> operator ParamGenerator< ::std::tr1::tuple<$for j, [[T$j]]> >() const { return ParamGenerator< ::std::tr1::tuple<$for j, [[T$j]]> >( new CartesianProductGenerator$i<$for j, [[T$j]]>( $for j,[[ static_cast >(g$(j)_) ]])); } private: // No implementation - assignment is unsupported. void operator=(const CartesianProductHolder$i& other); $for j [[ const Generator$j g$(j)_; ]] }; // class CartesianProductHolder$i ]] # endif // GTEST_HAS_COMBINE } // namespace internal } // namespace testing #endif // GTEST_HAS_PARAM_TEST #endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_ dlt-daemon-2.18.4/gtest-1.7.0/include/gtest/internal/gtest-param-util.h000066400000000000000000000571771353342203500253770ustar00rootroot00000000000000// Copyright 2008 Google Inc. // All Rights Reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: vladl@google.com (Vlad Losev) // Type and function utilities for implementing parameterized tests. #ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_ #define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_ #include #include #include // scripts/fuse_gtest.py depends on gtest's own header being #included // *unconditionally*. Therefore these #includes cannot be moved // inside #if GTEST_HAS_PARAM_TEST. #include "gtest/internal/gtest-internal.h" #include "gtest/internal/gtest-linked_ptr.h" #include "gtest/internal/gtest-port.h" #include "gtest/gtest-printers.h" #if GTEST_HAS_PARAM_TEST namespace testing { namespace internal { // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. // // Outputs a message explaining invalid registration of different // fixture class for the same test case. This may happen when // TEST_P macro is used to define two tests with the same name // but in different namespaces. GTEST_API_ void ReportInvalidTestCaseType(const char* test_case_name, const char* file, int line); template class ParamGeneratorInterface; template class ParamGenerator; // Interface for iterating over elements provided by an implementation // of ParamGeneratorInterface. template class ParamIteratorInterface { public: virtual ~ParamIteratorInterface() {} // A pointer to the base generator instance. // Used only for the purposes of iterator comparison // to make sure that two iterators belong to the same generator. virtual const ParamGeneratorInterface* BaseGenerator() const = 0; // Advances iterator to point to the next element // provided by the generator. The caller is responsible // for not calling Advance() on an iterator equal to // BaseGenerator()->End(). virtual void Advance() = 0; // Clones the iterator object. Used for implementing copy semantics // of ParamIterator. virtual ParamIteratorInterface* Clone() const = 0; // Dereferences the current iterator and provides (read-only) access // to the pointed value. It is the caller's responsibility not to call // Current() on an iterator equal to BaseGenerator()->End(). // Used for implementing ParamGenerator::operator*(). virtual const T* Current() const = 0; // Determines whether the given iterator and other point to the same // element in the sequence generated by the generator. // Used for implementing ParamGenerator::operator==(). virtual bool Equals(const ParamIteratorInterface& other) const = 0; }; // Class iterating over elements provided by an implementation of // ParamGeneratorInterface. It wraps ParamIteratorInterface // and implements the const forward iterator concept. template class ParamIterator { public: typedef T value_type; typedef const T& reference; typedef ptrdiff_t difference_type; // ParamIterator assumes ownership of the impl_ pointer. ParamIterator(const ParamIterator& other) : impl_(other.impl_->Clone()) {} ParamIterator& operator=(const ParamIterator& other) { if (this != &other) impl_.reset(other.impl_->Clone()); return *this; } const T& operator*() const { return *impl_->Current(); } const T* operator->() const { return impl_->Current(); } // Prefix version of operator++. ParamIterator& operator++() { impl_->Advance(); return *this; } // Postfix version of operator++. ParamIterator operator++(int /*unused*/) { ParamIteratorInterface* clone = impl_->Clone(); impl_->Advance(); return ParamIterator(clone); } bool operator==(const ParamIterator& other) const { return impl_.get() == other.impl_.get() || impl_->Equals(*other.impl_); } bool operator!=(const ParamIterator& other) const { return !(*this == other); } private: friend class ParamGenerator; explicit ParamIterator(ParamIteratorInterface* impl) : impl_(impl) {} scoped_ptr > impl_; }; // ParamGeneratorInterface is the binary interface to access generators // defined in other translation units. template class ParamGeneratorInterface { public: typedef T ParamType; virtual ~ParamGeneratorInterface() {} // Generator interface definition virtual ParamIteratorInterface* Begin() const = 0; virtual ParamIteratorInterface* End() const = 0; }; // Wraps ParamGeneratorInterface and provides general generator syntax // compatible with the STL Container concept. // This class implements copy initialization semantics and the contained // ParamGeneratorInterface instance is shared among all copies // of the original object. This is possible because that instance is immutable. template class ParamGenerator { public: typedef ParamIterator iterator; explicit ParamGenerator(ParamGeneratorInterface* impl) : impl_(impl) {} ParamGenerator(const ParamGenerator& other) : impl_(other.impl_) {} ParamGenerator& operator=(const ParamGenerator& other) { impl_ = other.impl_; return *this; } iterator begin() const { return iterator(impl_->Begin()); } iterator end() const { return iterator(impl_->End()); } private: linked_ptr > impl_; }; // Generates values from a range of two comparable values. Can be used to // generate sequences of user-defined types that implement operator+() and // operator<(). // This class is used in the Range() function. template class RangeGenerator : public ParamGeneratorInterface { public: RangeGenerator(T begin, T end, IncrementT step) : begin_(begin), end_(end), step_(step), end_index_(CalculateEndIndex(begin, end, step)) {} virtual ~RangeGenerator() {} virtual ParamIteratorInterface* Begin() const { return new Iterator(this, begin_, 0, step_); } virtual ParamIteratorInterface* End() const { return new Iterator(this, end_, end_index_, step_); } private: class Iterator : public ParamIteratorInterface { public: Iterator(const ParamGeneratorInterface* base, T value, int index, IncrementT step) : base_(base), value_(value), index_(index), step_(step) {} virtual ~Iterator() {} virtual const ParamGeneratorInterface* BaseGenerator() const { return base_; } virtual void Advance() { value_ = value_ + step_; index_++; } virtual ParamIteratorInterface* Clone() const { return new Iterator(*this); } virtual const T* Current() const { return &value_; } virtual bool Equals(const ParamIteratorInterface& other) const { // Having the same base generator guarantees that the other // iterator is of the same type and we can downcast. GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) << "The program attempted to compare iterators " << "from different generators." << std::endl; const int other_index = CheckedDowncastToActualType(&other)->index_; return index_ == other_index; } private: Iterator(const Iterator& other) : ParamIteratorInterface(), base_(other.base_), value_(other.value_), index_(other.index_), step_(other.step_) {} // No implementation - assignment is unsupported. void operator=(const Iterator& other); const ParamGeneratorInterface* const base_; T value_; int index_; const IncrementT step_; }; // class RangeGenerator::Iterator static int CalculateEndIndex(const T& begin, const T& end, const IncrementT& step) { int end_index = 0; for (T i = begin; i < end; i = i + step) end_index++; return end_index; } // No implementation - assignment is unsupported. void operator=(const RangeGenerator& other); const T begin_; const T end_; const IncrementT step_; // The index for the end() iterator. All the elements in the generated // sequence are indexed (0-based) to aid iterator comparison. const int end_index_; }; // class RangeGenerator // Generates values from a pair of STL-style iterators. Used in the // ValuesIn() function. The elements are copied from the source range // since the source can be located on the stack, and the generator // is likely to persist beyond that stack frame. template class ValuesInIteratorRangeGenerator : public ParamGeneratorInterface { public: template ValuesInIteratorRangeGenerator(ForwardIterator begin, ForwardIterator end) : container_(begin, end) {} virtual ~ValuesInIteratorRangeGenerator() {} virtual ParamIteratorInterface* Begin() const { return new Iterator(this, container_.begin()); } virtual ParamIteratorInterface* End() const { return new Iterator(this, container_.end()); } private: typedef typename ::std::vector ContainerType; class Iterator : public ParamIteratorInterface { public: Iterator(const ParamGeneratorInterface* base, typename ContainerType::const_iterator iterator) : base_(base), iterator_(iterator) {} virtual ~Iterator() {} virtual const ParamGeneratorInterface* BaseGenerator() const { return base_; } virtual void Advance() { ++iterator_; value_.reset(); } virtual ParamIteratorInterface* Clone() const { return new Iterator(*this); } // We need to use cached value referenced by iterator_ because *iterator_ // can return a temporary object (and of type other then T), so just // having "return &*iterator_;" doesn't work. // value_ is updated here and not in Advance() because Advance() // can advance iterator_ beyond the end of the range, and we cannot // detect that fact. The client code, on the other hand, is // responsible for not calling Current() on an out-of-range iterator. virtual const T* Current() const { if (value_.get() == NULL) value_.reset(new T(*iterator_)); return value_.get(); } virtual bool Equals(const ParamIteratorInterface& other) const { // Having the same base generator guarantees that the other // iterator is of the same type and we can downcast. GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) << "The program attempted to compare iterators " << "from different generators." << std::endl; return iterator_ == CheckedDowncastToActualType(&other)->iterator_; } private: Iterator(const Iterator& other) // The explicit constructor call suppresses a false warning // emitted by gcc when supplied with the -Wextra option. : ParamIteratorInterface(), base_(other.base_), iterator_(other.iterator_) {} const ParamGeneratorInterface* const base_; typename ContainerType::const_iterator iterator_; // A cached value of *iterator_. We keep it here to allow access by // pointer in the wrapping iterator's operator->(). // value_ needs to be mutable to be accessed in Current(). // Use of scoped_ptr helps manage cached value's lifetime, // which is bound by the lifespan of the iterator itself. mutable scoped_ptr value_; }; // class ValuesInIteratorRangeGenerator::Iterator // No implementation - assignment is unsupported. void operator=(const ValuesInIteratorRangeGenerator& other); const ContainerType container_; }; // class ValuesInIteratorRangeGenerator // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. // // Stores a parameter value and later creates tests parameterized with that // value. template class ParameterizedTestFactory : public TestFactoryBase { public: typedef typename TestClass::ParamType ParamType; explicit ParameterizedTestFactory(ParamType parameter) : parameter_(parameter) {} virtual Test* CreateTest() { TestClass::SetParam(¶meter_); return new TestClass(); } private: const ParamType parameter_; GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestFactory); }; // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. // // TestMetaFactoryBase is a base class for meta-factories that create // test factories for passing into MakeAndRegisterTestInfo function. template class TestMetaFactoryBase { public: virtual ~TestMetaFactoryBase() {} virtual TestFactoryBase* CreateTestFactory(ParamType parameter) = 0; }; // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. // // TestMetaFactory creates test factories for passing into // MakeAndRegisterTestInfo function. Since MakeAndRegisterTestInfo receives // ownership of test factory pointer, same factory object cannot be passed // into that method twice. But ParameterizedTestCaseInfo is going to call // it for each Test/Parameter value combination. Thus it needs meta factory // creator class. template class TestMetaFactory : public TestMetaFactoryBase { public: typedef typename TestCase::ParamType ParamType; TestMetaFactory() {} virtual TestFactoryBase* CreateTestFactory(ParamType parameter) { return new ParameterizedTestFactory(parameter); } private: GTEST_DISALLOW_COPY_AND_ASSIGN_(TestMetaFactory); }; // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. // // ParameterizedTestCaseInfoBase is a generic interface // to ParameterizedTestCaseInfo classes. ParameterizedTestCaseInfoBase // accumulates test information provided by TEST_P macro invocations // and generators provided by INSTANTIATE_TEST_CASE_P macro invocations // and uses that information to register all resulting test instances // in RegisterTests method. The ParameterizeTestCaseRegistry class holds // a collection of pointers to the ParameterizedTestCaseInfo objects // and calls RegisterTests() on each of them when asked. class ParameterizedTestCaseInfoBase { public: virtual ~ParameterizedTestCaseInfoBase() {} // Base part of test case name for display purposes. virtual const string& GetTestCaseName() const = 0; // Test case id to verify identity. virtual TypeId GetTestCaseTypeId() const = 0; // UnitTest class invokes this method to register tests in this // test case right before running them in RUN_ALL_TESTS macro. // This method should not be called more then once on any single // instance of a ParameterizedTestCaseInfoBase derived class. virtual void RegisterTests() = 0; protected: ParameterizedTestCaseInfoBase() {} private: GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestCaseInfoBase); }; // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. // // ParameterizedTestCaseInfo accumulates tests obtained from TEST_P // macro invocations for a particular test case and generators // obtained from INSTANTIATE_TEST_CASE_P macro invocations for that // test case. It registers tests with all values generated by all // generators when asked. template class ParameterizedTestCaseInfo : public ParameterizedTestCaseInfoBase { public: // ParamType and GeneratorCreationFunc are private types but are required // for declarations of public methods AddTestPattern() and // AddTestCaseInstantiation(). typedef typename TestCase::ParamType ParamType; // A function that returns an instance of appropriate generator type. typedef ParamGenerator(GeneratorCreationFunc)(); explicit ParameterizedTestCaseInfo(const char* name) : test_case_name_(name) {} // Test case base name for display purposes. virtual const string& GetTestCaseName() const { return test_case_name_; } // Test case id to verify identity. virtual TypeId GetTestCaseTypeId() const { return GetTypeId(); } // TEST_P macro uses AddTestPattern() to record information // about a single test in a LocalTestInfo structure. // test_case_name is the base name of the test case (without invocation // prefix). test_base_name is the name of an individual test without // parameter index. For the test SequenceA/FooTest.DoBar/1 FooTest is // test case base name and DoBar is test base name. void AddTestPattern(const char* test_case_name, const char* test_base_name, TestMetaFactoryBase* meta_factory) { tests_.push_back(linked_ptr(new TestInfo(test_case_name, test_base_name, meta_factory))); } // INSTANTIATE_TEST_CASE_P macro uses AddGenerator() to record information // about a generator. int AddTestCaseInstantiation(const string& instantiation_name, GeneratorCreationFunc* func, const char* /* file */, int /* line */) { instantiations_.push_back(::std::make_pair(instantiation_name, func)); return 0; // Return value used only to run this method in namespace scope. } // UnitTest class invokes this method to register tests in this test case // test cases right before running tests in RUN_ALL_TESTS macro. // This method should not be called more then once on any single // instance of a ParameterizedTestCaseInfoBase derived class. // UnitTest has a guard to prevent from calling this method more then once. virtual void RegisterTests() { for (typename TestInfoContainer::iterator test_it = tests_.begin(); test_it != tests_.end(); ++test_it) { linked_ptr test_info = *test_it; for (typename InstantiationContainer::iterator gen_it = instantiations_.begin(); gen_it != instantiations_.end(); ++gen_it) { const string& instantiation_name = gen_it->first; ParamGenerator generator((*gen_it->second)()); string test_case_name; if ( !instantiation_name.empty() ) test_case_name = instantiation_name + "/"; test_case_name += test_info->test_case_base_name; int i = 0; for (typename ParamGenerator::iterator param_it = generator.begin(); param_it != generator.end(); ++param_it, ++i) { Message test_name_stream; test_name_stream << test_info->test_base_name << "/" << i; MakeAndRegisterTestInfo( test_case_name.c_str(), test_name_stream.GetString().c_str(), NULL, // No type parameter. PrintToString(*param_it).c_str(), GetTestCaseTypeId(), TestCase::SetUpTestCase, TestCase::TearDownTestCase, test_info->test_meta_factory->CreateTestFactory(*param_it)); } // for param_it } // for gen_it } // for test_it } // RegisterTests private: // LocalTestInfo structure keeps information about a single test registered // with TEST_P macro. struct TestInfo { TestInfo(const char* a_test_case_base_name, const char* a_test_base_name, TestMetaFactoryBase* a_test_meta_factory) : test_case_base_name(a_test_case_base_name), test_base_name(a_test_base_name), test_meta_factory(a_test_meta_factory) {} const string test_case_base_name; const string test_base_name; const scoped_ptr > test_meta_factory; }; typedef ::std::vector > TestInfoContainer; // Keeps pairs of // received from INSTANTIATE_TEST_CASE_P macros. typedef ::std::vector > InstantiationContainer; const string test_case_name_; TestInfoContainer tests_; InstantiationContainer instantiations_; GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestCaseInfo); }; // class ParameterizedTestCaseInfo // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. // // ParameterizedTestCaseRegistry contains a map of ParameterizedTestCaseInfoBase // classes accessed by test case names. TEST_P and INSTANTIATE_TEST_CASE_P // macros use it to locate their corresponding ParameterizedTestCaseInfo // descriptors. class ParameterizedTestCaseRegistry { public: ParameterizedTestCaseRegistry() {} ~ParameterizedTestCaseRegistry() { for (TestCaseInfoContainer::iterator it = test_case_infos_.begin(); it != test_case_infos_.end(); ++it) { delete *it; } } // Looks up or creates and returns a structure containing information about // tests and instantiations of a particular test case. template ParameterizedTestCaseInfo* GetTestCasePatternHolder( const char* test_case_name, const char* file, int line) { ParameterizedTestCaseInfo* typed_test_info = NULL; for (TestCaseInfoContainer::iterator it = test_case_infos_.begin(); it != test_case_infos_.end(); ++it) { if ((*it)->GetTestCaseName() == test_case_name) { if ((*it)->GetTestCaseTypeId() != GetTypeId()) { // Complain about incorrect usage of Google Test facilities // and terminate the program since we cannot guaranty correct // test case setup and tear-down in this case. ReportInvalidTestCaseType(test_case_name, file, line); posix::Abort(); } else { // At this point we are sure that the object we found is of the same // type we are looking for, so we downcast it to that type // without further checks. typed_test_info = CheckedDowncastToActualType< ParameterizedTestCaseInfo >(*it); } break; } } if (typed_test_info == NULL) { typed_test_info = new ParameterizedTestCaseInfo(test_case_name); test_case_infos_.push_back(typed_test_info); } return typed_test_info; } void RegisterTests() { for (TestCaseInfoContainer::iterator it = test_case_infos_.begin(); it != test_case_infos_.end(); ++it) { (*it)->RegisterTests(); } } private: typedef ::std::vector TestCaseInfoContainer; TestCaseInfoContainer test_case_infos_; GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestCaseRegistry); }; } // namespace internal } // namespace testing #endif // GTEST_HAS_PARAM_TEST #endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_ dlt-daemon-2.18.4/gtest-1.7.0/include/gtest/internal/gtest-port.h000066400000000000000000002062741353342203500243020ustar00rootroot00000000000000// Copyright 2005, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Authors: wan@google.com (Zhanyong Wan) // // Low-level types and utilities for porting Google Test to various // platforms. They are subject to change without notice. DO NOT USE // THEM IN USER CODE. // // This file is fundamental to Google Test. All other Google Test source // files are expected to #include this. Therefore, it cannot #include // any other Google Test header. #ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_ #define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_ // The user can define the following macros in the build script to // control Google Test's behavior. If the user doesn't define a macro // in this list, Google Test will define it. // // GTEST_HAS_CLONE - Define it to 1/0 to indicate that clone(2) // is/isn't available. // GTEST_HAS_EXCEPTIONS - Define it to 1/0 to indicate that exceptions // are enabled. // GTEST_HAS_GLOBAL_STRING - Define it to 1/0 to indicate that ::string // is/isn't available (some systems define // ::string, which is different to std::string). // GTEST_HAS_GLOBAL_WSTRING - Define it to 1/0 to indicate that ::string // is/isn't available (some systems define // ::wstring, which is different to std::wstring). // GTEST_HAS_POSIX_RE - Define it to 1/0 to indicate that POSIX regular // expressions are/aren't available. // GTEST_HAS_PTHREAD - Define it to 1/0 to indicate that // is/isn't available. // GTEST_HAS_RTTI - Define it to 1/0 to indicate that RTTI is/isn't // enabled. // GTEST_HAS_STD_WSTRING - Define it to 1/0 to indicate that // std::wstring does/doesn't work (Google Test can // be used where std::wstring is unavailable). // GTEST_HAS_TR1_TUPLE - Define it to 1/0 to indicate tr1::tuple // is/isn't available. // GTEST_HAS_SEH - Define it to 1/0 to indicate whether the // compiler supports Microsoft's "Structured // Exception Handling". // GTEST_HAS_STREAM_REDIRECTION // - Define it to 1/0 to indicate whether the // platform supports I/O stream redirection using // dup() and dup2(). // GTEST_USE_OWN_TR1_TUPLE - Define it to 1/0 to indicate whether Google // Test's own tr1 tuple implementation should be // used. Unused when the user sets // GTEST_HAS_TR1_TUPLE to 0. // GTEST_LANG_CXX11 - Define it to 1/0 to indicate that Google Test // is building in C++11/C++98 mode. // GTEST_LINKED_AS_SHARED_LIBRARY // - Define to 1 when compiling tests that use // Google Test as a shared library (known as // DLL on Windows). // GTEST_CREATE_SHARED_LIBRARY // - Define to 1 when compiling Google Test itself // as a shared library. // This header defines the following utilities: // // Macros indicating the current platform (defined to 1 if compiled on // the given platform; otherwise undefined): // GTEST_OS_AIX - IBM AIX // GTEST_OS_CYGWIN - Cygwin // GTEST_OS_HPUX - HP-UX // GTEST_OS_LINUX - Linux // GTEST_OS_LINUX_ANDROID - Google Android // GTEST_OS_MAC - Mac OS X // GTEST_OS_IOS - iOS // GTEST_OS_IOS_SIMULATOR - iOS simulator // GTEST_OS_NACL - Google Native Client (NaCl) // GTEST_OS_OPENBSD - OpenBSD // GTEST_OS_QNX - QNX // GTEST_OS_SOLARIS - Sun Solaris // GTEST_OS_SYMBIAN - Symbian // GTEST_OS_WINDOWS - Windows (Desktop, MinGW, or Mobile) // GTEST_OS_WINDOWS_DESKTOP - Windows Desktop // GTEST_OS_WINDOWS_MINGW - MinGW // GTEST_OS_WINDOWS_MOBILE - Windows Mobile // GTEST_OS_ZOS - z/OS // // Among the platforms, Cygwin, Linux, Max OS X, and Windows have the // most stable support. Since core members of the Google Test project // don't have access to other platforms, support for them may be less // stable. If you notice any problems on your platform, please notify // googletestframework@googlegroups.com (patches for fixing them are // even more welcome!). // // Note that it is possible that none of the GTEST_OS_* macros are defined. // // Macros indicating available Google Test features (defined to 1 if // the corresponding feature is supported; otherwise undefined): // GTEST_HAS_COMBINE - the Combine() function (for value-parameterized // tests) // GTEST_HAS_DEATH_TEST - death tests // GTEST_HAS_PARAM_TEST - value-parameterized tests // GTEST_HAS_TYPED_TEST - typed tests // GTEST_HAS_TYPED_TEST_P - type-parameterized tests // GTEST_USES_POSIX_RE - enhanced POSIX regex is used. Do not confuse with // GTEST_HAS_POSIX_RE (see above) which users can // define themselves. // GTEST_USES_SIMPLE_RE - our own simple regex is used; // the above two are mutually exclusive. // GTEST_CAN_COMPARE_NULL - accepts untyped NULL in EXPECT_EQ(). // // Macros for basic C++ coding: // GTEST_AMBIGUOUS_ELSE_BLOCKER_ - for disabling a gcc warning. // GTEST_ATTRIBUTE_UNUSED_ - declares that a class' instances or a // variable don't have to be used. // GTEST_DISALLOW_ASSIGN_ - disables operator=. // GTEST_DISALLOW_COPY_AND_ASSIGN_ - disables copy ctor and operator=. // GTEST_MUST_USE_RESULT_ - declares that a function's result must be used. // // Synchronization: // Mutex, MutexLock, ThreadLocal, GetThreadCount() // - synchronization primitives. // GTEST_IS_THREADSAFE - defined to 1 to indicate that the above // synchronization primitives have real implementations // and Google Test is thread-safe; or 0 otherwise. // // Template meta programming: // is_pointer - as in TR1; needed on Symbian and IBM XL C/C++ only. // IteratorTraits - partial implementation of std::iterator_traits, which // is not available in libCstd when compiled with Sun C++. // // Smart pointers: // scoped_ptr - as in TR2. // // Regular expressions: // RE - a simple regular expression class using the POSIX // Extended Regular Expression syntax on UNIX-like // platforms, or a reduced regular exception syntax on // other platforms, including Windows. // // Logging: // GTEST_LOG_() - logs messages at the specified severity level. // LogToStderr() - directs all log messages to stderr. // FlushInfoLog() - flushes informational log messages. // // Stdout and stderr capturing: // CaptureStdout() - starts capturing stdout. // GetCapturedStdout() - stops capturing stdout and returns the captured // string. // CaptureStderr() - starts capturing stderr. // GetCapturedStderr() - stops capturing stderr and returns the captured // string. // // Integer types: // TypeWithSize - maps an integer to a int type. // Int32, UInt32, Int64, UInt64, TimeInMillis // - integers of known sizes. // BiggestInt - the biggest signed integer type. // // Command-line utilities: // GTEST_FLAG() - references a flag. // GTEST_DECLARE_*() - declares a flag. // GTEST_DEFINE_*() - defines a flag. // GetInjectableArgvs() - returns the command line as a vector of strings. // // Environment variable utilities: // GetEnv() - gets the value of an environment variable. // BoolFromGTestEnv() - parses a bool environment variable. // Int32FromGTestEnv() - parses an Int32 environment variable. // StringFromGTestEnv() - parses a string environment variable. #include // for isspace, etc #include // for ptrdiff_t #include #include #include #ifndef _WIN32_WCE # include # include #endif // !_WIN32_WCE #if defined __APPLE__ # include # include #endif #include // NOLINT #include // NOLINT #include // NOLINT #define GTEST_DEV_EMAIL_ "googletestframework@@googlegroups.com" #define GTEST_FLAG_PREFIX_ "gtest_" #define GTEST_FLAG_PREFIX_DASH_ "gtest-" #define GTEST_FLAG_PREFIX_UPPER_ "GTEST_" #define GTEST_NAME_ "Google Test" #define GTEST_PROJECT_URL_ "http://code.google.com/p/googletest/" // Determines the version of gcc that is used to compile this. #ifdef __GNUC__ // 40302 means version 4.3.2. # define GTEST_GCC_VER_ \ (__GNUC__*10000 + __GNUC_MINOR__*100 + __GNUC_PATCHLEVEL__) #endif // __GNUC__ // Determines the platform on which Google Test is compiled. #ifdef __CYGWIN__ # define GTEST_OS_CYGWIN 1 #elif defined __SYMBIAN32__ # define GTEST_OS_SYMBIAN 1 #elif defined _WIN32 # define GTEST_OS_WINDOWS 1 # ifdef _WIN32_WCE # define GTEST_OS_WINDOWS_MOBILE 1 # elif defined(__MINGW__) || defined(__MINGW32__) # define GTEST_OS_WINDOWS_MINGW 1 # else # define GTEST_OS_WINDOWS_DESKTOP 1 # endif // _WIN32_WCE #elif defined __APPLE__ # define GTEST_OS_MAC 1 # 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__ #ifndef GTEST_LANG_CXX11 // gcc and clang define __GXX_EXPERIMENTAL_CXX0X__ when // -std={c,gnu}++{0x,11} is passed. The C++11 standard specifies a // value for __cplusplus, and recent versions of clang, gcc, and // probably other compilers set that too in C++11 mode. # if __GXX_EXPERIMENTAL_CXX0X__ || __cplusplus >= 201103L // Compiling in at least C++11 mode. # define GTEST_LANG_CXX11 1 # else # define GTEST_LANG_CXX11 0 # endif #endif // Brings in definitions for functions used in the testing::internal::posix // namespace (read, write, close, chdir, isatty, stat). We do not currently // use them on Windows Mobile. #if !GTEST_OS_WINDOWS // This assumes that non-Windows OSes provide unistd.h. For OSes where this // is not the case, we need to include headers that provide the functions // mentioned above. # include # include #elif !GTEST_OS_WINDOWS_MOBILE # include # include #endif #if GTEST_OS_LINUX_ANDROID // Used to define __ANDROID_API__ matching the target NDK API level. # include // NOLINT #endif // Defines this to true iff Google Test can use POSIX regular expressions. #ifndef GTEST_HAS_POSIX_RE # if GTEST_OS_LINUX_ANDROID // On Android, is only available starting with Gingerbread. # define GTEST_HAS_POSIX_RE (__ANDROID_API__ >= 9) # else # define GTEST_HAS_POSIX_RE (!GTEST_OS_WINDOWS) # endif #endif #if 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 // included , which is guaranteed to define size_t through // . # include // NOLINT # define GTEST_USES_POSIX_RE 1 #elif GTEST_OS_WINDOWS // is not available on Windows. Use our own simple regex // implementation instead. # define GTEST_USES_SIMPLE_RE 1 #else // may not be available on this platform. Use our own // simple regex implementation instead. # define GTEST_USES_SIMPLE_RE 1 #endif // GTEST_HAS_POSIX_RE #ifndef GTEST_HAS_EXCEPTIONS // The user didn't tell us whether exceptions are enabled, so we need // to figure it out. # if defined(_MSC_VER) || defined(__BORLANDC__) // MSVC's and C++Builder's implementations of the STL use the _HAS_EXCEPTIONS // macro to enable exceptions, so we'll do the same. // Assumes that exceptions are enabled by default. # ifndef _HAS_EXCEPTIONS # define _HAS_EXCEPTIONS 1 # endif // _HAS_EXCEPTIONS # define GTEST_HAS_EXCEPTIONS _HAS_EXCEPTIONS # elif defined(__GNUC__) && __EXCEPTIONS // gcc defines __EXCEPTIONS to 1 iff exceptions are enabled. # define GTEST_HAS_EXCEPTIONS 1 # elif defined(__SUNPRO_CC) // Sun Pro CC supports exceptions. However, there is no compile-time way of // detecting whether they are enabled or not. Therefore, we assume that // they are enabled unless the user tells us otherwise. # define GTEST_HAS_EXCEPTIONS 1 # elif defined(__IBMCPP__) && __EXCEPTIONS // xlC defines __EXCEPTIONS to 1 iff exceptions are enabled. # define GTEST_HAS_EXCEPTIONS 1 # elif defined(__HP_aCC) // Exception handling is in effect by default in HP aCC compiler. It has to // be turned of by +noeh compiler option if desired. # define GTEST_HAS_EXCEPTIONS 1 # else // For other compilers, we assume exceptions are disabled to be // conservative. # define GTEST_HAS_EXCEPTIONS 0 # endif // defined(_MSC_VER) || defined(__BORLANDC__) #endif // GTEST_HAS_EXCEPTIONS #if !defined(GTEST_HAS_STD_STRING) // Even though we don't use this macro any longer, we keep it in case // some clients still depend on it. # define GTEST_HAS_STD_STRING 1 #elif !GTEST_HAS_STD_STRING // The user told us that ::std::string isn't available. # error "Google Test cannot be used where ::std::string isn't available." #endif // !defined(GTEST_HAS_STD_STRING) #ifndef GTEST_HAS_GLOBAL_STRING // The user didn't tell us whether ::string is available, so we need // to figure it out. # define GTEST_HAS_GLOBAL_STRING 0 #endif // GTEST_HAS_GLOBAL_STRING #ifndef GTEST_HAS_STD_WSTRING // The user didn't tell us whether ::std::wstring is available, so we need // to figure it out. // TODO(wan@google.com): uses autoconf to detect whether ::std::wstring // is available. // Cygwin 1.7 and below doesn't support ::std::wstring. // Solaris' libc++ doesn't support it either. Android has // no support for it at least as recent as Froyo (2.2). # define GTEST_HAS_STD_WSTRING \ (!(GTEST_OS_LINUX_ANDROID || GTEST_OS_CYGWIN || GTEST_OS_SOLARIS)) #endif // GTEST_HAS_STD_WSTRING #ifndef GTEST_HAS_GLOBAL_WSTRING // The user didn't tell us whether ::wstring is available, so we need // to figure it out. # define GTEST_HAS_GLOBAL_WSTRING \ (GTEST_HAS_STD_WSTRING && GTEST_HAS_GLOBAL_STRING) #endif // GTEST_HAS_GLOBAL_WSTRING // Determines whether RTTI is available. #ifndef GTEST_HAS_RTTI // The user didn't tell us whether RTTI is enabled, so we need to // figure it out. # ifdef _MSC_VER # ifdef _CPPRTTI // MSVC defines this macro iff RTTI is enabled. # define GTEST_HAS_RTTI 1 # else # define GTEST_HAS_RTTI 0 # endif // Starting with version 4.3.2, gcc defines __GXX_RTTI iff RTTI is enabled. # elif defined(__GNUC__) && (GTEST_GCC_VER_ >= 40302) # ifdef __GXX_RTTI // When building against STLport with the Android NDK and with // -frtti -fno-exceptions, the build fails at link time with undefined // references to __cxa_bad_typeid. Note sure if STL or toolchain bug, // so disable RTTI when detected. # if GTEST_OS_LINUX_ANDROID && defined(_STLPORT_MAJOR) && \ !defined(__EXCEPTIONS) # define GTEST_HAS_RTTI 0 # else # define GTEST_HAS_RTTI 1 # endif // GTEST_OS_LINUX_ANDROID && __STLPORT_MAJOR && !__EXCEPTIONS # else # define GTEST_HAS_RTTI 0 # endif // __GXX_RTTI // Clang defines __GXX_RTTI starting with version 3.0, but its manual recommends // using has_feature instead. has_feature(cxx_rtti) is supported since 2.7, the // first version with C++ support. # elif defined(__clang__) # define GTEST_HAS_RTTI __has_feature(cxx_rtti) // Starting with version 9.0 IBM Visual Age defines __RTTI_ALL__ to 1 if // both the typeid and dynamic_cast features are present. # elif defined(__IBMCPP__) && (__IBMCPP__ >= 900) # ifdef __RTTI_ALL__ # define GTEST_HAS_RTTI 1 # else # define GTEST_HAS_RTTI 0 # endif # else // For all other compilers, we assume RTTI is enabled. # define GTEST_HAS_RTTI 1 # endif // _MSC_VER #endif // GTEST_HAS_RTTI // It's this header's responsibility to #include when RTTI // is enabled. #if GTEST_HAS_RTTI # include #endif // Determines whether Google Test can use the pthreads library. #ifndef GTEST_HAS_PTHREAD // The user didn't tell us explicitly, so we assume pthreads support is // available on Linux and Mac. // // To disable threading support in Google Test, add -DGTEST_HAS_PTHREAD=0 // to your compiler flags. # define GTEST_HAS_PTHREAD (GTEST_OS_LINUX || GTEST_OS_MAC || GTEST_OS_HPUX \ || GTEST_OS_QNX) #endif // GTEST_HAS_PTHREAD #if GTEST_HAS_PTHREAD // gtest-port.h guarantees to #include when GTEST_HAS_PTHREAD is // true. # include // NOLINT // For timespec and nanosleep, used below. # include // NOLINT #endif // Determines whether Google Test can use tr1/tuple. You can define // this macro to 0 to prevent Google Test from using tuple (any // feature depending on tuple with be disabled in this mode). #ifndef GTEST_HAS_TR1_TUPLE # if GTEST_OS_LINUX_ANDROID && defined(_STLPORT_MAJOR) // STLport, provided with the Android NDK, has neither or . # define GTEST_HAS_TR1_TUPLE 0 # else // The user didn't tell us not to do it, so we assume it's OK. # define GTEST_HAS_TR1_TUPLE 1 # endif #endif // GTEST_HAS_TR1_TUPLE // Determines whether Google Test's own tr1 tuple implementation // should be used. #ifndef GTEST_USE_OWN_TR1_TUPLE // The user didn't tell us, so we need to figure it out. // We use our own TR1 tuple if we aren't sure the user has an // implementation of it already. At this time, libstdc++ 4.0.0+ and // MSVC 2010 are the only mainstream standard libraries that come // with a TR1 tuple implementation. NVIDIA's CUDA NVCC compiler // pretends to be GCC by defining __GNUC__ and friends, but cannot // compile GCC's tuple implementation. MSVC 2008 (9.0) provides TR1 // tuple in a 323 MB Feature Pack download, which we cannot assume the // user has. QNX's QCC compiler is a modified GCC but it doesn't // support TR1 tuple. libc++ only provides std::tuple, in C++11 mode, // and it can be used with some compilers that define __GNUC__. # if (defined(__GNUC__) && !defined(__CUDACC__) && (GTEST_GCC_VER_ >= 40000) \ && !GTEST_OS_QNX && !defined(_LIBCPP_VERSION)) || _MSC_VER >= 1600 # define GTEST_ENV_HAS_TR1_TUPLE_ 1 # endif // C++11 specifies that provides std::tuple. 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) # define GTEST_ENV_HAS_STD_TUPLE_ 1 # endif # if GTEST_ENV_HAS_TR1_TUPLE_ || GTEST_ENV_HAS_STD_TUPLE_ # define GTEST_USE_OWN_TR1_TUPLE 0 # else # define GTEST_USE_OWN_TR1_TUPLE 1 # endif #endif // GTEST_USE_OWN_TR1_TUPLE // To avoid conditional compilation everywhere, we make it // gtest-port.h's responsibility to #include the header implementing // tr1/tuple. #if GTEST_HAS_TR1_TUPLE # if GTEST_USE_OWN_TR1_TUPLE # include "gtest/internal/gtest-tuple.h" # elif GTEST_ENV_HAS_STD_TUPLE_ # include // C++11 puts its tuple into the ::std namespace rather than // ::std::tr1. gtest expects tuple to live in ::std::tr1, so put it there. // This causes undefined behavior, but supported compilers react in // the way we intend. namespace std { namespace tr1 { using ::std::get; using ::std::make_tuple; using ::std::tuple; using ::std::tuple_element; using ::std::tuple_size; } } # elif GTEST_OS_SYMBIAN // On Symbian, BOOST_HAS_TR1_TUPLE causes Boost's TR1 tuple library to // use STLport's tuple implementation, which unfortunately doesn't // work as the copy of STLport distributed with Symbian is incomplete. // By making sure BOOST_HAS_TR1_TUPLE is undefined, we force Boost to // use its own tuple implementation. # ifdef BOOST_HAS_TR1_TUPLE # undef BOOST_HAS_TR1_TUPLE # endif // BOOST_HAS_TR1_TUPLE // This prevents , which defines // BOOST_HAS_TR1_TUPLE, from being #included by Boost's . # define BOOST_TR1_DETAIL_CONFIG_HPP_INCLUDED # include # elif defined(__GNUC__) && (GTEST_GCC_VER_ >= 40000) // GCC 4.0+ implements tr1/tuple in the header. This does // not conform to the TR1 spec, which requires the header to be . # if !GTEST_HAS_RTTI && GTEST_GCC_VER_ < 40302 // Until version 4.3.2, gcc has a bug that causes , // which is #included by , to not compile when RTTI is // disabled. _TR1_FUNCTIONAL is the header guard for // . Hence the following #define is a hack to prevent // from being included. # define _TR1_FUNCTIONAL 1 # include # undef _TR1_FUNCTIONAL // Allows the user to #include // if he chooses to. # else # include // NOLINT # endif // !GTEST_HAS_RTTI && GTEST_GCC_VER_ < 40302 # else // If the compiler is not GCC 4.0+, we assume the user is using a // spec-conforming TR1 implementation. # include // NOLINT # endif // GTEST_USE_OWN_TR1_TUPLE #endif // GTEST_HAS_TR1_TUPLE // Determines whether clone(2) is supported. // Usually it will only be available on Linux, excluding // Linux on the Itanium architecture. // Also see http://linux.die.net/man/2/clone. #ifndef GTEST_HAS_CLONE // The user didn't tell us, so we need to figure it out. # if GTEST_OS_LINUX && !defined(__ia64__) # if GTEST_OS_LINUX_ANDROID // On Android, clone() is only available on ARM starting with Gingerbread. # if defined(__arm__) && __ANDROID_API__ >= 9 # define GTEST_HAS_CLONE 1 # else # define GTEST_HAS_CLONE 0 # endif # else # define GTEST_HAS_CLONE 1 # endif # else # define GTEST_HAS_CLONE 0 # endif // GTEST_OS_LINUX && !defined(__ia64__) #endif // GTEST_HAS_CLONE // Determines whether to support stream redirection. This is used to test // output correctness and to implement death tests. #ifndef GTEST_HAS_STREAM_REDIRECTION // By default, we assume that stream redirection is supported on all // platforms except known mobile ones. # if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_SYMBIAN # define GTEST_HAS_STREAM_REDIRECTION 0 # else # define GTEST_HAS_STREAM_REDIRECTION 1 # endif // !GTEST_OS_WINDOWS_MOBILE && !GTEST_OS_SYMBIAN #endif // GTEST_HAS_STREAM_REDIRECTION // Determines whether to support death tests. // Google Test does not support death tests for VC 7.1 and earlier as // abort() in a VC 7.1 application compiled as GUI in debug config // pops up a dialog window that cannot be suppressed programmatically. #if (GTEST_OS_LINUX || GTEST_OS_CYGWIN || GTEST_OS_SOLARIS || \ (GTEST_OS_MAC && !GTEST_OS_IOS) || GTEST_OS_IOS_SIMULATOR || \ (GTEST_OS_WINDOWS_DESKTOP && _MSC_VER >= 1400) || \ GTEST_OS_WINDOWS_MINGW || GTEST_OS_AIX || GTEST_OS_HPUX || \ GTEST_OS_OPENBSD || GTEST_OS_QNX) # define GTEST_HAS_DEATH_TEST 1 # include // NOLINT #endif // We don't support MSVC 7.1 with exceptions disabled now. Therefore // all the compilers we care about are adequate for supporting // value-parameterized tests. #define GTEST_HAS_PARAM_TEST 1 // Determines whether to support type-driven tests. // Typed tests need and variadic macros, which GCC, VC++ 8.0, // Sun Pro CC, IBM Visual Age, and HP aCC support. #if defined(__GNUC__) || (_MSC_VER >= 1400) || defined(__SUNPRO_CC) || \ defined(__IBMCPP__) || defined(__HP_aCC) # define GTEST_HAS_TYPED_TEST 1 # define GTEST_HAS_TYPED_TEST_P 1 #endif // Determines whether to support Combine(). This only makes sense when // value-parameterized tests are enabled. The implementation doesn't // work on Sun Studio since it doesn't understand templated conversion // operators. #if GTEST_HAS_PARAM_TEST && GTEST_HAS_TR1_TUPLE && !defined(__SUNPRO_CC) # define GTEST_HAS_COMBINE 1 #endif // Determines whether the system compiler uses UTF-16 for encoding wide strings. #define GTEST_WIDE_STRING_USES_UTF16_ \ (GTEST_OS_WINDOWS || GTEST_OS_CYGWIN || GTEST_OS_SYMBIAN || GTEST_OS_AIX) // Determines whether test results can be streamed to a socket. #if GTEST_OS_LINUX # define GTEST_CAN_STREAM_RESULTS_ 1 #endif // Defines some utility macros. // The GNU compiler emits a warning if nested "if" statements are followed by // an "else" statement and braces are not used to explicitly disambiguate the // "else" binding. This leads to problems with code like: // // if (gate) // ASSERT_*(condition) << "Some message"; // // The "switch (0) case 0:" idiom is used to suppress this. #ifdef __INTEL_COMPILER # define GTEST_AMBIGUOUS_ELSE_BLOCKER_ #else # define GTEST_AMBIGUOUS_ELSE_BLOCKER_ switch (0) case 0: default: // NOLINT #endif // Use this annotation at the end of a struct/class definition to // prevent the compiler from optimizing away instances that are never // used. This is useful when all interesting logic happens inside the // c'tor and / or d'tor. Example: // // struct Foo { // Foo() { ... } // } GTEST_ATTRIBUTE_UNUSED_; // // Also use it after a variable or parameter declaration to tell the // compiler the variable/parameter does not have to be used. #if defined(__GNUC__) && !defined(COMPILER_ICC) # define GTEST_ATTRIBUTE_UNUSED_ __attribute__ ((unused)) #else # define GTEST_ATTRIBUTE_UNUSED_ #endif // A macro to disallow operator= // This should be used in the private: declarations for a class. #define GTEST_DISALLOW_ASSIGN_(type)\ void operator=(type const &) // A macro to disallow copy constructor and operator= // This should be used in the private: declarations for a class. #define GTEST_DISALLOW_COPY_AND_ASSIGN_(type)\ type(type const &);\ GTEST_DISALLOW_ASSIGN_(type) // Tell the compiler to warn about unused return values for functions declared // with this macro. The macro should be used on function declarations // following the argument list: // // Sprocket* AllocateSprocket() GTEST_MUST_USE_RESULT_; #if defined(__GNUC__) && (GTEST_GCC_VER_ >= 30400) && !defined(COMPILER_ICC) # define GTEST_MUST_USE_RESULT_ __attribute__ ((warn_unused_result)) #else # define GTEST_MUST_USE_RESULT_ #endif // __GNUC__ && (GTEST_GCC_VER_ >= 30400) && !COMPILER_ICC // Determine whether the compiler supports Microsoft's Structured Exception // Handling. This is supported by several Windows compilers but generally // does not exist on any other system. #ifndef GTEST_HAS_SEH // The user didn't tell us, so we need to figure it out. # if defined(_MSC_VER) || defined(__BORLANDC__) // These two compilers are known to support SEH. # define GTEST_HAS_SEH 1 # else // Assume no SEH. # define GTEST_HAS_SEH 0 # endif #endif // GTEST_HAS_SEH #ifdef _MSC_VER # if GTEST_LINKED_AS_SHARED_LIBRARY # define GTEST_API_ __declspec(dllimport) # elif GTEST_CREATE_SHARED_LIBRARY # define GTEST_API_ __declspec(dllexport) # endif #endif // _MSC_VER #ifndef GTEST_API_ # define GTEST_API_ #endif #ifdef __GNUC__ // Ask the compiler to never inline a given function. # define GTEST_NO_INLINE_ __attribute__((noinline)) #else # define GTEST_NO_INLINE_ #endif // _LIBCPP_VERSION is defined by the libc++ library from the LLVM project. #if defined(__GLIBCXX__) || defined(_LIBCPP_VERSION) # define GTEST_HAS_CXXABI_H_ 1 #else # define GTEST_HAS_CXXABI_H_ 0 #endif namespace testing { class Message; namespace internal { // A secret type that Google Test users don't know about. It has no // definition on purpose. Therefore it's impossible to create a // Secret object, which is what we want. class Secret; // The GTEST_COMPILE_ASSERT_ macro can be used to verify that a compile time // expression is true. For example, you could use it to verify the // size of a static array: // // GTEST_COMPILE_ASSERT_(ARRAYSIZE(content_type_names) == CONTENT_NUM_TYPES, // content_type_names_incorrect_size); // // or to make sure a struct is smaller than a certain size: // // GTEST_COMPILE_ASSERT_(sizeof(foo) < 128, foo_too_large); // // The second argument to the macro is the name of the variable. If // the expression is false, most compilers will issue a warning/error // containing the name of the variable. template struct CompileAssert { }; #define GTEST_COMPILE_ASSERT_(expr, msg) \ typedef ::testing::internal::CompileAssert<(static_cast(expr))> \ msg[static_cast(expr) ? 1 : -1] GTEST_ATTRIBUTE_UNUSED_ // Implementation details of GTEST_COMPILE_ASSERT_: // // - GTEST_COMPILE_ASSERT_ works by defining an array type that has -1 // elements (and thus is invalid) when the expression is false. // // - The simpler definition // // #define GTEST_COMPILE_ASSERT_(expr, msg) typedef char msg[(expr) ? 1 : -1] // // does not work, as gcc supports variable-length arrays whose sizes // are determined at run-time (this is gcc's extension and not part // of the C++ standard). As a result, gcc fails to reject the // following code with the simple definition: // // int foo; // GTEST_COMPILE_ASSERT_(foo, msg); // not supposed to compile as foo is // // not a compile-time constant. // // - By using the type CompileAssert<(bool(expr))>, we ensures that // expr is a compile-time constant. (Template arguments must be // determined at compile-time.) // // - The outter parentheses in CompileAssert<(bool(expr))> are necessary // to work around a bug in gcc 3.4.4 and 4.0.1. If we had written // // CompileAssert // // instead, these compilers will refuse to compile // // GTEST_COMPILE_ASSERT_(5 > 0, some_message); // // (They seem to think the ">" in "5 > 0" marks the end of the // template argument list.) // // - The array size is (bool(expr) ? 1 : -1), instead of simply // // ((expr) ? 1 : -1). // // This is to avoid running into a bug in MS VC 7.1, which // causes ((0.0) ? 1 : -1) to incorrectly evaluate to 1. // StaticAssertTypeEqHelper is used by StaticAssertTypeEq defined in gtest.h. // // This template is declared, but intentionally undefined. template struct StaticAssertTypeEqHelper; template struct StaticAssertTypeEqHelper {}; #if GTEST_HAS_GLOBAL_STRING typedef ::string string; #else typedef ::std::string string; #endif // GTEST_HAS_GLOBAL_STRING #if GTEST_HAS_GLOBAL_WSTRING typedef ::wstring wstring; #elif GTEST_HAS_STD_WSTRING typedef ::std::wstring wstring; #endif // GTEST_HAS_GLOBAL_WSTRING // A helper for suppressing warnings on constant condition. It just // returns 'condition'. GTEST_API_ bool IsTrue(bool condition); // Defines scoped_ptr. // This implementation of scoped_ptr is PARTIAL - it only contains // enough stuff to satisfy Google Test's need. template class scoped_ptr { public: typedef T element_type; explicit scoped_ptr(T* p = NULL) : ptr_(p) {} ~scoped_ptr() { reset(); } T& operator*() const { return *ptr_; } T* operator->() const { return ptr_; } T* get() const { return ptr_; } T* release() { T* const ptr = ptr_; ptr_ = NULL; return ptr; } void reset(T* p = NULL) { if (p != ptr_) { if (IsTrue(sizeof(T) > 0)) { // Makes sure T is a complete type. delete ptr_; } ptr_ = p; } } private: T* ptr_; GTEST_DISALLOW_COPY_AND_ASSIGN_(scoped_ptr); }; // Defines RE. // A simple C++ wrapper for . It uses the POSIX Extended // Regular Expression syntax. class GTEST_API_ RE { public: // A copy constructor is required by the Standard to initialize object // references from r-values. RE(const RE& other) { Init(other.pattern()); } // Constructs an RE from a string. RE(const ::std::string& regex) { Init(regex.c_str()); } // NOLINT #if GTEST_HAS_GLOBAL_STRING RE(const ::string& regex) { Init(regex.c_str()); } // NOLINT #endif // GTEST_HAS_GLOBAL_STRING RE(const char* regex) { Init(regex); } // NOLINT ~RE(); // Returns the string representation of the regex. const char* pattern() const { return pattern_; } // FullMatch(str, re) returns true iff regular expression re matches // the entire str. // PartialMatch(str, re) returns true iff regular expression re // matches a substring of str (including str itself). // // TODO(wan@google.com): make FullMatch() and PartialMatch() work // when str contains NUL characters. static bool FullMatch(const ::std::string& str, const RE& re) { return FullMatch(str.c_str(), re); } static bool PartialMatch(const ::std::string& str, const RE& re) { return PartialMatch(str.c_str(), re); } #if GTEST_HAS_GLOBAL_STRING static bool FullMatch(const ::string& str, const RE& re) { return FullMatch(str.c_str(), re); } static bool PartialMatch(const ::string& str, const RE& re) { return PartialMatch(str.c_str(), re); } #endif // GTEST_HAS_GLOBAL_STRING static bool FullMatch(const char* str, const RE& re); static bool PartialMatch(const char* str, const RE& re); private: void Init(const char* regex); // We use a const char* instead of an std::string, as Google Test used to be // used where std::string is not available. TODO(wan@google.com): change to // std::string. const char* pattern_; bool is_valid_; #if GTEST_USES_POSIX_RE regex_t full_regex_; // For FullMatch(). regex_t partial_regex_; // For PartialMatch(). #else // GTEST_USES_SIMPLE_RE const char* full_pattern_; // For FullMatch(); #endif GTEST_DISALLOW_ASSIGN_(RE); }; // Formats a source file path and a line number as they would appear // in an error message from the compiler used to compile this code. GTEST_API_ ::std::string FormatFileLocation(const char* file, int line); // Formats a file location for compiler-independent XML output. // Although this function is not platform dependent, we put it next to // FormatFileLocation in order to contrast the two functions. GTEST_API_ ::std::string FormatCompilerIndependentFileLocation(const char* file, int line); // Defines logging utilities: // GTEST_LOG_(severity) - logs messages at the specified severity level. The // message itself is streamed into the macro. // LogToStderr() - directs all log messages to stderr. // FlushInfoLog() - flushes informational log messages. enum GTestLogSeverity { GTEST_INFO, GTEST_WARNING, GTEST_ERROR, GTEST_FATAL }; // Formats log entry severity, provides a stream object for streaming the // log message, and terminates the message with a newline when going out of // scope. class GTEST_API_ GTestLog { public: GTestLog(GTestLogSeverity severity, const char* file, int line); // Flushes the buffers and, if severity is GTEST_FATAL, aborts the program. ~GTestLog(); ::std::ostream& GetStream() { return ::std::cerr; } private: const GTestLogSeverity severity_; GTEST_DISALLOW_COPY_AND_ASSIGN_(GTestLog); }; #define GTEST_LOG_(severity) \ ::testing::internal::GTestLog(::testing::internal::GTEST_##severity, \ __FILE__, __LINE__).GetStream() inline void LogToStderr() {} inline void FlushInfoLog() { fflush(NULL); } // INTERNAL IMPLEMENTATION - DO NOT USE. // // GTEST_CHECK_ is an all-mode assert. It aborts the program if the condition // is not satisfied. // Synopsys: // GTEST_CHECK_(boolean_condition); // or // GTEST_CHECK_(boolean_condition) << "Additional message"; // // This checks the condition and if the condition is not satisfied // it prints message about the condition violation, including the // condition itself, plus additional message streamed into it, if any, // and then it aborts the program. It aborts the program irrespective of // whether it is built in the debug mode or not. #define GTEST_CHECK_(condition) \ GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ if (::testing::internal::IsTrue(condition)) \ ; \ else \ GTEST_LOG_(FATAL) << "Condition " #condition " failed. " // An all-mode assert to verify that the given POSIX-style function // call returns 0 (indicating success). Known limitation: this // doesn't expand to a balanced 'if' statement, so enclose the macro // in {} if you need to use it as the only statement in an 'if' // branch. #define GTEST_CHECK_POSIX_SUCCESS_(posix_call) \ if (const int gtest_error = (posix_call)) \ GTEST_LOG_(FATAL) << #posix_call << "failed with error " \ << gtest_error // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. // // Use ImplicitCast_ as a safe version of static_cast for upcasting in // the type hierarchy (e.g. casting a Foo* to a SuperclassOfFoo* or a // const Foo*). When you use ImplicitCast_, the compiler checks that // the cast is safe. Such explicit ImplicitCast_s are necessary in // surprisingly many situations where C++ demands an exact type match // instead of an argument type convertable to a target type. // // The syntax for using ImplicitCast_ is the same as for static_cast: // // ImplicitCast_(expr) // // ImplicitCast_ would have been part of the C++ standard library, // but the proposal was submitted too late. It will probably make // its way into the language in the future. // // This relatively ugly name is intentional. It prevents clashes with // similar functions users may have (e.g., implicit_cast). The internal // namespace alone is not enough because the function can be found by ADL. template inline To ImplicitCast_(To x) { return x; } // When you upcast (that is, cast a pointer from type Foo to type // SuperclassOfFoo), it's fine to use ImplicitCast_<>, since upcasts // always succeed. When you downcast (that is, cast a pointer from // type Foo to type SubclassOfFoo), static_cast<> isn't safe, because // how do you know the pointer is really of type SubclassOfFoo? It // could be a bare Foo, or of type DifferentSubclassOfFoo. Thus, // when you downcast, you should use this macro. In debug mode, we // use dynamic_cast<> to double-check the downcast is legal (we die // if it's not). In normal mode, we do the efficient static_cast<> // instead. Thus, it's important to test in debug mode to make sure // the cast is legal! // This is the only place in the code we should use dynamic_cast<>. // In particular, you SHOULDN'T be using dynamic_cast<> in order to // do RTTI (eg code like this: // if (dynamic_cast(foo)) HandleASubclass1Object(foo); // if (dynamic_cast(foo)) HandleASubclass2Object(foo); // You should design the code some other way not to need this. // // This relatively ugly name is intentional. It prevents clashes with // similar functions users may have (e.g., down_cast). The internal // namespace alone is not enough because the function can be found by ADL. template // use like this: DownCast_(foo); inline To DownCast_(From* f) { // so we only accept pointers // Ensures that To is a sub-type of From *. This test is here only // for compile-time type checking, and has no overhead in an // optimized build at run-time, as it will be optimized away // completely. if (false) { const To to = NULL; ::testing::internal::ImplicitCast_(to); } #if GTEST_HAS_RTTI // RTTI: debug mode only! GTEST_CHECK_(f == NULL || dynamic_cast(f) != NULL); #endif return static_cast(f); } // Downcasts the pointer of type Base to Derived. // Derived must be a subclass of Base. The parameter MUST // point to a class of type Derived, not any subclass of it. // When RTTI is available, the function performs a runtime // check to enforce this. template Derived* CheckedDowncastToActualType(Base* base) { #if GTEST_HAS_RTTI GTEST_CHECK_(typeid(*base) == typeid(Derived)); return dynamic_cast(base); // NOLINT #else return static_cast(base); // Poor man's downcast. #endif } #if GTEST_HAS_STREAM_REDIRECTION // Defines the stderr capturer: // CaptureStdout - starts capturing stdout. // GetCapturedStdout - stops capturing stdout and returns the captured string. // CaptureStderr - starts capturing stderr. // GetCapturedStderr - stops capturing stderr and returns the captured string. // GTEST_API_ void CaptureStdout(); GTEST_API_ std::string GetCapturedStdout(); GTEST_API_ void CaptureStderr(); GTEST_API_ std::string GetCapturedStderr(); #endif // GTEST_HAS_STREAM_REDIRECTION #if GTEST_HAS_DEATH_TEST const ::std::vector& GetInjectableArgvs(); void SetInjectableArgvs(const ::std::vector* new_argvs); // A copy of all command line arguments. Set by InitGoogleTest(). 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. inline void SleepMilliseconds(int n) { const timespec time = { 0, // 0 seconds. n * 1000L * 1000L, // And n ms. }; nanosleep(&time, NULL); } // Allows a controller thread to pause execution of newly created // threads until notified. Instances of this class must be created // and destroyed in the controller thread. // // This class is only for testing Google Test's own constructs. Do not // use it in user tests, either directly or indirectly. class Notification { public: Notification() : notified_(false) { GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_init(&mutex_, NULL)); } ~Notification() { pthread_mutex_destroy(&mutex_); } // Notifies all threads created with this notification to start. Must // be called from the controller thread. void Notify() { pthread_mutex_lock(&mutex_); notified_ = true; pthread_mutex_unlock(&mutex_); } // Blocks until the controller thread notifies. Must be called from a test // thread. void WaitForNotification() { for (;;) { pthread_mutex_lock(&mutex_); const bool notified = notified_; pthread_mutex_unlock(&mutex_); if (notified) break; SleepMilliseconds(10); } } private: pthread_mutex_t mutex_; bool notified_; GTEST_DISALLOW_COPY_AND_ASSIGN_(Notification); }; // As a C-function, ThreadFuncWithCLinkage cannot be templated itself. // Consequently, it cannot select a correct instantiation of ThreadWithParam // in order to call its Run(). Introducing ThreadWithParamBase as a // non-templated base class for ThreadWithParam allows us to bypass this // problem. class ThreadWithParamBase { public: virtual ~ThreadWithParamBase() {} virtual void Run() = 0; }; // pthread_create() accepts a pointer to a function type with the C linkage. // According to the Standard (7.5/1), function types with different linkages // are different even if they are otherwise identical. Some compilers (for // example, SunStudio) treat them as different types. Since class methods // cannot be defined with C-linkage we need to define a free C-function to // pass into pthread_create(). extern "C" inline void* ThreadFuncWithCLinkage(void* thread) { static_cast(thread)->Run(); return NULL; } // Helper class for testing Google Test's multi-threading constructs. // To use it, write: // // void ThreadFunc(int param) { /* Do things with param */ } // Notification thread_can_start; // ... // // The thread_can_start parameter is optional; you can supply NULL. // ThreadWithParam thread(&ThreadFunc, 5, &thread_can_start); // thread_can_start.Notify(); // // These classes are only for testing Google Test's own constructs. Do // not use them in user tests, either directly or indirectly. template class ThreadWithParam : public ThreadWithParamBase { public: typedef void (*UserThreadFunc)(T); ThreadWithParam( UserThreadFunc func, T param, Notification* thread_can_start) : func_(func), param_(param), thread_can_start_(thread_can_start), finished_(false) { ThreadWithParamBase* const base = this; // The thread can be created only after all fields except thread_ // have been initialized. GTEST_CHECK_POSIX_SUCCESS_( pthread_create(&thread_, 0, &ThreadFuncWithCLinkage, base)); } ~ThreadWithParam() { Join(); } void Join() { if (!finished_) { GTEST_CHECK_POSIX_SUCCESS_(pthread_join(thread_, 0)); finished_ = true; } } virtual void Run() { if (thread_can_start_ != NULL) thread_can_start_->WaitForNotification(); func_(param_); } private: const UserThreadFunc func_; // User-supplied thread function. const T param_; // User-supplied parameter to the thread function. // When non-NULL, used to block execution until the controller thread // notifies. Notification* const thread_can_start_; bool finished_; // true iff we know that the thread function has finished. pthread_t thread_; // The native thread object. GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadWithParam); }; // MutexBase and Mutex implement mutex on pthreads-based platforms. They // are used in conjunction with class MutexLock: // // Mutex mutex; // ... // MutexLock lock(&mutex); // Acquires the mutex and releases it at the end // // of the current scope. // // MutexBase implements behavior for both statically and dynamically // allocated mutexes. Do not use MutexBase directly. Instead, write // the following to define a static mutex: // // GTEST_DEFINE_STATIC_MUTEX_(g_some_mutex); // // You can forward declare a static mutex like this: // // GTEST_DECLARE_STATIC_MUTEX_(g_some_mutex); // // To create a dynamic mutex, just define an object of type Mutex. class MutexBase { public: // Acquires this mutex. void Lock() { GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_lock(&mutex_)); owner_ = pthread_self(); has_owner_ = true; } // Releases this mutex. void Unlock() { // Since the lock is being released the owner_ field should no longer be // considered valid. We don't protect writing to has_owner_ here, as it's // the caller's responsibility to ensure that the current thread holds the // mutex when this is called. has_owner_ = false; GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_unlock(&mutex_)); } // Does nothing if the current thread holds the mutex. Otherwise, crashes // with high probability. void AssertHeld() const { GTEST_CHECK_(has_owner_ && pthread_equal(owner_, pthread_self())) << "The current thread is not holding the mutex @" << this; } // A static mutex may be used before main() is entered. It may even // be used before the dynamic initialization stage. Therefore we // must be able to initialize a static mutex object at link time. // This means MutexBase has to be a POD and its member variables // have to be public. public: pthread_mutex_t mutex_; // The underlying pthread mutex. // has_owner_ indicates whether the owner_ field below contains a valid thread // ID and is therefore safe to inspect (e.g., to use in pthread_equal()). All // accesses to the owner_ field should be protected by a check of this field. // An alternative might be to memset() owner_ to all zeros, but there's no // guarantee that a zero'd pthread_t is necessarily invalid or even different // from pthread_self(). bool has_owner_; pthread_t owner_; // The thread holding the mutex. }; // Forward-declares a static mutex. # define GTEST_DECLARE_STATIC_MUTEX_(mutex) \ extern ::testing::internal::MutexBase mutex // Defines and statically (i.e. at link time) initializes a static mutex. // The initialization list here does not explicitly initialize each field, // instead relying on default initialization for the unspecified fields. In // 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 } // The Mutex class can only be used for mutexes created at runtime. It // shares its API with MutexBase otherwise. class Mutex : public MutexBase { public: Mutex() { GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_init(&mutex_, NULL)); has_owner_ = false; } ~Mutex() { GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_destroy(&mutex_)); } private: GTEST_DISALLOW_COPY_AND_ASSIGN_(Mutex); }; // We cannot name this class MutexLock as the ctor declaration would // conflict with a macro named MutexLock, which is defined on some // platforms. Hence the typedef trick below. class GTestMutexLock { public: explicit GTestMutexLock(MutexBase* mutex) : mutex_(mutex) { mutex_->Lock(); } ~GTestMutexLock() { mutex_->Unlock(); } private: MutexBase* const mutex_; GTEST_DISALLOW_COPY_AND_ASSIGN_(GTestMutexLock); }; typedef GTestMutexLock MutexLock; // Helpers for ThreadLocal. // pthread_key_create() requires DeleteThreadLocalValue() to have // C-linkage. Therefore it cannot be templatized to access // ThreadLocal. Hence the need for class // ThreadLocalValueHolderBase. class ThreadLocalValueHolderBase { public: virtual ~ThreadLocalValueHolderBase() {} }; // Called by pthread to delete thread-local data stored by // pthread_setspecific(). extern "C" inline void DeleteThreadLocalValue(void* value_holder) { delete static_cast(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() { // Destroys the managed object for the current thread, if any. DeleteThreadLocalValue(pthread_getspecific(key_)); // Releases resources associated with the key. This will *not* // delete managed objects for other threads. GTEST_CHECK_POSIX_SUCCESS_(pthread_key_delete(key_)); } T* pointer() { return GetOrCreateValue(); } const T* pointer() const { return GetOrCreateValue(); } const T& get() const { return *pointer(); } void set(const T& value) { *pointer() = value; } private: // Holds a value of type T. class ValueHolder : public ThreadLocalValueHolderBase { public: explicit ValueHolder(const T& value) : value_(value) {} T* pointer() { return &value_; } private: T value_; GTEST_DISALLOW_COPY_AND_ASSIGN_(ValueHolder); }; static pthread_key_t CreateKey() { pthread_key_t key; // When a thread exits, DeleteThreadLocalValue() will be called on // the object managed for that thread. GTEST_CHECK_POSIX_SUCCESS_( pthread_key_create(&key, &DeleteThreadLocalValue)); return key; } T* GetOrCreateValue() const { ThreadLocalValueHolderBase* const holder = static_cast(pthread_getspecific(key_)); if (holder != NULL) { return CheckedDowncastToActualType(holder)->pointer(); } ValueHolder* const new_holder = new ValueHolder(default_); ThreadLocalValueHolderBase* const holder_base = new_holder; GTEST_CHECK_POSIX_SUCCESS_(pthread_setspecific(key_, holder_base)); return new_holder->pointer(); } // A key pthreads uses for looking up per-thread values. const pthread_key_t key_; const T default_; // The default value for each thread. GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadLocal); }; # define GTEST_IS_THREADSAFE 1 #else // GTEST_HAS_PTHREAD // A dummy implementation of synchronization primitives (mutex, lock, // and thread-local variable). Necessary for compiling Google Test where // mutex is not supported - using Google Test in multiple threads is not // supported on such platforms. class Mutex { public: Mutex() {} void Lock() {} void Unlock() {} void AssertHeld() const {} }; # define GTEST_DECLARE_STATIC_MUTEX_(mutex) \ extern ::testing::internal::Mutex mutex # define GTEST_DEFINE_STATIC_MUTEX_(mutex) ::testing::internal::Mutex mutex class GTestMutexLock { public: explicit GTestMutexLock(Mutex*) {} // NOLINT }; typedef GTestMutexLock MutexLock; template class ThreadLocal { public: ThreadLocal() : value_() {} explicit ThreadLocal(const T& value) : value_(value) {} T* pointer() { return &value_; } const T* pointer() const { return &value_; } const T& get() const { return value_; } void set(const T& value) { value_ = value; } private: T value_; }; // The above synchronization primitives have dummy implementations. // Therefore Google Test is not thread-safe. # define GTEST_IS_THREADSAFE 0 #endif // GTEST_HAS_PTHREAD // Returns the number of threads running in the process, or 0 to indicate that // we cannot detect it. GTEST_API_ size_t GetThreadCount(); // Passing non-POD classes through ellipsis (...) crashes the ARM // compiler and generates a warning in Sun Studio. The Nokia Symbian // and the IBM XL C/C++ compiler try to instantiate a copy constructor // for objects passed through ellipsis (...), failing for uncopyable // objects. We define this to ensure that only POD is passed through // ellipsis on these systems. #if defined(__SYMBIAN32__) || defined(__IBMCPP__) || defined(__SUNPRO_CC) // We lose support for NULL detection where the compiler doesn't like // passing non-POD classes through ellipsis (...). # define GTEST_ELLIPSIS_NEEDS_POD_ 1 #else # define GTEST_CAN_COMPARE_NULL 1 #endif // The Nokia Symbian and IBM XL C/C++ compilers cannot decide between // const T& and const T* in a function template. These compilers // _can_ decide between class template specializations for T and T*, // so a tr1::type_traits-like is_pointer works. #if defined(__SYMBIAN32__) || defined(__IBMCPP__) # define GTEST_NEEDS_IS_POINTER_ 1 #endif template struct bool_constant { typedef bool_constant type; static const bool value = bool_value; }; template const bool bool_constant::value; typedef bool_constant false_type; typedef bool_constant true_type; template struct is_pointer : public false_type {}; template struct is_pointer : public true_type {}; template struct IteratorTraits { typedef typename Iterator::value_type value_type; }; template struct IteratorTraits { typedef T value_type; }; template struct IteratorTraits { typedef T value_type; }; #if GTEST_OS_WINDOWS # define GTEST_PATH_SEP_ "\\" # define GTEST_HAS_ALT_PATH_SEP_ 1 // The biggest signed integer type the compiler supports. typedef __int64 BiggestInt; #else # define GTEST_PATH_SEP_ "/" # define GTEST_HAS_ALT_PATH_SEP_ 0 typedef long long BiggestInt; // NOLINT #endif // GTEST_OS_WINDOWS // Utilities for char. // isspace(int ch) and friends accept an unsigned char or EOF. char // may be signed, depending on the compiler (or compiler flags). // Therefore we need to cast a char to unsigned char before calling // isspace(), etc. inline bool IsAlpha(char ch) { return isalpha(static_cast(ch)) != 0; } inline bool IsAlNum(char ch) { return isalnum(static_cast(ch)) != 0; } inline bool IsDigit(char ch) { return isdigit(static_cast(ch)) != 0; } inline bool IsLower(char ch) { return islower(static_cast(ch)) != 0; } inline bool IsSpace(char ch) { return isspace(static_cast(ch)) != 0; } inline bool IsUpper(char ch) { return isupper(static_cast(ch)) != 0; } inline bool IsXDigit(char ch) { return isxdigit(static_cast(ch)) != 0; } inline bool IsXDigit(wchar_t ch) { const unsigned char low_byte = static_cast(ch); return ch == low_byte && isxdigit(low_byte) != 0; } inline char ToLower(char ch) { return static_cast(tolower(static_cast(ch))); } inline char ToUpper(char ch) { return static_cast(toupper(static_cast(ch))); } // The testing::internal::posix namespace holds wrappers for common // POSIX functions. These wrappers hide the differences between // Windows/MSVC and POSIX systems. Since some compilers define these // standard functions as macros, the wrapper cannot have the same name // as the wrapped function. namespace posix { // Functions with a different name on Windows. #if GTEST_OS_WINDOWS typedef struct _stat StatStruct; # ifdef __BORLANDC__ inline int IsATTY(int fd) { return isatty(fd); } inline int StrCaseCmp(const char* s1, const char* s2) { return stricmp(s1, s2); } inline char* StrDup(const char* src) { return strdup(src); } # else // !__BORLANDC__ # if GTEST_OS_WINDOWS_MOBILE inline int IsATTY(int /* fd */) { return 0; } # else inline int IsATTY(int fd) { return _isatty(fd); } # endif // GTEST_OS_WINDOWS_MOBILE inline int StrCaseCmp(const char* s1, const char* s2) { return _stricmp(s1, s2); } inline char* StrDup(const char* src) { return _strdup(src); } # endif // __BORLANDC__ # if GTEST_OS_WINDOWS_MOBILE inline int FileNo(FILE* file) { return reinterpret_cast(_fileno(file)); } // Stat(), RmDir(), and IsDir() are not needed on Windows CE at this // time and thus not defined there. # else inline int FileNo(FILE* file) { return _fileno(file); } inline int Stat(const char* path, StatStruct* buf) { return _stat(path, buf); } inline int RmDir(const char* dir) { return _rmdir(dir); } inline bool IsDir(const StatStruct& st) { return (_S_IFDIR & st.st_mode) != 0; } # endif // GTEST_OS_WINDOWS_MOBILE #else typedef struct stat StatStruct; inline int FileNo(FILE* file) { return fileno(file); } inline int IsATTY(int fd) { return isatty(fd); } inline int Stat(const char* path, StatStruct* buf) { return stat(path, buf); } inline int StrCaseCmp(const char* s1, const char* s2) { return strcasecmp(s1, s2); } inline char* StrDup(const char* src) { return strdup(src); } inline int RmDir(const char* dir) { return rmdir(dir); } inline bool IsDir(const StatStruct& st) { return S_ISDIR(st.st_mode); } #endif // GTEST_OS_WINDOWS // Functions deprecated by MSVC 8.0. #ifdef _MSC_VER // Temporarily disable warning 4996 (deprecated function). # pragma warning(push) # pragma warning(disable:4996) #endif inline const char* StrNCpy(char* dest, const char* src, size_t n) { return strncpy(dest, src, n); } // ChDir(), FReopen(), FDOpen(), Read(), Write(), Close(), and // StrError() aren't needed on Windows CE at this time and thus not // defined there. #if !GTEST_OS_WINDOWS_MOBILE inline int ChDir(const char* dir) { return chdir(dir); } #endif inline FILE* FOpen(const char* path, const char* mode) { return fopen(path, mode); } #if !GTEST_OS_WINDOWS_MOBILE inline FILE *FReopen(const char* path, const char* mode, FILE* stream) { return freopen(path, mode, stream); } inline FILE* FDOpen(int fd, const char* mode) { return fdopen(fd, mode); } #endif inline int FClose(FILE* fp) { return fclose(fp); } #if !GTEST_OS_WINDOWS_MOBILE inline int Read(int fd, void* buf, unsigned int count) { return static_cast(read(fd, buf, count)); } inline int Write(int fd, const void* buf, unsigned int count) { return static_cast(write(fd, buf, count)); } inline int Close(int fd) { return close(fd); } inline const char* StrError(int errnum) { return strerror(errnum); } #endif inline const char* GetEnv(const char* name) { #if GTEST_OS_WINDOWS_MOBILE // We are on Windows CE, which has no environment variables. return NULL; #elif defined(__BORLANDC__) || defined(__SunOS_5_8) || defined(__SunOS_5_9) // Environment variables which we programmatically clear will be set to the // empty string rather than unset (NULL). Handle that case. const char* const env = getenv(name); return (env != NULL && env[0] != '\0') ? env : NULL; #else return getenv(name); #endif } #ifdef _MSC_VER # pragma warning(pop) // Restores the warning state. #endif #if GTEST_OS_WINDOWS_MOBILE // Windows CE has no C library. The abort() function is used in // several places in Google Test. This implementation provides a reasonable // imitation of standard behaviour. void Abort(); #else inline void Abort() { abort(); } #endif // GTEST_OS_WINDOWS_MOBILE } // namespace posix // MSVC "deprecates" snprintf and issues warnings wherever it is used. In // order to avoid these warnings, we need to use _snprintf or _snprintf_s on // MSVC-based platforms. We map the GTEST_SNPRINTF_ macro to the appropriate // function in order to achieve that. We use macro definition here because // snprintf is a variadic function. #if _MSC_VER >= 1400 && !GTEST_OS_WINDOWS_MOBILE // MSVC 2005 and above support variadic macros. # define GTEST_SNPRINTF_(buffer, size, format, ...) \ _snprintf_s(buffer, size, size, format, __VA_ARGS__) #elif defined(_MSC_VER) // Windows CE does not define _snprintf_s and MSVC prior to 2005 doesn't // complain about _snprintf. # define GTEST_SNPRINTF_ _snprintf #else # define GTEST_SNPRINTF_ snprintf #endif // The maximum number a BiggestInt can represent. This definition // works no matter BiggestInt is represented in one's complement or // two's complement. // // We cannot rely on numeric_limits in STL, as __int64 and long long // are not part of standard C++ and numeric_limits doesn't need to be // defined for them. const BiggestInt kMaxBiggestInt = ~(static_cast(1) << (8*sizeof(BiggestInt) - 1)); // This template class serves as a compile-time function from size to // type. It maps a size in bytes to a primitive type with that // size. e.g. // // TypeWithSize<4>::UInt // // is typedef-ed to be unsigned int (unsigned integer made up of 4 // bytes). // // Such functionality should belong to STL, but I cannot find it // there. // // Google Test uses this class in the implementation of floating-point // comparison. // // For now it only handles UInt (unsigned int) as that's all Google Test // needs. Other types can be easily added in the future if need // arises. template class TypeWithSize { public: // This prevents the user from using TypeWithSize with incorrect // values of N. typedef void UInt; }; // The specialization for size 4. template <> class TypeWithSize<4> { public: // unsigned int has size 4 in both gcc and MSVC. // // As base/basictypes.h doesn't compile on Windows, we cannot use // uint32, uint64, and etc here. typedef int Int; typedef unsigned int UInt; }; // The specialization for size 8. template <> class TypeWithSize<8> { public: #if GTEST_OS_WINDOWS typedef __int64 Int; typedef unsigned __int64 UInt; #else typedef long long Int; // NOLINT typedef unsigned long long UInt; // NOLINT #endif // GTEST_OS_WINDOWS }; // Integer types of known sizes. typedef TypeWithSize<4>::Int Int32; typedef TypeWithSize<4>::UInt UInt32; typedef TypeWithSize<8>::Int Int64; typedef TypeWithSize<8>::UInt UInt64; typedef TypeWithSize<8>::Int TimeInMillis; // Represents time in milliseconds. // Utilities for command line flags and environment variables. // Macro for referencing flags. #define GTEST_FLAG(name) FLAGS_gtest_##name // Macros for declaring flags. #define GTEST_DECLARE_bool_(name) GTEST_API_ extern bool GTEST_FLAG(name) #define GTEST_DECLARE_int32_(name) \ GTEST_API_ extern ::testing::internal::Int32 GTEST_FLAG(name) #define GTEST_DECLARE_string_(name) \ GTEST_API_ extern ::std::string GTEST_FLAG(name) // Macros for defining flags. #define GTEST_DEFINE_bool_(name, default_val, doc) \ GTEST_API_ bool GTEST_FLAG(name) = (default_val) #define GTEST_DEFINE_int32_(name, default_val, doc) \ GTEST_API_ ::testing::internal::Int32 GTEST_FLAG(name) = (default_val) #define GTEST_DEFINE_string_(name, default_val, doc) \ GTEST_API_ ::std::string GTEST_FLAG(name) = (default_val) // Thread annotations #define GTEST_EXCLUSIVE_LOCK_REQUIRED_(locks) #define GTEST_LOCK_EXCLUDED_(locks) // Parses 'str' for a 32-bit signed integer. If successful, writes the result // to *value and returns true; otherwise leaves *value unchanged and returns // false. // TODO(chandlerc): Find a better way to refactor flag and environment parsing // out of both gtest-port.cc and gtest.cc to avoid exporting this utility // function. bool ParseInt32(const Message& src_text, const char* str, Int32* value); // Parses a bool/Int32/string from the environment variable // corresponding to the given Google Test flag. bool BoolFromGTestEnv(const char* flag, bool default_val); GTEST_API_ Int32 Int32FromGTestEnv(const char* flag, Int32 default_val); const char* StringFromGTestEnv(const char* flag, const char* default_val); } // namespace internal } // namespace testing #endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_ dlt-daemon-2.18.4/gtest-1.7.0/include/gtest/internal/gtest-string.h000066400000000000000000000154701353342203500246200ustar00rootroot00000000000000// Copyright 2005, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Authors: wan@google.com (Zhanyong Wan), eefacm@gmail.com (Sean Mcafee) // // The Google C++ Testing Framework (Google Test) // // This header file declares the String class and functions used internally by // Google Test. They are subject to change without notice. They should not used // by code external to Google Test. // // This header file is #included by . // It should not be #included by other files. #ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_ #define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_ #ifdef __BORLANDC__ // string.h is not guaranteed to provide strcpy on C++ Builder. # include #endif #include #include #include "gtest/internal/gtest-port.h" namespace testing { namespace internal { // String - an abstract class holding static string utilities. class GTEST_API_ String { public: // Static utility methods // Clones a 0-terminated C string, allocating memory using new. The // caller is responsible for deleting the return value using // delete[]. Returns the cloned string, or NULL if the input is // NULL. // // This is different from strdup() in string.h, which allocates // memory using malloc(). static const char* CloneCString(const char* c_str); #if GTEST_OS_WINDOWS_MOBILE // Windows CE does not have the 'ANSI' versions of Win32 APIs. To be // able to pass strings to Win32 APIs on CE we need to convert them // to 'Unicode', UTF-16. // Creates a UTF-16 wide string from the given ANSI string, allocating // memory using new. The caller is responsible for deleting the return // value using delete[]. Returns the wide string, or NULL if the // input is NULL. // // The wide string is created using the ANSI codepage (CP_ACP) to // match the behaviour of the ANSI versions of Win32 calls and the // C runtime. static LPCWSTR AnsiToUtf16(const char* c_str); // Creates an ANSI string from the given wide string, allocating // memory using new. The caller is responsible for deleting the return // value using delete[]. Returns the ANSI string, or NULL if the // input is NULL. // // The returned string is created using the ANSI codepage (CP_ACP) to // match the behaviour of the ANSI versions of Win32 calls and the // C runtime. static const char* Utf16ToAnsi(LPCWSTR utf16_str); #endif // Compares two C strings. Returns true iff they have the same content. // // Unlike strcmp(), this function can handle NULL argument(s). A // NULL C string is considered different to any non-NULL C string, // including the empty string. static bool CStringEquals(const char* lhs, const char* rhs); // Converts a wide C string to a String using the UTF-8 encoding. // NULL will be converted to "(null)". If an error occurred during // the conversion, "(failed to convert from wide string)" is // returned. static std::string ShowWideCString(const wchar_t* wide_c_str); // Compares two wide C strings. Returns true iff they have the same // content. // // Unlike wcscmp(), this function can handle NULL argument(s). A // NULL C string is considered different to any non-NULL C string, // including the empty string. static bool WideCStringEquals(const wchar_t* lhs, const wchar_t* rhs); // Compares two C strings, ignoring case. Returns true iff they // have the same content. // // Unlike strcasecmp(), this function can handle NULL argument(s). // A NULL C string is considered different to any non-NULL C string, // including the empty string. static bool CaseInsensitiveCStringEquals(const char* lhs, const char* rhs); // Compares two wide C strings, ignoring case. Returns true iff they // have the same content. // // Unlike wcscasecmp(), this function can handle NULL argument(s). // A NULL C string is considered different to any non-NULL wide C string, // including the empty string. // NB: The implementations on different platforms slightly differ. // On windows, this method uses _wcsicmp which compares according to LC_CTYPE // environment variable. On GNU platform this method uses wcscasecmp // which compares according to LC_CTYPE category of the current locale. // On MacOS X, it uses towlower, which also uses LC_CTYPE category of the // current locale. static bool CaseInsensitiveWideCStringEquals(const wchar_t* lhs, const wchar_t* rhs); // Returns true iff the given string ends with the given suffix, ignoring // case. Any string is considered to end with an empty suffix. static bool EndsWithCaseInsensitive( const std::string& str, const std::string& suffix); // Formats an int value as "%02d". static std::string FormatIntWidth2(int value); // "%02d" for width == 2 // Formats an int value as "%X". static std::string FormatHexInt(int value); // Formats a byte as "%02X". static std::string FormatByte(unsigned char value); private: String(); // Not meant to be instantiated. }; // class String // Gets the content of the stringstream's buffer as an std::string. Each '\0' // character in the buffer is replaced with "\\0". GTEST_API_ std::string StringStreamToString(::std::stringstream* stream); } // namespace internal } // namespace testing #endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_ dlt-daemon-2.18.4/gtest-1.7.0/include/gtest/internal/gtest-tuple.h000066400000000000000000000670771353342203500244550ustar00rootroot00000000000000// This file was GENERATED by command: // pump.py gtest-tuple.h.pump // DO NOT EDIT BY HAND!!! // Copyright 2009 Google Inc. // All Rights Reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: wan@google.com (Zhanyong Wan) // Implements a subset of TR1 tuple needed by Google Test and Google Mock. #ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_ #define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_ #include // For ::std::pair. // The compiler used in Symbian has a bug that prevents us from declaring the // tuple template as a friend (it complains that tuple is redefined). This // hack bypasses the bug by declaring the members that should otherwise be // private as public. // Sun Studio versions < 12 also have the above bug. #if defined(__SYMBIAN32__) || (defined(__SUNPRO_CC) && __SUNPRO_CC < 0x590) # define GTEST_DECLARE_TUPLE_AS_FRIEND_ public: #else # define GTEST_DECLARE_TUPLE_AS_FRIEND_ \ template friend class tuple; \ private: #endif // GTEST_n_TUPLE_(T) is the type of an n-tuple. #define GTEST_0_TUPLE_(T) tuple<> #define GTEST_1_TUPLE_(T) tuple #define GTEST_2_TUPLE_(T) tuple #define GTEST_3_TUPLE_(T) tuple #define GTEST_4_TUPLE_(T) tuple #define GTEST_5_TUPLE_(T) tuple #define GTEST_6_TUPLE_(T) tuple #define GTEST_7_TUPLE_(T) tuple #define GTEST_8_TUPLE_(T) tuple #define GTEST_9_TUPLE_(T) tuple #define GTEST_10_TUPLE_(T) tuple // GTEST_n_TYPENAMES_(T) declares a list of n typenames. #define GTEST_0_TYPENAMES_(T) #define GTEST_1_TYPENAMES_(T) typename T##0 #define GTEST_2_TYPENAMES_(T) typename T##0, typename T##1 #define GTEST_3_TYPENAMES_(T) typename T##0, typename T##1, typename T##2 #define GTEST_4_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \ typename T##3 #define GTEST_5_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \ typename T##3, typename T##4 #define GTEST_6_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \ typename T##3, typename T##4, typename T##5 #define GTEST_7_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \ typename T##3, typename T##4, typename T##5, typename T##6 #define GTEST_8_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \ typename T##3, typename T##4, typename T##5, typename T##6, typename T##7 #define GTEST_9_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \ typename T##3, typename T##4, typename T##5, typename T##6, \ typename T##7, typename T##8 #define GTEST_10_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \ typename T##3, typename T##4, typename T##5, typename T##6, \ typename T##7, typename T##8, typename T##9 // In theory, defining stuff in the ::std namespace is undefined // behavior. We can do this as we are playing the role of a standard // library vendor. namespace std { namespace tr1 { template class tuple; // Anything in namespace gtest_internal is Google Test's INTERNAL // IMPLEMENTATION DETAIL and MUST NOT BE USED DIRECTLY in user code. namespace gtest_internal { // ByRef::type is T if T is a reference; otherwise it's const T&. template struct ByRef { typedef const T& type; }; // NOLINT template struct ByRef { typedef T& type; }; // NOLINT // A handy wrapper for ByRef. #define GTEST_BY_REF_(T) typename ::std::tr1::gtest_internal::ByRef::type // AddRef::type is T if T is a reference; otherwise it's T&. This // is the same as tr1::add_reference::type. template struct AddRef { typedef T& type; }; // NOLINT template struct AddRef { typedef T& type; }; // NOLINT // A handy wrapper for AddRef. #define GTEST_ADD_REF_(T) typename ::std::tr1::gtest_internal::AddRef::type // A helper for implementing get(). template class Get; // A helper for implementing tuple_element. kIndexValid is true // iff k < the number of fields in tuple type T. template struct TupleElement; template struct TupleElement { typedef T0 type; }; template struct TupleElement { typedef T1 type; }; template struct TupleElement { typedef T2 type; }; template struct TupleElement { typedef T3 type; }; template struct TupleElement { typedef T4 type; }; template struct TupleElement { typedef T5 type; }; template struct TupleElement { typedef T6 type; }; template struct TupleElement { typedef T7 type; }; template struct TupleElement { typedef T8 type; }; template struct TupleElement { typedef T9 type; }; } // namespace gtest_internal template <> class tuple<> { public: tuple() {} tuple(const tuple& /* t */) {} tuple& operator=(const tuple& /* t */) { return *this; } }; template class GTEST_1_TUPLE_(T) { public: template friend class gtest_internal::Get; tuple() : f0_() {} explicit tuple(GTEST_BY_REF_(T0) f0) : f0_(f0) {} tuple(const tuple& t) : f0_(t.f0_) {} template tuple(const GTEST_1_TUPLE_(U)& t) : f0_(t.f0_) {} tuple& operator=(const tuple& t) { return CopyFrom(t); } template tuple& operator=(const GTEST_1_TUPLE_(U)& t) { return CopyFrom(t); } GTEST_DECLARE_TUPLE_AS_FRIEND_ template tuple& CopyFrom(const GTEST_1_TUPLE_(U)& t) { f0_ = t.f0_; return *this; } T0 f0_; }; template class GTEST_2_TUPLE_(T) { public: template friend class gtest_internal::Get; tuple() : f0_(), f1_() {} explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1) : f0_(f0), f1_(f1) {} tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_) {} template tuple(const GTEST_2_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_) {} template tuple(const ::std::pair& p) : f0_(p.first), f1_(p.second) {} tuple& operator=(const tuple& t) { return CopyFrom(t); } template tuple& operator=(const GTEST_2_TUPLE_(U)& t) { return CopyFrom(t); } template tuple& operator=(const ::std::pair& p) { f0_ = p.first; f1_ = p.second; return *this; } GTEST_DECLARE_TUPLE_AS_FRIEND_ template tuple& CopyFrom(const GTEST_2_TUPLE_(U)& t) { f0_ = t.f0_; f1_ = t.f1_; return *this; } T0 f0_; T1 f1_; }; template class GTEST_3_TUPLE_(T) { public: template friend class gtest_internal::Get; tuple() : f0_(), f1_(), f2_() {} explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, GTEST_BY_REF_(T2) f2) : f0_(f0), f1_(f1), f2_(f2) {} tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_) {} template tuple(const GTEST_3_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_) {} tuple& operator=(const tuple& t) { return CopyFrom(t); } template tuple& operator=(const GTEST_3_TUPLE_(U)& t) { return CopyFrom(t); } GTEST_DECLARE_TUPLE_AS_FRIEND_ template tuple& CopyFrom(const GTEST_3_TUPLE_(U)& t) { f0_ = t.f0_; f1_ = t.f1_; f2_ = t.f2_; return *this; } T0 f0_; T1 f1_; T2 f2_; }; template class GTEST_4_TUPLE_(T) { public: template friend class gtest_internal::Get; tuple() : f0_(), f1_(), f2_(), f3_() {} explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3) : f0_(f0), f1_(f1), f2_(f2), f3_(f3) {} tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_) {} template tuple(const GTEST_4_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_) {} tuple& operator=(const tuple& t) { return CopyFrom(t); } template tuple& operator=(const GTEST_4_TUPLE_(U)& t) { return CopyFrom(t); } GTEST_DECLARE_TUPLE_AS_FRIEND_ template tuple& CopyFrom(const GTEST_4_TUPLE_(U)& t) { f0_ = t.f0_; f1_ = t.f1_; f2_ = t.f2_; f3_ = t.f3_; return *this; } T0 f0_; T1 f1_; T2 f2_; T3 f3_; }; template class GTEST_5_TUPLE_(T) { public: template friend class gtest_internal::Get; tuple() : f0_(), f1_(), f2_(), f3_(), f4_() {} explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4) {} tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), f4_(t.f4_) {} template tuple(const GTEST_5_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), f4_(t.f4_) {} tuple& operator=(const tuple& t) { return CopyFrom(t); } template tuple& operator=(const GTEST_5_TUPLE_(U)& t) { return CopyFrom(t); } GTEST_DECLARE_TUPLE_AS_FRIEND_ template tuple& CopyFrom(const GTEST_5_TUPLE_(U)& t) { f0_ = t.f0_; f1_ = t.f1_; f2_ = t.f2_; f3_ = t.f3_; f4_ = t.f4_; return *this; } T0 f0_; T1 f1_; T2 f2_; T3 f3_; T4 f4_; }; template class GTEST_6_TUPLE_(T) { public: template friend class gtest_internal::Get; tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_() {} explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4, GTEST_BY_REF_(T5) f5) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4), f5_(f5) {} tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), f4_(t.f4_), f5_(t.f5_) {} template tuple(const GTEST_6_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), f4_(t.f4_), f5_(t.f5_) {} tuple& operator=(const tuple& t) { return CopyFrom(t); } template tuple& operator=(const GTEST_6_TUPLE_(U)& t) { return CopyFrom(t); } GTEST_DECLARE_TUPLE_AS_FRIEND_ template tuple& CopyFrom(const GTEST_6_TUPLE_(U)& t) { f0_ = t.f0_; f1_ = t.f1_; f2_ = t.f2_; f3_ = t.f3_; f4_ = t.f4_; f5_ = t.f5_; return *this; } T0 f0_; T1 f1_; T2 f2_; T3 f3_; T4 f4_; T5 f5_; }; template class GTEST_7_TUPLE_(T) { public: template friend class gtest_internal::Get; tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_(), f6_() {} explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4, GTEST_BY_REF_(T5) f5, GTEST_BY_REF_(T6) f6) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4), f5_(f5), f6_(f6) {} tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_) {} template tuple(const GTEST_7_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_) {} tuple& operator=(const tuple& t) { return CopyFrom(t); } template tuple& operator=(const GTEST_7_TUPLE_(U)& t) { return CopyFrom(t); } GTEST_DECLARE_TUPLE_AS_FRIEND_ template tuple& CopyFrom(const GTEST_7_TUPLE_(U)& t) { f0_ = t.f0_; f1_ = t.f1_; f2_ = t.f2_; f3_ = t.f3_; f4_ = t.f4_; f5_ = t.f5_; f6_ = t.f6_; return *this; } T0 f0_; T1 f1_; T2 f2_; T3 f3_; T4 f4_; T5 f5_; T6 f6_; }; template class GTEST_8_TUPLE_(T) { public: template friend class gtest_internal::Get; tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_(), f6_(), f7_() {} explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4, GTEST_BY_REF_(T5) f5, GTEST_BY_REF_(T6) f6, GTEST_BY_REF_(T7) f7) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4), f5_(f5), f6_(f6), f7_(f7) {} tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_) {} template tuple(const GTEST_8_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_) {} tuple& operator=(const tuple& t) { return CopyFrom(t); } template tuple& operator=(const GTEST_8_TUPLE_(U)& t) { return CopyFrom(t); } GTEST_DECLARE_TUPLE_AS_FRIEND_ template tuple& CopyFrom(const GTEST_8_TUPLE_(U)& t) { f0_ = t.f0_; f1_ = t.f1_; f2_ = t.f2_; f3_ = t.f3_; f4_ = t.f4_; f5_ = t.f5_; f6_ = t.f6_; f7_ = t.f7_; return *this; } T0 f0_; T1 f1_; T2 f2_; T3 f3_; T4 f4_; T5 f5_; T6 f6_; T7 f7_; }; template class GTEST_9_TUPLE_(T) { public: template friend class gtest_internal::Get; tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_(), f6_(), f7_(), f8_() {} explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4, GTEST_BY_REF_(T5) f5, GTEST_BY_REF_(T6) f6, GTEST_BY_REF_(T7) f7, GTEST_BY_REF_(T8) f8) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4), f5_(f5), f6_(f6), f7_(f7), f8_(f8) {} tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_), f8_(t.f8_) {} template tuple(const GTEST_9_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_), f8_(t.f8_) {} tuple& operator=(const tuple& t) { return CopyFrom(t); } template tuple& operator=(const GTEST_9_TUPLE_(U)& t) { return CopyFrom(t); } GTEST_DECLARE_TUPLE_AS_FRIEND_ template tuple& CopyFrom(const GTEST_9_TUPLE_(U)& t) { f0_ = t.f0_; f1_ = t.f1_; f2_ = t.f2_; f3_ = t.f3_; f4_ = t.f4_; f5_ = t.f5_; f6_ = t.f6_; f7_ = t.f7_; f8_ = t.f8_; return *this; } T0 f0_; T1 f1_; T2 f2_; T3 f3_; T4 f4_; T5 f5_; T6 f6_; T7 f7_; T8 f8_; }; template class tuple { public: template friend class gtest_internal::Get; tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_(), f6_(), f7_(), f8_(), f9_() {} explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4, GTEST_BY_REF_(T5) f5, GTEST_BY_REF_(T6) f6, GTEST_BY_REF_(T7) f7, GTEST_BY_REF_(T8) f8, GTEST_BY_REF_(T9) f9) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4), f5_(f5), f6_(f6), f7_(f7), f8_(f8), f9_(f9) {} tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_), f8_(t.f8_), f9_(t.f9_) {} template tuple(const GTEST_10_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_), f8_(t.f8_), f9_(t.f9_) {} tuple& operator=(const tuple& t) { return CopyFrom(t); } template tuple& operator=(const GTEST_10_TUPLE_(U)& t) { return CopyFrom(t); } GTEST_DECLARE_TUPLE_AS_FRIEND_ template tuple& CopyFrom(const GTEST_10_TUPLE_(U)& t) { f0_ = t.f0_; f1_ = t.f1_; f2_ = t.f2_; f3_ = t.f3_; f4_ = t.f4_; f5_ = t.f5_; f6_ = t.f6_; f7_ = t.f7_; f8_ = t.f8_; f9_ = t.f9_; return *this; } T0 f0_; T1 f1_; T2 f2_; T3 f3_; T4 f4_; T5 f5_; T6 f6_; T7 f7_; T8 f8_; T9 f9_; }; // 6.1.3.2 Tuple creation functions. // Known limitations: we don't support passing an // std::tr1::reference_wrapper to make_tuple(). And we don't // implement tie(). inline tuple<> make_tuple() { return tuple<>(); } template inline GTEST_1_TUPLE_(T) make_tuple(const T0& f0) { return GTEST_1_TUPLE_(T)(f0); } template inline GTEST_2_TUPLE_(T) make_tuple(const T0& f0, const T1& f1) { return GTEST_2_TUPLE_(T)(f0, f1); } template inline GTEST_3_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2) { return GTEST_3_TUPLE_(T)(f0, f1, f2); } template inline GTEST_4_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2, const T3& f3) { return GTEST_4_TUPLE_(T)(f0, f1, f2, f3); } template inline GTEST_5_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2, const T3& f3, const T4& f4) { return GTEST_5_TUPLE_(T)(f0, f1, f2, f3, f4); } template inline GTEST_6_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2, const T3& f3, const T4& f4, const T5& f5) { return GTEST_6_TUPLE_(T)(f0, f1, f2, f3, f4, f5); } template inline GTEST_7_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2, const T3& f3, const T4& f4, const T5& f5, const T6& f6) { return GTEST_7_TUPLE_(T)(f0, f1, f2, f3, f4, f5, f6); } template inline GTEST_8_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2, const T3& f3, const T4& f4, const T5& f5, const T6& f6, const T7& f7) { return GTEST_8_TUPLE_(T)(f0, f1, f2, f3, f4, f5, f6, f7); } template inline GTEST_9_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2, const T3& f3, const T4& f4, const T5& f5, const T6& f6, const T7& f7, const T8& f8) { return GTEST_9_TUPLE_(T)(f0, f1, f2, f3, f4, f5, f6, f7, f8); } template inline GTEST_10_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2, const T3& f3, const T4& f4, const T5& f5, const T6& f6, const T7& f7, const T8& f8, const T9& f9) { return GTEST_10_TUPLE_(T)(f0, f1, f2, f3, f4, f5, f6, f7, f8, f9); } // 6.1.3.3 Tuple helper classes. template struct tuple_size; template struct tuple_size { static const int value = 0; }; template struct tuple_size { static const int value = 1; }; template struct tuple_size { static const int value = 2; }; template struct tuple_size { static const int value = 3; }; template struct tuple_size { static const int value = 4; }; template struct tuple_size { static const int value = 5; }; template struct tuple_size { static const int value = 6; }; template struct tuple_size { static const int value = 7; }; template struct tuple_size { static const int value = 8; }; template struct tuple_size { static const int value = 9; }; template struct tuple_size { static const int value = 10; }; template struct tuple_element { typedef typename gtest_internal::TupleElement< k < (tuple_size::value), k, Tuple>::type type; }; #define GTEST_TUPLE_ELEMENT_(k, Tuple) typename tuple_element::type // 6.1.3.4 Element access. namespace gtest_internal { template <> class Get<0> { public: template static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(0, Tuple)) Field(Tuple& t) { return t.f0_; } // NOLINT template static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(0, Tuple)) ConstField(const Tuple& t) { return t.f0_; } }; template <> class Get<1> { public: template static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(1, Tuple)) Field(Tuple& t) { return t.f1_; } // NOLINT template static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(1, Tuple)) ConstField(const Tuple& t) { return t.f1_; } }; template <> class Get<2> { public: template static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(2, Tuple)) Field(Tuple& t) { return t.f2_; } // NOLINT template static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(2, Tuple)) ConstField(const Tuple& t) { return t.f2_; } }; template <> class Get<3> { public: template static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(3, Tuple)) Field(Tuple& t) { return t.f3_; } // NOLINT template static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(3, Tuple)) ConstField(const Tuple& t) { return t.f3_; } }; template <> class Get<4> { public: template static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(4, Tuple)) Field(Tuple& t) { return t.f4_; } // NOLINT template static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(4, Tuple)) ConstField(const Tuple& t) { return t.f4_; } }; template <> class Get<5> { public: template static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(5, Tuple)) Field(Tuple& t) { return t.f5_; } // NOLINT template static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(5, Tuple)) ConstField(const Tuple& t) { return t.f5_; } }; template <> class Get<6> { public: template static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(6, Tuple)) Field(Tuple& t) { return t.f6_; } // NOLINT template static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(6, Tuple)) ConstField(const Tuple& t) { return t.f6_; } }; template <> class Get<7> { public: template static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(7, Tuple)) Field(Tuple& t) { return t.f7_; } // NOLINT template static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(7, Tuple)) ConstField(const Tuple& t) { return t.f7_; } }; template <> class Get<8> { public: template static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(8, Tuple)) Field(Tuple& t) { return t.f8_; } // NOLINT template static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(8, Tuple)) ConstField(const Tuple& t) { return t.f8_; } }; template <> class Get<9> { public: template static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(9, Tuple)) Field(Tuple& t) { return t.f9_; } // NOLINT template static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(9, Tuple)) ConstField(const Tuple& t) { return t.f9_; } }; } // namespace gtest_internal template GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(k, GTEST_10_TUPLE_(T))) get(GTEST_10_TUPLE_(T)& t) { return gtest_internal::Get::Field(t); } template GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(k, GTEST_10_TUPLE_(T))) get(const GTEST_10_TUPLE_(T)& t) { return gtest_internal::Get::ConstField(t); } // 6.1.3.5 Relational operators // We only implement == and !=, as we don't have a need for the rest yet. namespace gtest_internal { // SameSizeTuplePrefixComparator::Eq(t1, t2) returns true if the // first k fields of t1 equals the first k fields of t2. // SameSizeTuplePrefixComparator(k1, k2) would be a compiler error if // k1 != k2. template struct SameSizeTuplePrefixComparator; template <> struct SameSizeTuplePrefixComparator<0, 0> { template static bool Eq(const Tuple1& /* t1 */, const Tuple2& /* t2 */) { return true; } }; template struct SameSizeTuplePrefixComparator { template static bool Eq(const Tuple1& t1, const Tuple2& t2) { return SameSizeTuplePrefixComparator::Eq(t1, t2) && ::std::tr1::get(t1) == ::std::tr1::get(t2); } }; } // namespace gtest_internal template inline bool operator==(const GTEST_10_TUPLE_(T)& t, const GTEST_10_TUPLE_(U)& u) { return gtest_internal::SameSizeTuplePrefixComparator< tuple_size::value, tuple_size::value>::Eq(t, u); } template inline bool operator!=(const GTEST_10_TUPLE_(T)& t, const GTEST_10_TUPLE_(U)& u) { return !(t == u); } // 6.1.4 Pairs. // Unimplemented. } // namespace tr1 } // namespace std #undef GTEST_0_TUPLE_ #undef GTEST_1_TUPLE_ #undef GTEST_2_TUPLE_ #undef GTEST_3_TUPLE_ #undef GTEST_4_TUPLE_ #undef GTEST_5_TUPLE_ #undef GTEST_6_TUPLE_ #undef GTEST_7_TUPLE_ #undef GTEST_8_TUPLE_ #undef GTEST_9_TUPLE_ #undef GTEST_10_TUPLE_ #undef GTEST_0_TYPENAMES_ #undef GTEST_1_TYPENAMES_ #undef GTEST_2_TYPENAMES_ #undef GTEST_3_TYPENAMES_ #undef GTEST_4_TYPENAMES_ #undef GTEST_5_TYPENAMES_ #undef GTEST_6_TYPENAMES_ #undef GTEST_7_TYPENAMES_ #undef GTEST_8_TYPENAMES_ #undef GTEST_9_TYPENAMES_ #undef GTEST_10_TYPENAMES_ #undef GTEST_DECLARE_TUPLE_AS_FRIEND_ #undef GTEST_BY_REF_ #undef GTEST_ADD_REF_ #undef GTEST_TUPLE_ELEMENT_ #endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_ dlt-daemon-2.18.4/gtest-1.7.0/include/gtest/internal/gtest-tuple.h.pump000066400000000000000000000220121353342203500254110ustar00rootroot00000000000000$$ -*- mode: c++; -*- $var n = 10 $$ Maximum number of tuple fields we want to support. $$ This meta comment fixes auto-indentation in Emacs. }} // Copyright 2009 Google Inc. // All Rights Reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: wan@google.com (Zhanyong Wan) // Implements a subset of TR1 tuple needed by Google Test and Google Mock. #ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_ #define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_ #include // For ::std::pair. // The compiler used in Symbian has a bug that prevents us from declaring the // tuple template as a friend (it complains that tuple is redefined). This // hack bypasses the bug by declaring the members that should otherwise be // private as public. // Sun Studio versions < 12 also have the above bug. #if defined(__SYMBIAN32__) || (defined(__SUNPRO_CC) && __SUNPRO_CC < 0x590) # define GTEST_DECLARE_TUPLE_AS_FRIEND_ public: #else # define GTEST_DECLARE_TUPLE_AS_FRIEND_ \ template friend class tuple; \ private: #endif $range i 0..n-1 $range j 0..n $range k 1..n // GTEST_n_TUPLE_(T) is the type of an n-tuple. #define GTEST_0_TUPLE_(T) tuple<> $for k [[ $range m 0..k-1 $range m2 k..n-1 #define GTEST_$(k)_TUPLE_(T) tuple<$for m, [[T##$m]]$for m2 [[, void]]> ]] // GTEST_n_TYPENAMES_(T) declares a list of n typenames. $for j [[ $range m 0..j-1 #define GTEST_$(j)_TYPENAMES_(T) $for m, [[typename T##$m]] ]] // In theory, defining stuff in the ::std namespace is undefined // behavior. We can do this as we are playing the role of a standard // library vendor. namespace std { namespace tr1 { template <$for i, [[typename T$i = void]]> class tuple; // Anything in namespace gtest_internal is Google Test's INTERNAL // IMPLEMENTATION DETAIL and MUST NOT BE USED DIRECTLY in user code. namespace gtest_internal { // ByRef::type is T if T is a reference; otherwise it's const T&. template struct ByRef { typedef const T& type; }; // NOLINT template struct ByRef { typedef T& type; }; // NOLINT // A handy wrapper for ByRef. #define GTEST_BY_REF_(T) typename ::std::tr1::gtest_internal::ByRef::type // AddRef::type is T if T is a reference; otherwise it's T&. This // is the same as tr1::add_reference::type. template struct AddRef { typedef T& type; }; // NOLINT template struct AddRef { typedef T& type; }; // NOLINT // A handy wrapper for AddRef. #define GTEST_ADD_REF_(T) typename ::std::tr1::gtest_internal::AddRef::type // A helper for implementing get(). template class Get; // A helper for implementing tuple_element. kIndexValid is true // iff k < the number of fields in tuple type T. template struct TupleElement; $for i [[ template struct TupleElement { typedef T$i type; }; ]] } // namespace gtest_internal template <> class tuple<> { public: tuple() {} tuple(const tuple& /* t */) {} tuple& operator=(const tuple& /* t */) { return *this; } }; $for k [[ $range m 0..k-1 template class $if k < n [[GTEST_$(k)_TUPLE_(T)]] $else [[tuple]] { public: template friend class gtest_internal::Get; tuple() : $for m, [[f$(m)_()]] {} explicit tuple($for m, [[GTEST_BY_REF_(T$m) f$m]]) : [[]] $for m, [[f$(m)_(f$m)]] {} tuple(const tuple& t) : $for m, [[f$(m)_(t.f$(m)_)]] {} template tuple(const GTEST_$(k)_TUPLE_(U)& t) : $for m, [[f$(m)_(t.f$(m)_)]] {} $if k == 2 [[ template tuple(const ::std::pair& p) : f0_(p.first), f1_(p.second) {} ]] tuple& operator=(const tuple& t) { return CopyFrom(t); } template tuple& operator=(const GTEST_$(k)_TUPLE_(U)& t) { return CopyFrom(t); } $if k == 2 [[ template tuple& operator=(const ::std::pair& p) { f0_ = p.first; f1_ = p.second; return *this; } ]] GTEST_DECLARE_TUPLE_AS_FRIEND_ template tuple& CopyFrom(const GTEST_$(k)_TUPLE_(U)& t) { $for m [[ f$(m)_ = t.f$(m)_; ]] return *this; } $for m [[ T$m f$(m)_; ]] }; ]] // 6.1.3.2 Tuple creation functions. // Known limitations: we don't support passing an // std::tr1::reference_wrapper to make_tuple(). And we don't // implement tie(). inline tuple<> make_tuple() { return tuple<>(); } $for k [[ $range m 0..k-1 template inline GTEST_$(k)_TUPLE_(T) make_tuple($for m, [[const T$m& f$m]]) { return GTEST_$(k)_TUPLE_(T)($for m, [[f$m]]); } ]] // 6.1.3.3 Tuple helper classes. template struct tuple_size; $for j [[ template struct tuple_size { static const int value = $j; }; ]] template struct tuple_element { typedef typename gtest_internal::TupleElement< k < (tuple_size::value), k, Tuple>::type type; }; #define GTEST_TUPLE_ELEMENT_(k, Tuple) typename tuple_element::type // 6.1.3.4 Element access. namespace gtest_internal { $for i [[ template <> class Get<$i> { public: template static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_($i, Tuple)) Field(Tuple& t) { return t.f$(i)_; } // NOLINT template static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_($i, Tuple)) ConstField(const Tuple& t) { return t.f$(i)_; } }; ]] } // namespace gtest_internal template GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(k, GTEST_$(n)_TUPLE_(T))) get(GTEST_$(n)_TUPLE_(T)& t) { return gtest_internal::Get::Field(t); } template GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(k, GTEST_$(n)_TUPLE_(T))) get(const GTEST_$(n)_TUPLE_(T)& t) { return gtest_internal::Get::ConstField(t); } // 6.1.3.5 Relational operators // We only implement == and !=, as we don't have a need for the rest yet. namespace gtest_internal { // SameSizeTuplePrefixComparator::Eq(t1, t2) returns true if the // first k fields of t1 equals the first k fields of t2. // SameSizeTuplePrefixComparator(k1, k2) would be a compiler error if // k1 != k2. template struct SameSizeTuplePrefixComparator; template <> struct SameSizeTuplePrefixComparator<0, 0> { template static bool Eq(const Tuple1& /* t1 */, const Tuple2& /* t2 */) { return true; } }; template struct SameSizeTuplePrefixComparator { template static bool Eq(const Tuple1& t1, const Tuple2& t2) { return SameSizeTuplePrefixComparator::Eq(t1, t2) && ::std::tr1::get(t1) == ::std::tr1::get(t2); } }; } // namespace gtest_internal template inline bool operator==(const GTEST_$(n)_TUPLE_(T)& t, const GTEST_$(n)_TUPLE_(U)& u) { return gtest_internal::SameSizeTuplePrefixComparator< tuple_size::value, tuple_size::value>::Eq(t, u); } template inline bool operator!=(const GTEST_$(n)_TUPLE_(T)& t, const GTEST_$(n)_TUPLE_(U)& u) { return !(t == u); } // 6.1.4 Pairs. // Unimplemented. } // namespace tr1 } // namespace std $for j [[ #undef GTEST_$(j)_TUPLE_ ]] $for j [[ #undef GTEST_$(j)_TYPENAMES_ ]] #undef GTEST_DECLARE_TUPLE_AS_FRIEND_ #undef GTEST_BY_REF_ #undef GTEST_ADD_REF_ #undef GTEST_TUPLE_ELEMENT_ #endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_ dlt-daemon-2.18.4/gtest-1.7.0/include/gtest/internal/gtest-type-util.h000066400000000000000000005525021353342203500252500ustar00rootroot00000000000000// This file was GENERATED by command: // pump.py gtest-type-util.h.pump // DO NOT EDIT BY HAND!!! // Copyright 2008 Google Inc. // All Rights Reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: wan@google.com (Zhanyong Wan) // Type utilities needed for implementing typed and type-parameterized // tests. This file is generated by a SCRIPT. DO NOT EDIT BY HAND! // // Currently we support at most 50 types in a list, and at most 50 // type-parameterized tests in one type-parameterized test case. // Please contact googletestframework@googlegroups.com if you need // more. #ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_ #define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_ #include "gtest/internal/gtest-port.h" // #ifdef __GNUC__ is too general here. It is possible to use gcc without using // libstdc++ (which is where cxxabi.h comes from). # if GTEST_HAS_CXXABI_H_ # include # elif defined(__HP_aCC) # include # endif // GTEST_HASH_CXXABI_H_ namespace testing { namespace internal { // GetTypeName() returns a human-readable name of type T. // NB: This function is also used in Google Mock, so don't move it inside of // the typed-test-only section below. template std::string GetTypeName() { # if GTEST_HAS_RTTI const char* const name = typeid(T).name(); # if GTEST_HAS_CXXABI_H_ || defined(__HP_aCC) int status = 0; // gcc's implementation of typeid(T).name() mangles the type name, // so we have to demangle it. # if GTEST_HAS_CXXABI_H_ using abi::__cxa_demangle; # endif // GTEST_HAS_CXXABI_H_ char* const readable_name = __cxa_demangle(name, 0, 0, &status); const std::string name_str(status == 0 ? readable_name : name); free(readable_name); return name_str; # else return name; # endif // GTEST_HAS_CXXABI_H_ || __HP_aCC # else return ""; # endif // GTEST_HAS_RTTI } #if GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P // AssertyTypeEq::type is defined iff T1 and T2 are the same // type. This can be used as a compile-time assertion to ensure that // two types are equal. template struct AssertTypeEq; template struct AssertTypeEq { typedef bool type; }; // A unique type used as the default value for the arguments of class // template Types. This allows us to simulate variadic templates // (e.g. Types, Type, and etc), which C++ doesn't // support directly. struct None {}; // The following family of struct and struct templates are used to // represent type lists. In particular, TypesN // represents a type list with N types (T1, T2, ..., and TN) in it. // Except for Types0, every struct in the family has two member types: // Head for the first type in the list, and Tail for the rest of the // list. // The empty type list. struct Types0 {}; // Type lists of length 1, 2, 3, and so on. template struct Types1 { typedef T1 Head; typedef Types0 Tail; }; template struct Types2 { typedef T1 Head; typedef Types1 Tail; }; template struct Types3 { typedef T1 Head; typedef Types2 Tail; }; template struct Types4 { typedef T1 Head; typedef Types3 Tail; }; template struct Types5 { typedef T1 Head; typedef Types4 Tail; }; template struct Types6 { typedef T1 Head; typedef Types5 Tail; }; template struct Types7 { typedef T1 Head; typedef Types6 Tail; }; template struct Types8 { typedef T1 Head; typedef Types7 Tail; }; template struct Types9 { typedef T1 Head; typedef Types8 Tail; }; template struct Types10 { typedef T1 Head; typedef Types9 Tail; }; template struct Types11 { typedef T1 Head; typedef Types10 Tail; }; template struct Types12 { typedef T1 Head; typedef Types11 Tail; }; template struct Types13 { typedef T1 Head; typedef Types12 Tail; }; template struct Types14 { typedef T1 Head; typedef Types13 Tail; }; template struct Types15 { typedef T1 Head; typedef Types14 Tail; }; template struct Types16 { typedef T1 Head; typedef Types15 Tail; }; template struct Types17 { typedef T1 Head; typedef Types16 Tail; }; template struct Types18 { typedef T1 Head; typedef Types17 Tail; }; template struct Types19 { typedef T1 Head; typedef Types18 Tail; }; template struct Types20 { typedef T1 Head; typedef Types19 Tail; }; template struct Types21 { typedef T1 Head; typedef Types20 Tail; }; template struct Types22 { typedef T1 Head; typedef Types21 Tail; }; template struct Types23 { typedef T1 Head; typedef Types22 Tail; }; template struct Types24 { typedef T1 Head; typedef Types23 Tail; }; template struct Types25 { typedef T1 Head; typedef Types24 Tail; }; template struct Types26 { typedef T1 Head; typedef Types25 Tail; }; template struct Types27 { typedef T1 Head; typedef Types26 Tail; }; template struct Types28 { typedef T1 Head; typedef Types27 Tail; }; template struct Types29 { typedef T1 Head; typedef Types28 Tail; }; template struct Types30 { typedef T1 Head; typedef Types29 Tail; }; template struct Types31 { typedef T1 Head; typedef Types30 Tail; }; template struct Types32 { typedef T1 Head; typedef Types31 Tail; }; template struct Types33 { typedef T1 Head; typedef Types32 Tail; }; template struct Types34 { typedef T1 Head; typedef Types33 Tail; }; template struct Types35 { typedef T1 Head; typedef Types34 Tail; }; template struct Types36 { typedef T1 Head; typedef Types35 Tail; }; template struct Types37 { typedef T1 Head; typedef Types36 Tail; }; template struct Types38 { typedef T1 Head; typedef Types37 Tail; }; template struct Types39 { typedef T1 Head; typedef Types38 Tail; }; template struct Types40 { typedef T1 Head; typedef Types39 Tail; }; template struct Types41 { typedef T1 Head; typedef Types40 Tail; }; template struct Types42 { typedef T1 Head; typedef Types41 Tail; }; template struct Types43 { typedef T1 Head; typedef Types42 Tail; }; template struct Types44 { typedef T1 Head; typedef Types43 Tail; }; template struct Types45 { typedef T1 Head; typedef Types44 Tail; }; template struct Types46 { typedef T1 Head; typedef Types45 Tail; }; template struct Types47 { typedef T1 Head; typedef Types46 Tail; }; template struct Types48 { typedef T1 Head; typedef Types47 Tail; }; template struct Types49 { typedef T1 Head; typedef Types48 Tail; }; template struct Types50 { typedef T1 Head; typedef Types49 Tail; }; } // namespace internal // We don't want to require the users to write TypesN<...> directly, // as that would require them to count the length. Types<...> is much // easier to write, but generates horrible messages when there is a // compiler error, as gcc insists on printing out each template // argument, even if it has the default value (this means Types // will appear as Types in the compiler // errors). // // Our solution is to combine the best part of the two approaches: a // user would write Types, and Google Test will translate // that to TypesN internally to make error messages // readable. The translation is done by the 'type' member of the // Types template. template struct Types { typedef internal::Types50 type; }; template <> struct Types { typedef internal::Types0 type; }; template struct Types { typedef internal::Types1 type; }; template struct Types { typedef internal::Types2 type; }; template struct Types { typedef internal::Types3 type; }; template struct Types { typedef internal::Types4 type; }; template struct Types { typedef internal::Types5 type; }; template struct Types { typedef internal::Types6 type; }; template struct Types { typedef internal::Types7 type; }; template struct Types { typedef internal::Types8 type; }; template struct Types { typedef internal::Types9 type; }; template struct Types { typedef internal::Types10 type; }; template struct Types { typedef internal::Types11 type; }; template struct Types { typedef internal::Types12 type; }; template struct Types { typedef internal::Types13 type; }; template struct Types { typedef internal::Types14 type; }; template struct Types { typedef internal::Types15 type; }; template struct Types { typedef internal::Types16 type; }; template struct Types { typedef internal::Types17 type; }; template struct Types { typedef internal::Types18 type; }; template struct Types { typedef internal::Types19 type; }; template struct Types { typedef internal::Types20 type; }; template struct Types { typedef internal::Types21 type; }; template struct Types { typedef internal::Types22 type; }; template struct Types { typedef internal::Types23 type; }; template struct Types { typedef internal::Types24 type; }; template struct Types { typedef internal::Types25 type; }; template struct Types { typedef internal::Types26 type; }; template struct Types { typedef internal::Types27 type; }; template struct Types { typedef internal::Types28 type; }; template struct Types { typedef internal::Types29 type; }; template struct Types { typedef internal::Types30 type; }; template struct Types { typedef internal::Types31 type; }; template struct Types { typedef internal::Types32 type; }; template struct Types { typedef internal::Types33 type; }; template struct Types { typedef internal::Types34 type; }; template struct Types { typedef internal::Types35 type; }; template struct Types { typedef internal::Types36 type; }; template struct Types { typedef internal::Types37 type; }; template struct Types { typedef internal::Types38 type; }; template struct Types { typedef internal::Types39 type; }; template struct Types { typedef internal::Types40 type; }; template struct Types { typedef internal::Types41 type; }; template struct Types { typedef internal::Types42 type; }; template struct Types { typedef internal::Types43 type; }; template struct Types { typedef internal::Types44 type; }; template struct Types { typedef internal::Types45 type; }; template struct Types { typedef internal::Types46 type; }; template struct Types { typedef internal::Types47 type; }; template struct Types { typedef internal::Types48 type; }; template struct Types { typedef internal::Types49 type; }; namespace internal { # define GTEST_TEMPLATE_ template class // The template "selector" struct TemplateSel is used to // represent Tmpl, which must be a class template with one type // parameter, as a type. TemplateSel::Bind::type is defined // as the type Tmpl. This allows us to actually instantiate the // template "selected" by TemplateSel. // // This trick is necessary for simulating typedef for class templates, // which C++ doesn't support directly. template struct TemplateSel { template struct Bind { typedef Tmpl type; }; }; # define GTEST_BIND_(TmplSel, T) \ TmplSel::template Bind::type // A unique struct template used as the default value for the // arguments of class template Templates. This allows us to simulate // variadic templates (e.g. Templates, Templates, // and etc), which C++ doesn't support directly. template struct NoneT {}; // The following family of struct and struct templates are used to // represent template lists. In particular, TemplatesN represents a list of N templates (T1, T2, ..., and TN). Except // for Templates0, every struct in the family has two member types: // Head for the selector of the first template in the list, and Tail // for the rest of the list. // The empty template list. struct Templates0 {}; // Template lists of length 1, 2, 3, and so on. template struct Templates1 { typedef TemplateSel Head; typedef Templates0 Tail; }; template struct Templates2 { typedef TemplateSel Head; typedef Templates1 Tail; }; template struct Templates3 { typedef TemplateSel Head; typedef Templates2 Tail; }; template struct Templates4 { typedef TemplateSel Head; typedef Templates3 Tail; }; template struct Templates5 { typedef TemplateSel Head; typedef Templates4 Tail; }; template struct Templates6 { typedef TemplateSel Head; typedef Templates5 Tail; }; template struct Templates7 { typedef TemplateSel Head; typedef Templates6 Tail; }; template struct Templates8 { typedef TemplateSel Head; typedef Templates7 Tail; }; template struct Templates9 { typedef TemplateSel Head; typedef Templates8 Tail; }; template struct Templates10 { typedef TemplateSel Head; typedef Templates9 Tail; }; template struct Templates11 { typedef TemplateSel Head; typedef Templates10 Tail; }; template struct Templates12 { typedef TemplateSel Head; typedef Templates11 Tail; }; template struct Templates13 { typedef TemplateSel Head; typedef Templates12 Tail; }; template struct Templates14 { typedef TemplateSel Head; typedef Templates13 Tail; }; template struct Templates15 { typedef TemplateSel Head; typedef Templates14 Tail; }; template struct Templates16 { typedef TemplateSel Head; typedef Templates15 Tail; }; template struct Templates17 { typedef TemplateSel Head; typedef Templates16 Tail; }; template struct Templates18 { typedef TemplateSel Head; typedef Templates17 Tail; }; template struct Templates19 { typedef TemplateSel Head; typedef Templates18 Tail; }; template struct Templates20 { typedef TemplateSel Head; typedef Templates19 Tail; }; template struct Templates21 { typedef TemplateSel Head; typedef Templates20 Tail; }; template struct Templates22 { typedef TemplateSel Head; typedef Templates21 Tail; }; template struct Templates23 { typedef TemplateSel Head; typedef Templates22 Tail; }; template struct Templates24 { typedef TemplateSel Head; typedef Templates23 Tail; }; template struct Templates25 { typedef TemplateSel Head; typedef Templates24 Tail; }; template struct Templates26 { typedef TemplateSel Head; typedef Templates25 Tail; }; template struct Templates27 { typedef TemplateSel Head; typedef Templates26 Tail; }; template struct Templates28 { typedef TemplateSel Head; typedef Templates27 Tail; }; template struct Templates29 { typedef TemplateSel Head; typedef Templates28 Tail; }; template struct Templates30 { typedef TemplateSel Head; typedef Templates29 Tail; }; template struct Templates31 { typedef TemplateSel Head; typedef Templates30 Tail; }; template struct Templates32 { typedef TemplateSel Head; typedef Templates31 Tail; }; template struct Templates33 { typedef TemplateSel Head; typedef Templates32 Tail; }; template struct Templates34 { typedef TemplateSel Head; typedef Templates33 Tail; }; template struct Templates35 { typedef TemplateSel Head; typedef Templates34 Tail; }; template struct Templates36 { typedef TemplateSel Head; typedef Templates35 Tail; }; template struct Templates37 { typedef TemplateSel Head; typedef Templates36 Tail; }; template struct Templates38 { typedef TemplateSel Head; typedef Templates37 Tail; }; template struct Templates39 { typedef TemplateSel Head; typedef Templates38 Tail; }; template struct Templates40 { typedef TemplateSel Head; typedef Templates39 Tail; }; template struct Templates41 { typedef TemplateSel Head; typedef Templates40 Tail; }; template struct Templates42 { typedef TemplateSel Head; typedef Templates41 Tail; }; template struct Templates43 { typedef TemplateSel Head; typedef Templates42 Tail; }; template struct Templates44 { typedef TemplateSel Head; typedef Templates43 Tail; }; template struct Templates45 { typedef TemplateSel Head; typedef Templates44 Tail; }; template struct Templates46 { typedef TemplateSel Head; typedef Templates45 Tail; }; template struct Templates47 { typedef TemplateSel Head; typedef Templates46 Tail; }; template struct Templates48 { typedef TemplateSel Head; typedef Templates47 Tail; }; template struct Templates49 { typedef TemplateSel Head; typedef Templates48 Tail; }; template struct Templates50 { typedef TemplateSel Head; typedef Templates49 Tail; }; // We don't want to require the users to write TemplatesN<...> directly, // as that would require them to count the length. Templates<...> is much // easier to write, but generates horrible messages when there is a // compiler error, as gcc insists on printing out each template // argument, even if it has the default value (this means Templates // will appear as Templates in the compiler // errors). // // Our solution is to combine the best part of the two approaches: a // user would write Templates, and Google Test will translate // that to TemplatesN internally to make error messages // readable. The translation is done by the 'type' member of the // Templates template. template struct Templates { typedef Templates50 type; }; template <> struct Templates { typedef Templates0 type; }; template struct Templates { typedef Templates1 type; }; template struct Templates { typedef Templates2 type; }; template struct Templates { typedef Templates3 type; }; template struct Templates { typedef Templates4 type; }; template struct Templates { typedef Templates5 type; }; template struct Templates { typedef Templates6 type; }; template struct Templates { typedef Templates7 type; }; template struct Templates { typedef Templates8 type; }; template struct Templates { typedef Templates9 type; }; template struct Templates { typedef Templates10 type; }; template struct Templates { typedef Templates11 type; }; template struct Templates { typedef Templates12 type; }; template struct Templates { typedef Templates13 type; }; template struct Templates { typedef Templates14 type; }; template struct Templates { typedef Templates15 type; }; template struct Templates { typedef Templates16 type; }; template struct Templates { typedef Templates17 type; }; template struct Templates { typedef Templates18 type; }; template struct Templates { typedef Templates19 type; }; template struct Templates { typedef Templates20 type; }; template struct Templates { typedef Templates21 type; }; template struct Templates { typedef Templates22 type; }; template struct Templates { typedef Templates23 type; }; template struct Templates { typedef Templates24 type; }; template struct Templates { typedef Templates25 type; }; template struct Templates { typedef Templates26 type; }; template struct Templates { typedef Templates27 type; }; template struct Templates { typedef Templates28 type; }; template struct Templates { typedef Templates29 type; }; template struct Templates { typedef Templates30 type; }; template struct Templates { typedef Templates31 type; }; template struct Templates { typedef Templates32 type; }; template struct Templates { typedef Templates33 type; }; template struct Templates { typedef Templates34 type; }; template struct Templates { typedef Templates35 type; }; template struct Templates { typedef Templates36 type; }; template struct Templates { typedef Templates37 type; }; template struct Templates { typedef Templates38 type; }; template struct Templates { typedef Templates39 type; }; template struct Templates { typedef Templates40 type; }; template struct Templates { typedef Templates41 type; }; template struct Templates { typedef Templates42 type; }; template struct Templates { typedef Templates43 type; }; template struct Templates { typedef Templates44 type; }; template struct Templates { typedef Templates45 type; }; template struct Templates { typedef Templates46 type; }; template struct Templates { typedef Templates47 type; }; template struct Templates { typedef Templates48 type; }; template struct Templates { typedef Templates49 type; }; // The TypeList template makes it possible to use either a single type // or a Types<...> list in TYPED_TEST_CASE() and // INSTANTIATE_TYPED_TEST_CASE_P(). template struct TypeList { typedef Types1 type; }; template struct TypeList > { typedef typename Types::type type; }; #endif // GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P } // namespace internal } // namespace testing #endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_ dlt-daemon-2.18.4/gtest-1.7.0/include/gtest/internal/gtest-type-util.h.pump000066400000000000000000000221451353342203500262230ustar00rootroot00000000000000$$ -*- mode: c++; -*- $var n = 50 $$ Maximum length of type lists we want to support. // Copyright 2008 Google Inc. // All Rights Reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: wan@google.com (Zhanyong Wan) // Type utilities needed for implementing typed and type-parameterized // tests. This file is generated by a SCRIPT. DO NOT EDIT BY HAND! // // Currently we support at most $n types in a list, and at most $n // type-parameterized tests in one type-parameterized test case. // Please contact googletestframework@googlegroups.com if you need // more. #ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_ #define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_ #include "gtest/internal/gtest-port.h" // #ifdef __GNUC__ is too general here. It is possible to use gcc without using // libstdc++ (which is where cxxabi.h comes from). # if GTEST_HAS_CXXABI_H_ # include # elif defined(__HP_aCC) # include # endif // GTEST_HASH_CXXABI_H_ namespace testing { namespace internal { // GetTypeName() returns a human-readable name of type T. // NB: This function is also used in Google Mock, so don't move it inside of // the typed-test-only section below. template std::string GetTypeName() { # if GTEST_HAS_RTTI const char* const name = typeid(T).name(); # if GTEST_HAS_CXXABI_H_ || defined(__HP_aCC) int status = 0; // gcc's implementation of typeid(T).name() mangles the type name, // so we have to demangle it. # if GTEST_HAS_CXXABI_H_ using abi::__cxa_demangle; # endif // GTEST_HAS_CXXABI_H_ char* const readable_name = __cxa_demangle(name, 0, 0, &status); const std::string name_str(status == 0 ? readable_name : name); free(readable_name); return name_str; # else return name; # endif // GTEST_HAS_CXXABI_H_ || __HP_aCC # else return ""; # endif // GTEST_HAS_RTTI } #if GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P // AssertyTypeEq::type is defined iff T1 and T2 are the same // type. This can be used as a compile-time assertion to ensure that // two types are equal. template struct AssertTypeEq; template struct AssertTypeEq { typedef bool type; }; // A unique type used as the default value for the arguments of class // template Types. This allows us to simulate variadic templates // (e.g. Types, Type, and etc), which C++ doesn't // support directly. struct None {}; // The following family of struct and struct templates are used to // represent type lists. In particular, TypesN // represents a type list with N types (T1, T2, ..., and TN) in it. // Except for Types0, every struct in the family has two member types: // Head for the first type in the list, and Tail for the rest of the // list. // The empty type list. struct Types0 {}; // Type lists of length 1, 2, 3, and so on. template struct Types1 { typedef T1 Head; typedef Types0 Tail; }; $range i 2..n $for i [[ $range j 1..i $range k 2..i template <$for j, [[typename T$j]]> struct Types$i { typedef T1 Head; typedef Types$(i-1)<$for k, [[T$k]]> Tail; }; ]] } // namespace internal // We don't want to require the users to write TypesN<...> directly, // as that would require them to count the length. Types<...> is much // easier to write, but generates horrible messages when there is a // compiler error, as gcc insists on printing out each template // argument, even if it has the default value (this means Types // will appear as Types in the compiler // errors). // // Our solution is to combine the best part of the two approaches: a // user would write Types, and Google Test will translate // that to TypesN internally to make error messages // readable. The translation is done by the 'type' member of the // Types template. $range i 1..n template <$for i, [[typename T$i = internal::None]]> struct Types { typedef internal::Types$n<$for i, [[T$i]]> type; }; template <> struct Types<$for i, [[internal::None]]> { typedef internal::Types0 type; }; $range i 1..n-1 $for i [[ $range j 1..i $range k i+1..n template <$for j, [[typename T$j]]> struct Types<$for j, [[T$j]]$for k[[, internal::None]]> { typedef internal::Types$i<$for j, [[T$j]]> type; }; ]] namespace internal { # define GTEST_TEMPLATE_ template class // The template "selector" struct TemplateSel is used to // represent Tmpl, which must be a class template with one type // parameter, as a type. TemplateSel::Bind::type is defined // as the type Tmpl. This allows us to actually instantiate the // template "selected" by TemplateSel. // // This trick is necessary for simulating typedef for class templates, // which C++ doesn't support directly. template struct TemplateSel { template struct Bind { typedef Tmpl type; }; }; # define GTEST_BIND_(TmplSel, T) \ TmplSel::template Bind::type // A unique struct template used as the default value for the // arguments of class template Templates. This allows us to simulate // variadic templates (e.g. Templates, Templates, // and etc), which C++ doesn't support directly. template struct NoneT {}; // The following family of struct and struct templates are used to // represent template lists. In particular, TemplatesN represents a list of N templates (T1, T2, ..., and TN). Except // for Templates0, every struct in the family has two member types: // Head for the selector of the first template in the list, and Tail // for the rest of the list. // The empty template list. struct Templates0 {}; // Template lists of length 1, 2, 3, and so on. template struct Templates1 { typedef TemplateSel Head; typedef Templates0 Tail; }; $range i 2..n $for i [[ $range j 1..i $range k 2..i template <$for j, [[GTEST_TEMPLATE_ T$j]]> struct Templates$i { typedef TemplateSel Head; typedef Templates$(i-1)<$for k, [[T$k]]> Tail; }; ]] // We don't want to require the users to write TemplatesN<...> directly, // as that would require them to count the length. Templates<...> is much // easier to write, but generates horrible messages when there is a // compiler error, as gcc insists on printing out each template // argument, even if it has the default value (this means Templates // will appear as Templates in the compiler // errors). // // Our solution is to combine the best part of the two approaches: a // user would write Templates, and Google Test will translate // that to TemplatesN internally to make error messages // readable. The translation is done by the 'type' member of the // Templates template. $range i 1..n template <$for i, [[GTEST_TEMPLATE_ T$i = NoneT]]> struct Templates { typedef Templates$n<$for i, [[T$i]]> type; }; template <> struct Templates<$for i, [[NoneT]]> { typedef Templates0 type; }; $range i 1..n-1 $for i [[ $range j 1..i $range k i+1..n template <$for j, [[GTEST_TEMPLATE_ T$j]]> struct Templates<$for j, [[T$j]]$for k[[, NoneT]]> { typedef Templates$i<$for j, [[T$j]]> type; }; ]] // The TypeList template makes it possible to use either a single type // or a Types<...> list in TYPED_TEST_CASE() and // INSTANTIATE_TYPED_TEST_CASE_P(). template struct TypeList { typedef Types1 type; }; $range i 1..n template <$for i, [[typename T$i]]> struct TypeList > { typedef typename Types<$for i, [[T$i]]>::type type; }; #endif // GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P } // namespace internal } // namespace testing #endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_ dlt-daemon-2.18.4/gtest-1.7.0/lib/000077500000000000000000000000001353342203500161675ustar00rootroot00000000000000dlt-daemon-2.18.4/gtest-1.7.0/lib/.dirstamp000066400000000000000000000000001353342203500200010ustar00rootroot00000000000000dlt-daemon-2.18.4/gtest-1.7.0/lib/.libs/000077500000000000000000000000001353342203500171765ustar00rootroot00000000000000dlt-daemon-2.18.4/gtest-1.7.0/lib/.libs/libgtest.a000066400000000000000000121647361353342203500212010ustar00rootroot00000000000000! / 1428496271 0 0 0 39338 ` _ZNKSt5ctypeIcE8do_widenEc_ZN7testing8internal26ThreadLocalValueHolderBaseD2Ev_ZN7testing8internal26ThreadLocalValueHolderBaseD1EvDeleteThreadLocalValue_ZN7testing4Test11DeleteSelf_Ev_ZN7testing4Test5SetupEv_ZN7testing8TestCase16RunSetUpTestCaseEv_ZN7testing8TestCase19RunTearDownTestCaseEv_ZN7testing11EnvironmentD2Ev_ZN7testing11EnvironmentD1Ev_ZN7testing11Environment5SetUpEv_ZN7testing11Environment8TearDownEv_ZN7testing11Environment5SetupEv_ZN7testing22EmptyTestEventListener18OnTestProgramStartERKNS_8UnitTestE_ZN7testing22EmptyTestEventListener20OnTestIterationStartERKNS_8UnitTestEi_ZN7testing22EmptyTestEventListener24OnEnvironmentsSetUpStartERKNS_8UnitTestE_ZN7testing22EmptyTestEventListener22OnEnvironmentsSetUpEndERKNS_8UnitTestE_ZN7testing22EmptyTestEventListener15OnTestCaseStartERKNS_8TestCaseE_ZN7testing22EmptyTestEventListener11OnTestStartERKNS_8TestInfoE_ZN7testing22EmptyTestEventListener16OnTestPartResultERKNS_14TestPartResultE_ZN7testing22EmptyTestEventListener9OnTestEndERKNS_8TestInfoE_ZN7testing22EmptyTestEventListener13OnTestCaseEndERKNS_8TestCaseE_ZN7testing22EmptyTestEventListener27OnEnvironmentsTearDownStartERKNS_8UnitTestE_ZN7testing22EmptyTestEventListener25OnEnvironmentsTearDownEndERKNS_8UnitTestE_ZN7testing22EmptyTestEventListener18OnTestIterationEndERKNS_8UnitTestEi_ZN7testing22EmptyTestEventListener16OnTestProgramEndERKNS_8UnitTestE_ZN7testing8internal17StreamingListener20AbstractSocketWriter15CloseConnectionEv_ZN7testing22EmptyTestEventListenerD2Ev_ZN7testing22EmptyTestEventListenerD1Ev_ZN7testing4Test5SetUpEv_ZN7testing4Test8TearDownEv_ZNK7testing8TestCase30reportable_disabled_test_countEv_ZNK7testing8TestCase19disabled_test_countEv_ZNK7testing8TestCase21reportable_test_countEv_ZNK7testing8TestCase17test_to_run_countEv_ZNK7testing8TestCase16total_test_countEv_ZN7testing8internal27PrettyUnitTestResultPrinter18OnTestProgramStartERKNS_8UnitTestE_ZN7testing8internal27PrettyUnitTestResultPrinter22OnEnvironmentsSetUpEndERKNS_8UnitTestE_ZN7testing8internal27PrettyUnitTestResultPrinter25OnEnvironmentsTearDownEndERKNS_8UnitTestE_ZN7testing8internal27PrettyUnitTestResultPrinter16OnTestProgramEndERKNS_8UnitTestE_ZN7testing8internal18OsStackTraceGetter16UponLeavingGTestEv_ZN7testing8internal24HasNewFatalFailureHelper20ReportTestPartResultERKNS_14TestPartResultE_ZN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE11ValueHolderD2Ev_ZN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE11ValueHolderD1Ev_ZN7testing8internal23DefaultDeathTestFactoryD2Ev_ZN7testing8internal23DefaultDeathTestFactoryD1Ev_ZN7testing8internal27PrettyUnitTestResultPrinterD2Ev_ZN7testing8internal27PrettyUnitTestResultPrinterD1Ev_ZN7testing8internal38DefaultPerThreadTestPartResultReporterD2Ev_ZN7testing8internal38DefaultPerThreadTestPartResultReporterD1Ev_ZN7testing8internal35DefaultGlobalTestPartResultReporterD2Ev_ZN7testing8internal35DefaultGlobalTestPartResultReporterD1Ev_ZN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE11ValueHolderD0Ev_ZN7testing8internal26ThreadLocalValueHolderBaseD0Ev_ZN7testing11EnvironmentD0Ev_ZN7testing8internal23DefaultDeathTestFactoryD0Ev_ZN7testing8internal38DefaultPerThreadTestPartResultReporterD0Ev_ZN7testing8internal35DefaultGlobalTestPartResultReporterD0Ev_ZN7testing8internal27PrettyUnitTestResultPrinterD0Ev_ZN7testing22EmptyTestEventListenerD0Ev_ZN7testing8internal17TestEventRepeaterD2Ev_ZTVN7testing8internal17TestEventRepeaterE_ZN7testing8internal17TestEventRepeaterD1Ev_ZN7testing8internal17TestEventRepeaterD0Ev_ZN7testing8internal18OsStackTraceGetter17CurrentStackTraceEii_ZN7testing8internal26GoogleTestFailureExceptionD2Ev_ZTVN7testing8internal26GoogleTestFailureExceptionE_ZN7testing8internal26GoogleTestFailureExceptionD1Ev_ZN7testing8internal26GoogleTestFailureExceptionD0Ev_ZN7testing8internal17TestEventRepeater18OnTestProgramStartERKNS_8UnitTestE_ZN7testing8internal17TestEventRepeater24OnEnvironmentsSetUpStartERKNS_8UnitTestE_ZN7testing8internal17TestEventRepeater15OnTestCaseStartERKNS_8TestCaseE_ZN7testing8internal17TestEventRepeater11OnTestStartERKNS_8TestInfoE_ZN7testing8internal17TestEventRepeater16OnTestPartResultERKNS_14TestPartResultE_ZN7testing8internal17TestEventRepeater27OnEnvironmentsTearDownStartERKNS_8UnitTestE_ZN7testing8internal17TestEventRepeater22OnEnvironmentsSetUpEndERKNS_8UnitTestE_ZN7testing8internal17TestEventRepeater25OnEnvironmentsTearDownEndERKNS_8UnitTestE_ZN7testing8internal17TestEventRepeater9OnTestEndERKNS_8TestInfoE_ZN7testing8internal17TestEventRepeater13OnTestCaseEndERKNS_8TestCaseE_ZN7testing8internal17TestEventRepeater16OnTestProgramEndERKNS_8UnitTestE_ZN7testing8internal17TestEventRepeater20OnTestIterationStartERKNS_8UnitTestEi_ZN7testing8internal17TestEventRepeater18OnTestIterationEndERKNS_8UnitTestEi_ZN7testing8internal24XmlUnitTestResultPrinterD2Ev_ZTVN7testing8internal24XmlUnitTestResultPrinterE_ZN7testing8internal24XmlUnitTestResultPrinterD1Ev_ZN7testing8internal24XmlUnitTestResultPrinterD0Ev_ZN7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEE11ValueHolderD2Ev_ZTVN7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEE11ValueHolderE_ZN7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEE11ValueHolderD1Ev_ZN7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEE11ValueHolderD0Ev_ZNSt6vectorISsSaISsEED2Ev_ZNSt6vectorISsSaISsEED1Ev_ZN7testing8internal29ParameterizedTestCaseRegistryD2Ev_ZN7testing8internal29ParameterizedTestCaseRegistryD1Ev_ZN7testing8internal12AssertHelperC2ENS_14TestPartResult4TypeEPKciS5__ZN7testing8internal12AssertHelperC1ENS_14TestPartResult4TypeEPKciS5__ZN7testing8internal12AssertHelperD2Ev_ZN7testing8internal12AssertHelperD1Ev_ZN7testing8internal15UnitTestOptions15GetOutputFormatEv_ZN7testing18FLAGS_gtest_outputE_ZN7testing8internal15UnitTestOptions20PatternMatchesStringEPKcS3__ZN7testing8internal15UnitTestOptions13MatchesFilterERKSsPKc_ZN7testing8internal13GetTestTypeIdEv_ZN7testing8internal12TypeIdHelperINS_4TestEE6dummy_E_ZN7testing8internal20SingleFailureCheckerC2EPKNS_19TestPartResultArrayENS_14TestPartResult4TypeERKSs_ZN7testing8internal20SingleFailureCheckerC1EPKNS_19TestPartResultArrayENS_14TestPartResult4TypeERKSs_ZN7testing8internal35DefaultGlobalTestPartResultReporterC2EPNS0_12UnitTestImplE_ZTVN7testing8internal35DefaultGlobalTestPartResultReporterE_ZN7testing8internal35DefaultGlobalTestPartResultReporterC1EPNS0_12UnitTestImplE_ZN7testing8internal38DefaultPerThreadTestPartResultReporterC2EPNS0_12UnitTestImplE_ZTVN7testing8internal38DefaultPerThreadTestPartResultReporterE_ZN7testing8internal38DefaultPerThreadTestPartResultReporterC1EPNS0_12UnitTestImplE_ZNK7testing8internal12UnitTestImpl21total_test_case_countEv_ZNK7testing8internal12UnitTestImpl22test_case_to_run_countEv_ZNK7testing8internal12UnitTestImpl21successful_test_countEv_ZNK7testing8TestCase21successful_test_countEv_ZNK7testing8internal12UnitTestImpl17failed_test_countEv_ZNK7testing8TestCase17failed_test_countEv_ZNK7testing8internal12UnitTestImpl30reportable_disabled_test_countEv_ZNK7testing8internal12UnitTestImpl19disabled_test_countEv_ZNK7testing8internal12UnitTestImpl21reportable_test_countEv_ZNK7testing8internal12UnitTestImpl16total_test_countEv_ZNK7testing8internal12UnitTestImpl17test_to_run_countEv_ZN7testing8internal12UnitTestImpl28CurrentOsStackTraceExceptTopEi_ZN7testing8internal15GetTimeInMillisEv_ZN7testing8internal6String13CStringEqualsEPKcS3__ZN7testing15AssertionResultC2ERKS0__ZN7testing15AssertionResultC1ERKS0__ZN7testing16AssertionSuccessEv_ZN7testing16AssertionFailureEv_ZN7testing8internal6String17WideCStringEqualsEPKwS3__ZN7testing8internal6String28CaseInsensitiveCStringEqualsEPKcS3__ZN7testing8internal6String32CaseInsensitiveWideCStringEqualsEPKwS3__ZN7testing8internal6String23EndsWithCaseInsensitiveERKSsS3__ZN7testing8internal20StringStreamToStringEPSt18basic_stringstreamIcSt11char_traitsIcESaIcEE_ZNK7testing7Message9GetStringEv_ZN7testing15AssertionResult13AppendMessageERKNS_7MessageE_ZNK7testing10TestResult17GetTestPartResultEi_ZNK7testing10TestResult15GetTestPropertyEi_ZN7testing10TestResult20ClearTestPartResultsEv_ZN7testing10TestResult5ClearEv_ZNK7testing10TestResult6FailedEv_ZNK7testing8internal12UnitTestImpl26successful_test_case_countEv_ZNK7testing8internal12UnitTestImpl22failed_test_case_countEv_ZNK7testing10TestResult15HasFatalFailureEv_ZNK7testing10TestResult18HasNonfatalFailureEv_ZNK7testing10TestResult16total_part_countEv_ZNK7testing10TestResult19test_property_countEv_ZN7testing4TestC2Ev_ZTVN7testing4TestE_ZN7testing35FLAGS_gtest_also_run_disabled_testsE_ZN7testing28FLAGS_gtest_break_on_failureE_ZN7testing28FLAGS_gtest_catch_exceptionsE_ZN7testing17FLAGS_gtest_colorE_ZN7testing28FLAGS_gtest_death_test_styleE_ZN7testing31FLAGS_gtest_death_test_use_forkE_ZN7testing18FLAGS_gtest_filterE_ZN7testing8internal35FLAGS_gtest_internal_run_death_testE_ZN7testing22FLAGS_gtest_list_testsE_ZN7testing22FLAGS_gtest_print_timeE_ZN7testing23FLAGS_gtest_random_seedE_ZN7testing18FLAGS_gtest_repeatE_ZN7testing19FLAGS_gtest_shuffleE_ZN7testing29FLAGS_gtest_stack_trace_depthE_ZN7testing28FLAGS_gtest_stream_result_toE_ZN7testing28FLAGS_gtest_throw_on_failureE_ZN7testing4TestC1Ev_ZN7testing4TestD2Ev_ZN7testing4TestD1Ev_ZN7testing4TestD0Ev_ZN7testing8internal12UnitTestImpl26RegisterParameterizedTestsEv_ZNK7testing8TestCase11GetTestInfoEi_ZN7testing8TestCase18GetMutableTestInfoEi_ZN7testing8TestCase11ClearResultEv_ZN7testing8TestCase14UnshuffleTestsEv_ZN7testing8internal16GetAnsiColorCodeENS0_10GTestColorE_ZN7testing8internal14ShouldUseColorEb_ZN7testing8internal13ColoredPrintfENS0_10GTestColorEPKcz_ZN7testing8internal27PrettyUnitTestResultPrinter24OnEnvironmentsSetUpStartERKNS_8UnitTestE_ZN7testing8internal27PrettyUnitTestResultPrinter27OnEnvironmentsTearDownStartERKNS_8UnitTestE_ZN7testing8internal27PrettyUnitTestResultPrinter11OnTestStartERKNS_8TestInfoE_ZN7testing8internal29PrintFullTestCommentIfPresentERKNS_8TestInfoE_ZN7testing8internal27PrettyUnitTestResultPrinter16PrintFailedTestsERKNS_8UnitTestE_ZN7testing8internal17TestEventRepeater7ReleaseEPNS_17TestEventListenerE_ZN7testing8internal24XmlUnitTestResultPrinterC2EPKc_ZN7testing8internal24XmlUnitTestResultPrinterC1EPKc_ZN7testing8internal24XmlUnitTestResultPrinter26RemoveInvalidXmlCharactersERKSs_ZN7testing8internal24XmlUnitTestResultPrinter21OutputXmlCDataSectionEPSoPKc_ZN7testing18TestEventListenersC2Ev_ZN7testing18TestEventListenersC1Ev_ZN7testing18TestEventListenersD2Ev_ZN7testing18TestEventListenersD1Ev_ZN7testing18TestEventListeners7ReleaseEPNS_17TestEventListenerE_ZN7testing18TestEventListeners8repeaterEv_ZNK7testing18TestEventListeners22EventForwardingEnabledEv_ZN7testing18TestEventListeners23SuppressEventForwardingEv_ZNK7testing8UnitTest26successful_test_case_countEv_ZNK7testing8UnitTest22failed_test_case_countEv_ZNK7testing8UnitTest21total_test_case_countEv_ZNK7testing8UnitTest22test_case_to_run_countEv_ZNK7testing8UnitTest21successful_test_countEv_ZNK7testing8UnitTest17failed_test_countEv_ZNK7testing8UnitTest30reportable_disabled_test_countEv_ZNK7testing8UnitTest19disabled_test_countEv_ZNK7testing8UnitTest21reportable_test_countEv_ZNK7testing8UnitTest16total_test_countEv_ZNK7testing8UnitTest17test_to_run_countEv_ZNK7testing8UnitTest15start_timestampEv_ZNK7testing8UnitTest12elapsed_timeEv_ZNK7testing8UnitTest6PassedEv_ZNK7testing8UnitTest6FailedEv_ZNK7testing8UnitTest11GetTestCaseEi_ZNK7testing8UnitTest18ad_hoc_test_resultEv_ZN7testing8UnitTest18GetMutableTestCaseEi_ZN7testing8UnitTest9listenersEv_ZN7testing14TestPartResultD2Ev_ZN7testing14TestPartResultD1Ev_ZN7testing12TestPropertyD2Ev_ZN7testing12TestPropertyD1Ev_ZNK7testing8UnitTest20original_working_dirEv_ZNK7testing8UnitTest11random_seedEv_ZN7testing8UnitTest27parameterized_test_registryEv_ZN7testing8internal12UnitTestImpl32SuppressTestEventsIfInSubprocessEv_ZN7testing8internal30WriteToShardStatusFileIfNeededEv_ZN7testing8internal20ShouldRunTestOnShardEiii_ZN7testing8internal12UnitTestImpl23ListTestsMatchingFilterEv_ZN7testing8internal12UnitTestImpl25set_os_stack_trace_getterEPNS0_27OsStackTraceGetterInterfaceE_ZN7testing8internal12UnitTestImpl19current_test_resultEv_ZN7testing8internal12UnitTestImpl14UnshuffleTestsEv_ZN7testing8internal6IsTrueEb_ZN7testing8internal10AlwaysTrueEv_ZN7testing8internal10SkipPrefixEPKcPS2__ZN7testing8internal14ParseFlagValueEPKcS2_b_ZN7testing8internal13ParseBoolFlagEPKcS2_Pb_ZN7testing8internal15ParseStringFlagEPKcS2_PSs_ZN7testing8internal16InDeathTestChildEv_ZN7testing14ExitedWithCodeC2Ei_ZN7testing14ExitedWithCodeC1Ei_ZNK7testing14ExitedWithCodeclEi_ZN7testing14KilledBySignalC2Ei_ZN7testing14KilledBySignalC1Ei_ZNK7testing14KilledBySignalclEi_ZN7testing8internal20ExitedUnsuccessfullyEi_ZN7testing8internal23GetLastErrnoDescriptionEv_ZN7testing8internal9DeathTest11LastMessageEv_ZN7testing8internal9DeathTest24last_death_test_message_E_ZN7testing8internal9DeathTest27set_last_death_test_messageERKSs_ZN7testing8internal21StackLowerThanAddressEPKvPb_ZN7testing8internal14StackGrowsDownEv_ZNK7testing8internal8FilePath21FindLastPathSeparatorEv_ZNK7testing8internal8FilePath21FileOrDirectoryExistsEv_ZNK7testing8internal8FilePath15DirectoryExistsEv_ZNK7testing8internal8FilePath15IsRootDirectoryEv_ZNK7testing8internal8FilePath14IsAbsolutePathEv_ZNK7testing8internal8FilePath11IsDirectoryEv_ZNK7testing8internal8FilePath12CreateFolderEv_ZN7testing8internal8FilePath9NormalizeEv_ZN7testing8internal8FilePath13GetCurrentDirEv_ZNK7testing8internal8FilePath19RemoveDirectoryNameEv_ZN7testing8internal24GetCurrentExecutableNameEv_ZN7testing8internal17g_executable_pathE_ZNK7testing8internal8FilePath14RemoveFileNameEv_ZNK7testing8internal8FilePath27RemoveTrailingPathSeparatorEv_ZNK7testing8internal8FilePath28CreateDirectoriesRecursivelyEv_ZNK7testing8internal8FilePath15RemoveExtensionEPKc_ZN7testing8internal14GetThreadCountEv_ZN7testing8internal2RED2Ev_ZN7testing8internal2RED1Ev_ZN7testing8internal2RE9FullMatchEPKcRKS1__ZN7testing8internal2RE12PartialMatchEPKcRKS1__ZN7testing8internal8GTestLogD2Ev_ZN7testing8internal8GTestLogD1Ev_ZN7testing8internal14CapturedStream11GetFileSizeEP8_IO_FILE_ZN7testing8internal14CapturedStream14ReadEntireFileEP8_IO_FILE_ZN7testing8internal17GetCapturedStreamEPPNS0_14CapturedStreamE_ZN7testing8internal17GetCapturedStdoutEv_ZN7testing8internal17GetCapturedStderrEv_ZN7testing8internal18SetInjectableArgvsEPKSt6vectorISsSaISsEE_ZN7testing8internal18GetInjectableArgvsEv_ZN7testing8internal7g_argvsE_ZN7testing9internal220PrintBytesInObjectToEPKhjPSo_ZN7testinglsERSoRKNS_14TestPartResultE_ZNK7testing19TestPartResultArray17GetTestPartResultEi_ZNK7testing19TestPartResultArray4sizeEv_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEED2Ev_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEED1Ev_ZN7testing7MessageC2Ev_ZN7testing7MessageC1Ev_ZN7testing8internal30GetBoolAssertionFailureMessageERKNS_15AssertionResultEPKcS5_S5__ZN7testing8internal10ParseInt32ERKNS_7MessageEPKcPi_ZN7testing8internal17Int32FromEnvOrDieEPKci_ZN7testing8internal14ParseInt32FlagEPKcS2_Pi_ZN7testing8internal16BoolFromGTestEnvEPKcb_ZN7testing8internal18StringFromGTestEnvEPKcS2__ZN7testing8internal17Int32FromGTestEnvEPKci_ZN7testing7MessageC2ERKS0__ZN7testing7MessageC1ERKS0__ZN7testing8internal11ShouldShardEPKcS2_b_ZN7testing8internal6String12FormatHexIntEi_ZN7testing8internal27FormatTimeInMillisAsSecondsEx_ZN7testing8internal6String15FormatIntWidth2Ei_ZN7testing8internal6String10FormatByteEh_ZN7testing8internal24XmlUnitTestResultPrinter9EscapeXmlERKSsb_ZN7testing8internal24XmlUnitTestResultPrinter29TestPropertiesAsXmlAttributesERKNS_10TestResultE_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEED0Ev_ZN7testing8internal10scoped_ptrISsE5resetEPSs_ZN7testing8internal9EqFailureEPKcS2_RKSsS4_b_ZNK7testing15AssertionResultntEv_ZN7testing16AssertionFailureERKNS_7MessageE_ZN7testing8internal10scoped_ptrINS0_24InternalRunDeathTestFlagEE5resetEPS2__ZStplIcSt11char_traitsIcESaIcEESbIT_T0_T1_ERKS6_PKS3__ZStplIcSt11char_traitsIcESaIcEESbIT_T0_T1_EPKS3_RKS6__ZN7testing8internal15CodePointToUtf8Ej_ZN7testing8internal16WideStringToUtf8EPKwi_ZN7testing7MessagelsERKSbIwSt11char_traitsIwESaIwEE_ZN7testing8internal6String15ShowWideCStringEPKw_ZN7testing7MessagelsEPKw_ZN7testing7MessagelsEPw_ZN7testing8internal19UniversalPrintArrayEPKcjPSo_ZN7testing8internal7PrintToEPKcPSo_ZN7testing8internal13PrintStringToERKSsPSo_ZN7testing13PrintToStringIPKcEESsRKT__ZN7testing8internal14CmpHelperSTREQEPKcS2_S2_S2__ZN7testing8internal18CmpHelperSTRCASEEQEPKcS2_S2_S2__ZN7testing8internal19UniversalPrintArrayEPKwjPSo_ZN7testing8internal7PrintToEPKwPSo_ZN7testing8internal17PrintWideStringToERKSbIwSt11char_traitsIwESaIwEEPSo_ZN7testing13PrintToStringIPKwEESsRKT__ZN7testing8internal14CmpHelperSTREQEPKcS2_PKwS4__ZN7testing8internal17StreamingListener9UrlEncodeEPKc_ZN7testing8internal18StreamableToStringIiEESsRKT__ZN7testing8internal27PrettyUnitTestResultPrinter15OnTestCaseStartERKNS_8TestCaseE_ZN7testing8internal27PrettyUnitTestResultPrinter20OnTestIterationStartERKNS_8UnitTestEi_ZN7testing8internal18StreamableToStringIxEESsRKT__ZN7testing8internal27PrettyUnitTestResultPrinter9OnTestEndERKNS_8TestInfoE_ZN7testing8internal27PrettyUnitTestResultPrinter13OnTestCaseEndERKNS_8TestCaseE_ZN7testing8internal27PrettyUnitTestResultPrinter18OnTestIterationEndERKNS_8UnitTestEi_ZStplIcSt11char_traitsIcESaIcEESbIT_T0_T1_ERKS6_S8__ZN7testing8internal8FilePath11ConcatPathsERKS1_S3__ZN7testing8internal32FormatEpochTimeInMillisAsIso8601Ex_ZN7testing8internal8FilePath12MakeFileNameERKS1_S3_iPKc_ZN7testing8internal8FilePath22GenerateUniqueFileNameERKS1_S3_PKc_ZN7testing8internal18FormatFileLocationEPKci_ZN7testing8internal8GTestLogC2ENS0_16GTestLogSeverityEPKci_ZN7testing8internal8GTestLogC1ENS0_16GTestLogSeverityEPKci_ZN7testing8internal13CaptureStreamEiPKcPPNS0_14CapturedStreamE_ZN7testing8internal13CaptureStdoutEv_ZN7testing8internal13CaptureStderrEv_ZN7testing8internal17StreamingListener12SocketWriter14MakeConnectionEv_ZN7testing8internal17StreamingListener12SocketWriter15CloseConnectionEv_ZN7testing8internal5MutexD2Ev_ZN7testing8internal5MutexD1Ev_ZN7testing8internal9MutexBase6UnlockEv_ZN7testing8internal9MutexBase4LockEv_ZN7testing8internal17StreamingListener12SocketWriter4SendERKSs_ZN7testing8internal6Random8GenerateEj_ZN7testing8internal13DeathTestImpl6PassedEb_ZN7testing8internal17StreamingListener12SocketWriterD2Ev_ZTVN7testing8internal17StreamingListener12SocketWriterE_ZN7testing8internal17StreamingListener12SocketWriterD1Ev_ZN7testing8internal17StreamingListener12SocketWriterD0Ev_ZN7testing8internal17StreamingListenerD2Ev_ZTVN7testing8internal17StreamingListenerE_ZN7testing8internal17StreamingListenerD1Ev_ZN7testing8internal17StreamingListenerD0Ev_ZN7testing8internal17StreamingListener20AbstractSocketWriter6SendLnERKSs_ZN7testing8internal17StreamingListener11OnTestStartERKNS_8TestInfoE_ZN7testing8internal17StreamingListener15OnTestCaseStartERKNS_8TestCaseE_ZN7testing8internal17StreamingListener16OnTestProgramEndERKNS_8UnitTestE_ZN7testing8internal17StreamingListener16OnTestPartResultERKNS_14TestPartResultE_ZN7testing8internal17StreamingListener20OnTestIterationStartERKNS_8UnitTestEi_ZN7testing10TestResultC2Ev_ZN7testing10TestResultC1Ev_ZN7testing8internal18OsStackTraceGetterD2Ev_ZTVN7testing8internal18OsStackTraceGetterE_ZN7testing8internal18OsStackTraceGetterD1Ev_ZN7testing8internal18OsStackTraceGetterD0Ev_ZN7testing8internal12UnitTestImpl21os_stack_trace_getterEv_ZN7testing8internal12UnitTestImpl31SetGlobalTestPartResultReporterEPNS_31TestPartResultReporterInterfaceE_ZN7testing8internal12UnitTestImpl31GetGlobalTestPartResultReporterEv_ZNK7testing8UnitTest17current_test_caseEv_ZNK7testing8UnitTest17current_test_infoEv_ZN7testing8internal38DefaultPerThreadTestPartResultReporter20ReportTestPartResultERKNS_14TestPartResultE_ZN7testing10TestResultD2Ev_ZN7testing10TestResultD1Ev_ZN7testing8internal17StreamingListener18OnTestProgramStartERKNS_8UnitTestE_ZN7testing8internal26GoogleTestFailureExceptionC2ERKNS_14TestPartResultE_ZN7testing8internal26GoogleTestFailureExceptionC1ERKNS_14TestPartResultE_ZN7testing8internal27PrettyUnitTestResultPrinter16OnTestPartResultERKNS_14TestPartResultE_ZN7testing8internal25ReportInvalidTestCaseTypeEPKcS2_i_ZN7testing8internal37FormatCompilerIndependentFileLocationEPKci_ZN7testing8internal17AppendUserMessageERKSsRKNS_7MessageE_ZN7testing8internal17StreamingListener9OnTestEndERKNS_8TestInfoE_ZN7testing8internal17StreamingListener13OnTestCaseEndERKNS_8TestCaseE_ZN7testing8internal17StreamingListener18OnTestIterationEndERKNS_8UnitTestEi_ZN7testing15AssertionResultlsINS_7MessageEEERS0_RKT__ZN7testing15AssertionResultlsIA11_cEERS0_RKT__ZN7testing15AssertionResultlsISsEERS0_RKT__ZN7testing15AssertionResultlsIA2_cEERS0_RKT__ZN7testing15AssertionResultlsINS_14TestPartResultEEERS0_RKT__ZN7testing15AssertionResultlsIA3_cEERS0_RKT__ZN7testing8internal13HasOneFailureEPKcS2_S2_RKNS_19TestPartResultArrayENS_14TestPartResult4TypeERKSs_ZN7testing15AssertionResultlsIPKcEERS0_RKT__ZN7testing11IsSubstringEPKcS1_S1_S1__ZN7testing14IsNotSubstringEPKcS1_S1_S1__ZN7testing11IsSubstringEPKcS1_RKSsS3__ZN7testing14IsNotSubstringEPKcS1_RKSsS3__ZN7testing11IsSubstringEPKcS1_RKSbIwSt11char_traitsIwESaIwEES7__ZN7testing14IsNotSubstringEPKcS1_RKSbIwSt11char_traitsIwESaIwEES7__ZN7testing11IsSubstringEPKcS1_PKwS3__ZN7testing14IsNotSubstringEPKcS1_PKwS3__ZN7testing15AssertionResultlsIA5_cEERS0_RKT__ZN7testing15AssertionResultlsIA7_cEERS0_RKT__ZN7testing8internal20DoubleNearPredFormatEPKcS2_S2_ddd_ZN7testing15AssertionResultlsIA12_cEERS0_RKT__ZN7testing8internal14CmpHelperSTRNEEPKcS2_PKwS4__ZN7testing8internal14CmpHelperSTRNEEPKcS2_S2_S2__ZN7testing8internal18CmpHelperSTRCASENEEPKcS2_S2_S2__ZN7testing8internal15FloatingPointLEIfEENS_15AssertionResultEPKcS4_T_S5__ZN7testing7FloatLEEPKcS1_ff_ZN7testing8internal15FloatingPointLEIdEENS_15AssertionResultEPKcS4_T_S5__ZN7testing8DoubleLEEPKcS1_dd_ZN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEED2Ev_ZN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEED1Ev_ZN7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEED2Ev_ZN7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEED1Ev_ZN7testing8internal12ShuffleRangeIiEEvPNS0_6RandomEiiPSt6vectorIT_SaIS5_EE_ZN7testing8TestCase12ShuffleTestsEPNS_8internal6RandomE_ZN7testing8internal12UnitTestImpl12ShuffleTestsEv_ZN7testing8internal18ParseNaturalNumberIiEEbRKSsPT__ZN7testing8internal18PrintCharAndCodeToIhhEEvT0_PSo_ZN7testing8internal7PrintToEhPSo_ZN7testing8internal18PrintCharAndCodeToIhaEEvT0_PSo_ZN7testing8internal7PrintToEaPSo_ZN7testing8internal18PrintCharAndCodeToIwwEEvT0_PSo_ZN7testing8internal7PrintToEwPSo_ZN7testing8internal10scoped_ptrIKSsE5resetEPS2__ZN7testing8TestInfoD2Ev_ZN7testing8TestInfoD1Ev_ZN7testing8TestCaseD2Ev_ZTVN7testing8TestCaseE_ZN7testing8TestCaseD1Ev_ZN7testing8TestCaseD0Ev_ZN7testing8internal12UnitTestImplD2Ev_ZTVN7testing8internal12UnitTestImplE_ZN7testing8internal12UnitTestImplD1Ev_ZN7testing8internal12UnitTestImplD0Ev_ZN7testing8UnitTestD2Ev_ZTVN7testing8UnitTestE_ZN7testing8UnitTestD1Ev_ZN7testing8UnitTestD0Ev_ZN7testing8TestCaseC2EPKcS2_PFvvES4__ZN7testing8TestCaseC1EPKcS2_PFvvES4__ZN7testing8TestInfoC2ERKSsS2_PKcS4_PKvPNS_8internal15TestFactoryBaseE_ZN7testing8TestInfoC1ERKSsS2_PKcS4_PKvPNS_8internal15TestFactoryBaseE_ZNSt6vectorIPN7testing8TestInfoESaIS2_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS2_S4_EERKS2__ZNSt6vectorIiSaIiEE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPiS1_EERKi_ZN7testing8TestCase11AddTestInfoEPNS_8TestInfoE_ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS2_S4_EERKS2__ZN7testing8internal12UnitTestImpl24ConfigureStreamingOutputEv_ZN7testing8internal17TestEventRepeater6AppendEPNS_17TestEventListenerE_ZN7testing18TestEventListeners6AppendEPNS_17TestEventListenerE_ZN7testing18TestEventListeners23SetDefaultResultPrinterEPNS_17TestEventListenerE_ZN7testing8internal12UnitTestImplC2EPNS_8UnitTestE_ZTVN7testing8internal23DefaultDeathTestFactoryE_ZTVN7testing8internal27PrettyUnitTestResultPrinterE_ZN7testing8internal12UnitTestImplC1EPNS_8UnitTestE_ZN7testing8UnitTestC2Ev_ZN7testing8UnitTestC1Ev_ZN7testing8UnitTest11GetInstanceEv_ZN7testing8internal15UnitTestOptions27GetAbsolutePathToOutputFileEv_ZN7testing4Test15HasFatalFailureEv_ZN7testing4Test18HasNonfatalFailureEv_ZN7testing8internal31GetCurrentOsStackTraceExceptTopEPNS_8UnitTestEi_ZN7testing8internal14DeathTestAbortERKSs_ZN7testing8internal13DeathTestImpl26ReadAndInterpretStatusByteEv_ZN7testing8internal13DeathTestImpl5AbortENS0_9DeathTest11AbortReasonE_ZN7testing8internal16ForkingDeathTest4WaitEv_ZN7testing8internal15NoExecDeathTestD2Ev_ZTVN7testing8internal13DeathTestImplE_ZN7testing8internal15NoExecDeathTestD1Ev_ZN7testing8internal13ExecDeathTestD2Ev_ZN7testing8internal13ExecDeathTestD1Ev_ZN7testing8internal15NoExecDeathTestD0Ev_ZN7testing8internal13ExecDeathTestD0Ev_ZN7testing8internal9DeathTestC2Ev_ZTVN7testing8internal9DeathTestE_ZN7testing8internal9DeathTestC1Ev_ZN7testing8internal16ForkingDeathTestC2EPKcPKNS0_2REE_ZTVN7testing8internal16ForkingDeathTestE_ZN7testing8internal16ForkingDeathTestC1EPKcPKNS0_2REE_ZN7testing8internal9DeathTest6CreateEPKcPKNS0_2REES3_iPPS1__ZN7testing8internal15NoExecDeathTest10AssumeRoleEv_ZN7testing8internal23DefaultDeathTestFactory6CreateEPKcPKNS0_2REES3_iPPNS0_9DeathTestE_ZTVN7testing8internal15NoExecDeathTestE_ZTVN7testing8internal13ExecDeathTestE_ZN7testing18TestEventListeners22SetDefaultXmlGeneratorEPNS_17TestEventListenerE_ZN7testing8internal12UnitTestImpl18ConfigureXmlOutputEv_ZNSt6vectorIPN7testing11EnvironmentESaIS2_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS2_S4_EERKS2__ZN7testing8UnitTest14AddEnvironmentEPNS_11EnvironmentE_ZNSt6vectorIPN7testing8TestCaseESaIS2_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS2_S4_EERKS2__ZN7testing8internal18StreamableToStringIPcEESsRKT__ZNSt6vectorIPcSaIS0_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS0_S2_EERKS0__ZNSt6vectorIPcSaIS0_EE6insertEN9__gnu_cxx17__normal_iteratorIPS0_S2_EERKS0__ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE8_M_eraseEPSt13_Rb_tree_nodeISsE_ZNKSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE4findERKSs_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE16_M_insert_uniqueERKSs_ZN7testing8internal27CheckedDowncastToActualTypeINS0_11ThreadLocalISt6vectorINS0_9TraceInfoESaIS4_EEE11ValueHolderENS0_26ThreadLocalValueHolderBaseEEEPT_PT0__ZTSN7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEE11ValueHolderE_ZTIN7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEE11ValueHolderE_ZTIN7testing8internal26ThreadLocalValueHolderBaseE_ZN7testing13PrintToStringIxEESsRKT__ZN7testing8internal11CmpHelperEQEPKcS2_xx_ZN7testing8internal11CmpHelperNEEPKcS2_xx_ZN7testing8internal11CmpHelperLEEPKcS2_xx_ZN7testing8internal11CmpHelperLTEPKcS2_xx_ZN7testing8internal11CmpHelperGEEPKcS2_xx_ZN7testing8internal11CmpHelperGTEPKcS2_xx_ZSt9__find_ifIN9__gnu_cxx17__normal_iteratorIPN7testing12TestPropertyESt6vectorIS3_SaIS3_EEEENS0_5__ops10_Iter_predINS2_8internal17TestPropertyKeyIsEEEET_SE_SE_T0_St26random_access_iterator_tag_ZSt9__find_ifIN9__gnu_cxx17__normal_iteratorIPKSsSt6vectorISsSaISsEEEENS0_5__ops16_Iter_equals_valIS2_EEET_SB_SB_T0_St26random_access_iterator_tag_ZSt9__find_ifIN9__gnu_cxx17__normal_iteratorIPPN7testing8TestCaseESt6vectorIS4_SaIS4_EEEENS0_5__ops10_Iter_predINS2_8internal14TestCaseNameIsEEEET_SF_SF_T0_St26random_access_iterator_tag_ZN7testing8internal12UnitTestImpl11GetTestCaseEPKcS3_PFvvES5__ZN7testing8internal23MakeAndRegisterTestInfoEPKcS2_S2_S2_PKvPFvvES6_PNS0_15TestFactoryBaseE_ZNSs12_S_constructIPKcEEPcT_S3_RKSaIcESt20forward_iterator_tag_ZN7testing8internal15UnitTestOptions17FilterMatchesTestERKSsS3__ZN7testing8internal12UnitTestImpl11FilterTestsENS1_18ReactionToShardingE_ZN7testing14TestPartResult14ExtractSummaryEPKc_ZN7testing8internal17kStackTraceMarkerE_ZN7testing8internal19TypedTestCasePState25VerifyRegisteredTestNamesEPKciS3__ZN7testing8internal28ParseGoogleTestFlagsOnlyImplIwEEvPiPPT__ZN7testing8internal11g_help_flagE_ZN7testing8internal24ParseGoogleTestFlagsOnlyEPiPPw_ZN7testing8internal28ParseGoogleTestFlagsOnlyImplIcEEvPiPPT__ZN7testing8internal24ParseGoogleTestFlagsOnlyEPiPPc_ZN7testing8internal27CheckedDowncastToActualTypeINS0_11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE11ValueHolderENS0_26ThreadLocalValueHolderBaseEEEPT_PT0__ZTSN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE11ValueHolderE_ZTIN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE11ValueHolderE_ZNK7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE16GetOrCreateValueEv_ZTVN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE11ValueHolderE_ZN7testing8internal12UnitTestImpl41GetTestPartResultReporterForCurrentThreadEv_ZN7testing8internal12UnitTestImpl41SetTestPartResultReporterForCurrentThreadEPNS_31TestPartResultReporterInterfaceE_ZN7testing8internal24HasNewFatalFailureHelperD2Ev_ZTVN7testing8internal24HasNewFatalFailureHelperE_ZN7testing8internal24HasNewFatalFailureHelperD1Ev_ZN7testing8internal24HasNewFatalFailureHelperD0Ev_ZN7testing32ScopedFakeTestPartResultReporterD2Ev_ZTVN7testing32ScopedFakeTestPartResultReporterE_ZN7testing32ScopedFakeTestPartResultReporterD1Ev_ZN7testing32ScopedFakeTestPartResultReporterD0Ev_ZN7testing8internal24HasNewFatalFailureHelperC2Ev_ZN7testing8internal24HasNewFatalFailureHelperC1Ev_ZN7testing32ScopedFakeTestPartResultReporter4InitEv_ZN7testing32ScopedFakeTestPartResultReporterC2EPNS_19TestPartResultArrayE_ZN7testing32ScopedFakeTestPartResultReporterC1EPNS_19TestPartResultArrayE_ZN7testing32ScopedFakeTestPartResultReporterC2ENS0_13InterceptModeEPNS_19TestPartResultArrayE_ZN7testing32ScopedFakeTestPartResultReporterC1ENS0_13InterceptModeEPNS_19TestPartResultArrayE_ZNSt12_Destroy_auxILb0EE9__destroyIPSsEEvT_S3__ZN7testing8internal13ExecDeathTest10AssumeRoleEv_ZN7testing8internal24XmlUnitTestResultPrinter18OutputXmlAttributeEPSoRKSsS4_S4__ZN7testing8internal24XmlUnitTestResultPrinter17OutputXmlTestInfoEPSoPKcRKNS_8TestInfoE_ZN7testing8internal24XmlUnitTestResultPrinter16PrintXmlTestCaseEPSoRKNS_8TestCaseE_ZN7testing8internal24XmlUnitTestResultPrinter16PrintXmlUnitTestEPSoRKNS_8UnitTestE_ZN7testing8internal24XmlUnitTestResultPrinter18OnTestIterationEndERKNS_8UnitTestEi_ZNSt6vectorISsSaISsEE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPSsS1_EERKSs_ZN7testing8internal29ParseInternalRunDeathTestFlagEv_ZN7testing8internal12UnitTestImpl19PostFlagParsingInitEv_ZN7testing8internal18InitGoogleTestImplIcEEvPiPPT__ZN7testing8internal18g_init_gtest_countE_ZN7testing14InitGoogleTestEPiPPc_ZN7testing8internal18InitGoogleTestImplIwEEvPiPPT__ZN7testing14InitGoogleTestEPiPPw_ZNSt12_Destroy_auxILb0EE9__destroyIPN7testing8internal9TraceInfoEEEvT_S6__ZNK7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEE16GetOrCreateValueEv_ZN7testing8UnitTest17AddTestPartResultENS_14TestPartResult4TypeEPKciRKSsS6__ZTIN7testing8internal26GoogleTestFailureExceptionE_ZNK7testing8internal12AssertHelperaSERKNS_7MessageE_ZN7testing8internal20SingleFailureCheckerD2Ev_ZN7testing8internal20SingleFailureCheckerD1Ev_ZN7testing24ValidateTestPropertyNameERKSsRKSt6vectorISsSaISsEE_ZN7testing10TestResult20ValidateTestPropertyERKSsRKNS_12TestPropertyE_ZN7testing4Test19HasSameFixtureClassEv_ZN7testing8internal2RE4InitEPKc_ZN7testing8internal30ReportFailureInUnknownLocationENS_14TestPartResult4TypeERKSs_ZN7testing8internal35HandleExceptionsInMethodIfSupportedINS_4TestEvEET0_PT_MS4_FS3_vEPKc_ZN7testing4Test3RunEv_ZN7testing8internal35HandleExceptionsInMethodIfSupportedINS0_15TestFactoryBaseEPNS_4TestEEET0_PT_MS6_FS5_vEPKc_ZN7testing8TestInfo3RunEv_ZN7testing8internal35HandleExceptionsInMethodIfSupportedINS_8TestCaseEvEET0_PT_MS4_FS3_vEPKc_ZN7testing8TestCase3RunEv_ZN7testing8internal12UnitTestImpl11RunAllTestsEv_ZN7testing8internal35HandleExceptionsInMethodIfSupportedINS0_12UnitTestImplEbEET0_PT_MS4_FS3_vEPKc_ZN7testing8UnitTest3RunEv_ZN7testing8UnitTest13PopGTestTraceEv_ZN7testing8internal11ScopedTraceD2Ev_ZN7testing8internal11ScopedTraceD1Ev_ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS2_S4_EERKS2__ZN7testing8UnitTest14PushGTestTraceERKNS_8internal9TraceInfoE_ZN7testing8internal11ScopedTraceC2EPKciRKNS_7MessageE_ZN7testing8internal11ScopedTraceC1EPKciRKNS_7MessageE_ZNSt20__uninitialized_copyILb0EE13__uninit_copyIPN7testing14TestPartResultES4_EET0_T_S6_S5__ZNSt6vectorIN7testing14TestPartResultESaIS1_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS1_S3_EERKS1__ZN7testing8internal35DefaultGlobalTestPartResultReporter20ReportTestPartResultERKNS_14TestPartResultE_ZN7testing10TestResult17AddTestPartResultERKNS_14TestPartResultE_ZN7testing19TestPartResultArray6AppendERKNS_14TestPartResultE_ZN7testing32ScopedFakeTestPartResultReporter20ReportTestPartResultERKNS_14TestPartResultE_ZNSt20__uninitialized_copyILb0EE13__uninit_copyIPN7testing12TestPropertyES4_EET0_T_S6_S5__ZNSt6vectorIN7testing12TestPropertyESaIS1_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS1_S3_EERKS1__ZN7testing10TestResult14RecordPropertyERKSsRKNS_12TestPropertyE_ZN7testing8internal12UnitTestImpl14RecordPropertyERKNS_12TestPropertyE_ZN7testing8UnitTest14RecordPropertyERKSsS2__ZN7testing4Test14RecordPropertyERKSsS2__ZN7testing4Test14RecordPropertyERKSsi_ZN7testing8internal23kTestTypeIdInGoogleTestE_ZTSN7testing8internal26ThreadLocalValueHolderBaseE_ZTSN7testing8internal26GoogleTestFailureExceptionE_ZTIN7testing8internal9DeathTestE_ZTSN7testing8internal9DeathTestE_ZTIN7testing8internal16DeathTestFactoryE_ZTSN7testing8internal16DeathTestFactoryE_ZTSN7testing8internal23DefaultDeathTestFactoryE_ZTIN7testing8internal23DefaultDeathTestFactoryE_ZTIN7testing31TestPartResultReporterInterfaceE_ZTSN7testing31TestPartResultReporterInterfaceE_ZTSN7testing8internal24HasNewFatalFailureHelperE_ZTIN7testing8internal24HasNewFatalFailureHelperE_ZTSN7testing4TestE_ZTIN7testing4TestE_ZTSN7testing8TestCaseE_ZTIN7testing8TestCaseE_ZTIN7testing17TestEventListenerE_ZTSN7testing17TestEventListenerE_ZTIN7testing22EmptyTestEventListenerE_ZTSN7testing22EmptyTestEventListenerE_ZTSN7testing8UnitTestE_ZTIN7testing8UnitTestE_ZTSN7testing32ScopedFakeTestPartResultReporterE_ZTIN7testing32ScopedFakeTestPartResultReporterE_ZTIN7testing8internal27OsStackTraceGetterInterfaceE_ZTSN7testing8internal27OsStackTraceGetterInterfaceE_ZTSN7testing8internal18OsStackTraceGetterE_ZTIN7testing8internal18OsStackTraceGetterE_ZTSN7testing8internal35DefaultGlobalTestPartResultReporterE_ZTIN7testing8internal35DefaultGlobalTestPartResultReporterE_ZTSN7testing8internal38DefaultPerThreadTestPartResultReporterE_ZTIN7testing8internal38DefaultPerThreadTestPartResultReporterE_ZTSN7testing8internal12UnitTestImplE_ZTIN7testing8internal12UnitTestImplE_ZTIN7testing8internal17StreamingListener20AbstractSocketWriterE_ZTSN7testing8internal17StreamingListener20AbstractSocketWriterE_ZTIN7testing8internal17StreamingListener12SocketWriterE_ZTSN7testing8internal17StreamingListener12SocketWriterE_ZTIN7testing8internal17StreamingListenerE_ZTSN7testing8internal17StreamingListenerE_ZTSN7testing8internal27PrettyUnitTestResultPrinterE_ZTIN7testing8internal27PrettyUnitTestResultPrinterE_ZTSN7testing8internal17TestEventRepeaterE_ZTIN7testing8internal17TestEventRepeaterE_ZTSN7testing8internal24XmlUnitTestResultPrinterE_ZTIN7testing8internal24XmlUnitTestResultPrinterE_ZTSN7testing8internal13DeathTestImplE_ZTIN7testing8internal13DeathTestImplE_ZTSN7testing8internal16ForkingDeathTestE_ZTIN7testing8internal16ForkingDeathTestE_ZTSN7testing8internal15NoExecDeathTestE_ZTIN7testing8internal15NoExecDeathTestE_ZTSN7testing8internal13ExecDeathTestE_ZTIN7testing8internal13ExecDeathTestE_ZN7testing8internal18OsStackTraceGetter19kElidedFramesMarkerE_ZN7testing8internal18g_linked_ptr_mutexE_ZN7testing38FLAGS_gtest_show_internal_stack_framesEgtest-all.o/ 1428496271 1000 1000 100664 2641844 ` ELFu4(&')*     89#$,-56 /0!"23>?ABDEGHJKMNPQTUWXZ[]^`ahicdklnoqrtuwxz{}~    !#$&')*,-/0235689;<>?ABDEGHJKMNPQSTVWYZ\]_`bcefhiklnoqrtuwxz{Í&'Í&'SD$P X19t& yty9u[SD$P X19t& y9u[ÍSD$P X19t& y9u[ÍSD$P X19t& y9u[ÍT$B+B fÍ&'T$D$:u@@T$D$AUWVS }w _9t t&t  PR9uwtue[^_]e[^_]ËWÅt R Sv'S\$S\$ [t&S\$$D$PhS([&'WVS|$t$t9WG )t*1ۍVPRWG )9r[^_fWVS|$t$t9WG )t*1ۍVPRWG )9r[^_fWVS|$t$t9WG )t*1ۍVPRWG )9r[^_fWVS|$t$t9WG )t*1ۍVPRWG )9r[^_fWVS|$t$t9WG )t*1ۍVPR WG )9r[^_fWVS|$t$t9WG )t*1ۍVPR,WG )9r[^_fWVSt$|$~t:F^ )x* v'FWPRu[^_ÐWVSt$|$~t:F^ )x* v'FWPR0u[^_ÐWVSt$|$~t:F^ )x* v'FWPR$u[^_ÐWVSt$|$~t:F^ )x* v'FWPR(u[^_ÐWVSt$|$~t:F^ )x* v'FWPR8u[^_ÐUWVS l$ \$$t$(}t:UE )t+1VSPR UE )9r݃ [^_]Ðt&UWVS t$ |$$l$(~t3F^ )x#fFUWPR4u [^_]ÍVSƃXl;Xpt  RQ;^puFx[^UWVSÃK)tR߉Ӊփ1\$ 1ې&T$ tD0 QЋOË)9rу[^_]1vVSÃtX1u-Mv' Rt*/ uڃ huփ[^Í& h[^Ív'StH~[ËHYɉXRP[ÐUWVS1,E v'Vj W j hutX)@9ERVWPXEZPuE =u 떍U&넍t&@9wy]jVWSY^SuE =u Eԍe[^_]ÍUEԍe[^_]PVhhËEԋ =tU SPVhhËE =tUv붉ËE =tU]띍t&'UWVS1׃,ɉL$t$@\$D$D$D$ D$ (Ph+jS$ PSV;l$tKD=tèuD$ jD$!PV륐t&D$-jD$"PV농,[^_]VSƉӃt+ R PSPR[^Í&jh0P[^Ð&UVSjËE ECECEPC uPEe[^]à S4$&S\$ tB =u R[Ít&T$ސfUVSutKj:St!U)RPSVe[^]t&EPSVݐ&EPhV P&'VSD$ t$$XCK<*t7~<:t\hlVu)h|VuhVv![^Ð&=WVS\$t$t|tQD$tID$Ph VS5$[^_ÐVS5[^_É' hl 5$$Ǣ$0t&1G&hj$D$ t&hj$D$ t&S\$hj s3h$ D$ [WVST$ BR 11ۅtÉ߉Éuu [^_ÍvL$ hL$tcVh ht hSh h[^_fR 11jzt&ukUW1VSD$0@$D$ T/GD$0P$JTBX)ȃ/D$ 5t&D$ x6{,u[Ðt&Sh5u뱉'UWVS,E] EԋEuEڃPh VY_VuV jh7VX}ZVW$ PSWE =u{E =u~]܃1CPSuEtC=uee[^_]ÍvUU}ttԃ<=Dōt&e1[^_]Ít&Uxv vt&뒉ËE܃ =tUE =tUE =tU SËE =tӍUɉ밉jt$t$t'Ѓv'UEoEhP_XEhPEă pPEPEă =&U@o'M (jQjRP Ejh0Pt&UnvUEoE܃ [PރF<~&E܃hP_XEVPtE܃hPẼuPE܃ t  PREhPEY[hPẼ pPEPE jhrPE j hPEЃ pPEPẼ =u2EЃ =2E܃hPUnmĉËẼ =tUUmEЃ =u@Ut RQE =tU m SËE؃ =tUm붉륉ËE܅t PR뎉ËEă =tʃ SuËE =b렉YeËE =?zËEȃ ='bv'UWVS$]jSuSCC C$C(C,C0C4C8C<C@e[^_]Ð&}huhDjW j!hh jhhXZVh<$S W$fUWVSut e[^_]f j(Í@Y_jPu CC$؉e[^_]Ðt&EhuhDjP j!hh jhhXZWhE$놉ƃ S4$ƍE Pܐ&UWVS8]s VEu1Ce[^_]Ít&Eh0P뚍v'Yae[^_]ÉËE =tU8a SËEtك PRː&UVSE]U uWEPuSXZSVE =uE =u)e[^]Ít&U`E =tڍv`e[^]ÉËE =tUm` SËE =tӍUM`ɐv'USU u]ÍvE uX5E =u 5]ÍvU_݉ËE =tU_ SUVSE]PE j$hP{ S PESPEjhPE j?hPE jh4P1 S PESPEj hPE j>hTPE j=hPE j=hPE jChPE j hPYE[uPX]uZuu S Vuh5E =uwE =uZEt PRe[^]ËEh0P&Eh0P&]띍&U]|ËE =tU]E =tUw]Et PR Sˉ܍vUWVSu}܃ U ]VDRWExoEPV<$}W jhW VWSE =u[E =u^E܃ =u+e[^_]t&WSE܃ =tՉ\e[^_]vUx\뛍i\뙉ËE܃ =tUP\ SËE =tU0\E =tU\ЉvUWVSu$E]} 0VE @u&WSE =uTe[^_]W}W jhrW VWSE =tU[륍Up[e[^_]ËE =tUM[ SËE =tӍU-['U:*WVSM}ԃ0}uQEPWE؉$^+ĩ8E؃hNPEԃ pPE؃PXEZhrPEY_hYPXEZSP_XEhdPF+1ۃ~P&SVNjE؃ jhrPXEZWPF+i9|E؃EEPEPY[PuXEZjPE؅t  PREԃ =Ee[^_]jVÃ9EtXEEhNEPZYWPY^hrP_ZhnPY^SP_ZPuPE 0st'E@7UXEe[^_]EEhNEPY^WPu܉lj4$E܃ j hyPXZVWE܃t  PRu W^_hPZYhnP^_SPY[PulËE܅t PREjPE؅t PREԃ =tUW S뿍&'UWVSÃe[^_]ÍUO>‰ËE 8PE@t PE@ t PEjPE@ =tU= S뛍t&S\$S\$ [t&UWVS,uFX~T9Eu%O& S$9}t,t@=t҃ SЃ9}u݉'~L^H9uDt& P9t-tRtڃ P҃9uݍv't  PR Pt  PRt/C x P = St$@=N S$ P^lFp9t$&t  PR;^puFlt PF`t PFTt PFHt P v@t  PR v@u(F PF =uqe[^_]Ít&}hhDjW jhYh jhhXZSh<$끃 SЃU:e[^_]ÍU:aËF =tU: SÍFl PF`t PFTt PFHt PF@ PF PuÍ P|ϋVlÅz RiÍjPt PR뙉Ëtȃ PR뺉Nj =tU9봃 W<Í P륐fS\$S\$ [t&UVS]s$t$@= V4$ Sue[^]Ð&uhyhDjV jhlh jhhXZSh4$e[^]Ít& VЃn V$ S4$&S\$S\$ [t&UWVSu0]}CVu P0 j EVWP{EC CCCCC$EC C,C0C4C(C8jPuQCPCXC\C`CdChClCpCtCxe[^_]ÍhuhDjV j!hh jhhZYWh4$X'CƋCt PC t PPPCjPC =tU6 V V뚃 uԉ뾉뺍UWVS4]u }uSXCZuP< jEԍE PWQ{ jǍE PVW{ ECCCCE CCjPuPC4C<C@CDCHCLCPCTCXC\e[^_]Ðt&}huhDjW j!hh jhhYXVh<$VC t&CƍC RRjPPPCjPC =tU4 =tU4 V W랉σ W뚉떃 uԉ딉fS\$ C;Ct@t T$$CCC+S;C T$ t9tC[Ð&T$(RPC P뼉'T$RPS뼐&HuÍvUWVS0jj:h uPjhV@9UEjShP$$XCZCVP^XEPC P$_E׍] PhSZYSwE =E}H ;Ht9H H E܃ =u^E؃ =u1e[^_]Ð5h X5Ӎt&Q2ƍ&U@2qv12뙍&URQPlPShhËE؃ =tU1 SËE =tU1Gt PR WE܃ =tU1땉ƃ SˉƋC =tUh1׉뺉몉ƋC =tҍUG1ȉw&' T$B ;Bt!t L$B B Ív'L$QPRې&D$ L$$L$ B ;BttB B Ít&L$QPRᐐ&VSt$ \$$F9tAPVt PRۉ^t\$ B ;BttB B [^Ðt&L$QPRސ&UWVS}@]E CCWhPC C [C[CC ZYjPECC8hEčEPEԃCHCLCPCTCXC@EC\C`CdChCDClCpCtCxC|ǃǃjPE ƃǃǃǃǃǃǃǃǃǃVǃƃǃǃǃǃǃǃǃ$YZEhPEE ǃǃǃ ƃjZYPVe[^_]Ð&EhuhDjP j!hh jhhYXVhEЉ$vhhDjW j1h8 h jhhXZuh<$&EhuhDjP j!hh jhhYXVhE܉$vEhhDjP j1h8 h jhhXZVhE؉$ƋC =tU+ VƍEЃ PωƋt PRPPjPt PR uCl PC`t PCTt PCHt PC@ P u W6|ƍE܃ Pf빉ƍE؃ P릉ƍ P&UWVS$]{jWu* ChXZSVs$e[^_]ÍEhuhDjP j!hh jhhYXVhE$yÍE P$ V W$v'=tÐUShu]Í h$ hhh]à h$t&UWVSLj:PxuE܃]PWVXZVS$E =EĀ8/EPW}WYXEWPljE<$M܃}Q@$pWXEZWPẺ$}؍Ẽ uPW<$SE؃ =]Ẽ = Eȃ = Eԃ = EЃ = EċPu/SuEă =oEe[^_]f|/uʃ VE}PEE܃ WuSPE =E =E܃PuE܃ =h1'\t&E̍]܃Ph} S^E_SPƉE4$UȃR@$pEPY}[VW<$u uWV4$uE =E؃ =Eԃ =E =E܃ =vI&t&U8&kvEPhuUt& &t&%t&%t&%t&%t&U%XvU%7vU%v%t&y%t&i%ËEԃ =tUM%E =tU8%E܃ =tU#% SɉËE =tύU$ʼnËE =tU$E؃ =oU$bËE؃ =t$Ẽ =t$Eȃ =t$Eԃ =tr$EЃ =u5Eă =1UL$$щ둉ËE܃ =tˉ)$ËEă =tU$E =U#뇉ډËE؃ =lU#_ËE =tU#E =4U#'މ& @$JE PÐt& @$JE PÐt&S\$L$QRp$S[S@$t>h p YXSjIXZSD$0$$PP5D$0Z5&UWVSL]'8jVst܅uC v8u& stCe[^_]Ít&DžPVXZPh* S hSWXZh WPY[VPSXZhSV_Xh VWY[h# WVVt& P hhjWY^h h rRP<$ = uljÍEЃuPEt PR SËẼ =tÍU볉ËEȃ =tU뜃uu W] Suh5Ẽ =tU 5ËẼ =tUhvvUWVS1@j@VEjPSV PhWF=umCs<@t2 CRfz둉먉뿉j~, P UWVSӃ4Eh Rh Sh SZuhhjV_Xh hZYh P rRP4$Eԃ@@Eԍe[^_]Ív}ԃ GGjÉEЃ G}䍴&tW6S uߋEԉXEԍe[^_]Í}ԃ GGj ÉEЃ  G}䍴&tW6S@ uߋEԉX농&}ԃ GGjÉEЃ G}䍴&tW6S uߋEԉXËEԋt P S V$˃ P^_Su뭉릃 PXYSu PXYSubV&UWVSE܃ APEԃ0EuԃPEjhPE jhV PEVPEjh\ PE jhV PZESPEj&hPE j=hPE jhz Pu$7 hhjVWV4$Et PR1ۍe[^_]Ðt&]W&} WEYMXhAPMXZAh4PMЃEuЃPEhPXEZh PEԃEuԃPEh P=EVPEhrPEY^h4PXEZhtPEY^hPXEZhPu$7 hhjVWV4$Eo PRe[^_]Ð&e[^_]ÐEh0P&Eh0P3&Eh0P&Eh0P&Eh0P&Eh0PH VEt PR SËEt PR VۉfUWVSH] uS$x <$Sh WPljEFjWPFtN; EÃjPF(PEFEt& ue[^_]Ðt&EEu܃ VE܃ jh P$ PESPE܃ j3h0PEԍU$h h RP]؃uhhjSVS$Eԃ =uAE܅t  PR] =u' S9붍&)ЉËE܅t PRPPEjP$ SEԃ =tUԍ뭉却&'USE]PhSSu jjuPE =u ]ÍUh]ÉËE =tUL SfSu [ÍX$ SR h jj t$t5 SR u\h jj t$[f SR u7h jjt$뛃 P҃of P҃뙐t& P҃뾐t&UWMbVSÃ,p$@$SWPXZjD$$P4$ȋL$,l$(D$ȉT$)ʉЙщT$L$T$L$R hdjj st  VR 1Ҹh RPUXZjD$$PȋL$,l$(D$T$ȺMb)ʉЙD$T$+D$T$Y]CXSWS\P$dž,[^_]Ív UN& P҃v' P҃>fD$xuÍt&Kv'UWVSÃ<@$D$ @$SWP4$R _1Ҹh RPS^]jD$4PkȋL$t Ve[^]Í& hV t8th PPjjh:$^t>t V Sv'UWVS8]sVEuaC C$ CPPJHB = CVuqe[^_]É'}h<hDjW jhh jhhYXuh<$Ct&}hHhDjW jhh jhhXZSh<$e[^_]ÍvU؀ W$ V$ W$v' D$ UWVS8]u {WEC C$ CPEԃ@;A!t$PVPVPEԃ@Uԃ B CWure[^_]Ív'Eh<hDjPE jhh jhhXZuhYuEhHhDjPljE jhh jhhXZSh<$e[^_]ÍVPu uԉ$ W$ uԉ$US],E E EEEE0SE$PE =u,URPE =u]Ðt&U(~ʍ~]ÉËE =tU} SËE =tӍU}ɐv'UWVSE} @JE^$;^(trtDGPCPGCYXG PC PXGZPCPE^$@^$WPR e[^_]É' WSVE@ÉƋC =tU} VƋC =tӍU|ɍ&'UWVS}u _$;_(tYt>FPCPFCYXF PC PXCZVP_$_$e[^_]É'G VSP܉ƋC =tU6| VƋC =tӍU|ɍt&UWVS}u _;_tYt>FPCPFCYXF PC PXCZVP__e[^_]É'VSW߉ƋC =tUy{ VƋC =tӍUY{ɐUWVSEu x _;_tVt>FPCPFCYXF PC PXCZVP__e[^_]ÍVSWƋC =tUz VƋC =tӍUzɐUWVSDuu ]ue[^_]Ív' SRCE˃CuPE0VXZVuVC0Y_EC,VuVEXEZVP_uXEPVE} =VWE$WuuPEuă =^E܃ =]E؃ =\EЃ =[Ẽ =ZC09EEPEpEPXEԃZPVEԃ =# Se[^_]Í&}h<hDjW jhh jhhYXVh<$T;s4t*uVEY^PEPC0EEC0@vIxqt&U8xv)xt&xt& xt&wt&wC,uVPƋE =tUwE؃ =tUwEЃ =tUwẼ =tUvw S4$ƋE =tމMwՃ W$뾉륉댉pƋE܃ =]U wPƋE =tӍUvɉƋEԃ =c냐UVS]E tDujh Vu VSE =u8e[^]Ðt6uj h V8밐t&U8ve[^]Ðuh VÈ|ËE =tUu SUVS]u SYE^uPXEZSp$E =uE =u#e[^]Ít&UuE =tvUxue[^]ÉËE =tUZu S S4$&' t$t$PÐfUSE PXEZu PYE[uPX]EZPuSSuPE =u*E =u5Et PR]Ðt&UxtE =t΍vat‰ËEt PR SËE =tU*tE =tUt붉D$D$tBD$tB1D$@$D$@(1UWVS}Ӊƃ8MWۋEtSQQh|Pډ RRhPPPEhXSUԃ SShPQQhPRXZuVE t, PRËUt RP Se[^_]Ð,Xq''Aq$Wo 0DR 0Qwm +@N6Y 5unl B Bh i5AQ]p\em-6>e&.7Q5A[c&'QxYMVo*%;|?\,BE.wIWmN"N"8,vA6*'2iv+9O)B,o(h          ''-K-S a*1+E`$82% +@o+1@n$Zt %8R,Vp/q%\t6P> %Wr %WrI9b+D9FRgFRg9FRg"!PAi+;DW"0#%TEml8F w5$Jr?W -G"'0=MV^b`?L Y f x           I-<HzOY."@L\jsAy)=?l,3%9U(2.T}p0D&|m8L&u@T&}#&!V;)EYj/,5 Nu .     a  .   " . [  E  p   w  6A 6<+(T!;3':H':H"?Ju:#8DXdt!/&@T&}Pd&%x&#`t(&&#`t(&&#h|(&&#h|(&&$K-&)&&0-=i!;FNTju$- &jP:&%%#"9EU`/.hs5#)%[gw5 &%Xdt<)2&eq(&5[q4c!'Vx4c! Oq4c!>&1_<@5d!"xN0Y&fN0Y2dD:F:tI-N4c!4c!Zp -   -  -  4c!FRmM"O7 )!O~ B]   >I  ] >  I  6d& .]&$bFP-m!>[!F[%*KS,&$,p&% 5E&4$9Nfv&H"'htc%   &(  &   &  "2=`t& @u>G O        8      7w           :  @   (     8C09'c/7EWhx/7EWhx0CQct0CQct *=B]&k                           $        Q IYj{y$K# 6AR(5Y%CW_*':F[+Vb}8+:Fa8+:Fa8+:Fa8+:Fa8. ;JVz2'3Lv[H6%1D?(i (eI\`E8~10A~0F2JCW_*g&n&v&&5&,(f&%$E (%(%+ *****)))////////(((&! $ # J# / #4444))#3222#22214443#6666666$#66666664##1 1 1 1 1 1 0 #!#!#!#!#!#!#!""#$6*+/+/+/+/+/,/,-,,/,/,/-/-/-/-/YNWw!%HWFU.Vg   '  ,( d v                 N &S           B"17QA7' s}JW1<Y 2pY$8E X$@N"90,!O(FCG1I(=fs-3|&/9 g 8  E E '%OR ]xU>+hI}}U>+hI}}U>+hI}}6 B N U>+hI}} 5I/7(&&E88-*}5>8('&#/D!3sHyWu}]R/DStx8}AVeP*?Ny**?Nv*-BQv*)T8V}YL'6R^<#}dbn,& *+ <D...\n[ DEATH ] basic_string::substr%02X(null)\0autoTERMxtermxterm-colorxterm-256colorscreenscreen-256colorlinuxcygwinyestruet1[0;3%sm[----------] [ RUN ] %s.%s, where %s = %s and [ FAILED ] ]]>]]>Non-fatal failureSuccessFatal failure:: : Value of: Actual: Expected: ()" thrown in Unknown C++ exceptionWARNING: has value "". %s has value , which overflows. The value of flag --0Environment variable = , but have left unset. < , but you have =, . <>&'"&#x; (ignoring case) Which is: (Invalid Unicode 0x\'\\\a\b\f\r\t\v\x'\"" (no terminating NUL)NULL pointing to L"%testtests%s from %s, where %s = %s Google TestNote: %s filter = %s [==========] test casetest casesRunning %s from %s. [ OK ] (%s ms) %s from %s (%s ms total) TESTTESTS%s from %s ran. (%s ms total)[ PASSED ] %s. %2d FAILED %s YOU HAVE %d DISABLED %s %s, listed below: T_[WARNING][ INFO ][ FATAL ][ ERROR ]./src/gtest-port.ccOnly one stdoutstderr./src/gtest.cc./src/gtest-internal-inl.hfailed with error pthread_mutex_unlock(&mutex_)pthread_mutex_lock(&mutex_)Condition range > 0 failed. ) was requested, ).Death test: Result: failed to die. Error msg: Expected: Actual msg: Exited with exit status Terminated by signal (core dumped) ./src/gtest-death-test.ccevent=TestStart&name=event=TestCaseStart&name=event=TestProgramEnd&passed=event=TestPartResult&file=&line=&message=event=TestProgramStartFailure Unknown result type, you tried test cases.%s %sevent=TestEnd&passed=&elapsed_time=msevent=TestCaseEnd&passed=1 fatal failure1 non-fatal failureExpected: Actual: failures Actual: containing "" not a substring of Which is: The difference between is , which exceeds , where evaluates to , , and Expected: () != (), actual: vs ), actual: "" vs ") (ignoring case), actual: ") <= () pthread_key_delete(key_)Invalid shuffle range start : must be in range [0, ].Invalid shuffle range finish : must be in range [, 0xL' []unexpected status byte (, line posix::Close(read_fd()) != -1CHECK failed: File read_fd_ == -1pipe(pipe_fd) != -1child_pid != -1close(pipe_fd[0])close(pipe_fd[1])Death test count (fastUnknown death test style "" encounteredclose(args->close_fd)chdir("") failed: execve(, ...) in failed: xml) < () >= () > ( is listed more than once. No test named You forgot to list test Test @-h-?/?--help|stack != MAP_FAILEDtestsuitestestsuitetestcaseCondition false failed. Attribute is not allowed for element <>.="runnotrun > <failuresdisablederrors this->size() (which is %zu)vector::_M_range_check: __n (which is %zu) >= this->size() (which is %zu)Global test environment set-up.Global test environment tear-downXML output file may not be null Could not write to the test shard status file "%s" specified by the %s environment variable. Invalid index (%d) into TestPartResultArray. C++ exception with description " is expected to be a 32-bit integer, but actuallyThe value of environment variable The default value %s is used. Invalid environment variables: you have Invalid environment variables: we require 0 <= Repeating all tests (iteration %d) . . . Note: This is test shard %d of %s. Note: Randomizing tests' orders with a seed of %d . capturer can exist at a time.Condition sockfd_ == -1 failed. MakeConnection() can't be called when there is already a connection.stream_result_to: getaddrinfo() failed: stream_result_to: failed to connect to Condition sockfd_ != -1 failed. CloseConnection() can be called only when there is a connection../include/gtest/internal/gtest-port.hpthread_mutex_destroy(&mutex_)Send() can be called only when there is a connection.stream_result_to: failed to stream to Cannot generate a number in the range [0, 0).Condition range <= kMaxRange failed. Generation of a number in [0, but this can only generate numbers in [0, Result: threw an exception. Result: illegal return in test statement. Result: died but not with expected error. Result: died but not with expected exit code: DeathTest::Passed somehow called before conclusion of testevent=TestIterationStart&iteration=pthread_mutex_init(&mutex_, NULL)Attempted redefinition of test case All tests in the same test case must use the same test fixture class. However, in test case to define a test using a fixture class different from the one used earlier. This can happen if the two fixture classes are from different namespaces and have the same name. You should probably rename one of the classes to put the tests into different event=TestIterationEnd&passed=Condition 0 <= begin && begin <= size failed. Condition begin <= end && end <= size failed. gtest_streaming_protocol_version=1.0WARNING: unrecognized streaming target "%s" ignored. pthread_key_create(&key, &DeleteThreadLocalValue)Error while reading death test internal: Death test child process reported Read from death test child process failed: posix::Write(write_fd(), &status_ch, 1)waitpid(child_pid_, &status_value, 0)Cannot run a death test outside of a TEST or TEST_F constructDeath tests use fork(), which is unsafe particularly in a threaded context. For this test, couldn't detect the number of threads.) somehow exceeded expected maximum (WARNING: unrecognized output format "%s" ignored. Condition typeid(*base) == typeid(Derived) failed. Condition !original_working_dir_.IsEmpty() failed. Failed to get the current working directory.basic_string::_S_construct null not valid can be found in this test case. pthread_setspecific(key_, holder_base)fcntl(pipe_fd[1], F_SETFD, 0) != -1sigaction( SIGPROF, &ignore_sigprof_action, &saved_sigprof_action)stack_size > kMaxStackAlignment && reinterpret_cast(stack_top) % kMaxStackAlignment == 0munmap(stack, stack_size) != -1sigaction(SIGPROF, &saved_sigprof_action, NULL)Unrecognized xml_element provided: Condition std::find(allowed_names.begin(), allowed_names.end(), name) != allowed_names.end() failed. Bad --gtest_internal_run_death_test flag: Reserved key used in RecordProperty(): class, so mixing TEST_F and TEST in the same test case is is defined using TEST. You probably want to change the TEST to TEST_F or move it to another test using two different test fixture classes. This can happen if the two classes are from different namespaces or translation units and have the same name. You should probably rename one of the classes to put the tests into different test cases." is not a valid POSIX Extended regular expression.the test fixture's constructor This test program did NOT call ::testing::InitGoogleTest before calling RUN_ALL_TESTS(). Please fix it.Condition 1 <= seed && seed <= kMaxRandomSeed failed. auxiliary test code (environments or event listeners)... Google Test internal frames ...UVSuF9t#&t  PR9^utEe[^]v'e[^]ÉËt R SUWVS,]Ct]uE 0VuV PVsE =ue[^_]ÍU\e[^_]Ð& j{E 9tutu =u WEԉC\\ËE =tU\ SS\$ C =u#C =u.C =uA[Ít&T$\C =tfT$\C =tɍv'T$\[S\$ C =u =u'[Ív'T$\ =t܍vT$\[S\$ C$ =u S([ÍT$\UWVS8}hÍ@4$E5ƃ C4ǃƃFǃǃǃǃ3 CYNXjQXZC@DjPs @C( C44C C CCCCC C$$C C,C0 YXVuXZU E2PXEZpPPE =ue[^_]ÍU\e[^_]É8dEV= Ɖ< C4u$4$E =tU\t PR S VY^hSX^^^^8^^^^^^^^^^^^^^^^^^^^^^]^]0nPoPoPoPoPoPoPnpnnnnnoPoPoPoPoPoPoPoPoPoPoPoPoPoPoPoPoPoPoPoPoPoPoPoPoPo0oPoPoPoPoPoPoPoPoPoPoPoPoPoPoPoPoPoPoPoPoPoPoPoPoPoPoPoPoPoPoPoPoPoPoPoPoPoPoPoPoPoPoPoPoPoPoPoPoPoPoPoPon02unknown file./This program contains tests written using Google Test. You can use the following command line flags to control its behavior: Test Selection: @G--gtest_list_tests@D List the names of all tests instead of running them. The name of TEST(Foo, Bar) is "Foo.Bar". @G--gtest_filter=@YPOSTIVE_PATTERNS[@G-@YNEGATIVE_PATTERNS]@D Run only the tests whose name matches one of the positive patterns but none of the negative patterns. '?' matches any single character; '*' matches any substring; ':' separates two patterns. @G--gtest_also_run_disabled_tests@D Run all disabled tests too. Test Execution: @G--gtest_repeat=@Y[COUNT]@D Run the tests repeatedly; use a negative count to repeat forever. @G--gtest_shuffle@D Randomize tests' orders on every iteration. @G--gtest_random_seed=@Y[NUMBER]@D Random number seed to use for shuffling test orders (between 1 and 99999, or 0 to use a seed based on the current time). Test Output: @G--gtest_color=@Y(@Gyes@Y|@Gno@Y|@Gauto@Y)@D Enable/disable colored output. The default is @Gauto@D. -@G-gtest_print_time=0@D Don't print the elapsed time of each test. @G--gtest_output=xml@Y[@G:@YDIRECTORY_PATH@G/@Y|@G:@YFILE_PATH]@D Generate an XML report in the given directory or with the given file name. @YFILE_PATH@D defaults to @Gtest_details.xml@D. @G--gtest_stream_result_to=@YHOST@G:@YPORT@D Stream test results to the given server. Assertion Behavior: @G--gtest_death_test_style=@Y(@Gfast@Y|@Gthreadsafe@Y)@D Set the default death test style. @G--gtest_break_on_failure@D Turn assertion failures into debugger break-points. @G--gtest_throw_on_failure@D Turn assertion failures into C++ exceptions. @G--gtest_catch_exceptions=0@D Do not report exceptions as test failures. Instead, allow them to crash the program or throw a pop-up (on Windows). Except for @G--gtest_list_tests@D, you can alternatively set the corresponding environment variable of a flag (all letters in upper-case). For example, to disable colored text output, you can either specify @G--gtest_color=no@D or set the @GGTEST_COLOR@D environment variable to @Gno@D. For more information, please read the Google Test documentation at @Ghttp://code.google.com/p/googletest/@D. If you find a bug in Google Test (not one in your own code or tests), please report it to @G@D. GetParam()TypeParamthrow_on_failurestream_result_tostack_trace_depthshufflerepeatrandom_seedprint_timeoutputlist_testsfiltercolorcatch_exceptionsbreak_on_failurealso_run_disabled_testsinternal_run_death_testdeath_test_use_forkdeath_test_stylefastM % A H 6 * % 9H % 9H GTEST_SHARD_STATUS_FILEGTEST_TOTAL_SHARDSGTEST_SHARD_INDEXtest_detail.xml**DeathTest:*DeathTest/*DISABLED_*:*/DISABLED_*` Stack trace: S\$ C$ =u%C P$([ÍT$\WVSt$ |$$9tt =u S>[^_Í&T$\UWVSu} 9t1t+C x P =u S>e[^_]fU\މƋ A=tU\ VUVS]uu S4$ PVSe[^]Ƌ A=tU\ VUWVS8} ]uWYZ UPRS uWSXZVSe[^_]Ƌ A=tU\ VUWVS`WE Dž`EECEEEE,,Dž0,CY^jPXZ44AjP5 F,TDž, Dž`4Dž4 $Dž8Dž<Dž@DžDDžHDžLDžPYX8Dž8DžXDž\ PWE 'RP(P(4P|p( = 8Pu\ Dž, Dž`4Dž4 Dž8 =T Dž8PF5,4@4C, <$,Dž`Ee[^_]4hPt&(\N&&\':[tË( =t &\, P$8 PX,ZhP Dž`W$S5 ,É,UWVS`WE Dž`EECEEEE,,Dž0X,CZjPY^44A50jP5 F,TDž, Dž`4Dž4 $Dž8Dž<Dž@DžDDžHDžLDžPX8Dž8DžXZPWDž\ E 'RP(P(4Ps(P8Pu\ Dž, Dž`4Dž4 Dž8 =T Dž8PF5,4@4C, <$,Dž`Ee[^_]&4hPt&(\Mt/Hȅ&P밍t&HQPЉLb)k8 PZ,YhP Dž`W$,S ,ˋ(pu, P$HtPP&PV뾋PJHUSE ]PYXE 0EPRXZuSU t RP؋]ËUt RP SUSE ]PE p0EPRXZuSU t RP؋]ËUt RP SUVS]u SXZuSe[^]Ƌ A=tU\ VUVS]Ct PCe[^]ÍvuhahjV j hh j@hh4$C떉à V$UVSuue[^]ÍuhyhDjV jhlh jhhXZSh4$e[^]Éà V$UVSE@Pu e[^]ÍvuhHhDjV jhh jhhXZSh4$e[^]Éà V$UWVS(]SuCCe[^_]Ð}h<hDjW jhh jhhXZVh<$딉à W$UWVS]CU rVRP9tjuhUhjV j&hhC pPh jhPC pPW4$e[^_]Ít&uhPhjV j hh j5hh4$C  V$ V$UVS]Ct PCC =uC =u"e[^]ÍvU\C =tvU\e[^]ÉƋC =tU\KA=tU\ VUVS]Ct PCC =u'C =u2 Se[^]Í&U\C =tэvU\ĉƋC =tU\KA=tU\ VUVSEXtS@=utCt PCC =u6C =u Se[^]ÍU\ݍU\ SЃe[^]ÉƋC =tU\KA=tU\ VUVSu^tS@=u|Ct PCC =u>C =u! S Ve[^]fU\ՍU\븍 SЃƋC =tU\KA=tU\ VUWVSu܃$]xu V jhrVCU܃rVRP9tjuhUhjV j&hhC pPh jhPC pPW4$E܃ =uie[^_]ÐuhPhjV j hh j5hh4$CVS뎍&U\e[^_]É VE܃ =tU\ SE܃ =tU\؃ VUVS]E pEPhSYXS]S4$ PVSXEZSpE =uE =u&e[^]Í&U\E =tݍv\e[^]ÉE =tU\E =tU\ SUVS]E pEPh2SYXS]S4$ PVSXEZSpE =uE =u&e[^]Í&U\E =tݍv\e[^]ÉE =tU\E =tU\ SUWVS(E uX$S~i:]}SPW WhLS$vE =uQE =u\F PR e[^_]Ðt& ÈSu|&U\E =tv\뛉ËE =tU\E =tU\ SUWVSuD} _KwVDG}ԉEЍEЉ$WEĉ$PX]ȍEZPhiS$]S jhSE؃ WSPYE[]hPSX}ZVSWE<$pE =E܃ =E؃ =Ẽ =Eȃ =Eă =Eԃ =E =e[^_]Í&U\E܃ =r&\E؃ =d&\Ẽ =U&\Eȃ =F&\Eă =7&\Eԃ =(&\E =&\e[^_]É>y!\C~E =tU\E܃ =tU\E؃ =tU\Ẽ =tU\Eȃ =tU\Eă =tU\Eԃ =tU\E =tU\ SẼ =tU\UVSEu]PVXZVhSE$pE =uE =u'e[^]Ð&U\E =t܍v\e[^]ÉËE =tU\E =tU\ SUVSEPu e[^]ÍuhyhDjV jhlh jhhXZSh4$e[^]Éà V$UWVS(]CPu Se[^_]Ð&}hyhDjW jhlh jhhXZVh<$덉à W$UWVSE֍u؃0PhVEXxXZVuV jhrVCU܃rVRP9tjuhUhjV j&hhC pPh jhPC pPW4$E܃ =E؃ =use[^_]ÍvuhPhjV j hh j5hh4$C&VSpt&U\e[^_]ÍU\cI\#à VE܃ =tU\E؃ =tU\ SE܃ =tՍU\˃ VUWVSuԃD] CXS\EEUPVS :}EURPW]̃ WhS$]S jhS}؃ VSW]܉<$S jh SXEZSpE܃ =uTE؃ =u_EЃ =ujẼ =uuEȃ =|Eԃ =e[^_]ÍvU\E؃ =tv\EЃ =tt&\Ẽ =tt&\Eȃ =tt&\Eԃ =}\e[^_]ÉCE܃ =tU\E؃ =tU\EЃ =tU\Ẽ =tU\Eȃ =tU\Eԃ =tU\ S량n͉ËEЃ =tU\UWVSuԃD] C0S4EEUPVS :}OURPW]̃ WhS$]S jhS}؃ VSW]܉<$S jh SXEZSpE܃ =uOE؃ =uZEЃ =ueẼ =upEȃ =u{Eԃ =e[^_]fU\E؃ =tv\EЃ =tt&\Ẽ =tt&\Eȃ =tt&\Eԃ =tt&\e[^_]ÉCE܃ =tU\E؃ =tU\EЃ =tU\Ẽ =tU\Eȃ =tU\Eԃ =tU\ S량n͉ËEЃ =tU\UWVSuԃD] C$EEUPV[$S:Eƍ}ȃPRW]̃ WhXS$]S jhS}؃ VSW]܉<$S jh SXEZSpE܃ =E؃ =EЃ =Ẽ =Eȃ =Eԃ =e[^_]Ð ÈSt&U\E؃ =r&\EЃ =d\Ẽ =]&\Eȃ =N&\Eԃ =?&\e[^_]É?EЃ =tU\Ẽ =tU\Eȃ =tU\Eԃ =tU\ S밋E܃ =tU\E؃ =tU\EЃ =uU\hv막UWVSE܍u(]PEYxXE 0VXEZpPWE =u^{twEuP}W PWsE =u2E܅t PRe[^_]Ðt&U\똍\ō& jZY PCPe3ËE =tU\E܅t PR SE =t׉\UWVSE(u ]PExts V PVWst}EuPuV PVsE =u8Et PRe[^_]Ív@xGPW뉍U\뾍 jZY PCP_ËE =tU\Et PR SUVSE]PE pPEPstjEuPuV PVsE =u%Et PRe[^]É'U\э jZY PCPrËE =tU\Et PR SUWVSE(u ]PExts V PVWst}EuPuV PVsE =u8Et PRe[^_]Ív@xGPW뉍U\뾍 jZY PCP_ËE =tU\Et PR SUVSE]PXEZu PstaEuPuV PVsE =uEt PRe[^]ÍU\ڍ jZY PCP{ËE =tU\Et PR SUWVSE(u ]PExts V PVWst}EuPuV PVsE =u8Et PRe[^_]Ív@xGPW뉍U\뾍 jZY PCP_ËE =tU\Et PR SUVSE]PE 0tx V PEVPst|EuPuV PVsE =u7Et PRe[^]ÍvEjh0P늍U\뿍 jZY PCP`ËE =tU\Et PR SUWVSE(u ]PExts V PVWst}EuPuV PVsE =u8Et PRe[^_]Ív@xGPW뉍U\뾍 jZY PCP_ËE =tU\Et PR SUWVSE(u ]PExts V PVWst}EuPuV PVsE =u8Et PRe[^_]Ív@xGPW뉍U\뾍 jZY PCP_ËE =tU\Et PR SUWVSE(u ]PExts V PVWst}EuPuV PVsE =u8Et PRe[^_]Ív@xGPW뉍U\뾍 jZY PCP_ËE =tU\Et PR SUWVSEEw_E_UсtTÁمIˉЉ HÉ)É)9Bƒw'E@Ee[^_]t&t Pƅ5 DžDžƅCDžDž Dž$Dž(ppDžtpCY^jPXx=Zx@8jP=@pDžp Dž4Džx $Dž|DžDžDžDžDžDžYDž|Dž_|Dž WPxE@\$4$DŽ|`$E5 CDž`_EEEEEE,,XDž0,CjP=Y^4@48jP=@,TDž, Dž`4Dž4 8$Dž8Dž<Dž@DžDDžHDžLDžPX`Dž8DžXZWPDž\ 4E@\$4$DŽ8Y\,^PWp$`Ph$ƅhDžlP^ZU RPZYhOPYU^RPdT4$d jhVAPXZVTdt  PRhYTZY`QPZYhPZYWPZYPult = W` =\ =\Dž, Dž`4Dž4 Dž8 =wT Dž8P5@,54@4C5 ,,`Dž`$Džp Dž4Džx Dž| = Dž|P5= @p5x@xCppDž$Ee[^_]v'h\I,\?h\yh\-\ qQS5 pÉp DžP$S5 ,É,` Dž`Pp P$볉à W_X,hP먉cDdt PRPPljP` =t h\\ =t h\, PF뜉à WXpZhPUWVSEݕPEݕHTPTLHLTTP ËLLH9s1)ڃwZwUvE@Ee[^_]w9r)ӉȉÐ&TP 2 Pƅ DžDžƅCDžDž Dž$Dž(ppDžtpCY^jPXxZx@jP=@pDžp Dž4Džx $Dž|DžDžDžDžDžDžYDž|Dž_|Dž WPx @TPVDŽ|`$E5 CDž`_EEEEEE,,XDž0,CjP=Y^4@48jP8@,TDž, Dž`4Dž4 $Dž8Dž<Dž@DžDDžHDžLDžPX`Dž8DžXZWPDž\ 4 @LHVDŽ8Y\,^PWp$`Ph$ƅhDžlP^ZU RPZYhOPYU^RPdP4$d jhVBPXZVPdt  PRhYPZ`YRPZYhPZYWPZYPult =1 W` =\ =\Dž, Dž`4Dž4 Dž8 =T Dž8P5@,54@4C5 ,,`Dž`$Džp Dž4Džx Dž| = Dž|P=5@px@xCp pDž$Ee[^_]t&LH A؃s؃ډAh\,\h\Oh\\ =OS= pÉp DžP$dt PRPPljP` =t h\\ =t h\, Pp P$븉ω= W_X,hP` Dž`P랋S= ,É,ȉĉy WXpZhPUVS]3t PR 3ue[^]ÐuhhDjV jhYh jhhXZSh4$e[^]Éà V$UWVS8}7t  PR 7tUuhhDjV jhYh jhhXZSh4$w_9u1 9t!C =tU \9u䐍t&wt Ve[^_]ÉEà V]ԃ_w9tF =tU\ 9u_t S uUWVS,}u G+9ƉErxnE9E;u]E)~=Eԉu &SuE Uԃmʃ20 uЍe[^_]ÍEh:hjPE j.hxh jhrhXZVh jhPYXuS[ZhPYuE9EEh=hjPE j.hh jhhXZuh jhPYXVS jhPXZuSZYhPXur u$ u$VSD$ stF0 w;j D$PSL$ 9uu 9t v1[^ËT$$UWVS0] ujhS<\$t&jhSt&jhS jhSXZWSF<jhSe[^_]Íjh7S jhS͍vjhSh&jhSH&jhS(&jhS&jhS&jhS&jhS&jhS&G^EWPEYXEPEhPXEZpPSE =E =jhSIVjhSXZWSEWPY^jhSE pPSE =U\U\jU\L'EEjPS jhSQLE =tU\E =u SËE =tU\0Pp8UWVS0] ujhS<\$v'jhSt&jhS jhSXZWSF<jhSe[^_]Íjh7S jhS͍vjhShjhSP&jhS0&jhS&jhS&jhS&jhS&jhS&G^ ERPEYXEPEhPXEZpPSE =E =jhSLVjhSXZWSvEVPY^jhSE pPSE =U\U\bU\Dt&EEjPS jhSQLE =tU\E =u SËE =tU\0Pp@UWVS ] ujhSډmjhSue[^_]Í&jhSYXVStFwjhSe[^_]Ít&EVPXZjhSE pPSE =tU\뛉ËE =tU\ SWVSt$ |$$9tt =u S>[^_Í&T$\UWVSt$0|$4l$8F;FtMtPFPVP])u[^_]Ð&)RWP܍)Љ9D$)щL$ t$L$ tE)ʼnuoL+n)u=ͅt P\$n^H&D$)fUWQL$L$ 뫐&UPS~=?6\$)1ۅF(UWVSt$0|$4^;^tItCCFD$80C)u7[^_]Ít&)PWS) 9)‰T$ SŋD$T$ )tD$8uhVL )u6<t P.~^Nf)눐t&RT$WQL$T$ L$몃QL$t$UL$ z?0)…*щD$1=UWVSt$0|$4l$8F;FtMtPFPVP])u[^_]Ð&)RWP܍)Љ9D$)щL$ t$L$ tE)ʼnuoL+n)u=ͅt P\$n^H&D$)fUWQL$L$ 뫐&UPS~=?6\$)1ۅF(UWVS WSS*E =tU\E =tU\E܃ =tU\EЃ =tU\Ẽ =tU\Eȃ =tU\E؃ =t\ S렉뱉‰UWVS WSS*E =tU\E =tU\E܃ =tU\EЃ =tU\Ẽ =tU\Eȃ =tU\E؃ =t\ S렉뱉‰UWVS WSS*E =tU\E =tU\E܃ =tU\EЃ =tU\Ẽ =tU\Eȃ =tU\E؃ =t\ S렉뱉‰UWVS WSS*E =tU\E =tU\E܃ =tU\EЃ =tU\Ẽ =tU\Eȃ =tU\E؃ =t\ S렉뱉‰UWVSt$0|$4l$8F;FtMtPFPVP])u[^_]Ð&)RWP܍)Љ9D$)щL$ t$L$ tE)ʼnuoL+n)u=ͅt P\$n^H&D$)fUWQL$L$ 뫐&UPS~=?6\$)1ۅF(UWVSt$0|$4l$8F;FtMtPFPVP])u[^_]Ð&)RWP܍)Љ9D$)щL$ t$L$ tE)ʼnuoL+n)u=ͅt P\$n^H&D$)fUWQL$L$ 뫐&UPS~=?6\$)1ۅF(UVSEuPE tP S PESPRuVU t RPe[^]Ejh0P벉ËUt RP SUWVSt$0|$4l$8F;FtMtPFPVP])u[^_]Ð&)RWP܍)Љ9D$)щL$ t$L$ tE)ʼnuoL+n)u=ͅt P\$n^H&D$)fUWQL$L$ 뫐&UPS~=?6\$)1ۅF(UWVS \$$L$(t$ l$,ϋC);Ct9t'UQS [^_]&t UCC [^_]WVS\$$|$ uDt& St.s WCs =tύT$\čt&[^_UWVSD$4pPT$ D$8T$8ol$mt-EX9F)QWPDÅyϋm uӋD$9D$ tF@X9FQPW)څD…xD$0T$D$0[^_]D$0T$ D$0[^_]UWVSE pE؅EExFt>ƋFXE9FӃRPuUU)مDxF 1Ʌu‹E܄ɉu܉EuA)RuuDÅE0@Ee[^_]u؍&E 9p t. V}Xu܉Ƌ?][}9F뉉u܋u9uEVrX9މF)QRPD1xt jÍ@uPuuSVE @E@Ee[^_]E܅f1 jÍ@녃 P$ SUWVS]tt@ptG>*tQt4uh{hDjV j3h\ h4$jhhSe[^_]à V$UWVS`WE Dž`EECEEEE,,Dž0X,CZjPY ‰44B^jP8@,TDž, Dž`4Dž4 $Dž8Dž<Dž@DžDDžHDžLDžPXZVWDž8DžXDž\ E p04PXZVu\ Dž, Dž`4Dž4 Dž8 =T Dž8P5  @,4@4C,<$,Dž`Ee[^_]t&+\k3S5 ,É, Dž`W$, P$밃 VY,^hPUWVS \$$|$(l$ t$,)߉@sVtUsVtJsVtO 9t`3Vu] [^_]&v] [^_]] [^_]D$()t2tt=D$(E [^_]7Vt*7Vt7Vu}F|$$UWVS l$$t$()D$,{.&E9xtPE9xtxE 9x9E9xuуWSPuD$ (D$ [^_]vWSPuD$ UD$ [^_]&WSPrD$ U랍&WSPVD$ U st&D$()ttVtFD$ L$(HD$,(]9Xt]9Xu׃SUPuŋD$ 0D$,(]ыL$,)P]9t밃RUPu뿃SUPu뫋t$$XUWVS \$$|$(l$ t$,)߉ft6pCt6pCt6pC t6p9zD$()t:ttMD$(E [^_]t6pt=t6pt t6puv] [^_]'] [^_]]˃ ]UWVS t$ D$$9tmut h &)t$,jPǍh t SVUu* [^_]G 損& [^_]ÐGD UWVS,Eu 8vEԍElm}hh WtnE9t!EԍTDv'8x9uEE =@E9z=te[^_]Ít&hh~ Wthhm WVhhg W8hh Whh Whh` Whh WhhU WhhN WhhC Wfhh7 WHhh0 W*hh( W hh Whh Whh WEh Pu-&E =U\Eh PtÍEh PtEh Pt*uJËE =tU\ SUWVS,E} 8v47PEPEZYhh PEtjE9tD7T'0p9uEE =`E9z=te[^_]Ít&hh~ uvhhm uVhhg u6hh uhh uhh` uhh uhhU uhhN uvhhC uVhh7 u6hh0 uhh( uhh uhh uhh uEh Pu-&E =U\Eh PtÍEh PtEh PtE*u)ËE =tU\ SUWVS]tt@ptG>*tVt4uh{hDjV j3h\ h4$jhhSe[^_]à V$UWVS(u6t Pe[^_]Í& jËFCY_S6u eC[^_]f}hhDjW j&hD h jhhXZVh<$뜉à W$VS\$ t$$9u-t&9t! =tT$\9u䐍t&[^UWVS<}u G;GtPRPGGEuPWBZ)э<~t&CPS9uEPVE =ue[^_]ÍU\))ˍŨ PE]Љ]tuu]9ƉEt%t&tuSEE9uߋOCEĉ9ΉMt't&t VS9uuGEԋ7;uuDt&9ut2 =tU\9vPE?)&EԋEԅt PEЋM̉_G2qH?w)˅EE PZYSuE =tU\ SMЉMă PEăt:uuEЅt P SEȋ =tȍU\뾉( P^_SunNtÐt&UWVS,E$}u W<$hE =! 59u.9t! =tM\9ދMuE1ۉ u uzv'E9tcVW ;tytWPE =tU\E9u'u u@$t&e[^_]ÍWPh둍t& hӍU\E =tU\ SE =tU\ SUWVS,}te[^_]Ív'~E ]lmShE =  9ȉEԉt8} 9t! =tڃ\9u捴&}E1u cv97tYE lm;twtSPE =tU\97ut&u W@$ hv'SPh듍U\E =tU\ SVS\$ t$$9u-t& 9t!C =tT$ \9ut&[^UWVS8E0t& PEԋEԍe[^_]É' j‰EЃEԋEX+XBBB iEE̋MÉAAY MyY9ƍtCFCPFP 9uՋEЃpPE0 uhhDjVY_hD h_ZhPZYSP4$&=UUUw SẼuh EЋ@t P u$ V$ PXZVuUVSu] @$utu9 VӃe[^]É'u Vv \Vf\뿃uz ]P$RMƒRRSjE =tU\kE =tU\ S ]PM1҉PPSjE =tU\& PE =tU\ S SUVSu] @$utu9 VӃe[^]É'u Vv \Vf\뿃u| ]P$RMƒRRSjE =tU\1iE =tU\ S ]PM1҉PPSjE =tU\1& PE =tU\ S SUVSu] @$utu9 VӃe[^]É'u Vv \Vf\뿃uz ]P$RMƒRRSjE =tU\kE =tU\ S ]PM1҉PPSjE =tU\& PE =tU\ S SUVSu] @$utu9 VӃe[^]É'u Vv \Vf\뿃u| ]P$RMƒRRSjE =tU\1iE =tU\ S ]PM1҉PPSjE =tU\1& PE =tU\ S SUWVS<}u ]G;Gt!PPPPRPG GCE܋CSEEPWZB))ziɫ~+'PXPPPSP9uދE܃FEFEPVE =ue[^_]ÍU\)i )ЉEԍIM PEЋEEЉEt MȃCAASP]9ƉEt4t"MԃACȃPCPE E9űOC Eĉ9ΉMtt WEUĉFEFR~G =tU\G =tU\ SMătM u Pt*E9Ét- V9u P WEąu묉 } )ׅEEEԃ P$E =tU\E؃ =tU\ S?ՉߋG =tU\G =tU\볉Ѓ PUăUWVSu} ]9t4v'tVSXFZPCP9u֍e[^_]Ƌ =tU\ P9]t uE9]u SUWVS,]u{;{t"GPWXGZPGP{E{VPYE_VPSB+E ~/Ѝr9ut@F =tߍU\Ս?9vJM E)U\븋t PEЋM̉{ȉCwM )҉EEE P$E =tU\ SA=tU\ۃ PttE9Ɖty S9ud=Eԋ =tU\ SEЃt& u PUЃuڃ uEЅuщ , =tU\؃ PEЃ9tEԉǃ S9u} SrS$h hhhXZjho Y[jh XZjh Y[h:h \$SPh hhhXZh h SPh hhhYXhh SPh hhhXZjh YXjh XZjh YXjh XZjdh YXhh SPh hhhXZjh  hhhYXh h  SPh hhhXZjh Shh hhh  hhh hhh([N7testing8internal26ThreadLocalValueHolderBaseEN7testing8internal26GoogleTestFailureExceptionEN7testing8internal9DeathTestEN7testing8internal16DeathTestFactoryEN7testing8internal23DefaultDeathTestFactoryEN7testing31TestPartResultReporterInterfaceEN7testing8internal24HasNewFatalFailureHelperEN7testing4TestEN7testing8TestCaseEN7testing17TestEventListenerEN7testing22EmptyTestEventListenerEN7testing8UnitTestEN7testing32ScopedFakeTestPartResultReporterEN7testing8internal27OsStackTraceGetterInterfaceEN7testing8internal18OsStackTraceGetterEN7testing8internal35DefaultGlobalTestPartResultReporterEN7testing8internal38DefaultPerThreadTestPartResultReporterEN7testing8internal12UnitTestImplEN7testing8internal17StreamingListener20AbstractSocketWriterEN7testing8internal17StreamingListener12SocketWriterEN7testing8internal17StreamingListenerEN7testing8internal27PrettyUnitTestResultPrinterEN7testing8internal17TestEventRepeaterEN7testing8internal24XmlUnitTestResultPrinterEN7testing8internal13DeathTestImplEN7testing8internal16ForkingDeathTestEN7testing8internal15NoExecDeathTestEN7testing8internal13ExecDeathTestEN7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEE11ValueHolderEN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE11ValueHolderEzD+g Xa{Sstd=$2@'2'2'2'2'2'2(2@(2[(2w(2(2(2(2(2)2!)2L)2g)2})2)2)2)2)2*2:*2Z*2u*2*2*2*2*2+2+28+2+2,2-,2L,2k,2,2,2,2,2 -2--2M-2l-2Ƃ-2Ǣ-2-2-2.2.20.2N.2m.2ϋ.2Ъ.2[2 v2 3S3\3^ ? ,4Y G4_)  4c<  4gO ) G#O0( \8v\8{\8\8\8\8 r*ŐvŐ{ŐŐŐŐ AvA{AAAA\"9v"9{"9"9"9"9 y%dX%5hdɋϋ4eq&$ϋϋlt$"$ϋϋZ%ՋՋՋF FSՋՋϋ!:ۋ)ۋՋh?ۋMۋՋ5- ۋqۋ4m:4?Q #?ϋ5$$eof(c?kH,v?%59%4y6$%dX7'5=c;eqAM=$^ltE>$|ZIM%MHFQJ!UohYB&5] JmaWdQe)5i$eofm+>kHqT6566267L7cv5%58\}08_@8`K8cev8dk;M8qDJ;M8sZe 8yq%8\28_K8cv8d;M8q;M8s 8y%p h !*"CS*#\%y$/6h!ʾ!x@zK{v|(a4Rg6ib Cq"  | $ %h%gh%qR %G  &V%2&s%7'&9%B'|9Hѐ(x$} ($ )Ǒ ː)eQ˴> ː)\ϴA ːh(E* ː(j'*$ 4 ː.%!CːX hh)`Rk v ː*W%y ː+;=* ː,%o* ːh+$* +(*  Ő*+,7ː1 7 +2#O U +6Ym s *:  Ő+Ah h'*K#7 hh'+IS2h  hh+ĭ[$$ ) '(dB_I *'hoNmji *'hvJ *h%#] *#]a *#]OO ***#] *'' %( hh*(%wI< Q Őhhh*%e k Ő-|9ѐ./ Ő//% Ő/% Őא/% Őאhh/% Őאhh/%'<Ő'h/%L\Ő'/%lŐh%.,S"Ő%01I*l/ݐŐא01I2x{ݐŐ'01I=,ݐ Ő%0)f"(Ő0)q5AG1endys`fŐ1endm0QŐ0Q;0(3Ő0(30u3h 0OXh9?0XhX^2#%LsŐh%2#XŐh0NTh2%HŐh2.y-FŐ05$0D)5@h0UYdŐh1atk|h1atvŐh0IݐŐא0I`ݐŐ'0I|ݐ Ő%0%D5ݐ/:Őא0%UݐShŐאhh0%)ݐŐ'h0ݐŐ'0%ݐŐh%2q-!Ő%35%zݐ!Őא05^=ݐ:OŐאhh05%=ݐhxŐ'h05z ݐŐ'05ݐŐh%2wK:Őh%0wݐŐhא0w8ݐ1KŐhאhh0w%g&ݐdyŐh'h0w"6lݐŐh'0w9ݐŐhh%0wKlŐ%0idaUݐ"Őhh0it;FŐ0i%ӧ_oŐ0BݐŐhhא0ݐŐhhאhh0%ݐŐhh'h0:ݐ!6Őhh'0ݐOiŐhhh%0UݐŐא0'+ݐŐ'h0<[hݐŐ'0Qݐ+Őh%0v4ݐD^Ő**0XAݐwŐ''0EݐŐ0BݐŐ+.#%k|ݐ)Őhhh%+R%&ݐA[Őhh'h*h%4)%[*h%0h%h*hh2 %3Őݐ0d5W' 013%pU'(.0,'&GM0F%hf{'hh0FIhאh0FXth'h0F%8h%h0$KvO hאh0$K% |3h8M'hh0$Khfv'h0$K%k!h%h06hאh06%/h'hh06h'h06 /h8H%h0Thaqאh0%>Fwh'hh0h'h0$Yh%h0$2h אh0$%Sh3H'hh0$QHhaq'h0$%_V%h%h0qhאh0%jh'hh0nh 'h0%$h3C%h0r`\lhh0Z %א0Z%:%hhא0Z%t%hhאhh0Z%%'0Z%t%3Hhh'0Z%Jk%a{hh'h$ 4%{Q*X'''7**'''1*'''<%)>CI'Ő''47%{*tX***O****7DK****% CI*Ő**!%5(56O6bKp6 !'"h x '# %y$/6  !ʾ!8 xK{v|8Rg8ib6Cq6 | =!% %g %qR %G " !&V%2 &s%7;(&9%B'|9S (xZ$!!($!!)f!!)eQ!!)\Ԍ! " (Eދ' "&"(j2'="M".%!b q"  )`L""*W%""+;'"",%o~'" +$' ##+(''#2#'+,=J#P#+2- h#n#+6= ##*:##+AI ## '*K##  '+ISN $$  +ĭ[ԃ$7$B$5((db$'5( oNm#$'5( vl$' $%#]$'  #]$'  #]F%'''#]h"%'5(5( & %A%  *(%U%j%   *%b~%%-|9_ ./%%//%%%/%%%/%%&  /%&0&  /%@&U&5( /%e&u&5(/%&& $%.,S"&&%01I*k&&01I2&&5(01I=P'"'$%0)fi? ;'A'0)q Z'`'1endy{ y''1endM4 ''0Q!''0Q ''0(3!''0(3 ((03 3(9(0 R(X(0 q(w(2#%(( $%2#tM(( 0N ((2%(( 2.y- ))05$/)5)0DC N)Y) 0Uؠ r)}) 1atkm4 )) 1at )) 0I))0IL* *5(0I$*/*$%0%DH*S*0%U`/l**  0%)#**5( 0***5(0%** $%2q- ++$%35%)/+:+05^1S+h+  05%e++5( 05z++5(05)^++ $%2w+,  $%0w]!,1, 0w7J,d,   0w%gq},, 5( 0w",, 5(0w90,,  $%0wKX -- $%0id+-;-  0itk9 T-_- 0i%8 x--  0--  0A5--    0%xy.!.  5( 0:.O.  5(0Gh..   $%0..  0'Tx..  5( 0<ʎ./  5(0Q[@*/D/   $%0vn&]/w/  ''0]//  5(5(09//    0w/0    +.#%(0B0   $%+R%`Z0t0  5( '0 $%4)%'0 $%0h%5 00'  2 %m!0 10d5d5("1(1013%}R5(A1G10,^ `1f10F%  115(  0FI" 11 0FXK 115( 0F% 12$% 0$Kv (282 0$K% = Q2f25(  0$Kz 225( 0$K% 22$% 06w 22 06%/ϭ 235(  06C (3835( 06[a Q3a3$% 0 z33 0%>|[ 335(  0G 335( 0$Э 3 4$% 0$2P #434 0$%Sŀ L4a45(  0$Q-3 z445( 0$%_R 44$% 0qn 44 0%j $ 4 55(  0& #5355( 0%lD L5\5$% 0r[, u55  0Z %550Z%%55  0Z%.%56    0Z%%(6365(0Z%%L6a6  5(0Z%%z66  5( =!!$%5566, R9>7 #!3^7 ^ \  P  w$  (9 [ v N  RI e )0 1 S= 7˩!g7 k C ՗ 9 C  U7!7   ,f  7!7   1 8:9!J8:[w!R:!$.!+818F;g!>8F%!6dec!9= !9>hex! 9=D!9=!9 >oct!9@==!9?n !9?!"9?v!&9?!)9?(!,9?{I!/9 ?x!39@=!69=!99J?!<9=h8!N:V8=A!Q:=i!V:=O!Y:>app!lY:8>ate!oY:= !tY:>in!wY:>out!zY:=S !}Y: !7>beg!::>cur!:>end!::RW:SL:T':\m:e:h:i8%=@];/;?;L%L.yP;`;L%L3wGPx;;L9%G;3lP;;L^3ɫGP;;L,3YGP;;L%3P<<L3qP3<><L]3cGPV<a<LU%!%5(3 O;nˑ<<L'3.;^ˑ<<LAput;Aˑ<<L<y>%3;? ˑ ==G%LG%3;imGˑ,=7=L%3;?ˑX=c=%L%3";?!+ˑ==]L]B@;?Tˑ=,L, l>Cp=!i777Cp>!i999Cvp!>!i|:|:|:Cwp@>!iBBBCI-p_>!iP@P@P@C=p~>!i@@@Dp!i555 0W?E0[B>CIB!iBBBBE80[9?CI9!i9999E8.0[|:9?CI|:!i|:|:|:|:Ez0[P@j?CIP@!iP@P@P@P@E0[@?CI@!i@@@@F@0[5CI5!i5555 i@ݑ(1I<AA)s<AA)<AA(l<>$AA('I<$BB((<_$%B0B(;I<2]$GBRB(W<}r$iBtBJ<˙$B1A u=JDDCJy"%0d"-=J EECJ0*G"T<=J,E2ECJ@"DGERE,L%."cEiE,L!%5(8oF0maDEEEaR%*\FMu>N#>O6FP^I>FQ>$FR>&/>%I_TpF6n9?; $F%$% z$מF%$%7+)ZF  + )\jG% k)aFr)^4%)bF%)cF%s)dF #)_44)g*F"GF4)nىF;GF4)uFTGFS)|6FFF b*`G%M*e4%e/*f4G*lGG4G*pGG444I_T14I_T248vwH1strG?HGH< JT  H5H4%L8U,4GKH[H4%L!%5(5|H)9D, u=8\Io98_oF8aF);M8qHH5;M8sHH558yHH5%V8h8i"IIH,b8\~I;;M8qEIKI+6;M8s[IfI+616 8yrI+6% l@vI8'>'3$@oI ~I+>@r$II555I_Tp'I )RJ F%y)'()BF)%J+J6()C*BJHJ60'I"IW9,)ZVXR) K "I!:-)I!U)F!.) K"_)JJ76"_)JJ76=6C62)rJJ76$IY$<)nKJ)];ZA)iJXK)5oF)*)V9{)tX )6"7)XX6]7)XY6X"7)YY66X+) 2X8Y>Y6+tH)rXVY\Y6+N)tWXtYzY6+SI)C6YY6+SI) _BXYY6%+eN)(@6YY6+eN)/ΒXYY6%+l)7G>$ZZ66X+();Z$D[[[60/AL/[\\60/E>([5\;\60)/N֫4[T\Z\61end/WF4[s\y\60Q/`KL[\\60(3/iXL[\\60/1$\\60/#X[\\60/SX[]]62 /=)]4]660w/ t_M]X]66[0w/|4[v]]6@[62i/\9]]64[0i/l'X[]]66Z2i/^1]]64[4[2.y/k\ ^^60/X[(^3^660F/X4[L^W^660F/Կ@[p^{^660%/l4[^^660%/+@[^^660j%/94[^^660j%/$E@[_ _660/{Z$_/_660/ZH_S_6632'5:tI5HZ *`_%M*etX%e/*f$G*l__6G*p__666I_T1tXI_T2$tX*J8\`=8_oF8aŐ">8bK8cݐv8dא;M8qC`I`>7;M8sY`d`>7D78yt``>7%a8h`8i_a>Z8h`8i 38w`>7D_ Hc !% Oa _%V,Ra%Sa%TaG!%V:a@aP7G!%ZOaZaP7V7)seCmaxaP7\7#PaP7%oFM-?a>K@%A`n_(eqb7aah7(euV7aan7(yabbn7G|%b+bh7G:bEbh7t7aGYbdbh7Gsbbh7t7Gbbh7%(5;Ilabbh7)<NVbbh7ab)bch7I_Tp_` ֻj֝bֿb֨aaa`&oFa">8?KC?vN?w@RgBibjCqj_9ccz7T9cdz77cT9/d0dz7c77Oc.9>FdQdz77.bdmdz7%31I7ddz77252ddz7c70)#δcddz70),XRcdd71end5c eez71end>Vc+e1e70QGLcJePez70QP-cieoe70(3Y>ceez70(3bGcee70?cee70Icee72#ffz7cOc0NFc)f/f70X$HfNf7bAhpbfmfz7c0 scffz7c0cff7c2PB ff7c1at6'scffz7c1atHcgg7c0pS6sc4g:gz70p[cSgYg70Ucscrgxgz70Ukҍcgg7013z[cggz7013wgcgg72q~Sggz7723\H hhz73wkt4c(h8hz7c72w0Mhbhz7cc70i}?c{hhz7c0ichhz7cc2 hhz772.y hhz72jShiz7c7bvXB#i3iz772Hi]iz7cc72F-riiz7cא0&ѽcii7c'2l$iiz7[c3O~?ciiz7c3Ocjjz7cc.&0jEj!i*z7**c.BdjyjCI*z7**.P:jjCI*z7**7I_Tp5_6 (6c s$j%$%!%;8\kD8_oF8a7">8b7K8c7v8d7;M8qKkQk7;M8saklk778y|kk7%VD8h8ij7j 9 Hm !% OOl j%V,ROl%SOl%TOlG!%Vkl7G!%Zll77)se /l:l77#PCl7%oFMdF_l>KJG%Aknj(eq47ll7(eu67ll8(y٢vlll8G|ll7Glm7 8vlGm&m7G5mEm7 8GTm_m7%(5;?&Olvmm7)<"mm7Olb)>3mm7I_Tp7jk t_mցmjl֞lֻlk&7oFOl">oFKzFvFiGRgIibtCqtj9nn8T9nn88nT9/nn8}n88n.9>oo8!8.$o/o8%31IH'8GoRo8!825Cgowo8}n80)#pMnoo80),џYnoo-81end5fMnoo81end>Ynoo-80QGaqn pp80QPlen+p1p-80(3YiqnJpPp80(3bfenipop-80C}npp-80}npp-82#pp8}nn0N}npp-80'*$ qq-8bA$q/q8}n0 5nHqSq8}n0Anlqwq-8}n2PB o/qq-8}n1at6o5nqq8}n1atHAnqq-8}n0pS5nqq80p[Anrr-80Uc5n4r:r80UkAnSrYr-8013znrrxr8013)nrr-82qrr8823rr83wkAMnrr8Mn82w0ps$s8Mn}n80i}Mn=sHs8Mn0iOMnasqs8MnMn2 Mss8'82.yZss82jrss8}n8bvXss882c] tt8Mn}n82FA4tDt8Mn70&}n]tmt-8}n'2}/tt8n3OiLMntt8Mn3OMntt8MnMnI_Tp75j6(6fm 41u@4oF47K47R7 `3oIuc3q ?h8\vI8_oF8a\8">8bb8K8ch8v8dn8;M8quu8;M8suu888yuu8%V;8h8iIuIu x H3x !% Ov Iu%V,Rv%Sv%TvG!%VYv_v8G!%Znvyv88)seh<vv88#Pv8%oFM4Kv>KL%AvnIu(eqE?8vv8(eu8ww8(yv/w5w8G|DwJw8GYwdw88vGxww8Gww88Gww8%(5; vww8)<Qwx8vb)LYx x8I_TpIuv1I Mּwwvvwv&oFv">?KKJKvUK]LRg|NibMCqRIu9yy8T9y$y88xT9/:yOy8x88nx.9>eypy88.yy8%31I$8yy8825yy8x80)#xyy80),-x zz81end5vx+z1z81end>xJzPz80QG8xizoz80QPrxzz80(3Y' xzz80(3bxzz80Xxzz80ۍx{ {82#O{/{8xnx0NRxH{N{80$g{m{8bA{{8x0 )x{{8x0rx{{8x2PB )Q{{8x1at6x ||8x1atH@Xx/|:|8x0pSTxS|Y|80p[٧xr|x|80Ucz`x||80Ukx||8013zƒzx||80131x||82q }}8823P)}/}83wk7xG}W}8x82w0p^l}}8xx80i}1x}}8x0iaax}}8xx2 }}882.y~ ~82j~.~8x8bvXB~R~882Sig~|~8xx82F47~~8xn80&x~~8x'2!~~8zx3O,x 8x3O x%58xxxI_Tp5Iu66f8xI-8\P8_oF8a"9">8b(9K8c.9v8d49;M8qL9;M8sL9R98yL9%VF+8h8i\\  HF !% O \%V,R%S%TG!%Vlr^9G!%Z^9d9)se^9j9#P^9%oFM=Rπ>K#S%A'n\(eq0p9v9(eud9%+|9(yBH|9G|W]v9Glwv99Gv9Gv99Gāρv9%(5;ʜv9)<Zv9b)(3v9I_Tp\+ eρڀ+&oF㿀">HRKSRv^RfSRgUibeCqj\99T9,799T9/Mb999.9>x99.9%31I9ƒ9925N׃990)#`90),iɂ%91end5Q>D91end>ɂ]c90QG|90QPe6Ղ90(3Y590(3bP;Ղل߄90Q)9092#o2B90N[a90$z9bAu90 Å90|܅92PB Ύ91at6mX*91atHfgBM90pSpOfl90p[l90UcQ90UkAÆɆ9013z9013=92q'9923 L<B93wkxZj992w0990i}i90iч92 @992.y92j1A99bvX Ue992z992F829490&#Q͈݈9'2l93O'p 93OF8H9I_Tp5\6&6K:8\.U8_oF8a9">8b9K8c9v8d:;M8qӉى:;M8s:":8y:%V+8h8it9t ? H^ !% O׊ t%V,R׊%S׊%T׊G!%V.:G!%Z.:4:)seŠ.:::#Pˊ.:%oFM9W>KX%A?nt(eq@: &F:(euy4:=CL:(yagZ`L:G|ouF:GF:R:GF:G͋F:R:G܋F:%(5;k׊ F:)<z,F:׊b)R>@KF:I_Tp9t3~[ x &C3&9oF׊">DWKOWvZWbXRgZibxCq}t9-3X:T9DOX:^:T9/ezX:d:^:.9>X:j:.X:%31I0p:ύڍX:j:25X:d:0)#JՌX:0),7=v:1end5LՌV\X:1end>4yu{v:0QGb<X:0QPKv:0(3Y~Ҏ؎X:0(3b!v:0cuv:0ٚ/5v:2#YJZX:0N6Dsyv:0?$v:bAFX:0 /ЏۏX:0$Ɍv:2PB v:1at6lk7BX:1atHK6ɌZev:0pSs~X:0p[..Ɍv:0UcX:0Uk/aɌېv:013zX:013ʉv:2qk4?X:d:23TZX:3wk_ՌrX:Ռd:2w0X:Ռd:0i}**ՌőБX:Ռ0i{!ՌX:ՌՌ2 DX:p:2.y.4X:2jIYX:d:bvXYm}X:d:2ؽX:Ռd:2F̒X:Ռ:0&0 v:'2S X:3Oi(Ռ-8X:Ռ3OՌP`X:ՌՌI_Tp95t66-c8\A\8_oF8a|:">8b'K8c:v8d:;M8q:;M8s::8y":%V9G8h8i% i Hq !% O %V,R%S%TG!%V:G!%Z::)se|ʔՔ::#Pޔ:%oFMB^>K(_%ARn(eq:39:(eu:PV:(yms:G|:G::G:GЕ::G:%(5; :)</?:b)wS^:I_Tp%F ֋9VF&%oF">M^KX^vc^k_RgaibꋝCq됝9@F:T9Wb::$T9/x:::.9>::.ʗ:%31IT:::25::0)#0+1:0),rJP:1end5}io:1end>s:0QG0 :0QP1Ƙ̘:0(3Y :0(3baq :0Q#):0i BH:2#'&]m:0N :0!$:bAʙ:0 +Ж:08ܖ:2PB H'2:1at6ЖJU:1atHvjܖmx:0pS6 Ж:0p[ILܖ:0UcЖϚ՚:0Uk-ܖ:013zp$ :013NĖ,2:2q&<GR::23]gm:3wk::2w0::0i}tP؛:0i  :2 <!,::2.ykAG:2j\l::bvXM::2::2F`Ϝߜ::0&/:'2(:3OG@K:3O_Tcs:I_Tp%566<vAvKAw|A{X;An;A;A;A;A;A;A <A$<A?<A_<A<A<A<A<A<A<A=A.=AN=AAaAi=A=A=A=A=A=*8\&a8_oF8aP@">8b\@K8cg@v8dm@;M8q˞ў@;M8s@@8y@%V]48h8ilV@l  HV !% Oϟ l%V,Rϟ%Sϟ%TϟG!%V|@G!%Z@@)seQ@@#Pß@%oFMcߟ>Kfd%A7nl(eqP@@(eu@5;@(yRX@G|gm@G|@@G@GŠ@@GԠߠ@%(5;Hϟ@)<$@ϟb)8C@I_TpV@l+ 9 pߠ;+&V@oFϟ">cKcvcdRgfibpCqul9%+@T9<G@@ T9/]r@@@.9>@@.@%31I @ǢҢ@@25١ms@0QG9@0QPL@0(3YgʣУ@0(3b@0D@0'-@2#BR@0NRkq@0`$@bAZ@0  ȤӤ@0hh@2PB  @1at6qq/:@1atH/R]@0pS/Nv|@0p[j@0Uc@0Ukӥ٥@013z`@013R@2q,7@@23=LR@3wk[͡jz@͡@2w0Z@͡@0i}͡Ȧ@͡0i1F͡@͡͡2 @@2.y&,@2jAQ@@bvX2eu@@2~@͡@2F!=ħ@͡m@0&bݧ@'2/ @3OA͡%0@͡3O͡HX@͡͡I_TpV@5l6="J aGd idd nd@ ooF p'K q2Cq yըۨC/Cq CCq CC3 T)/C3tH |GMC3N ekC3SI 8CC3SI @6uC%3eN SCĩʩC3eN ۷uC%3~H juC3I hC(3C3H uKVC0N *CozC0 FCRd[־8\gh8_oF8a@">8b@K8c@v8dA;M8q A;M8s"-A A8y=HA%V88h8i@ ! H !% O %V,R%S%TG!%Vë,AG!%Zҫݫ,A2A)se,A8A#P,A%oFMj >Kok%Axn(eq>AY_DA(euF2Av|JA(y"7JAG|DAGȬDAPA7GܬDAGDAPAG DA%(5;F&7BDA)<"<UeDAb)yDAI_Tp@lj ֶ B+_|l&@oF">jKjvjkRgmib궴Cq뻴9flVAT9}VA\AJT9/VA>bA\Aҭ.9>ɮԮVAhA.VA%31I]nAVAhA25(8VA>bA0)#.QWVA0),OpvtA1end5VA1end>DtA0QG#p2ͯӯVA0QPJ&tA0(3Y2 VA0(3b=F&*0tA0>IOtA0B>hntA2#ۘVA>ҭ0Nm=>tA0m$˰ѰtAbAVA>0  VA>0-8tA>2PB IMXtA>1at6op{VA>1atH\tA>0pSqVA0p[\RֱܱtA0UcpYVA0UktA013zޭ39VA013)RXtA2q{EmxVAbA23VA3wkJVAbA2w0вVA>bA0i}Dy VA0iO"2VA2 2GRVAnA2.yVUgmVA2jj*VA>bAbvXVAbA2˳VA>bA2F8_VAA0&>.tA>'2CNVAޭ3OfqVA3OVA>I_Tp@5656g8\"p8_oF8aA">8bAK8cAv8dA;M8q$*A;M8s:EAA8yU`A%VJ8h8iŴ)Ŵ ! H !% O( Ŵ%V,R(%S(%T(G!%Vյ۵AG!%ZAA)se,AA#PA%oFMq8>Kr%AnŴ(eq\AqwB(euA B(yO BG|ƶBGնBBOGBGBBG-8B%(5;|(OZB)<EGm}B(b)HBI_Tp)Ŵ= ɾ8ZCw֔&)oF(">qKqvqrRg uibɾCqξŴ9~BT9BBbT9/˸BV"BB.9>B(B.B%31I*.B +B(B25@PBV"B0)#&ioB0),K24B1end5&B1end>2ƹ̹4B0QGpJB0QP> 4B0(3YJ#)B0(3b>BH4B0Vag4B0KV4B2#Q BV0NIGVĺʺ4B0.%$4BbAߡBV0 !,BV0?qEP4BV2PB ep4BV1at6]BV1atHx4BV0pS ϻջB0p[F4B0Uc# B0Ukw,24B013z}KQB013,Fjp4B2qiB"B23B3wkȿ&üӼB&"B2w0U)B&V"B0i}&!B&0it&:JB&&2 /_jB.B2.yB2jEBV"BbvXνB"B2A;B&V"B2F2 B&A0&V6F4BV'2z[fB3Ou&~B&3O&B&&VI_Tp)5Ŵ6D6 4 f4<@4oF4"9K4.9R"9 {3o2c3q ? 4t f4<@4oF4K4אR YT3hc3j ?8\F5w8_oF8aB">8bBK8cBv8dB;M8qB;M8s BB8y'B%V_8h8i; Hv !% O %V,R%S%TG!%VBG!%ZBB)seBB#PB%oFMx>Ky%AWn(eqMsB8>B(euPBU[C(yrxCG|BGB CGBGB CGB%(5;"!B)<:4DBb)"XcBI_Tp;KF ֐! >[K&;oF">xKxvxzRg,|ibCq9EKCT9\gCC)T9/}CCC.9>C!C.C%31IN'CC!C25 CC0)#G06C0),kOU-C1end5ntC1end><-C0QG5C0QP-C0(3Y`C0(3bX -C0l(.-C0GM-C2#A}brC0N-C0$-CbA;C0 KC0 -C2PB ,7-C1at6OZC1atHVr}-C0pS 4C0p[-C0UcMC0Uk-C013zC013f17-C2qaLWCC23`lrC3wkW:CC2w0iCC0i}C0iC2 v&1C'C2.y=FLC2jaqCCbvXJCC2JCC2FCB0& -C'2Q"-C3OEPC3OhxCI_Tp;56~6{ 4@4oF4BK4BRB %3oc3q ? C40 f4<@4oF4'K4kR' *-3hHc3j ? q\4@4oF4@K4AR@ G4 f4<@4oF4@K4@R@ L3hc3j ? 4@4oF4P@K4g@RP@ MS4G@4doF4dK4dRd )4ve`ft'<I_TpV@w%bP@*Kg@u8\Sd~8_oF8a5">8bCK8cCv8dD;M8qD;M8sDD8y)4D%VP8h8i* e H !% O %V,R%S%TG!%V*DG!%Z*D0D)seg*D6D#P*D%oFM >K%Adn(eq4Kv'/RgNibCq9RXTDT9itTDZD6T9/TD*`DZD.9>TDfD.TD%31IlDTDfD25;m$TD*`D0)#a=CTD0),\brD1end5 {TD1end>\rD0QGDTD0QP>rD0(3Y TD0(3brD0*5;rD0[*TZrD2#roTD*0NV*rD01]$rDbA{,TD*0 FTD*0$rD*2PB n9DrD*1at6Z\gTD*1atHrD*0pSWTD0p[CrD0UcTD0UkچrD013z%TD013>DrD2q)4YdTD`D23%yTD3wk[TD`D2w0hTD*`D0i}=TD0iATD2 3>TDlD2.ySYTD2jn~TD*`DbvX=nTD`D2mTD*`D2FTDD0&q* rD*'2$/:TD3ObR]TD3OauTD*I_Tp*56S65 t4@4oF45K4CR5 _U3oc3q ?8\oX8_oF8aD;M8q6<D;M8sLWDD 8ycD% 6,@v8>3$@o o+>@r$DאאI_Tp )C F%y)() mŐD()39D0W)ZX) !:-)!U)F!.)"_)D"_)DDD2)ۆDeD%$Y$<)n$J)]4@ZA)ZKE0T)2o E0T) E0[)w E0[)wE[)fw4[)אO[w$) j>[w$)$gK[(9)(wN>[(9),[K[)0wK[)4אK[)8_> >[)<!K'K[)@5[>B>[)D^\K]K+,?)MoGu EEX+G)|oG EE+t)4oG EE+RN)MzoG EE+B )l% E>>א+)H=M E>א+tb)Iep Eא+()k E*O)p E+)r Eא+)Eא+[)n)> Eא+[)%VkEא.Q)| E.Q) ED%E.Q) E+E.u) E%01I)GF1E E+E0)C#E0))<B E0))][aE1end)iz E1end)vE0Q)K E0Q)ME0(3)" E0(3)PE0)$4:E0)t SYE0)6rxE2 )e. E1E0)\i Eא0Yb) Eא0)7R  Eא0)"2 Eא*;)D@FQ E*;)Rneu E2i)i E2i)mx E0i)_ Eא2i)Ɲ E2i)kt# E2i)k8H E2.y)]c E0F)v| Eא0F)Eא0)@eEא0%) EE0%)[ EE0j%);0; EE0j%)VT_EE0)*x Eא0)IEא0)$E320EY:t_ )}r)F%=)K)ݐoF)Ő9{) )DG|)RXF\|)grF8(tH)(kF(N)P"F(SI) FF(SI)C5-F%(eN)\FF(eN)[-*F%(l)6$ALFF-(()S$hsFFI_Tp Q)Zr)F!=)>K)אoF))9{)} )D"7)yE]7) yE"7)$yEE+) FAGE+tH)#_eE+N).}E+SI)VEyE+SI) UyE%+eN)(ġEyE+eN)/(yE%+l)7ʬ$(EE+();$EPEEI_Tp66 M ̹*`%M*e%e/*f$G*lFG*pFF6I_T1I_T2$^U ^eR/Z2/sM%/t/g&/h/i?=/j/k_/Rg/Cq//_set/}7E`set/7ED=E1_set/7ECE01I/ǿIE7ECE0/=@OE0/A%%OE0/E1>DOE0)/NI=]cOE1end/W1=|OE0Q/`5UOE0(3/i3UOE0/$OE0/aOE0/aOE2 /2=7EIE0w/Va7EUE 0w/=7EIUE2i/\N7E=0i/l`a7E[E2i/7E==2.y/ 7E0/+a1<OE[E0F/2@=U`7E[E0F/BIyOE[E0%/8=7E[E0%/IOE[E0j%/+o=7E[E0j%/ I OE[E0/X-87E[E0/dQ\OE[Efju7E%325:t5_ *`%M*e}%e/*f$G*lEG*pEE6I_T1}I_T2$V} Q4B@4oF4\8K4h8R\8 ?4y@4oF4b8K4n8Rb8 $4@4oF49K4:R9 l4@4oF49K49R9 H4@4oF4|:K4:R|: 4U@4oF4BK4BRB 4@4oF4AK4ARA U4@4oF4\@K4m@R\@ ۔4@4oF4ŐK4ݐRŐ @iOH'3'u@: +>@>E5ITF5+>@B5lwF5I_Tp' I4 f4S@4SRfS f4 f4B@4BRB 4  f4k@4kRk H8:8?\0J7J7_ t@iYOH3 @: :+>@>}ݐGݐ+>@BE אGאI_TpY k`FCd!i\8\8\8Cd !i"9"9"9Cd*!iAAADed!iŐŐŐЮ3mg3c ?I_Tp\8 d+4ѱd4\84E4Ԅy\8R\8YNE$&)3g3 ?I_Tp"9 (4d4"94E4ԭ"9R"9YNE$ 4H f4<@4R* \0@Eb 0DŐCIB!iŐBBŐE0DŐCI*!iŐ**ŐE0DŐCIŐ!iŐŐŐŐE0DACI u!iA u uAE^0DAICIA!iAAAA4z0D\8~CI\8!i\8\8\8\8ElM0D"9CI"9!i"9"9"9"9Y^$$3g3 ?I_Tp9 R4%d494E4R9R9YNE$3Lg3B ?I_Tp|: @4ѐd4|:4E4X||:R|:YNE$jS3g3 ?I_TpB 4d4ӤB4E4kOBRBYNE$73"g3 ?I_Tpz հ4fd4z4E4".RzRzYNE$3g3 ?I_TpP@ h4d4P@4E4ԀP@RP@YNE$*3g3 ?I_TpA Y4<d4ӰA4E4n(ARAYNE$Z3cg3Y ?I_Tp@ b4ѧd4@4E4eIo@R@YNE$&3g3 ?I_Tp5 4d454E4B5R5YNE$S39g3/ ?I_TpŐ d4}d4Ő4E4EiŐRŐYNE$ ;4 f4<@4oF4*K4eR* ,4@4oF4AK4ARA 3hc3j ?+335g35+ ?I_Tp\8^|33\g35R ?I_Tp"9_33g35y ?I_Tp933g35 ?I_Tp|:f;33g35 ?I_TpB3:g3= ?I_Tpz  4<d4z4E4ܼ&(zRzYNE$}33cg35Y ?I_TpP@N33g35 ?I_TpAx33g35 ?I_Tp@333g35 ?I_Tp533g35 ?I_TpŐQc5 TH995I_Tp9999 Rg9|:^I_Tp%''|: h9BI_Tp;BBB ڐ9P@I_TpV@\@\@P@ 9@I_Tp@@@@95I_Tp*CC5)m qB5I_Tp;BBB Qq9^I_Tp9999 $q|:I_Tp%''|: qP@I_TpV@\@\@P@ q@I_Tp@@@@q5I_Tp*CC53&g3 ?I_Tpg 33Mg35C ?I_TpG33tg35j ?I_TpB686=8o3.* LV8IUH ~[L%bL %[LV80 lIy K%. !'[L0m @KI%0 V+do[L!%5(b.yB)&M[LV8hB~S[L,L~DE M!O666EjH!K666E M!777 +Pˑ8(ˑ' +Pˑ\(ˑ%ETh![PvP66EM!W66E9!_PP6KCb|E8Bl+xj$RR p $!%('א  ˑT!%(ˑא p $!%(א'  v{%mRvmmvE84ɒ!&fS[wE:M4ɾ!&Btx  |*{%ZR|ZZ|E4H!&kQC(gI_TpŐE7z .~|EaR Jˑ!%(ˑE$(/*I_Tp058 S/b'8ia '%!%5(5Astr~9%F@F^  JNE M!w^7m^7^7El$lF%Ej$ˑ!%(ˑlFC ez!i777Cp!i7I_Tp7777C!Tz!i999CF!i9I_Tp999(:C`ze!i|:|:|:C!i|:I_Tp%|:|::C7z!iBBBCa!iBI_Tp;BBB J{%,|RJ,|,|JCF z/!iP@P@P@C<\!iP@I_TpV@P@P@@C\z{!i@@@C_!i@I_Tp@@@&A 6 {%fRff  $$RdCC H 0$"RdCCC%DzA!i555CȬn!i5I_Tp*55$DE_8$I_Tp%ET(/\8I_Tph8Cܳ\I_Tp\8CKz!i\8\8\8C`!i\8I_Tp\8\88Ey(/"93I_Tp.9CD\MI_Tp"9C zl!i"9"9"9C{!i"9I_Tp"9"9X9EC(/ŐI_TpݐC\I_TpŐC z!iŐŐŐCs>!iŐI_TpŐŐJ7C:OEI_T1I_T2ŐאE0kŐvCIB!iŐBBŐ "0ŐCIB!iŐI_TpBBŐJ7Ew BRBr/BB/EE;4!&'5Eo-Z-_'''<Eq-rPCI''' SyoR\8\8  I\8Y{$v\8{\8\8\8\8 p!yR\8\8 7[\8Y{$v\8{\8\8\8\8Ei)I_Tp9%ii HR"9"9 ҮI"9Y{$v"9{"9"9"9"9 X!R"9"9 wq["9Y{$v"9{"9"9"9"9E4ɉ{!&*DE&-Z_***<E)-rCI***E$F%E'q$j!%%Ej$ˑ%!%(ˑjEj$ˑQ!%(ˑFG  $!%(א'C?(I_Tp%::C=OI_T1I_T2'Ő5E0kŐCI*!iŐ**Ő 0ŐDCI*!iŐI_Tp**ŐJ7EY{$I_II@I_OI@@@@ Lt@zY{$I_II@I_OI@@@@ (@I_II@I_OI@@@@E;c0k@CI@!i@@@@ 0@CI@!i@I_Tp@@@@&A A0'@]CI@!i@@@@&A 0v@v@{@@@@ 05Y{$I_II5I_OI5555 N5Y{$I_II5I_OI5555 59I_II5I_OI5555E0k5jCI5!i5555 %v05CI5!i5I_Tp*555$D V0'5CI5!i5555$D kv5 v5{5555&2?G ̲u ] !%(א' P4ˑ !%(ˑ8 .x#>  a%LU#;   a%L!%5(jhex!@ @ x!k@!@̲%N!!%('א̲P H!!%(אא ̲ !!%(א%4 pfS!_fSr.fSfS.< _ "!%אא4w p BV"_Br/BB/<4^  pk"_kr/kk/< ^ k"{%krkkE^  k"Rkr/kk/  B%#{%BI_TpBBא vŐW#vŐ{ŐŐŐŐy v\8#v\8{\8\8\8\8 7 fS#{%fSr fSfS E fS#RfSr.fSfS.k7eQ$klQ1>aFlT1J7SDNtx:$'m4 ELZˑo$!%(ˑ'n> D8@4))#4$4b)N9$$443e RD?$'4nE)\4$4nD4$|&%ointw.$bQ"$  %>hF0n% 2G&%G%%EG*%G*% G* %oG*%^G*!SG*!G*!|G* !&TG*$!G*(!xRG*,!;cGR0!G X4!ChG %8!8G%J'''%'v$% RJ'($%' SJ %5(5('v;($% gJK%[('% = JR%w('5(m 1J{%('5(m J'('weJ' J'(''(v' +Jm')'''( a Ji%))v)' ԇJ'F)'F)'(v' wJ'g)$%' YJ'})$% @ J\%)''5(m bJ%)5(5(m վJ')'' pJd%)'5(& ƭJ%*'5(& yJq%:*''5(& J%Z*5(5(& BJl%u*5(& SJ%*5(& !yJr'**$%(v%EJ'*'5(EJ%*5(5(EJ%+5(5(EJ'+'5(EjJ'8+5(5( XJW']+''5(]+vc+h+xtm,K+%@K%%.K%%v?K%%K% %CK%%hOK%%9TK%%YK%%K% %=1K@%$%K'( J',5(ELJ'-,'5('EurJ%L,5(5('EڐJ'k,'5(' KJ',*,'(v5( J',5(5( #J%,5(,v' JU%,5(, J' -'5(, J@%--5(,% _JG%M-5(,%EJ'l-'5(' RRJ%-' f&JE%-5(5(' JI'-'5(' wJN'-'5(' qJR'.'$%' JY%.5(m 5KJ%0.5(m4J5(N.5($%GJG5(m.5(5(4J5(.5($%-J-5(.5(5(J<5(.5($%'y2[2[2v2y,$0 f,܎/%<, G,"/-/E zHN,$I/T/RfSEfSea/l/Eٓey//E%r  ,/%O,EG,//EאzW,$//RBEBy' S,܄0%<,G,0#0Fe00;0FeH0S0F%zN,$o0z0RkFkr./EQ,Ď/0y' אE),/0rF`,.r   , -L :2 =oF ?*"> @'K Aev Bkp OK1Q1qp Qa1l1qw V|11q%3Y3 Y& 111}#13Y3 ][^111}/13R c  111q0]bF mU 22q 103 qq01272}bs XK2[2q 1kb.l o2z2q 1I_Tp%0 :4 =oF ?'"> @5(K Av Bp O22p Q23 V33%3Y3 Y7253@323Y3 ]62X3c323R c)2{332]bF m33223 q_,233bs 332b.l 442I_Tp$%2 L7a4&I<L:%&$L;%&L?$&gwL@%y%WP 6Z *<@ <K \C78PC60~H  68%8VC60N $\C>8I8PC60H n6b8m8VC60  588VCR'N66 ,L78&I<L:;&$L;;&L?$&gwL@%yG% L7-9&I<L:'&$L;'&L?$&gwL@%y% L7o9&I<L:x&$L;x&L?$&gwL@%y+%T :; =oF ?F)"> @*K A5v B5p O995p Q9955 V9:5%3Y3 Yc9:&:593Y3 ]9>:I:593R cA9a:q:5{9]bF mQ::59{93 q01{9::5bs ::595b.l ::59I_Tp'o9 dM_;oFMHMH4RM\;E;5;FM:d;5;;.lM~;5;4M6;;54MHr5;5,M;55 M;MII_TpIHE := =oF ?6"> @6K A 6v B6p OM<S<6p Qc<n<66 V~<<6%3Y3 Ys <<<%6%<3Y3 ]<<<%61<3R c <<<6<]bF m5 ==6 <<3 q<3=9=%6bs EM=]=6 <6b.l /q=|=6 <I_TpI;} :? =oF ?Ő"> @K Aݐv Bאp O==,7p Q=>,727 V>>,7%3Y3 Y=7>B>87=3Y3 ]E{=Z>e>87=3R cH=}>>,7=]bF m*>>,7==3 q1=>>87bs oc>>,7=אb.l %??,7=I_Tp= M_w@oFM`">M`KM`vM'`M_4RM-??J7Y?FM?J7-?Y?.lM?J7-?4MLVY??D74MƹD7?D7,M_@J7J7 M(@MЌ`I_Tp >ZMI@MЮ`I_TpCMm@I_TpJ7-?א_WV BZ Ő<@ <K <@ I<K _ @7K A7v B7p OE E7p Q0E;E77 VKEVE7%3Y3 Y.DnEyE7D3Y3 ]0>DEE7D3R cODEE7D]bF myEE7DD3 qUDFF7bs eyF*F7D7b.l >FIF7DI_Tp7D HRM_iGoFM k">MkKM#kvM/kMj4RM2dFF7FFMD-F7dFF.lMF7dF4MF G74Mŭc7$G7,Ma]>G77 DM_GMАkI_Tp7jW IZ 7<@ u<K u @b8K Ah8v Bn8p OIIt8p QJ Jt8z8 VJ&Jt8%3Y3 YQI>JIJ8I3Y3 ]'IaJlJ8I3R c>8IJJt8I]bF mjJJt8II3 qyIJJ8bs JJt8In8b.l @KKt8II_TpI <M_]LoFMhu">MtuKMuvMuM\u4RM4KK8`KFMrK84K`K.lM K84K4M`KK84MŒ8K8,MWL88 ;M/LMuI_TpCUMSLI_Tp84Kn8IuWX |NZ \8<@ <K - @(9K A.9v B49p OPP:9p Q QQ:9@9 V$Q/Q:9%3Y3 YWPGQRQF9P3Y3 ]0PjQuQF9P3R cPQQ:9P]bF mQQ:9PP3 qPQQF9bs {QR:9P49b.l 9R"R:9PI_TpP M_fSoFM{">MKMvMMo4RME=RRX9iRFMRX9=RiR.lMRX9=R4M/iRRR94M6R9RR9,MhOSX9X9 F+M8SMI_TpCM\SI_TpX9=R49\W UZ "9< f <@ <K  :(W =oF ?9"> @9K A9v B:p OUU :p QVV :: V V+V :%3Y3 Y&UCVNV:U3Y3 ]lDUfVqV:U3R c0UVV :U]bF mUnVV :UU3 qUVV:bs >DVV :U:b.l <WW :UI_Tp9U M_bXoFM">MKMvMM4RMW9WW(:eWFMW(:9WeW.lM)W(:9W4MғeWW":4MG1":W":,MX(:(: +M4XMI_Tp9CZNMXXI_Tp9(:9W:tWs ZZ 9<@ <K  @'K A:v B:p O\\:p Q]]:: V)]4]:%3Y3 Y\L]W]:\3Y3 ]K\o]z]:\3R cV\]]:\]bF mb]]:\\3 q\]]:bs ]^:\:b.l ^@^'^:\I_Tp%\ M_k_oFM">MKMvMʓM4RM WB^^:n^FMI^:B^n^.lMu^:B^4M®Dn^^:4MS#:_:,M 0_:: 9GM=_M+I_Tp%C;Ma_I_Tp%:B^:W aZ |:<@ <K   @\@K Ag@v Bm@p O6bMKMvMM4RMucc@cFMj~c@cc.lMbd@c4MB$c'd@4M{@@d@,MMZd@@ ]4M{dMI_TpV@CMdI_TpV@@cm@lW fZ P@<@ <K fug{gF0SI aFggF0SI fggF%0eN FggF0eN 7fghF%0 fh%hFf0I AF>hIhFf0~H fbhmhFf0N iFhhFf0H 2fhhFf0 ^hFhhFR\@N[ :xj =oF ?@"> @@K A@v BAp O?iEiAp QUi`iAA Vpi{iA%3Y3 YlhiiAi3Y3 ] iiiA#i3R chiiAh]bF mYi jAhh3 qh%j+jAbs ?jOjAhAb.l zcjnjAhI_Tp@h xM_koFM̪">MتKMvMM4RM6(jj&AjFMj&Ajj.lM k&Aj4MXj0k A4Mń AIk A,MA7ck&A&A 8MτkMQI_Tp@CMkI_Tp@&AjAWS mZ @< f <@ <K  @AK AAv BAp OzppAp QppAA VppA%3Y3 Y\:pppARp3Y3 ]$FpppA^p3R c:pq$qA.p]bF m4Z8qHqA:p.p3 qY.p`qfqAbs ]zqqA:pAb.l VqqA:pI_Tp)"p M_roFM">MKMvMMش4RMGqrAqFM8rAqq.lMRrAq4MqkrA4MX@ArA,MǔrAA JMϿrMiI_Tp)C'MrI_Tp)AqAŴW  uZ A<@ a<K w @BK ABv BBp OwwBp QwwBB VwwB%3Y3 Y!MwwwBew3Y3 ]YwxxBqw3R c%Mw'x7xBAw]bF mamKx[xBMwAw3 qHAwsxyxBbs xxBMwBb.l xxBMwI_Tp;5w AM_zoFM">MKMÿvMϿM4RMC x,yByFM KyBxy.lMeyBx4M¿y~yB4M̋ByB,MڪyBB _MyM0I_Tp;CMyI_Tp;BxBW ,|Z B @CK ACv BDp O~~Dp Q~~D D V~~D%3Y3 Y,|~D~3Y3 ]:~3>D~3R c|~VfDp~]bF m%zD|~p~3 q7Xp~Dbs [<D|~Db.l D|~I_Tp*d~ M_/oFM">MKMvMM4RM]"[$D2FMz$D2.lM`$D4M2D4MŢDƀD,M $D$D PMM=I_Tp*CM%I_Tp*$DDW( NZ 5<@ <K D~D0eN /]h~D%0 [WDJ0I D~DJ0~H ~H/ɂԂDJ0N aD~DJ0H /DJ0 \D5;DR5N6/8C : =oF ?D"> @DK ADv BDp ODp QƃуDD VD%3Y3 YZ pD3Y3 ] |'2D3R c19pJZDd]bF m#(n~Dpd3 qdDbs DpDb.l ~qԄ߄DpI_TpX M_oFMM4RME.KGFMZsMKG.lMVgKG4MŸD4MDD,Mz KGKG]L|NZbXk_,|rfw@a4 u ;N/ N0${)0R&tK%{AR@K%{NRZK% ' =$R7Nmamam 3 =$R@Ntt  =$Rb8N8xQyQy < =$R9Nczz  =$;R'Nss  ShR"9NK[w[w ' =$RBN{ * =$‡R\@N[RR 0 kR@NQQ vH /$RP@N[SS =$IRNctxtx z BvRNctxtx  =$R5NE&:N$'' =$RBN{   @RŐNcpp  xLHR\8N8x  suRAN%%EN$%* ݾ (zRBN{  =$RAN  /$R"9NK[w[w w }XGR9Nc > _tR|:Nvss R2 dRP@N[SS X /$ΊR@NQQ . 6$`@C@NtQ l7 J1R5Ng /$R5N "J\%v5(, J,5(,% JN%5(,%yO7ɋ|O8O}4}dvdv4}}};v;v}d z38P52%P9*%eP:*%q0P@*%\PF* %_PG*%HPH*%PI*%/PJ*%JPK* %PL*$%PM%(% PN%)%@PP%*%PR%+%6PT%,% PV%-%!+P]%.%UYP^%/%Pa%0%QPc%1%$,Pe%2%Pg%3%>Pn%4%[Po%5ExP|*L%'~'PWvQ(%EnQ7,awQ8N%rQ|sϻQ}9%QTQ~9%QG%?`Q9%Q9%CQ@%˰Qh>Q%t%uy'*Q@%Q@%Q@%p[Q@%Q@%ZQ%Q@%Q%oQ9%KK M Kx%+Kz%+K{5$-R%֍tG%uy' SƎ%+S %}S!2T%o{Tt+%%%Tu+%sNTysO+Tz%T^%%R9T_9%%<T`%%Tf% %IgTo9%s'T}s6T~sjT@%t%ˏuy'X&TTWs6Ti'sjT%cT֏t%uy'/NdT9%t%0uy't%@uy'Lv@U %vc}%}'v0}2v2v}}}$%};(v2}4v4v}vv' vv$ }$ }' }t9%v{v8 v6v, v=!}=!}6}, v6*v0'v*G%}7v7V4G%@Vbvh]E6V%'LEeuV''WEVW'EVLˑ'};v@v?v@}?}@v$}$v1AvB}BvBvYD}Bv$qWb K%LWc%remWd%(We%qWj|%LWk@%remWl@%WmVqWvR%LWw,remWx,iWy!Xm*qY]ܒ%KY3YÒZ%ܒbWv%]]]OG  GR%GR%uGX%G%v!vn%t%nuy'vt%uy''%FO& <X[.x%~[0~%d[22%%s[5 %8G[:%+[;%e[@%R[A%[E~ %d[G2%(%Y[J,%@[N0%72[P4%~[[a8%#[\a@%F[]aH%I[mG%P%I[nG%T+%T\ @\K%]*G%y! ]e!J]j!+]mG%!,]pG%!]s !d]x*!._]~!]']9%[]9%]9%]9%k]9%~H]9%]9%v%#]s%]%]mǕ!]!|]]+1DREHy!9'!u$!M!y\(RE?J11RE[f11REw1'~RE1%0 g'1[+ME$ޖ11[I$11[+4$'1[I $>'1*R]1'L1Îm11% y  1 WW!P W.З1~'%. ]1%0-k1 1" 0;11L1I K11~W7} 8ZF_XˏZ(_$ZP`Ǝ28;12+BC9ȘΘ12M:17}1aW݊ r~a.݊t%+1.4x<G1%"݊}Wb11L1I}r11WZ9 !F_1TZ911.ʙՙ1%"Z911L1I@11K5:/M$Y$WڸT^IntZ%<}-[9%W `Intf,<}-gN%W@z!ϝ4T}~44.Κٚ4%0tH440N441getZ40640Sm4OU42'$ju44"}44*1IW_44ITG'^:K^El''^f$'' ^l165(^t$>5(5(^|6$^'''B^^$~5(5(8^$11^W6%f ^G6Ԝ%f\^6%'^-5;%N6=*035>@K3595/@[f35131IDX[?5~3595SetIR35953RMm1ǝE53d5N F'ߝE5oQ7WK 9595%'\_1@9595j e9595'37or$}E53qttE53ߣ|hE532ZמݞE536%E5'3O-e$E53^2$6<E536$TZE53v%$rxE53[$E53>o$E536RJ$̟ҟE5) K35(~'E535%    @Ut5'%56q ept5%G  t5z5H1I 5t5z5$& 赢@I Sߠ TU%L Uߠ PG 5?T 5+C 5 ߠ $T $͖ 5u_ zT it55[u ԝU%ߠ &XUU%Max +9&U%0q 0Y5̡ҡ50[ 3!ߠ50 6;ߠ 500G 9tߠ)/50y <-$HN505 He$gr55? gF ߠ5{ smߠ55U% Ť@I S T%L U yG 5?T 5+C 5 / /$T /$͖ 5u_ zƢT y55[u .% &;%Max +%0q 05ܣ50[ 3GC50 6Z 500G 959?50y <@i$X^505 Hy$w55? g%5{ syE55%W, g! $!ҹ Z., 60 \$!;6'%'' vm'Q6'%'W: +2Q 7x!* +T: 6+2 IťХ6+0 g+6+": 66L1I m66/mP+gGEA cm @ sFf   uG:iug6[Y$զ'1'%G.GO6@RA 6%mIjRA-36ZpD%ATZ6FEyr$A{6$|A6mX_R'cmا1GG6IH1I6I^?%6%%!8`%! % ^[u61%%%E6%3163 g%ƨ̨63S2%635ZU%6"^#67L1I;367 Wk-&kz&+'&7W&z&J5(&79 uGUA Ʃѩ7%KS }L;HK @H e=C7.9 TZ7"9 ju7HL1I C17HW ,<U\ _m!2 a. .ȪΪ38. , /ߪ38%2 W38" c 3898L1I c03898W^Yzq!ϝŐT}~lw8Ő.8%0tHlnݐ80NyŐ˫ѫ81getqŐ80SŐ 82'$$/8Ő"}?J89*1I^i89ITA\pkWz!ϝT}~9.ɬԬ9%0tH!א90N 91get+190S:JP92'$`ep9"}99*1I܃99IT' / ]I ȭ|puGU' ȭ9%K%i \ZHȭ(.9.I ?E9"I U`9IL1I -+p9IS vv!p $! r {.U Ʈ;U=w |ܮ;%2{ ;;0n f; +;;0&1\ G$DJ7H2A] _j;$t Xz|;HA[ @|;H%c |߯;H q|;H :|1<;+H &|Ze;94 6f|;n8 q  |;9]? ~ |հ;+H  | ;H/ N |'2;Hl ? |P`;H%U ;|~;H"t ;=HL1It N;=HWV 9ߚ!!0! %!-B\F "ߚ8;'%'.ߚIT;$;21INQit;$;#@};%ͱ!*;.V Ʋ/;'%'.;ײ/;%21IC5;5"V /;;;L1I-[-/;;; _`%_hA;%I _i%_j_c~F;8L;2_fF;%G_lȳF;R;H1I_l׳F;R;Rh6>U<%=$%$%'$%6%46%V$ %j6%_6%D$% 86%$ %<$%C(%Ux$,%0%Z64%L$8U @ B @%glBW9Z!g6T9_6A@10>bT$Ze@49f9s~@c@% Wt)UyI6~46[@Q$''[S4$ 11Wq%$1'5B !'! %!-B6e5BjuAAeA%1IAAA#5BA߿2n b` >uG!6G!:!D=V !e?!2B&@!E !AvI߿@!1M[H!QT!HWv`!\l!_$x!8Vc%|!Hi@!0o9!h&y! }!G!8$!<%!g!kv!`v!$!~9B'$TitDGUD%0  &@D2oFɸԸD&@0&@D2qD&@0<%,2G0ER%KQG0igF%jpG0ob%G0f3g %G0fU %ǹ͹G0 Ӈ%G0R% G0@0%$*G0R] @%CIG0S^%bhG0:vG0 =CvG0FE@$źG0ED/$޺G0gJzCG%0nQn@!,D%0DWe ;EKD0z9djD0^QY9G2A2DG0 +G»ȻD06D%0gM@D''2b?4ID90Ks5GbhD2:}D@2 D92u$üD0~D$ܼD2\WD2DmjD2le֒-8D4909\g4%Q\DͶ22qwD0TgVzCG0G9D0I9νԽG0uQ#@D05j.B D05j(B+1G2r#"FLD0g+6ekG0AD20D2*D2/վ۾D2ˡĞD0O%%G0EV!q6.4D2=N+IOD2HdjD0,L$G*3SD$"ÿDHL1IӿDHW)!@!!@EQQ!&@TE=HQG2@0oF8@agQG"EwQGWG*1I3QGWGDQG%.1,@T1,@2@. ,@%0oF8@%+,@0oF.>@DJD@1getD"2@ciD@setAT,@2@-H+N8@D@"1,@J@*1IU,@J@IT&@߿Woz4!ϝ6T}~/:zA6.KVzA%0tH2AouA0NM6A1get6A0S±6zA2'$;zA6"} zAA*1IJd!,zAAIT Wlzi!ϝAT}~doAA.A%0tHjAA0N AA1getGAA0S9AA2'$Hl'AA"}7BAA*1IVaAAITi9iWuGf9AHf9A@mviA%G'$iA'1'%G9)Wq:!@!ӾEQQ!TEx]G(B0oFB]G"E]GcG*1IT]GcGDA]G%.1 :BT1 +:B(B.<G:B%0oFB`f:B0oFR4B@B1get(B@Bset :B(B-+{B@B"1:BFB*1IT "-:BFBAITWozo!ϝLBT}~juRBLB.RB%0tHcXB^B0N9LB^B1get_LB^B0SLB RB2'$"-RBLB"}=HRBdB*1IL\gRBdBIT.vA1{EuGfLBHfLB1IXBLBHU23LB%63.9LBL;9XW]LB<:oLBL;\)!&AB! h%!9i!!j .DHL;L;U/IH%O10;HL;*Sn f;OUH`%rxH"lHHL1IlBHH[&[ e''.rHL;L;TuHLBtx o%0HHU|CtoNYHHA[lowHH%l oHH%.oH+H]? oH+H*o%0H9 q oNYH94owHn8*YHL;*?{mH+N̸H$"HH*1I y HHio+6H%?C m " c 8 +W' ! 0T' bC'.{4 bC%"' bChCL1I bChCmW2!/>6T5&1nC10>9}($JUtCzCfcnnCiSynC%Q$7 - 4 O  uW-_ wm!.-_yxD.} xD%2Q<!,xD'0NMCEKxD;aIStrxD7B!$C!d%WK fd_N%!+O%!Q6TKD%.a#4D%0-86!D3IT6;D2L~'UD"KSepDDL1ISDD7e|  -G=DWo&Cz&O&א&7ITW6&C$z&O&7IT, W' F$b $ITWEIK[M`6nEK,;,W $/ 5$-s9 1^]} %]} Gmȝ]ITo]W&z&E&7IT,Wy&CQz&OKIE&7IT,QouGf}IIfI1IEO$IIIQI%a3 WW%$%&@a3Y#G@`8CG%֤e0`kGn83$&$GGa3GGH1IGGidifGGfGK$)HG'1'%G=XG%,dA33!q0$!s%(fGG.fG'1'%KL_RiG-lD'c i'G%݈$A!M f݈grGG.݈G'1KZ%3G2  G-3G%i$-A3f"-GG./>NG'1K6xRouG5G%{. jALA!T0!lG!'$ !nm%! !%! %f{.#GG.{.l4DG'1UTvZeG%NvGmKFE$G$00{Q'G0a |1G0}E$G2~/,7G$0s %%PVG2(^CkvG%0j5G2wPG0Qa{e%G2DmG%05Z% G2\!(3G%=EG3WW!RlHT}HD֤AV}Hn8"}HH*1I}HHXV }H% WW!RlHT NYqHD֤wqHn8" qHwH*1IqHwHoJqH%N$uG.N GU#.G%K5'_O_G%%}G"NGHL1IlGHg@ 4+ 4't($0m 0!F_!$.'t(.HK5' O_H%% }H"'tHH*1I~UHHFH%D v\)! \FTD  %H'l a >N%HH%  <8$h%] $%C R61$*q gL61i C61" v6'O< t&7111  "/&7'+ hO&7'9 j&7+Hf &7HaG X69"D %H1H*1I i%H1H"+%H%|> vvf>&1CHIH.> BHCHu e''t O#CHHA[ CHH%c CHH CHH J,7CH+H Z U`CH94 $~CHn8 q 9 CH9]? - CH+H x CHH/  "-CHHl(  K[CHH%U OyCHHJ 9HQCH%VoiAȭp yQtfp IITp*5 In8)E I%Q QG$q%: $SS u%'' F'' %D %%% D'' 4%8'/^ .'W% eI%m% U%D d%%9% D%' d%%]9%)*'w0 v LU$$%$% +3$%$% e $I$ & '_F Fs($u$w_*${|\$% ݗ IT6^ .%IE%:%%  ITpZHNq' _ ZH9ITȭpZH9q'E cITp@Ir'  $ITp$DDs' I%9?uhAu1'9FQvhAv X%98x?y8y D%D9c? {j: {K$[zC (P$rzCg'9cFQ|j:|2'9{FQJ!CJwޏ7 c% r eIC,@% X +0%E̗$+$% )$A%{ˑ[%&7 J]yITo]]X1&7z"&1&7q&ITא&7 )$$%d!5&7z"&!5&70W&-IT, &7 v$C%V'9[FQ@޾OLIE%6:w6 \$%%% %%wVE.6IT'w $~~'hGw85w1I$5_}|:55b|:,{sH.*''vw<$v&OIT,E&7rQ&aIT,E&7&/IT,E&7 !'6ZIT1,IT2,EExw1%z7'% A%hA)'{36'٩SITv;61!V$zC0{Xb65 b"`= d QF'm؞p {g9|-07g$'F)$'ȶE'''$mk$''R$'''5$4?/u$>%- y0Qp6!4i]-J>y =6J-6WV7#q69'''\6''{$"5'%JCF'R|0G$j'';m6'?!$'$'''ң'5(>$''$O 6v U J''11$Č&6d+OvX65(%ox5('5{<$%$%$%&7{$%&7 ^%''&7'1^%''&7#2+nQ''&7z"6=#l'&7 '''':S ''''-^$%5('&7:< ^$%5('&7#21)5('&7z"GpD5(&7 X m''5(5(4&>6IT%:4s56IT,E# 86va6'%y {j5%'J@&{6(% 6?n8S Rn8v&r''%q6'%615wak '''8L;D '''%%%%91 ?''5(5(%9 h''''ط ''''%‡ U%''U%U%U%v %''%%G7w!IE%6%%: k:$I%1|:{8u%%%&7[ݖ%%%&7z""K%&7{KV%%%&7\D%%%&7z"2%&7^$%$%$%&7z"x$%&7pNSIT9SIT@?SITV@k6G%1K8 %1%$4(i6DIT*Dy,K]Gp%A \QImZ ''q,/{[ ''*~v ''[+  '' I'' r'' 1Q9''''9 (8 )6' , ''^$%|:,4#^%|:5ByQGO% \QIX[kC%-PmL6'kH`^%|:52Kk,^$%|:,i1 & ITpZHNq'*&d0ZH?ITȭpZH9q'&,lITp@Ir'EV%TrV@ޓsV@Ea%%& &($ITp$DDs'cμ5.;U%y*Y ۋkk%62Y 7f3Y  4 Z yr aF\\í_Y3Z ZDZ F[UZ 0`\fZ o]wZ s^Z _Z 7|`Z *MaZ O-bZ cZ W6*dZ FeZ x"f[ i%k/m[$u[96a)7p)7)7)7(Sm d[ Dn u[ n!1[ t{la{$'L]'R'Tȕ'I 5V'/pW[ /ZX[ ./wFQ%R%\ BPwDP{6xDP"7Uss_ෛ<+Y4]!5`1<55/eLW5'35oz53h55$3u555(3,;55'355!535b!s5IT5&6s5IT5n8rjs5IT25BRs5IT5 =s55@IT5*Os5\gIT5(٠s5ITj5z $s5IT5?s5IT5Gs5IT5qs5*IT55s5FQIT$54s5mxITX5h1s5IT5;s5IT5 s5ITN5^fs5 IT5s50;IT51s5WbITD5Tjs5~IT5Xs5ITi'5s5ITJ5Z{s5IT5s5%IT'57qis5ALITy5ps5hsIT5As5IT;5K s5ITt5s5IT5{s5IT!518s5+6IT05s`s5R]IT54s5yIT5^s5ITY5i#s5IT5Hs5IT5.s5 IT5As5<GIT 5 s5cnIT 5Ts5IT5ts5IT5Rs5ITQ5a(1`V%`%/(1` 7%3>`ј$0;7%H1I`#J77`̮%_`%/`7%B>`$ 7%[y 7&nnk2eQ'&7&52w/{3  \4 %I g%^o6%Pr%%%*s6 %0t6w<d~\8'%'3H rb83LC'b83R"%b83>U'b83-BX$'b83[3$,2b83^$JPb83ma$hnb83da'$b84Ňk 6'f0i\8%fw\8n81Ih8\8n8Q* ~ %8xQ*$ * 8b> I 8n837%n8a l 8%3F%  8GQ*  88H1I 88W7!@0$!05A.7   99T7 #  9$0C D$< B 902H M [ a 90-BG'z  904'  90!9   94*^)k   95*1I7   99f   9%97 B IT5( 9e9_ j IT 959  IT 9א0I#c9  IT 90Yß9  ITG 9 0&6@9  IT 9n8!90 ; IT 99X c IT> 9b0@9  IT' 9559  IT$ 94~19  IT,  9*O9  IT 9( $9# . IT 9R9K V IT 9 =9s ~ IT 9k9  IT% 95@9  IT 9٠9  ITj 9z?9IT 90T9>IIT9 9IG9fqIT 9q9IT 9 4[N<\F!/\F! ! !Z{í!e$!y/$!$!:D9!3.rqkv9%0tE'903w *'90թ{'90C8'90R$ 90j"$*0903S9IO9"_911''9+rB%9Run729$ 9"99L1IU99N<iuGU;`KVV@%~tzV@MV@<9HV@W: v!K;!qQM;!.O;.:   ;.mX ) ;%2 >I ;;0n;bm ;;0{M;;0P ';;+|5; ;*< ;;*_XC  ;;+1RG4$%;*H9? ;":ROZ ;;L1IRj ;;rv }uGfr;Hfr;1IEMH;HUv;%tZv"-;HA[;vK[;H%cIvy;Hv;Hzv;+Hٗv;94zv(;n8 qt vFQ;9]?nv voz;+H v;H/X v;Hl? v;H%UWv;H!_3WWO_7Q % W%W_Rd6%>_S&@%3_TH T!H8.!'H68Uܗ;%H%֤FIl%Hn8*."HG!_V1<HHH1I_VKHH,W uGf,&@Hf,&@1IPH&@H@=W&@%֤XW&@n8g|"uG!/6! !Wc !:v!N/$![(!e$,!`0!h&8.gV @''Ub @%03t'zC0թ'%zC0R z0$>DzC0f3+ %]czC0f0 3Y%|zC0 5 g%zC0: [Z%zC0@? %zC0D >%zC0R]I %  zC0FE#G$6 < zC0E&%$U [ zC0 ) t z zC08i M9  zC%01I9  zC+S`8%p:  @+S`;j:  zC+nPp [9!!@%*-D0!;!@$*w xO!Z!@9* n!t!@N"|!@Run} !!@*,W!!@*Zv[!!@W^46$!9?c]$ "9xiC$'"9nCL$A"9esH-$["9Ȥx)k$u"9*= X_""@6* #p""@"g""@+HL1I"@+HO}$8aF$#אא!$;#, eg;\#eQ''&7Nx#eQ'&7"$#'' #'$''55- #$''אאk 0$, $''"$L$5(5(j= 5($''eeQ"Q"|6"/D(_$W)$uG!F_!D$9G1Run%% %G0^T'"%(%H0Tgd/zCA%G%H0l9`%f%H0Os@%%%H0KyG%%G0<ON%%%H0ERT%%%H0iYÉ%%&H0o_2%& &H0f3dV%9&?&H0fi%X&^&H0 lad%w&}&H0q5%&&H0@v%&&H0R]{v%&&H0~_%&&H0v''H0 v1'7'H0FE`k$P'V'H0E$o'u'H0gzC''H%0i9''H0Dԝ H''G+O\V@''GV@*G.,(-(G'%11*leA(Q(G11+n,@i(t(G%+VD((G+RcG((H"D((GZ$((G%*]()GA*"G¼) )G"D0);)GHL1IK)GH$Iv+vfI))HHfI))H1IZH))HHt\)))HHA[B\) **HH%c\)9*D*HH \)b*m*HHr\)**H+H}\)**H94\)**Hn8 q \)++H9]? \)/+:+H+Hg \)X+c+HH/6 \)++HHl \)++HH%US\)++HH*\)+H%%\)vWwO w,  'G, 6^,% 6u,%m' >c,Yg% Cc,Yg%7@$,n80J$,n84:O1-1n8E1,-15O2 F-5?N&O_6g-IT'5H&O 6-IT5(e 6-%''8 -''''} -'''' $.''11}!} M.''11( v.''!5!5}.R. .''!5!5 U .''5(5(} .''5(5(oJ /''U%U%KhQ)# C/''%%u&OL6d/IT,E9@c{/1i7/|:59/|:,j 6/7K#$/17kU'6k53$kl{$k$kǠ͞&6kx6k ާn$k^6k{0$kk`ko+$B$ p$b6%dkj^$ X X n'Y *Y M;'Y +8Y <IY ׻PzZY P^.kY P|Y }SY 3Gv}y}\Fvyv}aF}\vavv}~1v} @a 2sa"%spa#a$1Ia:qa?=4rtaF3aKa2%CaL֍%M<aM aR2%aS%%"eaT%% BaU2 aZ2%Ca[֍%M<a\% Ba]2ab3%Cac֍%M<ad%5ae%%af 2 %aag 2al%3%am%c/an+%asG3%8at@%%au% azu3%a{%Ga|%%wa}9%saG4saN?2sULaVa2_rta^2sah2s+ao3sPav%3sNa~G3%/a@%%aA%% aC%%a72 t%4uy'91a+2#bU&4v,484% Ac4rcc4snc4sH`c!4%%c#D4%K=c+ܒ%c.%%i=c144%4v4v4v4vFvjGvoG}44vGv}Gv}v4151v}}}wHvvv}}vy8=a568V5v[5abiuK5v$}'v}5U%}v}v}5%}/vŤ}Ť}'}0vo9};v;vH}I}HvIvIvRJ}I}RJv;}=v=v"I}WJviJ}I}K}iK}Kv\Jv[Z}5K}wO}Q}[Z}\JvZ}[}o_}Zvo_}X]}]vʤvtX}Yv_}X}Zvt_}_}$vg}<6vAv v?}?vvV}Vv[vvaFv=}?v?v_}`}_v`}a}`}av`vc}Ebvc}d}0d}j}cvjv7vv77}7}7vD}SFvSFvj}k}jvk}Zl}k}_lvkvm}mvm}n}n}t}mvtv}<viG}K87vI}iGvv}}vI}#Kv#KvIu}v}Iuvv}v}v}vvvv3x}dwv8x}$y}Oy}W}8xvWvv } vAvq}qv }v} vv}}vP},Rv,Rv\}}\v'}ʀ}'}πvvF}wvK}7}b}o}Kvovv}vv}9vȭvv } v9v99}9}9vU}(Wv(Wvt}.}tv?}}?}v3v^}vc}O}z}}cvv%}%}%v\}1^v1^v}A}vR}}R}vFvq}vv}b}}}vvv|vvvv } vͱ};vv9}98v>}} -W%n;4E!Md%;' MW%;' MW@%;'EAe;]]''jdivWK;%% W4* <' W|$<@%@% W^%?<'' Wi'_<''' Wa%<'''W<''w>Wv%YWx<9%EW%<'5EW@%<'5%EtWG%='5% xKW%.=' OWl'N=*5(' {We%i=*$% W=,, W$,='ERW,='5%E WN%='5%EWU%='5EWW\% >'51f3> m w ݯ , g7X>%g9%%#g:%v3>7Eh> Z  J   e   >i2% #j>%j>%_j>t%>uy' j}? ] X P    Dv l H  . ~ ? + 4 s  W 49   k7?!k9%!$k:%!Nk;%!k<% !Q4k=!1k>?!k?*!Rk@?v>v}?v@}?vv v&@vWv߿}!@v&@v!@v}vV@vvb@V@}V@}b@va}ocvocvl}&}lv7}ڟ}7}ߟv+vV}v[}G}r}}[vv@vv@@}@}@vh}xjvxjv}g}vx}}x} vlv}Ȭv}}}}vv} v4}4viv9}iv}v)v})}v"p}qvqvŴ}}Ŵv}3}}8vv}v}}˸}Ӿ}vӾvv:}:vv?}vA}AvfS}vB"9v+w}fSvB}Bv0w}Bv;vB;};}Bv5w}xvxv}F}vW}}W}vKvv}v{}g}}}{vvz}?CBvK~}zv6vP~}6vm}vvv$vm}C@vU~}mvk}C@vZ~}kvd}CP@v_~}dvu}v}uvC*}*}Cvd~}vv}S}vd}}d} vXv}v}t}}}vvv/}D5vS}/vvc%}vvvvC}}CvX}vv}HvZ}}}r}$vMvd}>}}}d}Mv}}}v}a}vVv}$W}CXv}}$v}}(v}v`Z}}E,v]L}E\8v}]Lv.אv/v|N}Eb8v…}|NvZ}F9vDž}ZvbX}.F9v̅}bXvk_}KF|:vх}k_v,|}hFBvօ},|vr}FAvۅ}rvf}F\@v}fv/vw@}FŐv}w@vv}-}Lvi}vt%Guy'}Gvva4v}a4v u}:GAv} u}v}vA}-%uGmv{GpgiGvv}v}dv6vi}v}v3}L1v}QvQGv$vv}}vW)}}W)v}v}$}v}v}THvvv}+Dv}vV}8v%},vo}v}6};}v\)} ,}\)},}vv },}Wv}}}}v}QvQ}V}QN'WIrN'N' fIqI B II BII B"II I2#II I II IvJJ JIW =J__pvDvDXJcJ cJCJDwJJ cJEJJ cJ JJ JːJJ BJJ J%IK%K %K%QG59KNK b@%Xl%oKCloKvzKR K/0tKK0%vR&K/AKKA%DCR@L/NKKN%X L'L J__a'LvD2EALVL VL%,Lv~pLL L%[Lv;v];LL L%LLLv^DgDLM M%MLL?;M:M L%:ML{NMsM B1IsMpIhא(MM I(1MM I1MM I1IMpI p!N__pq"N&N &N__a+N5 ANVN VN% I jNN BpAh__sA'JNNNɋϋ NN J NN J__nh OO B0O__sՋ)cOۋՋ__n) O__dd*__sd'__ndh77O__p7s7OO__a!O6__b!O6P__a!K6__b!K6=P__a!7__b!7LPcP L V8P(!P__s'ˑ8P(!P__c%ˑ};`;PP L__n9%}v}6\'Q__a!['Q__b![6Pv7c8AQiQ iQ*!BJ8*!DJ8,Q{Q__a!W6Q__a!_Q__b!_6P8QQ iQ*!SJ8W!SJ8*!UJ88R*R iQ!v*!x89RaR iQ!*!vEvRR R__ca%aRv}RR Ra+xRRRRR GRS S1[ Sch%<%MS<'cMSv}~qSstqSSSSS F1*SאSS SrhsIS3595SS BST B'0T__s'__c%?TTT 6%cTxT xT%AHTT T%GTT T6̨TT TTT T~ UU E$U/U E2>UIU EPXUcU EnrU}U EUU !@%UU U%qHUU U%}H# VV V9'V2V 2V91FVQV QV9eVpV pV9VV pV%VV VzCVV B% VV V%CH+W%W %W%Ht(9WDW G(SW^W ^WH rWW W%GhWW lH@WW lH9wWW WGXX lH"X-X WtA{aa a__n >VAaa aA%,aa a ;aa aA0bb gaQ!b,b W;bFb WUb`b W͹obzb Wbb W bb W*bb WIbb WbIT6c!%(n 6c1 ;cˑאiVcwcIT% _valswc|c:7Mcc%}ccIT% _valsc|ckcc 5`}eZ dd dd@cTed!%( L ed 'אeydd d7fdd d__nczdd d8߄dd d9ۏde e__nv:)e4e e CeNe V]ehe Vwee e__n X: ee e:ʙee e__n :"ef @i 'f!f !f-C5fMf Mf__n Cjaff )[|% fi 'Hff )[|% fi 'Hff )[|% fi '+H<g5g )[|% 5gi '9eIgog )[|% ogi 'n8gg )[|% gi 'Hgg )[|% gi %H gh )[|% hi %H1hWh )[|% Whi %9khh )[|% hi %+H`hh )[|% hi %Hhi )[ i} %i 'H2&iYi )[ Yi} %i %HHmixi xi4Bii i__n VB}U2ii iinCi}i9%ijIT9% _valsj|ci1jIj Ij__n *TDmf]juj uj__n cz7{jj d__nxl Sjj A;I Ijj A;SI%Uj k  kp44k3k  k%;1BkMk Mkq4aklk lkl1kk Mk%ekk lk%kl *;te'9%msg'Al%2-l8l 8lLlWl Wl3kll 8l%ll Wl%Gll l__i l?8E8VIll lP8womm m8G"m-m lHmamammm mit XMn38mm lHnn e__nNnIE%v.Nni.% .%: bnxn xnpLBRBunn xn%;nn L__n,nnIT, _valsn|cE;o)o L__f%?o`oIT% _vals`o|c55Uwoo 2V|oo d__nHx0oo pVsoo 2V!o|^9!p|c9Åp6p d__nTZHpSp 2V*bpzp d__nHSpp p__i pjBpB`Upp p{BBpp p__i pBBe qq dd$q/q dD>qIq IqB=rq! bq!b%|qqZHvrqqITpw ZHD: Nq '=q!  r! %ZHqr9vq IrITȭpZHw 9D: q '=mr!  }r! %wr}r@vmr9rITpw @D: Ir 'fzrr r__i r3C9C6ss s__i  sPC5m84s?s ?sVC=hs! X|s!X%$vs|sDvhscsITp$w DD: Ds 'ss spAAlst t__i tCCm/t:t :tCoNtYt YtCSnmtxt Ytntt tC}U~tR@N L =t >tttvGS4vtu utu-u -u__i 2u~DDFuQu QuDeupu pu E7nuu t__i uCWuu gauu gavu$uzC@v9?uc@v u%ithAźTv_v Wnvyv Wv@vyvv{%mRv m: m__f vw9FQvc'w'vhAJNw%w %wEL9wQw Qw__i VwEE}+w{w!&fS{w[w=ww w,7>ww w%d`ww w%>73`wx w+ax x  xP7b4x?x ?xh7/Sxjx jx?,oxEא}0wx!&BxtxNxx x__i xEEyxx d1zxx diP yy yEN,y7y y/OFyQy x}…yRb8N8x L =y >yQyQyvy$yn8z98x?ycz y%itx8Zz0z 0z__i 5zF FIzTz e\cznz en\}zz zFZzz z4[zz 0z}DžzR9Nc L =z >{zzv{${9t{9c? {ct{  {%itj:< {{ V {{ VD{[KzC[{[PzC?&{{ ^Wu'|| ^Wi%-|8| V%G|R| ^W| |f %i %[ |j %| |H+H9|9v|}{%ZR| Z: Z__f |V,}O} O}__p UK T} ::4X}I_Tp9__aM}__pM9WaM}(::OZ}} }3FX}} }__i }"F(F]}~ ~__p \K #~::=_a~I_Tp%__aMa~__pMB^aMf~::Xaz~~ ~PF_~~ ~__i ~?FEF|~~ ~__i ~\FbFt~ !f6  !fyx/R R__p MwK WBByI_Tp;__aM__pMxaMBB{ DC"c __p aK s@m@{d3I_TpV@__aM3__pMcaM8@m@fLW WCek __i CC5 @ۨҀ Ҁ__x C ] FAfq'J J__p :pK OAArI_Tp)__aM__pMqaMAAt FFsŁ݁ ݁__i yFF!g __i FFT'2 2@FQ 2}Z~*q!&kqQ+j __p hK AAkI_Tp@__aM__pMjaM&AAe e) W,?VIT% _oFVDj __p |~K DDЃI_Tp*__aMЃ__pMaMՃ$DD>  w__p =K אI@JI_Tp__aMJ__pM-?aMOJ7אdBcn nF@ __i FF}ŐHI_TpŐ__a(__b('(Ő J7J7?4__aM4__bM9J7J7ZaMd  x__xed\7ax ?x}g~|E__f .aRą J!%(nJˑу %DW,A A%D___x)(>Ox__x) > __x)yE EX҆ __x)X69R   [6wR(  II_Tp0__r(/I5+J]h h6| __x@BGאQ1 MkwJч lk__a8s. BS. .%BW F%ti~ *;%w _% ^BJЈ __p IK t8n8/L6I_Tp__aM6__pM4KaM;8n8QOr r__p PK w:9498SI_Tp__aM__pM=RaMX949/Ή , E~Z d% 8 8-B=HL;)T_ %Wuq F%q J__p :p8rЊ__aMЊ__pMqA iWfd% 0- -,Fn2DY i%0h Srhs>95 [&0ɋ S;ڋ S%x'  [e& [5@ [mXfpD3g .*__ak {  F7'̌ ^Wی 8/$RE  VL' Lv<S Sb8'S|__a!w^7__b!w^7  kp~4m__n$%!%(n$__f$lFˑ( B6( ?sh?c %37NY sfhs B}P~R'N L = >ssʎ F__s'  F1 א2- 8l-AX Wl__a8sXG1lw Ix  %;EǏ Ǐ%7lkۏ %7=!i777A!i7z7:z7|!i7I_Tp77:7|7 J %uɐ ɐ%8 Jҡ 5$ r=sam g=5i9 sv9 t u v55/ Ñ Ñ5ב Ñsam g5Ci9 sCv9 tH u/ v/55?\g ÑQv r% %L9JÒڒ __p IK__aM__pM4K8S pA,D D bI@49;R"9NK L  [w[w-/RfS v,fS&TΓٓ p}0T/, ٓl/,+ %R:Q r__p PRu__aMu__pM=RX9V O}%” ”%:=!i999!i9z9:z9N!i9I_Tp99:9N(:]bw ~% %:>!i|:|:|:F!i|:z|::z|:e'!i|:I_Tp%|::|:':V;R O}__p UWv__aMv__pM9W(:^ ~__p \^Ŗ__aMŖ__pMB^:wٖ R%  %B!>6!iBBBc!iBzB:zB!iBI_Tp;B:BB~ mF|їܗ | ~}օh4RBN{ L =4 >9J;v>{%,|RJ ,|: ,|__f Jx R__p MwKyߘ__aMߘ__pMxB 2Fc $ __p acH__aMH__pMc@Wb\q % %@@>!iP@P@P@!iP@zP@:zP@/!!iP@I_TpV@P@:P@!@`i5J %-Yn n%A_>!i@@@\!i@z@:z@{!i@I_Tp@@:@&Ah F=g-8 {gGR }R\@N[ L = >RRV@v{%fR f: f__f 4l  :t12 2[9zCtC‡oR@N L o tQQrl t}0#0, -;0,М -%Oj  __p hj/__aM/__pMj&ACN NC}_~RP@N[ L / 0SSʝRd__x $ʝ__y %ϝCC/ N' dk  ҀFRd__x 0F__y 1KCC~_t % %D~>!i555"!i5z5:z5A$!i5I_Tp*5:5$$D8C CrDWn __p |~z__aM__pM$D> w__p =?__aM__pM-?J7j__x)$K__x),KX'> >__x)8F#R] pun|I_Tp%| E Ǐ;k kɠԠ Ԡ7l 7n mE!= Ǐ__p mDDFm__aMm__pMdF__nMF7m __pOl__n:lO̡ Ԡ%lۡ Em  %o. m%I=H uWb ɐJvq| |85w 8Jˢ __p mIIK__aM__pM4K__nM`K8w4 __pv__nvOEZ |%{I_Tp__r(/{h8I_Tp ]\\8Σ!i\8d\8:d\8!i\8z\8:z\88!i\8I_Tp\8:\888vLW wf{ %~ pzx8} PФۤ r ] ^9H#. .v9QB^ r__p mPPR__aM__pM=R__nMiRX9ǥ .__p__nOإ %I_Tp__r(/.934I_Tp ]\"9a!i"9d"9:d"9M!i"9z"9:z"9l˦!i"9I_Tp"9:"9˦X9ߦ . .%݈5 5p9IT 5r9cFQ|c''|j:v4\8v4"9>Χ w__p m==?__aM__pM-?__nMY?J7b.S ?x__pa__nxaOdy  x%I_Tp__r(/ݐI_Tp ]\Ő!iŐzŐ:zŐ*!iŐI_TpŐ:Ő*J7b>S ?x%ibz ujp[c= w27I`ĩ w__a8sĩD7@aة  x__aZV7C IqDI_T1I_T2__pOŐ?ODאVCXc pRNc L = >txtxECIB!iŐ0kB:0kBD0lŐDc0s$vICIB!iŐI_Tp0B:0BD0ŐIJ7ՋՋ__nIRNc L  txtx/۫RB jxv,B0y' K,אZRBr/ B: B /Uit O}É ”u .:`Ǭ ǬF:V۬ O}__p mUUW'__aM'__pM9W__nMeW(: ;` Ǭ__p׊__nŠOq %  Ǭ͋ĭ Ǭ%\ӭޭ ~֓  :s&1 1:]Ea ~__p m\\^__aM__pMB^__nMn^:ʮ 1__p__nՔOۮ %  1. 1%Fv49c^v4|:}wmx Rۿ  Bx˯ ˯B5߯ Mf )[7x/ R__p mMwAw,y___aM___pMx__nMyB!s ˯__p__nO %!Ͱذ ˯ ˯%29{FQJc'2'J!CF[ Mf%sv4ԤB9v4zv4P@bα __p maac__aM__pMc__nMc@7 7__pϟ__n@OMb b%@v 7Š 7%v4԰A$q̲ J__p m:p.pr__aM__pMq__nMqAZ,Q Q__p(__nB&bep  m bX 7/iͳس  n   ,A + +DAi?[ __p mhhj__aM__pMj__nMj&ABĴ +__p__nOմ  %B +( +%p7L J%E[p p%AO %Azv4@~ǵҵ   *D% %BDf9U __p m|~p~[__aM__pM__nM2$D. %__p__nO϶ %. % " %%$1< IjKV Quep -ub Ij}SvȷR5N L =ȷ >ͷ Ij%v45P&v4Ő5@ &OZ Ait tD tk puǸ `߸ wD (!&'(5__'-Z':-Z'<'3N'-CI'-r':-r' __p*Y''O'FX'$%|'4%|'__a%|F<,%__r%ːX''$'4'__aѺ'$'4'__aѺCI' F$%'4%'__a%eu1I I__i N.G4Gbm xio| xicܻv\8{\8\8:\8D\8__nPR\8v\8o]Y{$v\8{\8I\8:I\8DI\88SN$R\8v!\8μY{$v\8{\8[\8:[\8D[\8Jݼ 8K__aM8v$ $8z8C dpI_Tp9%__ap__buiilJ __n cI]kKɽ__aMɽ__nM`K8wݽ __na vB49)?R"9v"9HY{$v"9{"9I"9:I"9DI"98SN$R"9v!"9Y{$v"9{"9["9:["9D["9Q) )F9RF__aMFR9Ze e|9y duQ r__n cP]tRӿ__aMӿ__nMiRX9ρ .__n}% !&* W_*-Z*:-Z*<% yR9v9D Y{$v9{9I9:I9DI98SN$ R9v!9 IY{$v9{9[9:[9D[9VXc c:W__aM€":& L: eqV O}__n cU]pW __aM __nMeW(:!: Ǭ__n \R|:v|: Y{$v|:{|:I|::I|:DI|:8SN$6 R|:v!|:U ,Y{$v|:{|:[|::[|:D[|:];F F:^c__aMc:9w :) ez] ~__n c\]y^__aM__nMn^: 1__n ?RBvB Y{$vB{BIB:IBDIB8SN$ RBv!B Y{$vB{B[B:[BD[B[x) )BeyF__aMFB>Ze eC.y !fx R__n cAw]y__aM__nMyB ˯__nv4z dI_Tp;qB:qBDqB/xG L Rzvzk Y{$I_IIBI_OIBB:BDB8S$ Rzv!z VY{$I_IIzI_OIzz:zDzUep Mf{ __n (z}K~RBN{ L = > $I_IIzI_OIzz:zDz3> MfMe Mf}4 RP@vP@S Y{$vP@{P@IP@:IP@DIP@8SN$ RP@v!P@ WY{$vP@{P@[P@:[P@D[P@cfq q@d__aMŽ@ @ 2b __n ca]c__aM__nMc@ߠ/H 7__nZj FjA RAvA Y{$vA{AIA:IADIA8SN$E RAv!Ad aY{$vA{A[A:[AD[AHqp{ {Ap J__n c.p]q__aM__nMqA8 Q__nRr__aMAw(3 3 BgGR xi sI_Tp)__r(/sA I_Tp) ]\A !iAzA:zA !iAI_Tp)A:AAZ" Q1F Q%Xm m%]Gjp J pƵ  Q$R@v@C[Y{$v@{@I@:I@DI@8SN$}R@v!@Y{$v@{@[@:[@D[@ j Ak__aM A_" "JAO6A gaiPl __n ch]j__aM__nMj&A  +__nR5v5>Y{$v5{5I5:I5DI58SN$5`R5v!5TY{$v5{5[5:[5D[5 D__aMDK HD;$ C>3O __n cp~]=s__aMs__nM2$D  %__nvŐ{ŐŐ:ŐDŐ__nRŐvŐvY{$vŐ{ŐIŐ:IŐDIŐ8SN$RŐv!Ő Y{$vŐ{Ő[Ő:[ŐD[Ő> 87e>1 w__n c=]d?U__aMU__nMY?J7bi ?x__na n7?__aMŹD7db ?x__n__at7?__aMD7e(3 dFCIŐ!iŐ0kŐ:0kŐD0lŐDc0s$wCIŐ!iŐI_Tp0Ő:0ŐD0ŐJ77CIŐ!iŐ_0'Ő:0(ŐD0)Ő"0*7J7@KV ndep uj}RŐNc L  ppd ujc ujh uj__x7Z'C __p mpd.s__aMs__pM__nMKG pu[ pu__p) D pu__p))& t%5J pu%kI_Tp' __r(/kא D__x)__x)0KI_Tp9%__a__bii .`hh__d>8o!%( L o tאא __x@r__y@rDאא pu4__x)* __x)FFG.Q Q__a*pV__b*p[444oz >__x)4K __x)__y)__k)א   4 4__x)79EEntI_T1I_T2__pO\8?Otn8CI\8!i\80k\8:0k\8D0l\8Dc0s$CI\8!i\8I_Tp0\8:0\8D0\88}CI\8!i\8Iu0'\8:0(\8D0)\8"0*}8L %wy }R\8N8x L  z  K'2 lHD\ QV'V\n8s~ a* D H3Dn8GI_T1I_T2__pO"9?O49o7CI"9!i"90k"9:0k"9D0l"9Dc0s$CI"9!i"9I_Tp0"9:0"9D0"9X9CI"9!i"9\0'"9:0("9D0)"9"0*X9 4v"9{"9v"9:v"9Dv"9CN 5%]h 5RI_T1)I_T2)__pOA?OAzCIA!iA0kA:0kAD0lADc0s$GCIA!iAI_Tp)0A:0AD0AGACIA!iAŴ0'A:0(AD0)A"0*A+vA{AvA:vADvAbs  P% i}ۅHcRAN L c h%%| ip JA* p__a8sA۵ __aZAIC,@%]3!&*3D{j_*-Z*:-Z*<u%3N*CI*-r*:-r* __p*Y'*O*CDX*$%|*4%|*__a%|D,%__r%ːt*$*4*__a*$*4*__aCI* F$%*4%*__a%8__n$%Y!%__c$%!%(n$__f$jˑ%!%(n$__f$FˑvQG v@ @;0 L<v+jq0n%:7c$%+ch%Ac%os&7[ITo]xJ]< L__p]y!sX!osX&71Is&Ios&&71s/&Osos&O&7אIT/&os&&7אch$%%sdosd&7!5#s&#os&&7!5M/&OMos&O&7IT, /&os&&7& % F__c% _   '5S'HIT _valsH|c5zU^s _%,  `%t%uy' }IT _vals|cV4!%( L 4 'אt%Iuy' }9eIT9 _vals|cIIT _vals|cאt%uy'}IT _vals|c$,}G/<]ITG _vals]|c }>V~IT> _vals|cbt%uy'}}IT _vals|c -IT _vals-|cn8t%Buy' }2^IT2 _vals|cB}IT _vals|ct%uy'}IT _vals|ct%(uy'}@DeIT _valse|c(t%zuy'}jgITj _vals|czt%uy'} IT _vals |ct%uy'}:[IT _vals[|cO'%__x'%t%uy' }IT _vals|ct%uy'}IT _vals|ct%4uy'}$*PqIT$ _valsq|c4"\uqאא< [(oә BpDh-ch%C2|nAL i1^i XYx xnp~LB e% e% %9V59[FQc'5'@oI^ s%:m %zA   a%Ԯ a% % %H84? 1xNY hs 5 p~ e0 e QV W H,7 %K,F^ %K/^2@+r} }D@J }  ,@i /2@ ,11"7 %Fa lHI_Tp%__a(__b('(%::IE%EVL6vL: lHu" @EV 60,, `;S V3 Sn8t%huy' }XQITX _vals|cht%uy'}xIT _vals|ct% uy'$}(IIT _valsI|c t%^uy'?}NzITN _vals|c^t%uy'}IT _vals|ct%uy'>}?IT _vals?|ct%Tuy'=}D;pITD _vals|cTt%uy'C}bIT _vals|c 2V[  V&+6 ^WG,OR %&^i ^W^,; %' ^W & ^W^& ^W}i' ITi' _vals |c"!, `Estr E1t%Zuy'}JvITJ _vals|cZfd%buf9%t%uy'}IT _vals|ct%7uy'}'StIT' _valst|c7t%uy'.}y%ITy _vals|ct%uy'2}LIT _vals|c6-Bc61t%Kuy'4};sgIT; _vals|cK}tITt _vals|ct%uy'&}IT _vals|ct%1uy'1}!MnIT! _valsn|c1}0IT0 _vals|cst%uy'"}6IT _vals|ct%uy'(}]3TIT _valsT|ct%iuy'}YITY _vals|cit%uy'}IT _vals|c}:IT _vals:|cf%NY ^W!h @BD$  @\%\%\%t%uy'}IT _vals|c7ch%u,XTj jx o55>< L__fU%h x 559( I 1 I' _)y'!5#[, \u[q`}k5( IT5( `/e}'IT'7_I_T1I_T2'__pOŐ?O5^CI*!iŐ0k*:0k*D0lŐDc0s$CI*!iŐI_Tp0*:0*D0ŐJ7DCI*-r*:-r*j5!i* uj*:*__nEjJjMyCI* uj*:*+b ?x__at7}t'uy',Yg%0}t'uy',Yg%0/: E IT V&cn ^W&} ^W' ^WgY{$I_IIBI_OIBB:BDB6I_IIBI_OIBB:BDB>xCIB!iB0[B:0[BD0\BCIB!iB0kB:0kBD0lBDc0s$CIB!iBI_Tp;0B:0BD0BBF|CIB!iB0'B:0(BD0)B"0*|BvB{BvB:vBDvBz RBN{ L  1I )[FH{ ;) [s aFH ;  aFH ;| UD= UD /2@&1 V@K aZe mt  +6 p~6 TS sp~A :B1%0 V$LI$ %[f ^Wx [30f SrhsD95 lHY &@Ը  lH%= lHY &@LLW W|fd%Y@'fd%buf]9%K eA%@G%d%610 ^%dBW W%Gu-n %G# ]Ol'3l1r ^O'31k  lH'2;D5 M  ]`~$\ g  9v   T   WOf'3f1g' g%-   O/'3/1MY3 %3$E ]  aFH;1l w  lH   lH۾   lHh   uje #_|:$_5} #b|:$b,~ +  + D2? [  __n cd] __aM __nMKG<   pu{   pu__x) ')E    __a*p __b*p FF6 * B  v)B EV y  y __a*p~ __b*p EE6 str.*'m    7E    __x/ OE[E;\    6>Y )  ) 6zY= H  Z\W b   $Zq   ) __x); 6=    __x/ __p/iUEt% uy'!}   IT  _vals|c \/Z-B  %vQ\ \?Gup{ \u I}RAN L = >.CI u!iA0k u:0k uD0lADc0s$CI u!iAI_Tp)0 u:0 uD0AAkr__aMŞA Q__n__aB mg m/(BG/: IT lH} GpIT  _vals|cT  V% dkey_1R"9NK L / 0[w[wT-8 pAG_ vBR_1\keyy/y11t%uy':}nIT _vals|ct%uy'}3IT _vals3|cQsrc't%auy'3}Q}ITQ _vals|ca( `lHZH' G QV"1%g 9 lH| ; , !v @ lH| ; i % lH  + s*5 )z{%uR u: u__f ü  lHxc$$ $$|;%%$i%%/G lH/3$Yd Fy&ՉD&IT,E&7oIT,/&ڽos&&7|&EIT,/&Qos&Q&7E)IT,/&a)os&a&7E,S/&OSos&O&7EIT,/&os&&7E/&os&&7ES/ME/IT1,IT2,/EE5WI_Tp9q9:q9Dq9/xG [Y{$I_II9I_OI99:9D98S$Y{$I_II9I_OI99:9D9JI_II9I_OI99:9D9>CI9!i90[9:0[9D0\9CI9!i90k9:0k9D0l9Dc0s$60CI9!i9I_Tp909:09D090(:vCI9!i9t0'9:0(9D0)9"0*(:v9{9v9:v9Dv9X } e}̅LR9Nc L L Q=ep e^I_Tp%q':q'Dq|:/xG Y{$I_II|:I_OI|:|::|:D|:8S$$jY{$I_II|:I_OI|:|::|:D|:`I_II|:I_OI|:|::|:D|:?CI|:!i|:0[|::0[|:D0\|:BCI|:!i|:0k|::0k|:D0l|:Dc0s$CI|:!i|:I_Tp%0|::0|:D0|::CI|:!i|:0'|::0(|:D0)|:"0*:C?v|:{|:v|::v|:Dv|:_NY ~hs e}хGR|:Nv L  ssP e!I_TpV@q\@:q\@DqP@/xG uY{$I_IIP@I_OIP@P@:P@DP@8S$Y{$I_IIP@I_OIP@P@:P@DP@I_IIP@I_OIP@P@:P@DP@9?VCIP@!iP@0[P@:0[P@D0\P@CIP@!iP@0kP@:0kP@D0lP@Dc0s$PCIP@!iP@I_TpV@0P@:0P@D0P@@Z CIP@!iP@l0'P@:0(P@D0)P@"0*Z @ vP@{P@vP@:vP@DvP@t RP@N[ L    SSԽ ! lHL!I_Tp@q@:q@Dq@/xG !Y{$I_II@I_OI@@:@D@8S$>!Y{$I_II@I_OI@@:@D@z?"I_II@I_OI@@:@D@j?"CI@!i@0[@:0[@D0\@"CI@!i@0k@:0k@D0l@Dc0s$%#CI@!i@I_Tp@0@:0@D0@%#&A#CI@!i@0'@:0(@D0)@"0*#&A]#v@{@v@:v@Dv@8## av#$ a;$R@N L /;$ 0@$QQT$l$ i35l$1o$$!&@ t__i $QΊ$`@C@N L 6$ 7$tQ@m%% :t__n kd%I_Tp*qC:qCDq5/xG %Y{$I_II5I_OI55:5D58S$&Y{$I_II5I_OI55:5D5W&I_II5I_OI55:5D5?&CI5!i50[5:0[5D0\59&CI5!i50k5:0k5D0l5Dc0s$j='CI5!i5I_Tp*05:05D05='$D'CI5!i50'5:0(5D0)5"0*'$D'v5{5v5:v5Dv5(R5N L ( $(B8(C( Ij1{(R5N L /{( 0(7C(( Iq(( Qu__n J(Qmc,(( (xDZa)stra)v%$z7cposh1w)str'(%i%=)! B)!B%%))zCv)*}A*D:B)sumC%iD'hAd*str'Fp'ch'*e*'msgDA*^.n%).n%E** R__c3%**+**J`!+++JZ+$Cr++ ]++ ! ++ @! +, @*K*,),9KV8,C, b@),~_,i,8,zx,, b@i,M,,x,,, b@),, %W,H)-;- %W;-%H*X-o- %Wo-HD*-- %W-Hm*-- %W-+H*- . %W .9*(.?. %W?.n8*\.s. %Ws.9+.. %W.+H:+.. %W.Hc+./ %W/H+,/L/ %WL/%H+i// %W/H9// XV//W// 00  "60|i9 0N00 V{+#6 G{<{# +#V{>+#e{]0:(0'"0|n9P*0q1 V{[; G{<{# [V{[e{0h0 A"1|s9*11 V{@ G{<{# V{*e{I["2|x9*022 V{E G{<{# V{e{|22-|e J )e# )e# e23 V3H+3B3 VB3H_3v3 Vv3H[33 V3H_33 3333C#4&4 &43f+4Gn8JZL4V4K}TBr4|4TV744VU44UU]44UJ 5(5K\ JD5b5J\ *K~559K\ }T55T\ UPP56U\ Uv,6J6U\ Vf66V\ VL66W\ 6ITvxS;Ʈ67 )[%60v796H$x 7$PH$(zm/6R 6z7lw I8Fذldls}/p:RFpM)\ 7w 9Fذds}/:RFM)\ \ 6.9L967\ .!d99 %% 0N!U99AN0NɁ!9:AN0N :AN!\ RfXzN1::afkf6kfaf6zf3f0 fjfjfPN:;ffd6ffd6ffdP fff:N3;;ff6ff6ffp ffg&N;<gg6gg6(g f fWfW:g6f@N5<<IgSgT6SgIgT6bgofT fftgN<=gg6gg6gf ffgqO7==gg7g g,7gKf ffgN0O=->ghD7hgD7hfD ff"hOI>>1h;h7;hC1hb7Jhf ff\h~O>??khuh7uhkh7hf fTfTh; O[??hh47hyh47hf4 ffh@p[?X@hhh7hhh7if fKfKi?Tt@@&i0i=i0=i`0is&i0Lif ffm00 AAmm7m 7mC l7 XAm l7$l l;A-mE XB.D 8%BF  8TF MΧ8اTO\ LL F__s'C+LPL Bph__nhe`Q7`QgUQret68Pat' h 5aMԎʎKLLhLMBL45L+L[NMNtNjNICMI$$ M'T3_NBtqI@#&NItLX#LL:wBRu`L@xNBL5L+L[N@NN6tNjNI@CNI$$VX+O^a3aOB qIa#jOI Lj#L^LwBRud3PBqI#OIL#LL*wBRud3PBudqI#ZPIudL#L=Lj wBRu`P}X~qg} BqI#QIL#LL wBRu_\ 1v;# RG;eQ ;'A<'mos<&798=[0i>'Pj?5cPa IWRPwPOa LR"Oi 9] t :$P DRPP; :$P FRPNPz :$a Q] _ XRS___cP pWSPwPO LS"O 9]  :$ __cP P0wP+ :$ΪSS m%it 0MnStSdVS,TSCl 0^Tml$ll TGm  1TVml 6ll-m* 0Z3Zs' (Gk';T Y#TeTz ]  .Y1>'0 n-Z_Z _Z98rdZF;L;Z,@ %ZZ-Z7ZDZQZ e  up ZZ [[bgF 6[l[!ba b#Tb#T[[VzCp *[[ Wu vv#T "v 1v,bg \5\;b AP#TFbU  Q\p\Ub& AP#T`bӇ0 \\obF AP#TzbRP \\bf AP#Tb0p ]!]b AP#Tb @ =]\]b AP#TbS^ x]]b AP#TȻ !]] lH% X@OH^@Xh] lPDH^lhsl'rhsl'm]  Z^r^ `r^9H^S^_Z^d^`^*` _^_d _ r] \ \ u__ `____#s? __$ `__'__#@D`lhs5(rhs5(]*>.D`lhs.'rhs.';Y 3RY FY ] ^B0`lhsB5(rhsC5(] ~Z4astr[a!&[a4!XV\5T!W]5!_Yp\{anY!qII!WI-fI!_Y]anY!qII!WI-fI!9`11a b F__c-%C/v P!fss{ bfstr|f!}01"end~0D"36V|b"l(Sl}bS!WIlfI!_Yo~cnY"rec"Xr~qg"dech'#cԎE#ʎKLE#Lh0]#a0b]#a0b#I/sdIqIIWI-fIN2dN#N#qI3dIWI-fINH3VeN#N#N#N$J3eJN׃NN'$3`eB@$qI#eI@$Lx#L|$L$1wBRuc=EfBqI=# fILD#L$L#%SwBRuc3SfBudqIS#fIudLY#L6%Lc%hwBRucq\ 1cfg&b g/g `V)/g5CgYg _pŐgkugHjg!g,gv%$&bS$,gS%WI$fI%K',KhL%L&O'@h"O%-9] :h3:,hB&qI:#hI&LC#LW&L&`wBRuc4gz+oiMg&Cg&3diB&qI#+iI&L(#L&L'wBRv\ +i4'X~qS'g4'3,3jBudqI#iIudL#L'L'wBRuczr] \ {Wjoj d__n xBjk 2Vi%eojwo'dVd((d((o@kkoM(ow(Hj`JHkajM(Wjw($$zjxKjj( _^ kk d__n 2Bkl 2Vi%6p+lHp)d[di)di)Spllp)bp)kJlk)k)2$$pKp(p0* _ %^ /ll E%O@ mao QVKC*{Nh*Q2&**ΣQQQ~*`g +l`]l +3`/nnBE+qI`#5nIE+Lf #Lg+L+wBR_3m( /nB+qImH #nI+Ls` #L+L3,wBR_3/BQ,qI#oIQ,L#L,L,wBR_soo vB%i/os QV0q%-{J-2&i-|-Σ~- g-l ]l-3 / qB .qI #pI .L #L+.L}.QwBR_3  /qB.qI  #JqI.L #L.L.lwBR_3!/B/qI!#qI/L'#LQ/L/7wBR_:s`1I/s@ '0yWŦ000ayWuyW4yW~THC0X g'y0aoX ]soy03x WsB0qI #sI0L #L0L#1wBR_3BA1qI#sIA1L#L}1L1wBR_7`sct 2V i8%1eo 8Wtwo2d VdR2dR20ojDPB{tdu V{R , G{<{w2 V{2 e{2ojDuo2po3op( _&uoE3|sos_o3zze3cB|uIv V{@ 1 G{<{}3@ V{3@ e{3o)vp3p4odvo4szzK4DavFw WuX vvc4X "v4X 1v4{ &w{4 {4{ L{4y{ #{4duxt&t52@D^w'x WuBp vv5p "vN5p 1vm5{Zx{5` {5y{` Q{5iduxtvt5,@x3@@xn8E4`xx 2V5y Fyy5 y6 y<6,x3Jxn8O4x?y 2V6y Pyy6 y6 y6eoi[yywodVd# d# 6p0yyHpd4 [d#,d#,Ѵyy y @zz z=@8z=zyX dyC7Xz7XX~q8g?8_z8X_~q8g?8hA{`9Xh~q8g?8o{9Xo~qZ:g:v{;Xv~q;g;}"|P<X}~q<gP<vS X|SS<vS |Si=S=vS |S=S=vS |SR>Sj>vS $}S>S>vS6( W}S;?SS?A3Z}Bs4qIZ#}Is4L`#L?L?owBRuw3oE~BsqIo# ~IsLu#L?L#@wBRuw3~BsqI#~IsL#L6@Lc@wBRuw33BsqI#~IsL#Lv@L@wBRuw3BsqI#qIsL#L@L@wBRuw3BsqI#IsL#L@L#AwBRuwXr] \ \ La y%p %a!+p= @ iL6AvSX STASA7vS< /SASAGvSUx bS BSEB`vSe SmBSBpvS~ ȁSBSBvS S$CS^C3 rBCqI#9ICL #LCLC@wBRuw3 BCqI#ICL #L DL,DPwBRuw3 `BJDqI#'IJDL8 #LlDLD`wBRuw3P ׃BDqI#IDLh #LDLDpwBRuw3 NBEqI#IEL  #L0ELREwBRuw3 ńBpEqI#IpEL #LELEwBRuw3<Bs4qI#Is4L#LELEwBRuw3BsqI#zIsL#LFL?FwBRuw3*BsqI#IsL#LRFLFwBRuw3BsqI#hIsL#LFLFwBRuw3BsqI#߆IsL#LFLFwBRuw3BsqI#RIsL#LGL?GwBRuw(\ \ a ۇp.;\ m$@mRGO@Pz `/- Vii % Sj %qGnlj @n5n*n#es/ee /ƈG @ip % Sq %Gnq @n5n*n#e/ee`|9Z!>x @T  |qG| (}}|GG RGooe#p$ eee3He eRHeRH3Zvd0>ZYvP(ދY('YjHSU SWIUfI```^HӋYHHYHYYHyY# Y?;^^^+^@^U^j^j`5;= Ffmt= 'Hm`Q> HeD $+F $I Ze &Z\^ "] "] r^ NYa^ ,S Vދ^ ^ H,ڍ Vڍދ^ ^ H7Dg V| gZ HZIZI"] ދ ] $^ 9Q0ҏ|p ҏթq 0JCr 0!J`:q 0`?Jn`:|}`jJSE}SJWIEfIJ`Gr `Jn`Go}`JSY S!KWIY fI!K"] "] "] "] 9  WiJ%SK%R|9xΒ]|l|4K{( {Fb(iUbGK1AP\#TC=]|C=l|C={|uK8|CH $G|KbCHZ!bKaCHbKbKh|{` ߑ| L|+L׏` L?LVLnK@nL5n L*nLe/ee|L| 1-|eJ )e)e|Lo ao%Mo  oNM sG ދZ "] b ln ] du-ݒ Mf  ؔ )[FH ;i 'Mf  hfMfM&f  5fM?fM>  WMMΒ ~/NݒMp ē   H;. QNoNN N FQN9oN,N UN!^  yC 'ؔA0!SR! iSNWIR!fIN3! ߕBsqI!#IsL!#LVL0O!wBRvR!w!^ !^ !_ !\ !wstrr w8l7s 6! s COX! ~qWOgCOI!t IxOPitu O!pu OWI!prfIO(!v K3PZ! ZPY"u kh7P?"u NWPa#"w bPabPI#"/IqI#"IWI#"-fINQ"22NPNPqIV"3fIWIV"-fIN["3NQN$Q"NFQNYQJ"ȘJN"׃NNnQF"" aBqI"#(IL"#LQLQ"wBRug!"\ 1"{Қ &713 '"lMY 'QcP" PwPR":$"D 0cP" QP3RwPKR#:$*I#0 IIP.<lh. 1lcq._ Y._ ..m. (vS.dSS.N.pptr]3.%x  .. x$ w. /̷/ ^/ "^/^c/_ 6 //#/5^#/M^ d@^Ud S#/?S d2SUd5/_ Z@/5y [C/,3$jdy(o5^C/\M^d@^d SC/?Sd2SdU/_ YS^/ dSd95/ [_Y/nYqI/IWI/-fIfJ/ Nx/ [^/ f^[/jS/(SI/6IqI/IWI/-fI@/=5 [3I%d/`  0ҟ_0P Sesrcd'Ee$eCpe\If*eS0`ӻSeWI0fIe_Y20gnYeq^0(yw^f^7f0(3f7fO0@}k"Of09] 0Oq^0a׼^^Vf03Vf0O00 ` F09` 0W` K S@1e0 Xcwdn _11ouff31@BVqI1#IVL1#LIgLxg1wBRu_:1B153B1owBgqIB1#=IgLN1#LgL!hs1wBRu_31&oBqhqI1 #IqhL1#LhLh1wBRu_1l` 111\ t%y'17 [&0h1 h1 ^1 "^/^Mi1_ 1(jaii3r2@YB-jqIr2# I-jLw2#LLjLyj2wBRus12532HBjqI2h#IjL 2#LjLjH2wBRusY 2 rkhIHrLY4#L[rLrh4wBRut33533BrqI3#IrL3#LrLs4wBRutq^3X^Qs^is33Qsis 4O344 BsqI44#IsL:4#LsLsI4wBRuo3n4FButqIn4# IutLt4#LsL t4wBRuo3R4\ U4s# [4VtS4(StI46ItqI4ItWI4-fItY4 X@rTthst4L4 XwBLt5L+Lt44X(t u3*5@BVuqI*5#IVuL/5#LuuLu>5wBRo445348XBuqI4P#gIuL4#LuLu5wBRo3 5 XBvqI 5#IvL5#LvLJv5wBRo(5\ /P5>x [hm8X^50]vS^5(S]vI^56I]vqI^5I]vWI^5-fI]vɋ58ڋv35;BvqI5#NIvL5#LvLv6wBRu_ɋ59ڋw35;BwqI5#IwL5#L&wL;w5wBRwɋ69ڋNw36;BNwqI6#tINwL 6#LcwLxw6wBRw#6:ڋud3#6;BudqI#6#IudL)6#LwLw86wBRu_55X55#5!6\ ݞw@6 [w'JAx\FX^6 xʭwx ݭKk6@y YLxLAyOk6 N"Oxs69] 6hO7ByqIO7#IyLU7#LyLyd7wBRu_j6X?B zqI6x#I zL6#LzL{H7wBRu__Y6{^nY/{L6{BL[{5L|{+L/{66{C{{37@2BWqI7#IWL7#L|L-|7wBRu_66536{B@|qI6#I@|L6#Lb|L|87wBRu_360}1B|qI6P#I|L6p#L|L|#7wBRsY7}`r}h} 7d7B+}qId7#I+}Lj7#L@}LU}37}6Bh}qI7#Ih}L7#L}}L}7wBRu_37{B}qI7#tI}L7#L}L}7wBRu_^66`z7\  7 %1W77$L7` 8` 8`  84str're'8)ǕhH8` 1^ `84&^^g8^o8!^}^~o8!^h8` ] Q!%(n4Qˑ'e} J__c %_98&_^8_^&8qCV85uo e8 %-~69t$gR8 RK~vR_~8.R}~vR~8Eą85~8<8<9&_~ _,919^ ,9^ ;W@9&WDR9` _9a !]`9|]Dy^5~J_C~fa'k?b'1m\Fs9}9 ` 9` 9$a 99W` ! !AB\FBD5J !%vDy9ppJ(e\F9@P@c Z :AZRZ0:B_ @;:`C%KA:]_ :BqI:#UIL:#LL:wBRug:^  :Ia :da ;:&&J:xZ53U:4OBqIU:#ILX:#L>L`:wBRugU:za n:\ :\ ::P ::P;}O)7I;JI~;4$ ;4Ԩ;4I;4~II/;g3/;]BqI/;#IL4;#LLTG;wBR_/S;>rS;.D8S;W;  ЁW; MΧاЁ`;\ l;\ ,:;\#3GNeQN'osO&7,S5T5FY_5;)GneQn'oso&7;pC @P; QPP;<cP;QPTwPm;:$;9$cP;]iPwP;:$;kQPR0Q@;kQPR ? Q ? cP;(bPӂwP<:$i1/<kQPwR0Qs,@<os:3: ;_V<@J_SV<XSLWIV<fILU_m<<>d_Sm<MSăIm<6IăqIm<IăWIm<-fIăcP~<@<PwP1O~<"Og<9] H=( PwP=PJ=XVPLPPR= 0P$PԄ_=<:$cP<L>^ >"] zj>HOjjRjF > 8jd$>Tdd@I^ S%8ȳCzI3`@BzqI#IzL#LLوAwBRo2L@AL-H+W W%\__m84Lv  v %aLD M%L  _.@> S>I+ S>`Y`>g`>  vlj`>H #?lj> M>p #?/MM>L?#?LLS-? FZ<z? cXzZ?h?cNJXh?~qgNJaL?pL,?x???|x? An{? g֍Q{? $Rϋ R RS>r] ?\ ?\ ?fM?'' c'!aY'msg\T`?0!}c`J`?P!D*`jS@SWI@fI!@܌!@|ccP$@h!PwP 7@:$_:@!_._cPB@!nPՍwPOB@ c"OՍK@9] \@:$!__|AcPO\@!o-e!|ccPb@!P-wPUu@:$_x@"_u_͎cP@("yPwPO@ n"O@9] @:$H"__?AcP@`" Tl`"|ccP@x"PTwP@:$_@" 6__ɏ@cP&@" Fޏ<"|ccP@"PޏwP@:$O@ oe>@|ccP@"PwPm@:$_@# __ŐcPA#PwPOA "OA9]  A:$8#__7AcP#AP# L1A&bM1Ah# 7^nk1A#Uknj1A#jjnMA ^udkAUkudjAjjud!@A\ 9a''#-B\n#F0H#|c3cP&?F[<s?|cQcPOT#oe#|cgcPvv|ccP&ZF'<O|ccP#b&bM#^k$Ukj($jjMF^kUkjjj?RmPwRstRPwRuT\ -ossb15vA$%str'/@$end*P{9 3"Ox$msgTHcP-F*hPvwPO-F ]"Ov6F9] GF:$*__FcPMWF*^ΡkWF+UkΡjWF+jjΡMFI^udkFUkudjFjjudEFWFF\ jFta '0+V e\FX|\F37bF|ccPFX+P7wPF:$_Fp+_΢_+__LGcPGcPG+)G&bM)G+^ak)G+Ukj)G+jj,i',_YKG,nYKqIKG0,IKWIKGH,-fIK`G`,*`mGa cmGx,ccx,|cPvG,PPG:$G,8G&bMG,^kG,UkjG-j5j3G-BUqIG#IULG0-#LLͥGwBRud3G B qIG#PI LG#L LM HwBRu_MH^`kHUk`jHjuj`-HA ^udk-HUkudj-HjjudFKGH\ PHjv ' $H-|\Fl0yYgH  YsH;3Hh-Z BlqIH#! IlLH-#LLʦHwBRkgHsPlRHP ' '-|\Fl/ 0yYH-  YH;3H-!o BlqIH-#6 IlLH.#L L9 IwBRkHsPlRIr' .g| \FL 03PyY'IH.  Yg2I;NI`. {ç`.|ccPTI.P{wPdI:$dI.F F.|cbdI.(ccoIdI 9 IqIdIIWIdI-fIzI:$MI. ^kI/UkjI/j j3I0/B5qIIP/# I5LIp/#LWLy`JwBRud@cI/a`cVc/|cI=I/I&b3J/BqIJ/#ILJ#LL-JwBRwM Jd^@k JUk@j JjUj@MmJ^ikmJUkijmJj~ji3J$=BqIJ#ILJ#LLԪJwBRuSMJ^kJUkjJjj3JBudqIJ#IudLJ#Lu\LJwBRw'Is4PuTRuNIIIJ"] AJ^ J\ ! _msg`5r2/`I+# 0&g&00Yvy&h0#?oy M0#?/MMHL#?LL#-0XF6<b0cb*cX*~qpgaL~pL< >0aN&b|D`bO1ar(c(c~IO gI(qIOI(WIO-fI(b:$3b81aBqIbX1#ILkp1#LұLwBRuc3a`B!qI#'I!L#L6LcwBRuck`kvjjjvr] \ \ \ JK'q''xc$1'$"%"1msg:XpK;#&npK|ccPsK1P&wPK:$oK1<ų 1|cKcPK1<lA1|ccPK2PAwPK:$K82<ݴ%82|ccPKX2PݴwPYK:$:Kx2=:ZyPx2|ccPK2PywPK:$oK2=]2|ccPK2PwPK:$&K2=F<2|ccPK3PwP-L:$@cL83=J`cMVc83|cL=LX3>ٷ!X3|ccPLx3PٷwPU,L:$,L3>u3|ccP2L3PuwPBL:$&BL3>F<Y3|ccPHL3PwPXL:$@cZL4>`cVc4|cgL=gL 4>()q 4|ccPmL@4P)wP}L:$ML`4>^źkLx4UkjL4jRjL ?L&b3L4?+BqIL4#ILL4#LۻLNwBRu\*O^k*OUkj*Oj0jAO^DkAOUkDjAOjYjD3O?WBmqIO#ImLO#LLOwBRu\MO"A^¼kO"Uk¼jO"j׼j¼pKLLދL^ 4z"msg2TM539=335|cNcPN054{g05|cNcPNP54+P5|c-NcP@c-Np54`c_Vcp5|c#?3/MM(VLhY#?LL-V@>3F<Vh>c3FWiW cXiW ~qmgaLGY!3pL`YyW1YDYYyW>f5v1W>$11>18W> VX> poMeoX? 4Yt$gRX(? RvR H?RQvRsXEW`?f{5*RWx?$9RCR3?RRSW?g5W((W?g7 (8W?5}6I3W@@[6BqIW(@#!6ILW@@#LHLzXwBRu~2L X@AL"XD("XA56g(S(L+XX@#;6LLL1Xp@#;LLaLcX5pL({XW=Y Y\ hY\ ԜrY2>/r%@>sss ~Y@s@9I+e Y@7YgYAm8v4Y8A#?84Z MZhA#?J8/MMAZL]#?LL-WZA9F<WZAc8ZZ c~XZ ~qg~aL\!)9pL]Z\\YZAtW:!v81[A$1u1A1[B V8\(B poe;\HB :\t$gRE\hB RZvR|BRvRi\E'[Bt:)*R'[B$9RCRBRRP*[Bu:PP&a[< 8[t;#q'A['QA[!QQ QA[Q*QA[!VQ>Q`OA[!` P>P* G[t<#u'G['2QG[!mKQAQG[ZQQG[!EQQ`OG[!\OOb[Cv<r[((r[(Cv> (18r[HC5=Ic3r[hC@c=BqIr[C#)=IL[C#LL\wBRu~2L[@AL[D([A5=g(S(;L[#;=LL_L[#;LLaL \5pL#\\\\ ]\ @]FstrD FTqD $C FmE XCEiG 'IY]G >IqIY]IWIY]-fICchH '8.]"N p?N"D:]"|ccP]DP"wPO]:$c] De ?crc D|cP]8DPP^:$.] K B@ND] |ccP]XDPwP^:$^U @!9^|ccP^pDP!wPN0^:$8^ Q Aq8^ |ccP;^DPqwPN^:$^^"[ A^^"|ccPa^DPwPt^:$(^'` A3Z^ Zc^ ] &Bcc1^ |cP^DPFPf^:$c^ W Bccy^ |cP^DPP _:$(_Db BD|ccP,_EPwP<_:$<_(Eb C#(E|cb<_HE(cc8I<_ CIqI<_IWI<_-fIR_:$&R_pEc DF[<spE|ccPX_EP[wPh_:$3h_Eb DBqIh_E#YDILq_#LL_wBR[3_b EBqI_#DIL_#L-LZ_wBR['_47]Ek @Em]&bM]Ek E^k]FUkj](FjjM_ k F^k_ Ukj_ jjY]_\ 1_*M3H *M@FMI T`F(LiJ %6p_FJ FHp,d_F[dJdJF*K /My_`FL uG__cP`FSGPwPO` HG"O `9] `:$G__ acP&`0GL GF<0G|ccP `PGPwPV3`:$&3`pGM ;HFv<pG|ccP9`GPvwPI`:$I`GM HG|cbI`G(ccII` HIqII`IWII`-fI_`:$&_`GM YIF-<G|ccPe`HP-wPeu`:$3u`8HM IBqIu`XH#IIL~`pH#LLawBRu[3`HM IJBqI`#JIL`H#L#LE+awBRud,`HM sJ7s`2>&`HL JF<H|ccP`IPwPV`:$``L &K`S`SWI`fI3aM KBvqIa#eKIvLa#LLawBRu[3aM LBqIa#KILa#LL awBRu[`k`@aIO RL Na&bMNa0IO L^BkNaHIUkBjNa`IjdjBMaO M^xkaUkxjajjx_a\ 9498Y0KPMNI8xI@NI3I@MBqII#MILI#LL*IwBRo2L@ALH-5\ 4gK7NNCgMg3INBgqI#NIgLI#LLIwBRo-\ B NOIT `/OIT5ahZ''hZ AmZl"$J]ZmsgLbOb|ccPb(JPwP b:$_b@JP_/_cP"bXJ{PPwPO"b pP"O+b9] dW^k>dUkj>djj6czcgs%c \X_%c `_B_)c_~_zcM@Y~cM4gcMMgDCg3cN3YBdqIc#XIdLcN#LL7dwBRvc\ McY^kcUkjcjjzQdY~Qd ^d4gMad"HZ^:kad"Uk:jad"jOj:bcw^}d\ 11j ZZIT `/ZITאB d#Z_ V0Nw_ _dHN<[`c_{_d__`d\[*`rZd`N;_Z8ZLdxN0\xN|cbdN(ccId #\IqIdIWId-fId:$gdNn^!ggd,\d&bSd,\SCWIdfICKeN,]LrLOe ]"Ore9] eh3eN,]BqIeO#\]ILe0O#LLPewBRuode+]Xde~q<g3~e,Y^BPqI~e# ^IPLe#LeLewBRuober] te4gM$e^^k$eUkj$ejjMe0_^keUkjejjde~ee4ge\ ,-epf-BpfNeHOdN7NoeOa1'O|ceOJeOR`f&bbfO`(cscIf `IsqIfIsWIf-fIsf:$3fPTaBqIf P#aILf8P#L]LfwBRu\3\gBuXqI\g#aIuXLbg#LLqgwBRu\g)fPPd!gg34f,boCf&bSCf,YbSWICffIKFfxP,bLL1OFf b"OOf9] ^fh3^fP,/cBQqI^fP#bIQLgfP#LLfwBRvf+{cXf~qg3-g,cBqI-g#cIL3g#L*L?AgwBRvfr]  g4gMnfid^RknfUkRjnfjjRMAgd^kAgUkjAgjjeseP1e_eP`__e__zfPf(~fQW4gf8QMgCgW3fXQfBqIf#eILfpQ#LLfwBRwf\ zg[f~g#g4gfw^+g\ 5ff p6uff %uf;yf0hfffQhfF 4gd)da 3,QgBwqI,#rgIwL1Q#LLXwBRug3\BSqI\#gISLa#LLpwBRugA\ y\ a.WMiʭQBiݭKy hLLWO h"O9] *h:;iBuqI:#iIuL?#LLNwBRuwW\ !uk!%( L%'%kQk J%@%hC%ii1%iO % j"O9] %WjX~q% gI"%wjI9 XjB{ qIX#jI{ L]#L L lwBRug1>hGu\ אJgo2+ RostrX6gRkNW Ak R[6g0RkN A 0R[.hHRlʭ  HRݭK:hhRy -lL LE GhhhlBe qIh#elIe Lh#Ly L iwBRu[7h3GhRmB qIGhR#lI LPhR#L L hwBRu[3[h%mB qI[h#]mI Lah#L, LA shwBRv6hRmNT Ah R[6hRnN A R[ 6hS?nN A S[6h SvnN, A@  S[3inBX qIi#nIX L i#Lm L iwBRu[3i&foB qIi#-oI L i #L L /iwBRu[g hw(.hMi8i\ d@i-sstr5(%8S"s ~`Sqi%ExS&+biSp(ccIi pIqIiIWIi-fIi:$3iSqBqIiS#pILiS#L;LxiwBRu~3jqBu~qIj #RqIu~Lk#LLkwBRu~ik(iTs (8i0T5prI 3iPT@NrB<qIipT#rI<L&jT#LnLjwBRu~2L1j@ALJjD(JjK5rg(S(L_j#;rLLLzj#;LL*aLj5pLNjjii&bj+jj\  ku)yx5(x'msgy5Tuiz'0[kT|LtrT|cb[kT(crcI[k ?tIrqI[kIrWI[k-fIruk:$3ukU|tBqIuk U#tIL~k8U#LLkwBRucckPU'ucc/PU|cPkhUPCPWk:$3k|uBudqIk#fuIudLk#LzLkwBRuc[kok\ luNvlU;vIlUIIlU-Il-sQs lOv5(I*Lrs#L*L*swBRv3s B*qIs#I*Ls#L*L+swBRu_3sgBu`qIs#.Iu`Ls#L!+LN+swBRu_s`;s Gs \sOs\ s^$%)5(a+len'+os&7+s40/m$+cPs OP/wP+s:$s^S',[cur;(N,tĒx,tx,-ta cP8t[ P,wP,Kt:$cPKt ,P,wP,[t:$ tBRvktP\RvcPotPwP,t:$Γ^$%)5(len'os&7 tN)15(len1'os1&7t[2-D-z-cPt\'tP-wP-t:$tQstR1Q)tasG5(osG&7t K-.tc=cPtKBP;.wPS. u:$cP(uIyPwPf.8u:$u+#uPQ 5Pu2xMPu(\eMIPu@\IIPuX\-IbuQxWstr&5(os&&7g-IT5(/&Op\ss&P ~\&PgI+. \.g\/v8/ ]#?A8/ MP]#?q/MM/LW#?LL0-h]*F0<Q0]cQ06T c0XT ~q/1g0aL<PpLD1Oc&92k]&QNJZ1=1R]&q2dk2](]&@23k2]&X2 k2]&2k2xMeMk2IIk2I-Ik2Qu~]&2I^#I2I-I2N(^#N2N3P^ND3NZ3Kh^Ko3K3 K3K3K RK3K3K TK4K4 K>4"q^&=Q4Iq #KIQ4Iq-IQ4Nz^#Nu4N46Nu~NVK^0KKvK4K4KRK4K4K TKKv KR"cP^&Rx4((^&R (58_5PIE53(_@.Bw5qIH_#Iw5L`_#L5L5wBRu~2L @AL5&D(&x_5g(S(6L/_#;LLA6LQ_#;LLe6aL`_5pL6yW\ \ eDpuˠ ' ' 5(  5(u _u `6_6_u_6_63u_0B6qIu_#I6Lu`#L7L%7vwBRu_3uBC7qIu#oIC7Lu#LX7Lm7vwBRv3v  B7qIv#I7Lv#L7L7)vwBRu_34vBu`qI4v#_Iu`L:v#L7L8IvwBRu_u_uWuWuO2v\ Pvistr[ '8(`^3\ _v\ Wb8X_v~qv8gb8@`ch^ %8avh`g b8ah`b8Iv/IqIvIWIv-fINv2N9N/9qIv3PIWIv-fINv`3բNG9Ng9hwN9N9JkwղJNuw ׃NN9v3w`d YB9qIw`# I9Lw`#L9L:`wwBRu_3&w`d ѣB-:qI&w#I-:L,wa#LB:Lo:>wwBRud3wd IB:qIw#I:Lw#L:L:wwBRu_3wd B:qIw#I:Lw#L:L;wwBRu_v47 wMiwwIBqIw#ILw#L,;LY;wwBRu_kvr_ wvw\ mnӦIT%7_Ӧ@cإ`cl;Vc;|c&=(a;1&bM10aa^;k1HaUk;j1`aj <j;MR^utkRUkutjRjjutn\ :-w %<2 'n<0 'w ʭ<wݭKxy L<L#=xhxxxa ʭ=;>xaݭKxay )L>LH?Ox "O>!x9] ,xhxBWqIx#]IWLx#L?L?xwBRu_x3,xa B?qI,xa#ݨI?L5xa#L@LU@`xwBRu_3Fk5cUk>Fj5dj`Fj>FMV^utkVUkutjVjjutr\ E{2Ȳ V| o{ otFo{ /oF{sZ| cZFZG|"] 3Y|d ۳BGqIY|8d#IGLb|Pd#L8GLZG|wBRuk3| SBulqI|#IulL|#LxGLG|wBRuk{ދ|sK|Y|"] w|^ | ] |ދ|l}\ 9}˴@ V[ @hd5 \F`3}d zBGqI}d#AIGL}d#LGLG}wBRug3}d BHqI}d#IHL}#LHL*H}wBRv3}  jB=HqI}#1I=HL}#LRHLH}wBRup3} BulqI}#IulL~#LHLH~wBRug6}2M}ئ PuhQ4[}ދv}}"] }^ }\ +H- ~j]% V( %%e$6 %HA@ %I8~ - ٷ+:IA~[6A~- AIW~ئPu`QOW~ e- [^IbW~ e~bJJo~ASd~- SiJWId~fIiJio~- ӸtJ~ئPu\Q43~8e- KBJqI~Xe#IJL~pe#LJLHKwBRu[3~e- ùBvKqI~e#IvKL~e#LKLKwBRu\~0 KH[~W[ L3~e0 wB!LqI~e#>I!LLf#LCLLeLwBRu[$4 L,b$e;bL9Ai94 tLPئPu`Q43_ f4 qBLqI_@f#8ILLhXf#L;MLwMwBRu\{spf6 {MFbspfiUbMAf7 \M_vfnvMEvf@TvM(OTv'Nb[EDq['NsFwff8 %HN{f8 {qNFbfiUbNAi: tNئPu`RwQ43f: xBNqIg#?INLg#LNLO wBRu\3m: B#OqIm#I#OLs#L8OLeOwBRu\ދ"] R|""] (0g@ _xO`b(0gmobO7A3'Hg0 ׾BOqI'#IOL-`g#LOLOiwBRu[3?- OBOqI?#IOLE#LOL)PTwBRu[3T - B6/bX/~qcgbvSalS3cScm3mlBcqIm8l#OIcLyPl#LcLcwBRv3BdqI#IdL #L.dLCd&Vdd5ɋhlڋe3l;BeqIl#~IeLl#LfeLewBRu`3Ȉl/BeqIȈ#IeLΈl#L fLFfwBRvvS;mbSfSfG3G mB gqIG@m#I gLSXm#L/gLMgwBRv3ZpmPBkgqIZ#IkgL`m#LgLgwBRv3gmBgqIg#IgLmm#LgLhljwBRv3tm>B/hqIt#I/hLzm#LQhLsh׉wBRv3BhqI#|IhL#LhLhwBRv3n,BhqI#IhLn#LhLhnwBRud3$ B iqI$#jI iL*#L iLMi9wBRuC3DB`iqID#I`iLJ#LuiLiYwBRud3Y BiqIY#XIiL_#LiLiɋrڋi3r;BiqIr#IiLx#LjL4jwBRu`3BGjqI#OIGjL#L\jLjwBRud3BjqI#IjL#LjLjwBRud3vBjqI#=IjL#LkL3kΊwBRud3Ί6BFkqIΊ#IFkLԊ0#L[kLkwBRudRai *,;B\ 9595@At' 0ns%kPnk+8 vl8 5^8 M^8l@^jl S8 ?S8l2SjlE_ SghnS~lSlvSgnJS~lSlnɋnncڋl3nn;BlqInn#(IlLw#L$mLomwBRuڋm3;BmqI#ImL#LmLmwBRuɋڋu3;BuqI#LIuLË#LmLnҋwBRud'\ 9595' %n\FP%oʭnQnoݭK40oy ^LnLnAh}B:oqI}#I:oL#LOoLdowBRv1OHoʭwooHoݭK[hoy @L pLEphhBuqI#vIuL#LqpLpwBRuWX3ho/BpqIho#IpLqo#LpLpwBRuW3xoBqqIx#nIqL~o#L1qLSqwBRv3pBqqqI#IqqLp#LqLqwBRv30pBqqIPp#^IqLpp#LqLr֌wBRv3 B5rqI#I5rL#LJrLwr+wBRuW36BrqI6#NIrL<#LrLrKwBRuW3KBrqIK#IrLQ#LrL!s`wBRuW3`wB4sqI`#>I4sLf#LIsLvsuwBRuW%iO*4\  S_h~' %H0A}  ps^pX_^&pqCV p5"o e q st$gR"(q RsvRs8R tvR!tEą> 5L4tF<><SSGtWIfIGtcPK PtwPtT:$cPWPtwPtd:$cPg@qPuwP;uOk O"OYut9] XqPluwPu=PpqVPuLPuP 0Pu$Pu:$cPqPuwPu:$3q~BvqIq#EIvLq#LPvLvwBRuc3BudqI#IudL%#LvLv4wBRuc=\ O !fd%r*'Z,%@fd{%b{'{JcPn}PvwP:$cPq}PwwPO "O0w9] rPCwwP=P(rVPWwLPkwPPr y0PWw$P~wА:$cP~PwwP:$ ӏhrx%ww5wX~q/xgwr3D@Cxq^)r-^nx^x)r3nxxO)r}"OnxiO#a u^ Ia da 3mBsqI#4IsL#LuLLxwBRva nď}яr] }\ \ \ $O 0DO;P' r71r }?@v ?8z %xcPzo PxwP:$cPp PywP:$j5 ?&y# b ?*b Rda br (c9ycNyI I9yqII9yWI-fI9y:$bs (caycvyI IayqIIayWI-fIay+:$z}ܑTb tb b cP’cPʒ}cPcP3}I}\}o}Q\ d\ w\ HU %cPEaOPwPY:$cP\bPywPm:$da Eu}}\ + %y%1(sycP5yWPlwPI:$cPLyPywP]:$b 5j=r}}\  1H%C9 HsycP=H[PwPQ:$cPTHP zwPe:$b =r=z}}\  1<%hs#zcPE<_PwPY:$cP\<PWzwPm:$b Ez=}} b \  -BOlenS%L;1"/soz_YsSnYzqIsIzWIs-fIzcPGsVPzwP[:$b[sWe(czcI[ ZIzqI[IzWI[-fIzo:$cPtsWPzwPz:$btW!(c{cI I{qII{WI-fI{:$cPPQP.{wP:$cPQPV{wP:$+b G}} }}\ "\ Х#E s#+cPʓ)EPn{wPޓ:$cP*uP{wP:$P*P{P<cP*P{wP{:$cP+ P{wP|$:$P&+=P|P3<cP6 +qP0|wPH|C:$cPu'P[|wP:$cP(P|wP:$ʓK}u}\ }Ŕ\ =%mД&U ]=C$(t.\F$|J P Pt6"}Z}Pt|ccPhtP"}wP}#:$_&t__}cP.tP~wP)~O. "O~79] H:$t__Z~cPKtPp~wP~v:$&HtbF~<t|ccPNuP~wP~a:$n8u"<8u|ccPPu#`xPu|ccPpu#pu|cbu(ccI IqIIWI-fIЕ:$3Еu# BqIЕu#ILٕ #LLuD+$'S^+bS>WI^fI>^av+^p^a ^0^ŀ^0^XE` y v/ , v|ccP8v0bi8v|ccP&Xv0F<ȁXv|cĖcPƖpv1pv|c֖cP֖v1&v|cb֖v(cc9I֖ IqI֖IWI֖-fI:$3v1 BQqIv#IQL #LfL{31oBuHqI#JIuHL#Lu`LPvPLPuHRuRPuRs3w6 BLw#LLwBRu`qI#I0w5O#˂0w1T“|cӘcPӘPw.Pw|ccP@c՘`cVcC՘|c=$ZDX:p|ccPpw˃&bMw^kwUkjwjɃjMhC^khUkjhjj)w4:w|c=cP=w5^w|cPcPPx5 ̄x|cbP(x(ccIP IqIPIWIP-fIf:$&fPx5 F!<IPx|ccPlpxP!wPm|:$|x6` x|ccPxPwPم:$x6 x|cbx(cc?I  IqIIWI-fI:$3y5 BpqI8y#^ IpLPy#LLwBRu`35 B҆qI# I҆L#LL wBRu`3 6u B'qI #N I'L#L<LQ=hy ]dShy|c/cP/y ȇy|cBcPBy އy|cbBy(cއc IB IއqIBIއWIB-fIއX:$3XyB;qIXz# I;La#LQLf&dy|cϗcPїz'ň݈z|ccP0z'e0z|cbPz(ccI XIqIIWI-fI:$3xz'BOqIz#IOL#LdLy3'1BqI# IL #LL3#BɉqI#pIɉL#L߉L3Ț#BqIȚ#ILΚ#LL1?'D&bz?w(vSzdSS3z?B(qIz#I(L {#LkLwBRu`MP^ŋkUkŋjjjŋ3)({@BqI)#IL/@{#LILx wBRu`M)^kUkjjj3+ @BqI+#hIL1#L֌L@wBRu3K?BqIK#ILQ#L-LB`wBRu` PLBPu@RuPLaPuRucP}PLPuDRuPLPuPRu}I\  %r;KDU"da 3,X{IBuqI,#IuL2p{#LLXwBRuw39{I4B'qI9{#I'L?{#LOLqpwBRuw3yIBu# qIy#yIu# L#LLwBRuw3I0Bu#qI#Iu#L#LώLwBRuw\ W {LK-"da 3,{I!BKqI,#IKL2|#LmLhwBRuw39|IBʏqI90|#`IʏL?H|#LLwBRuw3IBs qI#Is L#L,LYwBRuw3IBsqI#LIsL#LlLwBRuwO\ \ . 8%}n `|.vnSn `|lnbn$|$|Li2K;da 3E|IB;qIE#I;LK|#L]LwBRuw3R|I|BqIR#CILX}#LLwBRuw3IBs qI#Is L#LL,wBRuw3IBsqI#/IsL#L?LlwBRuwh\ \ f (}.Q}n @}.nSn @}lnbn$`}ے$}LCے2Kf;da 3E}IB"qIE#I"LK}#LDLfwBRuw3R}IVBqIR#ILX}#LLȓwBRuw3IBs qI#Is L#LLwBRuw3IBsqI# IsL#L&LSwBRuwh\ t\ \ ]u X-B<L;f:P$u~= ʭrf~ݭKy / LrL-h B]qI#g I]L#LrLwBRud< ~=U# ~j_YHH~S9!nY}qIHI}WIH-fI}cPx`~Vi!PwP:$bx~W!(ccI !IqIIWI-fI:$cP~W%"PwP:$b~W"(c/cI "I/qII/WI-fI/:$cPP"PDwP :$cP Q #P|wP:$Yb u}%}a}}3~=#BqI##IL~#LЗL HwBRud3d&=E$B*qId# $I*Lj #L?LlywBRu[\ h$' 8|'LZ $[ZS wSØWI fIØ ~x%ʭD~ݭK,y p%LLٙO, e%"O49] ?h,@ %*[ Mf3M@$&BqIM`#%ILVx#LBL~wBRuo3]&BqI]#c&ILc#LΛLwBRs3'B qI#&I L#L!LNwBRuo3'BupqI#S'IupL#LaLwBRuo \ 9'* 8[*[ /([S SWI fI (ʭ=fݭK,y (LҝLO, ("Oҝ49] ?h,@(*} ϞMf3M(v)BqIMH#=)ILV`#LdLwBRuo3]x)BΟqI]#)IΟLc#LLwBRs3f*B.qI#-*I.L#LCLpwBRuo3*BupqI#*IupL#LLwBRuo \ +H0  +C. 8|C.+à_vnvEv@Tv+Tvb[E+q[sFw̌؀+ی05D.,*C Of3O,BqIO(#m,ILX@#LL#wBRu_3_X-BQqI_p#,IQLe#LqLwBRsl>-3-BĢqI#}-IĢL#L٢LwBRu_3..Bu`qI#-Iu`L#LLFwBRu_DMi \ HY1`.8 8'V88'YU_'/d_SMSݣI6IݣqIIݣWI-fIݣ]Ё 0ʭRЁݭKly /L=Lyh0BuLqI#/IuLL #LPL}/wBRudi=0* f3 0BHqI@#|0IHLX#LLاXwBRuC3p-1BqI#0IL#L&LFwwBRw31BdqIЂ#l1IdL#LLwBRw32BƨqI#1IƨL0#LL wBRw3H2B(qI`#\2I(Lx#LJLlwBRw3 3BqI#2IL#LLΩwBRw3؃3BqI#L3IL%#LL0wBRw30 3BNqI08#3INL6P#LpL7wBRw3iu4BqIi#<4ILo#LŪL~wBRuC3~4BqI~#4IL#LLGwBRuC3e5BZqI#,5IZL#LoLwBRuC35BqI#5IL#LīLwBRuC3U6BqI#6IL#LLFwBRuC36BYqI#6IYL#LnLwBRuC3E7BqI# 7IL#LìLwBRuC37BqI#7IL#LLEwBRuP(ˠ=iIˠ]Mi**\ n8Y,8: 8:}%&h8*X ­4f348BqI4#8IL=#LXLhwBRuo3DЄv9B®qID#=9I®LJ#LLwBRs39B qI#9I L#L5LbwBRuo3f:BupqI#-:IupL#LuLwBRuoi&Mi\ H:: u%>:X<: ;:0:cPu;;PwP:$cPuk;P+wP:$c =›}՛}?!;NC!Cb!}qCY6M<hx6#x6}xݛ\  t<N=HC=HcPEy<PlwPY:$cP\y=P.wPm:$b Ez=}}\ :j=j> hU>F pcPUy=PlwPi:$cPly >PwP}:$b U=}}-\ \ >? lH n?:ȅ:-:tcP`u ?PwPq:$cPtu9?PвwP:$c ]=}Ü} r] \ \ oFМ3?AAܜ(@&ܜ(&H@\cP5<Z@PwPI:$cPL<@P޳wP]:$b 5l=t}}b h"h.WcPH?APwP:$cPHoAPwP:$ b ʝ=ҝ}}\ \ 7 6ACFCR˴B R B?cPu<~BPwP:$cP<BPwP:$%b u=}+}4b 4("4(`"cP՞HcCPawP:$cPHCPwP:$Jb ՞ =}>}3\ F\ (%P>C F ^WEf\fE߶ D\߶ EcP<DPWwPџ:$cPԟ<DPwP:$eb =}s}tb zg"zϷ(cPHEP7wP1:$cP4HEP_wPE:$b R=Z}}{\ \ G%>!F4H ^WXHnwnCG8F7GcP<FP-wP:$cP<GPUwP%:$b 4=<}}b o"mιcP]HGP wPq:$cPtHGP5wP:$Рb ]=}ơ}\ Ρ\ YСILHJ U3J7ߡkJFMRߡ0IHߡ0XIӺcPH<IPwP\:$cP_<OIP:wPp:$b H}=}}b x"RxcPHJPwP:$cPH4JPwPҢ:$ b ߢ=}}\ \ n8JJ 5%pyJJ %JJ QV%JXb K9QJJ,wMJ'2aLŦI\a2au2a42a~THo@ȉg'ao@ȉ]so3@YLBҼqI@# LIҼLE #L L,wBRud3SBJqIS#LIJLY#LLhwBRud,^ i?u[3 MBX?L[\ JhPJnzO2&Σzzz~@gl@]l3`/NBqIx#NIL#L;L]wBRud3/qI#uI>L#LSLwBRuG3vBqI#HvIL#LLwBRuG3vBqI#vIL#LL*wBRuG3qwB=qI#8wI=L#LRLwBRuG3wBqI#wIL#LLwBRuG35axBqI#(xIL/#LL)%wBRuG(`Mi*.\ 9Tx 8[{%  y{<y{% #{<+dǔ.X:yیK]pzʭ!ipݭKly yLLTyh=zBuPqI=#yIuPLC#LLRwBRu\izʭ%mݭKy zLL(hؗz* f39{BVqI#{IVL0#LLwBRuG3H{BqI`#x{ILx#L2LR/wBRs3)|BpqI#{IpL#LLGwBRs3ؘ|BqI#h|IL#LL_wBRs3 }B4qI8#|I4LP#LVLxwwBRs3h}BqI#X}IL#LLwBRs3 ~BqI#}IL#L L:wBRuG3~BMqI#H~IML#LbLwBRuG3~BqI#~IL#LLwBRuG3qBqI#8IL#L L9wBRuG3BLqI#ILL#LaLwBRuG35aBqI#(IL/#LLwBRuG%]Mi*&\ +H* 8*% H[W[!15_v1nv`Ev1@Tv`0Tvb[3Eq[?s7Fw̌BșځیXjʭݭKyy CLLhBqI#{IL #LLwBRu\v -ʭl ݭK8y %LL7hPa*  f3pكBqI#IL#LpL`wBRuG3QBqIؚ#IL#LLwBRs3ɄB8qI #I8L8#LZL|wBRs3PABqIh#IL#LLwBRs3BqI#IL ț#LL@wBRs31B^qI#I^L#LLwBRs3BqI#pIL"#LL1wBRuG31!BqI1#IL7#L*LWFwBRuG3F&BjqIF#`IjLL #LL[wBRuG3lBqIl#؇ILr#LLwBRuG3BqI#PIL#L)LVwBRuG3/BiqI#ȈIiL)#L~LwBRuG.jMi*d\ HNU=KmNN (X1'(|c P%] %+&bb,k(ccI, `IqI,IWI,-fI::$3:ȜBqI:#ILC#LKLwBRud3BqI#IL#LL wBRudgJ!ggPQ,`&bS`,SWI`fIKc8,ELLJOc :"Oi9] vh3vP,B^qIvp#I^L#LLwBRv+ X~qg3',BudqI'#HIudL-#Lu`L;wBRvr] 4gM^,kUk,jjNj,M X^bk Ukbj jwjb'\  IT `/я|co_~_cPPwP&O% L"OT.9] ďPgwP{=P<VPLPP 0P$P9:$g9 !ggC,$IR&bSR,`SWIRfIKU@,LLOU "O[9] hh3hX,6BqIhx#ILq#L-L\wBRu_+zX~qgz3,BqI#IL#LLwBRu_r] 4gMxp^kxUkjxj0jMΒ^u`kUku`jjju`\ rZZZՓDd|cb(cDcI ȓIDqIIDWI-fID,:$g,(!gg6,(&E&bSE,dSbWIEfIbKHH,”LLOH "ON9] [h3[`,:BqI[#ILd#L L9wBRuo+WX~qgW3,BqI#ŕIL#LLwBRuor] 4gMkt^kkUkjkj jMҖ^upkUkupjjjup\  ]ITG `/]&KF!<W|co_x~_WcPПPwPO% Ɨ"O.9] >PwP=P<VP4LPHP 20P4$P[9:$g90!gogC,R&bSR,ژSWIRfIKUP,8LWLOU -"OW[9] hh3hh,BqIh#wILq#LLwBRu_+ X~q; g 3,tBO qI#;IO L#Ld L wBRu_r] 4gMx^ kxUk jxj j MH^u`kUku`jjju`\   IT `/   |c%)g%Р!g) ge /,3 >&bS>,oS WI>fI KA,͜L L: OA œ"O G9] Th3T,EBN qIT(# IN L]@#L} L wBRuo+ X~q g 3, B qI#НI L#L LK wBRuor] 4gMd^^ kdUk^ jdj j^ Mݞ^upkUkupjjjup\ n8  ,IT `/,ITj-M X  X|co_~_ cPxP wP/ O% "O] .9] zPp wP =P<VP LP P n0P $P 9:$g9ءŢ!g gC,ڠRR&bSR,SWIRfIKU,tLLOU i"O[9] hh3h,BqIh0#ILqH#L6LewBRu_+8X~qg3,BqI#wIL#LLwBRu_r] 4gMx&^kxUkjxj9jM^u`kUku`jjju`\ ; ǣIT> `/ǣb@Bݭ''' 9dݭerf`ҭg\FLmsgjPrtMjvkjdvTddl#|ccPȢlErȢ|cb(cEcI IEqIIEWI-fIE:$&lF<|cͬcPͬ0m.)0|ccP@cPml`cVcKP|c=Hhmhm^h|ccPin%jn jdTdd&$osF< |ccP*أPwP!::$;oA T|cI)"jsg q"_g `i__k__z|h~04gMjɨ^:kUk:jjvj:3HABqI#IL`#LLhwBRu`sxv_x`L_l___*I7{שII4gMAj^*kAUk*jAj?j*3T.!BSqIT#ISLZ(#LhLiwBRu`kv|Nw^ӭjmrZm'b2w^mrZrZm bw^r\ 8L;n8c  IT' `/_@__cP `PwPO "O)9] ::$__FcP=P[wPs:$g:3!ggD,HS&bSS,SBWISfIBKVإ,L~LOV ׯ"O~\9] ih3i,ZBqIi#!ILr(#LLwBRuo+7X~qbg73,BvqI#IvL#LLwBRuor] 4gMy^kyUkjyjjM^upkUkupjjjup\ 5x#2\u'q' H`IT$ `/`4#V'$';'\uq@$0H hY$*III(^8k>@Uk"9j>Xj9j"9Mq^9kqUk9jqj9j9>gpp9M^ :kUk :jjB:j :MZ^b:kZUkb:jZjw:jb:vgzݹЯ:~ݹ:4gݹMg:Cg:30B ;qI#I ;LH#L';LI;?wBRw\  d_ `g;_{;_ _;_;zC;~C;P4gImUbom{man{mԹݹw^X\ ee./ ' '\u 5(<q 5(J<PsR1Q.,0''\u5(<q5(<PsR0Q FeIT `/eIT(09FP.`N=DE=`|co_~_E=cPPt=wP=O% ;"O=.9] P=wP==P<VP">LP6>P 0P">$PI>9:$g9!g]>g>C,>R&bSR,OS ?WIRfI ?KU,LE?Ln?OU "OE?[9] hh3h,%B?qIh8#I?LqP#L?L?wBRu_+q?X~q)@g?3,B=@qI#I=@L#LR@L@wBRu_r] 4gMx_^@kxUk@jxj@j@M^u`kUku`jjju`\  IT `/IT-(thb@@h|co_~_@cPP-AwPcAO% "OA.9] UPAwPA=P<ȱVPALPAP I0PA$PB9:$g9!gBgRBC,BR&bSR,SBWIRfIBKU,OLBL'COU D"OB[9] hh3h ,B;CqIh@#I;CLqX#LjCLCwBRu_+CX~qCgC3,BCqI#RICL#L DL8DwBRu_r] 4gMx^KDkxUkKDjxjmDjKDM_^u`kUku`jjju`\ . IT `/V IT `/~ IT% `/5 #;IT `/; VnITj `/nz IT `/ 2z'z'6' X%X%k% p G5D`BUrDO _O `D_D_R_D_Dth! EJPExE|ccPȲPPEwPE:$M^EkUk;FjjGj;FM* ^ Hk*Uk Hj*j#Hj Hgsn }_n `_7H_r__~HĻ(HHѻH H&IH|ccP׻`PHwP|I:$Mxn^IkUkIjj}KjIMA^KkAUkKjAjKjKѻg GKK)o-pIo?oL|co3onLoLB7=MK^LkK(UkMjK@jNjMMX2^NkXUkNjXjNjN-Kg aX-N#NmpOQR|ccP¼ PQwPSRҼ:$Mۼ8^sRkۼPUkRjۼhjSjRM^SkUkSjjTjSۼgs|&TNT$ DwT:T|ccPPwTwPT!:$M*е^Uk*UkXUj*jVVjXUMg^vVkUkvVjjVjvV *g@VV)oL0Io?oV0|coRHo7WosWa7=Mj`i^WkjxUkWjjjXjWM^XkUkXjjXjXLjgsFX$Y$ȶoDMY:uYȶ|ccPPMYwPY:$Mƽ^YkƽUk.Zjƽ(jZj.ZMܿ1^[kܿUk[jܿj[j[ƽgܽ@+[S[)oXIo?oq[X|copo[o[7=M3^\kUkf\jj\jf\M^]kUk]jj*]j]gs6з>]f]$C9D]:]|ccPIP]wP ^Y:$Mb ^)^kb8Ukp^jbPj^jp^M^^kUk^jj_j^Cbgxhp#_K_)oIo?oi_|coo_o_7=M^`kȸUk`jj@`j`M6[^u\k6Uku\j6jju\gzϾTT`~Ͼ`4gϾ8Mg`Cg`3ݾXGB`qIݾ#I`Lp#L`LawBRw\ z1a~Fa 4gĻ 0*6ƾϾw^(\ 3IT9 `/Oxosaea|co_~_acPPawPbO% "O#L#LUwBRu|2LI@ALsbD(bF5g(S(Lw#;LLL#;LLaL5pLI((CG (8P5I3p@BqI#ZIL#LQLwBRu~2L@ALD(F5$g(S(ňL##;LLL3#;LL aL^5pL1vzAn~4g3BB̉qI#ỈL#LLwBRu|3CB$qI #EI$L#L:LiwBRu|&b&b %mrZ0rZw^t1\ |\ .'nzJ'zJ'XKU% XKU%^} Ñrhs H5 %%z%'z&'X'% X(%%lhs/Ťrhs/Ť8 |,< ~n(00|}M(P K\( ?ȑh ?ב̊ML K\L ?ȑ ?בp M 4l'4p uu v +_ `4_H__g_{8I+ 0E<)g)X4vl)#?l M#?/MML#?LLW-Fm<c?[} cX} ~qgaL!pL9$֑֍Q0$Ro RϒHRo`9Xoco7=x<&Iޓ+" gS>v^#?^- M-#?0/MMUL.#?LLw-p(F<ݖpPcݖ chX ~qghaLpLh==֍Q$R R%Rio=oo87=soA_o`W__v __.A| ěٛ!|ccPPٛwP:$M( ^k@UkjXjjMn^kUkjj3jgzBpAg G~By4gBMgCgy3OZ B˝qIO#! I˝LT#LL wBRvh\ 3kB B+qIk # I+Lt#L]L[wBRu|30CY!BqI #!ILH#LߞLwBRu|(`<" (/851"Ia3@"BqI#!IL#LL{wBRu|2L@AL1D(F5"g(S(qL#;|"LLL#;LLՠaL.5pLF(FC+$ (y8F05#I3FP@x#BݡqIFp#>#IݡLz#LLAkwBRu~2L@AL_D(F5$g(S(L#;#LLL#;LLˢaL5pLzAq$,~[4g3B$BqI#$IL #LLϣ%wBRu|3%Cc%BqI% #)%IL.#LL'@wBRu|M&bb&bm!rZ.07rZBw^Oa\ i\ //R&zQ'zQ'XR% XR%a&& %%R& b&'a&&$:u'w&McPU'PYwPi:$cPlB'PvwP}:$/^c U=}}tc \ +'' %%'u=','($('cPQG(PʤwPb:$cPew(PwPv:$0^c N=}}DM*D 7)2727 E7~*EEEx gp_ ]qp3 BqI#)IL8#LLwBRud"1<,BQ6m   Mֲ̲\ DD,Dw#+¦#¦# E#~*EEVxgզ_]qզ3BqI#+IL #LLDwBRuc""1w",BW6S"& s&M̲sֲ/\ tc =\ !0IE%EV76)7%end7%v8: P 09%eh9[-eاeا7Q-.IC%D%qE%GeoF-eeevF-eea~F!.ku~~gcP:].PwP:$cP;.PܨwP:$cP;.PwP :$cP8=.P*wPL:$cPO>!/PbwP`:$cPt>U/PzwP:$cP?/PwPȩ:$==cP}8o===cP}}}\ \ X_$=00  e M0ee ,4001 lH=0.aT1bYbY1i'qapS1bbӪ e M1ee,P,m,!m3%str3|:end*lN%Q242O$F3 %fS2SI6IqIIWI-fI3 "_ :=1IV3%%c%os&7ucX;%%c%os&70M;ءcP 3PwP:$#3H8J3@3lcP8>4PɭwPH:$cPq4PwP :$cP 4PwP7:$cP 4PJwPb:$cP  5PuwP :$cP0 =5PwP@:$cPP p5PˮwP`:$cPp 5PwP:$cP 5P!wP9:$cP  6PLwPd:$j(6uwb6(ccCI 6IqIIWI-fI:$3*7BqI#6IL#LLwBR[3#7BqI##h7IL)#L6LpwBR`P7PP:$3K8ḆqI#8I̱L%#LL4wBR[348B!qI4#8I!L:#L5LJw(MicPP 9P]wP`:$:$D:$:$cP`HS9P wPTp:$_:$cP9PwP:$cP}h9PwP:$b@:(ccI 5:IqIIWI-fI:$3:B&qI#~:I&L#L;LhwBR[3L.;B{qIL#:I{LR#LLawBR[y=h=}w(J\ ;c%os&7V3;%%c%os&7kC%%c%os&7CءcP ]<PwP״:$;?A;;;cP@<PAwPYP:$cP<PlwP:$cP=PwP:$cP Q=P¶wPڶ:$cP =PwP :$cP0 =PwP0@:$cPP =PCwP[`:$cPp >PnwP:$cP P>PwP:$cP >PķwPܷ:$j>ub -?(c]cI "?I]qII]WI-fI]:$3@?BqI`#k?ILx#L,LfwBR[3(@BqI(#?IL.#LL޹wBR`PN@PP':$3'@B:qI'#@I:L-#LOL|<wBR[3<*ABqI<#AILB#LLw(MicPXِAP˺wP#h:$:$I:$ :$cPhAPzwP»x:$d:$cPBPwP:$cP3BP-wPU:$b B(ccI BIqIIWI-fI:$3@1CBqIX#BIL#LLּwBR[3TCBqIT#oCILZ#LLiwBR[=m=w(R\ Dc%&os&7;2/G$%$%c$%os&7p$GءEcP רDPwPy:$cP(DPwPƽ::$cPPEPwP`:$cPyGEP=wPU:$cP}EPwPh:$bF(ccI EIqIIWI-fI:$3{FBqI#BFIL#LL޾wBRuc3FBudqI#FIudL#LLwBRuc({GPvRsi=w(\ ^}Gwc$%os&7DPGG p}G`KGSHGG3HHB1qI#HI1L(#LOLIwBRo-\ ZeHzH 9%SHo8AHLeH@gI}G@GֿG3$`[IBqI$#"IIL)x#LL*wBRuw=\ @/JH}G@GwGH3G#JBqIG#IILL#LLwBRuw\\ 3_JBqI_#nJILe#L LGwBRuw3lKBuqIl #JIuLq8#LLwBRuwPIK}GhsK}G3KB-qI#KI-L#LBLowBRuw3cLBqI#*LIL#LLwBRuwJ\ ,JxLITxS9LL @%LU@LLRLTX)d gM|q|X)(}}|Lb L5ozHw\ b 9NS Sxa lx6 ME[O\ b O,;QE /Q̬ M۬/Q\ b Od}GGGd3OBqI#OIL#LLwBRug\ 3b KPBqI #PIL(#LFLwBRug'b Q '--a1 lx61 ME[O:\ =b Q=,C;Q/EQCG d̬G M۬dP\ V@b Rd}G3d(b RBqIdX#XRILgp#LLwBRugJ$J\ LbRRLL\ SITxS@&SITxSV@t5SJS lH%&S9fSa5Sv^ Tvv!v^(vvvSR RLTLL\ &JT'&J(֛ɛVS0 S*K0T9K9\ :TIss>s^bVmuffffVVf0 kUYda 3UBlqI#UIlL(#LLuwBRud3BqI#VIL#LL wBRud\ @V6 6 7\ S$X+YSxWSl$ 0+Wml$$ll%Gm' 1mWVml'6l}l-mJ 0r] Skr] {\ \ \  lI_Tp999:99D99/@G ̒l m e__n__s'C`h%mt eGՌ)__xGtnQ9SY} Lmm}q}y}} M,}qB}6}3S"3;.!"y3_"@}l3Vlll"l`]^ hC^`0=``YWaoblh_olc llVl]eh ko)e)eCqc*oW`o>1(a;p!+(Mr] Y} ipm}}y}H} M,}B}6}H5@rirukh[@0.*k@0k@J@0~ksg@0]<k/"@kW@k~@ @9k,@H;^ 5Xy4tuhA[aX0.*AaX0AaXJX0~sAgaX0]</A"aXAaWXA~aX X9,AaXH^ ,;QE 4̬ M۬4\ :5*uI_Tp%9':9'D9|:/@G ߜ9unu e__n__s'Csfu:} eGG__xG:}xwQ%|(~ L2v<~T~H~} M}~~/S1+$\/+\\/_+\t/V u+t\tuU^ bC^s0=`s YWaRobp*ub_wPuc Cu9uV_uebweeCgcwWyz`xax?hMh{r] (~ ix<~T~H~} M}~~rz,B0.uh,0&,4X0~,j0],\OB,, Xp,x2^  y|B 0.uh 0& 4! 0~j 0] \OB   !p  A^ wa lx6 ME[O\ :N}f} e__xf}d:2z}} e__x}:;!}" @|w 9?}Hx d~X}1N}^Y} Y~m}}y}} M,}B}6}r me6y ~eek}>hy }z}Y(~G<~T~H~}GM}~~nu^nI_Tp;9B:9BD9B/@G } !f__n__s'Cxh~ MfG__xG~cQ;\ Lvp,J|_  M/,EJ9_3Sr3r?3_rsf"3VPrC6_]^ hC^x0=`xAYWaobnh_7c }Vfh ffCqcρW`] BajMr] \ iCp|  M/E9!rna&TPGn0. &Pnx0&Pn60~k&_PSn0](&Pn&Pn&PnF&9P,nU;^ !(yنnaTG(0. x(0(:6(0~k_S(0]((((:(F9,(UZ^ ds}/ :RF M)\ B 8rWrL;L;Ї DWDL;L; 87(@ Mf__x@C] lHH?_SˈSI6Ihpos5LBLf5L+LLBL5L +L3[NN[tN jN3ICI3b$$ f0s!ڇ)Ї3!EBqI#YIL#LLwBRud3E B)qI#ъI)L #L>LkwBRudHW_i_sGx~b8sy`* $f3xBMqI#ًIML#LkL wBRu`3BqI#QIL#LLwBRu`w}ns׌nSnlnbn-r] \ Iύe)[R" ;1| 2(\ pVk|  M/VEk9I3GBqI#IL0#LL/wBRs3HBqI#IL`#L1LSwBRs3d 7BqqId#IqLj#LLywBRuV3BqI#vIL#LLwBRuVr] "] ^ \ \ 1"0G1;7x| 2S(\? p| ? M/E9rI GҐ[e" ;1)| 2a(\ p|  M/E9swՒʒ 'Ie ['" ;E1c| 2(\ p&|;  M/E&9;Bkey%-key%X<T lHG- PWp<FV Nz} ғ }:@:p:cPu[PwP:$cPuPwP :$c =%}{}ՒLtcPDPwP:$cPtPwP-:$c :=E}{}87:p::mcPu(PwP:$cPuXPwP:$lc =}a}?Nb}qYhs#s}s&}1@m m}m<&}K-Zi- .i٠-i-}ɠie ٘~t*6 N#hTMZ%Z 5 X@cPEЙPwPV:$cPYP0wPj:$hc By=}D}2|AH|H|}H%ɋO <ڋ3O ;BqIO#ILU#LLdwBRuO:Isss^`m-uf̛\r ra lx6 ME[O\ p[ f~1rO0 M?U1IO\ Bbb(xα ٱ Mȱ\ Lr] r] sm\ J#1( G!T͞ҟ:x::cPu5P7wP):$cP,uePOwP=:$c J=U}k}r] Ts\ ~\ \ 0Y=r^ $c &N=^ c ,\ 0MB60g0H3TS9SWI9fITF/#TTQ] h 3=@ϡB\qI=#I\LC#LqLRwBR\|5MBqI8#ILP#L L (wBR\fx  SS WIfI .  5Lg[ [_[2 SNS2 WIfI2 hJ  58 a SES8 Sa vSJS8 Sa ɋڋ 3;B qI#xI L(#LL%wBRvɋ3(EڋC33@;BeqI3# IeL9X#LLWwBRv3DpBqID#ILJ#LLgwBRvɋUPڋ;3U;B;qIU#I;L[#L]L{wwBRv3fȦBqIf#ILl#LLwBRvz Sz(SIz6Iɋ0ڋh3H;BhqI#yIhL`#L{LwBRvSSWIfIxwڋ3;BqI#=IL#LMLwBRT3BqI#IL#LL wBRɋڋ(30;B(qIH#JI(L#L=LP/wBRvM`5c3L@$B\qIL#I\LR#LoLawBR`^f5Lu[[u_[SuNSWIufIxYD3 @HBxqI#IxL#LLwBR`5ɋڋ3;BqI#IL#L7LqwBRLɋڋ3(;BqI#EIL@#LLwBRv3XB!qI#I!Lp#LPLywBRvɋڋ3;BqI#PIL#LLwBRv3BqI#ɭIL#L L3hB0qI#/I0L#LELrwBRLɋڋ3;BqI#IL#LL(wBRL3($sBqI(#:IL.#LL=wBRLɋiڋ/3i;B/qIi#̯I/Lo#LBLo~wBRLɋ~ ڋ3~ ;BqI~#_IL#LLwBRLɋ,ڋ3;BqI#IL#LLwBRvɋڋ3;BqI#IL#L#L6wBRv37BIqI#IIL#L^LqwBRvɋʲڋ3;BqI#IL#LLwBRv3 0BqI# IL#LLɋ(ijڋ3(;BqI#IL"#LL>wBRɋ#WڋQ3#;BQqI##IQL)#LfLy7wBRvR/ȴBqIR#ILX)#LLkwBR\Tڋ3;BqI#IL#LL!wBRT2ŵB4qI#I4L,#LGLtwBRTs0[XSMn0DF\ &+t0t'Ex8 + #z(0+z'GxP*cG%XX]0q]x-BtT0= La a>tDWKn-bEc d *d ^ Gd  _ ^ *d ^ 1fd8%9J:J;;%^G%3] ]%}k?%Y.<Zd 2]L A]K]/%%Cb amda 3uBqI #;IL#LLwBR}3BqI #IL#LL,wBR}3,gB1qI, #-I1L5#LGLvGwBR}3GBqIG #ILP#LLbwBR}3b&YBqIb #ILk#LL&wBR}3+ҼB9qI #I9L"#LOL~wBR}3KBqI #IL#LL wBR}3 =ĽBqI #IL)4#LL( ?wBR}]_ i*)=Ccs]uO]; ]O b(۾(cd cz I оId qIId WI-fId :$3@SB qIX#I L#L L wBRw2] }A] K] p pȸ}ո};! >o!!""/Zd l"bI(c"c"I I"qII"WI-fI":$3IB"qI#I"L#L"L3#bwBR}3#IBQ#qI #VIQ#L#Lg#L#wBR}dmcPcP=cP}}E #&bb(E(c#cI I#qII#WI-fI#,:$34@E B#qI4X#I#L@#L$L($RwBRv3uEB;$qIu #JI;$L~#LQ$L$wBR}M&J^$k&Uk$j&j$j$`N@p$v$N|ccPpP$wP$Oc"O$^:$M5J^$k5Uk$j5j%j$H_ 4}r}2]f /A])%K]=%P cPQ%Pd%<2] A]w%K]%3$B%qI #I%L#L%L%wBR}%_ ]mrcP}cPcPcP}}}\ _ \ e` ]Jpmxm'm%%D&6&b 3OBJ&qIO#IJ&LU#L_&L&dwBR3d6B&qId#I&Lj#L&L&ywBR3yB&qIy#uI&L#L 'L:'wBR3(BM'qI#IM'L#Lb'L'wBR3B'qI#gI'L#L'L'wBR3B'qI#I'L#L(L?(wBR3BR(qI#YIR(L#Lg(L(wBR3C B(qI#I(L=#L(L(wBR_ i*%6GMcGd \ 0Q ^F%%&%)36 &WB)qI6#I)L<#L3)Lb)KwBR3V&Bu)qIV#Iu)L\#L)L)kwBR3k&IB)qIk#I)Lq#L)L*wBR3&B!*qI#I!*L#L6*Le*wBR3&;Bx*qI#Ix*L#L*L*wBR3&B*qI#zI*L#L*L+wBR3&-B&+qI#I&+L#L;+Lj+wBR39&B}+qI#lI}+L3#L+L+wBRm_ zd i* .4c\';\+]+\T\ D`u ]%\j\un  -j,Q `,3vLB1,qI#I1,L#LF,Ls,wBRuF3vB,qI#I,L#L,L,wBRuF3v<B,qI#I,L#L,L-wBRuF3vB0-qI#{I0-L#LE-Lr-wBRuF3v,B-qI#I-L #L-L-wBRuF3vB-qI#kI-L #L-L./wBRuF3/-vB/.qI/#I/.L5'#LD.LY.CwBRv<iJ\m}*cL\ 0\uB  8djl.Q 8`l.3vLB.qI#I.L#L.L.wBRuF3vB.qI#I.L#L/L./wBRuF3v<BA/qI#IA/L#LV/L/wBRuF3vB/qI#{I/L#L/L/wBRuF3v,B/qI#I/L #L0L-0wBRuF3vB@0qI#kI@0L #LU0L0/wBRuF3/-vB0qI/#I0L5'#L0L0CwBRv<iJ\m}*cL\ \thn\ P-n0  P-0Q P`03vgB 1qI#.I 1L#L51Lb1wBRuF3vBu1qI#Iu1L#L1L1wBRuF3vWB1qI#I1L#L1L 2wBRuF3vB2qI#I2L#L42La2wBRuF3vGBt2qI#It2L#L2L2&wBRuF3&vB2qI&#I2L,#L2L 3;wBRuF3;-v7B3qI;#I3LA'#L33LH3OwBRvHiVhy*c!\ X\ 0ahB0 hdB[3  hd[3Q h`[33vB3qI#TI3L#L3L3wBRuF3vB3qI#I3L#L4L@4wBRuF3v}BS4qI#DIS4L#Lh4L4wBRuF3vB4qI#I4L#L4L4wBRuF3vmB4qI#4I4L#L5L?5&wBRuF3&vBR5qI&#IR5L,#Lg5L5;wBRuF3;-v]B5qI;#$I5LA'#L5L5OwBRvHiVhy*c!\ X\ զ 6P9+Mb P@%03TSButqIT#IutLZ#L5L6iwBRusJRcr\ 8ND$620Y'a Y1Z' Z% ZG[0[C6aab6N e*75#<XJ6d*9o*}*XQ% qx g6 |ccP(8Px wP6;:$;X[7R7X|ccPAxP7wP7Q:$OQo7e8|ccPWP7wPd8g:$&g'F8<8|ccPmP8wP9}:$}ލ99q9|ccP8P99wP9:$X9&bMx^K:kUkK:jj:jK:MZv^:kZUk:jZj:j:%b9 (c:cI I:qII:WI-fI::$39B<qI#II<L#Li>L>_wBRv (?(>vS @dS>S?-3-X?JBg@qI-x#Ig@L6#LALmBPwBRT A@jUO U Ha^ N%B_ da $i8M`q*c]O:]B]BVZ0aVaB[ -[C[CZ%GC3VZ4BeCqIV#IeCL\#L{CLCkwBR3k ZBCqIk#sICLq#LCLDwBR3Z&BDqI#IDL#L)DLXDwBR3ZBkDqI#eIkDL#LDLDwBR3ZBDqI#IDL#LDLEwBR3$ZBEqI#WIEL#L.EL]EwBR3Z BpEqI#IpEL#LELEwBR33'ZBEqI3#IIEL9!#LEL FHwBR_ da i*0>Dcs][]F];F& \B? OF5 cF]tLl]F]G3KB)GqI#I)GL#L>GLmGwBR3K^BGqI#$IGL #LGLGwBR3KBGqI#IGL!#LGLH0wBR30KPB,HqI0#I,HL6#LAHLpHEwBR3EKBHqIE#IHLK#LHLHZwBR3ZKBBHqIZ#IHL`#LHLIowBR3o!KB2IqIo#I2ILu#LGILvIwBR3 ?3BIqI#IIL#LILI,wBRT}d  fd i*ci*c}\ , T0'a 1'  %GlHITI%@0=!LIaa0JM P]\ FJ7VPFVYJ>h(nJvS>dSnJSJK3K%BJqIK#IJLT#LJLKwBRuG3_B:KqI_#dI:KLe#LiKLKwBRs3pBKqIp#IKLv0#LKLLwBRs3HB2LqI#TI2LL`#LaLLLwBRs3xBLqI#ILL#LLLLwBRs3kBMqI#DIML #L%ML:M$d WdMMJdyM$dWdMJdM$dWd'NJdoN/ BD N N NB0NNNBNNNJ(OvSdSOS3O3mB[OqI(#4I[OL@#LyOLOwBRu\3(BOqI#IOL"#LOLOwBRs P O P *P >P RPXh*P>PRPp*P>PRP3BPqI#IPL#LPLPwBRu\3"BPqI#NIPL#LPL!QwBRu\3)B4QqI)#I4QL/#LIQLvQ>wBRuG3BwBQqIB#>IQLH#LQLQWwBRuG3[BQqI[#IQLa#LQL RpwBRuG3tgB3RqIt#.I3RLz#LHRLuRwBRuG3BRqI#IRL#LRLRwBRuG3WBudqI#IudL#LRL SwBRuGiiMi -*>@r] Mir] \ \ %\   > U3 Q> S0jS}%S3BSqI#ISL#LSL TwBR3<B3TqI#I3TL#LFTLuTwBR3BTqI#{ITL#LTLTwBR3.BTqI#ITL#LTL!UwBR3B4UqI#mI4UL#LIULxU wBR3  BUqI #IUL#LULUwBR3BUqI#_IUL%#LUL&V4wBR34B9VqI4#I9VL:#LNVL}VMwBR_ da i 2ER*evcL[V[_[VSNSVWIfIV3hBVqI#/IVL#LVL WwBRL3BWqI#IWL#L0WL]WwBRL3XBpWqI#IpWL#LWLWwBRL3BWqI#IWL#LWLXwBRL3 HBXqI#IXL#L-XLZXwBRL3BmXqI#ImXL #LXLXwBRD38BXqI#IXL#LXLY-wBRD3-BYqI-#wIYL3#L*YLWYBwBRD3B(BjYqIB#IjYLH#LYLYWwBRD3WBYqIW#gIYL]#LYLZlwBRD3l BZqIl#IZLr#L)ZLVZwBRD3  BiZqI#W IiZL#L|ZLZwBRD0d 'd /mJZkz*cm*c\ C vm3  we  E O (u O ZE ZI("eZ[Z"@ ;Z1[X| 2M[([\ g p[[|[  M/[E[9[BP8  lHx3\$da Wd Jd\nS3 Sx\WIfIx\|[S [\3 B\qI# I\L#L\L]8wBRuo3C B4]qI(# I4]LH#LV]Lx] wBRut &]]$d Wd]Jd]3?B]qI?# I]LE#L]L^TwBRuo3mB^qIm#TI^Ls#L-^LZ^wBRuoa[XYr] 3 "] ^ j\ ]\ 1:I_TpV@9\@:9\@D9P@/@G ħI~ 2__n__s'CXhJ G͡m^__xGJ`/QV@^ LB^&^^ M^^^_ 3xS ^ )_| f_3xI^<)_/f_3x_^)_f_x_3xV^)_f_x+_]^ hC^X0=`X_YWa`ob9`:h_`c SIVo`h CqcW `)  ` a/`9aMa/ar]  iCa&aaa MCaaaarL ? a2 a% a0.aaaV0aasab0~Ia=a1a0]aaaaaa!baUaHaqbaaa5b;^ yL ? [b2 b% b0.[bbbV0[bbsbb0~I[b=b1b0][bbb[bbb!b[bUbHbqb[bbbb^  c(c7cα ٱJc]cxc MJcȱ]cxc\ m@^v __xv@'Se GenvV@cOHhc^c =?d&Udjd M?dUdjd~  }dI_Tp@9@:9@D9@/@G  ga__n>__s'Ch   aGd__xG 8Q@d LƂeނe҂3ev Mee3e#3PS#Fe#te#e}3PFetee3P_=Fe0te#ePLee3PVFeteyePe]^ hC^0=`fYWaޭZfobޭfhh_zc Vhfah SbbCqcW7`aTga#>glwggAMPggfzgZr]  iƂgނg҂gv Mggg*#rQw#j#g]#$hP#Bh"0.##g#$h"Bh"0"g"$h"Bh"`h?"0~t"gh"$h\"Bh!0]1"g$"$h"Bh!!g!$h!BhL!!g!$hs!Bh!`h!.!g!!$h!Bh=!h;^ *#y w#j#h]#hP#h"0.##h#h"h"0"h"h"h"i?"0~t"hh"h\"h!0]1"h$"h"h!!h!h!hL!!h!hs!h!i!.!h!!h!h=!.i^ Tigii[ fi~iri0 M?iUiIi\ A$"IT*7_")!Ii?icP u!P%jwP8jO j!"O%j)9] ::$(Ihj?|jcP:@PjwPj:$=`!I&bMIxE"^jkIUkjjIjjjjM"^utkUkutjjjut\ D#I_Tp*9C:9CD95/@G #L# C__n*__s'Chd#+ IjGk__xG+$Q*,k L$JkÃhk}k[ MjJkhkt}k'3S'k'k'k`3kkk3_ kkk/l"3V"k"k"k"9l]^ hC^0=`_lYWalobl#h_%.#c !##V=#6m)h %88Cqci%W'`%((`mx(az&m(OZmf$M3mIm=r]  i&mÃm!n[ Mjmmt!nB'@r(''Dnu'nnh'n&@0.7'*'Dn'nn'n&@0&Dn&nn&n@&nW&@0~&Dn&nnt&n&@0]I&Dn<&nn/&n%@&Dn%nn%nd%@%Dn%nn%n@%n%@F%Dn9%nn,%n@U%n;^ B'Xys*''nu'oh':o&X0.7'*'n'o':o&X0&n&o&:oX&XoW&X0~&n&ot&:o&X0]I&n<&o/&:o%X&n%o%:od%X%n%o%:oX%Xo%XF%n9%o,%:oXU%xo^ oooU `oxol p* M9oOoC p\ Dt5+N, Ijo p__xoN, x__nrJp"r+1ppu$uppu'r+((B+PvB,pÃpp[PMjpptp4L#`D_k,- pu__x)p__y))--qKq )P-uqqC )NfqZq M'=q1q#\ 6")q36" BqqI6#-IqL9#LLqRwBRo6S,l-L. B1L.6KC__r%אi.2 __k)2__j)r().#r@)c0NryrrryC")rss.C"@sasTs-C" .s-sC".Fs#.es0.=.sICX/IsqICIsWIC-fIsNFp30sfsYs]d Syz$)1rst.z$@sasTt-z$ .s-tz$.t#.)t0.=.__p)p>__v)p2)s$__z)wא2a: pu__v)a:V:)oGt2)I6128u'2Xu@2xuM2uZ2ug21v()3Tvy>@) 5vvv.>@@savTv->@ .v-v@. w#.w0.=.=wI>4IvqI>XIvWI>X-fIvNNp4sf[wYw^d ^y)!6www.@sawTw- .w-w.w#.w0.=.xN5sf1xY]xd `.)ox$  )u6   x{2)-:2x2x2y27y2Wy2y *)t8yyy. *@sayTy- * .y-y *.y#.z0.=.$zI 7IyqI IyWI -fIyI(#8IBzqIIBzWI-fIBzN@]8sfjzY}z/d %XX =p)w!:  zp  =):9 [ =)f r z0 =MI z? U zGr] r] I)V9ڃO)9{@{[):C)NfZM'=1\ e 'e -e p$ s)   ^{\ אD3;%A \QyIR{:R}{R{cPH{:P{wP\:$Hd}y9e \e }\ C/*@IT,/&O*@@ss&P ~8&PC=I+{ h;+|gp<s|v|#?<| M#?M</MM|L`#?LLE}-(=F[}<}Hc<};S c}XS ~qo~g}aLx,=pL~bb`&Q{>~~Xb`&j~w~`.b`&9~F~b`&X~~b`&x~~Eb`&R~`|&nb`&nqn~y={x&R>((&R@ (85}?I3@[?B#qI#!?I#L#LULSwBRu~2L@ALD( 5?g(S(ɀL8#;?LLLP#;LLaLp5pL54\ \ EpzCZ'['\ ]f@Y/3;%f#A܁ % ;3;3PfABRqIP#bAIRLY#LLwBRu_3`fBBׂqI`#AIׂLf #LL5wBRv _uB_ `S_g___3 fBBqI#BIL#LЃLwBRu_3feCBu`qI#,CIu`L#LL=wBRu_PO\ 0\Kz{'z{'X{ X{, {0D_, `P_d_/_w_H8{DÄH8Ä[3;NP{Du NP g3;sq {3E_q `7_W_u__h{FӅE8|ccPPwPc:$M$F^kUkjjjMF^kUkjjjg0{HP%F=. *GNfD~ |ccP 8PfwP:$M$PG^k$hUkj$jćjMG^؇kUk؇jjj؇$gzP{H~P4gPMg+Cg3ZHB?qIZ#HI?L_#L]LwBRvo\ 3r({]IBqIr#$IILx@#LLLjwBRu`3!{IBqI#IIL#LL'wBRu`z {J:~ g4g3{JBqIX#ZJILp#LL։wBRu`3 { KBqI#JIL#LL+wBRu`rZGrZPw^\ 0C:Sz~'z~'X~ X~\~L>o\oo3;b~PLĊb{3;s ~L_ `"_Z___~N"ZBMo|ccPPowP:$MM^ k UkFj8jjFMN^kUkjj׍jg0 P~}OPF#.pNNLDp|ccPPLwP/:$M8 O^͎k8Uk͎j8jj͎M^hO^u\k^Uku\j^jju\8gzd~aP ~d-4gd(MgOCg-3nHTPBoqIn#PIoLs`#LLwBRv\ 3x~PB͏qI#PI͏L#LLwBRu`3~QQB/qI#QI/L#LDLqwBRu` ~Q_ `____z ~QԐ~ 4g3~qRB.qI#8RI.L!#LCLp6wBRu`36(~RBqI6#RIL<"#LLőKwBRu` rZ[rZdw^T\ C[z'z'X XSؑ  3;.T^3;s T_ `___H_U( U A(|ccP@P wP:$M!XU^k!pUkj!j0jMNU^\kNUk\jNjqj\!g0\[WPF.iVND|ccPoPwPG:$MV^gkUkgj jjgMFW^u\kUku\jjju\igz8?X~Xǖ4gxMgCgǖ32XB qI#WI L#L'LIGwBRv\ 3XBgqI#~XIgL#LL8wBRu`3/YBɗqI#XIɗL#LޗL wBRu` Y_ `_2__E_Yza Yn~a n4g3nOZBȘqIn#ZIȘLq#LݘL wBRu`3(ZBqI#ZIL"#L2L_wBRu`FS\rZrZw^\  Cbz'z'X X([r( 3; @ \ @ 3;s%  n\_%  `V__) __B X]VP x\ۛx|ccPV PwP f :$Mq _]^@kq Ukzjq jʜjzM ]^k Ukj j jP q g0 9_PFW. e^ND|ccP (PwP :$M @^^k XUkj pjjM $_^u\k Uku\j jju\  gz `?~ a4g MgCga3 `BqI #_IL #LL wBRv# \ 3& `BqI& #\`IL, 0#L#LE wBRu`33  aBcqI3 #`IcL9 #LxLH wBRu`R  oa_R  `_̟_U _ߟ_z  a~  5 4g3 -bBbqI H#aIbL `#LwL wBRu`3 (bBqI #lbIL "#L̠L wBRu`6 B    rZ rZ w^ \ I Cjz'z'X XL xc =L x=_ 3;R cR k 3;su  Ld_u  `_(_y _|_ e( d=u|ccP P=wP :$M =e^ڣk Ukj (jdjM e^k Ukj jj  g0 @gPF. `CfNDR`|ccP xPwP{ :$M( f^k( Ukj( jjMN g^u\kN Uku\jN jju\ ( gzT g٥~T 4gT MgCg3^ 8gB=qI^ #gI=Lc P#L[L} wBRvs \ 3v hshBqIv #:hIL| #LLߦ wBRu`3 hBqI #hIL #LL? wBRu`  Mi_  `R_f_ _y_z  i~  ϧ 4g3  jBqI #iIL #LL>& wBRu`3& (jBQqI& #JjIQL, "#LfL; wBRu`     rZK rZT w^D \ !Eo_fSr. pfS: pfS q. <? tN  tvkxjk k0 |k0 ,6,`0 c-a a<C rl=C ,6,=`C c-a= aOV l2V ,6Ƭ,`V c-a abp xnmEp ,6I,`p c-a a{0 zmΓH ~mΓ=` mΓe In ,6,` c-a aȯ  hnΓ n ! ,64,!` c-a! aG" oΓs% % ,6,`% c-a aư0!o!% L o oאא"lw_Br/ pB: pB q/ <x? t  t[pooë8 |;q6۫o8,ooޱI8 pIޱqI8IޱWI8-fIޱN s2fEYXd ë@ rk۫o@,oײoI@ qIqI@IWI@-fIN s3fFYYd ëH rl۫oH,oسoIH rIqIHIWIH-fIN s4fGYZd ë_ xsmִ۫o_,ooI_ sIqI_IWI_-fINg syfYrd I zsXI ~tXڵI 8tXë@ u*۫Lo@,otoI@ tIqI@IWI@-fIN sfŶYضd IG 7uXëJ v۫oJ,o0oDIJ uIDqIJIDWIJ-fIDNQ sWfjY}\d ëy Ow۫oy,oٷoIy( vIqIyHIWIyH-fII}` wIqI}IWI}-fIN s,f?YRd I XeS0wwRk -v,kV"x"{_kr/ pk: pk q/ <x? t}7  t=xawTwlw0 xxww 2,$ظC] lwN |xww  Q,$Uhb] lwm 9yww p,$ι] lw" yww ,$ ] lw yww; ,$Na] y ztlw Tzww ,$] y szźlw zwwݺ ,$.] yP zzyh ~{>yp f"g{{%kr k: k 0{r,"{Rkr/ k: k /{ | ao__xo |__nrbAX|7| a__x7|bAp |T|l lHM'թN'WO ?YPW[R:Z@XE$ T|^$T$) # (T>}#Ҽs (6tXs# T}#$s $ts"{ @TcY{HL{ٿ?{ci p }iHi g{  {{?i ,1~i?i  ,~ pi ,iip 2 ,D3 2BFqI  #~IFL 8#LLqwBRs2,Du`32Bu`qI#mIu`L#LLwBRud{ P {{{  'Ji  ,iiJ h ՀМ2,D32BqI#IL#L LmwBRvw  М2 ,D30 2BqI#TILH #LQL'wBRs2)`  #D3)x 2BqI) #IL/ #LMLoGwBRs2Q D3Q2BqIQ#}ILW#LLfwBRuO М2,D32BqI#'IL#LL wBRv2: TD3: 2BqI: #IL@ #LALcgwBRs3K ToBqIK8 #6ILQP #LLwBRs3h _BqI #IL #LL[wBRu\$ f  %y%{ f{{{- {[: vƂނ҂v: M| iU)|| JƂ/ނG҂\v M/G\eleoeok} l}z}(~ <~T~,H~A}M}~,~A5nu2fTDc3f2BcqIf#pIcLl#LxL{wBRuO3{&T"BqI{#IL #LLwBRuO zr] cpY\ \ \ { lHW?Y|9rώ'3'թ'C' xW?Yd90 |9 3AP ԉBAqIAp #IALJ #LLXwBRu_3U LBqIU#IL[ #L'LpGwBRvf lk0lq {= qSqoSIq6I`{ x`Fn`{|?}`oS}SWIfIS ыSSvS( JSSɋH dڋ33h ;B3qI #*I3L #LULwgwBRw SoSI6IɋNڋ3;BqI#IL#LLwBRw<|}"cP!cP)}w}3BqI#ލIL#LL<wBRu_3$BOqI#VIOL#LdLwBRu_ (r] Ah\ \ \ Q2   ,#/($   #$/{3 %-3 -vMAC %ҹŹ)cOC O]{OnO)0OPi]UOHO;O[fe Ns gNNNK%N{N^( %%NN6NSNWJJN׃NNws"# C4 a@ #np000/6TX]6Xh 7ʭPGh ݭK  y /LPLsh SsS%WIfI% ʭQz ݭK& y LLHO& "O.9] 9hwBuXqI#>IuXL#LLwBRu`&39 BqI9#ILB#LLwBRu`SM3S WIMfI TS0g#TQTa] hXh~qg5oXo~qgֺHߕ"`%巕"`K`y"l_`X%~qg^vSxS^S3BqI#RIL#L*LYwBRuWvSSwS37BqI(#IL@#LL>(wBRuWSS\I6I\qII\WI-fI\SS~WIfI~3X_BqIx#&IL #LLowBRs3טBqI#IL#LL9wBRs3OBWqI#IWL# #LyLwBRsq^ ^^ 3Oq^8-^^83O }!"O9] Oq^P^J^bP3JbO3/BqI/#ƚIL5#LL3IeBqII#,ILO#LL^wBRuW3^ݛBqI^#ILd#L)LVswBRuW3sUBiqIs#IiLy#L~LwBRu`3͜BqI#IL#LLwBRu`pYMpYE\ 1118eL lHagͶhAh"j"S]q%^"r%,is'asȝb}b}[t@uL jx'Vedx+)e)e(|y9az\F\<}$$q$YlK$yʞYHrh 3`lB)qI#3I)L#LKLmwBRu_3BudqI#IudL$#LL3wBRu_pY/2apYYjv4rh3BqI#sIL#LCLrwBRud3 $BqI#IL#LLwBRuda\ 13@g-B3'40*IN4¡II`%y>K`y>l_mXm%~qg"\ str )'& *' str '& ';.3M#W W.4' .4%2.4'@Lއ.5@[$.<R].=HŮ.`\T 8.: vS.+Se  #.=X #/y#)ZP)irhѫk.>'/F3.@\FDe.F$p.@¢ѢT *#T,T] ֺ& +&%嶥&K&yl_&3X9%~q8gK < .A ^ MQ.\.Bv|ccP_PvwPr:$r.BA|cbr(ccIr 4IqIrIWIr-fI:$=8.B]S-8|ccPPPwPC:$3h.V BcqI#IcL#LL .Tr9 Q|ccPP9wPg:$8#it.GhH .HʨW /X. (.G= 1$$d;.JWdJdG N(.Qc 2 E( _23s .CBLs #LL{wBRD$@.SDr:@|ccPXPrwP:$x.SҪx|cb(ccI ŪIqIIWI-fI:$3V.VBqIV# IL\#L$LQkwBRD>.>d>wT #TTd] S #Se 'it.XhH .Y)W ./X.. .XR= F$ .[ ^ |'Q.3'.[BqI'0#ìIL*H#LLwBRwA.\fCA|ccPDhPwPgW:$_].\____cPqcPq.\ |ccPwPwP:$.`P&b.a&CT$d WdCJdT3.` BkqI#IkL#LL"wBRw.=d-&/Z5S,M.hį^kUkjj j&.=- &&/Z5 5S,M5!.hh^Mk5!UkMj5!jcjM3s.`߰BwqIs#IwLy#LLwBR@S.cSWIfI3.cBqI0#XIL#LL wBR@ _.e^ 3.c#BWqI#IWL#LLLwBR@Bc ^ T\ 61!*,*_H;*PJ*U*Thڲ#T@T ] ֺ()c(%)cK(y)lc_53FBqIF#³ILL#LLwBRuf3rBqI#2IL#LLwBPvtRufFދދދ\ ]C^$%#|:$,.i%9[[[+M_\F\arg0cS5nSWI5fIR*jB%$dLWdJd$dLWd#Jd;$dM(WdJd$dM\WdJd &3ԶB:qI(#I:LH#L\L~wBRuc3?LBudqI?#IudLE#LLTwBRuc5~zpPuds2$v"K+++-K+i++;+Yw+45Pwa]\  X   %~^%#|:$5`i%[[[+M_\F\arg0S7\S1WI7fI1V&zjB%S$dLWdfJd$dLWdJd$dMWd=JdU.$d5MJWdJdF3ºBqI#IL#LL#wBRuc3`:BudqI`#IudLf#LALnuwBRuc7 O+++5U+u++5U+u+U5PuTa~\  F0`  5#-% \QyIR{RRcPH{PwP\:$Hd}y9e \e }\ < }*JW%K\J%-N <HUb),-7B8PMFP¾qcP_PD wP:$cPPwP:$Ze =}}f,tc #`Br] \ @( Lh4cLhr4-Lh<4hHUbdʿ,7PFJqscP;PD wP:$cPkPwP:$e = }},Ttc d`r] "\ 0%/</<-<<HFUdbdW,7zPF q+cP0PD wP:$cP`P_wP:$e = } },wDtc T`zr]  \ # &4%  45 bH: 0= 8b)/%= 8\= X-= X<XHU8b8X ,c7z <PFqcP PD wP :$cP PwP :$ e   =!}!} ,H tc X `z r]  !\ r !Pn.!;!\ } %<lHHni@!0};R!<W!0`!@/%`!`!-`!<H,UJbJ!,u7"8PFPqcP"6P wP #:$cP #fP; wP#:$"e "*#=2#}h#}",S n!tc !`"r] !p>g  p!  ! > cPU"<P wPi":$cPl"<P wP}":$!b U""="}B#}!b !" !  cP!HzP; wP":$cP"HPc wP":$!b !&"=."}U#}J#\ ]#\ p#\ np#;}~##\  JU &4;#qJ#\#0#(\ { #P c#Pr -#P< PH U b #L, 7$xvP0 FT q 3$e $%cP%cP%=&%}L%}A$, #tc #`$r] #]3#0#]/ %) #R  # -#< H U b #,7Z$ $P0FT8qs$e $$cP$cP$=$}9%}}$,#tc #`Z$r] A%\ T%\ `%, X/lHl%/7q%0z%x4 z%cz%r-z%<HUb%,:7Z&PMFpqs&e ''cP'cP'='}o(}&,%tc %`Z&r] %5C/%H%f%0-%0<0HUb%{,7&`P,FBxqv&e ((cP(cP'(=0(}Z(}& ,%tc %`&r] 7%1FR%e#W%#YcPH'<PwP\':$cP_'<&P wPp':$%b H''='}(}%b %"!&&(2Y(&H&Hp&cP&<BPtwP&:$cP&<rPwP':$&b &'=('}E(}/&"B&M(\ b(\ w(\ (\   38!$(%<Y(h (63(8YU(%hr(I8FIIg3]BqI#NIL$#L;Lu7wBRo (D Ij__x`D5d uj__x>7b ! ?x__nTrCIB!iŐ0DB:0DBD0EŐ>0GŐKIStr (ic7  (p\'O$Cd%Qm84vl84$X%9$a5H/!oK+5,oK@% (%i~( WMWNTPpVQ%z#X}%^\Fz;la\FzQf}r(M)0= )OLa )a] )T*]]LZz)`[ZSz)wSWIz)fIfZ})`uZ-S})tS-WI})fI-HB@qI6* #I@LB*8#LLL5wBR}PBjqIM* #|IjLV*h#LL5wBRz&B!qIa* #I!Lj*#L]L5wBRzBqIu* #ZIL~*#LLq5wBRzBqI* #IL*#LL^5wBRz sB|qI* #8I|L*( #LL5wBRz@ B3qI+` #I3L+x #LL5wBRz QB0qI+ #I0L, #L~Lq5wBRz BqI , #IL, #L3L|a5wBRz /BqI, #IL(,!#LL1Q5wBRz !BOqI3, #cIOL<,8!#LL6wBRzP! B qIG, #I LP,h!#L` L q6wBRz!|B qI[, #AI Ld,!#L0!L!a6wBRz!B!qIo, #I!Lx,!#L"LV"Q6wBRz!ZBt"qI, #It"L,!#L"L&#A6wBRz"BD#qI, #ID#L,("#L#L#16wBRz@"8B$qI, #I$L,X"#Lp$L$!6wBRzp"B$qI, #lI$L,"#L@%L%6wBRz3,"e!B%qI, #I%L,"#L)&L&A5wBRz,"f9&,"zt&I'%-L#)(,#y8(& ,#&,#}&ҷ9y'9 '9 ''9 (%-0#g0#(%-p#m7-#m'(7-#@u(((7-#t( (Z7-$is($15($<HW)5($M+)W),5r] :$ɩ>-u(ة(jd9-@$@ydyd-X$DC6))-X$0ڪ)ΪªX$)!-X$0~V)J>[*X$d*-0K7*+*- ; 0P5+ԨS+ ; ;I ;e ;'e RD-e /RD@>zXD.Dq+8+XD`D ++`DMΧ+ا+iD\ r-Pg\+e,-P,8-  C<--e (-x$0(\-(I.PX|-.+I%.$g?I-%.$$- -%.$-Ԩ-$I%.$~I-I).G.%gT.3G.%]BT.qIG.#LIT.LL. #L.L.^.wBRz/l.>.l..D>/8`/l.p.  s//p. MΧs/ا/y.\ |.;h//8|.C/.e (.$(:0(.+.$iG008. C0.e (.$<(@1(.+.%k(1vS. %dS1S[2 /3 /8%kB2qI /X%#I2L/p%#L3L 46wBRz  /m14/O 4/ pQ@/^ @/%rG*4?4%}U4}*~7^5%J53C?B5qIC #I5L%C#L5L 67CwBR|37CB6qI7C #~I6L@C#L46Lc6RCwBR|3RC1Bv6qIRC #Iv6L[C#L6L6mCwBR|3mCB6qImC #pI6LvC#L6L7CwBR|3C#B%7qIC #I%7LC#L;7Lj7CwBR|3CB}7qIC #bI}7LC#L7L7CwBR|3CB7qIC #I7LC#L7L8CwBR|3Ct{B-8qIC #TI-8LCk#LC8LX8/_ /e 4i4444*4455c&Jkk8x88N9^ 2c2 }$ }2 364B9qI6 #I9L6#L9L96wBRz364WB9qI6 #I9L6#L9L96wBRz364B :qI6 #I :L6#L :L5:6wBRz364KBH:qI6 #IH:L6#L^:Ls: 7wBRz3 74B:qI 7 #I:L7#L:L:(7wBRz3(74?B:qI(7 #I:L17#L:L:C7wBRz3C74B;qIC7 #~I;LL7 #L;L-;3}7/B@;qI}7 #I@;L7#LV;Lk;7wBRz37/B~;qI7 #^I~;L7#L;L;7wBRz37/B;qI7 #I;L7#L;L;7wBRz37/B;qI7 #RI;L7#L<L%<7wBRz37/B8<qI7 #I8<L7#LN<Lc<8wBRz38/mBv<qI8 #FIv<L 8 #L<L<318$/B<qI18 #I<L:8#L<L<P8wBRz3A#aB<qIA #&I<L A#L=L=AwBRz3A#B-=qIA #I-=L'A#L@=LU=9AwBRz39A#UBh=qI9A #Ih=LBA#L~=L=TAwBRz3TA#B=qITA #I=L]A#L=L=oAwBRz3oA#IB=qIoA #I=LxA#L=L>AwBRz3A#B">qIA #I">LA#L8>LM>AwBRz3A9#)B`>qIA #I`>LA0#Lv>L>/e /f -04f 80_f c0i|0000*000c2i2.2B2R2*f2z22c2r^ 2^ 8i88 99*/9C9I9cH&>3;@B>qI; #I>L(;#L>L>:;wBRz3:;@RB?qI:; #I?LC;#L?L-?U;wBRz3U;@B@?qIU; #I@?L^;#LV?Lk?p;wBRz3p;@FB~?qIp; # I~?Ly;#L?L?;wBRz3;@B?qI; #I?L;#L?L?;wBRz3;@:B?qI; #I?L;#L@L%@;wBRz3;@B8@qI; #yI8@L;#LN@Lc@;wBRz3;@Bv@qI; #Iv@L;#L@L@1_ 1e 3i33 44*.4B4V4\4c38h&DB@L8&#L@L@#8wBRzqI: #I@3:DyB@qI: #>I@L :#LALA:wBRz3:DB0AqI: #I0AL(:#LCALXA::wBRz3::DmBkAqI:: #2IkALC:#LALAU:wBRz3U:DBAqIU: #IAL^:#LALAp:wBRz3p:DaBAqIp: #&IALy:#LALB:wBRz3:DB%BqI: #I%BL:#L;BLPB:wBRzu/yf 0d 2h9i9999*999c&s%cB3AsBBqIA #IBLA#LBLBAwBRz3AsVBBqIA #IBLB#LBLBBwBRz3BsBBqIB #IBLB#LCL(C/BwBRz3/BNsJB;CqI/B #I;CL8BE#LQCLfCNBwBRz3}BsByCqI}B #IyCLB#LCLCBwBRz3Bs>BCqIB #ICLB#LCLCBwBRz3BsBCqIB #}ICLB#LDLDBwBRz3BNs2B0DqIB #I0DLBE#LCDLXDBwBRz51_ L1da 3i(3=3Q3a3*u3333c]T1&t]kD]s]W1&u]D]Dc1&f D'E"c1~f1Duc1$uDuREpp1~Dup16uEuV1~eE1` ҷ1}E1 E1E F1U1 `xFlAF*1 M9OFCAF1\ & i1v ? TF5 F31 'eF BFqI1 # IFL18'#LFL G5wBRz31P'w B+GqI1 # I+GL1h'#LOGLqG2wBRzW7'f/ GW7&h G"W7~= 1GuW7$uGuGVn7'~] eHv7` ҷU8}/HU8 /H[8DHfH[8U_8 `xlyH*_8 M9OCyHh8\ 3k8e BHqIk8 #n IHLt8#LHLH8wBR{38$w! BHqI8 # IHL8#LHL)I8wBRz; B#LMLM>wBR}>;BNqI> #jINL>2#L&NLUN5>wBR}3?\BhNqI? #IhNL?#L{NLN?wBR}3?\BNqI? #\INL?#LNLO?wBR}3?\BOqI? #IOL?#L+OLZO?wBR}3?\BmOqI? #NImOL@#LOLO@wBR}3@\BOqI@ #IOL @#LOL P2@wBR}32@\zBPqI2@ #@IPL;@#L3PLbPM@wBR}3M@\BuPqIM@ #IuPLV@#LPLPl@wBR}3@&kmBPqI@ #2IPL@#LPLP@wBRzG)d e)f )))) *&*6**i*i*i+++?+S+h+|++*++*++*.:r>i>>>>*>>>c?i:?O?e?w?*???c8\ yjGCI* uj*:*__aG7CI*!iŐ0D*:0D*D0EŐ>0GŐd/D's' Q$dD Wd JdQD$dD-WdRJd)SD$dDaWdSJd0TDb E'(cTcTI E ITqI EITWI E-fITE:$ E DT%x E4xTx E}xTHE'1  THE'7**UTbUyHE'bUɩHE'ةbU(5KE(dUWUM V(KE(UU V(&@VZKE0(i Vs@V0(1KE0(< VH@VKE0(M V+lV@ViEr] ^~EX( VVW ~EX(0BV6V*WX(P?WL~EX(0~VuVikWX(W~E0KWWEF 0P #XԨAXF FIFe F'e F-e Ep(# aXE(7*XaXX("5E(dXW5YMmY(E(X5YmY(&YZ3F(!imYsY(13F(<mYHY3F(MmY+YYQFr] ^fF ) Y(Z`Z fF )0BY6(Z*`Z )PZLfF )0~Yu(ZiZ )ZfF0Ks"&[\[FG 0P"[Ԩ[G (GIGe 0G'e CG-e y0F@) #Xɩ0F@)ةX/F>[F.D[8\FF \7\FMΧ\ا7\F\ EX)&J\Ex)7*\J\\yE)o$\ɩE)ة\)5E)d]WY]M])E)]Y]])&]ZE)x%i]s])1E)<]H]E)M]+^]Er] ^E* H^^^ E*0BH^6^*^*P^LE*0~H^u^i_*T_E0KY&}__FG 0P&_Ԩ`G  GIGe G'e 7G-e DDcP EcP E}F\ F}F\ 1"R'{%BI_Tp B: BK R'אPG. &7 .3 ./ .  *|.y .'` 'mG ((D'V`7'`*'`mG MA5Go,G R(7`G2>cPGH* (P`wP2aG:$bG`* )(c[acIG )I[aqIGI[aWIG-fI[aG:$cPGx* B)PnawPaG:$bG* )(cacIG )IaqIGIaWIG-fIaG:$cPG* )PawPbG:$3G* v*B2bqIG*#=*I2bLG*#LjbLbHwBRuTIHJ [,IbH4+$b bH4bԨbH4IH4~IbIbH+g*c3H+]B*cqIH#j+I*cLH(+#LbcLc-HwBRw/;H>c;H.Dc8c;H?H  cd?H MΧcاdHH\ bH@+ ,(c"dc5dIH ,I"dqIHI"dWIH-fI"dH:$cPHX+ -PHdwP`dH:$bHp+ -(cdcIH+ -IdqIH+IdWIH+-fIdH:$3I .BdqII#-IdLI#LdLd$IwBRuTjG9.Pu\Ru mH~HcPHcPHcPH}H}I I\ 1117/0I%I &7 '| %I+I3 *I5q \F1 %do D z TU_L 8d_qSLMSrIL6IrqILIrWIL-fIr cPL0 49PswPsL:$bL0 9(ctcIL 9ItqILItWIL-fItL:$cPL0 9PKtwPtL:$3L1 h:BtqIL 1#/:ItLL81#LtLuhNwBRud3LP1 :BB`xqIP#>I`xLP#LuxLxPwBRu`3P >BxqIP#z>IxLP#LxLxPwBRu`3P +?B yqIP#>I yLP#LyLLyPwBRuP3P$ ?B_yqIP#j?I_yLP#LtyLyPwBRuDP@ByqIP#?IyLP#LyLyPwBRud3P @ByqIP#S@IyLQ#LzL3zQwBRud3Q @BFzqIQ#@IFzLQ#L[zLpz)Q#cABzqI)Q#*AIzL/Q#LzLz>QwBRud8LiRLdLL MMAMMM|McPMoj3N2 >BBzqIN3#BIzLN83#LzL{NwBRud3O BB<{qIO#}BI<{LO#LQ{L~{OwBRud3O  CB{qIO#BI{LO#L{L{3O  CB{qIO#[CI{LO#L{L|OwBRu3O DB&|qIO#CI&|LP#L<|Li|PwBRud3P  sDB||qIP#LDI||LP#L|L|3PP3 DB|LPh3#DL|L|'PwBRudqILQ#I|3+P cEB|qI+P#*EI|L1P#L }L:}@PwBRud3@P EBM}qI@P#EIM}LFP#Lc}Lx}3UP AFB}qIUP#FI}L[P#L}L}jPwBRud3jP FB}qIjP#FI}LpP#L}L ~3rQ GB~qIrQ#FI~LxQ#L4~La~QwBRud3Q GBt~qIQ#^GIt~LQ#L~L~3Q GB~qIQ#GI~LQ#L~L~3Q" cHB~qIQ#*HI~LQ#LL2QwBRudTIcIcPvIIIW'IIJW'HJ]JnJW'JJJW'K-&K:KW'rKKKW'KFNcPNcPO\ 99n8OQZ &7[ Z3Z \FcPR3 IP wPER:$bR3 BJ(cncIR 7JInqIRInWIR-fIn!R:$3[R3 JBqI[R4#JILdR4#LqLԀeUwBRud3oR04 2KBqIoRH4#JILuR`4#L&LH~UwBRud3Rx4 KBfqIR4#qKIfLR4#LLUwBRu`3R4 "LBqIR4#KILR4#LLUwBRu`3'S5 LB$qI'S05#aLI$L0SH5#LLUwBRu`3;S`5 MBHqI;Sx5#LIHLAS5#LjLUwBRu`3S5 MBqIS5#QMILS5#L0LUwBRu`3S5 NB΅qIS6#MI΅LS(6#LLUwBRu`3S@6 zNB0qIS`6#ANI0LSx6#LLUwBRud3T6 NB$qIT6#NI$LT6#LDLfVwBRud3KT6 jOBqIKT6#1OILTT7#L͇L#VwBRud3_T(7 OBDqI_T@7#OIDLeTX7#LfL#dIL[(>#LL)\wBRu\3[@>; [eBWqI[X># eIWL[p>#LyL]wBRu[xfi> %8|[>> eG|آb[>Z!ba[>b%b%{[ ? f|N|n׏[ N[ n[>K@n5nN*nǣe[>/ee[1\4IcP,\>B fPwP <\:$b<\>B ^g(c(cI<\ SgI(qI<\I(WI<\-fI(L\:$3Y\?B gBhqIY\(?#gIhLb\@?#LL$]wBRud3]- NhBqI]#hIL]#LLE]wBRud3] - hBXqI]#hIXL]#LmL3] B -iBqI]#hIL]#LLڥ]wBRu3]0 iBqI]#liIL]#LL/]wBRud3] 0 jBBqI]#iIBL]#LWLl3]X?9 jBL]p?#fjLL^wBRudqI^#I3 ^, jBqI ^#jIL^#LҦL ^wBRu`3$^) skBqI$^#:kIL*^#LL=9^wBRu`39^) kBPqI9^#kIPL?^#LfL{3R^6 SlBqIR^#lILX^#LLg^wBRu3g^$6 lB˧qIg^#lI˧Lm^#LL^wBRu3^2 EmBqI^# mIL^#LLJ^wBRud3^2 mB]qI^#mI]L^#LrL3^; #nBqI^#mIL^#LLܨ^wBRu\3^$; nBqI^#bnIL^#LL1_wBRu\3 _ , oBDqI _#nIDL_#LZL&_wBRu`3-_' yoBqI-_#RoIL3_#LLũ3L_%' oBةqIL_#oIةLR_#LLa_wBRu`WWcP9XiMX\XW'XiXXW'Yi0Y?YW'~YYYW'YYZW'JZ-]ZlZW'ZiZZW'[FT[i[{[W'[cPY\cP]\ H _qNy yC Ny%?Cyj D. ~v ~1  ~_? 6rz3Mc@%rBqIMc #qILVc#L)LXhcwBRu~__5Z_? jrZkZ`B_ `?1 8tI+ `@r$`g$`8@esv;$`h@#?s;` M`@#?Bs/MM׮`Lc##?LLb-`@sFx<`@csBa^a c%X^a ~qg%aLlc!!tpLðcuacc3a@3 tBqIaA#wtILa A#LSLbwBRu~(a8A1 v (8a`A5uI 3aA@fuB[qIaA#-uI[LbA#LLbwBRw2L b@AL$bD($bA5ug(S(cL-bA#;uLLL?bA#;LLaLebB5pLM}bɋ}b B vڋ3}b@B;BqI}b`B#rvILbxB#L^LbwBRu~ɋbB4 Awڋʵ3bB;BʵqIb #wIʵLbB#L LJbwBRu~ɋc wڋh3c;BhqIc #wIhLc#L~L#cwBRu~ɋ#c*4 ixڋ3#c*;BqI#c #.xIL,c!#LֶL>cwBRu~3c&3 xBqIc #xILc#L.L]cwBRu~__#_Bc _^ __ a$Za&ba*d a]_ cGc\ H%#yvŐ{ŐvŐ:vŐDvŐiyy d__nc__s'CEj-zCIŐ!iŐ0DŐ:0DŐD0EŐ>0GŐ]iEzi ujGcp__xGiB#}Q\BLz%=1ڃBM,SyJCS{y.}yApyJC.AJC_X.KA>CgaJCV¸CvSk(CSS:xvS@CW,|SMS3XCW|BqIxC#k|ILC#LL˹wBRuc3(%W}BqI(#|IL.#LL+=wBRucGC^C^Ej0=`Ej>YWa[csob[cyC_}yryyֻCyjd}ydydCc7WvC`~oZDa~iǼsD1<HM+r] (Di %/=C1oڃ(DM/Co@Drp)d@D0.d3@D0h\Pd@Dvwy@D0~zzy߾@Dz90K7L+ 0PLԨ I-e e 'e 2hDy) 2hD0. 32hD0h\ PhDvZy2hD0~zz yhDz@0K~7+hN 0PԨ  Ie ('e -e d*$ d*Ԩd*Id*~II&xgD3x]BDqIx#IDL}#L|LwBRud.D8   MΧا\ f$ fԨftIw{.D81w~  ]~ MΧا]\ 5ȟԟqMq3 BqqI#IqL#LLwBRud\e 'e e -e F\ אg} uj__x7kdD  %S%ecH5Z%$d d5WdJddBd%xBd4x xBd}x )_dD{) &)O )D5)TB)_d/b%x_d4xbx_d}xbDQ)iLd EۇBL5L-+LV[Nd@EԇNtN-jNVId`ECɇIVyg$$dndxEx}1dm%=1ڃdMde-z3dBqId#ILd#LLJdwBRuLL eEBL]5L+L[N eEN+tNjNI eCvIg$$;en>eE%c}Je%=1ڃJeM[e-g-z3geEB*qIge#dI*LmeE#LsLgwBRH3gB qIg#܊I Lg#LLLgwBRH3gB_qIg#TI_Lg#LtLgwBRDdxeFE>xeFWMExe Fg ʄE F؄~e@FhZʄ8@F؄e`FiʄL`F؄IexFsIeF$9 meF9ԨmFIeF~I9IeFg3eF]BqIe#ILeF#LLewBRuP/e>;e.D8ee  ?[e MΧ?ا[e\ g3eFBnqIe#InLeF#LL\ gwBRXjdeG/ydzydzNj7f0G]jgjNjOf1q]jgjANjif2]jagjf G9>mfIfHG9ʑIfpG$ fpGԨpGIfpG~IIfGg3fG]BqIf#ِILfG#LMLfwBRu`/f>f.D8ff  f MΧاf\ 3:g4BB%qI:g# I%L@g#L:LgOgwBRX3gBzqIgG#IzLgG#LLgwBR@\d!fMi'fcAf1[f1uf1fr] [gg\ cg\  h0z ] "hGǔl uf'hHfWff7h Hf>h ʓGhda 3Jh8HABqIJh#ILOhPH#LL7hwBRug3hBVqIh#wIVLh#LULhwBRug_h\ 'hw hh) alh a[lh -[[mvhhH[mh@Psh hEh\  Ğh h{^%#k|:,$k5@vS=HsSTSrJ3JHsBqIJH#\ILSH#LL wBRuc ^Hw (SdIblpj6$ j6Ԩj6Ij6~IIIg3I]BqI#IL8I#LL9wBRwXIix%WnIy}%E=]1rڃME]ro-z3IyBqI#ۘIL I#LL wBRuc3yBudqI#SIudL#LL<wBRuc  0~˙ O {>> F0 II }3sBqI#TIL#LLwBRuc= \ \ {/i#|:$5i^$%#k|:$k,vSEIsrSSS3SIsBFqISJ#IFL\0J#LdL|wBRuc gHJw7 Sl`JblrJ$ rJԨJIrJ~IIJgK3J]BKqI#IKLJ#LLwBRsJix%nJy}L%=1ڃMo-z3KyeBqI#,IL  K#LL0wBRuc3yݞBudqI#IudL#LNL{wBRuc~zPsv2$u " ( ~3  44 S<0 ?!} QE~zPsu \ /i#|:$,i EFРE*Ex8Kg_8K]q38KBOqI#IOL%PK#LL8wBRoиߠ i__x>(B} " Q__nsCI u!iA0D u:0D uD0EA>0GA hK*JWm\J#K8JKo XРXKߠXK@JGuTX(L%G uTXPLGPL``L``LM(pr] $guT^i^xL@lmimi.LD{nHaTL0HL "L0~WHK?Leh$0KZ. S o 0P  E-e e 'e "@1,B6  (H M̲(ֲH\ Lѥ%[e !2cP?cPH=P}}tc #f:Jr] \ \ \ @BT#^ E V<m='%>%V?'' iv  Gr1'% -B W%Lmsg@3L5i̧D5i|cb5iL(ccI5iM IqI5i(MIWI5i@M-fIMi:$Si[i:[iXMFI/ cipM/Qkis^ikiMpmiumiu&jF<j|cjcPOjMoeM|cjcPZjM:z'pOM|cjcPMi%q:jMI kN/ ks^i kNémimi0N}J*:ii&ckNF#<[N|ccPgkNP#wPwk:$wkNdN|cbwkN(ccIwk WIqIwkIWIwk-fIk:$&k O˫F<9 O|ccPk@OPwP[k:$k`O{`O|cbkO(c{cIk }I{qIkI{WIk-fI{k:$3kOBqIkO#ɬILk#LL>kwBRP3kzBQqIk#AIQLk#LfLkwBRPbkSi­SWIifIiOi&biO8QEY9-#3ClDBqICl#qILIl#LLWlwBRv3WlD!BqIWl#IL]l#LL llwBRHiiQiSitSWIifI3i PBZqIi@P#IZLiXP#LLkwBRvjN  jpPc jpPrj-^jPx"=gjMgjPٰ^UkgjPUkUjgjPjjjU$jPD~:P|cjcPjQڱQ|cbj Q(ccIj@Q ͱIqIjXQIWIjpQ-fIj:$k"lM l"e^k l"Ukj l"j$jll"ֲB8qIll#I8Lrl#LMLzlwBRH5i^j8llf l\lf lf 'l\ 11AglJ -Bg30mQn߳BqI0mQ#IL9mQ#LL`mwBRu_3@mQnWBIqI@mQ#IILFmR#LiLwmwBRs3m nϴBqIm#ILm#LLmwBRu_3mnGBu`qIm#Iu`Lm#LL)mwBRu_l0l]mmm00m^m\ 5;5ŵ _Z%GFmX RXnHR<T`nHRc`<`nW*`pSnSWInfIM@n^k@nUkj@njjzVnhRַ~VnR14gVnRMgzCg13]nRɷBqI]n#ILbnR#LLnwBRu\rn\ Mn7^knUkjnj jzn}!~n6n4gṃn+nV8n/@nWnW3unR2BcqIun#IcL{nR#LLnwBRv3n)BqIn#qILn##LL owBRv o\ /j  i'7/ ocq*{# '&oSD'7'H*'j&oS MA5@ooLo(S{(SϹ\]o޹jd`o@SydydjdxoXSydyd&opSxF<pS|ccPoSPwPo:$dodd oSI*S|cboS(cc?Io <IqIoIWIo-fIo:$&oTFo<T|ccPo TPowPo:$oo|ccPo@TPwPp:$.p'ND1p'|ccPpXTPwPF/p:$@ppTvOp&bMOpT^kOpTUkjOpTjQjMqo^kqUkjqjjXoqpTT|cpcPpTh[T|cbpU(ccIp8U [IqIpPUIWIphU-fIp:$pUU|cpcPpUikU|cbpU(ckcIp \IkqIpIkWIp-fIkp:$opU +cU|cpcPOpV oeV|cpcP&p(V /FC<{(V|cpcPM/q^k/qUkj/qjj3Eq@VBqIEq#ILKqXV#LML|qqwBRud3uqBqIuq#GIL{q#LLqwBRu[Mq^kqUkjqjjqpqV'q//qWq\ qW17(qos(o )t3rpV+BqIrV#ILrV#LPLrwBRuWI&rS+I,rV$ ,rVԨVI,rV~II@rVg3@rV]BqI@r#ILErV#LTLvVrwBRv/fr>fr.D8frmr  mr MΧاvr\ 3r+0BuXqIr#IuXLr#L"LOrwBRuWqNPsRu rrrr\ 149rQWFlHb[V|pVu,íE\05'pVkí. 0Wr7r0LZr0W[ZSr0WwSWIr0WfILZrHW[ZSrHWwS WIrHWfI pWN$I?$gWy 0Y/0fZ"sWuZS"sWtSWI"sWfId0sWzW|ccP3sWPwPBFs:$FsX]eX|ccPLs0XPewP\s:$\sPXPX|ccPbspXPwPGrs:$_rsX_g_X__vcPscPsXX|ccPsXPwP5 s:$sYU Y|ccPs(YPU wP s:$_s@Y<_g_ `Y1__ vcPscPsxY xY|ccPsYP wP) s:$sYI Y|ccPsYPI wP  t:$_tY[_ _ ZP__ vcP&tcP&t Z  Z|ccP,t@ZP wPE ?t:$Z?t`Z!ze p`Z|ccPEtZPe wP Ut:$UtZ Z|ccP[tZP wP kt:$Mt^ ktUk jtj j M7wF^ k7wUk j7wj3 j 0stVt/tW4wWfZtZuZG StZtSG WItZfIG dtZZ z Z|ctcPt[U  [|cucP_u [_P _ H[__ wcP'ucP'u`[`[|c>ucPo?u[*H[|cQucP_Qu[_P _[x__$wcPqucPqu[[|cucP_u[_&_^\__vcPucP&u0\XF<0\|cucPuP\(P\|cucPZup\zpp\|cucPu\('\|cucPu\PO\|cvcPM4v^wk4vUkwj4vjjwMUw^kUwUkjUwjjt"vV,v/4vWuwWSw\ >wk a '\5PC8wC6we \p0_wf ]X_w(]g`__wH]__?x`]%M`]|ccPExx]P%wPUx:$_Ux]O__cPUx]PwP!OUx C"O]x9] nx:$gnx]±Q}]|ccPtx]PQwPyx:$3x^(BqIx^#ILx0^#LL'ywBRsMx^kxUkjxj&jzxP^kF~xh^h4gx^MgCgh3x^^BqIx#%ILy^#LL7ywBRvy\ M;y^k;yUkj;yjjzNy1~NyF[y4g3wyBsqIwy#NIsL}y#LLywBRuS?xxxVx/xWtyWwr_ w ` wQ] wf xW` cy\ y}Kr1-BK3y^BqIy^#uILy_#LLVywBRus3y&ButqIy#IutLz#LiLzwBRusyy0y^z\ 1ITpw'ZHD:'Nq''  ?0q"_Bqq%qvzJeH30_KBqIH_#RIL#LLwBRus3KB-qI#I-L#LBLowBRuse +PsQu-e -e 3`_OBqIx_#IL#LL-wBRus_He P'e z-e 3POiBqIP#0ILV#LLewBRus\s\ e  PsR0Qu2-e j-e s\ \ }W#I z $z 1)zy__*8z`p=z0Izj>ozPwzMzj>zPzj>zP EITȭpZHw'9D:'qH''  ?.0r"_Bb;r.r!r._eHEf3_KByqI`#IyL#LLwBRus3KkBqI#2IL#LLwBRuse PsQu-e -e 3 `O*B!qI8`#I!L #L4La/wBRusP`YJLe T'e ~-e 3TOBtqIT#ItLZ#LLiwBRus\s\ e  PsR0Qu4-e n-e w\ \ I{g%h`1>KXX{` `XXR{] { #{0W&{ WWRa1{` 1s~X|A e|AXX|] W[| % WW1{0{j>{{M{j>|Py|72|.%| #1>KX|O?ITpw'@D:'Ir''  ?0r"`BrrHrvz(eH3`KiBqI`#0IL#LL=wBRus3KBPqI#IPL#LeLwBRuse  PsQu-e -e 3aOBqI a#gIL#LL-wBRus8aHe P'e z-e 3POGBqIP#ILV#L L:ewBRus\s\ e  PsR0Qu2-e j-e s\ \ Ig|vMPa| #|0W|  MWWa|ha msX5}a aXXC}] aS |H}a -|9 eH}aJ )ee )ee } H%z }=1>KX}O}X}B }BXX}] W`~ W W |0 }j>5}.3~j>W~.g~6v~ +~lii %t![N@envrV@envsV@%P%zD~a?^ b b!u!!!B"" ~8b  ƒPsXWPbPbXXk] a]s"hbK,#b_vbnv#Evb@Tv#bTv#b[cEq[#sFw%R#v%vv$v%(vvv_$i t$ `X(c(cXX)] 7'$7(֛ɛ$ 4%@cR%bXcF!bq%aXcb%b%c%%c%ncR@nD&5n%*nY&e:/eeg"cvcU|mo&׀|Zo&\|$uo&k*&H&\6u&k5>Bl_Rc % c c &X"9v"9XX0] ނd&d'ZkcPxcP=cP=cP}U}(0d+'8'M٫=06̓HdAN'HdOl'['X`d`dXX#] ~-è]\ rITp$w'DD:'Ds'''  ?[0s"xdBs's((s(deHr(3dK B(qId#I(L#L(L)wBRus3KB0)qI#_I0)L#LE)Lr)wBRuse PsQu-e -e 3dOWB)qId#I)L #L)L)/wBRusewLe T'e ~-e 3TOB)qIT#I)LZ#L)L*iwBRus\s\ e  ?PsR0Qu4-e n-e w\ \ I B 'Q DbC %$` G eSJ$-*='_Y`LnY { -v9E*/\*@eYo*za yYȄXe)Y*Մ;|Մpe)Q**2*Ze ;Z*Z +B_  g  ]_  Y~)za 5\ )@3 Ge)+OeX+OeX+e+cPՅ<_P+wP:$cP<P,wP:$Ub Յ =}}db :gfI, j(f/H,|sՊ|Hfi,hf|,Ê,hfM|,,_hf q,3hfB,qI#I,Lf#L,L-wBRudf"6-fn-f-cP5HP-wPI:$cPLHP-wP]:$b 5j=r}}" .\ \ Ɔ\ U EZ Z%t53 YІ{E؆0vA{AA:ADA__na2 xi__nV__s'CCIA!iA0DA:0DAD0EA>0GA~  iG&#.__xG f@ Q)TT%Lqh..t.%M'.=.1."!  /I/=FgQ u/ehgS//hgS/F/9hg_//g-0hgVe00g1Hd(1ZJ1vS0gSl1S1HHgWd1ZvS`gS1S_gWq13gB2qIg#uI2Lg#L?2La2wBRu[_%Wq23%B2qI# I2L#L2L2wBRu[g C^0=`2YWa/3obs3h_ .4f44h#4^i  mimiCc4W+0h`9 UH+5`ha 5`h5M555#r] T)hiN h55tE6)hM'5=51E64h  66QLVhr #7r7Vh0.A4#7'7Vh0#77h72Vh0~g#7[O8huk8h`&0Ku ~8d"S 8Q 0P 9Q \ E-e Qe d'e Lhy\ 299rh0.A429'9h0299h92h0~g29[9Ohu:h!0K S:S : 0P8 ::  Ee 'e i-e + ;2;+;2;+ E+~*E;EE;xgc;_]qc;3B;qI#L I;L#L;L< wBRu\3 ,B61<3:  E<: Mֲ̲E<C\  Y<x<Y<x< E ,B6<  < Mֲ̲<\ * Ê<*M<_* q<3*B<qI* # I<L3#L<L%=BwBRu\e 'e 'e u-e \ Ap1 I  i__xI "B(f  G}J i 8= i t=  it=Hi =cP<) P>wṖ:$cPχ<Y P*>wP:$b =}}b :hi IB> !i/o>3s" ;i ; >1 >TG( h?3?tS?G(M'?=3?1S?K$  ??fuxi "?xi@i!@cPH PU@wP.:$cP1HJ P}@wPB:$b O=W}}"@\ \ \ A0   Z '  %-B  }J )5 ? t      ii  dĈ j @&bG͈  Y@͈FAX͈~qAgFAvS8j < SAS%B3Pj  BBqIpj#{ IBLj#LBLC8wBRug_j H q2C3jBnCqIj# InCLj#LCLCGwBRs_N   qD3N BDqIN# IDLT#L.DL[DcwBRug3n T BuhqIn# IuhLt#LnDLDwBRug 0N l\ /   E n8I CI\8!i\80D\8D:0D\8D0E\8k >0G\8D> (k0KV g E[CEt $@kS nE E3}/ BEqI}# IEL#LELEwBRug3/B B FqI#  I FL#LFLLFwBRug8M\Σ0P _F}F~_FF gFe 'e -e \ \#? v\8{\8v\8:v\8Dv\8/P `  E` n8~t   d__nx__s'C5|~h g#  Gx__xGg# Xk QLkL F) G8GkMЈF Gڈ8Gt k  aG G3/ BGqI# IGL"#LGLG1wBRuT31/{ BHqI1#B IHL7#L#HLPHFwBRuT4IXt ^kQ  cH H3/0 BHqI# IHL#LHLIwBRuS3// B,IqI#n I,IL)#LAILnIwBRuSy ZSc 1 I$ I IZIIIZ_?I2I%IZNIZV0J|JIZͻJ? :Z JP #KvSk/ SRKSeKvS/- SKSKvS /S8LSrL? kW" Z LP LvSl/ SLS2MvS%8l/ SbMSM4vS5Xl/SMSNFlFlW lIN3Fl/ BkNqIFl# IkNLOl#LNLNwBRuS3Vl// BNqIV# INL\m#LNLOwBRuS3c m/B/OqIc#i I/OLi8m#LQOLsOwBRuSPmR# C^50=`5OYWazxOobzx Pe pm_}  P~ Pt Qpm KQd Y ddCcQWm` Qνma* ݽ0Rm\RzM\RpRRr] mi R)RRmMЈRRڈRt m  KS S3/& BSqI# ISL#LSLTwBRuT3/ B-TqI#d I-TL#LBTLoT wBRuT " nra obTUTH n0. TTy n0TTnT "# ny obUUHGU# n0. UGUy# n0UGU ngU/ :8n! 2&UUΣ:8n8n:8n~U@PngUl@Pn]lU3@pn/, B1VqI@# I1VLFn#LmVLVwBRuT3Mn/ BVqIM#j IVLSn#LVLWwBRuT3a/B6WqIa# I6WLg#LWLWvwBRuT! %Wˢ ֢W MŢW\  n6" %Wnˢ ֢X MŢX+\ C" 2&ΣCCC~'XLngjXXڒm # Xm MÒ͒Xve 3'e <e je -e Ue \ \ n8|{# #  __x# 8# %  U3% # 'X2o% NXDXl# o# X{# 5Y8o% |Y)YY8oMЈ|YYڈYt ‰Po  Y Z3K /7% B#ZqIK#$ I#ZLQ#L8ZLeZ`wBRug3k/% Bs qIk#u% Is Lq#LxZLZwBRug։> a % sZi\ n82\L& ' DNl# ho' # Z{# [o' ^[)[[oMЈ^[[ڈ[t o  [ "\3 /R' B@\qI#' I@\L#LU\L\*wBRug35/' Bs qI5#' Is L;#L\L\JwBRugԊ 3\ ~P( ) l# _oE) # \{# #]go) Y])w]]goMЈY]w]ڈ]t ko  ] ^3ҋ /F) B7^qIҋ# ) I7^L؋#LL^Ly^wBRug3/) Bs qI#) Is L#L^L^wBRugˋ \ * ,  3G , ~"oH+ ^_l# "pE# ^{# _*(p+ 8_)V__*(pMЈ8_V_ڈ_t .@p  _ _3 /f+ B`qI#-+ I`L#L+`LX`wBRug3/+ Bs qI#+ Is L#Lk`L`njwBRugBWf \ n8~u, CI"9!i"90D"9:0D"9D0E"9b, >0G"9CI"9!i"9, ,  vB, 49, ;Z. +, `7, C, XpO. U, ` pp0K- `*au, $pS, Ua, sa3X- BaqIX#o- IaL]#LaLalwBRug.=aw0P0. auaw4w~TaH b g'7bwe 'e -e \ . v"9{"9"9:"9D"9__n. .  d__n__s'CH / =  5G__xG= p%4 QX|pL^0 Wbbb@pMOWbebYbu, p , b, :c3O0 BccqI#0 IccL#LvcLcwBRu`,;u, ApQ 1 , c, d3$0 BBdqI#0 IBdL#LWdLdwBRu_Wcl9S2 &dd dl9ddd?l9_dsdfdl9eZ. l9V. d. Few. dl9. eeevSM2 SeS fvS SfS4fqW3 IffvS0q2 SIfSfvSHqSfSfaopqW4 sog3q3 B:gqIq#p3 I:gLq#L\gL~gwBRu_3qBgqI#3 IgLq#LgLgwBRu_zr= C^H0=`HgYWa3hobkh. (r_4 . h. 6i. bi(r. id4 ddCciWNPr`5 xkiؿ$ra5 Sjr$jƿ$Mjjj-r] |3ri6 jjk@3rMOjejYku, ?r , k, k36 B$lqI#i6 I$lL#L8lLelwBRu`IZ_rr9 xlll7_r0.wxljl]l_r0xlllr)l, _r0~C, xl7, l+, ?mrU, ~mpr0Kn8 mnu, tsS, Fn, on3k`8 BnqIk#'8 InLp#LnLnwBRu`~a'0P8 VuuP'4'~TVHnsg'.oe 'e -e 0sy9 Zoo70s0.wZoj]o0s0Zoo0s)o, PsM; ŦopaPsuPs4Ps~THphsg'7paohs]so7p3s: BzpLs#: LpL qwBRu`qI#Izp3sBqqI#; IqLs#LUqLwqwBRu`; q^ iuq3 MBXLq#\ $n< Ŧa$u$4$~THqsg'qt< *rt^iu>r3MBXL>r%\ Q@F= \hRr+@M:DRrKe e -'e 6e f-e e \ \ 49#= {%fSr  fS: fS  0> r , #E> RfSr. fS: fS .T> l>  5__xl> 9Ќ> lL  QVslL  qL tWL frSMr@t? r> @trht? "scP}<p? PaswP:$cP<? PswP:$ b }=} }b 9t@ s tCNCtQ@ ]tzpCt6ptp4Kt@ C uzpKt$p up= Nt$G = Eu= u= ucNu @ dEu d:v[= \ u B = vc\Hu,DA dv dwghhu,A ؉|wΉwchhu,d|w dwvvu,+B x3vuZBxqIvu#A IxLu#LyL zwBRw,+z3ZB+zqI#B I+zL#L@zLmzwBRud> u D 8> z,>  > ߓ :C zzc ,dz dzv C ,{8v,{3XvZB{qIxv#C I{Lv#L|L|(wBRu`] D  }], }3]ZB }qI]#[D I }Lc#L}LL}rwBRu`jv PE _}v,_}3vZB}qI#E I}Lȍv#L?~L~7wBRwӍw E ~3Ӎ wZB qIӍ#E I Lٍ8w#LyLGwBRw xF 3ZBqI#>F IL#LL/wBRuT= B= ,B3= ZBBqI=#F IBLC#LWLVwBRu`PwG 3hwZBqI#~G ILw#LLCWwBRw3w0H BaqI#G IaLw#LL gwBRwNwrH ]+zpw6ptp8+wH QGvS+xSS939 x ȎpxJ ^> qT> |юxJ ؃&@юxMO؃eY&u, Վx , 9, e3zJ BxqI#SJ IxL#LL. (K 3ZBqI#J ILƏ#LɄLՏwBRuT3ՏK B qIՏ#gK I Lۏ#LLKwBRuTK "^3 x@L BuTL x##L LudLPwBRwqIv#IuT(7*\ (\ 149L O  lH O xO s6lH9v"M X~qgq^y|M ^8^Py38PO3ؐ(yM BpqIؐHy#M IpL`y#LL(wBRusq^xyNN ^^xy3 Oq^0N ^>^VA3QN ButqIQ#N IutLW#LvLfwBRusؐq> o\ 49$O IO  vBYIO NO 11-(pkO Q  GkeyQ /Q O uyPP ;O .O $O >3CP BqI# P IL#LՈLwBRuoaoy\Q so3yP BgqIy#P IgLz#LL߉БwBRuo3(zB qI@z#"Q I LXz#L-LOwBRuovL \ "\ 11d,0Q o|80ISO yPU key~U /~%pzxU d@c`z]R `cQ Vcmz|cq=rzR &bdzR |؊o(0SO 3z=S B`qI{#S I`L{#LLNjwBRuk30{S BqIH{#|S IL`{#LL7wBRsMÒT ^UkÒUkUjÒjwjUMwT ^kUkjjj3!T BqI!#T IL'#LɌL6wBRuk36gU B qI6#.U I L<#LLKKwBRuk`\ 11W *.n** u V X ~q^gR g\V XR ~qgsx{V %xsx{4xxsx{}x%c 3a Fa Ya ov c v c v c a ( ; Na a wv c a c v c  a 8Oc pc c FXFXFX//00#020A0P0_0n0}0000000d00  1 G1 $)1} Y91k I1X Y1@ i1 u1 1 1 2,@O 0_ o  ~ m g ` U N C 9!7 10  A( YQ a q 2  t%[ y' [ @!,L9RFTSIm/Gz5$)F+4aPx648} 999~D9*H*=FFA1<60s77D\  ] i%"] % CFj%9] 'm͝9%Q] ' [F%r] *''m4779] *] '%EǿgG%] ] X>vE/%] '' ;%] ''E J%^ 5(5(vo$%W ҔFs%F^ D'& SvFZ%\^ D \ %r^ %5%^ ^ v,^ ^ ݼ%^ 'E^F%^ Dԑ}^ ]9%'/9%_ ]''DtW%_ %mS*B_ '' FD]_ ''E*F%r_ D ͝'_ 'E%_ ''' *_ %~>m2|:e6D*_ '% %` %'MS G4@% ` '47~O9` NW` %y'7Hl`  {\*` *'3]>` ` vW`  ]6%` ` ''` %v` vǕ gvF%a D@%% ZF@%$a D K*F'Ia ''D L\%da %% l\a%za %EXF%a 'Egn%a %E;nx%a %EHKa a a vh+va V Wk%a *jdup\% b %E*oq%*b %%%Eo%Ib %Ib vOb > dk%yb ''?yb v?<kb ? sok'b % Zp%b b vˏ \p%b b "p%b b wpƎ O\nc %]' p%7c b 7c v=c  GFd%^c D'm p^%tc  kIpac vector::_M_insert_aux ^pY%c c Lv<+c ^ 5%c L $F2Dd %' dHF=%*d %D*H%Gd 'DO\[Zd % 7\hzd %'Eq֍d ֍|:% \%d |:wAS\֍ \%d ' a\'%d 'CCp֖%e ]]9%'e )}F*\e ]a5a5%|`RNe ]y'E2nv%e % +pd%e ]E7*e ' Ab%e %e e ve 84v84wn\%E\dr94f '%%%EsQ%Yf Yf %mvE^'rL%yf 'ETb%f f vETt%f %%mf 9%)f L(f  ]2% g ` '%/F']''D% U$ > 9: ; : ; : ; : ;  : ; : ; (  : ;  I8 9: ; .?: ;I</II.?: ;I<: ; I.?: ; n<&I.?: ; nI<.?: ;nI<.?: ;nI<.?: ;nI<: ;I.?: ;n<.?: ;nI< : ; I8 2 : ; I2 .?: ; 2 <dI4 .?: ; 2 <d! : ;I8 ".?: ;<d#.?4<d$ : ;I?2 <% : ; I8 & : ; I?<'.?: ; nI<(.?: ; nI<d).?: ; n<d*.?: ;n<d+.?: ;nI<d,.?: ;nI<d-.?: ;nI<..?: ;2 <d/.?: ; 2 <cd0.?: ;nI2 <d1.?: ;nI2 <d2.?: ;n2 <d3.?: ; nI2 <d4.?: ; nI<5/I6<7 : ; 8<9 : ;2 : : ;I?<;.?: ;2 <d<: ;I2 = : ;I?2 < > : ;I?2 < ? : ;I?2 <@.?: ; L 2 <dA.?: ; nI2 <dB.?: ; nI2 <dC.?: ; <D.?: ; <E.?: ; I<F.?: ; I<G.?: ; <dH.?: ; n<dI/IJ.?: ; nI<dK.?: ;nIL M2 <dL.?: ;n<dM : ; N : ;O9P4: ;I<Q:: ;R : ; S.?: ; nI<T.?: ;2 <cdU.?: ;L 2 <dV : ; 2 W : ;X : ;2 Y0I Z : ;I8 2 [.?: ;nI2 <\.?: ; <cd].?: ;<cd^<_.?: ; 2 <d`.?: ; 2 <cda : ; 2 b.?: ; n2 <dc : ; d : ; I8 2 e.?4<df.?42 <dg : ;h.?: ; n2 <di.?L 42 <dj.?: ;I<k4: ; nI?<l4: ; I<mn.?: ; n<o$ > p Iq : ; nr : ; s : ; ItIu!I/ v Iw.?: ;I<x : ; y9: ; z.?: ; I<d{.: ; I<|:: ; } I~.?: ; I<  : ; n : ;  I8 &! : ; I8 I: ;  : ;I 8  : ;n9: ; : ;.?: ;2 <d : ;.?42 <d: ;I2 .?: ; nI2 <.?: ; <d.?: ; n2 <d.?: ; nI2 < : ; : ;I : ; I?2 < : ;I8 .?: ;nI2 <.?: ;nI2 <.?: ;nI2 <d : ;I?2 <  : ;  : ; 2  I8 42 .?: ; nIL M2 <d.?: ; nL M2 <d.?: ;n2 <.?: ;n2 < : ;.?: ;nL M2 <d.?: ;nI2 <.?I4<d : ; : ;2  : ;I8.?L 42 <d.?: ;n2 <d.?: ; nIL M2 <d : ;2 .?nI42 <d.?: ;n2 <d.?: ;nL M<d9.?: ;L 2 <d.?: ;<.?: ;</.: ;I<.G<.: ;I<.: ;<.?: ;n<.: ; <4: ;nI?<4: ;I<4: ; nI?<4: ; I<4: ; I<4: ;I< 4: ;I<4: ;I<4: ;I<4: ; I< 4: ;I?<4: ; I<.?: ; I2 <d.?: ; I2 <d.?I42 <d.?: ;I2 <d.?: ;I2 <d.?: ;n2 <.?: ;n<d.?: ;nIL M<d.?I42 <d.?: ;nIL M<d.?: ;nL M2 <d.?: ; nL M2 <d.: ;I<.?: ;L <d.: ; I< : ;  : ; I: ; : ; .?: ;I : ;I.G dI4.G  4: ; I.G: ; d.: ; I 4: ; I5I: ; I: ; I.G: ; d: ;I.?: ; I .?: ; 4: ;I4: ;I.G .G: ; dId  .4 .1n@dB1.1@B1BB.G@dBI4I4.G@dI1X Y1 41: ; IB1.1n@dB1X Y1RUX Y1RUX Y1RUX Y  UB11X Y 11X Y .1@dB.1@B1 .1@dB1RUX Y 1  1.G@B: ;I U4: ;I4: ;I: ; I4: ; I4: ; I.G: ;@B: ;I: ;I.1n@B.1n@B41: ;I4: ;I.G: ;@dB41.1n@d4: ;I .G@dB.G: ; @dB: ; I.G@B4: ; I.G: ; @B4: ; I!I/.G;@B41 1.G@B4: ;I.G: ;@B.G: ;@dB: ; I.G: ; @dB1B 1RUX Y4IB.4@B14: ; I?<4I?4<4G4G 4G4G4G4G4Gn 4Gn4Gn 4Gn4Gn.?n4<.?nI4<.?I4<.?4<6.?4<.?I4<PP%101NP(1R1GRGJrJNR:NQUa0axPXaRaqRqtrtxRatrtxQ0PRRrR0PRRrR"RHLu#HLSLbSbeselSSR^PlxVxzuz~VpxVxzuz~RRS "0"1S18s8JSJ#ar0rSsSd#0SsS#0!S!(s(:S:#Qb0bqSqxsxST#0SsS#+W+VsS# p2&1#+vAVV{WAVV{VLOsOTSTV# p2&1DV#V{vWVsS# p2&1#vWVsS# p2&1#v1FFkW1FFkV<?s?DSDF# p2&14F#Fkv0WwWuUWVsS v p2&1v0?P?_V_`P0?p?_v_`P#l:HSHNs|N^SNV;A`kPk{S{WPSP`RQRQ`0S0`0UuU0k{S{WPSPPSsS/s/7S9TS0VvV)v~)3V9UV`PP`RR`pP#m{ m{p pQ p-#$o$(R(-o(P(S())FSFG(s()#)FsFG#4o48R8Go#P)8Pawab#KVS;S;@st@_S#S#'st';S;Dst#s#'s|';s;Ds|'o-8o8?R?Ko'P-?PKawab#KS w w<K`VOS w w<O[V jWjkjwjk#KVS;S;@st@hS#S#'st';S;Dst#s#'s|';s;Ds|'o-8o8?R?Ko'P-?PKjwjk#KS w w<KiVOS w w<O[VBVS2S27s|7VSSs|2S2;s|o$/o/6R6BoP$6PBXWXYBJ ww4BWVFJ ww4FRVRzWz|R|WR Wp{uT{|tP|uTtP uT&V&*S*5V:XVVV VPS<s<LSsSs {uT{|tP|uTtPuT uTR(sv*5svRsvsv(V*5VV V<WW W<  P<ud ud <uT uT<ud<u`9P<  <XVV<zWz|R|WRW<XxSx{u`{|t\|Su`t\Su`X{uT{|tP|uTtPuTgxSx{u`{|t\|Su`t\j{ud{|t`|udt`jtPtxs<x{u`<{|t\<|Pu`udRudPu` R  u` PP{uT{|tP|uTtP uTuTu_Ru_P  P P B RB W R B QB H8 B 0t U P uw" P uw"a Sa V Y p Y V Z p Z V P V  P ' V' ( P R S p#  P ' V' ( P p# -S-?SFTSWYSu@VFUVWtV u@VFUVWtV u#4vWtv*4 T4@VFUV4; vv4FU vv44EPFWP8; vv48EP[c vv4R_c vv4_gRA s us t tt uA s us t tt uA s us t t t uA s u s t tt u A D PD q Sq t pt S R R s r r s# o o R o P P  S R S  : ( :G R :  S ( SG R S   S ( S  :  S@ \ \ d px@ `  0 P R R r Rpu #t#u #Svu#t#vu#t#RP39D-9D )P)-rt9BPBDrt#8Q9DQ39D -9Dl&ud&)\):ud:=\=qudoSRV&uT&)L):uT:=L=quTSu o&ud&)\):ud:=\=quduSs#S)7S7PVQQuPdpr"uPptuPptpuP"&ud&)\):ud:=\&uc&)[):uc:=["P"&ud<&)\<)0PDNucNRRRqucDRPYcuccgRgqucYgPu #P$QudQR\Rgudgh\ud'OVReVV'(s@QudQR\Rgudgh\CQucQR[Rgucgh[C_PPuTsWWVVPPPuTpuTuTucRucPPttttttt p t# RRt$t# t# t# t# t# t# t # RPtt%&t&'t'(t(-t-2t p,t#,R%1R12t$t#,t#,%&t#,&'t#,'(t#,(-t#,-2t #,RKw # NVw$#$QUQVw$#$QYVYSslSY}S}slSslYms s f__R_R_fpPPmzsss__R_sPPY}s}s|ss|Y__R_R_R_YcPcms<Pv # yWyv$vUyWyv$WgSglsll}SS!sl!gSgpsl s 7Ds !_=L_LPRPd_dkRkp_P=PP sQ^s!_Wd_dkRkp_!PWkPs!s|!gsgps|!_'2_26R6L_LPRPd_dkRkp_P s<'6Psv,#,yW#0yUyWSsxSSsxSsxSsxSsx__R_PPss|ss|__R_R_Ps<P0BSCVCDDOVOPCv CD# Y# w # Ya0aV\SSjvRvwsw{rdpvRvwsw{rdpvrv{Rt# w # 0VSSRsrdRsrdu.#T.2v24#T0.W)S)1S RR&.vI~#T~v#TIQ0Q~WLySySZhR`hRv~wR# r 0R0PPplPr R# r 0R0PPplPr hPUSUVvVWu#WXt#XShpsPUsUVv#VW u##WX t##Xshpsphopovpv}p}p46s46@P@Us4UVv#4VW u##4WX t##4Xs4hpsPUsUVv#VW u##WX t##XshpsPUsUVv#VW u##WX t##XsopsPUsUVv#VW u##WX t##Xsopspovpv}p}p46s46@P@Us4UVv#4VW u##4WX t##4Xs4vpsPUsUVv#VW u##WX t##Xsvpspv}p}p46s46@P@Us4UVv#4VW u##4WX t##4Xs4}p46s46@P@Us4UVv#4VW u##4WX t##4Xs4}pspsPUsUVv#VW u##WX t##XsXPUsUVv#VW u##WX t##XsPUsUVv#VW u##WX t##XPUsUVv#VW u##WX t##XsPUsUVv#VW u##WX t##3X36s46@P@Us4UVv#4VW u##4WX t##4`juwjnRnuw`nPuuwRuwuPuwRuwPuwRuwPuwRuwPuwRuwP +S2S),s,6P6+s2s)+2<FPF+s2s<+2RUsU_P_+s2sR+2eoPo+s2se+2{~s~P+s2s{+2s4P+s42s4+2+s42s4+uw2uwP2?P+sBs+uwBuwPBOP+sRs+uwRuwPR_P+sbs+uwbuwPboP+srs +uwruw PrP+ss+uwuwPPuwRuwPuwRuwPuwRuwPuwRuwPuwRuwP uw RuwP@OORPRRs # s SSs|sPs|pd0"P"#[VVvSpuPwSVVwV10kw1VVS6=PstdsGYP0dfPfjS6R6#r#EGPGY#GRGY# r # YjR1=P),P,0#$0Y\9[0[\Vy \9y @[R#$C[r #$#T[\y \[y #$[g\2$s"gt \2$r" p2$r"[y   #$#`0! U4 y UWP! W4 y WP! W4 y Wp P ! w4 y w 0 Q u u 0 Q q !u!!#!#!u !S!#!S S!#!S P!!P R!!R!#!s 1!#!1 q4!!q4R!!s!!#!!s!!P!!u!!p!!u!!u !!P!"S"h"Sh"j"sj"z"S""S!!P!!u ! "V"b"Vb"s"Q""Q!A"u j"s"u " "Öj"s"Ö#"b"Vb"s"Q""Q."s"W""WQ"b"""Q"Y"pr"["s"W""W["e"pt""pt""W""pt""pw"""ug""R""ug""P""""S""t""`#8#S"##:#W:#;#"#"#""S""t""`#8#S$#:#W:#;#####S####$$P$$$-$P-$1$###$R$$R$5$R`$j$j$k$Pp${$$$$$$$P$$#$$$P$$#$%%P%%#$1%4%P4%8%#$Q%T%PT%X%#$q%t%Pt%x%#$%%P%%#$%&S&&S&%&s~&&S&%&s~;&Q&SR&^&S^&f&s~f&j&R&^&S^&f&s~f&j&}&&S&&#$&&2$v"}&&s&& #$#`&&R3s34#4}s}~#<o<@R@ToTXRXtotxRx~oP"s<4@P"s ANs 4oGToTXRXtotxRx~o%PGXP"/sYfs(4o_totxRx~o(4P_xP%s%&#&UsUV#4o48R8LoLPRPVoP!s<&8P%S%&9USUV&o>LoLPRPVo&P>PPN'X'#N'X'0N'X'#''P''Pw'' '' w''P''S''S'(0(H)U])t)U ((#T(H)\#T])t)\#T+(H)W])t)W+(A(0A((1((Q()1)')Q])t)1+(A(0A(2)S])t)SA((V()V])t)VX((V])g)VX((v ])g)v z((V])g)Vz((v ])g)v ((P()Wg)t)W()wg)t)w()Wg)t)W()wg)t)w()P))0)-*S)-*#T* *P *)*s2$w")*-*s2$w"**0*"*P* *p *"* s2$w"#|**P**S**P**s**tp*+s++tp+7+s++P+,uP,,tL,,,uP\,i,uP, ,R ,,,rz+,,7<,,7z++V++t++t+,u`,,t\,,,u`<,,u`+,,7<,,7,,7+,V,,ud,,t`,,,V<,,V,,V,,ud,,u\,,R,,u\,,P++S+,u ,,t,,,u <,\,S\,i,u i,k,Sk,,u ,,S,,u +,V,,ud,,t`,,,V<,,V,,V++S+,u ,,t,,,u <,\,S\,i,u i,k,Sk,,u ++W+,u\,,tX,,,u\<,\,W\,i,u\i,,Wk,,u\q,{,u[{,,R,,u[q,,P+,V,,ud,,t`,,,V<,i,V+,u[,,tW,,,u[<,i,u[++P<,G,P+,u`,,t\,,,u`M,i,u`+,ud,,t`,,,udM,i,ud++PM,V,P+,u\,,tX,,,u\\,i,u\+,u\,,tX\,i,u\+,ud,,t`\,i,ud++P+,st\,f,Pf,i,st,,ud,,u[,,R,,u[,,P,,u`,,u[,,R,,u[,,P,,P-"-PE-J-PJ-q-SN-m-SN-m---h.p.R//#/'/'/,/P,/./t./4/4/>/#/(/@/o/0o/u/RC/G/G/L/PL/N/tN/T/T/u/C/H/^/o///P/ 0P0000W00!0T0ST0_0s_00S2040P400V002040P40T0VT00P0000W00W0020000W00V000000W00W0011[1S[1^1u_^1a1t_a1y1Sy1|1u_|11t_11S11u_11S11u_11\1V\1a1Pa1z1Vz1|1u|11t11V11u_11R11u_11PK1[1S[1^1u_^1a1t_a1y1Sy1|1u_|11t_N1^1u_^1a1t_a1|1u_|11t_N1Z1PZ1[1s<[1^1u_<^1a1t_<a1r1P11u_11u_11R11u_11P11P2)2P11V12u 22t242V4252u 5282t82P2u U22u 11v12V22ut22tp82J2VU2W2VW2n2utp2r2Vr22ut12S22u22t82J2SU2W2SW2n2up22S22ur22S22uw22us22R22usw22P 22V22ut22tp82J2V 22us22to82J2us 22P82G2P242V4252u 5282t232S3282PW2n2ut]2g2usg2k2Rk2n2us]2k2P22u`22W22u`23X3'3W'3(3u`(3+3t\+3f3W22S22ud23\3%3S%3(3ud(3+3t`+3-3S-3K3udK3M3SM3d3udd3f3S22S22ud23\3%3S%3(3ud(3+3t`22W22u`23X3'3W'3(3u`(3+3t\22S22ud23\3%3S%3(3ud(3+3t`22S22u`23X33S3(3u`(3+3t\22u_23W3(3u_(3+3t[22P33P22u`23X3(3u`(3+3t\22ud23\3(3ud(3+3t`22P22u`<23X<33P-3K3u`33=3u_=3A3RA3K3u_33A3PM3d3udS3]3u_]3a3Ra3d3u_S3a3P33P3 4P~33P33u 34u #424u l44u 33V33t33t33V33up33V33up33h3 4up 4#4h#424V24l4upl44V33up3 4up33V33t33t33ut#424utl44ut33up33V#424Vl44V33ut#424ut33uo#424uo33P#4/4P33up33h4 4up 4#4hR4l4up33S33P44S4#4PR4j4ST4j4SY4c4utc4g4Rg4l4utY4g4P33up33h4 4up 4#4h33ut33l4 4ut 4#4l33P33up<33h<44P3433up34V44R4up:4D4uoD4H4RH4R4uo:4H4Pt4~4uo~44R44uot44P44P4444P4B544P4444S44V44t44t44t44t 44P4B54 5V 5(5p(5*5V*5B5p4 5S 5(5(5@5S@5B5*5@5S@5B5/595o95=5R=5B5o/5=5P45V45o55R55o45P 5(5p55o55R5(5o55P^5u5Vu5w5uw5x5tx5:6V56W55W55u`56W66u`56u_55P55P55u`55ud55P66u` 66ud 66P)636u_3676R76:6u_)676P^66u66t 6,7u,7/7t /7u7uz77u^66S66ud66t`6)7S)7,7ud,7/7t`/7O7SO7z7udz7|7S|7~7ud~77S77ud77S77ud77S77udk66u66t 6,7u,7/7t /7d7u~77u77uk66V66u`66t\6*7V*7,7u`,7/7t\/7d7V~77V77VO7d7u`U7_7u__7c7Rc7d7u_U7c7P66S66ud66t`6)7S)7,7ud,7/7t`/7M7S~77S77ud77S77ud77S77ud66u_66t[6,7u_,7/7t[/7M7u_~77u_77u_66P:7G7P66u /7:7u 77u 66u <u`<660/7:7077066ud/7:7ud77ud66W/7:7W77W77u_77R77u_77P66ud/7:7ud66u_/7:7u_66P/777P66u`77u`66ud77ud66P7"7P67u 67Wd7q7udj7q7u_j7q7P77u`77u_77P77ud77u_77R77u_77Po8u8Ru88o8888S869S819:88S819S89:89S88P919x9|9P|99U99P99V99099P99P99099S92:S2:3:P3:C:S::S :(:s;:C:S::S::ug::R::ug::PJ:q:S::SU:q:s::s^:q:ug::ug^:e:P::P;o;U;S;V;%;S;B;SB;G;s|G;o;S%;+;S+;/;s|/;B;SB;K;s|%;/;_4;?;_?;F;RF;S;_%;/;P4;F;PS;o;US;[; uu4S;o;VW;[; uu4W;c;V;<<<V<<<4<V; < <<S<4<S;<<<W<4<W;;P;;R;; ? ;;c;;;<i;<<<V<<T<<P<B=B=J=PJ==T<<p<B=#B=J=pJ==#s<<P<B=B=J=PJ==s<<p<B=#B=J=pJ==#~<<R<<\B=g=0~<<S<6=B=g=Sg==~<<R<<\B=g=0B=g=SR=g=1R=^=RR=Y=r<B=g==<<S<6=g==<B=g==<<P<:=Sg==S<=V==V<:=Sg==S<B=g==<:=Sg==S<<=Wg==W<:=Sg==S< =W==0==S==1==R==r =:=Sg==S==S =B=:g==:==: =(= ss<"g=x=sp"==sp"=;=Vg==V==V=B=:g==:=;=Vg==Vg==:g==V2=A=P==P==>>==P==>>=>=>R>>'s$'2#$2Cs$<o<@R@CoP2@P'S'2X>_>P_>?S??u??t??SX>~?W~??s4??u#4??t#4??W??t??u>?S??u??t??S>>P>>Q>?ud??t`??ud??s??ud!??H??H!??V??u# ??t# ??V??s h??v$??u#0??t#0??v$??s0o?r?s0??s4??S??u??t??u??t??A??W??ud??t`?? wud<"??A?? wud<"#@QAuTQATAtPdAAuT?l@u TAAu ?l@u #TAAu #@@P@@u #!@TAdAA!@QAudQATAt`dAAud!@1@ud#1@6@P:@x@x@@@@@TAdAAAAAA:@QAudQATAt`dAAudB@\@WB@J@ud#R@V@pV@[@PdAAudb@TAAAb@o@po@t@Px@@@@@TAAAAAx@QAudQATAt`AAud@@V@@ud#@@p@@PAAud@@@@ud@@ud#@@p@@P@@@@ud@@@@p@@P@TAAA@QAudQATAt`AAud@@ud#@@p@@P@TAAA@QAudQATAt`AAudA ASA Aud#AApAAPAAud#AQAudQATAt`7AQAudQATAt`7ATA0RQSQvRvySyRQUuTUvQvuTQ#Q|#QW?Q?HPTvTvudududt`vvudPPPududt`ududt`00ud0A&BP&B+Br+B3BP:CCCPCCKCrx B&BP&B+Br:CCCPCCKCrxvSvwvtwyuT4yztP4zSvtuT4tP4SvtSvtvt>xWxyuyztzWutWWWSyudyzt`zudt`ududSVw#hyudyzt`zudt`kyucyzt_zuct_kPuducRucPW0KKPKLVL"MVMPNVNNV*OXOVOOV K&KP&KYLSLMSM NSpKLDNND*OXODOODpKLWNNW*OXOWOOWpKKw#KKPKLk NNk *OAOk OOk KLWNNW*OAOWOOWKLpNNp*OAOpOOpKLWNNW*OAOWOOWKKpKKPKLX NNX *OAOX OOX KLWNNW*OAOWOOWKKpKKPKLtNNt*OAOtOOtKLWNNW*OAOWOOWKKpKKPKLk NNk *OAOk OOk KLWNNW*OAOWOOWKKpKKPKLNN*OAOOOKLWNNW*OAOWOOWKLpLLP LZL-ZLLNN*OAOOO LLWNNW*OAOWOOWLLNN*OAOOOLLWNNW*OAOWOOWL&Lp&L+LP2LLX NNX *OAOX OOX 2LLWNNW*OAOWOOW2LY?Yt?YCYtmVVu~VVPVXu~XX~XYu~VWu~WWVWXu~XX~XGYu~hYYu~hYYu~VGYHVMWu~MWiWPiWtWttWxWtxWXu~XX~XGYu~aWiWp$iWtWt#$tWxWt#$xWXu~XX~XGYu~sWxWu~GYMYu~MY_YP_YhYu~W Y0WWVWXu~XX~X Yu~W Y0WXVX YVWWvXX XY XXVXYVXXQXXu~XXRXXu~XYu~YYQYYu~XX XY XXQXXu~XXRXXu~XYu~XX XY XXu~XYu~WX2XX2WWu~WWPWXu~XX~XXu~WW upt"WW up"WX2XX2WW upt"WWup"WXu~XX~XXu~WXu~XX~XXu~WXu~XX~XXu~WXu~XX~XXu~WXu~XX~XXu~W XPXXP XXu~XX~"XXu~XX~>XXu~XX~SXXu~XX~cXiXu~iXzXPzXXu~XX~Y Zu~ ZZPZ0\u~0\3\~3\6]u~YYu~YYPYZu~ZZPZ0\u~0\3\~3\6]u~\\t\\tY Zu~ ZZPZ0\u~0\3\~3\6]u~ Z.Zu~.Z1ZP1Z[u~[[V[0\u~0\3\~3\\u~]2]u~]2]u~{Z\H{ZZu~ZZPZZtZZtZ0\u~0\3\~3\\u~ZZp$ZZt#$ZZt#$Z0\u~0\3\~3\\u~ZZu~\\u~\]P]]u~[\0[[V[0\u~0\3\~3\\u~[\0[.\V3\\V#['[v3\\ \\ 3\\V\\VC\Q\QQ\Z\u~Z\h\Rh\\u~\\u~\\Q\\u~E\\ \\ E\Q\QQ\Z\u~Z\h\Rh\\u~\\u~Z\\ \\ Z\\u~\\u~'[3\2\\2'[>[u~>[A[RA[U[u~U[`[P`[0\u~0\3\~\\u~'[8[ upt"8[>[ ur"'[3\2\\2'[8[ upt"O[0\u~0\3\~\\u~O[U[u~U[`[P`[0\u~0\3\~\\u~8[>[u~>[A[RA[U[u~U[`[P`[0\u~0\3\~\\u~A[`[RA[3\J\\JA[3\8\\8A[O[r A[3\ \\ A[`[r A[U[u~U[`[P`[0\u~0\3\~\\u~A[3\ @\\ @A[O[ r  8!i[0\u~0\3\~\\u~{[0\u~0\3\~\\u~[0\u~0\3\~\\u~[0\u~0\3\~\\u~[0\u~0\3\~\\u~[[P\\P[0\u~0\3\~[0\u~0\3\~[0\u~0\3\~[0\u~0\3\~ \\u~\"\P"\0\u~0\3\~Y]g]0g]]S]_SY]]V]]]_Vz]]R]]S]^R^^S^/^R/^5^S5^M^RM^S^SS^s^Rs^y^Sy^^R^^ps"^^S^^R^^S^^R^_S__ps"__S]]]]\]]\#]]P^^>^^\^^Q^^Z^^P]^]^\]^\#^^P^5^^5^\^*^\#*^/^P5^S^5^S^\5^H^\#H^M^P^^y^^^y^\^^n^\#n^s^Py^^S__S^^\^^r^^Y^^P^_\__r__X__P,__,__\,_6_p6_;_PB__`B__\B_L_\#L_Q_PX__X__\X_b_pb_g_Pn__`q__[__R__[q_z_Pz__`<__P__`__[__R__[__P]]\]]\]]0__\__0__0_&aS&a+as+acWcdWPb~bPb~buTPbXbuT#Xb`bp`bebPkb~bWkb~buTkbnbuT#rbubpubzbP~bccad}dd~bcuTcctPcaduT}dduT~bbuT#bbpbbPbcOcadO}ddObcuTcctPcaduT}dduTbbSbbuT#bbpbbPcduTbbbbuTbbuT#bbpbbPb"cSbcbcuTbbuT#bbpbcP ccuT ccuT#ccpccP0ccuTcctPdaduT}dduT0ccu`cct\dadu`}ddu`>ccuTcctPdQduTdduT>ctcStcuctucyctyccuXcctTd-dS-dQduXddSdduXEccuTcctPdQduTdduTEccWdQdWddWOccVccu\cctXddQduX>dQd0cc0dad0}dd0ccu`cct\dadu`}ddu`)cc0dad0}dd0)ccudcct`dadud}ddudccu`cct\-du~>bPbu~t~u~7u~Rbp$bu~t~u~7u~\bu~7Ru~ku~Qu~t~u~u~kPttPu Qu~u~u~u~u~u~u~u~u~u~PPu~u~Ru~Pu~t~u~u~t~u~u~t~u~u~t~u~u~t~u~PPu~t~u~t~5u~t~Ju~t~cu~t~.r8r1.r8rS1r8r01r8rsrrVrru_rrPrrPrrudrru`rrPrrudrru_rrRrru_rrPrru_rrRrru_rrPss1ssSss0sssbssVessu_eslsPssPlssudrssu`rssPssudssu_ssRssu_ssPssu_ssRssu_ssPssPstUttPssRstWttRssQstVttQss0 ttp1)ktotp1)ss0 t>tS>tktsktotSs tQt,tQ,tot\t,tQ,tot\8tot8totVKtot/KtotVottVttQttSttttSttttRttttRttttPttttPttttttStttuSu"uP"u#utuVu"uQ"u#ut#u!t uP#u@uV@uAuzu~z}P}u~t~u~ u~ Wu~t~W34t48t\zu~z}P}u~t~u~u~Pu~Qu~t~u~<u~Wu~Wqu~ H H<HqH=u~=bPbu~t~ u~ u~<u~qu~Qbp$bu~t~ u~ u~<u~qu~^bu~<Wu~ku~Qu~t~u~ u~u~qu~kPttPu Qu~u~ u~qu~u~u~u~ u~qu~u~u~u~u~u~RRu~Ru~u~u~ p|u~4u~#p|u~4 p| p|u~4Qqu~u~zu~u~zVV vu~t~u~u~t~u~u~t~u~u~t~u~u~t~u~ PP u~t~&u~t~<u~t~Qu~t~ju~t~uu1uuSuu0uusuvVuvu_uuPvvPuvuduvu`uuPv2vudv$vu_$v(vR(v2vu_v(vP:vDvu_DvHvRHvKvu_:vHvPPvzvzv9wV9w>wv>wOwVTw~wVwwVSvvuevfvwzvvSvvSAwNwSbw~wSvvSbw~wSvvQvvuTbw~wuTvvbwuwvvpr"vvuTbw~wuTvvptbw~wptbw~wuTbw~wptuw~wpuT"wEwudTwbwudwEwu_Twbwu_w&wPTw_wP&wEwu`,w6wud6w=wR=wEwud,w=wPwwudwwu_wwRwwu_wwPwwu`wwu_wwRwwu_wwPwwu_wwRwwu_wwPMu MPP_u MutMPlPnut(MutMPl7MutMPl7P0wwRwRxuTRxSxtPSxxuTxxtPxxuTwwQwxQwwVwwtwwtwRxu`RxSxt\Sxxu`xxt\xxu`xxxxxPxVPxRxudRxSxt`Sx~xV~xxudxxt`xxVxxVxOxSOxRxQuR1)(RxSxQtR1)(Sx}xS}xxQuR1)(xxQtR1)(xxSxxQuR1)(xPxVPxRxudRxSxt`Sx~xV~xxudxxt`xxVxOxSOxRxQuR1)(RxSxQtR1)(Sx}xS}xxQuR1)(xxQtR1)(xxSxxQuR1)(xQxWQxSxPSxxWxxPxxWxxu_xxRxxu_xxP2xPxVPxRxudRxSxt`Sx~xV~xxudxxt`5xRxu_RxSxt[Sxxu_xxt[5x?xP?xIxv<Sx_xPuw>BRBLuw4BPP&u &)t);P;Hu HKtKu u )/K/ՁVՁ&u\&)tXKyu\y{V{u\VudRudP$V$&ud&)t`KyVVƂud݂V#S#&u&)tKySSƂu݂߂S߂uSu[Ru[P$V$&ud&)t`KyV&u[&)tWKyu[PYgP&u`&)t\KYu`jyu` &ud&)t`KYudjyud PjvP&u\&)tXKYu\&ud&)t`KYudPKVP)HuHKt )ESEKP{u\u[Ru[PƂudu[łRłƂu[łPƂ݂u`̂ւu[ւڂRڂ݂u[̂ڂP@NPNVWcPcVVNQSQTu`TWt\tSQTuTWttuQ\PP\Tu\TWtXtu\bTu`TWt\tu`bmPPmTuTTWtPtuTsTu`TWt\tu`s~PP~TuPTWtLtuPTu`TWt\tu`PPTuHTWtDątuHTu`TWt\ątu`Pą΅PTuDTWt@ԅtuDTu`TWt\ԅtu`PԅޅPTuTWttuTu`TWt\tu`„PP„TuTWttuȄTu`TWt\tu`ȄӄPPӄTuTWttuلTu`TWt\tu`لPPTuTWttuTu`TWt\tu`PPTuTWt$tuTu`TWt\$tu`P$.PTu@TWt4tu@ Tu`TWt\4tu` P4>PTuLTWtHDtuLTu`TWt\Dtu`(PDNP(TuXTWtTTtuX.Tu`TWt\Ttu`.9PT^P9TudTWt`dtud?Tu`TWt\dtu`?JPdnPvu`|uRu|Pu\uRuPuTuRuPʆuPņuņɆRɆʆuɆPʆ߆uHІچuچކRކ߆uІކP߆uDuRuP uuR uP uuRuP3u$.u.2R23u$2P3Hu9CuCGRGHu9GPH]uNXuX\R\]uN\P]ru@cmumqRqrucqPruLxuRuxPuXuRuPuduRuP#guDgWuDىuDىWuDt@BuDBYWYuD6QuDuDagWghthltluLىuLBYuLaguDgWىWBYWsuLىuLyVىVyPىPuHudPuDuDt@uDpuDuDud\udt`udpududud\udt`udu`Xu`t\u`ȈPPȈuDuDt@Έud\udt`ΈވPވuD<<P;AWABtBFtFu`ىu`u`;AuDAWىWWMu`ىu`SVىVSZPPZu\ىu\`udىud`gPPguXىuXmudىudmtPƉPtuPɉىuPzudɉىudzPɉ։PuTudP$uT$ud$P$BuD*4uC48R8BuC*8PDYuLJTudTXRXYudJXPYfuH_fud_fPrudxu`Ru`xPu`udRudPu\udRudPΊuXɊudɊ͊R͊Ίud͊PΊuPԊudRudԊP+202NWNWRWWRԋWVPԋV2NVVP2Nuut2<v2Nugutԋu2NVgVPԋV2Nutut2NuwuRutwPVuRuPË͋u͋ыRыԋuËыP%4%+W+,t,0t0uXuX4uX44`w4WW4`WwWW}u\udPO4KOVV46V6KudVud[[uuuuWRuWPnVVquWuWqxPPxu\u\~udud~PPu`u`ududPPuXŌόuXudȌόudPȌՌP4uX&uW&*R*4uW*P6Kud<FuWFJRJKuW<JPK`u\Q[uW[_R_`uWQ_P`wu`fpuWptRtwuWftPVV=VKSSS":"KSS:S>EPudt`udt`=udIVVISPSSSWWSSgWWgSSkW0S1RrSSudt`udt`uct_uct_PP%/uc/3R3=uc%3PnǏǏSՐSSՐ0Ր1ƐϐPƐɐRǏӏۏuۏߏPӏ֏P֏SwSsw#ss)+P+uDt@)uLtH)sw#PܑPPzQd@kS;v P!;v !*P\}4P4yS|~SL|<P<SSTP,V/DPDV\#5V%u G"asrrPWs ʓCCDCSCPuTCdCuT&C@K$6Cb6BPu3Ŕ30<S<DPD0'S'{0{S0IKSb0ƚ0+eIeƚeCuCDtD+uIuƚup"P&CuCDtDuIuƚu.HV.6u#>BpBGPZ{uZ{0Zpu#puPNZr{rIrƚrN[p[`Pƚޚuƚޚuuu@uÕu#ǕʕpʕϕP֕u@ٕu`ٕPHZp0)^u'ZuޚuakP'9P9<s<DpXakR'DR'9P9<s<DpX'DR~ޚ~uPuޚuuPurPSƖƖSܖuHܖSܖߖs#uHu`PΙuPΙu`ΙPSΙSӘӘu\ייu\՘u\u\Ιu\ u\Ιu\ u\Ι0 0h}u\h}0)Ι )Ιu uBΙBΙuuVΙuLuLVΙuuVYu#]`p`ePlΙrrlΙuulvpv{PΙΙuupPΙuPuPΙuuu#pPΙuLuLΙu`u`PP uLu` R u` P uPu`Pnttnuu4n4nuHnuHnuHKu#ORpRWP^nuanu`anP}u}uїїuuDuu#pPuDu`PuDu`Puu`PȚޚu@Κޚu`ΚޚPCuCDt'u{uIXuAVACuXCDtT'V{VIXVD'{IXAVACuXCDtT'V{V Cu`CDt\'u`{u` P{PCuCDt'uD0'0)CuCDt'u/Cu`CDt\'u`/<PP+u+0+Iu1;u;?R?Iu1?PKXuXQXu`QXP,uwu,Lu# LMt# Mvu# vwt# 2LuwLMtsMvuwvwts2<P<Fs <MWP9Fu#Xeu#?Fuw^euw?MP^oPuwRuwPuwRuwP VSYS,SS,Vs Ys 2XuwXYoYuw2<P<Fs <YgP9Fshus?Fuwnuuw?FPnPuwRuwPuwRuwPcu#ru#t#u#$kSrSS2ESSEks rs KkuwruwKRPPRksrsXkuwruwX_PrPuwRuwPuwRuwP |V~Vu|v~vu#$kS~SS2ESSEks ~s Kkuw~uwKRPPRks~sXkuw~uwX_P~PuwRuwPuwRuwPSu 9u PTu X\u u u HVHu\TV0u\09V9Ou\OPTPu\Vu\Vu\u\udRudP<HVHu\V0u\PTu\Xdu\u\u\<S0SPRSRTuX\uSQcVHu\u\u\xsPWs 0PTXd 0u\T9Ou\OPTud\9OudOP\P9GPdyu\jtu[txRxyu[jxPpu pqtqu u pu #pqt#qu ##u # oVqVV &S&'t'+t+puppqtlquphup,oVqVV,nSnputpqtpqSutlSutSutDnSnputpqtpqSutlDLPLpupqtquSnSnputpqtpqSutlVpuopqtkquogV`P`js<qP]jupupcjSutcqPPutuoRuoPuoRuoPpu pqtqu tu pu #pqt#qu #t#u # oVqVV &S&'t'+t+puppqtlquptlup,oVqVV,nSnputpqtpqSuttpSutSutDnSnputpqtpqSuttpDLPLpupqtqutSnSnputpqtpqSuttpVpuopqtkquotkV`P`js<qP]jupupcjSutcqPPutuoRuoPuoRuoP.u u SSs~Ss~$VDSud\SSudDVVVUSud\SXu_Wu_XbPbls<P_lWu`elSudelPPlvudu_Ru_Pu_R u_P#MS?ASegS.W.Hu HItI>u >??u 1u .w.Hu #HIt#I>u #>?#?u #1u #]?FUYei1]cScdtdhthHuHHItDI>uH>?@FUuHYeuHiuH1uHl?FUY]aei1lSHuLHItHI>uL>?DFJuLJLSLUuLY]uLacSceuLiuL1uL *ud*.R.1ud .PGWGHudHIt`I=W=>ud>?\FJWi~WHuHItI>u>?FJui~uGWGHudHIt`I=W=>ud>?\HuCHItI>uC>?Pw<IWPSXiu\W^iudP^vPuXwuXud}udP}PuLuLududPPuHuHududPPuDuDudud"PP0uTuT%0udud%3PP0Au`(u`6Aud(ud6IP6Pi~udoyuCy}R}~uCo}P~u\uCRuCPuXuCRuCPuLuCRuCPuHuCRuCPuDuCRuCPuTuCRuCPu` uP RuPP&USUWutWXtpXSuttpSut&WuWXtXutu:USUWutWXtpXSuttp=WuoWXtkXuotk=GPGQs<XgPDQVhuupJQSnuutJXPn~PutuoRuoPuoRuoP dSdgughthϛSϛЛuPeVhPݛVʛ!ds dgu# ght# 6ds,dgu#,ght#,)u#)*t#*u#t#u#!DPDSS\ 4S8SuP4s8su#"$P$5V8TPTVlP?S?CPCȜSpP?s?CpCȜs&(P(AWCKPKȜW`Ȝtܜߜs ߜVڝVݝVܜߜs ߜVڝVݝVPuTtP4P4ܝuTܝݝLݝuT5|ݝL||ݝV|ڝVVP|PٝSSݝݝs [V^V FVs [V^V FV-/P/EuT^tPtuT 3uTu 3E^R R3FRE[VV3FVQVPVZSԞPԞS38S՞ 3F \_s_VeVhV\_s_VeVhVmoPouTPuTh{uTh{ԟ Dh D{ DVeV{VPSPdS{Sh{4hsVVΡVsVVΡVPˠuTPDuTuTDDˠ8FD8FΡ8FˠVDVΡVנܠPܠSD\P\SS]ΡtߡSw`)Sw`Sw`ߡs W)WWPV)3P3VVH_)HHHWWP%SPS S,Jv,MSv,2W28S2~S~sxS8OSOSsxS~S~sx8OSOSsxh~S~sxELudmtudESPmP8OsOSs|S~s~s|8SudYcudcgRgud8BPBLs<YgPJv,MSv, v4v,8W v4v,8WJv MSv #WSSslCSͣSͣѣslѣSsls s ududPPʣs sãʣud udãѣPPͣsͣѣs|ѣss|ѣudףudR#udPs<ףP#Jv MSv #+ v(v D#KWMWW'+ v(v D'3W3JVMSVCdPdSS|,V,-t-1t1uXtTuXtTuXhuluuuuhu#lu#u#u#u#!,V,-t-1t1uXtTuXtTuX!S|SSSSSS&,V,-t-1t1uXtTuXtTuX5rrr5]V]u\tX V Xu\XlVlu\tXu\Vu\u\Vu\u\udRudPQ]V]u\ V Xu\u\u\u\QSXSSSfxV]u\u\u\sPWs X4Xu\tXlu\tXu\udt`ludt`udPPu\uWRuWPuXtTluXtTudt`ludt`PlwPuXuWRuWPR̥R̥ڥRڥHR֤ r̥ڥPr̥R#̥ڥrڥHR#R̥RڥHRr̥R#ڥHR#˥ud˥̥t`ڥudt`1HudɥVɥ˥u`˥̥t\ڥVu`t\1HV)v#).P5̥ڥ5ɥVɥ˥u`˥̥t\ڥVu`t\5?p?DPEɥVɥ˥u`˥̥t\ڥVu`t\EkWڥWELv#TXpX]PdɥVɥ˥u`˥̥t\ڥVu`t\hpQprWruThv#Pڥu`˥u`˥̥t\u`t\̥00˥ud˥̥t`udt`˥u`˥̥t\u`t\ǥPǥ˥ud<˥̥t`<P1ud#u_#'R'1u_'PSuph٦S٦ۦupۦܦhuogۦuoۦܦgPs<PutŦutSŦupPΦPަutuoRuoPuoRuoP5|u|}t}u5?R?|u |}t}u @|ut|}tp}ut]|ut|}tp}ut`|us|}to}us`gP}PusRusPħ_ul_`th` ulħԧul#ԧ٧Pݧ)a )aݧ_ul_`th`ul ulSul#pP`yul`y pP`y (p(-P4`4y4 44>p>CPG`)ay)a )aG_ul_`thyul ulOiSOSul#_cpchPyulo` o|p|P`TT TpP` pP` pèPʨ` ʨԨpԨ٨P` pP_ul_`thul ul_ut_`tput ut/]S]_up_`tlS2_uk_`tguk29PP9_ut_`tput?_up_`tlup?FPPF_ul_`thF`0ԩupũϩukϩөRөԩukũөPԩutکukRukکPul0NݪMNTWTUtUYtYu\ݪu\Mu\]ݪ0GI]WݪW0WGIW{WݪW~u[ݪu[~PݪPududu`u`PPu\ʪu\udêʪudPêЪPu\ u[ Ru[P0u`!+u[+/R/0u[!/P0Gud6@u[@DRDGu[6DPSuuu7uu`Xu`Xud\ud\Pu`<X<Pr7rWttu 7u r7rW7WΫWѫ۫u_۫߫R߫u_ѫ߫Pu`u_Ru_P5ud$.u_.2R25u_$2P1=p 1ututu.?uC\u`.9=?C\`fSfgtgkukuLtHuLtHuL.9uL=?uLC\uLo.9=?C\oSuPtLuPtLuP.0S09uP=?uPCESE\uPKUu\UYRY\u\KYP  29 =? WuXtTWuXtTW29W=?W  29 =? Su\tXSu\tXu\24S49u\=?SSu\tXSu\tX=?SPutut=?uSu\tXSu\tXuGtCuGtCPs<PW -uXS&-u\P&6PuP7DuPu\=Du\P=NPuLO\uLu\U\u\PUfPuHgtuHu\mtu\Pm~P uTuT u\u\PPu\uGRuGPuXuGRuGPuPuGRuGPuLuGRuGPuH uG RuGP.uT uG $R$.uG$P%NSN u tu t!u &7u 79S9Tu .:p0). u tutu&7u;Tu]&157;T]cScdtdhth uL tHuLtHuL&1uL57uL;TuLl&157;TlS uP tLuPtLuP&(S(1uP57uP;=S=TuPCMu\MQRQTu\CQP  *1 57  W  uX tTWuXtTW*1W57W  *1 57  S  u\ tXSu\tXu\*,S,1u\57S S  u\ tXSu\tX57SP u tut57u S  u\ tXSu\tX uG tCuGtCPs<PW%uXS%u\P.PuP/<uPu\5<u\P5FPuLGTuLu\MTu\PM^PuH_luHu\elu\PevPuTwuTu\}u\P}Pu\uGRuGPuXuGRuGPuPuGRuGPuLuGRuGPuHuGRuGP&uTuGR&uGP1S1Qu /Tu (s$.1S1Qu /Tu 1BS/9S9Ts~/9S9Ts~BGuj/T1djpSpqtqutu.uL./tHTuLtHuL1uLduLuLy/TdhlyS.uP./tLTuPtLSuPuPdhuPluPuPSuPuP u\Ru\ P/ T dh l  -W-.uX./tTTWuXtTdhWlWW/ T dh l  +S+.u\./tXTSu\tXdfSfhu\lu\S+S+.u\./tXTSu\tXP+S+.u\./tXTSu\tX.uG./tCTuGtCPs<T_PW`quXSfqu\Pf~PuPuPu\u\PPuLuLu\u\PPuHuH u\u\ PP'uTuT'u\u\/PP1uL",uG,0R01uG"0P1FuH7AuGAEREFuG7EPFduTLVuGVZRZduGLZPlu\r|uG|RuGrPuXuGRuGPuPuGRuGPZu u u u u\tX=u\Zu u u u MWW W0Vu`t\V V'=V0MWW W@Vu`t\VV'=VCudt`udud'=udCJPP u`ud R  ud PJu\tXu\u\'=u\JSPSSQu\tXu\u\'=u\`udt`udud'=udcWWW'=Wcds|udt`udu`t\u`PPPttp-:Pu\tX0 'u\ '0<V<Cu Vu u`t\u`#<V<Cu Vu #9WWu`#%9V0Wu`#1Ww?u`t\u`u`?SPSSCu`t\u`u`Rudt`ududUVVVUVsnudt`udqu_t[u_qxPPPttpudu_Ru_Pxu`t\x0?u u uptlup&up#&+P2uptlupup2SPSS6uptlupupEuttpututHVVVHIsauttputduotkuodkPPPttputuoRuoPkuptlk0<V<Cu Vu u`t\u`#<V<Cu Vu #9WWu`#%9V0Wu`#1Ww?u`t\u`u`?SPSSCu`t\u`u`Rudt`ududUVVVUVsnudt`udqu_t[u_qxPPPttpudu_Ru_Pxu`t\x08u u uptlup+uptlupup+}S}PSS/uptlupup>uttpututA~VVVABsZuttput]uotkuo]dPPPttputuoRuoPduptld0<V<Cu Vu u`t\u`#<V<Cu Vu #9WWu`#%9V0Wu`#1Ww?u`t\u`u`?SPSSCu`t\u`u`Rudt`ududUVVVUVsnudt`udqu_t[u_qxPPPttpudu_Ru_Pxu`t\x0حڭPڭ`Su SSvxS~VȭV7u7`VuVu*uvxu|VN|~NuX|~uXҬWҬuT|~uTuX|~uXuX#Pr|~ruX|~uXҬY|~YҬuX|~uXuX|~uXd|~duX|~uX 0aS V|~V*ar*auX*4p49P?aW?auXa0|~0avu`v{P{u`|~u`k0|~0kud|~udu`PudŭuXŭȭtT`ruXrutTȭ0`u0ŭuTŭȭtP`ruTrutPŭu`ŭȭt\`ru`rut\PŭuT<ŭȭtP<`gP߭70vx0߭u`P7u`vxu`70vx07udvxud7?u ?BtBFt7?sN`1N`uT`0T`u#u00uxu`xP0u`000ud0yPW0W0yVu\0VpP̮Vu\̮00u\000Au`03ud3=P=AudATuXAT0TruTZdu`dhRhru`ZhPDu u u uptlup :V (up#04p49Pup0up#P@uptlupup@SPSSDuptlupupSuttpututVVVVVWsouttputruotkuoryPPPttputuoRuoPyuptly0įRįmRm}R}RQluDlmt@muDt@uDدm00įPmuPu}uįQm}QįQįPm00u` P lu`lmt\u`m00ludlmt`udHmHNu@\m\VluXlmtTuXϱuXϱV\fqfkP}VluXlmtTuXϱuX}VްuXްjVjlu\lmtXVuXϱu\}m00ϱ0mϱu@mϱjVjlu\lmtXVϱVǰqǰ̰PްjVjlu\lmtXVްm00ϱu\ϱ0Glu`lmt\u`Gludlmt`udGm00KcWWPcu\u\PWPP}1}SP0spu`udPud  p ` ptd 3 3:p:B`BL **3p34t4BdBLPrRrRPrQruDƲrƲuDt@3uD34t@4uD040`Cu3u34t kzu`VCu 1V13u 34tkzu 040u`Pu`t\4u`040udt`4ud4Vku@ 4Vk PVPuXtT4VuXkV qP+PVPuXtT4VuX+PVPuXVu\tX4AVACuXCVu\+04V0muXm0W4VW]u@k4VkVu\tX4VVkuquzPVu\tX4AV04A0CVu\CV0u`t\4Au`udt`4Aud04A0W4AWu\4Au\P4>P410S04P#40#0s04pVku`V[ud[bPbkudRmRQ^uD^drduDt@uDt@muD$1m1ҵuut ?NuPҵu u t?Nu @0m0@Cu`CXPXu`t\mu`L0m0Ludt`mudҵu ?Nu PٵW?VWҵu ?Nu SuTtPuT(?uT?ASAmuTSuTtPuT(?uTVmuTS#uT#ASAuXSu\tXS(*uT*?uXVXuXXmu\00(?0Vm0AVuTAV0(?VmPBW(?W(?VmASAuXtTuX(*S*?uXVmuXpP#ASAuXtTuXVmuX#ASAuXSu\tXSVXuXXmu\#00Vm0*?uX*?0krPrWVmWySu\tXSVXSXmu\Su\tXS00¶u`t\u`¶udt`ud¶00ƶ޶WW˶޶u\u\˶ҶPP1VP0vp(u`udP(udзRRзQuD t@ Q0uD01t@1uD 111P PuR R0 01003u`3HPHu` t\1u`< 010<ud t`1ud}P SSSuP tL1AuPXuPuPWDuTDcScuXWu\ tX1AWXZuXZou\oquTquXuPuT 01A0X0 1AX SSɸ 1AXɸWuT tP1AuTXuTWɸӸpӸظPWuT tP1AuTXuTWDuTDcScuXWu\ tX1AWXZuXZou\oquTquX 01A0X0uT0 1AXPoWoW% 1AX%cScuX tT1AuXXouXoqSquX%/p/4PDcScuX tT1AuXXouXDcScuXWu\ tX1AWXZuXZou\D 01A0Xo0quXq0PSXZSWu\ tX1AW 01A0Zou\Zo0u` t\1Au`ud t`1Aud 01A0S1ASu\1Au\P1>P11.V.1P 10 .v.1pCXu`CHudHOPOXudֺ ֺݺpݺ` ͺͺֺpֺ׺t׺d  p ` ptd<V<Cu Vu u`t\u`#<V<Cu Vu #9WWu`#%9V0Wu`#1Ww?u`t\u`u`?SPSSCu`t\u`u`Rudt`ududUVVVUVsnudt`udqu_t[u_qxPPPttpudu_Ru_Pxu`t\x0<V<Cu Vu u`t\u`#<V<Cu Vu #9WWu`#%9V0Wu`#1Ww?u`t\u`u`?SPSSCu`t\u`u`Rudt`ududUVVVUVsnudt`udqu_t[u_qxPPPttpudu_Ru_Pxu`t\x0IY[e~[@B % %OY1OYSRY0RYsyu`ɻVɻu`t\Ru`(RVttutu(RupPutu?Ruu#W#QuQdWduWu@W0uD0CWCpuHpW̽uL߽̽W߽ uP 9W9huTh{W{uXWu\tXW?AuAXuXouou@uDuHܿuLܿuPuT6uX6Ru\0?R0*?u*?0eu`ɻVɻu`t\Ru`rudt`Rudɻ?RɻлPлV?VV׻?R׻#W#utu?VWVRu׻pP#W#utuVRu#W#QuQdWduWu@W0uD0CWCpuHpW̽uL߽̽W߽ uP 9W9huTh{W{uXWu\tXWVXuXouou@uDuHܿuLܿuPuT6uX6Ru\0VR0AVuAV0%$VR$%,P,VVV3dWdutuVmWmRu3utuVRu3<p<APQdWdutumRuQdWduWu@W0uD0CWCpuHpW̽uL߽̽W߽ uP 9W9huTh{W{uXWu\tXWmouou@uDuHܿuLܿuPuT6uX6Ru\Q0mR0XmuXm0amRaVmVsmRsWu@tu@mWRu@s}p}PWu@tu@Ru@Wu@W0uD0CWCpuHpW̽uL߽̽W߽ uP 9W9huTh{W{uXWu\tXWu@uDuHܿuLܿuPuT6uX6Ru\0R0ou@o0RPVV¼R¼WuDt@uDWRuD¼̼p̼ѼPWuDt@uDRuDW0uD0CWCpuHpW̽uL߽̽W߽ uP 9W9huTh{W{uXWu\tXWuDuHܿuLܿuPuT6uX6Ru\0R0uD0R P VڿVRCWCuHtDuHWRuHp P0CWCuHtDuHRuH0CWCpuHpW̽uL߽̽W߽ uP 9W9huTh{W{uXWu\tXWuHܿuLܿuPuT6uX6Ru\00R0uH0@R@VڿVRWuLtHuLڿWڿRuLRutuRuR[p[`PpWuLtHuLڿRuLpW̽uL߽̽W߽ uP 9W9huTh{W{uXWu\tXWڿܿuLܿuPuT6uX6Ru\p0ڿR0ڿuLڿ0ڿRP;VڿVڿR߽W߽uPtLuPڿWRuPpP߽̽W߽uPtLuPRuP߽̽W߽ uP 9W9huTh{W{uXWu\tXWuPuT6uX6Ru\̽0R0ܿuPܿ0ܽRܽ;VV9W9uTtPuTWRuTutuRupP 9W9uTtPuTRuT 9W9huTh{W{uXWu\tXWuT6uX6Ru\ 0R0uT0;R;BPBҾVRVIRI{W{uXtTuX4W4RuXISpSXRh{W{uXtTuX4RuXh{W{uXWu\tXW46uX6Ru\h04R04uX40x 4R xҾV4RVWu\tXW4RWutu4RupPWu\tXW0վu`t\u`վudt`udվ0ݾVVu\tXu\PP(u`udP(ud<V<Cu Vu u`t\u`#<V<Cu Vu #9WWu`#%9V0Wu`#1Ww?u`t\u`u`?SPSSCu`t\u`u`Rudt`ududUVVVUVsnudt`udqu_t[u_qxPPPttpudu_Ru_Pxu`t\x0~1~S0s010u`Pu`1u`010ud1ud1PhW1W 1 V1V *p*/P?V?0ku`kudk0oWWtu\u\t{PPuTu`PPuXu`Ru`PuXu`Ru`Pu`Ru`udPuduT u`Ru` P^h1^hSah0ahsx{u`{Pu`t\u`udt`udP VV W uXtTuXWuXpR W uXtTuXuX W :uX:Wu\tXWuXu\00uX0 ++ PXVV++Wu\tXWW%p%*Q:Wu\tXW:0su`t\u`sudt`uds0{VVu\tXu\PPu`udPud1S0s(+u`+CPCLu`LOt\Ou`2LudLOt`OudUYpU\P\VpVcYpcWLuXLOtTOYuXpWuXcmpmrRWLuXLOtTOYuXuXWuXKWKLu\LOtXOYWuXu\Y00ruXr0Y22PVVY22KWKLu\LOtXOYWWpQKWKLu\LOtXOYWY0#Lu`LOt\OYu`#LudLOt`OYud#Y0+JVOYV0Lu\LOtXOYu\07POVP[pu`[`ud`gPgpudyfRfyYRY1yffDyYDyfDUYUyfUyfy1yuP0u#pHRH%u|%(P(u|Pttu||Ru|u}Pu}P7u}7=u~=DPDiu~iPu~~u~u}u~1u}1eu~|'u~'Ru}ttDEtEIt%u|%(P(u|Pttu||Ru|EOVOu||u|u|Vu|1'u|'RVu|HHH1'H,RHu|]W]u|u~Wu~~u~u|1Iu||~u|~W'u~,RWu}]w$]u}u~w$u~~u~u}1Iu}|~u}~w$'u~,Rw$ u}u~u}(P(1u}8881'8OVOu||u|u|1'u|$uv<"  uv<"8881'8$ uv<"  uv<"2u uu1eu|u'u2OVOu||u|u|1'u|7HHH1eH|'H7u~Pu~Pu~~u~u~1eu~|'u~7=u~=DPDiu~iPu~~u~u~1eu~|'u~ttu~Pu~Pu~~u~u~1eu~|'u~u~Vu~~u~1:V:Iu~|V'u~1Iu~HH~'Hu~Wu~~u~~W'u~}w$u~~u~~w$'u~u~IOu~OaPaeu~88'8Vu~~u~'u~ uv<"88'8 uv<"uuu'uVu~~u~'u~000'0u|Pu||u|u|'u|000'0u||u|u|'u|%VVV#'V%1u|BVVV#'VBmVmu||Vu|VV#'VBLqLQPimVmu||Vu|Vi00u|0u||u|u||u|00WWu|u|PPu||u|u||u|PPu||u|u||u| PP u~~u~1u~~u~;u~u}}u}u~>u||u|>IPPIu~u||u~bu~~u~wu~~u~u~~u~u~P^u~^du}duPuu}}u~u||u|u||u|u}}u}u~~u~PPu||u||Nu||3u||^du}duPuu}}u|Ru|u|Pu|u|u|Ru|Pu|u|Ru|P( ( L P /p/Pp/Pp/@@P/@1uP0u#p HP Hu|PSu|S\P\]t]ata u|  t|P u| u} (P(bu}bPu}u~Pu~P u~  t~Pu~u}u~u}Ru~iu~ u}ttttu|PSu|S\P\]t]ata u|  t|P u|V u|  t|Pu|u|Vu| Vu|  HPHHH H }u|}Wu|?W? u~  t~Pu~u~Ru~iqu~quWuwu|wWu~u|W Wv}u}}w$u}?w$? u~  t~Pu~u~Ru~iqu~quw$uwu}ww$u~u}w$ w$u} u~u}Pu} APAAAV u|  t|Pu|u|u| upt" uv<"  upt"! uv<" APAAA upt"  uv<"  upt"! uv<"u|iu|V u|  t|Pu|u|u| HPHHRHiH"u~"%P%Eu~ELPL u~  t~Pu~u~Ru~iu~u~Pu~P u~  t~Pu~u~Ru~iu~tt"u~"%P%Eu~ELPL u~  t~Pu~u~Ru~iu~:Iu~IFVF u~  t~Pu~u~Ru~iqu~qVVu~ HPHHRHiuHwH?W? u~  t~Pu~u~Ru~iqu~quWwWu~?w$? u~  t~Pu~u~Ru~iqu~quw$ww$u~ u~u~Pu~ APAARAiqAFVF u~  t~Pu~u~Ru~iqu~ upt"! uv<" APAARAiqA upt"! uv<"3 u|  t|Pu|u|u|iqu|3FVF u~  t~Pu~u~Ru~iqu~b 0P00%0bhu|hP u|  t|Pu|u|%u|v 0P00%0v u|  t|Pu|u|%u| VPVVVu| VPVVVV u|  t|P`V`pu|pVVVrPV u|  t|P`V`pu|pV 0P0u|0K u|  t|Pu|K u|  t|Pu|K 0P0OkWWTku|u|T_PPk u|  t|Pu|t u|  t|Pu|tPPZP u|  t|`u| u|  t|`u|PP u~  t~`u~ u~  t~`u~wu~w u}  t}`pu}pu~ u|  t|`u|PpzPu~ u|  t|`pu~ u~  t~`pu~ u~  t~`pu~ u~  t~`pu~.4u~4EPEu~u}P u}  t}`pu~O u|  t|`pu|m u|  t|`pu|w u}  t}`pu}z u~  t~`pu~zP`jP u|  t| u|  t| u|  t| u|  t|u}P u}  t} u| $R$%u|u|P%u|%u| u| $R$%u|$P%@u|.;u|;?R?@u|.?P!P6TPTSSl"P7MPMSSQYYewVSSstSSstSstss|ss|ududRudPPw w w<V w w<V"SVV"vtv"v| ucR"uc P"* w w<&* w w<&2S.P.NuTPuT7u-uuu?bSbftfsSgjpu "jyP{R{PQxxxrPS8OrrPSPS r Pth$#=WP#Tm0VvVp#TSRrPth:UPR`dPRLU1`m1LUP`kPkmr!s SSSJJLSLc&SSSJJLSLc&GPGVWPVPVPVP(V(?P?HVH_P_hVhPVPVPVPQVQ^P^pWpVWVPAVAcW8K8KS7SSS((S(H(HSHhHhShhSSSpQvQ^p^pwvpAvp``R``4`pSSS4p``R`p[[R[#PP#pPP)p``R`)4PPPp\S4`%/[/3R34[%3P4AP:A[:APK4JYKSS4SSJLSLY`QJY`SQSSJLSLYS}JY}SJLSLY``[R[PLY`RY[RYPP S!S!##%S%RRTSTk&S!S!##%S%RRTSTk&/P/VWVVVcPcuWuVQVWVPIVIkW@S@SS7SSS((S(H(HSHhHhShhSSSVvH$H&VcpH$H&cuwH$H&vH$H&pH$H&IvH$H& u``R`#`'<` uSS!S!#'<u``R`u[[R[(PP(uPP.u``R`.9PPPp\S'<`-7[7;R;<[-;P<IPBI[BIPS9RaSSS9SSRTSTahVRahSVSSRTSTaSRaSRTSTa``[R[PTa`Za[ZaPP-9P9GWIWW ESEHu HItISSu -ESEHu HItISSu ISSu yySSu ududucRucPucRucP0S9KS0o9DoDHRHKo$P9HP |s s s 0$@VV)@uwuw)4PP@|sss@0G_VVL_uwuwLSPP_|sse~uw~tsuwtsenPnxs<Pl|SSqxuwuwqPPs Ps sPssuwRuwPSuwRuwPX\p X\S\zSz}s}SSbV'Vpu#u# u#4Pu# u#4Pu# u#u# 4Pu#u# 4Pu# u#0S Sug ugP Pu##u# t#ug_ug tcP'5u#-5u# u#4-9P15u# u#419P=Ku# CKu#u# 4COPGKu#u# 4GOPS[u#[^p^cPdu#pzugz~R~ugp~PvjvmvWwWWwWSSSvjvm|vv v Dvprvv&<S<?s?CSC_S_bs|,8PE[P,8Pvjvm|vv v Dvv|00 0 D00vjvm|vv v Bvv|00 0 B00SmzSSPSmzSudmzudPmtPSudRudPvjvz|vv v BvvS-vOv]jvz|v Bvv-MSMS$)S-OV]mVz|V BVV-Uv$BvJUVUvOv]jvz|v $vvU] vv4UaPY] vv4YaP)Bv)5 vv4)9R15 vv419RevOv]jvz|v $vvhp vv4htPlp vv4ltPxvOv]jvz|v $vv{ vv4{P vv4PvOv]jvz|v $vv vv4P vv4PvOv]jvz|v $vvPPS P OS]iSz|SSOYY$Ov]jvudt`]ludlmt`P]dP|vucRucPv vv4P vv4Pv vv4P vv4Pv vv4P vv4PDJvJTPTXvXpvrvr0,V,2s2?S?dPdSSell|]`Wg|0]`sg|ss8Ps8 gs8|s8s8PW !P!gW|~WW%g9gss`s gs |s s {s gs|ss~s s s4P s s4Ps ss 4P ss 4PsPssucRucPVYWl|0VYsl|s~WZl0~s Zls sPsZs|ssPVPZV|~VVZ,Zs<s~s Ps sPssucRucPSucRucPFWHhW3@SHbS@VHbV'p|'P3>PHUPUWv435R5>p|HUp|UWv83@WHbW3@1Hb15>r4H\r4q4\4 q4Yhq4SvCSS0su"QUQ(\(C0|P1ChPC2mWh2mV CVYhVV0VCVUCsq"QSvCSWCWP(:P1C1u4(Cu4QQ(\vvW(W1(1u4(u4V vp4PV vp4PBWDWfW,<VDZV,V,<DZ:s|DMs|MO #8:SDMSMO #4,:SDMSMO #4,/s|/1P1:s|DMs|MO #8,<WDZW,<1DZ11:p4DTp4r4\4r4Qfr4U>UU0uq"QWQ X >0rQ1>[Q[f vp2&1$z>uOfuV>VQfVV0V>V>ur"RU>UW>WXX >X1>1q4 1q41>\4QQ XRv vW W1 1r4r4 \4V vp4PV vp4P*XggqrqwggqRqSs SX# Xs # 3s 3 -P6SsSX#ws#EXlwlRlESsSX#ws#GSsGSlGPPPSsFWHhW3@SHbS@VHbV'p|'P3>PHUPUWv435R5>p|HUp|UWv83@WHbW3@1Hb15>r4H\r4q4\4 q4Yhq4SvCSS0su"QUQ(\(C0|P1ChPCWhV CVYhVV0VCVUCsq"QSvCSWCWP(:P1C1u4(Cu4QQ(\vvW(W1(1u4(u4V vp4PV vp4PP/sPSQdssP/sQdss0"0" " /SQdSS""!Mu\MQPQRtRVtVu\Qu\u\u\"u\!IVIuXQuXuXVuXV"uX!,P,WQWWW"W4Mu\MQPQRtRVtVu\Qu\u\u\"u\4IVIuXQuXuXVuX"uX4hShlwStSSsudRudPs udRud PkwQww"wkWQWW"WySQSSudyWQWWSQSu`Qu`PPudu`Ru`Pw0WW%QWu#u#%Qu#W1QWP1APABu#BHpxu`u`%Qu`p1ApAB u##BHPpu`Qu\u\%1u\udud%1udP%.PuXuXududPPduXjtuVtxRxuVjxPu\uVRuVP0IVjjqqqw7jjqQqw7RrRV#Vfrfw#?Rr?R?LPQQRRrxlQlrr#RrlP%S+GS%V+GV%S+GS %R+6R6;v;Arx%l+:l:AQAGl%r+6r6;v#;AR%r%lPehshyPysv~u@HtszSv~u@ tSz}s }Pss v~u@Dt|s Sv~u@ tSsv~u@<ttsPu@tOu@Oms mu@9s 9u@PVP-VMOVmoV-m-sv~u@# tH-MssPsVPMVikVmoVM8 m8 MakPkut-uu&s9iuusyPyVPVLNVSUVSiu# t# -u# u# s9Lu# u# u#,t#,-u#,u#,s9Lu#,u#,'sv~u@#(t@-s&s9iss'svu@#4t4-s&s9iss'svu@#@t(-s&s9iss'svu@#LtL-s&s9iss0-009L00svu@#t#\-ss9Lss60-009L006sv,u@#t#p-ss9LssN]P]bsT]P]bsTsv0u@#t#t-ss9LssZsv4u@#t#x-ss9LsspvPvuDt@-APAuDuD9LuDuDE8 9L8 Ysv8u@#t#|sPOmsU_uO_cRcmuOUcPs0sPss&s ss4P ss4P&s ss4P ss4P&s ss4P  ss4 PWWPVPsVVs,]>PP-3P3CF:-:L:FPPsV4V-VLVxVVsS4S-SLSS@S@S!@!#S#9@9=S=p@prSrt@tvSvx@S@S@S@S@=R@CM\MQRQR\CQPV4V-VLV;VptVV\P\\P4#\#'R'-\L\!\!00;\pt\\P'PS4SLSS@S@S!@!#S#9@9;SprSrt@S@S@S@S@PsWtzLLLL!L9;LLPPWzLW!9;Pp$#WzDLDD!D9;WWPHP H PzHLHH!H9;HHzWLWWzSLSS@%zWLW%3W3UHUzLlHlW(zVLV(3PP3zHLH3UHUzLlHl9zVLV9DPLVPDzD\DJzV\VJUP\fPUzl[zVlV[fPlvPfzL|LlzV|VlwP|PzS4SS!#S#0@S@S@SVP4VV!0VV4!04X!##0X4TTRT!0TPP4VV!0V4!0PP4X4V.PMS X=XFHSHJXJLSLcXceSeXxXMQ\Q]P]V =FJJgVgxLcVR\`\`R`c`R`PnxPnup$#V PPVPgPxPV WWgWxWW`R`P VVVW VW LLRLPP WWW W VVPP PPP VVVPP  VVPP X V PPLRLP(#L#'R'(L'P(=X.8L8<R<=L.<Pi~VoyLy}R}~Lo}P~WLRLPWVPHVPDVPVPLVP@RP#0X)0V)0PRpVXf\fjRjp\XjPTRTPVTRTPPp~+6P6>p~PPp$Pp$#p p $P<UPPUVUC}CtVt} V f}fxVx}V]}.3sLULU1U\PmPbhshlt} } R}P,}'}'+R+,}+P,G}5B}BFRFG}5FPGb}P]}]aRab}PaPb}k|}|R}kP}}R}P V}R }P DW):}:>R>D})>Puu }P}WP4W fWWWgWWW2GP PPP f jVj } fVV}}V}V W fWWWgWWWU}Wg}}}Wg}P}Wg}}W]}]aRag}PWaP}}R}PW}g}}W}gu}=W}@WV@QPu}~}R}~P } 0fVf}]}#}0frfr2WP3}}R}PPPS%vOd`U__cRcdUcPdyVjttxRxyjxPyXRPTRPHRPDRP@RPPRPalPP6TP<FFJRJT<JPVk`\ffjRjk\jPkVq{{RqPXRPTRPHRPDRP@RPSP P GuL\uuduFRuFPu`uFRuFPu\uFRuFPuPuFRuFPuL uFRuF P/uH *uF*.R./uF .P/LuX5LuG5BP P GuL\uuduFRuFPu`uFRuFPu\uFRuFPuPuFRuFPuL uFRuF P/uH *uF*.R./uF .P/LuX5LuG5BP P +u+,t,,P,SuXhuuduFRuFPu`uFRuFPu\uFRuFPuP uF RuFP&uL!uF!%R%&uF%P&;uH,6uF6:R:;uF,:P;XuXAXuGANP P +u+,t,,P,SuXhuuduFRuFPu`uFRuFPu\uFRuFPuP uF RuFP&uL!uF!%R%&uF%P&;uH,6uF6:R:;uF,:P;XuXAXuGANPZdusdhRhrusZhPSp$Pp$#pf{PP%VU\UVZ\ZV\%5v#5:PA Z x AVU\UV\Z\xV\AKpKPPW[Z[x[WVU\UV\Z\xV\WapafPmZxmVU\UV\Z\xV\mwpw|P Z x VU\UV\Z\xV\pPVU\UV\Z\xV\VU\UV\Z\xV\0Z0x0_xV_x0SXSXSX"S"'X')S).X.0S05X57S7<X<>S>CXCESEJXJVSVXSXSXSXSXSX13S3JXJUSUZXx}S}XSSXSXSX"S"'X')S).X.0S05X57S7<X<>S>CXCESEJXJVSVXSXSXSXSXSX13S3JXJUSUZXSVU\UV\\1Z\\PU^P SXSXUS STVSVXSXSXSXSXSX13S3JXJUSUZXS U T1Z3SXSXUS STVSVXSXSXSXSXSX13S3JXJUSUZXS6TW$T$DWDKTKOROUTT WTTWTW1JWJOTOSWSZTTW6APDOP{PPW`p$#p0p$#pPPPVk\ffjRjk\jPkqRqPRP@RPLRPPRPW  RP3JX9CCGRGJ9GPW\1WrWW)W)WDT1Zr{PXRPW R P0P!++/R/0!/P0ED6@@DRDE6DPEZ@KUUYRYZKYPZo`jjnRno`nPouRuP1X'T'+R+1T+PPSSBSSSpRr>SvSSud>vQSvSTuGvuGT_PP_u`vu`u`eudvududepPPpuTvuTuTvudvududvPPuPvuPuPudvududPPuLvuLudvudPvPu\udPutuSSEvEE'Ev'   %' %'BEuBEu BIPIS%'SSSudSSu\u\PPu`udPuuuvuuu PrSruuuvudu\Ru\Pu`u\Ru\P)@u\/9uG9=R=@uG/=PBYuLHRuGRVRVYuGHVP[ruPakuGkoRoruGaoPtuTzuGRuGzPu`uGRuGPuGRuGP4S4SSPRnPP`RPVRPWRPTRP H R  P DRP4@%//3R34%3P4RP:HHLRLR:LPPp$#p`LRLPWLRLPTLRLPPLRLPVLRLP` DRD P-W(D(,R,-D,P-BT3=D=ARABD3APBWPHRDRVRVWDHVPWlL]gDgkRklD]kPlr|D|RDrPVDRDP%S+GS%V+GV%S+GS %R+6R6;v;Arx%l+:l:AQAGl%r+6r6;v#;AR%r%lPaSuptlS&up&'tl'=up=?S?uput'=ut]utPu'=uut'=utuo'=uoP'7Pupuput utP Pup?]upEOuoOSRS]uoESPmuts}uo}RuosPFWHhW3@SHbS@VHbV'p|'P3>PHUPUWv435R5>p|HUp|UWv83@WHbW3@1Hb15>r4H\r4q4\4 q4Yhq4SvCSS0su"QUQ(\(C0|P1ChPCWhV CVYhVV0VCVUCsq"QSvCSWCWP(:P1C1u4(Cu4QQ(\vvW(W1(1u4(u4V vp4PV vp4PpPqq #$#HQqRQQ#$qFWHhW3@SHbS@VHbV'p|'P3>PHUPUWv435R5>p|HUp|UWv83@WHbW3@1Hb15>r4H\r4q4\4 q4Yhq4SvCSS0su"QUQ(\(C0|P1ChPCWhV CVYhVV0VCVUCsq"QSvCSWCWP(:P1C1u4(Cu4QQ(\vvW(W1(1u4(u4V vp4PV vp4PCu ju gutgjtpjut :S (ut#04p49Rju jutj0jut#POgutgjtpOj0FWHhW3@SHbS@VHbV'p|'P3>PHUPUWv435R5>p|HUp|UWv83@WHbW3@1Hb15>r4H\r4q4\4 q4Yhq4SvCSS0su"QUQ(\(C0|P1ChPCq#Whq#V CVYhVV0VCVUCsq"QSvCSWCWP(:P1C1u4(Cu4QQ(\vvW(W1(1u4(u4V vp4PV vp4P3QItQ Ew4Ipw4CSCIIlSltIlSltIqUqt I\P  S"t#\S*W?TWS"t?TS*WS"t*1s"t#?TsBQPpXR !P!!P!2R2?U?X.V.2P?Uz22?u?CX#CluNUSUVpt2CVNSQSV2CPetP2CWNWN\PzX#rzzVSPPW\RP00u\0tX0u\0V0u\*uu*u u 8>Pv}PuX P *uX<>PP*1*808>Q>m1mv0vQ1P0P*u *uX4tT4u uX4tT4uX4>Su <>p>Su*W*>SFS*3PmtP*>u\N]P]u\*>u`Nu`u u@SWWPPu`t\u`udt`ud{3uP)uuu\tXVu\00)u u =fVfoPoVV1V )u =u\#u\# )u'S'(pt9V7=PP=u\#u\#.R.P=UuUVtVZtu=11=00LUuUVtVZtuLZPPzuPGPHg\ \ zu~z}P}Au~AD~Du~ u~ @W@Au~AD~DWtt\zu~z}P}Au~AD~Du~su~sxPxAu~AD~DXu~\xu~u~`xu~XH\`HHHVAu~AD~DXV\`VVVu~Sv$Au~AD~DXv$\`v$v$v$u~]au~xu~hAu ADDXu \`u u hsu~sxPxAu~AD~DXu~\`u~u~hX0\`00hkp{Au~AD~DXu~Au~AD~DXu~VAu~AD~DXVAu~AD~DXu~Au~AD~DXu~PDRPAu~AD~Au~AD~Au~AD~Au~AD~%Au~AD~/uP/vuHvytDuHuH.P.vuHvytDuH/vuHvytDuH/2uP2:P:vuPvytLuPVtVtvu`vyt\VYvu_vyt[u_Y`PP`vudvyt`udfvu`vyt\u`fmPPy1ySP0spudu_Ru_Pu_Ru_P,61,6S/60/6sH[u@[0uHKuKUPUVtVZtZ0u[^u@^fPf0u@g0,0gju`jPu`,u`u0,0uud,ud(u(WuX(WqPWuXW*uX*VuXu\0(uX(0PSWW  V pP*V*0u\0Vu`VudV0ZrWW_ru\u\_fPPruPxu`xPPuTu`Ru`Pu`Ru`udPuduPu`Ru`PuTu`Ru`P\ou@ousu\_u_iPijtjntnusuousuoru@rzPzu@su@{060TX0\s0{~u`~Pu`6u`TXu`\su`060TX0\s0ud6udTXud\sudOO\sOuOO\sOWuXuXW\suXqPWuXuX\suXW>uX>VV\^uX^su\00\s0uX0\sPgW\sW\sVV\sV)p).P>VV>00ju`u`jududj00nWWsu\u\szPPuPuPu`u`PPuTu`Ru`P1S0s1u`15R56u`udP6ud6uP'1u`15R56u`'5P6TuT<Fu`FJRJTu`<JPu@u+uuPttu+uu+uu@Pu@+u@0+000u`Pu`+u`u`u`0+000ud+ududud! +a! ! u! +a! ! UWUuX+LuXLaWuXqP'UWUuX+LuXuX'UWUuXV+LVuXu\'0+L00NauXNa0a+LahPhWWo+LoV+LVVoypy~PV+LV0+L0u`+Lu`ud+Lud0+L0W:LWu\:Lu\P:FPuP+:uPu`+:u`P+7PuTu`Ru`P 1 S 0 sau`Ru`afudfmPmudnuPwu`Ru`wPuTu`Ru`P u@ J u{  uu P  t  t J u{  u J u{  u  u@  P J u@{  u@ J 0{  0  0  0  u` 5 P5 J u`{  u`  u`  u`) J 0{  0  0  0) J ud{  ud  ud  udB J ' {  '  ' B H uV J ' {  '  ' V  W J uX{  uX  W  uXV ` q` e Pw  W J uX{  uX  uXw  W  uX J V{  V  uX  u\w J 0{  0  0  uX  0 J {      P  W  W J {     J V{  V  V  p  P J V{  V J 0{  0 J u`{  u` J ud{  ud J 0{  0 & W  W & u\  u\  P  P& J uP{  uP, J u`{  u`, 3 P{  P3 J uT9 C u`C G RG J u`9 G PR \ 1R \ SU \ 0U \ s  u`  R  u`  ud  P  ud  uP  u`  R  u`  P  uT  u`  R  u`  PL _ u@_  u c uL O uO Y PY Z tZ ^ t^  u c u_  u c u_ b u@b j Pj  u@ c u@k  0 & 0D H 0L c 0k n u`n  P  u` & u`D H u`L c u`y  0 & 0D H 0L c 0y  ud & udD H udL c ud  .  . L c .  u  .  . L c .  W  uX  uX  WL c uX  q  P  W  uX  uXL c uX  W . uX.  V  VL N uXN c u\  0  0L c 0  uX  0    L c   P W WL c W    L c   V  VL c V  p  P.  V  V.  0  0Z  u`  u`Z  ud  udZ  0  0^ v W  Wc v u\  u\c j P  Pv  uP  uP|  u`  u`|  P  P  uT  u`  R  u`  P  1  S  0  s ! u`! % R% & u`  ud  P & ud & uP ! u`! % R% & u` % P& D uT, 6 u`6 : R: D u`, : P,W,0 s5&?CWCE s5&0lslpshsSssxp8sspp@sh0pVV V V0lslpshsSssxp8sspp@sh06s67t7;PClslpspsSpssxp8spCpVV V VClslpspsSpssxp8spCIsIJtJNPVlslpsxsSpsxVpVV VVlslpsxsSpsxV\s\]t]aP0lSlps`pSSsxSspp@SshpHs`0VV V V0lSlps`pSSsxSspp@SshpHs`pusuvtvzP0pjjCpjjVpjjWVWwtP j%W%V%WwtP"%j%7W%7V%7W%*w*+t+/P(V(1 u4&V u4&1WuW_utuR u ut1_oo1_  1WuW_utuR u utWSP@WuW_ux u ux@_oo@_  @WuW_ux u uxWSPHWu W_u| u  u|H_ooH_  HWu W_u| u u| W SP1WUW_up_UUr| U up1oo1  1WUW_up_UUr| U upgWgSgqP1_oo@_ooH_oo@JVV@Joo@J  @JVVSUPGJoJcVJcoJc JcVQcSQcUQ[PyVv|Vyoy yVv|V RUPo,W,. s4&.VG]V]b bxV2BP2VG]V]b bxVNVG]V]b bxVQaPQVG]V]b bxVmVbxVpPpVbxVVpxVPVpxVVPVwVPVw5V-P5VNwGxwmwbxwwpxw:lWnWGW  S  t  t muPmntLnuPtLuP  uT  S muTmntPnuTtPOuTOQSQuTSuTSuT  p mu#Tmnt#Tnu#T(u#T:{u#Tu#Tu#T  p mu#Xmnt#Xnypyu#Xqu#Xq$u#X:OqO{u#Xu#Xu#X mu#Tmnt#Tnu#T(u#T:{u#Tu#Tu#T mu#Tmnt#Tnu#TqQu#T$u#T:OQO{u#Tu#Tu#T  S muTmntPnuTtPOuTOQSQ{uTSuTuT  u#X mu@mntnu@u@ u@O{u@u@u@  WWO{WWW  uX  P  uX  P muXmntTnuXtT{uXuXuX  P muXmntTnuXtTfuXuX kVkmu`mnt\nVu`t\fVV kVkmu`mnt\nVu`t\OVV  u\  P mu\mntXnu\tXOu\u\ kVkmu`mnt\nVu`t\OVV  V ud)u\):uX:KuTV'u\'8uXGXuTudVu\ jSjmudmnt`nSudt`OSSudSud  PPudRudP  u\  P mu\mntXnu\u\tXOu\u\ mudmnt`nududt`Oudud mudmnt`nududt`Oudud udmu\mntXnu\u\udu\tXOu\u\ ud)u\):uX:KuT'u\'8uXGXuTud mu`mnt\nu`u`t\Ou`u` PPmu\mntXnu\u\u\tXOu\u\)u\):uX:KuT'u\'8uXGXuTmudmnt`nudududt`Oudud,P,:u\<&P):uX'8uX):uX:KuT'8uXGXuT/:ud-8ud/=P-FPQfuXWauOaeRefuOWePu\u`P:KuTGXuT@KudMXud@NPMfPK\uPgxuPQ\udmxudQ\PmPududt`Oudu\u\tXOu\P PPqpu#|u@#:Owu`:Ou`R:ARAC w2$q"Qu#T:OQ rq4:A rq4AC w2$4:OQ:Ou`:FPu` u`u#Tq u#Tu#Tu`Pqu#`$4qudt`$:udqu#`$4qqu#`udPu#df{uTlvuOvzRz{uOlzP{uPuORuOPGSPqSSGVudt`VVJu_t[u_u_JUPLWPUu`t\Lu`]u`u`[udt`Lud]udud[fP?FPqSP?S]qSSqu ?u ]ru u qu?u]ruuqtPtuTtP?uT]uTuTqtptuT#tP#?uT#]uT#uT#qtpt{uT#1uT#]uT#uT#{SP1?S{sp1?sP1ud]ududuT#P1uT#]uT#uT#1ud]ud1u`]u`P]fP1uT#luT#udu`Pudu_Ru_Pu`u_Ru_P(x(5P5x(mVmppxVV=BPBlSlmvmppxSSKZPZnWnoutopptpsPsxWWNxNmVmppxVVNoUopPpxUUNlSlmvmppxSSP^SP^VP^UsxU^lSlmvmpS^nWnoutopptW?4W45uX56tT6WuXtT-WGWWS`R`uDuDRuD -uDGuDuDu@uEu 2S25ud56t`6Sudt`/S/EudEISIudSudSudu @u Eu hV VV2S25ud56t`6Sudt`-SGISIudSudSud&hV VV&4W45uX56tT6WuXtT-WGWWu`Ru`P?2S25ud56t`6Sudt`-SGISIudSudB5u`56t\6u`t\-u`Gu`u`BMPPM -GS- --G--hu\P5u\56tX6u\tXu\ -u\Gu\u\ou\u`hou\o5u`56t\6u`t\u` -u`Gu`u`o5u`56t\6u`t\u` -u`Gu`u`uVPuVuV -uVG^uVuVPVv V-vVuDuD -uDG^uDuDudud -udG^udududud -udG^ududPu\u\ -u\G^u\u\udud -uduWuW -uWP Pudud-udPu`u`-u`udud-uduWuW-uWP'Pu\u\6au` u`Wau` udZaud PZnPu\r|u\udu|ud PuP*uXuX#*udud#.PP u\Pu\RuDu\Pu\Pu`/<ud5<u`5<PI^udOYuWY]R]^uWO]P^u`dnuWnrRruWdrPsu\yu`Ru`yPuXu`P  P uHuLDuLtH5uLB0BuP}uPuPH05uPB0BuDuDuDP05uDB0Bu@Wu@u@05u@pUu#Tpu#T#Tu#Tt#TQWW5Wau`Xu`5u`n0uTQuT5uTSSSSQVJVhQV5VPs2EPEJshs1h10h1uPuLuHPw,yPsWyWududu_u_PP$.u_.2R25u_$2Pa050aWW5Wu`Xu`ud\udPPu`udRudPKyVyzu z}t}Vu V`cuwclRlzuwz}tsuw`lP`yVyzu z}tV`xSx}PSrwPwxsx}prxSx}P $qVvP?L?GPGHtHLtLTLT^R^L!P!"t"&t&LP)L)4P4L?L?GPGHtHLtLTLT^R^L!P!"t"&t&LP)L)4P4LVV$0ToVo0 N0Ns10VVToV&)D)2R2<D&2P&<V&6H6<W9<P9<W<W WH$WTmWoW<?L?GPGHtHLtLL TLT^R^L!P!"t"&t&LP$LTmLoL\x \\l#lqPxWxx#P4 pPWeWWH$WoWDhvDvzRzDDP$oPhzP pP9S9;P;sSSs#";;AsABtBFt"sWNsWNTLT^R^sLP #PW#PVmW\fDfjRjmD\jPVV,$,o,vPSPS$SoqSS#߫VVL!P!"t"&t&LV0VW3W3:PPA_ _ AAQ#QVPZssZwwpP$q$q$WH$WP!PLPL0&)L)4P4TL5T5T0sy@R@yPW@R@P@R@P@:VZVVzW|WWWWWWPPP:VV(+ug+4P4ugug(+P+SS(:VLufLSPSZvtPvt uf  R uf P vt1S?S8fWW]W5ud]udRfS = udPud=ud= udPud P ud%P%=ud= ud P ud%P%=ud= ud%P%=udududucucPPEOucOSRS]ucESP1S`SJNPNuT~uT7ud~udVgS ^ udPud^ud^ udP ud -P-8ud8EPE^ud^  ud -P-8ud8EPE^ud5^ 58ud8EPE^udududucucPPfpucptRt~ucftPGPHg\ \ "P1APPjSjnp|nS#,P,1p|Javamu#mnt#nu#JMPMjSjnp|nSacPckVnPVcjSjnp|Lqvqsu#@stt#@tvu#@t#@u#@TcPtPSSdgPglp|vu#Dt#Du#DPSSPVP"VS<dvdfu#@fgt#@gvu#@t#@ u#@DSPgyPSp| STZPZgp|vu#Dt#D u#DPSp| SPVP V Sp|= e Ve h ph  V  p  !V= f Wh  W= f wh  wH W Ph y P  S  p|  !SX [ P[ h p|  w  P  S  p|  !S  P  W  P  !W  !  S  p|^!!S!!S!6"v`9""S7#<#S<#]#v`f!!V"7#V]#p#Vf!!S""Sf!!"7#]#p#f!!s""sn!!P""P""R"7#uT]#p#uT!!P""s""P""R"7#uT]#p#uT""P""S""P"7#S]#b#S"7#D ]#p#D #7#""uT!!P!8"uT8"9"tP9""uT7#]#uT!!S!6"v`9""S7#<#S<#]#v`!6"V9""V7#]#V!"7#]#!!P!8"uP8"9"tL9"T"PT""uP7#]#uPU""7#J#l""!9"J#]#!6"VJ#]#V!!P!5"SJ#O#S!9"J#]#"9"##W$A$W$$W##w$A$w$$w##P$$P($F$V$.%VA%T%V##P"$A$w$$w"$%$P%$F$V$.%VA%T%V;$A$PA$F$uT$$P$.%uTA%T%uTA$F$V#$S$$pF$$S$$p$$S.%3%S#$WF$}$W$$W#$GF$$G.%A%G#$wF$}$w$$w##PF$Y$Ph$$V$$p|$$V.%A%V##P#$p|b$}$w$$wb$e$Pe$$V$$p|$$V.%A%V{$}$P}$$uT$$tP$$P$$uT.%A%uT}$$V$$p|t%%S%I&SI&K&w`M&&S&'S8(@(S@(M(w`b(j(Sw((S((w`z%%SM&&S''Sb(j(Sz%%sM&&s''sb(j(s%%PM&Y&Ph&&W''Wb(w(W%%Pb&&s''sb(j(sb&e&Pe&&W''Wb(w(W{&&P&&uP''P''uPb(w(uP&&W%%V%%p&&V'8(VM(b(V%%S&&S%%&&'8(M(b(%%s&&s%%P&&P&&W'8(WM(b(W%%P&&s&&P&&W'8(WM(b(W&&P&&S''P'8(SM(U(S&&W%I&SI&K&w`&'S8(@(S@(M(w`w((S((w`%K&W&'W8(M(Ww((W%M&h&'h8(M(hw((h%%P%&uP0'3'P3''uPw((uPH''w((_''%M&h&0'h8(M(h&J&V&0'V8(M(V&I&SI&K&w`&0'S8(@(S@(M(w`&K&W&0'W8(M(W&M&&0'8(M(&&,&P,&L&uLL&M&tH&&P&0'uL8(M(uL&0'8(M(&0'5&M&  2S27s|7DSSs|2S2;s|o$/o/6R6;oP$6P))P)F)R))p )3) ).)P.)3)#q))Vq))v}))V?**W*5z55W58z8=z==W@qDzB*4}45S55}55R58}8=}@C}CCSCC}CCSCC}CCSCqD}B*M*P55PM*5z58z8=z@qDzV**W*5z55W58z8=z==W@qDzV*a*P55Pa*5z58z8=z@qDzj**W*5z55W58z8=z==W@qDzj*u*P55Pu*5z58z8=z@qDz~**W*5z55W58z8=z==W@qDz~**P55P*0}0,0Q,02}22P25}58}8=}@qD}**W*5z55W58z8=z==W@qDz**P55P*5z58z8=z@qDz**W*5z55W58z8=z==W@qDz**P55P+<-V<-65{655V56{66V68{89{99V9;{t=={@qD{+5z58z8;zt==z@qDz++Pv55P+v5{58{8;{t=={@qD{,v5z58z8;zt==z@qDz, ,Pf5p5P ,f5{58{8;{t=={@qD{,f5z58z8;zt==z@qDz,,PV5`5P,V5{58{8;{t=={@qD{(,V5z58z8;zt==z@qDz(,3,PF5P5P3,F5{58{8;{t=={@qD{<,F5z58z8;zt==z@qDz<,G,Pv66PG,F5{5v6{68{8;{t=={@qD{P,F5z5v6z68z8;zt==z@qDzP,[,Pf6p6P[,F5{5f6{68{8;{t=={@qD{d,F5z5f6z68z8;zt==z@qDzd,o,PV6`6Po,F5{5V6{68{8;{t=={@qD{x,F5z5V6z68z8;zt==z@qDzx,,PF6P6P,F5z5F6z68z8;zt==z@qDz,F5z5F6z68z8;zt==z@qDz,,P66@6P,F5z566z68z8;zt==z@qDz,F5z566z68z8;zt==z@qDz,,P&606P,F5{5&6{68{8;{t=={@qD{,F5z5&6z68z8;zt==z@qDz,,P6 6P,F5{56{68{8;{t=={@qD{,F5z56z68z8;zt==z@qDz,,P66P,F5{56{68{88R88{8;{t=={@qD{,F5z56z68z8;zt==z@qDz,,P65@5P,65z56z68z8;zt==z@qDz -65z56z68z8;zt==z@qDz -65z56z68z8;zt==z@qDz99z99z#z499P7--S565S9:S7-65z56z6_8z89z9;zt==z@qDza--S565S9:Sa-i-Pi-k-v2&5+5P+565v2&9:P::v2&a-65z56z6_8z89z9;zt==z@qDz5+5P+565v2&9:P::v2&56509:0--W66W;;WKDqDW-515616W71{7U81891::1:;1t==1@qD1--S;;SKDMDS--W--V66W;;VKDqDV--S--s|;;SKDMDS--V--v|;;VKDqDV ;;VKDqDV ;;WKDqDWXDdDz#z4XDhDP`DdDz#z4`DhDP-5z56z6W7z{7U8z89z::z:;z;;zt==z@KDz-5z56z6W7z{7U8z89z::z:;z;;zt==z@KDz-.S..s|.5.S66}::S--s--t-l.1:;1.l.::%.l.z66z::z%.5.S66}::S%.7.W66}::W%.l.W66}::W7.C.WC.G.w|G.`.W`.l.w|7.G.zL.l.zL.].Pl.5z56z6W7z{7U8z89z::z;;zt==z@KDzl.t.z#z4l..Vp.t.z#z4p.|.V|..z|.5z56z6W7z{7U8z89z::z;;zt==z@KDz.515616W71{7U81891::1;;1t==1@KD1..z.5z56z6W7z{7U8z89z::z;;zt==z@KDz.515616W71{7U81891::1;;1t==1@KD1./S/5{55{56S6W7{{7U8{89{::{;;{t=={@@S@KD{.5566W7{7U889::;;t==@KD//S/5{55{56S6W7{{7U8{89{::{;;{t=={AKD{/5z56z6W7z{7U8z89z::z;;zt==zAKDz/ /P56P@/t/}@/t/zc//0 /000P000S00 00P0i1Si1z1# 12 22 22S33S\45 {78 (8U8 8I9 I99S::SAA _B{B CCSCD //0022//P//P00P22PC7Cz%C2C|2C6CR6C7C|%C6CP7CRC}@CMC|MCQCRQCRC|@CQCPRCmCz[ChC|hClCRlCmC|[ClCPmCC}vCC|CCRCC|vCCPCC}CC|CCRCC|CCPCC}CC|CCRCC|CCPCC}CC|CCRCC|CCPCC}CCzCCP//P/j0V11V88V//P/J0W12W88PtB{BW/0@12@6W7@{78@(8U8@t==@_B{B@BC@00wp"0,0P11v@r0.(w"66|66z66P66V66z66P66|66z66P6 7|6 7z6 7P 7(7|7(7z7'7P(7C7|17C7z17B7PC7W7|L7W7zL7W7P}77|77z77P77|77z77P77|77z77P77|77z77P78|78z78P88| 88z 88P18U8V:8U8z:8O8PAA| AAz AAPA9AV'A9Az'A8AP9ATA|BATAzBASAPTAoA|]AoAz]AnAPoAA|xAAzxAAPAA|AAzAAPAA|AAzAAP01P1-1PI9U9P;:;|(;:;z(;9;P:;U;VC;U;zC;T;PU;p;|^;p;z^;o;Pp;;|y;;zy;;P;;|;;z;;P;;|;;z;;P;;{;;z;;P;;|;;z;;P::{::z::P::{ ::z ::P:::V(:::z(:9:P::U:{C:U:zC:T:PU:p:{^:p:z^:o:Pp::{y::zy::P::{::z::P-141PO1W1PAA{AAzAAPAB{BBzBBPB/B{B/BzB.BP/BSB{8BSBz8BMBP}BB{BBzBBPBBVBBzBBPBB{BBzBBPBBWBBzBBPT112255]112255]1z1}p11z22z55zp11S11s|11S22S55Sp112255p11z#1111z22z55z11z#z411P11z#z411Pp111221551p11225511z22z55z11z22z55z11P55P11z22z11z22z11P22PW7{7zU8_8z]7q7Vq7v7v|v7{7VU8_8VW7{7 U8_8 v7{7 U8_8z[8_8z#z4[8_8P_8g8Pk88zt88{88R88{t88P88z88z88R88z88P;<V<<z<<P<-<{<-<z<,<P-<H<{6<H<z6<G<PH<c<{Q<c<zQ<b<Pc<~<{l<~<zl<}<P~<<{<<z<<P<<{<<z<<P<<{<<z<<P<<z<<z<<P<=z<=z<=P= ={= =z==P =;={)=;=z)=:=P;=_={D=_=zD=Y=P==W==}==R==}==P==z==}==R==}==P==z==}==R==}==P==z==}==R==}==P=>}>>}>>R>>}>>P>:>z>0>}0>4>R4>:>}>4>P??W??}??R??}??P??}??}??R??}??P??}??}??R??}??P?@}@@}@@R@@}@@P@2@} @-@}-@1@R1@2@} @1@P2@M@};@H@}H@L@RL@M@};@L@PM@q@}V@g@}g@k@Rk@q@}V@k@P@A{@Az@@PDDRDAESAEEEREEmESmEEREESE)FR)FUFSUFFRFFSFFRFFSFFRFFSFFRFFSFHGRDDRDAESAEEEREEmESmEEREESE)FR)FUFSUFFRFFSFFRFFSFFRFFSFFRFFSFHGRDE )FF FF FF G0G GSiFFVFFv|G0GVGSG0GSGSG0GuPSP>SLSw<UUP;SLSuDUUuDASLSu`UUu`ASLSPUUPSSWS\UuP\U]UtLUUWU]VuP]V^VtL^VVuPW*WuP5WbWuPWWuPS\Uu`\U]Ut\U]Vu`]V^Vt\^VVu`W*Wu`5WbWu`WWu`SSPSSw<UUPSSuLUUuLSSu`UUu`SSPUUPS\UuT\U]UtPU]VuT]V^VtP^VVuTW*WuTWWuTS\Uud\U]Ut`U]Vud]V^Vt`^VVudW*WudWWudSTPTTuT<UUPTTWUVuXTTudVVudTTPVVPQT\Uu`\U]Ut\V]Vu`]V^Vt\W*Wu`TT\Uud\U]Ut`V]Vud]V^Vt`W*WudTTbTPbTpTu`<V"VP_TpTu\#V4Vu\eTpTud)V4VudeTpTP)V;VPpTYUSAVZVSWWSW*Wu T\Uud\U]Ut`AV]Vud]V^Vt`W*WudTZUVAV[VVW*WVT]U\ AV^V\ TTPT\Uud\U]Ut`AV]Vud]V^Vt`T\Uu`\U]Ut\AV]Vu`]V^Vt\TTPAVHVPTT0TUWTYUSNVZVSTUs U]U NV^V UZUVNV[VV'U\Uu\U]UtNV]Vu]V^Vt4U]U\ NV^V\ 4U@UPGU\Uu\U]UtNV]Vu]V^VtJU\Uud\U]Ut`NV]Vud]V^Vt`JU]UPNVUVP`VuVu`fVpVudpVtVRtVuVudfVtVPuVVu\{VVud{VVPVVuVVuVVRVVuVVPVVuVVudVVRVVudVVPVVuVVudVVPVVuDVVu`VVPW*WudW*Wu`W*WPVVuPVVu`VVRVVu`VVPVWuLWWu`WWP7WLWuT=WGWudGWKWRKWLWud=WKWPLWbWuXRWbWudRWbWPdWzWujWzWu`jWzWP|WWuHWWu`WWRWWu`WWPWWu@WWu`WWRWWu`WWPW] ]C_ J_q_ Ws\Wu\*]W,]]W]C_WJ_q_WXPXuPX[XP[Xt\ut\u\tu\+]u+],]t,]]u]C_uJ_q_uXXPX[u u\\u ,]]u ]]u ]]u ^^u _C_u J_q_u X!XP!X%Xu #$%XXu,]V]u+_C_uJ_c_ubXXSXt\ut\u\tu\+]u+],]t,]V]SV]]u]^u"^+_uc_q_ueXt\u`t\u\t\u\+]u`+],]t\,]]u`]^u`"^+_u`c_q_u`eXsXPsXXs<,]5]PpXXV6]G]uvXXu`<]G]u`vXXP<]P]PX[u u\\u V]]u ]]u ]]u ^^u "^^u _+_u c_q_u XXPXXu #$XKYuV]]u ^^u"^P^u _+_uX YS Yt\ut\u\tu\+]u+],]tV]]S]]u]^uP^+_uc_q_uXt\u`t\u\t\u\+]u`+],]t\V]]u`]^u`P^+_u`c_q_u`XXPXXs<V]_]PXXV`]q]uXXu`f]q]u`XXPf]z]PX[u u\\u ]]u ]]u ]]u ^^u P^^u _+_u c_q_u YKYu ^^u _+_uHYYSYt\ut\u\tu\\u\\S\+]u+],]t]]S]]u] ^uP^ _uc_q_uNYYYQYY[u[t\u`t\u\t\u\]u]+]u`+],]t\]]Q]]u] ^uP^ _uc_q_uNYYYP]]PYYt\ut\u\tu\+]u+],]t]]u] ^uP^ _uc_q_u_Yt\u`t\u\t\u\+]u`+],]t\]]u`] ^u`P^ _u`c_q_u`_YjYP\\PYYSYt\ut\u\tu\\u\\S\+]u+],]t]]u]]uP^ _uj_q_uYt\udt\u\t`u\\ud\+]ud+],]t`]]ud]]udP^ _udj_q_udYYPYYs<\\PYYV\\u@YYud\\udYYP\\PY[u u\\u \\u ]]u P^^u j_q_u YYu #$YYP ZNZSNZt\uHt\u\tDu\\uH\\S\\uH\\S\+]uH+],]tD]]uHP^ _uHZt\udt\u\t`u\\ud\+]ud+],]t`]]udP^ _udZZP\\PZt\uDt\u\t@u\\uD\+]uD+],]t@]]uDP^ _uD!Zt\udt\u\t`u\\ud\+]ud+],]t`]]udP^ _ud!Z,ZP\\P,Z[u u\\u \\u P^^u ,Z>Zu #$>ZIZPrZZSZt\uPt\u\tLu\\uP\\S\\S\+]uP+],]tL]]uPP^^uP^ _uPuZt\udt\u\t`u\\ud\\ud\+]ud+],]t`]]udP^^ud^ _uduZZP\\PZt\uLt\u\tHu\\uL\+]uL+],]tH]]uLP^^uL^ _uLZt\udt\u\t`u\\ud\+]ud+],]t`]]udP^^ud^ _udZZP\\PZ[Su\\SZ[u`u\\u`ZZP\\PZ[uTu\\uTZ[u`u\\u`Z[Pu\|\P[[u [[u #$[t\ut\u\t\+]u+],]t]]u^ _u![t\u\t\u\tX\+]u\+],]tX]]u\^ _u\![s\W\*]W]]W^ _W1[t\u\t\u\tX\+]u\+],]tX]]u\^ _u\4[t\udt\u\t`\+]ud+],]t`]]ud^ _ud4[?[P]]P[t\u`t\u\t\\+]u`+],]t\[t\u\t\u\tX\+]u\+],]tX[[P[[u`<\\P[[ud\]ud[[u`]]u`[[P]]P[[0[,\S[[P[[u #\,\u [[V#\,\u #$[[v#\,\ u #$#T[#\S#\,\s[[u #\,\u #$[[s2$q"[,\ #\,\ u #$#`,\u\ ],] ,\s\W]*]WB\t\ut\u\t]+]u+],]t_\t\ut\u\t]+]u+],]tb\t\udt\u\t`]+]ud+],]t`b\u\P]#]P]]u]]ud]]R]]ud]]P]]u@]]ud]]P]]u]]u]]R]]u]]P]]uH]]ud]]R]]ud]]P]]uD]]ud]]P^^u\^^ud^^P ^^u^^u`^^P$^9^u*^4^u`4^8^R8^9^u`*^8^P9^L^u?^L^u`?^L^PR^g^uXX^g^u`X^f^Pg^^uTm^^u`m^^P^^uP^^ud^^R^^ud^^P^^uL^^ud^^P^^u`^^u\^^R^^u\^^P^_ud^^u\^_R__u\^_P _+_u_!_u`!_%_R%_+_u`_%_P-_C_u3_C_u`3_C_PL_c_uR_\_u`\_`_R`_c_u`R_`_P__0_ `0 ``P`bu~bbt~bbu~bbt~bcu~Gcjc0jccu~cdu~__v__P_`v`bu#bbt#bbu#bbt#bcu#Gcjcvjccu#ccu#cdu#__u~_*`S*`bu~bbt~bbu~bbt~bGcu~GcIcSIcKcu~KcMcSMcdu~Mcjcu~Vcccu~ccgcRgcjcu~VcgcP_c jcc cd _`v`cHjccHcdH``u~``P`au~aaPabu~bbt~bbu~bbt~bcu~jccu~cdu~``u~`#`P#`oau~oataPtabu~bbt~bbu~bbt~bcu~jccu~cdu~cctccth``u~``P`au~aaPabu~bbt~bbu~bbt~bcu~jccu~cdu~`aWabu~bbt~bbu~bbt~bcu~ccWccu~ccWcdu~ccu~`cHcdH`Jau~JaoaPoapatpatattabu~bbt~bbu~bbt~bcu~cdu~^aoap$oapat#$patat#$tabu~bbt~bbu~bbt~bcu~cdu~hatau~lcrcu~rccPccu~abWbbu~bbt~bbWbbu~bbt~bbWabu~bbt~bbu~bbt~bbu~aaPbbPabu~bbt~bbu~bbt~bbu~abu~bbt~bbu~bbt~bbu~abu~bbt~bbu~bbt~bbu~bbu~bbt~bbu~bbt~bbu~b bPbbP bbu~bbt~bbu~bbt~bbu~$bbu~bbt~bbu~bbt~bbu~:bbu~bbt~bbu~bbt~bbu~Ubbu~bbt~bbu~bbt~bbu~ebkbu~kb|bP|bbu~bbt~bbu~bbt~bbu~bbu~bbt~bbu~bbt~bbu~bbu~bbu~bbt~bbu~bbt~bbu~bbu~bbt~bbu~bbt~bbu~bbPbbPbbu~bbt~bbu~bbt~bbu~bbt~bbu~bbt~bbPbbPc#cu~ccu~c"cR"c#cu~c"cP#c>cu~,c9cu~9c=cR=c>cu~,c=cPccu~ccu~ccRccu~ccPV;VbdVV V(FVMVVVAu"p|"+R+PScSSUPUcrxS000(=0SSSSSUPUcrxcks|kwPws|XcPqwPws|qSudPududududucucPP(=ud.8uc8<R<=uc.<Ps4s4 s4uPuPuP (uPFuPuP)02;P;buDuDuP0 (uDFMuDMSuPSwuD00uD0c (c Fc 1(1F1uu u1RR R}(}F}RzRzRz(RzFRzuu uu0uLuuttuPs"SuHuHSuH (uHFMuHMSSSuHSuPuPuP (uPFMuPuPuPuPP111 (1FM1111PuT%/PuTuTuTuTSuTuTuTuTuTuPuPuP9;P;uDuD (uDFMuDuD9;Q;buTuT (uTFMuTuT911 (1FM11;QVV (VFMVV9;P;SS (SFHS;WVWbv|V (VFMVV;TSTbs|S (SFHS(SFHS(uDFMuDuDduTuTdkVdVVksVsxv|xVv|kxud}udRudud}PuTuTfsPswuDfwuPwuPuPuP~uPuHudRudP:d'fuT1fguTgRgLRgZgPZghL:d_duT_ddu`ddSdeu`eeSeVeu`VeaeSae'fu`1ffu`ffRfgu`ggXg gR g&gX&g5gS5gJgXJgNgRNgOgXcg|gX|ggSggXggS_d'f|1fOg|cgg|_d'fuT1fguTgOgLcggL_d'fW1ffWfgu@gggOgWcggWggggWtdxd0ddSdeSe4eS4e5et5e6et6e:etcgygSggS_ddu`ddSdeu`eeSeVeu`VeaeSae'fu`1ffu`ffRfgu`ggXg gR g&gX&g5gS5gJgXJgNgRNgOgXcg|gX|ggSggXggSxddVddPdeVe#eP#eeVg5gVcgygVggVggVggVddRddvsdevscgxgRxgygvsddSdeScgygSxddWdeWcgygWggWxdddecgygggxdduPdduPddQdeuPeeQeeuPggHxddu`ddu`ddSdeu`eeSggSddu`ddSddu`dduPddQdduPddPxdduPdduPxdduLdduLddRdduLddPe'f 1fOg gg e4eS4e5et5e6et6e:etggSe'fW1ffWfgu@gggOgWggWgge'f1fOggg>eVeSVeZetZe'fuL1fguLggDg&gS&g'gt'g(gt(g,gt,gOgDggDggD>eVeu`VeaeSae'fu`1ffu`ffRfgu`ggXg gR g&gX&g5gS5gJgXJgNgRNgOgXggSggXJeVeu`VeaeSaegeu`JeVeSVeZetZegeuLJeZePge'fuL1fguLggD5gOgDggDmeeuPeeRe'fuP1fguPggHggRggH5gOgHggHmexePggPggDggHggRggHggPggHggDggRggDggPxe'fu`1ffu`ffRfgu`ggXg gR ggX5gJgXJgNgRNgOgXggXxe'fuT1fguTggL5gOgLggL~eeSe'fud1ffudffrfgudgg\g gr gg\5gJg\JgNgrNgOg\gg\e'fuX1fguXggP5gOgPggPe'fV1ffVggV5gOgVe'fuh1ffuhffrfguhgg`g gr gg`5gJg`JgNgrNgOg`gg`e'fu\1fgu\ggT5gOgTggTeePe'fu`1ffu`ffRfgu`ggXg gR ggX5gJgXJgNgRNgOgXggXe'fV1ffVggV5gOgVeeSeeSees|eeSeeSees|eeSees|eeuPeeuPeeReeuPeePeePe'fu`1ffu`ffRffu`fguTggLggXg gR ggX5gJgXJgNgRNgOgXggXee uhu`4ff u\uT4efS1ffSggSee uhu`4eeSe'fW1ffWfgu@ggggW5gOgWgge'fu`1ffu`ffRfgu`ggXg gR ggX5gJgXJgNgRNgOgXggXeePg gPe'fuT1fguTggL5gOgLggL1fguTggLggL1fg1gg1HfguTggLggLHfg2gg2bfguTggLggLbfg3gg3ffQfguggggffVffsggVffWffsggWfguggggfgSggPggSggtfguTggLffWffVffVffv|fgVffVffv|ffVffv|ffu`ffu`ffRffu`ffPffPfguTggLff u\uT4fgWff u\uT4ffW:gOg@@gJgXJgNgRNgOgX@gNgPggWgg@ggRgg@ggPh&hP&hhShhPhhShhP"h&hP&hhShhPhhShhP/h:hP:hhWhhW/hhshhP#hhshhP#7hbhVhhV>hFhPJhbhVhhVOhbhughhugOhVhPhhPhhughhRhhughhPhhhShhPhhSlhvhslhvh0lhvhsvhhShhPhhS=RWZW=RZPRWZWWWSRucZucucucS^PP^RZdrQjVjrQjrQrSs|Sr{S{s|Ss|rududrPP0S s 'SZtSSud'udZtududud'ZtudPud'uduc ucR'ucPud< PucRucP'6u 69t9=t'6u9=tIRPt|PuducRucPESudSudYSS\ucuc\gPt{PgtwPtuTuTwQWwPVv|VVv|Vv|ududPP0Vv#VVtVVud#udVtudud#VtudPud#uduc ucR#ucP PucRucP#.u ./t/3t#VW?PP  3S38st8DSSst3S3<stss|3s3<s|o%0o07R7<oP%7P"P7IPPXuPuPuP#&P&,p|Uu#Xu#UXPXRXuPXoRouPRuP^u#Xu#^aPauTu#Xu#P s2&ժzXoPo{ s2&ժz s2&ժzP s2&ժzXoPo{ s2&ժz s2&ժzP s2&ժzX{00PXuL{PuLuLX1{111S{SPV{PVVVVvtVVVVVVVVVuLuLuTuT#uT<PuT#uT<P P XSSSiZiPZi l+ll5iGiD#GiLiPSiZiPZi l+llSi l+ll[ifiw$fijip~[iciw$#cijiPsiuiPkkPjkrkkrjkDkkDjk[kk[jkDkkDjk kk jkDkkDk.kPjkw$k kp~jkw$#k kPkkP ovv> )w7w> bstWovvW)w7wWbslsqlsqsPst&ttovvvv&)w7wxstWovvW)w7wWvvudstovv)w7wsspssPstV ovvV )w7wV sspssPstudovvud)w7wudvvudst\ ovv\ )w7w\ sspssPstV ovvV )w7wV stpt tPttovv)w7wttudovvud)w7wudovvud,tt)w7w,t9tp9t>tPEtt)w7wEtOtpOtTtP[ttz )w7wz [tetpetjtPttudtt07wJwud7wJw0ttPtXvv)wSwzwtVvWVvWvudWvXvt`v)wWSwzwWtXv4v)w4jwzw4tVvWVvWvudWvXvt`v)wWjwzwWWuuuXvvv w)wjwzw uVvWVvWvudWvXvt`v)wWjwzwWv wud-uXvvv w)wjwzwCuXv vv w)w jwzw WuWvudWvXvt`vvud w)wudjwzwud w)wudwuXv vv jwzw uXvvvjwzwuWvudWvXvt`vvudjwzwudvvuduXvrjwzwruXv4jwzw4uXvtjwzwtuXvjwzwuXvjwzw4vWvudWvXvt`4vXv0UwjwudUwjw0wwWwwtwwPw!xW!x"xuD"x#xt@#xyWw xS#xxS9y;ySwwPwwtwwtx xP#x3x0x xu`#xxu`xxRxyu` x#x0,xy0 x xud,xyudExNy gyy Ex;yV;yNyu\gylyVlyyu\yyVExOxpOxTxPUx9yxgyyxUx9yVgylyVlyyu\yyVUxxSUxXxv#dxhxphxmxPtx9y0gyy0tx~xp~xxPx9yuTxxSxyuXy)yS)y9yuXxxPy&yPxyu\)y9yu\xy0)y9y0xyu`)y9yu`xyud)y9yudxy0)y9y0xyS)y9ySyyu\)y9yu\y yP)y6yP;yNyu\;yNy0Nycyu`NySyudSyZyPZycyudwyyuT}yyuSyyRyyuS}yyPyySyyutyytpyySyyutyytpyyusyytoyyusyytoyyPzzuszzRzzuszzPSV"-SV^fSV"-u^unusu"-u V^u VVnu VnsVsu V"-u^unusuPSusRusPutusRusP7S(us(,R,7us,PPeutV`us`dRdeusVdP@zzSz {SSV"-SV^fSV"-u^uruwu"-u V^u VVru VrwVwu V"-u^uruwuPSusRusPutusRusP;S *us*.R.;us .PTiutZdusdhRhiusZhP{"{P"{i|Si|m|Pm||S&{j|Vm||V{{P{K|Um||U||U&{i|Si|m|Pm||S1{4{p$#4{?{pX|j|VX|m|0SV"-SV^fSV"-u^unusu"-u V^u VVnu VnsVsu V"-u^unusuPSusRusPutusRusP7S(us(,R,7us,PPeutV`us`dRdeusVdP||P|r~Sr~v~Pv~~S||P|6}V6}v~v~~V~~|r~Sr~v~Pv~~S||p$#|}p}}0}}V}r~Sr~v~P~~S}}s }}P}}P`~v~`~v~0~SS u  t ISI]u~ 0 PWPWPǃ W GW"P07p0.7uH0.uH0.ǃ uH0.  tD0. ]uH0.W0́u0u 0G]uṔuu PG]uQ́uu QG]uWss sGIsI]u#D0uLʁPʁ́uLuL 0G]uL|́SԂ#SESGISI]u#ŚSSGISI]ússGIsI]u4P uP uP#uPuP t sԂsWwWĀWĀʀw|RƀR 0mW SmS sms.W.7w7^W^mwmS"P".w2$q".7w2$q"OTw2$q"m ms|ԂsԂsԂsRRނWwEWG]WW#8s8<P#Es̓уQ"QуԃQԃqqPSV"-SV^fSV"-u^uruwu"-u V^u VVru VrwVwu V"-u^uruwuPSusRusPutusRusP;S *us*.R.;us .PTiutZdusdhRhiusZhPhipt0.{{QV ܄PV܄PS PVOVzV}ƆVOVzV}ƆV]_P_uTLԅPԅ|uT|}tP}ƆuTՅƆqvPvws$w{p~qvpv{PPPQ}Qq}qud\|ud|}t`}udP}P}VzVVP4P4ySS5}L}VVVV.VaVVV*RVpzVYu6pt67w<7<pl6P67w7<px"6pt67w<7<pl"6P67w7<pxOu\u\cgu\u\hwrtw}w<}phnrhnsSswrhw}wH}pxh00cg00hwrtw}w<}ppxshnrhnsSswrhw}wH}pxplsxQplsxpxsSPs u\u\udPududu\u\ududu[u[PPu\udu[Ru[P)uT<$)p<).uT<}p<)uP.cuPgluPuP~uP)TuPT0PuD_auDacuPgl0uDuDuPuDD0Hd0dpuDz~0cc gc ~c c1g1~1Ku.ulu1"Q.QlQc g ~ cglt~Ku$.u}u)u)0)uL)Ku)?S?KuKTsxacsxsx)/uPuT"/6P6uH.cuHgluHuH~uH4?S?KuKTsxacsxsx46P6TuHacuHuH^`S`uP.auPgluPuPuP*uPHpuPz~uP^`P^1.a1gl111*1Hp1z~1^`P`uTPgluT*uTHduTz~uT^`S`uTgluT*uTHduTz~uTduTgluT*uTHduTz~uT*uPQduPz~uPPuD.auDuDuDdpuDQuT_auTuTuTdpuT1.a111dp1PS.aSSSSst_aSSSS_aSSSSSuDuDdpuDuT.3uTVV._VVvtV.3vtvv|v.3v|u\u\ R u\.3u\ P3_uT:FuTPuDuPuPDHuPpzuPuP*DuH*DuH#3=u\=ARADu\3APWWb}WWWWb}WWPuPtLPauPabHbuPχ(-P-.s$.2p~(-p-2P;SVSovxb}V;>P>eQeuTtPuTbtQt}uTGeQexuTGSVSovxGVPV`q`epxKSVSovxKVPV`q`epxx b } xWWPP^S}Sb}1b ݈*u*+ +KuKLtLguluÈ*ul*+d+KulKLthLulÈutP*ut*+l+KutKLtpLutԈut)S)*uh*+`+JSJKuhKLtdlnSnuhutP*ut*+l+KutKLtplut)S)*uh*+`+JSJKuhKLtd*ug*+_+KugKLtcP+7P*ul*+d:KulKLth*ut*+l:KutKLtp*uh*+`:KuhKLtd+P:FPNlulNlutT^ug^bRblugTbPt~ug~RugtP  pVswVy{VuiSsSbVbivlswVy{VeSeislsS$_VswVy{V$_SsS}s ugRugPsugRugPSSuutuutpuuLu[wlwlLwl[WWLW[wlwlLwl[WWLW1w ",uT,0R01uT"0P1Hw7AuTAEREHuT7EPiSspsp SipuTxuTuT uTu`uSRuSPuXuSRuSPplvDpXQpXv(u p0x000plvDs|spvpXQpXv(shs\v|Rshs\v|s|spvVSstvstPttstshvsPss|vsxPslv s Sv puTxuTu Q uXPttpuXxuX u #qP%(u`(+P+/t/3t3pu`xu`%.q .3P9=P=AtAEtEpudxud9:u #=@p@EPLpuTxuTLpudxudOpuSxuSOVPxPVpu`u`\puSuS\cPPcpuXuXipuSuSipPPwDwDwDxuDuD uDuDLhuD uD #0#4S7:u@uDS0 uD3aSam0 uDLhuDc  c c Lhc 1 11Lh1uxuu1Q{QQ    Lh x      Lh uuuu0uuS spspS  SLhSuDw"2WW WWLhWS spspS  SLhS WW W WLhWw uTRuTP wuT R  uT P xuDuDuD3muD u tt x1113m1#4SS3aS#$u *.t#x1113a17xWW7@S7xSS@]S]aslaxSSsl@]s ]asxs sxFauTuTFMPPM]s]aspsspSauTuTuTSZPP@]s]as|axsss|@auTgquTquRuxuTuTguPWWyuD .uDCLuDLSVSWtWXvlXaVLSVSWtWavlmyWĉPĉ͉u#'=P%W'W V'6V6Iv`IKVikV v '6v 6IVIKv ikv  v IKv ikv  WIWSIS‰WIW‰SISKisQ[ug[_R_iugQ_Pq{ug{RugqP pۊVۊu tV.u 3Lu w u# t# Lw w Lw ۊVۊu V.u 3Lu SLSۊVۊu V.u 3Lu SLS3s%ug%)R)3ug)P;EugEIRILug;IP_Vu tҋVҋu  u \Wut WgWЋ WgVu ЋҋVҋu  u gSЋ SkVu ЋҋVҋu  u kSЋ Sҋs؋ugRug؋PugR ugP"^V^yu yztzVu Ɍu "xWzɌW*rWɌW*^V^ru Vu Ɍu *iSɌS.^V^lu Vu Ɍu .iSɌSsugRugPŒugŒƌRƌɌugƌP  QVTXVuJSTSCVCJvxTXVFSFJsxTS$@VTXV$@STSXnS]guggkRknug]kPwSwuwutuutNuuu"wx"+P+>wxwxwx>WWW"wx"+P+>wxwxwx>WWWWu`Ru`PMQVQRtRVtV{v|jnv|v|MVPVu`u`fu`u`u_Ru_Pf~rx~VSflrploPo{rp{~Vf~u f00fj0n0flrploPo{rp{~V~vpsprxPx~p vpspVSVSs|su`Pu`u`u tPttududu #pPu`u`ududu_u_PPu`u`u_u_PP3w8 q8Mfq83uP <uPuPuP3]uP]0VW <WVVuP-@uP@N0[a0k0fc c c f111Cu u<fu1,R R<fRf4 4 4 / </ Df/ / / Cu uMfu$3u$30$3uL3Cu3OVO]v|v|Vv|-@V38uPw"8HPH_W_uTuTuTW-@W[auTkuT?OVO]v|v|Vv|-@V?HPH]WW-@WuTu`Ru`P_uP <uPuPuP[auPkuP_gu _gW_1 <111[a1k1_WWW[aWkW_guPgVvxvxvx[aVkVgWwx[aWkWgVvx[aVkVtW[aWkWtV[aVkVkVpzu`z~R~u`p~PuPStsxSStsxVVVu t1 <111PuT uTVV <VVvxV Vvxvv|v vv|u`u`Ru` u`PVvx Vvxu` u`P P"P"PuPStsxSStsxNWuP(uP@NuT]SaSu(S 1VM^VŽV V|V(*V]SaSu(SP+Va|P|ŽV(V}Ž(Ž9=V=>t>BtB`uL`atHŽuLuL,uL9=uP=RVRStSZtZ`uP`atLŽuPuP,.V.uPH]s,ŽՏs,s,0s,HMs0ŽՏs0s00s0K]s,ŽՏs,s,0s,VZtZ`uP`atLŽՏuPuP0uPVu@ lu@Տu@0tu@VZPZ`u`atŽՏuu0uVkVk`uX`atTŽՏuXuX02V24uX46V6uX`kVk`uX`atTŽuXuX46V6uX`fPfou`ouPu`u``at\Žu`u`4u`lou`ouPu`u``at\Žu`u`;u`lV`u\`atXŽ u\ Vu\Vu\u\;=V=[u\[]V]u\|`u``at\Žu`u`;u`|u`udӍu\ӍuX`uP`atLŽ uP u`-ud-<u\<LuXLuPuP;=u`=[u\[]u`]tudtuP_W_`ud`at`ŽWW;WP Pu`udRudP`u\`atXŽ u\u\u\;u\`ud`at`Ž ududud;ud`ud`at`Ž udududtudud`u\`atXŽ u\-ud-u\u\tu\udӍu\ӍuX`uP`atLŽ uP-ud-<u\<LuXLuPuPtuP`u``at\Ž u`u`u`tu`P'P]tudcmu`mqRqtu`cqP`u\`atXŽ u\-u\u\tu\Ӎu\ӍuX`uP`atLŽ uP-<u\<LuXLuPuPtuPȍ`ud`at`Ž ud-ududtudȍӍP-6PӍ`uX`atTŽ uX<uXuXtuXӍuX`uP`atLŽ uP<LuXLuPuPtuPٍ`ud`at`Ž ud<ududtudٍP<FPuXuTRuTP=[u\CQu`QURU[u`CUP`uP`atLŽ uPLuPuPtuP`ud`at`Ž udLududtudPLVP`uL`atHŽ uL\uLuLtuL`ud`at`Ž ud\ududtudP\fP]s,Ž s,ls,s,ts,Ms0Ž s0ls0s0ts028P8MuTl|uTtuT?MuTl|uTBMudl|udBMPlvPMa> Žێuێ܎t܎t|uŽ s,|s, s,ю s, s,юێuێ܎t܎tюVՎێuێ܎t܎tՎV u@ ud PՏuPƏЏuTЏԏRԏՏuTƏԏPՏuLۏuTRuTۏP> ːS,SJOSutːVːutl.ut./tp/oututv ut/@utː utːVސutl.ut./tpusk.us./toP'P utV/O /3ut3OVWausaeReousWePsÑuÑđt đut "usÑu Ñđtđu t"u sxupxSÑupÑđtlđSuptlSup"SupuoRuoPSÑupÑđtlđSuptlÑutÑđtpđuttpÑuoÑđtkđuotkPut<đϑPSБݑupuo֑ݑuođP֑P`ڒulڒےdےQulvڒulڒےdےulQulْSْڒutڒےlےS!S!6utڒuڒےےu6uْSْڒutڒےlےSڒukڒےcےukPÒs<ےPÒupupÒSutÒPPÒڒulڒےdÒے0ul0!6ut'1uk15R56uk'5P6Mup<FukFJRJMuk<JP\oOO\oQ !-GbkYt~VCKKyWulnrL" 1\T=R =mckKhfh\\hhhhht_Ex]~FF~hlszpsz;>AFdl +.16T\{~kks3@Pafiw  ) )09 09 09 ['8;@-8;@ ['8;@-8;@/27$/27q| q| (0q|       &035@&035@@X@IXadgadgq|adgjjq|    +     < H P S t }    4;AP8;APA e h k   R  C34@  #VY\_b)1=qVY\_bl  )1)1':=@:=@JX`:=@CCJX`z%2%2`z`m`ffmmzmssz!dgl 7Q7= =Q Qdgl QWWdglsvy9<A"RT\psv|.BDL~XfhNZ 6AHK 8,8;<Uade~8H8HHXHXXhXhhxhxx xbdl  U[_psuw:n|:GLQGLQdGL)C)1CHwz`w `n   8 !#! !#! !#!!s"""!!!s"""!!!!!!!""#"!!""""""""j"o"""e"j"#"e"""["e"""########%%&&;&H&X&b&f&k&X&b&f&k&8A8A"AYAG"GY"/Yy"(Y_(/_y0909!9Q9>!>Qd''''d'n's'u'w''''''(Q)X)t)''(H)`)t)((2):)=)@) (2)`)t)$(((+(2)`)t)+(8(((((H(((2)`)t)z((`)p)()p)t)* * **R++,0,3,5,@,,z++++,,++++++++++k,,++++++++@,P,++++++@,P,++P,`,++P,`,++++++++`,k,++`,k,,- -"-//////000 0000000000000000000000U1h1s11111B1H1K111B1H1K1U1h1s1B1H1K1N1N1U1h1s112 2-2@22122 2r2222 22@2W222 2 2 22@2W2222233-3f32222222222222222332222332222223322223322223322222233x3{3~3334(44x3{3~33x3{3~3333333333(444333333(4443333T4n4333344333333444444*5B5444 54444V5X5^5n55:655555655555655555556F6L6R667#7077^6666O7d7k66666666@7O7666666@7O76666666677666607@766666607@766 777#766 7777667#77 77788891969888919698819698889d9f9m999w:::9A:C:F:::;:A:C:F:J:e:::U:e:::U:X:[:^:X:[:^:e:::/;?;B;G;4;?;B;G;;<<4<;<< <~<<H=p=J=M=R=p=<<<<< ======= =6===H=p=====(=p=========(=p==2=6===H=>>>> 8C 8CS>V>X>x?~??????S>V>X>`>f>m>s>>>>`>f>m>s>>>>?? ???`>f>m>s>>>>>>>>>?? ? ?!?o??? ? ?!?Z?x?{???{?~???{?~?????@GAXAA??@@XAhA??@@$@.@1@:@:@\@_@b@hAAB@O@R@S@V@\@_@b@hAA\@_@b@x@b@l@o@x@x@@@@AA@@@@@@@@AA@@@@@@@@@@@@@@@@@@@@@@@@@@@@@#AAAAAAAA A A#AAA#A1A4A7A1A4A7AGA1A4A7AGA1A4A7AGA TgjmAAAB!B&B0B0C3C5C@CE0BCPDDDDFAFGFGFJFFFWFZF]FtFWFZF]FtFWFZF]FtFFFFGGGGDHFFFFFGGGGGGGG)G,G/G)G,G/G?G)G,G/G?G)G,G/G?GKGNGQGGKGNGGGKGNGGGKGNGGG`GmGpGvGmGpGvGGGGvGyG|GGGGGGGGGGGGGGGGGGGGGGGGGGGGVH^HbHHHHHHHHHHHHHHI IHHHHHHHHI IHHHHHHI IIIII"III`JmJJ'I2I7I9INIQITIdIgIjITI[I^IdIgIjIdIgIjIzI}IIdIgIjInItIzI}IIIIIIIIIIIIIIIIDJGJJJ`JIIDJGJJJMJIIMJ`JIIIIIIIIJ J J JJ J JJ>&,39QT|&,39QT|&,39QT|1>DFORSORSW\behbehrbehkkrJJK+PdKLNN*OXOOOsK}KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKL L LKKLL L LL L LLLLLLL,L/L2LL#L&L,L/L2L,L/L2LBLELHL2L9LXSX1X7XSXcXYYY#\&\)\8\6]YYYZ[[\6]YYYYYYYYYYYYYYYYYWZ]6]YYYYYYYZZ ZZZ ZAZWZ]Z{ZZZZZZWZ]Z{ZZZ[['[8\\\\['[8\\\\[#[8\\\\8\Q\`\\\\;\=\C\E\\\E\Q\`\\\\`\\\\'[*[-[8['[*[-[8['[*[-[8[*[-[O[b[h[i[b[h[i[r[x[{[r[x[{[#\\\r[x[[[\\r[x[[[\\r[x[[[[[\\F]I]S]]]_Y]]]_p]]]_]]]]]]^^]]^^^^]]^^^'^*^8^;^E^H^X^a^k^n^^^^^^^___(_+_,_<_?_B_,_3_6_<_?_B_<_?_B_R_U_X_<_?_B_F_L_R_U_X_R_U_X_h_k_n_X___b_h_k_n_h_k_n__h_k_n_q_]]]]]]]]]]]]]]]]___daxaa_@axaaaa__````+a4a```#a&a+axaaaa``` `` a` `````` `a a`` `3`6`9` `*`-`3`6`9`3`6`9`I`L`O`9`@`C`I`L`O`I`L`O`_`b`e`I`L`O`S`Y`_`b`e`_`b`e`u`x`{`e`l`o`u`x`{`u`x`{``xaau`x`{`~`~``xaa`` a#a&a+a`` a#a&a+a``````````````@aNaQaTaNaQaTadaNaQaTadaNaQaTada-@K @K @K$@K$@Kaccdbbbbb?bcd"b/b2b3b6bdQddd7c=c>cmc d0ddd7c:c>cBcEcmc d0ddd7c:c>cBcEcJcMcOcJcMcOcYc\c_cYc\c_cmc d0dYc\c_cbcbcmc d0dzc}ccczc}ccczc}ccccccc0d>dcccc0d>dcccc0d>dcc0d>dcc0d>dd7eHeeddddd7eHeeddddddddddddddddd$eHeeeeeeeee$eHeXeeeeee$eHeXeeeeeeffffg-gsgeee)fff\gsge)fff\gsgef f ff f fffffff)ffffffff)fff)fnffffg-gAgFf^fafdf^fafdfnfff^fafdfgfgfnfffeeeeffffffffffffffffffffffffff8Py,8P\18P\-:WJXuggg@igggggggg.hGhJhMhhi:hGhJhMhGhJhMh[hhhGhJhMhPhPh[hhhhhhhhhhhhhhhhhhhhhLiPiSijjjjkjiijktiiiiiijkiiiiiiiiiiiiiiiiiiiiiiijjjiijJjjjii#j1jjjii#j&j&j1jjj&k(k/k1k4kkkk[kukxk{k[kdkokukxk{kukxk{kkkkukxk{k~k~kkkkkkkkkkkkkkll llll llll llllllllllllllllllllllllllmmm mmmmmm mmm m*m8m@mmm m#m#m*m8m@mmmmmmmmmmmmmmmmmwozo{oooooooooooooooooooooooooo1qZq_qhqkqmqoqtqFqZq_qhqqqqqqqqqqqqq ruxl cfil "(=@\"(=@\Rl"(=@\6>\6krY\c(.5JJY\cY\cr|rrrrrr|rrrrrrrr\s_sbslsss\s_sbseseslsssstt tt;t>tkt8t;t>tKtttttttttttttPuTuXuZuPuTuXuZuPuTuXuZu y| cfiq "(=@\"(=@\Wq"(=@\6=QT^6kqqzy&  &`cj/5<QQ`cj`cjyuuuuvvuuuuuuvv_vHwXwwwvzv}vHwXwwwwvvhwwvvhwwwww&wXwhwwwwww&wXwhw&w6w9w>w,w6w9w>w(147147G147G147Gx,x/x2xxxx,x/x2x,x/x2xw!+ u~(} 0 "# G[^a[^attєӔ<H &&&HKN`.;>?BHKN`KNcmpHKNadgNX[adgЕӕ֕ĕʕЕӕ֕Еӕ֕Еӕٕ֕^0`ak0HyƖƖ֖ٖܖ֖ٖܖ֖ٖܖΙΙ)ΙhӘ՘Ιԙי))))=@B=@BPSVPSVfilPSVZ`filfil|lsv||/24/24BEHBEHX[^BEHLRX[^X[^pX[^aї ): /: ,9PX29PX9FXp9?X^?F^p F`,9`h29`h9Fh9?hn?Fn kx$kx$_xERKRR_xX_x k k$k$_ERKRR_X_ <<0XdHKNQx@H@H @CD,@CD@CDMPSMPS]xMPSVV]x]j]ccj @CD,@CD@CDMPSMPS]xMPSVV]x]j]ccj5DORUORU_ORUXX__l_eel AP7i1]y|1ly|PXPXXwX^^www}}0%%00A7066A7&47:47:D`h47:==D`hDQhDJhnJQn !pݛ pݛ#0 $@ $@ 3HȜ,HȜ(HȜܜ ՝ݝܜ ݝܜ ݝ՝՝S` F47:` 3/` 347=BES3F47ABES3F\Z]`h\zh{\oh{zZ]`{zZ]`{٠ΡHH٠HΡàǠ٠HΡߡ0ߡ0ߡ0@LS{~@Lh{~@EhmELm{~ʣѣʣããʣ3EPp!p&QQ`]`cfpxpxȤ֤ͤХ/25#)/25/25E5<?EE^adEQTUX^ad^adh{~hrsz¥¥ϦϦ8x8gWZ]gWZ]``gY` ǧѧԧݧݧ``.14%(.14.14G4;>GGiloO\_`ciloilooy|ĨǨʨĨǨʨĨǨʨڨݨʨѨԨڨݨڨݨ),/9),/2299F?F!*ѪMux{ux{~~ѪêêѪVY\_e7VY\_emȫ˫Ϋȫ˫Ϋѫ1NQT`|E\o|   7 &&77O7==OOgOUUgggmm  .KNQ]y|=Tly|///G/55GG_GMM__w_eewww}}1B0JBX[^JXjyX`X```ff  '' J  J  ,/0,/0:=@:=@J:=@CCJJ'=cvy|vy|vy|9<? #9<?<?<?9<?xUhknhknxhknqqx,/2 &,/2,/2kH[^a[^ak[^addk9<? #9<?<?<?9<?xUhknhknxhknqqx%(+%(+dATWZTWZdTWZ]]d9<? #9<?<?<?9<?xUhknhknxhknqqxAKPVY]`ȭhuv{~ͬЬҬͬЬҬ  aINT]$'*;>?*14;>?;>?IQT`h`h{ܮ0Ʈɮ̮ܮƮɮ̮ܮƮɮ̮ܮ:=@ -014:=@=@:=@yViloiloyilorrycpЯpuůȯ˯HKNѱVY\n\cfnwz}wz}wz}ѱϰİǰϰذ۰ްذ۰ްذ۰ްADGcADGcADGcKWPWc *8cy{~;m  %(+;%(+;%(+;WZ]CVehk}kru}8C8C8C8C8C޶mʵAXʵʵʵ3*A  #3 #3 #3fikXmsvysv{}sv{}sv{}¶޶¶޶¶޶ƶҶ˶Ҷݷ'8 øƸɸ۸ɸиӸ۸Tq"%7%,/7>ADT>ADT>ADTƹZqƹƹƹݹ8Cݹ8Cݹ8C8C8C9<? #9<?<?<?9<?xUhknhknxhknqqx9<? #9<?<?<?9<?xUhknhknxhknqqx@YhRhny*AĻǻɻAXѻԻ׻׻޻ #%aXo-03D39<DKNQaKNQaKNQaaompssz}¼Լ¼ɼ̼Լۼ޼ۼ޼ۼ޼@ ##*-0@*-0@*-0@@ܿLORcRX[cjmpjmpjmpܽܿƽɽ̽ܽƽɽ̽ܽƽɽ̽ܽܽ   69;x6CFI[IPS[behxbehxbehxx6RϾҾվϾҾվϾҾվݾ9<? #9<?<?<?9<?xUhknhknxhknqqx O1 2 '*29<?O9<?O9<?Oehkehkehko{t{  ~ J-"%-47:J47:J47:Jmpsmpsmps{.27>PSUr]`cucjmu||| #CP[ #CP[ #CP[+7P[07P[ vy|Rt41.Ro3DE3DEZou ou '2 '2 '2 '2771e7IR\]IR\]1IIR\]bi}b%+1y9?BTBILT`fiy`fiy`fiy    1b ;I ;>>Ivy|#)N^ (P(L Lp""p0Pp@P0@ )/6<WZ)/6<WZ)/6<WZ [bv} [w`fp-8:-8:Upv pv(3(3(3(39EFBHKkBHKkBHKkO_T_kP`tP`FLOpppp.FLOFLO`pFLm`pFLw`pFLwzz`p  %%8@&X_blo{~ovy{TWY_WYppsv{Z`mc#&P4L###4)4P`4D`pQ_}k#&X9'T  (((9.9Xh9I hxVd'AP(+-:$@K$@K @$4)4@_GSLS_lellxlqqx   V[^ddgjpgjp0?Ebm|m|m|m|O]$*-e$D$*-UOO]e]e,AP]`p~cfpcfpcfp{VYp~~`p```@Ph3>PhhCQQYYh0C0<Hb/:Hbbz>JzJQY[QY[f > 6`il>AES@Ph3>PhhCQQYYh0C0"" QdQd!("034_hk"bhk(y((8Q8Q8>AQ(8(87R`cfw%0G%0G%036GVYehnz0o0o$'OoOoOo'-ayUo'-ayUo'-ayUoZy|09UZy09UZv09Uss,9hks=R 0 0 "%"%"%3"%3"%((33DP`3DP`9DP`DU`pJU`pUfpUfp[fpfzlzz   88MiLi |]XuH]fUWgWgWg,4:=W4:=@EKSVfEKNQSaft%%13>DP h  \  \ ,h ,h 27rZx%;>A(25;>A;>AQTWAHKQTWQTWgjmW^agjmgjm}mtw}}XdXd -03 -03-03AHX-0366AHXHV3Zilq>KNQ>KNQKNQ_KNQTT__peppvB}BvOUXHUX%0G%0G%036GUX[ 00?0?    @Ph3>PhhCQQYYh0C0@Ph3>PhhCQQYYh0C0=p -014::=p:=s}=ILOILO_ILO_ILO_@Ph3>PhhCQQYYh0C09;?Ph #*X#6X69?B9?BX!8!8pCFKSFKU`SU`ez}}>cfm>CFNN^`c^`fmsvz % '2%'27=[]`=IIOO[]`svz 47:H beh` "(=@\"(=@\`x"(=@\;?];beh{{4H`H`H`H`%%%4%(/%(/;PSV`PSVYY``mfmHNQ[NQ[g0:  $'*:$'*:$'*:PSVrPSVrPSVrZf_frx\beobeo{ N^s1&)18;>N8;>N8;>Ndgjdgjdgjnzsz!$'!$'67Na !$'7!$'7!$'7\_ailoovy@N@N@N@N@N0@0@nqtwqtw       B E H    P S V h V ] ` h q t w  q t w  q t w                               &      &      &           & 3   , 3           L R U _ R U _ k                              > N c    !    ! ( + . > ( + . > ( + . > T W Z v   T W Z v   T W Z v   ^ j   c j   v    |           &  E !  8@@HHW@Gyy}y}} ;PSUXhx !PSUXv |  fp         :GQf                                         ) ') ') ') '):'G):'G)/'-/:-G:KGg:KGg:@GM@KMgK\gKQgmQ\m$$:Q$)/:ADGUP`ADGJJUP`Uf@P[f@Pq@`{8@`l`l`l00fs35;=CIN^s^f*@ 9<?&9<?9<?M9<?BBMSdfh   / / WrWZ Zrrruu*##*55%H5djn5dgns5}Nr`morVsVs<\rux_ilruxruxrux|_bes_behhs(479N_be'-0'-0:'*03*-3:DNQ]]qtwtwqtww&&  "(58:FILSLS ] ] ~ ~7:GJ &),8cfipBHJPPcpLjx""<_p <TW]p z = ` p    != [ ] ` p    !X [ ] ` z        !R!!!1"@"p#`!c!f!!"7#]#p#`!c!f!!"7#]#p#"""""""7#]#p#!!!1"@""7#]#!!!!@""7#J#!!!!@""7#J#!!!1"J#]#!!!1"J#]###$P$$.%A%T%##$P$$.%A%T%$ $"$($($A$$.%A%T%##P$$$$.%A%####P$$$$.%A%####Z$`$b$h$h$}$$$.%A%l%%%E&P&(z%%P&&''b(w(z%%P&&''b(w(Z&`&b&h&h&&''b(w(%%%%&&'8(M(b(%%%%&&'8(M(b(&&&&&&'8(M(b(%&0''w((%%%&&&0''w((%%0''w((%%&& &&&E&&0'8(M(&/&5&<&&0'8(M(&,&&0'8(M(/&2&<&E&/27$/27(&))).)8)11qD6*<*?*M*556*<*?*B*B*M*55M*a*55V*a*55a*u*55j*u*55u**55~**55**55**55**55**55++++v55++++++v55+ ,f5v5, ,f5v5 ,,V5f5,,V5f5,3,F5V5(,3,F5V53,G,v66<,G,v66G,[,f6v6P,[,f6v6[,o,V6f6d,o,V6f6o,,F6V6x,,F6V6,,66F6,,66F6,,&666,,&666,,6&6,,6&6,,66,,66,,65F5,,65F5,%-*---99,,,- -%-*---,,--%-*----565669:;;MDqD%-*---7-7--565669:;;MDqD7-9->-\-a--5659:7-9-a--5659:7-9-a-i-5659:9->-\-a---;;MDRD----%.|.::%.l.::............. ///. /// /// /56 ///// /56@/0112356W7}7U889::;;AACMD//`45CMD/012226W7}7818U88I9AA1#13`4;;818::818::01T123ACT1W1Z1]1W1Z1]1c1m1p1c1i1p11c1i1p111155115511221122W7}7U8k8n7q7v7}7 E EEEHEEFFHEEFFHEKENEbEKENEbEEFFKENEbEiEkEpEsEvE~EEFFEE!FFG2G>GHGEE!FFG2G>GHGEE!F0F3F6FJFFG2G>GHG3F6FJFQFSFXF[F^FfFFG2G>GHG0F3F6FJFE!FFG2G>GE!FFG2G>GEEEEEEE!FFG2G>GEEEEEEEEE!FFG2G>GVGYG\G_GeGKHXH*IGGGGGGGGGGGGGGGGGGGGGGGHHHGGGGGHHHH%H(H-HH%H(H-HHHHHHHHHHHHHHHHHHHHHHHHHegg e.egg>egeg:ggexeggmexeggxeeeexe~eeeee~eeeeeeeeeeeeeeeeeeeeeeeeeeeeggeeggeefffffffffffffffffgffffffffffffgggggggg"hhhhh'h-h/hhhhh7hVhhhJhVhhhOhVhhhvh|hhh=JMPJMP^JMPSS^^d0`x`x   IRxESVYSVYgtSVY\\gtgltwrtw(`t`t 038%038 ,@#&),JPU`X[^`X[g|`{X[`{X[`{^g|{`&i)i/i}jjl5iAiGiMi5i8i;i=i5i8i;i=i5i8i;i=i[ikipisicikipisikipisi~ijjjjjjjjjkkkj kkkk kkk kkkktuple iosfwdstl_function.hcstdlibbasic_ios.tccpostypes.hfunctexcept.hostream_insert.hstdio.hlibio.hstdarg.h stddef.h wchar.htime.hnumeric_traits.halloc_traits.htype_traits.hdebug.h locale.htypes.hsched.htime.hpthreadtypes.hatomic_word.h wctype.hstdlib.htypes.h sigset.hselect.h stat.hunistd.hregex.hgtest-string.hgtest-spi.hgtest-death-test.hsiginfo.hsignal.hsigaction.hstdlib-float.hstdlib-bsearch.hfcntl-linux.htime.h socket_type.hsockaddr.hsocket.hnetdb.hgthr-default.h errno.hctype.hsocket.h pthread.hwait.h mman.h sched.hfcntl.hcxxabi.h  KJ     o.{fJ1 o{.J oJ oJrJ <eYK֐ e. .dt J< itfjX JJLtJK{t<mm<m<X<mm<m<X<mm<m<X<mm<m<X<mm<m<X<mm<m<X<m4<m4<m4<m4<m4tme=m<m<XNtmz< st ~~JJo/0Ons JufJ' Xt~Os<.0P ,KK,AJ@ |J=/=/>/=/=/=/=/ JLw- SX,<./wYo3L\Y[.<m[q.{X3QtK#PJ2 KsK t-<~>?y<><~ Zj<~  t-Zf,h ~ffJi.|<JJ J9MG<FJ;.}."[ <su Z;Yd{<|<|f<|.<z< l<l<C<<|<|f<|<}f<}.j<<|t<t|< ~|<|<C<~<U1i[<|<|J} <} <}f#<b<b}<}<i <.l |t<|"jlY'<Y<=z..z. v.<kJflf<l<Jzb<z<z<C<tv7zhf>Cfvz<'zf<z<Jz< {t~X<~.<z< l<l<C<:zb<z<z<C<tv<<{JCXtz@hf<{fCfv{<Cf ȐgYK<=oi-/e<d<<;L;>;ruz<z<C<=Cf /<kJ<;=;j/.bJ=<a<<b<>^< <>;vCX=Cf=Cf I=i9 tv f lfl<C< v  fx<|C<"V#zJ#   t;=m&vCtg-u-={ <kflf<l<C<u;Qy<z<.}<ffy<{tCf{JJ{J.JL[{K;=;={f<kfXlf<l<C<t{CfK;=;={f<kfXlf<l<C<t{Cfg;uY'<Ys->-FXu otz<z<C<=tCftnfCfnCf=Cf=CXt>q<p<|J.M,@l<l<C<tlCf$s=/mffvr|< l<l<C<=Cfj#v%xtx<X l? Cf=Cfo<~<f  1l*<l<C<tvtl$Cf&s= .zc#l)<l<C<tl<l<C<=)Cf=CfȐ=vrX|< l<l<C<=Cfn<k0<k<C<o Jfk<k<C<~J<~. o<.|Xk<k<C<o%o...Pm<gfk0Cf=1Cf= Cf = Cf=.CfSf{.fn<tn<n<~~<<C<=tCf=tCfXt~. < Cf=CX=Cf=Cf=Cf#RV0 fǹ,/!;!!;!/!;!i<i<C<=Cf=Cf=Cf=Cf=Cf=Cf=Cf=Cf=Cf=Cf=Cf=Cf=Cf=CfwX <w< <iCf=Cf=Cf=Cf=Cf=Cf=Cf=Cf=Cf = Cf = Cf=Cf=Cf=Cf=CfE~:<t#~<~fC<=Cf~<<C<=CfN0!;!~<~fC<=tCf=tCf=tCf=tCfNpCf=tCf=Cf=Cf=.Cf=fCf=Cf=Cf=Cf+<~f<<~<~Y-/~t<~<C<2 CX=Cf!WYe:>r <r<C<=tCftrCf r Cf=Cft>l}n<n<C<tl<CfY;<=of<|<|} <} <|f<<|<|f<|<|f<|<|} <} <|f<<|<|f<|<|f<|<|f<|<|f<|<|f<|<t|<  p<< p#<p<C<=tCftv ot_Cf = Cf v|!WYet{<t{<t{<t{<>r!;!!;!{~<~<C<=Cf=Cf=Cf=Cf=Cf2 usc<Xa u  u uy4t|f< Xg;z~<~<C<=Cf"y4t|f<X;YxjCf=CfyfCf=.Cf=.Cf=.Cf=.Cf=.Cf<v*4zX<z<<z < 0:+!;!sf0.vf < ..zCf=Cf = Cf = Cf=Cf=Cf=Cf=Cf=Cf = Cf = Cf=Cf=Cf=Cf=Cf=Cf=Cf!=!Cf#=#Cf%=%CfXw-=S.kf yfj<p<Y;=sf Lb<d<d.Xbt<b<C<=tCfts Lb<b<C<XbCftbCf=it yfi~<<.k~yJ<y<C<=tCfty.<ty2Cf=CfȐy#<t ~yJty <y<~<<|t<~{<b=;=b.<c<~JXJP1?c{<Cf<btX=;=7%?28@?w.WGcJ{< <_JC<=Cf!b'XJ(t_Cf=Cf~f} Jt .r<.Ӓ:>v <.sJof<)fk<J;=~X  t./<{<|<~f<<kJfkf<n<|t<~f<~<C<v }. .< w)&.zf).~)<.~...l/J~/<~<C<t<|<~f<<kJfkf<n<|t<).zf).~)<.~.i/.{</<}C</<}<C<.~t(t<|<|Mj<<|<}X .l<Cf)t.y)X{fCf=fCf.~.~<.~<<C<.~ ttCf#fgs\<#\.#.hfh<.\#<\<#tK=LLLLMxo<\C<$^,hzXf]<#X#a"yXW/Xyfy<C<=C=C=C=C=CWIg;eX)<!e!<X</<!!yfy<C<=C=C=C=C=C=C=C=C=C=C=C=Cyy<#~XX~<{.{X|X,gg0 0w y ff J< ~t<9y"CXA J y ff X<y ff <~f {.~f~<C<<W(fX( K"[91e/ f"/Zz#/,}X|<<|< f}fP <f ~Xt$ 8 J <<<<MV xlJC= C= C= C= C= C= C f ~X< ~X|tC= C= C= C= C= C=$Cf JC= C!xf tC= C= C= C= C= C= C~5t0wt00SC= C= C= C= C= C= C= C= C= C= C= C= C= C= C= C= C= C= C= C= C=KC= C= C= C= C= C2R X   XXcRX   XXyC= C= C= C= C= C= C=C=C= C= C= C= C= C= C =0 C"= "C$= $C&= &C=EC= C= C= C=EC= C= C= C= C= C= C= C0~kXf  <zzzt3 .<xr r  <s<  < t v. X v< <v0w fr  <s<  < t v. X v< <v0w v  <s<  < t v. X v< <v0w wX J J0rJ00S00S00Sh:>:h g.~l.~.<n~<<n~<~<C<}fCX~X J z&0h.|<n<~<~<.֩ +hXCfk<f"e=h<h<C<=Cf~<}J.L&h<h<C<=Cf}<}J.K&h<h<C<=Cf"Jh<h<C<=Cf&h<<h<C<=Cf(hf<h<C<=Cfh<{ l<l<C<fh~<;h jfjJ~<<n~<~<C<hCf=Cf=Cf=Cf=Cf=Cf-hCf=Cf=tCf=Cf = Cf=.Cf=.Cf=Cf=.Cf=Cf=Cf= Cf= Cf=Cfg;<=i~<<pJ'h<h<C<=CfJ'h<h<C<=Cf 'hfhfC<=Cf)h<h<C<=Cf<jf<%g<g<C<=Cf<jf<%g<g<C<=Cf0g<g<C<=Cf<j<g<{ l<l<C<*g <g<C<=Cf>jXj <t}XJ!jt<j<XiJ~<<g<g<C<g^Cf=-Cfg Cf=$Cf=5Cf=Cf=tCf=Cf=Cf=.Cf=.Cf=Cf=.Cf=Cf=Cf=Cf=XCf= Cf=Cf=Cf=Cf=Cf.hfff>hP "im|<|rx{Cf t91YtCf txvԒhd>%t. <t<C<t}f.}<CX~t t Wt.Cf txY fw. ,<<2JztB><<|t<}f} <} <|f<|<}f<rC<=<C<tv{CXt2vqzCf #RxfDs( <s<C< tsCfKv " Kutzf xt. Xut~ f Xv< <vftt Xt< 5T2t< 3+?G?\<s< ptttbKt~  Xw<<wfus<~X<~2 Xs. r< Xr< r p  mKd>_824#'eJfjf-",>=-=cffc i i/df . {g. |tfctd +i9i+ib. JD[<<.XH`<trf<c<Xct}JJcf{ c f h ;gk<={<~<{JX{ yJ$;Kk yt* y*XhJJ.lJfy<{ Cf=Cf~Jf yJ>yf{ Cf=Cft;=< yJ>}f{ Cf=Cf te= | Y|fJu }< .}f X}<XS-<SfC< ~< ~<fC<=Cf=Cf=Cf=Cf < x.yJ(.=y<y<.<{J~<<<n.~<<rw{J(=;gXytCf=tCfty Cf yCf=Cf=;gXytCf=tCfty"Cf=XCf=Cf~<<~fL;gXytCf=tCftb~-yCf=Cf~<<~fL;gXytCf=tCftb~5{Cf=Cf fu<<= Xuy<}<<{t~<<n.~<<rhy<Cft{t%m.uyCf=Cf Y;y<f o~< x<x<C<=tCftyXCfyCf=Cf Y;y<f o~< x<x<C<=tCftyXCfyCf=Cf{fIX1x<x<C<=tCft<{<gfxCf=Cf=Cf #U^z<<y<}X_!<_< u~<< u~< x<x<C<=tCf=tCf=tCf=tCf=tCfy Cf=Cf= Cf= Cf= Cf yCf=Cf=Cf=Cf=Cf=Cf=/Cf h:<{<<{UX+<U< u~<< u~< x<x<C<=Cf=Cf=Cf=Cf=Cf{<gfxXCf=Cf= Cf=Cf=CfyCf=Cf=Cf=Cf=Cf=Cf=Cf)g<z<<=~f<y <z< l<l<C<:ttzb<z<z<C<tv{/hfCfv{JCfg;Vt../xJ(.Y >Vt...xtX.w<}f.Cf~< J w}fJCf~ Jf}.}<iPr><|(~<-//.3rt(~.~t(~. ~~1zXftzf[Xq<md!.bgf}.X< }87A}.|)<%< l<l<C<=Cf}}~<<l<l<C<=4 }~Cf=Cf= Cff}.X<}87A}.|)<*< l<l<C<=Cf}}D ~<<l<l<C<84 }~Cf=Cf= Cff}}<.} t}}.~<<l<l<C<=.Cffh{JCXt0t ~j: {zt z. t ~j:J+xYJ{J<N}t& |f&f |f#f ~f#J ~f#J ~<#g~.#X~ #f~ #}#f"}f"N|J<}X<}<.}fm<|C<"V#z# ffz# J #~< t&;=#z& t&}!   yJ  yJ < y< mt mt mrJ m t {< . { . {<  {< . {<nv m t < m t < mua   y < y<<nX<nX< m<nX mJ"f rJ {J r { r {$t. rX|<.nX mJX f rJ|Xnf mf    yJ  yJ < y<,.,a<,a<,a< `v,. et,{<. et,{<. `B J {< . {<  {f . {f%tNO-V<%*.-Vf%*.f%~f.<.%B%m<X8 t.&;=\J#<WJOj8[.Cf$;֔ZKUSzXxX vX uX sXrXqXpXoXnXmXkXiXgXm<[$<[tC<t<mJ<mJ<Lr[Cf&;=\f#<\#<JOj8[.Cf$;֔ZKqoztxt vt ut strtqtptotntmtktitgtm<[$<[tC<t<mJ<mJ<L[Cf>J+xYJ{J<N}t >uue<<gfg.f0e<<rxJ(.X CX~j ~J ~<>:><~<fK <t< <s J~<~<C<t |t . {X y0}.X0}< f0w.70}fJ0}< t0w}.<CX = {Jz t>;;0t {zJ000SCf f}3 t0}XXC0~J00S&9[.kf]~<~<C<fufJCX~&.dX` yX{Cf%h``{4Cf=tCf&W=?9[.q h]~<~<C<Xuf.w<tCX~ X<d.X!` yX{Cf%k`g{'CfX Cf~ ul<l<<8gfgXu< <y<{J|h,==0 J0|t <v< <t3 ttw0_< 0hXXf J 0t00S wf _8>XH*X?9idq<q<C<q Cf?9iq<q<C<w qCfwwf _8>XH*X?9idq<q<C< XqCf?9iq<q<C<]rqCfwwf _8>XH*X?9idq<q<C<q Cf?9iq<q<C<w qCfwwf _8>XH*X?9idq<q<C< XqCf?9iq<q<C<]rqCfw ~J~<~f<X<~<ff<sf<<~<~<C<t | . {X y0}.X0}< .J0|"70}fJ0}< J0|}.<Cf = {Jz t:==:0t {zJ .z<000SCff}3 t0}XXC0~J00S0l \J0; <Cf=Cf0~w 0kj ~JD}f4}<<<|f|<<|<| fs|ff|<.|JX|tf| <|JX|f~f<~<C<=tCf=tCft&| < {X yX0;0~<0}XhffCf=tCf~ttCf = {z, J;==:0XCf=Cf }xX}tw Jw< X ~,  {zX#V<Cf=Cf)tCf=CfJ0l J0| CX0~w 0kqj ~J(fX<<<= .s JJf~f<~<C<=tCft|t < {X y0}. J0|4<0~<0}Xh<CX~tCf = {Jz$ J>;;0 {zX .z.V<Cf=CX}tw Jw< XC }xX ~,.CX0~w Jw< X0kqX.1\Jۋ]z^/ 7 7z ^& u  X&z ^6<T}<{ + s< X'<<{<<{.{Xnext_segmentline_ZNSt6vectorIiSaIiEE6assignEjRKi__sigset_tPrettyUnitTestResultPrinter_ZN7testing22EmptyTestEventListeneraSERKS0_current_test_resultbreak_on_failureCStringEquals_ZN9__gnu_cxx13new_allocatorIN7testing12TestPropertyEE10deallocateEPS2_jiterator_traits_ZNK7testing8internal24HasNewFatalFailureHelper21has_new_fatal_failureEv_ZNSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE2atEjPrintAsStringLiteralTotesting_internalRawType_ZNK9__gnu_cxx17__normal_iteratorIPPN7testing8TestInfoESt6vectorIS3_SaIS3_EEEmiEi_ZNSt11char_traitsIcE4copyEPcPKcj_ZNSt6vectorIPcSaIS0_EE8_M_eraseEN9__gnu_cxx17__normal_iteratorIPS0_S2_EES6__S_oct_ZN7testing8TestCase11ClearResultEv_TypestartPrintStringTo__copy_move_backwardread_ZN7testing8internal12TypeIdHelperINS_4TestEE6dummy_E_ZN7testing8internal24HasNewFatalFailureHelperD0Ev_ZNSbIwSt11char_traitsIwESaIwEE6assignEPKw_ZN7testing22EmptyTestEventListener13OnTestCaseEndERKNS_8TestCaseE_ZN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE11ValueHolder7pointerEv_ZNK7testing8internal13FloatingPointIfE8sign_bitEv_ZN7testing8TestCase16RunSetUpTestCaseEvstrtof_ZNKSbIwSt11char_traitsIwESaIwEE7compareEjjPKw__alloc_traits >_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE6_S_keyEPKSt13_Rb_tree_nodeIS1_E_ZN7testing32ScopedFakeTestPartResultReporter4InitEvstrtoloperator<< _ZN9__gnu_cxx14__alloc_traitsISaIPN7testing8TestInfoEEE10_S_on_swapERS4_S6__ZN7testing8internal13DeathTestImpl12set_write_fdEi_ZN7testing8TestInfoaSERKS0___haystackIsNotSubstringallocatorgetwcconstruct >ImplicitCast__ZNKSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE2atEjgtest_arline_number__ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EE2atEj_ZNK9__gnu_cxx17__normal_iteratorIPN7testing12TestPropertyESt6vectorIS2_SaIS2_EEEptEvCheckedDowncastToActualType >::ValueHolder, testing::internal::ThreadLocalValueHolderBase>socklen_t_ZNSt6vectorIPN7testing8TestCaseESaIS2_EE7reserveEj_Rb_tree_node_base__niter_base_ZNKSt6vectorIiSaIiEE8capacityEvHandleExceptionsInMethodIfSupported_ZN9__gnu_cxx17__normal_iteratorIPKPN7testing17TestEventListenerESt6vectorIS3_SaIS3_EEEmmEi_ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EE5frontEv__copy_move_backward_a_ZN7testing8internal27PrettyUnitTestResultPrinter11OnTestStartERKNS_8TestInfoE_ZN7testing18TestEventListeners22SetDefaultXmlGeneratorEPNS_17TestEventListenerEHandleSehExceptionsInMethodIfSupportedMSG_EOR_ZNKSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE12_M_rightmostEv_ZN7testing8internal12UnitTestImpl21set_current_test_infoEPNS_8TestInfoE_ZN9__gnu_cxx17__normal_iteratorIPKN7testing8internal9TraceInfoESt6vectorIS3_SaIS3_EEEmIEiswprintftype__ZNKSs5rfindERKSsj__uninit_copy<__gnu_cxx::__normal_iterator*, std::vector > >, std::basic_string*>si_codebasic_stringstreamsockfd__ZNKSt3setISsSt4lessISsESaISsEE11upper_boundERKSs_ZNKSt9_IdentityISsEclERKSsmbsinit_ZNKSt6vectorIiSaIiEE8max_sizeEv~ExecDeathTest_ZNSt6vectorIPN7testing11EnvironmentESaIS2_EEixEj__numeric_traits_integerfrac_digits_ZN7testing22EmptyTestEventListener22OnEnvironmentsSetUpEndERKNS_8UnitTestEoperator<< last_errorfailbitUniversalPrint >_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE5eraseESt17_Rb_tree_iteratorISsEuninitialized_copybreak_on_failure__ZNK7testing8internal10scoped_ptrIKSsEdeEv_ZNSbIwSt11char_traitsIwESaIwEEpLEPKwTestEventListenerswap*>expected_expressiondata_internal_run_death_test__rhsactual_ZNKSt17_Rb_tree_iteratorIPKcEdeEv_ZNSt6vectorIPN7testing8TestCaseESaIS2_EE4rendEv_ZNK7testing8internal8FilePath21FileOrDirectoryExistsEv11__mbstate_tIsPathSeparator_ZNSt12_Vector_baseIPN7testing11EnvironmentESaIS2_EE13_M_deallocateEPS2_j_ZN7testing8internal17StreamingListener12SocketWriterD0Ev_ZN9__gnu_cxx17__normal_iteratorIPKPN7testing17TestEventListenerESt6vectorIS3_SaIS3_EEEmmEv_ZNSt6vectorIN7testing12TestPropertyESaIS1_EE15_M_erase_at_endEPS1_si_errno_ZN7testing8internal12UnitTestImpl21set_current_test_caseEPNS_8TestCaseE_ZNK7testing8internal10scoped_ptrIKSsE3getEv_ZN7testing8internal13DeathTestImpl11set_spawnedEbpair_ZN7testing19TestPartResultArrayaSERKS0_impl__normal_iterator, std::allocator > >vector >_ZNKSt12_Vector_baseIN7testing12TestPropertyESaIS1_EE13get_allocatorEvcopy_backward*, std::basic_string*>_ZNSt6vectorISsSaISsEE8_M_eraseEN9__gnu_cxx17__normal_iteratorIPSsS1_EES5_should_run__ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE15_M_insert_equalERKS1_FloatingPointLE_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE6_S_keyEPKSt13_Rb_tree_nodeISsETypeIdfor_each<__gnu_cxx::__normal_iterator >, void (*)(testing::Environment*)>_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE12_M_erase_auxESt23_Rb_tree_const_iteratorIS1_ES9_StrError_Destroy_ZNKSbIwSt11char_traitsIwESaIwEE13get_allocatorEv_M_insert_lower_ZNSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE8pop_backEv~StreamingListeneroperator- >_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE16_M_insert_uniqueERKSsTEST_ENCOUNTERED_RETURN_STATEMENT_ZNK9__gnu_cxx17__normal_iteratorIPPN7testing8internal29ParameterizedTestCaseInfoBaseESt6vectorIS4_SaIS4_EEE4baseEv_ZN7testing4Test14RecordPropertyERKSsiiterator_traits<__gnu_cxx::__normal_iterator, std::allocator >*, std::vector, std::allocator >, std::allocator, std::allocator > > > > >_ZN9__gnu_cxx14__alloc_traitsISaIN7testing8internal9TraceInfoEEE10_S_on_swapERS4_S6__ZNSt11char_traitsIwE11eq_int_typeERKjS2___cxa_begin_catchsrc_texterror_message_ZNKSt6vectorIPN7testing11EnvironmentESaIS2_EE5beginEvoperator delete_ZNKSt12_Vector_baseIPcSaIS0_EE13get_allocatorEv_ZNSt6vectorIPcSaIS0_EE4dataEv_Allocator_ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EE2atEjoriginal_reporter__ZN9__gnu_cxx13new_allocatorISsE10deallocateEPSsj_ZN7testing8internal23kTestTypeIdInGoogleTestE_ZN9__gnu_cxx13new_allocatorIPKcE7destroyEPS2_operator<< , std::allocator >file__ZN7testing8TestCaseaSERKS0_AssertHeld_ZNKSt6vectorIPN7testing8TestCaseESaIS2_EE4dataEv_ZNK9__gnu_cxx17__normal_iteratorIPcSsE4baseEv_ZN7testing8internal17TestEventRepeaterD2Ev_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE7_S_leftEPKSt18_Rb_tree_node_basereverse_iterator<__gnu_cxx::__normal_iterator, std::allocator > > >TestPartResultTypeToString_ZN9__gnu_cxx14__alloc_traitsISaIPN7testing17TestEventListenerEEE8max_sizeERKS4__ZN7testing8UnitTest14AddEnvironmentEPNS_11EnvironmentE_ZNSs7reserveEj_ZNSt12_Vector_baseIPcSaIS0_EE17_M_create_storageEj_Iter_equals_val, std::allocator > >InitGoogleTestRETURNED_ZNKSt12_Vector_baseIiSaIiEE13get_allocatorEvregistered_testsoperator booluser_msg_string_ZN7testing8internal13ExecDeathTestD0EvAbstractSocketWriter__ino_toriginal_working_dir_iterator_traits, std::allocator >*>_ZN7testing8internal12UnitTestImpl31GetGlobalTestPartResultReporterEvregex_ZNK7testing8internal12UnitTestImpl21successful_test_countEv_ZNK9__gnu_cxx17__normal_iteratorIPKcSsEplEinormalized_seed_ZN7testing14TestPartResult14ExtractSummaryEPKcStackLowerThanAddress_ZNK9__gnu_cxx17__normal_iteratorIPPN7testing8TestCaseESt6vectorIS3_SaIS3_EEEmiEitest_propertiesmove_ZNK9__gnu_cxx13new_allocatorIPN7testing17TestEventListenerEE7addressERS3__CharToperator<< _ZN7testing14ExitedWithCodeC2Eiunsigned int_ZN7testing8internal12UnitTestImpl34InitDeathTestSubprocessControlInfoEvignoring_casePrintTowcstold_ZNSt12_Vector_baseIPN7testing17TestEventListenerESaIS2_EE17_M_create_storageEj_ZNSt10_Iter_baseIN9__gnu_cxx17__normal_iteratorIPPN7testing17TestEventListenerESt6vectorIS4_SaIS4_EEEELb0EE7_S_baseES9__ZN9__gnu_cxx14__alloc_traitsISaIiEE17_S_select_on_copyERKS1_copy_backward_ZNSbIwSt11char_traitsIwESaIwEE6appendEPKwj_ZNKSbIwSt11char_traitsIwESaIwEE16find_last_not_ofEPKwjj_ZN9__gnu_cxx14__alloc_traitsISaIPN7testing11EnvironmentEEE8max_sizeERKS4__ZN9__gnu_cxx17__normal_iteratorIPKcSsEmIEiClearTestResult_ZNKSs11_M_disjunctEPKc_vptr.UnitTestdestinternal_run_death_test_flag_size_t_ZN7testing8internal17StreamingListener12SocketWriter15CloseConnectionEv_M_destroy_noderegoff_tparameterlower_bound_ZNSt6vectorIPcSaIS0_EE8pop_backEv_ZNK7testing8internal12UnitTestImpl11random_seedEv_ZNK7testing8internal13DeathTestImpl6statusEvlast_sep_ZN7testing8internal16UniversalPrinterISsE5PrintERKSsPSopthread_mutex_tad_hoc_test_result_bool_ZN7testing8internal15CodePointToUtf8Ejunicode_code_pointcomma__distanceFloatingPoint_ZNKSbIwSt11char_traitsIwESaIwEE16find_last_not_ofEPKwjFormatForComparisonFailureMessage_ZNK7testing14TestPartResult14fatally_failedEvString_Category~TestFactoryBasekUniversalFilter__builtin_fwrite_ZN7testing8internal13GetTestTypeIdEv_ZNSs4_Rep7_M_grabERKSaIcES2__M_copyreverse_iterator<__gnu_cxx::__normal_iterator, std::allocator >*, std::vector, std::allocator >, std::allocator, std::allocator > > > > >argvs_ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EE6insertEN9__gnu_cxx17__normal_iteratorIPS2_S4_EEjRKS2___cxa_throw_ZN9__gnu_cxx13new_allocatorIwE8allocateEjPKv_ZNSbIwSt11char_traitsIwESaIwEE6assignERKS2_summary_rdstatekStackTraceDepthFlagfreadTestPartResultArraythread_count__copy_move_b*, std::basic_string*>operator!= >_S_blackos_stack_trace_getter_ZNSo9_M_insertIPKvEERSoT___cxa_guard_abort_ZN7testing8internal12UnitTestImpl12ShuffleTestsEv_sigfaultGTEST_SHARD_INDEXMSG_CONFIRM__is_normal_iterator_ZNSt6vectorIiSaIiEEixEjTearDownTestCaseFunc__miter_basekThresholdint_n_cs_precedesbinary_function, std::allocator >, std::basic_string, std::allocator >, bool>_ZN7testing8internal35HandleExceptionsInMethodIfSupportedINS_8TestCaseEvEET0_PT_MS4_FS3_vEPKc_M_key_compareallocator_ZN7testing15AssertionResultlsIA3_cEERS0_RKT_~ForkingDeathTest_ZNKSt6vectorISsSaISsEE6rbeginEvatexitreverse_iterator<__gnu_cxx::__normal_iterator > > >kReservedTestSuiteAttributesDeathTestImpl_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE15_M_destroy_nodeEPSt13_Rb_tree_nodeIS1_E_ZN7testing7MessageC2Evfwrite_ZNKSs13find_first_ofEcj_ZN9__gnu_cxx17__normal_iteratorIPKSsSt6vectorISsSaISsEEEmmEisi_addr_lsb_ZNKSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE14_M_range_checkEj_ZN9__gnu_cxx17__normal_iteratorIPKPN7testing8TestInfoESt6vectorIS3_SaIS3_EEEmIEi_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE16_M_insert_equal_ESt23_Rb_tree_const_iteratorIS1_ERKS1__ZNSt6vectorIiSaIiEE5beginEv_ZN9__gnu_cxx17__normal_iteratorIPKSsSt6vectorISsSaISsEEEmmEv_Valcurrent_test_info_operator<< GTEST_ERRORforwarding_enabledsiginfo_t_ZN7testing8internal29ParameterizedTestCaseInfoBaseaSERKS1_kColorEncodedHelpMessage_ZNSt6vectorIN7testing14TestPartResultESaIS1_EE5eraseEN9__gnu_cxx17__normal_iteratorIPS1_S3_EE_ZNSbIwSt11char_traitsIwESaIwEE6assignERKS2_jjstringstream_Key_ZNSt6vectorIN7testing12TestPropertyESaIS1_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS1_S3_EERKS1__ZNSbIwSt11char_traitsIwESaIwEE4_Rep7_M_grabERKS1_S5_~SingleFailureChecker_ZNK7testing8UnitTest22test_case_to_run_countEvpop_backrend_ZNKSbIwSt11char_traitsIwESaIwEE17find_first_not_ofEPKwjsuccessful_test_count_ZNKSs5rfindEPKcjjname_ZN9__gnu_cxx17__normal_iteratorIPKPN7testing17TestEventListenerESt6vectorIS3_SaIS3_EEEpLEioutput_format_ZN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE11ValueHolderaSERKS5_rebind~ScopedPrematureExitFileoperator<< _ZN7testing8internal2RE9FullMatchEPKcRKS1_MSG_RSTOnTestPartResult_ZN7testing4Test15HasFatalFailureEv__cxa_atexit_ZN7testing8internal17PrintWideStringToERKSbIwSt11char_traitsIwESaIwEEPSocur_addr_ZN7testing8internal12UnitTestImpl27parameterized_test_registryEv_ZNKSs5beginEv_ZNK7testing8internal13DeathTestImpl7outcomeEv__cxa_guard_acquirefind_first_ofn_cs_precedes__normal_iterator, std::allocator >*, std::vector, std::allocator >, std::allocator, std::allocator > > > >_ZNSt6vectorIN7testing14TestPartResultESaIS1_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS1_S3_EERKS1_output_ZN7testing8internal27PrettyUnitTestResultPrinterD2EvGetTestPartResult_ZNSbIwSt11char_traitsIwESaIwEE6insertEjRKS2_jjoutput_GetPrefixUntilComma_ZN7testing8internal24XmlUnitTestResultPrinter24IsNormalizableWhitespaceEcLock_ZNSt6vectorIN7testing14TestPartResultESaIS1_EE6rbeginEvCOLOR_GREENoperator<< _ZN7testing8internal16ForkingDeathTestC2EPKcPKNS0_2REEline_num_S_right_ZN9__gnu_cxx13new_allocatorISt13_Rb_tree_nodeISsEE8allocateEjPKvMakeFrom_S_empty_rep_ZSt29_Rb_tree_insert_and_rebalancebPSt18_Rb_tree_node_baseS0_RS__Znwj_ZN9__gnu_cxx17__normal_iteratorIPPN7testing11EnvironmentESt6vectorIS3_SaIS3_EEEpLEi__is_null_pointermethod_ZNSs6insertEN9__gnu_cxx17__normal_iteratorIPcSsEEjc_ZNK9__gnu_cxx13new_allocatorIPcE7addressERKS1__ZNKSs7compareEjjRKSsset_current_test_case_ZNSt12_Vector_baseIPN7testing17TestEventListenerESaIS2_EE13_M_deallocateEPS2_j_ZN7testing7MessagelsEPw__iterator_category__is_normal_iterator_ZN7testing8internal10scoped_ptrINS0_24InternalRunDeathTestFlagEE5resetEPS2_iterator_traitsallocatorUniversalPrintCharArray_ZN9__gnu_cxx13new_allocatorIPcE9constructEPS1_RKS1___alloc_traits >operator!= >__destroy__elems_beforevalue_compare_ZNSt11char_traitsIwE2eqERKwS2__ZNKSt6vectorIPN7testing8TestCaseESaIS2_EE8capacityEv9siginfo_t~TestEventRepeater_ZN7testing10TestResultaSERKS0__ZNKSt6vectorIN7testing12TestPropertyESaIS1_EE4dataEv_ZNK7testing8TestCase17test_to_run_countEvseekdirGetCurrentExecutableNametest_case_name__Destroy*, std::basic_string >operator- >_vptr.UnitTestImpl_ZN9__gnu_cxx17__normal_iteratorIPKcSsEpLEi_ZNKSt18basic_stringstreamIcSt11char_traitsIcESaIcEE3strEvexpression_textOnTestCaseEndbytes_readtm_hour_ZNSt6vectorISsSaISsEE8_M_eraseEN9__gnu_cxx17__normal_iteratorIPSsS1_EESignAndMagnitudeToBiasedoperator<< __trip_countreportable_test_count_M_insert_ZNSt3setISsSt4lessISsESaISsEE4findERKSs_ZNSbIwSt11char_traitsIwESaIwEE7replaceEN9__gnu_cxx17__normal_iteratorIPwS2_EES6_jw_ZNK7testing8internal29ParameterizedTestCaseInfoBase17GetTestCaseTypeIdEvCaptureStdout_ZNSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE6insertEN9__gnu_cxx17__normal_iteratorIPS3_S5_EERKS3__ZNSt6vectorIPN7testing11EnvironmentESaIS2_EE8_M_eraseEN9__gnu_cxx17__normal_iteratorIPS2_S4_EE_ZNSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS3_S5_EERKS3___addressof >_ZNKSt3setISsSt4lessISsESaISsEE4findERKSsunknown fileExecDeathTestArgs_ZNKSt6vectorIPN7testing8TestCaseESaIS2_EE8max_sizeEv__gthread_active_ptrkExponentBitCountstatus_ok_ZNK7testing8internal13FloatingPointIdE13exponent_bitsEv_ZNKSbIwSt11char_traitsIwESaIwEE13find_first_ofEPKwj_ZNKSt6vectorIPcSaIS0_EE5frontEv_S_out_ZN7testing8internal24XmlUnitTestResultPrinter18EscapeXmlAttributeERKSs_Destroystrrchr_ZN9__gnu_cxx13new_allocatorIPN7testing8TestInfoEE9constructEPS3_RKS3__ZN7testing8internal12UnitTestImpl11RunAllTestsEv_ZNSt6vectorIPN7testing8TestInfoESaIS2_EE4swapERS4__ZN7testing8internal9DeathTest4WaitEv_ZN9__gnu_cxx17__normal_iteratorIPSsSt6vectorISsSaISsEEEmmEi_HasBase_ZN7testing18TestEventListenersD2Ev_ZNSt6vectorIPN7testing8TestCaseESaIS2_EE9push_backERKS2__vptr.AbstractSocketWriter_ZN9__gnu_cxx17__normal_iteratorIPSsSt6vectorISsSaISsEEEmmEv_ZNK7testing8internal8FilePath5c_strEvdo_widen_ZNKSt6vectorIPN7testing8TestCaseESaIS2_EE4rendEv_ZN7testing8internal12UnitTestImpl31SetGlobalTestPartResultReporterEPNS_31TestPartResultReporterInterfaceE_ZNK7testing19TestPartResultArray4sizeEv_ZNK7testing8TestCase6PassedEvPopGTestTracesign_bitrebind_ZNSt12_Vector_baseIN7testing8internal9TraceInfoESaIS2_EE13_M_deallocateEPS2_jDeathTest_ZNKSt6vectorISsSaISsEE4rendEv_ZNK7testing15AssertionResult7messageEv_ZNK7testing8internal17TestEventRepeater18forwarding_enabledEva_value_paramoperator!__iterator_categoryfputcoperator&operator*operator+iterator_traitsoperator-_ZNSt12_Vector_baseIPN7testing11EnvironmentESaIS2_EE11_M_allocateEjfputs_ZStplIcSt11char_traitsIcESaIcEESbIT_T0_T1_ERKS6_S8_operator<operator=operator>FormatForComparison_ZNSs9_M_mutateEjjj_ZN7testing17TestEventListener24OnEnvironmentsSetUpStartERKNS_8UnitTestE_ZNKSt3setISsSt4lessISsESaISsEE5beginEv_ZN7testing8internal6Random6ReseedEj_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE17_M_insert_unique_ESt23_Rb_tree_const_iteratorIS1_ERKS1_rebindSOCK_RAW_ZNSt6vectorIPN7testing8TestCaseESaIS2_EE6insertEN9__gnu_cxx17__normal_iteratorIPS2_S4_EERKS2__ZN7testing8internal7PrintToEhPSo_ZNSs12_S_constructIPcEES0_T_S1_RKSaIcEis_selectedsystemwcsrtombsTestProperty_ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EEixEj__valFailFromInternalError_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE14_M_lower_boundEPSt13_Rb_tree_nodeIS1_ESA_RKS1__timer_ZN7testing10TestResult17AddTestPartResultERKNS_14TestPartResultEquot_ZNSt6vectorISsSaISsEE6rbeginEv_ZNKSt6vectorIPN7testing11EnvironmentESaIS2_EE6rbeginEvthrow_on_failure_operator|operator~atof_ZNSt9basic_iosIcSt11char_traitsIcEE5clearESt12_Ios_Iostate_ZN9__gnu_cxx17__normal_iteratorIPKPN7testing8TestCaseESt6vectorIS3_SaIS3_EEEmIEiatoiatol_ZNKSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE6rbeginEv_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE3endEvPrintToStringconstruct_ZN7testing4Test13SetUpTestCaseEv_ZN7testing8internal17TestEventRepeateraSERKS1__ZNSt3setISsSt4lessISsESaISsEE5eraseESt23_Rb_tree_const_iteratorISsEgoodbitwcstombswrite_Rb_tree_iterator_ZN7testing8internal26ThreadLocalValueHolderBaseaSERKS1__Znaj_ZN9__gnu_cxx17__normal_iteratorIPKSsSt6vectorISsSaISsEEEpLEi__k2_M_eraseCreateDirectoriesRecursively_ZNSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE5eraseEN9__gnu_cxx17__normal_iteratorIPS3_S5_EES9_exit_status_ZNSt6vectorIiSaIiEE5eraseEN9__gnu_cxx17__normal_iteratorIPiS1_EEfull_pattern_S_hexowner__sigpoll_ZNKSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE6_M_endEvint_p_sep_by_spacekMaxRangeGetStringFunctor_ZN7testing8internal12AssertHelper16AssertHelperDataaSERKS2__Rb_tree_const_iterator, std::allocator > >_ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EE15_M_erase_at_endEPS2_IsAbsolutePathfailed_test_case_count_ZNKSt6vectorIPN7testing8TestCaseESaIS2_EE5frontEv_ZNSs4_Rep10_M_disposeERKSaIcEfputwc_Iterator_Iter_base_M_clone_nodeParseStringFlagFilterMatchesTestfputwsMakeConnection~basic_stringCmpHelperSTRCASEEQiterator_traits<__gnu_cxx::__normal_iterator > > >index_ZNK7testing8TestInfo6resultEv_ZNKSs12find_last_ofERKSsj_ZN7testing8UnitTestC2Ev_ZNK9__gnu_cxx17__normal_iteratorIPPN7testing8TestInfoESt6vectorIS3_SaIS3_EEEptEv_ZNSt6vectorIiSaIiEEaSERKS1_fcntl_ZNK7testing8internal17TestPropertyKeyIsclERKNS_12TestPropertyE~DeathTestImpl_ZN7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEE11ValueHolderaSERKS7__ZN7testing8internal13FloatingPointIfE8InfinityEv_S_ios_openmode_end_ZN7testing8TestCaseD2EvGTestFlagSaverGetOutputFormat_ZN9__gnu_cxx13new_allocatorIcE10deallocateEPcj_ZN7testing8internal18SetInjectableArgvsEPKSt6vectorISsSaISsEErandom_ZN9__gnu_cxx14__alloc_traitsISaISsEE8max_sizeERKS1__ZNKSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE11upper_boundERKSs_ZNKSt6vectorIPN7testing17TestEventListenerESaIS2_EE2atEjstrtold_ZNK9__gnu_cxx17__normal_iteratorIPKN7testing8internal9TraceInfoESt6vectorIS3_SaIS3_EEEdeEvoperator<< suffix_len_ZNSt6vectorIPcSaIS0_EE5frontEvportset_up_tc__maskTestPassed_M_destroyMSG_MOREnew_holder_ZN9__gnu_cxx14__alloc_traitsISaIN7testing14TestPartResultEEE10_S_on_swapERS3_S5__ZNKSt6vectorIN7testing14TestPartResultESaIS1_EE2atEj_M_fill_assign_ZNSt3setIPKcSt4lessIS1_ESaIS1_EE4findERKS1_operator<< _ZN7testing8internal24ParseGoogleTestFlagsOnlyEPiPPwoperator<< _ZNKSs7_M_iendEv_ZN7testing8internal11ScopedTraceD2Evresume_pos_ZNK7testing8internal12UnitTestImpl18ad_hoc_test_resultEvtm_yday_ZNSt6vectorIPN7testing8TestInfoESaIS2_EE14_M_fill_assignEjRKS2__ZNSt8ios_base4setfESt13_Ios_FmtflagsS0_putwcharftell__miter_base<__gnu_cxx::__normal_iterator > >SOCK_STREAM_ZSt16__ostream_insertIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_PKS3_icomparestream_result_to__ZNSt6vectorIPN7testing11EnvironmentESaIS2_EE7reserveEj_ZN7testing8internal12AssertHelperaSERKS1_ExecDeathTestSpawnChild__blksize_t_ZNKSbIwSt11char_traitsIwESaIwEE12find_last_ofEPKwjj_M_upper_bound_ZNK9__gnu_cxx17__normal_iteratorIPPcSt6vectorIS1_SaIS1_EEEixEiPrintCharAndCodeTo_ZN7testing14TestPartResultD2EvAddEnvironment_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE10_S_maximumEPKSt18_Rb_tree_node_basepthread_mutex_unlock_ZNKSt6vectorIPcSaIS0_EE3endEvint_curr_symbolset_write_fd~GTestLog_ZN7testing8UnitTest14PushGTestTraceERKNS_8internal9TraceInfoEnum_runnable_tests_ZNK9__gnu_cxx17__normal_iteratorIPKN7testing8internal9TraceInfoESt6vectorIS3_SaIS3_EEEixEi_ZNSbIwSt11char_traitsIwESaIwEE6insertEjRKS2__ZNKSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE5beginEv_ZN7testing8internal12AssertHelperD2Ev_ZNK9__gnu_cxx13new_allocatorIcE7addressERKcpthread_key_create_TrivialValueTypesfind_if<__gnu_cxx::__normal_iterator >, testing::internal::TestCaseNameIs>translate_ZNSt6vectorIPN7testing8TestCaseESaIS2_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS2_S4_EERKS2_wcstoul__is_normal_iteratorsa_data_ZNSt6vectorIPN7testing8TestInfoESaIS2_EE6insertEN9__gnu_cxx17__normal_iteratorIPS2_S4_EERKS2_index___mode_t_ZN7testing8internal18InitGoogleTestImplIcEEvPiPPT___cxa_bad_typeid_DestroyFLAGS_gtest_repeat__n1pair, std::_Rb_tree_const_iterator >_ZNSs13_S_copy_charsEPcN9__gnu_cxx17__normal_iteratorIPKcSsEES4_read_fd_ZN9__gnu_cxx17__normal_iteratorIPSsSt6vectorISsSaISsEEEpLEi_Destroysrc/gtest-all.cc~basic_stringbufFormatFileLocation_ZNSt6vectorIPcSaIS0_EE8_M_eraseEN9__gnu_cxx17__normal_iteratorIPS0_S2_EE_M_insert_equalconst_reverse_iteratorwchar_t_ZN9__gnu_cxx14__alloc_traitsISaIPN7testing11EnvironmentEEE7destroyERS4_PS3__ZNKSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE6rbeginEv_ZNK7testing7Message9GetStringEv_markers__assignable__copy_move_backwardOnEnvironmentsSetUpStart_ZN9__gnu_cxx14__alloc_traitsISaIPN7testing8internal29ParameterizedTestCaseInfoBaseEEE17_S_select_on_copyERKS5___alloc_traits >_ZN7testing8internal10scoped_ptrINS0_24InternalRunDeathTestFlagEEaSERKS3_iostatea_write_fd__pad1__pad2__pad3__copy_move_a__pad5a_filefieldssi_overrun_ZNK7testing8internal8FilePath28CreateDirectoriesRecursivelyEvRecordProperty_ZNK7testing8internal13DeathTestImpl7read_fdEv_M_get_Tp_allocatorgetwchar__destroy*>_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE7_M_rootEv_ZN9__gnu_cxx17__normal_iteratorIPPN7testing8internal29ParameterizedTestCaseInfoBaseESt6vectorIS4_SaIS4_EEEmIEi_ZNKSt6vectorIPN7testing17TestEventListenerESaIS2_EE4dataEv_ZNKSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE4rendEv_ZNKSt17_Rb_tree_iteratorIPKcEneERKS2_current_test_case_ZNKSt6vectorIN7testing12TestPropertyESaIS1_EE2atEj_ZN9__gnu_cxx3divExxkSizestdout_is_ttycopy_backward_ZNK9__gnu_cxx17__normal_iteratorIPKPN7testing17TestEventListenerESt6vectorIS3_SaIS3_EEEplEi_ZNK9__gnu_cxx17__normal_iteratorIPKPN7testing11EnvironmentESt6vectorIS3_SaIS3_EEE4baseEv_ZN7testing8internal24XmlUnitTestResultPrinter17OutputXmlTestInfoEPSoPKcRKNS_8TestInfoE_ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EE9push_backERKS2__ZNSt6vectorIN7testing14TestPartResultESaIS1_EE14_M_fill_insertEN9__gnu_cxx17__normal_iteratorIPS1_S3_EEjRKS1__ZNK7testing8UnitTest18ad_hoc_test_resultEvtotal_test_case_count_ZNKSt16reverse_iteratorIN9__gnu_cxx17__normal_iteratorIPPN7testing11EnvironmentESt6vectorIS4_SaIS4_EEEEEplEioperator<< __copy_move_backward_aoperator<< _ZN9__gnu_cxx13new_allocatorIN7testing14TestPartResultEE10deallocateEPS2_jcur_pattern_ZN7testing4TestaSERKS0__ZNSt6vectorIPN7testing8TestInfoESaIS2_EE2atEj_ZN7testing15AssertionResult13AppendMessageERKNS_7MessageEIsSubstringImpl >__copy_move_a2_ZN7testing32ScopedFakeTestPartResultReporter20ReportTestPartResultERKNS_14TestPartResultEMSG_DONTWAITiterator_traits_ZNSt3setIPKcSt4lessIS1_ESaIS1_EE11lower_boundERKS1__ZNSt13_Rb_tree_nodeISsE9_M_valptrEvkElidedFramesMarkerset_read_fdParseInternalRunDeathTestFlagstatus__ZN7testing8internal19TypedTestCasePState25VerifyRegisteredTestNamesEPKciS3__ZNSt6vectorIPcSaIS0_EE14_M_fill_insertEN9__gnu_cxx17__normal_iteratorIPS0_S2_EEjRKS0__ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE12_M_erase_auxESt23_Rb_tree_const_iteratorISsES7_GetMutableTestCase*DeathTest:*DeathTest/*_ZNKSs16find_last_not_ofEPKcj__osRelease_ZNK9__gnu_cxx17__normal_iteratorIPKcSsEmiEi_IO_write_base__distance_ZNSt3setISsSt4lessISsESaISsEE11upper_boundERKSs_ZNK9__gnu_cxx17__normal_iteratorIPPN7testing8TestCaseESt6vectorIS3_SaIS3_EEEptEvUniversalPrinter, std::allocator > >GoogleTestFailureException_ZN7testing8TestCase14UnshuffleTestsEvreason_ZN7testing8internal23GetLastErrnoDescriptionEv__miter_base__builtin_memcmp_ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EE6rbeginEvfront_ZN7testing8internal7PrintToEPKwPSowmemsetsetfillkTestcase_ZNKSt6vectorIN7testing8internal9TraceInfoESaIS2_EEixEj__copy_move_backward_a2FormatCompilerIndependentFileLocationpush_backtotal_shards_envsubstr_ZNKSt6vectorIN7testing14TestPartResultESaIS1_EE6rbeginEv_ZN9__gnu_cxx14__alloc_traitsISaIPKcEE17_S_select_on_copyERKS3__ZNKSt6vectorIN7testing14TestPartResultESaIS1_EEixEjincrement_death_test_count_ZNKSt6vectorIiSaIiEE5beginEv_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE13_Rb_tree_implIS5_Lb0EE13_M_initializeEv_ZN9__gnu_cxx14__alloc_traitsISaISt13_Rb_tree_nodeISsEEE10deallocateERS3_PS2_jst_ino_ZNKSt6vectorIiSaIiEE3endEvxml_element_S_terminal_ZNK9__gnu_cxx13new_allocatorISt13_Rb_tree_nodeIPKcEE7addressERS4_OsStackTraceGetter_Compare_ZN7testing8internal17StreamingListener16OnTestProgramEndERKNS_8UnitTestEstrtouliterator_traits_ZNKSs4findEPKcjmbstate_t_ZN7testing17TestEventListener9OnTestEndERKNS_8TestInfoEPrintToString_ZN9__gnu_cxx14__alloc_traitsISaIPN7testing11EnvironmentEEE8allocateERS4_jlast_death_test_message_~_Rb_treeStrCaseCmp_ZN7testing8internal35DefaultGlobalTestPartResultReporterC2EPNS0_12UnitTestImplETHREWPrintTestNameis_valid__ZN7testing8internal35DefaultGlobalTestPartResultReporterD0EvMSG_TRUNC_ZN7testing8internal13DeathTestImpl5AbortENS0_9DeathTest11AbortReasonEDefaultPrintTodelimiterIsDigit_ZNSt11char_traitsIcE7not_eofERKi__it__destroy_ZN7testing8internal15FloatingPointLEIdEENS_15AssertionResultEPKcS4_T_S5__ZNKSs12find_last_ofEPKcjj__u_quad_t_ZN9__gnu_cxx17__normal_iteratorIPPN7testing8TestInfoESt6vectorIS3_SaIS3_EEEppEiputwcTestPartResult__normal_iterator > >shuffle__ZN9__gnu_cxx17__normal_iteratorIPPN7testing8TestInfoESt6vectorIS3_SaIS3_EEEppEv_Vector_base >_M_is_leaked_ZN7testing8internal17StreamingListeneraSERKS1__ZNSt6vectorIPN7testing11EnvironmentESaIS2_EE6assignEjRKS2__ZNSbIwSt11char_traitsIwESaIwEE7replaceEjjPKwj_ZN7testing8internal20ShouldRunTestOnShardEiii_ZNK7testing8internal10scoped_ptrISsEptEvPrint_ZNKSbIwSt11char_traitsIwESaIwEE5rfindEPKwj_ZN9__gnu_cxx17__normal_iteratorIPPN7testing8TestCaseESt6vectorIS3_SaIS3_EEEppEioperator-*, std::vector > >__uninit_copyoperator<< reserved_names_SelfStart_ZNK9__gnu_cxx13new_allocatorISsE7addressERKSsThis program contains tests written using Google Test. You can use the following command line flags to control its behavior: Test Selection: @G--gtest_list_tests@D List the names of all tests instead of running them. The name of TEST(Foo, Bar) is "Foo.Bar". @G--gtest_filter=@YPOSTIVE_PATTERNS[@G-@YNEGATIVE_PATTERNS]@D Run only the tests whose name matches one of the positive patterns but none of the negative patterns. '?' matches any single character; '*' matches any substring; ':' separates two patterns. @G--gtest_also_run_disabled_tests@D Run all disabled tests too. Test Execution: @G--gtest_repeat=@Y[COUNT]@D Run the tests repeatedly; use a negative count to repeat forever. @G--gtest_shuffle@D Randomize tests' orders on every iteration. @G--gtest_random_seed=@Y[NUMBER]@D Random number seed to use for shuffling test orders (between 1 and 99999, or 0 to use a seed based on the current time). Test Output: @G--gtest_color=@Y(@Gyes@Y|@Gno@Y|@Gauto@Y)@D Enable/disable colored output. The default is @Gauto@D. -@G-gtest_print_time=0@D Don't print the elapsed time of each test. @G--gtest_output=xml@Y[@G:@YDIRECTORY_PATH@G/@Y|@G:@YFILE_PATH]@D Generate an XML report in the given directory or with the given file name. @YFILE_PATH@D defaults to @Gtest_details.xml@D. @G--gtest_stream_result_to=@YHOST@G:@YPORT@D Stream test results to the given server. Assertion Behavior: @G--gtest_death_test_style=@Y(@Gfast@Y|@Gthreadsafe@Y)@D Set the default death test style. @G--gtest_break_on_failure@D Turn assertion failures into debugger break-points. @G--gtest_throw_on_failure@D Turn assertion failures into C++ exceptions. @G--gtest_catch_exceptions=0@D Do not report exceptions as test failures. Instead, allow them to crash the program or throw a pop-up (on Windows). Except for @G--gtest_list_tests@D, you can alternatively set the corresponding environment variable of a flag (all letters in upper-case). For example, to disable colored text output, you can either specify @G--gtest_color=no@D or set the @GGTEST_COLOR@D environment variable to @Gno@D. For more information, please read the Google Test documentation at @Ghttp://code.google.com/p/googletest/@D. If you find a bug in Google Test (not one in your own code or tests), please report it to @G@D. BoolFromGTestEnv_ZNSt6vectorIPcSaIS0_EE15_M_erase_at_endEPS0__ZNKSbIwSt11char_traitsIwESaIwEE17find_first_not_ofEwjInteger__find_if<__gnu_cxx::__normal_iterator >, __gnu_cxx::__ops::_Iter_pred >strcasecmpst_ctim_ZNSt6vectorIN7testing12TestPropertyESaIS1_EE6assignEjRKS1__ZNSt6vectorIPN7testing8TestCaseESaIS2_EE4dataEvtuple_size >_ZNKSt6vectorIPcSaIS0_EE4backEv_Vector_base >_ZNKSt6vectorIN7testing14TestPartResultESaIS1_EE8capacityEv_M_leak_hardprefix_len_ZNKSs13find_first_ofERKSsj_ZN7testing8internal15FloatingPointLEIfEENS_15AssertionResultEPKcS4_T_S5__ZN7testing4Test5SetupEvGTestLogSeverity_ZN9__gnu_cxx14__alloc_traitsISaIN7testing12TestPropertyEEE17_S_select_on_copyERKS3__ZNSt6vectorIN7testing12TestPropertyESaIS1_EE14_M_fill_insertEN9__gnu_cxx17__normal_iteratorIPS1_S3_EEjRKS1__ZSt9__find_ifIN9__gnu_cxx17__normal_iteratorIPPN7testing8TestCaseESt6vectorIS4_SaIS4_EEEENS0_5__ops10_Iter_predINS2_8internal14TestCaseNameIsEEEET_SF_SF_T0_St26random_access_iterator_tag_vptr.TestCase_ZNK7testing8UnitTest21total_test_case_countEv_ZNKSt9_IdentityIPKcEclERKS1__ZNSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE8_M_eraseEN9__gnu_cxx17__normal_iteratorIPS3_S5_EES9__ZNSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE7reserveEj_ZN9__gnu_cxx17__normal_iteratorIPPN7testing17TestEventListenerESt6vectorIS3_SaIS3_EEEppEv_ZN9__gnu_cxx17__normal_iteratorIPcSsEppEitoupper_vptr.ThreadLocalValueHolderBase_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE12_M_rightmostEv Stack trace: _ZN9__gnu_cxx17__normal_iteratorIPcSsEppEv__normal_iterator, std::allocator > >_ZNK9__gnu_cxx17__normal_iteratorIPiSt6vectorIiSaIiEEEixEi__datCodePointToUtf8_ZNSbIwSt11char_traitsIwESaIwEE4_Rep26_M_set_length_and_sharableEj_ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EE14_M_fill_assignEjRKS2_test_namenot_bol_ZNSs3endEv_ZN9__gnu_cxx17__normal_iteratorIPKPN7testing17TestEventListenerESt6vectorIS3_SaIS3_EEEmIEi_ZNKSt6vectorIN7testing14TestPartResultESaIS1_EE8max_sizeEv_ZN7testing8internal12UnitTestImplD0EvIsRootDirectorymemcpyFloatingPointLE_ZN7testing8internal6RandomaSERKS1__ZN7testing8internal21ImplicitlyConvertibleIPKvS3_E6HelperEz_ZNKSt6vectorIN7testing12TestPropertyESaIS1_EE14_M_range_checkEj_ZNSbIwSt11char_traitsIwESaIwEE4_Rep15_M_set_sharableEvFlushInfoLog_ZN7testing15AssertionResultlsIA12_cEERS0_RKT___s1construct_ZNSt3setISsSt4lessISsESaISsEE6insertESt23_Rb_tree_const_iteratorISsERKSsreverse_iterator<__gnu_cxx::__normal_iterator > > >_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE5eraseERKSsHasFailurewcsncpy_ZNKSt6vectorIN7testing12TestPropertyESaIS1_EE3endEv_ZN7testing8internal28ParseGoogleTestFlagsOnlyImplIcEEvPiPPT_back_ZNK7testing10TestResult6PassedEvcopy_ZN7testing8internal12UnitTestImpl21os_stack_trace_getterEv_S_construct_aux15pthread_mutex_tregex_tmbrtowcresultRandom~ParameterizedTestCaseInfoBase_ZNSt3setISsSt4lessISsESaISsEE5eraseERKSs_ZNK9__gnu_cxx13new_allocatorIPN7testing17TestEventListenerEE7addressERKS3__ZN7testing8internal12UnitTestImpl14RecordPropertyERKNS_12TestPropertyE__numeric_traits_integerfreeaddrinfo_M_limitoperator<< _ZNSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE4rendEv_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE5eraseESt17_Rb_tree_iteratorIS1_ES9__ZNK7testing8internal8FilePath12CreateFolderEv_ZNK7testing8internal10scoped_ptrINS0_16DeathTestFactoryEE3getEv_ZNSt6vectorISsSaISsEE3endEvkPathSeparator_ZN7testing12TestPropertyD2Evvfprintfiterator_traits, std::allocator >*>~Mutexisxdigitmatched_ZNSbIwSt11char_traitsIwESaIwEE4_Rep10_M_disposeERKS1__ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE10_S_maximumEPSt18_Rb_tree_node_basesi_fd_ZNSt6vectorISsSaISsEE4backEv_next_S_basefieldStringType__is_move_iterator_ZNSt6vectorIPN7testing8TestInfoESaIS2_EE3endEv__niter_base_ZNSt6vectorIPN7testing8TestCaseESaIS2_EE8_M_eraseEN9__gnu_cxx17__normal_iteratorIPS2_S4_EES8___uninitialized_copy_a_S_scientificerase_ZNK7testing8internal8FilePath15IsRootDirectoryEv_ZNKSt6vectorIN7testing14TestPartResultESaIS1_EE4rendEv_ZN7testing17TestEventListener11OnTestStartERKNS_8TestInfoEallocator, std::allocator > > >_ZNK7testing10TestResult15GetTestPropertyEi_ZN7testing32ScopedFakeTestPartResultReporterD0Ev_ZNSt6vectorIPN7testing8TestCaseESaIS2_EE6resizeEjS2_is_wide_stringstack_trace_depth_ZNK7testing8internal10scoped_ptrINS0_24InternalRunDeathTestFlagEEdeEvchar_type_ZN7testing4TestD0Evwctype_t_ZNKSs5rfindEPKcj_ZNSt6vectorISsSaISsEE14_M_fill_insertEN9__gnu_cxx17__normal_iteratorIPSsS1_EEjRKSs_ZNSt6vectorIiSaIiEE6insertEN9__gnu_cxx17__normal_iteratorIPiS1_EEjRKi_DestroyReinterpretBitsai_canonnameConfigureStreamingOutputalso_run_disabled_tests_ZN9__gnu_cxx17__normal_iteratorIPPN7testing8TestCaseESt6vectorIS3_SaIS3_EEEppEv_ZN7testing15AssertionResultlsISsEERS0_RKT__ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE12_M_erase_auxESt23_Rb_tree_const_iteratorISsESkipPrefix_ZN9__gnu_cxx17__normal_iteratorIPPcSt6vectorIS1_SaIS1_EEEppEi_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE14_M_upper_boundEPSt13_Rb_tree_nodeIS1_ESA_RKS1__ZNK9__gnu_cxx17__normal_iteratorIPPN7testing8internal29ParameterizedTestCaseInfoBaseESt6vectorIS4_SaIS4_EEEptEv_ZNSt12_Vector_baseIN7testing12TestPropertyESaIS1_EE11_M_allocateEjsaved_sigprof_actionoperator<< low_bits_IteratorR_ZNKSbIwSt11char_traitsIwESaIwEE8_M_limitEjj_ZNKSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE11__rb_verifyEv_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE5eraseESt17_Rb_tree_iteratorISsES7_successspawned__ZNSt13_Bit_iteratorppEi__sigchld_clock_ttear_down_tc__Vector_base >_ZNKSt5ctypeIcE13_M_widen_initEv__destroy_ZN7testing8internal12UnitTestImpl19PostFlagParsingInitEvmatchFLAGS_gtest_stack_trace_depth_ZNSt13_Bit_iteratorppEv_ZN7testing17TestEventListener20OnTestIterationStartERKNS_8UnitTestEikDeathTestStyleFlag_ZN7testing8internal18FormatFileLocationEPKci_ZN7testing15AssertionResultlsIA2_cEERS0_RKT__ZNKSt6vectorIPcSaIS0_EE4sizeEvcatch_exceptionsg_injected_test_argvs_ZNKSs4findEcj_M_get_insert_equal_pos_ZNSbIwSt11char_traitsIwESaIwEE12_S_empty_repEv_ZN7testing28FLAGS_gtest_stream_result_toEreverse_iterator<__gnu_cxx::__normal_iterator > > >_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE28_M_get_insert_hint_equal_posESt23_Rb_tree_const_iteratorIS1_ERKS1_PostFlagParsingInit_ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EE7reserveEj_ZNK7testing8internal12UnitTestImpl28internal_run_death_test_flagEv_ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EE8pop_backEv_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE5beginEv__positionqsortSocketWriter_ZNK9__gnu_cxx17__normal_iteratorIPN7testing14TestPartResultESt6vectorIS2_SaIS2_EEEplEi_ZNSbIwSt11char_traitsIwESaIwEE6insertEN9__gnu_cxx17__normal_iteratorIPwS2_EEw_ZNKSs4findERKSsj_ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EE5beginEvkAsIs_ZNK7testing8internal12UnitTestImpl6PassedEv_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE5eraseESt23_Rb_tree_const_iteratorIS1_ES9__ZNSt18_Rb_tree_node_base10_S_maximumEPS__ZNK7testing8UnitTest22failed_test_case_countEv_M_end_of_storage_ZN7testing8internal27PrettyUnitTestResultPrinter22OnEnvironmentsSetUpEndERKNS_8UnitTestE_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE17_M_insert_unique_ESt23_Rb_tree_const_iteratorISsERKSs__exchange_and_add_singleTearDownTestCase__x_copy_ZN9__gnu_cxx14__alloc_traitsISaIN7testing8internal9TraceInfoEEE7destroyERS4_PS3__ZN9__gnu_cxx14__alloc_traitsISaIN7testing12TestPropertyEEE8allocateERS3_j_Alloc_pad__uninitialized_copy_a*, std::basic_string >_ZN7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEE9CreateKeyEvgettervwscanfexponent_bitsputcharselected_Setwoperator<< _ZNK7testing8TestCase21reportable_test_countEvdeath_test_count__ZNKSt6vectorIN7testing14TestPartResultESaIS1_EE5frontEv_ZNKSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE4rendEv_M_headerinternal_run_death_test_SplitStringfind_last_of~TestEventListener__is_normal_iterator<__gnu_cxx::__normal_iterator > > >WideStringToUtf8_ZNKSt6vectorIPN7testing11EnvironmentESaIS2_EE5emptyEvuninitialized_copy<__gnu_cxx::__normal_iterator*, std::vector > >, std::basic_string*>__oldoperator- >_ZNSt6vectorIPN7testing8TestCaseESaIS2_EE5frontEvneedle_expr_ZN7testing8internal12UnitTestImpl18ConfigureXmlOutputEvunit_test__uninitialized_move_if_noexcept_a >reverse_iterator<__gnu_cxx::__normal_iterator > > >~set_ZN7testing22EmptyTestEventListener24OnEnvironmentsSetUpStartERKNS_8UnitTestE_Rb_tree_const_iteratorfabs_ZN7testing8internal14CapturedStream14ReadEntireFileEP8_IO_FILE_ZNSt3setISsSt4lessISsESaISsEE4swapERS3___vtt_parm_Destroy_M_ibeginactual_expression_ZNSt6vectorIPN7testing11EnvironmentESaIS2_EE5clearEv_ZNSt6vectorISsSaISsEE6assignEjRKSsGetRandomSeedFromFlag_ZNK9__gnu_cxx13new_allocatorIPN7testing8TestCaseEE7addressERS3__ZN7testing8internal17AppendUserMessageERKSsRKNS_7MessageEoperator!=*, std::vector > >__enable_if__throw_out_of_range_fmt_ZNKSt6vectorIPN7testing17TestEventListenerESaIS2_EE4sizeEvGetTestPartResultReporterForCurrentThread__copy_move_backward_a_ZN9__gnu_cxx17__normal_iteratorIPKSsSt6vectorISsSaISsEEEmIEiInternalRunDeathTestFlag_ZNKSbIwSt11char_traitsIwESaIwEE13find_first_ofERKS2_j_ZNK7testing8UnitTest21reportable_test_countEvF_OWNER_PGRP_ZNSt6vectorISsSaISsEE5eraseEN9__gnu_cxx17__normal_iteratorIPSsS1_EES5__ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS2_S4_EERKS2__ZN7testing14IsNotSubstringEPKcS1_S1_S1___off64_t_Iter_base<__gnu_cxx::__normal_iterator > >, false>__copy_move_a_ZNKSt6vectorIPN7testing8TestCaseESaIS2_EE12_M_check_lenEjPKc__gnu_cxx__typeEqFailureexpected_to_be_substringGetCapturedStringExitedUnsuccessfully_ZNK7testing8UnitTest20original_working_dirEvDeleteThreadLocalValue_ZN7testing8internal24HasNewFatalFailureHelperC2Evoperator+, std::allocator >_ZN7testing8internal38DefaultPerThreadTestPartResultReporterC2EPNS0_12UnitTestImplEoperator==_vptr.TestFactoryBase_M_current_ZNSs7replaceEjjjc_ZNSt6vectorIN7testing14TestPartResultESaIS1_EE5clearEv_Destroy_ZNKSs13find_first_ofEPKcjj_ZNSt6vectorIPN7testing8TestInfoESaIS2_EE8_M_eraseEN9__gnu_cxx17__normal_iteratorIPS2_S4_EES8__ZNK7testing8internal13FloatingPointIdE12AlmostEqualsERKS2__Iter_pred__copy_move_aoperator<< _ZNSt6vectorIiSaIiEE4rendEvtest_case_infos__ZNK9__gnu_cxx17__normal_iteratorIPN7testing14TestPartResultESt6vectorIS2_SaIS2_EEE4baseEv_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE11_M_put_nodeEPSt13_Rb_tree_nodeIS1_Earray___copy_move_backward_a2_sigsys_ZN9__gnu_cxx13new_allocatorIiE8allocateEjPKvreverse_iterator<__gnu_cxx::__normal_iterator > > >_S_create_Arg1_Arg2_ZNSt6vectorIPcSaIS0_EE6rbeginEv_ZNK7testing8internal13FloatingPointIfE12AlmostEqualsERKS2__Vector_base, std::allocator >, std::allocator, std::allocator > > >_ZNKSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE4rendEvattributesstack_trace_depth_MSG_FASTOPEN_Destroy_aux_ZN7testing8internal17StreamingListener10FormatBoolEbdefault__ZN7testing14KilledBySignalC2EiFullMatchreverse_iterator<__gnu_cxx::__normal_iterator > > >g_captured_stderrSetGlobalTestPartResultReporterpair, std::allocator > >, bool>PrintAsCharLiteralToabs_errorRegisterParameterizedTests_ZNKSt6vectorIPcSaIS0_EEixEjGetTestTypeId/home/user/projects/ascgit/ascgit003.dlt-daemon/build/gtest-1.7.0__copy_move_a2 >, __gnu_cxx::__normal_iterator > >test_indexValidateTestPropertyargs__M_insert_uniqueoperator<< UInt32RemoveExtensionkStreamResultToFlagkCurrentDirectoryStringname_template_ZNSt6vectorIiSaIiEE2atEjflag_ZN7testing8internal17StreamingListener18OnTestIterationEndERKNS_8UnitTestEiiterator_traits_ZNK9__gnu_cxx17__normal_iteratorIPiSt6vectorIiSaIiEEEdeEv_ZN7testing8internal13HasOneFailureEPKcS2_S2_RKNS_19TestPartResultArrayENS_14TestPartResult4TypeERKSs_ZNKSt6vectorISsSaISsEE12_M_check_lenEjPKcbool_constantkShuffleFlag_ZNKSt18_Bit_iterator_baseltERKS___uninit_copyCharType_ZNK7testing8TestCase30reportable_disabled_test_countEv_ZN9__gnu_cxx14__alloc_traitsISaISsEE7destroyERS1_PSsungetwcoperator- >__copy_move_achild_argcurrency_symbol_ZNK9__gnu_cxx17__normal_iteratorIPN7testing14TestPartResultESt6vectorIS2_SaIS2_EEEptEvgettimeofday_ZNKSt3setIPKcSt4lessIS1_ESaIS1_EE4findERKS1_locationShowWideCString__wchb_ZNSt12_Vector_baseIPN7testing17TestEventListenerESaIS2_EE11_M_allocateEj_ZNSbIwSt11char_traitsIwESaIwEE9_M_assignEPwjwoperator!= >_ZN7testing35FLAGS_gtest_also_run_disabled_testsEIsSubstringPred >_ZNKSt6vectorIiSaIiEE4dataEv_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE7_M_copyEPKSt13_Rb_tree_nodeISsEPS7__S_value~TestPropertyKeyIs_ZN9__gnu_cxx13new_allocatorISt13_Rb_tree_nodeISsEE9constructEPS2_RKS2___exchange_and_addbasic_string__normal_iterator, std::allocator >*, std::vector, std::allocator >, std::allocator, std::allocator > > > >_ZNSt6vectorIPcSaIS0_EE5beginEv_ZN9__gnu_cxx17__normal_iteratorIPSsSt6vectorISsSaISsEEEmIEinew_allocator_ZNK9__gnu_cxx13new_allocatorIiE7addressERi_Iter_base_M_range_initializefirst_is_TEST_ZN9__gnu_cxx17__normal_iteratorIPPN7testing11EnvironmentESt6vectorIS3_SaIS3_EEEppEi_M_checkglobal_test_part_result_reporter_mutex_AddTestInfo_ZNSt3setISsSt4lessISsESaISsEE5eraseESt23_Rb_tree_const_iteratorISsES5___size_ZNSt6vectorIPcSaIS0_EE5eraseEN9__gnu_cxx17__normal_iteratorIPS0_S2_EE_ZNSt10_Iter_baseIPN7testing14TestPartResultELb0EE7_S_baseES2__ZNK7testing10TestResult18HasNonfatalFailureEv_ZN9__gnu_cxx17__normal_iteratorIPKPN7testing8TestInfoESt6vectorIS3_SaIS3_EEEmmEi_ZNK9__gnu_cxx17__normal_iteratorIPPN7testing8TestInfoESt6vectorIS3_SaIS3_EEE4baseEv_ZNKSt18_Bit_iterator_basegeERKS__ZNKSs5emptyEv__builtin_unwind_resume_ZN7testing31FLAGS_gtest_death_test_use_forkEunary_function_ZNSt6vectorIPN7testing11EnvironmentESaIS2_EE6rbeginEvResult_ZNKSt6vectorIN7testing8internal9TraceInfoESaIS2_EE4backEv_ZNK7testing8TestCase10type_paramEva_current_test_infoAssumeRole_ZNSbIwSt11char_traitsIwESaIwEE13_S_copy_charsEPwN9__gnu_cxx17__normal_iteratorIPKwS2_EES8__ZNSt6vectorIN7testing12TestPropertyESaIS1_EE3endEv_ZNKSt3setIPKcSt4lessIS1_ESaIS1_EE11equal_rangeERKS1__ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE5eraseEPKSsS7___ostream_type__insert_left_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE7_S_leftEPSt18_Rb_tree_node_base_ZNKSt6vectorISsSaISsEE4dataEv_ZNSt6vectorIPN7testing8TestCaseESaIS2_EE3endEv_M_check_length_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE21_M_insert_equal_lowerERKS1__ZNKSt23_Rb_tree_const_iteratorISsEptEvdeath_test_use_fork__S_app_ZNSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE18_M_fill_initializeEjRKS3__ZNKSs4findEPKcjj_ZN7testing22EmptyTestEventListenerD2Ev_ZN9__gnu_cxx14__alloc_traitsISaIN7testing14TestPartResultEEE8allocateERS3_jMSG_OOB_ZN7testing8internal12UnitTestImpl9listenersEv__syscall_slong_t__alloc_traits, std::allocator > > >__alloc_traits >_ZN7testing8internal15UnitTestOptions17FilterMatchesTestERKSsS3__Identityp_sep_by_space_ZNKSt6vectorIN7testing12TestPropertyESaIS1_EE8capacityEvstart_timestampappendIsDirectoryTestDisabled_ZNKSt6vectorIPN7testing17TestEventListenerESaIS2_EE6rbeginEv_ZNK7testing8internal12AssertHelperaSERKNS_7MessageEsetlocale_ZNK7testing8UnitTest17failed_test_countEvbase_ZN7testing8internal17StreamingListenerD0Ev_ZNSt6vectorIPN7testing8TestInfoESaIS2_EE6assignEjRKS2_host_ZNKSt16reverse_iteratorIN9__gnu_cxx17__normal_iteratorIPPN7testing11EnvironmentESt6vectorIS4_SaIS4_EEEEEmiEi_Setprecisionfailed_ZN7testing8internal38DefaultPerThreadTestPartResultReporterD2Ev__copy_move_bbasic_streambufDefaultGlobalTestPartResultReporter_ZNKSt3setISsSt4lessISsESaISsEE6rbeginEv_IO_write_ptr_ZNSs6insertEN9__gnu_cxx17__normal_iteratorIPcSsEEcGTEST_WARNING_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE8_S_rightEPSt18_Rb_tree_node_base_ZN7testing8internal2RE12PartialMatchEPKcRKS1__S_in_ZN7testing17TestEventListener18OnTestIterationEndERKNS_8UnitTestEicopynew_allocator_mode_ZNKSt6vectorIN7testing12TestPropertyESaIS1_EE8max_sizeEvwcscasecmpGTestLog_ZN7testing12TestProperty8SetValueERKSs__socket_type_ZNSt9basic_iosIcSt11char_traitsIcEE4initEPSt15basic_streambufIcS1_E_ZN7testing8internal13FloatingPointIdE3MaxEvminpair, bool>SumOverTestCaseList_Vector_base >_ZNSt12_Vector_baseIPcSaIS0_EE12_Vector_impl12_M_swap_dataERS3__ZNK9__gnu_cxx17__normal_iteratorIPKcSsEptEv__ops_ZNK9__gnu_cxx13new_allocatorIPN7testing8TestCaseEE8max_sizeEvpair_ZN7testing8internal17StreamingListener9OnTestEndERKNS_8TestInfoE_ZN7testing8internal19FormatForComparisonIxxE6FormatERKx_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE11equal_rangeERKS1__ZN9__gnu_cxx14__alloc_traitsISaIN7testing8internal9TraceInfoEEE10deallocateERS4_PS3_j_Tp_alloc_typetest_detail.xml_Constructfull_regex_len_ZNSt6vectorIPN7testing8TestInfoESaIS2_EE5clearEv_ZNKSt3setISsSt4lessISsESaISsEE11lower_boundERKSsSOCK_RDM_ZNSt12_Vector_baseIiSaIiEE11_M_allocateEjCloneCString_ZNKSt3setIPKcSt4lessIS1_ESaIS1_EE4rendEv_ZNKSt6vectorIPcSaIS0_EE5beginEv_ZNKSt9basic_iosIcSt11char_traitsIcEE5widenEcoperator!=, std::allocator >_ZNK9__gnu_cxx17__normal_iteratorIPKPN7testing8TestCaseESt6vectorIS3_SaIS3_EEEplEiWrite_M_fill_initializekDefaultDeathTestStyle__normal_iterator > >waitpidtimezonetest_property_count_ZNK7testing10TestResult19test_property_countEv_ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EEaSERKS4__Vector_base >reverse_iterator<__gnu_cxx::__normal_iterator > > >an_outcome_S_ate_ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EE14_M_fill_assignEjRKS2_regexecmatches_filter__ZNKSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE11equal_rangeERKS1_expected_posoutcome__ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EEaSERKS7__ZNKSt6vectorISsSaISsEE3endEv_ZNKSs7compareEjjRKSsjj_ZN9__gnu_cxx13new_allocatorIiE9constructEPiRKi_ZNSt18_Bit_iterator_base12_M_bump_downEv_ZNSbIwSt11char_traitsIwESaIwEE14_M_replace_auxEjjjw_ZNKSt3setISsSt4lessISsESaISsEE5emptyEv_ZNSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE6assignEjRKS3__ZN7testing8internal23ScopedPrematureExitFileaSERKS1__Destroy_ZN7testing8internal6String13CStringEqualsEPKcS3__Rb_tree_iterator, std::allocator > >_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE21_M_get_Node_allocatorEvlast_in_range_ZN9__gnu_cxx17__normal_iteratorIPPN7testing8TestInfoESt6vectorIS3_SaIS3_EEEmmEi_ZNKSt6vectorIN7testing8internal9TraceInfoESaIS2_EE4sizeEv_ZNSt6vectorIPcSaIS0_EE2atEj__find_if<__gnu_cxx::__normal_iterator*, std::vector > >, __gnu_cxx::__ops::_Iter_equals_val > >_ZNSsaSEcUniversalPrinter, std::allocator > >_ZN9__gnu_cxx17__normal_iteratorIPPN7testing8TestInfoESt6vectorIS3_SaIS3_EEEmmEv_ZNSs7replaceEN9__gnu_cxx17__normal_iteratorIPcSsEES2_jc_ZN7testing8internal12UnitTestImpl12environmentsEv_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE4findERKS1_kSignBitMaska_value__uninit_copy*>countlong long unsigned int_ZN7testing8TestInfo15ClearTestResultEPS0__ZNSs6appendERKSs_ZN7testing8internal6String12FormatHexIntEiconstruct_vptr.TestEventListenerCaseInsensitiveCStringEquals_ZNK9__gnu_cxx13new_allocatorIPN7testing8TestCaseEE7addressERKS3_pair, std::allocator > >, bool>kDeathTestUseForkuppercase_ZNSbIwSt11char_traitsIwESaIwEEpLEwparameterized_test_registry__ZNKSbIwSt11char_traitsIwESaIwEE4rendEvconstructFormatTestCaseCount_ZNKSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE5frontEvFLAGS_gtest_stream_result_to_ZNKSt6vectorIPN7testing17TestEventListenerESaIS2_EE8capacityEv_ZN9__gnu_cxx13new_allocatorIN7testing14TestPartResultEE9constructEPS2_RKS2_MakeAndRegisterTestInfounsigned char_ZNK7testing8internal24InternalRunDeathTestFlag5indexEv_M_grab_ZNKSt23_Rb_tree_const_iteratorIPKcEdeEv_ZN7testing14IsNotSubstringEPKcS1_PKwS3_stack_traceoperator<< ClearResultregmatch_tFLAGS_gtest_death_test_style_ZNKSt6vectorIPN7testing8TestCaseESaIS2_EEixEj_ZN9__gnu_cxx17__normal_iteratorIPPN7testing17TestEventListenerESt6vectorIS3_SaIS3_EEEmmEi_ZN7testing8internal13ParseBoolFlagEPKcS2_Pb_ZN7testing8internal14ParseFlagValueEPKcS2_bUnitTestOptions_ZN9__gnu_cxx17__normal_iteratorIPPN7testing17TestEventListenerESt6vectorIS3_SaIS3_EEEmmEv_ZN9__gnu_cxx17__normal_iteratorIPcSsEmmEi__gnu_debug_ZN9__gnu_cxx17__normal_iteratorIPcSsEmmEvSOCK_DGRAM_ZNSt6vectorIN7testing14TestPartResultESaIS1_EE7reserveEj__is_char__outTypeIdHelper_ZNK7testing14TestPartResult9file_nameEv_ZN7testing8internal6String12CloneCStringEPKc_ZNKSt6vectorIPN7testing17TestEventListenerESaIS2_EE8max_sizeEv_ZNKSt6vectorIPN7testing11EnvironmentESaIS2_EE4backEv_ZN9__gnu_cxx13new_allocatorIPN7testing8TestCaseEE9constructEPS3_RKS3_test_info_list_fwide_ZN7testing8internal17StreamingListener5StartEv__iterator_category<__gnu_cxx::__normal_iterator > >_ZN7testing22EmptyTestEventListener18OnTestProgramStartERKNS_8UnitTestE_ZNKSt6vectorIPN7testing8TestCaseESaIS2_EE5beginEvoutput_file_for_each<__gnu_cxx::__normal_iterator >, void (*)(testing::TestEventListener*)>F_OWNER_GID_ZNKSt6vectorIiSaIiEEixEj_ZNK7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEE7pointerEv_ZN7testing8internal27OsStackTraceGetterInterface16UponLeavingGTestEv_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE5clearEv_ZNSs6insertEjPKcj_ZN7testing8internal27PrettyUnitTestResultPrinter9OnTestEndERKNS_8TestInfoE_ZNK7testing8UnitTest15start_timestampEv_ZNKSt12_Vector_baseIN7testing8internal9TraceInfoESaIS2_EE19_M_get_Tp_allocatorEvkChunkSize_ZNSt6vectorIPcSaIS0_EE3endEv~GoogleTestFailureExceptionHandleSehExceptionsInMethodIfSupportedSetDefaultResultPrinterwcsspn~_Iter_pred_ZNSt6vectorISsSaISsEE6resizeEjSsoperator<< _ZNKSt6vectorIPN7testing17TestEventListenerESaIS2_EE5frontEvGetAnsiColorCode__copy_move_backward_a2__alloc_traits, std::allocator > > > >_ZNSt6vectorIPN7testing11EnvironmentESaIS2_EE18_M_fill_initializeEjRKS2__Rb_tree_ZNSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE5clearEv_ZN7testing8internal6String17WideCStringEqualsEPKwS3_streamraw_seed_ZNK7testing8internal12UnitTestImpl15start_timestampEvmax_length_ZNK7testing14TestPartResult6passedEv_ZNK9__gnu_cxx13new_allocatorIN7testing8internal9TraceInfoEE8max_sizeEvFOpen_sifields_ZN7testing17TestEventListener27OnEnvironmentsTearDownStartERKNS_8UnitTestEInfinitycan_be_nullwctyperesults_GetTestProperty__copy_move_backward_a_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE13_M_clone_nodeEPKSt13_Rb_tree_nodeIS1_E_ZNKSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE4dataEv_Destroy_ZN9__gnu_cxx14__alloc_traitsISaISt13_Rb_tree_nodeISsEEE7destroyERS3_PS2_HandleSehExceptionsInMethodIfSupported_ZNKSt3setIPKcSt4lessIS1_ESaIS1_EE5countERKS1_TEST_name__xstat_ZN9__gnu_cxx17__normal_iteratorIPN7testing14TestPartResultESt6vectorIS2_SaIS2_EEEppEi_ZN7testing8internal24XmlUnitTestResultPrinter18OutputXmlAttributeEPSoRKSsS4_S4__ZNSs12_M_leak_hardEv_M_insert_unique__Ios_Iostate_ZN9__gnu_cxx17__normal_iteratorIPN7testing14TestPartResultESt6vectorIS2_SaIS2_EEEppEviterator_traits_ZN9__gnu_cxx13new_allocatorIN7testing12TestPropertyEE9constructEPS2_RKS2__ZNSsixEj_ZN7testing8internal6String10FormatByteEh_ZNSt6vectorIN7testing12TestPropertyESaIS1_EEaSERKS3__ZN9__gnu_cxx13new_allocatorIPN7testing8TestInfoEE8allocateEjPKvSetTestPartResultReporterForCurrentThreadOnEnvironmentsSetUpEnd_ZNSspLERKSsAddArguments >size_typeEnvironment_ZN9__gnu_cxx17__normal_iteratorIPPN7testing8TestCaseESt6vectorIS3_SaIS3_EEEmmEvfull_regex_srand_Destroy__delta_ZN9__gnu_cxx17__normal_iteratorIPPcSt6vectorIS1_SaIS1_EEEmmEifreeset_catch_exceptionspart_ZN9__gnu_cxx14__alloc_traitsISaIPcEE8max_sizeERKS2_TypedTestCasePState_ZN7testing8internal14GTestMutexLockaSERKS1__ZN9__gnu_cxx17__normal_iteratorIPPcSt6vectorIS1_SaIS1_EEEmmEv_ZN7testing8internal9DeathTest24last_death_test_message_EtypeCreateCodePointFromUtf16SurrogatePair_ZNSt13_Bit_iteratormmEiConfigureXmlOutputalso_run_disabled_tests__ZNSt13_Bit_iteratormmEv_ZNSt6vectorIPN7testing8TestCaseESaIS2_EE2atEj_ZNSt6vectorIPN7testing8TestCaseESaIS2_EEixEjinit_ZNKSt9basic_iosIcSt11char_traitsIcEE4fillEvother_ZNKSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE4findERKSs_ZNK7testing8internal13DeathTestImpl7spawnedEvOnTestProgramStart_Unwind_Resumeai_flagskDeathTestThrew_ZNSbIwSt11char_traitsIwESaIwEE7_M_copyEPwPKwj_ZN7testing11EnvironmentD0EvTearDown_Rb_tree_node_ZNSs4_Rep10_M_refdataEv__cxxabiv1_ZN7testing8internal17Int32FromEnvOrDieEPKci__pos_ZNSt6vectorIN7testing14TestPartResultESaIS1_EE3endEvtype_info_ZNK9__gnu_cxx17__normal_iteratorIPN7testing14TestPartResultESt6vectorIS2_SaIS2_EEEmiEi_ZNSt6vectorIPcSaIS0_EE4backEvwcsstrTesthost_name__ZNKSt6vectorIPN7testing11EnvironmentESaIS2_EE4sizeEvkReservedTestSuitesAttributes_ZN7testing7MessagelsERKSbIwSt11char_traitsIwESaIwEEpath_ZN7testing8internal16ForkingDeathTest4WaitEv_ZNKSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE5emptyEvClearAdHocTestResultst_size_ZN7testing8internal24XmlUnitTestResultPrinter18OnTestIterationEndERKNS_8UnitTestEi_ZNKSt6vectorIPN7testing8TestCaseESaIS2_EE4backEv_ZNK9__gnu_cxx13new_allocatorISt13_Rb_tree_nodeISsEE8max_sizeEv_ZNSt6vectorISsSaISsEE2atEj_ZNKSt13_Rb_tree_nodeIPKcE9_M_valptrEvFLAGS_gtest_death_test_use_fork_ZN7testing8internal12UnitTestImpl18death_test_factoryEv_Rb_tree_impl, std::allocator > >, false>_ZN7testing8UnitTest18GetMutableTestCaseEi_ZNKSs5c_strEvreverse_iterator<__gnu_cxx::__normal_iterator > > >exit_code_ZNSt12_Vector_baseIN7testing14TestPartResultESaIS1_EE11_M_allocateEjtest_properties__ZN7testing8TestCaseD0Ev_ZNKSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE7_M_rootEvfraction_bits_ZN7testing8internal10scoped_ptrINS0_17StreamingListener20AbstractSocketWriterEE5resetEPS3_testing_Result_ZN9__gnu_cxx17__normal_iteratorIPPN7testing8TestInfoESt6vectorIS3_SaIS3_EEEpLEitm_mday_ZNK9__gnu_cxx17__normal_iteratorIPN7testing12TestPropertyESt6vectorIS2_SaIS2_EEEdeEv__niter_baseAppend_ZNKSt12_Vector_baseIPcSaIS0_EE19_M_get_Tp_allocatorEv_Iter_predsi_addr_ZN9__gnu_cxx13new_allocatorIwE9constructEPwRKw_ZN7testing8internal2RE12PartialMatchERKSsRKS1_RunAllTests__miter_base_ZNKSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE3endEvGetTestCase_M_swap_data_ZNSt10_Iter_baseIPPN7testing11EnvironmentELb0EE7_S_baseES3_~basic_iostream_M_erase_at_enditerator_traitschild_pidallocator_ZNK9__gnu_cxx13new_allocatorIPcE7addressERS1__ZNK7testing8internal8FilePath11IsDirectoryEv_ZNKSt4lessISsEclERKSsS2_precisioncopy<__gnu_cxx::__normal_iterator >, __gnu_cxx::__normal_iterator > >MSG_NOSIGNALkOutputFlag_ZN7testing7MessagelsEPFRSoS1_E_ZNSt6vectorIN7testing14TestPartResultESaIS1_EE6assignEjRKS1_ad_hoc_test_result_ZNSt3setISsSt4lessISsESaISsEE5clearEvsingular_form_Iter_base_ZN7testing31TestPartResultReporterInterface20ReportTestPartResultERKNS_14TestPartResultEoperator<< _ZN9__gnu_cxx17__normal_iteratorIPPN7testing17TestEventListenerESt6vectorIS3_SaIS3_EEEpLEi__are_samebinary_function__resoperator<< kTestTotalShardsiterator_traits_ZN9__gnu_cxx17__normal_iteratorIPcSsEpLEibasic_streambuf >_ZNSt6vectorISsSaISsEE18_M_fill_initializeEjRKSs_call_addroriginal_working_dir_ZN7testing18TestEventListeners23SuppressEventForwardingEv_ZNSbIwSt11char_traitsIwESaIwEE9push_backEw_ZNKSs7compareERKSsExitSummary_ZNK9__gnu_cxx17__normal_iteratorIPKN7testing8internal9TraceInfoESt6vectorIS3_SaIS3_EEE4baseEvtimeval_ZNKSt6vectorIPN7testing8TestCaseESaIS2_EE4sizeEv_ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EEixEj_ZNSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE9push_backERKS3___normal_iterator > >~DeathTest_ZNSbIwSt11char_traitsIwESaIwEE6resizeEjwvector, std::allocator >, std::allocator, std::allocator > > >fopen_ZNSbIwSt11char_traitsIwESaIwEEaSEPKw_ZNSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE4dataEvdifference_typerebind_ZNSo5flushEvsetprecision_M_value_field_ZN9__gnu_cxx14__alloc_traitsISaIPcEE10deallocateERS2_PS1_j_S_badbit~OsStackTraceGetterInterfacecaller_frame__ZNSs7_M_dataEPcwcslenline_endtype_param__ZNSbIwSt11char_traitsIwESaIwEE10_S_compareEjj_ZNK7testing8internal12UnitTestImpl17failed_test_countEvenvironSOCK_CLOEXEClisteners_kInternalRunDeathTestFlag5div_tGetGlobalTestPartResultReporterScopedTracewcstoullboolalpha_ZN7testing8internal16ForkingDeathTest13set_child_pidEi_ZN7testing8internal13FloatingPointIfE24SignAndMagnitudeToBiasedERKj_Link_type_ZN7testing8internal14StackGrowsDownEv_ZSt9__find_ifIN9__gnu_cxx17__normal_iteratorIPKSsSt6vectorISsSaISsEEEENS0_5__ops16_Iter_equals_valIS2_EEET_SB_SB_T0_St26random_access_iterator_tag_ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EE6resizeEjS2_Normalizetest_propertywrite_fd_swapreverse_iterator, std::allocator > > >_ZNKSt6vectorIPN7testing8TestInfoESaIS2_EE12_M_check_lenEjPKcscientificCaptureStream_S_showposGTEST_TOTAL_SHARDS_ZN7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEE3setERKS5_predicate_ZNK9__gnu_cxx17__normal_iteratorIPKPN7testing11EnvironmentESt6vectorIS3_SaIS3_EEEdeEvpair, std::allocator > >, std::_Rb_tree_iterator, std::allocator > > >_ZNSs13_S_copy_charsEPcN9__gnu_cxx17__normal_iteratorIS_SsEES2__ZNKSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE5beginEv_ZNKSbIwSt11char_traitsIwESaIwEE7compareEPKw_ZNSbIwSt11char_traitsIwESaIwEE7replaceEjjPKwDelete_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE8_S_valueEPKSt18_Rb_tree_node_baselldiv_t_ZN7testing8internal30GetBoolAssertionFailureMessageERKNS_15AssertionResultEPKcS5_S5_~_Alloc_hider_M_create_nodedeath_test_count_ZN9__gnu_cxx17__normal_iteratorIPPN7testing8TestCaseESt6vectorIS3_SaIS3_EEEpLEi_ZNKSt6vectorIN7testing8internal9TraceInfoESaIS2_EE5frontEv_ZN7testing8UnitTest27parameterized_test_registryEv_ZNSbIwSt11char_traitsIwESaIwEE5eraseEjj_ZN9__gnu_cxx17__normal_iteratorIPPcSt6vectorIS1_SaIS1_EEEpLEiBiggestConvertible_ZNKSt6vectorIN7testing14TestPartResultESaIS1_EE4dataEv_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE3endEvMSG_TRYHARD_ZN7testing8internal18OsStackTraceGetter17CurrentStackTraceEii_IO_buf_basematches_filter_ZNSt13_Bit_iteratorpLEi__FILE__pthread_internal_slist~InternalRunDeathTestFlag_ZNKSt18_Bit_iterator_baseneERKS__ZNK9__gnu_cxx17__normal_iteratorIPN7testing12TestPropertyESt6vectorIS2_SaIS2_EEEixEifilename__ZNSt18_Bit_iterator_base10_M_bump_upEv_ZNSbIwSt11char_traitsIwESaIwEE5clearEv_S_endTestBody_ZNKSt6vectorIN7testing12TestPropertyESaIS1_EE4backEv_ZNK9__gnu_cxx17__normal_iteratorIPKSsSt6vectorISsSaISsEEEdeEvget_allocator_ZNKSt6vectorIN7testing14TestPartResultESaIS1_EE12_M_check_lenEjPKc_ZNSt14_Bit_reference4flipEv_ZN9__gnu_cxx13new_allocatorIPN7testing17TestEventListenerEE8allocateEjPKvcaptured_stream_ZNK9__gnu_cxx17__normal_iteratorIPKPN7testing11EnvironmentESt6vectorIS3_SaIS3_EEEixEikUnknownFile_ZNKSt12_Vector_baseISsSaISsEE19_M_get_Tp_allocatorEv_ZNSt6vectorIPcSaIS0_EEaSERKS2_test_indices_operator!=<__gnu_cxx::__normal_iterator > >_ZNK9__gnu_cxx13new_allocatorISsE7addressERSsPrintTo_ZN7testing8internal17StreamingListener16OnTestPartResultERKNS_14TestPartResultE_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE16_M_insert_uniqueERKS1__ZN9__gnu_cxx17__normal_iteratorIPPN7testing11EnvironmentESt6vectorIS3_SaIS3_EEEmmEikStdErrFileno_ZN7testing8internal13DeathTestImpl26ReadAndInterpretStatusByteEv~DefaultDeathTestFactory_ZN9__gnu_cxx17__normal_iteratorIPPN7testing11EnvironmentESt6vectorIS3_SaIS3_EEEmmEv_ZNKSt13_Rb_tree_nodeISsE9_M_valptrEv_ZN9__gnu_cxx13new_allocatorIPN7testing8internal29ParameterizedTestCaseInfoBaseEE7destroyEPS4_SuppressTestEventsIfInSubprocessAddArgument_ZN9__gnu_cxx17__normal_iteratorIPN7testing12TestPropertyESt6vectorIS2_SaIS2_EEEppEv_M_initializefastmap_accurate_ZNSbIwSt11char_traitsIwESaIwEE7_M_leakEvreverse_iterator<__gnu_cxx::__normal_iterator > > >_ZNSs7replaceEjjPKcjkBreakOnFailureFlaglong unsigned int__uninitialized_copy_a_ZN7testing8internal20SingleFailureCheckerC2EPKNS_19TestPartResultArrayENS_14TestPartResult4TypeERKSsword_list_ZN7testing8internal12UnitTestImpl41SetTestPartResultReporterForCurrentThreadEPNS_31TestPartResultReporterInterfaceEtm_isdst_ZNK9__gnu_cxx13new_allocatorISt13_Rb_tree_nodeIPKcEE8max_sizeEvint_n_sign_posn_ZNSt6vectorIPN7testing8TestInfoESaIS2_EE9push_backERKS2_operator!= >HasGoogleTestFlagPrefix_ZNKSt6vectorIPcSaIS0_EE2atEj_ZNKSbIwSt11char_traitsIwESaIwEE9_M_ibeginEv_ZNK7testing8internal10scoped_ptrISt18basic_stringstreamIcSt11char_traitsIcESaIcEEE3getEv_ZN7testing8internal16InDeathTestChildEv_ZNSt6vectorIN7testing12TestPropertyESaIS1_EE9push_backERKS1_TypeParam_ZNK9__gnu_cxx17__normal_iteratorIPKSsSt6vectorISsSaISsEEEixEiegptr_ZNKSt9type_infoeqERKS__ZNSt6vectorIPN7testing8TestCaseESaIS2_EE8_M_eraseEN9__gnu_cxx17__normal_iteratorIPS2_S4_EE__intptr_tClearTestPartResultsoperator==<__gnu_cxx::__normal_iterator > >CharFormatvfwprintf_ZN7testing17TestEventListener16OnTestPartResultERKNS_14TestPartResultE_ZNK7testing8UnitTest11GetTestCaseEi_ZN7testing8internal7g_argvsE_ZNSt14_Bit_referenceaSERKS_EscapeXmlText_ZNSbIwSt11char_traitsIwESaIwEE6insertEjjw_ZNKSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE11lower_boundERKSsstrchr_ZNKSt5ctypeIcE8do_widenEc__normal_iterator > >fixed_IO_read_base_ZNSt6vectorIN7testing14TestPartResultESaIS1_EE4rendEv__find_if<__gnu_cxx::__normal_iterator >, __gnu_cxx::__ops::_Iter_pred >_ZNKSt16reverse_iteratorIN9__gnu_cxx17__normal_iteratorIPPN7testing11EnvironmentESt6vectorIS4_SaIS4_EEEEEptEv_ZNSbIwSt11char_traitsIwESaIwEE4swapERS2__ZNKSt6vectorIPN7testing8TestInfoESaIS2_EE4rendEv_ZNKSt6vectorIiSaIiEE5emptyEvScopedFakeTestPartResultReporterkThrowOnFailureFlag__alloc_ZNSt11char_traitsIcE2ltERKcS2__ZNK7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE3getEvIsSubstringPred_M_insert_ZNK7testing8TestInfo13is_reportableEv_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE4rendEvsockaddr_ZN7testing8DoubleLEEPKcS1_dd__debug_ZN7testing8internal27PrettyUnitTestResultPrinter18OnTestProgramStartERKNS_8UnitTestE_ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EE4backEvfull_name_Swallow_assignwcstod_ZNK7testing14TestPartResult7messageEvreset_ZNK9__gnu_cxx13new_allocatorIPN7testing11EnvironmentEE8max_sizeEv_ZNSt6vectorIiSaIiEE4dataEv_ZNK9__gnu_cxx13new_allocatorIN7testing8internal9TraceInfoEE7addressERKS3___addressofuninitialized_copy_ZNKSt15basic_stringbufIcSt11char_traitsIcESaIcEE3strEv_ZN7testing8internal15UnitTestOptions13MatchesFilterERKSsPKcreg_syntax_t_ZNSt9basic_iosIcSt11char_traitsIcEE8setstateESt12_Ios_Iostate_ZNK7testing8internal8FilePath15RemoveExtensionEPKc_vptr.Test_ZN7testing8internal13FloatingPointIfE3MaxEvwmemcmp_ZNSbIwSt11char_traitsIwESaIwEE7replaceEN9__gnu_cxx17__normal_iteratorIPwS2_EES6_S5_S5_value_type_ZNSs15_M_replace_safeEjjPKcjsuffix_Const_Link_type_ZNSt3setIPKcSt4lessIS1_ESaIS1_EE5eraseERKS1_this_test_info_ZN7testing8internal13ExecDeathTest32GetArgvsForDeathTestChildProcessEvconstructInitGoogleTestImpl_ZNK9__gnu_cxx17__normal_iteratorIPPN7testing11EnvironmentESt6vectorIS3_SaIS3_EEEmiEi_ZN9__gnu_cxx13new_allocatorISt13_Rb_tree_nodeISsEE10deallocateEPS2_j_ZNSt6vectorIPN7testing8TestInfoESaIS2_EE8_M_eraseEN9__gnu_cxx17__normal_iteratorIPS2_S4_EEStreamableToStringskipwshas_owner_operator!=_Iter_base__is_move_iterator_ZNKSt6vectorIN7testing12TestPropertyESaIS1_EE4sizeEv__cxa_rethrow_ZN9__gnu_cxx14__alloc_traitsISaIPN7testing8TestInfoEEE7destroyERS4_PS3__ZNSt6vectorIN7testing14TestPartResultESaIS1_EEixEjsocket_ZN9__gnu_cxx17__normal_iteratorIPPN7testing8TestCaseESt6vectorIS3_SaIS3_EEEmmEi_ZNSt6vectorIPN7testing8TestCaseESaIS2_EE18_M_fill_initializeEjRKS2_property_ZNSbIwSt11char_traitsIwESaIwEE6appendEPKw~EmptyTestEventListener_ZN7testing11EnvironmentD2Ev_ZNK7testing10TestResult17GetTestPartResultEirebind_Iter_base_Rb_tree_colortv_sec_ZNSs7replaceEN9__gnu_cxx17__normal_iteratorIPcSsEES2_PKcjuse_color_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE5clearEv_ZN7testing8UnitTest17AddTestPartResultENS_14TestPartResult4TypeEPKciRKSsS6__ZNSt6vectorIPcSaIS0_EE7reserveEj_ZNSt12_Vector_baseIN7testing8internal9TraceInfoESaIS2_EE12_Vector_impl12_M_swap_dataERS5_test_properites_mutex__unused2IN_PROGRESSpid_t__are_same__destroyUniversalTersePrinterPrintCharsAsStringToIsSubstringImpl >GetStreamset_should_run_ZNKSt6vectorIN7testing14TestPartResultESaIS1_EE5beginEvbtowc_ZNKSt6vectorIPN7testing8TestInfoESaIS2_EE5frontEv_ZStplIcSt11char_traitsIcESaIcEESbIT_T0_T1_ERKS6_PKS3__M_node_counttm_ming_init_gtest_countMSG_WAITALLoperator<< _ZNSt6vectorIPN7testing8TestCaseESaIS2_EE5beginEv_ZN9__gnu_cxx14__alloc_traitsISaIN7testing12TestPropertyEEE8max_sizeERKS3__ZNSbIwSt11char_traitsIwESaIwEE6appendERKS2_jjbasic_stringstrcmp_ZNK7testing8internal12UnitTestImpl6FailedEv_ZN7testing8internal12UnitTestImpl24ConfigureStreamingOutputEv_ZNSt6vectorIiSaIiEE6rbeginEv_ZN7testing8internal30WriteToShardStatusFileIfNeededEv_ZN7testing8internal35HandleExceptionsInMethodIfSupportedINS0_15TestFactoryBaseEPNS_4TestEEET0_PT_MS6_FS5_vEPKc_ZN7testing8internal24HasNewFatalFailureHelper20ReportTestPartResultERKNS_14TestPartResultE_ZNK9__gnu_cxx13new_allocatorIPKcE8max_sizeEv_ZNSt3setIPKcSt4lessIS1_ESaIS1_EE5eraseESt23_Rb_tree_const_iteratorIS1_ES7_ai_addr_ZNK9__gnu_cxx13new_allocatorISsE8max_sizeEv__strThreadLocalfailuresfwscanf~AbstractSocketWriter_DestroyCreateFolder_ZN7testing9internal220PrintBytesInObjectToEPKhjPSoisspace_ZNKSs8_M_limitEjj_ZN7testing16AssertionFailureERKNS_7MessageEglobal_test_part_result_repoter__ZNSs4swapERSs_ZNKSt3setISsSt4lessISsESaISsEE4rendEv_ZNSt12_Vector_baseIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE17_M_create_storageEj__uninitialized_move_if_noexcept_a >_ZN7testing8internal12UnitTestImpl11FilterTestsENS1_18ReactionToShardingE_ZNK9__gnu_cxx17__normal_iteratorIPKN7testing8internal9TraceInfoESt6vectorIS3_SaIS3_EEEplEifailure_message_ZNKSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE14_M_lower_boundEPKSt13_Rb_tree_nodeIS1_ESB_RKS1__ZNSbIwSt11char_traitsIwESaIwEE7replaceEjjRKS2_jjStreamableToStringAlmostEqualsInDeathTestChild_ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EE6rbeginEvShouldShardoperator<< _ZNK9__gnu_cxx13new_allocatorIwE7addressERKw_ZNSt16reverse_iteratorIN9__gnu_cxx17__normal_iteratorIPPN7testing11EnvironmentESt6vectorIS4_SaIS4_EEEEEppEi_ZNKSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE8max_sizeEv_ZNKSt17_Rb_tree_iteratorISsEeqERKS0__ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE21_M_get_Node_allocatorEv_ZN7testing14InitGoogleTestEPiPPcfind_if<__gnu_cxx::__normal_iterator >, testing::internal::TestPropertyKeyIs>GetEnviron_ZNSt16reverse_iteratorIN9__gnu_cxx17__normal_iteratorIPPN7testing11EnvironmentESt6vectorIS4_SaIS4_EEEEEppEvdefault_val_ZNK7testing8TestInfo11value_paramEv_ZNSt3setISsSt4lessISsESaISsEE11lower_boundERKSs_ZNSs6insertEjRKSsjj_ZN7testing14InitGoogleTestEPiPPwCmpHelperSTRNEMSG_WAITFORONE_ZN7testing8internal9MutexBase6UnlockEv_ZNSbIwSt11char_traitsIwESaIwEE5eraseEN9__gnu_cxx17__normal_iteratorIPwS2_EEoperator&=pattern_DeathTestFactory_ZNSt3setIPKcSt4lessIS1_ESaIS1_EE5eraseESt23_Rb_tree_const_iteratorIS1_E_ZNK9__gnu_cxx13new_allocatorIPN7testing11EnvironmentEE7addressERS3__ZN7testing8internal24XmlUnitTestResultPrinterD2Ev_ZN7testing8internal18OsStackTraceGetterD0EvTestEventListeners_ZNSt11char_traitsIcE4moveEPcPKcj~AssertHelperkTestShardIndex_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE11upper_boundERKSs_ZN7testing8internal17StreamingListener12SocketWriter14MakeConnectionEv_ZNK7testing8internal13FloatingPointIfE13fraction_bitsEv_M_refcopy_ZNSt20__uninitialized_copyILb0EE13__uninit_copyIPN7testing12TestPropertyES4_EET0_T_S6_S5_si_uid_ZNKSt15basic_streambufIcSt11char_traitsIcEE5pbaseEv_Destroy_ZN9__gnu_cxx13new_allocatorIPN7testing8TestInfoEE7destroyEPS3__ZN7testing8internal26GoogleTestFailureExceptionC2ERKNS_14TestPartResultEsa_mask_S_floatfieldsizetypeIsSubstringImpl_ZN7testing4TestC2Ev_ZNSs4_Rep10_M_refcopyEv~TestPartResultReporterInterfacepremature_exit_file_ZNKSbIwSt11char_traitsIwESaIwEE5rfindEPKwjj__errno_location_ZNSt11char_traitsIwE3eofEv_ZNKSt23_Rb_tree_const_iteratorIPKcEeqERKS2_new_allocator_ZNKSt6vectorIPcSaIS0_EE6rbeginEvoperator()_ZNKSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE12_M_rightmostEv_ZNK7testing10TestResult6FailedEv_M_get_insert_unique_pos_ZNSt12_Vector_baseIN7testing14TestPartResultESaIS1_EE19_M_get_Tp_allocatorEv_ZN7testing16AssertionFailureEvMSG_SYN__value_ZN9__gnu_cxx17__normal_iteratorIPN7testing14TestPartResultESt6vectorIS2_SaIS2_EEEmmEi_ZN7testing15AssertionResultlsINS_14TestPartResultEEERS0_RKT__ZN9__gnu_cxx14__alloc_traitsISaIN7testing8internal9TraceInfoEEE17_S_select_on_copyERKS4_success_scoped_ptr, std::allocator > >sigactiondirectory_ZN9__gnu_cxx17__normal_iteratorIPN7testing14TestPartResultESt6vectorIS2_SaIS2_EEEmmEveofbit_ZNSt3tr110tuple_sizeINS_5tupleIIEEEE5valueE_ZNSs4_Rep26_M_set_length_and_sharableEj_ZNSt6vectorIPcSaIS0_EE5eraseEN9__gnu_cxx17__normal_iteratorIPS0_S2_EES6_CaseInsensitiveWideCStringEquals_ZNKSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE8key_compEv_ZNSt13_Rb_tree_nodeIPKcE9_M_valptrEvgtest_trace_stack_should_ZNSt11char_traitsIwE4copyEPwPKwj_ZNSt10_Iter_baseIPPcLb0EE7_S_baseES1_printf_ZNSt12_Vector_baseISsSaISsEE12_Vector_impl12_M_swap_dataERS2__ZN7testing8internal13DeathTestImpl10set_statusEi__lentm_monrepeat__ZN7testing8TestCase22TestReportableDisabledEPKNS_8TestInfoEsi_pid__off_t_M_get_Node_allocator__resultdefault_global_test_part_result_reporter_factory_new_allocatorrebindDoubleNearPredFormatreverse_iterator<__gnu_cxx::__normal_iterator > > >_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE8_S_valueEPKSt13_Rb_tree_nodeIS1_Eflag_str_ZN9__gnu_cxx14__alloc_traitsISaISt13_Rb_tree_nodeISsEEE8allocateERS3_j_ZNSt6vectorIPN7testing11EnvironmentESaIS2_EE5eraseEN9__gnu_cxx17__normal_iteratorIPS2_S4_EES8__ZN7testing8internal24ParseGoogleTestFlagsOnlyEPiPPc_ZNKSt23_Rb_tree_const_iteratorISsE13_M_const_castEv_ZNKSt12_Vector_baseIPN7testing8TestCaseESaIS2_EE19_M_get_Tp_allocatorEv_M_rightmostIsSpace_ZNSolsEd_ZNSolsEf_ZNSolsEi_ZNSolsEjdiffobj_bytesShuffleRange_syscall_ZNSolsEx_ZNSt6vectorIiSaIiEE8_M_eraseEN9__gnu_cxx17__normal_iteratorIPiS1_EEkBitCountmarker__wch_ZN7testing8internal12UnitTestImpl14UnshuffleTestsEvlistener_Arg__copy_move_boperator== >_ZdaPv__alloc_swap, std::allocator > >, true>StackGrowsDownFloatingPointUnionoperator++ignore_ZNSt10_Iter_baseIPPN7testing8TestCaseELb0EE7_S_baseES3_operator+=__glibc_reserved4__glibc_reserved5range_width~Test_ZNK7testing8TestCase18ad_hoc_test_resultEv__string_typePrintFailedTestsallocator, std::allocator > >trace_ZNKSt14_Bit_referenceltERKS__ZN7testing8internal27PrettyUnitTestResultPrinter15OnTestCaseStartERKNS_8TestCaseE_ZN7testing8internal21UniversalTersePrinterIPKwE5PrintES3_PSoInitGoogleTestImpl_ZN9__gnu_cxx17__normal_iteratorIPPN7testing8TestInfoESt6vectorIS3_SaIS3_EEEmIEibasic_string, std::allocator >flag_lenCapturedStreamwcsncat__lhs_ZN7testing8internal10scoped_ptrINS0_17StreamingListener20AbstractSocketWriterEEaSERKS4__ZNSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE8_M_eraseEN9__gnu_cxx17__normal_iteratorIPS3_S5_EEnew_allocatorsetstate_ZNSt6vectorIiSaIiEE14_M_fill_assignEjRKi_ZN7testing8internal9DeathTestC2Ev_ZN7testing8internal9Arguments4ArgvEv_ZNSbIwSt11char_traitsIwESaIwEE6resizeEj_ZNK7testing8TestCase11GetTestInfoEi_ZNSt11char_traitsIwE7compareEPKwS2_j_ZNK7testing8internal10scoped_ptrINS0_24InternalRunDeathTestFlagEEptEv_ZNSt6vectorIPN7testing11EnvironmentESaIS2_EE5frontEvoperator--Delete_ZNKSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE8max_sizeEv__elision_data_Containeroperator-=operator->FormatTimeInMillisAsSecondsShuffleoperator<< _ZN7testing8internal15GetTimeInMillisEvtm_year_ZNSt6vectorIN7testing12TestPropertyESaIS1_EE5frontEvLIVED_ZNSs16_S_construct_auxIPcEES0_T_S1_RKSaIcESt12__false_typereverse_iterator<__gnu_cxx::__normal_iterator, std::allocator > > >GetMutableTestInfo_ZNK9__gnu_cxx17__normal_iteratorIPcSsEdeEvMSG_DONTROUTE_ZNSt6vectorIN7testing14TestPartResultESaIS1_EE8pop_backEv~_Vector_impl_M_widen_initargsto_int_type_ZNKSt6vectorIN7testing12TestPropertyESaIS1_EE12_M_check_lenEjPKc_M_set_sharableenvironments_ZSt7nothrow_ZNSt12_Vector_baseIPN7testing11EnvironmentESaIS2_EE12_Vector_impl12_M_swap_dataERS5___iter_equals_val >unit_test__ZN9__gnu_cxx17__normal_iteratorIPPN7testing17TestEventListenerESt6vectorIS3_SaIS3_EEEmIEi_ZNKSbIwSt11char_traitsIwESaIwEE4dataEvallocateoperator<< ai_nextParseInt32Flagnew_value_ZN9__gnu_cxx17__normal_iteratorIPcSsEmIEi__is_move_iterator, std::allocator >*>__builtin_strstr_ZNSt6vectorISsSaISsEE9push_backERKSs_IO_write_end~TestCaseNameIs__uninitialized_copy_a_IO_save_basepptrtm_wday_ZN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE3setERKS3_kExponentBitMask_ZNSt11char_traitsIwE7not_eofERKj_ZNSt6vectorIN7testing14TestPartResultESaIS1_EE5frontEv_ZN7testing32ScopedFakeTestPartResultReporterC2ENS0_13InterceptModeEPNS_19TestPartResultArrayE__are_same_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE10_S_minimumEPKSt18_Rb_tree_node_base_ZN7testing8internal18g_init_gtest_countE_ZN7testing8UnitTest4implEva_typetest_part_resultlast_death_test_case__ZNSt12_Vector_baseISsSaISsEE13_M_deallocateEPSsj_ZNK9__gnu_cxx17__normal_iteratorIPcSsEixEi_ZN9__gnu_cxx13new_allocatorIPN7testing11EnvironmentEE7destroyEPS3__ZNKSt6vectorIPcSaIS0_EE8capacityEv_ZNSt11char_traitsIwE12to_char_typeERKjdistance__new_start_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE6_S_keyEPKSt18_Rb_tree_node_baseSetInjectableArgvsos_stack_trace_ZNK9__gnu_cxx17__normal_iteratorIPPN7testing8TestCaseESt6vectorIS3_SaIS3_EEE4baseEv_ZNK9__gnu_cxx13new_allocatorIPcE8max_sizeEvint_type~TestEventListeners_ZN7testing8internal17StreamingListener20AbstractSocketWriter15CloseConnectionEvMSG_PEEKremoveval1val2_ZN7testing8internal24XmlUnitTestResultPrinter29TestPropertiesAsXmlAttributesERKNS_10TestResultEsegmentn_sign_posnactual_message_ZNSt6vectorIPN7testing8TestCaseESaIS2_EE4backEva_key_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE8_S_rightEPKSt18_Rb_tree_node_base_ZNK7testing8internal8FilePath14RemoveFileNameEvwrite_fdrebind, std::allocator > > >captured_fd_ZNSt12_Vector_baseIN7testing12TestPropertyESaIS1_EE13_M_deallocateEPS1_jWait_ZN7testing17TestEventListener18OnTestProgramStartERKNS_8UnitTestEOnTestIterationStartuninitialized_copy*, std::basic_string*>_ZNKSt6vectorIPcSaIS0_EE8max_sizeEv_M_end_ZNSt6vectorIPcSaIS0_EE6insertEN9__gnu_cxx17__normal_iteratorIPS0_S2_EERKS0__ZNSt12_Vector_baseIN7testing8internal9TraceInfoESaIS2_EE19_M_get_Tp_allocatorEvFormatByteiterator_traits_ZNK9__gnu_cxx17__normal_iteratorIPPcSt6vectorIS1_SaIS1_EEE4baseEv_ZSt18_Rb_tree_incrementPKSt18_Rb_tree_node_basekDeathTestReturned_S_copy_chars_ZNKSt6vectorIPcSaIS0_EE5emptyEvtotal_test_count_ZNSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE14_M_fill_insertEN9__gnu_cxx17__normal_iteratorIPS3_S5_EEjRKS3_IsValidXmlCharacter_ZNSt6vectorIPN7testing8TestCaseESaIS2_EEaSERKS4__ZN7testing8internal21ImplicitlyConvertibleIPKvS3_E8MakeFromEv_ZNSt6vectorIN7testing14TestPartResultESaIS1_EE6insertEN9__gnu_cxx17__normal_iteratorIPS1_S3_EEjRKS1__ZN9__gnu_cxx17__normal_iteratorIPN7testing14TestPartResultESt6vectorIS2_SaIS2_EEEpLEiArgumentsstreamable_ZNSs7_M_copyEPcPKcj_ZN7testing8internal10scoped_ptrISt18basic_stringstreamIcSt11char_traitsIcESaIcEEEaSERKS7_signum__Rb_tree_impl_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE10_S_minimumEPSt18_Rb_tree_node_baseColoredPrintfkColorFlag~Environmentsa_sigaction_ZN9__gnu_cxx17__normal_iteratorIPPN7testing8TestCaseESt6vectorIS3_SaIS3_EEEmIEi_IteratorL_ZN7testing8internal10scoped_ptrIKSsE5resetEPS2__ZN7testing8internal26ThreadLocalValueHolderBaseD2Ev_ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EE9push_backERKS2__ZNKSbIwSt11char_traitsIwESaIwEE13find_first_ofEwjstack_sizesi_stimeshard_testsGetNextRandomSeed__arg_ZN9__gnu_cxx17__normal_iteratorIPPcSt6vectorIS1_SaIS1_EEEmIEi_Iter_baseallocator >_ZN7testing10TestResultD2Ev_M_insert_equal_lowerreverse_iterator<__gnu_cxx::__normal_iterator, std::allocator > > >_ZNSt13_Bit_iteratormIEi_ZN7testing15AssertionResultlsIA11_cEERS0_RKT__ZNK7testing8UnitTest4implEv_ZN9__gnu_cxx13new_allocatorISsE9constructEPSsRKSs_ZNK7testing8internal10scoped_ptrINS0_17StreamingListener20AbstractSocketWriterEEdeEv_ZNSt11char_traitsIcE3eofEvfastmap_ZNKSt3setISsSt4lessISsESaISsEE11equal_rangeERKSspthread_key_tmmap_ZNK7testing8UnitTest30reportable_disabled_test_countEvgetaddrinfo_Iter_base, std::allocator >*, false>TestReportablefull_flag__niter_base*>_ZNKSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE5countERKSs_ZNSbIwSt11char_traitsIwESaIwEE6assignEPKwjst_uid__builtin_strrchrstr_valdefault_per_thread_test_part_result_reporter_thousands_sep_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE15_M_destroy_nodeEPSt13_Rb_tree_nodeISsE_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE15_M_insert_lowerEPSt18_Rb_tree_node_baseRKS1__ZN7testing8internal17TestEventRepeater7ReleaseEPNS_17TestEventListenerE_ZNK7testing8internal24InternalRunDeathTestFlag4lineEv__copy_move_bPrintByteSegmentInObjectTo_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE4rendEvInt32_ZNK7testing8internal2RE7patternEv_ZN9__gnu_cxx17__normal_iteratorIPN7testing12TestPropertyESt6vectorIS2_SaIS2_EEEmmEv_ZNSt6vectorISsSaISsEED2Ev_ZNSs7replaceEN9__gnu_cxx17__normal_iteratorIPcSsEES2_PKccopya_test_case_name_ZNSbIwSt11char_traitsIwESaIwEE13_S_copy_charsEPwPKwS5___copy_move_bEscapeXmlAttribute_ForwardIterator_ZNK9__gnu_cxx17__normal_iteratorIPKPN7testing17TestEventListenerESt6vectorIS3_SaIS3_EEE4baseEv_ZNSt6vectorIN7testing12TestPropertyESaIS1_EE5eraseEN9__gnu_cxx17__normal_iteratorIPS1_S3_EE_Bit_reference_ZN7testing8internal24XmlUnitTestResultPrinteraSERKS1_gtest_trace_stack_ZNSt8ios_base4setfESt13_Ios_Fmtflags_ZN7testing8internal12UnitTestImpl20ClearAdHocTestResultEv_ZN7testing8internal15NoExecDeathTestD2Evwords_ZNK7testing8internal10scoped_ptrINS0_16DeathTestFactoryEEdeEvstart_timestamp__ZNKSt17_Rb_tree_iteratorISsEdeEv_ZNKSs7compareEjjPKcj_ZNK7testing8UnitTest6PassedEv_Destroy_aux_ZNKSt6vectorIPN7testing17TestEventListenerESaIS2_EE5beginEvcopy_backward_ZNSt12_Vector_baseIPN7testing8TestInfoESaIS2_EE11_M_allocateEjdestroy_ZNSs6insertEjPKc_ZN7testing8internal10scoped_ptrINS0_16DeathTestFactoryEE5resetEPS2__ZNKSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE6rbeginEv_ZN7testing8internal17StreamingListener20OnTestIterationStartERKNS_8UnitTestEig_help_flagFlagToEnvVar_ZN9__gnu_cxx17__normal_iteratorIPN7testing12TestPropertyESt6vectorIS2_SaIS2_EEEppEia_file_name_ZNKSt6vectorIPN7testing8TestCaseESaIS2_EE5emptyEvwidenF_OWNER_TIDnonfatally_failed_ZN7testing8internal19UniversalPrintArrayEPKcjPSoReactionToSharding__quad_tenable_ZN9__gnu_cxx13new_allocatorIPN7testing8TestInfoEE10deallocateEPS3_j_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE14_M_upper_boundEPSt13_Rb_tree_nodeISsES8_RKSs_ZNSt3setIPKcSt4lessIS1_ESaIS1_EEaSERKS5_file_stat_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE8_M_beginEvgai_strerror__new_finishcopy_backwardtest_case_to_run_countFLAGS_gtest_show_internal_stack_framesnew_allocator_ZNSt6vectorIPN7testing8TestCaseESaIS2_EE6rbeginEvgtest_flag_saver__ZNSt6vectorISsSaISsEE7reserveEjoperator<< kPathSeparatorString_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE8_M_eraseEPSt13_Rb_tree_nodeISsEOnTestEndbitsRemoveTrailingPathSeparator~ScopedTracereverse_iteratoris_attribute_ZNKSt6vectorIiSaIiEE4rendEv_ZN9__gnu_cxx13new_allocatorISt13_Rb_tree_nodeISsEE7destroyEPS2__ZNKSt6vectorIPcSaIS0_EE12_M_check_lenEjPKcdistance__normal_iterator > >wcsncmp_ZNKSt18_Bit_iterator_baseleERKS__ZN9__gnu_cxx14__alloc_traitsISaIN7testing14TestPartResultEEE10deallocateERS3_PS2_j_ZNK7testing8internal8FilePath7IsEmptyEv__normal_iterator > >_ZNK9__gnu_cxx17__normal_iteratorIPPcSt6vectorIS1_SaIS1_EEEdeEv_ZNSt6vectorIPN7testing8TestInfoESaIS2_EE5frontEv_M_right_ZNKSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE4findERKS1___copy_move_a2_ZNK7testing8internal8FilePath27RemoveTrailingPathSeparatorEvbase_name_M_get_insert_hint_unique_pos_ZN7testing8internal15NoExecDeathTestD0Ev_ZN7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEED2Evtowctrans_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE8_M_beginEv_ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EE8_M_eraseEN9__gnu_cxx17__normal_iteratorIPS2_S4_EE_ZNSs2atEj__uninitialized_copy_afilenoRunTearDownTestCase_ZN7testing17TestEventListener13OnTestCaseEndERKNS_8TestCaseE_ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EE4swapERS4__ZN7testing8internal11CmpHelperLEEPKcS2_xxcharoperator- >_S_refcount__digits_ZNKSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE21_M_get_Node_allocatorEv__normal_iterator > >_ZNSbIwSt11char_traitsIwESaIwEE7replaceEN9__gnu_cxx17__normal_iteratorIPwS2_EES6_PKwj__is_normal_iteratorfixture_class_id_ZN7testing8internal27PrettyUnitTestResultPrinter27OnEnvironmentsTearDownStartERKNS_8UnitTestE_ZNSt6vectorIPN7testing8TestCaseESaIS2_EE5eraseEN9__gnu_cxx17__normal_iteratorIPS2_S4_EEvswprintf_Value_ZNSs4_Rep10_M_destroyERKSaIcE_ZN7testing4Test8TestBodyEvUniversalPrinterdetailexpr1expr2_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE28_M_get_insert_hint_equal_posESt23_Rb_tree_const_iteratorISsERKSs__uninit_copy_ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EE15_M_erase_at_endEPS2___are_samefixture_class_id__ZN7testing28FLAGS_gtest_break_on_failureEFLAGS_gtest_print_timeType_IsMove_ZN7testing8internal29PrintFullTestCommentIfPresentERKNS_8TestInfoEoperator<< __copy_move_backward_a__is_normal_iterator_ZNKSt6vectorIN7testing12TestPropertyESaIS1_EEixEjtest_info_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE23_M_get_insert_equal_posERKSs_ZNSt6vectorIiSaIiEE3endEvMutexBase_ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EE6resizeEjS2__ZN7testing14IsNotSubstringEPKcS1_RKSsS3_tv_usec_ZNKSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE3endEvHelpermemmoveFindLastPathSeparatorpair, std::_Rb_tree_iterator >_ZN9__gnu_cxx14__alloc_traitsISaIPN7testing11EnvironmentEEE10deallocateERS4_PS3_j_ZNSbIwSt11char_traitsIwESaIwEE4_Rep8_M_cloneERKS1_j_ZNSt6vectorIPN7testing8TestInfoESaIS2_EE4rendEvCOLOR_DEFAULT_ZNK7testing8internal12UnitTestImpl21reportable_test_countEvto_char_type_ZN9__gnu_cxx13new_allocatorIPN7testing8TestCaseEE7destroyEPS3_length_ZN7testing8internal13CaptureStderrEvwide_c_str_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE16_M_insert_equal_ESt23_Rb_tree_const_iteratorISsERKSs_ZN7testing8internal6String32CaseInsensitiveWideCStringEqualsEPKwS3_operator<<_M_set_leaked_ZNSt6vectorIiSaIiEE15_M_erase_at_endEPi_ZN7testing8internal11CmpHelperGTEPKcS2_xx_M_clonesigset_t_ZNK7testing14TestPartResult11line_numberEvcapacityoperator()<__gnu_cxx::__normal_iterator*, std::vector > > >_ZN7testing8internal26GoogleTestFailureExceptionD0Ev_ZNK9__gnu_cxx17__normal_iteratorIPKN7testing8internal9TraceInfoESt6vectorIS3_SaIS3_EEEmiEi_ZN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE11ValueHolderD2Evsetf_ZN7testing8TestCase19RunTearDownTestCaseEvFileOrDirectoryExists_ZNSbIwSt11char_traitsIwESaIwEE6appendEjw_ZN7testing8internal17TestEventRepeater11OnTestStartERKNS_8TestInfoEthis_fixture_id_ZNK9__gnu_cxx17__normal_iteratorIPKN7testing14TestPartResultESt6vectorIS2_SaIS2_EEEdeEv_ZNKSbIwSt11char_traitsIwESaIwEE11_M_disjunctEPKwsetwhas_tests_to_run_ZNK7testing8internal8FilePath21FindLastPathSeparatorEvsigemptyset_ZNSspLEPKcoperator==_ZNKSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE6_M_endEv_ZNSt16reverse_iteratorIN9__gnu_cxx17__normal_iteratorIPPN7testing11EnvironmentESt6vectorIS4_SaIS4_EEEEEmmEi_ZN9__gnu_cxx17__normal_iteratorIPPN7testing11EnvironmentESt6vectorIS3_SaIS3_EEEmIEiis_nan_ZNKSt12_Vector_baseIiSaIiEE19_M_get_Tp_allocatorEvvalue_compparent_ZN9__gnu_cxx17__normal_iteratorIPN7testing12TestPropertyESt6vectorIS2_SaIS2_EEEpLEi__first_ZN7testing24ValidateTestPropertyNameERKSsRKSt6vectorISsSaISsEECOLOR_RED__copy_move_backward_a2ExecDeathTestoperator<< _ZN7testing8internal17TestEventRepeater22set_forwarding_enabledEb_ZN7testing8internal13ExecDeathTestD2Ev__tmpkRepeatFlag_ZN7testing8internal12UnitTestImplD2Ev_ZNKSs6substrEjjhaystack_ZN7testing8internal12UnitTestImpl19current_test_resultEvkey_type_M_rootExtractSummarymbsrtowcsDefinedTestIter_S_beg_ZN7testing8internal24XmlUnitTestResultPrinter16PrintXmlUnitTestEPSoRKNS_8UnitTestE_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE21_M_insert_equal_lowerERKSsoperator>=number_ZNK7testing8internal12UnitTestImpl22failed_test_case_countEvvalue_str_ZNKSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE11__rb_verifyEvOtherOperand_ZN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE9CreateKeyEv_ZN7testing8internal13PrintStringToERKSsPSo_ZNKSt6vectorIPN7testing8TestInfoESaIS2_EE4dataEvWideCStringEquals_ZNSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE5frontEvkAlsoRunDisabledTestsFlagbasic_ostream_ZN9__gnu_cxx14__alloc_traitsISaISsEE8allocateERS1_j~UnitTestImpl_ZN9__gnu_cxx17__normal_iteratorIPiSt6vectorIiSaIiEEEppEi_S_construct_ZNSt10_Iter_baseIPiLb0EE7_S_baseES0_listeners_ZNK9__gnu_cxx17__normal_iteratorIPKN7testing14TestPartResultESt6vectorIS2_SaIS2_EEEixEi_ZN9__gnu_cxx17__normal_iteratorIPiSt6vectorIiSaIiEEEppEv_ZN7testing8internal11CmpHelperEQEPKcS2_xx_ZNSt6vectorISsSaISsEE5clearEv_ZNKSt3setIPKcSt4lessIS1_ESaIS1_EE11lower_boundERKS1__ZNSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE6rbeginEv_ZN7testing8internal29ParameterizedTestCaseRegistryD2Ev_ZNK9__gnu_cxx17__normal_iteratorIPKPN7testing8TestInfoESt6vectorIS3_SaIS3_EEEixEi__pid_tAbortReason_ConstructkReservedTestCaseAttributes_ZNK7testing8internal10scoped_ptrIKSsEptEv_ZNKSt6vectorISsSaISsEE4backEvint_frac_digits_ZNSt12_Vector_baseIPcSaIS0_EE11_M_allocateEj_ZNK7testing8UnitTest17current_test_caseEv_ZN9__gnu_cxx17__normal_iteratorIPPN7testing8internal29ParameterizedTestCaseInfoBaseESt6vectorIS4_SaIS4_EEEppEi_ZNSbIwSt11char_traitsIwESaIwEE7replaceEN9__gnu_cxx17__normal_iteratorIPwS2_EES6_PKw_ZNKSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE5emptyEv_ZNKSt17_Rb_tree_iteratorIPKcEptEv_ZN9__gnu_cxx17__normal_iteratorIPPN7testing8internal29ParameterizedTestCaseInfoBaseESt6vectorIS4_SaIS4_EEEppEv_ZNSt20__uninitialized_copyILb0EE13__uninit_copyIPN7testing14TestPartResultES4_EET0_T_S6_S5___is_normal_iterator_ZNK7testing8internal10scoped_ptrISt18basic_stringstreamIcSt11char_traitsIcESaIcEEEdeEv__copy_move_b_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE5eraseERKS1_vector >PrintCharAndCodeTo_ZNKSt6vectorIPN7testing11EnvironmentESaIS2_EE3endEv_ZN9__gnu_cxx13new_allocatorIcE7destroyEPcs1_expressionOutputXmlTestInfo_ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EE5clearEv_ZNSt8ios_base9precisionEi_ZN7testing8internal19UniversalPrintArrayEPKwjPSo_ZNSt6vectorIN7testing14TestPartResultESaIS1_EE4dataEv__uninitialized_move_if_noexcept_a >_M_iend_ZNK7testing8internal10scoped_ptrINS0_24InternalRunDeathTestFlagEE3getEvTearDownEnvironmentkDeathTestCaseFiltersi_tidnewline_anchorst_rdev__sigaction_handler_S_empty_rep_storage__copy_move_a2_ZN7testing8UnitTest3RunEviterator_traitsg_argvs_ZN9__gnu_cxx13new_allocatorIPcE7destroyEPS1__ZNSs6assignEPKcExecDeathTestChildMainlocaltime_ZNKSt6vectorIPN7testing11EnvironmentESaIS2_EE8capacityEv_ZNKSbIwSt11char_traitsIwESaIwEE7_M_dataEv_ZN7testing8internal14DeathTestAbortERKSs_ZN7testing8internal14CmpHelperSTRNEEPKcS2_S2_S2_value_param___pfnStreamableToStringold_reporter__ZNSs6resizeEjcTimeInMillis_ZN7testing32ScopedFakeTestPartResultReporterD2Ev_DestroykMaxUlpsmemcmp_ZN7testing8internal18PrintCharAndCodeToIhhEEvT0_PSoforwarding_enabled__M_check_len__is_normal_iterator_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE11lower_boundERKS1___rb_verify_ZN7testing28FLAGS_gtest_throw_on_failureE_S_bin~ScopedFakeTestPartResultReporterint_n_sep_by_space_ZNSt12_Destroy_auxILb0EE9__destroyIPN7testing8internal9TraceInfoEEEvT_S6__ZNKSt6vectorIPN7testing8TestCaseESaIS2_EE2atEj_IO_marker_ZNKSt6vectorIPN7testing11EnvironmentESaIS2_EE8max_sizeEv_ZNK7testing14ExitedWithCodeclEi_ZNK9__gnu_cxx17__normal_iteratorIPPN7testing11EnvironmentESt6vectorIS3_SaIS3_EEEdeEvtest_case_indices__ZN7testing8internal11g_help_flagE_FacetDeathTestOutcome_ZN7testing8internal10scoped_ptrISt18basic_stringstreamIcSt11char_traitsIcESaIcEEE5resetEPS6_print_time__ZNSt6vectorIN7testing14TestPartResultESaIS1_EE18_M_fill_initializeEjRKS1__ZNKSt6vectorIN7testing8internal9TraceInfoESaIS2_EE5beginEv_ZNSs6appendERKSsjjIsNotContainer_ZN7testing8internal10ParseInt32ERKNS_7MessageEPKcPiAssertHelperDataFLAGS_gtest_break_on_failure_Destroy_ZNK9__gnu_cxx13new_allocatorIPN7testing8internal29ParameterizedTestCaseInfoBaseEE7addressERS4__ZNSt12_Vector_baseIPN7testing17TestEventListenerESaIS2_EE12_Vector_impl12_M_swap_dataERS5_re_nsubGetAbsolutePathToOutputFilehas_new_fatal_failure_INTERCEPT_ONLY_CURRENT_THREADiterator_traits_ZNKSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE11lower_boundERKS1__ZNK9__gnu_cxx17__normal_iteratorIPPN7testing17TestEventListenerESt6vectorIS3_SaIS3_EEEdeEvDefaultPerThreadTestPartResultReporter_ZNSt6vectorIPN7testing8TestCaseESaIS2_EE4swapERS4_bytes_last_read_BI1_BI2_ZNKSt12_Vector_baseIN7testing14TestPartResultESaIS1_EE19_M_get_Tp_allocatorEvptr__ZN7testing8UnitTest9listenersEv_ZNK9__gnu_cxx17__normal_iteratorIPPN7testing11EnvironmentESt6vectorIS3_SaIS3_EEE4baseEvai_socktype__is_move_iterator_ZN9__gnu_cxx17__normal_iteratorIPKPN7testing11EnvironmentESt6vectorIS3_SaIS3_EEEppEiPrintFullTestCommentIfPresentwctrans_S_truncscoped_ptr, std::allocator > >_ZN9__gnu_cxx17__normal_iteratorIPKPN7testing11EnvironmentESt6vectorIS3_SaIS3_EEEppEv_ZNKSs7compareEPKc__pad4_ZNKSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE5beginEvset_elapsed_time_ZNK9__gnu_cxx17__normal_iteratorIPPN7testing11EnvironmentESt6vectorIS3_SaIS3_EEEixEi_S_ios_iostate_end_ZN7testing8internal17GetCapturedStderrEvFLAGS_gtest_coloroperator<< ~new_allocator~ThreadLocal_ZN7testing8internal8FilePath22GenerateUniqueFileNameERKS1_S3_PKcwidth_ZNSbIwSt11char_traitsIwESaIwEE4_Rep12_S_empty_repEvreverse_iterator<__gnu_cxx::__normal_iterator > > >_ZN9__gnu_cxx13new_allocatorIwE7destroyEPw_ZNKSt6vectorISsSaISsEE4sizeEv__uninitialized_move_if_noexcept_a >_ZNKSt12_Vector_baseIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE13get_allocatorEvoperator<< strtoll~UnitTestReadReportFailureInUnknownLocation_ZN7testing8internal12UnitTestImpl28CurrentOsStackTraceExceptTopEi__baseInt32FromGTestEnv_ZNK9__gnu_cxx17__normal_iteratorIPKPN7testing8TestCaseESt6vectorIS3_SaIS3_EEEdeEv__is_move_iterator<__gnu_cxx::__normal_iterator > > >user_msgerrnum_ZNK9__gnu_cxx17__normal_iteratorIPPN7testing17TestEventListenerESt6vectorIS3_SaIS3_EEEixEi__copy_move_backward_a2emptyinstance_ZN7testing8internal29ParameterizedTestCaseRegistryaSERKS1_val1_ss__copy_move_b__end_ZN9__gnu_cxx14__alloc_traitsISaIPKcEE10deallocateERS3_PS2_jobject_ZN7testing8internal14CapturedStream11GetFileSizeEP8_IO_FILE_ZN7testing18FLAGS_gtest_repeatE_ZNK9__gnu_cxx17__normal_iteratorIPPN7testing8internal29ParameterizedTestCaseInfoBaseESt6vectorIS4_SaIS4_EEEdeEv__mbstate_t_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE10_S_maximumEPKSt18_Rb_tree_node_baseDeleteSelf___normal_iterator > >_ZNSbIwSt11char_traitsIwESaIwEE7replaceEN9__gnu_cxx17__normal_iteratorIPwS2_EES6_S6_S6_tz_minuteswestkDefaultOutputFile_M_valptr_ZNSt6vectorIN7testing12TestPropertyESaIS1_EE18_M_fill_initializeEjRKS1__ZN7testing8internal17TestEventRepeaterD0Ev_ZNKSt23_Rb_tree_const_iteratorIPKcE13_M_const_castEv_ZNSt16reverse_iteratorIN9__gnu_cxx17__normal_iteratorIPPN7testing11EnvironmentESt6vectorIS4_SaIS4_EEEEEpLEitype_param_S_internal_ZN7testing8internal10scoped_ptrISsE7releaseEv_ZNK9__gnu_cxx17__normal_iteratorIPN7testing8internal9TraceInfoESt6vectorIS3_SaIS3_EEEdeEvconst_referenceOnEnvironmentsTearDownStart__uninit_copy_ZN9__gnu_cxx14__alloc_traitsISaIPN7testing17TestEventListenerEEE10_S_on_swapERS4_S6__ZNK9__gnu_cxx13new_allocatorIN7testing12TestPropertyEE7addressERKS2_output_dir_ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EE3endEvset_last_death_test_message_ZNKSt3setIPKcSt4lessIS1_ESaIS1_EE5beginEv_ZN7testing16AssertionSuccessEvport_num_COLOR_YELLOWrebindreverse_iterator<__gnu_cxx::__normal_iterator > > >_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE4findERKSsreservedeath_test_index_ZN9__gnu_cxx17__normal_iteratorIPN7testing8internal9TraceInfoESt6vectorIS3_SaIS3_EEEppEi_ZNK9__gnu_cxx17__normal_iteratorIPKPN7testing8TestCaseESt6vectorIS3_SaIS3_EEEixEi_M_disjunct_ZNKSbIwSt11char_traitsIwESaIwEE12find_last_ofEwj_M_leak_ZNSs7_M_leakEv~Arguments_ZN9__gnu_cxx17__normal_iteratorIPN7testing8internal9TraceInfoESt6vectorIS3_SaIS3_EEEppEv_ZNSt6vectorIiSaIiEE6insertEN9__gnu_cxx17__normal_iteratorIPiS1_EERKierrors_str__is_move_iteratorfloatfieldg_executable_path_ZNKSt12_Vector_baseIPN7testing17TestEventListenerESaIS2_EE13get_allocatorEvForEach, void (*)(testing::TestInfo*)>_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE15_M_insert_equalERKSsrm_so_ZNSt6vectorIPcSaIS0_EE4swapERS2_elapsedfclose_ZN7testing8internal8FilePath11ConcatPathsERKS1_S3__S_unitbuf_ZNK9__gnu_cxx17__normal_iteratorIPPN7testing8internal29ParameterizedTestCaseInfoBaseESt6vectorIS4_SaIS4_EEEixEi_ZNKSt4lessIPKcEclERKS1_S4_kHexEscapeFLAGS_gtest_internal_run_death_testAssertionSuccessright_ZNKSbIwSt11char_traitsIwESaIwEEixEj_ZNSt6vectorIPcSaIS0_EE6insertEN9__gnu_cxx17__normal_iteratorIPS0_S2_EEjRKS0__ZNKSs2atEj_ZN7testing8internal10scoped_ptrINS0_24InternalRunDeathTestFlagEE7releaseEv_ZNK7testing8internal13FloatingPointIdE4bitsEv_ZNKSbIwSt11char_traitsIwESaIwEE6_M_repEvallocatorline__ZNKSt6vectorIN7testing14TestPartResultESaIS1_EE5emptyEvoperator< , std::allocator >_ZN9__gnu_cxx14__alloc_traitsISaISt13_Rb_tree_nodeISsEEE17_S_select_on_copyERKS3__ZNK9__gnu_cxx17__normal_iteratorIPN7testing8internal9TraceInfoESt6vectorIS3_SaIS3_EEEixEioriginal_dir_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEED2Ev_ZN7testing8internal7PrintToEwPSo_ZNSbIwSt11char_traitsIwESaIwEE6rbeginEv_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE15_M_insert_lowerEPSt18_Rb_tree_node_baseRKSsMessage_M_parent_ZNKSt6vectorIPN7testing8TestInfoESaIS2_EE5beginEv_ZNKSbIwSt11char_traitsIwESaIwEE6rbeginEv6ldiv_t_ZNKSt17_Rb_tree_iteratorIPKcEeqERKS2_EmptyTestEventListener_Destroyaddrinfoiterator_ZNKSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE14_M_lower_boundEPKSt13_Rb_tree_nodeISsES9_RKSsmemset_ZNK9__gnu_cxx13new_allocatorIPN7testing8internal29ParameterizedTestCaseInfoBaseEE8max_sizeEv_M_length_ZN7testing8internal11CmpHelperGEEPKcS2_xxchar_traitsFLAGS_gtest_random_seed_ZN9__gnu_cxx14__alloc_traitsISaIN7testing12TestPropertyEEE10deallocateERS3_PS2_jfactoryregex__Setfill_ZNKSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE4backEvreverse_iterator >pthread_mutex_init_ZNKSs9_M_ibeginEv_ZN7testing8internal6String28CaseInsensitiveCStringEqualsEPKcS3_insert_ZN7testing8internal17TestEventRepeater13OnTestCaseEndERKNS_8TestCaseE__miter_baseTypeWithSize<4u>_ZNSt12_Vector_baseISsSaISsEE19_M_get_Tp_allocatorEv_ZNSt3setIPKcSt4lessIS1_ESaIS1_EE6insertERKS1__ZN7testinglsERSoRKNS_14TestPartResultEHasOneFailureCmpHelperSTREQ_ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EE8pop_backEvdefined_test_names__ZNK7testing10TestResult15test_propertiesEvCmpHelperSTRCASENE_ZN7testing8UnitTestD2Ev_ZNSt11char_traitsIwE2ltERKwS2__ZN7testing18FLAGS_gtest_outputE_Iter_equals_valexit_code__ZNSt6vectorIiSaIiEE7reserveEj_ZN9__gnu_cxx17__normal_iteratorIPKN7testing14TestPartResultESt6vectorIS2_SaIS2_EEEppEi_Ios_SeekdirListTestsMatchingFilter_ZNSt6vectorIN7testing14TestPartResultESaIS1_EE6insertEN9__gnu_cxx17__normal_iteratorIPS1_S3_EERKS1_rebind, std::allocator > >_ZN7testing8internal37FormatCompilerIndependentFileLocationEPKci_ZN9__gnu_cxx17__normal_iteratorIPKN7testing14TestPartResultESt6vectorIS2_SaIS2_EEEppEvGenerateUniqueFileName_ZNKSt6vectorISsSaISsEE2atEjchar_traitskMaxBiggestInt__builtin_puts_ZN7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEE11ValueHolder7pointerEvoutput_name__addressoffile_size_ZNSt8ios_base5widthEi_ZN7testing8internal12UnitTestImpl23ClearNonAdHocTestResultEv_ZNSt6vectorIPN7testing8TestInfoESaIS2_EE14_M_fill_insertEN9__gnu_cxx17__normal_iteratorIPS2_S4_EEjRKS2___alloc_traits >GetThreadCount_ZN7testing8UnitTest14RecordPropertyERKSsS2_~GTestMutexLock_M_dataplusallocator__uninitialized_move_if_noexcept_a >_ZNSt6vectorIN7testing12TestPropertyESaIS1_EE7reserveEj~basic_ostreamequal_range_ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EE6insertEN9__gnu_cxx17__normal_iteratorIPS2_S4_EERKS2_plural_form_M_predinternal_ZN9__gnu_cxx14__alloc_traitsISaIPN7testing11EnvironmentEEE10_S_on_swapERS4_S6__ZNK7testing8internal12UnitTestImpl11GetTestCaseEi_M_left__builtin_putcharnothrow_t__destroyTestEventRepeater__builtin_fputsnew_test_case_ZNK9__gnu_cxx13new_allocatorIPN7testing17TestEventListenerEE8max_sizeEv_ZNKSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EEixEjkDeathTestLivedparameterized_tests_registered_ldiv_t_ZNKSs13find_first_ofEPKcjForEach, void (*)(testing::TestCase*)>_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE5eraseESt23_Rb_tree_const_iteratorISsE_ZNSs18_S_construct_aux_2EjcRKSaIcE_ZN7testing10TestResult20ValidateTestPropertyERKSsRKNS_12TestPropertyE_Vector_base >INTERCEPT_ALL_THREADSva_listinfoline_number_ZN7testing8TestInfoC2ERKSsS2_PKcS4_PKvPNS_8internal15TestFactoryBaseEShouldRunTestOnShard_S_synced_with_stdioInt32FromEnvOrDieIsEmptyTestFailedpositive_sign_ZN9__gnu_cxx13new_allocatorIcE9constructEPcRKcshard_index_env__lockmkstempKilledBySignal__in_chrg_ZN7testing8internal27PrettyUnitTestResultPrinterD0Evclone_ZNSbIwSt11char_traitsIwESaIwEE6appendERKS2__ZNSt11char_traitsIwE11to_int_typeERKw__normal_iterator, std::allocator > >_ZNKSt6vectorIN7testing8internal9TraceInfoESaIS2_EE14_M_range_checkEj_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE8_M_eraseEPSt13_Rb_tree_nodeIS1_Estatement__ZN7testing8internal13ExecDeathTest10AssumeRoleEv__builtin_strchr_ZN9__gnu_cxx14__alloc_traitsISaIPcEE17_S_select_on_copyERKS2_kFatalFailuretest_idMSG_CMSG_CLOEXEC_ZNK9__gnu_cxx17__normal_iteratorIPSsSt6vectorISsSaISsEEEdeEvGetEnvchild_pid___miter_basescoped_ptr_ZNSt12_Vector_baseIiSaIiEE19_M_get_Tp_allocatorEv~AssertionResultRegisterTests_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE29_M_get_insert_hint_unique_posESt23_Rb_tree_const_iteratorIS1_ERKS1__ZNSt6vectorIPN7testing11EnvironmentESaIS2_EE6insertEN9__gnu_cxx17__normal_iteratorIPS2_S4_EEjRKS2__ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EE5eraseEN9__gnu_cxx17__normal_iteratorIPS2_S4_EE_ZNK7testing8TestCase12elapsed_timeEv_ZNSs5clearEvSetUpEnvironmentin_color_moderange_ZNK9__gnu_cxx13new_allocatorIN7testing14TestPartResultEE8max_sizeEv_M_lower_bound_ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EE8_M_eraseEN9__gnu_cxx17__normal_iteratorIPS2_S4_EE__ptrContainer_ZNKSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE4sizeEvStreamingListener_ZN7testing8internal17TestEventRepeater6AppendEPNS_17TestEventListenerECreateKey__copy_move_b_ZN7testing8internal12UnitTestImplC2EPNS_8UnitTestEoperator<< _ZNSt3setISsSt4lessISsESaISsEE11equal_rangeERKSs_ZNSt6vectorIN7testing12TestPropertyESaIS1_EEixEj_ZNKSt6vectorISsSaISsEE5frontEv_ZNSt12_Vector_baseIPN7testing11EnvironmentESaIS2_EE17_M_create_storageEj_ZN7testing8internal13FloatingPointIdE24SignAndMagnitudeToBiasedERKyxmloutThreadLocal > >_ZN7testing8internal17Int32FromGTestEnvEPKci_ZNKSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE14_M_upper_boundEPKSt13_Rb_tree_nodeIS1_ESB_RKS1__Predicateiterationvector >_ZN7testing8internal35HandleExceptionsInMethodIfSupportedINS_4TestEvEET0_PT_MS4_FS3_vEPKc_ZNK7testing8internal10scoped_ptrINS0_17StreamingListener20AbstractSocketWriterEE3getEv_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE5eraseESt17_Rb_tree_iteratorIS1_E_ZN7testing15AssertionResultC2ERKS0__ZNSbIwSt11char_traitsIwESaIwEE5eraseEN9__gnu_cxx17__normal_iteratorIPwS2_EES6_string_value__c1__c2__alloc_traits >_ZNKSt6vectorIPN7testing8TestInfoESaIS2_EE14_M_range_checkEj_ZNK9__gnu_cxx17__normal_iteratorIPSsSt6vectorISsSaISsEEEixEi_ZN9__gnu_cxx14__alloc_traitsISaIPN7testing8TestCaseEEE8max_sizeERKS4__ZN9__gnu_cxx14__alloc_traitsISaISt13_Rb_tree_nodeISsEEE8max_sizeERKS3__M_finishactual_predicate_valuewcstof_ZN7testing8internal17StreamingListener13OnTestCaseEndERKNS_8TestCaseE_ZNK7testing8internal12UnitTestImpl17current_test_caseEvwcstokwcstol_ZNKSs16find_last_not_ofERKSsj_ZNKSbIwSt11char_traitsIwESaIwEE6lengthEv_ZN9__gnu_cxx13new_allocatorIPKcE9constructEPS2_RKS2_operator== >iterator_typeInitDeathTestSubprocessControlInfo_S_failbit__normal_iterator__ch_ZN7testing8internal23DefaultDeathTestFactory6CreateEPKcPKNS0_2REES3_iPPNS0_9DeathTestE_vptr.DeathTest_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE14_M_create_nodeERKS1__ZN7testing29FLAGS_gtest_stack_trace_depthESOCK_SEQPACKETGetElementOrtest_to_run_count_ZN9__gnu_cxx14__alloc_traitsISaIPN7testing8TestCaseEEE10deallocateERS4_PS3_j_ZN7testing8internal35DefaultGlobalTestPartResultReporteraSERKS1__ZN7testing13PrintToStringIPKcEESsRKT___int32_t__normal_iterator > >kMaxStackAlignment_ZN9__gnu_cxx13new_allocatorISt13_Rb_tree_nodeIPKcEE7destroyEPS4_operator<< UnshuffleTests_ZNSt6vectorIN7testing14TestPartResultESaIS1_EE9push_backERKS1__ZNK7testing8internal12UnitTestImpl17gtest_trace_stackEvpthread_key_deletest_mtimuncaptured_fd__ZN7testing8internal17StreamingListener20AbstractSocketWriter6SendLnERKSs_ZNSt6vectorISsSaISsEEixEjtm_zone_Bit_type_ZN7testing8UnitTestaSERKS0__ZNKSt12_Vector_baseISsSaISsEE13get_allocatorEv_ZNSt6vectorIPN7testing11EnvironmentESaIS2_EE5beginEv_ZNSt12_Vector_baseIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE19_M_get_Tp_allocatorEv_ZNSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE4backEv_ZNSs5eraseEN9__gnu_cxx17__normal_iteratorIPcSsEE__distance_ZN7testing8internal9Arguments11AddArgumentEPKcclose_ZNSt6vectorIPcSaIS0_EE6resizeEjS0__ZNKSt12_Vector_baseIN7testing8internal9TraceInfoESaIS2_EE13get_allocatorEvfunctorVerifyRegisteredTestNamesFormatCountableNounPrintBytesInObjectTo_ZN7testing15AssertionResultlsIA7_cEERS0_RKT_PrintCharAndCodeTo_ZNSt6vectorIPN7testing11EnvironmentESaIS2_EE6resizeEjS2__ZN7testing8internal11CmpHelperLTEPKcS2_xx__is_move_iteratorbinary_ZNK7testing8TestInfo10should_runEv_ZN7testing8internal11ScopedTraceaSERKS1_rebindEscapeXmlFormatIntWidth2_ZNK9__gnu_cxx17__normal_iteratorIPKN7testing8internal9TraceInfoESt6vectorIS3_SaIS3_EEEptEvallocator_ZNSt12_Vector_baseIN7testing12TestPropertyESaIS1_EE17_M_create_storageEj__uninitialized_copy_a_ZNKSt6vectorIN7testing14TestPartResultESaIS1_EE4backEv_Rb_tree_node, std::allocator > >_ZNSt12_Vector_baseIN7testing14TestPartResultESaIS1_EE13_M_deallocateEPS1_jcopy_backwardStatStruct__pthread_mutex_sGetInstance_S_construct_aux_2skip_count_ZN7testing8internal25ReportInvalidTestCaseTypeEPKcS2_ifile_name__ZNK7testing10TestResult16total_part_countEvsa_familyFLAGS_gtest_filter_ZNSt6vectorIPcSaIS0_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS0_S2_EERKS0_shard_index_ZNSt6vectorIN7testing14TestPartResultESaIS1_EE5beginEv_ZN9__gnu_cxx17__normal_iteratorIPN7testing12TestPropertyESt6vectorIS2_SaIS2_EEEmIEi__dso_handle_ZN7testing8internal18CmpHelperSTRCASEEQEPKcS2_S2_S2__ZNK9__gnu_cxx17__normal_iteratorIPKPN7testing11EnvironmentESt6vectorIS3_SaIS3_EEEplEi_ZN7testing8internal17TestEventRepeater16OnTestProgramEndERKNS_8UnitTestEtime_t_Alloc_hider_ZNSs10_S_compareEjj_ZNK9__gnu_cxx17__normal_iteratorIPiSt6vectorIiSaIiEEEmiEi_ZNSt6vectorIPN7testing11EnvironmentESaIS2_EE5eraseEN9__gnu_cxx17__normal_iteratorIPS2_S4_EE_ZNSt6vectorIN7testing12TestPropertyESaIS1_EE8_M_eraseEN9__gnu_cxx17__normal_iteratorIPS1_S3_EES7_a_current_test_case_ZNSt6vectorIN7testing14TestPartResultESaIS1_EE4swapERS3_for_each<__gnu_cxx::__normal_iterator >, void (*)(testing::TestCase*)>_ZNKSt12_Vector_baseIPN7testing8TestInfoESaIS2_EE19_M_get_Tp_allocatorEv_ZNSt6vectorIPN7testing8TestCaseESaIS2_EE15_M_erase_at_endEPS2__ZNK7testing8TestCase14test_info_listEvRemoveInvalidXmlCharactersnew_allocator >_ZNKSt13_Bit_iterator13_M_const_castEv_ZNSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE14_M_fill_assignEjRKS3__ZN7testing32ScopedFakeTestPartResultReporteraSERKS0_ForEach, void (*)(testing::TestEventListener*)>_ZNKSt6vectorIPN7testing17TestEventListenerESaIS2_EE14_M_range_checkEj_ZNSt12_Vector_baseISsSaISsEE17_M_create_storageEj_ZNKSs17find_first_not_ofERKSsj_ZN9__gnu_cxx13new_allocatorISsE7destroyEPSs7lldiv_tregs_allocated_ZN9__gnu_cxx17__normal_iteratorIPiSt6vectorIiSaIiEEEmmEi_ZN7testing18TestEventListeners23SetDefaultResultPrinterEPNS_17TestEventListenerErandom_access_iterator_tag_M_offset_ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EE4dataEv_ZN9__gnu_cxx17__normal_iteratorIPiSt6vectorIiSaIiEEEmmEvuninitialized_copy_ZNK7testing8TestInfo10type_paramEvint_p_cs_precedes_ZN7testing8internal18PrintCharAndCodeToIwwEEvT0_PSo_ZNKSt6vectorIPN7testing8TestCaseESaIS2_EE6rbeginEv__uninitialized_copy_a<__gnu_cxx::__normal_iterator >, testing::internal::TraceInfo*, testing::internal::TraceInfo>bsearch_ZNKSt6vectorIPN7testing8TestCaseESaIS2_EE14_M_range_checkEjshould_shard_ZNKSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE12_M_check_lenEjPKc_ZNK9__gnu_cxx17__normal_iteratorIPKSsSt6vectorISsSaISsEEEplEimon_grouping_M_deallocate_Node_allocator_ZN9__gnu_cxx17__normal_iteratorIPPN7testing8internal29ParameterizedTestCaseInfoBaseESt6vectorIS4_SaIS4_EEEmmEiParseGoogleTestFlagsOnlyImpl_ZNKSs4rendEv_ZNKSbIwSt11char_traitsIwESaIwEE5rfindEwj_ZN9__gnu_cxx17__normal_iteratorIPPN7testing8internal29ParameterizedTestCaseInfoBaseESt6vectorIS4_SaIS4_EEEmmEv_ZNSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE5eraseEN9__gnu_cxx17__normal_iteratorIPS3_S5_EETestCasePassed_offset_ZN7testing28FLAGS_gtest_death_test_styleE_M_replace_safe_ZNK7testing8internal12UnitTestImpl22test_case_to_run_countEvGetCapturedStdout__numeric_traits_integer_ZN7testing8internal24HasNewFatalFailureHelperD2Ev_ZNSbIwSt11char_traitsIwESaIwEE6insertEN9__gnu_cxx17__normal_iteratorIPwS2_EEjw_M_beginbasic_istream >_ZN7testing8internal38DefaultPerThreadTestPartResultReporteraSERKS1___kindlow_byte_Destroy >_old_offsetfile_namembstowcs_ZNSt6vectorIN7testing14TestPartResultESaIS1_EE15_M_erase_at_endEPS1__ZNSt6vectorIPN7testing11EnvironmentESaIS2_EE4rendEv_ZNKSt12_Vector_baseIPN7testing11EnvironmentESaIS2_EE13get_allocatorEvrepeat_ZN9__gnu_cxx14__alloc_traitsISaIN7testing8internal9TraceInfoEEE8max_sizeERKS4__ZNSs7replaceEjjPKcFormatBooloperator<< basic_ios >_ZNKSt6vectorIN7testing8internal9TraceInfoESaIS2_EE3endEvuninitialized_copy~basic_streambuf_ZN9__gnu_cxx14__alloc_traitsISaIPKcEE7destroyERS3_PS2__ZNKSt18_Bit_iterator_baseeqERKS__cur_column_ZN7testing4Test18HasNonfatalFailureEvGetArgvsForDeathTestChildProcessoperator<< spawnedthrow_on_failure_ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EE3endEvFormatEpochTimeInMillisAsIso8601_ZNKSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE11_M_leftmostEv_ZNSt11char_traitsIcE6lengthEPKcFormatTestCount_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE23_M_get_insert_equal_posERKS1__ZN7testing8internal7PrintToEaPSo_S_construct_auxOnTestProgramEndreverse_iterator<__gnu_cxx::__normal_iterator > > >_M_value_ZNKSt6vectorIN7testing14TestPartResultESaIS1_EE4sizeEvpthread_self_ZN7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEE11ValueHolderD0Evsizelist_tests~_Rb_tree_implextension_Tp1ShouldRunTestCase_ZNK7testing10TestResult16death_test_countEv__pred_iter_ZN9__gnu_cxx14__alloc_traitsISaIN7testing14TestPartResultEEE17_S_select_on_copyERKS3__ZNK7testing8internal24InternalRunDeathTestFlag4fileEv__copy_move_b_ZNSbIwSt11char_traitsIwESaIwEE12_M_leak_hardEv__destroyset_spawned_ZNKSt6vectorIPN7testing17TestEventListenerESaIS2_EE5emptyEv_ZNSt6vectorIPN7testing8TestCaseESaIS2_EE8pop_backEv__copy_move_a2exitGTEST_INFOtime_structFileNo_ZN7testing8internal14CapturedStreamaSERKS1_key_compDefaultPrintNonContainerTo_ZN9__gnu_cxx14__alloc_traitsISaIPN7testing8internal29ParameterizedTestCaseInfoBaseEEE8max_sizeERKS5__ZNSt6vectorIiSaIiEE8pop_backEv_ZN9__gnu_cxx24__numeric_traits_integerImE8__digitsE_ZNSt6vectorIiSaIiEE4backEvcopyvalue_messageGTEST_FATAL_ZNKSs4_Rep12_M_is_leakedEv_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE11lower_boundERKSs_ZN7testing8TestCase10TestFailedEPKNS_8TestInfoEoperator[]_ZN7testing8internal24XmlUnitTestResultPrinter19IsValidXmlCharacterEc_ZNSt6vectorIPN7testing11EnvironmentESaIS2_EE4swapERS4__ZN7testing10TestResult5ClearEv_ZN9__gnu_cxx17__normal_iteratorIPKPN7testing11EnvironmentESt6vectorIS3_SaIS3_EEEmmEi_ZNK9__gnu_cxx13new_allocatorIPKcE7addressERKS2_strncmp_ZNKSs16find_last_not_ofEPKcjj__n2_ZN9__gnu_cxx17__normal_iteratorIPKPN7testing11EnvironmentESt6vectorIS3_SaIS3_EEEmmEvp_cs_precedeswint_t_ZNK7testing8internal24InternalRunDeathTestFlag8write_fdEv__cxa_guard_releasePrintCharsAsStringTo_ZNSt6vectorIN7testing12TestPropertyESaIS1_EE5eraseEN9__gnu_cxx17__normal_iteratorIPS1_S3_EES7__ZN7testing8internal27PrettyUnitTestResultPrinter25OnEnvironmentsTearDownEndERKNS_8UnitTestE_ZNSt12_Vector_baseIiSaIiEE12_Vector_impl12_M_swap_dataERS2_mblen__blkcnt_t__are_samebasic_iosGetBoolAssertionFailureMessage_ZN7testing8internal23DefaultDeathTestFactoryD2Evoperator<< decimal_pointkey_compareIsDirconnect_S_select_on_copy_ZNKSbIwSt11char_traitsIwESaIwEE8capacityEv_ZN7testing28FLAGS_gtest_catch_exceptionsE__uninitialized_copy_a_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE11_M_get_nodeEv_ZNSt6vectorIPN7testing8TestInfoESaIS2_EE4dataEv_ZN7testing8internal11ScopedTraceC2EPKciRKNS_7MessageE__nlink_tUniversalPrintexpected_value_ZN7testing8internal27PrettyUnitTestResultPrinter13OnTestCaseEndERKNS_8TestCaseE_ZNKSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE4sizeEv_ZN9__gnu_cxx14__alloc_traitsISaIN7testing12TestPropertyEEE7destroyERS3_PS2__S_ios_fmtflags_end_ZNKSbIwSt11char_traitsIwESaIwEE4findERKS2_jAssertionFailure_ZNSt6vectorIiSaIiEE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPiS1_EERKi_M_c__niter_base_ZNSt12_Vector_baseIPN7testing8TestInfoESaIS2_EE12_Vector_impl12_M_swap_dataERS5__ZNSt16reverse_iteratorIN9__gnu_cxx17__normal_iteratorIPPN7testing11EnvironmentESt6vectorIS4_SaIS4_EEEEEmIEi~scoped_ptr_M_n_M_p_ZNSt10_Iter_baseIPN7testing12TestPropertyELb0EE7_S_baseES2__M_t_ZNKSbIwSt11char_traitsIwESaIwEE8max_sizeEv_ZNKSt6vectorISsSaISsEEixEjMakeFileName_ZNKSt5ctypeIcE5widenEc_M_set_length_and_sharable_ZNSbIwSt11char_traitsIwESaIwEE7replaceEN9__gnu_cxx17__normal_iteratorIPwS2_EES6_NS4_IPKwS2_EES9___next_Rb_tree_const_iterator~_Vector_base_ZNKSbIwSt11char_traitsIwESaIwEE5beginEv__pfa_line_ZNSt11char_traitsIwE6lengthEPKw_ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EE6insertEN9__gnu_cxx17__normal_iteratorIPS2_S4_EEjRKS2__ZNKSt3setISsSt4lessISsESaISsEE8max_sizeEv_ZN7testing8TestCase14set_should_runEb_ZN9__gnu_cxx17__normal_iteratorIPN7testing8internal9TraceInfoESt6vectorIS3_SaIS3_EEEmmEi_ZN9__gnu_cxx17__normal_iteratorIPN7testing8internal9TraceInfoESt6vectorIS3_SaIS3_EEEmmEvdisabled_test_count_M_dataintercept_mode~TestCase_ZNKSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE8capacityEvexpected_predicate_value_IO_buf_endshort unsigned int_ZN9__gnu_cxx17__normal_iteratorIPiSt6vectorIiSaIiEEEpLEi_IO_backup_base_ZNSs6appendEPKcj_ZNSs12_S_constructIPcEES0_T_S1_RKSaIcESt20forward_iterator_tagTestPartFatallyFailed_ZN7testing11Environment8TearDownEv_ZNK7testing8internal10scoped_ptrISsE3getEv_ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EE8_M_eraseEN9__gnu_cxx17__normal_iteratorIPS2_S4_EES8_key_reportable_disabled_test_count_M_create_storageconstruct_ZNSt6vectorIPN7testing8TestInfoESaIS2_EE5beginEv__copy_move_a2_ZN7testing8internal6String23EndsWithCaseInsensitiveERKSsS3__ZN9__gnu_cxx13new_allocatorIPN7testing17TestEventListenerEE9constructEPS3_RKS3_iterator_traits_ZN9__gnu_cxx17__normal_iteratorIPPN7testing8internal29ParameterizedTestCaseInfoBaseESt6vectorIS4_SaIS4_EEEpLEi_ZNKSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE8max_sizeEv_ZN7testing8internal13CaptureStdoutEv__normal_iterator > >StringFromGTestEnv__s2_M_insert_equal__ZNKSs17find_first_not_ofEPKcjj_S_ios_seekdir_end_ZN7testing8internal35FLAGS_gtest_internal_run_death_testE_M_disposeGetCurrentOsStackTraceExceptTopreverse_iterator<__gnu_cxx::__normal_iterator, std::allocator >*, std::vector, std::allocator >, std::allocator, std::allocator > > > > >ios_base__copy_move_backward_a2_ZNSt17_Rb_tree_iteratorISsEppEv_shortbuf_ZN9__gnu_cxx14__alloc_traitsISaIPN7testing17TestEventListenerEEE8allocateERS4_j_ZNSt6vectorIPN7testing11EnvironmentESaIS2_EEaSERKS4_kDisableTestFilter_S_goodbitn_sep_by_space_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE14_M_create_nodeERKSs_M_insert_timespecAssertHelper_ZNKSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE5countERKS1__ZNSt12_Vector_baseIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE12_Vector_impl12_M_swap_dataERS6__ZN9__gnu_cxx14__alloc_traitsISaIPN7testing17TestEventListenerEEE10deallocateERS4_PS3_j_ZNKSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE4sizeEvTypeWithSize<8u>kTestsuites_vptr.TestPartResultReporterInterface_ZNSt6vectorIN7testing14TestPartResultESaIS1_EE8_M_eraseEN9__gnu_cxx17__normal_iteratorIPS1_S3_EES7__ZNK9__gnu_cxx13new_allocatorISt13_Rb_tree_nodeISsEE7addressERS2_this_test_name_Destroy*>_ZNSt6vectorIiSaIiEE5eraseEN9__gnu_cxx17__normal_iteratorIPiS1_EES5__ZNSt6vectorIN7testing12TestPropertyESaIS1_EE14_M_fill_assignEjRKS1_ChopLowBits_ZN7testing8internal13ColoredPrintfENS0_10GTestColorEPKczFDOpenIsNormalizableWhitespaceelapsed_timeParseNaturalNumber_ZNKSbIwSt11char_traitsIwESaIwEE4findEPKwjjTEST_THREW_EXCEPTION_ZNSt6vectorIN7testing14TestPartResultESaIS1_EEaSERKS3_FormatCxxExceptionMessage_ZN7testing8internal24XmlUnitTestResultPrinter13EscapeXmlTextEPKcnegative_signoperator delete []__miter_basebegin_string_quoteoperator!= >__copy_move_a2showpointtermdouble_ZNK7testing8UnitTest17current_test_infoEvlock__destroy_ZN7testing18TestEventListeners7ReleaseEPNS_17TestEventListenerE_ZNK9__gnu_cxx13new_allocatorIPN7testing8TestInfoEE7addressERS3__ZN7testing22EmptyTestEventListener27OnEnvironmentsTearDownStartERKNS_8UnitTestEkProtobufOneLinerMaxLength_ZN9__gnu_cxx17__normal_iteratorIPN7testing12TestPropertyESt6vectorIS2_SaIS2_EEEmmEiset_statusresult__ZN7testing8internal13FloatingPointIdE8InfinityEvCmpHelperEQallowed_names_ZN9__gnu_cxx14__alloc_traitsISaIPN7testing17TestEventListenerEEE7destroyERS4_PS3__ZNK7testing14KilledBySignalclEi_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE5beginEvresults_ZNK9__gnu_cxx17__normal_iteratorIPKPN7testing17TestEventListenerESt6vectorIS3_SaIS3_EEEmiEioperator<< _ZNK7testing15AssertionResult15failure_messageEvuse_forklesselement_namefatally_failedallocatorStringStreamToStringFailed_ZN7testing8internal29ParseInternalRunDeathTestFlagEvGeneratecopy_ZNK9__gnu_cxx13new_allocatorIN7testing12TestPropertyEE8max_sizeEvpassed_ZN7testing8internal17TestEventRepeater9OnTestEndERKNS_8TestInfoE_ZNKSt13_Bit_iteratordeEv_ZN7testing8internal20SingleFailureCheckerD2Evtuple<>case_listcondition_ZN7testing8internal10scoped_ptrISsE5resetEPSs_ZN7testing8internal5MutexD2Ev~vector_ZN9__gnu_cxx14__alloc_traitsISaIPN7testing8internal29ParameterizedTestCaseInfoBaseEEE7destroyERS5_PS4__ZNSt6vectorIPN7testing8TestCaseESaIS2_EE5eraseEN9__gnu_cxx17__normal_iteratorIPS2_S4_EES8_mbtowccopy_backward_ZNSs4rendEv__cxa_end_catch__normal_iterator > >_ZNSt12_Vector_baseIPN7testing8TestCaseESaIS2_EE19_M_get_Tp_allocatorEv__is_move_iterator_ZN9__gnu_cxx17__normal_iteratorIPKPN7testing11EnvironmentESt6vectorIS3_SaIS3_EEEpLEi_ZNSs7replaceEjjRKSsjjCmpHelperGE_ZN7testing8internal12UnitTestImpl32SuppressTestEventsIfInSubprocessEvmax_ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EE18_M_fill_initializeEjRKS2___compar_fn_t__copy_move_backward_a*, std::basic_string*>CmpHelperGT_ZN7testing8internal24HasNewFatalFailureHelperaSERKS1_parent_ldivtable_sizetotal_shardsholder__pid_type__pathGTestColoroperator()<__gnu_cxx::__normal_iterator > >_ZN7testing8internal26ThreadLocalValueHolderBaseD0Evoperator<< _ZN7testing8internal14CapturedStream17GetCapturedStringEv_ZNSt6vectorIN7testing12TestPropertyESaIS1_EE4rendEv__align__alloc_traits >_ZN7testing17TestEventListener22OnEnvironmentsSetUpEndERKNS_8UnitTestEiterator_traits_ZNSt11char_traitsIcE11eq_int_typeERKiS2__ZN9__gnu_cxx13new_allocatorISsE8allocateEjPKv_ZNKSt13_Bit_iteratorixEi_ZN9__gnu_cxx13new_allocatorIPN7testing11EnvironmentEE8allocateEjPKvstdoutflush >_ZNKSt6vectorISsSaISsEE14_M_range_checkEjmutex_ZN7testing8internal12UnitTestImpl23ListTestsMatchingFilterEv_ZNSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE5beginEv~MessageSetValue_ZNK7testing14TestPartResult17nonfatally_failedEv_ZN7testing8internal15ParseStringFlagEPKcS2_PSs~NoExecDeathTest_ZNSt6vectorIPN7testing8TestInfoESaIS2_EE7reserveEj_ZNSs6assignERKSs_ZNSs6appendEjc_ZN7testing8internal18OsStackTraceGetter16UponLeavingGTestEvregistered___normal_iterator > >_ZNSs4_Rep8_M_cloneERKSaIcEj_ZN7testing23FLAGS_gtest_random_seedE_ZNSt6vectorIPN7testing8TestCaseESaIS2_EE6assignEjRKS2_st_nlink_ZNK7testing18TestEventListeners22EventForwardingEnabledEvkFilterFlag__copy_move_backward_a2_ZNSt6vectorIPN7testing8TestInfoESaIS2_EE18_M_fill_initializeEjRKS2_basic_stringbuf, std::allocator >_ZN7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEEaSERKS6_MSG_PROXY_ZNSt11char_traitsIwE6assignEPwjw_S_compare_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE10_M_insert_EPSt18_Rb_tree_node_baseS9_RKS1__ZN7testing8internal16BoolFromGTestEnvEPKcb_ZNKSs5rfindEcj_ZNSt6vectorIPN7testing8TestInfoESaIS2_EE5eraseEN9__gnu_cxx17__normal_iteratorIPS2_S4_EES8__ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE10_S_minimumEPKSt18_Rb_tree_node_base__miter_base_ZN9__gnu_cxx14__alloc_traitsISaIPcEE8allocateERS2_j_ZN7testing8internal24XmlUnitTestResultPrinter21OutputXmlCDataSectionEPSoPKc__uninitialized_copy_a<__gnu_cxx::__normal_iterator*, std::vector > >, std::basic_string*, std::basic_string >_ZNSbIwSt11char_traitsIwESaIwEE7_M_moveEPwPKwjpipe_fd__sighandler_ttz_dsttime_M_put_node_ZNKSt3setIPKcSt4lessIS1_ESaIS1_EE4sizeEv__max_ZN9__gnu_cxx17__normal_iteratorIPN7testing8internal9TraceInfoESt6vectorIS3_SaIS3_EEEpLEi_S_leftai_family__begfdopen__copy_mfind_first_not_ofhas_new_fatal_failure_ZN9__gnu_cxx13new_allocatorIPN7testing11EnvironmentEE10deallocateEPS3_jlong double_Vector_impl_ZNKSt6vectorIN7testing8internal9TraceInfoESaIS2_EE5emptyEvupper_boundDirectoryExistsa_status_ZN7testing8TestCase14test_info_listEvabortfilter_flaga_line_number_ZNK7testing8TestCase6FailedEv_ZNK9__gnu_cxx17__normal_iteratorIPcSsEplEi_Iter_ZNKSs13get_allocatorEv_ZNSt12_Vector_baseIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE11_M_allocateEj_ZN7testing17FLAGS_gtest_colorEreverse_iterator<__gnu_cxx::__normal_iterator > > >__k1munmap_ZN7testing8internal17StreamingListener9UrlEncodeEPKclocaleconvUniversalPrintCharArrayScopedPrematureExitFileoperator!= >_ZN9__gnu_cxx14__alloc_traitsISaIPN7testing8TestCaseEEE8allocateERS4_j_ZNK7testing8internal14TestCaseNameIsclEPKNS_8TestCaseE__cxa_free_exception_M_mutatecopy_Rb_tree_decrement_ZNKSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE11_M_leftmostEvkMaxCodePoint1kMaxCodePoint2kMaxCodePoint3kMaxCodePoint4beginwstring_S_construct__pred_iter__copy_move_backward_a__clock_t__fmtfl_ZNKSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE5emptyEvkStackTraceMarker_ZN7testing8internal17StreamingListener11OnTestStartERKNS_8TestInfoECmpHelperLE_ZNSt18_Rb_tree_node_base10_S_minimumEPS_rebindp_sign_posn_ZN7testing8internal15TestFactoryBaseaSERKS1_CmpHelperLTinternal_run_death_test_flag_ZNKSt3setISsSt4lessISsESaISsEE5countERKSsallocated_ZN7testing8internal21UniversalTersePrinterIPKcE5PrintES3_PSos2_expression_ZN7testing8internal18InitGoogleTestImplIwEEvPiPPT__Rb_tree, std::less, std::allocator >_S_on_swapfirst_fixture_id_ZN7testing4Test14RecordPropertyERKSsS2___copy_move_a__copy_move_backward_a2_ZN9__gnu_cxx14__alloc_traitsISaIPN7testing8internal29ParameterizedTestCaseInfoBaseEEE10deallocateERS5_PS4_j_ZNKSt15basic_streambufIcSt11char_traitsIcEE5egptrEv_ZNSt6vectorISsSaISsEE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPSsS1_EERKSs__uninit_copy_ZN7testing14IsNotSubstringEPKcS1_RKSbIwSt11char_traitsIwESaIwEES7__ZN9__gnu_cxx17__normal_iteratorIPKN7testing14TestPartResultESt6vectorIS2_SaIS2_EEEpLEi_M_get_nodeflush__mempositive_ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EE4swapERS4__ZNKSt3setIPKcSt4lessIS1_ESaIS1_EE10value_compEv_ZNSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE15_M_erase_at_endEPS3_valuetest_part_results_name_CmpHelperNEmessage_TestPartNonfatallyFailed_S_uppercase_ZN7testing8internal21ImplicitlyConvertibleIPKvS3_E5valueEgrouping_ZNK7testing8TestCase10should_runEvcopy_backwardGetTimeInMillis_ZNSt6vectorIPN7testing8TestInfoESaIS2_EEaSERKS4__ZNKSt6vectorIiSaIiEE6rbeginEv_ZNK9__gnu_cxx17__normal_iteratorIPiSt6vectorIiSaIiEEEplEiresult_typeoperator<< >_ZNSs12_S_constructIPKcEEPcT_S3_RKSaIcE_ZNKSt3setIPKcSt4lessIS1_ESaIS1_EE5emptyEv_GLOBAL__sub_I__ZN7testing8internal17kStackTraceMarkerEflip_ZN7testing8TestInfo3RunEvoperator- >_ZNSt6vectorIPN7testing11EnvironmentESaIS2_EE14_M_fill_assignEjRKS2__ZNK9__gnu_cxx17__normal_iteratorIPKPN7testing11EnvironmentESt6vectorIS3_SaIS3_EEEmiEiFLAGS_gtest_also_run_disabled_testsaddressHasNewFatalFailureHelperlconvregfreeflag_enda_regexReadEntireFile_ZNK9__gnu_cxx17__normal_iteratorIPiSt6vectorIiSaIiEEEptEv_ZNKSbIwSt11char_traitsIwESaIwEE4sizeEv_ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EE5frontEvmkdir_ZNKSbIwSt11char_traitsIwESaIwEE3endEv_ZNSt6vectorISsSaISsEE6insertEN9__gnu_cxx17__normal_iteratorIPSsS1_EERKSsDIEDkQuoteBegin_ZNSt12_Vector_baseIPcSaIS0_EE19_M_get_Tp_allocatorEvreverse_iterator<__gnu_cxx::__normal_iterator > > >_ZN9__gnu_cxx13new_allocatorISt13_Rb_tree_nodeIPKcEE10deallocateEPS4_jeq_int_type_ZNK7testing8internal13FloatingPointIdE8sign_bitEvgtest_output_flagnpos_ZN7testing8TestCase10TestPassedEPKNS_8TestInfoE_ZNKSt6vectorIN7testing12TestPropertyESaIS1_EE6rbeginEvabs_error_expr_ZNSt6vectorISsSaISsEE5frontEvHasFatalFailure_ZNSt18_Rb_tree_node_base10_S_maximumEPKS_strdupinternal2__uninitialized_copy_aoperator- >_ZN7testing4Test10HasFailureEv_ZNK9__gnu_cxx17__normal_iteratorIPKSsSt6vectorISsSaISsEEEmiEi_ZNKSs6_M_repEv__uninit_copytext_ZN9__gnu_cxx13new_allocatorIN7testing14TestPartResultEE8allocateEjPKv__normal_iteratorpost_flag_parse_init_performed__ZN7testing8internal32FormatEpochTimeInMillisAsIso8601ExTestPropertyKeyIs_ZN7testing8internal10scoped_ptrINS0_16DeathTestFactoryEE7releaseEv_ZN7testing8internal17g_executable_pathE_ZN7testing15AssertionResultlsIA5_cEERS0_RKT_ParameterizedTestCaseInfoBasestack_grows_down_ZNSt3setIPKcSt4lessIS1_ESaIS1_EE11upper_boundERKS1_posix_ZNSt6vectorIPN7testing11EnvironmentESaIS2_EE3endEvvector_ZN7testing8internal18ParseNaturalNumberIiEEbRKSsPT_allocator_ZNK7testing8internal9MutexBase10AssertHeldEv_ZN7testing8internal17TestEventRepeater15OnTestCaseStartERKNS_8TestCaseE_M_allocate_ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EE14_M_fill_insertEN9__gnu_cxx17__normal_iteratorIPS2_S4_EEjRKS2__ZNKSs6rbeginEvnum_readtest_countpstr_M_erase_aux_Construct_ZNSt6vectorIiSaIiEE9push_backERKi__minOutputXmlAttribute_ZNSt6vectorIPN7testing8TestInfoESaIS2_EE6rbeginEvkTestShardStatusFile_ZNKSt6vectorIPN7testing17TestEventListenerESaIS2_EE3endEv__ownerSetup_should_be_spelled_SetUpoperator<< _ZNSt6vectorIPN7testing11EnvironmentESaIS2_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS2_S4_EERKS2__ZN7testing8internal17GetCapturedStreamEPPNS0_14CapturedStreamE_Construct, char const*>_ZNKSbIwSt11char_traitsIwESaIwEE7_M_iendEv_ZN7testing8internal11ShouldShardEPKcS2_b_ZNSt12_Vector_baseIPN7testing8TestInfoESaIS2_EE17_M_create_storageEj_ZN7testing10TestResultC2Ev_ZNSs4_Rep15_M_set_sharableEvsa_family_t_M_bump_up_ZN7testing8internal18StreamableToStringIiEESsRKT__ZN7testing8internal17TestEventRepeater18OnTestIterationEndERKNS_8UnitTestEi_ZNSbIwSt11char_traitsIwESaIwEE5beginEvPredicateswapiterator_traits_ZNKSt6vectorIPN7testing8TestInfoESaIS2_EE5emptyEv_ZSt16__throw_bad_castv_ZNK7testing8internal12UnitTestImpl16total_test_countEv_vtable_offsetSetUpTestCaseFuncTestResultwctrans_t_ZNK7testing8UnitTest11random_seedEv__addressofOVERSEE_TEST_ZNKSt3setISsSt4lessISsESaISsEE8key_compEv_ZN7testing8internal24XmlUnitTestResultPrinterC2EPKcdot_extension_ZNSs7replaceEN9__gnu_cxx17__normal_iteratorIPcSsEES2_PKcS4_set_forwarding_enabled_M_impl_ZN7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEE11ValueHolderD2Evsi_sigvalvwprintf_ZN7testing8TestInfo26increment_death_test_countEv_M_range_check_ZNSt23_Rb_tree_const_iteratorIPKcEppEipremature_exit_filepath~GTestFlagSaver_ZNSs7replaceEN9__gnu_cxx17__normal_iteratorIPcSsEES2_NS0_IPKcSsEES5_CheckedDowncastToActualType::ValueHolder, testing::internal::ThreadLocalValueHolderBase>_ZNSt23_Rb_tree_const_iteratorIPKcEppEv_ZNK7testing8internal12UnitTestImpl12elapsed_timeEv_ZNKSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE8key_compEv_ZNKSt6vectorIPN7testing8TestInfoESaIS2_EE8capacityEv_ZNK9__gnu_cxx13new_allocatorIPN7testing8TestInfoEE7addressERKS3__ZNK7testing15AssertionResultcvbEvCountIf, bool (*)(const testing::TestInfo*)>_ZNK7testing8TestInfo14test_case_nameEvPassed_ZN7testing8internal2RE9FullMatchERKSsRKS1__ZN7testing8internal13FloatingPointIdE38DistanceBetweenSignAndMagnitudeNumbersERKyS4__ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EE18_M_fill_initializeEjRKS2__ZNK9__gnu_cxx17__normal_iteratorIPPN7testing8TestInfoESt6vectorIS3_SaIS3_EEEdeEvpointerkStdOutFileno_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEEaSERKS5__ZNKSt6vectorISsSaISsEE8capacityEv_ZNSbIwSt11char_traitsIwESaIwEE13_S_copy_charsEPwS3_S3_forward_iterator_tagfastst_modean_index_ZNKSt6vectorIN7testing8internal9TraceInfoESaIS2_EE8capacityEv_ZN9__gnu_cxx14__alloc_traitsISaIN7testing8internal9TraceInfoEEE8allocateERS4_jiterator_traits_ZNSbIwSt11char_traitsIwESaIwEE7replaceEjjjw_ZN9__gnu_cxx24__numeric_traits_integerIsE5__maxE_ZNSt6vectorISsSaISsEE8pop_backEv_ZNK9__gnu_cxx17__normal_iteratorIPPcSt6vectorIS1_SaIS1_EEEplEi_ZNKSt6vectorIiSaIiEE14_M_range_checkEjtest_result_ZNSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EEaSERKS5__InputIterator_S_skipwsdest_ptrClosepthread_getspecificTestFactoryBase_ZNKSt6vectorISsSaISsEE8max_sizeEv_ZNK7testing8internal12UnitTestImpl17current_test_infoEv_ZN9__gnu_cxx14__alloc_traitsISaIiEE10deallocateERS1_Pij__copy_move_backward_a2_ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EE14_M_fill_insertEN9__gnu_cxx17__normal_iteratorIPS2_S4_EEjRKS2__M_leftmost_ZNKSt3setIPKcSt4lessIS1_ESaIS1_EE6rbeginEv_ZN7testing8internal27CheckedDowncastToActualTypeINS0_11ThreadLocalISt6vectorINS0_9TraceInfoESaIS4_EEE11ValueHolderENS0_26ThreadLocalValueHolderBaseEEEPT_PT0__ZNKSt6vectorIN7testing8internal9TraceInfoESaIS2_EE8max_sizeEv_ZNSt6vectorIN7testing12TestPropertyESaIS1_EE8pop_backEv_ZN7testing8TestCase12TestDisabledEPKNS_8TestInfoE_ZNK9__gnu_cxx17__normal_iteratorIPPN7testing8TestInfoESt6vectorIS3_SaIS3_EEEixEibits__ZN7testing22EmptyTestEventListenerD0Ev__uninitialized_move_if_noexcept_a >allocator_ZN7testing17TestEventListeneraSERKS0___uninit_copy_ZNSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE4swapERS5__ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE24_M_get_insert_unique_posERKSs_M_get_insert_hint_equal_pos_M_move_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE8_S_rightEPSt18_Rb_tree_node_base__niter_base_ZNK7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE16GetOrCreateValueEv_ZNSs13_S_copy_charsEPcS_S__ZNSt10_Iter_baseIPPN7testing17TestEventListenerELb0EE7_S_baseES3__ZNSt6vectorIN7testing14TestPartResultESaIS1_EE6resizeEjS1__ZNK9__gnu_cxx17__normal_iteratorIPSsSt6vectorISsSaISsEEE4baseEvoperator<< >_ZN7testing8internal38DefaultPerThreadTestPartResultReporterD0Ev_ZNKSbIwSt11char_traitsIwESaIwEE17find_first_not_ofERKS2_jnext_seed_ZNKSt12_Vector_baseIPN7testing17TestEventListenerESaIS2_EE19_M_get_Tp_allocatorEv_ZNKSt6vectorIN7testing14TestPartResultESaIS1_EE14_M_range_checkEjcerrdefault_result_printer_pfile_ZNSs12_S_constructIPKcEEPcT_S3_RKSaIcESt20forward_iterator_tag_ZN9__gnu_cxx13new_allocatorIPKcE10deallocateEPS2_jtest_case_count_ZN7testing8internal24XmlUnitTestResultPrinter9EscapeXmlERKSsbwctob_ZNKSt6vectorISsSaISsEE5beginEv_IO_save_end_ZNK7testing8internal12UnitTestImpl19disabled_test_countEvst_gidrelative_path__throw_logic_error_ZN7testing8internal9DeathTest11LastMessageEv__normal_iterator > >_ZN7testing8internal12UnitTestImpl20set_catch_exceptionsEb_ZN7testing22EmptyTestEventListener16OnTestProgramEndERKNS_8UnitTestE__ioinit_ZNKSs8capacityEv_DestroykFractionBitCount__gid_t__are_same, std::allocator >*, std::basic_string, std::allocator >*>new_allocatorFClose_ZN7testing8internal9EqFailureEPKcS2_RKSsS4_bIsUtf16SurrogatePair_ZNSs5eraseEjj_ZNKSs4dataEv_ZN7testing8internal18OsStackTraceGetteraSERKS1_construct_ZNSt23_Rb_tree_const_iteratorISsEppEi_ZN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEEaSERKS4_PrintAsCharLiteralTo_ZN9__gnu_cxx17__normal_iteratorIPiSt6vectorIiSaIiEEEmIEistr_len_ZNSt23_Rb_tree_const_iteratorISsEppEv__uninitialized_move_if_noexcept_a >UniversalPrint >ClearNonAdHocTestResult_ZNKSt23_Rb_tree_const_iteratorIPKcEptEv_ZN7testing17TestEventListener16OnTestProgramEndERKNS_8UnitTestE_ZN7testing8internal6String15FormatIntWidth2Eioperator== >_ZNKSs6lengthEvSetDefaultXmlGenerator_ZN7testing8internal16WideStringToUtf8EPKwiwcsftime_ZNKSs8max_sizeEv~DefaultGlobalTestPartResultReporter_FwdIterator_ZN7testing8internal14CmpHelperSTREQEPKcS2_PKwS4__ZN7testing8internal6IsTrueEbtear_down_tc_ZNSt12_Vector_baseIN7testing14TestPartResultESaIS1_EE17_M_create_storageEj_ZNSt6vectorIPN7testing8TestInfoESaIS2_EE6resizeEjS2__ZN7testing8internal17StreamingListener6SendLnERKSs_ZNK9__gnu_cxx17__normal_iteratorIPKN7testing14TestPartResultESt6vectorIS2_SaIS2_EEEplEi_ZNK7testing8TestCase19disabled_test_countEv_ZNKSbIwSt11char_traitsIwESaIwEE4_Rep12_M_is_leakedEv_ZNK9__gnu_cxx17__normal_iteratorIPKPN7testing8TestInfoESt6vectorIS3_SaIS3_EEE4baseEv_ZNSt17_Rb_tree_iteratorISsEmmEi_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE10_S_maximumEPSt18_Rb_tree_node_base_ZN7testing8TestCase18GetMutableTestInfoEi_ZNK9__gnu_cxx17__normal_iteratorIPKPN7testing8TestInfoESt6vectorIS3_SaIS3_EEEplEiBaseholder_base_ZNSt17_Rb_tree_iteratorISsEmmEv_ZNSt12__alloc_swapISaISsELb1EE8_S_do_itERS0_S2_argumentpartial_regex__ZN7testing8internal19TypedTestCasePState11AddTestNameEPKciS3_S3_ConcatPaths_ZN7testing8internal15TestFactoryBase10CreateTestEv__pointer_ZN7testing8internal35DefaultGlobalTestPartResultReporterD2Evtestsnegative_ZN9__gnu_cxx14__alloc_traitsISaIPN7testing8internal29ParameterizedTestCaseInfoBaseEEE10_S_on_swapERS5_S7__ZN9__gnu_cxx13new_allocatorIN7testing8internal9TraceInfoEE9constructEPS3_RKS3__S_boolalpha_ZNSbIwSt11char_traitsIwESaIwEE6assignEjw_ZNK7testing8internal12UnitTestImpl17test_to_run_countEvtest_shard_file__uninit_copy__initialize_pAppendMessage_ZN9__gnu_cxx14__alloc_traitsISaISsEE10_S_on_swapERS1_S3_targetmutex_arg_string_ZN7testing8TestCase12ShuffleTestsEPNS_8internal6RandomE_ZNK7testing8UnitTest17test_to_run_countEv_ZN7testing8internal27OsStackTraceGetterInterface17CurrentStackTraceEii__copy_move_backward_anew_allocatortest_info_listHONOR_SHARDING_PROTOCOL_ZNSt6vectorIN7testing14TestPartResultESaIS1_EE4backEv_ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EE4rendEvelapsed_time__ZNSt6vectorIPN7testing11EnvironmentESaIS2_EE4dataEv_ZNKSt6vectorIPN7testing8TestInfoESaIS2_EE4backEv_ZNSt6vectorIN7testing14TestPartResultESaIS1_EE5eraseEN9__gnu_cxx17__normal_iteratorIPS1_S3_EES7_execveg_in_fast_death_test_childTestPropertiesAsXmlAttributesdummy__ZN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEED2Ev_ZN7testing8internal20StringStreamToStringEPSt18basic_stringstreamIcSt11char_traitsIcESaIcEEstream_name_ZN9__gnu_cxx13new_allocatorIiE10deallocateEPij_Pointer_Rb_tree_insert_and_rebalance_ZNSt11char_traitsIwE6assignERwRKwuninitialized_copyin_subprocess_for_death_testpthread_mutexattr_t_ZNK9__gnu_cxx13new_allocatorIPKcE7addressERS2_for_each > >, void (*)(testing::Environment*)>_ZN7testing8internal16GetAnsiColorCodeENS0_10GTestColorE_ZN9__gnu_cxx17__normal_iteratorIPN7testing14TestPartResultESt6vectorIS2_SaIS2_EEEmIEifound_Destroy_ZNK9__gnu_cxx17__normal_iteratorIPPN7testing8TestCaseESt6vectorIS3_SaIS3_EEEdeEv_ZN7testing8internal29ParameterizedTestCaseInfoBase13RegisterTestsEvShouldUseColorcopy_backwarditerator_categoryPrintXmlUnitTest_S_eofbit_ZN7testing8internal17TestEventRepeater16OnTestPartResultERKNS_14TestPartResultEoperator<< _Iter_predfailed_test_countassertion_result_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE8_S_valueEPKSt13_Rb_tree_nodeISsE__nusersconst_iterator_ZNKSt12_Vector_baseIPN7testing8TestInfoESaIS2_EE13get_allocatorEv_M_capacityTestCaseoperator== >~Init_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE7_S_leftEPKSt18_Rb_tree_node_baseFILE_filenoDoubleLEoperator|=severity_ZNKSt6vectorIPN7testing11EnvironmentESaIS2_EEixEj_ZNSt11char_traitsIcE6assignERcRKcCaptureStderrallocator_ZNK7testing8internal8FilePath19RemoveDirectoryNameEvCreateTest~TestPartResult_ZNK7testing8internal13FloatingPointIdE6is_nanEvoperator<< _ZN7testing8internal18StreamableToStringIPcEESsRKT__ZNKSt6vectorIN7testing12TestPropertyESaIS1_EE5beginEv_ZN9__gnu_cxx17__normal_iteratorIPKPN7testing11EnvironmentESt6vectorIS3_SaIS3_EEEmIEi_ZN7testing8internal9DeathTest10AssumeRoleEv_ZNKSt6vectorIiSaIiEE2atEjHasNonfatalFailureFormatWordListvector >filter_outcome_ZNSt6vectorIiSaIiEE5clearEv_M_color_ZN7testing8TestCase13ShouldRunTestEPKNS_8TestInfoE_ZNK9__gnu_cxx17__normal_iteratorIPPN7testing8TestCaseESt6vectorIS3_SaIS3_EEEixEi_ZNSbIwSt11char_traitsIwESaIwEEaSERKS2__ZN7testing8internal8GTestLog9GetStreamEv_ZN7testing8internal27OsStackTraceGetterInterfaceaSERKS1_internal_flag_ZNSt12_Vector_baseISsSaISsEE11_M_allocateEjignore_sigprof_actionOnTestIterationEnd_ZNKSt6vectorIN7testing12TestPropertyESaIS1_EE5frontEvscoped_ptr_ZNKSs3endEv_ZNK7testing8internal8FilePath6stringEv_ZNSt6vectorIPcSaIS0_EE6assignEjRKS0__ZN9__gnu_cxx13new_allocatorIPN7testing17TestEventListenerEE10deallocateEPS3_j_ZN7testing8internal13FloatingPointIfE38DistanceBetweenSignAndMagnitudeNumbersERKjS4_getpagesize_ZNKSt6vectorIPcSaIS0_EE14_M_range_checkEj_ZNSt6vectorIPcSaIS0_EE14_M_fill_assignEjRKS0__ZNK7testing8internal10scoped_ptrISsEdeEv_ZNSo5writeEPKci_ZN7testing22FLAGS_gtest_list_testsE_ZNKSbIwSt11char_traitsIwESaIwEE16find_last_not_ofERKS2_jctype__socklen_t_ZNSt11char_traitsIwE4moveEPwPKwj_ZNK9__gnu_cxx17__normal_iteratorIPPN7testing11EnvironmentESt6vectorIS3_SaIS3_EEEplEiFloatLEStreamWideCharsToMessage_ZNSt6vectorIN7testing12TestPropertyESaIS1_EE6resizeEjS1__ZN7testing10TestResult26increment_death_test_countEv_ZNSt6vectorIN7testing12TestPropertyESaIS1_EE8_M_eraseEN9__gnu_cxx17__normal_iteratorIPS1_S3_EEoperator==, std::allocator >partial_regexsival_ptrHasSameFixtureClass_Destroyproperty_name_ZNSt6vectorIPN7testing11EnvironmentESaIS2_EE2atEj_M_refcountis_runnable_ZN7testing8internal17TestEventRepeater22OnEnvironmentsSetUpEndERKNS_8UnitTestE_ZNK7testing14TestPartResult4typeEv_ZNK9__gnu_cxx17__normal_iteratorIPPN7testing17TestEventListenerESt6vectorIS3_SaIS3_EEEplEi~TestInfo__dev_t_Base_ptr_ZN7testing8internal17StreamingListener12SocketWriterD2Ev_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE14_M_lower_boundEPSt13_Rb_tree_nodeISsES8_RKSsIsTrue_ZNSt12_Vector_baseIPN7testing17TestEventListenerESaIS2_EE19_M_get_Tp_allocatorEvfilter_M_bump_downfull_pathnameEXECUTE_TESTMSG_ERRQUEUE__uninitialized_copy_a*, std::basic_string*, std::basic_string >new_allocator_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE5eraseESt23_Rb_tree_const_iteratorISsES7__ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EE5eraseEN9__gnu_cxx17__normal_iteratorIPS2_S4_EES8__ZN7testing8internal20ExitedUnsuccessfullyEineedle_ZNKSt6vectorIPN7testing8TestInfoESaIS2_EE4sizeEv_ZN7testing7MessagelsEPKw_Bit_iterator_ZN9__gnu_cxx17__normal_iteratorIPN7testing8internal9TraceInfoESt6vectorIS3_SaIS3_EEEmIEi_ZNK7testing8UnitTest16total_test_countEvper_thread_test_part_result_reporter_fseek~DeathTestFactory_ZN7testing18TestEventListenersC2Evbasic_stringstream, std::allocator >ptrdiff_t_ZN7testing8internal14ShouldUseColorEb_ZN7testing8internal12ShuffleRangeIiEEvPNS0_6RandomEiiPSt6vectorIT_SaIS5_EEset, std::allocator >_Distance_archF_OWNER_PIDwmemmove~TestResultset_outcome__destroy__alloc_traits >_ZNK9__gnu_cxx17__normal_iteratorIPcSsEmiEi_ZSt24__throw_out_of_range_fmtPKczbasic_iostream_ZNSt6vectorIN7testing12TestPropertyESaIS1_EE6insertEN9__gnu_cxx17__normal_iteratorIPS1_S3_EERKS1_GetLastErrnoDescriptionwcrtombwstrclear_ZNKSt6vectorIPN7testing8TestInfoESaIS2_EE3endEv_ZN9__gnu_cxx13new_allocatorIPN7testing8internal29ParameterizedTestCaseInfoBaseEE9constructEPS4_RKS4_failure_ZN9__gnu_cxx13new_allocatorIPN7testing8internal29ParameterizedTestCaseInfoBaseEE10deallocateEPS4_j__check_facet >_ZN7testing8internal17TestEventRepeater18OnTestProgramStartERKNS_8UnitTestE_ZNK9__gnu_cxx17__normal_iteratorIPPN7testing8internal29ParameterizedTestCaseInfoBaseESt6vectorIS4_SaIS4_EEEplEi_ZNK7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEE16GetOrCreateValueEv__espins_ZNSsaSEPKcdefault_result_printer_ZNK9__gnu_cxx17__normal_iteratorIPN7testing8internal9TraceInfoESt6vectorIS3_SaIS3_EEEplEi_ZNSbIwSt11char_traitsIwESaIwEE3endEvrm_eo_ZN7testing8TestCase19ClearTestCaseResultEPS0_operator<< _ZNSs14_M_replace_auxEjjjcWriteToShardStatusFileIfNeeded_Rep_baseenv_varvalue_holderfirst_test_info_ZNSspLEckPrintTimeFlag_ZNSt3setIPKcSt4lessIS1_ESaIS1_EE6insertESt23_Rb_tree_const_iteratorIS1_ERKS1__ZN7testing10TestResult20ClearTestPartResultsEv__copy_move_backward_anew_allocator, std::allocator > >MSG_FINreverse_iterator<__gnu_cxx::__normal_iterator > > >st_atim_ZN7testing11Environment5SetUpEvst_dev_ZNSt6vectorIPN7testing11EnvironmentESaIS2_EE14_M_fill_insertEN9__gnu_cxx17__normal_iteratorIPS2_S4_EEjRKS2__ZN9__gnu_cxx17__normal_iteratorIPKN7testing14TestPartResultESt6vectorIS2_SaIS2_EEEmIEi__is_signedcountsCloseConnection__state_ZNKSt3setISsSt4lessISsESaISsEE4sizeEv_ZN7testing18TestEventListeners6AppendEPNS_17TestEventListenerEfirst_ZNSt6vectorIPN7testing8TestInfoESaIS2_EE15_M_erase_at_endEPS2__ZN9__gnu_cxx24__numeric_traits_integerIcE5__maxE_ZNKSbIwSt11char_traitsIwESaIwEE17find_first_not_ofEPKwjjInit_ZN7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEE7pointerEvGetTestCaseName_ZNKSt14_Bit_referenceeqERKS__ZNKSbIwSt11char_traitsIwESaIwEE5emptyEvMSG_CTRUNC__normal_iterator > >_ZNK9__gnu_cxx17__normal_iteratorIPKPN7testing11EnvironmentESt6vectorIS3_SaIS3_EEEptEv__alloc_traits >_ZN7testing8internal2REaSERKS1__ZN7testing8internal12UnitTestImpl17gtest_trace_stackEvnum_failuresenvironments_Delete__copy_move_b_M_insert_ZN9__gnu_cxx13new_allocatorIwE10deallocateEPwj_ZN7testing8internal10scoped_ptrIKSsEaSERKS3__ZN9__gnu_cxx14__alloc_traitsISaIPN7testing8TestCaseEEE7destroyERS4_PS3_PrintTestPartResult__copy_move_backward_a2*, std::basic_string*>_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE11equal_rangeERKSsgtest_ar__Identity, std::allocator > >AlwaysTrueoperator<< >set_current_test_infoTEST_DID_NOT_DIEwcscollopenmode_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE11_M_leftmostEvvalue_~TestPropertyoperator!= >_ZN7testing8internal27FormatTimeInMillisAsSecondsEx_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE13_Rb_tree_implIS3_Lb0EE13_M_initializeEv__last_ZNK9__gnu_cxx17__normal_iteratorIPKPN7testing8TestInfoESt6vectorIS3_SaIS3_EEEdeEv_ZNK9__gnu_cxx17__normal_iteratorIPKSsSt6vectorISsSaISsEEEptEv_ZNK7testing8internal12UnitTestImpl30reportable_disabled_test_countEvOnTestCaseStart__prioritydeath_test_style_kCatchExceptionsFlag_ZNSs12_S_constructEjcRKSaIcE__addressofuninitialized_copy*>ForkingDeathTestdeath_test_factory_ZN9__gnu_cxx14__alloc_traitsISaIN7testing14TestPartResultEEE8max_sizeERKS3_OsStackTraceGetterInterface_ZNSs7_M_moveEPcPKcj__copy_move_backward_a_ZNSt18_Rb_tree_node_base10_S_minimumEPKS_ParameterizedTestCaseRegistry_ZNSt12_Vector_baseIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE13_M_deallocateEPS3_j__time_t_ZN7testing8internal17StreamingListener20AbstractSocketWriteraSERKS2_signumMutexpathname__miter_base*>_ZN7testing8TestCase3RunEv_ZNKSbIwSt11char_traitsIwESaIwEE7compareEjjRKS2_jj_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE8_S_valueEPKSt18_Rb_tree_node_baseFloatingPoint_ZN9__gnu_cxx14__alloc_traitsISaIPN7testing17TestEventListenerEEE17_S_select_on_copyERKS4_fgetwc_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE4swapERS5__ZN7testing8internal12UnitTestImpl18GetMutableTestCaseEi_ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EE4rendEv_ZNKSt6vectorIN7testing8internal9TraceInfoESaIS2_EE6rbeginEv_ZNSt6vectorIN7testing12TestPropertyESaIS1_EE4dataEvrelease_ZNSt6vectorIPN7testing11EnvironmentESaIS2_EE6insertEN9__gnu_cxx17__normal_iteratorIPS2_S4_EERKS2__ZNK7testing8internal12UnitTestImpl26successful_test_case_countEvnew_allocator_ZN9__gnu_cxx17__normal_iteratorIPKN7testing14TestPartResultESt6vectorIS2_SaIS2_EEEmmEiParseBoolFlagParseInt32OnTestStartread_fd__ZN7testing8internal27PrettyUnitTestResultPrinter18OnTestIterationEndERKNS_8UnitTestEistrstrcolor__ZN9__gnu_cxx17__normal_iteratorIPKN7testing14TestPartResultESt6vectorIS2_SaIS2_EEEmmEv_ZNSs6resizeEj__vtbl_ptr_typeGTestIsInitialized_Is_pod_comparator__destroy_ZN7testing19FLAGS_gtest_shuffleEGetInjectableArgvsFormatDeathTestOutput_ZNKSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE11equal_rangeERKSs_ZNSbIwSt11char_traitsIwESaIwEEaSEwunary_function, std::allocator >, std::basic_string, std::allocator > >puts_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE7_S_leftEPSt18_Rb_tree_node_base__gnuc_va_listdeath_test_factory__ZNKSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE8_M_beginEv__builtin_memmoveGetOrCreateValue_ZNK7testing8internal8FilePath15DirectoryExistsEvThreadLocal_ZN9__gnu_cxx14__alloc_traitsISaIPcEE7destroyERS2_PS1__ZNKSt6vectorIN7testing14TestPartResultESaIS1_EE3endEv_ZNSt23_Rb_tree_const_iteratorIPKcEmmEiAbortSingleFailureChecker_ZN7testing11IsSubstringEPKcS1_RKSsS3__flags2_ZNSt23_Rb_tree_const_iteratorIPKcEmmEv_ZNKSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE21_M_get_Node_allocatorEv~HasNewFatalFailureHelper_ZN9__gnu_cxx14__alloc_traitsISaIPN7testing8TestInfoEEE8max_sizeERKS4__flagsthisbasic_ostream >_ZNKSt6vectorIPN7testing11EnvironmentESaIS2_EE4dataEv_ZNSt6vectorIPN7testing8TestInfoESaIS2_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS2_S4_EERKS2__ZStplIcSt11char_traitsIcESaIcEESbIT_T0_T1_EPKS3_RKS6__ZNK9__gnu_cxx17__normal_iteratorIPSsSt6vectorISsSaISsEEEplEiclose_fd_ZN9__gnu_cxx17__normal_iteratorIPPN7testing17TestEventListenerESt6vectorIS3_SaIS3_EEEppEikDeathTestInternalErrorrandom___is_move_iterator_ZN7testing8internal30ReportFailureInUnknownLocationENS_14TestPartResult4TypeERKSs_ZNSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE3endEv_ZNK9__gnu_cxx13new_allocatorISt13_Rb_tree_nodeIPKcEE7addressERKS4__ZNK7testing8UnitTest6FailedEv_ZN9__gnu_cxx13new_allocatorISt13_Rb_tree_nodeIPKcEE8allocateEjPKvtest_casesrcfile__miter_basewmemchr_ZN7testing18TestEventListeners8repeaterEvIsPrintableAsciiGetTypeId_ZNK9__gnu_cxx17__normal_iteratorIPPcSt6vectorIS1_SaIS1_EEEmiEiiswctypethis_is_TEST_ZNKSt9basic_iosIcSt11char_traitsIcEE7rdstateEv_Rb_tree_iterator__builtin_strlen_ZNKSs4copyEPcjj_ZN9__gnu_cxx14__alloc_traitsISaIPN7testing8TestInfoEEE10deallocateERS4_PS3_j__is_normal_iterator, std::allocator >*>__uninitialized_copy_ZN7testing8internal15NoExecDeathTest10AssumeRoleEv_ZN7testing15AssertionResultaSERKS0__ZNK9__gnu_cxx17__normal_iteratorIPN7testing12TestPropertyESt6vectorIS2_SaIS2_EEEplEicatch_exceptions__ZN7testing11Environment5SetupEv__ssize_t__niter_base<__gnu_cxx::__normal_iterator > >_ZNKSt6vectorIPN7testing8TestInfoESaIS2_EE8max_sizeEv_InIteratorseedgtest_msgallocator_ZN7testing8internal16UniversalPrinterIxE5PrintERKxPSo_ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EE5eraseEN9__gnu_cxx17__normal_iteratorIPS2_S4_EES8_chdirsival_intstrtod_ZNK7testing8TestCase21successful_test_countEvStreamableToString_ZNKSbIwSt11char_traitsIwESaIwEE4findEPKwjReportInvalidTestCaseTypeUnsignedChar_ZN7testing8internal10scoped_ptrINS0_17StreamingListener20AbstractSocketWriterEE7releaseEv_ZN7testing8internal17StreamingListenerD2Ev_ZNKSs16find_last_not_ofEcjPatternMatchesString_ZN7testing15AssertionResultlsINS_7MessageEEERS0_RKT_gtest_retval_ZN7testing8internal18StringFromGTestEnvEPKcS2_Fromstrlen_ZN7testing8internal13FloatingPointIfE15ReinterpretBitsEjstack_top_ZN7testing8internal38DefaultPerThreadTestPartResultReporter20ReportTestPartResultERKNS_14TestPartResultEPrintOnOneLinebasic_iostream >_ZNKSbIwSt11char_traitsIwESaIwEE4findEwj_ZNSs6insertEjjc__fmtkFractionBitMaskUnitTestImpl_ZN7testing22EmptyTestEventListener18OnTestIterationEndERKNS_8UnitTestEi_ZNSbIwSt11char_traitsIwESaIwEE4_Rep13_M_set_leakedEv_ZN7testing8internal29ParameterizedTestCaseRegistry13RegisterTestsEv_ZNKSt6vectorIPcSaIS0_EE4rendEvkSuccessOutputXmlCDataSectionGetCapturedStreamRemoveFileName__uninitialized_move_if_noexcept_a >_ZNSbIwSt11char_traitsIwESaIwEE2atEj_ZNSbIwSt11char_traitsIwESaIwEEixEj_ZNSbIwSt11char_traitsIwESaIwEE6insertEjPKw_ZNSt23_Rb_tree_const_iteratorISsEmmEiparse_success_ZNSbIwSt11char_traitsIwESaIwEE7replaceEN9__gnu_cxx17__normal_iteratorIPwS2_EES6_PKwS8_DeathTestAbort_ZNSt23_Rb_tree_const_iteratorISsEmmEvcoloncolor__uninitialized_move_if_noexcept_a >_vptr.Environment_Destroybasefield_ZNSt11char_traitsIcE7compareEPKcS2_j_ZN7testing8internal14CmpHelperSTREQEPKcS2_S2_S2__ZNSt6vectorIPN7testing11EnvironmentESaIS2_EE4backEvreverse_iterator<__gnu_cxx::__normal_iterator > > >RemoveDirectoryName_ZN7testing8internal21ImplicitlyConvertibleIPKvS3_E6HelperES3__Rep_typeis_disabled~basic_ios__niter_base_ZNSt12_Vector_baseIPN7testing8TestInfoESaIS2_EE13_M_deallocateEPS2_jcontentShouldRunTestReportTestPartResultcurrent_ZNSt6vectorIN7testing14TestPartResultESaIS1_EE2atEj__normal_iterator > >_ZN9__gnu_cxx17__normal_iteratorIPKN7testing8internal9TraceInfoESt6vectorIS3_SaIS3_EEEppEi_ZNK9__gnu_cxx17__normal_iteratorIPKN7testing14TestPartResultESt6vectorIS2_SaIS2_EEEmiEi_ZNKSt23_Rb_tree_const_iteratorISsEdeEv_ZNKSt6vectorIPN7testing8TestInfoESaIS2_EE6rbeginEv_M_fill_insertbasic_stringbufAddTestName_ZN9__gnu_cxx17__normal_iteratorIPKN7testing8internal9TraceInfoESt6vectorIS3_SaIS3_EEEppEvnothrow_ZNK9__gnu_cxx17__normal_iteratorIPKPN7testing8TestInfoESt6vectorIS3_SaIS3_EEEmiEiis_spawnedoperator<< _ZN7testing8internal23DefaultDeathTestFactoryD0Evvector >_ZNSs5eraseEN9__gnu_cxx17__normal_iteratorIPcSsEES2_Argvoperator<< _ZN7testing8internal27PrettyUnitTestResultPrinter16OnTestPartResultERKNS_14TestPartResultE_ZSt19__throw_logic_errorPKc__prec__pred_ZNKSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE8_M_beginEv_ZN7testing4Test16TearDownTestCaseEv_ZNSt12_Vector_baseIPN7testing8TestInfoESaIS2_EE19_M_get_Tp_allocatorEvSecretSOCK_DCCP_ZNK9__gnu_cxx17__normal_iteratorIPPN7testing17TestEventListenerESt6vectorIS3_SaIS3_EEEptEv_Ios_OpenmodeDelete_ZN7testing4Test5SetUpEv_ZN7testing18TestEventListenersaSERKS0__ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE11_M_put_nodeEPSt13_Rb_tree_nodeISsE_ZNSs6appendEPKc_S_cur_ZNKSt6vectorIPN7testing11EnvironmentESaIS2_EE14_M_range_checkEjshowposSetUpTestCasestdin__pthread_slist_t_ZNKSs4_Rep12_M_is_sharedEv_ZNSt11char_traitsIcE12to_char_typeERKi_ZNKSt6vectorIPN7testing11EnvironmentESaIS2_EE12_M_check_lenEjPKc_ZNSolsEPFRSt8ios_baseS0_E_ZN7testing15AssertionResultlsEPFRSoS1_E_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE5eraseEPKS1_S9_GetFileSize_ZNSt6vectorISsSaISsEE4rendEv_ZN9__gnu_cxx14__alloc_traitsISaIPKcEE8allocateERS3_j_ZNKSbIwSt11char_traitsIwESaIwEE15_M_check_lengthEjjPKc_ZNKSt23_Rb_tree_const_iteratorISsEeqERKS0__ZN7testing8internal27CheckedDowncastToActualTypeINS0_11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE11ValueHolderENS0_26ThreadLocalValueHolderBaseEEEPT_PT0__ZNK9__gnu_cxx13new_allocatorIiE8max_sizeEvvfwscanf_ZNKSbIwSt11char_traitsIwESaIwEE13find_first_ofEPKwjj_ZNSbIwSt11char_traitsIwESaIwEE4_Rep10_M_destroyERKS1_reverse_iterator<__gnu_cxx::__normal_iterator > > >_ZSt17__throw_bad_allocv_ZNKSt12_Vector_baseIN7testing14TestPartResultESaIS1_EE13get_allocatorEvdummyatoll_ZNSo9_M_insertImEERSoT_num_selected_tests_ZNKSbIwSt11char_traitsIwESaIwEE4copyEPwjjoperator<< _ZNSt12_Vector_baseIiSaIiEE17_M_create_storageEjfind<__gnu_cxx::__normal_iterator*, std::vector > >, std::basic_string >_ZNKSt6vectorIiSaIiEE4backEvbuffershort intsnprintf_ZNKSbIwSt11char_traitsIwESaIwEE5c_strEvwmemcpy~FilePathcurrent_test_info_ZNK7testing8internal13DeathTestImpl8write_fdEvForEach, void (*)(testing::Environment*)>_ZN7testing8internal13FloatingPointIdE15ReinterpretBitsEy_Iter_basefind_last_not_of_ZNSt6vectorIN7testing12TestPropertyESaIS1_EE6rbeginEv_ZNK7testing10TestResult12elapsed_timeEv_ZNKSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE7_M_rootEv_ZNKSt6vectorIPN7testing8TestCaseESaIS2_EE3endEvuninitialized_copy<__gnu_cxx::__normal_iterator >, testing::internal::TraceInfo*>ThreadLocalValueHolderBase__normal_iterator, std::allocator > >sa_flagstestoperator<< GetCapturedStderr_ZN9__gnu_cxx17__normal_iteratorIPPN7testing11EnvironmentESt6vectorIS3_SaIS3_EEEppEv_ZNKSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE14_M_upper_boundEPKSt13_Rb_tree_nodeISsES9_RKSs_ZNSbIwSt11char_traitsIwESaIwEE4_Rep10_M_refdataEvNoExecDeathTest_ZNSt6vectorISsSaISsEE5beginEv_ZNKSs8_M_checkEjPKc_ZNSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE6resizeEjS3__vptr.DeathTestFactorybasic_istream_ZNSt12_Vector_baseIN7testing8internal9TraceInfoESaIS2_EE11_M_allocateEj_ZNK9__gnu_cxx17__normal_iteratorIPKcSsEixEi__exchange_and_add_dispatchReseed_ZNK9__gnu_cxx17__normal_iteratorIPKPN7testing17TestEventListenerESt6vectorIS3_SaIS3_EEEptEvcopy_backwardconstructParseFlagValue_ZN7testing8internal24XmlUnitTestResultPrinterD0Ev_ZNK9__gnu_cxx17__normal_iteratorIPKcSsE4baseEv_Construct, std::basic_string >_ZNKSt6vectorIN7testing8internal9TraceInfoESaIS2_EE2atEj_ZNSbIwSt11char_traitsIwESaIwEE4rendEv_ZN7testing8internal18CmpHelperSTRCASENEEPKcS2_S2_S2__ZN7testing8internal17GetCapturedStdoutEv__iterator_category<__gnu_cxx::__normal_iterator > >PushGTestTrace_ZN7testing8internal17TestEventRepeater24OnEnvironmentsSetUpStartERKNS_8UnitTestE_ZN9__gnu_cxx13new_allocatorIcE8allocateEjPKvAssertionResult_ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EE5beginEvuninitialized_copy_ZN9__gnu_cxx14__alloc_traitsISaISsEE17_S_select_on_copyERKS1_operator- >dup2rbegin__gthread_active_pnames_ZNSbIwSt11char_traitsIwESaIwEE6insertEjPKwj_ZNK9__gnu_cxx17__normal_iteratorIPN7testing12TestPropertyESt6vectorIS2_SaIS2_EEE4baseEv_ZNSt12_Vector_baseIPN7testing8TestCaseESaIS2_EE12_Vector_impl12_M_swap_dataERS5_CountIf, bool (*)(const testing::TestCase*)>_sigchldoutput_file_vptr.ParameterizedTestCaseInfoBase__uid_tGTEST_SHARD_STATUS_FILEerrorPrintXmlTestCase_ZN9__gnu_cxx17__normal_iteratorIPKcSsEppEicode_point_ZNSs6assignERKSsjj_ZNKSt6vectorIiSaIiEE4sizeEv_ZNSt10_Iter_baseIPN7testing8internal9TraceInfoELb0EE7_S_baseES3_mon_thousands_sep_ZN7testing8UnitTest13PopGTestTraceEv_ZN9__gnu_cxx17__normal_iteratorIPKcSsEppEv_ZNKSt6vectorIPN7testing17TestEventListenerESaIS2_EEixEj_ZNK7testing18TestEventListeners22default_result_printerEv_ZNK9__gnu_cxx17__normal_iteratorIPPN7testing17TestEventListenerESt6vectorIS3_SaIS3_EEEmiEiLogToStderrwcscatUponLeavingGTest_Vector_base >_ZNSo9_M_insertIxEERSoT__ZN7testing8internal9DeathTest27set_last_death_test_messageERKSs_ZNSbIwSt11char_traitsIwESaIwEE7replaceEjjRKS2_MutexLock_ZNSt6vectorIPN7testing8TestInfoESaIS2_EE4backEvrepeater__Const_Base_ptroperator!= >getcwdSendLn_ZN7testing8internal28ParseGoogleTestFlagsOnlyImplIwEEvPiPPT__ZNSt3setISsSt4lessISsESaISsEEaSERKS3_set_os_stack_trace_getter_ZNKSt23_Rb_tree_const_iteratorISsEneERKS0__ZN7testing8internal15UnitTestOptions27GetAbsolutePathToOutputFileEv_ZNK9__gnu_cxx17__normal_iteratorIPKN7testing14TestPartResultESt6vectorIS2_SaIS2_EEE4baseEv__normal_iterator > >pair, bool>repeaterbasic_stringstatus_valuePrintTestPartResultToStringa_name_ZNSt6vectorIPN7testing8TestCaseESaIS2_EE6insertEN9__gnu_cxx17__normal_iteratorIPS2_S4_EEjRKS2__ZNKSsixEj_ZNSs7replaceEN9__gnu_cxx17__normal_iteratorIPcSsEES2_S1_S1__ZNK9__gnu_cxx13new_allocatorIcE8max_sizeEv_ZN7testing8internal21UniversalTersePrinterIxE5PrintERKxPSo_ZN7testing8internal14GetThreadCountEvreplace_ZNSbIwSt11char_traitsIwESaIwEE18_S_construct_aux_2EjwRKS1_XmlUnitTestResultPrinter_ZNK9__gnu_cxx17__normal_iteratorIPcSsEptEv_ZN7testing8internal2RE4InitEPKc_ZNK9__gnu_cxx13new_allocatorIPN7testing11EnvironmentEE7addressERKS3_AppendUserMessageUniversalTersePrinter_ZNKSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE13get_allocatorEv_ZNKSs7compareEjjPKc__suseconds_t_ZNK9__gnu_cxx17__normal_iteratorIPKPN7testing8TestCaseESt6vectorIS3_SaIS3_EEEmiEi_ZN9__gnu_cxx24__numeric_traits_integerIsE5__minE_ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EE5clearEvshuffle_RandomAccessIterator_ZN9__gnu_cxx14__alloc_traitsISaIiEE7destroyERS1_Pi_ZNSbIwSt11char_traitsIwESaIwEE13_S_copy_charsEPwN9__gnu_cxx17__normal_iteratorIS3_S2_EES6_PrintColorEncoded_M_is_sharediterator_traits_ZN7testing8internal27PrettyUnitTestResultPrinter16OnTestProgramEndERKNS_8UnitTestE_ZNK9__gnu_cxx17__normal_iteratorIPPN7testing8internal29ParameterizedTestCaseInfoBaseESt6vectorIS4_SaIS4_EEEmiEi_ZNSt6vectorIiSaIiEE18_M_fill_initializeEjRKi_ZNSt6vectorISsSaISsEE14_M_fill_assignEjRKSsscoped_ptr_ZN7testing8internal17kStackTraceMarkerE_ZN7testing8internal12UnitTestImpl11GetTestCaseEPKcS3_PFvvES5_premature_exit_filepath__S_constructparameterized_test_registry_ZN7testing8internal6Random8GenerateEj_ZN9__gnu_cxx17__normal_iteratorIPKPN7testing8TestInfoESt6vectorIS3_SaIS3_EEEppEi_Vector_baseiterator_traits<__gnu_cxx::__normal_iterator > > >_ZN7testing18FLAGS_gtest_filterE_ZNK9__gnu_cxx17__normal_iteratorIPN7testing8internal9TraceInfoESt6vectorIS3_SaIS3_EEEmiEi__copy_m_ZN9__gnu_cxx17__normal_iteratorIPKPN7testing8TestInfoESt6vectorIS3_SaIS3_EEEppEva_message__are_same_ZNSt6vectorIPcSaIS0_EE18_M_fill_initializeEjRKS0_TestCaseNameIs_M_insert_M_mask_ZN7testing8internal10scoped_ptrIKSsE7releaseEvis_reportableTestReportableDisabled_ZNK9__gnu_cxx17__normal_iteratorIPiSt6vectorIiSaIiEEE4baseEvreverse_iterator<__gnu_cxx::__normal_iterator, std::allocator > > >_ZN9__gnu_cxx13new_allocatorIPN7testing8TestCaseEE10deallocateEPS3_j_ZNSbIwSt11char_traitsIwESaIwEE9_M_mutateEjjj_ZN7testing4Test3RunEvIsSubstring_ZSt9__find_ifIN9__gnu_cxx17__normal_iteratorIPN7testing12TestPropertyESt6vectorIS3_SaIS3_EEEENS0_5__ops10_Iter_predINS2_8internal17TestPropertyKeyIsEEEET_SE_SE_T0_St26random_access_iterator_tagallocator_typeSetUp__comp_ZN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE7pointerEvpthread_mutex_lockassignrandom_seed__ZN7testing8internal15UnitTestOptions15GetOutputFormatEv_ZSt4cerr_ZNSbIwSt11char_traitsIwESaIwEE7_M_dataEPwfilefillCurrentOsStackTraceExceptTop_ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EE5eraseEN9__gnu_cxx17__normal_iteratorIPS2_S4_EE_ZN7testing8internal35DefaultGlobalTestPartResultReporter20ReportTestPartResultERKNS_14TestPartResultE_ZNSt12_Vector_baseIPN7testing8TestCaseESaIS2_EE17_M_create_storageEj_ZN7testing15AssertionResultlsIPKcEERS0_RKT__ZNSt12_Vector_baseIPcSaIS0_EE13_M_deallocateEPS0_j_exit_ZN7testing11IsSubstringEPKcS1_PKwS3_DistanceBetweenSignAndMagnitudeNumbers_ZNK7testing14TestPartResult6failedEvImplicitlyConvertible_ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EE6assignEjRKS2__ZN7testing8internal27PrettyUnitTestResultPrinter16PrintFailedTestsERKNS_8UnitTestE_ZNSt6vectorIPN7testing11EnvironmentESaIS2_EE8_M_eraseEN9__gnu_cxx17__normal_iteratorIPS2_S4_EES8__ZNKSt6vectorIPN7testing17TestEventListenerESaIS2_EE12_M_check_lenEjPKcerror_num_M_initialize_dispatch10regmatch_t_ZN7testing17TestEventListener15OnTestCaseStartERKNS_8TestCaseE_ZN7testing19TestPartResultArray6AppendERKNS_14TestPartResultE_S_red~ThreadLocalValueHolderBase_ZN9__gnu_cxx14__alloc_traitsISaIPKcEE10_S_on_swapERS3_S5__ZNK9__gnu_cxx13new_allocatorIN7testing12TestPropertyEE7addressERS2__ZN7testing10TestResult16set_elapsed_timeExarguments_ZN9__gnu_cxx24__numeric_traits_integerIiE5__maxEoperator!= >_ZNSt6vectorIN7testing12TestPropertyESaIS1_EE5beginEvgtest_error_ZNSbIwSt11char_traitsIwESaIwEEpLERKS2__ZN7testing8internal20DoubleNearPredFormatEPKcS2_S2_ddd_ZN7testing8internal8GTestLogaSERKS1__ZN7testing8internal35HandleExceptionsInMethodIfSupportedINS0_12UnitTestImplEbEET0_PT_MS4_FS3_vEPKcClearTestCaseResult_M_insert_aux~TraceInfo_ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS2_S4_EERKS2_state__S_adjustfield~AssertHelperData_ZNSt10_Iter_baseIPPN7testing8TestInfoELb0EE7_S_baseES3_ai_protocol_ZN7testing8internal16UniversalPrinterISbIwSt11char_traitsIwESaIwEEE5PrintERKS5_PSoTestInfo_Iter_base_vptr.OsStackTraceGetterInterfacefind_ZN7testing8internal8FilePath12MakeFileNameERKS1_S3_iPKc_ZN9__gnu_cxx14__alloc_traitsISaIPN7testing8TestCaseEEE17_S_select_on_copyERKS4__ZN7testing8internal8FilePath13GetCurrentDirEvparsedgetenv_ZNSt17_Rb_tree_iteratorIPKcEppEiParseGoogleTestFlagsOnlyImplintercept_mode__ZN7testing8internal10SkipPrefixEPKcPS2__Bit_iterator_base_ZNSt17_Rb_tree_iteratorIPKcEppEv_ZNK7testing12TestProperty5valueEv__wide_IO_read_endHandleExceptionsInMethodIfSupported_ZNK7testing8internal10scoped_ptrINS0_17StreamingListener20AbstractSocketWriterEEptEvwcschrIsSubstringPred >__builtin_va_list_ZNKSt3setISsSt4lessISsESaISsEE13get_allocatorEv__cxa_allocate_exceptionoperator new []val2_ss_ZNSt14_Bit_referenceaSEbpathname__ZNKSt6vectorISsSaISsEE5emptyEvstream_result_to__copy_m_S_minimumnew_allocator_ZNK7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEE3getEvIsXDigit_IO_FILE_ZN7testing8internal24InternalRunDeathTestFlagaSERKS1_uninitialized_copy_ZNKSt6vectorIN7testing8internal9TraceInfoESaIS2_EE4rendEv_ZN7testing8internal24GetCurrentExecutableNameEv_ZNKSt6vectorIPN7testing11EnvironmentESaIS2_EE2atEj__statbufis_previous_hex_ZN7testing22EmptyTestEventListener11OnTestStartERKNS_8TestInfoE_ZNKSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE13get_allocatorEvservinfo__false_typewcsrchr__uninitialized_move_if_noexcept_a*, std::basic_string*, std::allocator > >_ZN9__gnu_cxx13new_allocatorIPN7testing8TestCaseEE8allocateEjPKv__is_null_pointerbiased1biased2_ZNKSbIwSt11char_traitsIwESaIwEE12find_last_ofERKS2_jValueHolder_ZNK7testing8internal13DeathTestImpl9statementEv_ZNSt6vectorISsSaISsEEaSERKS1_PrintWideStringTo_Vector_base >bool_valuepattern_ZN7testing22EmptyTestEventListener9OnTestEndERKNS_8TestInfoE_ZNKSt17_Rb_tree_iteratorISsEptEv_ZN7testing22EmptyTestEventListener15OnTestCaseStartERKNS_8TestCaseE_ZNKSt13_Bit_iteratorplEi__is_move_iterator__alloc_traits >IsATTY~basic_stringstream_ZN9__gnu_cxx13new_allocatorIN7testing14TestPartResultEE7destroyEPS2__ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE13_M_clone_nodeEPKSt13_Rb_tree_nodeISsE_M_const_castlldiv_ZN7testing8internal9MutexBase4LockEv_ZN7testing8internal12UnitTestImpl41GetTestPartResultReporterForCurrentThreadEvstatus_ch_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE6_M_endEvSuppressEventForwardingoperator<< >adjustfield_ZNSt6vectorIN7testing14TestPartResultESaIS1_EE14_M_fill_assignEjRKS1__ZNKSbIwSt11char_traitsIwESaIwEE12find_last_ofEPKwjwctomb_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE6_S_keyEPKSt18_Rb_tree_node_baseIsSubstringImplsi_utimeUniversalTersePrinter_Key_compare_ZN7testing8internal6String15ShowWideCStringEPKwswscanfwcscspn_ZN7testing8internal9DeathTest6PassedEbhaystack_exprtest_case_nameformatiterator_traitsDISABLED_*:*/DISABLED_*Clear_ZNSt6vectorIPN7testing8TestInfoESaIS2_EE6insertEN9__gnu_cxx17__normal_iteratorIPS2_S4_EEjRKS2___uninitialized_copy_a_ZN9__gnu_cxx17__normal_iteratorIPKPN7testing8TestCaseESt6vectorIS3_SaIS3_EEEppEi_ZNK9__gnu_cxx17__normal_iteratorIPSsSt6vectorISsSaISsEEEmiEi_Funct_ZNK7testing8internal13FloatingPointIfE4bitsEv_ZN9__gnu_cxx17__normal_iteratorIPKPN7testing8TestCaseESt6vectorIS3_SaIS3_EEEppEv__uninit_copy<__gnu_cxx::__normal_iterator >, testing::internal::TraceInfo*>_S_showbase~basic_istreamconstruct_ZNSbIwSt11char_traitsIwESaIwEE7reserveEj_ZNKSt6vectorIN7testing12TestPropertyESaIS1_EE5emptyEvsigval_t_ZNKSt14_Bit_referencecvbEvsi_bandsigvalGetUnitTestImpl_ZN9__gnu_cxx14__alloc_traitsISaIPN7testing8TestInfoEEE8allocateERS4_jwcscmpsyntax_ValueT_ZNK9__gnu_cxx17__normal_iteratorIPPcSt6vectorIS1_SaIS1_EEEptEv_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE10_M_insert_EPSt18_Rb_tree_node_baseS7_RKSsiterator_traitsGetTestCaseTypeIdstrerrorstderr_ZNSt6vectorIN7testing12TestPropertyESaIS1_EE5clearEv_ZNKSbIwSt11char_traitsIwESaIwEE7compareEjjRKS2__ZNK7testing8internal10scoped_ptrINS0_16DeathTestFactoryEEptEvstreamsize_S_max_size_lock_ZN7testing7MessagelsEb__uninit_copy_ZN9__gnu_cxx13new_allocatorIPcE8allocateEjPKv_ZNK9__gnu_cxx17__normal_iteratorIPKPN7testing8TestCaseESt6vectorIS3_SaIS3_EEE4baseEvInterceptMode10__sigset_t_ZNKSt6vectorIPN7testing11EnvironmentESaIS2_EE5frontEv_ZNSs12_S_empty_repEv_ZNSs6assignEjc_ZNSt6vectorIPN7testing8TestInfoESaIS2_EE8pop_backEv_ZN9__gnu_cxx13new_allocatorIN7testing12TestPropertyEE8allocateEjPKvnum_disabled_ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EEaSERKS4__ZNSt6vectorIPN7testing11EnvironmentESaIS2_EE9push_backERKS2__ZNSt6vectorIPN7testing8TestCaseESaIS2_EE14_M_fill_insertEN9__gnu_cxx17__normal_iteratorIPS2_S4_EEjRKS2__ZN7testing8internal17StreamingListener12SocketWriter4SendERKSs_ZNSolsEPKv_ZNK7testing8internal29ParameterizedTestCaseInfoBase15GetTestCaseNameEv_ZN7testing8internal17TestEventRepeater27OnEnvironmentsTearDownStartERKNS_8UnitTestE_ZN7testing8internal13DeathTestImpl11set_read_fdEi_ZNK7testing15AssertionResultntEvGetCurrentDir__is_normal_iterator_ZNSt18_Bit_iterator_base7_M_incrEivswscanf_ZNSo9_M_insertIdEERSoT__ZNK7testing14TestPartResult7summaryEv__normal_iterator > >_ZNSs5beginEvkMaxStackTraceDepth_ZNSs13_S_copy_charsEPcPKcS1_IGNORE_SHARDING_PROTOCOL_chainDefaultDeathTestFactoryfor_each<__gnu_cxx::__normal_iterator >, void (*)(testing::TestInfo*)>_ZNK7testing8TestCase16total_test_countEv_ZNSt6vectorISsSaISsEE4swapERS1__ZNSs6rbeginEvuninitialized_copy_ZNK7testing8UnitTest12elapsed_timeEv_ZNK9__gnu_cxx17__normal_iteratorIPN7testing8internal9TraceInfoESt6vectorIS3_SaIS3_EEE4baseEv_ZN7testing8internal27PrettyUnitTestResultPrinter13PrintTestNameEPKcS3_wcstollwcsxfrm_ZNKSbIwSt11char_traitsIwESaIwEE5rfindERKS2_jdistance_ZN9__gnu_cxx13new_allocatorIN7testing12TestPropertyEE7destroyEPS2__ZNKSt9_IdentityISsEclERSsleftfmtflagskTestsuitewcscpy_S_maximum_ZNKSt3setISsSt4lessISsESaISsEE10value_compEv_ZNKSt6vectorIN7testing8internal9TraceInfoESaIS2_EE12_M_check_lenEjPKc_ZN7testing11IsSubstringEPKcS1_S1_S1_fflushpair, std::allocator > >, std::_Rb_tree_const_iterator, std::allocator > > >vectorst_blksize_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE6rbeginEvkListTestsFlagreverse_iterator, std::allocator > > >_ZNK7testing12TestProperty3keyEv_ZNK9__gnu_cxx17__normal_iteratorIPPN7testing17TestEventListenerESt6vectorIS3_SaIS3_EEE4baseEv_M_assign_ZNSbIwSt11char_traitsIwESaIwEE4_Rep10_M_refcopyEv_ZN9__gnu_cxx14__alloc_traitsISaISsEE10deallocateERS1_PSsj_ZNKSt12_Vector_baseIN7testing12TestPropertyESaIS1_EE19_M_get_Tp_allocatorEv~PrettyUnitTestResultPrintersa_handlerg_linked_ptr_mutex_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE7_M_rootEv_ZNKSt6vectorIPN7testing11EnvironmentESaIS2_EE4rendEvkMaxRandomSeed_ZN7testing8internal12UnitTestImplaSERKS1_PrintAsCharLiteralTo_ZN7testing8internal10AlwaysTrueEv__mode_ZNSt6vectorIN7testing12TestPropertyESaIS1_EE6insertEN9__gnu_cxx17__normal_iteratorIPS1_S3_EEjRKS1__ZN7testing8internal24XmlUnitTestResultPrinter16PrintXmlTestCaseEPSoRKNS_8TestCaseE_IO_read_ptrset, std::allocator >, std::less, std::allocator > >, std::allocator, std::allocator > > >_ZN7testing13PrintToStringIxEESsRKT__ZN7testing8internal12UnitTestImpl6randomEvconstruct_ZN9__gnu_cxx17__normal_iteratorIPKN7testing8internal9TraceInfoESt6vectorIS3_SaIS3_EEEmmEi_ZNK9__gnu_cxx17__normal_iteratorIPKN7testing14TestPartResultESt6vectorIS2_SaIS2_EEEptEvfalse_type_ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EE4dataEv_ZNSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EEixEj_ZN9__gnu_cxx17__normal_iteratorIPKN7testing8internal9TraceInfoESt6vectorIS3_SaIS3_EEEmmEvHandleSehExceptionsInMethodIfSupported_ZNSbIwSt11char_traitsIwESaIwEE12_S_constructEjwRKS1__M_incr_ZNK7testing8internal13DeathTestImpl5regexEv_ZNK9__gnu_cxx17__normal_iteratorIPKPN7testing8TestInfoESt6vectorIS3_SaIS3_EEEptEv_ZN7testing8TestCase11AddTestInfoEPNS_8TestInfoEPrintBytesInObjectToImpl~allocatorrandom_seed_flag_ZN7testing8internal9DeathTest5AbortENS1_11AbortReasonEshowbase__copy_move_a_ZN7testing4Test19HasSameFixtureClassEvFLAGS_gtest_throw_on_failureAlwaysFalsekSpecialEscape_ZNK9__gnu_cxx17__normal_iteratorIPKPN7testing17TestEventListenerESt6vectorIS3_SaIS3_EEEdeEv_Vector_base >_ZN9__gnu_cxx14__alloc_traitsISaIPN7testing11EnvironmentEEE17_S_select_on_copyERKS4_rebind >_ZN7testing8UnitTest11GetInstanceEv_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE10_S_minimumEPSt18_Rb_tree_node_base_ZNKSt16reverse_iteratorIN9__gnu_cxx17__normal_iteratorIPPN7testing11EnvironmentESt6vectorIS4_SaIS4_EEEEEdeEv_ZN9__gnu_cxx13new_allocatorIPN7testing17TestEventListenerEE7destroyEPS3_new_allocator_ZN7testing8internal12UnitTestImpl17current_test_infoEv_ZNSt3setISsSt4lessISsESaISsEE6insertERKSs_ZNKSs12find_last_ofEPKcjBits__uninitialized_copy_S_fixed_ZNSbIwSt11char_traitsIwESaIwEE7replaceEN9__gnu_cxx17__normal_iteratorIPwS2_EES6_RKS2_UnitTest_ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EE4backEv_ZNK9__gnu_cxx17__normal_iteratorIPKcSsEdeEvmax_size_ZN7testing8internal20SingleFailureCheckeraSERKS1__Traits_ZN7testing8internal9DeathTestaSERKS1_default_valuesigned char_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE11_M_get_nodeEvisattybidirectional_iterator_tag_ZNKSbIwSt11char_traitsIwESaIwEE7compareEjjPKwj_ZN7testing8internal27PrettyUnitTestResultPrinter20OnTestIterationStartERKNS_8UnitTestEiHandleExceptionsInMethodIfSupportedFLAGS_gtest_output_ZN7testing8internal10scoped_ptrINS0_16DeathTestFactoryEEaSERKS3_FloatingPoint__copy_m_ZN9__gnu_cxx14__alloc_traitsISaIPcEE10_S_on_swapERS2_S4_wcspbrka_statement_ZNK9__gnu_cxx17__normal_iteratorIPKPN7testing17TestEventListenerESt6vectorIS3_SaIS3_EEEixEioperator<< Sendsubstr__ZN7testing11IsSubstringEPKcS1_RKSbIwSt11char_traitsIwESaIwEES7_negation_ZNSt11char_traitsIcE2eqERKcS2__ZNKSt16reverse_iteratorIN9__gnu_cxx17__normal_iteratorIPPN7testing11EnvironmentESt6vectorIS4_SaIS4_EEEEEixEi_ZNK7testing8internal10scoped_ptrISt18basic_stringstreamIcSt11char_traitsIcESaIcEEEptEvHandleExceptionsInMethodIfSupported_M_refdataendl >_ZNK7testing8TestCase4nameEv__throw_bad_alloc_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE11_M_leftmostEvprint_timeregcomp_ZNSt10_Iter_baseIPSsLb0EE7_S_baseES0__ZNK9__gnu_cxx13new_allocatorIN7testing14TestPartResultEE7addressERKS2_scoped_ptrChar_kill_ZN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE11ValueHolderD0Ev_ZNK9__gnu_cxx13new_allocatorISt13_Rb_tree_nodeISsEE7addressERKS2_severity_pthread_mutex_destroy_ZNSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE6insertEN9__gnu_cxx17__normal_iteratorIPS3_S5_EEjRKS3__ZNSolsEPFRSoS_Evprintf_ZNSt12_Vector_baseIN7testing12TestPropertyESaIS1_EE12_Vector_impl12_M_swap_dataERS4_operator<< _sbuf_ZNSt3setIPKcSt4lessIS1_ESaIS1_EE11equal_rangeERKS1_FLAGS_gtest_catch_exceptions_ZN7testing8internal27PrettyUnitTestResultPrinter24OnEnvironmentsSetUpStartERKNS_8UnitTestEdef_optional_ZNSt6vectorIiSaIiEE5frontEvtruncreporter_ZNSbIwSt11char_traitsIwESaIwEE4_Rep9_S_createEjjRKS1__ZN7testing8internal18g_linked_ptr_mutexE_ZNSt6vectorIPcSaIS0_EE4rendEv_ZN7testing8internal18OsStackTraceGetterD2Ev_ZNKSbIwSt11char_traitsIwESaIwEE7compareERKS2___throw_bad_cast__uninitialized_copy_a_ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EE6assignEjRKS2_strtoull__ostream_insert >fwprintf_Destroy__is_normal_iterator_ZN9__gnu_cxx14__alloc_traitsISaIN7testing14TestPartResultEEE7destroyERS3_PS2__ZN7testing8internal17StreamingListener18OnTestProgramStartERKNS_8UnitTestElong int_ZNSt11char_traitsIcE6assignEPcjc_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE7_M_copyEPKSt13_Rb_tree_nodeIS1_EPS9_ToUppervector >_ZN7testing13PrintToStringIPKwEESsRKT_operator-*, std::vector > >default_xml_generatorFormatHexIntstatus_ZN9__gnu_cxx14__alloc_traitsISaISt13_Rb_tree_nodeISsEEE10_S_on_swapERS3_S5__ZNK9__gnu_cxx17__normal_iteratorIPPN7testing11EnvironmentESt6vectorIS3_SaIS3_EEEptEv_ZNSt6vectorIiSaIiEE14_M_fill_insertEN9__gnu_cxx17__normal_iteratorIPiS1_EEjRKi_ZN7testing8internal10scoped_ptrISt18basic_stringstreamIcSt11char_traitsIcESaIcEEE7releaseEv_ZN9__gnu_cxx13new_allocatorIN7testing8internal9TraceInfoEE8allocateEjPKv_ZN7testing4Test8TearDownEvarray_ZNKSt12_Vector_baseIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE19_M_get_Tp_allocatorEv_ZNSt6vectorISsSaISsEE6insertEN9__gnu_cxx17__normal_iteratorIPSsS1_EEjRKSs_ZNKSs7_M_dataEv_ZNSt12_Vector_baseIiSaIiEE13_M_deallocateEPijiteratoroperator!= >__destroy_ZN7testing8internal18StreamableToStringIxEESsRKT_socket_writer__ZN9__gnu_cxx17__normal_iteratorIPKcSsEmmEidescriptionGetDefaultFilter_ZN9__gnu_cxx17__normal_iteratorIPKcSsEmmEvbasic_string, std::allocator >_ZNK9__gnu_cxx17__normal_iteratorIPPN7testing8TestInfoESt6vectorIS3_SaIS3_EEEplEi_ZNKSt15basic_streambufIcSt11char_traitsIcEE4pptrEvIsContainerTest_ZNSs4_Rep13_M_set_leakedEvreverse_iterator >_ZNKSbIwSt11char_traitsIwESaIwEE4_Rep12_M_is_sharedEv_ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EE8_M_eraseEN9__gnu_cxx17__normal_iteratorIPS2_S4_EES8___uninit_copy*, std::basic_string*>_ZN7testing8internal13DeathTestImpl6PassedEb_ZNKSt6vectorIPN7testing17TestEventListenerESaIS2_EE4backEv_ZNK7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE7pointerEv_ZN7testing8internal5MutexaSERKS1_no_sub_ZNSs6insertEjRKSs_Rb_tree, std::allocator >, std::basic_string, std::allocator >, std::_Identity, std::allocator > >, std::less, std::allocator > >, std::allocator, std::allocator > > >_ZNSbIwSt11char_traitsIwESaIwEE15_M_replace_safeEjjPKwj_ZN7testing8internal10scoped_ptrISsEaSERKS2__ZNSt6vectorIPcSaIS0_EE5clearEv_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE24_M_get_insert_unique_posERKS1__ZN7testing8internal17TestEventRepeater20OnTestIterationStartERKNS_8UnitTestEi_S_do_ituninitialized_copySOCK_NONBLOCK_ZNK9__gnu_cxx13new_allocatorIPN7testing8TestInfoEE8max_sizeEvRunSetUpTestCase_ZNSt6vectorIPN7testing11EnvironmentESaIS2_EE8pop_backEv_ZNKSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE3endEv_ZN7testing8UnitTestD0Ev_ZN7testing8internal31GetCurrentOsStackTraceExceptTopEPNS_8UnitTestEi_ZN7testing8internal9DeathTest6CreateEPKcPKNS0_2REES3_iPPS1_random_seed_ZNK9__gnu_cxx17__normal_iteratorIPN7testing12TestPropertyESt6vectorIS2_SaIS2_EEEmiEiFilePath_Atomic_wordimpl_Format_ZNK7testing18TestEventListeners21default_xml_generatorEvos_stack_trace_getter__ZN9__gnu_cxx13new_allocatorIPcE10deallocateEPS1_j_ZN7testing17TestEventListener25OnEnvironmentsTearDownEndERKNS_8UnitTestE__is_normal_iterator_ZN7testing22EmptyTestEventListener16OnTestPartResultERKNS_14TestPartResultEpipe_ZNKSt6vectorIPcSaIS0_EE4dataEvsi_signo_ZNSt12_Destroy_auxILb0EE9__destroyIPSsEEvT_S3__ZNK9__gnu_cxx17__normal_iteratorIPKPN7testing8TestCaseESt6vectorIS3_SaIS3_EEEptEvCreateSOCK_PACKETiterator_S_keyTestRoleless, std::allocator > >allocator_KeyOfValue_ZN7testing8internal15UnitTestOptions20PatternMatchesStringEPKcS3__ZNKSt12_Vector_baseIPN7testing11EnvironmentESaIS2_EE19_M_get_Tp_allocatorEvwprintf_ZNK9__gnu_cxx17__normal_iteratorIPKSsSt6vectorISsSaISsEEE4baseEvvector >_ZN9__gnu_cxx17__normal_iteratorIPKN7testing8internal9TraceInfoESt6vectorIS3_SaIS3_EEEpLEi_ZNSt6vectorIPN7testing8TestCaseESaIS2_EE14_M_fill_assignEjRKS2_operator- >__normal_iterator > >floatdeath_test_use_forktest_cases__ZN9__gnu_cxx17__normal_iteratorIPKPN7testing8TestInfoESt6vectorIS3_SaIS3_EEEmmEv_ZNK9__gnu_cxx17__normal_iteratorIPN7testing8internal9TraceInfoESt6vectorIS3_SaIS3_EEEptEv_ZNSt6vectorISsSaISsEE4dataEv__needlenum_chars_M_repBiggestInt_ZN7testing7FloatLEEPKcS1_ff_Iter_base<__gnu_cxx::__normal_iterator > >, true>set_child_pid__copy_mFLAGS_gtest_list_testsmbrlen_ZNSs9push_backEc_ZN9__gnu_cxx17__normal_iteratorIPKPN7testing17TestEventListenerESt6vectorIS3_SaIS3_EEEppEiGetParam()re_pattern_buffer_ZN7testing4TestD2Ev_ZNK7testing8internal13FloatingPointIfE13exponent_bitsEvssize_t_ZN9__gnu_cxx17__normal_iteratorIPKPN7testing17TestEventListenerESt6vectorIS3_SaIS3_EEEppEvreverse_iterator<__gnu_cxx::__normal_iterator > > >_ZNKSt12_Vector_baseIPN7testing8TestCaseESaIS2_EE13get_allocatorEvargc_Ios_Fmtflags_M_replace_aux_ZN7testing8internal7PrintToEPKcPSo~CapturedStream__niter_baseresize_ZSt18_Rb_tree_decrementPSt18_Rb_tree_node_base_ZNSt11char_traitsIcE11to_int_typeERKc_ZN7testing14ExitedWithCodeaSERKS0_argvoperator<< _ZN7testing32ScopedFakeTestPartResultReporterC2EPNS_19TestPartResultArrayE_ZNSt6vectorISsSaISsEE15_M_erase_at_endEPSserrors_ZNKSt6vectorIPN7testing8TestInfoESaIS2_EEixEj_ZN7testing8internal12UnitTestImpl26RegisterParameterizedTestsEvDerivedforever_ZNK7testing19TestPartResultArray17GetTestPartResultEi_ZNKSs17find_first_not_ofEcjseconds_IIter__niter_base_ZN7testing7MessageaSERKS0___elision_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE12_M_erase_auxESt23_Rb_tree_const_iteratorIS1_E_ZNSt6vectorIiSaIiEE6resizeEji_ZNSt12_Vector_baseIPN7testing8TestCaseESaIS2_EE11_M_allocateEjUrlEncode_ZNK9__gnu_cxx13new_allocatorIcE7addressERc_ZNSt10_Iter_baseIN9__gnu_cxx17__normal_iteratorIPPN7testing17TestEventListenerESt6vectorIS4_SaIS4_EEEELb1EE7_S_baseES9_CurrentStackTrace_ZN7testing8internal16DeathTestFactory6CreateEPKcPKNS0_2REES3_iPPNS0_9DeathTestE__data_ZNK9__gnu_cxx17__normal_iteratorIPN7testing14TestPartResultESt6vectorIS2_SaIS2_EEEdeEvtest_part_resultsTestCaseFaileddiv_t__normal_iterator > >reverse_iterator<__gnu_cxx::__normal_iterator > > >_ZNSt17_Rb_tree_iteratorIPKcEmmEi_ZN7testing4Test11DeleteSelf_EvStrDup__copy_move_ZNK7testing8TestInfo4nameEv_ZNSt6vectorIPN7testing8TestInfoESaIS2_EE5eraseEN9__gnu_cxx17__normal_iteratorIPS2_S4_EE_ZNSs16_S_construct_auxIPKcEEPcT_S3_RKSaIcESt12__false_type_ZNSt17_Rb_tree_iteratorIPKcEmmEv__dynamic_cast__is_move_iterator~XmlUnitTestResultPrinterBasicNarrowIoManip__list_ZNSt9basic_iosIcSt11char_traitsIcEE4fillEctv_nsec_ZN7testing38FLAGS_gtest_show_internal_stack_framesEUnlock_ZNK7testing10TestResult15HasFatalFailureEvpthread_setspecific__dnewinput_iterator_tag~ParameterizedTestCaseRegistryprinted_test_case_name_M_start_ZNK9__gnu_cxx13new_allocatorIwE8max_sizeEvusedSkipCommaTestPartResultReporterInterface__numeric_traits_integer_ZNSt6vectorIN7testing14TestPartResultESaIS1_EE8_M_eraseEN9__gnu_cxx17__normal_iteratorIPS1_S3_EE_ZN7testing8TestCase14TestReportableEPKNS_8TestInfoEUInt_ZNK7testing8internal13FloatingPointIfE6is_nanEv_ZNK9__gnu_cxx17__normal_iteratorIPPN7testing8TestCaseESt6vectorIS3_SaIS3_EEEplEioperator!= >_ZNK9__gnu_cxx17__normal_iteratorIPN7testing14TestPartResultESt6vectorIS2_SaIS2_EEEixEidefault_xml_generator__ZN7testing8internal17StreamingListener15OnTestCaseStartERKNS_8TestCaseE_ZNSt6vectorIPN7testing8TestInfoESaIS2_EEixEjstackset_up_tc_TEST_F_namesecond_ZNSsaSERKSsis_disabled_OnEnvironmentsTearDownEnd~SocketWriter_Num_ZNSt6vectorIPN7testing11EnvironmentESaIS2_EE15_M_erase_at_endEPS2__ZNKSt6vectorIiSaIiEE12_M_check_lenEjPKc_ZN9__gnu_cxx14__alloc_traitsISaIiEE10_S_on_swapERS1_S3__ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEED0Evdashstatement_ZN7testing22FLAGS_gtest_print_timeE_ZNSt12_Vector_baseIN7testing12TestPropertyESaIS1_EE19_M_get_Tp_allocatorEv_ZNKSt13_Bit_iteratormiEiExitedWithCodehintstm_gmtoff_ZN9__gnu_cxx14__alloc_traitsISaIPN7testing8TestInfoEEE17_S_select_on_copyERKS4__ZN7testing8internal14CmpHelperSTRNEEPKcS2_PKwS4__ZNKSt3setISsSt4lessISsESaISsEE3endEvoperator<< _ZN7testing7MessageC2ERKS0_UniversalPrintArrayst_blocks_ZN7testing8internal12UnitTestImpl25set_os_stack_trace_getterEPNS0_27OsStackTraceGetterInterfaceEpthread_tprefix_ZN9__gnu_cxx14__alloc_traitsISaIPN7testing8internal29ParameterizedTestCaseInfoBaseEEE8allocateERS5_jDeathTestThreadWarningdata_ZN9__gnu_cxx17__normal_iteratorIPPcSt6vectorIS1_SaIS1_EEEppEv_ZNKSs4sizeEv__miter_base_ZN7testing8internal17StreamingListener20AbstractSocketWriter4SendERKSsallocator > >_ZNSt6vectorIPcSaIS0_EE9push_backERKS0_ai_addrlenkNonFatalFailure_ZNKSbIwSt11char_traitsIwESaIwEE2atEj_ZN7testing8internal21StackLowerThanAddressEPKvPbStat_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE29_M_get_insert_hint_unique_posESt23_Rb_tree_const_iteratorISsERKSs_ZNSt17_Rb_tree_iteratorISsEppEic_str_ZN7testing8internal13CaptureStreamEiPKcPPNS0_14CapturedStreamEsi_statusParseGoogleTestFlagsOnly_ZNK7testing8UnitTest19disabled_test_countEv__niter_baseoperator<< _ZNKSt6vectorIPN7testing8TestInfoESaIS2_EE2atEjg_captured_stdout_ZN9__gnu_cxx14__alloc_traitsISaIPKcEE8max_sizeERKS3__ZN7testing22EmptyTestEventListener25OnEnvironmentsTearDownEndERKNS_8UnitTestEdeath_test_style_ZNKSs15_M_check_lengthEjjPKc_ZN9__gnu_cxx14__alloc_traitsISaIPN7testing8TestCaseEEE10_S_on_swapERS4_S6__ZNK9__gnu_cxx13new_allocatorIwE7addressERwoperator new_ZN9__gnu_cxx17__normal_iteratorIPKPN7testing8TestCaseESt6vectorIS3_SaIS3_EEEmmEi__class_type_info_ZNK9__gnu_cxx17__normal_iteratorIPSsSt6vectorISsSaISsEEEptEvbadbit_ZN7testing8TestInfoD2EvGetTestInfo_ZN9__gnu_cxx17__normal_iteratorIPKPN7testing8TestCaseESt6vectorIS3_SaIS3_EEEmmEvruntime_errorEndsWithCaseInsensitivevector >__countGTestMutexLocksam1ostreamsam2long_value_ZN7testing8internal8GTestLogD2Ev_Vector_base >_ZN7testing8internal18GetInjectableArgvsEv_ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EE6insertEN9__gnu_cxx17__normal_iteratorIPS2_S4_EERKS2__ZN9__gnu_cxx17__normal_iteratorIPKSsSt6vectorISsSaISsEEEppEi_ZN9__gnu_cxx17__normal_iteratorIPKPN7testing8TestInfoESt6vectorIS3_SaIS3_EEEpLEi_ZNKSt6vectorIN7testing12TestPropertyESaIS1_EE4rendEvrebind_ZN9__gnu_cxx17__normal_iteratorIPKSsSt6vectorISsSaISsEEEppEv_ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EE7reserveEj_ZNSt12_Vector_baseIPN7testing8TestCaseESaIS2_EE13_M_deallocateEPS2_j_ZNSt12_Vector_baseIN7testing14TestPartResultESaIS1_EE12_Vector_impl12_M_swap_dataERS4_Setupsuccessful_test_case_countstat_ZNSt6vectorIiSaIiEE4swapERS1_exceptionReadAndInterpretStatusByte_ZN7testing8internal18OsStackTraceGetter19kElidedFramesMarkerEsa_restorerallocator_ZNSt3setIPKcSt4lessIS1_ESaIS1_EE4swapERS5__M_node_ZNSs6assignEPKcj_ZN7testing8internal15GetUnitTestImplEvShuffleTests__iterator_categoryconst_pointer_ZNK9__gnu_cxx13new_allocatorIPN7testing8internal29ParameterizedTestCaseInfoBaseEE7addressERKS4_fgetws_ZNKSt3setIPKcSt4lessIS1_ESaIS1_EE13get_allocatorEvrand__cursummaryArrayAsVector<8>int_p_sign_posn_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE5eraseESt23_Rb_tree_const_iteratorIS1_E_ZN7testing8internal12UnitTestImpl11AddTestInfoEPFvvES3_PNS_8TestInfoE_ZNSt6vectorISsSaISsEE5eraseEN9__gnu_cxx17__normal_iteratorIPSsS1_EE_ZN9__gnu_cxx13new_allocatorIPN7testing11EnvironmentEE9constructEPS3_RKS3_GetReservedAttributesForElementmode_ZN9__gnu_cxx13new_allocatorIiE7destroyEPioperator<< _ZNSt6vectorIN7testing12TestPropertyESaIS1_EE4swapERS3_operator<< tm_sec__size_typekMaxParamLength_ZN9__gnu_cxx13new_allocatorIPKcE8allocateEjPKv__static_initialization_and_destruction_0new_allocator_ZN7testing8internal8GTestLogC2ENS0_16GTestLogSeverityEPKciactual_valueoperator<< _ZNSo3putEc_ZNK7testing10TestResult17test_part_resultsEvmessageTraceInfo__normal_iterator > >_ZN7testing22EmptyTestEventListener20OnTestIterationStartERKNS_8UnitTestEiFLAGS_gtest_shuffle_ZNSs7replaceEjjRKSs_ZN7testing8internal17StreamingListener12SocketWriteraSERKS2_new_allocator, std::allocator > > >value_paramArrayAsVector<6>_ZNSs4_Rep9_S_createEjjRKSaIcE__addressof >kValueParamLabel_Destroy_ZdlPv_ZNKSt3setIPKcSt4lessIS1_ESaIS1_EE8key_compEv_ZNKSbIwSt11char_traitsIwESaIwEE16find_last_not_ofEwjlist_tests__ZN9__gnu_cxx14__alloc_traitsISaIiEE8max_sizeERKS1_~ValueHolder_ZN7testing8internal18PrintCharAndCodeToIhaEEvT0_PSo_ZNKSt3setIPKcSt4lessIS1_ESaIS1_EE11upper_boundERKS1_term_supports_color_Rb_tree_increment_ZNKSt9_IdentityIPKcEclERS1__ZN9__gnu_cxx13new_allocatorISt13_Rb_tree_nodeIPKcEE9constructEPS4_RKS4__S_base_ZNSs7replaceEN9__gnu_cxx17__normal_iteratorIPcSsEES2_S2_S2__ZNKSt6vectorIN7testing8internal9TraceInfoESaIS2_EE4dataEv_ZNK7testing8internal12UnitTestImpl21total_test_case_countEv_ZNSt6vectorIPcSaIS0_EEixEj~OsStackTraceGetterkTestTypeIdInGoogleTestdeallocatemask_ZNKSt3setIPKcSt4lessIS1_ESaIS1_EE3endEv_Reppbase_ZN7testing8internal14ParseInt32FlagEPKcS2_Pi_ZN7testing8TestCaseC2EPKcS2_PFvvES4_AddTestPartResult__is_normal_iteratorfprintf_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE6_M_endEvtotal_part_count_ZNSt12_Vector_baseIN7testing8internal9TraceInfoESaIS2_EE17_M_create_storageEjnot_eofSkipSpacesnot_eolPrintToString_ZNSs4_Rep12_S_empty_repEvmon_decimal_pointcurrent_test_case_operator<< _ZNKSs17find_first_not_ofEPKcjoperator<< vector >unitbuf_ZNKSbIwSt11char_traitsIwESaIwEE8_M_checkEjPKcPartialMatchiterator_traits<__gnu_cxx::__normal_iterator > > >in_death_test_child_process~DefaultPerThreadTestPartResultReporter_ZNSs9_M_assignEPcjc_ZNK7testing8internal8FilePath14IsAbsolutePathEv_ZNSt11char_traitsIwE4findEPKwjRS1_ValidateTestPropertyNamereferencerfind_Referencewscanf_ZN7testing8internal12AssertHelperC2ENS_14TestPartResult4TypeEPKciS5___osize_DestroyToPrint_ZNK9__gnu_cxx13new_allocatorIiE7addressERKi_ZN7testing8internal8FilePath9NormalizeEv_ZN9__gnu_cxx17__normal_iteratorIPSsSt6vectorISsSaISsEEEppEi_ZNKSt6vectorIiSaIiEE5frontEv_ZN7testing8internal24XmlUnitTestResultPrinter26RemoveInvalidXmlCharactersERKSs__are_same_ZNK7testing8internal12UnitTestImpl16catch_exceptionsEvkRandomSeedFlag__iterator_category<__gnu_cxx::__normal_iterator*, std::vector > > >_ZlsRKN7testing8internal6SecretEi_ZN9__gnu_cxx17__normal_iteratorIPSsSt6vectorISsSaISsEEEppEv_ZNK7testing8UnitTest26successful_test_case_countEvoperator()<__gnu_cxx::__normal_iterator > >_S_showpoint_ZN7testing8internal17TestEventRepeater25OnEnvironmentsTearDownEndERKNS_8UnitTestE_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE11upper_boundERKS1__IO_lock_t_ZN9__gnu_cxx14__alloc_traitsISaIN7testing12TestPropertyEEE10_S_on_swapERS3_S5__ZN9__gnu_cxx13new_allocatorIPN7testing8internal29ParameterizedTestCaseInfoBaseEE8allocateEjPKv_ZN7testing8internal13DeathTestImpl11set_outcomeENS0_16DeathTestOutcomeE_ZN9__gnu_cxx24__numeric_traits_integerIiE5__minE_ZN7testing31TestPartResultReporterInterfaceaSERKS0__ZNSt12_Vector_baseIPN7testing11EnvironmentESaIS2_EE19_M_get_Tp_allocatorEv__copy_m_ZN7testing8internal23MakeAndRegisterTestInfoEPKcS2_S2_S2_PKvPFvvES6_PNS0_15TestFactoryBaseEnew_allocator_ZNK9__gnu_cxx13new_allocatorIN7testing14TestPartResultEE7addressERS2__ZNSt6vectorIN7testing12TestPropertyESaIS1_EE4backEvEventForwardingEnabled__alloc_traits >_Rb_tree_impl, false>_ZN7testing8internal8FilePath3SetERKS1_should_runstring_ZNKSt17_Rb_tree_iteratorISsEneERKS0_kTypeParamLabel__simplefork_ZNSt11char_traitsIcE4findEPKcjRS1___is_move_iteratorproperty_with_matching_keylong long int_ZNKSt3setIPKcSt4lessIS1_ESaIS1_EE8max_sizeEv_ZNSt16reverse_iteratorIN9__gnu_cxx17__normal_iteratorIPPN7testing11EnvironmentESt6vectorIS4_SaIS4_EEEEEmmEv_ZNSt6vectorIiSaIiEE8_M_eraseEN9__gnu_cxx17__normal_iteratorIPiS1_EES5_intptr_t_ZNKSt16reverse_iteratorIN9__gnu_cxx17__normal_iteratorIPPN7testing11EnvironmentESt6vectorIS4_SaIS4_EEEEE4baseEv_ZN7testing8internal26GoogleTestFailureExceptionD2Ev_ZNSt6vectorIPN7testing8TestCaseESaIS2_EE5clearEv_ZNKSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE11upper_boundERKS1__ZNSs7replaceEN9__gnu_cxx17__normal_iteratorIPcSsEES2_RKSs_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE6rbeginEv_ZN9__gnu_cxx17__normal_iteratorIPKPN7testing8TestCaseESt6vectorIS3_SaIS3_EEEpLEi_ZNK7testing8UnitTest21successful_test_countEv_ZN9__gnu_cxx13new_allocatorIN7testing8internal9TraceInfoEE7destroyEPS3__ZN9__gnu_cxx14__alloc_traitsISaIiEE8allocateERS1_jcopyMatchesFilteroperator<=19pthread_mutexattr_t_ZN7testing8internal2RED2Ev_ZN7testing10TestResult14RecordPropertyERKSsRKNS_12TestPropertyECountIf, bool (*)(const testing::TestPartResult&)>_ZNSt6vectorIN7testing12TestPropertyESaIS1_EE2atEjGNU C++ 4.9.2 20150212 (Red Hat 4.9.2-6) -mtune=generic -march=i686 -g -O2LastMessage_ZNKSt6vectorIPN7testing17TestEventListenerESaIS2_EE4rendEv_ZNK7testing8TestCase17failed_test_countEvscoped_ptr, std::allocator > >_Iter_basegtest_color_ZNKSs12find_last_ofEcj_ZNKSt23_Rb_tree_const_iteratorIPKcEneERKS2__ZN9__gnu_cxx13new_allocatorIN7testing8internal9TraceInfoEE10deallocateEPS3_j_ZNK7testing8internal13FloatingPointIdE13fraction_bitsEv_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE4swapERS7__ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE8_S_rightEPKSt18_Rb_tree_node_base_ZN7testing8internal8FilePathaSERKS1_vector >_ZNKSbIwSt11char_traitsIwESaIwEE6substrEjj_ZN7testing8internal11CmpHelperNEEPKcS2_xx_S_dec_DestroyFilterTestsfirst_test_nameTestCaseInfoContainer_ZNSt3setIPKcSt4lessIS1_ESaIS1_EE5clearEva_type_param_ZNK9__gnu_cxx13new_allocatorIN7testing8internal9TraceInfoEE7addressERS3__ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE12_M_rightmostEv_ZNKSt18_Bit_iterator_basegtERKS_GCC: (GNU) 4.9.2 20150212 (Red Hat 4.9.2-6)zR| 0DXl    4H\p$8L 0AnhP*Ah*Ah*Ah  4#H\p$8zPLR| @$0vAB Fc.[ AAA F D AAA A ACE LA(!AC$I(E,A0HC !ACK LA48NAA AkFA LJ AA4pPNAA AkFA LJ AA4NAA AkFA LJ AA4NAA AkFA LJ AA4@NAA AkFA LJ AA4PNAA AkFA LJ AA4OAA AvFA FF AA40OAA AvFA FF AA4OAA AvFA FF AA40OAA AvFA FF AA4h OAA AvFA FF AAHp[AA AAC o$F(A,A0L LAA AAHTAA AAC r$F(A,A0F HAA AA0800AA ENF FL AADl`mAA AAE0}AA APBA HJAA HI AA 0  @ % p   ( *AhD CV\  CVt 0 CV P CV p CV CV CV( !AC$I(E,A0HC$HAH8BAA CH NJG HG AA$0P(AA COA HGEA HG  AAE CEA HGEA HGEA HHE HAEA HGEA HGEA HGEA HGEA HGEA HGEA HF CAtHA AwAE HAAF TA  AAB CAAF HA  AAJ CE HKF s,CEB ]0,CEB ]0PDACIB HCBE ]At0AA AC { A AAD G,E0H L$A(E,E0J G,E0H C$A(E,E0H C A AAC pxAA CAH0(H&CAC `,D0HAG 4,"@>AB F. AAA A 4d"?AB Fy. AAA G <"AB Ch.L.R.c.R.`AAA @"A$2AB I{ AAA F ]. AAA G @ #EAB Fo.O AAA F G AAA A @d#EAB Fx.W AAA E F AAA G @#FtAB Ca. AAA A g AAA A L4(PHjAA AC T,D0H f C AAG LC AA0(HPAC P,D0H Z CC LCDp$IAB Im.y AAA K  AAA A D$AB F. AAA G L AAA A 4%JK?AB FL AAA H .48%0PAB Oo. AAA D 4p% SAB C. AAA F 8%VvAB Oo. AAA H r.8%Y9AB Or. AAA H z.4 &@]jAB IU.G AAA E 4X&_AB Iy.V AAA J (*KAC ],G0PAG <+KAA AC a,A0H E A AAH 4&aAB Fi. AAA E 04'd#AB Ec.r AA I 4h'eAB IO. AAA G 4'yLAB F[.f AAA C 0'WXAB E].N AA C 4 (uhAB Fc.d AAA C 4D(gtAB Ft AAA H a.4|(@iAB IP. AAA F 4( kAB CJ.j AAA C 4-lACWCHT- lOAC O$B(A,A0E,C E AK C$E(E,A0H EA4X)plwAB G[.[ H N A 4)lwAB G[.[ H N A 4)pmgAB CT.k AAA A 4*m5AB C~ AAA I A.@. p\CMBEA HE K C M CBEA HHx.pAA CAG$B(E,A0H ^,A0H G$B(E,A0H$B(E,A0H S$B(E,A0H CAA AA4@/ qTAA Cx  AAI C CA\x/qaAA COAA HBEA P GAJCBEA HC AA/q<+lAB C{..f. AAA I 4+rRAB Fe AAA G Z.U. 4,riAB Fe AAA G Z.U. x0sAA CAG4B8EJ AB FG AAA E d. AAA A D`8>q AB FG AAA E d. AAA A 48СI AB FL AAA H g.D8  AB F  AAA D d.u AAA A D(9 AB Fd. AAA D t AAA A Dp9 AB CN. AAA E } AAA A <9P0 AB E\.u AA E i AA A 49 G AB DM D N.v D 00:]W AB HZ. AA A @d:= AG Cn.\ AAA H g AAA F @:P AB Ci.[ AAA C V AAA C D:\ AB Cc. AAA D  AAA A D4;T AB C`. AAA C  AAA A D|;6AB Cl. AAA B  AAA A 4;=vAB F].y AAA F 4;AB Ih.] AAA D 04<AB H\.] AA J 4h<AB Ih.] AAA D 0<AB HU.] AA A 4<(AB Ih.] AAA D D =@BJAL F^.Q AAA C  AAA C 0T=AB Hj.] AA D D=VAB Cr.a AAA D ] AAA H (B/AHIED NC(DB ,AEIED NCD(>P6AB C`.a AAA F P AAA E (B-AHHDD NC(B*AEHDD NCP>}AB C^.Q.J..J.Z AAA I P AAA E (dCp-AHHDD NC(C*AEHDD NCDt?з4AB Cn. AAA H ] AAA H (D/AHIED NC(0D,AEIED NC4@rAB Ih.] AAA D 4L@AB Ih.] AAA D D@ 2AB Fv AAA F R. AAA J 4@HAB Ih.] AAA D 4A`jAB Fe AAA G Z.D"AB IZ.{.S.`.S.].S.Z AAA A  AAA A D]_"AB C\. AAA I _ AAA F 8 ^4#AB Fj.m AAA A .DH^dx#AB FN. AAA A  AAA A 4^h#AB Cl.R AAA I ch4^#YB Fd. AAA G \ci4(_#AB FY AAA K ^.ci(cFAA C ~ AA8_($AB Fj AAA J ..4_ id$AB I\.9 AAA D H`l$AB Ck.X.R. f AAA D c AAA A L``mX$AB Cb. U.i. M.S AAA G [ AAA B H` o$AB Ip.y. M.v AAA A I AAA A 4`q"%AB C`.y AAA A `4ar9%AB Fx.A. J.k AAA F ]. J.m AAA I K AAA B <awv%AB F AAA F R.c. e.4ay}%AB Di. Y G L A @b%AB Ec.I AA J T.J.h.J.{.f zACL AG KA JTBBD HLA JPBBD HC AC CA JPBBD HEA EJA EJA E@b &AB Ec.I AA J T.J.j.J.}.pg{AA FAE@YHILAPDLAHBLEPL@TDBHBLCPH@VLAPJ@[DAHALAPFLAHBLEPALAHFLAPI@M AA AAD CLAPH@OLAPE@RLAPE@$h|@cd&AB Ec.I AA J T.J.h.J.{.|h|AA AAEP_XI\A`PP[TAXA\A`F\AXB\E`QPcXA\A`HP`XB\E`A\D`PPWTAXA\A`F\CXA\A`TAA AAKPC\A`EPJ\A`EP4i~Te~&AB F AAA A V AAA A a. AAA A @Xe&AB Ec.I AA J T.J.j.J.}.0e`0'FB Bk.i AA H @e@>'AB Fn.| AAA J  AAA D \jІCL8,f~t'AB F.~ AAA A .Dhf'AB Fu.d AAA K  AAA G 8f'AB A_.a.M.Y F [ A 8f(AB Fj.| AAA A ^.8(gh4(AB F{.0 AAA A .4dg(AB FM.} AAA J 4g(AB Fv.d AAA J 4gP(AB Fv.d AAA J 4 h(AB Fy.d AAA G 8Dh(AB F`.g AAA A B.8h)AB Fm. AAA A =.HhЌl)AB FY AAA K r.t. .x AAA H <i)AB Eb.r AA B | AA B <Hip)AB BX.t AA E d AA A m0CHDDA H0iP)AB GR.h.M.y F (nAC,E0H$E(E,E0F,A(B,E0F,A(B,E0P,A(B,E0F,A(E,E0M$E(A,E0H$E(E,E0F,A(E,E0H$A(A,E0H$E(E,E0F,A(E,E0H$A(A,E0H$E(E,E0F,A(B,E0F,F(B,E0K,A(B,E0F,F(B,E0K,A(B,E0F,F(E,E0H$A(A,E0H$E(E,E0F,A(B,E0H$T(E,E0F,A(E,E0R$A(A,E0H$E(E,E0F,A(B,E0H$F(E,E0H$E(E,E0H$O(E,E0H$Y(E,E0RA.symtab.strtab.shstrtab.rel.text.data.bss.text.unlikely._ZNKSt5ctypeIcE8do_widenEc.text._ZNKSt5ctypeIcE8do_widenEc.text.unlikely._ZN7testing8internal26ThreadLocalValueHolderBaseD2Ev.text._ZN7testing8internal26ThreadLocalValueHolderBaseD2Ev.text.unlikely.DeleteThreadLocalValue.text.DeleteThreadLocalValue.text.unlikely._ZN7testing4Test11DeleteSelf_Ev.text._ZN7testing4Test11DeleteSelf_Ev.text.unlikely._ZN7testing4Test5SetupEv.text._ZN7testing4Test5SetupEv.text.unlikely._ZN7testing8TestCase16RunSetUpTestCaseEv.text._ZN7testing8TestCase16RunSetUpTestCaseEv.text.unlikely._ZN7testing8TestCase19RunTearDownTestCaseEv.text._ZN7testing8TestCase19RunTearDownTestCaseEv.text.unlikely._ZN7testing11EnvironmentD2Ev.text._ZN7testing11EnvironmentD2Ev.text.unlikely._ZN7testing11Environment5SetUpEv.text._ZN7testing11Environment5SetUpEv.text.unlikely._ZN7testing11Environment8TearDownEv.text._ZN7testing11Environment8TearDownEv.text.unlikely._ZN7testing11Environment5SetupEv.text._ZN7testing11Environment5SetupEv.text.unlikely._ZN7testing22EmptyTestEventListener18OnTestProgramStartERKNS_8UnitTestE.text._ZN7testing22EmptyTestEventListener18OnTestProgramStartERKNS_8UnitTestE.text.unlikely._ZN7testing22EmptyTestEventListener20OnTestIterationStartERKNS_8UnitTestEi.text._ZN7testing22EmptyTestEventListener20OnTestIterationStartERKNS_8UnitTestEi.text.unlikely._ZN7testing22EmptyTestEventListener24OnEnvironmentsSetUpStartERKNS_8UnitTestE.text._ZN7testing22EmptyTestEventListener24OnEnvironmentsSetUpStartERKNS_8UnitTestE.text.unlikely._ZN7testing22EmptyTestEventListener22OnEnvironmentsSetUpEndERKNS_8UnitTestE.text._ZN7testing22EmptyTestEventListener22OnEnvironmentsSetUpEndERKNS_8UnitTestE.text.unlikely._ZN7testing22EmptyTestEventListener15OnTestCaseStartERKNS_8TestCaseE.text._ZN7testing22EmptyTestEventListener15OnTestCaseStartERKNS_8TestCaseE.text.unlikely._ZN7testing22EmptyTestEventListener11OnTestStartERKNS_8TestInfoE.text._ZN7testing22EmptyTestEventListener11OnTestStartERKNS_8TestInfoE.text.unlikely._ZN7testing22EmptyTestEventListener16OnTestPartResultERKNS_14TestPartResultE.text._ZN7testing22EmptyTestEventListener16OnTestPartResultERKNS_14TestPartResultE.text.unlikely._ZN7testing22EmptyTestEventListener9OnTestEndERKNS_8TestInfoE.text._ZN7testing22EmptyTestEventListener9OnTestEndERKNS_8TestInfoE.text.unlikely._ZN7testing22EmptyTestEventListener13OnTestCaseEndERKNS_8TestCaseE.text._ZN7testing22EmptyTestEventListener13OnTestCaseEndERKNS_8TestCaseE.text.unlikely._ZN7testing22EmptyTestEventListener27OnEnvironmentsTearDownStartERKNS_8UnitTestE.text._ZN7testing22EmptyTestEventListener27OnEnvironmentsTearDownStartERKNS_8UnitTestE.text.unlikely._ZN7testing22EmptyTestEventListener25OnEnvironmentsTearDownEndERKNS_8UnitTestE.text._ZN7testing22EmptyTestEventListener25OnEnvironmentsTearDownEndERKNS_8UnitTestE.text.unlikely._ZN7testing22EmptyTestEventListener18OnTestIterationEndERKNS_8UnitTestEi.text._ZN7testing22EmptyTestEventListener18OnTestIterationEndERKNS_8UnitTestEi.text.unlikely._ZN7testing22EmptyTestEventListener16OnTestProgramEndERKNS_8UnitTestE.text._ZN7testing22EmptyTestEventListener16OnTestProgramEndERKNS_8UnitTestE.text.unlikely._ZN7testing8internal17StreamingListener20AbstractSocketWriter15CloseConnectionEv.text._ZN7testing8internal17StreamingListener20AbstractSocketWriter15CloseConnectionEv.text.unlikely._ZN7testing22EmptyTestEventListenerD2Ev.text._ZN7testing22EmptyTestEventListenerD2Ev.rel.text.unlikely.text.unlikely._ZN7testing8internal27PrettyUnitTestResultPrinter18OnTestProgramStartERKNS_8UnitTestE.text._ZN7testing8internal27PrettyUnitTestResultPrinter18OnTestProgramStartERKNS_8UnitTestE.text.unlikely._ZN7testing8internal27PrettyUnitTestResultPrinter22OnEnvironmentsSetUpEndERKNS_8UnitTestE.text._ZN7testing8internal27PrettyUnitTestResultPrinter22OnEnvironmentsSetUpEndERKNS_8UnitTestE.text.unlikely._ZN7testing8internal27PrettyUnitTestResultPrinter25OnEnvironmentsTearDownEndERKNS_8UnitTestE.text._ZN7testing8internal27PrettyUnitTestResultPrinter25OnEnvironmentsTearDownEndERKNS_8UnitTestE.text.unlikely._ZN7testing8internal27PrettyUnitTestResultPrinter16OnTestProgramEndERKNS_8UnitTestE.text._ZN7testing8internal27PrettyUnitTestResultPrinter16OnTestProgramEndERKNS_8UnitTestE.text.unlikely._ZN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE11ValueHolderD2Ev.text._ZN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE11ValueHolderD2Ev.text.unlikely._ZN7testing8internal23DefaultDeathTestFactoryD2Ev.text._ZN7testing8internal23DefaultDeathTestFactoryD2Ev.text.unlikely._ZN7testing8internal27PrettyUnitTestResultPrinterD2Ev.text._ZN7testing8internal27PrettyUnitTestResultPrinterD2Ev.text.unlikely._ZN7testing8internal38DefaultPerThreadTestPartResultReporterD2Ev.text._ZN7testing8internal38DefaultPerThreadTestPartResultReporterD2Ev.text.unlikely._ZN7testing8internal35DefaultGlobalTestPartResultReporterD2Ev.text._ZN7testing8internal35DefaultGlobalTestPartResultReporterD2Ev.text.unlikely._ZN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE11ValueHolderD0Ev.rel.text._ZN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE11ValueHolderD0Ev.text.unlikely._ZN7testing8internal26ThreadLocalValueHolderBaseD0Ev.rel.text._ZN7testing8internal26ThreadLocalValueHolderBaseD0Ev.text.unlikely._ZN7testing11EnvironmentD0Ev.rel.text._ZN7testing11EnvironmentD0Ev.text.unlikely._ZN7testing8internal23DefaultDeathTestFactoryD0Ev.rel.text._ZN7testing8internal23DefaultDeathTestFactoryD0Ev.text.unlikely._ZN7testing8internal38DefaultPerThreadTestPartResultReporterD0Ev.rel.text._ZN7testing8internal38DefaultPerThreadTestPartResultReporterD0Ev.text.unlikely._ZN7testing8internal35DefaultGlobalTestPartResultReporterD0Ev.rel.text._ZN7testing8internal35DefaultGlobalTestPartResultReporterD0Ev.text.unlikely._ZN7testing8internal27PrettyUnitTestResultPrinterD0Ev.rel.text._ZN7testing8internal27PrettyUnitTestResultPrinterD0Ev.text.unlikely._ZN7testing22EmptyTestEventListenerD0Ev.rel.text._ZN7testing22EmptyTestEventListenerD0Ev.rel.gcc_except_table.rodata.str1.1.text.unlikely._ZN7testing8internal26GoogleTestFailureExceptionD2Ev.rel.text._ZN7testing8internal26GoogleTestFailureExceptionD2Ev.text.unlikely._ZN7testing8internal26GoogleTestFailureExceptionD0Ev.rel.text._ZN7testing8internal26GoogleTestFailureExceptionD0Ev.text.unlikely._ZN7testing8internal24XmlUnitTestResultPrinterD2Ev.rel.text._ZN7testing8internal24XmlUnitTestResultPrinterD2Ev.text.unlikely._ZN7testing8internal24XmlUnitTestResultPrinterD0Ev.rel.text._ZN7testing8internal24XmlUnitTestResultPrinterD0Ev.text.unlikely._ZN7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEE11ValueHolderD2Ev.rel.text._ZN7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEE11ValueHolderD2Ev.text.unlikely._ZN7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEE11ValueHolderD0Ev.rel.text._ZN7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEE11ValueHolderD0Ev.text.unlikely._ZNSt6vectorISsSaISsEED2Ev.rel.text._ZNSt6vectorISsSaISsEED2Ev.rodata.str1.4.text.unlikely._ZN7testing8internal29ParameterizedTestCaseRegistryD2Ev.rel.text._ZN7testing8internal29ParameterizedTestCaseRegistryD2Ev.text.unlikely._ZN7testing15AssertionResult13AppendMessageERKNS_7MessageE.rel.text._ZN7testing15AssertionResult13AppendMessageERKNS_7MessageE.text.unlikely._ZN7testing14TestPartResultD2Ev.rel.text._ZN7testing14TestPartResultD2Ev.text.unlikely._ZN7testing12TestPropertyD2Ev.rel.text._ZN7testing12TestPropertyD2Ev.text.unlikely._ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEED2Ev.rel.text._ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEED2Ev.text.unlikely._ZN7testing7MessageC2ERKS0_.rel.text._ZN7testing7MessageC2ERKS0_.rel.rodata.text.unlikely._ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEED0Ev.rel.text._ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEED0Ev.text.unlikely._ZN7testing8internal10scoped_ptrISsE5resetEPSs.rel.text._ZN7testing8internal10scoped_ptrISsE5resetEPSs.text.unlikely._ZN7testing8internal10scoped_ptrINS0_24InternalRunDeathTestFlagEE5resetEPS2_.rel.text._ZN7testing8internal10scoped_ptrINS0_24InternalRunDeathTestFlagEE5resetEPS2_.text.unlikely._ZStplIcSt11char_traitsIcESaIcEESbIT_T0_T1_ERKS6_PKS3_.rel.text._ZStplIcSt11char_traitsIcESaIcEESbIT_T0_T1_ERKS6_PKS3_.text.unlikely._ZStplIcSt11char_traitsIcESaIcEESbIT_T0_T1_EPKS3_RKS6_.rel.text._ZStplIcSt11char_traitsIcESaIcEESbIT_T0_T1_EPKS3_RKS6_.text.unlikely._ZN7testing13PrintToStringIPKcEESsRKT_.rel.text._ZN7testing13PrintToStringIPKcEESsRKT_.text.unlikely._ZN7testing13PrintToStringIPKwEESsRKT_.rel.text._ZN7testing13PrintToStringIPKwEESsRKT_.text.unlikely._ZN7testing8internal18StreamableToStringIiEESsRKT_.rel.text._ZN7testing8internal18StreamableToStringIiEESsRKT_.text.unlikely._ZN7testing8internal18StreamableToStringIxEESsRKT_.rel.text._ZN7testing8internal18StreamableToStringIxEESsRKT_.text.unlikely._ZStplIcSt11char_traitsIcESaIcEESbIT_T0_T1_ERKS6_S8_.rel.text._ZStplIcSt11char_traitsIcESaIcEESbIT_T0_T1_ERKS6_S8_.text.unlikely._ZN7testing8internal17StreamingListener12SocketWriter15CloseConnectionEv.rel.text._ZN7testing8internal17StreamingListener12SocketWriter15CloseConnectionEv.text.unlikely._ZN7testing8internal5MutexD2Ev.rel.text._ZN7testing8internal5MutexD2Ev.text.unlikely._ZN7testing8internal9MutexBase6UnlockEv.rel.text._ZN7testing8internal9MutexBase6UnlockEv.text.unlikely._ZN7testing8internal9MutexBase4LockEv.rel.text._ZN7testing8internal9MutexBase4LockEv.text.unlikely._ZN7testing8internal17StreamingListener12SocketWriter4SendERKSs.rel.text._ZN7testing8internal17StreamingListener12SocketWriter4SendERKSs.text.unlikely._ZN7testing8internal17StreamingListener12SocketWriterD2Ev.rel.text._ZN7testing8internal17StreamingListener12SocketWriterD2Ev.text.unlikely._ZN7testing8internal17StreamingListener12SocketWriterD0Ev.rel.text._ZN7testing8internal17StreamingListener12SocketWriterD0Ev.text.unlikely._ZN7testing8internal17StreamingListenerD2Ev.rel.text._ZN7testing8internal17StreamingListenerD2Ev.text.unlikely._ZN7testing8internal17StreamingListenerD0Ev.rel.text._ZN7testing8internal17StreamingListenerD0Ev.text.unlikely._ZN7testing8internal17StreamingListener20AbstractSocketWriter6SendLnERKSs.rel.text._ZN7testing8internal17StreamingListener20AbstractSocketWriter6SendLnERKSs.text.unlikely._ZN7testing8internal17StreamingListener11OnTestStartERKNS_8TestInfoE.rel.text._ZN7testing8internal17StreamingListener11OnTestStartERKNS_8TestInfoE.text.unlikely._ZN7testing8internal17StreamingListener15OnTestCaseStartERKNS_8TestCaseE.rel.text._ZN7testing8internal17StreamingListener15OnTestCaseStartERKNS_8TestCaseE.text.unlikely._ZN7testing8internal17StreamingListener16OnTestProgramEndERKNS_8UnitTestE.rel.text._ZN7testing8internal17StreamingListener16OnTestProgramEndERKNS_8UnitTestE.text.unlikely._ZN7testing8internal17StreamingListener16OnTestPartResultERKNS_14TestPartResultE.rel.text._ZN7testing8internal17StreamingListener16OnTestPartResultERKNS_14TestPartResultE.text.unlikely._ZN7testing8internal17StreamingListener20OnTestIterationStartERKNS_8UnitTestEi.rel.text._ZN7testing8internal17StreamingListener20OnTestIterationStartERKNS_8UnitTestEi.text.unlikely._ZN7testing8internal18OsStackTraceGetterD2Ev.rel.text._ZN7testing8internal18OsStackTraceGetterD2Ev.text.unlikely._ZN7testing8internal18OsStackTraceGetterD0Ev.rel.text._ZN7testing8internal18OsStackTraceGetterD0Ev.text.unlikely._ZN7testing8internal17StreamingListener18OnTestProgramStartERKNS_8UnitTestE.rel.text._ZN7testing8internal17StreamingListener18OnTestProgramStartERKNS_8UnitTestE.text.unlikely._ZN7testing8internal17StreamingListener9OnTestEndERKNS_8TestInfoE.rel.text._ZN7testing8internal17StreamingListener9OnTestEndERKNS_8TestInfoE.text.unlikely._ZN7testing8internal17StreamingListener13OnTestCaseEndERKNS_8TestCaseE.rel.text._ZN7testing8internal17StreamingListener13OnTestCaseEndERKNS_8TestCaseE.text.unlikely._ZN7testing8internal17StreamingListener18OnTestIterationEndERKNS_8UnitTestEi.rel.text._ZN7testing8internal17StreamingListener18OnTestIterationEndERKNS_8UnitTestEi.text.unlikely._ZN7testing15AssertionResultlsINS_7MessageEEERS0_RKT_.rel.text._ZN7testing15AssertionResultlsINS_7MessageEEERS0_RKT_.text.unlikely._ZN7testing15AssertionResultlsIA11_cEERS0_RKT_.rel.text._ZN7testing15AssertionResultlsIA11_cEERS0_RKT_.text.unlikely._ZN7testing15AssertionResultlsISsEERS0_RKT_.rel.text._ZN7testing15AssertionResultlsISsEERS0_RKT_.text.unlikely._ZN7testing15AssertionResultlsIA2_cEERS0_RKT_.rel.text._ZN7testing15AssertionResultlsIA2_cEERS0_RKT_.text.unlikely._ZN7testing15AssertionResultlsINS_14TestPartResultEEERS0_RKT_.rel.text._ZN7testing15AssertionResultlsINS_14TestPartResultEEERS0_RKT_.text.unlikely._ZN7testing15AssertionResultlsIA3_cEERS0_RKT_.rel.text._ZN7testing15AssertionResultlsIA3_cEERS0_RKT_.text.unlikely._ZN7testing15AssertionResultlsIPKcEERS0_RKT_.rel.text._ZN7testing15AssertionResultlsIPKcEERS0_RKT_.text.unlikely._ZN7testing15AssertionResultlsIA5_cEERS0_RKT_.rel.text._ZN7testing15AssertionResultlsIA5_cEERS0_RKT_.text.unlikely._ZN7testing15AssertionResultlsIA7_cEERS0_RKT_.rel.text._ZN7testing15AssertionResultlsIA7_cEERS0_RKT_.text.unlikely._ZN7testing15AssertionResultlsIA12_cEERS0_RKT_.rel.text._ZN7testing15AssertionResultlsIA12_cEERS0_RKT_.text.unlikely._ZN7testing8internal15FloatingPointLEIfEENS_15AssertionResultEPKcS4_T_S5_.rel.text._ZN7testing8internal15FloatingPointLEIfEENS_15AssertionResultEPKcS4_T_S5_.text.unlikely._ZN7testing8internal15FloatingPointLEIdEENS_15AssertionResultEPKcS4_T_S5_.rel.text._ZN7testing8internal15FloatingPointLEIdEENS_15AssertionResultEPKcS4_T_S5_.text.unlikely._ZN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEED2Ev.rel.text._ZN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEED2Ev.text.unlikely._ZN7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEED2Ev.rel.text._ZN7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEED2Ev.text.unlikely._ZN7testing8internal12ShuffleRangeIiEEvPNS0_6RandomEiiPSt6vectorIT_SaIS5_EE.rel.text._ZN7testing8internal12ShuffleRangeIiEEvPNS0_6RandomEiiPSt6vectorIT_SaIS5_EE.text.unlikely._ZN7testing8internal18ParseNaturalNumberIiEEbRKSsPT_.rel.text._ZN7testing8internal18ParseNaturalNumberIiEEbRKSsPT_.text.unlikely._ZN7testing8internal18PrintCharAndCodeToIhhEEvT0_PSo.rel.text._ZN7testing8internal18PrintCharAndCodeToIhhEEvT0_PSo.rel.rodata._ZN7testing8internal18PrintCharAndCodeToIhhEEvT0_PSo.text.unlikely._ZN7testing8internal18PrintCharAndCodeToIhaEEvT0_PSo.rel.text._ZN7testing8internal18PrintCharAndCodeToIhaEEvT0_PSo.rel.rodata._ZN7testing8internal18PrintCharAndCodeToIhaEEvT0_PSo.text.unlikely._ZN7testing8internal18PrintCharAndCodeToIwwEEvT0_PSo.rel.text._ZN7testing8internal18PrintCharAndCodeToIwwEEvT0_PSo.text.unlikely._ZN7testing8internal10scoped_ptrIKSsE5resetEPS2_.rel.text._ZN7testing8internal10scoped_ptrIKSsE5resetEPS2_.text.unlikely._ZNSt6vectorIPN7testing8TestInfoESaIS2_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS2_S4_EERKS2_.rel.text._ZNSt6vectorIPN7testing8TestInfoESaIS2_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS2_S4_EERKS2_.text.unlikely._ZNSt6vectorIiSaIiEE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPiS1_EERKi.rel.text._ZNSt6vectorIiSaIiEE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPiS1_EERKi.text.unlikely._ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS2_S4_EERKS2_.rel.text._ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS2_S4_EERKS2_.text.unlikely._ZN7testing8internal15NoExecDeathTestD2Ev.rel.text._ZN7testing8internal15NoExecDeathTestD2Ev.text.unlikely._ZN7testing8internal13ExecDeathTestD2Ev.rel.text._ZN7testing8internal13ExecDeathTestD2Ev.text.unlikely._ZN7testing8internal15NoExecDeathTestD0Ev.rel.text._ZN7testing8internal15NoExecDeathTestD0Ev.text.unlikely._ZN7testing8internal13ExecDeathTestD0Ev.rel.text._ZN7testing8internal13ExecDeathTestD0Ev.text.unlikely._ZNSt6vectorIPN7testing11EnvironmentESaIS2_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS2_S4_EERKS2_.rel.text._ZNSt6vectorIPN7testing11EnvironmentESaIS2_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS2_S4_EERKS2_.text.unlikely._ZNSt6vectorIPN7testing8TestCaseESaIS2_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS2_S4_EERKS2_.rel.text._ZNSt6vectorIPN7testing8TestCaseESaIS2_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS2_S4_EERKS2_.text.unlikely._ZN7testing8internal18StreamableToStringIPcEESsRKT_.rel.text._ZN7testing8internal18StreamableToStringIPcEESsRKT_.text.unlikely._ZNSt6vectorIPcSaIS0_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS0_S2_EERKS0_.rel.text._ZNSt6vectorIPcSaIS0_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS0_S2_EERKS0_.text.unlikely._ZNSt6vectorIPcSaIS0_EE6insertEN9__gnu_cxx17__normal_iteratorIPS0_S2_EERKS0_.rel.text._ZNSt6vectorIPcSaIS0_EE6insertEN9__gnu_cxx17__normal_iteratorIPS0_S2_EERKS0_.text.unlikely._ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE8_M_eraseEPSt13_Rb_tree_nodeISsE.rel.text._ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE8_M_eraseEPSt13_Rb_tree_nodeISsE.text.unlikely._ZNKSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE4findERKSs.rel.text._ZNKSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE4findERKSs.text.unlikely._ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE16_M_insert_uniqueERKSs.rel.text._ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE16_M_insert_uniqueERKSs.text.unlikely._ZN7testing8internal27CheckedDowncastToActualTypeINS0_11ThreadLocalISt6vectorINS0_9TraceInfoESaIS4_EEE11ValueHolderENS0_26ThreadLocalValueHolderBaseEEEPT_PT0_.rel.text._ZN7testing8internal27CheckedDowncastToActualTypeINS0_11ThreadLocalISt6vectorINS0_9TraceInfoESaIS4_EEE11ValueHolderENS0_26ThreadLocalValueHolderBaseEEEPT_PT0_.text.unlikely._ZN7testing13PrintToStringIxEESsRKT_.rel.text._ZN7testing13PrintToStringIxEESsRKT_.text.unlikely._ZSt9__find_ifIN9__gnu_cxx17__normal_iteratorIPN7testing12TestPropertyESt6vectorIS3_SaIS3_EEEENS0_5__ops10_Iter_predINS2_8internal17TestPropertyKeyIsEEEET_SE_SE_T0_St26random_access_iterator_tag.rel.text._ZSt9__find_ifIN9__gnu_cxx17__normal_iteratorIPN7testing12TestPropertyESt6vectorIS3_SaIS3_EEEENS0_5__ops10_Iter_predINS2_8internal17TestPropertyKeyIsEEEET_SE_SE_T0_St26random_access_iterator_tag.text.unlikely._ZSt9__find_ifIN9__gnu_cxx17__normal_iteratorIPKSsSt6vectorISsSaISsEEEENS0_5__ops16_Iter_equals_valIS2_EEET_SB_SB_T0_St26random_access_iterator_tag.rel.text._ZSt9__find_ifIN9__gnu_cxx17__normal_iteratorIPKSsSt6vectorISsSaISsEEEENS0_5__ops16_Iter_equals_valIS2_EEET_SB_SB_T0_St26random_access_iterator_tag.text.unlikely._ZSt9__find_ifIN9__gnu_cxx17__normal_iteratorIPPN7testing8TestCaseESt6vectorIS4_SaIS4_EEEENS0_5__ops10_Iter_predINS2_8internal14TestCaseNameIsEEEET_SF_SF_T0_St26random_access_iterator_tag.rel.text._ZSt9__find_ifIN9__gnu_cxx17__normal_iteratorIPPN7testing8TestCaseESt6vectorIS4_SaIS4_EEEENS0_5__ops10_Iter_predINS2_8internal14TestCaseNameIsEEEET_SF_SF_T0_St26random_access_iterator_tag.text.unlikely._ZNSs12_S_constructIPKcEEPcT_S3_RKSaIcESt20forward_iterator_tag.rel.text._ZNSs12_S_constructIPKcEEPcT_S3_RKSaIcESt20forward_iterator_tag.text.unlikely._ZN7testing8internal28ParseGoogleTestFlagsOnlyImplIwEEvPiPPT_.rel.text._ZN7testing8internal28ParseGoogleTestFlagsOnlyImplIwEEvPiPPT_.text.unlikely._ZN7testing8internal28ParseGoogleTestFlagsOnlyImplIcEEvPiPPT_.rel.text._ZN7testing8internal28ParseGoogleTestFlagsOnlyImplIcEEvPiPPT_.text.unlikely._ZN7testing8internal27CheckedDowncastToActualTypeINS0_11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE11ValueHolderENS0_26ThreadLocalValueHolderBaseEEEPT_PT0_.rel.text._ZN7testing8internal27CheckedDowncastToActualTypeINS0_11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE11ValueHolderENS0_26ThreadLocalValueHolderBaseEEEPT_PT0_.text.unlikely._ZNK7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE16GetOrCreateValueEv.rel.text._ZNK7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE16GetOrCreateValueEv.text.unlikely._ZNSt12_Destroy_auxILb0EE9__destroyIPSsEEvT_S3_.rel.text._ZNSt12_Destroy_auxILb0EE9__destroyIPSsEEvT_S3_.text.unlikely._ZNSt6vectorISsSaISsEE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPSsS1_EERKSs.rel.text._ZNSt6vectorISsSaISsEE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPSsS1_EERKSs.text.unlikely._ZN7testing8internal18InitGoogleTestImplIcEEvPiPPT_.rel.text._ZN7testing8internal18InitGoogleTestImplIcEEvPiPPT_.text.unlikely._ZN7testing8internal18InitGoogleTestImplIwEEvPiPPT_.rel.text._ZN7testing8internal18InitGoogleTestImplIwEEvPiPPT_.text.unlikely._ZNSt12_Destroy_auxILb0EE9__destroyIPN7testing8internal9TraceInfoEEEvT_S6_.rel.text._ZNSt12_Destroy_auxILb0EE9__destroyIPN7testing8internal9TraceInfoEEEvT_S6_.text.unlikely._ZNK7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEE16GetOrCreateValueEv.rel.text._ZNK7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEE16GetOrCreateValueEv.text.unlikely._ZN7testing8internal35HandleExceptionsInMethodIfSupportedINS_4TestEvEET0_PT_MS4_FS3_vEPKc.rel.text._ZN7testing8internal35HandleExceptionsInMethodIfSupportedINS_4TestEvEET0_PT_MS4_FS3_vEPKc.text.unlikely._ZN7testing8internal35HandleExceptionsInMethodIfSupportedINS0_15TestFactoryBaseEPNS_4TestEEET0_PT_MS6_FS5_vEPKc.rel.text._ZN7testing8internal35HandleExceptionsInMethodIfSupportedINS0_15TestFactoryBaseEPNS_4TestEEET0_PT_MS6_FS5_vEPKc.text.unlikely._ZN7testing8internal35HandleExceptionsInMethodIfSupportedINS_8TestCaseEvEET0_PT_MS4_FS3_vEPKc.rel.text._ZN7testing8internal35HandleExceptionsInMethodIfSupportedINS_8TestCaseEvEET0_PT_MS4_FS3_vEPKc.text.unlikely._ZN7testing8internal35HandleExceptionsInMethodIfSupportedINS0_12UnitTestImplEbEET0_PT_MS4_FS3_vEPKc.rel.text._ZN7testing8internal35HandleExceptionsInMethodIfSupportedINS0_12UnitTestImplEbEET0_PT_MS4_FS3_vEPKc.text.unlikely._ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS2_S4_EERKS2_.rel.text._ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS2_S4_EERKS2_.text.unlikely._ZNSt20__uninitialized_copyILb0EE13__uninit_copyIPN7testing14TestPartResultES4_EET0_T_S6_S5_.rel.text._ZNSt20__uninitialized_copyILb0EE13__uninit_copyIPN7testing14TestPartResultES4_EET0_T_S6_S5_.text.unlikely._ZNSt6vectorIN7testing14TestPartResultESaIS1_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS1_S3_EERKS1_.rel.text._ZNSt6vectorIN7testing14TestPartResultESaIS1_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS1_S3_EERKS1_.text.unlikely._ZNSt20__uninitialized_copyILb0EE13__uninit_copyIPN7testing12TestPropertyES4_EET0_T_S6_S5_.rel.text._ZNSt20__uninitialized_copyILb0EE13__uninit_copyIPN7testing12TestPropertyES4_EET0_T_S6_S5_.text.unlikely._ZNSt6vectorIN7testing12TestPropertyESaIS1_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS1_S3_EERKS1_.rel.text._ZNSt6vectorIN7testing12TestPropertyESaIS1_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS1_S3_EERKS1_.rel.text.startup.rel.init_array.bss._ZN7testing8internal12TypeIdHelperINS_4TestEE6dummy_E.rel.rodata._ZTIN7testing8internal26ThreadLocalValueHolderBaseE.rodata._ZTSN7testing8internal26ThreadLocalValueHolderBaseE.rel.rodata._ZTIN7testing8internal26GoogleTestFailureExceptionE.rodata._ZTSN7testing8internal26GoogleTestFailureExceptionE.rel.rodata._ZTIN7testing8internal9DeathTestE.rodata._ZTSN7testing8internal9DeathTestE.rel.rodata._ZTIN7testing8internal16DeathTestFactoryE.rodata._ZTSN7testing8internal16DeathTestFactoryE.rodata._ZTSN7testing8internal23DefaultDeathTestFactoryE.rel.rodata._ZTIN7testing8internal23DefaultDeathTestFactoryE.rel.rodata._ZTIN7testing31TestPartResultReporterInterfaceE.rodata._ZTSN7testing31TestPartResultReporterInterfaceE.rodata._ZTSN7testing8internal24HasNewFatalFailureHelperE.rel.rodata._ZTIN7testing8internal24HasNewFatalFailureHelperE.rodata._ZTSN7testing4TestE.rel.rodata._ZTIN7testing4TestE.rodata._ZTSN7testing8TestCaseE.rel.rodata._ZTIN7testing8TestCaseE.rel.rodata._ZTIN7testing17TestEventListenerE.rodata._ZTSN7testing17TestEventListenerE.rel.rodata._ZTIN7testing22EmptyTestEventListenerE.rodata._ZTSN7testing22EmptyTestEventListenerE.rodata._ZTSN7testing8UnitTestE.rel.rodata._ZTIN7testing8UnitTestE.rodata._ZTSN7testing32ScopedFakeTestPartResultReporterE.rel.rodata._ZTIN7testing32ScopedFakeTestPartResultReporterE.rel.rodata._ZTIN7testing8internal27OsStackTraceGetterInterfaceE.rodata._ZTSN7testing8internal27OsStackTraceGetterInterfaceE.rodata._ZTSN7testing8internal18OsStackTraceGetterE.rel.rodata._ZTIN7testing8internal18OsStackTraceGetterE.rodata._ZTSN7testing8internal35DefaultGlobalTestPartResultReporterE.rel.rodata._ZTIN7testing8internal35DefaultGlobalTestPartResultReporterE.rodata._ZTSN7testing8internal38DefaultPerThreadTestPartResultReporterE.rel.rodata._ZTIN7testing8internal38DefaultPerThreadTestPartResultReporterE.rodata._ZTSN7testing8internal12UnitTestImplE.rel.rodata._ZTIN7testing8internal12UnitTestImplE.rel.rodata._ZTIN7testing8internal17StreamingListener20AbstractSocketWriterE.rodata._ZTSN7testing8internal17StreamingListener20AbstractSocketWriterE.rel.rodata._ZTIN7testing8internal17StreamingListener12SocketWriterE.rodata._ZTSN7testing8internal17StreamingListener12SocketWriterE.rel.rodata._ZTIN7testing8internal17StreamingListenerE.rodata._ZTSN7testing8internal17StreamingListenerE.rodata._ZTSN7testing8internal27PrettyUnitTestResultPrinterE.rel.rodata._ZTIN7testing8internal27PrettyUnitTestResultPrinterE.rodata._ZTSN7testing8internal17TestEventRepeaterE.rel.rodata._ZTIN7testing8internal17TestEventRepeaterE.rodata._ZTSN7testing8internal24XmlUnitTestResultPrinterE.rel.rodata._ZTIN7testing8internal24XmlUnitTestResultPrinterE.rodata._ZTSN7testing8internal13DeathTestImplE.rel.rodata._ZTIN7testing8internal13DeathTestImplE.rodata._ZTSN7testing8internal16ForkingDeathTestE.rel.rodata._ZTIN7testing8internal16ForkingDeathTestE.rodata._ZTSN7testing8internal15NoExecDeathTestE.rel.rodata._ZTIN7testing8internal15NoExecDeathTestE.rodata._ZTSN7testing8internal13ExecDeathTestE.rel.rodata._ZTIN7testing8internal13ExecDeathTestE.rel.rodata._ZTIN7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEE11ValueHolderE.rodata._ZTSN7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEE11ValueHolderE.rel.rodata._ZTIN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE11ValueHolderE.rodata._ZTSN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE11ValueHolderE.rel.rodata._ZTVN7testing8internal26GoogleTestFailureExceptionE.rel.rodata._ZTVN7testing8internal9DeathTestE.rel.rodata._ZTVN7testing8internal17StreamingListener12SocketWriterE.rel.rodata._ZTVN7testing8internal17StreamingListenerE.rel.rodata._ZTVN7testing32ScopedFakeTestPartResultReporterE.rel.rodata._ZTVN7testing8internal35DefaultGlobalTestPartResultReporterE.rel.rodata._ZTVN7testing8internal38DefaultPerThreadTestPartResultReporterE.rel.rodata._ZTVN7testing4TestE.rel.rodata._ZTVN7testing8TestCaseE.rel.rodata._ZTVN7testing8internal27PrettyUnitTestResultPrinterE.rel.rodata._ZTVN7testing8internal17TestEventRepeaterE.rel.rodata._ZTVN7testing8internal24XmlUnitTestResultPrinterE.rel.rodata._ZTVN7testing8internal18OsStackTraceGetterE.rel.rodata._ZTVN7testing8UnitTestE.rel.rodata._ZTVN7testing8internal12UnitTestImplE.rel.rodata._ZTVN7testing8internal13DeathTestImplE.rel.rodata._ZTVN7testing8internal16ForkingDeathTestE.rel.rodata._ZTVN7testing8internal15NoExecDeathTestE.rel.rodata._ZTVN7testing8internal13ExecDeathTestE.rel.rodata._ZTVN7testing8internal23DefaultDeathTestFactoryE.rel.rodata._ZTVN7testing8internal24HasNewFatalFailureHelperE.rel.rodata._ZTVN7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEE11ValueHolderE.rel.rodata._ZTVN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE11ValueHolderE.rodata.cst4.rel.debug_info.debug_abbrev.rel.debug_loc.rel.debug_aranges.rel.debug_ranges.rel.debug_line.debug_str.comment.note.GNU-stack.rel.eh_frame.groupn4 n@nT n` nl nx n nn n n n n n n n n n n n( n4 n@ nL nX nd npn n n n nnnnnnn,n@nT n` nl pnx n nn n Yn ]n ^n _n mn sn yn |n n n( n4 n@ nL nXnln n n n n n nn n n n n  n n$ n0 n< nH nT n` nl nx n n n n n n nnn n n n n n(n<nP In\ Knh Lnt Mn Nn On Pn Rn Xn ^n en fn gn jn un xn zn }n( n4 n@ nL nX nd np n| n n n n n n n nGn[nnnnn nnn$n,n4n<nDnLnTn\ndnlntn|nnnnnnnnnnnnnnnnnn nnn$n,n4n<nD nL nT n\ nd nlntn|nnnnnZnYn|n{nn8nnnnLnOn~n n n  n 'n$ n, n4 n< 1nD ;nL BnT Cn\ nd nl ,nt ~ Q $`%ќ+ 0Z{ =l 2@DP @Z{` jpr,S^WНҝc TG + "} 0 2& @} B P0 R ` b, px r / f   x x h1c'ŸПҟFf $y  '&,0( *O6@ -F P 0gV` $3fEpA ,6v 49* <@;24WS |?! B[ -W ENPG (H|bx  KAk= (N|Y ,Q2`F`tB DU \hXF~B ģ@[lNPV (^ C ,(aDso Td@ @ df K 0i$lfpKb $ly <8oN 9 @W t0r !u! @u\!! l! x!!! t{*"_p"`nl"  ~""r" 4 (#B p#P Ll# T(# $ $ |`V$0 $0 $ ܮp$ $ $ Lp%X O%` K% x{% % "% 4&" a&0 ]& `& & & \h.'m'i' ıp'~'' 4x(`m(`i( ()) `))) < *h* d* *+1+ Ls++ + p*,j,f, |x,,, -*o-0k- t@-4.@\. x^..T. ,x/ e/!a/ /#0#=/ $=0%0%{0 x0,&00&0 ,h%1,'f10'b1 x1L(1P(1 h/2<)p2@)l2 tx2\*2`*2 3|+X3+T3 lx3,3,3 x4-C4-?4 \xx4.4.R4 %5275@7 ~5 d5F@36P@/6 x6A6A=6 l27=B7@B7 @73D+8@Dm'8 Tf8D8Dc8 d8Ht8 D*9Ir9Ikn9 ,9Lt9 9pN6:pN2: q:nO:pOK: :Of;Ohb; (;(Q4<0Qf0< ( <R =Rh= ( =T=T\= =lU+>pU\'> Y>V>Vh> >8X?@Xh> /?Y?Yh? (@[@ [h@ (A\LA\HA 8!A6]A@]hA T($IB^B^tB |'B$_eC0__aC  *C_D_D -\Dh`Dp`D h0EcbEpbE p3fF cFcF `6FeGeEG 89hH5gI@g I $8<IixJixtJ \8?:KjKjK 0BK0k$L0k] L 0EhLnLn~L 0HLrMrM $pK^NrNrN N5OsxOsFtO $QOsPsP 4TkPvPvP 4WPx3Qx/Q ,ZmQUzQ`zFQ ]RzRzR `R|VS|RS cS3~9T@~5T fT UU |iUSU`U DleVV~V o^WnWpW `r1XXX`hX lu$YȋYЋY $HxY|qZmZ lx{ZPZ h}ZZ L[C[?[ T[ 0 [P [ d[`0 ;\7\ |e\\\ \& \- 4]0 0] q]<m] ]`, ]. ^Д ^ Y^ܔy^u^ ^^^ ^^ _5_8 1_ d_`# ___ $_- `Е ` 4Q`ܕM` L`1 `@( ah ` \7a9 a |a ta< b  b Yb@" bdb blb c= Sc Oc c5 c c  d@' ?d1 d |d d' d d 'e. ee0 ae $e@# ed e <f& 7f 3f Tif% f f lf# g$ f 5g0 1g g@Q@g g UhV@hh  h@ h ()i`%i (niD@ji <iți  ii  +j'j  wj  sj (j@j DjD@j \jD@j 3kD@/k \qkȝmk (kk kk k k 4(2l  .l \(hl@ dl 8l` l 8ll   m m  KmGm 4mm LnОnԞ/g n d0 +n \=n_ Í9n \+ Ln"Hn t&_nH[n , &@'qn2/ mn l3(}n09T]n0%-nRnTon 8(nxa (T      !"#$&')*,-/0235689;=>?AB00X`m`?DEGHJKMNPQSeN  XTUWX f] f fZ[]^@ f*8fh`a"FtcdJk fiX ffhiklnoqrtu kpmgm5P p\pwxsz{}~w f? fdVP6U}з   G(v} f  !#$&')*,-/0235689;<>? fAB f J @ fDE{ f ~ f m f g f) fU f ` f f U f N f C fG 7 fo 0 f ( f  f  f fGHJKMNPQ=   D  f0 f] fST hVWYZ\]_`bcef {hi |klnoqrtuwxz{}}KZ f   U !"#<$q%&'(M*m+,-8<5=aDUV%`Oa      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~w"""""3"L "u """"" "A"""""n"""A""""b"" " B"j" 0P*,*[*""`""N#""`""""0" q" """"."$"'"*"- "0U "3 "6 "9 0v!2!D!]!l!0v!!!"""?K"!"""?"!"B#NN#PN#N#N.$@N$N$O$%0Ow%O%O& OJ&p[&T&&&'-"EG'D!y''-"E'G"H(b"KW(!(b"K)k"NX)Y"Qs)Y"Q)))))))*Q*t"U*t"U*0 W+ +0 WS+ =z+ =+ ++,,` Y, >,0 ,,@ %X-e-@ %-p .!Y.p . .!>/ / / * 0 J0PBy0 0B00 #1P ^1p 1 1  2 !O2Hw22PD22S2S3'3 G3@D}33D3304 44]4P!445#5"X^5B55B5@56`06Dr6@D6464 7870h7@}7 !777898K8v8889%9|J9xp9t9p9l9h :d5:@J:+_:+t: :@:`/:/;>>;$e;0;P(;;< <<*<1<8<L<,<<<,=Db=0=x= C>K>0!>>>>0!>!?"{e?v?}??@#C?@#C?#B!@#BE@#V@@$@P$ @`$ 'Ap$[A$A$A$A$B$DB%|B %B@%B`%C%-C%VC%|C%FC0&;Cp&2C&  D&26D' WD~"[wD~"[DV"^DV"^D' E '&E0' ZE@'E`'gEEE'F'RF)3F)F)R#G@*AGP*dG`*@GG@+G,FG0-BH1H-3ZHmH- H- H-H- H- I.!/I0.\IP.<III.I J.OJ.J.J/JJ / K(K@/5ZK/K/ K/K/=L L0JLPLWL^L0LL1L2L $Mp3UM4MP5M@6N7-N77INQNVN77rN 84NN`84N8NO OO;OSO8uO@9OOO`9|OP9DPIPOPVP:P:P;}P;Q 2Q;fQQ@<QQQ=J$R >MRC"aRRRRC"a'S@>?SRSSSS'T8TKTUT@>mT?TA$TTE,UEZUbUPHjUHPUIU"dV"d#VJKMV0PyVV SVVVv-WYWW@]W_WK"i,XK"l[XaXd#XeXy"o%YW"r\Yu"uYgY@iY/Z6ZlkZ lOZplwZlwZZ qT [qa.[I[qu[l"x[r[r\tN6\taZ\Pu\"{\\2]i]pu]Pv]n"~^xW^y^r"^^{2H_}_ ~j_L"%`qY`i`r` `` `0a^a}a}a@bb"bHb0nbP'bbbbbb"4c"Scic"c"cc"cc d""KdQdExdД&d"d!e"Re"e"eD!e"f";f"f"f"g "]g1"g"gh,hHh"uh!h"h"h7iМ3i6iP>j>>jСIj j j",kPvkkPk 7l]olwl=lPl\"5mT"|m"m="m".n"Zn"n"n"n@BZo"o/o ,oo-p*9pepp-p*pp/q,@q"nq"q 2q"r`5r@grrR"r's "Ns/ls"sss"/t="xt="t" u$Fu0yum"uuc"uvk"Cvev"vvK"vAwAw@L8w!Pw@Liwww!wwx6x!NxgxxxxyZyh"yf" z@zh" zz0G8{Gx{w{PW{|!B|D!w|PW|||}}}-}0r}+} +}P*~x-~4~:~@~F~]~~`~0 \"4 ![\"\"\"h"h"'bJ !lbNƀ !N'2d !# !JPX_wP8h"TSh""!'h"$|t"'Ʉ_"*"-`g"0&8FV"3Q!J !!Ӈ"6C0n0CCĈC CE"9݉"<qx"?-p |lɋ"B &ELe׌@g f0M}]"E L~"H0"KcV! !"Nv!А@40 ܑ! A !t@!0!ג@!0 p#;#n#`%,֓(%!(%l(%˔(%*F"QZ(ƕ͕PG70IQW7_"TݗdhM"W`i͘"Zi#F"]n"`ș i. !bnlmXmX oVqrśwy}A"c zÜ"f3|N"i~ǝ~"l]`x@ІĞІ~"oZП"rdh"uѠ8zP"xo"{ڢЌctp0ʣP !+Z0!ݤ0!'!I!k!&!-! !!!Q,!.! !!! !%!=!_! !#!ϧ!!-!0 !a!1!˨(! !#9!` !<!ݩ !"!C!i!=! !$5!] !'!1! !'!H !s.! !׬#! !%&!O !y%! !˭#! !6I f@ q gtest-all.cc_ZN7testing8internal12UnitTestImpl26RegisterParameterizedTestsEv.part.102_ZN7testing8internalL19SumOverTestCaseListERKSt6vectorIPNS_8TestCaseESaIS3_EEMS2_KFivE.constprop.389_ZN7testing8internalL14PrintOnOneLineEPKci.constprop.390_ZNSs4_Rep10_M_disposeERKSaIcE.part.7_ZN7testing8internalL21FormatDeathTestOutputERKSs_ZN7testing12_GLOBAL__N_126PrintByteSegmentInObjectToEPKhjjPSo_ZN7testing7MessagelsIKcEERS0_RKPT_.isra.62CSWTCH.1179_ZGVZN7testing8internal13ColoredPrintfENS0_10GTestColorEPKczE13in_color_mode_ZZN7testing8internal13ColoredPrintfENS0_10GTestColorEPKczE13in_color_mode_ZN7testing8internalL15kTypeParamLabelE_ZN7testing8internalL16kValueParamLabelE_ZN7testingL20kTestShardStatusFileE_ZN7testing8internalL23HasGoogleTestFlagPrefixEPKc_ZN7testing8internalL26g_in_fast_death_test_childE_ZN7testing8internalL23kCurrentDirectoryStringE_ZN7testing8internalL17g_captured_stdoutE_ZN7testing8internalL17g_captured_stderrE_ZN7testing8internalL21g_injected_test_argvsE_ZN7testing8internalL25FormatCxxExceptionMessageEPKcS2__ZN7testing8internalL12FlagToEnvVarEPKc_ZN7testingL15kTestShardIndexE_ZN7testingL16kTestTotalShardsE_ZN7testing8internalL24StreamWideCharsToMessageEPKwjPNS_7MessageE_ZN7testing8internal18StreamableToStringIPwEESsRKT_.isra.349_ZN7testing8internalL20PrintAsCharLiteralToIwwEENS0_10CharFormatET0_PSo_ZN7testing8internalL22PrintAsStringLiteralToEwPSo_ZN7testing8internalL20PrintCharsAsStringToIcEEvPKT_jPSo_ZN7testing8internalL20PrintCharsAsStringToIwEEvPKT_jPSo_ZN7testingL19FormatCountableNounEiPKcS1__ZN7testingL16kUniversalFilterE_ZN7testing8internalL12kUnknownFileE_ZN7testing8internalL27PrintTestPartResultToStringERKNS_14TestPartResultE_ZN7testing12_GLOBAL__N_115IsSubstringImplIPKcEENS_15AssertionResultEbS3_S3_RKT_S7__ZN7testing12_GLOBAL__N_115IsSubstringImplISsEENS_15AssertionResultEbPKcS4_RKT_S7__ZN7testing12_GLOBAL__N_115IsSubstringImplISbIwSt11char_traitsIwESaIwEEEENS_15AssertionResultEbPKcS8_RKT_SB__ZN7testing12_GLOBAL__N_115IsSubstringImplIPKwEENS_15AssertionResultEbPKcS6_RKT_S9__ZGVZN7testing8UnitTest11GetInstanceEvE8instance_ZZN7testing8UnitTest11GetInstanceEvE8instance_ZN7testingL18kDefaultOutputFileE_ZN7testing8internalL22ExecDeathTestChildMainEPv_ZN7testingL20kDeathTestCaseFilterE_ZN7testingL18kDisableTestFilterE_ZN7testing8internalL17PrintColorEncodedEPKc.constprop.388_ZN7testing8internalL24kColorEncodedHelpMessageE_ZN7testing8internalL25kAlsoRunDisabledTestsFlagE_ZN7testing8internalL19kBreakOnFailureFlagE_ZN7testing8internalL20kCatchExceptionsFlagE_ZN7testing8internalL10kColorFlagE_ZN7testing8internalL19kDeathTestStyleFlagE_ZN7testing8internalL17kDeathTestUseForkE_ZN7testing8internalL11kFilterFlagE_ZN7testing8internalL25kInternalRunDeathTestFlagE_ZN7testing8internalL14kListTestsFlagE_ZN7testing8internalL11kOutputFlagE_ZN7testing8internalL14kPrintTimeFlagE_ZN7testing8internalL15kRandomSeedFlagE_ZN7testing8internalL11kRepeatFlagE_ZN7testing8internalL12kShuffleFlagE_ZN7testing8internalL20kStackTraceDepthFlagE_ZN7testing8internalL19kStreamResultToFlagE_ZN7testing8internalL19kThrowOnFailureFlagE_ZGVZN7testing8internalL23ExecDeathTestSpawnChildEPKPciE16stack_grows_down_ZZN7testing8internalL23ExecDeathTestSpawnChildEPKPciE16stack_grows_down_ZN7testingL31GetReservedAttributesForElementERKSs_ZN7testingL28kReservedTestSuiteAttributesE_ZN7testingL29kReservedTestSuitesAttributesE_ZN7testingL27kReservedTestCaseAttributesE_ZN7testing8internal12UnitTestImpl19PostFlagParsingInitEv.part.358_ZN7testing8TestInfo3RunEv.part.366_ZN7testing8TestCase3RunEv.part.367_GLOBAL__sub_I__ZN7testing8internal17kStackTraceMarkerE_ZStL8__ioinit_ZN7testingL22kDefaultDeathTestStyleE_ZN7testing8internal26ThreadLocalValueHolderBaseD5Ev_ZN7testing11EnvironmentD5Ev_ZN7testing22EmptyTestEventListenerD5Ev_ZN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE11ValueHolderD5Ev_ZN7testing8internal23DefaultDeathTestFactoryD5Ev_ZN7testing8internal27PrettyUnitTestResultPrinterD5Ev_ZN7testing8internal38DefaultPerThreadTestPartResultReporterD5Ev_ZN7testing8internal35DefaultGlobalTestPartResultReporterD5Ev_ZN7testing8internal26GoogleTestFailureExceptionD5Ev_ZN7testing8internal24XmlUnitTestResultPrinterD5Ev_ZN7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEE11ValueHolderD5Ev_ZNSt6vectorISsSaISsEED5Ev_ZN7testing8internal29ParameterizedTestCaseRegistryD5Ev_ZN7testing14TestPartResultD5Ev_ZN7testing12TestPropertyD5Ev_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEED5Ev_ZN7testing7MessageC5ERKS0__ZN7testing8internal5MutexD5Ev_ZN7testing8internal17StreamingListener12SocketWriterD5Ev_ZN7testing8internal17StreamingListenerD5Ev_ZN7testing8internal18OsStackTraceGetterD5Ev_ZN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEED5Ev_ZN7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEED5Ev_ZN7testing8internal15NoExecDeathTestD5Ev_ZN7testing8internal13ExecDeathTestD5Ev_ZNKSt5ctypeIcE8do_widenEc_ZN7testing8internal26ThreadLocalValueHolderBaseD2Ev_ZN7testing8internal26ThreadLocalValueHolderBaseD1EvDeleteThreadLocalValue_ZN7testing4Test11DeleteSelf_Ev_ZN7testing4Test5SetupEv_ZN7testing8TestCase16RunSetUpTestCaseEv_ZN7testing8TestCase19RunTearDownTestCaseEv_ZN7testing11EnvironmentD2Ev_ZN7testing11EnvironmentD1Ev_ZN7testing11Environment5SetUpEv_ZN7testing11Environment8TearDownEv_ZN7testing11Environment5SetupEv_ZN7testing22EmptyTestEventListener18OnTestProgramStartERKNS_8UnitTestE_ZN7testing22EmptyTestEventListener20OnTestIterationStartERKNS_8UnitTestEi_ZN7testing22EmptyTestEventListener24OnEnvironmentsSetUpStartERKNS_8UnitTestE_ZN7testing22EmptyTestEventListener22OnEnvironmentsSetUpEndERKNS_8UnitTestE_ZN7testing22EmptyTestEventListener15OnTestCaseStartERKNS_8TestCaseE_ZN7testing22EmptyTestEventListener11OnTestStartERKNS_8TestInfoE_ZN7testing22EmptyTestEventListener16OnTestPartResultERKNS_14TestPartResultE_ZN7testing22EmptyTestEventListener9OnTestEndERKNS_8TestInfoE_ZN7testing22EmptyTestEventListener13OnTestCaseEndERKNS_8TestCaseE_ZN7testing22EmptyTestEventListener27OnEnvironmentsTearDownStartERKNS_8UnitTestE_ZN7testing22EmptyTestEventListener25OnEnvironmentsTearDownEndERKNS_8UnitTestE_ZN7testing22EmptyTestEventListener18OnTestIterationEndERKNS_8UnitTestEi_ZN7testing22EmptyTestEventListener16OnTestProgramEndERKNS_8UnitTestE_ZN7testing8internal17StreamingListener20AbstractSocketWriter15CloseConnectionEv_ZN7testing22EmptyTestEventListenerD2Ev_ZN7testing22EmptyTestEventListenerD1Ev_ZN7testing4Test5SetUpEv_ZN7testing4Test8TearDownEv_ZNK7testing8TestCase30reportable_disabled_test_countEv_ZNK7testing8TestCase19disabled_test_countEv_ZNK7testing8TestCase21reportable_test_countEv_ZNK7testing8TestCase17test_to_run_countEv_ZNK7testing8TestCase16total_test_countEv_ZN7testing8internal27PrettyUnitTestResultPrinter18OnTestProgramStartERKNS_8UnitTestE_ZN7testing8internal27PrettyUnitTestResultPrinter22OnEnvironmentsSetUpEndERKNS_8UnitTestE_ZN7testing8internal27PrettyUnitTestResultPrinter25OnEnvironmentsTearDownEndERKNS_8UnitTestE_ZN7testing8internal27PrettyUnitTestResultPrinter16OnTestProgramEndERKNS_8UnitTestE_ZN7testing8internal18OsStackTraceGetter16UponLeavingGTestEv_ZN7testing8internal24HasNewFatalFailureHelper20ReportTestPartResultERKNS_14TestPartResultE_ZN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE11ValueHolderD2Ev_ZN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE11ValueHolderD1Ev_ZN7testing8internal23DefaultDeathTestFactoryD2Ev_ZN7testing8internal23DefaultDeathTestFactoryD1Ev_ZN7testing8internal27PrettyUnitTestResultPrinterD2Ev_ZN7testing8internal27PrettyUnitTestResultPrinterD1Ev_ZN7testing8internal38DefaultPerThreadTestPartResultReporterD2Ev_ZN7testing8internal38DefaultPerThreadTestPartResultReporterD1Ev_ZN7testing8internal35DefaultGlobalTestPartResultReporterD2Ev_ZN7testing8internal35DefaultGlobalTestPartResultReporterD1Ev_ZN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE11ValueHolderD0Ev_ZdlPv_ZN7testing8internal26ThreadLocalValueHolderBaseD0Ev_ZN7testing11EnvironmentD0Ev_ZN7testing8internal23DefaultDeathTestFactoryD0Ev_ZN7testing8internal38DefaultPerThreadTestPartResultReporterD0Ev_ZN7testing8internal35DefaultGlobalTestPartResultReporterD0Ev_ZN7testing8internal27PrettyUnitTestResultPrinterD0Ev_ZN7testing22EmptyTestEventListenerD0Ev_ZN7testing8internal17TestEventRepeaterD2Ev__gxx_personality_v0_ZTVN7testing8internal17TestEventRepeaterE_Unwind_Resume_ZN7testing8internal17TestEventRepeaterD1Ev_ZN7testing8internal17TestEventRepeaterD0Ev_ZN7testing8internal18OsStackTraceGetter17CurrentStackTraceEii_ZNSsC1EPKcRKSaIcE_ZN7testing8internal26GoogleTestFailureExceptionD2Ev_ZTVN7testing8internal26GoogleTestFailureExceptionE_ZNSt13runtime_errorD2Ev_ZN7testing8internal26GoogleTestFailureExceptionD1Ev_ZN7testing8internal26GoogleTestFailureExceptionD0Ev_ZN7testing8internal17TestEventRepeater18OnTestProgramStartERKNS_8UnitTestE_ZN7testing8internal17TestEventRepeater24OnEnvironmentsSetUpStartERKNS_8UnitTestE_ZN7testing8internal17TestEventRepeater15OnTestCaseStartERKNS_8TestCaseE_ZN7testing8internal17TestEventRepeater11OnTestStartERKNS_8TestInfoE_ZN7testing8internal17TestEventRepeater16OnTestPartResultERKNS_14TestPartResultE_ZN7testing8internal17TestEventRepeater27OnEnvironmentsTearDownStartERKNS_8UnitTestE_ZN7testing8internal17TestEventRepeater22OnEnvironmentsSetUpEndERKNS_8UnitTestE_ZN7testing8internal17TestEventRepeater25OnEnvironmentsTearDownEndERKNS_8UnitTestE_ZN7testing8internal17TestEventRepeater9OnTestEndERKNS_8TestInfoE_ZN7testing8internal17TestEventRepeater13OnTestCaseEndERKNS_8TestCaseE_ZN7testing8internal17TestEventRepeater16OnTestProgramEndERKNS_8UnitTestE_ZN7testing8internal17TestEventRepeater20OnTestIterationStartERKNS_8UnitTestEi_ZN7testing8internal17TestEventRepeater18OnTestIterationEndERKNS_8UnitTestEiputcharprintf_ZNSs4_Rep10_M_destroyERKSaIcE_ZN7testing8internal24XmlUnitTestResultPrinterD2Ev_ZTVN7testing8internal24XmlUnitTestResultPrinterE_ZNSs4_Rep20_S_empty_rep_storageE_ZN7testing8internal24XmlUnitTestResultPrinterD1Ev_ZN7testing8internal24XmlUnitTestResultPrinterD0Ev_ZN7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEE11ValueHolderD2Ev_ZTVN7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEE11ValueHolderE_ZN7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEE11ValueHolderD1Ev_ZN7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEE11ValueHolderD0Ev_ZNSt6vectorISsSaISsEED2Ev_ZNSt6vectorISsSaISsEED1Ev_ZNKSs4findEcj_ZNSs6appendEPKcj_ZNSsC1ERKSsjj_ZNSs6appendERKSs_ZSt24__throw_out_of_range_fmtPKczsnprintfstrlen_ZSt16__ostream_insertIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_PKS3_i_ZN7testing8internal29ParameterizedTestCaseRegistryD2Ev_ZN7testing8internal29ParameterizedTestCaseRegistryD1Ev_ZN7testing8internal12AssertHelperC2ENS_14TestPartResult4TypeEPKciS5__Znwj_ZN7testing8internal12AssertHelperC1ENS_14TestPartResult4TypeEPKciS5__ZN7testing8internal12AssertHelperD2Ev_ZN7testing8internal12AssertHelperD1Ev_ZN7testing8internal15UnitTestOptions15GetOutputFormatEv_ZN7testing18FLAGS_gtest_outputEstrchr_ZNSsC1EPKcjRKSaIcE_ZN7testing8internal15UnitTestOptions20PatternMatchesStringEPKcS3__ZN7testing8internal15UnitTestOptions13MatchesFilterERKSsPKc_ZN7testing8internal13GetTestTypeIdEv_ZN7testing8internal12TypeIdHelperINS_4TestEE6dummy_E_ZN7testing8internal20SingleFailureCheckerC2EPKNS_19TestPartResultArrayENS_14TestPartResult4TypeERKSs_ZNSsC1ERKSs_ZN7testing8internal20SingleFailureCheckerC1EPKNS_19TestPartResultArrayENS_14TestPartResult4TypeERKSs_ZN7testing8internal35DefaultGlobalTestPartResultReporterC2EPNS0_12UnitTestImplE_ZTVN7testing8internal35DefaultGlobalTestPartResultReporterE_ZN7testing8internal35DefaultGlobalTestPartResultReporterC1EPNS0_12UnitTestImplE_ZN7testing8internal38DefaultPerThreadTestPartResultReporterC2EPNS0_12UnitTestImplE_ZTVN7testing8internal38DefaultPerThreadTestPartResultReporterE_ZN7testing8internal38DefaultPerThreadTestPartResultReporterC1EPNS0_12UnitTestImplE_ZNK7testing8internal12UnitTestImpl21total_test_case_countEv_ZNK7testing8internal12UnitTestImpl22test_case_to_run_countEv_ZNK7testing8internal12UnitTestImpl21successful_test_countEv_ZNK7testing8TestCase21successful_test_countEv_ZNK7testing8internal12UnitTestImpl17failed_test_countEv_ZNK7testing8TestCase17failed_test_countEv_ZNK7testing8internal12UnitTestImpl30reportable_disabled_test_countEv_ZNK7testing8internal12UnitTestImpl19disabled_test_countEv_ZNK7testing8internal12UnitTestImpl21reportable_test_countEv_ZNK7testing8internal12UnitTestImpl16total_test_countEv_ZNK7testing8internal12UnitTestImpl17test_to_run_countEv_ZN7testing8internal12UnitTestImpl28CurrentOsStackTraceExceptTopEi_ZN7testing8internal15GetTimeInMillisEvgettimeofday_ZN7testing8internal6String13CStringEqualsEPKcS3_strcmp_ZN7testing15AssertionResultC2ERKS0__ZN7testing15AssertionResultC1ERKS0__ZN7testing16AssertionSuccessEv_ZN7testing16AssertionFailureEv_ZN7testing8internal6String17WideCStringEqualsEPKwS3_wcscmp_ZN7testing8internal6String28CaseInsensitiveCStringEqualsEPKcS3_strcasecmp_ZN7testing8internal6String32CaseInsensitiveWideCStringEqualsEPKwS3_wcscasecmp_ZN7testing8internal6String23EndsWithCaseInsensitiveERKSsS3__ZN7testing8internal20StringStreamToStringEPSt18basic_stringstreamIcSt11char_traitsIcESaIcEE_ZNKSt15basic_stringbufIcSt11char_traitsIcESaIcEE3strEv_ZNSs7reserveEj_ZNK7testing7Message9GetStringEv_ZN7testing15AssertionResult13AppendMessageERKNS_7MessageE_ZNK7testing10TestResult17GetTestPartResultEiabort_ZNK7testing10TestResult15GetTestPropertyEi_ZN7testing10TestResult20ClearTestPartResultsEv_ZN7testing10TestResult5ClearEv_ZNK7testing10TestResult6FailedEv_ZNK7testing8internal12UnitTestImpl26successful_test_case_countEv_ZNK7testing8internal12UnitTestImpl22failed_test_case_countEv_ZNK7testing10TestResult15HasFatalFailureEv_ZNK7testing10TestResult18HasNonfatalFailureEv_ZNK7testing10TestResult16total_part_countEv_ZNK7testing10TestResult19test_property_countEv_ZN7testing4TestC2Ev_ZTVN7testing4TestE_ZN7testing35FLAGS_gtest_also_run_disabled_testsE_ZN7testing28FLAGS_gtest_break_on_failureE_ZN7testing28FLAGS_gtest_catch_exceptionsE_ZN7testing17FLAGS_gtest_colorE_ZNSs6assignERKSs_ZN7testing28FLAGS_gtest_death_test_styleE_ZN7testing31FLAGS_gtest_death_test_use_forkE_ZN7testing18FLAGS_gtest_filterE_ZN7testing8internal35FLAGS_gtest_internal_run_death_testE_ZN7testing22FLAGS_gtest_list_testsE_ZN7testing22FLAGS_gtest_print_timeE_ZN7testing23FLAGS_gtest_random_seedE_ZN7testing18FLAGS_gtest_repeatE_ZN7testing19FLAGS_gtest_shuffleE_ZN7testing29FLAGS_gtest_stack_trace_depthE_ZN7testing28FLAGS_gtest_stream_result_toE_ZN7testing28FLAGS_gtest_throw_on_failureE_ZN7testing4TestC1Ev_ZN7testing4TestD2Ev_ZN7testing4TestD1Ev_ZN7testing4TestD0Ev_ZN7testing8internal12UnitTestImpl26RegisterParameterizedTestsEv_ZNK7testing8TestCase11GetTestInfoEi_ZN7testing8TestCase18GetMutableTestInfoEi_ZN7testing8TestCase11ClearResultEv_ZN7testing8TestCase14UnshuffleTestsEv_ZN7testing8internal16GetAnsiColorCodeENS0_10GTestColorE_ZN7testing8internal14ShouldUseColorEbgetenv_ZN7testing8internal13ColoredPrintfENS0_10GTestColorEPKczstdoutvfprintf__cxa_guard_acquirefilenoisatty__cxa_guard_release_ZN7testing8internal27PrettyUnitTestResultPrinter24OnEnvironmentsSetUpStartERKNS_8UnitTestEputsfflush_ZN7testing8internal27PrettyUnitTestResultPrinter27OnEnvironmentsTearDownStartERKNS_8UnitTestE_ZN7testing8internal27PrettyUnitTestResultPrinter11OnTestStartERKNS_8TestInfoE_ZN7testing8internal29PrintFullTestCommentIfPresentERKNS_8TestInfoE_ZN7testing8internal27PrettyUnitTestResultPrinter16PrintFailedTestsERKNS_8UnitTestE_ZN7testing8internal17TestEventRepeater7ReleaseEPNS_17TestEventListenerEmemmove_ZN7testing8internal24XmlUnitTestResultPrinterC2EPKcstderrfwriteexit_ZN7testing8internal24XmlUnitTestResultPrinterC1EPKc_ZN7testing8internal24XmlUnitTestResultPrinter26RemoveInvalidXmlCharactersERKSs_ZN7testing8internal24XmlUnitTestResultPrinter21OutputXmlCDataSectionEPSoPKc_ZNSo5writeEPKcistrstr_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc_ZN7testing18TestEventListenersC2Ev_ZN7testing18TestEventListenersC1Ev_ZN7testing18TestEventListenersD2Ev_ZN7testing18TestEventListenersD1Ev_ZN7testing18TestEventListeners7ReleaseEPNS_17TestEventListenerE_ZN7testing18TestEventListeners8repeaterEv_ZNK7testing18TestEventListeners22EventForwardingEnabledEv_ZN7testing18TestEventListeners23SuppressEventForwardingEv_ZNK7testing8UnitTest26successful_test_case_countEv_ZNK7testing8UnitTest22failed_test_case_countEv_ZNK7testing8UnitTest21total_test_case_countEv_ZNK7testing8UnitTest22test_case_to_run_countEv_ZNK7testing8UnitTest21successful_test_countEv_ZNK7testing8UnitTest17failed_test_countEv_ZNK7testing8UnitTest30reportable_disabled_test_countEv_ZNK7testing8UnitTest19disabled_test_countEv_ZNK7testing8UnitTest21reportable_test_countEv_ZNK7testing8UnitTest16total_test_countEv_ZNK7testing8UnitTest17test_to_run_countEv_ZNK7testing8UnitTest15start_timestampEv_ZNK7testing8UnitTest12elapsed_timeEv_ZNK7testing8UnitTest6PassedEv_ZNK7testing8UnitTest6FailedEv_ZNK7testing8UnitTest11GetTestCaseEi_ZNK7testing8UnitTest18ad_hoc_test_resultEv_ZN7testing8UnitTest18GetMutableTestCaseEi_ZN7testing8UnitTest9listenersEv_ZN7testing14TestPartResultD2Ev_ZN7testing14TestPartResultD1Ev_ZN7testing12TestPropertyD2Ev_ZN7testing12TestPropertyD1Ev_ZNK7testing8UnitTest20original_working_dirEv_ZNK7testing8UnitTest11random_seedEv_ZN7testing8UnitTest27parameterized_test_registryEv_ZN7testing8internal12UnitTestImpl32SuppressTestEventsIfInSubprocessEv_ZN7testing8internal30WriteToShardStatusFileIfNeededEvfopenfclose_ZN7testing8internal20ShouldRunTestOnShardEiii_ZN7testing8internal12UnitTestImpl23ListTestsMatchingFilterEv_ZN7testing8internal12UnitTestImpl25set_os_stack_trace_getterEPNS0_27OsStackTraceGetterInterfaceE_ZN7testing8internal12UnitTestImpl19current_test_resultEv_ZN7testing8internal12UnitTestImpl14UnshuffleTestsEv_ZN7testing8internal6IsTrueEb_ZN7testing8internal10AlwaysTrueEv_ZN7testing8internal10SkipPrefixEPKcPS2_strncmp_ZN7testing8internal14ParseFlagValueEPKcS2_b_ZN7testing8internal13ParseBoolFlagEPKcS2_Pb_ZN7testing8internal15ParseStringFlagEPKcS2_PSs_ZNSs6assignEPKcj_ZN7testing8internal16InDeathTestChildEv_ZNKSs7compareEPKc_ZN7testing14ExitedWithCodeC2Ei_ZN7testing14ExitedWithCodeC1Ei_ZNK7testing14ExitedWithCodeclEi_ZN7testing14KilledBySignalC2Ei_ZN7testing14KilledBySignalC1Ei_ZNK7testing14KilledBySignalclEi_ZN7testing8internal20ExitedUnsuccessfullyEi_ZN7testing8internal23GetLastErrnoDescriptionEv__errno_locationstrerror_ZN7testing8internal9DeathTest11LastMessageEv_ZN7testing8internal9DeathTest24last_death_test_message_E_ZN7testing8internal9DeathTest27set_last_death_test_messageERKSs_ZN7testing8internal21StackLowerThanAddressEPKvPb_ZN7testing8internal14StackGrowsDownEv_ZNK7testing8internal8FilePath21FindLastPathSeparatorEvstrrchr_ZNK7testing8internal8FilePath21FileOrDirectoryExistsEv__xstat_ZNK7testing8internal8FilePath15DirectoryExistsEv_ZNK7testing8internal8FilePath15IsRootDirectoryEv_ZNK7testing8internal8FilePath14IsAbsolutePathEv_ZNK7testing8internal8FilePath11IsDirectoryEv_ZNK7testing8internal8FilePath12CreateFolderEvmkdir_ZN7testing8internal8FilePath9NormalizeEv_Znajmemset_ZdaPv_ZN7testing8internal8FilePath13GetCurrentDirEvgetcwd_ZNK7testing8internal8FilePath19RemoveDirectoryNameEv_ZN7testing8internal24GetCurrentExecutableNameEv_ZN7testing8internal17g_executable_pathE_ZNK7testing8internal8FilePath14RemoveFileNameEv_ZNK7testing8internal8FilePath27RemoveTrailingPathSeparatorEv_ZNK7testing8internal8FilePath28CreateDirectoriesRecursivelyEv_ZNK7testing8internal8FilePath15RemoveExtensionEPKc_ZN7testing8internal14GetThreadCountEv_ZN7testing8internal2RED2Evregfreefree_ZN7testing8internal2RED1Ev_ZN7testing8internal2RE9FullMatchEPKcRKS1_regexec_ZN7testing8internal2RE12PartialMatchEPKcRKS1__ZN7testing8internal8GTestLogD2Ev_ZSt4cerr_ZNSo3putEc_ZNSo5flushEv_ZNKSt5ctypeIcE13_M_widen_initEv_ZSt16__throw_bad_castv_ZN7testing8internal8GTestLogD1Ev_ZN7testing8internal14CapturedStream11GetFileSizeEP8_IO_FILEfseekftell_ZN7testing8internal14CapturedStream14ReadEntireFileEP8_IO_FILEfread_ZN7testing8internal17GetCapturedStreamEPPNS0_14CapturedStreamEdup2closeremove_ZN7testing8internal17GetCapturedStdoutEv_ZN7testing8internal17GetCapturedStderrEv_ZN7testing8internal18SetInjectableArgvsEPKSt6vectorISsSaISsEE_ZN7testing8internal18GetInjectableArgvsEv_ZN7testing8internal7g_argvsE_ZN7testing9internal220PrintBytesInObjectToEPKhjPSo_ZNSo9_M_insertImEERSoT__ZN7testinglsERSoRKNS_14TestPartResultE_ZNSolsEi_ZNSt9basic_iosIcSt11char_traitsIcEE5clearESt12_Ios_Iostate_ZNK7testing19TestPartResultArray17GetTestPartResultEi_ZNK7testing19TestPartResultArray4sizeEv_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEED2Ev_ZTVSt15basic_stringbufIcSt11char_traitsIcESaIcEE_ZTVSt15basic_streambufIcSt11char_traitsIcEE_ZNSt6localeD1Ev_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEED1Ev_ZN7testing7MessageC2Ev_ZNSt8ios_baseC2Ev_ZTTSt18basic_stringstreamIcSt11char_traitsIcESaIcEE_ZTVSt9basic_iosIcSt11char_traitsIcEE_ZNSt9basic_iosIcSt11char_traitsIcEE4initEPSt15basic_streambufIcS1_E_ZTVSt18basic_stringstreamIcSt11char_traitsIcESaIcEE_ZNSt6localeC1Ev_ZNSt8ios_baseD2Ev_ZNSdD2Ev_ZN7testing7MessageC1Ev_ZN7testing8internal30GetBoolAssertionFailureMessageERKNS_15AssertionResultEPKcS5_S5__ZN7testing8internal10ParseInt32ERKNS_7MessageEPKcPistrtol_ZN7testing8internal17Int32FromEnvOrDieEPKci_ZN7testing8internal14ParseInt32FlagEPKcS2_Pitoupper_ZN7testing8internal16BoolFromGTestEnvEPKcb_ZN7testing8internal18StringFromGTestEnvEPKcS2__ZN7testing8internal17Int32FromGTestEnvEPKci_ZN7testing7MessageC2ERKS0__ZN7testing7MessageC1ERKS0__ZN7testing8internal11ShouldShardEPKcS2_b_ZN7testing8internal6String12FormatHexIntEi_ZNSt18basic_stringstreamIcSt11char_traitsIcESaIcEED1Ev_ZN7testing8internal27FormatTimeInMillisAsSecondsEx_ZNSo9_M_insertIdEERSoT__ZN7testing8internal6String15FormatIntWidth2Ei_ZN7testing8internal6String10FormatByteEh_ZN7testing8internal24XmlUnitTestResultPrinter9EscapeXmlERKSsb_ZN7testing8internal24XmlUnitTestResultPrinter29TestPropertiesAsXmlAttributesERKNS_10TestResultE_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEED0Ev_ZN7testing8internal10scoped_ptrISsE5resetEPSs_ZN7testing8internal9EqFailureEPKcS2_RKSsS4_b_ZNK7testing15AssertionResultntEv_ZN7testing16AssertionFailureERKNS_7MessageE_ZN7testing8internal10scoped_ptrINS0_24InternalRunDeathTestFlagEE5resetEPS2__ZStplIcSt11char_traitsIcESaIcEESbIT_T0_T1_ERKS6_PKS3__ZStplIcSt11char_traitsIcESaIcEESbIT_T0_T1_EPKS3_RKS6__ZN7testing8internal15CodePointToUtf8Ej_ZN7testing8internal16WideStringToUtf8EPKwi_ZNSt18basic_stringstreamIcSt11char_traitsIcESaIcEEC1ESt13_Ios_Openmodewcslen_ZN7testing7MessagelsERKSbIwSt11char_traitsIwESaIwEE_ZN7testing8internal6String15ShowWideCStringEPKw_ZN7testing7MessagelsEPKw_ZN7testing7MessagelsEPwisxdigit_ZN7testing8internal19UniversalPrintArrayEPKcjPSo_ZN7testing8internal7PrintToEPKcPSo_ZNSo9_M_insertIPKvEERSoT__ZN7testing8internal13PrintStringToERKSsPSo_ZN7testing13PrintToStringIPKcEESsRKT__ZN7testing8internal14CmpHelperSTREQEPKcS2_S2_S2__ZN7testing8internal18CmpHelperSTRCASEEQEPKcS2_S2_S2__ZN7testing8internal19UniversalPrintArrayEPKwjPSo_ZN7testing8internal7PrintToEPKwPSo_ZN7testing8internal17PrintWideStringToERKSbIwSt11char_traitsIwESaIwEEPSo_ZN7testing13PrintToStringIPKwEESsRKT__ZNSbIwSt11char_traitsIwESaIwEEC1EPKwRKS1__ZNSbIwSt11char_traitsIwESaIwEE4_Rep20_S_empty_rep_storageE_ZNSbIwSt11char_traitsIwESaIwEE4_Rep10_M_destroyERKS1__ZN7testing8internal14CmpHelperSTREQEPKcS2_PKwS4__ZN7testing8internal17StreamingListener9UrlEncodeEPKc_ZN7testing8internal18StreamableToStringIiEESsRKT__ZN7testing8internal27PrettyUnitTestResultPrinter15OnTestCaseStartERKNS_8TestCaseE_ZN7testing8internal27PrettyUnitTestResultPrinter20OnTestIterationStartERKNS_8UnitTestEi_ZN7testing8internal18StreamableToStringIxEESsRKT__ZNSo9_M_insertIxEERSoT__ZN7testing8internal27PrettyUnitTestResultPrinter9OnTestEndERKNS_8TestInfoE_ZN7testing8internal27PrettyUnitTestResultPrinter13OnTestCaseEndERKNS_8TestCaseE_ZN7testing8internal27PrettyUnitTestResultPrinter18OnTestIterationEndERKNS_8UnitTestEi_ZStplIcSt11char_traitsIcESaIcEESbIT_T0_T1_ERKS6_S8__ZN7testing8internal8FilePath11ConcatPathsERKS1_S3__ZNSs6appendEjc__divdi3_ZN7testing8internal32FormatEpochTimeInMillisAsIso8601Exlocaltime_ZN7testing8internal8FilePath12MakeFileNameERKS1_S3_iPKc_ZN7testing8internal8FilePath22GenerateUniqueFileNameERKS1_S3_PKc_ZN7testing8internal18FormatFileLocationEPKci_ZN7testing8internal8GTestLogC2ENS0_16GTestLogSeverityEPKci_ZN7testing8internal8GTestLogC1ENS0_16GTestLogSeverityEPKci_ZN7testing8internal13CaptureStreamEiPKcPPNS0_14CapturedStreamEdupmkstemp_ZN7testing8internal13CaptureStdoutEv_ZN7testing8internal13CaptureStderrEv_ZN7testing8internal17StreamingListener12SocketWriter14MakeConnectionEvgetaddrinfosocketconnectfreeaddrinfogai_strerror_ZN7testing8internal17StreamingListener12SocketWriter15CloseConnectionEv_ZN7testing8internal5MutexD2Evpthread_mutex_destroy_ZN7testing8internal5MutexD1Ev_ZN7testing8internal9MutexBase6UnlockEvpthread_mutex_unlock_ZN7testing8internal9MutexBase4LockEvpthread_mutex_lockpthread_self_ZN7testing8internal17StreamingListener12SocketWriter4SendERKSswrite_ZN7testing8internal6Random8GenerateEj_ZN7testing8internal13DeathTestImpl6PassedEb_ZN7testing8internal17StreamingListener12SocketWriterD2Ev_ZTVN7testing8internal17StreamingListener12SocketWriterE_ZN7testing8internal17StreamingListener12SocketWriterD1Ev_ZN7testing8internal17StreamingListener12SocketWriterD0Ev_ZN7testing8internal17StreamingListenerD2Ev_ZTVN7testing8internal17StreamingListenerE_ZN7testing8internal17StreamingListenerD1Ev_ZN7testing8internal17StreamingListenerD0Ev_ZN7testing8internal17StreamingListener20AbstractSocketWriter6SendLnERKSs_ZN7testing8internal17StreamingListener11OnTestStartERKNS_8TestInfoE_ZN7testing8internal17StreamingListener15OnTestCaseStartERKNS_8TestCaseE_ZN7testing8internal17StreamingListener16OnTestProgramEndERKNS_8UnitTestE_ZN7testing8internal17StreamingListener16OnTestPartResultERKNS_14TestPartResultE_ZN7testing8internal17StreamingListener20OnTestIterationStartERKNS_8UnitTestEi_ZN7testing10TestResultC2Evpthread_mutex_init_ZN7testing10TestResultC1Ev_ZN7testing8internal18OsStackTraceGetterD2Ev_ZTVN7testing8internal18OsStackTraceGetterE_ZN7testing8internal18OsStackTraceGetterD1Ev_ZN7testing8internal18OsStackTraceGetterD0Ev_ZN7testing8internal12UnitTestImpl21os_stack_trace_getterEv_ZN7testing8internal12UnitTestImpl31SetGlobalTestPartResultReporterEPNS_31TestPartResultReporterInterfaceE_ZN7testing8internal12UnitTestImpl31GetGlobalTestPartResultReporterEv_ZNK7testing8UnitTest17current_test_caseEv_ZNK7testing8UnitTest17current_test_infoEv_ZN7testing8internal38DefaultPerThreadTestPartResultReporter20ReportTestPartResultERKNS_14TestPartResultE_ZN7testing10TestResultD2Ev_ZN7testing10TestResultD1Ev_ZN7testing8internal17StreamingListener18OnTestProgramStartERKNS_8UnitTestE_ZN7testing8internal26GoogleTestFailureExceptionC2ERKNS_14TestPartResultE_ZNSt13runtime_errorC2ERKSs_ZN7testing8internal26GoogleTestFailureExceptionC1ERKNS_14TestPartResultE_ZN7testing8internal27PrettyUnitTestResultPrinter16OnTestPartResultERKNS_14TestPartResultE_ZN7testing8internal25ReportInvalidTestCaseTypeEPKcS2_ifprintf_ZN7testing8internal37FormatCompilerIndependentFileLocationEPKci_ZN7testing8internal17AppendUserMessageERKSsRKNS_7MessageE_ZN7testing8internal17StreamingListener9OnTestEndERKNS_8TestInfoE_ZN7testing8internal17StreamingListener13OnTestCaseEndERKNS_8TestCaseE_ZN7testing8internal17StreamingListener18OnTestIterationEndERKNS_8UnitTestEi_ZN7testing15AssertionResultlsINS_7MessageEEERS0_RKT__ZN7testing15AssertionResultlsIA11_cEERS0_RKT__ZN7testing15AssertionResultlsISsEERS0_RKT__ZN7testing15AssertionResultlsIA2_cEERS0_RKT__ZN7testing15AssertionResultlsINS_14TestPartResultEEERS0_RKT__ZN7testing15AssertionResultlsIA3_cEERS0_RKT__ZN7testing8internal13HasOneFailureEPKcS2_S2_RKNS_19TestPartResultArrayENS_14TestPartResult4TypeERKSs_ZN7testing15AssertionResultlsIPKcEERS0_RKT__ZN7testing11IsSubstringEPKcS1_S1_S1__ZN7testing14IsNotSubstringEPKcS1_S1_S1__ZNKSs4findEPKcjj_ZN7testing11IsSubstringEPKcS1_RKSsS3__ZN7testing14IsNotSubstringEPKcS1_RKSsS3__ZNKSbIwSt11char_traitsIwESaIwEE4findEPKwjj_ZN7testing11IsSubstringEPKcS1_RKSbIwSt11char_traitsIwESaIwEES7__ZN7testing14IsNotSubstringEPKcS1_RKSbIwSt11char_traitsIwESaIwEES7_wcsstr_ZN7testing11IsSubstringEPKcS1_PKwS3__ZN7testing14IsNotSubstringEPKcS1_PKwS3__ZN7testing15AssertionResultlsIA5_cEERS0_RKT__ZN7testing15AssertionResultlsIA7_cEERS0_RKT__ZN7testing8internal20DoubleNearPredFormatEPKcS2_S2_ddd_ZN7testing15AssertionResultlsIA12_cEERS0_RKT__ZN7testing8internal14CmpHelperSTRNEEPKcS2_PKwS4__ZN7testing8internal14CmpHelperSTRNEEPKcS2_S2_S2__ZN7testing8internal18CmpHelperSTRCASENEEPKcS2_S2_S2__ZN7testing8internal15FloatingPointLEIfEENS_15AssertionResultEPKcS4_T_S5__ZN7testing7FloatLEEPKcS1_ff_ZN7testing8internal15FloatingPointLEIdEENS_15AssertionResultEPKcS4_T_S5__ZN7testing8DoubleLEEPKcS1_dd_ZN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEED2Evpthread_getspecificpthread_key_delete_ZN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEED1Ev_ZN7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEED2Ev_ZN7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEED1Ev_ZN7testing8internal12ShuffleRangeIiEEvPNS0_6RandomEiiPSt6vectorIT_SaIS5_EE_ZN7testing8TestCase12ShuffleTestsEPNS_8internal6RandomE_ZN7testing8internal12UnitTestImpl12ShuffleTestsEv_ZN7testing8internal18ParseNaturalNumberIiEEbRKSsPT_strtoull_ZN7testing8internal18PrintCharAndCodeToIhhEEvT0_PSo_ZN7testing8internal7PrintToEhPSo_ZN7testing8internal18PrintCharAndCodeToIhaEEvT0_PSo_ZN7testing8internal7PrintToEaPSo_ZN7testing8internal18PrintCharAndCodeToIwwEEvT0_PSo_ZN7testing8internal7PrintToEwPSo_ZN7testing8internal10scoped_ptrIKSsE5resetEPS2__ZN7testing8TestInfoD2Ev_ZN7testing8TestInfoD1Ev_ZN7testing8TestCaseD2Ev_ZTVN7testing8TestCaseE_ZN7testing8TestCaseD1Ev_ZN7testing8TestCaseD0Ev_ZN7testing8internal12UnitTestImplD2Ev_ZTVN7testing8internal12UnitTestImplE_ZN7testing8internal12UnitTestImplD1Ev_ZN7testing8internal12UnitTestImplD0Ev_ZN7testing8UnitTestD2Ev_ZTVN7testing8UnitTestE_ZN7testing8UnitTestD1Ev_ZN7testing8UnitTestD0Ev_ZN7testing8TestCaseC2EPKcS2_PFvvES4__ZN7testing8TestCaseC1EPKcS2_PFvvES4__ZN7testing8TestInfoC2ERKSsS2_PKcS4_PKvPNS_8internal15TestFactoryBaseE_ZN7testing8TestInfoC1ERKSsS2_PKcS4_PKvPNS_8internal15TestFactoryBaseE_ZNSt6vectorIPN7testing8TestInfoESaIS2_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS2_S4_EERKS2__ZNSt6vectorIiSaIiEE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPiS1_EERKi_ZN7testing8TestCase11AddTestInfoEPNS_8TestInfoE_ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS2_S4_EERKS2__ZN7testing8internal12UnitTestImpl24ConfigureStreamingOutputEv_ZN7testing8internal17TestEventRepeater6AppendEPNS_17TestEventListenerE_ZN7testing18TestEventListeners6AppendEPNS_17TestEventListenerE_ZN7testing18TestEventListeners23SetDefaultResultPrinterEPNS_17TestEventListenerE_ZN7testing8internal12UnitTestImplC2EPNS_8UnitTestEpthread_key_create_ZTVN7testing8internal23DefaultDeathTestFactoryE_ZTVN7testing8internal27PrettyUnitTestResultPrinterE_ZN7testing8internal12UnitTestImplC1EPNS_8UnitTestE_ZN7testing8UnitTestC2Ev_ZN7testing8UnitTestC1Ev_ZN7testing8UnitTest11GetInstanceEv__dso_handle__cxa_atexit__cxa_guard_abort_ZN7testing8internal15UnitTestOptions27GetAbsolutePathToOutputFileEv_ZN7testing4Test15HasFatalFailureEv_ZN7testing4Test18HasNonfatalFailureEv_ZN7testing8internal31GetCurrentOsStackTraceExceptTopEPNS_8UnitTestEi_ZN7testing8internal14DeathTestAbortERKSsfdopenfputcfputs_exit_ZN7testing8internal13DeathTestImpl26ReadAndInterpretStatusByteEvread_ZN7testing8internal13DeathTestImpl5AbortENS0_9DeathTest11AbortReasonE_ZN7testing8internal16ForkingDeathTest4WaitEvwaitpid_ZN7testing8internal15NoExecDeathTestD2Ev_ZTVN7testing8internal13DeathTestImplE_ZN7testing8internal15NoExecDeathTestD1Ev_ZN7testing8internal13ExecDeathTestD2Ev_ZN7testing8internal13ExecDeathTestD1Ev_ZN7testing8internal15NoExecDeathTestD0Ev_ZN7testing8internal13ExecDeathTestD0Ev_ZN7testing8internal9DeathTestC2Ev_ZTVN7testing8internal9DeathTestE_ZN7testing8internal9DeathTestC1Ev_ZN7testing8internal16ForkingDeathTestC2EPKcPKNS0_2REE_ZTVN7testing8internal16ForkingDeathTestE_ZN7testing8internal16ForkingDeathTestC1EPKcPKNS0_2REE_ZN7testing8internal9DeathTest6CreateEPKcPKNS0_2REES3_iPPS1__ZN7testing8internal15NoExecDeathTest10AssumeRoleEvpipefork_ZN7testing8internal23DefaultDeathTestFactory6CreateEPKcPKNS0_2REES3_iPPNS0_9DeathTestE_ZTVN7testing8internal15NoExecDeathTestE_ZTVN7testing8internal13ExecDeathTestEchdirenvironexecve_ZN7testing18TestEventListeners22SetDefaultXmlGeneratorEPNS_17TestEventListenerE_ZN7testing8internal12UnitTestImpl18ConfigureXmlOutputEv_ZNSt6vectorIPN7testing11EnvironmentESaIS2_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS2_S4_EERKS2__ZN7testing8UnitTest14AddEnvironmentEPNS_11EnvironmentE_ZNSt6vectorIPN7testing8TestCaseESaIS2_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS2_S4_EERKS2__ZN7testing8internal18StreamableToStringIPcEESsRKT__ZNSt6vectorIPcSaIS0_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS0_S2_EERKS0__ZNSt6vectorIPcSaIS0_EE6insertEN9__gnu_cxx17__normal_iteratorIPS0_S2_EERKS0__ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE8_M_eraseEPSt13_Rb_tree_nodeISsE_ZNKSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE4findERKSsmemcmp_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE16_M_insert_uniqueERKSs_ZSt18_Rb_tree_decrementPSt18_Rb_tree_node_base_ZSt29_Rb_tree_insert_and_rebalancebPSt18_Rb_tree_node_baseS0_RS___cxa_begin_catch__cxa_rethrow__cxa_end_catch_ZN7testing8internal27CheckedDowncastToActualTypeINS0_11ThreadLocalISt6vectorINS0_9TraceInfoESaIS4_EEE11ValueHolderENS0_26ThreadLocalValueHolderBaseEEEPT_PT0__ZTSN7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEE11ValueHolderE_ZTIN7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEE11ValueHolderE_ZTIN7testing8internal26ThreadLocalValueHolderBaseE__dynamic_cast__cxa_bad_typeid_ZN7testing13PrintToStringIxEESsRKT__ZN7testing8internal11CmpHelperEQEPKcS2_xx_ZN7testing8internal11CmpHelperNEEPKcS2_xx_ZN7testing8internal11CmpHelperLEEPKcS2_xx_ZN7testing8internal11CmpHelperLTEPKcS2_xx_ZN7testing8internal11CmpHelperGEEPKcS2_xx_ZN7testing8internal11CmpHelperGTEPKcS2_xx_ZSt9__find_ifIN9__gnu_cxx17__normal_iteratorIPN7testing12TestPropertyESt6vectorIS3_SaIS3_EEEENS0_5__ops10_Iter_predINS2_8internal17TestPropertyKeyIsEEEET_SE_SE_T0_St26random_access_iterator_tag_ZSt9__find_ifIN9__gnu_cxx17__normal_iteratorIPKSsSt6vectorISsSaISsEEEENS0_5__ops16_Iter_equals_valIS2_EEET_SB_SB_T0_St26random_access_iterator_tag_ZSt9__find_ifIN9__gnu_cxx17__normal_iteratorIPPN7testing8TestCaseESt6vectorIS4_SaIS4_EEEENS0_5__ops10_Iter_predINS2_8internal14TestCaseNameIsEEEET_SF_SF_T0_St26random_access_iterator_tag_ZN7testing8internal12UnitTestImpl11GetTestCaseEPKcS3_PFvvES5__ZN7testing8internal23MakeAndRegisterTestInfoEPKcS2_S2_S2_PKvPFvvES6_PNS0_15TestFactoryBaseE_ZNSs12_S_constructIPKcEEPcT_S3_RKSaIcESt20forward_iterator_tag_ZSt19__throw_logic_errorPKc_ZNSs4_Rep9_S_createEjjRKSaIcEmemcpy_ZN7testing8internal15UnitTestOptions17FilterMatchesTestERKSsS3__ZN7testing8internal12UnitTestImpl11FilterTestsENS1_18ReactionToShardingE_ZN7testing14TestPartResult14ExtractSummaryEPKc_ZN7testing8internal17kStackTraceMarkerE_ZN7testing8internal19TypedTestCasePState25VerifyRegisteredTestNamesEPKciS3_isspace_ZSt18_Rb_tree_incrementPKSt18_Rb_tree_node_base_ZN7testing8internal28ParseGoogleTestFlagsOnlyImplIwEEvPiPPT__ZN7testing8internal11g_help_flagE_ZN7testing8internal24ParseGoogleTestFlagsOnlyEPiPPw_ZN7testing8internal28ParseGoogleTestFlagsOnlyImplIcEEvPiPPT__ZN7testing8internal24ParseGoogleTestFlagsOnlyEPiPPc_ZN7testing8internal27CheckedDowncastToActualTypeINS0_11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE11ValueHolderENS0_26ThreadLocalValueHolderBaseEEEPT_PT0__ZTSN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE11ValueHolderE_ZTIN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE11ValueHolderE_ZNK7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE16GetOrCreateValueEv_ZTVN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE11ValueHolderEpthread_setspecific_ZN7testing8internal12UnitTestImpl41GetTestPartResultReporterForCurrentThreadEv_ZN7testing8internal12UnitTestImpl41SetTestPartResultReporterForCurrentThreadEPNS_31TestPartResultReporterInterfaceE_ZN7testing8internal24HasNewFatalFailureHelperD2Ev_ZTVN7testing8internal24HasNewFatalFailureHelperE_ZN7testing8internal24HasNewFatalFailureHelperD1Ev_ZN7testing8internal24HasNewFatalFailureHelperD0Ev_ZN7testing32ScopedFakeTestPartResultReporterD2Ev_ZTVN7testing32ScopedFakeTestPartResultReporterE_ZN7testing32ScopedFakeTestPartResultReporterD1Ev_ZN7testing32ScopedFakeTestPartResultReporterD0Ev_ZN7testing8internal24HasNewFatalFailureHelperC2Ev_ZN7testing8internal24HasNewFatalFailureHelperC1Ev_ZN7testing32ScopedFakeTestPartResultReporter4InitEv_ZN7testing32ScopedFakeTestPartResultReporterC2EPNS_19TestPartResultArrayE_ZN7testing32ScopedFakeTestPartResultReporterC1EPNS_19TestPartResultArrayE_ZN7testing32ScopedFakeTestPartResultReporterC2ENS0_13InterceptModeEPNS_19TestPartResultArrayE_ZN7testing32ScopedFakeTestPartResultReporterC1ENS0_13InterceptModeEPNS_19TestPartResultArrayE_ZNSt12_Destroy_auxILb0EE9__destroyIPSsEEvT_S3__ZN7testing8internal13ExecDeathTest10AssumeRoleEvfcntlstrdupsigemptysetsigactiongetpagesizemmapclonemunmap_ZSt17__throw_bad_allocv_ZN7testing8internal24XmlUnitTestResultPrinter18OutputXmlAttributeEPSoRKSsS4_S4__ZN7testing8internal24XmlUnitTestResultPrinter17OutputXmlTestInfoEPSoPKcRKNS_8TestInfoE_ZN7testing8internal24XmlUnitTestResultPrinter16PrintXmlTestCaseEPSoRKNS_8TestCaseE_ZN7testing8internal24XmlUnitTestResultPrinter16PrintXmlUnitTestEPSoRKNS_8UnitTestE_ZN7testing8internal24XmlUnitTestResultPrinter18OnTestIterationEndERKNS_8UnitTestEi_ZNSt6vectorISsSaISsEE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPSsS1_EERKSs_ZN7testing8internal29ParseInternalRunDeathTestFlagEv_ZN7testing8internal12UnitTestImpl19PostFlagParsingInitEv_ZN7testing8internal18InitGoogleTestImplIcEEvPiPPT__ZN7testing8internal18g_init_gtest_countE_ZN7testing14InitGoogleTestEPiPPc_ZN7testing8internal18InitGoogleTestImplIwEEvPiPPT__ZN7testing14InitGoogleTestEPiPPw_ZNSt12_Destroy_auxILb0EE9__destroyIPN7testing8internal9TraceInfoEEEvT_S6__ZNK7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEE16GetOrCreateValueEv_ZN7testing8UnitTest17AddTestPartResultENS_14TestPartResult4TypeEPKciRKSsS6___cxa_allocate_exception_ZTIN7testing8internal26GoogleTestFailureExceptionE__cxa_throw__cxa_free_exception_ZNK7testing8internal12AssertHelperaSERKNS_7MessageE_ZN7testing8internal20SingleFailureCheckerD2Ev_ZN7testing8internal20SingleFailureCheckerD1Ev_ZN7testing24ValidateTestPropertyNameERKSsRKSt6vectorISsSaISsEE_ZN7testing10TestResult20ValidateTestPropertyERKSsRKNS_12TestPropertyE_ZN7testing4Test19HasSameFixtureClassEv_ZN7testing8internal2RE4InitEPKcregcomp_ZN7testing8internal30ReportFailureInUnknownLocationENS_14TestPartResult4TypeERKSs_ZN7testing8internal35HandleExceptionsInMethodIfSupportedINS_4TestEvEET0_PT_MS4_FS3_vEPKc_ZTISt9exception_ZN7testing4Test3RunEv_ZN7testing8internal35HandleExceptionsInMethodIfSupportedINS0_15TestFactoryBaseEPNS_4TestEEET0_PT_MS6_FS5_vEPKc_ZN7testing8TestInfo3RunEv_ZN7testing8internal35HandleExceptionsInMethodIfSupportedINS_8TestCaseEvEET0_PT_MS4_FS3_vEPKc_ZN7testing8TestCase3RunEv_ZN7testing8internal12UnitTestImpl11RunAllTestsEv_ZN7testing8internal35HandleExceptionsInMethodIfSupportedINS0_12UnitTestImplEbEET0_PT_MS4_FS3_vEPKc_ZN7testing8UnitTest3RunEv_ZN7testing8UnitTest13PopGTestTraceEv_ZN7testing8internal11ScopedTraceD2Ev_ZN7testing8internal11ScopedTraceD1Ev_ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS2_S4_EERKS2__ZN7testing8UnitTest14PushGTestTraceERKNS_8internal9TraceInfoE_ZN7testing8internal11ScopedTraceC2EPKciRKNS_7MessageE_ZN7testing8internal11ScopedTraceC1EPKciRKNS_7MessageE_ZNSt20__uninitialized_copyILb0EE13__uninit_copyIPN7testing14TestPartResultES4_EET0_T_S6_S5__ZNSt6vectorIN7testing14TestPartResultESaIS1_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS1_S3_EERKS1__ZN7testing8internal35DefaultGlobalTestPartResultReporter20ReportTestPartResultERKNS_14TestPartResultE_ZN7testing10TestResult17AddTestPartResultERKNS_14TestPartResultE_ZN7testing19TestPartResultArray6AppendERKNS_14TestPartResultE_ZN7testing32ScopedFakeTestPartResultReporter20ReportTestPartResultERKNS_14TestPartResultE_ZNSt20__uninitialized_copyILb0EE13__uninit_copyIPN7testing12TestPropertyES4_EET0_T_S6_S5__ZNSt6vectorIN7testing12TestPropertyESaIS1_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS1_S3_EERKS1__ZN7testing10TestResult14RecordPropertyERKSsRKNS_12TestPropertyE_ZN7testing8internal12UnitTestImpl14RecordPropertyERKNS_12TestPropertyE_ZNSs6assignEPKc_ZN7testing8UnitTest14RecordPropertyERKSsS2__ZN7testing4Test14RecordPropertyERKSsS2__ZN7testing4Test14RecordPropertyERKSsi_ZNSt8ios_base4InitC1Ev_ZNSt8ios_base4InitD1Ev_ZNSsD1Ev_ZN7testing8internal23kTestTypeIdInGoogleTestE_ZTVN10__cxxabiv117__class_type_infoE_ZTSN7testing8internal26ThreadLocalValueHolderBaseE_ZTVN10__cxxabiv120__si_class_type_infoE_ZTSN7testing8internal26GoogleTestFailureExceptionE_ZTISt13runtime_error_ZTIN7testing8internal9DeathTestE_ZTSN7testing8internal9DeathTestE_ZTIN7testing8internal16DeathTestFactoryE_ZTSN7testing8internal16DeathTestFactoryE_ZTSN7testing8internal23DefaultDeathTestFactoryE_ZTIN7testing8internal23DefaultDeathTestFactoryE_ZTIN7testing31TestPartResultReporterInterfaceE_ZTSN7testing31TestPartResultReporterInterfaceE_ZTSN7testing8internal24HasNewFatalFailureHelperE_ZTIN7testing8internal24HasNewFatalFailureHelperE_ZTSN7testing4TestE_ZTIN7testing4TestE_ZTSN7testing8TestCaseE_ZTIN7testing8TestCaseE_ZTIN7testing17TestEventListenerE_ZTSN7testing17TestEventListenerE_ZTIN7testing22EmptyTestEventListenerE_ZTSN7testing22EmptyTestEventListenerE_ZTSN7testing8UnitTestE_ZTIN7testing8UnitTestE_ZTSN7testing32ScopedFakeTestPartResultReporterE_ZTIN7testing32ScopedFakeTestPartResultReporterE_ZTIN7testing8internal27OsStackTraceGetterInterfaceE_ZTSN7testing8internal27OsStackTraceGetterInterfaceE_ZTSN7testing8internal18OsStackTraceGetterE_ZTIN7testing8internal18OsStackTraceGetterE_ZTSN7testing8internal35DefaultGlobalTestPartResultReporterE_ZTIN7testing8internal35DefaultGlobalTestPartResultReporterE_ZTSN7testing8internal38DefaultPerThreadTestPartResultReporterE_ZTIN7testing8internal38DefaultPerThreadTestPartResultReporterE_ZTSN7testing8internal12UnitTestImplE_ZTIN7testing8internal12UnitTestImplE_ZTIN7testing8internal17StreamingListener20AbstractSocketWriterE_ZTSN7testing8internal17StreamingListener20AbstractSocketWriterE_ZTIN7testing8internal17StreamingListener12SocketWriterE_ZTSN7testing8internal17StreamingListener12SocketWriterE_ZTIN7testing8internal17StreamingListenerE_ZTSN7testing8internal17StreamingListenerE_ZTSN7testing8internal27PrettyUnitTestResultPrinterE_ZTIN7testing8internal27PrettyUnitTestResultPrinterE_ZTSN7testing8internal17TestEventRepeaterE_ZTIN7testing8internal17TestEventRepeaterE_ZTSN7testing8internal24XmlUnitTestResultPrinterE_ZTIN7testing8internal24XmlUnitTestResultPrinterE_ZTSN7testing8internal13DeathTestImplE_ZTIN7testing8internal13DeathTestImplE_ZTSN7testing8internal16ForkingDeathTestE_ZTIN7testing8internal16ForkingDeathTestE_ZTSN7testing8internal15NoExecDeathTestE_ZTIN7testing8internal15NoExecDeathTestE_ZTSN7testing8internal13ExecDeathTestE_ZTIN7testing8internal13ExecDeathTestE_ZNKSt13runtime_error4whatEv__cxa_pure_virtual_ZN7testing8internal18OsStackTraceGetter19kElidedFramesMarkerE_ZN7testing8internal18g_linked_ptr_mutexE_ZN7testing38FLAGS_gtest_show_internal_stack_framesE__pthread_key_createD   ]# ]%$D]I$b%(1]234 (R3]4k(]p5( ]p5((U ]] 6e 7p 8 8 8 7 8 ] 8; <a {    (  A B C" 8 ]> L   D B D1 Gz L O T V4 T t    ] ^i`<I Yfhjhmt(n]2n((E(Z(m lrp5!r)p.5g(t((((((((>(X((((,qxvvVeVM~T<[(b(k(r(y((A $,7=Da(v((((( ~%.3>CNW\glwA(((( (($(((((( *uuAW`]fgu]{g]g]g]_]]_]_ ]_!]'_6]<_K]Q_`]f_]$]$-2:JQX]]p]p]]$#]$]$]$]$VV v< ]C Q ]V $^ j #!D!'N!e!n!ps!z!!!!(! !(!nB"n\"("(" "]"8""]"8#] # #*#]0#8K#<Q# ## $T$V%$%D%d%%%x&v=&xe'j'{']''''p''''O(]T($l(q(]v($(#(]($((]($ )#I)q*7**]**]**]**]* +]+%+]*+p+]v++I+]+2+I+7+2+(+(++(r,(,(,(, ,(,?-S-7a--]----U.`.]m...... /1/Q//,0B00700]0 1 1]-161I>1O1(1(1 1(111I1 2(&2IQ2 ^2(x2(2]22 2I222(2 2(43(G3 T3(33(3C33(3I33(44;4(N4 Z4(u4(4I434I44(5($5 05(555 5(55(5 6(6 *6(T6]Z6f6Io67|626(6k636I66(6(7I7(V7(k7(v7 7(7(7(78D888888889#9(9-9r29N9!o9 y99!9$9C99 :&:'$:],:7:#=:Q:(_:(j::(: ::%::% ;5;(\;h;q;;;-;/;];8;];8 <]E<]a<]f<]<7<8<]<8<1<]<8<7<8<]<8<7=8.=[=2u===2==p=$>rO><\>;b><o><v>=>>><><>>><><??????$?7V?@]?6k?(t?>?=?A?? ?9?<?B?<@:*@]3@8G@7X@8h@]q@8@7@8@]@8@@]@8@]@8 A7A8-Al[A]oA]xAA]AA]AA AF8B:EB]NB8dBlsB8B(BpB8B]B8BB]B8BlB]B$C(CCHC:UC]^C8tClC8C(CpC8C]C8CC]C8ClC]D$D(D"DD D(D(D(D(E3E:@EpIE8QE7bE8pEEEE E F:F]"F82F7CF8SFEF]FF F:F]F8G%GlGG:iGI~G8GlG(G]GG(H oH{H]H(HH(.IJI:WI]`I8vI8IEI(I:I1IlIpJ$J(8J=JNJ(J(J J( KGKGlK:yKpK8KKK]K8KK8K]K8KK8K]L8L1L](L85L>L8KL]TL8cL1pL]yL8LNLlLL(LLLL:LpM8MM&M],M;M1HM]QM8^MgM8tM]}M8MNMlMM(MMM:MpNNN N])N8N1BN]KNUN^NkN]qN}NNNlNN(NNO O(O(O(DP;JP<TP<^P=P>P<P<P>P<P<Q? Q?Q?!Q7bQ@tQ6Q(Q>Q1QmQ?Q?Q?Q6R(R7"R8+R<1R<=R<CR<sR={RAR=RAR RQR R9R<RBS<FS;LS<VS<`S=S>S<S<S>S<S<T? T?T?(T7iT@wT6T(T>TTSTmT?T?T?T6T( U7U8U<U<"U<(U<7U<dU=iUAU=UAU UQU U9U<UBU<$V;*V<4V<>V=V>V<V<V>V<V<V?V?V?W7BW@SW6oW(uW>W1WmW?W?W?W6W(X7X8'X<-X<3X<?X<oX=wXAXXYYQY -Y9:Y<@YBVY=\YAdY sY<Y;Y<Y<Y=Z>Z<3Z<=Z>CZ<IZ<cZ?mZ?wZ?Z7Z@Z6Z(Z>][/n[m[?[?[?[6[([7[8[<[<[<\<\=\Ae\x\\\Q\ \9\<\B]= ]A] #]<U]:]]]]8]l]]^8#^],^8A^]J^8g^]p^8^8^8_8#_U/_]8_8N_8[_]d_8r_(_(_ _:`7`8&`]/`8<`]E`8[`8h`]q`8`(`(`s``V`]`8a]aJala a(a(a: b]b8'b78b8EbYb]bb8wb8b]b8b7b8b]b8bb]c8c82c:FclUc8cc(vcpcac(cc]cd]dZdYyd d(d:d8dle7e2e(^e<fe(peYe(eYe e:flf8f(?flKf7Zf2hf(faf(ff<f(gYgY'g 4g(cg(ghP$h]*h_3hI=h]Ch2Qh(bh(h( i(!i(4i fibi`i8i(ilj? j?j?j6'j(@j7Fj8Kj<Qj<`j<fj<{j<j<j=jAjcjQj  k(Wkaqk8k(k8k(k 8laYl]_llel8l(l(l mem8$m(Pm(cm m:mgmlm mn] n86n] K(`(y((((Պ(!]'A`jx(( ċ(!y-I7]=2KTI^]d2r((((]^Ɍ((0 =(R(g(((Ǎ]ލ]]]5:BP8Z]`8p7{8]8(Ȏ2&(9 b]jt]y~878p8͏<܏(eq}&'̐2ܐ (  ] 49]@n]vp8p8ؑ;N'p]pƒ]p 8]'8/EM X` ks ]ƓГpՓړ8p8/]8p 8//9]?8Gi]q{]8p8  %:]837D8T]]8p]̕8ڕ(l (0(p]]ǖ]Җ8("]+8]>T8b(y]p—p˗՗]ޗ8(Ai]r8:Ƙ]Ϙޘ1]l0p9F]Lb8o]x8]88((ؙ]((2(E R(((Ϛ((ypp8]81ћٛ < QpYcphm8w]|81 )p1;]@E8O]TY8ch1pp]8]8Ɲ1Ν  !0Fipq{]8]81ɞpў۞]8]81'/ :B appß]ȟ͟8ן]ܟ81p#](-87]<A8IN1Vow  ̠p] 8]!8+018QpYc]hm8w]|81 ¡ʡ 9pDN]SX8b]gl8ty1p]8Ģ]ɢ΢8֢ۢ1   F(Z(n((ģ(أ(((,8Ypakppu8]81 ɤ]]:+88]A8I7Z88l(ѥ]](- u~(((Ѧ( (GNSa(lq( :ͧp֧878 ]8!p*87p@8T7e8u]~8p8p8p8ͨp֨8]8l] %3(@(g]p]Ʃ(۩( 3JyVI`]f2q(((IĪ(( "(7(ilI(I]2īҫ(( %(B]G]gr:]8]ɬ֬]ܬ1]3-]68E0xaY(ϭ3]] ]#.aC]:]8®p]]a:Y[(n ۯ]]]] ]")]/;DR:_]h8sp]:]ɰ8԰p] ]'.]4=aQ(\Y o]]]]òʲ]вײ]ݲ: ]8!p?]GSa:n]w8p]]ʳճܳ]a( _Yg '],]9]D]Uah]nu]{:pε]Ե۵]:]8p<C]IP]Vbo:p]a̶(׶Y$ ]])]4]EQX]^e]kw:fp:̸]ո8޸p]:(]18:p]d]jq]w:fpʹ]йٹa(LYT {:]8pͻ:ڻ]8p]):>SGpi:v]8p:ż]μ8׼p:]8&pH:]Sfp]:]8½p:Sp ]&2?:L]U8^p:Sp]¾˾a(Y$ sess]]] :#],85pXaau(((( Y (S_]]:]8p:]'80pSZ]`ia(Y g3]@LY:f]o8xp:]8p] ]a1(<dYl Li*(9M(Xf(r(((( (Tks(( 6L`q( 5P'(  ^q(p ]8'],189>1F( :6Q](%4Ypakppu8]81  '1F<Vp(p-28<]AF8NS1[( I%I:<Og<w pp %8/]498AF1N(( n13 3<)<6DISI[mps~(((p$ET]Yp^5k(~ ((( (n>jp]vLOhH<P^d<pp8] 81!6p>HpMR8\]af8pu1}pp8]81p p8]$)8161AV(i w]:-@]w< pp %8/]498AF1Qgo z     !( :AMBoxI(II)(:(K(\(m(I(@ ((I(CIZIbjII(((((8]@((/(B S(p((((((((*(D(Y((((y$CzYm\]'()*)r!8,Yi'y]]^]^ ]^]%^2]9^?&Yf]nupz8(:+,D`s]{p8]1](Z8~]p]/]l ]#(80A(n( (((6(Q(l(( ((*(*y]]^]^]!^+p2^<]C^I&V(k((((((( X+i|/y]]^]^]^p^#]*^0&=(P ](r((((((8!@pFN&[(n 7;!:.p78DpM8Z]c8p]y8p8l]8(?]$)7(EJ]Q]b@'' y.]4?]I^S]\^mt]{^]^]^&y]]^]^ ]^%],^3]:^@&|y]]^]^]^]^&( ("(7(L(a(v( y]]^]^]^ ]^&](r(((((((:(yy] _p^)3]:^BGU(f(w((((] !]&+<<F7B]_]^((<7QC((  ! 0(I(b({((('DE#F+=]FV^`]g^v^]^&]^]^& y]'].^8]A^NX]a^k]r^|]^&(((((  ((4(I(^(s((((((((&(;(>]@d]j}"<G((]p$ (F(Y ft(I+^7^LZZ(g(( (W^c^m]~:]8p]:]8 pCLa`(ky((Y((  k^w^]:]8p]:"]+84pW`at(((Y((=(P ^^]: ]8pBI]OXe:r]{8pa(((jYx((  ^ ^! ]2 > L :Y ]b 8m p  ]   : ] 8 p  a ( - (: ( Y ( (  [ ^g ^q ]   : ] 8 p  ]   : ] 8$ pG P ad (o } ( ( Y (- (@    I I I I ( I g((0(A(R(v< E(K.(N(n(K1X(m((  (($<= K(\(gh(]p p%s{ (( (I]2"I*752C(O]Bk(r(j((E (($(IE[(v((7]6(A P(e(z(((G G]( E+n6W]E((( %(OqUij s:B/jIPe]n88]8(Bs-tC[Ri(]88p8t#P4(J]S8m}]8]l](O1OP ](z(](r( B1j<]BM(]]( P`z~<~pp8]81 @Pzv<|~pp8]81   . 6 D T zv <| ~  p  p  8 ]  8  1!!! *!N!S!j!~!z!!!!p!!]!"8 "]""8"""1*"I"pQ"["]`"e"8o"]t"y"8""1""<"~""p""p##8#]##8!#&#1.#>#F# Q#Y# d#l# z#####z###z$<$~/$V$<\$~o$$p$$p$$$]$$1$$p$$p$% %]%%1"%5%=% H%P% m%%%z%%z%% &&>&V&<\&~o&&<&~&&p&&]&&8']' '8''1$'9'pD'N']S'X'8b']g'l'8v'{'1''p''p''']''1''p'(p( ((](#(1,(A(I( V(^( k(s( (( (((((C)?a))]))])^))^)])^*^*]"*^2*^C*(W*(k*(*(*(*(*y*y*y+]+ +]'+^4+;+^H+]O+^d+^q+]x+^++]+^++]+^++(,(,(),(=,(Q,(e,(y,(,(,(,(,(,(!-M&-.---I- .NM.(u...N..N.].///($/)/]0/2^N2[2]b2^o2pv2^|2&222222 3y3]$323]93^F3]M3^]3j3]q3^~3]3^3]3^3&3y3]33]3^3]4^4#4]*4^74p>4^K4]R4^X4&|4y4]44]4^4]4^44]4^4p4^5] 5^5&(5<6(6(6(6(7(27(M7(r77(7(7(7(7(8(;8(d8u8(8(8 8y8]88]8^9]9^9$9]+9^89]?9^E9&d9yw9]}99]9^9]9^99]9^9]9^9&9:():(D:(_:(z:(:(:(:0;U;;V);(D;(_;(z;(;(;(;(;(<(<(7<(R<(m<(<(<(<(<(<(=(*=(E=(=(=(=(=(>( >(n>y>]>>]>^>]>^>>]>^>p>^>&?y.?]6?D?]K?^X?]a?^s??]?^?]?^?&?(?(?(@(!@(<@(W@(@( A((A(CA(^A(yA(A(A(A(B(B(9B(B(B(B(B(&C(AC(\C(wC(C(C(C(C(NDWeDD]DD]DD]DD]DD]DDDpEE8EeE<wEEEE<E FFMF<_F|FFFF FF FUFFVFWFUGGVGU$G,GV3GW?GW|GfGVG]G8G8G]G8G8G]G8G(H(DHaH]iHpHpuHzHH]HH8H]H8H8H]HHHI0 I I(JI]PIWI]_IrII]III(I(II]IJJ( J(DJSJ]YJjJxJ(J(J]J]JJ]JJJ(J(KRK]"K6KDK(UK(nK}K]KKK(K(KWK8K(4LAL]NL^`L^nL(LLVL]L8L8L]L8L(L(L] M^M^'M(=MIMWM(gM]oM8}M(M(M(MqM]MN]NN(N]NN(N(O(;O(aO(O(O(O(O P(P(2P(GP(\P(qP(P(P(P(P(P(Q(Q(0Q(SQ(yQ(Q(Q(Q(Q]QR] R8R80R?R]ERWReR(vR(RRyR]RRR(R(RVRy S]S#S1S(BS(QScSyqS]wSSS(S(S]SS]SSS( T(!TR,T]2TGTUT(fT(|TWT8T]T8T(TTU]U8-U87U]=U8KU(lU(U(U(U(V(*V(gV(|V(V(V V(V(V(V(W(W(>W(SW(kW(W(W(W]WWpWW]W8X8X5XyCX]IXXXfX(wX(XVXyX]XXX(X(XYy&Y],Y;YOY(`Y(tY]zYY]YYY(Y(YY]YZZ("Z(FZRSZ]YZhZvZ(Z(ZZyZ]ZZZ(Z([W'[85[(J[]P[_[]e[w[[([([][[ \2\]8\8H\8O\]U\c\(\(](=](g](](](](] ](](^(+^(@^(Y^(n^(^(^(^(^(^(_(4_(S_(_I__ __]______]` `;&`<0`<:`=`>`<`<`>`<`<`?`?`?`7>a@Pa6da(qa>|aala)a(aa?a?a?a6b(b7 b8)b</b<;b<Ab<qb=ybAb(b(cQc(-c(Cc Wc({c=cAc<c(c9c<cB d]dd=dXdd1d3dId( e7e3WeIne(e(ee(ffpf_#f&=fWfqff<fIf(f)gAg(Wg0_g kg]pgpug5g0g(g(g]gpg5gg(#hCh'Ph([hhHhh(h 1i:Ii8Wigiili]iipii(j}/jJjZjcjjqjj8j]jj]jj]jkIk^kjk]sk8k8k]k8k8k(k(l#l 4lJl(^l(sl(llllllll\mm,m:m(Gm(gm(m(m m(m]m]m]mm:n]'n;4ncn(nn|n(n]n>nYn(o Lq(|q(q q>rr r(Fr(rrr0r r(rrGsG,s:9spBs8OspXs8es]ns8ss]s8s]s8ss]s8s]t8"t2tp;t8HtpQt8^t]gt8qt]{t]t;tt>t:tpttpu#u1u]:uDu]Mumu{u]uuu]uupuupuupuupv v]v]v;(v0v>wv]vv]vv]vv]vv]ww] w0w>Ow qw>ww7ww]w6ww]wx;x:Hx]Qx8Yx7jx8wxpx8x]x]x]xDx]x;xx>x(y(yWyY_y py>~y(y]yyyy(z(z %z9zEzSz^z]kzsz#zzz]zzzz]z{-{N{^{{{p{{#{{{{]{ |^u||| }}$})}]1}?}^}}^/~=~D~K~]S~~~v~O)o3Fg^ %^n#,^xpv9N]V]pbgn]t}1]1]Ƀ^QY a~p(̄]ф]] %(1 Q`x(Ʌpхۅ]8]81)p1;]@E8O]TY8af1n  † Ԇ/bIp]Çȇ8҇]ׇ܇81 p ]%*84]9>8FK1Sq   Ј(l( (U(h u(҉III:R(e r(IЊIߊI (/ <({IIINjً( (>ISIbI( (3?IWIcIrI(Ie(ɍ(ڍ(((&5C(Rqpy]8]81ݎII((Ǐ(܏( ($ D(d(}((]Ԑ(] 7]=X(k II((ב((   4E\:m1{l((( ((=({a I5g7 ##$2$|$w$x$Rg&vY) 008[9"<8>=`q8t8!u1x7!#ii:)p/;B]MZ]cp|]]l &&\&`&&&(','   '(% '( 5>,.(<T,.(<T`%(3Kdp B l)762D(\v<((( (()(=H(U`(u((5?(M 6(7)8=<";(<5<<=><<><<???7@6-(8>Jl^8l(<=A ( 9 <B  $(,048<@DHLPTX\`dhlptx|  $(,048<@DHLPTX\`dhlptx|]]] ] ] ] ] ] ] ] ] ] ] ] ] ]$ ]( ], ]0 ]4 ]8 ]< ] p 6(#7)81E()E%'2(=Tb(lu I7&2@(JS 7(-n:2C4^(hq ;<$<.=><<><<???72@D6X(_>(m???6(78$<*<6<U<i=nA](Q 9*<0B@=FAN W<;<$<.=><<><<???72@C6Z(_>tum???6(7"8+<1<=<\<p=uA]v"9/<5BE=KAS b<|uQ v:"1-lj :&}1ln I45(?H '9]AKpPU8_pdi8q  )p1;p@E8O]TY8af1n 1p9C]HM8W]\a8in1v 9pAK]PU8_]di8qv1~ ';]CMpRW8fk8w]}88]p8p8   '3(@(T_(l(( '3(@(Kdo(|(( )7'L(Y(d|(( )7'L(Y(dp(( I#])22Ui]q{p88]88(]p8p8!D]k(u~ (](I07;2IW(d(|((( ](I07;2IW(d(|((( x ]1:]@_KY(f(v]((( ]$x9yExS]Y_eIo]u2]^((((((&(7(T_(s~((((((3p(z(((((((  !(+yp"_0>(K(do({((  9pAKpPU8_]di8qv1~ )IpQ[p`e8o]ty81 ].I8]>2Gj~]p88]88((]#p(-87p<A8It(( ($|*v2]9]JV]\_hIr]x2I]2(((((('(3>(KV(cn({(((((( (!* L(V!|'V/]6]GS]Y_eIo]u2I]2(((((((+6(CN([f(s~(((((((" D(N*|3xC]T`pf_rI|]2I]2(((( ((;vK]\g({(((((#(-8(BM(W` s(}((:'l68D(\le7r2(<(Y(# .(7:*758NlW7d2r(2<(Y( :(8AlJ7W2e(<(Y( :*758NlW7d2r(2<(Y( :!0:lC7P2^(<(Y( :*758NlW7d2r(2<(Y( :%768OlX7e2s(]8<(Y( :*758NlW7d2r(2<(Y( :*758NlW7d2r(2<(Y( :*758NlW7d2r(2<(Y( ;<<=.>4<@<V>[<a<{???7@6 (>3SA;K<X=><<><<?? ?7^@o6(>Sll]]!5:E]N8\p}]]a(((?#?-?76?(X7^8c<i<x<~<<=A???6(78<<%<4<:<j=rA<=%A- 6<X=^ApQx 9<BY((Q39@<FB%;+<8<B=><<><<?? ?7W@h6(>S;<=)>.<4<Q>V<\<|???7@6( >4SIl^lk]]:]8p]$]*3>aU(du((???6(78<<<<<:=BAU?_?i?s6{(78<<<<<=AWgw<=A Y(!/(<KQ]Qe |9<B=A<9<B+IpQ[]`e8o]ty81 ,BpJT]Y^8h]mr8z1( (+9 c]p8]81]81] )]4>pCH8R]W\8fk1w]}81]81]  6]8/>]D8V]\8f]l8u1]8]8]8]8]8]86]<8V]\8v]|8]8]8P]_ 8(*(:]@8U][8d1yP]88(8]8&(0;(F S(]  $(,048<@DHLPTX\`dhlptx|  $(,048<@DHLPTX\`dhlp]82F]L8^]d8n]t8}1]8]8]8]8]8]86]<8V]\8v]|8]8]8P]_8(/(?]E8Z]`8i1P]88(8]8.(8C(N [(e  $(,048<@DHLPTX\`dhlptx|  $(,048<@DHLPTX\`dhlp]8$0]68V]\8e1]8P]88(( ()EY<7Q<.Y<718y@]FQ]X^b]i^y]^]^&(((( (!(+6(?H 18y@]FQ]X^b]i^y]^]^&(((( (!(+6(?H 1DyL]R]]d^n]u^]^]^&(((( ("-(7B(KT 1DyL]R]]d^n]u^]^]^&(((( ("-(7B(KT Y<7Y<7:%768Ely]8 Y<70M2OC(NYQQZQQS+QC<WIlT<UVW Y&Y<pDNpSX8`jZo[u\] ;<$<.=><<><<???77@E6Y(^>u}m???6(78<<<<<+=0AOe<=A Q 9<B8K^w,nQQQQXQQQ?`^`}``` `*`p$k?lWm`((1<AG(v #)<AGZ_ex}AHH,17JOUHhms]v(]] ]"0F(PY 3L=BK(v $)1DIQdiqA H$)1HDIQdiqH]v( ]$]*<]BQg(qz {&{<pDNpSX8`j|o[u\] z><D~Vypp8]81 %(3(ICIt(<IIJI~(U$V/(9B XUpVWU(UVWW 9LA FT(`-f-(-L--I-- (:xBf-ky( (  AJ O](h-n-(---I--(0u8Mf-kx( &(4XF<L,Ip$p).5];D1Ll<W  UV~U9(W(W U9().WDULVW(afWo vW ~U9(W(W U 9!(+0WHUPV[(ejWs zW ~U9(W(W U9().WDULVW(afWo vW ~U9(W(W U 9!(+0WHUPV[(ejWs zW 9IaI(<MIII( ?UV( U VW#U4(>MUX`VeWqW4IIIXI((UVW 0IEITIuIII0BP(](j(|<III+G(T(h(r(( U'/V8UTfUr (( W#(-8(BQU*I9I^(hsUVW (I7ISI_I(()<EIVIzII((v~ ( (U( U!)V2UGbWq({UVWU ! *]/J8]=BJGP]UJ\]a]fkKy~ ]K ]]KAA  ]J]$L)2]7L=E]JJOX]]Lci]n]sK} ]J (  ]GK  ]J$*]/4<AFK TX(]bgl u---0- y   Y[{[    $(,048<@     { z$(,~048<@   ! $(,048<"@  ) * $(,048<@     -.-2 5>.-4 6.- A Z- .|  !(/*=PWdt})5@KQo *1NUry !(Ge} '.KRjq)5Kf'4Tiu   % 7 B M X ^ g m             5 < Y _ w ~          ! 8 ? V ] t {         * 1 J Q j q           ) 0 R Y l s |     =] )0On !(@G_f$AHk;Bip")PWy LSz#*GNpw 7>jq,3_f*1\c/6NU| 'NUw~ 'IPry"IPry"DKmt"IP!DJWu|    # - 9 L Y y          ! !!%!1!>!P![!f!q!w!!!!!!!!!!! ""'"-"N"U"r"x"""""""""##3#:#Q#X#o#v######### $'$C$J$c$j$$$$$$$$$% %#%*%B%I%k%r%%%%%%%&1&V&v&&&&&&&'#'*'B'I'h'''''''''(("(:(A(Y(`(x((((((((()))6)=)Z)a))))))) **0*7*T*[*********++;+B+i+p+++++++ ,,2,9,e,l,,,,,,,--<-C-`-g-------".).P.W.......//E/L/x//////00C0J0u0|0000000 11)101H1O1g1n11111112292@2g2n22222223393@3b3i3333333 4444;4b4i4444444 5545;5]5d55555556646;6b6i6666666666666677777#7*71797A7H7O7V7_7k7q7w7}7777777777777777788828K8W8d8k888888889'9C9Q9m9{999999999::":0:>:m:::;;@;a;g;;;;;;;;;;<"<?<E<b<k<t<z<<<<<<<===8=>=P=d=j=|=========>>">->A>L>`>k>>>>>>>>>> ??!?:?I?R?k?z????????? @"@(@?@E@a@g@@@@@@@@@@AAA(A2ADAPA\A{AAAAAAAAAABB1B7BSBYBuB{BBBBBBBBCC/C5CLCRCnCtCCCCCCCCCDD:DAD_DhDDDDDDDDDDEE3ESEjEsE}EEEEEEEEEFF*F?FGFbFmFyFFFFFFFFFFFFF GG#G)G]|/6NUsz>a~ 8?X_sy29MTrx.4QW'1AIU`kv(3>HTgy5>IYew $/5LRio /5RXz+7CYz%,DKj$<C[b%,Kn&-ELel&?FZa";A^d'=Xp|#:N[o|%1?LYfx%=D\c| ")AH`g!5<PWkr (/CJ^e&-NUqx?Fl $+CJi#;BZay 3:RYv}$+IPdk<C`g #.9DYsy +1RX~ *1HOfm .5[`jv&2>JVb&-ELk%>Egn =Dah9@]v #.9COZepz +6ALVbmx 29U\ 1;GPZmt +2G]nz )4?IUdm(1JP]f&<MYdj}#/:@S\g})2=Sdp{):FQWjs~%6L]s)2=Sdz 6_ 6_'=Nduz(/LSpy%9I]| /8AUenw +:Ihw /GTn%GRfq0;]h|#.BMo4NYmxFU^w.=Qap*:IYcl & 6 E U _ h             7 G V f p y           & / M ] l |      5 E T d n w           $ - F V e u        %5DT^g 6FUeox %.GV_x9IR[o!*Hp!1:S{,<E^m| &5>WgpyEThx GW`i*:C\l7GPw%5a&DT]v /8Qaj?O{.7@^nw:IRk{  ( 8 A J ^ n w       !!)!2!;!O!V!c!l!u!!!!!!!!!! ""#"0"9"W"]"j"s""""""""#&#6#?#]#m#v#########$ $$%$+$;$A$N$W$u${$$$$$$$$$$$$%% %'%.%5%<%C%J%Q%X%_%d%o%{%%%%%%%%%%%&&&+&8&E&R&_&l&y&&&&&&&&&&&''')':'E'Q']'|''''''((A(\(x((((()")M)h)~)))))*;*[*v*****++9+t++++++++++++,.,M,l,,,,,-.-N-m-----..1.7.O.V.n.t........//./A/U/m////////// 0$0<0T0g0{000000001 11$101<1R1m1111111112 282>2\2b22222222233$3A3G3d3j333333333 4,474B4M4X4b4o4}4444444445545;5X5_5w5~555555566+626O6V6n6w66666666667747;7S7Z7w7~77777778 8&8-8J8Q8n8u8888888888888999$9.9:9E9P9[9f9p9|99999999: :':-:J:P:r:x:::::::;;;(;.;F;L;e;k;;;;;;;;;;;<<<&<2<><T<o<<<<<<<<<="=:=@=^=d=========> >&>C>I>f>l>>>>>>>>>"?.?9?D?O?Z?e?k???????????@@)@5@J@n@x@@@@@@@@@ AA+A2AJAQAnAuAAAAAAAABB$BABHBeBlBBBBBBBBBBBC C8C?CWC^CvC}CCCCCCCDD%D,DIDPDmDtDDDDDDDDDDD E!ERIRTR_RjRuR{RRRRRRRRRRSS$S9S]SgStSSSSSSSSSTT'T.TFTMTjTqTTTTTTTTTU U=UDUaUhUUUUUUUUUUUUV,V2VOVUVrVxVVVVVVVWW.W:WEWPW[WfWqWwWWWWWWWWWWXX X5XYXcXpX~XXXXXXXXXYY5Y_b_l_y________```&`>`E`b`i`````````aa5aeEe]ede|eeeeeeeeff+f2fOfVfsfzffffffffff g"g>gEg]gdg|ggggggggh h&h-hJhQhnhuhhhhhhhhhi ii$i0iFiai|iiiiiiiijj,j2jPjVj~jjjjjjjjjjjkkk1k7kJkPkdkpkkkkkkkkkll5lx\xbxzxxxxxxxxxyyy-y3yLyRyfylyyyyyyyyyzzz)z6zCzPzgzzzzzzzzz{ {#{*{G{N{k{r{{{{{{{{||#|-|:|H|U|b|o|||||||||}#}*}B}I}f}m}}}}}}}}}~!~9~B~e~q~}~~~~~~~~~"?Egm(3>D\b{ǀ̀&0=KXerāˁ &-ELipՂ܂$<EOYeq}҃39[aDŽ/5NThn 'A[ktņΆ(<LUiyÇӇ܇ -6JZcwˆ҈ۈ,5IYbvщډ+4HXauϊߊ2>G\w*6BNZfr~ƌҌތ&3M^it̍׍ +6ALWbnzǎҎގ &2?JVbnz̏ۏSMXn)2LZc}ǒВݒ".:FēГܓ $0<HT`l~ȔՔ ,=N_pȕՕ"Ɩߖ&?F^e !<Cbo}Ϙ֘,Hcj֙+6Q_zښ7>V]vʛЛ  &@F`f֜ܜ1LgmȝΝ"(BHflƞޞ%=C[ayӟٟ %1VqƠӠ&2?Yu|ӡڡ07OVszȢ֢ $6BOiģˣ !(@G_fˤؤ =Dhvѥإ,CTago|֦5;\b§ɧ٧&2?LvͨӨ $+ESZlzҩ٩!(D[v}Ϫ!(BO\x٫0KRwլܬ29QXqʭܭ/Fah~Ǯ,3KRlsïʯ>Egn 4;biα۱9U\uDz%?KWcoɳϳ*6BNZfr~ƴҴ &BIfµ̵ӵ *7DQ^v϶ݶ*7DQ^kxƷӷ!.<KYuոܸ3:RYqxιչ +2JQipƺͺ -4LSkrɻл 'JQipļ˼ 9@]dxսܽ29MTlsȾܾ5<PWkrĿ˿ -IPh ,3Rr;W^v}:GTp(CJk|(5C[h,HOgn@MZv.IPq;B_f<CW^y 29[b 29[bHU[agn{ 29Vp -4Ln{ ")<CVqx%2GT[ox .5Sep$EKlr Jk5MZs.OVw $Egn8?W^w~5<Xp}1>[b/6ah /6ah")OVip07PWkr2JQgn9@bi /6]d7\s:BXn4J`v !;Od{(1F]t,B\{.EXdm(4=FNZg0\y#6=RYipu|&,?FOVjqz(/GNl $KRel 29RYmt *1ELnt*ASZsz@Gip")6JYbv|39BK_ez%+ELYbqx!(JQsz$+8AQls| '@GXm$.4<AGQ[akq{ #-3=CMS]cms} ".;HUbo| "=X^{ %+Dk.U{ 1XBi,Sz=d'Nu8_"Ip<B\ht %1=IU39QWou  + 1 J P m s         $ + C J b i           D l        = d k     0 X     &Ks !(/:ALS^e{1DK_f #*BIc6=U\t{3:W^u|29PWjq '4AN[w~18P!+6X_|*1JQnu&-@[bx /6]d*1SZ|'8EKYjv #=CYju '4AN[hu&-ELdk  % = D \ c {         !!$!>!>'>->4>@>L>_>k>q>w>}>>>>>>>>>>>>>?? ????&?-?4?;?B?I?Q?Y?a?i?s?~?????????}G,I>IKIhIIIIIIJZJyJJJJJJKK;KEKPKcKKKKKKKKLCLMLrL|LLLLLLLM'M1MPMZMgMMMMMMNCNMNlNvNNNNNO=OJOOONPXPoPyPPPPCQMQ\QQQQQRRR;RERTRxRRRRR"S4SASSSSSSTATKTeToTTTTTT U&U@UZUtUUUUUUU V)VHVgVVVVVVVWW;WUWtW~WWWWWW X$X>XXXrX|XXXXXYY.YpYYYYYYY ZZ(Z@Z]ZwZZZZZZ[[?[Y[s[[[[[[\8\B\e\o\\\\\\])]C]M]j]]]]]]^B^^^^_(_2_L_f_____` `,`K`e``````aaa"a/aQa}aaaa b#b=bWbqbbbbbc ccc*cXc}cccc d0d9dBdLdYd{ddddd+eEe_eyeeeef7fcfmfffffggKgUggggggh3h=hmhwhhhhhh(i2i?ioiiii3j_jjjjjj k*kDkckkkkkkkkl/lNlmlwlllllm$m>mXmsm|mmmmmnBndnnnnnoAoyooooop pJpdpppp q&q@qXqeqqqqqqqr#r0r=rSr`rrrrrrs6sNs[sssssst1tPtotttttttuHuguuuuuvv$vVvpvvvvvvvvw;wmwwwwwwwx6xUx_xxxxxy.yHycylyvyyyyyyzKzezzzzzzzz+{4{I{X{{{{{{ |/|I|_|n||||||}.}D}}}}}~V~|~~~~1G(Nm)?ǁ)Hc AKlŃ?eڄOzЅم.8Ԇ_~Ӈ%DNku҈+QgЉډ",Vs}"FPj܋7isÌ݌>Hō΍؍Pj̎Cnݏ *6M`lO\kxّ )6^xŒ.8ZcmzГ"<Ӕ2>dn˕Օ =ۖ #BLXoӗ(\eo|^hřϙۙ7A[e˚ޚ/Idmw˛؛&CLVcҜܜEenx#akȞҞޞ:Y)Tˠ #áݡ%?YsGQãڣ (NhrҤ%Dڥ)@JVmw)K`i~Ч0fp̨֨@Jdnک9ZoxĪЪܪ +8[hӫݫ$-7COkݬ=s}խ (Gݮ%;So¯uϰ&HRhOYxβ.gϳ"A״9C]gɵ;Ѷ۶3Mg7Qk׸9COkuǹԹ%=Wan3d~ '4APis¼߼:߽ )3KU^hu̾־߾ \{1;Gcm#0=Z#FPhr{ =y)3KU^hu \{ .;HWpz0=Jg 5OYq{'1>Kh1\{(1;HUr*I3=Zd%2?Ngq8R"1JTlv5 #-6@MZik*?HR^jx+Mg)7A:CLVc0qi .7@JWdq)FPu+CL_ly(E_ )6Xajt7@JW~%DNZv ,U_lDenx%C][5f)`j(g>`F<bR&C`z )KUoy 6Pj.HRt$.HT =G*| r-C`v#xU*iO5PjtV8BO",8DRjsEOYf1Ke*BKUam -6?IVcp 3=]g(B\v'?]z '1Np'DNpz 7 A ^ x          & G Q n        " A     , 6 X     ? Y s   /9Sr":CVcp1Kr/IS~'3@MZx,AJTa1;[ep;l!.;Jc$1>V_iuAJS]jw )3@g'DQ^(6NWjw&3Pj-JWds )3?Kbku   ' 4 A N k t ~        !#!0!?!X!u!!!!!!!!"&"3"K"T"^"j"v""""""""""##6#?#H#R#_#l#y########$$"$/$V$`$$$$$$$$%.%;%H%W%p%%%%%%%%&1&>&K&c&l&v&&&&&&&&&&&'','N'W'`'j'w''''''''''((:(O(X(b(o((((()()7)S))))))=*q******* ++1+ E+K+ `+ t+|++ ++++++ , ,:,I,M,z,,,,,,, --F- Z-z-"--$--&-.(*.J.*^.~.,.....0./2./W/4k//6///8///0*0<0P0a0000000000 1+191?1M1W1h1~11111111 2222C2c2q2w222222;23=-3M3?a33A33333 444!464:4C\4`4E44G44I44K44M5M.525OO5Oh5l5Q5Q55S5S55U5U66W76WP6T6Yq6Y66[6[667 7+7F7P7m7w77777777777788858;8O8j888888888 99999C9R9f9999_9_99a9a9:a :a::E:[:i:s:w::::::::::;;;!;G;];k;u;y;;;;;;;;;;<<<#<I<_<m<w<{<<<<<<<<<< ==!=%=K=Y=c=i=w==========> >>%>3>7>]>k>u>{>>>>>>>>>>???-?7?E?I?o?}?????????@@+@5@9@F@P@^@b@@@@@@@@@@@AA-A3AAAKA`AjA{AAAAAAAAAAAABBB(BaHaLaYacagataaaaaaaaaaaab,bKb`bfbqbbbbbbbbbbbcc#c8cBc_cgcccccccccccd dd#d-dHd_dydddddddddd eee9eOeXejeneeeeeeeeeeef#f-f3fKfjffffffffffg#gEg_gcgwgwggwgwggwggwghhhw1h7hwBhwQhwUhfhphwthhhwhhhhwhwhhhhwhiiw&i1iw5iBiLiRiwfiwuiwiiwiiiwiwjwjj!jw5jw?jwYjxjjjjjjjjjkkkk/k9k?kNkRkekqk~kkkkkl ll%l1l5lFlPlZl^lolylllllllll mm-m7mNmXmomymmmmmmmmmmmmnnnn0n;n?nLnVn\ntnxnnnnnnnnnnnnoo%o6o@oFouooooooooo pp!p9pGp]pgpkpwpppppppppppppppqq&q0q4qEqPqTqaqkqqqqqqqqqqqrrr#r6r@rWrarkrrrrrrrrrrrrrsss$s(s5s?sEs]snsxsssssssss ttt,t6t:tGtQtYtit}ttttttttttttuuuu,u=uJu[uju~uuuuuuuuuuuuvvv/v@vOvcvtvxvvvvvvvvvvvvwww,w=wLw`wqwuwwwwwwwwwwwww xx4xNxbxjxtxxxxxxxxxxxxyyyy'y-y7yEyIyjyyyyyz"z&zGzKz\zfzzzzzzzzzzzz{{1{;{G{[{e{|{{{{{{{{{{||(|,|>|I|O|^|r||||||||||||||| }}}*}.}>}H}N}]}{}}}}}}}~#~-~3~K~i~~~~~~~!9Ww  *4NXr|ŀπӀ &59ISYh|΁ҁ4?CPZ`x|ǂтׂ "-1>HNfjzŃ݃,6<TXhr˄ $*B`ׅ0Nnņ8Xisyȇ҇/JP[eȈ,Tfz͉׉ +9CGT^koŠي )7=IYcz]ȋՋ'-:@KUjtzԌ '1AUkuǍэ/9?JT^rŽӎݎ)6:KUYjuȏ/=GKaerxȐ̐ݐ&6:KU_cpzÑ3=G\g|ߒ+:DYcnʓԓޓ )-LP]gqwƔ 3HRcoǕ͕4>Shrϖٖݖ *48EQUfqu—ݗ#-8SlpΘ.?IOcnǙљ]#8BHW[n]y]ǚ0Kfƛ̛֛ &0?Ch|Мܜ !)/>Bc|ȝם۝ #'HY_osϞ ,=CSgxğ՟۟/3TswĠʠܠ 2CGTZhrס0:\`¢բ&4>jУԣ~~ ~(3~7DNT~l~p~~Ťˤ~~~~!.8>~W[|̥֥ܥ$/3@JPimϦ.?^bƧ֧ܧ '1FPVakuɨݨ0:AGRXcixЩک +6GQboʪߪ)3=GQ[es߫2<GX^lvz¬Ƭ֬!+;V\fpz̭߭;K[euЮԮ1<MW]q}ǯѯۯ (=HYci}ΰذް *.;EKcgxбڱ /AK`k|Ѳܲ"1Qaqwų$9CM^hrȴ޴],9=hlĵȵ /?Rs¶Ҷֶ&FV`vz׷:Rblv̸ָ '1BLRbrĹ޹5TXy}Ǻ !+>RZ`qwͻٻ"&3=GK\bm}]]Ǽͼټ*:X\lv˽ս۽ #'8CGT^d}̾־ܾ%9FPZdx~ĿԿ޿&7AG[apt *4ITeou  !04EOY]isy 1;?KUYjuy#)BWaq{";?OUeiy(48HRXgk{$9DU_ey#->HN^r|$.4HOau+5;F[lr}.2CMQbm~,@MWk*48ITXeou!6@PZoz!'<FPZdo *?EP[mw '-EIYdx 4:IM]gk|7;KU[bt~$<PZoz/9CT2;Eg+/<FLZdj{.>NT_epv 7AVfv]'?[lv| -7=Q\gv *:DJXhr|)?IO]s} &9IXy}] 2<PZ`k] /M`t~ $5DHXbl1;APTdnt'1;PVas} &*;EOSdjy}BV`pzKUdh-7Ax6@DU[fj{%/9=MS^nx ",6:FPV`is}  *.?J[ev +5?TZep"&6@J_ep{ '-<@Q]nr~ )37GQ[pv &0=\v99%+9<9L9akq999999 99/9?9P9`9du{99999 9$95?H9R9o99 %06AGeiz&*:@OScmw )39Qak .2CMSdht~ ,0AGVZkuy"/DNcn*4AEV`fw{+/?IShr-Ggx )/@DPZ`qu #26GQUfqu "7AQ[lv !28G\fl%59JTXdnr>N^hs}%/9NT_jz*KU_jy] ]"(9=NX^rx (26GQUblp})/>BS]amw{,6KVgqw " C M X g w           ' + 8 B H \ |              < @ M W ] q            & * ; E K \ ` l v |              ! 2 ; L P a k o {               %):DJWgk| (8BS]j %+CXbr|6@JT^i  1;EI`fuy &0GQ^sy *4EO`ix| "->HNfz)/:@^s}  *0AEQ[arv)/@DU_evz#-3@PTeou "3=CTXdnt .2CMQ]gkx -?IYct~$5?E]r|"/?CT^dq $*7GK\fly    , A G V Z k u y           !!!$!6!@!P!Z!k!u!!!!!!!!!!"")"3"D"N"W"a"g"q"|"""""""""""### #&#3#C#G#X#b#h#u#############$ $$$.$2$C$M$S$d$h$t$~$$$$$$$$$$$$$%%%%+%5%9%F%P%]%r%x%%%%%%%%%%%%% &&'&1&B&L&U&g&q&&&&&&&&&&' ''+'@'J'Z'd'u'''''''''''("(,(6(U(_(i((((((((((( )))))3)7)N)T)c)g)~)))))))))))***6*@*M*b*h*o*y************+ ++'+1+A+K+[+v++++++++++++,,",&,7,=,L,P,a,k,o,,,,,,,,,,,,,---$-?-I-M-d-o-s-----------..4.>.B.S.Y.d.h.y...........//&/0/:/>/N/T/_/o/y////////////0 000-030B0F0W0a0e0v0000000000000111151?1C1Z1e1i1|1111111111122!2?2C2[2e2i2z222222222222233+373;3L3V3`3d3t3z333333333333 444)43474C4M4S4]4g4k4x4444444444444445 5!5%565@5J5N5Z5d5j5t555555555555556 66'6+686B6H6a6q6w66666666667777!7+7=7M7]7{7777777777777 88 8$8;8A8P8g8s8w888888888888 99$9+959;9F9J9[9e9o9s9999999999999999 :::(:.:8:B:H:]:a:r:|::::::::::::: ;;&;0;A;K;U;[;i;s;;;;;;;;;;<<<"<0<:<K<U<_<o<y<<<<<<<<<<<<<===$=/=3=@=J=P=i=y========= >>>>)>8>X>h>>>>>>>>>>? ? ?*?0?E?I?U?_?e?v?z????????????@@@'@1@7@H@]@g@m@@@@@@@@@@@@@A AA3A=ACAXA\AhArAxAAAAAAAAAA BBB,BGBMBbBfBrB|BBBBBBBBBBBBBBCCC0C4C@CJCTCiCsCCCCCCCCCCCCC DD D$D5D?DCDTD_DpDzDDDDDDDDDD EE E1E7EFEJE[EeEiEuEEEEEEEEEEEEFF#F3FCFMF]FpFzF~FFFFFFFFFFFFFGGG$G9G?GJGUGeGkG{GGGGGGGGGGGGGHH H*H0HAHEHVHbHsHwHHHHHHHHHHHIII.I2I>IHINI_IcItI~IIIIIIIIIIII JJJ'J1J7JOJSJdJjJyJ}JJJJJJJJJJJK,KAKKK`KkK|KKKKKKKKKKLL"L.L2LCLILXL\LmLwL{LLLLLLLLLLLM MM!M:M>M_McMsM}MMMMMMMMMMMMN NN!N%NONSNdNnNNNNNNNNNN OO,OWHWLWXWbWfWsW}WWWWWWWWWWXX&X0X:XKXUXbXfXwXXXXXXXXXXXXXYYYY!Y5YFY[YeYuYYYYYYYYYYZ ZZ&Z7ZAZJZTZ_ZZZZZZZZZ [[[6[B[W[b[f[w[[[[[[[[[[[\%\6\:\K\U\_\t\z\\\\\\\\\\] ]]#]']8]B]F]W]b]f]s]}]]]]]]]]]^^&^7^A^G^[^e^t^^^^^^^^^^___)_2_=_K_U_f_l_y____________ ```%`/`3`C`I`X`\`l`v```````````aaa!a%a2agNgXgmgxg|gggggggghhh'h6h:h\hthhhhhhhhhii#i)i=iDiSibikiti~iiiiiiiiijj&j0jGjQj]jrjyjjjjjjjjjjj kk-k8k>k\k`kqk{kkkkkkkkkkkkklll$l/lAlKl`lkl|lllllllllllllm m$m9mCmXmcmtm~mmmmmmmmmmmmnnn#n-n3nEnInZndnjn|nnnnnnnnn oo(o3oDoNoTohonoxoooooooooooppp'p1p;pPpZpkpuppppppppppppppq7qXqiqsqyqqqqqqqqqqqqqrrr+r5r;rTrdrjrvrrrrrrrrrs sss$s3sCsNsTs_spsvsssssssssssst tt't8tAtRtVtgtqtuttttttttttttu uuu-uLulu}uuuuuuuuuuv vv#v'v4v=vWvgvwvvvvvvvvvvvv www3w=wNwXwiwrwwwwwwwwwwwwwx:xKxUx[xoxyxxxxxxxxxxxyyy/y9yJyTyeynyyyyyyyyyyyyyz6zGzQzWzkzuzzzzzzzzzzzz{ {{!{.{L{f{{{{{{{{{{| || |4|>|D|S|g|q|w||||||||||} }}}3}=}C}R}f}p}v}}}}}}}}}}} ~~~(~2~G~Q~b~l~}~~~~~~~~~~~~~  *?JN[ek-AK`k|Àۀ'=]HNYhwʁ]с܁]'28MWlrʂԂڂ *=]HNeo݃ !+1<FaƄۄ]"-7W[҅&6TXpz~Ɇ͆)MQblvżև $5?IM^hnx|ˆƈӈ݈!2;W[lvЉ *0EKZ^ouŠƊ֊!:JP\`wʋ΋ۋ.>NbwČȌٌ$<Q[p{ɍӍ,Kk|Ȏ׎+@Q[ev̏Џݏ$9DU_e}͐אݐ4EOUis}đՑ] 5]@FQ_jpʒΒߒ#.Ddw]ԓ(2<FJ[ekv)39H_]jp{ϕӕ  ]tȖ̖ݖ 28GKbhw×Ǘחݗ#0EKR\bmqŘɘ֘ *4ISdnÙǙؙ *4>BR\bt~ȚΚܚ *4EQUblrƛЛڛ2?ETXio~Мڜޜ 4DJVZq{ĝȝ՝۝(8H\qžӞݞ6KUjuß͟&Eev Ѡ&0GQYmw{ǡޡ "=VZku{΢ע &*7AG_ct~ף '17Odnäͤפ'17KU`oΥޥ %)5?CPZgʦަ $;]FL`uѧէ +Ect~èǨب 1;?P[_lv|ȩө !+@K\flʪԪ'8BS`duث(28LVo]vѬެ4?R[it~ҭح]#'8BFSYi~ծ] $1;AY]nxѯ!+1IhǰѰ۰"9L`jpʱб߱ (2?]wʲײ  &5JTZim~óɳ 1;AU_is}ʹڴ '+<GKXbhеڵ ,7HRXpʶж]",7K_lʷз߷]0:>KQav͸]ٸݸ )39QUfptɹ޹ $(9DHU_e}úغ޺]"3>BOY_w{һܻ *?FQ^hs}üؼ޼] %):EIV`f~νؽ޽#4>BOUeizžݾ-7=Ujt˿տ߿0?HQ[k{ 5>GQ^ly0=AQ[am0:OZku{/9NY]jtz $8BHSgq#4>D\pz&7BLPako%=AR\q|-1BLalp}!2<Q\`mw} ",ALP]gm1<@MW]uy !,0=GMeiz -7=Ujt (.G\f{ 9NXmx +@J_j{2<Q\mw}$.CN_io 5@Q[az'2CMShr|/?N]l{+59JUYfpv,0@JNZdhy 59ISYhl|!.8>VZjt &,DXbw 2FPep 4>S^oy+5JUfpv#8CT^d| !+5@\l| %5?IZdj|#.?IOew1Rcms 04EOU`r|'17B]| 59JTitx %):DHYdhu*4ITeou$9DU_ey=KUYvz(=CN^s}!+@FQ_isw !+/@KO\fl5BUt!15BLVZjt{%/7NX\mw:U[oz(2BS^h} %/DN_iz$.8BLV`jt~"9pFUjv *ApN]r~$.E]Rav(2I]VezCQ[_pz~'8BS\ko'<HWlx0<K`l{(4CXbhw%CWdt~ %+<@Waeu &7;GQWhl} "&2<F[ev ",AK\hl} &*;EKXhl} "&2<F[ev0Pq &*;AThrx /9?P`dtz!2<EUYjtz   ) 3 H R c m ~                $ 5 9 E O U f j {              % ) : D H Y d h u            * 4 I T e o {                $ 5 9 E O Y n x            $9CIZjn%6@QZko!+7LVkv-1BLP]gm} $.?IVZku"/DNcn&Dcmw 5;JN_i~":\2AEfj{ '+<FJ[fjw2Rcms $.2?IM^h} )>IMZdj5FPVkx #'8BW]lp#'4>D\{ *0ES]w] ] & 1 C M b m ~             !!!!2!?!C!T!`!o!s!!!!!!!!!!! """+"/"@"P"e"o""""""""""#####-#7#A#K#[#_#p#z##########$$#$-$3$G$V$j$w$$$$$$$$$$%%%%-%7%A%V%\%g%r%~%%%%%%%%%%%%%& &&*&.&?&I&M&^&i&m&z&&&&&&&&&&''9'Y'j't'z''''''''' ((((5(9(J(T(Z(j(n((((((((((((()))#)')8)C)G)T)^)d)|)))))))))))) **(*3*D*N*T*l*********++/+3+D+N+R+_+i+m+z+++++++++++,,,,%,4,8,I,S,W,h,s,w,,,,,,,,,,,,,- -$-9-D-Y-c-x-------- ...0.:.N.b.o.........../ //-/1/B/L/R/b/f/w/////////000$0.040C0G0X0b0f0w00000000000000 1113171H1R1V1g1r1v11111111111112 2#2'282B2F2W2b2f2s2}222222222222233(32363G3R3V3c3m3s33333333333344"474B4S4]4c4{44444444455'525C5M5S5k555555555566"636=6C6[6p6z66666666677#7-737K7`7j777777777777788.8D8X8\8m8w8}888888888888999#9'989C9G9T9^9d9|999999999:3:D:N:T:h:r:|:::::::::;;%;p2;A;V;b;m;w;;;;;;;;;;;<<,<6<F<O<^<b<<<<<<<<p<<<===%=/=9=E=T=X=y=}=========p== >>">,>6>@>J>W>a>p>>>>>>>>>>>>??$?0?;?E?O?Y?c?p?z??????????@@@@&@0@E@Q@`@u@@@@@@@@@@@@@@A AA*A6AEAZAfAqA{AAAAAAAAAAAABB%B)B6BKYKcKmKKKKKKKKKKKKKL LL&L*L7LALGL_LpLzLLLLLLLLL MMM(M>MHMRMhMrMxMMMMMMMMNN N$N0N:N>NJNTNXNhNrNvNNNNNNNNNNNNN O OO$O*OBORO\OqO|OOOOOOOOOO P P*P4PJPTPZPnPrPPPPPPpPPPPPQQQ$Q0Q?QSQmQqQQQQQQQQQQQQ]QRR(R2R8RCRUR_RtRRRRRRRRRRRRRRSS)S3SDSQSUSfSrSSSSSSSSSSS T TT(T.T=TATRTbTwTTTTTTTTTT UU!U+U5U?UIUSU]UmUqUUUUUUUUUUUVV V1V;VAV[V_VpVzVVVVVVVVVVWW#W-W3WGWMWaWqW|WWWWWWWWWWWXXX,X6XGXQXbXlX}XXXXXXXXXXXXYY Y1Y:YKYOY`YjYpYYYYYYYYYYYYYYZZ!Z1Z5ZLZVZZZjZtZ~ZZZZZZZZZZZZ[[[ [*[.[;[E[R[V[g[q[[[[[[[[[[[ \\$\*\B\a\{\\\\\\\\]"]3]=]A]R]]]a]n]x]~]]]]]]]]]]]]^#^-^B^M^^^h^n^^^^^^^^__$_:_I_f_j____________``` `$`1`;`A`Y`x````````a aa+a;aKa[aeayaapaaaaapaaaaa bbb'b1b;bPbVbablb|bbbbbbbbbbbbb cc'c+c7cAcGcXc\cmcycccccccccccccd d!d'd2d=dMdSdcdgdxdddddddddddddeee)e-e>eJe[e_ekeue{eeeeeeeeeeeeff!f%f1f;fAfRfVfgfsfffffffffffffggg0g:g>gOgZg^gkgug{ggggggggggg h h*h:hDhUh_hlhhhhhhhhhhii#i4i>iDi\iqi{iiiiiiiiiiijj!j5jJjTjZjnjjjjjjjjjjjjjjk k"k&k7kAkVkakekrk|kkkkkkkkkkkkkl'l1lFlQlblllrlllllllllmm!m6mAmRm\mbmvm|mmmmmmmmmmm nnn"n3n=nRn]nannnxn~nnnnnnnnnn oo o*o.o?oJo[oeokoooooooooopp/p:pKpUp[popupppppppqqq%q/q5q@qDqUq_qequqyqqqqqqqqqrr"r&r7rArGrWr[rlrvr|rrrrrrrrrrrrrs ss!s's?sCsTs^sbsss~sssssssssssssttt/t3tDtNtRtctntrtttttttttttttuuu#u4u>uBuSu^ubuouyuuuuuuuuuuv$v.vCvNv_vivovvvvvvvvvvww3w>wOwYw_wwwwwwwwwwwxx#x.x?xIxOxcxmxwxxxxxxxxxyyy%y/y5y@yDyUy_yeyuyyyyyyyyyyyzz"z&z7zAzGzWz[zlzvz|zzzzzzzzzzzzz{ {{!{'{?{C{T{^{b{s{~{{{{{{{{{{{{{|||/|3|D|N|R|c|n|r|||||||||||||}}}#}4}>}B}S}^}b}o}y}}}}}}}}}}~$~.~C~N~_~i~o~~~~~~~~~~3>OY_w#.?IOcmwӀ$.2?IMZ`r|ρՁ*4:EWav‚Ƃׂ '37HRXgk|ǃ߃"/9?W[lvzτӄ)/GK\fj{Åԅޅ7LVkvĆΆ '<F[fwӇއ,6KVgqwÈΈ߈ !59cgxщ׉#->HYbquʊЊ"3=C^bs}ƋЋ +1<KO`jnÌ،.NioˍՍ,6GQZdsĎΎԎ(=CN\fptƏ׏ۏ*?IZfj{ĐȐِ$<Q[r|Ǒؑ*4DN_ivВڒ 1;ARVblvzʓۓߓ.CM^jnȔ̔ݔ "(@U_v˕ܕ .8HRcmzԖޖ)->HN_s~ȗ֗#-4@QUfpzØԘ $/>BS]ar}˙ՙ!6AR\bvȚٚ)JThÛɛ֛$*9NXiuyĜӜל#-3K`j˝֝ $9CS]nxߞ7;eizʟԟޟ&*7AK_ip|ˠѠ 1;EZ`kz~ʡԡڡ(2>S]r}ˢ,Keң -7`jnĤΤԤ'+7AK`j{ťϥե$48OUbrvæͦѦ'17HLXbhy}Ƨۧ(,=GKX^n¨ϨӨ)/GK\`mwȩΩݩ (2?CTXeoyʪΪߪ 15FPT`jn{˫ܫ'8>Ncm}Ĭά #)3=GQ[eoyɭԭ .2CMW[kuʮήڮ$9?Ncm~ȯίٯ '+8BH`u˰  *9NXhrӱ&JTkzƲֲ $.2?IO_tųֳ  $0:@QUfptѴ %):DNRcmsʵԵص +5EO`js}ƶʶ׶ *.;EK_pŷҷ(2<FPZdnxĸԸ;K[kv|˹ֹܹ '28LPakuѺۺ+5?PZgk|ƻʻֻ &04AKXmwμҼ -1=GM^bs}Խ޽ &59JTXeosȾӾ׾.?ISdn{ǿѿۿ !+5?ITm} ,<} $8<MWaey!+<FSWhr|%/3?IMZdq%/5FJV`fw{",5?NRisw &04AKXw  *.?I^imz&0AGS]gq{ )9Ix ,6AGRXhx%6@MQhrv -7APTeoy}*4AV`pz&06GK\fjv"9CGXbfr| $(9CGT^boy.8BS]j$/HXhx HRpt ,2=KU_cpz .8IUYjt~ +@Jakw#3=NXe@DU_ev&:DKWhl}  5;FUYjtx .8MXisy&@ak%/Xb &1;P[p]#/9?PTeos'<T^v(26BLP]gt .4EIU_evz!+4>MQblvz '1>S]mw#-3DHYcgs} 0:DHYciz~ !+;EV`is#-1=GKXbo#-3DHT^duy *3=LPakuy",9NXhr(.?CT^bnx|+5?CZ`qu"<]gvz %/5IZoy 5BVZku{ (2<PZam~ ",6KQ\ko#/DNcn<Vw !2<I^oy $*;?PZ^jtx$.2?IMZdnr'26CMSk"3=C[pz)3=GQ[eoy,=GQbly}#48DNTeiz#-<@Q[eiz  -Lf3>BOY_s  AKbr +/CMerv!%1;?LVcx!'8<HRXim~$.=AR\`mw{!6@QWcmw!1AQu0<MW]w    - 7 A E V \ g k |              ( 2 < @ P V a q {                ) / 9 F J [ e k z ~               " & = C R i u y              & - 7 = H L ] g q u             '1>BS]gk| "/DN^hy#8CGT^dx!6AER\b{1AGSnx"&6@DU`dq{*;AMbl} !+@K\fl%5EUe.CGXblp $(5?E[_p{%):@KO`jtx  $4:EU_v *.?IO^bs} !'6MY]nx !,0AKUYeou "&7AKO`jp(2BL]gpz  ' + 8 B H \ m q            !!%!)!6!@!F!_!c!t!~!!!!!!!!!!!!!!"%"+"7"R"\"w"""""""""""""# ##$#(#9#D#H#U#_#e#~#########$$$%$1$F$P$a$g$w$$$$$$$$$$$%%$%/%@%J%P%e%o%y%%%%%%%%%%%%%% &&)&9&I&c&m&y&&&&&&&&&] ''-'9'D'N'X'b'l'w'''''''''(((2(>(M(b(n(y((((((((((())),)<)F)P)T)`)j)n)z))))))))))))**/*9*?*M*c*m*w*********+++-+=+O+_+i+y++++++++++,.,<,J,`,j,t,,,,,,,,,-"---7-;-L-V-]-k-v-|---------. ..#.3.H.T.c.x.......... //'/>>#>7>A>G>V>j>t>z>>>>>>>>>>? ??$?3?7?G?Q?U?f?q?u????????????@ @!@5@?@E@T@h@r@@@@@@@@@@ AA$A,A6AEAIAYAcAiAsA}AAAAAAAAAAAAB BB$B*B9B=BMB]BrB|BBBBBBBBBBBBCCC7CKCUCjCuCCCCCCCCCCDD,D5DZDdDnDxDD]DDDDD]DDDD]E EE.E8E>EMEQEcE]nEtEEEEEEEEEEE FFF(F,F=FHFYFcFiFFFFFFFFGG&G5GaGGGGGGGG HHH&H0H6HJHgHqHHHHHHHHHHHHHII(I,I9ICIII]ImIqIIIIIIIIIIIIIJ JJ%J5J9JJJTJiJtJxJJJJJJJJJJJJJK K%K)K:K@KOKSKdKjKyKKKKKKKKKKKLL%L0LALKLQLeLoLyLLLLLL MM1M;MLMRM\MmMqMMMMMMMMMMMMNN%N+N?NTN^NoNyNNNNNNNNNNNOO&O0O4OAOKOUOYOjOtOOOOOOOOOOOO PPP)P3P9PQPfPpPPPPPPPPPPP QQ#Q8QBQSQ]QsQ}QQQQQQQQQQQ RRR4R>RBRSR^RbRoRyRRRRRRRRR7SASPSTSuSSSSSSSSSSST*T4TQT[T_TlTvTTTTTTTTTTTTTUUUU)U-U>UHU\UbUqUuUUUUUUUUUUUVV"V3V=VCVXVhVlV}VVVVVVVVVVVW WW%W1WFWPWaWsWWWWWWWWWWWXX(X>XHXNXbXsX}XXXXXXXXXX YYY1YFYPYaYkYYYYYYYYYYYZZ"Z3Z=ZSZ]ZcZqZZZZZZZZZZ[[%[/[5[C[Y[c[m[[[[[[[[[[[[\\*\?\K\V\`\j\t\~\\\\\\\\\\\\\] ]]+]@]J]Z]d]y]]]]]]]]]]^^^,^B^L^V^l^v^|^^^^^^^^^^__(_>_H_N_b_w___________`` `4`I`O`^`s`~``````````````a a(a2aLaVaeaiaaaaaaaaaaabbb2b>bIbSb]bgbqb}bbbbbbbbbbcc$c(cmcqcccccccccccccdd*d6dAdKdUd_didyddddddddddee$e9eCeTe^ene{eeeeeeeeeeeef f"f,f2f@fVf`fjfffffffffffgg(g2gy ByUy_yiysy wyyyyyyy yyyyy yyyzz zz)z3z=z AzNzXzbzhzrz|z zzzzzzz z zzzz {  { {*{4{>{ B{O{Y{c{i{s{}{ {{{{{ {{{{{ {{{{|  ||#|-|3|=|G| K|X|b|l|r|||| | |||| | |||} }}&},} P}|}}}}}}}}}}~~%~/~?~I~S~[~j~~~~~~~~~~~~~8ERa  .8BL \fp|  ƀЀڀ ހ *4>DNT e o| ʁ  )= AXc gx  ȂԂ   )3=I Mdnx  ȃ҃܃ $ (4>HR Vcmw  Ąфۄ  /9CM Qdnx  Ņхۅ   !.8BL P]gqw Ɔ ߆    (2<F V`jp ҇܇*K_gmwĈ͈ވ"&7AKUYjt~ωى  5?T_pz̊׊ 'BMQblpËԋߋ-7LWhrxnjьٌ,6@DQ[ezčՍٍ %/5MQblŎڎ%=R\q|ŏϏُ(,9CMblv *4IS]gwΑܑ &0:>KU_t~̒>HZ^Ó͓ؓ'1FRavŔɔ/;J_kvŕϕӕ.COZdnx–̖ܖ/=R\mwėΗҗޗ %5BWar|ʘԘߘ )>HSWhrvǙ֙  *;LVgqĚΚޚ#)BWar|Ǜқ ",2@V`jÜԜޜ(2<R\bvƝН֝$.4DNXblvܞ  ,;P\gq{ßɟ؟ܟ !5;EPbr|֠AA &59JT^r|ѡס+5;Shn|բߢ*4DN_mqƣУԣ%):DHT^bs~ͤפۤ",2KO`jåǥإ -7=VZkuΦҦ&*;EIU_tΧا  #'8CGT^d}ͨרݨ &04EPakqǩѩ &,;PZkuêͪת &06JP_ct~ɫӫ٫!+@KO\flĬȬլ߬ ,6KVZgqwĭϭ *5FPVnǮخ 5@Q[ayǯү !+;EZevΰذ 2GQakűڱ%=R\lvв *6KUeoʳ߳#4>DYkuʴܴ 1;AVhrǵ͵ӵݵ'-7=DSgxƶ׶*>OZiyƷ۷ !2<BMWakzʸ׸(2CNXt~ùιع!6AR\b{˺պۺ (3DNTmǻͻ%6@F_t~ؼ (28Qfpƽнڽ+@JUYjt~ɾҾ 1;AYnxƿۿ-7AV`q{2<Q\mw}&6KUfp&0EPakq %)5?IM^ev  *5JTZi~&0:DNXblv+5;J_i~#<Q[p{.CMbm~ 5?T_pz"(2<FPZdoz#4>D]r| &06Odn"(AV`u 3HRgr,6=Hbl{*4:Rgq $*BWav 2GQfq (.8BLV`l{*4:Rgq $*BWav 2GQfq (.8BLV`l{ )4EOUm$5?E]r| %/5Mbl%9CIS]gq{0:OZku{  *?J[ek/:KU[s *;EK_ioy&7Fe4:JZjz(2?OZdh|pp04@JPaeu -1AKQbfr|0:JTeox%/3DOS`jp (28Pap+5@Q`du!:OYny ,AK`k|3=R]nx~%/DO`jp 3=H]gr *;EKdy-7=Vku)/H]g|!5?ISYcms}.;K[k{ '+<FJWcgx +/@J_jn{0:OZ^ku{  *?J[eq ",6@DQ[eos/:>KU[s (26CMWaer|*4ITeou$9DU_e} )4EOUm$5?EYcmw +1;FPeo#)BWav 4IShs &;EZev(28BLV`jt *5FPVn%6@F^s} &06Ncm &>S]r}.CMbm~   3 = R ] n x ~                 * 5 O S y                 ) 3 = M W a i w        ]     - 9 = N Y ] n x |               ! + 1 I ^ h r           0:OZku{-Kq(2<HLYcmw{  1;HSYdju  $/3DPZjz 0:DNReoy "/9CMQ^hrx0:DNR_isy)3=CMW[hr|",6<` #-7?N_{'=GR\q{ !.8BHR\`mw #-7Yl )>HR\lv %/9=IS]gkw(.8>W[r|(26BLV`dq{  " 3 = G M [ k u            !!!"!2!"K"i""""""""#?#R# f#s#~##### #### #$ $$ $'$1$;$E$ I$V$`$j$t$ x$$$$$$$ $$$$$$$ $  %%!%'%2%8%C%M% Q%d%z%%% % %% %%% &&&(& 8&H& X&b&n& & &&&& &&&& &&'''  '3'='G'Q' U'b'l'v'|''' ''''' ''''' ''((( (,(6(@(F(P(Z( ^(k(u((((( ( ((((( (()))  )-)7)A)G)Q)[) _)k)u))) ))))) ))))) ))* ***%* )*6*@*J*P*Z*`* y* **** * **** **+ + #+"7+D+N+c+s+}+"++"++"+++"+,,,"(,2,<,D,"Y,$m,,,,$,,,,$,,,$ ---$5-?-E-$V-$m-w-$--$---$---$-$- ..%.2.W.&k....&...&...../&//%///&@/J/T/&e/o/u/&////&///&//&//&00$0*0&90&=0R0i0&~0000&000&000&00 11&1)131&D1N1&_1l1&p1111&1&111&11&2 2)2\2222(233*343(83I3S3Y3c3m3w333(333(33333(3334(444$4.484H4R4(g4q4(u444(444(4444(4(445((525<5F5(W5a5k5(|555(5555(5555(5(56'6(86>6(O6(p6{6(66666666(6667(77&7(77A7G7(U7_7o7y7(}777(777(777(777(8 8(8)8(-8D8N8T8(c8(g8|88(8888(88(888(999%9(/9(@9(D9\9(`9w999(9(9(9(9(:( :(:(#:(3:(7:P:X:(l:*{::::*:::*::*:*;* ;*;* ;**;*9;,P;`;~;,;;;,;;;,;,;;;;,;<<,#<,'<><D<,S<,j<v<,z<<<<,<<<,<,<<,<< =,!='=,.=,8=,>=,I=,M=^=h=r=,v=====,====,====,==>>>, >3>9>J>,N>Z>d>j>,>,>>>,>,>>>,>>>,>>?, ??'?,+?8?B?H?,a?,q?w?,?,???,???,???,?@@,@,@,!@,5@E@U@e@u@@@@@@@@@@@@@AAAA)A-A>AHALA]AhAlAyAAAAAAAAAAAABB.B?BIBSBdBnB{BBBBBBBBBC2CCCMCSCgCqCCCCCCCCCDDD)D6D:DKDUD_DcDpDvDDDDDDDDDDDEE"E,E9E=ENEXEbEfEwEEEEEEEEEEEEEEFFFF*F?FIFYFcFtF~FFFFFFFFFFFFFGGGG0G4GEGOGSG_GiGmGzGGGGGGGGGGGH HH&H*H7HAHEHRH\HfHjH{HHHHHHHHHHHI II*I.I;IEIKIcIxIIIIIIIIII JJ!J6J@JDJUJ`JdJqJ{JJJJJJJJJJ KK!K+K5K?KIKSKbKrKKKKKKKKKKKKL LL%L/L3L@LFLVLkL|LLLLLLLLLLLLMMMM'M1M7MHMLM]MgMkMwMMMMMMMMMMMMNNN#N4N>NHNLN]NgNmN~NNNNNNNNNNNNNNOO/OIOjOtOOOOOOOOOOOOOOPP!P%P2PRBRORYR_RwRRRRRRRRRRR SSS'S1S@SPS`SpSSSSSSSSSSSSST TTT$T4TITZTdTnTTTTTTTTTTTTTTUUU&U*U;UEUIUUU_UcUpUzUUUUUUUUUUUVVV&V*V;VEVKV\V`VlVvV|VVVVVVVVVVVV W'WHWRWaWeWvWWWWWWWWWWWWWWXXX X4XEXIXZXdXyXXXXXXXXXXX YYY5YJY[YeYoYYYYYYYYYYYZZZ Z-Z7Z=ZUZjZtZZZZZZZZZZZZ[[[.[>[N[^[r[v[[[[[[[[[[[[[[\\'\8\B\L\]\g\t\x\\\\\\\\\\\\\]]]#]']3]=]A]N]X]e]z]]]]]]]]]]]]^^^#^)^:^>^J^T^Z^k^o^^^^^^^^^^^_&_0_?_C_T_^_b_o_y_}_____________`#`'`8`B`W`b`f`s`}``````````a(a9aCaMa^ahauaaaaaaaaaaaa bbb3bHbRbgbrbbbbbbbbbbbbb cc,cn.On.cnnn.nnn.nnn.nnn.n.o o.o%o/o.?oIoSo.donoto.oooo0ooooppp(p2p06pHpUpap0epuppp0pppp0pp0pp0pq0q q*q0q0Aq0EqUq_qiq0mqyqqq0qq0qq0qq0qr rr0!r0%r5r?rIr0MrYrcrmr0rr0rr0rr0rrrr0s0ss)s09sCsMs0bsls0}ss0ss0ssss0s0st0tt03t>t0BtRt\tft0jtvttt0tt0tt0tt0ttu u0u02u=u0Qu[ueu0uuuu0uu0uu0uu0uuv v0v0!v1v;vEv0IvUv_viv0mv~vv0vvv0vvv0vvv0vv0 ww0*w4w>wDw0Uw0ew|wwww2wwwwwwx xx2x*x7xCx2]xgx2wxxx2x2xx2xxx2x2yy2y)y/y2?y2Yycy2sy}yy2y2yy2yyy2y2yz2 z*z2:zDzJz2Zz2nzyz2zz2zzz2z2zzz2{ {2{.{7{A{N{[{s{}{{{{{{{{!|B|V|c|s||||||||||||}}}!}%}2}D}Y}c}t}}}}}}}}}}}}}}~ ~~&~,~7~;~K~U~_~c~o~y~~~~~~~~~~~~~~~8Ss!-1AKO[eiv׀ #0:OZ^ku{ŁρӁ )>HYcx΂؂ "->HNim~Ãǃԃރ 1<@MW]uyńτՄ(2<BLVjt~ąȅم  0:DL[pzÆ͆׆ 1;LVkvŇχ $*4>DNYc}Èӈ#3CMXbfw‰ډމ*4:RcrvĊΊފ %:EV`q~Nj׋ۋ%04AKQj֌+5;PZdnxčٍ2<Q\mw}ƎՎَ5 #5.>HRXblv5z5ď5ȏ؏5%5:DNT5c5z55Đʐ555'5;K[kuƑʑݑ]] &1=R\my}Ò͒ג$DU_eyēȓՓߓ-9=NX^mΔؔ $.8BFV`jpz~ٕ .8<MX\isyŖɖږ%=R\mwƗЗ !,0=GMeizŘݘ -7=Ujt~ęΙؙܙ#37HR\`mw}̚ݚ'2CMSkś˛"3=C[pzϜ՜ߜ)9CNT_epvÝʝН۝-3>DT_epvŞОԞ.9=JTZrŸ̟ҟ%/:>OYny}ǠѠ &.8CYixqȡܡ",2<@MWagmӢ%2APZ`iuƣ֣ܣ $5?CPZdnt~ˤ%/9MWaguҥܥ#'7AGX\hrx¦Φئ-6GK[ek|˧ϧ&06GKWagtĨШԨ )-=GMYiȩҩة .8>OS_isǪت#-3L\bpz~ūӫ#/3CIX\lv|ɬͬڬ &;?KU[lpĭȭح"-AGVjt~îͮ&:DTZj~ʯޯ",<FWanǰͰ $4>BS^oyұ %/9CNg{˲Ѳ )3=CMQ^hrx~ȳ̳ٳ8ISYt~:̴ܴ.8:MW:hp:::Ƶ:۵:::.:CMS:b:fw::¶:ڶ:::*4::N:r:|:::::::·:̷:ַ::::::::0:::IMoMʸݸ&M*;EMIV^MuMMMɹӹٹMM MM1;AMPMTeoMsMMȺMMM"(M<MFMPMZMdMnMxMMMMMMMMȻMһMܻMMMMM"DfOu~OƼOۼOOOOOO$O>JWdsQʽԽQQ (2QIpVQeQzQQQQQQȾQݾQQQQ7;LVZgquſпԿ%p2AVbmw#6AKO\fjw}p'6KWblv /?NRblvz -7>LVmpz+:>[e %/3@JTXeos !-<Q]hr|(2<@MSak %)6<FPeq (2L[_ (2GRVgqx*9=MWaer|&4:DNXblv.=AR\`mw{%+5?IS]gv "&39CMWav",6IM^dtx(2<FP[ko|-9H]it~ &*PjtSSS*4SITSXeouS -6@LXf,9L`mz  &17DUfw%0EO`j{ %/5JXbw (6@U`dq{3>BOY_u -7=Sak 1?I^imz'<GKXbh~%)6@F\jt$:HRgrv '+<FJ[ekz~'-?CP`dqu -7;MW]gz *.:JPZdx%/5CYcm%6KRbfw(2GRcms !+1EZdn  1>MQblp}(7HW[lv| &,EZdy7LVkv )>H]hy0:OZku}  *;Yi~"3=C]r| '17Qfp %+EZdy %:DYdu.8MXisy ",AL]gs !,=GMg| 1;A[pz %/5Odn#+5?IS]cmw #-7ALZdy.8>Xmw",2Lak &@U_t &0:@JT^hr|$9DU_e-8ISYs !,=GMg| )3=IS^h}!2<B\q{ &06Peo $*DYcx4>HRXblv&;EV`l  % / 5 C Y c m              " , 2 L P a k               - 7 C G X _ n             5 J T i t            # 5 ? T _ p z           %:EV`f|  +<FLbt~",2HZdy.@J_j{&0EPakq +6GQWl~+5;Pbl4FPep #8BWbs}*4ITeou&;FWag-8ISYoy%/9CMSYcis} ,Xakw]$3HRXgk|#-=JN_im $1;EKU_ct~#'4>HNXbfr|   7 ; L V Z m w                 ! !!(!.!8!/B/S/]/a/r/}/////////////000.0C0M0b0m0~000000000000111"131=1R1]1a1n1x1~11111111222#2-212B2M2Q2^2h2n222222222222333!323=3A3N3X3^3v3z3333333333334 44"4-414>4H4N4f4j4{4444444444444555!5.585>5V5Z5k5u5y555555555555 66'616B6K6Z6^6o6y6}666666666667 777%7-737@7J7Z7j7~7777777777 88"8,808<8F8J8W8d8h8y88888888888889 99%9+9:9>9O9_9t9~999999999999 :::*:5:9:F:P:V:n:r:::::::::::;;;0;=;A;R;\;`;q;|;;;;;;;;;;;;;<<<-<1<B<L<R<a<e<v<<<<<<<<<<<<< ===)=3=9=Q=U=f=p===========>>#>)>A>V>`>u>>>>>>>>>> ???1?F?P?e?p???????????@@/@9@N@Y@j@t@z@@@@@@@@@AA%A0AAAKAQAeAoAyAAAAAAAAAAAAAB BBB&B,BDBYBcBxBBBBBBBBBB CC"C7CACVCaCrC|CCCCCCCCCCD(D2DGDRDcDmDyD}DDDDDDDDDDEE%E0EAEKEQEiE~EEEEEEEEEFFF)F/FGF\FfF{FFFFFFFFFFG G%G:GDGYGdGuGGGGGGGGGGHH%H0HAHKHQHeHkHuH{HHHHHHHHHHHHHHHHHHIII:IJIZIjItIIII]IIIIIIIJJJ0J9JHJLJ]JgJkJ|JJJJJJJJJJJJJKKK K8K\B\O\Y\_\w\\\\\\\\\\\] ]]#])]A]E]V]`]d]u]]]]]]]]]]]]^^^"^3^>^B^O^Y^_^y^}^^^^^^^^^^^___'_2_6_C_M_S_k_o_____________````#`4`>`B`S`^`b`o`y````````````aa$a.a2a?aKaOa`ajanaaaaaaaaaaaabbbb#b;b?bPbZb^bobzb~bbbbbbbbbbbccc/c3cDcNcRc_ckcocccccccccccc ddd+d6d:dGdQdWdodsddddddddddddde ee&e*e7eAeGe]ete~eeeeeeeeeeeee ff$f*f8fBfFfSf]fgfqfufffffffffffgg g1g;gLgUgdghgygggggggggggghh,h6hnHn]nhnynnnnnnnnnnoo.o8oMoXoiosooooooooooop ppp'p-p7pApGpQpWp]pgpqpwpppppppppppppppqq8qBqMqSqdquqqqqqqqqqqr rr'r-rtBtSt]tatrt}ttttttttttttt uuu(u3u7uDuNuTulu|uuuuuuuuuuuv vvv#v4v>vBvNvXv\vmvxv|vvvvvvvvvvvw www'w-wGw\wfwvwwwwwwwwww xx)x4xExOxUxoxxxxxxxxxxxy yy y*y4y>yEy_yhyryyyyyyyyzz!z3z[GzTz_zuzzz[zzzzz[zzzzz[z[{{{+{[/{<{F{V{[Z{g{q{}{{{[{{{{{{[{{{{[|[||#|[2|[6|G|Q|[U|f|q|[u||||[|[||[||[|} }[}[%}/}<}G}M}X}^}i}s}[w}}}}}}}[}[}}[~~"~[&~7~C~M~[]~m~[}~~~~[~[~~~~~[~~~[[-=G[K^nx[|[[ [[28[B[N[X[b[v[z[€̀܀[ ['1;AKU[isy[[[[[ȁ[ҁ[[ [%/5[C[S]g[w[[[̂ւ܂[[ [.[JT[pv[[[ǃу׃[[[['[CM[io[[[Ƅ[ք[[![7[A[K[U[`[˅܅]%,;PZkuԆކ(1?IM^hr|ćˇև )3=MWago~Έ؈ވ )->HR\qx̉։+/@J_jn{Š׊0:OZku{Njˋ؋ &*:DJT`dpzҌ܌ *48DNR^h}ƍ׍+5?U_euĎюێ#8BMblwʏԏޏ)3=AMW]gkwԐߐ.8NX^lБ *0H]gk|’̒֒6@DU_ct~Гԓ)/G_}͔"/3DJ]gq^ɕԕڕ^^#^'8B^FWb^fs}^^^іۖ^^ &^4^DNX^\hr^v^^Ǘ͗^^ $.^CMWa^q{^^^^֘^^^9^Y^jtz^^^™^љ^^^ ^^0:^OZ^ku{^^^^šҚ`-A`EVb i`x`|``țқ؛```&0`4GQ[`_ku{``Ü`ǜӜݜ```9LV`Zku``̝֝ܝ````'2`6CMS`k```Ş˞`ߞ``$*`9`J`Y`nt```Οޟb+b/;EbIU_bcpzbbb .7AMYgydơѡۡdߡd$d(5?IdM^h{ddȢd̢ޢddd+d;PdTrdvdƣУڣdޣ d.8dNTd`dt~ddddddҤܤddd&0:dPZ`dq{ddddddȥdӥdݥddddd%/;GSdxŦզ8MQfptҧ %)6<LPakvѨۨ#0<OY]nx|ũ˩ܩ "&DHYciz~ʪЪ$5?PYjnѫի !+@J[evĬϬ'<GXbh|ȭ̭ݭ%/9MWlwĮή #)3>S]nz~ʯԯگ",0=CTXio~ȰҰ߰!%6@FW[gq{Ʊϱ )9CT^gyIJز 8LYmqdzͳ$(5?E]r|մ%/5IS]gq{˵ϵ"&3=R]nxƶж (26CMW[lv˷ܷ &0=R\msĸո߸ 8MWlw¹ѹ+/@JT^b}ɺӺ׺,6<MQ]gm~Żֻڻ(>OSdnt˼ռۼ !2<BW[gqwȽҽֽ)3CM^hqþǾ޾ 04GK]nrſϿտ ):DU^os%5JTdn#-BM^hn 1AQeiz!+/;EKUYeoy} &<FLZpz2PV`f.=AR\`mw{ (3=AR\`mw{!26BLRcgx #'8DUYeou"(3BFWctx '-AGRaev'+<HY]isy $5?HR\fp .8>K[_pz 04EOUioz $5AN^bs-9FVku (2<HYmz "2<FJWamq 4:EUYiu.BL\fw  +/<FL`q*4ITeou(<@Q[_p{(.8BVfmsfffff.8f<MXfisyfffffff-f7fAfPfTeofsffffff f+6fGQWfkftf~fffffff(3BLVgr|hh%h4h8IS]dwhhhhhh-8hISYhmhwhhhhhhhh,<hFhPh_ht~hhhhhhhhh(h2h<hUms} ,7H[k%4kKQalrkkkkk k+6kGQWkokkkkkk kkk.k2CMkQbmk~kkkkkk k%/5kIkRk\kfkkkkkk )>HSWhsw?JYj} -CQ]v6AOU_is}-3CGXbfsy%/@FX\ix %)6@LPakq{*4EO`s+/<HYl| &-7AQUflvn '-AnRnanevnnnn&n;EnZenvnnnnnnnn$n5?EnYinsn}nnnnnn nnnAnKnUn_nin /FRgq| ",2=GWnu +5JVez /9=JT^bnx)37DJT^s  *GQei%>GQ]iwppp,6@JpZdjpwp{pppp$.8p<IS_ispppppp!p%6@pDQ[p_p{ppppp  p & , pB L Y d j u {   p       p p  p 4 ? pC T ` j pz  p    p p     p     ' p+ 7 A G pT pX o   p    p      p    % / pC S pc o p{ p  p p p p p p    p % / ? pC P Z f p z p~      p  p  p p  $ p. p: pD pN pb p}   p   p p   p  p   p( 2 pG R pc m s p p  p p  p  p  p; E O p_ i o py p p  p p  p  p p4 > pT ^ pn x p  p  p   p p p p p p3 T h u                / D P [ e o y               " , 6 @ P Z d n ~                5 A L V ` j t            ) - e |             # - 3 B F W a e v                  % / 5 N c m ~         ! 2 < B V ` k   r          r " , 6 r: F P Z rn x r  r   r r  r  r  * 0 rD rJ rP r\ rp z  r r   r  r r r r r   & 3 R v   t     t # - 7 A tE Q [ e o ts    t  t  t   t  t ( t= H tY c i t} t t t t    t  t  t   t6 tJ T ti t t   t t t t t    t   " t3 = G M t[ e tv    t  t   t    t t  $ t3 tC M S ti tm ~   t    t t    t t    t( t, = G tK [ e ti z  t    t t   t  t     t5 t9 E O td o ts    t t         t   # ) 3 = t_ tp  t   t    t  t    t0 t4 E O Y c tg s }   t    t  t  t   t, t@ J t_ j t{   t t t t t    t    t" / 9 E O U tg tk    t    t      t t 1 ; E tI ] g tk }  t   t   t   t  t    t2 t6 F P te p tt    t t  t  t  ! t"! tC! I! tW! ts! }! t! ! t! t! ! ! ! t! " t$" *" t<" tc" t{" t" t" " t" " " t" t" " t # # t# t!# t+# t5# t?# tI# tT# t^# t}# # # # # # # # $ $ $  $ -$ 7$ A$ E$ V$ `$ j$ t$ x$ $ $ $ $ $ $ $ $ $ $ $ % % % %% =% [% {% % % % % % % % % % % &  & 3& 7& H& R& \& `& q& {& & & & & & & & & & & & & & ' ' 0' :' @' X' v' ' ' ' ' ' ' ' ' ' ' ' (( ,( <( F( P( T( e( o( y( ( ( ( ( ( ( ( ( ( ( ( ( ) ) $) .) 4) L) j) ) ) ) ) ) ) ) ) ) ) * * #* '* 8* B* L* P* \* f* p* t* * * * * * * * * * * * * *  + + (+ 3+ D+ N+ T+ l+ + + + + + + + + + , , #, -, 9, E, W, c, l, , , , v, , , , v, , - - v- "- ,- 6- vK- U- vj- u- v- - - v- v- v- v- - - v- v- . . v". (. v2. v<. vF. vQ. vf. o. y. . . . . . x / / :/ D/ X/ x\/ m/ w/ / / x/ / / / / x/ / / / x/ / x0 0 x-0 70 =0 xQ0 xW0 xd0 xh0 y0 0 0 x0 0 x0 0 x0 0 0 x1 x1 x1 x'1 11 ;1 E1 xV1 `1 j1 t1 x1 1 1 1 x1 1 x1 1 1 1 x1 1 x 2 2 2 x42 >2 D2 xS2 xd2 n2 t2 x2 x2 2 2 2 x2 2 2 2 x2 x2 2 3 3 x3 x3 -3 73 x;3 L3 V3 xZ3 k3 v3 xz3 3 3 3 x3 x3 3 3 x3 3 x3 3 4  4 x 4 x'4 14 >4 I4 O4 Z4 `4 k4 u4 xy4 4 4 4 4 4 4 x4 x4 4 x5 5 $5 x(5 95 E5 O5 x_5 o5 x5 5 5 5 x5 x5 5 5 5 5 x5 5 5 6  6 x6 6 &6 06 xE6 O6 xd6 o6 x6 6 6 x6 x6 x6 x6 6 6 6 6 x6 7 7 7 %7 x)7 67 @7 J7 P7 Z7 d7 xh7 t7 ~7 7 7 7 7 x7 7 7 7 x7 7 7 7 x8  8 x"8 -8 x>8 H8 N8 xb8 xh8 xt8 x8 x8 x8 8 x8 8 8 x8 x8 x8 x 9 x9 (9 89 B9 xF9 Y9 i9 s9 xw9 9 9 9 9 9 x9 x9 9 9 9 x9 :  : x: #: -: x1: =: G: xK: W: a: xe: v: : x: : : : x: x: : x: : : x ; ; x; %; /; 5; xS; xt; z; x; x; ; x; ; x; x < x!< x/< xE< O< xS< _< e< xt< xx< < < < x< < x< < x< x= $= x:= @= xH= xR= x\= xf= xp= xz= x= x= x= = = = = = = > > "> .> :> V> z> > > > > > > > > > > ?  ? ? ? (? .? N DN TN iN sN yN N N N N N N N O &O 0O =O YO mO O O O O O O O O O P P !P +P 1P EP KP VP ZP kP uP yP P P P P P P P P P P P P Q  Q Q (Q ,Q 9Q CQ IQ ^Q hQ rQ xQ Q Q Q Q Q Q R  R R "R 5R @R FR SR cR gR xR ~R R R R R R R R R R R R R  S S S %S +S CS GS XS bS fS wS S S S S S S S S S S T T T 1T ;T KT UT fT pT }T T T T T T T T T  U U )U 4U EU OU UU iU sU zU U U yU yU yU  U yU V V y'V 2V yIV UV bV yfV yV -V yV V -V yV V -V yV yV yV yV yV yV yV yW yW yW y W y*W y0W y:W yDW yNW yXW ybW ylW yvW y|W yW yW yW yW yW yW yW yW yW yW yW W W X X $X 0X BJN]ajnw{ *.6:IMVZcgrv/3<@IMX\eiz~aaa#a37?CJNW[jn  $,07;DHW[os{ ,08<KOX\cg".2CGOSbfnr   )-48TXdhy} $+/8<KO`dsw   ! + / C G P T _ c t x                        / 3 ; ? F J S W ^ b r v }                          ' + 4 8 ? C L P W [ j n u y                 % ) 8 g< gE gI g] ga gj gn gu gy g g g i i i i i i i i i i i i i i i i i i" i& i- i1 iB iF iM iQ i` kd km kq k k k k k k k k k k k k k k k k k k kkkkk(k,k5k9kJkNkWk[kdkhkokskkkkkkkkkkkkkkkkk%m)m0m4mDmHmQmUmimmm|mmmmmmmmmmmmmmmmmmmm mmmm.m2m;m?mHmLmSmWmhmlmsmwmmmmmmmmmmmmm o oo o/o3o:o>oGoKoZo^oeoiorovo}oooooooooooooooooo o o%o)o8o<oToXogkrv} "&-18<CGNRaelpw{]]  $48?COS_cjnz~] ]]'+26?CTX`dtx #'6:A]FJQ]^bimvz $(15<@IM^bkox| *.=AJNUYjn}  $+/AELPW[mqx|'+;?NRZ^fjz~ +/CuGuPuTu]uaujunuuuuuuuuuuuuuuuuuuuuuu uuu&3u7u>uBuQuUueuiuuuuuuuuuuuuuuuuu,08<DHX\dhpt '+;?HLUYmqz~!(,;?GKRVeiz~   # , 0 < @ L P d h o s {                !!!! !$!4!8!@!D!T!X!_!c!k!o!v!z!!!!!!!!!!!!!!!!!""""" "1"5"D"H"O"S"Z"^"f"j"r"v"~""""""""""""""""""####'#+#2#6#E#I#P#]]#a#h#l#s#w###############$$$'$+$@$D$M$Q$Z$^$g$k$|$$$$$$$$$$$$$$$$$$%%%%#%'%6%:%C%G%N%R%c%g%v%wz%w%w%w%w%w%w%w%w%w%w%w%w%w%w%w%w%w%w%w&w &w&w&w(&w,&w5&w9&wB&wF&wW&w[&wd&wh&wq&wu&w~&w&w&w&w&w&w&w&w&w&w&w&w&w&w&w&w'w'w'w'w!'w%'w4'w8'w?'wC'wS'wW'w_'wc'wl'wp'w'w'w'w'w'w'w'w'w'''''''''''(( (((((,(5(9(M(Q(X(\(c(g(w({((((((((((((((()) ))))%)))1)5)=)A)I)M)U)Y)i)m)v)z)))))))))))))))))* ***0*4*C*G*P*T*h*l*s*w******************* ++++%+)+0+4+E+I+R+V+g+k+t+x+++++++++++++++++++, ,,,,",3,7,>,B,Q,U,^,b,k,o,x,|,,,,,,,,,,,,,,,,,,,----%-)-2-6-J-N-U-Y-i-m-|-------------------- . ...+./.8.<.E.I.P.T.].a.h.l.}..................////"/&///3/2B2R2V2_2c2w2{222222222222222223333$3(30343E3I3R3V3e3i3p3}333333333333333334 444#4*4.464:4K4O4V4c4g4s4w44444444444444455 555(5,565:5N5R5Z5^5m5q5z5~5555555555555556666!6(6,6<6@6I6M6V6Z6e6i6r6v666666666666666667777 7$7-717C7G7N7R7Y7]7e7i7t7x7777777777777777778888#8+8/8?8C8L8P8Y8]8f8j8s8w88888888888888888899 999%9)989<9K9O9`9d9m9q9z9~99999999999999999:::::#:2:6:E:I:Z:^:f:j:r:v:::::::::::::::::::; ;;!;*;.;7;;;B;F;O;S;_;c;r;v;;;;;;;;;;;;;;;;;;;< <<<(<,<;<?<P<T<]<a<j<n<u<y<<<<<<<<<<<<<<<<<= ===="=.=2=A=E=T=X=i=m=t=================>> >>>$>(>7>;>R>V>]>j>n>u>y>>>>>>>>>>A>>>>>>>? ?? ?$?;???F?S?W?`?d?k?o?x?|???????????????@@@@#@'@6@:@C@G@N@R@c@g@v@z@@@@@@@@@@@@@@@@@AAAA#A'A6A:AAAEATAXAaAeAlApAyA}AAAAAAAAAAAAAAAAAAA BBBB#B'B0B4BEBIBPBUBYB`BmBqBxB|BBBBBBBBBBBBBBBBBBCCA CCCA$C(C1C5CR]KROR_RcRjRnRvRzRRRRRRRRRRRRRRRRRRS SSSS)S-S5S9S@SDSKSOS^SbSkSoS~SSSSSSSSSSSSSSST T T T$T+T/TBTFTMTQTdThToTsTTTTTTTTTTTTTTTTTUU UUUU2U6U=UAUKUOUdUhUoUsUUUUUUUUUU~U~U~U~U~U~V~ V~V~"V~+V~/V~6V~:V~CV~GV~NV~RV~[V~_V~fV~jV~{V~V~V~V~V~V~V~V~V~V~V~V~V~V~V~V~V~V~V~W~W~ W~W~!W~(W~,W~;W~?W~HW~LW~]W~aW~jW~nW~wW~{W~W~W~W~W~W~W~WWWWWWWWWWXXXXX X'X+XaEaIaXa\aeaiaravaaaaaaaaaaaaaaaaaaab bbb*b.b7b;bDbHbYb]bfbjbsbwbbbbbbbbbbbbbbbbbcccc*c.c7c;cBcFcWc[cjcncucycccccccccccccccc dddd&d*d2d6d?dCdUdYdjdndvdzddddddddddddddddee eee&e*e1e5eEeIePeTe]eaepete{eeeeeeeeeeeeeeeeeeeef fff#f'f7f;fCfGfVfZfafefufyffffffffffffffffffffgg gggg"g*g.g6g:gIgMgWg[gbgfgxg|ggggggggggggggggggh hh!h%h,h0hlBlIlMlVlZlclglnlrl{llllllllllllllllllllmmmmm!m(m,m5m9mJmNmUmYmbmfmomsmzm~mmmmmmmmmmmmmmmmmmmn nnn*n.n5n9nHnLnUnYnbnfnonsnnnnnnnnnnnnnnnnnnooo o$o+o/o@oDoSoWoholouoyooooooooooooooooooo p ppp p$p,p0p?pCpLpPpWp[pdphpqpup~ppppppppppppppppppppq qqq(q,q5q9q@qDqKqOq^qbqkqoqqqqqqqqqqqqqqqqqqq r rrrr#r*r.r5r9rHrLr[r_rhrlrsrwrrrrrrrrrrrrrrrrrrssss"s.s2s>sBsQsUs\sismsvszsssssssssssssssss ttt"t)t-t5t9t@tDtTtXt_tctstwtttttttttttttttttttuu uu u$u+u/u7u;uBuFuVuZuaueuuuyuuuuuuuuuuuuuuuuuv vv!v*v.v5v9vJvNv]vavhvlvtvxvvvvvvvvvvvvvvvvvvwww&w*w;w?wNwRwcwgwxw|wwwwwwwwwwwwwwwwwwwx xxx&x*x3x7x@xDxKxOxXx\xexixpxtx}xxxxxxxxxxxxxxxxxxxxxy y yyy!y%y-y1yAyEyLyPyYy]yfyjyqyuy~yyyyyyyyyyyyyyyyyy z zzz!z%z.z2z9z=zFzJzSzWz^zbzizmzvzzzzzzzzzzzzzzzzzzzzzz{{{{ {/{3{;{?{G{K{[{_{|{{{{{{{{{{{{{{{{{{|| ||||-|1|@|D|M|Q|b|f|o|s|||||||||||||||||}}}}+}/}@}D}U}Y}h}l}}}}}}}}}}}}}}}}}}~ ~~~-~1~8~<~K~O~_~c~j~n~}~~~~~~~~~~~~~~~~ "15=APTcgnry}   )->BKO`dko~€ƀπӀ '+48?CTX_crvЁԁ %)04CGOSZ^mq]Âӂׂނ]!%-18<LPY]imvzăȃуՃ !15<@HLSWgkrvńԄ؄]]'+;?F]KOV]cgnry}ȅ̅Ӆ]؅܅],07;JN]aquÆʆΆՆن(,8<PT[_fjy}ˇχއ  '+37GK[_fjz~ĈȈو݈!%,09=FJY]dhquljˉ҉։߉ !%-19=FJZ^fjz~NJˊԊ؊,0AELPY]nrz~ϋӋ"*.6:JNVZjnz~]ČȌό]܌ .29>BINRY^binry~čՍٍ -18]=AH]UYbfuy͎юڎގ#,0?CTX_]lpɏ͏ޏ]!]&*1]>BKOX\mq}ŐɐҐ֐ߐ $(7;LPY]nr{999999ȑ9̑9ӑ9ב999999999990949;pH9L9[9_9f]s9w999]99]99]9’9˒9ϒ9ؒ9ܒ99999]99'9+92]79;9B]O9S9b9f9o9s9|999999999ē9̓9Г99999   $+/6:OSZ^fjqu]]]”ƔϔӔܔ $,0@DMQZ^os{ĕȕϕӕڕޕ!%,0?CLPY]nry}ΖҖpp p&*37HLX\kov]{]]җ֗ߗ *.7;DHY]d]imt]y}]˜˘Ϙ$(/3BFW[koʙΙޙ]] ]#'04EIUYhltxÚǚϚӚۚߚ #'.2AELPW[jnuyț̛՛ٛ p#p04=ARVbfuy]]Ü̜Мߜ )-4]9=D]QU^bqu~ȝ̝۝ߝ -1AELPX\dhos{pžƞ͞pڞޞ"&59@EIP]ahluy̟Пܟ !%48@DTX_cjnuy]]ƠʠӠנ!&*1>BIMVZcgvzΡҡۡߡ(,37AELPbfos|΢Ң٢ޢ!*.7;LPaenr{ģȣѣգޣ ,08<KO`dosʤΤפۤ  $59AEUYbfos|ͥѥإܥ  $-18<MQ`duyʦΦզ٦ $(9=DHTXgk{]]]]çǧΧҧ٧ݧ$(15FJQU\`osƨʨѨըި  !%59BFW[dhy}é̩Щ-1@DUYim~êԪت#'.29=FJW[hlswūɫҫ֫ݫ !%-19=EIY]eiy}¬ˬϬܬ !(,59HLUYbfswĭͭѭڭޭ#'6:BFNRbfmq~ǮˮҮ֮!%15AENR[_ptȯ̯ԯد )-:>EIRVcgtxİȰа԰ܰ (,59BFOS\`im~ұֱ߱!%6:CGNRcgvz²ɲͲԲز߲ &*1p6:ApFJQpVZapnry}ųɳгճٳ #'.2AEL]QU\]ael]qu|]ʴδݴ %)04;?FJY]fjy}]]]]ŵ̵е׵۵ %)059@EIP]ahlsw~]Ŷ̶]Ѷնܶ]]-1:>MQX]ahmqx}Ʒʷٷݷ]]]  ]!%,07;BFUYbfuyȸ̸Ӹ׸޸]!%,]15<]AEL]Y]dhosz~ȹ͹ѹعݹ )-4]9=D]IMT]Y]d]qu|źɺкԺۺߺ'+26?CRV^bjnvzƻʻۻ߻ 04DHY]mq¼Ƽ׼ۼpp p&p37>BIMTXgkrw{ŽɽнԽ]]]]+/6:AELP_cjoszȾ̾۾߾]]] ]#'.29=DHW[bgkrw{Ŀӿ׿޿]]]]&*15<@OSZ^eipt!%.2CGPTeirv $(9=LPaeuypppp$(/48?DHO\`gkrv}]]]]  ',07<@GTX_cjnuy]]]]$(/48?DHOTX_lpw{]]]] ")-<@IM\`gkrv} !%.2;?PT]arv&*15FJY]nr 15=AQU_cjnx| (,37?CKOY]dhrv ,0AEOSZ^pt{ "+/@DUY`dnr| '+=AKOY]os}#'9=GK]ako  "&04>BQU]aqu .2:>NR\`gkuy !37RV]a| $(:>HLVZlpz~ &*<@GKZ^hl~ '+59CGY]gkrv(,6:AEOS]ako+/;?IMW[mq %)8<MQZ^osz~ $(/3<@QU^bsw37?CSWfj$(26HLVZdhz~(,6:AEOSeisw~ $48BFMQ[_im )-48@DLPZ^hl~ !%8<CGQU_cuy  $-1:>EIZ^gk| )-7;BFPT[_imw{&*48?CMQ[_qu *.>BKO`duy 15?CMQcgqu%);?IM_cmq%)8<CGOSZ^fjqu}"&-]:>OS_crv}]!%,]9=NR^bqu|]]!15FJRVfjy}]#'8<HL[_f]sw -1:>EIZ^mq,07;JNW[dhy}  ")].29]>BI]VZcgvz]]] -18]=AH]MQX]eirv#'04EIPT`dsw]]] ]'+48AEVZcgvz  $-1BFOSdhx| *.59HLSWgkrv  /3:?CJOSZ_cjosz &*9=DHW[b]os ] '],07]DHQU^bko$(7;GKTXgk|]])-6:IM^bnr{  $-1BFMQY]eirv   '+48AELP_cjnuy "&/3:>OSbfos|"&.2BFOS\`im~"&/3DHPTdhos %):>OScg{ $8<LPW[bfos!%.2CGPT]arv} (,<@PTeirv}$(7;CGOS[_os|"*.6:JNUY`dsw~ '+26?CJN]ajnw{"37@DMQZ^os| !15=AQU\`imvz*.?CRV_clp (,59BFW[dhqu&*15FJQUdhw{ $,08<CGW[cgos    % ) 9 = D H P T \ ` g k {                        ( , 3 7 C G W [ k o v         ]   ]   ]         ! ( ]- 1 8 ]E I Q U e i y }                     , 0 A E T X h l s                     , 0 @ D K X \ m q z ~               &*15EIQU\`imtx%);?IMW[bfx| &*<@JNX\nr| *.8<NR\`gkuy 04<@GKRV_crv /3CGW[bfz~ "&-18<CGOS[_fjz~ %)59HLUY`duy )-AENR[_hl}$(7;JNUYbfw{ !%,0:>EISW^blpw{  '+26=AHLSW^bimtx]"15<]IMTXgkr]]]  ]!%,0?CJ]W[bfuy]]]"&04;?HL^bim|#'6:AEMQaetx ")-7;BFPT[_qu|] ")-48AEW[bfmq   # ' / 3 ; ? N R Z ^ m q x ]     ]          !!!!!!%!-!1!8!4B4Q4U4_4c4u4y4444444444444444555!5%5/535E5I5S5W5a5e5w5{555555555555555556 66!6+6/6A6E6O6S6e6i6s6w66666666666666777%7)70747C7G7X7\7m7q777777777777777778888!8%8,80898=8D8H8O8S8b8f8v8z88888888888888888889 9999"9/939G9K9S9W9g9k9t9x999999999999999::::-:1:B:F:O:S:Z:^:o:s:::::::::::::::::;;;;,;0;9;=;D;H;Y;];l;p;x;|;;;;;;;;;;;;;;;;; <<<#<*<.<6<:<B<F<N<R<Z<^<n<r<y<}<<<<<<<<<<<<<<<<<<<=] ===]#='=.=2=;=?=H=L=S=W=`=d=m=q=x=|============= >>>>;>?>F>J>S>W>`>d>k>o>x>|>>>>>>>>>>>>>>???%?)?H?L?S?W?^?b?i?m?t?x???????????????????@@@@&@*@3@7@@@D@U@Y@`@d@p@t@@@@@@@@@@@@@@@@@A AAA%A)A8AFBFKFOF`FdFtFxFFFFFFFFFFFFFFFFFFFGGGG#G'G8GIEIIIPITI[I_IgIkIrIvI~IIIIIIIIIIIIIIIIIIIIIJ J JJJ J$J+J/J7J;JJJNJUJYJiJmJvJzJJJJJJJJJJJJJJJJJJK KKKK&K*K3K7KHKLKSKWKcKgKvKzKKKKKKKKKKKKKKKKKKK LL!L%L.L2LCLGLPLTLeLiLpLtLLLLLLLLLLLLLLLLLLLLM MMMM&M*M;M?MHMLMUMYMbMfMwM{MMMMMMMMMMMMMMMMMMMN NNN'N+N2N6NHNLNSNWN^NbNqNuN|NNNNNNNNNNNNNNNNO OOO#O'O8OTGTKTTTXTiTmTtTxTTTTTTTTTTTTTTTTTU UUU/U3UaHaLaSaWaiama|aaaaaaaaaaaaaaaabbbb*b.b?bCbMbQbXb\bnbrbbbbbbbbbbbbbbbbbbbbbbcccc#c3c7c>cBcJcNcVcZcccgcpctcccccccccccccccccccd ddd.d2dCdGdVdZdcdgdqdud~dddddddddddddddddddde ee!e*e.e7e;eDeHeQeUefejeseweeeeeeeeeeeeeeeeeee ffff$f(f1f5fFfJfQfUfafefrfvfffffffffffffffffffff gggg/g3g:g>gMgQgXg\gkgogxg|gggggggggggggggghhhh h/h3hoOoSodohowo{oo]ooo]ooo]ooo]oooooooooooo ppp]p!p(p]-p1p8p]EpIpQpUp]papqpup~pppppppppppppppppqqqq q1q5q>qBqSqWq^qbqqquq~qqqqqqqqqqqqqqqqrrrr"r&r5r9rJrNrWr[rbrfrwr{rrrrrrrrrrrrrrrss ss!s%s4s8sIsMsVsZsasesvszsssssssssssssssssss tt!t%t4t8tGtKtTtXtatetntrt{ttttttttttttttt]ttt]tu uuu!u(u,u;u?uFuJuYu]ulupuuuuuuuuuuuu]uuu]uuvvvv!v%v.v2v;v?vPvTv]vavjvnvwv{vvvvvvvvvvvvvvvv]vvw]www!w0w4wCwGwWw[wkwow~wwwwwpwwwwwwwwwwwwwx xxxx/x3xCxGxNxRxZx^xnxrx{xxxxxxxxxxxxxxxpxxypyyyp&y*y9y=yNyRyayeyvyzyyyypyyyyyyyyy]yyyyyy zzz]#z'z.z2z9z=zDzHzWz[zbz]ozszzzzzzpzzzpzzzpzzzzz]zz{ {{{.{2{9{p>{B{I{pV{Z{a{pn{r{y{p~{{{p{{{p{{{{{]{{{{{p| |||0|4|;|]H|L|[|_|f|]k|o|v|]|||p||||||||||||||||||}}}}"}&}-}]2}6}=}]B}F}M}]Z}^}h}l}v}z}}}}}}}}}}}}}}}}}~~~~)~-~:~>~G~K~Z~^~p~t~{~]~~~~~~~]~~~]~~~]~~~]~~p$(/p<@JN`dk]x|'+>BLPZ^pt{ŀɀЀԀ܀pp,0:>EISWimt]]ȁ́Ӂׁ]&*9=QUfj{˂ςւڂ]!].2CGX\c]ptɃ̓Ճكp"&-p:>HL^bi]nry]̄Єڄބ!%,]15<]IMW[mqz~]]ÅDžم݅ )-?CPT]apt}Æ҆ֆ'+<@QUdho]tx]]ȇ̇އ (,;?QUfjy}ppňɈЈ]݈ "/3<@OSdhy}ɉ͉߉  15DHRV`dnr|ŠƊ͊ъ (,37@DMQX\kox|ŋɋӋ׋%)37IMVZcgx|Č֌ڌ -1BFUYaeuyʍ΍׍ۍ'+7;OS\`qu|ώӎ܎-18<KOX\mqz~ʏΏ׏ۏ,09=DHY]lpy}̐Аܐ !(,;?HL]ajnÑ̑Б ,0?CLPW[lpÒǒےߒ"&/3DHQUfjquȓ̓ӓד&*37>BSWfjrv~ŔΔҔ۔ߔ %)04=AHL]arvʕΕՕٕ  ")-48?CKOW[jn}pǖp̖Жזp] /3DHOpTX_pdhop|pЗԗݗ *.?CLPW[lpØǘӘט&*15DHOS[_gktxƙʙٙݙ  #'.2;?FJ[_fjswĚȚКԚܚ  $-1BFOS\`im~Λқٛݛ !%.29=NRaenry}Ŝɜќ՜ %)=AHLSWfjqu}ҝ֝ݝ  $+/8<EIPT]ahl}ϞӞڞޞ!*.7;BFOSdhqu~Οҟ۟ߟ.2CGPT[_ptàǠϠӠ04CGNR[_hlsw~ǡˡԡء#'.2>BQU\`qu|ĢȢ٢ݢ &*15FJY]dhosɣͣݣ *.:>RV]]bfm]rv}]]]ŤͤѤڤޤ(,=AH]MQX]]ah]mqx]}]]ʥΥץۥ  !%.2;?PT]ahl}ĦͦѦڦަ (,48HLSW`dmqx|§Ƨاܧ &*15FJQUdhquƨʨӨר (,59JNW[lpw{Ωҩ٩ݩ04;?NR[_pt}ŪɪҪ֪ݪ '+26GKZ^os|īȫѫիܫ&*15FJY]nr{ìǬЬԬ۬߬%)04EIX\cgpt}­ƭέҭڭޭ "+/6:CGX\eirv®ƮͮѮ  $59BFMQbfuyį̯Яدܯ +/6]CGPT`dx|ͰѰݰ .29]FJQU\`pt{ñDZαұ]-1:>EIRV_ctxpòpвԲ۲]&*37>BIM\`gksw]Ƴʳѳ]޳] !.29=DHW[bfmqx|]]]˴ϴڴ޴  !%,0?CJNVZaemq]]]ŵ̵ѵյܵ"&-18<CGNRael]qu|]]ʶζ߶ $,07;CGW[b]gkr]]·Ϸӷڷ޷$(7;B]GKR]_cj]w{¸Ƹ͸Ѹظܸ -18]=AH]UY`]mqx}ιҹٹݹ ]!(]59@]MQX\eipt}ĺӺ׺޺]"&-]:>E]RV]bfmrv}»ɻͻԻػ]]]'+48IM\`osz~Ҽּݼ ,07;JNW[dhquĽ˽Ͻ۽߽,0?C[_nr{žξҾ&*;?HL]ahl{ÿʿοݿ&*37>BSW^bnr"&59@DKO^bi]vz &*6:FJVZfj~ !%,0?CJNVZbfos|]]]  $+/8<EIRV]ajnw{ )-6:KOVZaelpppp]&*15DHY]dpimtpp  +/6:IM^bkovz!%48IMVZaevz $(/3=ASW`dpt.2>BQU\]ael]y}(,=AHL[_kox| *.?CLPY]fj{".2>BQUfjsw~ #48?COSbfos$(/3DHW[cgos%)26GKRVeirv} #,09=FJ[_nr~]]] p&p+/6pCGPTcgnpsw~pp /3BFRV_crv]]]pp p$(7;BpGKRpW[bpos|ppppp p#,0?CJ]OSZ]_cj]w{'+48GKTXaevz!26FJ[_hlsw $])-4]9=D]QU\`hltx]]]] #*.=AJN_cjn}#'.2AEVZcgnr -1@DLPX\dhpt| #'37FJQ]VZa]nry}]] "&7;JN_clpw{ "&.2:>FJRVfjq]vz]]]  $-1BFM]RV]]bfm]rv}]] +/8<CGX\kov]{]]] &*1]6:A]FJQ]VZa]nry}  $-1:>MQX\dhpt| *.59EIX\cgx| %):>GK\`gkz~  $+/>BSW`dko *.=ARV_cjn  )-<@GKSW_ckow{ !%,]15<]AEL]QU\]imtx] ] '],07]<@G]TX_clpy}%)0]59@]EIP]UY`]mqx|]] ]](,37@DMQX\eirv "*.6:BFVZaenr{!26=ARV]apt}!%48AEVZcgx| %):>MQbfosz~ $(9=LPaenry} !%59@DLP`dkovz]]]] ]$(04<@IMVZcgpt}]]]]]]#,09=FJSW^bkox|]$(/]48?]DHO]TX_]lpw{]] ]]#*]7;BFOS\`gktx ")-6:CGNR[_pt} %)8<EIZ^gk|  "+/@DKO^bko*.7;BFW[jn)-6:AEVZim~%)15=AIM]ahlsw "&-18<KOX\eirv !%.2;?PT[_fjqu!%,07;JN^bkox| ,09=NRbfw{ &*15<@TXgk{ $+/6:IMVZcgpt -1:>GK\`gkz~04DHPTdhqu~ &*37@DMQbfos| $(9=DHW[bfnr !%,08<CGW[dhqu 48HL[_os| (,59BFW[bfmq     ' + ; ? O S d h q u |                    ) - 6 : C G P T e i p t {                        ' + : > N R [ _ h l }                     " + / 6 : K O ^ b k o                         / 3 : > E I ] a p t                  ")-48?CRV_clpy} !%6:CGPTeipt$(9=MQX\cgnry}] ]#'04EIPT]arv]] ]])-6:KOX\mqx]}]] !%.2AETXimuy %):>GKTXaevz)-9=LPX\lpy})-=AQUei}] (,3]@DKOX\kox| *.?CSWhluy&*37FJ[_f]sw  $-1BFOS\`im~$(7;BFNRbfvz %);?FJRV^bjnvz %)9=FJQU^bko]]] &]+/6];?F]SW^bkox| $(/3<@IMTXaevz]]]]  ]   ]& * 1 5 > B K O V Z i m v z                  !!!!$!(!9!=!F!J!S!W!h!l!t!x!!!!!!!!!!!!!!!!!" ""","0"9"="N"R"c"g"p"t"{""""""""""""""""""""####'#+#4#8#H#L#T#X#`#d#m#q#z#~###################$$$$"$&$6$:$B$F$N$R$Z$^$n$r$y$}$$$$$$$$$$$$$$$$$$$%%%%#%'%/%3%C%G%P%T%]%a%r%v%}%]%%%]%%%]%%%%%]%%%]%%%]%%&&&&&&(&,&;&?&H&L&[&_&f&j&s&w&&&&&&&&&&&&&&&&&&&&' '''#'4'8'H'L'S']X'\'c']p't'''']''']''''''''''''((((( ()(-(<(@(H(L(\(`(q(u((((((((((((((((())))!)%).)2)C)G)N)R)a)e)u)y))))))))))))))))) ****,*0*7*;*C*G*O*S*[*_*g*k*s*w*******************++++++.+2+:+>+N+R+[+_+f+j+s+w+++++++++++++++++,,,,,,-,1,9,=,M,Q,X,\,e,i,r,v,,,,,,,,,,,,,,,,,,,-- ----#-'-0-4-;-?-H-L-U-Y-`-d-m-q-z-~----------------..] ...].!.(.]-.1.8.]E.I.P.T.[._.n.r.y.]~...]...]...]............////"/&/5/9/@/D/M/Q/Z/^/g/k/|/////////////////////000'0+0;0?0F0J0Q0U0d0h0o0s0|00000000000000000000 1111&1*1;1?1H1L1U1Y1j1n1v1z111111111111111122 222.222;2?2P2T2e2i2r2v2}22222222222222222222 3333-31383<3C3G3X3\3c3g3v3z3333333333333333334 4444,40474;4B4F4M4Q4`4d4m4q4z4~444444444444444444445 5 555#5'50545=5A5J5N5_5c5k5o5w5{5555]555]555]5555555]555]66 6]66$6(61656>6B6K6O6X6\6k6o6x6|666666666666666666677 7777'7+72767?7C7L7P7Y7]7n7r7z7~7777777777]777]777]778 888$8(8/8]4888?8]D8H8O8]\8`8g8k8t8x888888888888888888899 99"9&9-919:9>9E9I9R9V9_9c9j9n9w9{99999999999999999 ::::":&:/:3:B:F:N:R:b:f:w:{::::::::::::::::: ; ;;;';+;4;8;I;M;T;X;g;k;{;;;;;;;;;;;;;;;;;<<<<!<)<-<6<:<J<N<V<Z<b<f<o<s<|<<<<<<<<<<<<<<<<<<<<====&=*=1=5=E=I=R=V=_=c=t=x==================> >>">&>6>:>I>M>]>a>j>n>w>{>>>>>>>>>>>>>>>>>>> ? ???#?'?0?4?E?I?P?T?[?_?n?r??????????????????@ @ @@@)@-@=@A@R@V@_@c@j@n@@@@@@@@@@@@@@@@@@A AAAA-A1A8ARBRSRWR`RdRsRwR~RRRRRRRRRRRRRRRRRRRRSS SSSS%S)S2S6S=SASJSNSUSYSbSfSoSsSzS~SSSSSSSSSSSSSSSSSSTTT&T*T1T]6T:TAT]NTRTYT]TdThTwT{TT]TTT]TTTTTTTTTTTTTTTUUUU U)U-U6U:UCUGUXU\UcUgUpUtU{UUUUUUUUUUUUUUUUUUUUUUVV VVVV'V+V4V8VAVEVVVZVbVfVvVzVVVVVVVVVVVVVVVVVVW WWWW"W&W7W;WDWHWQWUW^WbWsWwWWWWWWWWWWWWWWWWWWWWX XXXX"X&X-X1X:X>XEXIXRXVX_XcXjXnXwX{XXXXXXXXXXXXXXXXYY] YYY]$Y(Y/Y3Y:Y>YMYQYXY]]YaYhY]uYyYYYYYYYYYYYYYYYYYYYYZ ZZZZ.Z2Z9Z=ZFZJZQZUZ^ZbZiZmZvZzZZZZZZZZZZZZZZZZZZZ[[[[+[/[6[;[?[F[S[W[^[b[q[u[|[[[[[[[[[[[[[[[[[[[\ \\\#\*\.\7\;\D\H\Q\U\f\j\q\u\~\\\\\\\\\\\\\\\\\\\\]]]]*].]>]B]I]]N]R]Y]]f]j]q]u]|]]]]]]]]]]]]]]]]]]]]]] ^ ^^^)^-^4^8^A^E^N^R^[^_^p^t^{^^^^^^^^^^^^^^^^^^^^__#_'_._3_7_>_K_O_V_Z_i_m_t_x___________________` ``` `$`-`1`@`D`T`X`a`e`n`r``````````````````aaaa"a1a5aFaJaSaWa^abasawa~aaaaaaaaaaaaaaaaaaaabbbb$b(bcBcKcOcXc\cmcqczc~cccccccccccccccccdddd"d&d/d3dDdHdOdSdbdfdmdqdyd}dddddddddddddddeeee,e0e@eDeSeWegeke|eeeeeeeeeeeeeeeeeeffff#f](f,f3f]@fDfKfOfVfZfifmftf]yf}ff]ffffffffffffff gg g$g4g8g?gCgRgVg_gcgtgxgggggggggggggggghh hh h/h3hDhHhQhUh\h`hqhuhhhhhhhhhhhhhhhhhii ii i$i3i7iGiKiZi^iniriiiiiiiiiiiiiiiiiiij] j jj]!j%j,j0j7j;jJjNjUj]Zj^jej]rjvj}jjjjjjjjjjjjjjjjjjjk k kkk+k/k6k:kCkGkNkRk[k_khklkskwkkkkkkkkkkkkkk]kkk]l llll l/l3l:l]?lClJl]Wl[lblflolsl|llllllllllllllllllm mmm m$m5m9mBmFmOmSmdmhmxm|mmmmmmmmmmmmmmmmmn nnn%n)n9n=nLnPn`ndnunynnnnnnnnnnnnnnnnnn]nno]ooo"o)o-oNRY]gkuyрՀ߀ "&8<DHPT\`pt~Ɂ]΁ҁف]ށ]] &]+/6];?F]KOV]cgnr|̂Ђق݂ ",0?CKO_cuyɃ̓׃ۃ +/9=OSZ^mq{фՄ܄ !%/3=ASW^bquÅՅم #'15?CUY`dswņφӆ%)37IMW[bfpt~ɇׇ͇ۇ  #-1;?QU_cmqňɈӈ׈ 15?CJNX\nr|̉Љ$(:>HLSWim|̊Њ׊ '48?DHOTX_lpw|ċȋϋԋ؋ߋ  '48HLTXgk{ČΌҌٌ݌ &*<@JNUYcgnr|ʍ΍؍܍"48@DLPX\lpz~ĎȎҎ֎!+/6:DHW[mqy}ÏʏΏ؏܏ )-7;BFPT[_imw{ːϐِݐ#,0:>GKUYcgptđ֑ڑ!%/3=AKOY]osϒӒےߒ 26EIcgptȓ̓ޓ"&04;?IMTXbfpt~”ɔ͔ה۔ (,>BJN^blpw{ȕ֕̕ڕ !%/3=AKOY]dhw{ɖ͖ݖ $.2<@GKRVhluyɗ͗֗ڗ '+=AKOY]gkuyĘΘҘܘ %)15=AIMUYim|řΙҙۙߙ  %)37AEW[cgos{ĚȚҚ֚.2<@JNX\fj|]]]]ěțٛݛ]]]  ]!%,0:>HLSWaelpw{Üǜќ՜ܜ  !37GKUYcgy}˝ϝ֝ڝ +/9=GK]akoy}ɞ͞ߞ /3=AKOaeos}˟ϟ"15?CMQ[_quàՠ٠  $.2<@GKUYcgy}ǡˡݡ!+/AELP_cmqˢϢ٢ݢ ,0:>EI[_imtxϣӣ '+:>MQX\cgvz]ʤΤդ]ڤޤ]] #26EIPT]apt{¥ƥϥӥ  ")-<@QUmq¦Ʀզ٦$(/3DHW[swħȧاܧ'+48GKX\ko~ppĨȨϨpܨ]] *.5p:>EpJNUpbfm]z~]]ȩ̩өש .2:>EIY]qu}ĪӪת ".2FJRVfjqu|ƫʫҫ֫ݫ #*.6:AEMQX\lpw{ĬȬϬӬڬެ  '+26=AHLSW^bimtxɭͭԭ]] #*]7;JNU]bfuy]]ˮϮ֮]]!%,]9=LPW]dhw{ǯ˯ׯۯ  !%.2CGNRY]dhpt°˰ϰذܰ"&6:CGPT[_pt{̱б!%59JN]ah]mqx]}]]]IJ̲вײ۲ ] '],07]<@G]TX_cjnuy]óʳ]ϳӳڳ]&*;?HLSWhl{Ĵȴ״۴  '+;?FJRV]aimtxĵ˵ϵֵڵ #'.2AEL]Y]lpw]]¶ƶͶ]ڶ޶] #]04CGN][_nry]]ķȷϷ]ܷ"&37DH]ajnw{Ǹ˸Ҹָ޸ ,09=FJQUfjqu¹ɹ͹޹ '+:>OS\`gk|˺Ϻֺ]ۺߺ]]] ]#'.2:>EIPT[_fjz~]]]]»ƻͻѻػܻ ]-18]=AH]UY`dkożּڼ&*26EIPT[_fjy}ƽʽѽսݽ")-=AH]UYhlsw¾ɾ;޾  "15<@OS\`imtxſֿڿ *.59HLUYbfw{ %)26GKRVbfuy -1BFOSZ^os $59@DSW`dx| /3QUdhtx".2FJSW`dmq/3QUdh!%/3=ASW`dos| $(26@DVZcgrv (,>BJNVZbfnr 04;?FJY]lpw{ !+/9=GKUYcgqu%)059@EIPUY`eip}37FJdhw{ '+59KOim|  '+:>X\koy})-7;EISWaeos]] ]-1:>OS\`imvz26EIcgvz"&59SWfjtx "15<pAELpY]d]qu|  '+26=APT[p`dkpx|] #48IMeix| '+26GK\`imtx  "+/6:CGPT]arv}pp]'+48?CTXaelp)-59@DSW^bqu| "&-1@DLP`dos  '+26=AIM]ahltx !(,48HLX\kovz"&-1AEMQaelp 48G K S W ^ b i m |                       + / 6 : A E \ ` i m t x                       , 0 ; ? R V ] a p t {                        "' + 2? C J N U Y h l {                      , 0 8 < D H X \ d h x |                     ! % - 1 A E P T _ c w {            !15>BIM^bko{ #,09=DHY]fjvz          , 0 7 ; J N _ c r v }                       * . A E P T ` d o s                         # ' / 3 B F MR V ]j n u y                     & * 1 5 = A P T [ _ n r y }                       ' + : > F J Z ^ i m             !%.29=DHQUfjqu~  $37>CGN[_f]kov] !%.29=FJQUfjqu| )-48AENR[_fjsw)->BKOVZko~$(/3:>MQX\kox|)-48?CRVcgtx"&/3CGVZko 15>BSW^bqu '+37?CSW`dko )-48?CLPaenry}  '+26EIPTcgnry}&*;?NR[_fjsw #+/8<FJVZhl}  ")-59BFNR[_gktxpp] $.2>BPT^btxpp]  #'04=AKOX\mqx|pp] *.;?IMZ^sw -1;?IMW[mq{ )-7;EISWimw{ *.8<EIVZgkuy (,6:DHRVhlsw%)37@DQUbfpt~ p#p04;]HLVZcgtx-1;?FJ\`rv"15OSbfx|$(7;BpOSZ]gkrv}A  $+/6:AELPW[dhos| $(/3<@GK\`qu~     " + / 8 < C G P T ] a h l u y                         $ ( / 3 < @ G K T X _ c l p w {                           . 2 9 = E I R V _ c l p y }                        # 2 6 J N U Y b f o s |                          # ' 8 < C G N R a e l p w {                    %)04CGPTeirv !(,;?HL]ahl{ #'04;?HLSWhl{"+/8<MQZ^gkrv (,=APTcgnr{ "&/3:>GK\`os| $(15DHOSZ^eix| "&7;DHQU\`qu|!%.2;?PT[_fjy} !04EIRV]arv  /3BFOSZ^os#'6:IM^bqu!(,>BQUfjy} !%48GKTX_ctx -18]EIY]dhos /3CGNRaemq "15GKUY`dvz &*9=OS]ahl~    ( , ; ? O S d h z ~              !! !!!!!!(!,!;!?!F!J!Q!U!\!`!o!s!|!!!!!!!!!!!!!!!!!!!!""""""&"-"1"8"<"C"G"N"R"Y"]"l"p"y"}"""""""""""""""#####!#3#7#>#B#Q#U#g#k#u#y################$$$($,$;$?$Q$U$_$c$j$n$$$$$$$$$$$$$$%%%)%-%=%A%Q%U%d%h%w%{%%%%%%%%%%%%%%%&&&& &$&6&:&J&N&_&c&m&q&x&|&&&&&&&&&&&&&&& ''''$'(':'>'M'Q'b'f'p't'{''''''''''''''''((("()(-(?(C(R(V(g(k(u(y((((((((((((((()) )))")3)7)A)E)L)P)b)f)u)y)))))))))))))))))**!*%*6*:*D*H*O*S*e*i*x*|****************+++&+*+;+?+I+M+T+X+j+n+}++++++++++++++++, ,,,,!,1,5,F,J,S,W,^,b,s,w,,,,,,,,,,,,,,,,-- --!-0-4-E-I-R-V-]-a-r-v----------------.. .. ./.3.D.H.Y.].l.p.w.{...............//////./2/A/E/V/Z/c/g/n/r///////////////00 0000-010@0D0U0Y0b0f0m0q0000000000000000011 11 1$15191B1F1M1Q1b1f1u1y11111111111111111 222#24282A2E2L2P2a2e2t2x22222222222222222 333"33373H3L3[3_3f3j3r3v3~33333333333333333444 4$4+4/4@4D4S4W4h4l4u4y44444444444444445555#5*5.5?5C5R5V5g5k5t5x5555555555555555666$6(6/636C6G6O6S6b6f6s6w66666666666666666667 777%7p*7.757p:7>7E7pR7V7]7a7j7n7u7y77777777777777]777]777]8 8888#8*8.878;8D8H8O8S8d8h8q8u8888]888]888]8888888888889999&9*999=9D9pI9M9T9pY9]9d9pq9u9|99999999999999999999: ::::":+:/:6:::K:O:V:Z:c:g:n:r:{::::::::::::::::::; ;;;;";+;/;6;:;C;G;N;R;[;_;f;j;s;w;~;;;;;;;;;;;;;;;;;;;;;;<<<<<<&<*<3<7<><B<K<O<V<Z<c<g<n<r<{<<<<<<<<<<<<<<<<<<<<<<= ===="=)=-=6=:=A=E=N=R=Y=]=f=j=q=u=~======================>>>>>>&>*>1>5>>>B>I>M>V>Z>i>m>t>x>>>>>>>>>>>>>>>>>>>>? ? ???!?%?,?0?7?;?D?H?O?S?\?`?g?k?t?x??????????????????????@ @@@@@#@*@/@3@:@?@C@J@O@S@Z@g@k@r@v@@@@@@@@@@@@@@@@@@@@@@@AA AAAA%A)A0A4A=AAAHALAUAYA`AdAmAqAAAAAAAAAAAAAAAAAAAAAAAB BBBB!B(B,B5B9B@BDBMBQBZB^BmBqBxB|BBBBBBBBBBBBBBBCCCC'C+C4C8CGCKCRCVCeCiC{CCCCCCCCCCCCCCCCDDDD)D-D7D;DBDFDXD\DkDoDDDDDDDDDDDDDDDDDE EEE.E2EGBGLGPGWG[GmGqGGGGGGGGGGGGGGGGGHHHH,H0HAHEHOHSHZH^HpHtHHHHHHHHHHHHHHHHI I II#I2I6IGIKIUIYI`IdIvIzIIIIIIIIIIIIIIIIJJ JJJJ!J0J4JFJJJYJ]JnJrJyJ}JJJJJJJJJJJJJJJJJJJJK KK K'K+K:K>KGKKKTKXKiKmKvKzKKKKKKKKKKKKKKKKKKLLLL#L2L6L?LCLLLPLaLeLnLrL{LLLLLLLLLLLLLLLLLMMM%M)M:M>MMMQMYM]MeMiMyM}MMMMMM]MMM]MMM]MMM]MMMMMMMN NNNN'N+N2N]7N;NBN]GNKNRN]WN[NbN]oNsNzNNNNNNNNNNNNNNNNNNNNO OOOO"O3O7O>OCOGONO[O_OfOjOyO}OOOOOOOOOOOOOOOPPPP*P.P>PBPRPVP]PaPhPlPuPyPPPPPPPPPPPPPPPQQ QQ!Q%Q4Q8QIQMQVQZQaQeQvQzQQQQQQQQQQQQQQQRR RR R$R3R7RHRLRURYR`RdRuRyRRRRRRRRRRRRRRRRR SSS!S(S,S4S8S?SCSKSOSVSZSjSnSuSySSSSSSSSSSSSSSSSSST TT T$T3T7TFTJTTTXT_TcTuTyTTTTTTTTTTTTTTTUU UU!U%U4U8UIUMUWU[UbUfUxU|UUUUUUUUUUUUUUUV VVV&V*V9V=VNVRV\V`VgVkV}VVVVVVVVVVVVVVVV WWW!W0W4W=WAWHWLW]WaWpWtWWWWWWWWWWWWWWWWWX XXX-X1X:X>XEXIXZX^XmXqXXXXXXXXXXXXXXXXXYYYY*Y.Y7Y;YBYFYWY[YjYnYYYYYYYYYYYYYYYYYZZZZ)Z-Z6Z:ZAZEZVZZZiZmZ|ZZZZZZZZZZZZZZZZZZ[[[[![%[,[0[8[<[M[Q[Z[^[g[k[r[v[[[[[[[[[[[[[[[\\ \\\\&\*\1\5\>\B\K\O\X\\\c\g\x\|\\\\\\\\\\\\\\\\\]]]]!]%]4]8]A]E]V]Z]c]g]x]|]]]]]]]]]]]]]]]]]^ ^^^-^1^:^>^E^I^Z^^^m^q^y^}^^^^^^^^^^^^^^^^^_ ___)_-_4_8_A_E_N_R_f_j_q_u_________________````&`*`9`=`D`H`P`T```d`k`o`v`z````````````````````a a aa a/a3aCaGaNaRaaaealapaxa|aaaaaaaaaaaaaaaaabbbb!b%b5b9bDbHb[b_bfbjbqbubbbbbbbbbbbbbbbbb c cc c7c;cJcNc]cacxc|ccccccccccccccccccd dddd,d0d?dCdUdYdjdnd}ddddddddddddddddddee eee"e3e7eFeJeQeUe\e`etexeeeeeeeeeeeeeeeeeefff$f(f4f8fCfGfZf^fefifqfufffffffffffffffffffffgggg!g&g*g1g>gBgIgMgTgXgggkgzg~gggggggggggggggggh hhh$h(h/h3hBhFhMhQh`hdhlhphhhhhhhhhhhhhhhhhhhiiii.i2i=iAiTiXigikiiiiiiiiiiiiiiijjjj%j)j8jo Eo Io Xo \o do ho xo |o o o o o o o o o o o o o  p p  p"$p",p"0p"7p";p"Jp"Np"Yp"]p"pp"tp"{p"p"p"p"p"p"p"p"p"p"p"p"p"p"p"p"p$p$q$q$q$q$q$q$-q$1q$8q$r&Nr&Rr&Yr&]r&er&ir&yr&}r&r&r&r&r&r&r&r&r&r&r&r&r&r&r&r&r&s&s&s&s&!s&%s&1s&5s&Fs&Js&Qs&Us&es&is&ps&ts&{s&s&s&s&s&s&s&s&s&s&s&s&s&s&s&s&t&t&t&t&)t&-t&v(Bv(Tv(Xv(_v(cv(kv(ov({v(v(v(v(v(v(v(v(v(v(v(v(v(v(v(v( w(w(w(#w(*w(.w(=w(Aw(Hw(Lw([w(_w(gw(kw(rw(vw(w(w(w(w(w(w(w(w(w(w(w(w(w(w(x(x(x(x(x("x(1x(5x(=x(Ax(Ix(Mx(]x(ax(ix(mx(ux(yx(x(x(xx(x(x(x(x(x(x(x(x(x(x(x(x(x(y(y(y(y(#y('y(7y(;y(Cy(Gy(Wy([y(by(fy(my(qy(xy(|y(y(y(y(y(y(y(y(y(y(y(y(y(y(y(y(z(z(z($z((z(/z(3z(Bz(Fz(Rz(Vz(jz(nz(}z(z(z(z(z(z(z(z(z(z(z(z(z(z(z(z(z(z({( {({({( {(${(,{(0{(@{(D{(K{(O{(^{(b{(j{(n{(}{*{*{*{*{Z{*{*{Z{*{*{p{*{*{p{,{,{,{,{,{,|, |,|,|,+|,/|,9|,=|,D|,H|,R|,V|,`|,d|,s|,w|,|,|,|,|,|,|,|,|,|,|,|,|,|,|,|,|,|,|,}, },},},!},%},/},3},E},I},[},_},g},k},s},w},},},},},},},},},},},},},},},},},},},},~, ~, ~,~,~,%~,)~,2~,6~,?~,C~,L~,P~,Y~,]~,o~,s~,~,~,~,~,~,~,~,~,~,~,~,~,~,~,~,~,~,~,, ,,,!,%,/,3,E,I,Q,U,],a,q,u,,,,,,,,,,,,,,,,,,,,,#,',1,5,?,C,U,Y,c,g,q,u,,,,,,,,,ɀ,̀,׀,ۀ,,,,,,,,#,5,9,C,G,Y]fjswǁˁ܁ #'04=ARV]ajnw{ĂȂׂۂ  $59@DSWgkrvЃԃ݃!(,=APTdhw{ÄDŽфՄ܄ "&7;CGW[dhos|…Ӆׅޅ]]] $+]8<CGPTcgptƆʆӆ׆%)0]=AHLSWfjq]~ćȇ؇܇+/?CJN]ajnLjˈ҈ֈ '+:>GKRVgktxʼn։ډ +/>BKOY]os}ĊȊҊ֊ "&.2:>FJZ^gkrvƋʋҋ֋ "&-]26=]BFM]Z^osz]]]Ì̌Ќ׌ی $(15FJQU^bimtxƍ׍ۍ]] ]#'.29=LPW]\`g]lpw]͎ю؎܎ -1:>OS[_osz~͏яڏޏ /3DHQU\`quÐԐؐ.2CGPT[_ptőɑܑؑ  "&.2:>HL^blpȒ̒Ԓؒ &*37HLTX`dlpǓ]̓Гד]ܓ]  ]$])-4]AELPY]fjqu”˔ϔ04<@HL\`qu]]]ȕ̕ӕו]] ]")-48GKTXgkrvǖ˖Ԗؖ  '+48IMTXgktxɗ͗ޗ "26EIY]nr{Ș̘ݘ !26?CJN_crvș̙ԙؙ  )-48AEVZbfnrz~Ě͚њ '+48AEVZa]fjq]vz]]]ÛǛΛ]ۛߛ  $-1@DKOX\eiz~ʜΜ֜ڜ #*]/3:]?CJ]W[bfmq]]]ÝǝΝҝ #+/?CLPaenrŞΞҞ#'04EIPTcgx|̟Пߟ  $59BFMQbfw{̠Р٠ݠ '+=AKOVZbfnr|áǡΡҡۡߡ (,59@DMQZ^gk|Ţ΢Ңۢߢ] ]](,=AH]MQX]]ah]uyǣˣڣޣ#,07;BFOSdhpt|Ĥ]ɤͤԤ]٤ݤ] %]*.5]:>E]RV]ahl{ťɥ٥ݥ !)-=AHL[_hl}ʦΦߦ#*.?CRVfjy}ϧӧܧ")->BQUfjsw~....Ĩ.Ȩ.Ϩ.Ө...... ...$.(.3.7.B.F.T.X.c.g.r.v...........ȩ.̩.ԩ.ة...........&.*.3.7.C.G.P.T.].a.m.q...........̪.Ъ.۪.ߪ...... ...&.*.=.A.H.L.S.W._.c.j.n.v.z...........ǫ.˫.ԫ.ث...... ....".2.6.A.E.P.T._.c.l.p.z.~.........Ƭ.ʬ.Ӭ.׬...........%.).1.5.E.I.R.V.a.e.n.r.{..........ŭ.ɭ.ԭ.ح...... ....#.*...6.:.I.M.T.X.a.e.l.p.w.{...........Į.Ȯ.Ԯ.خ......... %.).0=.A.HM.Q.Xe.i.pu.y.......ȯ.̯.ԯ.د..... ..!.%.4.8.G.K.S.W._.c.s.w.~......ư.ʰ.Ұ.ְ.ް..0000000060:0E0I0T0X0c0g0p0t00000000±0ʱ0α0ޱ0000000 0000!02060E0I0X0\0k0o0z0~00000000ò0ʲײ0۲0000000000"03070F0J0Y0]0l0p0{000000000ij0˳س0ܳ000000 0000#04080G0K0Z0^0m0q0z0~0000000000ô0ִ0ڴ00000 000"0)0-060:0A0E0L0P0Y0]0d0h0y0}0000000µ0Ƶ0͵ڵ0޵00000 00*0.070;0L0P0W\0`0gt0x000000000Ŷ0ɶ0ض0ܶ0000000#0040D0H0W0[0j0n0}000000000ŷ0̷ٷ0ݷ000000 000,000?0C0R0V0e0i0p}2222222222Ÿ2ɸ2ظ2ܸ2222222 22 2$2+2/262:2B2F2U2Y2h2l2s2w2~2222222222ι2ҹ2ٹ2ݹ22222 222!2(2,2;2?2N2R2a2e2t2x2222222ź2ɺ2кݺ22222222!&2*21>2B2IN2R2Yf2j2qv2z2Ȼ̻Իػ )-6:AENR[_hluyҼּ $04@DX\fjvzŽϽӽ߽ $(48DHTXdhtx̾оھ޾  $04HLSW`dmqz~Ŀȿٿݿ #'15?CMQcgpt}!*.?CJNW[dhqu~  $-18<EIRV]apt}(,37FJQU^bkox|  !%.29=DHQU\`qu|(,59JNW[dhqu~!*.7;DHQU^bkox| $(15>BKOX\mqx| "&/3<@QU^bkox|"+/8<MQZ^osz~ #,0AENRcgnr #,09=FJ[_fjy}-18<HL[_nr  /3GK\`os} ,0AELPcgx| #'.2AELPY]fjqu '+48AENR[_pt{ !)-=AHLTX`dlpx|".2FJQU\`os| 37@DUYbfw{ '+<@OSdhqu|555555555555555 555$5(5/535:5>5K5O5]5a5h5l5{5555555555555555555555 5555)5-54585?5C5J5N5]5a5h5l5y5}5555555555555555555#5'565:5A5E5N5R5[5_5nry}'+37GKSW_csw~ %)15=AQU\`gkz~ #*.59HLSW`dmqx|  $+/8<EIPT[_hlsw  $)-49=DQU^bkox|!%59BFOS\`imvz "&/3:>GKTXaenr"&/3<@IM^bkox| *.7;DHY]dhw{ )->BIM\`im~$(9=DHW[dhy}  !*.59JNU]bfmq)-6:AEVZim~ &*26>BJN^bjnvz!%-18<DHQU]aim} '+48AEVZbfnry}"&.29=EIY]eiy} )-6:KOX\mqx|!%.2CGPT]arv} #+/>BKOVZcgpt"&-1@DTXaevz !%-1:>EIRV]arv/3:>EIQU\`pt| %)8<KO^bimtx #'/3<@GKTXaevz] ]-1CGPTcgnry} &*9=DpQUgktx #26EIRV]arv}]$(15<@QUdhw{ .2FJQ^bim| &]+/6]CGQUgkx|] #-1CGN]SW^]ko  $-18<MQcgw{ #,07;LP_cjosz~ )-6:AENRcgnry}$(9:=:E:I:P:T:c:g:n:r:y:}:::::::::]::]::::::::#:':.];:?:H:L:S:W:`:d:k:o:x:|:::::]::::::::::::] ::::%:):::>:G:K:\:`:i:m:~::::::::::::MMMMMMM MMMM!M1M5M>MBMSMWMfMjMq]vMzM]MMMMMMMMMM]MMMMMMM MMMM!M(M,M=MAMH]UMYMbMfMmMqMzM~MMMMM]MMMMMMMMMMMMMM#M'M.M2MAMEMNMRMYM]MnMrMOOOO|OO|OOpOOpQQQQQQ QQQQ-Q1Q8Q<QMQQQZQ^QjQnQzQ~QQQQQQQQQQQQQQQQQQQ]QQQ#Q48BFRVbfpt"&26JNUY`dsw~]".2FJQUdhos| +/6:AELP_cj]w{%)8<CGPTcgnr]&*;?FJQU^bimtx ,07;JNUYaeuy     p# ' . p; ? F ]S W g k r v ~                        ! & * 1 > B I M U Y a e l p x |    ]   ]   ]             ! ( , ; ? F ]K O V ]c g n ]{                       ! 0 4 > B T X _ c j n u y                         ) - 4 8 ? C R V ] b f m r v }                  04>BTX_cjnw{&*15<@GKTX_cjn '+:>MQ[_im #*.59HLSWfjqvz ,0BFMQX\cgvz#'.29=DHW[bgkrw{]]  ]!%,15<AELY]dhos &*15=AIMTX`dtx]]]SSSSSSSSSSSSSS&S*S;S?SHSLSUSYS`SdSuSySSS -1@DKOX\cgpt}!+/6:LPW[jnw{!%.2;?HL]ahluy#,07;DHQU\`qu| $(15>BIM^bim| $37>BLPW[eipt~!04>BLPZ^hl~!37@DMQZ^gk| 15<@OS]akoy}     $ . 2 < @ J N ` d m q z ~                  ! !!!!0!4!=!A!J!N!W![!d!h!q!u!!!!!!!!!!!!!!!!!"" """"'"+"4"8"A"E"V"Z"a"e"t"x"""""""""""""""""""####&#*#1#5#D#H#R#V#`#d#n#r#|##################$$$$"$&$0$4$>$B$L$P$Z$^$p$t$}$$$$$$$$$$$$$$$$$$%%%%% %*%.%@%D%M%Q%Z%^%g%k%t%x%%%%%%%%%%%%%%%%%%%& &&&)&-&6&:&C&G&P&T&]&a&j&n&&&&&&&&&&&&&&&&&&&'' ''''''+'4'8'I'M'V'Z'c'g'p't'}'''''''''''''''((((#(,(0(9(=(F(J(S(W(`(d(u(y((((((((((((((((((())))))(),)5)9)B)F)W)[)b)f)q)u)|)))))))))))))))))))* ****#*'*/*3*;*?*G*K*[*_*h*l*u*y********************+ ++++"+&+5+9+@+D+S+W+^+b+q+u+++++++++++++,,,,, ,),-,6,:,C,G,P,T,e,i,r,v,,,,,,,,,,,,,,,,,,,,- ----'-+-<-@-H-L-\-`-h-l-|-------------------. . ...).-.4.8.A.E.T.X._.c.l.p.w.{.................///// /)/-/>/B/`/d/s/w////////////////0 0000%0)0:0>0F0J0R0V0^0b0j0n0v0z000000000000000000011111"1+1/1@1D1L1P1X1\1d1h1p1t1|1111111111111111111122222"2,202:2>2E2I2[2_2f2k2o2v2{2222222222222222222222223 3333%3)33373A3E3O3S3]3a3k3o3y3}3333333333333333333 4444*4.4?4C4U4Y4b4f4m4q4x4|444444444444444444444555555$5(51555>5B5I5M5^5b5i5m5q5x5|5555555555555555555 666"64686B6F6M6Q6c6g6v6z6666666666666666777%7)7;7?7I7M7T7X7j7n7}77777777777777778888-818C8G8X8\8k8o8v8z8888888888888888888889 9999#9,90999=9N9R9^9b9i9m9x9999999999999 :: :$:5:9:H:L:^:b:s:w:::::::::::::;;;;-;1;@;D;V;Z;k;o;~;;;;;;;;;;;;;;<<%<)<8<<<N<R<c<g<v<z<<<<<<<<<<<<<= ===-=1=@=D=U=Y=h=l=~==============>>">&>8><>M>Q>`>d>v>z>>>>>>>>>>>>>>>? ???-?1?@?D?V?Z?k?o?~??????????????@@%@)@8@<@N@R@c@g@v@z@@@@@@@@@@@@@A AA!A0A4ACAGAXA\AkAoAAAAAAAAAAAAAABBB%B)B;B?BPBTBcBgBnBrBBBBBBBBBBBBBBCCC(C,C;C?CQCUCfCjCyC}CCCCCCCCCCCCCD DD!D0D4DCDGDXD\DkDoDwD{DDDDDDDDDDDDDDDDDE EEE#E'E0E4E=EAEREVE]EbEfEmErEvE}EEEEEEEEEEEEEE FFF#FAFEFTFXF`FdFlFpFFFFFFFFFFFFFFFFFFF GGGG+G/G9G=GOGSG\G`GqGuG|GGGGGGGGGGGGGGGGGGH HHH"H/H3HDHHHfHjHyH}HHHHHHHHHHHHHHHI III)I-IQHQLQSQWQaQeQlQpQzQ~QQQQQQQQQQQQQQQQQQQQR RRRR#R'R.R2RUEUJUNUUUbUfUnUrUyU}UUUUUUUUUUUUUUUUUUUUU V VVV V$V,V0V@VDVLVPVXV\VlVpVxV|VVVVVVVVVVVVVVVVVVVVW WWWW"W'W+W2W?WCWKWOWWW[WkWoWvW{WWWWWWWWWWWWWWWWWWWWX XXX#X'X.X2XAXEXMXQXaXeXlXqXuX|XXXXXXXXXXXXXXXXXXXXYY YYYY!Y(Y5Y9Y@YEYIYPYUYYY`YmYqYyY}YYYYYYYYYYYYYYYYYYZZ ZZZ(Z,Z3Z8Z[B[I[M[\[`[g[k[t[x[[[[[[[[[[[[[[[\\\\7\;\J\N\U\Z\^\e\j\n\u\z\~\\\\\\\\\\\\\\\\\\\\\]]]]!]%],]1]5]<]A]E]L]Y]]]d]i]m]t]y]}]]]]]]]]]]]]]]]]]]]]^^^^ ^(^,^4^8^H^L^S^W^_^c^k^o^^^^^^^^^^^^^^^^^^^^^^^_ ___&_+_/_6_:_A_E_T_X___c_j_n_}____________________` ```'`+`4`8`A`E`V`Z`a`e`l`p`w`{`````````````````a] aaa]aa%a]2a6a=aAaHaLa[a_anaraya]~aaa]aaaaaaaaaaaaaaaab]b bb]b#b2b6b=bAbJbNbWb[bjbnbwb{bbbbbbbbbbbbbbbbc cccc*c.c5c9cBcFcMcQcbcfcocscccccccccccccccdd"d&d5d9dHdLdSd]`dddkdodddddddddddddddddee eeee.e2e9e=eJeNe[e_efejewe{eeeeeeeeeeeeeeeeeeef fff!f%f7f;fDfHfQfUf^fbfkfofxf|fffffffffffffffffgggg%g)g0g4gCgGgNgRg_gcgpgtg{gggggggggggggggggggg hhhh)h-h:h>hGhKhThXhahehnhrhhhhhhhhhhhhhhhhhiiii$i(i1i5iFiJiQiUidihioisiiiiiiiiiiiiiiiiiiiij jjjj,j0j9j=jJjNj[j_jhjljujyjjjjjjjjjjjjjjjjjkkkk!k%k/k3kEkIkRkVkgkkkrkvkkkkkkkkkkkkkkkkkkkkl ll!l%l.l2l;l?lHlLlUlYlblflolsl|llllllllllllllllllmmmm-m1m:m>mGmKmTmXmamemnmrm{mmmmmmmmmmmmmmmmmmmm nnnn(n,n;n?nFnJn[n_nhnln}nnnnnnnnnnnnnnnnnnno oooo%o)o2o6oGoKoRoVobofouoyoooooooooooooooooop pppp-p1p9p=pMpQpZp^pgpkptpxpppppppppppppppppppqqqq#q'q.q2q9q=qDqHqOqSqZq^qeqiqpqtq{qqqqqqqqqqqqqqqqqqrrrr(r,r5r9rJrNrUrYr`rdrkror~rrrrrrrrrrrrrrrrrrsssss!s2s6s=sAsPsTs[s_shslsusyssssss]sss]sss]sss]sss]ssssttt t)t-t6t:tKtOtVt][t_tft]ktotvt]{ttt]tttttttttttttttu u uu"u)u-uwGwKw\w`wiwmw~wwwwwwwwwwwwwwwwwx xx x$x-x1xBxFxMxQx`xdxuxyxxxxxxxxxxxxxxxxx yyy#y,y0y7y;yLyPy_ycytyxyyyyyyyyyyyyyyyz zzzz"z3z7zFzJz[z_zpztzzzzzzzzzzzzzzzz{ { {{"{){-{<{@{Q{U{^{b{i{m{~{{{{{{{{{{{{{{{|||&|*|<|@|I|M|T|X|i|m|||||||||||||||| }}}}%})}:}>}M}Q}c}g}x}|}}}}}}}}}}}}}}} ~~~#~4~8~A~E~L~P~a~e~t~x~~~~~~~~~~~~~ !26EIPT[_nr| #'15?CMQ[_qu~ÀԀ؀߀&*37HLSWfjqu~Á́Ёف݁ "&/3<@IMVZcgpt}Ă΂҂ $(/3<@IMTXaenr{ăȃуՃރ %)59HLUYjnw{„Ƅτӄڄބ04=AJNW[dhqu~΅҅ۅ߅!04=AJNW[dhqu~džˆԆ؆$(/3DHQUfjqu͇чڇއ!%15DHQUfjswLjˈۈ߈$(/3:>MQX]]ah]uyĉȉщՉމ "*.=AHL[_pt{]]ĊȊҊ֊] ]"15?CMQ[_qu~ˋϋ  $59JN]aswˌό،܌ !%6:IM^bswÍǍ؍܍ -1BFUYjnw{ÎԎ؎%):>GKRVgkz~Ϗӏڏ]ߏ]] !(,37FJTX_cmq{ɐ͐Ԑؐ (,<@GKVZcgpt}ǑˑՑّ  $-1:>GKTXaenr{’ɒ͒ߒ #+/7;CGOS[_gkswǓ˓ԓؓ!+/9=DHRV`dnrŔɔҔ֔ߔ"&-1CGPTeiptÕ˕ϕוە&*15?CMQ[_fjtx͖іؖܖ &*15>BKOX\mqx|×Ǘї՗ߗ!*.7;DHQU^bsw~Ƙʘј՘ߘ  -1:>GKTXaenr{řəؙܙ %)8<DHPT\`hltxšƚϚӚܚ &*;?HLUYbfos|ɛ֛͛ڛ #,09=FJSW`dmqĜȜ؜ܜ #,07;BFOS\`imvzÝ̝Нٝݝ &*37@DMQZ^gktxʞΞמ۞ $(/3BFOSdhosƟʟџ՟ !%.2;?HL]ajnw{ ɠ͠Ԡؠ(,=AJNW[dhqu~¡ˡϡءܡ )-48DHW[dhy}Ţɢآܢ%)37NRY]nrǣˣ]] (,6:DHRVhlvz¤ƤϤӤ%)04EIX\mqĥȥڥޥ/3BFW[lpҦ֦!(,=APTfj{˧ϧ !*.59JN]arvǨ˨ܨ 15DHZ^gkrvũɩةܩ .2:>FJQU^bkox|ĪͪѪتܪ %)59BFRVbfz~˫ϫ٫ݫ)-7;BFX\kov]{]]ìǬϬӬ #'15?CMQ[_imíͭѭۭ߭ '+;?IMTXbfmq{Ů׮ۮ (,37AELPbfx|ɯͯׯۯ%)26BFRV`dnr|ðǰѰհܰ $(26@DSWaeos}ñͱѱ۱߱ )-7;EI[_imw{ŲɲӲײ#'15?CMQcgquóͳѳ۳߳ )-7;MQ[_fjtx´ƴдԴ޴",0:>HL^blpz~ʵεصܵ &*48JNUYhl~Ķֶڶ .2<@GK]ap[t[|[[[[[[[[[[[[[·[ɷ[ͷ[Է[ط[[[[[[ [[[.[2[A[E[L[P[a[e[m[q[y[}[[[[[[[[[¸[Ƹ[͸[Ѹ[ڸ[޸[[[[[[ [[[%[)[:[>[M[Q[Z[^[e[i[r[v[[[[[[[[[˹[Ϲ[ֹ[ڹ[[[[[ [[[[+[/[>[B[M[Q[\[`[s[w[[[[[[[[[[[ú[Ǻ[Ϻ[Ӻ[ں[޺[[[[[[[ [[[["[&[.[2[:[>[F[J[R[V[^[b[r[v[}[[[[[[[[»[ƻ[ֻ[ڻ[[[[[[[[[[[$[([7[;[BG[K[RW[[[bo[s[z[[[[[[[[Ǽ[˼[Ӽ[׼[߼[[[[[ [[[/[3[C[G[O[S[[[_[o[s[[[[[[[[[[[[[ƽ[ʽ[ҽ[ֽ[ݽ[[[[[[[ [[[ [$[,[0[8[<[D[H[P[T[d[h[w[{[[[[[[[[[[[[þ[˾[Ͼ[߾[[[[[[[[ [[[[%[)[9[=[L[P[X[\[d[h[p[t[|[[[[[[[[[[ǿ[˿[ӿ[׿[߿[[[[[[ [[[["[&[.[2[:[>[F[J[Z[^[f[j[r[v[~[[[[[[[[[[[[[[[[[[[[[[ [ [[ ['[+[4[8[?[C[J[N[U[Y[h[l[s[w[[[[[[[[[[[[[[[[[[[[[[[&[*[1[5[D[H[O[S[\[`[g[k[|[[[[[[[[[[[[[[[[[[ [ [[![1[5[=[A[I[M[][a[q[u[[[[[[[[[ &*15>BIMVZaenr{  $-1:>OS\`imvz  $,08<DHOSbfosz~ $(15>BIMVZimtx -18<CGVZaelpw{]]]] 15>BKOVZcgnr!*.59JN]ajnw{ +/6];?F]KOV]cgnrz~ $(15<@IMVZaenry}*.7;DHQU^bsw #,07;LP_ctx #'04EIRV_clpy}  #'8<EIRV_clp!*.7;LPY]fjsw $(9=DHOSZ^mq !(,;?HLUY`dmqz~!%,0?C[_nry} "&/3:>GK\`gkz~#,0AEMQaenr{#+/>BKOX\mqx| $-18<MQZ^gkrv%):>GKRVgkz~!(,6:AEW[bfmq"&7;BFUYbfmq ,^0^@^D^T^X^_^c^r^v^} ^^ ^^^^^^^^^^^^^^^^ ^^^^(^,^3-8^<^C-H^L^S-X^\^c-p^t^^^^^^^^^^^^^^^^^^^^^^^$^(^9^=^D^H^W^[^c^g^n^r^{^^^^^^^^^^^^^^^^^^-^^- ^^-^!^(--^1^8-E^I^P-]^a^r^v^^^^^^^^^^^^^^^^^^^^^^ ^'^+^<^@^O^S^[^_^g^k^{^^^^^^^^^^^^^^^^^^````&`*`1`5`F`J`Q`U`d`h`q`u```````-``-```````````` `$`+`/`8`<`K`O`V`Z`c`g`n`r````````````````````````!`*`.`7`;`L`P`W-\```g-l`p`w-|``-``-````````````````0`4`;`?`N`R`[`_`f`j`{````````````bbbbbbbbbb"b&b/b3b:b>bObSb\b`bibmbvbzbbbbbbbbbbbbbdddddd dddd$d(d8d<dCdGdXd\dhdlddddddddddddddddddddd ddd#d/d3dGdKdRdVdhdldsdwddddddddddddddd dd(d,d4d8dHdLdSdWd_dcdjdndvdzdddddddddddddddddddd ddddd.d2d9d=dFdJdQdUd\d`dodsdzd~ddddddddddddddddddd(d,dHdLd[d_dfdjdqdud "/3;?QUbfuy]]]] '+2]7;B]OS\`qu#'.]37>]CGN][_hluy]!%,]9=FJ[_hl{")->BQUfjsw~ %)04;?FJY]eiqu}%)04=AJNUYaenr{ "+/8<EIZ^gktx *.=AHUYjn~q$(8<MQZ^eiz~ &*6:IMTXimtx  )-<@GKRV]apt} 15>BKOX\eiz~ !%6:CGNRcgpt   (,48HLUYjn] *.?COS\`osz]] $]15FJVZcgvz "&/3<@QU]aimuypppp #,09=FJ[_hlsw]] ]$(/3<@IMVZkox| +/6];?F]KOV]cgpt{]]] !%.2CGN]SW^]cgn]{ "+/8<MQZ^gk|#'04=APT]ajn   '+48?CTXaevz"&/3:>OSbfuy.29=DHW[bfnry} '+48IMTXgktGz~Gpppp$(/3BFRVeippuypp]] ]")-48GKTXgkrw{  ]   ] ! ( ]5 9 B F U Y ` ]e i p ]u y  ]               ]   ]   ]) - 6 : I M T ]Y ] d ]i m t ]                      ! ( p- 1 8 pE I R V e i p pu y  p       ]   ]         " 3 7 G K Z ^ e pj n u pz ~  p             p   p   p    % ) 2 6 = A P T [ ` d k p t {                    ]] $+]04;]HLS]X\c]hls]x|]] ]]&*16:AFJQ^bkox|]]pp pp'+2p7;BpOSZp_cjpw{ #'6:AELP_cjnvz%)0]59@]MQX\eipt}!%15>BQU\paelpy}&*26FJSWhluy !15FJSW^bsw '+48AEVZimvzfffffffffffff fff%f)f6f:fGfKfVfZfgfkfvfzffffffffffffffffff fff-f1fBfFfOfSfZf^fofsfffffffffffffffffffff*.59HhLhThXhdhhhthxhhhhhhhhhhhhhhhhhh hhh.h2h:h>hFhJhRhVhfhjhyh}hhhhhhhhhhhhhhhhhhh!h%h4h8hAhEhLhPhahehthxhhhhhhhhh ")-48?CRV]ako~kkkkkkkkkkk k(k,k4k8kHkLkYk]kjknkyk}kkkkkkkkkkkkkkkkkkkk!k(k,k=kAkPkTkekikrkvk}kkkkkkkkkkkkkkkk kkkk%k)k:k>kMQX\cgqu    & * 9 = D H R V e i z ~                   !! !$!+!/!6!:!A!E!L!P!W![!b!f!u!y!!!!!!!!!!!!!!!!!" """!"%"-"1"B"F"M"Q"Z"^"g"k"r"v"}"""""""""""""""""""# ###,#0#8#<#D#H#O#S#[#_#g#k#s#w###################$$$$)$-$7$;$E$I$_$c$l$p$z$~$$$$$$$$$$$$$$$%%%%%!%4%8%?%C%R%V%^%b%q%u%|%%%%%%%%%%%%%%%%%& & &&&+&/&D&H&Y&]&o&s&&&&&&&&&&&&&&&&&' '''%')'8'<'N'R'Y']'l'p'w'{''''''n'n'n'n'n'n'n'n'n'n'n(n(n (n(n(n((n,(n9(n=(nJ(nN(nY(n](nj(nn(ny(n}(n(n(n(n(n(n(n(n(n(n(n(n(n(n(n(n)n)n )n)n!)n0)n4)nE)nI)nR)nV)n])na)nr)nv)n)n)n)n)n)n)n)n)n)n)n)n)n)n)n)n)n*n *n*n*n-*1*E*I*P*\*`*o*s*z****]**************] ++++)+-+6+:+C+G+X+\+c+g+n+r++++++++++++++++++]+++],,,],,&,*,2,6,H,L,V,Z,i,m,|,,,,,,,,,,,,,,,,,,----#-'-6-:-A-F-J-Q-V-Z-a-n-r-y-}--------------]---]---] ...#.p'.p/.p3.p:.p>.pE.pI.pP.pT.p[.p_.pf.pj.pq.pu.p|.p.p.p.p.p.p.p.p.p.p.p.p.p.p.p.p.p.p/p/p/p/p$/p(/p4/p8/pI/pM/pT/pX/p`/pd/pu/py/p/p/p/p/p/p/p/p/p/p/p/p/p/p/p/p/p/p/p0p 0p0p0p-0p10p90p=0pE0pI0pQ0pU0pe0pi0pr0pv0p0p0p0p0p0p0p0p0p0p0p0p0p0p0p0p0p0p0p1p1p1p1p(1p,1p51p91pJ1pN1pW1p[1pl1pp1p1p1p1p1p1p1p1p1p1p1p1p1p1p1p1p1p1p1p2p 2p2p!2p*2p.2p?2pC2pL2pP2pa2pe2pl2pp2p2p2p2p2p2p2p2p2p2p2p2p2p2p2p2p2p3p 3p3p3p/3p33p;3p?3pG3pK3pS3pW3p_3pc3ps3pw3p3p3p3p3p3p3p3p3p3p3p3p3p3p3p3p3p3p3p3p3p3p3p4p4p4p4p4p4p.4p24p94>4pB4pI4N4pR4pY4f4pj4pr4pv4p~4p4p4p4p4p4p4p4p4p4p4p4p4p4p4p4p4p4p45p5p55p5p5+5p/5p65;5p?5pF5K5pO5pV5[5p_5pf5k5po5pv55p5p5p5p5p5p5p5p5p5p5p5p5p5p5p6p 6p6p6p6p#6p'6p06p46pE6pI6pW6p[6pb6pf6pn6pr6pz6p~6p6p6p6p6p6p6p6p6p6p6p6p6p6p6p6p6p6p6p7p7p7p7p#7p'7p.7p27p:7p>7pF7pJ7pR7pV7p^7pb7pj7pn7pv7pz7p7p7p7p7p7p7p7p7p7p7p7p7p7p7p7p7p7p7p7p8p8p8p8p 8p(8p,8p38p78p?8pC8pK8pO8pW8p[8pk8po8p~8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p9p 9p9p9p9p"9p29p69p=9pA9pI9pM9pU9pY9pa9pe9pm9pq9p9p9p9p9p9p9p9p9p9p9p9p9p9p9p9p9p9p9p9p9p:p:p:p:p:p#:p*:p.:p5:p9:p@:pD:pS:pW:p^:pb:pk:po:pv:pz:p:p:p:p:p:p:p:p:p:p:p:p:p:p:p:p:p:p:p:p;p;p;p;p";p2;p6;pE;pI;pP;pT;pc;pg;pn;pr;p{;p;p;p;p;p;p;p;p;p;p;p;p;p;p;p;p;p;p;p<p <p <p<p"<p1<p5<pE<pI<pY<p]<pd<ph<px<p|<p<p<p<p<p<p<p<p<p<p<p<p<p<p<p=p =p=p=p%=p)=p8=<=E=I=R=V=_=c=t=x=====================>> >]>>>]*>.>5>]B>F>M>Q>Y>]>o>s>}>>>>>>>>>>>>>>>>>>>>?????#?3?7?>?B?S?W?^?b?j?n????????????????????@@@@!@%@,@0@7@;@B@F@U@Y@`@]e@i@p@]}@@@]@@@@@@@@@@@@@@@@A AAAA$A(A1A5AFAJASAWA^AbAkAoAxA|AAAAAAAAAAAAAAAAAAAB BBB%B)B2B6B=BABJBNBWB[BdBhBqBuBBBBBBBBBBBBBBBBBBBBCCCC#C2C6C?CCCLCPCYC]CnCrC{CCCCCCCCCCCCCCCCCCDDDD.D2D;D?DFDJD[D_DnDrD{DDDDDDDrDrDrDrDrDrDrDrDrDrDrDrDrDr ErErErEr%Er)Er0Er4ErCErGErNErREr[Er_ErnErrEryEr}ErErErErErErErErErErErErErErErErEr FrFrFr#Fr,Fr0Fr7Fr;FrLFrPFr_FrcFrjFrnFr}FrFrFrFrFrFrFrFrFrFrFrFrFtFtFtFtFtFt Gt GtGtGt#Gt'Gt8GtVtBVtKVtOVtXVt\VtmVtqVtzVt~VtVtVtVtVtVtVtVtVtVtVtVtVtVtVtVtVtWtWtWtWt#Wt'Wt6Wt:WtCWtGWtPWtTWt]WtaWtjWtnWtWtWtWtWtWtWtWtWtWtWtWtWtWtWtWtWtWtXtXtXt'Xt+Xt3Xt7Xt>XtBXtJXtNXtWXt[XtjXtnXtuXtyXtXtXtXtXtXXXXXXXXXXXXXY YYYY"Y&Y5Y9YBYFYOYSYZY^YgYkY|YYYYYYYYYYYYYYYYYYZ ZZZ#Z'Z8Z]F]J]Y]]]d]h]w]{]]]]]]]]]]]]]]]]]]]]]^ ^^^$^(^7^;^L^P^Y^]^d^h^y^}^^^^^^^^^^^^^^^^^^^_ ___%_)_8_<_C_G_V_Z_a_e_m_q_x_|___________________````+`/`8`<`C`G`X`\`k`o`x`|``````v`v`v`v`v`v`v`v`v`v`v`v`vav avavavav*av.av5av9avBavFavUavYav`avdavsavwav~avavavavavavavavavavavavavavavav bvbvbvbv#bv'bv7bv;bvCbvGbvWbx[bxcbxgbxobxsbxbxbxbxbxbxbxbxbxbxbxbxbxbxbxbxbxbxbxcxcx cxcxcxcx%cx)cx:cx>cxEcxIcxPcxTcxccxgcxvcxzcxcxcxcxcxcxcxcxcxcxcxcxcxcxcxcxcxcxcxdx dxdxdx dx$dx-dx1dxBdxFdxWdx[dxddxhdxodxsdxdxdxdxdxdxdxdxdxdxdxdxdxdxdxdxdxdxdxexexexex&ex*ex2ex6exFexJexSexWex^exbexkexoexvexzexexexexexexexexexexexexexexexexex fxfxfx#fx4fx8fxIfxMfxVfxZfxafxefxnfxrfxfxfxfxfxfxfxfxfxfxfxfxfxfxfxfxfxfxfxgx gxgxgx%gx)gx:gx>gxGgxKgx\gx`gxigxmgx~gxgxgxgxgxgxgxgxgxgxgxgxgxgxgxgxgxhx hxhxhx hx3hx7hx?hxChxKhxOhxWhx[hxkhxohxwhx{hxhxhxhxhxhxhxhxhxhxhxhxhxhxhxhxhxhxhxhxhxhxix iixixiix"ix)i6ix:ixBixFixNixRixbixfixnixrixzix~ixixixixixixixixixixixiixixiixixiixixj jxjxjjxjx&j+jx/jx6j;jx?jxFjSjxWjx_jxcjxkjxojxjxjxjxjxjxjxjxjxjxjxjxjxjxjxjxjxjxkx kxkxkx#kx0kx4kx;kx?kxFkxJkxRkxVkx^kxbkxjkxnkxukxykxkxkxkxkxkxkxkxkxkxkxkxkxkxkxkxkxkxkxkxkxlx lxlxlx$lx(lx8lxrxBrxRrxVrxfrjrsrwrrrrrrrrrrrrrrrrrrrrrssss"s&s-s1s8svEvIvRvVv_vcvlvpvyv}vvvvvvvvvvvvvvvvvvvvvwwww(w,w3w7w@wDwMwQwZw^wgwkw|wwwwwwwwwwwwwwwwwwwwxxxxxx'x+x2x6x?xCxLxPxWx[xdxhxoxsxxxxxxxxxxxxxxxxxxxyyyyyy(y,y5y9yByFyOySy\y`yiymyvyzyyyyyyyyyyyyyyyyyyyyy zzzz+z/z@zDzMzQzXz\zmzqzzzzzzzzzzzzzzzzzzzz{ {{{{,{0{9{={F{J{S{W{`{d{m{q{{{{{{{{{{{{{{{{{{{{| ||||&|*|3|7|@|D|M|Q|Z|^|g|k|t|x||||||||||||||||||| }}}#},}0}7};}L}P}_}c}l}p}y}}}}}}}}}}}}}}}}}}}}}~~~~~!~*~.~?~C~L~P~Y~]~f~j~s~w~~~~~~~~~~~~~~~~~~~  #'04=AJNW[dhy}/3BFW[dhos€ˀπ؀܀ !%.2CGNRaenr{āȁсՁށ +/8<EIRV_ctxȂ̂Ղق&*;?FJY]dqu}Ãǃ؃܃ &*9=EIQUeix|Ʉ̈́քڄ  "+/6:KO^bivząȅхՅޅ $(8<C]PT]apt}Ɔʆӆ׆ ]"+/>BI]VZcgvz‡Ƈ·҇ڇއ "*.>BKOVZcgpt{ĈՈو $-1:>EIRVgktxʉΉ߉ -1:>OSZ^mqz~ÊNJ؊܊ (,48@DLP`dkox|Njˋҋ֋"&7;BFUYbfw{Ɍ͌֌ڌ  "+/6:KO^ybyi myqyxyy yyyy ( 0 8@HPX`hpx "$&(*,.02468;=?ACEG I(K0M8O@QHSPUXW`Yh[p_xagikmouw~9 (08@HPX`hpx (08@HPX`hpx   "$&(*,.025 :(M0O8Q@SH[P^X``bhdpfxhknprtvxy  $048<@DPTX\`dptx|(,048<HLPT`dhlptx|ggggggggiiiiiii iii i$i(i,i8i<i@iDiPkTkXk\khklkpktkkkkkmmmmmmmmmmmmoooooooo $(,8<@DHLPTX\hlptx|  $(,04@DHLX\`dhlx| $048<@DPTX\`dptx|uuuuuuuu  $(,04@DHLX\`dptx| $048<HLPT`dhlx|wwwwwwwwwwwwwwwwwwwwwwwwww(w,w0w4w@DHLPT`dhlx|      ( , 0 4 8 < H L P T ` d h l p t                              $ ( , 0 4 @ D H L X \ ` d h l x |                               ( , 0 4 @ D H L X \ ` d p t x |                             ( , 0 4 @ D H L X \ ` d h l x |                            $ ( , 8 < @ D P T X \ h l p t                       (,048<HLPT`dhlptx| (,048<HLPTX\hlpt  $(,8<@DPTX\`dptx|  $048<HLPT`dhlx|~~~~~~~~~~~~~~~~~~~~(~,~0~4~@~D~H~L~X~\~`~d~ptx|  $048<@DPTX\`dptx|  $(,8<@DPTX\`dhlx|(,04@DHLX\`dptx|(,04@DHLX\`dhlptx| (,048<HLPTX\hlpt (,048<HLPT`dhlx|(,04@DHLX\`dhlx|  $(,8<@DPTX\hlptx|  $(,04@DHLX\`dhlx|  $048<@DPTX\`dptx|(,04@DHLPT`dhlx|(,04@DHLX\`dptx|  $048<HLPT`dhlpt       $ ( , 0 4 8 < H L P T X \ ` d p t x |                       !!!!!! !$!0!4!8!>> >>> >$>(>,>0>4>@>D>H>L>P>T>X>\>h>l>p>t>>>>>>>>>>>>>>>>>>>>>>>>>>>? ?????(?,?0?4?8?>>>>>(>,>0>4>@>D>H>L>X>\>`>d>p>t>x>|>>>>>>>>>>>>>>>>>>>>>>>? ?????(?,?0?4?@?D?H?L?X?\?`?d?p?t?x?|?????????????????????????@@@@@@ @$@(@,@8@<@@@D@H@L@P@T@X@\@h@l@p@t@x@|@@@@@@@@@@@@@@@@@@@@@@@@@A AAA A$A(A,A8A,|(P "F$}&3(d*,.025K:WMnOQ S2[^`zbdyfhkjnprmtvx y 4H \ p$ 8"L$`&t(*,.02468(<Pl;=?A$8LC`EtGIKMOQSUW(Y<[[ py\_a<tT4l<p D gd i k m oX a \  l uu \  \   \@       , H ` x      Dpy\(Lpy\w\$Lt4l8\p\\$Hl4Tt\\H$8L`t $<Tl$8\p~h|4Hlu\ @Th|(Hh   \  \ !)!\d!m!\!!\!!\""\T"h""""<#h###\$4$`$$$,%&8&L&x&&\&&\&9&\('1'\l'u'\''\''\8((((\) )\L)U)\))\))\))\0*9*\l*u*\**\*+H+Q+\++\++\++\$,-,\X,a,\,,\,,\- -\8-X---\--\..\L.U.\..D/|////\0090\h0q0\01H1111\12\42=2\l2u2\22\22\33\H3Q3\t3}3\33\33\44\H4Q4\44\44\5%5\X5a5\55\55\6<6\6e6\66\66\7!7\X7a7\77\77\8 8\t8}8\88\88\(919\\9e9\99\99\$:-:\\:e:\::\::\;%;\\;e;\;;\;;\<%<\d<m<\<<\<<\,=5=\t=}=\==\> >\D>M>\|>>\>>\>>\8?A?\??\??\@@\H@Q@\@@\@@\@@\ A)A\XAaA\AA\AA\BHBtB}B\BBCC\hCCCC\D4D`DiD\DD\DD\E!E\PEYE\EE\EE\F!F\`FFF\FGG\TG]G\GG\GGDHHH\HHH\II!I\\IpIII\II\4JXJaJ\JJJ\K(K1K\`KiK\KL LL \MeM\MMM@ AY܅QB0Z7: '[MzdmCRJ=Ŏ_W&'R/dCk8+/QM9tWI~*ebYC!@4:MH ikv1Fطxb՛K2y+Dip5ep^"y 7b(RCE#]{ 紾Råi'b$DXyv$PA ,g5FPwBVGd\ f?⑥#R-Fe`sL 'IB8X{YX%܄x0a}?qMz$Y{BPBU }Ou]M&Y3=h;|*i)g,r8wCR?HW9zVW?EE$ݡ4S7@>S9z-#Z=?WRʞZ'yғLxW0{dظjw(zdt "NvDI hs <5`ʂXxRd5m}4th,v:mfPd RۙˡNHSu]ou\czߞP Q.[.wb>A,e/z*-g!]U~ݡ3 }ICѯwb^=VQXO3>?FУ9-\,Zxp𠅒_IME7ӚcWYO]֠Xqz-tB+<2}5}UPJLU SR]Hpν= VZ:S2ӹBɊn*1 0 9Gl=y;uL; ҂Ø>b[Qڜ{oNCu@ې 牥 ”YOCC u1 1Z=7f,?Ŗ_WVF{i 6+.AZύ;%ORh`i=ü d9h_}JkԩA= Tru&8t!UA.\"'ҼLĕc3^{+G@8{YOz Qzwo+C".xx 1#|?ڂ̣4?]Uzre)YOx.E^괽)"6ɋdc5Z_ѳ/F}ExL=g^H[&K!Q: ]/I?= 5yPl`"0* + wZQó>< ҄ 5Y \K>B$Zguֻ@p3¬-?|I>5JWYh . ΋d%yHjs+_#=zRW^[su0w= >AiEh_o츖Sk'QI::G|k[Cƍ9RAx+(乐|Z7$7LڥY7>5h2[@qXk#_t"&h0w'iM]>[6ujH{?`b?DpN#ϱE&D]P&`J]>q4\vZWYS.IҋdEU{H˨//=rCx(l)i6UOk;+6sDOK? <@[@5K(*7X [ A@ #{wK;5Eu(c<6D*՜;^l;$9sDIl7!w:T< +bh6]ll ;P2 j)1QO5O=<wMLa()O2(܂Gu*y+{2FF\M75QOmyu<(@CUqR 2*9v@(+=[qsn /M;A4l!rӜ A$y4*+9a9z>54(!lp}?/>AjFdӂOjyj4( (cbAp(<~Oق@b?L";lg~IBMКZ!^P3 " }.V  M0%" 0 D@9M P! &Է\ l!*P Q!RH!t gm=$ 2p@A? ҄2" o2O B3R .V  ;" 02O _P V /" Eq oy" \PJQ" >tR $.* cC " 7c+ 9_ -! R  }ztx lR@ ; P" Z"  <. %}7 zX !Lp"D" P+" 9'K@ D  ns3" D" _ =q' D! 00 s$.! @" $'`K( R! ;* 9P" $;" 0. M0%" =. 0: f " - V  ^@  tZPE|" >~( m !<`o 8D!1Z  ; !lP1 ! X" wp" P" GP inC" x`" " fL0 1 Z eH !t;@nA ҙԧ !j<!Edj h0* Е" H" @" >KE 8 ?T P" >`t nr)" HP! @ /1" Z@C ! c*pQ =N 2O @. 0Y2 r! 'IR ^ E@a _ h9f F 0/% o" .`V  ͋0" Z P @1N K  & G T%C !p" * R #70c `&! s! p~9 $xtQ! u" 0!pH!v|kP/\ 0 ~P Eu̦!!f/@W  T4" rDZ (L@ ]`= A;mA b" ^ 0|pz! " -! /W c` @ {*L0 3] 1" b -U  Q0,%" /WO Y B" "@D4 Rrwn"  4S m oy" (0! 2[ Z!xW<"  !D"BX eP@*" ȧ !4@aO ve jvb ;mD <! 6c# j5a  xh -$ !9! `!J:S p3O Sg# KP CF@+" ܀}] fk" `!  dn !> " 70" " 5aM XО" ,W:-" S.* ;n F0N M#" vp" !k@)  `p !~  9& `" /;" ;` S00" )j! KP}7 eph" BPq" Q0,%" =D uh0m" Bk'  #^ sT3" " m oy" UN 'L/ /( 2ops3" zti A4^O l3 ] P@*" =S`/" <#FP P}7 6Pb1 e( -`2 U7Pc( J5a  w1N Z  * {" '0LL \{" uY Y@B" 9 j# 5a }] Y0 0" O<. .V  (!;pEN A&з " ) PV ѷ|E` " " ( !"D jS00" i! " gR )T1" /WT i!( P %طN#! OM$" `8Pd  u>T   !:k " [d uX i >GpZ" a 4 ~#`FP 9Q) &ȷ > " jp`" [ }7 `>b ː0! j] `n"  X^! `/ u%p }V! n@s)" At փ " R." ie "A " 7cB ˘ ! " sG C &ķ!.80d )O> 3zpq ( @" I[" #FT p!" '! 2 [ E0 8d ca" m1P`" ]i o@` J!" v\ ?v_ z6b 6lˇ" 0" P-U  S@  `n" G\6h I`" 6@1! Z#! ?t " {~{  ` -V  p=0 J 0Y  .q !0 !;\ 0! |+S X[2 0Z  ip!bp * ~H# d ! " k@9M y0l/ ,+R $ 3@]R D !r4_ IH`" bqs" G" .l0, DP .* W K@ g:j g0R dH H>r 3]C 8$ eN }z 5:m O1P`" ;0I=q+ ap * >Ԧ ! Xy R@  vD!M " $" if =` 0N  0" ` N!P@I L l0, ,C` e" c&̷m" aW- " c} !I" qPX" " \PJQ"  3O 96bJ 5! o_ *x!dj __gmon_start___fini_ITM_deregisterTMCloneTable_ITM_registerTMCloneTable__cxa_finalize_Jv_RegisterClasses_ZNKSt5ctypeIcE8do_widenEc_ZN7testing8internal26ThreadLocalValueHolderBaseD2Ev_ZN7testing8internal26ThreadLocalValueHolderBaseD1EvDeleteThreadLocalValue_ZN7testing4Test11DeleteSelf_Ev_ZN7testing4Test5SetupEv_ZN7testing8TestCase16RunSetUpTestCaseEv_ZN7testing8TestCase19RunTearDownTestCaseEv_ZN7testing11EnvironmentD2Ev_ZN7testing11EnvironmentD1Ev_ZN7testing11Environment5SetUpEv_ZN7testing11Environment8TearDownEv_ZN7testing11Environment5SetupEv_ZN7testing22EmptyTestEventListener18OnTestProgramStartERKNS_8UnitTestE_ZN7testing22EmptyTestEventListener20OnTestIterationStartERKNS_8UnitTestEi_ZN7testing22EmptyTestEventListener24OnEnvironmentsSetUpStartERKNS_8UnitTestE_ZN7testing22EmptyTestEventListener22OnEnvironmentsSetUpEndERKNS_8UnitTestE_ZN7testing22EmptyTestEventListener15OnTestCaseStartERKNS_8TestCaseE_ZN7testing22EmptyTestEventListener11OnTestStartERKNS_8TestInfoE_ZN7testing22EmptyTestEventListener16OnTestPartResultERKNS_14TestPartResultE_ZN7testing22EmptyTestEventListener9OnTestEndERKNS_8TestInfoE_ZN7testing22EmptyTestEventListener13OnTestCaseEndERKNS_8TestCaseE_ZN7testing22EmptyTestEventListener27OnEnvironmentsTearDownStartERKNS_8UnitTestE_ZN7testing22EmptyTestEventListener25OnEnvironmentsTearDownEndERKNS_8UnitTestE_ZN7testing22EmptyTestEventListener18OnTestIterationEndERKNS_8UnitTestEi_ZN7testing22EmptyTestEventListener16OnTestProgramEndERKNS_8UnitTestE_ZN7testing8internal17StreamingListener20AbstractSocketWriter15CloseConnectionEv_ZN7testing22EmptyTestEventListenerD2Ev_ZN7testing22EmptyTestEventListenerD1Ev_ZN7testing4Test5SetUpEv_ZN7testing4Test8TearDownEv_ZNK7testing8TestCase30reportable_disabled_test_countEv_ZNK7testing8TestCase19disabled_test_countEv_ZNK7testing8TestCase21reportable_test_countEv_ZNK7testing8TestCase17test_to_run_countEv_ZNK7testing8TestCase16total_test_countEv_ZN7testing8internal27PrettyUnitTestResultPrinter18OnTestProgramStartERKNS_8UnitTestE_ZN7testing8internal27PrettyUnitTestResultPrinter22OnEnvironmentsSetUpEndERKNS_8UnitTestE_ZN7testing8internal27PrettyUnitTestResultPrinter25OnEnvironmentsTearDownEndERKNS_8UnitTestE_ZN7testing8internal27PrettyUnitTestResultPrinter16OnTestProgramEndERKNS_8UnitTestE_ZN7testing8internal18OsStackTraceGetter16UponLeavingGTestEv_ZN7testing8internal24HasNewFatalFailureHelper20ReportTestPartResultERKNS_14TestPartResultE_ZN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE11ValueHolderD2Ev_ZN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE11ValueHolderD1Ev_ZN7testing8internal23DefaultDeathTestFactoryD2Ev_ZN7testing8internal23DefaultDeathTestFactoryD1Ev_ZN7testing8internal27PrettyUnitTestResultPrinterD2Ev_ZN7testing8internal27PrettyUnitTestResultPrinterD1Ev_ZN7testing8internal38DefaultPerThreadTestPartResultReporterD2Ev_ZN7testing8internal38DefaultPerThreadTestPartResultReporterD1Ev_ZN7testing8internal35DefaultGlobalTestPartResultReporterD2Ev_ZN7testing8internal35DefaultGlobalTestPartResultReporterD1Ev_ZN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE11ValueHolderD0Ev_ZdlPv_ZN7testing8internal26ThreadLocalValueHolderBaseD0Ev_ZN7testing11EnvironmentD0Ev_ZN7testing8internal23DefaultDeathTestFactoryD0Ev_ZN7testing8internal38DefaultPerThreadTestPartResultReporterD0Ev_ZN7testing8internal35DefaultGlobalTestPartResultReporterD0Ev_ZN7testing8internal27PrettyUnitTestResultPrinterD0Ev_ZN7testing22EmptyTestEventListenerD0Ev_ZN7testing8internal17TestEventRepeaterD2Ev_ZTVN7testing8internal17TestEventRepeaterE_Unwind_Resume__gxx_personality_v0_ZN7testing8internal17TestEventRepeaterD1Ev_ZN7testing8internal17TestEventRepeaterD0Ev_ZN7testing8internal18OsStackTraceGetter17CurrentStackTraceEii_ZNSsC1EPKcRKSaIcE_ZN7testing8internal26GoogleTestFailureExceptionD2Ev_ZTVN7testing8internal26GoogleTestFailureExceptionE_ZNSt13runtime_errorD2Ev_ZN7testing8internal26GoogleTestFailureExceptionD1Ev_ZN7testing8internal26GoogleTestFailureExceptionD0Ev_ZN7testing8internal17TestEventRepeater18OnTestProgramStartERKNS_8UnitTestE_ZN7testing8internal17TestEventRepeater24OnEnvironmentsSetUpStartERKNS_8UnitTestE_ZN7testing8internal17TestEventRepeater15OnTestCaseStartERKNS_8TestCaseE_ZN7testing8internal17TestEventRepeater11OnTestStartERKNS_8TestInfoE_ZN7testing8internal17TestEventRepeater16OnTestPartResultERKNS_14TestPartResultE_ZN7testing8internal17TestEventRepeater27OnEnvironmentsTearDownStartERKNS_8UnitTestE_ZN7testing8internal17TestEventRepeater22OnEnvironmentsSetUpEndERKNS_8UnitTestE_ZN7testing8internal17TestEventRepeater25OnEnvironmentsTearDownEndERKNS_8UnitTestE_ZN7testing8internal17TestEventRepeater9OnTestEndERKNS_8TestInfoE_ZN7testing8internal17TestEventRepeater13OnTestCaseEndERKNS_8TestCaseE_ZN7testing8internal17TestEventRepeater16OnTestProgramEndERKNS_8UnitTestE_ZN7testing8internal17TestEventRepeater20OnTestIterationStartERKNS_8UnitTestEi_ZN7testing8internal17TestEventRepeater18OnTestIterationEndERKNS_8UnitTestEiputchar_ZNSs4_Rep10_M_destroyERKSaIcE_ZN7testing8internal24XmlUnitTestResultPrinterD0Ev_ZTVN7testing8internal24XmlUnitTestResultPrinterE_ZNSs4_Rep20_S_empty_rep_storageE_ZN7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEE11ValueHolderD2Ev_ZTVN7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEE11ValueHolderE_ZN7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEE11ValueHolderD1Ev_ZN7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEE11ValueHolderD0Ev_ZNSt6vectorISsSaISsEED2Ev_ZNSt6vectorISsSaISsEED1Ev_ZNKSs4findEcj_ZNSs6appendEPKcj_ZNSsC1ERKSsjj_ZNSs6appendERKSs_ZSt24__throw_out_of_range_fmtPKczsnprintfstrlen_ZSt16__ostream_insertIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_PKS3_i_ZN7testing8internal24XmlUnitTestResultPrinterD2Ev_ZN7testing8internal24XmlUnitTestResultPrinterD1Ev_ZN7testing8internal29ParameterizedTestCaseRegistryD2Ev_ZN7testing8internal29ParameterizedTestCaseRegistryD1Ev_ZN7testing8internal12AssertHelperC2ENS_14TestPartResult4TypeEPKciS5__Znwj_ZN7testing8internal12AssertHelperC1ENS_14TestPartResult4TypeEPKciS5__ZN7testing8internal12AssertHelperD2Ev_ZN7testing8internal12AssertHelperD1Ev_ZN7testing8internal15UnitTestOptions15GetOutputFormatEv_ZN7testing18FLAGS_gtest_outputEstrchr_ZNSsC1EPKcjRKSaIcE_ZN7testing8internal15UnitTestOptions20PatternMatchesStringEPKcS3__ZN7testing8internal15UnitTestOptions13MatchesFilterERKSsPKc_ZN7testing8internal13GetTestTypeIdEv_ZN7testing8internal12TypeIdHelperINS_4TestEE6dummy_E_ZN7testing8internal20SingleFailureCheckerC2EPKNS_19TestPartResultArrayENS_14TestPartResult4TypeERKSs_ZNSsC1ERKSs_ZN7testing8internal20SingleFailureCheckerC1EPKNS_19TestPartResultArrayENS_14TestPartResult4TypeERKSs_ZN7testing8internal35DefaultGlobalTestPartResultReporterC2EPNS0_12UnitTestImplE_ZTVN7testing8internal35DefaultGlobalTestPartResultReporterE_ZN7testing8internal35DefaultGlobalTestPartResultReporterC1EPNS0_12UnitTestImplE_ZN7testing8internal38DefaultPerThreadTestPartResultReporterC2EPNS0_12UnitTestImplE_ZTVN7testing8internal38DefaultPerThreadTestPartResultReporterE_ZN7testing8internal38DefaultPerThreadTestPartResultReporterC1EPNS0_12UnitTestImplE_ZNK7testing8internal12UnitTestImpl21total_test_case_countEv_ZNK7testing8internal12UnitTestImpl22test_case_to_run_countEv_ZNK7testing8internal12UnitTestImpl21successful_test_countEv_ZNK7testing8TestCase21successful_test_countEv_ZNK7testing8internal12UnitTestImpl17failed_test_countEv_ZNK7testing8TestCase17failed_test_countEv_ZNK7testing8internal12UnitTestImpl30reportable_disabled_test_countEv_ZNK7testing8internal12UnitTestImpl19disabled_test_countEv_ZNK7testing8internal12UnitTestImpl21reportable_test_countEv_ZNK7testing8internal12UnitTestImpl16total_test_countEv_ZNK7testing8internal12UnitTestImpl17test_to_run_countEv_ZN7testing8internal12UnitTestImpl28CurrentOsStackTraceExceptTopEi_ZN7testing8internal15GetTimeInMillisEvgettimeofday_ZN7testing8internal6String13CStringEqualsEPKcS3_strcmp_ZN7testing15AssertionResultC2ERKS0__ZN7testing15AssertionResultC1ERKS0__ZN7testing16AssertionSuccessEv_ZN7testing16AssertionFailureEv_ZN7testing8internal6String17WideCStringEqualsEPKwS3_wcscmp_ZN7testing8internal6String28CaseInsensitiveCStringEqualsEPKcS3_strcasecmp_ZN7testing8internal6String32CaseInsensitiveWideCStringEqualsEPKwS3_wcscasecmp_ZN7testing8internal6String23EndsWithCaseInsensitiveERKSsS3__ZN7testing8internal20StringStreamToStringEPSt18basic_stringstreamIcSt11char_traitsIcESaIcEE_ZNKSt15basic_stringbufIcSt11char_traitsIcESaIcEE3strEv_ZNSs7reserveEj_ZNK7testing7Message9GetStringEv_ZN7testing10TestResult20ClearTestPartResultsEv_ZN7testing10TestResult5ClearEv_ZNK7testing10TestResult15HasFatalFailureEv_ZNK7testing10TestResult18HasNonfatalFailureEv_ZNK7testing10TestResult16total_part_countEv_ZNK7testing10TestResult17GetTestPartResultEi_ZNK7testing10TestResult6FailedEv_ZNK7testing8internal12UnitTestImpl26successful_test_case_countEv_ZNK7testing8internal12UnitTestImpl22failed_test_case_countEv_ZNK7testing10TestResult19test_property_countEv_ZNK7testing10TestResult15GetTestPropertyEi_ZN7testing4TestC2Ev_ZTVN7testing4TestE_ZN7testing35FLAGS_gtest_also_run_disabled_testsE_ZN7testing28FLAGS_gtest_break_on_failureE_ZN7testing28FLAGS_gtest_catch_exceptionsE_ZN7testing17FLAGS_gtest_colorE_ZNSs6assignERKSs_ZN7testing28FLAGS_gtest_death_test_styleE_ZN7testing31FLAGS_gtest_death_test_use_forkE_ZN7testing18FLAGS_gtest_filterE_ZN7testing8internal35FLAGS_gtest_internal_run_death_testE_ZN7testing22FLAGS_gtest_list_testsE_ZN7testing22FLAGS_gtest_print_timeE_ZN7testing23FLAGS_gtest_random_seedE_ZN7testing18FLAGS_gtest_repeatE_ZN7testing19FLAGS_gtest_shuffleE_ZN7testing29FLAGS_gtest_stack_trace_depthE_ZN7testing28FLAGS_gtest_stream_result_toE_ZN7testing28FLAGS_gtest_throw_on_failureE_ZN7testing4TestC1Ev_ZN7testing4TestD2Ev_ZN7testing4TestD1Ev_ZN7testing4TestD0Ev_ZN7testing8internal12UnitTestImpl26RegisterParameterizedTestsEv_ZNK7testing8TestCase11GetTestInfoEi_ZN7testing8TestCase18GetMutableTestInfoEi_ZN7testing8TestCase11ClearResultEv_ZN7testing8TestCase14UnshuffleTestsEv_ZN7testing8internal16GetAnsiColorCodeENS0_10GTestColorE_ZN7testing8internal14ShouldUseColorEbgetenv_ZN7testing8internal13ColoredPrintfENS0_10GTestColorEPKczstdoutvfprintf__cxa_guard_acquirefilenoisatty__cxa_guard_release__cxa_guard_abort_ZN7testing8internal27PrettyUnitTestResultPrinter24OnEnvironmentsSetUpStartERKNS_8UnitTestEfflush_ZN7testing8internal27PrettyUnitTestResultPrinter27OnEnvironmentsTearDownStartERKNS_8UnitTestE_ZN7testing8internal27PrettyUnitTestResultPrinter11OnTestStartERKNS_8TestInfoE_ZN7testing8internal29PrintFullTestCommentIfPresentERKNS_8TestInfoE_ZN7testing8internal17TestEventRepeater7ReleaseEPNS_17TestEventListenerEmemmove_ZN7testing8internal24XmlUnitTestResultPrinterC2EPKcstderrfwrite_ZN7testing8internal24XmlUnitTestResultPrinterC1EPKc_ZN7testing8internal24XmlUnitTestResultPrinter26RemoveInvalidXmlCharactersERKSs_ZN7testing8internal24XmlUnitTestResultPrinter21OutputXmlCDataSectionEPSoPKc_ZNSo5writeEPKcistrstr_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc_ZN7testing18TestEventListenersC2Ev_ZN7testing18TestEventListenersC1Ev_ZN7testing18TestEventListenersD2Ev_ZN7testing18TestEventListenersD1Ev_ZN7testing18TestEventListeners7ReleaseEPNS_17TestEventListenerE_ZN7testing18TestEventListeners8repeaterEv_ZNK7testing18TestEventListeners22EventForwardingEnabledEv_ZN7testing18TestEventListeners23SuppressEventForwardingEv_ZNK7testing8UnitTest26successful_test_case_countEv_ZNK7testing8UnitTest22failed_test_case_countEv_ZNK7testing8UnitTest21total_test_case_countEv_ZNK7testing8UnitTest22test_case_to_run_countEv_ZNK7testing8UnitTest21successful_test_countEv_ZNK7testing8UnitTest17failed_test_countEv_ZNK7testing8UnitTest30reportable_disabled_test_countEv_ZNK7testing8UnitTest19disabled_test_countEv_ZNK7testing8UnitTest21reportable_test_countEv_ZNK7testing8UnitTest16total_test_countEv_ZNK7testing8UnitTest17test_to_run_countEv_ZNK7testing8UnitTest15start_timestampEv_ZNK7testing8UnitTest12elapsed_timeEv_ZNK7testing8UnitTest6PassedEv_ZNK7testing8UnitTest6FailedEv_ZNK7testing8UnitTest11GetTestCaseEi_ZN7testing8internal27PrettyUnitTestResultPrinter16PrintFailedTestsERKNS_8UnitTestE_ZNK7testing8UnitTest18ad_hoc_test_resultEv_ZN7testing8UnitTest18GetMutableTestCaseEi_ZN7testing8UnitTest9listenersEv_ZN7testing14TestPartResultD2Ev_ZN7testing14TestPartResultD1Ev_ZN7testing12TestPropertyD2Ev_ZN7testing12TestPropertyD1Ev_ZNK7testing8UnitTest20original_working_dirEv_ZNK7testing8UnitTest11random_seedEv_ZN7testing8UnitTest27parameterized_test_registryEv_ZN7testing8internal12UnitTestImpl32SuppressTestEventsIfInSubprocessEv_ZN7testing8internal30WriteToShardStatusFileIfNeededEvfopenfclose_ZN7testing8internal20ShouldRunTestOnShardEiii_ZN7testing8internal12UnitTestImpl23ListTestsMatchingFilterEv_ZN7testing8internal12UnitTestImpl25set_os_stack_trace_getterEPNS0_27OsStackTraceGetterInterfaceE_ZN7testing8internal12UnitTestImpl19current_test_resultEv_ZN7testing8internal12UnitTestImpl14UnshuffleTestsEv_ZN7testing8internal6IsTrueEb_ZN7testing8internal10AlwaysTrueEv__cxa_allocate_exception__cxa_throw_ZN7testing8internal10SkipPrefixEPKcPS2_strncmp_ZN7testing8internal14ParseFlagValueEPKcS2_b_ZN7testing8internal13ParseBoolFlagEPKcS2_Pb_ZN7testing8internal15ParseStringFlagEPKcS2_PSs_ZNSs6assignEPKcj_ZN7testing8internal16InDeathTestChildEv_ZNKSs7compareEPKc_ZN7testing14ExitedWithCodeC2Ei_ZN7testing14ExitedWithCodeC1Ei_ZNK7testing14ExitedWithCodeclEi_ZN7testing14KilledBySignalC2Ei_ZN7testing14KilledBySignalC1Ei_ZNK7testing14KilledBySignalclEi_ZN7testing8internal20ExitedUnsuccessfullyEi_ZN7testing8internal23GetLastErrnoDescriptionEv__errno_location_ZN7testing8internal9DeathTest11LastMessageEv_ZN7testing8internal9DeathTest24last_death_test_message_E_ZN7testing8internal9DeathTest27set_last_death_test_messageERKSs_ZN7testing8internal21StackLowerThanAddressEPKvPb_ZN7testing8internal14StackGrowsDownEv_ZNK7testing8internal8FilePath21FindLastPathSeparatorEvstrrchr_ZNK7testing8internal8FilePath21FileOrDirectoryExistsEv__xstat_ZNK7testing8internal8FilePath15DirectoryExistsEv_ZNK7testing8internal8FilePath15IsRootDirectoryEv_ZNK7testing8internal8FilePath14IsAbsolutePathEv_ZNK7testing8internal8FilePath11IsDirectoryEv_ZNK7testing8internal8FilePath12CreateFolderEvmkdir_ZN7testing8internal8FilePath9NormalizeEv_Znajmemset_ZdaPv_ZN7testing8internal8FilePath13GetCurrentDirEvgetcwd_ZNK7testing8internal8FilePath19RemoveDirectoryNameEv_ZN7testing8internal24GetCurrentExecutableNameEv_ZN7testing8internal17g_executable_pathE_ZNK7testing8internal8FilePath14RemoveFileNameEv_ZNK7testing8internal8FilePath27RemoveTrailingPathSeparatorEv_ZNK7testing8internal8FilePath28CreateDirectoriesRecursivelyEv_ZNK7testing8internal8FilePath15RemoveExtensionEPKc_ZN7testing8internal14GetThreadCountEv_ZN7testing8internal2RED2Evregfree_ZN7testing8internal2RED1Ev_ZN7testing8internal2RE9FullMatchEPKcRKS1_regexec_ZN7testing8internal2RE12PartialMatchEPKcRKS1__ZN7testing8internal8GTestLogD2Ev_ZSt4cerr_ZNSo3putEc_ZNSo5flushEv_ZNKSt5ctypeIcE13_M_widen_initEv_ZSt16__throw_bad_castv_ZN7testing8internal8GTestLogD1Ev_ZN7testing8internal14CapturedStream11GetFileSizeEP8_IO_FILEfseekftell_ZN7testing8internal14CapturedStream14ReadEntireFileEP8_IO_FILEfread_ZN7testing8internal17GetCapturedStreamEPPNS0_14CapturedStreamEdup2remove_ZN7testing8internal17GetCapturedStdoutEv_ZN7testing8internal17GetCapturedStderrEv_ZN7testing8internal18SetInjectableArgvsEPKSt6vectorISsSaISsEE_ZN7testing8internal18GetInjectableArgvsEv_ZN7testing8internal7g_argvsE_ZN7testing9internal220PrintBytesInObjectToEPKhjPSo_ZNSo9_M_insertImEERSoT__ZN7testinglsERSoRKNS_14TestPartResultE_ZNSolsEi_ZNSt9basic_iosIcSt11char_traitsIcEE5clearESt12_Ios_Iostate_ZNK7testing19TestPartResultArray4sizeEv_ZNK7testing19TestPartResultArray17GetTestPartResultEi_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEED2Ev_ZTVSt15basic_stringbufIcSt11char_traitsIcESaIcEE_ZTVSt15basic_streambufIcSt11char_traitsIcEE_ZNSt6localeD1Ev_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEED1Ev_ZN7testing7MessageC2Ev_ZNSt8ios_baseC2Ev_ZTVSt9basic_iosIcSt11char_traitsIcEE_ZTTSt18basic_stringstreamIcSt11char_traitsIcESaIcEE_ZNSt9basic_iosIcSt11char_traitsIcEE4initEPSt15basic_streambufIcS1_E_ZTVSt18basic_stringstreamIcSt11char_traitsIcESaIcEE_ZNSt6localeC1Ev_ZNSt8ios_baseD2Ev_ZNSdD2Ev_ZN7testing7MessageC1Ev_ZN7testing8internal6String12FormatHexIntEi_ZNSt18basic_stringstreamIcSt11char_traitsIcESaIcEED1Ev_ZN7testing8internal27FormatTimeInMillisAsSecondsEx_ZNSo9_M_insertIdEERSoT__ZN7testing8internal6String15FormatIntWidth2Ei_ZN7testing8internal6String10FormatByteEh_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEED0Ev_ZN7testing8internal10scoped_ptrISsE5resetEPSs_ZN7testing15AssertionResult13AppendMessageERKNS_7MessageE_ZN7testing8internal10scoped_ptrINS0_24InternalRunDeathTestFlagEE5resetEPS2__ZStplIcSt11char_traitsIcESaIcEESbIT_T0_T1_ERKS6_PKS3__ZStplIcSt11char_traitsIcESaIcEESbIT_T0_T1_EPKS3_RKS6__ZN7testing8internal15CodePointToUtf8Ej_ZN7testing8internal16WideStringToUtf8EPKwi_ZNSt18basic_stringstreamIcSt11char_traitsIcESaIcEEC1ESt13_Ios_Openmodewcslen_ZN7testing7MessagelsERKSbIwSt11char_traitsIwESaIwEE_ZN7testing8internal6String15ShowWideCStringEPKw_ZN7testing7MessagelsEPKw_ZN7testing7MessagelsEPwisxdigit_ZN7testing8internal19UniversalPrintArrayEPKcjPSo_ZN7testing8internal7PrintToEPKcPSo_ZNSo9_M_insertIPKvEERSoT__ZN7testing8internal13PrintStringToERKSsPSo_ZN7testing13PrintToStringIPKcEESsRKT__ZN7testing8internal19UniversalPrintArrayEPKwjPSo_ZN7testing8internal7PrintToEPKwPSo_ZN7testing8internal17PrintWideStringToERKSbIwSt11char_traitsIwESaIwEEPSo_ZN7testing13PrintToStringIPKwEESsRKT__ZNSbIwSt11char_traitsIwESaIwEEC1EPKwRKS1__ZNSbIwSt11char_traitsIwESaIwEE4_Rep20_S_empty_rep_storageE_ZNSbIwSt11char_traitsIwESaIwEE4_Rep10_M_destroyERKS1__ZN7testing8internal17StreamingListener9UrlEncodeEPKc_ZStplIcSt11char_traitsIcESaIcEESbIT_T0_T1_ERKS6_S8__ZN7testing8internal8FilePath11ConcatPathsERKS1_S3__ZNSs6appendEjc_ZN7testing8internal17AppendUserMessageERKSsRKNS_7MessageE_ZN7testing8internal18PrintCharAndCodeToIhhEEvT0_PSo_ZN7testing8internal7PrintToEhPSo_ZN7testing8internal18PrintCharAndCodeToIhaEEvT0_PSo_ZN7testing8internal7PrintToEaPSo_ZN7testing8internal18PrintCharAndCodeToIwwEEvT0_PSo_ZN7testing8internal7PrintToEwPSo_ZN7testing8internal10scoped_ptrISt18basic_stringstreamIcSt11char_traitsIcESaIcEEE5resetEPS6__ZN7testing15AssertionResultlsIA2_cEERS0_RKT__ZN7testing15AssertionResultlsISsEERS0_RKT__ZN7testing15AssertionResultlsIA11_cEERS0_RKT__ZN7testing15AssertionResultlsINS_14TestPartResultEEERS0_RKT__ZN7testing8internal13HasOneFailureEPKcS2_S2_RKNS_19TestPartResultArrayENS_14TestPartResult4TypeERKSs_ZN7testing15AssertionResultlsIPKcEERS0_RKT__ZN7testing8internal18StreamableToStringIiEESsRKT__ZN7testing8internal27PrettyUnitTestResultPrinter15OnTestCaseStartERKNS_8TestCaseE__divdi3_ZN7testing8internal32FormatEpochTimeInMillisAsIso8601Exlocaltime_ZN7testing8internal8FilePath12MakeFileNameERKS1_S3_iPKc_ZN7testing8internal8FilePath22GenerateUniqueFileNameERKS1_S3_PKc_ZN7testing8internal18FormatFileLocationEPKci_ZN7testing8internal8GTestLogC2ENS0_16GTestLogSeverityEPKci_ZN7testing8internal8GTestLogC1ENS0_16GTestLogSeverityEPKci_ZN7testing8internal6Random8GenerateEj_ZN7testing8internal17StreamingListener12SocketWriter4SendERKSs_ZN7testing8internal9MutexBase4LockEvpthread_mutex_lockpthread_self_ZN7testing8internal9MutexBase6UnlockEvpthread_mutex_unlock_ZN7testing8internal5MutexD2Evpthread_mutex_destroy_ZN7testing8internal5MutexD1Ev_ZN7testing8internal12ShuffleRangeIiEEvPNS0_6RandomEiiPSt6vectorIT_SaIS5_EE_ZN7testing8TestCase12ShuffleTestsEPNS_8internal6RandomE_ZN7testing8internal12UnitTestImpl12ShuffleTestsEv_ZN7testing8internal17StreamingListener12SocketWriter15CloseConnectionEv_ZN7testing8internal17StreamingListener12SocketWriter14MakeConnectionEvgetaddrinfosocketconnectfreeaddrinfogai_strerror_ZN7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEED2Evpthread_getspecificpthread_key_delete_ZN7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEED1Ev_ZN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEED2Ev_ZN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEED1Ev_ZN7testing8internal18ParseNaturalNumberIiEEbRKSsPT_strtoull_ZN7testing8internal13CaptureStreamEiPKcPPNS0_14CapturedStreamEmkstemp_ZN7testing8internal13CaptureStdoutEv_ZN7testing8internal13CaptureStderrEv_ZN7testing8internal17StreamingListener12SocketWriterD2Ev_ZTVN7testing8internal17StreamingListener12SocketWriterE_ZN7testing8internal17StreamingListener12SocketWriterD1Ev_ZN7testing8internal17StreamingListener12SocketWriterD0Ev_ZN7testing10TestResultC2Evpthread_mutex_init_ZN7testing10TestResultC1Ev_ZN7testing8internal18OsStackTraceGetterD2Ev_ZTVN7testing8internal18OsStackTraceGetterE_ZN7testing8internal18OsStackTraceGetterD1Ev_ZN7testing8internal18OsStackTraceGetterD0Ev_ZN7testing8internal17StreamingListenerD2Ev_ZTVN7testing8internal17StreamingListenerE_ZN7testing8internal17StreamingListenerD1Ev_ZN7testing8internal12UnitTestImpl21os_stack_trace_getterEv_ZN7testing8internal17StreamingListener20AbstractSocketWriter6SendLnERKSs_ZN7testing8internal17StreamingListener15OnTestCaseStartERKNS_8TestCaseE_ZN7testing8internal17StreamingListener16OnTestProgramEndERKNS_8UnitTestE_ZN7testing8internal17StreamingListener16OnTestPartResultERKNS_14TestPartResultE_ZN7testing8internal17StreamingListenerD0Ev_ZN7testing8internal12UnitTestImpl31SetGlobalTestPartResultReporterEPNS_31TestPartResultReporterInterfaceE_ZN7testing8internal12UnitTestImpl31GetGlobalTestPartResultReporterEv_ZN7testing8internal38DefaultPerThreadTestPartResultReporter20ReportTestPartResultERKNS_14TestPartResultE_ZNK7testing8UnitTest17current_test_infoEv_ZNK7testing8UnitTest17current_test_caseEv_ZN7testing10TestResultD2Ev_ZN7testing10TestResultD1Ev_ZN7testing8internal17StreamingListener18OnTestProgramStartERKNS_8UnitTestE_ZN7testing8internal17StreamingListener20OnTestIterationStartERKNS_8UnitTestEi_ZN7testing8internal17StreamingListener11OnTestStartERKNS_8TestInfoE_ZN7testing8internal37FormatCompilerIndependentFileLocationEPKci_ZN7testing8internal30GetBoolAssertionFailureMessageERKNS_15AssertionResultEPKcS5_S5__ZN7testing8internal26GoogleTestFailureExceptionC2ERKNS_14TestPartResultE_ZNSt13runtime_errorC2ERKSs_ZN7testing8internal26GoogleTestFailureExceptionC1ERKNS_14TestPartResultE_ZN7testing8internal27PrettyUnitTestResultPrinter16OnTestPartResultERKNS_14TestPartResultE_ZN7testing8internal25ReportInvalidTestCaseTypeEPKcS2_i_ZN7testing8internal18StreamableToStringIxEESsRKT__ZNSo9_M_insertIxEERSoT__ZN7testing8internal17StreamingListener9OnTestEndERKNS_8TestInfoE_ZN7testing8internal17StreamingListener13OnTestCaseEndERKNS_8TestCaseE_ZN7testing8internal27PrettyUnitTestResultPrinter9OnTestEndERKNS_8TestInfoE_ZN7testing8internal27PrettyUnitTestResultPrinter13OnTestCaseEndERKNS_8TestCaseE_ZN7testing8internal27PrettyUnitTestResultPrinter18OnTestIterationEndERKNS_8UnitTestEi_ZN7testing8internal17StreamingListener18OnTestIterationEndERKNS_8UnitTestEi_ZN7testing8internal24XmlUnitTestResultPrinter9EscapeXmlERKSsb_ZN7testing8internal24XmlUnitTestResultPrinter29TestPropertiesAsXmlAttributesERKNS_10TestResultE_ZN7testing7MessageC2ERKS0__ZN7testing7MessageC1ERKS0__ZN7testing8internal13DeathTestImpl6PassedEb_ZN7testing8internal10ParseInt32ERKNS_7MessageEPKcPistrtol_ZN7testing8internal17Int32FromEnvOrDieEPKci_ZN7testing8internal11ShouldShardEPKcS2_b_ZN7testing8internal27PrettyUnitTestResultPrinter20OnTestIterationStartERKNS_8UnitTestEi_ZN7testing8internal14ParseInt32FlagEPKcS2_Pitoupper_ZN7testing8internal16BoolFromGTestEnvEPKcb_ZN7testing8internal18StringFromGTestEnvEPKcS2__ZN7testing8internal17Int32FromGTestEnvEPKci_ZN7testing16AssertionFailureERKNS_7MessageE_ZN7testing8internal9EqFailureEPKcS2_RKSsS4_b_ZN7testing8internal14CmpHelperSTREQEPKcS2_S2_S2__ZN7testing8internal18CmpHelperSTRCASEEQEPKcS2_S2_S2__ZN7testing8internal14CmpHelperSTREQEPKcS2_PKwS4__ZNK7testing15AssertionResultntEv_ZN7testing8internal20DoubleNearPredFormatEPKcS2_S2_ddd_ZN7testing8internal15FloatingPointLEIdEENS_15AssertionResultEPKcS4_T_S5__ZN7testing8DoubleLEEPKcS1_dd_ZN7testing8internal14CmpHelperSTRNEEPKcS2_PKwS4__ZN7testing8internal14CmpHelperSTRNEEPKcS2_S2_S2__ZN7testing8internal18CmpHelperSTRCASENEEPKcS2_S2_S2__ZN7testing11IsSubstringEPKcS1_S1_S1__ZN7testing14IsNotSubstringEPKcS1_S1_S1__ZNKSs4findEPKcjj_ZN7testing11IsSubstringEPKcS1_RKSsS3__ZN7testing14IsNotSubstringEPKcS1_RKSsS3__ZN7testing8internal15FloatingPointLEIfEENS_15AssertionResultEPKcS4_T_S5__ZN7testing7FloatLEEPKcS1_ff_ZNKSbIwSt11char_traitsIwESaIwEE4findEPKwjj_ZN7testing11IsSubstringEPKcS1_RKSbIwSt11char_traitsIwESaIwEES7__ZN7testing14IsNotSubstringEPKcS1_RKSbIwSt11char_traitsIwESaIwEES7_wcsstr_ZN7testing11IsSubstringEPKcS1_PKwS3__ZN7testing14IsNotSubstringEPKcS1_PKwS3__ZN7testing8internal10scoped_ptrINS0_17StreamingListener20AbstractSocketWriterEE5resetEPS3__ZNSt6vectorIN7testing12TestPropertyESaIS1_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS1_S3_EERKS1___cxa_begin_catch__cxa_rethrow__cxa_end_catch_ZN7testing8internal10scoped_ptrIKSsE5resetEPS2__ZN7testing8TestInfoC2ERKSsS2_PKcS4_PKvPNS_8internal15TestFactoryBaseE_ZN7testing8TestInfoC1ERKSsS2_PKcS4_PKvPNS_8internal15TestFactoryBaseE_ZN7testing8TestCaseC2EPKcS2_PFvvES4__ZTVN7testing8TestCaseE_ZN7testing8TestCaseC1EPKcS2_PFvvES4__ZN7testing8TestInfoD2Ev_ZN7testing8TestInfoD1Ev_ZN7testing8TestCaseD2Ev_ZN7testing8TestCaseD1Ev_ZN7testing8TestCaseD0Ev_ZNSt6vectorIPN7testing8TestInfoESaIS2_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS2_S4_EERKS2__ZNSt6vectorIiSaIiEE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPiS1_EERKi_ZN7testing8TestCase11AddTestInfoEPNS_8TestInfoE_ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS2_S4_EERKS2__ZN7testing8internal17TestEventRepeater6AppendEPNS_17TestEventListenerE_ZN7testing18TestEventListeners6AppendEPNS_17TestEventListenerE_ZN7testing18TestEventListeners23SetDefaultResultPrinterEPNS_17TestEventListenerE_ZN7testing18TestEventListeners22SetDefaultXmlGeneratorEPNS_17TestEventListenerE_ZN7testing8internal12UnitTestImpl24ConfigureStreamingOutputEv_ZNSt6vectorIPN7testing11EnvironmentESaIS2_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS2_S4_EERKS2__ZN7testing8UnitTest14AddEnvironmentEPNS_11EnvironmentE_ZN7testing8internal10scoped_ptrINS0_16DeathTestFactoryEE5resetEPS2__ZN7testing8internal12UnitTestImplD2Ev_ZTVN7testing8internal12UnitTestImplE_ZN7testing8internal12UnitTestImplD1Ev_ZN7testing8internal12UnitTestImplD0Ev_ZN7testing8UnitTestD2Ev_ZTVN7testing8UnitTestE_ZN7testing8UnitTestD1Ev_ZN7testing8UnitTestD0Ev_ZN7testing8internal12UnitTestImplC2EPNS_8UnitTestE_ZTVN7testing8internal23DefaultDeathTestFactoryE_ZTVN7testing8internal27PrettyUnitTestResultPrinterE_ZN7testing8internal12UnitTestImplC1EPNS_8UnitTestE_ZN7testing8UnitTestC2Ev_ZN7testing8UnitTestC1Ev_ZN7testing8UnitTest11GetInstanceEv__cxa_atexit_ZN7testing8internal15UnitTestOptions27GetAbsolutePathToOutputFileEv_ZN7testing8internal12UnitTestImpl18ConfigureXmlOutputEv_ZN7testing4Test15HasFatalFailureEv_ZN7testing4Test18HasNonfatalFailureEv_ZN7testing8internal31GetCurrentOsStackTraceExceptTopEPNS_8UnitTestEi_ZN7testing8internal14DeathTestAbortERKSsfdopenfputcfputs_exit_ZN7testing8internal13DeathTestImpl26ReadAndInterpretStatusByteEv_ZN7testing8internal13DeathTestImpl5AbortENS0_9DeathTest11AbortReasonE_ZN7testing8internal16ForkingDeathTest4WaitEvwaitpid_ZN7testing8internal13DeathTestImplD2Ev_ZTVN7testing8internal13DeathTestImplE_ZN7testing8internal13DeathTestImplD1Ev_ZN7testing8internal13DeathTestImplD0Ev_ZN7testing8internal13ExecDeathTestD2Ev_ZTVN7testing8internal16ForkingDeathTestE_ZN7testing8internal13ExecDeathTestD1Ev_ZN7testing8internal13ExecDeathTestD0Ev_ZN7testing8internal15NoExecDeathTestD2Ev_ZN7testing8internal15NoExecDeathTestD1Ev_ZN7testing8internal15NoExecDeathTestD0Ev_ZN7testing8internal9DeathTestC2Ev_ZTVN7testing8internal9DeathTestE_ZN7testing8internal9DeathTestC1Ev_ZN7testing8internal16ForkingDeathTestC2EPKcPKNS0_2REE_ZN7testing8internal16ForkingDeathTestC1EPKcPKNS0_2REE_ZN7testing8internal9DeathTest6CreateEPKcPKNS0_2REES3_iPPS1__ZN7testing8internal15NoExecDeathTest10AssumeRoleEvpipefork_ZN7testing8internal23DefaultDeathTestFactory6CreateEPKcPKNS0_2REES3_iPPNS0_9DeathTestE_ZTVN7testing8internal15NoExecDeathTestE_ZTVN7testing8internal13ExecDeathTestEchdirexecve_ZNSt6vectorIPN7testing8TestCaseESaIS2_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS2_S4_EERKS2__ZN7testing8internal18StreamableToStringIPcEESsRKT__ZNSt6vectorIPcSaIS0_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS0_S2_EERKS0__ZNSt6vectorIPcSaIS0_EE6insertEN9__gnu_cxx17__normal_iteratorIPS0_S2_EERKS0__ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE8_M_eraseEPSt13_Rb_tree_nodeISsE_ZNKSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE4findERKSsmemcmp_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE16_M_insert_uniqueERKSs_ZSt18_Rb_tree_decrementPSt18_Rb_tree_node_base_ZSt29_Rb_tree_insert_and_rebalancebPSt18_Rb_tree_node_baseS0_RS__ZN7testing8internal27CheckedDowncastToActualTypeINS0_11ThreadLocalISt6vectorINS0_9TraceInfoESaIS4_EEE11ValueHolderENS0_26ThreadLocalValueHolderBaseEEEPT_PT0__ZTSN7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEE11ValueHolderE_ZTIN7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEE11ValueHolderE_ZTIN7testing8internal26ThreadLocalValueHolderBaseE__dynamic_cast__cxa_bad_typeid_ZN7testing13PrintToStringIxEESsRKT__ZN7testing8internal11CmpHelperEQEPKcS2_xx_ZN7testing8internal11CmpHelperNEEPKcS2_xx_ZN7testing8internal11CmpHelperLEEPKcS2_xx_ZN7testing8internal11CmpHelperLTEPKcS2_xx_ZN7testing8internal11CmpHelperGEEPKcS2_xx_ZN7testing8internal11CmpHelperGTEPKcS2_xx_ZSt9__find_ifIN9__gnu_cxx17__normal_iteratorIPN7testing12TestPropertyESt6vectorIS3_SaIS3_EEEENS0_5__ops10_Iter_predINS2_8internal17TestPropertyKeyIsEEEET_SE_SE_T0_St26random_access_iterator_tag_ZSt9__find_ifIN9__gnu_cxx17__normal_iteratorIPKSsSt6vectorISsSaISsEEEENS0_5__ops16_Iter_equals_valIS2_EEET_SB_SB_T0_St26random_access_iterator_tag_ZSt9__find_ifIN9__gnu_cxx17__normal_iteratorIPPN7testing8TestCaseESt6vectorIS4_SaIS4_EEEENS0_5__ops10_Iter_predINS2_8internal14TestCaseNameIsEEEET_SF_SF_T0_St26random_access_iterator_tag_ZN7testing8internal12UnitTestImpl11GetTestCaseEPKcS3_PFvvES5__ZN7testing8internal23MakeAndRegisterTestInfoEPKcS2_S2_S2_PKvPFvvES6_PNS0_15TestFactoryBaseE_ZNSs12_S_constructIPKcEEPcT_S3_RKSaIcESt20forward_iterator_tag_ZSt19__throw_logic_errorPKc_ZNSs4_Rep9_S_createEjjRKSaIcEmemcpy_ZN7testing8internal15UnitTestOptions17FilterMatchesTestERKSsS3__ZN7testing8internal12UnitTestImpl11FilterTestsENS1_18ReactionToShardingE_ZN7testing14TestPartResult14ExtractSummaryEPKc_ZN7testing8internal17kStackTraceMarkerE_ZN7testing8internal19TypedTestCasePState25VerifyRegisteredTestNamesEPKciS3_isspace_ZSt18_Rb_tree_incrementPKSt18_Rb_tree_node_base_ZN7testing8internal28ParseGoogleTestFlagsOnlyImplIwEEvPiPPT__ZN7testing8internal11g_help_flagE_ZN7testing8internal24ParseGoogleTestFlagsOnlyEPiPPw_ZN7testing8internal28ParseGoogleTestFlagsOnlyImplIcEEvPiPPT__ZN7testing8internal24ParseGoogleTestFlagsOnlyEPiPPc_ZN7testing8internal27CheckedDowncastToActualTypeINS0_11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE11ValueHolderENS0_26ThreadLocalValueHolderBaseEEEPT_PT0__ZTSN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE11ValueHolderE_ZTIN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE11ValueHolderE_ZN7testing8internal12UnitTestImpl41GetTestPartResultReporterForCurrentThreadEv_ZTVN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE11ValueHolderEpthread_setspecific_ZN7testing8internal12UnitTestImpl41SetTestPartResultReporterForCurrentThreadEPNS_31TestPartResultReporterInterfaceE_ZN7testing32ScopedFakeTestPartResultReporter4InitEv_ZN7testing32ScopedFakeTestPartResultReporterC2EPNS_19TestPartResultArrayE_ZTVN7testing32ScopedFakeTestPartResultReporterE_ZN7testing32ScopedFakeTestPartResultReporterC1EPNS_19TestPartResultArrayE_ZN7testing32ScopedFakeTestPartResultReporterC2ENS0_13InterceptModeEPNS_19TestPartResultArrayE_ZN7testing32ScopedFakeTestPartResultReporterC1ENS0_13InterceptModeEPNS_19TestPartResultArrayE_ZN7testing32ScopedFakeTestPartResultReporterD2Ev_ZN7testing32ScopedFakeTestPartResultReporterD1Ev_ZN7testing32ScopedFakeTestPartResultReporterD0Ev_ZN7testing8internal24HasNewFatalFailureHelperC2Ev_ZTVN7testing8internal24HasNewFatalFailureHelperE_ZN7testing8internal24HasNewFatalFailureHelperC1Ev_ZN7testing8internal24HasNewFatalFailureHelperD2Ev_ZN7testing8internal24HasNewFatalFailureHelperD1Ev_ZN7testing8internal24HasNewFatalFailureHelperD0Ev_ZNSt12_Destroy_auxILb0EE9__destroyIPSsEEvT_S3__ZN7testing8internal13ExecDeathTest10AssumeRoleEvfcntlstrdupsigemptysetsigactiongetpagesizemmapclonemunmap_ZSt17__throw_bad_allocv_ZN7testing8internal24XmlUnitTestResultPrinter18OutputXmlAttributeEPSoRKSsS4_S4__ZN7testing8internal24XmlUnitTestResultPrinter17OutputXmlTestInfoEPSoPKcRKNS_8TestInfoE_ZN7testing8internal24XmlUnitTestResultPrinter16PrintXmlTestCaseEPSoRKNS_8TestCaseE_ZN7testing8internal24XmlUnitTestResultPrinter16PrintXmlUnitTestEPSoRKNS_8UnitTestE_ZN7testing8internal24XmlUnitTestResultPrinter18OnTestIterationEndERKNS_8UnitTestEi_ZNSt6vectorISsSaISsEE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPSsS1_EERKSs_ZN7testing8internal29ParseInternalRunDeathTestFlagEv_ZN7testing8internal12UnitTestImpl19PostFlagParsingInitEv_ZN7testing8internal18InitGoogleTestImplIcEEvPiPPT__ZN7testing8internal18g_init_gtest_countE_ZN7testing14InitGoogleTestEPiPPc_ZN7testing8internal18InitGoogleTestImplIwEEvPiPPT__ZN7testing14InitGoogleTestEPiPPw_ZNSt12_Destroy_auxILb0EE9__destroyIPN7testing8internal9TraceInfoEEEvT_S6__ZNK7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEE16GetOrCreateValueEv_ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS2_S4_EERKS2__ZN7testing8UnitTest13PopGTestTraceEv_ZN7testing8internal11ScopedTraceD2Ev_ZN7testing8internal11ScopedTraceD1Ev_ZN7testing8UnitTest17AddTestPartResultENS_14TestPartResult4TypeEPKciRKSsS6__ZTIN7testing8internal26GoogleTestFailureExceptionE__cxa_free_exception_ZNK7testing8internal12AssertHelperaSERKNS_7MessageE_ZN7testing8internal20SingleFailureCheckerD2Ev_ZN7testing8internal20SingleFailureCheckerD1Ev_ZN7testing24ValidateTestPropertyNameERKSsRKSt6vectorISsSaISsEE_ZN7testing10TestResult20ValidateTestPropertyERKSsRKNS_12TestPropertyE_ZN7testing10TestResult14RecordPropertyERKSsRKNS_12TestPropertyE_ZN7testing8internal12UnitTestImpl14RecordPropertyERKNS_12TestPropertyE_ZNSs6assignEPKc_ZN7testing8UnitTest14RecordPropertyERKSsS2__ZN7testing4Test14RecordPropertyERKSsS2__ZN7testing4Test14RecordPropertyERKSsi_ZN7testing4Test19HasSameFixtureClassEv_ZN7testing8internal2RE4InitEPKcregcomp_ZN7testing8internal30ReportFailureInUnknownLocationENS_14TestPartResult4TypeERKSs_ZN7testing8internal35HandleExceptionsInMethodIfSupportedINS_4TestEvEET0_PT_MS4_FS3_vEPKc_ZN7testing4Test3RunEv_ZN7testing8internal35HandleExceptionsInMethodIfSupportedINS0_15TestFactoryBaseEPNS_4TestEEET0_PT_MS6_FS5_vEPKc_ZN7testing8TestInfo3RunEv_ZN7testing8internal35HandleExceptionsInMethodIfSupportedINS_8TestCaseEvEET0_PT_MS4_FS3_vEPKc_ZN7testing8TestCase3RunEv_ZN7testing8internal12UnitTestImpl11RunAllTestsEv_ZN7testing8internal35HandleExceptionsInMethodIfSupportedINS0_12UnitTestImplEbEET0_PT_MS4_FS3_vEPKc_ZN7testing8UnitTest3RunEv_ZN7testing8UnitTest14PushGTestTraceERKNS_8internal9TraceInfoE_ZN7testing8internal11ScopedTraceC2EPKciRKNS_7MessageE_ZN7testing8internal11ScopedTraceC1EPKciRKNS_7MessageE_ZNSt20__uninitialized_copyILb0EE13__uninit_copyIPN7testing14TestPartResultES4_EET0_T_S6_S5__ZNSt6vectorIN7testing14TestPartResultESaIS1_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS1_S3_EERKS1__ZN7testing19TestPartResultArray6AppendERKNS_14TestPartResultE_ZN7testing32ScopedFakeTestPartResultReporter20ReportTestPartResultERKNS_14TestPartResultE_ZN7testing10TestResult17AddTestPartResultERKNS_14TestPartResultE_ZN7testing8internal35DefaultGlobalTestPartResultReporter20ReportTestPartResultERKNS_14TestPartResultE_ZNSt8ios_base4InitC1Ev_ZNSt8ios_base4InitD1Ev_ZNSsD1Ev_ZN7testing8internal23kTestTypeIdInGoogleTestE_ZTVN10__cxxabiv117__class_type_infoE_ZTSN7testing8internal26ThreadLocalValueHolderBaseE_ZTVN10__cxxabiv120__si_class_type_infoE_ZTSN7testing8internal26GoogleTestFailureExceptionE_ZTISt13runtime_error_ZTIN7testing8internal9DeathTestE_ZTSN7testing8internal9DeathTestE_ZTIN7testing8internal16DeathTestFactoryE_ZTSN7testing8internal16DeathTestFactoryE_ZTSN7testing8internal23DefaultDeathTestFactoryE_ZTIN7testing8internal23DefaultDeathTestFactoryE_ZTIN7testing31TestPartResultReporterInterfaceE_ZTSN7testing31TestPartResultReporterInterfaceE_ZTSN7testing8internal24HasNewFatalFailureHelperE_ZTIN7testing8internal24HasNewFatalFailureHelperE_ZTSN7testing4TestE_ZTIN7testing4TestE_ZTSN7testing8TestCaseE_ZTIN7testing8TestCaseE_ZTIN7testing11EnvironmentE_ZTSN7testing11EnvironmentE_ZTIN7testing17TestEventListenerE_ZTSN7testing17TestEventListenerE_ZTIN7testing22EmptyTestEventListenerE_ZTSN7testing22EmptyTestEventListenerE_ZTSN7testing8UnitTestE_ZTIN7testing8UnitTestE_ZTSN7testing32ScopedFakeTestPartResultReporterE_ZTIN7testing32ScopedFakeTestPartResultReporterE_ZTIN7testing8internal27OsStackTraceGetterInterfaceE_ZTSN7testing8internal27OsStackTraceGetterInterfaceE_ZTSN7testing8internal18OsStackTraceGetterE_ZTIN7testing8internal18OsStackTraceGetterE_ZTSN7testing8internal35DefaultGlobalTestPartResultReporterE_ZTIN7testing8internal35DefaultGlobalTestPartResultReporterE_ZTSN7testing8internal38DefaultPerThreadTestPartResultReporterE_ZTIN7testing8internal38DefaultPerThreadTestPartResultReporterE_ZTSN7testing8internal12UnitTestImplE_ZTIN7testing8internal12UnitTestImplE_ZTIN7testing8internal17StreamingListener20AbstractSocketWriterE_ZTSN7testing8internal17StreamingListener20AbstractSocketWriterE_ZTIN7testing8internal17StreamingListener12SocketWriterE_ZTSN7testing8internal17StreamingListener12SocketWriterE_ZTIN7testing8internal17StreamingListenerE_ZTSN7testing8internal17StreamingListenerE_ZTSN7testing8internal27PrettyUnitTestResultPrinterE_ZTIN7testing8internal27PrettyUnitTestResultPrinterE_ZTSN7testing8internal17TestEventRepeaterE_ZTIN7testing8internal17TestEventRepeaterE_ZTSN7testing8internal24XmlUnitTestResultPrinterE_ZTIN7testing8internal24XmlUnitTestResultPrinterE_ZTSN7testing8internal13DeathTestImplE_ZTIN7testing8internal13DeathTestImplE_ZTSN7testing8internal16ForkingDeathTestE_ZTIN7testing8internal16ForkingDeathTestE_ZTSN7testing8internal15NoExecDeathTestE_ZTIN7testing8internal15NoExecDeathTestE_ZTSN7testing8internal13ExecDeathTestE_ZTIN7testing8internal13ExecDeathTestE_ZTVN7testing8internal26ThreadLocalValueHolderBaseE_ZNKSt13runtime_error4whatEv__cxa_pure_virtual_ZTVN7testing8internal16DeathTestFactoryE_ZTVN7testing31TestPartResultReporterInterfaceE_ZTVN7testing11EnvironmentE_ZTVN7testing17TestEventListenerE_ZTVN7testing22EmptyTestEventListenerE_ZTVN7testing8internal27OsStackTraceGetterInterfaceE_ZTVN7testing8internal17StreamingListener20AbstractSocketWriterE_ZN7testing8internal18OsStackTraceGetter19kElidedFramesMarkerE_ZN7testing8internal18g_linked_ptr_mutexE_ZN7testing38FLAGS_gtest_show_internal_stack_framesE__pthread_key_create_ZTISt9exceptionlibstdc++.so.6libm.so.6libc.so.6__environlibgcc_s.so.1_edata__bss_start_endlibgtest.so.0GCC_3.0GLIBC_2.0GLIBCXX_3.4.9GLIBCXX_3.4.11CXXABI_1.3GLIBCXX_3.4.20GLIBCXX_3.4GLIBC_2.1GLIBC_2.3.4GLIBC_2.1.3           &0P&y Zii b`) lazӯkpt)ii ti si ŝii b048@`dhlptx|ȦĦȚTTTTTT T(T<TPT|TTЦԦ~~~0~D~X~d~p~~~~~~ȧ~ԧ~~~~~ئ-ܦ`>Vd Llx|$*,$4g8Ĩ@HT\`h>t9ni`ħḐЧDاܧ44BBJ JJ\J&$DخD$D(,b0PnTnXn\npnnШnԨnبnܨnnnnnnnnnnnnnnnnnVjHRLPTX\` d$h(l,p0t;4;4;x"8"8"|@%ĩȩ(̩1^ P0 i$(,0<@ML,PET X;d%hlIp|X(ĪȪ̪x  j  $(,#048< @nSN6e^|'+AC <LPTtX\dh_į_ltcx|جuuܬuuԬĬȬ̬oЬ U @$(048L<DYYHL[PTX\J`dhlptx|EZ9A-?Į:Ȯ<̮pЮԮܮB"EWY} I_V a$=,0l48 <Q@DHL PMT?X`Zdhfl:ptx|vDFo31(s, S $(,0&48<@D HLP T.X\ ` dhl p tx|=.5F2HİȰH̰а԰Cذ2ܰ+-  ! $ (,)04!8 <@=D"H#LP$T%X\ `&dhl'ptxU|()*?+,Z./Nbhı&ȱ0̱yб1Ա2رܱ,/)7345 67 $(8,0438_<@D9HL;P:TtX\=`UdOhl>pKt?xu|@AkCDel'cIJȲF̲rвԲزGܲTHI2JKsL MNOP g$Q(],0R4T8S<@DUH LPOTVXW\`XdmhBlp[tZx|[\ ]^+abYc%d/0Lijeȳ̳\гfԳسgܳhqqij~k E3y $(m,04T85<o@DH]LpPQT#X@\`d6h!lptJxq|Frtu(vwE4xyz:{ĴBȴ̴|д}Դ<شܴ~LO X7k $(,04;8,<@DfHLPTX\`dhlptx|Ra*<zĵȵ̵rеԵ!صܵ< W4 $(, 048<@@DHL*PTX\9`dhlptx\|QWwĶPȶ̶жmԶض5ܶD"}G _ MSW gt2[ hhhhh h($h0(h8p,h@`0hHP4hP@8hX0<h` @hhDhpHhxLhPhThXh\h`hdhhhplh`phPth@xh0|h hhhhhhhh h(h0h8ph@`hHPhP@hX0h` hhhphxhhhhhhhhph`hPh@h0h hhh hhhhh  h($h0(h8p,h@`0hHP4hP@8hX0<h` @hhDhpHhxLhPhThXh\h`hdhhhplh`phPth@xh0|h hhhhhhhh h(h0h8ph@`hHPhP@hX0h` hhhphxhhhhhhhhph`hPh@h0h hhh hhhhh  h($h0(h8p,h@`0hHP4hP@8hX0<h` @hhDhpHhxLhPhThXh\h`hdhhhplh`phPth@xh0|h hhhhhhhh h(h0h8ph@`hHPhP@hX0h` hhhphxhhhhhhhhph`hPh@h0h hhh hhhhh  h($h0(h8p,h@`0hHP4hP@8hX0<h` @hhDhpHhxLhPhThXh\h`hdhhhplh`phPth@xh0|h hhhhhhhh h(h0h8ph@`hHPhP@hX0h` hhhphxhhhhhhhhph`hPh@h0h hhh hhhhh  h($h0(h8p,h@`0hHP4hP@8hX0<h` @hhDhpHhxLhPhThXh\h`hdhhhplh`phPth@xh0|h hhhh h h h h h( h0 h8 ph@ `hH PhP @hX 0h` hh hp hx h h h h h h h h ph `h Ph @h 0h h h h h h h h h h( $h0 (h8 p,h@ `0hH P4hP @8hX 0<h` @hh Dhp Hhx Lh Ph Th Xh \h `h dh hh plh `ph Pth @xh 0|h h h h h h h h h h( h0 h8 ph@ `hH PhP @hX 0h` hh hp hx h h h h h h h h ph `h Ph @h 0h h h h h h h h h h( $h0 (h8 p,h@ `0hH P4hP @8hX 0<h` @hh Dhp Hhx Lh Ph Th Xh \h `h dh hh plh `ph Pth @xh 0|h h h h h h h h h h( h0 h8 ph@ `hH PhP @hX 0h` hh hp hx h h h h h h h h ph `h Ph @h 0h h h h hhhhh  h(UWVSu8UV}EtZ\ QQRPUԃRRKRPPPPEPgUQQRPFRRRR0ZYVW$V*e[^_]ÉPPjV<$YffffUWVSׅ8X@WL VW XZjP<Y_jP$@]XjP XX=ZPSP \|$#WPUz VUUYX6$PP WPD VUTXZTD$PPK WP V UYXjPKX!ZjPYXjPX ZjPtYXjdPX%Zt$P WPa VUqYX6jP`Q T$ VPU9#PGP# WP VUXXZjP#4 Wtt$W VWUlT$ VPUP @@VP{<[^_]f$ffffffUS03)Ѝd$vt$Ѝd$[]Ít&US÷00)Ѝd$tt D$$эd$[]Í&USWgd$쀻@u$t@$<7ƃ@d$[]É'USd$썃<ud$[]6t$fffffffÍ&'Í&'VD$P p19t& yty9u^VD$P p19t& y9u^ÍVD$P p19t& y9u^ÍVD$P p19t& y9u^ÍT$B+B fÍ&' T$D$:u@@RPQÐv'UWVSÕ My q9t#t&t  PR9uExt Wde[^_]ÉƋEPt RD V&VS t$V4$[^Ð&VSD$t$$PTPV$[^UWVl$t$}t9UE )t*1VPRUE )9r^_]fUWVl$t$}t9UE )t*1VPRUE )9r^_]fUWVl$t$}t9UE )t*1VPRUE )9r^_]fUWVl$t$}t9UE )t*1VPRUE )9r^_]fUWVl$t$}t9UE )t*1VPR UE )9r^_]fUWVl$t$}t9UE )t*1VPR,UE )9r^_]fUWV|$l$t:Gw )x* v'G0UPRu^_]ÐUWV|$l$t:Gw )x* v'G0UPR0u^_]ÐUWV|$l$t:Gw )x* v'G0UPR$u^_]ÐUWV|$l$t:Gw )x* v'G0UPR(u^_]ÐUWV|$l$t:Gw )x* v'G0UPR8u^_]ÐUWVt$|$~t=VF )t.1퍶Wt$PR VF )9r^_]Í&'UWVt$l$~t>VF )x.< V: Ut$RQ4u^_]Í'UWVQD$ ƉD$)tN1t$ 1vL$ D$t L$D RЋWƋ)9r˃^_]1&'UWVSz tW1퍳u*F& Rt&/ uڃ Vuڃ [^_]É' P [^_]ÍVSIYzdtH~[^fHqɉpRP[^UWVS1z,EЉUԋ E̍Wj u j uutXEԃ)@9RW}uW;XZWuE ;u듍vU넍t&Eԋ@9ujWuVY_VuE ;u EЍe[^_]ÍUEЍe[^_]PWPlPJƋEЋ ;tUp V7PWPlPƋE ;tU:밉ƋE ;tU 떍&'UWVSWgx,L$@|$DD$D$Ѝt$T$$*1D$D$D$ $(Pt$jV4$ PVW;l$@tMD$tèuD$ jD$!PW륐t&D$-jt$W|뇍&,[^_]Ð&WVStÄwt* R1 PVPR1[^_Ð&/jPP [^_UWVS%w(jƋE EFEFEPF uP/E0e[^_]à V<$<VSùvt$ tB ;u R[^ÍT$ېfUWVSUev} 0tMj:V"t#U)RPVW]e[^_]EPVWJې&EPTPW,뽃 PNWVSD$|$upFN<*t6~<:tSe[^_]ÍvWu 6be[^_]Í&P PEgx 6能$$Zu䈃(E9E. uP4$&SJZ`Pj$UXx0G[fS `Pj$Xx0[fVS_ t$Pj^ v6P$ Xx0[^Ív'UWVSgw_D$0P@ ҉11t„҉u u[^_]ÍL$ PML$ti"WPW*t P"VPW[^_]Ív@ 11ftt&f뷍UWVSwÇ^ D$ l$$p@ )t&19.Vu*v'փ9jt9u 1[^_]Ðt&V9t)щu‹D$ P [^_]ÍQRVD$0P ϐ&UWVS}]0uXFWu PFtPu504j jP%X0$ve[^_]ËNEԍA;t uUWVS%]4u E pVE xƅu#v'Wv#P9tp> tՋEPJ;HMwH~uu]EP EP;u%E P9uEe[^_]&}@x8ȉƋEA;tU VfUWVS\ t$4l$8j PVD$D$ ()PUoVh jt$Vyt$UuȃUV jt$VG,[^_]Ð&'VSIY[t$j@@@ @FF[^Ðv'VSZD$0t#@9u V辽4$[^Ðt& VЃ[^Ð&SÚZD$T$9Pt49PtR0[Í&@R0[Ð@R0[Ð&D$Ð&D$@Ðt&D$@Ðt&SYD$p$e[SYD$p$[SúYD$p$[SÚYD$p$%[SjzYD$p$e[SJZYD$p$腷[S*:YD$p$%[S YD$p$5[SXD$p$起[SXD$p$5[SúXD$p$[ËD$@$ÍD$@$ÍVSIYXD$p$Vc1҅~ [^f ƈVa‰[^ÐVS XD$p$V~[^Í& ƈV ƒ[^ÍWVD$ L$p$1x~`Vd)9} xFT^_Í&'UWVSWgW(t$<D$L$ u&D$ t$/uv t$4PV[^t&UWVS觻÷>,,;L$@tlthy19t;D$L$ D$9t 9tT$9uL$ 9tL$ WiL$ QYD$@,,[^_]Ít&5>,t É'PÉ'UWVS׺=t$,|$0l$(VW> jRP艵vV1҉Wj@/M jPW]VXY)WV jPW5[^_]Ðt&1҉WVΐt&UWVS'7=D$4|$0ehtmSEHPL$J RT$裧 PT$RW褴VjPW菴XZt$WӚǍ jPWo4$W PVW\^ jPWJ U& PUW+@t|~tAF'PWc$ ,[^_]ÍvPBPR詮0 V觝P; tj V҃fPBPRYYT$B+iÐVSiy;t$x t$9|VPuPD$[^Í&'UWVS;(hҨƍ@4$EҚdƆdžƆdždžGdždžF4GW E@U؉FXZQjR4YXGNWMHFjQGWN M@PFFFFP F F$P4 FV4F F($L`F,F F0XZuu耨E}܃0F@De[^_]ÉNjd F4u趩4$螚<$ uEȞXWYRV謪E܃뵋}W}؉<fUWV,S/9lj`P$dEEEEEFEE`N Fʉ, @,Dž0XAZjPJV4YB4_~8jP~VG P,G Dž<Dž@DžDDžH,G4DžLDžP`G 4BT8$`DžXB8B \XZ8R$9^X4PʋB @B u QoZYuG ,G4`G 4`8\ ; 8 @,4@4 ,@,d`X$触Ee[^_]&+SƋd $`a4$虬 94$聬 aXFYP>뛋 Ɖ,Q,xUWVS,蟲ï5E U`PYdEEEEEFEE`NV A,,Dž0yXZjWVY4B4 V_ȉjP苣~VGP,G Dž<Dž@DžDDžH,G4DžLDžP`G 4BT8$菠`DžXB8B \XZ8R譢߭^س.$BZYu袦G ,G4`G 4`8\ ; 8C@, 4@4,@,d`X*Ee[^_]v'+uPƋd `4$ 蹧4$ XFYP辣뛋,V,xUWVS`,)2$QdEEEEG~V EE`EG,,Dž0XGZjPRYXF‰44 BVjP VNBP,Dž<B Dž@DžDDžHDžL,B4DžP`B 4BT8$!`DžXB8B \XZ8R$?4 p~uFt0@u DŽ<`ZYuP ,P4`P 4`8\ ; 8蟦@, 4@4G,,d`X$茟Ee[^_]t&N|ɉtmytFu Qǐ@;u!4ʉ'+腴j Ѓ ٣4$! XFYPޟd $`螞4$֤,WƋ,뽐&UWVS`/.E $Q,dEEEEG~V EE`EG,,Dž0XGZjPIYXF‰4 4 BVjPVNBP,Dž<B Dž@DžDDžHDžL,B4DžP`B 4BT8$`DžXB8B \XZ8R$64 p~u5Ft0P DŽ<PʋB @B QcZYuP ,P4`P 4`8\ ; 8r@, 4@4G,,d`X$_Ee[^_]&N|ɉtmytFu Q藌@;u!4ʉ'+Uj Ѓى 詟4$ яXFYP讛d $`n4$覠,WƋ,뽐&UWVS*,U uwnw)EUE܃PEPVe[^_]fЉ ??ɀEȀMUE랍E܃}RPE=X{ZuPW[<$Vn jPV耞E M9~E܃ ;EI谮=vE?ȀUE vЉE?Ȁ?E ɀ?MUȀE&U@uNj u9tUE ;EtU E܃ ;EtU V辞ƋE׉ƋE뷍t&UWVS%(}} ,jPeM~{tu(1t&;utXtQP蒖X(ZpP4Pj( ;t';uuvuP P ,P4 4``8\ ; 8TPٝPHR,PH4R4P@ ,R,d``$ʖEe[^_]v' WE`(Eƃ l4$贜Ƌ( ;t׍'ƫʍt&UWVS&,E 8GEtc1vtgMԍU)QPR,EYZpPEEЃP蒝E ;ufEԍtQ9uEe[^_]Í&EUEjREЃP79uc뿉'EUE떉ƋE ;tUƪ V荛VS %D$$t$ tjPV8 [^vD$P/PV[^UVSEu uP艡Ù$EZYpPPRJE ;u e[^]ÍUe[^]ÉƋE ;tUש V螚&'UVSEu uP $~EZYpPPR躛E ;u e[^]ÍUhe[^]ÉƋE ;tUG V&'UWVSsÃ#,\@␍t&jt&PVe[^_]É'6jӍvjÍvj볍vj룍vj듍vj냍vjpj`jPP^vx}PW}ԍ}UYXuPWsXEZpPV4E䋳 9uE 9u ֧Uٍ̧v'EEjPVޙ1NjE䋳 9tU芧E 9tUx W?Njېt&S語ú!"t4'ujPRe1[Ív[&jPR6[É'UWVS5E! |$4D$KjD$PWL$ti)q)D$D$ At&.u1 Uׄt!jt$W衘 jt$W蒘;t$ujt$Wn[^_]ÍvVSyÉ T$D$t$t |Jt& V jPV[^Ðt&t$[^WVSt$$ |$t>VẂ j RPʗ4$貊|$[^_&jPW薗[^_ D$L$PL$Jv'UWVSsà |$4T$jD$PW/txM1D$ 'ȃt;4$tOLu9u߃ QL$L$tǃjt$WȖ jt$W蹖L$렍KjPW螖[^_]ÍvVS詛ùT$D$t$tLt( V jPVM[^Í&t$[^ WVSt$4D|$t>VW j RP4$貀|$[^_o&jPW趕[^_ D$L$PL$*v'UWVS蕚å8U} WEZYPuG7Edt&<%}h< tdEPJ;HMwH~uuEP EP;7tx<&~<=uEMVQe^uXuuVČ4$uIE ;u8E ;t07u&Ee[^_]vU뾍U@PFƋE ;tUС V藒ƋE ;tU诡E ;tU虡믉fUWVS՘,E uR}܃PW̋<$}W@ j/jW装E uWPEzXuV4$^E䋻 9uSE 9uYE܃ 9u/e[^_]vuVe[^_]t&UǍU谠룍U蠠띋ƋE܃ 9tU脠 VKEԋ 9tUauԋE 9tULE 9tU:뢉ƋЉƋ؉ƋE 9xUkUWVS}BR4uuW E @u0u V~E 9uae[^_]t&Eu PE~~S jPu WuVyE䋻 9tUR땍UHe[^_]ƋE 9tU" VƋE䋻 9tӍUt&'S:Jt$D$P„[Í'S t$D$Pw[Í'Sڕt$t$脑[ UWVSMu蟕ïp}}QMEPVŃEE$E^<$El WE߅YXwPEPE/~E pPEPEЏXSZEPEPE}YXkPEPE}XEZVPEu Y^PEPE}1TVWE͋ME juAUPXEZuPEC WE軄9|EЃ EPE,EuԉEPEԍEY_xEuPE藍XEZpPW舎E U9uԅuԍEuPQ}W8 PWu請E ;EEt juGuu#_XjVvju9yE ;E Ee[^_]Et PR뤃jWE1ǃ9EE؃ PEMقw$uZYVPxZSYRPyY^RP^ZWP踍ZYPuME^_jPEuEE 0w&tz uE{ EU蒚Ee[^_]U}:Upr uj莂}ZYW PV-u uEw$uEǁZYVPEwƍEE$E< j PEPEFEEăuPՊURU~U PRv)Eă ;EEt$ jtEt  PRu VvƍEȉE$耊M jPEȃPHFẼuP+URU~U PRvẼ ;EuaEȅt$ j~tEȅt  PRPVFZYWP=Y^PuҀXEZjPUsUh땍U^ jZYMQ PFPs)ƃjuuEjPrjuuE ;EtU V贈ƋẼ ;EtUϗ뜉ƋEă ;EtU踗ju+u녃 jEZYQ MPFPYr뵉EƍE܃jP6rE5ǃjVrƋE }9tUuԃjut뷉NjE ;Et֋Uږ̉UWVS}"4EЍEԃu UPWDuot<$}Wu jPW!XZWufu4${ PVuE䋳 9uE 9u,EЍe[^_]É'U(E 9tڍEЍe[^_]ÉNjE䋳 9u-E 9tU W詆NjE 9tӍU迕ɉNj뿉NjEЋ 9t΍U藕Đt&UVS֌u V}EQ-QXZPjI|2 vuP{FtZtTP"P=P{x 0zwE ;u e[^]fUؔe[^]Ð j vq뷉ƋE ;tU謔 VsvUWVS|jhuu nEE$sX}v W}.sEFM$QsFUu$Vl|EqYU_yUWVRQtXuZuuVpmYXEWVP1tXuZuWVRmYX_}PVWtXuZuWV0mYU_VUWVRsXuZuuV mYXEWVPEsXZuWulE 9E܃ 9Eԃ 9EЃ 9Eȃ 9 Eă 9 E 9E 9E 9E 9E 9E 9Ẽ 9E؃ 9E 9Ee[^_]EPTPuwEe[^_]v'UvUvUvUvUؑvUȑvU踑vU訑vU蘑vU舑vUxvUhvUXvUHvU8NjE 9tUE܃ 9tUEԃ 9tUEЃ 9tUEȃ 9tUѐEă 9tU运E 9tU譐E 9tU蛐E 9tU艐E 9tUwE 9t |bE 9tUPẼ 9tU>E؃ 9tU,E 9tU WNjNjNjNjNjNjNj NjNjNjNj Nj%Nj*Nj/v'UWVS蕆å LM}ɍF EEȃMPWQoX}ZuuWxoEĉ<$PEzẼ} 9eEȃ 9uWm<$z Wu ufE 9KEă 9%Ee[^_]&EԃEUPR+lYMX MPWQnX}ZuuWgYXE܉UPWRnX}ZuuWnEĉ<$PEyE} 9u` j PW&v jDPWvYus PiMĉEvh} PjQM_h j(PWuXZuWcYusvh PEjPljE_X ZPcV rRP`uZVYRPcV rRPAu<$se[^_]à us4$s ur4$s ur4$s UWVSyn jPW,nZYVWsTXukEЃe[^_]à uԉk4$l uԉk4$lfSr D$pU]ZYt$PR[Ít&UWVSr8uFPEeEu;mF F$ FủE^uwEЍe[^_]Ít&h<PEjPE.W jPWm jPWmXZuWIS_uje&hHPEjPEV jPWl jPWlZYVWRXujjEЃe[^_]à uԉOj4$k uԉ:j4$jfUWVSequ8uFPE-dEu;>lF F$ FủE ]uwEЍe[^_]Ít&h<PEjPEU jPWk jPWkXZuWQ_upie&hHPEjPEfU jPWNk jPWPE܃P aH j=PE܃Pa j=PE܃P` jCPE܃P` j PE܃P`^XEWP_ZuEYuu VEY uuP0WE M9uzE ;Eu_jWKe[^_]É'/PE܃PjNbt&/PE܃PJNt&m똍&UmyƋE U9tUmE ;EtUmPPjWJ4$A^ƋEΉUWVSdõ(u ~W^"Pj$Tv6PS<$^8t_FXV\EUE܍URP#LX0uPSSE܃ ;ujx 0"Oe[^_]Í& j 6IϐPjoSF& VGLU&U@l댉ƋE܃ ;tU&l V\UWVSUce VU4$EzG VvUZEYRjCPXEZuủ‹E^YXuPOE 9 V#I}ȍZU EPWPmO VGt78u,EȅtfZUEPVPjOx 0Ke[^_]ÍUhhWvUXhv j D닐U8hvU(hE 9v'UhƋE 9u+ VXƋE 9tUgƋE܃ 9tՍUg҉ƋE܋ 9tUg룍&'UWVS^8E} E֍EPEXHtW1&0JވU׀ɋ ፶jPEP@Y;pr}ЃWu$X$WgDEe[^_]&j릍v}j댉'js}tjj]v'M׃ EՀ} Uus}>EM׍UރjRPM]X&EU݃jE"RP7XfEU܃jE'RPXf}tU׍ERPGX ZjPEPWE pPEPW jPEPWE ;uaUdeRƋE ;tUEejuB4$V獶UWVSE1`\p8EPNV WJ PEWPW jPE܃PVE܍K jWPVE pPE܃PVE܃ jWPVE ;E ; u @9Vu GǍEڃ PEwPEIM juQMSEX?ZjPE܃PV/PE܃P9Dt&Uc_vUc=vũVuT$VAEe[^_]ƃju@4$-TƋE䋻 9tUCcE 9tǍU1c뽉Ƌ␍t&UWVSeZuLE ME1y u e[^_]ÍvE PEGEPETE xj PEPT0 WG PEWPTESjWPTE@eUEȋtb, PEP~B:Y^PEPiBEȃ pPEPTEȋ 9M1EuPERuAE 9WUt$ jGtEt  PRE 9e[^_]Ít&}UE؋aE pEPEoREE<~*zPEP]AYXEuP\9tPEP+AuEԃVPQ$V>X ZPEP@^XPEP@Eԃ pPEPRXEZWP@_XTPEP@E؃ pPEPQREԋ 9E؃ 90U_#&UEċ'`PEP1@_X:PEP@Eă pPEPQEċ 9Uw_f}h;PjW;Y ^P?<$AO1WUE̋__P PEPi?X:ZPEPT?Ẽ pPEPPE̋ 93fU^=Epu?trf/PEP>&U@^vUĉEaPBP>(t&UEЋO^E@0 PEPQ>YXGPEP<>E`WP>XTZPP >EЃ pPPOEЋ 9Ua]RNjEȋ 9u6PPju:E 9tU)] WMNjE 9tʍU ]뼉QQjut:E؃ 9tU\덉NjE̋ 9w뫃 WLZNjEċ 9DuNj딉NjEԋ 9tUe\uNjEЋ 91t&UWVSESÒ0Ej Pu '=U؃:u$5Ue[^_]Ívu܃ V,M j PE܃PMEY_xEuPELXEZpPWME䋻 9 j1PE܃PM j PE܃PMYu n@ PEu PkM jPE܃PSMXEZVPGLXuPAE 9Fx 0f=Y_jV\8e1[^_]Í&u܃ V L j PE܃PLEY_xEuPEKXEZpPWLE䋻 9 j1PE܃PL j PE܃PgLYXEu P: jPE܃P>LXEZVP2KXuP@E 9ux 0Uut6Ee[^_]Ð&Et PRҍvE e[^_]à jIPPju54$H'UWVSEOU,}te1[^_]Ít&ju[7XZju M7ƃuutu0t9 e[^_]ÍE PljEHYXx PEP7X$ZPEP7YX PEP7XEZVP/Y^PEPi7X$ZPEPT7Y^PEP?7XZW}Wa:YXjV74XZWVGXuj=E ;sx 08 j!HE PEGYMX PAP6XZU䍋$QM̍BP6UYXPBP6XEZ$RPUx6YXPEPc6MXZAuPR6YXE䍋 QM̃P:6XEZVP;.QY^PEP6XZUuЍBP6YM^u̍AP5MXZAWP-M_XPAP5Y^uԍ}VW8XZjV2YXWVnFZuj35YX PEP)5XEZWP*-Y_PEP5X$ZPEP4Y_PEP4X}ZVW7YXjV1XZWV|EXujA;E ;u/x 06UTUTUSljƋE ;tUSPPjWU14$DPPjW=14$DPPju'14$oDƋE ;tUSPPjW04$EDQQjW04$-DWWju04$DƋE ;tU/SPPjW04$CPPjW04$CPPjuw04$C&'UWVS%J5,u 8tEP P8986$PWM?$$jPWEBt8`Pj<94$4_YnEQyQJ}4$t&WVShExT$ D$ |$$^ t$B*t37ƹƋD$ ;u([^_Í&D$ ;tߍ&T$ M[^_Í&'VSDT$ D$ t$)ƅD$ Dt$$ ;u [^Ít&T$ 'M[^ UWVSERDbM܍{ jPAP>EԋM܃ pPAP>E؃ PWu>NjE܃t0 j2tE܅t PRt&Eԋ}؃ 9e[^_]Ðt&} WV=EY^u Pu$XEZWP=X\uPi2E䋳 9uVjW;)x_0-.Eԋ} 9rUKe[^_]Í&ΐ&UhK렋EPPjW(}ăEԃ 9tU;K W;&'UWVSE}AïHEP1W;EY^pEu EPEEJ;XEZpPV;t W<$9uuދE 8PE@t PE@ t PE@tV j<tEExt; 9uG WcE@ 9t&Ue[^_]ÍvE@ 9uڍe[^_]ÍU믉ƋE 8PE@t PE@ t PEjPEHA;tU. Vډ떐VSYit$V4$n[^Ð&VS)9t$ F;Fte[^_]ÍvhuPEjPE j!PWn jPW\XZuWYu(hPju* j1PW jPWXZuWEYut&hPEjPE j1PW jPWXZuWXuhO uSF ;tU* WǍQQjP?PPjP,Zuc uuFl PFF`t PCFTt P0FHt PF@ P^ u 8 u{Dԃ ub‰dǍ PN(&UWVSUe4uFjPEu/ FhXZVW[~$e[^_]Ðt&huPEjPE j!P jPXZWYuYj uԉD4$ W u4$鐍UWVSEU Ht e[^_]ÍvH W[t׃ V+<$@ PVMe[^_]à W4$=UWVSõ\ j:PqxE܃PEEWPƉEYXVuV4$6E䋋 M9| VEPW}WWXEZWPljE<$ Pm}ȃ uPWZYW}Wa<$E؃ uWPEvXuV E؃ ;EZẼ ;E[Eȃ ;E\Eԃ ;EEЃ ;E Ve u}EWE uWVu E ;EE ;EuuE܃ ;EEă ;EEe[^_]vVuDЍ&ẼuP&$PVY_}VW<$] PUȃ RPEPXEZVP4$#E WVPEXuuE䋋 M9E؃ ;E Eԃ ;EE ;EE܃ ;EUh vUX wvUH EvEPTPufU vU UvUt&UdvUvUvUvUvUvUvUxƋEEԃ ;EtUUE ;EtUBE܃ ;EtU/ VƋEĉƋE U9tU븉ƋE뫉ƋE䋓 U9tUE؃ ;EYULƋE܃ ;EEă ;EeUXƋE몉ƋE؋ U9UYƋEȃ ;EtU?Eԃ ;EtU,EЃ ;EzUmƋẼ ;EtUƋE؃ ;Et܋U҉0룉ƋEċ U9tUE ;EtUgƋE׉ƋE ;EUpƋE ;Et׍UV͍t&UWVSuâ(Vsb$Vu]E Paj}7XZWVLEZYVPE䋳 9E 9u1e[^_]fTPV0u)E 9tύUe[^_]É'uPXx0벐t&UHoNjE 9tU) W VE䋳 9tǍU뽉t&S:J p$$[Ít&S  p$$I[Ít&VS~t$gL$QRp$V[^'VSé~+@$tFRp L} EEEPT@XE)GEEEEE̍EEȉ'EupuȉljEDGW G,E)7E1Et&} uuu襛t&EċEF@,MЈA,E ;EЃP @E)94uvu芨XP$ZPuȉEƲEuuu讲EԃEԃFuuMԃF: 1Dt&EEF8v'UX9vE ;u+EE}PT@XE)9bEe[^_]ËUˍ$jP茡YE$^jPyEƋE ;tUE ;tU VwEEe[^_]ÐUWVSո;$} uWʪt#UjRPWe[^_]t&EPWVҦe[^_] P&UWVSUe;|E} PquE |PEEEEEEE܉EEЉEvj,W͜ujVPW%E̍ẼEEuuPEE ;EjPEP]Ẽ pPEPG jPEP/E̋ U9j,Wt& PIut&EPEWPE4#t&EpE9un Vg;EtUvuϤu؍EuuP覰 E̋ M97uȉ(t&jPEP Ẽ pPEP  j!PEP늋EuȋxE9EĉEEt& W臣;EVwu uuuEă M ;EuV;MuEjuP_GtCPEP腞jPEP*bUMM뚃/뵃uVT$V<Eȃ ;Eu+uu踨XZju |e[^_]ËUsˉƃuu聨Y_ju՚4$ƋẼ ;t΍U5뾉ƋEȃ ;EtU멃uu uud VuP69Ẽ ;EtUӼ 6I1ƋẼ ;EtU謼z&UWVS6,E@EЍj@W襘EjPVW Puu:G;utF~<@t9E 9 E{x~DƒuPEPElu xPVluVuu8eE 90E 9;Eup\pXV4_YXuPEPdYlVduudEă 9E 9Ẽuu PƉl l xPEPEkVuuumdEȃ 9Ẽ 9uxiXEZpPu,xE܃ 9EEht&FHDƒvPu)oXF SZQu|EЉtPEfYX|uleEЃ 9EԃuuP|jE؃ j|PfXZjPuLwE؃ pPu:w j RP(wE؃ 9GEԃ 9)vtuuBeYXVux1eE 9@xppQ.pAQp1p!p5p3ƋEȃ 9t pẼ 9u Whũ RPVOXZuPEPE\Vuuu[UEЃ ;EẼ ;Et8te WVUZEEYuPET^uX!uPVm\uVuuTE؃ ;EaEԃ ;EE WacZYPu6Z^XEpPuhE܃ ;EE؃P-Pu[Eԃ uPPV[uVuuTTE ;E<E ;EDPuE^V1;&VW6b$Y~VWbZYPuh W^9|PuUU rRPgZYuPUE ;Ee[^_]ËUMuU@uU3u$U&uUuU uUtE ;E"UtUt[UtE ;EUtUte[^_]ÍUtE ;EUt~MttE ;EM[tQt UDtƋE ;EtU*tE ;Eu<$$Vt&}hHPjW!B jPV X jPVWXZuV<><$Ue[^_]É' jM‰EċBE̋Eȋ+BBB iEEMƉAAq Mȋ9UftFGFPGPC 9uuԋEăxPEV}hPjW@YXPEYZRPDYZVP<<$Tt&=UUUw{ VLEt&U@d}O W8T4$T W%T4$Tƃ uO4$Tƃ uk?Q WSƃ P8SXYWu=K5@QEċ@t P?렍SZl< PsF[Í&'UWVSEZòxEPTE pPEăPXUEE$JE@$E$UP+i*Et HẼuPSE U^_EԋERu̅TEEPEP;HXEZVE܍EPAYE_}WVPHẼ ;{E up$S;_ZVPRM t&@8t  8= VTYuMXZju|?e[^_]ËEăPLBE pPEăPSSPEEăPBX/ZPEăPAP^_PEăPAE@$E$#TP+ibD@E' PFEEu0Ev6PeLXEZjuP"SEȃ pPEăP S jPEăPRF pPEăPREȃ ;qm EE @$ERC7 jHEAEE+AAA iEEUƉBBr U9Mlj'tFGFPGP> 9uuԋExPElQa}hPjW;YXP?YZRP?YZVP7<$DOt&uԉ_'=UUU V,GE}E^y jIXZVWI WK PNXYWuF; EW J} VQ u|Iju;4$$O=LE@t P9 u9밃 W,N"L׉녉돉뙉ƋEȃ ;wU]jƋE U9t]E؃ ;EtU]Ẽ ;E,U]ƋEĉƋEʍUWVS}uTÿ,A6jp$W?XEZu Eԃ PVFE HPMԉUЉE5WVuuuPEE 9uE 9u%e[^_]Ðt&U\E 9t፶\e[^_]ËƋE 9tU\ VVMƋE 9tӍUl\ɍv'UWVS}Sò0uFPXv6P`PfPWR7}E܃ PEVME PvhPEjPE8uu5Xu=E܃t' jAtE܅t PRvMtY jAtHMtA U9u_ Q6F ;Et,A[e[^_]É'EԋF ;Euԍe[^_]Ít&Tt&U܉MZM둉EԋF ;tZ uKERRju>8PPEjP5뼃 uԉEk<$C uC4$CE 9tUR}뿃 uB4$C릉Nj늉NjkNjLNjE܃ 9u uVBE 9uCe[^_]Ívt>,j PEPE=8멐&UQe[^_]Í!PEPEz,ƈmƋE 9tUXQ VB&'UWVSuHÒ$u V0YE_uP0XEZVp$=E䋳 9uE 9u'e[^_]Í&UPE 9tߍUPe[^_]ÉƋE ;tUP V_A V1<$LASGL)t$t$Pk8[ÍUWVSEGÒ8ljEPnAXEZu P(YE^WP1AXuEZPuV5Y_Vu1E䋻 9uQE 9u7U܅t$ j5tE܅t PRe[^_]Ít&O&UxO륉ƋE䋻 9tU\OE 9tUJOPPju,4$@ƋЉސ&UWVSeFu,'@$R QqOuЉU9ыwMQ(U9ˆUA(MU9ЈEuԋuЋ} WE?M䍃 j?PAP@M䍃4 j:PAP@M䍃 jPAPs@EЃ%EuЃP.jPEP8@ jEPEP@EVPB.jPEP?E juЃP?MԃEuԃP-pj&PEP? j=PEP? jPEPh?u$vhPjV)WV&4$.XZjW|*EEԍe[^_]É'EЉE9t&} WE>M䍃 j?PAP>M䍃 jPAP>ẼEũP,jPEP> jPEPl>EЃEuЃP,j PEP1>FEVPV,SjPEP= j>PEP= j=PEP=X j>PEP= j:PEP=u$vhPjV(WV1%4$ -Y^jW(Eԃe[^_]EEԍe[^_]Í/PEPj+t&/PEPJ+Rt&/PEP*+t&/PEP +t&/PEP*t&/PEP*9 EV,uԃPPjW'4$;RRjW'4$: EV+uԃډt&UWVSEAUH} Wc:M<$.P $U2UĉƍWPRV9EjVPr,MAtP?mEǃjPȃ(PC,MEEAt" V5e[^_]ÍvEEE܃ PEv:M܍ jPAP>;<$&.M܃ PWAP%;M܍ j3PAP ;Eԉ$RRURP*}؃uhPjWl%uW"<$X*Eԃ ;cju%M j~.} ;u+ W#v' H딍&UG˃ W)Eԃ ;tUGRRjuF%PPEjP"4$~8‰ԉfUVSEu>PTPV-a Vu jjuP/E ;u e[^]Ðt&U8Ge[^]ÉƋE ;tUG V7WVSX>h]'u [^_Ðt&x$ W"R 9Pjj t$U2)t9 W"R 9ud$Pjj t$ 2[^_É' WG"R 9u;Pjjt$1f P҃if P҃두t& P҃뺐t&UWVSW=gt$0~u [^_]Ít&h$ P4$4XZVWPa0T$$ U! L$ R 9Pjj v,D$t 'th U7!R ;T$ uyL/1QRPt$0/+$T$FXV\VWP$Dž[^_]Ív t$-뇍& P҃Kf P҃yfUWVS<t$0~,u [^_]Ít&@$D$o P2$N3YXVWP,$;  L$ R 9,M11QRPVh(.$T$&UVC6$ V9|.+$T$ F0V4t$R ;T$ uL]1QRPV'XZVWP(D$ǀ[^_]Ív P҃1f P҃멐t&UWVS:õ\up8t e[^_]Ít& V5O*P$P$P(3ZYPV&Eht1:t* H;ƧiŸ)A PV1E-ŨvRP‰EUEEt&~XFT9t!EԍvEԃ 0K2EE9u,MEUąwt8x}̃uvWP XZvWPFL~H9t>E'9}t(@;t RЃ9}u&M̃vQP#uF121҅xN`Fd)9} xFT R0 V.9|ŨvRP,FH~L9t=E&9}t(W@ 9t MȃRЃ9}ԋMuݐt&M̃vQP0A( P-e1[^_]EE8M̃uvQP *+EMUăuvQP44$,E Vb%t8uDEE9E}EEԋẼvPR8Eԃe[^_]f G=P%tYO| P1GF V-khPEjPEIXZPuZpYRPfZYWPmZYRPNZYhPQZTYRP2Yu.% EVU#EmD) uԉ.4$@/UWVS5Ÿ t@t]1E1ҋH$XVRPQt?t W'e[^_]Í& P1t8tPW#P7jjP&4$!Rt?t W)' VM.UWVS4ŷHEPE}'E/U B B$BEA P"EЋMЋA;At'M PQPQRPEЃ@MЃ AE @uEupe[^_]Ð&}h<PjW jPV. jPV.XZuV<$L,t&}hHPjWI jPV1. jPV.XZuVd<$+e[^_]Ð j#‰EċBEЋEȋ+BBB iEEMċUƉAAq M9ftFGFPGP 9uuԋEăxPE,}hPjWYXP4YZRP%YZVP,<$*t&=UUU V"E 'u Pu!}= WV*4$+ WC*4$*ƃ u.%4$*ƃ u( W*ƃ PV)XYWu[!S'Eċ@t P9렍t&UWVS}04uWF EE E܋EE*E<$P,%E؃ 9u/JU܃RPME 9u e[^_]Ð&U(9Ǎ9e[^_]ÉNjE 9tU8 W)NjE؃ 9tٍU8ύ&'UWVS0%,E} p;pt^tAGPFPGFYXG PF PqXFZWPbEpEpe[^_]Ð&WVuމNjEԋF ;EtU 8 W(NjF M9tύU7Ő&S:/Jt$D$p [ÍUWVS/,E} p$;p(t^tAGPFPvGFYXG PF PaXFZWPREp$Ep$e[^_]Ð&EWV PډNjEԋF ;EtU 7 W'NjF M9tύU6ōt&WVS|$t$ .0 w$ZYVPFG$%_ZVPR [^_fffD$ffffffffffff D$t PR ff D$t PR ff1ffffff D$P$ f D$P( ffffffffffffffffffffff1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffS+Út$[fSj+zt$[fSJ+Zt$h[fS*+:t$H[fS +t$([fS*t$[fS*ڭt$[fS*út$[fS*ÚlD$P[fffVSY*ilt$V4$c[^ffffffVS*)Xt$ F ;u V$[^Ít&T$2 V $[^ffffUWVS)Ǭ,L$@yq9tDD$D$ t& 9t!F 9tT$ 29u捴&L$@yt Wt ,[^_]ffffUWVS')7,L$@yq9tDD$D$ t& 9t!F 9tT$ 19u捴&L$@ytL$ W L$ Q <[^_]ffffUWVS(×,D$@x09t7D$D$ 9t 9tT$ 09uD$@8t W] ,[^_]fVS()XD$ @P;u [^Ðt&dt&HȅۃD$PRȍvHqpfffffUWVS'å }7G9tt  PR9wut P e[^_]ÉƋt Rk  V fffffffWVS'(|$ G 9uG 9u)G 9u7[^_ÍT$/G 9tܐt&T$o/G 9tΐt&T$W/[^_WVS&è|$ G 9u 9u"[^_ÍvT$/ 9t䍶T$.[^_VS9&I`t$ F$ ;u# FV$[^Ðt&T$.ffVS%`t$ F$ ;u+ FP4$ $[^ÍT$/.ffffffUWVSg%wt$0|$49>t3 j(t .tE ;u UT >[^_]Í&T$-ffUWVS$u~tREu P}W PWv E ;u e[^_]Ít&UH-e[^_]à jfQ ZYPFP눉ƋE ;tU- VffffUWVS5$E,u} 9>tP jt=Et4@ x PEԋEЃ ;u" u>e[^_]Ív'Uh,ԉƋEԋA;tUL, VfUWVS#Õ$u}u V <$5 PWVe[^_]NjA;tU+ WfffffUWVS#%8u u}YZMԃ HQV uu V!XZWVhe[^_]NjA;tUR+ WffffUWVS`,y"É QKdEEEEG~V EE`EG,,Dž0X GZjPYXF4P4ЋVjPFV8@,PDž<Dž@DžDDžH DžLDžP,P4`P 48T$`DžX8 \XZWE 1'RP(PZY( ;WumP ,P4`P 4`8\ ; 8FV@,FV4@4FV ,@,d`XEe[^_]t&jPi(%(G&(,:Y|Ƌ( ;t &' R4$ W_XFP `d `4$RWƉ,,ffffUWVS`,é QkdEEEEG~V EE`EG,,Dž0X GZjPYXF4P4ЋVjPFPV@,G Dž<Dž@DžD,G4DžHDžLDžP`G 48T$ `DžX8 \X8ZPE ''RP(PjXZ(P;uG ,G4`G 4`8\ ; 8/FV@,FV4@4FV ,@,d`X(Ee[^_]&jP(U$Ddt&Hȅ&PRr 뷋HH͉Uk(t YXFP d `D4$|WƉ,,(A;u 4$;dytRR&RP뿋QzyffUWVSuÅ$uu VXZuVe[^_]NjA;tU" WfffUWVS%0Eu jljEЍPVE<\$t&jPVvjuV jPVxXZWVEЃ<njPVKe[^_]Í6jPV. juV ӍvjPVfjPVFjPV&jPVjPVjPVfjPVFjPV&G^ EWPEEY‰EXEPPR XEZpPVE䋋 9E 9juV}JPjPVXZWVEWPcY_jPVRE pPVBE ;UUfU߉MMEEЃjEEPV juV}QB ƋE䋋 9tU߉MpMԋE 9u V*ƋE ;tUBUWVSÕ0u }jPVEDEЉ<\@&jPVvjuV jPVXZuV-G<njPVe[^_]f6jPV juVэvjPVvfjPVVFjPV6&jPVjPVjPVjPVjPVEЃ ^!ERPEdEEXEZPPQyXEZpPV:E䋋 9E 9juV@WjPVXZuV/&EWPY_jPVE pPVE ;UPUCYU߉M3M8vEEjPVD juV6oQ, ƋE䋋 9tU߉MMԋE 9u V ƋE ;tUfffffUWVS0u }jPV +rEԍjPVv ue[^_]Í&jPVN YXWV}tGw$njPV" e[^_]Í&EWPXZjPV E pPV E ;tU듉ƋE ;tU VF fffWVSt$Ĕ|$9>t% j|tt PR>[^_ffffffUWVSEbr8} EPuJ EP UWUЃ PWR FEuP }W PWv< E ;u[Ut$ jtEt PRe[^_]Í@PBPR:ft&U(뛍 jFY_ PFP6E ;tUPPjuM4$ ffUWVS}8uW E pPEP Nt~EWP EPE PuvE ;u5Ut$ jdtEt PRe[^_]ÍU j&YZ PFPYƋE ;tUPPjW14$yffffUWVSE8} EPuEP UW}UЃ PWR FEuPb}WI PWvE ;u[Ut$ j*tEt PRe[^_]Í@PBPRft&U뛍 jY_ PFP_6E ;tUYPPju4$ffUWVS} Ò8uWpXEZu PNEWP$EPE PuvyE ;u8Ut$ jtEt PRe[^_]ÍvU뾍 jYZ PFP?VƋE ;tU;PPjW4$ffffUWVSEb r8EԋuPME 8 W PEWPFEuP}W PWv@E ;u_Ut$ jtEt PRe[^_]Ív'/jPEPh`vU(뗍 jFY_ PFP2E ;tUPPjuM4$ffUWVSu (}VXE Z0EPR YXVWU t$ jtEt PRe[^_]PPjV<$fffU1WVSs Ã8u~P:uQ}hPPjW j PPE j5Pu<$E xWPv9tx}hUPjW j&PPEF pPuV jUPRkF pPuY<$1e[^_]É W4$ W4$ffffffUWVS% 58uVuFFe[^_]Íh<PEjPE jP jPZYWXuQ낉ƃ u?4$fffUWVSeu8E@POue[^_]ÍhHPEjPE jPW jPWZYVWXue[^_]Éƃ u4$BfUWVSŊ8uu e[^_]ÍvhyPEjPEV8 jPW> jPW,ZYVWsXue[^_]Éƃ u4$fffffUWVS8}G+9E EЋE !Ph:PEjPEX j.PV{ jPViYXu Vƍ< jPVJXZuVT jRP-Yu E9Eu19u !Pt[u+u E~9Eԉ}Vu}E Uԃmʃ:8 u͍e[^_]Ðt&h=PEjPE j.PVnW jPV\XZuVƍu jPV=YXu VƍQ jPVXZuVcZTYRPDXu u4$x u4$effU1WVS(u~PuP}haPjW| j Pe j@PN<$& vFe[^_]Éƃ W4$fUWVS%58E0t  PRE 0t^}hPjW jP jPXZV<$NExp9tDEEЉM t& 9t!F ;EtUЃ 9u捴&Ext W]e[^_]ÉEƃ WuԃEpx9t1E㋋EЋG 9tUЉM M̃ 9uEpt V u3fUWVSõ8u6"t PR 6Eu e[^_]Ít&hPEjPE& jPW jPWZYVWCXue[^_]Éƃ u4$jfffffUWVS,E0N0 wyEԍEj PVƋE׀8u5Eԋu, jRtC9u,E 0"& j&Ett&1e[^_]ÍEhPEjPE j4PXu}r룉ƃ u4$FfffUWVSŃ,u~tv jnuP}haPjWP j P9 j@P"<$ vFF 9u"F 9ue[^_]ÍUe[^_]ÍUԉEE WF 9tUhF 9tUV ufffffUWVSÕ,u~tv j>uP}haPjW  j P  j@P<$ vFF 9u2F 9u Ve[^_]Ít&UhލUXĉEE WSF 9tU(F 9tU ufffffUWVSEU8EPPDu e[^_]ÍvhyPEjPE8 jPW jPWZYVWXuze[^_]Éƃ ub4$fffffUWVSÕ8uFPu Ve[^_]Ð&hyPEjPE8 jP jPZYWXu뀉ƃ u4$GfffUWVS,uDF jiv@;~tv j'uP}haPjW  j P j@P<$ vuFF 9uCF 9u) Ve[^_]Ðt& VЃ萍t&U@͍U0볉EE W+F 9tUF 9tU ufUWVS}"2~4u@u WES jPWCE;( 1~PuPhPPEjPE j PWv j5PWdZu;E܃xWPv%9trhUPEjPE$ j&PW F pPWǍV jPWF pPWXuE܃ ;ue[^_]ÍEWVՍt&Uhe[^_]É u]E܃ ;tU4 VE܃ ;tU ׃ ufffffUWVSu2B| E xEPPVbYXVuV<$ PWVCXEZVpE䋻 9uE 9u e[^_]ÍUhE 9t捶Qe[^_]ÉƋE䋻 9tU!E 9tU VfffUWVSuBR{8u } 7VDPEPE\ uPV 4$wE䋋 M9u(E ;Eu5G PR e[^_]ÍUXE ;EtАt&A‰ƋEƋE䋻 }9tUE ;EtU VffffUWVS5EzT} TwNwDEPEG}ԉEЍEЉ$WEqEĉ4$PEXuȍZuPV4$uVa! jPVE؃ WVPu܉<$V3( j PV} uVWE<$pE䋳 9upE܃ 9u~E؃ 9Ẽ 9Eȃ 9Eă 9Eԃ 9E 9e[^_]Ív'UE܃ 9tqE؃ 9{vYẼ 9qvAEȃ 9gv)Eă 9]vEԃ 9SvE 9Ive[^_]ÉNjNjE䋳 9tUE܃ 9tUE؃ 9tUẼ 9tUtEȃ 9tUbEă 9tUPEԃ 9tU>E 9tU, WNjlNjE܋ 9hU[NjNNjS NjTE̋ 9@U3Nj8fUWVSv,uDV j~@;tz jGuThaPEjPE& j P j@PXu wGG M9uTG ;Eu9 W Ve[^_]É' WЃؐt&UH뽍U8뢉 u3G U9tUG ;EtU VffffUWVSE֍}/u@P2PWXEYp@EXW}WS jPW,E;( 1~PuPhPPEjPEw j PW_ j5PWMZu$E܃xWPv9trhUPEjPE  j&PWF pPWǍV jPWF pPWXuE܋ 9u5E؃ 9ue[^_]ÍvEWV̍t&UHe[^_]ÍU8"QgNj(ǃ u#E܋ 9tUE؃ 9tU WE܋ 9tՍU˃ ufUWVSEurD}PV\YX8 VPWEp@<$}WERS jPWE;(& 1~P\uPhPPEjPE; j PW# j5PWZuE܃xWPv9trhUPEjPE j&PWF pPWǍV jPWF pPWXu\E܋ 9uIE؃ 9uWEԃ 9ue[^_]Ðt&EWVt&Ue[^_]Ð&UE؃ 9tU량NjSE܋ 9tUE؃ 9tUEԃ 9tU WK uE܋ 9tUU뫉Nj볉 Ɖz u?fffffUWVS}brp@E pEPIPWXZW}W4$ PVWsEY^p@W}WES jPWGE;(% 1~PuPhPPEjPE j PWz j5PWhZu?E܃xWPv)9trhUPEjPE( j&PWF pPWǍV jPWF pPWXuE܋ 9u@E؃ 9uNEԃ 9ue[^_]Ít&EWVt&UXe[^_]ÍUHE؃ 9tU0먉]Nj& u!E܋ 9tUE؃ 9tUEԃ 9tU WE܋ 9tÍU빉E؋ 9tU멃 ulNj댉[ffffUWVSuòm(}VE p0EPRYXVWPU t$ j<tEt PRe[^_]PPjVZ<$fUWVS}"mTu FXV\EEUPWV7 7EURPEPEu̍ uPV4$uV@ jPVE؃ WVP<$}W jPWXEZWpE܋ 9u?E؃ 9uMEЃ 9u[Ẽ 9uiEȃ 9uwEԃ 9e[^_]ÐUE؃ 9tEЃ 9t&yẼ 9t&aEȃ 9t&IEԃ 9t&1e[^_]ÉNjFNjE܋ 9tUE؃ 9tUEЃ 9tUẼ 9tUEȃ 9tUEԃ 9tU WjNj륉tNjNj뾉NjEЋ 9tUY{ffUWVS}âjTu F0V4EEUPWpV 7OURPEPEu̍ uPV?4$uV jPVaE؃ WVPa<$}W jPW3XEZWpuE܋ 9uBE؃ 9uPEЃ 9u^Ẽ 9ulEȃ 9uzEԃ 9e[^_]Ít&U(E؃ 9tEЃ 9t&Ẽ 9t&Eȃ 9t&Eԃ 9t&e[^_]ÉNjFNjE܋ 9tU}E؃ 9tUkEЃ 9tUYẼ 9tUGEȃ 9tU5Eԃ 9tU# WNj륉tNjNj뾉NjEЋ 9tU{ffUWVS}"hXu V0YEUXEPWV 7DURPEPEu̍ uPV4$uVA jPVE؃ WVP<$}W jPWXEZWpE܋ 9u@E؃ 9uNEЃ 9u\Ẽ 9ujEȃ 9uxEԃ 9e[^_]fUE؃ 9tEЃ 9t&yẼ 9t&aEȃ 9t&IEԃ 9t&1e[^_]ÉNjFNjE܋ 9tUE؃ 9tUEЃ 9tUẼ 9tUEȃ 9tUEԃ 9tU WjNj륉tNjNj뾉NjEЋ 9tUY{ffUWVSåe8hbƍ@4$EbdƆdžƆdždžGdždžF4O GʉEЉM̉@FXZQjRYXGWF@DjPGWN MЋ@PFFFFP F F$P4 FV4F F($`F,F B F0XZuuEY_0Eu P EZYpPEEԃPE ;ue[^_]Ív'Ue[^_]É;cKMЉNjQM̉ d F4u4$<$E ;tU7PPju4$ uЉEXZWRVẼfffffffUWVS5EcEݕ@Eݕ8D@D%=<8<04D-D@ϋ<<89wi)׉w 3vp ljP0dƅDžƅDžDž FDž$Dž(VN Bp(,pDžtYXBjPmNxXZQx$N jR >VNBPpDžB DžDžDžDžpB4DžB xB|$B`DžAY|B |XQ0`x @D@WDŽ|,lj`$@5d,EEEEA(EEE`B,,Dž0XBYjP$Y_J44 jQ}BP,B Dž<Dž@,B4DžDDžHDžL`B DžP4AT8 $`DžXB8A \XZ8R@ 4 @<8WDŽ8,XPZP82XTP hWXV[ j PXP YXVWXZjV]^XE PWq\lj4$ jP\PXZVWYXjVXEZPW'`lj4$7 jP`PYXVWSXZjV^XkPWZY Pdlj4$l jPdP1YXVWXZjVn^X8WpZYPu%^l_jP襽T ;P ;P ,P4`P 4`8\ ;W 8j(Y@,$ 4@4,,@@,d`QP pP4P x`| ;M | Z@p$(x@x,p@0pdwEe[^_]& uE e[^_]t&9)&D@ ~'<ȋ8 T&04؃ ރt&SX PPjVDPPljP葺T ;t OP ;t Ov  4$,ƉpW(pd 04$D(QQjVm$PPjVYPPjVEM dXFZPAXƋ,(,@,d @` YXFP몉xUfUWVSEUXEEEUсƁمIΉЉ HƉ)Ɖ)9Bƒ(p lj P@荷dƅDžƅDžDž FDž$Dž(FV p<@8pDžtXAZjPVY_Jxx4ȋNjP0VNB,P(pDžB DžDžDžDžpB4DžB xB|$`DžA||B DXZQ@xE@\$<$DŽ|Y,lj$`$D觵dE8EEEA@;tz j蓹uThaPEjPEr j P[ j@PDXu wݻGG 9uCG 9u) WPE e[^_]à WЃ萍t&U͍UMM뭉 uG 9tUM_MԋG 9tUJ VUWVSÕLt3 j訳t .tE ;u UԨ>[^_]Í&T$7ffUWVSwÇGt$0|$4L$8F;FtJtPFPVP1)u7[^_]Í)RWPލ)9D$)Љ‰L$ T$ t$貴L$ T$t)‰u~LV)uD<t P躧.l$~n@D$)Љwt&RT$WQL$ET$ L$뜐&RT$PU!T$g=?l$)Չ1.fffffffUWVSEt$0|$4V;VtFtBBFD$80B)u 7[^_]Ð)PWR胷㍶) 9D$)‰T$ t$"ŋD$T$ )tD$8ujVL )u8<t P&.l$~nIfD$)fRT$WQL$轶T$ L$먃QL$t$U螶L$ x?(T$)…!щD$17fffUWVSWgDt$0|$4L$8F;FtJtPFPVP1)u7[^_]Í)RWPލ)9D$)Љ‰L$ T$ t$蒱L$ T$t)‰u~LV)uD<t P蚤.l$~n@D$)Љwt&RT$WQL$%T$ L$뜐&RT$PUT$g=?l$)Չ1.fffffffUWVS跿Bt$0|$4L$8F;FtJtPFPVP1)u7[^_]Í)RWP[ލ)9D$)Љ‰L$ T$ t$L$ T$t)‰u~LV)uD<t P.l$~n@D$)Љwt&RT$WQL$腳T$ L$뜐&RT$PUaT$g=?l$)Չ1.fffffffWVSt$$A|$9>t% jܬtt PR>[^_ffffffUWVSŽ@\MpgẼ 9jEЃ 9tEԃ 9~E؃ 9E܃ 9E 9E xP u֍E}EvPW苣XEZPPEPEBM؍ PuQM XEuPEi jPuUЃ WuRU<$}W4 jPWҴZEYWPE jPu说Xu覠Eȃ 9UẼ 9&UEЃ 9fEԃ 9vUE؃ 9zfUE܃ 9pv'UhE 9^v'UH3Lve[^_]ÉƋtƋEȋ 9tU Ẽ 9tUEЃ 9tUEԃ 9tUE؃ 9tUE܃ 9tUE 9tU VglƋy ƋzE̋ 9fUXYƋ^Ƌ_ƋdEԋ 9>U 1fffVSIY=t$Vf4$^[^ffffS*= D$P[fffVS< t$V軣4$[^ffffffS誹ú< D$P|[fffVSyÉ< t$VK4$胝[^ffffffUWVS7G<t$0|$4L$8F;FtJtPFPVP1)u7[^_]Í)RWPۭލ)9D$)Љ‰L$ T$ t$rL$ T$t)‰u~LV)uD<t Pz.l$~n@D$)Љwt&RT$WQL$T$ L$뜐&RT$PUT$g=?l$)Չ1.fffffffUWVS}蒷â:(W胱E 0tg V> PEVP=Wu.U t$ jtEt PREe[^_]v/jPEPر뙉PPjW4$bfUWVS׶9t$0|$4L$8F;FtJtPFPVP1)u7[^_]Í)RWP{ލ)9D$)Љ‰L$ T$ t$L$ T$t)‰u~LV)uD<t P.l$~n@D$)Љwt&RT$WQL$襪T$ L$뜐&RT$PU聪T$g=?l$)Չ1.fffffffUWVS7G8 t$$L$(l$,ϋV);Vt9t(UQV5L$  [^_]t&t EVVfUWVSǴ7,|$DD$l$@D$ uH& WŘt.w URGw ;t΋T$ Ív,[^_]ffffUWVSGW7D$4xPT$ D$8T$D$ht&|$t0Gp9F)Qt$ PؕDƅy̋ uЋD$9D$ tK@p9FQPt$蠕)D…x D$0T$D$0[^_]&D$0T$ D$0[^_]ffffUWVSUe6,E xEԅEPE܉UBtB‹zEUw9F΃QWu܉MߔMU)DxB 1Ʌuɉ׉}UEEuFUPuu蜔U؃)օDƅE8@Ee[^_]}ԍE 9x t0 WWE}ϋPE܋ApE9F낉}u9uEVrx9F)QRPD1xz jעƍ@uP胙uuVW^E @E0@Ee[^_]E`1 jXƍ@| P肩4$芕肖 VªfUWVS5E4EE@p91>*t Q P˟t$j\u辟e[^_]Ívuh{PjV艕 j3Pr4$J롐t&褝ǃ V)<$UWV,SO_3lj`P$dEEEEEFEE`N Fʉ, @,Dž0XAZjPzXZV4z4VωjWEV~B ,PDž<Dž@DžDDžHG DžLDžP,G4`G 4BT8$I`DžXYB8B 8\XR$gE p0ZYuaG ,G4`G 4`8\ ; 8 @,4@4 ,@,d`X$Ee[^_]'+5Q"C Ɖ,Q,d $`}4$赦 W4$蟦롃 {XFZPXfUWVS/ t$$l$(|$,):I'vWԚt]vWtRvW讚tW 9tp6W蕚uD$ 0D$ [^_]v'ݍvD$ 0D$ [^_]D$ 0D$ [^_]'D$()t8ttDD$ T$(D$ [^_]uWt,uWޙtuWșuD$ (.l$$UWVSwÇ.|$4t$8)D$<(uD$ -t&G9ptPG9ptxG 9p9|$ 9puЃVUPuD$08D$0[^_]fVUPŌuD$0WD$0[^_]&VUP蕌rD$0W럍&VUPmVD$0W tt&t$ D$8)ttVtFD$0L$8ED$<j9hte9hu׃URPuŋD$00D$<jыT$<Hj9t밃QRT$P轋T$ u뷃URT$P衋T$ u뛋t$4HfffffUWVS臩×,t$4D$8l$0|$<)D$ vt7p Ft7pFt7pϢF t7p谢;t$ xT$8)t:ttMD$8E[^_]t7pZtCt7p=t&t7p u'u[^_]u[^_]uӃ uffffUWVS+|$0D$49trut Pkv)t$*t V P t$j\ue[^_]Ívuh{PjVɃ j3P貙4$芗롐t&ǃ Vi<$!UWVS藞ç!,t$@|$DD$D$ 9u "f9t 9tT$ 9u,[^_]ffffUWVS5E! uP҆Yu1҉XZVjE ;tU21' P腆sE ;tU V蹇҄ V詇ffffUWVS%}u o@$}t"u: Wփe[^_]É'u W܋ t0Wft0뾃uz uP讅$RZu‰蹉_XVj迀E ;tUkE ;tUޕɃ V蠆 uP4Yu1҉GXZVjME ;tU蔕' PqE ;tU[F V6 V ffffffUWVSuÅ}u n@$}t"u: Wփe[^_]É'u W܋ t0Wft0뾃u| uP$RZu‰_XVjE ;tUfQ1iE ;tU<' V uP蒃Yu1҉襇XZVj~E ;tU݁1' PEMpE ;tU跓袁 Vy蒁 ViffffUWVSՊ ,};} utKt;GPFPHrYXGFG PF P3rXGZPFP$r9} ue[^_]8]F M9tUF ;EtU PI9ut ufE9uu5oE볉蓀 VjfffffUWVSՉ LE}p;ptBFFPFPAqFFYXFPF P,qXFZPFPqEpEpEԍGPEPEpGY^E܍G PEPEpXEZWPEpE@H+M p܉)$ỉEą~AF~FWV]}XFZFFPFPH}YXF PV9};}ĉuEԋM uP}YE܋M ^Au P|XE ZuP|E䋻 9uE 9uE؃ 9ue[^_]ÍUڍUڍUڋE)i̅u )֍M PxEut;GPFP|oYXGFG PF PgoXFZWPXoEuu 0lxE Wpu lEEH09EԋMĉE"F 9uQF 9u=9utIF 9tڋUЍ 9u E ) U跏빋U譏륋Et QkMUȉMHEUBmEWF 9tUNF 9tU< u~MtM ujk P{~t*E9ljt- V菁9u PM~ VqEu묉 u )օEEEԃ P4$FE 9tU^E؃ 9tUL VEċVƋˉEċ |ˋF 9tUF 9tU u~Eƃ PD}U $S[...\n[ DEATH ] basic_string::substr%02X(null)\023autoTERMxtermxterm-colorxterm-256colorscreenscreen-256colorlinuxcygwinyestrue[0;3%sm[----------] [ RUN ] %s.%s, where %s = %s and ]]>]]>]]> 0 failed. ) was requested, )../src/gtest-internal-inl.hpthread_mutex_lock(&mutex_)failed with error pthread_mutex_unlock(&mutex_)Invalid shuffle range start : must be in range [0, ].Invalid shuffle range finish : must be in range [pthread_key_delete(key_)./src/gtest-port.ccOnly one stdoutstderrevent=TestCaseStart&name=event=TestProgramEnd&passed=event=TestPartResult&file=&line=&message=event=TestProgramStartevent=TestStart&name=Value of: Actual: Expected: Failure Unknown result type thrown in Unknown C++ exception, you tried test cases.%s %sevent=TestEnd&passed=&elapsed_time=msevent=TestCaseEnd&passed=[ OK ] (%s ms) %s from %s (%s ms total) TESTTESTS[==========] test casestest case%s from %s ran. (%s ms total)[ PASSED ] %s, listed below: %2d FAILED %s YOU HAVE %d DISABLED %s <>&'"&#xDeath test: Result: failed to die. Error msg: Expected: Actual msg: Exited with exit status Terminated by signal (core dumped) ./src/gtest-death-test.ccWARNING: has value "". has value , which overflows. , but have left unset. < , but you have Google TestNote: %s filter = %s Running %s from %s. The value of flag --Environment variable (ignoring case) Which is: The difference between is , which exceeds , where evaluates to , , and Expected: () <= ( vs ) != (), actual: " vs ") (ignoring case), actual: "not a substring of xmlunexpected status byte (CHECK failed: File , line posix::Close(read_fd())read_fd_ == -1detected threads.pipe(pipe_fd) != -1child_pid != -1close(pipe_fd[0])close(pipe_fd[1])Death test count (fastUnknown death test style "" encounteredclose(args->close_fd)chdir("") failed: execve(, ...) in ) < () >= () > ( is listed more than once. No test named You forgot to list test Test @-h-?/?--help|stack != MAP_FAILEDtestsuitestestsuiteCondition false failed. Attribute is not allowed for element <>.notrun /> <disablederrors this->size() (which is %zu)vector::_M_range_check: __n (which is %zu) >= this->size() (which is %zu)Global test environment set-up.Global test environment tear-downXML output file may not be null Could not write to the test shard status file "%s" specified by the %s environment variable. Invalid index (%d) into TestPartResultArray. Cannot generate a number in the range [0, 0).Condition range <= kMaxRange failed. Generation of a number in [0, but this can only generate numbers in [0, Condition sockfd_ != -1 failed. Send() can be called only when there is a connection.stream_result_to: failed to stream to ./include/gtest/internal/gtest-port.hpthread_mutex_destroy(&mutex_)Condition 0 <= begin && begin <= size failed. Condition begin <= end && end <= size failed. CloseConnection() can be called only when there is a connection.Condition sockfd_ == -1 failed. MakeConnection() can't be called when there is already a connection.stream_result_to: getaddrinfo() failed: stream_result_to: failed to connect to Condition sizeof(Integer) <= sizeof(parsed) failed. capturer can exist at a time.pthread_mutex_init(&mutex_, NULL)event=TestIterationStart&iteration=C++ exception with description "Attempted redefinition of test case All tests in the same test case must use the same test fixture class. However, in test case to define a test using a fixture class different from the one used earlier. This can happen if the two fixture classes are from different namespaces and have the same name. You should probably rename one of the classes to put the tests into different event=TestIterationEnd&passed= Result: threw an exception. Result: illegal return in test statement. Result: died but not with expected error. Result: died but not with expected exit code: DeathTest::Passed somehow called before conclusion of test is expected to be a 32-bit integer, but actuallyThe value of environment variable Invalid environment variables: you have Invalid environment variables: we require 0 <= Repeating all tests (iteration %d) . . . Note: This is test shard %d of %s. Note: Randomizing tests' orders with a seed of %d . The default value %s is used. gtest_streaming_protocol_version=1.0WARNING: unrecognized streaming target "%s" ignored. pthread_key_create(&key, &DeleteThreadLocalValue)WARNING: unrecognized output format "%s" ignored. Error while reading death test internal: Death test child process reported Read from death test child process failed: posix::Write(write_fd(), &status_ch, 1)waitpid(child_pid_, &status_value, 0)Cannot run a death test outside of a TEST or TEST_F constructDeath tests use fork(), which is unsafe particularly in a threaded context. For this test, couldn't detect the number of threads.) somehow exceeded expected maximum (Condition typeid(*base) == typeid(Derived) failed. Condition !original_working_dir_.IsEmpty() failed. Failed to get the current working directory.basic_string::_S_construct null not valid can be found in this test case. pthread_setspecific(key_, holder_base)fcntl(pipe_fd[1], F_SETFD, 0) != -1sigaction( SIGPROF, &ignore_sigprof_action, &saved_sigprof_action)stack_size > kMaxStackAlignment && reinterpret_cast(stack_top) % kMaxStackAlignment == 0munmap(stack, stack_size) != -1sigaction(SIGPROF, &saved_sigprof_action, NULL)Unrecognized xml_element provided: Condition std::find(allowed_names.begin(), allowed_names.end(), name) != allowed_names.end() failed. Bad --gtest_internal_run_death_test flag: Reserved key used in RecordProperty(): class, so mixing TEST_F and TEST in the same test case is is defined using TEST. You probably want to change the TEST to TEST_F or move it to another test using two different test fixture classes. This can happen if the two classes are from different namespaces or translation units and have the same name. You should probably rename one of the classes to put the tests into different test cases." is not a valid POSIX Extended regular expression.the test fixture's constructor This test program did NOT call ::testing::InitGoogleTest before calling RUN_ALL_TESTS(). Please fix it.Condition 1 <= seed && seed <= kMaxRandomSeed failed. auxiliary test code (environments or event listeners)... Google Test internal frames ...`````` 0@`````````````````````````P````````````````````````````````````````````````````000000000000000000000000xunknown file./This program contains tests written using Google Test. You can use the following command line flags to control its behavior: Test Selection: @G--gtest_list_tests@D List the names of all tests instead of running them. The name of TEST(Foo, Bar) is "Foo.Bar". @G--gtest_filter=@YPOSTIVE_PATTERNS[@G-@YNEGATIVE_PATTERNS]@D Run only the tests whose name matches one of the positive patterns but none of the negative patterns. '?' matches any single character; '*' matches any substring; ':' separates two patterns. @G--gtest_also_run_disabled_tests@D Run all disabled tests too. Test Execution: @G--gtest_repeat=@Y[COUNT]@D Run the tests repeatedly; use a negative count to repeat forever. @G--gtest_shuffle@D Randomize tests' orders on every iteration. @G--gtest_random_seed=@Y[NUMBER]@D Random number seed to use for shuffling test orders (between 1 and 99999, or 0 to use a seed based on the current time). Test Output: @G--gtest_color=@Y(@Gyes@Y|@Gno@Y|@Gauto@Y)@D Enable/disable colored output. The default is @Gauto@D. -@G-gtest_print_time=0@D Don't print the elapsed time of each test. @G--gtest_output=xml@Y[@G:@YDIRECTORY_PATH@G/@Y|@G:@YFILE_PATH]@D Generate an XML report in the given directory or with the given file name. @YFILE_PATH@D defaults to @Gtest_details.xml@D. @G--gtest_stream_result_to=@YHOST@G:@YPORT@D Stream test results to the given server. Assertion Behavior: @G--gtest_death_test_style=@Y(@Gfast@Y|@Gthreadsafe@Y)@D Set the default death test style. @G--gtest_break_on_failure@D Turn assertion failures into debugger break-points. @G--gtest_throw_on_failure@D Turn assertion failures into C++ exceptions. @G--gtest_catch_exceptions=0@D Do not report exceptions as test failures. Instead, allow them to crash the program or throw a pop-up (on Windows). Except for @G--gtest_list_tests@D, you can alternatively set the corresponding environment variable of a flag (all letters in upper-case). For example, to disable colored text output, you can either specify @G--gtest_color=no@D or set the @GGTEST_COLOR@D environment variable to @Gno@D. For more information, please read the Google Test documentation at @Ghttp://code.google.com/p/googletest/@D. If you find a bug in Google Test (not one in your own code or tests), please report it to @G@D. GetParam()TypeParamthrow_on_failurestream_result_tostack_trace_depthshufflerepeatrandom_seedprint_timeoutputlist_testsfiltercolorcatch_exceptionsbreak_on_failurealso_run_disabled_testsinternal_run_death_testdeath_test_use_forkdeath_test_stylefastGTEST_SHARD_STATUS_FILEGTEST_TOTAL_SHARDSGTEST_SHARD_INDEXtest_detail.xml**DeathTest:*DeathTest/*DISABLED_*:*/DISABLED_**N7testing8internal12_GLOBAL__N_123ClassUniqueToAlwaysTrueE Stack trace: cddddddcccd8dXdxddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd c gHhHhHhHhHhHhHghggggghHhHhHhHhHhHhHhHhHhHhHhHhHhHhHhHhHhHhHhHhHhHhHhHhHh(hHhHhHhHhHhHhHhHhHhHhHhHhHhHhHhHhHhHhHhHhHhHhHhHhHhHhHhHhHhHhHhHhHhHhHhHhHhHhHhHhHhHhHhHhHhHhHhHhHhHhHhHhfN7testing8internal26ThreadLocalValueHolderBaseEN7testing8internal26GoogleTestFailureExceptionEN7testing8internal9DeathTestEN7testing8internal16DeathTestFactoryEN7testing8internal23DefaultDeathTestFactoryEN7testing31TestPartResultReporterInterfaceEN7testing8internal24HasNewFatalFailureHelperEN7testing4TestEN7testing8TestCaseEN7testing11EnvironmentEN7testing17TestEventListenerEN7testing22EmptyTestEventListenerEN7testing8UnitTestEN7testing32ScopedFakeTestPartResultReporterEN7testing8internal27OsStackTraceGetterInterfaceEN7testing8internal18OsStackTraceGetterEN7testing8internal35DefaultGlobalTestPartResultReporterEN7testing8internal38DefaultPerThreadTestPartResultReporterEN7testing8internal12UnitTestImplEN7testing8internal17StreamingListener20AbstractSocketWriterEN7testing8internal17StreamingListener12SocketWriterEN7testing8internal17StreamingListenerEN7testing8internal27PrettyUnitTestResultPrinterEN7testing8internal17TestEventRepeaterEN7testing8internal24XmlUnitTestResultPrinterEN7testing8internal13DeathTestImplEN7testing8internal16ForkingDeathTestEN7testing8internal15NoExecDeathTestEN7testing8internal13ExecDeathTestEN7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEE11ValueHolderEN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE11ValueHolderEzD;@-\TJTDKTOdOtOOOP$4P@DPTPP|QDQtQdQRdR RDS|TSSS$DT\TTDUUD$VVWXXYYdZZTT[[D\(d\<\d\x]]D]t]],]d^4^d^ ^D ^x $_ _ _$!`8!4`L!`!`!4a!ta("bl"b"c"$e#de@#ed#ex#4f#f $fP$4g$g$g%g0%Dht%$j%l%l&lD&$mh&Tm&m&m&n&o'p((qT(Dq(q(rH)Ds)s)u*u*$v*v+vl+w+w+$w+Dw+dw+w,w8,w\,w,x,$x,Dx,dx-x4-xH-x\-y-ty-y.z.z.${.4{|/D{/T{/d{/{/$|D0D|X0~0D~1d~,1~d1~x1$1t2422d3P33343D3t34P4$d4T4t44Ԅ4 5TP5td5x555Ԇd66Ԉ6ĉ47|777<8ĎP88d88TT999(:4\:d::4:;t<<=8=dp===??@<@t@@AdLAԯABlBtBCdCԲCTLDtD4EĶLEԷE(F4FdGH4H$ItdIdIDIT0JxJK LtLMM4 NdNdOt(QpQQDQ0RxRSdSTT`T4TUdVTVV4 WDWW4X|XXY@Y$YYD Z \Z Zd Zt[L[[[$\t\\\0]x]T!]#^'@^4'l^d'^d*^*^*p_+_d._.`.<`T2t`2`2a$4at5b7Hb8b8ct9d9d9dT:0e:ed=Hf=fBgB0gCtg$DgHgIhdJThtPhQhRi4R0itRhiSi[i4^jdahkbkdbkblnLl$slyo{8p}ppԀpăpqsTstt44uxu$ud$vvěvĜ,wԝpw4wtw xpxDxxԟ yty zXzzz {Th{{D8|D|t4}~4\~d~T~d D\t dTԀ p$, d̄T`T D4 D T t     , @ T h!|!$!4!D!T!d!t!!!0!D!X!l!!!T"h"|$"4"D"T"d"t"("<"`""#$#D#d#8##8#4T$|$%%tt&&.t'8/'<4( >(X>)>)>*$?*\?+Bd/`D3D3E7E4;PFT8G$?pG@GA(HC`HCJDJE KTFdKGK4ItLILdK,M4LpMTM8NN|NONP0OTQhOROT,PUpPVP4ZP[R^S`PSdcTUcUtfUhVtk|Wm\x(_`a$@ab48cdTe|fDdjējj$jdkSAA AAN Q(B,A0H J(B,A0H ICA AA >$ >2ANXA HA$8>"8T>"Lp>`l>*Ah4|>.AA CNKA KA AA4x>.AA CNKA KA AA4p>.AA CNKA KA AA4$h>.AA CNKA KA AA4\`>.AA CNKA KA AA4X>.AA CNKA KA AA4P>.AA CNKA KA AA0H>0AA N$I(G,A0H CA48D>WAA FN8BTANSAA HH AK H AG 4 >bhAB Cq.R AAA A >>8 >TANSAA HH AK H AG 8H?TANSAA HH AK H AG ((?=ANZAA HHA4ANGB TH HA(H>ANGB TH HA@@HVAA NKB NCBA RH H AAHAA AAN0y AA AAA MDyAAB CB.c AAA J l AAA I 4>|/{AAB CC.S AAA I D>taAAB C\. AAA K ~ AAA A 4?@AB C.p AAA A DC̬!@AB CK.n AAA F H AAA E @0D|?AB Cr. AAA A j AAA A LIЮAA AN T,D0H j C AAH dC AA<I aAA N P,D0H [  CAE L CADEPU?AB FD. AAA F  AAA H 4LE(AB CB.W. l AAA J R AAA C DF>AB CB.W. l AAA J R AAA C 4F>AB Cx. AAA F DG>AB CE. AAA F U AAA C DLG( >AB C.u AAA J U AAA H @L<AA NHDD D$D(D,A0E,C CADG>AB CH. AAA H e AAA H D HD?AB Cz. AAA C R AAA K DhH?AB Cz. AAA C R AAA K 4H?AB C. AAA F (N/AHIEDF HC(,N,AEIEDF HC4@I>AB Co. AAA H (N-AHHDDD JC(N*AEHDDD JCDI- >AB C:.o AAA F U AAA H 80OL4AA NH D$D(D,A0E,C CA4TJPX>AB Cl.& AAA E (Ox-AHHDDD JC(O|*AEHDDD JC4J>AB C~.8 AAA A (4P/AHIEDF HC(`P,AEIEDF HC4tK "f>AB Cb. AAA A 8Kx#S>AB C{. AAA A n.LQ'kAA AAN0OAB Cf. AAA H 4pLTH#>AB C.y AAA G DLl>AB C^. AAA G D AAA A @L=AB Ct. AAA D W AAA A (LR (AA NE P AA|xR&AA AAN0{ AA AAG C4C8Aa +7M]Fb$u ]BL-V +xBN`oepy6?Gu&:BMn#IZs{!@HuLRo@*&/Ek&$Ch''-S-S (>uB#C 1E` ;g:i6y?YO 1a} 1a}BD994 &:U"/;H[emf7;!,Ae!'Ne$!L"@3e!L"@, b6M^-@ A0 +  ; "  C     H"{>.vK,8JUj BaM] m }            JBSb#<(i/+NZo|T#4&mRg"!#Zv;@Ul*Me E] $3*pSo!#Vu5!6/4+3p*+?} im9Q9n.-#b-#b*Um e|*2t#5*+&8\&<9.)5HV'R]{A2JYnz2t&$u"' $u"' $}"/ $}"/  0#=Os&<975/I[&<9C;)5Hbt&<9B#1HXly1IE\bxw 09 +6z_<;~&3%2zO6.4*o{6+1*lxr4d)6 ,R*/L63*nz%{!i3+E`4&,:L p 0      J  j  0   ' 0 :   a N_w]%R4L.50t               3!!Q8/ 83s|"+Me+c(nE}5$AP-D'?%$H_U$H_U$H_U!>\&EK c v!  $      "            #      !  !  2   'M%NW`x! sM"@Xm!!!!IM"@Xm!!!!IPx90!7WO'Du90!7I  !  !  2    #g'Ar0-,Fhu7-4R'h&eX2Afu;$ }(,AVm-EU$1Ec:\I8&ySD "  * %@ \=F """#EP}* PQ] e !             !  #'DO`U?~       4?    ,      :@N:4jGA !6ZzFG/        v        _Ni|{ Gq       D            >a%PG'JVm\O:+t}! P82y! P82y! P82y! P82y! :+K\k3%5A\_$L7 2AV&8Z 5vYmqFF3Pa{PhKbPG*p***BBBBJJKKKKKKKKH K K O P P P O O O O O O L M M NNNNOOO9ALOAOCCCCCCC<OAAAAAA? \O!?!?"?"J"J"J"I%aO&I&I&I&I&I'I'G(YO)G)G)G)G)G*G*G*E-JO.E.E/E/E/E/E/C0RO1C1C2C2C2C2C2>2:6O9C:><<OYO!L#% O*mL8O')  ,F@                    n .Hd            B%-BSe      6E82)}V!mIE@7o[$HV$FU90))!E8C6-}i_c"("3 ZC       I            ?]-9U9D6?ygs ,  @)7.LWK   B   E E  23ZZ "*oU>:x\}}0$($U>:x\}}##U>:x\}}#x#DH * U>:x\}} ## LKmec?"("3?Q!3tHzWv}eX:O^ v8 }5JY15JY1- *-@  ô  !ô&L  08o8\L ѝ 0` ooo.oP     & 6 F V f v         &6FVfv&6FVfv&6FVfv&6FVfv&6FVfv&6FVfv&6FVfv&6FVfv&6FVfv&6FVfv&6FVfv&6FVfv&6FVfv&6FVfv&6FVfv&6FVfv&6FVfv&6FVfv  & 6 F V f v         !!&!6!F!V!f!v!!!!!!!!!""&"6"F"V"f"v"""""""""##&#6#F#V#f#v#########$$&$6$F$V$f$v$$$$$$$$$%%&%6%F%V%f%v%%%%%%%%%&&&&6&F&V&f&v&&&&&&&&&''&'6'F'V'f'v'''''''''((&(6(F(V(f(v((((((((())&)GCC: (GNU) 4.9.2 20150212 (Red Hat 4.9.2-6)0. 0Pp 0@P`p 0@P` @`)3X0`nuPqP`[ck` e ` @+pZ`0C[[` [!p"D#$0%%+((}@*+0,%`-5.`/001345]9:-<?0)@BB|PE|G|PJQL W- a`chkphjzk0mnC oyr(r)s3@s)ps3sPuvwn xxxy{|mpp`pPX2p`Е0Оp *ޅ K^sp?std=%2@'21'2'2'2'2(22(2X(2s(2(2(2(2(2(2)29)2d)2)2)2)2)2)2 *2-*2R*2r*2*2*2*2*2+2+26+2P+2,2&,2E,2d,2,2,2,2,2-2%-2E-2e-2ń-2ƚ-2Ǻ-2-2-2.21.2H.2f.2΅.2ϣ.2.2s2 2 mG3S3\3^ 74Y 64_)  4c<  m4gO ) O0( 888888 )ݐݐݐݐݐݐ tl9l9l9l9l9l9AAAAAA wv'%H %'Yd4eq%lt%)C %E6 ??+3)&M'fq4u4?H {?0($%eof([?U4,es?tX5Q%24v6<%H71''=T;eqA:%^ltE%|)ITE %  EMp 6Q6  ?U#` &Y:& ']JuaNdHeC0(i%eofm6U4q/L6566J67d<7cg5 %zD8\} 1-8_8``8c}m8d;8qDJ;8sZe O8yq %8\2-8_`8cm8d;8qŐ;8sŐː O8yŐ % p  h ! *" CSѐ*#\ѐ %- y$( h!C != x z` {m |( y4; 6`_  f_ "  Um $ %B h%X h%b j 3 &(%2&p%7'&%B'D7 4(u S%} ( n% )7w  )H z0 ) ϕ9 h( ް* (d &*$ 4 %!/X hh)t Ok v * U%Wp +44 5* ,w%o * h+ $* א+ (Q*  ݐ*+  ,C*1 7 א+ۧ 2O U א+ 6Vm s א* : ݐ+o Ah אh'*} K# אhh'+; S+h  אhh+ [#% ) א'& dVI *'h? myi *'h$ vy6 *h'%iT D *iT ^ *iT @ ***iT | *''&  %( hh*%F< Q ݐhhh* %e k ݐ-D7 m.~P  ݐ/~P% ݐ~P% ݐ~P% ݐhh~P% ݐhh~P%'<ݐ'h~P%L\ݐ'~P%lݐh'%.}P "ݐ %0F *ݐ0F 2(lݐ'0F =Q ݐ'%0  fZ"(ݐ0  q3AGא1end y`fݐ1end  ^א0: ݐ0: -א01 n ݐ01 א0 h א0E Jh9?א0+ _JhX^א2D%sݐh'%2D ݐh0X Ehא2%<ݐh2i -Uݐ0 5y%א0 D5@אh0 U|Ydݐh1at k|אh1at lݐh0A hݐ0A zݐ'0A m ݐ'%0%DT/:ݐ0%UېShݐhh0%)ݐ'h0 ݐ'0%ݐh'%2n - ݐ'%3'%!ݐ0' ^:Oݐhh0'%)hxݐ'h0' zݐ'0' ݐh'%2 8ݐh'%0 ݐh0 _11Kݐhhh0%g dyݐh'h0 "+cݐh'0 9ݐhh'%0 Kݐ'%0"M dG"ݐhh0"M t;Fݐ0"M%9_oݐ0ȱ .ݐhh0ȱ  ݐhhhh0ȱ%ݐhh'h0ȱ !6ݐhh'0ȱ sOiݐhhh'%0ȱ Aݐ0ȱ 'M$ݐ'h0ȱ <]_ݐ'0ȱ Q+ݐh'%0ȱ vD^ݐ**0ȱ  3wݐ''0ȱ 1ݐ0ȱ `4ݐ+%m)ݐhhh'%+%A[ݐhh'h  *h'%4%y*h'%0&%hא*hh2|%y+ݐ0uv ' א0 %$G'(.א0  ,QGMא06%hf{א'hh06 I˞hאh06 XWqhא'h06%ihא'%h06 v hאh06% c1h8Mא'hh06 hfvא'h06%hא'%h03 %hאh03%/hא'hh03 Ohא'h03 -h8Hא'%h0 QQhaqאh0%>shא'hh0 .hא'h0 $:'ݐ''4޶%{ *tJ*** >G****޶ H****M% :*ݐ** '%5^(56zG6Y@C p6  ! (" h x  (ː#   %- y$(   !C !8 = x` {m | 8; 8`_ 6f_ 6 Um =!%B %X %b j 3 " !&(%2 &p%7S(&%B'D7 a%(u ""ː* U%U""ː+44 .("",w%oLu("ː + $( ##+ ( ('#2#(+  ,#J#P#+ۧ 2 h#n#+ 6/ ##* :##+o Ae5 ## '*} K##  '+; S $$  + [Kz%7$B$M(& d@b$(M( ? m$(M( $ v*$( <%iT P$(  iT $(  iT 8%(((iT _"%(M(M(& ~ %A%  *%)U%j%   * %~%%-D7 %.~P %%/~P%%%ː~P%%%+~P%%&+  ~P%&0&+  ː~P%@&U&M( ː~P%e&u&M(ː~P%&& <%ː.}P "&& %0F *\1&&+0F 2"1&&M(0F =1'"'<%0  f/1 ;'A'0  q; Z'`'1end yl y''1end & ''0: ݩ!''0:  ''01 !''01  ((0 5& 3(9(0E  R(X(0+  q(w(2D%I(( <%2D E(( 0X  ((2%(( 2i - ))0 5&r%/)5)0 D) N)Y) 0 Un r)}) 1at k  )) 1at I )) 0A 1))+0A |1* *M(0A 1$*/*<%0%D1H*S*+0%U'1l**+  0%)"1**M( 0 _#1**M(0%sy1** <%2n -7 ++<%3'%(1/+:++0' ^/1S+h++  0'%\1++M( 0' zO1++M(0' O1++ <%2 +,  <%0 Z1!,1, +0 51J,d, +  0%gT1},, M( 0 "1,, M(0 91,,  <%0 K| -- <%0"M d 1+-;-  0"M t1 T-_- 0"M%% x--  0ȱ 1--  +0ȱ -1--  +  0ȱ%v1.!.  M( 0ȱ 1:.O.  M(0ȱ 91h..   <%0ȱ l1..  +0ȱ 'n1..  M( 0ȱ < 1./  M(0ȱ Q=1*/D/   <%0ȱ v%1]/w/  ((0ȱ 1//  M(M(0ȱ ;1//    0ȱ 1/0    +% 1(0B0   <%+%1Z0t0  M(  б(0 <%ː4%G(0 <%ː0&% 00(  2|%E0 110uv M("1(10 %JM(A1G10  ,X `1f106% 11M(  06 IJ 11+ 06 X0 11M( 06%b 12<% 06 v (282+ 06% 5 Q2f2M(  06 v 22M( 06% 22<% 03 Y 22+ 03%/ 23M(  03  A (383M( 03 X Q3a3<% 0 6 z33+ 0%>{X 33M(  0 N 33M( 0 $ǣ 3 4<% 0 2B #434+ 0%Soq L4a4M(  0 Q1 z44M( 0%_с 44<% 0ɠ q_ 44+ 0ɠ%j" 4 5M(  0ɠ % #535M( 0ɠ%n0 L5\5<% 0n  G, u55  0) Z %55+0)% %55  +0)%y{ %56  +  0)% %(636M(0)% %L6a6  M(0)% %z66  M( =! <%5^566X, P9>7\a!3^7 O aG c N ן  c 6 G _ :  : Q "  E5 671!g7 " m )  aA  R7!7   W  7!7 G~  ?  &8:9 !J8:n!j:0!%. !+818^;Y!>8^ %<!6dec!9=f!9>hex! 9=ڟ!9=%!9 >oct!9@=j!9?J!9?b!"9?:!&9?!)9?:!,9?T!/9 ?"!39@=!69=!99J?H5!<9=!N:V8=W!Q:=!V:=!Y:>app!lY:8>ate!oY:=!tY:>in!wY:>out!zY:=!}Y: <;!7>beg!::>cur!:>end!::Ro:Sd:T1':\:e:h:iΑ8:=@];/;?;L %L. P;`;L %L3,wH?Qx;;LQ%G;3,wl@Q;;Ls^3,wɬ?Q;;L,3,w*?Q;;L%3,wQ<<L3,w=Q3<><Lu3,w4?QV<a<Lm% '%5^(3f&;_<<L'3;Ҷ<<LAput;.<<L<v>'%3;?Y ==_%L_%3,w;i>?,=7=L %3?t;?X=c=%L%3\;?)==uLuB=;?&=,L, l>Cp=`777Cp>`7:7:7:Csp!>`:::Chp@>`BBBC%p_>`@@@C:p~>`/A/A/ADp`MMM H)W?EL)[B>:B`BBBBES*)[7:?:7:`7:7:7:7:E )[:9?::`::::EZw)[@j?:@`@@@@E)[/A?:/A`/A/A/A/AF)[M:M`MMMM `@(F*\FM>N>O6FPXA>FQ>$FR:>&>%I_TpF6?; ,$F%$ % u$מF%$ %77$*ZF U ) {*\jG%%\*aF*^5%i*bF%"*cF%j*dF *_54*gF"GF4*nQzF;GF4W*uFTGFSW*|-)FFF h+`G%|+e5%+f5GC+lGG5GC+pGG555I_T15I_T258jgwH1strG<HGH<BT@ H5H%5 %L8U?4GKH[H%5 %L '%5^(5|H9D, F8\I9-8_N8a^);8qHH36;8sHH3696O8yHH36 %VT8h8i"IIH08\~I <;8qEIKIu6;8s[IfIu6{6 O8yrIu6 % @vI''%@oI ~I+6@rͦ%IIE666I_Tp'I *RJ F%*'(*p:^)%J+JK6(*BBJHJQ6.'I"IW*ZVXl>* K "I!+*I!P*F!3'* K"~*JJ6"~*JJ6662*oJJ6+IY%<-*nK;*];Z]3*iJ<*b5<*c5< ~*f'<}*g'\KX`*6N*B*Vw*tX*Q6"2*XX6]2*XY6X"2*YY66X+* 4X8Y>Y7+E*lXVY\Y7+F*(IXtYzY7+MA*I5 7YY6+MA* 4XYY6 %+E*(\ 7YY6+E*/XYY6 %+z*796%ZZ77X+!*;TE%FdQd77.]bdmd7 %3F7dd772'-dd7c70 #գcdd70 ,Ccdd71end5zc ee71end>{c+e1e70:G JcJePe70:P+cieoe701Ycee701bEcee70Mcee70+;cee72Dff7cOc0Xe8c)f/f70%HfNf7bAIgbfmf7c0 qscff7c0Ccff7c24 mff7c1at6scff7c1atHcgg7c0mS(sc4g:g70m[cSgYg70ncڑscrgxg70nkcgg70z [cgg70.gcgg72nKgg77219 hh73k&c(h8h7c720Mhbh7cc70"M}+c{hh7c0"M̪chh7cc2|fhh772i>hh72hi7c7bU#i3i772Hi]i7cc72F rii7c0zcii7c'2J,ii7[c3M =cii7c3Mcjj7cc.0jEj`B7BBc.djyj:B7BB.?,jj:B7BB7I_Tp5_6&6c $j%$'% '%<8\kD-8_N8a7L*8b7`8c7m8d8;8qKkQk8;8saklk8#8O8y|kk8 %VU<8h8ij7j % Hm H OOl j%ROl%SOl% TOlGHVkl/8GHZll/858)e/l:l/8;8#HCl/8 %NM|F_lhKbG%]3k=nj(bq!A8llG8(buh58llM8( yvlllM8G.|llG8G.lmG8S8vlG.m&mG8G.5mEmG8S8G-Tm_mG8 %(-iOlvmmG8)|zmmG8Olb=+mmG8I_Tp7jkt t_mցmjl֞lֻlk}7NOlL*F`FmFG;I`_tf_t-=j^nnY8T^nnY8_8nT^/nnY8}ne8_8n.^>ooY8k8.]$o/oY8 %3Fs:q8GoRoY8k82'hgowoY8}ne80 #MnooY80 ,Ynoow81end5{MnooY81end>Ynoow80:Gqn ppY80:Pcen+p1pw801Y[qnJpPpY801bcenipopw80B}nppw80+}nppw82D ppY8}nn0X"}nppw80% qqw8bA $q/qY8}n0 D5nHqSqY8}n0ѶAnlqwqw8}n24 -qqw8}n1at6$5nqqY8}n1atHuAnqqw8}n0mSN5nqqY80m[ Anrrw80nc5n4r:rY80nkAnSrYrw80zHnrrxrY80)nrrw82nSrrY8e821rrY83k>MnrrY8Mne820s$sY8Mn}ne80"M}TMn=sHsY8Mn0"MEMMnasqsY8MnMn2|'?ssY8q82i4ssY82)ssY8}ne8bUssY8e82T ttY8Mn}ne82Fp?4tDtY8Mn80z_}n]tmtw8}n'2J>"ttY8n3MCMnttY8Mn3MMnttY8MnMnI_Tp75j6U6m 41u4N47`47P7 3oIuc3q 7c=8\vI-8_N8a8L*8b8`8c8m8d8;8quu8;8suu88O8yuu8 %V'8h8iIu3Iu :u H3x H Ov Iu%Rv%Sv% TvGHVYv_v8GHZnvyv88)e(vv88#Hv8 %NMLKvhK2L%]3v=nIu(bq778vv8(bu8ww9( yv/w5w9G.|DwJw8G.Ywdw89vG.xww8G.ww89G-ww8 %(-vww8)wx8vb=Kx x8I_Tp3Iuv5 Mּwwvvwv}3NvL*WK`bKmmKuL;N`_Mf_R-=Iu^yy 9T^y$y 99xT^/:yOy 9x99nx.^>eypy 99.]yy 9 %3F$9yy 992'yy 9x90 #xyy 90 ,&x zz*91end5x+z1z 91end>΂xJzPz*90:GT6xizoz 90:Pnxzz*901Yxzz 901bxzz*90xzz*90+Px{ {*92D+A{/{ 9xnx0XуxH{N{*90S%g{m{*9bA{{ 9x0 "x{{ 9x0Eox{{*9x24 B{{*9x1at6qx || 9x1atH|Ux/|:|*9x0mSQLxS|Y| 90m[Ԣxr|x|*90ncRx|| 90nklx||*90z.zx|| 90? x||*92n }} 9921MH)}/} 93kxG}W} 9x920Ul}} 9xx90"M}/x}} 9x0"MSx}} 9xx2|}} 9$92i~ ~ 92T~.~ 9x9bUB~R~ 992+fg~|~ 9xx92F5~~ 9x80z x~~*9x'2J~~ 9zx3Mx  9x3Mx%5 9xxxI_Tp35Iu668x-8\P-8_N8al9L*8br9`8cx9m8d~9;8q9;8s99O8y9 %V#8h8i\\ ڬ HF H O \%R%S% TGHVlr9GHZ99)eY99#H9 %NMURπhK;S%]3'=n\(bqL99(bu9%+9( yBH9G.|W]9G.lw99G.9G.99G-āρ9 %(-9)Q9b=(39I_Tp\  eρڀ+}N㿀L*`R`kRmvR~S;U`_ef_j-=\^9T^,799T^/Mb999.^>x99.]9 %3F9ƒ992'͂׃990 #90 ,Zɂ%91end5>D91end>!ɂ]c90:Gڠ|90:P(Ղ901Y 901b'Ղل߄90"90+92D`2B90XC[a90%z9bAд90 vÅ90/s܅924 <91at6D*91atHDdBM90mSGfl90m[]90nc=90nkO ÆɆ90zi}90l;92n'9921=<B93k^iZj9920%990"M}`90"M ч92|,992iw921A99bU Ue992 z992F09~90zH͈݈9'2Jr93M,a 93M-8H9I_Tp5\668Kj68\.U-8_N8a7:L*8b=:`8cH:m8dN:;8qӉىf:;8sf:l:O8yf: %V8h8it%:t x H^ H O׊ t%R׊%S׊% T׊GHVx:GHZx:~:)eŠx::#Hˊx: %NMQWhK7X%]3?=nt(bq|: &:(bu`~:=C:( yXZ`:G.|ou:G.::G.:G.͋::G-܋: %(-b׊ :),:׊b=0@K:I_Tp%:t3F x &C3}%:N׊L*\W`gWmrWzX;Z`_xf_}-=t^-3:T^DO::T^/ez:::.^>::.]: %3F#:ύڍ::2'::0 #^Ռ:0 ,s7=:1end58ՌV\:1end>iu{:0:G(.:0:Pɕ:01YuҎ؎:01bo:0Pf:0+/5:2DLKJZ:0X5sy:01%:bA:0 Џۏ:0_Ɍ:24 :1at6Dh7B:1atH"ɌZe:0mSj~:0m[&Ɍ:0nc:0nkRɌې:0z:0:2nP4?::21TZ:3k\Ռr:Ռ:20:Ռ:0"M}ՌőБ:Ռ0"MՌ:ՌՌ2|:B::2i.4:2#IY::bUVm}::2Q:Ռ:2F̒:ՌN:0zb:'2Jp :3M !Ռ-8:Ռ3MՌP`:ՌՌI_Tp%:5t66+c8\A\-8_N8a:L*8b'`8c:m8d:;8q:;8s::O8y": %VD8h8i % Hq H O %R%S% TGHV:GHZ:;)eʔՔ:;#Hޔ: %NMZ^hK@_%]3R=n(bq;39;(bu{;PV;( yms;G.|;G.; ;G.;G.Е; ;G-; %(-J;),/?;b=ǞS^;I_Tp %F ֋9VF} %NL*e^`p^m{^_;a`_ꋝf_됝-=^@F&;T^Wb&;,;$T^/x&;2;,;.^>&;8;.]ʗ&; %3FQ>;&;8;2' &;2;0 #.+1&;0 ,oJPD;1end5sio&;1end>mpD;0:G( &;0:P#Ƙ̘D;01Y &;01b,h D;0##)D;0+ BHD;2D]m&;0XeD;0%D;bAʙ&;0 T*Ж&;0ܖD;24 K:'2D;1at6LЖJU&;1atH[ܖmxD;0mSЖ&;0m[8ܖD;0ncЖϚ՚&;0nk}ܖD;0z' &;0 Ė,2D;2n-GR&;2;21gm&;3kv&;2;20i&;2;0"M}M؛&;0"M &;2|1)!,&;>;2i\AG&;2\l&;2;bUD&;2;2O&;2;2FϜߜ&;:0zD;'2JEw(&;3M?@K&;3M@cs&;I_Tp %56z6vAvcAwA{;A;A;A;A;A"<A=<AS<An<A<A<A<A<A<A =A$=AC=Ab=Ax=A=AŒAaA=A=A">A=A>A<>Q8\&a-8_N8a@L*8b@`8c@m8d@;8q˞ў@;8s@@O8y@ %V?28h8il@l  HV H Oϟ l%Rϟ%Sϟ% TϟGHV|@GHZ@@)e!I@@#Hß@ %NMcߟhK~d%]37=nl(bq<@@(bu @5;@( yFRX@G.|gm@G.|@AG.@G.Š@AG-Ԡߠ@ %(-!Fϟ@)$@ϟb=8C@I_Tp@l+s% pߠ;+}@NϟL*c`cmcd;f`_pf_u-=l^%+ AT^<G AA T^/]r AAA.^> AA.] A %3F#AǢҢ AA2'u AA0 #͡ A0 ,6١/5)A1end5 ,͡NT A1end>١ms)A0:G A0:P)J)A01YʣУ A01bd)A0)A0+'-)A2DEBR A0Xkq)A0[%)AbAW A0  ȤӤ A0Y)A24  )A1at6vb/: A1atHcR])A0mSEv| A0m[6)A0nc A0nkӥ٥)A0zR A0g)A2nV,7 AA21oLR A3k}͡jz A͡A20i A͡A0"M}͡Ȧ A͡0"M>͡ A͡͡2|9 A#A2i&, A2AQ AAbU%eu AA2o A͡A2F.ħ A͡@0zݧ)A'2JG  A3M?͡%0 A͡3M͡HX A͡͡I_Tp@5l6 Вa_dkidQndo4Np?`qJf_yըۨ!D/f_!Df_!D'D31a@)/-D3EGM-D3Fek-D3MA03D!D3MA±.u!D %3EϬ?3Dĩʩ!D3E.{u!D %3Efu-D3Aj3D(3!D3FuKV-D0}FR3Doz!D0-DPd[8\gh-8_N8a/AL*8b;A`8cFAm8dLA;8q dA;8s"-dAjAO8y=HdA %V/8h8i5A K H H O %R%S% TGHVëvAGHZҫݫvA|A)eکvAA#HvA %NMj hKk%]3x=n(bq\ AY_A(bu>|Av|A( y7AG.|AG.ȬAA7G.ܬAG.AAG- A %(-7BA)r(UeAb=yAI_Tp5Al[ ֶ B+_|l}5ANL*j`jmjk;m`_궴f_뻴-=^flAT^}AAJT^/A>AAҭ.^>ɮԮAA.]A %3FEUAAA2'L(8A>A0 #~'QWA0 ,2pvA1end5MA1end>{A0:Gg2ͯӯA0:P&A01Y 2 A01bC&*0A0>IOA0+k@>hnA2DYA>ҭ0X:>A0d%˰ѰAbA A>0 4 A>0-8A>24 MXA>1at6p{A>1atHA>0mSlA0m[OֱܱA0ncPA0nk2A0z ޭ39A0RXA2nBmxAA21A3k6HAA20вA>A0"M}o A0"M"2A2|NGRAA2iAgmA2#A>AbU AA2˳A>A2F7\ALA0z>.A>'2JCNAޭ3MgfqA3MA>I_Tp5A56W'68\:p-8_N8aAL*8bB`8cBm8d B;8q$*$B;8s:E$B*BO8yU`$B %VH8h8iŴAŴ  H H O( Ŵ%R(%S(% T(GHVյ۵6BGHZ6B ɾ8ZCw֔}AN(L*q`qmqs;$u`_ɾf_ξ-=Ŵ^~`BT^`BfBbT^/˸`BVlBfB.^>`BrB.]`B %3FTxB +`BrB2'T@P`BVlB0 #ݞ&io`B0 ,2~B1end5x&`B1end>;2ƹ̹~B0:GvmJ`B0:P,}> ~B01Y|J#)`B01b>BH~B0DVag~B0+R=V~B2D`BV0X8Vĺʺ~B0z%~BbA`BV0 !,`BV0mEP~BV24 ̺ep~BV1at6`BV1atHq~BV0mS- ϻջ`B0m[T ~B0nc\ `B0nk.,2~B0z KQ`B0.2jp~B2ne`BlB21 `B3k#&üӼ`B&lB20'`B&VlB0"M}ͽ&!`B&0"Me&:J`B&&2|!_j`BxB2i˳`B2y7`BVlBbUᖉν`BlB2-`B&VlB2F `B& B0zV6F~BV'2Jq[f`B3Mjl&~`B&3M&`B&&VI_TpA5Ŵ6<6[ 4^W4<4N4l9`4x9Pl9 q3o2c3q 7 4t^W4<4N4א`4Pא E3hc3j 78e8\FMw-8_N8aBL*8bB`8cBm8dC;8qC;8s C#CO8y'C %V8h8iP; y Hv H O %R%S% TGHV/CGHZ/C5C)eё/C;C#H/C %NMxhKy%]3W=n(bqHdAC8>GC(buSB5CU[MC( yrxMCG.|GCG.GCSCG.GCG.GCSCG-GC %(-!GC)84DGCb=Q!XcGCI_TpP;K ֐! >[K}P;NL*x`ymyz;D|`_f_-=^EKYCT^\gYC_C)T^/}YCeC_C.^>YCkC.]YC %3FqCYCkC2' YCeC0 #006YC0 ,bOUwC1end5sntYC1end>p.wC0:G$.YC0:PwC01YSRYC01bPD wC0g(.wC0+}GMwC2DsbrYC0XywC0L%wCbA4(YC0 HYC0 wC24 r,7wC1at6OZYC1atHTr}wC0mS]&YC0m[wC0ncYC0nk$wC0zYC0c17wC2nYXLWYCeC21lrYC3k&YCeC20YCeC0"M}:YC0"MgYC2|Zm&1YCqC2i}FLYC2 aqYCeCbUtYCeC2<YCeC2FYCC0zL wC'2J=O"-YC3M־EPYC3MLhxYCI_TpP;56n6{ b44N4B`4BPB }3oc3q 7 40^W4<4N4'`4P' %3hHc3j 7 S44N4;A`4LAP;A e94^W4<4N4/A`4FAP/A =D3oc3q 7 83hc3j 7 )4(4N4@`4@P@ P4_4dN4d`4dPd [4vex~vr/&<I_Tp@vh %T@7@uG~8\k|~-8_N8aML*8b9D`8cDDm8dJD;8qbD;8s&1bDhDO8yALbD %V8h8i* H H O %R%S% TGHVtDGHZtDzD)etDD#HtD %NM$hK%]3|=n(bq!'D]cD(buzDzD( y};DG.|DG.DD;G.DG. DDG-$D %(-3;FD)wYiDb=L}DI_Tp*p ֵ$F/cրp}*NL*)`4m?G;f`_f_-=^jpDT^DDNT^/DBDD.^>DD.]D %3F(D DD2'@^,<DBD0 #U[D0 ,tzD1end5D1end>YD0:G6D0:P6*D01Y6D01bw*.4D03BMSD0+RBlrD2DYDB0XyNBD0wT%DbA"%DB0 2 DB0g1<DB24 _Q\DB1at6tDB1atHDB0mSTD0m[@AD0ncD0nkYD0z7=D0%V\D2n q|DD21F$D3kSDD20NDBD0"M} D0"M9&6D2|KVDD2ikqD2mDBDbUB_DD2jDBD2F] DJD0zhB"2DB'2JGRD3M_juD3MDBI_Tp*56J6  ?q44N4M`4DDPM L3oc3q 7J/8\p-8_N8aE;8qNT-E;8sdo-E3E O8y{-E % *@v%@o +6@r%DI_Tp *[ F%*(*iݐ.4E(*אKQ E.W*Z X@** !+*!P*F!3'**"~*9E"~*9E?EEE2*w9Ee} 9E %+Y%<-*n<;*]L@Z]3*r<*b5<*c5< ~*f<}*g}%&G2GI_Tp N*r*F!)*>`*N*א* w** E"2*E]2*!E"2*1<EE+* >Y_E+E*w}E+F*E+MA*rHEE+MA* GE %+E*(ZEE+E*/E %+z*7%5@EE+!*;Ю%]hEEI_Tp616e +`%|+e %+f%GC+l8GGC+p8G>G#7I_T1 I_T2%^|^0Z0se%0t ~0g}0h+0i:0j=0k_0;0f_0-0*_set0E`set0E?EEI_set0EE0F0EEE0/0=21E0+|0Ab=7=E0 0E IV\E0 0NGGUu{E1end0WTUE0:0`mE010i+mE00@%E00pyE0+0y/5E2|0JUEE00nyEE%00UEaE2"M0\0LEU0"M0lRyEE2"M0EUU2i0c*0E0%0UyITEE060=UmxEE060"@aEE0ʾ0.1UEE0ʾ0aEE0X0lUEE0X0W a!,EE00EEPEE002[itEEfߦE %05p5_ +`%|+e%+f%GC+lEGC+pEE#7I_T1I_T2%V 4Z4N48`48P8 a144N48`48P8 ˴44N4=:`4N:P=: i44N47:`4H:P7: F464N4:`4:P: Z4m4N4B`4CPB #44N4A`4BPA 744N4@`4@P@ ͐44N4ݐ`4Pݐ @i6I@'',@: +6@>16alDG6+6@Bq6DG6I_Tp'6 54^W4S4SP~S `4^W4B4BPB 4"^W4k4kPk @8R8MH77_ @iqI@u@: R+6@>!`G+6@B `GI_Tpq |b`^CFd`888Cd#`l9l9l9CdB`AAADbd`ݐݐݐǤ3g3{ 7I_Tp8 $4Q4Ӧ8414B8P8YB%!3g3 7I_Tpl9 !44Q4l9414 l9Pl9YB% 4`^W4<4PB g)@E>)Dl9:l9`l9l9l9l9E )Dݐ:B`ݐBBݐE)Dݐ:B`ݐBBݐE)Dݐ0:ݐ`ݐݐݐݐE)DAa:$u`A$u$uAEEP)DA:A`AAAA4=q)D18:8`8888Y[%3g3 7I_Tp7: P4=Q47:414Ԯ)7:P7:YB%3dg3Z 7I_Tp: 4ѨQ4:414Pp:P:YB%$?3g3 7I_TpB G4Q4B414@BPBYB%E3:g30 7I_Tpz 4~Q4z414ԡ!FjzPzYB%3g3 7I_Tp@ 4Q4Ӛ@414@P@YB%3g3 7I_TpA E4TQ4A414@@APAYB%v3{g3q 7I_Tp/A GY4ѿQ4/A414_A/AP/AYB% 3g3 7I_TpM ʾ4*Q4M414:MPMYB%J3Qg3G 7I_Tpݐ [4ѕQ4ݐ414V]ݐPݐYB% 94^W4<4N4*`4}P* @44N4B`4 BPB 3h&c3j 7%*33Mg35C 7I_Tp8s33tg35j 7I_Tpl9\33g35 7I_Tp7:33g35 7I_Tp:.933g35 7I_TpB3:g3= 7I_Tpz 4TQ43z414|@zPzYB%I33{g35q 7I_Tp@33g35 7I_TpASo33g35 7I_Tp/A33g35 7I_TpM 33g35 7I_TpݐH`5 N@97:MI_Tp%:=:=:7: Z^9:vI_Tp %'': _9BI_TpP;BBB 9@I_Tp@@@@ {9/AI_Tp5A;A;A/A9MI_Tp*9D9DMm qBMI_TpP;BBB <q7:vI_Tp%:=:=:7: q:I_Tp %'': Nq@I_Tp@@@@ q/AI_Tp5A;A;A/AqMI_Tp*9D9DM3>g34 7I_Tp733eg35[ 7I_Tp7333g35 7I_TpB6M%683( WV8GJUΓ L %bD rLV805 lbGJv K'%.ϓ 9?L0C XcGJ'%05 |L '%5^(biB)JLV8hHB~}LvLDEsJ!O666EE!K666EsJ!7,77 AP^(' At^('%EY![AQGQ66E}J!W66E)2!_AQGQ6Cb|E8$Bz,xO%RR a %6 '%^('  l '%^( a % '%^('  t;m;tmmtE14ɪK~StE 94KB v  yB;Z;yZZyE4`KkuC'I_TpݐȁȁEj .ҏ|ER HJ '%^(E'/BI_TpH68hk/^b8i^% % '%5^(5Astr~^X^| BNEsJ!w^7^7^7E$lF %Ev$ '%^(lFCaVz`777Ca`7I_Tp777)8CEz1`7:7:7:C^`7:I_Tp%:7:7:r:C]z}`:::C`:I_Tp %:::C1z`BBBC^`BI_TpP;BB)C r  (;D|; D|D| CzG`@@@C{4t`@I_Tp@@@@ChGz`/A/A/AC`/AI_Tp5A/A/ApA 0 h;f;hffh $%Pd'D'D V0%:Pd'D'DCAzY`MMMCç`MI_Tp*MMnDEA8%I_Tp'%EͲ'/8I_Tp38C\I_Tp38C[7z`888C-`8I_Tp3888Ey'/l9KI_Tpx9C0\eI_Tpl9CPz`l9l9l9C `l9I_Tpl9l99E/'/ݐI_TpC\I_TpݐCz`ݐݐݐC;5`ݐI_Tpݐݐ7C3O]I_T1I_T2ݐE)kݐ:B`ݐBBݐ 8)ݐ:B`ݐI_TpBBݐ7E BPB_/BB/E 94K'6Ek.ZE'''<Ek.rh:''' ٓP88 h I8YWr%88888 >m!P88 [8YWr%88888E !lPMM [MYWr%MMMMM /\]Pݐݐ IݐYWr%ݐݐݐݐݐ 7{!]"Pݐݐ u[ݐ^YWr%ݐݐݐݐݐER)kݐ:ݐ`ݐݐݐݐ d)ݐ:ݐ`ݐI_Tpݐݐݐ7 K)'ݐ:ݐ`ݐ_ݐݐݐ7E?'/א-I_Tp' E)':[::`::::: DWv:::::: @YWr%I_II@I_OI@@@@ h@YWr%I_II@I_OI@@@@ z@7I_II@I_OI@@@@El)k@h:@`@@@@ M)@:@`@I_Tp@@@@@ l)'@:@`@l@@@@ 0 v@@@@@@ ^/AVYWr%I_II/AI_OI/A/A/A/A k/AYWr%I_II/AI_OI/A/A/A/A T/AI_II/AI_OI/A/A/A/AET)k/A:/A`/A/A/A/A )/A5:/A`/AI_Tp5A/A/A/ApA ׏)'/Au:/A`/A/A/A/ApA A#v/A/A/A/A/A/A MYWr%I_IIMI_OIMMMM MYWr%I_IIMI_OIMMMM MQI_IIMI_OIMMMMEu)kM:M`MMMM l)M:M`MI_Tp*MMMnD H)'M :M`MMMMnD bvM4 MMMMMF?G u u  '%^(' 4  '%^(84!.;#>   %LU:#;    %L '%5^(jhex!X!X "!kX,!X%f! '%^(' P eF! '%^( ! '%^('%4 pz~S"~S_/~S~S/< A 4" '%4 pBn"B_/BB/<46 pwk"k_ 0kk 0< [ k";k_kkE6 k #Pk_ 0kk 0  B=#;BI_TpBB vݐo#ݐݐݐݐݐ / ~S#;~S_#~S~S#E ~S#P~S_/~S~S/ Gv8 $88888kI7eI$k1>aFlE1J7NDN;iR$'m4XELW$ '%^('nD814*K5$5T*NQ7$%55 sVD?$'4p1*%T5%5nD4%@ %oint' w_u?  nF0% G'%G %%G*%=G*%G* %kG*%G*!-KG*! G*!G* !KG*$!G*(!CG*,!2`Gj0!G p4!{YG  %8!TG %:-693% ]9V:a:-693 - c4-9y::!69ub  mGC::!6993+ q)9::-6b ::!696bU ;;!69I_Tp'9 aM_ <NMH-MH4 -M);];?64; MH|;?6);4;UM;?6);4+M #4;;964Mo96;96vMx;?6?6 TM<MII_TpIH, :=- =N ?K6L* @Q6` AW6m B]6 Oe<k<c6 Q{<<c6i6 V<<c6 %3% Yp%<<<o6=<3% ]ʆ1<<<o6I<3 - c-%<<=c6<ub  m'#=3=c6%<<3+ q<K=Q=o6b 1e=u=c6%<]6bU ==c6%<I_TpI <jn :4?- =N ?ݐL* @א` Am B O=>v7 Q>>v7|7 V,>7>v7 %3% Y=O>Z>7=3% ]w=r>}>7=3 - c=>>v7=ub  m$>>v7==3+ q@*=>>7b Z> ?v7=bU ?*?v7=I_Tp= ]M_@NM`L*M``M`mM'`-M_4 -ME??7q? Ma?7E?q?UMf?7E?4+MˆSq??74Mů7@7vMǮP@77 M@@MЌ`I_Tp QMa@MЮ`I_TpC6M@I_Tp7E?_WBZhݐ<<`<I<`_M_GNM kL*Mk`M#kmM/k-Mj4 -M>|FF)8F M F)8|FFUMe G)8|F4+MbF#G#84MŤ`#8IZh7<u<`uJ8 %3% Y=IVJaJ8I3% ]}IyJJ8I3 - c*IJJ8Iub  mgJJ8II3+ qIJJ8b KK8I8bU S&K1K8II_Tp3I :M_uLNMhuL*Mtu`MumMu-M\u4 -MLKK8xK MTiK8LKxKUMK8LK4+M•yxKK84M8 L8vM*U&L88 'MGLMuI_Tp3CcGMkLI_Tp38LK8IuWM NZh8</<`ENFL0F=uLWNbNFL01 F{NNFP8rF8xW]tPZh8<f<`|TB0MATBWT]TB0MA=d~SvTTB %0E^BTTB0E~STTB %0 STTBS0A 6|BU UBS0E ܉~S%U0UBS0}FBIUTUBS0F~SmUxUBS01BUUBPl9rFK6f6 :@W- =N ?7:L* @=:` AH:m BN: OV VT: QV(VT:Z: V8VCVT: %3% YU[VfV`:U3% ]6U~VV`:U3 - cUVVT:Uub  mDeVVT:UU3+ qUVV`:b AWWT:UN:bU 4+W6WT:UI_Tp%:U M_zXNML*M`MmM-M4 -M9QWWr:}W MWr:QW}WUME"Wr:QW4+M}WWl:4Ml:Xl:vM+Xr:r: MLXMI_Tp%:CKMpXI_Tp%:r:QWN:tWiZZh7:<<`\`FZ0}F-fFW\b\OFZ0FsZ{\\`FZ01rLUF\\`FP=:rFc :I^- =N ?:L* @'` A:m B: O]]: Q&]1]:: VA]L]: %3% Y\d]o]:\3% ]7\]]:\3 - c-\]]:\ub  mcT]]:\\3+ q\]]:b ^ ^:\:bU ~,4^?^:\I_Tp %\ M__NML*M`MmMʓ-M4 -MBZ^^:^ Mr;^:Z^^UM^:Z^4+M°0^_:4M":_:vMǴ4_:: DMU_M+I_Tp %COMy_I_Tp %:Z^:WaZh:< <`!A">A<>divAxdŒa,,Q :c- =N ?@L* @@` A@m B@ ONbTb@ Qdbob@@ Vbb@ %3% Y2bbb@&b3% ]Ybbb@2b3 - cbbb@bub  m% cc@bb3+ qb4c:c@b ,Nc^c@b@bU 5Nrc}c@bI_Tp@a M_dNML*M`MmM-M4 -Mqcc@c Mt d@ccUM_&d@c4+M #c?d@4M@Xd@vMǟrd@@ ?2MϓdMI_Tp@CzMdI_Tp@@c@lWfZh@<<`tF %0-sWtbtF s0A vF{ttF s0E KlsttF s0}FfFttF s0F3sttF s01F uuFPArFWCwZhB<<`K %{ AjXK %{ NjrK % v=%P7rFmkk =%̆P;ArF.r.r =%P8rF8xvv T:=%&P=:rFcXxXx =%SP'rF55 SPl9rFKtt =%PBrF{ F)=%ڇP@rF[ +kP/ArFuu p@/%4P@rF[ =%aPאrFc v v wBPאrFc v v =%PMrFLLE7N%و'' Y=%PBrF{YY =@3PݐrFc++  L`P8rF8xqq  sPArFMMEN%'%* @z؉PBrF{YY `=%PBrF /%2Pl9rFKtt mX_P7:rFc%% ;<_P:rFv $dP@rF[ I/%P/ArFuu 6%W;A/ArF.ru )bIPMrFLLX/%PMrFLL I!Jt%M(, J,M(, % GJf%΋M(, %yxO7|O8O}4}dvdv4}}};v;v}d %8P5J%4P9*%P:*%P@*%YPF* %&PG*%4PH*%PI*%PJ*%jPK* %PL*$%#PM'%(%'PN'%)%PP'%*%tNPR'%+%*PT'%,%VPV'%-%+P]'%.%DP^'%/%Pa'%0%pNPc'%1%*Pe'%2%RPg'%3%+Pn'%4%@Po'%5E P|*d %'~PovsQ( %4eQ7,tQ8f%cQ|Q}Q%EQ~Q%}Q_%>]QQ%QQ%;QX%QpQ %t % u'QX%zQX%8QX%oXQX% QX%eQ %KQX%Q %`QQ%zKK RKx%F$Kz%<K{MrR%t_%u' Sގ%F$S %EtS!-T<_% : TQ%TSv\TTT[ ӏ T\rTqmTsV%lTtC%%sTuC%scFTy4s Tz%T^ %%%T_Q%%.T` %%Tf % %XToQ%,sXT} sT~ӏs TX%t'%u' TTFCsT's T %HCTt'%-u'/d[TQ%t'%Hu't'%Xu'd*vXU %v{}'%}'v 1}2v2v}}}<%}S(v2}24v24v}vv' vv$ }$ }' }tQ%v{v8 v6v, v=!}=!}6}, v6BvH'v*_%}7v7V4_%52VzvuEAV %1'dElV1'1'oElVoΑ'ECVd'};v@v?v@}?}@v%}%v1AvB}BvBvYD}Bv%qWb c%JWc %remWd %!We=qWjЪ%JWkX%remWlX%ѪWmnqWv9Œ%JWw,remWx,:WygXmBqY)%4IY+Yے-Z% Wv %1uu.;G  Gj%Gj%Gp%G %v9v%t'%u'v1t'%u'' %*FO' fX[.%o[0%a[2J%%fp[5 %8[:%[;͍%\[@%(D[A%[E %a[GJ%(%[J؍,%[N,0%[P74%vo[[y8%[\y@%ł[]yH%A[m_%P%A[n_%TC%\ X`\ce]*_%O ]e!Z]j!G]m_%!E]p_%!]s !*[]x*!-\]~!-]&']Q%B]Q%]Q%]Q%]Q%h4]Q%v]Q%v5%]3$] %]ߕ!]!l]]1ڟ/REH!42'!r%!!(N(REWb11REs~11RE1'~RE1 %0N^'Ж֖1[6%11[56%11[2%6'1[5r%V'1* 8ju1'LFqs11   +/ GW Zo! o. Z2' %. Z2 %0w&\2282" Z HS2 2LF ^c2 2Ws 8ZXZ!_%Z!`ގ2>; آ22yB122M,2s 2yW' ry.'t=C2.&xT_2 %"'}oz2$2LF}2$2W4$!*2T4ƙљ/22.3/2 %"4/252LF/252øKM:M%Y%WSTvIntZ %<[Q%W`Intf,<gf%W8zϛ!%5T~ʚ՚+5%5.+5 %0E†15 750F%5)/751get?%5HN750%5gm+52+5%5"+5=5*FVǛ+5=5ITGҺ^:u^EO'':^f %''ɺ^l866M(:^t%VM(M(^|%v'':^v%M(M([%^%11F^I6ќ %^f6 %S^65%Һ^w5ߟ;7%6ߟ=BH}5ߟ>Xc}55/ߟ@s~}513FDF5}55SetI>}553PM^1ٝߝ53uvNC'5;Q#_W855 %'yN_X55j}55'3Woi%53gtAk53e|Zўמ53ȏSQ53 5'3(Mb%0653* %NT53]y<%lr53cy.%53%53U%Ɵ̟53O6%5)7}5(tƓz' 5ޟ+}5 %h h Xm5' %_5h }5 %Gh 55HF 55<s% ͢:A Sv Tm%O> U h? 5E 5@ 5 7 7$L 7$( 5u_ zΠT | 55[ו wm% &Rm%Max +m%0G 0B550g 3v 50> 63"(50D 9AG50{ <%`f50. H<%55Q= g5׾ s^â55m% 8 ݤ:A Sv T%O> U 쑚? 5E 5@ 5 G G$L G$( 5u_ zޢT | 55[ו e% &%Max +%0G 06 60g 3@ 60> 6E28 60D 9<(QW 60{ <UZ%pv 60. H[% 66Q= g6׾ s#7Ӥ66%ҢW !C %!K Z.  60  7N%9S6' %'' Nj'i6' %'W, CN Ox! CT, ȥ)7C2 oGݥ)7C0 C )7C", ')7/7LF ۊ7)7/7mhCEY%c 2 dxf   PvG: rg6[YD%'1' %G.O:7@>RY$:7 %m^[jYEK:7?RpnB %Ylr:7yq%Y:7%T|kYƧ:7DD_rD'c?1G :7JIHFf:7JI-jW%l6%M %!7] %! % -js@71 % % %S @7 %3T@Y1ƨF73k#^ %ިF73, %F73a % F7"-j0;@7L7LFoK@7L7%W &&7&'p7W&7&BM(p7GU3ީ7 %KqI; 8IKe:>ϭ178IۼVU[7.lr7"7>ILF7/7>IW ,TG_m! a..}8./}8 %2ۼW2}8"c-8}88LFcH}88WDz!ݐT~B9ݐ.B9 %0Eq_īʫH90FavݐH91getݐH90ݐ!'B92<GB9ݐ"WbB9N9*FvB9N9ITY|#pWzʭ!אT~ŬЬ:א.: %0EQ :0Fكא$*:1getאCI:0Źאbh:2W}:א"::*Ft­::IT' p uϭX RGU9& : %K:Z NH@F:.X W]:"X mx:PILF :PI:;S ر!fp %!r {.:;U خޮJ;U9;w J; %2{ J;P;0k ]P;8CJ;P;0J3\ ^E%\bH2F3] }wJ;% kJ;]HR rɯٯJ;]H %` J;]HQ b +J;]Hx ,ITJ;uH~ yr}J;1:2 WJ;8g h İϰJ;1:<  J;uH}  !J;]H : ?JJ;]H] 0 hxJ;]H % 6J;]H":;t J;HLFt ḺJ;HWN3Q!!T@H!k%!\F "6Ph;?' %'.alh;n;2FNh;n;#h; %!t;.N3IJ޲y;?' %'.M3y; %2F;_5"N3*5y;;LF,XEy;;ر0 _`%"_h;% _i%5_j0_c;69?;0_fƳ; %G0_lճ;;HF_l+;;Ph6VQ4<%%%?%%2%%56%x6% % %6%Z6%0%%56%H% %$%w;(%t%,%p0%W64%aJ%8Q4T@ P4 T@ %lZWZ!g6T_NYZ@106bQ%r}`@~9fZ@{bZ@ %#WtASyǼ65~6[%N %''[UP%#11-C(%1'  Ҷ!T@'!k %!6e A Be A %FB¶A B# ˶Ad<Ҷ!e R ^<G! 6.H!:!;=n !\?/!X+Bp@!xE !\I@!sM[H! QT!Wv`!\l!/_%x!Mc %|!4i5A!/o%:! %y!}!$9H!*%! %!!b!R!#!Q:22%Td<D3HUҶD %0'p@Ƹ̸D2CDp@00p@ D2' +Dp@0)~ %DJ?H0O~ %ci?H0fi2 %?H0f %?H0M1@ %ƹ?H0$X %߹?H0xx %?H0)C %#?H0=u %<B?H0T1 %[a?H0O %z?H0}:?H0;=q5?H0@%׺ݺ?H0D1(%?H0JC ?H %0YkQ|5A9DD %0vWV;]cD0Z}9|D0P^XV9?H2D9H09HڻD06D %0M5A7D''2+LaD%:0U3EHzD28D5A2:v D%:2LռۼD0f~B%D2ID2ja*0D2\bȎEPD~90Gg, %itD2D0CC?H0%:ǽͽD09;+:?H0IH#A D02asxB$*D02arBCI?H2_ ^dD08MF7}?H0yAD2'8 D2ҾؾD2^(D2D0i$ %'-?H0S! )7FLD2$*)agD2u @|D0|,8%?H*x3ED%"d<пۿDKHLFDKHW`!f@!ٳk@0ii!vp@T0U`G|@0N@yG"0GG*F1GG0G %.v@Tv@|@.$v@ %0NS@=Cv@0N`@\b@1get|@{@setKv@|@-ۿ-+m@@@"v@@*FG v@@ITp@WzL!@7T~GRA@7.cnA %0EAA0FzE@7A1get@7A0@7A2a9 A@7"%AA*FAa9DAAIT%W]z!AT~|AA.A %0EaAA0FAA1get9AA0R+AA2=c4?AA"OZAA*FnyAAITd(^GfdADIfdA@4gA %%A'1' %GQAW^R!f@!ٳӾ0ii!vT0GrB0Ne`BG"0GG*FIRGG0YG %.!'BT8CBrB.T_B %0Nq`Bx~B0N5~BB1getrBBsetBrB-ۿ-+k`B B"&BB*F:EBBYIT2Wz!BT~BB.B %0EZBB0FBB1getLBB0B%B2L:EBB"U`BB*FCtBBIT.Y>C18CGf>CBHf>CBFzBBHUs*3(B %06- FQB;~p9OouBJ<'B;)!XYFCB!O h %!i!j .FCD H;;U4I*H %0OHSH;*nPn 3gmH~p`#H"FClHHLFl/HH[F[ '.rH;;TuHBx=HH]H|pfqH]HRcH]H %]f H]H %xkHuH< HuH~h=HH1:gH fqH1:2H8*JKH;*xPH+H%"HH*Fu%0HHiCNH %W   u | 6 "W^2 !Ŷ HT^2 C'.]2 C %"^2 CCLF CCW6TIC1069%bmCCfHHQ6/H %}wG.}%9HU&;F9H %K^Qgw9H % %ɬ9H"}9HILF]9HIҶ#2 5m* 52($j H!!C*$.2@FcHK gwcH % %ɬ cH"2cHiH*F2GcHiH2cH %  )!e \FT -8oH']  VfoH]H % 6%'%1U %'%<C {C61%q 8861 ` hA61 a6'. 7,p7111 Gp7'k egp7'1:Ҫ p7uHpW N~p7]HSG OP6:" oH{H*F `oH{HoH % f>IHH. Z`Hr W}'' H]HR 2H]H %` H]HQ &H]Hx BBDOHuH~ mxH1:2 H8g  H1:< U HuH} o H]H k :EH]H]( ~ csH]H % H]HB ]HH %/nY  if &1VI\IT BMVI8 ]VI %i "?%'%,  %S ,r %'' `''  %D 8 % % tD5'' J! %P']T ('o % F % % F %D r % %*Q% D %'  % %uQ%*' F%$<%<% C?<%<% 5W %U%wv*%{\%v'%  ϭIT6Ę . %IE %8; % %c ITHo'  HITH:o'( CITJ5A p' Z  %sITҶ%Dq' , %sF`lsAlsj'sFNtAt C %sF8x`0w90w 6 %$sFc`x:xK%;CP%RCS'|sFcNy:y'sF{N kC  c'%  eIC,X% PCX %Eׇ%<% f%'%{r˩/'%p7 ZJuMITouuA!&e1p7 &ITp7 f%<%A!&k5p7H&IT, +p7FLIE %)7&;d*'-sF[NhAh ]s%C'% '%Y'%E6uIT(fCK1w- %w0M{]4/*''<%EQ %5s&OIT,Ep7oGQ):YJv9ne6' %e6EZ9'''n 6\8t o8G6''['' %4-%6IT,E{w6 %~%_5'qEJ('a./%L''%VJ|"3%p''q0d6'%'%G''''F ''11%i ;''''P d'''' J ''M(M(<& '''%%%Ê%s %''%%1" ''M(M(1I D''''Ѧ m''''%A m%''m%m%FSIT %:SITJ5AsSITP@6 3H %:I8 %{64&' %K*4|!Z6kIT*JDhy<GYibI:Z ''Kq,"{6G ''~m '', G'', L p''@ nw ''=%:''''ϭ: 5 )6' J ''Q&%<%:,3"bR?A:,Ve%'%:M3"_b>:M4yFGibIWX9D %-(j@7k kG]%'%:MBk %<%:,w(;?1m&hITHo'&(HITH:o'J&X+ITJ5A p'cr@Fs@EX % %&%8ITҶ%Dq'RcG5^H';cM %V]x Zkk96Ú2x {3x 4x ry2\VۭYx %Z y ?x[y |rW\+y (\]m )z 0n :z Ds/]z wllS{%'LVT'R0'T݅'IMV'/gWz /&Xz ./8Q%R% z L@PqwDP"xDPS7PU(ss_ϛYC5P]ciY5P`yY5_5/PeY5'3,we5Y5H3,w4e5Y5%3,wfe5Y5M(3,w8e5 +Y5(3,we5CNY5k53N`6flq5)FWY5_5{e5IT'Y56nse5IT %Y5:Use5IT'%Y5mse5&ITQ%Y583X'V\83a[%tz83d^%83da8%83dd&%84~k6'?fEZ  8 %fy3 $ 88F83 883( ~ %հ8x(l r 09b  098358  69 %3]D %  69G(  09<9HF 09<9D W˼!80%!r5Y.˼D O T9Z9T˼` k T9%07 _6%  `90E    `906E'  `905-z'  `90,w!f9  T9C5*P)sh * T9_5*F7> I T9Z9fʼW b T9 %Wf9  ITM(T9(f9  ITJGT9f9  ITT9059Zf9  ITPT9`0" 8f9% 0 IT3T98f9M X IT/T9_5f9u  IT?T9  f9  ITLT9\0,Jf9  IT'T96Df9  ITӏT9,.f9 # ITnT9~Ff9@ K ITT9іf9h s IT%T95,f9  ITvT9f9  ITT9"j=f9  ITT9f9ITdT9t֯f90;ITT9 f9XcIT(T98^f9ITzT9m.f9ITT9!$f9IT, T9+ [N.<#2aIV;P;+>G%ag\;*H{V;"ORV;b;LFR{V;b;bGfP;IfP;F> I%P;IU;FP; %DRdoP;]HR}P;]H %`FP;]HQP;]Hx P;uH~6AP;1:2__jP;8ghq P;1:<m P;uH} P;]Hn P;]H] ,<P;]H %QIVP;]H1_3_7 h %_Rx%_Sp@%%_TH T1H09.1'Hx09U0;g!H %\F!ig?JH8* .2^dHG1_Vs~HHHF_VHHJGfp@,Ifp@Fd<2Ip@,I@5%p@ %\>p@89|J'#3G! 6!rʭ!:c !Hv!$!(!f%,!R0! %8.9V 5A''Ub J)5A %0'BHC0Gi'agC0& #%C0M1+  %C0$X0 D %C05 . %C0): L % C0=? % ! C0D ; %: @ C0TI < %Y _ C0#D%x ~ C0&%  C0;)/  C0$i /E+:  C %0P1A:  C+Q8:!!5A+Q;:5!;!C+Hp CM%:S!^!5A %*&D&r!}!5A%*w !!5A%:* j!!5ANl!5ARun} ^{!!5A*^WQ!"5A*m[1y""5AU^(%5"+:_c%O"+:i;%i"+:n=%"+:\s%"+:Nx.\%"+:*$* P""5A)7*u l""5A"9# #5AuHLF#5AuHO$8aF%X#߻%}#, ++m^;#F&'&'p76N#F&'p7L%#''  $'%''66M& >$%''h r$, %''++L%$M(M(\5 M(%''((Q'#Q'#J|6'#/#(_$)#G!!D$9}3H1Run %E%K%3H0^6'd%j%QH0dFC%%QH0lf+:%%QH0s?2 %%%QH0y EH%%3H0)O9 %%&QH0OTڟ %&$&QH0fYB %=&C&QH0f_0 %\&b&QH0M1dB %{&&QH0$Xi* %&&QH0lw[ %&&QH0)qL" %&&QH0=v %&&QH0T{g %''QH0~3Q %5';'QH0}hT'Z'QH0;s'y'QH0]b%''QH0%''QH0C''QH %0Pf:''QH0vWH((3H+NY@1(<(3H@*v3$P(o(3H?' %11*\b((3H11+Yk5A((3H %+`3MD((3H+`3hZ?H((QH"#))3Hh$)))3H %*Z=)H)3H B*D\)b)3H"#r)})3H]HLF)3H]H$#A,f#))IIf#))IF.I)*II)$*/*I]HR.)M*]*I]H %`){**I]HQ3 )**I]Hx)**IuH~)*+I1:2)+*+I8g% )H+S+I1:<z )q+|+IuH}< )++I]HB# )++I]H] )++I]H %IE),%,I]H#)5,I %g) 'q,? 6, %5 6, %' +c,Y %g /c,Y %- -w7 K@%'-8"J%>-84,w:Ȯ2\-28K&OL6}-IT'6p4&O6-ITM((E,w2-2_5 6- %''w++ -_5YQ .''%%n E.''''' n.''''n- .''11'!t .''11`J  .''m%m%n(= /''k5k5'.! ;/''k5k5n  d/''M(M(' /''M(M(q&O6/IT,E^,c/1//:Mt1/:,[ 6076|%1017kU6k%%k3r%k%kۖ6kJ6k ެ_%kׯ6k@r'%k&k]ɜkfD%.%F ]%\6h%dk^%w Zw lkJ&w *w w[3w *w [.x Px P,0x PAx SRx 8v}}\Fvv}aF}tvyvv}2v}$3a _2sӋa" %saa#*a$;2a: qa?.;J4rtaF4aK2%;aL%?4aM aR2%oaS %%baT %%3aU_2 aZ3%;a[%?4a\%3a]_2abM3%;ac%?4ad%)"ae %%afj2 %Xagj2alo3%am*%t-anC%as3%!atX%%ԑau % az3%a{*%?a| %%ha}Q%saGJ4saN2sIaV2_rta^2syah3s)aoM3s"Navo3s%a~3%Ea@ %%aA %%G aC %%za2 t %Z4u'/;au2 bUp4vv44 % Wc4rc4sce4sWc!4%c#4%=5c+%c. %%)c154 %4*vZ4v4v5vFvjGvoG} 55vGv}Gvϛ}ϛvI52Y52v/}(}/}wHv(vԛv}7}v7y=56$5v5abiu5v<}&'v }5m%}7v͢}͢vҢ}5%}Gvݤ}ݤ}'}Hv9};v;vH}I}HvIvIvRJ}I}RJv <}=v=v"I}WJviJ}I}K}iK}Kv\Jv[Z}5K}wO}Q}[Z}\JvZ}[}o_}Zvo_}X]}]vvtX}Yv_}X}Zvt_}_}%v}T:7vYv%vW}Wv-v}vvvaFv=}4?v4?v_}`}_v`}a}`}av`vc}Ebvc}d}0d}j}cvjv7vv77}7}7vD}kFvkFvj}k}jvk}Zl}k}_lvkvm}mvm}n}n}t}mvtv}TvG}87vI}Gv3v? }3}? vI};Kv;KvIu}v}Iuvv}v}v}vvvv3x}dwv8x}$y}Oy}W}8xvWvD v } vYv}v }v} vv}}vP}DRvDRv\}}\v'}ʀ}'}πvvF}wvK}7}b}o}Kvovv}vvʭ}ʭ:vv vK}Kv%:vC:%:}%:}C:vU}@Wv@Wvt}.}tv?}}?}v3v^}vc}O}z}}cvv %} %}%v\}I^vI^v}A}vR}}R}vFvq}vv}b}}}vvvvvvb}bv}h;vرvQ}Q69vV}}  2W %;5EJd%;' KW %;' KWX%;'E e*"<uu&'&' jdivWc=< % % YW4*S<' Wn<X%X% W^ %<'&' Wi&'<('&' ) Wa %<('&'W<*&'&' wWv %Wx =Q%E݋W%$='MEgWX%C='M %E7qW_%b='M % HW %x=' uLWl&'=*M(&' We %=*<% WŒ=,, SW$,='E`W,>'M %EOWf%">'M %EzWm%<>'ME@TWt%V>'M f}> d h   g7>%g9 %%/g: %v}>7oh> W  -H A  ˘   0iJ% j?%@j>%\j?t'%.?u' j?  5P ?H  Or  r |i  [' n 7 * 2 d  U 1  2 k7=@!'k9 %!k: %!jk; %!k< % ! k=!8*k>=@!k?*!NJk@C@v>v?vO@?vv#v-p@vv}k@vp@vk@v}v@vPv@@}@}@va}cvcvl}&}lv7}ڟ}7}ߟv+vV}v[}G}r}}[vv5AvJvAA5A}5A}AAvh}jvjv}g}vx}}x} vlv}Ȭv}}}}vv}%vL}LvvQ}v(}(vAv-}A}-v:p}qvqvŴ}}Ŵv}3}}8vv}v}}˸}Ӿ}vӾv2vR}RvvW}vY}Yv~S}Bl9vCw}~SvB}BאvHw}BvP;vBP;}P;}BvMw}xvxv}F}vW}}W}vKvv}v{}g}}}{vvz}CBvc~}zv6vh~}6v}vvv$vm}C;Avm~}mvk}C/Avr~}kvd}D@vw~}dvu}v}uv?D*}*}?Dv|~} v v}k}v|}}|}$vpv}v}}}}vvvG}DMvk}Gvv{%}vҶvvv[}}[vp}vv}`vr}}7}}<vev|}V}}}|}ev}}}v}y}vVv}$W}CXv}<v}}@v}v`Z}}E,vuL}F8vՅ}uLv/v/vN}>F8vڅ}NvZ}[F=:v߅}ZvzX}xF7:v}zXv_}F:v}_vD|}FBv}D|vs}FAv}svf}F@v}fv 0v@}Gݐv}@v v}E}dv}vt'%ZGu'}JGvvy4v}y4v$u}GBv}$u}v} vY}E %GmvGpGvv}v}|v:7v}v}vK}d1v}ivi3Hv$vv}}v)}})v}v}$} v}v}Hvvv}A,Dv/}vn}09vg}F,v}v}N}S}v)}K,})}P,}vb}U,}v}}}}v}ivi}n}iKN'IN' N' II5B II5BII5B"I J5 J2#J(J5 J 7JBJ5BJv\JgJ5gJGJW J__p *vDvDJJ5JJDJJ5JEJJ5J JK5KKK5B.KCK5CKֹ%bIZKoK5oKֹ%GwKK5@ֹ%Al %K@lK*vKj$K! 0K4I 0 %vj>'L! AK4I A %; CjXKL! NK4I N %X ZLqL5K__a qLvD2ELL5Lֹ%vLvLL5Lֹ%Lv;vu;LM5Mֹ%MLLv^DgD-MLM5LMֹ%QMML?;eMM5Mֹ%ML{MM5Bm* IM Ih(MM5 J(1MM5 J1N*N5 Jm* I*N I +p!JN__p *q"YNpN5pN__a uNːM NN5Nֹ%VI NN5B Ah__s A'JNNO O!O5K 0OGO5K__n hVOaO5BzO__s)O‹__n) O__d d*__s d'__n dh'$7*P__p7*m7P**?P__a!O6__b!O6cP__a!K6__b!K6P__a!7__b!7PP5Lp V8,P^(P__s'PQ^(Q__c'%};`;*QAQ5M__nQ%}}6tqQ__a![qQ__b![6GQv7c8QQ5Q!BJ8%!DJ8vQQ__a!W6Q__a!_Q__b!_6GQ8R=R5Q!SJ8T!SJ8%!UJ88LRtR5Q!v%!x8RR5Q6!%!vERR5R__ca'%Rv}RS5SY,xSRR(S3S5HBSMS5MS2sjSch'%f %S 'Sv}SstSSSS5Gm* *SST5TrhsIT}55+T6T5BETPT5B'zT__s'__c %TT557ֹ%TT5Tֹ%A`TT5Tֹ%GƨU U5 UF7 U+U5 U:UEU5 UTU_U5>FnUyU5>FzUU5>FUU5>FUU5>FUU5k@ֹ%UV5Vֹ%H)V>V5>Vֹ%Hk RV]V5]V`9UqV|V5|V9sVV5V94VV5V+:SVV5VgVV5VC%WW5Bֹ% .WCW5CWֹ%H%,ZWoW5oWֹ%I(WW5.H(WW5WQH%WW5Wֹ%9HWW5H5A X$X5H%:3X>X5>X?HRX]X5HͽlXwX5>XXX5>XXX5>XXX5Xֹ%BXX5BY Y5k@ 3Y|<%<%$iY|<%<%OYs1's2' YY5BY'?Zd % Ha# H\1$ %ZT@D7Zfd %Q$ %aZ$'Y$'pZ{Z5VZZ5V`Z ' 'CZZ5ZHfZc '%[ ' 'b&[>[5>[=e] %J;R[][5>Xl[w[5>X[[5>XD[[5Hߝ[[5[5a[[5H[\5T)\\5VU0\;\5;\(HO\Z\5;\i\t\5;\O\\5;\n\\5\ %H\\5;\\\5\b ]]5;\$];]5\fd % J]U]5;\+d]{]5\fd %]]5]  H\']__s'__c %v5] 'buf]a^c\'%"^:^5G__s 2'6n^str'ren^@ߕ1vy^Q^Q;^^5Mdls^P>^^5>F^^5>F^_5_75_6_IT'56_N;_Y56sO_e_5e_p~ݐB9O y__5_%T9__5_H9ʫ__5_ __5]V*_`5`: `"`5`1`<`5VK`V`5VEe`p`5p`r9` '%^(C ' ```5`__n>A`a5a__n >A"a-a5-aAAaLa5LaA0`aka5`v~aIT6a '%^(k am* aabIT %56_valsbb:,w79bb %};b\bIT'%56_vals\bbpb{b5_}}Zbb5bbZ@{blb '%^(C b 'ec c5 c7f!c9c5 c__nczHcSc5Sc*9߄gcrc5rc9ۏcc5c__n:cc5c!cc5VHcc5Vdd5d__n : ,d7d57dD;ʙKdcd5cd__n &;wdd5dwCdd5d__n YCdd5>[<$ di &']Hٯd"e5>[<$ "ei &']H+6e\e5>[<$ \ei &'uHTpee5>[<$ ei &'1:}ee5>[<$ ei &'8e f5>[<$ fi &']HfDf5>[<$ Dfi %]H!Xf~f5>[<$ ~fi %]Hff5>[<$ fi %1:ϰff5>[<$ fi %uHxg,g5>[<$ ,gi %]H@gsg5>[ sgj %i &']HJgg5>[ gj %i %]HHgg5g~Bgh5h__n V`B}m2"h2h52h7hC h}BhQ%]h~hITQ%56_vals~hbj %2MjXj5Xjljwj5wjŐ3jj5Xjֹ%jj5wjֹ%Gjj5j__ij88nIkk5k8wo#k.k5.kY8GBkMk5k4H\kgk5jovkk5.k}IrkP7rFmC=k>kkkkk5kitXMn}8ll5H l8l57d__nnlIE %v.nli. %. %8;ll5lֹ%B;ll5M__n,&llIT,56_valslbE; m$m5M__f%M:m[mIT%56_vals[mb5|omm5Sc__nHxrmm5Vmm5|V"m^+:5"mc+:Åmn5rc__n*#n;n5rc__nHSJnbn5bn__ignBBxU{nn5nBCnn5n__inBBenn5 cdnn5 cDn o5 oB=3o!bCo!1b %=oCoHv3ooIT H 8 o6 '=o! o!1 %Hoo:vo pITH : 8 o6 '=.p! >p!1 %8p>p5Av.ppITJ 5A 8  p6 '~zpp5p__ip}CC6pp5p__ipC68pq5qC=)q!X=q!1X %%7q=qDv)qCqITҶ% D 8 q6 '0lqq5q__iqCCmqq5qCoqq5qCknrr5qnr)r5)rC}m~lrP;ArFC=lr>qr.r.rv_k4vrr5rvrrr5r__irDD4rr5rDrs5sWEOns3s5)r__i3sCWGsRs5`asls5`vrs%sCsssF`lscsls% %itAݺss5>Xtt5>Xt5Avtgt;m;t| mw m__f ttsFNtc't'tAbNtt5tFLtt5t__itF F}CwuK~Sut=&u1u51uv7>EuZu51uֹ%d`iu~u5~uֹ%73`uu5~u+auu5u7buu5u7/uv5v7-v,F}Hw+vKB+v vN?vWv5Wv__i\v2F8Fypv{v5Sc1zvv5ScPvv5vCF Ovv5vGOvv5Wv}څ̆&wP8rF8xC=&w>+wvvv6w%Fw8wsF8x`0wcw0w% %itx9Zww5w__iwOFUFww5c\wx5c\xx5x`F[3x>x5xL[MxXx5w}߅xP=:rFcC=x>xXxXxvx%x+: ysFc`xc yx% %it:~ y*y5V_ 9yDy5V$]yKC;vyPCy y$X %i % yj % y]HuH1:y%:vyAz;Z;y| Zw Z__f yVPzsz5sz__p U4I xzT:N:LXzI_Tp%:__aMz__pMQWYMzr:N:gZzz5z}FXz{5{__i {lFrF]{B{5B{__p \4I G{::U_{I_Tp %__aM{__pMZ^YM{::pa{{5{F_{{5{__i{FF|{|5|__i |FFt|*|5d69|D|5dxS|v|5v|__p ew4I {| CCy|I_TpP;__aM|__pMxYM|)CC|||5|C:c|}5}__p b4I }@@dW}I_Tp@__aMW}__pMcYM\}@@fp}{}5{}De}}5}__i}D D5}}5} Aۨ}}5}__x!D ~~5}u'~7~5F7~ B~qK~n~5n~__p Rp4I s~B Br~I_TpA__aM~__pMqYM~0B Bt~~5~F^s~5__iFF9g252__i7FFTKV5V)Aju5V}r~BKkuCj5__p i4I RALAkI_Tp5A__aM__pMjYMpALAe(35}6eBM5{}tczIT'%56_NzJD5__p ~4I PDJDI_Tp*__aM__pMYMnDJD> 051u__p =4I 0a@nI_Tp__aMn__pME?YMs7|B5G@5__iÁG G}ݐ` I_Tpݐ__a' __b'}'ݐȁȁ.**/77@X__aMX__bM]77Zaq5u__xe7a5u}΂ҏ|E__f .R݂5gJ '%^(kJ'<5<ֹ%EoPe5eֹ%-E__x*(Vg__x* VÃ5Ã__x*E׃5]EX5__x*X69R"-5-6wRAL5-mI_TpH__r'/m6+J5Q65__x@B`Gi1ф5miJ 5i__a8s . +5BS =R5Rֹ%ѐf{5Gֹ%5t;ֹ%ƅ5e_ֹ%Յ5BJ5__p I4I 88GLZI_Tp3__aMZ__pMLKYM_88Qs5__p P4I 9~9PSنI_Tp__aMن__pMURYMކ9~9+/ 5  -#!FZ 55bֹ%D\5\aH;)x5oW5Fֹ%qЇ5n~__p RpPr__aM__pMq0B5ho+fd %!0:Q5Q -F2h}52hֹ%H5Trhs>52ˆ5T ;ӈ5Tֹ%}5[5[4fpD3Ch5R= *__a hk { 5G5\%REĉω5L(މ5Lv5b8k>__a!w^7__b!w^7Mc5Nip~%5{__n$ % '%^(k$б__f$lF(ŊЊ5B 7ߊ5qc '%K75pf*55B}h~&sP'rFC=s>x555G__s 'ˋ5Gm* ˋ2ߋ5Xj5wj__a8sːG1.95 Jx K`5`ֹ% SEt5ֹ% 8lk5ֹ%8=֌`777`7|z7wz7>`7I_Tp7|7w7>)8#JRg5ֹ%uv5ֹ%85CKǍ5Ǎ5 ۍ5Ǎsam g5G% sG% tL& u7. v755G`k5Ǎz5 65sam g6% s% t & uG. vG66W)5,Q8M5ֹ%\q5qֹ%9K5__p IK__aM__pMLK8Tԏߏ5nY5b `@~9SHPl9rFKCHMttE/jP~S5 s-~S>T5bn}0l/-5 /-ؐ5 ֹ%R5__p PR7__aM7__pMUR9(VK`5szֹ%o5ֹ%f:=`7:7:7:Ց`7:|z7:wz7:1`7:I_Tp%:|7:w7:r:1]$95B{ֹ%H]5]ֹ%:>`:::^`:|z:wz:}`:I_Tp %|:w::W5sz__p UW8__aM8__pMQWr: ^Lc5B{__p \^__aM__pMZ^:w5v|ֹ% ԓ5ԓֹ%C!>`BBB%`B|zBwzB``BI_TpP;|BwB`)C1~t5F|5|5|}PBrF{C=> P;vW;D|; | D|w D|__f  xf}5v|__p ewcy__aM__pMx)C5V^cϕ5}__p b d __aM __pMc@ob35}ֹ%BW5Wֹ%@@>{`@@@(`@|z@wz@G`@I_Tp@|@w@@xi 5ֹ%-050ֹ%dA_>T`/A/A/At`/A|z/Awz/A`/AI_Tp5A|/Aw/ApAhЗۗ5ۗFUg5ۗg 52}RP@rF[C=R>Wh@v\;f;h| fw f__f hLl˜͘5qIܘ59CCڇ1P/ArFC16uulJU5q}0;0-l|5Q|US0-5Qֹ%gj͙5__p ik__aM__pMjpA5-D}w~SP@rF[C/S0XPd__x$__y%'D'D/5}dkΚٚ5}Pd__x0__y1 'D'D~!65ֹ%1EZ5Zֹ%bD~>~`MMM:`M|zMwzMY`MI_Tp*|MwMnD45D05__p ~T__aMT__pMnD ?h51u__p =?__aM__pME?7__x*$cڜ__x*,cp5__x*P G;5s>I_Tp'%>C"EWb5;kq|5k5/8l5G8nɝԝ5.kE5__p mDDF/__aM/__pM|F__nMF)8mCh5__pOl__n:lOy5ֹ%l5Em̞5ֹ%o۞5.kֹ%I 5u$5Jv3>5>85wR]5]8Jq5__p mIIK__aM__pMLK__nMxK8wџ5]__pv__nvO5>ֹ%=I_Tp3__r'/=8cI_Tp3N\8`8|d8wd8`8|z8wz8`8I_Tp3|8w88v5]w(=5]ֹ%~Ld5dzx 9}x5dP55q]ơѡ5ѡ9H59Q 5__p mPPRP__aMP__pMUR__nMR9d5__p__nO5ѡֹ%-ТI_Tp__r'/Тx9KI_TpN\l9#`l9|dl9wdl9eR`l9|zl9wzl9`l9I_Tp|l9wl995У5ֹ%݈ߣ59 5RLsFcNyc'L'y:is4Ԧ8s4l9>51u__p m==?ܤ__aMܤ__pME?__nMq?7b5u__pa__nxaO&;5uֹ%\I_Tp__r'/\I_TpN\ݐ`ݐ|zݐwzݐ`ݐI_Tp|ݐwݐ7b5uֹ%i$<5h[c>K[51u[|7I`o5~u__a8s7@a5u__aZ70CŦЦ5 o5I_T1I_T2__pOݐ7OnC%5n4]PאrFcC=]>b v v]:B`ݐ|)kBw)kB;)lݐ;`)s% :B`ݐI_Tp|)Bw)B;)ݐ 7C‹__na{PאrFcC{ v v/PB5vs-B0ըPp' 4I-ըPB_/| Bw B  /U+65szÉEP5u_j5jx:`~5:V5sz__p mUUW__aM__pMQW__nM}Wr: "5__p׊__nŠO3H5jֹ% Wb5͋q5ֹ%]5B{֓5]ɪԪ5Ԫ:s5;]#5B{__p m\\^S__aMS__pMZ^__nM^:g5__p__nՔO5Ԫֹ%̫5۫5ֹ%s47:{ s4:w/:5v|ۿIT5ԓcn5n/Cx5GC55dǮƬ5>[Oxլ5v|__p mewYwDy!__aM!__pMx__nMy)C!5Z5__p__nOk5nֹ%!55ֹ%|sF{N c'' kC5dֹ%5s4BQMs4zes4Ԛ@bt5}__p mbbc__aM__pMc__nMc@Ԯ5__pϟ__n@O$5$ֹ%@8C5ŠRg5ֹ%'s4Ab'25}AL5Wm[f5$Xu5Gi550ðΰ5ΰvA5Aj5__p mi ijM__aMM__pMj__nMjpABa5__p__nO5ΰֹ%BƱ5ձ5ֹ%p5n~ֹ%E252ֹ%$BOH]5]ֹ%6Bzs4/A~55ZȲ5ȲtDܲ5D~5__p m~~sG__aMG__pM__nMJnDF[5__p__nO5Ȳֹ%F5 ϳ5ֹ%<5h 5r'25rzAL5h}kPMrFC=>LL5hֹ%дs4Mhs4ݐ5<>5e+6569EJU56do5s~5`5~u3E5ŵе5K'6!'|.Z'w.Z'<B'<N'Eo:'|.r'w.r' __p * 'M 'J'%|'B%|'__a%|%__r%J'P' 'B '__a P' 'B '__a ߷:'5G%'B%'__a%߷}u 5 __ixG~G$/5go>I5gc88|8w8;8__n/hP8s8YWr%88|I8wI8;I8>N%AP8s!8YWr%88|[8w[8;[8J58Kǹ__aMǹ8v۹59z5Sc2I_TpQ%__a2__b7N%Pl9s!l9ѻYWr%l9l9|[l9w[l9;[l9Q59R__aM9'5'9;F5rcQUq5__n cPuR__aM__nMR9ρ¼5__n}=KB¼ B|.ZBw.ZB<= ;P7:s7:\ YWr%7:7:|I7:wI7:;I7:>N% P7:s!7:  YWr%7:7:|[7:w[7:;[7:V%5%`:WB__aMBl:&Va5a:u5cV5sz__n cUuWϾ__aMϾ__nM}Wr:5__n P:s: }YWr%::|I:wI:;I:>N%N P:s!:m YWr%::|[:w[:;[:]5:^%__aM%:99D5D;)Xc57d]r5B{__n c\u^__aM__nM^:5__n PBsB `YWr%BB|IBwIB;IB>N% PBs!B# YWr%BB|[Bw[B;[Bsx5C}y__aM#C>'5'MC.;F5d'xUq5v|__n cYwu&y__aM__nMy)C5__n's4z$&I_TpP;|qBwqB;qBBx_ d HPzsz YWr%I_IIBI_OIB|BwB;B>% Pzs!z YWr%I_IIzI_OIz|zwz;zU'25d{AY5|__n @z}c~وPBrF{C=>YY I_IIzI_OIz|zwz;z5d'5d}L IP@s@k YWr%@@|I@wI@;I@>N% P@s!@ YWr%@@|[@w[@;[@c(353@&dP__aMP@do5o@5Vb5}__n cbuc__aM__nMc@ߠ 5__n,5F, B SPAsA! YWr%AA|IAwIA;IA>N%] PAs!A| #YWr%AA|[Aw[A;[A`q2=5=BqQm5n~__n cFpur__aM__nMr0B85__njr__aM*Bw5TBg 5g 5I_TpA__r'/5B [I_TpAN\A `A|zAwzA`AI_TpA|AwA0BZ55ֹ%/5/ֹ%GpCN5n~]h52Ƶw5]5<P/As/A[YWr%/A/A|I/AwI/A;I/A>N%?P/As!/AYWr%/A/A|[/Aw[/A;[/A%j5^A/k__aMjA_5AO5`i.5__n c iujR__aMR__nMjpA f5__nPMsMYWr%MM|IMwIM;IM>N%M"PMs!MlqYWr%MM|[Mw[M;[M5\D__aM¨hDc5DS5V5__n c~uU5__aM5__nMJnD$Ib5__nݐݐ|ݐwݐ;ݐ__nPݐsݐ8YWr%ݐݐ|IݐwIݐ;Iݐ>N%ZPݐs!ݐ"YWr%ݐݐ|[ݐw[ݐ;[ݐ>57}>51u__n c=u|?__aM__nMq?7b+D5u__naS^5^7?{__aM{7db5u__n__a7?__aM7e5 c^?:ݐ`ݐ|)kݐw)kݐ;)lݐ;`)s%:ݐ`ݐI_Tp|)ݐw)ݐ;)ݐ7:ݐ`ݐ_|)'ݐw)(ݐ;))ݐ)*7A5d +5h}iPݐrFcCin++d5hc5hh5h__x7r5<__p m|F.__aM.__pM__nMGBM5ss\t5s__p*5E5s__p**56ֹ%5sֹ%&I_Tp' __r'/&4:E5E E1c__x*|__x*0c-I_TpQ%__a©__b®P* '%^(C  *  /Ch5h__x@rm__y@rrD5sL__x*B5__x*&G2GG 5 __a+p__b+p555*55N__x*4c]5__x*__y*__k*555__x*7EE/I_T13I_T23__pO87O/8:8`8|)k8w)k8;)l8;`)s%:8`8I_Tp3|)8w)8;)888:8`8Iu|)'8w)(8;))8)*88LLW5tyfq5d}Յ3P8rF8xCqqz5d_ I_T1I_T2__pOl97O ~9_:l9`l9|)kl9w)kl9;)ll9;`)s%:l9`l9I_Tp|)l9w)l9;)l99:l9`l9\|)'l9w)(l9;))l9)*98\l9l9|vl9wvl9;vl9kv5%5jI_T1AI_T2A__pOA7O B:A`A|)kAw)kA;)lA;`)s%o:A`AI_TpA|)Aw)A;)Ao0B:A`AŴ|)'Aw)(A;))A)*0BCAA|vAwvA;vAzs(35~PBM5h}`PArFCMM5hp5n~B*52__a8s*B۵ $5]__aZ$_IT56_vals_b"t'%tu'}dITd56_valsbtt'%u'}IT56_valsbJ(%(__x(%t'%8u' }($TuIT(56_valsub8t'%u'}zKITz56_valsbt'%u'}rIT56_valsb3#M MRf~5~2/2љ5~ֹ%`5oKD5oK|@C5@b&5$5@5@v@Tl5@l|@85*25W/5cHx5d5  5 p~א:Ь4I5 ֹ%Xc5d0r}5cd5cdֹ%5dֹ%5ֹ%(I_Tp %__a'(__b'-}' %::]IE %SL)7vL&;-lw5H15Xq5lp~Bn5hgm*"sF[Nhc'"'hA6K5Kֹ%AR_t5tֹ%AԮ5aֹ%5}ֹ%5B Dh-ch'%Z, ?x(@5CW; @8t'%Uu' }EqITE56_valsbUt'%u'}IT56_valsbt'%u'$}6IT56_vals6bt'%Ku'?};gIT;56_valsbKt'%u'}5IT56_valsbt'%u'>}\ ,IT56_vals,bt'%Au'=}1]~IT156_vals~bAt'%u'C}IT56_valsb15|V  5Vq,"O %,;2 %}'WxIT'56_valsxb;d5p`str 1t'%u'}IT56_valsb9fd %buf*%Q%t'%Iu'}9eIT956_valsbIt'%u'}FIT56_valsbt'%u'.}m *IT56_vals*bt'%?u'2}/[|IT/56_vals|b?t'%u'4}IT56_valsb}IT56_valsbt'%%u'&} AbIT56_valsbb%t'%wu'1}g0ITg56_valsbw}HWITH56_valsbt'% u'"}~'HIT56_valsHb t'%]u'(}MyITM56_valsb]t'%u'}IT56_valsbt'%u'}>IT56_vals>b}_IT56_valsbC^!5AA:D% 5AAt'%u'}AIT56_valsbC0ch'%,pF\5\x a55><u5M__fm%5x 559(5 J 15 JX#,  #++}.M(b IaITM(5_a(}l(YIT(VfI_T1I_T2'__pOݐ7O6!:B`ݐ|)kBw)kB;)lݐ;`)s%t:B`ݐI_Tp|)Bw)B;)ݐt7\:B|.rBw.rBj`B5h|BwB__nEjJj<:B5h|BwB+bKb5u__ab7}mt'}u',Y %bg}t'u',Y %b 5>F  5VfYWr%I_IIBI_OIB|BwB;BI_IIBI_OIB|BwB;B>:B`B|)[Bw)[B;)\B>:B`B|)kBw)kB;)lB;`)s%:B`BI_TpP;|)Bw)B;)B)C^:B`B|)'Bw)(B;))B)*)C;BB|vBwvB;vBzJU5|PBrF{CYY5@|@5}V5aϪ5k 858 C)76Lb5tp~@7 s~5Tk5Kp~A5BI5CW%I$~5TrhsD5ud9D5>Xifd % '{f UlD1fd %bufu%Q%c(5( b-i %8 %a %@71DY5]ֹ%/dk5ֹ%G-5ֹ%G;5\l'%l15H/45\Ɩ~%CN5C:]h5 Uw5f'%f1T@g'kg %E5/'%/1I 5H%5Hh4?5hNY5Y'EJm5<__n c|u(__aM__nMGT5s5s__x*}*KE:5:__a+p?__b+pD8G>G#7!Xp5Ãs*pE5__a+p__b+pEE#7str/*'5E05__x0EE;\-8586>YLW5W7zYkv5Z\58$Z5W__x*;7U5__x0__p0Et'%u'!}h$EIT56_valsEbt0Z[p5ֹ%w5Gu5u5 }؉PBrFC=>\:$u`A|)k$uw)k$u;)lA;`)s%:$u`AI_TpA|)$uw)$u;)A0Br__aM*B5__n__aZB"5/1I5/IrB_]h5 w5H}8IT856_valsb 5]V=5bkey_1BPl9rFKC/B0GttT[f5nu5BeJ1t'%u':}IT56_valsbt'%u'} 1 IT56_vals1 bO src't'%_ u'3}O {  ITO 56_vals b_ j  5 `3`HH  5V1 K 5C:`3 HD P; , !Z  5AA`3 HD P; i % ZBh%  5Hȥ  58 C' 2 5}sA L 5}A ;u;h| uw u__f hۼ 7 5HU%R%z%d%DP;]%%i % %F ^ 5H3%¶p { 5Fy&ՠ D8&IT,Ep7  IT,& os&p7|&E IT,&Q os&Qp7E'@ IT,&a@ os&ap7EDj &Oj os&Op7EF IT,& os&p7E & os&p7Ek M EeIT1,IT2,EEMnI_Tp%:|q=:wq=:;q7:Bx_ sYWr%I_II7:I_OI7:|7:w7:;7:>%YWr%I_II7:I_OI7:|7:w7:;7:aI_II7:I_OI7:|7:w7:;7:>:7:`7:|)[7:w)[7:;)\7::7:`7:|)k7:w)k7:;)l7:;`)s%NG:7:`7:I_Tp%:|)7:w)7:;)7:Gr::7:`7:t|)'7:w)(7:;))7:)*r:7:7:|v7:wv7:;v7:X 5z%5d}2cP7:rFcCch%%=|5dvI_Tp %|q'wq';q:Bx_ 2YWr%I_II:I_OI:|:w:;:>%<YWr%I_II:I_OI:|:w:;:xI_II:I_OI:|:w:;:?::`:|)[:w)[:;)\:Y::`:|)k:w)k:;)l:;`)s%::`:I_Tp %|):w):;):: ::`:|)':w)(:;)):)* :[V::|v:wv:;v:_ep5{5cd}_P:rFvCP5cd8I_Tp@|q@wq@;q@Bx_ YWr%I_II@I_OI@|@w@;@>%YWr%I_II@I_OI@|@w@;@+I_II@I_OI@|@w@;@9?m:@`@|)[@w)[@;)\@7:@`@|)k@w)k@;)l@;`)s%h:@`@I_Tp@|)@w)@;)@@q:@`@l|)'@w)(@;))@)*q@@@|v@wv@;v@P@rF[C 5HcI_Tp5A|q;Awq;A;q/ABx_ YWr%I_II/AI_OI/A|/Aw/A;/A>%VYWr%I_II/AI_OI/A|/Aw/A;/AVI_II/AI_OI/A|/Aw/A;/Aj?:/A`/A|)[/Aw)[/A;)\/A:/A`/A|)k/Aw)k/A;)l/A;`)s%<:/A`/AI_Tp5A|)/Aw)/A;)/A<pA5:/A`/A|)'/Aw)(/A;))/A)*pAu/A/A|v/Awv/A;v/A85av5aRP/ArFC/R0Wuu-k52h51pK/A5)r__iuW;A/ArFC67.ruXm/5q__n k{I_Tp*|q9Dwq9D;qMBx_ YWr%I_IIMI_OIM|MwM;M>%)YWr%I_IIMI_OIM|MwM;MnI_IIMI_OIM|MwM;M?:M`M|)[Mw)[M;)\MQ:M`M|)kMw)kM;)lM;`)s%T:M`MI_Tp*|)Mw)M;)MTnD:M`M|)'Mw)(M;))M)*nD MM|vMwvM;vM6PMrFC6;LLZOZ5hIPMrFC/0LLOC5 o5r__nbHmcD  5 Dx strx Ss'%#7Rcposh1 str' %i %= !B !1B % %  Cv 3!A3! 8B sumC %iD&'A{!str'(\^p'ch'd-!P/n %x/n %E!!5R__c3'%!!!!!K$X "".K09"PQ"_"5 pw""5 !""5AA"""5AAtK#""K##5@"~o-#7##F#Q#5@7#am#w#F###5@*##5oW#]H/*# $5oW $ %]H]*&$=$5oW=$]H*Z$q$5oWq$]H* $$5oW$uH*0$$5oW$1:+@$ %5oW %8*+P*%A%5oWA%1:S+`^%u%5oWu%uH|+p%%5oW%]H+%%5oW%]H+%&5oW& %]H+7&N&5oWN&]HQk&y&5XHW&&ZW0.&&5 @.&&5 O"'i+:P.0''5Vx[.#6 xx# [.#x[.#x&j.&]i"'n+:.*'?(5Vx.; xx# .xp.x'.'"X(s+: .*p((5Vx.@ xx# .x.x "(x+:! .*([)5Vx.E xx# .xI.xh@ /s))5Vc/ J c# c# }))5CW)]H)*5CW*]H-*D*5CWD*]Hsa*x*5CWx*]Hw**5}* /***[0/%**5*;f*G8HKx+"+ZKT >+H+TWu50d+n+.WU:@++UVNP++)VHK`++ZKx{ K! ,,.K{ tKo6,J,K{ Tf,z,T{ UA,,U{ Vr,,)V{ W , -.W8{ HWU>@&-:-ZWX{ X-ITxSP;ޮg-|-5>[ֹ%X-~`/-/g-/'x .ۭ/'(I</:-/ L- /w ./&/5K?// /Ƭ/ Mլ߬//{ /w //&/5K?B//UƬ/Mլ߬U/{ /{ X-/(//g- 00{ F 00/05 % % F0zN@`)"020NzN@x3N00NzN |0Nh{ dkP0N01ddd06ddd06dhdd0 wdwdd0N$11de06ed06ehd08 wd wd 'e,0N1 26e@e16@e6e16Oe%hd1X wd\wd\aey@1N&22pezeT16zepeT16ethdT1x wdwdeW1N2 3ee16ee16ehd1 wdwde1N(33ee16ee16ehd1 wdIwdIfb02O34f(fD27(fafD277fhdD2 wdwdIf:2O244Xfbf27bfXf27qf:hd2 wdrwdrfh2O4(5ff27ff27fhd2 wd wd f 3OD55ff437f2fQ437fphd43 wdwdf6p3O5:6gg37gg37g hd3 wdCwdC1gr3RV66@gJgWg3:WgJg@g3:fghhd3 wdwdxg0 4S6f7ggg44;ggg44;g hd44 wd)wd) 4r7 N!!%!Qa40D`a`a} 5+8 5  X  ?5{ e5{ 5{ KL5PC89ZL dL 'L5p 8>L2L* 5 8>LO 2Ld K5 RKO Kd K5 T Ly K L 5v  9-95-9ֹ%oH9ХXN9:99 99 W f I #9I KL #dL. ZL[ +8Ro{ "{ :$:5hֹ%#Z:`A|dAwdA`Ae30v:<:L:y WH;y   [WH{ o WH$:WH~D: 8: :[(gN [(] W[(f' KL[H #;dLc ZL +8RLIw #I' #߯   ͯ   M  { '<>q> :h:* H>* O b [H{O ob H$:H~D:O 8:u :gN ] Wf KL #=dLZL4+8RLI #I /#߯/Rt/7ͯ7M@{ P{ Qd>>5hֹ%B,?`ݐ|dݐwdݐ`ݐ>B_`nH?A>{;h@ڥΥ{;{;>{;~? ?aguW]fKL #F@dL#ZLC+8RLI #Ia Ϥä M{ )AAA5G__s 'CPAuA5B h__n h5FFzFret6(Eat&'wXi5}6@BAiA6 3AA)AiH6hAAP6BgAZAPA)NP6 BNUNN)IP6 CBI)7<$u6w6 C6W6CfI68 #KCIKL6P #dL(ZL=6+8Ru`AA6pDgAPZArPAN6 DNNrNI6 C DIN7<$66PDf6W6DfI6 #DIKL6 #dLZL86+8RudWP7@EfIP7 #EIKLV7 #dLZLf7+8RudWj7EfudIj7 #EIudKLp7 #dLZL7+8Ru`66t6  F46 ZMC7!fuI7 #@FIuKL 7 #dLZL07+8Ru_97{ 1v}#7G?;F;&'%<&'os&'8j?56P7XFQGQvPT8R$P7IGPPaO7 GlO7{  8R$P&8DGQP68R$7|  _p8`HH_)_)_P8p{HPBP`aO8 pHlOB8{ 8R$8)__xP8P/P8R$92uH9J9W fI #EIII -IKL #dLZL3=dL\ZL'L +J>L2L I>L2LK RKKK8 T LK&8 LQ0v HJlJ5kֹ%it0Mn9JPqJLHJg%QK^JNkg0J#k}jg$j}jJgki14Kvkji6jjMk0\k̞/L۞4CYM  "ԝ M{ ̞/L۞4CYM "ԝM{ { [L)M5)M[?T@\'k] %^'y;L 78dJMMLLMM Mi8_Mj! jMiyii98%| ,9{ 49{ ޲bM N5)Mֹ%M3[@9M'NNM{Z9cNWZ9f0IZ9 #NI0KL`9  #dLbZL9+8Roq9{ 9O8Oo(HHT9PO+TI9 IPT9OmTaT9>| 99:":{ 0:ON'str':O#:SvPvP ':)h'0PT:jPmTNaTc:>| ;O1% ;PP5P69?nP;;P@;2P QPPPP m;/QGQ5>VD Q7r;"cQvQ/Q9QUQQ5VDvQ;"QQQQi;QR5>XQa; `a#T`a#T57RVC;*ORR5>Xs;ss#T;sv;s <.RR5>XG<f7P#TƹP<.R"S5>Xw<f7P#T<.:S]S5>X<f7P#T<.uSS5>X<f7P#T#<.SS5>X=f7P#TB=.ST5>X7=f7P#Ta@=.&TIT5>Xg=f7P#Tp=0aTT5H %=L=WTPnow7h=[| l>TTlhsl'rhsl')>{| 3 U'U5_'UZ9T`>bHUUUU_}>zU_@_>UY_O_U>%| >>{ >{ ,>&Vj_> _y_@_>Y_O_#->Vj_> _y_@_>Y_O_#6?TVlhsM(rhsM(9?*V.p?T-Wlhs.'rhs.'iY? 3YtY?| vB?=oWlhsBM(rhsCM(@| Z@;Xstr[X[XhjH\5T]5Y@\#XYI@ II@ -IY$@]xXYI$@ II$@ -ID@V11XX5G__c -'%j; /v4 \P@It]ss{Xi]str|t]}HCend~HV;6V@|fY t@@Tt@}Y+TIt@ IYw@~YYt@ Z 4@ ZMC \ch'! }@(vZW A@( 3AW )A@h@Ho X@H Xo XHX I@ /[II@ II@ -INA 2>[N N I A 3r[II A -I!OA` 3[:O 0O  A:O!0O#!J A [JN*A NN6!@W0Ax}\fN!I0A #D\IN!KL6A #dL!ZL!SA+8RucbA\fIbA #\IKLjA #dL"ZL1"zA+8RucWzA^]fudIzA #%]IudKLA #dLD"ZLq"A+8Ruc@A{ 1NA*]]5]AXq5/]]5Fֹ%A]L`5ViAx# =ALV"A"ܠ"AcA~w"BAgV #]A]] #WA/W_fB#KLA( #:_dL~#ZL#>B+8RHI+B #IB#WBH/_f#IB` #_I#KLBx #dL#ZL$YB+8RHWB/f,$IB # `I,$KL B #dLN$ZLn$tB+8RH^`s`5Bֹ%/BX`d5ViB0bx# =BLV$B $ܠ$B  cB ~w$BB gV%]B ]]%WBH /afJ%KLBh #adL%ZL%C+8RHIB #IJ%WB /obf%IB #5bI%KLB #dL%ZL&)C+8RHWB /f4&IB #bI4&KLB #dLV&ZLv&DC+8RH[C( 1 &У[C@ ߣ&RiCg{&o&#iCgC7iCgiCg~ &բmCh g:'L`mCh ]^`:'WmC Edfr'KLmC #(ddL'ZL'C+8RHIC #Ir'WC f'IC #dI'KLC #dL4(ZLT(C+8RH-d;@d8ED4dOe5|Vr(Fw D( Fnwcw(( }w(( w('-he;Jhe8O@D4ee5|V-)FwKD@ PnwcwL)@ }wq)@ w)wUDe0f5|V9cDVHc# Hc# {?fWf5Sc__n xPDdrfZg5|Vi %`mDX /gym)om*0fDx J gIf)?f*9cD"gHcHcE<$hD KhhP*^DOgD| De7EYugg5|V i8 %{*:EWfOEepENgh5VxrE , xx* x* x*mEhm +Em7+mE _phmc+EZgmE_m7+>xEMx+ENhi5VxE 1 xx+ x+ x+mEsim,Em-,mEdgim-,EZg>xEMxY,+FPij5>XsF ssq, s, s,Dy2FpjOy,8F Oy,*y8F L9y,y8F #y,AFhrNFr,J`FPjqk5>XsbF( ss-( s<-( s[-]yFQkhy}-F hy-yF Qy-FhrFr-ZFkk5|VXcF [gc#,gc#,kk5rc__n tFTll5|Vi %nF@ l-n-#n-kFX Jlk-k-XcF"lgcgcG<$mFKmn#.^GlG| Fqkl m5 mT@m)m5 m|5 GEm2smlKGp dslN.tKG m.4KG ZMC/tWGm/4WG ZMCL0tZGBn04ZG ZMC`1t]Gn14]G ZMCg2t`Gn24`G ZMCa3tcGo34cG ZMC3SG MoSSN4GSGoS4S4GSG oS,5SD5GSGoS5S5GSG pS6S-6GS4H LpS6S6@HW\Hpfv4I\H #pIv4KLbH #dL 7ZL87rH+8RugWrH:qfvIrH #qIvKLxH #dLK7ZLx7H+8RugWHqfvIH #xqIvKLH #dL7ZL7H+8RugWH(rfvIH #qIvKLH #dL7ZL7H+8RugWHrfvIH #frIvKLH #dL 8ZL88H+8RugWHfvIH #rIvKLH #dLK8ZLx8H+8RugIG%| H{ H{ AsVs5 mֹ%+eszs5 ֹ%VsaIRszes2s-I izAs8S6I sS8S8bISgI( $tS 9S89sISI@ WtS`9S9ISIX tS9S9ISIýtS:SQ:ISIp tSy:S:JWJ guf:KLJ #JudL:ZL;J+8RugIJ #I:W'J uf=;I'J #uI=;KL-J #dL_;ZL;J+8RugW1J Uvf;I1J #vI;KL7J #dL;ZL;J+8RugW;J(vf<I;J #vI<KLAJ@ #dL#<ZLE<J+8RugWEJXCwfc<IEJ # wIc<KLKJp #dL<ZL<J+8RugWOJwf<IOJ #wI<KLUJ #dL<ZL =J+8RugWJ1xfv4IJ #wIv4KLJ #dL'=ZLT=J+8RugWJxfvIJ #oxIvKLJ #dLg=ZL=J+8RugWJyfvIJ #xIvKLK #dL=ZL=K+8RugWKyfvIK #]yIvKLK #dL=ZL>#K+8RugW#K zfvI#K #yIvKL)K #dL'>ZLT>5K+8RugW5KfvI5K #GzIvKL;K #dLg>ZL>GK+8RuggJ{ RK{ Vs`K(zzeszKK{ kK@z{lK+l>kK'k>K'k>kKXz{#k>jK$j>j?MkKX\k? K/{3|5Vii %j %1?8lKj `lUlJl#dK/,d,d;!L/K||5AAip %q %D?8l Lq `lUlJl#dL/,d,d|%:!0LL|}5AATL$ }>3# yTL$(3z&zzW?|`L |?qLs`NLs`"L$}}5AALi &'?dL ,d?,d?vL@~(\ ^?YgLpY0~Y@TM` ~+TIM` IpMV@NV[NVvNTxeYC@xYxYa@Y@Y$M# Y@3M=<DMTMTMTMTMTNTNTMVN(\= ^fmt= 'mH> @tD %($F %"A7ZNe TZBAHZoAN| 7ZOK LTZAHZAO| ZCO E vZAMO| ZMOE *ZBUO} N}N{ N{ 2O%} eOYwO?} OO} O{ O> ?5CW?OpO_} Ow} ]HO>\5CWOp P_} Pw} ]HO PV5CW ZBP ZBZGBVP{ BPpbP{ pPw} 1:Pp Gq H[BEr HzB"`Pq 1`B_P|_BTP}+TBIP IB<`Pr _K`C_P &_:CTP+ToCIP IoCP{ Q{ Q{ 2Q{ 1:-5dpQ̃5>[@@ P;8i &'ChdQ (wdCwdCdQ RdCdCQ` #Q`~C#2QDŽKAQxQx HQxD|=Do[DxDQxD=D[DxD R} Ņ5-9 '2 RԆTRR /+TDIRR IDWR# fvIR #nIvKLR #dLWZLDR+8RwRR{R} Rw} R} R{ R9strr 9.s 6tRs [E4R ZMCEIRt {I%Eitu 9ESu чŊEIS rIE Sv EZ S ZE(S u -*E+S@u MFXKSXw X,FXXXUFIKS /ʈIIKS IIKS -IN~S 2NFNFIS 3(IIS -I!OSp 3:OF0OFS:O G0OGJS ՊJNS NN2GsSS!#fIS #IKLS #dLKGZLxGS+8RugSS{ 1,S  p7 ' 'GPT PPGTR$&TT[ HP&T PGPGWTR$tIZT FIۨI HgT} HTs<zTPPzT PۨPAHTR$8 5V;FgTU΋LT$APTU psTpTT}cpT%| O ^s5ֹ%LBUWŌ^X-)U g-`H2U:U{  `Ug5@@ P;UUUU7E5I(U `n5n\;g,U 5[U -0[&[sH%V ׍5WVi& V 5W;Vj$&@V 7O5W[VQC&`V g5W{V7Rb&V 5WVR&V ǎߎ5WVR&V 5WV"S&V '?5WV]S&W Wo5WWS& W 5W;WS'@W Ϗ5W[WT;'`W5WC[`WR[#$Z'W+W5W][Wl[#$y'WOo5WsWtHsW@sHWsHw[WE[HWZgWj'WT5WsXsH(Xs Iw[+XEz[ I7XZg XjƑ5>XiJ %K%'PX2ޑ~5Wi %]X"-I]X"OI8l_XK`lUlJliIdfX/,d,dvyX͓yyIX8y8y8yIXyIxyIyImHY BmJmKY  lmXja 3+X>XaOja }lO+Xsa{ aO_afaMȦbaLb3bxa6TaETpIa 6IpIa IpIa -IpE٦5~ %R7Ȧ a $٦`a>[5[M %X7q50{ %d7`b q{ b!֧5M %j7Pb1,M %lbxb$bJ{%jb 1j0jRXb~ b~ bƧbΨTb`+TlIb Ilاc#%c%ScdSSlc10czptru;3cM %xPc(ĩ_cM %l;%knc*c!ީ/5[c $H]c ]/]eXc~ T̰c+IǪ5[cfӱ]cԂ]zX]XjScSzX|SXc~ rcB5[c,;%X ❫f]c]X]>YjScSX|S>Yd~ S d SSY50d5[Y0dYI0d II0d -I̟Pd 5|5[Pd H]Vd ^'`d5[6T`d(ETI`d 6II`d II`d -I6@dN,f5[;I %iYd~ dǪ_d'5Tsrcd'Y#e?DY:f*YTd`+TYId IYYeg#Y/Z^`ey,^NZ"^aZ`e 3NZaZaO`e }lONZle{ weO^ea,^T"^Ze 3TZeOe e* eH c6M5Td@M1ee= 2cwdn=_'fXo1@Z6'[Wf@ fuIfx #IuKLf #dLw[ZL[f+8Ru_%f.ffW.fof[I.f #oI[KL:f #dL\ZLO\[f+8Ru_Wpf#o!f\Ipf #I\KLyf #dL\ZL\f+8Ru_e] ff{ t'%O'fiy5[n$H\'f@@]6}]Wg@/f]Ig8 #I]KLgP #dL^ZL-^g+8Rucg gfW ghf@^I g #~I@^KLg #dLx^ZL^Xg+8Ruc}0g ^^:gWpg]f_Ipg #$I_KLvg #dL#_ZLP_g+8Rucfĩfeg{ gŶ;zXgzͳc_g'g @6_ggfSgcTL`S`SgJSL`S`hˆh(ӈ`WhH;f(aIhh #I(aKLh #dLzaZLaHh+8Ru_ˆ#hӈaW#h;faI#h #OIaKL,h #dLbZLLbWh+8RvˆfhӈbWfh;fbIfh #IbKLlh #dLbZLbxh+8Ru_ˆhӈbWh;fbIh #uIbKLh( #dLbZL!ch+8Ru_#hOh{ מh.߶5[@ۺ$H4cdir6Xthh\_c4hh ZMC_c[h[cThN+TcIh IcShSdSKdhWh\fdIh ##IdKLi #dLdZLdi+8Ru_' i @d6-eWi@fleIi #¸IleKLi #dLeZLei+8Rudi ifW i(feI iH #JIeKL)i` #dLeZL7fhi+8Rud^@i ܹ,^uf"^f@i 3uffXiOWiSffIi #IfKLi #dLfZLfi+8Ru_WiʺfudIi #IudKLi #dLgZL;gi+8Ru_hĩhi{ UiN5[YiW.YNgAAi XhgAgZAgPANg j' jxX@g6(hWj@fhIj #ϻIhKLj #dLhZLhj+8RucjjfWjXfhIj #XIhKL&j #dLiZLGihj+8Ruc}@j XeiiJjWujX9fiIuj #IiKL{j #dLiZLij+8Ruci|j{ /ji?5[4l87XYj4Yjˆ4k08CӈDjW4kP;fXjI4kp # IXjKL=k #dLjZLjk+8Ru_ˆWk)9׾ӈjWWk);fjIWk #IjKL]k# #dLjZLjpk+8RuTˆk!9kӈkWk!;fkIk #0IkKLk #dLkZL,kk+8RuTkӈudWk;fudIk #IudKLk #dL?kZLlkk+8Ru_j| kǪ*k4kŶNkNkk{ wkY5[2w'2x\FXkxkk.Al y 3Al)AlaOl lOll{ *lhlfumIl #XIumKLm  #dLmZLmm+8Ru_l8fmI*lX #ImKL-lp #dLonZLnl+8Ru_YWl{%YnAAel{^gAoZA=oPAnql'sl{ @io6oWkm@fuIkm #IuKLsm #dLoZLom+8Ru_|llfWl{fpIl #JIpKLl #dL&pZLHpl+8Ru_Wl}ffpIl8 #IfpKLlX #dLpZLpl+8Rv}lp})pplm#fpIm #aIpKL m #dLqZLqW=m}f-qI=m #I-qKLCm #dLBqZLWqPm+8Ru_WTm{vfjqITm #=IjqKLZm #dLqZLqgm+8Ru_ lPloW.m{ "m5ֹ%1\CmDmx mx m mAistr'rein)@ߕh$n 1:^r@nAG^S^Sn`^[n!S^qG^q[n!`^htn u  '%^(k4?*B5gJ__c '%Ti5MSֹ%B%nT^n^^nqn5a4 *n q(o$Rn RrR$rn.RBrRVrnEn5irn<n<^o#o| ow} SW0o,T@WDNo Vo 9]`oT@]D^5|rZ_?Dra&'r<b&'rFm\F}oo o o ooH 5T@AFB\FfD !5ֹ%vD1oG~ ! <F\F p( s( sZ8pA [Z=sJp~ WpH C'Qs]p ~ p!efIp #,IKLp #dLosZLsp+8Rugpw} %p: .pU Wpfp` 1 sWqpx 4&fsIqp #IsKLtp #dLsZLtp+8Rugqpk p{ p{ Kp+fq'[q+1q'k@qT7>bq\>/tgq?NtڥmtΥtgq?mttgq?>gq?~?mt ?takq gutWkq ]ftKLkq #dLtZLuq+8RHIq #Itq4uqSuouqqϤäuqMuq{ q{ q'#?NF%N&'osOp7*S5T5MV_5r?nF%n&'osop7.r!puuu!@Q.rQ4Qu*Qu5r<P5rQP>PvGrR$Rr7r&vPar]5PMvPevsrR$arFQPuR0rFPuR ? PrbPxvPvrR$rFPuR0>-ros:;:^r@G^vTrX+TvIr Iv^r<^'w6TrMET]wIr 6I]wIr I]wIr -I]wPs !<PwPwaOs'lOxs{ s PxP3xPs8!PFxPZxcPs zPFxnPmxs,sR$P/s<PxPxAsR$POs<PxPxasR$Pas?qP%yPCyaOas flO%yis{ tsR$Pts?PayPysR$PsP!@}PyPyaOs lOys{ 0trPyP zP2th!PzP1zcP:t fzPznPDzGtsR$^s!@^^s!qXzs!5Z4z*zs!  zTt$Rs! R{R2{t0RP{Rd{ tEs5w{s<s<Ms=28 S`t5;9cdtTHcHcitR iitji{i{^tL_t| t{ ht!Ohh{t@5ֹ%[W"@_f{I #&I{KL " #dL|ZL/| +8Ro|L@LM|H5ֹ%__m8%5Lv  5ֹ%LD25LMֹ%2LSIT56_7-tpIu8":l|ωu`"މ|uCux"k|Cu"#?'|uVMu"#?JyMeM+}uMv#?AM-MVu"{}}u#cĉ}vt'v c}4'v ZMC}Lcv#L ~zv@vvv>@v8#dW~ML~{CvP#l~~=RCvh#$҂LR~VR~h#eR~t%| v{ v{ !ٙ!X!ٙ!kX5H.M5ֹ%ML a5ֹ%Lќkvzk %#ssl4 ~v#l~ωv#މgvw#w$#?g'vwVMvw@$#?yMeMwMz##?AM-Mu~w`$M=]w$c ĉ]ExtXx$c4Xx$ ZMCLy%sLyxyz2xm[KA/xkQx!R~RRkx.RQx!VQԁQ?Px!`VPԁJP2xm"KA x k|Qx!mQGQkxQkMQx!EdQGXQPx!\2PG&Pkx$nL x@x$n.x%5$Wx%@fIx #IKLx0% #dLEZLwy+8Ru~|Ly@L yR yN5uaL,yH%#;oML݃MByh%#;AM-MLny5L%yx=yy{ y{ @zzms %ss 4 ~Fz% IωFz%dމzz(& لzP&#?'ل{VM{x&#?yMeM5{M}##?AM-Mu~W{&ZzW{&c[ĉz{t{&cυ4{& ZMCυL2}%L6O}|}}l | mL m.|7=0|' : 6>|@>|' .e\|8'5Wk|P'@fÇIk| #IÇKLt|h' #dLZL'+}+8Ru~|L|@LE|R|N5uaiL|#;]MLM|#;AM-ML|5LՈ}g}W}{ o}{ c5L % d}*d %'sse4 ~}'eω}'މA}}'+}((#?'n~VMp~3#?yMeM~M#?AM-M ~H(#7~x(cyĉ7?tR(c4R( ZMCLu%LՊ_r(f($1F(d΂) ݂F() p4y*H) 7$Rŀh) RR8)R}RE)fqtR)$RRF)Rf)g @*g.ō *5sW8*@Qf)I #I)KLP* #dL[ZL+8Ru~|L$@LARAH5uaώLW#;MLMs#;AM-ML5L;=GO{ { r( r5%h* sss4 ~Ɓ*s._ωƁ*މ*_(+#? 'wVMy3#?<yMeMMʅ#?AM-Ms΂H+΂x+cĉHt[+c4[+ ZMCL%L;…+tEQh+$,ʑ΂0, ݂P, p4ߑ*p, g$R, R|R,RRE,t'KtR,$R}R,R̓Q-u4Q*Q<2(-tKAHӃzQӃ!RRRzӃ.RϔQӃ!VQQ?PӃ!`VPJPϔ2كtqKAك z|Qك!mQLQzكQpMQك!EdQLXQPك!\2PL&Pp@-v @X-v.-x-5sW<-@Qf!I< #I!KLE- #dLSZLK+8Ru~|LQ@LnRnH5uaǖLz-#;MLM#;AM-ML5L3фw{ ʅ{ c< -@WW/-@fI/ #IKL5. #dLZLq+8Ro|L=@LT\{ ',5e_pݐkH W(.fI #IKL@. #dL;ZLu+8R_ŝ{  5_)_5sh/<T,}+TI IA X.,3Aܘ)AaO  lOܘ&{ 3hW3p.,SfI3. #IKL<. #dLUZLX+8Ructj +4j ZMCW,fudI #IudKL #dLϙZL+8Rucy]j%| { Ka5tp@7p5(ֹ%<a9KUa.p FU W.rfYI #9IYKL . #dLyZL8 +8RugW< !fuTI<  #IuTKLD  #dLٚZLT +8Rugŝ { ] { &` e /.A  y 3A)A[aO  lO {  h fuI  #IuKL  #dLZL +8Rug  { ,!  '%^(C%'% /B%-%hj;%Ǜm*%yaO @/%lO  { t `/%*54 `/ ZMC5I %JIa9 fI9  #IKL>  #dLZLN +8Rug  h( W { _P%Cx/TstrX^X/`vi/^\/vi//yם/.A/ y 3AE)AmhgqfIg0 #8IKLi0 #dLZLΞ+8Ru[W00fIP0 #IKLÆh0 #dLZL!`+8Ru[Wچif?Iچ #0I?KL #dLTZLi+8Rw^0v|i0^0vi0ԟ^)0v(i<0^10IvTih0WfI #IKL #dLZL +8Ru[W69fՠI #IՠKL0 #dLZL+8Ru[/ { Ї strM(  %*0 4 ~1ki %y01H%C~aOX1kaΡaIO `IΡIO IΡIO -IΡfR$Wfx1fKIf1 #IKKLr1 #dLoZL+8Ru~W_fu~I #%Iu~KLlj #dLʢZLډ+8Ru~N1. 15C>WԈ2@!fpIԈ #IpKL݈ 2 #dLZLԣ+8Ru~|L@LRB5uaL#;ML:M3#;AM-M^LI5Lf X,{ AixM(Ex&'msgyY5iz&'+\=56_i=82J JI -IP22%Ӥ P24:$p2|ZZP|p2b~a$2aZaI$ IZI$ IZI$ -IZ>R$W>2|KfI>2 #IKLG2 #dL֥ZL+8Ruc%bx2Eb;b2bP{3Q*P>R$WĊ|&fudIĊ #IudKLʊ #dLaZLڊ+8Ruc$_{ k5ZzpvM(_=Pv56_pvM(:r03qZP03b~arH3aaBIr dIIr IIr -IR$Wh3fZI3 #IZKL3 #dLZLҧ+8RusWafutI #(IutKL #dLZL=ɋ+8RusrBҋ{ r 56_pv(:3mZPP3b~a3aPaI `IPI IPI -IPR$W3f I4 #I KL(4 #dLEZL8+8RusWC] futIC #$ IutKLI #dLZLY+8RusBb{ p1u<%}<%c<%osp7@P PPϫP@4 PPR$PЌ: P P%Pc P8PPP PcP{P PPP PPѬP0 PPP@0 PP'PPY P:PR`x e~aX4 aa׭I II II -IR$Wx4z fI4 #A IKL4 #dL$ZL9ԍ+8Ru_W4 fWI # IWKL4 #dLlZLʍ+8RwP$ QPʮR$W fݮI5 #b IݮKL5 #dLZL+8Ru_W%f2I # I2KL #dLGZLt(+8Ru_{ 1{ -@gc<%osp7گPYP-PEkR$PPPfR$r G%'% 'len&'osp7̎'HK%P̎PKPߎR$ߎt&'1Vcur'gP05 PP/R$ " P/ VPܱP>R$D  M1PuRwPSPKP9bR$l%'% 'len&'osp7p` +'Xlen+&'os+p7H5,lزP'PPR$ЏR1Џqs6'9os6p7d :6c=P:jPͳPR$P(8PƩP:R$c~ !P_sX_osXp7IPp5YJIIP5 IIP5 -If1istr&'os&p7\-` IT'&O5 ss&P4 ~f 5&P+ωf 6މs  06 `6#?o' VM '#?yMeM7 M#?AM-Mu~S 6ULlS 6cĉl t c4  ZMCL %{L   d 6&Qo|.ojx> 6&Bܶ6N> 6&fYܶ&> 6&X<1ܶO WO 6&f IO 7 #I KL[ 07 #dL-ZLQ +8Ru~PP  &PoPg R$W &hfI  #.IKL  #dLZL +8Ru~< g H7&R s @s `7&R.' 75qYW 7@OfI  #IKL 7 #dLZL{ +8Ru~|L @L  R <5ua1L #;MLUM #;AM-MyL 5L;   { { 6p%<% M(len&'osp7'H٩%kPP٩PR$&'7curS(̺P7 APPR$ڐ!ڐ! P P@PXR$̐1RwP PKPk2R$ 8%<% M(len&'osp73@a 1M(len1&'os1p7\82+Ի Pq'P4PLR$q##R1SqsGM(kosGp7ʑ Kgԑc=PԑKPPR$PIPƩP*R$,#n0sdIosdp7M008e{MIJ0H8 JII0`8 -IIF#k5str&M(os&p7}-@+$ITM(&O$x8$ss&P4 ~F8&P]ωF8Kމu{8{ 9#?'VM'#?yMeMM#?AM-M~0@9̾0`9cAĉ̾tc;4 ZMC;L%LĿ9&QN#ڿ0*9&r Is<99&s 9&Xs)])9&!l.J)9 # J.I) -I.JN5: #cNyYN(:cNYN'LP@: !>L2LZ |!>LS2LhKZ RKSKhK T L}KL~"P &!PP7R$]X:&G#lJ #S"JI -IJNp: #cN6YNZ56cNu~YN'L5: :#>L2LA#>L2LKA RKKK` T LKp` LR["A:&Rx# R@R:&R$.p:5P$QW:@.$fI ##IKL; #dLZLK+8Ru~|L@LR<5$ua)L#;$MLMM#;AM-MqL5L-{ 5{ (P)str[ '(;);\ tdH;\ %4dH; ZMC`;)ch^ '%X;g 'XX;XI /%&II II -IN 2O&NN"I 3&II -I!O; 3':O:0OZ:O0OJ &JN NNؒWG;d 'fIG; #S'IKLP; #dL ZL,+8Ru_WX<d (fJIX #'IJKL^ < #dL_ZLtp+8RvWۓd |(fIۓ #C(IKL #dLZL+8Ru_Wd (fI #(IKL #dLZL+8Ru_+*< G#|)fI #C)IKL #dL1ZL^Г+8Ru_{c~ ٓ{ f!pZ* '%^(C P * Q *8<*m* S u*fuI #<*IuKL #dLqZL+8Rug{ !+ '%^(C + '%B m* *f8a09a0/Df0P<V0dir7T*ĩ+6T*oETI* 6I*Dp<`,**9p<*~!N,fu`I~< #,Iu`KL< #dLZL+8RudP]'q<-@6W(@,fI(< #,IKL*< #dLZL?+8Ru[zfW=LJ-fI0= #N-IKLH= #dLZL.+8Ru[Wh=-fLI #-ILKL= #dLZL+8RuTˆ=ǒ.ӈW=;fI #W.IKL= #dLZL@+8RuT}.^~Ĕˆ S/ӈW ;fI  #/IKL #dLZL+8Ru[WB/fIB #/IKLH #dLZL3T+8Ru[WT*A0fFIT #0IFKLZ$ #dL[ZLf+8Ru[Dp)%{ 5543&4393=)3E\FXW>11fI #0IKL(> #dLZLX+8Rud)1Qy).A@> y 13A)A&hW3X>2fI3p> #1IKL6> #dLZL"N+8Ru_Wl2f5Il #]2I5KLr #dLJZLw~+8Ru_W3fI> #2IKL> #dLZL+8Ru_Õy]ܕ3){ 1_5q3u5%}5%c5%osp7t;u5%}5%c5%osp7>i;1P>3PPR$>3?8e3C[3P Y4PP2R$P4PPR$P 4P1PIR$P 4P\PtR$P %5PP R$P X5PP*R$P8 5PPJR$PX 5PP jR$Px 5P3PKR$P $6P^PvR$C6~a@?6aaI 6II II -IR$W`?E7f.I? # 7I.KL? #dLNZL+8R[W?7fI #7IKL? #dLZL+8RDP7QP%R$Wg8f8I? #.8I8KL@ #dLLZLy0+8R[W38fI3 #8IKL9 #dLZL P8@29PP FR$R$1R$R$PF@@o9PwPXR$NR$Ps9PPR$Pm`@9P*PR~R$~a~x@\:a|aI~ Q:I|I~ I|I~ -I|R$W@:fI@ #:IKL #dLZL+8R[WHJ;fIH #;IKLN #dLZL^+8R[a=W=mF{ #;c5%osp7Ζq3;u5%}.%c.%osp7K`Cu5%}.%c.%osp7@C1Pzn<PP#R$;@QA;;P<PPR$P <PP2R$PH /=PPZR$Ph b=PP*zR$P =P=PUR$P =PhPR$P =PPR$P .>PPR$P a>PPR$P( >PP,:R$H>?~aA>?aaI 3?II II -IR$W8A?f9IXA #|?I9KLpA #dLYZLm+8R[WA-@fI #?IKLA #dLZL]+8RDPz`@QP<R$W@fOIA #@IOKLA #dLcZL+8R[WaO2 NlO;{ JhWJE,NfRIJ8E #cNIRKLSPE #dLZL+8Ru_t +N4 ZMCW,\OfI ##OIKL #dLZL;+8Ru_/y]%| [+ON*i[+U9iNqG[+GpGNlŝ+Pu`*iU9iu`qG{  [[P{TITP5_{Tf&hEQ|hEb^&P^P)EPP'aO7EQlObC{ EQPuPPTEPPcP QzPnPQR$QFS$Tn,R+TMIn IMAq F,cR3A)AaOq XRlOw{ hW8F,RfIXF #RIKLpF #dL ZL<+8Ru_t F+#SZ4 F ZMCZW1,SfI1 #bSIKL7 #dLZLG+8Ru_ny] %| !+%T*i+U9iqG+GGŝGjTu`*iGU9iu`SqG&[{ ` `TWIT35_WFT0FbFWhT,cU+TI IAF,U3A)A^aO UlO{ hWF,9VfrIG #VIrKL(G #dLZL +8Ru_t,  +V4,  ZMCWO ,VfIO  #VIKLU  #dL.ZL[e +8Ru_y]* %| A +Wn*i+U9inqG+GGnŝe Wu`*ie U9iu`o qGw { 80 W XIT/5_ X_5-3Xos3Xsb8X2_5X SXkXIT?5_kX  XXITL5_X\@k''' dke?nfk@Gk&g\Fmsgj/rtkfŗpGlY|;pGbP:Gl>ZZPGb~aGaaI 1ZII II -IR$GlZLGb!Pf#GmZ|EGb?Pa@Hm[aaHbW=W HmB[/ HbuPl\in %x8Ho[8HbPXHPPR$xHo\xHb͘iWHq`WWRH*^HbX$H'X2X~a:I+]aaI: ]II: II: -IHR$WH I]f6IH@I #i]I6KLKXI #dLvZL#+8RuWt ^fItxI #]IKLwI #dLZL+8Ru9y]bIH`NT,^+TI IAI,^3A)AaO ^lO{ hWI,g_fIJ #,_IKLJ #dLPZL0+8RutB0J+_4B0J ZMCW,)`fI #_IKL #dLZLƞ+8Ruy]B%| SHJ`*i`JU9iqGxJGGŝ`2*iU9i2qG)ϙqEa;Hϙ]י)]qa;r]j)יJ|a;יJ+ڙJjb*iڙJU9iqGWKbfI K #UbIKL8K #dLQZL+8Ru)PKvb;hKtIʚ{ cII;ښ} =XK|kf]XOSXwKc0&KbPKPP4՛R$՛KeeT,c+TI IAL,]d3A)AXaO0L RdlO{ hWHL,dflIhL #dIlKL L #dLZLB+8RuXW՝,MefI՝ #eIKL۝ #dLZL+8RuXt+e#4 ZMC#y] %| ')+fN*i)+U9iNqG)+G}GN:ŝdf*iU9iqGpXbL}iXXbpLf5xmLbPpLP5PR$MiT,`g+T1I I1A8M,g3AS)AaOPM glOS{ hWhM,6hfIM #gIKLʜM #dLZL8+8RuXtS+~h4S ZMCW,hfI #hIKLĝ #dLZLIѝ+8RuXy]Q%| eϜ+i\*iϜ+U9i\qGϜ+GqG\ŝoi*ioU9i|qGp)|j;jWj*iU9iqGWjfI #jIKL #dLZL7+8Ru)<!vk;J<!_J{&V͙/iW&VhG0"ŝX"pud*iX"U9iudb"qG""y]j"{ :-О;6u% %R ' 'O 7rO.A 0O y q3A )AEh/rfIHO #rIKL`O #dLZL  !xO AsxO.A*O y r3Ai)A aO* rlOi2{ ?h9sfuPIO #sIuPKLO #dLR ZL  +8Ru_*W?O sf I?P #sI KLBP #dL ZL x+8Ru_WR8P 1tfN IRPP #sIN KLXhP #dLp ZL +8RwW# tf I #ptI KL #dL ZL +8Ru_Wϟ  !uf Iϟ #tI KL՟ #dL ZL- +8Ru_oǟ{ &NuKw5CW KwP@wwp \FlclP uc@ _lu_` Tv+T Iv I WP uvf IP #+8Ru~W> qfI> #7IKLD #dLZLP+8RuWP f2IP #I2KLV #dLGZLvb+8RuWb cfIb #)IKLh #dLZLt+8RuWt ܅fIt #IKLz #dLZL$+8Ru4 Rbroϡ)) )6G)Yg)f{ u+P9k % 2'XTT@6tjTP74jT ZMC7STSSWTffIT #IfKLæT #dLZL7+8RwW˦_fI˦ #8IKLѦ #dLZL'٦@ 6pfˆU*ӈW U;fI@U #IKLXU #dLZLe`+8Ru`W pUfI  #hIKLU #dLZLG+8RwSUԉS:SWUKfIU #IKLU #dLZL+8RwWVŠf/I #I/KL V #dLQZLs+8RwW8V9fI #IKLħPV #dLZL+8RwWȧhVfIȧ #wIKLΧV #dLZL7'+8RwWҧ'fUIҧ #IUKLا #dLjZL+8RwWgVfIg #eIKLmV #dLZL+8RudWqfIq #܌IKLw #dLZL +8RuCWf$ I #SI$ KL #dL9 ZLf +8RudW fy I #ʍIy KL #dL ZL ˆӈ W;f I #II KL #dL ZL Ȩ+8Ru`WШf !IШ #I !KL֨ #dL !ZLM!+8RudWqf`!I #8I`!KL #dLu!ZL!+8RudWf!I #I!KL #dL!ZL!+8RudW3_f "I #&I "KL - #dL"ZLL"+8Rud+Eo[l){ 55X@9k2' Vd %_"FV^"hˆhWӈ"Wh0W;f"KLhXW #ԑdL#ZL@#ǩ+8RuPIxW #I"SWKTS#S#SWJSS#S#ީ גӈ#Wީ ;f#Iީ #I#KL #dL#ZL$+8RucˆjӈudW;fudI #0IudKL #dL$ZLC$+8Ruc/{ 55D T@'k %Wd\FPsWĔV$$W.AX y K3A$)A8%hܫ(f%IܫX #I%KL߫0X #dL%ZL%+8RvHX&J&HX.AhX y -3A&)A&hfuIX #cIuKLX #dL&ZL)'+8RuWWXf<'IX #I<'KLX #dLZ'ZL|'H+8RuWWϪYf'IϪ #[I'KLժ Y #dL'ZL'W+8RvW٪8Y f'I٪ #ӖI'KLߪPY #dL(ZL@(g+8RvWhYf^(IY #KI^(KLY #dL(ZL(-+8RvWt#f(It #×I(KLz #dL(ZL)+8RuWWtf)I #;I)KL #dL*)ZLW)+8RuWWfj)I #Ij)KL #dL)ZL)+8RuWW!df)I #+I)KL #dL)ZL*ͫ+8RuWPso){ ח5MSYT@'k %H-0ʙ Yٙ*TYx+Td*IY Id*^Z^^Zq(Z5N4**PZ *ŭ$RpZ R+R#+@8RA+RU+IE 5xh+ɬ<<PάZP{+P+٬R$P٬ZP+P,R$PZœP",P{,aO?lO,{ ZP,P,PZP,P,cP zP,nP-R$P[P-PA-%R$W%0[nf_-I%P[ #5I_-KL.h[ #dL-ZL-+8RucWǭfudIǭ #IudKLͭ #dL-ZL".ݭ+8Ruc{ #=58#CPJ['dP5.PbR$Pb[(P].PtR$Pʮ[)ĞPu.PR$P[*P.PR$Q[*$4Q.*Q<P[*XP.P.R$P\+P.P/%R$Q'0\+4Q'/*Q2<P2H\+P>/PV/DR$)ŝJ}ŝʮMbj{ w{ *Lt5tOylenS%H;=p"D:LV`\%ei/P"\PP|/P"R$P"\Q P/P"R$Y"\SxY/I"\ I/I"\ -I/P!#\VP/P<#R$~a<#\W0a0aI<# %I0I<# I0I<# -I0N#R$PP#]WdP-0PE0e#R$~ae#8]Wad0aIe# Id0Ie# Id0Ie# -Id0w#R$"ŝ""# !#####{ #{ Id5*2<%: #<IP]'Uy0P$h]<УPҪP1$R$P1$]<P0PH$R$#ۀ $V$=_$q$# y${ ˘Kf5*2H%<1$4K])W0P$]HҤPP$R$P$]HP0P$R$$ $%=%&%.%{ CCh5hֹ%y%24>0%;C]0Y1Pz%^y٥P8P%R$P% ^y P/1P%R$L% z%%=%%%{ c%+ũIE %S7)7 7 %end7 %v8&; 8^9%G1d%P^9٦,d~1,d~1P=&h^: P1PU&R$PU&^;9P1Pg&R$Pt&^;mP2P2&R$P&^:P12PI2&R$&NsAC %\2^D%HE%2ӨP3Pt'R$P'8_>P03PH3'R$P'P_?;P[3Ps3'R$&ŝ=&r&=&=&&ŝJ''='='='P''('{  ({ "1ݩL5AAS )72 Q3Dd M@,d,d;Ld5H]ܯl3Qah_`a3`a3_ i&'4Qa_`a:4`a:4/ũ; ;m-85t#(T-PT(_aPP4Pk(R$Pk(_bPx4P(R$6(ŝT(((U (({ SPѮ5t_r ?@:v C@z %4İL3 C@4/ !N 4U P`o P4PR$P0`p P4PR$P} P5PR$~a`H` a)5a>5I` I)5I` I)5I` -I)5pR$~ah` 5aQ5af5I *IQ5I IQ5I -IQ5R$vŝx \ űֱ P"L`PPIJٲ{ ̲{ { C5ֹ%%Ѯk(}!(Jy5`5P)`P5P5)R$P5)`P5PL)R$(́ )Z)=b)):e)a:5n)H8 6%686[n)H{%6o86n)H$:n)H~D:%68:K6:x)`gNv6x)`]v6Wx)`f6KLx)` #dL6ZL 7)+8RuPI) #I6)*7߯)B7d7)) ͯw77) Mw77){ :)Y:7)5<777[)5{7o7)5$:)5~D:78:W:)$gN8)$]8W)$f"8KL)a #dLD8ZLY8*+8RuPI) #I"8"*l8߯"*8V"*&*ͯ88&*M88/*{ ( =*{ 65@ֹ%%S@*R.^*{8(a'8P*Ha´PP*R$P*`aP9P*R${*́ **=**^* +{ +ֶ %strֶ:xa˶end*X, f%R/9%9; %96T$+=ET9I$+ 6I9I$+ I9I$+ -I94+]:P+PP+R$D+~ \+>~+ŝ+ŝ+,",*,{ 15fd %>*Q,%fd{ %WT{' {!P.}P':PFR$PIa}_PO:PaOQ lOm:Z{ aTP:PPeaP:P:cP HzP:nP:eR$Ph~P:PzR$۶aD:;t ;;4 ZMC;;bDm;^b-,^;"^;b 3;;aO8b }lO;3O ?w} I: QU W9fvI #IvKL #dLuLZL;+8RuD .%| { ʴ{ Ҵ{ ))4 ̺5tֹ%c0,%̺X,XbK-;P,pbaUP;P,R$P,bbP2<P,R$b,ŝ,,,U -W,bI$fJ<I,b #IJ<KL,b #dL<ZL<-+8RudW,bIf =I, #cI =KL,c #dLQ=ZL=,+8RudW -I fI -(c #ӼIKL#-@c #dL=ZL=8-+8RucW8-I|fI8- #CIKL>- #dL=ZL >J-+8RucU-{ `-5c̺w-XcLN̺ >-pcKq->>P-caP\>P-R$P-cbJP>P-R$-ŝ---U ].W-cIf>I-c #I>KL.c #dL>ZL>H.+8RudW.dIaf?I. #(I?KL.(d #dL=?ZLl?8.+8RudW`.Iٿfv I`.@d #Iv KLc.Xd #dL?ZL?x.+8RucWx.IfvIx. #IvKL~. #dL?ZL?.+8Ruc!.{ .{ ,r5hu%D5V^0@BcWpdr @d~@@Pҵdu1PPR$PduaPt@PR$_$ ҵ=,l@ClR@$l}3@7@֡@}ơ@4{ -.^,4.d!C@dYNAP.dyP8P/R$P/eyPwAP$/R$. .-/=6/N/V/{ 2`/H<w/(e'A4/@eCA@eYBP/XeyP8P/R$P/peyP7BP/R$/ /0=0!0/{ )0{ 0.Nc5\ֹ%%r5lpB<݌00NslR0e.lOBcR0e|rOB0e̺B0eL̺B0eK-BP0ea{PBP0R$P0fbPBP0R$0ŝ00 1U 1W1 fIJfCI18f #ICKL1Pf #dL2CZLTCp1+8RudW%1pfIfrCI%1 #IrCKL+1f #dLCZLC`1+8RudW1I:fv I1f #Iv KL1f #dLCZLD1+8RucW1IfvI1 #uIvKL1 #dLDZLAD1+8Ruc81{ g0ŝ1{ @ 5H|fTDcfrD g~DPڶ@gupPEPR$P`guP6EPR$$ ڶ=Gz%| 2{ :{ u5X<;'101xg=*SNExg.A1$ y 3AS)AE1h}3"f-FI}3 #I-FKL3 #dLBFZLoF3+8Rud1=2g=VFLFgeGPB2gPP*GPZ2R$PZ2gQPbGPl2R$Yx2gSYzGIx2 IzGIx2 -IzGP2hVKPGP2R$~a20hWaGaI2 IGI2 IGI2 -IG2R$P2PhWPGPH2R$~a2phWa!HaI2 I!HI2 I!HI2 -I!H2R$!2ŝB2u22 23S33W3h=Af6HI3 #I6HKL 3h #dLrHZLH83+8RudWV3'=fHIV3 #IHKL\3! #dLHZLIl3+8Ru[*3uTu3{ 35\\3[\!IT3+TeII3 IeI3hIIh.A3h y 3ARJ)ApJaO3 lORJ3{ 3h353h*NJDDK 4W 4ifKI 4(i #iIKKL4@i #dLKZLL84+8Ru_W4`ifCLI4xi #ICLKL$4i #dLeLZLLO4+8RvWg4fLIg4i #YILKLj4i #dLLZLL4+8Ru_W4 fu`I4 #Iu`KL4 #dLLZL%M4+8Ru_34{ uHH485\|4i8MKM454iNMDM5W5j1f*NI5(j #I*NKL5@j #dLbNZLNH5+8Ru_W5`jfNI5xj #pINKL5j #dLNZLO_5+8Rvƅ#5ՅOWp5AfTOIp5j #ITOKLs5j #dLiOZLO5+8Ru_W5fu`I5 #Iu`KL5 #dLOZLO5+8Ru_4W4 5{ ]Hq5]~5\M~jsd'O^5^P6T5METmPI5 6ImPI5 ImPI5 -ImP#6jP*Qj.A/6k y %3AQ)A RA6h85fRI88k #]IRKL8Pk #dLRZLR8+8Rud/6Q6hkSOShk.A]6k y 3AS)A5To6h8LxfTI8k #?ITKL8k #dLTZLU8+8Rud]656kN$UDU6W6k,fUI6l #IUKL6(l #dL=VZL{V7+8RuCW6HlfVI6`l #kIVKL6xl #dLVZLV/7+8RwW6lf WI6l #I WKL6l #dL+WZLMWG7+8RwW6lfkWI6l #[IkWKL6m #dLWZLW_7+8RwW6 m fWI68m #IWKL6Pm #dLWZLXw7+8RwW6hmf/XI6m #KI/XKL6m #dLQXZLsX7+8RwW6mfXI6m #IXKL6m #dLXZLX7+8RwW6mtfXI6n #;IXKL6(n #dLYZL7Y7+8RwW7fUYI7@n #IUYKL7Xn #dLjYZLY7+8RuCW7dfYI7 #+IYKL7 #dLYZLY8+8RuCW8fYI8 #IYKL8 #dLZZLAZ8+8RuCW8TfTZI8 #ITZKL 8 #dLiZZLZ,8+8RuCW,8fZI,8 #IZKL28 #dLZZLZ>8+8RuCW>8DfZI>8 # IZKLD8 #dL[ZL@[P8+8RuCWP8fS[IP8 #IS[KLV8 #dLh[ZL[b8+8RuCWb8*6f[Ib8 #I[KLh8$ #dL[ZL[t8+8Ru5%5o6%#6 Q6)6)}8{ 8<U9N<'9pn.N[sl-9n.l&\c-9n|r&\n9n̺u\n9nL̺u\9nK-\P9naP\P9R$P9obP\P9R$9ŝ999U }:W9(oI`f]I9@o #'I]KL9Xo #dL#]ZLE]h:+8RudW :xoIfc]I : #Ic]KL:o #dL]ZL]X:+8RudW:IPfw I:o #Iw KL:o #dL]ZL]:+8RucW:IfwI: #IwKL: #dL^ZL2^:+8Ruc :{ G9ŝ,:{ :{ ̸PK 5Hp@oE^Wgo0p^f1:goI^p$U _Pʷ8p<Pe_PR$PPp<P_PR$sۀ ʷ=~ hp_<hpK_pW!`P*pHPU`PBR$PBpHP}`PTR$ *]=f{ { N-(5Hp`WqCp`fD:qI`0q7U[aPPq<PaP2R$P2hq<PaPDR$øۀ O=XѹҸ ظqa<ظqKbqWYbPzqHPbPR$PrHPbPR$ z=ٹ{ { q,@h5V;h 8% ^5WrknbW7@rnpBcf:7@rIBc`rUcPr<8PcPR$Pr<hPdP̺R$Cۀ ׺=aR Xro d<XrKXdrWdP sHPdP"R$P" sHAPeP4R$p  ==Fvi{ ~{ j%^5W8s~feW`sfpef:`sIesUePs<KP#fPR$Ps<{PKfP,R$ۀ 7=@ sgcf<sKfsWfPj(tH$PgPR$P@tHTPFgPR$л j=ּɼ{ ޼{ 5ֹ%py5dֹ%[5Vֹ%nYH^gRfvg{gog#fC7ff~ gբXtggL`Xt]^`gWxtlf#hKLt #OdL_hZLh;+8RuPI) #I#hWtfhIt #IhKLt #dLhZL iS+8RuPf'iUfdz?inaif j +Cti7ij Mtiis{ viiiܠic~w jBugV6j]u]]6jW u/fnjKL8u #dLjZLjν+8RuPI #InjWPu/VfjIhu #IjKLu #dLkZL>k+8RuPWu/f\kIu #I\kKLu #dL~kZLk+8RuP(kŸџk۟k  l-lb Mq l{-l#{ 4&u=C@luY`lPbvyP8PzR$Pz(vyPlPR$1 b={ :-`e5\e5:@vydNlD mƅ:hvՅQm:vmn:v=Smv.A;v y P3A_n)An;h<f(oI<v #I(oKL<w #dL=oZLjo<+8Rud;=&;w=hV}oLoweoPY;8wP2P pPq;R$Pq;XwQbP3pP;R$Y;pwSYKpI; IKpI; -IKpP;wVPzpP;R$~a;wWrapaI; gIpI; IpI; -Ip;R$P;wWPpPp;R$~a;wW.apaI; #IpI; IpI; -Ip<R$8;ŝY;;; ;<<<W<x=fqI<x #IqKL<0x #dLPqZLqh<+8RudW<=XfqI<Px #IqKL<hx #dLqZLq<+8RuWJ<uDW+<xyf rI+< #I rKL1<x #dLHrZLrX<+8RudW<yTfrI< #IrKL< #dLrZLr<+8RuW:<{ ]Hq<5\j %5$=xNrD}sƅ$=Յs*=x5tt/=y=u5ty.A>=0y y 3A=u)AuP=h>f#vI>Hy #I#vKL>`y #dL8vZLev>+8Rud>==b=xy=VxvLvxyevP=yPaPwP=R$P=yQP>wP=R$Y=ySYVwI= IVwI= -IVwP=yVPwP>R$~a>zWawaI> IwI> IwI> -Iw'>R$P)>(zWPwPw;>R$~a;>HzW]awaI;> RIwI;> IwI;> -IwK>R$t=ŝ=== =T>0?q?WW>`z=fxIW>xz #IxKLZ>z #dL[xZLx>+8RudW3?3=fxI3?z #NIxKL6?z #dLxZLyK?+8RuS>uDWg>z f'yIg>z #I'yKLm>{ #dLIyZLky>+8RudWq>({fyIq> #JIyKLw>@{ #dLyZLz>+8RudW>fzI> #IzKL> #dL4zZLaz ?+8RuSW ?sftzI ? #:ItzKL? #dLzZLz?+8RuS=o$= %?{ ]H? 5\ aZ?$pZzT?w+T{I? I{?X{0{{X{.A?x{ y 3A!|)AJ|aO? lO!|?{ ?hA(f|IA{ #I|KLA{ #dL|ZL*}B+8Rud?5?{N=}D}ƅ?|yՅ ~?|u~?P|=uP|.A?p| y 3AV)A?hA"xfvIA| #?IvKLA| #dLZLA+8Rud?= @|=VˁL|e^P>@|PPqPV@R$PV@|QPPh@R$Yt@}SqYIt@ IIt@ -IP@(}VPP@R$~a@H}W)a(aI@ I(I@ I(I@ -I(@R$P@h}W]P=PU@R$~a@}WahaI@ IhI@ IhI@ -Ih@R$@ŝ>@q@@ @@ABWA}=f}IA} #^I}KLA} #dLƃZLXA+8RudWA=f=IA} #I=KLA~ #dLRZLA+8RuS:AuDWA ~fIA8~ #ZIKLAP~ #dLZLքpA+8RudWAh~ fIA #IKL A~ #dL0ZLlHA+8RudWAfIA #JIKLA #dLZL̅A+8RuSWAf߅IA #I߅KLA #dLZL!A+8RuS?A{ 1:y T@'k %~ d\FT&4l&.A~ y 3A)A1hW>~Lf4I>~ #I4KLA #dLTZLv+8Ru[WQ0fIQ #IKLWH #dLZL؇˿+8RuTW[`= fI[ # IKLa #dLZL:+8RwWؿ fXIؿ #| IXKL޿ #dLmZL+8Ru[W- fI # IKL #dLˆZL+8Ru[W& fI #l IKL #dLZLD(+8Ru[ o>){ @/6X<'' w'P'Wmsg/\_T __T( _Te+TˉIe Iˉfv3 |vbPv@PPMR$ _X )_p_Px P P3aO  lO { R$)__cP> xbPЀPxPR$ _ )_Ћ_(P  PWPjaO lOW{ R$@)__6Pb QxnjbPXPP܌R$ _p )_ _$PP9PMaOlO9({ 9R$9 7}bP9ȁP}PQR$T ōbPTPōPlR$ _l  F)_L_tPz@$PPΎaOzlO{ R$`)__VPx *iU9iqGG5Gŝ] ud*i]U9iudgqGvy]o{ Z9EpkM kI^ ^ITX+TI I؂  ŏ^ B^6TMETI 6II II -I: ZHPb~a0aHaI IHI IHI -IHR$X h*RXbPpP*PR$ _ )__ǑPPP7aO lO { R$ _Ѓ )__gP,_PPaO,TlONR$()__PP@PP3R$_` V*i_xU9iVqG_GGVsŝW fI #PIKL #dLZL*+8RvW fhI #IhKL #dL}ZL +8Ru_ Fu`*iU9iu`!qG_y]{ 815N8p40Wn؄BfIn # IKLq #dLZL$+8Ru_W0fRIH #IRKL` #dLtZL+8RvW2fI #IKL #dLǕZL+8Ru_Wfu`Ix #qIu`KL #dLZL4 +8Ru_UPudRu en{ \M ; 81.(2(G2s8 sWY؅ fٖIY #IٖKLb #dLZL7+8RusW }futI #DIutKL #dLUZL+8Rus@PutRu K_} Yw} tw} { o0)N'6'(C/\[^)HX{ܗqHbp)P})})b)P)`2Z`b)P)&)b)P)lΘ)b)P) *i) U9i)qG*ud*i*U9iud*qGR)})GPvRuT)G8PvRu)y]*{ %_'T@'k %x%X/TbPPP;R$ _)_^_PІPəPܙaO lOə{  R$)__ Pb (!xbP (P!PY(R$Q(PqgPbP(pPP@R$@bP@PP)XR$ _[Ї )_Y_Pct P͛PaOc i lO͛l{ }R$)__P>}( ^%T(bP}HP%P]R$p\! pbPPPŜR$G!g]bP؈PP-R$G""g]]bP P]PR$H"ŝHbPhPŝPR$"-bPP-PeR$T ȉ$#+TI ȉ IWP#fўIP #c#IўKLS #dL ZL8+8Ru[Wf8$fVIf ##IVKLlP #dLZL+8Rvq Y$ҟ*iq U9iҟ|qGW$fIh #$IKL #dL ZL6 +8Ru[W I%fII  #%IIKL #dL^ZL+8Ru[#%*i#U9i'qGy]3PJ /{ @B'IT,V'l`BR&llߠ`Bbl`Bll,wB=B&O*iBȊU9iOqGBG|GOBŝB'ud*iBU9iudBqG`BBy]B{ EHB|8'/5\/mBq'mmC 'm CZg C'.CDC(J.APC0 y 0(3Aݢ)A5bCh/E(fuPI/EP #h(IuPKL2Eh #dLZLGE+8Ru\PCrC)2z.A~C y )3A)AHCh~C5CN)NʥD'CWC؋)fvIC #)IvKLC #dLȦZLC+8RuGWC0>*f2ICH #*I2KLC` #dLTZLtD+8RwWCx*fIC #}*IKLC #dLZL֧'D+8RwWC.+fIC، #*IKLC #dLZL8?D+8RwWC+fVIC #m+IVKLC8 #dLxZLWD+8RwWCP,fICh #+IKLC #dLڨZLoD+8RwWD,fID #],IKLD #dL/ZL\D+8RuGWD-foID #,IoKLD #dLZLD+8RuGWD-fĩID #M-IĩKLD #dL٩ZLD+8RuGWD-fID #-IKLD #dL.ZL[D+8RuGWDv.fnID #=.InKLD #dLZLD+8RuGWDD.fêID #.IêKLD> #dLتZLD+8RuGC%DC rC)E{ 1:PE|4/75\7*yE /9yyE #yEhEȍ/EE0E.AE y 003Aج)A0EhG0fuPIG #h0IuPKLG8 #dLZLG+8Ru\EEP1-uP.AEh y 13A)AC FhE5FN1NůD"FWF1fqIFȎ #1IqKLF #dLðZLxF+8RuGW.F>2f-I.F #2I-KL4F0 #dLOZLoF+8RwW8FH2fI8F` #}2IKL>Fx #dLZLѱF+8RwWBF.3fIBF #2IKLHF #dLZL3F+8RwWLF؏3fQILF #m3IQKLRF #dLsZLF+8RwWVF 4fIVF8 #3IKL\FP #dLղZLF+8RwW G4fI Gh #]4IKLG #dL*ZLW#G+8RuGW#G5fjI#G #4IjKL)G #dLZL5G+8RuGW5G5fI5G #M5IKL;G #dLԳZLGG+8RuGWGG5fIGG #5IKLMG #dL)ZLVYG+8RuGWYGv6fiIYG #=6IiKL_G #dL~ZLkG+8RuGWkGD6fIkG #6IKLqG> #dLӴZL}G+8RuGE%E E)G{ uH@C4795CW 9mW q7mmZ 7mK`ZgZ 7ZiZ{ W G8fI #8IKLА #dL׵ZL`+8Ru[Wd 8fu\Id #8Iu\KLj #dLZLDz+8Ru[|pZg%{ w} { 1pI#{ 1:379;5CW ;;wp \FPW5 9fWI5 #9IWKL88 #dLlZL+8RuWWXX _:fIXp #%:IKLa #dLZLɶq+8RuDW :fܶI #:IܶKL #dLZL+8Ru`W O;fu\I #;Iu\KL #dL1ZL^+8RuW(qo;PuXp%5{ Xw} { uHE2;PB5CW( PB %EBs6 %q @ % - E<qPuTT- <+TI I"(Б- <-3LqPuDW_- ,=fQI_ #<IQKLb( #dLZL޸x+8Ru[WvH- =f Iv` #k=I KL|x #dL.ZLO+8RuDW0 >fmI #=ImKLȒ #dLZLH+8Ru["4 P>-ϹqPuTW4 >fI #>IKL #dL6ZLh+8RuD0D@$X8 %"]: ?-ԺrqPuTRu@WP: ?fIp #^?IKL #dL"ZLD8+8RuDW: @fbI #?IbKL #dLwZL+8RuDJ]p{ vy{ W- @fI #@IKL #dLZLɻW0 "AfܻI #@IܻKL #dLZL+8Ru[W- Afu\I #aAIu\KL #dLZLF+8Ru[pO'_{ %{ { p{ +6Wߎ pw} Z{ { ]HG|mB'J5\'J % HГBYl-HCHCȼ.AOH y ,C3A)AaHh/JCfuPI/J( #dCIuPKL2J@ #dLZLGJ+8Ru\OHqHXD@X.A}Hp y D3Aƿ)AHh}H5HJDNDHWHDf<IHД #DI<KLH #dLZLH+8RuGWH:EfIH #EIKLH8 #dLZL:I+8RwWHPEfXIHh #yEIXKLH #dLzZL'I+8RwWH*FfIH #EIKLHȕ #dLZL?I+8RwWHFfIH #iFIKLH #dL>ZL`WI+8RwWH(Gf~IH@ #FI~KLHX #dLZLoI+8RwWIGfIIp #YGIKLI #dLZL"I+8RuGWI Hf5II #GI5KLI #dLJZLwI+8RuGWIHfII #IHIKLI #dLZLI+8RuGWIHfII #HIKLI #dLZL!I+8RuGWIrIf4II #9II4KLI #dLIZLvI+8RuGWIDIfII #IIKLI> #dLZLI+8RuGGH%HWCH qH)J{ ]HdQstrD QhD %QmE /XPiG &'I:G JII: II: -IؖchH '>x N `KD\x bPx PDPpz[ KbPPPR$%b(e .LEb;b(bP@QPsR$K L,DbPP,PXzU LqbPPqPQ QMbPPP0'` MZ0 Z%b ] MEb;b bP`Q/POR$%b W [NEb;bb bPxQvPR$Ab NaWbPPPR$:ؗb OZPؗb~aaa"I tOII II -IR$ c OF^ bP@PFPrR$Whb `PfI #'PIKL% #dLZL<+8R[WEb PfIE #PIKLK #dLZLH[+8R[* k )Q[*i U9i[qG[k nQo*i[U9iohqG:y]p{ 1 X;H XWeI /TcWiJ %ؘXWK X _L R)__PRPPaO xRlO{ R$8)__/PPL SDPbPpPDPlR$M kSbPPPR$:M &TZPb~aaaI TII II -IR$(M T6(bPHP6P^%R$W%hM Uf~I% #TI~KL. #dLZL+8Ru[W:M zUfI: #@UIKL@К #dLZL$+8RuPM UB,JL VnbP PnPR$V`L WVe`T+TI IWEM VfIE@ #VIKLHX #dLZLG]+8Ru[W]M GWfZI] #WIZKLc #dLoZLo+8Ru[qkZqk O W*i U9iqG.O W*i.U9i;qGy]C{ :~9i"X9X56_msg`9X_5XPJQZX,\"X,XpJp`.ZωpJXމ~JJ_YJ؛#? Y'JVMK#?Kh`WZW5M~aKaZa@aIK ZI@IK I@IK -I@KR$WKaY[fIKȜ # [IKLK #dLZL'L+8RucWSLa[f:ISL #[I:KLYL #dLOZL|iL+8Ruc*iiL`[9iuLqGnJ%| Ky]KL{ SL{ }L{ Q\~ %m/i\q5\@%p(\F%Z/>.]^*TbbP P*PR$ _8])__PX]PZPmaO]lOZ {  R$x)__LP 5^bP&PPAR$[|Н"w^{qDНbP>#^^fT~bP:#x_ZPb~a(aaI k_II II -IR$WP#_fIh #_IKL #dLZL,\o5a7\*E\\Q`H`bPO`ouebPa`aab=abP\a*iU9iqGˠa*iU9iqGy]E4ae([`bP>(56b^T(b/P:/@5bZP@b~a/`aaI/ bII/ II/ -IER$F57cMubTP>V6yc^TbiP:i68dZPb~ai؟aa%Ii +dIIi IIi -IR$W5dfUI #wdIUKL8 #dLwZL?+8RuW"6,efI #dIKL #dLZL+8RuX3h6+%W!1efKL! #edL'ZL<)+8RudI #I/fO wbP>ؠ0Gf^TؠbP0fbP>1f^TbP:01gZ'P<0b~aPa'aOI }gI'I I'I -I'R$WB1gfuPIBx #gIuPKLE #dLudZLP:^uAhPuPRuGPuRvW6hfgI #rhIgKL #dL|ZL+8Ru`W#5%ifI# #hIKL& #dLZL;+8Ruki!bP>ءi^CT[ءbP:ljZpPb~aapaI _jIpI IpI -Ip R$W 8jfI P #jIKL h #dLZL&k /bP>'Vk^QTibP:'lZ~Pb~aآa~aI lI~I I~I -I~R$W'{lfI #TlIKL0 #dLZLWF#lfIFH #lIKLI` #dL*ZL?W'GmfRIx # mIRKL #dLgZL|W%mfI #mIKL #dLZLWأ?%nfI #mIKL #dLZLD`+8Rud+nb*i+U9ibqG+GGbŝW,(@ofI, #nIKL2@ #dLZL+8RudVMo1*iVU9i1bqGWe@ofFIe #oIFKLk #dL\ZLw+8RuW?>pfI #pIKL #dLZL+8Rudf|uAmpPuHRuy]ΨluApPuXRuuApPuDRuMaPouApPuLRu{ v`=||str'qXo|end*P%|;vmsg/T r:rbPȤP:PR$sbX'XX?~a0ra]aI rI]I I]I -I]R$WPisfIp #0sIKL #dLZL+8Ru`WMsf IM #sI KLS #dL5ZLbc+8Ru`y]}TtubPPuP1R$>1t^T7bP1PPfIR$ _J>u)__PJ0PPaOJ 2ulOR{ eR$AeXuaLWXbPexPLP}R$WvfI #uIKLئ #dLZL+8RuT_v *iU9i qGWhvfIh #vIKLn #dL3ZLHz+8RuTy]{ w} d|msg/T\w[*iU9i[qG w} bP8P}PR$Xy-XbX'XVX~axaaI xII II -I"R$W"yfI" #xIKL% #dL ZL,+8Ru`WyfudI #]yIudKL #dLJZLw+8Ru`y]}9 zbP90PPQR$QPqzPbPQhPPAiR$ _kz)_d_zPz{bPzPPR$W{fI #G{IKL #dLZL#+8RuTW${fAI$ #{IAKL* #dLVZLk6+8RuT9?|~*i9U9i~CqGy]{ w} $=!{ K{ _5X% ~varJ'0J8~\K';PXYXK}Y=<Q}1Z'bPpPZPR$ _Q~)__PPKPaOȩ}lOK{  R$Qp~*iU9iqG GG0ŝQ~ud*iU9iudqG q}} { (pn''U%@ $%Vhmsg:(XI>;i_>bSPU<WbkPAk</aWbP<q'QbPت=تbP=KbP=7bPa =ya aU b=b@>x@bPX>'OXb P p>?pbPa>aaIb+=b+>Âxb@PQ > *iQ U9i YqGWmȫ?fPIm #GIPKLv #dLpZL+8Ru\W?fI #IKL  #dLZL+8Ru\A=*iU9i#qG/{*i/U9i;qGC/*iCU9i/QqG>Oby]mpw} msg2(Tc03@Dyl0bPH4'HbPA`4ąaW`bPax4aa7xb=5Hb P 5)Qb P( ج5̆H>جb5PC 5C*iC U9iCKqGW_6fI_ #PIKLh0 #dLZL+8Ru`W6fI #ȇIKL #dLZLH+8Ru`8F[*iU9i[qGp*iU9ipqGˆ*iU9iqGATy]_pw} Hmsg*(PcDh+IyhbYPZ,ZbnPAp,͉a WEbPa,aab=Э-QsЭbP-'&^bP(-ՊH>bP -*i U9iqGW0.fIP #YIKLh #dLZL<+8Ru`W[. fZI[ #ыIZKLa #dLoZLq+8Ru`q0O*iqU9i{qG*iU9iqGˌud*iU9iudqGDy]p"w} /} ||{ { { +{ C{ Y{ { { { $j5CW jj %_  HT +TI IH1p YU [Y `=<U|yp lȮ #qPudT ގ+TAI IA" -pqPvW fI #OIKL8 #dLZL+8Ru_WX fI #ǏIKLp #dLBZLq+8RvW xfI #?IKL #dLZL+8Ru_W fu`I #Iu`KL #dLZL+8Ru_{ T9~dplO{ w} p)e;p{ ]HLstr|'f|'|q=~H$.9c.bP.دPcPFR$ _I)__PMP<POaOM lO<V{ gR$()__Py@L*iyXU9iqGypGGŝud*iU9iudqGf.y q{ p|f'%\\FX_m/\z%w%) %bP%P%Pm =R$ _@Д)_ _ Ŕ)__ PXPk *ikU9i xqGi&'K YYj I( Ij I@ -Ij X# f %bpEb;b pbPQ P R$U *iȱU9i qGWΖf I #I KL #dLT ZL #+8RuTW0Ff I0 # I KL6 #dL ZL F+8Ru_O# *iOU9i# ^qGeɗud*ieU9iudtqG%ky]y]O{ |{ f'%0_m\FluH8 Y YV =<WPfj Ip #ØIj KL #dL ZL  +8RkPlR a1f''_m\Fl H Y= Y I=<WPز!flIP #ܙIlKL\ #dL ZLC y+8Rk=PlRf'(_m \FLu Hq ;PYP ʚY =<h1 hbPP P|R$:ZPb~aгaa*I II II -IR$"[J*i"U9iJqG"(GGJ<ŝWb@ӜfIbh #IKLq #dLZL+8Rudaa6anb=WȴfI #TIKL #dLZL8+8RuD ӝ*i8U9iqGC(*iCU9i(MqGWSf=IS #WI=KLY #dLRZLe+8RuSWq$ fIqP #ϞIKLth #dLZL+8RuDNu\*iU9iu\qGlPuTRu  qy]{ w} n{ q7*iU9iqGGGŝ {ud*i U9iud*qGvy]2{ -@ WIȵWW<i͢bXq 'X X5~a@ҡa^aI ǡI^I I^I -I^R$W`IfI #IKL #dLZL;+8Ru\WfYI #IYKL #dLnZL+8Ru\y]T,2+T@I I@Aض,3A)AaO lO{ hW, f I #ϣI KL( #dLNZL+8Rut +R4 ZMCW%&,̤fI% #IKL+ #dLZL;+8Ruy]%| +V*i+U9iqG+G?G ŝ _*i U9i_ qGi)1@;t1`1 WSyfIS #@IKLX #dLZL2+8RvEŝi{ )֦;Pec&V1#{ _5P3''F -3!%зmsg/Lf|_|z|bP|P_PR$ _)__mPkPPaO `lO{ R$8)__P0Nb  b0bNPNbzPbPhPbPR$:ZPb~aaaI IIظ II -IR$d<bPPPR$ _  )__P%8P6PIaO% ߪlO6.{ ?R$X)__yPHwHbPHpPP`R$cɫbc  bbov0bPvPP+R$:۬ZP[b~aعaapI άII II( -IR$W@WWhhbX'XX(~aa=aI ޭI=I I=I -I=R$W`fI #'IKL #dL ZLS +8RuSWX׮fq IX #Iq KL^ #dL ZL n+8RuSy] 0O *i PU9i qG pG!G ŝn"!*inU9i"!zqG )5;7!5f!5л !f!WW|f!IW #CI!KL\ #dL!ZL!'+8RwIŝq{ t+"*it+U9i"qGt+G5"G"ŝ.CI"*i.U9iI":qG)D;^"Ds"Q|&V5B{ 11&''&' 'W f"I@ #HI"KLX #dL"ZL#X+8Ru_W xf%#I  #I%#KL #dLT#ZL#G+8RwWeqf#Ie #8I#KLk #dL#ZL#x+8Ru_Wfu`I #Iu`KL #dL#ZL#$+8Ru_T1U{ ;''&' 'Wؼf6$I #I6$KL #dLn$ZL$h+8Ru_W0jf$I #1I$KL H #dL$ZL%W+8RwWuf7%Iu #I7%KL{ #dLL%ZLy%+8Ru_WZfu`I` #!Iu`KLx #dL%ZL%+8Ru_VAU{ d ' '& M(  M(Wcf%I #*I%KLȽ #dL&ZL3&x+8Ru_W*۷fQ&I* #IQ&KL0 #dL&ZL&g+8RwWSf&I #I&KL #dL&ZL'+8Ru_W˸fu`I #Iu`KL0 #dL"'ZLO'+8Ru_VQU{  #5]VH~ j_`_b'y_z'@_Y_O_'__':LxYZL'PL (:ZP+(b~aaaT(Iؾ II II -I!R$! ((TB,+T(IB I(AE@,K3A()AaOE @lO(N{ ]hW]X,ûf')I]x #I')KLf #dLI)ZLk)+8Ru_t+ )4 ZMC)W,f)I #JI)KL #dL)ZL)+8Ru_By]%| n+  **in+U9i *qGn+G*G *ŝ R2**i U9i2*qG! ;! -5{  ƽITӏ5_ƽ, ITn5_~# ,IT5_,K G_IT%5__5s zITv5_ žIT5_ž" IT5_ +ITd5_+tP!p'p'(' EP%JP%B% t5G*z߿e* **2oR*H1+bP0P*P+R$P+*ihU9i+qGS+*iSU9i+_qG˽5 ,C,l,,bPPl,P -R$ 1-*i U9i1-qG?$~-*i?U9i~-KqG '`--5  .C. bP58P .P.MR$Z  .*iZ U9i.dqG)O/*i)U9i/5qG5X1dXQ3/Gk/$mrpDm:m/pblxm/ m+07= 1K0*i U9iK0qGv0*iU9i0qGrd0z01<1bPP1P1R$\1*iU9i1qG2*iU9i2 qG(,2d2(HBH2>2HbP`P2P93R$ \3*i U9i\3%qG3*iU9i3qGʾ033=m44l4bP=P44P4XR$c4*icU9i4kqG*5*iU9i*5qG=a1k/Q?5Gw5$mvDm:m5bl|m5 mo67=6*iU9i6qG6*iU9i6qGvpX ZX6X#7b8A7xy78bPPPA7P7R$ 7*i U9i7qGI58*iU9i58qGʾpJ8888bPP8PK9R$ /k9*i U9ik9qGt9*iU9i9qG 1Q9G9$mDm:m(:bl$mz: m:37=>V:*i>U9i:FqG7;*iU9i7;qG<FL;;zQ <;; bPQ8P;P,<iR$t O<*it U9iO<|qG~<*i~U9i<qGQrʾX<<xg=O=xbPP=P=R$=*iU9i=qGk>*ikU9i>wqG1)Q>GD>$mDm:mb>blm> m>7= ?*i U9i?qGE/?*iEU9i/?QqG) o;D? f?)T;?T?a&Vk%kk0kkkG3Ui{ v0H5rhs HH6c{IT5_{L %p%'p&'EP'% JP(% lhs/ݤrhs/ݤ84 |z<4 ~!LP0:?0?Lh K?kL ?z?U ?%@M K=@kM ?z=@0U ?u@Ž5M M͎@ڎ@@5A5M uc]AWM vAM8HA BωM(މBMM@yCMh#?&'CSNVMSN#?VyMeMDNMQV#?AM-MSEN iEENcĉEOt$OcF4$O ZMCFLoV81LGV`OVW{`O09GH=RiOP$҂LRvHVRHheR&IllO9mI mIO7=O< JPJωO+މ'KOOKO#?'KPVMP0#?yMeMLCPMW#?AM-MqMbPHeMMbPpc!ĉMPtPcZN4P ZMCZNL9W0LNVWQwWW{Q= OeO=R$Q$҂LROVRPeRePl'Q=6mP mPDQ7=MQ Aam(QcpQQ8.RvR8bPQPP.RPRQR$Q  "S*iQ U9i"SQqGVPS*iVU9iSVqGQQQpASSzQ TxTbPQP TPUQR$R6$U*iRU9i$U RqGV{U*iVU9iUVqGQRpXRAXUXUb)R "VxzV bP)R8P"VPVDRR$OR aW*iOR U9iWWRqGVcW*iVU9icWVqG)RMRtRXByWWRxGWXxbPRPWPXRR$R X*iR U9iXRqGUX*iUU9iXUqGRR)RA(;XR$YRWRBfaYIR #gIaYKLR( #dLYZLYU+8Ru|WR@CfYIR #IYKLRX #dLZZL]ZU+8Ru|Sp<.{Z5S5ZWDS@fZIDS #IZKLMS #dLI[ZL[U+8Ru||LYS@L[vSRvS5cua[MS#;@AM-M\LS#;MLK\LS5L}\SS@C.\Th5_\WT@=f!]IT #I!]KL'T #dLS]ZL]U+8Ru||L3T@L]PTRPT5ua]L\T#;ML]MsT#;AM-M^LbT5L3^T)UA6;W^Um^UWUBf^IU #uI^KLU #dL^ZL^V+8Ru|WVC(f^IV #I^KLV #dL _ZL9_*V+8Ru|^QXwQXQ&VQkRkfRw^3mTkmbPw(P3mPmR$H6m*i`U9imqG{'n*iU9i'nqGwx]qG`S*i`U9i `qG]4])X]XA;.X]x]g]Wg]B$fIg] #IKLs] #dLɦZL_+8Ru|W]CfI] #cIKL] #dLVZL_+8Ru|]<.]85wW]P@Uf4I] #I4KL]h #dLZL¨_+8Ru||L]@L^R^5ua L^#;MLRM5^#;AM-ML^5Lk^k^Cr.^5(W^ @fZI^ #IZKL^8 #dLZL_+8Ru||L^@Lܪ^R^P5OuaM^p#;,AM-M$L^#;MLHL^5LlE_)`A;``W"`B1fիI"` #IիKL+` #dLZL>`+8Ru|W>`Cf-I>` #pI-KLG` #dLCZLrZ`+8Ru|[X\X\&V[\k\k\  IT, 5_ +>$ X8+, %'' 8+=+ -+%H "Ƭ:M NN:NƬM  K"M:J  J:I  -I: f1Gc <#GGp "GbPp PP R$  "Ȯ*i  U9iȮ qG +#*i U9i qGp    8 $ $  #*i U9i qG #*i U9i qG  A pX X5%XX;b x$YxxbP PYP R$ $*i U9i qG" $%uL*i" U9iuL0 qG  z8 `&LE %bPE  PPC] R$h @ &f*ih XU9ifp qG O&*i U9i qGE f G| p'GG &NbP PP R$  5'̳*i  U9i̳ qG z'*i U9i qG    Y(  G '{*i U9i{ qG >(*i U9i qG  A G )GG (+bP PPb R$#  .)*i#  U9i+ qG s)*i U9i qG ! )6 0r*;6 Pڵ6 p ڵWX [*fIX  #"*IKL]  #dL:ZLX +8RvJ ŝn { ) *;v  H &VW .*iU9iqGCi3P/SIθ.*iU9iqG.uH*iU9iuHqGzpXhD0XIXb/xbPPPbR$/*iU9iqG30ٺ*iU9iٺ qGzo16!0_bP!0P_P9R$DP1B*iDhU9iBLqG^1*iU9iqG!BGX2GGe1WbPkPPyR$ D2ս*i U9iսqG2*iU9iqGe3d3SI$3X*iU9iXqGI3*iU9iqGzG4GG¾3bPPP?R$ 94o*i U9ioqG~4*iU9iqG)8}5;XĿx ĿW<f5fI< #-5IKLA #dL$ZLB+8Rv.ŝR{ )5;`u&V)NA4c@ûc@_B5(c@Qa:c@V::H~:c@:dԺʺSd>SS!dSd S4SId&dxWN?Ժ^ʺS&d!?S^S4dS9dSSEdL`EdWZ@^`WEd?fIEd #?IKLHd #dLZLrd+8Ru_WXd@f&IXd # @I&KL^dX #dLHZLj|d+8Ru_%fp>Kj;^H:`HNaofb:~d_4A::::@Xc~d Agcgcd%ud`ZA:-daAqd|!FdMU!k5_Id%| diB]̆qddMs]q}::d V:LL:WfBfIf #BIKLf #dLZLg+8Ru`ddd(r,E"_d()."d()C"7+(Q:d()~/;"#;;(=;9dP)KDd::dhSV:L:W*gDfI*g #ODIKL/g #dLZL#?g+8Ru`de#Jg)PEC76JgJg~ VբVggbgJg ng g $eyoG_$e).$e)C7+QV:$e)~/;#;;=;0e)KF::4eSV:L:WfFfEIf #FIEKLf #dLXZLf+8Ru`>eMe#f)PKGC7ff~ բfg;ff f g RoeI{go#oeC7oe~ բre gL`re ]^`WreHHfKLre` #pHdLOZL~e+8RuLIe #IWexfIe #HIKLe #dLZLe+8RuLUeIdzn e e +C7e Me{ Ug"Jdzn1 g+C7EgME"g{ goJ*YgMYgRg"K{o#g"C7g"g"~ mբggg g *g wg g g g -f{ Lf{ ~9hgK}K5 pאXKWhkK8LgKqKW5h#LfI5h #KIKL;h #dLZL4ih+8R_(hŝLh{ JLL5C:_LLG'E'}oϭy:118LԸjLNJLTLaLnL {LLL2MR r \M %l M4vXK%y8M4XKW(Nf/IP #MI/KLh #dLDZLq+8RugWNfI #gNIKL #dLZL+8Rug%| %| >{ { { O?O5AAV 'GV 'TW JX NP3H[ORO OO$O 1OZ^ O Ii^ PXoi~Pi}_c~^ `Pr;٪~;~}ɪ;}^ 2Q]̫۫]Xg}rq# .F: M{ ^ Rbq ĩܩЩ0 M0{ %^ .R4CXKW  ^ RfpI  #mRIpKL #dLZL+8Rw2J%| Z*{ 8{ RR5C:ֹ%R$PSWR%S4XKqKgKWSf I #SI KL( #dLLZLnx+8Rugŝ2{ %HT4XKHqKgKW`TfI #xTIKLx #dLWZLyh+8Rugŝ{ W?UfI #UIKL #dLZL/X+8RugWUfMI #~UIMKL #dLkZLH+8Rug%|U4XKWYVfI # VIKL #dLZL4+8RugWVfGI #VIGKL #dLZZL+8Rug%V4XK{ 0WIT xS%:?WTW5AAֹ%0WRpW>]?W*d W>3y*(3z&zzW" $W'/7{ }Qb XE̫Q۫EXZg}jqZ#^ .F:^ Mg{ jb Ybjqppt ĩܩ!ЩCt M!C}{ % b iZ4VXK qKgKVW@SZfIX #ZIKLp #dLZL+8Rugŝ{ Wb ZfI #ZIKL #dL^ZL+8Rug}b [̫۫Xg}q## .F: # M ,{ /b \ b/q 58Z59 ĩܩmЩ9 MmB{ %Hb \4VXKWY*b ']fIY #\IKLb! #dLZLr+8RugQ{{ 0W(Z]t]?W{ $]I_Tp%:|9=:w9=:;97:B@_ ̒]^5c__n__s'j;`ph^e5dGՌ*__xGe_Q%:_}zh L^z}zzAzh MPz}fzZzhSAhA;h_|obA_t]hV]]]A]h} h"j;^`:``Naofb]h0_`]{ ]]V0]|chHb`cch`%!`+hx``UHԾia2ai¾iMi%| }z+iiaz-zKz^Az+iMPz-fzKZz^L5irhcr5i).A4'5i)a5i)~~5i)]SF95in5i"5iPC6_%i} LFiy;e[yrFi).A[4y'Fi)yaFi)~y~Fi)]SyF9FiynFiy"FiPyC6_i} Yi7JeYi]i ĩxܩЩ]i Mxfi{ N:M1fI_Tp %|9'w9';9:B@_ ߜ@fuf57d__n__s'j;sjzfQn5cdG__xGQn&hQ %L{2j L9g`{ x{7l{l{2j M{ 5{7){lJjSH;.JjӿƿJj__REn9eJjVffe"fYmj} zjj;^s:`sNaofb1fzj_hWf{ Jf@fVffVdzjh,d,dj%hj0` ijXaiXjcjMr|j%| L{j ij`{ x{+l{K{j M{ 5{+){KjxrkyYjx).yjx)=1%xK jx)~jx)]2jxsfYjxx# jxx+Rk} jymaYj).aj)=1%Kj)~j)]2jsfYj#j3k} XjgH}[qvj#j .F:j Mj{ :en}n5d__x}n:2nn5cd__xn2;}!n9p5AAw %:Vnx {oonen/}z pozqzzAz MPzqfzZz*^dy o,d,dny nn*L{-p`{lx{l{{M{l5{){BufvpI_TpP;|9Bw9B;9BB@_ pp5d__n__s'j;xkpx5dG__xGxzrQP;|k Lq||3|HD|k MS|i|3]|HkS-[ k[k_B[5(Q9pkVgp[ZpMpvp k} l"j;^x:`x0Nauofbpl0_Nsp{ ppV0phdlH'swdwdl`%rUlx`tsr@2lashq2l|F2lMUk_>l%| |KliZt|||D|KlMS|i|]|Ulr-v *Tr>Ul). ~*qTdrUl)"*T r0Ul)~*TrfUl)]*TrUlX*KT>rHUl*|TorUl*Trl} flyx.N>fl).~q.dNfl)". N0lfl)~.Nffl)].NflXK.>NHfl|.oNlfl.Nl} &yl5K?yl}l 1Ƭ}l Mլ߬1l{ C7xx5d__xxeCPOxy5>[@@{ P;Dxc| x|x|k y|||D|k MS|i|]|pk #yy5@@ P;x  Ry0z5@@ P;Ōy*0RKz}z5@@P;WŌ{yzz5\rzTrz;;zz5tDzTDz;;{{5\ؾ+{(5HP(ȷ6T{ETȷI 6IȷI IȷI -Iȷ(pos5(AA@'|gAZAPAAAX|gA&ZAHPAfNp |NNHNfI C|IfN<$}z%zz_zz@s,~zfzz;WE}fpI #d}IpKL #dLZL+8RudWE~fI #}IKL #dLZL+8Rud^ltztsv{58~NRDWX~fIx #~IKL #dLZL(+8RuZWofI #6IKL #dL2ZL_+8RuZzsrslsl)c<%| { [[#WwfCI0 #>ICKLH #dLeZL7+8RvWfI #IKL #dLZL+8RvWV#gfIV #.IKL\ #dLZL$h+8RuZW߁f7I #I7KL #dLLZLy+8RuZ %| y{ w} { q{ 1yI_Tp@|9@w9@;9@B@_ ħ5V__n__s'j;X0mՂ5}G͡__xG`nQ@}Vm L2}J} >}|Vm M|} |vmmxS2cmmx 2cImmx_2}cpx-mmxV[2NcAxjm} m"j;^X:`XNaLofbvym_B{ Vmm%ڄm`hma?mhmMh{m%| }miN2}J}>}|mM|}|mr!cVI+<Im). +Imm)+Ig+m)~`T+HIm)]+Im+I8myl+_Igm +I)n} n(ycVI<%n(). %mn()%(C+n()~`TH%n()]%n(%8n(yl_%(Cn( %()ckn} ŮnԮޮnn en Mt~&n{ @Ŋ5}__xŊA(@[5.Henv@^HS}f 2}J}>}|f M|}|  Ëً5KpA=cnCË͋nŝ0ITJxS5ANITPxS@]r5Hֹ%N}}]gtX-ttH"tX(YtLt?tnh $0WT?W{ )G n)G(00 B^tK0TK|9{ ' 6͋ËŝP_<U.Ka!pN( l1U W4fI4 #׎IKL6 #dLZL+8RudWfI8 #JIKLP #dLZL+8RudŝP{ 9JhHJ0r^JVk0#k0j$j0jgk&1Uvkj&6jjMkE0\k̞S/0۞S4SCYM1SW  "DԝW MD`{ ̞!-/۞!-4!'CYMW!'&! "jԝ&!Mj/!{ }c}̫c۫}Xig}qi#m .F:m Mv{ yyƱyձRaw k9  (@L 4n  ML  n { a CR ŮԮ ޮ    e Mt ~ { F  ;'. PzPx PR$PP PR$́ z=R! ˆ0ٕӈ W0;f IP #I KLh #dL ZLI +8Rud}; g ̫; ۫g XA g} q A #E  .F : E  M  N { yQ } ƱQ ձ RW aw k# W [  (@6 4X [  M6  X d { g Ok Cg Rk Ům Ԯ ޮ m q    eq  Mt ~ z { ˆ  ӈ W  ;f I  #I KL  #dL ZL2  +8RucP  _E  <' 66w    & 8    { m!N!(]!!{ )™י5.Hֹ%!™N!,] !!{ 4"C Y P:"yPPR"R$PR"yP-Pd"R$ " :"m"=v"""{ ""{ "(4™""{ `key-%key-%p5Hl3H#ϛŤ+#EB#cb#r0~PJ%XufPTPb%R$Pb%xuP|Pt%R$m#$ J%%=%]&{#4{#APPP &CP;P"&R$P"&8sPcP4&R$#  &?&=H&N'#{f#u{L#}[{#PKӰ#P#P}ðc#rw٪#w#}ɪw##.ɝ#|#}\$ ?*s =$ iV)Lmb$hs~$$`$mX|P%6PoP%R$P%fPP%R$$ %%=%5'$$h$}w% ˆ`&!ӈ W`&!;f I`& #\I KLf& #dLZLLv&+8RuS'& 6_&P&(_&<}&̫&۫X&g}q&#& .F:"& M"&{ y&5Ʊ&ձ5R&awKki&& (@|4& M| &{ &`C&RŮ&Ԯޮ&& e& Mt~'{ K#Z#0$A$$%|  %%| "%y&{ &&&' 'r'(Ԥߤ5.HŤlQ' Ԥc'@r%h~\P(ucPP)(R$P)(uPP@(R$'$ (N(=W(l('%| 't({ ({ (({ }(s9(%} (+)O} (!h(?} )ׂ 3){ ѵ@) o(HH;TTT)+TIT) IPTd)ImTaT'o)>| ')@:6W.@fI. #IKL.( #dLZL&.+8Ru`))f@gf9I)` #.I9KL)x #dLZLH,+8Ru`')@6)*f'%*ۨ@6/*7*fK*Y'SK*ETS'SK*JSS'T*ˆT*ӈpWT*;fIT*8 #IKL]*P #dLZLK,+8Ruˆf*hӈiWf*;fIf* #GIKLl* #dLZL* ,+8RuWu*fH Iu* #ªIH KL{* #dL ZL ,+8Ruˆ*ӈ W*;f I* #VI KL* #dL !ZL- #dL(ZL(K-+8RuPˆK-|ӈ(WK-;f(IK- #BI(KLQ- #dL(ZL)^-+8RuPW^-+f')I^- #I')KLd-% #dL<)ZLi)q-+8RuPˆ-ӈ|)W-;f|)I- #MI|)KL- #dL)ZL)-+8RuPˆ-ӈ)W-;f)I- #I)KL- #dL)ZL*-+8RuPˆ-ӈ&*W-;f&*I- #sI&*KL- #dL;*ZLP*.+8Ruˆ-+Bӈc*W-+;fc*I- #Ic*KL.% #dLx*ZL*.+8RuCWN.f*IN. #I*KLT. #dL*ZL*a.+8Ruˆa.Qӈ*Wa.;f*Ia. #I*KLg. #dL +ZL+t.+8RuWt.f2+It. #I2+KLz. #dLG+ZL\+ˆ.Lӈo+W.;fo+I. #Io+KL. #dL+ZL+.+8Ruˆ.(ӈ+W.(;f+I. #I+KL." #dL+ZL+.+8Ru.+Rf+I. #I+KL.% #dL+ZL+,/+8Ru`/ùf>,I/ #I>,KL/ #dLS,ZL,0/+8RuX7/Oӈu`W7/;fu`I7/ #Iu`KL=/ #dL,ZL,J/+8RuX))) **ڗ#*J*+*|*N*y*Ő+L+o+++ڗ++++v,z-{ P/\d5HY1d,bm/vbbb,|/T/+TU-I/ IU-[/@һ[-W/XJf-I/x #I-KL/ #dL-ZL-X0+8Ru_W/¼f.I/ #I.KL/ #dL3.ZLU.0+8Rud/s..b/  bs.b./We0f.Ie0 #[I.KLk0 #dL.ZL.w0+8Ru_W0 f/I0 #ӽI/KL0 #dL'/ZLT/0+8Ru_m/N/s/%| //0z20{ @0w} 0{ 0{ 1h0,#0t00/0dz0,#0z00/1me17S3H %#$1H)1=1ITiP1t`1XZg/#`1e1*e1 9/ae1 "a/r1F/Dr1(0[/O01 1 1+ 1w} 1H 1#t1#^1 1| 1+ 1w}  fd8 %V9/Z:-; % G%K1 5\@f'%}< %02+>0p0$2[ \42 \\0X: %0W>2Lf0KL>2 #/dL0ZL04+8Ru}Iy3 #I0]2v 1k2U W3f.1I3 #I.1KL3 #dLR1ZLv14+8RwW3ff1I3 #-I1KL30 #dL1ZL1o4+8RwW3Hf1I3 #I1KL3` #dL2ZLB2_4+8RwW3xVf`2I3 #I`2KL3 #dL2ZL2O4+8RwW3f2I3 #I2KL3 #dL2ZL3?4+8RwW3Ff,3I3 # I,3KL3 #dLP3ZLt3/4+8RwW3f3I3 #I3KL3 #dL3ZL33+8RwW 87f3I 8 #I3KL8 #dL3ZL4$8+8Ru}W$8#f)4I$8 #vI)4KL-8 #dL?4ZLn4<8+8Ru}W8)f4I8 #I4KL8 #dL4ZL48+8Ru}W8)f4I8 #hI4KL8 #dL4ZL58+8Ru}W83f15I8 #I15KL8* #dLG5ZLv58+8Ru}W8f5I8 #ZI5KL8  #dL5ZL59+8Ru}W9 f5I9 #I5KL9 #dL5ZL&6,9+8Ru}W,93f96I,9 #LI96KL59* #dLO6ZL~6D9+8Ru}x2~ 2o2233):3X3s3y3iP28U2\4\]4 7$].]6~a4Pa6a6I4 I6I4 I6I4 -I64R$W4h=f6I4 #I6KL5 #dL6ZL65+8Ru}\M5c\\ 7g5w7}}N75>+7775[ -8~a6Ia@8ad8I6 yI@8I6 I@8I6 -I@86R$WF6Ifw8IF6  #Iw8KLR68 #dL8ZL87+8Ru}W9"Ivf8I9 #<I8KL9 #dL8ZL"99+8Ru}5,56P&6P/6=>6PF69~a7PECa59aI7 8I59I7 I59I7 -I597R$W7hEfY9I7 #IY9KL7( #dLo9ZL97+8RwW9%E4f9I9 #I9KL9 #dL9ZL99+8Ru}^6Jy9*i^6U9i9n6qG6\@::6\bP6P:P/:aO6lO:6R$_9JIH:*i_9U9iH:o9qG55~ 7y]779\6\\^:Q574Qr:*Q:<7<\[7\\:WG8pf:IG8 #6I:KLP8 #dL:ZL:c8+8Ru} 2~ 4,44P47$7P37PK7PS7u897~ E8{ w9{ 9{ }95\m': %;W!:(f;KL!:P #dL5;ZLW;<+8RuCI;p #I;=:uAu;P: W+;f;I+; #WI;KL1; #dL;ZL;;+8RwW9;f;I9; #I;KL?; #dL<ZL2<;+8RwWG;fP<IG; #GIP<KLM;  #dLr<ZL<;+8RwWU; f<IU; #I<KL[;0  #dL<ZL<;+8RwW_;H pf=I_; #7I=KLe;`  #dL6=ZLX=;+8RwWi;x fv=Ii; #Iv=KLo;  #dL=ZL=;+8RwWs;`f=Is; #'I=KLy; #dL=ZL>;+8RwW<f>I< #I>KL#< #dL*>ZLW>/<+8RuCW:<Pfj>I:<  #Ij>KL=<  #dL>ZL>R<+8RuCWR<f>IR< #I>KLX< #dL>ZL?d<+8RuCWd<@f?Id< #I?KLj< #dL)?ZLV?v<+8RuCWv<fi?Iv< #Ii?KL|< #dL~?ZL?<+8RuCW<0f?I< #I?KL< #dL?ZL@<+8RuCW<f@I< #oI@KL< #dL(@ZLU@<+8RuCW<W fh@I< #Ih@KL<Q #dL}@ZL@<+8RuC]:~ ~:o::::)::;;i0: 5:\;\;H 8<{ =$z5] oa% % :& %@WO=8 &f@KLO=`  #xdL@ZLAH?+8RuIJ>  #I@W[> & f0AI[> #I0AKLa>  #dLRAZLtA7?+8RwWi> &fAIi> #LIAKLo>  #dLAZLA'?+8RwWw> &fAIw> #IAKL}>  #dLBZL8B?+8RwW>( &ufVBI> #<IVBKL>@  #dLxBZLB?+8RwW>X &fBI> #IBKL>p  #dLBZLB>+8RwW> &efCI> #,ICKL>  #dL+8RwW>&f|CI> #I|CKL> #dLCZLC>+8RwWU?#&VfCIU? #ICKL[? #dLCZLCg?+8RuWx?&fDIx? #IDKL~? #dL%DZLTD?+8RuW?&HfgDI? #IgDKL? #dL|DZLD?+8RuW?&fDI? #IDKL? #dLDZLE?+8RuW?&:fEI? #IEKL? #dL*EZLYE?+8RuW?&flEI? #yIlEKL? #dLEZLE?+8RuW@&,fEI@ #IEKL @ #dLEZLF@+8RuW@&fudI@  #kIudKL@  #dLFZLIF2@+8Ru={ =~ =o===>)>/>D>J>i`= &:e=\>\\>'d\\F\{FI=p?{ \5\ֹ%z9A oyW=o v;fFKL=o  #dLFZLFp+8RuGIp8  #IFWPoP vfGIPoh  #zIGKLVo  #dL:GZL\Gp+8RuW^o v-fzGI^o  #IzGKLdo  #dLGZLGp+8RwWlo vfGIlo  #lIGKLro  #dLGZL Hq+8RuWzo( v!f>HIzo@  #I>HKLoX  #dL`HZLHq+8RuWop vfHIo  #`IHKLo  #dLHZLH8q+8RuWo vfIIo  #IIKLo  #dL$IZLFIXq+8Ruov?o\]q\pv!dII.A'p8 y 3AJ)A]J;phxr!fuTIxrX #IuTKL{rp #dLJZLJr+8RuP'pPpvJ.K.A\p y 3AuK)AKnph,rLf>LI,r #I>LKL/r #dLSLZLLHr+8RuH\popvtLL.A}p y l3A)M)AqMph}pW|qvfMI|q( #IMKLq@ #dLMZLMq+8RuGWqvdfNIq #+INKLq #dLNZLDNq+8RuGWqvfWNIq #IWNKLq #dLlNZLNq+8RuGWqvTfNIq #INKLq #dLNZLNq+8RuGWqvfOIq #IOKLq #dLOZLCOq+8RuGWqvDfVOIq # IVOKLq #dLkOZLOq+8RuGWq>vfOIq #IOKLq8 #dLOZLOr+8RuGoŝooopPp)pi r{ zԈr(5rr{ Ya}r)Qk2rXdDPrYUs3kYspdkP2spdDP%s-s{ a@s)C2Os-D>Pdskps3_s-]P2s-D]Pss{ 557$PC:D@@H=|P#a@P<f@W@SfPI@ #{IPKL@ #dLPZLP@+8RusW@S,futI@ #IutKL@ #dL QZL7Q@+8Rus@@i@{ W|5]'%1H6@`Wan@JQ@@A?Y'%Y1T@Z'kZ % ZG#OA[pTATA[iQ2aTAAaQ(&'msg/fA1 50(75Q<X JRA`9IR`XARESbPAPRPSAR$A+STbPAPSPaTAR$AܑTTbPA PTP'UAR$AHLUUHbPA`PLUPUBR$B]V*VbPBPVP?V6BR$Gh7BghdV]h|VbQ;B4QV*QVEB<HB#VVHBbPHBPVPV+PBމK WA#WbPPBP WP8W]BR$oB PW*ioB8U9iPWqGoBPGWGPWBŝCM$7W*iCM$U9iWRMqGAoBy]~aBh9aWaIB IWIB IWIB -IWBR$WB9KfXIB #IXKLB #dL*XZLLXK+8RuWB=fjXIB #IjXKLB #dLXZLXXD+8RuWC =?fXIC8 #IXKL CP #dLXZLYxD+8RuWCh=f,YIC #~I,YKLC #dLNYZLpYD+8RuW"C=3fYI"C #IYKL(C #dLYZLYD+8RuW0C=fYI0C #rIYKL6C( #dLZZL4ZD+8RuW>C@='fRZI>CX #IRZKLDCp #dLtZZLZD+8RuLC=QQC\D\W"D=fZI"D #IZKL+D #dLZZL[;D+8RuW/E?Bf=[I/E # I=[KL8E #dL[ZL&\K+8RuXEE HbOEw} WxE KfD\IxE8 #ID\KL~EP #dLf\ZL\F+8RuWEhKVf\IE #I\KLE #dL\ZL\F+8RuWEKf]IE #I]KLE #dL*]ZLL]F+8RuWEKJfj]IE #Ij]KLE( #dL]ZL]G+8RuWE@Kf]IEX #I]KLEp #dL]ZL^8G+8RuWEK>f.^IE #I.^KLE #dLP^ZLr^XG+8RuEKhE\]G\WFKf^IF #I^KLF #dL^ZL^F+8Ru{]hGL ]_]1_0`:N %_W]HXNf_I]Hx #eI_KLfH #dL_ZL`K+8RuWnHNf&`InH #I&`KLtH #dLU`ZL`K+8RuW|HNf`I|H #XI`KLH #dL`ZLaxK+8RuWHN faIH #IaKLH  #dLMaZL|ahK+8RuWH8NfaIH #LIaKLHP #dLaZLaJ+8RuWHhNfaIH #IaKLH #dLbZL@bJ+8RuWHN{fnbIH #@InbKLH #dLbZLbJ+8RuWHNfbIH #IbKLH #dLbZLbH+8RuGU G~ GoGG HH)/HDHWH]HiGNG\H\U]H Od]cn]#c#HVH[HV[7c :Z %dcWI8ZfcIIX #NIcKLIp #dLcZLcXK+8RuWIZfcII #IcKLJ #dLdZL*dHK+8RuWJZ|fHdIJ #AIHdKLJ #dLjdZLd8K+8RuWJZfdIJ #IdKLJ #dLdZLd(K+8RuW$JZpf eI$J #5I eKL*J0 #dL.eZLPeK+8RuW2JHZfneI2J #IneKL8J` #dLeZLeK+8RuW@JxZdfeI@J #)IeKLFJ #dLeZLfJ+8RuWNJZf4fINJ #I4fKLTJ #dLIfZL^f`J+8RuW`LZWfqfI`L #IqfKLfL #dLfZLfrL+8RuWvLZffIvL #IfKL|L #dLfZL gL+8RuWLZI f gIL # I gKLL #dL5gZLdgL+8RuWLZ fwgIL # IwgKLL #dLgZLgL+8RuWLZ; fgIL # IgKLL #dLgZLhL+8RuWLZ f%hIL #z I%hKLL #dL:hZLihL+8RuWLZ- f|hIL # I|hKLL #dLhZLhL+8RuWLIZ fhIL #l IhKLMC #dLhZLi M+8Ru5I~ ZIolIIII)IIIIi{JU `JZ; eJ\J\]J [e $]*i.]Ii J\ &ii}iWKK fiIK # IiKLK #dLiZLiK+8RuWKK fiIK #G IiKLK #dLjZL7jK+8RuWKK fJjIK # IJjKLK #dL_jZLjL+8RuWLKsfjIL #9IjKLL #dLjZLjL+8RuWLKfjIL #IjKLL #dL kZLsbsqOOsssO|WOftIO #NItKLO0 #dL=tZL_tP+8Ru\WO(f}tIO #I}tKLO" #dLtZLtP+8Rwh*PPQtttuw"u;P|WPfZuIP #IZuKLP #dLouZLuP+8RuGWPAfuIP #IuKLP #dLuZLuP+8RuGWPfvIP #IvKLP #dLvZLFvQ+8RuGWQ#1fYvIQ #IYvKL Q #dLnvZLvQ+8RuGW*QfvI*Q #pIvKL0Q #dLvZLv__s'j;sG2 :5aG__xG :!3Q5AHs L2fs Mfs!S*?s!sf*s!_*!H1s!V111*!1ht}  t"j;^:`NaޭӇofbޭ1 t!_42{ 21V! 2eQa t!4`a`a't"%L4Q* 6v L,=π*Uۀj6v M*UjMv`#S}"Mv`#c}VIMv`#_}`# ;Mv`#V<};;`#<,uv} v"j;^:`RNaofb$<vx#_>J<{ =<3<Vx#Y<)v#>v#%>v#`?(b:v#a?IS#v(vM Əv%| vi?πڏۀ vMڏ Yv#rA.Lvv#).N.AL4v'v#)Lv#nv#)~Lv)v#)]`LSvFv#Lv{v#Lv#/v#]LPvC#lҐow} Yv$yC&Ppv$).NA&4P'pv$)&Pp$nv$)~&Pp)v$)]`&SPFpv$&Pp{v$&Pp$/v$]&PPCp$lKw} Lv[qevv "%:8.Sv M%8Sw{ JDwnaDrE5hof__xorE 0$__nrwrDrw$rrwH$r E(nDxvfEπVUۀxMVUwh<D xxEG5s__x*`$__y*46x$*GRpY6x$*FhrW6x$ fKL6x$ #eFdLZL̓x+8RLInx$ #IMPx *\ߓfPx * ߓ!Px Mߓ[x{ nxwEl.G}G5Bm* }G S7 j; __r  %xG\{~dfYI>\x- #EdIYKLA\- #dLnZLY\+8RuGWY\1{dfIY\ #dIKL_\+ #dLìZLl\+8RuGZUbZ&VZkZk3[:L{[:L[u\{ \Enp~'p~'EP~ JP~ ]~e' ] '*]ZT *]~8fuV *] V>]ZTMG]-~cgmcP]-fH-bPP]-PHPŮh]R$s]  g*is] U9i{]qG_Rg"*i_U9i"_qGP]q]]-~h7oz] .gԯ .bP]8.PP]R$]X.8h<*i]p.U9i<]qG}_}hv*i}_U9iv_qG]]M].~imcð].i(.bP].PP`]R$^ ci*i^ U9i ^qGj_i*ij_U9iv_qG]^^.~jű&^/Ij'O/bP&^/P'Pm>^R$K^ j*iK^ U9iS^qG._j*i._U9i:_qG&^I^)k^8/~k;k^X/˲k^x/ ˲W^/kfI^/ #kIKL^/ #dLZL=_+8Rw^ŝ^{ W^/~Jlf[I^ #lI[KL^0 #dL}ZL^+8RvW^.~lfI^ #lIKL^( #dLҳZL^+8RvW_~:mfI_ #mIKL_ #dLZL<%_+8RuG)=_~m;O=_dJ_WM_~mfIM_0 #mIKLP_00 #dLZLӴh_+8RuG\UG]&V]k]k^:L`^:Lk^._{ _Gwp'p'EP JP `n  `  `ZT `:ou9 ` 9.`ZTM7`H0epmhc@``0o+c`0bP@`x0P+PX`R$c` p˶*ic` U9i˶k`qG|bTp*i|bU9ibqG@`a`˽w`0qR`0p0bP`0PP`R$`0:q*i`1U9i`qGmbqY*imbU9iYwbqG``M`(1rmnc`H1 rӸ H1bP``1PӸPC`R$` erf*i` U9if`qGZbr*iZbU9ifbqG``a1sйa1Ks 21bPa1P PP.aR$;a ss*i;a U9isCaqGbs*ibU9i*bqGa9a)[a1t;[a1[a2 úWa82tf׺IaP2 #tI׺KLah2 #dLZL a+8Rwsaŝa{ Wa2Luf>Ia #uI>KLa2 #dL`ZLa+8RvWa.ufIa #uIKLa( #dLZLʻa+8RvWbfId #IKLd #dLZLe+8RuG)e;e**eW-efWI-eX5 #IWKL0ep5 #dLlZLHe+8RuGbU'c&Vgckckc:L@d:LKde{ peKp'p'EP JP e e eZT e>u e fZTMf5im.cf f5΁)5bP f5PPn8fR$Cf *iCf U9iKfqG\hX*i\hU9ihhqG fAf˽Wf5ef6E}6bPef6PEP}fR$f86>*ifP6U9ifqGMh*iMhU9iWhqGeffMfh6m4clf6$6bPf6PP fR$f i,*if U9i,fqG:hY*i:hU9iYFhqGfff6nf6O6bPf6PPgR$g 9*ig U9i9#gqGgمL*igU9iL hqGfg);g7؆;a;g87t;gX7 tWagx7fIag7 #IKLcg7 #dLZLg+8RwSgŝ|g{ Wg7PfIg #IKLg7 #dL&ZLHg+8RvWg.ȇffIg #IfKLg( #dL{ZLg+8RvWg@fIg #IKLg #dLZLg+8RuG) h; h hWhf:Ih7 #ňI:KL h8 #dLOZL|8h+8RuGeUf&VWfkfkf:L0g:L;gg{ !p~S_/| p~Sw p~S  q/ <(8= t`8 t:q-R@ |ktjߏ@ -u`@ c``kLRS tj&ߏS -r&u`S c`&`_Rf gtjzߏf -zu`f c`z`rR xt.jߏ -2u` c``8 z ~#&Ѐ BNR  tvjߏ  -u`  c``,3 ߌR6 ]tj ߏ6 - u`6 c` `0BI |\RL ttjߏL -u`L c``X"' '%C ' ,4"pB_/| pBw pB  q/ <8= tC8 tҎmW`f8 |Y8- I vII II -I 5( 8 .r8- I VII II -I@ 5( K ȁ9 r/sȁ9- Iȁ 6IIȁ IIȁ -Ih 5( s  xR0- I II II -I 5<(Ob  " zqu V ~ ~ Ă 9 Ă 9-7 WIĂ SIWIĂ IWIĂ -IW0 5u(?  ˂ ΂ ΂- I΂ RII΂ II΂ -IՂ 5&(9L 89 ƕ_89- IP9 2IIp9 IIp9 -II9 II II -I 5(8#   Kk0Pk5Qs-kn"`k_ 0| pkw pk  q 0 <9= t cv9 t#8G x͘-ܘ{|  |\͘-;ܘN҃{| ݃ ͘-ܘ{| " ͘-ܘ{| S X!͘U-4ܘGf{| ;m wJZp ˘r͘r-ܘ{| ; J# >͘!-ܘ{| ;9 z]J;؄ ~|J$; JL"ޙ;k_| kw k  0_ -"APk_ 0| kw k  0P5ao__xo__nrAX5a__xAh˚d5H_M'GN'TO JP:ORtzZAAX\h8:TsukhhP:TqhP:6q qhTqh$qqhh:TЙÙ'hh Z,h"hhޙh:  hh:-,h"hh+h:-D:hh:-,h"hhVh:-퐝hWh;2fIh0; #UIKLhH; #dLZL?j+8Ru@V l!-hu`W l!2fu`I lh; #Iu`KLl; #dL2ZL_)l+8Rud i; Z4r([ i vrlh i-܂,hr"hi/i; O8V/i;-܂hW/i;2f%I/i< #I%KL2i(< #dLZLj+8Ru/iCiH<  VCi`<-܂hWCix<2fICi #ΟIKLIi< #dLZLLPj+8Ru@VQi< hzWQi<2fIQi< #dIKLWi< #dLZLhj+8Ru@Vk 3hWk2fIk #IKLk #dL-ZLZk+8RuOk mVk-܂hmWk2fmIk #ImKLk #dLZL l+8RuV_i=TvhW_i =2fI_i8= #;IKLeiP= #dLZLj+8Ru@Wmih=Tf Imi= #I KLsi= #dL.ZLPj+8Ru@Wi=_ifnIi= #.InKLi= #dLZL;k+8Rujf!A j>f@fDZfP>t\k v4!6\k M!6,j/2j>iפIkj̤jM)k/2djl,d,dnj8>lnn4L{j`{Xx{nl{{jM{X5{n){WkufWyk#TfIyk #ץIKLk #dLZLk+8RuOVk ThWk 2fIk #jIKLk #dL ZL:k+8RuOWk_fMIk #IMKLk #dLbZLwk+8Ruhi%| iiiOk{ k{ k{ 7s5HTJ%:0l/í_''G'E' }oϭTJy:`>C:Wl>̨fIl> #IKLl> #dLZL=m+8Ru_Wl>Df[Il # I[KLl> #dLZLm+8Rw#l dldl? J}sl 6TloETnIl 6In"`l0?p1`_l|7_Tl}+TIl ISmH?ɪT.S]Sm`?JS.S](mˆ(m?]ӈW(m?;fI(m? #"IKL1m? #dLZLm+8RuT:m?6T:m?oETI:m? 6Iˆ=n"Hӈ:W=n";f:I=n # I:KLCn #dLOZLdPn+8RuTllnmRSmŝrmmPmPmmWnfwIn@ #֬IwKLn @ #dLZLn+8Ru_Wn"fIn #NIKL!n #dLZL.n+8Ru_Zljlvl%| lm{ m{ 7n{ C&¶ζڶ 8@ %$X@ڶζ!¶AlX@B+x@%bAVl+x@.vAlo;@%u7WzO;@ OOWOzOH iQOO/OBWG Ns gNNaOC%O!O^@%:Ot0O:OV0OUJ JN NNuv"# ;4 `n_#@ (pHK"H!6TO6Xfn@@.AnA y #3A)Anhp!fIp #[IKLp #dLZLp+8Ru`nTwnر+TIwn In0AF0A.AnXA y k3A)AaOn `lOn{ nhEq!ܲfuXIEqpA #IuXKLHqA #dLZLaq+8Ru`nWnA\fInA ##IKLnA #dL[ZLp+8Ru`TnA+TInA IPTnB̳mT$aTKn>| tn0B`4n0B ZMCtn\4n ZMCoHB<ҷ ƷjUo`B% vji`B o`B ; .j!`Bo4o%ZMC"SoxBpS"Sk(oW(oBfI(oB #IKL1oB #dLZLp+8RuWSNoBS;SjXoWXoCfIXo C #[IKLao8C #dLZLp+8RuW6TioET-Iio 6I-Iio I-Iio -I-WoPCfOIopC #GIOKLoC #dLqZLo+8RwWoCfIoC #IKLoC #dLZLo+8RwWoDpfIo0D #7IKLoPD #dL5ZLWp+8Rw^0p ʸ,^u"^0p 3uDpO^PphDN,^"^PphD 3aOPp }BlO\p{ mpO^mpD,^"^mpD 3pOWpf@Ip #I@KLp #dLUZLjWpf}Ip #MI}KLp #dLZLq+8RuWWqfIq #źIKL q #dLZLq+8RuWWqvf'Iq #=I'KLq #dL<ZLi)q+8Ru`W)qf|I)q #I|KL/q #dLZL;q+8Ru`LooOoOp{ p{ 111PpqE[5HXgDP hjRZq %" rr %~ D;is&' QaqDs`aI `aI DtAA _u[ Ejx&'G cq(Ex^cq cq HEyC: z\F\“}%  % b%A H%a nr  WtrhEmf Itr #2I KLzrE #dL ZL Hs+8RuWsf< Is #I< KLs #dLQ ZLf s+8RuKrrrOrOr&rvAy  WPsEf IPs #I KLVsE #dL ZL:s+8RuLWs#3fXIs #IXKLs #dLmZLs+8RuLqs|s|s{ 13tx3'EBO4HtI*t4II6t} =t6ҷƷ5H~U=tE%v5iHE =tE ;.5!HEJt4Jt%ZMCntt{ str )'[% *'str '[% 'S/3ti2%5%T@/4'k/4 %&/4'E7~/5@[X/'hFy/@\FD[V/F%9uF/@eFPTu *mT,aTeu>| u +ҷƷUuF%viF uF ;.!F+u4+u%ZMC v7u$/A CLuG[uF/BFbP[uFPPsuR$:suF/BDZPFb~asuGaaIsu 7IIsu IIsu -IuR$u8G/B 88GbPuXGP PMuR$WuG/C!frIuG #IrKLuG #dLZLv+8Rvv:it/Gwvv/Hy2v0XA\0vG/Gk9v$bCv/JbbGQvXv/Q\qXvjvLWmv/V{fImvG #TIKLpvH #dLZLv H/S HbPv8HPPvR$:vXH/SZP*XHb~avxHaa?Iv IIv IIv -IvR$vH/T.d$|HbPvHPdPvR$WUx/VfIUx #?IKL[x #dLZLkx+8RDu=/> u= PTuH mT1aT u>| RSu #]S`ue vJit/Xwvv/Y\2v0XAOwH/\oeHbPwIPP*qwR$\w(I/XkOw$9w@I/[gGwGWGwXI/[fIGwxI #\IKLJwI #dLZLw+8R _wwI/\)_ _/I)__QwPbwI/\CfxIbPwJPfP~wR$6ww/abw  bbwWw(J/`fIw #IKLw@J #dLZL -x+8RJw/=`[)w0Z)xwEx /h>*ix U9i>xqGJ1x/=[S1x0ZS?xwE?x/h,h*i?xU9ihKxqGWsx/`f}Isx #jI}KLyx #dLZLx+8R@Tx/c+TIx IWxXJ/cUfIxpJ #IKLx #dLZL4x+8R@^x/etx| Wx/cfIx #IKLx #dLGZLtx+8R@twy]xxJ xw} Sx{ 618!y@kC!J`R!Ja!l!PT0yJmT@aTQ;y>| HyJYҷoƷUHyJ%oviJ HyJ ;o.!JUyWiyJfIiy #IKLlyK #dLZLy+8RufW$z@fI$z #IKL'z #dL2ZL_7z+8PwtRuffypypzp@z{ %<%:,Ki %8K[[o[|P\F\argHTPK<+TIPK I$+ZjB %bȈLb b1ڈbLbSbk"b)Mbb;bBM*bbTWZhKfIZK #iIKL`K #dLZL +8RucWnfudIn #IudKLt #dL<ZLi+8Ruc?PuLv2$w"||ӆ|<|_|ȇ|o1oT|wo|cPuP/{ &@z!Rb:b,\zkA%'%:MKi %|K[[o[|P\F\argHTK#+TIK I&AjB %bLubb.bLbPbhbMb}bbMbb,W/KfI/L #PIKL5(L #dLZL +8RucWFfudIF #IudKLL #dL9 ZLf \+8Ruc:|||Ί|7Z}|Ë|o o,|Oor|;PuT_/e{ epz!_:_MzRpi1ybIR@L{~Ry S P{P PR$ōŝ &<= GO{ =5mmCKUoKMCK%zU5H z`L!z`L!z`L!`L{!!!z!z%!"L-F"P:{LlPPQ{R$PQ{LPz"Ph{R${z :{v{={{{"z zz%| {{  { (5Hp@E{L^5T"&{L5"{L"L#7#7#{b#{##M-#PJ|0M\PPa|R$Pa|HMP2$Px|R$|z J||=|||J${ {{%| |{ J|\5`M`3/Hj$#|/\||=||}H5;09}7B}5 (x;(09LP}7;a}p5ֹ%`3<HaČ}]pxM$#}<}}}a'}(6p ~~{ %EP5*6{ ~PlE#C~\H~#S~M]^~S~=j~;5*ֹ%p~9;#~b0~~~(Wq~~{ >NPX, ?$?ajMgu$WjM]f$KLjM # dL%ZL5%+8RLI #I$;F5 \Um5h__xmD5d5h__x>7b5u__n:B`ݐ|)DBw)DB;)Eݐ*)Gݐc-SIStr5 $Sic7$g5 N'U9Dy %H X4{]4%: %C+%X5>a!K +5,K:@ %d5 ֹ%i~~y(_H5MTH`3M>XS%fN Uf%$PVy%Q%zX}^\Fz@]a\FzHf} r#~Mk~*~O9S%a~"a%U]!Td]%n]&WpNYKf=&Ip #I=&KLy(N #dLo&ZL&++8RuzW@NYf&I #I&KLXN #dL&ZL?';+8RuzWpNY?f]'I #I]'KLN #dL'ZL'+8RuzWNYf'I #~I'KLN #dL(ZLC( +8RuzWNY3fa(I #Ia(KLN #dL(ZL(+8RuzWOYf(I #rI(KLO #dL)ZL+)#+8Ruz0OY\(\WHOYPfI)I`O #II)KL #dLr)ZL)+8Ru}W@xO\f)I@ #I)KLIO #dL*ZL4*+8RuzWUO\DfR*IU # IR*KL^O #dL*ZL*+8RuzWjO\f*Ij #I*KLsO #dL"+ZLT+{+8RuzWP\8fr+I #Ir+KL P #dL+ZL+k+8RuzW8P\f+I #wI+KLPP #dL&,ZLX,[+8RuzWhP\,fv,I #Iv,KLP #dL,ZL,K+8RuzP\VÁ\P\WP\f,IP #I,KL͂# #dL-ZLi-+8Ru}aZ`P`'pZ|-T`Pw+T-I`P I-{ZrP`Z-TrPt+T-IrP I-Qf-IT0Q #I-KL`HQ #dL".ZL.J+8Ru}`Q\f.Il #!I.KLuxQ #dL"/ZL/Z+8RuzQf/I #I/KLQ #dL00ZL0j+8RuzQ:f0I #I0KLQ #dL>1ZL1z+8RuzQf1I #nI1KLR #dLL2ZL2+8Ruz Rf2I #I2KLɄ8R #dLZ3ZL3+8RuzPRf3I%pR #LI3KL1R #dL4ZL5+8RuzRf5I= #I5KLFR #dL5ZL6+8RuzRef-6IR #*I-6KL[R #dL6ZL7ʚ+8RuzSf;7Ig #I;7KLpS #dL7ZL+8ښ+8Ruz0SCfI8I| #II8KLHS #dL8ZL99+8Ruz`SfW9I #wIW9KLxS #dL9ZLG:+8RuzS!fe:I #Ie:KLS #dL:ZLU; +8RuzSfs;I #UIs;KLĆS #dL;ZLc<+8RuzSf<IІ #I<KLنT #dL<ZLq=*+8Ruz Tnf=I #3I=KL8T #dL>ZL>:+8RuzPTf>I #I>KLhT #dL?ZL?J+8RuzTLf?I #I?KLT #dL#@ZL@Z+8RuzW$Tef@I$ #I@KL-T #dL1AZLAj+8Ruz,9Tf;AF9Tz_?BUBwh<@BUypOAͲBUܲABU}Ay/Cϳ/CL[qECecCz0Ug90Ur`Um-vCCbU@JccU@TD=DDDDU=DDU+5=DUU DUM9ED%| M%UDzYEާgU)UEU)~FU6FЦ)KjFFћ)PWFћߛ>ћ  F F!@GLG5GLTϤHGäfGTMHGfG]{ -Ug7yG-G-UFG6 @ A  HJ PV,H wLHtIDX9hvqdHgH6  EA dH 0Vk IɈIDXɈHViqgIgI6 Ɉ A gIԈ ڈ`VJIDWxVktfjJIV #9IjJKL$V #dLKZLK+8Ruz5 p?w} ?VrH,KKV}K}~LWLW8WfLIXW #HILKLpW #dLMZL6M;+8Ru}WWfTMI #ITMKLW #dLxMZLM++8RuzWWvfMI #;IMKLNJW #dLMZLN+8RuzWӊWf NIӊ #I NKL܊X #dLDNZLhN +8RuzWXjfNI #/INKL0X #dLNZLN+8RuzWHXfNI #INKL`X #dLOZL4O+8RuzWxX^fROI ##IROKLX #dLvOZLOӋ+8RuzW')fOI' #IOKL0 #dLOZLOG+8RuzWOQfOIO #IOKLX #dL PZL fTI # ITKLY #dLTZLUk+8RuzWY# f/UI #} I/UKLY #dLSUZLwU[+8RuzW)Y#2 fUI) # IUKL2Y #dLUZLUK+8Ruz>#R C\WY# fUIZ # IUKL" #dLVZL=V9+8RuzW؎(Z/F fPVI؎ # IPVKL@Z #dLtVZLV+8RuzWXZ/ fVI # IVKLpZ #dLVZLWː+8RuzWZ/: f8WI # I8WKL Z #dL\WZLW+8RuzWZ/ fWI #y IWKL Z #dLWZLW+8RuzW,Z/. fXI, # IXKL5[ #dL(XZLLX+8RuzWA[/ fjXIA #m IjXKLJ0[ #dLXZLX{+8RuzV/ [\W@H[/BfXI@`[ #IXKLL$ #dLXZLYc+8RuzWx[4f%YI #I%YKL[ #dLIYZLmY+8RuzW[46fYI #IYKL&[ #dLYZLY+8RuzW2[4f ZI2 #uI ZKL;[ #dL1ZZLUZے+8RuzWG\4*fsZIG #IsZKLP \ #dLZZLZ˒+8RuzW\8\4fZI\ #iIZKLeP\ #dLZZL![+8RuzWqh\4f?[Iq #I?[KLz\ #dLc[ZL[+8Ruz4>\Wu\4f[Iu\ #}I[KL #dL[ZL[+8RuzWg/2f[Ig #I[KLp #dL\ZL&\+8RuzW/f9\I #qI9\KL #dLO\ZLe\+8RuzW$/fx\I #Ix\KL #dL\ZL\WÞ#f\IÞ #QI\KL̞ #dL\ZL\ߞ+8RuzWߞ#f\Iߞ #I\KL #dL ]ZL"]+8RuzW#f5]I #EI5]KL #dLK]ZLa]+8RuzW#ft]I #It]KL  #dL]ZL]3+8RuzW3#tf]I3 #9I]KL< #dL]ZL]O+8RuzWO#f]IO #I]KLX #dL^ZL^k+8RuzWk:#Tf1^Ik #-I1^KLt1 #dLG^ZL]^Wâ4fp^Iâ #Ip^KL̢ #dL^ZL^ߢ+8RuzWߢ4Hf^Iߢ # I^KL #dL^ZL^+8RuzW4f^I #I^KL #dL_ZL_+8RuzW4<f-_I #I-_KL  #dLC_ZLY_3+8RuzW34fl_I3 #{Il_KL< #dL_ZL_O+8RuzWO40f_IO #I_KLX #dL_ZL_k+8RuzWk:4f_Ik #oI_KLt1 #dL`ZL`W/f)`I #I)`KL #dL?`ZLU`+8RuzW/fh`I #OIh`KLʣ #dL~`ZL`ݣ+8RuzWݣ/f`Iݣ #I`KL #dL`ZL`+8RuzW3/~f`I #CI`KL* #dL`ZLa+8Ruzg%} wۄ  Yŝoύ)iŝȍ)$:@i @ ŝo.C)Youitz?} tO} \$E%aW \@_f8aI ] #$I8aKL ] #dLKaZLaa˔+8RuzW%8]@faI% #IaKL.P] #dLaZLa++8RuzW:h]@SfaI: #IaKLC] #dL bZL-b+8RuzWO]@fKbIO #IKbKLX] #dLobZLb +8RuzWd]@GfbId # IbKLm] #dLbZLb+8RuzWu]@fcIu #IcKL~^ #dL;cZL_c+8RuzW(^@; f}cI # I}cKL@^ #dLcZLc۔+8RuzW)@ fcI #z IcKL #dLcZLd+8RuzW@/!f"dI # I"dKLġ #dL8dZLNdס+8RuzWס@!fadIס #n!IadKL #dLwdZLd+8RuzW@#"fdI #!IdKL #dLdZLd+8RuzW@"fdI #b"IdKL #dLdZL e++8RuzW+@#feI+ #"IeKL4 #dL4eZLJeG+8RuzWG@#f]eIG #V#I]eKLP #dLseZLec+8RuzWc@ $feIc ##IeKLl #dLeZLe+8RuzWD@q$feI #J$IeKL; #dLeZLf/ <~ ioœ)ۓ i@$\WXX^Dv%ffIX #;%IfKLap^ #dL>fZLbf++8RuzWm^D%ffIm #%IfKLv^ #dLfZLf;+8RuzW^Dj&fgI #/&IgKL^ #dL&gZLJg+8RuzW^D&fhgI #&IhgKL_ #dLgZLg +8RuzW_D^'fgI ##'IgKL0_ #dLgZLh+8RuzWH_D'f4hI #'I4hKLʕ`_ #dLXhZL|h+8Ruz֕D'ە\Wx_Dr(fhI_ #7(IhKL& #dLhZLhі+8RuzW(_D(fhKL(_ #(dLiZLi3+8RuzI #IhW٠Df)f.iI٠ #+)I.iKL #dLDiZLZi+8RuzWD)fmiI #)ImiKL #dLiZLi+8RuzWDZ*fiI #*IiKL #dLiZLi-+8RuzW-D*fiI- #*IiKL6 #dLjZLjI+8RuzWIDN+f*jII #+I*jKLR #dL@jZLVje+8RuzWeD+fijIe #+IijKLn #dLjZLj+8RuztZ ŝ o:Qg|)i +H _n4:s %jWF_s,fjIF` #,IjKLR0` #dLjZLj +8RuzW^H`sW-fkI^ #-IkKLg`` #dL&kZLJkk+8RuzWsx`s-fhkIs #-IhkKL|` #dLkZLk[+8RuzW`sK.fkI #.IkKL` #dLkZLlK+8RuzW`s.f4lI #.I4lKL` #dLXlZL|l;+8RuzWas?/flI #/IlKL a #dLlZLl++8RuzWØ8as/fmIØ #~/ImKL̘Pa #dL$mZLHm+8RuzWԘ,s30ffmIԘ #/IfmKLݘ# #dL|mZLm+8RuzWs0fmI #r0ImKL #dLmZLm+8RuzWs'1fmI #0ImKL #dLmZLn!+8RuzW!s1f#nI! #f1I#nKL* #dL9nZLOn=+8RuzW=s2fbnI= #1IbnKLF #dLxnZLnY+8RuzWYs2fnIY #Z2InKLb #dLnZLnu+8RuzWus3fnIu #2InKL~ #dLnZL o+8RuzWs3foI #N3IoKL #dL5oZLKo+8RuzWs4f^oI #3I^oKL #dLtoZLoɜ+8RuzkU x~ oӗ)*@FiPs4U\{]phat4]o]]yau4$]o.]oU|af6doa5zp|~W5or|$rorep2~5Apr6rpr~5'p }pϳpL[q!qe?q™ ":Rq.pq™ MRqpq˙{  v6&qqWΙae77fqIΙ #6IqKLיa #dLrZLCr+8RuzWbw7farI #v7IarKLb #dLrZLr;+8RuzUɜ>fb9drɜ.8zrɜ~.8rrɜ$rrr*s2Ϝ~p8ABsrϜ6rXsrޜ~8'ns }sϳsL[qses ":.s Ms{ We9fsI #9IsKL #dLsZL t#+8RuzW#%wU:ftI# #:ItKL, #dL5tZLdt?+8RuzW%k:fwtI #:IwtKL #dLtZLtş+8RuzW'\H;ftI #;ItKL #dLtZLt+8Ru}W  \;fuI  #;IuKL #dL$uZLSu'+8Ru}W+ \:<ffuI+ #<IfuKL4 #dL|uZLuG+8Ru}WK\<fuIK #y<IuKLT #dLuZLvg+8Ru}W,'\,=fvI, #<IvKL5 #dL,vZL[vL+8Ru}WS \=fnvIS #k=InvKL\ #dLvZLvo+8Ru}Ws:\>fvIs #=IvKL|1 #dLvZL w+8Ru}'>fwI #V>IwKL #dL4wZLcwͤ+8Ru}Ԥ ?fvwIԤ #>IvwKLݤ #dLwZLw+8Ru}u?fwI #:?IwKL #dLwZLw+8Ruz?f xI #?I xKL #dL#xZL9x,+8Ruz,[@fLxI, # @ILxKL5 #dLbxZLxxH+8RuzH@fxIH #@IxKLQ #dLxZLxd+8RuzdAAfxId #AIxKLm #dLxZLx+8Ruz'Af yI #yAI yKL #dLyZL5y+8Ruz''BfHyI #AIHyKL #dL^yZLtyǥ+8RuzΥ BfyIΥ #_BIyKLץ #dLyZLy+8Ruz CfyI #BIyKL #dLyZLy +8Ruz CfzI #ECIzKL #dLzZL1z*+8Ruz. CfDzI. #CIDzKL7 #dLZzZLpzJ+8RuzN fDfzIN #+DIzKLW #dLzZLzj+8RuznJDfzIn #DIzKLwA #dLzZLz+8RuzԦ'KEf{IԦ #EI{KLݦ #dL{ZLF{+8Ru} EfY{I #EIY{KL #dLo{ZL{+8Ru} /Ff{I #EI{KL$ #dL{ZL{7+8Ru};Ffu~I; #iFIu~KLD #dL |ZL8|W+8Ru} ŝAo[w)Āi݁u ŝo/Kcz)i׃?Too)oJ`vх))%)Ψ5ڟH{ yjwHH:B5h|BwB__aH7I:B`ݐ|)DBw)DB;)Eݐ*)Gݐ/`vTpvTK|by ]Ib!b&}bIb~bY~bIbb@ا Juاuuا}u0b M_HPbHHHwHI<pbJUKIpbIbb'ubbubbK+5bb bM=!%| !1b niaT́G1b)́b<H1b)~HH́HhbH@)KLʂS )PL6T >  A acPt_Ha(cHHHtwHăPcOaPc'#KPcaPc#KPcCxcnN+K5xcCxcK CxcMKa%| !qc n„aT%G]qc)%]cHqc)~HH%HcH)KSOC )POy  >   <@cPUKă@căˆĩϤäĩMͩ{ }xcS1_HxcHHyH1wH<xdOQUKxd0d{0d'@0d{0d@0d{XdXR+5Xd{Xd {XdM%| !d n/a[TGʉd)[ʉdHd)~H[HH.dH\)K=SӨ' )P{S' 2>' : M ~a d1Ta$a7I  &TI$I  I$I  -I$/R$ͧŝP P7{ ٩{ 1 #T;BI_Tp| Bw B4I T`2}\  p7 }\ \ \ dr\F \J{T UTTTҋڨ 1%d UOBP٪e UPPR$P e VPPR$~a@e Va(aI VI(I I(I -I(R$P`e VP<PT2R$~a2e \WataI2e QWItI2e ItI2e -ItFR$PFe WPPXR$df Wx,JPyf WPߌPR$~a8f fXaaI [XII II -IR$PXf XP'P?R$~axf "Ya]aI YI]I I]I -I]R$Pf VYPPҫR$Wҫf YfIҫf #YIKLիf #dLZL+N+8RuT>R [>I<[kڥΥ<<><~? ?agguގWg]fގI #ZIގKL 0g #dLZL8+8Ru+V+x+/ ϤäÏ/ MÏ8{ Wh 1\f֏Ih #[I֏KLn #dLZL~+8RuTIO\PwRu ŝ٪a^f{ 1117G /w  p7_ ' /wPg$w; 4w+m \Fs %m  2]mWEpg ]f<IEg #q]I<KLHg #dLؑZLU+8Ru~W\g &^fI\g #]IKLbg #dLZLȒԲ+8Ru~<`j  ^K`_je^_Tt+TfIt IfWh _fI0h #^IKLHh #dLZLȓ+8Ru~Wɭ`h _fIɭ #W_IKLϭxh #dL ZL,+8Ru~"`׭  `1`J_׭|__^T}+TvI IvW%h `fI%h #I`IKL.h #dLZLؔ+8Ru~W6h `fI6 #`IKL<h #dLZL<o+8Ru~Wi xafZI0i #=aIZKLHi #dLZLs+8Ru~W`i afIxi #aIKLi #dLĖZL+8Ru~Wi lbfIi #1bIKLi #dLtZL +8Ru~W i bfI j #bIKL(j #dL4ZLV&+8Ru~Wc@j `cftIc`j #%cItKLlxj #dLʘZL 6+8Ru~Wtj cfPItj #cIPKLzj #dLpZLO+8Ru~~aj fdaaI [dII II -IR$Wj df&Ik #dI&KL0k #dL|ZLҚ_+8Ru~Hkoi %hko 9wko6 @* Dp T^د e^E6TدMETIد 6IIد IIد -Ik 0fTkU+TRIk IRW4k ffI4l #ofIKL=l #dLZL-۱+8Ru~]0l fKq,JPrPl gPPߝR$~apl gaaI gII II -IR$Pl gP;PR$Wl >hfIl #hIKLl #dLҞZL +8Ru~Wm hf,I #}hI,KLm #dLuZL+8Ru~^ǰ i^ܟTǰX+TIǰ IW0m ifIPm #NiIKLhm #dLMZLK+8Ru~W m jfI m #iIKL)m #dLZL8+8RuP1m 7jP0PhER$WEm jfIEn #vjIKLN n #dLZL++8Ru~WV8n +kfIV #jIKL\Pn #dL3ZLb+8Ru~Wdhn kfId #jkIKLjn #dLZLĢ+8Ru~Wd lfId #kIKLj #dLZL v+8RuWv lfIv #^lIKL| #dL4ZLI+8RuW mf\I #lI\KL #dLqZL+8RuW$ mfI #RmIKL #dLZLã+8Ru~nf֣I #mI֣KLĴ #dLZLӴ+8Ru~W״ znfI״ #?nIKLݴ #dL(ZL=+8Ru~W nfPI #nIPKL #dLeZLz SofI #oIKL #dLZL+8Ru~4]ްԆ >ñPWf}eWin :pfʤIin #oIʤKLrn #dLZL+8Ru~W pf.I #ypI.KL #dLCZLX+8Ru~W  qfkI #pIkKL #dLZLWų qfIų #YqIKL˳ #dLZL׳+8RuW rfI #qIKL #dLZL++8Ru~W  srf>I #LrI>KL #dLTZLiWo rf|KLo #rdLZL +8Ru~I" #I|W gsfI #,sIKL #dLϦZL%+8Ru~W% sfI% #sIKL+ #dL ZL"W7 Gtf5I70o # tI5KL:Ho #dLKZL`R+8Ru~WR tfsIR #tIsKLX #dLZLWK 'ufIK #tIKLQ #dLƧZLۧ`+8Ru~W` ufI` #fuIKLf #dLZLWu uf+Iu #uI+KL{ #dLAZLVW" mvfiI #2vIiKL #dLZL+8Ru~ݬP3ETT%TmT̮T5QcTQiPP{ 1::8g  p7 `ouE \F~a o xaaQI  xII  II  -I$R$Wro xfdIro #XxIdKLuo #dLZLG+8RuWp yfuI p #xIuKL8p #dLZL+8RuW߶Pp yfتI߶pp #LyIتKLp #dLzZL+8RuWp zf2Ip #yI2KLp #dLUZLw+8RuWDp {zfIDq #@zIKLM q #dL5ZLȹ+8RuWV8q zfIVPq #zIKL\hq #dLZL1߹+8RuWq o{fOIq #4{IOKLq #dLծZLE+8RuWq {fsIq #{IsKLr #dLZL+8RuW r c|fկI 8r #(|IկKLPr #dLEZL+8RuWhr |fIr #|IKL#r #dLZL''+8RuWbr W}fEIbr #}IEKLkr #dLZL4+8RuWts }fIts #}IKLz0s #dLAZLcK+8Ru } ~aHs }~aaI r~II II -IR$W`s ~fIs #~IKLs #dL[ZLc+8RuǸQ=i %ܸ[){{\~a*s a߳aI* I߳I* I߳I* -I߳:R$WEs Cf2IEs #I2KLNt #dLrZLp+8RuWR f̴IR #I̴KLX #dLZLe+8RuWe  #f Ie #I KLk #dLZL3Wp fFIp #bIFKLv #dL\ZL+8RuW fI #ہIKL #dLZLȵ+8RuW f۵I #UI۵KL #dLZL+8RuW fIt #ςIKL0t #dL.ZLC׺+8RuW׺ pfVI׺ #IIVKLݺ #dLlZLW fI #IKL #dLZL+8RuW PfѶI #)IѶKL  #dLZLWHt ʄfKL`t #dL#ZL8+8RuIe #IW( DfKI( # IKKL. #dL`ZLu;+8RuW; fI; #IKLA #dLZLWR fŷIR #IŷKLX #dL۷ZLWx# fIx #OIKL~ #dLZL-+8Ru PF`rTX(oͶ߶T ho2DTn'oT T=PbTQP*PEP{ uH͛  p7 ͛xt›! \F~at$ `a@aI UI@I I@I -I@ R$Wwt' ؈fԸIwt #IԸKLzt #dLbZLҹ+8Ru`Wu' PfI0u #IKLHu #dL#ZLE+8Ru`W`u) ȉfcIu #IcKLu #dLZLa,+8Ru`Wu) @fIu #IKLu #dLZLԻE+8Ru`WIu, fIIv #IKLX0v #dLZLO+8WaHv, *f=Ia #I=KLg`v #dLZL%+8RuWxv- fCIv #iICKLv #dL߾ZL\+8RuWýv- fIýv #IKLɽv #dLZLο+8RuWw0 fI0w #]IKLHw #dLZL+8RuW%`w0 fI% #׌IKL+xw #dLgZLz+8RuWuw2 fIuw #QIKL~w #dLZL+8RuWw2 fI #ˍIKLw #dLZLm+8RuWx6 fI0x #EIKLHx #dL6ZLX`+8RuW`x6 fvI #IvKLxx #dLZLS+8Ru~ax9 aa.I {II II -I+R$W+x9 fNI+x #ŏINKL4x #dLZL\+8RuW|x; zfI|y #?IKL0y #dLTZL+8RuWHy; fI`y #IKLxy #dLZL+8RuDDi> % ʿƑҿX(Ƒ>w~ayB Бa>a~I őI>I I>I -I>&R$W1yB JfI1y #IKL:y #dLZL +8RuWc- Ēf+Ic #I+KLi #dLAZLVv+8RuWv - *fiIv #IiKL| #dL~ZLWB fI #iIKL #dLZL+8RuW0 fI #IKL #dLZL(+8RuW 0 f;I #\I;KL #dLPZLeWy9 fxKLz #dLZL+8RuIh #IxW, ufI #<IKL #dLZL+8Ru`W) fI #IKL #dL ZL6+8Ru`W) SfII #,IIKL #dL_ZLtW6 ͖fI #IKL  #dLZL+8RuW"6 GfI # IKL #dLZL0+8RuW;2 fI; #IKLA #dLZL+N+8RuWN2 'f>IN #I>KLT #dLSZLhW~; f{I~ #fI{KL #dLZL+8RuW"; fI #IKL #dLZL+8RuW', fI #ZIKL! #dL ZL8+8Ru`W' fKI #ҙIKKL #dLaZLvW+' qfI(z #8IKL@z #dLZL+8Ru`ӻPP1?LoewToҼTߎ"o7ITT۽ϏPwT=KcuTeoӾT͓QSj|TPP1P{ ]H80A,5-9 , %XzW D ~m ~ 1 4 ~'6z @~6bW-@fI #ŜIKL$ #dLZL@+8Ru~ZbfZz D [SZ~ z1 ωzމ]{;0{#?'VMX{#?yMeMRM-#?AM-Mp{͞{cĉhtn{cs4n{ ZMCsL'LRcW{3 fI| #IIKL | #dLZL +8Ru~8|1 .2`|5Z;WAx|@8fIA #IKLJ| #dLZL%?+8Rw|LR@LCoRoN5ȠuaL{|#;MLM|#;AM-M-L|5L{ˆ| ӈW};fI8} #DIKLP} #dLsZL3+8Ru~ˆh}4 ӈW};fI #١IKL} #dLZL_+8Ru~ˆW ӈ}WW;f}IW #nI}KL` #dLZLo+8Ru~ˆo-4 =ӈWo-;fIo #IKLx$ #dLZL+8Ru~W!3 f-I #|I-KL& #dLCZLr9+8Ru~wŶNJ w} } X+  ~ T{ { ]H=#vݐݐ|vݐwvݐ;vݐi5 c__nc__s'j;Ej :ݐ`ݐ|)Dݐw)Dݐ;)Eݐ*)Gݐ]i2#K5hGc__xGK}Q\5֎}LӥIaU֎}M #1}S٦h[NZ}}_ })b}V,U}S3~SS@SG ~W SSUWU8~WfIUX~ #HIKL^p~ #dLZL;v+8RucW&WfYI #IYKL #dLnZL++8Ruc ~@j;^Ej:`EjNa[cofb[c'vx~_ӨF~rbx cc%1~`[N~a+75~c Mcw%| 5iIaUM #Ïɏ rQa?ɏ ).areɏ )#a  1ɏ )~aפO xЦ؏)K )P- >  ȑ Hy%t?H).%rteH)#%t H1H)~%tפHFЦ)K_ )P0  >  ͑ @1խڥ\Υ|@1\|@1>@1~?\ ?aCxguWCx]fKLC #dLZLl+8RuHIX #Id' Ϥä; M;{ TήڥOΥnTOnTb>e]el Ϥäl Mu{ YMhrW fI #ܯIKL #dLZL+8RudJ }  ّ 4{ g_w5h__xw7k % %}cHa %bbTbpnuu]u}u] q0 = # &L TY 'h /AAHfgAZAPANFx _NQNNIF CTIU<$dPgi_5oIaEUZoM #EZ W${fmI #BImKL #dLZL+8RuLAAȀgAZA PAMN  N|N NMI CIM<$Pi_)5IyaUM y#8 W*fI #IKL #dLZL'+8RuWf"I #iI"KL #dL7ZLd+8RDWfwI #IwKL #dLZL+8R6~uuu}u0xb0{q΁0(g(΁6Hi@H΁<`h`&>G_>QGڥΥG>G~? ?aZguWZ]fKLZЁ #dL;ZLh+8RuIp #I<l Ϥä M{  \cWfI #IKL #dLZL+8RXb /ccW84f0IX #RI0KLp #dLNZL%+8RX9ٺ0.>=9ļ>]FC]ڥΥFCFC>FC~? ?aJȂguWJȂ]fKLJ #dLZL*w+8RuI_ #IHj Ϥä M{ h0hhh1hhh2Bhh/WcfCIc  #ICKLf8 #dLXZL|+8R@W42fI #IKL #dLZL+8RX i%| ... { {   PWhb<\WUAKjaBp YU WпfI #IKLЃ #dL ZL,+8RugW!fuTI #IuTKL #dLjZL+8Rugpŝ{ \|Ϙk{{ %'%k:kMS=s SSKWKsfIK  #IIKLT8 #dLQZL+8Ruc%`Pw4hh$.kCڥΥkCkC>kC~? ?aguIW]fII #IIKL #dLZL+8RuPix %W؄yffKL #IdL%ZLG,+8RuLI #IPyiu_5IaU M # } Wy{fudI #BIudKL #dLZLI+8Ruc:#NV=:Na { / !:M<q%<%k:k,S 0sS\SWHsfIh #IKL# #dLZL2B+8Ruc%/wH4P7$.h:ЅڥΥh:ЅhЅ>:Ѕ~? ?aXguWX]fIX #IKL] #dL,ZLNp+8RuTix %lW@yfKL` #dLZL+8RuPIԔ #IPywi _O5lIaUM #Ȕ5 WMyfudIM #IudKLS #dLZLc+8RucPuTv2$u "#2 RPwu  l{ /P!:,l$:ep`8:D::gN>]>WfvKL #gdLZL+8RLI #Iv5mmCKU/MCK%Bи5h__x>rB}25__n0:$u`A|)D$uw)D$u;)EA*)GAkЕ؆E"'n;e1-0 -`@E,TuP - %TuP-Tm@ȇxB@ȇMQg5[P%| l%D, uPg;@ggg\DU )@4(N2)~g[Ou)!)KYs~S1~'~[ )P{o  ŗ$:q  ͗ q@& ߯w: Z w{ ͯm  { Mm  {   z P'P0=8 S"%| { { { PAA|AwA;A__ny_5g__nV__s'j;a:A`A|)DAw)DA;)EA*)GA5hG&__xG@QATx~ (L~ ~ ~ <~ (MK~ a~ U~ ~ $ 1~; '~m (~7`Q1~'~ Y\xS*   \x  S\x_  zx= \xV2u % xA  &$ F SSh S{  W|& SS SW Wf I( #I KLʘ@ #dL# ZLE +8Ru[&Wc W&fx I #fIx KL #dL ZL ͚+8Ru[Xxj;^:` NaofbFPp_tvi9_epgPgg%S`}pa!VmxBMQg[%| x~؉i~~~<~؉MK~a~U~~& 1~'~CtIr8 |I).i\ OB|I) |I)~  X!)KK~\S1~'~v[X )P{oX c$:$ X k t0yE0).i\OEB0)E00)~E0!)K_~S1~'~X[ )P{o $:  p 2[2{o2$:2~D:8: :`gN'`]'W`f_KLx #dLZL +8RuHI #I_߯77> ͯ> MG{ $[{o$$:߯y8 ͯd Md{ Ї0Oۇx0MÇx0 xW0fI0 #IKL9 #dLZLI+8Ru\  - | ֚{  BH)J5.H+Wp?f:I?UPO<SPPgR$Pg(<P(PyR$ۀ O=x h@Cw@N@]@@55xK";`1#Ћ;g#@gg2 @r.2r . R(%.RHHm8PxZB8PMQg[ZH%| %\hD h)@4(hNH2h)~g[Othu!)K~S1~'~[ )P{Wou@ $:   @uL߯3ͯFfMFf{ yz  PP$=, S %| { 1ЇۇMÇ WfI #IKL، #dLZLT`+8Rudr<KWP8HP0 PR$PPHPX PR$! =p <{ { { m \q5qֹ%5J'V"\$-5FM %?'<(@P5.H$?d' % P?OUhEmsg/ ;? L:`iZP`b~a`aa I` \II` II`Ѝ -IxR$Wp f)!:hwa!N]!g g!g!0O!C"0bPH""HbPh#K#hb'Pni %#h'2w#N5]#=g=Ў\g $g $HOZ $hpwI$Np]$p$ %+%+%yP"Hh;X%1%\&b&g\@xggk@&&d'k& d' %&d' & m(x'B(MQg'['%| %\@D (S( @)@S(4(@N(2@)~gS([O(@u )!)KtJ)~S1~'~)[ )P{)o) $:   S S@)߯Y) *Y] ͯ3*U*] M3*U*f{ hh*z 8LP[Pd=lyS. C%| t{ g&gg**bPP*P*R$:LZ+P:+b~aa+a\+I ?I+I I+I -I+R$(++(bPHP+P+R$:prZ+P,pb~aa+a4,I eI+I I+I -I+R$WfY,Iؑ #IY,KL #dL{,ZL,+8RvW!bf,I #)I,KL #dL,ZL-+8RPT+T-I I-_---=..WDhf/I8 #/I/KLP #dL/ZL*/+8RwWDf=/I #I=/KL #dLR/ZL/+8RL`'T2+T/I I/W'hf/I' #qI/KL0 #dL0ZLi0+8Rw 0< 0*i U9i0qG[00bP:ВZ0P0Вb~aa0a 1I I0I  I0I8 -I0R$)D/14<7G1*i7U9iG1DqG6f\1I #I\1KL0 #dLq1ZL1+8RL`y]M=5~ I~  &L{ 11 Bg0z5gWPnf1Ip #I1KL #dL2ZL?2+8Ru_Wnfm2I #NIm2KLؓ #dL2ZL2+8RvWnf2I #I2KL #dL2ZL3+8Ru_Wnwfu`I #>Iu`KL #dL"3ZLO34+8Ru_O]ITtk0{ ;_55Pֹ%@ XPb3_P_b3__3T+T3I I3p,3*iU9i3qGG3G3ŝ);4ؔW4 4W4W/f4I/0 #I4KL1H #dL4ZL 5+8Ru\!ŝJ{ _*5*iU9i*5qG);?5T5~X_WJhJf5IJ #I5KLS #dL5ZL5_+8RwW#f5I #I5KL #dL5ZL 6+8Rw{ /a w /i&'70  hb w {T7TT 6TB6ڨ7 N1Z2 f6\l 6btؕccm66bPP6P6QR$b8cccP!c+c6h7-7hbPP7PA7R$:ZPe7b~aЖaay7I II II( -IR$@. 77@bP`P7P7R$b #7x8 #bP P7P8"R$p  98*ip U9i98}qG  e8*iU9ie8qGipy]t y88bP:3 Z8P%9b~aЗa8aQ9I & I8I I8I( -I8R$b@u u9x9@bP:`4 Z9P:`b~aa9a4:I ' I9I I9I -I9R$ v X::bP  ::bPؘ   ;X;ؘbPS? ;*iSU9i;[qGW[  f;I[@ #~ I;KLdX #dL;ZL;+8RDW0 f<I # I<KL #dL<ZLF<+8RWu Y<*iU9iY<qG<I_Q{ { 17( p( ) W7p+e fm<I7 #, Im<KL= #dL<ZL<+8RuW>JQ+P ><P;  =ڥB=ΥU=P;B=U=P;>P;~?B= ?h=agșgu=Wgș]f=Ig #] I=KLl #dL=ZL=~+8Ru >->I> Ϥ\>äx> M\>x>{ W+ fuXI # IuXKL #dL>ZL>+8RuWI PvRu+4 { 1~9o#V ;~S_#| ~Sw ~S  #0w _# -## P~S_/| ~Sw ~S  / 5__x 9`  5Vp   >U?M>W  G p1?f7 :  I1?P; U]?P p< P?P"R$P"< P?P4R$+ۀ  ==F= ^w ?;@hvi @;ni6Tn@Jn\sК kFA;nsК$TnFAJn y H ^A; A. Aby ^ b^Ab;BV 8  j Bb`- bBb'Cx- CCbx-bCbC-  gDWZfDIЛ #Y IDKL #dLEZLE+84- FW4ZfFI4 # IFKL7  #dLFZLBFL+8Rudw 8   UF    UFFb -܂bUFbFǐX J ؐFp-܂ 0GWZfGI #  IGKL #dL*HZLsH+8Ruǐ  ؐH-܂ HWZfHI # IHKL% #dLHZLH1+8RuKǐ  ؐHМ-܂ HWZfII #y IIKL #dLIZLI+8Ru@ J  IW0ZfDJI # IDJKL H #dLJZLJ+8Ru@L   KWLZfKIL # IKKLR #dL#KZLPK^+8RuTǐ ؐcK-܂ cKWZfcKI #N IcKKL #dLxKZLK+8Ru`!  KWxZfKI # IKKL #dLKZL2L+8Ru@W" fPLI" #` IPLKL( #dLLZLL+8Ru@v0 M;n06TnOMJnfU؝6 MuMSYSMS8NcWc fNIc8 #u INKLlP #dLNZLO+8Ru@th !O<thKIOWhOPH) POPR$PHY POPR$ = PО  O P^ 1P̆IPuPd^Ms1PIP}uP::b V:PL:PW fPI #o IPKL #dLQZL#Q+8Ru@n*K; 6Q<^  NQW^ZfNQI^ #G INQKLd #dLcQZLQp+8RuTWp fQIp # IQKLv #dLQZLQ+8RuT# Q<W5 fuTI5 #b IuTKL; #dLudZLRK+8Ru@ \T{ { { 1~90P r 5Hr (g p6\W9#RtgH LR4gH ZMCLR^}h ,^R"^R}h 3RROWV fRI # IRKL #dL9SZLuS+8Ruc^П ,^S"^SП 3SSO^ ,^S"^S&W6\ fudI6 ## IudKL< #dLTZLHTH+8Ruc Q{ ~9$  5BP  11o(`  5.Hkey  w f  [T T TW fZUI #l IZUKL #dLoUZLU+8Ru_L` ^`UW0I fUIP # IUKLh #dL'VZLcV+8Ru_WfVI # IVKL #dLVZLV+8Ru_ { ${ 110*6 keyy6 y; DU 11`! key~! ~ %Р! 9/Ta ad aVb=WK fYWI( # IYWKL@ #dLWZLW(+8Ru[W` fWI # IWKLx #dL XZLdxbP1ЦP>dPvdLR$LE+ dbPLPdPddR$ _d@+ )_c_eh+ )__JeFPPf, _e|bPP_ePeR$ _Z, )_e_eاO, )__;fPP, PfbPPPfPxfR$8 - f 8bPXPfPfR$G- gg]bPPgP(gR$Ȩ- Xg ȨbPPXgPgR$I. gbP(PgPg5R$i. h*iiU9ihqqG]. *h*i]U9i*hgqG{P{PU__gWaZHpZ}ZTHw+T?hIH I?ho{ { V^/ 4 5%'`4 5nhN?Dh6 / A h x"0 aH i- 4 uXj_80 _7iy_Vi@_8ЩY_iO_iz0 iibP}PiP'jR$ _ r1 )_Gj_ojP8PjPjaO`f1 lOj{ R$e x1  j{ xbPPjPjR$WK2 fkIЪ #2 IkKL! #dL0kZLhk+8Rw-2 k*i-U9ik:qG):0}3 ;k:Pk:p kkWhf3 f lIh #,3 I lKLm #dL*lZLLl+8RuDRŝ~{ W3 fjlI #3 IjlKL #dLlZLl+8RuS84 l*iU9ilqG)!}4 ;l!lz _c~  |  RH {  16 $?16 WC5 fmIC #[5 ImKLL #dLhmZLmh+8RusWq 6 futIq #5 IutKLw #dLmZLm+8Rus'/C{ 1;9 IT'H 8'om6'' # ?6 IoB6 {o;nnosnaooz(8 eH9 GoWA(Kq7 fZoIA@ #87 IZoKLJ #dLmoZLoZ+8RucWlK7 foIl #7 IoKLr #dLoZLo+8Ruc" 7 8 PvA4 _  WXO8 fpIp #g8 IpKL #dLpZLBp̜+8Ruc8 9    WOG9 fUpI #9 IUpKL #dLjpZLp+8Rucvv{  9 PvR04 ќ   { #{ 9 }#\I W9 :   :  !   p#`O: 66 i 66 9Y66 h0> ITH': 8'op6'' #J ? ; Oo^BA; o qoDqoqЬ< eH> rWK; f+rI #; I+rKL #dL>rZLkr+8RucWKJ< f~rI #< I~rKL #dLrZLr$+8Ruc םj< Pv4  ) WUO= frIU0 #< IrKL^ #dLrZLsn+8RucH0= ">    WO= f&sI #o= I&sKL #dL;sZLhs+8Rucvv2{ > K= PvR0U4 s  { Ǟ{ 9 \I $NC> ?  s>  " / < ` {s` s" s/ s< t# > W >  XsX+tW % %?  XUtXhtT,: <iIq66 yT ОC ITJ'5A 8' p|t6'' # ?@ DpxB<@ vptipt\puVzA eHC uWK@ fuI #@ IuKL #dLuZLv+8RucWKIA f2vI #A I2vKL #dLGvZLtvŸ+8Rucb wiA Pv4  ǟ WOB fvIح #A IvKL #dLvZLv +8Ruc/B !C ' / Z W/OB fvI/ #nB IvKL5 #dLvZLwE+8Ruc.v<vП{ ܟ B PvR04  J S{ c{ 9 \IK ^{[BC D Z lC f s  Z /wf Yws w w# C  W  C WYwWgx D  x3| [)W GD WxWx!*2Ex? TT? !D N5AD envr@D envs@E  %IB% B@2E K  8E         W#_} XK  yX 0y y y y Tz hz z x0F  {x 9{ f{ T[PF [{{J  {Ȯ | %G  N|gt%tt|"t%(YtLt?t|D  D }|EnG  &}nE(<}D  D }`A(H % }`"H *} }`"7~8lbR`l~Ul}Jl-~di/,d,dK Q H ' C~}Z ~C~}$}C~}2 H A Y~}H}Y~}6}o~}L J[I  v i  >I Κ(D  D ~s~(I t~s~(@s~0 I s~w[0EI [~?ZgjD @mJ D ~@E  ŝPP=P=P( P`J  3 STWiZTUeL ~-*5T70{ pN ITҶ%'D 8'qi6'' # ?K CqxBK xqkq^qM eHN W!KXL f̀I! #L ÌKL* #dL߀ZL :+8RucWNKL fIN #L IKLT #dL4ZLad+8Ruc L Pv!4 ? i WدOM ftI #NM ItKL #dLZL+8RucM N ˡ ӡ  WӡO.N fǁIӡ #M IǁKL١ #dL܁ZL +8RucΠvܠvr{ ~ pN PvR04   { { 9 \IN N 5N 84 'C DCN O 5N ֹ%,%0%O Q 5.H P 56%5'YDO YpID IpID -Ip7 i -O P :F kN 8YP N ~k YP)9P Y=<N h)P N N ̂6N Z P  [Z~   ~ N  YP N MO k K #{ pQ *Q 5h__x*Q lB))0GQ X 5.HHOX X 8WJmR pfnQ :JIaR UP'< R PTP?R$P?0<:R P|PQR$Sۀ '\=dZf hiHV wNiH]iHHkS "V ;1رTg@rS gg(@|T ƆS Ɔ  "0%"PPmXxBXMQg[%| %\TpDU :f Tp)@f4(pN2Tp)~gf[OȈpu`!)KnU ~dS1~'~I~[ )PU {Wou@ $:   @uP߯gͯM{ V ͉z PP= S%| { Q W Q Q x~+W ~~!~@<~+MK~a~!U~@~' 1~o'~?ȲX <ȲKW9PH*X P{PR$P(HZX PPR$ =mw<b{ u{ {  BH X "Y 5qT@ 'k % "Y HO A_5X CY T\ X X X Y  @I\ Y T^  h Y p Ӌt h4 h ZMCS( Z S}S4W4 Z fHI4 #QZ IHKL=г #dLZL֍x+8RuWS [ WSf0IS( #Z I0KL\@ #dLlZL+8Rw [ ƎWfێI #x[ IێKL #dLZL+8RuWW *\ fuXI #[ IuXKL #dL0ZL]+8RuW(y]FS/Q {  /e\ u\ 5Fu\ 8^ :8`8|)D8pw)D8;)E8X^ *)G80p)K6^ "ϏT\ 4So\ 0e\ YW/] fwI #r] IwKL #dLZL+8RugW/"^ f̐I #] I̐KL #dLZL+8RugH]lǢ)P^ !?ǢcǢ~!wSBϢ gVڢǢ   { #_ 88|v8wv8;v8$ /0_ @_ 5F@_ 8~T_ _ 5Sc__nx__s'j;5|~_ Wo 5dGx__xGWo дf Q3L!6Lpa 5MבA6M בT\ : o\ /e\ ^W/` fI( #` IKL@ #dLZLɒ+8RuTW"/[a fܒI #"a IܒKL #dLZL+8RuTOdsT\ XQb o\ 1e\ vW*/b fI* #a IKL- #dLǓZLB+8RuSWB@/b fIB #Nb IKLH: #dLZLIT+8RuSǣ^ ӣ^SCd _ \_ ^ ŔAӣ^\uhŔӣ^_\Ŕӣ^ٔIӣ^Vs`fŔӣ^ȕ_ ::_ ە0_ S/c S9SLS/ d SySؖS  /SSY'_ 1еWe :_ 0_ S7/d SҗSJSW/d S$SFcSh0/SfSt]tPWf ]Wtp/e fʘIt #_e IʘKLw #dLZL+8RuSWȶ/f f,I #e I,KL #dLNZLp+8RuSW/fI #If IKL #dLZLҙ+8RuS"(8o j;^5:`5Nazx%ofbzxiE_ H_]g k_ ^_ TT_ Hz_ 9c9g HcHcѤ%w٤p`g 5a h grɜ~<MKɜaݜU%| !ii 5MAuM uT\ ȷ o\ Нe\ +W:/i fjI: #h IjKL= #dLZLR+8RuTWR/}i fIR #Di IKLX #dLԞZLd+8RuT)8;rAj *L;).L4;)i]LQwxNz\ Q(yj *ٟQ().ٟ4Q()i]Qٟ(wcz\ qHm 1ܠ\qHHcqH~woBy`gV]y`]]Wy/l fРKLy #k dLZLH+8RuI #IРW/l f[I #Ll I[KLȸ #dLZL+8RuW/fסI #l IסKL #dLZLB+8RuŸm џ۟` sb Mq{s{ Ÿyn џ۟ybyMq{{ n ܠc~wB(gVƦ n vƦ MϦo   æ  ̧ *{ ]{ { 8|ko o 5d__xo 9r Do q 5H;Dq \o @Eyq uo 0ko ~!`nq 5MA$`M $T\ x o\ Be\ Wm/p fIm #p IKLs #dLZL+8RugW/Yq fv I # q Iv KL #dLZL$+8Rug .]_ { 8!$q q 5;Gq o 86q s 5VMs \o s uo 7ko !s 5ͥMAGMͥ GT\  o\ ee\ W/+s fŦI #r IŦKL #dLڦZL+8RugW/s fv I #is Iv KL0 #dLZLG+8Rug/>q_ { 8Js Ft 5>V;Ft ['t [Z/q 8: *v {!2*/n!!t,Hut 4,H ZMCt,`gu l4,` ZMCl,xwu `u,xu`u,x}u`D*T*ׂ d*|*****ׂ ** +ׂ %+5+E+ׂ U+m+1+1++1+++ׂ +',ׂ /,{PM,],m,ׂ },,,ׂ ,ׂ ,ׂ VFp#Fp|Fp*10x@0O0^0m0|0000ܷ0ط0Է0ѷ0з0̷1ķ1ȷ)1d61tӏE1PӏU18JGe16s1&11ӏ1m11x1`1%28`IctpvHӏ|ӏv~v mngd)`P9UdINPYCi7dy08(vv%6PGt'%]z ' Kz X@i@tLRTI/JGL5(( 40",,$X)FC42<N4.89=qQ9\99Glk)FFh9IY"m790{ *{ **4 %{  % ƐFj %{ 'mQ%| ' F %%| *&''m4'$77*>| *[| ' %EgG %u| u| >vE*( %| ''  %| ''E<J %| M(M(v$)W ĐFs %| D'' |YFZ %} D \  %%}  %3 %9} 9} v,O} 9} )_} 9} V` %w} 'EF %} D *} *uQ%[&e&Q%} u&'&'DW}  %JK*~ '' FD ~ ''EF %5~ DQ*I~ Q%P(c~ **d &'y~ 'E %~ ''&' ff*~  %~ 6m2:\\*~ ' %  %~  %'S &@ % '4j7L** m*H * %'7@] * C\*x *&'%]>  v%W * ]6 %  '&'  %v vߕ .gF % DX% % WFX% D (F&': *&'&'D 5\ %U  % % \a %k  %E>PF % 'E-nx %  %EK  v+v n f&\nВۀ  %u&' o %  vwoގ Yo %  o %/  E"pq %N  % % %Ep %m  %m vs > [k % ''I@ vC@.k C@ bfk'́  % o^ % - ;oa* - Wk % *jdup\ %$  % o %?  ? vE  ŐFd %f D'mEn %{  %vector::_M_insert_aux * *7"{  [oY %т т dv-2 % d** F2D  %' EF= %+  %Djt %H 'D\[[  % -\hВ{  %*&'Eq : % \ % :w\ ͋\ %҃ ' eS\' % '9D9Demom % uuQ%}F*= u55 %{]Rן*e *u'E+nv %z  % od % -uEX)* ' Wb %ʄ  %ʄ Մ vЄ 4v4w _\ %Er[r9* *&' % % %؍EwsQ %: : * %*mvErL %Z *&'Ezb %o o vEQt %  % %m * N]2 %  ' %e&F&'u&'&'D% U$ > 9: ; : ; : ; : ;  : ; : ; (  : ;  I8 9: ; .?: ;I</II.?: ;I<: ; I.?: ; n<&I.?: ; nI<.?: ;nI<.?: ;nI<.?: ;nI<: ;I.?: ;n<.?: ;nI< : ; I8 2 : ; I2 .?: ; 2 <dI4 .?: ; 2 <d! : ;I8 ".?: ;<d#.?4<d$ : ;I?2 <% : ; I8 & : ; I?<'.?: ; nI<(.?: ; nI<d).?: ; n<d*.?: ;n<d+.?: ;nI<d,.?: ;nI<d-.?: ;nI<..?: ;2 <d/.?: ; 2 <cd0.?: ;nI2 <d1.?: ;nI2 <d2.?: ;n2 <d3.?: ; nI2 <d4.?: ; nI<5/I6<7 : ; 8<9 : ;2 : : ;I?<;.?: ;2 <d<: ;I2 = : ;I?2 < > : ;I?2 < ? : ;I?2 <@.?: ; L 2 <dA.?: ; nI2 <dB.?: ; nI2 <dC.?: ; <D.?: ; <E.?: ; I<F.?: ; I<G.?: ; <dH.?: ; n<dI/IJ.?: ; nI<dK.?: ;nIL M2 <dL.?: ;n<dM : ; N : ;O9P4: ;I<Q:: ;R : ; S.?: ; nI<T.?: ;2 <cdU.?: ;L 2 <dV : ; 2 W : ;X : ;2 Y0I Z : ;I8 2 [.?: ;nI2 <\.?: ; <cd].?: ;<cd^<_.?: ; 2 <d`.?: ; 2 <cda : ; 2 b.?: ; n2 <dc : ; d : ; I8 2 e.?4<df.?42 <dg : ;h.?: ; n2 <di.?L 42 <dj.?: ;I<k4: ; nI?<l4: ; I<mn.?: ; n<o$ > p Iq : ; nr : ; s : ; ItIu!I/ v Iw.?: ;I<x : ; y9: ; z.?: ; I<d{.: ; I<|:: ; } I~.?: ; I<  : ; n : ;  I8 &! : ; I8 I: ;  : ;I 8  : ;n9: ; : ;.?: ;2 <d : ;.?42 <d: ;I2 .?: ; nI2 <.?: ; <d.?: ; n2 <d.?: ; nI2 < : ; : ;I : ; I?2 < : ;I8 .?: ;nI2 <.?: ;nI2 <.?: ;nI2 <d : ;I?2 <  : ;  : ; 2  I8 42 .?: ; nIL M2 <d.?: ; nL M2 <d.?: ;n2 <.?: ;n2 < : ;.?: ;nL M2 <d.?: ;nI2 <.?I4<d : ; : ;2  : ;I8.?L 42 <d.?: ;n2 <d.?: ; nIL M2 <d : ;2 .?nI42 <d.?: ;n2 <d.?: ;nL M<d9.?: ;L 2 <d.?: ;<.?: ;</.: ;I<.G<.: ;I<.: ;<.?: ;n<.: ; <4: ;nI?<4: ;I<4: ; nI?<4: ; I<4: ; I<4: ;I< 4: ;I<4: ;I<4: ;I<4: ; I< 4: ;I?<4: ; I<.?: ; I2 <d.?: ; I2 <d.?I42 <d.?: ;I2 <d.?: ;I2 <d.?: ;n2 <.?: ;n<d.?: ;nIL M<d.?I42 <d.?: ;nIL M<d.?: ;nL M2 <d.?: ; nL M2 <d.: ;I<.?: ;L <d.: ; I< : ;  : ; I: ; : ; .?: ;I : ;I.G dI4.G  4: ; I.G: ; d.: ; I 4: ; I5I: ; I: ; I.G: ; d: ;I.?: ; I .?: ; 4: ;I.G .G: ; 4: ;IdId  .4 .1n@dB1.1@B.G@dBI4.G@dBI1X Y1 411: ; I1.1n@dB1X Y1X Y 1RUX Y 1RUX Y U.1@B1 .1@dB1  1RUX Y 1RUX Y1B.G@B: ;I U4: ;I4: ;I: ; I: ; I4: ; I4: ; I1X Y 41.G: ;@B: ;I: ;I.G@B4: ;I4: ;I.G: ;@dBI4.1n@B414: ;I : ;I.G: ; @dB4: ; I.G: ; @B4: ; I!I/.G;@B41 1.G@B.G: ;@B: ; IB1B1B.G: ;@dB1X Y1B 4I.4@B14: ; I?<4I?4<4G4G 4G4G4G4G4Gn4Gn.?n4<.?nI4<.?I4<.?4<6.?4<.?I4<8 /usr/include/c++/4.9.2/bits./include/gtest/internal./include/gtest./src/usr/include/c++/4.9.2/ext/usr/include/c++/4.9.2/usr/include/usr/include/bits/usr/include/sys/usr/include/c++/4.9.2/i686-redhat-linux/bits/usr/include/c++/4.9.2/tr1/usr/lib/gcc/i686-redhat-linux/4.9.2/include/usr/include/c++/4.9.2/debuglocale_facets.hgtest-port.hgtest.hgtest-internal-inl.hgtest.ccstl_vector.hgtest-test-part.ccgtest-death-test-internal.hstl_algo.hnew_allocator.hgtest-internal.hbasic_string.hatomicity.hstl_construct.hgtest-death-test.ccgtest-printers.ccostreamchar_traits.hgtest-message.hgtest-param-util.hstl_iterator.hstring.hsstreamstdio.hvector.tccstl_algobase.hgtest-test-part.hgtest-filepath.ccstat.h gtest-filepath.hgtest-port.ccbasic_ios.hios_base.hstreambufistreamiomanipbasic_string.tccgtest-printers.hmove.hmathinline.hstl_uninitialized.hstl_tree.hstl_pair.htypeinfopredefined_ops.hstl_iterator_base_funcs.hgtest-typed-test.ccstl_set.hiostreamcwcharcpp_type_traits.hstl_iterator_base_types.hc++config.h clocalenewallocator.hstringfwd.hcwctypeostream.tccstl_bvector.htuple iosfwdstl_function.hcstdlibbasic_ios.tccpostypes.hfunctexcept.hostream_insert.hstdio.hlibio.hstdarg.h stddef.h wchar.htime.hnumeric_traits.halloc_traits.htype_traits.hdebug.h locale.htypes.hsched.htime.hpthreadtypes.hatomic_word.h wctype.hstdlib.htypes.h sigset.hselect.h stat.hunistd.hregex.hgtest-string.hgtest-spi.hgtest-death-test.hsiginfo.hsignal.hsigaction.hstdlib-float.hstdlib-bsearch.hfcntl-linux.htime.h socket_type.hsockaddr.hsocket.hnetdb.hgthr-default.h errno.hctype.hpthread.hsocket.h wait.h mman.h sched.hfcntl.hcxxabi.h  0 y ><~ Z~  tN -Zf,h ~ffJ i .|<J JiU2  FJ;< }<"M <s;rX %u fu<zC<fz<C<=Cf t/<kJ<;=;j/.bJ=<a<<b<>^< <>; vC.=fC<=Cf=Cf 4gI=ig t v f  lfl<C< xfx<|Jf|f C"V#zX# X X ;=m<& vtC {<X< ~.g uJCf J u  fu< uC< f u<C< X u<Cf=fC<=fC<!$e=q<p< |J.Mhb@ l< l<C<} lCf>RV0 f7X/!e!!;!// iC<f i<C<=Cf=Cf=Cf=Cf=Cf=Cf=Cf=Cf=Cf=Cf=Cf=Cf=Cf=Cfw Xw< < iC<=fC<=Cf=Cf=Cf=Cf=Cf=Cf=Cf=Cf = Cf = Cf=Cf=Cf=Cf=CfE>: <f .fg *~<~fC<=Cf~ < <C<=CfNF</X ~<~fC<=JCf=JCf=JCf=JCfNo   Cf=JCf=fCf=Cf=Cf=<Cf=Cf=Cf=Cf+4~f<~<<;/ ~t<~<C<2  CX=Cfge=0 Ju fu<{ uzC<fz<C<=JCf=JCf=JCfJy. ~. ~<C< ~GCf=Cf=Cf = Cf=C<=fC<=C<=fCX<=@~2X L  ~  <  {f  < <  . |t}L?9} }< ~ < ~<C<-=}*+t }.<!}X zft | tCf3#<@:"<*~ ux*}.}f<}}f<~%XKo< }< LbffaJ<a.fa<a<Xgs=a<a<XMv!-.=Dz=_Xg<xJ tjgyfy<'gzX<<Yz<;zJ<zy, y,z. Jz<<Yz<;Kz<<zy, y,z<z< Jzfu<k<Y K<ky, "y,k<<k Jf<k<Y K<ky, "y,k<<k Jfv<} tCX~J Cf=CX~ J} Cf=JCf~J Cf=Cf=<Cf~ J <}y,.}xfg;g u fu<{ ~C<f ~<C<=JCf =J CfJ+ ~ ~<C<  ~: Cf=fC<=fC<= Cf'<<<{< X||f|} <} <}<|ff|f<|<} <}<<fy<<|X|f}f} <} <| f|Jf|f<|<} <}<<}f<< rC<f r<C<=tCfX rCf = Cf=tC<=fC< .>l}e! nt< n<C< lJCfg;=rf|f|} <} <}<|ff| f| f|} <} <}<|ff| f| f| f| f| f  p< p< p"C<f p<C<=tCfX o< _C<=fC< = Cf #<o<~<f<<1 l,< l<C<v l$Cf&<= z#i# l1C<f l<C<J l< l<C<=+Cf=fC<=fC<<=} n<}f} }f< lC<f l<C<=Cf k,< k<C<}  k< k<C<;=s=|J k< k<C<)W/.z%w1 k(Cf =' Cf=Cf=Cf= C<=fC<< i.=K;=k|fL<$n;=kk&kfit}<}X<}<}<}<gk fk |<f ~f< <kJ fnf fn<|<f ~f< ~<C<=Cf%gWgf} <} <}<|ff|f<|< ~f< <kJ fkf <n<|<< ~f< ~<C<=Cf <Y:>}<}<l  ~f.l |<f|?l;=l {fC<=fC< = Cf<=;>-.fU|f| } <} <|f<<| <k7A$| +~< <kJ flfC<fl<C<'. }< }<C<u {.Cf/[ }<(x.DB*zfz  "~< <kJ fkt <k  ~< <kJ flfC<fl<C<=Cf| +~< <kJ flfC<fl<C<fe!]| +~< <kJ flfC<fl<C<fkK| )8C.=fCf|<0|<<|t<|. <~< <kJ XlfC<fl<C<=C<=fC<J {Cf=fCfX {fCf=C<=fC< }C<=fC<=C<=fC<=.C<=fC< i9u Z;Yd~|f|f<|.< <D<  lC<fl<C<|f| f}t} <}<<| ft~<  |f< |<C<.~73u~|f|f<|.< <D<  lC<fl<C<|f| f}}f<|<ft~<  |f< |<C<JT {JCf {<Cf=JCf=fCf J<k<fkX.k^<|<}f<<}.<fa<<d<dXKj=dt <d=%f\<$._:0" Jgf^!^.! d _  < _<C< / ^!d _  < _<C< sJ^!^<! d _  < _<C<  _;Cf {BCf {BCfO<= mf l<.y&}}. n<}} }f< lC<f l<C<=Cfjv(x<x<X  lM Cf=fC<=fC<#<>U1i_|f|J} <} <}f#<b<bXK.3\~X>~|f|{<<~ |<=s <vf}<< ~f<< {< {<C<{# |Cf~1KXwt |<Ct |J |.C<tfx<x. |.J |XC<f,g;xXx.k==z<f~<|<< ~f~<< <kJ <pf <p<<{~f<|<f~~< y<y<~f<|<f~y<y.~f<|ff~{~<B<f<>{~f<|<f~y<y.~<<|X<~{~<B<f<>{~f<|<f~y<y.~<<|X<~{~<B<f<>t~ <~ 7Av v< <~fK=_I:u~f<|<f~u <u<~f<|<f~z< u <u<~f<|<f~u <u<~f<|<f~zX<z< {tC.=fC< {Cf=XCf Xy"y< *~*X,. D X J. {f< {<C<=Cf=Cf=Cf=Cf=Cf=Cf=Cf X|}X<~<XguCy<_}XJ D X J. {f< {<C<=Cf=Cf=Cf=Cf=Cf=Cf=Cf **X, ~fX|JzJ:0 {XCf=Cf=Cf=Cf=Cf=Cf=Cf=Cf&=$&Cf$=$Cf"="Cf = Cf=Cf=Cf=Cf=CfC {$Cf {XCf~<Z}ff{.<>>  u fu< ~<<  u fu< yC<f y<C<=Cf=Cf=Cf=Cf=Cf2  usc<Xa  uX  uu}}.. Xg;! xXC<f x<C<=Cf"}}.X;Y xoCf=Cf=Cf=Cf=Cf=C<=fC<= C<=fC<=Cft y>C<=fC<"> )})X*X A t.f. zf< z<C<=Cf=Cf=Cf=Cf=Cf=Cf=Cf .X:>5. zf< z<C<=Cf=Cf=Cf=Cf d<f0.!e! zf< z<C<=Cf=Cf=Cf=Cf=Cf=.Cf. zeCf=Cf!=!Cf#=#Cf%=%Cf = Cf=Cf=<Cf=Cf=Cf=Cf = Cf =' Cf = Cf=Cf=?Cf=Cf=Cf=Cf=Cf-<~$ yfC<f y<C<=tCfXx y8Cf=tC<=fC< <~)y~f<|<f~y<y<~f<|<f~~< y<y<~f<|<f~y<y<~f<|<f~~X<~< {tC.=fC<t {Cf=XCf5 {C<=fC<=Cf+6<J~)y~f<|<f~y<y<~f<|<f~~< y<y<~f<|<f~y<y<~f<|<f~~X<~< {tC.=fC<t {Cf=XCf=RCfX {C<=fC<F<J~)y~f<|<f~y<y<~f<|<f~}< y<y<~f<|<f~y<y<~f<|<f~~X<~< {tC.=fC<t {Cf=XCf=RCfX {C<=fC<F<J~)y~f<|<f~y<y<~f<|<f~}< y<y<~f<|<f~y<y<~f<|<f~~X<~< {tC.=fC<t {Cf=XCf=RCfX {C<=fC<F<J~)y~f<|<f~y<y<~f<|<f~}< y<y<~f<|<f~y<y<~f<|<f~~X<~< {tC.=fC<t {Cf=XCf=RCfX {C<=fC<Fjbbe<e  aC< afC< ` <C< < <C<=Cf=Cf=Cf=Cf.m"8@ a.< a<C<4zrb'=;=YbXfc<~Jf:$ic {fCf!bf=%a%Z=N8@=?6KMW _#Cf!b'OJ> _Cf=Cf!(t]<f}  Jt .r</>:>vf </sJoff*k<J;g~   t f0wf~$|f ~f< <kJ fnf fn<|<f ~fC<f ~<C<v }. .< w*&/zf*/~*</~. ./l0J ~JC<=fC<|f ~f< <kJ fnf fn<|<f*</zf*~/~*</~.i0  }C<0< }<C</~X(X<|<|M:}f<|ff}/I /l< Cf*X/ye=*< {XCf=tCf/~ /~< /~< <C</~  ttCf#=\#\.#. hf h<. \C<#K=LLLLMxo< \C<$7^<<,hzXf]<#Xa' yC=C=C=C=C=C ""X$[ t f # yff y<C< *X% yC=C=C=C=C=C ##X%*V t f# yff y<C< ~X yf yX ytfV'!e!t yJf y<C<=C=C=C=C=C#eX,J!e!JJ!e!J!e! yf y<C<=C=C=C=C=C=C=C=C=C=C=C=Cyy<#P~XXy.|X h,gg) )w .yff<~J<yffX<yff<~f  yf y<C<XW(fX( Ke |X zf z<C<=C=C=C=C=C=C=C ~ph#[9i( ztC=C=C=C=C=C X zf z<C<~u y<C=C=C=C=C=C X yf y<C<d> yC=C=C=C=C=C X yf y<C< |X yf y<C<=C=C=C=C=C=C=C yXC=C=C=C=C=C X yf y<C< *|*X,X ? f XJXXX yff y<C<=C=C=C=C=C=C=C|<7f|<zfP<f~X gt<l<  j f j< ~f. <n fn< ~< ~<.n fn<~lJfl  ~. <n fn< ~< <n fn< ~C<f ~<C<}f tCX~tt J  h.Cf  kfg;3 h C<f h<C<=Cf~f }J.L, h < h<C<=Cf}f }J.K, h < h<C<=Cf)  h  <  h< C<=Cf0 hJ< h<C<=Cf6 h < h<C<=Cf h < { l<l<C<bsyb h~< hh:/<'.;;==< tCX~< J Cf<ztX w< w<C<w Jwf<w<X~f~<  tCX~ J<W).vX{f<!{tf{<{f<|3 {X xC<=<C<  wXCf=<Cf=tCfJJ$<>ketX~f./z t tCf bC%@w<=kf k</~<<k<JflP im{c J~< <.kJ fkCyXy<nl<l<z<fh<.c<f |X< ~f< <kJ fnf fn<|<f ~f< <kJ flf<l<C<.n<<n<fnrx. {< {<C< 91Y tCf x h:- t< < s<=fC<J}f fCX~tt J  t.Cf =  |u|f<|<Ju}< }X}<X SC< SfC< ~ Cf=Cf=Cf=Cf=CffvX < v   <~f<~<C<=;Ky),ty,| yJ'y<y< {C<=fC<=Cf = Cf = Cf @. wtCX w?Cf=fCf=CfJ< b<f bf< b.< i.t if2JztB<}f<|<<}f<<}.<|f<|<}fD < <C< s< <K {CXz5 Cf#`xf s* < s<C<  sCfv > LguLz x K)fu~ fw#jh9?+?sX ptt Kft~ Z0"+vW=1:hhhr p  <a<f82l#C_J fcf:>egL,>=-=c {Xi [9i f% {. |b}.t}t:>d5c fh 4 } ~<C<=fC<= Cf=Cf<f}}  t} }J ~< <l<l<C<=<Cf0 KKf0g;=I=X}<|X<}f}<<~ ~<< yb< z<z<C<u{. }<<!}< zf hf h.X Cfg;=  f<l<.kJ flf <ly..$ <|'~<-//.3u*~.~f<~~f<~ht+(!-.=<{f.u( >V..Xxffx< <w<} Cf~ J  w} Cf~  J@* <>Vt../x*./ + z<Xzf[b2XuYgt!.tN|t0,C<=fC<PE h:>}X_"!_<  u fu< ~<<  u fu< ~<  xC<f x<C<=JCf=JCf=JCf=JCf=JCf y<Cf=Cf= Cf= Cf= Cf  yC<=fC<=Cf=Cf=Cf=Cf=Cf=>C<=fC<G h:?e*U"+U<  u fu< ~<<  u fu< ~<  xC<f x<C<=JCf=JCf=JCf=JCf=JCf y Cf=Cf= Cf= Cf= Cf  yC<=fC<=Cf=Cf=Cf=Cf=Cf=>C<=fC<PJ< #C ~f#f~#"}f#f}f"f"<"f"<} f~f f}<.y. ~< .kJ lf<l<C<~#0 ~f Cf}<$Lf% z ft ) 7 <X {#X ~f#,~#~.#$}#f"}"<(""f"f} f~f|  f< }ff$}.f!<|<!| X#( ~f# ~f#~#f~.#}#f}t"<"""f} f~f .$}f!<|<!|fyf -sy ~f<|<~yfy.~f<|<~~< ytfy.~f<|<~yfy.~f<|<~f~ f~  {f {<C<=C|- C"V#z f# z#  #~f t< }f<|' C"V#z f# z# fuf#  #~f t<{<<gg<< zt fwf fwXx  {.C=.C.#xX 8}G#|/ 04Wk zJ t +  {#X ~f#.~#<~.#,}#f"}"<(""f"f} f~f|f f< }ff$}f!<|<!t| X#, ~f#J ~f#~#f~.##}#f}t"<"""f}f f~f .< }ff$}<f!<|<!t|fyf -sy<~f<|<~yfy.~f<|<~~< ytfy.~f<|<~yfy.~f<|<~f~ f~  {f {<C<=C|- C"V# {# z#  J#~f t< }f<|' C"V#z f# z#  #~f t<{<<gg<< y tp  {.C=.C.#xX 8}G#|/ 04a<=KI/.{+f{<& ytC<=fC<=JCfJ~Z~8 yC<=fC<= Cf`c@8@ ~J%f<<<<f  .s  X <J <~fC<f~<C<=JCfJ|<{X y)}<<)}. J)|a)}<.)}< tJ)|<} CX~J Cf ={z+ tg;0H V.Cf {zX CX=tCX)~ w Jw< X)kt <C } XCX)~ w Jw< X)ktX ~,)}X}w Jw< X)hXh K {fCf0ph  ~j:.u~J:.t|t.|. f={ yX1HKJo.~< J0I={tC{ zfj  ~hh{.zJz. k  ~j:.u~J:.t|t.|. f={ yX1HKJo.~< J0I={tC{ zf0m  ~j:.u~J:.t|t.|. f={ yX1HKJo.~< J0I={tC{ zfn KKf0 o< ~f Cf=Cf=Cf=Cf=Cf=Cf $$}X' I   u fu<z <z< u fu< u< u fu<z < <C<=Cf=fCf=Cf=.Cf= Cf=Cf }X C<=fC<=Cf=Cf=Cf=Cf=Cf = Cf=8C<=fC<=@C<=fC<rrfJsfJ@s[%f[J%ps[%f[J%s  ~j:.u~J:.t|t.|. f={ yX1HKJo.~< J0I={tC{ zfPug;f} <} <}z<,x<f,xuW{ff,x tt&| |X&f | #@ ~f#<0~#3"}J#f}t"f("<<"t}|  <~f f< }ff}.<}< m<m<|t C"V#z#fz# fuf#  X&;=#z+ &%}& X yJJ yJ< y< t m t m t mr J mt {ft { {n  mt  < mt  < mua pX yf. y.< y< "<nX<nX< m .nX  mJ"f rJ {J r { r {\ t.rX |<.nX  mJ X frJ|X  n   m  `X yJ yJ< y<-<.-a<-a<-a< `.v-.et-{<.et-{<. `B {<. {< {f. {f% N%.V<%*..Vf%*. f%~f .<. X%B%fmX< 8 t<&=;=& \J#< \#<Jyj8 [.Cf$;ְZKzx v u srqponmkig mJ [CfJ mJJ mJJL [Cf&=$ \t#< \#<JOj8 [.Cf$;ְZKzx v u srqponmkig mJ [CfJ mJJ mJJL [Cfp>,x<f,xuW{ff,x ttP Z CX~@ ~ J ~<.h:><~<f~<</  <t<  <s  J~<~<C< |<{X y)}<<)}. )wa)}f.)}<.)}< f)w<} tCX <={Jz tg-/={zX)0)S Cf f}3 t)}XX C)~X0)S&=91.q ]<~<~<C<u< CX~&Xd."` yX {fCf%`` {%Cf&=91.q ] ~<~<C<u<.w< CX~ <d.` yX {fCf%4`` {%Cfp Z Cf~0Е >ul<l<<guf <y{J|-;>) J)| <v< <t: tw)_< )hXXf J )t0)S @b@ ~J~$f~f<<~<f f< sf f< < <~f<~<C< |<{X y)}<<)}. J)|a)}f.)}<.)}< fJ)|<} tCf <={Jz t:h:/=t{zX)0)S Cff}3 t)}XX C)~X0)S<wf _8>H*X?9id q< q<C< q Cf?9i q< q<C<w  qCfw0<wf _8>H*X?9id q< q<C< X qCf?9i q< q<C<]r qCfwО<wf _8>H*X?9id q< q<C< q Cf?9i q< q<C<w  qCfwp<wf _8>H*X?9id q< q<C< X qCf?9i q< q<C<]r qCfw)_ZNK7testing8internal24HasNewFatalFailureHelper21has_new_fatal_failureEv_ZNSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE2atEjPrintAsStringLiteralTotesting_internalRawType_ZNK9__gnu_cxx17__normal_iteratorIPPN7testing8TestInfoESt6vectorIS3_SaIS3_EEEmiEi_ZNSt11char_traitsIcE4copyEPcPKcj_ZNSt6vectorIPcSaIS0_EE8_M_eraseEN9__gnu_cxx17__normal_iteratorIPS0_S2_EES6__S_oct_ZN7testing8TestCase11ClearResultEv_TypePrintStringTo__copy_move_backward_ZN7testing8internal12TypeIdHelperINS_4TestEE6dummy_E_ZN7testing8internal24HasNewFatalFailureHelperD0Ev_ZNSbIwSt11char_traitsIwESaIwEE6assignEPKw_ZN7testing22EmptyTestEventListener13OnTestCaseEndERKNS_8TestCaseE_ZN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE11ValueHolder7pointerEv_ZNK7testing8internal13FloatingPointIfE8sign_bitEv_ZN7testing8TestCase16RunSetUpTestCaseEvstrtof_ZNKSbIwSt11char_traitsIwESaIwEE7compareEjjPKw__alloc_traits >_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE6_S_keyEPKSt13_Rb_tree_nodeIS1_E_ZN7testing32ScopedFakeTestPartResultReporter4InitEvstrtoloperator<< _ZN9__gnu_cxx14__alloc_traitsISaIPN7testing8TestInfoEEE10_S_on_swapERS4_S6__ZN7testing8internal13DeathTestImpl12set_write_fdEi_ZN7testing8TestInfoaSERKS0___haystackIsNotSubstringconstruct >ImplicitCast__ZNKSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE2atEjgtest_arline_number__ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EE2atEj_ZNK9__gnu_cxx17__normal_iteratorIPN7testing12TestPropertyESt6vectorIS2_SaIS2_EEEptEvCheckedDowncastToActualType >::ValueHolder, testing::internal::ThreadLocalValueHolderBase>_ZNSt6vectorIPN7testing8TestCaseESaIS2_EE7reserveEj__niter_base_ZNKSt6vectorIiSaIiEE8capacityEvHandleExceptionsInMethodIfSupported_ZN9__gnu_cxx17__normal_iteratorIPKPN7testing17TestEventListenerESt6vectorIS3_SaIS3_EEEmmEi_ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EE5frontEv__copy_move_backward_a_ZN7testing8internal27PrettyUnitTestResultPrinter11OnTestStartERKNS_8TestInfoE_ZN7testing18TestEventListeners22SetDefaultXmlGeneratorEPNS_17TestEventListenerEHandleSehExceptionsInMethodIfSupportedMSG_EOR_ZNKSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE12_M_rightmostEv_ZN7testing8internal12UnitTestImpl21set_current_test_infoEPNS_8TestInfoE_ZN9__gnu_cxx17__normal_iteratorIPKN7testing8internal9TraceInfoESt6vectorIS3_SaIS3_EEEmIEitype__ZNKSs5rfindERKSsj__uninit_copy<__gnu_cxx::__normal_iterator*, std::vector > >, std::basic_string*>si_codesockfd__ZNKSt3setISsSt4lessISsESaISsEE11upper_boundERKSs_ZNKSt9_IdentityISsEclERKSsmbsinit_ZNKSt6vectorIiSaIiEE8max_sizeEv~ExecDeathTest_ZNSt6vectorIPN7testing11EnvironmentESaIS2_EEixEj__numeric_traits_integer_ZN7testing22EmptyTestEventListener22OnEnvironmentsSetUpEndERKNS_8UnitTestEoperator<< last_errorUniversalPrint >_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE5eraseESt17_Rb_tree_iteratorISsEuninitialized_copybreak_on_failure__ZNK7testing8internal10scoped_ptrIKSsEdeEv_ZNSbIwSt11char_traitsIwESaIwEEpLEPKwswap*>expected_expressiondata___rhsactual_ZNKSt17_Rb_tree_iteratorIPKcEdeEv_ZNSt6vectorIPN7testing8TestCaseESaIS2_EE4rendEv_ZNK7testing8internal8FilePath21FileOrDirectoryExistsEv11__mbstate_tIsPathSeparator_ZNSt12_Vector_baseIPN7testing11EnvironmentESaIS2_EE13_M_deallocateEPS2_j_ZN7testing8internal17StreamingListener12SocketWriterD0Ev_ZN9__gnu_cxx17__normal_iteratorIPKPN7testing17TestEventListenerESt6vectorIS3_SaIS3_EEEmmEv_ZNSt6vectorIN7testing12TestPropertyESaIS1_EE15_M_erase_at_endEPS1_si_errno_ZN7testing8internal12UnitTestImpl21set_current_test_caseEPNS_8TestCaseE_ZNK7testing8internal10scoped_ptrIKSsE3getEv_ZN7testing8internal13DeathTestImpl11set_spawnedEbpair_ZN7testing19TestPartResultArrayaSERKS0___normal_iterator, std::allocator > >vector >_ZNKSt12_Vector_baseIN7testing12TestPropertyESaIS1_EE13get_allocatorEvcopy_backward*, std::basic_string*>_ZNSt6vectorISsSaISsEE8_M_eraseEN9__gnu_cxx17__normal_iteratorIPSsS1_EES5_should_run__ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE15_M_insert_equalERKS1_FloatingPointLE_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE6_S_keyEPKSt13_Rb_tree_nodeISsEfor_each<__gnu_cxx::__normal_iterator >, void (*)(testing::Environment*)>_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE12_M_erase_auxESt23_Rb_tree_const_iteratorIS1_ES9_StrError_Destroy_ZNKSbIwSt11char_traitsIwESaIwEE13get_allocatorEv_M_insert_lower_ZNSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE8pop_backEv~StreamingListeneroperator- >_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE16_M_insert_uniqueERKSsTEST_ENCOUNTERED_RETURN_STATEMENT_ZNK9__gnu_cxx17__normal_iteratorIPPN7testing8internal29ParameterizedTestCaseInfoBaseESt6vectorIS4_SaIS4_EEE4baseEv_ZN7testing4Test14RecordPropertyERKSsiiterator_traits<__gnu_cxx::__normal_iterator, std::allocator >*, std::vector, std::allocator >, std::allocator, std::allocator > > > > >_ZN9__gnu_cxx14__alloc_traitsISaIN7testing8internal9TraceInfoEEE10_S_on_swapERS4_S6__ZNSt11char_traitsIwE11eq_int_typeERKjS2___cxa_begin_catchsrc_texterror_message_ZNKSt6vectorIPN7testing11EnvironmentESaIS2_EE5beginEvoperator delete_ZNKSt12_Vector_baseIPcSaIS0_EE13get_allocatorEv_ZNSt6vectorIPcSaIS0_EE4dataEv_Allocator_ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EE2atEjoriginal_reporter__ZN9__gnu_cxx13new_allocatorISsE10deallocateEPSsj_ZN7testing8internal23kTestTypeIdInGoogleTestE_ZN9__gnu_cxx13new_allocatorIPKcE7destroyEPS2_operator<< , std::allocator >_ZN7testing8TestCaseaSERKS0_AssertHeld_ZNKSt6vectorIPN7testing8TestCaseESaIS2_EE4dataEv_ZNK9__gnu_cxx17__normal_iteratorIPcSsE4baseEv_ZN7testing8internal17TestEventRepeaterD2Ev_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE7_S_leftEPKSt18_Rb_tree_node_basereverse_iterator<__gnu_cxx::__normal_iterator, std::allocator > > >TestPartResultTypeToString_ZN9__gnu_cxx14__alloc_traitsISaIPN7testing17TestEventListenerEEE8max_sizeERKS4__ZN7testing8UnitTest14AddEnvironmentEPNS_11EnvironmentE_ZNSs7reserveEj_ZNSt12_Vector_baseIPcSaIS0_EE17_M_create_storageEj_Iter_equals_val, std::allocator > >InitGoogleTestRETURNED_ZNKSt12_Vector_baseIiSaIiEE13get_allocatorEvregistered_testsoperator booluser_msg_string_ZN7testing8internal13ExecDeathTestD0Ev__ino_toriginal_working_dir_iterator_traits, std::allocator >*>_ZN7testing8internal12UnitTestImpl31GetGlobalTestPartResultReporterEv_ZNK7testing8internal12UnitTestImpl21successful_test_countEv_ZNK9__gnu_cxx17__normal_iteratorIPKcSsEplEinormalized_seed_ZN7testing14TestPartResult14ExtractSummaryEPKcStackLowerThanAddress_ZNK9__gnu_cxx17__normal_iteratorIPPN7testing8TestCaseESt6vectorIS3_SaIS3_EEEmiEitest_properties_ZNK9__gnu_cxx13new_allocatorIPN7testing17TestEventListenerEE7addressERS3__CharToperator<< _ZN7testing14ExitedWithCodeC2Ei_ZN7testing8internal12UnitTestImpl34InitDeathTestSubprocessControlInfoEvignoring_casePrintTowcstold_ZNSt12_Vector_baseIPN7testing17TestEventListenerESaIS2_EE17_M_create_storageEj_ZNSt10_Iter_baseIN9__gnu_cxx17__normal_iteratorIPPN7testing17TestEventListenerESt6vectorIS4_SaIS4_EEEELb0EE7_S_baseES9__ZN9__gnu_cxx14__alloc_traitsISaIiEE17_S_select_on_copyERKS1_copy_backward_ZNSbIwSt11char_traitsIwESaIwEE6appendEPKwj_ZNKSbIwSt11char_traitsIwESaIwEE16find_last_not_ofEPKwjj_ZN9__gnu_cxx14__alloc_traitsISaIPN7testing11EnvironmentEEE8max_sizeERKS4__ZN9__gnu_cxx17__normal_iteratorIPKcSsEmIEiClearTestResult_ZNKSs11_M_disjunctEPKc_vptr.UnitTestdestinternal_run_death_test_flag__ZN7testing8internal17StreamingListener12SocketWriter15CloseConnectionEv_M_destroy_noderegoff_tparameter_ZNSt6vectorIPcSaIS0_EE8pop_backEv_ZNK7testing8internal12UnitTestImpl11random_seedEv_ZNK7testing8internal13DeathTestImpl6statusEvlast_sep_ZN7testing8internal16UniversalPrinterISsE5PrintERKSsPSoad_hoc_test_result__ZN7testing8internal15CodePointToUtf8Ejunicode_code_pointcomma__distanceFloatingPoint_ZNKSbIwSt11char_traitsIwESaIwEE16find_last_not_ofEPKwjFormatForComparisonFailureMessage_ZNK7testing14TestPartResult14fatally_failedEv_Category~TestFactoryBasekUniversalFilter__builtin_fwrite_ZN7testing8internal13GetTestTypeIdEv_ZNSs4_Rep7_M_grabERKSaIcES2__M_copyreverse_iterator<__gnu_cxx::__normal_iterator, std::allocator >*, std::vector, std::allocator >, std::allocator, std::allocator > > > > >_ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EE6insertEN9__gnu_cxx17__normal_iteratorIPS2_S4_EEjRKS2___cxa_throw_ZN9__gnu_cxx13new_allocatorIwE8allocateEjPKv_ZNSbIwSt11char_traitsIwESaIwEE6assignERKS2_summary_rdstatekStackTraceDepthFlagfreadTestPartResultArraythread_count__copy_move_b*, std::basic_string*>operator!= >_S_black_ZNSo9_M_insertIPKvEERSoT___cxa_guard_abort_ZN7testing8internal12UnitTestImpl12ShuffleTestsEv_sigfaultGTEST_SHARD_INDEXMSG_CONFIRM__is_normal_iterator_ZNSt6vectorIiSaIiEEixEjTearDownTestCaseFunc__miter_basekThresholdint_n_cs_precedesbinary_function, std::allocator >, std::basic_string, std::allocator >, bool>_ZN7testing8internal35HandleExceptionsInMethodIfSupportedINS_8TestCaseEvEET0_PT_MS4_FS3_vEPKc_M_key_compare~ForkingDeathTest_ZNKSt6vectorISsSaISsEE6rbeginEvreverse_iterator<__gnu_cxx::__normal_iterator > > >kReservedTestSuiteAttributes_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE15_M_destroy_nodeEPSt13_Rb_tree_nodeIS1_E_ZN7testing7MessageC2Ev_ZNKSs13find_first_ofEcj_ZN9__gnu_cxx17__normal_iteratorIPKSsSt6vectorISsSaISsEEEmmEisi_addr_lsb_ZNKSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE14_M_range_checkEj_ZN9__gnu_cxx17__normal_iteratorIPKPN7testing8TestInfoESt6vectorIS3_SaIS3_EEEmIEi_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE16_M_insert_equal_ESt23_Rb_tree_const_iteratorIS1_ERKS1__ZNSt6vectorIiSaIiEE5beginEv_ZN9__gnu_cxx17__normal_iteratorIPKSsSt6vectorISsSaISsEEEmmEv_Valcurrent_test_info_operator<< GTEST_ERROR_ZN7testing8internal29ParameterizedTestCaseInfoBaseaSERKS1_kColorEncodedHelpMessage_ZNSt6vectorIN7testing14TestPartResultESaIS1_EE5eraseEN9__gnu_cxx17__normal_iteratorIPS1_S3_EE_ZNSbIwSt11char_traitsIwESaIwEE6assignERKS2_jj_Key_ZNSt6vectorIN7testing12TestPropertyESaIS1_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS1_S3_EERKS1__ZNSbIwSt11char_traitsIwESaIwEE4_Rep7_M_grabERKS1_S5_~SingleFailureChecker_ZNK7testing8UnitTest22test_case_to_run_countEvpop_backrend_ZNKSbIwSt11char_traitsIwESaIwEE17find_first_not_ofEPKwjsuccessful_test_count_ZNKSs5rfindEPKcjj_ZN9__gnu_cxx17__normal_iteratorIPKPN7testing17TestEventListenerESt6vectorIS3_SaIS3_EEEpLEioutput_format_ZN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE11ValueHolderaSERKS5_rebind~ScopedPrematureExitFileoperator<< _ZN7testing8internal2RE9FullMatchEPKcRKS1_MSG_RSTOnTestPartResult_ZN7testing4Test15HasFatalFailureEv__cxa_atexit_ZN7testing8internal17PrintWideStringToERKSbIwSt11char_traitsIwESaIwEEPSocur_addr_ZN7testing8internal12UnitTestImpl27parameterized_test_registryEv_ZNKSs5beginEv_ZNK7testing8internal13DeathTestImpl7outcomeEv__cxa_guard_acquirefind_first_of__normal_iterator, std::allocator >*, std::vector, std::allocator >, std::allocator, std::allocator > > > >_ZNSt6vectorIN7testing14TestPartResultESaIS1_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS1_S3_EERKS1__ZN7testing8internal27PrettyUnitTestResultPrinterD2EvGetTestPartResult_ZNSbIwSt11char_traitsIwESaIwEE6insertEjRKS2_jjoutput_GetPrefixUntilComma_ZN7testing8internal24XmlUnitTestResultPrinter24IsNormalizableWhitespaceEc_ZNSt6vectorIN7testing14TestPartResultESaIS1_EE6rbeginEvCOLOR_GREENoperator<< _ZN7testing8internal16ForkingDeathTestC2EPKcPKNS0_2REEline_num_S_right_ZN9__gnu_cxx13new_allocatorISt13_Rb_tree_nodeISsEE8allocateEjPKvMakeFrom_S_empty_rep_ZSt29_Rb_tree_insert_and_rebalancebPSt18_Rb_tree_node_baseS0_RS__Znwj_ZN9__gnu_cxx17__normal_iteratorIPPN7testing11EnvironmentESt6vectorIS3_SaIS3_EEEpLEi__is_null_pointermethod_ZNSs6insertEN9__gnu_cxx17__normal_iteratorIPcSsEEjc_ZNK9__gnu_cxx13new_allocatorIPcE7addressERKS1__ZNKSs7compareEjjRKSsset_current_test_case_ZNSt12_Vector_baseIPN7testing17TestEventListenerESaIS2_EE13_M_deallocateEPS2_j_ZN7testing7MessagelsEPw__iterator_category__is_normal_iterator_ZN7testing8internal10scoped_ptrINS0_24InternalRunDeathTestFlagEE5resetEPS2_iterator_traitsUniversalPrintCharArray_ZN9__gnu_cxx13new_allocatorIPcE9constructEPS1_RKS1___alloc_traits >operator!= >__destroy__elems_beforevalue_compare_ZNSt11char_traitsIwE2eqERKwS2__ZNKSt6vectorIPN7testing8TestCaseESaIS2_EE8capacityEv9siginfo_t~TestEventRepeater_ZN7testing10TestResultaSERKS0__ZNKSt6vectorIN7testing12TestPropertyESaIS1_EE4dataEv_ZNK7testing8TestCase17test_to_run_countEvseekdirGetCurrentExecutableNametest_case_name__Destroy*, std::basic_string >operator- >_vptr.UnitTestImpl_ZN9__gnu_cxx17__normal_iteratorIPKcSsEpLEi_ZNKSt18basic_stringstreamIcSt11char_traitsIcESaIcEE3strEvexpression_textOnTestCaseEndbytes_readtm_hour_ZNSt6vectorISsSaISsEE8_M_eraseEN9__gnu_cxx17__normal_iteratorIPSsS1_EESignAndMagnitudeToBiasedoperator<< __trip_countreportable_test_count_M_insert_ZNSt3setISsSt4lessISsESaISsEE4findERKSs_ZNSbIwSt11char_traitsIwESaIwEE7replaceEN9__gnu_cxx17__normal_iteratorIPwS2_EES6_jw_ZNK7testing8internal29ParameterizedTestCaseInfoBase17GetTestCaseTypeIdEvCaptureStdout_ZNSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE6insertEN9__gnu_cxx17__normal_iteratorIPS3_S5_EERKS3__ZNSt6vectorIPN7testing11EnvironmentESaIS2_EE8_M_eraseEN9__gnu_cxx17__normal_iteratorIPS2_S4_EE_ZNSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS3_S5_EERKS3___addressof >_ZNKSt3setISsSt4lessISsESaISsEE4findERKSsunknown fileExecDeathTestArgs_ZNKSt6vectorIPN7testing8TestCaseESaIS2_EE8max_sizeEv__gthread_active_ptrkExponentBitCountstatus_ok_ZNK7testing8internal13FloatingPointIdE13exponent_bitsEv_ZNKSbIwSt11char_traitsIwESaIwEE13find_first_ofEPKwj_ZNKSt6vectorIPcSaIS0_EE5frontEv_S_out_ZN7testing8internal24XmlUnitTestResultPrinter18EscapeXmlAttributeERKSs_Destroy_ZN9__gnu_cxx13new_allocatorIPN7testing8TestInfoEE9constructEPS3_RKS3__ZN7testing8internal12UnitTestImpl11RunAllTestsEv_ZNSt6vectorIPN7testing8TestInfoESaIS2_EE4swapERS4__ZN7testing8internal9DeathTest4WaitEv_ZN9__gnu_cxx17__normal_iteratorIPSsSt6vectorISsSaISsEEEmmEi_HasBase_ZN7testing18TestEventListenersD2Ev_ZNSt6vectorIPN7testing8TestCaseESaIS2_EE9push_backERKS2__vptr.AbstractSocketWriter_ZN9__gnu_cxx17__normal_iteratorIPSsSt6vectorISsSaISsEEEmmEv_ZNK7testing8internal8FilePath5c_strEvdo_widen_ZNKSt6vectorIPN7testing8TestCaseESaIS2_EE4rendEv_ZN7testing8internal12UnitTestImpl31SetGlobalTestPartResultReporterEPNS_31TestPartResultReporterInterfaceE_ZNK7testing19TestPartResultArray4sizeEv_ZNK7testing8TestCase6PassedEvPopGTestTracesign_bitrebind_ZNSt12_Vector_baseIN7testing8internal9TraceInfoESaIS2_EE13_M_deallocateEPS2_j_ZNKSt6vectorISsSaISsEE4rendEv_ZNK7testing15AssertionResult7messageEv_ZNK7testing8internal17TestEventRepeater18forwarding_enabledEva_value_paramoperator!__iterator_categoryfputcoperator&operator*operator+iterator_traitsoperator-_ZNSt12_Vector_baseIPN7testing11EnvironmentESaIS2_EE11_M_allocateEj_ZStplIcSt11char_traitsIcESaIcEESbIT_T0_T1_ERKS6_S8_operator<operator=operator>FormatForComparison_ZNSs9_M_mutateEjjj_ZN7testing17TestEventListener24OnEnvironmentsSetUpStartERKNS_8UnitTestE_ZNKSt3setISsSt4lessISsESaISsEE5beginEv_ZN7testing8internal6Random6ReseedEj_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE17_M_insert_unique_ESt23_Rb_tree_const_iteratorIS1_ERKS1_rebindSOCK_RAW_ZNSt6vectorIPN7testing8TestCaseESaIS2_EE6insertEN9__gnu_cxx17__normal_iteratorIPS2_S4_EERKS2__ZN7testing8internal7PrintToEhPSo_ZNSs12_S_constructIPcEES0_T_S1_RKSaIcEis_selectedsystemwcsrtombs_ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EEixEj__valFailFromInternalError_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE14_M_lower_boundEPSt13_Rb_tree_nodeIS1_ESA_RKS1__timer_ZN7testing10TestResult17AddTestPartResultERKNS_14TestPartResultEquot_ZNSt6vectorISsSaISsEE6rbeginEv_ZNKSt6vectorIPN7testing11EnvironmentESaIS2_EE6rbeginEvthrow_on_failure_operator|operator~atof_ZNSt9basic_iosIcSt11char_traitsIcEE5clearESt12_Ios_Iostate_ZN9__gnu_cxx17__normal_iteratorIPKPN7testing8TestCaseESt6vectorIS3_SaIS3_EEEmIEiatoiatol_ZNKSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE6rbeginEv_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE3endEvPrintToStringconstruct_ZN7testing4Test13SetUpTestCaseEv_ZN7testing8internal17TestEventRepeateraSERKS1__ZNSt3setISsSt4lessISsESaISsEE5eraseESt23_Rb_tree_const_iteratorISsEwcstombs_Rb_tree_iterator_ZN7testing8internal26ThreadLocalValueHolderBaseaSERKS1__Znaj_ZN9__gnu_cxx17__normal_iteratorIPKSsSt6vectorISsSaISsEEEpLEi__k2_M_eraseCreateDirectoriesRecursively_ZNSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE5eraseEN9__gnu_cxx17__normal_iteratorIPS3_S5_EES9_exit_status_ZNSt6vectorIiSaIiEE5eraseEN9__gnu_cxx17__normal_iteratorIPiS1_EEfull_pattern_S_hex_sigpoll_ZNKSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE6_M_endEvint_p_sep_by_spacekMaxRangeGetStringFunctor_ZN7testing8internal12AssertHelper16AssertHelperDataaSERKS2__Rb_tree_const_iterator, std::allocator > >_ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EE15_M_erase_at_endEPS2_IsAbsolutePathfailed_test_case_count_ZNKSt6vectorIPN7testing8TestCaseESaIS2_EE5frontEv_ZNSs4_Rep10_M_disposeERKSaIcEfputwc_Iterator_Iter_base_M_clone_nodeParseStringFlagFilterMatchesTestfputwsMakeConnection~basic_stringCmpHelperSTRCASEEQiterator_traits<__gnu_cxx::__normal_iterator > > >_ZNK7testing8TestInfo6resultEv_ZNKSs12find_last_ofERKSsj_ZN7testing8UnitTestC2Ev_ZNK9__gnu_cxx17__normal_iteratorIPPN7testing8TestInfoESt6vectorIS3_SaIS3_EEEptEv_ZNSt6vectorIiSaIiEEaSERKS1_fcntl_ZNK7testing8internal17TestPropertyKeyIsclERKNS_12TestPropertyE~DeathTestImpl_ZN7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEE11ValueHolderaSERKS7__ZN7testing8internal13FloatingPointIfE8InfinityEv_S_ios_openmode_end_ZN7testing8TestCaseD2EvGetOutputFormat_ZN9__gnu_cxx13new_allocatorIcE10deallocateEPcj_ZN7testing8internal18SetInjectableArgvsEPKSt6vectorISsSaISsEErandom_ZN9__gnu_cxx14__alloc_traitsISaISsEE8max_sizeERKS1__ZNKSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE11upper_boundERKSs_ZNKSt6vectorIPN7testing17TestEventListenerESaIS2_EE2atEjstrtold_ZNK9__gnu_cxx17__normal_iteratorIPKN7testing8internal9TraceInfoESt6vectorIS3_SaIS3_EEEdeEvoperator<< suffix_len_ZNSt6vectorIPcSaIS0_EE5frontEvportset_up_tc__maskTestPassed_M_destroyMSG_MOREnew_holder_ZN9__gnu_cxx14__alloc_traitsISaIN7testing14TestPartResultEEE10_S_on_swapERS3_S5__ZNKSt6vectorIN7testing14TestPartResultESaIS1_EE2atEj_M_fill_assign_ZNSt3setIPKcSt4lessIS1_ESaIS1_EE4findERKS1_operator<< operator<< _ZNKSs7_M_iendEv_ZN7testing8internal11ScopedTraceD2Evresume_pos_ZNK7testing8internal12UnitTestImpl18ad_hoc_test_resultEvtm_yday_ZNSt6vectorIPN7testing8TestInfoESaIS2_EE14_M_fill_assignEjRKS2__ZNSt8ios_base4setfESt13_Ios_FmtflagsS0_putwcharftell__miter_base<__gnu_cxx::__normal_iterator > >SOCK_STREAM_ZSt16__ostream_insertIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_PKS3_istream_result_to__ZNSt6vectorIPN7testing11EnvironmentESaIS2_EE7reserveEj_ZN7testing8internal12AssertHelperaSERKS1_ExecDeathTestSpawnChild__blksize_t_ZNKSbIwSt11char_traitsIwESaIwEE12find_last_ofEPKwjj_M_upper_bound_ZNK9__gnu_cxx17__normal_iteratorIPPcSt6vectorIS1_SaIS1_EEEixEiPrintCharAndCodeTo_ZN7testing14TestPartResultD2EvAddEnvironment_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE10_S_maximumEPKSt18_Rb_tree_node_basepthread_mutex_unlock_ZNKSt6vectorIPcSaIS0_EE3endEvint_curr_symbolset_write_fd~GTestLog_ZN7testing8UnitTest14PushGTestTraceERKNS_8internal9TraceInfoEnum_runnable_tests_ZNK9__gnu_cxx17__normal_iteratorIPKN7testing8internal9TraceInfoESt6vectorIS3_SaIS3_EEEixEi_ZNSbIwSt11char_traitsIwESaIwEE6insertEjRKS2__ZNKSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE5beginEv_ZN7testing8internal12AssertHelperD2Ev_ZNK9__gnu_cxx13new_allocatorIcE7addressERKcpthread_key_create_TrivialValueTypesfind_if<__gnu_cxx::__normal_iterator >, testing::internal::TestCaseNameIs>translate_ZNSt6vectorIPN7testing8TestCaseESaIS2_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS2_S4_EERKS2_wcstoul__is_normal_iteratorsa_data_ZNSt6vectorIPN7testing8TestInfoESaIS2_EE6insertEN9__gnu_cxx17__normal_iteratorIPS2_S4_EERKS2_index___mode_t_ZN7testing8internal18InitGoogleTestImplIcEEvPiPPT___cxa_bad_typeid_DestroyFLAGS_gtest_repeat__n1pair, std::_Rb_tree_const_iterator >_ZNSs13_S_copy_charsEPcN9__gnu_cxx17__normal_iteratorIPKcSsEES4__ZN9__gnu_cxx17__normal_iteratorIPSsSt6vectorISsSaISsEEEpLEi_Destroysrc/gtest-all.cc~basic_stringbufFormatFileLocation_ZNSt6vectorIPcSaIS0_EE8_M_eraseEN9__gnu_cxx17__normal_iteratorIPS0_S2_EE_M_insert_equalconst_reverse_iteratorwchar_t_ZN9__gnu_cxx14__alloc_traitsISaIPN7testing11EnvironmentEEE7destroyERS4_PS3__ZNKSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE6rbeginEv_ZNK7testing7Message9GetStringEv_markers__assignable__copy_move_backwardOnEnvironmentsSetUpStart_ZN9__gnu_cxx14__alloc_traitsISaIPN7testing8internal29ParameterizedTestCaseInfoBaseEEE17_S_select_on_copyERKS5___alloc_traits >_ZN7testing8internal10scoped_ptrINS0_24InternalRunDeathTestFlagEEaSERKS3_iostatea_write_fd__pad1__pad2__pad3__copy_move_a__pad5a_filesi_overrun_ZNK7testing8internal8FilePath28CreateDirectoriesRecursivelyEvRecordProperty_ZNK7testing8internal13DeathTestImpl7read_fdEv_M_get_Tp_allocatorgetwchar__destroy*>_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE7_M_rootEv_ZN9__gnu_cxx17__normal_iteratorIPPN7testing8internal29ParameterizedTestCaseInfoBaseESt6vectorIS4_SaIS4_EEEmIEi_ZNKSt6vectorIPN7testing17TestEventListenerESaIS2_EE4dataEv_ZNKSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE4rendEv_ZNKSt17_Rb_tree_iteratorIPKcEneERKS2__ZNKSt6vectorIN7testing12TestPropertyESaIS1_EE2atEj_ZN9__gnu_cxx3divExxstdout_is_ttycopy_backward_ZNK9__gnu_cxx17__normal_iteratorIPKPN7testing17TestEventListenerESt6vectorIS3_SaIS3_EEEplEi_ZNK9__gnu_cxx17__normal_iteratorIPKPN7testing11EnvironmentESt6vectorIS3_SaIS3_EEE4baseEv_ZN7testing8internal24XmlUnitTestResultPrinter17OutputXmlTestInfoEPSoPKcRKNS_8TestInfoE_ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EE9push_backERKS2__ZNSt6vectorIN7testing14TestPartResultESaIS1_EE14_M_fill_insertEN9__gnu_cxx17__normal_iteratorIPS1_S3_EEjRKS1__ZNK7testing8UnitTest18ad_hoc_test_resultEvtotal_test_case_count_ZNKSt16reverse_iteratorIN9__gnu_cxx17__normal_iteratorIPPN7testing11EnvironmentESt6vectorIS4_SaIS4_EEEEEplEioperator<< __copy_move_backward_aoperator<< _ZN9__gnu_cxx13new_allocatorIN7testing14TestPartResultEE10deallocateEPS2_jcur_pattern_ZN7testing4TestaSERKS0__ZNSt6vectorIPN7testing8TestInfoESaIS2_EE2atEj_ZN7testing15AssertionResult13AppendMessageERKNS_7MessageEIsSubstringImpl >__copy_move_a2_ZN7testing32ScopedFakeTestPartResultReporter20ReportTestPartResultERKNS_14TestPartResultEMSG_DONTWAITiterator_traits_ZNSt3setIPKcSt4lessIS1_ESaIS1_EE11lower_boundERKS1__ZNSt13_Rb_tree_nodeISsE9_M_valptrEvkElidedFramesMarkerset_read_fdParseInternalRunDeathTestFlagstatus__ZN7testing8internal19TypedTestCasePState25VerifyRegisteredTestNamesEPKciS3__ZNSt6vectorIPcSaIS0_EE14_M_fill_insertEN9__gnu_cxx17__normal_iteratorIPS0_S2_EEjRKS0__ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE12_M_erase_auxESt23_Rb_tree_const_iteratorISsES7_GetMutableTestCase*DeathTest:*DeathTest/*_ZNKSs16find_last_not_ofEPKcj__osRelease_ZNK9__gnu_cxx17__normal_iteratorIPKcSsEmiEi_IO_write_base__distance_ZNSt3setISsSt4lessISsESaISsEE11upper_boundERKSs_ZNK9__gnu_cxx17__normal_iteratorIPPN7testing8TestCaseESt6vectorIS3_SaIS3_EEEptEvUniversalPrinter, std::allocator > >_ZN7testing8TestCase14UnshuffleTestsEvreason_ZN7testing8internal23GetLastErrnoDescriptionEv__miter_base__builtin_memcmp_ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EE6rbeginEvfront_ZN7testing8internal7PrintToEPKwPSowmemsetsetfillkTestcase_ZNKSt6vectorIN7testing8internal9TraceInfoESaIS2_EEixEj__copy_move_backward_a2FormatCompilerIndependentFileLocationpush_backtotal_shards_envsubstr_ZNKSt6vectorIN7testing14TestPartResultESaIS1_EE6rbeginEv_ZN9__gnu_cxx14__alloc_traitsISaIPKcEE17_S_select_on_copyERKS3__ZNKSt6vectorIN7testing14TestPartResultESaIS1_EEixEjincrement_death_test_count_ZNKSt6vectorIiSaIiEE5beginEv_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE13_Rb_tree_implIS5_Lb0EE13_M_initializeEv_ZN9__gnu_cxx14__alloc_traitsISaISt13_Rb_tree_nodeISsEEE10deallocateERS3_PS2_jst_ino_ZNKSt6vectorIiSaIiEE3endEvxml_element_S_terminal_ZNK9__gnu_cxx13new_allocatorISt13_Rb_tree_nodeIPKcEE7addressERS4__Compare_ZN7testing8internal17StreamingListener16OnTestProgramEndERKNS_8UnitTestEstrtouliterator_traits_ZNKSs4findEPKcj_ZN7testing17TestEventListener9OnTestEndERKNS_8TestInfoEPrintToString_ZN9__gnu_cxx14__alloc_traitsISaIPN7testing11EnvironmentEEE8allocateERS4_jlast_death_test_message_~_Rb_treeStrCaseCmp_ZN7testing8internal35DefaultGlobalTestPartResultReporterC2EPNS0_12UnitTestImplETHREWPrintTestNameis_valid__ZN7testing8internal35DefaultGlobalTestPartResultReporterD0EvMSG_TRUNC_ZN7testing8internal13DeathTestImpl5AbortENS0_9DeathTest11AbortReasonEDefaultPrintTodelimiterIsDigit_ZNSt11char_traitsIcE7not_eofERKi__it__destroy_ZN7testing8internal15FloatingPointLEIdEENS_15AssertionResultEPKcS4_T_S5__ZNKSs12find_last_ofEPKcjj__u_quad_t_ZN9__gnu_cxx17__normal_iteratorIPPN7testing8TestInfoESt6vectorIS3_SaIS3_EEEppEi__normal_iterator > >shuffle__ZN9__gnu_cxx17__normal_iteratorIPPN7testing8TestInfoESt6vectorIS3_SaIS3_EEEppEv_Vector_base >_M_is_leaked_ZN7testing8internal17StreamingListeneraSERKS1__ZNSt6vectorIPN7testing11EnvironmentESaIS2_EE6assignEjRKS2__ZNSbIwSt11char_traitsIwESaIwEE7replaceEjjPKwj_ZN7testing8internal20ShouldRunTestOnShardEiii_ZNK7testing8internal10scoped_ptrISsEptEv_ZNKSbIwSt11char_traitsIwESaIwEE5rfindEPKwj_ZN9__gnu_cxx17__normal_iteratorIPPN7testing8TestCaseESt6vectorIS3_SaIS3_EEEppEioperator-*, std::vector > >__uninit_copyoperator<< reserved_names_Self_ZNK9__gnu_cxx13new_allocatorISsE7addressERKSsThis program contains tests written using Google Test. You can use the following command line flags to control its behavior: Test Selection: @G--gtest_list_tests@D List the names of all tests instead of running them. The name of TEST(Foo, Bar) is "Foo.Bar". @G--gtest_filter=@YPOSTIVE_PATTERNS[@G-@YNEGATIVE_PATTERNS]@D Run only the tests whose name matches one of the positive patterns but none of the negative patterns. '?' matches any single character; '*' matches any substring; ':' separates two patterns. @G--gtest_also_run_disabled_tests@D Run all disabled tests too. Test Execution: @G--gtest_repeat=@Y[COUNT]@D Run the tests repeatedly; use a negative count to repeat forever. @G--gtest_shuffle@D Randomize tests' orders on every iteration. @G--gtest_random_seed=@Y[NUMBER]@D Random number seed to use for shuffling test orders (between 1 and 99999, or 0 to use a seed based on the current time). Test Output: @G--gtest_color=@Y(@Gyes@Y|@Gno@Y|@Gauto@Y)@D Enable/disable colored output. The default is @Gauto@D. -@G-gtest_print_time=0@D Don't print the elapsed time of each test. @G--gtest_output=xml@Y[@G:@YDIRECTORY_PATH@G/@Y|@G:@YFILE_PATH]@D Generate an XML report in the given directory or with the given file name. @YFILE_PATH@D defaults to @Gtest_details.xml@D. @G--gtest_stream_result_to=@YHOST@G:@YPORT@D Stream test results to the given server. Assertion Behavior: @G--gtest_death_test_style=@Y(@Gfast@Y|@Gthreadsafe@Y)@D Set the default death test style. @G--gtest_break_on_failure@D Turn assertion failures into debugger break-points. @G--gtest_throw_on_failure@D Turn assertion failures into C++ exceptions. @G--gtest_catch_exceptions=0@D Do not report exceptions as test failures. Instead, allow them to crash the program or throw a pop-up (on Windows). Except for @G--gtest_list_tests@D, you can alternatively set the corresponding environment variable of a flag (all letters in upper-case). For example, to disable colored text output, you can either specify @G--gtest_color=no@D or set the @GGTEST_COLOR@D environment variable to @Gno@D. For more information, please read the Google Test documentation at @Ghttp://code.google.com/p/googletest/@D. If you find a bug in Google Test (not one in your own code or tests), please report it to @G@D. BoolFromGTestEnv_ZNSt6vectorIPcSaIS0_EE15_M_erase_at_endEPS0__ZNKSbIwSt11char_traitsIwESaIwEE17find_first_not_ofEwjInteger__find_if<__gnu_cxx::__normal_iterator >, __gnu_cxx::__ops::_Iter_pred >strcasecmpst_ctim_ZNSt6vectorIN7testing12TestPropertyESaIS1_EE6assignEjRKS1__ZNSt6vectorIPN7testing8TestCaseESaIS2_EE4dataEvtuple_size >_ZNKSt6vectorIPcSaIS0_EE4backEv_Vector_base >_ZNKSt6vectorIN7testing14TestPartResultESaIS1_EE8capacityEv_M_leak_hardprefix_len_ZNKSs13find_first_ofERKSsj_ZN7testing8internal15FloatingPointLEIfEENS_15AssertionResultEPKcS4_T_S5__ZN7testing4Test5SetupEvGTestLogSeverity_ZN9__gnu_cxx14__alloc_traitsISaIN7testing12TestPropertyEEE17_S_select_on_copyERKS3__ZNSt6vectorIN7testing12TestPropertyESaIS1_EE14_M_fill_insertEN9__gnu_cxx17__normal_iteratorIPS1_S3_EEjRKS1__ZSt9__find_ifIN9__gnu_cxx17__normal_iteratorIPPN7testing8TestCaseESt6vectorIS4_SaIS4_EEEENS0_5__ops10_Iter_predINS2_8internal14TestCaseNameIsEEEET_SF_SF_T0_St26random_access_iterator_tag_vptr.TestCase_ZNK7testing8UnitTest21total_test_case_countEv_ZNKSt9_IdentityIPKcEclERKS1__ZNSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE8_M_eraseEN9__gnu_cxx17__normal_iteratorIPS3_S5_EES9__ZNSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE7reserveEj_ZN9__gnu_cxx17__normal_iteratorIPPN7testing17TestEventListenerESt6vectorIS3_SaIS3_EEEppEv_ZN9__gnu_cxx17__normal_iteratorIPcSsEppEitoupper_vptr.ThreadLocalValueHolderBase_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE12_M_rightmostEv Stack trace: _ZN9__gnu_cxx17__normal_iteratorIPcSsEppEv__normal_iterator, std::allocator > >_ZNK9__gnu_cxx17__normal_iteratorIPiSt6vectorIiSaIiEEEixEi__datCodePointToUtf8_ZNSbIwSt11char_traitsIwESaIwEE4_Rep26_M_set_length_and_sharableEj_ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EE14_M_fill_assignEjRKS2_not_bol_ZNSs3endEv_ZN9__gnu_cxx17__normal_iteratorIPKPN7testing17TestEventListenerESt6vectorIS3_SaIS3_EEEmIEi_ZNKSt6vectorIN7testing14TestPartResultESaIS1_EE8max_sizeEv_ZN7testing8internal12UnitTestImplD0EvIsRootDirectoryFloatingPointLE_ZN7testing8internal6RandomaSERKS1__ZN7testing8internal21ImplicitlyConvertibleIPKvS3_E6HelperEz_ZNKSt6vectorIN7testing12TestPropertyESaIS1_EE14_M_range_checkEj_ZNSbIwSt11char_traitsIwESaIwEE4_Rep15_M_set_sharableEvFlushInfoLog__s1construct_ZNSt3setISsSt4lessISsESaISsEE6insertESt23_Rb_tree_const_iteratorISsERKSsreverse_iterator<__gnu_cxx::__normal_iterator > > >_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE5eraseERKSsHasFailurewcsncpy_ZNKSt6vectorIN7testing12TestPropertyESaIS1_EE3endEv_ZN7testing8internal28ParseGoogleTestFlagsOnlyImplIcEEvPiPPT__ZNK7testing10TestResult6PassedEv_ZN7testing8internal12UnitTestImpl21os_stack_trace_getterEv_S_construct_aux15pthread_mutex_tregex_tmbrtowcRandom~ParameterizedTestCaseInfoBase_ZNSt3setISsSt4lessISsESaISsEE5eraseERKSs_ZNK9__gnu_cxx13new_allocatorIPN7testing17TestEventListenerEE7addressERKS3__ZN7testing8internal12UnitTestImpl14RecordPropertyERKNS_12TestPropertyE__numeric_traits_integerfreeaddrinfo_M_limitoperator<< _ZNSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE4rendEv_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE5eraseESt17_Rb_tree_iteratorIS1_ES9__ZNK7testing8internal8FilePath12CreateFolderEv_ZNK7testing8internal10scoped_ptrINS0_16DeathTestFactoryEE3getEv_ZNSt6vectorISsSaISsEE3endEvkPathSeparator_ZN7testing12TestPropertyD2Evvfprintfiterator_traits, std::allocator >*>~Mutexisxdigitmatched_ZNSbIwSt11char_traitsIwESaIwEE4_Rep10_M_disposeERKS1__ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE10_S_maximumEPSt18_Rb_tree_node_basesi_fd_ZNSt6vectorISsSaISsEE4backEv_S_basefieldStringType__is_move_iterator_ZNSt6vectorIPN7testing8TestInfoESaIS2_EE3endEv__niter_base_ZNSt6vectorIPN7testing8TestCaseESaIS2_EE8_M_eraseEN9__gnu_cxx17__normal_iteratorIPS2_S4_EES8___uninitialized_copy_a_S_scientific_ZNK7testing8internal8FilePath15IsRootDirectoryEv_ZNKSt6vectorIN7testing14TestPartResultESaIS1_EE4rendEv_ZN7testing17TestEventListener11OnTestStartERKNS_8TestInfoE_ZNK7testing10TestResult15GetTestPropertyEi_ZN7testing32ScopedFakeTestPartResultReporterD0Ev_ZNSt6vectorIPN7testing8TestCaseESaIS2_EE6resizeEjS2_is_wide_string_ZNK7testing8internal10scoped_ptrINS0_24InternalRunDeathTestFlagEEdeEv_ZN7testing4TestD0Evwctype_t_ZNKSs5rfindEPKcj_ZNSt6vectorISsSaISsEE14_M_fill_insertEN9__gnu_cxx17__normal_iteratorIPSsS1_EEjRKSs_ZNSt6vectorIiSaIiEE6insertEN9__gnu_cxx17__normal_iteratorIPiS1_EEjRKi_DestroyReinterpretBitsai_canonnameConfigureStreamingOutput_ZN9__gnu_cxx17__normal_iteratorIPPN7testing8TestCaseESt6vectorIS3_SaIS3_EEEppEv_ZN7testing15AssertionResultlsISsEERS0_RKT__ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE12_M_erase_auxESt23_Rb_tree_const_iteratorISsESkipPrefix_ZN9__gnu_cxx17__normal_iteratorIPPcSt6vectorIS1_SaIS1_EEEppEi_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE14_M_upper_boundEPSt13_Rb_tree_nodeIS1_ESA_RKS1__ZNK9__gnu_cxx17__normal_iteratorIPPN7testing8internal29ParameterizedTestCaseInfoBaseESt6vectorIS4_SaIS4_EEEptEv_ZNSt12_Vector_baseIN7testing12TestPropertyESaIS1_EE11_M_allocateEjsaved_sigprof_actionoperator<< low_bits_IteratorR_ZNKSbIwSt11char_traitsIwESaIwEE8_M_limitEjj_ZNKSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE11__rb_verifyEv_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE5eraseESt17_Rb_tree_iteratorISsES7_spawned__ZNSt13_Bit_iteratorppEi__sigchld_clock_ttear_down_tc__Vector_base >_ZNKSt5ctypeIcE13_M_widen_initEv__destroy_ZN7testing8internal12UnitTestImpl19PostFlagParsingInitEvmatchFLAGS_gtest_stack_trace_depth_ZNSt13_Bit_iteratorppEv_ZN7testing17TestEventListener20OnTestIterationStartERKNS_8UnitTestEikDeathTestStyleFlag_ZN7testing8internal18FormatFileLocationEPKci_ZN7testing15AssertionResultlsIA2_cEERS0_RKT__ZNKSt6vectorIPcSaIS0_EE4sizeEvg_injected_test_argvs_ZNKSs4findEcj_M_get_insert_equal_pos_ZNSbIwSt11char_traitsIwESaIwEE12_S_empty_repEv_ZN7testing28FLAGS_gtest_stream_result_toEreverse_iterator<__gnu_cxx::__normal_iterator > > >_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE28_M_get_insert_hint_equal_posESt23_Rb_tree_const_iteratorIS1_ERKS1_PostFlagParsingInit_ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EE7reserveEj_ZNK7testing8internal12UnitTestImpl28internal_run_death_test_flagEv_ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EE8pop_backEv_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE5beginEv__positionqsort_ZNK9__gnu_cxx17__normal_iteratorIPN7testing14TestPartResultESt6vectorIS2_SaIS2_EEEplEi_ZNSbIwSt11char_traitsIwESaIwEE6insertEN9__gnu_cxx17__normal_iteratorIPwS2_EEw_ZNKSs4findERKSsj_ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EE5beginEvkAsIs_ZNK7testing8internal12UnitTestImpl6PassedEv_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE5eraseESt23_Rb_tree_const_iteratorIS1_ES9__ZNSt18_Rb_tree_node_base10_S_maximumEPS__ZNK7testing8UnitTest22failed_test_case_countEv_M_end_of_storage_ZN7testing8internal27PrettyUnitTestResultPrinter22OnEnvironmentsSetUpEndERKNS_8UnitTestE_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE17_M_insert_unique_ESt23_Rb_tree_const_iteratorISsERKSs__exchange_and_add_single__x_copy_ZN9__gnu_cxx14__alloc_traitsISaIN7testing8internal9TraceInfoEEE7destroyERS4_PS3__ZN9__gnu_cxx14__alloc_traitsISaIN7testing12TestPropertyEEE8allocateERS3_j_Alloc_pad__uninitialized_copy_a*, std::basic_string >_ZN7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEE9CreateKeyEvvwscanfexponent_bits_Setwoperator<< _ZNK7testing8TestCase21reportable_test_countEvdeath_test_count__ZNKSt6vectorIN7testing14TestPartResultESaIS1_EE5frontEv_ZNKSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE4rendEv_M_headerinternal_run_death_test_SplitStringfind_last_of~TestEventListener__is_normal_iterator<__gnu_cxx::__normal_iterator > > >WideStringToUtf8_ZNKSt6vectorIPN7testing11EnvironmentESaIS2_EE5emptyEvuninitialized_copy<__gnu_cxx::__normal_iterator*, std::vector > >, std::basic_string*>__oldoperator- >_ZNSt6vectorIPN7testing8TestCaseESaIS2_EE5frontEvneedle_expr_ZN7testing8internal12UnitTestImpl18ConfigureXmlOutputEvunit_test__uninitialized_move_if_noexcept_a >reverse_iterator<__gnu_cxx::__normal_iterator > > >~set_ZN7testing22EmptyTestEventListener24OnEnvironmentsSetUpStartERKNS_8UnitTestE_Rb_tree_const_iteratorfabs_ZN7testing8internal14CapturedStream14ReadEntireFileEP8_IO_FILE_ZNSt3setISsSt4lessISsESaISsEE4swapERS3___vtt_parm_Destroy_M_ibeginactual_expression_ZNSt6vectorIPN7testing11EnvironmentESaIS2_EE5clearEv_ZNSt6vectorISsSaISsEE6assignEjRKSsGetRandomSeedFromFlag_ZNK9__gnu_cxx13new_allocatorIPN7testing8TestCaseEE7addressERS3__ZN7testing8internal17AppendUserMessageERKSsRKNS_7MessageEoperator!=*, std::vector > >__enable_if__throw_out_of_range_fmt_ZNKSt6vectorIPN7testing17TestEventListenerESaIS2_EE4sizeEvGetTestPartResultReporterForCurrentThread__copy_move_backward_a_ZN9__gnu_cxx17__normal_iteratorIPKSsSt6vectorISsSaISsEEEmIEi_ZNKSbIwSt11char_traitsIwESaIwEE13find_first_ofERKS2_j_ZNK7testing8UnitTest21reportable_test_countEvF_OWNER_PGRP_ZNSt6vectorISsSaISsEE5eraseEN9__gnu_cxx17__normal_iteratorIPSsS1_EES5__ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS2_S4_EERKS2__ZN7testing14IsNotSubstringEPKcS1_S1_S1___off64_t_Iter_base<__gnu_cxx::__normal_iterator > >, false>__copy_move_a_ZNKSt6vectorIPN7testing8TestCaseESaIS2_EE12_M_check_lenEjPKc__gnu_cxx__typeEqFailureexpected_to_be_substringGetCapturedStringExitedUnsuccessfully_ZNK7testing8UnitTest20original_working_dirEvDeleteThreadLocalValue_ZN7testing8internal24HasNewFatalFailureHelperC2Evoperator+, std::allocator >_ZN7testing8internal38DefaultPerThreadTestPartResultReporterC2EPNS0_12UnitTestImplEoperator==_vptr.TestFactoryBase_M_current_ZNSs7replaceEjjjc_ZNSt6vectorIN7testing14TestPartResultESaIS1_EE5clearEv_Destroy_ZNKSs13find_first_ofEPKcjj_ZNSt6vectorIPN7testing8TestInfoESaIS2_EE8_M_eraseEN9__gnu_cxx17__normal_iteratorIPS2_S4_EES8__ZNK7testing8internal13FloatingPointIdE12AlmostEqualsERKS2___copy_move_aoperator<< _ZNSt6vectorIiSaIiEE4rendEvtest_case_infos__ZNK9__gnu_cxx17__normal_iteratorIPN7testing14TestPartResultESt6vectorIS2_SaIS2_EEE4baseEv_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE11_M_put_nodeEPSt13_Rb_tree_nodeIS1_Earray___copy_move_backward_a2_sigsys_ZN9__gnu_cxx13new_allocatorIiE8allocateEjPKvreverse_iterator<__gnu_cxx::__normal_iterator > > >_S_create_Arg1_Arg2_ZNSt6vectorIPcSaIS0_EE6rbeginEv_ZNK7testing8internal13FloatingPointIfE12AlmostEqualsERKS2__Vector_base, std::allocator >, std::allocator, std::allocator > > >_ZNKSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE4rendEvattributesstack_trace_depth_MSG_FASTOPEN_Destroy_aux_ZN7testing8internal17StreamingListener10FormatBoolEbdefault__ZN7testing14KilledBySignalC2EiFullMatchreverse_iterator<__gnu_cxx::__normal_iterator > > >g_captured_stderrSetGlobalTestPartResultReporterpair, std::allocator > >, bool>PrintAsCharLiteralToabs_errorRegisterParameterizedTests_ZNKSt6vectorIPcSaIS0_EEixEjGetTestTypeId/home/user/projects/ascgit/ascgit003.dlt-daemon/build/gtest-1.7.0__copy_move_a2 >, __gnu_cxx::__normal_iterator > >ValidateTestPropertyargs__M_insert_uniqueoperator<< UInt32RemoveExtensionkStreamResultToFlagkCurrentDirectoryStringname_template_ZNSt6vectorIiSaIiEE2atEj_ZN7testing8internal17StreamingListener18OnTestIterationEndERKNS_8UnitTestEiiterator_traits_ZNK9__gnu_cxx17__normal_iteratorIPiSt6vectorIiSaIiEEEdeEv_ZN7testing8internal13HasOneFailureEPKcS2_S2_RKNS_19TestPartResultArrayENS_14TestPartResult4TypeERKSs_ZNKSt6vectorISsSaISsEE12_M_check_lenEjPKcbool_constantkShuffleFlag_ZNKSt18_Bit_iterator_baseltERKS___uninit_copyCharType_ZNK7testing8TestCase30reportable_disabled_test_countEv_ZN9__gnu_cxx14__alloc_traitsISaISsEE7destroyERS1_PSsungetwcoperator- >__copy_move_achild_argcurrency_symbol_ZNK9__gnu_cxx17__normal_iteratorIPN7testing14TestPartResultESt6vectorIS2_SaIS2_EEEptEvgettimeofday_ZNKSt3setIPKcSt4lessIS1_ESaIS1_EE4findERKS1_ShowWideCString__wchb_ZNSt12_Vector_baseIPN7testing17TestEventListenerESaIS2_EE11_M_allocateEj_ZNSbIwSt11char_traitsIwESaIwEE9_M_assignEPwjwoperator!= >_ZN7testing35FLAGS_gtest_also_run_disabled_testsEIsSubstringPred >_ZNKSt6vectorIiSaIiEE4dataEv_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE7_M_copyEPKSt13_Rb_tree_nodeISsEPS7__S_value~TestPropertyKeyIs_ZN9__gnu_cxx13new_allocatorISt13_Rb_tree_nodeISsEE9constructEPS2_RKS2___exchange_and_addbasic_string__normal_iterator, std::allocator >*, std::vector, std::allocator >, std::allocator, std::allocator > > > >_ZNSt6vectorIPcSaIS0_EE5beginEv_ZN9__gnu_cxx17__normal_iteratorIPSsSt6vectorISsSaISsEEEmIEinew_allocator_ZNK9__gnu_cxx13new_allocatorIiE7addressERi_Iter_base_M_range_initializefirst_is_TEST_ZN9__gnu_cxx17__normal_iteratorIPPN7testing11EnvironmentESt6vectorIS3_SaIS3_EEEppEi_M_checkglobal_test_part_result_reporter_mutex_AddTestInfo_ZNSt3setISsSt4lessISsESaISsEE5eraseESt23_Rb_tree_const_iteratorISsES5___size_ZNSt6vectorIPcSaIS0_EE5eraseEN9__gnu_cxx17__normal_iteratorIPS0_S2_EE_ZNSt10_Iter_baseIPN7testing14TestPartResultELb0EE7_S_baseES2__ZNK7testing10TestResult18HasNonfatalFailureEv_ZN9__gnu_cxx17__normal_iteratorIPKPN7testing8TestInfoESt6vectorIS3_SaIS3_EEEmmEi_ZNK9__gnu_cxx17__normal_iteratorIPPN7testing8TestInfoESt6vectorIS3_SaIS3_EEE4baseEv_ZNKSt18_Bit_iterator_basegeERKS__ZNKSs5emptyEv__builtin_unwind_resume_ZN7testing31FLAGS_gtest_death_test_use_forkEunary_function_ZNSt6vectorIPN7testing11EnvironmentESaIS2_EE6rbeginEv_ZNKSt6vectorIN7testing8internal9TraceInfoESaIS2_EE4backEv_ZNK7testing8TestCase10type_paramEva_current_test_infoAssumeRole_ZNSbIwSt11char_traitsIwESaIwEE13_S_copy_charsEPwN9__gnu_cxx17__normal_iteratorIPKwS2_EES8__ZNSt6vectorIN7testing12TestPropertyESaIS1_EE3endEv_ZNKSt3setIPKcSt4lessIS1_ESaIS1_EE11equal_rangeERKS1__ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE5eraseEPKSsS7___ostream_type__insert_left_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE7_S_leftEPSt18_Rb_tree_node_base_ZNKSt6vectorISsSaISsEE4dataEv_ZNSt6vectorIPN7testing8TestCaseESaIS2_EE3endEv_M_check_length_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE21_M_insert_equal_lowerERKS1__ZNKSt23_Rb_tree_const_iteratorISsEptEvdeath_test_use_fork__S_app_ZNSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE18_M_fill_initializeEjRKS3__ZNKSs4findEPKcjj_ZN7testing22EmptyTestEventListenerD2Ev_ZN9__gnu_cxx14__alloc_traitsISaIN7testing14TestPartResultEEE8allocateERS3_jMSG_OOB_ZN7testing8internal12UnitTestImpl9listenersEv__syscall_slong_t__alloc_traits, std::allocator > > >__alloc_traits >_ZN7testing8internal15UnitTestOptions17FilterMatchesTestERKSsS3__Identity_ZNKSt6vectorIN7testing12TestPropertyESaIS1_EE8capacityEvstart_timestampappendIsDirectoryTestDisabled_ZNKSt6vectorIPN7testing17TestEventListenerESaIS2_EE6rbeginEv_ZNK7testing8internal12AssertHelperaSERKNS_7MessageEsetlocale_ZNK7testing8UnitTest17failed_test_countEv_ZN7testing8internal17StreamingListenerD0Ev_ZNSt6vectorIPN7testing8TestInfoESaIS2_EE6assignEjRKS2_host_ZNKSt16reverse_iteratorIN9__gnu_cxx17__normal_iteratorIPPN7testing11EnvironmentESt6vectorIS4_SaIS4_EEEEEmiEi_Setprecision_ZN7testing8internal38DefaultPerThreadTestPartResultReporterD2Ev__copy_move_b_ZNKSt3setISsSt4lessISsESaISsEE6rbeginEv_IO_write_ptr_ZNSs6insertEN9__gnu_cxx17__normal_iteratorIPcSsEEcGTEST_WARNING_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE8_S_rightEPSt18_Rb_tree_node_base_ZN7testing8internal2RE12PartialMatchEPKcRKS1__S_in_ZN7testing17TestEventListener18OnTestIterationEndERKNS_8UnitTestEinew_allocator_ZNKSt6vectorIN7testing12TestPropertyESaIS1_EE8max_sizeEvwcscasecmp_ZN7testing12TestProperty8SetValueERKSs__socket_type_ZNSt9basic_iosIcSt11char_traitsIcEE4initEPSt15basic_streambufIcS1_E_ZN7testing8internal13FloatingPointIdE3MaxEvminpair, bool>SumOverTestCaseList_Vector_base >_ZNSt12_Vector_baseIPcSaIS0_EE12_Vector_impl12_M_swap_dataERS3__ZNK9__gnu_cxx17__normal_iteratorIPKcSsEptEv__ops_ZNK9__gnu_cxx13new_allocatorIPN7testing8TestCaseEE8max_sizeEvpair_ZN7testing8internal17StreamingListener9OnTestEndERKNS_8TestInfoE_ZN7testing8internal19FormatForComparisonIxxE6FormatERKx_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE11equal_rangeERKS1__ZN9__gnu_cxx14__alloc_traitsISaIN7testing8internal9TraceInfoEEE10deallocateERS4_PS3_j_Tp_alloc_typetest_detail.xml_Constructfull_regex_len_ZNSt6vectorIPN7testing8TestInfoESaIS2_EE5clearEv_ZNKSt3setISsSt4lessISsESaISsEE11lower_boundERKSsSOCK_RDM_ZNSt12_Vector_baseIiSaIiEE11_M_allocateEjCloneCString_ZNKSt3setIPKcSt4lessIS1_ESaIS1_EE4rendEv_ZNKSt6vectorIPcSaIS0_EE5beginEv_ZNKSt9basic_iosIcSt11char_traitsIcEE5widenEcoperator!=, std::allocator >_ZNK9__gnu_cxx17__normal_iteratorIPKPN7testing8TestCaseESt6vectorIS3_SaIS3_EEEplEiWrite_M_fill_initializekDefaultDeathTestStyle__normal_iterator > >waitpidtimezonetest_property_count_ZNK7testing10TestResult19test_property_countEv_ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EEaSERKS4__Vector_base >reverse_iterator<__gnu_cxx::__normal_iterator > > >an_outcome_S_ate_ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EE14_M_fill_assignEjRKS2_regexecmatches_filter__ZNKSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE11equal_rangeERKS1_expectedoutcome__ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EEaSERKS7__ZNKSt6vectorISsSaISsEE3endEv_ZNKSs7compareEjjRKSsjj_ZN9__gnu_cxx13new_allocatorIiE9constructEPiRKi_ZNSt18_Bit_iterator_base12_M_bump_downEv_ZNSbIwSt11char_traitsIwESaIwEE14_M_replace_auxEjjjw_ZNKSt3setISsSt4lessISsESaISsEE5emptyEv_ZNSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE6assignEjRKS3__ZN7testing8internal23ScopedPrematureExitFileaSERKS1__Destroy_ZN7testing8internal6String13CStringEqualsEPKcS3__Rb_tree_iterator, std::allocator > >_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE21_M_get_Node_allocatorEvlast_in_range_ZN9__gnu_cxx17__normal_iteratorIPPN7testing8TestInfoESt6vectorIS3_SaIS3_EEEmmEi_ZNKSt6vectorIN7testing8internal9TraceInfoESaIS2_EE4sizeEv_ZNSt6vectorIPcSaIS0_EE2atEj__find_if<__gnu_cxx::__normal_iterator*, std::vector > >, __gnu_cxx::__ops::_Iter_equals_val > >_ZNSsaSEcUniversalPrinter, std::allocator > >_ZN9__gnu_cxx17__normal_iteratorIPPN7testing8TestInfoESt6vectorIS3_SaIS3_EEEmmEv_ZNSs7replaceEN9__gnu_cxx17__normal_iteratorIPcSsEES2_jc_ZN7testing8internal12UnitTestImpl12environmentsEv_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE4findERKS1_kSignBitMaska_value__uninit_copy*>long long unsigned int_ZN7testing8TestInfo15ClearTestResultEPS0__ZNSs6appendERKSs_ZN7testing8internal6String12FormatHexIntEi_vptr.TestEventListenerCaseInsensitiveCStringEquals_ZNK9__gnu_cxx13new_allocatorIPN7testing8TestCaseEE7addressERKS3_pair, std::allocator > >, bool>kDeathTestUseFork_ZNSbIwSt11char_traitsIwESaIwEEpLEwparameterized_test_registry__ZNKSbIwSt11char_traitsIwESaIwEE4rendEvFormatTestCaseCount_ZNKSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE5frontEvFLAGS_gtest_stream_result_to_ZNKSt6vectorIPN7testing17TestEventListenerESaIS2_EE8capacityEv_ZN9__gnu_cxx13new_allocatorIN7testing14TestPartResultEE9constructEPS2_RKS2_MakeAndRegisterTestInfounsigned char_ZNK7testing8internal24InternalRunDeathTestFlag5indexEv_M_grab_ZNKSt23_Rb_tree_const_iteratorIPKcEdeEv_ZN7testing14IsNotSubstringEPKcS1_PKwS3_operator<< ClearResultFLAGS_gtest_death_test_style_ZNKSt6vectorIPN7testing8TestCaseESaIS2_EEixEj_ZN9__gnu_cxx17__normal_iteratorIPPN7testing17TestEventListenerESt6vectorIS3_SaIS3_EEEmmEi_ZN7testing8internal13ParseBoolFlagEPKcS2_Pb_ZN7testing8internal14ParseFlagValueEPKcS2_bUnitTestOptions_ZN9__gnu_cxx17__normal_iteratorIPPN7testing17TestEventListenerESt6vectorIS3_SaIS3_EEEmmEv_ZN9__gnu_cxx17__normal_iteratorIPcSsEmmEi__gnu_debug_ZN9__gnu_cxx17__normal_iteratorIPcSsEmmEvSOCK_DGRAM_ZNSt6vectorIN7testing14TestPartResultESaIS1_EE7reserveEj__is_char__outTypeIdHelper_ZNK7testing14TestPartResult9file_nameEv_ZN7testing8internal6String12CloneCStringEPKc_ZNKSt6vectorIPN7testing17TestEventListenerESaIS2_EE8max_sizeEv_ZNKSt6vectorIPN7testing11EnvironmentESaIS2_EE4backEv_ZN9__gnu_cxx13new_allocatorIPN7testing8TestCaseEE9constructEPS3_RKS3_test_info_list_fwide_ZN7testing8internal17StreamingListener5StartEv__iterator_category<__gnu_cxx::__normal_iterator > >_ZN7testing22EmptyTestEventListener18OnTestProgramStartERKNS_8UnitTestE_ZNKSt6vectorIPN7testing8TestCaseESaIS2_EE5beginEvoutput_file_for_each<__gnu_cxx::__normal_iterator >, void (*)(testing::TestEventListener*)>F_OWNER_GID_ZNKSt6vectorIiSaIiEEixEj_ZNK7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEE7pointerEv_ZN7testing8internal27OsStackTraceGetterInterface16UponLeavingGTestEv_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE5clearEv_ZNSs6insertEjPKcj_ZN7testing8internal27PrettyUnitTestResultPrinter9OnTestEndERKNS_8TestInfoE_ZNK7testing8UnitTest15start_timestampEv_ZNKSt12_Vector_baseIN7testing8internal9TraceInfoESaIS2_EE19_M_get_Tp_allocatorEvkChunkSize_ZNSt6vectorIPcSaIS0_EE3endEv~GoogleTestFailureExceptionHandleSehExceptionsInMethodIfSupportedSetDefaultResultPrinterwcsspn~_Iter_pred_ZNSt6vectorISsSaISsEE6resizeEjSsoperator<< _ZNKSt6vectorIPN7testing17TestEventListenerESaIS2_EE5frontEvGetAnsiColorCode__copy_move_backward_a2__alloc_traits, std::allocator > > > >_ZNSt6vectorIPN7testing11EnvironmentESaIS2_EE18_M_fill_initializeEjRKS2__ZNSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE5clearEv_ZN7testing8internal6String17WideCStringEqualsEPKwS3_raw_seed_ZNK7testing8internal12UnitTestImpl15start_timestampEvmax_length_ZNK7testing14TestPartResult6passedEv_ZNK9__gnu_cxx13new_allocatorIN7testing8internal9TraceInfoEE8max_sizeEvFOpen_sifields_ZN7testing17TestEventListener27OnEnvironmentsTearDownStartERKNS_8UnitTestEInfinitycan_be_nullGetTestProperty__copy_move_backward_a_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE13_M_clone_nodeEPKSt13_Rb_tree_nodeIS1_E_ZNKSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE4dataEv_Destroy_ZN9__gnu_cxx14__alloc_traitsISaISt13_Rb_tree_nodeISsEEE7destroyERS3_PS2_HandleSehExceptionsInMethodIfSupported_ZNKSt3setIPKcSt4lessIS1_ESaIS1_EE5countERKS1_TEST_name__xstat_ZN9__gnu_cxx17__normal_iteratorIPN7testing14TestPartResultESt6vectorIS2_SaIS2_EEEppEi_ZN7testing8internal24XmlUnitTestResultPrinter18OutputXmlAttributeEPSoRKSsS4_S4__ZNSs12_M_leak_hardEv_M_insert_unique__ZN9__gnu_cxx17__normal_iteratorIPN7testing14TestPartResultESt6vectorIS2_SaIS2_EEEppEviterator_traits_ZN9__gnu_cxx13new_allocatorIN7testing12TestPropertyEE9constructEPS2_RKS2__ZNSsixEj_ZN7testing8internal6String10FormatByteEh_ZNSt6vectorIN7testing12TestPropertyESaIS1_EEaSERKS3__ZN9__gnu_cxx13new_allocatorIPN7testing8TestInfoEE8allocateEjPKvSetTestPartResultReporterForCurrentThreadOnEnvironmentsSetUpEnd_ZNSspLERKSsAddArguments >_ZN9__gnu_cxx17__normal_iteratorIPPN7testing8TestCaseESt6vectorIS3_SaIS3_EEEmmEvfull_regex_srand_Destroy__delta_ZN9__gnu_cxx17__normal_iteratorIPPcSt6vectorIS1_SaIS1_EEEmmEiset_catch_exceptionspart_ZN9__gnu_cxx14__alloc_traitsISaIPcEE8max_sizeERKS2_TypedTestCasePState_ZN7testing8internal14GTestMutexLockaSERKS1__ZN9__gnu_cxx17__normal_iteratorIPPcSt6vectorIS1_SaIS1_EEEmmEv_ZN7testing8internal9DeathTest24last_death_test_message_ECreateCodePointFromUtf16SurrogatePair_ZNSt13_Bit_iteratormmEiConfigureXmlOutputalso_run_disabled_tests__ZNSt13_Bit_iteratormmEv_ZNSt6vectorIPN7testing8TestCaseESaIS2_EE2atEj_ZNSt6vectorIPN7testing8TestCaseESaIS2_EEixEj_ZNKSt9basic_iosIcSt11char_traitsIcEE4fillEvother_ZNKSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE4findERKSs_ZNK7testing8internal13DeathTestImpl7spawnedEvOnTestProgramStart_Unwind_Resumeai_flagskDeathTestThrew_ZNSbIwSt11char_traitsIwESaIwEE7_M_copyEPwPKwj_ZN7testing11EnvironmentD0EvTearDown_Rb_tree_node_ZNSs4_Rep10_M_refdataEv__cxxabiv1_ZN7testing8internal17Int32FromEnvOrDieEPKci__pos_ZNSt6vectorIN7testing14TestPartResultESaIS1_EE3endEv_ZNK9__gnu_cxx17__normal_iteratorIPN7testing14TestPartResultESt6vectorIS2_SaIS2_EEEmiEi_ZNSt6vectorIPcSaIS0_EE4backEvwcsstrhost_name__ZNKSt6vectorIPN7testing11EnvironmentESaIS2_EE4sizeEvkReservedTestSuitesAttributes_ZN7testing7MessagelsERKSbIwSt11char_traitsIwESaIwEE_ZN7testing8internal16ForkingDeathTest4WaitEv_ZNKSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE5emptyEvClearAdHocTestResultst_size_ZN7testing8internal24XmlUnitTestResultPrinter18OnTestIterationEndERKNS_8UnitTestEi_ZNKSt6vectorIPN7testing8TestCaseESaIS2_EE4backEv_ZNK9__gnu_cxx13new_allocatorISt13_Rb_tree_nodeISsEE8max_sizeEv_ZNSt6vectorISsSaISsEE2atEj_ZNKSt13_Rb_tree_nodeIPKcE9_M_valptrEvFLAGS_gtest_death_test_use_fork_ZN7testing8internal12UnitTestImpl18death_test_factoryEv_Rb_tree_impl, std::allocator > >, false>_ZN7testing8UnitTest18GetMutableTestCaseEi_ZNKSs5c_strEvreverse_iterator<__gnu_cxx::__normal_iterator > > >exit_code_ZNSt12_Vector_baseIN7testing14TestPartResultESaIS1_EE11_M_allocateEjtest_properties__ZN7testing8TestCaseD0Ev_ZNKSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE7_M_rootEvfraction_bits_ZN7testing8internal10scoped_ptrINS0_17StreamingListener20AbstractSocketWriterEE5resetEPS3_testing_Result_ZN9__gnu_cxx17__normal_iteratorIPPN7testing8TestInfoESt6vectorIS3_SaIS3_EEEpLEitm_mday_ZNK9__gnu_cxx17__normal_iteratorIPN7testing12TestPropertyESt6vectorIS2_SaIS2_EEEdeEv__niter_baseAppend_ZNKSt12_Vector_baseIPcSaIS0_EE19_M_get_Tp_allocatorEv_Iter_predsi_addr_ZN9__gnu_cxx13new_allocatorIwE9constructEPwRKw_ZN7testing8internal2RE12PartialMatchERKSsRKS1_RunAllTests__miter_base_ZNKSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE3endEvGetTestCase_M_swap_data_ZNSt10_Iter_baseIPPN7testing11EnvironmentELb0EE7_S_baseES3_~basic_iostream_M_erase_at_enditerator_traits_ZNK9__gnu_cxx13new_allocatorIPcE7addressERS1__ZNK7testing8internal8FilePath11IsDirectoryEv_ZNKSt4lessISsEclERKSsS2_copy<__gnu_cxx::__normal_iterator >, __gnu_cxx::__normal_iterator > >MSG_NOSIGNALkOutputFlag_ZN7testing7MessagelsEPFRSoS1_E_ZNSt6vectorIN7testing14TestPartResultESaIS1_EE6assignEjRKS1_ad_hoc_test_result_ZNSt3setISsSt4lessISsESaISsEE5clearEvsingular_form_Iter_base_ZN7testing31TestPartResultReporterInterface20ReportTestPartResultERKNS_14TestPartResultEoperator<< _ZN9__gnu_cxx17__normal_iteratorIPPN7testing17TestEventListenerESt6vectorIS3_SaIS3_EEEpLEi__are_samebinary_function__resoperator<< kTestTotalShardsiterator_traits_ZN9__gnu_cxx17__normal_iteratorIPcSsEpLEibasic_streambuf >_ZNSt6vectorISsSaISsEE18_M_fill_initializeEjRKSs_call_addroriginal_working_dir_ZN7testing18TestEventListeners23SuppressEventForwardingEv_ZNSbIwSt11char_traitsIwESaIwEE9push_backEw_ZNKSs7compareERKSsExitSummary_ZNK9__gnu_cxx17__normal_iteratorIPKN7testing8internal9TraceInfoESt6vectorIS3_SaIS3_EEE4baseEvtimeval_ZNKSt6vectorIPN7testing8TestCaseESaIS2_EE4sizeEv_ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EEixEj_ZNSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE9push_backERKS3___normal_iterator > >~DeathTest_ZNSbIwSt11char_traitsIwESaIwEE6resizeEjwvector, std::allocator >, std::allocator, std::allocator > > >fopen_ZNSbIwSt11char_traitsIwESaIwEEaSEPKw_ZNSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE4dataEvdifference_typerebind_ZNSo5flushEvsetprecision_M_value_field_ZN9__gnu_cxx14__alloc_traitsISaIPcEE10deallocateERS2_PS1_j_S_badbit~OsStackTraceGetterInterfacecaller_frame__ZNSs7_M_dataEPcwcslenline_endtype_param__ZNSbIwSt11char_traitsIwESaIwEE10_S_compareEjj_ZNK7testing8internal12UnitTestImpl17failed_test_countEvenvironSOCK_CLOEXEClisteners_kInternalRunDeathTestFlag5div_tGetGlobalTestPartResultReporterwcstoull_ZN7testing8internal16ForkingDeathTest13set_child_pidEi_ZN7testing8internal13FloatingPointIfE24SignAndMagnitudeToBiasedERKj_ZN7testing8internal14StackGrowsDownEv_ZSt9__find_ifIN9__gnu_cxx17__normal_iteratorIPKSsSt6vectorISsSaISsEEEENS0_5__ops16_Iter_equals_valIS2_EEET_SB_SB_T0_St26random_access_iterator_tag_ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EE6resizeEjS2_Normalizetest_propertywrite_fd_reverse_iterator, std::allocator > > >_ZNKSt6vectorIPN7testing8TestInfoESaIS2_EE12_M_check_lenEjPKcCaptureStream_S_showposGTEST_TOTAL_SHARDS_ZN7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEE3setERKS5_predicate_ZNK9__gnu_cxx17__normal_iteratorIPKPN7testing11EnvironmentESt6vectorIS3_SaIS3_EEEdeEvpair, std::allocator > >, std::_Rb_tree_iterator, std::allocator > > >_ZNSs13_S_copy_charsEPcN9__gnu_cxx17__normal_iteratorIS_SsEES2__ZNKSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE5beginEv_ZNKSbIwSt11char_traitsIwESaIwEE7compareEPKw_ZNSbIwSt11char_traitsIwESaIwEE7replaceEjjPKwDelete_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE8_S_valueEPKSt18_Rb_tree_node_base_ZN7testing8internal30GetBoolAssertionFailureMessageERKNS_15AssertionResultEPKcS5_S5_~_Alloc_hider_M_create_node_ZN9__gnu_cxx17__normal_iteratorIPPN7testing8TestCaseESt6vectorIS3_SaIS3_EEEpLEi_ZNKSt6vectorIN7testing8internal9TraceInfoESaIS2_EE5frontEv_ZN7testing8UnitTest27parameterized_test_registryEv_ZNSbIwSt11char_traitsIwESaIwEE5eraseEjj_ZN9__gnu_cxx17__normal_iteratorIPPcSt6vectorIS1_SaIS1_EEEpLEiBiggestConvertible_ZNKSt6vectorIN7testing14TestPartResultESaIS1_EE4dataEv_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE3endEvMSG_TRYHARD_ZN7testing8internal18OsStackTraceGetter17CurrentStackTraceEii_IO_buf_basematches_filter_ZNSt13_Bit_iteratorpLEi__FILE__pthread_internal_slist~InternalRunDeathTestFlag_ZNKSt18_Bit_iterator_baseneERKS__ZNK9__gnu_cxx17__normal_iteratorIPN7testing12TestPropertyESt6vectorIS2_SaIS2_EEEixEifilename__ZNSt18_Bit_iterator_base10_M_bump_upEv_ZNSbIwSt11char_traitsIwESaIwEE5clearEv_S_endTestBody_ZNKSt6vectorIN7testing12TestPropertyESaIS1_EE4backEv_ZNK9__gnu_cxx17__normal_iteratorIPKSsSt6vectorISsSaISsEEEdeEvget_allocator_ZNKSt6vectorIN7testing14TestPartResultESaIS1_EE12_M_check_lenEjPKc_ZNSt14_Bit_reference4flipEv_ZN9__gnu_cxx13new_allocatorIPN7testing17TestEventListenerEE8allocateEjPKvcaptured_stream_ZNK9__gnu_cxx17__normal_iteratorIPKPN7testing11EnvironmentESt6vectorIS3_SaIS3_EEEixEikUnknownFile_ZNKSt12_Vector_baseISsSaISsEE19_M_get_Tp_allocatorEv_ZNSt6vectorIPcSaIS0_EEaSERKS2_test_indices_operator!=<__gnu_cxx::__normal_iterator > >_ZNK9__gnu_cxx13new_allocatorISsE7addressERSs_ZN7testing8internal17StreamingListener16OnTestPartResultERKNS_14TestPartResultE_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE16_M_insert_uniqueERKS1__ZN9__gnu_cxx17__normal_iteratorIPPN7testing11EnvironmentESt6vectorIS3_SaIS3_EEEmmEikStdErrFileno_ZN7testing8internal13DeathTestImpl26ReadAndInterpretStatusByteEv~DefaultDeathTestFactory_ZN9__gnu_cxx17__normal_iteratorIPPN7testing11EnvironmentESt6vectorIS3_SaIS3_EEEmmEv_ZNKSt13_Rb_tree_nodeISsE9_M_valptrEv_ZN9__gnu_cxx13new_allocatorIPN7testing8internal29ParameterizedTestCaseInfoBaseEE7destroyEPS4_SuppressTestEventsIfInSubprocessAddArgument_ZN9__gnu_cxx17__normal_iteratorIPN7testing12TestPropertyESt6vectorIS2_SaIS2_EEEppEv_M_initializefastmap_accurate_ZNSbIwSt11char_traitsIwESaIwEE7_M_leakEvreverse_iterator<__gnu_cxx::__normal_iterator > > >_ZNSs7replaceEjjPKcjkBreakOnFailureFlag__uninitialized_copy_a_ZN7testing8internal20SingleFailureCheckerC2EPKNS_19TestPartResultArrayENS_14TestPartResult4TypeERKSsword_list_ZN7testing8internal12UnitTestImpl41SetTestPartResultReporterForCurrentThreadEPNS_31TestPartResultReporterInterfaceEtm_isdst_ZNK9__gnu_cxx13new_allocatorISt13_Rb_tree_nodeIPKcEE8max_sizeEvint_n_sign_posn_ZNSt6vectorIPN7testing8TestInfoESaIS2_EE9push_backERKS2_operator!= >HasGoogleTestFlagPrefix_ZNKSt6vectorIPcSaIS0_EE2atEj_ZNKSbIwSt11char_traitsIwESaIwEE9_M_ibeginEv_ZNK7testing8internal10scoped_ptrISt18basic_stringstreamIcSt11char_traitsIcESaIcEEE3getEv_ZN7testing8internal16InDeathTestChildEv_ZNSt6vectorIN7testing12TestPropertyESaIS1_EE9push_backERKS1_TypeParam_ZNK9__gnu_cxx17__normal_iteratorIPKSsSt6vectorISsSaISsEEEixEiegptr_ZNKSt9type_infoeqERKS__ZNSt6vectorIPN7testing8TestCaseESaIS2_EE8_M_eraseEN9__gnu_cxx17__normal_iteratorIPS2_S4_EE__intptr_tClearTestPartResultsoperator==<__gnu_cxx::__normal_iterator > >CharFormatvfwprintf_ZN7testing17TestEventListener16OnTestPartResultERKNS_14TestPartResultE_ZNK7testing8UnitTest11GetTestCaseEi_ZN7testing8internal7g_argvsE_ZNSt14_Bit_referenceaSERKS_EscapeXmlText_ZNSbIwSt11char_traitsIwESaIwEE6insertEjjw_ZNKSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE11lower_boundERKSs_ZNKSt5ctypeIcE8do_widenEc__normal_iterator > >_IO_read_base_ZNSt6vectorIN7testing14TestPartResultESaIS1_EE4rendEv__find_if<__gnu_cxx::__normal_iterator >, __gnu_cxx::__ops::_Iter_pred >_ZNKSt16reverse_iteratorIN9__gnu_cxx17__normal_iteratorIPPN7testing11EnvironmentESt6vectorIS4_SaIS4_EEEEEptEv_ZNSbIwSt11char_traitsIwESaIwEE4swapERS2__ZNKSt6vectorIPN7testing8TestInfoESaIS2_EE4rendEv_ZNKSt6vectorIiSaIiEE5emptyEvkThrowOnFailureFlag__alloc_ZNSt11char_traitsIcE2ltERKcS2__ZNK7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE3getEvIsSubstringPred_M_insert_ZNK7testing8TestInfo13is_reportableEv_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE4rendEvsockaddr_ZN7testing8DoubleLEEPKcS1_dd__debug_ZN7testing8internal27PrettyUnitTestResultPrinter18OnTestProgramStartERKNS_8UnitTestE_ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EE4backEvfull_name_Swallow_assignwcstod_ZNK7testing14TestPartResult7messageEvreset_ZNK9__gnu_cxx13new_allocatorIPN7testing11EnvironmentEE8max_sizeEv_ZNSt6vectorIiSaIiEE4dataEv_ZNK9__gnu_cxx13new_allocatorIN7testing8internal9TraceInfoEE7addressERKS3___addressofuninitialized_copy_ZNKSt15basic_stringbufIcSt11char_traitsIcESaIcEE3strEv_ZN7testing8internal15UnitTestOptions13MatchesFilterERKSsPKcreg_syntax_t_ZNSt9basic_iosIcSt11char_traitsIcEE8setstateESt12_Ios_Iostate_ZNK7testing8internal8FilePath15RemoveExtensionEPKc_vptr.Test_ZN7testing8internal13FloatingPointIfE3MaxEvwmemcmp_ZNSbIwSt11char_traitsIwESaIwEE7replaceEN9__gnu_cxx17__normal_iteratorIPwS2_EES6_S5_S5_value_type_ZNSs15_M_replace_safeEjjPKcjsuffix_Const_Link_type_ZNSt3setIPKcSt4lessIS1_ESaIS1_EE5eraseERKS1_this_test_info_ZN7testing8internal13ExecDeathTest32GetArgvsForDeathTestChildProcessEvconstructInitGoogleTestImpl_ZNK9__gnu_cxx17__normal_iteratorIPPN7testing11EnvironmentESt6vectorIS3_SaIS3_EEEmiEi_ZN9__gnu_cxx13new_allocatorISt13_Rb_tree_nodeISsEE10deallocateEPS2_j_ZNSt6vectorIPN7testing8TestInfoESaIS2_EE8_M_eraseEN9__gnu_cxx17__normal_iteratorIPS2_S4_EEStreamableToStringhas_owner_operator!=_Iter_base__is_move_iterator_ZNKSt6vectorIN7testing12TestPropertyESaIS1_EE4sizeEv__cxa_rethrow_ZN9__gnu_cxx14__alloc_traitsISaIPN7testing8TestInfoEEE7destroyERS4_PS3__ZNSt6vectorIN7testing14TestPartResultESaIS1_EEixEjsocket_ZN9__gnu_cxx17__normal_iteratorIPPN7testing8TestCaseESt6vectorIS3_SaIS3_EEEmmEi_ZNSt6vectorIPN7testing8TestCaseESaIS2_EE18_M_fill_initializeEjRKS2__ZNSbIwSt11char_traitsIwESaIwEE6appendEPKw~EmptyTestEventListener_ZN7testing11EnvironmentD2Ev_ZNK7testing10TestResult17GetTestPartResultEirebind_Iter_base_Rb_tree_colortv_sec_ZNSs7replaceEN9__gnu_cxx17__normal_iteratorIPcSsEES2_PKcjuse_color_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE5clearEv_ZN7testing8UnitTest17AddTestPartResultENS_14TestPartResult4TypeEPKciRKSsS6__ZNSt6vectorIPcSaIS0_EE7reserveEj_ZNSt12_Vector_baseIN7testing8internal9TraceInfoESaIS2_EE12_Vector_impl12_M_swap_dataERS5_test_properites_mutex__unused2IN_PROGRESS__are_same__destroyUniversalTersePrinterPrintCharsAsStringToIsSubstringImpl >GetStreamset_should_run_ZNKSt6vectorIN7testing14TestPartResultESaIS1_EE5beginEv_ZNKSt6vectorIPN7testing8TestInfoESaIS2_EE5frontEv_ZStplIcSt11char_traitsIcESaIcEESbIT_T0_T1_ERKS6_PKS3__M_node_counttm_ming_init_gtest_countMSG_WAITALLoperator<< _ZNSt6vectorIPN7testing8TestCaseESaIS2_EE5beginEv_ZN9__gnu_cxx14__alloc_traitsISaIN7testing12TestPropertyEEE8max_sizeERKS3__ZNSbIwSt11char_traitsIwESaIwEE6appendERKS2_jjstrcmp_ZNK7testing8internal12UnitTestImpl6FailedEv_ZN7testing8internal12UnitTestImpl24ConfigureStreamingOutputEv_ZNSt6vectorIiSaIiEE6rbeginEv_ZN7testing8internal30WriteToShardStatusFileIfNeededEv_ZN7testing8internal35HandleExceptionsInMethodIfSupportedINS0_15TestFactoryBaseEPNS_4TestEEET0_PT_MS6_FS5_vEPKc_ZN7testing8internal24HasNewFatalFailureHelper20ReportTestPartResultERKNS_14TestPartResultE_ZNK9__gnu_cxx13new_allocatorIPKcE8max_sizeEv_ZNSt3setIPKcSt4lessIS1_ESaIS1_EE5eraseESt23_Rb_tree_const_iteratorIS1_ES7_ai_addr_ZNK9__gnu_cxx13new_allocatorISsE8max_sizeEv__str~AbstractSocketWriter_DestroyCreateFolder_ZN7testing9internal220PrintBytesInObjectToEPKhjPSoisspace_ZNKSs8_M_limitEjj_ZN7testing16AssertionFailureERKNS_7MessageEglobal_test_part_result_repoter__ZNSs4swapERSs_ZNKSt3setISsSt4lessISsESaISsEE4rendEv_ZNSt12_Vector_baseIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE17_M_create_storageEj__uninitialized_move_if_noexcept_a >_ZN7testing8internal12UnitTestImpl11FilterTestsENS1_18ReactionToShardingE_ZNK9__gnu_cxx17__normal_iteratorIPKN7testing8internal9TraceInfoESt6vectorIS3_SaIS3_EEEplEifailure_message_ZNKSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE14_M_lower_boundEPKSt13_Rb_tree_nodeIS1_ESB_RKS1__ZNSbIwSt11char_traitsIwESaIwEE7replaceEjjRKS2_jjStreamableToStringAlmostEqualsInDeathTestChild_ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EE6rbeginEvShouldShardoperator<< _ZNK9__gnu_cxx13new_allocatorIwE7addressERKw_ZNSt16reverse_iteratorIN9__gnu_cxx17__normal_iteratorIPPN7testing11EnvironmentESt6vectorIS4_SaIS4_EEEEEppEi_ZNKSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE8max_sizeEv_ZNKSt17_Rb_tree_iteratorISsEeqERKS0__ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE21_M_get_Node_allocatorEv_ZN7testing14InitGoogleTestEPiPPcfind_if<__gnu_cxx::__normal_iterator >, testing::internal::TestPropertyKeyIs>GetEnviron_ZNSt16reverse_iteratorIN9__gnu_cxx17__normal_iteratorIPPN7testing11EnvironmentESt6vectorIS4_SaIS4_EEEEEppEvdefault_val_ZNK7testing8TestInfo11value_paramEv_ZNSt3setISsSt4lessISsESaISsEE11lower_boundERKSs_ZNSs6insertEjRKSsjj_ZN7testing14InitGoogleTestEPiPPwCmpHelperSTRNEMSG_WAITFORONE_ZN7testing8internal9MutexBase6UnlockEv_ZNSbIwSt11char_traitsIwESaIwEE5eraseEN9__gnu_cxx17__normal_iteratorIPwS2_EEoperator&=pattern__ZNSt3setIPKcSt4lessIS1_ESaIS1_EE5eraseESt23_Rb_tree_const_iteratorIS1_E_ZNK9__gnu_cxx13new_allocatorIPN7testing11EnvironmentEE7addressERS3__ZN7testing8internal24XmlUnitTestResultPrinterD2Ev_ZN7testing8internal18OsStackTraceGetterD0Ev_ZNSt11char_traitsIcE4moveEPcPKcj~AssertHelperkTestShardIndex_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE11upper_boundERKSs_ZN7testing8internal17StreamingListener12SocketWriter14MakeConnectionEv_ZNK7testing8internal13FloatingPointIfE13fraction_bitsEv_M_refcopysi_uid_ZNKSt15basic_streambufIcSt11char_traitsIcEE5pbaseEv_Destroy_ZN9__gnu_cxx13new_allocatorIPN7testing8TestInfoEE7destroyEPS3__ZN7testing8internal26GoogleTestFailureExceptionC2ERKNS_14TestPartResultEsa_mask_S_floatfieldsizetypeIsSubstringImpl_ZN7testing4TestC2Ev_ZNSs4_Rep10_M_refcopyEv~TestPartResultReporterInterfacepremature_exit_file_ZNKSbIwSt11char_traitsIwESaIwEE5rfindEPKwjj__errno_location_ZNSt11char_traitsIwE3eofEv_ZNKSt23_Rb_tree_const_iteratorIPKcEeqERKS2_new_allocator_ZNKSt6vectorIPcSaIS0_EE6rbeginEvoperator()_ZNKSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE12_M_rightmostEv_ZNK7testing10TestResult6FailedEv_M_get_insert_unique_pos_ZNSt12_Vector_baseIN7testing14TestPartResultESaIS1_EE19_M_get_Tp_allocatorEv_ZN7testing16AssertionFailureEvMSG_SYN__value_ZN9__gnu_cxx17__normal_iteratorIPN7testing14TestPartResultESt6vectorIS2_SaIS2_EEEmmEi_ZN7testing15AssertionResultlsINS_14TestPartResultEEERS0_RKT__ZN9__gnu_cxx14__alloc_traitsISaIN7testing8internal9TraceInfoEEE17_S_select_on_copyERKS4_success_scoped_ptr, std::allocator > >directory_ZN9__gnu_cxx17__normal_iteratorIPN7testing14TestPartResultESt6vectorIS2_SaIS2_EEEmmEv_ZNSt3tr110tuple_sizeINS_5tupleIIEEEE5valueE_ZNSs4_Rep26_M_set_length_and_sharableEj_ZNSt6vectorIPcSaIS0_EE5eraseEN9__gnu_cxx17__normal_iteratorIPS0_S2_EES6_CaseInsensitiveWideCStringEquals_ZNKSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE8key_compEv_ZNSt13_Rb_tree_nodeIPKcE9_M_valptrEvgtest_trace_stack_should_ZNSt11char_traitsIwE4copyEPwPKwj_ZNSt10_Iter_baseIPPcLb0EE7_S_baseES1__ZNSt12_Vector_baseISsSaISsEE12_Vector_impl12_M_swap_dataERS2__ZN7testing8internal13DeathTestImpl10set_statusEi__lentm_monrepeat__ZN7testing8TestCase22TestReportableDisabledEPKNS_8TestInfoEsi_pid__off_t_M_get_Node_allocator__resultdefault_global_test_part_result_reporter_new_allocatorrebindDoubleNearPredFormatreverse_iterator<__gnu_cxx::__normal_iterator > > >_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE8_S_valueEPKSt13_Rb_tree_nodeIS1_Eflag_str_ZN9__gnu_cxx14__alloc_traitsISaISt13_Rb_tree_nodeISsEEE8allocateERS3_j_ZNSt6vectorIPN7testing11EnvironmentESaIS2_EE5eraseEN9__gnu_cxx17__normal_iteratorIPS2_S4_EES8__ZN7testing8internal24ParseGoogleTestFlagsOnlyEPiPPc_ZNKSt23_Rb_tree_const_iteratorISsE13_M_const_castEv_ZNKSt12_Vector_baseIPN7testing8TestCaseESaIS2_EE19_M_get_Tp_allocatorEv_M_rightmostIsSpace_ZNSolsEd_ZNSolsEf_ZNSolsEi_ZNSolsEj_ZN7testing8internal24ParseGoogleTestFlagsOnlyEPiPPwobj_bytesShuffleRange_syscall_ZNSolsEx_ZNSt6vectorIiSaIiEE8_M_eraseEN9__gnu_cxx17__normal_iteratorIPiS1_EEkBitCount__wch_ZN7testing8internal12UnitTestImpl14UnshuffleTestsEvlistener_Arg__copy_move_boperator== >_ZdaPv__alloc_swap, std::allocator > >, true>StackGrowsDownFloatingPointUnionoperator++ignore_ZNSt10_Iter_baseIPPN7testing8TestCaseELb0EE7_S_baseES3_operator+=__glibc_reserved4__glibc_reserved5range_width~Test_ZNK7testing8TestCase18ad_hoc_test_resultEv__string_typePrintFailedTests_ZNKSt14_Bit_referenceltERKS__ZN7testing8internal27PrettyUnitTestResultPrinter15OnTestCaseStartERKNS_8TestCaseE_ZN7testing8internal21UniversalTersePrinterIPKwE5PrintES3_PSoInitGoogleTestImpl_ZN9__gnu_cxx17__normal_iteratorIPPN7testing8TestInfoESt6vectorIS3_SaIS3_EEEmIEibasic_string, std::allocator >flag_lenwcsncat__lhs_ZN7testing8internal10scoped_ptrINS0_17StreamingListener20AbstractSocketWriterEEaSERKS4__ZNSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE8_M_eraseEN9__gnu_cxx17__normal_iteratorIPS3_S5_EEnew_allocatorsetstate_ZNSt6vectorIiSaIiEE14_M_fill_assignEjRKi_ZN7testing8internal9DeathTestC2Ev_ZN7testing8internal9Arguments4ArgvEv_ZNSbIwSt11char_traitsIwESaIwEE6resizeEj_ZNK7testing8TestCase11GetTestInfoEi_ZNSt11char_traitsIwE7compareEPKwS2_j_ZNK7testing8internal10scoped_ptrINS0_24InternalRunDeathTestFlagEEptEv_ZNSt6vectorIPN7testing11EnvironmentESaIS2_EE5frontEvoperator--Delete_ZNKSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE8max_sizeEv__elision_data_Containeroperator-=operator->FormatTimeInMillisAsSecondsShuffleoperator<< _ZN7testing8internal15GetTimeInMillisEvtm_year_ZNSt6vectorIN7testing12TestPropertyESaIS1_EE5frontEvLIVED_ZNSs16_S_construct_auxIPcEES0_T_S1_RKSaIcESt12__false_typereverse_iterator<__gnu_cxx::__normal_iterator, std::allocator > > >GetMutableTestInfo_ZNK9__gnu_cxx17__normal_iteratorIPcSsEdeEvMSG_DONTROUTE_ZNSt6vectorIN7testing14TestPartResultESaIS1_EE8pop_backEv~_Vector_impl_M_widen_initargsto_int_type_ZNKSt6vectorIN7testing12TestPropertyESaIS1_EE12_M_check_lenEjPKc_M_set_sharableenvironments_ZSt7nothrow_ZNSt12_Vector_baseIPN7testing11EnvironmentESaIS2_EE12_Vector_impl12_M_swap_dataERS5___iter_equals_val >unit_test__ZN9__gnu_cxx17__normal_iteratorIPPN7testing17TestEventListenerESt6vectorIS3_SaIS3_EEEmIEi_ZNKSbIwSt11char_traitsIwESaIwEE4dataEvoperator<< ai_nextParseInt32Flagnew_value_ZN9__gnu_cxx17__normal_iteratorIPcSsEmIEi__is_move_iterator, std::allocator >*>__builtin_strstr_ZNSt6vectorISsSaISsEE9push_backERKSs_IO_write_end~TestCaseNameIs__uninitialized_copy_a_IO_save_basepptrtm_wday_ZN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE3setERKS3_kExponentBitMask_ZNSt11char_traitsIwE7not_eofERKj_ZNSt6vectorIN7testing14TestPartResultESaIS1_EE5frontEv_ZN7testing32ScopedFakeTestPartResultReporterC2ENS0_13InterceptModeEPNS_19TestPartResultArrayE__are_same_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE10_S_minimumEPKSt18_Rb_tree_node_base_ZN7testing8internal18g_init_gtest_countE_ZN7testing8UnitTest4implEva_typetest_part_resultlast_death_test_case__ZNSt12_Vector_baseISsSaISsEE13_M_deallocateEPSsj_ZNK9__gnu_cxx17__normal_iteratorIPcSsEixEi_ZN9__gnu_cxx13new_allocatorIPN7testing11EnvironmentEE7destroyEPS3__ZNKSt6vectorIPcSaIS0_EE8capacityEv_ZNSt11char_traitsIwE12to_char_typeERKj__new_start_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE6_S_keyEPKSt18_Rb_tree_node_baseSetInjectableArgvsos_stack_trace_ZNK9__gnu_cxx17__normal_iteratorIPPN7testing8TestCaseESt6vectorIS3_SaIS3_EEE4baseEv_ZNK9__gnu_cxx13new_allocatorIPcE8max_sizeEv~TestEventListeners_ZN7testing8internal17StreamingListener20AbstractSocketWriter15CloseConnectionEvMSG_PEEKremoveval1val2_ZN7testing8internal24XmlUnitTestResultPrinter29TestPropertiesAsXmlAttributesERKNS_10TestResultEactual_message_ZNSt6vectorIPN7testing8TestCaseESaIS2_EE4backEva_key_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE8_S_rightEPKSt18_Rb_tree_node_base_ZNK7testing8internal8FilePath14RemoveFileNameEvrebind, std::allocator > > >captured_fd_ZNSt12_Vector_baseIN7testing12TestPropertyESaIS1_EE13_M_deallocateEPS1_jWait_ZN7testing17TestEventListener18OnTestProgramStartERKNS_8UnitTestEOnTestIterationStartuninitialized_copy*, std::basic_string*>_ZNKSt6vectorIPcSaIS0_EE8max_sizeEv_M_end_ZNSt6vectorIPcSaIS0_EE6insertEN9__gnu_cxx17__normal_iteratorIPS0_S2_EERKS0__ZNSt12_Vector_baseIN7testing8internal9TraceInfoESaIS2_EE19_M_get_Tp_allocatorEvFormatByteiterator_traits_ZNK9__gnu_cxx17__normal_iteratorIPPcSt6vectorIS1_SaIS1_EEE4baseEv_ZSt18_Rb_tree_incrementPKSt18_Rb_tree_node_basekDeathTestReturned_S_copy_chars_ZNKSt6vectorIPcSaIS0_EE5emptyEvtotal_test_count_ZNSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE14_M_fill_insertEN9__gnu_cxx17__normal_iteratorIPS3_S5_EEjRKS3_IsValidXmlCharacter_ZNSt6vectorIPN7testing8TestCaseESaIS2_EEaSERKS4__ZN7testing8internal21ImplicitlyConvertibleIPKvS3_E8MakeFromEv_ZNSt6vectorIN7testing14TestPartResultESaIS1_EE6insertEN9__gnu_cxx17__normal_iteratorIPS1_S3_EEjRKS1__ZN9__gnu_cxx17__normal_iteratorIPN7testing14TestPartResultESt6vectorIS2_SaIS2_EEEpLEi__throw_logic_errorstreamable_ZNSs7_M_copyEPcPKcj_ZN7testing8internal10scoped_ptrISt18basic_stringstreamIcSt11char_traitsIcESaIcEEEaSERKS7_signum__ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE10_S_minimumEPSt18_Rb_tree_node_baseColoredPrintfkColorFlag~Environmentsa_sigaction_ZN9__gnu_cxx17__normal_iteratorIPPN7testing8TestCaseESt6vectorIS3_SaIS3_EEEmIEi_IteratorL_ZN7testing8internal10scoped_ptrIKSsE5resetEPS2__ZN7testing8internal26ThreadLocalValueHolderBaseD2Ev_ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EE9push_backERKS2__ZNKSbIwSt11char_traitsIwESaIwEE13find_first_ofEwjstack_sizesi_stimeshard_testsGetNextRandomSeed__arg_ZN9__gnu_cxx17__normal_iteratorIPPcSt6vectorIS1_SaIS1_EEEmIEi_Iter_base_ZN7testing10TestResultD2Ev_M_insert_equal_lowerreverse_iterator<__gnu_cxx::__normal_iterator, std::allocator > > >_ZNSt13_Bit_iteratormIEi_ZN7testing15AssertionResultlsIA11_cEERS0_RKT__ZNK7testing8UnitTest4implEv_ZN9__gnu_cxx13new_allocatorISsE9constructEPSsRKSs_ZNK7testing8internal10scoped_ptrINS0_17StreamingListener20AbstractSocketWriterEEdeEv_ZNSt11char_traitsIcE3eofEvfastmap_ZNKSt3setISsSt4lessISsESaISsEE11equal_rangeERKSspthread_key_tmmap_ZNK7testing8UnitTest30reportable_disabled_test_countEvgetaddrinfo_Iter_base, std::allocator >*, false>TestReportablefull_flag__niter_base*>_ZNKSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE5countERKSs_ZNSbIwSt11char_traitsIwESaIwEE6assignEPKwjst_uid__builtin_strrchrstr_valdefault_per_thread_test_part_result_reporter__ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE15_M_destroy_nodeEPSt13_Rb_tree_nodeISsE_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE15_M_insert_lowerEPSt18_Rb_tree_node_baseRKS1__ZN7testing8internal17TestEventRepeater7ReleaseEPNS_17TestEventListenerE_ZNK7testing8internal24InternalRunDeathTestFlag4lineEv__copy_move_bPrintByteSegmentInObjectTo_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE4rendEv_ZNK7testing8internal2RE7patternEv_ZN9__gnu_cxx17__normal_iteratorIPN7testing12TestPropertyESt6vectorIS2_SaIS2_EEEmmEv_ZNSt6vectorISsSaISsEED2Ev_ZNSs7replaceEN9__gnu_cxx17__normal_iteratorIPcSsEES2_PKca_test_case_name_ZNSbIwSt11char_traitsIwESaIwEE13_S_copy_charsEPwPKwS5___copy_move_bEscapeXmlAttribute_ForwardIterator_ZNK9__gnu_cxx17__normal_iteratorIPKPN7testing17TestEventListenerESt6vectorIS3_SaIS3_EEE4baseEv_ZNSt6vectorIN7testing12TestPropertyESaIS1_EE5eraseEN9__gnu_cxx17__normal_iteratorIPS1_S3_EE_Bit_reference_ZN7testing8internal24XmlUnitTestResultPrinteraSERKS1_gtest_trace_stack_ZNSt8ios_base4setfESt13_Ios_Fmtflags_ZN7testing8internal12UnitTestImpl20ClearAdHocTestResultEv_ZN7testing8internal15NoExecDeathTestD2Evwords_ZNK7testing8internal10scoped_ptrINS0_16DeathTestFactoryEEdeEvstart_timestamp__ZNKSt17_Rb_tree_iteratorISsEdeEv_ZNKSs7compareEjjPKcj_ZNK7testing8UnitTest6PassedEv_Destroy_aux_ZNKSt6vectorIPN7testing17TestEventListenerESaIS2_EE5beginEvcopy_backward_ZNSt12_Vector_baseIPN7testing8TestInfoESaIS2_EE11_M_allocateEj_ZNSs6insertEjPKc_ZN7testing8internal10scoped_ptrINS0_16DeathTestFactoryEE5resetEPS2__ZNKSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE6rbeginEv_ZN7testing8internal17StreamingListener20OnTestIterationStartERKNS_8UnitTestEig_help_flagFlagToEnvVar_ZN9__gnu_cxx17__normal_iteratorIPN7testing12TestPropertyESt6vectorIS2_SaIS2_EEEppEia_file_name_ZNKSt6vectorIPN7testing8TestCaseESaIS2_EE5emptyEvF_OWNER_TIDnonfatally_failed_ZN7testing8internal19UniversalPrintArrayEPKcjPSoReactionToSharding__quad_tenable_ZN9__gnu_cxx13new_allocatorIPN7testing8TestInfoEE10deallocateEPS3_j_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE14_M_upper_boundEPSt13_Rb_tree_nodeISsES8_RKSs_ZNSt3setIPKcSt4lessIS1_ESaIS1_EEaSERKS5_file_stat_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE8_M_beginEvgai_strerror__new_finishcopy_backwardtest_case_to_run_countFLAGS_gtest_show_internal_stack_frames_ZNSt6vectorIPN7testing8TestCaseESaIS2_EE6rbeginEvgtest_flag_saver__ZNSt6vectorISsSaISsEE7reserveEjoperator<< kPathSeparatorString_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE8_M_eraseEPSt13_Rb_tree_nodeISsEOnTestEndRemoveTrailingPathSeparator~ScopedTraceis_attribute_ZNKSt6vectorIiSaIiEE4rendEv_ZN9__gnu_cxx13new_allocatorISt13_Rb_tree_nodeISsEE7destroyEPS2__ZNKSt6vectorIPcSaIS0_EE12_M_check_lenEjPKc__normal_iterator > >wcsncmp_ZNKSt18_Bit_iterator_baseleERKS__ZN9__gnu_cxx14__alloc_traitsISaIN7testing14TestPartResultEEE10deallocateERS3_PS2_j_ZNK7testing8internal8FilePath7IsEmptyEv__normal_iterator > >_ZNK9__gnu_cxx17__normal_iteratorIPPcSt6vectorIS1_SaIS1_EEEdeEv_ZNSt6vectorIPN7testing8TestInfoESaIS2_EE5frontEv_M_right_ZNKSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE4findERKS1___copy_move_a2_ZNK7testing8internal8FilePath27RemoveTrailingPathSeparatorEvbase_name_M_get_insert_hint_unique_pos_ZN7testing8internal15NoExecDeathTestD0Ev_ZN7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEED2Evtowctrans_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE8_M_beginEv_ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EE8_M_eraseEN9__gnu_cxx17__normal_iteratorIPS2_S4_EE_ZNSs2atEj__uninitialized_copy_aRunTearDownTestCase_ZN7testing17TestEventListener13OnTestCaseEndERKNS_8TestCaseE_ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EE4swapERS4__ZN7testing8internal11CmpHelperLEEPKcS2_xxoperator- >_S_refcount__digits_ZNKSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE21_M_get_Node_allocatorEv__normal_iterator > >_ZNSbIwSt11char_traitsIwESaIwEE7replaceEN9__gnu_cxx17__normal_iteratorIPwS2_EES6_PKwj__is_normal_iteratorfixture_class_id_ZN7testing8internal27PrettyUnitTestResultPrinter27OnEnvironmentsTearDownStartERKNS_8UnitTestE_ZNSt6vectorIPN7testing8TestCaseESaIS2_EE5eraseEN9__gnu_cxx17__normal_iteratorIPS2_S4_EEvswprintf_Value_ZNSs4_Rep10_M_destroyERKSaIcE_ZN7testing4Test8TestBodyEvUniversalPrinterdetailexpr1expr2_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE28_M_get_insert_hint_equal_posESt23_Rb_tree_const_iteratorISsERKSs__uninit_copy_ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EE15_M_erase_at_endEPS2___are_samefixture_class_id__ZN7testing28FLAGS_gtest_break_on_failureEFLAGS_gtest_print_time_IsMove_ZN7testing8internal29PrintFullTestCommentIfPresentERKNS_8TestInfoEoperator<< __copy_move_backward_a__is_normal_iterator_ZNKSt6vectorIN7testing12TestPropertyESaIS1_EEixEj_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE23_M_get_insert_equal_posERKSs_ZNSt6vectorIiSaIiEE3endEvMutexBase_ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EE6resizeEjS2__ZN7testing14IsNotSubstringEPKcS1_RKSsS3_tv_usec_ZNKSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE3endEvFindLastPathSeparatorpair, std::_Rb_tree_iterator >diff_ZN9__gnu_cxx14__alloc_traitsISaIPN7testing11EnvironmentEEE10deallocateERS4_PS3_j_ZNSbIwSt11char_traitsIwESaIwEE4_Rep8_M_cloneERKS1_j_ZNSt6vectorIPN7testing8TestInfoESaIS2_EE4rendEvCOLOR_DEFAULT_ZNK7testing8internal12UnitTestImpl21reportable_test_countEvto_char_type_ZN9__gnu_cxx13new_allocatorIPN7testing8TestCaseEE7destroyEPS3__ZN7testing8internal13CaptureStderrEvwide_c_str_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE16_M_insert_equal_ESt23_Rb_tree_const_iteratorISsERKSs_ZN7testing8internal6String32CaseInsensitiveWideCStringEqualsEPKwS3_operator<<_M_set_leaked_ZNSt6vectorIiSaIiEE15_M_erase_at_endEPi_ZN7testing8internal11CmpHelperGTEPKcS2_xx_M_clone_ZNK7testing14TestPartResult11line_numberEvoperator()<__gnu_cxx::__normal_iterator*, std::vector > > >_ZN7testing8internal26GoogleTestFailureExceptionD0Ev_ZNK9__gnu_cxx17__normal_iteratorIPKN7testing8internal9TraceInfoESt6vectorIS3_SaIS3_EEEmiEi_ZN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE11ValueHolderD2Evsetf_ZN7testing8TestCase19RunTearDownTestCaseEvFileOrDirectoryExists_ZNSbIwSt11char_traitsIwESaIwEE6appendEjw_ZN7testing8internal17TestEventRepeater11OnTestStartERKNS_8TestInfoEthis_fixture_id_ZNK9__gnu_cxx17__normal_iteratorIPKN7testing14TestPartResultESt6vectorIS2_SaIS2_EEEdeEv_ZNKSbIwSt11char_traitsIwESaIwEE11_M_disjunctEPKwsetwhas_tests_to_run_ZNK7testing8internal8FilePath21FindLastPathSeparatorEvsigemptyset_ZNSspLEPKcoperator==_ZNKSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE6_M_endEv_ZNSt16reverse_iteratorIN9__gnu_cxx17__normal_iteratorIPPN7testing11EnvironmentESt6vectorIS4_SaIS4_EEEEEmmEi_ZN9__gnu_cxx17__normal_iteratorIPPN7testing11EnvironmentESt6vectorIS3_SaIS3_EEEmIEiis_nan_ZNKSt12_Vector_baseIiSaIiEE19_M_get_Tp_allocatorEvvalue_comp_ZN9__gnu_cxx17__normal_iteratorIPN7testing12TestPropertyESt6vectorIS2_SaIS2_EEEpLEi__first_ZN7testing24ValidateTestPropertyNameERKSsRKSt6vectorISsSaISsEECOLOR_RED__copy_move_backward_a2operator<< _ZN7testing8internal17TestEventRepeater22set_forwarding_enabledEb_ZN7testing8internal13ExecDeathTestD2Ev__tmpkRepeatFlag_ZN7testing8internal12UnitTestImplD2Ev_ZNKSs6substrEjj_ZN7testing8internal12UnitTestImpl19current_test_resultEvkey_type_M_rootExtractSummarymbsrtowcsDefinedTestIter_S_beg_ZN7testing8internal24XmlUnitTestResultPrinter16PrintXmlUnitTestEPSoRKNS_8UnitTestE_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE21_M_insert_equal_lowerERKSsoperator>=_ZNK7testing8internal12UnitTestImpl22failed_test_case_countEvvalue_str_ZNKSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE11__rb_verifyEvOtherOperand_ZN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE9CreateKeyEv_ZN7testing8internal13PrintStringToERKSsPSo_ZNKSt6vectorIPN7testing8TestInfoESaIS2_EE4dataEv_ZNSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE5frontEvkAlsoRunDisabledTestsFlag_ZN9__gnu_cxx14__alloc_traitsISaISsEE8allocateERS1_j~UnitTestImpl_ZN9__gnu_cxx17__normal_iteratorIPiSt6vectorIiSaIiEEEppEi_S_construct_ZNSt10_Iter_baseIPiLb0EE7_S_baseES0_listeners_ZNK9__gnu_cxx17__normal_iteratorIPKN7testing14TestPartResultESt6vectorIS2_SaIS2_EEEixEi_ZN9__gnu_cxx17__normal_iteratorIPiSt6vectorIiSaIiEEEppEv_ZN7testing8internal11CmpHelperEQEPKcS2_xx_ZNSt6vectorISsSaISsEE5clearEv_ZNKSt3setIPKcSt4lessIS1_ESaIS1_EE11lower_boundERKS1__ZNSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE6rbeginEv_ZN7testing8internal29ParameterizedTestCaseRegistryD2Ev_ZNK9__gnu_cxx17__normal_iteratorIPKPN7testing8TestInfoESt6vectorIS3_SaIS3_EEEixEi__pid_tAbortReason_ConstructkReservedTestCaseAttributes_ZNK7testing8internal10scoped_ptrIKSsEptEv_ZNKSt6vectorISsSaISsEE4backEvint_frac_digits_ZNSt12_Vector_baseIPcSaIS0_EE11_M_allocateEj_ZN7testing8internal16GetAnsiColorCodeENS0_10GTestColorE_ZN9__gnu_cxx17__normal_iteratorIPPN7testing8internal29ParameterizedTestCaseInfoBaseESt6vectorIS4_SaIS4_EEEppEi_ZNSbIwSt11char_traitsIwESaIwEE7replaceEN9__gnu_cxx17__normal_iteratorIPwS2_EES6_PKw_ZNKSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE5emptyEv_ZNKSt17_Rb_tree_iteratorIPKcEptEv_ZN9__gnu_cxx17__normal_iteratorIPPN7testing8internal29ParameterizedTestCaseInfoBaseESt6vectorIS4_SaIS4_EEEppEv_ZNSt20__uninitialized_copyILb0EE13__uninit_copyIPN7testing14TestPartResultES4_EET0_T_S6_S5___is_normal_iterator_ZNK7testing8internal10scoped_ptrISt18basic_stringstreamIcSt11char_traitsIcESaIcEEEdeEv__copy_move_b_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE5eraseERKS1_vector >PrintCharAndCodeTo_ZNKSt6vectorIPN7testing11EnvironmentESaIS2_EE3endEv_ZN9__gnu_cxx13new_allocatorIcE7destroyEPcs1_expressionOutputXmlTestInfo_ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EE5clearEv_ZNSt8ios_base9precisionEi_ZN7testing8internal13DeathTestImplD0Ev_ZN7testing8internal19UniversalPrintArrayEPKwjPSo_ZNSt6vectorIN7testing14TestPartResultESaIS1_EE4dataEv__uninitialized_move_if_noexcept_a >_M_iend_ZNK7testing8internal10scoped_ptrINS0_24InternalRunDeathTestFlagEE3getEvTearDownEnvironmentkDeathTestCaseFiltersi_tidnewline_anchorst_rdev__sigaction_handler_S_empty_rep_storage__copy_move_a2_ZN7testing8UnitTest3RunEviterator_traitsg_argvs_ZN9__gnu_cxx13new_allocatorIPcE7destroyEPS1__ZNSs6assignEPKcExecDeathTestChildMainlocaltime_ZNKSt6vectorIPN7testing11EnvironmentESaIS2_EE8capacityEv_ZNKSbIwSt11char_traitsIwESaIwEE7_M_dataEv_ZN7testing8internal14DeathTestAbortERKSs_ZN7testing8internal14CmpHelperSTRNEEPKcS2_S2_S2_value_param___pfnStreamableToStringold_reporter__ZNSs6resizeEjc_ZN7testing32ScopedFakeTestPartResultReporterD2Ev_DestroykMaxUlps_ZN7testing8internal18PrintCharAndCodeToIhhEEvT0_PSoforwarding_enabled__M_check_len__is_normal_iterator_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE11lower_boundERKS1___rb_verify_ZN7testing28FLAGS_gtest_throw_on_failureE_S_bin~ScopedFakeTestPartResultReporterint_n_sep_by_space_ZNSt12_Destroy_auxILb0EE9__destroyIPN7testing8internal9TraceInfoEEEvT_S6__ZNKSt6vectorIPN7testing8TestCaseESaIS2_EE2atEj_IO_marker_ZNKSt6vectorIPN7testing11EnvironmentESaIS2_EE8max_sizeEv_ZNK7testing14ExitedWithCodeclEi_ZNK9__gnu_cxx17__normal_iteratorIPPN7testing11EnvironmentESt6vectorIS3_SaIS3_EEEdeEvtest_case_indices__ZN7testing8internal11g_help_flagE_FacetDeathTestOutcome_ZN7testing8internal10scoped_ptrISt18basic_stringstreamIcSt11char_traitsIcESaIcEEE5resetEPS6_print_time__ZNSt6vectorIN7testing14TestPartResultESaIS1_EE18_M_fill_initializeEjRKS1__ZNKSt6vectorIN7testing8internal9TraceInfoESaIS2_EE5beginEv_ZNSs6appendERKSsjjIsNotContainer_ZN7testing8internal10ParseInt32ERKNS_7MessageEPKcPiFLAGS_gtest_break_on_failure_Destroy_ZNK9__gnu_cxx13new_allocatorIPN7testing8internal29ParameterizedTestCaseInfoBaseEE7addressERS4__ZNSt12_Vector_baseIPN7testing17TestEventListenerESaIS2_EE12_Vector_impl12_M_swap_dataERS5_re_nsubGetAbsolutePathToOutputFilehas_new_fatal_failure_INTERCEPT_ONLY_CURRENT_THREADiterator_traits_ZNKSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE11lower_boundERKS1__ZNK9__gnu_cxx17__normal_iteratorIPPN7testing17TestEventListenerESt6vectorIS3_SaIS3_EEEdeEv_ZNSt6vectorIPN7testing8TestCaseESaIS2_EE4swapERS4_bytes_last_read_BI1_BI2_ZNKSt12_Vector_baseIN7testing14TestPartResultESaIS1_EE19_M_get_Tp_allocatorEvptr__ZN7testing8UnitTest9listenersEv_ZNK9__gnu_cxx17__normal_iteratorIPPN7testing11EnvironmentESt6vectorIS3_SaIS3_EEE4baseEvai_socktype__is_move_iterator_ZN9__gnu_cxx17__normal_iteratorIPKPN7testing11EnvironmentESt6vectorIS3_SaIS3_EEEppEiPrintFullTestCommentIfPresent_S_truncscoped_ptr, std::allocator > >_ZN9__gnu_cxx17__normal_iteratorIPKPN7testing11EnvironmentESt6vectorIS3_SaIS3_EEEppEv_ZNKSs7compareEPKc__pad4_ZNKSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE5beginEvset_elapsed_time_ZNK9__gnu_cxx17__normal_iteratorIPPN7testing11EnvironmentESt6vectorIS3_SaIS3_EEEixEi_S_ios_iostate_end_ZN7testing8internal17GetCapturedStderrEvFLAGS_gtest_coloroperator<< ~new_allocator~ThreadLocal_ZN7testing8internal8FilePath22GenerateUniqueFileNameERKS1_S3_PKc_ZNSbIwSt11char_traitsIwESaIwEE4_Rep12_S_empty_repEvreverse_iterator<__gnu_cxx::__normal_iterator > > >_ZN9__gnu_cxx13new_allocatorIwE7destroyEPw_ZNKSt6vectorISsSaISsEE4sizeEv__uninitialized_move_if_noexcept_a >_ZNKSt12_Vector_baseIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE13get_allocatorEvoperator<< strtoll~UnitTestReadReportFailureInUnknownLocation_ZN7testing8internal12UnitTestImpl28CurrentOsStackTraceExceptTopEi__baseInt32FromGTestEnv_ZNK9__gnu_cxx17__normal_iteratorIPKPN7testing8TestCaseESt6vectorIS3_SaIS3_EEEdeEv__is_move_iterator<__gnu_cxx::__normal_iterator > > >user_msgerrnum_ZNK9__gnu_cxx17__normal_iteratorIPPN7testing17TestEventListenerESt6vectorIS3_SaIS3_EEEixEi__copy_move_backward_a2emptyinstance_ZN7testing8internal29ParameterizedTestCaseRegistryaSERKS1_val1_ss__copy_move_b__end_ZN9__gnu_cxx14__alloc_traitsISaIPKcEE10deallocateERS3_PS2_jobject_ZN7testing8internal14CapturedStream11GetFileSizeEP8_IO_FILE_ZN7testing18FLAGS_gtest_repeatE_ZNK9__gnu_cxx17__normal_iteratorIPPN7testing8internal29ParameterizedTestCaseInfoBaseESt6vectorIS4_SaIS4_EEEdeEv_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE10_S_maximumEPKSt18_Rb_tree_node_baseDeleteSelf___normal_iterator > >_ZNSbIwSt11char_traitsIwESaIwEE7replaceEN9__gnu_cxx17__normal_iteratorIPwS2_EES6_S6_S6_tz_minuteswestkDefaultOutputFile_M_valptr_ZNSt6vectorIN7testing12TestPropertyESaIS1_EE18_M_fill_initializeEjRKS1__ZN7testing8internal17TestEventRepeaterD0Ev_ZNKSt23_Rb_tree_const_iteratorIPKcE13_M_const_castEv_ZNSt16reverse_iteratorIN9__gnu_cxx17__normal_iteratorIPPN7testing11EnvironmentESt6vectorIS4_SaIS4_EEEEEpLEi_S_internal_ZN7testing8internal10scoped_ptrISsE7releaseEv_ZNK9__gnu_cxx17__normal_iteratorIPN7testing8internal9TraceInfoESt6vectorIS3_SaIS3_EEEdeEvconst_referenceOnEnvironmentsTearDownStart__uninit_copy_ZN9__gnu_cxx14__alloc_traitsISaIPN7testing17TestEventListenerEEE10_S_on_swapERS4_S6__ZNK9__gnu_cxx13new_allocatorIN7testing12TestPropertyEE7addressERKS2_output_dir_ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EE3endEvset_last_death_test_message_ZNKSt3setIPKcSt4lessIS1_ESaIS1_EE5beginEv_ZN7testing16AssertionSuccessEvport_num_COLOR_YELLOWrebindreverse_iterator<__gnu_cxx::__normal_iterator > > >_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE4findERKSsreservedeath_test_index_ZN9__gnu_cxx17__normal_iteratorIPN7testing8internal9TraceInfoESt6vectorIS3_SaIS3_EEEppEi_ZNK9__gnu_cxx17__normal_iteratorIPKPN7testing8TestCaseESt6vectorIS3_SaIS3_EEEixEi_M_disjunct_ZNKSbIwSt11char_traitsIwESaIwEE12find_last_ofEwj_M_leak_ZNSs7_M_leakEv~Arguments_ZN9__gnu_cxx17__normal_iteratorIPN7testing8internal9TraceInfoESt6vectorIS3_SaIS3_EEEppEv_ZNSt6vectorIiSaIiEE6insertEN9__gnu_cxx17__normal_iteratorIPiS1_EERKierrors_str__is_move_iteratorg_executable_path_ZNKSt12_Vector_baseIPN7testing17TestEventListenerESaIS2_EE13get_allocatorEvForEach, void (*)(testing::TestInfo*)>_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE15_M_insert_equalERKSsrm_so_ZNSt6vectorIPcSaIS0_EE4swapERS2_elapsedfclose_ZN7testing8internal8FilePath11ConcatPathsERKS1_S3__S_unitbuf_ZNK9__gnu_cxx17__normal_iteratorIPPN7testing8internal29ParameterizedTestCaseInfoBaseESt6vectorIS4_SaIS4_EEEixEi_ZNKSt4lessIPKcEclERKS1_S4_kHexEscapeFLAGS_gtest_internal_run_death_testAssertionSuccess_ZNKSbIwSt11char_traitsIwESaIwEEixEj_ZNSt6vectorIPcSaIS0_EE6insertEN9__gnu_cxx17__normal_iteratorIPS0_S2_EEjRKS0__ZNKSs2atEj_ZN7testing8internal10scoped_ptrINS0_24InternalRunDeathTestFlagEE7releaseEv_ZNK7testing8internal13FloatingPointIdE4bitsEv_ZNKSbIwSt11char_traitsIwESaIwEE6_M_repEvline__ZNKSt6vectorIN7testing14TestPartResultESaIS1_EE5emptyEvoperator< , std::allocator >_ZN9__gnu_cxx14__alloc_traitsISaISt13_Rb_tree_nodeISsEEE17_S_select_on_copyERKS3__ZNK9__gnu_cxx17__normal_iteratorIPN7testing8internal9TraceInfoESt6vectorIS3_SaIS3_EEEixEioriginal_dir_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEED2Ev_ZN7testing8internal7PrintToEwPSo_ZNSbIwSt11char_traitsIwESaIwEE6rbeginEv_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE15_M_insert_lowerEPSt18_Rb_tree_node_baseRKSs_M_parent_ZNKSt6vectorIPN7testing8TestInfoESaIS2_EE5beginEv_ZNKSbIwSt11char_traitsIwESaIwEE6rbeginEv6ldiv_t_ZNKSt17_Rb_tree_iteratorIPKcEeqERKS2__Destroyiterator_ZNKSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE14_M_lower_boundEPKSt13_Rb_tree_nodeISsES9_RKSs_ZNK9__gnu_cxx13new_allocatorIPN7testing8internal29ParameterizedTestCaseInfoBaseEE8max_sizeEv_M_length_ZN7testing8internal11CmpHelperGEEPKcS2_xxchar_traitsFLAGS_gtest_random_seed_ZN9__gnu_cxx14__alloc_traitsISaIN7testing12TestPropertyEEE10deallocateERS3_PS2_j_Setfill_ZNKSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE4backEvreverse_iterator >pthread_mutex_init_ZNKSs9_M_ibeginEv_ZN7testing8internal6String28CaseInsensitiveCStringEqualsEPKcS3__ZN7testing8internal17TestEventRepeater13OnTestCaseEndERKNS_8TestCaseE__miter_baseTypeWithSize<4u>_ZNSt12_Vector_baseISsSaISsEE19_M_get_Tp_allocatorEv_ZNSt3setIPKcSt4lessIS1_ESaIS1_EE6insertERKS1__ZN7testinglsERSoRKNS_14TestPartResultEHasOneFailureCmpHelperSTREQ_ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EE8pop_backEvdefined_test_names__ZNK7testing10TestResult15test_propertiesEvCmpHelperSTRCASENE_ZN7testing8UnitTestD2Ev_ZNSt11char_traitsIwE2ltERKwS2__ZN7testing18FLAGS_gtest_outputE_Iter_equals_valexit_code__ZNSt6vectorIiSaIiEE7reserveEj_ZN9__gnu_cxx17__normal_iteratorIPKN7testing14TestPartResultESt6vectorIS2_SaIS2_EEEppEi_Ios_SeekdirListTestsMatchingFilter_ZNSt6vectorIN7testing14TestPartResultESaIS1_EE6insertEN9__gnu_cxx17__normal_iteratorIPS1_S3_EERKS1_rebind, std::allocator > >_ZN7testing8internal37FormatCompilerIndependentFileLocationEPKci_ZN9__gnu_cxx17__normal_iteratorIPKN7testing14TestPartResultESt6vectorIS2_SaIS2_EEEppEvGenerateUniqueFileName_ZNKSt6vectorISsSaISsEE2atEjchar_traitskMaxBiggestInt__builtin_puts_ZN7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEE11ValueHolder7pointerEvoutput_name__addressoffile_size_ZNSt8ios_base5widthEi_ZN7testing8internal12UnitTestImpl23ClearNonAdHocTestResultEv_ZNSt6vectorIPN7testing8TestInfoESaIS2_EE14_M_fill_insertEN9__gnu_cxx17__normal_iteratorIPS2_S4_EEjRKS2___alloc_traits >GetThreadCount_ZN7testing8UnitTest14RecordPropertyERKSsS2_~GTestMutexLock_M_dataplus__uninitialized_move_if_noexcept_a >_ZNSt6vectorIN7testing12TestPropertyESaIS1_EE7reserveEj~basic_ostreamequal_range_ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EE6insertEN9__gnu_cxx17__normal_iteratorIPS2_S4_EERKS2_plural_form_M_pred_ZN9__gnu_cxx14__alloc_traitsISaIPN7testing11EnvironmentEEE10_S_on_swapERS4_S6__ZNK7testing8internal12UnitTestImpl11GetTestCaseEi_M_left__builtin_putcharnothrow_t__destroy__builtin_fputsnew_test_case_ZNK9__gnu_cxx13new_allocatorIPN7testing17TestEventListenerEE8max_sizeEv_ZNKSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EEixEjkDeathTestLivedparameterized_tests_registered__ZNKSs13find_first_ofEPKcjForEach, void (*)(testing::TestCase*)>_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE5eraseESt23_Rb_tree_const_iteratorISsE_ZNSs18_S_construct_aux_2EjcRKSaIcE_ZN7testing10TestResult20ValidateTestPropertyERKSsRKNS_12TestPropertyE_Vector_base >INTERCEPT_ALL_THREADS_ZN7testing8TestInfoC2ERKSsS2_PKcS4_PKvPNS_8internal15TestFactoryBaseEShouldRunTestOnShard_S_synced_with_stdioInt32FromEnvOrDieIsEmptyTestFailedpositive_sign_ZN9__gnu_cxx13new_allocatorIcE9constructEPcRKcshard_index_env__lockmkstempKilledBySignal__in_chrg_ZN7testing8internal27PrettyUnitTestResultPrinterD0Ev_ZNSbIwSt11char_traitsIwESaIwEE6appendERKS2__ZNSt11char_traitsIwE11to_int_typeERKw__normal_iterator, std::allocator > >_ZNKSt6vectorIN7testing8internal9TraceInfoESaIS2_EE14_M_range_checkEj_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE8_M_eraseEPSt13_Rb_tree_nodeIS1_Estatement__ZN7testing8internal13ExecDeathTest10AssumeRoleEv__builtin_strchr_ZN9__gnu_cxx14__alloc_traitsISaIPcEE17_S_select_on_copyERKS2_kFatalFailuretest_idMSG_CMSG_CLOEXEC_ZNK9__gnu_cxx17__normal_iteratorIPSsSt6vectorISsSaISsEEEdeEvGetEnvchild_pid___miter_base_ZNSt12_Vector_baseIiSaIiEE19_M_get_Tp_allocatorEv~AssertionResultRegisterTests_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE29_M_get_insert_hint_unique_posESt23_Rb_tree_const_iteratorIS1_ERKS1__ZNSt6vectorIPN7testing11EnvironmentESaIS2_EE6insertEN9__gnu_cxx17__normal_iteratorIPS2_S4_EEjRKS2__ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EE5eraseEN9__gnu_cxx17__normal_iteratorIPS2_S4_EE_ZNK7testing8TestCase12elapsed_timeEv_ZNSs5clearEvSetUpEnvironmentin_color_mode_ZNK9__gnu_cxx13new_allocatorIN7testing14TestPartResultEE8max_sizeEv_M_lower_bound_ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EE8_M_eraseEN9__gnu_cxx17__normal_iteratorIPS2_S4_EE__ptr_ZNKSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE4sizeEv_ZN7testing8internal17TestEventRepeater6AppendEPNS_17TestEventListenerECreateKey__copy_move_b_ZN7testing8internal12UnitTestImplC2EPNS_8UnitTestEoperator<< _ZNSt3setISsSt4lessISsESaISsEE11equal_rangeERKSs_ZNSt6vectorIN7testing12TestPropertyESaIS1_EEixEj_ZNKSt6vectorISsSaISsEE5frontEv_ZNSt12_Vector_baseIPN7testing11EnvironmentESaIS2_EE17_M_create_storageEj_ZN7testing8internal13FloatingPointIdE24SignAndMagnitudeToBiasedERKyxmloutThreadLocal > >_ZN7testing8internal17Int32FromGTestEnvEPKci_ZNKSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE14_M_upper_boundEPKSt13_Rb_tree_nodeIS1_ESB_RKS1__Predicateiterationvector >_ZN7testing8internal35HandleExceptionsInMethodIfSupportedINS_4TestEvEET0_PT_MS4_FS3_vEPKc_ZNK7testing8internal10scoped_ptrINS0_17StreamingListener20AbstractSocketWriterEE3getEv_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE5eraseESt17_Rb_tree_iteratorIS1_E_ZN7testing15AssertionResultC2ERKS0__ZNSbIwSt11char_traitsIwESaIwEE5eraseEN9__gnu_cxx17__normal_iteratorIPwS2_EES6_string_value__c1__c2__alloc_traits >_ZNKSt6vectorIPN7testing8TestInfoESaIS2_EE14_M_range_checkEj_ZNK9__gnu_cxx17__normal_iteratorIPSsSt6vectorISsSaISsEEEixEi_ZN9__gnu_cxx14__alloc_traitsISaIPN7testing8TestCaseEEE8max_sizeERKS4__ZN9__gnu_cxx14__alloc_traitsISaISt13_Rb_tree_nodeISsEEE8max_sizeERKS3__M_finishactual_predicate_valuewcstof_ZN7testing8internal17StreamingListener13OnTestCaseEndERKNS_8TestCaseE_ZNK7testing8internal12UnitTestImpl17current_test_caseEvwcstokwcstol_ZNKSs16find_last_not_ofERKSsj_ZNKSbIwSt11char_traitsIwESaIwEE6lengthEv_ZN9__gnu_cxx13new_allocatorIPKcE9constructEPS2_RKS2_operator== >iterator_typeInitDeathTestSubprocessControlInfo_S_failbit__normal_iterator__ch_ZN7testing8internal23DefaultDeathTestFactory6CreateEPKcPKNS0_2REES3_iPPNS0_9DeathTestE_vptr.DeathTest_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE14_M_create_nodeERKS1__ZN7testing29FLAGS_gtest_stack_trace_depthESOCK_SEQPACKETGetElementOrtest_to_run_count_ZN9__gnu_cxx14__alloc_traitsISaIPN7testing8TestCaseEEE10deallocateERS4_PS3_j_ZN7testing8internal35DefaultGlobalTestPartResultReporteraSERKS1__ZN7testing13PrintToStringIPKcEESsRKT___int32_t__normal_iterator > >kMaxStackAlignment_ZN9__gnu_cxx13new_allocatorISt13_Rb_tree_nodeIPKcEE7destroyEPS4_operator<< UnshuffleTests_ZNSt6vectorIN7testing14TestPartResultESaIS1_EE9push_backERKS1__ZNK7testing8internal12UnitTestImpl17gtest_trace_stackEvpthread_key_deletest_mtimuncaptured_fd__ZN7testing8internal17StreamingListener20AbstractSocketWriter6SendLnERKSs_ZNSt6vectorISsSaISsEEixEjtm_zone_Bit_type_ZN7testing8UnitTestaSERKS0__ZNKSt12_Vector_baseISsSaISsEE13get_allocatorEv_ZNSt6vectorIPN7testing11EnvironmentESaIS2_EE5beginEv_ZNSt12_Vector_baseIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE19_M_get_Tp_allocatorEv_ZNSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE4backEv_ZNSs5eraseEN9__gnu_cxx17__normal_iteratorIPcSsEE__distance_ZN7testing8internal9Arguments11AddArgumentEPKc_ZNSt6vectorIPcSaIS0_EE6resizeEjS0__ZNKSt12_Vector_baseIN7testing8internal9TraceInfoESaIS2_EE13get_allocatorEvfunctorVerifyRegisteredTestNamesFormatCountableNounPrintBytesInObjectToPrintCharAndCodeTo_ZNSt6vectorIPN7testing11EnvironmentESaIS2_EE6resizeEjS2__ZN7testing8internal11CmpHelperLTEPKcS2_xx__is_move_iteratorbinary_ZNK7testing8TestInfo10should_runEv_ZN7testing8internal11ScopedTraceaSERKS1_rebindEscapeXmlFormatIntWidth2_ZNK9__gnu_cxx17__normal_iteratorIPKN7testing8internal9TraceInfoESt6vectorIS3_SaIS3_EEEptEv_ZNSt12_Vector_baseIN7testing12TestPropertyESaIS1_EE17_M_create_storageEj__uninitialized_copy_a_ZNKSt6vectorIN7testing14TestPartResultESaIS1_EE4backEv_Rb_tree_node, std::allocator > >_ZNSt12_Vector_baseIN7testing14TestPartResultESaIS1_EE13_M_deallocateEPS1_jcopy_backwardStatStruct__pthread_mutex_sGetInstance_S_construct_aux_2skip_count_ZN7testing8internal25ReportInvalidTestCaseTypeEPKcS2_ifile_name__ZNK7testing10TestResult16total_part_countEvsa_familyFLAGS_gtest_filter_ZNSt6vectorIPcSaIS0_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS0_S2_EERKS0_shard_index_ZNSt6vectorIN7testing14TestPartResultESaIS1_EE5beginEv_ZN9__gnu_cxx17__normal_iteratorIPN7testing12TestPropertyESt6vectorIS2_SaIS2_EEEmIEiGNU C++ 4.9.2 20150212 (Red Hat 4.9.2-6) -mtune=generic -march=i686 -g -O2 -fPIC__dso_handle_ZN7testing8internal18CmpHelperSTRCASEEQEPKcS2_S2_S2__ZNK9__gnu_cxx17__normal_iteratorIPKPN7testing11EnvironmentESt6vectorIS3_SaIS3_EEEplEi_ZN7testing8internal17TestEventRepeater16OnTestProgramEndERKNS_8UnitTestE_ZNSs10_S_compareEjj_ZNK9__gnu_cxx17__normal_iteratorIPiSt6vectorIiSaIiEEEmiEi_ZNSt6vectorIPN7testing11EnvironmentESaIS2_EE5eraseEN9__gnu_cxx17__normal_iteratorIPS2_S4_EE_ZNSt6vectorIN7testing12TestPropertyESaIS1_EE8_M_eraseEN9__gnu_cxx17__normal_iteratorIPS1_S3_EES7_a_current_test_case_ZNSt6vectorIN7testing14TestPartResultESaIS1_EE4swapERS3_for_each<__gnu_cxx::__normal_iterator >, void (*)(testing::TestCase*)>_ZNKSt12_Vector_baseIPN7testing8TestInfoESaIS2_EE19_M_get_Tp_allocatorEv_ZNSt6vectorIPN7testing8TestCaseESaIS2_EE15_M_erase_at_endEPS2__ZNK7testing8TestCase14test_info_listEvRemoveInvalidXmlCharactersnew_allocator >_ZNKSt13_Bit_iterator13_M_const_castEv_ZNSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE14_M_fill_assignEjRKS3__ZN7testing32ScopedFakeTestPartResultReporteraSERKS0_ForEach, void (*)(testing::TestEventListener*)>_ZNKSt6vectorIPN7testing17TestEventListenerESaIS2_EE14_M_range_checkEj_ZNSt12_Vector_baseISsSaISsEE17_M_create_storageEj_ZNKSs17find_first_not_ofERKSsj_ZN9__gnu_cxx13new_allocatorISsE7destroyEPSs7lldiv_tregs_allocated_ZN9__gnu_cxx17__normal_iteratorIPiSt6vectorIiSaIiEEEmmEi_ZN7testing18TestEventListeners23SetDefaultResultPrinterEPNS_17TestEventListenerE_M_offset_ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EE4dataEv_ZN9__gnu_cxx17__normal_iteratorIPiSt6vectorIiSaIiEEEmmEvuninitialized_copy_ZNK7testing8TestInfo10type_paramEvint_p_cs_precedes_ZN7testing8internal18PrintCharAndCodeToIwwEEvT0_PSo_ZNKSt6vectorIPN7testing8TestCaseESaIS2_EE6rbeginEv__uninitialized_copy_a<__gnu_cxx::__normal_iterator >, testing::internal::TraceInfo*, testing::internal::TraceInfo>bsearch_ZNKSt6vectorIPN7testing8TestCaseESaIS2_EE14_M_range_checkEjshould_shard_ZNKSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE12_M_check_lenEjPKc_ZNK9__gnu_cxx17__normal_iteratorIPKSsSt6vectorISsSaISsEEEplEimon_grouping_M_deallocate_ZN9__gnu_cxx17__normal_iteratorIPPN7testing8internal29ParameterizedTestCaseInfoBaseESt6vectorIS4_SaIS4_EEEmmEiParseGoogleTestFlagsOnlyImpl_ZNKSs4rendEv_ZNKSbIwSt11char_traitsIwESaIwEE5rfindEwj_ZN9__gnu_cxx17__normal_iteratorIPPN7testing8internal29ParameterizedTestCaseInfoBaseESt6vectorIS4_SaIS4_EEEmmEv_ZNSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE5eraseEN9__gnu_cxx17__normal_iteratorIPS3_S5_EETestCasePassed_ZN7testing28FLAGS_gtest_death_test_styleE_M_replace_safe_ZNK7testing8internal12UnitTestImpl22test_case_to_run_countEvGetCapturedStdout__numeric_traits_integer_ZN7testing8internal24HasNewFatalFailureHelperD2Ev_ZNSbIwSt11char_traitsIwESaIwEE6insertEN9__gnu_cxx17__normal_iteratorIPwS2_EEjw_M_beginbasic_istream >_ZN7testing8internal38DefaultPerThreadTestPartResultReporteraSERKS1___kindlow_byte_Destroy >_old_offsetmbstowcs_ZNSt6vectorIN7testing14TestPartResultESaIS1_EE15_M_erase_at_endEPS1__ZNSt6vectorIPN7testing11EnvironmentESaIS2_EE4rendEv_ZNKSt12_Vector_baseIPN7testing11EnvironmentESaIS2_EE13get_allocatorEv_ZN9__gnu_cxx14__alloc_traitsISaIN7testing8internal9TraceInfoEEE8max_sizeERKS4__ZNSs7replaceEjjPKcFormatBooloperator<< basic_ios >_ZNKSt6vectorIN7testing8internal9TraceInfoESaIS2_EE3endEvuninitialized_copy~basic_streambuf_ZN9__gnu_cxx14__alloc_traitsISaIPKcEE7destroyERS3_PS2__ZNKSt18_Bit_iterator_baseeqERKS__cur_column_ZN7testing4Test18HasNonfatalFailureEvGetArgvsForDeathTestChildProcessoperator<< _ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EE3endEvFormatEpochTimeInMillisAsIso8601_ZNKSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE11_M_leftmostEv_ZNSt11char_traitsIcE6lengthEPKcFormatTestCount_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE23_M_get_insert_equal_posERKS1__ZN7testing8internal7PrintToEaPSo_S_construct_auxOnTestProgramEndreverse_iterator<__gnu_cxx::__normal_iterator > > >_M_value_ZNKSt6vectorIN7testing14TestPartResultESaIS1_EE4sizeEvpthread_self_ZN7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEE11ValueHolderD0Ev~_Rb_tree_impl_Tp1ShouldRunTestCase_ZNK7testing10TestResult16death_test_countEv__pred_iter_ZN9__gnu_cxx14__alloc_traitsISaIN7testing14TestPartResultEEE17_S_select_on_copyERKS3__ZNK7testing8internal24InternalRunDeathTestFlag4fileEv__copy_move_b_ZNSbIwSt11char_traitsIwESaIwEE12_M_leak_hardEv__destroyset_spawned_ZNKSt6vectorIPN7testing17TestEventListenerESaIS2_EE5emptyEv_ZNSt6vectorIPN7testing8TestCaseESaIS2_EE8pop_backEv__copy_move_a2GTEST_INFOtime_structFileNo_ZN7testing8internal14CapturedStreamaSERKS1_key_compDefaultPrintNonContainerTo_ZN9__gnu_cxx14__alloc_traitsISaIPN7testing8internal29ParameterizedTestCaseInfoBaseEEE8max_sizeERKS5__ZNSt6vectorIiSaIiEE8pop_backEv_ZN9__gnu_cxx24__numeric_traits_integerImE8__digitsE_ZNSt6vectorIiSaIiEE4backEvvalue_messageGTEST_FATAL_ZNKSs4_Rep12_M_is_leakedEv_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE11lower_boundERKSs_ZN7testing8TestCase10TestFailedEPKNS_8TestInfoEoperator[]_ZN7testing8internal24XmlUnitTestResultPrinter19IsValidXmlCharacterEc_ZNSt6vectorIPN7testing11EnvironmentESaIS2_EE4swapERS4__ZN7testing10TestResult5ClearEv_ZN9__gnu_cxx17__normal_iteratorIPKPN7testing11EnvironmentESt6vectorIS3_SaIS3_EEEmmEi_ZNK9__gnu_cxx13new_allocatorIPKcE7addressERKS2_strncmp_ZNKSs16find_last_not_ofEPKcjj__n2_ZN9__gnu_cxx17__normal_iteratorIPKPN7testing11EnvironmentESt6vectorIS3_SaIS3_EEEmmEvwint_t_ZNK7testing8internal24InternalRunDeathTestFlag8write_fdEv__cxa_guard_releasePrintCharsAsStringTo_ZNSt6vectorIN7testing12TestPropertyESaIS1_EE5eraseEN9__gnu_cxx17__normal_iteratorIPS1_S3_EES7__ZN7testing8internal27PrettyUnitTestResultPrinter25OnEnvironmentsTearDownEndERKNS_8UnitTestE_ZNSt12_Vector_baseIiSaIiEE12_Vector_impl12_M_swap_dataERS2_mblen__blkcnt_t__are_sameGetBoolAssertionFailureMessage_ZN7testing8internal23DefaultDeathTestFactoryD2Evoperator<< IsDirconnect_S_select_on_copy_ZNKSbIwSt11char_traitsIwESaIwEE8capacityEv_ZN7testing28FLAGS_gtest_catch_exceptionsE__uninitialized_copy_a_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE11_M_get_nodeEv_ZNSt6vectorIPN7testing8TestInfoESaIS2_EE4dataEv_ZN7testing8internal11ScopedTraceC2EPKciRKNS_7MessageE__nlink_tUniversalPrintexpected_value_ZN7testing8internal27PrettyUnitTestResultPrinter13OnTestCaseEndERKNS_8TestCaseE_ZNKSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE4sizeEv_ZN9__gnu_cxx14__alloc_traitsISaIN7testing12TestPropertyEEE7destroyERS3_PS2__S_ios_fmtflags_end_ZNKSbIwSt11char_traitsIwESaIwEE4findERKS2_jAssertionFailure_ZNSt6vectorIiSaIiEE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPiS1_EERKi_M_c__niter_base_ZNSt12_Vector_baseIPN7testing8TestInfoESaIS2_EE12_Vector_impl12_M_swap_dataERS5__ZNSt16reverse_iteratorIN9__gnu_cxx17__normal_iteratorIPPN7testing11EnvironmentESt6vectorIS4_SaIS4_EEEEEmIEi~scoped_ptr_M_n_M_p_ZNSt10_Iter_baseIPN7testing12TestPropertyELb0EE7_S_baseES2__M_t_ZNKSbIwSt11char_traitsIwESaIwEE8max_sizeEv_ZNKSt6vectorISsSaISsEEixEjMakeFileName_ZNKSt5ctypeIcE5widenEc_M_set_length_and_sharable_ZNSbIwSt11char_traitsIwESaIwEE7replaceEN9__gnu_cxx17__normal_iteratorIPwS2_EES6_NS4_IPKwS2_EES9___next_Rb_tree_const_iterator~_Vector_base_ZNKSbIwSt11char_traitsIwESaIwEE5beginEv__pfa_line_ZNSt11char_traitsIwE6lengthEPKw_ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EE6insertEN9__gnu_cxx17__normal_iteratorIPS2_S4_EEjRKS2__ZNKSt3setISsSt4lessISsESaISsEE8max_sizeEv_ZN7testing8TestCase14set_should_runEb_ZN9__gnu_cxx17__normal_iteratorIPN7testing8internal9TraceInfoESt6vectorIS3_SaIS3_EEEmmEi_ZN9__gnu_cxx17__normal_iteratorIPN7testing8internal9TraceInfoESt6vectorIS3_SaIS3_EEEmmEv_M_dataintercept_mode~TestCase_ZNKSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE8capacityEvexpected_predicate_value_IO_buf_endshort unsigned int_ZN9__gnu_cxx17__normal_iteratorIPiSt6vectorIiSaIiEEEpLEi_IO_backup_base_ZNSs6appendEPKcj_ZNSs12_S_constructIPcEES0_T_S1_RKSaIcESt20forward_iterator_tagTestPartFatallyFailed_ZN7testing11Environment8TearDownEv_ZNK7testing8internal10scoped_ptrISsE3getEv_ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EE8_M_eraseEN9__gnu_cxx17__normal_iteratorIPS2_S4_EES8_key_reportable_disabled_test_count_M_create_storageconstruct_ZNSt6vectorIPN7testing8TestInfoESaIS2_EE5beginEv__copy_move_a2_ZN7testing8internal6String23EndsWithCaseInsensitiveERKSsS3__ZN9__gnu_cxx13new_allocatorIPN7testing17TestEventListenerEE9constructEPS3_RKS3_iterator_traits_ZN9__gnu_cxx17__normal_iteratorIPPN7testing8internal29ParameterizedTestCaseInfoBaseESt6vectorIS4_SaIS4_EEEpLEi_ZNKSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE8max_sizeEv_ZN7testing8internal13CaptureStdoutEv__normal_iterator > >StringFromGTestEnv__s2_M_insert_equal__ZNKSs17find_first_not_ofEPKcjj_S_ios_seekdir_end_ZN7testing8internal35FLAGS_gtest_internal_run_death_testE_M_disposeGetCurrentOsStackTraceExceptTopreverse_iterator<__gnu_cxx::__normal_iterator, std::allocator >*, std::vector, std::allocator >, std::allocator, std::allocator > > > > >ios_base__copy_move_backward_a2_ZNSt17_Rb_tree_iteratorISsEppEv_shortbuf_ZN9__gnu_cxx14__alloc_traitsISaIPN7testing17TestEventListenerEEE8allocateERS4_j_ZNSt6vectorIPN7testing11EnvironmentESaIS2_EEaSERKS4_kDisableTestFilter_S_goodbit_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE14_M_create_nodeERKSs_M_insert_timespec_ZNKSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE5countERKS1__ZNSt12_Vector_baseIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE12_Vector_impl12_M_swap_dataERS6__ZN9__gnu_cxx14__alloc_traitsISaIPN7testing17TestEventListenerEEE10deallocateERS4_PS3_j_ZNKSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE4sizeEvTypeWithSize<8u>kTestsuites_vptr.TestPartResultReporterInterface_ZNSt6vectorIN7testing14TestPartResultESaIS1_EE8_M_eraseEN9__gnu_cxx17__normal_iteratorIPS1_S3_EES7__ZNK9__gnu_cxx13new_allocatorISt13_Rb_tree_nodeISsEE7addressERS2_this_test_name_Destroy*>_ZNSt6vectorIiSaIiEE5eraseEN9__gnu_cxx17__normal_iteratorIPiS1_EES5__ZNSt6vectorIN7testing12TestPropertyESaIS1_EE14_M_fill_assignEjRKS1_ChopLowBits_ZN7testing8internal13ColoredPrintfENS0_10GTestColorEPKczFDOpenIsNormalizableWhitespaceParseNaturalNumber_ZNKSbIwSt11char_traitsIwESaIwEE4findEPKwjjTEST_THREW_EXCEPTION_ZNSt6vectorIN7testing14TestPartResultESaIS1_EEaSERKS3_FormatCxxExceptionMessage_ZN7testing8internal24XmlUnitTestResultPrinter13EscapeXmlTextEPKcnegative_signoperator delete []__miter_basebegin_string_quoteoperator!= >__copy_move_a2term_ZNK7testing8UnitTest17current_test_infoEv__destroy_ZN7testing18TestEventListeners7ReleaseEPNS_17TestEventListenerE_ZNK9__gnu_cxx13new_allocatorIPN7testing8TestInfoEE7addressERS3__ZN7testing22EmptyTestEventListener27OnEnvironmentsTearDownStartERKNS_8UnitTestEkProtobufOneLinerMaxLength_ZN9__gnu_cxx17__normal_iteratorIPN7testing12TestPropertyESt6vectorIS2_SaIS2_EEEmmEiset_status_ZN7testing8internal13FloatingPointIdE8InfinityEvCmpHelperEQallowed_names_ZN9__gnu_cxx14__alloc_traitsISaIPN7testing17TestEventListenerEEE7destroyERS4_PS3__ZNK7testing14KilledBySignalclEi_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE5beginEv_ZNK9__gnu_cxx17__normal_iteratorIPKPN7testing17TestEventListenerESt6vectorIS3_SaIS3_EEEmiEioperator<< _ZNK7testing15AssertionResult15failure_messageEvlesselement_nameStringStreamToString_ZN7testing8internal29ParseInternalRunDeathTestFlagEvGenerate_ZNK9__gnu_cxx13new_allocatorIN7testing12TestPropertyEE8max_sizeEvpassed_ZN7testing8internal17TestEventRepeater9OnTestEndERKNS_8TestInfoE_ZNKSt13_Bit_iteratordeEv_ZN7testing8internal20SingleFailureCheckerD2Evtuple<>case_listcondition_ZN7testing8internal10scoped_ptrISsE5resetEPSs_ZN7testing8internal5MutexD2Ev~vector_ZN9__gnu_cxx14__alloc_traitsISaIPN7testing8internal29ParameterizedTestCaseInfoBaseEEE7destroyERS5_PS4__ZNSt6vectorIPN7testing8TestCaseESaIS2_EE5eraseEN9__gnu_cxx17__normal_iteratorIPS2_S4_EES8_mbtowccopy_backward_ZNSs4rendEv__cxa_end_catch__normal_iterator > >_ZNSt12_Vector_baseIPN7testing8TestCaseESaIS2_EE19_M_get_Tp_allocatorEv__is_move_iterator_ZN9__gnu_cxx17__normal_iteratorIPKPN7testing11EnvironmentESt6vectorIS3_SaIS3_EEEpLEi_ZNSs7replaceEjjRKSsjjCmpHelperGE_ZN7testing8internal12UnitTestImpl32SuppressTestEventsIfInSubprocessEvmax_ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EE18_M_fill_initializeEjRKS2___compar_fn_t__copy_move_backward_a*, std::basic_string*>CmpHelperGT_ZN7testing8internal24HasNewFatalFailureHelperaSERKS1_parent_table_sizetotal_shards__pid_type__pathGTestColoroperator()<__gnu_cxx::__normal_iterator > >_ZN7testing8internal26ThreadLocalValueHolderBaseD0Evoperator<< _ZN7testing8internal14CapturedStream17GetCapturedStringEv_ZNSt6vectorIN7testing12TestPropertyESaIS1_EE4rendEv__align__alloc_traits >_ZN7testing17TestEventListener22OnEnvironmentsSetUpEndERKNS_8UnitTestEiterator_traits_ZNSt11char_traitsIcE11eq_int_typeERKiS2__ZN9__gnu_cxx13new_allocatorISsE8allocateEjPKv_ZNKSt13_Bit_iteratorixEi_ZN9__gnu_cxx13new_allocatorIPN7testing11EnvironmentEE8allocateEjPKvflush >_ZNKSt6vectorISsSaISsEE14_M_range_checkEj_ZN7testing8internal12UnitTestImpl23ListTestsMatchingFilterEv_ZNSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE5beginEv~MessageSetValue_ZNK7testing14TestPartResult17nonfatally_failedEv_ZN7testing8internal15ParseStringFlagEPKcS2_PSs~NoExecDeathTest_ZNSt6vectorIPN7testing8TestInfoESaIS2_EE7reserveEj_ZNSs6assignERKSs_ZNSs6appendEjc_ZN7testing8internal18OsStackTraceGetter16UponLeavingGTestEv__normal_iterator > >_ZNSs4_Rep8_M_cloneERKSaIcEj_ZN7testing23FLAGS_gtest_random_seedE_ZNSt6vectorIPN7testing8TestCaseESaIS2_EE6assignEjRKS2_st_nlink_ZNK7testing18TestEventListeners22EventForwardingEnabledEvkFilterFlag__copy_move_backward_a2_ZNSt6vectorIPN7testing8TestInfoESaIS2_EE18_M_fill_initializeEjRKS2_basic_stringbuf, std::allocator >_ZN7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEEaSERKS6_MSG_PROXY_ZNSt11char_traitsIwE6assignEPwjw_S_compare_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE10_M_insert_EPSt18_Rb_tree_node_baseS9_RKS1__ZN7testing8internal16BoolFromGTestEnvEPKcb_ZNKSs5rfindEcj_ZNSt6vectorIPN7testing8TestInfoESaIS2_EE5eraseEN9__gnu_cxx17__normal_iteratorIPS2_S4_EES8__ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE10_S_minimumEPKSt18_Rb_tree_node_base__miter_base_ZN9__gnu_cxx14__alloc_traitsISaIPcEE8allocateERS2_j_ZN7testing8internal24XmlUnitTestResultPrinter21OutputXmlCDataSectionEPSoPKc__uninitialized_copy_a<__gnu_cxx::__normal_iterator*, std::vector > >, std::basic_string*, std::basic_string >_ZNSbIwSt11char_traitsIwESaIwEE7_M_moveEPwPKwjpipe_fd__sighandler_ttz_dsttime_M_put_node_ZNKSt3setIPKcSt4lessIS1_ESaIS1_EE4sizeEv__max_ZN9__gnu_cxx17__normal_iteratorIPN7testing8internal9TraceInfoESt6vectorIS3_SaIS3_EEEpLEi_S_leftai_family__begfdopen__copy_mfind_first_not_ofhas_new_fatal_failure_ZN9__gnu_cxx13new_allocatorIPN7testing11EnvironmentEE10deallocateEPS3_jlong double_ZNKSt6vectorIN7testing8internal9TraceInfoESaIS2_EE5emptyEva_status_ZN7testing8TestCase14test_info_listEvfilter_flaga_line_number_ZNK7testing8TestCase6FailedEv_ZNK9__gnu_cxx17__normal_iteratorIPcSsEplEi_Iter_ZNKSs13get_allocatorEv_ZNSt12_Vector_baseIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE11_M_allocateEj_ZN7testing17FLAGS_gtest_colorEreverse_iterator<__gnu_cxx::__normal_iterator > > >__k1munmap_ZN7testing8internal17StreamingListener9UrlEncodeEPKclocaleconvUniversalPrintCharArrayoperator!= >_ZN9__gnu_cxx14__alloc_traitsISaIPN7testing8TestCaseEEE8allocateERS4_j_ZNK7testing8internal14TestCaseNameIsclEPKNS_8TestCaseE__cxa_free_exception_M_mutate_Rb_tree_decrement_ZNKSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE11_M_leftmostEvkMaxCodePoint1kMaxCodePoint2kMaxCodePoint3kMaxCodePoint4wstring_S_construct__pred_iter__copy_move_backward_a__clock_t__fmtfl_ZNKSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE5emptyEvkStackTraceMarker_ZN7testing8internal17StreamingListener11OnTestStartERKNS_8TestInfoECmpHelperLE_ZNSt18_Rb_tree_node_base10_S_minimumEPS_rebind_ZN7testing8internal15TestFactoryBaseaSERKS1_CmpHelperLTinternal_run_death_test_flag_ZNKSt3setISsSt4lessISsESaISsEE5countERKSs_ZN7testing8internal21UniversalTersePrinterIPKcE5PrintES3_PSos2_expression_ZN7testing8internal18InitGoogleTestImplIwEEvPiPPT__Rb_tree, std::less, std::allocator >_S_on_swapfirst_fixture_id_ZN7testing4Test14RecordPropertyERKSsS2___copy_move_a__copy_move_backward_a2_ZN9__gnu_cxx14__alloc_traitsISaIPN7testing8internal29ParameterizedTestCaseInfoBaseEEE10deallocateERS5_PS4_j_ZNKSt15basic_streambufIcSt11char_traitsIcEE5egptrEv_ZNSt6vectorISsSaISsEE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPSsS1_EERKSs__uninit_copy_ZN7testing14IsNotSubstringEPKcS1_RKSbIwSt11char_traitsIwESaIwEES7__ZN9__gnu_cxx17__normal_iteratorIPKN7testing14TestPartResultESt6vectorIS2_SaIS2_EEEpLEi_M_get_node__mempositive_ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EE4swapERS4__ZNKSt3setIPKcSt4lessIS1_ESaIS1_EE10value_compEv_ZNSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE15_M_erase_at_endEPS3_test_part_results_CmpHelperNETestPartNonfatallyFailed_S_uppercase_ZN7testing8internal21ImplicitlyConvertibleIPKvS3_E5valueE_ZNK7testing8TestCase10should_runEvcopy_backwardGetTimeInMillis_ZNSt6vectorIPN7testing8TestInfoESaIS2_EEaSERKS4__ZNKSt6vectorIiSaIiEE6rbeginEv_ZNK9__gnu_cxx17__normal_iteratorIPiSt6vectorIiSaIiEEEplEiresult_typeoperator<< >_ZNSs12_S_constructIPKcEEPcT_S3_RKSaIcE_ZNKSt3setIPKcSt4lessIS1_ESaIS1_EE5emptyEvflip_ZN7testing8TestInfo3RunEvoperator- >_ZNSt6vectorIPN7testing11EnvironmentESaIS2_EE14_M_fill_assignEjRKS2__ZNK9__gnu_cxx17__normal_iteratorIPKPN7testing11EnvironmentESt6vectorIS3_SaIS3_EEEmiEiFLAGS_gtest_also_run_disabled_testsaddresslconvregfreeflag_enda_regexReadEntireFile_ZNK9__gnu_cxx17__normal_iteratorIPiSt6vectorIiSaIiEEEptEv_ZNKSbIwSt11char_traitsIwESaIwEE4sizeEv_ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EE5frontEvmkdir_ZNKSbIwSt11char_traitsIwESaIwEE3endEv_ZNSt6vectorISsSaISsEE6insertEN9__gnu_cxx17__normal_iteratorIPSsS1_EERKSsDIEDkQuoteBegin_ZNSt12_Vector_baseIPcSaIS0_EE19_M_get_Tp_allocatorEvreverse_iterator<__gnu_cxx::__normal_iterator > > >_ZN9__gnu_cxx13new_allocatorISt13_Rb_tree_nodeIPKcEE10deallocateEPS4_jeq_int_type_ZNK7testing8internal13FloatingPointIdE8sign_bitEvgtest_output_flagnpos_ZN7testing8TestCase10TestPassedEPKNS_8TestInfoE_ZNKSt6vectorIN7testing12TestPropertyESaIS1_EE6rbeginEvabs_error_expr_ZNSt6vectorISsSaISsEE5frontEvHasFatalFailure_ZNSt18_Rb_tree_node_base10_S_maximumEPKS_strdupinternal2__uninitialized_copy_aoperator- >_ZN7testing4Test10HasFailureEv_ZNK9__gnu_cxx17__normal_iteratorIPKSsSt6vectorISsSaISsEEEmiEi_ZNKSs6_M_repEv__uninit_copy_ZN9__gnu_cxx13new_allocatorIN7testing14TestPartResultEE8allocateEjPKv__normal_iteratorpost_flag_parse_init_performed__ZN7testing8internal32FormatEpochTimeInMillisAsIso8601Ex_ZN7testing8internal10scoped_ptrINS0_16DeathTestFactoryEE7releaseEv_ZN7testing8internal17g_executable_pathEstack_grows_down_ZNSt3setIPKcSt4lessIS1_ESaIS1_EE11upper_boundERKS1_posix_ZNSt6vectorIPN7testing11EnvironmentESaIS2_EE3endEvvector_ZN7testing8internal18ParseNaturalNumberIiEEbRKSsPT__ZNK7testing8internal9MutexBase10AssertHeldEv_ZN7testing8internal17TestEventRepeater15OnTestCaseStartERKNS_8TestCaseE_M_allocate_ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EE14_M_fill_insertEN9__gnu_cxx17__normal_iteratorIPS2_S4_EEjRKS2__ZNKSs6rbeginEvnum_readpstr_M_erase_aux_Construct_ZNSt6vectorIiSaIiEE9push_backERKi__minOutputXmlAttribute_ZNSt6vectorIPN7testing8TestInfoESaIS2_EE6rbeginEvkTestShardStatusFile_ZNKSt6vectorIPN7testing17TestEventListenerESaIS2_EE3endEv__ownerSetup_should_be_spelled_SetUpoperator<< _ZNSt6vectorIPN7testing11EnvironmentESaIS2_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS2_S4_EERKS2__ZN7testing8internal17GetCapturedStreamEPPNS0_14CapturedStreamE_Construct, char const*>_ZNKSbIwSt11char_traitsIwESaIwEE7_M_iendEv_ZN7testing8internal11ShouldShardEPKcS2_b_ZNSt12_Vector_baseIPN7testing8TestInfoESaIS2_EE17_M_create_storageEj_ZN7testing10TestResultC2Ev_ZNSs4_Rep15_M_set_sharableEvsa_family_t_M_bump_up_ZN7testing8internal18StreamableToStringIiEESsRKT__ZN7testing8internal17TestEventRepeater18OnTestIterationEndERKNS_8UnitTestEi_ZNSbIwSt11char_traitsIwESaIwEE5beginEvswapiterator_traits_ZNKSt6vectorIPN7testing8TestInfoESaIS2_EE5emptyEv_ZSt16__throw_bad_castv_ZNK7testing8internal12UnitTestImpl16total_test_countEv_vtable_offsetSetUpTestCaseFuncwctrans_t_ZNK7testing8UnitTest11random_seedEv__addressofOVERSEE_TEST_ZNKSt3setISsSt4lessISsESaISsEE8key_compEv_ZN7testing8internal24XmlUnitTestResultPrinterC2EPKcdot_extension_ZNSs7replaceEN9__gnu_cxx17__normal_iteratorIPcSsEES2_PKcS4_set_forwarding_enabled_M_impl_ZN7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEE11ValueHolderD2Evsi_sigvalvwprintf_ZN7testing8TestInfo26increment_death_test_countEv_M_range_check_ZNSt23_Rb_tree_const_iteratorIPKcEppEipremature_exit_filepath~GTestFlagSaver_ZNSs7replaceEN9__gnu_cxx17__normal_iteratorIPcSsEES2_NS0_IPKcSsEES5_CheckedDowncastToActualType::ValueHolder, testing::internal::ThreadLocalValueHolderBase>_ZNSt23_Rb_tree_const_iteratorIPKcEppEv_ZNK7testing8internal12UnitTestImpl12elapsed_timeEv_ZNKSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE8key_compEv_ZNKSt6vectorIPN7testing8TestInfoESaIS2_EE8capacityEv_ZNK9__gnu_cxx13new_allocatorIPN7testing8TestInfoEE7addressERKS3__ZNK7testing15AssertionResultcvbEvCountIf, bool (*)(const testing::TestInfo*)>_ZNK7testing8TestInfo14test_case_nameEv_ZN7testing8internal2RE9FullMatchERKSsRKS1__ZN7testing8internal13FloatingPointIdE38DistanceBetweenSignAndMagnitudeNumbersERKyS4__ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EE18_M_fill_initializeEjRKS2__ZNK9__gnu_cxx17__normal_iteratorIPPN7testing8TestInfoESt6vectorIS3_SaIS3_EEEdeEvkStdOutFileno_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEEaSERKS5__ZNKSt6vectorISsSaISsEE8capacityEv_ZNSbIwSt11char_traitsIwESaIwEE13_S_copy_charsEPwS3_S3_fastst_modean_index_ZNKSt6vectorIN7testing8internal9TraceInfoESaIS2_EE8capacityEv_ZN9__gnu_cxx14__alloc_traitsISaIN7testing8internal9TraceInfoEEE8allocateERS4_jiterator_traits_ZNSbIwSt11char_traitsIwESaIwEE7replaceEjjjw_ZN9__gnu_cxx24__numeric_traits_integerIsE5__maxE_ZNSt6vectorISsSaISsEE8pop_backEv_ZNK9__gnu_cxx17__normal_iteratorIPPcSt6vectorIS1_SaIS1_EEEplEi_ZNKSt6vectorIiSaIiEE14_M_range_checkEj_ZNSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EEaSERKS5__InputIterator_S_skipws_GLOBAL__sub_I_gtest_all.ccdest_ptrpthread_getspecific_ZNKSt6vectorISsSaISsEE8max_sizeEv_ZNK7testing8internal12UnitTestImpl17current_test_infoEv_ZN9__gnu_cxx14__alloc_traitsISaIiEE10deallocateERS1_Pij__copy_move_backward_a2_ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EE14_M_fill_insertEN9__gnu_cxx17__normal_iteratorIPS2_S4_EEjRKS2__M_leftmost_ZNKSt3setIPKcSt4lessIS1_ESaIS1_EE6rbeginEv_ZN7testing8internal27CheckedDowncastToActualTypeINS0_11ThreadLocalISt6vectorINS0_9TraceInfoESaIS4_EEE11ValueHolderENS0_26ThreadLocalValueHolderBaseEEEPT_PT0__ZNKSt6vectorIN7testing8internal9TraceInfoESaIS2_EE8max_sizeEv_ZNSt6vectorIN7testing12TestPropertyESaIS1_EE8pop_backEv_ZN7testing8TestCase12TestDisabledEPKNS_8TestInfoE_ZNK9__gnu_cxx17__normal_iteratorIPPN7testing8TestInfoESt6vectorIS3_SaIS3_EEEixEibits__ZN7testing22EmptyTestEventListenerD0Ev__uninitialized_move_if_noexcept_a >_ZN7testing17TestEventListeneraSERKS0___uninit_copy_ZNSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE4swapERS5__ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE24_M_get_insert_unique_posERKSs_M_get_insert_hint_equal_pos_M_move_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE8_S_rightEPSt18_Rb_tree_node_base__niter_base_ZNK7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE16GetOrCreateValueEv_ZNSs13_S_copy_charsEPcS_S__ZNSt10_Iter_baseIPPN7testing17TestEventListenerELb0EE7_S_baseES3__ZNSt6vectorIN7testing14TestPartResultESaIS1_EE6resizeEjS1__ZNK9__gnu_cxx17__normal_iteratorIPSsSt6vectorISsSaISsEEE4baseEvoperator<< >_ZN7testing8internal38DefaultPerThreadTestPartResultReporterD0Ev_ZNKSbIwSt11char_traitsIwESaIwEE17find_first_not_ofERKS2_jnext_seed_ZNKSt12_Vector_baseIPN7testing17TestEventListenerESaIS2_EE19_M_get_Tp_allocatorEv_ZNKSt6vectorIN7testing14TestPartResultESaIS1_EE14_M_range_checkEjdefault_result_printer_pfile_ZNSs12_S_constructIPKcEEPcT_S3_RKSaIcESt20forward_iterator_tag_ZN9__gnu_cxx13new_allocatorIPKcE10deallocateEPS2_j_ZN7testing8internal24XmlUnitTestResultPrinter9EscapeXmlERKSsbwctob_ZNKSt6vectorISsSaISsEE5beginEv_IO_save_end_ZNK7testing8internal12UnitTestImpl19disabled_test_countEvst_gidrelative_path__are_same_ZN7testing8internal9DeathTest11LastMessageEv__normal_iterator > >_ZN7testing8internal12UnitTestImpl20set_catch_exceptionsEb_ZN7testing22EmptyTestEventListener16OnTestProgramEndERKNS_8UnitTestE__ioinit_ZNKSs8capacityEv_DestroykFractionBitCount__gid_t__are_same, std::allocator >*, std::basic_string, std::allocator >*>new_allocatorFClose_ZN7testing8internal9EqFailureEPKcS2_RKSsS4_bIsUtf16SurrogatePair_ZNK7testing8UnitTest17current_test_caseEv_ZNSs5eraseEjj_ZNKSs4dataEv_ZN7testing8internal18OsStackTraceGetteraSERKS1_construct_ZNSt23_Rb_tree_const_iteratorISsEppEi_ZN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEEaSERKS4_PrintAsCharLiteralTo_ZN9__gnu_cxx17__normal_iteratorIPiSt6vectorIiSaIiEEEmIEistr_len_ZNSt23_Rb_tree_const_iteratorISsEppEv__uninitialized_move_if_noexcept_a >UniversalPrint >ClearNonAdHocTestResult_ZNKSt23_Rb_tree_const_iteratorIPKcEptEv_ZN7testing17TestEventListener16OnTestProgramEndERKNS_8UnitTestE_ZN7testing8internal6String15FormatIntWidth2Eioperator== >_ZNKSs6lengthEvSetDefaultXmlGenerator_ZN7testing8internal16WideStringToUtf8EPKwiwcsftime_ZNKSs8max_sizeEv~DefaultGlobalTestPartResultReporter_FwdIterator_ZN7testing8internal14CmpHelperSTREQEPKcS2_PKwS4__ZN7testing8internal6IsTrueEbtear_down_tc_ZNSt12_Vector_baseIN7testing14TestPartResultESaIS1_EE17_M_create_storageEj_ZNSt6vectorIPN7testing8TestInfoESaIS2_EE6resizeEjS2__ZN7testing8internal17StreamingListener6SendLnERKSs_ZNK9__gnu_cxx17__normal_iteratorIPKN7testing14TestPartResultESt6vectorIS2_SaIS2_EEEplEi_ZNK7testing8TestCase19disabled_test_countEv_ZNKSbIwSt11char_traitsIwESaIwEE4_Rep12_M_is_leakedEv_ZNK9__gnu_cxx17__normal_iteratorIPKPN7testing8TestInfoESt6vectorIS3_SaIS3_EEE4baseEv_ZNSt17_Rb_tree_iteratorISsEmmEi_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE10_S_maximumEPSt18_Rb_tree_node_base_ZN7testing8TestCase18GetMutableTestInfoEi_ZNK9__gnu_cxx17__normal_iteratorIPKPN7testing8TestInfoESt6vectorIS3_SaIS3_EEEplEiholder_base_ZNSt17_Rb_tree_iteratorISsEmmEv_ZNSt12__alloc_swapISaISsELb1EE8_S_do_itERS0_S2_argumentpartial_regex__ZN7testing8internal19TypedTestCasePState11AddTestNameEPKciS3_S3_ConcatPaths_ZN7testing8internal15TestFactoryBase10CreateTestEv__pointer_ZN7testing8internal35DefaultGlobalTestPartResultReporterD2Evnegative_ZN9__gnu_cxx14__alloc_traitsISaIPN7testing8internal29ParameterizedTestCaseInfoBaseEEE10_S_on_swapERS5_S7__ZN9__gnu_cxx13new_allocatorIN7testing8internal9TraceInfoEE9constructEPS3_RKS3__S_boolalpha_ZNSbIwSt11char_traitsIwESaIwEE6assignEjw_ZNK7testing8internal12UnitTestImpl17test_to_run_countEvtest_shard_file__uninit_copy__initialize_pAppendMessage_ZN9__gnu_cxx14__alloc_traitsISaISsEE10_S_on_swapERS1_S3_targetarg_string_ZN7testing8TestCase12ShuffleTestsEPNS_8internal6RandomE_ZNK7testing8UnitTest17test_to_run_countEv_ZN7testing8internal27OsStackTraceGetterInterface17CurrentStackTraceEii__copy_move_backward_anew_allocatortest_info_listHONOR_SHARDING_PROTOCOL_ZNSt6vectorIN7testing14TestPartResultESaIS1_EE4backEv_ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EE4rendEvelapsed_time__ZNSt6vectorIPN7testing11EnvironmentESaIS2_EE4dataEv_ZNKSt6vectorIPN7testing8TestInfoESaIS2_EE4backEv_ZNSt6vectorIN7testing14TestPartResultESaIS1_EE5eraseEN9__gnu_cxx17__normal_iteratorIPS1_S3_EES7_execveg_in_fast_death_test_childTestPropertiesAsXmlAttributesdummy__ZN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEED2Ev_ZN7testing8internal20StringStreamToStringEPSt18basic_stringstreamIcSt11char_traitsIcESaIcEEstream_name_ZN9__gnu_cxx13new_allocatorIiE10deallocateEPij_Pointer_Rb_tree_insert_and_rebalance_ZNSt11char_traitsIwE6assignERwRKwuninitialized_copyin_subprocess_for_death_test_ZNK9__gnu_cxx13new_allocatorIPKcE7addressERS2_for_each > >, void (*)(testing::Environment*)>_ZN9__gnu_cxx17__normal_iteratorIPN7testing14TestPartResultESt6vectorIS2_SaIS2_EEEmIEifound_Destroy_ZNK9__gnu_cxx17__normal_iteratorIPPN7testing8TestCaseESt6vectorIS3_SaIS3_EEEdeEv_ZN7testing8internal29ParameterizedTestCaseInfoBase13RegisterTestsEvShouldUseColorcopy_backwarditerator_categoryPrintXmlUnitTest_S_eofbit_ZN7testing8internal17TestEventRepeater16OnTestPartResultERKNS_14TestPartResultEoperator<< _Iter_predfailed_test_countassertion_result_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE8_S_valueEPKSt13_Rb_tree_nodeISsE__nusers_ZNKSt12_Vector_baseIPN7testing8TestInfoESaIS2_EE13get_allocatorEv_M_capacityoperator== >~Init_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE7_S_leftEPKSt18_Rb_tree_node_base_filenoDoubleLEoperator|=severity_ZNKSt6vectorIPN7testing11EnvironmentESaIS2_EEixEj_ZNSt11char_traitsIcE6assignERcRKcCaptureStderr_ZNK7testing8internal8FilePath19RemoveDirectoryNameEvCreateTest~TestPartResult_ZNK7testing8internal13FloatingPointIdE6is_nanEvoperator<< _ZN7testing8internal18StreamableToStringIPcEESsRKT__ZNKSt6vectorIN7testing12TestPropertyESaIS1_EE5beginEv_ZN9__gnu_cxx17__normal_iteratorIPKPN7testing11EnvironmentESt6vectorIS3_SaIS3_EEEmIEi_ZN7testing8internal9DeathTest10AssumeRoleEv_ZNKSt6vectorIiSaIiEE2atEjHasNonfatalFailureFormatWordListvector >_ZNSt6vectorIiSaIiEE5clearEv_M_color_ZN7testing8TestCase13ShouldRunTestEPKNS_8TestInfoE_ZNK9__gnu_cxx17__normal_iteratorIPPN7testing8TestCaseESt6vectorIS3_SaIS3_EEEixEi_ZNSbIwSt11char_traitsIwESaIwEEaSERKS2__ZN7testing8internal8GTestLog9GetStreamEv_ZN7testing8internal27OsStackTraceGetterInterfaceaSERKS1_internal_flag_ZNSt12_Vector_baseISsSaISsEE11_M_allocateEjignore_sigprof_actionOnTestIterationEnd_ZNKSt6vectorIN7testing12TestPropertyESaIS1_EE5frontEvscoped_ptr_ZNKSs3endEv_ZNK7testing8internal8FilePath6stringEv_ZNSt6vectorIPcSaIS0_EE6assignEjRKS0__ZN9__gnu_cxx13new_allocatorIPN7testing17TestEventListenerEE10deallocateEPS3_j_ZN7testing8internal13FloatingPointIfE38DistanceBetweenSignAndMagnitudeNumbersERKjS4_getpagesize_ZNKSt6vectorIPcSaIS0_EE14_M_range_checkEj_ZNSt6vectorIPcSaIS0_EE14_M_fill_assignEjRKS0__ZNK7testing8internal10scoped_ptrISsEdeEv_ZNSo5writeEPKci_ZN7testing22FLAGS_gtest_list_testsE_ZNKSbIwSt11char_traitsIwESaIwEE16find_last_not_ofERKS2_jctype__socklen_t_ZNSt11char_traitsIwE4moveEPwPKwj_ZNK9__gnu_cxx17__normal_iteratorIPPN7testing11EnvironmentESt6vectorIS3_SaIS3_EEEplEiFloatLEStreamWideCharsToMessage_ZNSt6vectorIN7testing12TestPropertyESaIS1_EE6resizeEjS1__ZN7testing10TestResult26increment_death_test_countEv_ZNSt6vectorIN7testing12TestPropertyESaIS1_EE8_M_eraseEN9__gnu_cxx17__normal_iteratorIPS1_S3_EEoperator==, std::allocator >partial_regexsival_ptrHasSameFixtureClass_Destroyproperty_name_ZNSt6vectorIPN7testing11EnvironmentESaIS2_EE2atEj_M_refcountis_runnable_ZN7testing8internal17TestEventRepeater22OnEnvironmentsSetUpEndERKNS_8UnitTestE_ZNK7testing14TestPartResult4typeEv_ZNK9__gnu_cxx17__normal_iteratorIPPN7testing17TestEventListenerESt6vectorIS3_SaIS3_EEEplEi~TestInfo__dev_t_ZN7testing8internal17StreamingListener12SocketWriterD2Ev_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE14_M_lower_boundEPSt13_Rb_tree_nodeISsES8_RKSsIsTrue_ZNSt12_Vector_baseIPN7testing17TestEventListenerESaIS2_EE19_M_get_Tp_allocatorEv_M_bump_downfull_pathnameEXECUTE_TESTMSG_ERRQUEUE__uninitialized_copy_a*, std::basic_string*, std::basic_string >new_allocator_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE5eraseESt23_Rb_tree_const_iteratorISsES7__ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EE5eraseEN9__gnu_cxx17__normal_iteratorIPS2_S4_EES8__ZN7testing8internal20ExitedUnsuccessfullyEi_ZNKSt6vectorIPN7testing8TestInfoESaIS2_EE4sizeEv_ZN7testing7MessagelsEPKw_Bit_iterator_ZN9__gnu_cxx17__normal_iteratorIPN7testing8internal9TraceInfoESt6vectorIS3_SaIS3_EEEmIEi_ZNK7testing8UnitTest16total_test_countEvfseek~DeathTestFactory_ZN7testing18TestEventListenersC2Evbasic_stringstream, std::allocator >ptrdiff_t_ZN7testing8internal14ShouldUseColorEb_ZN7testing8internal12ShuffleRangeIiEEvPNS0_6RandomEiiPSt6vectorIT_SaIS5_EEset, std::allocator >_Distance_archF_OWNER_PIDwmemmove~TestResultset_outcome__destroy__alloc_traits >_ZNK9__gnu_cxx17__normal_iteratorIPcSsEmiEi_ZSt24__throw_out_of_range_fmtPKcz_ZNSt6vectorIN7testing12TestPropertyESaIS1_EE6insertEN9__gnu_cxx17__normal_iteratorIPS1_S3_EERKS1_GetLastErrnoDescriptionwcrtombwstrclear_ZNKSt6vectorIPN7testing8TestInfoESaIS2_EE3endEv_ZN9__gnu_cxx13new_allocatorIPN7testing8internal29ParameterizedTestCaseInfoBaseEE9constructEPS4_RKS4__ZN9__gnu_cxx13new_allocatorIPN7testing8internal29ParameterizedTestCaseInfoBaseEE10deallocateEPS4_j__check_facet >_ZN7testing8internal17TestEventRepeater18OnTestProgramStartERKNS_8UnitTestE_ZNK9__gnu_cxx17__normal_iteratorIPPN7testing8internal29ParameterizedTestCaseInfoBaseESt6vectorIS4_SaIS4_EEEplEi_ZNK7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEE16GetOrCreateValueEv__espins_ZNSsaSEPKcdefault_result_printer_ZNK9__gnu_cxx17__normal_iteratorIPN7testing8internal9TraceInfoESt6vectorIS3_SaIS3_EEEplEi_ZNSbIwSt11char_traitsIwESaIwEE3endEvrm_eo_ZN7testing8TestCase19ClearTestCaseResultEPS0_operator<< _ZNSs14_M_replace_auxEjjjcWriteToShardStatusFileIfNeeded_Rep_baseenv_varvalue_holderfirst_test_info_ZNSspLEckPrintTimeFlag_ZNSt3setIPKcSt4lessIS1_ESaIS1_EE6insertESt23_Rb_tree_const_iteratorIS1_ERKS1__ZN7testing10TestResult20ClearTestPartResultsEv__copy_move_backward_anew_allocator, std::allocator > >MSG_FINreverse_iterator<__gnu_cxx::__normal_iterator > > >st_atim_ZN7testing11Environment5SetUpEvst_dev_ZNSt6vectorIPN7testing11EnvironmentESaIS2_EE14_M_fill_insertEN9__gnu_cxx17__normal_iteratorIPS2_S4_EEjRKS2__ZN9__gnu_cxx17__normal_iteratorIPKN7testing14TestPartResultESt6vectorIS2_SaIS2_EEEmIEi__is_signedcountsCloseConnection__state_ZNKSt3setISsSt4lessISsESaISsEE4sizeEv_ZN7testing18TestEventListeners6AppendEPNS_17TestEventListenerE_ZNSt6vectorIPN7testing8TestInfoESaIS2_EE15_M_erase_at_endEPS2__ZN9__gnu_cxx24__numeric_traits_integerIcE5__maxE_ZNKSbIwSt11char_traitsIwESaIwEE17find_first_not_ofEPKwjj_ZN7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEE7pointerEvGetTestCaseName_ZNKSt14_Bit_referenceeqERKS__ZNKSbIwSt11char_traitsIwESaIwEE5emptyEvMSG_CTRUNC__normal_iterator > >_ZNK9__gnu_cxx17__normal_iteratorIPKPN7testing11EnvironmentESt6vectorIS3_SaIS3_EEEptEv__alloc_traits >_ZN7testing8internal2REaSERKS1__ZN7testing8internal12UnitTestImpl17gtest_trace_stackEvnum_failuresenvironments_Delete__copy_move_b_M_insert_ZN9__gnu_cxx13new_allocatorIwE10deallocateEPwj_ZN7testing8internal10scoped_ptrIKSsEaSERKS3__ZN9__gnu_cxx14__alloc_traitsISaIPN7testing8TestCaseEEE7destroyERS4_PS3_PrintTestPartResult__copy_move_backward_a2*, std::basic_string*>_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE11equal_rangeERKSsgtest_ar__Identity, std::allocator > >AlwaysTrueoperator<< >set_current_test_infoTEST_DID_NOT_DIEwcscollopenmode_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE11_M_leftmostEvvalue_~TestPropertyoperator!= >_ZN7testing8internal27FormatTimeInMillisAsSecondsEx_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE13_Rb_tree_implIS3_Lb0EE13_M_initializeEv__last_ZNK9__gnu_cxx17__normal_iteratorIPKPN7testing8TestInfoESt6vectorIS3_SaIS3_EEEdeEv_ZNK9__gnu_cxx17__normal_iteratorIPKSsSt6vectorISsSaISsEEEptEv_ZNK7testing8internal12UnitTestImpl30reportable_disabled_test_countEvOnTestCaseStart__prioritydeath_test_style_kCatchExceptionsFlag_ZNSs12_S_constructEjcRKSaIcE__addressofuninitialized_copy*>death_test_factory_ZN9__gnu_cxx14__alloc_traitsISaIN7testing14TestPartResultEEE8max_sizeERKS3__ZNSs7_M_moveEPcPKcj__copy_move_backward_a_ZNSt18_Rb_tree_node_base10_S_minimumEPKS__ZNSt12_Vector_baseIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE13_M_deallocateEPS3_j__time_t_ZN7testing8internal17StreamingListener20AbstractSocketWriteraSERKS2_signum__miter_base*>_ZN7testing8TestCase3RunEv_ZNKSbIwSt11char_traitsIwESaIwEE7compareEjjRKS2_jj_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE8_S_valueEPKSt18_Rb_tree_node_baseFloatingPoint_ZN9__gnu_cxx14__alloc_traitsISaIPN7testing17TestEventListenerEEE17_S_select_on_copyERKS4_fgetwc_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE4swapERS5__ZN7testing8internal12UnitTestImpl18GetMutableTestCaseEi_ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EE4rendEv_ZNKSt6vectorIN7testing8internal9TraceInfoESaIS2_EE6rbeginEv_ZNSt6vectorIN7testing12TestPropertyESaIS1_EE4dataEv_ZNSt6vectorIPN7testing11EnvironmentESaIS2_EE6insertEN9__gnu_cxx17__normal_iteratorIPS2_S4_EERKS2__ZNK7testing8internal12UnitTestImpl26successful_test_case_countEvnew_allocator_ZN9__gnu_cxx17__normal_iteratorIPKN7testing14TestPartResultESt6vectorIS2_SaIS2_EEEmmEiParseBoolFlagParseInt32OnTestStartread_fd__ZN7testing8internal27PrettyUnitTestResultPrinter18OnTestIterationEndERKNS_8UnitTestEicolor__ZN9__gnu_cxx17__normal_iteratorIPKN7testing14TestPartResultESt6vectorIS2_SaIS2_EEEmmEv_ZNSs6resizeEj__vtbl_ptr_typeGTestIsInitialized_Is_pod_comparator__destroy_ZN7testing19FLAGS_gtest_shuffleEGetInjectableArgvsFormatDeathTestOutput_ZNKSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE11equal_rangeERKSs_ZNSbIwSt11char_traitsIwESaIwEEaSEwunary_function, std::allocator >, std::basic_string, std::allocator > >_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE7_S_leftEPSt18_Rb_tree_node_base__gnuc_va_listdeath_test_factory__ZNKSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE8_M_beginEv__builtin_memmoveGetOrCreateValue_ZNK7testing8internal8FilePath15DirectoryExistsEvThreadLocal_ZN9__gnu_cxx14__alloc_traitsISaIPcEE7destroyERS2_PS1__ZNKSt6vectorIN7testing14TestPartResultESaIS1_EE3endEv_ZNSt23_Rb_tree_const_iteratorIPKcEmmEi_ZN7testing11IsSubstringEPKcS1_RKSsS3__flags2_ZNSt23_Rb_tree_const_iteratorIPKcEmmEv_ZNKSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE21_M_get_Node_allocatorEv~HasNewFatalFailureHelper_ZN9__gnu_cxx14__alloc_traitsISaIPN7testing8TestInfoEEE8max_sizeERKS4_thisbasic_ostream >_ZNKSt6vectorIPN7testing11EnvironmentESaIS2_EE4dataEv_ZNSt6vectorIPN7testing8TestInfoESaIS2_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS2_S4_EERKS2__ZStplIcSt11char_traitsIcESaIcEESbIT_T0_T1_EPKS3_RKS6__ZNK9__gnu_cxx17__normal_iteratorIPSsSt6vectorISsSaISsEEEplEiclose_fd_ZN9__gnu_cxx17__normal_iteratorIPPN7testing17TestEventListenerESt6vectorIS3_SaIS3_EEEppEikDeathTestInternalErrorrandom___is_move_iterator_ZN7testing8internal30ReportFailureInUnknownLocationENS_14TestPartResult4TypeERKSs_ZNSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE3endEv_ZNK9__gnu_cxx13new_allocatorISt13_Rb_tree_nodeIPKcEE7addressERKS4__ZNK7testing8UnitTest6FailedEv_ZN9__gnu_cxx13new_allocatorISt13_Rb_tree_nodeIPKcEE8allocateEjPKvsrcfile__miter_basewmemchr_ZN7testing18TestEventListeners8repeaterEvIsPrintableAsciiGetTypeId_ZNK9__gnu_cxx17__normal_iteratorIPPcSt6vectorIS1_SaIS1_EEEmiEiiswctypethis_is_TEST_ZNKSt9basic_iosIcSt11char_traitsIcEE7rdstateEv_Rb_tree_iterator__builtin_strlen_ZNKSs4copyEPcjj_ZN9__gnu_cxx14__alloc_traitsISaIPN7testing8TestInfoEEE10deallocateERS4_PS3_j__is_normal_iterator, std::allocator >*>__uninitialized_copy_ZN7testing8internal15NoExecDeathTest10AssumeRoleEv_ZN7testing15AssertionResultaSERKS0__ZNK9__gnu_cxx17__normal_iteratorIPN7testing12TestPropertyESt6vectorIS2_SaIS2_EEEplEicatch_exceptions__ZN7testing11Environment5SetupEv__ssize_t__niter_base<__gnu_cxx::__normal_iterator > >_ZNKSt6vectorIPN7testing8TestInfoESaIS2_EE8max_sizeEv_InIteratorgtest_msg_ZN7testing8internal16UniversalPrinterIxE5PrintERKxPSo_ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EE5eraseEN9__gnu_cxx17__normal_iteratorIPS2_S4_EES8_chdirsival_intstrtod_ZNK7testing8TestCase21successful_test_countEvStreamableToString_ZNKSbIwSt11char_traitsIwESaIwEE4findEPKwjReportInvalidTestCaseTypeUnsignedChar_ZN7testing8internal10scoped_ptrINS0_17StreamingListener20AbstractSocketWriterEE7releaseEv_ZN7testing8internal17StreamingListenerD2Ev_ZNKSs16find_last_not_ofEcjPatternMatchesStringgtest_retval_ZN7testing8internal18StringFromGTestEnvEPKcS2__ZN7testing8internal13FloatingPointIfE15ReinterpretBitsEjstack_top_ZN7testing8internal38DefaultPerThreadTestPartResultReporter20ReportTestPartResultERKNS_14TestPartResultEPrintOnOneLinebasic_iostream >_ZNKSbIwSt11char_traitsIwESaIwEE4findEwj_ZNSs6insertEjjc__fmtkFractionBitMask_ZN7testing22EmptyTestEventListener18OnTestIterationEndERKNS_8UnitTestEi_ZNSbIwSt11char_traitsIwESaIwEE4_Rep13_M_set_leakedEv_ZN7testing8internal29ParameterizedTestCaseRegistry13RegisterTestsEv_ZNKSt6vectorIPcSaIS0_EE4rendEvkSuccessOutputXmlCDataSectionGetCapturedStreamRemoveFileName__uninitialized_move_if_noexcept_a >_ZNSbIwSt11char_traitsIwESaIwEE2atEj_ZNSbIwSt11char_traitsIwESaIwEEixEj_ZNSbIwSt11char_traitsIwESaIwEE6insertEjPKw_ZNSt23_Rb_tree_const_iteratorISsEmmEiparse_success_ZNSbIwSt11char_traitsIwESaIwEE7replaceEN9__gnu_cxx17__normal_iteratorIPwS2_EES6_PKwS8_DeathTestAbort_ZNSt23_Rb_tree_const_iteratorISsEmmEvcolon__uninitialized_move_if_noexcept_a >_vptr.Environment_Destroy_ZNSt11char_traitsIcE7compareEPKcS2_j_ZN7testing8internal14CmpHelperSTREQEPKcS2_S2_S2__ZNSt6vectorIPN7testing11EnvironmentESaIS2_EE4backEvreverse_iterator<__gnu_cxx::__normal_iterator > > >RemoveDirectoryName_ZN7testing8internal21ImplicitlyConvertibleIPKvS3_E6HelperES3__Rep_typeis_disabled~basic_ios__niter_base_ZNSt12_Vector_baseIPN7testing8TestInfoESaIS2_EE13_M_deallocateEPS2_jcontentShouldRunTestReportTestPartResult_ZNSt6vectorIN7testing14TestPartResultESaIS1_EE2atEj__normal_iterator > >_ZN9__gnu_cxx17__normal_iteratorIPKN7testing8internal9TraceInfoESt6vectorIS3_SaIS3_EEEppEi_ZNK9__gnu_cxx17__normal_iteratorIPKN7testing14TestPartResultESt6vectorIS2_SaIS2_EEEmiEi_ZNKSt23_Rb_tree_const_iteratorISsEdeEv_ZNKSt6vectorIPN7testing8TestInfoESaIS2_EE6rbeginEv_M_fill_insertAddTestName_ZN9__gnu_cxx17__normal_iteratorIPKN7testing8internal9TraceInfoESt6vectorIS3_SaIS3_EEEppEv_ZNK9__gnu_cxx17__normal_iteratorIPKPN7testing8TestInfoESt6vectorIS3_SaIS3_EEEmiEiis_spawnedoperator<< _ZN7testing8internal23DefaultDeathTestFactoryD0Evvector >_ZNSs5eraseEN9__gnu_cxx17__normal_iteratorIPcSsEES2_Argvoperator<< _ZN7testing8internal27PrettyUnitTestResultPrinter16OnTestPartResultERKNS_14TestPartResultE_ZSt19__throw_logic_errorPKc__prec__pred_ZNKSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE8_M_beginEv_ZN7testing4Test16TearDownTestCaseEv_ZNSt12_Vector_baseIPN7testing8TestInfoESaIS2_EE19_M_get_Tp_allocatorEvSecretSOCK_DCCP_ZNK9__gnu_cxx17__normal_iteratorIPPN7testing17TestEventListenerESt6vectorIS3_SaIS3_EEEptEv_Ios_OpenmodeDelete_ZN7testing4Test5SetUpEv_ZN7testing18TestEventListenersaSERKS0__ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE11_M_put_nodeEPSt13_Rb_tree_nodeISsE_ZNSs6appendEPKc_S_cur_ZNKSt6vectorIPN7testing11EnvironmentESaIS2_EE14_M_range_checkEjstdin__pthread_slist_t_ZNKSs4_Rep12_M_is_sharedEv_ZNSt11char_traitsIcE12to_char_typeERKi_ZNKSt6vectorIPN7testing11EnvironmentESaIS2_EE12_M_check_lenEjPKc_ZNSolsEPFRSt8ios_baseS0_E_ZN7testing15AssertionResultlsEPFRSoS1_E_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE5eraseEPKS1_S9_GetFileSize_ZNSt6vectorISsSaISsEE4rendEv_ZN9__gnu_cxx14__alloc_traitsISaIPKcEE8allocateERS3_j_ZNKSbIwSt11char_traitsIwESaIwEE15_M_check_lengthEjjPKc_ZNKSt23_Rb_tree_const_iteratorISsEeqERKS0__ZN7testing8internal27CheckedDowncastToActualTypeINS0_11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE11ValueHolderENS0_26ThreadLocalValueHolderBaseEEEPT_PT0__ZNK9__gnu_cxx13new_allocatorIiE8max_sizeEvvfwscanf_ZNKSbIwSt11char_traitsIwESaIwEE13find_first_ofEPKwjj_ZNSbIwSt11char_traitsIwESaIwEE4_Rep10_M_destroyERKS1_reverse_iterator<__gnu_cxx::__normal_iterator > > >_ZSt17__throw_bad_allocv_ZNKSt12_Vector_baseIN7testing14TestPartResultESaIS1_EE13get_allocatorEvdummyatoll_ZNSo9_M_insertImEERSoT_num_selected_tests_ZNKSbIwSt11char_traitsIwESaIwEE4copyEPwjjoperator<< _ZNSt12_Vector_baseIiSaIiEE17_M_create_storageEjfind<__gnu_cxx::__normal_iterator*, std::vector > >, std::basic_string >_ZNKSt6vectorIiSaIiEE4backEvshort intsnprintf_ZNKSbIwSt11char_traitsIwESaIwEE5c_strEvwmemcpy~FilePath_ZNK7testing8internal13DeathTestImpl8write_fdEvForEach, void (*)(testing::Environment*)>_ZN7testing8internal13FloatingPointIdE15ReinterpretBitsEy_Iter_basefind_last_not_of_ZNSt6vectorIN7testing12TestPropertyESaIS1_EE6rbeginEv_ZNK7testing10TestResult12elapsed_timeEv_ZNKSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE7_M_rootEv_ZNKSt6vectorIPN7testing8TestCaseESaIS2_EE3endEvuninitialized_copy<__gnu_cxx::__normal_iterator >, testing::internal::TraceInfo*>__normal_iterator, std::allocator > >sa_flagsoperator<< GetCapturedStderr_ZN9__gnu_cxx17__normal_iteratorIPPN7testing11EnvironmentESt6vectorIS3_SaIS3_EEEppEv_ZNKSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE14_M_upper_boundEPKSt13_Rb_tree_nodeISsES9_RKSs_ZNSbIwSt11char_traitsIwESaIwEE4_Rep10_M_refdataEv_ZNSt6vectorISsSaISsEE5beginEv_ZNKSs8_M_checkEjPKc_ZNSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE6resizeEjS3__vptr.DeathTestFactory_ZNSt12_Vector_baseIN7testing8internal9TraceInfoESaIS2_EE11_M_allocateEj_ZNK9__gnu_cxx17__normal_iteratorIPKcSsEixEi__exchange_and_add_dispatchReseed_ZNK9__gnu_cxx17__normal_iteratorIPKPN7testing17TestEventListenerESt6vectorIS3_SaIS3_EEEptEvcopy_backwardconstructParseFlagValue_ZN7testing8internal24XmlUnitTestResultPrinterD0Ev_ZNK9__gnu_cxx17__normal_iteratorIPKcSsE4baseEv_Construct, std::basic_string >_ZNKSt6vectorIN7testing8internal9TraceInfoESaIS2_EE2atEj_ZNSbIwSt11char_traitsIwESaIwEE4rendEv_ZN7testing8internal18CmpHelperSTRCASENEEPKcS2_S2_S2__ZN7testing8internal17GetCapturedStdoutEv__iterator_category<__gnu_cxx::__normal_iterator > >PushGTestTrace_ZN7testing8internal17TestEventRepeater24OnEnvironmentsSetUpStartERKNS_8UnitTestE_ZN9__gnu_cxx13new_allocatorIcE8allocateEjPKv_ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EE5beginEvuninitialized_copy_ZN9__gnu_cxx14__alloc_traitsISaISsEE17_S_select_on_copyERKS1_operator- >dup2rbegin__gthread_active_p_ZNSbIwSt11char_traitsIwESaIwEE6insertEjPKwj_ZNK9__gnu_cxx17__normal_iteratorIPN7testing12TestPropertyESt6vectorIS2_SaIS2_EEE4baseEv_ZNSt12_Vector_baseIPN7testing8TestCaseESaIS2_EE12_Vector_impl12_M_swap_dataERS5_CountIf, bool (*)(const testing::TestCase*)>_sigchldoutput_file_vptr.ParameterizedTestCaseInfoBase__uid_tGTEST_SHARD_STATUS_FILEPrintXmlTestCase_ZN9__gnu_cxx17__normal_iteratorIPKcSsEppEi_ZNSs6assignERKSsjj_ZNKSt6vectorIiSaIiEE4sizeEv_ZNSt10_Iter_baseIPN7testing8internal9TraceInfoELb0EE7_S_baseES3_mon_thousands_sep_ZN7testing8UnitTest13PopGTestTraceEv_ZN9__gnu_cxx17__normal_iteratorIPKcSsEppEv_ZNKSt6vectorIPN7testing17TestEventListenerESaIS2_EEixEj_ZNK7testing18TestEventListeners22default_result_printerEv_ZNK9__gnu_cxx17__normal_iteratorIPPN7testing17TestEventListenerESt6vectorIS3_SaIS3_EEEmiEiLogToStderrwcscatUponLeavingGTest_Vector_base >_ZNSo9_M_insertIxEERSoT__ZN7testing8internal9DeathTest27set_last_death_test_messageERKSs_ZNSbIwSt11char_traitsIwESaIwEE7replaceEjjRKS2__ZNSt6vectorIPN7testing8TestInfoESaIS2_EE4backEvrepeater__Const_Base_ptroperator!= >getcwdSendLn_ZN7testing8internal28ParseGoogleTestFlagsOnlyImplIwEEvPiPPT__ZNSt3setISsSt4lessISsESaISsEEaSERKS3_set_os_stack_trace_getter_ZNKSt23_Rb_tree_const_iteratorISsEneERKS0__ZN7testing8internal15UnitTestOptions27GetAbsolutePathToOutputFileEv_ZNK9__gnu_cxx17__normal_iteratorIPKN7testing14TestPartResultESt6vectorIS2_SaIS2_EEE4baseEv__normal_iterator > >pair, bool>repeaterbasic_stringstatus_valuePrintTestPartResultToStringa_name_ZNSt6vectorIPN7testing8TestCaseESaIS2_EE6insertEN9__gnu_cxx17__normal_iteratorIPS2_S4_EEjRKS2__ZNKSsixEj_ZNSs7replaceEN9__gnu_cxx17__normal_iteratorIPcSsEES2_S1_S1__ZNK9__gnu_cxx13new_allocatorIcE8max_sizeEv_ZN7testing8internal21UniversalTersePrinterIxE5PrintERKxPSo_ZN7testing8internal14GetThreadCountEvreplace_ZNSbIwSt11char_traitsIwESaIwEE18_S_construct_aux_2EjwRKS1__ZNK9__gnu_cxx17__normal_iteratorIPcSsEptEv_ZN7testing8internal2RE4InitEPKc_ZNK9__gnu_cxx13new_allocatorIPN7testing11EnvironmentEE7addressERKS3_AppendUserMessageUniversalTersePrinter_ZNKSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE13get_allocatorEv_ZNKSs7compareEjjPKc__suseconds_t_ZNK9__gnu_cxx17__normal_iteratorIPKPN7testing8TestCaseESt6vectorIS3_SaIS3_EEEmiEi_ZN9__gnu_cxx24__numeric_traits_integerIsE5__minE_ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EE5clearEv_RandomAccessIterator_ZN9__gnu_cxx14__alloc_traitsISaIiEE7destroyERS1_Pi_ZNSbIwSt11char_traitsIwESaIwEE13_S_copy_charsEPwN9__gnu_cxx17__normal_iteratorIS3_S2_EES6_PrintColorEncoded_M_is_sharediterator_traits_ZN7testing8internal27PrettyUnitTestResultPrinter16OnTestProgramEndERKNS_8UnitTestE_ZNK9__gnu_cxx17__normal_iteratorIPPN7testing8internal29ParameterizedTestCaseInfoBaseESt6vectorIS4_SaIS4_EEEmiEi_ZNSt6vectorIiSaIiEE18_M_fill_initializeEjRKi_ZNSt6vectorISsSaISsEE14_M_fill_assignEjRKSsscoped_ptr_ZN7testing8internal17kStackTraceMarkerE_ZN7testing8internal12UnitTestImpl11GetTestCaseEPKcS3_PFvvES5_premature_exit_filepath__S_constructparameterized_test_registry_ZN7testing8internal6Random8GenerateEj_ZN9__gnu_cxx17__normal_iteratorIPKPN7testing8TestInfoESt6vectorIS3_SaIS3_EEEppEiiterator_traits<__gnu_cxx::__normal_iterator > > >_ZN7testing18FLAGS_gtest_filterE_ZNK9__gnu_cxx17__normal_iteratorIPN7testing8internal9TraceInfoESt6vectorIS3_SaIS3_EEEmiEi__copy_m_ZN9__gnu_cxx17__normal_iteratorIPKPN7testing8TestInfoESt6vectorIS3_SaIS3_EEEppEva_message__are_same_ZNSt6vectorIPcSaIS0_EE18_M_fill_initializeEjRKS0__M_insert_M_mask_ZN7testing8internal10scoped_ptrIKSsE7releaseEvis_reportableTestReportableDisabled_ZNK9__gnu_cxx17__normal_iteratorIPiSt6vectorIiSaIiEEE4baseEvreverse_iterator<__gnu_cxx::__normal_iterator, std::allocator > > >_ZN9__gnu_cxx13new_allocatorIPN7testing8TestCaseEE10deallocateEPS3_j_ZNSbIwSt11char_traitsIwESaIwEE9_M_mutateEjjj_ZN7testing4Test3RunEvIsSubstring_ZSt9__find_ifIN9__gnu_cxx17__normal_iteratorIPN7testing12TestPropertyESt6vectorIS3_SaIS3_EEEENS0_5__ops10_Iter_predINS2_8internal17TestPropertyKeyIsEEEET_SE_SE_T0_St26random_access_iterator_tagallocator_type__comp_ZN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE7pointerEvpthread_mutex_lockrandom_seed__ZN7testing8internal15UnitTestOptions15GetOutputFormatEv_ZSt4cerr_ZNSbIwSt11char_traitsIwESaIwEE7_M_dataEPwfill_ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EE5eraseEN9__gnu_cxx17__normal_iteratorIPS2_S4_EE_ZN7testing8internal35DefaultGlobalTestPartResultReporter20ReportTestPartResultERKNS_14TestPartResultE_ZNSt12_Vector_baseIPN7testing8TestCaseESaIS2_EE17_M_create_storageEj_ZN7testing15AssertionResultlsIPKcEERS0_RKT__ZNSt12_Vector_baseIPcSaIS0_EE13_M_deallocateEPS0_j_exit_ZN7testing11IsSubstringEPKcS1_PKwS3_DistanceBetweenSignAndMagnitudeNumbers_ZNK7testing14TestPartResult6failedEvImplicitlyConvertible_ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EE6assignEjRKS2__ZN7testing8internal27PrettyUnitTestResultPrinter16PrintFailedTestsERKNS_8UnitTestE_ZNSt6vectorIPN7testing11EnvironmentESaIS2_EE8_M_eraseEN9__gnu_cxx17__normal_iteratorIPS2_S4_EES8__ZNKSt6vectorIPN7testing17TestEventListenerESaIS2_EE12_M_check_lenEjPKcerror_num_M_initialize_dispatch10regmatch_t_ZN7testing17TestEventListener15OnTestCaseStartERKNS_8TestCaseE_ZN7testing19TestPartResultArray6AppendERKNS_14TestPartResultE_S_red~ThreadLocalValueHolderBase_ZN9__gnu_cxx14__alloc_traitsISaIPKcEE10_S_on_swapERS3_S5__ZNK9__gnu_cxx13new_allocatorIN7testing12TestPropertyEE7addressERS2__ZN7testing10TestResult16set_elapsed_timeExarguments_ZN9__gnu_cxx24__numeric_traits_integerIiE5__maxEoperator!= >_ZNSt6vectorIN7testing12TestPropertyESaIS1_EE5beginEvgtest_error_ZNSbIwSt11char_traitsIwESaIwEEpLERKS2__ZN7testing8internal20DoubleNearPredFormatEPKcS2_S2_ddd_ZN7testing8internal8GTestLogaSERKS1__ZN7testing8internal35HandleExceptionsInMethodIfSupportedINS0_12UnitTestImplEbEET0_PT_MS4_FS3_vEPKcClearTestCaseResult_M_insert_aux~TraceInfo_ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS2_S4_EERKS2_state__S_adjustfield~AssertHelperData_ZNSt10_Iter_baseIPPN7testing8TestInfoELb0EE7_S_baseES3_ai_protocol_ZN7testing8internal16UniversalPrinterISbIwSt11char_traitsIwESaIwEEE5PrintERKS5_PSo_Iter_base_vptr.OsStackTraceGetterInterface_ZN7testing8internal8FilePath12MakeFileNameERKS1_S3_iPKc_ZN9__gnu_cxx14__alloc_traitsISaIPN7testing8TestCaseEEE17_S_select_on_copyERKS4__ZN7testing8internal8FilePath13GetCurrentDirEvparsedgetenv_ZNSt17_Rb_tree_iteratorIPKcEppEiParseGoogleTestFlagsOnlyImplintercept_mode__ZN7testing8internal10SkipPrefixEPKcPS2__Bit_iterator_base_ZNSt17_Rb_tree_iteratorIPKcEppEv_ZNK7testing12TestProperty5valueEv__wide_IO_read_endHandleExceptionsInMethodIfSupported_ZNK7testing8internal10scoped_ptrINS0_17StreamingListener20AbstractSocketWriterEEptEvwcschrIsSubstringPred >__builtin_va_list_ZNKSt3setISsSt4lessISsESaISsEE13get_allocatorEv__cxa_allocate_exceptionoperator new []val2_ss_ZNSt14_Bit_referenceaSEbpathname__ZNKSt6vectorISsSaISsEE5emptyEv__copy_m_S_minimumnew_allocator_ZNK7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEE3getEvIsXDigit_ZN7testing8internal24InternalRunDeathTestFlagaSERKS1_uninitialized_copy_ZNKSt6vectorIN7testing8internal9TraceInfoESaIS2_EE4rendEv_ZN7testing8internal24GetCurrentExecutableNameEv_ZNKSt6vectorIPN7testing11EnvironmentESaIS2_EE2atEj__statbufis_previous_hex_ZN7testing22EmptyTestEventListener11OnTestStartERKNS_8TestInfoE_ZNKSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE13get_allocatorEvservinfowcsrchr__uninitialized_move_if_noexcept_a*, std::basic_string*, std::allocator > >_ZN9__gnu_cxx13new_allocatorIPN7testing8TestCaseEE8allocateEjPKv__is_null_pointerbiased1biased2_ZNKSbIwSt11char_traitsIwESaIwEE12find_last_ofERKS2_j_ZNK7testing8internal13DeathTestImpl9statementEv_ZNSt6vectorISsSaISsEEaSERKS1_PrintWideStringTo_Vector_base >bool_value_ZN7testing22EmptyTestEventListener9OnTestEndERKNS_8TestInfoE_ZNKSt17_Rb_tree_iteratorISsEptEv_ZN7testing22EmptyTestEventListener15OnTestCaseStartERKNS_8TestCaseE_ZNKSt13_Bit_iteratorplEi__is_move_iterator__alloc_traits >IsATTY~basic_stringstream_ZN9__gnu_cxx13new_allocatorIN7testing14TestPartResultEE7destroyEPS2__ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE13_M_clone_nodeEPKSt13_Rb_tree_nodeISsE_M_const_castlldiv_ZN7testing8internal9MutexBase4LockEv_ZN7testing8internal12UnitTestImpl41GetTestPartResultReporterForCurrentThreadEvstatus_ch_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE6_M_endEvSuppressEventForwardingoperator<< >_ZNSt6vectorIN7testing14TestPartResultESaIS1_EE14_M_fill_assignEjRKS1__ZNKSbIwSt11char_traitsIwESaIwEE12find_last_ofEPKwjwctomb_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE6_S_keyEPKSt18_Rb_tree_node_baseIsSubstringImplsi_utimeUniversalTersePrinter_Key_compare_ZN7testing8internal6String15ShowWideCStringEPKwwcscspn_ZN7testing8internal9DeathTest6PassedEbhaystack_expriterator_traitsDISABLED_*:*/DISABLED_*Clear_ZNSt6vectorIPN7testing8TestInfoESaIS2_EE6insertEN9__gnu_cxx17__normal_iteratorIPS2_S4_EEjRKS2___uninitialized_copy_a_ZN9__gnu_cxx17__normal_iteratorIPKPN7testing8TestCaseESt6vectorIS3_SaIS3_EEEppEi_ZNK9__gnu_cxx17__normal_iteratorIPSsSt6vectorISsSaISsEEEmiEi_Funct_ZNK7testing8internal13FloatingPointIfE4bitsEv_ZN9__gnu_cxx17__normal_iteratorIPKPN7testing8TestCaseESt6vectorIS3_SaIS3_EEEppEv__uninit_copy<__gnu_cxx::__normal_iterator >, testing::internal::TraceInfo*>_S_showbase~basic_istreamconstruct_ZNSbIwSt11char_traitsIwESaIwEE7reserveEj_ZNKSt6vectorIN7testing12TestPropertyESaIS1_EE5emptyEvsigval_t_ZNKSt14_Bit_referencecvbEvsi_bandGetUnitTestImpl_ZN9__gnu_cxx14__alloc_traitsISaIPN7testing8TestInfoEEE8allocateERS4_jwcscmpsyntax_ValueT_ZNK9__gnu_cxx17__normal_iteratorIPPcSt6vectorIS1_SaIS1_EEEptEv_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE10_M_insert_EPSt18_Rb_tree_node_baseS7_RKSsiterator_traitsGetTestCaseTypeId_ZNSt6vectorIN7testing12TestPropertyESaIS1_EE5clearEv_ZNKSbIwSt11char_traitsIwESaIwEE7compareEjjRKS2__ZNK7testing8internal10scoped_ptrINS0_16DeathTestFactoryEEptEvstreamsize_S_max_size_ZN7testing7MessagelsEb__uninit_copy_ZN9__gnu_cxx13new_allocatorIPcE8allocateEjPKv_ZNK9__gnu_cxx17__normal_iteratorIPKPN7testing8TestCaseESt6vectorIS3_SaIS3_EEE4baseEvInterceptMode10__sigset_t_ZNKSt6vectorIPN7testing11EnvironmentESaIS2_EE5frontEv_ZNSs12_S_empty_repEv_ZNSs6assignEjc_ZNSt6vectorIPN7testing8TestInfoESaIS2_EE8pop_backEv_ZN9__gnu_cxx13new_allocatorIN7testing12TestPropertyEE8allocateEjPKvnum_disabled_ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EEaSERKS4__ZNSt6vectorIPN7testing11EnvironmentESaIS2_EE9push_backERKS2__ZNSt6vectorIPN7testing8TestCaseESaIS2_EE14_M_fill_insertEN9__gnu_cxx17__normal_iteratorIPS2_S4_EEjRKS2__ZN7testing8internal17StreamingListener12SocketWriter4SendERKSs_ZNSolsEPKv_ZNK7testing8internal29ParameterizedTestCaseInfoBase15GetTestCaseNameEv_ZN7testing8internal17TestEventRepeater27OnEnvironmentsTearDownStartERKNS_8UnitTestE_ZN7testing8internal13DeathTestImpl11set_read_fdEi_ZNK7testing15AssertionResultntEvGetCurrentDir__is_normal_iterator_ZNSt18_Bit_iterator_base7_M_incrEivswscanf_ZNSo9_M_insertIdEERSoT__ZNK7testing14TestPartResult7summaryEv__normal_iterator > >_ZNSs5beginEvkMaxStackTraceDepth_ZNSs13_S_copy_charsEPcPKcS1_IGNORE_SHARDING_PROTOCOL_chainfor_each<__gnu_cxx::__normal_iterator >, void (*)(testing::TestInfo*)>_ZNK7testing8TestCase16total_test_countEv_ZNSt6vectorISsSaISsEE4swapERS1__ZNSs6rbeginEvuninitialized_copy_ZNK7testing8UnitTest12elapsed_timeEv_ZNK9__gnu_cxx17__normal_iteratorIPN7testing8internal9TraceInfoESt6vectorIS3_SaIS3_EEE4baseEv_ZN7testing8internal27PrettyUnitTestResultPrinter13PrintTestNameEPKcS3_wcstollwcsxfrm_ZNKSbIwSt11char_traitsIwESaIwEE5rfindERKS2_j_ZN9__gnu_cxx13new_allocatorIN7testing12TestPropertyEE7destroyEPS2__ZNKSt9_IdentityISsEclERSsfmtflagskTestsuitewcscpy_S_maximum_ZNKSt3setISsSt4lessISsESaISsEE10value_compEv_ZNKSt6vectorIN7testing8internal9TraceInfoESaIS2_EE12_M_check_lenEjPKc_ZN7testing11IsSubstringEPKcS1_S1_S1_fflushpair, std::allocator > >, std::_Rb_tree_const_iterator, std::allocator > > >st_blksize_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE6rbeginEvkListTestsFlagreverse_iterator, std::allocator > > >_ZNK7testing12TestProperty3keyEv_ZNK9__gnu_cxx17__normal_iteratorIPPN7testing17TestEventListenerESt6vectorIS3_SaIS3_EEE4baseEv_M_assign_ZNSbIwSt11char_traitsIwESaIwEE4_Rep10_M_refcopyEv_ZN9__gnu_cxx14__alloc_traitsISaISsEE10deallocateERS1_PSsj_ZNKSt12_Vector_baseIN7testing12TestPropertyESaIS1_EE19_M_get_Tp_allocatorEv~PrettyUnitTestResultPrintersa_handlerg_linked_ptr_mutex_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE7_M_rootEv_ZNKSt6vectorIPN7testing11EnvironmentESaIS2_EE4rendEvkMaxRandomSeed_ZN7testing8internal12UnitTestImplaSERKS1_PrintAsCharLiteralTo_ZN7testing8internal10AlwaysTrueEv__mode_ZNSt6vectorIN7testing12TestPropertyESaIS1_EE6insertEN9__gnu_cxx17__normal_iteratorIPS1_S3_EEjRKS1__ZN7testing8internal24XmlUnitTestResultPrinter16PrintXmlTestCaseEPSoRKNS_8TestCaseE_IO_read_ptrset, std::allocator >, std::less, std::allocator > >, std::allocator, std::allocator > > >_ZN7testing13PrintToStringIxEESsRKT__ZN7testing8internal12UnitTestImpl6randomEvconstruct_ZN9__gnu_cxx17__normal_iteratorIPKN7testing8internal9TraceInfoESt6vectorIS3_SaIS3_EEEmmEi_ZNK9__gnu_cxx17__normal_iteratorIPKN7testing14TestPartResultESt6vectorIS2_SaIS2_EEEptEv_ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EE4dataEv_ZNSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EEixEj_ZN9__gnu_cxx17__normal_iteratorIPKN7testing8internal9TraceInfoESt6vectorIS3_SaIS3_EEEmmEvHandleSehExceptionsInMethodIfSupported_ZNSbIwSt11char_traitsIwESaIwEE12_S_constructEjwRKS1__M_incr_ZNK7testing8internal13DeathTestImpl5regexEv_ZNK9__gnu_cxx17__normal_iteratorIPKPN7testing8TestInfoESt6vectorIS3_SaIS3_EEEptEv_ZN7testing8TestCase11AddTestInfoEPNS_8TestInfoEPrintBytesInObjectToImpl~allocatorrandom_seed_flag_ZN7testing8internal9DeathTest5AbortENS1_11AbortReasonE__copy_move_a_ZN7testing4Test19HasSameFixtureClassEvFLAGS_gtest_throw_on_failureAlwaysFalsekSpecialEscape_ZNK9__gnu_cxx17__normal_iteratorIPKPN7testing17TestEventListenerESt6vectorIS3_SaIS3_EEEdeEv_Vector_base >_ZN9__gnu_cxx14__alloc_traitsISaIPN7testing11EnvironmentEEE17_S_select_on_copyERKS4_rebind >_ZN7testing8UnitTest11GetInstanceEv_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE10_S_minimumEPSt18_Rb_tree_node_base_ZNKSt16reverse_iteratorIN9__gnu_cxx17__normal_iteratorIPPN7testing11EnvironmentESt6vectorIS4_SaIS4_EEEEEdeEv_ZN9__gnu_cxx13new_allocatorIPN7testing17TestEventListenerEE7destroyEPS3_new_allocator_ZN7testing8internal12UnitTestImpl17current_test_infoEv_ZNSt3setISsSt4lessISsESaISsEE6insertERKSs_ZNKSs12find_last_ofEPKcj__uninitialized_copy_S_fixed_ZNSbIwSt11char_traitsIwESaIwEE7replaceEN9__gnu_cxx17__normal_iteratorIPwS2_EES6_RKS2__ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EE4backEv_ZNK9__gnu_cxx17__normal_iteratorIPKcSsEdeEv_ZN7testing8internal20SingleFailureCheckeraSERKS1__Traits_ZN7testing8internal9DeathTestaSERKS1_default_value_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE11_M_get_nodeEvisattybidirectional_iterator_tag_ZNKSbIwSt11char_traitsIwESaIwEE7compareEjjPKwj_ZN7testing8internal27PrettyUnitTestResultPrinter20OnTestIterationStartERKNS_8UnitTestEiHandleExceptionsInMethodIfSupportedFLAGS_gtest_output_ZN7testing8internal10scoped_ptrINS0_16DeathTestFactoryEEaSERKS3_FloatingPoint__copy_m_ZN9__gnu_cxx14__alloc_traitsISaIPcEE10_S_on_swapERS2_S4_wcspbrka_statement_ZNK9__gnu_cxx17__normal_iteratorIPKPN7testing17TestEventListenerESt6vectorIS3_SaIS3_EEEixEioperator<< Sendsubstr__ZN7testing11IsSubstringEPKcS1_RKSbIwSt11char_traitsIwESaIwEES7_negation_ZNSt11char_traitsIcE2eqERKcS2__ZNKSt16reverse_iteratorIN9__gnu_cxx17__normal_iteratorIPPN7testing11EnvironmentESt6vectorIS4_SaIS4_EEEEEixEi_ZNK7testing8internal10scoped_ptrISt18basic_stringstreamIcSt11char_traitsIcESaIcEEEptEvHandleExceptionsInMethodIfSupported_M_refdataendl >_ZNK7testing8TestCase4nameEv__throw_bad_alloc_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE11_M_leftmostEvregcomp_ZNSt10_Iter_baseIPSsLb0EE7_S_baseES0__ZNK9__gnu_cxx13new_allocatorIN7testing14TestPartResultEE7addressERKS2_scoped_ptr_kill_ZN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE11ValueHolderD0Ev_ZNK9__gnu_cxx13new_allocatorISt13_Rb_tree_nodeISsEE7addressERKS2_severity_pthread_mutex_destroy_ZNSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE6insertEN9__gnu_cxx17__normal_iteratorIPS3_S5_EEjRKS3__ZNSolsEPFRSoS_Evprintf_ZNSt12_Vector_baseIN7testing12TestPropertyESaIS1_EE12_Vector_impl12_M_swap_dataERS4_operator<< _sbuf_ZNSt3setIPKcSt4lessIS1_ESaIS1_EE11equal_rangeERKS1_FLAGS_gtest_catch_exceptions_ZN7testing8internal27PrettyUnitTestResultPrinter24OnEnvironmentsSetUpStartERKNS_8UnitTestEdef_optional_ZNSt6vectorIiSaIiEE5frontEvreporter_ZNSbIwSt11char_traitsIwESaIwEE4_Rep9_S_createEjjRKS1__ZN7testing8internal18g_linked_ptr_mutexE_ZNSt6vectorIPcSaIS0_EE4rendEv_ZN7testing8internal18OsStackTraceGetterD2Ev_ZNKSbIwSt11char_traitsIwESaIwEE7compareERKS2___throw_bad_cast__uninitialized_copy_a_ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EE6assignEjRKS2_strtoull__ostream_insert >_Destroy__is_normal_iterator_ZN9__gnu_cxx14__alloc_traitsISaIN7testing14TestPartResultEEE7destroyERS3_PS2__ZN7testing8internal17StreamingListener18OnTestProgramStartERKNS_8UnitTestE_ZNSt11char_traitsIcE6assignEPcjc_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE7_M_copyEPKSt13_Rb_tree_nodeIS1_EPS9_ToUppervector >_ZN7testing13PrintToStringIPKwEESsRKT_operator-*, std::vector > >default_xml_generatorFormatHexInt_ZN9__gnu_cxx14__alloc_traitsISaISt13_Rb_tree_nodeISsEEE10_S_on_swapERS3_S5__ZNK9__gnu_cxx17__normal_iteratorIPPN7testing11EnvironmentESt6vectorIS3_SaIS3_EEEptEv_ZNSt6vectorIiSaIiEE14_M_fill_insertEN9__gnu_cxx17__normal_iteratorIPiS1_EEjRKi_ZN7testing8internal10scoped_ptrISt18basic_stringstreamIcSt11char_traitsIcESaIcEEE7releaseEv_ZN9__gnu_cxx13new_allocatorIN7testing8internal9TraceInfoEE8allocateEjPKv_ZN7testing4Test8TearDownEvarray_ZNKSt12_Vector_baseIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE19_M_get_Tp_allocatorEv_ZNSt6vectorISsSaISsEE6insertEN9__gnu_cxx17__normal_iteratorIPSsS1_EEjRKSs_ZNKSs7_M_dataEv_ZNSt12_Vector_baseIiSaIiEE13_M_deallocateEPijiteratoroperator!= >__destroy_ZN7testing8internal18StreamableToStringIxEESsRKT_socket_writer__ZN9__gnu_cxx17__normal_iteratorIPKcSsEmmEidescriptionGetDefaultFilter_ZN9__gnu_cxx17__normal_iteratorIPKcSsEmmEvbasic_string, std::allocator >_ZNK9__gnu_cxx17__normal_iteratorIPPN7testing8TestInfoESt6vectorIS3_SaIS3_EEEplEi_ZNKSt15basic_streambufIcSt11char_traitsIcEE4pptrEvIsContainerTest_ZNSs4_Rep13_M_set_leakedEvreverse_iterator >_ZNKSbIwSt11char_traitsIwESaIwEE4_Rep12_M_is_sharedEv_ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EE8_M_eraseEN9__gnu_cxx17__normal_iteratorIPS2_S4_EES8___uninit_copy*, std::basic_string*>_ZN7testing8internal13DeathTestImpl6PassedEb_ZNKSt6vectorIPN7testing17TestEventListenerESaIS2_EE4backEv_ZNK7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE7pointerEv_ZN7testing8internal5MutexaSERKS1_no_sub_ZNSs6insertEjRKSs_Rb_tree, std::allocator >, std::basic_string, std::allocator >, std::_Identity, std::allocator > >, std::less, std::allocator > >, std::allocator, std::allocator > > >_ZNSbIwSt11char_traitsIwESaIwEE15_M_replace_safeEjjPKwj_ZN7testing8internal10scoped_ptrISsEaSERKS2__ZNSt6vectorIPcSaIS0_EE5clearEv_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE24_M_get_insert_unique_posERKS1__ZN7testing8internal17TestEventRepeater20OnTestIterationStartERKNS_8UnitTestEi_S_do_ituninitialized_copySOCK_NONBLOCK_ZNK9__gnu_cxx13new_allocatorIPN7testing8TestInfoEE8max_sizeEvRunSetUpTestCase_ZNSt6vectorIPN7testing11EnvironmentESaIS2_EE8pop_backEv_ZNKSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE3endEv_ZN7testing8UnitTestD0Ev_ZN7testing8internal31GetCurrentOsStackTraceExceptTopEPNS_8UnitTestEi_ZN7testing8internal9DeathTest6CreateEPKcPKNS0_2REES3_iPPS1__ZNK9__gnu_cxx17__normal_iteratorIPN7testing12TestPropertyESt6vectorIS2_SaIS2_EEEmiEi_Atomic_wordimpl__ZNK7testing18TestEventListeners21default_xml_generatorEvos_stack_trace_getter__ZN9__gnu_cxx13new_allocatorIPcE10deallocateEPS1_j_ZN7testing17TestEventListener25OnEnvironmentsTearDownEndERKNS_8UnitTestE__is_normal_iterator_ZN7testing22EmptyTestEventListener16OnTestPartResultERKNS_14TestPartResultEpipe_ZNKSt6vectorIPcSaIS0_EE4dataEvsi_signo_ZNSt12_Destroy_auxILb0EE9__destroyIPSsEEvT_S3__ZNK9__gnu_cxx17__normal_iteratorIPKPN7testing8TestCaseESt6vectorIS3_SaIS3_EEEptEvCreateSOCK_PACKET_S_keyTestRoleless, std::allocator > >_KeyOfValue_ZN7testing8internal15UnitTestOptions20PatternMatchesStringEPKcS3__ZNKSt12_Vector_baseIPN7testing11EnvironmentESaIS2_EE19_M_get_Tp_allocatorEv_ZNK9__gnu_cxx17__normal_iteratorIPKSsSt6vectorISsSaISsEEE4baseEvvector >_ZN9__gnu_cxx17__normal_iteratorIPKN7testing8internal9TraceInfoESt6vectorIS3_SaIS3_EEEpLEi_ZNSt6vectorIPN7testing8TestCaseESaIS2_EE14_M_fill_assignEjRKS2_operator- >__normal_iterator > >floattest_cases__ZN9__gnu_cxx17__normal_iteratorIPKPN7testing8TestInfoESt6vectorIS3_SaIS3_EEEmmEv_ZNK9__gnu_cxx17__normal_iteratorIPN7testing8internal9TraceInfoESt6vectorIS3_SaIS3_EEEptEv_ZNSt6vectorISsSaISsEE4dataEv__needlenum_chars_M_rep_ZN7testing7FloatLEEPKcS1_ff_Iter_base<__gnu_cxx::__normal_iterator > >, true>set_child_pid__copy_mFLAGS_gtest_list_testsmbrlen_ZNSs9push_backEc_ZN9__gnu_cxx17__normal_iteratorIPKPN7testing17TestEventListenerESt6vectorIS3_SaIS3_EEEppEiGetParam()re_pattern_buffer_ZN7testing4TestD2Ev_ZNK7testing8internal13FloatingPointIfE13exponent_bitsEv_ZN9__gnu_cxx17__normal_iteratorIPKPN7testing17TestEventListenerESt6vectorIS3_SaIS3_EEEppEvreverse_iterator<__gnu_cxx::__normal_iterator > > >_ZNKSt12_Vector_baseIPN7testing8TestCaseESaIS2_EE13get_allocatorEvargc_M_replace_aux_ZN7testing8internal7PrintToEPKcPSo~CapturedStream__niter_baseresize_ZSt18_Rb_tree_decrementPSt18_Rb_tree_node_base_ZNSt11char_traitsIcE11to_int_typeERKc_ZN7testing14ExitedWithCodeaSERKS0_argvoperator<< _ZN7testing32ScopedFakeTestPartResultReporterC2EPNS_19TestPartResultArrayE_ZNSt6vectorISsSaISsEE15_M_erase_at_endEPSserrors_ZNKSt6vectorIPN7testing8TestInfoESaIS2_EEixEj_ZN7testing8internal12UnitTestImpl26RegisterParameterizedTestsEvDerivedforever_ZNK7testing19TestPartResultArray17GetTestPartResultEi_ZNKSs17find_first_not_ofEcjseconds_IIter__niter_base_ZN7testing7MessageaSERKS0___elision_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE12_M_erase_auxESt23_Rb_tree_const_iteratorIS1_E_ZNSt6vectorIiSaIiEE6resizeEji_ZNSt12_Vector_baseIPN7testing8TestCaseESaIS2_EE11_M_allocateEjUrlEncode_ZNK9__gnu_cxx13new_allocatorIcE7addressERc_ZNSt10_Iter_baseIN9__gnu_cxx17__normal_iteratorIPPN7testing17TestEventListenerESt6vectorIS4_SaIS4_EEEELb1EE7_S_baseES9_CurrentStackTrace_ZN7testing8internal16DeathTestFactory6CreateEPKcPKNS0_2REES3_iPPNS0_9DeathTestE__data_ZNK9__gnu_cxx17__normal_iteratorIPN7testing14TestPartResultESt6vectorIS2_SaIS2_EEEdeEvtest_part_resultsTestCaseFailed__normal_iterator > >reverse_iterator<__gnu_cxx::__normal_iterator > > >_ZNSt17_Rb_tree_iteratorIPKcEmmEi_ZN7testing4Test11DeleteSelf_EvStrDup__copy_move_ZNK7testing8TestInfo4nameEv_ZNSt6vectorIPN7testing8TestInfoESaIS2_EE5eraseEN9__gnu_cxx17__normal_iteratorIPS2_S4_EE_ZNSs16_S_construct_auxIPKcEEPcT_S3_RKSaIcESt12__false_type_ZNSt17_Rb_tree_iteratorIPKcEmmEv__dynamic_cast__is_move_iterator~XmlUnitTestResultPrinterBasicNarrowIoManip__list_ZNSt9basic_iosIcSt11char_traitsIcEE4fillEctv_nsec_ZN7testing38FLAGS_gtest_show_internal_stack_framesEUnlock_ZNK7testing10TestResult15HasFatalFailureEvpthread_setspecific__dnewinput_iterator_tag~ParameterizedTestCaseRegistryprinted_test_case_name_M_start_ZNK9__gnu_cxx13new_allocatorIwE8max_sizeEvusedSkipComma__numeric_traits_integer_ZNSt6vectorIN7testing14TestPartResultESaIS1_EE8_M_eraseEN9__gnu_cxx17__normal_iteratorIPS1_S3_EE_ZN7testing8TestCase14TestReportableEPKNS_8TestInfoEUInt_ZNK7testing8internal13FloatingPointIfE6is_nanEv_ZNK9__gnu_cxx17__normal_iteratorIPPN7testing8TestCaseESt6vectorIS3_SaIS3_EEEplEioperator!= >_ZNK9__gnu_cxx17__normal_iteratorIPN7testing14TestPartResultESt6vectorIS2_SaIS2_EEEixEidefault_xml_generator__ZN7testing8internal17StreamingListener15OnTestCaseStartERKNS_8TestCaseE_ZNSt6vectorIPN7testing8TestInfoESaIS2_EEixEjset_up_tc_TEST_F_namesecond_ZNSsaSERKSsis_disabled_OnEnvironmentsTearDownEnd~SocketWriter_Num_ZNSt6vectorIPN7testing11EnvironmentESaIS2_EE15_M_erase_at_endEPS2__ZNKSt6vectorIiSaIiEE12_M_check_lenEjPKc_ZN9__gnu_cxx14__alloc_traitsISaIiEE10_S_on_swapERS1_S3__ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEED0Evdash_ZN7testing22FLAGS_gtest_print_timeE_ZNSt12_Vector_baseIN7testing12TestPropertyESaIS1_EE19_M_get_Tp_allocatorEv_ZNKSt13_Bit_iteratormiEiExitedWithCodehintstm_gmtoff_ZN9__gnu_cxx14__alloc_traitsISaIPN7testing8TestInfoEEE17_S_select_on_copyERKS4__ZN7testing8internal14CmpHelperSTRNEEPKcS2_PKwS4__ZNKSt3setISsSt4lessISsESaISsEE3endEvoperator<< _ZN7testing7MessageC2ERKS0_UniversalPrintArrayst_blocks_ZN7testing8internal12UnitTestImpl25set_os_stack_trace_getterEPNS0_27OsStackTraceGetterInterfaceEpthread_tprefix_ZN9__gnu_cxx14__alloc_traitsISaIPN7testing8internal29ParameterizedTestCaseInfoBaseEEE8allocateERS5_jDeathTestThreadWarning_ZN9__gnu_cxx17__normal_iteratorIPPcSt6vectorIS1_SaIS1_EEEppEv_ZNKSs4sizeEv__miter_base_ZN7testing8internal17StreamingListener20AbstractSocketWriter4SendERKSsallocator > >_ZNSt6vectorIPcSaIS0_EE9push_backERKS0_ai_addrlenkNonFatalFailure_ZNKSbIwSt11char_traitsIwESaIwEE2atEj_ZN7testing8internal21StackLowerThanAddressEPKvPbStat_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE29_M_get_insert_hint_unique_posESt23_Rb_tree_const_iteratorISsERKSs_ZNSt17_Rb_tree_iteratorISsEppEi_ZN7testing8internal13CaptureStreamEiPKcPPNS0_14CapturedStreamEsi_statusParseGoogleTestFlagsOnly_ZNK7testing8UnitTest19disabled_test_countEv__niter_baseoperator<< _ZNKSt6vectorIPN7testing8TestInfoESaIS2_EE2atEjg_captured_stdout_ZN9__gnu_cxx14__alloc_traitsISaIPKcEE8max_sizeERKS3__ZN7testing22EmptyTestEventListener25OnEnvironmentsTearDownEndERKNS_8UnitTestE_ZNKSs15_M_check_lengthEjjPKc_ZN9__gnu_cxx14__alloc_traitsISaIPN7testing8TestCaseEEE10_S_on_swapERS4_S6__ZNK9__gnu_cxx13new_allocatorIwE7addressERwoperator new_ZN9__gnu_cxx17__normal_iteratorIPKPN7testing8TestCaseESt6vectorIS3_SaIS3_EEEmmEi__class_type_info_ZNK9__gnu_cxx17__normal_iteratorIPSsSt6vectorISsSaISsEEEptEv_ZN7testing8TestInfoD2EvGetTestInfo_ZN9__gnu_cxx17__normal_iteratorIPKPN7testing8TestCaseESt6vectorIS3_SaIS3_EEEmmEvruntime_errorEndsWithCaseInsensitivevector >__countsam1sam2long_value_ZN7testing8internal8GTestLogD2Ev_Vector_base >_ZN7testing8internal18GetInjectableArgvsEv_ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EE6insertEN9__gnu_cxx17__normal_iteratorIPS2_S4_EERKS2__ZN9__gnu_cxx17__normal_iteratorIPKSsSt6vectorISsSaISsEEEppEi_ZN9__gnu_cxx17__normal_iteratorIPKPN7testing8TestInfoESt6vectorIS3_SaIS3_EEEpLEi_ZNKSt6vectorIN7testing12TestPropertyESaIS1_EE4rendEvrebind_ZN9__gnu_cxx17__normal_iteratorIPKSsSt6vectorISsSaISsEEEppEv_ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EE7reserveEj_ZNSt12_Vector_baseIPN7testing8TestCaseESaIS2_EE13_M_deallocateEPS2_j_ZNSt12_Vector_baseIN7testing14TestPartResultESaIS1_EE12_Vector_impl12_M_swap_dataERS4_Setupsuccessful_test_case_count_ZNSt6vectorIiSaIiEE4swapERS1_ReadAndInterpretStatusByte_ZN7testing8internal18OsStackTraceGetter19kElidedFramesMarkerEsa_restorer_ZNSt3setIPKcSt4lessIS1_ESaIS1_EE4swapERS5__M_node_ZNSs6assignEPKcj_ZN7testing8internal15GetUnitTestImplEvShuffleTests__iterator_categoryconst_pointer_ZNK9__gnu_cxx13new_allocatorIPN7testing8internal29ParameterizedTestCaseInfoBaseEE7addressERKS4_fgetws_ZNKSt3setIPKcSt4lessIS1_ESaIS1_EE13get_allocatorEv__cursummaryArrayAsVector<8>int_p_sign_posn_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE5eraseESt23_Rb_tree_const_iteratorIS1_E_ZN7testing8internal12UnitTestImpl11AddTestInfoEPFvvES3_PNS_8TestInfoE_ZNSt6vectorISsSaISsEE5eraseEN9__gnu_cxx17__normal_iteratorIPSsS1_EE_ZN9__gnu_cxx13new_allocatorIPN7testing11EnvironmentEE9constructEPS3_RKS3_GetReservedAttributesForElement_ZN9__gnu_cxx13new_allocatorIiE7destroyEPioperator<< _ZNSt6vectorIN7testing12TestPropertyESaIS1_EE4swapERS3_operator<< tm_sec__size_typekMaxParamLength_ZN9__gnu_cxx13new_allocatorIPKcE8allocateEjPKv__static_initialization_and_destruction_0new_allocator_ZN7testing8internal8GTestLogC2ENS0_16GTestLogSeverityEPKciactual_valueoperator<< _ZNSo3putEc_ZNK7testing10TestResult17test_part_resultsEv__normal_iterator > >_ZN7testing22EmptyTestEventListener20OnTestIterationStartERKNS_8UnitTestEiFLAGS_gtest_shuffle_ZNSs7replaceEjjRKSs_ZN7testing8internal17StreamingListener12SocketWriteraSERKS2_new_allocator, std::allocator > > >ArrayAsVector<6>_ZNSs4_Rep9_S_createEjjRKSaIcE__addressof >kValueParamLabel_Destroy_ZdlPv_ZNKSt3setIPKcSt4lessIS1_ESaIS1_EE8key_compEv_ZNKSbIwSt11char_traitsIwESaIwEE16find_last_not_ofEwjlist_tests__ZN9__gnu_cxx14__alloc_traitsISaIiEE8max_sizeERKS1_~ValueHolder_ZN7testing8internal18PrintCharAndCodeToIhaEEvT0_PSo_ZNKSt3setIPKcSt4lessIS1_ESaIS1_EE11upper_boundERKS1_term_supports_color_Rb_tree_increment_ZNKSt9_IdentityIPKcEclERS1__ZN9__gnu_cxx13new_allocatorISt13_Rb_tree_nodeIPKcEE9constructEPS4_RKS4__S_base_ZNSs7replaceEN9__gnu_cxx17__normal_iteratorIPcSsEES2_S2_S2__ZNKSt6vectorIN7testing8internal9TraceInfoESaIS2_EE4dataEv_ZNK7testing8internal12UnitTestImpl21total_test_case_countEv_ZNSt6vectorIPcSaIS0_EEixEj~OsStackTraceGetterkTestTypeIdInGoogleTest_ZNKSt3setIPKcSt4lessIS1_ESaIS1_EE3endEv_Reppbase_ZN7testing8internal14ParseInt32FlagEPKcS2_Pi_ZN7testing8TestCaseC2EPKcS2_PFvvES4_AddTestPartResult__is_normal_iterator_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE6_M_endEvtotal_part_count_ZNSt12_Vector_baseIN7testing8internal9TraceInfoESaIS2_EE17_M_create_storageEjnot_eofSkipSpacesnot_eolPrintToString_ZNSs4_Rep12_S_empty_repEvmon_decimal_pointcurrent_test_case_operator<< _ZNKSs17find_first_not_ofEPKcjoperator<< vector >_ZNKSbIwSt11char_traitsIwESaIwEE8_M_checkEjPKcPartialMatchiterator_traits<__gnu_cxx::__normal_iterator > > >in_death_test_child_process~DefaultPerThreadTestPartResultReporter_ZNSs9_M_assignEPcjc_ZNK7testing8internal8FilePath14IsAbsolutePathEv_ZNSt11char_traitsIwE4findEPKwjRS1_ValidateTestPropertyNamerfind_Reference_ZN7testing8internal12AssertHelperC2ENS_14TestPartResult4TypeEPKciS5___osize_DestroyToPrint_ZNK9__gnu_cxx13new_allocatorIiE7addressERKi_ZN7testing8internal8FilePath9NormalizeEv_ZN9__gnu_cxx17__normal_iteratorIPSsSt6vectorISsSaISsEEEppEi_ZNKSt6vectorIiSaIiEE5frontEv_ZN7testing8internal24XmlUnitTestResultPrinter26RemoveInvalidXmlCharactersERKSs__are_same_ZNK7testing8internal12UnitTestImpl16catch_exceptionsEvkRandomSeedFlag__iterator_category<__gnu_cxx::__normal_iterator*, std::vector > > >_ZlsRKN7testing8internal6SecretEi_ZN9__gnu_cxx17__normal_iteratorIPSsSt6vectorISsSaISsEEEppEv_ZNK7testing8UnitTest26successful_test_case_countEvoperator()<__gnu_cxx::__normal_iterator > >_S_showpoint_ZN7testing8internal17TestEventRepeater25OnEnvironmentsTearDownEndERKNS_8UnitTestE_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE11upper_boundERKS1__IO_lock_t_ZN9__gnu_cxx14__alloc_traitsISaIN7testing12TestPropertyEEE10_S_on_swapERS3_S5__ZN9__gnu_cxx13new_allocatorIPN7testing8internal29ParameterizedTestCaseInfoBaseEE8allocateEjPKv_ZN7testing8internal13DeathTestImpl11set_outcomeENS0_16DeathTestOutcomeE_ZN9__gnu_cxx24__numeric_traits_integerIiE5__minE_ZN7testing31TestPartResultReporterInterfaceaSERKS0__ZNSt12_Vector_baseIPN7testing11EnvironmentESaIS2_EE19_M_get_Tp_allocatorEv__copy_m_ZN7testing8internal23MakeAndRegisterTestInfoEPKcS2_S2_S2_PKvPFvvES6_PNS0_15TestFactoryBaseEnew_allocator_ZNK9__gnu_cxx13new_allocatorIN7testing14TestPartResultEE7addressERS2__ZNSt6vectorIN7testing12TestPropertyESaIS1_EE4backEvEventForwardingEnabled__alloc_traits >_Rb_tree_impl, false>_ZN7testing8internal8FilePath3SetERKS1__ZNKSt17_Rb_tree_iteratorISsEneERKS0_kTypeParamLabel__simple_ZNSt11char_traitsIcE4findEPKcjRS1___is_move_iteratorproperty_with_matching_keylong long int_ZNKSt3setIPKcSt4lessIS1_ESaIS1_EE8max_sizeEv_ZNSt16reverse_iteratorIN9__gnu_cxx17__normal_iteratorIPPN7testing11EnvironmentESt6vectorIS4_SaIS4_EEEEEmmEv_ZNSt6vectorIiSaIiEE8_M_eraseEN9__gnu_cxx17__normal_iteratorIPiS1_EES5__ZNKSt16reverse_iteratorIN9__gnu_cxx17__normal_iteratorIPPN7testing11EnvironmentESt6vectorIS4_SaIS4_EEEEE4baseEv_ZN7testing8internal26GoogleTestFailureExceptionD2Ev_ZNSt6vectorIPN7testing8TestCaseESaIS2_EE5clearEv_ZN7testing8internal13DeathTestImplD2Ev_ZNKSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE11upper_boundERKS1__ZNSs7replaceEN9__gnu_cxx17__normal_iteratorIPcSsEES2_RKSs_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE6rbeginEv_ZN9__gnu_cxx17__normal_iteratorIPKPN7testing8TestCaseESt6vectorIS3_SaIS3_EEEpLEi_ZNK7testing8UnitTest21successful_test_countEv_ZN9__gnu_cxx13new_allocatorIN7testing8internal9TraceInfoEE7destroyEPS3__ZN9__gnu_cxx14__alloc_traitsISaIiEE8allocateERS1_jMatchesFilteroperator<=19pthread_mutexattr_t_ZN7testing8internal2RED2Ev_ZN7testing10TestResult14RecordPropertyERKSsRKNS_12TestPropertyECountIf, bool (*)(const testing::TestPartResult&)>_ZNSt6vectorIN7testing12TestPropertyESaIS1_EE2atEjLastMessage_ZNKSt6vectorIPN7testing17TestEventListenerESaIS2_EE4rendEv_ZNK7testing8TestCase17failed_test_countEvscoped_ptr, std::allocator > >_Iter_base_ZNKSs12find_last_ofEcj_ZNKSt23_Rb_tree_const_iteratorIPKcEneERKS2__ZN9__gnu_cxx13new_allocatorIN7testing8internal9TraceInfoEE10deallocateEPS3_j_ZNK7testing8internal13FloatingPointIdE13fraction_bitsEv_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE4swapERS7__ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE8_S_rightEPKSt18_Rb_tree_node_base_ZN7testing8internal8FilePathaSERKS1_vector >_ZNKSbIwSt11char_traitsIwESaIwEE6substrEjj_ZN7testing8internal11CmpHelperNEEPKcS2_xx_S_dec_DestroyFilterTestsfirst_test_nameTestCaseInfoContainer_ZNSt3setIPKcSt4lessIS1_ESaIS1_EE5clearEva_type_param_ZNK9__gnu_cxx13new_allocatorIN7testing8internal9TraceInfoEE7addressERS3__ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE12_M_rightmostEv_ZNKSt18_Bit_iterator_basegtERKS_U.a.0a.~.PX.a.Ra.w.Rw.z.rz.~.Rj.~.Q..0..P..R..R..r..R..r..Q..0..P..R..R..r..R..0./P..R./R//r//R//u#//V//V//v//V//V//P//W//W//R//RVa0r00r00W00w00Wd00#00000W00w00W00#1101!1W!1(1w(1:1W1:1#Q1b10b1q1Wq1x1wx11WT11#11011W11w11W11#12022W22w2*2W1*2#A2V2V2{2UA2V2V2{2WL2O2vO2T2VT2V2# p2&1D2V2#V2{2w2222U2222W22v22V22# p2&122#22w2223U2223W22v22V22# p2&122#23w13F3F3k3U13F3F3k3W<3?3v?3D3VD3F3# p2&143F3#F3k3w3333U3333W33v33V33# p2&133#33w33033U33u34U34#14J4J4o4U14o414J4J4o4V<4?4p?4J4P44J4#J4o4v44P44Q44W44P44Q44044V44044044U44u44U44044Q44W44P44Q5)5P)565W65E5wE5\5W\5k5wk5u5Ww55W5)50)595U95?5u?5_5U_5e5u~e5o5Uw55U55P55P55R55R55p55P#55 55p55 55p55Q V   'V'( v  # 'v'(#oR(oP PWkqk#WWWkVWVvtVksVswvtwVvtksvswv|wvv|kwL}LkwP}P# #<W# #<WQXqX#/WVVvtUVVvtV!vtvv|v!v|L /LP P/7# #</VW7GW{W{V{Vv|VVv|Vv|LLPP#4W#4W5"6R"66uT66tP67uT77L77uT56p6"6q"66uP66tL67uP77H77uP6"60"6l6Wl6o6to6p6tp6t6t66V66W77W97N7W;6G6PG6V6VV66v66V77v97N7Vh7j7v;67977;66uP66tL67uP77H77uP977uPZ6t6R77R77vwZ6l6Wl6o6to6p6tp6t6t77WZ66uT77uTh77uTZ6677h77w66W66ud66W66udh77Ww66uPh77uP66W66ud66W66ud66u`66P67 97h7 66W97N7W66uT66tP67uT77L97h7uT6797h766V66u`66t\66V67u`77XN7P7VP7h7u`66uP66tL67uP77HN7h7uP66V66u`66t\66V67u`77X66ud66t`67ud77\66P66v<66u`<66t\<66PP7h7u`V7a7uda7e7Re7h7udV7e7Pp7{7u`{77R77u`p77P 66P6"6Q"66uP66tL67uP77H77uP797uP 7+7u_+7/7R/797u_ 7/7P77P7h8P77R7Y8HY8h8R770 8Y8U8/8P/8;8uH";8S8PS8Y8uH"E8Y8L;8Y8W7Y8V7Y8W&8/8Y/858p58;8Y!8;8Wp88P88W88P88W88P88R88V88p#88P88W88P88p#88w#88p88PpE#)o)/P/EoR/R5ER)o)/P/Eo/R5ERp|* #4*/r5Cp|CE #4 p|5Cp|CE #4iVVVSpuipuipu#JPPRR8 9u 9!9t!949u8 9u 9!9t!949u8 9u 9!9t !949u8 9u 9!9t!949u 88P89V9!9p!949VZ9h9Rz99R99vZ9h9r z99r 99v# `9t9oz99o99R99o`9h9Pz99P99V9$:V99:99::$::99V99V:$:V::V: ;V:::::V;<0<<P;<R<<R<<r<<R>>p>>u #>>t#>>u #>>V>>w>>u#>>t#>>w>>u#>>t#??R????P??-@8@R8@>@qt2@I@Vt@HAudHAKAt`KA]Aud]A`At``AAudw@@V@@Q@@W@HAuPHAKAtLKA]AuP]A`AtL`AAuPS@@u w@HAudHAKAt`KA]Aud]A`At``AAud@@u@AVA*Av*AFAVKA[AV@@6@@P@@v@0AuW@0AWA*AZA Apr"A0AWAAptA0ARA0AWA0AR*A0Apw"0AHAudHAKAt`KA]Aud]A`At`6AHAucHAKAt_KA]Auc]A`At_6AAAPAAHAud<HAKAt`<KARAPjAuAucuAyARyAAucjAyAPAAucAARAAucAAPABPBB# BBLABUABPBB# BoBVoBtBvltBxBVB'BV'B+Bvl+BoBVoBxBvlB'Bv'B+Bv|+BoBvoBxBv|B+BH1BxBHBBPBBv<1B=BPBBv >BHBv B+BHDBxBHBBPDBXBPB$BvYBcBv B+BH_BxBH B+BP_BsBPBBPBB# BiCLBeCUBBPBB# B?CW?CDCwlDCHCWBBWBBwlB?CW?CHCwlBBwBBw|B?Cw?CHCw|BBHCHCHBBPBBw<C CPBBw CCw BBHCHCHBBPC(CPBBw)C3CwBBH/CHCHBBP/CCCP[CbCp,bCCq,CC#,iCqCPqCCLiCCUiCqCPqCCLCCWCCwxCCWCCWCCwxCCWCCwxCCwCCw|CCwCCw|CCHCCHCCPCCw<CCPCCWCCwxCCWCCwxCCHCCHCCPCCPD0D0D4DRD0D# 0D4Dr DD0D0DR0D4D0DDPD#DP#D%Dpl0D2DP2D4Dr @DpDpDtDREDpD# pDtDr EDQD0QDpDRpDtD0HDQDPQDcDPcDeDplpDrDPrDtDr DDVDDt DDtDEVDDw DDt# DEw DDVDDt DDtE&E0&EZEV\EgEVEEu EE# EE0EEWEEVEEVEEREEvEErdEEREEvEErdEErEEREE hE Fu FF# EE0EFWEEVE FVEEREEvEErdEEREEvEErdEF i(F_Fu_F`F#T(F0F00FVFW+FQFVQF]FV2F@FR8F@FRNFVFixFFuFF#TxFF0FFW{FFVFFVFFRFFRFFjFFVFFt FGtGGVFFw,FGt#,GGw,FFVFFt FGtKGQGPQGWHVWHXHwXHYHu#YHZHt#ZHHVKGQGpQGGvGGPGWHvWHXHw#XHYH u##YHZH t##ZHHvKGQGpQGWGvWGZGvZG]Gv]G`Gv`GcGvcG4Hv44H?HP?HWHv4WHXHw#4XHYH u##4YHZH t##4ZHHv4WGGvGGPGWHvWHXHw#XHYH u##YHZH t##ZHHvWGZGvZG]Gv]G`Gv`GcGvcG4Hv44H?HP?HWHv4WHXHw#4XHYH u##4YHZH t##4ZHHv4ZGGvGGPGWHvWHXHw#XHYH u##YHZH t##ZHHvZG]Gv]G`Gv`GcGvcG4Hv44H?HP?HWHv4WHXHw#4XHYH u##4YHZH t##4ZHHv4]GGvGGPGWHvWHXHw#XHYH u##YHZH t##ZHHv]G`Gv`GcGvcG4Hv44H?HP?HWHv4WHXHw#4XHYH u##4YHZH t##4ZHHv4`GGvGGPGWHvWHXHw#XHYH u##YHZH t##ZHHv`GcGvcG4Hv44H?HP?HWHv4WHXHw#4XHYH u##4YHZH t##4ZHHv4cG4Hv44H?HP?HWHv4WHXHw#4XHYH u##4YHZH t##4ZHHv4GGvGGPGWHvWHXHw#XHYH u##YHZH t##ZHHvGZHxGGPGWHvWHXHw#XHYH u##YHZH t##GZHGGvGGPGWHvWHXHw#XHYH u##YHZH t##GZHpGGPGWHvWHXHw#XHYH u##YHZH t##GZHGGvGGPGWHvWHXHw#XHYH u##YHZH t##1HZHȷ1H4Hv44H?HP?HWHv4WHXHw#4XHYH u##4YHZH t##4bHmHugmHqHRqHHugbHqHPxHHugHHRHHugxHHPHHugHHRHHugHHPHHugHHRHHugHHPHHugHHRHHugHHPHHugHHRHHugHHP-IjJVrJRKVSIVIvVIaIPaIjJvrJRKvSIjJrJRKgIrIPrIjJvrJJvgIjJxrJJxIIvIIPIjJvrJJvIjJrJJIIPIjJvrJJvIjJprJJpIIvIIPIjJvrJJvIjJrJJIIv4IJPJjJv4rJJv4IjJȷrJJȷJjJv4rJJv4#JjJugrJJug#J'JPrJJP'JjJvJJv-JjJugJJug-J1JPJJP1JjJvJJv7JjJugJJug7J;JPJJP;JjJvJJvAJjJugJJugAJEJPJJPEJjJvJJvKJjJugJJugKJOJPJJPOJjJvJJvUJjJugJJugUJYJPJJPJJugJJRJRKugJJPJJugJJRJRKugJJPK Kug KKRKRKugKKPKKugK"KR"KRKugK"KP)K0Kug0K4KR4KRKug)K4KP;KBKugBKFKRFKRKug;KFKPKKWKKwKKVKKv|KKVKK*{KK*{KKR"L,LRQL[L# [LhLVhLqLv|[LhLvhLkLPkLlLv|lLpLpdLL0LLPLL#LLLLRM5MWWMMW)N~NW$MOMVM)NV5M6MP6MOMWM)NWKMOMU$MOMBM)NBNNWNNuNNt NOWOOuOOt OOWNN1NO0NNWNNuNNt NNu NNtNNtNOWOOuOOt NOu O Ot O OtCOLOvMOTOPBPNPvNPPPtPPUPdBPNPvPPR=QTQ0PPPP=Q=QCQPCQjQP=Q#=QCQpCQjQ#PPRPP#P=Q=QCQPCQjQPP# =QCQp CQTQ# PPPpQQ0QQQQQ#QQ#QQ0QQQQQqQQVQRVQQVQRVQQPQ RPQQRQ RR RRvQQ1QR1QQq4Q Rq4RRRvRR#RRvRRPRSuRSu SSPS.SV.SSVSSvSSVSSVSSPSSu S4SW7SSWSSQSSQ SnSu SSu (S4SSSKSSWSSQSSQ\SaSQaSSuTSSuT~SS^SS^~SSpr"SSuTSSuTSSptSSRSSRSSuTSSRSSpuT"SSugSSRSSugSSPTBTUBTCTtCTGT@WTTUTTVTTHTZTߨHTZTV2TBTUBTCTtCTGT@ZTTUzTTVTT)U=UVUUUUPWWVWWVWWv~WWVWWv~X XV!X1XV1XCXv~!X1XV1XCXv~]XXVXX#$rXX2$w"]XXvXX #$#`XXPXYXXXWYYPYYWYYVY#YUFYKYPKYYUHYKYPKYYUHYKYpKYSYPSYYuYYRw#OwOP#oR,o,0R0DoDHRHPoPw<Pw #w o,o,0R0DoDHRHPoP0P w1;wo7DoDHRHPoP7HPew#w#qoRoRoqwPw~w<PuWWzooRozPP]ZeZPeZnZZZPZZVZZVZZPZZPZZZZZZPZZVZZV [h[0h[\T\\Q\\TG[\#T\\#T}[\U\\U}[[0[[1[\Q\p\1p\\Q\\1}[[0[\V\\V[[W \p\W\\W[[W\\W[[w \\w [[W\\W[[w \\w [[P'\p\U\\U'\p\u\\uM\^\U\\UM\^\u\\uW\Y\P[\u \\u @]c]0c]]VW]]#T!^%^P%^>^VP^n^Pn^^v^^tp^^v^^tp^ _v__R__uP__tL__R_`uPD`W`uP_`R``rW_`%$``%W_]_W]_^_t^_b_tb__u`__t\_`u`$``u`l_`%$``%``%l__W__ud__t`_`W$`b`Wb``ud``W``ud``W``ud``u\``R``u\``Pz__V__u __t_`u $`D`VD`W`u W`Y`VY``u ``V``u z__W__ud__t`_`W$`b`Wb``ud``W__V__u __t_`u $`D`VD`W`u W`Y`VY`t`u __uT__u\__tX_`u\$`W`u\W`h`uTh`t`u\Y`t`u\e`o`u[o`s`Rs`t`u[e`s`P__W__ud__t`_`W$`W`W__u[__tW_`u[$`W`u[__P$`/`P__u`__t\_`u`5`W`u`__ud__t`_`ud5`W`ud__P5`>`P__u\__tX_`u\D`W`u\__u\__tXD`W`u\__ud__t`D`W`ud__P__vtD`Q`PQ`W`vtt``udz``u[``R``u[z``P``u```u[``R``u[``P` aP*a5aPaafaPfaaVjaaVjaabbRccccccPcctcccccccd0d"dRccccPcctcdd"dcc ddddPddPd%eV%e/ev/eeVeePeeWeePe%eW%ekeRdeUeeeeUeeeeUeefeeWfeeUeeeeUeefJfVJfLfu_LfOft_OfcfVcfefu_efhf_hfpfVpffu_ffVffu_fLfuLfOftOfefuefhfhffuffuffu_ffRffu_ffP7fJfVJfLfu_LfOft_OfcfVcfefu_efhf_:fLfu_LfOft_Ofefu_efhf_:fEfPEfJfv<JfLfu_<LfOft_<OfZfPpffu_yffu_ffRffu_yffPffP)g9gPf%gW%g&gud&g)gt`IgZgWegpgWpggudggWggudf$gV$g&gu&g)gtIgZgVegggVggguggVgguggVgguggucggRggucggPg%gW%g&gud&g)gt`IgZgWg&guc&g)gt_IgZgucggPIgWgP)gEgWEgFgu FgIgt)gDgVDgIgPpggudvg~guc~ggRggucvggPggu`ggPg:huT:h=htP=hahuTahdhtPdhhuTg8hV8h:hud:h=ht`=h_hV_hahudahdht`dhfhVfhhudhhVhhudhhVg8hV8h:hud:h=ht`=h_hV_hahudahdht`g:huT:h=htP=hahuTahdhtPh8hV8h:hud:h=ht`=h_hV_hahudahdht`h)hV)h:hu`:h=ht\=hJhVJhahu`ahdht\h:hu_:h=ht[=hahu_ahdht[hhP=hGhP)h:hu`:h=ht\Jhahu`ahdht\,h:hud:h=ht`Jhahudahdht`,h3hP3h:hu`<:h=ht\<JhVhPfhhu`lhshu_shwhRwhhu_lhwhPhhudhhu_hhRhhu_hhPhhPhhp9iFiPhhu`hhPh iuT i6iu`6i9iX9iqiu`qitiXtiiuTiiu`iiuTh iu tiiu iiu hhuTh iudtiiudiiudhhPh iuTtiiuTiiuTi iudtiiudi iu_tiiu_i iPtiiP i6iu`6i9iX]iqiu`qitiXiiu` i4iV4i9iP]ioiVoitiPiiViiViiudiiRiiudiiP&i6iu`6i9iX]iqiu`qitiX)i6iud6i9i\]iqiudqiti\)i2iP2i6iu`<6i9iX<]igiP9i]i59iOiu`OiWiPWi]iuTiiu`iiu_iiRiiu_iiPiiu_iiRiiu_iiPijWj7ju 7j:jtYjju ii w<1i jPi:j0Yjj0 j6jW6j7jud7j:jt`YjujWujjudjjWjjud j5jV5j7ju7j:jtYjljVljjujjVjjujjVjjujjucjjRjjucjjP#j6jW6j7jud7j:jt`YjjjW&j7juc7j:jt_Yjjjuc&j.jPYjgjP:jUjWUjVju VjYjt:jTjVTjYjPujjud{jjucjjRjjuc{jjPjjVjkVkkukkVkku:kkuT:kWkuTWkyku`ykkuTkku`=kku_=kEkPkkPWkyku`]kykud]kokPkku`kkudkkPkku_kkRkku_kkP llullt llullt l)mu.mmu llVlludllt`llVlludllt`llVl.mud.m0mV0m;mud;m=mV=mRmudRmTmVTmimudimkmVkmmudllullt llullt lmu;mHmuRmmullWllu`llt\llWllu`llt\lmWmmu`;mHmWRmmWlmu` mmu_mmRmmu_ mmP6llVlludllt`llVlludllt`llV;m=mV=mHmudRmTmVTmimudimkmVkmmud9llu_llt[llu_llt[llu_;mHmu_Rmmu_9lDlPllPWllu llu Rmmu Wlflu <u`<Wll0ll0Rmm0slludlludRmmudsllulluRmmusm{mu_{mmRmmu_smmPlludlludllu_llu_llPllPllu`llu`lludlludllPllPllu llum%mud m%mu_ m%mP=mHmu`CmHmu_CmHmPTmimudZmbmu_bmfmRfmimu_ZmfmP[nanRan|n[n|nnnVn(oVn#o:nnVn#oVno:noVnnPooPooWooPooVoo0ooPooPoo0ooU pLpVLpMpPMp_pVppV8pBpvWp_pVppVppugppRppugppPfppVppVqppvppvzppugppugzppPppPbqqQqqLgqqQqqLgqqWgqqVgqqVqqv|qqVqqVqqv|qqVqqv|qqHqqHqqPqqPqqQqqHqq qq4qqWqqW.rrWrrrrW.rrVrrrrV.rrUrrrrU5rFrPzrrRrr ? arrMarrWrrڲrrWrrrsPssssPsTtrspss#sspsTt#ssPssssPsTtsspss#sspsTt#ssRs/s\ss0sOsWOssssWsTtssRs/s\ss0ssWss1ssRssr/ssVsTtV/sOsWOsssTtOssͮsTtͮOsUsPUssWsTtWassV.tOtVassWsTtWtss^sTt^tssWsTtWssUsTtUssWsTtWssU.tOt0.tOtW:tOt1:tFtR:tAtrssWs.tWOtTtWss:s.t:OtTt:ss ww<"stwp"OtStwp"ssVs.tVOtTtVss:s.t:ssVs.tVs.t:s.tVssPttttVttVttv$#$ v$oR oPPVuuPu^vV^v`vu`vavtavvVuup4u uP u`vud`vavt`avvud]u^vV^v`vu`vavtavvVuuQu`vu\`vavtXvvu\vvvvvu\uavHvvHuvQv`vu``vavt\vvu`!v`vu`#$`vavt\#$vvu`#$cvvv4Iv^vV^v`vu`vavtIv`vu`vavtKvavAKv_vW_v`vu\`vavtXKvYv wu\<"KvavAKvYv wu\<"#vvu~vvPvwWwyu}yyt}yyu}yyWy:zu}vvu~vvPvyu~yyt~y:zu~1wwWwyu}yyt}yyu}yyWy:zu}wyu~yyt~yyu~y:zu~(xyHyzH(xuxu~uxxRxyu~yyt~yyu~yzu~Uxuxu~uxxr$xyu~#$yyt~#$yyu~#$yzu~#$yyu~xyu~yyt~yyu~yyu~xxRxyJyyJxy8yy8xxr xy yy xxr xyu~yyt~yyu~yyu~xy @yy @xx r  8!xyu}yyt}yyu}xyu}yyt}yyu}xyu~yyt~yyu~xyu~yyt~yyu~xyu~yyt~yyu~xyPyyPyyu~yyt~ yyu~yyt~ I ugI M RM W ug> M P>r&&,Q,4r6%47p6%7@P@Cu <%Q̇r6rx6xnQṅnWQgWgu`̇WnQnuQugur|u[|Ru[rP̆WQeWφu[Qeu[φچPQ_Pچu\u`P6 Q6 Q #p?#)P)4r?47p?7Qu ?/Q6/QCQ6CQu`u[Ru[Pu\u[Ru[PЇsusvt vP܉u +0+VvVV?MP+?u~Vu~܉u~+?u~V`u~`ePeu~܉u~+?u~ou~+?u~ru~Ru~+8PrPljՉu~ՉىRى܉u~ljىPsu~svt~u~su~svt~u~Ԉsu~svt~u~݈su~svt~u~݈PPsu~svt~su~svt~su~svt~3su~svt~I^u~^ePesu~svt~u uPoWqW0fVqVvĊV$fudud$-u02P$,u#DfudŠudGfucŠucGRPPqu0PuP#ʊՊucՊيRيucʊيPruttputtpҋutrVPVutVҋurzv#uttputtpustoustoPut<tp<PċusċȋRȋҋusȋP/ut/0tp0@ut@AtpAbut.V.0P0?V?@u@AtACVCbu v#/ut/0tp0@ut@Atp/us/0to0@us@Ato,P,/ut</0tp<07PITusTXRXbusIXPpPnjPnjٌPٌ݌P݌PPPP P  P PP)P)-P-9P9@P@IPIPPPYPY`P`zPz֍P֍Pr ;PpRVnjRnjV֍R֍V1R19V9;RV--Vnj݌6nj݌V݌݌VV  V  V-@-@V@P@PVP`P`V`zPz֍P֍Pr ;P֍WWudV֍RVR֍W֍u_P̍ӍP̍u`̍udPÍɍPPpud֍Vud u_Ru_ P1u`#u_#'R'1u_'P@_P_uPuPPPP@jRjuRuRRRRYuYjRjuRRRҎPҎTmPގRގUmRߎ0p1)MSp1)ȎkWkmߎ0DvPMSvPqvDU A AWvAU/AK/AWSWvDUSkWkmpďVˏVˏЏRɏRɏЏPϏPVЏ!!?V?AЏ!!@W@AV P!!˩P!@W@APac r u~r  P H u~H K t~K 8u~c l u~l  Q H u~H K t~K 8u~ H u~H K t~K 8u~  u~ " R" H u~H K t~K  u~  u~8u~  H  H G WG H u~H K t~K  W  W  u~ G w$G H u~H K t~K  w$  w$  u~ u~ H u~H K t~K  u~  u~ 0 P0 1 t1 ; tK V PV \ u > g u~  u~  u~> g u~  u~  u~X g u~  u~[ g u~  u~[ g P  PK o ƩK o u~  u~  u~  R  u~  Pg H u~H K t~o  u~| H u~H K t~o  u~ H u~H K t~o  u~ H u~H K t~o  u~ H u~H K t~o  u~  Po z P H u~H K t~ H u~H K t~ H u~H K t~ H u~H K t~ H u~H K t~pP<U<=PpRVtPtP)t)5P58t8=P0̐ݐp1);W;=0̐ VQؐQ T  WڐQ T ٩ W ;W;=@\VVXpRpRXpPpPqqVV! W !ʑVPʑԑ˩ԑP W !0ACRu~RtPtu~t~ku~CLu~LtQtu~t~ku~u~t~ku~u~Ru~t}u~u~ku~u~HHHkHu~Pu~t~u~u~u~ku~u~p$u~#$t~#$u~#$u~#$u~#$ku~#$u~u~t}u~u~u~ku~ P  t t&P&,u Au~Pu~u~u~5ku~Au~Pfu~fu~u~u~u~u~5ku~2Au~Pfu~fu~u~u~5Au~Pu~5ARP}RRPu~P}RRP Pfp|f}u~4p|u~4Zf Zfp| p|u~4Qp|u~7Ʃ7u~u~5ku~u~5ku~P5ZP`kP5ZP`kP?Zp`kpAH AHpAu~t~?Pu~Xu~t~?Pu~pu~t~?Pu~u~t~?Pu~u~t~?Pu~P?JPu~t~u~t~u~t~u~t~u~t~PkWkpwpWWٓ WSuVPVVP!V!*P*,VsyVyPVQPVQƒQƒuTuT%%pr"uTuTptRRptuTRptpuT"MsVsyudVPyu_u_PXPPXyu`^yud^oPۓudu_Ru_P u`u_R u_P˓u_˓ϓRϓٓu_ϓPugRugP'CPCu tÔPÔДu ДӔtӔ u %u D/Ӕ/DJWJKtKOtOu\tXӔu\udRudPquTtPӔuT%(uT(TudhruTqVutӔV%BVBTuhjVjru(BV3:u[:>R>Bu[3>PuTtPӔuTu[tWӔu[PPu`t\Ӕu`u`udt`ӔududPPu\tXӔu\udt`ӔudPӔߔPДuДӔt ΔVΔӔP %u\u[R%u[PBTudHOu[OSRSTu[HSPThu`Zau[aeRehu[ZePu`t\Pau`adXudt`Paudad\Pu`<t\<PWPPSSPu u PSSPuTuT?PuTBIu_IMRMPu_BMPlu`ryu_y}R}u_r}Pudu_Ru_PV V    V FFHVH` V V    V FFHVH` PsWuW=W 5 5V6VVVV22V2R2RVRrRrVrrVV_L=L_DD D3D_VV V  3 _DD _[[R[ PP_\\_DD#PPPLV3D!([(/R/3[!/P3=H9=[9=P5#FV5VV#VVFHVHVF>FVFV>VVFHVHVsnsVmީFVީmVFHVHV``[R[PHV`NV[NVPwVVVVVVVVWLWPWL W RWULUWPWLVE6EVEbEbVbbVVVVV""V"B"BVBwH$H&pH$H&wH$H& LH$H&UwH$H&pH$H&wH$H&DUuDDDVUuVVDUuD[Ue[elRlu[PblP\Ub\DUbDPU\PPp\uVD[R[PH[P2EUV2EVUVVVUVUVVVnVUީީUVV)U`9U`<K[KOROU[<OP`[PHNPNhuThitPiuTtP*uT'fVfhu hitiV V %u HfVfhu hitiV V %u iV V %u nV V %u  ud uducR ucPuc R *uc PWJkWzWu IuTIJtPJuTu`WJkWzWu RuPJYRYeuT#WJk0JYRYeuT#Yk1YeRY`rIu`IJt\ku`u`GVGJPkVIudIJt`kzudududHWkzWWWv IudIJt`kzud Iu_IJt[kzu_ PkwPPttudu_Ru_PIu`IJt\J0)u u Wu`t\Ww#PWu`t\WWVPVV/udt`udud2:P:uTtPuTuT/3vPudt`udSu_t[u_S[PPPttudu_Ru_P[u`t\[0&_WWWu &uTtPHuTH[u`1_WWWu 1BRBQuPRuT#=QW0RuT#1RrWu`t\-u`1Gu`WVP+Vnudt`ud)-ud1GudqWW)-W1GWqrvudt`udu_t[u_PPPt t1Gud7Bu_BFRFGu_7FPu`t\0u  I u  W  u`  t\ w W W  u`  t\ I WM e W V  P I VM O V ud  t`  udM e udP uT  tP  uTM e uTv ud  t`  ud u_  t[  u_P  P, ; P; < t< @ tO e udU ` u_` d Rd e u_U d P u`  t\ 046P6WʚW[W[Wŗיww[w[wȞwŗיuu[u[uȞuיuu[u[uȞuיuu[u[uȞuu#PtיSS[S[SȞSיuu[u[uȞu#יkk[k[kȞk#יuu[u[uȞuDיuu[u[uȞu_י  [ [ Ȟ _יuu[u[uȞu VӘSӘuqPӘuӘuיuu[u[uȞuיuu[u[uȞu!יuu[uruȞu!יuu[uruȞu$יuu[uruȞu$pW(W5EWr}W>יuu[uruȞu>pW(W5EWr}WTיuu[uȞuWיu`u`[u`Ȟu`WbP"Ptuu`Pbיuu([uȞubיuPuP([uPȞuPיuu(5uȞuΙWW(5WWuTtיuu(5uיu`u`(5u`P(/PGRPȞuȞu`ŞPיuuי00uϙיuPϙיuT]ruP]ruT#0u`#*P*0udڙututututu`t\u`t\Pu<t< PʚuPtʚu\ʚҚu Қ՚t՚ٚtʚҚw3PbV:GVӝ՝V1V3huh:u@:GuGu@ӝu@ӝ3uƛu#ƛ͛P͛ԛtۛhuh:u@:GuGu@ӝu@ӝu/uۛbV:GVӝ՝V/VuDuDRu:ouӝuvuDӝuD uXӝuX )P:AP՝uD۝uXRuX۝P!P!"t"&t):u@Gu@ӝu@):0G0ӝ0u@b:MGMӝMbePeV0:VGoVVy:MGMӝMy:uGuӝuy{u#pP:uGmuӝuV0:VGmVV:uLӝuLR:uӝuvǜ:uLʜ:uXʜϜP07PS_P_`t`dtӝuLĝ̝uX̝НRНӝuXĝНPϜ0uHϜ00ouHu`udPuduuuRuP<[uX<?u\?IPI[u\  u F!m!u z!!u E!uTE!F!tPF!!uT!!u`  W  uT#  p  PF!m!u`F!m!/F!b!u`#b!g!P E!u`E!F!t\m!!u`!!u` C!VC!F!Pm!!V E!udE!F!t`m!z!ud!!ud!!ud D!Wm!z!W!!W!!W  v!E!udE!F!t`m!z!ud !E!u_E!F!t[m!z!u_ !!Pm!w!P!!P!!t!!t!!ud!!u_!!R!!u_!!P!E!u`E!F!t\!F!0"S"u S"V"tV"Y"u "Q"VQ"S"udS"V"t`V"j"V""Q"VQ"S"udS"V"t`""V"0ОRfuTfgtPguTL uTWt t fu`fgt\gu`X u`ǟ eWefudfgt`gWud\WudǟϟWϟudW ududu_P!HVHfuu R1)(fgttR1)(guu R1)(R1)(ǟ͟Vٟ͟uu R1)(V uu R1)(!eWefudfgt`gWud\ǟϟWϟٟudW ud*HVHfuu R1)(fgttR1)(guu R1)(R1)(V uu R1)(*fuPfgtLguPH uPu_R u_PKeWefudfgt`gWud\Nfu_fgt[gu_WNUPU\w<gwPR\u`xu`X\W~udX_P~Pǟu`u_Rǟu_Pϟٟud՟ٟu_՟ٟPru Ϡܠu ru #Ϡܠu #vxPxvutlΠutΠϠluskΠusΠϠkǠPusRusP;DPDVOSPSqVV&V+3V8@VsKWKLuLOtvmWvLuLOtvmuv~PvP~Lu\LOtXmu\Lu`LOt\mu`PPLuTLOtPmuTLu`LOt\mu`PPLuPLOtLmuPLu`LOt\mu`PPLuHLOtDmuHLu`LOt\mu`PǣPLuDLOt@ͣmuDLu`LOt\ͣmu`ĢPͣףPĢLuLOtݣmuʢLu`LOt\ݣmu`ʢҢPݣPҢLuLOtmuآLu`LOt\mu`آPPLuLOtmuLu`LOt\mu`PPLuLOt muLu`LOt\ mu`P PLuLOtmuLu`LOt\mu` P'P Lu@LOt-mu@Lu`LOt\-mu`P-7PLuLLOtH=muLLu`LOt\=mu`&P=GP&LuXLOtTMmuX,Lu`LOt\Mmu`,4PMWP4LudLOt`]mud:Lu`LOt\]mu`:BP]gPou`{uRu{Pu\uRuPuTuRuPuPuRuPϤuHäʤuʤΤRΤϤuäΤPϤuDդܤuܤRuդPuuRuPuuRuPu uRu P)u$u$(R()u(P)>u/>u/=P>Pu@DKuKOROPuDOPPbuLV]u]aRabuVaPbtuXhouosRstuhsPtudzuRuzPSuDP٦u٦%uD%(t@()uD)<u<QuDQTTuDu9uDW٦uL)<uLWuLuDP٦u)<uuW٦uL)<uLæ٦W)<Wæ˦P)6P˦٦uHѦ٦udѦ٦P٦%uD%(t@<QuDQTTeuDʨuD49uD٦%ud%(t`<QudQT\Teudʨud49ud%ud%(t`<QudQT\Teud%u`%(t\<Qu`QTXTeu` PT_P %uD%(t@<QuDQT%ud%(t`<QudQT\P%uD<%(t@<<FPWu`)u`ΨШWШu`uDPu)uΨuWu`)u`W)WPPu\)u\ud)udPPuX )uXħud )udħȧP PȧuP)uPΧud)udΧҧP&PҧuTاudاPgquTmqudmqPquDw~uC~RuCwPuLudRudPuHudPʨudèu`èǨRǨʨu`ǨPШu`֨ݨudݨRud֨Pu\udRudPuXudRudP!uP udR!ud Phu0uuTRP٩uT٩ܩtPܩuTZשVשܩPܩVuud٩ud٩ܩt`uuc٩uc٩ܩt_ƩPuud٩ud٩ܩt`uduVשVשܩPVީVucRucPucRucPsV:lV#VsyWyztz~t~uX:luX#uXV:lVVϫV#VŪWŪu\:lu\Wu\ϫ׫W׫٫u\٫Wu\ W #u\ܫu\udPV:lVV#VV:lVVudV#udV:lV#Vu:lu#uuWR#uWPȪV:lV˪uW:luW˪ϪP:GPϪu\Jlu\ժudJludժ٪PJVP٪u`\lu`ߪud\ludߪP\fPuX&uXud"&udP",PtuXzuWRuWzPuduWRuWPu\uWRuWPϫu`ȫuWȫ̫R̫ϫuW̫Pw=uP=>H>uuPuPHuP=ud=>\>uudud\udu::άV>uVŭVu::άV>uV>u:>uVȬP̬=uP=>HuPH̬جPج;VV>;VVPW=uT=>LPuTL;VVPW0V1Rr>ͮͮ;VV+=ud=>\ud\.=uc=>[uc[.>PPͭحucحܭRܭucͭܭPJjkʮjU@u tt U UWU`UW'U@K$;U;CP"#W""####""""u !######B##vY##VY#d#Rd##uTk##v ##P##W#$P$y$W:$d$$$P$%V%%V$%S%f%Pf%%V%%V%%&&P&*'uP*'+'tL+' (uP%&u+'<'u''u''u=&&X''X' (X^&&}&&<}&&V&&T&&P&&V&&t&'v'('V&'pu "''P'#'R'#'P'#'QJ''''k''W''u''V''Q''VrPth#ܯHUHIAu 0*W*/w/AWAuT((((t((İPͱձP˰SWͱ̲ͱ *hhfvfoPv P((P) )P )n)V))V')e)))>)e)e))u#n))u#n))Wn))Vn))V))vt))V))V))vt))V))vt))v))v|))v))v|))ud))ud))P))P))u#))u# u#<))W))u# u#<))W)**u#)**u#)"*V))W)*W*"*wt)*w*"*w|*"*uc**P"***u#"***u# u#<&***u# u#<&*2*V^*m*P**P**V**V**f+p+VRp++VW++PW++VW+,VWt++1++0++1++V++P++V,,V++u++u++u4+C+v.sIWsWQeWs01RrhuPP^V^apҴV^v^ap#Ҵv_W`uL`atH^v^ap#PX,,u --u,, --- -,,,,u# ,,# ,,u# ,-t# - -u# ,,ud,,\,,ud,-t`- -ud,,P--P,,u#,,#,,u#,-t#,,ud,,\,,ud,-t`,,P,-3-uc3-7-R7-U-uc,-7-P>-E-ucE-I-RI-U-uc>-I-Pw-).V,..V--VJ..V--J.O.T.`.---).v ,.J.v .+.ud+.,.\,.J.ud ..P:.G.P.).v,.:.v.+.ud+.,.\,.:.ud..P,.7.Pl.s.ucs.w.Rw..ucl.w.P~..uc..R..uc~..PWVut'VfhPhWP4Wlv u# t# v,u#,t#,..u#..t#.@/u#@/A/t#A/I/u#..P.>/VA/C/V/A/w//V/0V00u//v//P//v/0v00u#//P//W//P/)0W/0R0u0vu031u#C11u#0;1VS11V01Vr11V01r1w1|11011;1v S1r1v !1;1udS1r1ud!1%1Pb1o1P%1;1vS1b1v+1;1udS1b1ud+1/1PS1_1P11uc11R11uc11P11uc11R11uc11P|PVPLVvPvpLvPWƶPƶ)W:BW':L'12u 3,3u @3D3u H3N3u u3y3u }33u 1H2WH23u\33T3,3W,3?3u\?3@3tX@3u3u\u3y3Wy3}3u\}33W33u\}33u\33ud33R33ud33P2H2WH23u\@3D3u\H3V3u\y3}3u\33u\23V@3B3VB3D3uH3N3uy3{3V22WQ2x2@3D3H3V3c2x2x23u\y3}3u\33u\23y3}33323v23V23W23v 33u\33T,3?3u\?3@3tX 33ud33\,3?3ud?3@3t` 33P,373PV3l3u\\3g3u[g3k3Rk3l3u[\3k3P3/4u /404t04V4u V4W4W44u 3/4u #/404t#04V4u #V4W4#W44u #34WW4_4Wa4p4W33V33t33t3/4u`/404t\04V4u`V4W4XW44u`34Wa4p4W3-4V-4/4ud/404t`04T4VT4V4udV4W4\a4c4Vc4e4ude4g4Vg44ud4-4V-4/4ud/404t`04T4VT4V4udV4W4\4 4P 4/4u/404t04V4uV4W44-4V-4/4ud/404t`04T4VT4V4udV4W4\4/4u_/404t[04V4u_V4W4W4!4P!4(4v<0474P4(4u`84B4u`$4(4V>4B4ud$404P>4N4Pg44uds4z4u_z4~4R~44u_s4~4P44u_44R44u_44P44P485W8595u95:5t:5y5Wy55u475V7595ud95:5t`:5a5Vn5p5Vp55ud485W8595u95:5t:5a5Wn5y5Wy55u575V7595ud95:5t`:5a5V595u_95:5t[:5a5u_55P5#5v<:5G5P5#5u`H5S5u`5#5VN5S5ud5#5PN5^5P#585w8595u#95:5t#p55ud|55u_55R55u_|55P55u_55R55u_55P56V77V77V55W57u 77t77u 777x8u }8 9u 55w57u #77t#77u #77#7x8u #}8 9u ##67!7>8!}88!9 9!#6)6V)6*6t*6.6u.67uH77tD77uH77@7>8uH}88uH9 9uH867!7,8!}88!88!9 9!86T6VT67uL77tH77uL77D7,8uL}88uL88V88uL88V88V88uL9 9uL88uL88ud88R88ud88PQ67(78(}88(9 9(Q6r6Wr67uX77tT77uX77P78uX}88uX88W88uX88W88uX9 9uXf67(78(}88(9 9(f66V67u\77tX77u\77T77V78u\}88V88u\88V88u\9 9V88u\88ud88R88ud88P67W77ud77t`77W77ud77\77ud99W9 9ud67u77t77u7777u9 9u67W77ud77t`77W77ud77\67uC77t77uC7766P66w<77P66u\7"7u\66W7"7ud66P7.7P66uX/7=7uX66ud57=7ud66P57F7P66uLG7U7uL66udM7U7ud66PM7^7P66uH_7m7uH66ude7m7ud66Pe7v7P66uDw77uD66ud}77ud66P}77P66uT77uT66ud77ud66P77P66u`77u`66ud77ud67P77P77ud77uC77R77uC77P78u\78uC88R88uC78P88uX88uC88R88uC88P8,8uL 8'8uC'8+8R+8,8uC 8+8P,8>8uH2898uC98=8R=8>8uC28=8P>8P8uDD8K8uCK8O8RO8P8uCD8O8PP8b8uTV8]8uC]8a8Ra8b8uCV8a8Pb8}8u`h8}8uPh8s8P'94:V7:l:Vl:n:un:p:Vp:x:u594:v7:l:vl:n:u#n:p:vp:x:u#n9#:WK::W99Wj::W99j:n:r::999#:w K:j:w :#:udK:j:ud: :PZ:g:P :#:wK:Z:w:#:udK:Z:ud::PK:W:P::uc::R::uc::P::uc::R::uc::Pgjv jrPruPtLpuPpqtLquPgjv jrPruPtLpuPpqtLquP{}P}uLtHPpuLpqtHquLʷҪqҪ1q11uPtLpuPpqtLuPPPnVV*qKqv ¸P¸uLtHùuLùĹtHĹuLv ¸P¸uLtHùuLùĹtHĹuL˸͸P͸uPP`uPĹٹuP`ҪĹٹҪ;`D`ĹDٹDuLtH`ùuLùĹtHٹuLPV`fPfVٹVzĹٹĹ7:v:BPBuLtHSuLSTtHT~uL7:v:BPBuLtHSuLSTtHT~uLKMPMkuPPuPTiuPҪTiҪúkTi~kuLtHSuLSTtHi~uLw|P|VPQViqV Ti~+TvPuLtHuLtH޼uLvPuLtHuLtH޼uLP˻uPPHuPɼuPHҪɼҪ#H˻Hɼ޼˻uLtHHuLtHɼ޼uL׻ܻPܻVHVPVVɼѼVjɼ޼u#,u#,PfuTVNVNSvxSV$V$)vx)NVNXvx$v$)v|)NvNXv|)ud/fudP!v</:P$V$)vx;NVNXvx!ud@Dud)P@RPfu#,fnu#4u#,8frPjnu#4u#,8jrPvu# u# PuTVVvl8VVvlVvlvv|vv|ud½udPv<½ͽPv νؽv udԽؽudPԽPvvududPPu# u#(u# D"Pu#(u# D"P&,u,0t8NPNVV::W::t:;t;<<uX<<=<P=<_<uX_<`<tT`<<uX:;u=<L<un<r<uv<<u<<u:;u#=<L<u#n<r<u#v<<u#<<u#::W::t:;t;<<uX<<=<P=<_<uX_<`<tT`<<uX:$<V=<L<Vj<~<V<<V<<V<<V ;v<S<<S<<S ;_;W_;<<u\<<=<T=<L<WL<_<u\_<`<tX`<n<u\n<p<Wp<v<u\<<u\<<u\<<u\<<ud<<R<<ud<<P&;_;W_;<u\r<v<u\<<u\<<u\&;<Vr<v<V<<V<<V;;Wh;;<<z;;;<u\r<v<u\<<u\;<r<v<<<;<v;<V;<W<<v <<<u\<<=<TL<_<u\_<`<tX`<j<u\'<<<ud<<=<\L<_<ud_<`<t``<j<ud'<+<P`<g<P<<u\<<uW<<R<<uW<<P+<<<uX<<=<PL<_<uX_<`<tT1<<<ud<<=<\L<_<ud_<`<t`1<=<PL<W<P<<uX<<uW<<R<<uW<<P$=5=W5=6=t6===t==>uX>>tT>>uX>>tT> ?uX%?M?uXW?v?uX$==u>>u>>u>>u%?+?u[?f?u$==u#>>u#>>u#>>u#%?+?u#[?f?u#*=5=W5=6=t6===t==>uX>>tT>>uX>>tT> ?uX%?M?uXW?v?uX*=`>V>>V>>V>>V%?S>>S%?M?SW?v?SG==W=>u\>>tX>>W>>u\>>tX>>u\>>u\%?M?u\W?_?u\_?a?Wa?v?u\>>u\>>ud>>R>>ud>>Pb==W=T>u\%?3?u\W?_?u\f?v?u\b=T>V%?3?VW?_?Vf?v?V=>W==%?3?[?_?===T>u\W?[?u\f?v?u\>T>W?[?f?v?>T>v2>T>V2>T>WA>T>v W>>u\>>tX>>u\>>tX>>u\c>>ud>>t`>>ud>>t`>>udc>j>Pj>q>u\<>>P3?M?u\??F?uSF?J?RJ?M?uS??J?Pg>q>uX>>uXm>q>ud>>udm>q>P>>Pq>>uT>>tP>>uT>>tPw>>ud>>t`>>ud>>t`w>>P>>P> ?uX>?uS? ?R ? ?uS> ?P ?%?uT??uS??R?%?uS??P?@u ,ADPCCuH?DIDuHCCu\EDIDu\CCPEDVDPCCuTWDaDuTCCu\]DaDu\CCP]DnDPDDu\DDuGDDRDDuGDDPDDuXDDuGDDRDDuGDDPDDuPDDuGDDRDDuGDDPDDuLDDuGDDRDDuGDDPDDuHDDuGDDRDDuGDDPDEuTDDuGDDRDEuGDDPEEVEkFu kFlFtlFFu FFtFGu GGu GGVGGu EEp0)EkFukFlFtlFFuFFtFkGuGGuGGuEYGGGGGGGEEVEEtEEtEkFuLkFlFtHlFFuLFFtHFYGuLGGuLGGuLGGuLEFGGGGGGGGGE$FV$FkFuPkFlFtLlFFuPFFtLG GV G GuP GGVGGGuPGGVGGuPGGVGGVGGVGGuPGGu\GGRGGu\GGPEFG5GGGGGEEWEEtEEtEkFuXkFlFtTlFFuXFFtTG5GuXGGuXGGuXFF G#GGGGGFjFWjFkFu\kFlFtXlFFWFFu\FFtX G#Gu\GGWGGu\GGWFjFWjFkFu\kFlFtXlFFWFFu\FFtXGGWFFPFkFukFlFtlFFuFFtGGu'FjFWjFkFu\kFlFtXlFFWFFu\FFtX*FkFuGkFlFtClFFuGFFtC*F1FP1F8Fw<lFwFP.F8FuXxFFuX4F8FW~FFu\4F;FP~FFP8FBFuPFFuP>FBFu\FFu\>FEFPFFPBFLFuLFFuLHFLFu\FFu\HFOFPFFPLFVFuHFFuHRFVFu\FFu\RFYFPFFPVFdFuTFFuT\FdFu\FFu\\FlFPFFP G#Gu\GGuGG"GR"G#GuGG"GP#G5GuX)G0GuG0G4GR4G5GuG)G4GP5GGGuP;GBGuGBGFGRFGGGuG;GFGPGGYGuLMGTGuGTGXGRXGYGuGMGXGPYGkGuH_GfGuGfGjGRjGkGuG_GjGPkGGuTqGxGuGxG|GR|GGuGqG|GPWVwd dVdwdZW Wvtttvu\Qbu\u[Qbu[PQ_Pjuu[uyRyu[jyPAu\DuWDHPvP^vuXavu`apPuXu`Ru`PuWRuWP15P5)uH)*tD*=uHM_uHuHP'VM_VPR)uT)*tP*uT/DPDKRk)uD)*t@*uDuDuDn)u[)*tW*u[u[u[nyPyuD<mwPvuTxu`|uD~u\|P~Pu\=Mu\u[=Mu[P=GPPR)u`)*t\*=u`Mmu`u`)u\)*tX*=u\Mmu\u\"P_gPT\P\u@*=u@u@]u@*=u@u@u`*=u`u\*=u\P*7Pu`u\Pu`u[Pu\u[Pu[Ru[P HHP HHuHHtHvIuvIwItwIIuJ#Ju-JLJuCHIJJ!J#J-JLJCHIHVIHJHtJHNHtNHHuLHHtHHvIuLvIwItHwIIuLJJuL!J#JuL-JLJuLXHwIIIJJ!J#J-JLJXHHVHHuPHHtLHvIuPvIwItLIIVIIuPIIVIIuPJJVJJuPJJV!J#JV-J8JV8JLJuP;JBJu\BJFJRFJLJu\;JFJPqHwIIIJJ!J#JqHwHWwHxHtxH|Ht|HHuXHHtTHvIuXvIwItTIIuXJJuX!J#JuXHwIIIJJ!J#JHHWHHu\HHtXHuIWuIvIu\vIwItXIIu\JJWJJu\!J#JWHHWHHu\HHtXHuIWuIvIu\vIwItX!J#JWHHPHHuHHtHvIuvIwIt!J#JuHHWHHu\HHtXHuIWuIvIu\vIwItXHHuGHHtCHvIuGvIwItCHHPHHw<HHPHHuXHIuXHHWHIu\HHPHIPHHuPIIuPHHu\IIu\HHPI&IPHHuL'I1IuLHHu\-I1Iu\HHP-I>IPHHuH?IIIuHHHu\EIIIu\HHPEIVIPHHuTWIaIuTHHu\]IaIu\HHP]InIPIIu\IIuGIIRIIuGIIPIIuXIIuGIIRIIuGIIPIIuPIIuGIIRIIuGIIPIIuLIIuGIIRIIuGIIPIIuHIIuGIIRIIuGIIPIJuTIIuGIIRIJuGIIP:H0HVEV:W[W[tZmRmpv"Spv"Spv"S pv" Spv"&S&Zpv"ZxSxpv"Spv"Spv"[SxxLxL#&&L&L#WxJWxLnrQrxZjrPLL#LL#LL#&xS[SxLrYPLrXP[ [LL#PC`CLL#P C CL L#P"C`%7[7;R;C[%/P/4`<4;PE[`KV[VZRZ[[KZPL[pLVCEVqsVyWqyWOu\u\Wu\#pPu\O  u\#pPOKKpPOududu\#  p POKKp$P+Oudud.Ou[u[.:PP:Ou`u`@Oudud@LPPOuTuTC{uTOC]Ou\u\C]u\u\#pPE]udQXu[X\R\]u[Q\P]qu`cju[jnRnqu[cnP)u\),T.Cu\pJsJPsJKVKKuP<KKtL<K LV LLuP<LLH<LLVLLuP<LLVLLuP<LSLVSLjLuP<}LLVpJsJp4sJ}JP}JKuTKKv4KKuP#(KKtL#(K Lv4 LLuP#(LLH#(LLuTLLv4LLuP#(LSLuTSLjLuP#(}LLuTJKVKKuP<KKtL<K LV LLuP<LLH<LLVLLuP<LLVLLuP<LSLVSLjLuP<}LLVKKvKKuP4KKtL4K Lv LLuP4LLH4LLvLLuP4LLvLLuP4L,LvSLjLuP4}LLvL,LVjKLHLLHSLLHjKKQKKuPKKtLKLuPLLHLLuPSLjLuP}LLuPKKuP#$KKtL#$KLuP#$LLH#$LLuP#$SLjLuP#$}LLuP#$,LSLv4KKVKKuP<KKtL<K LV LLuP<LLH<LLVLLuP<LLVLLuP<SLjLuP<KKPKKuKKtKLuLLLLuLLuSLjLuKKudKKt`KLudLL\LLudSLiLudKKu#KKudKKt`KLudLL\KKucKKt_KLucLL[KLPSLiLudYLdLucdLhLRhLiLucYLhLPiLjLupLtLt0<W<DPD0WQ0QeWeV0W[0e[CuCDtDVuVeu@uuu@[uu#PCuCDtDVuuuu@[u Wu#pP.Qu@&.SQVSS[S&;p;@P|,DV,|u@DVu@:u@uHu@u@#pPuHudPuVeVzueaeudududud7Dud!@udud 7D!@ u@7Du@!@u@7Du@7Du@5uT7DuT5u@7Du@58u@#<?p?DPJS7DSJu@7Du@VT7DTVu@7Du@ouX7DuXou@7Du@oru@#vypy~PuT7DuTud7DudP7>PuXudP.PP'7uP*7ud*7P7@[7u@@[u@7G7u@7SP$V7T$V 7uP $V v#uXu`Ru`P#@uT/@ud/:P!!u@u@!:!u@!uD!u@u@#p P!uD!ud!PPPu@u@:u@uLu@u@#pPuLudPFVuHRVudRVPuLudPuD ud PCuCDtuQeuCudCDt`udQeudPQ_PCu@CDtu@D00,CuCDtu2CudCDt`ud2<PPVeu@eukrurvRvukvPu`udPPrPPPrPƮ!ƮKƮV!VKVv#Pu uKuV VKVu uKu WKMWuT uTKuT WKMWuT uTeuTu` u`eu`PPMeudS^u`^bRbeu`SbP  e u\u\eu\+u\#+0P:ЮЮeЮ:u\u\eu\:Cu\#CHPJ0q0qe0qJu\u\eu\Ju u eu JQu\#Y_p_dPnݮݮeݮnwu\#w|Pu`u`ududPP!u\hu`nudnyPu\TƮ!KƮƮV!KVVv#Pu!9uuV!9VVu!9uu+WWuT!9uTuT+WW.uT!9uT1u`!9u`19PPu`Ru`P9 !9 9u\!9u\9Ku\#KPPZ!9Zu\!9u\Zcu\#chPk0q!90qku\!9u\!9u\#Pu`udPP$9u`*9ud*5P9Ku\PFWHeWekPkqWsW"V"GuGHtHeuepVprursts}u}VueTsTGuTGHtPHeuTsuTuduT#Pe|s}|GuTGHtPHeuTs}uT"V"GuGHtHeus}uuT#r P GuTGHtPHeuTs}uT e0s}0P1W3<W//WWP0V3V/VV>Y>uTuTuT+ud+DuTDYudUCUuTuTuT+ud+CuTpCpuTuTuT+ud+CuTCuTuTuT+ud+CuTCuTuTuT+ud+CuTCuTuTuT+ud+CuT  C uTuTuT+ud+CuT!:!))C)uTuTuT+ud+CuTQQCQuTuTuT+ud+CuTCuTuTuT+ud+CuT  C uTuTuT+ud+CuT!))C)!uTuTuT+ud+CuT0ޮޮCޮ0uTuTuT+ud+CuTQuTuTuT+ud+CuTsuTuTvu\u\vPPud u\Ru\ P+u`3Cu`GYudxxVVuTudVuTVuTVuTudVVuTudVuTVuT  VVuTudVuTVuT))VVuTudVuTVuTVVuTudVuTVuTVVuTudVuTVuT((VVuTudVuTVuTCVVuTudVuTVuTeVVhu`u`hpPPudu`Ru`Pu\u\udD"xxYxDW"VVY[V[ruTrudVuTVuTuda"YaW"VVY[V[ruTrudVuTVuTp"  Y pW"VVY[V[ruTrudVuTVuT"::Y:W"VVY[V[ruTrudVuTVuT"YW"VVY[V[ruTrudVuTVuT"YW"VVY[V[ruTrudVuTVuT"YW"VVY[V[ruTrudVuTVuT"VVY[V[ruTrudVuTVuT"VV"u`u`PP[qudalu`lpRpqu`apPquXuX*WWU[uTUvyPyRudt`udPRVu`t\Vu_t[u_PPudt`udu`t\u`PPudu_Ru_Pu_Ru_P"P"WPWW.ff.uTtPuTud.@uT#@EPIIuTtPuTMgVMUuT#]apafPududt`0$R$VRVeRejVj|R%uTL-uT-.L.|uT%7uT#7<P@e˓@uTL-uT-.L.euTudkud\-ud-.\.eud0Vu`pv"PudPRud\-ud-.\u`X-u`-.Xud\-ud-.\Pu`<X<"P0Ou`6Au_AEREOu_6EPTcudPPlllkkRkPPNTPTYV=Hl\tktxRxk\iPill<lxPP"W(PWuTy{{(S{n{{yuDuD(CuDCSu\nuDu\uDu\qPyuTuT(SuTnuTyuDuD(CuDCSu\nuDu\ q P(yuDuD(CuDCSu\nuDu\(y00(S0n0kyuTuTqyududq~PPU(SUnUWu`(PWPSu`nWud(:udu\(:u\P(7Pu`CSu`SnuTY`uS`dRdnuSYdPqud}u\}PVudt`0cu u u cvu@vytyu@#u`#Ku@nu u u nWvuTvytPyWuTW#AWqu u u qVVVvuvytyu#=uVVVvuvytyu#=uvu\vytXyu\#=u\PPuXu\Ru\PvuTvytPyuTuT#=uTvu`vyt\yu`u`#=u`tVtvu\vytXyVV#%V%=u\PvuDvyt@yuDuD#=uDuDttVtvu\vytXyVVvuXvytTyuXuXPyPPtt%=u\+=uX+:PvuTvytPuTy00uT7vu`vyt\u`7vudvyt`ud7y00SlWWXlu\u\X`PP#u`#ud|uDt@.uD.BuTBDuDDVuTVouDouTuD|uD#P   , B uDt@,uDBDuDDVuTVouDouTuDWuD#pP uTWWujuTuT#pPuTuT#pPv ,vBvuTtPuT ,uTBuT uT#pP  , B uTtPuT ,uTBuT%?V%)uT#59p9>PuTHcHcuTHSuT#WZpZ_PcVvvuTvuT#pPuTuT#pPuTtPuT ,uTBuTSVSu`t\V V,u`BDVDVu`VXVXu`Vu`uTtPuT ,uTVuTu@tu@ ,u@Vou@ouXu@uWu\tXW ,WVnWutu ,uVnuWu\tXW ,WuStOuS ,uSP PXnu\^iuSimRmnuS^mPuXtTuX,uX0,0nuX;u`t\,u`;udt`,ud;0,0WtV,V\tu\,u\\hP&PtuTtPt0.BuTDVu`DGudGPPPVudWu`!t\@ZWu_!t[@Zu_ PIWP ud!t`@Iudu`!t\@Iu`P@FPeudksu_swRwu_kwPu_Ru_P-W-.u`.1t\PjW.u_.1t[Pju_PYgP.ud.1t`PYud .u`.1t\PYu` %PPVPuud{u_Ru_{Pu_Ru_P =W=>u`>At\`zW#>u_>At[`zu_#*PiwP*>ud>At``iud0>u`>At\`iu`05P`fPudu_Ru_Pu_Ru_Pr 6uu6u#u#r6u #u #r6uu W!W57W w#P t'W W'6uuBudud udEMPMuTuTuTcududfu_u_fnPPPtt udu_R u_Pnu`n0!u`[%2[xz % %%CnV"u`"%t\CSu`SWVWnu`%CTigW"u"%tCTuiSuSgWw#PW"u"%tCTuiSuWgu%ըCTըiSըP'V=?V%ըCTըiSը-u-"u"%tCTui=u=@u@Suu#P -u-"u"%tCTui=u?Su'%ƯCTƯi=Ư'*P*VVV')V>%ƯCTƯi=Ư>juj"u"%tCTui'u'*u*=u>Gu#GLPZjuj"u"%tCTui'u)=ud%CTi'dVVVxu"u"%tCTuiuu'uxuuuxpPu"u"%tCTuiu'u%˯CT˯i˯VV%˯CT˯i˯u"u"%tCTuiuuuu#Pu"u"%tCTuiuu%ܯCTܯiܯPKuu%ܯCTܯiܯ5V5"u"%tCTuiuVtu v# P5V5"u"%tCTuiuu5%CTi5<P<VVVVF%CTiFnWn"u@"%tCTu@iu@WFRw#RWPcnWn"u@"%tCTu@iu@u@k%tCTtitkVVV|W"uD"%t@CTuDiuDW|"u"%tCFuilu|uuuuu|pPW"uD"%t@CTuDiuDuD%CTiVV%CTiW"uH"%tDCTuHiuHWw#PW"uH"%tDCTuHiuHuH%CTiPV|~VVV%CTiW"uL"%tHCTuLiuLWpP W"uL"%tHCTuLiuLuL%CTiV|~VV$IWI"uP"%tLCTuPiuPW$"u"%tCFuilu|uu$-p-2P>IWI"uP"%tLCTuPiuPuPF%CTiFV|~VZ%CTiZW"uT"%tPCTuTi|uT|WZcw#chPtW"uT"%tPCTuTi|uT~uT%CTi|P!WCEWikW%CTi|V"uX"%tTCTuXirVrvtv|uXpPV"uX"%tTCTuXk|uX%CT!WCEWV"u\"%tXCLVLPtPTu\"u"%t~CFupPV"u\"%tXETu\ "u`"%t\ P"ud"%t`Tiu`TYudY`P`iudLTTWLTTWU'UMMTU'U|U'UQU5MMTUQU|U5MMTUQU|UWMMVWTUVWQUpUVWyMMPRTTPR5MWMWMMTUQUpUpU|UWMMTUQUpUMTH|UWHMMu|MMPM\NW\NTu|TTt||UUu|UUWUUu|UQVu|QVVu|VVu|VVu|VVu|VVu|VVu|VWu|MMu}MMPMOu|OOu~OOPOTu|TTt||UUu|UUu|UUu|U;Vu~QVVu|VVu|VVu~VVu|VVu~VVu|VVu~VVu|VWu|WWu|N\NW\NTu|TTt||UUu|UUWUUu|UQVu|QVVu|VVu|VVu|VVu|VVu|VVu|VWu|^NOWOTu|TTt||UUu|UUWUQVu|QVWVWWVoVu|VVu|VVWVWu|QVoVu|OTH|UUHUQVHVWHOGOu|GO_OQ_OOu|OPu|P Qu~ QQRQrQu|rQTu~TTt~|UUu~U;Vu~VVu~VVu|VWu|W9Wu|^WWu|WWu~4OGOu}GO_Oq$_OOu|#$OPu}P Qu~ QQr$QrQu|#$rQTu~TTt~|UUu~U;Vu~VVu~VVu|#$VWu|#$W9Wu}^WWu|#$WWu~oVVu}iOTA|UUAUQVAVVAVVAWWAiOOWOTu|TTt||UUu|UQVu|VVu|VVu|WWu|iOlO upt" lOrOuw<" $Q'Q upt"'Q-Q uw<"iOTA|UUAUQVAVVAVVAWWAiOlO upt" lOrO uw<" $Q'Q upt"'Q-Q uw<"OOu|OOWOTu|TTt||UUu|UQVu|VVu|VVu|WWu|OTH|UUHU;VHVVHWWHOOu~OOPO"PW"PTu|TTt||UUu|UUu|U;Vu~VVu|VVu~VVu|VVu~VVu|VVu~WWWWWu|OOu~OOPOTu|TTt||UUu|UUu|U;Vu~VVu|VVu~VVu|VVu~VVu|VVu~WWu|O"PW"PTu|TTt||UUu|UUu|U;Vu~VVu|VVu~VVu|VVu~VVu|VVu~WWWWWu|"P1Pu~1P}QW}QTu~TTt~|UUu~U;Vu~VVu~W)WW)W9Wu~^W`WW`WbWu~bWiWWiWWu~WWWWWu~W9Wu~PTH|UUHU;VHVVH^WWHP Qu~ QQRQrQu|rQTu~TTt~|UUu~U;Vu~VVu~^WWu|WWu~P Qu~ QQr$QrQu|#$rQTu~TTt~|UUu~U;Vu~VVu~^WWu|#$WWu~9W^Wu~$QTA|UUAU;VAVVAbWiWAWWA$Q}QW}QTu~TTt~|UUu~U;Vu~VVu~bWiWWWWWWWu~$Q'Q upt"'Q-Q uw<"$QTA|UUAU;VAVVAbWiWAWWA$Q'Q upt"'Q-Q uw<"?QYQu|?Q}QW}QTu~TTt~|UUu~U;Vu~VVu~bWiWWWWWWWu~QT|UUUUVVQQWQTu|TTt{|UUu|UUu|UUu|VVu|VVWVVu|VVu|VVu|VVu|VVu|VVu|QT|UUUUVVQQVQTu|TTt||UUu|UUu|VVVVVu|VVVVVtVVu|QQv#QQPQQVQTu|TTt||UUu|UUu|VVu|VVu|VVu|QT |UU UU VV VV QQPQ!RWVVWQT |UU UU VV VV QRVRTu|TTt||UUu|UUu|VVVVVu|VVVVVtVVu|QQv#QQPRRVRTu|TTt||UUu|UUu|VVu|VVu|VVu|!RT7|UU7UU7VV7VV7!R(RP(R|RWVVW2RT7|UU7UU7VV7VV72RXRVXRTu|TTt||UUu|UUu|VVVVVVVVtVVu|2R>Rv#>RCRPORXRVXRTu|TTt||UUu|UUu|VVu||RT|UUUU|RRPRRWUUWRT|UUUURRVRTu|TTt||UUu|UUVUUVUUtUUu|RRv#RRPRRVRTu|TTt||UUu|UUu|RTu|TTt{|UUu|RRPRTu|TTt||UUu|RTu|TTt||UUu|RTu|TTt{|UUu|RRPUUPRTu|TTt||UUu|UUu|RTu|TTt||UUu|UUu|RSPUUPSTu~TTt~|UUu~UUu~5STu~TTt~|UUu~UUu~DSTu~TTu}TTt}|UUu}UUu~MSTu|TTt||UUu|UUu|MSYSPUUPYS3Tu~3TTu|TTt||UUu~vSTu~TTt~|UUu~STu~TTt~|UUu~STu~TTt~|UUu~STu~TTu}TTt}|UUu~STu|TTt||UUu|TTu|TTt||UUu|TTu}TTt}|UUu}'TTu~TTt~|UUu~'T3TP|UUP3TTu|TTt|PTTu|TTt|mTTu|TTt|TTu|TTt|TTu}TTt}UUu|UUu|UUPUUu|UVu|U Vu| V VR VVu|U VPV*Vu|V%Vu|%V)VR)V*Vu|V)VP )He Vu`t\VV)-V-Hu`egVgvu`vzVzu`Vu`Vu`)8eAWAuPtLuPuP)8uPevuPvWuP'w#',P8AWAuPtLuPuP)8uPevuPuPzuPR)8evRYPYuehuc)8evcWuTtPuTuT)8uTevWuTclw#lqPWuTtPuTuT)8uTuTgvuT)8Pu)*u)8WuXtTuXuX)8WuXw#PWuXtTuXuXuX-8uXPduuuWu\tXWWWw#PWu\tXWWu\6Vu`t\VV6udt`udud600VlQQuaxWWalPPxuHtDuH~u`t\u`~PPuLtHuLu`t\u`PP )uLuGR)uGP8Hu`8=ud=DPDHudHeuHT^uG^bRbeuGTbP%&uD&u`t\u`uD%u`%#W#uLtHuLuLuL%WqP #W#uLtHuLuLuL&&-P-ouDuD77\W\uPtLuPuPW7@w#@EPS\W\uPtLuPuPuPo@@@ovPvuDuD@@@WuTtPuTWuTw#PWuTtPuTuTuT)))PuDuD)))WuXtTuXWuXw#PWuXtTuXuXuXKKKPduDuDKKKWu\tXWWw# P.Wu\tXWu\Gu`t\u`Gudt`udG00fhPhuDuDnWWnvPvu@<Pu@<u`udPudo 8ouDu` t\8u`uDu` 8XmWuL tH8XuLmuLuLWqPWuL tH8XuLmuLuL 8XmPuDuD 8XmWuP tL8XuPmuPWw#PWuP tL8XuPmuPuP 08X0m0PHuDmpuD 08X0m0EWEuT tP8XuTm~W~uTw#P,EWEuT tP8XuT~uTo~uTH )8X)~)HOPOuDIJuDY )8X)~)Y~W~uX tT8IuXIXW~uXYbw#bgPu~W~uX tT8IuX~uXMXuX K8IK~KPuD~uD K8IK~KWu\ tX8IW~Ww#PWu\ tX8IWu\u` t\8Iu`ud t`8Iud 08I0PuD8IuDW8IWPu@<8FPFIu@<Xmu`X]ud]dPdmudR;R;JRJR00`0P;EPEJuQ;JQQP]0S`zSS]dPdWikWn0S`zSSnV0uL`iuLirVrvtvzuLuLnpv#wzpzPV0uL`iuLuLkzuL0M`iMMu0M`iMMV0uP`iuPuPVtuPqPV0uP`iuPuP0R`iRRu+0R`iRR+]V]0uT`iuTuTVtuT+1q16PD]V]0uT`iuTuTuT`0S`iSS`gPg0u`iuuun0S`iSSnV0uX`iuXuXVtuXnvpv{PV0uX`iuXuXuX0K`iKKPWW0K`iKK0V`iVVtu\pP0V`iVu\0u``iu`0ud`iud00`i00W`iW0V`iV$P`fPzu`zudPud pd pth# #*p*2d2< #p#$t$2h2<@kRk? R0? 0Cutuu  u  u, / uCut uu  u  u, / uSS S ? SPW, . WSS S ? SVuLuL uL , uL, 5 V5 9 t9 ? uLv#PVuLuL uL , uL'MM M , M'-uAMM M , MAjVjuPuP uP " V" & t& , uPAGqGLPZjVjuPuP uP , uPRR RuRR RVuTuTVt uTqPVuTuT  uT uTSS  SPuu  uSS  SVuXuXVtuX  uXpPVuXuX  uXuX)KK  K)0P0fW  W7KK  K7VV  V  t  u\7?p?DPPVV  u\iu`u`iududi00WWVVPPu`udPudWU_s_aWU_s_aW0X__W0XW0XX0XQX$XP$X0Xu@K$!uu0*(WXX0XX0X0XU_H_aH0X6Xu|6XGXPGXXWXR_u|R_U_t|__u|__W_`u|``u|``u|``u|``u|``u|`au|aau|aau|0XGXu}GXRXPRXZu|Z+Zu~+Z8ZP8ZR_u|R_U_t|__u|_`u|``u|`k`u~``u|``u|``u~``u|``u~`au|aau~aau|aGau|Gaau|XXWXR_u|R_U_t|__u|__W_`u|``u|``u|``u|``u|``u|`au|aau|aau|XXu|XZWZR_u|R_U_t|__u|_`W``u|``W``u|`au|aaWaau|``u|YU_H__H``H`aHYYu|YYQY4Zu|4ZR[u|R[[u~[[Q[[u|[R_u~R_U_t~__u~`k`u~`au~aau|aGau|Gaiau|aau|aau~aau|aau~YYu}YYq$Y4Zu|#$4ZR[u}R[[u~[[q$[[u|#$[R_u~R_U_t~__u~`k`u~`au~aau|#$aGau|#$Gaiau}aau|#$aau~aau|#$aau~``u}YU_8__8``8`a8aa8Gaa8YZWZR_u|R_U_t|__u|``u|`au|aau|Gaau|YZuw<" [[ uw<"YU_8__8``8`a8aa8Gaa8YZ uw<" [[ uw<"ZR_uR_U_t__u``u``u``u`auaauGaauZZWZR_u|R_U_t|__u|``u|`au|aau|Gaau|ZU_H__H`k`H`aHGaaHZZu~Z+ZP+ZZWZR_u|R_U_t|__u|``u|`k`u~``u|``u~``u|``u~`au|aau~GaKaWKaau|Z+Zu~+Z8ZP8ZR_u|R_U_t|__u|``u|`k`u~``u|``u~``u|``u~`au|aau~Gaau|yZZWZR_u|R_U_t|__u|``u|`k`u~``u|``u~``u|``u~`au|aau~GaKaWKaau|ZZu~Z \W \R_u~R_U_t~__u~`k`u~`au~KaYaWYaiau~aaWaau~aaWaau~aaWaau~Maiau~R[U_H__H`k`H`aHaaHR[[u~[[Q[[u|[R_u~R_U_t~__u~`k`u~`au~aau|aau~aau|aau~[[u~[[q$[[u|#$[R_u~R_U_t~__u~`k`u~`au~aau|#$aau~aau|#$aau~iaau~[U_8__8`k`8`a8aa8aa8[ \W \R_u~R_U_t~__u~`k`u~`au~aaWaaWaau~[[ uw<"[U_8__8`k`8`a8aa8aa8[[ uw<"[R_uR_U_t__u``u``u``u`auaauaau[ \W \R_u~R_U_t~__u~`k`u~`au~aaWaaWaau~\U___`"``a\c\Wc\R_u|R_U_t|__u|``u|`"`u|``u|``W``u|``u|``u|``u|`au|aau|*\U___```a*\P\VP\R_u|R_U_t|__u|``u|``V``u|``V``t`au|*\6\v#6\;\PG\P\VP\R_u|R_U_t|__u|``u|``u|`au|``u|c\U_ __ `` `` `a c\j\Pj\\W``Wt\U_ __ `` `` `a t\\V\R_u|R_U_t|__u|``u|``V``u|``V``t`au|t\\v#\\P\\V\R_u|R_U_t|__u|``u|``u|`au|``u|\U_7__7``7``7`a7\\P\]W``W\U_7__7``7``7`a7\\V\R_u|R_U_t|__u|``u|``V`aVa at aau|\\v#\\P\\V\R_u|R_U_t|__u|``u|`au|]U___``]]P]_]W__W]U___``]?]V?]R_u|R_U_t|__u|__V``V` `t ``u|]%]v#%]*]P6]?]V?]R_u|R_U_t|__u|``u|_]R_u|R_U_t|__u|_]f]Pf]R_u|R_U_t|__u|p]R_u|R_U_t|__u|s]R_u|R_U_t|__u|s]]P__P]R_u|R_U_t|__u|__u|]R_u|R_U_t|__u|__u|]]P__P]R_u~R_U_t~__u~__u~]R_u~R_U_t~__u~__u~]^u~^R_u}R_U_t}__u}__u~]R_u|R_U_t|__u|__u|]]P__P]^u~^R_u|R_U_t|__u~^R_u~R_U_t~__u~^R_u~R_U_t~__u~5^R_u~R_U_t~__u~W^1_u~1_R_u}R_U_t}__u~t^R_u|R_U_t|__u|^R_u|R_U_t|__u|^R_u}R_U_t}__u}^R_u~R_U_t~__u~^^P__P^R_u|R_U_t|^R_u|R_U_t|_R_u|R_U_t|^R_u|R_U_t|1_R_u}R_U_t}`"`u|``u|``P`"`u|"`>`u|+`9`u|9`=`R=`>`u|+`=`P>`Z`u|G`U`u|U`Y`RY`Z`u|G`Y`P  R 8 R q 1 8 1 { u{ | t|  u  u  u  u  u  u" # u { u{ | t |  u  u  u  u  u  u" # uh q S  S 8 Sh o Po  W  Wy q S  S 8 Sy  V q uD  uD  uD  V  t 8 uDy  v#  P  V q uD  uD  uD 8 uD  uD q u  u  u  u  u  u" # u  P 1 W  W" & W  V q uH  uH 8 uH  uH q M  M 8 M 1 W" & W q M  M 8 M - V- q uL  uL " uL" + V+ / t/ 8 uL  v#  P - V- q uL  uL " uL= q R  R " R= D PD  W  WN q R  R " RN  V q uP  uP  uP  V  t " uPN W v#W \ Ph  V q uP  uP  uP " uP q S  S  S  P  W  W q S  S  S  V q uT  uT  uT  V  t  uT  p  P  V q uT  uT  uT  uT q u  u  u  P 9 W  W  W  V q uX  uX  uX q K  K 9 W  W q K  K q V  V  t  u\  v#  P# q V  V  u\< q u`  u`< q ud  ud< q 0  0X q W  W] q V  V] e P  P  u`  ud  P  ud  R `R`jRj&R U1&1  P`ePeju  Q`jQ5USSS&S5;uOUSSS&SOtWtUuDuDuDW&uDOXrX]PktWtUuDuDuD&uDuDP WWWVUuHuHuHuHUMMMM WWUMMMM V UuLuLuLuLV t uLv#pP V UuLuLuLuLuLURRRR P ]WW*URRRR*[V[UuPuPuPuPVtuP*,v#03p38PD[V[UuPuPuPuPuP]USSSS]dPdWWkUSSSSkVUuTuTuTVtuTkspsxPVUuTuTuTuTPWWWVUuXuXuXUKKWWUKKUVVtu\v#pPUVVu\ Uu`u` Uudud U00<UWWAUVVAIPPu`udPud0F FMpMUdU_ 0==FpFGtGUhU_`s szpzd `jjspsttth"bbWb_cW3bbWc_cWgbbccc&c~bbbbw bcw bbudbcudbbPb cPbbwbbwbbudbbudbbPbbP2c9cuc9c@cR@c_cuc2c@cPJcQcucQcUcRUc_cucJcUcPccuLfPfu|ffuccwxccPccwxLfPfwx|ffwxccWLfPfW|ffWccwxccPccwxLfPfwx|ffwxccWLfPfW|ffW|ffWffu`ffRffu`ffPccVcctcctccv|ffv|ccu`ccPcbduPjd~duPfCfuP-fCfu`3f>fu_>fBfRBfCfu_3fBfPccrxcdWd&dVccrpccPccrpccWcbd0jd~d0ff0f-f0ccrpccPccrpccWcdwpd&dvpccPccp cc wu 3&ddwpd&dvpddWd&dVd&dWd&dVd&dv|d&dv&dbdu`jd~du`9dbdudjd~dudQdbdu`jd~du`Qdbdudjd~dudTdbdu_jd~du_TdXdPjdqdPXdbdu`td~du`^dbdu_td~du_^dbdPtd{dPddw8eew8af|fw8deuPefuPfguPdduPde0e+eP+edeuLffuLffuPff0ffuPff0fguP*gng0ngguPgg0gguLgguLgg0~df{ Pf|f{ fg{ ~df1Pf|f1fg1~ddueeuPf|fudd1ddReeRPf|fRdf@Pf|f@fg@dep;efp;\f|fp;fgp;ddueeuaf|fuddudd0dduHdduddVddv|ffv|ffVnggVdduPw"ddWd}euDffuDffWffuDffWffuDfgWgnguDnggWgguDddVddv|ffv|ffVnggVddWffWffWfgWnggWfguDffu`fgRggu`fgPddVdeuPefuPffuPffuPffuP*gnguPgguPgguPddWde1ef1ff1ff1ff1*gng1gg1gg1deWffWffWddV eeveeVd eW eewxffWffW eeveeVdeWffWffW*gAgV/g:gu`:g>gR>gAgu`/g>gPJgnguPgguPJgVguPVg]gW]gagtagbgwxbgngWggWVg]gW]gagtagigwx)e+eP+exeuLffuLgguLgguL)e+eQ+edeuTffuTgguTgguT)ee1ef1ff1gg1gg1)e+eP+eeVeeuDeeuDffVggV+eSeVSedevxffVggV4ePeVffVggVffVffu`ffRffu`ffPffVggVffuLgguLgguLffuLffWfftffwxffWggWggWffWfftffwxoeeuTeeuToeeQoeeQeeVeeVeeVeevxeeVeeVeevxeeveev|eeveeveev|eeu`eeu`eeu`eePeeVeevxeeVeevxeeu`eeu`eePeePefuTeeuTgguPg%guPgguDgguPggVggtggvxggVggVggtggvx5hOhUYhkhU;hOh_Yhdh_dhhhRhhkh_;hChPYhhhPuTP^0vP^vW^g0v ^gv ilv luPuyv y~v~PvvugRugPVugRugP`cuT0`cvvcv  v ~v v v v v4P v v4P v  vv 4P vv 4PvP v *v*ugPv Mv P|v v |00P'v ':uTmwv wzuT#:ugmzug#'P':uP<mwPwzuP<v:MvPmvv0:m00PvuTZgvgmuTugZmugPuP<ZgPgmuP<v:MvPZvug_:OugOP_PZugPPWPV:MVug_:OugOP_P:GP|vPvvugRugPVugRugPv Pv q V:V:=v=BVV"BWWWZpZbu#Zbu# u#4ZfP^bu# u#4^fPjxu# pxu#u# 4p|Ptxu#u# 4t|Pu#u#u#{u#0{0WWugugPPpu#pu#ugugPP'u#'u# u#4+P#'u# u#4#+P/=u# 5=u#u# 45AP9=u#u# 49APEMu#MPpPUPYvu#bmugmqRq{ugbqPphhhhWhYiWzijWhhVhhVhhVhhhhhhp|hhPhhPhhPhh #4hhRhhp|hhp|hh #8hhWhhWhh1hh1hhr4hhr4iir4i+iX4iip4ijr4+ioiUoiziviiU+i3iU3iBi0BiFiur"FiTiQYiziWiiQiiXii0hhPh iu1$zii1ijPhi)^ij)^ iziViiVijVi+iVi+i0+iziViiV+i;iQ+i-iur"-i7iR5iziViiV5ioiUoiziviiU5iYiWiiW5iBiPiiP5izi1ii19iBir4iir4iiX4FiziViiVFiTiQiiQiiXFiTiviivFiYiWiiWFizi1ii1KiTir4iir4ii\4YiziVYiai vp4YieiP]iiiV]iai vp4]ieiPj*j*j]jW_jjWkkWGjWjV_jrjV2jGjVGjWj_jrj2jUjr|_jejr|ejgj #82jUjR_jejRejgj #4GjUjR_jejRejgj #4GjJjr|JjLjPLjUjr|_jejr|ejgj #8GjWjW_jrjWGjWj1_jrj1LjUjp4_jljp4jjr4jj\4kkr4ukkr4jkUkkvk^kUjjUjj0jjuq"jjQjkWk2kQ2k@kX@k^k0jjQkk1^kkQkk vp2&1$j^kfqkkfjkVk^kVukkVjjVjj0jkVk^kVjkk^kjjur"jjR@kQkRjkVk^kVjkUkkvk^kUjjWk^kWjjXk.kX@k^kXjk1k^k1jjq4@kQkq4Qk^k\4jkVk@kVjjQk2kQ2k@kXjjRjjvk)kvjjWk@kWjk1k@k1jjr4k2kr42k@k\4jkVjj vp4jjPjjVjj vp4jjP)r)/)R)Gv # 6v 6G# v Pv#/6v6G#l/:l:ARAGlv#/6v6G#vl P vkkkkWkylWl"mWkkVkkVkkVkkkkkkp|kkPkkPkkPkk #4kkRkkp|kkp|kk #8kkWkkWkk1kk1kkr4kkr42l=lr4=lKlX4llp4m"mr4KllUllvllUKlSlUSlbl0blflur"fltlQyllWllQllXll0llPl*lu1$ll1l"mPllp m"mp*llVllVm"mV2lKlV2lKl0KllVllVKl[lQKlMlur"MlWlRUllVllVUllUllvllUUlylWllWUlblPllPUll1ll1Ylblr4llr4llX4fllVllVfltlQllQllXfltlvllvflylWllWfll1ll1kltlr4llr4ll\4yllVyll vp4yllP}llV}ll vp4}llPPuqcQc~r~#r#k~rk~kxPPWtt wPW9TwPWtt w9Tw0;0ȷ;ȷ ; W9TWȷ;ȷ;%uP9uPqyuPyu`uPu`uPu`uPu`uP1u`1;uP%uL9uLqyuLyu\uL1u\1;uL%+P+WuT9uTqwWwyuTWuTWuTWuT19W9;uT@uP9uPuPu`uPu`uPu`uP1u`1;uP@uL9uLuL1u\1;uL@VwVVvudRudPv udRudP}uT9uTuT1;uTV9VVudPuT9uTuTV9VuZ9uZP'Pud uZRuZ PzVwzwuT#9uT#uT#19w9;uT#uT##p#(Pu*9uu`*9u`ud*9udP*6Pu\udPVqu\\cuZcgRgquZ\gPu`uZRuZP0mJmJmmWmnW:nnWmmzmVmmVVmmmVmmzmmmVmbmp|VmbmPmmxmPmmPmm #4mmomRomxmp|mmp|mm #8mmzmWmmWmmzm1mm1omxmr4mmr4mmr4mmX4NnSnp4nnr4m/nU/n:nvSnnUmmUmn0nnur"nnQn:nWSnjnQjnxnXxnn0mmPmmu1$:nSn1nnPmnnnm:nVNnnVnnVmmVmm0m:nVSnnVmmQmmur"mmRm:nVSnnVm/nU/n:nvSnnUmnWSnnWmnPxnnPm:n1Snn1mnr4xnnr4nnX4n:nVSnxnVnnQSnjnQjnxnXnnvSn\nvnnWSnxnWn:n1Snxn1 nnr4Snjnr4jnxn\4n:nVn!n vp4n%nPn)nVn!n vp4n%nP@l~p^y~P^yq~q #$#HQfyqfyfoR^yQ~Q#$qqu#TWwWWwWVVV/u#H)<V<?v?CVC_V_bv|/8PE[P/8Ppu# 0  0 Z!0u# Ku# u#  !u# 0 Z!0!XV V(0P4XVV?Xudud?GPP VudR udP#)p)-u#l&HVHV!!V# ÏXÏ !7!ÏE!Z!Ï&)p)-u#l&)p)-u#pBSÏS_PW_P!.!R&!.!Rcqu#`iqu#hu#`4iuPmqu#hu#`4muPyu#Tu#\u#T4Pu#\u#T4Pu#Hu#Pu#H4Pu#Pu#H4Pu#@PP VXfPfV ! !VE!M!VE!Z!p u#  #u#t# ud  \udt` PP; I u#`A I u#hu#`4A M PE I u#hu#`4E M PQ _ u#TW _ u#\u#T4W c P[ _ u#\u#T4[ c Pg u u#Hm u u#Pu#H4m y Pq u u#Pu#H4q y P  u#  uc  R  uc  P  u#  p  P  u#  p  P!"W""v""V"&"P&"~"V""V:""8""8[""+#<#v<#A#PA#*%v*%,%uH,%-%tH-%'vh#l#Pl#,%u,%-%t-%`&u&&u&('v ('Z'ua''uu#{#P{##u-%6%P6%%uP&`&uY%%P&`&k%%#*%v*%,%u# ,%-%t# %P&v&Z'va''v##P#+$u%%P%P&u='S'u&P&ܾA'S'ܾ+&P&#*%v*%,%u#(,%-%t#(%%v&'v('='vS'Z'va''v#*%v*%,%u#4,%-%t#4%%v&'v('='vS'Z'va''v#*%v*%,%u#@,%-%t#@%%v&'v('='vS'Z'va''v#*%v*%,%u#L,%-%t#L%%v&'v('='vS'Z'va''v\$-%0%%0&&0('='0a''0\$*%v*%,%u#,%-%t#%%v&&v('='va''v$-%0%%0&&0('='0a''0$*%v*%,%u#,%-%t#%%v&&v('='va''v$$P$$v$$P$$v$*%v*%,%u#,%-%t#%%v&&v('='va'z'v$*%v*%,%u#,%-%t#%%v&&v('='va'z'v$$P$,%u,%-%t%%P%%u&&u('='ua'z'u%%ܾ('='ܾ%%%*%v*%,%u#,%-%t#a'z'v%!%P`&&vf&q&uSq&u&Ru&&uSf&u&P&&v&&P&&v&&v&&P&&v&'v&& vv4&&P&& vv4&&P&'v&& vv4&&P&& vv4&&P&'v&& vv4&'P&& vv4&'P''P''uP''tL'(uP''P''W''P't(W((W(t(2(_(\)n)P],c,Pc,u,d)0+:=+],:~,L/:d)n)P))V)0+u=+Q+u=,],u~,,u-.uL.L/u))uD)0+V=+Q+V=,],V~,,V--V-.uDL.N.VN..uD..V..uD..V..uD..V..uD..V..uD..V..uD..V. /uD / /V //uD//V/5/uD5/7/V7/L/uD..uD..u`..R..u`..P)0+u=+Q+u=,],u~,,u-.uL..u/L/u)0+u`=+Q+u`=,],u`~,,u`-.u`L..u`/L/u`))P=,G,P))W))t)*uPM,],uP~,,uP,,uPL..uP..uP..uP))P)*W**uM,],u~,,u,,uL..u..u..W%*)*W)***t**.*t.**uHM,],uH~,,uH,,uHL.a.uH..uH%*)*uL)**WM,],W~,,W,,WL.a.W..WK**uM,],u~,,u,,u..uK**uDM,],uD~,,uD,,uD..uDZ**uM,],u~,,u,,uZ*f*uf**uL**uTM,],uT~,,uT,,u,,uL]**udM,],ud~,,ud,,ud]*f*P,,Pf**uLM,],uL~,,uL,,uLf**uL**uTM,],uT~,,uT,,uLl**udM,],ud~,,ud,,udl*u*P,,Pu**uHM,],uH~,,uH,,uH{**udM,],ud~,,ud,,ud{**P,,P**uTM,],uT~,,uT**udM,],ud~,,ud**P~,,P**uPM,],uP**udM,],ud**PM,W,P*!+ud,,ud--ud/L/ud*!+W,,W--W*+W+!+u\,,W,,u\--W--u\*!+uX,,uX--uX**P,,P*!+ud,,ud--ud*!+u`,,u`--u`*+P,,P+!+u\,,u\+!+ud,,ud+!+P,,P!+0+uD'+0+ud'+0+Po++V+0,u\,q-u\z--u\--V--u\--V--u\.L.u\o+t+u`t+0,W,q-Wz--W.L.W--u`--ud--R--ud--P++V++t+0,uT,K-uT--uT.L.uT++P+0,V,/-V/-K-uX--V--uX..V.&.uX&.(.V(.L.uX(.L.uX4.B.udB.F.RF.L.ud4.F.P+0,u,--u++u+,uX,0,u`,,u,-uX---u`+0,uP,--uP++P,,P+0,uX,--uX+,uX,0,u`,-uX---u`+0,ud,--ud+,P --P,0,uT, -uT---uT ,0,ud, -ud---ud ,,P,-P,0,u`---u`,0,ud---ud,!,P-'-P!,0,u\',0,ud',0,P8-K-uT>-F-uPF-J-RJ-K-uP>-J-PK-^-u`Q-Y-uPY-]-R]-^-uPQ-]-P^-q-u\d-l-uPl-p-Rp-q-uPd-p-P--ud--uP--R--uP--P--uX--uP--R--uP--P--u\--ud--P-.uD..uC..R..uC..PN.a.uHT.a.udT.`.Pa.t.uTg.t.udg.s.Pt..uPz..udz..P..uL..ud..P..uX..ud..P. /ud./u`//R/ /u`./P/5/ud/+/uX+///R//5/uX///P=/E/uXE/I/RI/L/uX=/I/Pm//V//u`//t\//V/0u`00t\0I0VI0]0u`]0c0Vc00u`//udK0]0ud00ud//P//uK0]0u//udK0]0ud//u_K0]0u_//PK0W0P//u`/0u`//ud00ud//P00P/0T0K0T/0u`0K0u`e00u`k0r0u_r0v0Rv00u_k0v0P00ud00u_00R00u_00Pn11P11Pe1h1p$h1n1Pe1h1p$#h1n1p11P11Vr11r1|1p 2 2P$272P#535P2!4u}!4"4t}"49u}22w42>21k2w2P3 4W"44W3 4u}"44u}33P44P]2f2u#f2j2t3 4u}"44u}3 4u}"44u}33Pt4~4P3 4u}"4t4u}3 4u}"4t4u}33Pd4n4P3 4u}"4d4u}3 4u}"4d4u}33PT4^4P3 4u}"4T4u}3 4u}"4T4u}33PA4N4P3 4u}"4A4u}3 4u}"4A4u}33P14>4P3 4u}"414u}3 4u}"414u}33P"4.4P3 4u}3 4u}33P 8$8u}88u}8#8R#8$8u}8#8P$8<8u}-878u}78;8R;8<8u}-8;8P88u}88u}88R88u}88P88u}88u}88R88u}88P88u}88u}88R88u}88P89u}99u}99R99u}99P9,9u}9'9u}'9+9R+9,9u}9+9P,9I9u}59?9u}?9C9RC9I9u}59C9P 4"4 4#5u}44P5#5u}5#5V55PM5\54y55P55u#55u}55Pv66Pj7t7P77P56j78]9w99956u}j78u}]9w9u}99u}56u}j78u}99u}576V 6^6u}78u} 66PO6^6u}78u}R6^6u}78u}R6^6P77P99u}99u}99R99u}99P77u}99u}77u}77W77P99u}99u}99R99u}99P^6v6u}66u}66u}66u}#_9w9u}66257D7V57;7P[7j73G8e8u}P8^8u}^8b8Rb8e8u}P8b8PP:\:P ;;W;<W#;;uC;<uC#;+;P<<P=:E:u#+;;u`;<u`1;;ud;<ud1;9;P;;P9;;u\;;u\?;;ud;;ud?;G;P;;PG;;uX;;uXM;;ud;;udM;U;P;;PU;;uL;;uL[;;ud;;ud[;_;P;;P_;;uH;;uHe;;ud;;ude;i;P;;Pi;;uD;;uDo;;ud;;udo;s;P;;Ps;;uTy;;udy;;P<8<uT#<*<uC*<.<R.<8<uC#<.<P:<R<udF<M<uCM<Q<RQ<R<uCF<Q<PR<d<u`X<_<uC_<c<Rc<d<uCX<c<Pd<v<u\j<q<uCq<u<Ru<v<uCj<u<Pv<<uX|<<uC<<R<<uC|<<P<<uL<<uC<<R<<uC<<P<<uH<<uC<<R<<uC<<P<<uD<<uC<<R<<uC<<P==PP>>W>M?WS>>u>M?uS>[>P>u`>>ud>i>P,?6?Pi>>u\>,?u\o>>ud>,?udo>w>P?&?Pw>>uX>?uX}>>ud>?ud}>>P ??P>>uL> ?uL>>ud> ?ud>>P>?P>>uH>>uH>>ud>>ud>>P>>P>>uD>>uD>>ud>>ud>>P>>P>>uT>>ud>>PU?p?uT[?b?ub?f?Rf?p?u[?f?Px??uD~??u??R??u~??P??uH??u??R??u??P??uL??u??R??u??P??uX??u??R??u??P??u\??u??R??u??P@@u` @@u@@R@@u @@P&@-@u-@1@R1@4@u&@1@P>>u>>Q>>PJooupequJoouGppuGppRpequGJoSoPSo^ou<ppPJo^ouLppWVo^ouHppuVoaoPppP^olouPppuPdolouLppuLdoooPppPlozouTppuTrozouPppuPro}oPppPzoouXqquXoouTqquTooPqqPoou\q&qu\oouXq&quXooPq7qPoou`8qFqu`oou\>qFqu\ooP>qWqPJoopeqzqq rkrxrrJooupequzqqu rkruxrruJoo0peqzqq r^rxrrJoou0pequzqqu r^ruxrrurruPrrRrruPrrPJooͮPpeqͮzqqͮ rMrͮJoouPpVpWVpequzqqu rMruJooͮepeqͮzqqͮ rrͮ,rMrͮJooWepeqWzqqWqquL rrWrruLrrW,r5rW5rMruL,rMruL8rCruHCrGrRGrMruH8rGrPJoospeqzqq rrJooWspeqWzqqWqquL rrWrruLJoopeqzqq rrJooupequzqqu rru|qquHqquGqqRqquGqqPqquLqquGqqRqquGqqPqquPqquGqqRqquGqqPqquTqquGqqRqquGqqPqquXqquGqqRqquGqqPqqu\qquGqqRqquGqqPq ru`qquGqqRq ruGqqPrrPrrs2sV2s3sYscsPcsisssVssf@i@p$#i@o@po@s@Pz@@P@@V@@us@@R@@us@@P@@us@@R@@us@@P@?AV?A@ATAWAp$WA`APTAWAp$#WA`ApAAPABVI+IVKKPKKVKKVCMHMVeMgMVMMV]E`EP`EIuIIt+IJuJJJKuYL!Mu=MCMuAAPABVI+IVKKVCMHMVeMgMVMMVABPI+IPKKPCMZMPeMyMPMMPABuI+IuKKuCMZMueMyMuMMuAAu#AAPABI+IKKeMyMMMABuI+IuKKueMyMuMMuAAu#AAPAB/I+I/KK/eMyM/MM/ABuI+IuKKueMyMuMMuAAu#AAPBBI+IKKeMyMMMBBuI+IuKKueMyMuMMuB Bu# BBPBPB°BPBuB0Bu#0B5BP;BPBF;BPBu;BPBV;B?Bp?BDBPHBPB̰HBPBuHBPBu#I+II+Iu`I+Iu`#uBBu`KKu`eMyMu`MMu`uBB0KK0eMyM0MM0HMZMu`BBu\KKu\MMu\BBu\KKu\BBu`KKu`BBPKKPBCuX;DIDuXBCu\ADIDVB CPADWDPCCuTXDfDuT CCu\^DfDu\ CCP^DwDPC"CuHxDDuHC"Cu\~DDu\C%CP~DDP"C0CuDDDuD(C0Cu\DDu\(C3CPDDP0C>Cu@DDu@6C>Cu\DDu\6CACPDDP>CLCuPDDuPDCLCu\DDu\DCLCPDDPBLCV(DEVBLCu+D6Du6D:DR:DEuBBPBCv<+D:DP5EqEVqEIuIIt+IJuJJJKuKKVYL!Mu=MCMu8EIuXIItT+IJuXJJPJKuXKKuXYL!MuX=MCMuX8E@EPKKPqEEuXFFuX~EEu\FFu\~EEPFFPEEuTFFuTEEu\FFu\EEPFFPEEuHFFuHEEu\FFu\EEPFFPEEuDFGuDEEu\FGu\EEPFGPEEu@G&Gu@EEu\G&Gu\EEPG7GPEEuP8GFGuPEEu\>GFGu\EEP>GWGPqEEu\FeGu\qEEuFFuFFRFeGuqE{EP{EEu\<FFPeGGueGIuIIt+IJuJJJKu^L!Mu=MCMuGGPcHHu\JJu\]KKu\fHHuJJu]KKufHnHPKKPnHHuXJJuX]KKuXtHHu\JJu\]KKu\tH|HP}KKP|HHuTJJuT]K}KuTHHu\JJu\]K}Ku\HHPmKwKPHHuPJJuP]KmKuPHHu\JJu\]KmKu\HHP]KgKPHHuDJJuDHHu\JJu\HHPJJPHHu@JJu@HHu\JJu\HHPHHu@<JJPHHuJJuHHu\JJu\HHPJJPHHuLHHu\HHPHHuHHudHHp$HHPHIp~+I4IP{JJPIiJu\J]Ku\IiJuJ]KuIIPMKWKPIiJuXJMKuXJiJu\JMKu\JJP=KGKPJiJuTJ=KuTJiJu\J=Ku\JJP-K7KPJiJuPJ-KuPJiJu\J-Ku\J$JPK'KP$JiJuDJKuD*JiJu\JKu\*J2JP KKP2JiJu@J Ku@8JiJu\J Ku\8J@JPJKP@JiJuJJuFJiJu\JJu\FJNJPJJPNJiJuLTJiJu\TJ_JP`LtLuLfLmLumLqLRqLtLufLqLPvLLu|LLuLLRLLu|LLPLLu@LLuLLRLLuLLPLLuDLLuLLRLLuLLPLLuPLLuLLRLLuLLPLLuTLLuLLRLLuLLPLLuXLLuLLRLLuLLPLMu\MMuM MR MMuM MPJJuJJQJJu`JJXJJ1JJuJJQKKu\KKuKKRKKuKKPKKuXKKuKKRKKuKKPKLuTKKuKKRKLuKKPLLuHL Lu LLRLLuLLPL$LuDLLuL#LR#L$LuL#LP$L6Lu@*L1Lu1L5LR5L6Lu*L5LP6LHLuPQuT>QIQVIQZQuTZQ\QVQQVQQuTQQudQQRQQudQQPoNNngPPn"Q\QnoNuNWuNvNtvNzNtzNNu`gPPu`"Q\Qu`NNngPPn>Q\QnNNWgPPW>Q@QW@QZQudZQ\QWNNWgPPWNNuGgPPuGNNP|PPPNNu`gP|Pu`PPu`NNudgP|PudPPudNNPPPPNNuTgP|PuTPPuTNNudgP|PudPPudNNPPPPNNuPgP|PuPPPuPNNudgP|PudPPudNNPPPPNNuLgP|PuLNNudgP|PudNNPgPvPPNNu\NNudNNPN0Ou0O1Ot1O@OuN.OV1O@OV@OP3PgP3PP3\QQ3@OPxPgPxPPx\QQxaOP1PP1\QQ1QQ1aOPxPPx\QQxQQxOOtOOtOOPOOVQQVOPWPPWOPu\PPu\OOPPPPOPu`OPudOPP6PfPufPgP6PfPufPgP 6P:Pt6P:Pt6P:PP:PdPVdPfPufPgPPPuTPPuGPPRPPuGPPPPPuPPPuGPPRPPuGPPPPQuLPQuGQQRQQuGPQPQQu\ QQuGQQRQQuG QQP*Q>Qu`0Q7QuG7Q;QR;Q>QuG0Q;QP@QZQudLQSQuGSQWQRWQZQuGLQWQP^QvQudjQqQu\qQuQRuQvQu\jQuQPvQQu`|QQu\QQRQQu\|QQPRRuSSPSTuTTtT$Vu$V%V%V{VuVWu X7Xu>XXXu;RGRPRSVTTVSSuCTTuCS SPTTP SSu`TTu`SSudTTudSSPTTPSSu\TTu\%SSudTTud%S1SPTTP1SSuXTTuX7SSudTTud7SCSPTTPCSSuLTTuLISSudTTudISUSPTTPUSSuHTTuH[SSudTTud[SgSPTTPgSSuDTTuDmSSudTTudmSySPTTPySSuTSSudSSP}VVuXVVuCVVRVVuCVVPVVuLVVuCVVRVVuCVVPVVuHVVuCVVRVVuCVVPVVuDVVuCVVRVVuCVVPVVuTVVuCVVRVVuCVVPaXwXudgXrXuCrXvXRvXwXuCgXvXPwXXu`}XXuCXXRXXuC}XXPXXu\XXuCXXRXXuCXXP'TlTVVV{VV*TlTuPVV{VuP*T6TPVV]VP6TlTu\cV{Vu\tP>tJtu1$tt1uBuP{Wg{i{Wi{{1{{Wzzu zzu`#i{{u`#zzuzzWzzptzzVi{}{VzzPi{w{Pzzu`#i{{u`#zzRzzPz{u{{t{ {ti{{uzB{1g{{1zB{0g{{0z{u{{t{ {t{{uz {P{{P,{?{u?{B{P{{P{|u4k|u|Pu|w|u4{w||||G|k||||||u~||P|Z}WZ}Tu}TW}Wpu}ptWtu}||u~||P|Tu~TW~Wu~}Z}WZ}Tu}TW}Wpu}ptWtu}H}Q}u~Q}z}Qz}Tu~TW}Wpu~tu~u~xu~}pHtxHHH}@~u~@~X~RX~Tu~TW~Wpu~txu~u~u~'~@~u~@~X~r$X~Tu~#$TW~#$Wpu~#$txu~#$u~#$u~#$u~_~Tu TWWpu txu u _~Tu~TW}Wpu~txu~u~_~p0tx00_~b~pq~Tu}TW}Wpu}~Tu}TW}Wpu}~Tu~TW~Wpu~~Tu~TW~Wpu~~Tu~TW~Wpu~~~PWjP~Tu~TW~~Tu~TW~~Tu~TW~Tu~TW~,Tu~TW~XYuPY\YuH\Y_YtDxYYuHXYuHYYPY\YuH\Y_YtDxYYuHY\YuH\Y_YtDxYYuHYYuPYYPY\YuP\Y_YtLxYYuP>Y[YW[Y\Yu`\Y_Yt\xYYWAY\Yu_\Y_Yt[xYYu_AYHYPxYYPHY\Yud\Y_Yt`YYudNY\Yu`\Y_Yt\YYu`NYSYPYYPYYudYYu_YYRYYu_YYPYYu_YYRYYu_YYP0ZEZuEZ\u0Z>Zu>ZDZPDZ\uEZPZuPZXZPXZ\ubZ>\\\bZ#\V#\>\u`\\V\\u`\\V\\u`\\V\\u`\\V\\u`tZ.\\\tZZWZ.\uP\\W\\uPtZ}Zw#}ZZPZZWZ.\uP\\uP\\uPZ.\\\ZZPZZu\\uZ.\\\ZZWZ.\uT\\W\\uTZZw#ZZPZZWZ.\uT\\uT\\uTZ.\\\ZZPZ9[u\\u[.\\\['[W'[.\uX\\W[ [w# [[P['[W'[.\uX9[.\9[@[P@[[u[[u\ \uJ[.\J[.\WJ[S[w#S[X[Pf[\W#\.\u\[\V[\ud[\0[[Q \\Q\\u[[W \\W[[P \\P[ \uH[ \u`[[P[\P[[uL[[u`[[P.\>\u`.\3\ud3\:\P:\>\ud>\Y\uHJ\T\uGT\X\RX\Y\uGJ\X\PY\u\uL_\g\uGg\k\Rk\u\uG_\k\P]*]u*]_u]#]u#])]P)]_u*]5]u5]=]P=]_uG]_._M_j__G]_V._2_V2_M_u`j_n_Vn_{_u`{_}_V}__u`__V__u`__V__u`Y]_._=_j__Y]|]W|]_uP._=_uPj__uP__WY]b]w#b]g]Ps]|]W|]_uP._=_uPj__uP__uP]_ ._=_ j__ ]]P]]u{_~_u]_ ._=_ j__ ]]W]_uT._=_uTj_{_uT{__W]]w#]]P]]W]_uT._=_uTj_{_uT}__uT]_._=_j_{_]]P]^uj_k_u]_._=_j_{_] ^W ^_uX._=_uXj_{_W]]w#]]P^ ^W ^_uX._=_uXn_{_uX^_._=_^%^P%^^u^^u._/_u/^_._=_/^_W._=_W/^8^w#8^=^PK^_W2_=_u\q^_Vq^_udq^_0^^Q^_Q__u^^W^_W^^P^_P^^uH^^uH^^u`^^u`^^P^^P^^uL^^u`^^P_._uL_ _uG _$_R$_._uG_$_P=_M_u`=_B_udB_I_PI_M_udM_j_uHY_c_uGc_g_Rg_j_uGY_g_P``u`bu``u``P`bu`%`u%`-`P-`bu7`ab=bZbb7`aVb"bV"b=bu`Zb^bV^bkbu`kbmbVmb|bu`|bbVbbu`bbVbbu`I`ab-bZbbI`l`Wl`auPb-buPZb|buP|bbWI`R`w#R`W`Pc`l`Wl`auPb-buPZb|buPbbuP}`ab-bZb|b}``P``ukbnbu`ab-bZb|b``W`auTb-buTZbkbuTkb|bW``w#``P``W`auTb-buTZbkbuTmb|buT`ab-bZbkb``P`auZb[bu`ab-bZbkb``W`auXb-buXZbkbW``w#``P``W`auXb-buX^bkbuXaab-baaPaauaaubbuaab-baaWb-bWa(aw#(a-aP;aaW"b-bu\aaaVaaaudaaa0aaQaaQaauaaWaaWaaPaaPaauHaauHaau`aau`aaPaaPaauLaau`aaPbbuLbbuGbbRbbuGbbP-b=bu`-b2bud2b9bP9b=bud=bZbuHIbSbuGSbWbRWbZbuGIbWbPb cu ceubcuc cP ceu ccuccPceu'cde-eJee'cdVeeVe-eu`JeNeVNe[eu`[e]eV]eleu`lepeVpe}eu`}eeVeeu`9cdeeJe}e9c\cW\cduPeeuPJeleuPle}eW9cBcw#BcGcPSc\cW\cduPeeuPJeleuPpe}euPmcdeeJelemctcPtccu[e^eu~cdeeJele~ccWcduTeeuTJe[euT[eleW~ccw#ccPccWcduTeeuTJe[euT]eleuTcdeeJe[eccPccuJeKeucdeeJe[eccWcduXeeuXJe[eWccw#ccPccWcduXeeuXNe[euXcdeecdPdduddueeuddeeddWeeWddw#ddP+ddWeeu\QddVQddudQdd0qddQddQddu|ddWddW|ddPddPdduHdduHddu`ddu`ddPddPdduLddu`ddPdeuLdeuGeeReeuGdePe-eu`e"eud"e)eP)e-eud-eJeuH9eCeuGCeGeRGeJeuG9eGePeeueuhueeueePeuhuefuf fP fuhufggh:hqhfgVghVhhu`:h>hV>hKhu`KhMhVMh\hu`\h`hV`hmhu`mhohVohqhu`)fgg h:hmh)fLfWLfguPg huP:h\huP\hmhW)f2fw#2f7fPCfLfWLfguPg huP:h\huP`hmhuP]fgg h:h\h]fdfPdffuKhNhunfgg h:h\hnffWfguTg huT:hKhuTKh\hWnfwfw#wf|fPffWfguTg huT:hKhuTMh\huTfgg h:hKhffPffu:h;hufgg h:hKhffWfguXg huX:hKhWffw#ffPffWfguXg huX>hKhuXfgg hffPfogugguggufgg hfgWg hWfgw#g gPggWh hu\AggVAggudAgg0agsgQggQggulggWggWlgsgPggPgguHgguHggu`ggu`ggPggPgguLggu`ggPgguLgguGggRgguGggP hhu` hhudhhPhhudh:huH)h3huG3h7hR7h:huG)h7hP%3U37 v5&jnUnp v5&7|v|vhvVvʀvxʀπp8π׀v׀vpp@vh7WˀWˀπ πW W7|v|vhvVvʀvxʀπp8π׀v׀vpp@vh7FvFGtGKPS|v|vpvʀVʀπpπ׀v׀vxp8vpSWˀWˀπ πW WS|v|vpvʀVʀπpπ׀v׀vxp8vpSYvYZtZ^Pf|v|vxπ׀v׀VpvxfWπW Wf|v|vxπ׀v׀VpvxflvlmtmqP7|V|v`VVvxVʀvpʀπp@π׀V׀vhpHv`7WˀWˀπ πW W7|V|v`VVvxVʀvpʀπp@π׀V׀vhpHv`vtP7qqSqqfqπq 6U 6W 6U &u&'t'+P36q6LU6LW6LU6<u<=t=APILqL_UL_WL_ULRuRStSWPRLURׁwׁwt5w59R9wwtuu  ׁwׁwt5w59R9wwt4V6UPׁwׁwx9wwxu9u 9 ׁwׁwx9wwx9aV9aU9JPȁׁw ׁw|aw w|ȁuauȁ a ȁׁw ׁw|aw w|aVaUarPׁWׁwpW5W59r|9Wwpuu  ׁWׁwpW5W59r|9WwpVUPWWW9WȁWaWĂ΂V0LVĂ΂u0LuĂ΂ 0L Ă΂V0LV0LU0>R>L\0>P˂΂W΂V΂u΂ ΂VՂUՂ߂RՂ߂PVv|0V0u0 Vv|0V0 "Q"R".\.0R"PWP v4&1W΄W΄҄ ҄WP1W΄W΄҄ ҄W1W΄W΄҄ ҄WуP1W΄W΄҄ ҄W݃1W҄WP1W҄W1WWP1WWSpWUePUpWmp8pWrPrW8WPW188݃18҄8188_iiWiiWhjjWhhVhhthhthiuPiiHikuPkktLk.luPhhuThhVhhthiuTiiLikuTkktPkqkuTqkwkVwk.luThhphiu#Tii#Ti ku#TkJku#T\kqku#Tk.lu#Thhphiu#Xii#Xiipiju#Xj+jq+jju#Xk(kr(kDku#X\kqkqk.lu#Xhiu#Tii#Ti ku#TkJku#T\kqku#Tk.lu#Thiu#Tii#Tiju#Tjjrj ju#T j+jQ+jju#TkDku#T\kqkQk.lu#ThhVhhthiuTiiLikuTkktPkqkuTk.luThhu#Xhiuiiiiu4jju.k6kuk.luh8iW4jDjWkkWkkWkkW l lWhhuXhhPhhVhiuiiikukktkqkukkukkVk.luhhVhiuiiikukktkqkukkuk.luhhu`hhPhhVhiuiiikukktkqkukkVkkuk lu llVl.luhhVhiuiiikukktkqkuk lu llVl.luhhPhiuiiiiui4ju\4jjujku\kktXkDkuDkqku\k.luhiuiiikukktkqkuk luh8iu8iCiudCiQiu\Qi_iuX_imiuT4jDjuDjPju\Pj^juXhjvjuTjjudkkuk lu\i iQ iiu@iii4ju@4j>jQ>jku@kktkqku@k lu@i iP4j>jPl$lud$l(lR(l.ludl(lP iiu\iiTi4ju\Djku\kktXkqku\k lu\ iiudii\i4judDjkudkkt`kqkudk lud8iiudii\i4judDjkudkkt`kqkudkkud8iCiudCiiu\iiTi4ju\Djju\jjudjku\kktXkqku\kku\8iCiudCiQiu\Qi_iuX_imiuTDjPju\Pj^juXhjvjuTjjud;iiu`iiXi4ju`Djku`kkt\kqku`kku`;iCiPjjPCiiu\iiTi4ju\Djju\jku\kktXkqku\kku\CiQiu\Qi_iuX_imiuTDjPju\Pj^juXhjvjuTIiiudii\i4judDjjudjkudkkt`kqkudkkudIiTiPTi_iu\<DjOjPQi_iuXPj^juXQi_iuX_imiuTPj^juXhjvjuTWi_iudVj^judWibiPVjgjPkkuXkkuOkkRkkuOkkPk lu\k lu`klP_imiuThjvjuTeimiudnjvjudeipiPnjjPmi{iuPjjuPsi{iudjjudsi{iPjjPi4judjkudkkt`kqkudi4ju\jku\kktXkqku\iiP.k:kPj jP j+ju#|+j4ju#\kqkw j4ju`\kqku` j+jR\kckRckek w2$q" j+jQ+j4ju#T\kqkQ j%j rq4\kck rq4ckek w2$4\kqkQ\kqku`\khkPjju`k.ku`jju#Tk(kr(k.ku#Tjju#Tjju`jjPj kqDkVkqjkudkkt`Dk\kudj kqDkVkqj kqj kudjkPk kqykkuPkkuOkkRkkuOkkPkkuTkkuOkkRkkuOkkPkkudkku\kkPlmVmmPmmV;n=nVlmWmmudmmt`mmW;nRnWlmu_mmt[mmu_;nRnu_llPmmPlmu`mmt\mmu`mmu`;nRnu`lmudmmt`mmudmmud;nRnudllPmmPlmVmmPmmVmmV;n=nVllu mmu mmu ;nRnu llummummu;nRnullPlmuPmmtLmmuPmmuP;nRnuPllplmuP#mmtL#mmuP#mmuP#;nRnuP#llplluP#mmuP#mmuP#;nRnuP#lmVmmPmmVlmvmmpmmvllPmmudmmud;nRnudm"muP#"m'mP'mmuP#mmuP#;nRnuP#.mmudmmud1mmu`mmu`1m:mPmmP:mmuP#mmuP#=nRnudCnRnu`CnOnPnnud nnu_nnRnnu_ nnPn.nu`!n)nu_)n-nR-n.nu_!n-nP%x%-P-x%nWnppxWW5:P:mVmnwnppxVVCVPVoUpsPsxUUFxFnWnppxWWFVRV^\^ou pxRu FmVmnwnppxVVH^VH^WHVRV^\sxR^mVmnwnpV^oUUnouDoouXootToouDo'puX'p(pP(ppuDp3quD=qCquDnnRnouooROp[pR[ppu|n{ou(ppupqu=q?quCqfqunoWooudoot`o&pW&p'pud'p(p\(ppWppudppWp=qud=qAqWAqCqudCqEqWEqfqudppudppu`ppRppu`ppPcn{ou (ppu pqu =q?qu Cqfqu nnVppVCqNqVnoWooudoot`o&pW&p'pud'p(p\(ppWppudppWp=qud=qAqWAqCqudCqEqWEqfqudnnVCqNqVnouDoouXootToouDo'puX'p(pP(ppuDp3quD=qfquDQq\qu`\q`qR`qfqu`Qq`qPnoWooudoot`o&pW&p'pud'p(p\(ppWppWp3qud=qAqWAqCqudnou`oot\o'pu`'p(pX(ppu`p3qu`=qCqu`nnPppPnpppp3q=qCqnp-pp-p3q-=qCq-nou\o'oP'owouwoou\ootXo'pu\'p(pT(pDpuDppu\ppupquq3qu\=q?qu?qCqu\nnu\nou`oot\o'pu`'p(pX(ppu`ppu`p3qu`=qCqu`nou`oot\o'pu`'p(pX(ppu`ppu`p3qu`=qCqu`oouVooPowou(pDpuppupqu=q?quooQowou@(pDpu@ppu@pqu@=q?qu@oouooRowoud(pDpudppudpqud=q?qudowoud(pDpudppudpqud=q?qudo'oP'owou(pDpuppupqu=q?qu.owoud(pDpudppud1owouW(pDpuWppuW1o9oPppPNowoud(pDpudppudNoQou`QoWoPWowou`(pDpu`ppu`^owoud(pDpudppudaowouW(pDpuWppuWaoioPppPiowou\(pDpu\oou`oou`ooudooudooPooPoou\oou\ooudooudooPooPoouXppuXooudppudooPppP(pDp6(pDpu\Op[pR[pmpu@mppuOpfpu\fplpPlppu\vppTvp|pu`|ppPppu`ppudppu`ppPpqudpquWqqRqquWpqPq3qu` qquWqqRq3quW qqPq3qu\q$qu`$q(qR(q3qu`q(qP)q3quX/q3qu`/q3qPssPssuqsusstssustutttqq0qcruDr$suDhssuDsst@ssuDst0qq0qnrur(suhssussPssust0qq0qesuhssWssusstssussust0qqpqqu#Thsnspnssu#Tsst#Tstu#Tttt#TqqPqrWrsuPsstLssuPssuPqsu`sst\ssu`ssu` r#r0#rMsWssW rrw rruP# rrp rMsuP# ssuP# #rrVrMsVssVssV#rruTrMsuT#rJrP ssPssv0r[r1s6s1[rnr0s6s1nrwrPwrruP#,6sGsq,nrruP6sGsQGsMsuPtrrud6sMsudzrru_6sMsu_zrrP6sGsPssudssu_ssPqs0ss0qrWrsuPsstLssuPssuPMssu`sst\ssu`Vssudsst`ssudVs^sPssPssu`ssudssP'tWtWWtXtu Xt[tt[tytWytztu zt}t}ttW=t@tug@tItRItXtugXt[ttcttug=tItP=tWtWWtXtu Xt[ttttW=tVtVVt[tPttVOtTtPTtVtvVt[tpOtVtVVt[tPtt tuWw"xV"x%xD%x/xVqxxDxxVxxDtuWux~ttwttPtuLuuPuxtuLuuPuxtuWuvWv/x0SxoxWoxx0vXv0Xvmv1vv0uuWuvWSxoxWu!uD!u7uVu*uPu7uWu1uH1u7uP4u7uP7uuv/xSxmxoxx7uuv/xSxmxoxx[uu[uu~[umu~#muruPyuuyuu~yuu~#uuPuuuu~uu~#uuPuuuuDuuPvAvVAvCvPCvvVvvVvmv#*vCv/CvIvvIvLvtLvPvt*vmvXvmvXvmvmvvyvvDyvvPvv˱vv~vv~#vvPvvvv~vv~#vvPvvvv~vv~#vvPUxmx[xfxDfxjxRjxmxD[xjxPuuWuuWuu,v/x,oxx,uuwuuPv!wW!w'wP'w#xW%x/xWoxxWvw#]wwڱwwڱ]ww~ww~]wkw~#kwpwP w'w w'w9ww w'w9ww w'wPww w'wSwwSwXwPwwPtwwwwwwtww~ww~ww~wwޮww~#wwPw/xTqxxTw"xV"x%xD%x/xVw/xwwP%x,xPw%xx%x~1xSx?xSx~sxxDyxx@xxRxx@yxxPxxVxxDxxxx@xxRxx@xxPxx@xxRxx@xxPy*y@*yZyW{yyWy zW*yyuTyyuTyyuTyyuTz!zuT!z"ztP"z@zuTxyyPyyvyyPyzP*yZyWz zWHyKyugKyTyPTyzug"z@zugHyKyPKyzV"z$zVHyZyWlyzuflytyPty{ywtyyPyywt'z2zuf2z6zR6z@zuf'z6zP6z@zwt1zVnVPzuPuPzudud$;VȈlȈudludllud)l)ludBlBludZludud`lucuc`lP PtucRuctPĉ1ĉOVgFVPOuTgeuTOudgeudVیDیudDudDDudDDudDDud/AudɌیud5Aucόیuc5APόPLWucW[R[eucL[PPu4+5P57u47<O+<Ozzwzzu#@zzt#@z{w{{u#@{{t#@{{u#@zzPzzPz{V{{VzzPzzp|z{w{{u#D{{t#D{{u#DzzPz{V{{V{{P{{W{&{P&{{WZ{{{{V{{w{{u#@{{t#@{|w|(|u#@(|)|t#@)||u#@{{P{{P|&|V&|)|p|)||V{{P{{p|{|w|(|u#D(|)|t#D)||u#D{{P{&|V&|)|p|)||V||P|'|W)|6|P6||Wj|||&|V&|)|p|||W| }W}}P}}PPffVv|V~Vv|Vv|~LL~PP~ PgRP3uz34tz4uzLuziuz*uz~ p!3u34Q!/P/3u#34qgu}0u}@u}yu~0u~@u~yP *Pu}0u} u}0@u}u~0u~ u~0@u~P0:Pu}0u} u}u~0u~ u~PPu}0u}u}u~0u~u~P Pu}0u}u}u~0u~u~PPu}0u}u~0u~P"PgV0V@Vgu} u} R0u}@u}P;u}@Xu}Lu}Iu~@Xu~Lu~IUPPUu}@Xu}Lu}u}^u~@Xu~Lu~u~^jPPju}@Xu}Lu}su~@Xu~Lu~sPpzPu}@Xu}Lpu}u~@Xu~Lpu~P`jPu}@Xu}L`u}u~@Xu~L`u~PLZPu}@Xu}u~@Xu~P@JP;VʂV@XVLV;u}͂߂u}߂Ru}@Xu}Lu}͂PXuzXuz#ruz]Luzuztz?uzHuzi*uzҦuz`Lu}u}t}?u}Hu}i*u}Ҧu}`lP?IPlLu}u}t}?u}O?u}Hu}i*u}Ҧu}uLu~u~t~?u~O?u~Hu~i*u~Ҧu~uPOYPLu}u}t}?u}_?u}Hu}i*u}Ҧu}Lu~u~t~?u~_?u~Hu~i*u~Ҧu~P_iPLu}u}t}?u}o?u}Hu}i*u}Ҧu}Lu~u~t~?u~o?u~Hu~i*u~Ҧu~PoyPLu}u}t}?u}?u}Hu}i*u}Ҧu}Lu~u~t~?u~?u~Hu~i*u~Ҧu~PPLu}u}t}?u}?u}Hu}i*u}Ҧu}ɄLu~u~t~?u~?u~Hu~i*u~Ҧu~ɄՄPP.WLu{u{t{?u{oWo#u{Hu{i*u{˦W˦Ҧu{1Lu~u~t~?u~#u~Hu~i*u~Ҧu~1=PP=Lu{u{t{?u{#u{Hu{i*u{Ҧu{FLu~u~t~?u~#u~Hu~i*u~Ҧu~FRPPRLu{u{t{?u{#u{Hu{i*u{Ҧu{[Lu~u~t~?u~#u~Hu~i*u~Ҧu~[gPɚPgLu{u{t{?u{Ϛ#u{Hu{i*u{Ҧu{pLu~u~t~?u~Ϛ#u~Hu~i*u~Ҧu~p|PϚٚP|Lu{u{t{?u{ߚ#u{Hu{i*u{Ҧu{Lu~u~t~?u~ߚ#u~Hu~i*u~Ҧu~PߚPLu{u{t{?u{#u{Hu{i*u{Ҧu{Lu~u~t~?u~#u~Hu~i*u~Ҧu~PPLu{u{t{?u{#u{Hu{i*u{Ҧu{Lu~u~t~?u~#u~Hu~i*u~Ҧu~P PLu{u{t{?u{#u{Hu{i*u{Ҧu{ĆLu~u~t~?u~#u~Hu~i*u~Ҧu~ĆІPPІLu{u{tz?u{#u{Hu{i*u{Ҧu{نLu~u~t~?u~#u~Hu~i*u~Ҧu~نP)PLuzuztz?uz/#uzHuzi*uzҦuzLu~u~t~?u~/#u~Hu~i*u~Ҧu~P/9PLu{u{t{?u{?#u{Hu{i*u{Ҧu{Lu~u~t~?u~?#u~Hu~i*u~Ҧu~P?IPLu{u{t{?u{O#u{Hu{i*u{Ҧu{Lu~u~t~?u~O#u~Hu~i*u~Ҧu~$POYP$Lu{u{t{?u{_#u{Hu{i*u{Ҧu{-Lu~u~t~?u~_#u~Hu~i*u~Ҧu~-9P_iP9Lu}u}t}?u}o#u}Hu}i*u}Ҧu}rLu~u~t~?u~o#u~Hu~i*u~Ҧu~rLu}u}t}?u}o#u}Hu}i*u}Ҧu}˦u}˦ u}u}4˦PPڇV‹VHMVLu}u}t}?u}oɜu}Hu}i*u}ڇV‹VHMVPÇw2&P‹w2&HLPLMw2&Lu}u}t}?u}oɜu}Hu}i*u}P‹w2&HLPLMw2&‹0HM0Lu}‹u}t}?u}oɜu}Mu}i*u}L1‹?1oɜ1M1i*1VțV?AVWțW?eWʟWVv|țV?AVWw|țW?eWʟw|ћW?eWFeu}LX u}u}4L\PTX u}u}4T\P!u}țu}ʟu}!u}țu}ʟu}!zVzVʟ՟V7EvEItP1ʟ1wluztLu}‹u}t}?u}ou}ɜu}M?u}eʟu}i*u}L1‹?1o1ɜ1M?1eʟ1i*1ɈψuzψӈtɈLu}‹u}t}?u}ou}ɜu}M?u}eʟu}i*u}ڈL1‹?1o1ɜ1M?1eʟ1i*1!VLu{‹u{t{?u{ou{Vɜu{M?u{eu{i*u{$Lu~‹u~t~?u~ou~ɜu~M?u~eu~i*u~$0PP?su}?ou}bL ‹ Puztz  P+?uzo uzɜuzM( 8?uze i uz* @fttPLu}‹@u}Lu}‹@u}P0:PLu}‹0u}Lu}‹0u}P *PLu}‹ u}NJLu}‹ u}NJӊPPӊLu}‹u}܊Lu}‹u}܊P PLu}‹u}Lu}‹u}PPLu}‹u}Lu}‹u}P؋PLu}‹؋u}Lu}‹؋u}'P‹ҋP'Lu}0Lu}0FPOku}Xfu}fjRjku}XjPku}tu}Ru}tPu}u}Ru}Pu}u}Ru}P۝u}ȝ֝u}֝ڝRڝ۝u}ȝڝP۝u}u}Ru}Pu}u}Ru}P(u}(u}(PPuzeuz*uzPuzeuz*uz@e@*@ĎʎPʎuzeuz*uz>u|>u|Ɍ>u}>u}ɌՌPPՌ>u|>u|u|ތ>u}>u}u}ތPP>u|>u|>u}>u}PpzP>u|>pu|>u}>pu}P`jP>u|>`u|>u}>`u})PPZP)>u|>Pu|2>u}>Pu}2>P>JP>VV>u}"u}"8PՎVu|hАu|Vu}hАu}PPVu|hu|Аu|Vu}hu}Аu}PʐPVu|hu| Vu}hu} PPVu|hu| Vu}hu} ,PP,Vu|hu|5Vu}hu}5APPAVu|hu|JVu}hu}JVPhzPՎVVIАVՎVu}LАu}LbPu|u|u}u}PPu|u|u|&u}u}u}&2PP2u|u|;u}u};GPВڒPGu|Вu|Pu}Вu}P\PʒP\u|u|eu}u}eqPPqu|u|zu}u}zPPV~Vu}u}Pgu|pu}pPu|u}Pu|u}PÞߞu}̞ߞu}̞ޞPߞu|u}Pu|u}P3u| 3u} 2P3Ou|<Ou}<NPOku|Xku}XjPku|tu}tPâߢu|̢ߢu}̢ޢPߢu|u}Pu|u}P3u| 3u} 2P3Ou|<Ou}<NPOku|Xku}XjPku|tu}tPu|u}Pݣu|ʣݣu}ʣܣPݣu|u}Pu|u}P/;P0W0u}%PʔP%u|Д0u|.u}Д0u}.:P *P:u|Д u|Cu}Д u}COPPOu|Дu|Xu}Дu}XdP Pdu|Дu|mu}Дu}muPPuu|Дu|~u}Дu}~PݔPu|Дݔu|u}Дݔu}PДڔPu|u}Pסu|ġסu}ġ֡Pסu|u}Pu|u}P+u|+u}*P+Gu|4Gu}4FPGcu|Pcu}PbPcu|lu}l~Pu|u}PS֕u{֖@u{a֕u}֖@u}amP *Pm֕u{֖ u{0@u{v֕u}֖ u}0@u}vP0:P֕u{֖ u{֕u}֖ u}PP֕u{֖u{֕u}֖u}P P֕u{֖u{֕u}֖u}PP֕u{֖u{ʕ֕u}֖u}ʕ֕P֖PS֕V@VS֕u}@u}ЖPu{u}P٠u{u}Pu{u}P-u{-u},P-Iu{6Iu}6HPIeu{Reu}RdPeu{nu}nPnwPOpWRpu}R^P P^u{pu{gu}pu}gsP`jPsu{`u{|u}`u}|PPZPu{Pu{u}Pu}P@JPu{@u{u}@u}P-:Pu{-u{u}-u}ØP*PØu{u{̘u}u}̘ԘPPԘu{ݘu}ݘPu{u}P!u{!u} P!=u{*=u}*<P=Yu{FYu}FXPYuu{buu}btPuu{~u}~Pu{u}Pɜu{ɜu}ȜPpuuu}u}t}+?u}u}Vv|V+?VV5+?55u}u}5u}t}+?u}u}ƙ u}u}4ʙP™ƙ u}u}4™ʙP1+?11uΙuztz+?uzuzיu~t~+?u~u~יPPuztz+?uzu~t~+?u~P+:Pɜu}ϜWw|Wɜ7Ϝu}Ϝu}7u} u}u}4PP#uz#u{"P#?uz,:uz:>R>?uz,>Pʟu{ʟu~ğP u}u}R u}P )u}"u}"&R&)u}&P+Iu}4Bu}BFRFIu}4FPKiu}Tbu}bfRfiu}TfP,Qu}5Gu}GKRKQu}5KPSqu}\ju}jnRnqu}\nPsu~|u}Ru}|PҤu}Ȥu}Ȥ̤R̤Ҥu}̤PԤu}ݤu}Ru}ݤPu{u~P,u{,u~+P,Huz5Hu~5GPHdu{Qdu~QcPdu{mu~mPu{u~P̥u{̥u~ƥPΥu{ץu~ץP u{ u~ P,u{,u~)P.Lu{7Lu~7IPNlu{Wlu~WiPnu{wu~wPԦu}ݦu}Ru}ݦPu}u}Ru}P9u}$2u}26R69u}$6PDRu}RVRVYu}DVP`RVR%V%rRrVReVeRVRVRVRVRRyRVR%V%rRrVReVeRVRVRVRVRRa,,٩,,:F,VR%V%aReVeRVR٩RRVR:FRVReVeRVRRVRاuPPax٩x:Fxa٩:FauP٩uP:FuPa٩:Fax٩x:FxauP٩uP:FuPa6٩6:F6a0٩0:F01auP٩uP:FuP1@V@auL٩uL:FuL1a٩:F1ax٩x:Fx1a1٩1:F11@x@aW٩W:FW1aV٩V:<V@YWYaw|٩W:FW@\V\av|٩V:<VV:<VuL:FuL?``?xx?uPuPWuPZxxZ``ZuPuPWuPZ66Z00quPuPuPqVuLuLuLqxxxq```q111q`WWqVVVWw|WVv|VVVVuLuL٩uPȩuP#uP4̩PĩȩuP#uP4ĩ̩Pr:FRr:FRruPW:uPFRuP:FR:FRuPW:uPFRuP88:8FR800:0FR0uP:uPFRuPVuL:uLFRuL:FR:FR1:1FR1W(WV:VFHV٨W٨w|(WܨVܨv|:VFHV':VFHV':uLFRuL%?V%.PWBu\BCtXCWouuPRԪu@wdPPdO du&dZ&1R1du8du OdxOWPdouoptpwtSfutSβVCSVu@BuXBCtTCSu@ɫSKɫѫPޫu@BuXBCtTCSu@BuTBCtPCSuTPCMPBu\BCtXBu\BCtX+WVV#v|#@VVv|V%v|uX +uXP P+Bu\BCtX+3 udu\4+AW/3 udu\4/;WhuXnyuTy}R}uTn}PìPì}u}~t~utuԯ0ԯu±P±}u}~t~~ut~b uuٲuuu1bu5BuQV}u}~t~utٲVٲųuu5ub5uIuT}u~}~t~~u~t~ųu~u~5u~b5u~Iu~T_P_jv<P\juɲubju~ɲudbjPӲPjuuu15uju# u# u# 15u# tvPvu# ׭VV׭ududɭPPɭ׭uuϭ׭ududϭ׭PP׭u׭u#Pu#+DVdV.Duddud.6Pt~P6Dudtu<Duddtud<DPdnPV}u}~t~utٲVduųub5uIsuu}ud}~t`~udt`ٲdudųudb5udIsududPv<ٲPuuududPP}u~}~t~~u~t~du~ųu~b5u~u~}ud}~t`~udt`dudųudb5ududPu~< P V u@ududP%Pi}u}~t~ut+dub5ul}ud}~t`~udt`+dudb5udlwPwu<+5PtV6DuLzud<DudzP<NP}u\}~tX~u\tXTdu\b5u\ut}u\}~tX~u\tXTdu\b u\}ud}~t`~udt`Tdudb udPT^Pԯ0ԯ}u}~t~utb uԯʰV˱VVմ״VVVVԯʰv˱vvմ״vvvvʰV˱VVմ״VVVVʰv ˱v v մ״v v v v :nu˱Pubuu=nud˱Pudbudud=EP˱ڱPcnu~Pu~bu~u~ynPbȴմy|utnuXPuXbuXȴuXnѲPѲbѲȴѲPnuXPuXbuXȴuXnudPudbudȴudP PnuTuTPuTbuTȴuTnududPudbudȴudǰPPǰʰVǰʰvnu`u`Pu`bu`u`nududPudbududP=JP&nudud=ud)nu`u`=u`)1P07P1nܲܲ0ܲ1=u@DtKnu\u\0u\Nnudud0udNVP *PVnuLuL uL\nudud ud\dPPdnuHuHjnududjnPPdvudjvu`juPvu\|u`|PuLuPPuHuDPȴu`ĴȴudĴȴP״uXݴudݴPuTudPuPudPovuurvududr~PPuHudPųuLųudųPųu˳ҳuҳֳRֳu˳ֳPuudPuudP"5u\(5ud(5P%u%ud$P%1u+1ud+1P7RuCRudCQPRbuXbudXbPK`uDQ`udQ_P`su@fsudfsPuu{ud{PuudPuZuZ[t[wuwxtxpuuu"u"cucvuvu#P~VZuZ[t[wuwxtxVpuuuZuZ[t[wuwxtxpuuuPv<xPuuuudPPVZu@Z[t[wu@wxtVpu@u@u@"Pu@cvu@u@Zu`Z[t\[wu`wxt\pu`u`u`"Pu`cvu`u`Pv<Puuu`u`PPJVZuHZ[tD[wuHwxtDVpuHuHuH"&uHcvuHuHMZu`Z[t\[wu`wxt\pu`u`u`"&u`cvu`u`MYPYev<ǹPVeuȹ׹uD\eu`ι׹u`\ePι޹PӷVӷZuPZ[tL[wuPwxtLVpuPuPcvuPuPZu`Z[t\[wu`wxt\pu`u`cvu`u`Pʷv<PʷuuLʷu`u`ʷPPZuZ[t[wuwxtPuucvuuZudZ[t`[wudwxt`Pududcvudud P ,u<P,VuX#,udud#,P&PhZu`Z[t\[wu`wxt\,Pu`cvu`kZudZ[t`[wudwxt`,PudcvudkwPwu`<,3Ptu\4Cu\zud:CudzP:JPYW[vWcvWZudZ[t`[wudwxt`cvud˸u[hucvuZudZ[t`[wudwxt`Zu`Z[t\[wu`wxt\ǸP[bPǸ˸0˸XVhuV0ZuZ[thwuwxt09PKZuZ[thwuwxtNZudZ[t`hwudwxt`N[PhoPReuTXeudXdPepuXkpudkpPpuv~u~RuvPu`udPu\udP׺uȺ׺udȺֺP׺uݺudݺPuPu`PuL u` Pevudkvu`kvP(;uH.;u`.:P;LuDALu`ALPRcuXcu`XcPxu@~u`~P uJuJKtKuutuu"u PVJuJKtKut"V"uuu"uJu`JKt\Ku`t\u`u`u`"u`Pv<Puuu` u`P PVJuJKtKut"JVJuuu"uJu`JKt\Ku`t\"u`u`u`"u`Pv<"+Pu,;uu`2;u`P2DPOVJuJKtKuVutJTVTuuu"uXaRaJuJKtKutJNRNuuu"uXaPJNPaJuJKtKutTuuu"ugJu`JKt\Ku`t\Tu`u`u`"u`gpPP޽V޽JuJKtKuVutTauuu"uJudJKt`Kududt`Taududud"udƽPƽҽv<Pýҽuu@ɽҽududɽҽPP^u^JuHJKtDKruHruuHuuHtDTauHuHJudJKt`Kududt`Taudud%PP%JuDJKt@KuDuDt@TauDuD+JudJKt`Kududt`Taudud+4PryP{uJuPJKtLKeuPeruuuPtLTauP9uPfuP~JudJKt`Krudududt`Taud9udfud~PPJuLJKtHKruLuLtHTauL9uLfuLJudJKt`Krududt`Taud9udfudPelPVKeVu`Keu`PX_PuTKXuTu`KXu`PKRPJu\JKtXu\tXTau\fu\#u&*t1Ju\JKtXu\tXTau\|u\4JudJKt`udt`Taud|ud4=PT[PJu`JKt\u`t\Ju\JKtXu\tXPu`<Pududu`u`PPHVVJuJKtut%P7JuJKtut:JudJKt`udt`:KPPcvuivudiuPvu@|ud|PuuRuPuHudPuDudPh|u\n|udn|Puu`Puu`Ru`Puu`PuX u` P5uT5u`/P;NuPANudAMPNbuLTbudTbP~u`u\Pudu\Puu`Ru`Puu`Pu u` Ru`P000Pu~t~"u~"#t~#Wu~0u~u~Mu~PSwSYPYw$w$u#t#"u#"#t##Ou#wu#wu#u#qu#3<u~<Vu~t~"u~"#t~#u~Vu~Vqu~u~u~Ru~PWqwWHHqHu~ P Vu~t~"u~"#t~#Wu~Vu~qu~ u~ Pu~t~"u~"#t~#Wu~u~qu~UVu~t~"u~"#t~#Wu~Vu~qu~u~Qu}t}"u}"#t}#Wu}u}qu}u~KWHqHKu~Ru}t}"u}"#t}#Wu}qu}~u~r$u}#$t}#$"u}#$"#t}#$#Wu}#$qu}#$u~Wu~t~W"u~"#t~#5u~5DWu~t~"u~"#t~#Du~P P u~t~"u~"#t~#Du~2u~t~"u~"#t~#Du~Au~t~"u~"#t~#Du~Ju~t~"u~"#t~#Du~JRP5>PRu~t~"u~"#t~#5u~ou~t~"u~"#t~#5u~u~t~"u~"#t~#5u~u~t~"u~"#t~#5u~u~t~"u~"#t~#5u~u~t~"u~"#t~#5u~u~u~t~"u~"#t~#5u~u~t~"u~"#t~#5u~P#2Pu~t~"u~"#t~u~t~"u~"#t~PPWou~`ju~jnRnou~`nPou~xu~Ru~xP>u~&4u~48R8>u~&8P֎u֎ݎp|ݎR֎P+V+rxf0nx0Ȑ̐0+0fVnxVȐʐV+rx+3v|3?P?Gv| +P9?P?Gv|9GVGfudnxud[fudnxud^fucnxuc^fPnuP+ud&uc&*R*+uc*Pv4v4ސv4quPȐuP̐ѐuPuP4uPƏuPƏ0 P 5uDĐƐuDƐȐuP̐ѐ0uD4;uD;AuPAeuD}0ȑ0ȑԑuDޑ0xȐ{ ̐{ 4{ xȐ1̐141xuquѐu1QtQѐQȐi̐i4iq0xȐ0̐ѐ0ِ040uuސuu0uLuuttuPv"̏V̏IuHĐƐuHƐȐV̐ѐuHuH4;uH;AVAuHΏӏVӏquPƐuP̐ѐuPuP4;uP}uPԑuPޑuPΏӏWΏq1Ɛ1̐ѐ114;1}1ԑ1ޑ1ΏW̐ѐWWΏӏVvVӏWw|̐ѐWWvV}uPȑuPޑuP  P MuDĐƐuDuD4;uDȑԑuD  Q 5uTĐƐuTuT4;uTȑԑuT q1Ɛ114;1ȑԑ1 !WĐƐWW4;WȑԑW  P qVƐVV46V 'W'5w|ĐƐWW4;WȑԑW $V$5v|ĐƐVV46VV46VuD4;uDȑԑuD@quTuT@MW@qWĐWMSWSXw|XqWw|MXud]qudud]kPĐuTuTTaPaeuDTeuPe}uPuPԑޑuPlxuPuHudRudPuTLLPLuT{u`{Vu`Vu` V Mu`MUQUuu`XXR X $R$1X1@V@XXX~VVXRXVX|~|||uTL~LLL`u`u@**~ 0[V[^t^_t_ctVttt@UVVW9IPIKRKWP'W*UWWWWKcR@TRTUwvK[V[^t^_t_ct@UVuKu@UK@Uuguu`g{u`{Vu`VVo{u`{Vu`ouoPuuuLuLRuLP' *@  VtttV'u*@'*@Vt'uL*1V12t23t37t7@DDu` V 'u`*1X1@VVu` V u`VtuLP'uL'u&PDRDPDP{u`{Vu`Vu` V Mu`MUQUuu`XXR X $R$1X1@V@XXX~VVXRXVX'Mu`MUQUuu`XXR X $R$*XXRXX'uTL*LLL6bVLMuhMUqUu#uh``r ` $r$*``r``Lu\T*TTTRbPBMudMUqUu#ud\\r \ $r$*\\r\\BuXP*PPPDGPGbQbuXMu`MUQUuu`XXR X $R$*XXRXXXFu`FuTLXR X $R$*XXRXXXbQbuXbVXVv|VbkVkpv|pVv|bpuuuWbpPuPMu`MUQUuuTLXR X $R$*XXRXX uhu`4 u\uT4VV uhu`4Vu@*Mu`MUQUuu`XXR X $R$*XXRXXP PuTL L*LLLV*Vu` X $R$*XP$P#)u#CVCUpV#@W@UpW#&u&-t#-P-SuFuTLFWFUVFrVrwv|wVU[V[_v|_rVr{v|U_uduU_PdvPuTL u\uT4W u\uT4W L 1 L 2 L 3c~lw@w{R{~@l{P@XRXPPVVuWVVudoPoWWdvvu#PvuTuTPuTuTugugPuP<PuP<ugRugP=oWokuPkltLluPWuPWuPQoWokuPkltLluPWTkucklt_lucT`PP``hyQyuLkyPyuTkyQyuLkyQyWw|WyWw|Ww|yududyPPǒ0ǒ'W',w,7WlWǒޒud7udǒޒuc7ucǒӒPӒޒud<+Pǒޒud7udludǒޒ`7`l``udPucRucP 5W5#uT#$tP$:uT:GWGKuTKMWMluT 5W5#uT#$tP$:uT:GW##uc#$t_$Guc#/P:AP/:`?HPH#uL#$tH$:uL?HQHuuP?HPHkVkpv|p}VHSVSXv|XkVkuv|HXud]uudHXP]oP0VvV$:VudԔuducڔucPud<ڔPudud$:ud``$:`Ԕ`ԔudǔPS^uc^bRblucSbPpVvt͕VVvtVvtvv|vv|LLPPP!PՖٖPٖ@uLuLuLPp|'u#@lu#'-P-sQs@uL@OQOguLgkQkїuL;u#@lu#;>P>їuPdu#@lu#dsPs~ v2&ժz@OPO[ v2&ժzce v2&ժzgkPkl v2&ժz@OPO[ v2&ժzce v2&ժzgkPkl v2&ժz@[0cl0@uP[cuPluPїuPP@uH[cPluHїuH@1[c1l1ї1V[cVP̖W[cPlWWїWĖWĖ̖wtlWWїWWlWWїWlWїWluHїuHquPwuP#uP<wP{uP#uP<{PP@VV Ju !pt!"q<"'pl !P!"q"'px !pt!"q<"'pl !P!"q"'px@Ҙu\ژu\jnu\͚u\borto u#<berhehVhorho u#HbҘ0ژ0jn0͚0borto u#<pxvberhehVhorho u#Hplvx{QplvxpxvVPv Ҙu\ژu\ҘudژudǘҘu\ژu\ǘҘudژudʘҘu[ژu[ʘҘPژP͚u\͚udȚu[Ț̚R͚̚u[̚Pw<*/w<w<uP/juPnsuPuP֚uPFuPF0PՙuDfhuDhjuPns0uD֚ݚuDݚuPuDK0Ok0kwuD0j{ n{ ֚{ j1n1֚1=u/usu1R/RsRj n ֚  j ns { ֚ =u*/uuu0uL=u1V1=u=Fvxhjvxݚvx!uPw"!NWNuHfhuHhjWnsuHuH֚ݚuHݚWuH&1V1=u=Fvxhjvxݚvx&FWhjWݚWNSVSuP/huPnsuPuP֚ݚuP0uPOwuPuPNSWN1/h1ns11֚ݚ101Ow11NWnsWOYWNSV|v VS|W|wtnsWOYW|v V\yWnsWOYW0uPXkuPuPPuDfhuDuD֚ݚuDkwuDQՙuTfhuTuT֚ݚuTkwuT1/h11֚ݚ1kw1PV/hVVؚ֚VęVęՙvtfhVVؚ֚VVfhVVؚ֚VVؚ֚VuD֚ݚuDkwuDuT/7uTWW/SWWwtW/7wtww|w/7w|u\u\/7u\ P7fuT>JuTPuDuPuPKOuPwuPuP0KuH0KuH#9Du\DHRHKu\9HPP2uP23tL3uPtL uPP2uP23tL3uPtL uPPuT3>P>uTuT4SuTmuTuTuTOҪmҪpP2uH23tDuHtDmuH uHp2uH#23tD#uH#tD#muH# uH#P PP4uDuDSuH#emuH# uH#aRa4uD4GRGSuDemuDuDR uD#SuH#emuH# uH##&P&SuLemuL uLRSuH#emuH# uH#RaPai v2&ժz4GPGS v2&ժz v2&ժzP v2&ժzRSuLemuL uL4GPGS v2&ժz v2&ժzP v2&ժz4S0004uLemuL uLP4u@emP u@41em1 1VemVPWemP WWwt WW WuL#uL<PuL#uL<PP4VVRS[R[_qrS[r[_q#2ud23t`udt`SeududPS_P32uP23tLuPtLuP)3PPuTtPuTP7L$`r#rwPP7L$7L$#$0 #$#P#0#PEGPS SLSS L/ /L// LP PLPP LP\P\g r2&ժz'8#$8g'5 #$#5<P<g#EGPVt{VVg)-P- Lg#)-p-# #L##gxP.BP P tyQt## #L#QQtQ LQ\t## #L#\_P_t Lt## #L#P v2&ժzP v2&ժzP v2&ժzt LP v2&ժzP v2&ժz00t LiyPtP Liyt11 1Li1y1VVPWP WLiWWwt WLiWW WLiW WLiW LiSiYa#<YeP]a#<]eP'P'tVy~VStSStpPDtDt#Ptt#Pvt{vt#PDtDPt{P{VPtPDPRPP )$EVVV  VVuw )$P  )  $  )$EPEVPPV !V!%t%)PV$P\WPTLRLPHH )HH$H-HH )HH0NWNLWL )LL0<PP#P)77L HLR LPVu`t\Vu`t\u_t[u_t[Pv<PududVu`PPud u_ Ru_P(/u_/3R36u_(3P WWWW ududududP u\ 0 fu`fgt\gu`t\u` fudfgt`gudt`ud 00/AQQuP:Xu\u\:APPu\u`udPudPXvyvSXu`u`S^PPvu`P=VvV=@p@BwZvi0=V=^֨=^D=KD#KPPV=v==DD#P=DD#P==DpP =Q =D D#!PpvDDDDv    vDDDDvvDDDD#PvvDDDv\\\vDDDD#PvpppvDDDv///vDDDvnnnvDDDSvDDav\\dvDDdlPP\WRWPD=MWM\uD\uXtTWFuWtSuWFJPPJu\tXPu\tXPWP\VPvVvv|V\cVcgv|gvVvv|\guXluX\gPl}Pu\tX udu\4W udu\4WuWRuWP QuNuuPUmPPP QuNuu28P8^WPNWW NҪҪ+N^bVbctcgtguLNuLuLPuL^buPb}V}~t~tuPNuPuPVPuPmpp,pzu#,mpp0pzu#00Ku#0NUp0U^u#0^mq0u#0szu#,tuPNpuPuPPuPuu2pu3uPuNpuuPuVuXN2uX2=V=puXuXVuXVPuXVuXN2uX2=V=^uXuXVPuXPWuN^uuWPuWuNLuuPuu\Wttu\Nu\W2u\24W4Lu\u\Pu\uN2uuPuuudu\uXuPNuPuudu\uX2uPuPuu\u3ud3PuPRu@Nu@R2u@u@Pu@PP4Lu`@GudGKRKLud@KPu\Nu\2u\u\Pu\udNud2ududPududNud2udud3Pududu\Nu\ud2u\u\3Pu\udu\uXuPNuPudu\uX2uPuP3PuPu`Nu`2u`u`3Pu`PP3ud%3u`%0Pu\Nu\2u\u\3Pu\u\uXuPNuPu\uX2uPuP3PuPudNud2udud3PudPPuXNuX2uXuX3PuXuXuPNuPuX2uPuP3PuP udNud2udud3Pud PPL^uXRYuTY]R]^uTR]Pu\u`PuPNuP2uPuP3PuPudNud2udud3Pud"PP"uLNuL2uLuL3PuL(udNud2udud3Pud(0PP0Ku#,NUp,U^u#,^mq,)q,0Ku#0NUp0U^u#0^mq0u#0YWuTWuT35W5PuTY]P]uuu3PuY]p]bPbu#u#u#3Pu#iWuTWuTludududltPPt7 7 tuPPWWNhuhitimtuNhu#,u#,^hu#,^huhitimt^mPmuubhuhitimtbmPmuuWudP7 ^puPdkuTkoRopuTdoPpuLv}uT}RuTvP7 ;JPV V/4VSudPuTud\udt`Qud}}udPuTud\udt`uc[uct_PP,udPuT4!ud%P%4uT<CucCGRGQuc<GPcut ut $ucu tu t$u ciu`iVu`t\u`t\Vu`$Vu`u_Ru_Pu`t\u`t\udt`udt`u_t[u_t[Pud<Pu`u`u_u_PPW uT  tP WuTWju\jrWrtuTtxW V  ud  t` *V u[  tW *u[P'P u`  t\ u` ud  t` udP P u\  tX 0,Dud8?u[?CRCDu[8CPDVu`JQu[QURUVu[JUPVju\PPppQp# p# RuLRV p# #uPuPtL p# #uPtL^uPuP WWWQuTQV>VVwKVQp# p# q p# # wwwRuLtHuLuLoruLuLuTp)qVV WoWudt`WoW'w#',P94449Wudt`WW9?q?DPQQWudt`WWQWqW\P" " " " " cWudt`WWudud#pPѳѳѳud#pPudt`udududud#pPѳѳѳpP" " " udt`ududud&pp&+ud#/2p27PAACud#GJpJOPYY[ud#_bpbgPudt`qudWo~W~udt`oWWw#P]~W~udt`]W q Pj! )"  )" +K! K])" ~W~udt`]W +ud: +]:?ud#CFpFKPUų ų+]ųUWud#[^p^cPjudt` ud+]ud+Kud׳ ׳K]׳ud#pP)"  )" K])" udt` udK]ud udSK]Sud#pPK]ud#pPK]ud#pPXK]Xud#pP&K]&(ud#,/p/4Piudt`]oud wwwRIuD]uuDPZV]VVVVIW]WW$P$(t(,tGIP]k0GIu`]u`Ru`G]0d0GIudduduDu\uDqP/ / uDuDWuD#qPqPuT!`W`uXWuX!-PP-u\u\@u`u`@udud@00hWWmu\u\muPPuTuSRuSPu\u`udPudIYVYZutZ[tp[mVmnutnolLZusZ[to[nusnokLgPwusRuswPVW̛VWVW̛uuu#ưu W8u W8hu uu"hlu Wlu uu"u WW#u W̛uuu#u")PGdVJUucUYRYducJYPludr}uc}RucrP֜Vǜucǜ˜R˜֜uc˜PuducRucP&W'W0JJUVW^lVWVW^lu-u2uǞu^lu W؝u W؝ u uu" u W-u uu"2u WWǞu W^lu-u2uǞuɝPVucRucP$uduc#R#$uc#P[zV^iucimRmzuc^mPuducRucPVVUUPWWt0;P;XXVVU0ОVW VW>FVW u>˟uПNuScu u W>xu Wxu uu"u W˟u uu"ПNu WNSWScu W u>˟uПNuScubiPVucRucPŸuducRŸucPVuc R uc P/Eud5@uc@DRDEuc5DPV;V P oUoX.U.;X56P6W;WtPtPtPt P tP.3t39P9;tV;V0U@uU.;UX0V0V#V0P]W]cPcW0@PWPp0.u0.0u0.t0.0u0.0u0@0@uu00u*0uLjxPxu@uuPԷ0urxRxu@uuR0uP PPpqqV0VV#Vr0uP@uPPuPuP00uPu@@u@u@0u@V@VV#Vv@vv#vPuTuT#uTuTtvWwW-W-3w|R/R_WwW_Ww_VxQ_ _vvvvRR~VOVmV#V0OVW%wmW0W%WO`v`dPOmvpVWVWޠVWuޠmuruuu Wޠu WJu uu"JNu WNmu uu"ru WWu Wuޠmuruu P'FV*5uc59R9Fuc*9PNdudT_uc_cRcducTcPVucRucPӡud١ucRuc١P34 p<0.cllxPxzcQMO PWMO PVPWNRPRuLtHuLtHuLNRPRuLtHuLtHuL[aPauTPluTTuT'uTObuTuTuT'lҪObҪHlPuHtDluHtDOuHbuHpuH#tD#luH#tD#OuH#buH#PPPuDuD'uH#GOuH#uH#1R1uDR'uDGOuDuDRuD'uH#GOuH#uH#P'uPGOuPuP"'uH#GOuH#uH#"1P1< v2&ժzP' v2&ժz v2&ժzP v2&ժz"'uPGOuPuPP' v2&ժz v2&ժzP v2&ժz'000TuPGOuPuPT^P^u@GOPu@T1GO11T^VGOVT^P^WGOPW^WwtWdWWuP#uP<PuP#uP<PPVVu Q'6u u QPuP#pxu QPuP#pxnQ lnQ bunQ uLtHluLtHbuuLPlvPvuTtPbuuTbuwnQ gu\ghtXhu\tXu\+ud+3P3gudght`hudt`ud(fWfguXghtThWuXtTWuX(+ud+3P3gudght`hudt`ud:fWfguXghtThWuXtT=guWghtShuWtS=APhwPYgu\ghtXzu\tXYgudght`zudt`\guXghtTzuXtT\hPzPu\uduWRuWPuWRuWP''WWW/u/zVV/rWrzwlWW/uVuzvlV4oWWW4oVVv ugRugPvugRugPǢVVǢϢuǢբuբ٢tޢuϢբuբ٢t6uwuuçu6|vlwvlçvl6|VwVçV:|vlwvlçvl:|VwVçVv uTRuTPvuTRuTPWwpwp*3wpmuWuTuTTuTmwuT*Bu`6=uS=ARABuS6APBTuXHOuSOSRSTuSHSPУݣplݣ u#DУӣpXӣ֣Q֣ݣpXݣ u#(Уu У000*0Уݣplݣ u#D v| /vp/1wУӣpXӣ֣Q֣ݣpXݣ u#( vh /v\/1w|R vh /v\/1w| v| /vp/1w1W V /vt/1w vtPtt vt /vh/1w vP v /v|/1wvx&P&/vl/1w  v /V/1w 1uTuT1Au ADPDIQ<uXuX<Au #ADpDIPUu`u`U]q ]bPhududhnpnsPuTuTududuSuSPPu`u`uSuSPPuXuXuSuSPPvDܥvDvDu@u@]mu@u@çߧu@;u@;W0WlWlu.u.3u@35W5:0:yu@WƦ0]mu@çߧu@{ ]m{ { çߧ{ 1]m11çߧ1 uuu٤1QåQQѤf ]mf f çߧf ٤_ ˥_ _ ]m_ _ çߧ_  uܥuuu0u u0W0;wp.3wp:Cwp]fWkmWçߧWu@v"qV.yVVҦV]mVçߧV0W0;wp.3wp:Cwp]fWkmWçߧW;V.3V:yV]mVçߧV:Rv FMuTMQRQRuTFQPRyvX_uT_cRcyuTXcP;u@.u@3:u@Ʀu@;Du GItIMt;1.13:1Ʀ1WW35WWWXu ^btW1.13511qQuDuDqVqV.VVvlVVvlvv|vvv|uTuTuTPv vxv vxuTuTPPvvpvvpuTuTuTPPQQҦۦu@yu@u@VtvlVVtvlƦҦV&W&Gu GHtHdWdu u GuGHtHuu@ubuu&W&@u bdWdu u 7VbV&W&7u bdWdu u 7VbVmvs{ug{RugsPugRugP6W6Wu WXtXxWxu u Wu# WXt# Xu# u# Pu# vu# u# 6W6Pu vxWxu u GVvV6W6Gu vxWxu u GVvVvugRugPugRugP#p~,,,,ld0l000000000001 1+1.11161T1\1{1~1111111111122!2&233344 44444444444444444445o55555555555555555LRW[pw[p}G 5566667755666677977666666779776(6;6K6P6V6Z6w677P6V6Z6g677P6V6Z6_6w66666666666666666666666697P76697P7666666666666666666777`8777`8777 88`877E8`88888888888EE8E8999Z9h999`9h999999$:====@@"@G@@@"@$@*@-@@@"@$@$@*@/@2@V@Y@g@>AKASAbAAV@Y@g@t@@@@0A@@@@@@@A A.AAA A.A0A>AKASA6A>AKASAAAAAABAAABAB B$B+BlBoBtBAB BB+B>BAB BB1B>BBB>BYBBB>BDBBBDBYBB$BYBlBoBtBB BYB_B B$B_BlBoBtBBBBBB[CBBBPCBBBBB|A|D|>|A|D|} }2}\|| }2}k|| }2}t|| }2}}}}}}}O}}}}~~ ~;~}~~ ~;~~~~}~~ ~;~p~~~~~ "g~~~~ "?RX^g 7 7 7р 7Àŀ27ŀр 2 2 A $ $ Ɓ́фԄׄƁ́Ɓ́ #)D #)D΂ʅ #)Dy΂؂ۂ %+p΂؂ۂ %+H[agp@Pg@Pg@Pg@Pg@Pgbg@Pb@PbÃ΃Ã΃Ã΃Ã΃كф@P-n@P<Q@PEQ@Pz &*Ths/=hs5=hs 369369DPX369<<DPX 0 ]  0 <   0 < z       + 9 W            2@̇X\_e\_hkɆ̆gɆ̆gioriorɆ̆چXgÆ̆φÆɆφچXg &),/14714=@fil܉ ܉08܉OUVflofloflorrfňˈԈ݈fx$>AD$-8>AD>ADXĊ>ADGGXĊx{rr{ '08'08 0̍̍Í̍Í̍   /ďǏɏˏЏPTXZPTXZPTXZf r  ; > A P 8f r      8f r            = C M 8      S { ~    S { ~     g P p   > O U X O U X g   O U X [ [ g   g s y | s y | ; p    p    p    p  Đǐ̐ѐ \048:048:048:FRc  kFRcFRc{{ -{0NWu0NWuA @P5k)/2)/2A7@P)/255A7@P7@PPf5k5k5<?H`kARUXRUX@Pp@P@P@Pdgj dgjuۓ GJMXGJMPPXXhkp^hkp*ǔؔD]`c~~q(B(*03*03B  ؔؔؔXlPXPX)3<?P36?B6<BP` 8#H     ##!!38F#1FX>Nm~~z  2HUbzbzUbUb2H#&)#&)369369U369<*ap* PpPpPpSVYpp  p   p [2JMPJMP[JMPSS[&QTW).1QTW7CFITWTWQTWGq  e     FLZ^aϞŗ##@CD@CDW]_W]_ИatϞ!b(t$b(t:=>HQTHQTb(HKTWKQWb(tw}w}b(aϞ(5(5BEGLיڙ"#0יڙ"#0ڙڙʚʚT:G՝<՛؛ۛƛ՛؛ۛ՛؛ۛ):G՝<  ):G  ):Gb0:G՝pvypvy|Ϝ0:Go՝ĜǜĜǜϜ0:ĜǜʜʜϜ0:    P!p!        P!p!  P!\!b!p!   !p!! !!!!!!!p!!!!! ! !!p!!!!!!""""J"""""J"""""J"! !!?HK *?HK ?HKRpx?BKNBHNRpxR\xRXx~X\~&ȠРlorxȠȠBPfilEgps~gjsvjpv~~УУĢУĢУĢҢʢҢҢآ    0  0 0@0@&@P&@P&4P`,4P`4B`o:B`oorx{rx{dgj0GX9jprx˦0@ææ˦0@ Xg Xg Xg @G@Gȧ ħȧ ȧҧ 0Χҧ 0gqmqFIZЩީFIZhknhkpxЩhkpxЩhkpxЩ&,=-@#sܫܫ߫߫ŪȪ#ŪȪ  #ŪȪϪ@PȪ˪Ū˪Ϫ@PϪ٪P`ժ٪P`٪`tߪ`t-""-JRT6@ά@xǭ@xǭǭ@xά٬߬٬߬%(+%(+6%(+..6Jbhkbhkuʮ  ''28;28;Eq"s""###""""""""""""""""!#<#?#B#<#?#B#P#V#Y#P#V#Y#e#h#k#e#h#k#w###$y$$1$7$:$1$7$:$J$$$$%%.%$$$$$$$$D%U%`%%%%z%%%%%%%%%#'0' (%%&&=&U&[&^&U&[&^&i&t&z&}&&&&&&&&&''''!'''''J'b'h'k'b'h'k'v'''''''''A258=T(k(q(t(k(q(t((QSiix`cfqwx(e))))$)')5);)>)5);)>)N)x))))))x))))))))**q*****+********$+++*,Ihxehxehz}QTWQTW#&3#)+X,,- -,,,,,,,,,,,,--,,,,,,,,--,,,,,,,, -#-)-,-#-)-,-8-w-.0..--T.`.-----------.@.T.-.. ... ..@.T...0.@...0.@.`.c.i.l.c.i.l.x.Wl4Wh4ҵ.....9/C/V/.//////&/w///)0///)0////////R0;1H110;1X110/1X1101|1100000000001%1h1|1111!111!1%1h1|1%1/1X1h1+1/1X1h111111111|):L):L):Lڶ 111112}3323H3V333B2N2Q2Z2`2c2Z2`2c2m2x2{2~222222222222222222222222330383 33038333443344344 444 44440484 4444444404844(484O44$484>4$4(4>4O4g4j4p4s4j4p4s44444445 555 555@5H555555 555@5H55#5H5p555H5N55#5N5p5p5s5y5|5s5y5|5556777 9#6A6D6G68 9/65686A6D6G68888888 9Q6o6r6u688]6c6f6o6r6u68888888866666666776666666677667/76677667/766/7G766/7576657G766G7_766G7M766M7_766_7w766_7e766e7w766w7766w7}766}7766776677667766776677667777777777'9#:@::-90959#:@::n9#:P::n9:P::99r::99999999999 :`:r:99::9:: :`:r: ::P:`:::P:`:::::::::giqgqg}qʷii*BHKBHKVĹո`Ĺٹ͸`Ĺٹ28;28;Fظ`ٹظ۸߸`ٹz7yFILT~7XTi7MTiúúκXyFILi~XaeyFILi~ "(+"(+6ٻ޼PɼPɼ # #.ٻPɼ޼ŻٻPɼ޼j!)KNS);/;!;KNS;@!@KNSν½νννԽԽ&:Hbzz:+<@<P<`<<<<:::::::+<@<P<`<<<<:::&;<<;; ;&;<<<<<<<<&;<<<<<Y;e;h;q;w;z;q;w;z;;;;;;;;;;;;;;;;;;;;;;<<;<<<<+<`<<<<$<'<<$<'<+<`<<<<<<<<<<+<5<P<X<1<5<P<X<$=g>>>>>>>%?v?*=g>>>>>>>%?v?/=6=9=b=>>>=D=G=b=>>>>>>>>b=T>%?3?f?v?=============== >>>>>>>>)>/>2>)>/>2>;>>>A>;>>>A>L>W>g>>>W>Z>`>c>Z>`>c>g>>>3?6?q>>>g>m>>>m>q>>>q>{>>>w>{>>>????AB????AABBABBB???A0A@APAXAAAAAB7B?????A0A@APAXAAAAAB7B??? @AA??? @AAAAAAAA @@AAB7B>@J@M@V@\@_@V@\@_@i@t@w@z@}@@@@@@@@@@@@@@@@@@@@@@@AAPAXAAA A AA A AAPAXAAAAAAAAAAAXAAAAXA^AAA^AAA$A@AHA A$A@AHAƾɾݾex9#&4>GJQ>AJMAGMQQ[ؿW[ؿ[e[aaeTWZoTWZjTWZ]v   @ @9?B,/039?B9?BT9?BEKTTlorT`florlor@]z@]!$!$!$S,?BEHP,67>PSPS_be_be_benwznqz}qw}8w8jY\_jY\_bbj6)9)L))**^)p)s)v)))))|@   (.1 "(.1(.1@FI(.14:@FI@FI[@FILR[[}cpstw}}}  #+.PY\fPS\_SY_ffqlq `BkBqByBBBBBBBBBBBBB C.C7C:CDCbCeChC/ELEPCVCYCbCeChC/E2E8E;E2E8E;ELErCCCC~CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCDCCCCCCCDCCD'DCCDDCCD'DCC'D?DCC'D-DCC-D?DCC?DWDCC?DEDCCEDWDCCWDoDCCWD]DCC]DoDDDDDDDDDEEEEEEEEGGEEEEEEGGGGGGGGEFFFEFFFFFFFFF$F'FF$F'F.FpFxFFF'F*FF$F*F.FpFxF.F8FxFF.F4FxF~F4F8F~FF8FBFFF8F>FFF>FBFFFBFLFFFBFHFFFHFLFFFLFVFFFLFRFFFRFVFFFVFdFFFVF\FFF\FdFFF GGGGGGG#GXdXd5>AH58AD8>DHX[^X[^a0(./LRU_hkvpx_bknbhnvpxvxv|x~|~@P@P"`p"`pA0@0@0@ H-H6H9HCHaHdHgH/JLJOHUHXHaHdHgH/J2J8J;J2J8J;JLJqHHHH}HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHIHHHHHHHIHHI'IHHIIHHI'IHH'I?IHH'I-IHH-I?IHH?IWIHH?IEIHHEIWIHHWIoIHHWI]IHH]IoIIIIIIIII.t:[P[00W^gj      "  ""E"%".{E{LeE{ %(+%(+%(+:%(+..::L@LEHNQHNQ]pJKKKLCL}LLpJJJJJJJ K&K,KL,LJJJK K&K2KNKQK_KjKpKsKK K&K2KNKQK_KjKpKsKKKKKKKKKKKKKKKKKKKKKKLLKKKKKKLL<H[ #&0X #&0X #&ADG&8;ADG|o  hjpv      /25/25FIJ/259?FIJFIJVViloiloilosy7F7F!007B[!0$'7!0$*7'*    $'  $'BEKNEKN[#&,/&,/B   !   !FIORIORV  #XhXh,:2:fiw$MMhMh   17:%+17:17:J17:=CJJeknJVY\_eknekn~eknqw~$M99"+."+.9"%.1%+199QWZ9EKQWZQWZkQWZ]ckkzzz@Pks    "7Ph"7Ph"7Ph+3/[Uknpknp  !!+.0+.0Bmpsmpsvv   &( &(69:_bep_behhp3/[DZ`aZ`appUX[`ltv.:@IIjMZ]^aggjy|y|y|#0|%17@@X[^[^##   0dpy=ILNPTYdpyPTY\\dpyy0 "%(\"%(\"%(\bknybknqqy0C0Cqtz}tz}ILc#%Kilnq%K147l147l147lS`X`p|B%2569??BHTZcvv) X Xn Xn    )  )  )58;t .58;t .58;t .Wh .\h . Pe Pe @P@P `u `u%P` %P` *p ##*p*5`p05`pA! !$' !$'      !$'n E]`c]`cn]`cffnx(369EnSn?S  'd)?5;>O5;>AGOd)ruxx~' 035k=CFZ=CFLRZkvy||F!$5$*-5F~~QWZkQWZ]ckk~ET      LTTTTTTTTWLMTULMU0UUUUUM5M0U>U5MMTUXUU5MWMpUUWMyMXUpUM`OfOiOQVVVWMMMNMMNNNNQVoVMMNSN\N^NSN\N^NNNNNNNNNNO7O8OAOGOMONNNNNNNNOO$O*O>OAOGOMO`OfOiOlOyOOiOlOyOOiOlOyOOlOyOOOOQ!Q$QWWOOOOOOOOOOORPXP_PW9WOOOOOP P"PP P"PCPbP|PPPPPPQbP|PPPPPPPPPPQQ!Q$Q'Q4Q?Q$Q'Q4Q?Q$Q'Q4Q?Q'Q4Q?QEQKQLQQQVVQQQQQQQQQQQQQRRRVVQQQQQQQQQQRRRRRRRRRR!RYRVV)R/R2RFR)R/R2R5R>RFRtRzR|RRUURRRRRRRRRRRRRRRRRRRRRRRRRRUURRRRRRUURSUURSUUSSSSUU5SvSUUDSYSUUMSYSUUvSSSSSSSSSSSSSSSSSSSSSSSTTTUUTPTUUT3TUU'T3TUUPTbTcTTTT\TbTmTsTyTTsTyTTTTTbTcTTTTT Bv/!'/LORgvZ`ctZ`cflt)8036x 036x 036x Vl VX^aX^al x~HKQTKQTg%   #&].47H.47:@Hilow}w}8 # #ADGADGADGfvnvcfou~x~589o~ ! !,589,589BEHIXPVYjPVY\bj~@I@I@I@I@I0@ @PX[]kzeknekntzMPQ(+9"(+.19DMPQDMPQZ]`hkn~nsv~0`k0`k0`k$`k$`kY? Yrtw. ? '*-cij . 5>AO8>ADGOZcijZcij $')Z  147G7<?GcficficfiWE_H_K_X_c_f_i_x_aW'Xx__WWx__0XY``aMa0XXXXXXX%Y+Y8Y``XXXXXXXXXY8YBYEYmYvYYYYYYYYYY8YBYEYmYvYYYYYYYYYYYYYYYZZZYZZZYZZZYYZZZZZ[MaaZCZIZ^ZdZZCZIZ^ZdZZZZZMaiaCZIZ^ZdZZZZZZZZZZ [[3[<[L[R[[[[Z [[3[<[L[R[i[o[u[[[[[[[[[[[[[[[[[[[[[[[[[[[\Q\``!\'\*\>\!\'\*\-\6\>\[\a\c\\\\``k\q\t\\k\q\t\w\\\\\\\\\\\\\\\`a\\\\\\\\\\]]]@]``]]]-]]]]]%]-]X]^]_]g]m]p]X]^]_]g]m]p]g]m]p]]__g]m]p]s]s]]__]]__]]__]k^q^t^_`]^_`]]_`]]_`^^^J^P^W^5^J^P^W^^^J^P^W^k^q^t^k^q^t^E_H_K___^^__^^__^^__^^^$_*_1_^^_$_*_1_^^$_*_1_E_ q  8     c f h    p v y  p v y            $ % " 8             $ %   $ % 8 ; = q t u  " E K N _ E K N Q W _ h q t u h q t u |                     -             6 9 < q   6 9 < q   6 9 < q   X e   ] e      U`&  `p58;uCLO`FLOUX`&MPQ!'*;!'*-3;DMPQDMPQX[]ehk{kps{ U U U<IAI"bbb_c"bbb_c3bbc&c^bdbgbub{b~bub{b~bbbbccbbbbbbbbccbbbcbbbc&c)c/c2c)c/c2cDccbdjd~dfPf|ffcc|ffcc|ffcccccc-fPf&dEdNdQd&d5d8d9d9d2P2]23(44 8G88_9>2P2y333344>2P23344y333333x4433x4433h4x433h4x433X4h433X4h433H4X433H4X43384H43384H433(48433(48488998999P2U2344444455#54555g56j7 8_9w9995^67 8996 6 6666F6L6O6^67 8F6L6O6R6R6^67 877777777777766666666666657=7C7D799 :=!:0:=:;;=!:0:;; ;+;<<!:0:#;+;<<;; ;#;+;9;;<1;9;;<9;G;;;?;G;;;G;U;;;M;U;;;U;_;;;[;_;;;_;i;;;e;i;;;i;s;;;o;s;;;:<=<C<F<=<C<F<R<0:5:;;==&=/=@=>>4@O=`=m=>>4@O=`=J>M>P>[>@?U?O=`=S>[>@?U?J>M>P>S>[>i>0?@?a>i>0?@?i>w> ?0?o>w> ?0?w>>? ?}>>? ?>>??>>??>>>?>>>?>>>>>>>>@@#@&@@#@&@4@`=e=>>=oCopppp=oCoppppppPo^oppPoVoppVo^opp^olopp^odoppdolopplozopqloropprozopqzooqqzooqqooqqooq8qooqqooq8qoo8qXqoo8q>qoo>qXqooXq]qp;p>pApxrr'p-p0p;p>pApxr{rrr{rrrrPpoprpsp,rxr\pbpepoprpsp,r/r5r8r/r5r8rxroprpspp}pppp|qqqqqqqqrrrrsss%sOsUsYsdsssssa@s@@@@@@@@@@@@%A,A/ATAWAZA`AAIIIIJJJJMABI0ICMgMAAAAAAAAAAAAAAAAAAAAAAAAAAAABBAAAAAABBABBBABBB BBB7B:B;BB*B0B7B:B;B7B:B;BHB;BCDD0C6CDD6C>CDD>CLCDD>CDCDDDCLCDDLCQCDD"D%D(D;D"D%D(D+D/E2E5E@EKK/E2E5E8E8E@EKKxEEFFxE~EFF~EEFFEEFFEEFFEEFFEEFFEEFFEEFFEEFGEEFFEEFGEEG8GEEGGEEG8GEE8GXGEE8G>GEE>GXGEEXG]GFFFFFFFFhGnGpGsGsG|GGHJJ`KK]H`HcHnHKK]H`HcHfHfHnHKKnH|HKKtH|HKK|HHpKKHHpKKHH`KpKHH`KpKHHJJHHJJHHJJHHJJHHJJHHJJHHJJGGHHHHHH0I`JpJJJ`K`LCMIIIIPK`KIIIIIIPK`KIJ@KPKJJ@KPKJJ0K@KJJ0K@KJ$J K0KJ$J K0K$J2JK K*J2JK K2J@JKK8J@JKK@JNJJKFJNJJK`JeJJJyMMMMyMMMMMNO$O'O,O8OZP]PbPpPQMMMMAN_NbNeNQQMNSNVN_NbNeNQQQQQQQQ{NNNNNNNNPPNNNNNNNNPPNNPPNNPPNNPPNNPPNNPPNNPPNNpPPNNpPPOOOOOOOOPPOOOOOOOOPP*P4P6PUP@QCQIQLQCQIQLQ^Q^QaQgQjQaQgQjQvQR~TTV%VXR R-RSTT}VVaXXRRR STTRRRSS STT SSTTSSTTS1STT%S1STT1SCSTT7SCSTTCSUSTTISUSTTUSgSTT[SgSTTgSySTTmSySTT R%RSS!T$T'T6TVVcV!T$T'T*T*T6TVVcV6THTcVoVxBxPx[xbxx6x:x>xBxPx[xnxx6x:x>xBxnxx6x:x>xBxqxwxzxxnxqxwxzxxZypyzyxxxxxxxyxxxxxxx yxx yy%y(y-y5y(y-y5y@yByEy@yByEyLyybzoz5{H{{yYzozzyyozxzyz zzyzzzzz zz2zDzGzJzDzGzJzQzz%{({,{`{{zzzzzzzzzzzzzzzzzzzzzzz {{{i{l{q{{zzi{l{q{x{{{}{z{x{{{}{{{ {{{%{({,{5{{{{{p|w||||GJM`|||Y~\~_~x|||||}||}}}}x||}H}}}}}}}}'~(~:~@~F~}}}}}}}~+~1~7~:~@~F~Y~\~_~q~q~~~~~~~G`x~~`x~~`x~~`x~~~,XXYYXYYY2Y;Y>YHYYY2Y5Y>YAY5Y;YAYHYYYHYSYYYNYSYYYYYYYYYYYbZZ\\kZqZtZZkZqZtZwZ}ZZZZZZZZ\\ZZZZZZZZZZZZZZZZZZZZZ([\\ZZ[[ZZ[[ [[3[6[9[p[\.\A[G[J[[[A[G[J[M[S[[[[[[[\\[[[[\\[[[[\\[[\\[[[[[[[[\\[[\\[[\\>\A\G\J\A\G\J\Y\G]}]__P]V]Y]j]P]V]Y]\]b]j]]]]]]]}__]]]]]]]]]]]]]]]]]]]]] ^j_}_]]]]]]]]]]^^^U^._=_&^,^/^@^&^,^/^2^8^@^k^n^q^^^_k^n^q^^^_k^n^q^^^_^^^_^^^^^^^^^_^^^^^^^^M_P_V_Y_P_V_Y_j_7`m`|bb@`F`I`Z`@`F`I`L`R`Z`w`z`}````mb|b``````````````````````Zbmb``````````a aaEab-baaa0aaaa"a(a0a[a^aaaaab[a^aaaaab[a^aaaaabaaabaaaaaaaaabaaaaaaaa=b@bFbIb@bFbIbZb'c]clee0c6c9cJc0c6c9cgAgggg;g>gAgggg;g>gAggggagsgggagcgiglgcgiglgsgggggggggggh h&h)h h&h)h:hЀـ p"%(+@U"ȁ@Vȁׁh~Ă˂0L0 vzGSÄńȄ؄vzÄńȄhhhiikk.lhhhhhhhhh_i8jhjjjkkk.lh i8jHj l.lhhhhhhhhhihhi i8jHjhhi i8jHjhhiihhi i8jHj lllllll.l iCijj/i5i8iCijj/i5i8iCijj/i5i8iCijj/i2i8i;i2i5i;iCijjCiQiHjPjCiQiHjPjCiQiHjPjIiQiHjPjQi_iPjhjQi_iPjhjQiWiPjVjWi_iVjhj_imihjj_imihjj_ieihjnjeiminjjmi{ijjmisijjsi{ijjiiii0kDkiiiiii0kDk j8j\kykjjkk#k0kjjj kDkKkQk\k6ly@yByHyUyXyZyiytyyylytyyyąDžʅzlZlZ``lOpeȉApe/AɌ/5Ɍό5Aό07zzz{ {{z{ {{:{Q{W{Z{Q{W{Z{j{{{{!|0||{{{{{|||0||||0||J|a|g|j|a|g|j|z||||}}}}}S~V~Y~^~jxjx~'*/VYp 0y 00@0@  ###(@UIUUj^jjpsp`p`pP`P`@K@KÁKPǂʂǂʂ͂`forrt{TZ]l?OTZ]``l?OlO_uO__o_oooՄɄՄ%+.=%+.11==RFRRgϚ[gϚg|Ϛߚp|Ϛߚ|ߚߚІĆІІ/ن//?/??O?O$O_$O_$9_o-9_o9zԦ9BLTrzBLThz-ȋHOAg-ȋHOAgȋHOȋHOțAFPV_bɈڈ!0!$$0?Pȋ@0oOAgi,tzPȋ@O(0@0@ 0 0ӊ NJӊ ӊ܊'ȋ'ȋOogi٠â,ՌɌՌՌތpp`p`p)P`)P`)>@P2>@P@"؎АА , ,,A5AAVpJVp@FIp@FIL2&22GВ;GВG\ВP\В\qeqqzu{~u{~Bâ %Д %Д%: B.: B:O CO OdXddumuu~ДДXm 0am 0m0@v0@  ֕ʕ֕(A(A@P]pɜFLO^FLORR^^s`pgs`psP`|P`@P@P0@0@Ø 0Ø 0ØԘ ̘Ԙ pyy||Ι|Ιי0;0;a٩<Ha٩<Ha٩<H!#(+.17=a٩<Hag@٩ag@٩agCFZCFZachknqw}@CFZx<HRx<HRx{~{~<HR{~<HR "%/fiw|;C٪ߪ    #&#&258258FLO258:258:258:FLOYdyyƫɫƫɫҫ۫ޫҫ۫ޫCUҫիޫի۫CU #  #v~ENQ\EHQTHNT\\jٲ\bbjٲɭɭɭ׭ϭ׭%(+6t%(+..6t6Ddt<Ddtٲٲ      +  +cfit+6cfillt+6t6Ttz6<z<TTdTd¯ɯPd"ɯϯدnPd"ɯϯدnPd" 47:Eб47:==Eб]`crxyrxyǰǰ@P@P #&10@ #&))10@1EHKEHKV 0EHKNNV 0Vd \d dnjnilovilorrv"K(K7:@C:@CRƵɵ׵ڵݵS[px $'0r{~xru~u{x߶߶DGJVȹDGJMMVȹVeȹV\ȹι\eιʷʷ  ,,##,,beht,4behkkt,4t4Rtz4:z:RǸ[hǸ[h*-0<EHKShpEHKNNShpźȺźȺ׺(ex(kxûƻCK"  &wwzz"  "",",,J,22JILUaJTILUXXaJTapgpýýýҽýɽɽҽ%%%4r+4rux{ux{~~ererXeXeKXKX+.1+.1=Tc+.144=Tc||(147C147::Ch~n~"6<P(q6<Scij>q$=@[$=@[$=@[#,6?EK#,6?EKhnt 8F2o8FAR8FJR8F{(8(8(8֎fnx;֎ڎݎG369CGUX[UX[fnxUX[^^fnxx;xqxѐِxِސސƏ;Aɏ̏Ώ}ȑ 5ȑԑCIXqCI]q*c(0*ZFIKg@ZFIKV@ZFIKNg*@0GIX069<?B69OX<?BGIOGIXGIXZhpZhu**#&)=CF=CFJX_orwJXdorwcfilfil~PW\bd=KNQKNQ`KNQTT``h@p$',$',p   /:M ##/:M/{}7<?{}:<?xXhkp]hkp{}(:MlԔڔԔ(:ї'ϖҖՖ@ї-0;ϖҖՖ@ї-0DYd@[gl-0d@[gl-0ds@[gl;DYd̖[glqїϖҖՖ@ Ҙژݚ7=@Y\_eĘǘĘǘĘǘҘژĘǘҘژĘǘʘʘҘژݚs{7{Fݚ&FݚILN$Okՙkw+8 8m8mOgmpgmp{Xem 8Xem #8Xem #2GR2GR8XRa8Xem8XeXeXe++FIW$`lrx`cfh`cfh`cfh'' N'=BE5=BE=BEPp Np &)x Ny|HNQ Ni\ Ni\kk NSxyxx'*-'*-<'*-00<%(%(6FIZJMPJMPJMPJMP/A/17:17:AJMP_yJMPSyS_Z}t{=`@HK`-2 -  S[^aS[^a[^al[^addl7:=J7:CF=CFJgsy~lsy~ P @FILPP 8P "(+"(+6^ilmilmssy~y~4^5y~4L47=@7=@L5 """"0(0UXYcfiYZ]cficfitcfillttwz~P!$4^bgQgmsvx{}fiwfiwx , ,  ,/58/58Dquxquxq -69$'-69-69ENQ069<?ENQENQ]`cHNQTW]`c]`c}}}#&#&#&8>A#&,28>A8>APVY8>ADJPVYPVYhPVY\bh 17:07:017:LRU17:@FLRULRUdgjLRUX^dgjdgj0K0K   #& #&#&5#&)/5R`8DG8DGI`8?AD`k8?dkz}-!!--:=@-:=@:=@:=@:=@humuCFIT`hCFILLT`h̛ADGZADGJ̜ޜ##0^l2UX[nUX[^Ǟ @V /Uc ;moWt&)+00morx@0@0~0P%m0PVY_?Nr!$':!$'*¡ӡD#DJKNilorvpObJKNapOb'?EH?EHSilv|0GO0GO0GO""T0"10TGO0Gpbwpbw`p (47:47:Ap47:==ApSVY`SVY`SVY\\`'z0o4o6ç6|ç:|çǣʣͣ**-36-36B1t}7:>ADKQRWZ]dghhknt}t}t}tww}çߧ٤ܤ˥٤ܤ˥;:d;:d:=CF=CFR;NTWQTWfilqyyyyҦ@P7m7mPchkGG,,,,,,,,,,,,0.  "0KPkps "02@BPR`bpr "02@BPR`} =@]`(0X`EPPP s] `   W ` 8@kp``*0s[`w  !!j"p"##y$$.%0%%% ((((=*@*++*,0,U-`-..V/`/)00011334455 99::<<v??7B0)*@BBBLEPEGGLJPJLLWWaa_c`cghkhphjjkk"m0mnno orrrrrs3s@sispsssBuPuvvwwx xxxyy{{||ppU`epOPlpЕЕї#0ǞОcpߧ *,.symtab.strtab.shstrtab.note.gnu.build-id.gnu.hash.dynsym.dynstr.gnu.version.gnu.version_r.rel.dyn.rel.plt.init.text.fini.rodata.eh_frame_hdr.eh_frame.gcc_except_table.init_array.fini_array.jcr.data.rel.ro.dynamic.got.got.plt.data.bss.comment.debug_aranges.debug_info.debug_abbrev.debug_line.debug_str.debug_loc.debug_ranges$.o888 @6@\L\LѝHo..Uod  m ``0 v  #q  p|0)0)~6@D  yb 9[" 9f :R l:V  :Y :P}7 .;=. f;@@ ;0R ;;<} 4<0 p<p !<^ <<Dd =2= ~P e=@B" =tx =aM =>" *>|m" O> |>`)" >" >~( ? " 6?\? ^ ?, ?(" ??T /@[" d@00" @@*" @bJ A0N WA`/" AP A`" #BP [B !B# B2" )CEC!]CX CCCc# 'D`n hD?= D Db D EdE` e" E Er)" F# 9FrF0" F" FFPb1 G!;GFP }Gc! G " G@nA H(H:HP`" XH !HԦ !H oy" Hd I@ II`I0! IIIN! I 4S JV! aJP}7 J#! Jc+ K TK0* }K Ka K" KN 1L` XL@9M Lj L( L`, M@/ oMp!Mp" M MV  M#N bN" Np=0 NP`" ND4 O$O0, HOn jO|O" OOP3 O`V  .PR PPP !P" (Qp` ZQ02O QFT Q0" ,R RR/ xR@z! RRRp< R! S S@S<. SS'  S5! S0 !T0T 4 MT T"( T@;2 UPJQ" U U, UV`-5" ;Vpz! pV V0%" VVpq FW.* uW b! WW " Wx!:XZX" XP Xvz YО" pYY@;2 YZ;" SZ0" ZZ G ZPq" Z) [@s)" C[." p[P! [q+ [ [ [PX" *\`&! T\0N \^ \}] \ ]`!#]YY]k]L ]!] !]1" (^ܷM^pEN |^^.! ^0: /_A_nC" __! _X _(`q``!`@]R a+a) Qa`/ }a " aaP a  Dbp * bb{" Gc !xcpQ cc̷ds" ldp" d0" d" 3e de !eD !ee e f5]" qfb  f#! f(! f] gg17 cgPK ggP h W  5h !Ih0. bhjz" hh?" i^O 0iЇ  \i@a i" iie j`n" 8jj`W j kp"D" NkN kD kk" k}] !l4l-! el@" lZw l" m0" rmЏq mUW mp`" n@1N Jn> jn~y( n" nTU o/( Goeoo" o[" pԧ !,p0, SpD!upx" p#" p qmD 8qNq`t wqtq# q q` r!%r8r.* crr`>b rp~9 r2O (s@V  Ws@C sD!s 00 tL$ 4tj st=$ tb t@ u" NuH tu u" u> u`)" v!Ov`vt xvk" vvw0! MwP" mwww" xr(" Gx`!qxA xȧ !x xyy` 3y@ Oy!ya" yz2O [zy z z1N {" &{<!>{P{3R {{ ! { |` " 5| !\|j |0||]C !}3}# s}! }E }}}2~̦!f~r)" ~ ~@ - ~b  WT * R _O> 8d  " 8s3" `i @W  ɀ <=W d1N @"! -K@ nL@ u" " E0 3O փ$" xx" T`K( iPd  R τ9 W- " R  dN H Յ<. 1 FO> " =! @WvV  r އa   +@ Z;* ˆ" (}" b0m" ͉ !V  ,KPJQ" gd  !֊!( 0 3V  `PX2  !ˋ`FP P Q0! `" Ȍ V  k ,'! W0%" v1 >T Y   !4@9M [mP@I ʎз5p+ _L " \Ə؏@" %" m`W 3" ߐ@D!Kwn" ;" h (p" ̒ܒ9! @!sps3" ! ; =a  ]!@[ @A? $طJPc( q 0/% p * Ay ͖ޖ ! 3_ ^ ] 0!|\ "Z  CP" " |Ԙ`c" ?nv"  !X" Td ! ܚ-! " [@1! $  3F3" {tR Ɯ0  ~P CU n@` ,! ՝@ A1  ;0d m" g (}" 40 ~ !џ@)   2 yc" ̠( *.* Wg1  ȡ١[ Z  ":S _ `n" P0N |!#x!S0Z0Z  n ģ  E}7 ķPE|" " *0LL N0 iP! <. ۥr G|" Pb `Ug h. 'Q! |" " ݧѷ`o RjԷ!;" " M` " ϩA*  " Ct [@q "y" W )BEY dt@ -  Ϋ@@ p?T 2 PV @" ¬" ,K+" `= W  0A 8D!c:-" " -!IL/ ѯ@ +Ue  @+" ݰmD 0l/ V~@. @*" " `" FЕ"  ڲ " 4  p~9  !&S s" P/\   q' /hk" `0" 00" '  ! 3 e`d " Ƕ#! crtstuff.c__JCR_LIST__deregister_tm_clonesregister_tm_clones__do_global_dtors_auxcompleted.6248__do_global_dtors_aux_fini_array_entryframe_dummy__frame_dummy_init_array_entrygtest-all.cc_ZN7testing8internal18OsStackTraceGetter16UponLeavingGTestEv.localalias.384_ZN7testing8internal17TestEventRepeaterD0Ev.localalias.388_ZN7testing8internalL19SumOverTestCaseListERKSt6vectorIPNS_8TestCaseESaIS3_EEMS2_KFivE.constprop.391_ZN7testing8internalL14PrintOnOneLineEPKci.constprop.393_ZNSs4_Rep10_M_disposeERKSaIcE.part.7_ZN7testing8internalL21FormatDeathTestOutputERKSs_ZN7testing12_GLOBAL__N_126PrintByteSegmentInObjectToEPKhjjPSo_ZN7testing7MessagelsIKcEERS0_RKPT_.isra.62_ZGVZN7testing8internal13ColoredPrintfENS0_10GTestColorEPKczE13in_color_mode_ZZN7testing8internal13ColoredPrintfENS0_10GTestColorEPKczE13in_color_mode_ZN7testing8internalL15kTypeParamLabelE_ZN7testing8internalL16kValueParamLabelE_ZN7testingL20kTestShardStatusFileE_ZTIN7testing8internal12_GLOBAL__N_123ClassUniqueToAlwaysTrueE_ZN7testing8internalL23HasGoogleTestFlagPrefixEPKc_ZN7testing8internalL26g_in_fast_death_test_childE_ZN7testing8internalL23kCurrentDirectoryStringE_ZN7testing8internalL17g_captured_stdoutE_ZN7testing8internalL17g_captured_stderrE_ZN7testing8internalL21g_injected_test_argvsE_ZN7testing8internalL20PrintAsCharLiteralToIwwEENS0_10CharFormatET0_PSo_ZN7testing8internalL22PrintAsStringLiteralToEwPSo_ZN7testing8internalL20PrintCharsAsStringToIcEEvPKT_jPSo_ZN7testing8internalL20PrintCharsAsStringToIwEEvPKT_jPSo_ZN7testingL19FormatCountableNounEiPKcS1__ZN7testing8internalL12kUnknownFileE_ZN7testing8internalL27PrintTestPartResultToStringERKNS_14TestPartResultE_ZN7testing8internalL25FormatCxxExceptionMessageEPKcS2__ZN7testingL15kTestShardIndexE_ZN7testingL16kTestTotalShardsE_ZN7testingL16kUniversalFilterE_ZN7testing8internalL12FlagToEnvVarEPKc_ZN7testing8internal18StreamableToStringIPwEESsRKT_.isra.349_ZN7testing12_GLOBAL__N_115IsSubstringImplIPKcEENS_15AssertionResultEbS3_S3_RKT_S7__ZN7testing12_GLOBAL__N_115IsSubstringImplISsEENS_15AssertionResultEbPKcS4_RKT_S7__ZN7testing12_GLOBAL__N_115IsSubstringImplISbIwSt11char_traitsIwESaIwEEEENS_15AssertionResultEbPKcS8_RKT_SB__ZN7testing12_GLOBAL__N_115IsSubstringImplIPKwEENS_15AssertionResultEbPKcS6_RKT_S9__ZN7testing8TestCaseD0Ev.localalias.385_ZN7testing8internal12UnitTestImplD0Ev.localalias.387_ZGVZN7testing8UnitTest11GetInstanceEvE8instance_ZZN7testing8UnitTest11GetInstanceEvE8instance_ZN7testingL18kDefaultOutputFileE_ZN7testing8internalL22ExecDeathTestChildMainEPv_ZN7testingL20kDeathTestCaseFilterE_ZN7testingL18kDisableTestFilterE_ZN7testing8internalL17PrintColorEncodedEPKc.constprop.390_ZN7testing8internalL24kColorEncodedHelpMessageE_ZN7testing8internalL25kAlsoRunDisabledTestsFlagE_ZN7testing8internalL19kBreakOnFailureFlagE_ZN7testing8internalL20kCatchExceptionsFlagE_ZN7testing8internalL10kColorFlagE_ZN7testing8internalL19kDeathTestStyleFlagE_ZN7testing8internalL17kDeathTestUseForkE_ZN7testing8internalL11kFilterFlagE_ZN7testing8internalL25kInternalRunDeathTestFlagE_ZN7testing8internalL14kListTestsFlagE_ZN7testing8internalL11kOutputFlagE_ZN7testing8internalL14kPrintTimeFlagE_ZN7testing8internalL15kRandomSeedFlagE_ZN7testing8internalL11kRepeatFlagE_ZN7testing8internalL12kShuffleFlagE_ZN7testing8internalL20kStackTraceDepthFlagE_ZN7testing8internalL19kStreamResultToFlagE_ZN7testing8internalL19kThrowOnFailureFlagE_ZGVZN7testing8internalL23ExecDeathTestSpawnChildEPKPciE16stack_grows_down_ZZN7testing8internalL23ExecDeathTestSpawnChildEPKPciE16stack_grows_down_ZN7testingL31GetReservedAttributesForElementERKSs_ZN7testingL28kReservedTestSuiteAttributesE_ZN7testingL29kReservedTestSuitesAttributesE_ZN7testingL27kReservedTestCaseAttributesE_GLOBAL__sub_I_gtest_all.cc_ZStL8__ioinit_ZN7testingL22kDefaultDeathTestStyleE_ZTSN7testing8internal12_GLOBAL__N_123ClassUniqueToAlwaysTrueE.L1650.L3537.L1888.L1934.L1651.L1653.L1654.L1655.L1656.L1657.L1658.L1659.L1660.L1661.L3538.L3540.L3541.L3542.L3543.L1889.L1891.L1892.L1893.L1894.L1895.L1896.L1897.L1898.L1899.L1935.L1937.L1938.L1939.L1940.L1941.L1942.L1943.L1944.L1945__FRAME_END____JCR_END__DW.ref.__gxx_personality_v0_GLOBAL_OFFSET_TABLE_DW.ref._ZTIN7testing8internal26GoogleTestFailureExceptionE__x86.get_pc_thunk.bx__TMC_END____dso_handleDW.ref._ZTISt9exception__x86.get_pc_thunk.cx_DYNAMICfileno@@GLIBC_2.0getpagesize@@GLIBC_2.0_ZN7testing8internal6Random8GenerateEj_ZN7testing16AssertionFailureERKNS_7MessageEfputs@@GLIBC_2.0abort@@GLIBC_2.0_ZN7testing8internal18OsStackTraceGetter16UponLeavingGTestEv__errno_location@@GLIBC_2.0_ZTIN7testing4TestE_ZN7testing8internal12UnitTestImpl32SuppressTestEventsIfInSubprocessEv_ZN7testing15AssertionResultlsIPKcEERS0_RKT__ZNK7testing8internal12UnitTestImpl17test_to_run_countEv_ZN7testing11IsSubstringEPKcS1_PKwS3__ZN7testing8TestInfo3RunEv_ZN7testing8internal18StringFromGTestEnvEPKcS2_sigemptyset@@GLIBC_2.0_ZNK7testing8TestCase11GetTestInfoEi_ZTIN7testing8internal17StreamingListenerE_ZNK7testing18TestEventListeners22EventForwardingEnabledEv_ZN7testing11Environment5SetupEv_ZN7testing8internal23DefaultDeathTestFactory6CreateEPKcPKNS0_2REES3_iPPNS0_9DeathTestE_ZN7testing22EmptyTestEventListener20OnTestIterationStartERKNS_8UnitTestEi_ZTVN7testing8internal17StreamingListener20AbstractSocketWriterE_ZTSN7testing8internal24HasNewFatalFailureHelperEconnect@@GLIBC_2.0_ZN7testing4TestC1Ev_ZTVSt18basic_stringstreamIcSt11char_traitsIcESaIcEE@@GLIBCXX_3.4_ZN7testing8internal12UnitTestImplC2EPNS_8UnitTestE_ZN7testing8internal13DeathTestImpl5AbortENS0_9DeathTest11AbortReasonE_ZN7testing4TestD2Evmmap@@GLIBC_2.0_ZN7testing8internal8FilePath11ConcatPathsERKS1_S3__ZN7testing8internal12UnitTestImplD1Ev_ZN7testing22EmptyTestEventListener9OnTestEndERKNS_8TestInfoE_ZN7testing8internal35DefaultGlobalTestPartResultReporter20ReportTestPartResultERKNS_14TestPartResultE_ZN7testing32ScopedFakeTestPartResultReporterC2EPNS_19TestPartResultArrayE_ZSt9__find_ifIN9__gnu_cxx17__normal_iteratorIPPN7testing8TestCaseESt6vectorIS4_SaIS4_EEEENS0_5__ops10_Iter_predINS2_8internal14TestCaseNameIsEEEET_SF_SF_T0_St26random_access_iterator_tag_ZN7testing8internal20ShouldRunTestOnShardEiii_ZN7testing8internal17StreamingListener12SocketWriterD1Ev_ZN7testing8internal27FormatTimeInMillisAsSecondsExmkdir@@GLIBC_2.0_ZNSolsEi@@GLIBCXX_3.4_ZNK7testing8TestCase17failed_test_countEv_ZNK7testing8internal12UnitTestImpl17failed_test_countEvstrerror@@GLIBC_2.0_ZN7testing8UnitTest18GetMutableTestCaseEi__cxa_atexit@@GLIBC_2.1.3regfree@@GLIBC_2.0_ZTSN7testing8TestCaseE_ZN7testing8internal12UnitTestImpl41SetTestPartResultReporterForCurrentThreadEPNS_31TestPartResultReporterInterfaceE_ZN7testing8UnitTest11GetInstanceEv_ZN7testing8internal12UnitTestImpl41GetTestPartResultReporterForCurrentThreadEv_ZNSo5writeEPKci@@GLIBCXX_3.4_ZN7testing8internal18PrintCharAndCodeToIhaEEvT0_PSo_ZN7testing8internal38DefaultPerThreadTestPartResultReporterD1Ev_ZNK7testing8internal12UnitTestImpl21reportable_test_countEv_ZTVN7testing8internal27OsStackTraceGetterInterfaceEmemcmp@@GLIBC_2.0_ZTIN7testing8internal17TestEventRepeaterE_ZN7testing8internal27PrettyUnitTestResultPrinterD1Ev_ZN7testing8internal15ParseStringFlagEPKcS2_PSs_ZN7testing8internal35HandleExceptionsInMethodIfSupportedINS0_12UnitTestImplEbEET0_PT_MS4_FS3_vEPKcfreeaddrinfo@@GLIBC_2.0_ZTSN7testing8internal15NoExecDeathTestE_ZN7testing8internal19TypedTestCasePState25VerifyRegisteredTestNamesEPKciS3__ZTVN7testing8internal24XmlUnitTestResultPrinterE_ZN7testing8internal13GetTestTypeIdEv_ZN7testing17FLAGS_gtest_colorE_ZTVSt15basic_stringbufIcSt11char_traitsIcESaIcEE@@GLIBCXX_3.4_ZN7testing10TestResultC1Ev_ZSt16__throw_bad_castv@@GLIBCXX_3.4_ZTVSt9basic_iosIcSt11char_traitsIcEE@@GLIBCXX_3.4_ZStplIcSt11char_traitsIcESaIcEESbIT_T0_T1_ERKS6_S8__ZSt24__throw_out_of_range_fmtPKcz@@GLIBCXX_3.4.20_ZN7testing8internal24XmlUnitTestResultPrinterD2Ev_ZN7testing8internal11CmpHelperLEEPKcS2_xx_ZN7testing8internal17StreamingListener16OnTestProgramEndERKNS_8UnitTestE_ZN7testing7MessagelsEPKw_ZTVN7testing8internal26ThreadLocalValueHolderBaseE_ZN7testing8internal18StreamableToStringIPcEESsRKT__ZTSN7testing8internal27OsStackTraceGetterInterfaceE_ZTVN7testing8internal15NoExecDeathTestE_ZNK7testing8internal12AssertHelperaSERKNS_7MessageE_ZN7testing8UnitTest14PushGTestTraceERKNS_8internal9TraceInfoE_ZN7testing8internal17StreamingListener12SocketWriter14MakeConnectionEv_ZN7testing8internal17StreamingListener20AbstractSocketWriter15CloseConnectionEv_ZN7testing24ValidateTestPropertyNameERKSsRKSt6vectorISsSaISsEE_ZN7testing8internal9DeathTest24last_death_test_message_E_ZN7testing7MessagelsEPw_ZNSt8ios_baseC2Ev@@GLIBCXX_3.4_ZN7testing8internal13DeathTestImpl6PassedEb_ZN7testing8internal27PrettyUnitTestResultPrinter25OnEnvironmentsTearDownEndERKNS_8UnitTestE_ZN7testing8internal18g_init_gtest_countE_ZN7testing8internal15NoExecDeathTestD2Ev_ZN7testing8internal8FilePath12MakeFileNameERKS1_S3_iPKc_ZN7testing8internal17StreamingListener12SocketWriterD2Ev_ZN7testing10TestResult5ClearEv_ZN7testing8internal14CmpHelperSTREQEPKcS2_PKwS4__ZN7testing4TestD1Ev_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEED2Ev_ZN7testing8internal35FLAGS_gtest_internal_run_death_testE__divdi3@@GLIBC_2.0_ZNK7testing8TestCase16total_test_countEv__cxa_guard_acquire@@CXXABI_1.3_ZNK7testing8TestCase30reportable_disabled_test_countEv_ZN7testing8internal6String23EndsWithCaseInsensitiveERKSsS3__ZN7testing8internal14ParseFlagValueEPKcS2_b_ZN7testing8internal10scoped_ptrISsE5resetEPSs_ZTIN7testing17TestEventListenerE_ZSt9__find_ifIN9__gnu_cxx17__normal_iteratorIPKSsSt6vectorISsSaISsEEEENS0_5__ops16_Iter_equals_valIS2_EEET_SB_SB_T0_St26random_access_iterator_tag_ZNSs6assignEPKc@@GLIBCXX_3.4__xstat@@GLIBC_2.0_ZNSt13runtime_errorC2ERKSs@@GLIBCXX_3.4_ZN7testing8internal11ScopedTraceD2Ev_ZN7testing8internal13HasOneFailureEPKcS2_S2_RKNS_19TestPartResultArrayENS_14TestPartResult4TypeERKSs__gmon_start___Jv_RegisterClasses_ZTVN7testing8internal18OsStackTraceGetterE_ZNSt6vectorIN7testing14TestPartResultESaIS1_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS1_S3_EERKS1__ZTVN7testing32ScopedFakeTestPartResultReporterE_ZN7testing8internal17TestEventRepeater6AppendEPNS_17TestEventListenerE_ZN7testing8internal11g_help_flagE_ZN7testing8internal17TestEventRepeater16OnTestProgramEndERKNS_8UnitTestE_ZN7testing22EmptyTestEventListener18OnTestIterationEndERKNS_8UnitTestEi_ZN7testing8internal29ParameterizedTestCaseRegistryD1Ev_ZN7testing28FLAGS_gtest_stream_result_toE_ZTTSt18basic_stringstreamIcSt11char_traitsIcESaIcEE@@GLIBCXX_3.4_ZdlPv@@GLIBCXX_3.4isspace@@GLIBC_2.0_ZN7testing8internal7PrintToEPKwPSo_ZN7testing8internal14DeathTestAbortERKSs_ZNK7testing10TestResult18HasNonfatalFailureEv_ZN7testing8internal16ForkingDeathTestC2EPKcPKNS0_2REElocaltime@@GLIBC_2.0_ZN7testing8internal12UnitTestImpl21os_stack_trace_getterEv_ZN7testing8internal14CapturedStream11GetFileSizeEP8_IO_FILE_ZN7testing18FLAGS_gtest_filterE_ZN7testing8internal21StackLowerThanAddressEPKvPb_ZTVN7testing8internal9DeathTestE_ZTSN7testing8internal38DefaultPerThreadTestPartResultReporterE_ZN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE11ValueHolderD1Ev_ZN7testing8internal18OsStackTraceGetter19kElidedFramesMarkerE_ZNKSt5ctypeIcE13_M_widen_initEv@@GLIBCXX_3.4.11_ZNSo9_M_insertIPKvEERSoT_@@GLIBCXX_3.4.9_ZN7testing22EmptyTestEventListener15OnTestCaseStartERKNS_8TestCaseE_ZN7testing18TestEventListenersD2Ev_ZN7testing8internal8GTestLogC1ENS0_16GTestLogSeverityEPKcistrchr@@GLIBC_2.0_ZN7testing8internal17kStackTraceMarkerEgetenv@@GLIBC_2.0_ZTIN7testing8internal18OsStackTraceGetterE_ZNSt20__uninitialized_copyILb0EE13__uninit_copyIPN7testing14TestPartResultES4_EET0_T_S6_S5__ZN7testing18TestEventListeners23SuppressEventForwardingEv_ZN7testing8internal17StreamingListenerD0Ev_ZTVN7testing8internal27PrettyUnitTestResultPrinterE_fini__cxa_rethrow@@CXXABI_1.3_ZN7testing8internal38DefaultPerThreadTestPartResultReporterC2EPNS0_12UnitTestImplE_ZN7testing8TestInfoD1Ev_ZNK7testing10TestResult19test_property_countEvputchar@@GLIBC_2.0_ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS2_S4_EERKS2__ZN7testing8internal27PrettyUnitTestResultPrinter18OnTestIterationEndERKNS_8UnitTestEi_ZN7testing8internal12AssertHelperC1ENS_14TestPartResult4TypeEPKciS5__ZSt9__find_ifIN9__gnu_cxx17__normal_iteratorIPN7testing12TestPropertyESt6vectorIS3_SaIS3_EEEENS0_5__ops10_Iter_predINS2_8internal17TestPropertyKeyIsEEEET_SE_SE_T0_St26random_access_iterator_tag_ZNSt8ios_base4InitC1Ev@@GLIBCXX_3.4wcslen@@GLIBC_2.0_ZTSN7testing11EnvironmentEwrite@@GLIBC_2.0_ZN7testing28FLAGS_gtest_death_test_styleE_ZN7testing8internal14GetThreadCountEvpthread_key_create_ZNKSs4findEcj@@GLIBCXX_3.4_ZN7testing8internal35DefaultGlobalTestPartResultReporterD2Ev_ZSt4cerr@@GLIBCXX_3.4_ZN7testing8internal17TestEventRepeaterD1Ev_ZN7testing18TestEventListenersC1Ev_ZNK7testing8internal8FilePath15DirectoryExistsEv_ZN7testing8internal10scoped_ptrISt18basic_stringstreamIcSt11char_traitsIcESaIcEEE5resetEPS6__ZN7testing15AssertionResultlsISsEERS0_RKT__ZN7testing8internal17GetCapturedStreamEPPNS0_14CapturedStreamEtoupper@@GLIBC_2.0_ZN7testing8internal18OsStackTraceGetterD2Ev_ZN7testing8internal17StreamingListener20OnTestIterationStartERKNS_8UnitTestEiregexec@@GLIBC_2.3.4_ZN7testing8internal18StreamableToStringIiEESsRKT__ZN7testing8internal6String15ShowWideCStringEPKw_ZNSt6vectorIPN7testing8TestInfoESaIS2_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS2_S4_EERKS2__ZN7testing8internal16BoolFromGTestEnvEPKcb_ZNK7testing8UnitTest6PassedEv_ZTSN7testing8internal17StreamingListenerEmemset@@GLIBC_2.0_ZTSN7testing8internal16ForkingDeathTestE_ZN7testing8internal12UnitTestImpl25set_os_stack_trace_getterEPNS0_27OsStackTraceGetterInterfaceE_ZN7testing8internal24XmlUnitTestResultPrinter18OutputXmlAttributeEPSoRKSsS4_S4__ZSt18_Rb_tree_decrementPSt18_Rb_tree_node_base@@GLIBCXX_3.4_ZN7testing8internal27PrettyUnitTestResultPrinter20OnTestIterationStartERKNS_8UnitTestEi_ZN7testing32ScopedFakeTestPartResultReporterD0Evisxdigit@@GLIBC_2.0_ZN7testing8internal27PrettyUnitTestResultPrinter16OnTestProgramEndERKNS_8UnitTestE_ZNK7testing8UnitTest11random_seedEv_ZN7testing8internal2RE9FullMatchEPKcRKS1__ZN7testing8internal12ShuffleRangeIiEEvPNS0_6RandomEiiPSt6vectorIT_SaIS5_EE_ZN7testing8internal17StreamingListener9OnTestEndERKNS_8TestInfoE_ZTVN7testing8internal35DefaultGlobalTestPartResultReporterE_ZN7testing8internal13DeathTestImplD1Ev_ZN7testing15AssertionResultC2ERKS0__ZN7testing15AssertionResultlsIA2_cEERS0_RKT__ZNK7testing8internal8FilePath19RemoveDirectoryNameEv_ZN7testing8internal24XmlUnitTestResultPrinter26RemoveInvalidXmlCharactersERKSs_ZNK7testing8UnitTest30reportable_disabled_test_countEv_ZN7testing8internal11CmpHelperNEEPKcS2_xx_ZN7testing32ScopedFakeTestPartResultReporterC1ENS0_13InterceptModeEPNS_19TestPartResultArrayE_ZNK7testing8internal12UnitTestImpl16total_test_countEv_ZN7testing8internal9DeathTestC1Ev_ZN7testing18TestEventListeners22SetDefaultXmlGeneratorEPNS_17TestEventListenerE_ZNSsC1ERKSs@@GLIBCXX_3.4_exit@@GLIBC_2.0_ZN7testing8internal6String15FormatIntWidth2Ei_ZN7testing8internal8GTestLogC2ENS0_16GTestLogSeverityEPKci_ZTIN7testing8internal38DefaultPerThreadTestPartResultReporterE_ZNK7testing8UnitTest17current_test_caseEvstrrchr@@GLIBC_2.0_ZNK7testing10TestResult17GetTestPartResultEiwcscasecmp@@GLIBC_2.1_ZN7testing8internal24HasNewFatalFailureHelperC1Ev_ZN7testing8internal18StreamableToStringIxEESsRKT__ZN7testing14TestPartResult14ExtractSummaryEPKc_ZN7testing8internal16InDeathTestChildEvclone@@GLIBC_2.0_ZN7testing22EmptyTestEventListenerD1Ev_ZN7testing13PrintToStringIxEESsRKT__ZN7testing8internal17Int32FromEnvOrDieEPKci_ZN7testing8internal26GoogleTestFailureExceptionD1Ev_ZN7testing11EnvironmentD0Ev_ZN7testing8internal24HasNewFatalFailureHelperD0Ev_ZN7testing8internal26ThreadLocalValueHolderBaseD2Ev_ZNSt13runtime_errorD2Ev@@GLIBCXX_3.4_ZNK7testing8UnitTest17current_test_infoEv_ZN7testing14IsNotSubstringEPKcS1_S1_S1__ZN7testing8internal17StreamingListener12SocketWriter15CloseConnectionEv_ZN7testing8internal6String17WideCStringEqualsEPKwS3__ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEED1Ev_ZN7testing8internal17StreamingListenerD2Ev_ZN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEED1Ev_ZN7testing8internal23GetLastErrnoDescriptionEv_ZN7testing8internal17TestEventRepeater15OnTestCaseStartERKNS_8TestCaseE_ZN7testing8internal18OsStackTraceGetterD0Ev_ZN7testing8internal29PrintFullTestCommentIfPresentERKNS_8TestInfoE_ZN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE11ValueHolderD0Ev_ZN7testing8internal20DoubleNearPredFormatEPKcS2_S2_ddd_ZTIN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE11ValueHolderE_ZN7testing8internal7PrintToEhPSo_ZNSt6vectorISsSaISsEE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPSsS1_EERKSs_ZNSsC1ERKSsjj@@GLIBCXX_3.4_ZTIN7testing8TestCaseE_ZN7testing8internal27PrettyUnitTestResultPrinter16PrintFailedTestsERKNS_8UnitTestE_ZNSt8ios_base4InitD1Ev@@GLIBCXX_3.4read@@GLIBC_2.0_ZN7testing8internal9DeathTest27set_last_death_test_messageERKSs_ZN7testing8internal15UnitTestOptions17FilterMatchesTestERKSsS3__ZN7testing8internal6String32CaseInsensitiveWideCStringEqualsEPKwS3__ITM_deregisterTMCloneTable_ZN7testing8internal9DeathTest11LastMessageEv_ZN7testing4Test19HasSameFixtureClassEv_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc@@GLIBCXX_3.4_ZStplIcSt11char_traitsIcESaIcEESbIT_T0_T1_ERKS6_PKS3__ZN7testing10TestResult17AddTestPartResultERKNS_14TestPartResultE_ZN7testing8internal13ExecDeathTestD1Ev_ZN7testing8internal12UnitTestImplC1EPNS_8UnitTestE_ZNKSbIwSt11char_traitsIwESaIwEE4findEPKwjj@@GLIBCXX_3.4DeleteThreadLocalValue_ZN7testing8internal18InitGoogleTestImplIcEEvPiPPT_gettimeofday@@GLIBC_2.0_ZN7testing8internal20ExitedUnsuccessfullyEi_ZTVN7testing8internal17StreamingListener12SocketWriterE_ZNK7testing8internal12UnitTestImpl26successful_test_case_countEv_ZNK7testing8internal8FilePath21FindLastPathSeparatorEv_ZN7testing8internal23DefaultDeathTestFactoryD1Ev_ZN7testing8internal2RE12PartialMatchEPKcRKS1_strtol@@GLIBC_2.0fdopen@@GLIBC_2.1_ZN7testing12TestPropertyD1Ev_ZTVN7testing8internal13ExecDeathTestE_ZTIN7testing8internal26GoogleTestFailureExceptionE_ZN7testing8internal13DeathTestImplD2Ev_ZN7testing8internal24XmlUnitTestResultPrinter9EscapeXmlERKSsb_ZN7testing8internal20SingleFailureCheckerD2Ev_ZNSsD1Ev@@GLIBCXX_3.4_ZTSN7testing8internal9DeathTestEfree@@GLIBC_2.0strtoull@@GLIBC_2.0_ZTSN7testing4TestE_ZN7testing8internal17TestEventRepeater18OnTestIterationEndERKNS_8UnitTestEi_ZTSN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE11ValueHolderE_ZN7testing32ScopedFakeTestPartResultReporterC2ENS0_13InterceptModeEPNS_19TestPartResultArrayE_ZTSN7testing8internal13DeathTestImplE_ZNK7testing8internal8FilePath21FileOrDirectoryExistsEv_ZN7testing7MessagelsERKSbIwSt11char_traitsIwESaIwEE_ZN7testing4Test14RecordPropertyERKSsS2__ZN7testing8internal12UnitTestImplD2Ev_ZNK7testing14ExitedWithCodeclEi_ZN7testing8internal11ScopedTraceD1Ev_ZN7testing8internal12UnitTestImpl31GetGlobalTestPartResultReporterEv_ZN7testing4Test14RecordPropertyERKSsi_ZN7testing8internal12AssertHelperD1Ev_ZN7testing8TestInfoC1ERKSsS2_PKcS4_PKvPNS_8internal15TestFactoryBaseE_ZN7testing8internal6String10FormatByteEh_ZN7testing14IsNotSubstringEPKcS1_PKwS3__ZN7testing8internal30GetBoolAssertionFailureMessageERKNS_15AssertionResultEPKcS5_S5__ZTVN7testing8internal12UnitTestImplE_ZN7testing4Test5SetupEv_ITM_registerTMCloneTable_ZNK7testing8UnitTest21successful_test_countEv_ZNSs4_Rep10_M_destroyERKSaIcE@@GLIBCXX_3.4_ZN7testing19TestPartResultArray6AppendERKNS_14TestPartResultE_ZN7testing14TestPartResultD2Ev_ZN7testing8internal12UnitTestImpl28CurrentOsStackTraceExceptTopEi_ZN7testing12TestPropertyD2Ev_ZNK7testing10TestResult15HasFatalFailureEvsigaction@@GLIBC_2.0_ZN7testing4Test15HasFatalFailureEv_ZN7testing8internal8GTestLogD2Evfflush@@GLIBC_2.0_ZN7testing8internal38DefaultPerThreadTestPartResultReporterD0Evmkstemp@@GLIBC_2.0_ZN7testing8internal9EqFailureEPKcS2_RKSsS4_b_ZNK7testing8UnitTest22test_case_to_run_countEv_ZN7testing18TestEventListeners23SetDefaultResultPrinterEPNS_17TestEventListenerEregcomp@@GLIBC_2.0pthread_getspecific_ZTIN7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEE11ValueHolderE_ZN7testing8TestCase19RunTearDownTestCaseEv_ZN7testing8internal19UniversalPrintArrayEPKcjPSo_ZN7testing8internal17TestEventRepeater22OnEnvironmentsSetUpEndERKNS_8UnitTestE_ZNK7testing10TestResult15GetTestPropertyEi_ZN7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEE11ValueHolderD1Ev_ZN7testing8UnitTest13PopGTestTraceEv_ZN7testing11IsSubstringEPKcS1_S1_S1__ZN7testing8internal24ParseGoogleTestFlagsOnlyEPiPPwsocket@@GLIBC_2.0dup2@@GLIBC_2.0_ZN7testing8DoubleLEEPKcS1_dd_ZN7testing8internal7PrintToEwPSofseek@@GLIBC_2.0pthread_mutex_unlock@@GLIBC_2.0_ZNK7testing8internal12UnitTestImpl30reportable_disabled_test_countEv_ZNKSs4findEPKcjj@@GLIBCXX_3.4_ZN7testing8UnitTestC1Ev_ZTSN7testing8internal17StreamingListener12SocketWriterE_ZTIN7testing22EmptyTestEventListenerEisatty@@GLIBC_2.0_ZN7testing7FloatLEEPKcS1_ff_ZN7testing8internal11ScopedTraceC1EPKciRKNS_7MessageE_ZN7testing8UnitTestD0Ev_ZN7testing8internal20SingleFailureCheckerC1EPKNS_19TestPartResultArrayENS_14TestPartResult4TypeERKSs_ZN7testing7MessageC1ERKS0__ZN7testing8internal24XmlUnitTestResultPrinter29TestPropertiesAsXmlAttributesERKNS_10TestResultE_ZN7testing8internal38DefaultPerThreadTestPartResultReporter20ReportTestPartResultERKNS_14TestPartResultEgetaddrinfo@@GLIBC_2.0_ZN7testing8internal17StreamingListener12SocketWriterD0Ev_ZN7testing8internal24ParseGoogleTestFlagsOnlyEPiPPc_ZN7testing8internal27PrettyUnitTestResultPrinter16OnTestPartResultERKNS_14TestPartResultE_ZN7testing8internal5MutexD2Evfclose@@GLIBC_2.1_ZN7testing8internal12UnitTestImpl11FilterTestsENS1_18ReactionToShardingE_ZNK7testing8TestCase21reportable_test_countEv_ZNK7testing14KilledBySignalclEi_ZTVN10__cxxabiv117__class_type_infoE@@CXXABI_1.3_ZN7testing8internal23DefaultDeathTestFactoryD2Ev_ZTVN7testing8internal38DefaultPerThreadTestPartResultReporterE__cxa_guard_release@@CXXABI_1.3_ZN7testing8internal27PrettyUnitTestResultPrinter18OnTestProgramStartERKNS_8UnitTestE_ZN7testing8internal17StreamingListener9UrlEncodeEPKc_ZN7testing8internal6String12FormatHexIntEi_ZN7testing8internal35HandleExceptionsInMethodIfSupportedINS_8TestCaseEvEET0_PT_MS4_FS3_vEPKcdup@@GLIBC_2.0_ZN7testing8internal20SingleFailureCheckerC2EPKNS_19TestPartResultArrayENS_14TestPartResult4TypeERKSs_ZNSs6appendEjc@@GLIBCXX_3.4_ZN7testing8internal35DefaultGlobalTestPartResultReporterC1EPNS0_12UnitTestImplE_ZN7testing8internal27PrettyUnitTestResultPrinterD2Ev__cxa_bad_typeid@@CXXABI_1.3_ZN7testing4TestC2Ev_ZN7testing8internal29ParameterizedTestCaseRegistryD2Ev_ZN7testing8internal13CaptureStderrEv_ZN7testing8internal15NoExecDeathTestD1Ev_ZN7testing8internal18OsStackTraceGetterD1Ev_ZN7testing14InitGoogleTestEPiPPw_ZN7testing8internal17GetCapturedStderrEv_ZN7testing8internal12UnitTestImpl23ListTestsMatchingFilterEv_ZNSt12_Destroy_auxILb0EE9__destroyIPSsEEvT_S3__ZTSN7testing8internal16DeathTestFactoryE_ZN7testing8internal17TestEventRepeater24OnEnvironmentsSetUpStartERKNS_8UnitTestE_ZN7testing8internal2RE4InitEPKc_ZN7testing32ScopedFakeTestPartResultReporterD2Evstderr@@GLIBC_2.0_ZTVN7testing8UnitTestE_ZN7testing8internal12TypeIdHelperINS_4TestEE6dummy_Ememcpy@@GLIBC_2.0_ZN7testing8internal14ShouldUseColorEb_ZTIN7testing8internal9DeathTestE_ZTVN7testing8internal16ForkingDeathTestE_ZN7testing8internal17StreamingListener20AbstractSocketWriter6SendLnERKSs_ZN7testing22FLAGS_gtest_print_timeE_ZNK7testing8TestCase21successful_test_countEv_ZSt18_Rb_tree_incrementPKSt18_Rb_tree_node_base@@GLIBCXX_3.4_ZTSN7testing8internal24XmlUnitTestResultPrinterE_ZN7testing8internal15UnitTestOptions20PatternMatchesStringEPKcS3_strlen@@GLIBC_2.0_ZN7testing8internal10scoped_ptrINS0_16DeathTestFactoryEE5resetEPS2_fopen@@GLIBC_2.1_ZTSN7testing17TestEventListenerE_ZN7testing8internal11CmpHelperEQEPKcS2_xx_ZNSbIwSt11char_traitsIwESaIwEE4_Rep10_M_destroyERKS1_@@GLIBCXX_3.4_ZNSbIwSt11char_traitsIwESaIwEE4_Rep20_S_empty_rep_storageE@@GLIBCXX_3.4_ZTISt13runtime_error@@GLIBCXX_3.4_ZTIN7testing8internal17StreamingListener20AbstractSocketWriterE_ZN7testing8internal12UnitTestImpl14UnshuffleTestsEvpthread_mutex_destroy@@GLIBC_2.0_ZN7testing8internal13CaptureStdoutEv_ZN7testing8internal17TestEventRepeaterD2Ev_ZN7testing8internal27PrettyUnitTestResultPrinterD0Ev_ZNKSs7compareEPKc@@GLIBCXX_3.4_ZN7testing8TestInfoD2Ev_ZN7testing8internal24XmlUnitTestResultPrinter17OutputXmlTestInfoEPSoPKcRKNS_8TestInfoE_ZN7testing14IsNotSubstringEPKcS1_RKSbIwSt11char_traitsIwESaIwEES7__ZNSsC1EPKcRKSaIcE@@GLIBCXX_3.4_ZN7testing8internal27CheckedDowncastToActualTypeINS0_11ThreadLocalISt6vectorINS0_9TraceInfoESaIS4_EEE11ValueHolderENS0_26ThreadLocalValueHolderBaseEEEPT_PT0__ZTIN7testing8internal23DefaultDeathTestFactoryE_ZN7testing8internal17TestEventRepeater7ReleaseEPNS_17TestEventListenerEgai_strerror@@GLIBC_2.1_ZN7testing29FLAGS_gtest_stack_trace_depthE_ZNSt6vectorIPN7testing8TestCaseESaIS2_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS2_S4_EERKS2__ZN7testing22EmptyTestEventListener27OnEnvironmentsTearDownStartERKNS_8UnitTestE_ZN7testing22EmptyTestEventListener11OnTestStartERKNS_8TestInfoE_ZN7testing8internal18PrintCharAndCodeToIhhEEvT0_PSo_ZN7testing8TestCase11AddTestInfoEPNS_8TestInfoE_ZTIN7testing8internal15NoExecDeathTestE_ZTIN7testing32ScopedFakeTestPartResultReporterEwaitpid@@GLIBC_2.0_ZN7testing8internal14ParseInt32FlagEPKcS2_Pi_ZN7testing18FLAGS_gtest_outputE_ZN7testing8internal17StreamingListener16OnTestPartResultERKNS_14TestPartResultE_ZN7testing14KilledBySignalC2Ei_ZTSN7testing22EmptyTestEventListenerE_ZTSN7testing8internal18OsStackTraceGetterE_ZN7testing8internal6IsTrueEb__dynamic_cast@@CXXABI_1.3_ZN7testing8internal31GetCurrentOsStackTraceExceptTopEPNS_8UnitTestEi_ZN7testing8internal12UnitTestImpl31SetGlobalTestPartResultReporterEPNS_31TestPartResultReporterInterfaceEftell@@GLIBC_2.0_ZN7testing8internal13PrintStringToERKSsPSo_ZNK7testing8UnitTest16total_test_countEv_ZTVN7testing4TestE_ZN7testing4Test5SetUpEv_ZNSt6vectorIiSaIiEE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPiS1_EERKiprintf@@GLIBC_2.0_ZN7testing8internal17StreamingListener11OnTestStartERKNS_8TestInfoE_ZN7testing8internal10SkipPrefixEPKcPS2__ZN7testing8internal16WideStringToUtf8EPKwi_ZN7testing8internal19UniversalPrintArrayEPKwjPSo_ZN7testing22EmptyTestEventListener16OnTestProgramEndERKNS_8UnitTestE_ZNSt6localeC1Ev@@GLIBCXX_3.4_ZN7testing8internal11CmpHelperGTEPKcS2_xx_ZNSt6vectorISsSaISsEED2Ev_ZNSt18basic_stringstreamIcSt11char_traitsIcESaIcEEC1ESt13_Ios_Openmode@@GLIBCXX_3.4_ZN7testing8internal13ParseBoolFlagEPKcS2_Pb_ZN7testing8internal24XmlUnitTestResultPrinter16PrintXmlUnitTestEPSoRKNS_8UnitTestE_ZN7testing8internal17StreamingListener12SocketWriter4SendERKSs_ZN7testing8internal13ColoredPrintfENS0_10GTestColorEPKcz_ZNK7testing10TestResult16total_part_countEvchdir@@GLIBC_2.0_ZN7testing8TestCase16RunSetUpTestCaseEv_ZN7testing32ScopedFakeTestPartResultReporterD1Evenviron@@GLIBC_2.0_ZTSN7testing8internal23DefaultDeathTestFactoryE_ZN7testing22EmptyTestEventListenerD0Ev_ZN7testing8internal30WriteToShardStatusFileIfNeededEv_ZN7testing8internal28ParseGoogleTestFlagsOnlyImplIcEEvPiPPT__ZN7testing8internal35HandleExceptionsInMethodIfSupportedINS0_15TestFactoryBaseEPNS_4TestEEET0_PT_MS6_FS5_vEPKc_ZN7testing8internal7PrintToEPKcPSo_ZN7testing18TestEventListenersD1Ev_ZNSt12_Destroy_auxILb0EE9__destroyIPN7testing8internal9TraceInfoEEEvT_S6__ZN7testing8internal17TestEventRepeater11OnTestStartERKNS_8TestInfoE_ZN7testing16AssertionFailureEv_ZN7testing8internal13ExecDeathTest10AssumeRoleEv_ZN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE11ValueHolderD2Ev_ZN7testing18TestEventListenersC2Ev_ZN7testing8internal17TestEventRepeaterD0Evpthread_mutex_init@@GLIBC_2.0__cxa_pure_virtual@@CXXABI_1.3_ZN7testing22EmptyTestEventListener25OnEnvironmentsTearDownEndERKNS_8UnitTestE_ZN7testing15AssertionResultlsIA11_cEERS0_RKT__ZTIN7testing8internal16ForkingDeathTestE_ZN7testing4Test18HasNonfatalFailureEv_ZTVN7testing17TestEventListenerE_ZNKSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE4findERKSs_ZN7testing8internal9MutexBase4LockEv_ZN7testing8internal13CaptureStreamEiPKcPPNS0_14CapturedStreamE_ZN7testing8internal2RED1Evstrcasecmp@@GLIBC_2.0_ZNK7testing19TestPartResultArray4sizeEv_ZN7testing31FLAGS_gtest_death_test_use_forkE_ZN7testing8internal7PrintToEaPSo_ZN7testing8TestCaseD1Ev_ZN7testing8UnitTest14RecordPropertyERKSsS2__ZTVN7testing8TestCaseE_Znwj@@GLIBCXX_3.4_ZNK7testing8TestCase17test_to_run_countEv_ZN7testing28FLAGS_gtest_break_on_failureE_ZN7testing15AssertionResultC1ERKS0__ZN7testing8internal24HasNewFatalFailureHelperD1Ev_ZN7testing8internal17TestEventRepeater9OnTestEndERKNS_8TestInfoE_ZNK7testing8UnitTest21total_test_case_countEv_ZN7testing8internal27PrettyUnitTestResultPrinter9OnTestEndERKNS_8TestInfoE_ZTVN7testing8internal17StreamingListenerE_ZN7testing8internal18OsStackTraceGetter17CurrentStackTraceEii_ZN7testing8TestCase14UnshuffleTestsEv_ZNK7testing8internal8FilePath28CreateDirectoriesRecursivelyEv_ZN7testing8internal16ForkingDeathTest4WaitEv_ZN7testing8internal11CmpHelperGEEPKcS2_xx_ZN7testing8UnitTest17AddTestPartResultENS_14TestPartResult4TypeEPKciRKSsS6__ZN7testing8internal26ThreadLocalValueHolderBaseD0Ev_ZN7testing8TestCaseC1EPKcS2_PFvvES4__ZN7testing4Test3RunEv_ZN7testing8internal35DefaultGlobalTestPartResultReporterD0Ev_ZN7testing16AssertionSuccessEv_ZN7testing8internal26GoogleTestFailureExceptionD2Ev_ZTVN7testing8internal23DefaultDeathTestFactoryEclose@@GLIBC_2.0_ZN7testing7MessageC2Ev_ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS2_S4_EERKS2_fwrite@@GLIBC_2.0_ZTISt9exception@@GLIBCXX_3.4_ZTSN7testing8internal26ThreadLocalValueHolderBaseE_ZN7testing4Test11DeleteSelf_Ev_Znaj@@GLIBCXX_3.4_ZNSt9basic_iosIcSt11char_traitsIcEE4initEPSt15basic_streambufIcS1_E@@GLIBCXX_3.4_ZN7testing8internal10scoped_ptrINS0_24InternalRunDeathTestFlagEE5resetEPS2__ZN7testing8internal13DeathTestImplD0Ev_ZTVN7testing8internal16DeathTestFactoryE_ZN7testing10TestResult20ClearTestPartResultsEv_ZTIN7testing8internal13DeathTestImplE_ZN7testing8internal15CodePointToUtf8Ejfprintf@@GLIBC_2.0strstr@@GLIBC_2.0_ZN7testing8internal7g_argvsE_ZN7testing10TestResultC2Ev_ZTVN7testing8internal24HasNewFatalFailureHelperE_ZN7testing8internal10scoped_ptrINS0_17StreamingListener20AbstractSocketWriterEE5resetEPS3__ZN7testing28FLAGS_gtest_catch_exceptionsE_ZN7testing8internal17TestEventRepeater25OnEnvironmentsTearDownEndERKNS_8UnitTestE_ZN7testing8internal37FormatCompilerIndependentFileLocationEPKci_ZN7testing10TestResultD1Ev_ZN7testing8internal17TestEventRepeater16OnTestPartResultERKNS_14TestPartResultE_ZN7testing11EnvironmentD1Ev_ZTIN7testing8UnitTestEremove@@GLIBC_2.0_ZN7testing8internal17TestEventRepeater20OnTestIterationStartERKNS_8UnitTestEiexecve@@GLIBC_2.0_ZN7testing14InitGoogleTestEPiPPc_ZN7testing8internal17AppendUserMessageERKSsRKNS_7MessageE_ZN7testing13PrintToStringIPKcEESsRKT__ZTIN7testing8internal13ExecDeathTestE_ZN7testing8TestInfoC2ERKSsS2_PKcS4_PKvPNS_8internal15TestFactoryBaseE__bss_start_ZSt29_Rb_tree_insert_and_rebalancebPSt18_Rb_tree_node_baseS0_RS_@@GLIBCXX_3.4_ZN7testing8internal10AlwaysTrueEvwcscmp@@GLIBC_2.0_ZN7testing18TestEventListeners6AppendEPNS_17TestEventListenerE_ZTSN7testing8UnitTestE_ZN7testing8internal32FormatEpochTimeInMillisAsIso8601Expthread_mutex_lock@@GLIBC_2.0_ZNSo5flushEv@@GLIBCXX_3.4_ZTVN10__cxxabiv120__si_class_type_infoE@@CXXABI_1.3_ZTIN7testing8internal26ThreadLocalValueHolderBaseE_ZN7testing8internal13ExecDeathTestD2Ev_ZN7testing8internal18CmpHelperSTRCASEEQEPKcS2_S2_S2__ZN7testing11IsSubstringEPKcS1_RKSsS3__ZN7testing14KilledBySignalC1Ei_ZNK7testing8UnitTest6FailedEv_ZN7testing8internal24XmlUnitTestResultPrinterC1EPKc_ZN7testing8internal27PrettyUnitTestResultPrinter24OnEnvironmentsSetUpStartERKNS_8UnitTestE_ZN7testing8internal12AssertHelperC2ENS_14TestPartResult4TypeEPKciS5__ZStplIcSt11char_traitsIcESaIcEESbIT_T0_T1_EPKS3_RKS6__ZN7testing8internal13ExecDeathTestD0Ev_ZNK7testing8internal8FilePath27RemoveTrailingPathSeparatorEv_ZNK7testing8UnitTest17test_to_run_countEv_ZNSt8ios_baseD2Ev@@GLIBCXX_3.4_ZN7testing8internal30ReportFailureInUnknownLocationENS_14TestPartResult4TypeERKSs_ZN7testing8internal15GetTimeInMillisEv_ZN7testing8internal17TestEventRepeater27OnEnvironmentsTearDownStartERKNS_8UnitTestE_ZN7testing8internal17g_executable_pathE_ZTSN7testing8internal12UnitTestImplE__cxa_allocate_exception@@CXXABI_1.3_ZN7testing8internal12UnitTestImpl26RegisterParameterizedTestsEv_ZN7testing8internal16GetAnsiColorCodeENS0_10GTestColorEfputc@@GLIBC_2.0_ZN7testing8internal24XmlUnitTestResultPrinterD1Ev_ZN7testing8internal27PrettyUnitTestResultPrinter22OnEnvironmentsSetUpEndERKNS_8UnitTestE_ZN7testing8internal26GoogleTestFailureExceptionC1ERKNS_14TestPartResultE_ZN7testing8internal17TestEventRepeater13OnTestCaseEndERKNS_8TestCaseE_ZN7testing8internal9MutexBase6UnlockEv_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE8_M_eraseEPSt13_Rb_tree_nodeISsE_ZN7testing4TestD0Ev_ZNK7testing8internal8FilePath14IsAbsolutePathEv_ZN7testing8internal24XmlUnitTestResultPrinterC2EPKc_ZN7testing8internal15UnitTestOptions15GetOutputFormatEv_ZN7testing8internal15FloatingPointLEIfEENS_15AssertionResultEPKcS4_T_S5__ZN7testing8internal18FormatFileLocationEPKci_ZNK7testing8internal8FilePath12CreateFolderEv_ZN7testing8TestCaseC2EPKcS2_PFvvES4___cxa_free_exception@@CXXABI_1.3_ZNK7testing8internal12UnitTestImpl19disabled_test_countEv__pthread_key_create_ZN7testing8internal27PrettyUnitTestResultPrinter27OnEnvironmentsTearDownStartERKNS_8UnitTestE_ZN7testing8internal35HandleExceptionsInMethodIfSupportedINS_4TestEvEET0_PT_MS4_FS3_vEPKc_ZTSN7testing8internal17StreamingListener20AbstractSocketWriterE_ZNSdD2Ev@@GLIBCXX_3.4_ZNSs6assignERKSs@@GLIBCXX_3.4_ZNK7testing8UnitTest26successful_test_case_countEv_ZN7testing9internal220PrintBytesInObjectToEPKhjPSo_ZN7testing14ExitedWithCodeC1Ei_ZN7testing8internal17Int32FromGTestEnvEPKci_ZN7testing8internal20SingleFailureCheckerD1Ev_ZSt19__throw_logic_errorPKc@@GLIBCXX_3.4_ZNK7testing8internal12UnitTestImpl22test_case_to_run_countEv_ZN7testing22FLAGS_gtest_list_testsE_ZN7testing8internal23DefaultDeathTestFactoryD0Ev_ZN7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEED2Ev_ZNSt6vectorIPN7testing11EnvironmentESaIS2_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS2_S4_EERKS2__ZTVN7testing8internal26GoogleTestFailureExceptionE_ZNK7testing8UnitTest17failed_test_countEv_ZNSs6assignEPKcj@@GLIBCXX_3.4_ZN7testing7MessageC2ERKS0__ZN7testing8internal8FilePath9NormalizeEvmemmove@@GLIBC_2.0_ZTIN7testing8internal24HasNewFatalFailureHelperE_ZN7testing8internal12UnitTestImplD0Ev_ZN7testing8internal18CmpHelperSTRCASENEEPKcS2_S2_S2__ZNK7testing8UnitTest19disabled_test_countEv_ZNK7testing8UnitTest11GetTestCaseEi_ZdaPv@@GLIBCXX_3.4_ZTIN7testing8internal24XmlUnitTestResultPrinterE_ZNK7testing8internal12UnitTestImpl22failed_test_case_countEv_ZN7testing8internal12UnitTestImpl14RecordPropertyERKNS_12TestPropertyE_ZTSN7testing8internal26GoogleTestFailureExceptionE_ZN7testing22EmptyTestEventListener13OnTestCaseEndERKNS_8TestCaseE_ZNK7testing8UnitTest22failed_test_case_countEv_ZNK7testing8internal8FilePath15RemoveExtensionEPKc_ZTSN7testing8internal17TestEventRepeaterE_ZN7testing8internal5MutexD1Ev_ZN7testing8TestCase12ShuffleTestsEPNS_8internal6RandomE_ZN7testing8internal6String13CStringEqualsEPKcS3__ZNK7testing8UnitTest18ad_hoc_test_resultEv_ZTVN7testing8internal13DeathTestImplE_ZN7testing8internal12AssertHelperD2Evgetcwd@@GLIBC_2.0_ZN7testing8internal20StringStreamToStringEPSt18basic_stringstreamIcSt11char_traitsIcESaIcEE_ZNSt9basic_iosIcSt11char_traitsIcEE5clearESt12_Ios_Iostate@@GLIBCXX_3.4_ZN7testing19FLAGS_gtest_shuffleE_ZN7testing8internal17GetCapturedStdoutEv_ZN7testing8internal15FloatingPointLEIdEENS_15AssertionResultEPKcS4_T_S5___cxa_throw@@CXXABI_1.3_endstdout@@GLIBC_2.0_ZN7testing22EmptyTestEventListener16OnTestPartResultERKNS_14TestPartResultE_ZN7testing22EmptyTestEventListener18OnTestProgramStartERKNS_8UnitTestE_ZNK7testing8UnitTest15start_timestampEv_ZN7testing8internal17StreamingListener15OnTestCaseStartERKNS_8TestCaseE_ZTVN7testing22EmptyTestEventListenerE_ZNKSt15basic_stringbufIcSt11char_traitsIcESaIcEE3strEv@@GLIBCXX_3.4_ZNSt6vectorIPcSaIS0_EE6insertEN9__gnu_cxx17__normal_iteratorIPS0_S2_EERKS0__ZN7testing8internal35DefaultGlobalTestPartResultReporterC2EPNS0_12UnitTestImplE_ZN7testing8internal12UnitTestImpl11GetTestCaseEPKcS3_PFvvES5__ZN7testing8internal27CheckedDowncastToActualTypeINS0_11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE11ValueHolderENS0_26ThreadLocalValueHolderBaseEEEPT_PT0_puts@@GLIBC_2.0_ZTSN7testing8internal35DefaultGlobalTestPartResultReporterE_ZTVN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE11ValueHolderE_ZN7testing8internal15NoExecDeathTestD0Evfork@@GLIBC_2.0_ZTVSt15basic_streambufIcSt11char_traitsIcEE@@GLIBCXX_3.4_ZN7testing8UnitTestD2Ev_ZNK7testing8internal12UnitTestImpl21total_test_case_countEv_ZN7testing14ExitedWithCodeC2Ei_ZNSo9_M_insertImEERSoT_@@GLIBCXX_3.4.9_ZTIN7testing8internal16DeathTestFactoryE_ZN7testing8UnitTest14AddEnvironmentEPNS_11EnvironmentE_ZN7testing8internal9DeathTest6CreateEPKcPKNS0_2REES3_iPPS1__ZN7testing23FLAGS_gtest_random_seedE_ZN7testing8internal14StackGrowsDownEv_ZNK7testing15AssertionResultntEv_ZN7testing8internal24HasNewFatalFailureHelper20ReportTestPartResultERKNS_14TestPartResultE_ZNSo9_M_insertIdEERSoT_@@GLIBCXX_3.4.9_ZN7testing14IsNotSubstringEPKcS1_RKSsS3__ZNSbIwSt11char_traitsIwESaIwEEC1EPKwRKS1_@@GLIBCXX_3.4_ZN7testing8internal25ReportInvalidTestCaseTypeEPKcS2_i__cxa_end_catch@@CXXABI_1.3fcntl@@GLIBC_2.0_ZSt17__throw_bad_allocv@@GLIBCXX_3.4_ZTIN7testing11EnvironmentEpthread_key_delete_ZN7testing8internal11CmpHelperLTEPKcS2_xx_ZN7testing8internal12UnitTestImpl19current_test_resultEv_ZTVN7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEE11ValueHolderE_ZN7testing32ScopedFakeTestPartResultReporter4InitEv_ZN7testing8UnitTest9listenersEv_ZN7testing8internal35DefaultGlobalTestPartResultReporterD1Ev_ZN7testing11Environment8TearDownEv_ZN7testing8internal23kTestTypeIdInGoogleTestE_ZNSt6vectorIN7testing12TestPropertyESaIS1_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS1_S3_EERKS1__ZNSs4_Rep20_S_empty_rep_storageE@@GLIBCXX_3.4_ZNSs4_Rep9_S_createEjjRKSaIcE@@GLIBCXX_3.4_ZNSt6vectorIPcSaIS0_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS0_S2_EERKS0__ZN7testing8internal14CmpHelperSTRNEEPKcS2_S2_S2__ZN7testing8internal24XmlUnitTestResultPrinterD0Ev_ZTIN7testing8internal35DefaultGlobalTestPartResultReporterE_ZN7testing8internal18g_linked_ptr_mutexE_ZNSsC1EPKcjRKSaIcE@@GLIBCXX_3.4_ZTSN7testing32ScopedFakeTestPartResultReporterE_ZN7testing22EmptyTestEventListener24OnEnvironmentsSetUpStartERKNS_8UnitTestE_ZTSN7testing8internal27PrettyUnitTestResultPrinterE_ZN7testing32ScopedFakeTestPartResultReporter20ReportTestPartResultERKNS_14TestPartResultE__environ@@GLIBC_2.0_ZN7testing8internal12UnitTestImpl12ShuffleTestsEvstrncmp@@GLIBC_2.0_ZN7testing8internal26GoogleTestFailureExceptionD0Ev_ZNK7testing19TestPartResultArray17GetTestPartResultEivfprintf@@GLIBC_2.0_ZN7testing8internal26GoogleTestFailureExceptionC2ERKNS_14TestPartResultE_ZN7testing8internal24HasNewFatalFailureHelperC2Ev_ZN7testing18TestEventListeners8repeaterEv_ZN7testing8internal16ForkingDeathTestC1EPKcPKNS0_2REE_ZTSN7testing31TestPartResultReporterInterfaceE_ZN7testing8internal12UnitTestImpl11RunAllTestsEv_ZN7testing8internal15NoExecDeathTest10AssumeRoleEv_ZNK7testing8internal8FilePath15IsRootDirectoryEvmunmap@@GLIBC_2.0_ZN7testing15AssertionResult13AppendMessageERKNS_7MessageE_ZN7testing8internal24GetCurrentExecutableNameEv_ZN7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEED1Ev_ZN7testing8internal17PrintWideStringToERKSbIwSt11char_traitsIwESaIwEEPSo__cxa_guard_abort@@CXXABI_1.3_ZTIN7testing8internal27PrettyUnitTestResultPrinterE_ZN7testing8internal15UnitTestOptions27GetAbsolutePathToOutputFileEv_ZN7testing10TestResultD2Ev_ZN7testing10TestResult20ValidateTestPropertyERKSsRKNS_12TestPropertyE__cxa_begin_catch@@CXXABI_1.3_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEED0Ev_ZN7testing8TestCaseD0Ev_ZNSt18basic_stringstreamIcSt11char_traitsIcESaIcEED1Ev@@GLIBCXX_3.4_ZNK7testing8TestCase19disabled_test_countEvpipe@@GLIBC_2.0_ZNSs6appendEPKcj@@GLIBCXX_3.4_ZN7testing8internal13DeathTestImpl26ReadAndInterpretStatusByteEvfread@@GLIBC_2.0_ZN7testing8TestCase3RunEv_ZNK7testing8UnitTest20original_working_dirEv_ZN7testing8internal15UnitTestOptions13MatchesFilterERKSsPKc_ZN7testing8internal11ScopedTraceC2EPKciRKNS_7MessageE_ZNSt6vectorISsSaISsEED1Ev_ZN7testing8internal17TestEventRepeater18OnTestProgramStartERKNS_8UnitTestE_ZTIN7testing8internal12UnitTestImplE_ZTVN7testing31TestPartResultReporterInterfaceE_edata_ZN7testing8UnitTest27parameterized_test_registryEv_ZN7testing8internal8GTestLogD1Evsnprintf@@GLIBC_2.0_ZN7testing8internal29ParseInternalRunDeathTestFlagEv__gxx_personality_v0@@CXXABI_1.3_ZN7testing8internal11ShouldShardEPKcS2_b_ZN7testing32ScopedFakeTestPartResultReporterC1EPNS_19TestPartResultArrayE_ZN7testing28FLAGS_gtest_throw_on_failureE_ZN7testing8internal17StreamingListener13OnTestCaseEndERKNS_8TestCaseE_ZN7testing22EmptyTestEventListenerD2Ev_ZN7testing8TestCase11ClearResultEv_ZN7testing8UnitTest3RunEv_ZTIN7testing8internal27OsStackTraceGetterInterfaceE_ZNK7testing8internal12UnitTestImpl21successful_test_countEv_ZN7testinglsERSoRKNS_14TestPartResultE_ZN7testing8internal17StreamingListener18OnTestIterationEndERKNS_8UnitTestEistrdup@@GLIBC_2.0_ZN7testing8internal27PrettyUnitTestResultPrinter15OnTestCaseStartERKNS_8TestCaseE_ZN7testing18TestEventListeners7ReleaseEPNS_17TestEventListenerE_ZNK7testing8internal8FilePath14RemoveFileNameEv_ZTSN7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEE11ValueHolderE_ZN7testing11Environment5SetUpEv_ZNSs12_S_constructIPKcEEPcT_S3_RKSaIcESt20forward_iterator_tag_ZN7testing38FLAGS_gtest_show_internal_stack_framesE_ZN7testing8internal14CapturedStream14ReadEntireFileEP8_IO_FILE_Unwind_Resume@@GCC_3.0_ZN7testing18FLAGS_gtest_repeatE_ZTIN7testing31TestPartResultReporterInterfaceE_ZN7testing8internal38DefaultPerThreadTestPartResultReporterC1EPNS0_12UnitTestImplE_ZN7testing8internal28ParseGoogleTestFlagsOnlyImplIwEEvPiPPT__ZN7testing10TestResult14RecordPropertyERKSsRKNS_12TestPropertyE_ZN7testing11EnvironmentD2Evwcsstr@@GLIBC_2.0strcmp@@GLIBC_2.0_ZNK7testing7Message9GetStringEv_ZNSt6localeD1Ev@@GLIBCXX_3.4_ZN7testing8internal26ThreadLocalValueHolderBaseD1Ev_ZN7testing7MessageC1Ev_ZN7testing8internal18SetInjectableArgvsEPKSt6vectorISsSaISsEE__cxa_finalize@@GLIBC_2.1.3_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE16_M_insert_uniqueERKSs_ZNK7testing8UnitTest12elapsed_timeEv_ZNSo3putEc@@GLIBCXX_3.4_ZNK7testing10TestResult6FailedEvexit@@GLIBC_2.0_ZN7testing11IsSubstringEPKcS1_RKSbIwSt11char_traitsIwESaIwEES7__ZN7testing8TestCaseD2Ev_ZN7testing8internal9DeathTestC2Ev_ZN7testing8internal6String28CaseInsensitiveCStringEqualsEPKcS3__ZN7testing8internal27PrettyUnitTestResultPrinter11OnTestStartERKNS_8TestInfoE_ZN7testing8internal38DefaultPerThreadTestPartResultReporterD2Ev_ZN7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEE11ValueHolderD0Evpthread_setspecific_ZNSs6appendERKSs@@GLIBCXX_3.4_ZN7testing8internal18ParseNaturalNumberIiEEbRKSsPT__ZN7testing8internal10ParseInt32ERKNS_7MessageEPKcPi_ZNK7testing8UnitTest21reportable_test_countEv_ZN7testing8internal24XmlUnitTestResultPrinter18OnTestIterationEndERKNS_8UnitTestEi_ZTVN7testing8internal17TestEventRepeaterE_ZN7testing8internal17StreamingListener18OnTestProgramStartERKNS_8UnitTestE_ZN7testing35FLAGS_gtest_also_run_disabled_testsE_ZN7testing22EmptyTestEventListener22OnEnvironmentsSetUpEndERKNS_8UnitTestE_ZTVN7testing11EnvironmentE_ZSt16__ostream_insertIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_PKS3_i@@GLIBCXX_3.4.9_ZN7testing8TestCase18GetMutableTestInfoEipthread_self@@GLIBC_2.0_ZN7testing8internal8FilePath22GenerateUniqueFileNameERKS1_S3_PKc_ZNKSt13runtime_error4whatEv@@GLIBCXX_3.4_ZN7testing8internal8FilePath13GetCurrentDirEv_ZN7testing8internal14CmpHelperSTRNEEPKcS2_PKwS4__ZN7testing13PrintToStringIPKwEESsRKT__ZN7testing8internal2RED2Ev_ZN7testing8internal23MakeAndRegisterTestInfoEPKcS2_S2_S2_PKvPFvvES6_PNS0_15TestFactoryBaseE_ZNSo9_M_insertIxEERSoT_@@GLIBCXX_3.4.9_ZN7testing4Test8TearDownEv_ZN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEED2Ev_ZN7testing14TestPartResultD1Ev_ZN7testing15AssertionResultlsINS_14TestPartResultEEERS0_RKT__ZNK7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEE16GetOrCreateValueEv_ZN7testing8internal12UnitTestImpl19PostFlagParsingInitEv_ZN7testing8internal12UnitTestImpl24ConfigureStreamingOutputEv_ZNKSt5ctypeIcE8do_widenEc_ZN7testing8internal24XmlUnitTestResultPrinter16PrintXmlTestCaseEPSoRKNS_8TestCaseE_ZN7testing8internal14CmpHelperSTREQEPKcS2_S2_S2__ZN7testing8internal24HasNewFatalFailureHelperD2Ev_ZTIN7testing8internal17StreamingListener12SocketWriterE_ZN7testing8internal24XmlUnitTestResultPrinter21OutputXmlCDataSectionEPSoPKc_ZN7testing8internal18PrintCharAndCodeToIwwEEvT0_PSo_ZN7testing8internal12UnitTestImpl18ConfigureXmlOutputEv_ZNSs7reserveEj@@GLIBCXX_3.4_init_ZN7testing8internal18GetInjectableArgvsEv_ZN7testing8internal10scoped_ptrIKSsE5resetEPS2__ZN7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEE11ValueHolderD2Ev_ZN7testing8internal17StreamingListenerD1Ev_ZN7testing8UnitTestC2Ev_ZN7testing8UnitTestD1Ev_ZN7testing8internal27PrettyUnitTestResultPrinter13OnTestCaseEndERKNS_8TestCaseE_ZNK7testing8internal8FilePath11IsDirectoryEv_ZN7testing8internal18InitGoogleTestImplIwEEvPiPPT__ZTSN7testing8internal13ExecDeathTestEdlt-daemon-2.18.4/gtest-1.7.0/lib/.libs/libgtest_main.a000066400000000000000000000503721353342203500221700ustar00rootroot00000000000000! / 1428496272 0 0 0 14 ` Rmaingtest_main.o/ 1428496272 1000 1000 100664 20588 ` ELF;4(Running main() from gtest_main.ccL$qUVSQ˃qhXZVS PeY[^]aÍh hhhPW| 0Kn (eint' 7l`z_ 8e4 n     n $ ( , 0  4  e8 _e< @ >D LF nG p H %L " .T ) /X 0 0\ 7 1` > 2%d d4eh 6l@ S!  Vn X0 \Te]O  ^Cp (| e  !''std"  @[  O  f  |        6  R  h  t      &  <  ]  y       4 O o          $ O j      % ; [ { ɛ ʻ    & D c    0/    e  (17eq N ' J77lt ' g77 ne== = ==7 R CC= ICC=  C5Ca ~OI n7 $?' IIeof ( b ,I 0 5O 6| 7r e3nPW v A|9JA  K g[ Yg _  K[>8 [ Z  = ' !;A"#N""e$s %> tZ&dect%Vt&hex t%t%t &octt@% t' t'H "t' &t')t'8,t'/t '3t@%6t%9tJ'<t(*J% N o %Q %V %fY (# in&appl  &ateo % t &inw &outz %p}  (,&beg9  &cur9 &end9 RSTO \e3hMib ) * tr1* +,;- . / 012. 2_Tp  3> 4J' 9 e ~  5Ta0 j6 O | e6Q O  86   e 3 6O 3  6t  e    3 6)Ke  e6Re6   76{eR   76!O h  8n O 6 % !% [ 6 m%  !% 6> ie   [ 6%   % !6O & 3  6O < 3 6\e]  % 76jey   76k O O  6xde   6e   6:qe  % 6e  6 le4 6eO 6r%o3  9    9e  9, e  9   9%  6W% % !:tm,eyehee e6 eee#e $!(6% 9    %9e  %9A $  %6 %II%  6&%j  6jA   6:  6   6 e6E e9^%%  %6e;O 6NEe[  %6 I {  %6N   %6R  3 %6Ye 762e 7;  3 qq &  ;Y Y D 3 11 c  F <F  3 %<    $,- 71:. 1;. 1_ ?" 1@. ) e7B1:1;1_ ?" 1@. ) E71:'1;'1_ ?" 1@. ) 0%71:w1;w1_ ?" 1@. ) S6H  6l e6 s e<71=8>>((>O85|9&:)@ F GIHI JK L$M( N)#P*R+T,fV-]. ^/a0kc1/e2 g3n4^o59|e!?OSeT{ U&eU&eV"eJ:W"eW "X+%'Y3 Y<Y"ZY+FZEP(y[S!&\]^]Ytq_ _ _` a:da2b cccd c ezxf g-4 gYei~h-g g+#ieq!j\e% U: ; I$ > $ >   I : ;  : ; I8 : ;I8  : ; n  : ;  : ; I I!I/  I: ; &I9: ; : ; : ;9: ; .?: ; n<I.?: ; nI<.?: ;nI<.?: ;nI<.?: ;nI< : ; ( < : ;2  : ;I?<!.?: ;2 <d"I4#.?: ;2 <d$: ; I2 % : ;I?2 < & : ;I?2 < ' : ;I?2 <(: ;I2 )/I*/I+ : ; , : ;-9.4: ;I</:: ;0 : ; 1 : ; I?<2/I34: ; nI?<44: ; I<5: ;I6.?: ;I<78.?: ;I<9.?: ; I<: : ; ;.?: ; nI<<9: ; =:: ; > I?.?: ; I<@ : ; nA : ; B I8 CD&E9: ;F : ;G : ;I8 2 H.?: ;n2 <dI.?: ;n2 <dJ : ;I?2 <K.?: ;nI<L4: ;I<M4: ; I<N4: ; I< O.?: ;nI2 <P.?: ;nI2 <dQ.?: ;n<R: ;S.?: ;I T.4 U: ; IV.?: ; I@BW: ; IX1X Y Y1Z.4@B[1X Y \1 ]1^_4: ; I?<`4I?4<a4G b4Gc4Gd4Ge4Gn f4Gng4Gn h4Gni.?nI4<j.?I4<$JP(JPxR src./include/gtest/usr/include/c++/4.9.2/usr/lib/gcc/i686-redhat-linux/4.9.2/include/usr/include/bits/usr/include/usr/include/c++/4.9.2/bits/usr/include/c++/4.9.2/i686-redhat-linux/bits/usr/include/c++/4.9.2/tr1/usr/include/c++/4.9.2/debug/usr/include/c++/4.9.2/ext./include/gtest/internalgtest_main.ccgtest.hiostreamstddef.htypes.hlibio.hstdio.hwchar.hstdarg.hcwcharchar_traits.hc++config.hclocaleios_base.hcwctypetuple iosfwdtime.hdebug.h predefined_ops.hnew_allocator.h numeric_traits.h locale.hpthreadtypes.hatomic_word.hwctype.hgtest-port.h gtest-internal.h gtest-death-test-internal.h gtest-linked_ptr.h gtest-printers.hcxxabi.h!J=n<$<\long int__debugint_p_cs_precedes_ZN7testing8internal21ImplicitlyConvertibleIPKvS3_E5valueEwcsxfrmgoodbit_shortbufvfwprintf_IO_lock_tUnitTeststderrGetInstanceRUN_ALL_TESTStm_ydayLock_ZNSt11char_traitsIcE11to_int_typeERKc_S_atepthread_tchar_type_S_uppercasevfwscanfeofbitp_cs_precedestowctrans_Swallow_assignunsigned int_ZN7testing8internal18g_linked_ptr_mutexE__gnu_cxx_S_fixed_S_floatfieldtuple_size >_flags__int32_t_cur_columnwchar_t_S_refcounttestingvwscanf_old_offset_markerstm_mday_ZNSt11char_traitsIcE2ltERKcS2_MakeFrommon_decimal_point_S_ios_iostate_end_IO_buf_end_ZN9__gnu_cxx24__numeric_traits_integerIiE5__minE__opswcscpy_ZN7testing8UnitTest11GetInstanceEvBiggestInt_ZNSt11char_traitsIcE7not_eofERKiwcscatlconvdecimal_point__numeric_traits_integer__pthread_slist_tAssertHeldn_sep_by_spaceg_linked_ptr_mutexcopy__gnu_debugfwscanftm_wday_poswcsncmpp_sep_by_spacetm_mon_IO_save_end__count__numeric_traits_integerinternal2floatignore__elisiongetwclong long unsigned int_S_endhas_owner__S_dec_S_hexint_n_sign_posn_IO_read_base_S_scientificunitbuflocaleconv__FILE__owneradjustfield_offsetto_int_type_ZNK7testing8internal9MutexBase10AssertHeldEvwcrtomb_ZN7testing8internal9MutexBase6UnlockEviostatevalue_S_ios_seekdir_end_S_failbitfixed__cxa_atexitHelper__gnuc_va_listp_sign_posn__initialize_pputsuppercasetuple<>Initsize_tmovefloatfieldshowposputwccerrputwchar_Ios_Seekdir__priority__lockargcstdin_nextint_frac_digitsfwideint_n_cs_precedes_S_right_S_showpointGNU C++ 4.9.2 20150212 (Red Hat 4.9.2-6) -mtune=generic -march=i686 -g -O2findbasic_ostream >negative_sign__elision_data_ZN7testing14InitGoogleTestEPiPPc__valuefputwc__nextgroupingwscanf_S_showbase_GLOBAL__sub_I_main_S_inchar_modeswscanfptrdiff_t_IO_markerint_type_IO_write_basewctype_S_adjustfield__max__wch_S_boolalpha__builtin_putsmbsrtowcs_S_begwcstoulwctrans_tfwprintfrightpthread_mutex_twcstofwcsspn_ZN9__gnu_cxx24__numeric_traits_integerIsE5__maxE_S_ios_openmode_end_Atomic_word__listlong long intlength_S_eofbit_ZN7testing8internal21ImplicitlyConvertibleIPKvS3_E6HelperEz_IO_save_base_S_oct_S_badbitmon_groupingUnlock_ZNSt11char_traitsIcE6assignERcRKcboolboolalphashowbasefgetwc_ZN7testing8internal21ImplicitlyConvertibleIPKvS3_E6HelperES3_fgetws_S_basefield__quad_tbadbitcomparestdout_IO_backup_base_S_goodbit__dso_handle_ZNSt11char_traitsIcE6assignEPcjc__kindassign__pad1__pad2__pad3__pad4__pad5kInternalRunDeathTestFlag__is_signedungetwcfmtflagssrc/gtest_main.cc_Value_Ios_Iostatewctype_t_vtable_offset_ZSt4cerr_ZN9__gnu_cxx24__numeric_traits_integerIiE5__maxE__mbstate_t_Traitsargvlong doublewcsncatopenmodewcscoll__espins_S_synced_with_stdio_ZNSt11char_traitsIcE4moveEPcPKcjfputws__static_initialization_and_destruction_0/home/user/projects/ascgit/ascgit003.dlt-daemon/build/gtest-1.7.0ios_basebtowcvwprintfFromkMaxStackTraceDepthmbrtowc_IO_read_endiswctypetm_yearmbsinitwmemchr_ZNSt11char_traitsIcE2eqERKcS2_short int_ZN7testing8UnitTest3RunEvmutex__ZNSt11char_traitsIcE3eofEv_CharTwcsrtombsint_curr_symbolkMaxBiggestIntwcstoullfrac_digitsmbrlenwmemcpyscientificn_sign_posn11__mbstate_tchar_traits_S_skipws_Ios_Openmodewcsrchrto_char_typegetwchar__cxxabiv1_IO_write_end_S_internal__wchbint_n_sep_by_space__numeric_traits_integerinternal_run_death_testshowpointbinary_S_binleftmbstate_twcsftimepositive_sign__datawcsstrskipws_ZNSt11char_traitsIcE11eq_int_typeERKiS2_owner__lock_S_left_ZNSt11char_traitsIcE12to_char_typeERKiwmemmove_Ios_Fmtflags__nuserswprintfdeath_test_use_forksizetypelong unsigned int~Init_S_trunc_IO_FILE_ZN7testing8internal21ImplicitlyConvertibleIPKvS3_E8MakeFromEvwint_t_S_appnot_eofwcstodwcspbrktm_minfailbitwcstokwcstoltm_zonewmemset_S_ios_fmtflags_endsetlocale_ZNSt11char_traitsIcE6lengthEPKcunsigned char_sbufMutexBaseinternal_IO_write_ptreq_int_typethousands_sep_ZN9__gnu_cxx24__numeric_traits_integerImE8__digitsE_ZN9__gnu_cxx24__numeric_traits_integerIsE5__minEostreamwcstoldwctob_ZNSt11char_traitsIcE4findEPKcjRS1_death_test_stylecurrency_symbolwcstoll__minswprintf_fileno_ZN9__gnu_cxx24__numeric_traits_integerIcE5__maxE15pthread_mutex_t__size__off_ttm_hourtrunckDeathTestStyleFlagsigned charmon_thousands_sepInitGoogleTestbasefieldshort unsigned int__digitstm_sec_S_unitbufmainwcscspn__builtin_va_list_S_curn_cs_precedestm_isdstseekdir_IO_read_ptrwcsncpy_ZNSt11char_traitsIcE4copyEPcPKcjint_p_sep_by_spacedoublevswscanfwcscmp_ZN7testing8internal9MutexBase4LockEvtm_gmtoff__pthread_internal_slist__align_chainwcschr__numeric_traits_integerkDeathTestUseForkwctransvswprintfkProtobufOneLinerMaxLength_flags2_S_out_ZNSt11char_traitsIcE7compareEPKcS2_jint_p_sign_posn_S_showposImplicitlyConvertiblewcslen__off64_t__ioinit_unused2_IO_buf_base_ZNSt3tr110tuple_sizeINS_5tupleIIEEEE5valueE__pthread_mutex_swmemcmpGCC: (GNU) 4.9.2 20150212 (Red Hat 4.9.2-6)zR| 8JD GuEutu|uxs AAAC $XP(CE HEEE H.symtab.strtab.shstrtab.text.data.bss.rodata.str1.4.text.unlikely.rel.text.startup.rel.init_array.rel.debug_info.debug_abbrev.rel.debug_aranges.rel.debug_ranges.rel.debug_line.debug_str.comment.note.GNU-stack.rel.eh_frame4!4'4,24";VN`xJ BX`\ Cpl C  |g@"( P h" 4P "V TP0%V0,:-Y:\:| \P:@ AP(#   2J7<^gtest_main.cc_GLOBAL__sub_I_main_ZStL8__ioinitmainputs_ZN7testing14InitGoogleTestEPiPPc_ZN7testing8UnitTest11GetInstanceEv_ZN7testing8UnitTest3RunEv_ZNSt8ios_base4InitC1Ev__dso_handle_ZNSt8ios_base4InitD1Ev__cxa_atexit'/8TYafkp !&3:AHOV[ov{ '4AN[hu+9GXco{3Pho6=U\ov %,3:AIQX_fo{+B[g  ' 6 E S a p }                    * 6 = D K P \ g }      7 S i u     ' = ^ z     5Pp-9EQ]iu%Pk&<\|'-ELdk #.9COZep{P\ht(4@LXdp})5AMYex4Nc} ,9@IPcjy&;GNk(1;?Rjoz $.:EO[_r  , \dlt-daemon-2.18.4/gtest-1.7.0/lib/.libs/libgtest_main.la000077700000000000000000000000001353342203500257022../libgtest_main.laustar00rootroot00000000000000dlt-daemon-2.18.4/gtest-1.7.0/lib/.libs/libgtest_main.lai000066400000000000000000000017711353342203500225140ustar00rootroot00000000000000# libgtest_main.la - a libtool library file # Generated by libtool (GNU libtool) 2.4.2 Debian-2.4.2-1ubuntu1 # # Please DO NOT delete this file! # It is necessary for linking the library. # The name that we can dlopen(3). dlname='libgtest_main.so.0' # Names of this library. library_names='libgtest_main.so.0.0.0 libgtest_main.so.0 libgtest_main.so' # The name of the static archive. old_library='libgtest_main.a' # Linker flags that can not go in dependency_libs. inherited_linker_flags=' -pthread' # Libraries that this one depends upon. dependency_libs=' /usr/local/lib/libgtest.la' # Names of additional weak libraries provided by this library weak_library_names='' # Version information for libgtest_main. current=0 age=0 revision=0 # Is this an already installed library? installed=yes # Should we warn about portability when linking against -modules? shouldnotlink=no # Files to dlopen/dlpreopen dlopen='' dlpreopen='' # Directory that this library needs to be installed in: libdir='/usr/local/lib' dlt-daemon-2.18.4/gtest-1.7.0/lib/.libs/libgtest_main.so000077700000000000000000000000001353342203500261732libgtest_main.so.0.0.0ustar00rootroot00000000000000dlt-daemon-2.18.4/gtest-1.7.0/lib/.libs/libgtest_main.so.0000077700000000000000000000000001353342203500263312libgtest_main.so.0.0.0ustar00rootroot00000000000000dlt-daemon-2.18.4/gtest-1.7.0/lib/.libs/libgtest_main.so.0.0.0000077500000000000000000000524111353342203500230220ustar00rootroot00000000000000ELFp4H4 ("\ \ hl$$Ptd|||$$QtdRtd<<GNU\iK urf!  @) |CEqXj| a  8 zR"o0 \, c, upY  D __gmon_start___init_fini_ITM_deregisterTMCloneTable_ITM_registerTMCloneTable__cxa_finalize_Jv_RegisterClassesmainputs_ZN7testing14InitGoogleTestEPiPPc_ZN7testing8UnitTest11GetInstanceEv_ZN7testing8UnitTest3RunEv_ZNSt8ios_base4InitC1Ev_ZNSt8ios_base4InitD1Ev__cxa_atexitlibgtest.so.0libstdc++.so.6libm.so.6libc.so.6libgcc_s.so.1_edata__bss_start_endlibgtest_main.so.0/home/user/projects/ascgit/ascgit003.dlt-daemon/build/gtest-1.7.0/lib/.libs:/usr/local/libGLIBCXX_3.4GLIBC_2.0GLIBC_2.1.3+ t)Dii si        $  (  SWGtB[ hhhhh h($h0(h8pL$qUWVSQxyXPXZWVO PeY[^_]aÍ&VS9)-V4 PV[^ffff$ffffffUS,/)Ѝd$vt$Ѝd$[]Ít&US×,,)Ѝd$tt D$$эd$[]Í&USWGd$쀻,u$t$|7ƃ,d$[]É'USd$썃ud$[]6t$Só[Running main() from gtest_main.cc; d<`TzR|   F J tx?;*2$"@@YD GuFupu|uxut@ AAAAC 48AA NG NAAF H AA+:DNt  Do8t   @p Poooo&6FVfGCC: (GNU) 4.9.2 20150212 (Red Hat 4.9.2-6)$pY8u H 0 (eint7ll z( @ 8e  5/   < b$ /( [, 0  4  e8 2e< @ >D LF hG  H %L .T /X 0\ 1` 2%d 4eh 6l@ S  Vn YX0  \hTe]O  ^C (|* Ge  !''std"  @[  O  f  |        6  R  h  t      &  <  ]  y       4 O o          $ O j      % ; [ { ɛ ʻ    & D c   0   0 e (17eq ' J77lt ' g77  Ae==  = ==7  CC=. +CC= WC5C  OI- n7= $ ' IIeof (8  ,I 0 5O 6| 7  e 3n_Z  pYbw D c  g n :7 ?w) [ 2 Z  ' !2 ;A"#1 N""e$%btZ&dect%]t&hex t% t% t &octt@%\t't' "t'e&t'z)t' ,t'/t '3t@%G6t% 9tJ'f<t(J%zN o %Q %V %BY (u in&appl  &ateo %g t &inw &outz %: }  (&beg9  &cur9 &end9 RSTO \e3hMib )T *T tr1* +,- . / 0q1. 2_Tp  3 > 4J' ef  a 5 a0 j6 O | e6O  86  e 3 6O 3  6  e    3 6AKe  e6sRe6   76{eR   76O h  8 O 6 % !% [ 6 m%  !% 6 ie   [ 6{%   % !6O & 3  6O < 3 6\e]  % 76aey   76O O  6rde   6e   6 qe  % 6`e  6 le4 6eO 6gr%o3  9   9ie  9~ e  9   9%  6u W% % !:tm,e etee Te e?eee $ !(6% 9m    %9Le  %9# $  %6[ %II%  6%j  6 A   6:  6    6  e6E e9`%%  %6e;O 6!Ee[  %6 I {  %6 N   %6 R  3 %6tYe 76e 7;  3   &  ;  D 3   c   <  3 %>((>O85|9:@e F GHIJ~ K L$1M(5N)sP*QR+KT," V-k].^/oa0Mc1Ge2 g3gn4o59 |e!?OSeT U&eU&eV"epY:W&"eW\ "X%'Y YYHYFZ8y["&\]^Y__+_(_`Ja:da2b cccd - c eHe" e-IeY!e~ee e+%flve_!ge% U: ; I$ > $ >   I : ;  : ; I8 : ;I8  : ; n  : ;  : ; I I!I/  I: ; &I9: ; : ; : ;9: ; .?: ; n<I.?: ; nI<.?: ;nI<.?: ;nI<.?: ;nI< : ; ( < : ;2  : ;I?<!.?: ;2 <d"I4#.?: ;2 <d$: ; I2 % : ;I?2 < & : ;I?2 < ' : ;I?2 <(: ;I2 )/I*/I+ : ; , : ;-9.4: ;I</:: ;0 : ; 1 : ; I?<2/I34: ; nI?<44: ; I<5: ;I6.?: ;I<78.?: ;I<9.?: ; I<: : ; ;.?: ; nI<<9: ; =:: ; > I?.?: ; I<@ : ; nA : ; B I8 CD&E9: ;F : ;G : ;I8 2 H.?: ;n2 <dI.?: ;n2 <dJ : ;I?2 <K.?: ;nI<L4: ;I<M4: ; I<N4: ; I< O.?: ;nI2 <P.?: ;nI2 <dQ.?: ;n<R: ;S.?: ;I T.4 U: ; IV.?: ; I@BW: ; IX1X Y Y1Z.4@B[1X Y \1 ]1^_4: ; I?<`4I?4<a4G b4Gc4Gd4Ge4Gnf.?nI4<g.?I4<S src./include/gtest/usr/include/c++/4.9.2/usr/lib/gcc/i686-redhat-linux/4.9.2/include/usr/include/bits/usr/include/usr/include/c++/4.9.2/bits/usr/include/c++/4.9.2/i686-redhat-linux/bits/usr/include/c++/4.9.2/tr1/usr/include/c++/4.9.2/debug/usr/include/c++/4.9.2/ext./include/gtest/internalgtest_main.ccgtest.hiostreamstddef.htypes.hlibio.hstdio.hwchar.hstdarg.hcwcharchar_traits.hc++config.hclocaleios_base.hcwctypetuple iosfwdtime.hdebug.h predefined_ops.hnew_allocator.h numeric_traits.h locale.hpthreadtypes.hatomic_word.hwctype.hgtest-port.h gtest-internal.h gtest-death-test-internal.h gtest-linked_ptr.h gtest-printers.hcxxabi.hp!=n<.$\"__debug_GLOBAL__sub_I_gtest_main.cc_ZN7testing8internal21ImplicitlyConvertibleIPKvS3_E5valueEwcsxfrm_shortbufvfwprintf_IO_lock_tUnitTeststderrGetInstanceRUN_ALL_TESTStm_ydayLock_ZNSt11char_traitsIcE11to_int_typeERKc_S_atepthread_t_S_uppercasevfwscanftowctrans_Swallow_assign_ZN7testing8internal18g_linked_ptr_mutexE__gnu_cxx_S_fixed_S_floatfieldtuple_size >_flags__int32_t_cur_columnwchar_t_S_refcounttestingvwscanf_old_offset_markerstm_mday_ZNSt11char_traitsIcE2ltERKcS2_MakeFrommon_decimal_point_S_ios_iostate_end_IO_buf_end_ZN9__gnu_cxx24__numeric_traits_integerIiE5__minE__opswcscpy_ZN7testing8UnitTest11GetInstanceEv_ZNSt11char_traitsIcE7not_eofERKiwcscatlconv__numeric_traits_integer__pthread_slist_tAssertHeldg_linked_ptr_mutexcopy__gnu_debugtm_wday_poswcsncmptm_mon_IO_save_end__count__numeric_traits_integerinternal2floatignore__elisionlong long unsigned int_S_endhas_owner__S_dec_S_hexint_n_sign_posn_IO_read_base_S_scientificlocaleconv__FILE__ownerto_int_type_ZNK7testing8internal9MutexBase10AssertHeldEvwcrtomb_ZN7testing8internal9MutexBase6UnlockEviostate_S_ios_seekdir_end_S_failbit__cxa_atexitHelper__gnuc_va_list__initialize_ptuple<>size_tputwchar_Ios_Seekdir__priority__lockargcstdinint_frac_digitsfwideint_n_cs_precedes_S_right_S_showpointint_p_cs_precedesfindbasic_ostream >negative_sign__elision_data_ZN7testing14InitGoogleTestEPiPPc__valuefputwc__next_S_showbase_S_in_modeptrdiff_t_IO_marker_IO_write_base_S_adjustfield__max__wch_S_boolalpha__builtin_putsmbsrtowcs_S_begwcstoulwctrans_twcstofwcsspn_ZN9__gnu_cxx24__numeric_traits_integerIsE5__maxE_S_ios_openmode_end_Atomic_word__listlong long intlength_S_eofbit_ZN7testing8internal21ImplicitlyConvertibleIPKvS3_E6HelperEz_IO_save_base_S_oct_S_badbitmon_groupingUnlock_ZNSt11char_traitsIcE6assignERcRKcboolfgetwc_ZN7testing8internal21ImplicitlyConvertibleIPKvS3_E6HelperES3_fgetws_S_basefield__quad_tcomparestdout_IO_backup_base_S_goodbit__dso_handle_ZNSt11char_traitsIcE6assignEPcjc__kind__pad1__pad2__pad3__pad4__pad5kInternalRunDeathTestFlag__is_signedungetwcfmtflagssrc/gtest_main.cc_Value_Ios_Iostatewctype_t_vtable_offset_ZSt4cerr_ZN9__gnu_cxx24__numeric_traits_integerIiE5__maxE_Traitsargvlong doublewcsncatopenmodewcscoll__espins_S_synced_with_stdio_ZNSt11char_traitsIcE4moveEPcPKcjfputws__static_initialization_and_destruction_0GNU C++ 4.9.2 20150212 (Red Hat 4.9.2-6) -mtune=generic -march=i686 -g -O2 -fPIC/home/user/projects/ascgit/ascgit003.dlt-daemon/build/gtest-1.7.0ios_basebtowcvwprintfkMaxStackTraceDepthmbrtowc_IO_read_endiswctypetm_yearmbsinitwmemchr_ZNSt11char_traitsIcE2eqERKcS2_short int_ZN7testing8UnitTest3RunEvmutex__ZNSt11char_traitsIcE3eofEv_CharTwcsrtombsint_curr_symbolkMaxBiggestIntwcstoullmbrlenwmemcpy11__mbstate_tchar_traits_S_skipws_Ios_Openmodewcsrchrto_char_typegetwchar__cxxabiv1_IO_write_end_S_internal__wchbint_n_sep_by_space__numeric_traits_integerinternal_run_death_testbinary_S_binwcsftimepositive_sign__datawcsstr_ZNSt11char_traitsIcE11eq_int_typeERKiS2__S_left_ZNSt11char_traitsIcE12to_char_typeERKiwmemmove_Ios_Fmtflags__nusersdeath_test_use_forksizetype~Init_S_trunc_IO_FILE_ZN7testing8internal21ImplicitlyConvertibleIPKvS3_E8MakeFromEvwint_t_S_appnot_eofwcstodwcspbrktm_minwcstokwcstoltm_zonewmemset_S_ios_fmtflags_endsetlocale_ZNSt11char_traitsIcE6lengthEPKcunsigned char_sbufMutexBase_IO_write_ptreq_int_type_ZN9__gnu_cxx24__numeric_traits_integerImE8__digitsE_ZN9__gnu_cxx24__numeric_traits_integerIsE5__minEostreamwcstoldwctob_ZNSt11char_traitsIcE4findEPKcjRS1_death_test_stylecurrency_symbolwcstoll__min_fileno_ZN9__gnu_cxx24__numeric_traits_integerIcE5__maxE15pthread_mutex_t__size__off_ttm_hourkDeathTestStyleFlagmon_thousands_sepInitGoogleTestshort unsigned int__digitstm_sec_S_unitbufmainwcscspn__builtin_va_list_S_curtm_isdstseekdir_IO_read_ptrwcsncpy_ZNSt11char_traitsIcE4copyEPcPKcjint_p_sep_by_spacevswscanfwcscmp_ZN7testing8internal9MutexBase4LockEvtm_gmtoff__pthread_internal_slist__align_chainwcschr__numeric_traits_integerkDeathTestUseForkvswprintfkProtobufOneLinerMaxLength_flags2_S_out_ZNSt11char_traitsIcE7compareEPKcS2_jint_p_sign_posn_S_showposImplicitlyConvertiblewcslen__off64_t__ioinit_unused2_IO_buf_base_ZNSt3tr110tuple_sizeINS_5tupleIIEEEE5valueE__pthread_mutex_swmemcmpp.symtab.strtab.shstrtab.note.gnu.build-id.gnu.hash.dynsym.dynstr.gnu.version.gnu.version_r.rel.dyn.rel.plt.init.text.fini.rodata.eh_frame_hdr.eh_frame.init_array.fini_array.jcr.data.rel.ro.dynamic.got.got.plt.bss.comment.debug_aranges.debug_info.debug_abbrev.debug_line.debug_str.debug_ranges$.o88<8 tt0@Ho&UoPd   Pm pp@ v#q|ppDD2XX$||$ ,, ,0,,X(y+ 1W,05)7/GGGEM`!4  \$output_objdir/\$libname.ver~ cat \$export_symbols | sed -e \\\"s/\\\\(.*\\\\)/\\\\1;/\\\" >> \$output_objdir/\$libname.ver~ echo \\\"local: *; };\\\" >> \$output_objdir/\$libname.ver~ \$CC -shared \$pic_flag \$libobjs \$deplibs \$compiler_flags \${wl}-soname \$wl\$soname \${wl}-version-script \${wl}\$output_objdir/\$libname.ver -o \$lib" # Commands used to build a loadable module if different from building # a shared archive. module_cmds="" module_expsym_cmds="" # Whether we are building with GNU ld or not. with_gnu_ld="yes" # Flag that allows shared libraries with undefined symbols to be built. allow_undefined_flag="" # Flag that enforces no undefined symbols. no_undefined_flag="" # Flag to hardcode $libdir into a binary during linking. # This must work even if $libdir does not exist hardcode_libdir_flag_spec="\${wl}-rpath \${wl}\$libdir" # Whether we need a single "-rpath" flag with a separated argument. hardcode_libdir_separator="" # Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes # DIR into the resulting binary. hardcode_direct=no # Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes # DIR into the resulting binary and the resulting library dependency is # "absolute",i.e impossible to change by setting ${shlibpath_var} if the # library is relocated. hardcode_direct_absolute=no # Set to "yes" if using the -LDIR flag during linking hardcodes DIR # into the resulting binary. hardcode_minus_L=no # Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR # into the resulting binary. hardcode_shlibpath_var=unsupported # Set to "yes" if building a shared library automatically hardcodes DIR # into the library and all subsequent libraries and executables linked # against it. hardcode_automatic=no # Set to yes if linker adds runtime paths of dependent libraries # to runtime path list. inherit_rpath=no # Whether libtool must link a program against all its dependency libraries. link_all_deplibs=no # Set to "yes" if exported symbols are required. always_export_symbols=no # The commands to list exported symbols. export_symbols_cmds="\$NM \$libobjs \$convenience | \$global_symbol_pipe | \$SED 's/.* //' | sort | uniq > \$export_symbols" # Symbols that should not be listed in the preloaded symbols. exclude_expsyms="_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*" # Symbols that must always be exported. include_expsyms="" # Commands necessary for linking programs (against libraries) with templates. prelink_cmds="" # Commands necessary for finishing linking programs. postlink_cmds="" # Specify filename containing input files. file_list_spec="" # How to hardcode a shared library path into an executable. hardcode_action=immediate # The directories searched by this compiler when creating a shared library. compiler_lib_search_dirs="" # Dependencies to place before and after the objects being linked to # create a shared library. predep_objects="" postdep_objects="" predeps="" postdeps="" # The library search path used internally by the compiler when linking # a shared library. compiler_lib_search_path="" # ### END LIBTOOL CONFIG # libtool (GNU libtool) 2.4.2 # Written by Gordon Matzigkeit , 1996 # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006, # 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. # This is free software; see the source for copying conditions. There is NO # warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # GNU Libtool is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # As a special exception to the GNU General Public License, # if you distribute this file as part of a program or library that # is built using GNU Libtool, you may include this file under the # same distribution terms that you use for the rest of that program. # # GNU Libtool is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with GNU Libtool; see the file COPYING. If not, a copy # can be downloaded from http://www.gnu.org/licenses/gpl.html, # or obtained by writing to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # Usage: $progname [OPTION]... [MODE-ARG]... # # Provide generalized library-building support services. # # --config show all configuration variables # --debug enable verbose shell tracing # -n, --dry-run display commands without modifying any files # --features display basic configuration information and exit # --mode=MODE use operation mode MODE # --preserve-dup-deps don't remove duplicate dependency libraries # --quiet, --silent don't print informational messages # --no-quiet, --no-silent # print informational messages (default) # --no-warn don't display warning messages # --tag=TAG use configuration variables from tag TAG # -v, --verbose print more informational messages than default # --no-verbose don't print the extra informational messages # --version print version information # -h, --help, --help-all print short, long, or detailed help message # # MODE must be one of the following: # # clean remove files from the build directory # compile compile a source file into a libtool object # execute automatically set library path, then run a program # finish complete the installation of libtool libraries # install install libraries or executables # link create a library or an executable # uninstall remove libraries from an installed directory # # MODE-ARGS vary depending on the MODE. When passed as first option, # `--mode=MODE' may be abbreviated as `MODE' or a unique abbreviation of that. # Try `$progname --help --mode=MODE' for a more detailed description of MODE. # # When reporting a bug, please describe a test case to reproduce it and # include the following information: # # host-triplet: $host # shell: $SHELL # compiler: $LTCC # compiler flags: $LTCFLAGS # linker: $LD (gnu? $with_gnu_ld) # $progname: (GNU libtool) 2.4.2 Debian-2.4.2-1ubuntu1 # automake: $automake_version # autoconf: $autoconf_version # # Report bugs to . # GNU libtool home page: . # General help using GNU software: . PROGRAM=libtool PACKAGE=libtool VERSION="2.4.2 Debian-2.4.2-1ubuntu1" TIMESTAMP="" package_revision=1.3337 # Be Bourne compatible if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac fi BIN_SH=xpg4; export BIN_SH # for Tru64 DUALCASE=1; export DUALCASE # for MKS sh # A function that is used when there is no print builtin or printf. func_fallback_echo () { eval 'cat <<_LTECHO_EOF $1 _LTECHO_EOF' } # NLS nuisances: We save the old values to restore during execute mode. lt_user_locale= lt_safe_locale= for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES do eval "if test \"\${$lt_var+set}\" = set; then save_$lt_var=\$$lt_var $lt_var=C export $lt_var lt_user_locale=\"$lt_var=\\\$save_\$lt_var; \$lt_user_locale\" lt_safe_locale=\"$lt_var=C; \$lt_safe_locale\" fi" done LC_ALL=C LANGUAGE=C export LANGUAGE LC_ALL $lt_unset CDPATH # Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh # is ksh but when the shell is invoked as "sh" and the current value of # the _XPG environment variable is not equal to 1 (one), the special # positional parameter $0, within a function call, is the name of the # function. progpath="$0" : ${CP="cp -f"} test "${ECHO+set}" = set || ECHO=${as_echo-'printf %s\n'} : ${MAKE="make"} : ${MKDIR="mkdir"} : ${MV="mv -f"} : ${RM="rm -f"} : ${SHELL="${CONFIG_SHELL-/bin/sh}"} : ${Xsed="$SED -e 1s/^X//"} # Global variables: EXIT_SUCCESS=0 EXIT_FAILURE=1 EXIT_MISMATCH=63 # $? = 63 is used to indicate version mismatch to missing. EXIT_SKIP=77 # $? = 77 is used to indicate a skipped test to automake. exit_status=$EXIT_SUCCESS # Make sure IFS has a sensible default lt_nl=' ' IFS=" $lt_nl" dirname="s,/[^/]*$,," basename="s,^.*/,," # func_dirname file append nondir_replacement # Compute the dirname of FILE. If nonempty, add APPEND to the result, # otherwise set result to NONDIR_REPLACEMENT. func_dirname () { case ${1} in */*) func_dirname_result="${1%/*}${2}" ;; * ) func_dirname_result="${3}" ;; esac } # Extended-shell func_dirname implementation # func_basename file func_basename () { func_basename_result="${1##*/}" } # Extended-shell func_basename implementation # func_dirname_and_basename file append nondir_replacement # perform func_basename and func_dirname in a single function # call: # dirname: Compute the dirname of FILE. If nonempty, # add APPEND to the result, otherwise set result # to NONDIR_REPLACEMENT. # value returned in "$func_dirname_result" # basename: Compute filename of FILE. # value retuned in "$func_basename_result" # Implementation must be kept synchronized with func_dirname # and func_basename. For efficiency, we do not delegate to # those functions but instead duplicate the functionality here. func_dirname_and_basename () { case ${1} in */*) func_dirname_result="${1%/*}${2}" ;; * ) func_dirname_result="${3}" ;; esac func_basename_result="${1##*/}" } # Extended-shell func_dirname_and_basename implementation # func_stripname prefix suffix name # strip PREFIX and SUFFIX off of NAME. # PREFIX and SUFFIX must not contain globbing or regex special # characters, hashes, percent signs, but SUFFIX may contain a leading # dot (in which case that matches only a dot). # func_strip_suffix prefix name func_stripname () { # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are # positional parameters, so assign one to ordinary parameter first. func_stripname_result=${3} func_stripname_result=${func_stripname_result#"${1}"} func_stripname_result=${func_stripname_result%"${2}"} } # Extended-shell func_stripname implementation # These SED scripts presuppose an absolute path with a trailing slash. pathcar='s,^/\([^/]*\).*$,\1,' pathcdr='s,^/[^/]*,,' removedotparts=':dotsl s@/\./@/@g t dotsl s,/\.$,/,' collapseslashes='s@/\{1,\}@/@g' finalslash='s,/*$,/,' # func_normal_abspath PATH # Remove doubled-up and trailing slashes, "." path components, # and cancel out any ".." path components in PATH after making # it an absolute path. # value returned in "$func_normal_abspath_result" func_normal_abspath () { # Start from root dir and reassemble the path. func_normal_abspath_result= func_normal_abspath_tpath=$1 func_normal_abspath_altnamespace= case $func_normal_abspath_tpath in "") # Empty path, that just means $cwd. func_stripname '' '/' "`pwd`" func_normal_abspath_result=$func_stripname_result return ;; # The next three entries are used to spot a run of precisely # two leading slashes without using negated character classes; # we take advantage of case's first-match behaviour. ///*) # Unusual form of absolute path, do nothing. ;; //*) # Not necessarily an ordinary path; POSIX reserves leading '//' # and for example Cygwin uses it to access remote file shares # over CIFS/SMB, so we conserve a leading double slash if found. func_normal_abspath_altnamespace=/ ;; /*) # Absolute path, do nothing. ;; *) # Relative path, prepend $cwd. func_normal_abspath_tpath=`pwd`/$func_normal_abspath_tpath ;; esac # Cancel out all the simple stuff to save iterations. We also want # the path to end with a slash for ease of parsing, so make sure # there is one (and only one) here. func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ -e "$removedotparts" -e "$collapseslashes" -e "$finalslash"` while :; do # Processed it all yet? if test "$func_normal_abspath_tpath" = / ; then # If we ascended to the root using ".." the result may be empty now. if test -z "$func_normal_abspath_result" ; then func_normal_abspath_result=/ fi break fi func_normal_abspath_tcomponent=`$ECHO "$func_normal_abspath_tpath" | $SED \ -e "$pathcar"` func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ -e "$pathcdr"` # Figure out what to do with it case $func_normal_abspath_tcomponent in "") # Trailing empty path component, ignore it. ;; ..) # Parent dir; strip last assembled component from result. func_dirname "$func_normal_abspath_result" func_normal_abspath_result=$func_dirname_result ;; *) # Actual path component, append it. func_normal_abspath_result=$func_normal_abspath_result/$func_normal_abspath_tcomponent ;; esac done # Restore leading double-slash if one was found on entry. func_normal_abspath_result=$func_normal_abspath_altnamespace$func_normal_abspath_result } # func_relative_path SRCDIR DSTDIR # generates a relative path from SRCDIR to DSTDIR, with a trailing # slash if non-empty, suitable for immediately appending a filename # without needing to append a separator. # value returned in "$func_relative_path_result" func_relative_path () { func_relative_path_result= func_normal_abspath "$1" func_relative_path_tlibdir=$func_normal_abspath_result func_normal_abspath "$2" func_relative_path_tbindir=$func_normal_abspath_result # Ascend the tree starting from libdir while :; do # check if we have found a prefix of bindir case $func_relative_path_tbindir in $func_relative_path_tlibdir) # found an exact match func_relative_path_tcancelled= break ;; $func_relative_path_tlibdir*) # found a matching prefix func_stripname "$func_relative_path_tlibdir" '' "$func_relative_path_tbindir" func_relative_path_tcancelled=$func_stripname_result if test -z "$func_relative_path_result"; then func_relative_path_result=. fi break ;; *) func_dirname $func_relative_path_tlibdir func_relative_path_tlibdir=${func_dirname_result} if test "x$func_relative_path_tlibdir" = x ; then # Have to descend all the way to the root! func_relative_path_result=../$func_relative_path_result func_relative_path_tcancelled=$func_relative_path_tbindir break fi func_relative_path_result=../$func_relative_path_result ;; esac done # Now calculate path; take care to avoid doubling-up slashes. func_stripname '' '/' "$func_relative_path_result" func_relative_path_result=$func_stripname_result func_stripname '/' '/' "$func_relative_path_tcancelled" if test "x$func_stripname_result" != x ; then func_relative_path_result=${func_relative_path_result}/${func_stripname_result} fi # Normalisation. If bindir is libdir, return empty string, # else relative path ending with a slash; either way, target # file name can be directly appended. if test ! -z "$func_relative_path_result"; then func_stripname './' '' "$func_relative_path_result/" func_relative_path_result=$func_stripname_result fi } # The name of this program: func_dirname_and_basename "$progpath" progname=$func_basename_result # Make sure we have an absolute path for reexecution: case $progpath in [\\/]*|[A-Za-z]:\\*) ;; *[\\/]*) progdir=$func_dirname_result progdir=`cd "$progdir" && pwd` progpath="$progdir/$progname" ;; *) save_IFS="$IFS" IFS=${PATH_SEPARATOR-:} for progdir in $PATH; do IFS="$save_IFS" test -x "$progdir/$progname" && break done IFS="$save_IFS" test -n "$progdir" || progdir=`pwd` progpath="$progdir/$progname" ;; esac # Sed substitution that helps us do robust quoting. It backslashifies # metacharacters that are still active within double-quoted strings. Xsed="${SED}"' -e 1s/^X//' sed_quote_subst='s/\([`"$\\]\)/\\\1/g' # Same as above, but do not quote variable references. double_quote_subst='s/\(["`\\]\)/\\\1/g' # Sed substitution that turns a string into a regex matching for the # string literally. sed_make_literal_regex='s,[].[^$\\*\/],\\&,g' # Sed substitution that converts a w32 file name or path # which contains forward slashes, into one that contains # (escaped) backslashes. A very naive implementation. lt_sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g' # Re-`\' parameter expansions in output of double_quote_subst that were # `\'-ed in input to the same. If an odd number of `\' preceded a '$' # in input to double_quote_subst, that '$' was protected from expansion. # Since each input `\' is now two `\'s, look for any number of runs of # four `\'s followed by two `\'s and then a '$'. `\' that '$'. bs='\\' bs2='\\\\' bs4='\\\\\\\\' dollar='\$' sed_double_backslash="\ s/$bs4/&\\ /g s/^$bs2$dollar/$bs&/ s/\\([^$bs]\\)$bs2$dollar/\\1$bs2$bs$dollar/g s/\n//g" # Standard options: opt_dry_run=false opt_help=false opt_quiet=false opt_verbose=false opt_warning=: # func_echo arg... # Echo program name prefixed message, along with the current mode # name if it has been set yet. func_echo () { $ECHO "$progname: ${opt_mode+$opt_mode: }$*" } # func_verbose arg... # Echo program name prefixed message in verbose mode only. func_verbose () { $opt_verbose && func_echo ${1+"$@"} # A bug in bash halts the script if the last line of a function # fails when set -e is in force, so we need another command to # work around that: : } # func_echo_all arg... # Invoke $ECHO with all args, space-separated. func_echo_all () { $ECHO "$*" } # func_error arg... # Echo program name prefixed message to standard error. func_error () { $ECHO "$progname: ${opt_mode+$opt_mode: }"${1+"$@"} 1>&2 } # func_warning arg... # Echo program name prefixed warning message to standard error. func_warning () { $opt_warning && $ECHO "$progname: ${opt_mode+$opt_mode: }warning: "${1+"$@"} 1>&2 # bash bug again: : } # func_fatal_error arg... # Echo program name prefixed message to standard error, and exit. func_fatal_error () { func_error ${1+"$@"} exit $EXIT_FAILURE } # func_fatal_help arg... # Echo program name prefixed message to standard error, followed by # a help hint, and exit. func_fatal_help () { func_error ${1+"$@"} func_fatal_error "$help" } help="Try \`$progname --help' for more information." ## default # func_grep expression filename # Check whether EXPRESSION matches any line of FILENAME, without output. func_grep () { $GREP "$1" "$2" >/dev/null 2>&1 } # func_mkdir_p directory-path # Make sure the entire path to DIRECTORY-PATH is available. func_mkdir_p () { my_directory_path="$1" my_dir_list= if test -n "$my_directory_path" && test "$opt_dry_run" != ":"; then # Protect directory names starting with `-' case $my_directory_path in -*) my_directory_path="./$my_directory_path" ;; esac # While some portion of DIR does not yet exist... while test ! -d "$my_directory_path"; do # ...make a list in topmost first order. Use a colon delimited # list incase some portion of path contains whitespace. my_dir_list="$my_directory_path:$my_dir_list" # If the last portion added has no slash in it, the list is done case $my_directory_path in */*) ;; *) break ;; esac # ...otherwise throw away the child directory and loop my_directory_path=`$ECHO "$my_directory_path" | $SED -e "$dirname"` done my_dir_list=`$ECHO "$my_dir_list" | $SED 's,:*$,,'` save_mkdir_p_IFS="$IFS"; IFS=':' for my_dir in $my_dir_list; do IFS="$save_mkdir_p_IFS" # mkdir can fail with a `File exist' error if two processes # try to create one of the directories concurrently. Don't # stop in that case! $MKDIR "$my_dir" 2>/dev/null || : done IFS="$save_mkdir_p_IFS" # Bail out if we (or some other process) failed to create a directory. test -d "$my_directory_path" || \ func_fatal_error "Failed to create \`$1'" fi } # func_mktempdir [string] # Make a temporary directory that won't clash with other running # libtool processes, and avoids race conditions if possible. If # given, STRING is the basename for that directory. func_mktempdir () { my_template="${TMPDIR-/tmp}/${1-$progname}" if test "$opt_dry_run" = ":"; then # Return a directory name, but don't create it in dry-run mode my_tmpdir="${my_template}-$$" else # If mktemp works, use that first and foremost my_tmpdir=`mktemp -d "${my_template}-XXXXXXXX" 2>/dev/null` if test ! -d "$my_tmpdir"; then # Failing that, at least try and use $RANDOM to avoid a race my_tmpdir="${my_template}-${RANDOM-0}$$" save_mktempdir_umask=`umask` umask 0077 $MKDIR "$my_tmpdir" umask $save_mktempdir_umask fi # If we're not in dry-run mode, bomb out on failure test -d "$my_tmpdir" || \ func_fatal_error "cannot create temporary directory \`$my_tmpdir'" fi $ECHO "$my_tmpdir" } # func_quote_for_eval arg # Aesthetically quote ARG to be evaled later. # This function returns two values: FUNC_QUOTE_FOR_EVAL_RESULT # is double-quoted, suitable for a subsequent eval, whereas # FUNC_QUOTE_FOR_EVAL_UNQUOTED_RESULT has merely all characters # which are still active within double quotes backslashified. func_quote_for_eval () { case $1 in *[\\\`\"\$]*) func_quote_for_eval_unquoted_result=`$ECHO "$1" | $SED "$sed_quote_subst"` ;; *) func_quote_for_eval_unquoted_result="$1" ;; esac case $func_quote_for_eval_unquoted_result in # Double-quote args containing shell metacharacters to delay # word splitting, command substitution and and variable # expansion for a subsequent eval. # Many Bourne shells cannot handle close brackets correctly # in scan sets, so we specify it separately. *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") func_quote_for_eval_result="\"$func_quote_for_eval_unquoted_result\"" ;; *) func_quote_for_eval_result="$func_quote_for_eval_unquoted_result" esac } # func_quote_for_expand arg # Aesthetically quote ARG to be evaled later; same as above, # but do not quote variable references. func_quote_for_expand () { case $1 in *[\\\`\"]*) my_arg=`$ECHO "$1" | $SED \ -e "$double_quote_subst" -e "$sed_double_backslash"` ;; *) my_arg="$1" ;; esac case $my_arg in # Double-quote args containing shell metacharacters to delay # word splitting and command substitution for a subsequent eval. # Many Bourne shells cannot handle close brackets correctly # in scan sets, so we specify it separately. *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") my_arg="\"$my_arg\"" ;; esac func_quote_for_expand_result="$my_arg" } # func_show_eval cmd [fail_exp] # Unless opt_silent is true, then output CMD. Then, if opt_dryrun is # not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP # is given, then evaluate it. func_show_eval () { my_cmd="$1" my_fail_exp="${2-:}" ${opt_silent-false} || { func_quote_for_expand "$my_cmd" eval "func_echo $func_quote_for_expand_result" } if ${opt_dry_run-false}; then :; else eval "$my_cmd" my_status=$? if test "$my_status" -eq 0; then :; else eval "(exit $my_status); $my_fail_exp" fi fi } # func_show_eval_locale cmd [fail_exp] # Unless opt_silent is true, then output CMD. Then, if opt_dryrun is # not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP # is given, then evaluate it. Use the saved locale for evaluation. func_show_eval_locale () { my_cmd="$1" my_fail_exp="${2-:}" ${opt_silent-false} || { func_quote_for_expand "$my_cmd" eval "func_echo $func_quote_for_expand_result" } if ${opt_dry_run-false}; then :; else eval "$lt_user_locale $my_cmd" my_status=$? eval "$lt_safe_locale" if test "$my_status" -eq 0; then :; else eval "(exit $my_status); $my_fail_exp" fi fi } # func_tr_sh # Turn $1 into a string suitable for a shell variable name. # Result is stored in $func_tr_sh_result. All characters # not in the set a-zA-Z0-9_ are replaced with '_'. Further, # if $1 begins with a digit, a '_' is prepended as well. func_tr_sh () { case $1 in [0-9]* | *[!a-zA-Z0-9_]*) func_tr_sh_result=`$ECHO "$1" | $SED 's/^\([0-9]\)/_\1/; s/[^a-zA-Z0-9_]/_/g'` ;; * ) func_tr_sh_result=$1 ;; esac } # func_version # Echo version message to standard output and exit. func_version () { $opt_debug $SED -n '/(C)/!b go :more /\./!{ N s/\n# / / b more } :go /^# '$PROGRAM' (GNU /,/# warranty; / { s/^# // s/^# *$// s/\((C)\)[ 0-9,-]*\( [1-9][0-9]*\)/\1\2/ p }' < "$progpath" exit $? } # func_usage # Echo short help message to standard output and exit. func_usage () { $opt_debug $SED -n '/^# Usage:/,/^# *.*--help/ { s/^# // s/^# *$// s/\$progname/'$progname'/ p }' < "$progpath" echo $ECHO "run \`$progname --help | more' for full usage" exit $? } # func_help [NOEXIT] # Echo long help message to standard output and exit, # unless 'noexit' is passed as argument. func_help () { $opt_debug $SED -n '/^# Usage:/,/# Report bugs to/ { :print s/^# // s/^# *$// s*\$progname*'$progname'* s*\$host*'"$host"'* s*\$SHELL*'"$SHELL"'* s*\$LTCC*'"$LTCC"'* s*\$LTCFLAGS*'"$LTCFLAGS"'* s*\$LD*'"$LD"'* s/\$with_gnu_ld/'"$with_gnu_ld"'/ s/\$automake_version/'"`(${AUTOMAKE-automake} --version) 2>/dev/null |$SED 1q`"'/ s/\$autoconf_version/'"`(${AUTOCONF-autoconf} --version) 2>/dev/null |$SED 1q`"'/ p d } /^# .* home page:/b print /^# General help using/b print ' < "$progpath" ret=$? if test -z "$1"; then exit $ret fi } # func_missing_arg argname # Echo program name prefixed message to standard error and set global # exit_cmd. func_missing_arg () { $opt_debug func_error "missing argument for $1." exit_cmd=exit } # func_split_short_opt shortopt # Set func_split_short_opt_name and func_split_short_opt_arg shell # variables after splitting SHORTOPT after the 2nd character. func_split_short_opt () { func_split_short_opt_arg=${1#??} func_split_short_opt_name=${1%"$func_split_short_opt_arg"} } # Extended-shell func_split_short_opt implementation # func_split_long_opt longopt # Set func_split_long_opt_name and func_split_long_opt_arg shell # variables after splitting LONGOPT at the `=' sign. func_split_long_opt () { func_split_long_opt_name=${1%%=*} func_split_long_opt_arg=${1#*=} } # Extended-shell func_split_long_opt implementation exit_cmd=: magic="%%%MAGIC variable%%%" magic_exe="%%%MAGIC EXE variable%%%" # Global variables. nonopt= preserve_args= lo2o="s/\\.lo\$/.${objext}/" o2lo="s/\\.${objext}\$/.lo/" extracted_archives= extracted_serial=0 # If this variable is set in any of the actions, the command in it # will be execed at the end. This prevents here-documents from being # left over by shells. exec_cmd= # func_append var value # Append VALUE to the end of shell variable VAR. func_append () { eval "${1}+=\${2}" } # Extended-shell func_append implementation # func_append_quoted var value # Quote VALUE and append to the end of shell variable VAR, separated # by a space. func_append_quoted () { func_quote_for_eval "${2}" eval "${1}+=\\ \$func_quote_for_eval_result" } # Extended-shell func_append_quoted implementation # func_arith arithmetic-term... func_arith () { func_arith_result=$(( $* )) } # Extended-shell func_arith implementation # func_len string # STRING may not start with a hyphen. func_len () { func_len_result=${#1} } # Extended-shell func_len implementation # func_lo2o object func_lo2o () { case ${1} in *.lo) func_lo2o_result=${1%.lo}.${objext} ;; *) func_lo2o_result=${1} ;; esac } # Extended-shell func_lo2o implementation # func_xform libobj-or-source func_xform () { func_xform_result=${1%.*}.lo } # Extended-shell func_xform implementation # func_fatal_configuration arg... # Echo program name prefixed message to standard error, followed by # a configuration failure hint, and exit. func_fatal_configuration () { func_error ${1+"$@"} func_error "See the $PACKAGE documentation for more information." func_fatal_error "Fatal configuration error." } # func_config # Display the configuration for all the tags in this script. func_config () { re_begincf='^# ### BEGIN LIBTOOL' re_endcf='^# ### END LIBTOOL' # Default configuration. $SED "1,/$re_begincf CONFIG/d;/$re_endcf CONFIG/,\$d" < "$progpath" # Now print the configurations for the tags. for tagname in $taglist; do $SED -n "/$re_begincf TAG CONFIG: $tagname\$/,/$re_endcf TAG CONFIG: $tagname\$/p" < "$progpath" done exit $? } # func_features # Display the features supported by this script. func_features () { echo "host: $host" if test "$build_libtool_libs" = yes; then echo "enable shared libraries" else echo "disable shared libraries" fi if test "$build_old_libs" = yes; then echo "enable static libraries" else echo "disable static libraries" fi exit $? } # func_enable_tag tagname # Verify that TAGNAME is valid, and either flag an error and exit, or # enable the TAGNAME tag. We also add TAGNAME to the global $taglist # variable here. func_enable_tag () { # Global variable: tagname="$1" re_begincf="^# ### BEGIN LIBTOOL TAG CONFIG: $tagname\$" re_endcf="^# ### END LIBTOOL TAG CONFIG: $tagname\$" sed_extractcf="/$re_begincf/,/$re_endcf/p" # Validate tagname. case $tagname in *[!-_A-Za-z0-9,/]*) func_fatal_error "invalid tag name: $tagname" ;; esac # Don't test for the "default" C tag, as we know it's # there but not specially marked. case $tagname in CC) ;; *) if $GREP "$re_begincf" "$progpath" >/dev/null 2>&1; then taglist="$taglist $tagname" # Evaluate the configuration. Be careful to quote the path # and the sed script, to avoid splitting on whitespace, but # also don't use non-portable quotes within backquotes within # quotes we have to do it in 2 steps: extractedcf=`$SED -n -e "$sed_extractcf" < "$progpath"` eval "$extractedcf" else func_error "ignoring unknown tag $tagname" fi ;; esac } # func_check_version_match # Ensure that we are using m4 macros, and libtool script from the same # release of libtool. func_check_version_match () { if test "$package_revision" != "$macro_revision"; then if test "$VERSION" != "$macro_version"; then if test -z "$macro_version"; then cat >&2 <<_LT_EOF $progname: Version mismatch error. This is $PACKAGE $VERSION, but the $progname: definition of this LT_INIT comes from an older release. $progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION $progname: and run autoconf again. _LT_EOF else cat >&2 <<_LT_EOF $progname: Version mismatch error. This is $PACKAGE $VERSION, but the $progname: definition of this LT_INIT comes from $PACKAGE $macro_version. $progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION $progname: and run autoconf again. _LT_EOF fi else cat >&2 <<_LT_EOF $progname: Version mismatch error. This is $PACKAGE $VERSION, revision $package_revision, $progname: but the definition of this LT_INIT comes from revision $macro_revision. $progname: You should recreate aclocal.m4 with macros from revision $package_revision $progname: of $PACKAGE $VERSION and run autoconf again. _LT_EOF fi exit $EXIT_MISMATCH fi } # Shorthand for --mode=foo, only valid as the first argument case $1 in clean|clea|cle|cl) shift; set dummy --mode clean ${1+"$@"}; shift ;; compile|compil|compi|comp|com|co|c) shift; set dummy --mode compile ${1+"$@"}; shift ;; execute|execut|execu|exec|exe|ex|e) shift; set dummy --mode execute ${1+"$@"}; shift ;; finish|finis|fini|fin|fi|f) shift; set dummy --mode finish ${1+"$@"}; shift ;; install|instal|insta|inst|ins|in|i) shift; set dummy --mode install ${1+"$@"}; shift ;; link|lin|li|l) shift; set dummy --mode link ${1+"$@"}; shift ;; uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u) shift; set dummy --mode uninstall ${1+"$@"}; shift ;; esac # Option defaults: opt_debug=: opt_dry_run=false opt_config=false opt_preserve_dup_deps=false opt_features=false opt_finish=false opt_help=false opt_help_all=false opt_silent=: opt_warning=: opt_verbose=: opt_silent=false opt_verbose=false # Parse options once, thoroughly. This comes as soon as possible in the # script to make things like `--version' happen as quickly as we can. { # this just eases exit handling while test $# -gt 0; do opt="$1" shift case $opt in --debug|-x) opt_debug='set -x' func_echo "enabling shell trace mode" $opt_debug ;; --dry-run|--dryrun|-n) opt_dry_run=: ;; --config) opt_config=: func_config ;; --dlopen|-dlopen) optarg="$1" opt_dlopen="${opt_dlopen+$opt_dlopen }$optarg" shift ;; --preserve-dup-deps) opt_preserve_dup_deps=: ;; --features) opt_features=: func_features ;; --finish) opt_finish=: set dummy --mode finish ${1+"$@"}; shift ;; --help) opt_help=: ;; --help-all) opt_help_all=: opt_help=': help-all' ;; --mode) test $# = 0 && func_missing_arg $opt && break optarg="$1" opt_mode="$optarg" case $optarg in # Valid mode arguments: clean|compile|execute|finish|install|link|relink|uninstall) ;; # Catch anything else as an error *) func_error "invalid argument for $opt" exit_cmd=exit break ;; esac shift ;; --no-silent|--no-quiet) opt_silent=false preserve_args+=" $opt" ;; --no-warning|--no-warn) opt_warning=false preserve_args+=" $opt" ;; --no-verbose) opt_verbose=false preserve_args+=" $opt" ;; --silent|--quiet) opt_silent=: preserve_args+=" $opt" opt_verbose=false ;; --verbose|-v) opt_verbose=: preserve_args+=" $opt" opt_silent=false ;; --tag) test $# = 0 && func_missing_arg $opt && break optarg="$1" opt_tag="$optarg" preserve_args+=" $opt $optarg" func_enable_tag "$optarg" shift ;; -\?|-h) func_usage ;; --help) func_help ;; --version) func_version ;; # Separate optargs to long options: --*=*) func_split_long_opt "$opt" set dummy "$func_split_long_opt_name" "$func_split_long_opt_arg" ${1+"$@"} shift ;; # Separate non-argument short options: -\?*|-h*|-n*|-v*) func_split_short_opt "$opt" set dummy "$func_split_short_opt_name" "-$func_split_short_opt_arg" ${1+"$@"} shift ;; --) break ;; -*) func_fatal_help "unrecognized option \`$opt'" ;; *) set dummy "$opt" ${1+"$@"}; shift; break ;; esac done # Validate options: # save first non-option argument if test "$#" -gt 0; then nonopt="$opt" shift fi # preserve --debug test "$opt_debug" = : || preserve_args+=" --debug" case $host in *cygwin* | *mingw* | *pw32* | *cegcc*) # don't eliminate duplications in $postdeps and $predeps opt_duplicate_compiler_generated_deps=: ;; *) opt_duplicate_compiler_generated_deps=$opt_preserve_dup_deps ;; esac $opt_help || { # Sanity checks first: func_check_version_match if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then func_fatal_configuration "not configured to build any kind of library" fi # Darwin sucks eval std_shrext=\"$shrext_cmds\" # Only execute mode is allowed to have -dlopen flags. if test -n "$opt_dlopen" && test "$opt_mode" != execute; then func_error "unrecognized option \`-dlopen'" $ECHO "$help" 1>&2 exit $EXIT_FAILURE fi # Change the help message to a mode-specific one. generic_help="$help" help="Try \`$progname --help --mode=$opt_mode' for more information." } # Bail if the options were screwed $exit_cmd $EXIT_FAILURE } ## ----------- ## ## Main. ## ## ----------- ## # func_lalib_p file # True iff FILE is a libtool `.la' library or `.lo' object file. # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_lalib_p () { test -f "$1" && $SED -e 4q "$1" 2>/dev/null \ | $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1 } # func_lalib_unsafe_p file # True iff FILE is a libtool `.la' library or `.lo' object file. # This function implements the same check as func_lalib_p without # resorting to external programs. To this end, it redirects stdin and # closes it afterwards, without saving the original file descriptor. # As a safety measure, use it only where a negative result would be # fatal anyway. Works if `file' does not exist. func_lalib_unsafe_p () { lalib_p=no if test -f "$1" && test -r "$1" && exec 5<&0 <"$1"; then for lalib_p_l in 1 2 3 4 do read lalib_p_line case "$lalib_p_line" in \#\ Generated\ by\ *$PACKAGE* ) lalib_p=yes; break;; esac done exec 0<&5 5<&- fi test "$lalib_p" = yes } # func_ltwrapper_script_p file # True iff FILE is a libtool wrapper script # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_ltwrapper_script_p () { func_lalib_p "$1" } # func_ltwrapper_executable_p file # True iff FILE is a libtool wrapper executable # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_ltwrapper_executable_p () { func_ltwrapper_exec_suffix= case $1 in *.exe) ;; *) func_ltwrapper_exec_suffix=.exe ;; esac $GREP "$magic_exe" "$1$func_ltwrapper_exec_suffix" >/dev/null 2>&1 } # func_ltwrapper_scriptname file # Assumes file is an ltwrapper_executable # uses $file to determine the appropriate filename for a # temporary ltwrapper_script. func_ltwrapper_scriptname () { func_dirname_and_basename "$1" "" "." func_stripname '' '.exe' "$func_basename_result" func_ltwrapper_scriptname_result="$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper" } # func_ltwrapper_p file # True iff FILE is a libtool wrapper script or wrapper executable # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_ltwrapper_p () { func_ltwrapper_script_p "$1" || func_ltwrapper_executable_p "$1" } # func_execute_cmds commands fail_cmd # Execute tilde-delimited COMMANDS. # If FAIL_CMD is given, eval that upon failure. # FAIL_CMD may read-access the current command in variable CMD! func_execute_cmds () { $opt_debug save_ifs=$IFS; IFS='~' for cmd in $1; do IFS=$save_ifs eval cmd=\"$cmd\" func_show_eval "$cmd" "${2-:}" done IFS=$save_ifs } # func_source file # Source FILE, adding directory component if necessary. # Note that it is not necessary on cygwin/mingw to append a dot to # FILE even if both FILE and FILE.exe exist: automatic-append-.exe # behavior happens only for exec(3), not for open(2)! Also, sourcing # `FILE.' does not work on cygwin managed mounts. func_source () { $opt_debug case $1 in */* | *\\*) . "$1" ;; *) . "./$1" ;; esac } # func_resolve_sysroot PATH # Replace a leading = in PATH with a sysroot. Store the result into # func_resolve_sysroot_result func_resolve_sysroot () { func_resolve_sysroot_result=$1 case $func_resolve_sysroot_result in =*) func_stripname '=' '' "$func_resolve_sysroot_result" func_resolve_sysroot_result=$lt_sysroot$func_stripname_result ;; esac } # func_replace_sysroot PATH # If PATH begins with the sysroot, replace it with = and # store the result into func_replace_sysroot_result. func_replace_sysroot () { case "$lt_sysroot:$1" in ?*:"$lt_sysroot"*) func_stripname "$lt_sysroot" '' "$1" func_replace_sysroot_result="=$func_stripname_result" ;; *) # Including no sysroot. func_replace_sysroot_result=$1 ;; esac } # func_infer_tag arg # Infer tagged configuration to use if any are available and # if one wasn't chosen via the "--tag" command line option. # Only attempt this if the compiler in the base compile # command doesn't match the default compiler. # arg is usually of the form 'gcc ...' func_infer_tag () { $opt_debug if test -n "$available_tags" && test -z "$tagname"; then CC_quoted= for arg in $CC; do func_append_quoted CC_quoted "$arg" done CC_expanded=`func_echo_all $CC` CC_quoted_expanded=`func_echo_all $CC_quoted` case $@ in # Blanks in the command may have been stripped by the calling shell, # but not from the CC environment variable when configure was run. " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \ " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) ;; # Blanks at the start of $base_compile will cause this to fail # if we don't check for them as well. *) for z in $available_tags; do if $GREP "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then # Evaluate the configuration. eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`" CC_quoted= for arg in $CC; do # Double-quote args containing other shell metacharacters. func_append_quoted CC_quoted "$arg" done CC_expanded=`func_echo_all $CC` CC_quoted_expanded=`func_echo_all $CC_quoted` case "$@ " in " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \ " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) # The compiler in the base compile command matches # the one in the tagged configuration. # Assume this is the tagged configuration we want. tagname=$z break ;; esac fi done # If $tagname still isn't set, then no tagged configuration # was found and let the user know that the "--tag" command # line option must be used. if test -z "$tagname"; then func_echo "unable to infer tagged configuration" func_fatal_error "specify a tag with \`--tag'" # else # func_verbose "using $tagname tagged configuration" fi ;; esac fi } # func_write_libtool_object output_name pic_name nonpic_name # Create a libtool object file (analogous to a ".la" file), # but don't create it if we're doing a dry run. func_write_libtool_object () { write_libobj=${1} if test "$build_libtool_libs" = yes; then write_lobj=\'${2}\' else write_lobj=none fi if test "$build_old_libs" = yes; then write_oldobj=\'${3}\' else write_oldobj=none fi $opt_dry_run || { cat >${write_libobj}T </dev/null` if test "$?" -eq 0 && test -n "${func_convert_core_file_wine_to_w32_tmp}"; then func_convert_core_file_wine_to_w32_result=`$ECHO "$func_convert_core_file_wine_to_w32_tmp" | $SED -e "$lt_sed_naive_backslashify"` else func_convert_core_file_wine_to_w32_result= fi fi } # end: func_convert_core_file_wine_to_w32 # func_convert_core_path_wine_to_w32 ARG # Helper function used by path conversion functions when $build is *nix, and # $host is mingw, cygwin, or some other w32 environment. Relies on a correctly # configured wine environment available, with the winepath program in $build's # $PATH. Assumes ARG has no leading or trailing path separator characters. # # ARG is path to be converted from $build format to win32. # Result is available in $func_convert_core_path_wine_to_w32_result. # Unconvertible file (directory) names in ARG are skipped; if no directory names # are convertible, then the result may be empty. func_convert_core_path_wine_to_w32 () { $opt_debug # unfortunately, winepath doesn't convert paths, only file names func_convert_core_path_wine_to_w32_result="" if test -n "$1"; then oldIFS=$IFS IFS=: for func_convert_core_path_wine_to_w32_f in $1; do IFS=$oldIFS func_convert_core_file_wine_to_w32 "$func_convert_core_path_wine_to_w32_f" if test -n "$func_convert_core_file_wine_to_w32_result" ; then if test -z "$func_convert_core_path_wine_to_w32_result"; then func_convert_core_path_wine_to_w32_result="$func_convert_core_file_wine_to_w32_result" else func_append func_convert_core_path_wine_to_w32_result ";$func_convert_core_file_wine_to_w32_result" fi fi done IFS=$oldIFS fi } # end: func_convert_core_path_wine_to_w32 # func_cygpath ARGS... # Wrapper around calling the cygpath program via LT_CYGPATH. This is used when # when (1) $build is *nix and Cygwin is hosted via a wine environment; or (2) # $build is MSYS and $host is Cygwin, or (3) $build is Cygwin. In case (1) or # (2), returns the Cygwin file name or path in func_cygpath_result (input # file name or path is assumed to be in w32 format, as previously converted # from $build's *nix or MSYS format). In case (3), returns the w32 file name # or path in func_cygpath_result (input file name or path is assumed to be in # Cygwin format). Returns an empty string on error. # # ARGS are passed to cygpath, with the last one being the file name or path to # be converted. # # Specify the absolute *nix (or w32) name to cygpath in the LT_CYGPATH # environment variable; do not put it in $PATH. func_cygpath () { $opt_debug if test -n "$LT_CYGPATH" && test -f "$LT_CYGPATH"; then func_cygpath_result=`$LT_CYGPATH "$@" 2>/dev/null` if test "$?" -ne 0; then # on failure, ensure result is empty func_cygpath_result= fi else func_cygpath_result= func_error "LT_CYGPATH is empty or specifies non-existent file: \`$LT_CYGPATH'" fi } #end: func_cygpath # func_convert_core_msys_to_w32 ARG # Convert file name or path ARG from MSYS format to w32 format. Return # result in func_convert_core_msys_to_w32_result. func_convert_core_msys_to_w32 () { $opt_debug # awkward: cmd appends spaces to result func_convert_core_msys_to_w32_result=`( cmd //c echo "$1" ) 2>/dev/null | $SED -e 's/[ ]*$//' -e "$lt_sed_naive_backslashify"` } #end: func_convert_core_msys_to_w32 # func_convert_file_check ARG1 ARG2 # Verify that ARG1 (a file name in $build format) was converted to $host # format in ARG2. Otherwise, emit an error message, but continue (resetting # func_to_host_file_result to ARG1). func_convert_file_check () { $opt_debug if test -z "$2" && test -n "$1" ; then func_error "Could not determine host file name corresponding to" func_error " \`$1'" func_error "Continuing, but uninstalled executables may not work." # Fallback: func_to_host_file_result="$1" fi } # end func_convert_file_check # func_convert_path_check FROM_PATHSEP TO_PATHSEP FROM_PATH TO_PATH # Verify that FROM_PATH (a path in $build format) was converted to $host # format in TO_PATH. Otherwise, emit an error message, but continue, resetting # func_to_host_file_result to a simplistic fallback value (see below). func_convert_path_check () { $opt_debug if test -z "$4" && test -n "$3"; then func_error "Could not determine the host path corresponding to" func_error " \`$3'" func_error "Continuing, but uninstalled executables may not work." # Fallback. This is a deliberately simplistic "conversion" and # should not be "improved". See libtool.info. if test "x$1" != "x$2"; then lt_replace_pathsep_chars="s|$1|$2|g" func_to_host_path_result=`echo "$3" | $SED -e "$lt_replace_pathsep_chars"` else func_to_host_path_result="$3" fi fi } # end func_convert_path_check # func_convert_path_front_back_pathsep FRONTPAT BACKPAT REPL ORIG # Modifies func_to_host_path_result by prepending REPL if ORIG matches FRONTPAT # and appending REPL if ORIG matches BACKPAT. func_convert_path_front_back_pathsep () { $opt_debug case $4 in $1 ) func_to_host_path_result="$3$func_to_host_path_result" ;; esac case $4 in $2 ) func_to_host_path_result+="$3" ;; esac } # end func_convert_path_front_back_pathsep ################################################## # $build to $host FILE NAME CONVERSION FUNCTIONS # ################################################## # invoked via `$to_host_file_cmd ARG' # # In each case, ARG is the path to be converted from $build to $host format. # Result will be available in $func_to_host_file_result. # func_to_host_file ARG # Converts the file name ARG from $build format to $host format. Return result # in func_to_host_file_result. func_to_host_file () { $opt_debug $to_host_file_cmd "$1" } # end func_to_host_file # func_to_tool_file ARG LAZY # converts the file name ARG from $build format to toolchain format. Return # result in func_to_tool_file_result. If the conversion in use is listed # in (the comma separated) LAZY, no conversion takes place. func_to_tool_file () { $opt_debug case ,$2, in *,"$to_tool_file_cmd",*) func_to_tool_file_result=$1 ;; *) $to_tool_file_cmd "$1" func_to_tool_file_result=$func_to_host_file_result ;; esac } # end func_to_tool_file # func_convert_file_noop ARG # Copy ARG to func_to_host_file_result. func_convert_file_noop () { func_to_host_file_result="$1" } # end func_convert_file_noop # func_convert_file_msys_to_w32 ARG # Convert file name ARG from (mingw) MSYS to (mingw) w32 format; automatic # conversion to w32 is not available inside the cwrapper. Returns result in # func_to_host_file_result. func_convert_file_msys_to_w32 () { $opt_debug func_to_host_file_result="$1" if test -n "$1"; then func_convert_core_msys_to_w32 "$1" func_to_host_file_result="$func_convert_core_msys_to_w32_result" fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_msys_to_w32 # func_convert_file_cygwin_to_w32 ARG # Convert file name ARG from Cygwin to w32 format. Returns result in # func_to_host_file_result. func_convert_file_cygwin_to_w32 () { $opt_debug func_to_host_file_result="$1" if test -n "$1"; then # because $build is cygwin, we call "the" cygpath in $PATH; no need to use # LT_CYGPATH in this case. func_to_host_file_result=`cygpath -m "$1"` fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_cygwin_to_w32 # func_convert_file_nix_to_w32 ARG # Convert file name ARG from *nix to w32 format. Requires a wine environment # and a working winepath. Returns result in func_to_host_file_result. func_convert_file_nix_to_w32 () { $opt_debug func_to_host_file_result="$1" if test -n "$1"; then func_convert_core_file_wine_to_w32 "$1" func_to_host_file_result="$func_convert_core_file_wine_to_w32_result" fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_nix_to_w32 # func_convert_file_msys_to_cygwin ARG # Convert file name ARG from MSYS to Cygwin format. Requires LT_CYGPATH set. # Returns result in func_to_host_file_result. func_convert_file_msys_to_cygwin () { $opt_debug func_to_host_file_result="$1" if test -n "$1"; then func_convert_core_msys_to_w32 "$1" func_cygpath -u "$func_convert_core_msys_to_w32_result" func_to_host_file_result="$func_cygpath_result" fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_msys_to_cygwin # func_convert_file_nix_to_cygwin ARG # Convert file name ARG from *nix to Cygwin format. Requires Cygwin installed # in a wine environment, working winepath, and LT_CYGPATH set. Returns result # in func_to_host_file_result. func_convert_file_nix_to_cygwin () { $opt_debug func_to_host_file_result="$1" if test -n "$1"; then # convert from *nix to w32, then use cygpath to convert from w32 to cygwin. func_convert_core_file_wine_to_w32 "$1" func_cygpath -u "$func_convert_core_file_wine_to_w32_result" func_to_host_file_result="$func_cygpath_result" fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_nix_to_cygwin ############################################# # $build to $host PATH CONVERSION FUNCTIONS # ############################################# # invoked via `$to_host_path_cmd ARG' # # In each case, ARG is the path to be converted from $build to $host format. # The result will be available in $func_to_host_path_result. # # Path separators are also converted from $build format to $host format. If # ARG begins or ends with a path separator character, it is preserved (but # converted to $host format) on output. # # All path conversion functions are named using the following convention: # file name conversion function : func_convert_file_X_to_Y () # path conversion function : func_convert_path_X_to_Y () # where, for any given $build/$host combination the 'X_to_Y' value is the # same. If conversion functions are added for new $build/$host combinations, # the two new functions must follow this pattern, or func_init_to_host_path_cmd # will break. # func_init_to_host_path_cmd # Ensures that function "pointer" variable $to_host_path_cmd is set to the # appropriate value, based on the value of $to_host_file_cmd. to_host_path_cmd= func_init_to_host_path_cmd () { $opt_debug if test -z "$to_host_path_cmd"; then func_stripname 'func_convert_file_' '' "$to_host_file_cmd" to_host_path_cmd="func_convert_path_${func_stripname_result}" fi } # func_to_host_path ARG # Converts the path ARG from $build format to $host format. Return result # in func_to_host_path_result. func_to_host_path () { $opt_debug func_init_to_host_path_cmd $to_host_path_cmd "$1" } # end func_to_host_path # func_convert_path_noop ARG # Copy ARG to func_to_host_path_result. func_convert_path_noop () { func_to_host_path_result="$1" } # end func_convert_path_noop # func_convert_path_msys_to_w32 ARG # Convert path ARG from (mingw) MSYS to (mingw) w32 format; automatic # conversion to w32 is not available inside the cwrapper. Returns result in # func_to_host_path_result. func_convert_path_msys_to_w32 () { $opt_debug func_to_host_path_result="$1" if test -n "$1"; then # Remove leading and trailing path separator characters from ARG. MSYS # behavior is inconsistent here; cygpath turns them into '.;' and ';.'; # and winepath ignores them completely. func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" func_to_host_path_result="$func_convert_core_msys_to_w32_result" func_convert_path_check : ";" \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" fi } # end func_convert_path_msys_to_w32 # func_convert_path_cygwin_to_w32 ARG # Convert path ARG from Cygwin to w32 format. Returns result in # func_to_host_file_result. func_convert_path_cygwin_to_w32 () { $opt_debug func_to_host_path_result="$1" if test -n "$1"; then # See func_convert_path_msys_to_w32: func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_to_host_path_result=`cygpath -m -p "$func_to_host_path_tmp1"` func_convert_path_check : ";" \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" fi } # end func_convert_path_cygwin_to_w32 # func_convert_path_nix_to_w32 ARG # Convert path ARG from *nix to w32 format. Requires a wine environment and # a working winepath. Returns result in func_to_host_file_result. func_convert_path_nix_to_w32 () { $opt_debug func_to_host_path_result="$1" if test -n "$1"; then # See func_convert_path_msys_to_w32: func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" func_to_host_path_result="$func_convert_core_path_wine_to_w32_result" func_convert_path_check : ";" \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" fi } # end func_convert_path_nix_to_w32 # func_convert_path_msys_to_cygwin ARG # Convert path ARG from MSYS to Cygwin format. Requires LT_CYGPATH set. # Returns result in func_to_host_file_result. func_convert_path_msys_to_cygwin () { $opt_debug func_to_host_path_result="$1" if test -n "$1"; then # See func_convert_path_msys_to_w32: func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" func_cygpath -u -p "$func_convert_core_msys_to_w32_result" func_to_host_path_result="$func_cygpath_result" func_convert_path_check : : \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" : "$1" fi } # end func_convert_path_msys_to_cygwin # func_convert_path_nix_to_cygwin ARG # Convert path ARG from *nix to Cygwin format. Requires Cygwin installed in a # a wine environment, working winepath, and LT_CYGPATH set. Returns result in # func_to_host_file_result. func_convert_path_nix_to_cygwin () { $opt_debug func_to_host_path_result="$1" if test -n "$1"; then # Remove leading and trailing path separator characters from # ARG. msys behavior is inconsistent here, cygpath turns them # into '.;' and ';.', and winepath ignores them completely. func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" func_cygpath -u -p "$func_convert_core_path_wine_to_w32_result" func_to_host_path_result="$func_cygpath_result" func_convert_path_check : : \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" : "$1" fi } # end func_convert_path_nix_to_cygwin # func_mode_compile arg... func_mode_compile () { $opt_debug # Get the compilation command and the source file. base_compile= srcfile="$nonopt" # always keep a non-empty value in "srcfile" suppress_opt=yes suppress_output= arg_mode=normal libobj= later= pie_flag= for arg do case $arg_mode in arg ) # do not "continue". Instead, add this to base_compile lastarg="$arg" arg_mode=normal ;; target ) libobj="$arg" arg_mode=normal continue ;; normal ) # Accept any command-line options. case $arg in -o) test -n "$libobj" && \ func_fatal_error "you cannot specify \`-o' more than once" arg_mode=target continue ;; -pie | -fpie | -fPIE) pie_flag+=" $arg" continue ;; -shared | -static | -prefer-pic | -prefer-non-pic) later+=" $arg" continue ;; -no-suppress) suppress_opt=no continue ;; -Xcompiler) arg_mode=arg # the next one goes into the "base_compile" arg list continue # The current "srcfile" will either be retained or ;; # replaced later. I would guess that would be a bug. -Wc,*) func_stripname '-Wc,' '' "$arg" args=$func_stripname_result lastarg= save_ifs="$IFS"; IFS=',' for arg in $args; do IFS="$save_ifs" func_append_quoted lastarg "$arg" done IFS="$save_ifs" func_stripname ' ' '' "$lastarg" lastarg=$func_stripname_result # Add the arguments to base_compile. base_compile+=" $lastarg" continue ;; *) # Accept the current argument as the source file. # The previous "srcfile" becomes the current argument. # lastarg="$srcfile" srcfile="$arg" ;; esac # case $arg ;; esac # case $arg_mode # Aesthetically quote the previous argument. func_append_quoted base_compile "$lastarg" done # for arg case $arg_mode in arg) func_fatal_error "you must specify an argument for -Xcompile" ;; target) func_fatal_error "you must specify a target with \`-o'" ;; *) # Get the name of the library object. test -z "$libobj" && { func_basename "$srcfile" libobj="$func_basename_result" } ;; esac # Recognize several different file suffixes. # If the user specifies -o file.o, it is replaced with file.lo case $libobj in *.[cCFSifmso] | \ *.ada | *.adb | *.ads | *.asm | \ *.c++ | *.cc | *.ii | *.class | *.cpp | *.cxx | \ *.[fF][09]? | *.for | *.java | *.go | *.obj | *.sx | *.cu | *.cup) func_xform "$libobj" libobj=$func_xform_result ;; esac case $libobj in *.lo) func_lo2o "$libobj"; obj=$func_lo2o_result ;; *) func_fatal_error "cannot determine name of library object from \`$libobj'" ;; esac func_infer_tag $base_compile for arg in $later; do case $arg in -shared) test "$build_libtool_libs" != yes && \ func_fatal_configuration "can not build a shared library" build_old_libs=no continue ;; -static) build_libtool_libs=no build_old_libs=yes continue ;; -prefer-pic) pic_mode=yes continue ;; -prefer-non-pic) pic_mode=no continue ;; esac done func_quote_for_eval "$libobj" test "X$libobj" != "X$func_quote_for_eval_result" \ && $ECHO "X$libobj" | $GREP '[]~#^*{};<>?"'"'"' &()|`$[]' \ && func_warning "libobj name \`$libobj' may not contain shell special characters." func_dirname_and_basename "$obj" "/" "" objname="$func_basename_result" xdir="$func_dirname_result" lobj=${xdir}$objdir/$objname test -z "$base_compile" && \ func_fatal_help "you must specify a compilation command" # Delete any leftover library objects. if test "$build_old_libs" = yes; then removelist="$obj $lobj $libobj ${libobj}T" else removelist="$lobj $libobj ${libobj}T" fi # On Cygwin there's no "real" PIC flag so we must build both object types case $host_os in cygwin* | mingw* | pw32* | os2* | cegcc*) pic_mode=default ;; esac if test "$pic_mode" = no && test "$deplibs_check_method" != pass_all; then # non-PIC code in shared libraries is not supported pic_mode=default fi # Calculate the filename of the output object if compiler does # not support -o with -c if test "$compiler_c_o" = no; then output_obj=`$ECHO "$srcfile" | $SED 's%^.*/%%; s%\.[^.]*$%%'`.${objext} lockfile="$output_obj.lock" else output_obj= need_locks=no lockfile= fi # Lock this critical section if it is needed # We use this script file to make the link, it avoids creating a new file if test "$need_locks" = yes; then until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do func_echo "Waiting for $lockfile to be removed" sleep 2 done elif test "$need_locks" = warn; then if test -f "$lockfile"; then $ECHO "\ *** ERROR, $lockfile exists and contains: `cat $lockfile 2>/dev/null` This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because your compiler does not support \`-c' and \`-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." $opt_dry_run || $RM $removelist exit $EXIT_FAILURE fi removelist+=" $output_obj" $ECHO "$srcfile" > "$lockfile" fi $opt_dry_run || $RM $removelist removelist+=" $lockfile" trap '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' 1 2 15 func_to_tool_file "$srcfile" func_convert_file_msys_to_w32 srcfile=$func_to_tool_file_result func_quote_for_eval "$srcfile" qsrcfile=$func_quote_for_eval_result # Only build a PIC object if we are building libtool libraries. if test "$build_libtool_libs" = yes; then # Without this assignment, base_compile gets emptied. fbsd_hideous_sh_bug=$base_compile if test "$pic_mode" != no; then command="$base_compile $qsrcfile $pic_flag" else # Don't build PIC code command="$base_compile $qsrcfile" fi func_mkdir_p "$xdir$objdir" if test -z "$output_obj"; then # Place PIC objects in $objdir command+=" -o $lobj" fi func_show_eval_locale "$command" \ 'test -n "$output_obj" && $RM $removelist; exit $EXIT_FAILURE' if test "$need_locks" = warn && test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then $ECHO "\ *** ERROR, $lockfile contains: `cat $lockfile 2>/dev/null` but it should contain: $srcfile This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because your compiler does not support \`-c' and \`-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." $opt_dry_run || $RM $removelist exit $EXIT_FAILURE fi # Just move the object if needed, then go on to compile the next one if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then func_show_eval '$MV "$output_obj" "$lobj"' \ 'error=$?; $opt_dry_run || $RM $removelist; exit $error' fi # Allow error messages only from the first compilation. if test "$suppress_opt" = yes; then suppress_output=' >/dev/null 2>&1' fi fi # Only build a position-dependent object if we build old libraries. if test "$build_old_libs" = yes; then if test "$pic_mode" != yes; then # Don't build PIC code command="$base_compile $qsrcfile$pie_flag" else command="$base_compile $qsrcfile $pic_flag" fi if test "$compiler_c_o" = yes; then command+=" -o $obj" fi # Suppress compiler output if we already did a PIC compilation. command+="$suppress_output" func_show_eval_locale "$command" \ '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' if test "$need_locks" = warn && test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then $ECHO "\ *** ERROR, $lockfile contains: `cat $lockfile 2>/dev/null` but it should contain: $srcfile This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because your compiler does not support \`-c' and \`-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." $opt_dry_run || $RM $removelist exit $EXIT_FAILURE fi # Just move the object if needed if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then func_show_eval '$MV "$output_obj" "$obj"' \ 'error=$?; $opt_dry_run || $RM $removelist; exit $error' fi fi $opt_dry_run || { func_write_libtool_object "$libobj" "$objdir/$objname" "$objname" # Unlock the critical section if it was locked if test "$need_locks" != no; then removelist=$lockfile $RM "$lockfile" fi } exit $EXIT_SUCCESS } $opt_help || { test "$opt_mode" = compile && func_mode_compile ${1+"$@"} } func_mode_help () { # We need to display help for each of the modes. case $opt_mode in "") # Generic help is extracted from the usage comments # at the start of this file. func_help ;; clean) $ECHO \ "Usage: $progname [OPTION]... --mode=clean RM [RM-OPTION]... FILE... Remove files from the build directory. RM is the name of the program to use to delete files associated with each FILE (typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed to RM. If FILE is a libtool library, object or program, all the files associated with it are deleted. Otherwise, only FILE itself is deleted using RM." ;; compile) $ECHO \ "Usage: $progname [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE Compile a source file into a libtool library object. This mode accepts the following additional options: -o OUTPUT-FILE set the output file name to OUTPUT-FILE -no-suppress do not suppress compiler output for multiple passes -prefer-pic try to build PIC objects only -prefer-non-pic try to build non-PIC objects only -shared do not build a \`.o' file suitable for static linking -static only build a \`.o' file suitable for static linking -Wc,FLAG pass FLAG directly to the compiler COMPILE-COMMAND is a command to be used in creating a \`standard' object file from the given SOURCEFILE. The output file name is determined by removing the directory component from SOURCEFILE, then substituting the C source code suffix \`.c' with the library object suffix, \`.lo'." ;; execute) $ECHO \ "Usage: $progname [OPTION]... --mode=execute COMMAND [ARGS]... Automatically set library path, then run a program. This mode accepts the following additional options: -dlopen FILE add the directory containing FILE to the library path This mode sets the library path environment variable according to \`-dlopen' flags. If any of the ARGS are libtool executable wrappers, then they are translated into their corresponding uninstalled binary, and any of their required library directories are added to the library path. Then, COMMAND is executed, with ARGS as arguments." ;; finish) $ECHO \ "Usage: $progname [OPTION]... --mode=finish [LIBDIR]... Complete the installation of libtool libraries. Each LIBDIR is a directory that contains libtool libraries. The commands that this mode executes may require superuser privileges. Use the \`--dry-run' option if you just want to see what would be executed." ;; install) $ECHO \ "Usage: $progname [OPTION]... --mode=install INSTALL-COMMAND... Install executables or libraries. INSTALL-COMMAND is the installation command. The first component should be either the \`install' or \`cp' program. The following components of INSTALL-COMMAND are treated specially: -inst-prefix-dir PREFIX-DIR Use PREFIX-DIR as a staging area for installation The rest of the components are interpreted as arguments to that command (only BSD-compatible install options are recognized)." ;; link) $ECHO \ "Usage: $progname [OPTION]... --mode=link LINK-COMMAND... Link object files or libraries together to form another library, or to create an executable program. LINK-COMMAND is a command using the C compiler that you would use to create a program from several object files. The following components of LINK-COMMAND are treated specially: -all-static do not do any dynamic linking at all -avoid-version do not add a version suffix if possible -bindir BINDIR specify path to binaries directory (for systems where libraries must be found in the PATH setting at runtime) -dlopen FILE \`-dlpreopen' FILE if it cannot be dlopened at runtime -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3) -export-symbols SYMFILE try to export only the symbols listed in SYMFILE -export-symbols-regex REGEX try to export only the symbols matching REGEX -LLIBDIR search LIBDIR for required installed libraries -lNAME OUTPUT-FILE requires the installed library libNAME -module build a library that can dlopened -no-fast-install disable the fast-install mode -no-install link a not-installable executable -no-undefined declare that a library does not refer to external symbols -o OUTPUT-FILE create OUTPUT-FILE from the specified objects -objectlist FILE Use a list of object files found in FILE to specify objects -precious-files-regex REGEX don't remove output files matching REGEX -release RELEASE specify package release information -rpath LIBDIR the created library will eventually be installed in LIBDIR -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries -shared only do dynamic linking of libtool libraries -shrext SUFFIX override the standard shared library file extension -static do not do any dynamic linking of uninstalled libtool libraries -static-libtool-libs do not do any dynamic linking of libtool libraries -version-info CURRENT[:REVISION[:AGE]] specify library version info [each variable defaults to 0] -weak LIBNAME declare that the target provides the LIBNAME interface -Wc,FLAG -Xcompiler FLAG pass linker-specific FLAG directly to the compiler -Wl,FLAG -Xlinker FLAG pass linker-specific FLAG directly to the linker -XCClinker FLAG pass link-specific FLAG to the compiler driver (CC) All other options (arguments beginning with \`-') are ignored. Every other argument is treated as a filename. Files ending in \`.la' are treated as uninstalled libtool libraries, other files are standard or library object files. If the OUTPUT-FILE ends in \`.la', then a libtool library is created, only library objects (\`.lo' files) may be specified, and \`-rpath' is required, except when creating a convenience library. If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created using \`ar' and \`ranlib', or on Windows using \`lib'. If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file is created, otherwise an executable program is created." ;; uninstall) $ECHO \ "Usage: $progname [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE... Remove libraries from an installation directory. RM is the name of the program to use to delete files associated with each FILE (typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed to RM. If FILE is a libtool library, all the files associated with it are deleted. Otherwise, only FILE itself is deleted using RM." ;; *) func_fatal_help "invalid operation mode \`$opt_mode'" ;; esac echo $ECHO "Try \`$progname --help' for more information about other modes." } # Now that we've collected a possible --mode arg, show help if necessary if $opt_help; then if test "$opt_help" = :; then func_mode_help else { func_help noexit for opt_mode in compile link execute install finish uninstall clean; do func_mode_help done } | sed -n '1p; 2,$s/^Usage:/ or: /p' { func_help noexit for opt_mode in compile link execute install finish uninstall clean; do echo func_mode_help done } | sed '1d /^When reporting/,/^Report/{ H d } $x /information about other modes/d /more detailed .*MODE/d s/^Usage:.*--mode=\([^ ]*\) .*/Description of \1 mode:/' fi exit $? fi # func_mode_execute arg... func_mode_execute () { $opt_debug # The first argument is the command name. cmd="$nonopt" test -z "$cmd" && \ func_fatal_help "you must specify a COMMAND" # Handle -dlopen flags immediately. for file in $opt_dlopen; do test -f "$file" \ || func_fatal_help "\`$file' is not a file" dir= case $file in *.la) func_resolve_sysroot "$file" file=$func_resolve_sysroot_result # Check to see that this really is a libtool archive. func_lalib_unsafe_p "$file" \ || func_fatal_help "\`$lib' is not a valid libtool archive" # Read the libtool library. dlname= library_names= func_source "$file" # Skip this library if it cannot be dlopened. if test -z "$dlname"; then # Warn if it was a shared library. test -n "$library_names" && \ func_warning "\`$file' was not linked with \`-export-dynamic'" continue fi func_dirname "$file" "" "." dir="$func_dirname_result" if test -f "$dir/$objdir/$dlname"; then dir+="/$objdir" else if test ! -f "$dir/$dlname"; then func_fatal_error "cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" fi fi ;; *.lo) # Just add the directory containing the .lo file. func_dirname "$file" "" "." dir="$func_dirname_result" ;; *) func_warning "\`-dlopen' is ignored for non-libtool libraries and objects" continue ;; esac # Get the absolute pathname. absdir=`cd "$dir" && pwd` test -n "$absdir" && dir="$absdir" # Now add the directory to shlibpath_var. if eval "test -z \"\$$shlibpath_var\""; then eval "$shlibpath_var=\"\$dir\"" else eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\"" fi done # This variable tells wrapper scripts just to set shlibpath_var # rather than running their programs. libtool_execute_magic="$magic" # Check if any of the arguments is a wrapper script. args= for file do case $file in -* | *.la | *.lo ) ;; *) # Do a test to see if this is really a libtool program. if func_ltwrapper_script_p "$file"; then func_source "$file" # Transform arg to wrapped name. file="$progdir/$program" elif func_ltwrapper_executable_p "$file"; then func_ltwrapper_scriptname "$file" func_source "$func_ltwrapper_scriptname_result" # Transform arg to wrapped name. file="$progdir/$program" fi ;; esac # Quote arguments (to preserve shell metacharacters). func_append_quoted args "$file" done if test "X$opt_dry_run" = Xfalse; then if test -n "$shlibpath_var"; then # Export the shlibpath_var. eval "export $shlibpath_var" fi # Restore saved environment variables for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES do eval "if test \"\${save_$lt_var+set}\" = set; then $lt_var=\$save_$lt_var; export $lt_var else $lt_unset $lt_var fi" done # Now prepare to actually exec the command. exec_cmd="\$cmd$args" else # Display what would be done. if test -n "$shlibpath_var"; then eval "\$ECHO \"\$shlibpath_var=\$$shlibpath_var\"" echo "export $shlibpath_var" fi $ECHO "$cmd$args" exit $EXIT_SUCCESS fi } test "$opt_mode" = execute && func_mode_execute ${1+"$@"} # func_mode_finish arg... func_mode_finish () { $opt_debug libs= libdirs= admincmds= for opt in "$nonopt" ${1+"$@"} do if test -d "$opt"; then libdirs+=" $opt" elif test -f "$opt"; then if func_lalib_unsafe_p "$opt"; then libs+=" $opt" else func_warning "\`$opt' is not a valid libtool archive" fi else func_fatal_error "invalid argument \`$opt'" fi done if test -n "$libs"; then if test -n "$lt_sysroot"; then sysroot_regex=`$ECHO "$lt_sysroot" | $SED "$sed_make_literal_regex"` sysroot_cmd="s/\([ ']\)$sysroot_regex/\1/g;" else sysroot_cmd= fi # Remove sysroot references if $opt_dry_run; then for lib in $libs; do echo "removing references to $lt_sysroot and \`=' prefixes from $lib" done else tmpdir=`func_mktempdir` for lib in $libs; do sed -e "${sysroot_cmd} s/\([ ']-[LR]\)=/\1/g; s/\([ ']\)=/\1/g" $lib \ > $tmpdir/tmp-la mv -f $tmpdir/tmp-la $lib done ${RM}r "$tmpdir" fi fi if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then for libdir in $libdirs; do if test -n "$finish_cmds"; then # Do each command in the finish commands. func_execute_cmds "$finish_cmds" 'admincmds="$admincmds '"$cmd"'"' fi if test -n "$finish_eval"; then # Do the single finish_eval. eval cmds=\"$finish_eval\" $opt_dry_run || eval "$cmds" || admincmds+=" $cmds" fi done fi # Exit here if they wanted silent mode. $opt_silent && exit $EXIT_SUCCESS if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then echo "----------------------------------------------------------------------" echo "Libraries have been installed in:" for libdir in $libdirs; do $ECHO " $libdir" done echo echo "If you ever happen to want to link against installed libraries" echo "in a given directory, LIBDIR, you must either use libtool, and" echo "specify the full pathname of the library, or use the \`-LLIBDIR'" echo "flag during linking and do at least one of the following:" if test -n "$shlibpath_var"; then echo " - add LIBDIR to the \`$shlibpath_var' environment variable" echo " during execution" fi if test -n "$runpath_var"; then echo " - add LIBDIR to the \`$runpath_var' environment variable" echo " during linking" fi if test -n "$hardcode_libdir_flag_spec"; then libdir=LIBDIR eval flag=\"$hardcode_libdir_flag_spec\" $ECHO " - use the \`$flag' linker flag" fi if test -n "$admincmds"; then $ECHO " - have your system administrator run these commands:$admincmds" fi if test -f /etc/ld.so.conf; then echo " - have your system administrator add LIBDIR to \`/etc/ld.so.conf'" fi echo echo "See any operating system documentation about shared libraries for" case $host in solaris2.[6789]|solaris2.1[0-9]) echo "more information, such as the ld(1), crle(1) and ld.so(8) manual" echo "pages." ;; *) echo "more information, such as the ld(1) and ld.so(8) manual pages." ;; esac echo "----------------------------------------------------------------------" fi exit $EXIT_SUCCESS } test "$opt_mode" = finish && func_mode_finish ${1+"$@"} # func_mode_install arg... func_mode_install () { $opt_debug # There may be an optional sh(1) argument at the beginning of # install_prog (especially on Windows NT). if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh || # Allow the use of GNU shtool's install command. case $nonopt in *shtool*) :;; *) false;; esac; then # Aesthetically quote it. func_quote_for_eval "$nonopt" install_prog="$func_quote_for_eval_result " arg=$1 shift else install_prog= arg=$nonopt fi # The real first argument should be the name of the installation program. # Aesthetically quote it. func_quote_for_eval "$arg" install_prog+="$func_quote_for_eval_result" install_shared_prog=$install_prog case " $install_prog " in *[\\\ /]cp\ *) install_cp=: ;; *) install_cp=false ;; esac # We need to accept at least all the BSD install flags. dest= files= opts= prev= install_type= isdir=no stripme= no_mode=: for arg do arg2= if test -n "$dest"; then files+=" $dest" dest=$arg continue fi case $arg in -d) isdir=yes ;; -f) if $install_cp; then :; else prev=$arg fi ;; -g | -m | -o) prev=$arg ;; -s) stripme=" -s" continue ;; -*) ;; *) # If the previous option needed an argument, then skip it. if test -n "$prev"; then if test "x$prev" = x-m && test -n "$install_override_mode"; then arg2=$install_override_mode no_mode=false fi prev= else dest=$arg continue fi ;; esac # Aesthetically quote the argument. func_quote_for_eval "$arg" install_prog+=" $func_quote_for_eval_result" if test -n "$arg2"; then func_quote_for_eval "$arg2" fi install_shared_prog+=" $func_quote_for_eval_result" done test -z "$install_prog" && \ func_fatal_help "you must specify an install program" test -n "$prev" && \ func_fatal_help "the \`$prev' option requires an argument" if test -n "$install_override_mode" && $no_mode; then if $install_cp; then :; else func_quote_for_eval "$install_override_mode" install_shared_prog+=" -m $func_quote_for_eval_result" fi fi if test -z "$files"; then if test -z "$dest"; then func_fatal_help "no file or destination specified" else func_fatal_help "you must specify a destination" fi fi # Strip any trailing slash from the destination. func_stripname '' '/' "$dest" dest=$func_stripname_result # Check to see that the destination is a directory. test -d "$dest" && isdir=yes if test "$isdir" = yes; then destdir="$dest" destname= else func_dirname_and_basename "$dest" "" "." destdir="$func_dirname_result" destname="$func_basename_result" # Not a directory, so check to see that there is only one file specified. set dummy $files; shift test "$#" -gt 1 && \ func_fatal_help "\`$dest' is not a directory" fi case $destdir in [\\/]* | [A-Za-z]:[\\/]*) ;; *) for file in $files; do case $file in *.lo) ;; *) func_fatal_help "\`$destdir' must be an absolute directory name" ;; esac done ;; esac # This variable tells wrapper scripts just to set variables rather # than running their programs. libtool_install_magic="$magic" staticlibs= future_libdirs= current_libdirs= for file in $files; do # Do each installation. case $file in *.$libext) # Do the static libraries later. staticlibs+=" $file" ;; *.la) func_resolve_sysroot "$file" file=$func_resolve_sysroot_result # Check to see that this really is a libtool archive. func_lalib_unsafe_p "$file" \ || func_fatal_help "\`$file' is not a valid libtool archive" library_names= old_library= relink_command= func_source "$file" # Add the libdir to current_libdirs if it is the destination. if test "X$destdir" = "X$libdir"; then case "$current_libdirs " in *" $libdir "*) ;; *) current_libdirs+=" $libdir" ;; esac else # Note the libdir as a future libdir. case "$future_libdirs " in *" $libdir "*) ;; *) future_libdirs+=" $libdir" ;; esac fi func_dirname "$file" "/" "" dir="$func_dirname_result" dir+="$objdir" if test -n "$relink_command"; then # Determine the prefix the user has applied to our future dir. inst_prefix_dir=`$ECHO "$destdir" | $SED -e "s%$libdir\$%%"` # Don't allow the user to place us outside of our expected # location b/c this prevents finding dependent libraries that # are installed to the same prefix. # At present, this check doesn't affect windows .dll's that # are installed into $libdir/../bin (currently, that works fine) # but it's something to keep an eye on. test "$inst_prefix_dir" = "$destdir" && \ func_fatal_error "error: cannot install \`$file' to a directory not ending in $libdir" if test -n "$inst_prefix_dir"; then # Stick the inst_prefix_dir data into the link command. relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"` else relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%%"` fi func_warning "relinking \`$file'" func_show_eval "$relink_command" \ 'func_fatal_error "error: relink \`$file'\'' with the above command before installing it"' fi # See the names of the shared library. set dummy $library_names; shift if test -n "$1"; then realname="$1" shift srcname="$realname" test -n "$relink_command" && srcname="$realname"T # Install the shared library and build the symlinks. func_show_eval "$install_shared_prog $dir/$srcname $destdir/$realname" \ 'exit $?' tstripme="$stripme" case $host_os in cygwin* | mingw* | pw32* | cegcc*) case $realname in *.dll.a) tstripme="" ;; esac ;; esac if test -n "$tstripme" && test -n "$striplib"; then func_show_eval "$striplib $destdir/$realname" 'exit $?' fi if test "$#" -gt 0; then # Delete the old symlinks, and create new ones. # Try `ln -sf' first, because the `ln' binary might depend on # the symlink we replace! Solaris /bin/ln does not understand -f, # so we also need to try rm && ln -s. for linkname do test "$linkname" != "$realname" \ && func_show_eval "(cd $destdir && { $LN_S -f $realname $linkname || { $RM $linkname && $LN_S $realname $linkname; }; })" done fi # Do each command in the postinstall commands. lib="$destdir/$realname" func_execute_cmds "$postinstall_cmds" 'exit $?' fi # Install the pseudo-library for information purposes. func_basename "$file" name="$func_basename_result" instname="$dir/$name"i func_show_eval "$install_prog $instname $destdir/$name" 'exit $?' # Maybe install the static library, too. test -n "$old_library" && staticlibs+=" $dir/$old_library" ;; *.lo) # Install (i.e. copy) a libtool object. # Figure out destination file name, if it wasn't already specified. if test -n "$destname"; then destfile="$destdir/$destname" else func_basename "$file" destfile="$func_basename_result" destfile="$destdir/$destfile" fi # Deduce the name of the destination old-style object file. case $destfile in *.lo) func_lo2o "$destfile" staticdest=$func_lo2o_result ;; *.$objext) staticdest="$destfile" destfile= ;; *) func_fatal_help "cannot copy a libtool object to \`$destfile'" ;; esac # Install the libtool object if requested. test -n "$destfile" && \ func_show_eval "$install_prog $file $destfile" 'exit $?' # Install the old object if enabled. if test "$build_old_libs" = yes; then # Deduce the name of the old-style object file. func_lo2o "$file" staticobj=$func_lo2o_result func_show_eval "$install_prog \$staticobj \$staticdest" 'exit $?' fi exit $EXIT_SUCCESS ;; *) # Figure out destination file name, if it wasn't already specified. if test -n "$destname"; then destfile="$destdir/$destname" else func_basename "$file" destfile="$func_basename_result" destfile="$destdir/$destfile" fi # If the file is missing, and there is a .exe on the end, strip it # because it is most likely a libtool script we actually want to # install stripped_ext="" case $file in *.exe) if test ! -f "$file"; then func_stripname '' '.exe' "$file" file=$func_stripname_result stripped_ext=".exe" fi ;; esac # Do a test to see if this is really a libtool program. case $host in *cygwin* | *mingw*) if func_ltwrapper_executable_p "$file"; then func_ltwrapper_scriptname "$file" wrapper=$func_ltwrapper_scriptname_result else func_stripname '' '.exe' "$file" wrapper=$func_stripname_result fi ;; *) wrapper=$file ;; esac if func_ltwrapper_script_p "$wrapper"; then notinst_deplibs= relink_command= func_source "$wrapper" # Check the variables that should have been set. test -z "$generated_by_libtool_version" && \ func_fatal_error "invalid libtool wrapper script \`$wrapper'" finalize=yes for lib in $notinst_deplibs; do # Check to see that each library is installed. libdir= if test -f "$lib"; then func_source "$lib" fi libfile="$libdir/"`$ECHO "$lib" | $SED 's%^.*/%%g'` ### testsuite: skip nested quoting test if test -n "$libdir" && test ! -f "$libfile"; then func_warning "\`$lib' has not been installed in \`$libdir'" finalize=no fi done relink_command= func_source "$wrapper" outputname= if test "$fast_install" = no && test -n "$relink_command"; then $opt_dry_run || { if test "$finalize" = yes; then tmpdir=`func_mktempdir` func_basename "$file$stripped_ext" file="$func_basename_result" outputname="$tmpdir/$file" # Replace the output file specification. relink_command=`$ECHO "$relink_command" | $SED 's%@OUTPUT@%'"$outputname"'%g'` $opt_silent || { func_quote_for_expand "$relink_command" eval "func_echo $func_quote_for_expand_result" } if eval "$relink_command"; then : else func_error "error: relink \`$file' with the above command before installing it" $opt_dry_run || ${RM}r "$tmpdir" continue fi file="$outputname" else func_warning "cannot relink \`$file'" fi } else # Install the binary that we compiled earlier. file=`$ECHO "$file$stripped_ext" | $SED "s%\([^/]*\)$%$objdir/\1%"` fi fi # remove .exe since cygwin /usr/bin/install will append another # one anyway case $install_prog,$host in */usr/bin/install*,*cygwin*) case $file:$destfile in *.exe:*.exe) # this is ok ;; *.exe:*) destfile=$destfile.exe ;; *:*.exe) func_stripname '' '.exe' "$destfile" destfile=$func_stripname_result ;; esac ;; esac func_show_eval "$install_prog\$stripme \$file \$destfile" 'exit $?' $opt_dry_run || if test -n "$outputname"; then ${RM}r "$tmpdir" fi ;; esac done for file in $staticlibs; do func_basename "$file" name="$func_basename_result" # Set up the ranlib parameters. oldlib="$destdir/$name" func_to_tool_file "$oldlib" func_convert_file_msys_to_w32 tool_oldlib=$func_to_tool_file_result func_show_eval "$install_prog \$file \$oldlib" 'exit $?' if test -n "$stripme" && test -n "$old_striplib"; then func_show_eval "$old_striplib $tool_oldlib" 'exit $?' fi # Do each command in the postinstall commands. func_execute_cmds "$old_postinstall_cmds" 'exit $?' done test -n "$future_libdirs" && \ func_warning "remember to run \`$progname --finish$future_libdirs'" if test -n "$current_libdirs"; then # Maybe just do a dry run. $opt_dry_run && current_libdirs=" -n$current_libdirs" exec_cmd='$SHELL $progpath $preserve_args --finish$current_libdirs' else exit $EXIT_SUCCESS fi } test "$opt_mode" = install && func_mode_install ${1+"$@"} # func_generate_dlsyms outputname originator pic_p # Extract symbols from dlprefiles and create ${outputname}S.o with # a dlpreopen symbol table. func_generate_dlsyms () { $opt_debug my_outputname="$1" my_originator="$2" my_pic_p="${3-no}" my_prefix=`$ECHO "$my_originator" | sed 's%[^a-zA-Z0-9]%_%g'` my_dlsyms= if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then if test -n "$NM" && test -n "$global_symbol_pipe"; then my_dlsyms="${my_outputname}S.c" else func_error "not configured to extract global symbols from dlpreopened files" fi fi if test -n "$my_dlsyms"; then case $my_dlsyms in "") ;; *.c) # Discover the nlist of each of the dlfiles. nlist="$output_objdir/${my_outputname}.nm" func_show_eval "$RM $nlist ${nlist}S ${nlist}T" # Parse the name list into a source file. func_verbose "creating $output_objdir/$my_dlsyms" $opt_dry_run || $ECHO > "$output_objdir/$my_dlsyms" "\ /* $my_dlsyms - symbol resolution table for \`$my_outputname' dlsym emulation. */ /* Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION */ #ifdef __cplusplus extern \"C\" { #endif #if defined(__GNUC__) && (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 4)) #pragma GCC diagnostic ignored \"-Wstrict-prototypes\" #endif /* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ #if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) /* DATA imports from DLLs on WIN32 con't be const, because runtime relocations are performed -- see ld's documentation on pseudo-relocs. */ # define LT_DLSYM_CONST #elif defined(__osf__) /* This system does not cope well with relocations in const data. */ # define LT_DLSYM_CONST #else # define LT_DLSYM_CONST const #endif /* External symbol declarations for the compiler. */\ " if test "$dlself" = yes; then func_verbose "generating symbol list for \`$output'" $opt_dry_run || echo ': @PROGRAM@ ' > "$nlist" # Add our own program objects to the symbol list. progfiles=`$ECHO "$objs$old_deplibs" | $SP2NL | $SED "$lo2o" | $NL2SP` for progfile in $progfiles; do func_to_tool_file "$progfile" func_convert_file_msys_to_w32 func_verbose "extracting global C symbols from \`$func_to_tool_file_result'" $opt_dry_run || eval "$NM $func_to_tool_file_result | $global_symbol_pipe >> '$nlist'" done if test -n "$exclude_expsyms"; then $opt_dry_run || { eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T' eval '$MV "$nlist"T "$nlist"' } fi if test -n "$export_symbols_regex"; then $opt_dry_run || { eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T' eval '$MV "$nlist"T "$nlist"' } fi # Prepare the list of exported symbols if test -z "$export_symbols"; then export_symbols="$output_objdir/$outputname.exp" $opt_dry_run || { $RM $export_symbols eval "${SED} -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' case $host in *cygwin* | *mingw* | *cegcc* ) eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"' ;; esac } else $opt_dry_run || { eval "${SED} -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"' eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T' eval '$MV "$nlist"T "$nlist"' case $host in *cygwin* | *mingw* | *cegcc* ) eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' eval 'cat "$nlist" >> "$output_objdir/$outputname.def"' ;; esac } fi fi for dlprefile in $dlprefiles; do func_verbose "extracting global C symbols from \`$dlprefile'" func_basename "$dlprefile" name="$func_basename_result" case $host in *cygwin* | *mingw* | *cegcc* ) # if an import library, we need to obtain dlname if func_win32_import_lib_p "$dlprefile"; then func_tr_sh "$dlprefile" eval "curr_lafile=\$libfile_$func_tr_sh_result" dlprefile_dlbasename="" if test -n "$curr_lafile" && func_lalib_p "$curr_lafile"; then # Use subshell, to avoid clobbering current variable values dlprefile_dlname=`source "$curr_lafile" && echo "$dlname"` if test -n "$dlprefile_dlname" ; then func_basename "$dlprefile_dlname" dlprefile_dlbasename="$func_basename_result" else # no lafile. user explicitly requested -dlpreopen . $sharedlib_from_linklib_cmd "$dlprefile" dlprefile_dlbasename=$sharedlib_from_linklib_result fi fi $opt_dry_run || { if test -n "$dlprefile_dlbasename" ; then eval '$ECHO ": $dlprefile_dlbasename" >> "$nlist"' else func_warning "Could not compute DLL name from $name" eval '$ECHO ": $name " >> "$nlist"' fi func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe | $SED -e '/I __imp/d' -e 's/I __nm_/D /;s/_nm__//' >> '$nlist'" } else # not an import lib $opt_dry_run || { eval '$ECHO ": $name " >> "$nlist"' func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'" } fi ;; *) $opt_dry_run || { eval '$ECHO ": $name " >> "$nlist"' func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'" } ;; esac done $opt_dry_run || { # Make sure we have at least an empty file. test -f "$nlist" || : > "$nlist" if test -n "$exclude_expsyms"; then $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T $MV "$nlist"T "$nlist" fi # Try sorting and uniquifying the output. if $GREP -v "^: " < "$nlist" | if sort -k 3 /dev/null 2>&1; then sort -k 3 else sort +2 fi | uniq > "$nlist"S; then : else $GREP -v "^: " < "$nlist" > "$nlist"S fi if test -f "$nlist"S; then eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$my_dlsyms"' else echo '/* NONE */' >> "$output_objdir/$my_dlsyms" fi echo >> "$output_objdir/$my_dlsyms" "\ /* The mapping between symbol names and symbols. */ typedef struct { const char *name; void *address; } lt_dlsymlist; extern LT_DLSYM_CONST lt_dlsymlist lt_${my_prefix}_LTX_preloaded_symbols[]; LT_DLSYM_CONST lt_dlsymlist lt_${my_prefix}_LTX_preloaded_symbols[] = {\ { \"$my_originator\", (void *) 0 }," case $need_lib_prefix in no) eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$my_dlsyms" ;; *) eval "$global_symbol_to_c_name_address_lib_prefix" < "$nlist" >> "$output_objdir/$my_dlsyms" ;; esac echo >> "$output_objdir/$my_dlsyms" "\ {0, (void *) 0} }; /* This works around a problem in FreeBSD linker */ #ifdef FREEBSD_WORKAROUND static const void *lt_preloaded_setup() { return lt_${my_prefix}_LTX_preloaded_symbols; } #endif #ifdef __cplusplus } #endif\ " } # !$opt_dry_run pic_flag_for_symtable= case "$compile_command " in *" -static "*) ;; *) case $host in # compiling the symbol table file with pic_flag works around # a FreeBSD bug that causes programs to crash when -lm is # linked before any other PIC object. But we must not use # pic_flag when linking with -static. The problem exists in # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1. *-*-freebsd2.*|*-*-freebsd3.0*|*-*-freebsdelf3.0*) pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND" ;; *-*-hpux*) pic_flag_for_symtable=" $pic_flag" ;; *) if test "X$my_pic_p" != Xno; then pic_flag_for_symtable=" $pic_flag" fi ;; esac ;; esac symtab_cflags= for arg in $LTCFLAGS; do case $arg in -pie | -fpie | -fPIE) ;; *) symtab_cflags+=" $arg" ;; esac done # Now compile the dynamic symbol file. func_show_eval '(cd $output_objdir && $LTCC$symtab_cflags -c$no_builtin_flag$pic_flag_for_symtable "$my_dlsyms")' 'exit $?' # Clean up the generated files. func_show_eval '$RM "$output_objdir/$my_dlsyms" "$nlist" "${nlist}S" "${nlist}T"' # Transform the symbol file into the correct name. symfileobj="$output_objdir/${my_outputname}S.$objext" case $host in *cygwin* | *mingw* | *cegcc* ) if test -f "$output_objdir/$my_outputname.def"; then compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` else compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"` finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"` fi ;; *) compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"` finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"` ;; esac ;; *) func_fatal_error "unknown suffix for \`$my_dlsyms'" ;; esac else # We keep going just in case the user didn't refer to # lt_preloaded_symbols. The linker will fail if global_symbol_pipe # really was required. # Nullify the symbol file. compile_command=`$ECHO "$compile_command" | $SED "s% @SYMFILE@%%"` finalize_command=`$ECHO "$finalize_command" | $SED "s% @SYMFILE@%%"` fi } # func_win32_libid arg # return the library type of file 'arg' # # Need a lot of goo to handle *both* DLLs and import libs # Has to be a shell function in order to 'eat' the argument # that is supplied when $file_magic_command is called. # Despite the name, also deal with 64 bit binaries. func_win32_libid () { $opt_debug win32_libid_type="unknown" win32_fileres=`file -L $1 2>/dev/null` case $win32_fileres in *ar\ archive\ import\ library*) # definitely import win32_libid_type="x86 archive import" ;; *ar\ archive*) # could be an import, or static # Keep the egrep pattern in sync with the one in _LT_CHECK_MAGIC_METHOD. if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null | $EGREP 'file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' >/dev/null; then func_to_tool_file "$1" func_convert_file_msys_to_w32 win32_nmres=`eval $NM -f posix -A \"$func_to_tool_file_result\" | $SED -n -e ' 1,100{ / I /{ s,.*,import, p q } }'` case $win32_nmres in import*) win32_libid_type="x86 archive import";; *) win32_libid_type="x86 archive static";; esac fi ;; *DLL*) win32_libid_type="x86 DLL" ;; *executable*) # but shell scripts are "executable" too... case $win32_fileres in *MS\ Windows\ PE\ Intel*) win32_libid_type="x86 DLL" ;; esac ;; esac $ECHO "$win32_libid_type" } # func_cygming_dll_for_implib ARG # # Platform-specific function to extract the # name of the DLL associated with the specified # import library ARG. # Invoked by eval'ing the libtool variable # $sharedlib_from_linklib_cmd # Result is available in the variable # $sharedlib_from_linklib_result func_cygming_dll_for_implib () { $opt_debug sharedlib_from_linklib_result=`$DLLTOOL --identify-strict --identify "$1"` } # func_cygming_dll_for_implib_fallback_core SECTION_NAME LIBNAMEs # # The is the core of a fallback implementation of a # platform-specific function to extract the name of the # DLL associated with the specified import library LIBNAME. # # SECTION_NAME is either .idata$6 or .idata$7, depending # on the platform and compiler that created the implib. # # Echos the name of the DLL associated with the # specified import library. func_cygming_dll_for_implib_fallback_core () { $opt_debug match_literal=`$ECHO "$1" | $SED "$sed_make_literal_regex"` $OBJDUMP -s --section "$1" "$2" 2>/dev/null | $SED '/^Contents of section '"$match_literal"':/{ # Place marker at beginning of archive member dllname section s/.*/====MARK====/ p d } # These lines can sometimes be longer than 43 characters, but # are always uninteresting /:[ ]*file format pe[i]\{,1\}-/d /^In archive [^:]*:/d # Ensure marker is printed /^====MARK====/p # Remove all lines with less than 43 characters /^.\{43\}/!d # From remaining lines, remove first 43 characters s/^.\{43\}//' | $SED -n ' # Join marker and all lines until next marker into a single line /^====MARK====/ b para H $ b para b :para x s/\n//g # Remove the marker s/^====MARK====// # Remove trailing dots and whitespace s/[\. \t]*$// # Print /./p' | # we now have a list, one entry per line, of the stringified # contents of the appropriate section of all members of the # archive which possess that section. Heuristic: eliminate # all those which have a first or second character that is # a '.' (that is, objdump's representation of an unprintable # character.) This should work for all archives with less than # 0x302f exports -- but will fail for DLLs whose name actually # begins with a literal '.' or a single character followed by # a '.'. # # Of those that remain, print the first one. $SED -e '/^\./d;/^.\./d;q' } # func_cygming_gnu_implib_p ARG # This predicate returns with zero status (TRUE) if # ARG is a GNU/binutils-style import library. Returns # with nonzero status (FALSE) otherwise. func_cygming_gnu_implib_p () { $opt_debug func_to_tool_file "$1" func_convert_file_msys_to_w32 func_cygming_gnu_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $EGREP ' (_head_[A-Za-z0-9_]+_[ad]l*|[A-Za-z0-9_]+_[ad]l*_iname)$'` test -n "$func_cygming_gnu_implib_tmp" } # func_cygming_ms_implib_p ARG # This predicate returns with zero status (TRUE) if # ARG is an MS-style import library. Returns # with nonzero status (FALSE) otherwise. func_cygming_ms_implib_p () { $opt_debug func_to_tool_file "$1" func_convert_file_msys_to_w32 func_cygming_ms_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $GREP '_NULL_IMPORT_DESCRIPTOR'` test -n "$func_cygming_ms_implib_tmp" } # func_cygming_dll_for_implib_fallback ARG # Platform-specific function to extract the # name of the DLL associated with the specified # import library ARG. # # This fallback implementation is for use when $DLLTOOL # does not support the --identify-strict option. # Invoked by eval'ing the libtool variable # $sharedlib_from_linklib_cmd # Result is available in the variable # $sharedlib_from_linklib_result func_cygming_dll_for_implib_fallback () { $opt_debug if func_cygming_gnu_implib_p "$1" ; then # binutils import library sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$7' "$1"` elif func_cygming_ms_implib_p "$1" ; then # ms-generated import library sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$6' "$1"` else # unknown sharedlib_from_linklib_result="" fi } # func_extract_an_archive dir oldlib func_extract_an_archive () { $opt_debug f_ex_an_ar_dir="$1"; shift f_ex_an_ar_oldlib="$1" if test "$lock_old_archive_extraction" = yes; then lockfile=$f_ex_an_ar_oldlib.lock until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do func_echo "Waiting for $lockfile to be removed" sleep 2 done fi func_show_eval "(cd \$f_ex_an_ar_dir && $AR x \"\$f_ex_an_ar_oldlib\")" \ 'stat=$?; rm -f "$lockfile"; exit $stat' if test "$lock_old_archive_extraction" = yes; then $opt_dry_run || rm -f "$lockfile" fi if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then : else func_fatal_error "object name conflicts in archive: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib" fi } # func_extract_archives gentop oldlib ... func_extract_archives () { $opt_debug my_gentop="$1"; shift my_oldlibs=${1+"$@"} my_oldobjs="" my_xlib="" my_xabs="" my_xdir="" for my_xlib in $my_oldlibs; do # Extract the objects. case $my_xlib in [\\/]* | [A-Za-z]:[\\/]*) my_xabs="$my_xlib" ;; *) my_xabs=`pwd`"/$my_xlib" ;; esac func_basename "$my_xlib" my_xlib="$func_basename_result" my_xlib_u=$my_xlib while :; do case " $extracted_archives " in *" $my_xlib_u "*) func_arith $extracted_serial + 1 extracted_serial=$func_arith_result my_xlib_u=lt$extracted_serial-$my_xlib ;; *) break ;; esac done extracted_archives="$extracted_archives $my_xlib_u" my_xdir="$my_gentop/$my_xlib_u" func_mkdir_p "$my_xdir" case $host in *-darwin*) func_verbose "Extracting $my_xabs" # Do not bother doing anything if just a dry run $opt_dry_run || { darwin_orig_dir=`pwd` cd $my_xdir || exit $? darwin_archive=$my_xabs darwin_curdir=`pwd` darwin_base_archive=`basename "$darwin_archive"` darwin_arches=`$LIPO -info "$darwin_archive" 2>/dev/null | $GREP Architectures 2>/dev/null || true` if test -n "$darwin_arches"; then darwin_arches=`$ECHO "$darwin_arches" | $SED -e 's/.*are://'` darwin_arch= func_verbose "$darwin_base_archive has multiple architectures $darwin_arches" for darwin_arch in $darwin_arches ; do func_mkdir_p "unfat-$$/${darwin_base_archive}-${darwin_arch}" $LIPO -thin $darwin_arch -output "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" "${darwin_archive}" cd "unfat-$$/${darwin_base_archive}-${darwin_arch}" func_extract_an_archive "`pwd`" "${darwin_base_archive}" cd "$darwin_curdir" $RM "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" done # $darwin_arches ## Okay now we've a bunch of thin objects, gotta fatten them up :) darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print | $SED -e "$basename" | sort -u` darwin_file= darwin_files= for darwin_file in $darwin_filelist; do darwin_files=`find unfat-$$ -name $darwin_file -print | sort | $NL2SP` $LIPO -create -output "$darwin_file" $darwin_files done # $darwin_filelist $RM -rf unfat-$$ cd "$darwin_orig_dir" else cd $darwin_orig_dir func_extract_an_archive "$my_xdir" "$my_xabs" fi # $darwin_arches } # !$opt_dry_run ;; *) func_extract_an_archive "$my_xdir" "$my_xabs" ;; esac my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | sort | $NL2SP` done func_extract_archives_result="$my_oldobjs" } # func_emit_wrapper [arg=no] # # Emit a libtool wrapper script on stdout. # Don't directly open a file because we may want to # incorporate the script contents within a cygwin/mingw # wrapper executable. Must ONLY be called from within # func_mode_link because it depends on a number of variables # set therein. # # ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR # variable will take. If 'yes', then the emitted script # will assume that the directory in which it is stored is # the $objdir directory. This is a cygwin/mingw-specific # behavior. func_emit_wrapper () { func_emit_wrapper_arg1=${1-no} $ECHO "\ #! $SHELL # $output - temporary wrapper script for $objdir/$outputname # Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION # # The $output program cannot be directly executed until all the libtool # libraries that it depends on are installed. # # This wrapper script should never be moved out of the build directory. # If it is, it will not operate correctly. # Sed substitution that helps us do robust quoting. It backslashifies # metacharacters that are still active within double-quoted strings. sed_quote_subst='$sed_quote_subst' # Be Bourne compatible if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on \${1+\"\$@\"}, which # is contrary to our usage. Disable this feature. alias -g '\${1+\"\$@\"}'='\"\$@\"' setopt NO_GLOB_SUBST else case \`(set -o) 2>/dev/null\` in *posix*) set -o posix;; esac fi BIN_SH=xpg4; export BIN_SH # for Tru64 DUALCASE=1; export DUALCASE # for MKS sh # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH relink_command=\"$relink_command\" # This environment variable determines our operation mode. if test \"\$libtool_install_magic\" = \"$magic\"; then # install mode needs the following variables: generated_by_libtool_version='$macro_version' notinst_deplibs='$notinst_deplibs' else # When we are sourced in execute mode, \$file and \$ECHO are already set. if test \"\$libtool_execute_magic\" != \"$magic\"; then file=\"\$0\"" qECHO=`$ECHO "$ECHO" | $SED "$sed_quote_subst"` $ECHO "\ # A function that is used when there is no print builtin or printf. func_fallback_echo () { eval 'cat <<_LTECHO_EOF \$1 _LTECHO_EOF' } ECHO=\"$qECHO\" fi # Very basic option parsing. These options are (a) specific to # the libtool wrapper, (b) are identical between the wrapper # /script/ and the wrapper /executable/ which is used only on # windows platforms, and (c) all begin with the string "--lt-" # (application programs are unlikely to have options which match # this pattern). # # There are only two supported options: --lt-debug and # --lt-dump-script. There is, deliberately, no --lt-help. # # The first argument to this parsing function should be the # script's $0 value, followed by "$@". lt_option_debug= func_parse_lt_options () { lt_script_arg0=\$0 shift for lt_opt do case \"\$lt_opt\" in --lt-debug) lt_option_debug=1 ;; --lt-dump-script) lt_dump_D=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%/[^/]*$%%'\` test \"X\$lt_dump_D\" = \"X\$lt_script_arg0\" && lt_dump_D=. lt_dump_F=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%^.*/%%'\` cat \"\$lt_dump_D/\$lt_dump_F\" exit 0 ;; --lt-*) \$ECHO \"Unrecognized --lt- option: '\$lt_opt'\" 1>&2 exit 1 ;; esac done # Print the debug banner immediately: if test -n \"\$lt_option_debug\"; then echo \"${outputname}:${output}:\${LINENO}: libtool wrapper (GNU $PACKAGE$TIMESTAMP) $VERSION\" 1>&2 fi } # Used when --lt-debug. Prints its arguments to stdout # (redirection is the responsibility of the caller) func_lt_dump_args () { lt_dump_args_N=1; for lt_arg do \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[\$lt_dump_args_N]: \$lt_arg\" lt_dump_args_N=\`expr \$lt_dump_args_N + 1\` done } # Core function for launching the target application func_exec_program_core () { " case $host in # Backslashes separate directories on plain windows *-*-mingw | *-*-os2* | *-cegcc*) $ECHO "\ if test -n \"\$lt_option_debug\"; then \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[0]: \$progdir\\\\\$program\" 1>&2 func_lt_dump_args \${1+\"\$@\"} 1>&2 fi exec \"\$progdir\\\\\$program\" \${1+\"\$@\"} " ;; *) $ECHO "\ if test -n \"\$lt_option_debug\"; then \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[0]: \$progdir/\$program\" 1>&2 func_lt_dump_args \${1+\"\$@\"} 1>&2 fi exec \"\$progdir/\$program\" \${1+\"\$@\"} " ;; esac $ECHO "\ \$ECHO \"\$0: cannot exec \$program \$*\" 1>&2 exit 1 } # A function to encapsulate launching the target application # Strips options in the --lt-* namespace from \$@ and # launches target application with the remaining arguments. func_exec_program () { case \" \$* \" in *\\ --lt-*) for lt_wr_arg do case \$lt_wr_arg in --lt-*) ;; *) set x \"\$@\" \"\$lt_wr_arg\"; shift;; esac shift done ;; esac func_exec_program_core \${1+\"\$@\"} } # Parse options func_parse_lt_options \"\$0\" \${1+\"\$@\"} # Find the directory that this script lives in. thisdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*$%%'\` test \"x\$thisdir\" = \"x\$file\" && thisdir=. # Follow symbolic links until we get to the real thisdir. file=\`ls -ld \"\$file\" | $SED -n 's/.*-> //p'\` while test -n \"\$file\"; do destdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*\$%%'\` # If there was a directory component, then change thisdir. if test \"x\$destdir\" != \"x\$file\"; then case \"\$destdir\" in [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;; *) thisdir=\"\$thisdir/\$destdir\" ;; esac fi file=\`\$ECHO \"\$file\" | $SED 's%^.*/%%'\` file=\`ls -ld \"\$thisdir/\$file\" | $SED -n 's/.*-> //p'\` done # Usually 'no', except on cygwin/mingw when embedded into # the cwrapper. WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=$func_emit_wrapper_arg1 if test \"\$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\" = \"yes\"; then # special case for '.' if test \"\$thisdir\" = \".\"; then thisdir=\`pwd\` fi # remove .libs from thisdir case \"\$thisdir\" in *[\\\\/]$objdir ) thisdir=\`\$ECHO \"\$thisdir\" | $SED 's%[\\\\/][^\\\\/]*$%%'\` ;; $objdir ) thisdir=. ;; esac fi # Try to get the absolute directory name. absdir=\`cd \"\$thisdir\" && pwd\` test -n \"\$absdir\" && thisdir=\"\$absdir\" " if test "$fast_install" = yes; then $ECHO "\ program=lt-'$outputname'$exeext progdir=\"\$thisdir/$objdir\" if test ! -f \"\$progdir/\$program\" || { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | ${SED} 1q\`; \\ test \"X\$file\" != \"X\$progdir/\$program\"; }; then file=\"\$\$-\$program\" if test ! -d \"\$progdir\"; then $MKDIR \"\$progdir\" else $RM \"\$progdir/\$file\" fi" $ECHO "\ # relink executable if necessary if test -n \"\$relink_command\"; then if relink_command_output=\`eval \$relink_command 2>&1\`; then : else $ECHO \"\$relink_command_output\" >&2 $RM \"\$progdir/\$file\" exit 1 fi fi $MV \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null || { $RM \"\$progdir/\$program\"; $MV \"\$progdir/\$file\" \"\$progdir/\$program\"; } $RM \"\$progdir/\$file\" fi" else $ECHO "\ program='$outputname' progdir=\"\$thisdir/$objdir\" " fi $ECHO "\ if test -f \"\$progdir/\$program\"; then" # fixup the dll searchpath if we need to. # # Fix the DLL searchpath if we need to. Do this before prepending # to shlibpath, because on Windows, both are PATH and uninstalled # libraries must come first. if test -n "$dllsearchpath"; then $ECHO "\ # Add the dll search path components to the executable PATH PATH=$dllsearchpath:\$PATH " fi # Export our shlibpath_var if we have one. if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then $ECHO "\ # Add our own library path to $shlibpath_var $shlibpath_var=\"$temp_rpath\$$shlibpath_var\" # Some systems cannot cope with colon-terminated $shlibpath_var # The second colon is a workaround for a bug in BeOS R4 sed $shlibpath_var=\`\$ECHO \"\$$shlibpath_var\" | $SED 's/::*\$//'\` export $shlibpath_var " fi $ECHO "\ if test \"\$libtool_execute_magic\" != \"$magic\"; then # Run the actual program with our arguments. func_exec_program \${1+\"\$@\"} fi else # The program doesn't exist. \$ECHO \"\$0: error: \\\`\$progdir/\$program' does not exist\" 1>&2 \$ECHO \"This script is just a wrapper for \$program.\" 1>&2 \$ECHO \"See the $PACKAGE documentation for more information.\" 1>&2 exit 1 fi fi\ " } # func_emit_cwrapperexe_src # emit the source code for a wrapper executable on stdout # Must ONLY be called from within func_mode_link because # it depends on a number of variable set therein. func_emit_cwrapperexe_src () { cat < #include #ifdef _MSC_VER # include # include # include #else # include # include # ifdef __CYGWIN__ # include # endif #endif #include #include #include #include #include #include #include #include /* declarations of non-ANSI functions */ #if defined(__MINGW32__) # ifdef __STRICT_ANSI__ int _putenv (const char *); # endif #elif defined(__CYGWIN__) # ifdef __STRICT_ANSI__ char *realpath (const char *, char *); int putenv (char *); int setenv (const char *, const char *, int); # endif /* #elif defined (other platforms) ... */ #endif /* portability defines, excluding path handling macros */ #if defined(_MSC_VER) # define setmode _setmode # define stat _stat # define chmod _chmod # define getcwd _getcwd # define putenv _putenv # define S_IXUSR _S_IEXEC # ifndef _INTPTR_T_DEFINED # define _INTPTR_T_DEFINED # define intptr_t int # endif #elif defined(__MINGW32__) # define setmode _setmode # define stat _stat # define chmod _chmod # define getcwd _getcwd # define putenv _putenv #elif defined(__CYGWIN__) # define HAVE_SETENV # define FOPEN_WB "wb" /* #elif defined (other platforms) ... */ #endif #if defined(PATH_MAX) # define LT_PATHMAX PATH_MAX #elif defined(MAXPATHLEN) # define LT_PATHMAX MAXPATHLEN #else # define LT_PATHMAX 1024 #endif #ifndef S_IXOTH # define S_IXOTH 0 #endif #ifndef S_IXGRP # define S_IXGRP 0 #endif /* path handling portability macros */ #ifndef DIR_SEPARATOR # define DIR_SEPARATOR '/' # define PATH_SEPARATOR ':' #endif #if defined (_WIN32) || defined (__MSDOS__) || defined (__DJGPP__) || \ defined (__OS2__) # define HAVE_DOS_BASED_FILE_SYSTEM # define FOPEN_WB "wb" # ifndef DIR_SEPARATOR_2 # define DIR_SEPARATOR_2 '\\' # endif # ifndef PATH_SEPARATOR_2 # define PATH_SEPARATOR_2 ';' # endif #endif #ifndef DIR_SEPARATOR_2 # define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR) #else /* DIR_SEPARATOR_2 */ # define IS_DIR_SEPARATOR(ch) \ (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2)) #endif /* DIR_SEPARATOR_2 */ #ifndef PATH_SEPARATOR_2 # define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR) #else /* PATH_SEPARATOR_2 */ # define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2) #endif /* PATH_SEPARATOR_2 */ #ifndef FOPEN_WB # define FOPEN_WB "w" #endif #ifndef _O_BINARY # define _O_BINARY 0 #endif #define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type))) #define XFREE(stale) do { \ if (stale) { free ((void *) stale); stale = 0; } \ } while (0) #if defined(LT_DEBUGWRAPPER) static int lt_debug = 1; #else static int lt_debug = 0; #endif const char *program_name = "libtool-wrapper"; /* in case xstrdup fails */ void *xmalloc (size_t num); char *xstrdup (const char *string); const char *base_name (const char *name); char *find_executable (const char *wrapper); char *chase_symlinks (const char *pathspec); int make_executable (const char *path); int check_executable (const char *path); char *strendzap (char *str, const char *pat); void lt_debugprintf (const char *file, int line, const char *fmt, ...); void lt_fatal (const char *file, int line, const char *message, ...); static const char *nonnull (const char *s); static const char *nonempty (const char *s); void lt_setenv (const char *name, const char *value); char *lt_extend_str (const char *orig_value, const char *add, int to_end); void lt_update_exe_path (const char *name, const char *value); void lt_update_lib_path (const char *name, const char *value); char **prepare_spawn (char **argv); void lt_dump_script (FILE *f); EOF cat <= 0) && (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))) return 1; else return 0; } int make_executable (const char *path) { int rval = 0; struct stat st; lt_debugprintf (__FILE__, __LINE__, "(make_executable): %s\n", nonempty (path)); if ((!path) || (!*path)) return 0; if (stat (path, &st) >= 0) { rval = chmod (path, st.st_mode | S_IXOTH | S_IXGRP | S_IXUSR); } return rval; } /* Searches for the full path of the wrapper. Returns newly allocated full path name if found, NULL otherwise Does not chase symlinks, even on platforms that support them. */ char * find_executable (const char *wrapper) { int has_slash = 0; const char *p; const char *p_next; /* static buffer for getcwd */ char tmp[LT_PATHMAX + 1]; int tmp_len; char *concat_name; lt_debugprintf (__FILE__, __LINE__, "(find_executable): %s\n", nonempty (wrapper)); if ((wrapper == NULL) || (*wrapper == '\0')) return NULL; /* Absolute path? */ #if defined (HAVE_DOS_BASED_FILE_SYSTEM) if (isalpha ((unsigned char) wrapper[0]) && wrapper[1] == ':') { concat_name = xstrdup (wrapper); if (check_executable (concat_name)) return concat_name; XFREE (concat_name); } else { #endif if (IS_DIR_SEPARATOR (wrapper[0])) { concat_name = xstrdup (wrapper); if (check_executable (concat_name)) return concat_name; XFREE (concat_name); } #if defined (HAVE_DOS_BASED_FILE_SYSTEM) } #endif for (p = wrapper; *p; p++) if (*p == '/') { has_slash = 1; break; } if (!has_slash) { /* no slashes; search PATH */ const char *path = getenv ("PATH"); if (path != NULL) { for (p = path; *p; p = p_next) { const char *q; size_t p_len; for (q = p; *q; q++) if (IS_PATH_SEPARATOR (*q)) break; p_len = q - p; p_next = (*q == '\0' ? q : q + 1); if (p_len == 0) { /* empty path: current directory */ if (getcwd (tmp, LT_PATHMAX) == NULL) lt_fatal (__FILE__, __LINE__, "getcwd failed: %s", nonnull (strerror (errno))); tmp_len = strlen (tmp); concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); memcpy (concat_name, tmp, tmp_len); concat_name[tmp_len] = '/'; strcpy (concat_name + tmp_len + 1, wrapper); } else { concat_name = XMALLOC (char, p_len + 1 + strlen (wrapper) + 1); memcpy (concat_name, p, p_len); concat_name[p_len] = '/'; strcpy (concat_name + p_len + 1, wrapper); } if (check_executable (concat_name)) return concat_name; XFREE (concat_name); } } /* not found in PATH; assume curdir */ } /* Relative path | not found in path: prepend cwd */ if (getcwd (tmp, LT_PATHMAX) == NULL) lt_fatal (__FILE__, __LINE__, "getcwd failed: %s", nonnull (strerror (errno))); tmp_len = strlen (tmp); concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); memcpy (concat_name, tmp, tmp_len); concat_name[tmp_len] = '/'; strcpy (concat_name + tmp_len + 1, wrapper); if (check_executable (concat_name)) return concat_name; XFREE (concat_name); return NULL; } char * chase_symlinks (const char *pathspec) { #ifndef S_ISLNK return xstrdup (pathspec); #else char buf[LT_PATHMAX]; struct stat s; char *tmp_pathspec = xstrdup (pathspec); char *p; int has_symlinks = 0; while (strlen (tmp_pathspec) && !has_symlinks) { lt_debugprintf (__FILE__, __LINE__, "checking path component for symlinks: %s\n", tmp_pathspec); if (lstat (tmp_pathspec, &s) == 0) { if (S_ISLNK (s.st_mode) != 0) { has_symlinks = 1; break; } /* search backwards for last DIR_SEPARATOR */ p = tmp_pathspec + strlen (tmp_pathspec) - 1; while ((p > tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) p--; if ((p == tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) { /* no more DIR_SEPARATORS left */ break; } *p = '\0'; } else { lt_fatal (__FILE__, __LINE__, "error accessing file \"%s\": %s", tmp_pathspec, nonnull (strerror (errno))); } } XFREE (tmp_pathspec); if (!has_symlinks) { return xstrdup (pathspec); } tmp_pathspec = realpath (pathspec, buf); if (tmp_pathspec == 0) { lt_fatal (__FILE__, __LINE__, "could not follow symlinks for %s", pathspec); } return xstrdup (tmp_pathspec); #endif } char * strendzap (char *str, const char *pat) { size_t len, patlen; assert (str != NULL); assert (pat != NULL); len = strlen (str); patlen = strlen (pat); if (patlen <= len) { str += len - patlen; if (strcmp (str, pat) == 0) *str = '\0'; } return str; } void lt_debugprintf (const char *file, int line, const char *fmt, ...) { va_list args; if (lt_debug) { (void) fprintf (stderr, "%s:%s:%d: ", program_name, file, line); va_start (args, fmt); (void) vfprintf (stderr, fmt, args); va_end (args); } } static void lt_error_core (int exit_status, const char *file, int line, const char *mode, const char *message, va_list ap) { fprintf (stderr, "%s:%s:%d: %s: ", program_name, file, line, mode); vfprintf (stderr, message, ap); fprintf (stderr, ".\n"); if (exit_status >= 0) exit (exit_status); } void lt_fatal (const char *file, int line, const char *message, ...) { va_list ap; va_start (ap, message); lt_error_core (EXIT_FAILURE, file, line, "FATAL", message, ap); va_end (ap); } static const char * nonnull (const char *s) { return s ? s : "(null)"; } static const char * nonempty (const char *s) { return (s && !*s) ? "(empty)" : nonnull (s); } void lt_setenv (const char *name, const char *value) { lt_debugprintf (__FILE__, __LINE__, "(lt_setenv) setting '%s' to '%s'\n", nonnull (name), nonnull (value)); { #ifdef HAVE_SETENV /* always make a copy, for consistency with !HAVE_SETENV */ char *str = xstrdup (value); setenv (name, str, 1); #else int len = strlen (name) + 1 + strlen (value) + 1; char *str = XMALLOC (char, len); sprintf (str, "%s=%s", name, value); if (putenv (str) != EXIT_SUCCESS) { XFREE (str); } #endif } } char * lt_extend_str (const char *orig_value, const char *add, int to_end) { char *new_value; if (orig_value && *orig_value) { int orig_value_len = strlen (orig_value); int add_len = strlen (add); new_value = XMALLOC (char, add_len + orig_value_len + 1); if (to_end) { strcpy (new_value, orig_value); strcpy (new_value + orig_value_len, add); } else { strcpy (new_value, add); strcpy (new_value + add_len, orig_value); } } else { new_value = xstrdup (add); } return new_value; } void lt_update_exe_path (const char *name, const char *value) { lt_debugprintf (__FILE__, __LINE__, "(lt_update_exe_path) modifying '%s' by prepending '%s'\n", nonnull (name), nonnull (value)); if (name && *name && value && *value) { char *new_value = lt_extend_str (getenv (name), value, 0); /* some systems can't cope with a ':'-terminated path #' */ int len = strlen (new_value); while (((len = strlen (new_value)) > 0) && IS_PATH_SEPARATOR (new_value[len-1])) { new_value[len-1] = '\0'; } lt_setenv (name, new_value); XFREE (new_value); } } void lt_update_lib_path (const char *name, const char *value) { lt_debugprintf (__FILE__, __LINE__, "(lt_update_lib_path) modifying '%s' by prepending '%s'\n", nonnull (name), nonnull (value)); if (name && *name && value && *value) { char *new_value = lt_extend_str (getenv (name), value, 0); lt_setenv (name, new_value); XFREE (new_value); } } EOF case $host_os in mingw*) cat <<"EOF" /* Prepares an argument vector before calling spawn(). Note that spawn() does not by itself call the command interpreter (getenv ("COMSPEC") != NULL ? getenv ("COMSPEC") : ({ OSVERSIONINFO v; v.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); GetVersionEx(&v); v.dwPlatformId == VER_PLATFORM_WIN32_NT; }) ? "cmd.exe" : "command.com"). Instead it simply concatenates the arguments, separated by ' ', and calls CreateProcess(). We must quote the arguments since Win32 CreateProcess() interprets characters like ' ', '\t', '\\', '"' (but not '<' and '>') in a special way: - Space and tab are interpreted as delimiters. They are not treated as delimiters if they are surrounded by double quotes: "...". - Unescaped double quotes are removed from the input. Their only effect is that within double quotes, space and tab are treated like normal characters. - Backslashes not followed by double quotes are not special. - But 2*n+1 backslashes followed by a double quote become n backslashes followed by a double quote (n >= 0): \" -> " \\\" -> \" \\\\\" -> \\" */ #define SHELL_SPECIAL_CHARS "\"\\ \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" #define SHELL_SPACE_CHARS " \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" char ** prepare_spawn (char **argv) { size_t argc; char **new_argv; size_t i; /* Count number of arguments. */ for (argc = 0; argv[argc] != NULL; argc++) ; /* Allocate new argument vector. */ new_argv = XMALLOC (char *, argc + 1); /* Put quoted arguments into the new argument vector. */ for (i = 0; i < argc; i++) { const char *string = argv[i]; if (string[0] == '\0') new_argv[i] = xstrdup ("\"\""); else if (strpbrk (string, SHELL_SPECIAL_CHARS) != NULL) { int quote_around = (strpbrk (string, SHELL_SPACE_CHARS) != NULL); size_t length; unsigned int backslashes; const char *s; char *quoted_string; char *p; length = 0; backslashes = 0; if (quote_around) length++; for (s = string; *s != '\0'; s++) { char c = *s; if (c == '"') length += backslashes + 1; length++; if (c == '\\') backslashes++; else backslashes = 0; } if (quote_around) length += backslashes + 1; quoted_string = XMALLOC (char, length + 1); p = quoted_string; backslashes = 0; if (quote_around) *p++ = '"'; for (s = string; *s != '\0'; s++) { char c = *s; if (c == '"') { unsigned int j; for (j = backslashes + 1; j > 0; j--) *p++ = '\\'; } *p++ = c; if (c == '\\') backslashes++; else backslashes = 0; } if (quote_around) { unsigned int j; for (j = backslashes; j > 0; j--) *p++ = '\\'; *p++ = '"'; } *p = '\0'; new_argv[i] = quoted_string; } else new_argv[i] = (char *) string; } new_argv[argc] = NULL; return new_argv; } EOF ;; esac cat <<"EOF" void lt_dump_script (FILE* f) { EOF func_emit_wrapper yes | $SED -n -e ' s/^\(.\{79\}\)\(..*\)/\1\ \2/ h s/\([\\"]\)/\\\1/g s/$/\\n/ s/\([^\n]*\).*/ fputs ("\1", f);/p g D' cat <<"EOF" } EOF } # end: func_emit_cwrapperexe_src # func_win32_import_lib_p ARG # True if ARG is an import lib, as indicated by $file_magic_cmd func_win32_import_lib_p () { $opt_debug case `eval $file_magic_cmd \"\$1\" 2>/dev/null | $SED -e 10q` in *import*) : ;; *) false ;; esac } # func_mode_link arg... func_mode_link () { $opt_debug case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) # It is impossible to link a dll without this setting, and # we shouldn't force the makefile maintainer to figure out # which system we are compiling for in order to pass an extra # flag for every libtool invocation. # allow_undefined=no # FIXME: Unfortunately, there are problems with the above when trying # to make a dll which has undefined symbols, in which case not # even a static library is built. For now, we need to specify # -no-undefined on the libtool link line when we can be certain # that all symbols are satisfied, otherwise we get a static library. allow_undefined=yes ;; *) allow_undefined=yes ;; esac libtool_args=$nonopt base_compile="$nonopt $@" compile_command=$nonopt finalize_command=$nonopt compile_rpath= finalize_rpath= compile_shlibpath= finalize_shlibpath= convenience= old_convenience= deplibs= old_deplibs= compiler_flags= linker_flags= dllsearchpath= lib_search_path=`pwd` inst_prefix_dir= new_inherited_linker_flags= avoid_version=no bindir= dlfiles= dlprefiles= dlself=no export_dynamic=no export_symbols= export_symbols_regex= generated= libobjs= ltlibs= module=no no_install=no objs= non_pic_objects= precious_files_regex= prefer_static_libs=no preload=no prev= prevarg= release= rpath= xrpath= perm_rpath= temp_rpath= thread_safe=no vinfo= vinfo_number=no weak_libs= single_module="${wl}-single_module" func_infer_tag $base_compile # We need to know -static, to get the right output filenames. for arg do case $arg in -shared) test "$build_libtool_libs" != yes && \ func_fatal_configuration "can not build a shared library" build_old_libs=no break ;; -all-static | -static | -static-libtool-libs) case $arg in -all-static) if test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then func_warning "complete static linking is impossible in this configuration" fi if test -n "$link_static_flag"; then dlopen_self=$dlopen_self_static fi prefer_static_libs=yes ;; -static) if test -z "$pic_flag" && test -n "$link_static_flag"; then dlopen_self=$dlopen_self_static fi prefer_static_libs=built ;; -static-libtool-libs) if test -z "$pic_flag" && test -n "$link_static_flag"; then dlopen_self=$dlopen_self_static fi prefer_static_libs=yes ;; esac build_libtool_libs=no build_old_libs=yes break ;; esac done # See if our shared archives depend on static archives. test -n "$old_archive_from_new_cmds" && build_old_libs=yes # Go through the arguments, transforming them on the way. while test "$#" -gt 0; do arg="$1" shift func_quote_for_eval "$arg" qarg=$func_quote_for_eval_unquoted_result libtool_args+=" $func_quote_for_eval_result" # If the previous option needs an argument, assign it. if test -n "$prev"; then case $prev in output) compile_command+=" @OUTPUT@" finalize_command+=" @OUTPUT@" ;; esac case $prev in bindir) bindir="$arg" prev= continue ;; dlfiles|dlprefiles) if test "$preload" = no; then # Add the symbol object into the linking commands. compile_command+=" @SYMFILE@" finalize_command+=" @SYMFILE@" preload=yes fi case $arg in *.la | *.lo) ;; # We handle these cases below. force) if test "$dlself" = no; then dlself=needless export_dynamic=yes fi prev= continue ;; self) if test "$prev" = dlprefiles; then dlself=yes elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then dlself=yes else dlself=needless export_dynamic=yes fi prev= continue ;; *) if test "$prev" = dlfiles; then dlfiles+=" $arg" else dlprefiles+=" $arg" fi prev= continue ;; esac ;; expsyms) export_symbols="$arg" test -f "$arg" \ || func_fatal_error "symbol file \`$arg' does not exist" prev= continue ;; expsyms_regex) export_symbols_regex="$arg" prev= continue ;; framework) case $host in *-*-darwin*) case "$deplibs " in *" $qarg.ltframework "*) ;; *) deplibs+=" $qarg.ltframework" # this is fixed later ;; esac ;; esac prev= continue ;; inst_prefix) inst_prefix_dir="$arg" prev= continue ;; objectlist) if test -f "$arg"; then save_arg=$arg moreargs= for fil in `cat "$save_arg"` do # moreargs+=" $fil" arg=$fil # A libtool-controlled object. # Check to see that this really is a libtool object. if func_lalib_unsafe_p "$arg"; then pic_object= non_pic_object= # Read the .lo file func_source "$arg" if test -z "$pic_object" || test -z "$non_pic_object" || test "$pic_object" = none && test "$non_pic_object" = none; then func_fatal_error "cannot find name of object for \`$arg'" fi # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir="$func_dirname_result" if test "$pic_object" != none; then # Prepend the subdirectory the object is found in. pic_object="$xdir$pic_object" if test "$prev" = dlfiles; then if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then dlfiles+=" $pic_object" prev= continue else # If libtool objects are unsupported, then we need to preload. prev=dlprefiles fi fi # CHECK ME: I think I busted this. -Ossama if test "$prev" = dlprefiles; then # Preload the old-style object. dlprefiles+=" $pic_object" prev= fi # A PIC object. libobjs+=" $pic_object" arg="$pic_object" fi # Non-PIC object. if test "$non_pic_object" != none; then # Prepend the subdirectory the object is found in. non_pic_object="$xdir$non_pic_object" # A standard non-PIC object non_pic_objects+=" $non_pic_object" if test -z "$pic_object" || test "$pic_object" = none ; then arg="$non_pic_object" fi else # If the PIC object exists, use it instead. # $xdir was prepended to $pic_object above. non_pic_object="$pic_object" non_pic_objects+=" $non_pic_object" fi else # Only an error if not doing a dry-run. if $opt_dry_run; then # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir="$func_dirname_result" func_lo2o "$arg" pic_object=$xdir$objdir/$func_lo2o_result non_pic_object=$xdir$func_lo2o_result libobjs+=" $pic_object" non_pic_objects+=" $non_pic_object" else func_fatal_error "\`$arg' is not a valid libtool object" fi fi done else func_fatal_error "link input file \`$arg' does not exist" fi arg=$save_arg prev= continue ;; precious_regex) precious_files_regex="$arg" prev= continue ;; release) release="-$arg" prev= continue ;; rpath | xrpath) # We need an absolute path. case $arg in [\\/]* | [A-Za-z]:[\\/]*) ;; *) func_fatal_error "only absolute run-paths are allowed" ;; esac if test "$prev" = rpath; then case "$rpath " in *" $arg "*) ;; *) rpath+=" $arg" ;; esac else case "$xrpath " in *" $arg "*) ;; *) xrpath+=" $arg" ;; esac fi prev= continue ;; shrext) shrext_cmds="$arg" prev= continue ;; weak) weak_libs+=" $arg" prev= continue ;; xcclinker) linker_flags+=" $qarg" compiler_flags+=" $qarg" prev= compile_command+=" $qarg" finalize_command+=" $qarg" continue ;; xcompiler) compiler_flags+=" $qarg" prev= compile_command+=" $qarg" finalize_command+=" $qarg" continue ;; xlinker) linker_flags+=" $qarg" compiler_flags+=" $wl$qarg" prev= compile_command+=" $wl$qarg" finalize_command+=" $wl$qarg" continue ;; *) eval "$prev=\"\$arg\"" prev= continue ;; esac fi # test -n "$prev" prevarg="$arg" case $arg in -all-static) if test -n "$link_static_flag"; then # See comment for -static flag below, for more details. compile_command+=" $link_static_flag" finalize_command+=" $link_static_flag" fi continue ;; -allow-undefined) # FIXME: remove this flag sometime in the future. func_fatal_error "\`-allow-undefined' must not be used because it is the default" ;; -avoid-version) avoid_version=yes continue ;; -bindir) prev=bindir continue ;; -dlopen) prev=dlfiles continue ;; -dlpreopen) prev=dlprefiles continue ;; -export-dynamic) export_dynamic=yes continue ;; -export-symbols | -export-symbols-regex) if test -n "$export_symbols" || test -n "$export_symbols_regex"; then func_fatal_error "more than one -exported-symbols argument is not allowed" fi if test "X$arg" = "X-export-symbols"; then prev=expsyms else prev=expsyms_regex fi continue ;; -framework) prev=framework continue ;; -inst-prefix-dir) prev=inst_prefix continue ;; # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:* # so, if we see these flags be careful not to treat them like -L -L[A-Z][A-Z]*:*) case $with_gcc/$host in no/*-*-irix* | /*-*-irix*) compile_command+=" $arg" finalize_command+=" $arg" ;; esac continue ;; -L*) func_stripname "-L" '' "$arg" if test -z "$func_stripname_result"; then if test "$#" -gt 0; then func_fatal_error "require no space between \`-L' and \`$1'" else func_fatal_error "need path for \`-L' option" fi fi func_resolve_sysroot "$func_stripname_result" dir=$func_resolve_sysroot_result # We need an absolute path. case $dir in [\\/]* | [A-Za-z]:[\\/]*) ;; *) absdir=`cd "$dir" && pwd` test -z "$absdir" && \ func_fatal_error "cannot determine absolute directory name of \`$dir'" dir="$absdir" ;; esac case "$deplibs " in *" -L$dir "* | *" $arg "*) # Will only happen for absolute or sysroot arguments ;; *) # Preserve sysroot, but never include relative directories case $dir in [\\/]* | [A-Za-z]:[\\/]* | =*) deplibs+=" $arg" ;; *) deplibs+=" -L$dir" ;; esac lib_search_path+=" $dir" ;; esac case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) testbindir=`$ECHO "$dir" | $SED 's*/lib$*/bin*'` case :$dllsearchpath: in *":$dir:"*) ;; ::) dllsearchpath=$dir;; *) dllsearchpath+=":$dir";; esac case :$dllsearchpath: in *":$testbindir:"*) ;; ::) dllsearchpath=$testbindir;; *) dllsearchpath+=":$testbindir";; esac ;; esac continue ;; -l*) if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc* | *-*-haiku*) # These systems don't actually have a C or math library (as such) continue ;; *-*-os2*) # These systems don't actually have a C library (as such) test "X$arg" = "X-lc" && continue ;; *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) # Do not include libc due to us having libc/libc_r. test "X$arg" = "X-lc" && continue ;; *-*-rhapsody* | *-*-darwin1.[012]) # Rhapsody C and math libraries are in the System framework deplibs+=" System.ltframework" continue ;; *-*-sco3.2v5* | *-*-sco5v6*) # Causes problems with __ctype test "X$arg" = "X-lc" && continue ;; *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) # Compiler inserts libc in the correct place for threads to work test "X$arg" = "X-lc" && continue ;; esac elif test "X$arg" = "X-lc_r"; then case $host in *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) # Do not include libc_r directly, use -pthread flag. continue ;; esac fi deplibs+=" $arg" continue ;; -module) module=yes continue ;; # Tru64 UNIX uses -model [arg] to determine the layout of C++ # classes, name mangling, and exception handling. # Darwin uses the -arch flag to determine output architecture. -model|-arch|-isysroot|--sysroot) compiler_flags+=" $arg" compile_command+=" $arg" finalize_command+=" $arg" prev=xcompiler continue ;; -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \ |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*) compiler_flags+=" $arg" compile_command+=" $arg" finalize_command+=" $arg" case "$new_inherited_linker_flags " in *" $arg "*) ;; * ) new_inherited_linker_flags+=" $arg" ;; esac continue ;; -multi_module) single_module="${wl}-multi_module" continue ;; -no-fast-install) fast_install=no continue ;; -no-install) case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*) # The PATH hackery in wrapper scripts is required on Windows # and Darwin in order for the loader to find any dlls it needs. func_warning "\`-no-install' is ignored for $host" func_warning "assuming \`-no-fast-install' instead" fast_install=no ;; *) no_install=yes ;; esac continue ;; -no-undefined) allow_undefined=no continue ;; -objectlist) prev=objectlist continue ;; -o) prev=output ;; -precious-files-regex) prev=precious_regex continue ;; -release) prev=release continue ;; -rpath) prev=rpath continue ;; -R) prev=xrpath continue ;; -R*) func_stripname '-R' '' "$arg" dir=$func_stripname_result # We need an absolute path. case $dir in [\\/]* | [A-Za-z]:[\\/]*) ;; =*) func_stripname '=' '' "$dir" dir=$lt_sysroot$func_stripname_result ;; *) func_fatal_error "only absolute run-paths are allowed" ;; esac case "$xrpath " in *" $dir "*) ;; *) xrpath+=" $dir" ;; esac continue ;; -shared) # The effects of -shared are defined in a previous loop. continue ;; -shrext) prev=shrext continue ;; -static | -static-libtool-libs) # The effects of -static are defined in a previous loop. # We used to do the same as -all-static on platforms that # didn't have a PIC flag, but the assumption that the effects # would be equivalent was wrong. It would break on at least # Digital Unix and AIX. continue ;; -thread-safe) thread_safe=yes continue ;; -version-info) prev=vinfo continue ;; -version-number) prev=vinfo vinfo_number=yes continue ;; -weak) prev=weak continue ;; -Wc,*) func_stripname '-Wc,' '' "$arg" args=$func_stripname_result arg= save_ifs="$IFS"; IFS=',' for flag in $args; do IFS="$save_ifs" func_quote_for_eval "$flag" arg+=" $func_quote_for_eval_result" compiler_flags+=" $func_quote_for_eval_result" done IFS="$save_ifs" func_stripname ' ' '' "$arg" arg=$func_stripname_result ;; -Wl,*) func_stripname '-Wl,' '' "$arg" args=$func_stripname_result arg= save_ifs="$IFS"; IFS=',' for flag in $args; do IFS="$save_ifs" func_quote_for_eval "$flag" arg+=" $wl$func_quote_for_eval_result" compiler_flags+=" $wl$func_quote_for_eval_result" linker_flags+=" $func_quote_for_eval_result" done IFS="$save_ifs" func_stripname ' ' '' "$arg" arg=$func_stripname_result ;; -Xcompiler) prev=xcompiler continue ;; -Xlinker) prev=xlinker continue ;; -XCClinker) prev=xcclinker continue ;; # -msg_* for osf cc -msg_*) func_quote_for_eval "$arg" arg="$func_quote_for_eval_result" ;; # Flags to be passed through unchanged, with rationale: # -64, -mips[0-9] enable 64-bit mode for the SGI compiler # -r[0-9][0-9]* specify processor for the SGI compiler # -xarch=*, -xtarget=* enable 64-bit mode for the Sun compiler # +DA*, +DD* enable 64-bit mode for the HP compiler # -q* compiler args for the IBM compiler # -m*, -t[45]*, -txscale* architecture-specific flags for GCC # -F/path path to uninstalled frameworks, gcc on darwin # -p, -pg, --coverage, -fprofile-* profiling flags for GCC # @file GCC response files # -tp=* Portland pgcc target processor selection # --sysroot=* for sysroot support # -O*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \ -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \ -O*|-flto*|-fwhopr*|-fuse-linker-plugin) func_quote_for_eval "$arg" arg="$func_quote_for_eval_result" compile_command+=" $arg" finalize_command+=" $arg" compiler_flags+=" $arg" continue ;; # Some other compiler flag. -* | +*) func_quote_for_eval "$arg" arg="$func_quote_for_eval_result" ;; *.$objext) # A standard object. objs+=" $arg" ;; *.lo) # A libtool-controlled object. # Check to see that this really is a libtool object. if func_lalib_unsafe_p "$arg"; then pic_object= non_pic_object= # Read the .lo file func_source "$arg" if test -z "$pic_object" || test -z "$non_pic_object" || test "$pic_object" = none && test "$non_pic_object" = none; then func_fatal_error "cannot find name of object for \`$arg'" fi # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir="$func_dirname_result" if test "$pic_object" != none; then # Prepend the subdirectory the object is found in. pic_object="$xdir$pic_object" if test "$prev" = dlfiles; then if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then dlfiles+=" $pic_object" prev= continue else # If libtool objects are unsupported, then we need to preload. prev=dlprefiles fi fi # CHECK ME: I think I busted this. -Ossama if test "$prev" = dlprefiles; then # Preload the old-style object. dlprefiles+=" $pic_object" prev= fi # A PIC object. libobjs+=" $pic_object" arg="$pic_object" fi # Non-PIC object. if test "$non_pic_object" != none; then # Prepend the subdirectory the object is found in. non_pic_object="$xdir$non_pic_object" # A standard non-PIC object non_pic_objects+=" $non_pic_object" if test -z "$pic_object" || test "$pic_object" = none ; then arg="$non_pic_object" fi else # If the PIC object exists, use it instead. # $xdir was prepended to $pic_object above. non_pic_object="$pic_object" non_pic_objects+=" $non_pic_object" fi else # Only an error if not doing a dry-run. if $opt_dry_run; then # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir="$func_dirname_result" func_lo2o "$arg" pic_object=$xdir$objdir/$func_lo2o_result non_pic_object=$xdir$func_lo2o_result libobjs+=" $pic_object" non_pic_objects+=" $non_pic_object" else func_fatal_error "\`$arg' is not a valid libtool object" fi fi ;; *.$libext) # An archive. deplibs+=" $arg" old_deplibs+=" $arg" continue ;; *.la) # A libtool-controlled library. func_resolve_sysroot "$arg" if test "$prev" = dlfiles; then # This library was specified with -dlopen. dlfiles+=" $func_resolve_sysroot_result" prev= elif test "$prev" = dlprefiles; then # The library was specified with -dlpreopen. dlprefiles+=" $func_resolve_sysroot_result" prev= else deplibs+=" $func_resolve_sysroot_result" fi continue ;; # Some other compiler argument. *) # Unknown arguments in both finalize_command and compile_command need # to be aesthetically quoted because they are evaled later. func_quote_for_eval "$arg" arg="$func_quote_for_eval_result" ;; esac # arg # Now actually substitute the argument into the commands. if test -n "$arg"; then compile_command+=" $arg" finalize_command+=" $arg" fi done # argument parsing loop test -n "$prev" && \ func_fatal_help "the \`$prevarg' option requires an argument" if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then eval arg=\"$export_dynamic_flag_spec\" compile_command+=" $arg" finalize_command+=" $arg" fi oldlibs= # calculate the name of the file, without its directory func_basename "$output" outputname="$func_basename_result" libobjs_save="$libobjs" if test -n "$shlibpath_var"; then # get the directories listed in $shlibpath_var eval shlib_search_path=\`\$ECHO \"\${$shlibpath_var}\" \| \$SED \'s/:/ /g\'\` else shlib_search_path= fi eval sys_lib_search_path=\"$sys_lib_search_path_spec\" eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\" func_dirname "$output" "/" "" output_objdir="$func_dirname_result$objdir" func_to_tool_file "$output_objdir/" tool_output_objdir=$func_to_tool_file_result # Create the object directory. func_mkdir_p "$output_objdir" # Determine the type of output case $output in "") func_fatal_help "you must specify an output file" ;; *.$libext) linkmode=oldlib ;; *.lo | *.$objext) linkmode=obj ;; *.la) linkmode=lib ;; *) linkmode=prog ;; # Anything else should be a program. esac specialdeplibs= libs= # Find all interdependent deplibs by searching for libraries # that are linked more than once (e.g. -la -lb -la) for deplib in $deplibs; do if $opt_preserve_dup_deps ; then case "$libs " in *" $deplib "*) specialdeplibs+=" $deplib" ;; esac fi libs+=" $deplib" done if test "$linkmode" = lib; then libs="$predeps $libs $compiler_lib_search_path $postdeps" # Compute libraries that are listed more than once in $predeps # $postdeps and mark them as special (i.e., whose duplicates are # not to be eliminated). pre_post_deps= if $opt_duplicate_compiler_generated_deps; then for pre_post_dep in $predeps $postdeps; do case "$pre_post_deps " in *" $pre_post_dep "*) specialdeplibs+=" $pre_post_deps" ;; esac pre_post_deps+=" $pre_post_dep" done fi pre_post_deps= fi deplibs= newdependency_libs= newlib_search_path= need_relink=no # whether we're linking any uninstalled libtool libraries notinst_deplibs= # not-installed libtool libraries notinst_path= # paths that contain not-installed libtool libraries case $linkmode in lib) passes="conv dlpreopen link" for file in $dlfiles $dlprefiles; do case $file in *.la) ;; *) func_fatal_help "libraries can \`-dlopen' only libtool libraries: $file" ;; esac done ;; prog) compile_deplibs= finalize_deplibs= alldeplibs=no newdlfiles= newdlprefiles= passes="conv scan dlopen dlpreopen link" ;; *) passes="conv" ;; esac for pass in $passes; do # The preopen pass in lib mode reverses $deplibs; put it back here # so that -L comes before libs that need it for instance... if test "$linkmode,$pass" = "lib,link"; then ## FIXME: Find the place where the list is rebuilt in the wrong ## order, and fix it there properly tmp_deplibs= for deplib in $deplibs; do tmp_deplibs="$deplib $tmp_deplibs" done deplibs="$tmp_deplibs" fi if test "$linkmode,$pass" = "lib,link" || test "$linkmode,$pass" = "prog,scan"; then libs="$deplibs" deplibs= fi if test "$linkmode" = prog; then case $pass in dlopen) libs="$dlfiles" ;; dlpreopen) libs="$dlprefiles" ;; link) libs="$deplibs %DEPLIBS%" test "X$link_all_deplibs" != Xno && libs="$libs $dependency_libs" ;; esac fi if test "$linkmode,$pass" = "lib,dlpreopen"; then # Collect and forward deplibs of preopened libtool libs for lib in $dlprefiles; do # Ignore non-libtool-libs dependency_libs= func_resolve_sysroot "$lib" case $lib in *.la) func_source "$func_resolve_sysroot_result" ;; esac # Collect preopened libtool deplibs, except any this library # has declared as weak libs for deplib in $dependency_libs; do func_basename "$deplib" deplib_base=$func_basename_result case " $weak_libs " in *" $deplib_base "*) ;; *) deplibs+=" $deplib" ;; esac done done libs="$dlprefiles" fi if test "$pass" = dlopen; then # Collect dlpreopened libraries save_deplibs="$deplibs" deplibs= fi for deplib in $libs; do lib= found=no case $deplib in -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \ |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*) if test "$linkmode,$pass" = "prog,link"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else compiler_flags+=" $deplib" if test "$linkmode" = lib ; then case "$new_inherited_linker_flags " in *" $deplib "*) ;; * ) new_inherited_linker_flags+=" $deplib" ;; esac fi fi continue ;; -l*) if test "$linkmode" != lib && test "$linkmode" != prog; then func_warning "\`-l' is ignored for archives/objects" continue fi func_stripname '-l' '' "$deplib" name=$func_stripname_result if test "$linkmode" = lib; then searchdirs="$newlib_search_path $lib_search_path $compiler_lib_search_dirs $sys_lib_search_path $shlib_search_path" else searchdirs="$newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path" fi for searchdir in $searchdirs; do for search_ext in .la $std_shrext .so .a; do # Search the libtool library lib="$searchdir/lib${name}${search_ext}" if test -f "$lib"; then if test "$search_ext" = ".la"; then found=yes else found=no fi break 2 fi done done if test "$found" != yes; then # deplib doesn't seem to be a libtool library if test "$linkmode,$pass" = "prog,link"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else deplibs="$deplib $deplibs" test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" fi continue else # deplib is a libtool library # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib, # We need to do some special things here, and not later. if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then case " $predeps $postdeps " in *" $deplib "*) if func_lalib_p "$lib"; then library_names= old_library= func_source "$lib" for l in $old_library $library_names; do ll="$l" done if test "X$ll" = "X$old_library" ; then # only static version available found=no func_dirname "$lib" "" "." ladir="$func_dirname_result" lib=$ladir/$old_library if test "$linkmode,$pass" = "prog,link"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else deplibs="$deplib $deplibs" test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" fi continue fi fi ;; *) ;; esac fi fi ;; # -l *.ltframework) if test "$linkmode,$pass" = "prog,link"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else deplibs="$deplib $deplibs" if test "$linkmode" = lib ; then case "$new_inherited_linker_flags " in *" $deplib "*) ;; * ) new_inherited_linker_flags+=" $deplib" ;; esac fi fi continue ;; -L*) case $linkmode in lib) deplibs="$deplib $deplibs" test "$pass" = conv && continue newdependency_libs="$deplib $newdependency_libs" func_stripname '-L' '' "$deplib" func_resolve_sysroot "$func_stripname_result" newlib_search_path+=" $func_resolve_sysroot_result" ;; prog) if test "$pass" = conv; then deplibs="$deplib $deplibs" continue fi if test "$pass" = scan; then deplibs="$deplib $deplibs" else compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" fi func_stripname '-L' '' "$deplib" func_resolve_sysroot "$func_stripname_result" newlib_search_path+=" $func_resolve_sysroot_result" ;; *) func_warning "\`-L' is ignored for archives/objects" ;; esac # linkmode continue ;; # -L -R*) if test "$pass" = link; then func_stripname '-R' '' "$deplib" func_resolve_sysroot "$func_stripname_result" dir=$func_resolve_sysroot_result # Make sure the xrpath contains only unique directories. case "$xrpath " in *" $dir "*) ;; *) xrpath+=" $dir" ;; esac fi deplibs="$deplib $deplibs" continue ;; *.la) func_resolve_sysroot "$deplib" lib=$func_resolve_sysroot_result ;; *.$libext) if test "$pass" = conv; then deplibs="$deplib $deplibs" continue fi case $linkmode in lib) # Linking convenience modules into shared libraries is allowed, # but linking other static libraries is non-portable. case " $dlpreconveniencelibs " in *" $deplib "*) ;; *) valid_a_lib=no case $deplibs_check_method in match_pattern*) set dummy $deplibs_check_method; shift match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` if eval "\$ECHO \"$deplib\"" 2>/dev/null | $SED 10q \ | $EGREP "$match_pattern_regex" > /dev/null; then valid_a_lib=yes fi ;; pass_all) valid_a_lib=yes ;; esac if test "$valid_a_lib" != yes; then echo $ECHO "*** Warning: Trying to link with static lib archive $deplib." echo "*** I have the capability to make that library automatically link in when" echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have" echo "*** because the file extensions .$libext of this argument makes me believe" echo "*** that it is just a static archive that I should not use here." else echo $ECHO "*** Warning: Linking the shared library $output against the" $ECHO "*** static library $deplib is not portable!" deplibs="$deplib $deplibs" fi ;; esac continue ;; prog) if test "$pass" != link; then deplibs="$deplib $deplibs" else compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" fi continue ;; esac # linkmode ;; # *.$libext *.lo | *.$objext) if test "$pass" = conv; then deplibs="$deplib $deplibs" elif test "$linkmode" = prog; then if test "$pass" = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then # If there is no dlopen support or we're linking statically, # we need to preload. newdlprefiles+=" $deplib" compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else newdlfiles+=" $deplib" fi fi continue ;; %DEPLIBS%) alldeplibs=yes continue ;; esac # case $deplib if test "$found" = yes || test -f "$lib"; then : else func_fatal_error "cannot find the library \`$lib' or unhandled argument \`$deplib'" fi # Check to see that this really is a libtool archive. func_lalib_unsafe_p "$lib" \ || func_fatal_error "\`$lib' is not a valid libtool archive" func_dirname "$lib" "" "." ladir="$func_dirname_result" dlname= dlopen= dlpreopen= libdir= library_names= old_library= inherited_linker_flags= # If the library was installed with an old release of libtool, # it will not redefine variables installed, or shouldnotlink installed=yes shouldnotlink=no avoidtemprpath= # Read the .la file func_source "$lib" # Convert "-framework foo" to "foo.ltframework" if test -n "$inherited_linker_flags"; then tmp_inherited_linker_flags=`$ECHO "$inherited_linker_flags" | $SED 's/-framework \([^ $]*\)/\1.ltframework/g'` for tmp_inherited_linker_flag in $tmp_inherited_linker_flags; do case " $new_inherited_linker_flags " in *" $tmp_inherited_linker_flag "*) ;; *) new_inherited_linker_flags+=" $tmp_inherited_linker_flag";; esac done fi dependency_libs=`$ECHO " $dependency_libs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` if test "$linkmode,$pass" = "lib,link" || test "$linkmode,$pass" = "prog,scan" || { test "$linkmode" != prog && test "$linkmode" != lib; }; then test -n "$dlopen" && dlfiles+=" $dlopen" test -n "$dlpreopen" && dlprefiles+=" $dlpreopen" fi if test "$pass" = conv; then # Only check for convenience libraries deplibs="$lib $deplibs" if test -z "$libdir"; then if test -z "$old_library"; then func_fatal_error "cannot find name of link library for \`$lib'" fi # It is a libtool convenience library, so add in its objects. convenience+=" $ladir/$objdir/$old_library" old_convenience+=" $ladir/$objdir/$old_library" tmp_libs= for deplib in $dependency_libs; do deplibs="$deplib $deplibs" if $opt_preserve_dup_deps ; then case "$tmp_libs " in *" $deplib "*) specialdeplibs+=" $deplib" ;; esac fi tmp_libs+=" $deplib" done elif test "$linkmode" != prog && test "$linkmode" != lib; then func_fatal_error "\`$lib' is not a convenience library" fi continue fi # $pass = conv # Get the name of the library we link against. linklib= if test -n "$old_library" && { test "$prefer_static_libs" = yes || test "$prefer_static_libs,$installed" = "built,no"; }; then linklib=$old_library else for l in $old_library $library_names; do linklib="$l" done fi if test -z "$linklib"; then func_fatal_error "cannot find name of link library for \`$lib'" fi # This library was specified with -dlopen. if test "$pass" = dlopen; then if test -z "$libdir"; then func_fatal_error "cannot -dlopen a convenience library: \`$lib'" fi if test -z "$dlname" || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then # If there is no dlname, no dlopen support or we're linking # statically, we need to preload. We also need to preload any # dependent libraries so libltdl's deplib preloader doesn't # bomb out in the load deplibs phase. dlprefiles+=" $lib $dependency_libs" else newdlfiles+=" $lib" fi continue fi # $pass = dlopen # We need an absolute path. case $ladir in [\\/]* | [A-Za-z]:[\\/]*) abs_ladir="$ladir" ;; *) abs_ladir=`cd "$ladir" && pwd` if test -z "$abs_ladir"; then func_warning "cannot determine absolute directory name of \`$ladir'" func_warning "passing it literally to the linker, although it might fail" abs_ladir="$ladir" fi ;; esac func_basename "$lib" laname="$func_basename_result" # Find the relevant object directory and library name. if test "X$installed" = Xyes; then if test ! -f "$lt_sysroot$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then func_warning "library \`$lib' was moved." dir="$ladir" absdir="$abs_ladir" libdir="$abs_ladir" else dir="$lt_sysroot$libdir" absdir="$lt_sysroot$libdir" fi test "X$hardcode_automatic" = Xyes && avoidtemprpath=yes else if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then dir="$ladir" absdir="$abs_ladir" # Remove this search path later notinst_path+=" $abs_ladir" else dir="$ladir/$objdir" absdir="$abs_ladir/$objdir" # Remove this search path later notinst_path+=" $abs_ladir" fi fi # $installed = yes func_stripname 'lib' '.la' "$laname" name=$func_stripname_result # This library was specified with -dlpreopen. if test "$pass" = dlpreopen; then if test -z "$libdir" && test "$linkmode" = prog; then func_fatal_error "only libraries may -dlpreopen a convenience library: \`$lib'" fi case "$host" in # special handling for platforms with PE-DLLs. *cygwin* | *mingw* | *cegcc* ) # Linker will automatically link against shared library if both # static and shared are present. Therefore, ensure we extract # symbols from the import library if a shared library is present # (otherwise, the dlopen module name will be incorrect). We do # this by putting the import library name into $newdlprefiles. # We recover the dlopen module name by 'saving' the la file # name in a special purpose variable, and (later) extracting the # dlname from the la file. if test -n "$dlname"; then func_tr_sh "$dir/$linklib" eval "libfile_$func_tr_sh_result=\$abs_ladir/\$laname" newdlprefiles+=" $dir/$linklib" else newdlprefiles+=" $dir/$old_library" # Keep a list of preopened convenience libraries to check # that they are being used correctly in the link pass. test -z "$libdir" && \ dlpreconveniencelibs+=" $dir/$old_library" fi ;; * ) # Prefer using a static library (so that no silly _DYNAMIC symbols # are required to link). if test -n "$old_library"; then newdlprefiles+=" $dir/$old_library" # Keep a list of preopened convenience libraries to check # that they are being used correctly in the link pass. test -z "$libdir" && \ dlpreconveniencelibs+=" $dir/$old_library" # Otherwise, use the dlname, so that lt_dlopen finds it. elif test -n "$dlname"; then newdlprefiles+=" $dir/$dlname" else newdlprefiles+=" $dir/$linklib" fi ;; esac fi # $pass = dlpreopen if test -z "$libdir"; then # Link the convenience library if test "$linkmode" = lib; then deplibs="$dir/$old_library $deplibs" elif test "$linkmode,$pass" = "prog,link"; then compile_deplibs="$dir/$old_library $compile_deplibs" finalize_deplibs="$dir/$old_library $finalize_deplibs" else deplibs="$lib $deplibs" # used for prog,scan pass fi continue fi if test "$linkmode" = prog && test "$pass" != link; then newlib_search_path+=" $ladir" deplibs="$lib $deplibs" linkalldeplibs=no if test "$link_all_deplibs" != no || test -z "$library_names" || test "$build_libtool_libs" = no; then linkalldeplibs=yes fi tmp_libs= for deplib in $dependency_libs; do case $deplib in -L*) func_stripname '-L' '' "$deplib" func_resolve_sysroot "$func_stripname_result" newlib_search_path+=" $func_resolve_sysroot_result" ;; esac # Need to link against all dependency_libs? if test "$linkalldeplibs" = yes; then deplibs="$deplib $deplibs" else # Need to hardcode shared library paths # or/and link against static libraries newdependency_libs="$deplib $newdependency_libs" fi if $opt_preserve_dup_deps ; then case "$tmp_libs " in *" $deplib "*) specialdeplibs+=" $deplib" ;; esac fi tmp_libs+=" $deplib" done # for deplib continue fi # $linkmode = prog... if test "$linkmode,$pass" = "prog,link"; then if test -n "$library_names" && { { test "$prefer_static_libs" = no || test "$prefer_static_libs,$installed" = "built,yes"; } || test -z "$old_library"; }; then # We need to hardcode the library path if test -n "$shlibpath_var" && test -z "$avoidtemprpath" ; then # Make sure the rpath contains only unique directories. case "$temp_rpath:" in *"$absdir:"*) ;; *) temp_rpath+="$absdir:" ;; esac fi # Hardcode the library path. # Skip directories that are in the system default run-time # search path. case " $sys_lib_dlsearch_path " in *" $absdir "*) ;; *) case "$compile_rpath " in *" $absdir "*) ;; *) compile_rpath+=" $absdir" ;; esac ;; esac case " $sys_lib_dlsearch_path " in *" $libdir "*) ;; *) case "$finalize_rpath " in *" $libdir "*) ;; *) finalize_rpath+=" $libdir" ;; esac ;; esac fi # $linkmode,$pass = prog,link... if test "$alldeplibs" = yes && { test "$deplibs_check_method" = pass_all || { test "$build_libtool_libs" = yes && test -n "$library_names"; }; }; then # We only need to search for static libraries continue fi fi link_static=no # Whether the deplib will be linked statically use_static_libs=$prefer_static_libs if test "$use_static_libs" = built && test "$installed" = yes; then use_static_libs=no fi if test -n "$library_names" && { test "$use_static_libs" = no || test -z "$old_library"; }; then case $host in *cygwin* | *mingw* | *cegcc*) # No point in relinking DLLs because paths are not encoded notinst_deplibs+=" $lib" need_relink=no ;; *) if test "$installed" = no; then notinst_deplibs+=" $lib" need_relink=yes fi ;; esac # This is a shared library # Warn about portability, can't link against -module's on some # systems (darwin). Don't bleat about dlopened modules though! dlopenmodule="" for dlpremoduletest in $dlprefiles; do if test "X$dlpremoduletest" = "X$lib"; then dlopenmodule="$dlpremoduletest" break fi done if test -z "$dlopenmodule" && test "$shouldnotlink" = yes && test "$pass" = link; then echo if test "$linkmode" = prog; then $ECHO "*** Warning: Linking the executable $output against the loadable module" else $ECHO "*** Warning: Linking the shared library $output against the loadable module" fi $ECHO "*** $linklib is not portable!" fi if test "$linkmode" = lib && test "$hardcode_into_libs" = yes; then # Hardcode the library path. # Skip directories that are in the system default run-time # search path. case " $sys_lib_dlsearch_path " in *" $absdir "*) ;; *) case "$compile_rpath " in *" $absdir "*) ;; *) compile_rpath+=" $absdir" ;; esac ;; esac case " $sys_lib_dlsearch_path " in *" $libdir "*) ;; *) case "$finalize_rpath " in *" $libdir "*) ;; *) finalize_rpath+=" $libdir" ;; esac ;; esac fi if test -n "$old_archive_from_expsyms_cmds"; then # figure out the soname set dummy $library_names shift realname="$1" shift libname=`eval "\\$ECHO \"$libname_spec\""` # use dlname if we got it. it's perfectly good, no? if test -n "$dlname"; then soname="$dlname" elif test -n "$soname_spec"; then # bleh windows case $host in *cygwin* | mingw* | *cegcc*) func_arith $current - $age major=$func_arith_result versuffix="-$major" ;; esac eval soname=\"$soname_spec\" else soname="$realname" fi # Make a new name for the extract_expsyms_cmds to use soroot="$soname" func_basename "$soroot" soname="$func_basename_result" func_stripname 'lib' '.dll' "$soname" newlib=libimp-$func_stripname_result.a # If the library has no export list, then create one now if test -f "$output_objdir/$soname-def"; then : else func_verbose "extracting exported symbol list from \`$soname'" func_execute_cmds "$extract_expsyms_cmds" 'exit $?' fi # Create $newlib if test -f "$output_objdir/$newlib"; then :; else func_verbose "generating import library for \`$soname'" func_execute_cmds "$old_archive_from_expsyms_cmds" 'exit $?' fi # make sure the library variables are pointing to the new library dir=$output_objdir linklib=$newlib fi # test -n "$old_archive_from_expsyms_cmds" if test "$linkmode" = prog || test "$opt_mode" != relink; then add_shlibpath= add_dir= add= lib_linked=yes case $hardcode_action in immediate | unsupported) if test "$hardcode_direct" = no; then add="$dir/$linklib" case $host in *-*-sco3.2v5.0.[024]*) add_dir="-L$dir" ;; *-*-sysv4*uw2*) add_dir="-L$dir" ;; *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \ *-*-unixware7*) add_dir="-L$dir" ;; *-*-darwin* ) # if the lib is a (non-dlopened) module then we can not # link against it, someone is ignoring the earlier warnings if /usr/bin/file -L $add 2> /dev/null | $GREP ": [^:]* bundle" >/dev/null ; then if test "X$dlopenmodule" != "X$lib"; then $ECHO "*** Warning: lib $linklib is a module, not a shared library" if test -z "$old_library" ; then echo echo "*** And there doesn't seem to be a static archive available" echo "*** The link will probably fail, sorry" else add="$dir/$old_library" fi elif test -n "$old_library"; then add="$dir/$old_library" fi fi esac elif test "$hardcode_minus_L" = no; then case $host in *-*-sunos*) add_shlibpath="$dir" ;; esac add_dir="-L$dir" add="-l$name" elif test "$hardcode_shlibpath_var" = no; then add_shlibpath="$dir" add="-l$name" else lib_linked=no fi ;; relink) if test "$hardcode_direct" = yes && test "$hardcode_direct_absolute" = no; then add="$dir/$linklib" elif test "$hardcode_minus_L" = yes; then add_dir="-L$absdir" # Try looking first in the location we're being installed to. if test -n "$inst_prefix_dir"; then case $libdir in [\\/]*) add_dir+=" -L$inst_prefix_dir$libdir" ;; esac fi add="-l$name" elif test "$hardcode_shlibpath_var" = yes; then add_shlibpath="$dir" add="-l$name" else lib_linked=no fi ;; *) lib_linked=no ;; esac if test "$lib_linked" != yes; then func_fatal_configuration "unsupported hardcode properties" fi if test -n "$add_shlibpath"; then case :$compile_shlibpath: in *":$add_shlibpath:"*) ;; *) compile_shlibpath+="$add_shlibpath:" ;; esac fi if test "$linkmode" = prog; then test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs" test -n "$add" && compile_deplibs="$add $compile_deplibs" else test -n "$add_dir" && deplibs="$add_dir $deplibs" test -n "$add" && deplibs="$add $deplibs" if test "$hardcode_direct" != yes && test "$hardcode_minus_L" != yes && test "$hardcode_shlibpath_var" = yes; then case :$finalize_shlibpath: in *":$libdir:"*) ;; *) finalize_shlibpath+="$libdir:" ;; esac fi fi fi if test "$linkmode" = prog || test "$opt_mode" = relink; then add_shlibpath= add_dir= add= # Finalize command for both is simple: just hardcode it. if test "$hardcode_direct" = yes && test "$hardcode_direct_absolute" = no; then add="$libdir/$linklib" elif test "$hardcode_minus_L" = yes; then add_dir="-L$libdir" add="-l$name" elif test "$hardcode_shlibpath_var" = yes; then case :$finalize_shlibpath: in *":$libdir:"*) ;; *) finalize_shlibpath+="$libdir:" ;; esac add="-l$name" elif test "$hardcode_automatic" = yes; then if test -n "$inst_prefix_dir" && test -f "$inst_prefix_dir$libdir/$linklib" ; then add="$inst_prefix_dir$libdir/$linklib" else add="$libdir/$linklib" fi else # We cannot seem to hardcode it, guess we'll fake it. add_dir="-L$libdir" # Try looking first in the location we're being installed to. if test -n "$inst_prefix_dir"; then case $libdir in [\\/]*) add_dir+=" -L$inst_prefix_dir$libdir" ;; esac fi add="-l$name" fi if test "$linkmode" = prog; then test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs" test -n "$add" && finalize_deplibs="$add $finalize_deplibs" else test -n "$add_dir" && deplibs="$add_dir $deplibs" test -n "$add" && deplibs="$add $deplibs" fi fi elif test "$linkmode" = prog; then # Here we assume that one of hardcode_direct or hardcode_minus_L # is not unsupported. This is valid on all known static and # shared platforms. if test "$hardcode_direct" != unsupported; then test -n "$old_library" && linklib="$old_library" compile_deplibs="$dir/$linklib $compile_deplibs" finalize_deplibs="$dir/$linklib $finalize_deplibs" else compile_deplibs="-l$name -L$dir $compile_deplibs" finalize_deplibs="-l$name -L$dir $finalize_deplibs" fi elif test "$build_libtool_libs" = yes; then # Not a shared library if test "$deplibs_check_method" != pass_all; then # We're trying link a shared library against a static one # but the system doesn't support it. # Just print a warning and add the library to dependency_libs so # that the program can be linked against the static library. echo $ECHO "*** Warning: This system can not link to static lib archive $lib." echo "*** I have the capability to make that library automatically link in when" echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have." if test "$module" = yes; then echo "*** But as you try to build a module library, libtool will still create " echo "*** a static module, that should work as long as the dlopening application" echo "*** is linked with the -dlopen flag to resolve symbols at runtime." if test -z "$global_symbol_pipe"; then echo echo "*** However, this would only work if libtool was able to extract symbol" echo "*** lists from a program, using \`nm' or equivalent, but libtool could" echo "*** not find such a program. So, this module is probably useless." echo "*** \`nm' from GNU binutils and a full rebuild may help." fi if test "$build_old_libs" = no; then build_libtool_libs=module build_old_libs=yes else build_libtool_libs=no fi fi else deplibs="$dir/$old_library $deplibs" link_static=yes fi fi # link shared/static library? if test "$linkmode" = lib; then if test -n "$dependency_libs" && { test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes || test "$link_static" = yes; }; then # Extract -R from dependency_libs temp_deplibs= for libdir in $dependency_libs; do case $libdir in -R*) func_stripname '-R' '' "$libdir" temp_xrpath=$func_stripname_result case " $xrpath " in *" $temp_xrpath "*) ;; *) xrpath+=" $temp_xrpath";; esac;; *) temp_deplibs+=" $libdir";; esac done dependency_libs="$temp_deplibs" fi newlib_search_path+=" $absdir" # Link against this library test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs" # ... and its dependency_libs tmp_libs= for deplib in $dependency_libs; do newdependency_libs="$deplib $newdependency_libs" case $deplib in -L*) func_stripname '-L' '' "$deplib" func_resolve_sysroot "$func_stripname_result";; *) func_resolve_sysroot "$deplib" ;; esac if $opt_preserve_dup_deps ; then case "$tmp_libs " in *" $func_resolve_sysroot_result "*) specialdeplibs+=" $func_resolve_sysroot_result" ;; esac fi tmp_libs+=" $func_resolve_sysroot_result" done if test "$link_all_deplibs" != no; then # Add the search paths of all dependency libraries for deplib in $dependency_libs; do path= case $deplib in -L*) path="$deplib" ;; *.la) func_resolve_sysroot "$deplib" deplib=$func_resolve_sysroot_result func_dirname "$deplib" "" "." dir=$func_dirname_result # We need an absolute path. case $dir in [\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;; *) absdir=`cd "$dir" && pwd` if test -z "$absdir"; then func_warning "cannot determine absolute directory name of \`$dir'" absdir="$dir" fi ;; esac if $GREP "^installed=no" $deplib > /dev/null; then case $host in *-*-darwin*) depdepl= eval deplibrary_names=`${SED} -n -e 's/^library_names=\(.*\)$/\1/p' $deplib` if test -n "$deplibrary_names" ; then for tmp in $deplibrary_names ; do depdepl=$tmp done if test -f "$absdir/$objdir/$depdepl" ; then depdepl="$absdir/$objdir/$depdepl" darwin_install_name=`${OTOOL} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` if test -z "$darwin_install_name"; then darwin_install_name=`${OTOOL64} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` fi compiler_flags+=" ${wl}-dylib_file ${wl}${darwin_install_name}:${depdepl}" linker_flags+=" -dylib_file ${darwin_install_name}:${depdepl}" path= fi fi ;; *) path="-L$absdir/$objdir" ;; esac else eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` test -z "$libdir" && \ func_fatal_error "\`$deplib' is not a valid libtool archive" test "$absdir" != "$libdir" && \ func_warning "\`$deplib' seems to be moved" path="-L$absdir" fi ;; esac case " $deplibs " in *" $path "*) ;; *) deplibs="$path $deplibs" ;; esac done fi # link_all_deplibs != no fi # linkmode = lib done # for deplib in $libs if test "$pass" = link; then if test "$linkmode" = "prog"; then compile_deplibs="$new_inherited_linker_flags $compile_deplibs" finalize_deplibs="$new_inherited_linker_flags $finalize_deplibs" else compiler_flags="$compiler_flags "`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` fi fi dependency_libs="$newdependency_libs" if test "$pass" = dlpreopen; then # Link the dlpreopened libraries before other libraries for deplib in $save_deplibs; do deplibs="$deplib $deplibs" done fi if test "$pass" != dlopen; then if test "$pass" != conv; then # Make sure lib_search_path contains only unique directories. lib_search_path= for dir in $newlib_search_path; do case "$lib_search_path " in *" $dir "*) ;; *) lib_search_path+=" $dir" ;; esac done newlib_search_path= fi if test "$linkmode,$pass" != "prog,link"; then vars="deplibs" else vars="compile_deplibs finalize_deplibs" fi for var in $vars dependency_libs; do # Add libraries to $var in reverse order eval tmp_libs=\"\$$var\" new_libs= for deplib in $tmp_libs; do # FIXME: Pedantically, this is the right thing to do, so # that some nasty dependency loop isn't accidentally # broken: #new_libs="$deplib $new_libs" # Pragmatically, this seems to cause very few problems in # practice: case $deplib in -L*) new_libs="$deplib $new_libs" ;; -R*) ;; *) # And here is the reason: when a library appears more # than once as an explicit dependence of a library, or # is implicitly linked in more than once by the # compiler, it is considered special, and multiple # occurrences thereof are not removed. Compare this # with having the same library being listed as a # dependency of multiple other libraries: in this case, # we know (pedantically, we assume) the library does not # need to be listed more than once, so we keep only the # last copy. This is not always right, but it is rare # enough that we require users that really mean to play # such unportable linking tricks to link the library # using -Wl,-lname, so that libtool does not consider it # for duplicate removal. case " $specialdeplibs " in *" $deplib "*) new_libs="$deplib $new_libs" ;; *) case " $new_libs " in *" $deplib "*) ;; *) new_libs="$deplib $new_libs" ;; esac ;; esac ;; esac done tmp_libs= for deplib in $new_libs; do case $deplib in -L*) case " $tmp_libs " in *" $deplib "*) ;; *) tmp_libs+=" $deplib" ;; esac ;; *) tmp_libs+=" $deplib" ;; esac done eval $var=\"$tmp_libs\" done # for var fi # Last step: remove runtime libs from dependency_libs # (they stay in deplibs) tmp_libs= for i in $dependency_libs ; do case " $predeps $postdeps $compiler_lib_search_path " in *" $i "*) i="" ;; esac if test -n "$i" ; then tmp_libs+=" $i" fi done dependency_libs=$tmp_libs done # for pass if test "$linkmode" = prog; then dlfiles="$newdlfiles" fi if test "$linkmode" = prog || test "$linkmode" = lib; then dlprefiles="$newdlprefiles" fi case $linkmode in oldlib) if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then func_warning "\`-dlopen' is ignored for archives" fi case " $deplibs" in *\ -l* | *\ -L*) func_warning "\`-l' and \`-L' are ignored for archives" ;; esac test -n "$rpath" && \ func_warning "\`-rpath' is ignored for archives" test -n "$xrpath" && \ func_warning "\`-R' is ignored for archives" test -n "$vinfo" && \ func_warning "\`-version-info/-version-number' is ignored for archives" test -n "$release" && \ func_warning "\`-release' is ignored for archives" test -n "$export_symbols$export_symbols_regex" && \ func_warning "\`-export-symbols' is ignored for archives" # Now set the variables for building old libraries. build_libtool_libs=no oldlibs="$output" objs+="$old_deplibs" ;; lib) # Make sure we only generate libraries of the form `libNAME.la'. case $outputname in lib*) func_stripname 'lib' '.la' "$outputname" name=$func_stripname_result eval shared_ext=\"$shrext_cmds\" eval libname=\"$libname_spec\" ;; *) test "$module" = no && \ func_fatal_help "libtool library \`$output' must begin with \`lib'" if test "$need_lib_prefix" != no; then # Add the "lib" prefix for modules if required func_stripname '' '.la' "$outputname" name=$func_stripname_result eval shared_ext=\"$shrext_cmds\" eval libname=\"$libname_spec\" else func_stripname '' '.la' "$outputname" libname=$func_stripname_result fi ;; esac if test -n "$objs"; then if test "$deplibs_check_method" != pass_all; then func_fatal_error "cannot build libtool library \`$output' from non-libtool objects on this host:$objs" else echo $ECHO "*** Warning: Linking the shared library $output against the non-libtool" $ECHO "*** objects $objs is not portable!" libobjs+=" $objs" fi fi test "$dlself" != no && \ func_warning "\`-dlopen self' is ignored for libtool libraries" set dummy $rpath shift test "$#" -gt 1 && \ func_warning "ignoring multiple \`-rpath's for a libtool library" install_libdir="$1" oldlibs= if test -z "$rpath"; then if test "$build_libtool_libs" = yes; then # Building a libtool convenience library. # Some compilers have problems with a `.al' extension so # convenience libraries should have the same extension an # archive normally would. oldlibs="$output_objdir/$libname.$libext $oldlibs" build_libtool_libs=convenience build_old_libs=yes fi test -n "$vinfo" && \ func_warning "\`-version-info/-version-number' is ignored for convenience libraries" test -n "$release" && \ func_warning "\`-release' is ignored for convenience libraries" else # Parse the version information argument. save_ifs="$IFS"; IFS=':' set dummy $vinfo 0 0 0 shift IFS="$save_ifs" test -n "$7" && \ func_fatal_help "too many parameters to \`-version-info'" # convert absolute version numbers to libtool ages # this retains compatibility with .la files and attempts # to make the code below a bit more comprehensible case $vinfo_number in yes) number_major="$1" number_minor="$2" number_revision="$3" # # There are really only two kinds -- those that # use the current revision as the major version # and those that subtract age and use age as # a minor version. But, then there is irix # which has an extra 1 added just for fun # case $version_type in # correct linux to gnu/linux during the next big refactor darwin|linux|osf|windows|none) func_arith $number_major + $number_minor current=$func_arith_result age="$number_minor" revision="$number_revision" ;; freebsd-aout|freebsd-elf|qnx|sunos) current="$number_major" revision="$number_minor" age="0" ;; irix|nonstopux) func_arith $number_major + $number_minor current=$func_arith_result age="$number_minor" revision="$number_minor" lt_irix_increment=no ;; *) func_fatal_configuration "$modename: unknown library version type \`$version_type'" ;; esac ;; no) current="$1" revision="$2" age="$3" ;; esac # Check that each of the things are valid numbers. case $current in 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; *) func_error "CURRENT \`$current' must be a nonnegative integer" func_fatal_error "\`$vinfo' is not valid version information" ;; esac case $revision in 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; *) func_error "REVISION \`$revision' must be a nonnegative integer" func_fatal_error "\`$vinfo' is not valid version information" ;; esac case $age in 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; *) func_error "AGE \`$age' must be a nonnegative integer" func_fatal_error "\`$vinfo' is not valid version information" ;; esac if test "$age" -gt "$current"; then func_error "AGE \`$age' is greater than the current interface number \`$current'" func_fatal_error "\`$vinfo' is not valid version information" fi # Calculate the version variables. major= versuffix= verstring= case $version_type in none) ;; darwin) # Like Linux, but with the current version available in # verstring for coding it into the library header func_arith $current - $age major=.$func_arith_result versuffix="$major.$age.$revision" # Darwin ld doesn't like 0 for these options... func_arith $current + 1 minor_current=$func_arith_result xlcverstring="${wl}-compatibility_version ${wl}$minor_current ${wl}-current_version ${wl}$minor_current.$revision" verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" ;; freebsd-aout) major=".$current" versuffix=".$current.$revision"; ;; freebsd-elf) major=".$current" versuffix=".$current" ;; irix | nonstopux) if test "X$lt_irix_increment" = "Xno"; then func_arith $current - $age else func_arith $current - $age + 1 fi major=$func_arith_result case $version_type in nonstopux) verstring_prefix=nonstopux ;; *) verstring_prefix=sgi ;; esac verstring="$verstring_prefix$major.$revision" # Add in all the interfaces that we are compatible with. loop=$revision while test "$loop" -ne 0; do func_arith $revision - $loop iface=$func_arith_result func_arith $loop - 1 loop=$func_arith_result verstring="$verstring_prefix$major.$iface:$verstring" done # Before this point, $major must not contain `.'. major=.$major versuffix="$major.$revision" ;; linux) # correct to gnu/linux during the next big refactor func_arith $current - $age major=.$func_arith_result versuffix="$major.$age.$revision" ;; osf) func_arith $current - $age major=.$func_arith_result versuffix=".$current.$age.$revision" verstring="$current.$age.$revision" # Add in all the interfaces that we are compatible with. loop=$age while test "$loop" -ne 0; do func_arith $current - $loop iface=$func_arith_result func_arith $loop - 1 loop=$func_arith_result verstring="$verstring:${iface}.0" done # Make executables depend on our current version. verstring+=":${current}.0" ;; qnx) major=".$current" versuffix=".$current" ;; sunos) major=".$current" versuffix=".$current.$revision" ;; windows) # Use '-' rather than '.', since we only want one # extension on DOS 8.3 filesystems. func_arith $current - $age major=$func_arith_result versuffix="-$major" ;; *) func_fatal_configuration "unknown library version type \`$version_type'" ;; esac # Clear the version info if we defaulted, and they specified a release. if test -z "$vinfo" && test -n "$release"; then major= case $version_type in darwin) # we can't check for "0.0" in archive_cmds due to quoting # problems, so we reset it completely verstring= ;; *) verstring="0.0" ;; esac if test "$need_version" = no; then versuffix= else versuffix=".0.0" fi fi # Remove version info from name if versioning should be avoided if test "$avoid_version" = yes && test "$need_version" = no; then major= versuffix= verstring="" fi # Check to see if the archive will have undefined symbols. if test "$allow_undefined" = yes; then if test "$allow_undefined_flag" = unsupported; then func_warning "undefined symbols not allowed in $host shared libraries" build_libtool_libs=no build_old_libs=yes fi else # Don't allow undefined symbols. allow_undefined_flag="$no_undefined_flag" fi fi func_generate_dlsyms "$libname" "$libname" "yes" libobjs+=" $symfileobj" test "X$libobjs" = "X " && libobjs= if test "$opt_mode" != relink; then # Remove our outputs, but don't remove object files since they # may have been created when compiling PIC objects. removelist= tempremovelist=`$ECHO "$output_objdir/*"` for p in $tempremovelist; do case $p in *.$objext | *.gcno) ;; $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/${libname}${release}.*) if test "X$precious_files_regex" != "X"; then if $ECHO "$p" | $EGREP -e "$precious_files_regex" >/dev/null 2>&1 then continue fi fi removelist+=" $p" ;; *) ;; esac done test -n "$removelist" && \ func_show_eval "${RM}r \$removelist" fi # Now set the variables for building old libraries. if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then oldlibs+=" $output_objdir/$libname.$libext" # Transform .lo files to .o files. oldobjs="$objs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.${libext}$/d; $lo2o" | $NL2SP` fi # Eliminate all temporary directories. #for path in $notinst_path; do # lib_search_path=`$ECHO "$lib_search_path " | $SED "s% $path % %g"` # deplibs=`$ECHO "$deplibs " | $SED "s% -L$path % %g"` # dependency_libs=`$ECHO "$dependency_libs " | $SED "s% -L$path % %g"` #done if test -n "$xrpath"; then # If the user specified any rpath flags, then add them. temp_xrpath= for libdir in $xrpath; do func_replace_sysroot "$libdir" temp_xrpath+=" -R$func_replace_sysroot_result" case "$finalize_rpath " in *" $libdir "*) ;; *) finalize_rpath+=" $libdir" ;; esac done if test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes; then dependency_libs="$temp_xrpath $dependency_libs" fi fi # Make sure dlfiles contains only unique files that won't be dlpreopened old_dlfiles="$dlfiles" dlfiles= for lib in $old_dlfiles; do case " $dlprefiles $dlfiles " in *" $lib "*) ;; *) dlfiles+=" $lib" ;; esac done # Make sure dlprefiles contains only unique files old_dlprefiles="$dlprefiles" dlprefiles= for lib in $old_dlprefiles; do case "$dlprefiles " in *" $lib "*) ;; *) dlprefiles+=" $lib" ;; esac done if test "$build_libtool_libs" = yes; then if test -n "$rpath"; then case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc* | *-*-haiku*) # these systems don't actually have a c library (as such)! ;; *-*-rhapsody* | *-*-darwin1.[012]) # Rhapsody C library is in the System framework deplibs+=" System.ltframework" ;; *-*-netbsd*) # Don't link with libc until the a.out ld.so is fixed. ;; *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) # Do not include libc due to us having libc/libc_r. ;; *-*-sco3.2v5* | *-*-sco5v6*) # Causes problems with __ctype ;; *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) # Compiler inserts libc in the correct place for threads to work ;; *) # Add libc to deplibs on all other systems if necessary. if test "$build_libtool_need_lc" = "yes"; then deplibs+=" -lc" fi ;; esac fi # Transform deplibs into only deplibs that can be linked in shared. name_save=$name libname_save=$libname release_save=$release versuffix_save=$versuffix major_save=$major # I'm not sure if I'm treating the release correctly. I think # release should show up in the -l (ie -lgmp5) so we don't want to # add it in twice. Is that correct? release="" versuffix="" major="" newdeplibs= droppeddeps=no case $deplibs_check_method in pass_all) # Don't check for shared/static. Everything works. # This might be a little naive. We might want to check # whether the library exists or not. But this is on # osf3 & osf4 and I'm not really sure... Just # implementing what was already the behavior. newdeplibs=$deplibs ;; test_compile) # This code stresses the "libraries are programs" paradigm to its # limits. Maybe even breaks it. We compile a program, linking it # against the deplibs as a proxy for the library. Then we can check # whether they linked in statically or dynamically with ldd. $opt_dry_run || $RM conftest.c cat > conftest.c </dev/null` $nocaseglob else potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null` fi for potent_lib in $potential_libs; do # Follow soft links. if ls -lLd "$potent_lib" 2>/dev/null | $GREP " -> " >/dev/null; then continue fi # The statement above tries to avoid entering an # endless loop below, in case of cyclic links. # We might still enter an endless loop, since a link # loop can be closed while we follow links, # but so what? potlib="$potent_lib" while test -h "$potlib" 2>/dev/null; do potliblink=`ls -ld $potlib | ${SED} 's/.* -> //'` case $potliblink in [\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";; *) potlib=`$ECHO "$potlib" | $SED 's,[^/]*$,,'`"$potliblink";; esac done if eval $file_magic_cmd \"\$potlib\" 2>/dev/null | $SED -e 10q | $EGREP "$file_magic_regex" > /dev/null; then newdeplibs+=" $a_deplib" a_deplib="" break 2 fi done done fi if test -n "$a_deplib" ; then droppeddeps=yes echo $ECHO "*** Warning: linker path does not have real file for library $a_deplib." echo "*** I have the capability to make that library automatically link in when" echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have" echo "*** because I did check the linker path looking for a file starting" if test -z "$potlib" ; then $ECHO "*** with $libname but no candidates were found. (...for file magic test)" else $ECHO "*** with $libname and none of the candidates passed a file format test" $ECHO "*** using a file magic. Last file checked: $potlib" fi fi ;; *) # Add a -L argument. newdeplibs+=" $a_deplib" ;; esac done # Gone through all deplibs. ;; match_pattern*) set dummy $deplibs_check_method; shift match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` for a_deplib in $deplibs; do case $a_deplib in -l*) func_stripname -l '' "$a_deplib" name=$func_stripname_result if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then case " $predeps $postdeps " in *" $a_deplib "*) newdeplibs+=" $a_deplib" a_deplib="" ;; esac fi if test -n "$a_deplib" ; then libname=`eval "\\$ECHO \"$libname_spec\""` for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do potential_libs=`ls $i/$libname[.-]* 2>/dev/null` for potent_lib in $potential_libs; do potlib="$potent_lib" # see symlink-check above in file_magic test if eval "\$ECHO \"$potent_lib\"" 2>/dev/null | $SED 10q | \ $EGREP "$match_pattern_regex" > /dev/null; then newdeplibs+=" $a_deplib" a_deplib="" break 2 fi done done fi if test -n "$a_deplib" ; then droppeddeps=yes echo $ECHO "*** Warning: linker path does not have real file for library $a_deplib." echo "*** I have the capability to make that library automatically link in when" echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have" echo "*** because I did check the linker path looking for a file starting" if test -z "$potlib" ; then $ECHO "*** with $libname but no candidates were found. (...for regex pattern test)" else $ECHO "*** with $libname and none of the candidates passed a file format test" $ECHO "*** using a regex pattern. Last file checked: $potlib" fi fi ;; *) # Add a -L argument. newdeplibs+=" $a_deplib" ;; esac done # Gone through all deplibs. ;; none | unknown | *) newdeplibs="" tmp_deplibs=`$ECHO " $deplibs" | $SED 's/ -lc$//; s/ -[LR][^ ]*//g'` if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then for i in $predeps $postdeps ; do # can't use Xsed below, because $i might contain '/' tmp_deplibs=`$ECHO " $tmp_deplibs" | $SED "s,$i,,"` done fi case $tmp_deplibs in *[!\ \ ]*) echo if test "X$deplibs_check_method" = "Xnone"; then echo "*** Warning: inter-library dependencies are not supported in this platform." else echo "*** Warning: inter-library dependencies are not known to be supported." fi echo "*** All declared inter-library dependencies are being dropped." droppeddeps=yes ;; esac ;; esac versuffix=$versuffix_save major=$major_save release=$release_save libname=$libname_save name=$name_save case $host in *-*-rhapsody* | *-*-darwin1.[012]) # On Rhapsody replace the C library with the System framework newdeplibs=`$ECHO " $newdeplibs" | $SED 's/ -lc / System.ltframework /'` ;; esac if test "$droppeddeps" = yes; then if test "$module" = yes; then echo echo "*** Warning: libtool could not satisfy all declared inter-library" $ECHO "*** dependencies of module $libname. Therefore, libtool will create" echo "*** a static module, that should work as long as the dlopening" echo "*** application is linked with the -dlopen flag." if test -z "$global_symbol_pipe"; then echo echo "*** However, this would only work if libtool was able to extract symbol" echo "*** lists from a program, using \`nm' or equivalent, but libtool could" echo "*** not find such a program. So, this module is probably useless." echo "*** \`nm' from GNU binutils and a full rebuild may help." fi if test "$build_old_libs" = no; then oldlibs="$output_objdir/$libname.$libext" build_libtool_libs=module build_old_libs=yes else build_libtool_libs=no fi else echo "*** The inter-library dependencies that have been dropped here will be" echo "*** automatically added whenever a program is linked with this library" echo "*** or is declared to -dlopen it." if test "$allow_undefined" = no; then echo echo "*** Since this library must not contain undefined symbols," echo "*** because either the platform does not support them or" echo "*** it was explicitly requested with -no-undefined," echo "*** libtool will only create a static version of it." if test "$build_old_libs" = no; then oldlibs="$output_objdir/$libname.$libext" build_libtool_libs=module build_old_libs=yes else build_libtool_libs=no fi fi fi fi # Done checking deplibs! deplibs=$newdeplibs fi # Time to change all our "foo.ltframework" stuff back to "-framework foo" case $host in *-*-darwin*) newdeplibs=`$ECHO " $newdeplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` new_inherited_linker_flags=`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` deplibs=`$ECHO " $deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` ;; esac # move library search paths that coincide with paths to not yet # installed libraries to the beginning of the library search list new_libs= for path in $notinst_path; do case " $new_libs " in *" -L$path/$objdir "*) ;; *) case " $deplibs " in *" -L$path/$objdir "*) new_libs+=" -L$path/$objdir" ;; esac ;; esac done for deplib in $deplibs; do case $deplib in -L*) case " $new_libs " in *" $deplib "*) ;; *) new_libs+=" $deplib" ;; esac ;; *) new_libs+=" $deplib" ;; esac done deplibs="$new_libs" # All the library-specific variables (install_libdir is set above). library_names= old_library= dlname= # Test again, we may have decided not to build it any more if test "$build_libtool_libs" = yes; then # Remove ${wl} instances when linking with ld. # FIXME: should test the right _cmds variable. case $archive_cmds in *\$LD\ *) wl= ;; esac if test "$hardcode_into_libs" = yes; then # Hardcode the library paths hardcode_libdirs= dep_rpath= rpath="$finalize_rpath" test "$opt_mode" != relink && rpath="$compile_rpath$rpath" for libdir in $rpath; do if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then func_replace_sysroot "$libdir" libdir=$func_replace_sysroot_result if test -z "$hardcode_libdirs"; then hardcode_libdirs="$libdir" else # Just accumulate the unique libdirs. case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ;; *) hardcode_libdirs+="$hardcode_libdir_separator$libdir" ;; esac fi else eval flag=\"$hardcode_libdir_flag_spec\" dep_rpath+=" $flag" fi elif test -n "$runpath_var"; then case "$perm_rpath " in *" $libdir "*) ;; *) perm_rpath+=" $libdir" ;; esac fi done # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then libdir="$hardcode_libdirs" eval "dep_rpath=\"$hardcode_libdir_flag_spec\"" fi if test -n "$runpath_var" && test -n "$perm_rpath"; then # We should set the runpath_var. rpath= for dir in $perm_rpath; do rpath+="$dir:" done eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var" fi test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs" fi shlibpath="$finalize_shlibpath" test "$opt_mode" != relink && shlibpath="$compile_shlibpath$shlibpath" if test -n "$shlibpath"; then eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var" fi # Get the real and link names of the library. eval shared_ext=\"$shrext_cmds\" eval library_names=\"$library_names_spec\" set dummy $library_names shift realname="$1" shift if test -n "$soname_spec"; then eval soname=\"$soname_spec\" else soname="$realname" fi if test -z "$dlname"; then dlname=$soname fi lib="$output_objdir/$realname" linknames= for link do linknames+=" $link" done # Use standard objects if they are pic test -z "$pic_flag" && libobjs=`$ECHO "$libobjs" | $SP2NL | $SED "$lo2o" | $NL2SP` test "X$libobjs" = "X " && libobjs= delfiles= if test -n "$export_symbols" && test -n "$include_expsyms"; then $opt_dry_run || cp "$export_symbols" "$output_objdir/$libname.uexp" export_symbols="$output_objdir/$libname.uexp" delfiles+=" $export_symbols" fi orig_export_symbols= case $host_os in cygwin* | mingw* | cegcc*) if test -n "$export_symbols" && test -z "$export_symbols_regex"; then # exporting using user supplied symfile if test "x`$SED 1q $export_symbols`" != xEXPORTS; then # and it's NOT already a .def file. Must figure out # which of the given symbols are data symbols and tag # them as such. So, trigger use of export_symbols_cmds. # export_symbols gets reassigned inside the "prepare # the list of exported symbols" if statement, so the # include_expsyms logic still works. orig_export_symbols="$export_symbols" export_symbols= always_export_symbols=yes fi fi ;; esac # Prepare the list of exported symbols if test -z "$export_symbols"; then if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then func_verbose "generating symbol list for \`$libname.la'" export_symbols="$output_objdir/$libname.exp" $opt_dry_run || $RM $export_symbols cmds=$export_symbols_cmds save_ifs="$IFS"; IFS='~' for cmd1 in $cmds; do IFS="$save_ifs" # Take the normal branch if the nm_file_list_spec branch # doesn't work or if tool conversion is not needed. case $nm_file_list_spec~$to_tool_file_cmd in *~func_convert_file_noop | *~func_convert_file_msys_to_w32 | ~*) try_normal_branch=yes eval cmd=\"$cmd1\" func_len " $cmd" len=$func_len_result ;; *) try_normal_branch=no ;; esac if test "$try_normal_branch" = yes \ && { test "$len" -lt "$max_cmd_len" \ || test "$max_cmd_len" -le -1; } then func_show_eval "$cmd" 'exit $?' skipped_export=false elif test -n "$nm_file_list_spec"; then func_basename "$output" output_la=$func_basename_result save_libobjs=$libobjs save_output=$output output=${output_objdir}/${output_la}.nm func_to_tool_file "$output" libobjs=$nm_file_list_spec$func_to_tool_file_result delfiles+=" $output" func_verbose "creating $NM input file list: $output" for obj in $save_libobjs; do func_to_tool_file "$obj" $ECHO "$func_to_tool_file_result" done > "$output" eval cmd=\"$cmd1\" func_show_eval "$cmd" 'exit $?' output=$save_output libobjs=$save_libobjs skipped_export=false else # The command line is too long to execute in one step. func_verbose "using reloadable object file for export list..." skipped_export=: # Break out early, otherwise skipped_export may be # set to false by a later but shorter cmd. break fi done IFS="$save_ifs" if test -n "$export_symbols_regex" && test "X$skipped_export" != "X:"; then func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' func_show_eval '$MV "${export_symbols}T" "$export_symbols"' fi fi fi if test -n "$export_symbols" && test -n "$include_expsyms"; then tmp_export_symbols="$export_symbols" test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols" $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' fi if test "X$skipped_export" != "X:" && test -n "$orig_export_symbols"; then # The given exports_symbols file has to be filtered, so filter it. func_verbose "filter symbol list for \`$libname.la' to tag DATA exports" # FIXME: $output_objdir/$libname.filter potentially contains lots of # 's' commands which not all seds can handle. GNU sed should be fine # though. Also, the filter scales superlinearly with the number of # global variables. join(1) would be nice here, but unfortunately # isn't a blessed tool. $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter delfiles+=" $export_symbols $output_objdir/$libname.filter" export_symbols=$output_objdir/$libname.def $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols fi tmp_deplibs= for test_deplib in $deplibs; do case " $convenience " in *" $test_deplib "*) ;; *) tmp_deplibs+=" $test_deplib" ;; esac done deplibs="$tmp_deplibs" if test -n "$convenience"; then if test -n "$whole_archive_flag_spec" && test "$compiler_needs_object" = yes && test -z "$libobjs"; then # extract the archives, so we have objects to list. # TODO: could optimize this to just extract one archive. whole_archive_flag_spec= fi if test -n "$whole_archive_flag_spec"; then save_libobjs=$libobjs eval libobjs=\"\$libobjs $whole_archive_flag_spec\" test "X$libobjs" = "X " && libobjs= else gentop="$output_objdir/${outputname}x" generated+=" $gentop" func_extract_archives $gentop $convenience libobjs+=" $func_extract_archives_result" test "X$libobjs" = "X " && libobjs= fi fi if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then eval flag=\"$thread_safe_flag_spec\" linker_flags+=" $flag" fi # Make a backup of the uninstalled library when relinking if test "$opt_mode" = relink; then $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}U && $MV $realname ${realname}U)' || exit $? fi # Do each of the archive commands. if test "$module" = yes && test -n "$module_cmds" ; then if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then eval test_cmds=\"$module_expsym_cmds\" cmds=$module_expsym_cmds else eval test_cmds=\"$module_cmds\" cmds=$module_cmds fi else if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then eval test_cmds=\"$archive_expsym_cmds\" cmds=$archive_expsym_cmds else eval test_cmds=\"$archive_cmds\" cmds=$archive_cmds fi fi if test "X$skipped_export" != "X:" && func_len " $test_cmds" && len=$func_len_result && test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then : else # The command line is too long to link in one step, link piecewise # or, if using GNU ld and skipped_export is not :, use a linker # script. # Save the value of $output and $libobjs because we want to # use them later. If we have whole_archive_flag_spec, we # want to use save_libobjs as it was before # whole_archive_flag_spec was expanded, because we can't # assume the linker understands whole_archive_flag_spec. # This may have to be revisited, in case too many # convenience libraries get linked in and end up exceeding # the spec. if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then save_libobjs=$libobjs fi save_output=$output func_basename "$output" output_la=$func_basename_result # Clear the reloadable object creation command queue and # initialize k to one. test_cmds= concat_cmds= objlist= last_robj= k=1 if test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "$with_gnu_ld" = yes; then output=${output_objdir}/${output_la}.lnkscript func_verbose "creating GNU ld script: $output" echo 'INPUT (' > $output for obj in $save_libobjs do func_to_tool_file "$obj" $ECHO "$func_to_tool_file_result" >> $output done echo ')' >> $output delfiles+=" $output" func_to_tool_file "$output" output=$func_to_tool_file_result elif test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "X$file_list_spec" != X; then output=${output_objdir}/${output_la}.lnk func_verbose "creating linker input file list: $output" : > $output set x $save_libobjs shift firstobj= if test "$compiler_needs_object" = yes; then firstobj="$1 " shift fi for obj do func_to_tool_file "$obj" $ECHO "$func_to_tool_file_result" >> $output done delfiles+=" $output" func_to_tool_file "$output" output=$firstobj\"$file_list_spec$func_to_tool_file_result\" else if test -n "$save_libobjs"; then func_verbose "creating reloadable object files..." output=$output_objdir/$output_la-${k}.$objext eval test_cmds=\"$reload_cmds\" func_len " $test_cmds" len0=$func_len_result len=$len0 # Loop over the list of objects to be linked. for obj in $save_libobjs do func_len " $obj" func_arith $len + $func_len_result len=$func_arith_result if test "X$objlist" = X || test "$len" -lt "$max_cmd_len"; then objlist+=" $obj" else # The command $test_cmds is almost too long, add a # command to the queue. if test "$k" -eq 1 ; then # The first file doesn't have a previous command to add. reload_objs=$objlist eval concat_cmds=\"$reload_cmds\" else # All subsequent reloadable object files will link in # the last one created. reload_objs="$objlist $last_robj" eval concat_cmds=\"\$concat_cmds~$reload_cmds~\$RM $last_robj\" fi last_robj=$output_objdir/$output_la-${k}.$objext func_arith $k + 1 k=$func_arith_result output=$output_objdir/$output_la-${k}.$objext objlist=" $obj" func_len " $last_robj" func_arith $len0 + $func_len_result len=$func_arith_result fi done # Handle the remaining objects by creating one last # reloadable object file. All subsequent reloadable object # files will link in the last one created. test -z "$concat_cmds" || concat_cmds=$concat_cmds~ reload_objs="$objlist $last_robj" eval concat_cmds=\"\${concat_cmds}$reload_cmds\" if test -n "$last_robj"; then eval concat_cmds=\"\${concat_cmds}~\$RM $last_robj\" fi delfiles+=" $output" else output= fi if ${skipped_export-false}; then func_verbose "generating symbol list for \`$libname.la'" export_symbols="$output_objdir/$libname.exp" $opt_dry_run || $RM $export_symbols libobjs=$output # Append the command to create the export file. test -z "$concat_cmds" || concat_cmds=$concat_cmds~ eval concat_cmds=\"\$concat_cmds$export_symbols_cmds\" if test -n "$last_robj"; then eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\" fi fi test -n "$save_libobjs" && func_verbose "creating a temporary reloadable object file: $output" # Loop through the commands generated above and execute them. save_ifs="$IFS"; IFS='~' for cmd in $concat_cmds; do IFS="$save_ifs" $opt_silent || { func_quote_for_expand "$cmd" eval "func_echo $func_quote_for_expand_result" } $opt_dry_run || eval "$cmd" || { lt_exit=$? # Restore the uninstalled library and exit if test "$opt_mode" = relink; then ( cd "$output_objdir" && \ $RM "${realname}T" && \ $MV "${realname}U" "$realname" ) fi exit $lt_exit } done IFS="$save_ifs" if test -n "$export_symbols_regex" && ${skipped_export-false}; then func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' func_show_eval '$MV "${export_symbols}T" "$export_symbols"' fi fi if ${skipped_export-false}; then if test -n "$export_symbols" && test -n "$include_expsyms"; then tmp_export_symbols="$export_symbols" test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols" $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' fi if test -n "$orig_export_symbols"; then # The given exports_symbols file has to be filtered, so filter it. func_verbose "filter symbol list for \`$libname.la' to tag DATA exports" # FIXME: $output_objdir/$libname.filter potentially contains lots of # 's' commands which not all seds can handle. GNU sed should be fine # though. Also, the filter scales superlinearly with the number of # global variables. join(1) would be nice here, but unfortunately # isn't a blessed tool. $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter delfiles+=" $export_symbols $output_objdir/$libname.filter" export_symbols=$output_objdir/$libname.def $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols fi fi libobjs=$output # Restore the value of output. output=$save_output if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then eval libobjs=\"\$libobjs $whole_archive_flag_spec\" test "X$libobjs" = "X " && libobjs= fi # Expand the library linking commands again to reset the # value of $libobjs for piecewise linking. # Do each of the archive commands. if test "$module" = yes && test -n "$module_cmds" ; then if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then cmds=$module_expsym_cmds else cmds=$module_cmds fi else if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then cmds=$archive_expsym_cmds else cmds=$archive_cmds fi fi fi if test -n "$delfiles"; then # Append the command to remove temporary files to $cmds. eval cmds=\"\$cmds~\$RM $delfiles\" fi # Add any objects from preloaded convenience libraries if test -n "$dlprefiles"; then gentop="$output_objdir/${outputname}x" generated+=" $gentop" func_extract_archives $gentop $dlprefiles libobjs+=" $func_extract_archives_result" test "X$libobjs" = "X " && libobjs= fi save_ifs="$IFS"; IFS='~' for cmd in $cmds; do IFS="$save_ifs" eval cmd=\"$cmd\" $opt_silent || { func_quote_for_expand "$cmd" eval "func_echo $func_quote_for_expand_result" } $opt_dry_run || eval "$cmd" || { lt_exit=$? # Restore the uninstalled library and exit if test "$opt_mode" = relink; then ( cd "$output_objdir" && \ $RM "${realname}T" && \ $MV "${realname}U" "$realname" ) fi exit $lt_exit } done IFS="$save_ifs" # Restore the uninstalled library and exit if test "$opt_mode" = relink; then $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}T && $MV $realname ${realname}T && $MV ${realname}U $realname)' || exit $? if test -n "$convenience"; then if test -z "$whole_archive_flag_spec"; then func_show_eval '${RM}r "$gentop"' fi fi exit $EXIT_SUCCESS fi # Create links to the real library. for linkname in $linknames; do if test "$realname" != "$linkname"; then func_show_eval '(cd "$output_objdir" && $RM "$linkname" && $LN_S "$realname" "$linkname")' 'exit $?' fi done # If -module or -export-dynamic was specified, set the dlname. if test "$module" = yes || test "$export_dynamic" = yes; then # On all known operating systems, these are identical. dlname="$soname" fi fi ;; obj) if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then func_warning "\`-dlopen' is ignored for objects" fi case " $deplibs" in *\ -l* | *\ -L*) func_warning "\`-l' and \`-L' are ignored for objects" ;; esac test -n "$rpath" && \ func_warning "\`-rpath' is ignored for objects" test -n "$xrpath" && \ func_warning "\`-R' is ignored for objects" test -n "$vinfo" && \ func_warning "\`-version-info' is ignored for objects" test -n "$release" && \ func_warning "\`-release' is ignored for objects" case $output in *.lo) test -n "$objs$old_deplibs" && \ func_fatal_error "cannot build library object \`$output' from non-libtool objects" libobj=$output func_lo2o "$libobj" obj=$func_lo2o_result ;; *) libobj= obj="$output" ;; esac # Delete the old objects. $opt_dry_run || $RM $obj $libobj # Objects from convenience libraries. This assumes # single-version convenience libraries. Whenever we create # different ones for PIC/non-PIC, this we'll have to duplicate # the extraction. reload_conv_objs= gentop= # reload_cmds runs $LD directly, so let us get rid of # -Wl from whole_archive_flag_spec and hope we can get by with # turning comma into space.. wl= if test -n "$convenience"; then if test -n "$whole_archive_flag_spec"; then eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\" reload_conv_objs=$reload_objs\ `$ECHO "$tmp_whole_archive_flags" | $SED 's|,| |g'` else gentop="$output_objdir/${obj}x" generated+=" $gentop" func_extract_archives $gentop $convenience reload_conv_objs="$reload_objs $func_extract_archives_result" fi fi # If we're not building shared, we need to use non_pic_objs test "$build_libtool_libs" != yes && libobjs="$non_pic_objects" # Create the old-style object. reload_objs="$objs$old_deplibs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.${libext}$/d; /\.lib$/d; $lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test output="$obj" func_execute_cmds "$reload_cmds" 'exit $?' # Exit if we aren't doing a library object file. if test -z "$libobj"; then if test -n "$gentop"; then func_show_eval '${RM}r "$gentop"' fi exit $EXIT_SUCCESS fi if test "$build_libtool_libs" != yes; then if test -n "$gentop"; then func_show_eval '${RM}r "$gentop"' fi # Create an invalid libtool object if no PIC, so that we don't # accidentally link it into a program. # $show "echo timestamp > $libobj" # $opt_dry_run || eval "echo timestamp > $libobj" || exit $? exit $EXIT_SUCCESS fi if test -n "$pic_flag" || test "$pic_mode" != default; then # Only do commands if we really have different PIC objects. reload_objs="$libobjs $reload_conv_objs" output="$libobj" func_execute_cmds "$reload_cmds" 'exit $?' fi if test -n "$gentop"; then func_show_eval '${RM}r "$gentop"' fi exit $EXIT_SUCCESS ;; prog) case $host in *cygwin*) func_stripname '' '.exe' "$output" output=$func_stripname_result.exe;; esac test -n "$vinfo" && \ func_warning "\`-version-info' is ignored for programs" test -n "$release" && \ func_warning "\`-release' is ignored for programs" test "$preload" = yes \ && test "$dlopen_support" = unknown \ && test "$dlopen_self" = unknown \ && test "$dlopen_self_static" = unknown && \ func_warning "\`LT_INIT([dlopen])' not used. Assuming no dlopen support." case $host in *-*-rhapsody* | *-*-darwin1.[012]) # On Rhapsody replace the C library is the System framework compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's/ -lc / System.ltframework /'` finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's/ -lc / System.ltframework /'` ;; esac case $host in *-*-darwin*) # Don't allow lazy linking, it breaks C++ global constructors # But is supposedly fixed on 10.4 or later (yay!). if test "$tagname" = CXX ; then case ${MACOSX_DEPLOYMENT_TARGET-10.0} in 10.[0123]) compile_command+=" ${wl}-bind_at_load" finalize_command+=" ${wl}-bind_at_load" ;; esac fi # Time to change all our "foo.ltframework" stuff back to "-framework foo" compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` ;; esac # move library search paths that coincide with paths to not yet # installed libraries to the beginning of the library search list new_libs= for path in $notinst_path; do case " $new_libs " in *" -L$path/$objdir "*) ;; *) case " $compile_deplibs " in *" -L$path/$objdir "*) new_libs+=" -L$path/$objdir" ;; esac ;; esac done for deplib in $compile_deplibs; do case $deplib in -L*) case " $new_libs " in *" $deplib "*) ;; *) new_libs+=" $deplib" ;; esac ;; *) new_libs+=" $deplib" ;; esac done compile_deplibs="$new_libs" compile_command+=" $compile_deplibs" finalize_command+=" $finalize_deplibs" if test -n "$rpath$xrpath"; then # If the user specified any rpath flags, then add them. for libdir in $rpath $xrpath; do # This is the magic to use -rpath. case "$finalize_rpath " in *" $libdir "*) ;; *) finalize_rpath+=" $libdir" ;; esac done fi # Now hardcode the library paths rpath= hardcode_libdirs= for libdir in $compile_rpath $finalize_rpath; do if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then if test -z "$hardcode_libdirs"; then hardcode_libdirs="$libdir" else # Just accumulate the unique libdirs. case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ;; *) hardcode_libdirs+="$hardcode_libdir_separator$libdir" ;; esac fi else eval flag=\"$hardcode_libdir_flag_spec\" rpath+=" $flag" fi elif test -n "$runpath_var"; then case "$perm_rpath " in *" $libdir "*) ;; *) perm_rpath+=" $libdir" ;; esac fi case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) testbindir=`${ECHO} "$libdir" | ${SED} -e 's*/lib$*/bin*'` case :$dllsearchpath: in *":$libdir:"*) ;; ::) dllsearchpath=$libdir;; *) dllsearchpath+=":$libdir";; esac case :$dllsearchpath: in *":$testbindir:"*) ;; ::) dllsearchpath=$testbindir;; *) dllsearchpath+=":$testbindir";; esac ;; esac done # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then libdir="$hardcode_libdirs" eval rpath=\" $hardcode_libdir_flag_spec\" fi compile_rpath="$rpath" rpath= hardcode_libdirs= for libdir in $finalize_rpath; do if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then if test -z "$hardcode_libdirs"; then hardcode_libdirs="$libdir" else # Just accumulate the unique libdirs. case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ;; *) hardcode_libdirs+="$hardcode_libdir_separator$libdir" ;; esac fi else eval flag=\"$hardcode_libdir_flag_spec\" rpath+=" $flag" fi elif test -n "$runpath_var"; then case "$finalize_perm_rpath " in *" $libdir "*) ;; *) finalize_perm_rpath+=" $libdir" ;; esac fi done # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then libdir="$hardcode_libdirs" eval rpath=\" $hardcode_libdir_flag_spec\" fi finalize_rpath="$rpath" if test -n "$libobjs" && test "$build_old_libs" = yes; then # Transform all the library objects into standard objects. compile_command=`$ECHO "$compile_command" | $SP2NL | $SED "$lo2o" | $NL2SP` finalize_command=`$ECHO "$finalize_command" | $SP2NL | $SED "$lo2o" | $NL2SP` fi func_generate_dlsyms "$outputname" "@PROGRAM@" "no" # template prelinking step if test -n "$prelink_cmds"; then func_execute_cmds "$prelink_cmds" 'exit $?' fi wrappers_required=yes case $host in *cegcc* | *mingw32ce*) # Disable wrappers for cegcc and mingw32ce hosts, we are cross compiling anyway. wrappers_required=no ;; *cygwin* | *mingw* ) if test "$build_libtool_libs" != yes; then wrappers_required=no fi ;; *) if test "$need_relink" = no || test "$build_libtool_libs" != yes; then wrappers_required=no fi ;; esac if test "$wrappers_required" = no; then # Replace the output file specification. compile_command=`$ECHO "$compile_command" | $SED 's%@OUTPUT@%'"$output"'%g'` link_command="$compile_command$compile_rpath" # We have no uninstalled library dependencies, so finalize right now. exit_status=0 func_show_eval "$link_command" 'exit_status=$?' if test -n "$postlink_cmds"; then func_to_tool_file "$output" postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` func_execute_cmds "$postlink_cmds" 'exit $?' fi # Delete the generated files. if test -f "$output_objdir/${outputname}S.${objext}"; then func_show_eval '$RM "$output_objdir/${outputname}S.${objext}"' fi exit $exit_status fi if test -n "$compile_shlibpath$finalize_shlibpath"; then compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command" fi if test -n "$finalize_shlibpath"; then finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command" fi compile_var= finalize_var= if test -n "$runpath_var"; then if test -n "$perm_rpath"; then # We should set the runpath_var. rpath= for dir in $perm_rpath; do rpath+="$dir:" done compile_var="$runpath_var=\"$rpath\$$runpath_var\" " fi if test -n "$finalize_perm_rpath"; then # We should set the runpath_var. rpath= for dir in $finalize_perm_rpath; do rpath+="$dir:" done finalize_var="$runpath_var=\"$rpath\$$runpath_var\" " fi fi if test "$no_install" = yes; then # We don't need to create a wrapper script. link_command="$compile_var$compile_command$compile_rpath" # Replace the output file specification. link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output"'%g'` # Delete the old output file. $opt_dry_run || $RM $output # Link the executable and exit func_show_eval "$link_command" 'exit $?' if test -n "$postlink_cmds"; then func_to_tool_file "$output" postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` func_execute_cmds "$postlink_cmds" 'exit $?' fi exit $EXIT_SUCCESS fi if test "$hardcode_action" = relink; then # Fast installation is not supported link_command="$compile_var$compile_command$compile_rpath" relink_command="$finalize_var$finalize_command$finalize_rpath" func_warning "this platform does not like uninstalled shared libraries" func_warning "\`$output' will be relinked during installation" else if test "$fast_install" != no; then link_command="$finalize_var$compile_command$finalize_rpath" if test "$fast_install" = yes; then relink_command=`$ECHO "$compile_var$compile_command$compile_rpath" | $SED 's%@OUTPUT@%\$progdir/\$file%g'` else # fast_install is set to needless relink_command= fi else link_command="$compile_var$compile_command$compile_rpath" relink_command="$finalize_var$finalize_command$finalize_rpath" fi fi # Replace the output file specification. link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'` # Delete the old output files. $opt_dry_run || $RM $output $output_objdir/$outputname $output_objdir/lt-$outputname func_show_eval "$link_command" 'exit $?' if test -n "$postlink_cmds"; then func_to_tool_file "$output_objdir/$outputname" postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` func_execute_cmds "$postlink_cmds" 'exit $?' fi # Now create the wrapper script. func_verbose "creating $output" # Quote the relink command for shipping. if test -n "$relink_command"; then # Preserve any variables that may affect compiler behavior for var in $variables_saved_for_relink; do if eval test -z \"\${$var+set}\"; then relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" elif eval var_value=\$$var; test -z "$var_value"; then relink_command="$var=; export $var; $relink_command" else func_quote_for_eval "$var_value" relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" fi done relink_command="(cd `pwd`; $relink_command)" relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"` fi # Only actually do things if not in dry run mode. $opt_dry_run || { # win32 will think the script is a binary if it has # a .exe suffix, so we strip it off here. case $output in *.exe) func_stripname '' '.exe' "$output" output=$func_stripname_result ;; esac # test for cygwin because mv fails w/o .exe extensions case $host in *cygwin*) exeext=.exe func_stripname '' '.exe' "$outputname" outputname=$func_stripname_result ;; *) exeext= ;; esac case $host in *cygwin* | *mingw* ) func_dirname_and_basename "$output" "" "." output_name=$func_basename_result output_path=$func_dirname_result cwrappersource="$output_path/$objdir/lt-$output_name.c" cwrapper="$output_path/$output_name.exe" $RM $cwrappersource $cwrapper trap "$RM $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15 func_emit_cwrapperexe_src > $cwrappersource # The wrapper executable is built using the $host compiler, # because it contains $host paths and files. If cross- # compiling, it, like the target executable, must be # executed on the $host or under an emulation environment. $opt_dry_run || { $LTCC $LTCFLAGS -o $cwrapper $cwrappersource $STRIP $cwrapper } # Now, create the wrapper script for func_source use: func_ltwrapper_scriptname $cwrapper $RM $func_ltwrapper_scriptname_result trap "$RM $func_ltwrapper_scriptname_result; exit $EXIT_FAILURE" 1 2 15 $opt_dry_run || { # note: this script will not be executed, so do not chmod. if test "x$build" = "x$host" ; then $cwrapper --lt-dump-script > $func_ltwrapper_scriptname_result else func_emit_wrapper no > $func_ltwrapper_scriptname_result fi } ;; * ) $RM $output trap "$RM $output; exit $EXIT_FAILURE" 1 2 15 func_emit_wrapper no > $output chmod +x $output ;; esac } exit $EXIT_SUCCESS ;; esac # See if we need to build an old-fashioned archive. for oldlib in $oldlibs; do if test "$build_libtool_libs" = convenience; then oldobjs="$libobjs_save $symfileobj" addlibs="$convenience" build_libtool_libs=no else if test "$build_libtool_libs" = module; then oldobjs="$libobjs_save" build_libtool_libs=no else oldobjs="$old_deplibs $non_pic_objects" if test "$preload" = yes && test -f "$symfileobj"; then oldobjs+=" $symfileobj" fi fi addlibs="$old_convenience" fi if test -n "$addlibs"; then gentop="$output_objdir/${outputname}x" generated+=" $gentop" func_extract_archives $gentop $addlibs oldobjs+=" $func_extract_archives_result" fi # Do each command in the archive commands. if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then cmds=$old_archive_from_new_cmds else # Add any objects from preloaded convenience libraries if test -n "$dlprefiles"; then gentop="$output_objdir/${outputname}x" generated+=" $gentop" func_extract_archives $gentop $dlprefiles oldobjs+=" $func_extract_archives_result" fi # POSIX demands no paths to be encoded in archives. We have # to avoid creating archives with duplicate basenames if we # might have to extract them afterwards, e.g., when creating a # static archive out of a convenience library, or when linking # the entirety of a libtool archive into another (currently # not supported by libtool). if (for obj in $oldobjs do func_basename "$obj" $ECHO "$func_basename_result" done | sort | sort -uc >/dev/null 2>&1); then : else echo "copying selected object files to avoid basename conflicts..." gentop="$output_objdir/${outputname}x" generated+=" $gentop" func_mkdir_p "$gentop" save_oldobjs=$oldobjs oldobjs= counter=1 for obj in $save_oldobjs do func_basename "$obj" objbase="$func_basename_result" case " $oldobjs " in " ") oldobjs=$obj ;; *[\ /]"$objbase "*) while :; do # Make sure we don't pick an alternate name that also # overlaps. newobj=lt$counter-$objbase func_arith $counter + 1 counter=$func_arith_result case " $oldobjs " in *[\ /]"$newobj "*) ;; *) if test ! -f "$gentop/$newobj"; then break; fi ;; esac done func_show_eval "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj" oldobjs+=" $gentop/$newobj" ;; *) oldobjs+=" $obj" ;; esac done fi func_to_tool_file "$oldlib" func_convert_file_msys_to_w32 tool_oldlib=$func_to_tool_file_result eval cmds=\"$old_archive_cmds\" func_len " $cmds" len=$func_len_result if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then cmds=$old_archive_cmds elif test -n "$archiver_list_spec"; then func_verbose "using command file archive linking..." for obj in $oldobjs do func_to_tool_file "$obj" $ECHO "$func_to_tool_file_result" done > $output_objdir/$libname.libcmd func_to_tool_file "$output_objdir/$libname.libcmd" oldobjs=" $archiver_list_spec$func_to_tool_file_result" cmds=$old_archive_cmds else # the command line is too long to link in one step, link in parts func_verbose "using piecewise archive linking..." save_RANLIB=$RANLIB RANLIB=: objlist= concat_cmds= save_oldobjs=$oldobjs oldobjs= # Is there a better way of finding the last object in the list? for obj in $save_oldobjs do last_oldobj=$obj done eval test_cmds=\"$old_archive_cmds\" func_len " $test_cmds" len0=$func_len_result len=$len0 for obj in $save_oldobjs do func_len " $obj" func_arith $len + $func_len_result len=$func_arith_result objlist+=" $obj" if test "$len" -lt "$max_cmd_len"; then : else # the above command should be used before it gets too long oldobjs=$objlist if test "$obj" = "$last_oldobj" ; then RANLIB=$save_RANLIB fi test -z "$concat_cmds" || concat_cmds=$concat_cmds~ eval concat_cmds=\"\${concat_cmds}$old_archive_cmds\" objlist= len=$len0 fi done RANLIB=$save_RANLIB oldobjs=$objlist if test "X$oldobjs" = "X" ; then eval cmds=\"\$concat_cmds\" else eval cmds=\"\$concat_cmds~\$old_archive_cmds\" fi fi fi func_execute_cmds "$cmds" 'exit $?' done test -n "$generated" && \ func_show_eval "${RM}r$generated" # Now create the libtool archive. case $output in *.la) old_library= test "$build_old_libs" = yes && old_library="$libname.$libext" func_verbose "creating $output" # Preserve any variables that may affect compiler behavior for var in $variables_saved_for_relink; do if eval test -z \"\${$var+set}\"; then relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" elif eval var_value=\$$var; test -z "$var_value"; then relink_command="$var=; export $var; $relink_command" else func_quote_for_eval "$var_value" relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" fi done # Quote the link command for shipping. relink_command="(cd `pwd`; $SHELL $progpath $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)" relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"` if test "$hardcode_automatic" = yes ; then relink_command= fi # Only create the output if not a dry run. $opt_dry_run || { for installed in no yes; do if test "$installed" = yes; then if test -z "$install_libdir"; then break fi output="$output_objdir/$outputname"i # Replace all uninstalled libtool libraries with the installed ones newdependency_libs= for deplib in $dependency_libs; do case $deplib in *.la) func_basename "$deplib" name="$func_basename_result" func_resolve_sysroot "$deplib" eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $func_resolve_sysroot_result` test -z "$libdir" && \ func_fatal_error "\`$deplib' is not a valid libtool archive" newdependency_libs+=" ${lt_sysroot:+=}$libdir/$name" ;; -L*) func_stripname -L '' "$deplib" func_replace_sysroot "$func_stripname_result" newdependency_libs+=" -L$func_replace_sysroot_result" ;; -R*) func_stripname -R '' "$deplib" func_replace_sysroot "$func_stripname_result" newdependency_libs+=" -R$func_replace_sysroot_result" ;; *) newdependency_libs+=" $deplib" ;; esac done dependency_libs="$newdependency_libs" newdlfiles= for lib in $dlfiles; do case $lib in *.la) func_basename "$lib" name="$func_basename_result" eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` test -z "$libdir" && \ func_fatal_error "\`$lib' is not a valid libtool archive" newdlfiles+=" ${lt_sysroot:+=}$libdir/$name" ;; *) newdlfiles+=" $lib" ;; esac done dlfiles="$newdlfiles" newdlprefiles= for lib in $dlprefiles; do case $lib in *.la) # Only pass preopened files to the pseudo-archive (for # eventual linking with the app. that links it) if we # didn't already link the preopened objects directly into # the library: func_basename "$lib" name="$func_basename_result" eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` test -z "$libdir" && \ func_fatal_error "\`$lib' is not a valid libtool archive" newdlprefiles+=" ${lt_sysroot:+=}$libdir/$name" ;; esac done dlprefiles="$newdlprefiles" else newdlfiles= for lib in $dlfiles; do case $lib in [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; *) abs=`pwd`"/$lib" ;; esac newdlfiles+=" $abs" done dlfiles="$newdlfiles" newdlprefiles= for lib in $dlprefiles; do case $lib in [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; *) abs=`pwd`"/$lib" ;; esac newdlprefiles+=" $abs" done dlprefiles="$newdlprefiles" fi $RM $output # place dlname in correct position for cygwin # In fact, it would be nice if we could use this code for all target # systems that can't hard-code library paths into their executables # and that have no shared library path variable independent of PATH, # but it turns out we can't easily determine that from inspecting # libtool variables, so we have to hard-code the OSs to which it # applies here; at the moment, that means platforms that use the PE # object format with DLL files. See the long comment at the top of # tests/bindir.at for full details. tdlname=$dlname case $host,$output,$installed,$module,$dlname in *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll) # If a -bindir argument was supplied, place the dll there. if test "x$bindir" != x ; then func_relative_path "$install_libdir" "$bindir" tdlname=$func_relative_path_result$dlname else # Otherwise fall back on heuristic. tdlname=../bin/$dlname fi ;; esac $ECHO > $output "\ # $outputname - a libtool library file # Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION # # Please DO NOT delete this file! # It is necessary for linking the library. # The name that we can dlopen(3). dlname='$tdlname' # Names of this library. library_names='$library_names' # The name of the static archive. old_library='$old_library' # Linker flags that can not go in dependency_libs. inherited_linker_flags='$new_inherited_linker_flags' # Libraries that this one depends upon. dependency_libs='$dependency_libs' # Names of additional weak libraries provided by this library weak_library_names='$weak_libs' # Version information for $libname. current=$current age=$age revision=$revision # Is this an already installed library? installed=$installed # Should we warn about portability when linking against -modules? shouldnotlink=$module # Files to dlopen/dlpreopen dlopen='$dlfiles' dlpreopen='$dlprefiles' # Directory that this library needs to be installed in: libdir='$install_libdir'" if test "$installed" = no && test "$need_relink" = yes; then $ECHO >> $output "\ relink_command=\"$relink_command\"" fi done } # Do a symbolic link so that the libtool archive can be found in # LD_LIBRARY_PATH before the program is installed. func_show_eval '( cd "$output_objdir" && $RM "$outputname" && $LN_S "../$outputname" "$outputname" )' 'exit $?' ;; esac exit $EXIT_SUCCESS } { test "$opt_mode" = link || test "$opt_mode" = relink; } && func_mode_link ${1+"$@"} # func_mode_uninstall arg... func_mode_uninstall () { $opt_debug RM="$nonopt" files= rmforce= exit_status=0 # This variable tells wrapper scripts just to set variables rather # than running their programs. libtool_install_magic="$magic" for arg do case $arg in -f) RM+=" $arg"; rmforce=yes ;; -*) RM+=" $arg" ;; *) files+=" $arg" ;; esac done test -z "$RM" && \ func_fatal_help "you must specify an RM program" rmdirs= for file in $files; do func_dirname "$file" "" "." dir="$func_dirname_result" if test "X$dir" = X.; then odir="$objdir" else odir="$dir/$objdir" fi func_basename "$file" name="$func_basename_result" test "$opt_mode" = uninstall && odir="$dir" # Remember odir for removal later, being careful to avoid duplicates if test "$opt_mode" = clean; then case " $rmdirs " in *" $odir "*) ;; *) rmdirs+=" $odir" ;; esac fi # Don't error if the file doesn't exist and rm -f was used. if { test -L "$file"; } >/dev/null 2>&1 || { test -h "$file"; } >/dev/null 2>&1 || test -f "$file"; then : elif test -d "$file"; then exit_status=1 continue elif test "$rmforce" = yes; then continue fi rmfiles="$file" case $name in *.la) # Possibly a libtool archive, so verify it. if func_lalib_p "$file"; then func_source $dir/$name # Delete the libtool libraries and symlinks. for n in $library_names; do rmfiles+=" $odir/$n" done test -n "$old_library" && rmfiles+=" $odir/$old_library" case "$opt_mode" in clean) case " $library_names " in *" $dlname "*) ;; *) test -n "$dlname" && rmfiles+=" $odir/$dlname" ;; esac test -n "$libdir" && rmfiles+=" $odir/$name $odir/${name}i" ;; uninstall) if test -n "$library_names"; then # Do each command in the postuninstall commands. func_execute_cmds "$postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1' fi if test -n "$old_library"; then # Do each command in the old_postuninstall commands. func_execute_cmds "$old_postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1' fi # FIXME: should reinstall the best remaining shared library. ;; esac fi ;; *.lo) # Possibly a libtool object, so verify it. if func_lalib_p "$file"; then # Read the .lo file func_source $dir/$name # Add PIC object to the list of files to remove. if test -n "$pic_object" && test "$pic_object" != none; then rmfiles+=" $dir/$pic_object" fi # Add non-PIC object to the list of files to remove. if test -n "$non_pic_object" && test "$non_pic_object" != none; then rmfiles+=" $dir/$non_pic_object" fi fi ;; *) if test "$opt_mode" = clean ; then noexename=$name case $file in *.exe) func_stripname '' '.exe' "$file" file=$func_stripname_result func_stripname '' '.exe' "$name" noexename=$func_stripname_result # $file with .exe has already been added to rmfiles, # add $file without .exe rmfiles+=" $file" ;; esac # Do a test to see if this is a libtool program. if func_ltwrapper_p "$file"; then if func_ltwrapper_executable_p "$file"; then func_ltwrapper_scriptname "$file" relink_command= func_source $func_ltwrapper_scriptname_result rmfiles+=" $func_ltwrapper_scriptname_result" else relink_command= func_source $dir/$noexename fi # note $name still contains .exe if it was in $file originally # as does the version of $file that was added into $rmfiles rmfiles+=" $odir/$name $odir/${name}S.${objext}" if test "$fast_install" = yes && test -n "$relink_command"; then rmfiles+=" $odir/lt-$name" fi if test "X$noexename" != "X$name" ; then rmfiles+=" $odir/lt-${noexename}.c" fi fi fi ;; esac func_show_eval "$RM $rmfiles" 'exit_status=1' done # Try to remove the ${objdir}s in the directories where we deleted files for dir in $rmdirs; do if test -d "$dir"; then func_show_eval "rmdir $dir >/dev/null 2>&1" fi done exit $exit_status } { test "$opt_mode" = uninstall || test "$opt_mode" = clean; } && func_mode_uninstall ${1+"$@"} test -z "$opt_mode" && { help="$generic_help" func_fatal_help "you must specify a MODE" } test -z "$exec_cmd" && \ func_fatal_help "invalid operation mode \`$opt_mode'" if test -n "$exec_cmd"; then eval exec "$exec_cmd" exit $EXIT_FAILURE fi exit $exit_status # The TAGs below are defined such that we never get into a situation # in which we disable both kinds of libraries. Given conflicting # choices, we go for a static library, that is the most portable, # since we can't tell whether shared libraries were disabled because # the user asked for that or because the platform doesn't support # them. This is particularly important on AIX, because we don't # support having both static and shared libraries enabled at the same # time on that platform, so we default to a shared-only configuration. # If a disable-shared tag is given, we'll fallback to a static-only # configuration. But we'll never go from static-only to shared-only. # ### BEGIN LIBTOOL TAG CONFIG: disable-shared build_libtool_libs=no build_old_libs=yes # ### END LIBTOOL TAG CONFIG: disable-shared # ### BEGIN LIBTOOL TAG CONFIG: disable-static build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac` # ### END LIBTOOL TAG CONFIG: disable-static # Local Variables: # mode:shell-script # sh-indentation:2 # End: # vi:sw=2 # ### BEGIN LIBTOOL TAG CONFIG: CXX # The linker used to build libraries. LD="/usr/bin/ld" # How to create reloadable object files. reload_flag=" -r" reload_cmds="\$LD\$reload_flag -o \$output\$reload_objs" # Commands used to build an old-style archive. old_archive_cmds="\$AR \$AR_FLAGS \$oldlib\$oldobjs~\$RANLIB \$tool_oldlib" # A language specific compiler. CC="g++" # Is the compiler the GNU compiler? with_gcc=yes # Compiler flag to turn off builtin functions. no_builtin_flag=" -fno-builtin" # Additional compiler flags for building library objects. pic_flag=" -fPIC -DPIC" # How to pass a linker flag through the compiler. wl="-Wl," # Compiler flag to prevent dynamic linking. link_static_flag="" # Does compiler simultaneously support -c and -o options? compiler_c_o="yes" # Whether or not to add -lc for building shared libraries. build_libtool_need_lc=no # Whether or not to disallow shared libs when runtime libs are static. allow_libtool_libs_with_static_runtimes=no # Compiler flag to allow reflexive dlopens. export_dynamic_flag_spec="\${wl}--export-dynamic" # Compiler flag to generate shared objects directly from archives. whole_archive_flag_spec="\${wl}--whole-archive\$convenience \${wl}--no-whole-archive" # Whether the compiler copes with passing no objects directly. compiler_needs_object="no" # Create an old-style archive from a shared archive. old_archive_from_new_cmds="" # Create a temporary old-style archive to link instead of a shared archive. old_archive_from_expsyms_cmds="" # Commands used to build a shared archive. archive_cmds="\$CC \$pic_flag -shared -nostdlib \$predep_objects \$libobjs \$deplibs \$postdep_objects \$compiler_flags \${wl}-soname \$wl\$soname -o \$lib" archive_expsym_cmds="\$CC \$pic_flag -shared -nostdlib \$predep_objects \$libobjs \$deplibs \$postdep_objects \$compiler_flags \${wl}-soname \$wl\$soname \${wl}-retain-symbols-file \$wl\$export_symbols -o \$lib" # Commands used to build a loadable module if different from building # a shared archive. module_cmds="" module_expsym_cmds="" # Whether we are building with GNU ld or not. with_gnu_ld="yes" # Flag that allows shared libraries with undefined symbols to be built. allow_undefined_flag="" # Flag that enforces no undefined symbols. no_undefined_flag="" # Flag to hardcode $libdir into a binary during linking. # This must work even if $libdir does not exist hardcode_libdir_flag_spec="\${wl}-rpath \${wl}\$libdir" # Whether we need a single "-rpath" flag with a separated argument. hardcode_libdir_separator="" # Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes # DIR into the resulting binary. hardcode_direct=no # Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes # DIR into the resulting binary and the resulting library dependency is # "absolute",i.e impossible to change by setting ${shlibpath_var} if the # library is relocated. hardcode_direct_absolute=no # Set to "yes" if using the -LDIR flag during linking hardcodes DIR # into the resulting binary. hardcode_minus_L=no # Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR # into the resulting binary. hardcode_shlibpath_var=unsupported # Set to "yes" if building a shared library automatically hardcodes DIR # into the library and all subsequent libraries and executables linked # against it. hardcode_automatic=no # Set to yes if linker adds runtime paths of dependent libraries # to runtime path list. inherit_rpath=no # Whether libtool must link a program against all its dependency libraries. link_all_deplibs=no # Set to "yes" if exported symbols are required. always_export_symbols=no # The commands to list exported symbols. export_symbols_cmds="\$NM \$libobjs \$convenience | \$global_symbol_pipe | \$SED 's/.* //' | sort | uniq > \$export_symbols" # Symbols that should not be listed in the preloaded symbols. exclude_expsyms="_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*" # Symbols that must always be exported. include_expsyms="" # Commands necessary for linking programs (against libraries) with templates. prelink_cmds="" # Commands necessary for finishing linking programs. postlink_cmds="" # Specify filename containing input files. file_list_spec="" # How to hardcode a shared library path into an executable. hardcode_action=immediate # The directories searched by this compiler when creating a shared library. compiler_lib_search_dirs="/usr/lib/gcc/i686-redhat-linux/4.9.2 /usr/lib/gcc/i686-redhat-linux/4.9.2/../../.." # Dependencies to place before and after the objects being linked to # create a shared library. predep_objects="/usr/lib/gcc/i686-redhat-linux/4.9.2/../../../crti.o /usr/lib/gcc/i686-redhat-linux/4.9.2/crtbeginS.o" postdep_objects="/usr/lib/gcc/i686-redhat-linux/4.9.2/crtendS.o /usr/lib/gcc/i686-redhat-linux/4.9.2/../../../crtn.o" predeps="" postdeps="-lstdc++ -lm -lgcc_s -lc -lgcc_s" # The library search path used internally by the compiler when linking # a shared library. compiler_lib_search_path="-L/usr/lib/gcc/i686-redhat-linux/4.9.2 -L/usr/lib/gcc/i686-redhat-linux/4.9.2/../../.." # ### END LIBTOOL TAG CONFIG: CXX dlt-daemon-2.18.4/gtest-1.7.0/m4/000077500000000000000000000000001353342203500157415ustar00rootroot00000000000000dlt-daemon-2.18.4/gtest-1.7.0/m4/acx_pthread.m4000066400000000000000000000317661353342203500205020ustar00rootroot00000000000000# This was retrieved from # http://svn.0pointer.de/viewvc/trunk/common/acx_pthread.m4?revision=1277&root=avahi # See also (perhaps for new versions?) # http://svn.0pointer.de/viewvc/trunk/common/acx_pthread.m4?root=avahi # # We've rewritten the inconsistency check code (from avahi), to work # more broadly. In particular, it no longer assumes ld accepts -zdefs. # This caused a restructing of the code, but the functionality has only # changed a little. dnl @synopsis ACX_PTHREAD([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]]) dnl dnl @summary figure out how to build C programs using POSIX threads dnl dnl This macro figures out how to build C programs using POSIX threads. dnl It sets the PTHREAD_LIBS output variable to the threads library and dnl linker flags, and the PTHREAD_CFLAGS output variable to any special dnl C compiler flags that are needed. (The user can also force certain dnl compiler flags/libs to be tested by setting these environment dnl variables.) dnl dnl Also sets PTHREAD_CC to any special C compiler that is needed for dnl multi-threaded programs (defaults to the value of CC otherwise). dnl (This is necessary on AIX to use the special cc_r compiler alias.) dnl dnl NOTE: You are assumed to not only compile your program with these dnl flags, but also link it with them as well. e.g. you should link dnl with $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS dnl $LIBS dnl dnl If you are only building threads programs, you may wish to use dnl these variables in your default LIBS, CFLAGS, and CC: dnl dnl LIBS="$PTHREAD_LIBS $LIBS" dnl CFLAGS="$CFLAGS $PTHREAD_CFLAGS" dnl CC="$PTHREAD_CC" dnl dnl In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute dnl constant has a nonstandard name, defines PTHREAD_CREATE_JOINABLE to dnl that name (e.g. PTHREAD_CREATE_UNDETACHED on AIX). dnl dnl ACTION-IF-FOUND is a list of shell commands to run if a threads dnl library is found, and ACTION-IF-NOT-FOUND is a list of commands to dnl run it if it is not found. If ACTION-IF-FOUND is not specified, the dnl default action will define HAVE_PTHREAD. dnl dnl Please let the authors know if this macro fails on any platform, or dnl if you have any other suggestions or comments. This macro was based dnl on work by SGJ on autoconf scripts for FFTW (www.fftw.org) (with dnl help from M. Frigo), as well as ac_pthread and hb_pthread macros dnl posted by Alejandro Forero Cuervo to the autoconf macro repository. dnl We are also grateful for the helpful feedback of numerous users. dnl dnl @category InstalledPackages dnl @author Steven G. Johnson dnl @version 2006-05-29 dnl @license GPLWithACException dnl dnl Checks for GCC shared/pthread inconsistency based on work by dnl Marcin Owsiany AC_DEFUN([ACX_PTHREAD], [ AC_REQUIRE([AC_CANONICAL_HOST]) AC_LANG_SAVE AC_LANG_C acx_pthread_ok=no # We used to check for pthread.h first, but this fails if pthread.h # requires special compiler flags (e.g. on True64 or Sequent). # It gets checked for in the link test anyway. # First of all, check if the user has set any of the PTHREAD_LIBS, # etcetera environment variables, and if threads linking works using # them: if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $PTHREAD_CFLAGS" save_LIBS="$LIBS" LIBS="$PTHREAD_LIBS $LIBS" AC_MSG_CHECKING([for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS]) AC_TRY_LINK_FUNC(pthread_join, acx_pthread_ok=yes) AC_MSG_RESULT($acx_pthread_ok) if test x"$acx_pthread_ok" = xno; then PTHREAD_LIBS="" PTHREAD_CFLAGS="" fi LIBS="$save_LIBS" CFLAGS="$save_CFLAGS" fi # We must check for the threads library under a number of different # names; the ordering is very important because some systems # (e.g. DEC) have both -lpthread and -lpthreads, where one of the # libraries is broken (non-POSIX). # Create a list of thread flags to try. Items starting with a "-" are # C compiler flags, and other items are library names, except for "none" # which indicates that we try without any flags at all, and "pthread-config" # which is a program returning the flags for the Pth emulation library. acx_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config" # The ordering *is* (sometimes) important. Some notes on the # individual items follow: # pthreads: AIX (must check this before -lpthread) # none: in case threads are in libc; should be tried before -Kthread and # other compiler flags to prevent continual compiler warnings # -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h) # -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able) # lthread: LinuxThreads port on FreeBSD (also preferred to -pthread) # -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads) # -pthreads: Solaris/gcc # -mthreads: Mingw32/gcc, Lynx/gcc # -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it # doesn't hurt to check since this sometimes defines pthreads too; # also defines -D_REENTRANT) # ... -mt is also the pthreads flag for HP/aCC # pthread: Linux, etcetera # --thread-safe: KAI C++ # pthread-config: use pthread-config program (for GNU Pth library) case "${host_cpu}-${host_os}" in *solaris*) # On Solaris (at least, for some versions), libc contains stubbed # (non-functional) versions of the pthreads routines, so link-based # tests will erroneously succeed. (We need to link with -pthreads/-mt/ # -lpthread.) (The stubs are missing pthread_cleanup_push, or rather # a function called by this macro, so we could check for that, but # who knows whether they'll stub that too in a future libc.) So, # we'll just look for -pthreads and -lpthread first: acx_pthread_flags="-pthreads pthread -mt -pthread $acx_pthread_flags" ;; esac if test x"$acx_pthread_ok" = xno; then for flag in $acx_pthread_flags; do case $flag in none) AC_MSG_CHECKING([whether pthreads work without any flags]) ;; -*) AC_MSG_CHECKING([whether pthreads work with $flag]) PTHREAD_CFLAGS="$flag" ;; pthread-config) AC_CHECK_PROG(acx_pthread_config, pthread-config, yes, no) if test x"$acx_pthread_config" = xno; then continue; fi PTHREAD_CFLAGS="`pthread-config --cflags`" PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`" ;; *) AC_MSG_CHECKING([for the pthreads library -l$flag]) PTHREAD_LIBS="-l$flag" ;; esac save_LIBS="$LIBS" save_CFLAGS="$CFLAGS" LIBS="$PTHREAD_LIBS $LIBS" CFLAGS="$CFLAGS $PTHREAD_CFLAGS" # Check for various functions. We must include pthread.h, # since some functions may be macros. (On the Sequent, we # need a special flag -Kthread to make this header compile.) # We check for pthread_join because it is in -lpthread on IRIX # while pthread_create is in libc. We check for pthread_attr_init # due to DEC craziness with -lpthreads. We check for # pthread_cleanup_push because it is one of the few pthread # functions on Solaris that doesn't have a non-functional libc stub. # We try pthread_create on general principles. AC_TRY_LINK([#include ], [pthread_t th; pthread_join(th, 0); pthread_attr_init(0); pthread_cleanup_push(0, 0); pthread_create(0,0,0,0); pthread_cleanup_pop(0); ], [acx_pthread_ok=yes]) LIBS="$save_LIBS" CFLAGS="$save_CFLAGS" AC_MSG_RESULT($acx_pthread_ok) if test "x$acx_pthread_ok" = xyes; then break; fi PTHREAD_LIBS="" PTHREAD_CFLAGS="" done fi # Various other checks: if test "x$acx_pthread_ok" = xyes; then save_LIBS="$LIBS" LIBS="$PTHREAD_LIBS $LIBS" save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $PTHREAD_CFLAGS" # Detect AIX lossage: JOINABLE attribute is called UNDETACHED. AC_MSG_CHECKING([for joinable pthread attribute]) attr_name=unknown for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do AC_TRY_LINK([#include ], [int attr=$attr; return attr;], [attr_name=$attr; break]) done AC_MSG_RESULT($attr_name) if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then AC_DEFINE_UNQUOTED(PTHREAD_CREATE_JOINABLE, $attr_name, [Define to necessary symbol if this constant uses a non-standard name on your system.]) fi AC_MSG_CHECKING([if more special flags are required for pthreads]) flag=no case "${host_cpu}-${host_os}" in *-aix* | *-freebsd* | *-darwin*) flag="-D_THREAD_SAFE";; *solaris* | *-osf* | *-hpux*) flag="-D_REENTRANT";; esac AC_MSG_RESULT(${flag}) if test "x$flag" != xno; then PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS" fi LIBS="$save_LIBS" CFLAGS="$save_CFLAGS" # More AIX lossage: must compile with xlc_r or cc_r if test x"$GCC" != xyes; then AC_CHECK_PROGS(PTHREAD_CC, xlc_r cc_r, ${CC}) else PTHREAD_CC=$CC fi # The next part tries to detect GCC inconsistency with -shared on some # architectures and systems. The problem is that in certain # configurations, when -shared is specified, GCC "forgets" to # internally use various flags which are still necessary. # # Prepare the flags # save_CFLAGS="$CFLAGS" save_LIBS="$LIBS" save_CC="$CC" # Try with the flags determined by the earlier checks. # # -Wl,-z,defs forces link-time symbol resolution, so that the # linking checks with -shared actually have any value # # FIXME: -fPIC is required for -shared on many architectures, # so we specify it here, but the right way would probably be to # properly detect whether it is actually required. CFLAGS="-shared -fPIC -Wl,-z,defs $CFLAGS $PTHREAD_CFLAGS" LIBS="$PTHREAD_LIBS $LIBS" CC="$PTHREAD_CC" # In order not to create several levels of indentation, we test # the value of "$done" until we find the cure or run out of ideas. done="no" # First, make sure the CFLAGS we added are actually accepted by our # compiler. If not (and OS X's ld, for instance, does not accept -z), # then we can't do this test. if test x"$done" = xno; then AC_MSG_CHECKING([whether to check for GCC pthread/shared inconsistencies]) AC_TRY_LINK(,, , [done=yes]) if test "x$done" = xyes ; then AC_MSG_RESULT([no]) else AC_MSG_RESULT([yes]) fi fi if test x"$done" = xno; then AC_MSG_CHECKING([whether -pthread is sufficient with -shared]) AC_TRY_LINK([#include ], [pthread_t th; pthread_join(th, 0); pthread_attr_init(0); pthread_cleanup_push(0, 0); pthread_create(0,0,0,0); pthread_cleanup_pop(0); ], [done=yes]) if test "x$done" = xyes; then AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) fi fi # # Linux gcc on some architectures such as mips/mipsel forgets # about -lpthread # if test x"$done" = xno; then AC_MSG_CHECKING([whether -lpthread fixes that]) LIBS="-lpthread $PTHREAD_LIBS $save_LIBS" AC_TRY_LINK([#include ], [pthread_t th; pthread_join(th, 0); pthread_attr_init(0); pthread_cleanup_push(0, 0); pthread_create(0,0,0,0); pthread_cleanup_pop(0); ], [done=yes]) if test "x$done" = xyes; then AC_MSG_RESULT([yes]) PTHREAD_LIBS="-lpthread $PTHREAD_LIBS" else AC_MSG_RESULT([no]) fi fi # # FreeBSD 4.10 gcc forgets to use -lc_r instead of -lc # if test x"$done" = xno; then AC_MSG_CHECKING([whether -lc_r fixes that]) LIBS="-lc_r $PTHREAD_LIBS $save_LIBS" AC_TRY_LINK([#include ], [pthread_t th; pthread_join(th, 0); pthread_attr_init(0); pthread_cleanup_push(0, 0); pthread_create(0,0,0,0); pthread_cleanup_pop(0); ], [done=yes]) if test "x$done" = xyes; then AC_MSG_RESULT([yes]) PTHREAD_LIBS="-lc_r $PTHREAD_LIBS" else AC_MSG_RESULT([no]) fi fi if test x"$done" = xno; then # OK, we have run out of ideas AC_MSG_WARN([Impossible to determine how to use pthreads with shared libraries]) # so it's not safe to assume that we may use pthreads acx_pthread_ok=no fi CFLAGS="$save_CFLAGS" LIBS="$save_LIBS" CC="$save_CC" else PTHREAD_CC="$CC" fi AC_SUBST(PTHREAD_LIBS) AC_SUBST(PTHREAD_CFLAGS) AC_SUBST(PTHREAD_CC) # Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND: if test x"$acx_pthread_ok" = xyes; then ifelse([$1],,AC_DEFINE(HAVE_PTHREAD,1,[Define if you have POSIX threads libraries and header files.]),[$1]) : else acx_pthread_ok=no $2 fi AC_LANG_RESTORE ])dnl ACX_PTHREAD dlt-daemon-2.18.4/gtest-1.7.0/m4/gtest.m4000066400000000000000000000062211353342203500173320ustar00rootroot00000000000000dnl GTEST_LIB_CHECK([minimum version [, dnl action if found [,action if not found]]]) dnl dnl Check for the presence of the Google Test library, optionally at a minimum dnl version, and indicate a viable version with the HAVE_GTEST flag. It defines dnl standard variables for substitution including GTEST_CPPFLAGS, dnl GTEST_CXXFLAGS, GTEST_LDFLAGS, and GTEST_LIBS. It also defines dnl GTEST_VERSION as the version of Google Test found. Finally, it provides dnl optional custom action slots in the event GTEST is found or not. AC_DEFUN([GTEST_LIB_CHECK], [ dnl Provide a flag to enable or disable Google Test usage. AC_ARG_ENABLE([gtest], [AS_HELP_STRING([--enable-gtest], [Enable tests using the Google C++ Testing Framework. (Default is enabled.)])], [], [enable_gtest=]) AC_ARG_VAR([GTEST_CONFIG], [The exact path of Google Test's 'gtest-config' script.]) AC_ARG_VAR([GTEST_CPPFLAGS], [C-like preprocessor flags for Google Test.]) AC_ARG_VAR([GTEST_CXXFLAGS], [C++ compile flags for Google Test.]) AC_ARG_VAR([GTEST_LDFLAGS], [Linker path and option flags for Google Test.]) AC_ARG_VAR([GTEST_LIBS], [Library linking flags for Google Test.]) AC_ARG_VAR([GTEST_VERSION], [The version of Google Test available.]) HAVE_GTEST="no" AS_IF([test "x${enable_gtest}" != "xno"], [AC_MSG_CHECKING([for 'gtest-config']) AS_IF([test "x${enable_gtest}" != "xyes"], [AS_IF([test -x "${enable_gtest}/scripts/gtest-config"], [GTEST_CONFIG="${enable_gtest}/scripts/gtest-config"], [GTEST_CONFIG="${enable_gtest}/bin/gtest-config"]) AS_IF([test -x "${GTEST_CONFIG}"], [], [AC_MSG_RESULT([no]) AC_MSG_ERROR([dnl Unable to locate either a built or installed Google Test. The specific location '${enable_gtest}' was provided for a built or installed Google Test, but no 'gtest-config' script could be found at this location.]) ])], [AC_PATH_PROG([GTEST_CONFIG], [gtest-config])]) AS_IF([test -x "${GTEST_CONFIG}"], [AC_MSG_RESULT([${GTEST_CONFIG}]) m4_ifval([$1], [_gtest_min_version="--min-version=$1" AC_MSG_CHECKING([for Google Test at least version >= $1])], [_gtest_min_version="--min-version=0" AC_MSG_CHECKING([for Google Test])]) AS_IF([${GTEST_CONFIG} ${_gtest_min_version}], [AC_MSG_RESULT([yes]) HAVE_GTEST='yes'], [AC_MSG_RESULT([no])])], [AC_MSG_RESULT([no])]) AS_IF([test "x${HAVE_GTEST}" = "xyes"], [GTEST_CPPFLAGS=`${GTEST_CONFIG} --cppflags` GTEST_CXXFLAGS=`${GTEST_CONFIG} --cxxflags` GTEST_LDFLAGS=`${GTEST_CONFIG} --ldflags` GTEST_LIBS=`${GTEST_CONFIG} --libs` GTEST_VERSION=`${GTEST_CONFIG} --version` AC_DEFINE([HAVE_GTEST],[1],[Defined when Google Test is available.])], [AS_IF([test "x${enable_gtest}" = "xyes"], [AC_MSG_ERROR([dnl Google Test was enabled, but no viable version could be found.]) ])])]) AC_SUBST([HAVE_GTEST]) AM_CONDITIONAL([HAVE_GTEST],[test "x$HAVE_GTEST" = "xyes"]) AS_IF([test "x$HAVE_GTEST" = "xyes"], [m4_ifval([$2], [$2])], [m4_ifval([$3], [$3])]) ]) dlt-daemon-2.18.4/gtest-1.7.0/m4/libtool.m4000066400000000000000000010604341353342203500176570ustar00rootroot00000000000000# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- # # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, # 2006, 2007, 2008, 2009, 2010, 2011 Free Software # Foundation, Inc. # Written by Gordon Matzigkeit, 1996 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. m4_define([_LT_COPYING], [dnl # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, # 2006, 2007, 2008, 2009, 2010, 2011 Free Software # Foundation, Inc. # Written by Gordon Matzigkeit, 1996 # # This file is part of GNU Libtool. # # GNU Libtool is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as # published by the Free Software Foundation; either version 2 of # the License, or (at your option) any later version. # # As a special exception to the GNU General Public License, # if you distribute this file as part of a program or library that # is built using GNU Libtool, you may include this file under the # same distribution terms that you use for the rest of that program. # # GNU Libtool is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with GNU Libtool; see the file COPYING. If not, a copy # can be downloaded from http://www.gnu.org/licenses/gpl.html, or # obtained by writing to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ]) # serial 57 LT_INIT # LT_PREREQ(VERSION) # ------------------ # Complain and exit if this libtool version is less that VERSION. m4_defun([LT_PREREQ], [m4_if(m4_version_compare(m4_defn([LT_PACKAGE_VERSION]), [$1]), -1, [m4_default([$3], [m4_fatal([Libtool version $1 or higher is required], 63)])], [$2])]) # _LT_CHECK_BUILDDIR # ------------------ # Complain if the absolute build directory name contains unusual characters m4_defun([_LT_CHECK_BUILDDIR], [case `pwd` in *\ * | *\ *) AC_MSG_WARN([Libtool does not cope well with whitespace in `pwd`]) ;; esac ]) # LT_INIT([OPTIONS]) # ------------------ AC_DEFUN([LT_INIT], [AC_PREREQ([2.58])dnl We use AC_INCLUDES_DEFAULT AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl AC_BEFORE([$0], [LT_LANG])dnl AC_BEFORE([$0], [LT_OUTPUT])dnl AC_BEFORE([$0], [LTDL_INIT])dnl m4_require([_LT_CHECK_BUILDDIR])dnl dnl Autoconf doesn't catch unexpanded LT_ macros by default: m4_pattern_forbid([^_?LT_[A-Z_]+$])dnl m4_pattern_allow([^(_LT_EOF|LT_DLGLOBAL|LT_DLLAZY_OR_NOW|LT_MULTI_MODULE)$])dnl dnl aclocal doesn't pull ltoptions.m4, ltsugar.m4, or ltversion.m4 dnl unless we require an AC_DEFUNed macro: AC_REQUIRE([LTOPTIONS_VERSION])dnl AC_REQUIRE([LTSUGAR_VERSION])dnl AC_REQUIRE([LTVERSION_VERSION])dnl AC_REQUIRE([LTOBSOLETE_VERSION])dnl m4_require([_LT_PROG_LTMAIN])dnl _LT_SHELL_INIT([SHELL=${CONFIG_SHELL-/bin/sh}]) dnl Parse OPTIONS _LT_SET_OPTIONS([$0], [$1]) # This can be used to rebuild libtool when needed LIBTOOL_DEPS="$ltmain" # Always use our own libtool. LIBTOOL='$(SHELL) $(top_builddir)/libtool' AC_SUBST(LIBTOOL)dnl _LT_SETUP # Only expand once: m4_define([LT_INIT]) ])# LT_INIT # Old names: AU_ALIAS([AC_PROG_LIBTOOL], [LT_INIT]) AU_ALIAS([AM_PROG_LIBTOOL], [LT_INIT]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_PROG_LIBTOOL], []) dnl AC_DEFUN([AM_PROG_LIBTOOL], []) # _LT_CC_BASENAME(CC) # ------------------- # Calculate cc_basename. Skip known compiler wrappers and cross-prefix. m4_defun([_LT_CC_BASENAME], [for cc_temp in $1""; do case $cc_temp in compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;; distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;; \-*) ;; *) break;; esac done cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` ]) # _LT_FILEUTILS_DEFAULTS # ---------------------- # It is okay to use these file commands and assume they have been set # sensibly after `m4_require([_LT_FILEUTILS_DEFAULTS])'. m4_defun([_LT_FILEUTILS_DEFAULTS], [: ${CP="cp -f"} : ${MV="mv -f"} : ${RM="rm -f"} ])# _LT_FILEUTILS_DEFAULTS # _LT_SETUP # --------- m4_defun([_LT_SETUP], [AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_CANONICAL_BUILD])dnl AC_REQUIRE([_LT_PREPARE_SED_QUOTE_VARS])dnl AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl _LT_DECL([], [PATH_SEPARATOR], [1], [The PATH separator for the build system])dnl dnl _LT_DECL([], [host_alias], [0], [The host system])dnl _LT_DECL([], [host], [0])dnl _LT_DECL([], [host_os], [0])dnl dnl _LT_DECL([], [build_alias], [0], [The build system])dnl _LT_DECL([], [build], [0])dnl _LT_DECL([], [build_os], [0])dnl dnl AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([LT_PATH_LD])dnl AC_REQUIRE([LT_PATH_NM])dnl dnl AC_REQUIRE([AC_PROG_LN_S])dnl test -z "$LN_S" && LN_S="ln -s" _LT_DECL([], [LN_S], [1], [Whether we need soft or hard links])dnl dnl AC_REQUIRE([LT_CMD_MAX_LEN])dnl _LT_DECL([objext], [ac_objext], [0], [Object file suffix (normally "o")])dnl _LT_DECL([], [exeext], [0], [Executable file suffix (normally "")])dnl dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_CHECK_SHELL_FEATURES])dnl m4_require([_LT_PATH_CONVERSION_FUNCTIONS])dnl m4_require([_LT_CMD_RELOAD])dnl m4_require([_LT_CHECK_MAGIC_METHOD])dnl m4_require([_LT_CHECK_SHAREDLIB_FROM_LINKLIB])dnl m4_require([_LT_CMD_OLD_ARCHIVE])dnl m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl m4_require([_LT_WITH_SYSROOT])dnl _LT_CONFIG_LIBTOOL_INIT([ # See if we are running on zsh, and set the options which allow our # commands through without removal of \ escapes INIT. if test -n "\${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi ]) if test -n "${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi _LT_CHECK_OBJDIR m4_require([_LT_TAG_COMPILER])dnl case $host_os in aix3*) # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test "X${COLLECT_NAMES+set}" != Xset; then COLLECT_NAMES= export COLLECT_NAMES fi ;; esac # Global variables: ofile=libtool can_build_shared=yes # All known linkers require a `.a' archive for static linking (except MSVC, # which needs '.lib'). libext=a with_gnu_ld="$lt_cv_prog_gnu_ld" old_CC="$CC" old_CFLAGS="$CFLAGS" # Set sane defaults for various variables test -z "$CC" && CC=cc test -z "$LTCC" && LTCC=$CC test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS test -z "$LD" && LD=ld test -z "$ac_objext" && ac_objext=o _LT_CC_BASENAME([$compiler]) # Only perform the check for file, if the check method requires it test -z "$MAGIC_CMD" && MAGIC_CMD=file case $deplibs_check_method in file_magic*) if test "$file_magic_cmd" = '$MAGIC_CMD'; then _LT_PATH_MAGIC fi ;; esac # Use C for the default configuration in the libtool script LT_SUPPORTED_TAG([CC]) _LT_LANG_C_CONFIG _LT_LANG_DEFAULT_CONFIG _LT_CONFIG_COMMANDS ])# _LT_SETUP # _LT_PREPARE_SED_QUOTE_VARS # -------------------------- # Define a few sed substitution that help us do robust quoting. m4_defun([_LT_PREPARE_SED_QUOTE_VARS], [# Backslashify metacharacters that are still active within # double-quoted strings. sed_quote_subst='s/\([["`$\\]]\)/\\\1/g' # Same as above, but do not quote variable references. double_quote_subst='s/\([["`\\]]\)/\\\1/g' # Sed substitution to delay expansion of an escaped shell variable in a # double_quote_subst'ed string. delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' # Sed substitution to delay expansion of an escaped single quote. delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' # Sed substitution to avoid accidental globbing in evaled expressions no_glob_subst='s/\*/\\\*/g' ]) # _LT_PROG_LTMAIN # --------------- # Note that this code is called both from `configure', and `config.status' # now that we use AC_CONFIG_COMMANDS to generate libtool. Notably, # `config.status' has no value for ac_aux_dir unless we are using Automake, # so we pass a copy along to make sure it has a sensible value anyway. m4_defun([_LT_PROG_LTMAIN], [m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl _LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir']) ltmain="$ac_aux_dir/ltmain.sh" ])# _LT_PROG_LTMAIN ## ------------------------------------- ## ## Accumulate code for creating libtool. ## ## ------------------------------------- ## # So that we can recreate a full libtool script including additional # tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS # in macros and then make a single call at the end using the `libtool' # label. # _LT_CONFIG_LIBTOOL_INIT([INIT-COMMANDS]) # ---------------------------------------- # Register INIT-COMMANDS to be passed to AC_CONFIG_COMMANDS later. m4_define([_LT_CONFIG_LIBTOOL_INIT], [m4_ifval([$1], [m4_append([_LT_OUTPUT_LIBTOOL_INIT], [$1 ])])]) # Initialize. m4_define([_LT_OUTPUT_LIBTOOL_INIT]) # _LT_CONFIG_LIBTOOL([COMMANDS]) # ------------------------------ # Register COMMANDS to be passed to AC_CONFIG_COMMANDS later. m4_define([_LT_CONFIG_LIBTOOL], [m4_ifval([$1], [m4_append([_LT_OUTPUT_LIBTOOL_COMMANDS], [$1 ])])]) # Initialize. m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS]) # _LT_CONFIG_SAVE_COMMANDS([COMMANDS], [INIT_COMMANDS]) # ----------------------------------------------------- m4_defun([_LT_CONFIG_SAVE_COMMANDS], [_LT_CONFIG_LIBTOOL([$1]) _LT_CONFIG_LIBTOOL_INIT([$2]) ]) # _LT_FORMAT_COMMENT([COMMENT]) # ----------------------------- # Add leading comment marks to the start of each line, and a trailing # full-stop to the whole comment if one is not present already. m4_define([_LT_FORMAT_COMMENT], [m4_ifval([$1], [ m4_bpatsubst([m4_bpatsubst([$1], [^ *], [# ])], [['`$\]], [\\\&])]m4_bmatch([$1], [[!?.]$], [], [.]) )]) ## ------------------------ ## ## FIXME: Eliminate VARNAME ## ## ------------------------ ## # _LT_DECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION], [IS-TAGGED?]) # ------------------------------------------------------------------- # CONFIGNAME is the name given to the value in the libtool script. # VARNAME is the (base) name used in the configure script. # VALUE may be 0, 1 or 2 for a computed quote escaped value based on # VARNAME. Any other value will be used directly. m4_define([_LT_DECL], [lt_if_append_uniq([lt_decl_varnames], [$2], [, ], [lt_dict_add_subkey([lt_decl_dict], [$2], [libtool_name], [m4_ifval([$1], [$1], [$2])]) lt_dict_add_subkey([lt_decl_dict], [$2], [value], [$3]) m4_ifval([$4], [lt_dict_add_subkey([lt_decl_dict], [$2], [description], [$4])]) lt_dict_add_subkey([lt_decl_dict], [$2], [tagged?], [m4_ifval([$5], [yes], [no])])]) ]) # _LT_TAGDECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION]) # -------------------------------------------------------- m4_define([_LT_TAGDECL], [_LT_DECL([$1], [$2], [$3], [$4], [yes])]) # lt_decl_tag_varnames([SEPARATOR], [VARNAME1...]) # ------------------------------------------------ m4_define([lt_decl_tag_varnames], [_lt_decl_filter([tagged?], [yes], $@)]) # _lt_decl_filter(SUBKEY, VALUE, [SEPARATOR], [VARNAME1..]) # --------------------------------------------------------- m4_define([_lt_decl_filter], [m4_case([$#], [0], [m4_fatal([$0: too few arguments: $#])], [1], [m4_fatal([$0: too few arguments: $#: $1])], [2], [lt_dict_filter([lt_decl_dict], [$1], [$2], [], lt_decl_varnames)], [3], [lt_dict_filter([lt_decl_dict], [$1], [$2], [$3], lt_decl_varnames)], [lt_dict_filter([lt_decl_dict], $@)])[]dnl ]) # lt_decl_quote_varnames([SEPARATOR], [VARNAME1...]) # -------------------------------------------------- m4_define([lt_decl_quote_varnames], [_lt_decl_filter([value], [1], $@)]) # lt_decl_dquote_varnames([SEPARATOR], [VARNAME1...]) # --------------------------------------------------- m4_define([lt_decl_dquote_varnames], [_lt_decl_filter([value], [2], $@)]) # lt_decl_varnames_tagged([SEPARATOR], [VARNAME1...]) # --------------------------------------------------- m4_define([lt_decl_varnames_tagged], [m4_assert([$# <= 2])dnl _$0(m4_quote(m4_default([$1], [[, ]])), m4_ifval([$2], [[$2]], [m4_dquote(lt_decl_tag_varnames)]), m4_split(m4_normalize(m4_quote(_LT_TAGS)), [ ]))]) m4_define([_lt_decl_varnames_tagged], [m4_ifval([$3], [lt_combine([$1], [$2], [_], $3)])]) # lt_decl_all_varnames([SEPARATOR], [VARNAME1...]) # ------------------------------------------------ m4_define([lt_decl_all_varnames], [_$0(m4_quote(m4_default([$1], [[, ]])), m4_if([$2], [], m4_quote(lt_decl_varnames), m4_quote(m4_shift($@))))[]dnl ]) m4_define([_lt_decl_all_varnames], [lt_join($@, lt_decl_varnames_tagged([$1], lt_decl_tag_varnames([[, ]], m4_shift($@))))dnl ]) # _LT_CONFIG_STATUS_DECLARE([VARNAME]) # ------------------------------------ # Quote a variable value, and forward it to `config.status' so that its # declaration there will have the same value as in `configure'. VARNAME # must have a single quote delimited value for this to work. m4_define([_LT_CONFIG_STATUS_DECLARE], [$1='`$ECHO "$][$1" | $SED "$delay_single_quote_subst"`']) # _LT_CONFIG_STATUS_DECLARATIONS # ------------------------------ # We delimit libtool config variables with single quotes, so when # we write them to config.status, we have to be sure to quote all # embedded single quotes properly. In configure, this macro expands # each variable declared with _LT_DECL (and _LT_TAGDECL) into: # # ='`$ECHO "$" | $SED "$delay_single_quote_subst"`' m4_defun([_LT_CONFIG_STATUS_DECLARATIONS], [m4_foreach([_lt_var], m4_quote(lt_decl_all_varnames), [m4_n([_LT_CONFIG_STATUS_DECLARE(_lt_var)])])]) # _LT_LIBTOOL_TAGS # ---------------- # Output comment and list of tags supported by the script m4_defun([_LT_LIBTOOL_TAGS], [_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl available_tags="_LT_TAGS"dnl ]) # _LT_LIBTOOL_DECLARE(VARNAME, [TAG]) # ----------------------------------- # Extract the dictionary values for VARNAME (optionally with TAG) and # expand to a commented shell variable setting: # # # Some comment about what VAR is for. # visible_name=$lt_internal_name m4_define([_LT_LIBTOOL_DECLARE], [_LT_FORMAT_COMMENT(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [description])))[]dnl m4_pushdef([_libtool_name], m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [libtool_name])))[]dnl m4_case(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [value])), [0], [_libtool_name=[$]$1], [1], [_libtool_name=$lt_[]$1], [2], [_libtool_name=$lt_[]$1], [_libtool_name=lt_dict_fetch([lt_decl_dict], [$1], [value])])[]dnl m4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl ]) # _LT_LIBTOOL_CONFIG_VARS # ----------------------- # Produce commented declarations of non-tagged libtool config variables # suitable for insertion in the LIBTOOL CONFIG section of the `libtool' # script. Tagged libtool config variables (even for the LIBTOOL CONFIG # section) are produced by _LT_LIBTOOL_TAG_VARS. m4_defun([_LT_LIBTOOL_CONFIG_VARS], [m4_foreach([_lt_var], m4_quote(_lt_decl_filter([tagged?], [no], [], lt_decl_varnames)), [m4_n([_LT_LIBTOOL_DECLARE(_lt_var)])])]) # _LT_LIBTOOL_TAG_VARS(TAG) # ------------------------- m4_define([_LT_LIBTOOL_TAG_VARS], [m4_foreach([_lt_var], m4_quote(lt_decl_tag_varnames), [m4_n([_LT_LIBTOOL_DECLARE(_lt_var, [$1])])])]) # _LT_TAGVAR(VARNAME, [TAGNAME]) # ------------------------------ m4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])]) # _LT_CONFIG_COMMANDS # ------------------- # Send accumulated output to $CONFIG_STATUS. Thanks to the lists of # variables for single and double quote escaping we saved from calls # to _LT_DECL, we can put quote escaped variables declarations # into `config.status', and then the shell code to quote escape them in # for loops in `config.status'. Finally, any additional code accumulated # from calls to _LT_CONFIG_LIBTOOL_INIT is expanded. m4_defun([_LT_CONFIG_COMMANDS], [AC_PROVIDE_IFELSE([LT_OUTPUT], dnl If the libtool generation code has been placed in $CONFIG_LT, dnl instead of duplicating it all over again into config.status, dnl then we will have config.status run $CONFIG_LT later, so it dnl needs to know what name is stored there: [AC_CONFIG_COMMANDS([libtool], [$SHELL $CONFIG_LT || AS_EXIT(1)], [CONFIG_LT='$CONFIG_LT'])], dnl If the libtool generation code is destined for config.status, dnl expand the accumulated commands and init code now: [AC_CONFIG_COMMANDS([libtool], [_LT_OUTPUT_LIBTOOL_COMMANDS], [_LT_OUTPUT_LIBTOOL_COMMANDS_INIT])]) ])#_LT_CONFIG_COMMANDS # Initialize. m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS_INIT], [ # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH sed_quote_subst='$sed_quote_subst' double_quote_subst='$double_quote_subst' delay_variable_subst='$delay_variable_subst' _LT_CONFIG_STATUS_DECLARATIONS LTCC='$LTCC' LTCFLAGS='$LTCFLAGS' compiler='$compiler_DEFAULT' # A function that is used when there is no print builtin or printf. func_fallback_echo () { eval 'cat <<_LTECHO_EOF \$[]1 _LTECHO_EOF' } # Quote evaled strings. for var in lt_decl_all_varnames([[ \ ]], lt_decl_quote_varnames); do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[[\\\\\\\`\\"\\\$]]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done # Double-quote double-evaled strings. for var in lt_decl_all_varnames([[ \ ]], lt_decl_dquote_varnames); do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[[\\\\\\\`\\"\\\$]]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done _LT_OUTPUT_LIBTOOL_INIT ]) # _LT_GENERATED_FILE_INIT(FILE, [COMMENT]) # ------------------------------------ # Generate a child script FILE with all initialization necessary to # reuse the environment learned by the parent script, and make the # file executable. If COMMENT is supplied, it is inserted after the # `#!' sequence but before initialization text begins. After this # macro, additional text can be appended to FILE to form the body of # the child script. The macro ends with non-zero status if the # file could not be fully written (such as if the disk is full). m4_ifdef([AS_INIT_GENERATED], [m4_defun([_LT_GENERATED_FILE_INIT],[AS_INIT_GENERATED($@)])], [m4_defun([_LT_GENERATED_FILE_INIT], [m4_require([AS_PREPARE])]dnl [m4_pushdef([AS_MESSAGE_LOG_FD])]dnl [lt_write_fail=0 cat >$1 <<_ASEOF || lt_write_fail=1 #! $SHELL # Generated by $as_me. $2 SHELL=\${CONFIG_SHELL-$SHELL} export SHELL _ASEOF cat >>$1 <<\_ASEOF || lt_write_fail=1 AS_SHELL_SANITIZE _AS_PREPARE exec AS_MESSAGE_FD>&1 _ASEOF test $lt_write_fail = 0 && chmod +x $1[]dnl m4_popdef([AS_MESSAGE_LOG_FD])])])# _LT_GENERATED_FILE_INIT # LT_OUTPUT # --------- # This macro allows early generation of the libtool script (before # AC_OUTPUT is called), incase it is used in configure for compilation # tests. AC_DEFUN([LT_OUTPUT], [: ${CONFIG_LT=./config.lt} AC_MSG_NOTICE([creating $CONFIG_LT]) _LT_GENERATED_FILE_INIT(["$CONFIG_LT"], [# Run this file to recreate a libtool stub with the current configuration.]) cat >>"$CONFIG_LT" <<\_LTEOF lt_cl_silent=false exec AS_MESSAGE_LOG_FD>>config.log { echo AS_BOX([Running $as_me.]) } >&AS_MESSAGE_LOG_FD lt_cl_help="\ \`$as_me' creates a local libtool stub from the current configuration, for use in further configure time tests before the real libtool is generated. Usage: $[0] [[OPTIONS]] -h, --help print this help, then exit -V, --version print version number, then exit -q, --quiet do not print progress messages -d, --debug don't remove temporary files Report bugs to ." lt_cl_version="\ m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION]) configured by $[0], generated by m4_PACKAGE_STRING. Copyright (C) 2011 Free Software Foundation, Inc. This config.lt script is free software; the Free Software Foundation gives unlimited permision to copy, distribute and modify it." while test $[#] != 0 do case $[1] in --version | --v* | -V ) echo "$lt_cl_version"; exit 0 ;; --help | --h* | -h ) echo "$lt_cl_help"; exit 0 ;; --debug | --d* | -d ) debug=: ;; --quiet | --q* | --silent | --s* | -q ) lt_cl_silent=: ;; -*) AC_MSG_ERROR([unrecognized option: $[1] Try \`$[0] --help' for more information.]) ;; *) AC_MSG_ERROR([unrecognized argument: $[1] Try \`$[0] --help' for more information.]) ;; esac shift done if $lt_cl_silent; then exec AS_MESSAGE_FD>/dev/null fi _LTEOF cat >>"$CONFIG_LT" <<_LTEOF _LT_OUTPUT_LIBTOOL_COMMANDS_INIT _LTEOF cat >>"$CONFIG_LT" <<\_LTEOF AC_MSG_NOTICE([creating $ofile]) _LT_OUTPUT_LIBTOOL_COMMANDS AS_EXIT(0) _LTEOF chmod +x "$CONFIG_LT" # configure is writing to config.log, but config.lt does its own redirection, # appending to config.log, which fails on DOS, as config.log is still kept # open by configure. Here we exec the FD to /dev/null, effectively closing # config.log, so it can be properly (re)opened and appended to by config.lt. lt_cl_success=: test "$silent" = yes && lt_config_lt_args="$lt_config_lt_args --quiet" exec AS_MESSAGE_LOG_FD>/dev/null $SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false exec AS_MESSAGE_LOG_FD>>config.log $lt_cl_success || AS_EXIT(1) ])# LT_OUTPUT # _LT_CONFIG(TAG) # --------------- # If TAG is the built-in tag, create an initial libtool script with a # default configuration from the untagged config vars. Otherwise add code # to config.status for appending the configuration named by TAG from the # matching tagged config vars. m4_defun([_LT_CONFIG], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl _LT_CONFIG_SAVE_COMMANDS([ m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl m4_if(_LT_TAG, [C], [ # See if we are running on zsh, and set the options which allow our # commands through without removal of \ escapes. if test -n "${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi cfgfile="${ofile}T" trap "$RM \"$cfgfile\"; exit 1" 1 2 15 $RM "$cfgfile" cat <<_LT_EOF >> "$cfgfile" #! $SHELL # `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. # Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION # Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: # NOTE: Changes made to this file will be lost: look at ltmain.sh. # _LT_COPYING _LT_LIBTOOL_TAGS # ### BEGIN LIBTOOL CONFIG _LT_LIBTOOL_CONFIG_VARS _LT_LIBTOOL_TAG_VARS # ### END LIBTOOL CONFIG _LT_EOF case $host_os in aix3*) cat <<\_LT_EOF >> "$cfgfile" # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test "X${COLLECT_NAMES+set}" != Xset; then COLLECT_NAMES= export COLLECT_NAMES fi _LT_EOF ;; esac _LT_PROG_LTMAIN # We use sed instead of cat because bash on DJGPP gets confused if # if finds mixed CR/LF and LF-only lines. Since sed operates in # text mode, it properly converts lines to CR/LF. This bash problem # is reportedly fixed, but why not run on old versions too? sed '$q' "$ltmain" >> "$cfgfile" \ || (rm -f "$cfgfile"; exit 1) _LT_PROG_REPLACE_SHELLFNS mv -f "$cfgfile" "$ofile" || (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") chmod +x "$ofile" ], [cat <<_LT_EOF >> "$ofile" dnl Unfortunately we have to use $1 here, since _LT_TAG is not expanded dnl in a comment (ie after a #). # ### BEGIN LIBTOOL TAG CONFIG: $1 _LT_LIBTOOL_TAG_VARS(_LT_TAG) # ### END LIBTOOL TAG CONFIG: $1 _LT_EOF ])dnl /m4_if ], [m4_if([$1], [], [ PACKAGE='$PACKAGE' VERSION='$VERSION' TIMESTAMP='$TIMESTAMP' RM='$RM' ofile='$ofile'], []) ])dnl /_LT_CONFIG_SAVE_COMMANDS ])# _LT_CONFIG # LT_SUPPORTED_TAG(TAG) # --------------------- # Trace this macro to discover what tags are supported by the libtool # --tag option, using: # autoconf --trace 'LT_SUPPORTED_TAG:$1' AC_DEFUN([LT_SUPPORTED_TAG], []) # C support is built-in for now m4_define([_LT_LANG_C_enabled], []) m4_define([_LT_TAGS], []) # LT_LANG(LANG) # ------------- # Enable libtool support for the given language if not already enabled. AC_DEFUN([LT_LANG], [AC_BEFORE([$0], [LT_OUTPUT])dnl m4_case([$1], [C], [_LT_LANG(C)], [C++], [_LT_LANG(CXX)], [Go], [_LT_LANG(GO)], [Java], [_LT_LANG(GCJ)], [Fortran 77], [_LT_LANG(F77)], [Fortran], [_LT_LANG(FC)], [Windows Resource], [_LT_LANG(RC)], [m4_ifdef([_LT_LANG_]$1[_CONFIG], [_LT_LANG($1)], [m4_fatal([$0: unsupported language: "$1"])])])dnl ])# LT_LANG # _LT_LANG(LANGNAME) # ------------------ m4_defun([_LT_LANG], [m4_ifdef([_LT_LANG_]$1[_enabled], [], [LT_SUPPORTED_TAG([$1])dnl m4_append([_LT_TAGS], [$1 ])dnl m4_define([_LT_LANG_]$1[_enabled], [])dnl _LT_LANG_$1_CONFIG($1)])dnl ])# _LT_LANG m4_ifndef([AC_PROG_GO], [ ############################################################ # NOTE: This macro has been submitted for inclusion into # # GNU Autoconf as AC_PROG_GO. When it is available in # # a released version of Autoconf we should remove this # # macro and use it instead. # ############################################################ m4_defun([AC_PROG_GO], [AC_LANG_PUSH(Go)dnl AC_ARG_VAR([GOC], [Go compiler command])dnl AC_ARG_VAR([GOFLAGS], [Go compiler flags])dnl _AC_ARG_VAR_LDFLAGS()dnl AC_CHECK_TOOL(GOC, gccgo) if test -z "$GOC"; then if test -n "$ac_tool_prefix"; then AC_CHECK_PROG(GOC, [${ac_tool_prefix}gccgo], [${ac_tool_prefix}gccgo]) fi fi if test -z "$GOC"; then AC_CHECK_PROG(GOC, gccgo, gccgo, false) fi ])#m4_defun ])#m4_ifndef # _LT_LANG_DEFAULT_CONFIG # ----------------------- m4_defun([_LT_LANG_DEFAULT_CONFIG], [AC_PROVIDE_IFELSE([AC_PROG_CXX], [LT_LANG(CXX)], [m4_define([AC_PROG_CXX], defn([AC_PROG_CXX])[LT_LANG(CXX)])]) AC_PROVIDE_IFELSE([AC_PROG_F77], [LT_LANG(F77)], [m4_define([AC_PROG_F77], defn([AC_PROG_F77])[LT_LANG(F77)])]) AC_PROVIDE_IFELSE([AC_PROG_FC], [LT_LANG(FC)], [m4_define([AC_PROG_FC], defn([AC_PROG_FC])[LT_LANG(FC)])]) dnl The call to [A][M_PROG_GCJ] is quoted like that to stop aclocal dnl pulling things in needlessly. AC_PROVIDE_IFELSE([AC_PROG_GCJ], [LT_LANG(GCJ)], [AC_PROVIDE_IFELSE([A][M_PROG_GCJ], [LT_LANG(GCJ)], [AC_PROVIDE_IFELSE([LT_PROG_GCJ], [LT_LANG(GCJ)], [m4_ifdef([AC_PROG_GCJ], [m4_define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[LT_LANG(GCJ)])]) m4_ifdef([A][M_PROG_GCJ], [m4_define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[LT_LANG(GCJ)])]) m4_ifdef([LT_PROG_GCJ], [m4_define([LT_PROG_GCJ], defn([LT_PROG_GCJ])[LT_LANG(GCJ)])])])])]) AC_PROVIDE_IFELSE([AC_PROG_GO], [LT_LANG(GO)], [m4_define([AC_PROG_GO], defn([AC_PROG_GO])[LT_LANG(GO)])]) AC_PROVIDE_IFELSE([LT_PROG_RC], [LT_LANG(RC)], [m4_define([LT_PROG_RC], defn([LT_PROG_RC])[LT_LANG(RC)])]) ])# _LT_LANG_DEFAULT_CONFIG # Obsolete macros: AU_DEFUN([AC_LIBTOOL_CXX], [LT_LANG(C++)]) AU_DEFUN([AC_LIBTOOL_F77], [LT_LANG(Fortran 77)]) AU_DEFUN([AC_LIBTOOL_FC], [LT_LANG(Fortran)]) AU_DEFUN([AC_LIBTOOL_GCJ], [LT_LANG(Java)]) AU_DEFUN([AC_LIBTOOL_RC], [LT_LANG(Windows Resource)]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_CXX], []) dnl AC_DEFUN([AC_LIBTOOL_F77], []) dnl AC_DEFUN([AC_LIBTOOL_FC], []) dnl AC_DEFUN([AC_LIBTOOL_GCJ], []) dnl AC_DEFUN([AC_LIBTOOL_RC], []) # _LT_TAG_COMPILER # ---------------- m4_defun([_LT_TAG_COMPILER], [AC_REQUIRE([AC_PROG_CC])dnl _LT_DECL([LTCC], [CC], [1], [A C compiler])dnl _LT_DECL([LTCFLAGS], [CFLAGS], [1], [LTCC compiler flags])dnl _LT_TAGDECL([CC], [compiler], [1], [A language specific compiler])dnl _LT_TAGDECL([with_gcc], [GCC], [0], [Is the compiler the GNU compiler?])dnl # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC ])# _LT_TAG_COMPILER # _LT_COMPILER_BOILERPLATE # ------------------------ # Check for compiler boilerplate output or warnings with # the simple compiler test code. m4_defun([_LT_COMPILER_BOILERPLATE], [m4_require([_LT_DECL_SED])dnl ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" >conftest.$ac_ext eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_compiler_boilerplate=`cat conftest.err` $RM conftest* ])# _LT_COMPILER_BOILERPLATE # _LT_LINKER_BOILERPLATE # ---------------------- # Check for linker boilerplate output or warnings with # the simple link test code. m4_defun([_LT_LINKER_BOILERPLATE], [m4_require([_LT_DECL_SED])dnl ac_outfile=conftest.$ac_objext echo "$lt_simple_link_test_code" >conftest.$ac_ext eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_linker_boilerplate=`cat conftest.err` $RM -r conftest* ])# _LT_LINKER_BOILERPLATE # _LT_REQUIRED_DARWIN_CHECKS # ------------------------- m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[ case $host_os in rhapsody* | darwin*) AC_CHECK_TOOL([DSYMUTIL], [dsymutil], [:]) AC_CHECK_TOOL([NMEDIT], [nmedit], [:]) AC_CHECK_TOOL([LIPO], [lipo], [:]) AC_CHECK_TOOL([OTOOL], [otool], [:]) AC_CHECK_TOOL([OTOOL64], [otool64], [:]) _LT_DECL([], [DSYMUTIL], [1], [Tool to manipulate archived DWARF debug symbol files on Mac OS X]) _LT_DECL([], [NMEDIT], [1], [Tool to change global to local symbols on Mac OS X]) _LT_DECL([], [LIPO], [1], [Tool to manipulate fat objects and archives on Mac OS X]) _LT_DECL([], [OTOOL], [1], [ldd/readelf like tool for Mach-O binaries on Mac OS X]) _LT_DECL([], [OTOOL64], [1], [ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4]) AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod], [lt_cv_apple_cc_single_mod=no if test -z "${LT_MULTI_MODULE}"; then # By default we will add the -single_module flag. You can override # by either setting the environment variable LT_MULTI_MODULE # non-empty at configure time, or by adding -multi_module to the # link flags. rm -rf libconftest.dylib* echo "int foo(void){return 1;}" > conftest.c echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c" >&AS_MESSAGE_LOG_FD $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c 2>conftest.err _lt_result=$? # If there is a non-empty error log, and "single_module" # appears in it, assume the flag caused a linker warning if test -s conftest.err && $GREP single_module conftest.err; then cat conftest.err >&AS_MESSAGE_LOG_FD # Otherwise, if the output was created with a 0 exit code from # the compiler, it worked. elif test -f libconftest.dylib && test $_lt_result -eq 0; then lt_cv_apple_cc_single_mod=yes else cat conftest.err >&AS_MESSAGE_LOG_FD fi rm -rf libconftest.dylib* rm -f conftest.* fi]) AC_CACHE_CHECK([for -exported_symbols_list linker flag], [lt_cv_ld_exported_symbols_list], [lt_cv_ld_exported_symbols_list=no save_LDFLAGS=$LDFLAGS echo "_main" > conftest.sym LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], [lt_cv_ld_exported_symbols_list=yes], [lt_cv_ld_exported_symbols_list=no]) LDFLAGS="$save_LDFLAGS" ]) AC_CACHE_CHECK([for -force_load linker flag],[lt_cv_ld_force_load], [lt_cv_ld_force_load=no cat > conftest.c << _LT_EOF int forced_loaded() { return 2;} _LT_EOF echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&AS_MESSAGE_LOG_FD $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&AS_MESSAGE_LOG_FD echo "$AR cru libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD $AR cru libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD echo "$RANLIB libconftest.a" >&AS_MESSAGE_LOG_FD $RANLIB libconftest.a 2>&AS_MESSAGE_LOG_FD cat > conftest.c << _LT_EOF int main() { return 0;} _LT_EOF echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&AS_MESSAGE_LOG_FD $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err _lt_result=$? if test -s conftest.err && $GREP force_load conftest.err; then cat conftest.err >&AS_MESSAGE_LOG_FD elif test -f conftest && test $_lt_result -eq 0 && $GREP forced_load conftest >/dev/null 2>&1 ; then lt_cv_ld_force_load=yes else cat conftest.err >&AS_MESSAGE_LOG_FD fi rm -f conftest.err libconftest.a conftest conftest.c rm -rf conftest.dSYM ]) case $host_os in rhapsody* | darwin1.[[012]]) _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; darwin1.*) _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; darwin*) # darwin 5.x on # if running on 10.5 or later, the deployment target defaults # to the OS version, if on x86, and 10.4, the deployment # target defaults to 10.4. Don't you love it? case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in 10.0,*86*-darwin8*|10.0,*-darwin[[91]]*) _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; 10.[[012]]*) _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; 10.*) _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; esac ;; esac if test "$lt_cv_apple_cc_single_mod" = "yes"; then _lt_dar_single_mod='$single_module' fi if test "$lt_cv_ld_exported_symbols_list" = "yes"; then _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym' else _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}' fi if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then _lt_dsymutil='~$DSYMUTIL $lib || :' else _lt_dsymutil= fi ;; esac ]) # _LT_DARWIN_LINKER_FEATURES([TAG]) # --------------------------------- # Checks for linker and compiler features on darwin m4_defun([_LT_DARWIN_LINKER_FEATURES], [ m4_require([_LT_REQUIRED_DARWIN_CHECKS]) _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_automatic, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported if test "$lt_cv_ld_force_load" = "yes"; then _LT_TAGVAR(whole_archive_flag_spec, $1)='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' m4_case([$1], [F77], [_LT_TAGVAR(compiler_needs_object, $1)=yes], [FC], [_LT_TAGVAR(compiler_needs_object, $1)=yes]) else _LT_TAGVAR(whole_archive_flag_spec, $1)='' fi _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(allow_undefined_flag, $1)="$_lt_dar_allow_undefined" case $cc_basename in ifort*) _lt_dar_can_shared=yes ;; *) _lt_dar_can_shared=$GCC ;; esac if test "$_lt_dar_can_shared" = "yes"; then output_verbose_link_cmd=func_echo_all _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" m4_if([$1], [CXX], [ if test "$lt_cv_apple_cc_single_mod" != "yes"; then _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}" _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}" fi ],[]) else _LT_TAGVAR(ld_shlibs, $1)=no fi ]) # _LT_SYS_MODULE_PATH_AIX([TAGNAME]) # ---------------------------------- # Links a minimal program and checks the executable # for the system default hardcoded library path. In most cases, # this is /usr/lib:/lib, but when the MPI compilers are used # the location of the communication and MPI libs are included too. # If we don't find anything, use the default library path according # to the aix ld manual. # Store the results from the different compilers for each TAGNAME. # Allow to override them for all tags through lt_cv_aix_libpath. m4_defun([_LT_SYS_MODULE_PATH_AIX], [m4_require([_LT_DECL_SED])dnl if test "${lt_cv_aix_libpath+set}" = set; then aix_libpath=$lt_cv_aix_libpath else AC_CACHE_VAL([_LT_TAGVAR([lt_cv_aix_libpath_], [$1])], [AC_LINK_IFELSE([AC_LANG_PROGRAM],[ lt_aix_libpath_sed='[ /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }]' _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi],[]) if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then _LT_TAGVAR([lt_cv_aix_libpath_], [$1])="/usr/lib:/lib" fi ]) aix_libpath=$_LT_TAGVAR([lt_cv_aix_libpath_], [$1]) fi ])# _LT_SYS_MODULE_PATH_AIX # _LT_SHELL_INIT(ARG) # ------------------- m4_define([_LT_SHELL_INIT], [m4_divert_text([M4SH-INIT], [$1 ])])# _LT_SHELL_INIT # _LT_PROG_ECHO_BACKSLASH # ----------------------- # Find how we can fake an echo command that does not interpret backslash. # In particular, with Autoconf 2.60 or later we add some code to the start # of the generated configure script which will find a shell with a builtin # printf (which we can use as an echo command). m4_defun([_LT_PROG_ECHO_BACKSLASH], [ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO AC_MSG_CHECKING([how to print strings]) # Test print first, because it will be a builtin if present. if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='print -r --' elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='printf %s\n' else # Use this function as a fallback that always works. func_fallback_echo () { eval 'cat <<_LTECHO_EOF $[]1 _LTECHO_EOF' } ECHO='func_fallback_echo' fi # func_echo_all arg... # Invoke $ECHO with all args, space-separated. func_echo_all () { $ECHO "$*" } case "$ECHO" in printf*) AC_MSG_RESULT([printf]) ;; print*) AC_MSG_RESULT([print -r]) ;; *) AC_MSG_RESULT([cat]) ;; esac m4_ifdef([_AS_DETECT_SUGGESTED], [_AS_DETECT_SUGGESTED([ test -n "${ZSH_VERSION+set}${BASH_VERSION+set}" || ( ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO PATH=/empty FPATH=/empty; export PATH FPATH test "X`printf %s $ECHO`" = "X$ECHO" \ || test "X`print -r -- $ECHO`" = "X$ECHO" )])]) _LT_DECL([], [SHELL], [1], [Shell to use when invoking shell scripts]) _LT_DECL([], [ECHO], [1], [An echo program that protects backslashes]) ])# _LT_PROG_ECHO_BACKSLASH # _LT_WITH_SYSROOT # ---------------- AC_DEFUN([_LT_WITH_SYSROOT], [AC_MSG_CHECKING([for sysroot]) AC_ARG_WITH([sysroot], [ --with-sysroot[=DIR] Search for dependent libraries within DIR (or the compiler's sysroot if not specified).], [], [with_sysroot=no]) dnl lt_sysroot will always be passed unquoted. We quote it here dnl in case the user passed a directory name. lt_sysroot= case ${with_sysroot} in #( yes) if test "$GCC" = yes; then lt_sysroot=`$CC --print-sysroot 2>/dev/null` fi ;; #( /*) lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` ;; #( no|'') ;; #( *) AC_MSG_RESULT([${with_sysroot}]) AC_MSG_ERROR([The sysroot must be an absolute path.]) ;; esac AC_MSG_RESULT([${lt_sysroot:-no}]) _LT_DECL([], [lt_sysroot], [0], [The root where to search for ]dnl [dependent libraries, and in which our libraries should be installed.])]) # _LT_ENABLE_LOCK # --------------- m4_defun([_LT_ENABLE_LOCK], [AC_ARG_ENABLE([libtool-lock], [AS_HELP_STRING([--disable-libtool-lock], [avoid locking (might break parallel builds)])]) test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes # Some flags need to be propagated to the compiler or linker for good # libtool support. case $host in ia64-*-hpux*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `/usr/bin/file conftest.$ac_objext` in *ELF-32*) HPUX_IA64_MODE="32" ;; *ELF-64*) HPUX_IA64_MODE="64" ;; esac fi rm -rf conftest* ;; *-*-irix6*) # Find out which ABI we are using. echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then if test "$lt_cv_prog_gnu_ld" = yes; then case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -melf32bsmip" ;; *N32*) LD="${LD-ld} -melf32bmipn32" ;; *64-bit*) LD="${LD-ld} -melf64bmip" ;; esac else case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -32" ;; *N32*) LD="${LD-ld} -n32" ;; *64-bit*) LD="${LD-ld} -64" ;; esac fi fi rm -rf conftest* ;; x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `/usr/bin/file conftest.o` in *32-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_i386_fbsd" ;; x86_64-*linux*) LD="${LD-ld} -m elf_i386" ;; ppc64-*linux*|powerpc64-*linux*) LD="${LD-ld} -m elf32ppclinux" ;; s390x-*linux*) LD="${LD-ld} -m elf_s390" ;; sparc64-*linux*) LD="${LD-ld} -m elf32_sparc" ;; esac ;; *64-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_x86_64_fbsd" ;; x86_64-*linux*) LD="${LD-ld} -m elf_x86_64" ;; ppc*-*linux*|powerpc*-*linux*) LD="${LD-ld} -m elf64ppc" ;; s390*-*linux*|s390*-*tpf*) LD="${LD-ld} -m elf64_s390" ;; sparc*-*linux*) LD="${LD-ld} -m elf64_sparc" ;; esac ;; esac fi rm -rf conftest* ;; *-*-sco3.2v5*) # On SCO OpenServer 5, we need -belf to get full-featured binaries. SAVE_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -belf" AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf, [AC_LANG_PUSH(C) AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no]) AC_LANG_POP]) if test x"$lt_cv_cc_needs_belf" != x"yes"; then # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf CFLAGS="$SAVE_CFLAGS" fi ;; *-*solaris*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `/usr/bin/file conftest.o` in *64-bit*) case $lt_cv_prog_gnu_ld in yes*) case $host in i?86-*-solaris*) LD="${LD-ld} -m elf_x86_64" ;; sparc*-*-solaris*) LD="${LD-ld} -m elf64_sparc" ;; esac # GNU ld 2.21 introduced _sol2 emulations. Use them if available. if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then LD="${LD-ld}_sol2" fi ;; *) if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then LD="${LD-ld} -64" fi ;; esac ;; esac fi rm -rf conftest* ;; esac need_locks="$enable_libtool_lock" ])# _LT_ENABLE_LOCK # _LT_PROG_AR # ----------- m4_defun([_LT_PROG_AR], [AC_CHECK_TOOLS(AR, [ar], false) : ${AR=ar} : ${AR_FLAGS=cru} _LT_DECL([], [AR], [1], [The archiver]) _LT_DECL([], [AR_FLAGS], [1], [Flags to create an archive]) AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file], [lt_cv_ar_at_file=no AC_COMPILE_IFELSE([AC_LANG_PROGRAM], [echo conftest.$ac_objext > conftest.lst lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&AS_MESSAGE_LOG_FD' AC_TRY_EVAL([lt_ar_try]) if test "$ac_status" -eq 0; then # Ensure the archiver fails upon bogus file names. rm -f conftest.$ac_objext libconftest.a AC_TRY_EVAL([lt_ar_try]) if test "$ac_status" -ne 0; then lt_cv_ar_at_file=@ fi fi rm -f conftest.* libconftest.a ]) ]) if test "x$lt_cv_ar_at_file" = xno; then archiver_list_spec= else archiver_list_spec=$lt_cv_ar_at_file fi _LT_DECL([], [archiver_list_spec], [1], [How to feed a file listing to the archiver]) ])# _LT_PROG_AR # _LT_CMD_OLD_ARCHIVE # ------------------- m4_defun([_LT_CMD_OLD_ARCHIVE], [_LT_PROG_AR AC_CHECK_TOOL(STRIP, strip, :) test -z "$STRIP" && STRIP=: _LT_DECL([], [STRIP], [1], [A symbol stripping program]) AC_CHECK_TOOL(RANLIB, ranlib, :) test -z "$RANLIB" && RANLIB=: _LT_DECL([], [RANLIB], [1], [Commands used to install an old-style archive]) # Determine commands to create old-style static archives. old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' old_postinstall_cmds='chmod 644 $oldlib' old_postuninstall_cmds= if test -n "$RANLIB"; then case $host_os in openbsd*) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" ;; *) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" ;; esac old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" fi case $host_os in darwin*) lock_old_archive_extraction=yes ;; *) lock_old_archive_extraction=no ;; esac _LT_DECL([], [old_postinstall_cmds], [2]) _LT_DECL([], [old_postuninstall_cmds], [2]) _LT_TAGDECL([], [old_archive_cmds], [2], [Commands used to build an old-style archive]) _LT_DECL([], [lock_old_archive_extraction], [0], [Whether to use a lock for old archive extraction]) ])# _LT_CMD_OLD_ARCHIVE # _LT_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, # [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE]) # ---------------------------------------------------------------- # Check whether the given compiler option works AC_DEFUN([_LT_COMPILER_OPTION], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_SED])dnl AC_CACHE_CHECK([$1], [$2], [$2=no m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4]) echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="$3" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&AS_MESSAGE_LOG_FD echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then $2=yes fi fi $RM conftest* ]) if test x"[$]$2" = xyes; then m4_if([$5], , :, [$5]) else m4_if([$6], , :, [$6]) fi ])# _LT_COMPILER_OPTION # Old name: AU_ALIAS([AC_LIBTOOL_COMPILER_OPTION], [_LT_COMPILER_OPTION]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], []) # _LT_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, # [ACTION-SUCCESS], [ACTION-FAILURE]) # ---------------------------------------------------- # Check whether the given linker option works AC_DEFUN([_LT_LINKER_OPTION], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_SED])dnl AC_CACHE_CHECK([$1], [$2], [$2=no save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS $3" echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then # The linker can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&AS_MESSAGE_LOG_FD $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then $2=yes fi else $2=yes fi fi $RM -r conftest* LDFLAGS="$save_LDFLAGS" ]) if test x"[$]$2" = xyes; then m4_if([$4], , :, [$4]) else m4_if([$5], , :, [$5]) fi ])# _LT_LINKER_OPTION # Old name: AU_ALIAS([AC_LIBTOOL_LINKER_OPTION], [_LT_LINKER_OPTION]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], []) # LT_CMD_MAX_LEN #--------------- AC_DEFUN([LT_CMD_MAX_LEN], [AC_REQUIRE([AC_CANONICAL_HOST])dnl # find the maximum length of command line arguments AC_MSG_CHECKING([the maximum length of command line arguments]) AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl i=0 teststring="ABCD" case $build_os in msdosdjgpp*) # On DJGPP, this test can blow up pretty badly due to problems in libc # (any single argument exceeding 2000 bytes causes a buffer overrun # during glob expansion). Even if it were fixed, the result of this # check would be larger than it should be. lt_cv_sys_max_cmd_len=12288; # 12K is about right ;; gnu*) # Under GNU Hurd, this test is not required because there is # no limit to the length of command line arguments. # Libtool will interpret -1 as no limit whatsoever lt_cv_sys_max_cmd_len=-1; ;; cygwin* | mingw* | cegcc*) # On Win9x/ME, this test blows up -- it succeeds, but takes # about 5 minutes as the teststring grows exponentially. # Worse, since 9x/ME are not pre-emptively multitasking, # you end up with a "frozen" computer, even though with patience # the test eventually succeeds (with a max line length of 256k). # Instead, let's just punt: use the minimum linelength reported by # all of the supported platforms: 8192 (on NT/2K/XP). lt_cv_sys_max_cmd_len=8192; ;; mint*) # On MiNT this can take a long time and run out of memory. lt_cv_sys_max_cmd_len=8192; ;; amigaos*) # On AmigaOS with pdksh, this test takes hours, literally. # So we just punt and use a minimum line length of 8192. lt_cv_sys_max_cmd_len=8192; ;; netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) # This has been around since 386BSD, at least. Likely further. if test -x /sbin/sysctl; then lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` elif test -x /usr/sbin/sysctl; then lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` else lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs fi # And add a safety zone lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` ;; interix*) # We know the value 262144 and hardcode it with a safety zone (like BSD) lt_cv_sys_max_cmd_len=196608 ;; os2*) # The test takes a long time on OS/2. lt_cv_sys_max_cmd_len=8192 ;; osf*) # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not # nice to cause kernel panics so lets avoid the loop below. # First set a reasonable default. lt_cv_sys_max_cmd_len=16384 # if test -x /sbin/sysconfig; then case `/sbin/sysconfig -q proc exec_disable_arg_limit` in *1*) lt_cv_sys_max_cmd_len=-1 ;; esac fi ;; sco3.2v5*) lt_cv_sys_max_cmd_len=102400 ;; sysv5* | sco5v6* | sysv4.2uw2*) kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` if test -n "$kargmax"; then lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[ ]]//'` else lt_cv_sys_max_cmd_len=32768 fi ;; *) lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` if test -n "$lt_cv_sys_max_cmd_len"; then lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` else # Make teststring a little bigger before we do anything with it. # a 1K string should be a reasonable start. for i in 1 2 3 4 5 6 7 8 ; do teststring=$teststring$teststring done SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} # If test is not a shell built-in, we'll probably end up computing a # maximum length that is only half of the actual maximum length, but # we can't tell. while { test "X"`env echo "$teststring$teststring" 2>/dev/null` \ = "X$teststring$teststring"; } >/dev/null 2>&1 && test $i != 17 # 1/2 MB should be enough do i=`expr $i + 1` teststring=$teststring$teststring done # Only check the string length outside the loop. lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` teststring= # Add a significant safety factor because C++ compilers can tack on # massive amounts of additional arguments before passing them to the # linker. It appears as though 1/2 is a usable value. lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` fi ;; esac ]) if test -n $lt_cv_sys_max_cmd_len ; then AC_MSG_RESULT($lt_cv_sys_max_cmd_len) else AC_MSG_RESULT(none) fi max_cmd_len=$lt_cv_sys_max_cmd_len _LT_DECL([], [max_cmd_len], [0], [What is the maximum length of a command?]) ])# LT_CMD_MAX_LEN # Old name: AU_ALIAS([AC_LIBTOOL_SYS_MAX_CMD_LEN], [LT_CMD_MAX_LEN]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], []) # _LT_HEADER_DLFCN # ---------------- m4_defun([_LT_HEADER_DLFCN], [AC_CHECK_HEADERS([dlfcn.h], [], [], [AC_INCLUDES_DEFAULT])dnl ])# _LT_HEADER_DLFCN # _LT_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE, # ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING) # ---------------------------------------------------------------- m4_defun([_LT_TRY_DLOPEN_SELF], [m4_require([_LT_HEADER_DLFCN])dnl if test "$cross_compiling" = yes; then : [$4] else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF [#line $LINENO "configure" #include "confdefs.h" #if HAVE_DLFCN_H #include #endif #include #ifdef RTLD_GLOBAL # define LT_DLGLOBAL RTLD_GLOBAL #else # ifdef DL_GLOBAL # define LT_DLGLOBAL DL_GLOBAL # else # define LT_DLGLOBAL 0 # endif #endif /* We may have to define LT_DLLAZY_OR_NOW in the command line if we find out it does not work in some platform. */ #ifndef LT_DLLAZY_OR_NOW # ifdef RTLD_LAZY # define LT_DLLAZY_OR_NOW RTLD_LAZY # else # ifdef DL_LAZY # define LT_DLLAZY_OR_NOW DL_LAZY # else # ifdef RTLD_NOW # define LT_DLLAZY_OR_NOW RTLD_NOW # else # ifdef DL_NOW # define LT_DLLAZY_OR_NOW DL_NOW # else # define LT_DLLAZY_OR_NOW 0 # endif # endif # endif # endif #endif /* When -fvisbility=hidden is used, assume the code has been annotated correspondingly for the symbols needed. */ #if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) int fnord () __attribute__((visibility("default"))); #endif int fnord () { return 42; } int main () { void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); int status = $lt_dlunknown; if (self) { if (dlsym (self,"fnord")) status = $lt_dlno_uscore; else { if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; else puts (dlerror ()); } /* dlclose (self); */ } else puts (dlerror ()); return status; }] _LT_EOF if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null lt_status=$? case x$lt_status in x$lt_dlno_uscore) $1 ;; x$lt_dlneed_uscore) $2 ;; x$lt_dlunknown|x*) $3 ;; esac else : # compilation failed $3 fi fi rm -fr conftest* ])# _LT_TRY_DLOPEN_SELF # LT_SYS_DLOPEN_SELF # ------------------ AC_DEFUN([LT_SYS_DLOPEN_SELF], [m4_require([_LT_HEADER_DLFCN])dnl if test "x$enable_dlopen" != xyes; then enable_dlopen=unknown enable_dlopen_self=unknown enable_dlopen_self_static=unknown else lt_cv_dlopen=no lt_cv_dlopen_libs= case $host_os in beos*) lt_cv_dlopen="load_add_on" lt_cv_dlopen_libs= lt_cv_dlopen_self=yes ;; mingw* | pw32* | cegcc*) lt_cv_dlopen="LoadLibrary" lt_cv_dlopen_libs= ;; cygwin*) lt_cv_dlopen="dlopen" lt_cv_dlopen_libs= ;; darwin*) # if libdl is installed we need to link against it AC_CHECK_LIB([dl], [dlopen], [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],[ lt_cv_dlopen="dyld" lt_cv_dlopen_libs= lt_cv_dlopen_self=yes ]) ;; *) AC_CHECK_FUNC([shl_load], [lt_cv_dlopen="shl_load"], [AC_CHECK_LIB([dld], [shl_load], [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"], [AC_CHECK_FUNC([dlopen], [lt_cv_dlopen="dlopen"], [AC_CHECK_LIB([dl], [dlopen], [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"], [AC_CHECK_LIB([svld], [dlopen], [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"], [AC_CHECK_LIB([dld], [dld_link], [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"]) ]) ]) ]) ]) ]) ;; esac if test "x$lt_cv_dlopen" != xno; then enable_dlopen=yes else enable_dlopen=no fi case $lt_cv_dlopen in dlopen) save_CPPFLAGS="$CPPFLAGS" test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" save_LDFLAGS="$LDFLAGS" wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" save_LIBS="$LIBS" LIBS="$lt_cv_dlopen_libs $LIBS" AC_CACHE_CHECK([whether a program can dlopen itself], lt_cv_dlopen_self, [dnl _LT_TRY_DLOPEN_SELF( lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes, lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross) ]) if test "x$lt_cv_dlopen_self" = xyes; then wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" AC_CACHE_CHECK([whether a statically linked program can dlopen itself], lt_cv_dlopen_self_static, [dnl _LT_TRY_DLOPEN_SELF( lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross) ]) fi CPPFLAGS="$save_CPPFLAGS" LDFLAGS="$save_LDFLAGS" LIBS="$save_LIBS" ;; esac case $lt_cv_dlopen_self in yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; *) enable_dlopen_self=unknown ;; esac case $lt_cv_dlopen_self_static in yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; *) enable_dlopen_self_static=unknown ;; esac fi _LT_DECL([dlopen_support], [enable_dlopen], [0], [Whether dlopen is supported]) _LT_DECL([dlopen_self], [enable_dlopen_self], [0], [Whether dlopen of programs is supported]) _LT_DECL([dlopen_self_static], [enable_dlopen_self_static], [0], [Whether dlopen of statically linked programs is supported]) ])# LT_SYS_DLOPEN_SELF # Old name: AU_ALIAS([AC_LIBTOOL_DLOPEN_SELF], [LT_SYS_DLOPEN_SELF]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], []) # _LT_COMPILER_C_O([TAGNAME]) # --------------------------- # Check to see if options -c and -o are simultaneously supported by compiler. # This macro does not hard code the compiler like AC_PROG_CC_C_O. m4_defun([_LT_COMPILER_C_O], [m4_require([_LT_DECL_SED])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_TAG_COMPILER])dnl AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext], [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)], [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&AS_MESSAGE_LOG_FD echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes fi fi chmod u+w . 2>&AS_MESSAGE_LOG_FD $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* ]) _LT_TAGDECL([compiler_c_o], [lt_cv_prog_compiler_c_o], [1], [Does compiler simultaneously support -c and -o options?]) ])# _LT_COMPILER_C_O # _LT_COMPILER_FILE_LOCKS([TAGNAME]) # ---------------------------------- # Check to see if we can do hard links to lock some files if needed m4_defun([_LT_COMPILER_FILE_LOCKS], [m4_require([_LT_ENABLE_LOCK])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl _LT_COMPILER_C_O([$1]) hard_links="nottested" if test "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" = no && test "$need_locks" != no; then # do not overwrite the value of need_locks provided by the user AC_MSG_CHECKING([if we can lock with hard links]) hard_links=yes $RM conftest* ln conftest.a conftest.b 2>/dev/null && hard_links=no touch conftest.a ln conftest.a conftest.b 2>&5 || hard_links=no ln conftest.a conftest.b 2>/dev/null && hard_links=no AC_MSG_RESULT([$hard_links]) if test "$hard_links" = no; then AC_MSG_WARN([`$CC' does not support `-c -o', so `make -j' may be unsafe]) need_locks=warn fi else need_locks=no fi _LT_DECL([], [need_locks], [1], [Must we lock files when doing compilation?]) ])# _LT_COMPILER_FILE_LOCKS # _LT_CHECK_OBJDIR # ---------------- m4_defun([_LT_CHECK_OBJDIR], [AC_CACHE_CHECK([for objdir], [lt_cv_objdir], [rm -f .libs 2>/dev/null mkdir .libs 2>/dev/null if test -d .libs; then lt_cv_objdir=.libs else # MS-DOS does not allow filenames that begin with a dot. lt_cv_objdir=_libs fi rmdir .libs 2>/dev/null]) objdir=$lt_cv_objdir _LT_DECL([], [objdir], [0], [The name of the directory that contains temporary libtool files])dnl m4_pattern_allow([LT_OBJDIR])dnl AC_DEFINE_UNQUOTED(LT_OBJDIR, "$lt_cv_objdir/", [Define to the sub-directory in which libtool stores uninstalled libraries.]) ])# _LT_CHECK_OBJDIR # _LT_LINKER_HARDCODE_LIBPATH([TAGNAME]) # -------------------------------------- # Check hardcoding attributes. m4_defun([_LT_LINKER_HARDCODE_LIBPATH], [AC_MSG_CHECKING([how to hardcode library paths into programs]) _LT_TAGVAR(hardcode_action, $1)= if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" || test -n "$_LT_TAGVAR(runpath_var, $1)" || test "X$_LT_TAGVAR(hardcode_automatic, $1)" = "Xyes" ; then # We can hardcode non-existent directories. if test "$_LT_TAGVAR(hardcode_direct, $1)" != no && # If the only mechanism to avoid hardcoding is shlibpath_var, we # have to relink, otherwise we might link with an installed library # when we should be linking with a yet-to-be-installed one ## test "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" != no && test "$_LT_TAGVAR(hardcode_minus_L, $1)" != no; then # Linking always hardcodes the temporary library directory. _LT_TAGVAR(hardcode_action, $1)=relink else # We can link without hardcoding, and we can hardcode nonexisting dirs. _LT_TAGVAR(hardcode_action, $1)=immediate fi else # We cannot hardcode anything, or else we can only hardcode existing # directories. _LT_TAGVAR(hardcode_action, $1)=unsupported fi AC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)]) if test "$_LT_TAGVAR(hardcode_action, $1)" = relink || test "$_LT_TAGVAR(inherit_rpath, $1)" = yes; then # Fast installation is not supported enable_fast_install=no elif test "$shlibpath_overrides_runpath" = yes || test "$enable_shared" = no; then # Fast installation is not necessary enable_fast_install=needless fi _LT_TAGDECL([], [hardcode_action], [0], [How to hardcode a shared library path into an executable]) ])# _LT_LINKER_HARDCODE_LIBPATH # _LT_CMD_STRIPLIB # ---------------- m4_defun([_LT_CMD_STRIPLIB], [m4_require([_LT_DECL_EGREP]) striplib= old_striplib= AC_MSG_CHECKING([whether stripping libraries is possible]) if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" test -z "$striplib" && striplib="$STRIP --strip-unneeded" AC_MSG_RESULT([yes]) else # FIXME - insert some real tests, host_os isn't really good enough case $host_os in darwin*) if test -n "$STRIP" ; then striplib="$STRIP -x" old_striplib="$STRIP -S" AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) fi ;; *) AC_MSG_RESULT([no]) ;; esac fi _LT_DECL([], [old_striplib], [1], [Commands to strip libraries]) _LT_DECL([], [striplib], [1]) ])# _LT_CMD_STRIPLIB # _LT_SYS_DYNAMIC_LINKER([TAG]) # ----------------------------- # PORTME Fill in your ld.so characteristics m4_defun([_LT_SYS_DYNAMIC_LINKER], [AC_REQUIRE([AC_CANONICAL_HOST])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_OBJDUMP])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_CHECK_SHELL_FEATURES])dnl AC_MSG_CHECKING([dynamic linker characteristics]) m4_if([$1], [], [ if test "$GCC" = yes; then case $host_os in darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; *) lt_awk_arg="/^libraries:/" ;; esac case $host_os in mingw* | cegcc*) lt_sed_strip_eq="s,=\([[A-Za-z]]:\),\1,g" ;; *) lt_sed_strip_eq="s,=/,/,g" ;; esac lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` case $lt_search_path_spec in *\;*) # if the path contains ";" then we assume it to be the separator # otherwise default to the standard path separator (i.e. ":") - it is # assumed that no part of a normal pathname contains ";" but that should # okay in the real world where ";" in dirpaths is itself problematic. lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` ;; *) lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` ;; esac # Ok, now we have the path, separated by spaces, we can step through it # and add multilib dir if necessary. lt_tmp_lt_search_path_spec= lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` for lt_sys_path in $lt_search_path_spec; do if test -d "$lt_sys_path/$lt_multi_os_dir"; then lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir" else test -d "$lt_sys_path" && \ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" fi done lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' BEGIN {RS=" "; FS="/|\n";} { lt_foo=""; lt_count=0; for (lt_i = NF; lt_i > 0; lt_i--) { if ($lt_i != "" && $lt_i != ".") { if ($lt_i == "..") { lt_count++; } else { if (lt_count == 0) { lt_foo="/" $lt_i lt_foo; } else { lt_count--; } } } } if (lt_foo != "") { lt_freq[[lt_foo]]++; } if (lt_freq[[lt_foo]] == 1) { print lt_foo; } }'` # AWK program above erroneously prepends '/' to C:/dos/paths # for these hosts. case $host_os in mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ $SED 's,/\([[A-Za-z]]:\),\1,g'` ;; esac sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` else sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" fi]) library_names_spec= libname_spec='lib$name' soname_spec= shrext_cmds=".so" postinstall_cmds= postuninstall_cmds= finish_cmds= finish_eval= shlibpath_var= shlibpath_overrides_runpath=unknown version_type=none dynamic_linker="$host_os ld.so" sys_lib_dlsearch_path_spec="/lib /usr/lib" need_lib_prefix=unknown hardcode_into_libs=no # when you set need_version to no, make sure it does not cause -set_version # flags to be left without arguments need_version=unknown case $host_os in aix3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' shlibpath_var=LIBPATH # AIX 3 has no versioning support, so we append a major version to the name. soname_spec='${libname}${release}${shared_ext}$major' ;; aix[[4-9]]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no hardcode_into_libs=yes if test "$host_cpu" = ia64; then # AIX 5 supports IA64 library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH else # With GCC up to 2.95.x, collect2 would create an import file # for dependence libraries. The import file would start with # the line `#! .'. This would cause the generated library to # depend on `.', always an invalid library. This was fixed in # development snapshots of GCC prior to 3.0. case $host_os in aix4 | aix4.[[01]] | aix4.[[01]].*) if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' echo ' yes ' echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then : else can_build_shared=no fi ;; esac # AIX (on Power*) has no versioning support, so currently we can not hardcode correct # soname into executable. Probably we can add versioning support to # collect2, so additional links can be useful in future. if test "$aix_use_runtimelinking" = yes; then # If using run time linking (on AIX 4.2 or later) use lib.so # instead of lib.a to let people know that these are not # typical AIX shared libraries. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' else # We preserve .a as extension for shared libraries through AIX4.2 # and later when we are not doing run time linking. library_names_spec='${libname}${release}.a $libname.a' soname_spec='${libname}${release}${shared_ext}$major' fi shlibpath_var=LIBPATH fi ;; amigaos*) case $host_cpu in powerpc) # Since July 2007 AmigaOS4 officially supports .so libraries. # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ;; m68k) library_names_spec='$libname.ixlibrary $libname.a' # Create ${libname}_ixlibrary.a entries in /sys/libs. finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' ;; esac ;; beos*) library_names_spec='${libname}${shared_ext}' dynamic_linker="$host_os ld.so" shlibpath_var=LIBRARY_PATH ;; bsdi[[45]]*) version_type=linux # correct to gnu/linux during the next big refactor need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" # the default ld.so.conf also contains /usr/contrib/lib and # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow # libtool to hard-code these into programs ;; cygwin* | mingw* | pw32* | cegcc*) version_type=windows shrext_cmds=".dll" need_version=no need_lib_prefix=no case $GCC,$cc_basename in yes,*) # gcc library_names_spec='$libname.dll.a' # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \${file}`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes case $host_os in cygwin*) # Cygwin DLLs use 'cyg' prefix rather than 'lib' soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' m4_if([$1], [],[ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"]) ;; mingw* | cegcc*) # MinGW DLLs use traditional 'lib' prefix soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' ;; pw32*) # pw32 DLLs use 'pw' prefix rather than 'lib' library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' ;; esac dynamic_linker='Win32 ld.exe' ;; *,cl*) # Native MSVC libname_spec='$name' soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' library_names_spec='${libname}.dll.lib' case $build_os in mingw*) sys_lib_search_path_spec= lt_save_ifs=$IFS IFS=';' for lt_path in $LIB do IFS=$lt_save_ifs # Let DOS variable expansion print the short 8.3 style file name. lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" done IFS=$lt_save_ifs # Convert to MSYS style. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([[a-zA-Z]]\\):| /\\1|g' -e 's|^ ||'` ;; cygwin*) # Convert to unix form, then to dos form, then back to unix form # but this time dos style (no spaces!) so that the unix form looks # like /cygdrive/c/PROGRA~1:/cygdr... sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ;; *) sys_lib_search_path_spec="$LIB" if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then # It is most probably a Windows format PATH. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` else sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` fi # FIXME: find the short name or the path components, as spaces are # common. (e.g. "Program Files" -> "PROGRA~1") ;; esac # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \${file}`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes dynamic_linker='Win32 link.exe' ;; *) # Assume MSVC wrapper library_names_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext} $libname.lib' dynamic_linker='Win32 ld.exe' ;; esac # FIXME: first we should search . and the directory the executable is in shlibpath_var=PATH ;; darwin* | rhapsody*) dynamic_linker="$host_os dyld" version_type=darwin need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' soname_spec='${libname}${release}${major}$shared_ext' shlibpath_overrides_runpath=yes shlibpath_var=DYLD_LIBRARY_PATH shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' m4_if([$1], [],[ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"]) sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' ;; dgux*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH ;; freebsd* | dragonfly*) # DragonFly does not have aout. When/if they implement a new # versioning mechanism, adjust this. if test -x /usr/bin/objformat; then objformat=`/usr/bin/objformat` else case $host_os in freebsd[[23]].*) objformat=aout ;; *) objformat=elf ;; esac fi version_type=freebsd-$objformat case $version_type in freebsd-elf*) library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' need_version=no need_lib_prefix=no ;; freebsd-*) library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' need_version=yes ;; esac shlibpath_var=LD_LIBRARY_PATH case $host_os in freebsd2.*) shlibpath_overrides_runpath=yes ;; freebsd3.[[01]]* | freebsdelf3.[[01]]*) shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \ freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1) shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; *) # from 4.6 on, and DragonFly shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; esac ;; gnu*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; haiku*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no dynamic_linker="$host_os runtime_loader" library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LIBRARY_PATH shlibpath_overrides_runpath=yes sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' hardcode_into_libs=yes ;; hpux9* | hpux10* | hpux11*) # Give a soname corresponding to the major version so that dld.sl refuses to # link against other versions. version_type=sunos need_lib_prefix=no need_version=no case $host_cpu in ia64*) shrext_cmds='.so' hardcode_into_libs=yes dynamic_linker="$host_os dld.so" shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' if test "X$HPUX_IA64_MODE" = X32; then sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" else sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" fi sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; hppa*64*) shrext_cmds='.sl' hardcode_into_libs=yes dynamic_linker="$host_os dld.sl" shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; *) shrext_cmds='.sl' dynamic_linker="$host_os dld.sl" shlibpath_var=SHLIB_PATH shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' ;; esac # HP-UX runs *really* slowly unless shared libraries are mode 555, ... postinstall_cmds='chmod 555 $lib' # or fails outright, so override atomically: install_override_mode=555 ;; interix[[3-9]]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; irix5* | irix6* | nonstopux*) case $host_os in nonstopux*) version_type=nonstopux ;; *) if test "$lt_cv_prog_gnu_ld" = yes; then version_type=linux # correct to gnu/linux during the next big refactor else version_type=irix fi ;; esac need_lib_prefix=no need_version=no soname_spec='${libname}${release}${shared_ext}$major' library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' case $host_os in irix5* | nonstopux*) libsuff= shlibsuff= ;; *) case $LD in # libtool.m4 will add one of these switches to LD *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= libmagic=32-bit;; *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 libmagic=N32;; *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 libmagic=64-bit;; *) libsuff= shlibsuff= libmagic=never-match;; esac ;; esac shlibpath_var=LD_LIBRARY${shlibsuff}_PATH shlibpath_overrides_runpath=no sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" hardcode_into_libs=yes ;; # No shared lib support for Linux oldld, aout, or coff. linux*oldld* | linux*aout* | linux*coff*) dynamic_linker=no ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no # Some binutils ld are patched to set DT_RUNPATH AC_CACHE_VAL([lt_cv_shlibpath_overrides_runpath], [lt_cv_shlibpath_overrides_runpath=no save_LDFLAGS=$LDFLAGS save_libdir=$libdir eval "libdir=/foo; wl=\"$_LT_TAGVAR(lt_prog_compiler_wl, $1)\"; \ LDFLAGS=\"\$LDFLAGS $_LT_TAGVAR(hardcode_libdir_flag_spec, $1)\"" AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], [AS_IF([ ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null], [lt_cv_shlibpath_overrides_runpath=yes])]) LDFLAGS=$save_LDFLAGS libdir=$save_libdir ]) shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes # Append ld.so.conf contents to the search path if test -f /etc/ld.so.conf; then lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" fi # We used to test for /lib/ld.so.1 and disable shared libraries on # powerpc, because MkLinux only supported shared libraries with the # GNU dynamic linker. Since this was broken with cross compilers, # most powerpc-linux boxes support dynamic linking these days and # people can always --disable-shared, the test was removed, and we # assume the GNU/Linux dynamic linker is in use. dynamic_linker='GNU/Linux ld.so' ;; netbsdelf*-gnu) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='NetBSD ld.elf_so' ;; netbsd*) version_type=sunos need_lib_prefix=no need_version=no if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' dynamic_linker='NetBSD (a.out) ld.so' else library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' dynamic_linker='NetBSD ld.elf_so' fi shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; newsos6) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; *nto* | *qnx*) version_type=qnx need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='ldqnx.so' ;; openbsd*) version_type=sunos sys_lib_dlsearch_path_spec="/usr/lib" need_lib_prefix=no # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. case $host_os in openbsd3.3 | openbsd3.3.*) need_version=yes ;; *) need_version=no ;; esac library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' shlibpath_var=LD_LIBRARY_PATH if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then case $host_os in openbsd2.[[89]] | openbsd2.[[89]].*) shlibpath_overrides_runpath=no ;; *) shlibpath_overrides_runpath=yes ;; esac else shlibpath_overrides_runpath=yes fi ;; os2*) libname_spec='$name' shrext_cmds=".dll" need_lib_prefix=no library_names_spec='$libname${shared_ext} $libname.a' dynamic_linker='OS/2 ld.exe' shlibpath_var=LIBPATH ;; osf3* | osf4* | osf5*) version_type=osf need_lib_prefix=no need_version=no soname_spec='${libname}${release}${shared_ext}$major' library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" ;; rdos*) dynamic_linker=no ;; solaris*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes # ldd complains unless libraries are executable postinstall_cmds='chmod +x $lib' ;; sunos4*) version_type=sunos library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes if test "$with_gnu_ld" = yes; then need_lib_prefix=no fi need_version=yes ;; sysv4 | sysv4.3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH case $host_vendor in sni) shlibpath_overrides_runpath=no need_lib_prefix=no runpath_var=LD_RUN_PATH ;; siemens) need_lib_prefix=no ;; motorola) need_lib_prefix=no need_version=no shlibpath_overrides_runpath=no sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' ;; esac ;; sysv4*MP*) if test -d /usr/nec ;then version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' soname_spec='$libname${shared_ext}.$major' shlibpath_var=LD_LIBRARY_PATH fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) version_type=freebsd-elf need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes if test "$with_gnu_ld" = yes; then sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' else sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' case $host_os in sco3.2v5*) sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" ;; esac fi sys_lib_dlsearch_path_spec='/usr/lib' ;; tpf*) # TPF is a cross-target only. Preferred cross-host = GNU/Linux. version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; uts4*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH ;; *) dynamic_linker=no ;; esac AC_MSG_RESULT([$dynamic_linker]) test "$dynamic_linker" = no && can_build_shared=no variables_saved_for_relink="PATH $shlibpath_var $runpath_var" if test "$GCC" = yes; then variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" fi if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" fi if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" fi _LT_DECL([], [variables_saved_for_relink], [1], [Variables whose values should be saved in libtool wrapper scripts and restored at link time]) _LT_DECL([], [need_lib_prefix], [0], [Do we need the "lib" prefix for modules?]) _LT_DECL([], [need_version], [0], [Do we need a version for libraries?]) _LT_DECL([], [version_type], [0], [Library versioning type]) _LT_DECL([], [runpath_var], [0], [Shared library runtime path variable]) _LT_DECL([], [shlibpath_var], [0],[Shared library path variable]) _LT_DECL([], [shlibpath_overrides_runpath], [0], [Is shlibpath searched before the hard-coded library search path?]) _LT_DECL([], [libname_spec], [1], [Format of library name prefix]) _LT_DECL([], [library_names_spec], [1], [[List of archive names. First name is the real one, the rest are links. The last name is the one that the linker finds with -lNAME]]) _LT_DECL([], [soname_spec], [1], [[The coded name of the library, if different from the real name]]) _LT_DECL([], [install_override_mode], [1], [Permission mode override for installation of shared libraries]) _LT_DECL([], [postinstall_cmds], [2], [Command to use after installation of a shared archive]) _LT_DECL([], [postuninstall_cmds], [2], [Command to use after uninstallation of a shared archive]) _LT_DECL([], [finish_cmds], [2], [Commands used to finish a libtool library installation in a directory]) _LT_DECL([], [finish_eval], [1], [[As "finish_cmds", except a single script fragment to be evaled but not shown]]) _LT_DECL([], [hardcode_into_libs], [0], [Whether we should hardcode library paths into libraries]) _LT_DECL([], [sys_lib_search_path_spec], [2], [Compile-time system search path for libraries]) _LT_DECL([], [sys_lib_dlsearch_path_spec], [2], [Run-time system search path for libraries]) ])# _LT_SYS_DYNAMIC_LINKER # _LT_PATH_TOOL_PREFIX(TOOL) # -------------------------- # find a file program which can recognize shared library AC_DEFUN([_LT_PATH_TOOL_PREFIX], [m4_require([_LT_DECL_EGREP])dnl AC_MSG_CHECKING([for $1]) AC_CACHE_VAL(lt_cv_path_MAGIC_CMD, [case $MAGIC_CMD in [[\\/*] | ?:[\\/]*]) lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. ;; *) lt_save_MAGIC_CMD="$MAGIC_CMD" lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR dnl $ac_dummy forces splitting on constant user-supplied paths. dnl POSIX.2 word splitting is done only on the output of word expansions, dnl not every word. This closes a longstanding sh security hole. ac_dummy="m4_if([$2], , $PATH, [$2])" for ac_dir in $ac_dummy; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$1; then lt_cv_path_MAGIC_CMD="$ac_dir/$1" if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then : else cat <<_LT_EOF 1>&2 *** Warning: the command libtool uses to detect shared libraries, *** $file_magic_cmd, produces output that libtool cannot recognize. *** The result is that libtool may fail to recognize shared libraries *** as such. This will affect the creation of libtool libraries that *** depend on shared libraries, but programs linked with such libtool *** libraries will work regardless of this problem. Nevertheless, you *** may want to report the problem to your system manager and/or to *** bug-libtool@gnu.org _LT_EOF fi ;; esac fi break fi done IFS="$lt_save_ifs" MAGIC_CMD="$lt_save_MAGIC_CMD" ;; esac]) MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if test -n "$MAGIC_CMD"; then AC_MSG_RESULT($MAGIC_CMD) else AC_MSG_RESULT(no) fi _LT_DECL([], [MAGIC_CMD], [0], [Used to examine libraries when file_magic_cmd begins with "file"])dnl ])# _LT_PATH_TOOL_PREFIX # Old name: AU_ALIAS([AC_PATH_TOOL_PREFIX], [_LT_PATH_TOOL_PREFIX]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_PATH_TOOL_PREFIX], []) # _LT_PATH_MAGIC # -------------- # find a file program which can recognize a shared library m4_defun([_LT_PATH_MAGIC], [_LT_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH) if test -z "$lt_cv_path_MAGIC_CMD"; then if test -n "$ac_tool_prefix"; then _LT_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH) else MAGIC_CMD=: fi fi ])# _LT_PATH_MAGIC # LT_PATH_LD # ---------- # find the pathname to the GNU or non-GNU linker AC_DEFUN([LT_PATH_LD], [AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_CANONICAL_BUILD])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_PROG_ECHO_BACKSLASH])dnl AC_ARG_WITH([gnu-ld], [AS_HELP_STRING([--with-gnu-ld], [assume the C compiler uses GNU ld @<:@default=no@:>@])], [test "$withval" = no || with_gnu_ld=yes], [with_gnu_ld=no])dnl ac_prog=ld if test "$GCC" = yes; then # Check if gcc -print-prog-name=ld gives a path. AC_MSG_CHECKING([for ld used by $CC]) case $host in *-*-mingw*) # gcc leaves a trailing carriage return which upsets mingw ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; *) ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; esac case $ac_prog in # Accept absolute paths. [[\\/]]* | ?:[[\\/]]*) re_direlt='/[[^/]][[^/]]*/\.\./' # Canonicalize the pathname of ld ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` done test -z "$LD" && LD="$ac_prog" ;; "") # If it fails, then pretend we aren't using GCC. ac_prog=ld ;; *) # If it is relative, then search for the first ld in PATH. with_gnu_ld=unknown ;; esac elif test "$with_gnu_ld" = yes; then AC_MSG_CHECKING([for GNU ld]) else AC_MSG_CHECKING([for non-GNU ld]) fi AC_CACHE_VAL(lt_cv_path_LD, [if test -z "$LD"; then lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR for ac_dir in $PATH; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then lt_cv_path_LD="$ac_dir/$ac_prog" # Check to see if the program is GNU ld. I'd rather use --version, # but apparently some variants of GNU ld only accept -v. # Break only if it was the GNU/non-GNU ld that we prefer. case `"$lt_cv_path_LD" -v 2>&1 &1 /dev/null 2>&1; then lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' else # Keep this pattern in sync with the one in func_win32_libid. lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' lt_cv_file_magic_cmd='$OBJDUMP -f' fi ;; cegcc*) # use the weaker test based on 'objdump'. See mingw*. lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' lt_cv_file_magic_cmd='$OBJDUMP -f' ;; darwin* | rhapsody*) lt_cv_deplibs_check_method=pass_all ;; freebsd* | dragonfly*) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then case $host_cpu in i*86 ) # Not sure whether the presence of OpenBSD here was a mistake. # Let's accept both of them until this is cleared up. lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library' lt_cv_file_magic_cmd=/usr/bin/file lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` ;; esac else lt_cv_deplibs_check_method=pass_all fi ;; gnu*) lt_cv_deplibs_check_method=pass_all ;; haiku*) lt_cv_deplibs_check_method=pass_all ;; hpux10.20* | hpux11*) lt_cv_file_magic_cmd=/usr/bin/file case $host_cpu in ia64*) lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64' lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so ;; hppa*64*) [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]'] lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl ;; *) lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]]\.[[0-9]]) shared library' lt_cv_file_magic_test_file=/usr/lib/libc.sl ;; esac ;; interix[[3-9]]*) # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$' ;; irix5* | irix6* | nonstopux*) case $LD in *-32|*"-32 ") libmagic=32-bit;; *-n32|*"-n32 ") libmagic=N32;; *-64|*"-64 ") libmagic=64-bit;; *) libmagic=never-match;; esac lt_cv_deplibs_check_method=pass_all ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu) lt_cv_deplibs_check_method=pass_all ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$' fi ;; newos6*) lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)' lt_cv_file_magic_cmd=/usr/bin/file lt_cv_file_magic_test_file=/usr/lib/libnls.so ;; *nto* | *qnx*) lt_cv_deplibs_check_method=pass_all ;; openbsd*) if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' fi ;; osf3* | osf4* | osf5*) lt_cv_deplibs_check_method=pass_all ;; rdos*) lt_cv_deplibs_check_method=pass_all ;; solaris*) lt_cv_deplibs_check_method=pass_all ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) lt_cv_deplibs_check_method=pass_all ;; sysv4 | sysv4.3*) case $host_vendor in motorola) lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]' lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` ;; ncr) lt_cv_deplibs_check_method=pass_all ;; sequent) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' ;; sni) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib" lt_cv_file_magic_test_file=/lib/libc.so ;; siemens) lt_cv_deplibs_check_method=pass_all ;; pc) lt_cv_deplibs_check_method=pass_all ;; esac ;; tpf*) lt_cv_deplibs_check_method=pass_all ;; esac ]) file_magic_glob= want_nocaseglob=no if test "$build" = "$host"; then case $host_os in mingw* | pw32*) if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then want_nocaseglob=yes else file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[[\1]]\/[[\1]]\/g;/g"` fi ;; esac fi file_magic_cmd=$lt_cv_file_magic_cmd deplibs_check_method=$lt_cv_deplibs_check_method test -z "$deplibs_check_method" && deplibs_check_method=unknown _LT_DECL([], [deplibs_check_method], [1], [Method to check whether dependent libraries are shared objects]) _LT_DECL([], [file_magic_cmd], [1], [Command to use when deplibs_check_method = "file_magic"]) _LT_DECL([], [file_magic_glob], [1], [How to find potential files when deplibs_check_method = "file_magic"]) _LT_DECL([], [want_nocaseglob], [1], [Find potential files using nocaseglob when deplibs_check_method = "file_magic"]) ])# _LT_CHECK_MAGIC_METHOD # LT_PATH_NM # ---------- # find the pathname to a BSD- or MS-compatible name lister AC_DEFUN([LT_PATH_NM], [AC_REQUIRE([AC_PROG_CC])dnl AC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM, [if test -n "$NM"; then # Let the user override the test. lt_cv_path_NM="$NM" else lt_nm_to_check="${ac_tool_prefix}nm" if test -n "$ac_tool_prefix" && test "$build" = "$host"; then lt_nm_to_check="$lt_nm_to_check nm" fi for lt_tmp_nm in $lt_nm_to_check; do lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. tmp_nm="$ac_dir/$lt_tmp_nm" if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then # Check to see if the nm accepts a BSD-compat flag. # Adding the `sed 1q' prevents false positives on HP-UX, which says: # nm: unknown option "B" ignored # Tru64's nm complains that /dev/null is an invalid object file case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in */dev/null* | *'Invalid file or object type'*) lt_cv_path_NM="$tmp_nm -B" break ;; *) case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in */dev/null*) lt_cv_path_NM="$tmp_nm -p" break ;; *) lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but continue # so that we can try to find one that supports BSD flags ;; esac ;; esac fi done IFS="$lt_save_ifs" done : ${lt_cv_path_NM=no} fi]) if test "$lt_cv_path_NM" != "no"; then NM="$lt_cv_path_NM" else # Didn't find any BSD compatible name lister, look for dumpbin. if test -n "$DUMPBIN"; then : # Let the user override the test. else AC_CHECK_TOOLS(DUMPBIN, [dumpbin "link -dump"], :) case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in *COFF*) DUMPBIN="$DUMPBIN -symbols" ;; *) DUMPBIN=: ;; esac fi AC_SUBST([DUMPBIN]) if test "$DUMPBIN" != ":"; then NM="$DUMPBIN" fi fi test -z "$NM" && NM=nm AC_SUBST([NM]) _LT_DECL([], [NM], [1], [A BSD- or MS-compatible name lister])dnl AC_CACHE_CHECK([the name lister ($NM) interface], [lt_cv_nm_interface], [lt_cv_nm_interface="BSD nm" echo "int some_variable = 0;" > conftest.$ac_ext (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&AS_MESSAGE_LOG_FD) (eval "$ac_compile" 2>conftest.err) cat conftest.err >&AS_MESSAGE_LOG_FD (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&AS_MESSAGE_LOG_FD) (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) cat conftest.err >&AS_MESSAGE_LOG_FD (eval echo "\"\$as_me:$LINENO: output\"" >&AS_MESSAGE_LOG_FD) cat conftest.out >&AS_MESSAGE_LOG_FD if $GREP 'External.*some_variable' conftest.out > /dev/null; then lt_cv_nm_interface="MS dumpbin" fi rm -f conftest*]) ])# LT_PATH_NM # Old names: AU_ALIAS([AM_PROG_NM], [LT_PATH_NM]) AU_ALIAS([AC_PROG_NM], [LT_PATH_NM]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AM_PROG_NM], []) dnl AC_DEFUN([AC_PROG_NM], []) # _LT_CHECK_SHAREDLIB_FROM_LINKLIB # -------------------------------- # how to determine the name of the shared library # associated with a specific link library. # -- PORTME fill in with the dynamic library characteristics m4_defun([_LT_CHECK_SHAREDLIB_FROM_LINKLIB], [m4_require([_LT_DECL_EGREP]) m4_require([_LT_DECL_OBJDUMP]) m4_require([_LT_DECL_DLLTOOL]) AC_CACHE_CHECK([how to associate runtime and link libraries], lt_cv_sharedlib_from_linklib_cmd, [lt_cv_sharedlib_from_linklib_cmd='unknown' case $host_os in cygwin* | mingw* | pw32* | cegcc*) # two different shell functions defined in ltmain.sh # decide which to use based on capabilities of $DLLTOOL case `$DLLTOOL --help 2>&1` in *--identify-strict*) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib ;; *) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback ;; esac ;; *) # fallback: assume linklib IS sharedlib lt_cv_sharedlib_from_linklib_cmd="$ECHO" ;; esac ]) sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO _LT_DECL([], [sharedlib_from_linklib_cmd], [1], [Command to associate shared and link libraries]) ])# _LT_CHECK_SHAREDLIB_FROM_LINKLIB # _LT_PATH_MANIFEST_TOOL # ---------------------- # locate the manifest tool m4_defun([_LT_PATH_MANIFEST_TOOL], [AC_CHECK_TOOL(MANIFEST_TOOL, mt, :) test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt AC_CACHE_CHECK([if $MANIFEST_TOOL is a manifest tool], [lt_cv_path_mainfest_tool], [lt_cv_path_mainfest_tool=no echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&AS_MESSAGE_LOG_FD $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out cat conftest.err >&AS_MESSAGE_LOG_FD if $GREP 'Manifest Tool' conftest.out > /dev/null; then lt_cv_path_mainfest_tool=yes fi rm -f conftest*]) if test "x$lt_cv_path_mainfest_tool" != xyes; then MANIFEST_TOOL=: fi _LT_DECL([], [MANIFEST_TOOL], [1], [Manifest tool])dnl ])# _LT_PATH_MANIFEST_TOOL # LT_LIB_M # -------- # check for math library AC_DEFUN([LT_LIB_M], [AC_REQUIRE([AC_CANONICAL_HOST])dnl LIBM= case $host in *-*-beos* | *-*-cegcc* | *-*-cygwin* | *-*-haiku* | *-*-pw32* | *-*-darwin*) # These system don't have libm, or don't need it ;; *-ncr-sysv4.3*) AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw") AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm") ;; *) AC_CHECK_LIB(m, cos, LIBM="-lm") ;; esac AC_SUBST([LIBM]) ])# LT_LIB_M # Old name: AU_ALIAS([AC_CHECK_LIBM], [LT_LIB_M]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_CHECK_LIBM], []) # _LT_COMPILER_NO_RTTI([TAGNAME]) # ------------------------------- m4_defun([_LT_COMPILER_NO_RTTI], [m4_require([_LT_TAG_COMPILER])dnl _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= if test "$GCC" = yes; then case $cc_basename in nvcc*) _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -Xcompiler -fno-builtin' ;; *) _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' ;; esac _LT_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions], lt_cv_prog_compiler_rtti_exceptions, [-fno-rtti -fno-exceptions], [], [_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"]) fi _LT_TAGDECL([no_builtin_flag], [lt_prog_compiler_no_builtin_flag], [1], [Compiler flag to turn off builtin functions]) ])# _LT_COMPILER_NO_RTTI # _LT_CMD_GLOBAL_SYMBOLS # ---------------------- m4_defun([_LT_CMD_GLOBAL_SYMBOLS], [AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([AC_PROG_AWK])dnl AC_REQUIRE([LT_PATH_NM])dnl AC_REQUIRE([LT_PATH_LD])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_TAG_COMPILER])dnl # Check for command to grab the raw symbol name followed by C symbol from nm. AC_MSG_CHECKING([command to parse $NM output from $compiler object]) AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe], [ # These are sane defaults that work on at least a few old systems. # [They come from Ultrix. What could be older than Ultrix?!! ;)] # Character class describing NM global symbol codes. symcode='[[BCDEGRST]]' # Regexp to match symbols that can be accessed directly from C. sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)' # Define system-specific variables. case $host_os in aix*) symcode='[[BCDT]]' ;; cygwin* | mingw* | pw32* | cegcc*) symcode='[[ABCDGISTW]]' ;; hpux*) if test "$host_cpu" = ia64; then symcode='[[ABCDEGRST]]' fi ;; irix* | nonstopux*) symcode='[[BCDEGRST]]' ;; osf*) symcode='[[BCDEGQRST]]' ;; solaris*) symcode='[[BDRT]]' ;; sco3.2v5*) symcode='[[DT]]' ;; sysv4.2uw2*) symcode='[[DT]]' ;; sysv5* | sco5v6* | unixware* | OpenUNIX*) symcode='[[ABDT]]' ;; sysv4) symcode='[[DFNSTU]]' ;; esac # If we're using GNU nm, then use its standard symbol codes. case `$NM -V 2>&1` in *GNU* | *'with BFD'*) symcode='[[ABCDGIRSTW]]' ;; esac # Transform an extracted symbol line into a proper C declaration. # Some systems (esp. on ia64) link data and code symbols differently, # so use this general approach. lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" # Transform an extracted symbol line into symbol name and symbol address lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\)[[ ]]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p'" lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([[^ ]]*\)[[ ]]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \(lib[[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"lib\2\", (void *) \&\2},/p'" # Handle CRLF in mingw tool chain opt_cr= case $build_os in mingw*) opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp ;; esac # Try without a prefix underscore, then with it. for ac_symprfx in "" "_"; do # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. symxfrm="\\1 $ac_symprfx\\2 \\2" # Write the raw and C identifiers. if test "$lt_cv_nm_interface" = "MS dumpbin"; then # Fake it for dumpbin and say T for any non-static function # and D for any global variable. # Also find C++ and __fastcall symbols from MSVC++, # which start with @ or ?. lt_cv_sys_global_symbol_pipe="$AWK ['"\ " {last_section=section; section=\$ 3};"\ " /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ " /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ " \$ 0!~/External *\|/{next};"\ " / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ " {if(hide[section]) next};"\ " {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\ " {split(\$ 0, a, /\||\r/); split(a[2], s)};"\ " s[1]~/^[@?]/{print s[1], s[1]; next};"\ " s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\ " ' prfx=^$ac_symprfx]" else lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" fi lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" # Check to see that the pipe works correctly. pipe_works=no rm -f conftest* cat > conftest.$ac_ext <<_LT_EOF #ifdef __cplusplus extern "C" { #endif char nm_test_var; void nm_test_func(void); void nm_test_func(void){} #ifdef __cplusplus } #endif int main(){nm_test_var='a';nm_test_func();return(0);} _LT_EOF if AC_TRY_EVAL(ac_compile); then # Now try to grab the symbols. nlist=conftest.nm if AC_TRY_EVAL(NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) && test -s "$nlist"; then # Try sorting and uniquifying the output. if sort "$nlist" | uniq > "$nlist"T; then mv -f "$nlist"T "$nlist" else rm -f "$nlist"T fi # Make sure that we snagged all the symbols we need. if $GREP ' nm_test_var$' "$nlist" >/dev/null; then if $GREP ' nm_test_func$' "$nlist" >/dev/null; then cat <<_LT_EOF > conftest.$ac_ext /* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ #if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) /* DATA imports from DLLs on WIN32 con't be const, because runtime relocations are performed -- see ld's documentation on pseudo-relocs. */ # define LT@&t@_DLSYM_CONST #elif defined(__osf__) /* This system does not cope well with relocations in const data. */ # define LT@&t@_DLSYM_CONST #else # define LT@&t@_DLSYM_CONST const #endif #ifdef __cplusplus extern "C" { #endif _LT_EOF # Now generate the symbol file. eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' cat <<_LT_EOF >> conftest.$ac_ext /* The mapping between symbol names and symbols. */ LT@&t@_DLSYM_CONST struct { const char *name; void *address; } lt__PROGRAM__LTX_preloaded_symbols[[]] = { { "@PROGRAM@", (void *) 0 }, _LT_EOF $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext cat <<\_LT_EOF >> conftest.$ac_ext {0, (void *) 0} }; /* This works around a problem in FreeBSD linker */ #ifdef FREEBSD_WORKAROUND static const void *lt_preloaded_setup() { return lt__PROGRAM__LTX_preloaded_symbols; } #endif #ifdef __cplusplus } #endif _LT_EOF # Now try linking the two files. mv conftest.$ac_objext conftstm.$ac_objext lt_globsym_save_LIBS=$LIBS lt_globsym_save_CFLAGS=$CFLAGS LIBS="conftstm.$ac_objext" CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)" if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext}; then pipe_works=yes fi LIBS=$lt_globsym_save_LIBS CFLAGS=$lt_globsym_save_CFLAGS else echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD fi else echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD fi else echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD fi else echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD cat conftest.$ac_ext >&5 fi rm -rf conftest* conftst* # Do not use the global_symbol_pipe unless it works. if test "$pipe_works" = yes; then break else lt_cv_sys_global_symbol_pipe= fi done ]) if test -z "$lt_cv_sys_global_symbol_pipe"; then lt_cv_sys_global_symbol_to_cdecl= fi if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then AC_MSG_RESULT(failed) else AC_MSG_RESULT(ok) fi # Response file support. if test "$lt_cv_nm_interface" = "MS dumpbin"; then nm_file_list_spec='@' elif $NM --help 2>/dev/null | grep '[[@]]FILE' >/dev/null; then nm_file_list_spec='@' fi _LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1], [Take the output of nm and produce a listing of raw symbols and C names]) _LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1], [Transform the output of nm in a proper C declaration]) _LT_DECL([global_symbol_to_c_name_address], [lt_cv_sys_global_symbol_to_c_name_address], [1], [Transform the output of nm in a C name address pair]) _LT_DECL([global_symbol_to_c_name_address_lib_prefix], [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1], [Transform the output of nm in a C name address pair when lib prefix is needed]) _LT_DECL([], [nm_file_list_spec], [1], [Specify filename containing input files for $NM]) ]) # _LT_CMD_GLOBAL_SYMBOLS # _LT_COMPILER_PIC([TAGNAME]) # --------------------------- m4_defun([_LT_COMPILER_PIC], [m4_require([_LT_TAG_COMPILER])dnl _LT_TAGVAR(lt_prog_compiler_wl, $1)= _LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_static, $1)= m4_if([$1], [CXX], [ # C++ specific cases for pic, static, wl, etc. if test "$GXX" = yes; then _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' case $host_os in aix*) # All AIX code is PIC. if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but # adding the `-m68020' flag to GCC prevents building anything better, # like `-m68040'. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' ;; esac ;; beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | cygwin* | os2* | pw32* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style # (--disable-auto-import) libraries m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' ;; *djgpp*) # DJGPP does not support shared libraries at all _LT_TAGVAR(lt_prog_compiler_pic, $1)= ;; haiku*) # PIC is the default for Haiku. # The "-static" flag exists, but is broken. _LT_TAGVAR(lt_prog_compiler_static, $1)= ;; interix[[3-9]]*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; sysv4*MP*) if test -d /usr/nec; then _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic fi ;; hpux*) # PIC is the default for 64-bit PA HP-UX, but not for 32-bit # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag # sets the default TLS model and affects inlining. case $host_cpu in hppa*64*) ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac ;; *qnx* | *nto*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac else case $host_os in aix[[4-9]]*) # All AIX code is PIC. if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' else _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' fi ;; chorus*) case $cc_basename in cxch68*) # Green Hills C++ Compiler # _LT_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" ;; esac ;; mingw* | cygwin* | os2* | pw32* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) ;; dgux*) case $cc_basename in ec++*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ;; ghcx*) # Green Hills C++ Compiler _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ;; *) ;; esac ;; freebsd* | dragonfly*) # FreeBSD uses GNU C++ ;; hpux9* | hpux10* | hpux11*) case $cc_basename in CC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' if test "$host_cpu" != ia64; then _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' fi ;; aCC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' ;; esac ;; *) ;; esac ;; interix*) # This is c89, which is MS Visual C++ (no shared libs) # Anyone wants to do a port? ;; irix5* | irix6* | nonstopux*) case $cc_basename in CC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' # CC pic flag -KPIC is the default. ;; *) ;; esac ;; linux* | k*bsd*-gnu | kopensolaris*-gnu) case $cc_basename in KCC*) # KAI C++ Compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; ecpc* ) # old Intel C++ for x86_64 which still supported -KPIC. _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; icpc* ) # Intel C++, used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; pgCC* | pgcpp*) # Portland Group C++ compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; cxx*) # Compaq C++ # Make sure the PIC flag is empty. It appears that all Alpha # Linux and Compaq Tru64 Unix objects are PIC. _LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; xlc* | xlC* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL 8.0, 9.0 on PPC and BlueGene _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C++ 5.9 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' ;; esac ;; esac ;; lynxos*) ;; m88k*) ;; mvs*) case $cc_basename in cxx*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall' ;; *) ;; esac ;; netbsd* | netbsdelf*-gnu) ;; *qnx* | *nto*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; osf3* | osf4* | osf5*) case $cc_basename in KCC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' ;; RCC*) # Rational C++ 2.4.1 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ;; cxx*) # Digital/Compaq C++ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # Make sure the PIC flag is empty. It appears that all Alpha # Linux and Compaq Tru64 Unix objects are PIC. _LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; *) ;; esac ;; psos*) ;; solaris*) case $cc_basename in CC* | sunCC*) # Sun C++ 4.2, 5.x and Centerline C++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' ;; gcx*) # Green Hills C++ Compiler _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' ;; *) ;; esac ;; sunos4*) case $cc_basename in CC*) # Sun C++ 4.x _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; lcc*) # Lucid _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ;; *) ;; esac ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) case $cc_basename in CC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; esac ;; tandem*) case $cc_basename in NCC*) # NonStop-UX NCC 3.20 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ;; *) ;; esac ;; vxworks*) ;; *) _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ;; esac fi ], [ if test "$GCC" = yes; then _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' case $host_os in aix*) # All AIX code is PIC. if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but # adding the `-m68020' flag to GCC prevents building anything better, # like `-m68040'. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' ;; esac ;; beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style # (--disable-auto-import) libraries m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' ;; haiku*) # PIC is the default for Haiku. # The "-static" flag exists, but is broken. _LT_TAGVAR(lt_prog_compiler_static, $1)= ;; hpux*) # PIC is the default for 64-bit PA HP-UX, but not for 32-bit # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag # sets the default TLS model and affects inlining. case $host_cpu in hppa*64*) # +Z the default ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac ;; interix[[3-9]]*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; msdosdjgpp*) # Just because we use GCC doesn't mean we suddenly get shared libraries # on systems that don't support them. _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no enable_shared=no ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; sysv4*MP*) if test -d /usr/nec; then _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic fi ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac case $cc_basename in nvcc*) # Cuda Compiler Driver 2.2 _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Xlinker ' if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then _LT_TAGVAR(lt_prog_compiler_pic, $1)="-Xcompiler $_LT_TAGVAR(lt_prog_compiler_pic, $1)" fi ;; esac else # PORTME Check for flag to pass linker flags through the system compiler. case $host_os in aix*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' else _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' fi ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) ;; hpux9* | hpux10* | hpux11*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but # not for PA HP-UX. case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' ;; esac # Is there a better lt_prog_compiler_static that works with the bundled CC? _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' ;; irix5* | irix6* | nonstopux*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # PIC (with -KPIC) is the default. _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; linux* | k*bsd*-gnu | kopensolaris*-gnu) case $cc_basename in # old Intel for x86_64 which still supported -KPIC. ecc*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; # icc used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. icc* | ifort*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; # Lahey Fortran 8.1. lf95*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='--shared' _LT_TAGVAR(lt_prog_compiler_static, $1)='--static' ;; nagfor*) # NAG Fortran compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group compilers (*not* the Pentium gcc compiler, # which looks to be a dead project) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; ccc*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # All Alpha code is PIC. _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; xl* | bgxl* | bgf* | mpixl*) # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [[1-7]].* | *Sun*Fortran*\ 8.[[0-3]]*) # Sun Fortran 8.3 passes all unrecognized flags to the linker _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='' ;; *Sun\ F* | *Sun*Fortran*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' ;; *Sun\ C*) # Sun C 5.9 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ;; *Intel*\ [[CF]]*Compiler*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; *Portland\ Group*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; esac ;; esac ;; newsos6) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; osf3* | osf4* | osf5*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # All OSF/1 code is PIC. _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; rdos*) _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; solaris*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' case $cc_basename in f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';; *) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';; esac ;; sunos4*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; sysv4 | sysv4.2uw2* | sysv4.3*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; sysv4*MP*) if test -d /usr/nec ;then _LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; unicos*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ;; uts4*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; *) _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ;; esac fi ]) case $host_os in # For platforms which do not support PIC, -DPIC is meaningless: *djgpp*) _LT_TAGVAR(lt_prog_compiler_pic, $1)= ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])" ;; esac AC_CACHE_CHECK([for $compiler option to produce PIC], [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)], [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_prog_compiler_pic, $1)]) _LT_TAGVAR(lt_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_cv_prog_compiler_pic, $1) # # Check to make sure the PIC flag actually works. # if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then _LT_COMPILER_OPTION([if $compiler PIC flag $_LT_TAGVAR(lt_prog_compiler_pic, $1) works], [_LT_TAGVAR(lt_cv_prog_compiler_pic_works, $1)], [$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])], [], [case $_LT_TAGVAR(lt_prog_compiler_pic, $1) in "" | " "*) ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_TAGVAR(lt_prog_compiler_pic, $1)" ;; esac], [_LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no]) fi _LT_TAGDECL([pic_flag], [lt_prog_compiler_pic], [1], [Additional compiler flags for building library objects]) _LT_TAGDECL([wl], [lt_prog_compiler_wl], [1], [How to pass a linker flag through the compiler]) # # Check to make sure the static flag actually works. # wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_TAGVAR(lt_prog_compiler_static, $1)\" _LT_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works], _LT_TAGVAR(lt_cv_prog_compiler_static_works, $1), $lt_tmp_static_flag, [], [_LT_TAGVAR(lt_prog_compiler_static, $1)=]) _LT_TAGDECL([link_static_flag], [lt_prog_compiler_static], [1], [Compiler flag to prevent dynamic linking]) ])# _LT_COMPILER_PIC # _LT_LINKER_SHLIBS([TAGNAME]) # ---------------------------- # See if the linker supports building shared libraries. m4_defun([_LT_LINKER_SHLIBS], [AC_REQUIRE([LT_PATH_LD])dnl AC_REQUIRE([LT_PATH_NM])dnl m4_require([_LT_PATH_MANIFEST_TOOL])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl m4_require([_LT_TAG_COMPILER])dnl AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) m4_if([$1], [CXX], [ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] case $host_os in aix[[4-9]]*) # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to AIX nm, but means don't demangle with GNU nm # Also, AIX nm treats weak defined symbols like other global defined # symbols, whereas GNU nm marks them as "W". if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' else _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' fi ;; pw32*) _LT_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds" ;; cygwin* | mingw* | cegcc*) case $cc_basename in cl*) _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' ;; *) _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] ;; esac ;; linux* | k*bsd*-gnu | gnu*) _LT_TAGVAR(link_all_deplibs, $1)=no ;; *) _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' ;; esac ], [ runpath_var= _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_cmds, $1)= _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(compiler_needs_object, $1)=no _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(old_archive_from_new_cmds, $1)= _LT_TAGVAR(old_archive_from_expsyms_cmds, $1)= _LT_TAGVAR(thread_safe_flag_spec, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= # include_expsyms should be a list of space-separated symbols to be *always* # included in the symbol list _LT_TAGVAR(include_expsyms, $1)= # exclude_expsyms can be an extended regexp of symbols to exclude # it will be wrapped by ` (' and `)$', so one must not match beginning or # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', # as well as any symbol that contains `d'. _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out # platforms (ab)use it in PIC code, but their linkers get confused if # the symbol is explicitly referenced. Since portable code cannot # rely on this symbol name, it's probably fine to never include it in # preloaded symbol tables. # Exclude shared library initialization/finalization symbols. dnl Note also adjust exclude_expsyms for C++ above. extract_expsyms_cmds= case $host_os in cygwin* | mingw* | pw32* | cegcc*) # FIXME: the MSVC++ port hasn't been tested in a loooong time # When not using gcc, we currently assume that we are using # Microsoft Visual C++. if test "$GCC" != yes; then with_gnu_ld=no fi ;; interix*) # we just hope/assume this is gcc and not c89 (= MSVC++) with_gnu_ld=yes ;; openbsd*) with_gnu_ld=no ;; linux* | k*bsd*-gnu | gnu*) _LT_TAGVAR(link_all_deplibs, $1)=no ;; esac _LT_TAGVAR(ld_shlibs, $1)=yes # On some targets, GNU ld is compatible enough with the native linker # that we're better off using the native interface for both. lt_use_gnu_ld_interface=no if test "$with_gnu_ld" = yes; then case $host_os in aix*) # The AIX port of GNU ld has always aspired to compatibility # with the native linker. However, as the warning in the GNU ld # block says, versions before 2.19.5* couldn't really create working # shared libraries, regardless of the interface used. case `$LD -v 2>&1` in *\ \(GNU\ Binutils\)\ 2.19.5*) ;; *\ \(GNU\ Binutils\)\ 2.[[2-9]]*) ;; *\ \(GNU\ Binutils\)\ [[3-9]]*) ;; *) lt_use_gnu_ld_interface=yes ;; esac ;; *) lt_use_gnu_ld_interface=yes ;; esac fi if test "$lt_use_gnu_ld_interface" = yes; then # If archive_cmds runs LD, not CC, wlarc should be empty wlarc='${wl}' # Set some defaults for GNU ld with shared library support. These # are reset later if shared libraries are not supported. Putting them # here allows them to be overridden if necessary. runpath_var=LD_RUN_PATH _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' # ancient GNU ld didn't support --whole-archive et. al. if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' else _LT_TAGVAR(whole_archive_flag_spec, $1)= fi supports_anon_versioning=no case `$LD -v 2>&1` in *GNU\ gold*) supports_anon_versioning=yes ;; *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11 *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... *\ 2.11.*) ;; # other 2.11 versions *) supports_anon_versioning=yes ;; esac # See if GNU ld supports shared libraries. case $host_os in aix[[3-9]]*) # On AIX/PPC, the GNU linker is very broken if test "$host_cpu" != ia64; then _LT_TAGVAR(ld_shlibs, $1)=no cat <<_LT_EOF 1>&2 *** Warning: the GNU linker, at least up to release 2.19, is reported *** to be unable to reliably create shared libraries on AIX. *** Therefore, libtool is disabling shared libraries support. If you *** really care for shared libraries, you may want to install binutils *** 2.20 or above, or modify your PATH so that a non-GNU linker is found. *** You will then need to restart the configuration process. _LT_EOF fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='' ;; m68k) _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes ;; esac ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(allow_undefined_flag, $1)=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; cygwin* | mingw* | pw32* | cegcc*) # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, # as there is no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file (1st line # is EXPORTS), use it as is; otherwise, prepend... _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; haiku*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(link_all_deplibs, $1)=yes ;; interix[[3-9]]*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) tmp_diet=no if test "$host_os" = linux-dietlibc; then case $cc_basename in diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) esac fi if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ && test "$tmp_diet" = no then tmp_addflag=' $pic_flag' tmp_sharedflag='-shared' case $cc_basename,$host_cpu in pgcc*) # Portland Group C compiler _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' tmp_addflag=' $pic_flag' ;; pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group f77 and f90 compilers _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' tmp_addflag=' $pic_flag -Mnomain' ;; ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 tmp_addflag=' -i_dynamic' ;; efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 tmp_addflag=' -i_dynamic -nofor_main' ;; ifc* | ifort*) # Intel Fortran compiler tmp_addflag=' -nofor_main' ;; lf95*) # Lahey Fortran 8.1 _LT_TAGVAR(whole_archive_flag_spec, $1)= tmp_sharedflag='--shared' ;; xl[[cC]]* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below) tmp_sharedflag='-qmkshrobj' tmp_addflag= ;; nvcc*) # Cuda Compiler Driver 2.2 _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' _LT_TAGVAR(compiler_needs_object, $1)=yes ;; esac case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C 5.9 _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' _LT_TAGVAR(compiler_needs_object, $1)=yes tmp_sharedflag='-G' ;; *Sun\ F*) # Sun Fortran 8.3 tmp_sharedflag='-G' ;; esac _LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' if test "x$supports_anon_versioning" = xyes; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' fi case $cc_basename in xlf* | bgf* | bgxlf* | mpixlf*) # IBM XL Fortran 10.1 on PPC cannot create shared libs itself _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' if test "x$supports_anon_versioning" = xyes; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' fi ;; esac else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' wlarc= else _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' fi ;; solaris*) if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then _LT_TAGVAR(ld_shlibs, $1)=no cat <<_LT_EOF 1>&2 *** Warning: The releases 2.8.* of the GNU linker cannot reliably *** create shared libraries on Solaris systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.9.1 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) case `$LD -v 2>&1` in *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*) _LT_TAGVAR(ld_shlibs, $1)=no cat <<_LT_EOF 1>&2 *** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not *** reliably create shared libraries on SCO systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.16.91.0.3 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF ;; *) # For security reasons, it is highly recommended that you always # use absolute paths for naming shared libraries, and exclude the # DT_RUNPATH tag from executables and libraries. But doing so # requires that you compile everything twice, which is a pain. if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; sunos4*) _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' wlarc= _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac if test "$_LT_TAGVAR(ld_shlibs, $1)" = no; then runpath_var= _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= fi else # PORTME fill in a description of your system's linker (not GNU ld) case $host_os in aix3*) _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=yes _LT_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' # Note: this linker hardcodes the directories in LIBPATH if there # are no directories specified by -L. _LT_TAGVAR(hardcode_minus_L, $1)=yes if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then # Neither direct hardcoding nor static linking is supported with a # broken collect2. _LT_TAGVAR(hardcode_direct, $1)=unsupported fi ;; aix[[4-9]]*) if test "$host_cpu" = ia64; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag="" else # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to AIX nm, but means don't demangle with GNU nm # Also, AIX nm treats weak defined symbols like other global # defined symbols, whereas GNU nm marks them as "W". if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' else _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' fi aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # need to do runtime linking. case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) for ld_flag in $LDFLAGS; do if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then aix_use_runtimelinking=yes break fi done ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. _LT_TAGVAR(archive_cmds, $1)='' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(file_list_spec, $1)='${wl}-f,' if test "$GCC" = yes; then case $host_os in aix4.[[012]]|aix4.[[012]].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`${CC} -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then # We have reworked collect2 : else # We have old collect2 _LT_TAGVAR(hardcode_direct, $1)=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)= fi ;; esac shared_flag='-shared' if test "$aix_use_runtimelinking" = yes; then shared_flag="$shared_flag "'${wl}-G' fi _LT_TAGVAR(link_all_deplibs, $1)=no else # not using gcc if test "$host_cpu" = ia64; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test "$aix_use_runtimelinking" = yes; then shared_flag='${wl}-G' else shared_flag='${wl}-bM:SRE' fi fi fi _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to export. _LT_TAGVAR(always_export_symbols, $1)=yes if test "$aix_use_runtimelinking" = yes; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. _LT_TAGVAR(allow_undefined_flag, $1)='-berok' # Determine the default libpath from the value encoded in an # empty executable. _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" else if test "$host_cpu" = ia64; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' if test "$with_gnu_ld" = yes; then # We only use this code for GNU lds that support --whole-archive. _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' else # Exported symbols can be pulled into shared objects from archives _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' fi _LT_TAGVAR(archive_cmds_need_lc, $1)=yes # This is similar to how AIX traditionally builds its shared libraries. _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' fi fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='' ;; m68k) _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes ;; esac ;; bsdi[[45]]*) _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic ;; cygwin* | mingw* | pw32* | cegcc*) # When not using gcc, we currently assume that we are using # Microsoft Visual C++. # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. case $cc_basename in cl*) # Native MSVC _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=yes _LT_TAGVAR(file_list_spec, $1)='@' # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=".dll" # FIXME: Setting linknames here is a bad hack. _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; else sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; fi~ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1,DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols' # Don't use ranlib _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ lt_tool_outputfile="@TOOL_OUTPUT@"~ case $lt_outputfile in *.exe|*.EXE) ;; *) lt_outputfile="$lt_outputfile.exe" lt_tool_outputfile="$lt_tool_outputfile.exe" ;; esac~ if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; $RM "$lt_outputfile.manifest"; fi' ;; *) # Assume MSVC wrapper _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=".dll" # FIXME: Setting linknames here is a bad hack. _LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' # The linker will automatically build a .lib file if we build a DLL. _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' # FIXME: Should let the user specify the lib program. _LT_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes ;; esac ;; darwin* | rhapsody*) _LT_DARWIN_LINKER_FEATURES($1) ;; dgux*) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor # support. Future versions do this automatically, but an explicit c++rt0.o # does not break anything, and helps significantly (at the cost of a little # extra space). freebsd2.2*) _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; # Unfortunately, older versions of FreeBSD 2 do not have this feature. freebsd2.*) _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; # FreeBSD 3 and greater uses gcc -shared to do shared libraries. freebsd* | dragonfly*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; hpux9*) if test "$GCC" = yes; then _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' else _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_direct, $1)=yes # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' ;; hpux10*) if test "$GCC" = yes && test "$with_gnu_ld" = no; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' fi if test "$with_gnu_ld" = no; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. _LT_TAGVAR(hardcode_minus_L, $1)=yes fi ;; hpux11*) if test "$GCC" = yes && test "$with_gnu_ld" = no; then case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ;; esac else case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) m4_if($1, [], [ # Older versions of the 11.00 compiler do not understand -b yet # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) _LT_LINKER_OPTION([if $CC understands -b], _LT_TAGVAR(lt_cv_prog_compiler__b, $1), [-b], [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'], [_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'])], [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags']) ;; esac fi if test "$with_gnu_ld" = no; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: case $host_cpu in hppa*64*|ia64*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. _LT_TAGVAR(hardcode_minus_L, $1)=yes ;; esac fi ;; irix5* | irix6* | nonstopux*) if test "$GCC" = yes; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' # Try to use the -exported_symbol ld option, if it does not # work, assume that -exports_file does not work either and # implicitly export all symbols. # This should be the same for all languages, so no per-tag cache variable. AC_CACHE_CHECK([whether the $host_os linker accepts -exported_symbol], [lt_cv_irix_exported_symbol], [save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null" AC_LINK_IFELSE( [AC_LANG_SOURCE( [AC_LANG_CASE([C], [[int foo (void) { return 0; }]], [C++], [[int foo (void) { return 0; }]], [Fortran 77], [[ subroutine foo end]], [Fortran], [[ subroutine foo end]])])], [lt_cv_irix_exported_symbol=yes], [lt_cv_irix_exported_symbol=no]) LDFLAGS="$save_LDFLAGS"]) if test "$lt_cv_irix_exported_symbol" = yes; then _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' fi else _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib' fi _LT_TAGVAR(archive_cmds_need_lc, $1)='no' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(inherit_rpath, $1)=yes _LT_TAGVAR(link_all_deplibs, $1)=yes ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out else _LT_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; newsos6) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *nto* | *qnx*) ;; openbsd*) if test -f /usr/libexec/ld.so; then _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=yes if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' else case $host_os in openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*) _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' ;; esac fi else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; os2*) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' _LT_TAGVAR(old_archive_from_new_cmds, $1)='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' ;; osf3*) if test "$GCC" = yes; then _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' else _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' fi _LT_TAGVAR(archive_cmds_need_lc, $1)='no' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: ;; osf4* | osf5*) # as osf3* with the addition of -msym flag if test "$GCC" = yes; then _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' else _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp' # Both c and cxx compiler support -rpath directly _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' fi _LT_TAGVAR(archive_cmds_need_lc, $1)='no' _LT_TAGVAR(hardcode_libdir_separator, $1)=: ;; solaris*) _LT_TAGVAR(no_undefined_flag, $1)=' -z defs' if test "$GCC" = yes; then wlarc='${wl}' _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' else case `$CC -V 2>&1` in *"Compilers 5.0"*) wlarc='' _LT_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' ;; *) wlarc='${wl}' _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' ;; esac fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no case $host_os in solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) # The compiler driver will combine and reorder linker options, # but understands `-z linker_flag'. GCC discards it without `$wl', # but is careful enough not to reorder. # Supported since Solaris 2.6 (maybe 2.5.1?) if test "$GCC" = yes; then _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' else _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' fi ;; esac _LT_TAGVAR(link_all_deplibs, $1)=yes ;; sunos4*) if test "x$host_vendor" = xsequent; then # Use $CC to link under sequent, because it throws in some extra .o # files that make .init and .fini sections work. _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; sysv4) case $host_vendor in sni) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=yes # is this really true??? ;; siemens) ## LD is ld it makes a PLAMLIB ## CC just makes a GrossModule. _LT_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs' _LT_TAGVAR(hardcode_direct, $1)=no ;; motorola) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie ;; esac runpath_var='LD_RUN_PATH' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; sysv4.3*) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport' ;; sysv4*MP*) if test -d /usr/nec; then _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no runpath_var=LD_RUN_PATH hardcode_runpath_var=yes _LT_TAGVAR(ld_shlibs, $1)=yes fi ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no runpath_var='LD_RUN_PATH' if test "$GCC" = yes; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We can NOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' runpath_var='LD_RUN_PATH' if test "$GCC" = yes; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; uts4*) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) _LT_TAGVAR(ld_shlibs, $1)=no ;; esac if test x$host_vendor = xsni; then case $host in sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Blargedynsym' ;; esac fi fi ]) AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no _LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld _LT_DECL([], [libext], [0], [Old archive suffix (normally "a")])dnl _LT_DECL([], [shrext_cmds], [1], [Shared library suffix (normally ".so")])dnl _LT_DECL([], [extract_expsyms_cmds], [2], [The commands to extract the exported symbol list from a shared archive]) # # Do we need to explicitly link libc? # case "x$_LT_TAGVAR(archive_cmds_need_lc, $1)" in x|xyes) # Assume -lc should be added _LT_TAGVAR(archive_cmds_need_lc, $1)=yes if test "$enable_shared" = yes && test "$GCC" = yes; then case $_LT_TAGVAR(archive_cmds, $1) in *'~'*) # FIXME: we may have to deal with multi-command sequences. ;; '$CC '*) # Test whether the compiler implicitly links with -lc since on some # systems, -lgcc has to come before -lc. If gcc already passes -lc # to ld, don't add -lc before -lgcc. AC_CACHE_CHECK([whether -lc should be explicitly linked in], [lt_cv_]_LT_TAGVAR(archive_cmds_need_lc, $1), [$RM conftest* echo "$lt_simple_compile_test_code" > conftest.$ac_ext if AC_TRY_EVAL(ac_compile) 2>conftest.err; then soname=conftest lib=conftest libobjs=conftest.$ac_objext deplibs= wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) pic_flag=$_LT_TAGVAR(lt_prog_compiler_pic, $1) compiler_flags=-v linker_flags=-v verstring= output_objdir=. libname=conftest lt_save_allow_undefined_flag=$_LT_TAGVAR(allow_undefined_flag, $1) _LT_TAGVAR(allow_undefined_flag, $1)= if AC_TRY_EVAL(_LT_TAGVAR(archive_cmds, $1) 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) then lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=no else lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=yes fi _LT_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag else cat conftest.err 1>&5 fi $RM conftest* ]) _LT_TAGVAR(archive_cmds_need_lc, $1)=$lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1) ;; esac fi ;; esac _LT_TAGDECL([build_libtool_need_lc], [archive_cmds_need_lc], [0], [Whether or not to add -lc for building shared libraries]) _LT_TAGDECL([allow_libtool_libs_with_static_runtimes], [enable_shared_with_static_runtimes], [0], [Whether or not to disallow shared libs when runtime libs are static]) _LT_TAGDECL([], [export_dynamic_flag_spec], [1], [Compiler flag to allow reflexive dlopens]) _LT_TAGDECL([], [whole_archive_flag_spec], [1], [Compiler flag to generate shared objects directly from archives]) _LT_TAGDECL([], [compiler_needs_object], [1], [Whether the compiler copes with passing no objects directly]) _LT_TAGDECL([], [old_archive_from_new_cmds], [2], [Create an old-style archive from a shared archive]) _LT_TAGDECL([], [old_archive_from_expsyms_cmds], [2], [Create a temporary old-style archive to link instead of a shared archive]) _LT_TAGDECL([], [archive_cmds], [2], [Commands used to build a shared archive]) _LT_TAGDECL([], [archive_expsym_cmds], [2]) _LT_TAGDECL([], [module_cmds], [2], [Commands used to build a loadable module if different from building a shared archive.]) _LT_TAGDECL([], [module_expsym_cmds], [2]) _LT_TAGDECL([], [with_gnu_ld], [1], [Whether we are building with GNU ld or not]) _LT_TAGDECL([], [allow_undefined_flag], [1], [Flag that allows shared libraries with undefined symbols to be built]) _LT_TAGDECL([], [no_undefined_flag], [1], [Flag that enforces no undefined symbols]) _LT_TAGDECL([], [hardcode_libdir_flag_spec], [1], [Flag to hardcode $libdir into a binary during linking. This must work even if $libdir does not exist]) _LT_TAGDECL([], [hardcode_libdir_separator], [1], [Whether we need a single "-rpath" flag with a separated argument]) _LT_TAGDECL([], [hardcode_direct], [0], [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the resulting binary]) _LT_TAGDECL([], [hardcode_direct_absolute], [0], [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the resulting binary and the resulting library dependency is "absolute", i.e impossible to change by setting ${shlibpath_var} if the library is relocated]) _LT_TAGDECL([], [hardcode_minus_L], [0], [Set to "yes" if using the -LDIR flag during linking hardcodes DIR into the resulting binary]) _LT_TAGDECL([], [hardcode_shlibpath_var], [0], [Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into the resulting binary]) _LT_TAGDECL([], [hardcode_automatic], [0], [Set to "yes" if building a shared library automatically hardcodes DIR into the library and all subsequent libraries and executables linked against it]) _LT_TAGDECL([], [inherit_rpath], [0], [Set to yes if linker adds runtime paths of dependent libraries to runtime path list]) _LT_TAGDECL([], [link_all_deplibs], [0], [Whether libtool must link a program against all its dependency libraries]) _LT_TAGDECL([], [always_export_symbols], [0], [Set to "yes" if exported symbols are required]) _LT_TAGDECL([], [export_symbols_cmds], [2], [The commands to list exported symbols]) _LT_TAGDECL([], [exclude_expsyms], [1], [Symbols that should not be listed in the preloaded symbols]) _LT_TAGDECL([], [include_expsyms], [1], [Symbols that must always be exported]) _LT_TAGDECL([], [prelink_cmds], [2], [Commands necessary for linking programs (against libraries) with templates]) _LT_TAGDECL([], [postlink_cmds], [2], [Commands necessary for finishing linking programs]) _LT_TAGDECL([], [file_list_spec], [1], [Specify filename containing input files]) dnl FIXME: Not yet implemented dnl _LT_TAGDECL([], [thread_safe_flag_spec], [1], dnl [Compiler flag to generate thread safe objects]) ])# _LT_LINKER_SHLIBS # _LT_LANG_C_CONFIG([TAG]) # ------------------------ # Ensure that the configuration variables for a C compiler are suitably # defined. These variables are subsequently used by _LT_CONFIG to write # the compiler configuration to `libtool'. m4_defun([_LT_LANG_C_CONFIG], [m4_require([_LT_DECL_EGREP])dnl lt_save_CC="$CC" AC_LANG_PUSH(C) # Source file extension for C test sources. ac_ext=c # Object file extension for compiled C test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests lt_simple_link_test_code='int main(){return(0);}' _LT_TAG_COMPILER # Save the default compiler, since it gets overwritten when the other # tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. compiler_DEFAULT=$CC # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... if test -n "$compiler"; then _LT_COMPILER_NO_RTTI($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) LT_SYS_DLOPEN_SELF _LT_CMD_STRIPLIB # Report which library types will actually be built AC_MSG_CHECKING([if libtool supports shared libraries]) AC_MSG_RESULT([$can_build_shared]) AC_MSG_CHECKING([whether to build shared libraries]) test "$can_build_shared" = "no" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test "$enable_shared" = yes && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[[4-9]]*) if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then test "$enable_shared" = yes && enable_static=no fi ;; esac AC_MSG_RESULT([$enable_shared]) AC_MSG_CHECKING([whether to build static libraries]) # Make sure either enable_shared or enable_static is yes. test "$enable_shared" = yes || enable_static=yes AC_MSG_RESULT([$enable_static]) _LT_CONFIG($1) fi AC_LANG_POP CC="$lt_save_CC" ])# _LT_LANG_C_CONFIG # _LT_LANG_CXX_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for a C++ compiler are suitably # defined. These variables are subsequently used by _LT_CONFIG to write # the compiler configuration to `libtool'. m4_defun([_LT_LANG_CXX_CONFIG], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_PATH_MANIFEST_TOOL])dnl if test -n "$CXX" && ( test "X$CXX" != "Xno" && ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || (test "X$CXX" != "Xg++"))) ; then AC_PROG_CXXCPP else _lt_caught_CXX_error=yes fi AC_LANG_PUSH(C++) _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(compiler_needs_object, $1)=no _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds _LT_TAGVAR(no_undefined_flag, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no # Source file extension for C++ test sources. ac_ext=cpp # Object file extension for compiled C++ test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # No sense in running all these tests if we already determined that # the CXX compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. if test "$_lt_caught_CXX_error" != yes; then # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }' # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_CFLAGS=$CFLAGS lt_save_LD=$LD lt_save_GCC=$GCC GCC=$GXX lt_save_with_gnu_ld=$with_gnu_ld lt_save_path_LD=$lt_cv_path_LD if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx else $as_unset lt_cv_prog_gnu_ld fi if test -n "${lt_cv_path_LDCXX+set}"; then lt_cv_path_LD=$lt_cv_path_LDCXX else $as_unset lt_cv_path_LD fi test -z "${LDCXX+set}" || LD=$LDCXX CC=${CXX-"c++"} CFLAGS=$CXXFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) if test -n "$compiler"; then # We don't want -fno-exception when compiling C++ code, so set the # no_builtin_flag separately if test "$GXX" = yes; then _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' else _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= fi if test "$GXX" = yes; then # Set up default GNU C++ configuration LT_PATH_LD # Check if GNU C++ uses GNU ld as the underlying linker, since the # archiving commands below assume that GNU ld is being used. if test "$with_gnu_ld" = yes; then _LT_TAGVAR(archive_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' # If archive_cmds runs LD, not CC, wlarc should be empty # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to # investigate it a little bit more. (MM) wlarc='${wl}' # ancient GNU ld didn't support --whole-archive et. al. if eval "`$CC -print-prog-name=ld` --help 2>&1" | $GREP 'no-whole-archive' > /dev/null; then _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' else _LT_TAGVAR(whole_archive_flag_spec, $1)= fi else with_gnu_ld=no wlarc= # A generic and very simple default shared library creation # command for GNU C++ for the case where it uses the native # linker, instead of GNU ld. If possible, this setting should # overridden to take advantage of the native linker features on # the platform it is being used on. _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' fi # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' else GXX=no with_gnu_ld=no wlarc= fi # PORTME: fill in a description of your system's C++ link characteristics AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) _LT_TAGVAR(ld_shlibs, $1)=yes case $host_os in aix3*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; aix[[4-9]]*) if test "$host_cpu" = ia64; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag="" else aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # need to do runtime linking. case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) for ld_flag in $LDFLAGS; do case $ld_flag in *-brtl*) aix_use_runtimelinking=yes break ;; esac done ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. _LT_TAGVAR(archive_cmds, $1)='' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(file_list_spec, $1)='${wl}-f,' if test "$GXX" = yes; then case $host_os in aix4.[[012]]|aix4.[[012]].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`${CC} -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then # We have reworked collect2 : else # We have old collect2 _LT_TAGVAR(hardcode_direct, $1)=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)= fi esac shared_flag='-shared' if test "$aix_use_runtimelinking" = yes; then shared_flag="$shared_flag "'${wl}-G' fi else # not using gcc if test "$host_cpu" = ia64; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test "$aix_use_runtimelinking" = yes; then shared_flag='${wl}-G' else shared_flag='${wl}-bM:SRE' fi fi fi _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to # export. _LT_TAGVAR(always_export_symbols, $1)=yes if test "$aix_use_runtimelinking" = yes; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. _LT_TAGVAR(allow_undefined_flag, $1)='-berok' # Determine the default libpath from the value encoded in an empty # executable. _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" else if test "$host_cpu" = ia64; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' if test "$with_gnu_ld" = yes; then # We only use this code for GNU lds that support --whole-archive. _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' else # Exported symbols can be pulled into shared objects from archives _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' fi _LT_TAGVAR(archive_cmds_need_lc, $1)=yes # This is similar to how AIX traditionally builds its shared # libraries. _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' fi fi ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(allow_undefined_flag, $1)=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; chorus*) case $cc_basename in *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; cygwin* | mingw* | pw32* | cegcc*) case $GXX,$cc_basename in ,cl* | no,cl*) # Native MSVC # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=yes _LT_TAGVAR(file_list_spec, $1)='@' # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=".dll" # FIXME: Setting linknames here is a bad hack. _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then $SED -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; else $SED -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; fi~ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes # Don't use ranlib _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ lt_tool_outputfile="@TOOL_OUTPUT@"~ case $lt_outputfile in *.exe|*.EXE) ;; *) lt_outputfile="$lt_outputfile.exe" lt_tool_outputfile="$lt_tool_outputfile.exe" ;; esac~ func_to_tool_file "$lt_outputfile"~ if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; $RM "$lt_outputfile.manifest"; fi' ;; *) # g++ # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, # as there is no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file (1st line # is EXPORTS), use it as is; otherwise, prepend... _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; darwin* | rhapsody*) _LT_DARWIN_LINKER_FEATURES($1) ;; dgux*) case $cc_basename in ec++*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; ghcx*) # Green Hills C++ Compiler # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; freebsd2.*) # C++ shared libraries reported to be fairly broken before # switch to ELF _LT_TAGVAR(ld_shlibs, $1)=no ;; freebsd-elf*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; freebsd* | dragonfly*) # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF # conventions _LT_TAGVAR(ld_shlibs, $1)=yes ;; gnu*) ;; haiku*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(link_all_deplibs, $1)=yes ;; hpux9*) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, # but as the default # location of the library. case $cc_basename in CC*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; aCC*) _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test "$GXX" = yes; then _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' else # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; hpux10*|hpux11*) if test $with_gnu_ld = no; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: case $host_cpu in hppa*64*|ia64*) ;; *) _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' ;; esac fi case $host_cpu in hppa*64*|ia64*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, # but as the default # location of the library. ;; esac case $cc_basename in CC*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; aCC*) case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; esac # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test "$GXX" = yes; then if test $with_gnu_ld = no; then case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; esac fi else # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; interix[[3-9]]*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; irix5* | irix6*) case $cc_basename in CC*) # SGI C++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' # Archives containing C++ object files must be created using # "CC -ar", where "CC" is the IRIX C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs' ;; *) if test "$GXX" = yes; then if test "$with_gnu_ld" = no; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' else _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` -o $lib' fi fi _LT_TAGVAR(link_all_deplibs, $1)=yes ;; esac _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(inherit_rpath, $1)=yes ;; linux* | k*bsd*-gnu | kopensolaris*-gnu) case $cc_basename in KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' # Archives containing C++ object files must be created using # "CC -Bstatic", where "CC" is the KAI C++ compiler. _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;; icpc* | ecpc* ) # Intel C++ with_gnu_ld=yes # version 8.0 and above of icpc choke on multiply defined symbols # if we add $predep_objects and $postdep_objects, however 7.1 and # earlier do not add the objects themselves. case `$CC -V 2>&1` in *"Version 7."*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' ;; *) # Version 8.0 or newer tmp_idyn= case $host_cpu in ia64*) tmp_idyn=' -i_dynamic';; esac _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' ;; esac _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' ;; pgCC* | pgcpp*) # Portland Group C++ compiler case `$CC -V` in *pgCC\ [[1-5]].* | *pgcpp\ [[1-5]].*) _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"' _LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~ $RANLIB $oldlib' _LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' ;; *) # Version 6 and above use weak symbols _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' ;; esac _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' ;; cxx*) # Compaq C++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols' runpath_var=LD_RUN_PATH _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed' ;; xl* | mpixl* | bgxl*) # IBM XL 8.0 on PPC, with GNU ld _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' if test "x$supports_anon_versioning" = xyes; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' fi ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C++ 5.9 _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' _LT_TAGVAR(compiler_needs_object, $1)=yes # Not sure whether something based on # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 # would be better. output_verbose_link_cmd='func_echo_all' # Archives containing C++ object files must be created using # "CC -xar", where "CC" is the Sun C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' ;; esac ;; esac ;; lynxos*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; m88k*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; mvs*) case $cc_basename in cxx*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' wlarc= _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no fi # Workaround some broken pre-1.5 toolchains output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' ;; *nto* | *qnx*) _LT_TAGVAR(ld_shlibs, $1)=yes ;; openbsd2*) # C++ shared libraries are fairly broken _LT_TAGVAR(ld_shlibs, $1)=no ;; openbsd*) if test -f /usr/libexec/ld.so; then _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' fi output_verbose_link_cmd=func_echo_all else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; osf3* | osf4* | osf5*) case $cc_basename in KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Archives containing C++ object files must be created using # the KAI C++ compiler. case $host in osf3*) _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;; *) _LT_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' ;; esac ;; RCC*) # Rational C++ 2.4.1 # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; cxx*) case $host in osf3*) _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && func_echo_all "${wl}-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' ;; *) _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ echo "-hidden">> $lib.exp~ $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~ $RM $lib.exp' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' ;; esac _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test "$GXX" = yes && test "$with_gnu_ld" = no; then _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' case $host in osf3*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ;; esac _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' else # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; psos*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; sunos4*) case $cc_basename in CC*) # Sun C++ 4.x # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; lcc*) # Lucid # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; solaris*) case $cc_basename in CC* | sunCC*) # Sun C++ 4.2, 5.x and Centerline C++ _LT_TAGVAR(archive_cmds_need_lc,$1)=yes _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no case $host_os in solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) # The compiler driver will combine and reorder linker options, # but understands `-z linker_flag'. # Supported since Solaris 2.6 (maybe 2.5.1?) _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' ;; esac _LT_TAGVAR(link_all_deplibs, $1)=yes output_verbose_link_cmd='func_echo_all' # Archives containing C++ object files must be created using # "CC -xar", where "CC" is the Sun C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' ;; gcx*) # Green Hills C++ Compiler _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' # The C++ compiler must be used to create the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs' ;; *) # GNU C++ compiler with Solaris linker if test "$GXX" = yes && test "$with_gnu_ld" = no; then _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-z ${wl}defs' if $CC --version | $GREP -v '^2\.7' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -shared $pic_flag -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' else # g++ 2.7 appears to require `-G' NOT `-shared' on this # platform. _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $wl$libdir' case $host_os in solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' ;; esac fi ;; esac ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no runpath_var='LD_RUN_PATH' case $cc_basename in CC*) _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We can NOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' runpath_var='LD_RUN_PATH' case $cc_basename in CC*) _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(old_archive_cmds, $1)='$CC -Tprelink_objects $oldobjs~ '"$_LT_TAGVAR(old_archive_cmds, $1)" _LT_TAGVAR(reload_cmds, $1)='$CC -Tprelink_objects $reload_objs~ '"$_LT_TAGVAR(reload_cmds, $1)" ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; tandem*) case $cc_basename in NCC*) # NonStop-UX NCC 3.20 # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; vxworks*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no _LT_TAGVAR(GCC, $1)="$GXX" _LT_TAGVAR(LD, $1)="$LD" ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... _LT_SYS_HIDDEN_LIBDEPS($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi # test -n "$compiler" CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS LDCXX=$LD LD=$lt_save_LD GCC=$lt_save_GCC with_gnu_ld=$lt_save_with_gnu_ld lt_cv_path_LDCXX=$lt_cv_path_LD lt_cv_path_LD=$lt_save_path_LD lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld fi # test "$_lt_caught_CXX_error" != yes AC_LANG_POP ])# _LT_LANG_CXX_CONFIG # _LT_FUNC_STRIPNAME_CNF # ---------------------- # func_stripname_cnf prefix suffix name # strip PREFIX and SUFFIX off of NAME. # PREFIX and SUFFIX must not contain globbing or regex special # characters, hashes, percent signs, but SUFFIX may contain a leading # dot (in which case that matches only a dot). # # This function is identical to the (non-XSI) version of func_stripname, # except this one can be used by m4 code that may be executed by configure, # rather than the libtool script. m4_defun([_LT_FUNC_STRIPNAME_CNF],[dnl AC_REQUIRE([_LT_DECL_SED]) AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH]) func_stripname_cnf () { case ${2} in .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;; *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;; esac } # func_stripname_cnf ])# _LT_FUNC_STRIPNAME_CNF # _LT_SYS_HIDDEN_LIBDEPS([TAGNAME]) # --------------------------------- # Figure out "hidden" library dependencies from verbose # compiler output when linking a shared library. # Parse the compiler output and extract the necessary # objects, libraries and library flags. m4_defun([_LT_SYS_HIDDEN_LIBDEPS], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl AC_REQUIRE([_LT_FUNC_STRIPNAME_CNF])dnl # Dependencies to place before and after the object being linked: _LT_TAGVAR(predep_objects, $1)= _LT_TAGVAR(postdep_objects, $1)= _LT_TAGVAR(predeps, $1)= _LT_TAGVAR(postdeps, $1)= _LT_TAGVAR(compiler_lib_search_path, $1)= dnl we can't use the lt_simple_compile_test_code here, dnl because it contains code intended for an executable, dnl not a library. It's possible we should let each dnl tag define a new lt_????_link_test_code variable, dnl but it's only used here... m4_if([$1], [], [cat > conftest.$ac_ext <<_LT_EOF int a; void foo (void) { a = 0; } _LT_EOF ], [$1], [CXX], [cat > conftest.$ac_ext <<_LT_EOF class Foo { public: Foo (void) { a = 0; } private: int a; }; _LT_EOF ], [$1], [F77], [cat > conftest.$ac_ext <<_LT_EOF subroutine foo implicit none integer*4 a a=0 return end _LT_EOF ], [$1], [FC], [cat > conftest.$ac_ext <<_LT_EOF subroutine foo implicit none integer a a=0 return end _LT_EOF ], [$1], [GCJ], [cat > conftest.$ac_ext <<_LT_EOF public class foo { private int a; public void bar (void) { a = 0; } }; _LT_EOF ], [$1], [GO], [cat > conftest.$ac_ext <<_LT_EOF package foo func foo() { } _LT_EOF ]) _lt_libdeps_save_CFLAGS=$CFLAGS case "$CC $CFLAGS " in #( *\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;; *\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;; *\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;; esac dnl Parse the compiler output and extract the necessary dnl objects, libraries and library flags. if AC_TRY_EVAL(ac_compile); then # Parse the compiler output and extract the necessary # objects, libraries and library flags. # Sentinel used to keep track of whether or not we are before # the conftest object file. pre_test_object_deps_done=no for p in `eval "$output_verbose_link_cmd"`; do case ${prev}${p} in -L* | -R* | -l*) # Some compilers place space between "-{L,R}" and the path. # Remove the space. if test $p = "-L" || test $p = "-R"; then prev=$p continue fi # Expand the sysroot to ease extracting the directories later. if test -z "$prev"; then case $p in -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;; -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;; -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;; esac fi case $p in =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;; esac if test "$pre_test_object_deps_done" = no; then case ${prev} in -L | -R) # Internal compiler library paths should come after those # provided the user. The postdeps already come after the # user supplied libs so there is no need to process them. if test -z "$_LT_TAGVAR(compiler_lib_search_path, $1)"; then _LT_TAGVAR(compiler_lib_search_path, $1)="${prev}${p}" else _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} ${prev}${p}" fi ;; # The "-l" case would never come before the object being # linked, so don't bother handling this case. esac else if test -z "$_LT_TAGVAR(postdeps, $1)"; then _LT_TAGVAR(postdeps, $1)="${prev}${p}" else _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} ${prev}${p}" fi fi prev= ;; *.lto.$objext) ;; # Ignore GCC LTO objects *.$objext) # This assumes that the test object file only shows up # once in the compiler output. if test "$p" = "conftest.$objext"; then pre_test_object_deps_done=yes continue fi if test "$pre_test_object_deps_done" = no; then if test -z "$_LT_TAGVAR(predep_objects, $1)"; then _LT_TAGVAR(predep_objects, $1)="$p" else _LT_TAGVAR(predep_objects, $1)="$_LT_TAGVAR(predep_objects, $1) $p" fi else if test -z "$_LT_TAGVAR(postdep_objects, $1)"; then _LT_TAGVAR(postdep_objects, $1)="$p" else _LT_TAGVAR(postdep_objects, $1)="$_LT_TAGVAR(postdep_objects, $1) $p" fi fi ;; *) ;; # Ignore the rest. esac done # Clean up. rm -f a.out a.exe else echo "libtool.m4: error: problem compiling $1 test program" fi $RM -f confest.$objext CFLAGS=$_lt_libdeps_save_CFLAGS # PORTME: override above test on systems where it is broken m4_if([$1], [CXX], [case $host_os in interix[[3-9]]*) # Interix 3.5 installs completely hosed .la files for C++, so rather than # hack all around it, let's just trust "g++" to DTRT. _LT_TAGVAR(predep_objects,$1)= _LT_TAGVAR(postdep_objects,$1)= _LT_TAGVAR(postdeps,$1)= ;; linux*) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C++ 5.9 # The more standards-conforming stlport4 library is # incompatible with the Cstd library. Avoid specifying # it if it's in CXXFLAGS. Ignore libCrun as # -library=stlport4 depends on it. case " $CXX $CXXFLAGS " in *" -library=stlport4 "*) solaris_use_stlport4=yes ;; esac if test "$solaris_use_stlport4" != yes; then _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun' fi ;; esac ;; solaris*) case $cc_basename in CC* | sunCC*) # The more standards-conforming stlport4 library is # incompatible with the Cstd library. Avoid specifying # it if it's in CXXFLAGS. Ignore libCrun as # -library=stlport4 depends on it. case " $CXX $CXXFLAGS " in *" -library=stlport4 "*) solaris_use_stlport4=yes ;; esac # Adding this requires a known-good setup of shared libraries for # Sun compiler versions before 5.6, else PIC objects from an old # archive will be linked into the output, leading to subtle bugs. if test "$solaris_use_stlport4" != yes; then _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun' fi ;; esac ;; esac ]) case " $_LT_TAGVAR(postdeps, $1) " in *" -lc "*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; esac _LT_TAGVAR(compiler_lib_search_dirs, $1)= if test -n "${_LT_TAGVAR(compiler_lib_search_path, $1)}"; then _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | ${SED} -e 's! -L! !g' -e 's!^ !!'` fi _LT_TAGDECL([], [compiler_lib_search_dirs], [1], [The directories searched by this compiler when creating a shared library]) _LT_TAGDECL([], [predep_objects], [1], [Dependencies to place before and after the objects being linked to create a shared library]) _LT_TAGDECL([], [postdep_objects], [1]) _LT_TAGDECL([], [predeps], [1]) _LT_TAGDECL([], [postdeps], [1]) _LT_TAGDECL([], [compiler_lib_search_path], [1], [The library search path used internally by the compiler when linking a shared library]) ])# _LT_SYS_HIDDEN_LIBDEPS # _LT_LANG_F77_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for a Fortran 77 compiler are # suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to `libtool'. m4_defun([_LT_LANG_F77_CONFIG], [AC_LANG_PUSH(Fortran 77) if test -z "$F77" || test "X$F77" = "Xno"; then _lt_disable_F77=yes fi _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds _LT_TAGVAR(no_undefined_flag, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no # Source file extension for f77 test sources. ac_ext=f # Object file extension for compiled f77 test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # No sense in running all these tests if we already determined that # the F77 compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. if test "$_lt_disable_F77" != yes; then # Code to be used in simple compile tests lt_simple_compile_test_code="\ subroutine t return end " # Code to be used in simple link tests lt_simple_link_test_code="\ program t end " # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC="$CC" lt_save_GCC=$GCC lt_save_CFLAGS=$CFLAGS CC=${F77-"f77"} CFLAGS=$FFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) GCC=$G77 if test -n "$compiler"; then AC_MSG_CHECKING([if libtool supports shared libraries]) AC_MSG_RESULT([$can_build_shared]) AC_MSG_CHECKING([whether to build shared libraries]) test "$can_build_shared" = "no" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test "$enable_shared" = yes && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[[4-9]]*) if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then test "$enable_shared" = yes && enable_static=no fi ;; esac AC_MSG_RESULT([$enable_shared]) AC_MSG_CHECKING([whether to build static libraries]) # Make sure either enable_shared or enable_static is yes. test "$enable_shared" = yes || enable_static=yes AC_MSG_RESULT([$enable_static]) _LT_TAGVAR(GCC, $1)="$G77" _LT_TAGVAR(LD, $1)="$LD" ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi # test -n "$compiler" GCC=$lt_save_GCC CC="$lt_save_CC" CFLAGS="$lt_save_CFLAGS" fi # test "$_lt_disable_F77" != yes AC_LANG_POP ])# _LT_LANG_F77_CONFIG # _LT_LANG_FC_CONFIG([TAG]) # ------------------------- # Ensure that the configuration variables for a Fortran compiler are # suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to `libtool'. m4_defun([_LT_LANG_FC_CONFIG], [AC_LANG_PUSH(Fortran) if test -z "$FC" || test "X$FC" = "Xno"; then _lt_disable_FC=yes fi _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds _LT_TAGVAR(no_undefined_flag, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no # Source file extension for fc test sources. ac_ext=${ac_fc_srcext-f} # Object file extension for compiled fc test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # No sense in running all these tests if we already determined that # the FC compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. if test "$_lt_disable_FC" != yes; then # Code to be used in simple compile tests lt_simple_compile_test_code="\ subroutine t return end " # Code to be used in simple link tests lt_simple_link_test_code="\ program t end " # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC="$CC" lt_save_GCC=$GCC lt_save_CFLAGS=$CFLAGS CC=${FC-"f95"} CFLAGS=$FCFLAGS compiler=$CC GCC=$ac_cv_fc_compiler_gnu _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) if test -n "$compiler"; then AC_MSG_CHECKING([if libtool supports shared libraries]) AC_MSG_RESULT([$can_build_shared]) AC_MSG_CHECKING([whether to build shared libraries]) test "$can_build_shared" = "no" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test "$enable_shared" = yes && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[[4-9]]*) if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then test "$enable_shared" = yes && enable_static=no fi ;; esac AC_MSG_RESULT([$enable_shared]) AC_MSG_CHECKING([whether to build static libraries]) # Make sure either enable_shared or enable_static is yes. test "$enable_shared" = yes || enable_static=yes AC_MSG_RESULT([$enable_static]) _LT_TAGVAR(GCC, $1)="$ac_cv_fc_compiler_gnu" _LT_TAGVAR(LD, $1)="$LD" ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... _LT_SYS_HIDDEN_LIBDEPS($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi # test -n "$compiler" GCC=$lt_save_GCC CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS fi # test "$_lt_disable_FC" != yes AC_LANG_POP ])# _LT_LANG_FC_CONFIG # _LT_LANG_GCJ_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for the GNU Java Compiler compiler # are suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to `libtool'. m4_defun([_LT_LANG_GCJ_CONFIG], [AC_REQUIRE([LT_PROG_GCJ])dnl AC_LANG_SAVE # Source file extension for Java test sources. ac_ext=java # Object file extension for compiled Java test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="class foo {}" # Code to be used in simple link tests lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }' # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_CFLAGS=$CFLAGS lt_save_GCC=$GCC GCC=yes CC=${GCJ-"gcj"} CFLAGS=$GCJFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_TAGVAR(LD, $1)="$LD" _LT_CC_BASENAME([$compiler]) # GCJ did not exist at the time GCC didn't implicitly link libc in. _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... if test -n "$compiler"; then _LT_COMPILER_NO_RTTI($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi AC_LANG_RESTORE GCC=$lt_save_GCC CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS ])# _LT_LANG_GCJ_CONFIG # _LT_LANG_GO_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for the GNU Go compiler # are suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to `libtool'. m4_defun([_LT_LANG_GO_CONFIG], [AC_REQUIRE([LT_PROG_GO])dnl AC_LANG_SAVE # Source file extension for Go test sources. ac_ext=go # Object file extension for compiled Go test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="package main; func main() { }" # Code to be used in simple link tests lt_simple_link_test_code='package main; func main() { }' # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_CFLAGS=$CFLAGS lt_save_GCC=$GCC GCC=yes CC=${GOC-"gccgo"} CFLAGS=$GOFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_TAGVAR(LD, $1)="$LD" _LT_CC_BASENAME([$compiler]) # Go did not exist at the time GCC didn't implicitly link libc in. _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... if test -n "$compiler"; then _LT_COMPILER_NO_RTTI($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi AC_LANG_RESTORE GCC=$lt_save_GCC CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS ])# _LT_LANG_GO_CONFIG # _LT_LANG_RC_CONFIG([TAG]) # ------------------------- # Ensure that the configuration variables for the Windows resource compiler # are suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to `libtool'. m4_defun([_LT_LANG_RC_CONFIG], [AC_REQUIRE([LT_PROG_RC])dnl AC_LANG_SAVE # Source file extension for RC test sources. ac_ext=rc # Object file extension for compiled RC test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }' # Code to be used in simple link tests lt_simple_link_test_code="$lt_simple_compile_test_code" # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC="$CC" lt_save_CFLAGS=$CFLAGS lt_save_GCC=$GCC GCC= CC=${RC-"windres"} CFLAGS= compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes if test -n "$compiler"; then : _LT_CONFIG($1) fi GCC=$lt_save_GCC AC_LANG_RESTORE CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS ])# _LT_LANG_RC_CONFIG # LT_PROG_GCJ # ----------- AC_DEFUN([LT_PROG_GCJ], [m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ], [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ], [AC_CHECK_TOOL(GCJ, gcj,) test "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -O2" AC_SUBST(GCJFLAGS)])])[]dnl ]) # Old name: AU_ALIAS([LT_AC_PROG_GCJ], [LT_PROG_GCJ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([LT_AC_PROG_GCJ], []) # LT_PROG_GO # ---------- AC_DEFUN([LT_PROG_GO], [AC_CHECK_TOOL(GOC, gccgo,) ]) # LT_PROG_RC # ---------- AC_DEFUN([LT_PROG_RC], [AC_CHECK_TOOL(RC, windres,) ]) # Old name: AU_ALIAS([LT_AC_PROG_RC], [LT_PROG_RC]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([LT_AC_PROG_RC], []) # _LT_DECL_EGREP # -------------- # If we don't have a new enough Autoconf to choose the best grep # available, choose the one first in the user's PATH. m4_defun([_LT_DECL_EGREP], [AC_REQUIRE([AC_PROG_EGREP])dnl AC_REQUIRE([AC_PROG_FGREP])dnl test -z "$GREP" && GREP=grep _LT_DECL([], [GREP], [1], [A grep program that handles long lines]) _LT_DECL([], [EGREP], [1], [An ERE matcher]) _LT_DECL([], [FGREP], [1], [A literal string matcher]) dnl Non-bleeding-edge autoconf doesn't subst GREP, so do it here too AC_SUBST([GREP]) ]) # _LT_DECL_OBJDUMP # -------------- # If we don't have a new enough Autoconf to choose the best objdump # available, choose the one first in the user's PATH. m4_defun([_LT_DECL_OBJDUMP], [AC_CHECK_TOOL(OBJDUMP, objdump, false) test -z "$OBJDUMP" && OBJDUMP=objdump _LT_DECL([], [OBJDUMP], [1], [An object symbol dumper]) AC_SUBST([OBJDUMP]) ]) # _LT_DECL_DLLTOOL # ---------------- # Ensure DLLTOOL variable is set. m4_defun([_LT_DECL_DLLTOOL], [AC_CHECK_TOOL(DLLTOOL, dlltool, false) test -z "$DLLTOOL" && DLLTOOL=dlltool _LT_DECL([], [DLLTOOL], [1], [DLL creation program]) AC_SUBST([DLLTOOL]) ]) # _LT_DECL_SED # ------------ # Check for a fully-functional sed program, that truncates # as few characters as possible. Prefer GNU sed if found. m4_defun([_LT_DECL_SED], [AC_PROG_SED test -z "$SED" && SED=sed Xsed="$SED -e 1s/^X//" _LT_DECL([], [SED], [1], [A sed program that does not truncate output]) _LT_DECL([], [Xsed], ["\$SED -e 1s/^X//"], [Sed that helps us avoid accidentally triggering echo(1) options like -n]) ])# _LT_DECL_SED m4_ifndef([AC_PROG_SED], [ ############################################################ # NOTE: This macro has been submitted for inclusion into # # GNU Autoconf as AC_PROG_SED. When it is available in # # a released version of Autoconf we should remove this # # macro and use it instead. # ############################################################ m4_defun([AC_PROG_SED], [AC_MSG_CHECKING([for a sed that does not truncate output]) AC_CACHE_VAL(lt_cv_path_SED, [# Loop through the user's path and test for sed and gsed. # Then use that list of sed's as ones to test for truncation. as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for lt_ac_prog in sed gsed; do for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext" fi done done done IFS=$as_save_IFS lt_ac_max=0 lt_ac_count=0 # Add /usr/xpg4/bin/sed as it is typically found on Solaris # along with /bin/sed that truncates output. for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do test ! -f $lt_ac_sed && continue cat /dev/null > conftest.in lt_ac_count=0 echo $ECHO_N "0123456789$ECHO_C" >conftest.in # Check for GNU sed and select it if it is found. if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then lt_cv_path_SED=$lt_ac_sed break fi while true; do cat conftest.in conftest.in >conftest.tmp mv conftest.tmp conftest.in cp conftest.in conftest.nl echo >>conftest.nl $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break cmp -s conftest.out conftest.nl || break # 10000 chars as input seems more than enough test $lt_ac_count -gt 10 && break lt_ac_count=`expr $lt_ac_count + 1` if test $lt_ac_count -gt $lt_ac_max; then lt_ac_max=$lt_ac_count lt_cv_path_SED=$lt_ac_sed fi done done ]) SED=$lt_cv_path_SED AC_SUBST([SED]) AC_MSG_RESULT([$SED]) ])#AC_PROG_SED ])#m4_ifndef # Old name: AU_ALIAS([LT_AC_PROG_SED], [AC_PROG_SED]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([LT_AC_PROG_SED], []) # _LT_CHECK_SHELL_FEATURES # ------------------------ # Find out whether the shell is Bourne or XSI compatible, # or has some other useful features. m4_defun([_LT_CHECK_SHELL_FEATURES], [AC_MSG_CHECKING([whether the shell understands some XSI constructs]) # Try some XSI features xsi_shell=no ( _lt_dummy="a/b/c" test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \ = c,a/b,b/c, \ && eval 'test $(( 1 + 1 )) -eq 2 \ && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \ && xsi_shell=yes AC_MSG_RESULT([$xsi_shell]) _LT_CONFIG_LIBTOOL_INIT([xsi_shell='$xsi_shell']) AC_MSG_CHECKING([whether the shell understands "+="]) lt_shell_append=no ( foo=bar; set foo baz; eval "$[1]+=\$[2]" && test "$foo" = barbaz ) \ >/dev/null 2>&1 \ && lt_shell_append=yes AC_MSG_RESULT([$lt_shell_append]) _LT_CONFIG_LIBTOOL_INIT([lt_shell_append='$lt_shell_append']) if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then lt_unset=unset else lt_unset=false fi _LT_DECL([], [lt_unset], [0], [whether the shell understands "unset"])dnl # test EBCDIC or ASCII case `echo X|tr X '\101'` in A) # ASCII based system # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr lt_SP2NL='tr \040 \012' lt_NL2SP='tr \015\012 \040\040' ;; *) # EBCDIC based system lt_SP2NL='tr \100 \n' lt_NL2SP='tr \r\n \100\100' ;; esac _LT_DECL([SP2NL], [lt_SP2NL], [1], [turn spaces into newlines])dnl _LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl ])# _LT_CHECK_SHELL_FEATURES # _LT_PROG_FUNCTION_REPLACE (FUNCNAME, REPLACEMENT-BODY) # ------------------------------------------------------ # In `$cfgfile', look for function FUNCNAME delimited by `^FUNCNAME ()$' and # '^} FUNCNAME ', and replace its body with REPLACEMENT-BODY. m4_defun([_LT_PROG_FUNCTION_REPLACE], [dnl { sed -e '/^$1 ()$/,/^} # $1 /c\ $1 ()\ {\ m4_bpatsubsts([$2], [$], [\\], [^\([ ]\)], [\\\1]) } # Extended-shell $1 implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: ]) # _LT_PROG_REPLACE_SHELLFNS # ------------------------- # Replace existing portable implementations of several shell functions with # equivalent extended shell implementations where those features are available.. m4_defun([_LT_PROG_REPLACE_SHELLFNS], [if test x"$xsi_shell" = xyes; then _LT_PROG_FUNCTION_REPLACE([func_dirname], [dnl case ${1} in */*) func_dirname_result="${1%/*}${2}" ;; * ) func_dirname_result="${3}" ;; esac]) _LT_PROG_FUNCTION_REPLACE([func_basename], [dnl func_basename_result="${1##*/}"]) _LT_PROG_FUNCTION_REPLACE([func_dirname_and_basename], [dnl case ${1} in */*) func_dirname_result="${1%/*}${2}" ;; * ) func_dirname_result="${3}" ;; esac func_basename_result="${1##*/}"]) _LT_PROG_FUNCTION_REPLACE([func_stripname], [dnl # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are # positional parameters, so assign one to ordinary parameter first. func_stripname_result=${3} func_stripname_result=${func_stripname_result#"${1}"} func_stripname_result=${func_stripname_result%"${2}"}]) _LT_PROG_FUNCTION_REPLACE([func_split_long_opt], [dnl func_split_long_opt_name=${1%%=*} func_split_long_opt_arg=${1#*=}]) _LT_PROG_FUNCTION_REPLACE([func_split_short_opt], [dnl func_split_short_opt_arg=${1#??} func_split_short_opt_name=${1%"$func_split_short_opt_arg"}]) _LT_PROG_FUNCTION_REPLACE([func_lo2o], [dnl case ${1} in *.lo) func_lo2o_result=${1%.lo}.${objext} ;; *) func_lo2o_result=${1} ;; esac]) _LT_PROG_FUNCTION_REPLACE([func_xform], [ func_xform_result=${1%.*}.lo]) _LT_PROG_FUNCTION_REPLACE([func_arith], [ func_arith_result=$(( $[*] ))]) _LT_PROG_FUNCTION_REPLACE([func_len], [ func_len_result=${#1}]) fi if test x"$lt_shell_append" = xyes; then _LT_PROG_FUNCTION_REPLACE([func_append], [ eval "${1}+=\\${2}"]) _LT_PROG_FUNCTION_REPLACE([func_append_quoted], [dnl func_quote_for_eval "${2}" dnl m4 expansion turns \\\\ into \\, and then the shell eval turns that into \ eval "${1}+=\\\\ \\$func_quote_for_eval_result"]) # Save a `func_append' function call where possible by direct use of '+=' sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: else # Save a `func_append' function call even when '+=' is not available sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: fi if test x"$_lt_function_replace_fail" = x":"; then AC_MSG_WARN([Unable to substitute extended shell functions in $ofile]) fi ]) # _LT_PATH_CONVERSION_FUNCTIONS # ----------------------------- # Determine which file name conversion functions should be used by # func_to_host_file (and, implicitly, by func_to_host_path). These are needed # for certain cross-compile configurations and native mingw. m4_defun([_LT_PATH_CONVERSION_FUNCTIONS], [AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_CANONICAL_BUILD])dnl AC_MSG_CHECKING([how to convert $build file names to $host format]) AC_CACHE_VAL(lt_cv_to_host_file_cmd, [case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 ;; esac ;; *-*-cygwin* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_noop ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin ;; esac ;; * ) # unhandled hosts (and "normal" native builds) lt_cv_to_host_file_cmd=func_convert_file_noop ;; esac ]) to_host_file_cmd=$lt_cv_to_host_file_cmd AC_MSG_RESULT([$lt_cv_to_host_file_cmd]) _LT_DECL([to_host_file_cmd], [lt_cv_to_host_file_cmd], [0], [convert $build file names to $host format])dnl AC_MSG_CHECKING([how to convert $build file names to toolchain format]) AC_CACHE_VAL(lt_cv_to_tool_file_cmd, [#assume ordinary cross tools, or native build. lt_cv_to_tool_file_cmd=func_convert_file_noop case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 ;; esac ;; esac ]) to_tool_file_cmd=$lt_cv_to_tool_file_cmd AC_MSG_RESULT([$lt_cv_to_tool_file_cmd]) _LT_DECL([to_tool_file_cmd], [lt_cv_to_tool_file_cmd], [0], [convert $build files to toolchain format])dnl ])# _LT_PATH_CONVERSION_FUNCTIONS dlt-daemon-2.18.4/gtest-1.7.0/m4/ltoptions.m4000066400000000000000000000300731353342203500202410ustar00rootroot00000000000000# Helper functions for option handling. -*- Autoconf -*- # # Copyright (C) 2004, 2005, 2007, 2008, 2009 Free Software Foundation, # Inc. # Written by Gary V. Vaughan, 2004 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # serial 7 ltoptions.m4 # This is to help aclocal find these macros, as it can't see m4_define. AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])]) # _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME) # ------------------------------------------ m4_define([_LT_MANGLE_OPTION], [[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])]) # _LT_SET_OPTION(MACRO-NAME, OPTION-NAME) # --------------------------------------- # Set option OPTION-NAME for macro MACRO-NAME, and if there is a # matching handler defined, dispatch to it. Other OPTION-NAMEs are # saved as a flag. m4_define([_LT_SET_OPTION], [m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]), _LT_MANGLE_DEFUN([$1], [$2]), [m4_warning([Unknown $1 option `$2'])])[]dnl ]) # _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET]) # ------------------------------------------------------------ # Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. m4_define([_LT_IF_OPTION], [m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])]) # _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET) # ------------------------------------------------------- # Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME # are set. m4_define([_LT_UNLESS_OPTIONS], [m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), [m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option), [m4_define([$0_found])])])[]dnl m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3 ])[]dnl ]) # _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST) # ---------------------------------------- # OPTION-LIST is a space-separated list of Libtool options associated # with MACRO-NAME. If any OPTION has a matching handler declared with # LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about # the unknown option and exit. m4_defun([_LT_SET_OPTIONS], [# Set options m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), [_LT_SET_OPTION([$1], _LT_Option)]) m4_if([$1],[LT_INIT],[ dnl dnl Simply set some default values (i.e off) if boolean options were not dnl specified: _LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no ]) _LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no ]) dnl dnl If no reference was made to various pairs of opposing options, then dnl we run the default mode handler for the pair. For example, if neither dnl `shared' nor `disable-shared' was passed, we enable building of shared dnl archives by default: _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED]) _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC]) _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC]) _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install], [_LT_ENABLE_FAST_INSTALL]) ]) ])# _LT_SET_OPTIONS ## --------------------------------- ## ## Macros to handle LT_INIT options. ## ## --------------------------------- ## # _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME) # ----------------------------------------- m4_define([_LT_MANGLE_DEFUN], [[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])]) # LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE) # ----------------------------------------------- m4_define([LT_OPTION_DEFINE], [m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl ])# LT_OPTION_DEFINE # dlopen # ------ LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes ]) AU_DEFUN([AC_LIBTOOL_DLOPEN], [_LT_SET_OPTION([LT_INIT], [dlopen]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the `dlopen' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], []) # win32-dll # --------- # Declare package support for building win32 dll's. LT_OPTION_DEFINE([LT_INIT], [win32-dll], [enable_win32_dll=yes case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*) AC_CHECK_TOOL(AS, as, false) AC_CHECK_TOOL(DLLTOOL, dlltool, false) AC_CHECK_TOOL(OBJDUMP, objdump, false) ;; esac test -z "$AS" && AS=as _LT_DECL([], [AS], [1], [Assembler program])dnl test -z "$DLLTOOL" && DLLTOOL=dlltool _LT_DECL([], [DLLTOOL], [1], [DLL creation program])dnl test -z "$OBJDUMP" && OBJDUMP=objdump _LT_DECL([], [OBJDUMP], [1], [Object dumper program])dnl ])# win32-dll AU_DEFUN([AC_LIBTOOL_WIN32_DLL], [AC_REQUIRE([AC_CANONICAL_HOST])dnl _LT_SET_OPTION([LT_INIT], [win32-dll]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the `win32-dll' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], []) # _LT_ENABLE_SHARED([DEFAULT]) # ---------------------------- # implement the --enable-shared flag, and supports the `shared' and # `disable-shared' LT_INIT options. # DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. m4_define([_LT_ENABLE_SHARED], [m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([shared], [AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@], [build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])], [p=${PACKAGE-default} case $enableval in yes) enable_shared=yes ;; no) enable_shared=no ;; *) enable_shared=no # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for pkg in $enableval; do IFS="$lt_save_ifs" if test "X$pkg" = "X$p"; then enable_shared=yes fi done IFS="$lt_save_ifs" ;; esac], [enable_shared=]_LT_ENABLE_SHARED_DEFAULT) _LT_DECL([build_libtool_libs], [enable_shared], [0], [Whether or not to build shared libraries]) ])# _LT_ENABLE_SHARED LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])]) LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])]) # Old names: AC_DEFUN([AC_ENABLE_SHARED], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared]) ]) AC_DEFUN([AC_DISABLE_SHARED], [_LT_SET_OPTION([LT_INIT], [disable-shared]) ]) AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AM_ENABLE_SHARED], []) dnl AC_DEFUN([AM_DISABLE_SHARED], []) # _LT_ENABLE_STATIC([DEFAULT]) # ---------------------------- # implement the --enable-static flag, and support the `static' and # `disable-static' LT_INIT options. # DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. m4_define([_LT_ENABLE_STATIC], [m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([static], [AS_HELP_STRING([--enable-static@<:@=PKGS@:>@], [build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])], [p=${PACKAGE-default} case $enableval in yes) enable_static=yes ;; no) enable_static=no ;; *) enable_static=no # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for pkg in $enableval; do IFS="$lt_save_ifs" if test "X$pkg" = "X$p"; then enable_static=yes fi done IFS="$lt_save_ifs" ;; esac], [enable_static=]_LT_ENABLE_STATIC_DEFAULT) _LT_DECL([build_old_libs], [enable_static], [0], [Whether or not to build static libraries]) ])# _LT_ENABLE_STATIC LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])]) LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])]) # Old names: AC_DEFUN([AC_ENABLE_STATIC], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static]) ]) AC_DEFUN([AC_DISABLE_STATIC], [_LT_SET_OPTION([LT_INIT], [disable-static]) ]) AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AM_ENABLE_STATIC], []) dnl AC_DEFUN([AM_DISABLE_STATIC], []) # _LT_ENABLE_FAST_INSTALL([DEFAULT]) # ---------------------------------- # implement the --enable-fast-install flag, and support the `fast-install' # and `disable-fast-install' LT_INIT options. # DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. m4_define([_LT_ENABLE_FAST_INSTALL], [m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([fast-install], [AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@], [optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])], [p=${PACKAGE-default} case $enableval in yes) enable_fast_install=yes ;; no) enable_fast_install=no ;; *) enable_fast_install=no # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for pkg in $enableval; do IFS="$lt_save_ifs" if test "X$pkg" = "X$p"; then enable_fast_install=yes fi done IFS="$lt_save_ifs" ;; esac], [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT) _LT_DECL([fast_install], [enable_fast_install], [0], [Whether or not to optimize for fast installation])dnl ])# _LT_ENABLE_FAST_INSTALL LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])]) LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])]) # Old names: AU_DEFUN([AC_ENABLE_FAST_INSTALL], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the `fast-install' option into LT_INIT's first parameter.]) ]) AU_DEFUN([AC_DISABLE_FAST_INSTALL], [_LT_SET_OPTION([LT_INIT], [disable-fast-install]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the `disable-fast-install' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], []) dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], []) # _LT_WITH_PIC([MODE]) # -------------------- # implement the --with-pic flag, and support the `pic-only' and `no-pic' # LT_INIT options. # MODE is either `yes' or `no'. If omitted, it defaults to `both'. m4_define([_LT_WITH_PIC], [AC_ARG_WITH([pic], [AS_HELP_STRING([--with-pic@<:@=PKGS@:>@], [try to use only PIC/non-PIC objects @<:@default=use both@:>@])], [lt_p=${PACKAGE-default} case $withval in yes|no) pic_mode=$withval ;; *) pic_mode=default # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for lt_pkg in $withval; do IFS="$lt_save_ifs" if test "X$lt_pkg" = "X$lt_p"; then pic_mode=yes fi done IFS="$lt_save_ifs" ;; esac], [pic_mode=default]) test -z "$pic_mode" && pic_mode=m4_default([$1], [default]) _LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl ])# _LT_WITH_PIC LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])]) LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])]) # Old name: AU_DEFUN([AC_LIBTOOL_PICMODE], [_LT_SET_OPTION([LT_INIT], [pic-only]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the `pic-only' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_PICMODE], []) ## ----------------- ## ## LTDL_INIT Options ## ## ----------------- ## m4_define([_LTDL_MODE], []) LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive], [m4_define([_LTDL_MODE], [nonrecursive])]) LT_OPTION_DEFINE([LTDL_INIT], [recursive], [m4_define([_LTDL_MODE], [recursive])]) LT_OPTION_DEFINE([LTDL_INIT], [subproject], [m4_define([_LTDL_MODE], [subproject])]) m4_define([_LTDL_TYPE], []) LT_OPTION_DEFINE([LTDL_INIT], [installable], [m4_define([_LTDL_TYPE], [installable])]) LT_OPTION_DEFINE([LTDL_INIT], [convenience], [m4_define([_LTDL_TYPE], [convenience])]) dlt-daemon-2.18.4/gtest-1.7.0/m4/ltsugar.m4000066400000000000000000000104241353342203500176650ustar00rootroot00000000000000# ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*- # # Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc. # Written by Gary V. Vaughan, 2004 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # serial 6 ltsugar.m4 # This is to help aclocal find these macros, as it can't see m4_define. AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])]) # lt_join(SEP, ARG1, [ARG2...]) # ----------------------------- # Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their # associated separator. # Needed until we can rely on m4_join from Autoconf 2.62, since all earlier # versions in m4sugar had bugs. m4_define([lt_join], [m4_if([$#], [1], [], [$#], [2], [[$2]], [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])]) m4_define([_lt_join], [m4_if([$#$2], [2], [], [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])]) # lt_car(LIST) # lt_cdr(LIST) # ------------ # Manipulate m4 lists. # These macros are necessary as long as will still need to support # Autoconf-2.59 which quotes differently. m4_define([lt_car], [[$1]]) m4_define([lt_cdr], [m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])], [$#], 1, [], [m4_dquote(m4_shift($@))])]) m4_define([lt_unquote], $1) # lt_append(MACRO-NAME, STRING, [SEPARATOR]) # ------------------------------------------ # Redefine MACRO-NAME to hold its former content plus `SEPARATOR'`STRING'. # Note that neither SEPARATOR nor STRING are expanded; they are appended # to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked). # No SEPARATOR is output if MACRO-NAME was previously undefined (different # than defined and empty). # # This macro is needed until we can rely on Autoconf 2.62, since earlier # versions of m4sugar mistakenly expanded SEPARATOR but not STRING. m4_define([lt_append], [m4_define([$1], m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])]) # lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...]) # ---------------------------------------------------------- # Produce a SEP delimited list of all paired combinations of elements of # PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list # has the form PREFIXmINFIXSUFFIXn. # Needed until we can rely on m4_combine added in Autoconf 2.62. m4_define([lt_combine], [m4_if(m4_eval([$# > 3]), [1], [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl [[m4_foreach([_Lt_prefix], [$2], [m4_foreach([_Lt_suffix], ]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[, [_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])]) # lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ]) # ----------------------------------------------------------------------- # Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited # by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ. m4_define([lt_if_append_uniq], [m4_ifdef([$1], [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1], [lt_append([$1], [$2], [$3])$4], [$5])], [lt_append([$1], [$2], [$3])$4])]) # lt_dict_add(DICT, KEY, VALUE) # ----------------------------- m4_define([lt_dict_add], [m4_define([$1($2)], [$3])]) # lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE) # -------------------------------------------- m4_define([lt_dict_add_subkey], [m4_define([$1($2:$3)], [$4])]) # lt_dict_fetch(DICT, KEY, [SUBKEY]) # ---------------------------------- m4_define([lt_dict_fetch], [m4_ifval([$3], m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]), m4_ifdef([$1($2)], [m4_defn([$1($2)])]))]) # lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE]) # ----------------------------------------------------------------- m4_define([lt_if_dict_fetch], [m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4], [$5], [$6])]) # lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...]) # -------------------------------------------------------------- m4_define([lt_dict_filter], [m4_if([$5], [], [], [lt_join(m4_quote(m4_default([$4], [[, ]])), lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]), [lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl ]) dlt-daemon-2.18.4/gtest-1.7.0/m4/ltversion.m4000066400000000000000000000012621353342203500202310ustar00rootroot00000000000000# ltversion.m4 -- version numbers -*- Autoconf -*- # # Copyright (C) 2004 Free Software Foundation, Inc. # Written by Scott James Remnant, 2004 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # @configure_input@ # serial 3337 ltversion.m4 # This file is part of GNU Libtool m4_define([LT_PACKAGE_VERSION], [2.4.2]) m4_define([LT_PACKAGE_REVISION], [1.3337]) AC_DEFUN([LTVERSION_VERSION], [macro_version='2.4.2' macro_revision='1.3337' _LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?]) _LT_DECL(, macro_revision, 0) ]) dlt-daemon-2.18.4/gtest-1.7.0/m4/lt~obsolete.m4000066400000000000000000000137561353342203500205710ustar00rootroot00000000000000# lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*- # # Copyright (C) 2004, 2005, 2007, 2009 Free Software Foundation, Inc. # Written by Scott James Remnant, 2004. # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # serial 5 lt~obsolete.m4 # These exist entirely to fool aclocal when bootstrapping libtool. # # In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN) # which have later been changed to m4_define as they aren't part of the # exported API, or moved to Autoconf or Automake where they belong. # # The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN # in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us # using a macro with the same name in our local m4/libtool.m4 it'll # pull the old libtool.m4 in (it doesn't see our shiny new m4_define # and doesn't know about Autoconf macros at all.) # # So we provide this file, which has a silly filename so it's always # included after everything else. This provides aclocal with the # AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything # because those macros already exist, or will be overwritten later. # We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6. # # Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here. # Yes, that means every name once taken will need to remain here until # we give up compatibility with versions before 1.7, at which point # we need to keep only those names which we still refer to. # This is to help aclocal find these macros, as it can't see m4_define. AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])]) m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])]) m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])]) m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])]) m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])]) m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])]) m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])]) m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])]) m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])]) m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])]) m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])]) m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])]) m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])]) m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])]) m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])]) m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])]) m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])]) m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])]) m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])]) m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])]) m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])]) m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])]) m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])]) m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])]) m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])]) m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])]) m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])]) m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])]) m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])]) m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])]) m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])]) m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])]) m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])]) m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])]) m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])]) m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])]) m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])]) m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])]) m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])]) m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])]) m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])]) m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])]) m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])]) m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])]) m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])]) m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])]) m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])]) m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])]) m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])]) m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])]) m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])]) m4_ifndef([_LT_REQUIRED_DARWIN_CHECKS], [AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS])]) m4_ifndef([_LT_AC_PROG_CXXCPP], [AC_DEFUN([_LT_AC_PROG_CXXCPP])]) m4_ifndef([_LT_PREPARE_SED_QUOTE_VARS], [AC_DEFUN([_LT_PREPARE_SED_QUOTE_VARS])]) m4_ifndef([_LT_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_PROG_ECHO_BACKSLASH])]) m4_ifndef([_LT_PROG_F77], [AC_DEFUN([_LT_PROG_F77])]) m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])]) m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])]) dlt-daemon-2.18.4/gtest-1.7.0/make/000077500000000000000000000000001353342203500163365ustar00rootroot00000000000000dlt-daemon-2.18.4/gtest-1.7.0/make/Makefile000066400000000000000000000053011353342203500177750ustar00rootroot00000000000000# A sample Makefile for building Google Test and using it in user # tests. Please tweak it to suit your environment and project. You # may want to move it to your project's root directory. # # SYNOPSIS: # # make [all] - makes everything. # make TARGET - makes the given target. # make clean - removes all files generated by make. # Please tweak the following variable definitions as needed by your # project, except GTEST_HEADERS, which you can use in your own targets # but shouldn't modify. # Points to the root of Google Test, relative to where this file is. # Remember to tweak this if you move this file. GTEST_DIR = .. # Where to find user code. USER_DIR = ../samples # Flags passed to the preprocessor. # Set Google Test's header directory as a system directory, such that # the compiler doesn't generate warnings in Google Test headers. CPPFLAGS += -isystem $(GTEST_DIR)/include # Flags passed to the C++ compiler. CXXFLAGS += -g -Wall -Wextra -pthread # All tests produced by this Makefile. Remember to add new tests you # created to the list. TESTS = sample1_unittest # All Google Test headers. Usually you shouldn't change this # definition. GTEST_HEADERS = $(GTEST_DIR)/include/gtest/*.h \ $(GTEST_DIR)/include/gtest/internal/*.h # House-keeping build targets. all : $(TESTS) clean : rm -f $(TESTS) gtest.a gtest_main.a *.o # Builds gtest.a and gtest_main.a. # Usually you shouldn't tweak such internal variables, indicated by a # trailing _. GTEST_SRCS_ = $(GTEST_DIR)/src/*.cc $(GTEST_DIR)/src/*.h $(GTEST_HEADERS) # For simplicity and to avoid depending on Google Test's # implementation details, the dependencies specified below are # conservative and not optimized. This is fine as Google Test # compiles fast and for ordinary users its source rarely changes. gtest-all.o : $(GTEST_SRCS_) $(CXX) $(CPPFLAGS) -I$(GTEST_DIR) $(CXXFLAGS) -c \ $(GTEST_DIR)/src/gtest-all.cc gtest_main.o : $(GTEST_SRCS_) $(CXX) $(CPPFLAGS) -I$(GTEST_DIR) $(CXXFLAGS) -c \ $(GTEST_DIR)/src/gtest_main.cc gtest.a : gtest-all.o $(AR) $(ARFLAGS) $@ $^ gtest_main.a : gtest-all.o gtest_main.o $(AR) $(ARFLAGS) $@ $^ # Builds a sample test. A test should link with either gtest.a or # gtest_main.a, depending on whether it defines its own main() # function. sample1.o : $(USER_DIR)/sample1.cc $(USER_DIR)/sample1.h $(GTEST_HEADERS) $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/sample1.cc sample1_unittest.o : $(USER_DIR)/sample1_unittest.cc \ $(USER_DIR)/sample1.h $(GTEST_HEADERS) $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/sample1_unittest.cc sample1_unittest : sample1.o sample1_unittest.o gtest_main.a $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ dlt-daemon-2.18.4/gtest-1.7.0/msvc/000077500000000000000000000000001353342203500163715ustar00rootroot00000000000000dlt-daemon-2.18.4/gtest-1.7.0/msvc/gtest-md.sln000077500000000000000000000046301353342203500206410ustar00rootroot00000000000000Microsoft Visual Studio Solution File, Format Version 8.00 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gtest-md", "gtest-md.vcproj", "{C8F6C172-56F2-4E76-B5FA-C3B423B31BE8}" ProjectSection(ProjectDependencies) = postProject EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gtest_main-md", "gtest_main-md.vcproj", "{3AF54C8A-10BF-4332-9147-F68ED9862033}" ProjectSection(ProjectDependencies) = postProject EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gtest_prod_test-md", "gtest_prod_test-md.vcproj", "{24848551-EF4F-47E8-9A9D-EA4D49BC3ECB}" ProjectSection(ProjectDependencies) = postProject EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gtest_unittest-md", "gtest_unittest-md.vcproj", "{4D9FDFB5-986A-4139-823C-F4EE0ED481A2}" ProjectSection(ProjectDependencies) = postProject EndProjectSection EndProject Global GlobalSection(SolutionConfiguration) = preSolution Debug = Debug Release = Release EndGlobalSection GlobalSection(ProjectConfiguration) = postSolution {C8F6C172-56F2-4E76-B5FA-C3B423B31BE8}.Debug.ActiveCfg = Debug|Win32 {C8F6C172-56F2-4E76-B5FA-C3B423B31BE8}.Debug.Build.0 = Debug|Win32 {C8F6C172-56F2-4E76-B5FA-C3B423B31BE8}.Release.ActiveCfg = Release|Win32 {C8F6C172-56F2-4E76-B5FA-C3B423B31BE8}.Release.Build.0 = Release|Win32 {3AF54C8A-10BF-4332-9147-F68ED9862033}.Debug.ActiveCfg = Debug|Win32 {3AF54C8A-10BF-4332-9147-F68ED9862033}.Debug.Build.0 = Debug|Win32 {3AF54C8A-10BF-4332-9147-F68ED9862033}.Release.ActiveCfg = Release|Win32 {3AF54C8A-10BF-4332-9147-F68ED9862033}.Release.Build.0 = Release|Win32 {24848551-EF4F-47E8-9A9D-EA4D49BC3ECB}.Debug.ActiveCfg = Debug|Win32 {24848551-EF4F-47E8-9A9D-EA4D49BC3ECB}.Debug.Build.0 = Debug|Win32 {24848551-EF4F-47E8-9A9D-EA4D49BC3ECB}.Release.ActiveCfg = Release|Win32 {24848551-EF4F-47E8-9A9D-EA4D49BC3ECB}.Release.Build.0 = Release|Win32 {4D9FDFB5-986A-4139-823C-F4EE0ED481A2}.Debug.ActiveCfg = Debug|Win32 {4D9FDFB5-986A-4139-823C-F4EE0ED481A2}.Debug.Build.0 = Debug|Win32 {4D9FDFB5-986A-4139-823C-F4EE0ED481A2}.Release.ActiveCfg = Release|Win32 {4D9FDFB5-986A-4139-823C-F4EE0ED481A2}.Release.Build.0 = Release|Win32 EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution EndGlobalSection GlobalSection(ExtensibilityAddIns) = postSolution EndGlobalSection EndGlobal dlt-daemon-2.18.4/gtest-1.7.0/msvc/gtest-md.vcproj000077500000000000000000000064561353342203500213600ustar00rootroot00000000000000 dlt-daemon-2.18.4/gtest-1.7.0/msvc/gtest.sln000077500000000000000000000046001353342203500202400ustar00rootroot00000000000000Microsoft Visual Studio Solution File, Format Version 8.00 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gtest", "gtest.vcproj", "{C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}" ProjectSection(ProjectDependencies) = postProject EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gtest_main", "gtest_main.vcproj", "{3AF54C8A-10BF-4332-9147-F68ED9862032}" ProjectSection(ProjectDependencies) = postProject EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gtest_unittest", "gtest_unittest.vcproj", "{4D9FDFB5-986A-4139-823C-F4EE0ED481A1}" ProjectSection(ProjectDependencies) = postProject EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gtest_prod_test", "gtest_prod_test.vcproj", "{24848551-EF4F-47E8-9A9D-EA4D49BC3ECA}" ProjectSection(ProjectDependencies) = postProject EndProjectSection EndProject Global GlobalSection(SolutionConfiguration) = preSolution Debug = Debug Release = Release EndGlobalSection GlobalSection(ProjectConfiguration) = postSolution {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}.Debug.ActiveCfg = Debug|Win32 {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}.Debug.Build.0 = Debug|Win32 {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}.Release.ActiveCfg = Release|Win32 {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}.Release.Build.0 = Release|Win32 {3AF54C8A-10BF-4332-9147-F68ED9862032}.Debug.ActiveCfg = Debug|Win32 {3AF54C8A-10BF-4332-9147-F68ED9862032}.Debug.Build.0 = Debug|Win32 {3AF54C8A-10BF-4332-9147-F68ED9862032}.Release.ActiveCfg = Release|Win32 {3AF54C8A-10BF-4332-9147-F68ED9862032}.Release.Build.0 = Release|Win32 {4D9FDFB5-986A-4139-823C-F4EE0ED481A1}.Debug.ActiveCfg = Debug|Win32 {4D9FDFB5-986A-4139-823C-F4EE0ED481A1}.Debug.Build.0 = Debug|Win32 {4D9FDFB5-986A-4139-823C-F4EE0ED481A1}.Release.ActiveCfg = Release|Win32 {4D9FDFB5-986A-4139-823C-F4EE0ED481A1}.Release.Build.0 = Release|Win32 {24848551-EF4F-47E8-9A9D-EA4D49BC3ECA}.Debug.ActiveCfg = Debug|Win32 {24848551-EF4F-47E8-9A9D-EA4D49BC3ECA}.Debug.Build.0 = Debug|Win32 {24848551-EF4F-47E8-9A9D-EA4D49BC3ECA}.Release.ActiveCfg = Release|Win32 {24848551-EF4F-47E8-9A9D-EA4D49BC3ECA}.Release.Build.0 = Release|Win32 EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution EndGlobalSection GlobalSection(ExtensibilityAddIns) = postSolution EndGlobalSection EndGlobal dlt-daemon-2.18.4/gtest-1.7.0/msvc/gtest.vcproj000077500000000000000000000064531353342203500207570ustar00rootroot00000000000000 dlt-daemon-2.18.4/gtest-1.7.0/msvc/gtest_main-md.vcproj000077500000000000000000000066721353342203500223640ustar00rootroot00000000000000 dlt-daemon-2.18.4/gtest-1.7.0/msvc/gtest_main.vcproj000077500000000000000000000066641353342203500217670ustar00rootroot00000000000000 dlt-daemon-2.18.4/gtest-1.7.0/msvc/gtest_prod_test-md.vcproj000077500000000000000000000106431353342203500234340ustar00rootroot00000000000000 dlt-daemon-2.18.4/gtest-1.7.0/msvc/gtest_prod_test.vcproj000077500000000000000000000106351353342203500230370ustar00rootroot00000000000000 dlt-daemon-2.18.4/gtest-1.7.0/msvc/gtest_unittest-md.vcproj000077500000000000000000000076511353342203500233150ustar00rootroot00000000000000 dlt-daemon-2.18.4/gtest-1.7.0/msvc/gtest_unittest.vcproj000077500000000000000000000076431353342203500227200ustar00rootroot00000000000000 dlt-daemon-2.18.4/gtest-1.7.0/samples/000077500000000000000000000000001353342203500170655ustar00rootroot00000000000000dlt-daemon-2.18.4/gtest-1.7.0/samples/.deps/000077500000000000000000000000001353342203500200765ustar00rootroot00000000000000dlt-daemon-2.18.4/gtest-1.7.0/samples/.deps/.dirstamp000066400000000000000000000000001353342203500217100ustar00rootroot00000000000000dlt-daemon-2.18.4/gtest-1.7.0/samples/.deps/sample1.Plo000066400000000000000000000002101353342203500221050ustar00rootroot00000000000000samples/sample1.lo: samples/sample1.cc /usr/include/stdc-predef.h \ samples/sample1.h /usr/include/stdc-predef.h: samples/sample1.h: dlt-daemon-2.18.4/gtest-1.7.0/samples/.deps/sample10_unittest.Po000066400000000000000000000000101353342203500237460ustar00rootroot00000000000000# dummy dlt-daemon-2.18.4/gtest-1.7.0/samples/.deps/sample1_unittest.Po000066400000000000000000000000101353342203500236660ustar00rootroot00000000000000# dummy dlt-daemon-2.18.4/gtest-1.7.0/samples/.deps/sample2.Plo000066400000000000000000000011601353342203500221130ustar00rootroot00000000000000samples/sample2.lo: samples/sample2.cc /usr/include/stdc-predef.h \ samples/sample2.h /usr/include/string.h /usr/include/features.h \ /usr/include/sys/cdefs.h /usr/include/bits/wordsize.h \ /usr/include/gnu/stubs.h /usr/include/gnu/stubs-32.h \ /usr/lib/gcc/i686-redhat-linux/4.9.2/include/stddef.h \ /usr/include/xlocale.h /usr/include/stdc-predef.h: samples/sample2.h: /usr/include/string.h: /usr/include/features.h: /usr/include/sys/cdefs.h: /usr/include/bits/wordsize.h: /usr/include/gnu/stubs.h: /usr/include/gnu/stubs-32.h: /usr/lib/gcc/i686-redhat-linux/4.9.2/include/stddef.h: /usr/include/xlocale.h: dlt-daemon-2.18.4/gtest-1.7.0/samples/.deps/sample4.Plo000066400000000000000000000021561353342203500221230ustar00rootroot00000000000000samples/sample4.lo: samples/sample4.cc /usr/include/stdc-predef.h \ /usr/include/stdio.h /usr/include/features.h /usr/include/sys/cdefs.h \ /usr/include/bits/wordsize.h /usr/include/gnu/stubs.h \ /usr/include/gnu/stubs-32.h \ /usr/lib/gcc/i686-redhat-linux/4.9.2/include/stddef.h \ /usr/include/bits/types.h /usr/include/bits/typesizes.h \ /usr/include/libio.h /usr/include/_G_config.h /usr/include/wchar.h \ /usr/lib/gcc/i686-redhat-linux/4.9.2/include/stdarg.h \ /usr/include/bits/stdio_lim.h /usr/include/bits/sys_errlist.h \ /usr/include/bits/stdio.h samples/sample4.h /usr/include/stdc-predef.h: /usr/include/stdio.h: /usr/include/features.h: /usr/include/sys/cdefs.h: /usr/include/bits/wordsize.h: /usr/include/gnu/stubs.h: /usr/include/gnu/stubs-32.h: /usr/lib/gcc/i686-redhat-linux/4.9.2/include/stddef.h: /usr/include/bits/types.h: /usr/include/bits/typesizes.h: /usr/include/libio.h: /usr/include/_G_config.h: /usr/include/wchar.h: /usr/lib/gcc/i686-redhat-linux/4.9.2/include/stdarg.h: /usr/include/bits/stdio_lim.h: /usr/include/bits/sys_errlist.h: /usr/include/bits/stdio.h: samples/sample4.h: dlt-daemon-2.18.4/gtest-1.7.0/samples/.deps/test_fused_gtest_test-sample1.Po000066400000000000000000000000101353342203500263370ustar00rootroot00000000000000# dummy dlt-daemon-2.18.4/gtest-1.7.0/samples/.deps/test_fused_gtest_test-sample1_unittest.Po000066400000000000000000000000101353342203500302760ustar00rootroot00000000000000# dummy dlt-daemon-2.18.4/gtest-1.7.0/samples/.dirstamp000066400000000000000000000000001353342203500206770ustar00rootroot00000000000000dlt-daemon-2.18.4/gtest-1.7.0/samples/.libs/000077500000000000000000000000001353342203500200745ustar00rootroot00000000000000dlt-daemon-2.18.4/gtest-1.7.0/samples/.libs/libsamples.a000066400000000000000000000313001353342203500223660ustar00rootroot00000000000000! / 1428496273 0 0 0 204 `  d d d```_Z9Factoriali_Z7IsPrimei_ZN8MyString12CloneCStringEPKc__x86.get_pc_thunk.bx_ZN8MyString3SetEPKc_ZN7Counter9IncrementEv_ZNK7Counter5PrintEv__x86.get_pc_thunk.bxsample1.o/ 1428496273 1000 1000 100664 2840 ` ELF4(L$~vƒ9uøÍVt$~Vt>~1VUUU)R9t2vt$9}^Ð^Ð&1^?5%"*n%%& i'Jint/0dn/uB6i90% .?: ; nI@B: ; I 4: ; I4: ; I$ > $ > $$*Q1$P$*11$R$*10ee~V~VVBe3exQn) samplessample1.cc$L=;^w L[\%,>|Yp<fm.IsPrimeresultsamples/sample1.cc_Z9FactorialiboolFactorialGNU C++ 4.9.2 20150212 (Red Hat 4.9.2-6) -mtune=generic -march=i686 -g -O2 -fPIC_Z7IsPrimei/home/user/projects/ascgit/ascgit003.dlt-daemon/build/gtest-1.7.0GCC: (GNU) 4.9.2 20150212 (Red Hat 4.9.2-6)zR| *(00dAM B G I C.symtab.strtab.shstrtab.text.data.bss.text.unlikely.rel.debug_info.debug_abbrev.debug_loc.rel.debug_aranges.rel.debug_line.debug_str.comment.note.GNU-stack.rel.eh_frame@!',?; @ K|Y!h d  {.rw  00~-X     &    *0dsample1.cc_Z9Factoriali_Z7IsPrimei    ! & , 4KPY chy   6 4sample2.o/ 1428496273 1000 1000 100664 4800 ` ELF 4(UWVS l$ t6 Ux<$ WUP [^_]Ð&1썶WVSt$ t$ Džt R>[^_$d9)0LintRW_)q0+L ,q | q 0EL L _7 |_: | L _? | q G | EhJL17 L%OU SetQe | Lw^^w'Tq'Llen*:+ #d.z;%WU3`;ZZq3Lr%@5_>~|L%z L 0|   7 & % : ; I$ > $ >  I&I : ;  : ; I8 .?: ; nI<d I4 I .?: ; nI2 < .?: ; 2 <d.?: ; 2 <cd.?: ; nI2 <d.?: ; n2 <d I.G: ; @B: ; I U4: ; I4: ; I1.G: ; @dBI4 .?: ;I<.?nI4< .?I4<& .?n4<#-P-@w3:P:@VPW@PT samples/usr/lib/gcc/i686-redhat-linux/4.9.2/include/usr/includesample2.ccsample2.hstddef.hstring.h& KL;/Yy "W/J/_ZNK8MyString8c_stringEvoperator new []size_tc_string_clonetemp_ZN8MyString12CloneCStringEPKcGNU C++ 4.9.2 20150212 (Red Hat 4.9.2-6) -mtune=generic -march=i686 -g -O2 -fPICLength_ZN8MyStringaSERKS__ZNK8MyString6LengthEv~MyString_ZdaPvcharoperator=strlenthis_ZnajCloneCStringoperator delete []samples/sample2.ccshort unsigned intMyStringc_stringa_c_stringmemcpyunsigned int_ZN8MyString3SetEPKcsizetype/home/user/projects/ascgit/ascgit003.dlt-daemon/build/gtest-1.7.0GCC: (GNU) 4.9.2 20150212 (Red Hat 4.9.2-6)zR| PTAA AAN K,A0S$C(A,A0H E AA AAI <p`;AA ARD JIA HC AA.symtab.strtab.shstrtab.rel.text.data.bss.text.unlikely.text.__x86.get_pc_thunk.bx.rel.debug_info.debug_abbrev.debug_loc.rel.debug_aranges.debug_ranges.rel.debug_line.debug_str.comment.note.GNU-stack.rel.eh_frame.group4@ H%+0?_[ kyi    # 00-    8    T+AW^dk`;sample2.cc_ZN8MyString12CloneCStringEPKc__x86.get_pc_thunk.bx_GLOBAL_OFFSET_TABLE_strlen_Znajmemcpy_ZN8MyString3SetEPKc_ZdaPv *7hn z    ! & 3 : A Z _ k w }         8 > \       ! /8 B GPe {      tsample4.o/ 1428496273 1000 1000 100664 4900 ` ELF 4(T$H Ít&SD$0P[%d$ÛR}6800 .intf 7a<2o?-Zo X $ t  $ K( !, e0 D k4  Z8 aZ< z@ >D LF HqG H H%L .T /X 0\ 1` 2%d i4Zh 6l = eekZ4  -  ' P&(ZP,/ Z2  ' /<< ,&Zpp1 [kkjZ% : ; I$ > $ >   I : ;  : ; I8 : ;I8 : ; I !I/ &I : ; .?: ; 2 <dI4.?: ; nI2 <d.?: ; n2 <d.G: ; @dBI414: ; I?<.?: ;I<I6 samples/usr/lib/gcc/i686-redhat-linux/4.9.2/include/usr/include/bits/usr/includesample4.ccstddef.htypes.hlibio.hsample4.hstdio.h&Ku[!_IO_buf_end__quad_t_old_offset_IO_save_endshort intsize_tsizetype_offsetCounter_IO_write_ptrlong long int_IO_buf_base_markers_IO_read_endIncrementPrintsamples/sample4.cc_locklong intprintf_cur_column_pos_IO_write_base_sbuf_IO_FILEunsigned charsigned charlong long unsigned intunsigned int_IO_marker_shortbufGNU C++ 4.9.2 20150212 (Red Hat 4.9.2-6) -mtune=generic -march=i686 -g -O2 -fPIC_unused2_IO_read_ptrshort unsigned intchar_next__pad1__pad2__pad3__pad4__pad5long unsigned int_ZN7Counter9IncrementEv_IO_write_end__off64_t__off_t_chain_IO_backup_basestdin_flags2_mode_IO_read_base/home/user/projects/ascgit/ascgit003.dlt-daemon/build/gtest-1.7.0counter__vtable_offset_IO_save_base_fileno_ZNK7Counter5PrintEvthis_flagsstdout_IO_lock_tGCC: (GNU) 4.9.2 20150212 (Red Hat 4.9.2-6)zR|  $0&ANFG HAX.symtab.strtab.shstrtab.rel.text.data.bss.text.unlikely.rodata.str1.1.text.__x86.get_pc_thunk.bx.rel.debug_info.debug_abbrev.rel.debug_aranges.rel.debug_line.debug_str.comment.note.GNU-stack.rel.eh_frame.group4@6  %v+v0v?2vNyn}j 8 zQm    0\ 0| -  h  p (q     )&>Tjsample4.cc.LC1_ZN7Counter9IncrementEv_ZNK7Counter5PrintEv__x86.get_pc_thunk.bx_GLOBAL_OFFSET_TABLE_printf ' -    ! & 3 : A H O V d k p {               ) 6 C P ] j w              . 5 A M Y        0 H[ gv    4\dlt-daemon-2.18.4/gtest-1.7.0/samples/.libs/libsamples.la000077700000000000000000000000001353342203500254242../libsamples.laustar00rootroot00000000000000dlt-daemon-2.18.4/gtest-1.7.0/samples/.libs/sample1.o000066400000000000000000000054301353342203500216200ustar00rootroot00000000000000ELF4(L$~vƒ9uøÍVt$~Vt>~1VUUU)R9t2vt$9}^Ð^Ð&1^?5%"*n%%& i'Jint/0dn/uB6i90% .?: ; nI@B: ; I 4: ; I4: ; I$ > $ > $$*Q1$P$*11$R$*10ee~V~VVBe3exQn) samplessample1.cc$L=;^w L[\%,>|Yp<fm.IsPrimeresultsamples/sample1.cc_Z9FactorialiboolFactorialGNU C++ 4.9.2 20150212 (Red Hat 4.9.2-6) -mtune=generic -march=i686 -g -O2 -fPIC_Z7IsPrimei/home/user/projects/ascgit/ascgit003.dlt-daemon/build/gtest-1.7.0GCC: (GNU) 4.9.2 20150212 (Red Hat 4.9.2-6)zR| *(00dAM B G I C.symtab.strtab.shstrtab.text.data.bss.text.unlikely.rel.debug_info.debug_abbrev.debug_loc.rel.debug_aranges.rel.debug_line.debug_str.comment.note.GNU-stack.rel.eh_frame@!',?; @ K|Y!h d  {.rw  00~-X     &    *0dsample1.cc_Z9Factoriali_Z7IsPrimei    ! & , 4KPY chy   6 4dlt-daemon-2.18.4/gtest-1.7.0/samples/.libs/sample2.o000066400000000000000000000113001353342203500216120ustar00rootroot00000000000000ELF 4(UWVS l$ t6 Ux<$ WUP [^_]Ð&1썶WVSt$ t$ Džt R>[^_$d9)0LintRW_)q0+L ,q | q 0EL L _7 |_: | L _? | q G | EhJL17 L%OU SetQe | Lw^^w'Tq'Llen*:+ #d.z;%WU3`;ZZq3Lr%@5_>~|L%z L 0|   7 & % : ; I$ > $ >  I&I : ;  : ; I8 .?: ; nI<d I4 I .?: ; nI2 < .?: ; 2 <d.?: ; 2 <cd.?: ; nI2 <d.?: ; n2 <d I.G: ; @B: ; I U4: ; I4: ; I1.G: ; @dBI4 .?: ;I<.?nI4< .?I4<& .?n4<#-P-@w3:P:@VPW@PT samples/usr/lib/gcc/i686-redhat-linux/4.9.2/include/usr/includesample2.ccsample2.hstddef.hstring.h& KL;/Yy "W/J/_ZNK8MyString8c_stringEvoperator new []size_tc_string_clonetemp_ZN8MyString12CloneCStringEPKcGNU C++ 4.9.2 20150212 (Red Hat 4.9.2-6) -mtune=generic -march=i686 -g -O2 -fPICLength_ZN8MyStringaSERKS__ZNK8MyString6LengthEv~MyString_ZdaPvcharoperator=strlenthis_ZnajCloneCStringoperator delete []samples/sample2.ccshort unsigned intMyStringc_stringa_c_stringmemcpyunsigned int_ZN8MyString3SetEPKcsizetype/home/user/projects/ascgit/ascgit003.dlt-daemon/build/gtest-1.7.0GCC: (GNU) 4.9.2 20150212 (Red Hat 4.9.2-6)zR| PTAA AAN K,A0S$C(A,A0H E AA AAI <p`;AA ARD JIA HC AA.symtab.strtab.shstrtab.rel.text.data.bss.text.unlikely.text.__x86.get_pc_thunk.bx.rel.debug_info.debug_abbrev.debug_loc.rel.debug_aranges.debug_ranges.rel.debug_line.debug_str.comment.note.GNU-stack.rel.eh_frame.group4@ H%+0?_[ kyi    # 00-    8    T+AW^dk`;sample2.cc_ZN8MyString12CloneCStringEPKc__x86.get_pc_thunk.bx_GLOBAL_OFFSET_TABLE_strlen_Znajmemcpy_ZN8MyString3SetEPKc_ZdaPv *7hn z    ! & 3 : A Z _ k w }         8 > \       ! /8 B GPe {      tdlt-daemon-2.18.4/gtest-1.7.0/samples/.libs/sample4.o000066400000000000000000000114441353342203500216250ustar00rootroot00000000000000ELF 4(T$H Ít&SD$0P[%d$ÛR}6800 .intf 7a<2o?-Zo X $ t  $ K( !, e0 D k4  Z8 aZ< z@ >D LF HqG H H%L .T /X 0\ 1` 2%d i4Zh 6l = eekZ4  -  ' P&(ZP,/ Z2  ' /<< ,&Zpp1 [kkjZ% : ; I$ > $ >   I : ;  : ; I8 : ;I8 : ; I !I/ &I : ; .?: ; 2 <dI4.?: ; nI2 <d.?: ; n2 <d.G: ; @dBI414: ; I?<.?: ;I<I6 samples/usr/lib/gcc/i686-redhat-linux/4.9.2/include/usr/include/bits/usr/includesample4.ccstddef.htypes.hlibio.hsample4.hstdio.h&Ku[!_IO_buf_end__quad_t_old_offset_IO_save_endshort intsize_tsizetype_offsetCounter_IO_write_ptrlong long int_IO_buf_base_markers_IO_read_endIncrementPrintsamples/sample4.cc_locklong intprintf_cur_column_pos_IO_write_base_sbuf_IO_FILEunsigned charsigned charlong long unsigned intunsigned int_IO_marker_shortbufGNU C++ 4.9.2 20150212 (Red Hat 4.9.2-6) -mtune=generic -march=i686 -g -O2 -fPIC_unused2_IO_read_ptrshort unsigned intchar_next__pad1__pad2__pad3__pad4__pad5long unsigned int_ZN7Counter9IncrementEv_IO_write_end__off64_t__off_t_chain_IO_backup_basestdin_flags2_mode_IO_read_base/home/user/projects/ascgit/ascgit003.dlt-daemon/build/gtest-1.7.0counter__vtable_offset_IO_save_base_fileno_ZNK7Counter5PrintEvthis_flagsstdout_IO_lock_tGCC: (GNU) 4.9.2 20150212 (Red Hat 4.9.2-6)zR|  $0&ANFG HAX.symtab.strtab.shstrtab.rel.text.data.bss.text.unlikely.rodata.str1.1.text.__x86.get_pc_thunk.bx.rel.debug_info.debug_abbrev.rel.debug_aranges.rel.debug_line.debug_str.comment.note.GNU-stack.rel.eh_frame.group4@6  %v+v0v?2vNyn}j 8 zQm    0\ 0| -  h  p (q     )&>Tjsample4.cc.LC1_ZN7Counter9IncrementEv_ZNK7Counter5PrintEv__x86.get_pc_thunk.bx_GLOBAL_OFFSET_TABLE_printf ' -    ! & 3 : A H O V d k p {               ) 6 C P ] j w              . 5 A M Y        0 H[ gv    4\dlt-daemon-2.18.4/gtest-1.7.0/samples/libsamples.la000066400000000000000000000015671353342203500215470ustar00rootroot00000000000000# libsamples.la - a libtool library file # Generated by libtool (GNU libtool) 2.4.2 Debian-2.4.2-1ubuntu1 # # Please DO NOT delete this file! # It is necessary for linking the library. # The name that we can dlopen(3). dlname='' # Names of this library. library_names='' # The name of the static archive. old_library='libsamples.a' # Linker flags that can not go in dependency_libs. inherited_linker_flags=' -pthread' # Libraries that this one depends upon. dependency_libs='' # Names of additional weak libraries provided by this library weak_library_names='' # Version information for libsamples. current= age= revision= # Is this an already installed library? installed=no # Should we warn about portability when linking against -modules? shouldnotlink=no # Files to dlopen/dlpreopen dlopen='' dlpreopen='' # Directory that this library needs to be installed in: libdir='' dlt-daemon-2.18.4/gtest-1.7.0/samples/prime_tables.h000066400000000000000000000077501353342203500217150ustar00rootroot00000000000000// Copyright 2008 Google Inc. // All Rights Reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: wan@google.com (Zhanyong Wan) // Author: vladl@google.com (Vlad Losev) // This provides interface PrimeTable that determines whether a number is a // prime and determines a next prime number. This interface is used // in Google Test samples demonstrating use of parameterized tests. #ifndef GTEST_SAMPLES_PRIME_TABLES_H_ #define GTEST_SAMPLES_PRIME_TABLES_H_ #include // The prime table interface. class PrimeTable { public: virtual ~PrimeTable() {} // Returns true iff n is a prime number. virtual bool IsPrime(int n) const = 0; // Returns the smallest prime number greater than p; or returns -1 // if the next prime is beyond the capacity of the table. virtual int GetNextPrime(int p) const = 0; }; // Implementation #1 calculates the primes on-the-fly. class OnTheFlyPrimeTable : public PrimeTable { public: virtual bool IsPrime(int n) const { if (n <= 1) return false; for (int i = 2; i*i <= n; i++) { // n is divisible by an integer other than 1 and itself. if ((n % i) == 0) return false; } return true; } virtual int GetNextPrime(int p) const { for (int n = p + 1; n > 0; n++) { if (IsPrime(n)) return n; } return -1; } }; // Implementation #2 pre-calculates the primes and stores the result // in an array. class PreCalculatedPrimeTable : public PrimeTable { public: // 'max' specifies the maximum number the prime table holds. explicit PreCalculatedPrimeTable(int max) : is_prime_size_(max + 1), is_prime_(new bool[max + 1]) { CalculatePrimesUpTo(max); } virtual ~PreCalculatedPrimeTable() { delete[] is_prime_; } virtual bool IsPrime(int n) const { return 0 <= n && n < is_prime_size_ && is_prime_[n]; } virtual int GetNextPrime(int p) const { for (int n = p + 1; n < is_prime_size_; n++) { if (is_prime_[n]) return n; } return -1; } private: void CalculatePrimesUpTo(int max) { ::std::fill(is_prime_, is_prime_ + is_prime_size_, true); is_prime_[0] = is_prime_[1] = false; for (int i = 2; i <= max; i++) { if (!is_prime_[i]) continue; // Marks all multiples of i (except i itself) as non-prime. for (int j = 2*i; j <= max; j += i) { is_prime_[j] = false; } } } const int is_prime_size_; bool* const is_prime_; // Disables compiler warning "assignment operator could not be generated." void operator=(const PreCalculatedPrimeTable& rhs); }; #endif // GTEST_SAMPLES_PRIME_TABLES_H_ dlt-daemon-2.18.4/gtest-1.7.0/samples/sample1.cc000066400000000000000000000047061353342203500207450ustar00rootroot00000000000000// Copyright 2005, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // A sample program demonstrating using Google C++ testing framework. // // Author: wan@google.com (Zhanyong Wan) #include "sample1.h" // Returns n! (the factorial of n). For negative n, n! is defined to be 1. int Factorial(int n) { int result = 1; for (int i = 1; i <= n; i++) { result *= i; } return result; } // Returns true iff n is a prime number. bool IsPrime(int n) { // Trivial case 1: small numbers if (n <= 1) return false; // Trivial case 2: even numbers if (n % 2 == 0) return n == 2; // Now, we have that n is odd and n >= 3. // Try to divide n by every odd number i, starting from 3 for (int i = 3; ; i += 2) { // We only have to try i up to the squre root of n if (i > n/i) break; // Now, we have i <= n/i < n. // If n is divisible by i, n is not prime. if (n % i == 0) return false; } // n has no integer factor in the range (1, n), and thus is prime. return true; } dlt-daemon-2.18.4/gtest-1.7.0/samples/sample1.h000066400000000000000000000036211353342203500206020ustar00rootroot00000000000000// Copyright 2005, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // A sample program demonstrating using Google C++ testing framework. // // Author: wan@google.com (Zhanyong Wan) #ifndef GTEST_SAMPLES_SAMPLE1_H_ #define GTEST_SAMPLES_SAMPLE1_H_ // Returns n! (the factorial of n). For negative n, n! is defined to be 1. int Factorial(int n); // Returns true iff n is a prime number. bool IsPrime(int n); #endif // GTEST_SAMPLES_SAMPLE1_H_ dlt-daemon-2.18.4/gtest-1.7.0/samples/sample1.lo000066400000000000000000000004571353342203500207710ustar00rootroot00000000000000# samples/sample1.lo - a libtool object file # Generated by libtool (GNU libtool) 2.4.2 Debian-2.4.2-1ubuntu1 # # Please DO NOT delete this file! # It is necessary for linking the library. # Name of the PIC object. pic_object='.libs/sample1.o' # Name of the non-PIC object non_pic_object='sample1.o' dlt-daemon-2.18.4/gtest-1.7.0/samples/sample1.o000066400000000000000000000054241353342203500206140ustar00rootroot00000000000000ELF4(L$~vƒ9uøÍS\$~VtA~4غVUUU)R9t5 t$؃9}[Ð[Ð&1[Z%m*n%%S& i'JintK/0dn/u?9i9{% .?: ; nI@B: ; I 4: ; I4: ; I$ > $ > $$*Q1$P$*11$R$*10bb~S~SS?b3bxQn) samplessample1.cc$L=;^w L[_\(,>|Yp<fm.GNU C++ 4.9.2 20150212 (Red Hat 4.9.2-6) -mtune=generic -march=i686 -g -O2IsPrimeresultsamples/sample1.cc_Z9FactorialiboolFactorial_Z7IsPrimei/home/user/projects/ascgit/ascgit003.dlt-daemon/build/gtest-1.7.0GCC: (GNU) 4.9.2 20150212 (Red Hat 4.9.2-6)zR| *(00dAM B G I C.symtab.strtab.shstrtab.text.data.bss.text.unlikely.rel.debug_info.debug_abbrev.debug_loc.rel.debug_aranges.rel.debug_line.debug_str.comment.note.GNU-stack.rel.eh_frame@!',?; < K|Y!h d  {.rw  00x-X     &    *0dsample1.cc_Z9Factoriali_Z7IsPrimei    ! & , 4KPY chy   6 4dlt-daemon-2.18.4/gtest-1.7.0/samples/sample10_unittest.cc000066400000000000000000000116751353342203500227670ustar00rootroot00000000000000// Copyright 2009 Google Inc. All Rights Reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: vladl@google.com (Vlad Losev) // This sample shows how to use Google Test listener API to implement // a primitive leak checker. #include #include #include "gtest/gtest.h" using ::testing::EmptyTestEventListener; using ::testing::InitGoogleTest; using ::testing::Test; using ::testing::TestCase; using ::testing::TestEventListeners; using ::testing::TestInfo; using ::testing::TestPartResult; using ::testing::UnitTest; namespace { // We will track memory used by this class. class Water { public: // Normal Water declarations go here. // operator new and operator delete help us control water allocation. void* operator new(size_t allocation_size) { allocated_++; return malloc(allocation_size); } void operator delete(void* block, size_t /* allocation_size */) { allocated_--; free(block); } static int allocated() { return allocated_; } private: static int allocated_; }; int Water::allocated_ = 0; // This event listener monitors how many Water objects are created and // destroyed by each test, and reports a failure if a test leaks some Water // objects. It does this by comparing the number of live Water objects at // the beginning of a test and at the end of a test. class LeakChecker : public EmptyTestEventListener { private: // Called before a test starts. virtual void OnTestStart(const TestInfo& /* test_info */) { initially_allocated_ = Water::allocated(); } // Called after a test ends. virtual void OnTestEnd(const TestInfo& /* test_info */) { int difference = Water::allocated() - initially_allocated_; // You can generate a failure in any event handler except // OnTestPartResult. Just use an appropriate Google Test assertion to do // it. EXPECT_LE(difference, 0) << "Leaked " << difference << " unit(s) of Water!"; } int initially_allocated_; }; TEST(ListenersTest, DoesNotLeak) { Water* water = new Water; delete water; } // This should fail when the --check_for_leaks command line flag is // specified. TEST(ListenersTest, LeaksWater) { Water* water = new Water; EXPECT_TRUE(water != NULL); } } // namespace int main(int argc, char **argv) { InitGoogleTest(&argc, argv); bool check_for_leaks = false; if (argc > 1 && strcmp(argv[1], "--check_for_leaks") == 0 ) check_for_leaks = true; else printf("%s\n", "Run this program with --check_for_leaks to enable " "custom leak checking in the tests."); // If we are given the --check_for_leaks command line flag, installs the // leak checker. if (check_for_leaks) { TestEventListeners& listeners = UnitTest::GetInstance()->listeners(); // Adds the leak checker to the end of the test event listener list, // after the default text output printer and the default XML report // generator. // // The order is important - it ensures that failures generated in the // leak checker's OnTestEnd() method are processed by the text and XML // printers *before* their OnTestEnd() methods are called, such that // they are attributed to the right test. Remember that a listener // receives an OnXyzStart event *after* listeners preceding it in the // list received that event, and receives an OnXyzEnd event *before* // listeners preceding it. // // We don't need to worry about deleting the new listener later, as // Google Test will do it. listeners.Append(new LeakChecker); } return RUN_ALL_TESTS(); } dlt-daemon-2.18.4/gtest-1.7.0/samples/sample1_unittest.cc000066400000000000000000000120111353342203500226700ustar00rootroot00000000000000// Copyright 2005, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // A sample program demonstrating using Google C++ testing framework. // // Author: wan@google.com (Zhanyong Wan) // This sample shows how to write a simple unit test for a function, // using Google C++ testing framework. // // Writing a unit test using Google C++ testing framework is easy as 1-2-3: // Step 1. Include necessary header files such that the stuff your // test logic needs is declared. // // Don't forget gtest.h, which declares the testing framework. #include #include "sample1.h" #include "gtest/gtest.h" // Step 2. Use the TEST macro to define your tests. // // TEST has two parameters: the test case name and the test name. // After using the macro, you should define your test logic between a // pair of braces. You can use a bunch of macros to indicate the // success or failure of a test. EXPECT_TRUE and EXPECT_EQ are // examples of such macros. For a complete list, see gtest.h. // // // // In Google Test, tests are grouped into test cases. This is how we // keep test code organized. You should put logically related tests // into the same test case. // // The test case name and the test name should both be valid C++ // identifiers. And you should not use underscore (_) in the names. // // Google Test guarantees that each test you define is run exactly // once, but it makes no guarantee on the order the tests are // executed. Therefore, you should write your tests in such a way // that their results don't depend on their order. // // // Tests Factorial(). // Tests factorial of negative numbers. TEST(FactorialTest, Negative) { // This test is named "Negative", and belongs to the "FactorialTest" // test case. EXPECT_EQ(1, Factorial(-5)); EXPECT_EQ(1, Factorial(-1)); EXPECT_GT(Factorial(-10), 0); // // // EXPECT_EQ(expected, actual) is the same as // // EXPECT_TRUE((expected) == (actual)) // // except that it will print both the expected value and the actual // value when the assertion fails. This is very helpful for // debugging. Therefore in this case EXPECT_EQ is preferred. // // On the other hand, EXPECT_TRUE accepts any Boolean expression, // and is thus more general. // // } // Tests factorial of 0. TEST(FactorialTest, Zero) { EXPECT_EQ(1, Factorial(0)); } // Tests factorial of positive numbers. TEST(FactorialTest, Positive) { EXPECT_EQ(1, Factorial(1)); EXPECT_EQ(2, Factorial(2)); EXPECT_EQ(6, Factorial(3)); EXPECT_EQ(40320, Factorial(8)); } // Tests IsPrime() // Tests negative input. TEST(IsPrimeTest, Negative) { // This test belongs to the IsPrimeTest test case. EXPECT_FALSE(IsPrime(-1)); EXPECT_FALSE(IsPrime(-2)); EXPECT_FALSE(IsPrime(INT_MIN)); } // Tests some trivial cases. TEST(IsPrimeTest, Trivial) { EXPECT_FALSE(IsPrime(0)); EXPECT_FALSE(IsPrime(1)); EXPECT_TRUE(IsPrime(2)); EXPECT_TRUE(IsPrime(3)); } // Tests positive input. TEST(IsPrimeTest, Positive) { EXPECT_FALSE(IsPrime(4)); EXPECT_TRUE(IsPrime(5)); EXPECT_FALSE(IsPrime(6)); EXPECT_TRUE(IsPrime(23)); } // Step 3. Call RUN_ALL_TESTS() in main(). // // We do this by linking in src/gtest_main.cc file, which consists of // a main() function which calls RUN_ALL_TESTS() for us. // // This runs all the tests you've defined, prints the result, and // returns 0 if successful, or 1 otherwise. // // Did you notice that we didn't register the tests? The // RUN_ALL_TESTS() macro magically knows about all the tests we // defined. Isn't this convenient? dlt-daemon-2.18.4/gtest-1.7.0/samples/sample2.cc000066400000000000000000000043721353342203500207450ustar00rootroot00000000000000// Copyright 2005, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // A sample program demonstrating using Google C++ testing framework. // // Author: wan@google.com (Zhanyong Wan) #include "sample2.h" #include // Clones a 0-terminated C string, allocating memory using new. const char* MyString::CloneCString(const char* a_c_string) { if (a_c_string == NULL) return NULL; const size_t len = strlen(a_c_string); char* const clone = new char[ len + 1 ]; memcpy(clone, a_c_string, len + 1); return clone; } // Sets the 0-terminated C string this MyString object // represents. void MyString::Set(const char* a_c_string) { // Makes sure this works when c_string == c_string_ const char* const temp = MyString::CloneCString(a_c_string); delete[] c_string_; c_string_ = temp; } dlt-daemon-2.18.4/gtest-1.7.0/samples/sample2.h000066400000000000000000000056761353342203500206170ustar00rootroot00000000000000// Copyright 2005, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // A sample program demonstrating using Google C++ testing framework. // // Author: wan@google.com (Zhanyong Wan) #ifndef GTEST_SAMPLES_SAMPLE2_H_ #define GTEST_SAMPLES_SAMPLE2_H_ #include // A simple string class. class MyString { private: const char* c_string_; const MyString& operator=(const MyString& rhs); public: // Clones a 0-terminated C string, allocating memory using new. static const char* CloneCString(const char* a_c_string); //////////////////////////////////////////////////////////// // // C'tors // The default c'tor constructs a NULL string. MyString() : c_string_(NULL) {} // Constructs a MyString by cloning a 0-terminated C string. explicit MyString(const char* a_c_string) : c_string_(NULL) { Set(a_c_string); } // Copy c'tor MyString(const MyString& string) : c_string_(NULL) { Set(string.c_string_); } //////////////////////////////////////////////////////////// // // D'tor. MyString is intended to be a final class, so the d'tor // doesn't need to be virtual. ~MyString() { delete[] c_string_; } // Gets the 0-terminated C string this MyString object represents. const char* c_string() const { return c_string_; } size_t Length() const { return c_string_ == NULL ? 0 : strlen(c_string_); } // Sets the 0-terminated C string this MyString object represents. void Set(const char* c_string); }; #endif // GTEST_SAMPLES_SAMPLE2_H_ dlt-daemon-2.18.4/gtest-1.7.0/samples/sample2.lo000066400000000000000000000004571353342203500207720ustar00rootroot00000000000000# samples/sample2.lo - a libtool object file # Generated by libtool (GNU libtool) 2.4.2 Debian-2.4.2-1ubuntu1 # # Please DO NOT delete this file! # It is necessary for linking the library. # Name of the PIC object. pic_object='.libs/sample2.o' # Name of the non-PIC object non_pic_object='sample2.o' dlt-daemon-2.18.4/gtest-1.7.0/samples/sample2.o000066400000000000000000000106201353342203500206070ustar00rootroot00000000000000ELF\ 4(WVS|$t- Wp4$ VWP[^_Ív1t&VS\$t$ ƅt R3[^uq)0}2intRWE)q0+L d,iq | q 0EL L E7 |E: | L E? | q G | ENJL17 nL%OU SetQe | Lw^^w'<W'Llen*:+?e{,%WU3@1[[W3LI"@5`]Rf|L%{ L 0b   7 !  % : ; I$ > $ >  I&I : ;  : ; I8 .?: ; nI<d I4 I .?: ; nI2 < .?: ; 2 <d.?: ; 2 <cd.?: ; nI2 <d.?: ; n2 <d I.G: ; @B: ; I U4: ; I4: ; I1.G: ; @dBI4: ; I .?: ;I<.?nI4< .?I4< &!.?n4<55<WP1v$+P+1SYePepVpqq18< samples/usr/lib/gcc/i686-redhat-linux/4.9.2/include/usr/includesample2.ccsample2.hstddef.hstring.h& \     " 09 CHQf |      ddlt-daemon-2.18.4/gtest-1.7.0/samples/sample2_unittest.cc000066400000000000000000000075261353342203500227100ustar00rootroot00000000000000// Copyright 2005, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // A sample program demonstrating using Google C++ testing framework. // // Author: wan@google.com (Zhanyong Wan) // This sample shows how to write a more complex unit test for a class // that has multiple member functions. // // Usually, it's a good idea to have one test for each method in your // class. You don't have to do that exactly, but it helps to keep // your tests organized. You may also throw in additional tests as // needed. #include "sample2.h" #include "gtest/gtest.h" // In this example, we test the MyString class (a simple string). // Tests the default c'tor. TEST(MyString, DefaultConstructor) { const MyString s; // Asserts that s.c_string() returns NULL. // // // // If we write NULL instead of // // static_cast(NULL) // // in this assertion, it will generate a warning on gcc 3.4. The // reason is that EXPECT_EQ needs to know the types of its // arguments in order to print them when it fails. Since NULL is // #defined as 0, the compiler will use the formatter function for // int to print it. However, gcc thinks that NULL should be used as // a pointer, not an int, and therefore complains. // // The root of the problem is C++'s lack of distinction between the // integer number 0 and the null pointer constant. Unfortunately, // we have to live with this fact. // // EXPECT_STREQ(NULL, s.c_string()); EXPECT_EQ(0u, s.Length()); } const char kHelloString[] = "Hello, world!"; // Tests the c'tor that accepts a C string. TEST(MyString, ConstructorFromCString) { const MyString s(kHelloString); EXPECT_EQ(0, strcmp(s.c_string(), kHelloString)); EXPECT_EQ(sizeof(kHelloString)/sizeof(kHelloString[0]) - 1, s.Length()); } // Tests the copy c'tor. TEST(MyString, CopyConstructor) { const MyString s1(kHelloString); const MyString s2 = s1; EXPECT_EQ(0, strcmp(s2.c_string(), kHelloString)); } // Tests the Set method. TEST(MyString, Set) { MyString s; s.Set(kHelloString); EXPECT_EQ(0, strcmp(s.c_string(), kHelloString)); // Set should work when the input pointer is the same as the one // already in the MyString object. s.Set(s.c_string()); EXPECT_EQ(0, strcmp(s.c_string(), kHelloString)); // Can we set the MyString to NULL? s.Set(NULL); EXPECT_STREQ(NULL, s.c_string()); } dlt-daemon-2.18.4/gtest-1.7.0/samples/sample3-inl.h000066400000000000000000000123651353342203500213710ustar00rootroot00000000000000// Copyright 2005, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // A sample program demonstrating using Google C++ testing framework. // // Author: wan@google.com (Zhanyong Wan) #ifndef GTEST_SAMPLES_SAMPLE3_INL_H_ #define GTEST_SAMPLES_SAMPLE3_INL_H_ #include // Queue is a simple queue implemented as a singled-linked list. // // The element type must support copy constructor. template // E is the element type class Queue; // QueueNode is a node in a Queue, which consists of an element of // type E and a pointer to the next node. template // E is the element type class QueueNode { friend class Queue; public: // Gets the element in this node. const E& element() const { return element_; } // Gets the next node in the queue. QueueNode* next() { return next_; } const QueueNode* next() const { return next_; } private: // Creates a node with a given element value. The next pointer is // set to NULL. explicit QueueNode(const E& an_element) : element_(an_element), next_(NULL) {} // We disable the default assignment operator and copy c'tor. const QueueNode& operator = (const QueueNode&); QueueNode(const QueueNode&); E element_; QueueNode* next_; }; template // E is the element type. class Queue { public: // Creates an empty queue. Queue() : head_(NULL), last_(NULL), size_(0) {} // D'tor. Clears the queue. ~Queue() { Clear(); } // Clears the queue. void Clear() { if (size_ > 0) { // 1. Deletes every node. QueueNode* node = head_; QueueNode* next = node->next(); for (; ;) { delete node; node = next; if (node == NULL) break; next = node->next(); } // 2. Resets the member variables. head_ = last_ = NULL; size_ = 0; } } // Gets the number of elements. size_t Size() const { return size_; } // Gets the first element of the queue, or NULL if the queue is empty. QueueNode* Head() { return head_; } const QueueNode* Head() const { return head_; } // Gets the last element of the queue, or NULL if the queue is empty. QueueNode* Last() { return last_; } const QueueNode* Last() const { return last_; } // Adds an element to the end of the queue. A copy of the element is // created using the copy constructor, and then stored in the queue. // Changes made to the element in the queue doesn't affect the source // object, and vice versa. void Enqueue(const E& element) { QueueNode* new_node = new QueueNode(element); if (size_ == 0) { head_ = last_ = new_node; size_ = 1; } else { last_->next_ = new_node; last_ = new_node; size_++; } } // Removes the head of the queue and returns it. Returns NULL if // the queue is empty. E* Dequeue() { if (size_ == 0) { return NULL; } const QueueNode* const old_head = head_; head_ = head_->next_; size_--; if (size_ == 0) { last_ = NULL; } E* element = new E(old_head->element()); delete old_head; return element; } // Applies a function/functor on each element of the queue, and // returns the result in a new queue. The original queue is not // affected. template Queue* Map(F function) const { Queue* new_queue = new Queue(); for (const QueueNode* node = head_; node != NULL; node = node->next_) { new_queue->Enqueue(function(node->element())); } return new_queue; } private: QueueNode* head_; // The first node of the queue. QueueNode* last_; // The last node of the queue. size_t size_; // The number of elements in the queue. // We disallow copying a queue. Queue(const Queue&); const Queue& operator = (const Queue&); }; #endif // GTEST_SAMPLES_SAMPLE3_INL_H_ dlt-daemon-2.18.4/gtest-1.7.0/samples/sample3_unittest.cc000066400000000000000000000123471353342203500227060ustar00rootroot00000000000000// Copyright 2005, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // A sample program demonstrating using Google C++ testing framework. // // Author: wan@google.com (Zhanyong Wan) // In this example, we use a more advanced feature of Google Test called // test fixture. // // A test fixture is a place to hold objects and functions shared by // all tests in a test case. Using a test fixture avoids duplicating // the test code necessary to initialize and cleanup those common // objects for each test. It is also useful for defining sub-routines // that your tests need to invoke a lot. // // // // The tests share the test fixture in the sense of code sharing, not // data sharing. Each test is given its own fresh copy of the // fixture. You cannot expect the data modified by one test to be // passed on to another test, which is a bad idea. // // The reason for this design is that tests should be independent and // repeatable. In particular, a test should not fail as the result of // another test's failure. If one test depends on info produced by // another test, then the two tests should really be one big test. // // The macros for indicating the success/failure of a test // (EXPECT_TRUE, FAIL, etc) need to know what the current test is // (when Google Test prints the test result, it tells you which test // each failure belongs to). Technically, these macros invoke a // member function of the Test class. Therefore, you cannot use them // in a global function. That's why you should put test sub-routines // in a test fixture. // // #include "sample3-inl.h" #include "gtest/gtest.h" // To use a test fixture, derive a class from testing::Test. class QueueTest : public testing::Test { protected: // You should make the members protected s.t. they can be // accessed from sub-classes. // virtual void SetUp() will be called before each test is run. You // should define it if you need to initialize the varaibles. // Otherwise, this can be skipped. virtual void SetUp() { q1_.Enqueue(1); q2_.Enqueue(2); q2_.Enqueue(3); } // virtual void TearDown() will be called after each test is run. // You should define it if there is cleanup work to do. Otherwise, // you don't have to provide it. // // virtual void TearDown() { // } // A helper function that some test uses. static int Double(int n) { return 2*n; } // A helper function for testing Queue::Map(). void MapTester(const Queue * q) { // Creates a new queue, where each element is twice as big as the // corresponding one in q. const Queue * const new_q = q->Map(Double); // Verifies that the new queue has the same size as q. ASSERT_EQ(q->Size(), new_q->Size()); // Verifies the relationship between the elements of the two queues. for ( const QueueNode * n1 = q->Head(), * n2 = new_q->Head(); n1 != NULL; n1 = n1->next(), n2 = n2->next() ) { EXPECT_EQ(2 * n1->element(), n2->element()); } delete new_q; } // Declares the variables your tests want to use. Queue q0_; Queue q1_; Queue q2_; }; // When you have a test fixture, you define a test using TEST_F // instead of TEST. // Tests the default c'tor. TEST_F(QueueTest, DefaultConstructor) { // You can access data in the test fixture here. EXPECT_EQ(0u, q0_.Size()); } // Tests Dequeue(). TEST_F(QueueTest, Dequeue) { int * n = q0_.Dequeue(); EXPECT_TRUE(n == NULL); n = q1_.Dequeue(); ASSERT_TRUE(n != NULL); EXPECT_EQ(1, *n); EXPECT_EQ(0u, q1_.Size()); delete n; n = q2_.Dequeue(); ASSERT_TRUE(n != NULL); EXPECT_EQ(2, *n); EXPECT_EQ(1u, q2_.Size()); delete n; } // Tests the Queue::Map() function. TEST_F(QueueTest, Map) { MapTester(&q0_); MapTester(&q1_); MapTester(&q2_); } dlt-daemon-2.18.4/gtest-1.7.0/samples/sample4.cc000066400000000000000000000036071353342203500207470ustar00rootroot00000000000000// Copyright 2005, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // A sample program demonstrating using Google C++ testing framework. // // Author: wan@google.com (Zhanyong Wan) #include #include "sample4.h" // Returns the current counter value, and increments it. int Counter::Increment() { return counter_++; } // Prints the current counter value to STDOUT. void Counter::Print() const { printf("%d", counter_); } dlt-daemon-2.18.4/gtest-1.7.0/samples/sample4.h000066400000000000000000000040431353342203500206040ustar00rootroot00000000000000// Copyright 2005, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // A sample program demonstrating using Google C++ testing framework. // // Author: wan@google.com (Zhanyong Wan) #ifndef GTEST_SAMPLES_SAMPLE4_H_ #define GTEST_SAMPLES_SAMPLE4_H_ // A simple monotonic counter. class Counter { private: int counter_; public: // Creates a counter that starts at 0. Counter() : counter_(0) {} // Returns the current counter value, and increments it. int Increment(); // Prints the current counter value to STDOUT. void Print() const; }; #endif // GTEST_SAMPLES_SAMPLE4_H_ dlt-daemon-2.18.4/gtest-1.7.0/samples/sample4.lo000066400000000000000000000004571353342203500207740ustar00rootroot00000000000000# samples/sample4.lo - a libtool object file # Generated by libtool (GNU libtool) 2.4.2 Debian-2.4.2-1ubuntu1 # # Please DO NOT delete this file! # It is necessary for linking the library. # Name of the PIC object. pic_object='.libs/sample4.o' # Name of the non-PIC object non_pic_object='sample4.o' dlt-daemon-2.18.4/gtest-1.7.0/samples/sample4.o000066400000000000000000000107401353342203500206140ustar00rootroot00000000000000ELF 4(T$H Ít&D$0h%dw'80!h.intf  7a6,o?{-Z[i CX  t  $ E( !, e0 > k4  Z8 [Z< z@ >D LF 9qG H H%L .T /X 0\ 1` 2%d c4Zh R6l . eekZ4  -  ' P&(ZP,/Z2  ' /<< ,Zpp# UkkjZ% : ; I$ > $ >   I : ;  : ; I8 : ;I8 : ; I !I/ &I : ; .?: ; 2 <dI4.?: ; nI2 <d.?: ; n2 <d.G: ; @dBI414: ; I?<.?: ;I<I' samples/usr/lib/gcc/i686-redhat-linux/4.9.2/include/usr/include/bits/usr/includesample4.ccstddef.htypes.hlibio.hsample4.hstdio.h&Ku[=_IO_buf_end__quad_t_old_offset_IO_save_endshort intsize_tsizetype_offsetCounter_IO_write_ptrlong long int_IO_buf_base_markers_IO_read_endIncrementPrintsamples/sample4.cc_locklong intprintf_cur_column_pos_sbuf_IO_FILEunsigned charsigned charlong long unsigned intunsigned int_IO_marker_shortbuf_IO_write_base_unused2_IO_read_ptrshort unsigned intchar_next__pad1__pad2__pad3__pad4__pad5GNU C++ 4.9.2 20150212 (Red Hat 4.9.2-6) -mtune=generic -march=i686 -g -O2long unsigned int_ZN7Counter9IncrementEv_IO_write_end__off64_t__off_t_chain_IO_backup_basestdin_flags2_mode_IO_read_base/home/user/projects/ascgit/ascgit003.dlt-daemon/build/gtest-1.7.0counter__vtable_offset_IO_save_base_fileno_ZNK7Counter5PrintEvthis_flagsstdout_IO_lock_tGCC: (GNU) 4.9.2 20150212 (Red Hat 4.9.2-6)zR|  0CFE H.symtab.strtab.shstrtab.rel.text.data.bss.text.unlikely.rodata.str1.1.rel.debug_info.debug_abbrev.rel.debug_aranges.rel.debug_line.debug_str.comment.note.GNU-stack.rel.eh_frame@' p%g+g0h?2hRkN 8^ Qp[ l  {  0I0c -  L    0@    $9sample4.cc_ZN7Counter9IncrementEv_ZNK7Counter5PrintEvprintf    ! & 3 : A H O V d k p {               ) 6 C P ] j w              . 5 A M Y        0 H[ gv    4dlt-daemon-2.18.4/gtest-1.7.0/samples/sample4_unittest.cc000066400000000000000000000035651353342203500227110ustar00rootroot00000000000000// Copyright 2005, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: wan@google.com (Zhanyong Wan) #include "gtest/gtest.h" #include "sample4.h" // Tests the Increment() method. TEST(Counter, Increment) { Counter c; // EXPECT_EQ() evaluates its arguments exactly once, so they // can have side effects. EXPECT_EQ(0, c.Increment()); EXPECT_EQ(1, c.Increment()); EXPECT_EQ(2, c.Increment()); } dlt-daemon-2.18.4/gtest-1.7.0/samples/sample5_unittest.cc000066400000000000000000000146761353342203500227170ustar00rootroot00000000000000// Copyright 2005, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: wan@google.com (Zhanyong Wan) // This sample teaches how to reuse a test fixture in multiple test // cases by deriving sub-fixtures from it. // // When you define a test fixture, you specify the name of the test // case that will use this fixture. Therefore, a test fixture can // be used by only one test case. // // Sometimes, more than one test cases may want to use the same or // slightly different test fixtures. For example, you may want to // make sure that all tests for a GUI library don't leak important // system resources like fonts and brushes. In Google Test, you do // this by putting the shared logic in a super (as in "super class") // test fixture, and then have each test case use a fixture derived // from this super fixture. #include #include #include "sample3-inl.h" #include "gtest/gtest.h" #include "sample1.h" // In this sample, we want to ensure that every test finishes within // ~5 seconds. If a test takes longer to run, we consider it a // failure. // // We put the code for timing a test in a test fixture called // "QuickTest". QuickTest is intended to be the super fixture that // other fixtures derive from, therefore there is no test case with // the name "QuickTest". This is OK. // // Later, we will derive multiple test fixtures from QuickTest. class QuickTest : public testing::Test { protected: // Remember that SetUp() is run immediately before a test starts. // This is a good place to record the start time. virtual void SetUp() { start_time_ = time(NULL); } // TearDown() is invoked immediately after a test finishes. Here we // check if the test was too slow. virtual void TearDown() { // Gets the time when the test finishes const time_t end_time = time(NULL); // Asserts that the test took no more than ~5 seconds. Did you // know that you can use assertions in SetUp() and TearDown() as // well? EXPECT_TRUE(end_time - start_time_ <= 5) << "The test took too long."; } // The UTC time (in seconds) when the test starts time_t start_time_; }; // We derive a fixture named IntegerFunctionTest from the QuickTest // fixture. All tests using this fixture will be automatically // required to be quick. class IntegerFunctionTest : public QuickTest { // We don't need any more logic than already in the QuickTest fixture. // Therefore the body is empty. }; // Now we can write tests in the IntegerFunctionTest test case. // Tests Factorial() TEST_F(IntegerFunctionTest, Factorial) { // Tests factorial of negative numbers. EXPECT_EQ(1, Factorial(-5)); EXPECT_EQ(1, Factorial(-1)); EXPECT_GT(Factorial(-10), 0); // Tests factorial of 0. EXPECT_EQ(1, Factorial(0)); // Tests factorial of positive numbers. EXPECT_EQ(1, Factorial(1)); EXPECT_EQ(2, Factorial(2)); EXPECT_EQ(6, Factorial(3)); EXPECT_EQ(40320, Factorial(8)); } // Tests IsPrime() TEST_F(IntegerFunctionTest, IsPrime) { // Tests negative input. EXPECT_FALSE(IsPrime(-1)); EXPECT_FALSE(IsPrime(-2)); EXPECT_FALSE(IsPrime(INT_MIN)); // Tests some trivial cases. EXPECT_FALSE(IsPrime(0)); EXPECT_FALSE(IsPrime(1)); EXPECT_TRUE(IsPrime(2)); EXPECT_TRUE(IsPrime(3)); // Tests positive input. EXPECT_FALSE(IsPrime(4)); EXPECT_TRUE(IsPrime(5)); EXPECT_FALSE(IsPrime(6)); EXPECT_TRUE(IsPrime(23)); } // The next test case (named "QueueTest") also needs to be quick, so // we derive another fixture from QuickTest. // // The QueueTest test fixture has some logic and shared objects in // addition to what's in QuickTest already. We define the additional // stuff inside the body of the test fixture, as usual. class QueueTest : public QuickTest { protected: virtual void SetUp() { // First, we need to set up the super fixture (QuickTest). QuickTest::SetUp(); // Second, some additional setup for this fixture. q1_.Enqueue(1); q2_.Enqueue(2); q2_.Enqueue(3); } // By default, TearDown() inherits the behavior of // QuickTest::TearDown(). As we have no additional cleaning work // for QueueTest, we omit it here. // // virtual void TearDown() { // QuickTest::TearDown(); // } Queue q0_; Queue q1_; Queue q2_; }; // Now, let's write tests using the QueueTest fixture. // Tests the default constructor. TEST_F(QueueTest, DefaultConstructor) { EXPECT_EQ(0u, q0_.Size()); } // Tests Dequeue(). TEST_F(QueueTest, Dequeue) { int* n = q0_.Dequeue(); EXPECT_TRUE(n == NULL); n = q1_.Dequeue(); EXPECT_TRUE(n != NULL); EXPECT_EQ(1, *n); EXPECT_EQ(0u, q1_.Size()); delete n; n = q2_.Dequeue(); EXPECT_TRUE(n != NULL); EXPECT_EQ(2, *n); EXPECT_EQ(1u, q2_.Size()); delete n; } // If necessary, you can derive further test fixtures from a derived // fixture itself. For example, you can derive another fixture from // QueueTest. Google Test imposes no limit on how deep the hierarchy // can be. In practice, however, you probably don't want it to be too // deep as to be confusing. dlt-daemon-2.18.4/gtest-1.7.0/samples/sample6_unittest.cc000066400000000000000000000214351353342203500227070ustar00rootroot00000000000000// Copyright 2008 Google Inc. // All Rights Reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: wan@google.com (Zhanyong Wan) // This sample shows how to test common properties of multiple // implementations of the same interface (aka interface tests). // The interface and its implementations are in this header. #include "prime_tables.h" #include "gtest/gtest.h" // First, we define some factory functions for creating instances of // the implementations. You may be able to skip this step if all your // implementations can be constructed the same way. template PrimeTable* CreatePrimeTable(); template <> PrimeTable* CreatePrimeTable() { return new OnTheFlyPrimeTable; } template <> PrimeTable* CreatePrimeTable() { return new PreCalculatedPrimeTable(10000); } // Then we define a test fixture class template. template class PrimeTableTest : public testing::Test { protected: // The ctor calls the factory function to create a prime table // implemented by T. PrimeTableTest() : table_(CreatePrimeTable()) {} virtual ~PrimeTableTest() { delete table_; } // Note that we test an implementation via the base interface // instead of the actual implementation class. This is important // for keeping the tests close to the real world scenario, where the // implementation is invoked via the base interface. It avoids // got-yas where the implementation class has a method that shadows // a method with the same name (but slightly different argument // types) in the base interface, for example. PrimeTable* const table_; }; #if GTEST_HAS_TYPED_TEST using testing::Types; // Google Test offers two ways for reusing tests for different types. // The first is called "typed tests". You should use it if you // already know *all* the types you are gonna exercise when you write // the tests. // To write a typed test case, first use // // TYPED_TEST_CASE(TestCaseName, TypeList); // // to declare it and specify the type parameters. As with TEST_F, // TestCaseName must match the test fixture name. // The list of types we want to test. typedef Types Implementations; TYPED_TEST_CASE(PrimeTableTest, Implementations); // Then use TYPED_TEST(TestCaseName, TestName) to define a typed test, // similar to TEST_F. TYPED_TEST(PrimeTableTest, ReturnsFalseForNonPrimes) { // Inside the test body, you can refer to the type parameter by // TypeParam, and refer to the fixture class by TestFixture. We // don't need them in this example. // Since we are in the template world, C++ requires explicitly // writing 'this->' when referring to members of the fixture class. // This is something you have to learn to live with. EXPECT_FALSE(this->table_->IsPrime(-5)); EXPECT_FALSE(this->table_->IsPrime(0)); EXPECT_FALSE(this->table_->IsPrime(1)); EXPECT_FALSE(this->table_->IsPrime(4)); EXPECT_FALSE(this->table_->IsPrime(6)); EXPECT_FALSE(this->table_->IsPrime(100)); } TYPED_TEST(PrimeTableTest, ReturnsTrueForPrimes) { EXPECT_TRUE(this->table_->IsPrime(2)); EXPECT_TRUE(this->table_->IsPrime(3)); EXPECT_TRUE(this->table_->IsPrime(5)); EXPECT_TRUE(this->table_->IsPrime(7)); EXPECT_TRUE(this->table_->IsPrime(11)); EXPECT_TRUE(this->table_->IsPrime(131)); } TYPED_TEST(PrimeTableTest, CanGetNextPrime) { EXPECT_EQ(2, this->table_->GetNextPrime(0)); EXPECT_EQ(3, this->table_->GetNextPrime(2)); EXPECT_EQ(5, this->table_->GetNextPrime(3)); EXPECT_EQ(7, this->table_->GetNextPrime(5)); EXPECT_EQ(11, this->table_->GetNextPrime(7)); EXPECT_EQ(131, this->table_->GetNextPrime(128)); } // That's it! Google Test will repeat each TYPED_TEST for each type // in the type list specified in TYPED_TEST_CASE. Sit back and be // happy that you don't have to define them multiple times. #endif // GTEST_HAS_TYPED_TEST #if GTEST_HAS_TYPED_TEST_P using testing::Types; // Sometimes, however, you don't yet know all the types that you want // to test when you write the tests. For example, if you are the // author of an interface and expect other people to implement it, you // might want to write a set of tests to make sure each implementation // conforms to some basic requirements, but you don't know what // implementations will be written in the future. // // How can you write the tests without committing to the type // parameters? That's what "type-parameterized tests" can do for you. // It is a bit more involved than typed tests, but in return you get a // test pattern that can be reused in many contexts, which is a big // win. Here's how you do it: // First, define a test fixture class template. Here we just reuse // the PrimeTableTest fixture defined earlier: template class PrimeTableTest2 : public PrimeTableTest { }; // Then, declare the test case. The argument is the name of the test // fixture, and also the name of the test case (as usual). The _P // suffix is for "parameterized" or "pattern". TYPED_TEST_CASE_P(PrimeTableTest2); // Next, use TYPED_TEST_P(TestCaseName, TestName) to define a test, // similar to what you do with TEST_F. TYPED_TEST_P(PrimeTableTest2, ReturnsFalseForNonPrimes) { EXPECT_FALSE(this->table_->IsPrime(-5)); EXPECT_FALSE(this->table_->IsPrime(0)); EXPECT_FALSE(this->table_->IsPrime(1)); EXPECT_FALSE(this->table_->IsPrime(4)); EXPECT_FALSE(this->table_->IsPrime(6)); EXPECT_FALSE(this->table_->IsPrime(100)); } TYPED_TEST_P(PrimeTableTest2, ReturnsTrueForPrimes) { EXPECT_TRUE(this->table_->IsPrime(2)); EXPECT_TRUE(this->table_->IsPrime(3)); EXPECT_TRUE(this->table_->IsPrime(5)); EXPECT_TRUE(this->table_->IsPrime(7)); EXPECT_TRUE(this->table_->IsPrime(11)); EXPECT_TRUE(this->table_->IsPrime(131)); } TYPED_TEST_P(PrimeTableTest2, CanGetNextPrime) { EXPECT_EQ(2, this->table_->GetNextPrime(0)); EXPECT_EQ(3, this->table_->GetNextPrime(2)); EXPECT_EQ(5, this->table_->GetNextPrime(3)); EXPECT_EQ(7, this->table_->GetNextPrime(5)); EXPECT_EQ(11, this->table_->GetNextPrime(7)); EXPECT_EQ(131, this->table_->GetNextPrime(128)); } // Type-parameterized tests involve one extra step: you have to // enumerate the tests you defined: REGISTER_TYPED_TEST_CASE_P( PrimeTableTest2, // The first argument is the test case name. // The rest of the arguments are the test names. ReturnsFalseForNonPrimes, ReturnsTrueForPrimes, CanGetNextPrime); // At this point the test pattern is done. However, you don't have // any real test yet as you haven't said which types you want to run // the tests with. // To turn the abstract test pattern into real tests, you instantiate // it with a list of types. Usually the test pattern will be defined // in a .h file, and anyone can #include and instantiate it. You can // even instantiate it more than once in the same program. To tell // different instances apart, you give each of them a name, which will // become part of the test case name and can be used in test filters. // The list of types we want to test. Note that it doesn't have to be // defined at the time we write the TYPED_TEST_P()s. typedef Types PrimeTableImplementations; INSTANTIATE_TYPED_TEST_CASE_P(OnTheFlyAndPreCalculated, // Instance name PrimeTableTest2, // Test case name PrimeTableImplementations); // Type list #endif // GTEST_HAS_TYPED_TEST_P dlt-daemon-2.18.4/gtest-1.7.0/samples/sample7_unittest.cc000066400000000000000000000117531353342203500227120ustar00rootroot00000000000000// Copyright 2008 Google Inc. // All Rights Reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: vladl@google.com (Vlad Losev) // This sample shows how to test common properties of multiple // implementations of an interface (aka interface tests) using // value-parameterized tests. Each test in the test case has // a parameter that is an interface pointer to an implementation // tested. // The interface and its implementations are in this header. #include "prime_tables.h" #include "gtest/gtest.h" #if GTEST_HAS_PARAM_TEST using ::testing::TestWithParam; using ::testing::Values; // As a general rule, to prevent a test from affecting the tests that come // after it, you should create and destroy the tested objects for each test // instead of reusing them. In this sample we will define a simple factory // function for PrimeTable objects. We will instantiate objects in test's // SetUp() method and delete them in TearDown() method. typedef PrimeTable* CreatePrimeTableFunc(); PrimeTable* CreateOnTheFlyPrimeTable() { return new OnTheFlyPrimeTable(); } template PrimeTable* CreatePreCalculatedPrimeTable() { return new PreCalculatedPrimeTable(max_precalculated); } // Inside the test body, fixture constructor, SetUp(), and TearDown() you // can refer to the test parameter by GetParam(). In this case, the test // parameter is a factory function which we call in fixture's SetUp() to // create and store an instance of PrimeTable. class PrimeTableTest : public TestWithParam { public: virtual ~PrimeTableTest() { delete table_; } virtual void SetUp() { table_ = (*GetParam())(); } virtual void TearDown() { delete table_; table_ = NULL; } protected: PrimeTable* table_; }; TEST_P(PrimeTableTest, ReturnsFalseForNonPrimes) { EXPECT_FALSE(table_->IsPrime(-5)); EXPECT_FALSE(table_->IsPrime(0)); EXPECT_FALSE(table_->IsPrime(1)); EXPECT_FALSE(table_->IsPrime(4)); EXPECT_FALSE(table_->IsPrime(6)); EXPECT_FALSE(table_->IsPrime(100)); } TEST_P(PrimeTableTest, ReturnsTrueForPrimes) { EXPECT_TRUE(table_->IsPrime(2)); EXPECT_TRUE(table_->IsPrime(3)); EXPECT_TRUE(table_->IsPrime(5)); EXPECT_TRUE(table_->IsPrime(7)); EXPECT_TRUE(table_->IsPrime(11)); EXPECT_TRUE(table_->IsPrime(131)); } TEST_P(PrimeTableTest, CanGetNextPrime) { EXPECT_EQ(2, table_->GetNextPrime(0)); EXPECT_EQ(3, table_->GetNextPrime(2)); EXPECT_EQ(5, table_->GetNextPrime(3)); EXPECT_EQ(7, table_->GetNextPrime(5)); EXPECT_EQ(11, table_->GetNextPrime(7)); EXPECT_EQ(131, table_->GetNextPrime(128)); } // In order to run value-parameterized tests, you need to instantiate them, // or bind them to a list of values which will be used as test parameters. // You can instantiate them in a different translation module, or even // instantiate them several times. // // Here, we instantiate our tests with a list of two PrimeTable object // factory functions: INSTANTIATE_TEST_CASE_P( OnTheFlyAndPreCalculated, PrimeTableTest, Values(&CreateOnTheFlyPrimeTable, &CreatePreCalculatedPrimeTable<1000>)); #else // Google Test may not support value-parameterized tests with some // compilers. If we use conditional compilation to compile out all // code referring to the gtest_main library, MSVC linker will not link // that library at all and consequently complain about missing entry // point defined in that library (fatal error LNK1561: entry point // must be defined). This dummy test keeps gtest_main linked in. TEST(DummyTest, ValueParameterizedTestsAreNotSupportedOnThisPlatform) {} #endif // GTEST_HAS_PARAM_TEST dlt-daemon-2.18.4/gtest-1.7.0/samples/sample8_unittest.cc000066400000000000000000000154401353342203500227100ustar00rootroot00000000000000// Copyright 2008 Google Inc. // All Rights Reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: vladl@google.com (Vlad Losev) // This sample shows how to test code relying on some global flag variables. // Combine() helps with generating all possible combinations of such flags, // and each test is given one combination as a parameter. // Use class definitions to test from this header. #include "prime_tables.h" #include "gtest/gtest.h" #if GTEST_HAS_COMBINE // Suppose we want to introduce a new, improved implementation of PrimeTable // which combines speed of PrecalcPrimeTable and versatility of // OnTheFlyPrimeTable (see prime_tables.h). Inside it instantiates both // PrecalcPrimeTable and OnTheFlyPrimeTable and uses the one that is more // appropriate under the circumstances. But in low memory conditions, it can be // told to instantiate without PrecalcPrimeTable instance at all and use only // OnTheFlyPrimeTable. class HybridPrimeTable : public PrimeTable { public: HybridPrimeTable(bool force_on_the_fly, int max_precalculated) : on_the_fly_impl_(new OnTheFlyPrimeTable), precalc_impl_(force_on_the_fly ? NULL : new PreCalculatedPrimeTable(max_precalculated)), max_precalculated_(max_precalculated) {} virtual ~HybridPrimeTable() { delete on_the_fly_impl_; delete precalc_impl_; } virtual bool IsPrime(int n) const { if (precalc_impl_ != NULL && n < max_precalculated_) return precalc_impl_->IsPrime(n); else return on_the_fly_impl_->IsPrime(n); } virtual int GetNextPrime(int p) const { int next_prime = -1; if (precalc_impl_ != NULL && p < max_precalculated_) next_prime = precalc_impl_->GetNextPrime(p); return next_prime != -1 ? next_prime : on_the_fly_impl_->GetNextPrime(p); } private: OnTheFlyPrimeTable* on_the_fly_impl_; PreCalculatedPrimeTable* precalc_impl_; int max_precalculated_; }; using ::testing::TestWithParam; using ::testing::Bool; using ::testing::Values; using ::testing::Combine; // To test all code paths for HybridPrimeTable we must test it with numbers // both within and outside PreCalculatedPrimeTable's capacity and also with // PreCalculatedPrimeTable disabled. We do this by defining fixture which will // accept different combinations of parameters for instantiating a // HybridPrimeTable instance. class PrimeTableTest : public TestWithParam< ::std::tr1::tuple > { protected: virtual void SetUp() { // This can be written as // // bool force_on_the_fly; // int max_precalculated; // tie(force_on_the_fly, max_precalculated) = GetParam(); // // once the Google C++ Style Guide allows use of ::std::tr1::tie. // bool force_on_the_fly = ::std::tr1::get<0>(GetParam()); int max_precalculated = ::std::tr1::get<1>(GetParam()); table_ = new HybridPrimeTable(force_on_the_fly, max_precalculated); } virtual void TearDown() { delete table_; table_ = NULL; } HybridPrimeTable* table_; }; TEST_P(PrimeTableTest, ReturnsFalseForNonPrimes) { // Inside the test body, you can refer to the test parameter by GetParam(). // In this case, the test parameter is a PrimeTable interface pointer which // we can use directly. // Please note that you can also save it in the fixture's SetUp() method // or constructor and use saved copy in the tests. EXPECT_FALSE(table_->IsPrime(-5)); EXPECT_FALSE(table_->IsPrime(0)); EXPECT_FALSE(table_->IsPrime(1)); EXPECT_FALSE(table_->IsPrime(4)); EXPECT_FALSE(table_->IsPrime(6)); EXPECT_FALSE(table_->IsPrime(100)); } TEST_P(PrimeTableTest, ReturnsTrueForPrimes) { EXPECT_TRUE(table_->IsPrime(2)); EXPECT_TRUE(table_->IsPrime(3)); EXPECT_TRUE(table_->IsPrime(5)); EXPECT_TRUE(table_->IsPrime(7)); EXPECT_TRUE(table_->IsPrime(11)); EXPECT_TRUE(table_->IsPrime(131)); } TEST_P(PrimeTableTest, CanGetNextPrime) { EXPECT_EQ(2, table_->GetNextPrime(0)); EXPECT_EQ(3, table_->GetNextPrime(2)); EXPECT_EQ(5, table_->GetNextPrime(3)); EXPECT_EQ(7, table_->GetNextPrime(5)); EXPECT_EQ(11, table_->GetNextPrime(7)); EXPECT_EQ(131, table_->GetNextPrime(128)); } // In order to run value-parameterized tests, you need to instantiate them, // or bind them to a list of values which will be used as test parameters. // You can instantiate them in a different translation module, or even // instantiate them several times. // // Here, we instantiate our tests with a list of parameters. We must combine // all variations of the boolean flag suppressing PrecalcPrimeTable and some // meaningful values for tests. We choose a small value (1), and a value that // will put some of the tested numbers beyond the capability of the // PrecalcPrimeTable instance and some inside it (10). Combine will produce all // possible combinations. INSTANTIATE_TEST_CASE_P(MeaningfulTestParameters, PrimeTableTest, Combine(Bool(), Values(1, 10))); #else // Google Test may not support Combine() with some compilers. If we // use conditional compilation to compile out all code referring to // the gtest_main library, MSVC linker will not link that library at // all and consequently complain about missing entry point defined in // that library (fatal error LNK1561: entry point must be // defined). This dummy test keeps gtest_main linked in. TEST(DummyTest, CombineIsNotSupportedOnThisPlatform) {} #endif // GTEST_HAS_COMBINE dlt-daemon-2.18.4/gtest-1.7.0/samples/sample9_unittest.cc000066400000000000000000000134771353342203500227210ustar00rootroot00000000000000// Copyright 2009 Google Inc. All Rights Reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: vladl@google.com (Vlad Losev) // This sample shows how to use Google Test listener API to implement // an alternative console output and how to use the UnitTest reflection API // to enumerate test cases and tests and to inspect their results. #include #include "gtest/gtest.h" using ::testing::EmptyTestEventListener; using ::testing::InitGoogleTest; using ::testing::Test; using ::testing::TestCase; using ::testing::TestEventListeners; using ::testing::TestInfo; using ::testing::TestPartResult; using ::testing::UnitTest; namespace { // Provides alternative output mode which produces minimal amount of // information about tests. class TersePrinter : public EmptyTestEventListener { private: // Called before any test activity starts. virtual void OnTestProgramStart(const UnitTest& /* unit_test */) {} // Called after all test activities have ended. virtual void OnTestProgramEnd(const UnitTest& unit_test) { fprintf(stdout, "TEST %s\n", unit_test.Passed() ? "PASSED" : "FAILED"); fflush(stdout); } // Called before a test starts. virtual void OnTestStart(const TestInfo& test_info) { fprintf(stdout, "*** Test %s.%s starting.\n", test_info.test_case_name(), test_info.name()); fflush(stdout); } // Called after a failed assertion or a SUCCEED() invocation. virtual void OnTestPartResult(const TestPartResult& test_part_result) { fprintf(stdout, "%s in %s:%d\n%s\n", test_part_result.failed() ? "*** Failure" : "Success", test_part_result.file_name(), test_part_result.line_number(), test_part_result.summary()); fflush(stdout); } // Called after a test ends. virtual void OnTestEnd(const TestInfo& test_info) { fprintf(stdout, "*** Test %s.%s ending.\n", test_info.test_case_name(), test_info.name()); fflush(stdout); } }; // class TersePrinter TEST(CustomOutputTest, PrintsMessage) { printf("Printing something from the test body...\n"); } TEST(CustomOutputTest, Succeeds) { SUCCEED() << "SUCCEED() has been invoked from here"; } TEST(CustomOutputTest, Fails) { EXPECT_EQ(1, 2) << "This test fails in order to demonstrate alternative failure messages"; } } // namespace int main(int argc, char **argv) { InitGoogleTest(&argc, argv); bool terse_output = false; if (argc > 1 && strcmp(argv[1], "--terse_output") == 0 ) terse_output = true; else printf("%s\n", "Run this program with --terse_output to change the way " "it prints its output."); UnitTest& unit_test = *UnitTest::GetInstance(); // If we are given the --terse_output command line flag, suppresses the // standard output and attaches own result printer. if (terse_output) { TestEventListeners& listeners = unit_test.listeners(); // Removes the default console output listener from the list so it will // not receive events from Google Test and won't print any output. Since // this operation transfers ownership of the listener to the caller we // have to delete it as well. delete listeners.Release(listeners.default_result_printer()); // Adds the custom output listener to the list. It will now receive // events from Google Test and print the alternative output. We don't // have to worry about deleting it since Google Test assumes ownership // over it after adding it to the list. listeners.Append(new TersePrinter); } int ret_val = RUN_ALL_TESTS(); // This is an example of using the UnitTest reflection API to inspect test // results. Here we discount failures from the tests we expected to fail. int unexpectedly_failed_tests = 0; for (int i = 0; i < unit_test.total_test_case_count(); ++i) { const TestCase& test_case = *unit_test.GetTestCase(i); for (int j = 0; j < test_case.total_test_count(); ++j) { const TestInfo& test_info = *test_case.GetTestInfo(j); // Counts failed tests that were not meant to fail (those without // 'Fails' in the name). if (test_info.result()->Failed() && strcmp(test_info.name(), "Fails") != 0) { unexpectedly_failed_tests++; } } } // Test that were meant to fail should not affect the test program outcome. if (unexpectedly_failed_tests == 0) ret_val = 0; return ret_val; } dlt-daemon-2.18.4/gtest-1.7.0/scripts/000077500000000000000000000000001353342203500171105ustar00rootroot00000000000000dlt-daemon-2.18.4/gtest-1.7.0/scripts/fuse_gtest_files.py000077500000000000000000000211551353342203500230230ustar00rootroot00000000000000#!/usr/bin/env python # # Copyright 2009, Google Inc. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above # copyright notice, this list of conditions and the following disclaimer # in the documentation and/or other materials provided with the # distribution. # * Neither the name of Google Inc. nor the names of its # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. """fuse_gtest_files.py v0.2.0 Fuses Google Test source code into a .h file and a .cc file. SYNOPSIS fuse_gtest_files.py [GTEST_ROOT_DIR] OUTPUT_DIR Scans GTEST_ROOT_DIR for Google Test source code, and generates two files: OUTPUT_DIR/gtest/gtest.h and OUTPUT_DIR/gtest/gtest-all.cc. Then you can build your tests by adding OUTPUT_DIR to the include search path and linking with OUTPUT_DIR/gtest/gtest-all.cc. These two files contain everything you need to use Google Test. Hence you can "install" Google Test by copying them to wherever you want. GTEST_ROOT_DIR can be omitted and defaults to the parent directory of the directory holding this script. EXAMPLES ./fuse_gtest_files.py fused_gtest ./fuse_gtest_files.py path/to/unpacked/gtest fused_gtest This tool is experimental. In particular, it assumes that there is no conditional inclusion of Google Test headers. Please report any problems to googletestframework@googlegroups.com. You can read http://code.google.com/p/googletest/wiki/GoogleTestAdvancedGuide for more information. """ __author__ = 'wan@google.com (Zhanyong Wan)' import os import re import sets import sys # We assume that this file is in the scripts/ directory in the Google # Test root directory. DEFAULT_GTEST_ROOT_DIR = os.path.join(os.path.dirname(__file__), '..') # Regex for matching '#include "gtest/..."'. INCLUDE_GTEST_FILE_REGEX = re.compile(r'^\s*#\s*include\s*"(gtest/.+)"') # Regex for matching '#include "src/..."'. INCLUDE_SRC_FILE_REGEX = re.compile(r'^\s*#\s*include\s*"(src/.+)"') # Where to find the source seed files. GTEST_H_SEED = 'include/gtest/gtest.h' GTEST_SPI_H_SEED = 'include/gtest/gtest-spi.h' GTEST_ALL_CC_SEED = 'src/gtest-all.cc' # Where to put the generated files. GTEST_H_OUTPUT = 'gtest/gtest.h' GTEST_ALL_CC_OUTPUT = 'gtest/gtest-all.cc' def VerifyFileExists(directory, relative_path): """Verifies that the given file exists; aborts on failure. relative_path is the file path relative to the given directory. """ if not os.path.isfile(os.path.join(directory, relative_path)): print 'ERROR: Cannot find %s in directory %s.' % (relative_path, directory) print ('Please either specify a valid project root directory ' 'or omit it on the command line.') sys.exit(1) def ValidateGTestRootDir(gtest_root): """Makes sure gtest_root points to a valid gtest root directory. The function aborts the program on failure. """ VerifyFileExists(gtest_root, GTEST_H_SEED) VerifyFileExists(gtest_root, GTEST_ALL_CC_SEED) def VerifyOutputFile(output_dir, relative_path): """Verifies that the given output file path is valid. relative_path is relative to the output_dir directory. """ # Makes sure the output file either doesn't exist or can be overwritten. output_file = os.path.join(output_dir, relative_path) if os.path.exists(output_file): # TODO(wan@google.com): The following user-interaction doesn't # work with automated processes. We should provide a way for the # Makefile to force overwriting the files. print ('%s already exists in directory %s - overwrite it? (y/N) ' % (relative_path, output_dir)) answer = sys.stdin.readline().strip() if answer not in ['y', 'Y']: print 'ABORTED.' sys.exit(1) # Makes sure the directory holding the output file exists; creates # it and all its ancestors if necessary. parent_directory = os.path.dirname(output_file) if not os.path.isdir(parent_directory): os.makedirs(parent_directory) def ValidateOutputDir(output_dir): """Makes sure output_dir points to a valid output directory. The function aborts the program on failure. """ VerifyOutputFile(output_dir, GTEST_H_OUTPUT) VerifyOutputFile(output_dir, GTEST_ALL_CC_OUTPUT) def FuseGTestH(gtest_root, output_dir): """Scans folder gtest_root to generate gtest/gtest.h in output_dir.""" output_file = file(os.path.join(output_dir, GTEST_H_OUTPUT), 'w') processed_files = sets.Set() # Holds all gtest headers we've processed. def ProcessFile(gtest_header_path): """Processes the given gtest header file.""" # We don't process the same header twice. if gtest_header_path in processed_files: return processed_files.add(gtest_header_path) # Reads each line in the given gtest header. for line in file(os.path.join(gtest_root, gtest_header_path), 'r'): m = INCLUDE_GTEST_FILE_REGEX.match(line) if m: # It's '#include "gtest/..."' - let's process it recursively. ProcessFile('include/' + m.group(1)) else: # Otherwise we copy the line unchanged to the output file. output_file.write(line) ProcessFile(GTEST_H_SEED) output_file.close() def FuseGTestAllCcToFile(gtest_root, output_file): """Scans folder gtest_root to generate gtest/gtest-all.cc in output_file.""" processed_files = sets.Set() def ProcessFile(gtest_source_file): """Processes the given gtest source file.""" # We don't process the same #included file twice. if gtest_source_file in processed_files: return processed_files.add(gtest_source_file) # Reads each line in the given gtest source file. for line in file(os.path.join(gtest_root, gtest_source_file), 'r'): m = INCLUDE_GTEST_FILE_REGEX.match(line) if m: if 'include/' + m.group(1) == GTEST_SPI_H_SEED: # It's '#include "gtest/gtest-spi.h"'. This file is not # #included by "gtest/gtest.h", so we need to process it. ProcessFile(GTEST_SPI_H_SEED) else: # It's '#include "gtest/foo.h"' where foo is not gtest-spi. # We treat it as '#include "gtest/gtest.h"', as all other # gtest headers are being fused into gtest.h and cannot be # #included directly. # There is no need to #include "gtest/gtest.h" more than once. if not GTEST_H_SEED in processed_files: processed_files.add(GTEST_H_SEED) output_file.write('#include "%s"\n' % (GTEST_H_OUTPUT,)) else: m = INCLUDE_SRC_FILE_REGEX.match(line) if m: # It's '#include "src/foo"' - let's process it recursively. ProcessFile(m.group(1)) else: output_file.write(line) ProcessFile(GTEST_ALL_CC_SEED) def FuseGTestAllCc(gtest_root, output_dir): """Scans folder gtest_root to generate gtest/gtest-all.cc in output_dir.""" output_file = file(os.path.join(output_dir, GTEST_ALL_CC_OUTPUT), 'w') FuseGTestAllCcToFile(gtest_root, output_file) output_file.close() def FuseGTest(gtest_root, output_dir): """Fuses gtest.h and gtest-all.cc.""" ValidateGTestRootDir(gtest_root) ValidateOutputDir(output_dir) FuseGTestH(gtest_root, output_dir) FuseGTestAllCc(gtest_root, output_dir) def main(): argc = len(sys.argv) if argc == 2: # fuse_gtest_files.py OUTPUT_DIR FuseGTest(DEFAULT_GTEST_ROOT_DIR, sys.argv[1]) elif argc == 3: # fuse_gtest_files.py GTEST_ROOT_DIR OUTPUT_DIR FuseGTest(sys.argv[1], sys.argv[2]) else: print __doc__ sys.exit(1) if __name__ == '__main__': main() dlt-daemon-2.18.4/gtest-1.7.0/scripts/gen_gtest_pred_impl.py000077500000000000000000000527421353342203500235110ustar00rootroot00000000000000#!/usr/bin/env python # # Copyright 2006, Google Inc. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above # copyright notice, this list of conditions and the following disclaimer # in the documentation and/or other materials provided with the # distribution. # * Neither the name of Google Inc. nor the names of its # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. """gen_gtest_pred_impl.py v0.1 Generates the implementation of Google Test predicate assertions and accompanying tests. Usage: gen_gtest_pred_impl.py MAX_ARITY where MAX_ARITY is a positive integer. The command generates the implementation of up-to MAX_ARITY-ary predicate assertions, and writes it to file gtest_pred_impl.h in the directory where the script is. It also generates the accompanying unit test in file gtest_pred_impl_unittest.cc. """ __author__ = 'wan@google.com (Zhanyong Wan)' import os import sys import time # Where this script is. SCRIPT_DIR = os.path.dirname(sys.argv[0]) # Where to store the generated header. HEADER = os.path.join(SCRIPT_DIR, '../include/gtest/gtest_pred_impl.h') # Where to store the generated unit test. UNIT_TEST = os.path.join(SCRIPT_DIR, '../test/gtest_pred_impl_unittest.cc') def HeaderPreamble(n): """Returns the preamble for the header file. Args: n: the maximum arity of the predicate macros to be generated. """ # A map that defines the values used in the preamble template. DEFS = { 'today' : time.strftime('%m/%d/%Y'), 'year' : time.strftime('%Y'), 'command' : '%s %s' % (os.path.basename(sys.argv[0]), n), 'n' : n } return ( """// Copyright 2006, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // This file is AUTOMATICALLY GENERATED on %(today)s by command // '%(command)s'. DO NOT EDIT BY HAND! // // Implements a family of generic predicate assertion macros. #ifndef GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_ #define GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_ // Makes sure this header is not included before gtest.h. #ifndef GTEST_INCLUDE_GTEST_GTEST_H_ # error Do not include gtest_pred_impl.h directly. Include gtest.h instead. #endif // GTEST_INCLUDE_GTEST_GTEST_H_ // This header implements a family of generic predicate assertion // macros: // // ASSERT_PRED_FORMAT1(pred_format, v1) // ASSERT_PRED_FORMAT2(pred_format, v1, v2) // ... // // where pred_format is a function or functor that takes n (in the // case of ASSERT_PRED_FORMATn) values and their source expression // text, and returns a testing::AssertionResult. See the definition // of ASSERT_EQ in gtest.h for an example. // // If you don't care about formatting, you can use the more // restrictive version: // // ASSERT_PRED1(pred, v1) // ASSERT_PRED2(pred, v1, v2) // ... // // where pred is an n-ary function or functor that returns bool, // and the values v1, v2, ..., must support the << operator for // streaming to std::ostream. // // We also define the EXPECT_* variations. // // For now we only support predicates whose arity is at most %(n)s. // Please email googletestframework@googlegroups.com if you need // support for higher arities. // GTEST_ASSERT_ is the basic statement to which all of the assertions // in this file reduce. Don't use this in your code. #define GTEST_ASSERT_(expression, on_failure) \\ GTEST_AMBIGUOUS_ELSE_BLOCKER_ \\ if (const ::testing::AssertionResult gtest_ar = (expression)) \\ ; \\ else \\ on_failure(gtest_ar.failure_message()) """ % DEFS) def Arity(n): """Returns the English name of the given arity.""" if n < 0: return None elif n <= 3: return ['nullary', 'unary', 'binary', 'ternary'][n] else: return '%s-ary' % n def Title(word): """Returns the given word in title case. The difference between this and string's title() method is that Title('4-ary') is '4-ary' while '4-ary'.title() is '4-Ary'.""" return word[0].upper() + word[1:] def OneTo(n): """Returns the list [1, 2, 3, ..., n].""" return range(1, n + 1) def Iter(n, format, sep=''): """Given a positive integer n, a format string that contains 0 or more '%s' format specs, and optionally a separator string, returns the join of n strings, each formatted with the format string on an iterator ranged from 1 to n. Example: Iter(3, 'v%s', sep=', ') returns 'v1, v2, v3'. """ # How many '%s' specs are in format? spec_count = len(format.split('%s')) - 1 return sep.join([format % (spec_count * (i,)) for i in OneTo(n)]) def ImplementationForArity(n): """Returns the implementation of n-ary predicate assertions.""" # A map the defines the values used in the implementation template. DEFS = { 'n' : str(n), 'vs' : Iter(n, 'v%s', sep=', '), 'vts' : Iter(n, '#v%s', sep=', '), 'arity' : Arity(n), 'Arity' : Title(Arity(n)) } impl = """ // Helper function for implementing {EXPECT|ASSERT}_PRED%(n)s. Don't use // this in your code. template AssertionResult AssertPred%(n)sHelper(const char* pred_text""" % DEFS impl += Iter(n, """, const char* e%s""") impl += """, Pred pred""" impl += Iter(n, """, const T%s& v%s""") impl += """) { if (pred(%(vs)s)) return AssertionSuccess(); """ % DEFS impl += ' return AssertionFailure() << pred_text << "("' impl += Iter(n, """ << e%s""", sep=' << ", "') impl += ' << ") evaluates to false, where"' impl += Iter(n, """ << "\\n" << e%s << " evaluates to " << v%s""") impl += """; } // Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT%(n)s. // Don't use this in your code. #define GTEST_PRED_FORMAT%(n)s_(pred_format, %(vs)s, on_failure)\\ GTEST_ASSERT_(pred_format(%(vts)s, %(vs)s), \\ on_failure) // Internal macro for implementing {EXPECT|ASSERT}_PRED%(n)s. Don't use // this in your code. #define GTEST_PRED%(n)s_(pred, %(vs)s, on_failure)\\ GTEST_ASSERT_(::testing::AssertPred%(n)sHelper(#pred""" % DEFS impl += Iter(n, """, \\ #v%s""") impl += """, \\ pred""" impl += Iter(n, """, \\ v%s""") impl += """), on_failure) // %(Arity)s predicate assertion macros. #define EXPECT_PRED_FORMAT%(n)s(pred_format, %(vs)s) \\ GTEST_PRED_FORMAT%(n)s_(pred_format, %(vs)s, GTEST_NONFATAL_FAILURE_) #define EXPECT_PRED%(n)s(pred, %(vs)s) \\ GTEST_PRED%(n)s_(pred, %(vs)s, GTEST_NONFATAL_FAILURE_) #define ASSERT_PRED_FORMAT%(n)s(pred_format, %(vs)s) \\ GTEST_PRED_FORMAT%(n)s_(pred_format, %(vs)s, GTEST_FATAL_FAILURE_) #define ASSERT_PRED%(n)s(pred, %(vs)s) \\ GTEST_PRED%(n)s_(pred, %(vs)s, GTEST_FATAL_FAILURE_) """ % DEFS return impl def HeaderPostamble(): """Returns the postamble for the header file.""" return """ #endif // GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_ """ def GenerateFile(path, content): """Given a file path and a content string, overwrites it with the given content.""" print 'Updating file %s . . .' % path f = file(path, 'w+') print >>f, content, f.close() print 'File %s has been updated.' % path def GenerateHeader(n): """Given the maximum arity n, updates the header file that implements the predicate assertions.""" GenerateFile(HEADER, HeaderPreamble(n) + ''.join([ImplementationForArity(i) for i in OneTo(n)]) + HeaderPostamble()) def UnitTestPreamble(): """Returns the preamble for the unit test file.""" # A map that defines the values used in the preamble template. DEFS = { 'today' : time.strftime('%m/%d/%Y'), 'year' : time.strftime('%Y'), 'command' : '%s %s' % (os.path.basename(sys.argv[0]), sys.argv[1]), } return ( """// Copyright 2006, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // This file is AUTOMATICALLY GENERATED on %(today)s by command // '%(command)s'. DO NOT EDIT BY HAND! // Regression test for gtest_pred_impl.h // // This file is generated by a script and quite long. If you intend to // learn how Google Test works by reading its unit tests, read // gtest_unittest.cc instead. // // This is intended as a regression test for the Google Test predicate // assertions. We compile it as part of the gtest_unittest target // only to keep the implementation tidy and compact, as it is quite // involved to set up the stage for testing Google Test using Google // Test itself. // // Currently, gtest_unittest takes ~11 seconds to run in the testing // daemon. In the future, if it grows too large and needs much more // time to finish, we should consider separating this file into a // stand-alone regression test. #include #include "gtest/gtest.h" #include "gtest/gtest-spi.h" // A user-defined data type. struct Bool { explicit Bool(int val) : value(val != 0) {} bool operator>(int n) const { return value > Bool(n).value; } Bool operator+(const Bool& rhs) const { return Bool(value + rhs.value); } bool operator==(const Bool& rhs) const { return value == rhs.value; } bool value; }; // Enables Bool to be used in assertions. std::ostream& operator<<(std::ostream& os, const Bool& x) { return os << (x.value ? "true" : "false"); } """ % DEFS) def TestsForArity(n): """Returns the tests for n-ary predicate assertions.""" # A map that defines the values used in the template for the tests. DEFS = { 'n' : n, 'es' : Iter(n, 'e%s', sep=', '), 'vs' : Iter(n, 'v%s', sep=', '), 'vts' : Iter(n, '#v%s', sep=', '), 'tvs' : Iter(n, 'T%s v%s', sep=', '), 'int_vs' : Iter(n, 'int v%s', sep=', '), 'Bool_vs' : Iter(n, 'Bool v%s', sep=', '), 'types' : Iter(n, 'typename T%s', sep=', '), 'v_sum' : Iter(n, 'v%s', sep=' + '), 'arity' : Arity(n), 'Arity' : Title(Arity(n)), } tests = ( """// Sample functions/functors for testing %(arity)s predicate assertions. // A %(arity)s predicate function. template <%(types)s> bool PredFunction%(n)s(%(tvs)s) { return %(v_sum)s > 0; } // The following two functions are needed to circumvent a bug in // gcc 2.95.3, which sometimes has problem with the above template // function. bool PredFunction%(n)sInt(%(int_vs)s) { return %(v_sum)s > 0; } bool PredFunction%(n)sBool(%(Bool_vs)s) { return %(v_sum)s > 0; } """ % DEFS) tests += """ // A %(arity)s predicate functor. struct PredFunctor%(n)s { template <%(types)s> bool operator()(""" % DEFS tests += Iter(n, 'const T%s& v%s', sep=""", """) tests += """) { return %(v_sum)s > 0; } }; """ % DEFS tests += """ // A %(arity)s predicate-formatter function. template <%(types)s> testing::AssertionResult PredFormatFunction%(n)s(""" % DEFS tests += Iter(n, 'const char* e%s', sep=""", """) tests += Iter(n, """, const T%s& v%s""") tests += """) { if (PredFunction%(n)s(%(vs)s)) return testing::AssertionSuccess(); return testing::AssertionFailure() << """ % DEFS tests += Iter(n, 'e%s', sep=' << " + " << ') tests += """ << " is expected to be positive, but evaluates to " << %(v_sum)s << "."; } """ % DEFS tests += """ // A %(arity)s predicate-formatter functor. struct PredFormatFunctor%(n)s { template <%(types)s> testing::AssertionResult operator()(""" % DEFS tests += Iter(n, 'const char* e%s', sep=""", """) tests += Iter(n, """, const T%s& v%s""") tests += """) const { return PredFormatFunction%(n)s(%(es)s, %(vs)s); } }; """ % DEFS tests += """ // Tests for {EXPECT|ASSERT}_PRED_FORMAT%(n)s. class Predicate%(n)sTest : public testing::Test { protected: virtual void SetUp() { expected_to_finish_ = true; finished_ = false;""" % DEFS tests += """ """ + Iter(n, 'n%s_ = ') + """0; } """ tests += """ virtual void TearDown() { // Verifies that each of the predicate's arguments was evaluated // exactly once.""" tests += ''.join([""" EXPECT_EQ(1, n%s_) << "The predicate assertion didn't evaluate argument %s " "exactly once.";""" % (i, i + 1) for i in OneTo(n)]) tests += """ // Verifies that the control flow in the test function is expected. if (expected_to_finish_ && !finished_) { FAIL() << "The predicate assertion unexpactedly aborted the test."; } else if (!expected_to_finish_ && finished_) { FAIL() << "The failed predicate assertion didn't abort the test " "as expected."; } } // true iff the test function is expected to run to finish. static bool expected_to_finish_; // true iff the test function did run to finish. static bool finished_; """ % DEFS tests += Iter(n, """ static int n%s_;""") tests += """ }; bool Predicate%(n)sTest::expected_to_finish_; bool Predicate%(n)sTest::finished_; """ % DEFS tests += Iter(n, """int Predicate%%(n)sTest::n%s_; """) % DEFS tests += """ typedef Predicate%(n)sTest EXPECT_PRED_FORMAT%(n)sTest; typedef Predicate%(n)sTest ASSERT_PRED_FORMAT%(n)sTest; typedef Predicate%(n)sTest EXPECT_PRED%(n)sTest; typedef Predicate%(n)sTest ASSERT_PRED%(n)sTest; """ % DEFS def GenTest(use_format, use_assert, expect_failure, use_functor, use_user_type): """Returns the test for a predicate assertion macro. Args: use_format: true iff the assertion is a *_PRED_FORMAT*. use_assert: true iff the assertion is a ASSERT_*. expect_failure: true iff the assertion is expected to fail. use_functor: true iff the first argument of the assertion is a functor (as opposed to a function) use_user_type: true iff the predicate functor/function takes argument(s) of a user-defined type. Example: GenTest(1, 0, 0, 1, 0) returns a test that tests the behavior of a successful EXPECT_PRED_FORMATn() that takes a functor whose arguments have built-in types.""" if use_assert: assrt = 'ASSERT' # 'assert' is reserved, so we cannot use # that identifier here. else: assrt = 'EXPECT' assertion = assrt + '_PRED' if use_format: pred_format = 'PredFormat' assertion += '_FORMAT' else: pred_format = 'Pred' assertion += '%(n)s' % DEFS if use_functor: pred_format_type = 'functor' pred_format += 'Functor%(n)s()' else: pred_format_type = 'function' pred_format += 'Function%(n)s' if not use_format: if use_user_type: pred_format += 'Bool' else: pred_format += 'Int' test_name = pred_format_type.title() if use_user_type: arg_type = 'user-defined type (Bool)' test_name += 'OnUserType' if expect_failure: arg = 'Bool(n%s_++)' else: arg = 'Bool(++n%s_)' else: arg_type = 'built-in type (int)' test_name += 'OnBuiltInType' if expect_failure: arg = 'n%s_++' else: arg = '++n%s_' if expect_failure: successful_or_failed = 'failed' expected_or_not = 'expected.' test_name += 'Failure' else: successful_or_failed = 'successful' expected_or_not = 'UNEXPECTED!' test_name += 'Success' # A map that defines the values used in the test template. defs = DEFS.copy() defs.update({ 'assert' : assrt, 'assertion' : assertion, 'test_name' : test_name, 'pf_type' : pred_format_type, 'pf' : pred_format, 'arg_type' : arg_type, 'arg' : arg, 'successful' : successful_or_failed, 'expected' : expected_or_not, }) test = """ // Tests a %(successful)s %(assertion)s where the // predicate-formatter is a %(pf_type)s on a %(arg_type)s. TEST_F(%(assertion)sTest, %(test_name)s) {""" % defs indent = (len(assertion) + 3)*' ' extra_indent = '' if expect_failure: extra_indent = ' ' if use_assert: test += """ expected_to_finish_ = false; EXPECT_FATAL_FAILURE({ // NOLINT""" else: test += """ EXPECT_NONFATAL_FAILURE({ // NOLINT""" test += '\n' + extra_indent + """ %(assertion)s(%(pf)s""" % defs test = test % defs test += Iter(n, ',\n' + indent + extra_indent + '%(arg)s' % defs) test += ');\n' + extra_indent + ' finished_ = true;\n' if expect_failure: test += ' }, "");\n' test += '}\n' return test # Generates tests for all 2**6 = 64 combinations. tests += ''.join([GenTest(use_format, use_assert, expect_failure, use_functor, use_user_type) for use_format in [0, 1] for use_assert in [0, 1] for expect_failure in [0, 1] for use_functor in [0, 1] for use_user_type in [0, 1] ]) return tests def UnitTestPostamble(): """Returns the postamble for the tests.""" return '' def GenerateUnitTest(n): """Returns the tests for up-to n-ary predicate assertions.""" GenerateFile(UNIT_TEST, UnitTestPreamble() + ''.join([TestsForArity(i) for i in OneTo(n)]) + UnitTestPostamble()) def _Main(): """The entry point of the script. Generates the header file and its unit test.""" if len(sys.argv) != 2: print __doc__ print 'Author: ' + __author__ sys.exit(1) n = int(sys.argv[1]) GenerateHeader(n) GenerateUnitTest(n) if __name__ == '__main__': _Main() dlt-daemon-2.18.4/gtest-1.7.0/scripts/gtest-config000077500000000000000000000234401353342203500214320ustar00rootroot00000000000000#!/bin/sh # These variables are automatically filled in by the configure script. name="gtest" version="1.7.0" show_usage() { echo "Usage: gtest-config [OPTIONS...]" } show_help() { show_usage cat <<\EOF The `gtest-config' script provides access to the necessary compile and linking flags to connect with Google C++ Testing Framework, both in a build prior to installation, and on the system proper after installation. The installation overrides may be issued in combination with any other queries, but will only affect installation queries if called on a built but not installed gtest. The installation queries may not be issued with any other types of queries, and only one installation query may be made at a time. The version queries and compiler flag queries may be combined as desired but not mixed. Different version queries are always combined with logical "and" semantics, and only the last of any particular query is used while all previous ones ignored. All versions must be specified as a sequence of numbers separated by periods. Compiler flag queries output the union of the sets of flags when combined. Examples: gtest-config --min-version=1.0 || echo "Insufficient Google Test version." g++ $(gtest-config --cppflags --cxxflags) -o foo.o -c foo.cpp g++ $(gtest-config --ldflags --libs) -o foo foo.o # When using a built but not installed Google Test: g++ $(../../my_gtest_build/scripts/gtest-config ...) ... # When using an installed Google Test, but with installation overrides: export GTEST_PREFIX="/opt" g++ $(gtest-config --libdir="/opt/lib64" ...) ... Help: --usage brief usage information --help display this help message Installation Overrides: --prefix= overrides the installation prefix --exec-prefix= overrides the executable installation prefix --libdir= overrides the library installation prefix --includedir= overrides the header file installation prefix Installation Queries: --prefix installation prefix --exec-prefix executable installation prefix --libdir library installation directory --includedir header file installation directory --version the version of the Google Test installation Version Queries: --min-version=VERSION return 0 if the version is at least VERSION --exact-version=VERSION return 0 if the version is exactly VERSION --max-version=VERSION return 0 if the version is at most VERSION Compilation Flag Queries: --cppflags compile flags specific to the C-like preprocessors --cxxflags compile flags appropriate for C++ programs --ldflags linker flags --libs libraries for linking EOF } # This function bounds our version with a min and a max. It uses some clever # POSIX-compliant variable expansion to portably do all the work in the shell # and avoid any dependency on a particular "sed" or "awk" implementation. # Notable is that it will only ever compare the first 3 components of versions. # Further components will be cleanly stripped off. All versions must be # unadorned, so "v1.0" will *not* work. The minimum version must be in $1, and # the max in $2. TODO(chandlerc@google.com): If this ever breaks, we should # investigate expanding this via autom4te from AS_VERSION_COMPARE rather than # continuing to maintain our own shell version. check_versions() { major_version=${version%%.*} minor_version="0" point_version="0" if test "${version#*.}" != "${version}"; then minor_version=${version#*.} minor_version=${minor_version%%.*} fi if test "${version#*.*.}" != "${version}"; then point_version=${version#*.*.} point_version=${point_version%%.*} fi min_version="$1" min_major_version=${min_version%%.*} min_minor_version="0" min_point_version="0" if test "${min_version#*.}" != "${min_version}"; then min_minor_version=${min_version#*.} min_minor_version=${min_minor_version%%.*} fi if test "${min_version#*.*.}" != "${min_version}"; then min_point_version=${min_version#*.*.} min_point_version=${min_point_version%%.*} fi max_version="$2" max_major_version=${max_version%%.*} max_minor_version="0" max_point_version="0" if test "${max_version#*.}" != "${max_version}"; then max_minor_version=${max_version#*.} max_minor_version=${max_minor_version%%.*} fi if test "${max_version#*.*.}" != "${max_version}"; then max_point_version=${max_version#*.*.} max_point_version=${max_point_version%%.*} fi test $(($major_version)) -lt $(($min_major_version)) && exit 1 if test $(($major_version)) -eq $(($min_major_version)); then test $(($minor_version)) -lt $(($min_minor_version)) && exit 1 if test $(($minor_version)) -eq $(($min_minor_version)); then test $(($point_version)) -lt $(($min_point_version)) && exit 1 fi fi test $(($major_version)) -gt $(($max_major_version)) && exit 1 if test $(($major_version)) -eq $(($max_major_version)); then test $(($minor_version)) -gt $(($max_minor_version)) && exit 1 if test $(($minor_version)) -eq $(($max_minor_version)); then test $(($point_version)) -gt $(($max_point_version)) && exit 1 fi fi exit 0 } # Show the usage line when no arguments are specified. if test $# -eq 0; then show_usage exit 1 fi while test $# -gt 0; do case $1 in --usage) show_usage; exit 0;; --help) show_help; exit 0;; # Installation overrides --prefix=*) GTEST_PREFIX=${1#--prefix=};; --exec-prefix=*) GTEST_EXEC_PREFIX=${1#--exec-prefix=};; --libdir=*) GTEST_LIBDIR=${1#--libdir=};; --includedir=*) GTEST_INCLUDEDIR=${1#--includedir=};; # Installation queries --prefix|--exec-prefix|--libdir|--includedir|--version) if test -n "${do_query}"; then show_usage exit 1 fi do_query=${1#--} ;; # Version checking --min-version=*) do_check_versions=yes min_version=${1#--min-version=} ;; --max-version=*) do_check_versions=yes max_version=${1#--max-version=} ;; --exact-version=*) do_check_versions=yes exact_version=${1#--exact-version=} ;; # Compiler flag output --cppflags) echo_cppflags=yes;; --cxxflags) echo_cxxflags=yes;; --ldflags) echo_ldflags=yes;; --libs) echo_libs=yes;; # Everything else is an error *) show_usage; exit 1;; esac shift done # These have defaults filled in by the configure script but can also be # overridden by environment variables or command line parameters. prefix="${GTEST_PREFIX:-/usr/local}" exec_prefix="${GTEST_EXEC_PREFIX:-${prefix}}" libdir="${GTEST_LIBDIR:-${exec_prefix}/lib}" includedir="${GTEST_INCLUDEDIR:-${prefix}/include}" # We try and detect if our binary is not located at its installed location. If # it's not, we provide variables pointing to the source and build tree rather # than to the install tree. This allows building against a just-built gtest # rather than an installed gtest. bindir="${exec_prefix}/bin" this_relative_bindir=`dirname $0` this_bindir=`cd ${this_relative_bindir}; pwd -P` if test "${this_bindir}" = "${this_bindir%${bindir}}"; then # The path to the script doesn't end in the bindir sequence from Autoconf, # assume that we are in a build tree. build_dir=`dirname ${this_bindir}` src_dir=`cd ${this_bindir}; cd ..; pwd -P` # TODO(chandlerc@google.com): This is a dangerous dependency on libtool, we # should work to remove it, and/or remove libtool altogether, replacing it # with direct references to the library and a link path. gtest_libs="${build_dir}/lib/libgtest.la -pthread " gtest_ldflags="" # We provide hooks to include from either the source or build dir, where the # build dir is always preferred. This will potentially allow us to write # build rules for generated headers and have them automatically be preferred # over provided versions. gtest_cppflags="-I${build_dir}/include -I${src_dir}/include" gtest_cxxflags="-pthread" else # We're using an installed gtest, although it may be staged under some # prefix. Assume (as our own libraries do) that we can resolve the prefix, # and are present in the dynamic link paths. gtest_ldflags="-L${libdir}" gtest_libs="-l${name} -pthread " gtest_cppflags="-I${includedir}" gtest_cxxflags="-pthread" fi # Do an installation query if requested. if test -n "$do_query"; then case $do_query in prefix) echo $prefix; exit 0;; exec-prefix) echo $exec_prefix; exit 0;; libdir) echo $libdir; exit 0;; includedir) echo $includedir; exit 0;; version) echo $version; exit 0;; *) show_usage; exit 1;; esac fi # Do a version check if requested. if test "$do_check_versions" = "yes"; then # Make sure we didn't receive a bad combination of parameters. test "$echo_cppflags" = "yes" && show_usage && exit 1 test "$echo_cxxflags" = "yes" && show_usage && exit 1 test "$echo_ldflags" = "yes" && show_usage && exit 1 test "$echo_libs" = "yes" && show_usage && exit 1 if test "$exact_version" != ""; then check_versions $exact_version $exact_version # unreachable else check_versions ${min_version:-0.0.0} ${max_version:-9999.9999.9999} # unreachable fi fi # Do the output in the correct order so that these can be used in-line of # a compiler invocation. output="" test "$echo_cppflags" = "yes" && output="$output $gtest_cppflags" test "$echo_cxxflags" = "yes" && output="$output $gtest_cxxflags" test "$echo_ldflags" = "yes" && output="$output $gtest_ldflags" test "$echo_libs" = "yes" && output="$output $gtest_libs" echo $output exit 0 dlt-daemon-2.18.4/gtest-1.7.0/scripts/gtest-config.in000077500000000000000000000235471353342203500220470ustar00rootroot00000000000000#!/bin/sh # These variables are automatically filled in by the configure script. name="@PACKAGE_TARNAME@" version="@PACKAGE_VERSION@" show_usage() { echo "Usage: gtest-config [OPTIONS...]" } show_help() { show_usage cat <<\EOF The `gtest-config' script provides access to the necessary compile and linking flags to connect with Google C++ Testing Framework, both in a build prior to installation, and on the system proper after installation. The installation overrides may be issued in combination with any other queries, but will only affect installation queries if called on a built but not installed gtest. The installation queries may not be issued with any other types of queries, and only one installation query may be made at a time. The version queries and compiler flag queries may be combined as desired but not mixed. Different version queries are always combined with logical "and" semantics, and only the last of any particular query is used while all previous ones ignored. All versions must be specified as a sequence of numbers separated by periods. Compiler flag queries output the union of the sets of flags when combined. Examples: gtest-config --min-version=1.0 || echo "Insufficient Google Test version." g++ $(gtest-config --cppflags --cxxflags) -o foo.o -c foo.cpp g++ $(gtest-config --ldflags --libs) -o foo foo.o # When using a built but not installed Google Test: g++ $(../../my_gtest_build/scripts/gtest-config ...) ... # When using an installed Google Test, but with installation overrides: export GTEST_PREFIX="/opt" g++ $(gtest-config --libdir="/opt/lib64" ...) ... Help: --usage brief usage information --help display this help message Installation Overrides: --prefix= overrides the installation prefix --exec-prefix= overrides the executable installation prefix --libdir= overrides the library installation prefix --includedir= overrides the header file installation prefix Installation Queries: --prefix installation prefix --exec-prefix executable installation prefix --libdir library installation directory --includedir header file installation directory --version the version of the Google Test installation Version Queries: --min-version=VERSION return 0 if the version is at least VERSION --exact-version=VERSION return 0 if the version is exactly VERSION --max-version=VERSION return 0 if the version is at most VERSION Compilation Flag Queries: --cppflags compile flags specific to the C-like preprocessors --cxxflags compile flags appropriate for C++ programs --ldflags linker flags --libs libraries for linking EOF } # This function bounds our version with a min and a max. It uses some clever # POSIX-compliant variable expansion to portably do all the work in the shell # and avoid any dependency on a particular "sed" or "awk" implementation. # Notable is that it will only ever compare the first 3 components of versions. # Further components will be cleanly stripped off. All versions must be # unadorned, so "v1.0" will *not* work. The minimum version must be in $1, and # the max in $2. TODO(chandlerc@google.com): If this ever breaks, we should # investigate expanding this via autom4te from AS_VERSION_COMPARE rather than # continuing to maintain our own shell version. check_versions() { major_version=${version%%.*} minor_version="0" point_version="0" if test "${version#*.}" != "${version}"; then minor_version=${version#*.} minor_version=${minor_version%%.*} fi if test "${version#*.*.}" != "${version}"; then point_version=${version#*.*.} point_version=${point_version%%.*} fi min_version="$1" min_major_version=${min_version%%.*} min_minor_version="0" min_point_version="0" if test "${min_version#*.}" != "${min_version}"; then min_minor_version=${min_version#*.} min_minor_version=${min_minor_version%%.*} fi if test "${min_version#*.*.}" != "${min_version}"; then min_point_version=${min_version#*.*.} min_point_version=${min_point_version%%.*} fi max_version="$2" max_major_version=${max_version%%.*} max_minor_version="0" max_point_version="0" if test "${max_version#*.}" != "${max_version}"; then max_minor_version=${max_version#*.} max_minor_version=${max_minor_version%%.*} fi if test "${max_version#*.*.}" != "${max_version}"; then max_point_version=${max_version#*.*.} max_point_version=${max_point_version%%.*} fi test $(($major_version)) -lt $(($min_major_version)) && exit 1 if test $(($major_version)) -eq $(($min_major_version)); then test $(($minor_version)) -lt $(($min_minor_version)) && exit 1 if test $(($minor_version)) -eq $(($min_minor_version)); then test $(($point_version)) -lt $(($min_point_version)) && exit 1 fi fi test $(($major_version)) -gt $(($max_major_version)) && exit 1 if test $(($major_version)) -eq $(($max_major_version)); then test $(($minor_version)) -gt $(($max_minor_version)) && exit 1 if test $(($minor_version)) -eq $(($max_minor_version)); then test $(($point_version)) -gt $(($max_point_version)) && exit 1 fi fi exit 0 } # Show the usage line when no arguments are specified. if test $# -eq 0; then show_usage exit 1 fi while test $# -gt 0; do case $1 in --usage) show_usage; exit 0;; --help) show_help; exit 0;; # Installation overrides --prefix=*) GTEST_PREFIX=${1#--prefix=};; --exec-prefix=*) GTEST_EXEC_PREFIX=${1#--exec-prefix=};; --libdir=*) GTEST_LIBDIR=${1#--libdir=};; --includedir=*) GTEST_INCLUDEDIR=${1#--includedir=};; # Installation queries --prefix|--exec-prefix|--libdir|--includedir|--version) if test -n "${do_query}"; then show_usage exit 1 fi do_query=${1#--} ;; # Version checking --min-version=*) do_check_versions=yes min_version=${1#--min-version=} ;; --max-version=*) do_check_versions=yes max_version=${1#--max-version=} ;; --exact-version=*) do_check_versions=yes exact_version=${1#--exact-version=} ;; # Compiler flag output --cppflags) echo_cppflags=yes;; --cxxflags) echo_cxxflags=yes;; --ldflags) echo_ldflags=yes;; --libs) echo_libs=yes;; # Everything else is an error *) show_usage; exit 1;; esac shift done # These have defaults filled in by the configure script but can also be # overridden by environment variables or command line parameters. prefix="${GTEST_PREFIX:-@prefix@}" exec_prefix="${GTEST_EXEC_PREFIX:-@exec_prefix@}" libdir="${GTEST_LIBDIR:-@libdir@}" includedir="${GTEST_INCLUDEDIR:-@includedir@}" # We try and detect if our binary is not located at its installed location. If # it's not, we provide variables pointing to the source and build tree rather # than to the install tree. This allows building against a just-built gtest # rather than an installed gtest. bindir="@bindir@" this_relative_bindir=`dirname $0` this_bindir=`cd ${this_relative_bindir}; pwd -P` if test "${this_bindir}" = "${this_bindir%${bindir}}"; then # The path to the script doesn't end in the bindir sequence from Autoconf, # assume that we are in a build tree. build_dir=`dirname ${this_bindir}` src_dir=`cd ${this_bindir}; cd @top_srcdir@; pwd -P` # TODO(chandlerc@google.com): This is a dangerous dependency on libtool, we # should work to remove it, and/or remove libtool altogether, replacing it # with direct references to the library and a link path. gtest_libs="${build_dir}/lib/libgtest.la @PTHREAD_CFLAGS@ @PTHREAD_LIBS@" gtest_ldflags="" # We provide hooks to include from either the source or build dir, where the # build dir is always preferred. This will potentially allow us to write # build rules for generated headers and have them automatically be preferred # over provided versions. gtest_cppflags="-I${build_dir}/include -I${src_dir}/include" gtest_cxxflags="@PTHREAD_CFLAGS@" else # We're using an installed gtest, although it may be staged under some # prefix. Assume (as our own libraries do) that we can resolve the prefix, # and are present in the dynamic link paths. gtest_ldflags="-L${libdir}" gtest_libs="-l${name} @PTHREAD_CFLAGS@ @PTHREAD_LIBS@" gtest_cppflags="-I${includedir}" gtest_cxxflags="@PTHREAD_CFLAGS@" fi # Do an installation query if requested. if test -n "$do_query"; then case $do_query in prefix) echo $prefix; exit 0;; exec-prefix) echo $exec_prefix; exit 0;; libdir) echo $libdir; exit 0;; includedir) echo $includedir; exit 0;; version) echo $version; exit 0;; *) show_usage; exit 1;; esac fi # Do a version check if requested. if test "$do_check_versions" = "yes"; then # Make sure we didn't receive a bad combination of parameters. test "$echo_cppflags" = "yes" && show_usage && exit 1 test "$echo_cxxflags" = "yes" && show_usage && exit 1 test "$echo_ldflags" = "yes" && show_usage && exit 1 test "$echo_libs" = "yes" && show_usage && exit 1 if test "$exact_version" != ""; then check_versions $exact_version $exact_version # unreachable else check_versions ${min_version:-0.0.0} ${max_version:-9999.9999.9999} # unreachable fi fi # Do the output in the correct order so that these can be used in-line of # a compiler invocation. output="" test "$echo_cppflags" = "yes" && output="$output $gtest_cppflags" test "$echo_cxxflags" = "yes" && output="$output $gtest_cxxflags" test "$echo_ldflags" = "yes" && output="$output $gtest_ldflags" test "$echo_libs" = "yes" && output="$output $gtest_libs" echo $output exit 0 dlt-daemon-2.18.4/gtest-1.7.0/scripts/pump.py000077500000000000000000000561711353342203500204600ustar00rootroot00000000000000#!/usr/bin/env python # # 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. """pump v0.2.0 - Pretty Useful for Meta Programming. A tool for preprocessor meta programming. Useful for generating repetitive boilerplate code. Especially useful for writing C++ classes, functions, macros, and templates that need to work with various number of arguments. USAGE: pump.py SOURCE_FILE EXAMPLES: pump.py foo.cc.pump Converts foo.cc.pump to foo.cc. GRAMMAR: CODE ::= ATOMIC_CODE* ATOMIC_CODE ::= $var ID = EXPRESSION | $var ID = [[ CODE ]] | $range ID EXPRESSION..EXPRESSION | $for ID SEPARATOR [[ CODE ]] | $($) | $ID | $(EXPRESSION) | $if EXPRESSION [[ CODE ]] ELSE_BRANCH | [[ CODE ]] | RAW_CODE SEPARATOR ::= RAW_CODE | EMPTY ELSE_BRANCH ::= $else [[ CODE ]] | $elif EXPRESSION [[ CODE ]] ELSE_BRANCH | EMPTY EXPRESSION has Python syntax. """ __author__ = 'wan@google.com (Zhanyong Wan)' import os import re import sys TOKEN_TABLE = [ (re.compile(r'\$var\s+'), '$var'), (re.compile(r'\$elif\s+'), '$elif'), (re.compile(r'\$else\s+'), '$else'), (re.compile(r'\$for\s+'), '$for'), (re.compile(r'\$if\s+'), '$if'), (re.compile(r'\$range\s+'), '$range'), (re.compile(r'\$[_A-Za-z]\w*'), '$id'), (re.compile(r'\$\(\$\)'), '$($)'), (re.compile(r'\$'), '$'), (re.compile(r'\[\[\n?'), '[['), (re.compile(r'\]\]\n?'), ']]'), ] class Cursor: """Represents a position (line and column) in a text file.""" def __init__(self, line=-1, column=-1): self.line = line self.column = column def __eq__(self, rhs): return self.line == rhs.line and self.column == rhs.column def __ne__(self, rhs): return not self == rhs def __lt__(self, rhs): return self.line < rhs.line or ( self.line == rhs.line and self.column < rhs.column) def __le__(self, rhs): return self < rhs or self == rhs def __gt__(self, rhs): return rhs < self def __ge__(self, rhs): return rhs <= self def __str__(self): if self == Eof(): return 'EOF' else: return '%s(%s)' % (self.line + 1, self.column) def __add__(self, offset): return Cursor(self.line, self.column + offset) def __sub__(self, offset): return Cursor(self.line, self.column - offset) def Clone(self): """Returns a copy of self.""" return Cursor(self.line, self.column) # Special cursor to indicate the end-of-file. def Eof(): """Returns the special cursor to denote the end-of-file.""" return Cursor(-1, -1) class Token: """Represents a token in a Pump source file.""" def __init__(self, start=None, end=None, value=None, token_type=None): if start is None: self.start = Eof() else: self.start = start if end is None: self.end = Eof() else: self.end = end self.value = value self.token_type = token_type def __str__(self): return 'Token @%s: \'%s\' type=%s' % ( self.start, self.value, self.token_type) def Clone(self): """Returns a copy of self.""" return Token(self.start.Clone(), self.end.Clone(), self.value, self.token_type) def StartsWith(lines, pos, string): """Returns True iff the given position in lines starts with 'string'.""" return lines[pos.line][pos.column:].startswith(string) def FindFirstInLine(line, token_table): best_match_start = -1 for (regex, token_type) in token_table: m = regex.search(line) if m: # We found regex in lines if best_match_start < 0 or m.start() < best_match_start: best_match_start = m.start() best_match_length = m.end() - m.start() best_match_token_type = token_type if best_match_start < 0: return None return (best_match_start, best_match_length, best_match_token_type) def FindFirst(lines, token_table, cursor): """Finds the first occurrence of any string in strings in lines.""" start = cursor.Clone() cur_line_number = cursor.line for line in lines[start.line:]: if cur_line_number == start.line: line = line[start.column:] m = FindFirstInLine(line, token_table) if m: # We found a regex in line. (start_column, length, token_type) = m if cur_line_number == start.line: start_column += start.column found_start = Cursor(cur_line_number, start_column) found_end = found_start + length return MakeToken(lines, found_start, found_end, token_type) cur_line_number += 1 # We failed to find str in lines return None def SubString(lines, start, end): """Returns a substring in lines.""" if end == Eof(): end = Cursor(len(lines) - 1, len(lines[-1])) if start >= end: return '' if start.line == end.line: return lines[start.line][start.column:end.column] result_lines = ([lines[start.line][start.column:]] + lines[start.line + 1:end.line] + [lines[end.line][:end.column]]) return ''.join(result_lines) def StripMetaComments(str): """Strip meta comments from each line in the given string.""" # First, completely remove lines containing nothing but a meta # comment, including the trailing \n. str = re.sub(r'^\s*\$\$.*\n', '', str) # Then, remove meta comments from contentful lines. return re.sub(r'\s*\$\$.*', '', str) def MakeToken(lines, start, end, token_type): """Creates a new instance of Token.""" return Token(start, end, SubString(lines, start, end), token_type) def ParseToken(lines, pos, regex, token_type): line = lines[pos.line][pos.column:] m = regex.search(line) if m and not m.start(): return MakeToken(lines, pos, pos + m.end(), token_type) else: print 'ERROR: %s expected at %s.' % (token_type, pos) sys.exit(1) ID_REGEX = re.compile(r'[_A-Za-z]\w*') EQ_REGEX = re.compile(r'=') REST_OF_LINE_REGEX = re.compile(r'.*?(?=$|\$\$)') OPTIONAL_WHITE_SPACES_REGEX = re.compile(r'\s*') WHITE_SPACE_REGEX = re.compile(r'\s') DOT_DOT_REGEX = re.compile(r'\.\.') def Skip(lines, pos, regex): line = lines[pos.line][pos.column:] m = re.search(regex, line) if m and not m.start(): return pos + m.end() else: return pos def SkipUntil(lines, pos, regex, token_type): line = lines[pos.line][pos.column:] m = re.search(regex, line) if m: return pos + m.start() else: print ('ERROR: %s expected on line %s after column %s.' % (token_type, pos.line + 1, pos.column)) sys.exit(1) def ParseExpTokenInParens(lines, pos): def ParseInParens(pos): pos = Skip(lines, pos, OPTIONAL_WHITE_SPACES_REGEX) pos = Skip(lines, pos, r'\(') pos = Parse(pos) pos = Skip(lines, pos, r'\)') return pos def Parse(pos): pos = SkipUntil(lines, pos, r'\(|\)', ')') if SubString(lines, pos, pos + 1) == '(': pos = Parse(pos + 1) pos = Skip(lines, pos, r'\)') return Parse(pos) else: return pos start = pos.Clone() pos = ParseInParens(pos) return MakeToken(lines, start, pos, 'exp') def RStripNewLineFromToken(token): if token.value.endswith('\n'): return Token(token.start, token.end, token.value[:-1], token.token_type) else: return token def TokenizeLines(lines, pos): while True: found = FindFirst(lines, TOKEN_TABLE, pos) if not found: yield MakeToken(lines, pos, Eof(), 'code') return if found.start == pos: prev_token = None prev_token_rstripped = None else: prev_token = MakeToken(lines, pos, found.start, 'code') prev_token_rstripped = RStripNewLineFromToken(prev_token) if found.token_type == '$var': if prev_token_rstripped: yield prev_token_rstripped yield found id_token = ParseToken(lines, found.end, ID_REGEX, 'id') yield id_token pos = Skip(lines, id_token.end, OPTIONAL_WHITE_SPACES_REGEX) eq_token = ParseToken(lines, pos, EQ_REGEX, '=') yield eq_token pos = Skip(lines, eq_token.end, r'\s*') if SubString(lines, pos, pos + 2) != '[[': exp_token = ParseToken(lines, pos, REST_OF_LINE_REGEX, 'exp') yield exp_token pos = Cursor(exp_token.end.line + 1, 0) elif found.token_type == '$for': if prev_token_rstripped: yield prev_token_rstripped yield found id_token = ParseToken(lines, found.end, ID_REGEX, 'id') yield id_token pos = Skip(lines, id_token.end, WHITE_SPACE_REGEX) elif found.token_type == '$range': if prev_token_rstripped: yield prev_token_rstripped yield found id_token = ParseToken(lines, found.end, ID_REGEX, 'id') yield id_token pos = Skip(lines, id_token.end, OPTIONAL_WHITE_SPACES_REGEX) dots_pos = SkipUntil(lines, pos, DOT_DOT_REGEX, '..') yield MakeToken(lines, pos, dots_pos, 'exp') yield MakeToken(lines, dots_pos, dots_pos + 2, '..') pos = dots_pos + 2 new_pos = Cursor(pos.line + 1, 0) yield MakeToken(lines, pos, new_pos, 'exp') pos = new_pos elif found.token_type == '$': if prev_token: yield prev_token yield found exp_token = ParseExpTokenInParens(lines, found.end) yield exp_token pos = exp_token.end elif (found.token_type == ']]' or found.token_type == '$if' or found.token_type == '$elif' or found.token_type == '$else'): if prev_token_rstripped: yield prev_token_rstripped yield found pos = found.end else: if prev_token: yield prev_token yield found pos = found.end def Tokenize(s): """A generator that yields the tokens in the given string.""" if s != '': lines = s.splitlines(True) for token in TokenizeLines(lines, Cursor(0, 0)): yield token class CodeNode: def __init__(self, atomic_code_list=None): self.atomic_code = atomic_code_list class VarNode: def __init__(self, identifier=None, atomic_code=None): self.identifier = identifier self.atomic_code = atomic_code class RangeNode: def __init__(self, identifier=None, exp1=None, exp2=None): self.identifier = identifier self.exp1 = exp1 self.exp2 = exp2 class ForNode: def __init__(self, identifier=None, sep=None, code=None): self.identifier = identifier self.sep = sep self.code = code class ElseNode: def __init__(self, else_branch=None): self.else_branch = else_branch class IfNode: def __init__(self, exp=None, then_branch=None, else_branch=None): self.exp = exp self.then_branch = then_branch self.else_branch = else_branch class RawCodeNode: def __init__(self, token=None): self.raw_code = token class LiteralDollarNode: def __init__(self, token): self.token = token class ExpNode: def __init__(self, token, python_exp): self.token = token self.python_exp = python_exp def PopFront(a_list): head = a_list[0] a_list[:1] = [] return head def PushFront(a_list, elem): a_list[:0] = [elem] def PopToken(a_list, token_type=None): token = PopFront(a_list) if token_type is not None and token.token_type != token_type: print 'ERROR: %s expected at %s' % (token_type, token.start) print 'ERROR: %s found instead' % (token,) sys.exit(1) return token def PeekToken(a_list): if not a_list: return None return a_list[0] def ParseExpNode(token): python_exp = re.sub(r'([_A-Za-z]\w*)', r'self.GetValue("\1")', token.value) return ExpNode(token, python_exp) def ParseElseNode(tokens): def Pop(token_type=None): return PopToken(tokens, token_type) next = PeekToken(tokens) if not next: return None if next.token_type == '$else': Pop('$else') Pop('[[') code_node = ParseCodeNode(tokens) Pop(']]') return code_node elif next.token_type == '$elif': Pop('$elif') exp = Pop('code') Pop('[[') code_node = ParseCodeNode(tokens) Pop(']]') inner_else_node = ParseElseNode(tokens) return CodeNode([IfNode(ParseExpNode(exp), code_node, inner_else_node)]) elif not next.value.strip(): Pop('code') return ParseElseNode(tokens) else: return None def ParseAtomicCodeNode(tokens): def Pop(token_type=None): return PopToken(tokens, token_type) head = PopFront(tokens) t = head.token_type if t == 'code': return RawCodeNode(head) elif t == '$var': id_token = Pop('id') Pop('=') next = PeekToken(tokens) if next.token_type == 'exp': exp_token = Pop() return VarNode(id_token, ParseExpNode(exp_token)) Pop('[[') code_node = ParseCodeNode(tokens) Pop(']]') return VarNode(id_token, code_node) elif t == '$for': id_token = Pop('id') next_token = PeekToken(tokens) if next_token.token_type == 'code': sep_token = next_token Pop('code') else: sep_token = None Pop('[[') code_node = ParseCodeNode(tokens) Pop(']]') return ForNode(id_token, sep_token, code_node) elif t == '$if': exp_token = Pop('code') Pop('[[') code_node = ParseCodeNode(tokens) Pop(']]') else_node = ParseElseNode(tokens) return IfNode(ParseExpNode(exp_token), code_node, else_node) elif t == '$range': id_token = Pop('id') exp1_token = Pop('exp') Pop('..') exp2_token = Pop('exp') return RangeNode(id_token, ParseExpNode(exp1_token), ParseExpNode(exp2_token)) elif t == '$id': return ParseExpNode(Token(head.start + 1, head.end, head.value[1:], 'id')) elif t == '$($)': return LiteralDollarNode(head) elif t == '$': exp_token = Pop('exp') return ParseExpNode(exp_token) elif t == '[[': code_node = ParseCodeNode(tokens) Pop(']]') return code_node else: PushFront(tokens, head) return None def ParseCodeNode(tokens): atomic_code_list = [] while True: if not tokens: break atomic_code_node = ParseAtomicCodeNode(tokens) if atomic_code_node: atomic_code_list.append(atomic_code_node) else: break return CodeNode(atomic_code_list) def ParseToAST(pump_src_text): """Convert the given Pump source text into an AST.""" tokens = list(Tokenize(pump_src_text)) code_node = ParseCodeNode(tokens) return code_node class Env: def __init__(self): self.variables = [] self.ranges = [] def Clone(self): clone = Env() clone.variables = self.variables[:] clone.ranges = self.ranges[:] return clone def PushVariable(self, var, value): # If value looks like an int, store it as an int. try: int_value = int(value) if ('%s' % int_value) == value: value = int_value except Exception: pass self.variables[:0] = [(var, value)] def PopVariable(self): self.variables[:1] = [] def PushRange(self, var, lower, upper): self.ranges[:0] = [(var, lower, upper)] def PopRange(self): self.ranges[:1] = [] def GetValue(self, identifier): for (var, value) in self.variables: if identifier == var: return value print 'ERROR: meta variable %s is undefined.' % (identifier,) sys.exit(1) def EvalExp(self, exp): try: result = eval(exp.python_exp) except Exception, e: print 'ERROR: caught exception %s: %s' % (e.__class__.__name__, e) print ('ERROR: failed to evaluate meta expression %s at %s' % (exp.python_exp, exp.token.start)) sys.exit(1) return result def GetRange(self, identifier): for (var, lower, upper) in self.ranges: if identifier == var: return (lower, upper) print 'ERROR: range %s is undefined.' % (identifier,) sys.exit(1) class Output: def __init__(self): self.string = '' def GetLastLine(self): index = self.string.rfind('\n') if index < 0: return '' return self.string[index + 1:] def Append(self, s): self.string += s def RunAtomicCode(env, node, output): if isinstance(node, VarNode): identifier = node.identifier.value.strip() result = Output() RunAtomicCode(env.Clone(), node.atomic_code, result) value = result.string env.PushVariable(identifier, value) elif isinstance(node, RangeNode): identifier = node.identifier.value.strip() lower = int(env.EvalExp(node.exp1)) upper = int(env.EvalExp(node.exp2)) env.PushRange(identifier, lower, upper) elif isinstance(node, ForNode): identifier = node.identifier.value.strip() if node.sep is None: sep = '' else: sep = node.sep.value (lower, upper) = env.GetRange(identifier) for i in range(lower, upper + 1): new_env = env.Clone() new_env.PushVariable(identifier, i) RunCode(new_env, node.code, output) if i != upper: output.Append(sep) elif isinstance(node, RawCodeNode): output.Append(node.raw_code.value) elif isinstance(node, IfNode): cond = env.EvalExp(node.exp) if cond: RunCode(env.Clone(), node.then_branch, output) elif node.else_branch is not None: RunCode(env.Clone(), node.else_branch, output) elif isinstance(node, ExpNode): value = env.EvalExp(node) output.Append('%s' % (value,)) elif isinstance(node, LiteralDollarNode): output.Append('$') elif isinstance(node, CodeNode): RunCode(env.Clone(), node, output) else: print 'BAD' print node sys.exit(1) def RunCode(env, code_node, output): for atomic_code in code_node.atomic_code: RunAtomicCode(env, atomic_code, output) def IsSingleLineComment(cur_line): return '//' in cur_line def IsInPreprocessorDirective(prev_lines, cur_line): if cur_line.lstrip().startswith('#'): return True return prev_lines and prev_lines[-1].endswith('\\') def WrapComment(line, output): loc = line.find('//') before_comment = line[:loc].rstrip() if before_comment == '': indent = loc else: output.append(before_comment) indent = len(before_comment) - len(before_comment.lstrip()) prefix = indent*' ' + '// ' max_len = 80 - len(prefix) comment = line[loc + 2:].strip() segs = [seg for seg in re.split(r'(\w+\W*)', comment) if seg != ''] cur_line = '' for seg in segs: if len((cur_line + seg).rstrip()) < max_len: cur_line += seg else: if cur_line.strip() != '': output.append(prefix + cur_line.rstrip()) cur_line = seg.lstrip() if cur_line.strip() != '': output.append(prefix + cur_line.strip()) def WrapCode(line, line_concat, output): indent = len(line) - len(line.lstrip()) prefix = indent*' ' # Prefix of the current line max_len = 80 - indent - len(line_concat) # Maximum length of the current line new_prefix = prefix + 4*' ' # Prefix of a continuation line new_max_len = max_len - 4 # Maximum length of a continuation line # Prefers to wrap a line after a ',' or ';'. segs = [seg for seg in re.split(r'([^,;]+[,;]?)', line.strip()) if seg != ''] cur_line = '' # The current line without leading spaces. for seg in segs: # If the line is still too long, wrap at a space. while cur_line == '' and len(seg.strip()) > max_len: seg = seg.lstrip() split_at = seg.rfind(' ', 0, max_len) output.append(prefix + seg[:split_at].strip() + line_concat) seg = seg[split_at + 1:] prefix = new_prefix max_len = new_max_len if len((cur_line + seg).rstrip()) < max_len: cur_line = (cur_line + seg).lstrip() else: output.append(prefix + cur_line.rstrip() + line_concat) prefix = new_prefix max_len = new_max_len cur_line = seg.lstrip() if cur_line.strip() != '': output.append(prefix + cur_line.strip()) def WrapPreprocessorDirective(line, output): WrapCode(line, ' \\', output) def WrapPlainCode(line, output): WrapCode(line, '', output) def IsMultiLineIWYUPragma(line): return re.search(r'/\* IWYU pragma: ', line) def IsHeaderGuardIncludeOrOneLineIWYUPragma(line): return (re.match(r'^#(ifndef|define|endif\s*//)\s*[\w_]+\s*$', line) or re.match(r'^#include\s', line) or # Don't break IWYU pragmas, either; that causes iwyu.py problems. re.search(r'// IWYU pragma: ', line)) def WrapLongLine(line, output): line = line.rstrip() if len(line) <= 80: output.append(line) elif IsSingleLineComment(line): if IsHeaderGuardIncludeOrOneLineIWYUPragma(line): # The style guide made an exception to allow long header guard lines, # includes and IWYU pragmas. output.append(line) else: WrapComment(line, output) elif IsInPreprocessorDirective(output, line): if IsHeaderGuardIncludeOrOneLineIWYUPragma(line): # The style guide made an exception to allow long header guard lines, # includes and IWYU pragmas. output.append(line) else: WrapPreprocessorDirective(line, output) elif IsMultiLineIWYUPragma(line): output.append(line) else: WrapPlainCode(line, output) def BeautifyCode(string): lines = string.splitlines() output = [] for line in lines: WrapLongLine(line, output) output2 = [line.rstrip() for line in output] return '\n'.join(output2) + '\n' def ConvertFromPumpSource(src_text): """Return the text generated from the given Pump source text.""" ast = ParseToAST(StripMetaComments(src_text)) output = Output() RunCode(Env(), ast, output) return BeautifyCode(output.string) def main(argv): if len(argv) == 1: print __doc__ sys.exit(1) file_path = argv[-1] output_str = ConvertFromPumpSource(file(file_path, 'r').read()) if file_path.endswith('.pump'): output_file_path = file_path[:-5] else: output_file_path = '-' if output_file_path == '-': print output_str, else: output_file = file(output_file_path, 'w') output_file.write('// This file was GENERATED by command:\n') output_file.write('// %s %s\n' % (os.path.basename(__file__), os.path.basename(file_path))) output_file.write('// DO NOT EDIT BY HAND!!!\n\n') output_file.write(output_str) output_file.close() if __name__ == '__main__': main(sys.argv) dlt-daemon-2.18.4/gtest-1.7.0/scripts/test/000077500000000000000000000000001353342203500200675ustar00rootroot00000000000000dlt-daemon-2.18.4/gtest-1.7.0/scripts/test/Makefile000066400000000000000000000034121353342203500215270ustar00rootroot00000000000000# A Makefile for fusing Google Test and building a sample test against it. # # SYNOPSIS: # # make [all] - makes everything. # make TARGET - makes the given target. # make check - makes everything and runs the built sample test. # make clean - removes all files generated by make. # Points to the root of fused Google Test, relative to where this file is. FUSED_GTEST_DIR = output # Paths to the fused gtest files. FUSED_GTEST_H = $(FUSED_GTEST_DIR)/gtest/gtest.h FUSED_GTEST_ALL_CC = $(FUSED_GTEST_DIR)/gtest/gtest-all.cc # Where to find the sample test. SAMPLE_DIR = ../../samples # Where to find gtest_main.cc. GTEST_MAIN_CC = ../../src/gtest_main.cc # Flags passed to the preprocessor. # We have no idea here whether pthreads is available in the system, so # disable its use. CPPFLAGS += -I$(FUSED_GTEST_DIR) -DGTEST_HAS_PTHREAD=0 # Flags passed to the C++ compiler. CXXFLAGS += -g all : sample1_unittest check : all ./sample1_unittest clean : rm -rf $(FUSED_GTEST_DIR) sample1_unittest *.o $(FUSED_GTEST_H) : ../fuse_gtest_files.py $(FUSED_GTEST_DIR) $(FUSED_GTEST_ALL_CC) : ../fuse_gtest_files.py $(FUSED_GTEST_DIR) gtest-all.o : $(FUSED_GTEST_H) $(FUSED_GTEST_ALL_CC) $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(FUSED_GTEST_DIR)/gtest/gtest-all.cc gtest_main.o : $(FUSED_GTEST_H) $(GTEST_MAIN_CC) $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(GTEST_MAIN_CC) sample1.o : $(SAMPLE_DIR)/sample1.cc $(SAMPLE_DIR)/sample1.h $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(SAMPLE_DIR)/sample1.cc sample1_unittest.o : $(SAMPLE_DIR)/sample1_unittest.cc \ $(SAMPLE_DIR)/sample1.h $(FUSED_GTEST_H) $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(SAMPLE_DIR)/sample1_unittest.cc sample1_unittest : sample1.o sample1_unittest.o gtest-all.o gtest_main.o $(CXX) $(CPPFLAGS) $(CXXFLAGS) $^ -o $@ dlt-daemon-2.18.4/gtest-1.7.0/src/000077500000000000000000000000001353342203500162105ustar00rootroot00000000000000dlt-daemon-2.18.4/gtest-1.7.0/src/.deps/000077500000000000000000000000001353342203500172215ustar00rootroot00000000000000dlt-daemon-2.18.4/gtest-1.7.0/src/.deps/.dirstamp000066400000000000000000000000001353342203500210330ustar00rootroot00000000000000dlt-daemon-2.18.4/gtest-1.7.0/src/.deps/gtest-all.Plo000066400000000000000000000412211353342203500215710ustar00rootroot00000000000000src/gtest-all.lo: src/gtest-all.cc /usr/include/stdc-predef.h \ include/gtest/gtest.h /usr/include/c++/4.9.2/limits \ /usr/include/c++/4.9.2/i686-redhat-linux/bits/c++config.h \ /usr/include/c++/4.9.2/i686-redhat-linux/bits/os_defines.h \ /usr/include/features.h /usr/include/sys/cdefs.h \ /usr/include/bits/wordsize.h /usr/include/gnu/stubs.h \ /usr/include/gnu/stubs-32.h \ /usr/include/c++/4.9.2/i686-redhat-linux/bits/cpu_defines.h \ /usr/include/c++/4.9.2/ostream /usr/include/c++/4.9.2/ios \ /usr/include/c++/4.9.2/iosfwd /usr/include/c++/4.9.2/bits/stringfwd.h \ /usr/include/c++/4.9.2/bits/memoryfwd.h \ /usr/include/c++/4.9.2/bits/postypes.h /usr/include/c++/4.9.2/cwchar \ /usr/include/wchar.h /usr/include/stdio.h \ /usr/lib/gcc/i686-redhat-linux/4.9.2/include/stdarg.h \ /usr/include/bits/wchar.h \ /usr/lib/gcc/i686-redhat-linux/4.9.2/include/stddef.h \ /usr/include/xlocale.h /usr/include/c++/4.9.2/exception \ /usr/include/c++/4.9.2/bits/atomic_lockfree_defines.h \ /usr/include/c++/4.9.2/bits/char_traits.h \ /usr/include/c++/4.9.2/bits/stl_algobase.h \ /usr/include/c++/4.9.2/bits/functexcept.h \ /usr/include/c++/4.9.2/bits/exception_defines.h \ /usr/include/c++/4.9.2/bits/cpp_type_traits.h \ /usr/include/c++/4.9.2/ext/type_traits.h \ /usr/include/c++/4.9.2/ext/numeric_traits.h \ /usr/include/c++/4.9.2/bits/stl_pair.h \ /usr/include/c++/4.9.2/bits/move.h \ /usr/include/c++/4.9.2/bits/concept_check.h \ /usr/include/c++/4.9.2/bits/stl_iterator_base_types.h \ /usr/include/c++/4.9.2/bits/stl_iterator_base_funcs.h \ /usr/include/c++/4.9.2/debug/debug.h \ /usr/include/c++/4.9.2/bits/stl_iterator.h \ /usr/include/c++/4.9.2/bits/ptr_traits.h \ /usr/include/c++/4.9.2/bits/predefined_ops.h \ /usr/include/c++/4.9.2/bits/localefwd.h \ /usr/include/c++/4.9.2/i686-redhat-linux/bits/c++locale.h \ /usr/include/c++/4.9.2/clocale /usr/include/locale.h \ /usr/include/bits/locale.h /usr/include/c++/4.9.2/cctype \ /usr/include/ctype.h /usr/include/bits/types.h \ /usr/include/bits/typesizes.h /usr/include/endian.h \ /usr/include/bits/endian.h /usr/include/bits/byteswap.h \ /usr/include/bits/byteswap-16.h /usr/include/c++/4.9.2/bits/ios_base.h \ /usr/include/c++/4.9.2/ext/atomicity.h \ /usr/include/c++/4.9.2/i686-redhat-linux/bits/gthr.h \ /usr/include/c++/4.9.2/i686-redhat-linux/bits/gthr-default.h \ /usr/include/pthread.h /usr/include/sched.h /usr/include/time.h \ /usr/include/bits/sched.h /usr/include/bits/time.h \ /usr/include/bits/timex.h /usr/include/bits/pthreadtypes.h \ /usr/include/bits/setjmp.h \ /usr/include/c++/4.9.2/i686-redhat-linux/bits/atomic_word.h \ /usr/include/c++/4.9.2/bits/locale_classes.h \ /usr/include/c++/4.9.2/string /usr/include/c++/4.9.2/bits/allocator.h \ /usr/include/c++/4.9.2/i686-redhat-linux/bits/c++allocator.h \ /usr/include/c++/4.9.2/ext/new_allocator.h /usr/include/c++/4.9.2/new \ /usr/include/c++/4.9.2/bits/ostream_insert.h \ /usr/include/c++/4.9.2/bits/cxxabi_forced.h \ /usr/include/c++/4.9.2/bits/stl_function.h \ /usr/include/c++/4.9.2/backward/binders.h \ /usr/include/c++/4.9.2/bits/range_access.h \ /usr/include/c++/4.9.2/bits/basic_string.h \ /usr/include/c++/4.9.2/bits/basic_string.tcc \ /usr/include/c++/4.9.2/bits/locale_classes.tcc \ /usr/include/c++/4.9.2/streambuf \ /usr/include/c++/4.9.2/bits/streambuf.tcc \ /usr/include/c++/4.9.2/bits/basic_ios.h \ /usr/include/c++/4.9.2/bits/locale_facets.h \ /usr/include/c++/4.9.2/cwctype /usr/include/wctype.h \ /usr/include/c++/4.9.2/i686-redhat-linux/bits/ctype_base.h \ /usr/include/c++/4.9.2/bits/streambuf_iterator.h \ /usr/include/c++/4.9.2/i686-redhat-linux/bits/ctype_inline.h \ /usr/include/c++/4.9.2/bits/locale_facets.tcc \ /usr/include/c++/4.9.2/bits/basic_ios.tcc \ /usr/include/c++/4.9.2/bits/ostream.tcc /usr/include/c++/4.9.2/vector \ /usr/include/c++/4.9.2/bits/stl_construct.h \ /usr/include/c++/4.9.2/ext/alloc_traits.h \ /usr/include/c++/4.9.2/bits/stl_uninitialized.h \ /usr/include/c++/4.9.2/bits/stl_vector.h \ /usr/include/c++/4.9.2/bits/stl_bvector.h \ /usr/include/c++/4.9.2/bits/vector.tcc \ include/gtest/internal/gtest-internal.h \ include/gtest/internal/gtest-port.h /usr/include/stdlib.h \ /usr/include/bits/waitflags.h /usr/include/bits/waitstatus.h \ /usr/include/sys/types.h /usr/include/sys/select.h \ /usr/include/bits/select.h /usr/include/bits/sigset.h \ /usr/include/sys/sysmacros.h /usr/include/alloca.h \ /usr/include/bits/stdlib-bsearch.h /usr/include/bits/stdlib-float.h \ /usr/include/libio.h /usr/include/_G_config.h \ /usr/include/bits/stdio_lim.h /usr/include/bits/sys_errlist.h \ /usr/include/bits/stdio.h /usr/include/string.h /usr/include/sys/stat.h \ /usr/include/bits/stat.h /usr/include/c++/4.9.2/iostream \ /usr/include/c++/4.9.2/istream /usr/include/c++/4.9.2/bits/istream.tcc \ /usr/include/c++/4.9.2/sstream /usr/include/c++/4.9.2/bits/sstream.tcc \ /usr/include/unistd.h /usr/include/bits/posix_opt.h \ /usr/include/bits/environments.h /usr/include/bits/confname.h \ /usr/include/getopt.h /usr/include/strings.h /usr/include/regex.h \ /usr/include/c++/4.9.2/typeinfo /usr/include/c++/4.9.2/tr1/tuple \ /usr/include/c++/4.9.2/utility /usr/include/c++/4.9.2/bits/stl_relops.h \ /usr/include/sys/wait.h /usr/include/signal.h /usr/include/bits/signum.h \ /usr/include/bits/siginfo.h /usr/include/bits/sigaction.h \ /usr/include/bits/sigcontext.h /usr/include/bits/sigstack.h \ /usr/include/sys/ucontext.h /usr/include/bits/sigthread.h \ /usr/include/c++/4.9.2/stdexcept \ /usr/lib/gcc/i686-redhat-linux/4.9.2/include/float.h \ /usr/include/c++/4.9.2/iomanip /usr/include/c++/4.9.2/set \ /usr/include/c++/4.9.2/bits/stl_tree.h \ /usr/include/c++/4.9.2/bits/stl_set.h \ /usr/include/c++/4.9.2/bits/stl_multiset.h include/gtest/gtest-message.h \ include/gtest/internal/gtest-string.h \ include/gtest/internal/gtest-filepath.h \ include/gtest/internal/gtest-type-util.h /usr/include/c++/4.9.2/cxxabi.h \ /usr/include/c++/4.9.2/i686-redhat-linux/bits/cxxabi_tweaks.h \ include/gtest/gtest-death-test.h \ include/gtest/internal/gtest-death-test-internal.h \ include/gtest/gtest-param-test.h \ include/gtest/internal/gtest-param-util.h \ /usr/include/c++/4.9.2/iterator \ /usr/include/c++/4.9.2/bits/stream_iterator.h \ include/gtest/internal/gtest-linked_ptr.h /usr/include/assert.h \ include/gtest/gtest-printers.h \ include/gtest/internal/gtest-param-util-generated.h \ include/gtest/gtest_prod.h include/gtest/gtest-test-part.h \ include/gtest/gtest-typed-test.h include/gtest/gtest_pred_impl.h \ src/gtest.cc include/gtest/gtest-spi.h /usr/include/math.h \ /usr/include/bits/huge_val.h /usr/include/bits/huge_valf.h \ /usr/include/bits/huge_vall.h /usr/include/bits/inf.h \ /usr/include/bits/nan.h /usr/include/bits/mathdef.h \ /usr/include/bits/mathcalls.h /usr/include/bits/mathinline.h \ /usr/include/c++/4.9.2/algorithm /usr/include/c++/4.9.2/bits/stl_algo.h \ /usr/include/c++/4.9.2/cstdlib \ /usr/include/c++/4.9.2/bits/algorithmfwd.h \ /usr/include/c++/4.9.2/bits/stl_heap.h \ /usr/include/c++/4.9.2/bits/stl_tempbuf.h /usr/include/fcntl.h \ /usr/include/bits/fcntl.h /usr/include/bits/fcntl-linux.h \ /usr/include/bits/uio.h \ /usr/lib/gcc/i686-redhat-linux/4.9.2/include/limits.h \ /usr/lib/gcc/i686-redhat-linux/4.9.2/include/syslimits.h \ /usr/include/limits.h /usr/include/bits/posix1_lim.h \ /usr/include/bits/local_lim.h /usr/include/linux/limits.h \ /usr/include/bits/posix2_lim.h /usr/include/bits/xopen_lim.h \ /usr/include/sys/mman.h /usr/include/bits/mman.h \ /usr/include/bits/mman-linux.h /usr/include/sys/time.h \ /usr/include/arpa/inet.h /usr/include/netinet/in.h \ /usr/lib/gcc/i686-redhat-linux/4.9.2/include/stdint.h \ /usr/include/stdint.h /usr/include/sys/socket.h /usr/include/sys/uio.h \ /usr/include/bits/socket.h /usr/include/bits/socket_type.h \ /usr/include/bits/sockaddr.h /usr/include/asm/socket.h \ /usr/include/asm-generic/socket.h /usr/include/asm/sockios.h \ /usr/include/asm-generic/sockios.h /usr/include/bits/in.h \ /usr/include/netdb.h /usr/include/rpc/netdb.h /usr/include/bits/netdb.h \ src/gtest-internal-inl.h /usr/include/errno.h /usr/include/bits/errno.h \ /usr/include/linux/errno.h /usr/include/asm/errno.h \ /usr/include/asm-generic/errno.h /usr/include/asm-generic/errno-base.h \ src/gtest-death-test.cc src/gtest-filepath.cc \ /usr/include/c++/4.9.2/climits src/gtest-port.cc src/gtest-printers.cc \ src/gtest-test-part.cc src/gtest-typed-test.cc /usr/include/stdc-predef.h: include/gtest/gtest.h: /usr/include/c++/4.9.2/limits: /usr/include/c++/4.9.2/i686-redhat-linux/bits/c++config.h: /usr/include/c++/4.9.2/i686-redhat-linux/bits/os_defines.h: /usr/include/features.h: /usr/include/sys/cdefs.h: /usr/include/bits/wordsize.h: /usr/include/gnu/stubs.h: /usr/include/gnu/stubs-32.h: /usr/include/c++/4.9.2/i686-redhat-linux/bits/cpu_defines.h: /usr/include/c++/4.9.2/ostream: /usr/include/c++/4.9.2/ios: /usr/include/c++/4.9.2/iosfwd: /usr/include/c++/4.9.2/bits/stringfwd.h: /usr/include/c++/4.9.2/bits/memoryfwd.h: /usr/include/c++/4.9.2/bits/postypes.h: /usr/include/c++/4.9.2/cwchar: /usr/include/wchar.h: /usr/include/stdio.h: /usr/lib/gcc/i686-redhat-linux/4.9.2/include/stdarg.h: /usr/include/bits/wchar.h: /usr/lib/gcc/i686-redhat-linux/4.9.2/include/stddef.h: /usr/include/xlocale.h: /usr/include/c++/4.9.2/exception: /usr/include/c++/4.9.2/bits/atomic_lockfree_defines.h: /usr/include/c++/4.9.2/bits/char_traits.h: /usr/include/c++/4.9.2/bits/stl_algobase.h: /usr/include/c++/4.9.2/bits/functexcept.h: /usr/include/c++/4.9.2/bits/exception_defines.h: /usr/include/c++/4.9.2/bits/cpp_type_traits.h: /usr/include/c++/4.9.2/ext/type_traits.h: /usr/include/c++/4.9.2/ext/numeric_traits.h: /usr/include/c++/4.9.2/bits/stl_pair.h: /usr/include/c++/4.9.2/bits/move.h: /usr/include/c++/4.9.2/bits/concept_check.h: /usr/include/c++/4.9.2/bits/stl_iterator_base_types.h: /usr/include/c++/4.9.2/bits/stl_iterator_base_funcs.h: /usr/include/c++/4.9.2/debug/debug.h: /usr/include/c++/4.9.2/bits/stl_iterator.h: /usr/include/c++/4.9.2/bits/ptr_traits.h: /usr/include/c++/4.9.2/bits/predefined_ops.h: /usr/include/c++/4.9.2/bits/localefwd.h: /usr/include/c++/4.9.2/i686-redhat-linux/bits/c++locale.h: /usr/include/c++/4.9.2/clocale: /usr/include/locale.h: /usr/include/bits/locale.h: /usr/include/c++/4.9.2/cctype: /usr/include/ctype.h: /usr/include/bits/types.h: /usr/include/bits/typesizes.h: /usr/include/endian.h: /usr/include/bits/endian.h: /usr/include/bits/byteswap.h: /usr/include/bits/byteswap-16.h: /usr/include/c++/4.9.2/bits/ios_base.h: /usr/include/c++/4.9.2/ext/atomicity.h: /usr/include/c++/4.9.2/i686-redhat-linux/bits/gthr.h: /usr/include/c++/4.9.2/i686-redhat-linux/bits/gthr-default.h: /usr/include/pthread.h: /usr/include/sched.h: /usr/include/time.h: /usr/include/bits/sched.h: /usr/include/bits/time.h: /usr/include/bits/timex.h: /usr/include/bits/pthreadtypes.h: /usr/include/bits/setjmp.h: /usr/include/c++/4.9.2/i686-redhat-linux/bits/atomic_word.h: /usr/include/c++/4.9.2/bits/locale_classes.h: /usr/include/c++/4.9.2/string: /usr/include/c++/4.9.2/bits/allocator.h: /usr/include/c++/4.9.2/i686-redhat-linux/bits/c++allocator.h: /usr/include/c++/4.9.2/ext/new_allocator.h: /usr/include/c++/4.9.2/new: /usr/include/c++/4.9.2/bits/ostream_insert.h: /usr/include/c++/4.9.2/bits/cxxabi_forced.h: /usr/include/c++/4.9.2/bits/stl_function.h: /usr/include/c++/4.9.2/backward/binders.h: /usr/include/c++/4.9.2/bits/range_access.h: /usr/include/c++/4.9.2/bits/basic_string.h: /usr/include/c++/4.9.2/bits/basic_string.tcc: /usr/include/c++/4.9.2/bits/locale_classes.tcc: /usr/include/c++/4.9.2/streambuf: /usr/include/c++/4.9.2/bits/streambuf.tcc: /usr/include/c++/4.9.2/bits/basic_ios.h: /usr/include/c++/4.9.2/bits/locale_facets.h: /usr/include/c++/4.9.2/cwctype: /usr/include/wctype.h: /usr/include/c++/4.9.2/i686-redhat-linux/bits/ctype_base.h: /usr/include/c++/4.9.2/bits/streambuf_iterator.h: /usr/include/c++/4.9.2/i686-redhat-linux/bits/ctype_inline.h: /usr/include/c++/4.9.2/bits/locale_facets.tcc: /usr/include/c++/4.9.2/bits/basic_ios.tcc: /usr/include/c++/4.9.2/bits/ostream.tcc: /usr/include/c++/4.9.2/vector: /usr/include/c++/4.9.2/bits/stl_construct.h: /usr/include/c++/4.9.2/ext/alloc_traits.h: /usr/include/c++/4.9.2/bits/stl_uninitialized.h: /usr/include/c++/4.9.2/bits/stl_vector.h: /usr/include/c++/4.9.2/bits/stl_bvector.h: /usr/include/c++/4.9.2/bits/vector.tcc: include/gtest/internal/gtest-internal.h: include/gtest/internal/gtest-port.h: /usr/include/stdlib.h: /usr/include/bits/waitflags.h: /usr/include/bits/waitstatus.h: /usr/include/sys/types.h: /usr/include/sys/select.h: /usr/include/bits/select.h: /usr/include/bits/sigset.h: /usr/include/sys/sysmacros.h: /usr/include/alloca.h: /usr/include/bits/stdlib-bsearch.h: /usr/include/bits/stdlib-float.h: /usr/include/libio.h: /usr/include/_G_config.h: /usr/include/bits/stdio_lim.h: /usr/include/bits/sys_errlist.h: /usr/include/bits/stdio.h: /usr/include/string.h: /usr/include/sys/stat.h: /usr/include/bits/stat.h: /usr/include/c++/4.9.2/iostream: /usr/include/c++/4.9.2/istream: /usr/include/c++/4.9.2/bits/istream.tcc: /usr/include/c++/4.9.2/sstream: /usr/include/c++/4.9.2/bits/sstream.tcc: /usr/include/unistd.h: /usr/include/bits/posix_opt.h: /usr/include/bits/environments.h: /usr/include/bits/confname.h: /usr/include/getopt.h: /usr/include/strings.h: /usr/include/regex.h: /usr/include/c++/4.9.2/typeinfo: /usr/include/c++/4.9.2/tr1/tuple: /usr/include/c++/4.9.2/utility: /usr/include/c++/4.9.2/bits/stl_relops.h: /usr/include/sys/wait.h: /usr/include/signal.h: /usr/include/bits/signum.h: /usr/include/bits/siginfo.h: /usr/include/bits/sigaction.h: /usr/include/bits/sigcontext.h: /usr/include/bits/sigstack.h: /usr/include/sys/ucontext.h: /usr/include/bits/sigthread.h: /usr/include/c++/4.9.2/stdexcept: /usr/lib/gcc/i686-redhat-linux/4.9.2/include/float.h: /usr/include/c++/4.9.2/iomanip: /usr/include/c++/4.9.2/set: /usr/include/c++/4.9.2/bits/stl_tree.h: /usr/include/c++/4.9.2/bits/stl_set.h: /usr/include/c++/4.9.2/bits/stl_multiset.h: include/gtest/gtest-message.h: include/gtest/internal/gtest-string.h: include/gtest/internal/gtest-filepath.h: include/gtest/internal/gtest-type-util.h: /usr/include/c++/4.9.2/cxxabi.h: /usr/include/c++/4.9.2/i686-redhat-linux/bits/cxxabi_tweaks.h: include/gtest/gtest-death-test.h: include/gtest/internal/gtest-death-test-internal.h: include/gtest/gtest-param-test.h: include/gtest/internal/gtest-param-util.h: /usr/include/c++/4.9.2/iterator: /usr/include/c++/4.9.2/bits/stream_iterator.h: include/gtest/internal/gtest-linked_ptr.h: /usr/include/assert.h: include/gtest/gtest-printers.h: include/gtest/internal/gtest-param-util-generated.h: include/gtest/gtest_prod.h: include/gtest/gtest-test-part.h: include/gtest/gtest-typed-test.h: include/gtest/gtest_pred_impl.h: src/gtest.cc: include/gtest/gtest-spi.h: /usr/include/math.h: /usr/include/bits/huge_val.h: /usr/include/bits/huge_valf.h: /usr/include/bits/huge_vall.h: /usr/include/bits/inf.h: /usr/include/bits/nan.h: /usr/include/bits/mathdef.h: /usr/include/bits/mathcalls.h: /usr/include/bits/mathinline.h: /usr/include/c++/4.9.2/algorithm: /usr/include/c++/4.9.2/bits/stl_algo.h: /usr/include/c++/4.9.2/cstdlib: /usr/include/c++/4.9.2/bits/algorithmfwd.h: /usr/include/c++/4.9.2/bits/stl_heap.h: /usr/include/c++/4.9.2/bits/stl_tempbuf.h: /usr/include/fcntl.h: /usr/include/bits/fcntl.h: /usr/include/bits/fcntl-linux.h: /usr/include/bits/uio.h: /usr/lib/gcc/i686-redhat-linux/4.9.2/include/limits.h: /usr/lib/gcc/i686-redhat-linux/4.9.2/include/syslimits.h: /usr/include/limits.h: /usr/include/bits/posix1_lim.h: /usr/include/bits/local_lim.h: /usr/include/linux/limits.h: /usr/include/bits/posix2_lim.h: /usr/include/bits/xopen_lim.h: /usr/include/sys/mman.h: /usr/include/bits/mman.h: /usr/include/bits/mman-linux.h: /usr/include/sys/time.h: /usr/include/arpa/inet.h: /usr/include/netinet/in.h: /usr/lib/gcc/i686-redhat-linux/4.9.2/include/stdint.h: /usr/include/stdint.h: /usr/include/sys/socket.h: /usr/include/sys/uio.h: /usr/include/bits/socket.h: /usr/include/bits/socket_type.h: /usr/include/bits/sockaddr.h: /usr/include/asm/socket.h: /usr/include/asm-generic/socket.h: /usr/include/asm/sockios.h: /usr/include/asm-generic/sockios.h: /usr/include/bits/in.h: /usr/include/netdb.h: /usr/include/rpc/netdb.h: /usr/include/bits/netdb.h: src/gtest-internal-inl.h: /usr/include/errno.h: /usr/include/bits/errno.h: /usr/include/linux/errno.h: /usr/include/asm/errno.h: /usr/include/asm-generic/errno.h: /usr/include/asm-generic/errno-base.h: src/gtest-death-test.cc: src/gtest-filepath.cc: /usr/include/c++/4.9.2/climits: src/gtest-port.cc: src/gtest-printers.cc: src/gtest-test-part.cc: src/gtest-typed-test.cc: dlt-daemon-2.18.4/gtest-1.7.0/src/.deps/gtest_main.Plo000066400000000000000000000315141353342203500220330ustar00rootroot00000000000000src/gtest_main.lo: src/gtest_main.cc /usr/include/stdc-predef.h \ /usr/include/stdio.h /usr/include/features.h /usr/include/sys/cdefs.h \ /usr/include/bits/wordsize.h /usr/include/gnu/stubs.h \ /usr/include/gnu/stubs-32.h \ /usr/lib/gcc/i686-redhat-linux/4.9.2/include/stddef.h \ /usr/include/bits/types.h /usr/include/bits/typesizes.h \ /usr/include/libio.h /usr/include/_G_config.h /usr/include/wchar.h \ /usr/lib/gcc/i686-redhat-linux/4.9.2/include/stdarg.h \ /usr/include/bits/stdio_lim.h /usr/include/bits/sys_errlist.h \ /usr/include/bits/stdio.h include/gtest/gtest.h \ /usr/include/c++/4.9.2/limits \ /usr/include/c++/4.9.2/i686-redhat-linux/bits/c++config.h \ /usr/include/c++/4.9.2/i686-redhat-linux/bits/os_defines.h \ /usr/include/c++/4.9.2/i686-redhat-linux/bits/cpu_defines.h \ /usr/include/c++/4.9.2/ostream /usr/include/c++/4.9.2/ios \ /usr/include/c++/4.9.2/iosfwd /usr/include/c++/4.9.2/bits/stringfwd.h \ /usr/include/c++/4.9.2/bits/memoryfwd.h \ /usr/include/c++/4.9.2/bits/postypes.h /usr/include/c++/4.9.2/cwchar \ /usr/include/bits/wchar.h /usr/include/xlocale.h \ /usr/include/c++/4.9.2/exception \ /usr/include/c++/4.9.2/bits/atomic_lockfree_defines.h \ /usr/include/c++/4.9.2/bits/char_traits.h \ /usr/include/c++/4.9.2/bits/stl_algobase.h \ /usr/include/c++/4.9.2/bits/functexcept.h \ /usr/include/c++/4.9.2/bits/exception_defines.h \ /usr/include/c++/4.9.2/bits/cpp_type_traits.h \ /usr/include/c++/4.9.2/ext/type_traits.h \ /usr/include/c++/4.9.2/ext/numeric_traits.h \ /usr/include/c++/4.9.2/bits/stl_pair.h \ /usr/include/c++/4.9.2/bits/move.h \ /usr/include/c++/4.9.2/bits/concept_check.h \ /usr/include/c++/4.9.2/bits/stl_iterator_base_types.h \ /usr/include/c++/4.9.2/bits/stl_iterator_base_funcs.h \ /usr/include/c++/4.9.2/debug/debug.h \ /usr/include/c++/4.9.2/bits/stl_iterator.h \ /usr/include/c++/4.9.2/bits/ptr_traits.h \ /usr/include/c++/4.9.2/bits/predefined_ops.h \ /usr/include/c++/4.9.2/bits/localefwd.h \ /usr/include/c++/4.9.2/i686-redhat-linux/bits/c++locale.h \ /usr/include/c++/4.9.2/clocale /usr/include/locale.h \ /usr/include/bits/locale.h /usr/include/c++/4.9.2/cctype \ /usr/include/ctype.h /usr/include/endian.h /usr/include/bits/endian.h \ /usr/include/bits/byteswap.h /usr/include/bits/byteswap-16.h \ /usr/include/c++/4.9.2/bits/ios_base.h \ /usr/include/c++/4.9.2/ext/atomicity.h \ /usr/include/c++/4.9.2/i686-redhat-linux/bits/gthr.h \ /usr/include/c++/4.9.2/i686-redhat-linux/bits/gthr-default.h \ /usr/include/pthread.h /usr/include/sched.h /usr/include/time.h \ /usr/include/bits/sched.h /usr/include/bits/time.h \ /usr/include/bits/timex.h /usr/include/bits/pthreadtypes.h \ /usr/include/bits/setjmp.h \ /usr/include/c++/4.9.2/i686-redhat-linux/bits/atomic_word.h \ /usr/include/c++/4.9.2/bits/locale_classes.h \ /usr/include/c++/4.9.2/string /usr/include/c++/4.9.2/bits/allocator.h \ /usr/include/c++/4.9.2/i686-redhat-linux/bits/c++allocator.h \ /usr/include/c++/4.9.2/ext/new_allocator.h /usr/include/c++/4.9.2/new \ /usr/include/c++/4.9.2/bits/ostream_insert.h \ /usr/include/c++/4.9.2/bits/cxxabi_forced.h \ /usr/include/c++/4.9.2/bits/stl_function.h \ /usr/include/c++/4.9.2/backward/binders.h \ /usr/include/c++/4.9.2/bits/range_access.h \ /usr/include/c++/4.9.2/bits/basic_string.h \ /usr/include/c++/4.9.2/bits/basic_string.tcc \ /usr/include/c++/4.9.2/bits/locale_classes.tcc \ /usr/include/c++/4.9.2/streambuf \ /usr/include/c++/4.9.2/bits/streambuf.tcc \ /usr/include/c++/4.9.2/bits/basic_ios.h \ /usr/include/c++/4.9.2/bits/locale_facets.h \ /usr/include/c++/4.9.2/cwctype /usr/include/wctype.h \ /usr/include/c++/4.9.2/i686-redhat-linux/bits/ctype_base.h \ /usr/include/c++/4.9.2/bits/streambuf_iterator.h \ /usr/include/c++/4.9.2/i686-redhat-linux/bits/ctype_inline.h \ /usr/include/c++/4.9.2/bits/locale_facets.tcc \ /usr/include/c++/4.9.2/bits/basic_ios.tcc \ /usr/include/c++/4.9.2/bits/ostream.tcc /usr/include/c++/4.9.2/vector \ /usr/include/c++/4.9.2/bits/stl_construct.h \ /usr/include/c++/4.9.2/ext/alloc_traits.h \ /usr/include/c++/4.9.2/bits/stl_uninitialized.h \ /usr/include/c++/4.9.2/bits/stl_vector.h \ /usr/include/c++/4.9.2/bits/stl_bvector.h \ /usr/include/c++/4.9.2/bits/vector.tcc \ include/gtest/internal/gtest-internal.h \ include/gtest/internal/gtest-port.h /usr/include/stdlib.h \ /usr/include/bits/waitflags.h /usr/include/bits/waitstatus.h \ /usr/include/sys/types.h /usr/include/sys/select.h \ /usr/include/bits/select.h /usr/include/bits/sigset.h \ /usr/include/sys/sysmacros.h /usr/include/alloca.h \ /usr/include/bits/stdlib-bsearch.h /usr/include/bits/stdlib-float.h \ /usr/include/string.h /usr/include/sys/stat.h /usr/include/bits/stat.h \ /usr/include/c++/4.9.2/iostream /usr/include/c++/4.9.2/istream \ /usr/include/c++/4.9.2/bits/istream.tcc /usr/include/c++/4.9.2/sstream \ /usr/include/c++/4.9.2/bits/sstream.tcc /usr/include/unistd.h \ /usr/include/bits/posix_opt.h /usr/include/bits/environments.h \ /usr/include/bits/confname.h /usr/include/getopt.h \ /usr/include/strings.h /usr/include/regex.h \ /usr/include/c++/4.9.2/typeinfo /usr/include/c++/4.9.2/tr1/tuple \ /usr/include/c++/4.9.2/utility /usr/include/c++/4.9.2/bits/stl_relops.h \ /usr/include/sys/wait.h /usr/include/signal.h /usr/include/bits/signum.h \ /usr/include/bits/siginfo.h /usr/include/bits/sigaction.h \ /usr/include/bits/sigcontext.h /usr/include/bits/sigstack.h \ /usr/include/sys/ucontext.h /usr/include/bits/sigthread.h \ /usr/include/c++/4.9.2/stdexcept \ /usr/lib/gcc/i686-redhat-linux/4.9.2/include/float.h \ /usr/include/c++/4.9.2/iomanip /usr/include/c++/4.9.2/set \ /usr/include/c++/4.9.2/bits/stl_tree.h \ /usr/include/c++/4.9.2/bits/stl_set.h \ /usr/include/c++/4.9.2/bits/stl_multiset.h include/gtest/gtest-message.h \ include/gtest/internal/gtest-string.h \ include/gtest/internal/gtest-filepath.h \ include/gtest/internal/gtest-type-util.h /usr/include/c++/4.9.2/cxxabi.h \ /usr/include/c++/4.9.2/i686-redhat-linux/bits/cxxabi_tweaks.h \ include/gtest/gtest-death-test.h \ include/gtest/internal/gtest-death-test-internal.h \ include/gtest/gtest-param-test.h \ include/gtest/internal/gtest-param-util.h \ /usr/include/c++/4.9.2/iterator \ /usr/include/c++/4.9.2/bits/stream_iterator.h \ include/gtest/internal/gtest-linked_ptr.h /usr/include/assert.h \ include/gtest/gtest-printers.h \ include/gtest/internal/gtest-param-util-generated.h \ include/gtest/gtest_prod.h include/gtest/gtest-test-part.h \ include/gtest/gtest-typed-test.h include/gtest/gtest_pred_impl.h /usr/include/stdc-predef.h: /usr/include/stdio.h: /usr/include/features.h: /usr/include/sys/cdefs.h: /usr/include/bits/wordsize.h: /usr/include/gnu/stubs.h: /usr/include/gnu/stubs-32.h: /usr/lib/gcc/i686-redhat-linux/4.9.2/include/stddef.h: /usr/include/bits/types.h: /usr/include/bits/typesizes.h: /usr/include/libio.h: /usr/include/_G_config.h: /usr/include/wchar.h: /usr/lib/gcc/i686-redhat-linux/4.9.2/include/stdarg.h: /usr/include/bits/stdio_lim.h: /usr/include/bits/sys_errlist.h: /usr/include/bits/stdio.h: include/gtest/gtest.h: /usr/include/c++/4.9.2/limits: /usr/include/c++/4.9.2/i686-redhat-linux/bits/c++config.h: /usr/include/c++/4.9.2/i686-redhat-linux/bits/os_defines.h: /usr/include/c++/4.9.2/i686-redhat-linux/bits/cpu_defines.h: /usr/include/c++/4.9.2/ostream: /usr/include/c++/4.9.2/ios: /usr/include/c++/4.9.2/iosfwd: /usr/include/c++/4.9.2/bits/stringfwd.h: /usr/include/c++/4.9.2/bits/memoryfwd.h: /usr/include/c++/4.9.2/bits/postypes.h: /usr/include/c++/4.9.2/cwchar: /usr/include/bits/wchar.h: /usr/include/xlocale.h: /usr/include/c++/4.9.2/exception: /usr/include/c++/4.9.2/bits/atomic_lockfree_defines.h: /usr/include/c++/4.9.2/bits/char_traits.h: /usr/include/c++/4.9.2/bits/stl_algobase.h: /usr/include/c++/4.9.2/bits/functexcept.h: /usr/include/c++/4.9.2/bits/exception_defines.h: /usr/include/c++/4.9.2/bits/cpp_type_traits.h: /usr/include/c++/4.9.2/ext/type_traits.h: /usr/include/c++/4.9.2/ext/numeric_traits.h: /usr/include/c++/4.9.2/bits/stl_pair.h: /usr/include/c++/4.9.2/bits/move.h: /usr/include/c++/4.9.2/bits/concept_check.h: /usr/include/c++/4.9.2/bits/stl_iterator_base_types.h: /usr/include/c++/4.9.2/bits/stl_iterator_base_funcs.h: /usr/include/c++/4.9.2/debug/debug.h: /usr/include/c++/4.9.2/bits/stl_iterator.h: /usr/include/c++/4.9.2/bits/ptr_traits.h: /usr/include/c++/4.9.2/bits/predefined_ops.h: /usr/include/c++/4.9.2/bits/localefwd.h: /usr/include/c++/4.9.2/i686-redhat-linux/bits/c++locale.h: /usr/include/c++/4.9.2/clocale: /usr/include/locale.h: /usr/include/bits/locale.h: /usr/include/c++/4.9.2/cctype: /usr/include/ctype.h: /usr/include/endian.h: /usr/include/bits/endian.h: /usr/include/bits/byteswap.h: /usr/include/bits/byteswap-16.h: /usr/include/c++/4.9.2/bits/ios_base.h: /usr/include/c++/4.9.2/ext/atomicity.h: /usr/include/c++/4.9.2/i686-redhat-linux/bits/gthr.h: /usr/include/c++/4.9.2/i686-redhat-linux/bits/gthr-default.h: /usr/include/pthread.h: /usr/include/sched.h: /usr/include/time.h: /usr/include/bits/sched.h: /usr/include/bits/time.h: /usr/include/bits/timex.h: /usr/include/bits/pthreadtypes.h: /usr/include/bits/setjmp.h: /usr/include/c++/4.9.2/i686-redhat-linux/bits/atomic_word.h: /usr/include/c++/4.9.2/bits/locale_classes.h: /usr/include/c++/4.9.2/string: /usr/include/c++/4.9.2/bits/allocator.h: /usr/include/c++/4.9.2/i686-redhat-linux/bits/c++allocator.h: /usr/include/c++/4.9.2/ext/new_allocator.h: /usr/include/c++/4.9.2/new: /usr/include/c++/4.9.2/bits/ostream_insert.h: /usr/include/c++/4.9.2/bits/cxxabi_forced.h: /usr/include/c++/4.9.2/bits/stl_function.h: /usr/include/c++/4.9.2/backward/binders.h: /usr/include/c++/4.9.2/bits/range_access.h: /usr/include/c++/4.9.2/bits/basic_string.h: /usr/include/c++/4.9.2/bits/basic_string.tcc: /usr/include/c++/4.9.2/bits/locale_classes.tcc: /usr/include/c++/4.9.2/streambuf: /usr/include/c++/4.9.2/bits/streambuf.tcc: /usr/include/c++/4.9.2/bits/basic_ios.h: /usr/include/c++/4.9.2/bits/locale_facets.h: /usr/include/c++/4.9.2/cwctype: /usr/include/wctype.h: /usr/include/c++/4.9.2/i686-redhat-linux/bits/ctype_base.h: /usr/include/c++/4.9.2/bits/streambuf_iterator.h: /usr/include/c++/4.9.2/i686-redhat-linux/bits/ctype_inline.h: /usr/include/c++/4.9.2/bits/locale_facets.tcc: /usr/include/c++/4.9.2/bits/basic_ios.tcc: /usr/include/c++/4.9.2/bits/ostream.tcc: /usr/include/c++/4.9.2/vector: /usr/include/c++/4.9.2/bits/stl_construct.h: /usr/include/c++/4.9.2/ext/alloc_traits.h: /usr/include/c++/4.9.2/bits/stl_uninitialized.h: /usr/include/c++/4.9.2/bits/stl_vector.h: /usr/include/c++/4.9.2/bits/stl_bvector.h: /usr/include/c++/4.9.2/bits/vector.tcc: include/gtest/internal/gtest-internal.h: include/gtest/internal/gtest-port.h: /usr/include/stdlib.h: /usr/include/bits/waitflags.h: /usr/include/bits/waitstatus.h: /usr/include/sys/types.h: /usr/include/sys/select.h: /usr/include/bits/select.h: /usr/include/bits/sigset.h: /usr/include/sys/sysmacros.h: /usr/include/alloca.h: /usr/include/bits/stdlib-bsearch.h: /usr/include/bits/stdlib-float.h: /usr/include/string.h: /usr/include/sys/stat.h: /usr/include/bits/stat.h: /usr/include/c++/4.9.2/iostream: /usr/include/c++/4.9.2/istream: /usr/include/c++/4.9.2/bits/istream.tcc: /usr/include/c++/4.9.2/sstream: /usr/include/c++/4.9.2/bits/sstream.tcc: /usr/include/unistd.h: /usr/include/bits/posix_opt.h: /usr/include/bits/environments.h: /usr/include/bits/confname.h: /usr/include/getopt.h: /usr/include/strings.h: /usr/include/regex.h: /usr/include/c++/4.9.2/typeinfo: /usr/include/c++/4.9.2/tr1/tuple: /usr/include/c++/4.9.2/utility: /usr/include/c++/4.9.2/bits/stl_relops.h: /usr/include/sys/wait.h: /usr/include/signal.h: /usr/include/bits/signum.h: /usr/include/bits/siginfo.h: /usr/include/bits/sigaction.h: /usr/include/bits/sigcontext.h: /usr/include/bits/sigstack.h: /usr/include/sys/ucontext.h: /usr/include/bits/sigthread.h: /usr/include/c++/4.9.2/stdexcept: /usr/lib/gcc/i686-redhat-linux/4.9.2/include/float.h: /usr/include/c++/4.9.2/iomanip: /usr/include/c++/4.9.2/set: /usr/include/c++/4.9.2/bits/stl_tree.h: /usr/include/c++/4.9.2/bits/stl_set.h: /usr/include/c++/4.9.2/bits/stl_multiset.h: include/gtest/gtest-message.h: include/gtest/internal/gtest-string.h: include/gtest/internal/gtest-filepath.h: include/gtest/internal/gtest-type-util.h: /usr/include/c++/4.9.2/cxxabi.h: /usr/include/c++/4.9.2/i686-redhat-linux/bits/cxxabi_tweaks.h: include/gtest/gtest-death-test.h: include/gtest/internal/gtest-death-test-internal.h: include/gtest/gtest-param-test.h: include/gtest/internal/gtest-param-util.h: /usr/include/c++/4.9.2/iterator: /usr/include/c++/4.9.2/bits/stream_iterator.h: include/gtest/internal/gtest-linked_ptr.h: /usr/include/assert.h: include/gtest/gtest-printers.h: include/gtest/internal/gtest-param-util-generated.h: include/gtest/gtest_prod.h: include/gtest/gtest-test-part.h: include/gtest/gtest-typed-test.h: include/gtest/gtest_pred_impl.h: dlt-daemon-2.18.4/gtest-1.7.0/src/.dirstamp000066400000000000000000000000001353342203500200220ustar00rootroot00000000000000dlt-daemon-2.18.4/gtest-1.7.0/src/.libs/000077500000000000000000000000001353342203500172175ustar00rootroot00000000000000dlt-daemon-2.18.4/gtest-1.7.0/src/.libs/gtest-all.o000066400000000000000000124133441353342203500213070ustar00rootroot00000000000000ELF]4(C@2356     DE !"#$%&/0'(89)*AB+,;<-.>?JKMNPQ]^STVWYZ`acdfgijlmoprsuvxy{|    !#$&')*,-/0235689;<>?ABDEGHJKMNPQSTVWYZ\]_`bcefhiklnoqrtuwxz{}~   !#%()68:Í&'Í&'VD$P p19t& yty9u^VD$P p19t& y9u^ÍVD$P p19t& y9u^ÍVD$P p19t& y9u^ÍT$B+B fÍ&' T$D$:u@@RPQÐv'UWVS My q9t#t&t  PR9uExt We[^_]ÉƋEPt R V&VSt$V4$[^Ð&VSD$t$$PPV$[^UWVl$t$}t9UE )t*1VPRUE )9r^_]fUWVl$t$}t9UE )t*1VPRUE )9r^_]fUWVl$t$}t9UE )t*1VPRUE )9r^_]fUWVl$t$}t9UE )t*1VPRUE )9r^_]fUWVl$t$}t9UE )t*1VPR UE )9r^_]fUWVl$t$}t9UE )t*1VPR,UE )9r^_]fUWV|$l$t:Gw )x* v'G0UPRu^_]ÐUWV|$l$t:Gw )x* v'G0UPR0u^_]ÐUWV|$l$t:Gw )x* v'G0UPR$u^_]ÐUWV|$l$t:Gw )x* v'G0UPR(u^_]ÐUWV|$l$t:Gw )x* v'G0UPR8u^_]ÐUWVt$|$~t=VF )t.1퍶Wt$PR VF )9r^_]Í&'UWVt$l$~t>VF )x.< V: Ut$RQ4u^_]Í'UWVQD$ ƉD$)tN1t$ 1vL$ D$t L$D RЋWƋ)9r˃^_]1&'UWVS tW1퍳u*F& Rt&/ uڃ Vuڃ [^_]É' P [^_]ÍVStH~[^fHqɉpRP[^UWVS1,EЉUԋ E̍Wj u j uutXEԃ)@9RW}uWXZWuE ;u듍vU넍t&Eԋ@9ujWuVY_VuE ;u EЍe[^_]ÍUEЍe[^_]PWPPƋEЋ ;tUp VPWPPƋE ;tU:밉ƋE ;tU 떍&'UWVS,L$@|$DD$D$Ѝt$T$$1D$D$D$ $(Pt$jV4$ PVW;l$@tMD$tèuD$ jD$!PW륐t&D$-jt$W뇍&,[^_]Ð&WVSt* R PVPR[^_Ð&jPP[^_UWVS(jƋE EFEFEPF uPE0e[^_]à V<$VSt$ tB ;u R[^ÍT$ېfUWVS}0tMj:Vt#U)RPVWe[^_]EPVWې&EPPW뽃 PWVSD$|$pFN<*t6~<:tS tՋEPJ;HMwH~uuEP EP;u%E P9uEe[^_]&}@x8ȉƋEA;tU VfUWVS t$4l$8j PVD$D$ ()PUoV jt$Vt$UuȃUV jt$V,[^_]Ð&'VSt$j@@@ @FF[^Ðv'VSD$0t#@9u V4$[^Ðt& VЃ[^Ð&SD$T$9Pt49PtR0[Í&@R0[Ð@R0[Ð&D$Ð&D$@Ðt&D$@Ðt&SD$p$[SD$p$[SD$p$[SD$p$[SD$p$[SD$p$[SD$p$[SD$p$[SD$p$[SD$p$[SD$p$[ËD$@$ÍD$@$ÍVSD$p$V1҅~ [^f ƈV‰[^ÐVSD$p$V~[^Í& ƈVƒ[^ÍWVD$ L$p$1x~`Vd)9} xFT^_Í&'UWVS(t$<D$L$ u&D$ t$<9D$t$t$<x,tǃ 1Pu볍v W9}VWxt؍@ PtŃt$j uwP,$$ 뉉'[^_]Ð&D$@$ÐfWVD$ t$H$1xy`Qd)9} xAT^_Í&'D$@$ÐfD$@$@Ðt&D$@$fD$@$lÐt&SD$t P[Í'WVS Wt#PVt P[^_ÍWVPjX0$'D$ |$;T$Ð&'UWVSD$0D$@TD$D$0@XD$ )ȍ $:&D$L$1,1ɋUE )uxvwt$ G t1t+ PPG  j E U׃)9sh<tuuPEt-t' PPEty j (D$0@TD$D$0@XD$ D$ +D$D$L$9 0[^_]Ív1'1녍WVt$|$9tt PR^_ÐT$ˆADÐWV1S|$WTGX)t+t& 4G`WT4GX)9r[^_Í&'D$Ív'Sju [à j jRP'UWVSl$,U ƋD$(8VUW1҅u D$$0 [^_]ÐVSD$t$VPuVPt]VPt1[^ÍVPuݍVP[^Ð&VPu롍&UWVS,Eu E̋EEڃ}PPWYXW}W jPWXEZWPE4$ PVuE䋋 M9uyE ;Eu~u܃VRVuU1ɅUtF;Eude[^_]fU}ttڃ<=Dˍ&e1ɉ[^_]Ít&Upzvavt&MNM덉ƋE܋ }9tU,E ;EtUE ;EtU VƋE䋻 }9tύUʼnƋE륉ƋE뫍t&S jt$t$t+Ѓ/uvVW j RP4$|$[^_&jPW[^_ D$L$PL$Jv'UWVS |$4T$jD$PWtxM1D$ 'ȃt;4$tOLu9u߃ QL$L$tǃjt$W jt$WL$렍jPW[^_]ÍvVST$D$t$tLt( V jPV[^Í&t$[^ WVSt$|$t>VW j RP4$|$[^_o&jPW[^_ D$L$PL$*v'UWVS8U} WZYPu7Edt&<%}h< tdEPJ;HMwH~uuEP EP;7tx<&~<=uEMVQ^uXuuV4$uE ;u8E ;t07u&Ee[^_]vU뾍U@PFƋE ;tUС VƋE ;tU诡E ;tU虡믉fUWVS,E uR}܃PW<$}W j/jWE uWPEXuV4$E䋻 9uSE 9uYE܃ 9u/e[^_]vuVe[^_]t&UǍU谠룍U蠠띋ƋE܃ 9tU脠 VEԋ 9tUauԋE 9tULE 9tU:뢉ƋЉƋ؉ƋE 9xUkUWVS}4uuWE @u0u VE 9uae[^_]t&Eu PE jPu WuVE䋻 9tUR땍UHe[^_]ƋE 9tU" VƋE䋻 9tӍUt&'St$D$P[Í'St$D$P[Í'St$t$[ UWVSMup}}QMEPVEE$E<$El WEYXPEPEE pPEPEXZEPEPEYXPEPEXEZVPEY^PEPE1TVWEME juAUPXEZuPE WE9|EЃ EPEEuԉEPEEY_xEuPEXEZpPWE U9uԅuԍEuP}W PWuE ;EEt juGuu_XjVjuE ;E Ee[^_]Et PR뤃jWEǃ9EE؃ PEM$uZYVPZYRPY^RP^ZWPZYPuE^_jPEEE 0wtz uE EU蒚Ee[^_]U}:Upr uj}ZYW PV uE$uEZYVPEƍEE$E j PEPEFEEăuPURUU PRvEă ;EEt$ jtEt  PRu VƍEȉE$ jPEȃPFẼuPURUU PRvẼ ;EuaEȅt$ jtEȅt  PRPVZYWPY^PuXEZjPUh땍U^ jZYMQ PFP)ƃjuEjPjuE ;EtU VƋẼ ;EtUϗ뜉ƋEă ;EtU踗ju녃 jEZYQ MPFP뵉EƍE܃jPE5ǃjVƋE }9tUuԃju뷉NjE ;Et֋Uږ̉UWVS}4EЍEԃu UPWDu<$}W jPWXZWu4$ PVuE䋳 9uE 9u,EЍe[^_]É'U(E 9tڍEЍe[^_]ÉNjE䋳 9u-E 9tU WNjE 9tӍU迕ɉNj뿉NjEЋ 9t΍U藕Đt&UVSu VEQQXZPj vuPFtZtTP PP 0E ;u e[^]fUؔe[^]Ð j 뷉ƋE ;tU謔 VvUWVS|jhuu EE$E6PEMXvQMXUvRUX}v W}EFM$QFUu$Vl|EYU_UWVRXuZuuVYXEWVPXuZuWVY_}PVWXuZuWVYU_UWVRXuZuuVYXEWVPEXZuWuE 9E܃ 9Eԃ 9EЃ 9Eȃ 9 Eă 9 E 9E 9E 9E 9E 9E 9Ẽ 9E؃ 9E 9Ee[^_]EPPuEe[^_]v'UvUvUvUvUؑvUȑvU踑vU訑vU蘑vU舑vUxvUhvUXvUHvU8NjE 9tUE܃ 9tUEԃ 9tUEЃ 9tUEȃ 9tUѐEă 9tU运E 9tU譐E 9tU蛐E 9tU艐E 9tUwE 9t |bE 9tUPẼ 9tU>E؃ 9tU,E 9tU WNjNjNjNjNjNjNj NjNjNjNj Nj%Nj*Nj/v'UWVSLM}ɍF EEȃMPWQX}ZuuWEĉ<$PEẼ} 9eEȃ 9uW<$ Wu uE 9KEă 9%Ee[^_]&EԃEUPRYMXMPWQX}ZuuWYXE܉UPWRX}ZuuWEĉ<$PEE} 9uPE܃P j=PE܃P j=PE܃P jCPE܃P j PE܃P^XEWPZuEYuu VE uuP0E M9uzE ;Eu_jWe[^_]É'PE܃Pbt&PE܃Pt&m똍&UmyƋE U9tUmE ;EtUmPPjW4$ƋEΉUWVS(u ~WPjv6P<$8t_FXV\EUE܍URPXuPE܃ ;uj 0e[^_]Í& j ϐPjF& VU&U@l댉ƋE܃ ;tU&l VUWVS V4$E VZEYRjXEZuủ‹E^YXuPE 9 V}ȍ EPWP Vt78u,EȅtfEPVPj 0e[^_]ÍUhhWvUXhv j 닐U8hvU(hE 9v'UhƋE 9u+ VƋE 9tUgƋE܃ 9tՍUg҉ƋE܋ 9tUg룍&'UWVS8E} E֍EPEHtW1&0JވU׀ɋt ፶jPEP;pr}ЃWu$WEe[^_]&j릍v}j댉'js}tjj]v'M׃ EՀ} Uus}>EM׍UރjRPM&EU݃jE"RPfEU܃jE'RPf}tU׍ERPXZjPEPE pPEP jPEPE ;uaUdeRƋE ;tUEeju4$獶UWVSE18EP W PEWPjPE܃PE܍ jWPE pPE܃PE܃ jWPE ;E ; u 9Vu ǍEڃ PEwPEM juQMX?ZjPE܃PPE܃Pt&Uc_vUc=vũVu$VEe[^_]ƃju4$ƋE䋻 9tUCcE 9tǍU1c뽉Ƌ␍t&UWVSLE ME1y u e[^_]ÍvE PEEPEE xj PEP0 W PEWPEjWPE@eUEȋtbPEPY^PEPEȃ pPEPEȋ 9M1EuPEuE 9WUt$ jtEt  PRE 9e[^_]Ít&}UE؋aE pEPEEE<~*PEPYXEuPtPEPuEԃVP$VXZPEP^XPEPEԃ pPEPXEZWP_XPEPE؃ pPEPEԋ 9E؃ 90U_#&UEċ'`PEP_XPEPEă pPEPEċ 9Uw_f}h;PjWY^P<$1WUE̋__PEPXZPEPẼ pPEPE̋ 93fU^=EputrfPEP&U@^vUĉEPBP(t&UEЋO^E@0PEPYXPEPE`WPXZPPEЃ pPPEЋ 9Ua]RNjEȋ 9u6PPjuE 9tU)] WNjE 9tʍU ]뼉QQjuE؃ 9tU\덉NjE̋ 9w뫃 WZNjEċ 9DuNj딉NjEԋ 9tUe\uNjEЋ 91t&UWVSE0Ej Pu U؃:u$5Ue[^_]Ívu܃ V j PE܃PEY_xEuPEXEZpPWE䋻 9j1PE܃P j PE܃PYu PEu P jPE܃PXEZVPXuPE 9F 0Y_jVe1[^_]Í&u܃ V j PE܃PEY_xEuPEXEZpPWE䋻 9j1PE܃P j PE܃PYXEu P jPE܃PXEZVPXuPE 9u 0UY፶UYLvUYvUY RRjV<$EЋE 9tUjY}PPjV<$NjE ;tU=Y몉EЋE 9tU&Y}됉붉NjE ;tUY뜍vUWVS8uVE PEM䍃 j"PAP4$U PVBPE PWuUƅt jut6Ee[^_]Ð&Et PRҍvE e[^_]à jPPju4$'UWVS,}te1[^_]Ít&juXZju ƃuutu0t9 e[^_]ÍE PljEYXPEPX ZPEPYXPEPXEZVPY^PEPX ZPEPY^PEPXZW}WYXjVXZWVXujE ;s 0 jE PEYMXPAPXZU䍋 QM̍BPUYXPBPXEZ RPUYXPEPMXZAuPYXE䍋QM̃PXEZVPY^PEPXZUuЍBPYM^u̍APMXZAWPM_XPAPY^uԍ}VWXZjVYXWVZujE ; 0E PƉEYXPEPX ZPEPYXPEPXEZWPY_PEPX ZPEPY_PEPX}ZVWYXjVXZWVXujE ;u/ 0UTUTUSljƋE ;tUSPPjW4$PPjW4$PPju4$ƋE ;tUSPPjW4$QQjW4$WWju4$ƋE ;tU/SPPjW4$PPjW4$PPju4$&'UWVS,u 8tEPP8 PW jPWE8Pj4$_YEQQJ}4$ZuYRR‰# WuPE 9E 9 0e[^_]ÍWPPjf V PPjt&ju<$EPEԃPPj&QQt&UQ2ƋE 9tUP VƋE 9tӍUPɍUWVS0u jVuE PE jPEPt{ V PEVPuWuUƅt$ jtEt PRe[^_]Ðt&e1[^_]Ít&PEP뇉PPju4$v'UWVS8EЍEPE jPEPEVP}ԃEWP$WYuE1}ދPt5t&0 PM EjWQRE;puЋ}ԃWu$WE ;u&EЍe[^_]ÍPEP=U}NEЍe[^_]ÉƋE ;tUZN VjuɃju4$t&WVST$ D$ |$$^ t$t3ƹƋD$ ;u([^_Í&D$ ;tߍ&T$ M[^_Í&'VST$ D$ t$ƅD$ Dt$$ ;u [^Ít&T$ 'M[^ UWVSEt W<$9uuދE 8PE@t PE@ t PE@tV jtEExt; 9uG WE@ 9t&Ue[^_]ÍvE@ 9uڍe[^_]ÍU믉ƋE 8PE@t PE@ t PEjPEHA;tU. Vډ떐VSt$V4$[^Ð&VSt$ F;FtE 9 ExDƒuPEPEu xPVuVuuE 90E 9;Eup\pXVYXuPEPdVduuEă 9E 9Ẽuu PƉl xPEPEVuuuEȃ 9Ẽ 9uxXEZpPuE܃ 9EEht&FHDƒvPuXF ZQu|EЉtPEYX|ulEЃ 9EԃuuP|E؃ j|PXZjPuE؃ pPu j RPE؃ 9GEԃ 9)vtuuYXVuxE 9@xpZuuE 9j PuE܃ 9Ẽ 9Eȃ 9urE u9EuuƋt̃EE&hu t&pŃep赃~p襃p蕃p腃Dpu&UhvpUEu'PuE 9u'e[^_]ÍPuE 9tًpe[^_]ËpE 9p̂p輂E 9p裂p蓂E 9pzpjẼ 9>pQ.pAQp1p!p5p3ƋEȃ 9t pẼ 9u Wũ RPVXZuPEPEVuuuEЃ ;EẼ ;E8te WZEEYuPE^uXuPVuVuuE؃ ;EaEԃ ;EE WZYPu^XEpPuE܃ ;EE؃PPuEԃ uPPVuVuuE ;E<E ;EDPuE1;&VW$~VWZYPu W9|PuU rRPZYuPE ;Ee[^_]ËUMuU@uU3u$U&uUuU uUtE ;E"UtUt[UtE ;EUtUte[^_]ÍUtE ;EUt~MttE ;EM[tQt UDtƋE ;EtU*tE ;Euj PEPE8멐&UQe[^_]ÍPEPEƈmƋE 9tUXQ V&'UWVSu$u VYE_uPXEZVp$E䋳 9uE 9u'e[^_]Í&UPE 9tߍUPe[^_]ÉƋE ;tUP V V<$St$t$P[ÍUWVSE8ljEPXEZu PYE^WPXuEZPuVY_VuE䋻 9uQE 9u7U܅t$ jtE܅t PRe[^_]Ít&O&UxO륉ƋE䋻 9tU\OE 9tUJOPPju4$ƋЉސ&UWVS,@$R QqOuЉU9ыwMU9ˆUMU9ЈEuԋuЋ} WEM䍃 j?PAPM䍃 j:PAPM䍃 jPAPEЃ%EuЃPjPEP jEPEPEVPjPEPE juЃPMԃEuԃPj&PEP j=PEP jPEPu$hPjVWV4$XZjWEEԍe[^_]É'EЉE9t&} WEM䍃 j?PAPM䍃 jPAPẼEũPjPEP jPEPEЃEuЃPj PEPFEVPjPEP j>PEP j=PEP j>PEP j:PEPu$hPjVWV4$Y^jWEԃe[^_]EEԍe[^_]ÍPEPt&PEPRt&PEPt&PEPt&PEPt&PEP9 EVuԃPPjW4$RRjW4$ EVuԃډt&UWVSH} WM<$P $UUĉƍWPRVEjVPMAtP?EǃjPȃ(PMEEAt" Ve[^_]ÍvEEE܃ PEM܍ jPAP<$M܃ PWAPM܍ j3PAPEԉ$RRURP}؃uhPjWuW<$Eԃ ;cjuM j} ;u+ Wv' H딍&UG˃ WEԃ ;tUGRRjuPPEjP4$‰ԉfUVSEuPPVVu jjuPE ;u e[^]Ðt&U8Ge[^]ÉƋE ;tUG VWVSu [^_Ðt&x$ WR 9Pjj t$t9 WR 9udPjj t$[^_É' WR 9u;Pjjt$f P҃if P҃두t& P҃뺐t&UWVSt$0~u [^_]Ít&h$ P$XZVWPT$$ UL$ R 9Pjj vD$t th UR ;T$ uy1QRPt$+$T$FXV\VWP$Dž[^_]Ív t$뇍& P҃Kf P҃yfUWVSt$0~,u [^_]Ít&@$D$ P$YXVWP,$L$ R 911QRPV$T$&UV$ V9|+$T$ F0V4t$R ;T$ uL1QRPVXZVWP(D$ǀ[^_]Ív P҃1f P҃멐t&UWVS\u8t e[^_]Ít& VP P PZYPVE1:t* H;ƧiŸ)A PEŨvRP‰EUEEt&~XFT9t!EԍvEԃ 0EE9uMEUąw8x}̃uvWP XZvWPFL~H9t>E'9}t(@;t RЃ9}u&M̃vQPuF121҅xN`Fd)9} xFT R V9|ŨvRP,FH~L9t=E&9}t(W@ 9t MȃRЃ9}ԋMuݐt&M̃vQP0A Pe1[^_]EE8M̃uvQP +EMUăuvQP44$E V8uDEE9E}EEԋẼvPR8Eԃe[^_]f G=PtYO| PGF VkhPEjPEXZPZYRPZYWPZYRPZYhPZYRPYu% EVEm uԉ4$UWVS @t]1E1ҋH$VRPQt?t We[^_]Í& Pt8tPWPjjP4$Rt?t W VUWVSHEPEEU B B$BEA PEЋMЋA;At'M PQPQRPEЃ@MЃ AE @uEupe[^_]Ð&}h<PjW jPV jPVXZuV<$t&}hHPjW jPV jPVXZuV<$e[^_]Ð j‰EċBEЋEȋ+BBB iEEMċUƉAAq M9ftFGFPGP 9uuԋEăxPE}hPjWYXPYZRPYZVP<$t&=UUU VE 'u Pu}= W4$ W4$ƃ u4$ƃ u Wƃ PXYWuEċ@t P렍t&UWVS}4uWF EE E܋EEE<$PE؃ 9u/U܃RPE 9u e[^_]Ð&U(9Ǎ9e[^_]ÉNjE 9tU8 WNjE؃ 9tٍU8ύ&'UWVS,E} p;pt^tAGPFPGFYXG PF PXFZWPEpEpe[^_]Ð&WVuމNjEԋF ;EtU 8 WNjF M9tύU7Ő&St$D$p [ÍUWVS,E} p$;p(t^tAGPFPGFYXG PF PXFZWPEp$Ep$e[^_]Ð&EWV PډNjEԋF ;EtU 7 WNjF M9tύU6ōt&WVS|$t$ wZYVPG$_ZVPR [^_D$ D$t PR D$t PR 1 D$P$ D$P( 1UWVSu8UV}EtZQQRPUԃ< RRRPPPPEPU< QQRPRRRRZYVW$Ve[^_]ÉPPjV<$St$[St$[St$[St$[St$[St$[St$[St$[ <g(AD,Tl <Q_>a +7M]Fb$u ]BL-V +xBN`oepy6?Gu&:BMn#IZs{!@HuLRo@*&/Ek&$Ch''-S-S (>uB#C 1E` ;g:i6y?YO 1a} 1a}BD994 &:U"/;H[emf7;!,Ae!'Ne$!L"@3e!L"@, b6M^-@ A0 +  ; "  C     H"{>.vK,8JUj BaM] m }            JBSb#<(i/+NZo|T#4&mRg"!#Zv;@Ul*Me E] $3*pSo!#Vu5!6/4+3p*+?} im9Q9n.-#b-#b*Um e|*2t#5*+&8\&<9.)5HV'R]{A2JYnz2t&$u"' $u"' $}"/ $}"/  0#=Os&<975/I[&<9C;)5Hbt&<9B#1HXly1IE\bxw 09 +6z_<;~&3%2zO6.4*o{6+1*lxr4d)6 ,R*/L63*nz%{!i3+E`4&,:L p 0      J  j  0   ' 0 :   a N_w]%R4L.50t               3!!Q8/ 83s|"+Me+c(nE}5$AP-D'?%$H_U$H_U$H_U!>\&EK c v!  $      "            #      !  !  2   'M%NW`x! sM"@Xm!!!!IM"@Xm!!!!IPx90!7WO'Du90!7I  !  !  2    #g'Ar0-,Fhu7-4R'h&eX2Afu;$ }(,AVm-EU$1Ec:\I8&ySD "  * %@ \=F """#EP}* PQ] e !             !  #'DO`U?~       4?    ,      :@N:4jGA !6ZzFG/        v        _Ni|{ Gq       D            >a%PG'JVm\O:+t}! P82y! P82y! P82y! P82y! :+K\k3%5A\_$L7 2AV&8Z 5vYmqFF3Pa{PhKbPG*p***BBBBJJKKKKKKKKH K K O P P P O O O O O O L M M NNNNOOO9ALOAOCCCCCCC<OAAAAAA? \O!?!?"?"J"J"J"I%aO&I&I&I&I&I'I'G(YO)G)G)G)G)G*G*G*E-JO.E.E/E/E/E/E/C0RO1C1C2C2C2C2C2>2:6O9C:><<OYO!L#% O*mL8O')  ,F@                    n .Hd            B%-BSe      6E82)}V!mIE@7o[$HV$FU90))!E8C6-}i_c"("3 ZC       I            ?]-9U9D6?ygs ,  @)7.LWK   B   E E  23ZZ "*oU>:x\}}U>:x\}}U>:x\}}DH * U>:x\}} LKmec?"("3?Q!3tHzWv}eX:O^ v8 }5JY15JY1...\n[ DEATH ] basic_string::substr%02X(null)\0123autoTERMxtermxterm-colorxterm-256colorscreenscreen-256colorlinuxcygwinyestruet[0;3%sm[----------] [ RUN ] %s.%s, where %s = %s and ]]>]]>Non-fatal failureSuccessFatal failure:: : (Invalid Unicode 0x)\'\\\a\b\f\r\t\v\x'\""" (no terminating NUL)NULL pointing to L"% , 0x (L'1 fatal failure1 non-fatal failureExpected: Actual: failures Actual: containing "" teststest%s from %s, where %s = %s T_[WARNING][ INFO ][ FATAL ][ ERROR ]./src/gtest.ccCondition range > 0 failed. ) was requested, )../src/gtest-internal-inl.hpthread_mutex_lock(&mutex_)failed with error pthread_mutex_unlock(&mutex_)Invalid shuffle range start : must be in range [0, ].Invalid shuffle range finish : must be in range [, pthread_key_delete(key_)./src/gtest-port.ccOnly one stdoutstderrevent=TestCaseStart&name=0event=TestProgramEnd&passed=event=TestPartResult&file=&line=&message=event=TestProgramStartevent=TestStart&name=Value of: Actual: Expected: Failure Unknown result type thrown in Unknown C++ exception. , you tried test cases.%s %sevent=TestEnd&passed=&elapsed_time=msevent=TestCaseEnd&passed=[ OK ] (%s ms) %s from %s (%s ms total) TESTTESTS[==========] test casestest case%s from %s ran. (%s ms total)[ PASSED ] %s. %s, listed below: %2d FAILED %s YOU HAVE %d DISABLED %s <>&'"&#x;=Death test: Result: failed to die. Error msg: Expected: Actual msg: Exited with exit status Terminated by signal (core dumped) ./src/gtest-death-test.ccWARNING: has value "". %s has value , which overflows. = , but have left unset. < , but you have Google TestNote: %s filter = %s Running %s from %s. The value of flag --Environment variable (ignoring case) Which is: The difference between is , which exceeds , where evaluates to , , and Expected: () <= () vs ) != (), actual: ), actual: "" vs ") (ignoring case), actual: "not a substring of Which is: xml []unexpected status byte (CHECK failed: File , line posix::Close(read_fd()) != -1read_fd_ == -1detected threads.pipe(pipe_fd) != -1child_pid != -1close(pipe_fd[0])close(pipe_fd[1])Death test count (fastUnknown death test style "" encounteredclose(args->close_fd)chdir("") failed: execve(, ...) in failed: ) < () >= () > ( is listed more than once. No test named You forgot to list test Test @-h-?/?--help|stack != MAP_FAILEDtestsuitestestsuitetestcaseCondition false failed. Attribute is not allowed for element <>.="runnotrun /> <failuresdisablederrors this->size() (which is %zu)vector::_M_range_check: __n (which is %zu) >= this->size() (which is %zu)Global test environment set-up.Global test environment tear-downXML output file may not be null Could not write to the test shard status file "%s" specified by the %s environment variable. Invalid index (%d) into TestPartResultArray. Cannot generate a number in the range [0, 0).Condition range <= kMaxRange failed. Generation of a number in [0, but this can only generate numbers in [0, Condition sockfd_ != -1 failed. Send() can be called only when there is a connection.stream_result_to: failed to stream to ./include/gtest/internal/gtest-port.hpthread_mutex_destroy(&mutex_)Condition 0 <= begin && begin <= size failed. Condition begin <= end && end <= size failed. CloseConnection() can be called only when there is a connection.Condition sockfd_ == -1 failed. MakeConnection() can't be called when there is already a connection.stream_result_to: getaddrinfo() failed: stream_result_to: failed to connect to Condition sizeof(Integer) <= sizeof(parsed) failed. capturer can exist at a time.pthread_mutex_init(&mutex_, NULL)event=TestIterationStart&iteration=C++ exception with description "Attempted redefinition of test case All tests in the same test case must use the same test fixture class. However, in test case to define a test using a fixture class different from the one used earlier. This can happen if the two fixture classes are from different namespaces and have the same name. You should probably rename one of the classes to put the tests into different event=TestIterationEnd&passed= Result: threw an exception. Result: illegal return in test statement. Result: died but not with expected error. Result: died but not with expected exit code: DeathTest::Passed somehow called before conclusion of test is expected to be a 32-bit integer, but actuallyThe value of environment variable Invalid environment variables: you have Invalid environment variables: we require 0 <= Repeating all tests (iteration %d) . . . Note: This is test shard %d of %s. Note: Randomizing tests' orders with a seed of %d . The default value %s is used. gtest_streaming_protocol_version=1.0WARNING: unrecognized streaming target "%s" ignored. pthread_key_create(&key, &DeleteThreadLocalValue)WARNING: unrecognized output format "%s" ignored. Error while reading death test internal: Death test child process reported Read from death test child process failed: posix::Write(write_fd(), &status_ch, 1)waitpid(child_pid_, &status_value, 0)Cannot run a death test outside of a TEST or TEST_F constructDeath tests use fork(), which is unsafe particularly in a threaded context. For this test, couldn't detect the number of threads.) somehow exceeded expected maximum (Condition typeid(*base) == typeid(Derived) failed. Condition !original_working_dir_.IsEmpty() failed. Failed to get the current working directory.basic_string::_S_construct null not valid can be found in this test case. pthread_setspecific(key_, holder_base)fcntl(pipe_fd[1], F_SETFD, 0) != -1sigaction( SIGPROF, &ignore_sigprof_action, &saved_sigprof_action)stack_size > kMaxStackAlignment && reinterpret_cast(stack_top) % kMaxStackAlignment == 0munmap(stack, stack_size) != -1sigaction(SIGPROF, &saved_sigprof_action, NULL)Unrecognized xml_element provided: Condition std::find(allowed_names.begin(), allowed_names.end(), name) != allowed_names.end() failed. Bad --gtest_internal_run_death_test flag: Reserved key used in RecordProperty(): class, so mixing TEST_F and TEST in the same test case is is defined using TEST. You probably want to change the TEST to TEST_F or move it to another test using two different test fixture classes. This can happen if the two classes are from different namespaces or translation units and have the same name. You should probably rename one of the classes to put the tests into different test cases." is not a valid POSIX Extended regular expression.the test fixture's constructor This test program did NOT call ::testing::InitGoogleTest before calling RUN_ALL_TESTS(). Please fix it.Condition 1 <= seed && seed <= kMaxRandomSeed failed. auxiliary test code (environments or event listeners)... Google Test internal frames ...VSD$ @P;u [^Ðt&t&HȅۃD$PRȍvHqpUWVS }7G9tt  PR9wut Pe[^_]ÉƋt R VWVS|$ G 9uG 9u)G 9u7[^_ÍT$lG 9tܐt&T$lG 9tΐt&T$l[^_WVS|$ G 9u 9u"[^_ÍvT$l 9t䍶T$l[^_VSt$ F$ ;u# FV$[^Ðt&T$lVSt$ F$ ;u+ FP4$$[^ÍT$lUWVSt$0|$49>t3 jt .tE ;u U>[^_]Í&T$lUWVSu~tREu P}W PWvE ;u e[^_]Ít&Ule[^_]à jQ ZYPFP눉ƋE ;tUl VUWVS,u} 9>tP jt=Et4@ x PEԋEЃ ;u" u>e[^_]Ív'UlԉƋEԋA;tUl VUWVS$u}u V<$ PWVe[^_]NjA;tUl WUWVS8u u}YZMԃ HQV uu VXZWVe[^_]NjA;tUl Wunknown file./This program contains tests written using Google Test. You can use the following command line flags to control its behavior: Test Selection: @G--gtest_list_tests@D List the names of all tests instead of running them. The name of TEST(Foo, Bar) is "Foo.Bar". @G--gtest_filter=@YPOSTIVE_PATTERNS[@G-@YNEGATIVE_PATTERNS]@D Run only the tests whose name matches one of the positive patterns but none of the negative patterns. '?' matches any single character; '*' matches any substring; ':' separates two patterns. @G--gtest_also_run_disabled_tests@D Run all disabled tests too. Test Execution: @G--gtest_repeat=@Y[COUNT]@D Run the tests repeatedly; use a negative count to repeat forever. @G--gtest_shuffle@D Randomize tests' orders on every iteration. @G--gtest_random_seed=@Y[NUMBER]@D Random number seed to use for shuffling test orders (between 1 and 99999, or 0 to use a seed based on the current time). Test Output: @G--gtest_color=@Y(@Gyes@Y|@Gno@Y|@Gauto@Y)@D Enable/disable colored output. The default is @Gauto@D. -@G-gtest_print_time=0@D Don't print the elapsed time of each test. @G--gtest_output=xml@Y[@G:@YDIRECTORY_PATH@G/@Y|@G:@YFILE_PATH]@D Generate an XML report in the given directory or with the given file name. @YFILE_PATH@D defaults to @Gtest_details.xml@D. @G--gtest_stream_result_to=@YHOST@G:@YPORT@D Stream test results to the given server. Assertion Behavior: @G--gtest_death_test_style=@Y(@Gfast@Y|@Gthreadsafe@Y)@D Set the default death test style. @G--gtest_break_on_failure@D Turn assertion failures into debugger break-points. @G--gtest_throw_on_failure@D Turn assertion failures into C++ exceptions. @G--gtest_catch_exceptions=0@D Do not report exceptions as test failures. Instead, allow them to crash the program or throw a pop-up (on Windows). Except for @G--gtest_list_tests@D, you can alternatively set the corresponding environment variable of a flag (all letters in upper-case). For example, to disable colored text output, you can either specify @G--gtest_color=no@D or set the @GGTEST_COLOR@D environment variable to @Gno@D. For more information, please read the Google Test documentation at @Ghttp://code.google.com/p/googletest/@D. If you find a bug in Google Test (not one in your own code or tests), please report it to @G@D. GetParam()TypeParamthrow_on_failurestream_result_tostack_trace_depthshufflerepeatrandom_seedprint_timeoutputlist_testsfiltercolorcatch_exceptionsbreak_on_failurealso_run_disabled_testsinternal_run_death_testdeath_test_use_forkdeath_test_stylefastGTEST_SHARD_STATUS_FILEGTEST_TOTAL_SHARDSGTEST_SHARD_INDEXtest_detail.xml**DeathTest:*DeathTest/*DISABLED_*:*/DISABLED_**N7testing8internal12_GLOBAL__N_123ClassUniqueToAlwaysTrueE Stack trace: UWVS`, QEEEEG~V EE`EG,,Dž0X GZjPYXF4P4ЋVjPFV8@,Dž<Dž@DžDDžH DžLDžP,4` 48T$DžX8 \XZWE 1'RP(PZY( ;Wu ,4` 48\ ; 8FV@,FV4@4FV ,@,`XEe[^_]t&jP(lG&l,:Y|Ƌ( ;t &l 4$ W_XFP  `4$WƉ,,UWVS`, QEEEEG~V EE`EG,,Dž0X GZjPYXF4P4ЋVjPFV@,G Dž<Dž@DžD,G4DžHDžLDžP`G 48T$DžX8 \X8ZPE ''RP(PXZ(P;uG ,G4`G 48\ ; 8FV@,FV4@4FV ,@,`XEe[^_]&jP(lDt&Hȅ&PR뷋HH͉Uk(t YXFP  `4$WƉ,,(A;u 4$ytRR&RP뿋QzyUWVS$uu VXZuVe[^_]NjA;tUl WUWVS0Eu jljEЍPVE<\t&jPVvjuV jPVXZWVEЃ<jPVe[^_]ÍjPV juVӍvjPVfjPVFjPV&jPVjPVjPVjPVjPVG^ EWPEEY‰EXEPPRXEZpPVE䋋 9E 9juV}JPjPVXZWVEWPY_jPVE pPVE ;UlUlfU߉MlMEEЃjEEPV juV}QB ƋE䋋 9tU߉MlMԋE 9u VƋE ;tUlUWVS0u }jPVEEЉ<\jPVvjuV jPVXZuVG<jPVe[^_]fjPV juVэvjPVfjPVFjPV&jPVjPVjPVjPVjPVEЃ ^!ERPEEEXEZPPQXEZpPVE䋋 9E 9juV@WjPVXZuV&EWPY_jPVE pPVE ;UlUlYU߉MlM8vEEjPV juVoQ, ƋE䋋 9tU߉MlMԋE 9u VƋE ;tUlUWVS0u }jPV<^EԍjPVue[^_]Í&jPVYXWV}tGw$jPVe[^_]Í&EWPXZjPVE pPVE ;tUl듉ƋE ;tUl VWVSt$|$9>t% jtt PR>[^_UWVSE8} EPuEP UWUЃ PWRFEuP}W PWvE ;u[Ut$ jtEt PRe[^_]Í@PBPRft&Ul뛍 jY_ PFP6E ;tUlPPju4$UWVS}8uWE pPEPNt~EWPEPE PuvE ;u5Ut$ jtEt PRe[^_]ÍUl jYZ PFPYƋE ;tUlPPjW4$UWVSE8} EPuEP UWUЃ PWRFEuP}W PWvE ;u[Ut$ jtEt PRe[^_]Í@PBPRft&Ul뛍 jY_ PFP6E ;tUlPPju4$UWVS}8uWXEZu PNEWPEPE PuvE ;u8Ut$ jtEt PRe[^_]ÍvUl뾍 jYZ PFPVƋE ;tUlPPjW4$UWVSE8EԋuPE 8 W PEWPFEuP}W PWvE ;u_Ut$ jtEt PRe[^_]Ív'jPEP`vUl뗍 jY_ PFP2E ;tUlPPju4$UWVSu(}VXE Z0EPRYXVWU t$ jtEt PRe[^_]PPjV<$U1WVS8u~PuQ}hPPjW j PPE j5Pu<$E xWPv9tx}hUPjW j&PPEF pPu jUPRF pPu<$e[^_]É W4$ W4$UWVS8uVuFFe[^_]Íh<PEjPE jP jPZYWXu낉ƃ u4$UWVS8E@Pue[^_]ÍhHPEjPE jPW jPWZYVWXue[^_]Éƃ u4$UWVS8uu e[^_]ÍvhyPEjPE jPW jPWZYVWXue[^_]Éƃ u4$UWVS8}G+9E EЋE !Ph:PEjPE j.PV jPVYXu Vƍ jPVXZuV jRPYu E9Eu19u !Pt[u+u E~9Eԉ}Vu}E Uԃmʃ:8 u͍e[^_]Ðt&h=PEjPE j.PV jPVXZuVƍ jPVYXu Vƍ jPVXZuVZYRPXu u4$ u4$U1WVS(u~PuP}haPjW j P j@P<$ vFe[^_]Éƃ W4$UWVS8E0t  PRE 0t^}hPjW jP jPXZV<$Exp9tDEEЉM t& 9t!F ;EtUЃ l9u捴&Ext We[^_]ÉEƃ WuԃEpx9t1E㋋EЋG 9tUЉMlM̃ 9uEpt V uUWVS8u6t PR 6u e[^_]Ít&hPEjPE jPW jPWZYVWXue[^_]Éƃ u4$UWVS,E0N0 wyEԍEj PVƋE׀8u5Eԋu, jtC9u,E 0"& jEtt&1e[^_]ÍEhPEjPE j4PXu}r룉ƃ u4$UWVS,u~tv juP}haPjW j P j@P<$ vFF 9u"F 9ue[^_]ÍUle[^_]ÍUlԉEE WF 9tUlF 9tUl uUWVS,u~tv juP}haPjW j P j@P<$ vFF 9u2F 9u Ve[^_]Ít&UlލUlĉEE WF 9tUlF 9tUl uUWVS8EPPu e[^_]ÍvhyPEjPE jPW jPWZYVWXue[^_]Éƃ u4$UWVS8uFPu Ve[^_]Ð&hyPEjPE jP jPZYWXu뀉ƃ u4$UWVS,uF jv@;~tv juP}haPjW j P j@P<$ vFF 9uCF 9u) Ve[^_]Ðt& VЃ萍t&Ul͍Ul볉EE WF 9tUlF 9tUl uUWVS}4u@u WE jPWE; 1~PuPhPPEjPE j PW j5PWZuE܃xWPv9trhUPEjPE j&PWF pPWǍ jPWF pPWXuE܃ ;ue[^_]ÍEWVՍt&Ule[^_]É uE܃ ;tUl VE܃ ;tUl׃ uUWVSu E xEPPVYXVuV<$ PWVXEZVpE䋻 9uE 9u e[^_]ÍUlE 9t捶le[^_]ÉƋE䋻 9tUlE 9tUl VUWVSu8u } VDPEPE uPV4$wE䋋 M9u(E ;Eu5G PR e[^_]ÍUlE ;EtАt&l‰ƋEƋE䋻 }9tUlE ;EtUl VUWVST} wNwDEPEG}ԉEЍEЉ$WEEĉ4$PEXuȍZuPV4$uV jPVE؃ WVPu܉<$V j PV} uVWE<$pE䋳 9upE܃ 9u~E؃ 9Ẽ 9Eȃ 9Eă 9Eԃ 9E 9e[^_]Ív'UlE܃ 9tlE؃ 9{vlẼ 9qvlEȃ 9gvlEă 9]vlEԃ 9SvlE 9Ivle[^_]ÉNjNjE䋳 9tUlE܃ 9tUlE؃ 9tUlẼ 9tUlEȃ 9tUlEă 9tUlEԃ 9tUlE 9tUl WNjlNjE܋ 9hUl[NjNNjS NjTE̋ 9@Ul3Nj8UWVS,uV j~@;tz juThaPEjPE j P j@PXu wGG M9uTG ;Eu9 W Ve[^_]É' WЃؐt&Ul뽍Ul뢉 uG U9tUlG ;EtUl VUWVSE֍}@PPWEYp@EXW}W jPWE; 1~PuPhPPEjPE j PW j5PWZuE܃xWPv9trhUPEjPE j&PWF pPWǍ jPWF pPWXuE܋ 9u5E؃ 9ue[^_]ÍvEWV̍t&Ule[^_]ÍUl"QgNj(ǃ uE܋ 9tUlE؃ 9tUl WE܋ 9tՍUl˃ uUWVSEuD}PVYXVPWEp@<$}WE jPWE;& 1~PuPhPPEjPE j PW j5PWZuE܃xWPv9trhUPEjPE j&PWF pPWǍ jPWF pPWXuE܋ 9uIE؃ 9uWEԃ 9ue[^_]Ðt&EWVt&Ule[^_]Ð&UlE؃ 9tUl량NjSE܋ 9tUlE؃ 9tUlEԃ 9tUl W uE܋ 9tUl뫉Nj볉 Ɖz uUWVS}@E pEPPWXZW}W4$ PVWEY^p@W}WE jPWE;% 1~PuPhPPEjPE j PW j5PWZuE܃xWPv9trhUPEjPE j&PWF pPWǍ jPWF pPWXuE܋ 9u@E؃ 9uNEԃ 9ue[^_]Ít&EWVt&Ule[^_]ÍUlE؃ 9tUl먉]Nj& uE܋ 9tUlE؃ 9tUlEԃ 9tUl WE܋ 9tÍUl빉E؋ 9tUl멃 ulNj댉[UWVSu(}VE p0EPRYXVWU t$ jtEt PRe[^_]PPjV<$UWVS}Tu FXV\EEUPWV EURPEPEu̍ uPV4$uV jPVE؃ WVP<$}W jPWXEZWpE܋ 9u?E؃ 9uMEЃ 9u[Ẽ 9uiEȃ 9uwEԃ 9e[^_]ÐUlE؃ 9tlEЃ 9t&lẼ 9t&lEȃ 9t&lEԃ 9t&le[^_]ÉNjFNjE܋ 9tUlE؃ 9tUlEЃ 9tUlẼ 9tUlEȃ 9tUlEԃ 9tUl WNj륉tNjNj뾉NjEЋ 9tUl{UWVS}Tu F0V4EEUPWV OURPEPEu̍ uPV4$uV jPVE؃ WVP<$}W jPWXEZWpE܋ 9uBE؃ 9uPEЃ 9u^Ẽ 9ulEȃ 9uzEԃ 9e[^_]Ít&UlE؃ 9tlEЃ 9t&lẼ 9t&lEȃ 9t&lEԃ 9t&le[^_]ÉNjFNjE܋ 9tUlE؃ 9tUlEЃ 9tUlẼ 9tUlEȃ 9tUlEԃ 9tUl WNj륉tNjNj뾉NjEЋ 9tUl{UWVS}Xu VYEUXEPWV DURPEPEu̍ uPV4$uV jPVE؃ WVP<$}W jPWXEZWpE܋ 9u@E؃ 9uNEЃ 9u\Ẽ 9ujEȃ 9uxEԃ 9e[^_]fUlE؃ 9tlEЃ 9t&lẼ 9t&lEȃ 9t&lEԃ 9t&le[^_]ÉNjFNjE܋ 9tUlE؃ 9tUlEЃ 9tUlẼ 9tUlEȃ 9tUlEԃ 9tUl WNj륉tNjNj뾉NjEЋ 9tUl{UWVS8hƍ@4$EƆdžƆdždžGdždžF4O GʉEЉM̉@FXZQjRYXGWF@DjPGWN MЋ@FFFFP F F$P4 FV4F F($F,F B F0XZuuEY_0Eu PEZYpPEEԃPE ;ue[^_]Ív'Ule[^_]É;cKMЉNjQM̉  F4u4$<$E ;tUlPPju4$ uЉEXZWRVẼUWVSEݕ@Eݕ8D@D%=<8<04D-D@ϋ<<89wi)׉w 3vp ljP0ƅDžƅDžDž FDž$Dž(VN Bp(,pDžtYXBjPNxXZQx$N jR VNBpDžB DžDžDžDžpB4DžB xB|$DžAY|B |XQ0x @D@WDŽ|,lj`$@,EEEEA(EEE`B,,Dž0XBYjP$Y_J44 jQB,B Dž<Dž@,B4DžDDžHDžL`B DžP4AT8 $DžXB8A \XZ8R@ 4 @<8WDŽ8XPZP8XTP hWXV j PXPYXVWXZjV^XE PW\lj4$ jP\PXZVWYXjVXEZPW`lj4$ jP`PYXVWXZjV^XPWZY Pdlj4$ jPdPYXVWXZjV^X8WZYPu^l_jPT ;P ; ,4` 48\ ;W 8(Y@,$ 4@4,,@@,` p4 x| ;M | Z@p$(x@x,p@0pEe[^_]& uE e[^_]t&9)&D@ ~'<ȋ8 T&04؃ ރt&llSlXl PPjVPPljPT ;t OlP ;t Ol  4$,ƉpW(p 04$D(QQjV$PPjVPPjVM XFZPXƋ,(,@, @` YXFP몉xUUWVSEEEUсƁمIΉЉ HƉ)Ɖ)9Bƒ(p lj P@ƅDžƅDžDž FDž$Dž(FV p<@8pDžtXAZjPVY_Jxx4ȋNjP0VNB,(pDžB DžDžDžDžpB4DžB xB|$DžA||B DXZQ@xE@\$<$DŽ|,lj$`$DE8EEEA@;tz juThaPEjPE j P j@PXu wGG 9uCG 9u) WE e[^_]à WЃ萍t&Ul͍UMlM뭉 uG 9tUMlMԋG 9tUl VUWVSt3 jt .tE ;u U>[^_]Í&T$lUWVSt$0|$4L$8F;FtJtPFPVP1)u7[^_]Í)RWPލ)9D$)Љ‰L$ T$ t$L$ T$t)‰u~LV)uD<t P.l$~n@D$)Љwt&RT$WQL$T$ L$뜐&RT$PUT$g=?l$)Չ1.UWVSt$0|$4V;VtFtBBFD$80B)u 7[^_]Ð)PWR㍶) 9D$)‰T$ t$ŋD$T$ )tD$8ujVL )u8<t P.l$~nIfD$)fRT$WQL$T$ L$먃QL$t$UL$ x?(T$)…!щD$17UWVSt$0|$4L$8F;FtJtPFPVP1)u7[^_]Í)RWPލ)9D$)Љ‰L$ T$ t$L$ T$t)‰u~LV)uD<t P.l$~n@D$)Љwt&RT$WQL$T$ L$뜐&RT$PUT$g=?l$)Չ1.UWVSt$0|$4L$8F;FtJtPFPVP1)u7[^_]Í)RWPލ)9D$)Љ‰L$ T$ t$L$ T$t)‰u~LV)uD<t P.l$~n@D$)Љwt&RT$WQL$T$ L$뜐&RT$PUT$g=?l$)Չ1.WVSt$|$9>t% jtt PR>[^_UWVS\MgẼ 9jEЃ 9tEԃ 9~E؃ 9E܃ 9E 9E xPu֍E}EvPWXEZPPEPEM؍ PuQMXEuPE jPuUЃ WuRU<$}W jPWZEYWPE jPuXuEȃ 9UlẼ 9&UlEЃ 9flEԃ 9vUlE؃ 9zfUlE܃ 9pv'UlE 9^v'UlLve[^_]ÉƋtƋEȋ 9tUlẼ 9tUlEЃ 9tUlEԃ 9tUlE؃ 9tUlE܃ 9tUlE 9tUl VlƋy ƋzE̋ 9fUlYƋ^Ƌ_ƋdEԋ 9>Ul1VSt$V4$[^SD$P[VSt$V4$[^SD$P[VSt$V4$[^UWVSt$0|$4L$8F;FtJtPFPVP1)u7[^_]Í)RWPލ)9D$)Љ‰L$ T$ t$L$ T$t)‰u~LV)uD<t P.l$~n@D$)Љwt&RT$WQL$T$ L$뜐&RT$PUT$g=?l$)Չ1.UWVS}(WE 0tg V PEVPWuU t$ jtEt PREe[^_]vjPEP뙉PPjW4$UWVSt$0|$4L$8F;FtJtPFPVP1)u7[^_]Í)RWPލ)9D$)Љ‰L$ T$ t$L$ T$t)‰u~LV)uD<t P.l$~n@D$)Љwt&RT$WQL$T$ L$뜐&RT$PUT$g=?l$)Չ1.UWVS t$$L$(l$,ϋV);Vt9t(UQVL$  [^_]t&t EVVUWVS,|$DD$l$@D$ uH& Wt.w UGw ;t΋T$ lÍv,[^_]UWVSD$4xPT$ D$8T$D$ht&|$t0Gp9F)Qt$ PDƅy̋ uЋD$9D$ tK@p9FQPt$)D…x D$0T$D$0[^_]&D$0T$ D$0[^_]UWVS,E xEԅEPE܉UBtB‹zEUw9F΃QWu܉MMU)DxB 1Ʌuɉ׉}UEEuFUPuuU؃)օDƅE8@Ee[^_]}ԍE 9x t0 WE}ϋPE܋ApE9F낉}u9uEVrx9F)QRPD1xz jƍ@uPuuVWE @E0@Ee[^_]E`1 jƍ@| P4$ VUWVSEE@p91>*t Q Pt$jue[^_]Ívuh{PjV j3P4$롐t&ǃ V<$UWV,Slj`P$EEEEEFEE`N Fʉ, @,Dž0XAZjPXZV4z4VωjWV~B ,Dž<Dž@DžDDžHG DžLDžP,G4`G 4BT8$DžXYB8B 8\XR$E p0ZYuG ,G4`G 48\ ; 8 @,4@4 ,@,`X$Ee[^_]'+lQ"C Ɖ,Q, $`4$ 4$롃 XFZPUWVS t$$l$(|$,):I'vWt]vWtRvWtW 9tp6WuD$ 0D$ [^_]v'ݍvD$ 0D$ [^_]D$ 0D$ [^_]'D$()t8ttDD$ T$(D$ [^_]uWt,uWtuWuD$ (.l$$UWVS|$4t$8)D$<(uD$ -t&G9ptPG9ptxG 9p9|$ 9puЃVUPuD$08D$0[^_]fVUPuD$0WD$0[^_]&VUPrD$0W럍&VUPVD$0W tt&t$ D$8)ttVtFD$0L$8ED$<j9hte9hu׃URPuŋD$00D$<jыT$<Hj9t밃QRT$PT$ u뷃URT$PT$ u뛋t$4HUWVSt$4D$8l$0|$<)D$ vt7pFt7pFt7pF t7p;t$ xT$8)t:ttMD$8E[^_]t7ptCt7pt&t7pu'u[^_]u[^_]uӃ uUWVS|$0D$49trut Pv)t$ Pui- PuF' Pu# Pu Pu Pug Pu Put PuQ Pu. Pu Pu Pu Pu Pu Pu\Puu/&E ;iUl\PutPutPutE0uƋE ;tUl VUWVS,E8EEЍO E̍t&E <PuEZYuPEtrE9tE U D8Tv8x9uEE ;E90y8tJe[^_]É'> Puk- PuH' Pu% Pu Pu Pug Pu Puv PuS Pu0 Pu Pu Pu Pu Pu Pu^Puu/&E ;fUlYPutPutPutE0uƋE ;tUl VUWVSEE@p91>*t V Pt$jue[^_]Ívuh{PjV j3P4$롐t&ǃ V<$UWVS,t$@|$DD$D$ 9u "f9t 9tT$ l9u,[^_]UWVSU+4Y mF4_)  4c<  4gO ) "O0( 88 8888 r*ݐݐ ݐݐݐݐ ڂl9l9 l9l9l9l9zAA AAAA z'%W %}hd4eqn%lt!%xZ %? R!L:)g?M}u q4~4?ZP #?[5$%eof(Oc?G,bv?%5Q%K46<%W71'}=b;eqA=%^ltEй%|xZIM %  M Q%J  !Un gYA& }]` J~aWVdZPe[5i%eofm>=GqS6566J67d|7civ5 %}8\} 1T8_8`bJ8c}8dL8qDJL8sZe 8yq %8\2T8_bJ8c8dL8qŐL8sŐː 8yŐ % p A h !] *"A CSѐ*#5\ѐ %T y$5 h!\ ! x zbJ { |( y4f 6b  p "  #| $ %E h%"g h%"q j mF &%2&us%7'&˓%B'N9 G(x %} (_ f% )   )P > ) @ h( ލ* ( '*$ 4 %! CX hh) aRk v *W%y +U; <* ,l%oe* h+ $1* א+ (g*  ݐ*+! ,n71 7 א+N 2O U א+ 6Xm s א* : ݐ+ A5h אh'*4 Kk6 אhh'+ S2h  אhh+V [$% ) א'( d^I *'hM mi *'h vI *h'%f\   *f\ ` *f\ N ***f\  *''  N %( hh*(%II< Q ݐhhh*+%3e k ݐ-N9 ..  ݐ/.% ݐ.% ݐ.% ݐhh.% ݐhh.%'<ݐ'h.%L\ݐ'.%lݐh'%.R "ݐ %0I *.ݐ0I 2zݐ'0I = ݐ'%0R) f"(ݐ0R) q5AGא1end y`fݐ1end lא0 ݐ0 ;א02 ݐ02 א0 2h א0 Xh9?א0 bXhX^א2"%ޕsݐh'%2" ֎ݐh0 Shא2%Hݐh2x -ݐ0' 5)%א0C Dq5@אh0C U4Ydݐh1at kH|אh1at quݐh0H  ݐ0H ݐ'0H R| ݐ'%0S%D/:ݐ0S%UShݐhh0S%)ݐ'h0S ߩݐ'0S%Aݐh'%2q -H ݐ'%3}%/!ݐ0} ^:Oݐhh0}%=hxݐ'h0} zݐ'0} ݐh'%2  :ݐh'%0  ݐh0  \81Kݐhhh0 %gdyݐh'h0  "kݐh'0  90ݐhh'%0  Kݐ'%0ז dU"ݐhh0ז t};Fݐ0ז%_oݐ0H -Bݐhh0H Lݐhhhh0H% ݐhh'h0H !6ݐhh'0H Oiݐhhh'%0H GUݐ0H '+ݐ'h0H <gݐ'0H QX+ݐh'%0H v|D^ݐ**0H @wݐ''0H 7Eݐ0H Aݐ+v"%{)ݐhhh'%+%?&A[ݐhh'hl f*h'%4`)%ه*h'%0g%hא*hh2 %v2ݐ04 ' א0y2 %'U'(.א0$ ,%GMא0%Dhf{א'hh0 Ihאh0 XJthא'h0%hא'%h0lJ vO hאh0lJ% N3h8Mא'hh0lJ hfvא'h0lJ% !hא'%h05 Chאh05%/lhא'hh05 hא'h05 .h8Hא'%h0 Shaqאh0%>vhא'hh0 hא'h0 $Yhא'%h0Y$ 2h אh0Y$%Sh3Hא'hh0Y$ QCHhaqא'h0Y$%_$hא'%h0ڰ q/hאh0ڰ%j{hא'hh0ڰ Inh א'h0ڰ%h3Cא'%h0q \lאhh0xZ y %א0xZ%: %אhh0xZ% %אhhhh0xZ%I %א'0xZ% %3Hאhh'0xZ%j %a{אhh'h$ 4`%{P*X''' )*'''` \1*'''%)>H'ݐ''4%{*tX***g N**** K****% H*ݐ**!'%59(56+O6aJ p6A  !] ("A h x  (ː#5   %T y$5   !\ !8  xbJ { | 8f 8b 6p 6 #| =!%E %"g %"q j mF " !&%2 &us%7S(&˓%B'N9 %(x ?Z%!!7(_ ,%!!7)  Ǯ!!)P ˬ!!) q! " ( ӳ( "&"( u2(="M"ːː%!q"  ː) ""ː*W%M""ː+U; ("",l%o~("ː + $( ##+ (('#2#(+! ,ϱJ#P#+N 2 h#n#+ 6L= ##* :?##+ AH ## '*4 Kګ##  '+ S $$  +V [0%7$B$M(( db$(M( M mE#$(M(  vڿ$( <%f\ $(  f\ c$(  f\ 5F%(((f\ h"%(M(M(   %A%  *(%U%j%   *+%~%%-N9 ͟%.. %%/.%%%ː.%%%+.%%&+  .%&0&+  ː.%@&U&M( ː.%e&u&M(ː.%&& <%ː.R "&& %0I *-k1&&+0I 281&&M(0I =Ώ1'"'<%0R) f> ;'A'0R) q Z'`'1end yt{ y''1end 3 ''0 !''0  ''02 !''02 1 ((0 `3 3(9(0 N R(X(0  q(w(2"%_(( <%2" L(( 0 z ((2%(( 2x -w))0' 5%/)5)0C Dհ N)Y) 0C U  r)}) 1at k3 )) 1at  )) 0H 1))+0H L1* *M(0H 1$*/*<%0S%D1H*S*+0S%U.1l**+  0S%)#1**M( 0S &*1**M(0S%X1** <%2q -M ++<%3}%)1/+:++0} ^11S+h++  0}%d1++M( 0} z1++M(0} ]1++ <%2  +,  <%0  _]1!,1, +0  71J,d, +  0 %g1},, M( 0  "D1,, M(0  91,,  <%0  KƢ -- <%0ז d$1+-;-  0ז t8 T-_- 0ז% x--  0H 1--  +0H 41--  +  0H%y1.!.  M( 0H 71:.O.  M(0H LG1h..   <%0H 51..  +0H 'w1..  M( 0H <41./  M(0H Q-@1*/D/   <%0H v%1]/w/  ((0H 1//  M(M(0H ˧1//    0H ,1/0    +v"%T1(0B0   <%+%1Z0t0  M( l P(0 <%ː4`)%(0 <%ː0g%} 00(  2 % 0 1104 M("1(10y2 %QM(A1G10$ ,^ `1f10%  11M(  0 I 11+ 0 Xɛ 11M( 0% 12<% 0lJ vC (282+ 0lJ% = Q2f2M(  0lJ y 22M( 0lJ% 22<% 05  22+ 05%/ 23M(  05 RC (383M( 05 ` Q3a3<% 0 W z33+ 0%>[ 33M(  0  33M( 0 $b 3 4<% 0Y$ 2O #434+ 0Y$%SC L4a4M(  0Y$ Q2 z44M( 0Y$%_ 44<% 0ڰ qJn 44+ 0ڰ%j $ 4 5M(  0ڰ & #535M( 0ڰ%C L5\5<% 0q Z, u55  0xZ W  %55+0xZ%# %55  +0xZ% %56  +  0xZ%  %(636M(0xZ% %L6a6  M(0xZ% %z66  M( =!!<%59566, CR9>7h"!3^7 ] 9[ , P r ,$  8 ɖ  M  H  / y z f< 7!g7   g  C  \U7[!7  2 e ' 7!7 J   8i:9}!J8:v!j:!%.}!+818^;_g!>8^ %!6<1d!J70!BiJ8|88vQJ80!SqYJ888vQJ8J80!v88vQ0ߠ!88vQdec!9=!9>hex! 9=ֿ!9=!9 >oct!9@=ϰ!9? !9?^!"9?+!&9?8!)9?M(!,9?H!/9 ?!39@=<!69=!99J?!<9=7!N:V8=@!Q:=i!V:=N!Y:>app!lY:8>ate!oY:=n!tY:>in!wY:>out!zY:=!}Y: <>!7>beg!::>cur!:>end!::Ro:Sd:T1':\:e:h:iΑ8=@?];/;?;L %L.ՉP;`;L %L3FQx;;LQ%mG;3l7Q;;Ls^3FQ;;L,3lFQ;;L%3Q<<L3Q3<><Lu3vFQV<a<Lm%!'%59(3N;n<<L'3.;<<LAput;;A<<L<>'%3];?Q ==_%L_%3;iF,=7=L %3;?X=c=%L%3";?!+==uLuB?;?=,L, 'l>CGp=xh777Cp>xh7:7:7:Cvp!>xh:::Cjwp@>xhBBBC,p_>xh@@@C<p~>xh/A/A/AD pxhMMM )W?E)[B>HBxhBBBBE~7)[7:?H7:xh7:7:7:7:E-)[:9?H:xh::::Erz)[@j?H@xh@@@@E4)[/A?H/Axh/A/A/A/AF)[MHMxhMMMM Fi@(I*\FM*>NW#>O6FPH>FQ>$FRX>&/>%I_TpF68?; $F%X$ % $מF%X$ %7**ZF A + *\jG%j*aFr*^5%E*bF%b*cF%Ss*dF k*_54*g*F"GF4*nWF;GF4*uFTGFS*|X6FFF b+`G%+e5%.+f5G+lGG5G+pGG555I_T15I_T258!vwH1strG>HGH*-oGlOwO66OK+*poGOO66++t*loGOO6K6+M*MoGOO6K6+ *l KPP65K5K6+*eK4PDP65K6+a*DK\PgP66+(* {KPP6K{K*O*PP6{K+P*KKPP6{K{K6+P*B4KPQ6KK6+N[*\K Q5Q6{K{K6+N[*KMQbQ6KK6.*sQyQ6.*QQ666K.*QQ66.u*QQ6 %0I*G6QQ660y*[AIRR60R)* K3R9R60R)*]KRRXR61end*MKqRwR61end* }KRR60*UKRR60*rbKRR602*fKRR602*K SS60'*n%+S1S60*3 KJSPS60*M KiSoS62 *eYSS660v*`ZSS660a*qKSS660I*7IKST6K60*/KT)T6K6*+;*D%=THT6K*+;*R\TlT6KK2ז*iITT6K2ז*mH>TT6K0ז*_i KTT662ז*'TT6KK2ז* UU6KK2ז*k0/U?U6BB2x*Y+TUZU60*vKsU~U660*\sKUU660[*  KUU660%*KUU660%*KVV660%*WNK'V2V660%*TKKVVV660N**ZoVzV660N*IZVV6600*%VV62'0'6sIH N*tXr*F%=*VbJ*6E*^)z*V *K6G*IWOWE\*^WiWE/W(FH*WWWE(9N*ȎWWWE(H*EWWE(H*Z$WWWE %(M**EWWE(M*($WX!XE %(ȃ*紴%8XCXEE$W(_(*f%_XjXEEI_Tp' *QZr*F!=*>XbJ*6E*B*Vz*tX *Q6"*XX6]*XY6X"*YY66X++* ĨX8Y>Y7+FH*XVY\Y7+9N*+WXtYzY7+H*B 7YY6+H* AXYY6 %+M*( 7YY6+M*/LXYY6 %+ȃ*7Z=%ZZ77X+_(*;,Y%FdQd77.bdmd7 %3I7dd772}dd7c70R)#cdd70R),Qcdd71end5c ee71end>c+e1e70GuLcJePe70P|-cieoe702Ycee702bpGcee70ѡcee70Hcee72"ff7cOc0Fc)f/f70'%HfNf7bAobfmf7c0C scff7c0Ccff7c2A ff7c1at6scff7c1atH.cgg7c0pS)6sc4g:g70p[McSgYg70ÐcVscrgxg70Ðk.cgg70y2z[cgg70y2gcgg72qRgg7722G hh73 k3c(h8h7c72 0Mhbh7cc70ז}>c{hh7c0זXchh7cc2 hh772xhhh72hi7c7bHX#i3i772ǥ!Hi]i7cc72F-rii7c0?cii7c'2;#ii7[c3OP?cii7c3Ocjj7cc.0jEjxhB7BBc.djyjHB7BB.9jjHB7BB7I_Tp5_6 (6@c $j%c$'%!'%;8\kDT8_E8a7j=8b7bJ8c78d8L8qKkQk8L8saklk8#8 8y|kk8 %VC8hl8ij7j 8 Hm $ OOl j%+ROl%ySOl%TTOlG$Vkl/8G$Zll/858)e` /l:l/8;8#9PCl/8 %EM|F_lKbG%@knj(GeqA8llG8(Geu~58llM8($ykvlllM8G(|llG8G(lmG8S8vlG(m&mG8G(5mEmG8S8GTm_mG8 %(:%OlvmmG8)mmG8Olb2mmG8I_Tp7jk t_mցmjl֞lֻlk4&7EOlj=FbJFFGfIbtptTjnnY8TnnY8_8nT/nnY8}ne8_8n.>ooY8k8.$o/oY8 %3IAHq8GoRoY8k82}gowoY8}ne80R)#%MnooY80R),cYnoow81end5MnooY81end>Ynoow80Gqn ppY80Pken+p1pw802YגqnJpPpY802byfenipopw80}nppw80}nppw82"JppY8}nn0}nppw80')% qqw8bA+$q/qY8}n0C 5nHqSqY8}n0C#Anlqwqw8}n2A A/qqw8}n1at6o5nqqY8}n1atHAnqqw8}n0pSj5nqqY80p[~Anrrw80Ðc-5n4r:rY80ÐkAnSrYrw80y2z^nrrxrY80y2K)nrrw82qirrY8e822rrY83 k@MnrrY8Mne82 0s$sY8Mn}ne80ז}MMn=sHsY8Mn0זOMnasqsY8MnMn2 MssY8q82xssY82ssY8}ne8bHXQssY8e82ǥ\ ttY8Mn}ne82FA4tDtY8Mn80H}n]tmtw8}n'2;2/ttY8n3OKMnttY8Mn3OMnttY8MnMnI_Tp75j6'6m Z41u4E47bJ47R7 3oIuc3q >Jh8\vIT8_E8a8j=8b8bJ8c88d8L8quu8L8suu88 8yuu8 %V:8hl8iIu3Iu Lx H3x $ Ov Iu%+Rv%ySv%TTvG$VYv_v8G$Znvyv88)e;vv88#9Pv8 %EMLKvK2L%@vnIu(GeqX>8vv8(Geu8ww9($yv/w5w9G(|DwJw8G(Ywdw89vG(xww8G(ww89Gww8 %(:yvww8)wx8vbYx x8I_Tp3IuvyH Mּwwvvwv4&3Evj=WKbJbKmKuLfNbMpRTIuyy 9Ty$y 99xT/:yOy 9x99nx.>eypy 99.yy 9 %3I $9yy 992}(yy 9x90R)#xxyy 90R),]-x zz*91end5x+z1z 91end>xJzPz*90G^8xizoz 90Pqxzz*902Yxzz 902bxzz*90 xzz*90xx{ {*92"O{/{ 9xnx0xH{N{*90''%g{m{*9bAE{{ 9x0C L)x{{ 9x0C%rx{{*9x2A P{{*9x1at6;x || 9x1atHXx/|:|*9x0pS TxS|Y| 90p[Gxr|x|*90Ðc1`x|| 90Ðk&x||*90y2zXzx|| 90y2x||*92q) }} 9922O)}/} 93 kɺxG}W} 9x92 0]l}} 9xx90ז}j1x}} 9x0זax}} 9xx2 r}} 9$92x~ ~ 92~.~ 9x9bHXHB~R~ 992ǥhg~|~ 9xx92F7~~ 9x802x~~*9x'2;~~ 9zx3O.,x  9x3O x%5 9xxxI_Tp35Iu6i68xI-8\PT8_E8al9j=8br9bJ8cx98d~9L8q9L8s99 8y9 %V*8hl8i\\ P HF $ O \%+R%yS%TTG$Vlr9G$Z99)eP99#9P9 %EMURπK;S%@'n\(Geq 099(GeuL9%+9($yBH9G(|W]9G(lw99G(9G(99Gāρ9 %(:89)Y9bl(39I_Tp\s eρڀ+4&E㿀j=`RbJkRvR~SfUbepjT\9T,799T/Mb999.>x99.9 %3Ih9ƒ992}׃990R)#90R),:iɂ%91end5>D91end>Pɂ]c90G|90P5Ղ902Y902b:Ղل߄90(90=92"5o2B90 [a90'$%z9bA90C Å90C{܅92A k91at6W*91atHgBM90pSNfl90p[l90ÐcDQ90ÐkÆɆ90y2z90y2=92qK'9922uK<B93 k$xZj992 0990ז}h90זtч92 ?992x92O1A99bHX Ue992ǥ(z992F 29~90fP͈݈9'2;l93Oo 93O8H9I_Tp5\6s&6gK98\.UT8_E8a7:j=8b=:bJ8cH:8dN:L8qӉىf:L8sf:l: 8yf: %V*8hl8it%:t  H^ $ O׊ t%+R׊%yS׊%TT׊G$Vx:G$Zx:~:)eŠx::#9Pˊx: %EMQWK7X%@?nt(Geq^: &:(Geu.~:=C:($yfZ`:G(|ou:G(::G(:G(͋::G܋: %(:Ek׊ :)£,:׊b=@K:I_Tp%:t3Z x &C34&%:E׊j=\WbJgWrWzXfZbxp}Tt-3:TDO::T/ez:::.>::.: %3I0:ύڍ::2}L::0R)#Ռ:0R),O7=:1end5ՌV\:1end>xu{:0G;:0P:02YM~Ҏ؎:02b!:0t:0W/5:2"OYJZ:0Csy:0'$?%:bA:0C b.Џۏ:0C#Ɍ:2A o:1at6 k7B:1atH5ɌZe:0pS!s~:0p[-Ɍ:0Ðc0:0Ðk`Ɍې:0y2zC:0y2&:2q4?::22TZ:3 kv_Ռr:Ռ:2 0L:Ռ:0ז}r)ՌőБ:Ռ0ז0!Ռ:ՌՌ2 D::2x!.4:2IY::bHX0Ym}::2ǥj:Ռ:2F̒:ՌN:0 :'2; :3O'Ռ-8:Ռ3OՌP`:ՌՌI_Tp%:5t6(6-c]8\A\T8_E8a:j=8b'bJ8c:8d:L8q:L8s:: 8y": %V G8hl8i % ם Hq $ O %+R%yS%TTG$V:G$Z:;)e1ʔՔ:;#9Pޔ: %EMZ^K@_%@Rn(Geq;39;(Geu܄;PV;($yms;G(|;G(; ;G(;G(Е; ;G; %(:;)B/?;bS^;I_Tp %F ֋9VF4& %Ej=e^bJp^{^_fabꋝp됝T@F&;TWb&;,;$T/x&;2;,;.>&;8;.ʗ&; %3I^T>;&;8;2}&;2;0R)#b0+1&;0R),urJPD;1end5s|io&;1end>MsD;0G}/ &;0P0Ƙ̘D;02Y &;02bp D;0#)D;0i BHD;2"o%]m&;0 D;0'7!%D;bA-ʙ&;0C +Ж&;0CܖD;2A  H'2D;1at6ЖJU&;1atHiܖmxD;0pS~Ж&;0p[KܖD;0ÐcgЖϚ՚&;0ÐkuܖD;0y2z# &;0y2Ė,2D;2qu;GR&;2;22gm&;3 k&;2;2 0u&;2;0ז}FP؛&;0ז  &;2 .<!,&;>;2xjAG&;2\\l&;2;bHXDL&;2;2ǥe &;2;2FϜߜ&;:0?/D;'2;(&;3OF@K&;3OScs&;I_Tp %566vAvcAwA{;A;A;A;A;A"<A=<AS<An<A<A<A<A<A<A =A$=AC=Ab=Ax=A=AŒAaA=A=A">A=A>A<>8\&aT8_E8a@j=8b@bJ8c@8d@L8q˞ў@L8s@@ 8y@ %V/48hl8il@l  HV $ Oϟ l%+Rϟ%ySϟ%TTϟG$V|@G$Z@@)eP@@#9Pß@ %EMcߟK~d%@7nl(GeqP@@(Geu@5;@($yQRX@G(|gm@G(|@AG(@G(Š@AGԠߠ@ %(:zHϟ@)$@ϟbm8C@I_Tp@l+T8 pߠ;+4&@Eϟj=cbJccdffbppuTl%+ AT<G AA T/]r AAA.> AA. A %3II #AǢҢ AA2}x AA0R)#͡ A0R),<١/5)A1end5k9͡NT A1end>'١ms)A0G A0PL)A02YʣУ A02b)A0)A0)'-)A2"BR A0kq)A0'Ψ%)AbAZ A0C  ȤӤ A0Cg)A2A  )A1at6p/: A1atHwR])A0pSrMv| A0p[)A0Ðc] A0ÐkHӥ٥)A0y2z` A0y2Г)A2q,7 AA22LR A3 kٌ͡jz A͡A2 0 A͡A0ז}͡Ȧ A͡0זDE͡ A͡͡2  A#A2xj&, A2vAQ AAbHX2eu AA2ǥt~ A͡A2Fp<ħ A͡@0ݧ)A'2;.  A3OWA͡%0 A͡3O͡HX A͡͡I_Tp@5l6!a_d3idndo4Ep?bJqJpyըۨ!D/p!Dp!D'D3S)/-D3FHGM-D39Nm ek-D3H73D!D3H®5u!D %3M:S3Dĩʩ!D3Mu!D %3PHiu-D3H3D(3!D3pHuKV-D0.N3Doz!D0C-DRd[h8\ghT8_E8a/Aj=8b;AbJ8cFA8dLAL8q dAL8s"-dAjA 8y=HdA %Vʫ8hl8i5A H $ O %+R%yS%TTG$VëvAG$ZҫݫvA|A)e?vAA#9PvA %EMj Kk%@xn(GeqAY_A(GeuF|Av|A($y "7AG(|AG(ȬAA7G(ܬAG(AAG A %(:%7BA)j;UeAbyAI_Tp5Al1j ֶ B+_|l4&5AEj=jbJjjkfmb궴p뻴TflAT}AAJT/A>AAҭ.>ɮԮAA.A %3IB]AAA2}(8A>A0R)#Q.QWA0R),pvA1end5A1end>A0Gzo2ͯӯA0P&A02Y2 A02bF&*0A0>IOA0B>hnA2"IA>ҭ0?=>A0'm%˰ѰAbAA>0C   A>0C-8A>2A MXA>1at6p{A>1atHA>0pSߩA0p[.RֱܱA0ÐcXA0Ðk#A0y2z'ޭ39A0y2)RXA2qMEmxAA22A3 kJAA2 0вA>A0ז}x A0ז"2A2 ĜGRAA2xTgmA2)A>AbHXAA2ǥ˳A>A2F^ALA0)>.A>'2;wCNAޭ3OfqA3O A>I_Tp5A56468\:pT8_E8aAj=8bBbJ8cB8d BL8q$*$BL8s:E$B*B 8yU`$B %VgJ8hl8iŴAŴ i H $ O( Ŵ%+R(%yS(%TT(G$Vյ۵6BG$Z6B`BrB.`B %3IxB +`BrB2}@@P`BVlB0R)#'&io`B0R),ݙ2~B1end5&`B1end>M2ƹ̹~B0GVpJ`B0P_> ~B02Y%J#)`B02b >BH~B0Vag~B06KV~B2" `BV0FVĺʺ~B0'$%~BbAM`BV0C 2!,`BV0CpEP~BV2A Dep~BV1at6]`BV1atH~BV0pS ϻջ`B0p[~B0Ðc# `B0Ðk,2~B0y2zKQ`B0y2tEjp~B2qh`BlB22&`B3 kZ&üӼ`B&lB2 0U)`B&VlB0ז}P&!`B&0זHt&:J`B&&2 ._j`BxB2xd`B2E`BVlBbHXᴌν`BlB2ǥ:`B&VlB2F `B& B09V6F~BV'2;-z[f`B3O u&~`B&3OR&`B&&VI_TpA5Ŵ6C6 4e4<4E4l9bJ4x9Rl9 vz3o2c3q > 4te4<4E4אbJ4Rא S3hc3j >8\FMwT8_E8aBj=8bBbJ8cB8dCL8qCL8s C#C 8y'C %V8hl8iP; Hv $ O %+R%yS%TTG$V/CG$Z/C5C)e /C;C#9P/C %EMxKy%@Wn(GeqrAC8>GC(GeuAP5CU[MC($yrxMCG(|GCG(GCSCG(GCG(GCSCGGC %(:!GC):4DGCb"XcGCI_TpP;K ֐! >[K4&P;Ej=xbJyyzfD|bpTEKYCT\gYC_C)T/}YCeC_C.>YCkC.YC %3IqCYCkC2} YCeC0R)#06YC0R),jOUwC1end5ntYC1end>;wC0G!5YC0PswC02Yh`YC02bX wC0ڭ(.wC0GMwC2"|brYC0wC0'%wCbA,;YC0C hKYC0C\ wC2A @,7wC1at6OZYC1atHVr}wC0pS3YC0p[WwC0ÐcYC0Ðk:wC0y2zYC0y2=f17wC2qn`LWYCeC22ΡlrYC3 k9YCeC2 0YCeC0ז}&YC0זYC2 v&1YCqC2xFLYC2aqYCeCbHXYCeC2ǥIYCeC2FYCC08 wC'2;Q"-YC3O_EPYC3ObhxYCI_TpP;56}6{ 44E4BbJ4BRB 3oc3q > ՛40e4<4E4'bJ4R' ,3hHc3j > [44E4;AbJ4LAR;A 'G4e4<4E4/AbJ4FAR/A @R3oc3q > K3hc3j > ?4(4E4@bJ4@R@ S4_4dE4dbJ4dRd q4vex~vr'<I_Tp@-w %b@rJ@u8\k|~T8_E8aMj=8b9DbJ8cDD8dJDL8qbDL8s&1bDhD 8yALbD %V8hl8i* H $ O %+R%yS%TTG$VtDG$ZtDzD)etDD#9PtD %EM$K%@|n(GeqL4D]cD(GeuzDzD($y;DG(|DG(DD;G(DG( DDG$D %(:];FD)cYiDbX}DI_Tp*p  ֵ$F/cրp4&*Ej=)bJ4?GffbpTjpDTDDNT/DBDD.>DD.D %3ID DD2}l,<DBD0R)#U[D0R),tzD1end5yD1end>k\D0G6D0P=*D02Y 6D02b)*.4D0_BMSD0ZBlrD2"DB03VBD0't\%DbA+DB0C E DB0C1<DB2A mQ\DB1at6tDB1atH}DB0pS`WD0p[CD0Ðc|D0ÐkwD0y2z7=D0y2WV\D2qq3q|DD22%D3 k [DD2 0DBD0ז} D0ז@&6D2 KVDD2x kqD2DBDbHXmDD2ǥ`mDBD2F DJD0qB"2DB'2;GRD3OajuD3OaDBI_Tp*566 2t44E4MbJ4DDRM T3oc3q >8\pT8_E8aEL8qNT-EL8sdo-E3E 8y{-E % 6,@v%/@o +=@r%DI_Tp ^*[ F%*(E*lݐ.4E(E*אKQ E0W*Z X1** !:-*!ç*F!.**"_*9E"_*9E?EEE2 *Y9Ee 9E %lY%*hMoGWEiEp+*|oGWEiE++t*4oGWEiE+M*MsyoGWEiE+ *l<(=WEVV+*ڳUeWEV+a*}WE+(*WE*O* pWE+P*`rWE+P*z)]E+N[*mAVWE+N[*mn]E.*WE.*WE?EoE.*WEuE.u*WE %0I*GE{EWEuE0y*CC5;]E0R)*TZWE0R)* sy]E1end*WE1end*]E0*WE0*M]E02*Q"WE02*-3]E0'*%LR]E0*) *kq]E0*6*]E2 *eWE{E0v*\WE0a*@WE0I*7!WE0*N:JWE*+;*D^iWE*+;*Rm}WE2ז*iWE2ז*m WE0ז*_*WE2ז*4WE2ז*s+;WE2ז*k)P`WEאא2x*Vu{WE0*vPWE0*r]E0[*d*]E0%* WEiE0%*$/]EiE0%*:HSWEiE0%*SVlw]EiE0N**8WE0N*I]E00*Q%]E20qs_ *r*F%=*bJ*E*ݐz*  *EG*jp G\* GP(FH*j/&G(9N*Ř:&G(H*,G G(H*Ћ4E G %(M*[,G  G(M*ZE7B G %(ȃ*]6%Yd&G2GE(_(*JR%&G2GI_Tp ]Q*rr*F!=*>bJ*E*א* z* * E"*E]*!E"*1<EE++* EY_E+FH*kw}E+9N*E+H*uVEE+H* UE %+M*( EE+M*/pE %+ȃ*7%5@EE+_(*;P%]hEEI_Tp66% e :+`%+e %.+f%G+l8GG+p8G>G#7I_T1 I_T2%^ ^0Zz0se%0t0g4&0hN0i=0j0k_0f0p0T0*_set0E`set0E?EEI_set0EE0I0EEE0y0=9@1E00A =7=E0$0EIV\E0R)0NIUu{E1end0W1UE00`mE020i2mE0'0%E00dyE00y/5E2 0JUEE0 0nyEE%0 0UEaE2ז0\NEU0ז0lΑyEE2ז0\EUU2x0y*0E0[09+yITEE00@UmxEE00iBaEE0%0+8UEE0%0SaEE0%0nUEE0%0 a!,EE0N0EPEE0N0scitEEfRE %25s5_ b+`%+e%.+f%G+lEG+pEE#7I_T1I_T2%V 4Z4E48bJ48R8 >44E48bJ48R8 l44E4=:bJ4N:R=: Nl44E47:bJ4H:R7: ZH464E4:bJ4:R: K4m4E4BbJ4CRB M44E4AbJ4BRA 44E4@bJ4@R@ I44E4ݐbJ4Rݐ ~@i6G''@: +=@>D6alDG6+=@B6DG6I_Tp'6 I4e4S4SR~S f4e4B4BRB 54"e4k4kRk H8R8[H77_ @iqG@: R+=@>`G+=@BE `GI_Tpq j`^Cdxh888Cd#xhl9l9l9CqdBxhAAADdedxhݐݐݐb3g3{ >I_Tp8 *44Ӧ84/E48R8Y E%(3g3 >I_Tpl9 j(444l94/E4b l9Rl9Y E% 4`e4<4RB ژ)@EL)Dl9Hl9xhl9l9l9l9Eb )DݐHBxhݐBBݐE)DݐHBxhݐBBݐE)Dݐ0HݐxhݐݐݐݐE")DAaH$uxhA$u$uAES^)DAHAxhAAAA4y)D[8H8xh8888Y8^%3g3 >I_Tp7: R4=47:4/E4Ԛ)7:R7:Y E%U3dg3Z >I_Tp: 4Ѩ4:4/E4zp:R:Y E%R3g3 >I_TpB <44B4/E4NBRBY E%ɣ3:g30 >I_Tpz C4~4z4/E4"FjzRzY E%f3g3 >I_Tp@ 44Ӛ@4/E4@R@Y E%8*3g3 >I_TpA X4T4A4/E4Զ@ARAY E%3{g3q >I_Tp/A \a4ѿ4/A4/E4ԨH/AR/AY E%3g3 >I_TpM z4*4M4/E4BMRMY E%TR3Qg3G >I_Tpݐ c4ѕ4ݐ4/E4H]ݐRݐY E% ;4e4<4E4*bJ4}R* 44E4BbJ4 BRB 3h&c3j >+33Mg35C >I_Tp8{33tg35j >I_Tpl9D_33g35 >I_Tp7:33g35 >I_Tp:8;33g35 >I_TpB3:g3= >I_Tpz P4T43z4/E4&@zRzY E%33{g35q >I_Tp@33g35 >I_TpAx33g35 >I_Tp/AŖ33g35 >I_TpM|33g35 >I_Tpݐb5 G97:MI_Tp%:=:=:7: f9:vI_Tp %'': :h9BI_TpP;BBB D9@I_Tp@@@@ M9/AI_Tp5A;A;A/A9MI_Tp*9D9DM)m  qBMI_TpP;BBB \Pq7:vI_Tp%:=:=:7: K$q:I_Tp %'': 5q@I_Tp@@@@ q/AI_Tp5A;A;A/A<qMI_Tp*9D9DM3>g34 >I_Tp7 33eg35[ >I_Tp7F33g35 >I_TpB6.86M<8$3.* ʗV8GJU L %b;L )%LV80 l?GJ K'%. 9?L03m XcGJ'%0 *|L!'%59(bxB)LLV8h:B~LvLDEL!O666Exh:I_Tp %:::C7zxhBBBC3axhBI_TpP;BB)C  ($D| D|D| C zGxh@@@C;txh@I_Tp@@@@C@[zxh/A/A/ACxh/AI_Tp5A/A/ApA 6 h$fhffh l$%Rd'D'D 0%:Rd'D'DCCzYxhMMMC6xhMI_Tp*MMnDEͲ8%I_Tp'%E'/8I_Tp38CJ\I_Tp38CJzxh888C-xh8I_Tp3888E'/l9KI_Tpx9C_C\eI_Tpl9Czxhl9l9l9Cáxhl9I_Tpl9l99E(C'/ݐI_TpC\I_TpݐC` zxhݐݐݐCE>5xhݐI_Tpݐݐ7CO]I_T1I_T2ݐE)kݐHBxhݐBBݐ ")ݐHBxhݐI_TpBBݐ7E BRB/BB/E;4%'6En.ZE'''<EBq.rhH''' R88  I8Y {%8 8888 p!R88 [8Y {%8 8888E'I_Tp %::C=OI_T1I_T2'ݐ6E)kݐHBxhݐBBݐ )ݐ\HBxhݐI_TpBBݐ7EV.rKHBBB BY {%I_IIBI_OIBBBB BI_IIBI_OIBBBBEE)kBHBxhBBBB )B^HBxhBI_TpP;BBB)C `)'BHBxhBBBB)C nvBB BBBBE)kAH$uxhA$u$uA 3)AAH$uxhAI_TpA$u$uA0B c hs$uhuuh .7:Y {%I_II7:I_OI7:7:7:7: 7:Y {%I_II7:I_OI7:7:7:7: 7:I_II7:I_OI7:7:7:7:E*)k7:NH7:xh7:7:7:7: 6)7:H7:xh7:I_Tp%:7:7:7:r: ?)'7:H7:xh7:t7:7:7:r: v7:7: 7:7:7:7: ,:<Y {%I_II:I_OI:::: 1:xY {%I_II:I_OI:::: :I_II:I_OI::::E)k:H:xh:::: ):H:xh:I_Tp %:::: aL)':[H:xh::::: mev:: :::: g@Y {%I_II@I_OI@@@@ k@Y {%I_II@I_OI@@@@ V@7I_II@I_OI@@@@E˸)k@hH@xh@@@@ )@H@xh@I_Tp@@@@@ )'@H@xh@l@@@@ gv@@ @@@@ /AVY {%I_II/AI_OI/A/A/A/A s/AY {%I_II/AI_OI/A/A/A/A (/AI_II/AI_OI/A/A/A/AEb)k/AH/Axh/A/A/A/A E)/A5H/Axh/AI_Tp5A/A/A/ApA )'/AuH/Axh/A/A/A/ApA S0v/A/A /A/A/A/A MY {%I_IIMI_OIMMMM MY {%I_IIMI_OIMMMM @MQI_IIMI_OIMMMME)kMHMxhMMMM |u)MHMxhMI_Tp*MMMnD V)'M HMxhMMMMnD 'kvM4 M MMMM1?G : u u !'%9(' 4 !'%9(8ٝ!.x#>   %LU+#;    %L!'%59(jhex!X!X !kX,!X:%mf!!'%9(': P H!!'%9( : !!'%9('%4. p7~S"~S/~S~S/< Ͳ 4"!'%4 p+ Bn"B/BB/<4 pk"k 0kk 0< K^ k"$kkkE k #Rk 0kk 0  B=#$BI_TpBB vݐo#ݐ ݐݐݐݐ 6 ~S#$~S#~S~S#E. ~S#R~S/~S~S/ v8 $8 8888kM7eP$kP1>aFlS1J7DNwR$'m4U EL*Z$!'%9('n D8W?4(*"5$5b*N[9$%55 z^D?ǧ$'4D*"\5%5nD4%|& %ointlvvb="l 3a $gF0% zG'%G %%G*%7G*%G* %nG*%G*!RG*!^G*!1G* !iSG*$!G*(!QG*,!bGj0!/G p4!gG  %8!G %J]I't'%'u't<ߦJ^='[tJj'v%v''% -J1'' % J1'''v' =J((( %'v<% RJ1'2(<%' RJ  %M(M('vS(<% JK %s(' % JR %('M(m h1J{ %('M(m J1'('w[eJ1' A J&'('&'(v' Jm&')('&'( a Ji %.).)v4)' 0J&'^)(^)&'(v' ZwJ1')<%' YJ1')<% @ J\ %)(&'M(m J %)M(M(m CJ1')1'' Jd % *'M(' J %-*'M(' xJq %R*(&'M(' J %r*M(M(' cAJl %*M(' J %*M(' xJr&'**<%(v'%E8J(*(M(EJ %+M(M(E:J %+M(M(EJ(6+(M(EJ&'P+M(M( YXJW&'u+(&'M(u+v{++xtm,K,%9@K %%.K %%H?K %%K % %BK %%NK %%|SK %%(YK %%K % %0KX%$%1K'( xJ&'&,M(EEKJ(E,(M(&'EqJ %d,M(M(&'EHJ(,(M(&' QKJ&',*,&'(vM( J&',M(M( g#J%,M(,v( Jm%-M(, !J(%-(M(, (JX%E-M(, % <_J_%e-M(, %E;J&'-(M(&' QJ %-1' %JE %-M(M(&' կJI(-(M(&' IwJN(-(M(&' pJR(.(<%&' )JY %1.M(m }JJ %H.M(m4JM(f.M(<%JM(.M(M(4dJdM(.M(<%JM(.M(M(J<M(.M(<%&'yg2s2s22yB-$0 f-ܦ/%ο-#G#-:/E/!F#zM-%a/l/R~S!F~Se#y//!Fe//!F %# - 0%-'FG-//,Fz-%//RB,FBx' -ܜ0%ο-G#-00;0Fe#H0S0FUe`0k0F %z-%00RkFk/ 0E(Q-Ħ/0x' Em)- 00F-/## , -'L :2T =E ?*j= @'bJ A} Blo Oc1i1lo Qy11 V11 %32 Y%#111;132 ]]/111G13Q cQ#11 21ub4F mU!212#113 q1I2O2b c2s2#1bk \22#1I_Tp'% 1  :24T =E ?(j= @M(bJ A Blo O22lo Q33 V*353 %32 Y62M3X3232 ]52p3{323Q c)2332ub4F m*33223 q+233b 3 42bk 4(42I_Tp<%2 L7y4&;L:%&#L;%&9L?%&vL@%x %W6Z*<C88C60PH  628=8C60.N$CV8a8C60pHtn6z88C60R688CR'#N66 ,L79&;L:S&#L;S&9L?%&vL@%x_% gL7E9&;L:'&#L;'&9L?%&vL@%x'% L79&;L:&#L;&9L?%&vL@%xC%T :;T =E ?^)j= @BbJ A6 B6lo O99!6lo Q9:!6'6 V::!6 %32 Y`c93:>:-6932 ]B9V:a:-693Q c\@9y::!69ub4F m:Q::!6993 q09::-6b x::!696bk ;;!69I_Tp'9 cM_ <EMHTMH4QM);];?64;4FM̥|;?6);4;kM;?6);4M54;;964hMq96;96d,Md;?6?6 M<lMII_TpIH :=T =E ?K6j= @Q6bJ AW6 B]6lo Oe<k<c6lo Q{<<c6i6 V<<c6 %32 Ys%<<<o6=<32 ]31<<<o6I<3Q c%<<=c6<ub4F m5#=3=c6%<<3 q<K=Q=o6b De=u=c6%<]6bk ==c6%<I_TpI <8} :4?T =E ?ݐj= @אbJ A Blo O=>v7lo Q>>v7|7 V,>7>v7 %32 Y=O>Z>7=32 ]z=r>}>7=3Q c=>>v7=ub4F m*>>v7==3 q 1=>>7b b> ?v7=bk ?*?v7=I_Tp= M_@EM`j=M`bJM`M'`TM_4QME??7q?4FM?7E?q?kM ?7E?4MVq??74hM7@7d,MǼ^@77 .M@@lMЌ`I_Tp YMa@lMЮ`I_TpCM@I_Tp7E?_WBZݐ<<IJ8 %32 YPIVJaJ8I32 ]oIyJJ8I3Q c7IJJ8Iub4F mjJJ8II3 q IJJ8b -KK8I8bk &K1K8II_Tp3I b<M_uLEMhuj=MtubJMuMuTM\u4QM~LKK8xK4FMqK8LKxKkM K8LK4MxKK84hMG8 L8d,MW&L88 :MGLlMuI_Tp3CfUMkLI_Tp38LK8IuWNZ8</uLMMF %0C-LMMFL0H ^FMMFL0PH nuLNNFL0.N-dF3N>NFL0pH$uLWNbNFL0 F{NNFR8#N8xWowPZ8<fTB0HBWT]TB0Hl~SvTTB %0MBgBTTB0M~STTB %0CSTTBS0H "BU UBS0PH O~S%U0UBS0.NBIUTUBS0pH~SmUxUBS0BUUBRl9#NK6f'= :@WT =E ?7:j= @=:bJ AH: BN:lo OV VT:lo QV(VT:Z: V8VCVT: %32 YU[VfV`:U32 ]CU~VV`:U3Q cUVVT:Uub4F mmVVT:UU3 q5UVV`:b DWWT:UN:bk ;+W6WT:UI_Tp%:U 9M_zXEMj=MbJMMTM4QMQWWr:}W4FM.Wr:QW}WkM)Wr:QW4MP}WWl:4hMŏ0l:Xl:d,M+Xr:r: *MLXlMI_Tp%:C,NMpXI_Tp%:r:QWN:tWsrZZ7:<\`FZ0.N/fFW\b\OFZ0pHUZ{\\`FZ0uZUF\\`FR=:#Nc| :I^T =E ?:j= @'bJ A: B:lo O]]:lo Q&]1]:: VA]L]: %32 YN\d]o]:\32 ]J\]]:\3Q cĵ\]]:\ub4F mxb]]:\\3 q\]]:b ^ ^:\:bk ?4^?^:\I_Tp %\ }M__EMj=MbJMMʓTM4QMVZ^^:^4FMVI^:Z^^kM^:Z^4MC^_:4hMS#:_:d,Mh/4_:: GMU_lM+I_Tp %CMy_I_Tp %:Z^:WaZ:< A">A<>divA7gŒa,,_ :cT =E ?@j= @@bJ A@ B@lo ONbTb@lo Qdbob@@ Vbb@ %32 Y9bbb@&b32 ]bbb@2b3Q cFbbb@bub4F m$ cc@bb3 q#b4c:c@b 6?Nc^c@b@bk Urc}c@bI_Tp@a 'M_dEMj=MbJMMTM4QMtcc@c4FM} d@cckM%b&d@c4MB$c?d@4hM@Xd@d,M߿rd@@ /4MϓdlMI_Tp@CMdI_Tp@@c@lWfZ@<tF %0C-sWtbtF s0H #F{ttF s0PH {sttF s0.N;uFttF s0pHsttF s0F uuFRA#NWCwZB<K %{- AjXK %{: NjrK % =%R7#Nmkk {=%̆R;A#N.r.r =%R8#N8xvv <=%&R=:#NcXxXx =%SR'#N55 MSRl9#NKtt '=%RB#N{ *=%ڇR@#N[ kR/A#Nuu G/%4R@#N[ V=%aRא#Nc v v zBRא#Nc v v =%RM#NLLE9N%و'' =%RB#N{YY L @3Rݐ#Nc++ UL`R8#N8xqq  sRA#NMME/N%'%* K@z؉RB#N{YY L=%RB#N /%2Rl9#NKtt qvX_R7:#Nc%% >_R:#Nv 1dR@#N[ W/%R/A#Nuu M-6%_;A/A#N.ru 6bIRM#NLL7g/%RM#NLL "Jt%M(, 3J,M(, % i Jf%΋M(, %yO7|O8O}4}dvdv4}}};v;v}d 28P5J%@P9*%TeP:*%&0P@*%\PF* %;PG*%HPH*%PI*%PJ*%PK* %mPL*$%MPM'%(% PN'%)%PP'%*%PR'%+%5PT'%,% PV'%-%*P]'%.%XP^'%/%Pa'%0%PPc'%1%$,Pe'%2%Pg'%3%8>Pn'%4%Po'%5EP|*d %'~P'PovQ( %mQ7,vQ8f%rQ|Q}Q%SQ~Q%Q_%_QQ%QQ%BQX%9QQ %t % u')QX%QX%QX% [QX%tQX%ؙQ %QX%LQ %nQQ%:KK  Kx% +Kz%*K{M,R%t_%u' Sގ% +S %}S!1T<_% TQ%TSvTTTT[ӏ NT\rTqmTsV%zTtC%%$TuC%sNTy4s*Tz%*T^ %%8T_Q%%4<T` %%Tf % %fToQ%,s&T} sT~ӏsTX%t'%u'X&TTWsT'sT %LcTt'%-u'/cTQ%t'%Hu't'%Xu'd*vXU %v{}'%}'v 1}2v2v}}}<%}S(v2}24v24v}vv' vv$ }$ }' }tQ%v{v8 v6v, v=!}=!}6}, v6BvH'v*_%}7v7V4_%?VzvuEV %1'dEtV1'1'oEVoΑ'EVd'};v@v?v@}?}@v%}%v1AvB}BvBvYD}Bv%qWb6 c%pLWc %remWd %`'We=qWj%pLWkX%remWlX%WmnqWvŒ%pLWw,remWx,Wy!!XmBqY%KY3YےuZ%Wv %1uuNG  Gj%tGj%Gp%sG %v9v%t'%u'v1t'%u'' %*-FO' )<X[.%m~[0%Dd[2J%%Fs[5 %F[:%[;͍%e[@%+R[A%[E %Kd[GJ%(%[J؍,%[N,0%1[P74%D~[[y8%[\y@%[]yH%H[m_%P%H[n_%TC%S\ X\c%]*_%  ]e!]j!d+]m_%!+]p_%!]s !kc]x*!^]~!|]&'t]Q%]Q%.]Q%]Q%]Q%G]Q%]Q%v5%]s%] %]ߕ!]!{]a]1ֿ/REH!19'!u%!!0\(REWb11REs~11RE1'~RE1 %0Rg'Ж֖1[D%11[H'%11[}4%6'1[Hx%V'1*}ju1'LIJ11‡ .  0 Wo! o.2' %.\2 %0D-Uk2282" HS2 2LI Jc2 2W| 8Z^XZT(_%ZP`ގ2Y8;?آ22+B822M :2| 2yW[ ry.[t=C2.xT_2 %"[}oz2$2LI}2$2W8$!^*2T8ƙљ/22.L/2 %"8/252LI/252jKM:/M%YG%WlTvIntZ %<,[Q%Wg `Intf,<,gf%W?zϛ!a%5T~ʚ՚+5%5.L+5 %0FH15 7509N%5)/751get%5HN750ь %5gm+52#(+5%5"+5=5*I^Ǜ+5=5ITG'^:^E''^fR%''y^ly66M(X^t%VM(M(^|ȷ%v'':A^%M(M(<8^S%11^W6ќ % ^6 %[^>65%'^w5;7%6=BH}5>Xc}55/@s~}513ID}Z5}55SetIR}553CRMl1ٝߝ534NE'5QW855 %'\_ïX55j}55'3oJr%53qpts53'|mhўמ53zGY53h% 5'3Od%06531%NT53B6%lr53+%u%53Z%53ۍݖ%Ɵ̟53RI%5) *K}5([}x' 5ݯ+}5 %]  ]  Xm5' %_5p }5 %G]  55HI 55<& ͢H S Tm%3L U  h=G 5S 5B 5 7G 7$S 7$_ 5u_ zΠT< 55[ m%k &*Um%Max +%m%0lp 0550ɦ 3  50/ 6;"(50G 9tAG50Մ <,%`f505 HӶ%55? g 5 s.mâ55m%  ݤH S T%3L U  쑚=G 5S 5B 5 GG G$S G$_ 5u_ zޢT< 55[ v%k &%Max +%0lp 06 60ɦ 3C 60/ 6Y28 60G 9g5QW 60Մ <h%pv 605 H% 66? g6 sDӤ66%ҢW ! %!d Z.  60 ?\%9S6' %''| m'i6' %'W CQ Ox!r CT ȥ)7C2V Iݥ)7C07 C )7C" ')7/7LI  7)7/7mhCfGEY%&c ,@ ?sf   )G:ug6[YZ%'1' %G.fGO:7@TRY$:7 %XmijYEK:7ILI17>IW ,Tz[_m!a..}8.h+/}8 %2^W}8"c-8}88LIc6H}88WXz!aݐT~B9ݐ.LB9 %0FHmīʫH909NsyݐH91get&ݐH90ь~ݐ!'B92#F<GB9ݐ"WbB9N9*IvB9N9ITYpWzʭ!aאT~ŬЬ:א.L: %0FH! :09Nא$*:1getאCI:0ьאbh:2#`}:א"::*IZ­::IT' / uϭH ޲GU' : %Kh \H@F:.H W]:"H mx:PILI *:PIS ر!p %! r {.U خޮJ;U=w J; %2{ 8J;P;0ln )fP;8CJ;P;00\ G%\bH2@] wJ;% yJ;]HZ ɯٯJ;]H %1c J;]H  :q +J;]H ;:ITJ;uH r}J;1:4 eJ;8bp  İϰJ;1:/?  J;uH  !J;]H. N ?JJ;]H l k> hxJ;]H %  J;]H"t J;HLIt lṈJ;HW Qq!T!H! %!uA\F "q6Ph;?' %'.qalh;n;2I Qh;n;#h; %!t;. IJ޲y;?' %'.n:y; %2I;_5" *5y;;LIZEy;;رz _`%_h;%I _i%_jz_c;69?;2_fƳ; %Gz_lճ;;HI_l;;CRh6VU<%%%%%%%w6%6%% %qj6%ͧ6%C%%76%% %$%B(%w%,%0%Z64%L%8UT@ A T@ %glZW8Z!g6T8_NYZ@10=bT%r}`@~9f8Z@{b<Z@ %#WmtAUy6~|6[%''[R%#11V$%1'}A Ҷ!'!  %!uA6e}AA BeA %IB¶A B#}A˶AXҶm ` >G!6.H!:!#C=n !&e?/!U2Bp@!(E !uI@!M[H!7QT!ژWv`!\l!_%x!{Uc %|!Hi5A!0o%:!h&y! }!V9H!)8%! %!^!nj!`!$!QA2%TXD3HUҶD %0=  p@Ƹ̸D2AFDp@0ep@ D2  +Dp@0<< %DJ?H0R  %ci?H0iE %?H0.o %?H083g %ƹ?H0Mf %߹?H0Q %?H0Q %#?H0?~ %<B?H0\o? %[a?H0O ^ %z?H0C:_?H0s =C?H0D@h%׺ݺ?H0D/%?H0J/C ?H %0nQ5A9DD %0WV;]cD0ֆ9|D0f^X9?H261D9H0 ++9HڻD0 6D %0M'5A7D''2P>LaD%:0E5EHzD2:D5A2 D%:2$ռۼD0W~WD%D2W,D2i*0D2 eDEPD~90^[g3 %itD2D0fC?H0%:ǽͽD0I+:?H0P#A D0ijxB$*D0iirBCI?H2#"^dD0+F7}?H0lAD2oD2ҾؾD2>/D292D0% %'-?H0V!)7FLD2B=N+agD2TG|D0,:L%?H*K3SD%"XпۿDKHLIYDKHW!f@!pk@ii!p@TU`G|@0E@yG"GG*I3GG*DG %.S1v@TS1v@|@.$v@ %0E@=Cv@0Ev@\b@1get!|@{@setSv@|@--+d[N@@"S1v@@*IU v@@ITp@WzL!a@7T~GRA@7.LcnA %0FHAA09N+M@7A1get'@7A0ьT@7A2#k; A@7"%AA*Ic9DAAIT%WTlz!aAT~|AA.LA %0FH/jAA09NTAA1getAA0ь8AA2#k4?AA"OZAA*InyAAIT:9(Gf:9ADIf:9A@uA %&%A'1' %GQAWR!f@!pӾii!TGrB0E~`BG"GG*ITGG*DYG %.S1!'BTS18CBrB.T_B %0E`Bx~B0E~BB1get%rBBset BrB-i-+dz`B B"S1&BB*I :EBBYIT2Wz!aBT~BB.LB %0FHbBB09NBB1getBB0ьB%B2#=:EBB"U`BB*ISKtBBIT&.Y1EGfBHfBIBBHUp13(B %62FQB;L9WouBʾ<B;)!nYaB! h %!i!j .aD H;;U.I*H %OyHSH;*Rn :gmHL`%H"alHHLIlBBHH[%[ ''.&rH;;T&uHBx =HH]H |sfqH]HZ7lH]H % l  H]H %.HuH/? HuH@*=HH1:bp fqH1:4bH8*ʾYH;*zH+:H%"&HH*Ix%0HHiCNH %W  ~~  8 Wy' !f HTy' C'.M4 C %"y' CCLI CCWN2!/>6TN5>IC10=92(%bmCCfN{C hRC %Q$7 , ;4 N  uWp^ w!p.p^yD.}$D %29DD'0PL9D]cD;-yIStrD7B!N#9D! %W6K fd_N%!O %!EQ6T6KD %."4D %08639D3I«6SDzL&'mD"6KS}DDLISLDD7| b  -=DWKo&C y&O&p7ITW&C<y&O4+p7IT, W ^$a %ITWIK[M6EJ,,W $/ 5%-E9 t]uL} ;'%uL} .ZGmuITouWJ&7y&/Ep7IT,W@y&Ciy&OɚaEp7IT,^i Gf^bIhIf^bIIOnIbIhIHibI %2 %%%p@2Y5;G@6`P[G %eB0xG83k$&%GG2GGHIGG6|f6 GGf6 GKI%A`G'1' %GpG %,dYKK!qH$!!s%(fGG.fG'1' %KXLjG-Hl&c ?G %[$Y! f[ HH.[ H'1K f>>IHH.> Z`Hu }'' "H]HZ H]H %1c H]H  f&H]H IDOHuH Z mxH1:4 lH8bp  H1:/?  HuH lsAls'QtAt W %8x>0w90w D %$c>x:xK%;CQ'P%RC'|cQy:y'{Q kC - c'%  eIC,X% CX %EJ%<% q%'%{˩/'%p7 JuMITouuz"&e1p7q&ITp7 q%<%z"&k5p7V&IT, +p7`NLIE %)7&;*)'-[QhAh Zv%C'% '%Y'%E6uIT(fC1w %,w7M{G/*''<%EĬ %2v&OIT,Ep7Q)K&aFIT,Ep7&eIT,Ep7 !'6IT1,IT2,EE1'%7ʝ' %{A %A M'!SITP;o6%1-V'ϭV%LC-0 N{b6vX '^y_=  ^'mjp {1:|/\Dy% % % %r(X% %7%,'^)e%C'E@'g''%k%''R%'' '5"%4Эt% %-x0o6!3u-tH %->yF'!&'h<6K!-UV6-/6WU7-\t97DN %6a&6C-X6M( %oxM(&'Y5{-<%<%<%p7{G<%p7Yl̽'%'&'p7['̽'%'&'p7k1+Wm'&'p7z"6"'p7X1p7, ̽<%M(&'p7 <3̽<%M(&'p7k11&SM(&'p7z"GpnM(p7d4k5p7861_5{5%5%5%p7o5%5%5%p7z"J5%p7{VK5%.%.%p7[7Dw5%.%.%p7z".%p7<%<%<%p7z"<%p7 aټ  '''<9?;48>6*IT %: I86Da6c' %F7vIE %)7 % %&; 9%& %1: {4 %'!@GW$[ibIZ9D %-l@7"'k_̽'%:MuJk+ ̽<%:,;?1T&hITHo'r&/HITH:o'D&,ITJ5A p'r@ps@Ea % %& &p%8ITҶ%Dq'|Uc`5^.;U %.*x xkk62x Z63x # 4x ryF\\ۭYx Z y ć[y _\+y 9$]se5ITEY5U81se5ITY5͢se5ITY5Sse5*5IT;Y5Kfse5Q\ITY5se5xITY50se5IT1Y5Ajse5ITY5Xse5IT'Y5; se5ITY5V{se5;FIT9Y5I@se5bmITY5hse5ITY5ose5IT/Y5?$Ase5ITY5Use5 ITY5se5%0ITY5%zse5LWITgY5w8se5s~ITHY5se5ITY5 f4se5ITMY5]se5ITY5se5ITY5,Hse56AITY5C:.se5]hITY5se5ITY5se5IT8Y5se5ITY5)se5ITY5Qse5ITO Y5_ /p0`%"`%/p0`U`R7 %3=`c%xX7 %HI`*#R7^7-9`% _`%/9`d7 %B=`Ϗ%j7 %y6&n3n1%F&'p7m&52`w/? {3` I 3 s%I g?%o6%Pr %%%*s6 %/t6`w<8?' %'3THq?83L'83:R~ % 83>U8'8>83uAXn#'V\83[%tz83^%83Ema%83da'%84!k 6'?fh  8 %f`w $ 88I83 883Q* ~ %l8xQ*l r 09b  09837g$8  69 %3F %  69GQ*  09<9HI 09<9D W!?0%!/5Y.D O T9Z9T` k T9%0C C%  `90H    `90uAG'  `9024j'  `90!f9  T9C5*^)8k * T9_5*I7*> I T9Z9fMW b T9 %if9  ITM(T9(f9  ITJGT9f9  ITT90bHzbf9  ITPT9`0n5-?f9% 0 IT3T98f9M X IT/T9_5f9u  IT?T9 !f9  ITLT9\0 @6f9  IT'T96f9  ITӏT9,Z<f9 # ITnT9~mNf9@ K ITT9f9h s IT%T95?f9  ITvT9kf9  ITT9"?f9  ITT9S#f9ITdT9tmf90;ITT9Gf9XcIT(T98f9ITzT9j5f9ITT931f9IT, T9+ [N<<%90H6 +% 90j 1%+190s "JP907*8it9 %0~99 %+?''GA99+y!,x99*19* e9DW91~9[?%61~9*FC.LJU98+RF %ms9+ZrIoo %9*WL|9*FO9"?_9:LI_=9:W3`mK!5>\F!/\F!ʭ!ʭ !zۭ!e%!.%! %!MC:!. rq%: %0tmD'+:0a3wU)'+:0g{'+:0B8'.4+:08Ru%MS+:0*"%lr+:0S9+:"3%:11''ϭ:+ZrlA %%:Run1%:$x%:"3$/%:1:LIU?%:1: ^PN<<GU_P@ % L~P@iP@<&IP@W9: !aKJ;!PMP;!.OP;.9: IOV;.W `kV; %2V;P;0lnP;V;P;0{P;\;0 'P;\;+5P; V;*<Y*V;P;*XC >IV;P;+yQG%ag\;*H{V;"9:RV;b;LIR]V;b;rbGfrP;IfrP;IL I%P;IU;FP; %AZdoP;]HZP;]H %1c]IP;]H ^P;]H P;uHG6AP;1:4_jP;8bpet P;1:/?u P;uH P;]H. P;]H l ,<P;]H % TWVP;]HU!_3_7  %_Rx%Е_Sp@%_TH TU!H09.U!'Hx09Un;g!H %Fkg?JH8*}.^dHGU!_Vs~HHHI_VHH+J Gf+p@,If+p@IO2Ip@,I@<%p@ %>p@8.g|J'#QG!/6!ʭ!c !v!.$!ɝ(!e%,!`0!h&8..gV 5A''Ub J)5A %0a3'BHC0g 'agC08R /0%C083+ } %C0Mf0 XX %C05 ս %C0: Z % C0??  % ! C0OD = %: @ C0\I  %Y _ C0D#F%x ~ C0&%%  C0s )  C07i L+:  C %0f1"I:  C+ `8D%:!!5A+ `;:5!;!C+Op F[%:S!^!5A %*N-Dr!}!5A%*Pw !!5A%:*U !!5AN{!5ARun} !!5A*tW!"5A*u[""5AW^5%5"+:c%O"+:iB%i"+:fnK%"+:Wds,%"+:xj%"+:*B= _""5A)7* o""5A".g# #5AuHLI#5AuHO$8aF%X#%}#, ++f;#F&'&'p7N#F&'p7"%#''   $'%''66- >$%''sk r$, %''++"%$M(M(}< M(%''((Q'#Q'#J|6'#/(_$)$G!^!D$`9A3H1Run2 %E%K%3H0^±'d%j%QH0fdTC%%QH0lA+:%%QH0s? %%%QH0yEH%%3H0<O\M %%&QH0RT$ %&$&QH0iY` %=&C&QH0.o_2 %\&b&QH083dV %{&&QH0Mfi %&&QH0lc %&&QH0q5 %&&QH0?v %&&QH0\{u %''QH0O~H_ %5';'QH0CT'Z'QH0s gs'y'QH0Dj%''QH0w%''QH00C''QH %0f_i:''QH0fWH((3H+[@1(<(3H@*F+P(o(3H?' %11* e((3H11+n5A((3H %+GUD((3H+b?H((QH"))3H$)))3H %*\=)H)3H B*F \)b)3H"r)})3H]HLIC)3H]H$۴A,f۴))IIf۴))IIZI)*IIu)$*/*I]HZA)M*]*I]H %1cW){**I]H  )**I]H)**IuH)*+I1:4)+*+I8bpZ )H+S+I1:/? )q+|+IuH )++I]H. 6 )++I]H le )++I]H % LS),%,I]HQ*)5,I %g) 'q,?j 6, %` 6, %' '>c,YLg %g Bc,YLg %- -> @%'-8/J%>-84:2\-28N&O6}-IT'6G&O% 6-ITM((E2-2_5 6- %''(2 -_5gQ" .''%%+ E.''''} n.''''+ .''11}!| .''11oJ3 .''m%m%+($ /''k5k5}.. ;/''k5k5+  d/''M(M(} /''M(M(t&O6/IT,E?c/16/:Mq8/:,"j 607IJ%1017klU6k2]%kz%kǦ%kYS&6k6k* %n%k6kz/%kk9`MkEo*%B:%r <%6%dk^P% w .w 1n'w *2w |:w +.w ;x Px P0.0x PAx SRx Fv}}\Fvv}aF}tvyvv}2v}$a _2sla" %sSpa#*[a$;2a: qa?u=J4rtaF4aK2%BaL%`;aM aR2%aS %%daT %%YAaU_2 aZ3%Ba[%`;a\%YAa]_2abM3%Bac%`;ad%4ae %%=afj2 %`agj2alo3%am*%5/anC%as3%atX%%Pau % az3%a{*%Fa| %%7wa}Q%saGJ4saN2s'LaV2_rta^2s޺ah3s+aoM3sPavo3sa~3%wa@ %%aA %% aC %%a2 t %Z4u' 1au2|#bUp4vv44 % (@c4rc4sce4s_c!4%c#4%^<c+%c. %%<c154 %4*vZ4v4v5vFvjGvoG} 55vGv}Gvϛ}ϛvI52Y52v/}(}/}wHv(vԛv}7}v7y=56`75v5abiu5v<}&'v }5m%}7v͢}͢vҢ}5%}Gvݤ}ݤ}'}Hv9};v;vH}I}HvIvIvRJ}I}RJv <}=v=v"I}WJviJ}I}K}iK}Kv\Jv[Z}5K}wO}Q}[Z}\JvZ}[}o_}Zvo_}X]}]vvtX}Yv_}X}Zvt_}_}%v}T:7vYv%vW}Wv-v}vvvaFv=}4?v4?v_}`}_v`}a}`}av`vc}Ebvc}d}0d}j}cvjv7vv77}7}7vD}kFvkFvj}k}jvk}Zl}k}_lvkvm}mvm}n}n}t}mvtv}TvG}87vI}Gv3v? }3}? vI};Kv;KvIu}v}Iuvv}v}v}vvvv3x}dwv8x}$y}Oy}W}8xvWvD v } vYv}v }v} vv}}vP}DRvDRv\}}\v'}ʀ}'}πvvF}wvK}7}b}o}Kvovv}vvʭ}ʭ:vv vK}Kv%:vC:%:}%:}C:vU}@Wv@Wvt}.}tv?}}?}v3v^}vc}O}z}}cvv %} %}%v\}I^vI^v}A}vR}}R}vFvq}vv}b}}}vvvvvvb}bv}h;vرvQ}Q69vV}}  -W %;5ELd%;' MW %;' MWX%;'Ee*"<uu&'&' jdivWc=< % % SW4*S<' Wn<X%X% nW^ %<'&' Wi&'<('&' `Wa %<('&'[W<*&'&' w>Wv %Wx =Q%EvW%$='MEWX%C='M %E*tW_%b='M % JKW %x=' NWl&'=*M(&' We %=*<% 9WŒ=,, KW$,='EW,>'M %EL Wf%">'M %EWm%<>'MEVWt%V>'Mf}> 9m =w K  Kg7>%#g9 %%#g: %v}>7h> Z : J  .     '!>iJ% "j?%j>%n_j?t'%.?u' j?  X O  ( V  u Al H  .. } > + 4 Ls  W 8  . k7=@!k9 %!4$k: %!k; %!k< % !3k=!1k>=@!k?*!Rk@C@v>v?vO@?vv#v-p@vv}k@vp@vk@v}v@vPv@@}@}@va}cvcvl}&}lv7}ڟ}7}ߟv+vV}v[}G}r}}[vv5AvJvAA5A}5A}AAvh}jvjv}g}vx}}x} vlv}Ȭv}}}}vv}%vL}LvvQ}v(}(vAv-}A}-v:p}qvqvŴ}}Ŵv}3}}8vv}v}}˸}Ӿ}vӾv2vR}RvvW}vY}Yv~S}Bl9vCw}~SvB}BאvHw}BvP;vBP;}P;}BvMw}xvxv}F}vW}}W}vKvv}v{}g}}}{vvz}CBvc~}zv6vh~}6v}vvv$vm}C;Avm~}mvk}C/Avr~}kvd}D@vw~}dvu}v}uv?D*}*}?Dv|~} v v}k}v|}}|}$vpv}v}}}}vvvG}DMvk}Gvv{%}vҶvvv[}}[vp}vv}`vr}}7}}<vev|}V}}}|}ev}}}v}y}vVv}$W}CXv}<v}}@v}v`Z}}E,vuL}F8vՅ}uLv/v/vN}>F8vڅ}NvZ}[F=:v߅}ZvzX}xF7:v}zXv_}F:v}_vD|}FBv}D|vs}FAv}svf}F@v}fv 0v@}Gݐv}@v v}E}dv}vt'%ZGu'}JGvvy4v}y4v$u}GBv}$u}v} vY}E %GmvGpGvv}v}|v:7v}v}vK}d1v}ivi3Hv$vv}}v)}})v}v}$} v}v}Hvvv}A,Dv/}vn}09vg}F,v}v}N}S}v)}K,})}P,}vb}U,}v}}}}v}ivi}n}ipN'IrN'N' IIB IIBIIB"I J J2#J(J J 7JBJBJv\JgJgJGJW J__p *vDvDJJJJDJJJEJJJ JKKKKB.KCKCKH%bIZKoKoKH%GwKK@H%l %KBlK*vKj$K. 0KK 0 %vj>'L. AKK A %C CjXKL. NKK N %X ZLqLK__a qLvD2ELLLH%vLvLLLH%Lv;vu;LMMH%+MLLv^DgD-MLMLMH%+QMML?;eMMMH%+ML{MMBM1 IM Ih(MM J(1MM J1N*N JM1 I*N I +p!JN__p *q"YNpNpN__a uNːM NNNH%VI NNB Ah__s A'JN'N,O O!OK 0OGOK__n hVOaOBzO__s)O__n) O__d d*__s d'__n dh77*P__p7*s7P**?P__a!O6__b!O6cP__a!K6__b!K6P__a!7__b!7PPL\ V8,P9(P__s'PQ9(Q__c'%};`;*QAQM__nQ%}}6tqQ__a![qQ__b![6GQv7c8QQQ)!BJ8!DJ8vQQ__a!W6Q__a!_Q__b!_6GQ8R=RQ)!SJ8W!SJ8!UJ88LRtRQ!v!x8RRQ0!!vERRR__ca'%Rv}RSSa,xSRR(S3SHBSMSMS2sjSch'%)< %S'Sv}SstSSSSGM1 *SSTTrhsIT}55+T6TBETPTB'zT__s'__c %TT57H%TTTH%A`TTTH%GƨU U UF7 U+U U:UEU UTU_U>FnUyU>FzUU>FUU>FUU>FUUk@H%UVVH%H)V>V>VH%Hk RV]V]V`9UqV|V|V9sVVV94VVV+:SVVVgVVVC%WWBH% .WCWCWH%H%,ZWoWoWH%I(WW.H(WWWQH%WWWH%9HWWH^5A X$XHD%:3X>X>X?HRX]XHͽlXwX>XXX>XXX>XXXXH%BXXBY Yk@ 3Y<%.<%$iY<%.<%?FOYs1's2' YYBYa3'?ZRg %Y H5# HD$ %ZD7Zfd %H$ %aZA$'a$'pZ{ZVZZV`Zٖ ' 'CZZZHfZc '%[;'?'b&[>[>[m] %J;R[][>Xl[w[>X[[>XD[[Hߝ[[[5a[[H[\T)\\VU0\;\;\(HO\Z\;\i\t\;\O\\;\n\\\;% %H\\;\\\\ ]];\$];]\fd % J]U];\+d]{]\fd %]]] HD']__s'__c %v5];'buf]a^c\'%"^:^G__s 2'6n^str'ren^lߕ1vy^Q^Q;^^Mls^P>^^>F^^>F^__75_6_IT'6_E;_Y56sO_e_e_p~ݐB9O y___%T9___H9ʫ___ __]V*_``: `"``1`<`VK`V`VEe`p`p`r9`!'%9(MK ' ````__n>A`aa__n >A"a-a-aAAaLaLaA0`aka`v~aIT6a!'%9(gn aM1 aabIT %6_valsbb:7Lbb %};b\bIT'%6_vals\bbpb{b_}}ZbbbbZ@{blb!'%9(MK b 'ec c c7f!c9c c__nczHcScSc*9߄gcrcrc9ۏccc__n:ccc!ccVHccVddd__n : ,d7d7dD;ʙKdcdcd__n &;wdddwCddd__n YCdd>[|% di &']Hٯd"e>[|% "ei &']H+6e\e>[|% \ei &'uHTpee>[|% ei &'1:}ee>[|% ei &'8e f>[|% fi &']HfDf>[|% Dfi %]H!Xf~f>[|% ~fi %]Hff>[|% fi %1:ϰff>[|% fi %uHxg,g>[|% ,gi %]H@gsg>[V sg %i &']HJgg>[V g %i %]HHggg~Bghh__n V`B}m2"h2h2h7hC h}BhQ%]h~hITQ%6_vals~hbj{ %2MjXjXjljwjwjŐ3jjXjH%jjwjH%Gjjj__ij88nIkkk8wo#k.k.kY8GBkMkk4H\kgkjovkk.k}IrkR7#NmMK=k>kkkkkkitXMn}8llH l8l7d__nnlIE %v.nli. %h. %8;lllH%B;llM__n,&llIT,6_valslbE; m$mM__f%M:m[mIT%6_vals[mb5|ommSc__nHxrmmVmm|V"m|^+:5"m|c+:Åmnrc__n*#n;nrc__nHSJnbnbn__ignBBxU{nnnBCnnn__inBBenn cdnn cDn o oB=3o!bCo!b %=oCoHv3ooIT  H: op '=o! o! %Hoo:vo pITH  :: op '=.p! >p! %8p>p5Av.ppITJ  5A:  pp '~zppp__ip}CC6ppp__ipC68pqqC=)q!X=q!X %%7q=qDv)qCqITҶ%  D: qp '0lqqq__iqCCmqqqCoqqqCknrrqnr)r)rC}m~lrR;A#NMK=lr>qr.r.rv_k4vrrrvrrrr__irDD4rrrDrssWEOns3s)r__i3sCWGsRs`asls`vrs%sCss>lscsb ls[ %itAݺss>Xtt>Xt5Avtgt$mtw m m__f ttQtc'tt'tAbNtttFLttt__itF F}Cwu%~Sut=&u1u1uv7>EuZu1uH%d`iu~u~uH%73`uu~u+auuu7buuu7/uvv>-v,F}Hw+v%B+v vN?vWvWv__i\v2F8Fypv{vSc1zvvScPvvvCF OvvvGOvvWv}څ̆&wR8#N8xMK=&w>+wvvv6w%Fw8w8x>0wcwb 0w[ %itx9Zwww__iwOFUFwwc\wxc\xxx`F[3x>xxL[MxXxw}߅xR=:#NcMK=x>xXxXxvx%x+: yc>xc yb x[ %it:~ y*yV_ 9yDyV$]yٖKC;vyٖPCyV yMf %i %ٖ yj %| y]HuH1:y%:vyAz$Zyw Z Z__f yVPzszsz__p UK xzT:N:LXzI_Tp%:__aMz__pMQWaMzr:N:gZzzz}FXz{{__i {lFrF]{B{B{__p \K G{::U_{I_Tp %__aM{__pMZ^aM{::pa{{{F_{{{__i{FF|{||__i |FFt|*|d69|D|dxS|v|v|__p ewK {| CCy|I_TpP;__aM|__pMxaM|)CC||||C:c|}}__p bK }@@dW}I_Tp@__aMW}__pMcaM\}@@fp}{}{}De}}}__i}D D5}}} Aۨ}}}__x!D ~~}u'~7~F7~ B~qK~n~n~__p RpK s~B Br~I_TpA__aM~__pMqaM~0B Bt~~~F^s~__iFF9g22__i7FFTKVV)AjuV}r~B%kuCj__p iK RALAkI_Tp5A__aM__pMjaMpALAe(3}6eBM{}tczIT'%6_EzJD__p ~K PDJDI_Tp*__aM__pMaMnDJD> 01u__p =K 0a@nI_Tp__aMn__pME?aMs7|BG@__iÁG G}ݐ` I_Tpݐ__a' __b''ݐȁȁ.**/77@X__aMX__bM]77Zaqu__xe7au}΂|E__f .R݂gJ!'%9(gnJ'<<H%EoPeeH%-E__x*(Vg__x* VÃÃ__x*E׃]EX__x*X69R"--6wRAL-mI_TpH__r'/m6+JQ6__x@B`Gi1фmiJ i__a8s . +BS =RRH%ѐf{GH%t;H%ƅe_H%ՅBJ__p IK 88GLZI_Tp3__aMZ__pMLKaM_88Qs__p PK 9~9PSنI_Tp__aMن__pMURaMކ9~9+/  -#!FZ 5bH%D\\uAaH;)xoWFH%qЇn~__p RpPr__aM__pMq0Bho+fd %!0:QQ-F2h}2hH%HTrhs>52ˆT ;ӈTH%}[[4fpD3ChR[ *__a hk { G\/%REĉωL(މLvb8k>__a!w^7__b!w^7McNip~%5{__n$ %!'%9(gn$б__f$lF(ŊЊB 7ߊqc '%K7pf*5B}h~&sR'#NMK=s>x55G__s 'ˋGM1 ˋ2ߋXjwj__a8sːG1.9 Jx K``H% SEtH% 8lkH%8=֌xh777xh7wz7z7>xh7I_Tp7w77>)8#JRgH%uvH%8CKǍǍ5 ۍǍsam g5G8 sG8 tLG u7O v755G`kǍz 6sam g68 s8 t G uGO vG66W),Q8MH%\qqH%9K__p IK__aM__pMLK8TԏߏnY b `@~9SHRl9#NKMKHMttE/jR~S v-~S>Tbn}0l/- /-ؐ H%R__p PR7__aM7__pMUR9(VK`szH%oH%f:=xh7:7:7:Ցxh7:wz7:z7:1xh7:I_Tp%:w7:7:r:1]$9B{H%H]]H%:>xh:::^xh:wz:z:}xh:I_Tp %w:::Wsz__p UW8__aM8__pMQWr: ^LcB{__p \^__aM__pMZ^:wv|H% ԓԓH%C!>xhBBB%xhBwzBzB`xhBI_TpP;wBB`)C1~tF|||}RB#N{MK=> P;vW$D| w D| D|__f  xf}v|__p ewcy__aM__pMx)CV^cϕ}__p b d __aM __pMc@ob3}H%BWWH%@@>{xh@@@(xh@wz@z@Gxh@I_Tp@w@@@xi H%-00H%dA_>Txh/A/A/Atxh/Awz/Az/Axh/AI_Tp5Aw/A/ApAhЗۗۗFUgۗg 2}RR@#N[MK=R>Wh@v\$fhw f f__f hLl˜͘qIܘٖ9CCڇ1R/A#NMK16uulJUq}0;0-l|Q|US0-QH%gj͙__p ik__aM__pMjpA-D}w~SR@#N[MK/S0XRd__x$__y%'D'D/dkΚٚ}Rd__x0__y1 'D'D~!6H%1EZZH%bD~>~xhMMM:xhMwzMzMYxhMI_Tp*wMMnD4D0__p ~T__aMT__pMnD ?h1u__p =?__aM__pME?7__x*$cڜ__x*,cp__x*P G;s>I_Tp'%>C"EWb;kq|k/8lG8nɝԝ.kE__p mDDF/__aM/__pM|F__nMF)8mCh__pOl__n:lOyH%lEm̞H%o۞.kH%I u$Jv3>>85wR]]8Jq__p mIIK__aM__pMLK__nMxK8wџ]__pv__nvO>H%=I_Tp3__r'/=8cI_Tp3\\8xh8wd8d8xh8wz8z8xh8I_Tp3w888v]w(=]H%~Lddzx 9}xdPq]ơѡѡ9H9Q __p mPPRP__aMP__pMUR__nMR9d__p__nOѡH%-ТI_Tp__r'/Тx9KI_Tp\\l9#xhl9wdl9dl9eRxhl9wzl9zl9xhl9I_Tpwl9l99УH%݈ߣ9 RLcQyc'Lt'y:iv4Ԧ8v4l9>1u__p m==?ܤ__aMܤ__pME?__nMq?7bu__pa__nxaO&;uH%\I_Tp__r'/\I_Tp\\ݐxhݐwzݐzݐxhݐI_Tpwݐݐ7buH%i$<h[c>K[1u[|7I`o~u__a8s7@au__aZ70CŦЦ o5I_T1I_T2__pOݐ>OnC%n4]Rא#NcMK=]>b v v]HBxhݐw)kB)kBC)lݐb)s% HBxhݐI_Tpw)B)BC)ݐ 7C__na{Rא#NcMK{ v v/RBvv-B0ըx' K-ըRB/w B B /U+6szÉEPu_jjx:`~:Vsz__p mUUW__aM__pMQW__nM}Wr: "__p׊__nŠO3HjH% Wb͋qH%]B{֓]ɪԪԪ:s;]#B{__p m\\^S__aMS__pMZ^__nM^:g__p__nՔOԪH%̫۫H%v47:{ v4:w/:v|ۿITԓcnn/CxGC5dǮƬ>[Oxլv|__p mewYwDy!__aM!__pMx__nMy)C!5Z__p__nOknH%!H%|{Q c't' kCdH%5v4BQMv4zev4Ԛ@bt}__p mbbc__aM__pMc__nMc@Ԯ__pϟ__n@O$$H%@8CŠRgH%'v4Ab'2}ALWm[f$XuGi0ðΰΰvAAj__p mi ijM__aMM__pMj__nMjpABa__p__nOΰH%BƱձH%pn~H%E22H%$BOH]]H%6Bzv4/A~ZȲȲtDܲD~__p m~~sG__aMG__pM__nMJnDF[__p__nOȲH%F ϳH%<h r'2rzALh}kRM#NMK=>LLhH%дv4Mhv4ݐ<>e+669EJU6dos~`~u3E5ŵе%'6!'w.Z'.Z'<B'N'EoH'w.r'.r' __p *' 'O 'X'>$%|'ƥ%|'__a%|N+%__r%X'P'>$ 'ƥ '__a P'>$ 'ƥ '__a ߷H'G>$%'ƥ%'__a%߷}u  __ixG~G$/go>Igc8 8w88C8__n/hR8v8Y {%8 8wI8I8CI8RN%AR8v!8Y {%8 8w[8[8C[8J8Kǹ__aMǹ8v۹9zSc2I_TpQ%__a2__b7''MC.;Fd'xUqv|__n cYwu&y__aM__nMy)C__n'v4z$&I_TpP;wqBqBCqB.x_ d HRzvz Y {%I_IIBI_OIBwBBCBR% Rzv!z Y {%I_IIzI_OIzwzzCzU'2d{AY|__n @z}c~وRB#N{MK=>YY I_IIzI_OIzwzzCzd'dP}L IR@v@k Y {%@ @wI@I@CI@RN% R@v!@ Y {%@ @w[@[@C[@c(33@&dP__aMP@doo@Vb}__n cbuc__aM__nMc@ߠ __n,F, B SRAvA! Y {%A AwIAIACIARN%] RAv!A| #Y {%A Aw[A[AC[A`q2==BqQmn~__n cFpur__aM__nMr0B8__njr__aM*BwTBg g 5I_TpA__r'/5B [I_TpA\\A xhAwzAzAxhAI_TpAwAA0BZH%//H%GpCNn~]h2Ƶw]<R/Av/A[Y {%/A /AwI/AI/ACI/ARN%?R/Av!/AY {%/A /Aw[/A[/AC[/A%j^A/k__aMjA_AO`i.__n c iujR__aMR__nMjpA f__nRMvMY {%M MwIMIMCIMRN%M"RMv!MlqY {%M Mw[M[MC[M\D__aM¨hDcDSV__n c~uU5__aM5__nMJnD$Ib__nݐ ݐwݐݐCݐ__nRݐvݐ8Y {%ݐ ݐwIݐIݐCIݐRN%ZRݐv!ݐ"Y {%ݐ ݐw[ݐ[ݐC[ݐ>7}>1u__n c=u|?__aM__nMq?7b+Du__naS^^7?{__aM{7dbu__n__a7?__aM7e c^?Hݐxhݐw)kݐ)kݐC)lݐb)s%HݐxhݐI_Tpw)ݐ)ݐC)ݐ7Hݐxhݐ_w)'ݐ)(ݐC))ݐ!)*7Ad +h}iRݐ#NcMKin++dhchhh__x7r<__p m|F.__aM.__pM__nMGBMss\ts__p*Es__p**6H%sH%&I_Tp' __r'/&4:EE E1c__x*|__x*0c-I_TpQ%__a©__b®P*!'%9(MK  *  /Chh__x@rm__y@rrDsL__x*B__x*&G2GG  __a+p__b+p555*5N__x*4c]__x*__y*__k*__x*7EE/I_T13I_T23__pO8>O/8H8xh8w)k8)k8C)l8b)s%H8xh8I_Tp3w)8)8C)888H8xh8Iuw)'8)(8C))8!)*88LLWtyfqd}Յ3R8#N8xMKqqzd_ I_T1I_T2__pOl9>O ~9_Hl9xhl9w)kl9)kl9C)ll9b)s%Hl9xhl9I_Tpw)l9)l9C)l99Hl9xhl9\w)'l9)(l9C))l9!)*98\l9 l9wvl9vl9Cvl9kv%jI_T1AI_T2A__pOA>O BHAxhAw)kA)kAC)lAb)s%oHAxhAI_TpAw)A)AC)Ao0BHAxhAŴw)'A)(AC))A!)*0BCA AwvAvACvAzs(3~PBMh}`RA#NMKMMhpn~B*2__a8s*B۵ $]__aZ$$%|*ƥ%|*__a%|lN+%__r%t*>$ *ƥ *__a *>$ *ƥ *__a CH*G>$%*ƥ%*__a%C`__n$ %!'%__c$'%!'%9(gn$__f$j=!'%9(gn$__f$FviG v"X2X;AXMvClpXn %Oc<%ch'%c'%osp7/ITouxJu<&M__puMIs&Ios&p71s/&Osos&Op7eIT/&os&p7ch<%5%s&os&p7k5%/&O%os&Op7+XIT, /&Xos&p7+&lH%G__c '%/_IT/6_valsb_5U)6_H%I ;P_H%t'%`u' }P|ITP6_valsb`n!'%9(MK    't'%u' }5IT6_vals5b)PqIT6_valsqbt'%u'}vPITv6_valsb}JGwITJG6_valsb}?&GIT?6_valsGb t'%\u'}LxITL6_valsb\IT36_valsb8t'%u' }'IT6_vals'b}ӏ:HiITӏ6_valsib,t'%~u'}naITn6_valsb~t'%u'} IT6_vals bt'%"u'}>_IT6_vals_b"t'%tu'}dITd6_valsbtt'%u'}IT6_valsb(%(__x(%t'%8u' }($TuIT(6_valsub8t'%u'}zKITz6_valsbt'%u'}rIT6_valsb3#MtM͆Rf~~2/2љ~H%`oKDoK/|@C@b&$5@@v@Tl@/l|@8*2W/cHxd   p~א:Ь4I H%Xcd0r}cdcdH%dH%H%(I_Tp %__a'(__b'-' %::]IE %VL)7vL&;-lwH1Xqlp~Bnh5|*"[Qhc'"t'hA6KKH%AR_ttH%AԮaH%}H%B Dh-ch'%Z,T ?x(@CW @8t'%Uu' }EqITE6_valsbUt'%u'}IT6_valsbt'%u'$}6IT6_vals6bt'%Ku'?};gIT;6_valsbKt'%u'}5IT6_valsbt'%u'>}\ ,IT6_vals,bt'%Au'=}1]~IT16_vals~bAt'%u'C}IT6_valsb1|V  Vq,"nQ %,;; %}'WxIT'6_valsxb;dp`str 1t'%u'}IT6_valsb9fd %buf*[Q%t'%Iu'}9eIT96_valsbIt'%u'}FIT6_valsbt'%u'.}m *IT6_vals*bt'%?u'2}/[|IT/6_vals|b?t'%u'4}IT6_valsb}IT6_valsbt'%%u'&} AbIT6_valsbb%t'%wu'1}g0ITg6_valsbw}HWITH6_valsbt'% u'"}~'HIT6_valsHb t'%]u'(}MyITM6_valsb]t'%u'}IT6_valsbt'%u'}>IT6_vals>b}_IT6_valsbC^!AAAD% AAt'%u'}AIT6_valsbC0ch'%,pF\\x a55><uM__fm%x 559( J 1 JX#, t͆#++}.M(b IaITM(_/a(}l(YIT(^fI_T1I_T2'__pOݐ>O6!HBxhݐw)kB)kBC)lݐb)s%tHBxhݐI_Tpw)B)BC)ݐt7\HBw.rB.rBjxhBhwBB__nEjJj<HBhwBB+bKbu__ab7}mt'}u',YLg %xg}t'u',YLg %x >F  VfY {%I_IIBI_OIBwBBCBI_IIBI_OIBwBBCB>HBxhBw)[B)[BC)\B>HBxhBw)kB)kBC)lBb)s%HBxhBI_TpP;w)B)BC)B)C^HBxhBw)'B)(BC))B!)*)C;B BwvBvBCvBzJU|RB#N{MKYY@/|@}VaϪk 88 C)76Lbtp~@7 s~TkKp~ABICW%-I$~TrhsD5ud9D>Xifd %?'{uA UD1fd %bufu[Q%c((d- %F %9d %@71DY]H%/dkH%G-H%G;\l'3l1H/4\~%CNC:]h Uwf'3f1g' g %E/'3/1I H%Hh4?hNYY'EJm<__n c|u(__aM__nMGTss__x**KE::__a+p?__b+pD8G>G#7!XpÃv*pE__a+p__b+pEE#7str/*'E0__x0EE;\-886>YLWW7zYkvZ\8$ZW__x*;7U__x0__p0Et'%u'!}h$EIT6_valsEbt0Z[pH%wGuu }؉RB#NMK=>\H$uxhAw)k$u)k$uC)lAb)s%H$uxhAI_TpAw)$u)$uC)A0Br__aM*B__n__aZB"/1I//IrB_]h wH}8IT86_valsb ]V=bkey_1BRl9#NKMK/B0GttT[fnuBR1t'%u':}IT6_valsbt'%u'} 1 IT6_vals1 bO src't'%_ u'3}O {  ITO 6_vals b_ j   `HH  V1 K C: H P; , !Z  AA H P; i % VBh %  Hȥ  8 C' 2 }sA L }A $uhw u u__f hۼ 7 H/c%;%g%%P;%_$%i %P %F ^ H/3%¶p { Fy&ՠ D&IT,Ep7  IT,/& os&p7|&E IT,/&Q os&Qp7E'@ IT,/&a@ os&ap7EDj /&Oj os&Op7EF IT,/& os&p7E /& os&p7Ek /M EeIT1,IT2,/EEMnI_Tp%:wq=:q=:Cq7:.x_ sY {%I_II7:I_OI7:w7:7:C7:R%Y {%I_II7:I_OI7:w7:7:C7:aI_II7:I_OI7:w7:7:C7:>H7:xh7:w)[7:)[7:C)\7:H7:xh7:w)k7:)k7:C)l7:b)s%NGH7:xh7:I_Tp%:w)7:)7:C)7:Gr:H7:xh7:tw)'7:)(7:C))7:!)*r:7: 7:wv7:v7:Cv7:X z%d}2cR7:#NcMKch%%=|dvI_Tp %wq'q'Cq:.x_ 2Y {%I_II:I_OI:w::C:R%<Y {%I_II:I_OI:w::C:xI_II:I_OI:w::C:?H:xh:w)[:)[:C)\:YH:xh:w)k:)k:C)l:b)s%H:xh:I_Tp %w):):C):: H:xh:w)':)(:C)):!)* :[V: :wv:v:Cv:_ep{cd}_R:#NvMKPcd8I_Tp@wq@q@Cq@.x_ Y {%I_II@I_OI@w@@C@R%Y {%I_II@I_OI@w@@C@+I_II@I_OI@w@@C@9?mH@xh@w)[@)[@C)\@7H@xh@w)k@)k@C)l@b)s%hH@xh@I_Tp@w)@)@C)@@qH@xh@lw)'@)(@C))@!)*q@@ @wv@v@Cv@R@#N[MK HcI_Tp5Awq;Aq;ACq/A.x_ Y {%I_II/AI_OI/Aw/A/AC/AR%VY {%I_II/AI_OI/Aw/A/AC/AVI_II/AI_OI/Aw/A/AC/Aj?H/Axh/Aw)[/A)[/AC)\/AH/Axh/Aw)k/A)k/AC)l/Ab)s%<H/Axh/AI_Tp5Aw)/A)/AC)/A<pA5H/Axh/Aw)'/A)(/AC))/A!)*pAu/A /Awv/Av/ACv/A8avaRR/A#NMK/R0Wuu-k2ha351p%/A)r__iu_;A/A#NMK67.ruXm/q__n k{I_Tp*wq9Dq9DCqM.x_ Y {%I_IIMI_OIMwMMCMR%)Y {%I_IIMI_OIMwMMCMnI_IIMI_OIMwMMCM?HMxhMw)[M)[MC)\MQHMxhMw)kM)kMC)lMb)s%THMxhMI_Tp*w)M)MC)MTnDHMxhMw)'M)(MC))M!)*nD M MwvMvMCvM6RM#NMK6;LLZOZhIRM#NMK/0LLOC or__nbUPmcD   Dx strx Pv'%$7Lcposh31 str' %i %= !B !B % %  Cv 3!2A3!:B sumC %iD&'A{!str'9^p'ch'@!^/n %/n %E!!R__c3'%!!!!!K9`"".K9"Q"_" w"" !""AA"""AAtKi*""K##@"L~-#7##F#Q#@7#m#w#F###@*##oW#]H/*# $oW $ %]H]*&$=$oW=$]H*Z$q$oWq$]H*$$oW$uH*$$oW$1:+$ %oW %8*+*%A%oWA%1:S+^%u%oWu%uH|+%%oW%]H+%%oW%]H+%&oW& %]H+7&N&oWN&]HQk&y&XHWV&&ZW&& && O"'|i+: 0''Vx+#6 xx# +#x+#x&:&]i"'|n+:P*'?(Vx[; xx# [xp[x'h'"X(|s+: *p((Vx@ xx# xx "(|x+:! *([)VxE xx# xIxh@ s))Vc J c# c# }))CW)]H)*CW*]H-*D*CWD*]Hsa*x*CWx*]Hw**}*Q***[%***f*G8HK+"+ZKT>+H+TWz7d+n+.WU ++UV\++)VHK++ZK{ Kd,,.K{ tKL6,J,K{ TǦf,z,T{ UO,,U{ Vu,,)V{ WR, -.W{ HW9L&-:-ZW{ X-ITxSP;ޮg-|->[H%X-0-/g-X'x .ۭX'(I</:-b L- w .&5K? /Ƭ Mլ߬/{ w /&5K?BUƬMլ߬U{ { X-(//g-{ F0/0 % % zNiT)"020N$zN%3N00NzN |0Nh%-{ dy N01dd46dd46dhd4 wdwddpN$11de6ed6ehd8 wd wd 'e;:N1 26e@e6@e6e6Oe%hdX wd\wd\aeN&22peze$6zepe$6ethd$x wdwdee`N2 3eet6eet6ehdt wdwde N(33ee6ee6ehd wdIwdIf:qO34f(f7(faf77fhd wdwdIfNPO244Xfbfd7bfXfd7qf:hdd wdrwdrfO4(5ff7ff7fhd wd wd fOD55ff7f2fQ7fphd wdwdf@O5:6ggT7ggT7g hdT wdCwdC1gRV66@gJgWg:WgJg@g:fghhd wdwdxgk>S6f7ggg;ggg;g hd wd)wd) Pr7 N!!%!QaX0D`a`a} +8 5  X  { 5{ _{ KLpPC89ZL dL 'Lp 8>L2L*  8>LO 2Ld K RKO Kd K T Ly K L v  9-9-9H%oH9XN9:99 99 W f I #9I KL% #dL. ZL[ I+8Ro6{ R{ :$:hH%#Z:xhAwdAdAxhAAv:<::y 'H;y   ['H{ o 'H$:'H~D: 8: :+(gN +(] W+(f' KL+H #;dLc ZL ]+8RLIG #I' o#߯o  os ͯ  s M  |{ R<>q> :h:* 'H>* O b ['H{O ob 'H$:'H~D:O 8:u :+gN +] W+f KL+ #=dLZL4]+8RLIG #I o#߯oRtowͯwM{ { Qd>>hH%B,?xhݐwdݐdݐxhݐ>gnH?A>;h@ڥΥ;;>;~? ?aguW]fKL #F@dL#ZLCL+8RLI7 #IVVaVZ ϤäZ Mc{ )AAAG__s 'CPAuAB h__n hFs7FzFret6(Eat&'wX5}@BAiA 3AA)AihAA BgAZAPA)N  BNUNN)I  CBI)<$EG CPWPCfIP8 #KCIKLYP #dL(ZL=r+8Ru`AAxpDgAPZArPANx DNNrNIx C DI <$PDfWDfI #DIKL #dLZL8+8RudW @EfI  #EIKL&  #dLZL6 +8RudW: EfudI:  #EIudKL@  #dLZLP +8Ru`t  F4 ZMC!fuI #@FIuKL #dLZL +8Ru_ { 1v}#` GF;F;&'[<&'os&'8j?56P XFQGQvP$ R$P IGPPaO GlO {  R$P DGQP R$ |  _@ `HH_)_)_PV p{HPBP`aOV pHlOB_ { o R$ )__xP P0P R$99uH9J9W fI #EIII -IKL% #dLZL38=dL\ZL'L8 +J>L2LB I>L2LKB RKKKh T LK&h LQ`v HJlJkH%it0Mn9JqJLHJ%QK^JNk0J#k}j$j}jJgk14Kvkj6jjMk20\k̞</L۞<4<CYM<@  "ԝ@ MI{ ̞V/L۞V4XCYMX\ "ԝ\Me{ q{ [L)M)MT[?\' ] %uA^'y;LJ dJMMLLMM Mi _Mj! jMiyii  %|  {  { ޲bM N)MH%M] M'NNM{* cNW* f0I*  #NI0KL0  #dLbZLY +8RoA { ` O8O5H3HTw PO+TIw  IPT OmTaT >|     {  OR'str'n O# SvPa3vPs' )j'0PT jPmTNaTc >|  O1% PPP69T?qP;;P 2P QPPPP = /QGQ>VVD Q4uP "cQvQ/Q9QUQQVVDvQy "QQQQi QR>XQa `a#T`a#T57RٖVC *ORR>Xs ss#T sv s .RR>Xf7P#Tƹ .R"S>XGf7P#TP.:S]S>Xwf7P#T.uSS>Xf7P#T#.SS>Xf7P#TB.ST>Xf7P#Ta.&TIT>X7f7P#T@0aTTH %fLpWTPnow7h[| lTTlhsl'rhsl'{| 3 U'U_l'UZ9T0bHUUUU_MzU_@_rUY_O_U`%| l{ { ,&Vj_ _y_@_Y_O_#-Vj_ _y_@_Y_O_#6TVlhsM(rhsM( *V.@T-Wlhs.'rhs.'iY_ 3YtYi| vB=oWlhsBM(rhsCM(| Z;Xstr[X]&[XhmV\5UW]5Y\#XYI II -IY]xXYI II -IV11XXG__c -'%B /v4 \ It]ss{Xi]str|t]}HCend~HV6&|fY D@TD}Y+TID IYG~YYtT Z 4T ZMC \ch'! }k(vZW Ak( 3AW )AhHo XH Xo XHX I /[II II -IN 2>[N N I 3r[II -I!O` 3[:O 0O :O!0O#!J [JN NN6!Wx}\fN!I #D\IN!KL #dL!ZL!#+8Ruc2\fI2 #\IKL: #dL"ZL1"J+8RucWJ^]fudIJ #%]IudKLP #dLD"ZLq"`+8Rucki{ 1Np*]]]Xq5/]]FH%]L`Vix# =LV""ܠ"c~w"BgV #]]] #W/W_fB#KL( #:_dL~#ZL#+8RHI #IB#WH/_f#I` #_I#KLx #dL#ZL$)+8RHW/f,$I # `I,$KL #dLN$ZLn$D+8RH^`s`BH%/pX`dVi0bx# =LV$ $ܠ$  c ~w$B gV%] ]]%WH /afJ%KLh #adL%ZL%+8RHI #IJ%W /obf%I #5bI%KL #dL%ZL&+8RHW /f4&I #bI4&KL #dLV&ZLv&+8RH+( 1 &У+@ ߣ&R9g{&o&#9gC79g9g~ &բ=h g:'L`=h ]^`:'W= Edfr'KL= #(ddL'ZL'{+8RHIh #Ir'WX f'IX #dI'KL] #dL4(ZLT(+8RH-d@d8E4dOe|Vr(Fw( Fnwcw(( }w(( w('-heJhe8O4ee|V-)Fw@ PnwcwL)@ }wq)@ w)wUPe0f|V9cTVHc# Hc# {?fWfSc__n xPpdrfZg|Vi %`mX /gym)om*0fx J gIf)?f*9c"gHcHc<$h KhhP*^Og| e7Yugg|V i8 %{* Wfe@NghVxB , xx* x* x*mbhm +hm7+mh _phmc+tZgmk_m7+>x|Mx+NhiVx 1 xx+ x+ x+msim,m-,mdgim-,Zg>xMxY,+Pij>Xs ssq, s, s,DypjOy, Oy,*y L9y,y #y,hrr,J0Pjqk>Xs2( ss-( s<-( s[-]yRQkhy}-X hy-yX Qy-ahrnr-Zkk|VXc [gc#,gc#,kkrc__n tTll|Vi %n@ l-n-#n-kX Jlk-k-Xc"lgcgc<$mKmn#.^l| qkl m mT@m)m m<Em2smlp dslN.t m.4 ZMC/t'm/4' ZMCL0t*Bn04* ZMC`1t-n14- ZMCg2t0n240 ZMCa3t3o343 ZMC3SY MoSSN4jSooS4S4{S oS,5SD5SoS5S5S pS6S-6S LpS6S6W,pfv4I, #pIv4KL2 #dL 7ZL87B+8RugWB:qfvIB #qIvKLH #dLK7ZLx7X+8RugWXqfvIX #xqIvKL^ #dL7ZL7n+8RugWn(rfvIn #qIvKLt #dL7ZL7+8RugWrfvI #frIvKL #dL 8ZL88+8RugWfvI #rIvKL #dLK8ZLx8+8Rug%| { { AsVs mH%+eszs H%Vs Rszes2s izAs8S sS8S82S7( $tS 9S89CST@ WtS`9S9`SeX tS9S9qSýtS:SQ:Sp tSy:S:W guf:KL #JudL:ZL;P+8RugI #I:W uf=;I #uI=;KL #dL_;ZL;`+8RugW Uvf;I #vI;KL #dL;ZL;p+8RugW (vf<I  #vI<KL@ #dL#<ZLE<+8RugWXCwfc<I # wIc<KLp #dL<ZL<+8RugWwf<I #wI<KL% #dL<ZL =+8RugW1xfv4I #wIv4KL #dL'=ZLT=+8RugWxfvI #oxIvKL #dLg=ZL=+8RugWyfvI #xIvKL #dL=ZL=+8RugWyfvI #]yIvKL #dL=ZL>+8RugW zfvI #yIvKL #dL'>ZLT>+8RugWfvI #GzIvKL  #dLg>ZL>+8Rug7{ "{ Vs0(zzesJR{ k$`@z{lo+l>ko'k>o'k>koXz{#k>jo$j>j?MkX\k? /{3|Vii %Sj %1?8lj `lUlJl#d/,d,d;!/K||AAip %Sq %D?8lq `lUlJl#d/,d,d||%:!L|}AA$$ }>3# y$$(3z&zzW?|0 |?As`s`"P$}}AAWi &'?dW ,d?,d?v@~9 ^?YsvpY0~Y@T` ~+TI` I@V V+ VF TxeYC@xYxYa@Y@Y# Y@=<TpTTTTTTVP 9= ^fmt= 'mUP> @D %O+F %"A7Z e TZBAHZoA | 7Z K LTZAHZA | Z! E vZA!| Z!E *ZB%!}  } {  { !%} 5!YG!?} `!O} h!{ p!> ?CW?!p!_} !w} ]H!>\CW!p!_} !w} ]HO!VCW| Z" ZBZGB&"{ "p2"{ @"w} 1:P"|p gq H[BBr HzB"`f"q 1`B_f"|_BTq"}+TBIq" IB<`s"r _K`C_s" &_:CT"+ToCI" IoC"{ "{ "{ #{ 1:-dP@#̃>[G P;8i &'Chd`# (wdCwdCd# RdCdC#` ##`~C#2#DŽKA#x#x H#xD|=Do[DxD#xD=D[DxD#} Ņ-9 'd@#ԆT"$ /+TDI"$ IDWp$# fvIp$ #nIvKLy$ #dLWZLD$+8Rw"$K$} Y$w} e$} ${ $9strr 9.s7s 6t$s [E4$ ZMCEI$t {I%Eitu 9E$u чŊEI$ rIE$v EZ$ ZE$ u -*E$@u MFX%Xw X,FXXXUFI% /ʈII% II% -INN% 2NFNFIS% 3(IIS% -I!O[%p 3:OF0OF%:O G0OGJ% ՊJN% NN2GC%%!#fI% #IKL% #dLKGZLxG%+8Rug$%{ 1,%O p7y2 'X 'GP% PPG%R$%T[ HP% PGPG'&R$tI*& FII H7&} &s<J&PPJ& PPAHY&R$8 V;up&U΋L&$AP&U ps&pT&}cp&%| O ^sH%L)E&WŌ^X-& g-`H' '{  0'gG P;\'z'''7EI(' `nn\;g,' [' -0[&[sH%' ׍W'i&' W (j$&( 7OW+(QC&0( gWK(7Rb&P( Wk(R&p( ǎߎW(R&( W("S&( '?W(]S&( WoW(S&( W )S') ϏW+)T;'0)WC[0)R[#$Z'P)+WW][P)l[#$y'p)OoWs)tHs)@sH)sHw[)E[H)Zg)j')TWs)sH)s Iw[)Ez[ I*Zg)jƑ>XiJ %SK%' *2ޑ~Wi %-*"-I-*"OI8l/*K`lUlJliId6*/,d,dvy`*͓yyI{*8y8y8yIXyIxyIyIm+ BmJm+  lmX:3 3+X>XaO:3 }lO+XC3{ Q3O/3f`3MȦbo3LbIb36T3ETI3 6II3 II3 -IE٦o %R7Ȧ!3 $٦`3>[[:P %X7qT %d7`y3 q{3!֧:P %j7 41,:P %<4H4$`4J{%j4 1j0jRX4~ u4~ 4Ƨ4ΨT4`+TI4 Iا4#%uAc%S4dSS415zptru5E %x 5(ĩ/5E %l%k>5*P5!ީ/[_5 &H]_5 ]/]eXl5~ T̀5+IǪ[5nӱ]5Ԃ]zX]XjS5SzX|SX5~ rڰ5B[5,%X;❫n]5]X]>YjS5SX|S>Y5~ S5 SSY56[Y6YI6 II6 -I̟ 6 5|[ 6 a3H]&6 ^'06[6T06(ETI06 6II06 II06 -I6@P6N,f[I %iYp6~ 6Ǫ_6'Tsrcd'Y$e?DYHf*YT6`+TYI6 IYY6g#Y/Z^07y,^NZ"^aZ07 3NZaZaO07 }lONZ<7{ G7O^Z7a,^"^ZZ7 3Zl7O6 6* O7H c6MTa@M1e7= 2cwdn=_'7Xo1@Z6'[Wc8@ fuIc8x #IuKLf8 #dLw[ZL[8+8Ru_77fW7of[I7 #oI[KL 8 #dL\ZLO\+8+8Ru_W@8#o!f\I@8 #I\KLI8 #dL\ZL\X8+8Ru_7] 7a8{ t'%O'8iy[n&H\'8@@]6}]WY9@/f]IY98 #I]KL[9P #dL^ZL-^s9+8Ruc88fW8hf@^I8 #~I@^KL8 #dLx^ZL^(9+8Ruc}9 ^^ 9W@9]f_I@9 #$I_KLF9 #dL#_ZLP_S9+8Ruc8ĩ859{ 9ŶzX9zͳc_9'9 @6_99fS9cTL`S`S9JSL`S`9ˆ9(ӈ`W9H;f(aI9h #I(aKL9 #dLzaZLa:+8Ru_ˆ9ӈaW9;faI9 #OIaKL9 #dLbZLLb':+8Rvˆ6:ӈbW6:;fbI6: #IbKL<: #dLbZLbH:+8Ru_ˆS:ӈbWS:;fbIS: #uIbKLV:( #dLbZL!ck:+8Ru_9OQ:{ מp:.߶[@ۺ&H4cdir6Xt:h\_c4:h ZMC_c[:[cT:N+TcI: IcS:SdSKd:W:\fdI: ##IdKL: #dLdZLdP;+8Ru_': @d6-eWr;@fleIr; #¸IleKLw; #dLeZLe;+8Rud::fW:(feI:H #JIeKL:` #dLeZL7f8;+8Rud^; ܹ,^uf"^f; 3uff(;OWT;SffIT; #IfKLZ; #dLfZLff;+8Ru_W;ʺfudI; #IudKL; #dLgZL;g;+8Ru_:ĩ:o;{ U;N[Y;W.YNgAA; XhgAgZAgPANg;';xX@g6(hWc<@fhIc< #ϻIhKLe< #dLhZLh}<+8Ruc;;fW;XfhI; #XIhKL; #dLiZLGi8<+8Ruc}< Xeii<WE<X9fiIE< #IiKLK< #dLiZLiX<+8Ruc;|a<{ /<i?[487XY<4Yjˆ=08CӈDjW=P;fXjI=p # IXjKL = #dLjZLjh=+8Ru_ˆ'=)9׾ӈjW'=);fjI'= #IjKL-=# #dLjZLj@=+8RuTˆl=!9kӈkWl=!;fkIl= #0IkKLr= #dLkZL,k=+8RuT=ӈudW=;fudI= #IudKL= #dL?kZLlk=+8Ru_<|<Ǫ<=Ŷ=NY=={ w=Y[w'@x\FX=xkk.A= y 3Al)AlaO= lOl={ =h>fumI> #XIumKL>  #dLmZLm>+8Ru_=8fmI=X #ImKL=p #dLonZLn>+8Ru_Y'>{%YnAA5>{^gAoZA=oPAnA>'C>{ @io6oW;?@fuI;? #IuKLC? #dLoZLoP?+8Ru_L>U>fWU>{fpIU> #JIpKL^> #dL&pZLHp>+8Ru_Wc>}ffpIc>8 #IfpKLi>X #dLpZLp>+8Rv}>p})pp>>#fpI> #aIpKL> #dLqZLqW ?}f-qI ? #I-qKL? #dLBqZLWq ?+8Ru_W$?{vfjqI$? #=IjqKL*? #dLqZLq7?+8Ru_= >oW>{ "`?H%1(Wp?D?x ?x ? ?Aistr'rei?)lߕh? 1:^x@AG^S^#@`^+@!S^qG^q+@!`^hD@ u !'%9(gn4?*BgJ__c '%TiMSH%B8`@T^n@^^n@qv@5a4 *}@ q@$R@ RrR$r@.RBrRVr@E@5ir@<@<^@@| @w} SWA,WDA &A 9]0A]D ^5|r_?Dra&'r=?b&'rm\FMAWA iA A AAH AB\FfD !H%vD1AG! <\FA( s( sZBA [VZ=sB~ 'BH C'Qs-B ~ B!efIB #,IKLB #dLosZLsB+8RugAw} A: AU 'B6B` 1 sWABx 4&fsIAB #IsKLDB #dLsZLtB+8RugABk [B{ B{ KB+fB'[B+C'kCO)7>2C\>/t7C?NtڥmtΥt7C?mtt7C?>7C?~?mt ?ta;C gutW;C ]ftKL;C #dLtZLulC+8RHIWC #ItvC4uvCSuouvC~CϤäu~CMuC{ C{ C'#FNF[N&'osOp7,S5nT5X_5CFnF[n&'osop7C!puuu!@QCQ4Qu*QuD<PDQPXPvDR$"D7r&vP1D]5PMvPevCDR$1DFQPuR0VDFPuR ? PYDbPxvPvkDR$DFPuR0>-Dos::^D@G^vTDX+TvID Iv^D<^'w6TDMET]wID 6I]wID I]wID -I]wPD !<PwPwaOD'lOxD{ E PxP3xPE8!PFxPZxcPE zPFxnPmxEDR$PD<PxPxER$PE<PxPx1ER$P1E?qP%yPCyaO1E flO%y9E{ DER$PDE?PayPyVER$PVEP!@}PyPyaOaE lOyjE{ FrPyP zPFh!PzP1zcP F fzPznPDzFuER$^xE!@^^xE!qXzzE!5Z4z*zE!  z$F$RE! R{R2{E0RP{Rd{EEE5w{E<E<E=28 S0F;9c4FTHcHcig$PFR ii{Fji{i{^FL_F| F{ hF!Ohh{tF@H%Z[W"@_f{I #&I{KL% " #dL|ZL/|Y+8Ro|L-@LM|EHH%+__m8%5Lv  H%+LD2LMH%+2LSIT6_7.FpIF8":l|ωF`"މ|FGx"k|G"#?'|\GVM^G"#?JyMeM+}zGM~H#?AM-MVG"{}}G#cĉ}GtG c}4G ZMC}L3H#L ~JHHhHtH>H8#dW~ML~{HP#l~~=RHh#$҂LR~VR~h#eR~F%| RH{ ZH{ !]!X!]!kX5H.MH%+ML aH%+LќkHz/k %#ssl4 ~H#l~ωH#މgHH#H$#?g'FIVMFI@$#?yMeMyIMK##?AM-Mu~I`$M=]I$c ĉ]Jt(J$c4(J$ ZMCLK%sLKWJKK2YJm[KA/jJkQjJ!R~RRkjJ.RQjJ!VQԁQ?PjJ!`VPԁJP2pJm"KA pJ k|QpJ!mQGQkpJQkMQpJ!EdQGXQPpJ!\2PG&PkJ$nL J@J$n.J%5$WJ%@fIJ #IKLJ0% #dLEZLw{K+8Ru~|LJ@LJRJN5uaLJH%#;oML݃MKh%#;AM-ML>K5L%YKJ=KK{ K{ Lzms %ss 4 ~L% IωL%dމWL}L(& ل}LP&#?'لLVMLx&#?yMeMMMgO##?AM-Mu~'M&Zz'M&c[ĉzMtM&cυ4M& ZMCυLO%L6OMOObOlM mL mM7=N' : 6N@N' .e,N8'5W;NP'@fÇI;N #IÇKLDNh' #dLZL'N+8Ru~|LPN@LEmNRmNN5uaiLN#;]MLMN#;AM-MLN5LՈN7O'O{ ?O{ cLD  dO*/d %'sse4 ~O'eωO'މAOO'+O((#?'>PVM@P3#?yMeMsPMjS#?AM-M PH(#7Px(cyĉ7Qt"Q(c4"Q( ZMCLES%LՊbSQQ/SBSQQ(fcQ($1F(d΂cQ) ݂FR() p4y*RH) S$RRh) RR8)R}RREqQ)fqtRqQ)$RRF)RfQ)g Q@Q*g.ōQ *5sWQ8*@Qf)IQ #I)KLQP* #dL[ZLR+8Ru~|LQ@LRRRH5uaώL'R#;MLMCR#;AM-MLYR5L;tRQ=SS{ jS{ rS( /r5%h* sss4 ~S*s._ωS*މSS*_S(+#? 'GTVMIT3#?<yMeM|TMW#?AM-MsTH+Tx+cĉUt+U+c4+U+ ZMCLuW%L;WZU_WrWZU+tEQhyU+$,ʑ΂yU0, ݂VP, p4ߑ*Vp, 7W$RV, R|R,RRVEU,t'KtRU,$R}R,R̓QU-u4Q*QU<2U(-tKAHUzQU!RRRzU.RϔQU!VQQ?PU!`VPJPϔ2UtqKAU z|QU!mQLQzUQpMQU!EdQLXQPU!\2PL&PpU@-v U@UX-v.Ux-5sW V-@Qf!I V #I!KLV- #dLSZLW+8Ru~|L!V@L>VR>VH5uaǖLJV-#;MLMpV#;AM-MLV5L3VGWOW{ W{ /c<-@WW-@fI #IKL%. #dLZLa+8Ro|L-@LDL{ ',e_pݐFkH W5(.fI5 #IKL;@. #dL;ZLui+8R_(ŝL{  _)_58k/<T-,}+TI- IA0X.,3Aܘ)AaO0 lOܘ6{ ChWCp.,SfIC. #IKLL. #dLUZLh+8Ructz +4z ZMCW,fudI #IudKL #dLϙZL+8Ruc-y]z%| { Katp@7p(H%<k;KUa8.p? FHU WK.rfYIK #9IYKLV. #dLyZL+8RugW!fuTI #IuTKL #dLٚZL+8Rug(ŝi{ { -e /.A# y 3A)A[aO# lO+{ 6hGfuIG #IuKLL #dLZL\+8Rug#e{ ,!!'%9(MK%'% /NI%@@%hB%ǛM1%yaO@/%lO "{ t%`/%*54%`/ ZMC5I4%JIaifIi #IKLn #dLZL~+8Rug@OhX{ W_zCx/TstrX^(X/`vi/^,X/vi/uX/yם/.A~X/ y 3AE)AmXh7YqfI7Y0 #8IKL9Y0 #dLZLΞQY+8Ru[~XWX00fIXP0 #IKLXh0 #dLZL!0Y+8Ru[WXif?IX #0I?KLX #dLTZLiX+8Rw^X0v|i0^X0vi0ԟ^X0v(i<0^Y0IvTih0WSYfISY #IKLYY #dLZL fY+8Ru[WfY69fՠIfY #IՠKLlY0 #dLZLyY+8Ru[WcXuX Y{ Y strM( %*0O4 ~1ki %y01&C~aZX1kaΡaIZ `IΡIZ IΡIZ -IΡ6ZR$W6Zx1fKI6Z1 #IKKLBZ1 #dLoZLXZ+8Ru~W[_fu~I[ #%Iu~KL[ #dLʢZL[+8Ru~ZqZ1. Z15C>WZ2@!fpIZ #IpKLZ 2 #dLZLԣo[+8Ru~|LZ@LZRZB5uaLZ#;ML:M[#;AM-M^L[5L6[YqZXY[,[[{ AxxM(x&'msgyY5iz&'+[\=6_x=[82J[ JI[ -I[P22%Ӥ P24:[p2|ZZP|p2b~a[2aZaI[ IZI[ IZI[ -IZ\R$W\2|KfI\2 #IKL\2 #dL֥ZL\+8Ruc%bH\2Eb;b2bPK\3Q*P>i\R$W\|&fudI\ #IudKL\ #dLaZL\+8Ruc[_\{ k5\ZzCM(\_ ] ]v6_CM(:B]03qZP03b~aB]H3aaBIB] dIIB] IIB] -IV]R$WV]h3fZIV]3 #IZKL_]3 #dLZLҧx]+8RusW]afutI] #(IutKL] #dLZL=]+8RusB]B]{ ]r 6_C(:]3mZPP3b~a]3aPaI] `IPI] IPI] -IP]R$W]3f I]4 #I KL](4 #dLEZL^+8RusW^] futI^ #$ IutKL^ #dLZL)^+8Rus]B2^{ @^1<%<%c<%osp7@Pp^ PPϫP^@4 PP^R$P^: P P%P^c P8PPP^ PcP{P^ PPP^ PPѬP_ PPP_0 PP'P _Y P:PR0_x e~a^_X4 aa׭I^_ II^_ II^_ -Il_R$Wl_x4z fIl_4 #A IKLo_4 #dL$ZL9_+8Ru_W_4 fWI_ # IWKL_4 #dLlZL_+8RwP_$ QPʮ_R$W_ fݮI_5 #b IݮKL_5 #dLZL_+8Ru_W_%f2I_ # I2KL_ #dLGZLt_+8Ru_K_]_ `{ -`gc<%osp7گP)`P-PE;`R$PX`PPfj`R$Q`r G`̽'%R)'len&'osp7`@4H%P`PP`R$`tS&'1`Vcur'gP`05 PP`R$` "` P` VPܱPaR$a  a1PuRwP#aPP92aR$l̽'%R)'len&'osp7@a`R)+'Xlen+&'os+p7\aH5,lزPsa'PPaR$saaR1aqs6'9os6p7da :6ac=Pa:jPͳPaR$Pa8PP bR$ac~ a b_sX_osXp7I bp5YJII b5 II b5 -I6b1istr&'os&p7\-IT'/&O5 ss&P4 ~5&P+ω6މs5;06;`6#?o'VM'#?yMeMM#?AM-Mu~6ULl6cĉlytc4 ZMCL%{Ld6&Qo|.ojx6&Bܶ6N6&fYܶ&6&X<1ܶW6&f I7 #I KL07 #dL-ZLQ++8Ru~P &PoPR$WD&hfID #.IKLM #dLZL`+8Ru~H7&R @`7&R.'C75qYWR7@OfIR #IKL[7 #dLZL+8Ru~|Lg@L R<5ua1L#;MLUM#;AM-MyL5Lnv{ { 6@b̽<%R)M(len&'osp7^b@4H%kP^bPPqbR$qbS&'7curS(̺Pxb7 APPbR$b!b!b Pb P@PXbR$b1RwPbPPkcR$ 8̽<%R)M(len&'osp73caR)1M(len1&'os1p7,c82+Ի PAc'P4PLScR$Ac#qc#R1ScqsGM(kosGp7c Kgcc=PcKPPcR$PcIPP*cR$c,c#ndsdIosdp7Md08e{MIJdH8 JIId`8 -IId#k5str&M(os&p7}-+$ITM(/&O$x8$ss&P4 ~8&P]ω8Kމ5;8; 9#?'VM'#?yMeMM#?AM-M~@9̾`9cAĉ̾gtc;4 ZMC;L%LĿy9&QN#ڿ0*9&r Is<99&s 9&Xs]9&!l.J9 # J.I -I.JN: #cNyYN(:cNYN'L@: !>L2L |!>LS2LhK RKSKhK@ T L}K@L>"P&!PPR$]X:&G#lJ #S"JI -IJNp: #cN6YNZ6cNu~YN'L: :#>L2L#>L2LK RKKK  T LKp  LR":&Rx# @:&R$.0:5P$QW?:@.$fI? ##IKLH; #dLZL +8Ru~|LT@LqRq<5$ua)L#;$MLMM#;AM-MqL5L{ { ( d)str[ '(;)\ t4dH;\ %44dH; ZMC`;)ch^ '%Xd;g 'XX;XId /%&IId IId -INd 2O&NN"Id 3&IId -I!Od; 3':O:0OZpe:O0OJse &JN}e NNdWe;d 'fIe; #S'IKL e; #dL ZL,he+8Ru_W(e<d (fJI(e #'IJKL.e < #dL_ZLt@e+8RvWed |(fIe #C(IKLe #dLZLe+8Ru_Wed (fIe #(IKLe #dLZLe+8Ru_d* e ee#|)fIe #C)IKLe #dL1ZL^e+8Ru_Kdc~ Yde{ f!Z*!'%9(MK P * Q *8<*M1 S <u*fuI< #<*IuKLA #dLqZLQ+8Rug +Z{ !+!'%9(MK + '%NI M1 *f8ea02@a02Rf0P<V0dir7Teĩ+6TeoETIe 6I*fp<`,**9p<*Ng!N,fu`INg< #,Iu`KLQg< #dLZLjg+8Rud f-f'Af<-@6Wf@,fIf< #,IKLf< #dLZLg+8Ru[JfRffWRf=LJ-fIRf0= #N-IKLUfH= #dLZL.f+8Ru[Wefh=-fLIef #-ILKLkf= #dLZLf+8RuTˆof=ǒ.ӈWof=;fIof #W.IKLuf= #dLZL@f+8RuT}f.^~fˆfS/ӈWf;fIf #/IKLf #dLZLf+8Ru[Wg/fIg #/IKLg #dLZL3$g+8Ru[W$g*A0fFI$g #0IFKL*g$ #dL[ZL6g+8Ru[f@f)f{ 55pg4343r93=)3Q\FXWg>11fIg #0IKLg(> #dLZL(h+8Rudg)1Qyg).Ag@> y 13A)AghgWhX>2fIhp> #1IKLh> #dLZL"h+8Ru_W #2IKL\h> #dLZLqh+8Ru_gy]gh)Wh{ 1_5q35%5%c5%osp7t;5%5%c5%osp7>i;P>3PP1R$>33?8e3C[3PPY4PPbR$P4PPR$P 4P1PIR$P 4P\PtR$P( %5PP:R$PH X5PPZR$Ph 5PPzR$P 5PP R$P 5P3PKR$P $6P^PvR$C6~a @?6aaI  6II  II  -I.R$W.`?E7f.I.? # 7I.KL1? #dLNZL+8R[WE?7fIE #7IKLK? #dLZL+8RDP7QP%R$WEg8f8IE? #.8I8KLH@ #dLLZLy`+8R[Wc8fIc #8IKLi #dLZL Ph@29PP vR$R$aR$$R$Pv@@o9PwPR$~R$P9PPR$P`@9P*PRR$~ax@\:a|aI Q:I|I I|I -I|R$W@:fI@ #:IKL #dLZL+8R[WxJ;fIx #;IKL~ #dLZL+8R[==v{ h#;c5%osp7hq3;5%.%c.%osp7KC5%.%c.%osp7@CPn<PP#,R$;.@QA;;PP<PPbR$P<PPR$P /=PPR$P b=PP*R$P( =P=PU:R$PH =PhPZR$Ph =PPzR$P .>PPR$P a>PPR$P >PP,R$>?~a(A>?aaI( 3?II( II( -I6R$W68A?f9I6XA #|?I9KL9pA #dLYZL +8R[WMA-@fIM #?IKLSA #dLZL+8RDP`@QP<,R$W[@fOI[A #@IOKL^A #dLcZLv+8R[WyaOR NlO[{ jhWjE,NfRIj8E #cNIRKLsPE #dLZL+8Ru_t +N4 ZMCW,\OfI ##OIKL #dLZL;+8Ru_Oy]%| {+ON*i{+U9iNqG{+GpGNŝ+Pu`*iU9iu`qG {  [[P{TITP_/{Tf&hEQ|hEb^&P^P)EPP'aO7EQlObC{ EQPuPPTEPPcP QzPnPQR$QFS$Tn,R+TMIn IMAq F,cR3A)AaOq XRlOw{ hW8F,RfIXF #RIKLpF #dL ZL<+8Ru_t F+#SZ4 F ZMCZW1,SfI1 #bSIKL7 #dLZLG+8Ru_ny] %| !+%T*i+U9iqG+GGŝGjTu`*iGU9iu`SqG&[{ ` TWIT3_/W FT0Fb11FWhTL,cU+TIL IAOF,U3A)A^aOO UlOX{ ghWgF,9VfrIgG #VIrKLp(G #dLZL+8Ru_t +V4 ZMCW,VfI #VIKL #dL.ZL[+8Ru_Ly]%| x+Wn*ix+U9inqGx+GGnŝWu`*iU9iu`qG { 80 W XIT/_/ X_5-3Xos3Xsb8X2_5X SXkXIT?_/kX  XXITL_/X\ik''' dkTe?qfk@Gkjg\Fmsgj/rtkfipGlY|;pGbiP:iGl>ZZPGb~aiGaaIi 1ZIIi IIi -IiR$iGlZLGbiPfiGmZ|EGbjPajHm[aaHb'j='j HmB[/ HbEjPPjl\in %xcj8Ho[8HbPrjXHPPjR$jxHo\xHbjcjijWjHq`WWRjH*^HbXjH'X2X~a kI+]aaI k ]II k II k -IkR$Wk I]f6Ik@I #i]I6KLkXI #dLvZLl+8RuWDp ^fIDpxI #]IKLGpI #dLZL_p+8Ru ky]2kIH`NTOk,^+TIOk IARkI,^3A)AaORk ^lOXk{ ekhWekI,g_fIekJ #,_IKLnkJ #dLPZLm+8Rutm0J+_4m0J ZMCWp,)`fIp #_IKLp #dLZLp+8RuOky]m%| #mwkHJ`*iwk`JU9iqGwkxJGGkŝdp`2*idpU9i2qpqGj)kqEa;Hk]k)-pqa;r-p:p)kJ|a;kJnkJjb*ikJU9ikqGWkKbfIk K #UbIKLk8K #dLQZLl+8Ru)slPKvb;slhKltIl{ cII;l} =XmmK|kf]XOSXwmKc0&KbPmKPP4mR$mKeeTm,c+TIm IAmL,]d3A)AXaOm0L RdlOm{ mhWmHL,dflImhL #dIlKLmL #dLZLo+8RuXWo,MefIo #eIKLo #dLZLo+8RuXto+e#4o ZMC#my]o%| om+fN*im+U9iNqGm+G}GN nŝodf*ioU9ioqGmpX2nL}iXXb@nLf5xmLbP@nLP5PXnR$XnMiTun,`g+T1Iun I1Axn8M,g3AS)AaOxnPM glOSn{ nhWnhM,6hfInM #gIKLnM #dLZLo+8RuXt#o+~h4#o ZMCWo,hfIo #hIKLo #dLZLIo+8RuXuny]!o%| 5on+i\*in+U9i\qGn+GqG\nŝ?oi*i?oU9iLoqG@n)Oo|j;Oo]o`ojWj*i`oU9imoqGWpojfIpo #jIKLvo #dLZL7o+8Ru) p!vk;J p!_pKibisiij&Vkki'l&V8lGPŝxpud*ixU9iudqG <y]{ :-p;6u[ %R '¿ 'pO 7ruO.Ap0O y q3A )AEphlq/rfIlqHO #rIKLoq`O #dLZL ppxO AsxO.ApO y r3Ai)A aOp rlOiq{ qhq9sfuPIqO #sIuPKLqO #dLR ZL q+8Ru_pWqO sf IqP #sI KLqP #dL ZL Hq+8Ru_W"q8P 1tfN I"qPP #sIN KL(qhP #dLp ZL _q+8RwW|q# tf I|q #ptI KLq #dL ZL q+8Ru_Wq  !uf Iq #tI KLq #dL ZL- q+8Ru_poq{ &qNuKwCWٖ KwP@wE \Flc/PV/R$ŝMeŝ2:{ GO{ *LttuAOylenS%H;=yD:LV`\%ei/PD\PP|/P_R$P_\Q P/PsR$Y~\SxY/I~\ I/I~\ -I/P\VP/PR$~a\W0a0aI %I0I I0I -I0R$P]WdP-0PE0R$~a8]Wad0aI Id0I Id0I -Id0R$&ŝD{ +<3{ D{ Id*2<%:?<IP]'Uy0PZh]<УP&PqR$Pq]<P0PR$ۀ Z=+ { ˘Kf*2H%<84K])W0PR]HҤPUPjR$Pj]HP0P|R$! R={ CChhH%y%24u;C]0Y1PJ^y٥PPbR$Pb ^y P/1PtR$ J}={ c+ũIE %V7)7R)7 %end7 %v8&; 8^9%G1dP^9٦,d~1,d~1P]h^: P1PuR$Pu^;9P1PR$P^;mP2P2R$P^:P12PI2R$NsIC %\2^.D%ߦE%2ӨP3PR$P8_>P03PH3R$PP_?;P[3Ps3R$8ŝ]==ŝj===P#{ +{ "P1ݩLAAV )72f Q3Ddg M@,d,d|;LdH]l3QaÁh_`a3`a3_ i&'4Qa߁_`a:4`a:4ũ;܁;m-8t%T-PD_aPP4P[R$P[_bPx4PrR$&ŝDzU { S Ѯt_0r ?@Nv C@z %4<5 C@4ӂ/ N U Pb`o P4PzR$Pz0`p P4PR$Pƃ} P5PރR$~a0H` a)5a>5I0 I)5I0 I)5I0 -I)5@R$~aOh` 5aQ5af5IO *IQ5IO IQ5IO -IQ5_R$Fŝx , b ƃP0POPg{ { { CH%%Ѯst}!Jy5`5P^`P5PuR$Pu`P5PR$>́ ^=:a:5H8 6%686[H{%6o86H$:H~D:%68:K6:`gNv6`]v6W`f6KL` #dL6ZL 7+8RuPI #I6*7߯B7d7 ͯw77 Mw77{ :$Y:7-5<777[-5{7o7-5$:-5~D:78:W:1$gN81$]8W1$f"8KL1a #dLD8ZLY8R+8RuPI= #I"8bl8߯b8Vbfͯ88fM88o{  }{ 6@H%%aR.{8(a'8PjHa´PPR$P`aP9PR$;́ j= { ֶ& %strֶ:xa˶end*Xf%L/9%9 %96T=ET9I 6I9I I9I -I9$]:PPPPR$4~ L>nŝŝ{ 1fd %*Y,%fd{ %lb{'O{!P}P':PR$Pa}_PO:PaO! lOm:*{ aTP:PP5aP:P:cPR HzP:nP:_5R$P8~P:PJR$۶baD:;tr ;;4r ZMC;;bDm;^b-,^;"^;b 3;;aO8b }lO;O w} : !U W{9fvI{ #IvKL #dLuLZL;+8RuDo S`%| qy{ { { )Ԇ) ̺tH%&r%̺(XbK-;PPpbaUP;PgR$PgbbP2<P~R$2ŝPU WbI$fJ<Ib #IJ<KLb #dL<ZL<+8RudWbIf =I #cI =KLc #dLQ=ZL=+8RudWI fI(c #ӼIKL@c #dL=ZL=+8RucWI|fI #CIKL #dL=ZL >+8Ruc%{ 5c̺XcLN̺ >(pcKq->>PPcaP\>PgR$PgcbJP>P~R$2ŝPU WcIf>Ic #I>KLc #dL>ZL>+8RudWdIaf?I #(I?KL(d #dL=?ZLl?+8RudWIٿfv I@d #Iv KLXd #dL?ZL?+8RucWIfvI #IvKL #dL?ZL?*+8Ruc{ 5{ ,rhu%DV=Bc'pdr @d~@@Pdu1PPR$PduaPt@PЇR$/$ އ=<@C<R@$<}3@Q7@֡Q@Q}ơ@{ * ^,4d!C@dYNAPZdyPPrR$PreyPwAPR$, Z={  :H<(e'A4"@eCA@eYBPjXeyPPR$PpeyP7BPR$+ j=={ { 0.Nc\H%%rlpB<vNsl"e.lOBc"e|rOB^e̺B^eL̺BoeK-BPea{PBPR$PfbPBPR$yŝU UW fIJfCI8f #ICKLPf #dL2CZLTC@+8RudWpfIfrCI #IrCKLf #dLCZLC0+8RudWXI:fv IXf #Iv KL[f #dLCZLDp+8RucWpIfvIp #uIvKLv #dLDZLAD+8Ruc{ 7ŝ{  HLfTDcWfrD g~DP@gupPEPR$P`guP6EP؈R$d$ =J%| {  { uXuA<;0xg=*NExg.A+$ y 3A)AE=h"f-FI #I-FKL #dLBFZLoF+8Rud+=Og=VFLFgeGPgPP*GPR$PgQPbGPR$YgSYzGI IzGI -IzGPhVKPGPR$~a0hWaGaI IGI IGI -IGR$PPhWPGPH(R$~a(phWa!HaI( I!HI( I!HI( -I!H8R$aŝ AWDh=Af6HID #I6HKLJh #dLrHZLHx+8RudW'=fHI #IHKL! #dLHZLI+8Ru[juT{ \ٖ\[\!IT+TeII IeI.hIIh.A:h y 3ARJ)ApJaO: lORJB{ Mh:5Nh*NJDDK[W[ifKI[(i #iIKKL^@i #dLKZLL+8Ru_Wn`ifCLInxi #ICLKLti #dLeLZLL+8RvWfLIi #YILKLi #dLLZLL+8Ru_W fu`I #Iu`KL #dLLZL%M+8Ru_.{ uHH8\V|i8MKMD5WiNMDMbWbj1f*NIb(j #I*NKLe@j #dLbNZLN+8Ru_Wx`jfNIxxj #pINKL~j #dLNZLO+8RvƅՅOWAfTOIj #ITOKLj #dLiOZLO+8Ru_Wfu`I #Iu`KL #dLOZLO+8Ru_"WW { ]Hq]~\jU~js'O^^P6TMETmPI 6ImPI ImPI -ImPsjP*Qj.Ak y %3AQ)A Rh(5fRI(8k #]IRKL+Pk #dLRZLRD+8RudhkSOShk.Ak y 3AS)A5ThLxfTIk #?ITKLk #dLTZLU+8Rud5kN$UDUWk,fUIl #IUKL(l #dL=VZL{Vh+8RuCWHlfVI`l #kIVKLxl #dLVZLV+8RwWlf WIl #I WKLl #dL+WZLMW+8RwWlfkWIl #[IkWKLm #dLWZLW+8RwW m fWI8m #IWKLPm #dLWZLX+8RwW$hmf/XI$m #KI/XKL*m #dLQXZLsX+8RwW2mfXI2m #IXKL8m #dLXZLX+8RwW@mtfXI@n #;IXKLF(n #dLYZL7Y+8RwW.fUYI.@n #IUYKL1Xn #dLjYZLYF+8RuCWFdfYIF #+IYKLL #dLYZLYX+8RuCWXfYIX #IYKL^ #dLZZLAZj+8RuCWjTfTZIj #ITZKLp #dLiZZLZ|+8RuCW|fZI| #IZKL #dLZZLZ+8RuCWDfZI # IZKL #dL[ZL@[+8RuCWfS[I #IS[KL #dLh[ZL[+8RuCW*6f[I #I[KL$ #dL[ZL[+8Ru7%Oo^%s )){ 8< N<pn.N[sln.l&\cn|r&\^n̺u\^nL̺u\onK-\PnaP\PR$PobP\PR$yŝU mW(oI`f]I@o #'I]KLXo #dL#]ZLE]X+8RudWxoIfc]I #Ic]KLo #dL]ZL]H+8RudWpIPfw Ipo #Iw KLso #dL]ZL]+8RucWIfwI #IwKL #dL^ZL2^+8Ruc{ 7ŝ{ { ̸ K Hp@olE^W7o0p^f1:7oI^p$U _P8p<Pe_PR$PPp<P_PĉR$Cۀ ω=؉NR Xhp_<XhpK_pW!`PpHPU`PR$PpHP}`P$R$j -=6cV{ k{ pN-(Hpl`WqCp`fD:qI`0q7U[aPPq<PaPR$Phq<PaPR$ۀ =( qa<qKbqWYbPJqHPbPbR$PbrHPbPtR$ J}={ { q,@hVhۋ8%^WrklnbW@rnpBcf:@rIBc`rUcPrr<8PcPR$Pr<hPdPR$ۀ r=1" (ro d<(rKXdrWdPڌsHPdPR$P sHAPePR$@ ڌ =F9{ N{ j%P^W8s~lfeWg`sfpef:g`sIesUePҍs<KP#fPR$Ps<{PKfPR$sۀ ҍ= sgcf<sKfsWfP:(tH$PgPRR$PR@tHTPFgPdR$ :m=v{ { H%pydH%[VH%aHĎ^gRЎfvg{gog#ЎfC7ЎfЎf~ gբԎXtggL`ԎXt]^`gWԎxtlf#hKLԎt #OdL_hZLh +8RuPI #I#hWtfhIt #IhKLt #dLhZL i#+8RuP6'iU6dz?inai6 : +Cti7i: MtiiC{ FiRiiܠiRRcR~w jBZugV6j]Zu]]6jWZ u/fnjKLZ8u #dLjZLj+8RuPI #InjWpPu/VfjIphu #IjKLvu #dLkZL>k+8RuPWzu/f\kIzu #I\kKLu #dL~kZLkӏ+8RuP(kŸџk۟k  l-lb Mq l{-l{ 4u=C@luY`lP2vyPPJR$PJ(vyPlP\R$ 2e=n{ -`e\e5(@vydNlD mƅ(hvՅQm+vmn+v=mv.ABv y P3A_n)AnThf(oIv #I(oKLw #dL=oZLjo+8RudB=fw=hV}oLoweoP8wP2P pPR$PXwQbP3pPR$YpwSYKpI IKpI -IKpPwVPzpPR$~awWrapaI gIpI IpI -Ip+R$P-wWPpPp?R$~a?wW.apaI? #IpI? IpI? -IpOR$xŝ X(W[x=fqI[x #IqKL^0x #dLPqZLq+8RudW=XfqIPx #IqKLhx #dLqZLq+8RuWuDWkxyf rIk #I rKLqx #dLHrZLr+8RudWyTfrI #IrKL #dLrZLr+8RuW({ ]Hq\ %54xNrD}sƅ4Յs:x5tt?y=u5ty.AN0y y 3A=u)Au`hf#vIHy #I#vKL`y #dL8vZLev+8RudN=rxy=VxvLvxyevPyPaPwPR$PyQP>wPR$YySYVwI IVwI -IVwPyVPwP'R$~a'zWawaI' IwI' IwI' -Iw7R$P9(zWPwPwKR$~aKHzW]awaIK RIwIK IwIK -Iw[R$ŝ d@Wg`z=fxIgxz #IxKLjz #dL[xZLx+8RudWC3=fxICz #NIxKLFz #dLxZLy[+8RuSuDWwz f'yIwz #I'yKL}{ #dLIyZLky+8RudW({fyI #JIyKL@{ #dLyZLz+8RudWfzI #IzKL #dL4zZLaz+8RuSWsftzI #:ItzKL  #dLzZLz,+8RuS$o4 5{ ]H \| aZ$pZzTw+T{I I{.X{0{{X{.A:x{ y 3A!|)AJ|aO: lO!|B{ Mhy(f|Iy{ #I|KL|{ #dL|ZL*}+8Rud:5M{N=}D}ƅM|yՅ ~U|u~ZP|=uP|.Agp| y 3AV)AyhW"xfvIW| #?IvKLZ| #dLZLo+8Rudg=|=VˁL|e^P|PPqPR$P|QPPR$Y}SqYI II -IP((}VPP@R$~a@H}W)a(aI@ I(I@ I(I@ -I(PR$PRh}W]P=PUdR$~ad}WahaId IhId IhId -IhtR$ŝ (}W}=f}I} #^I}KL} #dLƃZL+8RudW=f=I} #I=KL~ #dLRZL*+8RuSuDW ~fI8~ #ZIKLP~ #dLZLք+8RudWh~ fI #IKL~ #dL0ZLl+8RudW*fI* #JIKL0 #dLZL̅<+8RuSW<f߅I< #I߅KLB #dLZL!N+8RuS.W{ 1:y '  %~ \FTސ&4lސ&.A~ y 3A)AhW~Lf4I~ #I4KL #dLTZLv+8Ru[W!0fI! #IKL'H #dLZL؇+8RuTW+`= fI+ # IKL1 #dLZL:n+8RwW fXI #| IXKL #dLmZL+8Ru[Wő- fIő # IKLȑ #dLˆZL+8Ru[W& fI #l IKL #dLZLD+8Ru[Ɛݐo)TÑ{ /_f?'' 'X'Wmsg/\_$ __$( _T5+TˉI5 IˉfF3 |FbPF@PPM^R$ _aX )_p_Pix P P3aOi  lO r{ R$)__cP> xbPЀPxPR$ _ )_Ћ_(P  PWPjaO lOW{ ʒR$@)__PbՒ QxnjՒbPՒXPP܌R$ _p )_ _$PP9PMaOlO9{  R$  7}bP ȁP}P!R$$ ōbP$PōP<R$ _<  F)_L_tPJ@$PPΎaOJlOU{ hR$`)__&Pwx *iwU9iqGwG5Gŝ- ud*i-U9iud7qGFwy]?{ Z9E@kjU kI^W ^ITWX+TIW IZ؂  ŏ^~ B^6T~METI~ 6II~ II~ -I: ZHPb~a0aHaI IHI IHI -IHR$X h*RXbPpP*PՔR$ _Ք )__ǑPՔPP7aOՔ lOݔ{ R$ _Ѓ )__gP_PPaOTlOR$()__P @PP3R$/` V*i/xU9iVqG/GGVCŝW] fI] #PIKLc #dLZL*+8RvWĕ fhIĕ #IhKLʕ #dL}ZLڕ+8Ru_ Fu`*iU9iu`qG/y]{ 81NIy8p<W>؄BfI> # IKLA #dLZL$+8Ru_WT0fRITH #IRKLZ` #dLtZL+8RvW2fI #IKL #dLǕZL+8Ru_W–fu`I–x #qIu`KLŖ #dLZL4ݖ+8Ru_%PudRu 5>{ \jU  81l.(2(G2s sW)؅ fٖI) #IٖKL2 #dLZL7X+8RusW\ }futI\ #DIutKLb #dLUZLr+8RusPutRu _} )w} Dw} {{ oN'p'(CuA/\[.HX{ܗqHb@PMMbaPd`2Z`byP&bPlΘbP *i U9iqGud*iU9iudqG"MGPvRuTG8PvRuy]{ %''  %x%#/TbPPP;R$ _)_^_P×ІPəPܙaO× lOə̗{ ݗR$)__ vPbݗ(!xbPݗ(P!PYR$QPqgPbPpPPR$bPPP)(R$ _+Ї )_Y_P3t P͛PaO3 i lO͛<{ MR$)__P>M( ^%T(bPMHP%P]hR$hp\! pbPhPPŜR$G!g]bP؈PP-R$G""g]]bP P]PR$H"ŝHbPhPŝPȘR$Ș"-bPȘP-PeR$Tȉ$#+TIȉ IW #fўI #c#IўKL# #dL ZL8+8Ru[W68$fVI6 ##IVKL<P #dLZL+8RvA Y$ҟ*iA U9iҟLqGW$fIh #$IKL™ #dL ZL6ڙ+8Ru[WڙI%fIIڙ #%IIKL #dL^ZL+8Ru[#%*i#U9iqGy] J { 'IT,^'l R&llߠ bl ll,7=@&O*i@ȊU9iOqG@G|GOTŝ|'ud*i|U9iudqG @y]{ EH|8'/\|/m q'mm3 'm9Zg<'^t(J.A0 y 0(3Aݢ)A5h_(fuPI_P #h(IuPKLbh #dLZLw+8Ru\)2z.A y )3A)AHh5N)NʥD'W؋)fvI #)IvKL #dLȦZL(+8RuGW0>*f2IH #*I2KL` #dLTZLt?+8RwWx*fI #}*IKL #dLZL֧W+8RwW.+fI، #*IKL #dLZL8o+8RwW+fVI #m+IVKL8 #dLxZL+8RwW P,fI h #+IKL #dLڨZL+8RwW,fI #],IKL #dL/ZL\+8RuGW-foI #,IoKL #dLZL+8RuGW-fĩI #M-IĩKL #dL٩ZL+8RuGW-fI #-IKL #dL.ZL[ +8RuGW v.fnI  #=.InKL #dLZL+8RuGWD.fêI #.IêKL!> #dLتZL-+8RuG3%t )6{ 1:|4/7\ٖ7*y0 /9yy0 #y6h9ȍ/[q0E.A} y 003Aج)A0h_0fuPI_ #h0IuPKLb8 #dLZLw+8Ru\}P1-uP.Ah y 13A)ACh5N1NůD"W1fqIȎ #1IqKL #dLðZL(+8RuGW>2f-I #2I-KL0 #dLOZLo?+8RwWH2fI` #}2IKLx #dLZLѱW+8RwW.3fI #2IKL #dLZL3o+8RwW؏3fQI #m3IQKL #dLsZL+8RwW 4fI8 #3IKL P #dLղZL+8RwW4fIh #]4IKL #dL*ZLW+8RuGW5fjI #4IjKL #dLZL+8RuGW5fI #M5IKL #dLԳZL+8RuGW5fI #5IKL #dL)ZLV +8RuGW v6fiI  #=6IiKL #dL~ZL+8RuGWD6fI #6IKL!> #dLӴZL-+8RuG0%q )6{ uHC479CW| 9m' q7mm* 7mK0ZgZO 7ZiZc{ W G8fI #8IKLА #dL׵ZL0+8Ru[W4 8fu\I4 #8Iu\KL: #dLZLDJ+8Ru[LpkZg%{ Κw} { p#S{ 1:`379;CWٖ ;;E \FPW 9fWI #9IWKL8 #dLlZLX+8RuWW(X _:fI(p #%:IKL1 #dLZLɶA+8RuDW\ :fܶI\ #:IܶKLb #dLZLn+8Ru`Wy O;fu\Iy #;Iu\KL| #dL1ZL^+8RuW(qo;PuXɛp%{ (w} w{ uHE2;PBCWV( PB %EB6 %q@ % ͜- E<qPuTT- <+TI I"Б- <-3qPuDW/- ,=fQI/ #<IQKL2( #dLZL޸H+8Ru[WFH- =f IF` #k=I KLLx #dL.ZLOh+8RuDW0 >fmI #=ImKLȒ #dLZL+8Ru["4 P>-ϹНqPuTW4 >fI #>IKL #dL6ZL8+8RuD0D@Mf8 %"-: ?-ԺBqPuTRu@WSP: ?fISp #^?IKL\ #dL"ZLD+8RuDW: @fbI #?IbKL #dLwZL+8RuD-pS{ mvy{ Wu- @fIu #@IKL{ #dLZLɻW0 "AfܻI #@IܻKL #dLZL+8Ru[W- Afu\I #aAIu\KL #dLZLFП+8Ru[Ŝp͜O/{ h{%{ { p{ Wߎܞpw} *{ { ]H|mB'J\V'J %;ГBYl]sCȼ.A y ,C3A)Ah_CfuPI_( #dCIuPKLb@ #dLZLw+8Ru\XD@X.Ap y D3Aƿ)Ah5JDNDWDf<IД #DI<KL #dLZL(+8RuGW:EfI #EIKL8 #dLZL:?+8RwWPEfXIh #yEIXKL #dLzZLW+8RwW*FfI #EIKLȕ #dLZLo+8RwWFfI #iFIKL #dL>ZL`+8RwW(Gf~I@ #FI~KLX #dLZL+8RwWGfIp #YGIKL #dLZL"+8RuGW Hf5I #GI5KL #dLJZLw+8RuGWHfI #IHIKL #dLZL+8RuGWHfI #HIKL #dLZL! +8RuGW rIf4I  #9II4KL #dLIZLv+8RuGWDIfI #IIKL!> #dLZL-+8RuG 2%8Ws )6{ ]HdQstrD QpD %QmE /XPiG &'I G JII  II  -IؖchH '>H N `KD\H bPH PDPpzS[ KbPSPP`R$%bb(e .LEb;b(bPb@QPCR$K L,DbPP,PXzU LqbPPqPРQ QMРbPРPP'` MZ Z%bP ] MEb;bP bPS`Q/POiR$%bp W [NEb;bbp bPsxQvPR$Ab NaWbPPPR$:ؗb OZPؗb~aaa"I tOII II -IԡR$ԡ c OF^ bPԡ@PFPrR$Whb `PfI #'PIKL #dLZL +8R[Wb PfI #PIKL #dLZLH++8R[*| k )Q[*i| U9i[qG+k nQo*i+U9io8qG |y]@{ 1P XH XWI /TcWiJ %ؘXW*K X _L R)__PRPPaO xRlO{ R$8)__/PPL SDPbPpPDPlR$M kSbPPP͢R$:͢M &TZPb~a͢aaI͢ TII͢ II͢ -IR$(M T6(bPHP6P^R$WhM Uf~I #TI~KL #dLZLȣ+8Ru[W M zUfI  #@UIKLК #dLZL$+8RuPYM UBm,JnL VnbPn PnPR$V`tL WVe`Tt+TIt IWM VfI@ #VIKLX #dLZLG-+8Ru[W-M GWfZI- #WIZKL3 #dLoZL?+8Ru[AkY*qkߣ O W*iߣ U9iqGO W*iU9i qGrߣy]{ :~9i"X9X6_msg`9X_5XO1QZX,\"X,X p`.Zω Xމ.c_Yc؛#? Y'VM#?`h`WZW5M~asaZa@aIs ZI@Is I@Is -I@R$WaY[fIȜ # [IKL #dLZL'+8RucWa[f:I #[I:KL  #dLOZL|+8Ruc*i`[9i%qG%| sy]{ { -{ Q\o %m/Pi\q\C%p.\F%/>.]^*TbbP P*PŤR$ _Ȥ8])__PФX]PZPmaOФ]lOZ٤{ R$x)__P5^bPPPR$[LН"w^{qDНbbP>b#^^fT~bwP:w#x_ZPb~aw(aaIw k_IIw IIw -IR$WP#_fIh #_IKL #dLZL,\?5a7\*E\\mQ`H`mbPO`ouebVPa`aab=abPȦ\a*iȦU9iզqGnˠa*inU9i|qGQȦy]E֦4ae([`bP>(56b^T(bP:@5bZP@b~a`aaI bII II -IR$57cMub$P>&6yc^Tb9P:968dZPb~a9؟aa%I9 +dII9 II9 -IOR$WO5dfUIO #wdIUKLR8 #dLwZL+8RuWf"6,efIf #dIKLl #dLZL|+8RuX3h+%W1efKL #edL'ZL<+8RudI #It/fO wtbP>ؠ0Gf^TؠbP0fb©P>é1f^Tb֩P:֩01gZ'P<0b~a֩Pa'aOI֩ }gI'I֩ I'I֩ -I'R$W1gfuPIx #gIuPKL #dLudZLP:^quAhPuPRuGPuRvW6hfgI #rhIgKL #dL|ZL+8Ru`W5%ifI #hIKL #dLZL +8Ruki!bP>ءi^CT[ءbħP:ħljZpPb~aħapaIħ _jIpIħ IpIħ -IpڧR$Wڧ8jfIڧP #jIKLݧh #dLZLa&k /bwP>x'Vk^QTibP:'lZ~Pb~aآa~aI lI~I I~I -I~R$W'{lfI #TlIKL0 #dLZLW#lfIH #lIKL` #dL*ZL?W'GmfRIx # mIRKL #dLgZL|WΪ%mfIΪ #mIKLѪ #dLZLWأ?%nfI #mIKLɥ #dLZLD0+8Rudѥ+nb*iѥ+U9ibqGѥ+GGbŝW(@ofI #nIKL@ #dLZLȨ+8Rud&Mo1*i&U9i12qGW5@ofFI5 #oIFKL; #dL\ZLG+8RuWR?>pfIR #pIKLX #dLZLd+8RudfLuAmpPuHRuy]Ψ<uApPuXRuuApPuDRu1P?auApPuLRuP{ v0=|%|str'/qXo|end*P8|vmsg/T r:rbPȤP:PR$sbX'XX?~aī0ra]aIī rI]Iī I]Iī -I]ҫR$WҫPisfIҫp #0sIKLի #dLZLح+8Ru`Wsf I #sI KL# #dL5ZLb3+8Ru`ëy]}TtubPPuPR$>t^T7bPPPfR$ _>u)__P0PPaO 2ulO"{ 5R$A5XuaLWXbP5xPLPMR$WivfIi #uIKLrئ #dLZLȭ+8RuT߭_v *i߭U9i qGW8vfI8 #vIKL> #dL3ZLHJ+8RuTYy]i{ w} d|msg/T\w[*iU9i[qG w} bP8P}P̬R$̬Xy-XbXԬ'XVX~axaaI xII II -IR$WyfI #xIKL #dL ZL,+8Ru`WUyfudIU #]yIudKL[ #dLJZLwk+8Ru`y]}  zbP 0PP!R$!PqzPbP!hPPA9R$ _;z)_d_JPJ{bPJPPbR$W~{fI~ #G{IKL #dLZL#+8RuTW{fAI #{IAKL #dLVZLk+8RuT ?|~*i U9i~qGny]~{ w} Y$={ { _5X% p~varJ'7J8~eK'PXYXK}Y=<Q}1Z'bPpPZPR$ _Q~)__PPKPaOȩ}lOKɮ{ ڮR$Qp~*iU9iqG GGŝOQ~ud*iOU9iud[qG qM} c{ (ppq''/c%@$l%Vhmsg:(XI;i_b#P%<Wb;PA;</aWbPPQ<q'QbhPjت=تb}P}=KbP=7bPa =ya aU b=b@>x@bʱP̱X>'OXb۱Pܱp>?pbPa>aaIb=b>ÂxbP! > *i! U9i )qGW=ȫ?fPI= #GIPKLF #dLpZLj+8Ru\Wӳ?fIӳ #IKLٳ #dLZL+8Ru\A=*iU9iqG{*iU9i qG/*iU9i/!qG2y]=pbw} msg2(Tcx03@Dyl0bPH4'HbPA`4ąaW`bPax4aa7xbƲ=Ʋ5Hb۲Pܲ5)QbP(ج5̆H>جbP 5C*i U9iCqGW/6fI/ #PIKL80 #dLZLw+8Ru`W{6fI{ #ȇIKL #dLZLH+8Ru`8F[*iU9i[qGp*iU9ipqGˆ*iU9iɳqGx$y]/pPw} Hmsg*(Pch+Iyhb)P*,Zb>PA@,͉a WEbSPaT,aabb=bЭ-QsЭbwPx-'&^bP(-ՊH>bP -*i U9iqGWͰ0.fIͰP #YIKLְh #dLZL<]+8Ru`W+. fZI+ #ыIZKL1 #dLoZLA+8Ru`A0O*iAU9iKqGY*iYU9icqGmˌud*imU9iudyqG°y]Ͱpw} } ||{ { ѳ{ { { ){ S{ k{ { $jCWV j %_s HT˴ +TI˴ I1pl Y% [Y 0=<%|Ip <Ȯ #VqPudTV ގ+TAIV IA"b -p}qPvW fI #OIKL8 #dLZLp+8Ru_WX fI #ǏIKLp #dLBZLq_+8RvW} xfI} #?IKL #dLZL+8Ru_W fu`I #Iu`KL #dLZL+8Ru_ȴ{ T ~4p<Oa{ ŵw} pe p{ ]HLstr|'|'/|qG~H$9cbPدPcPR$ _)__PP<POaO lO<&{ 7R$()__PI@L*iIXU9iqGIpGG_ŝud*iU9iudqGfI qƷ{ pз|'fd\FX-|/\zw;) bPP;Pm  R$ _Д)_ _ Ŕ)__ P(P; *i;U9i HqGi&'K YQYj IQ( Ij IQ@ -Ij hX# uf %bupEb;b pbP~Q P R$U *iȱU9i qGWΖf I #I KL #dLT ZL +8RuTWFf I # I KL #dL ZL +8Ru_# *iU9i# .qG5ɗud*i5U9iudDqG;y]Qy]{ L{ P'h%0-|\FlH8 Yr YV ~=<WPfj Ip #ØIj KL #dL ZL ٹ+8RkrPlRa1'h'-|\Fl/ H Y  Y =<W ز!flI #ܙIlKL, #dL ZLC I+8Rk PlR`'h(-| \FL Hq PYP ʚY =<h1 hbPP P|ʺR$:ʺZPb~aʺгaa*Iʺ IIʺ IIʺ -IR$[J*iU9iJqG(GGJ ŝW2@ӜfI2h #IKLA #dLZL߻+8Rudaja6anb{=WȴfI #TIKL #dLZL+8RuD ӝ*i8U9iqG(*iU9i(qGW#f=I# #WI=KL) #dLRZL5+8RuSWA$ fIAP #ϞIKLDh #dLZLY+8RuDeNu\*ieU9iu\sqGlPuTRu qjy]{ ûw} >{ q7*iU9iqGGGʼŝ{ud*iU9iudqGvy]{ - uAWȵWW<9͢bXA 'X X5~aW@ҡa^aIW ǡI^IW I^IW -I^eR$We`IfIe #IKLn #dLZL;h+8Ru\WfYI #IYKL #dLnZL̾+8Ru\Vy]zT,2+T@I I@Aض,3A)AaO lO{ hW, f I #ϣI KL( #dLNZLX+8Rut +R4 ZMCW&,̤fI #IKL #dLZL +8Ruy]%| Ƚ+V*iȽ+U9iqGȽ+G?GٽŝҾ _*iҾ U9i_ܾqG9)@;t` W#yfI# #@IKL( #dLZL2+8Rvŝ9{ )߾֦;P߾e3&V{ _5 3'X' Al"%зmsg/LfL|zLbPLPPdR$ _g)__mPokPPaOo `lOx{ R$8)__P0Nb  b0bNPNbzPbPhPbPR$:ZPb~aaaI IIظ II -IϿR$ҿd<ҿbPҿPPR$ _  )__P8P6PIaO ߪlO6{ R$X)__yPwbPpPP0R$3ɫb3  bb?F0bPFPP+^R$:^۬ZP[b~a^عaapI^ άII^ II^( -IvR$W@WWhhbX'XX(~aa=aI ޭI=I I=I -I=R$W`fI #'IKL #dL ZLS +8RuSW(׮fq I( #Iq KL. #dL ZL >+8RuSy]0O *iPU9i qGpG!G ŝ>"!*i>U9i"!JqG);7!f!л !f!W'|f!I' #CI!KL, #dL!ZL!+8RwŝA{ D+"*iD+U9i"qGD+G5"G"UŝCI"*iU9iI" qG);^"s"!L&V{ 11`&'X'j' 'W f"I@ #HI"KLX #dL"ZL#(+8Ru_Wxf%#I #I%#KL #dLT#ZL#+8RwW5qf#I5 #8I#KL; #dL#ZL#H+8Ru_WSfu`IS #Iu`KLV #dL#ZL#$n+8Ru_TUQ{ ;p'X'j' 'Wؼf6$I #I6$KL #dLn$ZL$8+8Ru_W0jf$I #1I$KLH #dL$ZL%'+8RwWEf7%IE #I7%KLK #dLL%ZLy%X+8Ru_WcZfu`Ic` #!Iu`KLfx #dL%ZL%~+8Ru_VUa{ d 'X 'j M(  M(Wcf%I #*I%KLȽ #dL&ZL3&H+8Ru_W۷fQ&I #IQ&KL #dL&ZL&7+8RwWUSf&IU #I&KL[ #dL&ZL'h+8Ru_Ws˸fu`Is #Iu`KLv0 #dL"'ZLO'+8Ru_V!Uq{  #]VHe j_`_b'y_z'@_Y_O_'__':LxYZL'PL (:ZP+(b~aaaT(Iؾ II II -IR$ ((T,+T(I I(A@,K3A()AaO @lO({ -hW-X,ûf')I-x #I')KL6 #dLI)ZLk)+8Ru_t+ )4 ZMC)W,f)I #JI)KL #dL)ZL)+8Ru_y]%| >+  **i>+U9i *qG>+G*G *OŝR2**iU9i2*qG ; {  ƽITӏ_/ƽ, ITn_/~# ,IT_/,K G_IT%_/_5s zITv_/ žIT_/ž" IT_/ +ITd_/+t !gy'my'6' %X%*X%ٹ% }5G*J߿e*a **2poR*H1+bPp0P*P+R$P+*ihU9i+qG#+*i#U9i+/qGp˽5 ,C,l,,bPPl,P -R$1-*iU9i1-qG$~-*iU9i~-qG`--  .C. bP8P .P.R$*  .*i* U9i.4qGO/*iU9i/qG(14XQ3/Gk/$mBpDm:m/pblHm/ m+0W7=d 1K0*id U9iK0nqGv0*iU9i0qGBbdn0z0|1<1bP|P1P1R$\1*iU9i1qG2*iU9i2qG|(,2d2(HBH2>2HbP`P2P93R$ \3*i U9i\3qG3*iU9i3qGʾ33 m44l4bP P44P4(R$34*i3U9i4;qG*5*iU9i*5qG 11;/Q?5Gw5$mFDm:m5blLm5 mo6[7=f6*ifU9i6nqG6*iU9i6qGFdpXn ZX6X#7by8A7xy78bPyPPA7P7R$ 7*i U9i7qGI58*iU9i58qGyʾpJ8888bPP8PK9R$/k9*iU9ik9qGpt9*ipU9i9zqG1Q9G9$mDm:m(:blmz: m:7=V:*iU9i:qG]7;*i]U9i7;iqG L;;z! <;; bP!8P;P,<9R$D O<*iD U9iO<LqGN<*iNU9i<XqG!BʾWX<<dxg=O=xbPjP=P=xR$=*iU9i=qG;>*i;U9i>GqGd1)Q>GD>$mDm:mb>blm> m>7= ?*i U9i?qG/?*iU9i/?!qG)o;D?f?)$;?$?1j&VkkkkkWkGU9{ v0Hrhs HH6c{IT_/{ %gy%'my&'%X'% *X(% lhs/ݤrhs/ݤr84 |t<4 ~!3P0:?0?3h K?k3 ?z?X ?%@U K=@kU ?z=@ ?u@Ž M͎@ڎ@@5A uc]A vA8HA Bω(މBH@yCHh#?&'CVM#?VyMeMDM #?AM-MSE iEEcĉEnttcF4t ZMCFL 81LG L _ {09GH=RP$҂LRvHVRHheR&Il9mI mI7=< JPJω+މ'KK#?'KjVMj0#?yMeMLMm #?AM-MqMHeMMpc!ĉM)t/cZN4/ ZMCZNL 0LN k  {k= OeO=Rt$҂LROVRPeRePlw=6mP mP7=M Aam(QcpQ8.RvR8bPPP.RPRR$   "S*i  U9i"SqG PS*i U9iS qG pASSz/ TxTbP/P TPUJR$U6$U*iUU9i$U]qG {U*i U9iU qG/SpXiAXUXUby "VxzV bPy8P"VPVR$ aW*i U9iWqG cW*i U9icW+ qGyXByWWxGWXxbPPWPXR$ X*i U9iXqG X*i U9iX, qG)A(;X$Y+W+BfaYI+ #gIaYKL7( #dLYZLY+8Ru|WC@CfYIC #IYKLLX #dLZZL]Z+8Ru|Xp<.{Z5ZW@fZI #IZKL #dLI[ZL[ +8Ru||L@L[R5cua[M#;@AM-M\L#;MLK\L5L}\//@C.\_h5_\Wn@=f!]In #I!]KLw #dLS]ZL]+8Ru||L@L]R5ua]L#;ML]M#;AM-M^L5L3^ )/ A6;W^/ m^? WB Bf^IB #uI^KLK  #dL^ZL^^ +8Ru|W^ C(f^I^ #I^KLg  #dL _ZL9_z +8Ru|XX&VkikG^3mTkmbPG(P3mPm_R$lH6m*il`U9imtqG{'n*iU9i'nqGGjx #dLqZLq+8Rw%ŝQ{ );qrT&Vk9kkkiU{ cITz_/DT'+'s1' s2'M3m=rcerErsbPHPrP`s]R$js*ij0U9isrqGv uL*ivU9iuLqGEhHHstzhGtthbPPGtPtR$ u*i U9iuqGc7Ku*icU9iKuoqGms`uuuubPPuPMvR$pv*iU9ipvqG?bv*i?U9ivIqG0vwz P/wgwPbP hP/wPw8R$E Hw*iE U9iwMqG#x*iU9i#x%qG CG[G8xGpxi.xxbPiPxPyR$ s9y*i U9i9yqGNqy*iNU9iqyZqGi);yy  yyW@fzI #gIzKLX #dL/zZLMz+8Rwŝ{ )(;z(z5"V?&Vkkk[kU={ #zt'͆'IT_/#@'%z''t@͆E p5%{HTl'{_R{tIIp{I{} G(G{G{51{/|bP5P{P|PR$[ v|*i[ U9i|cqG;|*i;U9i|GqG5YpXX }XD}b8\Y}x}8bPPPY}P}R$p~*iU9i~qGuP*iU9iuPqGz"I~~~~bPP~P,R$L*iU9iLqG*iU9iqGG*0MGG8PRPbP>hPPLR$Y Ѐ*iY U9iЀaqGx< *ixU9i qG8WGxGGWbPPPR$ "*i U9iqGcg8*icU9i8qqG)f;Mo oW0OfI #IKLH #dLςZL7+8Rvŝ{ )J; J W &V  IT, _/ +>$X8+, %''t8+͆=+ -+%H"Ƭ:MNN:NƬM K"M:J J:I -I:f1G3<#GG@"GbP@PP[R$f "Ȯ*if U9iȮnqG+#*iU9iqG@d 8 $ $ #*iU9iqG#*iU9iqGApXX5%XX;bx$YxxbPPYPR$$*iU9iqG$%uL*iU9iuLqGz`&L%bP PPC-R$8@ &f*i8XU9if@qGO&*iU9iqG6GLp'GGY&NbP_PPmR$x 5'̳*ix U9i̳qGz'*iU9iqGYv Y(  G'{*iU9i{qG>(*iU9iqGAG)GG(+bPPPbR$ .)*i U9iqGis)*iiU9iwqG)0r*;Pڵp ڵW([*fI( #"*IKL- #dL:ZLXg+8Rvŝ>{ )z*;vz&V'.*iU9iqG93gP/SIθ.*iU9iqG.uH*iU9iuHqGuzpXhD0XIXb/xbPPPbR$/*iU9iqG30ٺ*iU9iٺqGzo160_bP0P_P R$P1B*ihU9iBqG^1*iU9iqGG(2GG51WbP;PPIR$T D2ս*iT U9iս\qG2*iU9iqG5R3{d3SI$3X*iU9iXqGI3*iU9iqGzG4GG¾3bPPP?R$ 94o*i U9ioqGY~4*iYU9igqG)8}5;XĿx ĿW f5fI  #-5IKL #dL$ZLBW+8Rvŝ"{ )j5;`juw&V)Gl9c;SKPG__xGSKa@XQX& L<p̆d& Msp}::*8 V: L:SW<f|I #n<I|KL! #dLZL1+8Ru`7F::UPQd=V:L:W#W=fXI #=IXKL #dLmZL+8Ru_kz@S>NA4@û@_B5(@Qa:@V::H~:@:ԺʺS>SS!S S4SIxWN?Ժ^ʺS!?S^SSSSL`WZ@^`W?fI #?IKL #dLZL+8Ru_W@f&I # @I&KLX #dLHZLj+8Ru_p>KB^H=`HVanb:_4A::::@Xc Agcgc(%u0`ZA:-DaAqD|!FDMU!k5_IM%| SiB]̆qdSMs]q}::[ V:LL:WBfI #BIKL #dLZL+8Ru`etz(r,E"_z()."z()C"7+(Q:z()~/;"#;;(=;9P)KDd::hSV:L:WDfI #ODIKL #dLZL#+8Ru`#)PEC76~ Vբg   yoG_).)C7+QV:)~/;#;;=;)KF::SV:L:W9FfEI9 #FIEKL> #dLXZLN+8Ru`#Y)PKGC7YY~ բeg;qY } O RI{go#C7~ բ gL` ]^`WHHfKL` #pHdLOZL~K+8RuLI9 #IW(xfI( #HIKL- #dLZLv+8RuLUIdzn   +C7 M{ U"Jdzn1 +C7EME{ !oJ*Y!MY,Rb"K{o#b"C7b"b"~ mբlgx   E X  { { ~9hgK}K pאXK`kK8LgKqKW5#LfI5 #KIKL; #dLZL4i+8R_(ŝL{ JLLC:gL L['G'+xϭ:118LF`jLNJLTLaLnL {LLL2MR r \M %< M4FXK%I8M4VXKWY(Nf/IYP #MI/KL\h #dLDZLqt+8RugWtNfIt #gNIKLy #dLZL+8Rug%| %| { { { O?OAA V '[V 'WW XX NFH[ORO OO$O 1O*^ O I9^ PXo9~P9}_cN^ `Pr;٪N;N}ɪ;}^ 2Q]̫۫]Xg}rq# .F: M{ ^ Rbq ĩܩЩ0 M0{ %^ .R4CXKW ^ RfpI #mRIpKL #dLZL+8Rw%| *{ { RRC:H%R7 SWR%VS4XKVqKgKWSf I #SI KL( #dLLZLnH+8Rugjŝ{ %wHT4XKwHqKgKW`TfI #xTIKLx #dLWZLy8+8Rugŝ{ W?UfI #UIKL #dLZL/(+8RugWUfMI #~UIMKL #dLkZL+8Rug%LU4YXKWeYVfIe # VIKLk #dLZL4w+8RugWwVfGIw #VIGKL| #dLZZL+8Rug%V4XKV{ 0WIT xS%:?WTWAAH%0WpUpW>]?W*d W>3y*(3z&zzW $W'{ }!b XE̫!۫EX*g}jq*#. .F:. M7{ :b Yb:q@@D ĩܩ!ЩCD M!CM{ %P b iZ4VXKP qKgKVWu@SZfIuX #ZIKLwp #dLZL+8Rugdŝ{ Wb ZfI #ZIKL #dL^ZL+8Rug}b [̫۫Xg}q# .F:  M { b \ bq 8Z ĩܩmЩ Mm{ %b \4&XKW)*b ']fI) #\IKL2! #dLZLB+8Rug!K{ 0W`(Z]t]?Wz{ $]I_Tp%:w9=:9=:C97:.@_ ̒]^c__n__s'B`^edPGՌ*__xGe_XQ%:_}z& L^z}zzAz& MPz}fzZz=SA=A;=_|obA_t]=V]]]A]e} p"B^`=``Vanb]p0_`]{ ]]V0]|cpHb`ccw`%!`+x``UHԾa2a¾M%| }ziaz-zKz^AzMPz-fzKZz^Lrhcr).A4')a)~~)]SF9n"PC6_%_} Ly;e[yr).A[4y')ya)~y~)]SyF9yny"PyC6_;} 7Je ĩxܩЩ Mx{ N:M1fI_Tp %w9'9'C9:.@_ ߜ@fuf7d__n__s'BszfQncdPG__xGQn&hXQ %L{" L9g`{ x{7l{l{" M{ 5{7){l:SH;.:ӿƿ:__REn9e:Vffe"fY]} jB^s=`sVanb1fj_hWf{ Jf@fVffVdjh,d,do%h0` iXaiXcMr|%| L{ ij`{ x{+l{K{ M{ 5{+){KxrkyYx).yx)=1%xK x)~x)]2xsfYxx# xx+B} ymaY).a)=1%K)~)]2sfY##} XgH}[qv# .F: M{ :en}nd__x}n:2nncd__xn2;}!n9pAA|w %:Vnx {oonen/}z pozqzzAz MPzqfzZz^dy o,d,dny nn*L{-p`{lx{l{{M{l5{){ufvpI_TpP;w9B9BC9B.@_ ppd__n__s'BxpxdPG__xGxzrXQP;|& Lq||3|HD|& MS|i|3]|H=S-[ =[=_B[5(Q9p=Vgp[ZpMpvp e} p"B^x=`x0Vaunbpp0_Nsp{ ppV0phdpH'swdwdw`%rUx`tsr@ashq|FMUk_%| |iZt|||D|MS|i|]|r-v *Tr>). ~*qTdr)"*T r0)~*Trf)]*TrX*KT>rH*|Tor*Tr_} yx.N>).~q.dN)". N0l)~.Nf)].NXK.>NH|.oNl.N;} &5K? 1Ƭ Mլ߬1{ C7xxd__xxeC Oxy>[G{ P;Dx3| x|x|; y|||D|; MS|i|]|jpk p#yyG P;x  Ry0zG P;Ōy*RKz}zGP;'ŌKyzz\rzWrz;;zztDzWDz;;{{\ؾ`+{(H^(6Tt{ETIt 6IIt IIt -I(pos5(AA@'|gAZAPAAAX|gA&ZAHPAfNp |NNHNfI C|If<$}zzz_zzs,~zfzz;WE}fpI #d}IpKL #dLZL+8RudWE~fI #}IKL #dLZL+8Rud.<DzDsv{5^8~NRDlWlX~fIlx #~IKLo #dLZL+8RuZWofI #6IKL #dL2ZL_+8RuZ^Jsrslslc %| { [[#WwfCI0 #>ICKLH #dLeZL+8RvWfI #IKL #dLZL+8RvW&#gfI& #.IKL, #dLZL$8+8RuZWW߁f7IW #I7KL] #dLLZLyi+8RuZ%| y{ w} T{ A{ 1yI_Tp@w9@9@C9@.@_ ħV__n__s'BXՂ}PG͡__xG`nXQ@}& L2}J} >}|& M|} |v=xS2c=x 2cI=x_2}cpx-=xV[2NcAxje} p"B^X=`XVaLnbvyp_B{ Vpw%ڄ`ha?hMh{%| }iN2}J}>}|M|}|r!cVI+<I). +Im)+Ig+)~`T+HI)]+I+I8yl+_Ig +I)_} (ycVI<%(). %m()%(C+()~`TH%()]%(%8(yl_%(C( %()c;} ŮԮޮ e Mt~{ @Ŋ}__xŊA([.Henv@.HS}6 2}J}>}|6 M|}|bS  ËًKpAkCË͋$ŝ0ITJxS5ANITPxS@]rHH%Np}]gtX-ttH"tX(YtLt?tnh $0WT?W{ G nG(0 B^tKTK| { 'j 6j͋ËŝP_<U.KapN lU WfI #׎IKL #dLZL+8RudWfI8 #JIKLP #dLZL+8Rudŝ { 9JhHJ0r^JVk0#k0j$j0jgk1Uvkj6jjMk0\k̞#/0۞#4#CYM1#'  "Dԝ' MD0{ ̞-/۞-4'CYMW' "jԝMj{ }3}̫3۫}X9g}q9#= .F:= MF{ yIƱIձROaw k9 OS (@L 4n S ML  n \{ _a C_R ŮeԮ ޮ ei   ei Mt ~ r{ uF  ;'. PJPx PaR$PaP PxR$́ J=" ˆ0ٕӈ W0;f IP #I KLh #dL ZLI +8Rud} g ̫ ۫g Xg} q # .F :  M  { y!} Ʊ!ձ R'aw k# '+ (@6 4X + M6  X 4{ 7Ok C7Rk Ů=Ԯ ޮ =A   eA Mt ~ J{ ˆq ӈ Wq ;f Iq #I KLz #dL ZL2 +8RucP _E <'66w j\n{ =NP(]jr{ )™י.HH%™N,] { 4C Y P yPP"R$P"yP-P4R$  ==Fs{{ { (4™{ `key-%key-%pH3HϛŤEc2r0~PXufPTP2R$P2xuP|PDR$=$ O=X-K4KAPPPCP;PR$P8sPcPR$a =u{fuu{Lu}[{PKӰPP}ðcrw٪w}ɪw.ɝ|}, ?*s =^ iV)Lmbths~`mX|Pv6PoPR$PfPPR$ v=h}w ˆ0!ӈ W0!;f I0 #\I KL6 #dLZLLF+8RuS'W 6_aPd(_t<}̫۫Xg}q# .F:" M"{ y5Ʊձ5RawKki (@|4 M| { `CRŮԮޮ e Mt~{ *t%| %| yO{ }B(Ԥߤ.HŤS` Ԥc@r%h~\PucPPR$PuPPR$$ ='<%| D{ O{ ]e{ Aps9%} O} !h?} ׂ { ѵ 5H3HڼTT$+TI$ IPT4ImTaT'?>| 'f@:6W@fI #IKL( #dLZL&+8Ru`rzf@gf9Iz` #.I9KL}x #dLZL+8Ru`'@6f'ۨ@6fY'SETS'SJSS'$ˆ$ӈpW$;fI$8 #IKL-P #dLZLK+8Ruˆ6hӈiW6;fI6 #GIKL< #dLZL* +8RuWEfH IE #ªIH KLK #dL ZL +8RuˆTӈ WT;f IT #VI KLZ #dL !ZL,I #I>,KL #dLS,ZL,+8RuXOӈu`W;fu`I #Iu`KL  #dL,ZL,+8RuXfڗ+{|NyŐ?[dڗw+FJ{  \dHY3d,b=vbb,LTa+TU-Ia IU-[t@һ[-WXJf-Ix #I-KL #dL-ZL-(+8Ru_W¼f.I #I.KL #dL3.ZLU.+8Ruds..b  bs.b.W5f.I5 #[I.KL; #dL.ZL.G+8Ru_W^ f/I^ #ӽI/KLa #dL'/ZLT/v+8Ru_=N_si%| t0z{ w} [{ P{ 1h,#t/dz,#z/me7S3H %#H ITiI t0XZg/#05*5 9/a5 "a/BF/DB(0[/O0T ` n+ vw} H #t#^ | + w}  fd8 %79/:;; %^G%K \@'%}=? %0+>0p0[ \ \\0XӜ %0WLf0KL #/dL0ZL0c+8Ru}II #I0-v 1;U W]f.1I] #I.1KLf #dLR1ZLv1O+8RwWnff1In #-I1KLw0 #dL1ZL1?+8RwWHf1I #I1KL` #dL2ZLB2/+8RwWxVf`2I #I`2KL #dL2ZL2+8RwWf2I #I2KL #dL2ZL3+8RwWFf,3I # I,3KL #dLP3ZLt3+8RwWf3I #I3KL #dL3ZL3+8RwW 7f3I  #I3KL  #dL3ZL4 +8Ru}W #f)4I  #vI)4KL  #dL?4ZLn4 +8Ru}WR )f4IR  #I4KL[  #dL4ZL4j +8Ru}Wj )f4Ij  #hI4KLs  #dL4ZL5 +8Ru}W 3f15I  #I15KL * #dLG5ZLv5 +8Ru}W f5I  #ZI5KL   #dL5ZL5 +8Ru}W  f5I  #I5KL  #dL5ZL&6 +8Ru}W 3f96I  #LI96KL * #dLO6ZL~6 +8Ru}H~ mo) (CIi 8%\\] 7$].]6~aPa6a6I I6I I6I -I6R$Wh=f6I #I6KL #dL6ZL6+8Ru}\c\\ 77w7}}N7`>+777t[ -8~aIa@8ad8I yI@8I I@8I -I@8R$WIfw8I  #Iw8KL"8 #dL8ZL8 +8Ru}Wh "Ivf8Ih  #<I8KLq  #dL8ZL"9 +8Ru},PP=Pe ~ap PECa59aIp  8I59Ip  I59Ip  -I59 R$W hEfY9I  #IY9KL ( #dLo9ZL9 +8RwW %E4f9I  #I9KL  #dL9ZL9 +8Ru}.Jy9*i.U9i9>qGX\@::X\bPXP:P/:aOXlO:R$/ JIH:*i/ U9iH:? qG[~ S y]p   \\\^:Q 4Qr:*Q: <\+ \\:W pf:I  #6I:KL  #dL:ZL:3 +8Ru}~ w,PP P P# E R  ~  { G { Z { } \o'Ӝ %;W (f;KL P #dL5;ZLW; +8RuCI p #I; uAu;  W f;I  #WI;KL  #dL;ZL; +8RwW f;I  #I;KL  #dL<ZL2< +8RwW fP<I  #GIP<KL   #dLr<ZL< +8RwW%  f<I%  #I<KL+ 0  #dL<ZL< +8RwW/ H pf=I/  #7I=KL5 `  #dL6=ZLX= +8RwW9 x fv=I9  #Iv=KL?   #dL=ZL= +8RwWC `f=IC  #'I=KLI  #dL=ZL>X +8RwW f>I  #I>KL  #dL*>ZLW> +8RuCW Pfj>I   #Ij>KL   #dL>ZL>"+8RuCW"f>I" #I>KL( #dL>ZL?4+8RuCW4@f?I4 #I?KL: #dL)?ZLV?F+8RuCWFfi?IF #Ii?KLL #dL~?ZL?X+8RuCWX0f?IX #I?KL^ #dL?ZL@j+8RuCWjf@Ij #oI@KLp #dL(@ZLU@|+8RuCW|W fh@I| #Ih@KLQ #dL}@ZL@+8RuC- ~ N od {   )    i   \] \r H { $z] o% % Ӝ& %@W8 &f@KL`  #xdL@ZLA+8RuI  #I@W+ & f0AI+ #I0AKL1  #dLRAZLtA+8RwW9 &fAI9 #LIAKL?  #dLAZLA+8RwWG &fAIG #IAKLM  #dLBZL8B+8RwWU( &ufVBIU #<IVBKL[@  #dLxBZLB+8RwW_X &fBI_ #IBKLep  #dLBZLB+8RwWi &efCIi #,ICKLo  #dL v-fzGI>  #IzGKLD  #dLGZLG+8RwWL vfGIL  #lIGKLR  #dLGZL H+8RuWZ( v!f>HIZ@  #I>HKL`X  #dL`HZLH+8RuWhp vfHIh  #`IHKLn  #dLHZLH+8RuWv vfIIv  #IIKL|  #dL$IZLFI8+8Ruv?\=\v!dII.A8 y 3AJ)A]JhX!fuTIXX #IuTKL[p #dLJZLJt+8RuP0vJ.K.A< y 3AuK)AKNh Lf>LI  #I>LKL #dLSLZLL(+8RuH<OvtLL.A] y l3A)M)AqMqh]W\vfMI\( #IMKL_@ #dLMZLMt+8RuGWtvdfNIt #+INKLz #dLNZLDN+8RuGWvfWNI #IWNKL #dLlNZLN+8RuGWvTfNI #INKL #dLNZLN+8RuGWvfOI #IOKL #dLOZLCO+8RuGWvDfVOI # IVOKL #dLkOZLO+8RuGW>vfOI #IOKL8 #dLOZLO+8RuGŝo0)zi{ z(5"{ Y[)Qk2XdDP$Ya3kYpdkP2pdDP%-{ i)C2-D>P$It3_-]P2-D]P%-{ 575PC:nLH=|P#1P<6WoSfPIo #{IPKLx #dLPZLP+8RusWS,futI #IutKL #dL QZL7Q+8Rusgoi{ W|]'31H8`WanJQ?/Y'a Y1Z' Z % ZG#[p$$[iQ2a$AaQe*&'msg/fP1 0e*75Qt#<XJRt`9IR`XRESbPPRPSR$+STbPPSPaTR$ܑTTbP PTP'UR$HLUUHbP`PLUPUR$]V*VbPPVP?VR$GhghdV]h|VbQ 4QV*QV<#VVbPPVPV+ މK WA#WbP P WP8W-R$? PW*i?8U9iPWqG?PGWGPWSŝ$7W*i$U9iW"qG?y]~ah9aWaI IWI IWI -IWR$W9KfXI #IXKL #dL*XZLLX+8RuW=fjXI #IjXKL #dLXZLX(+8RuW =?fXI8 #IXKLP #dLXZLYH+8RuWh=f,YI #~I,YKL #dLNYZLpYh+8RuW=3fYI #IYKL #dLYZLY+8RuW=fYI #rIYKL( #dLZZL4Z+8RuW@='fRZIX #IRZKLp #dLtZZLZ+8Ru=Q!\\W=fZI #IZKL #dLZZL[ +8RuW?Bf=[I # I=[KL #dL[ZL&\+8RuX Hbw} WH KfD\IH8 #ID\KLNP #dLf\ZL\+8RuWVhKVf\IV #I\KL\ #dL\ZL\+8RuWdKf]Id #I]KLj #dL*]ZLL]+8RuWrKJfj]Ir #Ij]KLx( #dL]ZL]+8RuW@Kf]IX #I]KLp #dL]ZL^+8RuWK>f.^I #I.^KL #dLP^ZLr^(+8RuKh\-\WVKf^IV #I^KL_ #dL^ZL^o+8Ru{]8L ]_]1_0`ӜN %_W-XNf_I-x #eI_KL6 #dL_ZL`h+8RuW>Nf&`I> #I&`KLD #dLU`ZL`X+8RuWLNf`IL #XI`KLR #dL`ZLaH+8RuWZN faIZ #IaKL`  #dLMaZL|a8+8RuWh8NfaIh #LIaKLnP #dLaZLa+8RuWvhNfaIv #IaKL| #dLbZL@b+8RuWN{fnbI #@InbKL #dLbZLb+8RuWNfbI #IbKL #dLbZLb+8RupU }~ o)'-iXN]\\U] Od]cn]#c#V[V[7c ӜZ %dcW8ZfcIX #NIcKLp #dLcZLc(+8RuWZfcI #IcKL #dLdZL*d+8RuWZ|fHdI #AIHdKL #dLjdZLd+8RuWZfdI #IdKL #dLdZLd+8RuWZpf eI #5I eKL0 #dL.eZLPe+8RuWHZfneI #IneKL` #dLeZLe+8RuWxZdfeI #)IeKL #dLeZLf+8RuWZf4fI #I4fKL$ #dLIfZL^f0+8RuW0ZWfqfI0 #IqfKL6 #dLfZLfB+8RuWFZffIF #IfKLL #dLfZL gX+8RuW\ZI f gI\ # I gKLb #dL5gZLdgn+8RuWrZ fwgIr # IwgKLx #dLgZLg+8RuWZ; fgI # IgKL #dLgZLh+8RuWZ f%hI #z I%hKL #dL:hZLih+8RuWZ- f|hI # I|hKL #dLhZLh+8RuWIZ fhI #l IhKLC #dLhZLi+8Ru~ *o<Rhy)iKU 0Z; 5\\\]` [e $]*i.]Ii i\ &ii}iWK fiI # IiKL #dLiZLi+8RuWK fiI #G IiKL #dLjZL7j+8RuWK fJjI # IJjKL #dL_jZLj+8RuWKsfjI #9IjKL #dLjZLj+8RuWKfjI #IjKL #dL kZLsbsA!R!sssc!|W!ftI! #NItKL!0 #dL=tZL_t"+8Ru\W!(f}tI! #I}tKL!" #dLtZLt!+8Rwh!PQtttuw"u "|W"fZuI" #IZuKL" #dLouZLu"+8RuGW"AfuI" #IuKL" #dLuZLu"+8RuGW"fvI" #IvKL" #dLvZLFv"+8RuGW"#1fYvI" #IYvKL" #dLnvZLv"+8RuGW"fvI" #pIvKL# #dLvZLv #+8RuGW#!fwI#h #IwKL# #dLwZLEw(#+8RuGW.#fXwI.# #`IXwKL1# #dLmwZLwF#+8Ru\WF#fwIF# #IwKLL# #dLwZLwX#+8Ru\oo  ? )e ΨR!%| ! !!Ψ!%| o#{ "{ w#{ 4#1þ*1UP1xMHx%Ӝ %xW$xfxI$8 #?IxKL$P #dLxZLx&+8RuCW$hfyI$ #IyKL$ #dL$yZLFy&+8RvW$hfdyI$ #/IdyKL$ #dLyZLy&+8RvW%fyI% #IyKL% #dLyZL z&+8RvW%X f(zI% # I(zKL% #dLJzZLlz&+8RvW%%( fzI%% # IzKL+%@ #dLzZLzw&+8RvW7%XH!fzI7% #!IzKL=%p #dL{ZL0{g&+8RvWI%!fN{II% #!IN{KLO% #dLc{ZLx{b%+8RvWM(8"f{IM( #!I{KLS( #dL{ZL{c(+8RuCWc("f{Ic( #w"I{KLi( #dL{ZL"|y(+8RuCWy((#f5|Iy( #"I5|KL( #dLJ|ZLw|(+8RuCW(#f|I( #g#I|KL( #dL|ZL|(+8RuCW(!$f|I( ##I|KL( #dL|ZL!}(+8RuCW1*$f4}I1* #W$I4}KL7* #dLI}ZLv}G*+8RuCWG*%f}IG* #$I}KLM* #dL}ZL}]*+8RuCW]*'%f}I]* #G%I}KLc*! #dL}ZL ~w*+8RuC $U $~ 7$oF$^$v$$)$$$$i#&#\g%\W%&f3~I% #T&I3~KL% #dLQ~ZLs~.(+8RuPW&'f~I& #&I~KL &  #dL~ZL~:(+8RvW& }'f~I& #D'I~KL&8  #dLZL7F(+8RvW*&'fUI*& #'IUKL0& #dLjZLW<&P [(fI<&h  #"(IKLB&  #dLZL'+8Rv&Wm' (fIm'  #(IKLv'  #dLZL4'+8RuHW~' \)fRI~' ##)IRKL'! #dLtZL (+8RvW'!)fI' #)IKL'0! #dLրZL(+8RvW'H!L*fI' #*IKL'`! #dL8ZLZ(+8RvW'x!*fxI' #*IxKL'! #dLZL$(+8RvW'<+fځI' #+IځKL' #dLZL'+8RvW(+fI( #{+IKL( #dL,ZLY(+8RuHW(,,flI( #+IlKL( #dLZL(+8RuHW(,fI( #k,IKL( #dLւZL )+8RuHW )-fI ) #,IKL) #dL+ZLX")+8RuHW")-fkI") #[-IkKL() #dLZL8)+8RuHW8) .fI8) #-IKL>) #dLՃZLN)+8RuHWN)-.fIN) #K.IKLT)' #dL*ZLWh)+8RuHW{).fjI{) #.IjKL) #dLZL)+8RuPW)t/fI) #;/IKL) #dLԄZL)+8RuPW)E/fI) #/IKL)? #dL)ZLV)+8RuPW)$d0fiI) #+0IiKL) #dL~ZL*+8RuPW*!0fI* #0IKL* #dLӅZL&*+8RuPu%~%ڗ% %,%%%%)%i&҃ &,'#'6'E'X'g')m'i({ 1v1I_Tp5Aw9;A9;AC9/A.@_ 1/2`__n>__s'BG2 :aPG__xG :!3XQ5AH& L2f& Mf=!S*?=!sf*=!_*!H1=!V111*!1he} p"B^=`VaޭӇnbޭ1p!_42{ 21V! 2eQap!4`a`aw"%L4 "`4#W@"a]5fƈp@".9EM(%| i54GM4GAX"r7jtgЉX").6j)ЉX")ЉX"VX")~sЉX")]H;.ЉX"ЉcX"ЉX"X"E8+ЉX"T_} Ap"yf9Dbtgp").6D)bp")bp"ʊVp")~bsp")]Hb;.p"bcp"bp"ʊp"Eb8+p"T;} Ra w3kN (a@t4 Mat { LAK;IT*^;M" ;mc‹P)":PP aO) :lO2{ CR$"m=cQPC"PfP~R$R#t;*iR#U9iqGR0#GÌGfŝ;ud*iU9iudqGRy]{ JD$<I_Tp*w99D99DC9M.@_  3<h<__nB__s'B<DDhPG׌__xGDDH#>XQ* & L,=π*Uۀj& M*Uj=`#S}"=`#c}VI=`#_}`# ;=`#V<};;`#<,e} p"B^=`RVanb$<px#_>J<{ =<3<Vx#Y<)p#>w#%>#`?(b:#a?IS#(M Ə%| i?πڏۀ Mڏ Y#rA.Lv#).N.AL4v'#)Lv#n#)~Lv)#)]`LSvF#Lv{#Lv#/#]LPvC#lҐ_} Y$yC&Pp$).NA&4P'p$)&Pp$n$)~&Pp)$)]`&SPFp$&Pp{$&Pp$/$]&PPCp$l;} L[qe "%:8.S M%8S{ JDnaDrEhPof__xorE 0$__nrrDr$rr H$r E(nDXvfEπVUۀXMVU;h<DxEGs__x*`$__y*4$*GRpY$*FhrW$ fKL$ #eFdLZL̓k+8RLIN$ #IM0 *\ߓf0 * ߓ!0 Mߓ;{ NwEl.G}GBM1 }G J B __r  %G-qG-aڪ*i-U9iڪ-qG-4-)V-,{b;V-,V-, W|-,bf+I|-- #bI+KL~-(- #dLVZLt-+8Rwn-ŝ-{ W-H-{HcfI- #cIKL-`- #dLZL-+8RvW-{cfګI- #cIګKL- #dLZL-+8Rv)-{d;-, .W.{~dfYI.x- #EdIYKL.- #dLnZL).+8RuGW).1{dfI). #dIKL/.+ #dLìZL<.+8RuG+U2,&Vr,k,k-:LK-:LV-E.{ .Engy~'my~'%X~ *X~ .~e' . '.ZT .~8fuV . V/ZTM/-~cgmc /-fH-bP /-PHPŮ8/R$C/  g*iC/ U9iK/qG\1Rg"*i\1U9i"h1qG /A/W/-~h7oze/ .gԯ .bPe/8.PP}/R$/X.8h<*i/p.U9i</qGM1}hv*iM1U9ivW1qGe//M/.~imcð/.i(.bP/.PP`/R$/ ci*i/ U9i/qG:1i*i:1U9iF1qG///.~jű//Ij'O/bP//P'Pm0R$0 j*i0 U9i#0qG0j*i0U9i 1qG/0);08/~k;;0X/˲;0x/ ˲Wa0/kfIa0/ #kIKLc0/ #dLZL=0+8RwS0ŝ|0{ W0/~Jlf[I0 #lI[KL00 #dL}ZL0+8RvW0.~lfI0 #lIKL0( #dLҳZL0+8RvW0~:mfI0 #mIKL0 #dLZL<0+8RuG) 1~m;O 1d1W1~mfI10 #mIKL 100 #dLZLӴ81+8RuG.U/&VW/k/k/:L00:L;00{ 1Gwgy'my'%X *X 1n  1  1ZT 1:ou9 1 91ZTM2H0epmhc2`0o+c`0bP2x0P+P(2R$32 p˶*i32 U9i˶;2qGL4Tp*iL4U9iX4qG212˽G20qRU20p0bPU20PPm2R$z20:q*iz21U9i2qG=4qY*i=4U9iYG4qGU2x2M2(1rmnc2H1 rӸ H1bP2`1PӸPC2R$2 erf*i2 U9if2qG*4r*i*4U9i64qG2221sй21Ks 21bP21P PP2R$ 3 ss*i 3 U9is3qG3s*i3U9i3qG2 3)+31t;+31+32 úWQ382tf׺IQ3P2 #tI׺KLS3h2 #dLZL 3+8RwC3ŝl3{ Wo32Luf>Io3 #uI>KLu32 #dL`ZL3+8RvWz3.ufIz3 #uIKL3( #dLZLʻ3+8RvW3fI6 #IKL6 #dLZL6+8RuG)6;6*6W6fWI6X5 #IWKL7p5 #dLlZL7+8RuG4U4&V75k5k5:L6:L66{ p`7Kgy'my'%X *X 7 7 7ZT 7>u 7 7ZTM75im.cf75΁)5bP75PPn8R$8 *i8 U9i8qG,:X*i,:U9i8:qG78˽'85586E}6bP586PEPM8R$Z886>*iZ8P6U9ib8qG:*i:U9i':qG58X8Mp8h6m4cl~86$6bP~86PP 8R$8 i,*i8 U9i,8qG :Y*i :U9iY:qG~8886n86O6bP86PP8R$8 9*i8 U9i98qG9مL*i9U9iL9qG88) 97؆;a 987t 9X7 tW19x7fI197 #IKL397 #dLZL9+8Rw#9ŝL9{ WO97PfIO9 #IKLU97 #dL&ZLH9+8RvWZ9.ȇffIZ9 #IfKL`9( #dL{ZLp9+8RvW9@fI9 #IKL9 #dLZL9+8RuG)9;9 9W9f:I97 #ňI:KL98 #dLOZL|:+8RuG7U7&V'8kp8k8:L9:L 99{ !p~S/w p~S p~S q/ <(8? t`8 t:q-R@ |ktjߏ@ -u`@ c``kLRS tj&ߏS -r&u`S c`&`_Rf gtjzߏf -zu`f c`z`rR xt.jߏ -2u` c``8 z ~#& BNR  tvjߏ  -u`  c``,3 ߌR6 ]tj ߏ6 - u`6 c` `0BI |\RL ttjߏL -u`L c``X"'!'%MK ' ,4"B/w pB pB q/ <8? tC8 tҎmW`fH8 |YH8- IH vIIH IIH -I 5( P8 .rP8- IP VIIP IIP -I 5(  X9 r/sX9- IX 6IIX IIX -I 5(  q xR0q- Iq IIq IIq -Ix 5<(Ob   zqu  ~  T 9 T 9-7 WIT SIWIT IWIT -IW 5u(  [ ^ ^- I^ RII^ II^ -Ie 5&(9Lp 89 ƕ_89- IP9 2IIp9 IIp9 -II9 II II -I 5(8   Kk0RkQv-kn"k 0w pk pk q 0 <9? t c9 t#8G@ x͘B-ܘS{| ^ |\͘a-;ܘNr{| } ͘-ܘ{| " ͘-ܘ{|  X!͘-4ܘG{| ;  wJZ ˘r͘-ܘ#{| ;* J-# >͘/!-ܘ@{| ;`9 z]J;x ~|J$; JL"ޙ$kw k k 0-"ARk 0w k k 0PaPo__xo__nrAXa__xAP:˚dHM'gN'WO XP:OٖRtZAAX\t:8:Tsuk::P:Tq:P:6q q:Tq:$qq:h:TЙÙ'h: Z,h"h:ޙ::  h::-,h"h:+::-D:h::-,h"h:V::-퐝hW:;2fI:0; #UIKL:H; #dLZL<+8Ru@V=!-hu`W=!2fu`I=h; #Iu`KL=; #dL2ZL_=+8Rud:; Z4r([: vrlh:-܂,hr"h::; O8V:;-܂hW:;2f%I:< #I%KL;(< #dLZL<+8Ru:;H<  V;`<-܂hW;x<2fI; #ΟIKL;< #dLZLL <+8Ru@V!;< hzW!;<2fI!;< #dIKL';< #dLZL8<+8Ru@Vl= 3hWl=2fIl= #IKLr= #dL-ZLZ~=+8RuO= mV=-܂hmW=2fmI= #ImKL= #dLZL=+8RuV/;=TvhW/; =2fI/;8= #;IKL5;P= #dLZLX<+8Ru@W=;h=Tf I=;= #I KLC;= #dL.ZLPx<+8Ru@W;=_ifnI;= #.InKL;= #dLZL =+8Ru;f!A;>f@fDZfP>t,= v4!6,= M!6;/2<>iפIk<̤<M</2d<l,d,dn<8>lnn4L{<`{Xx{nl{{<M{X5{n){'=ufWI=#TfII= #ץIKLO= #dLZL[=+8RuOV~= ThW~= 2fI~= #jIKL= #dL ZL:=+8RuOW=_fMI= #IMKL= #dLbZLw=+8Rut:j;%| ;;;O={ d={ ={ 7sHWX|%:>/í'a3'g'B' +xϭWX:`>|C:Wa>>̨fIa>> #IKLd>> #dLZL=?+8Ru_W{>>Df[I{> # I[KL>> #dLZL?+8Rw#> d>d>? J}s> 6T>oETnI> 6In"`>0?p1`_>|7_T>}+TI> IS>H?ɪT.S]S>`?JS.S]>ˆ>?]ӈW>?;fI>? #"IKL?? #dLZL?+8RuT ??6T ??oETI ?? 6Iˆ @"Hӈ:W @";f:I @ # I:KL@ #dLOZLd @+8RuT>>n>R#?ŝB?V?Pe?Pm??W?fwI?@ #֬IwKL? @ #dLZL?+8Ru_W?"fI? #NIKL? #dLZL?+8Ru_*>:>F>%| a>?{ ?{ @{ P&¶ζڶ 8@ 5$X@ڶζ!¶AlX@B;x@%bAVl;x@.vAloK@%u7WzOK@ OOWOzOX iQOO/OBgG N gNNaOS%O!On@%:Ot0O:OV0OUJ JN NNuv"# K4 0@#@ M#(pHK/H.6T]6X6@@T@.AU@A y #3AT)Ag@hB!fIB #[IKLB #dLZLB+8Ru`U@TG@ر+TIG@ Ih@0AF0A.Av@XA y k3A)AaOv@ `lO~@{ @hC!ܲfuXICpA #IuXKLCA #dLZL1C+8Ru`v@W@A\fI@A ##IKL@A #dL[ZL`B+8Ru`T@A+TI@A IPT@B̳mT$aTK@>| t@0B`4@0B ZMCt@\4@ ZMC@HB<ҷ ƷjU@`B% vji`B @`B ; .j!`B@4@%ZMC"S@xBpS"Sk@W@BfI@B #IKLAB #dLZLpB+8RuWSABS;Sj(AW(ACfI(A C #[IKL1A8C #dLZLB+8RuW6T9AET-I9A 6I-I9A I-I9A -I-W\APCfOI\ApC #GIOKLbAC #dLqZLA+8RwWfACfIfAC #IKLlAC #dLZLA+8RwWpADpfIpA0D #7IKLvAPD #dL5ZLWA+8Rw^B ʸ,^u"^B 3uBO^ BhDN,^"^ BhD 3aO B }BlO,B{ =BO^=BD,^"^=BD 3RBOWBf@IB #I@KLB #dLUZLjWBf}IB #MI}KLB #dLZLB+8RuWWBfIB #źIKLB #dLZLB+8RuWWBvf'IB #=I'KLB #dL<ZLiB+8Ru`WBf|IB #I|KLB #dLZL C+8Ru`ASAOAOB{ B{ 111P@CE[H`gDPhlj\q %" jr %~ D;is&' QasCDs`aI `aI DٖtAA u[ Ejx&'G cC(Ex^cq cq HE|yC: z\F\}% k% .q%A >K%a >D  WDDhEmf IDD #2I KLJDE #dL ZL E+8RuWEf< IE #I< KLE #dLQ ZLf E+8RuDDDODOD&CvAy  W EEf I E #I KL&EE #dL ZL:aE+8RuLWE#3fXIE #IXKLE #dLmZLE+8RuLCtE|E|E{ 13ExuA3'E24HtIE4IIF}  F6ҷƷ5H~U FE%v5iHE  FE ;.5!HEF4F%ZMC>FVF{ str )'& *'str '& 'S/3`Fi2%%/4' /4 %2/4'E:/5@[#/'hFya3/@\FDd/F%9FF/@eFPTF *mT,aTeF>| F +ҷƷUFF%viF FF ;.!FF4F%ZMCGG$/A CGG+GF/BFbP+GFPPCGR$:CGF/BDZPFb~aCGGaaICG 7IICG IICG -IYGR$YG8G/B 88GbPYGXGP PMqGR$WqGG/C!frIqGG #IrKLtGG #dLZL^H+8RvG:it/GwvG/Hy2G0XA\HG/Gk H$bH/JbbG!H(H/Q\q(H:HLW=H/V{fI=HG #TIKL@HH #dLZLhH H/S HbPhH8HPPHR$:HXH/SZP*XHb~aHxHaa?IH IIH IIH -IHR$HH/T.d$|HbPHHPdPHR$W%J/VfI%J #?IKL+J #dLZL;J+8RDG=/> G= PTGH mT1aT G>| RSG #]S`Ge HJit/XwvH/Y\2H0XAOHH/\oeHbPHIPP*AIR$\H(I/XkOH$ I@I/[gIGWIXI/[fIIxI #\IKLII #dLZLI+8R _GII/\)_ _/I)__Q[IPb[II/\CfxIbP[IJPfP~vIR$II/abI  bbIWI(J/`fII #IKLI@J #dLZL I+8RJI/=`[)I0Z)IwEI /h>*iI U9i>IqGJJ/=[SJ0ZSJwEJ/h,h*iJU9ihJqGWCJ/`f}ICJ #jI}KLIJ #dLZLVJ+8R@TdJ/c+TIdJ IWJXJ/cUfIJpJ #IKLJ #dLZL4J+8R@^J/etJ| WJ/cfIJ #IKLJ #dLGZLtJ+8R@FIy]lJJJ Jw} #J{ 618!J@kC!J`R!Ja!l!PTKJmT@aTQ K>| KJYҷoƷUKJ%oviJ KJ ;o.!J%KW9KJfI9K #IKLa||3|Voyo|o|PuT/{ e@L!c"_:N#_M\LRW$[iybIR"@L{~Ry S P{P PR$Uŝr = { =CKWoK[CK%pLUH L`L!L`L!L`L!`L{!!!L!L%!"L-F"P MLlP| P!MR$P!MLPz"P8MR$Lz  MFM=OMaML"L LL%| iM{  pM (Hp@EML^5T"&ML5"ML"L#7#7#Mb#M##M-#PN0M\P| P1NR$P1NHMP2$PHNR$Mz NVN=_NqNMJ$M MM%| yN{ JN\`M/Hj$#N/\NN=NNNH09i#N7O(x(09CT O7;aROpH%<Ha`O]pxM$#O<OOOaO(6pOO{ %EP*6OPlE#P\P##PM].P#P=:P;*H%@P9;#bPb0gPsPrP(WqPP{ >X, ?$?aMgu$WM]f$KLM # dL%ZL5%L+8RLI7 #I$;F \Umh__xmD5dh__x>7bu__nHBxhݐw)DB)DBC)Eݐ>)Gݐc-SIStr Sic7$g '\'UN#9D %UP|4k4%Ӝ %C9%`5.!K+5V,KӜ@ %d H%i~Py(_HMTHM>XS%N Uf%5PVy%Q%zt#X}q%^\Fzka\FzUPf}r#PMkP*PO9S%aP"a%U]PTd]%n]&W@QNYKf=&I@Q #I=&KLIQ(N #dLo&ZL&T+8RuzWUQ@NYf&IUQ #I&KL^QXN #dL&ZL?' U+8RuzWjQpNY?f]'IjQ #I]'KLsQN #dL'ZL'T+8RuzWQNYf'IQ #~I'KLQN #dL(ZLC(T+8RuzWQNY3fa(IQ #Ia(KLQN #dL(ZL(T+8RuzWQOYf(IQ #rI(KLQO #dL)ZL+)R+8RuzQ0OYQ\R\WRHOYPfI)IR`O #II)KLR #dLr)ZL)R+8Ru}WSxO\f)IS #I)KLSO #dL*ZL4*[]+8RuzW%SO\DfR*I%S # IR*KL.SO #dL*ZL*k]+8RuzW:SO\f*I:S #I*KLCSO #dL"+ZLT+K]+8RuzWOSP\8fr+IOS #Ir+KLXS P #dL+ZL+;]+8RuzWdS8P\f+IdS #wI+KLmSPP #dL&,ZLX,+]+8RuzWyShP\,fv,IyS #Iv,KLSP #dL,ZL,U+8RuzSP\VS\ U\WTP\f,ITP #I,KLT# #dL-ZLi-T+8Ru}aZ0UP`'pZ|-T0UPw+T-I0UP I-{ZBUP`Z-TBUPt+T-IBUP I-Qf-I$V0Q #I-KL0VHQ #dL".ZL.l+8Ru}`Q\f.I1ZL1Jl+8RuzQf1I{V #nI1KLVR #dLL2ZL2Zl+8Ruz Rf2IV #I2KLV8R #dLZ3ZL3jl+8RuzPRf3IWpR #LI3KLXR #dL4ZL5zl+8RuzRf5I X #I5KLXR #dL5ZL6l+8RuzRef-6I"X #*I-6KL+XR #dL6ZL7l+8RuzSf;7I7X #I;7KL@XS #dL7ZL+8l+8Ruz0SCfI8ILX #II8KLUXHS #dL8ZL99l+8Ruz`SfW9IaX #wIW9KLjXxS #dL9ZLG:l+8RuzS!fe:IvX #Ie:KLXS #dL:ZLU;l+8RuzSfs;IX #UIs;KLXS #dL;ZLc<l+8RuzSf<IX #I<KLXT #dL<ZLq=l+8Ruz Tnf=IX #3I=KLX8T #dL>ZL> m+8RuzPTf>IX #I>KLXhT #dL?ZL?m+8RuzTLf?IX #I?KLXT #dL#@ZL@*m+8RuzWXTef@IX #I@KLXT #dL1AZLA:m+8Ruz, YTf;AF YTz_?BUBGYh<@YUypOAͲYUܲAYU}Axy/Cxϳ/CLx[qECecCxJY0Ug90UrOY`Um-vCCbOYU@JccVYU@TD=DDVYDDyYU=DDyYU+5=DUp]U Dp]UM9ED]%| o%YUDzYEާgYU)UEYU)~FU6FЦY)KjFFYm)PWFmm>m m p p!@GpG5Gp$pϤHGäfG$pMHGfG-p{ OYYUg7yG-GYUFG6 Z A  HZ  ZV,H GZLHDZIDX`Z9hvqdHgH6 `Z EA dHlZ rZ0Vk IZIDXZHViqgIgI6 Z A gIZ Z`VJZIDWZxVktfjJIZV #9IjJKLZV #dLKZLKvm+8Ruz[ p[w} [VrH,KKV}K}~LWLWa\8WfLIa\XW #HILKLm\pW #dLMZL6M ^+8Ru}Wy\WfTMIy\ #ITMKL\W #dLxMZLM]+8RuzW\WvfMI\ #;IMKL\W #dLMZLN]+8RuzW\Wf NI\ #I NKL\X #dLDNZLhN]+8RuzW\XjfNI\ #/INKL\0X #dLNZLN]+8RuzW\HXfNI\ #INKL\`X #dLOZL4O]+8RuzW\xX^fROI\ ##IROKL\X #dLvOZLO]+8RuzW\)fOI\ #IOKL] #dLOZLO]+8RuzWoQfOIo #IOKL(o #dL PZL fTI^ # ITKL^Y #dLTZLU;`+8RuzW^Y# f/UI^ #} I/UKL^Y #dLSUZLwU+`+8RuzW^Y#2 fUI^ # IUKL_Y #dLUZLU`+8Ruz_#R _\W_Y# fUI_Z # IUKL_ #dLVZL=V `+8RuzW`(Z/F fPVI` # IPVKL`@Z #dLtVZLVb+8RuzW`XZ/ fVI` # IVKL`pZ #dLVZLWb+8RuzW`Z/: f8WI` # I8WKL`Z #dL\WZLW{b+8RuzW`Z/ fWI` #y IWKL`Z #dLWZLWkb+8RuzW`Z/. fXI` # IXKLa[ #dL(XZLLX[b+8RuzWa[/ fjXIa #m IjXKLa0[ #dLXZLXKb+8Ruz&a/ +a\WbH[/BfXIb`[ #IXKLb$ #dLXZLY3b+8RuzWbx[4f%YIb #I%YKLb[ #dLIYZLmYd+8RuzWb[46fYIb #IYKLb[ #dLYZLYd+8RuzWc[4f ZIc #uI ZKL c[ #dL1ZZLUZd+8RuzWc\4*fsZIc #IsZKL c \ #dLZZLZd+8RuzW,c8\4fZI,c #iIZKL5cP\ #dLZZL![d+8RuzWAch\4f?[IAc #I?[KLJc\ #dLc[ZL[{d+8RuzVc4>[c\WEd\4f[IEd\ #}I[KLQd #dL[ZL[hd+8RuzW7p/2f[I7p #I[KL@p #dL\ZL&\Sp+8RuzWSp/f9\ISp #qI9\KL\p #dLO\ZLe\op+8RuzWop$/fx\Iop #Ix\KLxp #dL\ZL\Wp#f\Ip #QI\KLp #dL\ZL\p+8RuzWp#f\Ip #I\KLp #dL ]ZL"]p+8RuzWp#f5]Ip #EI5]KLp #dLK]ZLa]p+8RuzWp#ft]Ip #It]KLp #dL]ZL]q+8RuzWq#tf]Iq #9I]KL q #dL]ZL]q+8RuzWq#f]Iq #I]KL(q #dL^ZL^;q+8RuzW;q:#Tf1^I;q #-I1^KLDq1 #dLG^ZL]^Wt4fp^It #Ip^KLt #dL^ZL^t+8RuzWt4Hf^It # I^KLt #dL^ZL^t+8RuzWt4f^It #I^KLt #dL_ZL_t+8RuzWt4<f-_It #I-_KLt #dLC_ZLY_u+8RuzWu4fl_Iu #{Il_KL u #dL_ZL_u+8RuzWu40f_Iu #I_KL(u #dL_ZL_;u+8RuzW;u:4f_I;u #oI_KLDu1 #dL`ZL`Wuu/f)`Iuu #I)`KL~u #dL?`ZLU`u+8RuzWu/fh`Iu #OIh`KLu #dL~`ZL`u+8RuzWu/f`Iu #I`KLu #dL`ZL`u+8RuzWu3/~f`Iu #CI`KLu* #dL`ZLau+8Ruz7^%} G^ۄ `^ )_ŝX_or____)___iSaŝaoaaaa)a bbib wc@ cŝcocccd))d?dEdiDmzSm?} DrO} \$E%aWe\@_f8aIe] #$I8aKLe ] #dLKaZLaaf+8RuzWe8]@faIe #IaKLeP] #dLaZLaf+8RuzW fh]@SfaI f #IaKLf] #dL bZL-bf+8RuzWf]@fKbIf #IKbKL(f] #dLobZLbf+8RuzW4f]@GfbI4f # IbKL=f] #dLbZLbf+8RuzWEf]@fcIEf #IcKLNf^ #dL;cZL_cf+8RuzWVf(^@; f}cIVf # I}cKL_f@^ #dLcZLcf+8RuzWgf)@ fcIgf #z IcKLpf #dLcZLdf+8RuzWs@/!f"dIs # I"dKLs #dL8dZLNds+8RuzWs@!fadIs #n!IadKLs #dLwdZLds+8RuzWs@#"fdIs #!IdKLs #dLdZLds+8RuzWs@"fdIs #b"IdKLs #dLdZL es+8RuzWs@#feIs #"IeKLt #dL4eZLJet+8RuzWt@#f]eIt #V#I]eKL t #dLseZLe3t+8RuzW3t@ $feI3t ##IeKLfZLbfh+8RuzW=g^D%ffI=g #%IfKLFg^ #dLfZLf i+8RuzWRg^Dj&fgIRg #/&IgKL[g^ #dL&gZLJgh+8RuzWgg^D&fhgIgg #&IhgKLpg_ #dLgZLgh+8RuzW|g_D^'fgI|g ##'IgKLg0_ #dLgZLhh+8RuzWgH_D'f4hIg #'I4hKLg`_ #dLXhZL|hh+8RuzgD'g\W~hx_Dr(fhI~h_ #7(IhKLh& #dLhZLhh+8RuzWo_D(fhKLo_ #(dLiZLip+8RuzIQs #IhWrDf)f.iIr #+)I.iKLr #dLDiZLZir+8RuzWrD)fmiIr #)ImiKLr #dLiZLir+8RuzWrDZ*fiIr #*IiKLr #dLiZLir+8RuzWrD*fiIr #*IiKLs #dLjZLjs+8RuzWsDN+f*jIs #+I*jKL"s #dL@jZLVj5s+8RuzW5sD+fijI5s #+IijKL>s #dLjZLjQs+8RuzD[Z gŝgo h!h7hLh)bhxh~hik kkH _n4Ӝs %jWj_s,fjIj` #,IjKL"j0` #dLjZLjj+8RuzW.jH`sW-fkI.j #-IkKL7j`` #dL&kZLJk;k+8RuzWCjx`s-fhkICj #-IhkKLLj` #dLkZLk+k+8RuzWXj`sK.fkIXj #.IkKLaj` #dLkZLlk+8RuzWmj`s.f4lImj #.I4lKLvj` #dLXlZL|l k+8RuzWjas?/flIj #/IlKLj a #dLlZLlj+8RuzWj8as/fmIj #~/ImKLjPa #dL$mZLHmj+8RuzWj,s30ffmIj #/IfmKLj# #dL|mZLmj+8RuzWms0fmIm #r0ImKLm #dLmZLmm+8RuzWms'1fmIm #0ImKLm #dLmZLnm+8RuzWms1f#nIm #f1I#nKLm #dL9nZLOn n+8RuzW ns2fbnI n #1IbnKLn #dLxnZLn)n+8RuzW)ns2fnI)n #Z2InKL2n #dLnZLnEn+8RuzWEns3fnIEn #2InKLNn #dLnZL oan+8RuzWans3foIan #N3IoKLjn #dL5oZLKo}n+8RuzW}ns4f^oI}n #3I^oKLn #dLtoZLon+8Ruz;iU Hi~ rioiiii)iijji is4%i\{]@khat4]o]]Ikau4$]o.]oULkaf6doa5zpLk~W5orLk$rorep2bk~5Aprbk6rpruk~5'p}k k}pkϳpLk[q!qe?qkk ":Rq.pqk MRqpqk{  [kv6&qqWkae77fqIk #6IqKLka #dLrZLCrfm+8RuzWkbw7farIk #v7IarKLkb #dLrZLr l+8RuzUn>fb9drn.8zrn~.8rrn$rrr*s2n~p8ABsrn6rXsrn~8'nsn n}snϳsLn[qsesnn ":.sn Msn{ Wne9fsIn #9IsKLn #dLsZL tn+8RuzWn%wU:ftIn #:ItKLn #dL5tZLdto+8RuzWuq%k:fwtIuq #:IwtKL~q #dLtZLtq+8RuzWq'\H;ftIq #;ItKLq #dLtZLtq+8Ru}Wq \;fuIq #;IuKLq #dL$uZLSuq+8Ru}Wq \:<ffuIq #<IfuKLr #dL|uZLur+8Ru}Wr\<fuIr #y<IuKL$r #dLuZLv7r+8Ru}Wu'\,=fvIu #<IvKLv #dL,vZL[vv+8Ru}W#v \=fnvI#v #k=InvKL,v #dLvZLv?v+8Ru}WCv:\>fvICv #=IvKLLv1 #dLvZL w_v+8Ru}}v'>fwI}v #V>IwKLv #dL4wZLcwv+8Ru}v ?fvwIv #>IvwKLv #dLwZLwv+8Ru}vu?fwIv #:?IwKLv #dLwZLwv+8Ruzv?f xIv #?I xKLv #dL#xZL9xv+8Ruzv[@fLxIv # @ILxKLw #dLbxZLxxw+8Ruzw@fxIw #@IxKL!w #dLxZLx4w+8Ruz4wAAfxI4w #AIxKL=w #dLxZLxPw+8RuzPw'Af yIPw #yAI yKLYw #dLyZL5ypw+8Ruzww''BfHyIww #AIHyKLw #dL^yZLtyw+8Ruzw BfyIw #_BIyKLw #dLyZLyw+8Ruzw CfyIw #BIyKLw #dLyZLyw+8Ruzw CfzIw #ECIzKLw #dLzZL1zw+8Ruzw CfDzIw #CIDzKLx #dLZzZLpzx+8Ruzx fDfzIx #+DIzKL'x #dLzZLz:x+8Ruz>xJDfzI>x #DIzKLGxA #dLzZLzZx+8Ruzx'KEf{Ix #EI{KLx #dL{ZLF{x+8Ru}x EfY{Ix #EIY{KLx #dLo{ZL{x+8Ru}x /Ff{Ix #EI{KLx #dL{ZL{y+8Ru} yFfu~I y #iFIu~KLy #dL |ZL8|'y+8Ru}Q QŝRo+RGR_RvR)RRRiSu SŝSoST3TJT)hTTTicUUUUUV$VVoVoVoW0WFW[WpWWW)WW)WW)`ZZZΨ[qo{ yjwHHHBhwBB__aH7IHBxhݐw)DB)DBC)Eݐ>)Gݐ/0yvTisvTK|bIy ]Ib b&}VybayIb~bY~qybxyIbb@yy Juyuuy}uy0b M_HyPbHHHwHI<ypbJUKIypbIbyb'ubybubybK+5byb ybM=y%| !zb niaT́Gzb)́b<Hzb)~HH́HhbHz)KLʂ#z{ )PL6T{ {>{ { | 1zcPt_H1z(cHHHtwHăPcO1zPc'#KPc1zPc#KPc{xcnN+K5xc{xcK {xcMK1{%| !A{c n„aT%G]A{c)%]cHA{c)~HH%HcHP{)KSOCc{{ )POy{ {>{ { { <{cPUKă{că{{ˆ{{Ϥä{M{{ }HzcS1_HHzcHHyH1wH<HzdOQUKHzd0dKz0d'@0dKz0d@0dKzXdXR+5XdKzXd KzXdMiz%| !yzd n/a[TGʉyzd)[ʉdHyzd)~H[HH.dH\z)K=Sz{ )P{S{ |>{  | | ~azd1Ta$a7Iz &TI$Iz I$Iz -I$zR$yŝzzPzP{{{{ {{ 1 #T$BI_Tpw B BK T0|2}\O p7 }\a3 \/ \ dr\. \J{TW| UTTTҋڨW| o|1%o|d UOBP|e UPP|R$P| e VPP|R$~a|@e Va(aI| VI(I| I(I| -I(|R$P|`e VP<PT}R$~a}e \WataI}e QWItI}e ItI}e -It}R$P}e WPP(}R$4}f WH},JPI}f WPߌP[}R$~a[}8f fXaaI[} [XII[} II[} -Il}R$Pn}Xf XP'P?}R$~a}xf "Ya]aI} YI]I} I]I} -I]}R$P}f VYPP}R$W}f YfI}f #YIKL}f #dLZL+~+8RuT>}R [>I}<[kڥΥ}<}<>}<~? ?a}gguގW}g]fގI} #ZIގKL}0g #dLZL8}+8Ru}V}x}} ϤäÏ} MÏ~{ W8~ 1\f֏I8~ #[I֏KL>~ #dLZLN~+8RuTT|IO\PwRu |ŝ|1}.~]~6~{ 1117Gp~ /wO p7 '| /wPg$w 4w+p \F_1 %m~  2]mWpg ]f<Ig #q]I<KLg #dLؑZLU+8Ru~W,g &^fI,g #]IKL2g #dLZLȒ+8Ru~<`:  ^K`_:e^_TD+TfID IfWh _fI0h #^IKLHh #dLZLȓ_+8Ru~W`h _fI #W_IKLxh #dL ZL,o+8Ru~"`  `1`J_|__^T}+TvI IvWh `fIh #I`IKLh #dLZLؔO+8Ru~Wh `fI #`IKL h #dLZL<?+8Ru~Whi xafZIh0i #=aIZKLqHi #dLZLs+8Ru~Wy`i afIyxi #aIKLi #dLĖZL̈́+8Ru~Ẁi lbfÌi #1bIKLՀi #dLtZL݄+8Ru~W݀i bfI݀j #bIKL(j #dL4ZLV+8Ru~W3@j `cftI3`j #%cItKL<xj #dLʘZL +8Ru~WDj cfPIDj #cIPKLJj #dLpZL+8Ru~~adj fdaaId [dIId IId -ItR$Wtj df&Itk #dI&KL}0k #dL|ZLҚ/+8Ru~Hkoi %hko` 9wkop @> D`y T^ e^E6TMETI 6II II -Iȁk 0fTȁkU+TRIȁk IRWk ffIl #ofIKL l #dLZL-+8Ru~-0l fKA,JPBPl gPPߝTR$~aTpl gaaIT gIIT IIT -IfR$Pfl gP;PxR$Wxl >hfIxl #hIKLl #dLҞZLۃ+8Ru~Wm hf,I #}hI,KLm #dLuZL˃+8Ru~^ i^ܟTX+TI IW0m ifIPm #NiIKLȂhm #dLMZL+8Ru~Wm jfIm #iIKLm #dLZL+8RuPm 7jP0PhR$Wm jfIn #vjIKL n #dLZL+8Ru~W&8n +kfI& #jIKL,Pn #dL3ZLb+8Ru~W4hn kfI4 #jkIKL:n #dLZLĢ+8Ru~W4 lfI4 #kIKL: #dLZL F+8RuWF lfIF #^lIKLL #dL4ZLIX+8RuWX mf\IX #lI\KL^ #dLqZLj+8RuWj$ mfIj #RmIKLp #dLZLã+8Ru~nf֣I #mI֣KL #dLZL+8Ru~W znfI #?nIKL #dL(ZL=+8Ru~W nfPI #nIPKL† #dLeZLz҆ SofI҆ #oIKL؆ #dLZL+8Ru~ǁ-Ԇ>PgWfMeW9n :pfʤI9n #oIʤKLBn #dLZLx+8Ru~Wv pf.Iv #ypI.KL| #dLCZLX+8Ru~W  qfkI #pIkKL #dLZLW qfI #YqIKL #dLZL+8RuW rfI #qIKL #dLZL+Dž+8Ru~WDž  srf>IDž #LrI>KLͅ #dLTZLiWхo rf|KLхo #rdLZL܅+8Ru~I #I|W gsfI #,sIKL #dLϦZL+8Ru~W sfI #sIKL #dL ZL"W Gtf5I0o # tI5KL Ho #dLKZL`"+8Ru~W" tfsI" #tIsKL( #dLZLW 'ufI #tIKL! #dLƧZLۧ0+8Ru~W0 ufI0 #fuIKL6 #dLZLWE uf+IE #uI+KLK #dLAZLVWa" mvfiIa #2vIiKLg #dLZLv+8Ru~~~P~T]vTT=VhT̀T!3TcQ9P`P{ 1::8gO p7ٖ `ou \F~aۇo xaaQIۇ xIIۇ IIۇ -IR$WBo xfdIBo #XxIdKLEo #dLZLGP+8RuW\p yfuI\ p #xIuKLb8p #dLZLg+8RuWPp yfتIpp #LyIتKLp #dLzZLt+8RuWp zf2Ip #yI2KLLjp #dLUZLw+8RuWp {zfIq #@zIKL q #dL5ZL+8RuW&8q zfI&Pq #zIKL,hq #dLZL1+8RuWyq o{fOIyq #4{IOKLq #dLծZLE+8RuWq {fsIq #{IsKLr #dLZLӋ+8RuWۉr c|fկIۉ8r #(|IկKLPr #dLEZL+8RuWhr |fIr #|IKLr #dLZL'+8RuW2r W}fEI2r #}IEKL;r #dLZL+8RuWDs }fIDs #}IKLJ0s #dLAZLc+8RuS } ~abHs }~aaIb r~IIb IIb -IsR$W`s ~fIs #~IKLs #dL[ZL3+8RuQ=i %[){Њ{ߊ\~as a߳aI I߳I I߳I -I߳ R$Ws Cf2Is #I2KLt #dLrZL@+8RuW" f̴I" #I̴KL( #dLZL5+8RuW5  #f I5 #I KL; #dLZL3W@ fFI@ #bIFKLF #dL\ZLS+8RuW^ fI^ #ہIKLd #dLZLȵq+8RuWq f۵Iq #UI۵KLw #dLZL+8RuW fIt #ςIKL0t #dL.ZLC+8RuW pfVI #IIVKL #dLlZLWÌ fIÌ #IKLɌ #dLZL֌+8RuW֌ PfѶI֌ #)IѶKL܌ #dLZLWHt ʄfKL`t #dL#ZL8+8RuI5 #IW DfKI # IKKL #dL`ZLu +8RuW  fI  #IKL #dLZLW" fŷI" #IŷKL( #dL۷ZLWH# fIH #OIKLN #dLZL-[+8RuۇP0BTtX(oTوhoT>'RogyTɉۉT  2TbQPPP\{ uHp͛O p7V ͛xt›x ! \F~a׍t$ `a@aI׍ UI@I׍ I@I׍ -I@R$WGt' ؈fԸIGt #IԸKLJt #dLbZLҹ֒+8Ru`Wau' PfIa0u #IKLgHu #dL#ZLE+8Ru`W`u) ȉfcIu #IcKLu #dLZLa+8Ru`WƎu) @fIƎu #IKL̎u #dLZLԻ+8Ru`Wu, fIv #IKL(0v #dLZL+8W1Hv, *f=I1 #I=KL7`v #dLZL%d+8RuWxv- fCIv #iICKLv #dL߾ZL\q+8RuWv- fIv #IKLv #dLZLο+8RuWw0 fI0w #]IKLHw #dLZL+8RuW`w0 fI #׌IKLxw #dLgZLJ+8RuWEw2 fIEw #QIKLNw #dLZLW+8RuWWw2 fIW #ˍIKL]w #dLZL=+8RuWx6 fI0x #EIKLHx #dL6ZLX0+8RuWǐ`x6 fvIǐ #IvKL͐xx #dLZL#+8Ru~ax9 aa.I {II II -IR$Wx9 fNIx #ŏINKLx #dLZL,+8RuWLx; zfILy #?IKLU0y #dLTZL+8RuW^Hy; fI^`y #IKLdxy #dLZL+8RuDDi> % ƑX(Ƒ>w͑~ayB Бa>a~I őI>I I>I -I>R$WyB JfIy #IKL y #dLZL ƒ+8RuW3- Ēf+I3 #I+KL9 #dLAZLVF+8RuWF - *fiIF #IiKLL #dL~ZLWQB fIQ #iIKLW #dLZLd+8RuWo0 fIo #IKLu #dLZL(+8RuW 0 f;I #\I;KL #dLPZLeWy9 fxKLz #dLZL+8RuI8 #IxW, ufI #<IKL #dLZL+8Ru`W) fI #IKL #dL ZL6Ó+8Ru`WÓ) SfIIÓ #,IIKLɓ #dL_ZLtW֓6 ͖fI֓ #IKLܓ #dLZL+8RuW"6 GfI # IKL #dLZL+8RuW 2 fI  #IKL #dLZL++8RuW2 'f>I #I>KL$ #dLSZLhWN; f{IN #fI{KLT #dLZLa+8RuWa"; fIa #IKLg #dLZLx+8RuW', fI #ZIKL! #dL ZL8+8Ru`W' fKI #ҙIKKL #dLaZLvWǔ+' qfIǔ(z #8IKLʔ@z #dLZL+8Ru`P׍P?o5GTyoTގߎoTYoTϏPwяT 3ETzeoTߐ͓Q#:LTPPPm{ ]H8A,-9V , %Xz D ~ ~O1 4 ~'z @~6bWl-@fIl #ŜIKLu$ #dLZL@+8Ru~*2fZz D [SZ~ ŕz1 ωŕzމ]{;0{#?'gVMgX{#?yMeMRM-#?AM-Mp{͞{cĉ8t>{cs4>{ ZMCsL'Lz"3W{3 fI| #IIKL | #dLZLۘ+8Ru~җ8|1 .`|5Z;Wx|@8fI #IKL| #dLZL%+8Rw|L"@LC?R?N5ȠuaLK|#;MLMa|#;AM-M-L|5L{ˆ| ӈW};fI8} #DIKLP} #dLsZL+8Ru~ˆh}4 ӈW};fI #١IKL} #dLZL_+8Ru~ˆ' ӈ}W';f}I' #nI}KL0 #dLZL?+8Ru~ˆ?-4 =ӈW?-;fI? #IKLH$ #dLZLW+8Ru~W!3 f-I #|I-KL #dLCZLr +8Ru~GŶXNJ w} } X+ җ ~ $`{ { ]H=#vݐ ݐwvݐvݐCvݐi c__nc__s'BEj Hݐxhݐw)Dݐ)DݐC)Eݐ>)Gݐ]i2#KhPGc__xGK}XQ\5&}LӥIaU&}M #71^}S٦h[NZ^}^}_ })b^}V,U}S~SSS ~W SSW8~WfIX~ #HIKLp~ #dLZL;+8RucWe&WfYIe #IYKLk #dLnZL{+8Ruc[~@B^Ej=`EjVa[cnb[c'v~_ӨF~rb cc%1~`[N~a+75~c Mcw%| 5iIaUM # rQa? ).are )#a  1 )~aפO xЦ()K6 )P- >   PHy%t?PH).%rtePH)#%t H1PH)~%tפHFЦ`)K_nR )P0R ]>R e  1խڥ\Υ|1\|1>1~?\ ?axguWx]fKL #dLZL+8RuHI #Id' Ϥä; M;{ ήڥOΥnOn>] Ϥä M{ YMhrW fI #ܯIKL #dLZL+8Rud   ) { g_wh__xw7P  %S %dcHxY %bdbbvnuu]u}u] šq0 = # &L TY 'h /AAšHfgAZAPANx _NQNNI CTI%<$4P7i_5?IaEUZ?M #EZP W\${fmI\ #BImKLb #dLZLv+8RuLAAȀgAZA PAMN  N|N NMI CIM̞<$Pi_)5ěIyaUěM y#՛ W*fI #IKL #dLZL+8RuWdf"Id #iI"KLj #dL7ZLdz+8RDWfwI #IwKL #dLZL+8RȚ~uȚuuȚ}uxb{q΁(g(΁Hi@H΁ `h`&>_>QڥΥ>~? ?a*guW*]fKL*Ё #dL;ZLhW+8RuI@ #Icc<lcg Ϥäg Mp{ \3WsfIs #IKLy #dLZL+8RXb /ccW84f0IX #RI0KLȜp #dLNZL+8RX9ٺ0> 9ļ>]C]ڥΥCC>C~? ?aȂguWȂ]fKL #dLZL*G+8RuI/ #IYHYjY] Ϥä] Mf{ h0hhh1hhh2Bhh/W3fCI3  #ICKL68 #dLXZLL+8R@W~42fI~ #IKL #dLZL+8RXš i%| ..͝.Zٞ{ b{  2P'hb<,WUAKjaTBp[ YdU WgпfIg #IKLrЃ #dL ZL,ȟ+8RugW̟!fuTI̟ #IuTKLԟ #dLjZL+8Rug@ŝ{ ,|Ϙk{{ ̽'%c"k:N#kMSMs SS[W[sfI[  #IIKLd8 #dLQZL+8Ruc%pPw4xh$.{CڥΥ{C{C>{C~? ?aguIW]fII #IIKL #dLZL+8RuPix %W؄yffKL #IdL%ZLG<+8RuLI# #IPyiu_5IaU M #  Wy{fudI #BIudKL #dLZLI+8Ruc:#^fM:^q { /!c":N#M q̽<%c"k:N#k,SK0sS\SZWZHsfIZh #IKLc #dLZL2+8Ruc%owH4Pw$.hzЅڥΥhzЅhЅ>zЅ~? ?aguW]fI #IKL #dL,ZLN+8RuTix %lW@yfKL` #dLZL-+8RuPI #IPywi _O5lIaUM #u WyfudI #IudKL #dLZL+8RucPuTv2$u "#F2NKRPwu FY { / !c":N#,<$:`8:D::gN>]>WfvKL #gdLZLM+8RLI7 #IvCKW/[CK%Bиh__x>rB}2__n0H$uxhAw)D$u)D$uC)EA>)GAz؆.E"Wn;e1]0 ]`@E,TuP ] %TuP]TmpȇxBpȇMQg5[%| %t, uPgk@ggg\DU )@4(N2)~g[Ou)!)KYs~S1~'~[ )P{o  $:   @& ߯: Z  ͯm   Mm  {   z 4HPWP`=h .SR%| { { { PA AwAACA__ny_g__nV__s'BaHAxhAw)DA)DAC)EA>)GAhPG&__xG@XQATx~)(L~ ~ ~ <~)(MK~ a~ U~ ~-$ 1~; '~m H~W`Q1~'~ y|xS*   |x  S|x_  zx= |xV2u % xA  &$ F SSh S{  W|& SS SW Wf I( #I KL@ #dL# ZLE +8Ru[&Wc W&fx I #fIx KL #dL ZL +8Ru[XxB^=` VanbFPp_tvi9_epgPgg%S`}p/a!Vm/xB/MQg[8%| x~>؉i~~~<~>؉MK~a~U~~F 1~'~ctir8 |i).i\ OB|i) |i)~  x!)KK~|S1~'~[x )P{ox $:D x  t0yE0).i\OEB0)E00)~E0!)K_~S1~'~X[ )P{o $:   2[2{o2$:2~D:8: :`gN'`]'W`f_KLx #dLZL-+8RuHI #I_߯WW^ ͯ^ Mg{ $[{o$$$:߯'y8'. ͯd. Md7{ ЇPOۇxPMÇxP xWPfIP #IKLY #dLZLi+8Ru\  ? M  {  BH)PJ.H+lWjp?f:jI?UP<SPP7R$P7(<P(PIR$sۀ T=\H h@Cw@N@]@@55xK"ߡ;`1Ћ;g@gg @r.r . "(%."HHmPxZBPMQg[Z%| %\QhD Qh)@4(hNH2Qh)~g[Othu`!)K~dS1~'~~[ )P{Wou@ $:  £ £@uL߯ȣ3ȣ̣ͯFf̣MFfգ{ yz ȢܢPP= Sڡ%| { 1Ї͠ۇ͠MÇ͠ W͠fI͠ #IKLӠ، #dLZLT0+8Rudߠr<ߠKWP8HP0 PR$PPHPX PR$ =[ep p<P{ c{ x{ m \qqH%5JX"\FcU %?'<(P.H'1?': % uAPWUhEmsg/l ? L:0iZP0b~a0aa I0 \II0 II0Ѝ -IHR$WQp f)!Y:hYwa!Ng]!ogo g!g!0O!C"0bͥPΥH""HbPh#K#hbPni %#h2w#N]# g Ў\g $g $IZ $h@wI$N@]$@$ %+%+%IP"h;X%1%,&b&g,@xgg;@&&d';& d' [%&d'[ & m`(x'B`(MQg'['t%| ^%\@D (S( @)@S(4(@N(2@)~gS([O(@u )!)KtJ)~S1~'~)[ƨ )P{)o)ƨ Ѩ$:ƨ ٨ # #@)߯)) *)- ͯ3*U*- M3*U*6{ hh*z P+P4=<TIS %| D{ gR&ggl**bPpP*P*~R$:~LZ+P:+b~a~a+a\+I~ ?I+I~ I+I~ -I+R$(++(bPHP+P+R$:prZ+P,pb~aa+a4,I eI+I I+I -I+¦R$W¦fY,I¦ؑ #IY,KL˦ #dL{,ZL,R+8RvWp!bf,Ip #)I,KLv #dL,ZL-+8RPkT+T-I I-_---=..WDhf/I8 #/I/KLP #dL/ZL*/+8RwWDf=/I #I=/KL #dLR/ZL/+8RLդ`T2+T/I I/Whf/I #qI/KL #dL0ZLi0+8Rw_ 0h<j 0*ij U9i0tqG[00bP:ВZ0P0Вb~aa0a 1I I0I  I0I8 -I0R$D/1<G1*iU9iG1qG6f\1I #I\1KLĩ0 #dLq1ZL1թ+8RL0y]=_5~ I~  { 11 BgzuAgWvPnf1Ivp #I1KLy #dL2ZL?2+8Ru_Wnfm2I #NIm2KLؓ #dL2ZL2+8RvWϪnf2IϪ #I2KLժ #dL2ZL3+8Ru_Wnwfu`I #>Iu`KL #dL"3ZLO3+8Ru_-ITDk0bv{ ;_5PH%G XjPb3_jP_b3_j_3Tx+T3Ix I3p,3*iU9i3qGG3G3ëŝ);4ؔW4 4W4Wf4I0 #I4KLH #dL4ZL 5{+8Ru\ŝ{ _*5*iU9i*5qG);?5T5¬NXj_լWhJf5I #I5KL# #dL5ZL5/+8RwW#f5I #I5KL #dL5ZL 6+8Rw{ /)j  /i&'70 p z {TTT 6TB6ڨ 1*2 f6\< 6bDؕccSm66bPSP6P6!R$b`8cccpP!c+c6sh7-7hbPvP7PA7R$:ZPe7b~aЖaay7I II II( -IR$@. 77@bP`P7P7R$bڭ#7x8ڭ#bPڭP7P8R$@  98*i@ U9i98MqG  e8*iU9ie8qG9@y]Wt y88bjP:j3 Z8P%9b~ajЗa8aQ9Ij & I8Ij I8Ij( -I8R$b@u u9x9@bP:`4 Z9P:`b~aa9a4:I ' I9I I9I -I9R$ v X::b®PĮ  ::b׮P׮ؘ   ;X;ؘbP#? ;*i#U9i;+qGW+  f;I+@ #~ I;KL4X #dL;ZL;[+8RDW_0 f<I_ # I<KLe #dL<ZLF<u+8RWu Y<*iU9iY<qGU _!~{ { 17( is(  ) Wp+e fm<I #, Im<KL  #dL<ZL<+8RuW>Q+P >< ;  =ڥB=ΥU= ;B=U= ;> ;~?B= ?h=a7șgu=W7ș]f=I7 #] I=KL< #dL=ZL=N+8Ru[ >[->I>[_ Ϥ\>äx>_ M\>x>h{ W+ fuXI # IuXKL #dL>ZL>+8RuWI PvRu { 1~9o#V $~S#w ~S ~S #0w #-## R~S/w ~S ~S / __x 9`  Vis    l>RM>W G p1?f7 : I1?P; U]?Pڲp< P?PR$P< P?PR$ۀ ڲ =  .w ?;@8v9 @;n96Tn@Jn\CК kFA;nCК$TnFAJn I H ^A; A. AbI ^ b^Ab;BVV W8  j BbW`- bBb'Cgix- CCbix-bCbCss-  gDWsZfDIsЛ #Y IDKLv #dLEZLE}+8- FWZfFI # IFKL  #dLFZLBF+8Rudw 8   UF    UFFb -܂bUFbFǐX J ؐFp-܂ 0GWZfGI #  IGKL #dL*HZLsH+8Ruǐ  ؐH-܂ HWZfHI # IHKL #dLHZLH+8RuKǐȱ  ؐHȱМ-܂ HWȱZfIIȱ #y IIKLα #dLIZLI+8Ru@ֱ J  IWֱ0ZfDJIֱ # IDJKLܱH #dLJZLJ+8Ru@   KWZfKI # IKKL" #dL#KZLPK.+8RuTǐҴ ؐcKҴ-܂ cKWҴZfcKIҴ #N IcKKLش #dLxKZLK+8Ru`!  KWxZfKI # IKKL #dLKZL2L+8Ru@W fPLI #` IPLKL #dLLZLLг+8Ru@v M;n6TnOMJnf%؝6 MuMS)SMS8N3W3 fNI38 #u INKL<P #dLNZLO+8Ru@Dh !O<DhKIOWhOPwH) POPR$PHY POPR$T w=r О  O P. 1P̆IPuPd.Ms1PIP}uP::2 V:PL:PW} fPI} #o IPKL #dLQZL#Q+8Ru@>PK;b 6Qm<.  NQW.ZfNQI. #G INQKL4 #dLcQZLQ@+8RuTW@ fQI@ # IQKLF #dLQZLQR+8RuTR# Q]<W fuTI #b IuTKL  #dLudZLR+8Ru@߰ ,$e{ z{ { 1~90  r H r (g is6\5H9#Rt7H LR47H ZMCLR^Mh ,^R"^RMh 3RReOWV fRI # IRKL #dL9SZLuSص+8Ruc^П ,^S"^SП 3SSO^ ,^S"^SW\ fudI ## IudKL  #dLTZLHT+8Ruc !{ ~9$  BX  11o(0  .Hkey / w 6  [T T TW¶ fZUI¶ #l IZUKLȶ #dLoUZLUض+8Ru_P^L`l ^`UWl0I fUIlP # IUKLoh #dL'VZLcV+8Ru_WfVI # IVKL #dLVZLV+8Ru_l { { 11*6 keyy6 /y; % 110! key~! /~ %Р! /TaR ad aVbc=WK fYWI( # IYWKL@ #dLWZLW+8Ru[W` fWI # IWKLx #dL XZLdxbPЦP>dPvdR$E+ dbPPdPd4R$ _4@+ )_c_eh+ )__JePTPfT, _e|bPTP_ePeoR$ _rZ, )_e_eاO, )__;fּPP, PfbPPPfPxfR$8 - f 8bPXPfPfR$G- gg]bPPgP(gջR$ջȨ- Xg ȨbPջPXgPgR$I. gbP(PgPgR$9. h*i9U9ihAqG-. *h*i-U9i*h7qG{P{P%/_7'aZHpZ}ZTHw+T?hIH I?h?{ S{ Vp^/ 4 a '`4 5nhP?Dh6 / A h x"0 EpH i 4 Xj_0 _7iy_Vi@_ЩY_iO_iJ0 iibPMPiP'jbR$ _b r1 )_Gj_ojPb8PjPjaOb`f1 lOjj{ {R$e {x1  j{ xbP~PjPjR$WK2 fkIЪ #2 IkKL #dL0kZLhkg+8Rw2 k*iU9ik qG) 0}3 ;k Pk p kkW8f3 f lI8 #,3 I lKL= #dL*lZLLlx+8RuD"ŝN{ W3 fjlI #3 IjlKL #dLlZLl+8RuS84 l*iU9ilqG)!}4 ;l!lJ Ծ_c~  | ν "H ¿{  п16 '1?uA16 W5 fmI #[5 ImKL #dLhmZLm8+8RusWA 6 futIA #5 IutKLG #dLmZLmW+8Rus`{ 1;9 IT 'H:'omp'' # ?6 Io.B6 {o;nnosnaooz(8 eH9 GoW(Kq7 fZoI@ #87 IZoKL #dLmoZLo+8RucWK7 foI #7 IoKL #dLoZLo+8Ruc  8 Pv4   W#XO8 fpI#p #g8 IpKL, #dLpZLBp<+8Ruc8 9 W _  W_OG9 fUpI_ #9 IUpKLe #dLjpZLpu+8Ruc^vlv{   9 PvR0#4 A z { { 9 }#\I `9 :  n :  s!   p#`O: 66 i66  )66 h> ITH '::'opp'' # ? ; o.BA; o qoDqoqЬ< eH> rWK; f+rI #; I+rKL #dL>rZLkr+8RucWKJ< f~rI #< I~rKL #dLrZLr+8Ruc j< Pv4   W%O= frI%0 #< IrKL. #dLrZLs>+8RucH0= "> [ c  WcO= f&sIc #o= I&sKLi #dL;sZLhsy+8Ruc^vlv{  = PvR0%4 C ~ { { 9 \I 1`NC> ?  vs>  " / < ` {s` s" s/ s< t# > W >  XsX+tW` % %?  XUtXhtT:  iA66 IT C ITJ '5A:' p|tp'' # ?@ Dp.xB<@ vptipt\puzA eHC uWK@ fuI #@ IuKL #dLuZLv+8RucWKIA f2vI #A I2vKL #dLGvZLtv+8Ruc iA Pv4   W#OB fvI#ح #A IvKL, #dLvZLv<+8Ruc/B !C W _  W_OB fvI_ #nB IvKLe #dLvZLwu+8Ruc^vlv{   B PvR0#4 A z { { 9 \IK [BC D Z lC f s  Z /wf Yws w w# C W  C WYwWgx D  xm3|u [)W GD WxWxH? PTT? !D ٖN5AD envr@D envs@E  %7P% WD2E K  8E         '_} XK  yX 0y y y y Tz hz z x0F  {x 9{ f{T[PF [{{J  {Ȯ | ^%G  N|gt^%tt|"t^%(YtLt?t|D h D }u|EnG  &}nE(<}D  D }0A(H % }0"H *} }0"7~8l2R`l~Ul}Jl-~d9/,d,d^K jQ H ' C~}Z ~C~}$}C~}2 H A Y~}H}Y~}6}o~}L J[I  v i  >I Κ(D  D ~sN(I t~sN(@s~ I s~w[EI [~ZgVjD @mJ D ~@E ŝWkPzP=P=P  `J  3 ST'i*TnU5LY a~-T7{ N ITҶ% 'D:'qip'' # ?K Cq.xBK xqkq^qM eHN WKXL f̀I #L ÌKL #dL߀ZL +8RucWKL fI #L IKL #dL4ZLa+8Ruc L Pv4   W%دOM ftI% #NM ItKL. #dLZL>+8RucM N [ c  WcO.N fǁIc #M IǁKLi #dL܁ZL y+8Ruc^vlv{  pN PvR0%4 C ~ { { 9 \IN N N A 'P DCN O N H%,%%O Q .H P I%<'YO YI II -I7 9 -O P :F kN W8YP N ~lk YP)9P Y=<N h)P N N ̂6N Z P  [Z~   ~ N  YP N MO k QK { pQ *Q h__x*Q lB))GQ X .HIX X l8WmR pfnQ :IaR UP< R PTPR$P0<:R P|P!R$#ۀ ,=4*6 h9HV wN9H]9HHkhS "V ;1رTg@rS gg(@|T ƆS Ɔ  0%PPmXxBXMQg[%| q%\$pDU :f $p)@f4(pN2$p)~gf[OȈpu0!)KnU ~4S1~'~IN[ )PU {Wou@ $:   @uP߯gͯM{ V ͉tz PP=|T hS%| g{ Q qW Q Q x~+W ~~!~@<~+MK~a~!U~@~' 1~o'~ȲX <ȲKW9PWH*X P{PoR$Po(HZX PPR$ W==GR<2{ E{ Z{  BH X "Y q '  %uA "Y I A_5X tCY T\ X X X Y  @I\ Y T^ h Y p Ӌth4h ZMCS Z S}SW Z fHI #QZ IHKL г #dLZL֍H+8RuW# [ W#f0I#( #Z I0KL,@ #dLlZLW+8Rwa [ ƎWafێIa #x[ IێKLg #dLZLs+8RuWW~ *\ fuXI~ #[ IuXKL #dL0ZL]+8RuWy]#/Q |{  /e\ u\ Fu\ 8^ H8xh8w)D8p)D8C)E8X^ >)G8 p)K6^ "ϏT\ $So\ 0e\ YW~/] fwI~ #r] IwKL #dLZL+8RugW/"^ f̐I #] I̐KL #dLZL+8Rug8M\)P^ !?c~!wSB gV   { #_ 8 8wv8v8Cv8$ /0_ @_ F@_ 8~T_ _ Sc__nx__s'B5|~_ Wo dPGx__xGWo дf XQ3L!&Lpa 5MבA&M בT\ * o\ /e\ ^Wy/` fIy( #` IKL|@ #dLZLɒ+8RuTW"/[a fܒI #"a IܒKL #dLZL+8RuT?TcT\ rXQb o\ 1e\ vW/b fI #a IKL #dLǓZL2+8RuSW2@/b fI2 #Nb IKL8: #dLZLID+8RuS^ ^SCd _ \_ ^ ŔA^\uhŔ^_\Ŕ^ٔI^Vs`fŔ^ȕ_ ::_ ە0_ S/c S9SLS/ d SySؖS /SSY_ !еWe :_ 0_ S'/d SҗS:SG/d S$SFSSX0/SfSd]dPWf ]Wdp/e fʘId #_e IʘKLg #dLZL+8RuSWwȶ/f f,Iw #e I,KL} #dLNZLp+8RuSW/fI #If IKL #dLZLҙ+8RuS(8o B^5=`5Vazx%nbzxiE_ H_]g k_ ^_ TT_ Hz_ 9c9g HcHc%wp`g 5a h grɜ~<MKɜaݜU%| !ii 5MAuM uT\ ȷ o\ Нe\ +W*/i fjI* #h IjKL- #dLZLB+8RuTWB/}i fIB #Di IKLH #dLԞZLT+8RuT(+rAj *L+).L4+)i]LQwx>z\ A(yj *ٟA().ٟ4A()i]Qٟ(wSz\ aHm 1ܠ\aHHcaH~woBi`gV]i`]]Wi/l fРKLi #k dLZLH+8RuI #IРW/l f[I #Ll I[KLȸ #dLZL+8RuW/fסI #l IסKL #dLZLB+8RuŸm џ۟` sb Mq{s{ Ÿin џ۟ibiMq{t{ n ܠc~wB(gV n v M_ |   w  { M{ { 8|ko o d__xo 9r Do q HDq \o @Eyq uo 0ko ~!`nq 5MA$`M $T\ x o\ Be\ W=/p fI= #p IKLC #dLZLP+8RugW[/Yq fv I[ # q Iv KL^ #dLZL$v+8Rug-_ Y{ 8!$q q Gq o 86q s VjUs \o s uo 7ko !s 5ͥMAGMͥ GT\  o\ ee\ WQ/+s fŦIQ #r IŦKLW #dLڦZLd+8RugWo/s fv Io #is Iv KLr0 #dLZLG+8RugA_ m{ 8Js Ft >VFt ['t [Z/q 8Hv {!/n!!tHut 4H ZMCt`gu 4` ZMCxwu uxuux}u$4ׂ D\tׂ ׂ %ׂ 5M1e1}1ׂ ׂ {P-=Mׂ ]yׂ ׂ ׂ NFpFpFpV*10@0O0^0m0|00000000011)1d61ӏE1 ӏU1 JGe1 s1 1 1 ӏ1 m1@111 %28Ictv H ӏg ӏO v> v - n' d) P9 dI PY i dy 8  v v %6 PG t'%]z ' Kz XitLRTI/JG9L( ",$)FC4ON4829Q92\9yGr<FF@I</s7C{ *8{ *jצ %{  % +BFj %{ 'm Q%| ' F %%| *&''m4779*>| #*[| ' %E5gG %u| u| >vE / %| '' ؅ %| ''EwJ %| M(M(v$k%W @Fs %| D'' uFZ %} D \  %%}  %5 %9} 9} v,EO} 9} <+_} 9} o %w} 'EF %} DRS}*} *uQ%'.Q%} u&'&'D)W}  %Rp*~ '' 2FD ~ ''EF %5~ DK*I~ Q%)c~ **d &'y~ 'Es %~ ''&' *~  %~-=m2: eD*~ ' %  %~  %'S 3@ % '4d7PO** *H * %'{7H] * þ\*x *&'2]>  vFW * ]6 %  '&'  %v vߕ uF % DX% % YFX% D K*F&': *&'&'D \ %U  % % \a %k  %EXF % 'Enx %  %EڔK  v+v n N\nВۀ  %u&' jo %  vwEoގ V\o %  o %/  E)pq %N  % % %E`p %m  %m vs > ck % ''I@ vC@k C@ nk'́  % o^ % - Hoa* - 1Wk % *jdup\ %$  % o %?  ? vE  GFd %f D'mEn %{  %vector::_M_insert_aux* *( %^oY %т т dv-4 % d** D$F2D  %' 6HF= %+  %DH %H 'D\[[  % 7\hВ{  %*&'ECq : % R\ % :wR\ f\ %҃ ' za\' % '9D9DEph % uuQ%}F)**= u55 %`R*e *u'E 2nv %z  % :+od % -uE6* ' (@b %ʄ  %ʄ Մ vЄ 4v4wm\ %Ecr9* *&' % % %؍EsQ %: : * %*mvE'rL %Z *&'Eb %o o vE{Tt %  % %mj( * @]2 %  ' %.F&'u&'&'D% U$ > 9: ; : ; : ; : ;  : ; : ; (  : ;  I8 9: ; .?: ;I</II.?: ;I<: ; I.?: ; n<&I.?: ; nI<.?: ;nI<.?: ;nI<.?: ;nI<: ;I.?: ;n<.?: ;nI< : ; I8 2 : ; I2 .?: ; 2 <dI4 .?: ; 2 <d! : ;I8 ".?: ;<d#.?4<d$ : ;I?2 <% : ; I8 & : ; I?<'.?: ; nI<(.?: ; nI<d).?: ; n<d*.?: ;n<d+.?: ;nI<d,.?: ;nI<d-.?: ;nI<..?: ;2 <d/.?: ; 2 <cd0.?: ;nI2 <d1.?: ;nI2 <d2.?: ;n2 <d3.?: ; nI2 <d4.?: ; nI<5/I6<7 : ; 8<9 : ;2 : : ;I?<;.?: ;2 <d<: ;I2 = : ;I?2 < > : ;I?2 < ? : ;I?2 <@.?: ; L 2 <dA.?: ; nI2 <dB.?: ; nI2 <dC.?: ; <D.?: ; <E.?: ; I<F.?: ; I<G.?: ; <dH.?: ; n<dI/IJ.?: ; nI<dK.?: ;nIL M2 <dL.?: ;n<dM : ; N : ;O9P4: ;I<Q:: ;R : ; S.?: ; nI<T.?: ;2 <cdU.?: ;L 2 <dV : ; 2 W : ;X : ;2 Y0I Z : ;I8 2 [.?: ;nI2 <\.?: ; <cd].?: ;<cd^<_.?: ; 2 <d`.?: ; 2 <cda : ; 2 b.?: ; n2 <dc : ; d : ; I8 2 e.?4<df.?42 <dg : ;h.?: ; n2 <di.?L 42 <dj.?: ;I<k4: ; nI?<l4: ; I<mn.?: ; n<o$ > p Iq : ; nr : ; s : ; ItIu!I/ v Iw.?: ;I<x : ; y9: ; z.?: ; I<d{.: ; I<|:: ; } I~.?: ; I<  : ; n : ;  I8 &! : ; I8 I: ;  : ;I 8  : ;n9: ; : ;.?: ;2 <d : ;.?42 <d: ;I2 .?: ; nI2 <.?: ; <d.?: ; n2 <d.?: ; nI2 < : ; : ;I : ; I?2 < : ;I8 .?: ;nI2 <.?: ;nI2 <.?: ;nI2 <d : ;I?2 <  : ;  : ; 2  I8 42 .?: ; nIL M2 <d.?: ; nL M2 <d.?: ;n2 <.?: ;n2 < : ;.?: ;nL M2 <d.?: ;nI2 <.?I4<d : ; : ;2  : ;I8.?L 42 <d.?: ;n2 <d.?: ; nIL M2 <d : ;2 .?nI42 <d.?: ;n2 <d.?: ;nL M<d9.?: ;L 2 <d.?: ;<.?: ;</.: ;I<.G<.: ;I<.: ;<.?: ;n<.: ; <4: ;nI?<4: ;I<4: ; nI?<4: ; I<4: ; I<4: ;I< 4: ;I<4: ;I<4: ;I<4: ; I< 4: ;I?<4: ; I<.?: ; I2 <d.?: ; I2 <d.?I42 <d.?: ;I2 <d.?: ;I2 <d.?: ;n2 <.?: ;n<d.?: ;nIL M<d.?I42 <d.?: ;nIL M<d.?: ;nL M2 <d.?: ; nL M2 <d.: ;I<.?: ;L <d.: ; I< : ;  : ; I: ; : ; .?: ;I : ;I.G dI4.G  4: ; I.G: ; d.: ; I 4: ; I5I: ; I: ; I.G: ; d: ;I.?: ; I .?: ; 4: ;I.G .G: ; 4: ;IdId  .4 .1n@dB1.1@B.G@dBI4.G@dBI1X Y1 411: ; I1.1n@dB1X Y1X Y 1RUX Y 1RUX Y U.1@B1 .1@dB1  1RUX Y 1RUX Y1B.G@B: ;I U4: ;I4: ;I: ; I: ; I4: ; I4: ; I1X Y 41.G: ;@B: ;I: ;I.G@B4: ;I4: ;I.G: ;@dBI4.1n@B414: ;I : ;I.G: ; @dB4: ; I.G: ; @B4: ; I!I/.G;@B41 1.G@B.G: ;@B: ; IB1B1B.G: ;@dB1X Y1B 4I.4@B14: ; I?<4I?4<4G4G 4G4G4G4G4Gn4Gn.?n4<.?nI4<.?I4<.?4<6.?4<.?I4<%101NP(1R1GRGJrJNR:NQUa0axPXaRaqRqtrtxRatrtxQ0PRRrR0PRRrRX\u#X\V\rVruvuVVbnPWWRR2V231B0BQWQXwXjW4j#0WwW#0Ww W #!202AWAHwHZW$Z#q0WwWt#0WwW#&&KU&&KWv$V$&# p2&1&#&KwavvUavvWlovotVtv# p2&1dv#vwUWvV# p2&1#w;U;W vV# p2&1#;wQffUQffW\_v_dVdf# p2&1Tf#fw0UuU#?U??V pP#?vP_P_}Q}WPQa}0}V0a}0}UuU0g}Q}WPQPWw,W,;w;EWGhW0 U u/U/5u~5?UGiUpPPpRRppP# p pQ;V;<<WVWX;v;<#<WvWX#%DoDHRHXo%5P<HP';q;#'oW';V'XVX]vt]V;CVCGvtGXVXavt;CvCGv|GXvXav|;GLMoL;GPM\Pow# #<oWsw# #<sW;Q;';q;#'oW';V'XVX]vt]V;CVCGvtGXVXavt;CvCGv|GXvXav|;GLMoL;GPM\Pow# #<oWwWVW/VGVGLv|LkV/3V37v|7GVGPv|/7L<VL/7P<KPV^#4VlWZ^#4ZfWRuTtPuTLR uTpquPtLuPHR uP0<W<?t?@t@DtaeVrWW  W P&V&tvtVv  V8 : v  R  uPtLuPHuP R uP*DRRvw*<W<?t?@t@DtW*tuTuT8 R uT*t8 R GcWceudemWmtud8 R WGtuP8 R uPVcWceudemWmtudYtu`YqPt 8  tW  WtuTtPuTL 8 uTt 8 Vu`t\Vu`X V 8 u`uPtLuPH 8 uPVu`t\Vu`Xudt`ud\Pv<u`<t\<P 8 u`& 1 ud1 5 R5 8 ud& 5 P@ K u`K O RO R u`@ O PPQuPtLuPHR uP uPu_R u_P` P 8 P` R ) H) 8 R 0 ) U P uH" # P# ) uH" ) L ) W ) V ) W Y  p Y W@ ^ P^ w Ww P W PV ^ R^ v VV Z p#x P W Px p# w# p P"p"u#%YoY_P_uo%-R3_ReuR3YoY_P_uo3_ReuR3Np|NZ #4Z_resp|su #4BN BNp|esp|su #45V5QVTVV u u u#2<J<HP@HPXdR\dR u t  u u t  u u t  u u t  u P V p  V* 8 RJ T RT X v* 8 r J T r T X v# 0 D oJ T oT X RX ] o0 8 PJ X P V V : : : V V V V V : V 0 P R R r RT_p_|u #|}t#}u #rzVz{w{|u#|}t#r{w{|u#|}t#_hRhq_hPhqRqtVDudt`-ud-0t`0iudGVTZQZWuPtL-uP-0tL0iuP#u Gudt`-ud-0t`0iudTutVvV+V7PvuWWZpr"WptRWRpw"udt`-ud-0t`uct_-uc-0t_Pud<t`<"P:EucEIRIiuc:IPP[uc[_R_iucP_PP# cLbUP# ?V?DvlDHVVvl?V?Hvlvv|?v?Hv|HHHPv< Pv v HHHP(Pv)3vH/HHP/CPP# 9L5UP# WwlWWwlWwlww|ww|HHPw<Pw w HHPPwwHHPP+2p,2Qq,Q#,9APAL9U9APAQLQWwxWQdWdhwxhWwxQdwdhw|hww|QhHnHQZPZaw<nzPQdWdhwx{Wwx]hHH]hPPR# r 0R0PPplPr @@DR@# @Dr !0!@R@D0!P!3P35pl@BPBDr Vt tVw t# w Vt t0*V,7VXu # X`0`W[VVbnRnovosrdhnRnovosrdhnrnsR| hu # 0WVVRvrdRvrd i/u/0#T0&W!V!-VRR&iHu#THP0PvWKqVq}VR`RX`RnvjVt tVw,t#,w,Vt t!P!'V'(w()u#)*t#*V!p!^v^iPi'v'(w#() u##)* t##*v!p!'v'*v*-v-0v03v3v4P'v4'(w#4() u##4)* t##4*v4'nvnzPz'v'(w#() u##)* t##*v'*v*-v-0v03v3v4P'v4'(w#4() u##4)* t##4*v4*vP'v'(w#() u##)* t##*v*-v-0v03v3v4P'v4'(w#4() u##4)* t##4*v4-vP'v'(w#() u##)* t##*v-0v03v3v4P'v4'(w#4() u##4)* t##4*v40vP'v'(w#() u##)* t##*v03v3v4P'v4'(w#4() u##4)* t##4*v43v4P'v4'(w#4() u##4)* t##4*v4Y^v^iPi'v'(w#() u##)* t##*vo*ozPz'v'(w#() u##)* t##*vP'v'(w#() u##)* t##*P'v'(w#() u##)* t##*vP'v'(w#() u##)* t##*v4P'v4'(w#4() u##4)* t##42=ug=ARAug2APHSugSWRWugHWP^iugimRmug^mPtugRugtPugRugPugRugP:VB"V#&v&1P1:vB"v#:B"7BPB:vBv7:BQTvT_P_:vBvQ:BepPp:vBve:BvP:vBv:Bv4P:v4Bv4:B:v4Bv4:ugBugPBOP:vRv:ugRugPR_P:vbv:ugbug PboP :vrv:ugrugPrP:vv:ugugPP:vv%:ugug%)PPugR"ugPugR"ugPugR"ugPugR"ugPugR"ugP ugR"ug PoWowrVv|Vo*{*{RR!+# +8V8Av|+8v8;P;<v|<@pdPe0erPWr#RW'VWN WVXVPWXWUEXEY W u t W u t h!W 1 0 W u t u t t W u t u t t!!v!$!P""v" "t "%"d""vs""R #$#0""Pb" # ##P#:#b" ## ##p#:##q"s"Rs""#s" # ##P#:#s""# ##p #$## ""P@#v#0v##Q`###k###k#v#0v##Q##q##V##V##V##V##P##P##R##R##v##1##1##q4##q4"$m$vm$p$#p$$vy$$P$$u$$u $$P$$V$i%Vi%k%vk%|%V%%V$$P$$u $%W%c%Wc%t%Q%%Q$>%u k%t%u $%k%t%%c%Wc%t%Q%%Q,%1%Q1%t%uT%%uTN%c%^%%^N%V%pr"X%t%uT%%uTX%[%pt[%n%R%%R%%uT%%R%%puT"%%ug%%R%%ug%%P%&U&&t&&@'&`&U%^&V^&a&&*&&*&V&&U&&t&&@*&`&UJ&^&V^&a&& 'V''''P))V))V))v~))V))v~))V)*V**v~)*V**v~-*P*VP*R*#$B*O*2$w"-*P*vP*R* #$#`{**P*g+X**W**P*g+W*g+V**U++P+g+U++P+g+U++p+#+P#+g+u++R?w?@#@w#!DoDHRH\o\`R`totxRxo!(P(/w<@HP%/w ISw +@oO\o\`R`totxRxo+2PO`P/9wakw5@ogtotxRxo5@PgxP4w45#5_w_`#!<o<@R@ToTXRX`o!'P'.w<5@P%4W45A_W_`*5oFToTXRX`o*5PFXP-,5,P5,>,t,|,P|,,V,,V,,P,,Pv,,,,v,|,P|,,V,,V,8-08-c.Tg.r.Q..T-r.#T..#TM-r.U..UM-e-0e--1--Q-@.1@.V.Q..1M-e-0e-V.V..Ve--W-@.W..Ww--W..Ww--w ..w --W..W--w ..w --P-@.U..U-@.u..u...U..U...u..u'.).PU-V.u ..u /3/03/^/V'/^/#T//P/0V 0>0P>00v00tp00v00tp00v11R11uP11tL11R11uP2'2uP11R11r'11;12;'1-1W-1.1t.121t211u`11t\11u`12u`<11;1W2;s22;<11W11ud11t`11W122W22W2uds2~2W~22ud22Wu22ud22u\22R22u\22PJ11V11u 11t11u 12V2'2u '2)2V)2W2u 22V22u J11W11ud11t`11W122W22W2ud22WT11V11u 11t11u 12V2'2u '2)2V)2D2u T1{1uT{11u\11tX11u\1'2u\'282uT82D2u\)2D2u\52?2u[?2C2RC2D2u[52C2Pu11W11ud11t`11W1'2Wx11u[11tW11u[1'2u[x11P11P11u`11t\11u`2'2u`11ud11t`11ud2'2ud11P22P11u\11tX11u\2'2u\11u\11tX2'2u\11ud11t`2'2ud11P11vt2!2P!2'2vtD2W2udJ2R2u[R2V2RV2W2u[J2V2PW2s2u`]2e2u[e2i2Ri2s2u[]2i2P22P23P1363P63^3V:3Y3V:3Y344R_5a55555P55t55555555055R5555P55t55555555p66P66P66V66v6W7V66P6X7W66P66W6;7R6Y7UY7Z7Z7v7Uv7w76Y7UY7Z767X7W67Y7UY7Z7Z7v7Uv7w778V88u_88t_838V3858u_5888_88@8V@8a8u_a8c8Vc88u_78u88t858u588888\8ua88uq8{8u_{88R88u_q88P88V88u_88t_838V3858u_5888_ 88u_88t_858u_5888_ 88P88v<88u_<88t_<8*8P@8a8u_I8S8u_S8W8RW8a8u_I8W8P88P8 9P88W88ud88t`9*9W59@9W@9U9udW9Y9WY9w9ud88V88u88t9*9V5979V79U9uW9u9Vu9w9uY9u9Vu9w9ud9n9ucn9r9Rr9w9ucd9r9P88W88ud88t`9*9W88uc88t_9*9uc88P9'9P89W99u 99t89V99P@9U9udF9N9ucN9R9RR9U9ucF9R9P99u`99P9 :uT : :tP :1:uT1:4:tP4:o:uT9:V: :ud : :t` :/:V/:1:ud1:4:t`4:6:V6:Q:udQ:S:VS:m:udm:o:V9:V: :ud : :t` :/:V/:1:ud1:4:t`9 :uT : :tP :1:uT1:4:tP9:V: :ud : :t` :/:V/:1:ud1:4:t`99V9 :u` : :t\ ::V:1:u`1:4:t\9 :u_ : :t[ :1:u_1:4:t[99P ::P9 :u` : :t\:1:u`1:4:t\9 :ud : :t`:1:ud1:4:t`9:P: :u`< : :t\<:&:P6:Q:u`<:C:u_C:G:RG:Q:u_<:G:PS:m:ud_:f:u_f:j:Rj:m:u__:j:P::P::p ;;P::u`::P::uT:;u`; ;X ;A;u`A;D;XD;R;uTR;;u`;;uT::u D;R;u ;;u ::uT::udD;R;ud;;ud::P::uTD;R;uT;;uT::udD;R;ud::u_D;R;u_::PD;O;P:;u`; ;X-;A;u`A;D;Xo;;u`:;V; ;P-;?;V?;D;Po;;Vr;;Vw;~;ud~;;R;;udw;;P:;u`; ;X-;A;u`A;D;X:;ud; ;\-;A;udA;D;\:;P;;u`<; ;X<-;7;P ;-; ;;u`;';P';-;uTT;o;u`Z;a;u_a;e;Re;o;u_Z;e;P;;u_;;R;;u_;;P;;W;<u < <t)<<u ;; w<1;;P; <0)<<0;<W<<ud< <t`)<E<WE<a<uda<c<Wc<<ud;<V<<u< <t)<<<V<<a<ua<<V<<uc<<V<<un<x<ucx<|<R|<<ucn<|<P;<W<<ud< <t`)<:<W;<uc< <t_)<:<uc;;P)<7<P <%<W%<&<u &<)<t <$<V$<)<PE<a<udK<S<ucS<W<RW<a<ucK<W<P<<V<l=Vl==u==V==u ==uT ='=uT'=I=u`I=l=uTl==u` ==u_ ==P`=g=P'=I=u`-=I=ud-=?=Pl==u`r==udr==P==u_==R==u_==P=x>ux>{>t {>>u>>t >>u>R?u=v>Vv>x>udx>{>t`{>>V>>ud>>t`>>V>>ud>?V? ?ud ? ?V ?"?ud"?$?V$?9?ud9?;?V;?R?ud=x>ux>{>t {>>u>>t >>u ??u"?R?u=w>Ww>x>u`x>{>t\{>>W>>u`>>t\>>W>>u` ??W"?R?W>>u`>>u_>>R>>u_>>P>v>Vv>x>udx>{>t`{>>V>>ud>>t`>>V ? ?V ??ud"?$?V$?9?ud9?;?V;?R?ud >x>u_x>{>t[{>>u_>>t[>>u_ ??u_"?R?u_ >>P>>P'>n>u >>u "?R?u '>6>u <u`<'>n>0>>0"?R?0C>n>ud>>ud"?R?udC>n>u>>u"?R?uC?K?u_K?O?RO?R?u_C?O?P[>n>ud>>ud^>n>u_>>u_^>c>P>>Pc>n>u`>>u`i>n>ud>>udi>q>P>>P{>>u {>>u>>ud>>u_>>P ??u`??u_??P$?9?ud*?2?u_2?6?R6?9?u_*?6?P+@1@R1@L@+@L@}@@V@@V@@:@@V@@V@@:@@V@@PRAVAPVAAW\AhAPhAAV\AnA0nAtAPAAP\AnA0nAAUABVBBPB/BVBBVBBv'B/BVBBVBBugBBRBBugBBP6B^BVqBBVAB^BvqBBvJB^BugqBBugJBRBPqBBP2COCQOCvCL7COCQOCvCL7CvCW7COCV7CgCVgClCv|lCCVOCSCVSCWCv|WCgCVgCpCv|OCWCH\CvCHOCWCP\CkCPvCCQCCHvC~C qq4vCCW~CCWCqDWqDsDsDDWCODVODsDsDDVCrDUrDsDsDDUDDPJDUDRUDYD ? 1DYDg1DYDWYDsDmYDqDWqDsDDDPDEEEPE$FDDpDE#EEpE$F#DDPDEEEPE$FDDpDE#EEpE$F#DDRDD\EE0DEWEEEEWE$FDDRDD\EE0EEWEE1EEREErDEE$FDEWEEE$FEEE$FE%EP%EEWE$FW1EEVEFV1EEWE$FWDEEE$FDEEWE$FWVEEUE$FUVEEWE$FWaExEUEF0EFW FF1 FFR FFrxEEWEEWF$FWxEE:EE:F$F:xEE ww<"EEwp"F#Fwp"EEVEEVF$FVEE:EE:EEVEEVEE:EEVEEP{FF{FFVFFVFF9v$9K#$K[v$%ToTXRX[o%-PKXP-9V9KFFPF.HV.H0Hu0H1Ht1HHVFFp4FFPF0Hud0H1Ht`1HHud-G.HV.H0Hu0H1Ht1HHVjGmGQmG0Hu\0H1HtXZHcHu\cH~Hv~HHu\G1HHZH~HHGGQG0Hu`0H1Ht\ZH~Hu`G0Hu`#$0H1Ht\#$ZH~Hu`#$3HZHv4H.HV.H0Hu0H1HtH0Hu0H1HtH1HAH/HW/H0Hu\0H1HtXH)H wu\<"H1HAH)H wu\<"#HHu~HHPH`IW`IfKu}fKiKt}iKKu}KKWK Lu}HHu~HHPHfKu~fKiKt~iK Lu~I`IW`IfKu}fKiKt}iKKu}KKWK Lu}`IfKu~fKiKt~iKKu~K Lu~IKHKKHIEJu~EJVJRVJfKu~fKiKt~iKKu~KKu~%JEJu~EJVJr$VJfKu~#$fKiKt~#$iKKu~#$KKu~#$KKu~YJfKu~fKiKt~iKKu~KKu~jJJRjJKJKKJjJK8KK8jJxJr jJK KK jJJr jJfKu~fKiKt~iKKu~KKu~jJK @KK @jJxJ r  8!JfKu}fKiKt}iKKu}JfKu}fKiKt}iKKu}JfKu~fKiKt~iKKu~JfKu~fKiKt~iKKu~JfKu~fKiKt~iKKu~JJPiKzKPJfKu~fKiKt~JfKu~fKiKt~ KfKu~fKiKt~(KfKu~fKiKt~>KfKu~fKiKt~LLu~LLWLNu}NN}NOu}LELu~ELVLPVLNu~NN~NOu~LLWLNu}NN}NOu}LMQMNu}NN}NOu}'OOu}MOH'OgOHMMu~MMRMNu~NN~NOu~'OgOu~MMu~MMr$MNu~#$NN~#$NOu~#$'OgOu~#$O'Ou~MMu},%%@@MM[MNu},%%@@NN},%%@@NOu},%%@@'O?Ou},%%@@MNu}NN}NOu}'O?Ou}NNu}NN}NOu}NNu}NN}NOu},NNu~NN~NOu~;NNu~NN~NOu~DNNu~NN~NOu~DNPNPNNPPNNu~NN~mNNu~NN~NNu~NN~NNu~NN~NNu~NN~OOu~OOPORu~RRt~RSu~OOu~OOQORu~RRt~RSu~ PRu~RRt~RSu~@PWPu~WP`PP`PRu~RRt~RESu~jSSu~jSSu~PESHP?Qu~?QPQRPQRu~RRt~RESu~Q?Qu~?QPQr$PQRu~#$RRt~#$RESu~#$ESjSu~`QS0`QRu~RRt~RSu~cQS0cQRVRSVmQqQvRR RS RRVRSVRRQRRu}RRQRRu}RSu}SSQSSu}RR RS RRQRRu}RRQRRu}RSu}RR RS RRu}RSu}qQR2RR2qQRu~RRt~RRu~qQtQ upt"tQQ up"qQR2RR2qQtQ upt"tQzQup"QRu~RRt~RRu~QRu~RRt~RRu~QRu~RRt~RRu~QRu~RRt~RRu~QRu~RRt~RRu~QQPRRPQRu~RRt~RRu~RRt~'RRu~RRt~CRRu~RRt~YRRu~RRt~SSu~SSPSVu~VVt~VWu~SSu~SSQSVu~VVt~VWu~TVu~VVt~VWu~IT`Tu~`TiTPiTVu~VVt~VuWu~WWu~WWu~TuWHTHUu~HUYURYUVu~VVt~VuWu~(UHUu~HUYUr$YUVu~#$VVt~#$VuWu~#$uWWu~yUOW0yUVu~VVt~VOWu~yUOW0yUJVVVBWVUUvVW W7W VWV W7WVVVQVVu}VVQVWu} W2Wu}2W6WQ6W7Wu}VW W2W VVQVVu}VVQVWu} W2Wu}VW W2W VWu} W2Wu}UV2W W2UVu~VVt~W Wu~UU upt"UU ur"UV2W W2UU upt"UVu~VVt~W Wu~UVu~VVt~W Wu~UVu~VVt~W Wu~UURUVJW WJUV8W W8UUr UV W W UUr UVu~VVt~W Wu~UV @W W @UU r  8!UVu~VVt~W Wu~UVu~VVt~W Wu~UVu~VVt~W Wu~ VVu~VVt~W Wu~VVu~VVt~W Wu~V!VPWWP!VVu~VVt~>VVu~VVt~ZVVu~VVt~pVVu~VVt~VVu~VVt~QVQRRcVQv$QR#$Rcv$%\o\`R`co%-PR`P-QVQR5OUYkU;O_Yd_dhRhk_;CPYhP-[ud[\\\oudopt`ud0ZW\nWW01vI[ud[\\\oudopt`L[uc[\[\oucopt_LgPzPttucRucP8;P;GvGluTvuT?GPKluTvuTVlugvugV^P^luP<vPuP<ugRugP#AWABuBEt EGWGeu#BuBEtEeuLWugW[R[eugL[P%+P+9Q9duTdgtPguTdu dgtgu %dudgtgu4cWcdudgt giWiuiunyugy}R}ugn}PWWXBXPXXXXXXQXYr6%YYp6%YYPYYu <%!YYBXPX6BXPXHXPX6HXPXuXX!YfYYYuXXW!Y7YW7YfYu`YYWXX!YSYXXu!YSYu7YSYuBYLYu[LYPYRPYSYu[BYPYPXXW!Y5YWXXu[!Y5Yu[XXP!Y/YPXXu\XXu`XXPXX6XXX!Y6X!YXXp?XXPXYr?YYp?Y!Yu ?X!Y6X!YY!Y6Y!YSYfYu`YYaYu[aYeYReYfYu[YYeYPfYYu\lYtYu[tYxYRxYYu[lYxYPYYYC[uC[F[t F[_[_[d[Pd[[uYY0YSZVSZXZvXZ]ZV[[VZZPYZu~&Z]Zu~[[u~YZu~&Z0Zu~0Z5ZP5Z]Zu~[[u~YZu~?Z]Zu~YZu~BZPZu~PZWZRWZ]Zu~YZPBZWZP[[u~[[R[[u~[[PzZC[u~C[F[t~d[t[u~ZC[u~C[F[t~d[t[u~ZC[u~C[F[t~d[t[u~ZC[u~C[F[t~d[t[u~ZZPd[n[PZC[u~C[F[t~ZC[u~C[F[t~ZC[u~C[F[t~[C[u~C[F[t~[.[u~.[5[P5[C[u~C[F[t~[[u [[u[[P[?\WA\\W[[0[6\VA\X\VX\i\vi\\V[6\udw\\ud[[u\\P[[u#\6\udw\\ud\6\ucw\\uc\"\P\\PA\]\uc\l\0c\h\Ph\l\uP#\\uc\\R\\uc\\PB]o]uto]p]tpp]]ut]]tp]]utB]n]Vn]p]Pp]]V]]u]]t]]V]]uB]J]v#\]o]uto]p]tpp]]ut]]tp_]o]uso]p]top]]us]]to_]l]Pl]o]ut<o]p]tp<p]w]P]]us]]R]]us]]P]]ut]^tp^^ut^^tp^2^ut]]V]^P^^V^^u^^t^^V^2^u]]v#]]ut]^tp^^ut^^tp]]us]^to^^us^^to]]P]]ut<]^tp<^^P^$^us$^(^R(^2^us^(^P@^y^Py^^P^^P^^P^^P^^P^^P^^P^^P^^P^^P^^P^^P^^P^ _P __P__P_ _P _)_P)_0_P0_J_PJ__P__P__r _ `P@^i^Ri^^V^^R^u_Vu__R__V_`R` `V ` `Rp^{^p^{^V^^^^V^^7^^V^^^^V^^^^V^^^^V^^^^V^_^_V_ __ _V _0_ _0_V0_J_PJ__P__P__r _ `Pb__W__W__udb_u_Vu__R__V__Rx__W{__u_{__P__P__u`__ud__P__P__P__p__ud__V__ud__u___R__u___P_`u`__u___R_`u___P`/`P/`E`PE`P`PP`Q`PQ`^`P^`w`P`:`R:`E`RE`P`RP`Q`RQ`i`Ri`w`R)`E`)`:`R:`E`RQ`i`Ri`w`R``P``T`=aP``R``U`=aR``0``p1)a#ap1)`;aW;a=a``0`avPa#avP``q``v`aU`a`aW``v`aU`a`aW`#aW``v`aU#a;aW;a=a@aa\aaVaaaaVaaXaraRraaaaRaaXaraPraaaaPsaasaaVaaaaabVbbaaabWbbaaaaVaaPaaaaaaPabWbb b1bu~4P4u~t~u~ u~ 4Q4u~t~u~{u~t~u~u~Ru~t~<u~@u~u~V<HBHVWu~t~<WBWu~w$u~t~<w$Bw$u~u~u~t~4u~Bvu~PttPu u~ 0u~B`u~u~ 0u~B`u~u~ 0u~u~ 0u~P *Pu~D`u~M[u~[_R_`u~M_Pu~t~ u~u~t~ u~Cu~t~ u~Ru~t~ u~[u~t~ u~[gPPgu~t~u~t~u~t~u~t~u~t~@bdbPdb cU c cP@bpbRpbbVbbtbbPbbtbbPbbtbcPcctc cPqbb0bbp1)Zb cW c cqbb0bbVbbQbbQbbTbbbbWbbQbbTbbbbWb cW c ccdc,cXcVXcYcYclcVlcqc(c@cR@cYcYcjcRjcqc(c@cP@cYcYcpcPAcYcAcXcVXcYcccccVccccccWccccccVccPccccccPccWccddu~4P4u~t~+u~ u~ 4Q4u~t~+u~{u~t~+u~u~Ru~t}cu~gu~+u~u~D]H_cHgH+HDu~Pu~t~]u~_cu~gu~+u~wu~p$u~#$t~#$]u~#$_cu~#$gu~#$+u~#$u~u~t}Yu~_cu~gku~+u~PttPu u~Yu~_cu~u~+u~u~&u~&@u~@Iu~IYu~_cu~u~+u~u~&u~&@u~@Iu~IYu~u~Yu~R=R@YRYu~=R@YRY &p|&=u~4@Wp|WYu~4& &p|@Y @Wp|WYu~4CLQLOp|OYu~u~u~+u~u~+u~PP +PP +Pp +p pu~t~u~u~t~u~0u~t~u~?u~t~u~Hu~t~u~HTP PTu~t~qu~t~u~t~u~t~u~t~ d\d\d;eW;e@ew@eYeW]eeWeeW#dtdu\dtdVtddPddVddVddPddVddPddVCeIeVIeSePSeXeVjeeQddPddVjeeQddQdduTjeeuTdd%je}e%ddpr"dduTjeeuTddptddRjeseRseeptjeeuTjeseRseept}eepuT"eCeVCeIeud]ejeV eIeu_]ejeu_ e(eP]egeP(eIeu`.eIeud.e?ePeeudeeu_eeReeu_eePeeu`eeu_eeReeu_eePeeu_eeReeu_eePALugLPRPZugAPPefPffu fftffPffu fftffu fogu ff/fog/ffWfftfftffu\fftXfogu\ZgegudegigRigogudZgigPAffuTfftPffuTffuTf$gud8gBguTAffVffufftffVfgVg$gu8g:gV:gBgufgVg gu[ ggRggu[ggP^ffuTfftPffuTaffu[fftWffu[afefPffPeffu`fft\ffu`ffu`kffudfft`ffudffudkfofPffPoffu\fftXffu\uffudfft`ffudufyfPffPffufft ffVffPffu\ffu[ffRffu[ffPg$gudggu[g#gR#g$gu[g#gP$g8gu`*g1gu[1g5gR5g8gu[*g5gPggu`ggt\ h1hu`1h4hXggudggt` h1hud1h4h\ggPggu`<ggt\< h'hPg hWhuhg hu Whuhu g hWhuhg huTWhuhuTh huThhu_hhRh hu_hhPP>XuTXYtPYuTtPuTVVVXu XYtYVVu 8VVVXu XYtYVVu YVVu VVu ududucRucP uc RucP&_WWWu &uTtPHuTH[u`1_WWWu 1BRBQuPRuT#=QW0RuT#1RrWu`t\-u`1Gu`WVP+Vnudt`ud)-ud1GudqWW)-W1GWqrvudt`udu_t[u_PPPt t1Gud7Bu_BFRFGu_7FPu`t\0 Iu u Wu`t\W 2w#27P>Wu`t\WW>VPVVOudt`ududRZPZuTtPuTuTOSvpudt`udsu_t[u_s{PPPttudu_Ru_P{u`t\{0&_WWWu &uTtPHuTH[u`1_WWWu 1BRBQuPRuT#=QW0RuT#1RrWu`t\-u`1Gu`WVP+Vnudt`ud)-ud1GudqWW)-W1GWqrvudt`udu_t[u_PPPt t1Gud7Bu_BFRFGu_7FPu`t\0 Fu u Wu`t\W7Wu`t\WW7VPVVLudt`ududOWPWuTtPuTuTLPvmudt`udpu_t[u_pxPPPttudu_Ru_Pxu`t\x0llPlxlWllW+m`oWo+pWik9kk9l+m9+pzp9pp9ikukkul+mu+pzpuppuikukkul+mu+pzpuppuikukkul+mu+pzpuppuiiu#iiPiitikkkl+m+pzpppikukkul+mu+pzpuppuikDkkDl+mD+pzpDppDikukkul+mu+pzpuppujkukkul+mu+pzpuppu/jkOkkOl+mO+pzpOppO/jkukkul+mu+pzpuppuOjjVljjljjuljzjqzjjPjjujjujkukkul+mu+pzpuppujkukkul+mu+pzpuppujkukkul+muBpzpuppujkukkul+muBpzpuppujkukkul+muBpzpuppuj@kWllWmmWBpMpWkkukkul+muBpdpuppuk@kWllWmmWBpMpW$kkukkul+muppu'kku`kku`l+mu`ppu`'k2kPllPDpdpuPpdpu`Pp^pP2kkukkul+muppu2kkuPkkuPl+muPppuPOkkukkulmuppuRkkWkkWlmWppWRkSkuT`kdktkkkukkulmunkku`kku`lmu`nkwkPllPm"mPppuppu`ppPwkkukkuwkk0kk0dpvpukkuPkkuT-pBpuP-pBpuTnou`nnPnoudkkukktllulltkkukktllulltkku`kkt\llu`llt\kkPkku<kkt<llPxlluxllPlltllu\llu lltlltllwmmOodopdmmpmPpm2nV ooVooVopVmOodopdm8nu8n ou@ oouoOou@oou@opummu#mmPmmtm8nu8n ou@ oouoOou@oou@oouooum2nV ooVooVooVmOouDoouDmmRm|nu o?ouooummvmOouDoouDmOouXoouXmmP ooPoouDoouXooRoouXooPooPootootm ou@oOou@oou@m o0oOo0oo0oou@2n oroOoroor2n5nP5nnVo oVo?oVooVIn oroOoroorIn ouoOouoouInKnu#OnRnpRnWnP^n ouo=ouoou^nnVo oVo=oVooVun ouLoouLxnnRn ouoouxnynvn ouLn ouXnnPooP#o/oP/o0ot0o4otoouLoouXooRoouXooPnouHno0?oOouHOo`ou`OoRoudRo\oP\o`oud`opoupoouvo~ou~ooRoouvooP p+puX ppu\ppPp+pu\+[u u u +uTtPHuTH[u`3MW3;uT#CGpGLPu`0u`#PSu`t\-u`1Gu`SVP+Vjudt`ud)-ud1GudmWW)-W1GWmnvudt`udu_t[u_PPPt t1Gud7Bu_BFRFGu_7FPu`t\0 su svtvyu qVqsudsvt`vVBqVqsudsvt`Bv0ppRp6quT6q7qtP7qiquTiqjqLjqquTppWpptpptp6qu`6q7qt\7qiqu`iqjqXjqqu`p|quqquqqup5qW5q6qud6q7qt`7qhqWhqiqudiqjq\jqlqWlq|qudqqWqqudqqWqqudlq|qudxq|qu_xq|qPpqVq6quu R1)(6q7qttR1)(7qiquu R1)(iqjqR1)(qqVqquu R1)(qqVqquu R1)(p5qW5q6qud6q7qt`7qhqWhqiqudiqjq\qqWqqudqqWqqudpqVq6quu R1)(6q7qttR1)(7qiquu R1)(iqjqR1)(qqVqquu R1)(p6quP6q7qtL7qiquPiqjqHqquPqqu_qqRqqu_qqPq5qW5q6qud6q7qt`7qhqWhqiqudiqjq\q6qu_6q7qt[7qiqu_iqjqWq%qP%q,qw<7qGqP"q,qu`HqRqu`(q,qWNqRqud(q/qPNq^qP|qqu`qqu_qqRqqu_qqPqqudqqu_qqPBrqru rru Brqru #rru #FrHrPHrPrv|rrutrrlrrutrrlrrusrrkrrusrrkrrPrrusrrRrrusrrP ssPsrsVu#uP#uAuVwwVwwVwxVxxVCtuWuuuuutFu=vWFtuuuutFu=vuFtNtPFuWuPNtuu\uutX]u=vu\Ttuu`uut\]u=vu`Tt\tP]uguP\tuuTuutPmu=vuTbtuu`uut\mu=vu`btjtPmuwuPjtuuPuutL}u=vuPptuu`uut\}u=vu`ptxtP}uuPxtuuHuutDu=vuH~tuu`uut\u=vu`~ttPuuPtuuDuut@u=vuDtuu`uut\u=vu`ttPuuPtuuuutu=vutuu`uut\u=vu`ttPuuPtuuuutu=vutuu`uut\u=vu`ttPuuPtuuuutu=vutuu`uut\u=vu`ttPuuPtuuuutu=vutuu`uut\u=vu`ttPuuPtuuuutu=vutuu`uut\u=vu`ttPuuPtuu@uutu=vu@tuu`uut\u=vu`ttPuvPtuuLuutH v=vuLtuu`uut\ v=vu`ttP vvPtuuXuutTv=vuXtuu`uut\v=vu`tuPv'vPuuuduut`-v=vud uuu`uut\-v=vu` uuP-v7vP?vWvu`KvRvuRvVvRVvWvuKvVvPWvivu\]vdvudvhvRhvivu]vhvPiv{vuTovvvuvvzvRzv{vuovzvP{vvuPvvuvvRvvuvvPvvuHvvuvvRvvuvvPvvuDvvuvvRvvuvvPvvuvvuvvRvvuvvPvvuvvuvvRvvuvvPvvuvvuvvRvvuvvPvvuvvuvvRvvuvvPvwuvwuv wPw wu@wwuwwRw wuwwP w2wuL&w-wu-w1wR1w2wu&w1wP2wDwuX8w?wu?wCwRCwDwu8wCwPDw_wudJwQwuQwUwRUw_wuJwUwP#x{xuD{xxPxxuxxuDxxt@xyuDy zu z!zuD!z$z$z\zuD\zpzupz {uDxxxWxxuLy zuL\z^zW^zpzuLxx{xuD{xxPxxuy zu\zpzuxxWxxuLy zuLxxWy zWxxPyzPxxuHxxudxxPxxuDxxt@ z!zuD!z$z$z5zuDzzuD{ {uDxxudxxt` z!zud!z$z\$z5zudzzud{ {udxxudxxt` z!zud!z$z\$z5zudxxu`xxt\ z!zu`!z$zX$z5zu`xxP$z/zPxxuDxxt@ z!zuD!z$zxxudxxt` z!zud!z$z\xxPxxuD<xxt@< zzPey}yW}yyu`yyu`zzWzzu`eyhyuDhysyPsyyuyyuzzuzy}yW}yyu`yyu`yyWyyWyyPyyPyyu\yyu\yyudyyudyyPyyPyyuXyyuXyyudyyudyyPyyPyyuPyyuPyyudyyudyyPyyPyyuTyyudyyP7zAzuT=zAzud=zAzPAz\zuDGzNzuCNzRzRRz\zuCGzRzP^zpzuLdzkzudkzozRozpzuddzozPpzzzuHvzzzudvzzzPzzudzzu`zzRzzu`zzPzzu`zzudzzRzzudzzPzzu\zzudzzRzzudzzPzzuXzzudzzRzzudzzPzzuPzzudzzRzzudzzP8{E{0E{[{uT[{o{Ro{s{Ps{{uT{{tP{{uT*{{V{{P{{VE{[{ud{{ud{{t`E{[{uc{{uc{{t_{{PE{[{udw{{ud{{t`{{udE{[{Vw{{V{{P{{V{{V{{uc{{R{{uc{{P{{uc{{R{{uc{{PC|| }<}_}}C|I|WI|J|tJ|N|tN||uX }<}uX_}}uXX|| }<}_}}}}}}X||W||u\ }<}u\_}e}We}}u\}}W}}u\}}W}}u\}}W}}u\}}u\}}ud}}Pq|| }<}_}y}}}q||V }<}V_}g}Vg}y}ud}}V}}ud|| }<}}}||u }<}u}}u}}uW}}R}}uW}}P||V }<}V||uW }<}uW||P }}P||u\}<}u\||ud}<}ud||P}&}P||u`,}<}u`||ud,}<}ud||P,}6}P||uX||uX||ud||ud||P||PD}_}uXJ}Q}uWQ}U}RU}_}uWJ}U}Pg}y}udm}t}uWt}x}Rx}y}uWm}x}Py}}u\}}uW}}R}}uW}}P}}u`}}uW}}R}}uW}}PG~ uP HEuPVuPHuPY~ ud \EudVud\udh~E:V:q~~VEVVy~E:V:y~~VEVE:EV~~P~ uP HVuPH~~P~ VVV~uVu~ VVV~~P~~W~ uT LVbPbuTL~ VVV~~P~~WV|0V|Vj|1jvRjqr~|~ V|V~ ud \|ud\~ uc [|uc[~P|PucRucPP:O;P|:%ƀɀu ɀʀtʀ΀tڀ%ڀ%W%%W%@K$ % PWD~  "3 h~D~u |"|3D|vRuTv $&P&8W:FPFWzB(>P>VVsB#6P6VVkB%(P(JuPJKtLK+uPuK\uuu]+~sVPVt=v=HV%pu "%4P6CR6CP=CQjVVcfrfjPjqtq{h{#Uu܁0WwW߁uD}  d}LPP#Wbƃr6ov6?PUov U^P-PEMPMVVg$~Bu#u#WVVvt VVvtVvtvv|vv|ududPPu#u# u#< Wu# u#<W$ju#-ju#-bV-=W=XWXbwt=XwXbw|CbucCQPbju#bju# u#<fju# u#<frV-PBVPVVVBV`VR`|VW|PWVWVWdu101u|V|PVVuuuu$3vVCyVWCdW!5WCd0Rd1R^RRYr8VbjujnPbePe.V.1pyVr.v.1p#yv/W0uL01tH.v.1p#P(uuY   pLu# # u# t# u# ud\udt`udPPu##u#t#ud\udt`PucR%ucPucR%ucPV5V(V5VY   pLv v ud\udPPvvud\udPP ucR5uc P%uc%)R)5uc)P'VutV68P8WPW‡B<v u# t# Qv,u#,t#,&<u#<=t#=u#t#u#3FPFVV{BEVHVu"%v%*P*EvHvu#24P4FWHVPVWB"EvEu#Pu#^ V#VoVBV BG LX L v #Bv ud#BudP2?P v#2v ud#2udP#/PdkuckoRoucdoPv}uc}RucvPLRPRVPVW\v\cPcvpvkmPmWPW W ʈBu Zlu u u u u +WYu\YZTZlWlu\tXu\Wu\Wu\u\udRudPOWAu\u\u\u\u\OAVVuuVW   DAu\u\u\A||| AvAAW.Av DYu\YZTlu\tXJYudYZ\ludt`JZPlwPu\u[Ru[Pu tu u u #t#u ##u #.dWWW.4V45t59t9u`t\u`Xu`:dWW:}V}udt`Vud\VudVudR}V}udt`Vud\RZPZutug}V}udt`Vud\ju_t[u_WjqPqxv<Pnxu`u`txVudtPPudu_Ru_Pu_Ru_P"3P"WutWuWVudt`VVudWWutWWunVudt`Vqu_t[u_q{P{v<Pxu`u`~Vud~PPwu#t#udu_Ru_Pu_Ru_P+bVV!)V=W=Uu UVtVu u ]u =w=Uu #UVt#Vu ##u #]u #sz.zIzV]zsyVyztz~u~UuHUVtDVuH@.uHIuHV]uHz.|zz(IzV]zVUuLUVtHVuLD.|uL uL VuLV(1V1IuLV]uL(IuL4?ud?CRCIud4CP.j V]WUuXUVtTVuXP.juXuXWuXW uXV]uX.XV]VUu\UVtXVu\T.7V7Xu\Vu\Vu\V]Vu\udRudPTWTUudUVt`VWud\.FudVXWX]udUuUVtVu.FuV]uTWTUudUVt`VWud\UuCUVtVuCPw<VgPu\hru\WnrudPn~PuXuXudud PPuLuLududPP$uHuH$udud'PP$2uDuD*2udud*5PP2@uTuT8@udud8CPP@Nu`u`FNududFVPP.Fud:AuCAEREFuC:EPFXu\LSuCSWRWXuCLWPXjuX^euCeiRijuC^iPj|uLpwuCw{R{|uCp{P|uHuCRuCPuDuCRuCPuTuCRuCPu`uPP$V'\V\^u^`V`hu%$v'\v\^u#^`v`hu#^W;WoWZW Z^ bp Lw ;Zw ud;ZudPJWPw;Jwud;JudP;GP|ucRuc|PucRucP7:v :BPBzuPz{tL{@uP@AtLAkuP7:v :BPBzuPz{tL{@uP@AtLAkuPKMPMzuLz{tH{P@uL@AtHAkuL&AV&Bb{1A1Vk1bzuPz{tL@uP@AtLVkuPq{PP>VV^VAUVkUABv P͊uL͊ΊtHΊuLtHuLv P͊uL͊ΊtHΊuLtHuLPuPΊ֊P֊0uPuP0&& 0BΊD0DD͊uL͊ΊtH0uLtHuLƊPƊˊV06P6VVJUUkB v PSuLSTtHT#uL#$tH$NuL v PSuLSTtHT#uL#$tH$NuLP;uPT^P^uP$9uPr&$9&B;T$9N;SuLSTtH#uL#$tH9NuLGLPLQVƌPƌ!V9AVڌ$U9NU$BgjvjrPruLtHuLtHuLgjvjrPruLtHuLtHuL{}P}uPPuPuPҍ&&BuLtHuLtHuLPV&P&VV:UU[Bu#,Ўu#,ЎP6uTЎVЎV#vx#RVVvxV(vxvv|v(v|ud6udPv< PVvx V(vxududP"P6u#,6>u#4u#,86BP:>u#4u#,8:BPFu# Ru# RkPkuTRkVRΏVΏӏvlӏVkVvlΏVΏ؏vlkvv|ΏvΏ؏v|kududksPszv<Pkzv v vzududv}PPzvvududPҏPu# u#(u# DPu#(u# DPutPvVyVSyB(<W<=t=AtA|uX|}P}uXtT-uX(u}uuuu(u#}u#u#u#u#/<W<=t=AtA|uX|}P}uXtT-uX/dV}VVV V-VK-KW|u\|}T}Wu\tXu\Wu\u\-u\u\udRudPfWXu\u\u\-u\fXVVV-V W  DXu\u\-u\X||-|!Xv6X6XWEXv [|u\|}Tu\tXu\g|ud|}\udt`udgkPPu\uWRuWPk|uX|}PuXtTq|ud|}\udt`q}PPuXuWRuWP4EWEFtFMtMuXtTuXtTuX5]uXguX4uuuu5;ukvu4u#u#u#u#5;u#kvu#:EWEFtFMtMuXtTuXtTuX5]uXguX:pVVVV5LVgV:5]gW5]gWWu\tXWu\tXu\u\5]u\gou\oqWqu\u\udRudPrWdu\5Cu\gou\vu\rdV5CVgoVvVW 5C ko Ddu\gku\vu\d|gk|v|-dvBdBdWQdv gu\tXu\tXu\sudt`udt`udszPzu\<PC]u\OVuSVZRZ]uSOZPwuXuX}udud}PPuTtPuTtPudt`udt`PPuXuSRuSP5uT 'uS'+R+5uS +Pu u  u Wuu yu u u #u # u #Wuu #yu #u #.RVquVyVV.4W45t59t9uTtPuTtPuT:RVquVyV:^W^_t_ftfuXtTuXtT<uXWquXqsWsuXuXyuXudRudPR^W^_t_ftfuXtTuXtT<uXWquXuyuXuXuXRWPWuu uWquRWpWu#u# u#Wqu#U^W^_t_ftfuXtTuXtT<uXWquXuyuXuXuXUVVVVW`VuyVVVb<WquybftfuXtTuXtT<uXWquXuyuXuXuXp*WquypWu\tXWu\tXu\Wu\*u\Wqu\uyu\u\u\Wqu\cjudjnRnqudcnPW}u\u\u\uyu\u\}VVVuyVV.W   D}u\uyu\u\7}|uy||F}v[}[}Wj}v u\tXu\tXu\udt`udt`udPu\<P*u\%uS%)R)*uS)PuXuXududPPuTtPuTtPudt`udt`PP*<uX07uS7;R;<uS0;P<WuTBIuSIMRMWuSBMPސ5zÑ ސuT5u\zu\Ñ u\5zÑ5uTzuTÑۑuTۑu`uT5uTzuT5u[zu[!PzP!5udud'5u`u`'+PP+5u\]gu\15udcgud1:PcmPÑu\u[RÑu[Pőu`ёؑu[ؑߑRߑu[ёߑPudu[Ru[P:uTtPƓ.uTu u u #u #57P7:u #FƓ?FWudt`Ɠ?WFXw#X]Pa  $/ B Ɠ    + aWudt`Ɠ+WiViqw#y}p}PƓud+ud#pP $/ B    + udt`+udʒVud#ĒpĒɒP udՒ$Ւ$udՒud#pP$/ $ud$uTud#pP$ud#p P$ +$udt` +ud$/ud#36p6;PB  + Budt` +udJTQ_ctcgtJPud#\bpbgP +ud}udt`}0@RvRvRR@rvR#vrR#crvP~RvRR~rvR#R#uuduv\ud•t`udsVsuu`uvXVu`•t\Vtu`v#PƔvu•uƔsVsuu`uvXVu`•t\Ɣϔv#ϔԔPՔsVsuu`uvXVu`•t\ՔWWՔܔv#pPsVsuu`uvXVu`•t\PWuPv#Pu`0u`#P5uu`uvXu`•t\5v0•0]uuduv\ud•t`cuu`uvXu`•t\cnPnuud<uv\<PĕudʕՕu_ՕٕRٕu_ʕٕPJoVoqu`qrXrVMqu_qrWru_MWPW_v<rPT_ududZ_Vu`Z_PPudu_Ru_PΖؖu_ؖܖRܖߖu_ΖܖPMuMNtNvuRMu MNtNvu MutMNtpN{ut/MutMNtpNZut2MusMNtoNZus2:PNWPbmusmqRq{usbqP!R!euTeRuTR.a.aVMaMXPddududt`udTPudt`UWUVu\VWtXWWw#Pb bUWUVu\VWtXWW W×ݗV×˗w#ӗחpחܗPW{u\W{ u\#pPW<{< <u\# p PW|{| |u\#"p"'P+Wb{b b+Vu\VWtX{u\ u\3MV37u\#CGpGLP{u\VW V[u\#_bpbgPqW qsu\#wzpzPW u\#pPW u\#pPW\\ \u\#˜p˜ǘPјW** *јӘu\#טژpژߘPVudVWt`ud ud,TVTVu`VWt\V/Vu[VWtWu[/6PP6VudVWt`ud<Vu`VWt\u`<APPAVu\VWtXڙu`˙ՙu[ՙٙRٙڙu[˙ٙPڙudu[Ru[Pu\ wu wztz}u uVuwudwzt`zV )u  1v#16RFuVuwudwzt`Fz0<Jp <ututu6Su]|ut R6GRQSR]|RtzVz{t{tuLtHuLtH uL6GuLQSuL]|uLRR6GRQSR]|RVuPtLuPtLVuPVuP6>V>@uP@GVQSV]hVh|uPkru\rvRv|u\kvPaa@GaQSaWttuXtTuXtTuX@GuXQSuXaa@GaQSaWu\tXWu\tXu\@BWBGu\QSWWu\tXWu\tXQSWPututQSuWu\tXWu\tXuGtCuGtCPw<'PuX(2uXW.2u\P.>PuP?IuPu\EIu\PEVPuLWauLu\]au\P]nP uHoyuH u\uyu\ PuP uTuTu\u\PPu\uGRuGPuXuGRuGPuPuGRuGP uLuGR uGP uHuGRuGP6uT!(uG(,R,6uG!,P0^V^u tu t1u 6Su S[V[|u 9Gp0)9ututu6Su]|uq R6GRQSR]|RqwVwxtx|t|uLtHuLtH uL6GuLQSuL]|uLRR6GRQSR]|RVuPtLuPtLVuPVuP6>V>@uP@GVQSV]hVh|uPkru\rvRv|u\kvPaa@GaQSaWttuXtTuXtTuX@GuXQSuXaa@GaQSaWu\tXWu\tXu\@BWBGu\QSWWu\tXWu\tXQSWPututQSuWu\tXWu\tXuGtCuGtCPw<'PuX(2uXW.2u\P.>PuP?IuPu\EIu\PEVPuLWauLu\]au\P]nPuHoyuHu\uyu\ PuPuTuT u\u\ PPu\uGRuGPuXuGRuGPuPuGRuGP uLuGR uGP uHuGRuGP6uT!(uG(,R,6uG!,P'֚V֚ךwdٚ4V4Swd*ךWٚSWO[v[]t]^t^btO[vu\!2u\u[!2u[P!/P:Eu[EIRISu[:IPZu\ZuWPFWP.FuX1Fu`1@P\wuXbiu`imRmwu`bmPuWRuWPPuHtD uH/uHuHPV/V͜PRuTtPҟuTPR;uDt@muDuDuD>u[tWmu[u[u[>IPITuD<=GPFTuTHVu`LTuDNVu\LTPNgPu\ u\u[ u[P PŝPŝϝRu`t\ u`=u`u`u\tX u\=u\u\P/7P$,P,u@ u@u@-u@ u@u@Yu` u`\u\ u\\dPPu`u\Puu`{u[{Pu\u[Pğ˟u[˟ϟRϟҟu[ğϟP;IP;ututu6Su]|us R6GRQSR]|RsyVyztz~t~uLtHuLtH uL6GuLQSuL]|uLRR6GRQSR]|RVuPtLuPtLVuPVuP6>V>@uP@GVQSV]hVh|uPkru\rvRv|u\kvPaa@GaQSaWttuXtTuXtTuX@GuXQSuXaa@GaQSaWu\tXWu\tXu\@BWBGu\QSWWu\tXWu\tXQSWPututQSuWu\tXWu\tXuGtCuGtCPw<'PuX(2uXW.2u\P.>PuP?IuPu\EIu\PEVPuLWauLu\]au\P]nPuHoyuHu\uyu\ PuPuTuTu\u\PPu\uGRuGPuXuGRuGPuPuGRuGP uLuGR uGP uHuGRuGP6uT!(uG(,R,6uG!,P 0mVV pWp+W+D*=R=Qpv"QmSpv"Sàpv"àǠSǠ٠pv"٠Spv"S*pv"*HSHSpv"SnSnspv"sSpv"+SHSUHSLHSL#gLL#'HJ'HL>BQBHZ:BPPLL#Ǡ`ǠLǠL#ǠZǠLǠL#HS+SHnLchrhnYchPnLrXP+n+LL#Pġ`ġLġΡL#ΡӡPݡrݡLݡL#P`[ R [P`< P+`&[&*R*+[*P|L+@LzӣVVACVIvWAIWzu\ͣu\zWzu\#pPu\tͣtu\#pPͣǢpǢ̢PӢudͣudӢ֢u\#ڢݢpݢPͣpPudͣudu[ͣu[ PǣP u`u`ududPPzuT_ͣuTKuTzuwͣu-uzu\wͣu\-u\wyu\#}pP-ud!(u[(,R,-u[!,P-Au`3:u[:>R>Au[3>Pߣu\Tu\ #P#VuP<tL<VuP<H<VuP<VuP<VuP<-QV #p4#-P-uTv4uP#(tL#(v4uP#(H#(uTv4uP#(uTuP#(-QuT}VuP<tL<VuP<H<VuP<VuP<VuP<-QVvuP4tL4vuP4H4vuP4vuP4vuP4-QvVHHQH3Q3uPtLuPHuPuP-QuPGuP#$tL#$uP#$H#$uP#$uP#$-QuP#$v4eVuP<tL<VuP<H<VuP<VuP<uP<ejPjutuuuuxudt`ud\ududx{u#udt`ud\uct_uc[Pud ucRuc Pu $t0 W P0ϨWϨ!0!5W5&0PRWn+05vPjvn+vut&u&5u@Pjunouou@+uu#ĤPȤut&uPfunouou@+uФWФؤu#pP!u@!&Pfn+ p PL&Lu@&u@jju@}uH}u@}u@#pPuHudPEV5[Vmmu5[5[udududȦudududrudݦDDDݦu@u@u@u@u@uTuTu@u@u@# pPu@u@&&u@u@?uXuX?u@u@?Bu@#FIpINP[uTuT^udud^fPPfuXludl{PP[fPuPudP|+|u@+u@u@PVʩʩVܩuPܩVܩߩv#uXu`Ru`PuTud P̪u@̪u@u@ʧuDʧu@ʧͧu@#ѧԧpԧ٧PuDudPaau@u@u@uLu@u@#pPuLudP&uH"&ud"&PuLudPΪuDڪudڪPƥutϨu!5uɥudt`Ϩud!5udɥѥP!/Pѥu@tϨu@ѥ0Ϩ0utϨuudt`Ϩud PǨP&5u@5Pu;BuBFRFPu;FPR\u`X\udX\PYPrPPdPrP++O+VVOVv#PuݭuOuVݭVOVuݭuOu۫WWȫuTݭuTOuTȫ۫WWޫuTݭuT5OuTu`ݭu`5Ou`Pͭ׭P5ud#.u`.2R25u`#2Pͭ5Ou\ͭu\5Ou\u\#P 5ͭ55O5 u\ͭu\5Ou\ u\#P0qͭ0q5O0qu\ͭu\5Ou\u ͭu 5Ou !u\#)/p/4P>BͭB5OB>Gu\#GLPou`ͭu`rudͭudrzPǭP߭u\8Ou`>Oud>IPu\T++Om+VVOmVƬv#ƬˬPѬu uSmuѬV VSmVԬu uSmuԬWSUWuT uTSmuTWSUWuT uTu` u` PP[fu`fjRjmu`[jP   u\ u\ u\# P*I I*u\ u\*3u\#38P;0q 0q;u\ u\SU US\u\#\aPu`udPP u` udP u\PW5W5;P;AWCcWVut5u5@V@BuBCtCMuMOVOPu5CcuTtP5uTCPuTPcuduT#P5|CM|uTtP5uTCMuTVut5uCMuȮuT#̮ԮrԮٮPuTtP5uTCMuT50CM0PW WWgβWPVjVVgpVg8bo8ѳ)8guTbouTѳuTuduT)ud%g bo ѳ %guTbouTѳuTuduT@gboѳ@guTbouTѳuTuduTUg bo ѳ UguTbouTѳuTuduTjgboѳjguTbouTѳuTuduTg bo ѳ guTbouTѳuTuduTgtbotѳtguTbouTѳuTuduT:g)bo)ѳ)guTbouTѳuTuduTgboѳguTbouTѳuTuduṮg bo ѳ ̱guTbouTѳuTuduTgtbotѳtguTbouTѳuTuduTg)bo)ѳ)guTbouTѳuTuduTgboѳguTbouTѳuTuduT!guTbouTѳuTuduTCguTbouTFgu\bou\FRPbiPӳudٳu\Ru\ٳPu`u`)udxU oѳ xUVo{V{uTudVuTVuTVuTѳudU o UVo{V{uTudVuTVuTUioiUVo{V{uTudVuTVuTU)o)UVo{V{uTudVuTVuTβUmomβUVo{V{uTudVuTVuTU o UVo{V{uTudVuTVuTU~o~UVo{V{uTudVuTVuTUVo{V{uTudVuTVuT5UVoyV8Uu`oyu`8@PovP{udu`Ru`Pu\u\ѳud Ub ) WVUbV)+V+BuTBSudSUVUWuTWYVYnuTnud1 Ub )k 1WVUbV)+V+BuTBSudSUVUWuTWYVYkuT@iUbi)ki@WVUbV)+V+BuTBSudSUVUWuTWYVYkuTX:Ub:)k:XWVUbV)+V+BuTBSudSUVUWuTWYVYkuTjmUbm)kmjWVUbV)+V+BuTBSudSUVUWuTWYVYkuT Ub )k WVUbV)+V+BuTBSudSUVUWuTWYVYkuT~Ub~)k~WVUbV)+V+BuTBSudSUVUWuTWYVYkuTVUbV)+V+BuTBSudSUVUWuTWYVYkuTӰVUbVְu`Ubu`ְPU\P+Aud1<u`<@R@Au`1@PASuXYkuXִWеW%+uT%Q FIPIURVϵudϵеt`QudlxPx|R͵V͵ϵu`ϵеt\QuVϵu_ϵеt[Quu_PdoPϵudϵеt`Qdudϵu`ϵеt\Qdu`PQ^P}udu_Ru_Pu_Ru_PPWPWƷWƷuTtPuTƷuduT#PuTtPuT7V%uT#-1p16PudOudt`O0зRYVYиRиV5R5:V:LRϸuTϸиLиuTLLuTuT# P5˓ϸuTϸиLиuTL5uTиud;ϸudϸи\ud\5udWc0cVWu`clpv"ltP{udPRϸudϸи\ud\ϸu`ϸиXu`Xϸudϸи\ud\ȸPȸϸu`<ϸиX<Pu`u_Ru_P$3ud~PPr}lllkԹkԹعRعkPعP$P$)V l,DkDHRHQk,9P9<l<<HPPWPeiWuTISƻ#>ae~IuDSƻuDuD#u\>_uD_au\efuDf~u\ĺqĺɺPӺIuTSƻuT#uT>auTӺIuDSƻuDuD#u\>_uD_au\ӺںqںߺPIuDSƻuDuD#u\>_uD_au\I0Sƻ0#0>a0;IuT̻׻uTAIudϻ׻udANPϻ޻PoƻU#U>aUoWƻu` W #u`>aWƻud udƻu\ u\PPƻu`#u`#>uT)0uS04R4>uS)4PAaudMau\MXPVudt`03u ]u ̾u 3Fu@FItIӾu@Ӿu`u@>u ]u ̾u >˽W˽FuTFItPIWuT߾WWAu ]u ̾u A}V]mVV[FuFItIҾu u[}V]mVVkFuFItIu unFu\FItXIu\ u\nzP]gP̾uXǾu\Ǿ˾R˾̾u\˾PzFuTFItPI]uTmuT uTzFu`FIt\I]u`mu` u`DVDFu\FItXI]VVV u\PFuDFIt@I]uDuD uDuDtDVDFu\FItXI]VVFuXFItTI]uXuXȽPIWPPtt u\ uX PȽFuTFItPuTȽI00Ҿ߾uTFu`FIt\u`FudFIt`udI00#<WW(<u\u\(0PP߾u`߾udLyuDy|t@|uDuTuD&uT&?uD?OuTOSuDL^uD#^cPg  S gyuDy|t@|uDuD&uT&?uD?OuTOSuDoWowuD#pPuTWWuҿҿuTuT#pPҿuT¿uT#ƿɿpɿοPҿSҿyuTy|tP|uTuTSuTҿݿuT#pP  S yuTy|tP|uTuTSuTVuT# p PuT33uT#uT#'*p*/P3|VFyFyuTFQuT#UXpX]PdyuTdiuT#mpppuPyuTy|tP|uTuTSuT#V#yu`y|t\|VVu`V&u`&(V(Ou`OQVQSu`yuTy|tP|uTuT&SuTyu@y|t|u@u@&?u@?OuXOSu@uxWxyu\y|tX|WW&>Wyuy|t|uu&>uxWxyu\y|tX|WWyuSy|tO|uSuSPP(>u\.9uS9=R=>uS.=PyuXy|tT|uXuX00>OuX yu`y|t\u` yudy|t`ud |00'DVV,Du\u\,8PPDyuTy|tPD|0uT&u`ud P &udWu`t\*Wu_t[*u_P'Pudt`udu`t\u`PP5Qud;Cu_CGRGQu_;GP_iu_imRmpu__mPWu`t\ :Wu_t[ :u_P)7Pudt` )udu`t\ )u`P &PEaudKSu_SWRWau_KWPoyu_y}R}u_o}P W u`t\0JWu_t[0Ju_P9GPudt`09udu`t\09u`P06PUqud[cu_cgRgqu_[gPu_Ru_Pr uuu#u#ru #u #ruuiWuWWw#PtiWuWuuiuduududPiuTuuTuT3iuduud6iu_uu_6>PuPPttudu_Ru_P>iu`>i0u`Qi[[HJ % %j>jVu`t\#u`#'V'>u`y$97yWut$u9#u#7Wyw#PWut$u9#u'7u$9#PV V$9#uut$u9 u u#uu#Puut$u9 u#u2$29 2PVVVV2$29 2:u:ut$u9uu uu#P*:u:ut$u9u u4$94VVVHtutut$u9uuuHuuuHQpQVPdtutut$u9uun7$797nVV7$797uut$u9uuuu#Puut$u9uuH$H9HPuuH$H9HVut$u9uVtuv#PVut$u9uuQ$Q9Q P VVVVQ$Q9Q>W>u@t$u@9u@W"w#"'P3>W>u@t$u@9u@u@;t$t9t;VVVLqWquDt@$uD9uDWLutu9<uLOu]^unquuuLUpUZPfqWquDt@$uD9uDuDn`$`9`nVV`$`9`WuHtD$uH9uHWw#PWuHtD$uH9uHuHQ$Q9QPZVLNV]aVnpVQ$Q9QWuLtH$uL9nuLnWpPWuLtH$uL9nuLpuL$9nZVLNV]aVWuPtL$uP9]uP]nWutu9<uLOu]^upPWuPtL$uP9]uPanuPc$c9]cZVLNV*c$c9]c*\W\uTtP$uT9LuTL]W*3w#38PD\W\uTtP$uT9LuTN]uT\Q$Q9LQ\cPcWW9;WjQ$Q9LQjVuXtT$uX9BVBFtFLuXjrprwPVuXtT$uX;LuX$WWVu\tXV t $u\ut~upPVu\tX$u\u`t\Pudt`$9u`$)ud)0P09ud3; 3; QwU;Qww;Q;QVW;QVWVWPR;JPR;Q;QH Hu|PWu|t| u|  W ! u|! u| u| u| u|  u| u| 3 u|3 u|u}Pu|u~Pu|t| u| u| ! u|! u~ u| u| u~ u|  u~ u| 3 u~3 7 u|> g u|g u|bWu|t| u|  W ! u|! u| u| u| u|  u| u| 3 u|3 u|Wu|t| u| W u| W u| 3 u|3 5 W5 u| u|QH H H HQu|Qu| u| Yu~YjRju|u~t~ u~ u~ 3 u~3 7 u|> g u|g u| u| u~u}q$u|#$ u} Yu~Yjr$ju|#$u~t~ u~ u~ 3 u~3 7 u|#$> g u|#$g u} u|#$ u~ u}A A A 3 A7 > Ag AWu|t| u| u| 3 u|7 > u|g u| upt" uw<" tw upt"w} uw<"A A A 3 A7 > Ag A upt"  uw<" tw upt"w} uw<"u|Wu|t| u| u| 3 u|7 > u|g u|H H H 3 Hg Hu~PrWru|t| u| ! u|! u~ u| u~ u|  u~ u| 3 u~g k Wk u|u~Pu|t| u| ! u|! u~ u| u~ u|  u~ u| 3 u~g u|;rWru|t| u| ! u|! u~ u| u~ u|  u~ u| 3 u~g k Wk u|ru~Wu~t~ u~ u~ 3 u~k y Wy u~ W u~ W u~ W u~m u~ H H H 3 H H Yu~YjRju|u~t~ u~ u~ 3 u~ u| u~?Yu~Yjr$ju|#$u~t~ u~ u~ 3 u~ u|#$ u~ u~tA A A 3 A A AtWu~t~ u~ u~ 3 u~ W W u~tw upt"w} uw<"tA A A 3 A A Atw upt"w} uw<"u|Wu~t~ u~ u~ 3 u~ W W u~j j B j 3 j'W'u|t{ u| ! u|! B u| u| W u| u| u|  u| u| 3 u|j j / j 3 jVu|t| u| / u| V u| V  t 3 u|v#P Vu|t| u| / u| u| 3 u| u|'v v / v v 3 v'.P.qW W8v v / v v 3 v8oVou|t| u| / u| V u|  V  t 3 u|8Dv#DIPUoVou|t| u| / u| u| 3 u|  u|q} } / } } 3 }qxPxW W} } / } } 3 }Vu|t| u| / u| V & V& * t* 3 u|v#PVu|t| u| / u| 3 u|  / P#W  W  / Vu|t| u|  V ' V' + t+ / u|v#PVu|t| u| / u|#u|t{ u|#*P*u|t| u|4u|t| u|7u|t{ u|7CPPCu|t|u| u|Lu|t|u| u|LXPPXu~t~u~  u~u~t~u~  u~nu~nu}t}u}  u~u|t|u|  u|P Pu~u|t|u~u~t~u~u~t~u~u~t~u~u~u}t}u~8u|t|u|_u|t|u|nu}t}u}wu~t~u~wPPu|t|u|t|u|t|u|t|u}t}/ B u|/ 7 u|7 > P> B u|B ^ u|K Y u|Y ] R] ^ u|K ] P^ z u|g u u|u y Ry z u|g y P{jjj5hjlpjfVfhu`hkt\k{VVVu`57V7Fu`FJVJWu`W[V[hu`lnVnpu`{jjj5hjWhuPhktLk{uPuPuP5FuPFWWWhuPw#PWhuPhktLk{uPuPuP5FuPWhuPJWuP"{5FWh")P)ku58u3{5FWh3hWhhuThktPk{uTuTuT5FWWhuT3<w#<APOhWhhuThktPk{uTuTuTWhuT7FuTk{WhkrPruu|{Wh|WhuXhktTk{uXuXWWhuX|w#PWhuXhktTk{uXuXWhuXuX{WhP4ukyuWXu{WhgWghu\hktXk{WWWhWw#PgWghu\hktXk{WW[hu\fVfhu`hkt\k{VVhudhkt`k{udud{00&<QQu1HWW1<PPHhuHhktDuHNhu`hkt\u`NSPPShuLhktHuLYhu`hkt\u`Y^PPuLuGRuGPu` ud Pud5uH$.uG.2R25uG$2P`jxjuD]u`]`t\xu`uDu``jxjjjW]uL]`tHxuLuLuLWqPW]uL]`tHxuLuLuL`xP?uDuD`x,W,]uP]`tLxuPuPWw#P#,W,]uP]`tLxuPuPuP?`x?FPFuDuDP`xPW]uT]`tPxuTWuTPYw#Y^PlW]uT]`tPxuTuTuT`xPuDuD`xW]uX]`tTxuXWuXw#PW]uX]`tTxuXuXuX`xP4uDuD`x\W\]u\]`tXxWWw#P\W\]u\]`tXxWu\]u`]`t\xu`]ud]`t`xud`0x068P8TuDxuD>TWxW>FPFTu@<xPu@<u`udPud?jj?uDu`t\tu`twuDwu`Qj(j=_jcjQWuLtH(uL=_uLctuLtWQWqW\PjWuLtH(uL=_uLctuL(=_ctPuDcduD(=_ctWuPtL(uP=_uPctWw#PWuPtL(uP=_uPgtuP(=_PuD=@uD(=_WuTtP(uT=NWN_uTw#PWuTtP(uTN_uT?NuT(N_PauDuD)(N_)NWNuXtTuX(WN_uX)2w#27PENWNuXtTuXN_uX(uXaN_ahPhuDNOuDrN_rWu\tXWN_Wr{w#{PWu\tXWR_u\u`t\u`udt`ud00PuDuDWWPu@<Pu@<(=u`(-ud-4P4=udR R RR000P PuQ QQP-0Jc-4P4vW9;W>0Jc>dVduL09uL9BVBFtFJuLcuL>@v#GJpJOP[dVduL09uLcuL;JuLr09rcrur09rcrVuP09uPcuPVtuPqPVuP09uPcuP09cu09c-V-uT09uTcuTVtuTqP-V-uT09uTcuTuT009c07P7u09ucduvyu>09c>bVbuX09uXcvuXvVtuX>FpFKPYbVbuX09uXcvuXxuX09cvPWcgW09cvV09VclVlptpvu\pPV09Vgvu\u`09u`ud09ud0090W09WV09VP06PJ_u`JOudOVPV_ud pd pth pd  pth ;R;ROn00xuxytyuuuuuxuxyt yuuuuunPWWnVnuLuLuLuLV t uLv#PVnuLuLuLuLnrrrrunrrrr:V:nuPuPuPVtuPqP*:V:nuPuPuPuPOnOUuiniVnuTuTVtuTioqotPVnuTuTuTuTnPnuuunVnuXuXVtuXuXpPVnuXuXuXuXnP6WWnnVVVtu\pP nVVu\9nu`u`9nudud9n00UnWWZnVVZbPPu`udPud)- )- @WWhQxPu@K$!uu0*(WhhhH- Hu|PJWJu|t|Tu|T[W[au|au|8 u|8 K u|K L u|L _ u|_ ` u|` s u|s - u|u}Pwu|wu~Pu|t|Tu|T`u|`au|au~$ u|$ 8 u|8 K u~K L u|L _ u~_ ` u|` s u~s w u|~ u| - u|JWJu|t|Tu|T[W[au|au|8 u|8 K u|K L u|L _ u|_ ` u|` s u|s - u|JSu|SWu|t|Tu|[`W`u|Wu|$ s u|s u Wu - u|u|HTH`H$ - H1u|1SQSu|u|u~ Q Cu|Cu~t~Tu~`u~$ s u~s w u|~ u| u| u| u~  u| - u~(1u}1Sq$Su|#$u}u~ q$ Cu|#$Cu~t~Tu~`u~$ s u~s w u|#$~ u|#$ u} u|#$ u~  u|#$ - u~$ u}T8T8`8$ s 8w ~ 8 - 8TWu|t|Tu|`u|$ s u|w ~ u| - u|Tduw<"   uw<"T8T8`8$ s 8w ~ 8 - 8Td uw<"   uw<"rutTu`au$ 8 uK L u_ ` uw ~ u - urWu|t|Tu|`u|$ s u|w ~ u| - u|wHTH`H$ s H - Hw}u~}PWu|t|Tu|`au|au~$ 8 u|8 K u~K L u|L _ u~_ ` u|` s u~ W - u|wu~Pu|t|Tu|`au|au~$ 8 u|8 K u~K L u|L _ u~_ ` u|` s u~ - u|Wu|t|Tu|`au|au~$ 8 u|8 K u~K L u|L _ u~_ ` u|` s u~ W - u|u~jWju~t~Tu~`u~$ s u~ W u~ W u~ W  u~ & W& - u~ u~HTH`H$ s H - Hu~ Q Cu|Cu~t~Tu~`u~$ s u~ u| u~  u| - u~u~ q$ Cu|#$Cu~t~Tu~`u~$ s u~ u|#$ u~  u|#$ - u~ u~ 8T8`8$ s 8 8 - 8 jWju~t~Tu~`u~$ s u~ W & W& - u~  uw<" 8T8`8$ s 8 8 - 8  uw<")utTu`au$ 8 uK L u_ ` u u - u)jWju~t~Tu~`u~$ s u~ W & W& - u~ujTj`j$ s juWu|t|Tu|`au|au|$ + u|+ - W- 8 u|8 K u|K L u|L _ u|_ ` u|` s u|jTj`oj+ s jVu|t|Tu|`ou|+ / V/ 7 u|7 > V> B tB s u|v#PVu|t|Tu|`ou|/ 7 u|K s u|7 K u|vTv`ov/ 7 vK s vP W/ 1 WvTv`ov/ 7 vK s v V u|t|Tu|`ou|/ 3 V3 7 u|K R VR V tV s u|v#P V u|t|Tu|`ou|3 7 u|_ s u|K _ u| }T}`o}3 7 }_ s } PhW3 5 W}T}`o}3 7 }_ s }DVDu|t|Tu|`ou|3 7 V_ f Vf j tj s u|*v#*/P;DVDu|t|Tu|`ou|_ s u|hT`ohoPoWPRWyT`oyVu|t|Pu|PTV`gVgktkou|yv#PVu|t|Pu|`ou|u|t|Pu|Pu|t|Pu|u|t|Pu|u|t|Pu|P*Pu|t|u|0Pu|u|t|u|0Pu|P0:Pu~t~u~@Pu~!u~t~u~@Pu~0 u~ u}t}u}@Pu~9u|t|u|@Pu|9EP@JPEu~u|t|u~bu~t~u~yu~t~u~u~t~u~u~u}t}u~u|t|u|u|t|u| u}t}u}u~t~u~PPu|t|<u|t|uu|t|Yu|t|u}t}ou|owu|w~P~u|u|u|Ru|Pu|u|Ru|PRRA1`1KuKLtLjuuuuuuuKuKLt Ljuuuuuuu8A`z8?P?WWIA`zIoVoAuD`zuDuDVtuDIUv#UZPfoVoAuD`zuDuDuDuDAu`juuuuuuPWWWVAuH`zuHuHuHAr`zrrWWAr`zrrVAuL`zuLuLVtuLv#PVAuL`zuLuL A`z PQWWA`zOVOAuP`zuPuPVtuP'v#',P8OVOAuP`zuPuPuPQA`zQXPXWW_A`z_VAuT`zuTuTVtuT_gpglPxVAuT`zuTuTuTAu`juuP WimWWVAuX`zuXuXA`z WimWA`zAV`rVrvtvzu\v#PAV`iVmzu\ Au``iu` Aud`iud A0`i0(AW`iW-AV`iV-5P`fPzu`zudPudpR0R0:R:R%1P1P05P5:uQ0:Q%Pj u%PjDWD%uDPjuDuDWuD(r(-P;DWD%uDPjuDuDuDuDegPgWWWV%uHPjuHuHuH%rPjrrrWW%rPjrrrV%uLPjuLuLuLVtuLv#pPV%uLPjuLuLuLuL%PjP-WW%Pj+V+%uPPjuPuPuPVtuPv#pP+V+%uPPjuPuPuPuP-%Pj-4P4xWW;%Pj;]V]%uTPjuTuTVtuT;CpCHPT]V]%uTPjuTuTuTx{P{WY]WWV%uXPjuXuX%PjWY]W%Pj%VPbVbftfju\v#pP%VPYV]ju\%u`PYu`%udPYud%0PY0 %WPYW%VPYVPPVPju`joudovPvud p%d%/  pt%h%/0C CJpJRdR\ 0::CpCDtDRhR\RWWcW@W @D HV Lw @w ud@udP*:Pw*wud*udP'PbiucipRpucbpPzucRuczP&_uu3u&-wx-6P6Owxwx3wx&OWW3W*-wx-6P6Owxwx3wx*OWW3W3W!,u`,0R03u`!0P[bVbctcjtjv|v|[^u`^jPjuP uPuPu`u_Ru_PrxWVrpPrpW0 000rpPrpWwpvpPp wu 3&wpvpWVWVv|vu` u`ud udu` u`ud udu_ u_P Pu`u`u_u_PP:Sw8dnw8w8SMuPnuP3uPSwuPw0PuL3}uL}uP0uP0uP0!uP!/0<@uLJuL0{ { 3{ 1131_uMnuu0:1:LRPnRR(@@3@0Mp;Xp;p;3p;:_udnuuDSuDS0DSuHS_uSlVlwv|}v|V!VSVuPw"VWuD3}uD}WuDWuDWuD!W!uD[lVlwv|}v|V!V[wW}WWW!WuDu`Ru`PVMuPnuP3}uPuPuPuP<@uPJuPWM1n13}1111<@1J1WWWVvVWwxWWvVWWWVu`Ru`PuPuPuPWtwxWWWt wxPuL3}uL<@uLJuLQuT3}uT<@uTJuTM1n13}1<@1J1PVMuDnuD3}V<>VVvx3}V<>VV3}V<>V9PV>Iu`IMRMPu`>MPY}V<>VY}uL<@uLJuLYeuLelWlptpqwxq}W<@WJWelWlptpxwxMuTnuT!Q!Q!MVn~V!4V49vx9MVnxVx~vx!4v49v|9Mvnxvx~v|!9u`?Mu`nu`?JP!4V49vxnxVx~vx-9u`nu`-1PnuPuTuT/8uPuP!/uDbluPlsVswtwxvxxVlsVswtwvx5OUYkU;O_Yd_dhRhk_;CPYhPuT .0v .vW.70v .7v 9<v <EPEIv INvNUPUYvYtveougosRstugesPtVyugRugyP03uT003vv3v v Nvvv v v4P v v4Pv vv 4P vv 4PvPvvugP\v v Lv v \L00Pv uT=Gv GJuT ug=JugP uP<=GPGJuP<wv v =vvw0 =00PvuT*7v7=uTug*=ugPuP<*7P7=uP<v v *vug_ ug _ *ugP 'PV Vug_ ug _P PLQvQXPXevevkrugrvRvugkvPwV|ugRug|Pv Pv q V V v VVWW'*p*2u#*2u# u#4*6P.2u# u#4.6P:Hu# @Hu#u# 4@LPDHu#u# 4DLPPu#u#u#KOu#P0KO0uWWugugPPpu#pu#ugugPPu#u# u#4Pu# u#4P u#  u#u# 4P u#u# 4 Pu# p %P)Fu#2=ug=ARAKug2APPWRW W=JVRjV&=V=JRj&2p|&2P=HPR]P]_ #4=?R?Hp|R]p|]_ #8=JWRjW=J1Rj1?Hr4Rdr4r4X4#p4r4U v#kUU0ur"Q W#:Q:HXHk0Pu1$ #1kPk)^})^ VkVVV0 V#kVQur"R V#kVU v#kUW#kWPH^P 1#k1r4H^r4^kX4 V#HVQ#:Q:HXv#,vW#HW 1#H1r4#:r4:H\4 V vp4PV vp4PMWOWzW7GVObV"7V7GOb"Er|OUr|UW #8"EROURUW #47EROURUW #47:r|:<P<Er|OUr|UW #87GWObW7G1Ob1<Ep4O\p4r4\4 r4ezr4UvNUU0uq"QW"Q"0X0N0zQ1NoQoz vp2&1$NfazfV NVezVV0VNVNur"R0ARVNVUvNUWNWXX0NX1N1q40Aq4AN\4V0VQ"Q"0XRvvW0W101r4"r4"0\4V vp4PV vp4PrRv # v # v Pv#v#l l Rlv#v#vlPvPWRW W=JVRjV&=V=JRj&2p|&2P=HPR]P]_ #4=?R?Hp|R]p|]_ #8=JWRjW=J1Rj1?Hr4Rdr4r4X4#p4r4U v#kUU0ur"Q W#:Q:HXHk0Pu1$ #1kPkp}p VkVVV0 V#kVQur"R V#kVU v#kUW#kWPH^P 1#k1r4H^r4^kX4 V#HVQ#:Q:HXv#,vW#HW 1#H1r4#:r4:H\4 V vp4PV vp4P ESbbiqio3bbiQio3NrNS#S^r^o#;Nr;N;HPPWtt wPW $wPWtt w $w0 0   W $W  uP uPAIuPIWu`ouuPuu`uPu`uPu`uPu` uPuL uLAIuLIWu\ouLu\ uLPcWcuT uTAGWGIuTouWuuTWuTWuT W uTuP uPouuPuu`uPu`uPu`uPu` uPuL uLouLu\ uLPVPQwoVVvudRudPv udRudPMuT uTuT uTcV VVudckPkuT uTuTxV V{uZ uZ{PPuduZRuZPJPVPQwJcwcuT# uT#uT# w uT#uT#pPu uu` u`ud udPPu\udP&Au\,3uZ37R7AuZ,7PWku`]duZdhRhkuZ]hPPWRW W=JVRjV&=V=JRj&2p|&2P=HPR]P]_ #4=?R?Hp|R]p|]_ #8=JWRjW=J1Rj1?Hr4Rdr4r4X4#p4r4U v#kUU0ur"Q W#:Q:HXHk0Pu1$ #1kPk} VkVVV0 V#kVQur"R V#kVU v#kUW#kWPH^P 1#k1r4H^r4^kX4 V#HVQ#:Q:HXv#,vW#HW 1#H1r4#:r4:H\4 V vp4PV vp4P<NZZapak.INZZaPak.IqNVqV[ #$#H[aQ6Iq6I6?R.IQNVQV[#$[aqqu#TWwWWwWVVVu#H V vV/V/2v|P+PPppu#p00*0u#u#u#u#0*0(VVP(VV(ududPPVudRudPpu#lVVVÏ(ÏÏ*Ïpu#lpu#p#Ï#/P'/PRR3Au#`9Au#hu#`49EP=Au#hu#`4=EPIWu#TOWu#\u#T4O[PSWu#\u#T4S[P_mu#Hemu#Pu#H4eqPimu#Pu#H4iqPuu#@PPV(6P6VVVS*jBpu##u#t#ud\udt`PP u#`u#hu#`4Pu#hu#`4P!/u#T'/u#\u#T4'3P+/u#\u#T4+3P7Eu#H=Eu#Pu#H4=IPAEu#Pu#H4AIPqu#zucRuczPu#pPu#pPWvVPNVfnV Qf{+QB v PvuHtHXv8<P<ut0uOXuXv *u1XuEKPKiuP`u 0u)` 0;`BUvu# t# ` vO*v1XvioPouP u #u p #p Bvu#(t#(`vOv v#*v1Xvvu#4t#4`vOv v#*v1Xvvu#@t#@`vOv v#*v1Xvvu#Lt#L`vOv v#*v1Xv,0`0O0 01Q0,vu#t#`vOv v1Qv^0`0O0 01Q0^vu#t#`vOv v1Qv|PvPvvu#t#`vOdv v1Jvvu#t#`vOdv v1JvPut`fPfuOXu u1Jup p Bvu#t#1JvP0Ov6AuSAEREOuS6EPQWvW`P`dvdlvlsPsvv vv4P vv4Pv vv4P vv4Pv vv4P vv4PPuPtLiuPPWPDWeiWD/B,>P-3P3E4: -:N:4>PflVlu !u -uNuuufluDlV !V -VNVVuDV`uD`bVbwuDw{V{uDVuDVuDVuDVuDVuDVuDVuDuDu`Ru`Pu !u -uNuuuuu` !u` -u`Nu`u`u`u`P PWtruP-uPN]uPuPSuP`uPuPPWru-uN]uuSu`uWWttruH-uHN]uHuH1uH`uHuLrW-WN]WW1W`Wru-uN]uuyuruD-uDN]uDuDyuD*ru-uN]uu*6u6TuLTruT-uTN]uTuuL-rud-udN]udud-6PP6ruL-uLN]uLuL6TuLTruT-uTN]uTuL<rud-udN]udud<EPPEruH-uHN]uHuHKrud-udN]ududKTPPTruT-uTN]uTZrud-udN]udZcPNWPcruP-uPirud-udirP'Pud]udududW]WWWu\]|W|u\Wu\uX]uXuXP]gPudmududu`mu`u`PmvPu\|u\ud|udP|PuDudP?rVru\Au\JWu\WYVYvu\vxVxu\u\?Du`DWAWJWWYvu`eoudosRsvudesP|VtuTuTuTuT|PVVuXVuXVuXVuXuXudRudPuuuuXu`uuXu`uPuPPPuXuXuXu`uXu`ududPPuTuTuTudududPPu`u`ududPPu\udPuTuPRuPP.u`!)uP)-R-.uP!-P.Au\4<uP<@R@AuP4@PuduPRuPPuXuPRuPPu\udPuDuCRuCP1uH$1ud$0P1DuT7Dud7CPDSuPJSudJSPbwuLhwudhtP{uXudPudu`Ru`PuduXRuXP uXRuX P=kVku`t\Vu`t\V-u`-3V3|u`_ud-udP|udy~P~u-uud-udu_-u_P'Pu`u`ududPPu`u`5Pu`;Bu_BFRFPu_;FP^xudjqu_quRuxu_juP>SPP58p$8>P58p$#8>p[_P_VBBLp PPPu}t} u}w1;GPRWhWUu}hu}U]PTbP-6u#6:t]u}Tu}fu}Tu}fnPDNPnu}Du}wu}Du}wP4>Pu}4u}u}4u}P$.Pu}$u}u}$u}PPu}u}u}u}PPu}u}u}u}PPu}u}P  u}  u}  R  u}  P  u}  u}  R  u}  PR j u}[ e u}e i Ri j u}[ i Pj  u}s  u}  R  u}s  P  u}  u}  R  u}  P  u}  u}  R  u}  P  u}  u}  R  u}  P  u}  u}  R  u}  P u}Pu}VP,4IOPOPu#P^u}wPF^P: D P  P^:  - G Z  ^u}:  u}- G u}Z  u}^u}:  u}Z  u}V.u}  u}P.u}  u}".u}  u}".P  Ph  u}q  u}  R  u}q  Py  u}  u}  u}  W  P  u}  u}  R  u}  P.Fu}Xu}Xu}Xu}#/ G u}2  V  P+ : 3 5 u} . u}. 2 R2 5 u} 2 P , P e Wr  W e uCr  uC  P  P  u# e u`r  u` e udr  ud  P  P e u\r  u\ e udr  ud  P  P e uXr  uX e udr  ud % P  P% e uLr  uL+ e udr  ud+ / P  P/ e uHr  uH5 e udr  ud5 9 P  P9 e uDr  uD? e udr  ud? C Pr ~ PC e uTI e udI W P uT  uC  R uC  P "uduC!R!"uC!P"4u`(/uC/3R34uC(3P4Fu\:AuCAEREFuC:EPFXuXLSuCSWRWXuCLWPXjuL^euCeiRijuC^iPj|uHpwuCw{R{|uCp{P|uDuCRuCPP\P WW#uu#+P P+u` u`1ud ud19PP9u\u\?udud?GPPGuXuXMududMUPPUuLuL[udud[_PP_uHuHeududeiPPiuDuDoududosPPsuTyudyP%@uT+2u26R6@u+6PH\uDNUuUYRY\uNYPdxuHjququRuxujuPuLuRuPuXuRuPu\uRuPu`uRuPuRuPuQP*uEu*uGuGREuG*3P3>u<P*>uLW6>uHu6APP>LuPuPDLuLuLDOPPLZuTuTRZuPuPR]PPZhuXuX`huTuT`kPPhvu\u\nvuXuXnyPPvu`&u`|u\&u\|P7P* E Z K Xy *uEuZuKuXyu* E Z > Xy *uEuZu>uXyudouPosRsyuPdsP*0EZ-*u06W6EuZu-u*EEZ -*WEEWZeWeuLWuLW W-uL -uL#uH#'R'-uH'P*F SEF ZF F *WSEWZeWeuLWuL*F fEF ZtF F *ufEuZtuu\tuHhouGosRstuGhsPtuLzuGRuGzPuPuGRuGPuTuGRuGPuXuGRuGPu\uGRuGPu`uGRuGP#P#)2V23#P#)2V2369p$#9?p?CPJSPuVxusRusxPusRusPV$'p$'0P$'p$#'0pnwPwVVmpPp~VVV57VV^V-0P0utvuvwwmu)u utwPwVVVV57VV^V   * 5I Vh uuu*u5IuVhuu#P   5I Vh uuu5IuVhuu#P5IVhuuu5IuVhuu#Puuu5IuVhuuuu5IuVhuu#P U  uu#P  F  u  V pP _  u u#D u`u`#Eu`u`5Iu`Vhu`E005I0Vh0*u`u\u\Vhu\u\u\u`u`PPuX uXu\VP'PuT(6uTu\.6u\P.GPuHHVuHu\NVu\PNgPuDhvuDu\nvu\PnPu@u@u\u\PPuPuPu\u\PPVVuu R uPv< PAVAutvuvwwmu~V)u uuXtTvuXvwPwmuX~uX)uX uXP~PAVuXo}uXNVu\u}u\NYPuPVduTuT\du\u\\gPPdruHuHjru\u\juPPruDuDxu\u\xPPu@u@u\u\PPuPuPu\u\P'PAu\\5u\Au_jujnRn5uAKPKVu\<_nP5Tu5utvuvwwmu.u up|P3u\wu\-mu\6uwu-mu6>P]gP>uXwuX-]uXDu\wu\-]u\DLPMWPLuTwuT-MuTRu\wu\-Mu\RZP=GPZuPwuP-=uP`u\wu\-=u\`hP-7PhuDwuDnu\wu\nvPPvu@wu@|u\wu\|Pu@<wPuuu\u\PPuLu\Puudp$Pp~PK[P9u\-u\9u-uP'P9uXuX9u\u\P P9uT uT9u\ u\PP9uPuP9u\u\PP9uDuD9u\u\PP9u@u@9u\u\PP9uu9u\u\PP9uL$9u\$/P0DuL6=u=ARADu6APFZuLSuSWRWZuLWP\pu@biuimRmpubmPruDxuRuxPuPuRuPuTuRuPuXuRuPu\uRuP`vuvwQ`vu`vwXiw1ivuvwQu\uRuPuXuRuPuTuRuPuHuRuPuDuRuPu@uRuPuP uRu P7Iu\=IuX=IPl|u\r|uXr|PP V  V!!Vy##VpRr  l 7""l ""l ",#l ##l   V  t  t  uP7""uP""uP",#uP##uP&  l 7""l ""l ",#l ##l & n Vn  uT7""uT""V""uT""V"#uT##V#*#uT*#,#V##V##uT##ud##R##ud##P?  7""",#? E WE F tF J tJ  u`7""u`",#u`T  7""#,#T  W7""W##W#*#ud*#,#Wq  W7""Wt  uG7""uGt | PL"W"P|  u`7"L"u`]""u`  ud7"L"ud]""ud  P]"f"P  uT7"L"uTl""uT  ud7"L"udl""ud  Pl"v"P  uP7"L"uP|""uP  ud7"L"ud|""ud  P|""P  uL7"L"uL  ud7"L"ud  P7"F"P  u\  ud  P !u!!t!!u  V!!V!!I!7"I""I,#y#I!!!7""",#y#1!! "" ,#d# w#y# 1!!"",#d#w#y#^!b!t^!b!t^!b!Pb!!Vw#y#V!!W""W!!u\""u\!!P""P!!u`!!ud!!P"6"u6"7""6"u6"7" " "t" "t" "P "4"V4"6"u6"7"""uT""uG""R""uG""P""uP""uG""R""uG""P""uL""uG""R""uG""P""u\""uG""R""uG""P"#u`##uG# #R ##uG# #P#*#ud###uG##'#R'#*#uG#'#P.#F#ud:#A#u\A#E#RE#F#u\:#E#PF#Z#u`L#S#u\S#W#RW#Z#u\L#W#P##u%%P%Z&uZ&[&t&'u'''K(u()u)*u*(*u $$P$o%V[&&V$o%uC[&&uC$$P&&P$o%u`[&&u`$o%ud[&&ud$$P&&P$o%u\[&&u\$o%ud[&&ud$%P&&P%o%uX[&&uX%o%ud[&&ud%%P&&P%o%uL[&&uL%o%ud[&&ud%%%P|&&P%%o%uH[&|&uH+%o%ud[&|&ud+%7%Pl&v&P7%o%uD[&l&uD=%o%ud[&l&ud=%I%P[&f&PI%o%uTO%o%udO%a%PM(c(uXS(^(uC^(b(Rb(c(uCS(b(Pc(y(uLi(t(uCt(x(Rx(y(uCi(x(Py((uH((uC((R((uC((P((uD((uC((R((uC((P((uT((uC((R((uC((P1*G*ud7*B*uCB*F*RF*G*uC7*F*PG*]*u`M*X*uCX*\*R\*]*uCM*\*P]*|*u\c*r*uCr*v*Rv*|*uCc*v*P%<&V&(K(V%<&uP&(K(uP%&P&(-(P&<&u\3(K(u\ &<&ud3(K(ud &&P3(9(P&<&uX?(K(uX&<&ud?(K(ud&*&P?(E(P*&<&uT0&<&ud0&<&P<&N&u`''u`B&N&ud''udB&V&P''Ps''V'&(Vv''uH'&(uHv'~'P''P~''u\(&(u\''ud(&(ud''P((P''uX (&(uX''ud (&(ud''P ((P''uT(&(uT''ud(&(ud''P((P''uP(&(uP''ud(&(ud''P(#(P''uL''ud''P((uL((uH((R((uH((P((u`((uH((R((uH((P( )ud()uH) )R ) )uH( )P )")u\))uH)!)R!)")uH)!)P")8)uX()3)uH3)7)R7)8)uH()7)P8)N)uT>)I)uHI)M)RM)N)uH>)M)PN)m)uPT)c)uHc)g)Rg)m)uHT)g)P{))uX))uP))R))uP))P))uT))uP))R))uP))P))u`))uP))R))uP))P)*u\))uP)*R**uP)*P*(*ud*!*uP!*%*R%*(*uP*%*PPWRW W=JVRjV&=V=JRj&2p|&2P=HPR]P]_ #4=?R?Hp|R]p|]_ #8=JWRjW=J1Rj1?Hr4Rdr4r4X4#p4r4U v#kUU0ur"Q W#:Q:HXHk0Pu1$ #1kPkT2}T2 VkVVV0 V#kVQur"R V#kVU v#kUW#kWPH^P 1#k1r4H^r4^kX4 V#HVQ#:Q:HXv#,vW#HW 1#H1r4#:r4:H\4 V vp4PV vp4PJu u Wudt`W)CV)1w#9=p=BPu ud0ud#PXudt`X0PWRW W=JVRjV&=V=JRj&2p|&2P=HPR]P]_ #4=?R?Hp|R]p|]_ #8=JWRjW=J1Rj1?Hr4Rdr4r4X4#p4r4U v#kUU0ur"Q W#:Q:HXHk0Pu1$ #1kPk<}< VkVVV0 V#kVQur"R V#kVU v#kUW#kWPH^P 1#k1r4H^r4^kX4 V#HVQ#:Q:HXv#,vW#HW 1#H1r4#:r4:H\4 V vp4PV vp4P:Q@DQTnQ'Pw4Tnw4OVOTTnVTdR6W6:t;vW(BVWmV(BUWmU(6W6:tWmW(6w6:t#WmwZjP(BU(6W6:t(B1{XR,P,,P,;R;GWGX;W;GwGWW;;GwGKX#KwwV]V]^pt;KUV[Q[U;KPkPVgPX#rUVPP\RP0#0u`0t\0u`0V0u`:uu:u u HNPPuT +P+:uTLNPP :1:H0HNQN10Q1P Q0P:u :uT4tP4u uT4tP4uT4Nfu LNpNfu:ud:NVZV:CPwP:NWlWPud:Nu\lptpu\u u@VRuXRRPPu\tXu\udt`ud LuP#Kuu#u`t\Vu`#00#Ku u _WPWW1W/Ku /_u`#u`#/Ku@IWIJpt@_VVT_PP@_u`#u`#@PR@PP_wuwxtx|tu_11_00nwuwxtx|tun|PPuP0:P:Pu4Pu40   u~ +P+Wu}}u}Wmu}+u~+6P6u~~mu~qWu}}u}Wmu}u~Qu~}u~u~+mu~u~jHH+EHGmHju~Ru~~u~u~+Eu~Gmu~u~r$u~#$~#$u~#$u~#$+Eu~#$Gmu~#$+u~u u u +4u u~}u~u~+Au~00+A0pu}}u}u}}u} u~~u~u~~u~%u~~u~%1PP1u~~Nu~~ju~~u~~u~~**uP*,+uH,+/+tDH++uH**uH**P*,+uH,+/+tDH++uH*,+uH,+/+tDH++uH**uP**P*,+uP,+/+tLH++uP+++W++,+u`,+/+t\H+i+W+,+u_,+/+t[H+i+u_++PH+W+P+,+ud,+/+t`Z+i+ud+,+u`,+/+t\Z+i+u`+#+PZ+f+Pt++udz++u_++R++u_z++P++u_++R++u_++P,,u,.u,,u,,P,.u, ,u ,(,P(,.u2,.jV..j2,-V-.u`V.X.VX.Z.u`Z.^.V^.k.u`k.m.Vm.|.u`|..V..u`D,-jZ..jD,g,Wg,-uPZ.k.Wk..uPD,M,w#M,R,P^,g,Wg,-uPk..uP^.k.uPx,-k..x,,P,,uk.n.u,-k..,,W,-uTk.|.W|..uT,,w#,,P,,W,-uT|..uTm.|.uT,-|..,,P, -u|.}.u,-|..,,W,-uX|..W,,w#,,P,,W,-uX -- --P--u--u--u----W-#-w##-(-P6--W--u\\--V\--ud\--0|--Q--Q--u--W--W--P--P--uH--u`--P--P--uL--u`--P-.u`-.ud. .P ..ud.).uH.$.uG$.(.R(.).uG.(.P).E.uL/.7.uG7.;.R;.E.uG/.;.P..u.u1u..u..P.u1u./u/ /P /u1u/0j01j:1q1j/0V01V11u`:1>1V>1K1u`K1M1VM1\1u`\1`1V`1m1u`m1o1Vo1q1u`)/0j0 1j:1m1j)/L/WL/0uP0 1uP:1\1uP\1m1W)/2/w#2/7/PC/L/WL/0uP0 1uP:1\1uP`1m1uP]/0v0 1v:1\1v]/d/Pd//uK1N1un/0v0 1v:1\1vn//W/0uT0 1uT:1K1uTK1\1Wn/w/w#w/|/P//W/0uT0 1uT:1K1uTM1\1uT/00 1:1K1//P//u:1;1u/00 1:1K1//W/0uX0 1uX:1K1W//w#//P//W/0uX0 1uX>1K1uX/00 1//P/o0u00u00u/00 1/0W0 1W/0w#0 0P00W1 1u\A00VA00udA000a0s0Q00Q00ul00W00Wl0s0P00P00uH00uH00u`00u`00P00P00uL00u`00P00uL00uG00R00uG00P 11u` 11ud11P11ud1:1uH)131uG3171R71:1uG)171P11u1e4u11u11P1e4u11u11P1e4u23j3 4j*4a4j23V33V3 4u`*4.4V.4;4u`;4=4V=4L4u`L4P4VP4]4u`]4_4V_4a4u`23j33j*4]4j2<2W<23uP33uP*4L4uPL4]4W2"2w#"2'2P32<2W<23uP33uP*4L4uPP4]4uPM239 339 *4L49 M2T2PT22u;4>4u^239 339 *4L49 ^22W23uT33uT*4;4uT;4L4W^2g2w#g2l2Pz22W23uT33uT*4;4uT=4L4uT2333*4;422P22u*4+4u2333*4;422W23uX33uX*4;4W22w#22P22W23uX33uX.4;4uX233322P2_3u33u33u233323W33W22w#22P 33W33u\133V133ud1330Q3c3Q33Q33u\3o3W33W\3c3P33Po33uH33uHu33u`33u`u3z3P33Pz33uL33u`33P33uL33uG33R33uG33P3 4u`34ud4 4P 4 4ud 4*4uH4#4uG#4'4R'4*4uG4'4P44u4U7u44u44P4U7u44u44P4U7u46j66j7Q7j46V66V66u`77V7+7u`+7-7V-7<7u`<7@7V@7M7u`M7O7VO7Q7u` 56j66j7M7j 5,5W,56uP66uP7<7uP<7M7W 55w#55P#5,5W,56uP66uP7<7uP@7M7uP=56? 66? 7<7? =5D5PD55u+7.7uN56? 66? 7<7? N55W56uT66uT7+7uT+7<7WN5W5w#W5\5Pj55W56uT66uT7+7uT-7<7uT56667+755P55u77u56667+755W56uX66uX7+7W55w#55P55W56uX66uX7+7uX566655P5O6u66u66u566656W66W55w#55P56W66u\!66V!66ud!660A6S6Q66Q66uL6_6W66WL6S6P66P_66uH66uHe66u`66u`e6j6P66Pj66uLp66u`p66P66uL66uG66R66uG66P66u`66ud66P66ud67uH 77uG77R77uG 77P77u7E:u77u77P7E:u77u77P7E:u79j99j :A:j79V99V99u` ::V::u`::V:,:u`,:0:V0:=:u`=:?:V?:A:u`79j99j :=:j78W89uP99uP :,:uP,:=:W78w#88P88W89uP99uP :,:uP0:=:uP-89F 99F :,:F -848P48v8u::u>89F 99F :,:F >8s8Ws89uT99uT ::uT:,:W>8G8w#G8L8PZ8s8Ws89uT99uT ::uT:,:uTv8999 ::v8}8P}88u : :u8999 ::88W89uX99uX ::W88w#88P88W89uX99uX::uX899988P8?9uu99u99u899989W99W88w#88P89W99u\99V99ud99019C9Q99Q99u<9O9W99W<9C9P99PO9u9uH99uHU9u9u`99u`U9Z9P99PZ9u9uL`9u9u``9o9P99uL99uG99R99uG99P99u`99ud99P99ud9 :uH9:uG::R: :uG9:P%3U37 v5&jnUnp v5&7|v|vhvVvvxp8vvpp@vh7WW W W7|v|vhvVvvxp8vvpp@vh7FvFGtGKPS|v|vpvVpvvxp8vpSWW W WS|v|vpvVpvvxp8vpSYvYZtZ^Pf|v|vxvVpvxfWW Wf|v|vxvVpvxflvlmtmqP7|V|v`VVvxVvpp@VvhpHv`7WW W W7|V|v`VVvxVvpp@VvhpHv`vtP7qqSqqfqq 6U 6W 6U &u&'t'+P36q6LU6LW6LU6<u<=t=APILqL_UL_WL_ULRuRStSWP#DRRDgwgqwtwRw-wtDqu-uDq - DgwgqwtwRw-wtVUPPgwgqwxw-wxPqu-uPq - Pgwgqwxw-wxVUPXgw gqw|w -w|Xqu-uXq - Xgw gqw|w -w|VUPDgWgqwpqWWr|W-wpDu-uD - DgWgqwpqWWr|W-wpxVxUxPDqW-WPqW-WXqW-WT^VVT^uuT^  T^VVUR\P[^W^wV^wu^w ^wVewUeoReoPVv|Vu Vv|V QR\RPW)7P7= v4&=W_nWnr rWBRPBW_nWnr rW^W_nWnr rWaqPaW_nWnr rW}WrWPWrWWWPWWWPW 8-W"P-W*-8-GW/?P/GW^8_8}8r888/;[;W];s;W8<}<Wt:z:Vz:{:t{::t:\;uP\;];H];<uP<<tL<=uPt:z:uTz::V::t:\;uT\;];L];<uT<<tP<A=uTA=G=VG==uT::p:\;u#T\;];#T];<u#T<=u#T,=A=u#Td==u#T::p:\;u#X\;];#X];i;pi;;u#X;;q;<u#X<<r<=u#X,=A=qd==u#X:\;u#T\;];#T];<u#T<=u#T,=A=u#Td==u#T:\;u#T\;];#T];;u#T;;r;;u#T;;Q;<u#T<=u#T,=A=Qd==u#T::V::t:\;uT\;];L];<uT<<tP<A=uTd==uT::u#X:\;u\;];];;u<<u<=ud==u:;W<<Wd=l=W==W==W==W::uX::P::V:\;u\;];];<u<<t<A=ud==u==V==u::V:\;u\;];];<u<<t<A=ud=~=u==u::u`::P::V:\;u\;];];<u<<t<A=ud=j=Vj=~=u==u==V==u::V:\;u\;];];<u<<t<A=u==u==V==u::P:\;u\;];];;u;<u\<<u<<u\<<tX<=u=A=u\==u:\;u\;];];<u<<t<A=u==u:;u;;ud;!;u\!;/;uX/;=;uT<<u< <u\ <.<uX8<F<uT}<<ud==u==u\::Q:\;u@\;];];<u@<<Q<<u@<<t<A=u@==u@::P<<P==ud==R==ud==P:\;u\\;];T];<u\<<u\<<tX<A=u\==u\:\;ud\;];\];<ud<<ud<<t`<A=ud==ud;\;ud\;];\];<ud<<ud<<t`<A=ud==ud;;ud;\;u\\;];T];<u\<}<u\}<<ud<<u\<<tX<A=u\==u\;;ud;!;u\!;/;uX/;=;uT< <u\ <.<uX8<F<uT}<<ud ;\;u`\;];X];<u`<<u`<<t\<A=u`==u` ;;P}<<P;\;u\\;];T];<u\<}<u\<<u\<<tX<A=u\==u\;!;u\!;/;uX/;=;uT< <u\ <.<uX8<F<uT;\;ud\;];\];<ud<}<ud<<ud<<t`<A=ud==ud;$;P$;/;u\<<<P!;/;uX <.<uX!;/;uX/;=;uT <.<uX8<F<uT';/;ud&<.<ud';2;P&<7<Pl=~=uXr=y=uOy=}=R}=~=uOr=}=P==u\==u`==P/;=;uT8<F<uT5;=;ud><F<ud5;@;P><W<P=;K;uPX<f<uPC;K;ud^<f<udC;K;P^<w<P;<ud<<ud<<t`<A=ud;<u\<<u\<<tX<A=u\;;P< =P;;P;;u#|;<u#,=A=w;<u`,=A=u`;;R,=3=R3=5= w2$q";;Q;<u#T,=A=Q;; rq4,=3= rq43=5= w2$4,=A=Q,=A=u`,=8=P<<u`<<u`<<u#T<<r<<u#T<<u#T<<u`<<P<<q=&=q<<ud<<t`=,=ud<<q=&=q<<q<<ud<<P<<qI=[=uPO=V=uOV=Z=RZ=[=uOO=Z=P~==uT==uO==R==uO==P==ud==u\==Pm>>V>>P>?V @ @Vm>>W>>ud>>t`>?W @"@Wp>>u_>>t[>?u_ @"@u_p>{>P??P{>>u`>>t\>?u`??u` @"@u`>>ud>>t`>?ud??ud @"@ud>>P??P>>V>>P>?V??V @ @V>>u >?u ??u @"@u >>u>?u??u @"@u>>P>>uP>>tL>?uP??uP @"@uP>>p>>uP#>>tL#>?uP#??uP# @"@uP#>>p>>uP#>u?uP#??uP# @"@uP#>>V>>Pu??V>>v>>pu??v>>P>u?ud??ud @"@ud>>uP#>>P>u?uP#??uP# @"@uP#>u?ud??ud?u?u`??u`? ?P??P ?u?uP#??uP# @"@ud@"@u`@@P??ud??u_??R??u_??P??u`??u_??R??u_??P55=P=5~W~WWEJPJ}V}~w~VVSfPfUPUUVV~W~WWVfRfn\nu Ru V}V}~w~VVXnVXnWXfRfn\Rn}V}~w~VnUU@pAuDpAAuXAAtTAAuDAAuXAAPABuDBCuD CCuD@@R@@u@@RB+BR+BTBuL@KAuABuBBu CCuC6CuU@AWAAudAAt`AAWAAudAA\ABWBBudBBWB Cud CCWCCudCCWC6CudBBudBBu`BBRBBu`BBP3@KAu ABu BBu CCu C6Cu l@@VBBVCCVl@AWAAudAAt`AAWAAudAA\ABWBBudBBWB Cud CCWCCudCCWC6Cudv@@VCCVv@pAuDpAAuXAAtTAAuDAAuXAAPABuDBCuD C6CuD!C,Cu`,C0CR0C6Cu`!C0CP@AWAAudAAt`AAWAAudAA\ABWBBWBCud CCWCCud@Au`AAt\AAu`AAXABu`BCu` CCu`@@PTB_BP@TBeBBBC CC@TB-eBB-BC- CC-@@u\@@P@GAuGAAu\AAtXAAu\AATABuBTBu\eBBuBBuBCu\ CCuCCu\@@u\@Au`AAt\AAu`AAXATBu`eBBu`BCu` CCu`@Au`AAt\AAu`AAXATBu`eBBu`BCu` CCu`@@uV@@P@GAuABueBBuBBu CCu@@Q@GAu@ABu@eBBu@BBu@ CCu@@@u@@R@GAudABudeBBudBBud CCud@GAudABudeBBudBBud CCud@@P@GAuABueBBuBBu CCu@GAudABudeBBudAGAuWABuWeBBuWA APeBoBPAGAudABuduBBudA!Au`!A'AP'AGAu`ABu`uBBu`.AGAudABuduBBud1AGAuWABuWuBBuW1A9APuBBP9AGAu\ABu\\AfAu`AAu`bAfAudAAudbAiAPAAPfApAu\AAu\lApAudAAudlAsAPAAPpAzAuXAAuXvAzAudAAudvAAPAAPAB ABu\B+BR+B=Bu@=BTBuB6Bu\6BDu\DDu8EXEuXEYEPEEuEE0mCC0C5Eu8EWEWWEXEuXEYEtYEcEuEEuEE0sCvCpvCCu#T8E>Ep>EXEu#TXEYEt#TEEu#TEEt#TCCPCCWCXEuPXEYEtLYEcEuPEEuPCXEu`XEYEt\YEcEu`EEu`CC0CEWEEWCCw C\DuP# \DbDp bDEuP# EEuP# CrDVuDEVEEVEEVCeDuTDEuTCDPDDPDDvD+D1DE1+D>D0DE1>DGDPGDVDuP#,EEq,>DrDuPEEQEEuPDDrDudEEudJDrDu_EEu_JDVDPEEPEEudEEu_EEPCcE0EE0CCWCXEuPXEYEtLYEcEuPEEuPEXEu`XEYEt\YEcEu`&EXEudXEYEt`YEcEud&E.EPYE`EPEEu`EEudEEPE'FW'F(Fu (F+Ft+FIFWIFJFu JFMFMFXFW FFugFFRF(Fug(F+FtcVFXFug FFP F'FW'F(Fu (F+FtVFXFW F&FV&F+FPVFXFVF$FP$F&Fv&F+FpF&FV&F+FP`FF FFWIIVIIDIIVAJXJDXJgJVgJJD}FFWFJ~FFwFFPFFLFFPFJFFLFFPFJFGWGHWHI0#J?JW?JJ0G(H0(H=H1cHH0FGWGHW#J?JWFFDFGVFFPFGWFGHGGPGGPGGGI#J=J?JJGGGI#J=J?JJ+GG +GG~+G=G~#=GBGPIGGIGG~IGSG~#SGXGPbGGL bGG~bGkG~#kGpGP}GGGGDGGPGHVHHPHTHVcHHVG=H#GH/HHvHHtH HtG=H(H=H(H=H=HTHIHTHDIHTHPcHHh cHH~cHzH~#zHHPHHHH~HH~#HHPHHX HH~HH~#HHP%J=J+J6JD6J:JR:J=JD+J:JPGGWGGWGG,HI,?JJ,GGwGGPHHWHHPHIWIIW?JJWHI#-I~Iw IIw -I~I~II~-I;I~#;I@IPHHHH IIHH IIHH IIHH#II#I(IP~IIPDI~IwIIwDI~I~II~II~dI~IdIpI~#pIuIPIIAJJIIVIIDIIVIIIIPIIPIIII~J#JJ#J~CJXJDIJQJ@QJUJRUJXJ@IJUJPXJgJVgJJDJJJJ@JJRJJ@JJPJJ@JJRJJ@JJPJJJ*KWKKKWKKWJoKuTqKKuTKKuTKKuTKKuTKKtPKLuTHKKPKKvKKPKKPJ*KWKKWKKugK$KP$KKugKLugKKPKKVKKVK*KWsQsu}>sPsP>iGiPj@kW"j@ku}"j.jPjjP.jju{j@ku{7jju}j@ku}7jCjP0k:kPCjju{j0ku{Ljju}j0ku}LjXjP k*kPXjju{j ku{ajju}j ku}ajmjPkkPmjju{jku{vjju}jku}vjjPj kPjju{jju{jju}jju}jjPjjPjju{jju{jju}jju}jjPjjPjju{jju}jjPmmu{mmu}mmPmmu{mmu}mmPm nu{m nu}m nP n)nu{n)nu}n(nP)nEnu{2nEnu}2nDnPEnanu{Nnanu}Nn`nPan}nu{jn}nu}jn|nP}nnu{nnu}nnP@klkuUklkuUklku}bkku}kkt}klu}[mkmu}bkxkVxk}kv|}kkVklV[mkmVbkk5kl5[mkm5bkku}bkku}}kk5kku}kkt}klu}[mkmu}kk u}u}4kkPkk u}u}4kkPbkk1kl1[mkm1bklkukkuzkktzkluz[mkmuzkku~kkt~klu~[mkmu~kkP[memPkkuzkktzkluzkku~kkt~klu~kkPk lPnnu}nnWnnw|nnWnn7nnu}nnu}nn7nnu}nn u}u}4nnPnnPnnuznnu{nnPnouzn ouz ooRoouznoPuqqu{~qqu~~qqPqqu}qqu}qqRqqu}qqPqqu}qqu}qqRqqu}qqPqru}rru}rrRrru}rrPr9ru}$r2ru}2r6rR6r9ru}$r6rPu!vu}vvu}vvRv!vu}vvP#vAvu},v:vu}:v>vR>vAvu},v>vPCvavu~LvZvu}Zv^vR^vavu}Lv^vP}vvu}vvu}vvRvvu}vvPvvu}vvu}vvRvvu}vvPvvu{vvu~vvPvvu{vvu~vvPvwuzwwu~wwPw4wu{!w4wu~!w3wP4wPwu{=wPwu~=wOwPPwuwu{Ywuwu~YwowPwwwu{wwu~wwPwwu{wwu~wwPwwu{wwu~wwPwwu{wwu~wwPwxu{xxu~xxPxx\xu{Gx\xu~GxYxPxxu}xxu}xxRxxu}xxPxxu}xxu}xxRxxu}xxPx yu}xyu}yyRy yu}xyPy"yu}"y&yR&y)yu}y&yP0yUyRUyyVyyRyyVyBzRBzmzVmzzRz5{V5{v{Rv{{{V{{{R{{V{{R{{V{{R{{V{"|RIyUyRUyyVyyRyyVyBzRBzmzVmzzRz5{V5{v{Rv{{{V{{{R{{V{{R{{V{{R{{V{"|Ray1z z{ {{ {{ || ayyVyyRyyVy1zRz5{V5{v{Rv{{{V{{{R{{R{{R{{V{{R ||Rxyy z{ {{ xyyVyyRz5{V5{v{Rv{{{V{{{R{{R{{V{{RyyuPyyPy1z{{ ||y1z0{{0 ||0y1zuP{{uP ||uPy1z0{{0 ||0y1z{{ ||y1zuP{{uP ||uPy1z6{{6 ||6y1z0{{0 ||0z1zuP{{uP ||uPzzVz1zuL{{uL ||uLz1z0{{0 ||0z1z{{ ||z1z1{{1 ||1zzz1zW{{W ||Wz1zV{{V | |Vz)zW)z1zw|{{W ||Wz,zV,z1zv|{{V | |V{{V | |V{{uL ||uL{v{{{{v{{{{v{uP{{uP{{W{{uP*{v{{{*{v{{{*{v{uP{{uP{{W{{uP*{v{6{{6*{v{0{{0A{v{uP{{uP{{uPA{P{VP{v{uL{{uL{{uLA{v{{{{{A{v{{{{{A{v{1{{1{{1A{P{P{v{W{{WA{v{V{{V{{VP{i{Wi{v{w|{{WP{l{Vl{v{v|{{V{{V{{V{{V{{uL{{uL{{uP{{uP#uP4{{P{{uP#uP4{{PBzz@{{@{ |@|"|@Bzz`{{`{ |`|"|`BzzuP{{W{ |uP|"|uPbzz`{{`{ |`|"|`bzz@{{@{ |@|"|@bzzuP{{W{ |uP|"|uPbzz8{{8{ |8|"|8bzz0{{0{ |0|"|0yzzuP{ |uP|"|uPyzzVzzuL{ |uL|"|uLyzz`{ |`|"|`yzz@{ |@|"|@yzz1{ |1|"|1yzz@zzW{{WyzzV{ |V||VzzWzzw|{{WzzVzzv|{ |V||V{ |V||V{ |uL|"|uLz{VzzPT|}W}~u\~~tX~b~W_|?}uP~V~u_|b|Pb|n|Rn||u@T|n|w|4} P~b~ |4} |4}u|4} |}R}4}u}4}u }4} }'}P4}?}u?}@}t@}G}tP}#~u6~P~uP}S}uV}Z}tw}#~! w}}V~#~V}}u@}~uX~~tT~#~u@}#~}}P}}u@}~uX~~tT~#~u@}~uT~~tP~#~uT}}P~~P}~u\~~tX}~u\~~tX}}W}}V}}V}}v|}~V}}V}}v|}}V}}v|}}uX}}uX}}P}}P}~u\~~tX}~ udu\4}~W}~ udu\4} ~W8~P~uX>~I~uTI~M~RM~P~uT>~M~P~~P~MuMNtNutu0vuyPMuMNt~Nut~2us~uuTtuхu2uu!fVfMuMNtNutVuхuޅu2uu$Mu~MNt~Nu~t~u~хu~ޅu~2u~u~$/P/:v<P,:uu2:u~ud2:PP:uTtuхuu:u# Ttu# хu# u# DFPFPu# VTtVudTtudPT^PudtuuddtudPdnPuu#Pu#V4TVud4TudPDNPu4Du ud4Dud P4>PnVMuMNtNut҄V҄4utu2uCuxuqMudMNt`Nudt`4udtud2udCudxudq|P|v<Pyu„uud„udP̄PҀMu~MNt~Nu~t~҄4u~tu~2u~xu~ՀMudMNt`Nudt`҄4udtud2udxudՀPu~<҄܄P݀V݄u@ududPP9MuMNtNut4u2u<MudMNt`Nudt`4ud2ud<GPGRu<PDRVuLJRud udJRP PhMu\MNtXNu\tX$4u\2u\hluostzMu\MNtXNu\tX$4u\2u\}MudMNt`Nudt`$4ud2ud}P$.P0MuMNtNut2uVVVVȆʆVІ҆VVvvvvȆʆvІ҆vvҁVVVVȆʆVІ҆VVҁv v v v Ȇʆv І҆v v >u u2juІu >ud ud2judІud PP3>u~ u~2Xu~̆u~I>r  r 2Xr r r ILuOStZ>uX uX2XuXuXo>   2X  owP~>uX uX2XuXuX>ud ud2XududPЃڃP>uTЃuT uT2XuTuT>udЃud ud2XududPʃPVvł>u`u` u`2Xu`u`Ȃ>udud ud2XududȂЂP P>udud ud>u`u` u`PP>    ut>u\u\u\>ududud&PP&>uLuLuL,>ududud,4PP4>uHuH:>udud:>PP4Fud:Fu`:EPFXu\LXu`LWPXjuL^juP^iPjuHpuDpPu`udPuXudPȆuT†Ȇud†ȆP҆uP؆ud؆P?FufmuBFudimudBNPiwPvuH|ud|PuLudPuuRuPDžuDžudƅPDžхuͅхudͅхPu\udPuudPuudP"u"ud!P"2u(2ud(2P0uD!0ud!/P0Cu@6Cud6CPEXuKXudKXPaxugxudguPu*u*+t+GuGHtH@u\uuu3u3FuFkuPNV*u*+t+GuGHtHlVl@u\|ukuQ*u*+t+GuGHtH@u\|ukuQ_P_kv<HOP\kuP_ubkuV_udbkPVfPV*u@*+t+Gu@GHtlV@u@\|u@u@ u@3Fu@]ku@*u`*+t\+Gu`GHt\l@u`\|u`u` u`3Fu`]ku`ĈPĈЈv<lsPЈutuLjЈu`zu`LjЈPzPZVZ*uH*+tD+GuHGHtDV@uH\|uHuHuH3FuH]kuH*u`*+t\+Gu`GHt\@u`\|u`u`u`3Fu`]ku`)P)5v<P&5uuD,5u`u`,5PPV*uP*+tL+GuPGHtL؋V؋@uP\|uP3FuP]kuP*u`*+t\+Gu`GHt\@u`\|u`3Fu`]ku`Pv<PuˋuLu`‹ˋu`P‹ҋP*u*+t+GuGHt؋ u\|u3Fudku*ud*+t`+GudGHt`؋ ud\|ud3FuddkudPu<؋ߋPVuXududPP8*u`*+t\+Gu`GHt\ u`3Fu`;*ud*+t`+GudGHt` ud3Fud;GPGSu`<PDSu\u\JSud udJSP PS)W+FW3FWg*ud*+t`+GudGHt`3Fudgu+8u3Fu*ud*+t`+GudGHt`*u`*+t\+Gu`GHt\P+2P0(V8EV*u*+t8GuGHt P*u*+t8GuGHt*ud*+t`8GudGHt`+P8?P"5uT(5ud(4P5@uX;@ud;@P@\uFNuNRRR\uFRP^qu`dquddpPq|u\w|udw|PuudPuudPÌ֌uPɌ֌u`ɌՌP֌uL܌u`܌P5Fud;Fu`;FP uH u` P uDu`P"3u(3u`(3PH]u@N]u`NZPݍ}u}utu͒u͒ΒtΒQumuŔuݍPSVut͒u͒ΒtΒVQumuuuVu`t\͒u`͒Βt\ΒQu`mu`u`u`VdPdpv<ΒՒPapu֒ugpu`ܒu`gpPܒPVut͒u͒ΒtVQumuԓuuu`t\͒u`͒Βt\Qu`mu`ԓu`u`ɎPɎՎv<PƎՎu u̎Վu` u`̎ՎPPbVbut\u\iVi͒u͒Βt$V$Qumuԓuu(1R1ut͒u͒ΒtRQumuԓuu(1PP1ut͒u͒Βt$Qumuԓuu7u`t\͒u`͒Βt\$Qu`mu`ԓu`u`7@P\cPVut\uiV͒u͒Βt$1umuԓuuudt`\udi͒ud͒Βt`$1udmudԓududPv<ipPuqu@udwudPwP.u.uHtDBuHBOuO\uHu͒uH͒ΒtD$1uHԓuHudt`\ud͒ud͒Βt`$1udԓudPPuDt@\uD͒uD͒Βt@$1uDԓuDudt`\ud͒ud͒Βt`$1udԓudPBIPKuuPtL5uP5BuO\u͒uP͒ΒtL$1uPԓ uP6uPNudt`BudO\ud͒ud͒Βt`$1udԓ ud6udNWPOVPWuLtHBuL͒uL͒ΒtH$1uLԓ uL6uL]udt`Bud͒ud͒Βt`$1udԓ ud6ud]fP5<P֐V5V֐u`5u`ǐP(/Pǐ֐uT(uT͐֐u`(u`͐֐P"Pu\tX͒u\͒ΒtX$1u\6u\utu\tX͒u\͒ΒtX$1u\Lu\udt`͒ud͒Βt`$1udLud P$+PRu`t\͒u`͒Βt\Uu\tX͒u\͒ΒtXUaPamu`<P^mududdmu`u`dmPPV˒Vut͒u͒ΒtPut͒u͒Βt udt`͒ud͒Βt` PŒP3Fu9Fud9EPFQu@LQudLQPQmuW_u_cRcmuWcPouHuuduPuDudP8Lu\>Lud>LPuu`PÓuu`“R“Óu`“PÓГuɓГu`ɓГP֓uXܓu`ܓPuTu`P uPudP2uL$2ud$2PNau`Tau\T`Pa}udg}u\gwPuu`Ru`Puu`PǔuӔݔu`ݔRu`ӔP_00˕P˕̘u~̘͘t~͘u~t~'u~`0u~u~u~ #w#)P)kww̘u#̘͘t#͘u#t#u#`bwbju#jwu#u#Au# u~ SVS̘u~̘͘t~͘u~t~`u~`hVhju~jlVlAu~lu~uu~Ru~uP'Awŕ'HHAHŕ˕u~˕ܕPܕlVl̘u~̘͘t~͘u~t~'u~Vu~Au~ŕܕu~ܕP̘u~̘͘t~͘u~t~'u~u~Au~%lVl̘u~̘͘t~͘u~t~'u~Vu~Au~l{u~{Q̘u}̘͘t}͘u}t}'u}u}Au}u~'HAHhu~hyRy̘u}̘͘t}͘u}t}'u}Au}Nhu~hyr$y̘u}#$̘͘t}#$͘u}#$t}#$'u}#$Au}#$u~QWQ̘u~̘͘t~͘Wu~t~u~W̘u~̘͘t~͘u~t~u~ėP͘ژP̘ۗu~̘͘t~u~t~u~̘u~̘͘t~u~t~u~̘u~̘͘t~u~t~u~̘u~̘͘t~u~t~u~"PP"̘u~̘͘t~u~t~u~?̘u~̘͘t~u~t~u~[̘u~̘͘t~u~t~u~w̘u~̘͘t~u~t~u~̘u~̘͘t~u~t~u~̘u~̘͘t~u~t~u~u~̘u~̘͘t~u~t~u~̘u~̘͘t~u~t~u~PP̘u~̘͘t~u~t~̘u~̘͘t~u~t~͘PP'?u~0:u~:>R>?u~0>P?`u~HRu~RVRV`u~HVPu~u~Ru~P&Ru&-p|-6R&6Pm{Vm{rxm000e{0mVVVm{rx{v|Pv|p{PPv|VududududucucPPe{udkvucvzRz{uckzPv4v4.Iv4uPuP!uPIeuP2uPuPD0P\P\uDuDuP!0IeuDuDuPuD00$uD.20{ e{ 2{ 1e121 uu!Iu1QQ!IQiei2i00!0)e020 uu.Iuu0uL u u ttuPv"VuHuHV!uHIeuHuHV2uH#V#uPuP!uPIeuPuPuP$uP.2uP#W11!1Ie111$1.21JW!WW#V<?v?DV#<W<Dw|!WW<?v?DVuPuP.2uPZ\P\uDuDIeuDuD$uDZ\Q\uTuTIeuTuT$uTZ11Ie11$1\qWWIeWW$WZ\P\VVIeVV\wWww|WIeWW$W\tVtv|VIeVVReVVReuDuD$uDuTuTWWWWw|Ww|udududPuTuTPuDuPuPuP$.uPuPuHudRudPsuTstLQLQYPYLȚuTȚKu`KVVVu`VЛu`ЛۛVۛu`%Q%YuYsu`stXXRXRXV(X(NVb|V|XRXVXȚt|N|b||ȚsuTstLNLbLLȚ0u0su@stNb||̞̞ݚ0+V+.t./t/3tVttt%V̞VW PRWPW%WbdWW̞W3R$R$%wv+V+.t./t/3t%Vuu%b|%b|u7ub|u`7Ku`KVVVu`Vb|V?Ku`KVVV\u`?\u?OPu\{uuLbquLquRu{uLbuP  ̞ Vttt̞Vu̞̞ЛVЛԛtԛuLVtttDDЛu`ЛۛVۛu`XVVěЛu`ЛۛVۛu`ěЛVЛԛtԛuLěԛPuLuPd|juDuyRy|DjyPDPȚKu`KVVVu`VЛu`ЛۛVۛu`%Q%YuYsu`stXXRXRXV(X(NVb|V|XRXVXu`%Q%YuYsu`stXXRXRX|XRX̞XsuTstLL|L̞L2Vuh%q%Yu#Ysuhst``r`r`|`r`̞`su\stTT|T̞T"2Pud%q%Yu#Ysudst\\r\r\|\r\̞\suXstPP|P̞PP2Q2cu(u`%Q%YuYsu`stXXRXRX|XRX̞X(u`suTstLXRXRX|XRX̞X(2Q2cu(2V(RVRWv|WcV2;V;@v|@RVR\v|2@uE\u\cW2@PEVPcu`%Q%YuYsuTstLXRXRX|XRX̞Xck uhu`4Ya u\uT4cVVgk uhu`4gsVssu@st|̞yu`%Q%YuYsu`stXXRXRX|XRX̞XyPݝPsuTstLݝLL|L̞LŜԜVVȜԜu`XRXȜԜPPuV%p̞ԞVW%p̞WutP#u̞suTstLVW%VBVBGv|GqV%+V+/v|/BVBKv|%/u4Yu%/P4FPYsuTstLYa u\uT4YrW]a u\uT4]iWݝLݝ1ݝLݝ2ݝLݝ33N<G@GKRKN@<KP~@XRXP V̟V̟u'V̟V̟u4?P?WW4v̟v̟u#TWPWcvcuTuT[cPguTʟuTrugʟugrzPzuP<ǟPǟʟuP<ԟߟugߟRugԟPMW{uP{|tL|uPWuPWuPaW{uP{|tL|uPWd{uc{|t_|ucdpPPpxQuL{PuT{QuL{QWw|WWw|Ww|ududPP07W7<w<GW|Wud#Guduc)GucPud<);PudGud|udG|##udPucRucPKuWucuTcdtPdzuTzWuTWuT`uWucuTcdtPdzuTzWccuccdt_duccoPzPozPcuLcdtHdzuLQuPPVv|VVv|Vv|ududPP0(V(-v-4VdzVud4uduc4ucPud<,Pud4uddzud4dzudPucRucPHVHMvtM]V.3V37vt7HVHQvt.3v37v|7HvHQv|.7L=QL.7P=LP-PBQP P puLuLuL.1P17p|Wu#pu#W]P]QpuLpQuLQuLku#pu#knPnuPu#pu#P v2&ժzpP v2&ժz v2&ժzP v2&ժzpP v2&ժz v2&ժzP v2&ժzp00puPuPuPuPPpuHPuHuHp1111VVPWPWWWWwtWWWWWWWWWuHuHuPuP#uP<PuP#uP<P#P#pVV)ju)AptABq<BGpl)APABqBGpx-AptABq<BGpl-APABqBGpx`u\u\u\u\rt u#<rhVrh u#H0000rt u#<pxvrhVrh u#HplvxQplvxpxvVPv u\u\ududu\u\ududu[u[PPu\udu[Ru[P&>w<JOw<w<>2uPOuPuPuPuP>fuPf0PuDuDuP0uDuDuP'uD?k0o0uD0{ { { 111]u2Ouu&1&7R5ORR   2 9    &]uJOuu/>u/>0/>uL>]u>QVQ]u]fvxvxvx>AuPw"AnWn uHuHWuHuHuHWuHFQVQ]u]fvxvxvxFfWWWnsVs2uPOuPuPuPuP?PuPouPuPnsWn21O1111?P1o11nWWoyWnsVv VsWwtWoyWv V|WWoyW?PuPxuPuPP uDuDuDuDuDQuTuTuTuTuT21O1111P2VOVVVVvtVVVVVVVVVuDuDuD2uTOWuT W2WOsW Wwt2WOWwt ww|2wOWw| u\2u\OWu\,PWuT^juT#P#'uD'uP'?uPkouPuP.:uPPkuHPkuH#Ydu\dhRhku\YhPnrPruPtLơuPơǡtLǡڣuPnrPruPtLơuPơǡtLǡڣuP{PuTPduTǡVuT#uT=PuTxzuTuTd&=P&@dBPuHtDdơuHơǡtDǡ=uHPڣuHpuH#tD#dơuH#ơǡtD#ǡ=uH#PڣuH#Pǡ١PPuDuD#uH#5=uH#xڣuH#1R1uDR#uD5=uDxuDRڣuD#uH#5=uH#xڣuH#P#uL5=uLxڣuL"#uH#5=uH#xڣuH#"1P19 v2&ժzP# v2&ժzxz v2&ժzP v2&ժz"#uL5=uLxڣuLP# v2&ժzxz v2&ժzP v2&ժz#0xz00VuL5=uLڣuLV^P^u@5=Pڣu@V15=1ڣ1V^V5=VV^P^W5=PڣW^WwtڣWdWڣWȣУuL#uL<ȣԣP̣УuL#uL<̣ԣPPVV͠ߠR#+R+/q͠ߠr#+r+/q#Ӡudt`dơudơǡt`#5udPcudӠߠP#/PߠdǡPcߠuPtLdơuPơǡtLPcuPPdnPnơuTơǡtPPcuTǡUPcUǡBexQXPXjn0B#BGPQXPXjnQjnYj#$jYg #$#gnPn##wyPP٨bn٨bnե٨bnե٨bn ٨ b n ٨bn ,P,7 r2&ժz#$7 #$# P 7#P]צVDKVnpV7P٨bn7#p#٨#b#n#7HPPէ٧P٧DIY!D#W#٨#b#!jQjDWsQs٨YY]Q]b,D#W#٨#b#,/P/DW٨b[D#W#٨#b#[jPjr v2&ժzWsPs v2&ժzY]P]` v2&ժz[DW٨bWsPs v2&ժzY]P]` v2&ժzW0Yb0D٨9IYPDP٨9IYD11٨191IY1VVP̧WP٨W9WħWħ̧wt٨W9WW٨W9Wƨ٨W9Wƨ٨9#9)1#<)5P-1#<-5PPDVINVpDWnpDWnpxpx}PDDWDDW#PuDWuDW#PצvDKvDW#PȦDDWD˦PDKPKWV˦צPDQPpDvPRPvP٨bfVVVکܩVVEG٨bfǤPǤ  ٨ bf  ٨bfP|V|PPV٨VtPbfVP\WPTLRLPHH٨HbfHHHH٨HbfHWLWL٨LbfL PP_j#PکHĩЩLЩԩRԩکLĩԩPVu`t\ĪVĪƪu`ƪǪt\u_t[ƪu_ƪǪt[Pv<PududVu`PPϪudժܪu_ܪRu_ժPu_Ru_PpݫW\kWWǬWpݫud\kududǬudxzPݫu\ݫ0ݫ6u`67t\7[u`[\t\ku`ݫ6ud67t`7[ud[\t`kudݫ\0k0QkzQzuP (u\ku\ PkzPu\Ǭu`udPǬud (vITv#(u`OTu`#.PO\Pvu`P [VFPV pw*FS9^0 V .8 .D D# PpV vp p DpD#P DD#P  DpPڭ ڭ DڭD#P@FDSDDDWFS]~WFDS]D~DDpFS]~pFDS]D~Dp|D#|PFS]~FDS]D~DF\S]\~\FDS]D~DD#PF= S]= ~= FDS]D~DĮFS]~ĮFDS]D~D߮FS]~߮FDS]D~D#FDS]D1F\S]\4FDS]D4<PSZP_~\epWptRt~WetPD W,uD,vuXvwtTwWvuWvwtSwuWPwPvu\vwtX vu\vwtX [W ,V FVFSv|StV,3V37v|7FVFUv|,7uX<[uX,7P<MP[vu\vwtX[c udu\4[uW_c udu\4_kWuWRuWP!uuuP%=PY\PP!uuuP.WƲPƲWWڲ&&B.2V23t37t7uLRuLeuL uL.2uP2MVMNtNUtUuPRuPeuPV uP=@p,@Ju#,=@p0@Ju#0u#0%p0%.u#0.=q0u#0CJu#,QUtUuP@uPeuP uPQuuu@uuQUPUu@ueu uQ|V|uXuX V @uXeuXVôuXô˴V˴ uX[|V|uXuX V .uXeuXô˴V˴ uX[fPfmWmu.ueuôŴWŴ uimWmuueuд uimu\mWttu\uu\uWu\Wu\eu\д u\uueuд uuȱudȱֱu\ֱuXuPuuPuuudu\uXuPeuPдҴuҴu\uud uPRu@uu@u|R|u@eu@д u@Pu|Pu`udRudPu\uu\u\eu\д u\uduududeudд ududuududeud udȱudȱu\uu\udu\eu\ u\ȱudȱֱu\ֱuXuPuuPudu\uXuPeuP uPu`uu`u`eu` u`ȱPPudu`Pȱu\uu\u\eu\ u\ȱֱu\ֱuXuPuuPu\uXuPeuP uPαuduududeud udαֱPPֱuXuuXuXeuX uXֱuXuPuuPuXuPeuP uPܱuduududeud udܱPP.uX")uT)-R-.uT"-PҴu\شu`شPuPuuPuPeuP uPuduududeud udPPuLuuLųuLeuL uLuduudųudeud udPųϳPu#,%p,%.u#,.=q,q,u#0%p0%.u#0.=q0u#0)[W[uTճWezuTW uT)-P-uճuezu u)-p-2P2u#ճu#ezu# u#9[W[uTճWezuT<udճudezud<DPճ߳PD7 ez7 DOuOSP[gPgWezWwUezUB8u89t9=tu8u#,u#,.8u#,.8u89t9=t.=P=buz}u28u89t9=t2=P=Yuz}u}WudPbu7 .@uP4;uT;?R?@uT4?P@RuLFMuTMQRQRuTFQPRe7 PqVƵݵVV#\ud\dPdquTqud\ߵudߵt`!udMq M\ud\dPdquTud\ȵߵudߵt`uc[ȵߵucߵt_Pȵ׵Pȵ udPȵuT udPuT ucR!uc P3ut ut u3u tu tu 39u`9uVuu`t\u`t\¶V¶u`V¶u`ȶӶu_Ӷ׶R׶u_ȶ׶Pxu`t\u`t\xudt`udt`{u_t[u_t[{Pud<Pu`u`u_u_PPRW۷uT۷ܷtPܷ'uT':u\:BWBDuTDHWٷVٷ۷ud۷ܷt`ܷV۷u[۷ܷtWܷu[PP۷u`۷ܷt\ܷu`۷ud۷ܷt`ܷudPܷP۷u\۷ܷtXܷ0udu[Ru[P&u`!u[!%R%&u[%P&:u\lPPXPlpPXp}Qp# PXp# RuLP`RV p# #uPOuPOPtLPX p# #X_uP_`tL.uPgkuPٸWWP^WQuTP`QԸVVP]V]^wVQp# PXp# q p# #ٸwwP^wRuLtHuL`uL?BuLSguLuTp)ԸAV`VԸٸW<`<?g<Wudt``W?gWw#P `Sg Wudt``WSgW qP!V `V SgV !Wudt``WSgW!'q',Pӹ" ӹ" {" " Sg" 3Wudt``WSgW`{udV`{`Sg`V[ud#_bpbgPqn {n Sgn qsud#z}p}Pudt`{udSgududt {t Sgt ud#pPn {n Sgn ǹpǹ̹Pӹ" {" Sg" ӹudt`{udSgud{udSgud#pP,Sg,ud#pP) Sg )+ud#/2p27Pludt`ASudWP<?<gk<NWNOudOPt`?WgkWúw#úȺPպP|-|պNWNOudOPt`-WպۺqۺP:r! rP)" ۼ)" ! -)" NWNOudOPt`-Wۼud P`ۼ`-` ud#pP%P ۼ - %'ud#+.p.3P:OudOPt`ۼud-udud]P ۼ - ]bud#fipinPrP)" ۼ)" -)" rOudOPt`ۼud-udۼudP-ud#pPPl-lud#pPƻP-ƻȻud#̻ϻpϻԻP޻P-޻ud#pPP,-,ud#pP9OudOPt`-?udٸwwP^wRuD-EuDP*V-V¿ĿVƿȿVʿ̿VW-WƿʿWPttP-;0u`-u`Rοu`-04ο0ud4οudV ¿ʿ VuDu\¿ʿuDV\q\aPb/ ¿ƿ/ buD¿ƿuDbWbeuD#muquzPh¿ƿhqPzuT0W0VuXViWizuXPVfPVu\izu\Vu`izu`VudizudV0iz08VWizW=Vu\izu\=EPiwPuTuSRuSPu\¿u`udP¿ud)V)*ut*+tp+=V=>ut>?l*us*+to+>us>?k7PGRusRVRV`usGVP%VW.<VWnvVW.<unu~uu.<u Wnu Wu uu"u Wu uu"~u W~Wu W.<unu~uuPVucRucPuducRucP)FV,7uc7;R;Fuc,;P_uudepucptRtuucetPW[W%VW.<VWnvVW.<unuuu.<u Wnu Wu uu"u Wu uu"u WWu W.<unuuuPVucRucPuducRucP+JV.9uc9=R=Juc.=PcyudituctxRxyucixPrVruuVtUuUPsWuWt P XXrVruuV`tU`u0%VW.<VWnvVW.<unu~uu.<u Wnu Wu uu"u Wu uu"~u W~Wu W.<unu~uuPVucRucPuducRucP)FV,7uc7;R;Fuc,;P_uudepucptRtuucetPV VP?U?XU XPW WWctcxPx{t{PtPtPtPt P  tV VWY0YhUhl@luuuU UX0PVVVaq0qtPt-W-3P3SWPWPp0.u0.u0.t0.u0.S0Su0uu0uuL:HPHuuuPuBHRHuuuRuPPPpqqVVVVBS0SuPuPPuPuP0uPu@u@u@u@SVVVVSvvvv^ePeuuTuyuT#yuTepuTpttvWwWWw|RR/XWX^w^qW/XWXaw/aVHRQ/a /avvvvRRNVV=VVVWw=WWW0v04P=v%VW.<VWnvVW.<unuuu.<u Wnu Wu uu"u Wu uu"u WWu W.<unuuuPVucRucPuducRucP+JV.9uc9=R=Juc.=PcyudituctxRxyucixP <0.3<<HPHJ3PQ\yMO yn PWMO PVPW"P"uLtHuLtHuL"P"uLtHuLtHuL+1P1quTP<uT$uTuT2uTZ\uTlquT<&2&<BOSPSuHtD<uHtDuH2uHOSpSuH#tD#<uH#tD#uH#2uH#TgPPeiPiuDquDuH#uH#ZuH#RuDRuDuDZluDlpRpuDuH#uH#ZuH#PuPuPZuPuH#uH#ZuH#P  v2&ժzP v2&ժzZ\ v2&ժzlpPpq v2&ժzuPuPZuPP v2&ժzZ\ v2&ժzlpPpq v2&ժz0Z\0lq0$uPuPquP$.P.u@Pqu@$11q1$.VV$.P.\WPW.TWT\wtW4QWWuP#uP<PuP#uP<P{PVqvVqu Qu u QPuP#pxu QPuP#pxnQ <nQ 2EnQ uLtH<uLtH2EuLP<FPFuTtP2EuTWU2EUxBGZnQ 7u\78tX8^u\^_tX_u\udP7ud78t`8^ud^_t`_ud6W67uX78tT8]W]^uX^_tT|~W~uXudP7ud78t`8^ud^_t`|ud 6W67uX78tT8]W]^uX^_tT 7uW78tS8^uW^_tS P8GP)7u\78tXJ^u\^_tX)7ud78t`J^ud^_t`,7uX78tTJ^uX^_tT,8PJVPa|u\a|udgnuWnrRr|uWgrPuWRuWPrWtxWz|WujVtVbWbjwltxWz|WeVejvltV$_WtxWz|W$_VtV~v ugRugPvugRugPVVuutuut&ugruyuu&lvlgrvlyvl&lVgrVyV*lvlgrvlyvl*lVgrVyVyv uTRuTPvuTRuTPxWwpwp#wp]eWxuTuTDuT]guT2u`&-uS-1R12uS&1P2DuX8?uS?CRCDuS8CPpl u#DpXQpX u#(u 0000pl u#Dv|vp!wpXQpX u#(vhv\!w|Rvhv\!w|v|vp!w!WVvt!wvtPttvtvh!wvPvv|!w  vx Pvl!w v V!w !uTuT!1u 14P49Q,uXuX,1u #14p49PEu`u`EMq MRPXududX^p^cPpuTuTpududsuSuSswPPwu`u`}uSuS}PPuXuXuSuSPPvDvDvDu@u@M]u@ryu@u@+u@+G0G\W\uu#u@#%W%*0*iu@|W0M]u@u@{ M]{ ry{ { 1M]1ry11uuu1QQQf M]f ryf f _ _ _ M]_ ry_ _ uuuu0uu W +wp#wp*3wpMVW[]WWu@v"aViV|VVM]VV W +wp#wp*3wpMVW[]WW+V#V*iVM]VV*Bv 6=uT=ARABuT6APBivHOuTOSRSiuTHSP+u@u@#*u@|u@+4u 79t9=t+11#*1|1GrW#%W|WGHu NRtG11#%1|1azQzuDuDazVaVVzVvlVVvlzvv|vvv|zuTuTuTPzv vxv vxuTuTPPvvpvvpuTuTuTPPQQu@iwu@u@VtvlVVtvlVWu t4W4Tu Yxu utTuYxuu2TuYxuWu 24W4Tu Yxu V2xVWu 24W4Tu Yxu V2xV=YvCKugKOROYugCOPgqugquRuxugguPW'u '(t(HWHhu mu 'u# '(t# (hu# mu#  u# Fhu# mu# W u FHWHhu mu VFVWu FHWHhu mu VFVQmvW_ug_cRcmugWcP{ugRug{P#p~)3Xnuq`[cke+ZC[[[D+}%5]-|||Q - kzCy()3)3nxmpX2`%4<[^af$,KNQVt|X[gX[gX[gl?Pb-@I-@I%-@I"'+@GUX]+@MUX]"'+@GUX]+@MUX]07DGL0<DGLR  R ch R   &*G &*7 &*/GPSVPSVahkmxPSVYYahkmxx x r v z 0 r v 0 0  0 V c e f i r -8u%-8u8Nhu * 8 P ] 0 8 P ] w rw&)7#2i&)7Dkqtkqvy##[P<?D)))<?D)//<?D+    ++/259=AKah=AKXh{=AKXn{Xa{X]{]a>@B&16BD[hknt&24Kv,Y[^kno)H" &3677CMOTadeeq{}HXHXXhXh hx hx xx)%)WZ\a0KNS N ` V Y g h!f"""##:#f"s"x"}"##s"x"}""###(#s"x"##`################$t%%%$$$t%%%$$$$$$$$%%$$ % %%%$$$%k%p%$$f%k%%f%%%[%f%%%%%%Y&%%%%%&&*&*&:&<&>&))))))) *r*{*****{*****p+{*****p+{*****p+{****+p+%@I!%@I%/Ia%+IO+/Oa/9ay/5ag59gy%8A!%8A%.AY%*AF*.FY^,,,,^,m,r,t,v,,,,-...-r...-$-*---V.^.g.j.$-*-/-2-@-V...$-*-/-2-H-J-M-V...$-*-/-2-h---V...--...)...O-\-----//'/^/'///O/R/U/Z/01111112'1F1I1J1u223191<1F1I1J1u2x2~22x2~222F1I1J1i1r1u1)2D2T1i1r1u1)2,22252,22252D2i1r1u1112i1l1u1x1l1r1x1112112211221111112)2112)2222233066686;6d6}6666R7Z7o7073767G7073767?777777778 8+8@887788c88c8f8l8q8f8l8q887888 8+8788 8 88 8+8889 9 9w98888Y9w9Y9[9a9d9[9a9d9w98888 9@9888888 9@9999::':6:o:9999999999999999: :9999: :99999999: :999: :':999: :':99999: :':S:V:\:_:V:\:_:o:::::;8;H;;::::::::::::::::::H;T;::::::H;T;::::r;;::::0;8;::::::0;8;;;;;c<<c<e<k<n<e<k<n<<;;;;0<E<;;;;;;0<E<<<<=== ==`=l=== ==`=l=== = = ==`=l====n>>>>R?====>>>>==>>>>>>>>>>=>>>>>==> >=> >>>>'>*>->/>C>U>X>[>;?R?U>X>[>c>>>U>X>[>^>^>c>>>c>n>>>>>c>i>>>>>i>n>>>>>>>n@@@@@@v@@@@@@}@@@@@@@@2A4ADAAAdBxBBA-B/B2BBB'B-B/B2B6BRBxBBABRBxBBABDBGBJBDBGBJBRBxBB;CPCWCdCgClC;CPC\CdCgClCCkDxDDDDEEEEEEVExEFFFF FFxEEEFF$FzEEEFF$FEEF$FEEEFFFFF-P[%-P[FHHH3HJHZHHFGG0GGG0GGGG~HHGG0G^G^GaGdGgGjGzGGGGGGGGGGHGGGGGGGGGGHHHHHHH)HHHH)HHHHYK\K_KpK LHHHYJKKK LHHHHHIHHIIIIK LHHIFIOIPI_I`IFIOIPI_I`IyIIIIIIII=JIIIIIIIJ(J.J4J=JJJJJJJJYKpKKJJpKKJJpKKJJpKKJK KKK(KKK(K>KLL3L9L?LELKLNNNNOLL3L9L?LELKLMMMO'O?OOLL3L9L?LELKL}LLL}LLLMM'MgOO}LLLLLLLLLLLLLM'M-M0MXMaMuMMM'M-M0MXMaMuMMMMMMMNNNNNNNNNO,NmNNO;NPNNODNPNNOOOOtRwRzRRSOOOQQ]Q`QSSOOOOOOO POOOO PPPPjSSOOOO P@PPPPPPPPPP7QPPPPPPPPPQ"Q(Q.Q7QQQ]Q`QqQRRRScQqQRRRScQmQRRRSRRRRRSRRRRSSRRRRRSRRRSqQtQQQqQtQQQqQtQQQQQQQQQQtRRRQRRRQQRRQQRRSSSSSVVVVWSSSSSZUfUiUOWWSSSSSSSSSTSSSSTTTTWWSSSSTITTTTTTTTTT@UTTTTTTTTTU+U1U7U@UZUfUpUsUyUUVW W7WyUUVW W7WyUUVW W7WyUUVW W7WVVVW W7WVVVV2W7WVVVW W2WVW W2WUUUUUUUUUUUUUUUUUUUUUUUUUUUVW WU>VW W V!VW WV!VW WJVPVZVpVDXc-Xc%-Xc5C`k;C`k0CFICFIT`hCFILLT`h8^K^V^9Ge[i%+,%+/4WXXY(X,X/X5X,X/X8X;XuXXXX7YSY~XXXXXX7Y9Y?YBY9Y?YBYSYXXXX(Y7YXXXXXXXX(Y7YXXXXXXXXXXXYYYYY YYYYY6[9[<[P[[Y`Z[[YZZPZSZXZ[[Z%Z&Z6Z ,28;> #&( #&( #&(8;>{Rjmpjmp{jmpss{&QTW).1QTW7CFITWTWQTWGq  147147xOgjmgjmxgjmppxii*i.i1ikkllpiiiiiiiiiiiiiiiiiiiiiiijjjjjj'j-j/j'j-j/jPjcjfjrjjjjrjwj}jjjjjjjjjkkkl1mDppjjj2kllDpdpj2kllDpdp k kkk!k$kk!k$k2kllkk$k'kk!k'k2kllDpGpMpPpGpMpPpdp2kwkl1mppRkekhkkkekhkkkwklmekhkkknknkwklmmmmmwkkkkwkkkkwkkkkkknnnokknnnokkkkkkkkkkkkllkkkkkkllslvlxllslvlxllmm$n ooo pmmmmmmmmmmmmmmmmmm ooooo pmmmmmmmmmmmm oommmmmm oo2nno ooOooo@nFnInXn[n^n@nFnInLnRnXn[n^nXn[n^nno oo?oooxnnnnxnnnnnnnno onnnnnno o&MPS3@CDGMPSPSMPSGm <?Bj<?Bj<?Bjpplq|qpppplqoquqxqoquqxq|qpqqqqqpqqqqqqqqqqqqqq"q@qHqqqqqqqq"q@qHq"q,qHq_q"q(qHqNq(q,qNq_qqrrrrr{8{;{@{H{~{{{{8{;{@{H{~{{{{8{;{@{H{{{~{{{{w{~{{{w{~{{{{{ ||||}}C|g|}}O|U|X|g|}}}}}}}}q||||}}||||}}}}}}}}||||} }||||||||} }|| }0}|| }0}||0}D}||0}D}||||||||||||||||~"~$~Y~\~e~h~\~e~h~~Hb~e~j~~Hb~e~q~y~y~~H~~~~~~~~~~~~~~`~~`~~bej~~~~~~~~~~~~28;28;Eƀƀр׀ڀр׀ڀ  "DD_eh_ehs~~&@Zqwzqwz*8Rjpsjps~%0JbhkbhkvCP+"%]u{~u{~%(69A(146jÁƁȁ΁Ɓȁ߁߁ D[ad[adr!#99Hjrbzz036AGHORU_1$^dgu{~u{~1=CU1DPj8Hd58Hd58JMRdb!$'{~!$'(PVYgmpgmp~5(PVYgmpgmp~    '<'8‡‡҇ &5@Zrx{rx{4P"4Pj" ^ (^(oLX8L8L(8(8X[ad[adpLmp{ Wmpt Wm LjʈLjʈڈ #&OOA  (+.(+.9DRpxJRpx.NQR:NQRNQR[dg[dgn[^gj^djnnxnttx "DWbknbknxbenqekqxxx~~N`.]s(](+14+14]((`h`hhhnn$$$2$**22@288@@N@FFN.17:17:F0 %0^@^@obpPbPb@P@Ppsy|sy|7s9Ak7UAV7MAVƉX_bs9VkX[bs9Vk&ÊЊЊ0Њ0  Ê0Ê0JbhkbhkvIX$N(X$9X$9r(I9N(15I9Nڌgvy|g g} ҍ vy| vy|:RX[RX[fԎ#Ԏ Ԏ # #ZˏΏӏZpZppzpvvzzˏΏӏzˏΏӏ qy2JPSJPS^(k-(+,/+,/k-+,7fBHKf  fX-!!-36-36?BE?BEP[k[^dg^dgkkuqu4w5:w5?FIrNTWrrd5Cv'*-'*-9?B9?BKNQKNQ\gwgjpsjpswCFLOFLOvww}}.MPRy:MPRy||MPR*WyMPRUU*WyZ_bWygmpWZ`cZ`cy}(47@CF@CFRX[RX[dgjdgju*5Hn !!!+'++5T]`n+1T]`c15cnőȑΑёȑΑё$'*?$'*:Г$'*-FRXaaГivyz}Гʒ͒ВĒʒ͒ВՒ   $ $$<?B$06<?B<?Bk-JY\_bhhk-wz}wz}wz}WZ`cZ`c~~ÔƔÔƔÔƔՔÔƔɔϔՔՔՔ#  # #/25]/25]/25]]kck>GJTx>AJMAGMTxT_TZZ_–Ŗ˖ΖŖ˖ΖߖGP{:P{),/:P\),/22:P\ .@CFdy|L`ݗ`×Зӗԗחݗ`ݗݗ +"++MSV3@CDGMSVMSVhnqMSV\bhnqhnqhnqtzȘΘј˜ȘΘјȘΘјȘΘјԘژ ),6 #,/#)/66A<A™ș˙™ș˙ڙ +19@CFn@CFn@CFn<^gjt_|_bhkbhk| ( ((?(..??W?EEWWoW]]o oou u  9[dgq_|}_bhkbhk| ( ((?(..??W?EEWWoW]]ooouu  (4(4wP\P\(+.P(+.1y||ҟ"%/8;F@H/2;>28>F@HFTHuFLHNLTNu  0@0@SVYdSVY\\dğğҟ;]fis_|_bhkbhk| ( ((?(..??W?EEWWoW]]ooouuD m+ e+SbSTZbbe'Pbe.7:PS`cpsġġġԡڡݡġȡΡԡڡݡԡڡݡԡڡݡV[iKУK5УK͢ТӢĢǢ͢ТӢ͢ТӢ͢ТӢעݢ У У Y\_nvwntwntwz!!- `ce-Q cicici #S #4:@MS`cegsvx|gjmu +ȤȤ(Ф( Lbhjbhjwz}wz}wz}?֦ܦݦ8`n:@F`Ȧ֦ܦݦȦ֦ܦݦ֦ܦݦ &&9<?9<?OX[9<?CIOX[OX[fOR[^RX^fШ`+éɩʩéɩʩ֩٩ܩ֩٩ܩ֩٩ܩ+ħǧʧħǧʧڧħǧʧΧԧڧڧڧݧݧax~x~""&ΪѪתڪѪתڪåƥѥ(8åƥɥɥѥ(8 Ȩ Ȩ69Gx{mUЭ߭8Э߭8īǫȫҫ۫ޫҫ۫ޫЭ߭ҫիޫի۫Э߭    5;>&),/5;>5;>NQR5;>AGNQRilozЭilorrzЭUm̬ϬѬƬ̬ϬѬ̬ϬѬ UmԬ Um  !'* !'*!'*;!'*-3;;JPSJPScfgJPSV\cfg~~ ;Ccڮݮɮ̮ѮԮڮݮɮ̮Ϯ 8 8 8gboӳ+%;>@;>@QTUQTUjj}}̱̱ܱܱ߱߱=@CRbo=@CFFRbogUoӳxƲ̲βƲ̲βܲܲ /25@o{/2588@o{Ub+*01*01@@TWXTWXbhjbhjx~x~ͰаӰUbͰаӰְְUbŵе˴ѴԴִ%(+0<DFVbkl}h}h}XhXh׶yƷ :*-.177:ILQyILQyILQyŸиL(+.и+.иQTWQTQTQThux~ux~~ŸŸaimٹٹٹ4@I  $)4@I $),,4@IfiwIX߻~ʺкӺĺʺкӺʺкӺʺͺӺ׺ں,,,2;>Iƻɻ̻߻2;>Aƻɻ̻ϻAIϻ߻jmo|ADJMDJMe3P߾9<>z`pҾAz`pҾWZ[ehkehkz`pehknnz`pzȽP`pȽP`ȽP`<<<#0(0@oSLX^ggo|ҿÿɿҿҿ޿ $*3F^adFRX^ad^ady^adjpy^adf^adf^adf(S(>(> D D D'8,8 5 5  SV\_V\_p0E0E 0 0cfloflo@U@U0@0@sv|v|ixix>x-03-03>x-0366>xH >adj#>pvypvy|#4  4nBEHYHNQYn||; * "*;nFIL]LRU]nyyp]pNN]!'*;!'*-3;WZ\;Ndgjzjorz$)   +.1@ 3@3UXX^djU@X > m HNhHNh HNh)2<EKQ)2<EKQntzkqtm  &A &Am  &Ajprjpr Q )/5HQkqtwtwtww %'^ab  /58L/58;DLU^abU^abioq > yy / "#+14"#+14+14C+1477CCX LX X/58    /58/58  _nw FW"X[\7F*03D*036<DOX[\OX[\ehksy|sy|WpHHH&<&(.1(.1<HSNSS^Y^!$!$7- 9<?uxyGMPaGMPSYaluxyluxyTTT6F>F36?svwvENQ_HNQTW_jsvwjsvwcv ?N  O( &): &),2:[^aNciorioru{ (+-e;J5;>R5;>DJR !   ! !*-0cx8;>N>CFNcx0;0;0;0;0;)n)BDG39:*39:*39:ORU]fiw`filow* 369n369n369nUbZb- ,,CT7 ~ EHJEHJv+1:@F7:@FTZ]`gr]`gr]`grZ]`grww  - wBHO 3RluRlu ))))/56u7 K K _   E_ ~ 2!*2`fh`opvypvy| 0 00@0@@`!b@`0E@`9E@`bnono <    <NOHNuNOAP368p@FI]@FIOU] ADE/!'/8ADE8ADELOQY\_o_dgoiz A`i A`i A`i(5`i-5`i%00@ E0%(0g !   ! !(+-^58;K;@CK{Yj%PY%PY%PY PYPYR R cHV0H0H 0 0VY_bY_bt& 9&O9*O9UX[z}   9038MX038DXnDSSw[wz}9JO9P9PeilqMn(19Mn9M?M(1n-1n/@lpsx5C`k;C`k#*.9IKNYY\be\bet*-03N\biVY\w@L@L@Lw0@0@0@ 0 0LNQe!$':Puuw}w} )&JXp=HXppk}pwy{wy{(}Pk(P"GPj:EPjjNaaemoemoz0N0&JXp=HXppk}pwy{wy{(}Pk(P3NX[^ot & &u DGJDGM^acluxluxlox{ou{ &JXp=HXppk}pwy{wy{(}Pk(P.IPSVi2jmp0  3#u0,0,JPSagjagjzIf{ "(+"(+6258KQU` 0258K` 0&)28;28;FKQUr 3KQUr 3KQUo 3tz|```vdfltDD$fzz z}}  $'*$'*$'*6$'*6$'*--66E6E<EETKTTcP`TcP`ZcP`cr 0ir 0`p`p`ppp?VYY\be\bex{|SbSbSb&)7|twy~ 5 5^agjagj|BTY[  -h  R /  IOR]Xh U]XhIORU]nHXfnHXn8Hw8H(8(8((         %7:  / G Z  .  Z  .  "".  p v y          XX          X x                                    %    %   % /   + /   / 9   5 9   9 C x  ? C x     "  X ] 0=0 +%0#+% #+9199G?GGUMUU_[__ieiisos05#z}#z}0>066>>L>DDLLZLRRZZhZ``hhvhnnvv8v||88=!Xy !X[ad[ady0ORS X<BEORS XORSr]cfr\_eh_eht$%$%1CPoruorux$'*0dmprtm7         0 !'0?BEm?BEm?BEm ( ((H(..HHhHNNhhhnn! ~~HVoHNouNVuVdV\\ddrdjjrrrxx(((-VY\oVY\_8>@CCLe0~-03>`~-0366>`~>LP`DLP`LZ@PRZ@PZh0@`h0@hvnvv|X]0@W00 0 0  05W\IVlIVr     !*"-"2"@"# / 2 5 ## # & / 2 5 ########K Q T ] e n q | P"`"e h q t h n t | P"`"|  `"p"  `"p"  p""  p""  ""  ""  @"P"  @"P"R!\!^!q!!!!!""!!!!!!!!""!""%"#######.#.#1#7#:#1#7#:#F##N&`&''*###b%`&&M((1**$$$$&&$$$$$$&&$$&&$$&&$%&&$%&&%%&&%%&&%%%&&%%%&&%%7%p&&+%7%p&&7%I%`&p&=%I%`&p&##b%g%%%%&&(3(%%%%%&&(3(&&3(?( &&3(?(&*&?(M(&*&?(M(<&N&''<&B&''B&N&''m'p's'~''(m'p's'v'v'~''(~''( (''( ('' (('' ((''((''((''(&(''(&(&JXp=HXppk}pwy{wy{(}Pk(PF)69:=CCFCFRUXRUXRUX&JXp=HXppk}pwy{wy{(}Pk(PHXn "%'"0;Bp"0;Np"Np"QWZpNQWZ ,@ ,@{KNS[NS]k[]kp# Nwzaqtwqtz#/28:=G/28:25:=58ITGITY_}_kkqq}"(0L m +Gm ]cw]cw ]cw;>Rj;>Rj N1%1Z`jpvpv********+ +++P+`++++++ +++P+`++#+`+t++#+`+t+++++++++2,h,Z.m.;,A,D,U,;,A,D,G,M,U,r,u,x,,,,m.|.,,,,,,,,,,,,,,,,,,,,,,|..,,,,,,,,,,-- -@------+-----#-+-V-Y-\----V-Y-\----V-Y-\----|----|-~---~--------------.......)./M/\1u1 /&/)/:/ /&/)/,/2/:/W/Z/]////M1\1e/k/n//e/k/n/q/w//////////////:1M1/////////////%00 1///0///000;0>0A0000;0>0A0000;0>0A0000a0s000a0c0i0l0c0i0l0s000000000001 1&1)1 1&1)1:12=2L4e4222*22222"2*2G2J2M2222=4L4U2[2^2o2U2[2^2a2g2o2z2222z22222222*4=422222222222223332223222223+3.313o333+3.313o333+3.313o333Q3c333Q3S3Y3\3S3Y3\3c333o3z333u3z333 4444444*44-5<7U755 5555 5 55575:5=5s5v5w5-7<7E5K5N5_5E5K5N5Q5W5_5j5s5v5w5j5s5v5w555557-75555555555555666555555555566!6_66666!6_66666!6_666A6S666A6C6I6L6C6I6L6S666_6j666e6j666677 777 7778,:E:777 877778 8'8*8-8c8f8g8:,:58;8>8O858;8>8A8G8O8Z8c8f8g8Z8c8f8g8p8s8v88 ::~8888~8888888888998888888888 999O999 999O999 999O99919C999193999<93999<9C999O9Z999U9Z9999999999 : p"%( #&HPPXXgT["S`cehx"&),`cehV:\:j:U;`;<<=t:::::::::/;<8<<<l=~===::<<==::::::::::::::<<::::<<::::::::<<========:;<<:;;;<<:;;;<<:;;;<<:;; ;;; ;;<<;!;< <;!;< <;!;< <;!;< <!;/; <8<!;/; <8<!;'; <&<';/;&<8</;=;8<X</;=;8<X</;5;8<><5;=;><X<=;K;X<<=;C;X<^<C;K;^<<;;;;==;;;;;;==;<,=I=<<<<<=<<<<==!=,=> >>>>/@a>j>m>{>??a>d>m>p>d>j>p>{>??{>>??>>??>>>??? @/@>>x??>>>>>>>>>>>>> ???>>> ???>>>?? ??? ? ???????????88v;=CEKQVnnv6@9@G@zAAAB6C6@9@L@h@k@l@BBU@h@k@l@h@k@l@@@@C6Cv@@@@CCC!CCC!C6C@@@@XBhB@@@@@@@@XBhB@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ AhBxB@@@AA AhBxBA(A+A.A(A+A.A9AxBB(A+A.A1A1A9AxBB\AfAAAAA\AbAAAbAfAAAAAfApAAAAAAAfAlAAAAAlApAAAAApAzAAAAApAvAAAAAvAzAAA B=BCBFB=BCBFBXBTCNEYEEsCNEYEcEEEsC~C;EFEC1EYEcEEECCC EEECCCC_DjDCYDrD EEEDDYDE EJDYDE E E1EYEcE&E1EYEcEEF0FAF FFFFtFwFzFIIIIJFFFFFFFFFH%JCJFGGH%JCJFGGGFFGG+GCGFGIG+G7G=GCGFGIGCGFGIGYG_GbGCGFGIGMGSGYG_GbGYG_GbGqGzG}GYG_GbGeGkGqGzG}GqGzG}GGTHhHqGtG}GGtGzGGGTHhHH HHH=H@HFHIH@HFHIHTHhHHHHhHtHzHHHHHHHHHHHHHHHHHHHHHHHHHHHHGGGGHH-IGIHH0I8I;IGIHHHH III III I(I~IIII I#III#I(I~IIGI[IaIdIIINI[IaIdIII[IaIdI~I[IaIdIjIpI~IIIIJIIIJJJJJJJJJJKKLKKKLKKKKK%K(K*K9KDKKK{A{G{M{v{{{{{{*{Hzz{ ||"|Hzz{ ||"|HzKzNzbzKzNzbzz{ ||"|KzNzbzizkzpzszvzyzzzz{ ||"|zzzz6|9|G|L|O| ~~b~o|r|u|~||||||||||||||||||||||}}}}}}}}}}}} }}}} }}}} }}}})}4}I}O}P}I}O}P}[}]}`}[}]}`}n}t}w}n}t}w}}}}}}}}}}}}}}}}}}}}~%~}}}}}}}}~%~}}}}}}}}}}}}~FNx!,!$$,,:,22:TdTddvdvDTDT4D 4Dhknyhknqqyy҄y҄̀πҀ݄݀҄̀πҀՀՀ݄݄݄݀҄݀݀369D369<<DDR$DJ JR $dghtwztwz$4twz}}$4 4>Y 4>r 4ȁˁց܁    -03BHIBHITWZTWZfloflox{~x{~Ѓx{~ЃЃЃ‚łЂ ‚łȂȂЂ &&&4,44>:>9<?F`cfx9<?B`cfiBFixхх  "#+@HkۇއBKN\HPBENQEKQ\HP\kPl\bPVbkVlltltЈtLjtzLjЈz&&&5&,,5y|y|؋‹‹؋ۉމ؋ۉމ؋258D258;;DDS"DJ JS "begu+8+8 #8@#8@5H;HvyƒΒ׍ڍݍGPSaΒ֒GJSVJPVaΒ֒ap֒ag֒ܒgpܒƎƎƎՎƎ̎̎Վ%1$%((1$1@\i7@\iiqiqqqwwBOBOEHKWO\EHKNNWO\Wf5B]f5Bǐ(5ǐ(5ǐ֐(͐֐( $3 $3LOR^LORUU^^m^ddmƒ  ƒ8N>NǔʔДӔʔДӔ  ŘИA #39:lÕŕ|Aŕ + + +gjlgjlȖ˖`Ȗ˖8>DW`ėИėИҗؗۗ?""KQ[agwagwŘŘŘ&e&*-@^agjme2!))..IDPRUWZIe$dl{}šŚȚs3d~̞šŚߚ*d~̞šŚߚ7*&*7\̞̞(   ( (s(c*8@ORW*8EORWsyœŜלœŜȜȜל  l(/?BG(4?BGĝǝ369<69<N ',24Tzgz̟rz̟M[^a[^ap[^addppxP#47<)47<#KZ]`Z]`ozZ]`ccozow|z|8hz%(-%(-hz(7EHM(=EHM7H.147Wp]`kp]`tp]`p]`pktp)W]`y|$29$/9W/>>fFfiln?Do 2 2dСڣjknh=Pjknh=P7=@7=@KС(5=zڣߡ(5=ڣ(5=ڣ""Q("1(Q5=£ߠ(5͠ߠ(5Ӡߠ(5ߠhPehPe't0<BH036803680368YotwgotwotwΥԥեΥԥե٨    @ަ٨@RH`٨pILOR!ϧҧէ`٨9Yp,ϧҧէ`٨9Yp,;P[;P[`Yp[j`Yp̧٨#ϧҧէHIYRX[]lop~pux~~~¦ŦȦ¦ŦȦ¦ŦȦަH`¦ŦȦ˦˦ަH`  vvyy* `jmpz`p p p pp  p /IT #IO#/OT*MDKƭͭSY[` 0SY[`0`epssvƭƭڭWjmpjmpjmpv|jmprjmprjmprĮĮ׮ݮ߮׮ݮ߮#+.1#+.1+.1<S_+.144<S_  w  w7CINPS<CINPS԰   Ҵ Ҵڲ.9<=9<=CCINQINQx.ҴINQWZ[WZ[xWZ[iissxsxsvvx  ȱȱȱȱȱȱֱȱֱȱֱαֱֱֱܱȳȳȳȳسȳس%()369)*-369369Dس369<<DسDe}GJNe}w b}.Y}2Y}7ص!7=CFHKMeknеصеصõ69G_bc¶luxluxlox{ou{69GԷHRdghd{AEHPT`kѸԸθԸ{AEH`kƸθԸt`AkԸָݸ   !  !!-03!$'-03-03MSV`SV`MSVhnqMSV\bhnqhnqhnqw}͹йӹĹǹ͹йӹ͹йӹ &) &) &)8 &),28ɺҺպúɺҺպɺҺպ̺Һպغۺ   "% "%"%47:"%(.47:47:TZ]Z]TZ]rTZ]cirrûƻûƻûƻջۻ޻ûƻɻϻջۻ޻ջۻ޻ջۻ޻θѸ"0ο0ο0;4;JSVbMSVY\bb{bjmru{bjmp{~`p`p      `pz  `pz  `pz8Epz=Epz$08$08.<p#&)<#&),N_[.<p%(+>%(+.Rcmx.<p#&)<#&),N_ =?`'DP=?BH^^|Na = &)/.<p%(+>%(+.RcoWY\o9<?BF@21@2#9<FLOq\hknq_belq_belq$lqlq$\_beqq@2G@2GWouxoux0@Wa  @P   @P#&)0PW#&)0PW#&),,0PWj~ _~$_~~&ry&ly*lyy||ruxr#&#&2!dmp'*.14;ABGJMTWXX[^dmpdmpdmpwdgpsgmsww}ry+*T+*T*-36-36B+>DGADGVY\aiiiiw x=x=x[^dg^dgx 38;QQorx{rx{)3Xnuq`[cke+ZC[[[D+}%5]-|||Q - kzCy()3)3nxmpX2`8 /usr/include/c++/4.9.2/bits./include/gtest/internal./include/gtest./src/usr/include/c++/4.9.2/ext/usr/include/c++/4.9.2/usr/include/usr/include/bits/usr/include/sys/usr/include/c++/4.9.2/i686-redhat-linux/bits/usr/include/c++/4.9.2/tr1/usr/lib/gcc/i686-redhat-linux/4.9.2/include/usr/include/c++/4.9.2/debuglocale_facets.hgtest-port.hgtest.hgtest-internal-inl.hgtest.ccstl_vector.hgtest-test-part.ccgtest-death-test-internal.hstl_algo.hnew_allocator.hgtest-internal.hbasic_string.hatomicity.hstl_construct.hgtest-death-test.ccgtest-printers.ccostreamchar_traits.hgtest-message.hgtest-param-util.hstl_iterator.hstring.hsstreamstdio.hvector.tccstl_algobase.hgtest-test-part.hgtest-filepath.ccstat.h gtest-filepath.hgtest-port.ccbasic_ios.hios_base.hstreambufistreamiomanipbasic_string.tccgtest-printers.hmove.hmathinline.hstl_uninitialized.hstl_tree.hstl_pair.htypeinfopredefined_ops.hstl_iterator_base_funcs.hgtest-typed-test.ccstl_set.hiostreamcwcharcpp_type_traits.hstl_iterator_base_types.hc++config.h clocalenewallocator.hstringfwd.hcwctypeostream.tccstl_bvector.htuple iosfwdstl_function.hcstdlibbasic_ios.tccpostypes.hfunctexcept.hostream_insert.hstdio.hlibio.hstdarg.h stddef.h wchar.htime.hnumeric_traits.halloc_traits.htype_traits.hdebug.h locale.htypes.hsched.htime.hpthreadtypes.hatomic_word.h wctype.hstdlib.htypes.h sigset.hselect.h stat.hunistd.hregex.hgtest-string.hgtest-spi.hgtest-death-test.hsiginfo.hsignal.hsigaction.hstdlib-float.hstdlib-bsearch.hfcntl-linux.htime.h socket_type.hsockaddr.hsocket.hnetdb.hgthr-default.h errno.hctype.hpthread.hsocket.h wait.h mman.h sched.hfcntl.hcxxabi.h  y ><~ Z~  tN -Zf,h ~ffJ i .|<J JiU2  FJ;< }<"M <s;rX %u fu<zC<fz<C<=Cf t/<kJ<;=;j/.bJ=<a<<b<>^< <>; vC.=fC<=Cf=Cf 4gI=ig t v f  lfl<C< xfx<|Jf|f C"V#zX# X X ;=m<& vtC {<X< ~.g uJCf J u  fu< uC< f u<C< X u<Cf=fC<=fC<!$e=q<p< |J.Mhb@ l< l<C<} lCf>RV0 f7X/!e!!;!// iC<f i<C<=Cf=Cf=Cf=Cf=Cf=Cf=Cf=Cf=Cf=Cf=Cf=Cf=Cf=Cfw Xw< < iC<=fC<=Cf=Cf=Cf=Cf=Cf=Cf=Cf=Cf = Cf = Cf=Cf=Cf=Cf=CfE>: <f .fg *~<~fC<=Cf~ < <C<=CfNF</X ~<~fC<=JCf=JCf=JCf=JCfNo   Cf=JCf=fCf=Cf=Cf=<Cf=Cf=Cf=Cf+4~f<~<<;/ ~t<~<C<2  CX=Cfge=0 Ju fu<{ uzC<fz<C<=JCf=JCf=JCfJy. ~. ~<C< ~GCf=Cf=Cf = Cf=C<=fC<=C<=fCX<=@~2X L  ~  <  {f  < <  . |t}L?9} }< ~ < ~<C<-=}*+t }.<!}X zft | tCf3#<@:"<*~ ux*}.}f<}}f<~%XKo< }< LbffaJ<a.fa<a<Xgs=a<a<XMv!-.=Dz=_Xg<xJ tjgyfy<'gzX<<Yz<;zJ<zy, y,z. Jz<<Yz<;Kz<<zy, y,z<z< Jzfu<k<Y K<ky, "y,k<<k Jf<k<Y K<ky, "y,k<<k Jfv<} tCX~J Cf=CX~ J} Cf=JCf~J Cf=Cf=<Cf~ J <}y,.}xfg;g u fu<{ ~C<f ~<C<=JCf =J CfJ+ ~ ~<C<  ~: Cf=fC<=fC<= Cf'<<<{< X||f|} <} <}<|ff|f<|<} <}<<fy<<|X|f}f} <} <| f|Jf|f<|<} <}<<}f<< rC<f r<C<=tCfX rCf = Cf=tC<=fC< .>l}e! nt< n<C< lJCfg;=rf|f|} <} <}<|ff| f| f|} <} <}<|ff| f| f| f| f| f  p< p< p"C<f p<C<=tCfX o< _C<=fC< = Cf #<o<~<f<<1 l,< l<C<v l$Cf&<= z#i# l1C<f l<C<J l< l<C<=+Cf=fC<=fC<<=} n<}f} }f< lC<f l<C<=Cf k,< k<C<}  k< k<C<;=s=|J k< k<C<)W/.z%w1 k(Cf =' Cf=Cf=Cf= C<=fC<< i.=K;=k|fL<$n;=kk&kfit}<}X<}<}<}<gk fk |<f ~f< <kJ fnf fn<|<f ~f< ~<C<=Cf%gWgf} <} <}<|ff|f<|< ~f< <kJ fkf <n<|<< ~f< ~<C<=Cf <Y:>}<}<l  ~f.l |<f|?l;=l {fC<=fC< = Cf<=;>-.fU|f| } <} <|f<<| <k7A$| +~< <kJ flfC<fl<C<'. }< }<C<u {.Cf/[ }<(x.DB*zfz  "~< <kJ fkt <k  ~< <kJ flfC<fl<C<=Cf| +~< <kJ flfC<fl<C<fe!]| +~< <kJ flfC<fl<C<fkK| )8C.=fCf|<0|<<|t<|. <~< <kJ XlfC<fl<C<=C<=fC<J {Cf=fCfX {fCf=C<=fC< }C<=fC<=C<=fC<=.C<=fC< i9u Z;Yd~|f|f<|.< <D<  lC<fl<C<|f| f}t} <}<<| ft~<  |f< |<C<.~73u~|f|f<|.< <D<  lC<fl<C<|f| f}}f<|<ft~<  |f< |<C<JT {JCf {<Cf=JCf=fCf J<k<fkX.k^<|<}f<<}.<fa<<d<dXKj=dt <d=%f\<$._:0" Jgf^!^.! d _  < _<C< / ^!d _  < _<C< sJ^!^<! d _  < _<C<  _;Cf {BCf {BCfO<= mf l<.y&}}. n<}} }f< lC<f l<C<=Cfjv(x<x<X  lM Cf=fC<=fC<#<>U1i_|f|J} <} <}f#<b<bXK.3\~X>~|f|{<<~ |<=s <vf}<< ~f<< {< {<C<{# |Cf~1KXwt |<Ct |J |.C<tfx<x. |.J |XC<f,g;xXx.k==z<f~<|<< ~f~<< <kJ <pf <p<<{~f<|<f~~< y<y<~f<|<f~y<y.~f<|ff~{~<B<f<>{~f<|<f~y<y.~<<|X<~{~<B<f<>{~f<|<f~y<y.~<<|X<~{~<B<f<>t~ <~ 7Av v< <~fK=_I:u~f<|<f~u <u<~f<|<f~z< u <u<~f<|<f~u <u<~f<|<f~zX<z< {tC.=fC< {Cf=XCf Xy"y< *~*X,. D X J. {f< {<C<=Cf=Cf=Cf=Cf=Cf=Cf=Cf X|}X<~<XguCy<_}XJ D X J. {f< {<C<=Cf=Cf=Cf=Cf=Cf=Cf=Cf **X, ~fX|JzJ:0 {XCf=Cf=Cf=Cf=Cf=Cf=Cf=Cf&=$&Cf$=$Cf"="Cf = Cf=Cf=Cf=Cf=CfC {$Cf {XCf~<Z}ff{.<>>  u fu< ~<<  u fu< yC<f y<C<=Cf=Cf=Cf=Cf=Cf2  usc<Xa  uX  uu}}.. Xg;! xXC<f x<C<=Cf"}}.X;Y xoCf=Cf=Cf=Cf=Cf=C<=fC<= C<=fC<=Cft y>C<=fC<"> )})X*X A t.f. zf< z<C<=Cf=Cf=Cf=Cf=Cf=Cf=Cf .X:>5. zf< z<C<=Cf=Cf=Cf=Cf d<f0.!e! zf< z<C<=Cf=Cf=Cf=Cf=Cf=.Cf. zeCf=Cf!=!Cf#=#Cf%=%Cf = Cf=Cf=<Cf=Cf=Cf=Cf = Cf =' Cf = Cf=Cf=?Cf=Cf=Cf=Cf=Cf-<~$ yfC<f y<C<=tCfXx y8Cf=tC<=fC< <~)y~f<|<f~y<y<~f<|<f~~< y<y<~f<|<f~y<y<~f<|<f~~X<~< {tC.=fC<t {Cf=XCf5 {C<=fC<=Cf+6<J~)y~f<|<f~y<y<~f<|<f~~< y<y<~f<|<f~y<y<~f<|<f~~X<~< {tC.=fC<t {Cf=XCf=RCfX {C<=fC<F<J~)y~f<|<f~y<y<~f<|<f~}< y<y<~f<|<f~y<y<~f<|<f~~X<~< {tC.=fC<t {Cf=XCf=RCfX {C<=fC<F<J~)y~f<|<f~y<y<~f<|<f~}< y<y<~f<|<f~y<y<~f<|<f~~X<~< {tC.=fC<t {Cf=XCf=RCfX {C<=fC<F<J~)y~f<|<f~y<y<~f<|<f~}< y<y<~f<|<f~y<y<~f<|<f~~X<~< {tC.=fC<t {Cf=XCf=RCfX {C<=fC<Fjbbe<e  aC< afC< ` <C< < <C<=Cf=Cf=Cf=Cf.m"8@ a.< a<C<4zrb'=;=YbXfc<~Jf:$ic {fCf!bf=%a%Z=N8@=?6KMW _#Cf!b'OJ> _Cf=Cf!(t]<f}  Jt .r</>:>vf </sJoff*k<J;g~   t f0wf~$|f ~f< <kJ fnf fn<|<f ~fC<f ~<C<v }. .< w*&/zf*/~*</~. ./l0J ~JC<=fC<|f ~f< <kJ fnf fn<|<f*</zf*~/~*</~.i0  }C<0< }<C</~X(X<|<|M:}f<|ff}/I /l< Cf*X/ye=*< {XCf=tCf/~ /~< /~< <C</~  ttCf#=\#\.#. hf h<. \C<#K=LLLLMxo< \C<$7^<<,hzXf]<#Xa' yC=C=C=C=C=C ""X$[ t f # yff y<C< *X% yC=C=C=C=C=C ##X%*V t f# yff y<C< ~X yf yX ytfV'!e!t yJf y<C<=C=C=C=C=C#eX,J!e!JJ!e!J!e! yf y<C<=C=C=C=C=C=C=C=C=C=C=C=Cyy<#P~XXy.|X h,gg) )w .yff<~J<yffX<yff<~f  yf y<C<XW(fX( Ke |X zf z<C<=C=C=C=C=C=C=C ~ph#[9i( ztC=C=C=C=C=C X zf z<C<~u y<C=C=C=C=C=C X yf y<C<d> yC=C=C=C=C=C X yf y<C< |X yf y<C<=C=C=C=C=C=C=C yXC=C=C=C=C=C X yf y<C< *|*X,X ? f XJXXX yff y<C<=C=C=C=C=C=C=C|<7f|<zfP<f~X gt<l<  j f j< ~f. <n fn< ~< ~<.n fn<~lJfl  ~. <n fn< ~< <n fn< ~C<f ~<C<}f tCX~tt J  h.Cf  kfg;3 h C<f h<C<=Cf~f }J.L, h < h<C<=Cf}f }J.K, h < h<C<=Cf)  h  <  h< C<=Cf0 hJ< h<C<=Cf6 h < h<C<=Cf h < { l<l<C<bsyb h~< hh:/<'.;;==< tCX~< J Cf<ztX w< w<C<w Jwf<w<X~f~<  tCX~ J<W).vX{f<!{tf{<{f<|3 {X xC<=<C<  wXCf=<Cf=tCfJJ$<>ketX~f./z t tCf bC%@w<=kf k</~<<k<JflP im{c J~< <.kJ fkCyXy<nl<l<z<fh<.c<f |X< ~f< <kJ fnf fn<|<f ~f< <kJ flf<l<C<.n<<n<fnrx. {< {<C< 91Y tCf x h:- t< < s<=fC<J}f fCX~tt J  t.Cf =  |u|f<|<Ju}< }X}<X SC< SfC< ~ Cf=Cf=Cf=Cf=CffvX < v   <~f<~<C<=;Ky),ty,| yJ'y<y< {C<=fC<=Cf = Cf = Cf @. wtCX w?Cf=fCf=CfJ< b<f bf< b.< i.t if2JztB<}f<|<<}f<<}.<|f<|<}fD < <C< s< <K {CXz5 Cf#`xf s* < s<C<  sCfv > LguLz x K)fu~ fw#jh9?+?sX ptt Kft~ Z0"+vW=1:hhhr p  <a<f82l#C_J fcf:>egL,>=-=c {Xi [9i f% {. |b}.t}t:>d5c fh 4 } ~<C<=fC<= Cf=Cf<f}}  t} }J ~< <l<l<C<=<Cf KKf0g;=I=X}<|X<}f}<<~ ~<< yb< z<z<C<u{. }<<!}< zf hf h.X Cfg;=  f<l<.kJ flf <ly.. <|'~<-//.3u*~.~f<~~f<~ht+!-.=<{f.u >V..Xxffx< <w<} Cf~ J  w} Cf~  J <>Vt../x*./  z<Xzf[b2XuYgt!.tN|tC<=fC< h:>}X_"!_<  u fu< ~<<  u fu< ~<  xC<f x<C<=JCf=JCf=JCf=JCf=JCf y<Cf=Cf= Cf= Cf= Cf  yC<=fC<=Cf=Cf=Cf=Cf=Cf=>C<=fC< h:?e*U"+U<  u fu< ~<<  u fu< ~<  xC<f x<C<=JCf=JCf=JCf=JCf=JCf y Cf=Cf= Cf= Cf= Cf  yC<=fC<=Cf=Cf=Cf=Cf=Cf=>C<=fC<< #C ~f#f~#"}f#f}f"f"<"f"<} f~f f}<.y. ~< .kJ lf<l<C<~#0 ~f Cf}<$f% z ft ) 7 <X {#X ~f#,~#~.#$}#f"}"<(""f"f} f~f|  f< }ff$}.f!<|<!| X#( ~f# ~f#~#f~.#}#f}t"<"""f} f~f .$}f!<|<!|fyf -sy ~f<|<~yfy.~f<|<~~< ytfy.~f<|<~yfy.~f<|<~f~ f~  {f {<C<=C|- C"V#z f# z#  #~f t< }f<|' C"V#z f# z# fuf#  #~f t<{<<gg<< zt fwf fwXx  {.C=.C.#xX 8}G#|/ 04k zJ t +  {#X ~f#.~#<~.#,}#f"}"<(""f"f} f~f|f f< }ff$}f!<|<!t| X#, ~f#J ~f#~#f~.##}#f}t"<"""f}f f~f .< }ff$}<f!<|<!t|fyf -sy<~f<|<~yfy.~f<|<~~< ytfy.~f<|<~yfy.~f<|<~f~ f~  {f {<C<=C|- C"V# {# z#  J#~f t< }f<|' C"V#z f# z#  #~f t<{<<gg<< y tp  {.C=.C.#xX 8}G#|/ 04<=KI/.{+f{<& ytC<=fC<=JCfJ~Z~8 yC<=fC<= Cf@8@ ~J%f<<<<f  .s  X <J <~fC<f~<C<=JCfJ|<{X y)}<<)}. J)|a)}<.)}< tJ)|<} CX~J Cf ={z+ tg;0H V.Cf {zX CX=tCX)~ w Jw< X)kt <C } XCX)~ w Jw< X)ktX ~,)}X}w Jw< X)hX K {fCf0  ~j:.u~J:.t|t.|. f={ yX1HKJo.~< J0I={tC{ zf  ~hh{.zJz.   ~j:.u~J:.t|t.|. f={ yX1HKJo.~< J0I={tC{ zf  ~j:.u~J:.t|t.|. f={ yX1HKJo.~< J0I={tC{ zf KKf0< ~f Cf=Cf=Cf=Cf=Cf=Cf $$}X' I   u fu<z <z< u fu< u< u fu<z < <C<=Cf=fCf=Cf=.Cf= Cf=Cf }X C<=fC<=Cf=Cf=Cf=Cf=Cf = Cf=8C<=fC<=@C<=fC<fJfJ[%f[J%[%f[J%  ~j:.u~J:.t|t.|. f={ yX1HKJo.~< J0I={tC{ zfg;f} <} <}z<,x<f,xuW{ff,x tt& |X&f | #@ ~f#<0~#3"}J#f}t"f("<<"t}|  <~f f< }ff}.<}< m<m<|t C"V#z#fz# fuf#  X&;=#z+ &%}& X yJJ yJ< y< t m t m t mr J mt {ft { {n  mt  < mt  < mua X yf. y.< y< "<nX<nX< m .nX  mJ"f rJ {J r { r {\ t.rX |<.nX  mJ X frJ|X  n   m  X yJ yJ< y<-<.-a<-a<-a< `.v-.et-{<.et-{<. `B {<. {< {f. {f% N%.V<%*..Vf%*. f%~f .<. X%B%fmX< 8 t<&=;=& \J#< \#<Jyj8 [.Cf$;ְZKzx v u srqponmkig mJ [CfJ mJJ mJJL [Cf&=$ \t#< \#<JOj8 [.Cf$;ְZKzx v u srqponmkig mJ [CfJ mJJ mJJL [Cf>,x<f,xuW{ff,x tt Z CX~@ ~ J ~<.h:><~<f~<</  <t<  <s  J~<~<C< |<{X y)}<<)}. )wa)}f.)}<.)}< f)w<} tCX <={Jz tg-/={zX)0)S Cf f}3 t)}XX C)~X0)S&=91.q ]<~<~<C<u< CX~&Xd."` yX {fCf%`` {%Cf&=91.q ] ~<~<C<u<.w< CX~ <d.` yX {fCf%4`` {%Cf Z Cf~0 >ul<l<<guf <y{J|-;>) J)| <v< <t: tw)_< )hXXf J )t0)S @b@ ~J~$f~f<<~<f f< sf f< < <~f<~<C< |<{X y)}<<)}. J)|a)}f.)}<.)}< fJ)|<} tCf <={Jz t:h:/=t{zX)0)S Cff}3 t)}XX C)~X0)S<wf _8>H*X?9id q< q<C< q Cf?9i q< q<C<w  qCfw<wf _8>H*X?9id q< q<C< X qCf?9i q< q<C<]r qCfw<wf _8>H*X?9id q< q<C< q Cf?9i q< q<C<w  qCfw<wf _8>H*X?9id q< q<C< X qCf?9i q< q<C<]r qCfw)_ZNK7testing8internal24HasNewFatalFailureHelper21has_new_fatal_failureEv_ZNSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE2atEjPrintAsStringLiteralTotesting_internalRawType_ZNK9__gnu_cxx17__normal_iteratorIPPN7testing8TestInfoESt6vectorIS3_SaIS3_EEEmiEi_ZNSt11char_traitsIcE4copyEPcPKcj_ZNSt6vectorIPcSaIS0_EE8_M_eraseEN9__gnu_cxx17__normal_iteratorIPS0_S2_EES6__S_oct_ZN7testing8TestCase11ClearResultEv_TypestartPrintStringTo__copy_move_backwardread_ZN7testing8internal12TypeIdHelperINS_4TestEE6dummy_E_ZN7testing8internal24HasNewFatalFailureHelperD0Ev_ZNSbIwSt11char_traitsIwESaIwEE6assignEPKw_ZN7testing22EmptyTestEventListener13OnTestCaseEndERKNS_8TestCaseE_ZN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE11ValueHolder7pointerEv_ZNK7testing8internal13FloatingPointIfE8sign_bitEv_ZN7testing8TestCase16RunSetUpTestCaseEvstrtof_ZNKSbIwSt11char_traitsIwESaIwEE7compareEjjPKw__alloc_traits >_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE6_S_keyEPKSt13_Rb_tree_nodeIS1_E_ZN7testing32ScopedFakeTestPartResultReporter4InitEvstrtoloperator<< _ZN9__gnu_cxx14__alloc_traitsISaIPN7testing8TestInfoEEE10_S_on_swapERS4_S6__ZN7testing8internal13DeathTestImpl12set_write_fdEi_ZN7testing8TestInfoaSERKS0___haystackIsNotSubstringallocatorgetwcconstruct >ImplicitCast__ZNKSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE2atEjgtest_arline_number__ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EE2atEj_ZNK9__gnu_cxx17__normal_iteratorIPN7testing12TestPropertyESt6vectorIS2_SaIS2_EEEptEvCheckedDowncastToActualType >::ValueHolder, testing::internal::ThreadLocalValueHolderBase>socklen_t_ZNSt6vectorIPN7testing8TestCaseESaIS2_EE7reserveEj_Rb_tree_node_base__niter_base_ZNKSt6vectorIiSaIiEE8capacityEvHandleExceptionsInMethodIfSupported_ZN9__gnu_cxx17__normal_iteratorIPKPN7testing17TestEventListenerESt6vectorIS3_SaIS3_EEEmmEi_ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EE5frontEv__copy_move_backward_a_ZN7testing8internal27PrettyUnitTestResultPrinter11OnTestStartERKNS_8TestInfoE_ZN7testing18TestEventListeners22SetDefaultXmlGeneratorEPNS_17TestEventListenerEHandleSehExceptionsInMethodIfSupportedMSG_EOR_ZNKSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE12_M_rightmostEv_ZN7testing8internal12UnitTestImpl21set_current_test_infoEPNS_8TestInfoE_ZN9__gnu_cxx17__normal_iteratorIPKN7testing8internal9TraceInfoESt6vectorIS3_SaIS3_EEEmIEiswprintftype__ZNKSs5rfindERKSsj__uninit_copy<__gnu_cxx::__normal_iterator*, std::vector > >, std::basic_string*>si_codebasic_stringstreamsockfd__ZNKSt3setISsSt4lessISsESaISsEE11upper_boundERKSs_ZNKSt9_IdentityISsEclERKSsmbsinit_ZNKSt6vectorIiSaIiEE8max_sizeEv~ExecDeathTest_ZNSt6vectorIPN7testing11EnvironmentESaIS2_EEixEj__numeric_traits_integerfrac_digits_ZN7testing22EmptyTestEventListener22OnEnvironmentsSetUpEndERKNS_8UnitTestEoperator<< last_errorfailbitUniversalPrint >_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE5eraseESt17_Rb_tree_iteratorISsEuninitialized_copybreak_on_failure__ZNK7testing8internal10scoped_ptrIKSsEdeEv_ZNSbIwSt11char_traitsIwESaIwEEpLEPKwTestEventListenerswap*>expected_expressiondata_internal_run_death_test__rhsactual_ZNKSt17_Rb_tree_iteratorIPKcEdeEv_ZNSt6vectorIPN7testing8TestCaseESaIS2_EE4rendEv_ZNK7testing8internal8FilePath21FileOrDirectoryExistsEv11__mbstate_tIsPathSeparator_ZNSt12_Vector_baseIPN7testing11EnvironmentESaIS2_EE13_M_deallocateEPS2_j_ZN7testing8internal17StreamingListener12SocketWriterD0Ev_ZN9__gnu_cxx17__normal_iteratorIPKPN7testing17TestEventListenerESt6vectorIS3_SaIS3_EEEmmEv_ZNSt6vectorIN7testing12TestPropertyESaIS1_EE15_M_erase_at_endEPS1_si_errno_ZN7testing8internal12UnitTestImpl21set_current_test_caseEPNS_8TestCaseE_ZNK7testing8internal10scoped_ptrIKSsE3getEv_ZN7testing8internal13DeathTestImpl11set_spawnedEbpair_ZN7testing19TestPartResultArrayaSERKS0_impl__normal_iterator, std::allocator > >vector >_ZNKSt12_Vector_baseIN7testing12TestPropertyESaIS1_EE13get_allocatorEvcopy_backward*, std::basic_string*>_ZNSt6vectorISsSaISsEE8_M_eraseEN9__gnu_cxx17__normal_iteratorIPSsS1_EES5_should_run__ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE15_M_insert_equalERKS1_FloatingPointLE_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE6_S_keyEPKSt13_Rb_tree_nodeISsETypeIdfor_each<__gnu_cxx::__normal_iterator >, void (*)(testing::Environment*)>_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE12_M_erase_auxESt23_Rb_tree_const_iteratorIS1_ES9_StrError_Destroy_ZNKSbIwSt11char_traitsIwESaIwEE13get_allocatorEv_M_insert_lower_ZNSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE8pop_backEv~StreamingListeneroperator- >_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE16_M_insert_uniqueERKSsTEST_ENCOUNTERED_RETURN_STATEMENT_ZNK9__gnu_cxx17__normal_iteratorIPPN7testing8internal29ParameterizedTestCaseInfoBaseESt6vectorIS4_SaIS4_EEE4baseEv_ZN7testing4Test14RecordPropertyERKSsiiterator_traits<__gnu_cxx::__normal_iterator, std::allocator >*, std::vector, std::allocator >, std::allocator, std::allocator > > > > >_ZN9__gnu_cxx14__alloc_traitsISaIN7testing8internal9TraceInfoEEE10_S_on_swapERS4_S6__ZNSt11char_traitsIwE11eq_int_typeERKjS2___cxa_begin_catchsrc_texterror_message_ZNKSt6vectorIPN7testing11EnvironmentESaIS2_EE5beginEvoperator delete_ZNKSt12_Vector_baseIPcSaIS0_EE13get_allocatorEv_ZNSt6vectorIPcSaIS0_EE4dataEv_Allocator_ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EE2atEjoriginal_reporter__ZN9__gnu_cxx13new_allocatorISsE10deallocateEPSsj_ZN7testing8internal23kTestTypeIdInGoogleTestE_ZN9__gnu_cxx13new_allocatorIPKcE7destroyEPS2_operator<< , std::allocator >file__ZN7testing8TestCaseaSERKS0_AssertHeld_ZNKSt6vectorIPN7testing8TestCaseESaIS2_EE4dataEv_ZNK9__gnu_cxx17__normal_iteratorIPcSsE4baseEv_ZN7testing8internal17TestEventRepeaterD2Ev_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE7_S_leftEPKSt18_Rb_tree_node_basereverse_iterator<__gnu_cxx::__normal_iterator, std::allocator > > >TestPartResultTypeToString_ZN9__gnu_cxx14__alloc_traitsISaIPN7testing17TestEventListenerEEE8max_sizeERKS4__ZN7testing8UnitTest14AddEnvironmentEPNS_11EnvironmentE_ZNSs7reserveEj_ZNSt12_Vector_baseIPcSaIS0_EE17_M_create_storageEj_Iter_equals_val, std::allocator > >InitGoogleTestRETURNED_ZNKSt12_Vector_baseIiSaIiEE13get_allocatorEvregistered_testsoperator booluser_msg_string_ZN7testing8internal13ExecDeathTestD0EvAbstractSocketWriter__ino_toriginal_working_dir_iterator_traits, std::allocator >*>_ZN7testing8internal12UnitTestImpl31GetGlobalTestPartResultReporterEvregex_ZNK7testing8internal12UnitTestImpl21successful_test_countEv_ZNK9__gnu_cxx17__normal_iteratorIPKcSsEplEinormalized_seed_ZN7testing14TestPartResult14ExtractSummaryEPKcStackLowerThanAddress_ZNK9__gnu_cxx17__normal_iteratorIPPN7testing8TestCaseESt6vectorIS3_SaIS3_EEEmiEitest_propertiesmove_ZNK9__gnu_cxx13new_allocatorIPN7testing17TestEventListenerEE7addressERS3__CharToperator<< _ZN7testing14ExitedWithCodeC2Eiunsigned int_ZN7testing8internal12UnitTestImpl34InitDeathTestSubprocessControlInfoEvignoring_casePrintTowcstold_ZNSt12_Vector_baseIPN7testing17TestEventListenerESaIS2_EE17_M_create_storageEj_ZNSt10_Iter_baseIN9__gnu_cxx17__normal_iteratorIPPN7testing17TestEventListenerESt6vectorIS4_SaIS4_EEEELb0EE7_S_baseES9__ZN9__gnu_cxx14__alloc_traitsISaIiEE17_S_select_on_copyERKS1_copy_backward_ZNSbIwSt11char_traitsIwESaIwEE6appendEPKwj_ZNKSbIwSt11char_traitsIwESaIwEE16find_last_not_ofEPKwjj_ZN9__gnu_cxx14__alloc_traitsISaIPN7testing11EnvironmentEEE8max_sizeERKS4__ZN9__gnu_cxx17__normal_iteratorIPKcSsEmIEiClearTestResult_ZNKSs11_M_disjunctEPKc_vptr.UnitTestdestinternal_run_death_test_flag_size_t_ZN7testing8internal17StreamingListener12SocketWriter15CloseConnectionEv_M_destroy_noderegoff_tparameterlower_bound_ZNSt6vectorIPcSaIS0_EE8pop_backEv_ZNK7testing8internal12UnitTestImpl11random_seedEv_ZNK7testing8internal13DeathTestImpl6statusEvlast_sep_ZN7testing8internal16UniversalPrinterISsE5PrintERKSsPSopthread_mutex_tad_hoc_test_result_bool_ZN7testing8internal15CodePointToUtf8Ejunicode_code_pointcomma__distanceFloatingPoint_ZNKSbIwSt11char_traitsIwESaIwEE16find_last_not_ofEPKwjFormatForComparisonFailureMessage_ZNK7testing14TestPartResult14fatally_failedEvString_Category~TestFactoryBasekUniversalFilter__builtin_fwrite_ZN7testing8internal13GetTestTypeIdEv_ZNSs4_Rep7_M_grabERKSaIcES2__M_copyreverse_iterator<__gnu_cxx::__normal_iterator, std::allocator >*, std::vector, std::allocator >, std::allocator, std::allocator > > > > >argvs_ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EE6insertEN9__gnu_cxx17__normal_iteratorIPS2_S4_EEjRKS2___cxa_throw_ZN9__gnu_cxx13new_allocatorIwE8allocateEjPKv_ZNSbIwSt11char_traitsIwESaIwEE6assignERKS2_summary_rdstatekStackTraceDepthFlagfreadTestPartResultArraythread_count__copy_move_b*, std::basic_string*>operator!= >_S_blackos_stack_trace_getter_ZNSo9_M_insertIPKvEERSoT___cxa_guard_abort_ZN7testing8internal12UnitTestImpl12ShuffleTestsEv_sigfaultGTEST_SHARD_INDEXMSG_CONFIRM__is_normal_iterator_ZNSt6vectorIiSaIiEEixEjTearDownTestCaseFunc__miter_basekThresholdint_n_cs_precedesbinary_function, std::allocator >, std::basic_string, std::allocator >, bool>_ZN7testing8internal35HandleExceptionsInMethodIfSupportedINS_8TestCaseEvEET0_PT_MS4_FS3_vEPKc_M_key_compareallocator~ForkingDeathTest_ZNKSt6vectorISsSaISsEE6rbeginEvatexitreverse_iterator<__gnu_cxx::__normal_iterator > > >kReservedTestSuiteAttributesDeathTestImpl_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE15_M_destroy_nodeEPSt13_Rb_tree_nodeIS1_E_ZN7testing7MessageC2Evfwrite_ZNKSs13find_first_ofEcj_ZN9__gnu_cxx17__normal_iteratorIPKSsSt6vectorISsSaISsEEEmmEisi_addr_lsb_ZNKSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE14_M_range_checkEj_ZN9__gnu_cxx17__normal_iteratorIPKPN7testing8TestInfoESt6vectorIS3_SaIS3_EEEmIEi_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE16_M_insert_equal_ESt23_Rb_tree_const_iteratorIS1_ERKS1__ZNSt6vectorIiSaIiEE5beginEv_ZN9__gnu_cxx17__normal_iteratorIPKSsSt6vectorISsSaISsEEEmmEv_Valcurrent_test_info_operator<< GTEST_ERRORforwarding_enabledsiginfo_t_ZN7testing8internal29ParameterizedTestCaseInfoBaseaSERKS1_kColorEncodedHelpMessage_ZNSt6vectorIN7testing14TestPartResultESaIS1_EE5eraseEN9__gnu_cxx17__normal_iteratorIPS1_S3_EE_ZNSbIwSt11char_traitsIwESaIwEE6assignERKS2_jjstringstream_Key_ZNSt6vectorIN7testing12TestPropertyESaIS1_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS1_S3_EERKS1__ZNSbIwSt11char_traitsIwESaIwEE4_Rep7_M_grabERKS1_S5_~SingleFailureChecker_ZNK7testing8UnitTest22test_case_to_run_countEvpop_backrend_ZNKSbIwSt11char_traitsIwESaIwEE17find_first_not_ofEPKwjsuccessful_test_count_ZNKSs5rfindEPKcjjname_ZN9__gnu_cxx17__normal_iteratorIPKPN7testing17TestEventListenerESt6vectorIS3_SaIS3_EEEpLEioutput_format_ZN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE11ValueHolderaSERKS5_rebind~ScopedPrematureExitFileoperator<< _ZN7testing8internal2RE9FullMatchEPKcRKS1_MSG_RSTOnTestPartResult_ZN7testing4Test15HasFatalFailureEv__cxa_atexit_ZN7testing8internal17PrintWideStringToERKSbIwSt11char_traitsIwESaIwEEPSocur_addr_ZN7testing8internal12UnitTestImpl27parameterized_test_registryEv_ZNKSs5beginEv_ZNK7testing8internal13DeathTestImpl7outcomeEv__cxa_guard_acquirefind_first_ofn_cs_precedes__normal_iterator, std::allocator >*, std::vector, std::allocator >, std::allocator, std::allocator > > > >_ZNSt6vectorIN7testing14TestPartResultESaIS1_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS1_S3_EERKS1_output_ZN7testing8internal27PrettyUnitTestResultPrinterD2EvGetTestPartResult_ZNSbIwSt11char_traitsIwESaIwEE6insertEjRKS2_jjoutput_GetPrefixUntilComma_ZN7testing8internal24XmlUnitTestResultPrinter24IsNormalizableWhitespaceEcLock_ZNSt6vectorIN7testing14TestPartResultESaIS1_EE6rbeginEvCOLOR_GREENoperator<< _ZN7testing8internal16ForkingDeathTestC2EPKcPKNS0_2REEline_num_S_right_ZN9__gnu_cxx13new_allocatorISt13_Rb_tree_nodeISsEE8allocateEjPKvMakeFrom_S_empty_rep_ZSt29_Rb_tree_insert_and_rebalancebPSt18_Rb_tree_node_baseS0_RS__Znwj_ZN9__gnu_cxx17__normal_iteratorIPPN7testing11EnvironmentESt6vectorIS3_SaIS3_EEEpLEi__is_null_pointermethod_ZNSs6insertEN9__gnu_cxx17__normal_iteratorIPcSsEEjc_ZNK9__gnu_cxx13new_allocatorIPcE7addressERKS1__ZNKSs7compareEjjRKSsset_current_test_case_ZNSt12_Vector_baseIPN7testing17TestEventListenerESaIS2_EE13_M_deallocateEPS2_j_ZN7testing7MessagelsEPw__iterator_category__is_normal_iterator_ZN7testing8internal10scoped_ptrINS0_24InternalRunDeathTestFlagEE5resetEPS2_iterator_traitsallocatorUniversalPrintCharArray_ZN9__gnu_cxx13new_allocatorIPcE9constructEPS1_RKS1___alloc_traits >operator!= >__destroy__elems_beforevalue_compare_ZNSt11char_traitsIwE2eqERKwS2__ZNKSt6vectorIPN7testing8TestCaseESaIS2_EE8capacityEv9siginfo_t~TestEventRepeater_ZN7testing10TestResultaSERKS0__ZNKSt6vectorIN7testing12TestPropertyESaIS1_EE4dataEv_ZNK7testing8TestCase17test_to_run_countEvseekdirGetCurrentExecutableNametest_case_name__Destroy*, std::basic_string >operator- >_vptr.UnitTestImpl_ZN9__gnu_cxx17__normal_iteratorIPKcSsEpLEi_ZNKSt18basic_stringstreamIcSt11char_traitsIcESaIcEE3strEvexpression_textOnTestCaseEndbytes_readtm_hour_ZNSt6vectorISsSaISsEE8_M_eraseEN9__gnu_cxx17__normal_iteratorIPSsS1_EESignAndMagnitudeToBiasedoperator<< __trip_countreportable_test_count_M_insert_ZNSt3setISsSt4lessISsESaISsEE4findERKSs_ZNSbIwSt11char_traitsIwESaIwEE7replaceEN9__gnu_cxx17__normal_iteratorIPwS2_EES6_jw_ZNK7testing8internal29ParameterizedTestCaseInfoBase17GetTestCaseTypeIdEvCaptureStdout_ZNSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE6insertEN9__gnu_cxx17__normal_iteratorIPS3_S5_EERKS3__ZNSt6vectorIPN7testing11EnvironmentESaIS2_EE8_M_eraseEN9__gnu_cxx17__normal_iteratorIPS2_S4_EE_ZNSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS3_S5_EERKS3___addressof >_ZNKSt3setISsSt4lessISsESaISsEE4findERKSsunknown fileExecDeathTestArgs_ZNKSt6vectorIPN7testing8TestCaseESaIS2_EE8max_sizeEv__gthread_active_ptrkExponentBitCountstatus_ok_ZNK7testing8internal13FloatingPointIdE13exponent_bitsEv_ZNKSbIwSt11char_traitsIwESaIwEE13find_first_ofEPKwj_ZNKSt6vectorIPcSaIS0_EE5frontEv_S_out_ZN7testing8internal24XmlUnitTestResultPrinter18EscapeXmlAttributeERKSs_Destroystrrchr_ZN9__gnu_cxx13new_allocatorIPN7testing8TestInfoEE9constructEPS3_RKS3__ZN7testing8internal12UnitTestImpl11RunAllTestsEv_ZNSt6vectorIPN7testing8TestInfoESaIS2_EE4swapERS4__ZN7testing8internal9DeathTest4WaitEv_ZN9__gnu_cxx17__normal_iteratorIPSsSt6vectorISsSaISsEEEmmEi_HasBase_ZN7testing18TestEventListenersD2Ev_ZNSt6vectorIPN7testing8TestCaseESaIS2_EE9push_backERKS2__vptr.AbstractSocketWriter_ZN9__gnu_cxx17__normal_iteratorIPSsSt6vectorISsSaISsEEEmmEv_ZNK7testing8internal8FilePath5c_strEvdo_widen_ZNKSt6vectorIPN7testing8TestCaseESaIS2_EE4rendEv_ZN7testing8internal12UnitTestImpl31SetGlobalTestPartResultReporterEPNS_31TestPartResultReporterInterfaceE_ZNK7testing19TestPartResultArray4sizeEv_ZNK7testing8TestCase6PassedEvPopGTestTracesign_bitrebind_ZNSt12_Vector_baseIN7testing8internal9TraceInfoESaIS2_EE13_M_deallocateEPS2_jDeathTest_ZNKSt6vectorISsSaISsEE4rendEv_ZNK7testing15AssertionResult7messageEv_ZNK7testing8internal17TestEventRepeater18forwarding_enabledEva_value_paramoperator!__iterator_categoryfputcoperator&operator*operator+iterator_traitsoperator-_ZNSt12_Vector_baseIPN7testing11EnvironmentESaIS2_EE11_M_allocateEjfputs_ZStplIcSt11char_traitsIcESaIcEESbIT_T0_T1_ERKS6_S8_operator<operator=operator>FormatForComparison_ZNSs9_M_mutateEjjj_ZN7testing17TestEventListener24OnEnvironmentsSetUpStartERKNS_8UnitTestE_ZNKSt3setISsSt4lessISsESaISsEE5beginEv_ZN7testing8internal6Random6ReseedEj_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE17_M_insert_unique_ESt23_Rb_tree_const_iteratorIS1_ERKS1_rebindSOCK_RAW_ZNSt6vectorIPN7testing8TestCaseESaIS2_EE6insertEN9__gnu_cxx17__normal_iteratorIPS2_S4_EERKS2__ZN7testing8internal7PrintToEhPSo_ZNSs12_S_constructIPcEES0_T_S1_RKSaIcEis_selectedsystemwcsrtombsTestProperty_ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EEixEj__valFailFromInternalError_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE14_M_lower_boundEPSt13_Rb_tree_nodeIS1_ESA_RKS1__timer_ZN7testing10TestResult17AddTestPartResultERKNS_14TestPartResultEquot_ZNSt6vectorISsSaISsEE6rbeginEv_ZNKSt6vectorIPN7testing11EnvironmentESaIS2_EE6rbeginEvthrow_on_failure_operator|operator~atof_ZNSt9basic_iosIcSt11char_traitsIcEE5clearESt12_Ios_Iostate_ZN9__gnu_cxx17__normal_iteratorIPKPN7testing8TestCaseESt6vectorIS3_SaIS3_EEEmIEiatoiatol_ZNKSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE6rbeginEv_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE3endEvPrintToStringconstruct_ZN7testing4Test13SetUpTestCaseEv_ZN7testing8internal17TestEventRepeateraSERKS1__ZNSt3setISsSt4lessISsESaISsEE5eraseESt23_Rb_tree_const_iteratorISsEgoodbitwcstombswrite_Rb_tree_iterator_ZN7testing8internal26ThreadLocalValueHolderBaseaSERKS1__Znaj_ZN9__gnu_cxx17__normal_iteratorIPKSsSt6vectorISsSaISsEEEpLEi__k2_M_eraseCreateDirectoriesRecursively_ZNSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE5eraseEN9__gnu_cxx17__normal_iteratorIPS3_S5_EES9_exit_status_ZNSt6vectorIiSaIiEE5eraseEN9__gnu_cxx17__normal_iteratorIPiS1_EEfull_pattern_S_hexowner__sigpoll_ZNKSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE6_M_endEvint_p_sep_by_spacekMaxRangeGetStringFunctor_ZN7testing8internal12AssertHelper16AssertHelperDataaSERKS2__Rb_tree_const_iterator, std::allocator > >_ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EE15_M_erase_at_endEPS2_IsAbsolutePathfailed_test_case_count_ZNKSt6vectorIPN7testing8TestCaseESaIS2_EE5frontEv_ZNSs4_Rep10_M_disposeERKSaIcEfputwc_Iterator_Iter_base_M_clone_nodeParseStringFlagFilterMatchesTestfputwsMakeConnection~basic_stringCmpHelperSTRCASEEQiterator_traits<__gnu_cxx::__normal_iterator > > >index_ZNK7testing8TestInfo6resultEv_ZNKSs12find_last_ofERKSsj_ZN7testing8UnitTestC2Ev_ZNK9__gnu_cxx17__normal_iteratorIPPN7testing8TestInfoESt6vectorIS3_SaIS3_EEEptEv_ZNSt6vectorIiSaIiEEaSERKS1_fcntl_ZNK7testing8internal17TestPropertyKeyIsclERKNS_12TestPropertyE~DeathTestImpl_ZN7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEE11ValueHolderaSERKS7__ZN7testing8internal13FloatingPointIfE8InfinityEv_S_ios_openmode_end_ZN7testing8TestCaseD2EvGTestFlagSaverGetOutputFormat_ZN9__gnu_cxx13new_allocatorIcE10deallocateEPcj_ZN7testing8internal18SetInjectableArgvsEPKSt6vectorISsSaISsEErandom_ZN9__gnu_cxx14__alloc_traitsISaISsEE8max_sizeERKS1__ZNKSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE11upper_boundERKSs_ZNKSt6vectorIPN7testing17TestEventListenerESaIS2_EE2atEjstrtold_ZNK9__gnu_cxx17__normal_iteratorIPKN7testing8internal9TraceInfoESt6vectorIS3_SaIS3_EEEdeEvoperator<< suffix_len_ZNSt6vectorIPcSaIS0_EE5frontEvportset_up_tc__maskTestPassed_M_destroyMSG_MOREnew_holder_ZN9__gnu_cxx14__alloc_traitsISaIN7testing14TestPartResultEEE10_S_on_swapERS3_S5__ZNKSt6vectorIN7testing14TestPartResultESaIS1_EE2atEj_M_fill_assign_ZNSt3setIPKcSt4lessIS1_ESaIS1_EE4findERKS1_operator<< operator<< _ZNKSs7_M_iendEv_ZN7testing8internal11ScopedTraceD2Evresume_pos_ZNK7testing8internal12UnitTestImpl18ad_hoc_test_resultEvtm_yday_ZNSt6vectorIPN7testing8TestInfoESaIS2_EE14_M_fill_assignEjRKS2__ZNSt8ios_base4setfESt13_Ios_FmtflagsS0_putwcharftell__miter_base<__gnu_cxx::__normal_iterator > >SOCK_STREAM_ZSt16__ostream_insertIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_PKS3_icomparestream_result_to__ZNSt6vectorIPN7testing11EnvironmentESaIS2_EE7reserveEj_ZN7testing8internal12AssertHelperaSERKS1_ExecDeathTestSpawnChild__blksize_t_ZNKSbIwSt11char_traitsIwESaIwEE12find_last_ofEPKwjj_M_upper_bound_ZNK9__gnu_cxx17__normal_iteratorIPPcSt6vectorIS1_SaIS1_EEEixEiPrintCharAndCodeTo_ZN7testing14TestPartResultD2EvAddEnvironment_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE10_S_maximumEPKSt18_Rb_tree_node_basepthread_mutex_unlock_ZNKSt6vectorIPcSaIS0_EE3endEvint_curr_symbolset_write_fd~GTestLog_ZN7testing8UnitTest14PushGTestTraceERKNS_8internal9TraceInfoEnum_runnable_tests_ZNK9__gnu_cxx17__normal_iteratorIPKN7testing8internal9TraceInfoESt6vectorIS3_SaIS3_EEEixEi_ZNSbIwSt11char_traitsIwESaIwEE6insertEjRKS2__ZNKSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE5beginEv_ZN7testing8internal12AssertHelperD2Ev_ZNK9__gnu_cxx13new_allocatorIcE7addressERKcpthread_key_create_TrivialValueTypesfind_if<__gnu_cxx::__normal_iterator >, testing::internal::TestCaseNameIs>translate_ZNSt6vectorIPN7testing8TestCaseESaIS2_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS2_S4_EERKS2_wcstoul__is_normal_iteratorsa_data_ZNSt6vectorIPN7testing8TestInfoESaIS2_EE6insertEN9__gnu_cxx17__normal_iteratorIPS2_S4_EERKS2_index___mode_t_ZN7testing8internal18InitGoogleTestImplIcEEvPiPPT___cxa_bad_typeid_DestroyFLAGS_gtest_repeat__n1pair, std::_Rb_tree_const_iterator >_ZNSs13_S_copy_charsEPcN9__gnu_cxx17__normal_iteratorIPKcSsEES4_read_fd_ZN9__gnu_cxx17__normal_iteratorIPSsSt6vectorISsSaISsEEEpLEi_Destroysrc/gtest-all.cc~basic_stringbufFormatFileLocation_ZNSt6vectorIPcSaIS0_EE8_M_eraseEN9__gnu_cxx17__normal_iteratorIPS0_S2_EE_M_insert_equalconst_reverse_iteratorwchar_t_ZN9__gnu_cxx14__alloc_traitsISaIPN7testing11EnvironmentEEE7destroyERS4_PS3__ZNKSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE6rbeginEv_ZNK7testing7Message9GetStringEv_markers__assignable__copy_move_backwardOnEnvironmentsSetUpStart_ZN9__gnu_cxx14__alloc_traitsISaIPN7testing8internal29ParameterizedTestCaseInfoBaseEEE17_S_select_on_copyERKS5___alloc_traits >_ZN7testing8internal10scoped_ptrINS0_24InternalRunDeathTestFlagEEaSERKS3_iostatea_write_fd__pad1__pad2__pad3__copy_move_a__pad5a_filefieldssi_overrun_ZNK7testing8internal8FilePath28CreateDirectoriesRecursivelyEvRecordProperty_ZNK7testing8internal13DeathTestImpl7read_fdEv_M_get_Tp_allocatorgetwchar__destroy*>_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE7_M_rootEv_ZN9__gnu_cxx17__normal_iteratorIPPN7testing8internal29ParameterizedTestCaseInfoBaseESt6vectorIS4_SaIS4_EEEmIEi_ZNKSt6vectorIPN7testing17TestEventListenerESaIS2_EE4dataEv_ZNKSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE4rendEv_ZNKSt17_Rb_tree_iteratorIPKcEneERKS2_current_test_case_ZNKSt6vectorIN7testing12TestPropertyESaIS1_EE2atEj_ZN9__gnu_cxx3divExxkSizestdout_is_ttycopy_backward_ZNK9__gnu_cxx17__normal_iteratorIPKPN7testing17TestEventListenerESt6vectorIS3_SaIS3_EEEplEi_ZNK9__gnu_cxx17__normal_iteratorIPKPN7testing11EnvironmentESt6vectorIS3_SaIS3_EEE4baseEv_ZN7testing8internal24XmlUnitTestResultPrinter17OutputXmlTestInfoEPSoPKcRKNS_8TestInfoE_ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EE9push_backERKS2__ZNSt6vectorIN7testing14TestPartResultESaIS1_EE14_M_fill_insertEN9__gnu_cxx17__normal_iteratorIPS1_S3_EEjRKS1__ZNK7testing8UnitTest18ad_hoc_test_resultEvtotal_test_case_count_ZNKSt16reverse_iteratorIN9__gnu_cxx17__normal_iteratorIPPN7testing11EnvironmentESt6vectorIS4_SaIS4_EEEEEplEioperator<< __copy_move_backward_aoperator<< _ZN9__gnu_cxx13new_allocatorIN7testing14TestPartResultEE10deallocateEPS2_jcur_pattern_ZN7testing4TestaSERKS0__ZNSt6vectorIPN7testing8TestInfoESaIS2_EE2atEj_ZN7testing15AssertionResult13AppendMessageERKNS_7MessageEIsSubstringImpl >__copy_move_a2_ZN7testing32ScopedFakeTestPartResultReporter20ReportTestPartResultERKNS_14TestPartResultEMSG_DONTWAITiterator_traits_ZNSt3setIPKcSt4lessIS1_ESaIS1_EE11lower_boundERKS1__ZNSt13_Rb_tree_nodeISsE9_M_valptrEvkElidedFramesMarkerset_read_fdParseInternalRunDeathTestFlagstatus__ZN7testing8internal19TypedTestCasePState25VerifyRegisteredTestNamesEPKciS3__ZNSt6vectorIPcSaIS0_EE14_M_fill_insertEN9__gnu_cxx17__normal_iteratorIPS0_S2_EEjRKS0__ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE12_M_erase_auxESt23_Rb_tree_const_iteratorISsES7_GetMutableTestCase*DeathTest:*DeathTest/*_ZNKSs16find_last_not_ofEPKcj__osRelease_ZNK9__gnu_cxx17__normal_iteratorIPKcSsEmiEi_IO_write_base__distance_ZNSt3setISsSt4lessISsESaISsEE11upper_boundERKSs_ZNK9__gnu_cxx17__normal_iteratorIPPN7testing8TestCaseESt6vectorIS3_SaIS3_EEEptEvUniversalPrinter, std::allocator > >GoogleTestFailureException_ZN7testing8TestCase14UnshuffleTestsEvreason_ZN7testing8internal23GetLastErrnoDescriptionEv__miter_base__builtin_memcmp_ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EE6rbeginEvfront_ZN7testing8internal7PrintToEPKwPSowmemsetsetfillkTestcase_ZNKSt6vectorIN7testing8internal9TraceInfoESaIS2_EEixEj__copy_move_backward_a2FormatCompilerIndependentFileLocationpush_backtotal_shards_envsubstr_ZNKSt6vectorIN7testing14TestPartResultESaIS1_EE6rbeginEv_ZN9__gnu_cxx14__alloc_traitsISaIPKcEE17_S_select_on_copyERKS3__ZNKSt6vectorIN7testing14TestPartResultESaIS1_EEixEjincrement_death_test_count_ZNKSt6vectorIiSaIiEE5beginEv_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE13_Rb_tree_implIS5_Lb0EE13_M_initializeEv_ZN9__gnu_cxx14__alloc_traitsISaISt13_Rb_tree_nodeISsEEE10deallocateERS3_PS2_jst_ino_ZNKSt6vectorIiSaIiEE3endEvxml_element_S_terminal_ZNK9__gnu_cxx13new_allocatorISt13_Rb_tree_nodeIPKcEE7addressERS4_OsStackTraceGetter_Compare_ZN7testing8internal17StreamingListener16OnTestProgramEndERKNS_8UnitTestEstrtouliterator_traits_ZNKSs4findEPKcjmbstate_t_ZN7testing17TestEventListener9OnTestEndERKNS_8TestInfoEPrintToString_ZN9__gnu_cxx14__alloc_traitsISaIPN7testing11EnvironmentEEE8allocateERS4_jlast_death_test_message_~_Rb_treeStrCaseCmp_ZN7testing8internal35DefaultGlobalTestPartResultReporterC2EPNS0_12UnitTestImplETHREWPrintTestNameis_valid__ZN7testing8internal35DefaultGlobalTestPartResultReporterD0EvMSG_TRUNC_ZN7testing8internal13DeathTestImpl5AbortENS0_9DeathTest11AbortReasonEDefaultPrintTodelimiterIsDigit_ZNSt11char_traitsIcE7not_eofERKi__it__destroy_ZN7testing8internal15FloatingPointLEIdEENS_15AssertionResultEPKcS4_T_S5__ZNKSs12find_last_ofEPKcjj__u_quad_t_ZN9__gnu_cxx17__normal_iteratorIPPN7testing8TestInfoESt6vectorIS3_SaIS3_EEEppEiputwcTestPartResult__normal_iterator > >shuffle__ZN9__gnu_cxx17__normal_iteratorIPPN7testing8TestInfoESt6vectorIS3_SaIS3_EEEppEv_Vector_base >_M_is_leaked_ZN7testing8internal17StreamingListeneraSERKS1__ZNSt6vectorIPN7testing11EnvironmentESaIS2_EE6assignEjRKS2__ZNSbIwSt11char_traitsIwESaIwEE7replaceEjjPKwj_ZN7testing8internal20ShouldRunTestOnShardEiii_ZNK7testing8internal10scoped_ptrISsEptEvPrint_ZNKSbIwSt11char_traitsIwESaIwEE5rfindEPKwj_ZN9__gnu_cxx17__normal_iteratorIPPN7testing8TestCaseESt6vectorIS3_SaIS3_EEEppEioperator-*, std::vector > >__uninit_copyoperator<< reserved_names_SelfStart_ZNK9__gnu_cxx13new_allocatorISsE7addressERKSsThis program contains tests written using Google Test. You can use the following command line flags to control its behavior: Test Selection: @G--gtest_list_tests@D List the names of all tests instead of running them. The name of TEST(Foo, Bar) is "Foo.Bar". @G--gtest_filter=@YPOSTIVE_PATTERNS[@G-@YNEGATIVE_PATTERNS]@D Run only the tests whose name matches one of the positive patterns but none of the negative patterns. '?' matches any single character; '*' matches any substring; ':' separates two patterns. @G--gtest_also_run_disabled_tests@D Run all disabled tests too. Test Execution: @G--gtest_repeat=@Y[COUNT]@D Run the tests repeatedly; use a negative count to repeat forever. @G--gtest_shuffle@D Randomize tests' orders on every iteration. @G--gtest_random_seed=@Y[NUMBER]@D Random number seed to use for shuffling test orders (between 1 and 99999, or 0 to use a seed based on the current time). Test Output: @G--gtest_color=@Y(@Gyes@Y|@Gno@Y|@Gauto@Y)@D Enable/disable colored output. The default is @Gauto@D. -@G-gtest_print_time=0@D Don't print the elapsed time of each test. @G--gtest_output=xml@Y[@G:@YDIRECTORY_PATH@G/@Y|@G:@YFILE_PATH]@D Generate an XML report in the given directory or with the given file name. @YFILE_PATH@D defaults to @Gtest_details.xml@D. @G--gtest_stream_result_to=@YHOST@G:@YPORT@D Stream test results to the given server. Assertion Behavior: @G--gtest_death_test_style=@Y(@Gfast@Y|@Gthreadsafe@Y)@D Set the default death test style. @G--gtest_break_on_failure@D Turn assertion failures into debugger break-points. @G--gtest_throw_on_failure@D Turn assertion failures into C++ exceptions. @G--gtest_catch_exceptions=0@D Do not report exceptions as test failures. Instead, allow them to crash the program or throw a pop-up (on Windows). Except for @G--gtest_list_tests@D, you can alternatively set the corresponding environment variable of a flag (all letters in upper-case). For example, to disable colored text output, you can either specify @G--gtest_color=no@D or set the @GGTEST_COLOR@D environment variable to @Gno@D. For more information, please read the Google Test documentation at @Ghttp://code.google.com/p/googletest/@D. If you find a bug in Google Test (not one in your own code or tests), please report it to @G@D. BoolFromGTestEnv_ZNSt6vectorIPcSaIS0_EE15_M_erase_at_endEPS0__ZNKSbIwSt11char_traitsIwESaIwEE17find_first_not_ofEwjInteger__find_if<__gnu_cxx::__normal_iterator >, __gnu_cxx::__ops::_Iter_pred >strcasecmpst_ctim_ZNSt6vectorIN7testing12TestPropertyESaIS1_EE6assignEjRKS1__ZNSt6vectorIPN7testing8TestCaseESaIS2_EE4dataEvtuple_size >_ZNKSt6vectorIPcSaIS0_EE4backEv_Vector_base >_ZNKSt6vectorIN7testing14TestPartResultESaIS1_EE8capacityEv_M_leak_hardprefix_len_ZNKSs13find_first_ofERKSsj_ZN7testing8internal15FloatingPointLEIfEENS_15AssertionResultEPKcS4_T_S5__ZN7testing4Test5SetupEvGTestLogSeverity_ZN9__gnu_cxx14__alloc_traitsISaIN7testing12TestPropertyEEE17_S_select_on_copyERKS3__ZNSt6vectorIN7testing12TestPropertyESaIS1_EE14_M_fill_insertEN9__gnu_cxx17__normal_iteratorIPS1_S3_EEjRKS1__ZSt9__find_ifIN9__gnu_cxx17__normal_iteratorIPPN7testing8TestCaseESt6vectorIS4_SaIS4_EEEENS0_5__ops10_Iter_predINS2_8internal14TestCaseNameIsEEEET_SF_SF_T0_St26random_access_iterator_tag_vptr.TestCase_ZNK7testing8UnitTest21total_test_case_countEv_ZNKSt9_IdentityIPKcEclERKS1__ZNSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE8_M_eraseEN9__gnu_cxx17__normal_iteratorIPS3_S5_EES9__ZNSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE7reserveEj_ZN9__gnu_cxx17__normal_iteratorIPPN7testing17TestEventListenerESt6vectorIS3_SaIS3_EEEppEv_ZN9__gnu_cxx17__normal_iteratorIPcSsEppEitoupper_vptr.ThreadLocalValueHolderBase_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE12_M_rightmostEv Stack trace: _ZN9__gnu_cxx17__normal_iteratorIPcSsEppEv__normal_iterator, std::allocator > >_ZNK9__gnu_cxx17__normal_iteratorIPiSt6vectorIiSaIiEEEixEi__datCodePointToUtf8_ZNSbIwSt11char_traitsIwESaIwEE4_Rep26_M_set_length_and_sharableEj_ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EE14_M_fill_assignEjRKS2_test_namenot_bol_ZNSs3endEv_ZN9__gnu_cxx17__normal_iteratorIPKPN7testing17TestEventListenerESt6vectorIS3_SaIS3_EEEmIEi_ZNKSt6vectorIN7testing14TestPartResultESaIS1_EE8max_sizeEv_ZN7testing8internal12UnitTestImplD0EvIsRootDirectorymemcpyFloatingPointLE_ZN7testing8internal6RandomaSERKS1__ZN7testing8internal21ImplicitlyConvertibleIPKvS3_E6HelperEz_ZNKSt6vectorIN7testing12TestPropertyESaIS1_EE14_M_range_checkEj_ZNSbIwSt11char_traitsIwESaIwEE4_Rep15_M_set_sharableEvFlushInfoLog__s1construct_ZNSt3setISsSt4lessISsESaISsEE6insertESt23_Rb_tree_const_iteratorISsERKSsreverse_iterator<__gnu_cxx::__normal_iterator > > >_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE5eraseERKSsHasFailurewcsncpy_ZNKSt6vectorIN7testing12TestPropertyESaIS1_EE3endEv_ZN7testing8internal28ParseGoogleTestFlagsOnlyImplIcEEvPiPPT_back_ZNK7testing10TestResult6PassedEvcopy_ZN7testing8internal12UnitTestImpl21os_stack_trace_getterEv_S_construct_aux15pthread_mutex_tregex_tmbrtowcresultRandom~ParameterizedTestCaseInfoBase_ZNSt3setISsSt4lessISsESaISsEE5eraseERKSs_ZNK9__gnu_cxx13new_allocatorIPN7testing17TestEventListenerEE7addressERKS3__ZN7testing8internal12UnitTestImpl14RecordPropertyERKNS_12TestPropertyE__numeric_traits_integerfreeaddrinfo_M_limitoperator<< _ZNSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE4rendEv_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE5eraseESt17_Rb_tree_iteratorIS1_ES9__ZNK7testing8internal8FilePath12CreateFolderEv_ZNK7testing8internal10scoped_ptrINS0_16DeathTestFactoryEE3getEv_ZNSt6vectorISsSaISsEE3endEvkPathSeparator_ZN7testing12TestPropertyD2Evvfprintfiterator_traits, std::allocator >*>~Mutexisxdigitmatched_ZNSbIwSt11char_traitsIwESaIwEE4_Rep10_M_disposeERKS1__ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE10_S_maximumEPSt18_Rb_tree_node_basesi_fd_ZNSt6vectorISsSaISsEE4backEv_next_S_basefieldStringType__is_move_iterator_ZNSt6vectorIPN7testing8TestInfoESaIS2_EE3endEv__niter_base_ZNSt6vectorIPN7testing8TestCaseESaIS2_EE8_M_eraseEN9__gnu_cxx17__normal_iteratorIPS2_S4_EES8___uninitialized_copy_a_S_scientificerase_ZNK7testing8internal8FilePath15IsRootDirectoryEv_ZNKSt6vectorIN7testing14TestPartResultESaIS1_EE4rendEv_ZN7testing17TestEventListener11OnTestStartERKNS_8TestInfoEallocator, std::allocator > > >_ZNK7testing10TestResult15GetTestPropertyEi_ZN7testing32ScopedFakeTestPartResultReporterD0Ev_ZNSt6vectorIPN7testing8TestCaseESaIS2_EE6resizeEjS2_is_wide_stringstack_trace_depth_ZNK7testing8internal10scoped_ptrINS0_24InternalRunDeathTestFlagEEdeEvchar_type_ZN7testing4TestD0Evwctype_t_ZNKSs5rfindEPKcj_ZNSt6vectorISsSaISsEE14_M_fill_insertEN9__gnu_cxx17__normal_iteratorIPSsS1_EEjRKSs_ZNSt6vectorIiSaIiEE6insertEN9__gnu_cxx17__normal_iteratorIPiS1_EEjRKi_DestroyReinterpretBitsai_canonnameConfigureStreamingOutputalso_run_disabled_tests_ZN9__gnu_cxx17__normal_iteratorIPPN7testing8TestCaseESt6vectorIS3_SaIS3_EEEppEv_ZN7testing15AssertionResultlsISsEERS0_RKT__ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE12_M_erase_auxESt23_Rb_tree_const_iteratorISsESkipPrefix_ZN9__gnu_cxx17__normal_iteratorIPPcSt6vectorIS1_SaIS1_EEEppEi_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE14_M_upper_boundEPSt13_Rb_tree_nodeIS1_ESA_RKS1__ZNK9__gnu_cxx17__normal_iteratorIPPN7testing8internal29ParameterizedTestCaseInfoBaseESt6vectorIS4_SaIS4_EEEptEv_ZNSt12_Vector_baseIN7testing12TestPropertyESaIS1_EE11_M_allocateEjsaved_sigprof_actionoperator<< low_bits_IteratorR_ZNKSbIwSt11char_traitsIwESaIwEE8_M_limitEjj_ZNKSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE11__rb_verifyEv_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE5eraseESt17_Rb_tree_iteratorISsES7_successspawned__ZNSt13_Bit_iteratorppEi__sigchld_clock_ttear_down_tc__Vector_base >_ZNKSt5ctypeIcE13_M_widen_initEv__destroy_ZN7testing8internal12UnitTestImpl19PostFlagParsingInitEvmatchFLAGS_gtest_stack_trace_depth_ZNSt13_Bit_iteratorppEv_ZN7testing17TestEventListener20OnTestIterationStartERKNS_8UnitTestEikDeathTestStyleFlag_ZN7testing8internal18FormatFileLocationEPKci_ZN7testing15AssertionResultlsIA2_cEERS0_RKT__ZNKSt6vectorIPcSaIS0_EE4sizeEvcatch_exceptionsg_injected_test_argvs_ZNKSs4findEcj_M_get_insert_equal_pos_ZNSbIwSt11char_traitsIwESaIwEE12_S_empty_repEv_ZN7testing28FLAGS_gtest_stream_result_toEreverse_iterator<__gnu_cxx::__normal_iterator > > >_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE28_M_get_insert_hint_equal_posESt23_Rb_tree_const_iteratorIS1_ERKS1_PostFlagParsingInit_ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EE7reserveEj_ZNK7testing8internal12UnitTestImpl28internal_run_death_test_flagEv_ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EE8pop_backEv_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE5beginEv__positionqsortSocketWriter_ZNK9__gnu_cxx17__normal_iteratorIPN7testing14TestPartResultESt6vectorIS2_SaIS2_EEEplEi_ZNSbIwSt11char_traitsIwESaIwEE6insertEN9__gnu_cxx17__normal_iteratorIPwS2_EEw_ZNKSs4findERKSsj_ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EE5beginEvkAsIs_ZNK7testing8internal12UnitTestImpl6PassedEv_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE5eraseESt23_Rb_tree_const_iteratorIS1_ES9__ZNSt18_Rb_tree_node_base10_S_maximumEPS__ZNK7testing8UnitTest22failed_test_case_countEv_M_end_of_storage_ZN7testing8internal27PrettyUnitTestResultPrinter22OnEnvironmentsSetUpEndERKNS_8UnitTestE_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE17_M_insert_unique_ESt23_Rb_tree_const_iteratorISsERKSs__exchange_and_add_singleTearDownTestCase__x_copy_ZN9__gnu_cxx14__alloc_traitsISaIN7testing8internal9TraceInfoEEE7destroyERS4_PS3__ZN9__gnu_cxx14__alloc_traitsISaIN7testing12TestPropertyEEE8allocateERS3_j_Alloc_pad__uninitialized_copy_a*, std::basic_string >_ZN7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEE9CreateKeyEvgettervwscanfexponent_bitsputcharselected_Setwoperator<< _ZNK7testing8TestCase21reportable_test_countEvdeath_test_count__ZNKSt6vectorIN7testing14TestPartResultESaIS1_EE5frontEv_ZNKSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE4rendEv_M_headerinternal_run_death_test_SplitStringfind_last_of~TestEventListener__is_normal_iterator<__gnu_cxx::__normal_iterator > > >WideStringToUtf8_ZNKSt6vectorIPN7testing11EnvironmentESaIS2_EE5emptyEvuninitialized_copy<__gnu_cxx::__normal_iterator*, std::vector > >, std::basic_string*>__oldoperator- >_ZNSt6vectorIPN7testing8TestCaseESaIS2_EE5frontEvneedle_expr_ZN7testing8internal12UnitTestImpl18ConfigureXmlOutputEvunit_test__uninitialized_move_if_noexcept_a >reverse_iterator<__gnu_cxx::__normal_iterator > > >~set_ZN7testing22EmptyTestEventListener24OnEnvironmentsSetUpStartERKNS_8UnitTestE_Rb_tree_const_iteratorfabs_ZN7testing8internal14CapturedStream14ReadEntireFileEP8_IO_FILE_ZNSt3setISsSt4lessISsESaISsEE4swapERS3___vtt_parm_Destroy_M_ibeginactual_expression_ZNSt6vectorIPN7testing11EnvironmentESaIS2_EE5clearEv_ZNSt6vectorISsSaISsEE6assignEjRKSsGetRandomSeedFromFlag_ZNK9__gnu_cxx13new_allocatorIPN7testing8TestCaseEE7addressERS3__ZN7testing8internal17AppendUserMessageERKSsRKNS_7MessageEoperator!=*, std::vector > >__enable_if__throw_out_of_range_fmt_ZNKSt6vectorIPN7testing17TestEventListenerESaIS2_EE4sizeEvGetTestPartResultReporterForCurrentThread__copy_move_backward_a_ZN9__gnu_cxx17__normal_iteratorIPKSsSt6vectorISsSaISsEEEmIEiInternalRunDeathTestFlag_ZNKSbIwSt11char_traitsIwESaIwEE13find_first_ofERKS2_j_ZNK7testing8UnitTest21reportable_test_countEvF_OWNER_PGRP_ZNSt6vectorISsSaISsEE5eraseEN9__gnu_cxx17__normal_iteratorIPSsS1_EES5__ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS2_S4_EERKS2__ZN7testing14IsNotSubstringEPKcS1_S1_S1___off64_t_Iter_base<__gnu_cxx::__normal_iterator > >, false>__copy_move_a_ZNKSt6vectorIPN7testing8TestCaseESaIS2_EE12_M_check_lenEjPKc__gnu_cxx__typeEqFailureexpected_to_be_substringGetCapturedStringExitedUnsuccessfully_ZNK7testing8UnitTest20original_working_dirEvDeleteThreadLocalValue_ZN7testing8internal24HasNewFatalFailureHelperC2Evoperator+, std::allocator >_ZN7testing8internal38DefaultPerThreadTestPartResultReporterC2EPNS0_12UnitTestImplEoperator==_vptr.TestFactoryBase_M_current_ZNSs7replaceEjjjc_ZNSt6vectorIN7testing14TestPartResultESaIS1_EE5clearEv_Destroy_ZNKSs13find_first_ofEPKcjj_ZNSt6vectorIPN7testing8TestInfoESaIS2_EE8_M_eraseEN9__gnu_cxx17__normal_iteratorIPS2_S4_EES8__ZNK7testing8internal13FloatingPointIdE12AlmostEqualsERKS2__Iter_pred__copy_move_aoperator<< _ZNSt6vectorIiSaIiEE4rendEvtest_case_infos__ZNK9__gnu_cxx17__normal_iteratorIPN7testing14TestPartResultESt6vectorIS2_SaIS2_EEE4baseEv_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE11_M_put_nodeEPSt13_Rb_tree_nodeIS1_Earray___copy_move_backward_a2_sigsys_ZN9__gnu_cxx13new_allocatorIiE8allocateEjPKvreverse_iterator<__gnu_cxx::__normal_iterator > > >_S_create_Arg1_Arg2_ZNSt6vectorIPcSaIS0_EE6rbeginEv_ZNK7testing8internal13FloatingPointIfE12AlmostEqualsERKS2__Vector_base, std::allocator >, std::allocator, std::allocator > > >_ZNKSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE4rendEvattributesstack_trace_depth_MSG_FASTOPEN_Destroy_aux_ZN7testing8internal17StreamingListener10FormatBoolEbdefault__ZN7testing14KilledBySignalC2EiFullMatchreverse_iterator<__gnu_cxx::__normal_iterator > > >g_captured_stderrSetGlobalTestPartResultReporterpair, std::allocator > >, bool>PrintAsCharLiteralToabs_errorRegisterParameterizedTests_ZNKSt6vectorIPcSaIS0_EEixEjGetTestTypeId/home/user/projects/ascgit/ascgit003.dlt-daemon/build/gtest-1.7.0__copy_move_a2 >, __gnu_cxx::__normal_iterator > >test_indexValidateTestPropertyargs__M_insert_uniqueoperator<< UInt32RemoveExtensionkStreamResultToFlagkCurrentDirectoryStringname_template_ZNSt6vectorIiSaIiEE2atEjflag_ZN7testing8internal17StreamingListener18OnTestIterationEndERKNS_8UnitTestEiiterator_traits_ZNK9__gnu_cxx17__normal_iteratorIPiSt6vectorIiSaIiEEEdeEv_ZN7testing8internal13HasOneFailureEPKcS2_S2_RKNS_19TestPartResultArrayENS_14TestPartResult4TypeERKSs_ZNKSt6vectorISsSaISsEE12_M_check_lenEjPKcbool_constantkShuffleFlag_ZNKSt18_Bit_iterator_baseltERKS___uninit_copyCharType_ZNK7testing8TestCase30reportable_disabled_test_countEv_ZN9__gnu_cxx14__alloc_traitsISaISsEE7destroyERS1_PSsungetwcoperator- >__copy_move_achild_argcurrency_symbol_ZNK9__gnu_cxx17__normal_iteratorIPN7testing14TestPartResultESt6vectorIS2_SaIS2_EEEptEvgettimeofday_ZNKSt3setIPKcSt4lessIS1_ESaIS1_EE4findERKS1_locationShowWideCString__wchb_ZNSt12_Vector_baseIPN7testing17TestEventListenerESaIS2_EE11_M_allocateEj_ZNSbIwSt11char_traitsIwESaIwEE9_M_assignEPwjwoperator!= >_ZN7testing35FLAGS_gtest_also_run_disabled_testsEIsSubstringPred >_ZNKSt6vectorIiSaIiEE4dataEv_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE7_M_copyEPKSt13_Rb_tree_nodeISsEPS7__S_value~TestPropertyKeyIs_ZN9__gnu_cxx13new_allocatorISt13_Rb_tree_nodeISsEE9constructEPS2_RKS2___exchange_and_addbasic_string__normal_iterator, std::allocator >*, std::vector, std::allocator >, std::allocator, std::allocator > > > >_ZNSt6vectorIPcSaIS0_EE5beginEv_ZN9__gnu_cxx17__normal_iteratorIPSsSt6vectorISsSaISsEEEmIEinew_allocator_ZNK9__gnu_cxx13new_allocatorIiE7addressERi_Iter_base_M_range_initializefirst_is_TEST_ZN9__gnu_cxx17__normal_iteratorIPPN7testing11EnvironmentESt6vectorIS3_SaIS3_EEEppEi_M_checkglobal_test_part_result_reporter_mutex_AddTestInfo_ZNSt3setISsSt4lessISsESaISsEE5eraseESt23_Rb_tree_const_iteratorISsES5___size_ZNSt6vectorIPcSaIS0_EE5eraseEN9__gnu_cxx17__normal_iteratorIPS0_S2_EE_ZNSt10_Iter_baseIPN7testing14TestPartResultELb0EE7_S_baseES2__ZNK7testing10TestResult18HasNonfatalFailureEv_ZN9__gnu_cxx17__normal_iteratorIPKPN7testing8TestInfoESt6vectorIS3_SaIS3_EEEmmEi_ZNK9__gnu_cxx17__normal_iteratorIPPN7testing8TestInfoESt6vectorIS3_SaIS3_EEE4baseEv_ZNKSt18_Bit_iterator_basegeERKS__ZNKSs5emptyEv__builtin_unwind_resume_ZN7testing31FLAGS_gtest_death_test_use_forkEunary_function_ZNSt6vectorIPN7testing11EnvironmentESaIS2_EE6rbeginEvResult_ZNKSt6vectorIN7testing8internal9TraceInfoESaIS2_EE4backEv_ZNK7testing8TestCase10type_paramEva_current_test_infoAssumeRole_ZNSbIwSt11char_traitsIwESaIwEE13_S_copy_charsEPwN9__gnu_cxx17__normal_iteratorIPKwS2_EES8__ZNSt6vectorIN7testing12TestPropertyESaIS1_EE3endEv_ZNKSt3setIPKcSt4lessIS1_ESaIS1_EE11equal_rangeERKS1__ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE5eraseEPKSsS7___ostream_type__insert_left_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE7_S_leftEPSt18_Rb_tree_node_base_ZNKSt6vectorISsSaISsEE4dataEv_ZNSt6vectorIPN7testing8TestCaseESaIS2_EE3endEv_M_check_length_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE21_M_insert_equal_lowerERKS1__ZNKSt23_Rb_tree_const_iteratorISsEptEvdeath_test_use_fork__S_app_ZNSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE18_M_fill_initializeEjRKS3__ZNKSs4findEPKcjj_ZN7testing22EmptyTestEventListenerD2Ev_ZN9__gnu_cxx14__alloc_traitsISaIN7testing14TestPartResultEEE8allocateERS3_jMSG_OOB_ZN7testing8internal12UnitTestImpl9listenersEv__syscall_slong_t__alloc_traits, std::allocator > > >__alloc_traits >_ZN7testing8internal15UnitTestOptions17FilterMatchesTestERKSsS3__Identityp_sep_by_space_ZNKSt6vectorIN7testing12TestPropertyESaIS1_EE8capacityEvstart_timestampappendIsDirectoryTestDisabled_ZNKSt6vectorIPN7testing17TestEventListenerESaIS2_EE6rbeginEv_ZNK7testing8internal12AssertHelperaSERKNS_7MessageEsetlocale_ZNK7testing8UnitTest17failed_test_countEvbase_ZN7testing8internal17StreamingListenerD0Ev_ZNSt6vectorIPN7testing8TestInfoESaIS2_EE6assignEjRKS2_host_ZNKSt16reverse_iteratorIN9__gnu_cxx17__normal_iteratorIPPN7testing11EnvironmentESt6vectorIS4_SaIS4_EEEEEmiEi_Setprecisionfailed_ZN7testing8internal38DefaultPerThreadTestPartResultReporterD2Ev__copy_move_bbasic_streambufDefaultGlobalTestPartResultReporter_ZNKSt3setISsSt4lessISsESaISsEE6rbeginEv_IO_write_ptr_ZNSs6insertEN9__gnu_cxx17__normal_iteratorIPcSsEEcGTEST_WARNING_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE8_S_rightEPSt18_Rb_tree_node_base_ZN7testing8internal2RE12PartialMatchEPKcRKS1__S_in_ZN7testing17TestEventListener18OnTestIterationEndERKNS_8UnitTestEicopynew_allocator_mode_ZNKSt6vectorIN7testing12TestPropertyESaIS1_EE8max_sizeEvwcscasecmpGTestLog_ZN7testing12TestProperty8SetValueERKSs__socket_type_ZNSt9basic_iosIcSt11char_traitsIcEE4initEPSt15basic_streambufIcS1_E_ZN7testing8internal13FloatingPointIdE3MaxEvminpair, bool>SumOverTestCaseList_Vector_base >_ZNSt12_Vector_baseIPcSaIS0_EE12_Vector_impl12_M_swap_dataERS3__ZNK9__gnu_cxx17__normal_iteratorIPKcSsEptEv__ops_ZNK9__gnu_cxx13new_allocatorIPN7testing8TestCaseEE8max_sizeEvpair_ZN7testing8internal17StreamingListener9OnTestEndERKNS_8TestInfoE_ZN7testing8internal19FormatForComparisonIxxE6FormatERKx_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE11equal_rangeERKS1__ZN9__gnu_cxx14__alloc_traitsISaIN7testing8internal9TraceInfoEEE10deallocateERS4_PS3_j_Tp_alloc_typetest_detail.xml_Constructfull_regex_len_ZNSt6vectorIPN7testing8TestInfoESaIS2_EE5clearEv_ZNKSt3setISsSt4lessISsESaISsEE11lower_boundERKSsSOCK_RDM_ZNSt12_Vector_baseIiSaIiEE11_M_allocateEjCloneCString_ZNKSt3setIPKcSt4lessIS1_ESaIS1_EE4rendEv_ZNKSt6vectorIPcSaIS0_EE5beginEv_ZNKSt9basic_iosIcSt11char_traitsIcEE5widenEcoperator!=, std::allocator >_ZNK9__gnu_cxx17__normal_iteratorIPKPN7testing8TestCaseESt6vectorIS3_SaIS3_EEEplEiWrite_M_fill_initializekDefaultDeathTestStyle__normal_iterator > >waitpidtimezonetest_property_count_ZNK7testing10TestResult19test_property_countEv_ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EEaSERKS4__Vector_base >reverse_iterator<__gnu_cxx::__normal_iterator > > >an_outcome_S_ate_ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EE14_M_fill_assignEjRKS2_regexecmatches_filter__ZNKSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE11equal_rangeERKS1_expected_posoutcome__ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EEaSERKS7__ZNKSt6vectorISsSaISsEE3endEv_ZNKSs7compareEjjRKSsjj_ZN9__gnu_cxx13new_allocatorIiE9constructEPiRKi_ZNSt18_Bit_iterator_base12_M_bump_downEv_ZNSbIwSt11char_traitsIwESaIwEE14_M_replace_auxEjjjw_ZNKSt3setISsSt4lessISsESaISsEE5emptyEv_ZNSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE6assignEjRKS3__ZN7testing8internal23ScopedPrematureExitFileaSERKS1__Destroy_ZN7testing8internal6String13CStringEqualsEPKcS3__Rb_tree_iterator, std::allocator > >_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE21_M_get_Node_allocatorEvlast_in_range_ZN9__gnu_cxx17__normal_iteratorIPPN7testing8TestInfoESt6vectorIS3_SaIS3_EEEmmEi_ZNKSt6vectorIN7testing8internal9TraceInfoESaIS2_EE4sizeEv_ZNSt6vectorIPcSaIS0_EE2atEj__find_if<__gnu_cxx::__normal_iterator*, std::vector > >, __gnu_cxx::__ops::_Iter_equals_val > >_ZNSsaSEcUniversalPrinter, std::allocator > >_ZN9__gnu_cxx17__normal_iteratorIPPN7testing8TestInfoESt6vectorIS3_SaIS3_EEEmmEv_ZNSs7replaceEN9__gnu_cxx17__normal_iteratorIPcSsEES2_jc_ZN7testing8internal12UnitTestImpl12environmentsEv_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE4findERKS1_kSignBitMaska_value__uninit_copy*>countlong long unsigned int_ZN7testing8TestInfo15ClearTestResultEPS0__ZNSs6appendERKSs_ZN7testing8internal6String12FormatHexIntEiconstruct_vptr.TestEventListenerCaseInsensitiveCStringEquals_ZNK9__gnu_cxx13new_allocatorIPN7testing8TestCaseEE7addressERKS3_pair, std::allocator > >, bool>kDeathTestUseForkuppercase_ZNSbIwSt11char_traitsIwESaIwEEpLEwparameterized_test_registry__ZNKSbIwSt11char_traitsIwESaIwEE4rendEvconstructFormatTestCaseCount_ZNKSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE5frontEvFLAGS_gtest_stream_result_to_ZNKSt6vectorIPN7testing17TestEventListenerESaIS2_EE8capacityEv_ZN9__gnu_cxx13new_allocatorIN7testing14TestPartResultEE9constructEPS2_RKS2_MakeAndRegisterTestInfounsigned char_ZNK7testing8internal24InternalRunDeathTestFlag5indexEv_M_grab_ZNKSt23_Rb_tree_const_iteratorIPKcEdeEv_ZN7testing14IsNotSubstringEPKcS1_PKwS3_stack_traceoperator<< ClearResultregmatch_tFLAGS_gtest_death_test_style_ZNKSt6vectorIPN7testing8TestCaseESaIS2_EEixEj_ZN9__gnu_cxx17__normal_iteratorIPPN7testing17TestEventListenerESt6vectorIS3_SaIS3_EEEmmEi_ZN7testing8internal13ParseBoolFlagEPKcS2_Pb_ZN7testing8internal14ParseFlagValueEPKcS2_bUnitTestOptions_ZN9__gnu_cxx17__normal_iteratorIPPN7testing17TestEventListenerESt6vectorIS3_SaIS3_EEEmmEv_ZN9__gnu_cxx17__normal_iteratorIPcSsEmmEi__gnu_debug_ZN9__gnu_cxx17__normal_iteratorIPcSsEmmEvSOCK_DGRAM_ZNSt6vectorIN7testing14TestPartResultESaIS1_EE7reserveEj__is_char__outTypeIdHelper_ZNK7testing14TestPartResult9file_nameEv_ZN7testing8internal6String12CloneCStringEPKc_ZNKSt6vectorIPN7testing17TestEventListenerESaIS2_EE8max_sizeEv_ZNKSt6vectorIPN7testing11EnvironmentESaIS2_EE4backEv_ZN9__gnu_cxx13new_allocatorIPN7testing8TestCaseEE9constructEPS3_RKS3_test_info_list_fwide_ZN7testing8internal17StreamingListener5StartEv__iterator_category<__gnu_cxx::__normal_iterator > >_ZN7testing22EmptyTestEventListener18OnTestProgramStartERKNS_8UnitTestE_ZNKSt6vectorIPN7testing8TestCaseESaIS2_EE5beginEvoutput_file_for_each<__gnu_cxx::__normal_iterator >, void (*)(testing::TestEventListener*)>F_OWNER_GID_ZNKSt6vectorIiSaIiEEixEj_ZNK7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEE7pointerEv_ZN7testing8internal27OsStackTraceGetterInterface16UponLeavingGTestEv_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE5clearEv_ZNSs6insertEjPKcj_ZN7testing8internal27PrettyUnitTestResultPrinter9OnTestEndERKNS_8TestInfoE_ZNK7testing8UnitTest15start_timestampEv_ZNKSt12_Vector_baseIN7testing8internal9TraceInfoESaIS2_EE19_M_get_Tp_allocatorEvkChunkSize_ZNSt6vectorIPcSaIS0_EE3endEv~GoogleTestFailureExceptionHandleSehExceptionsInMethodIfSupportedSetDefaultResultPrinterwcsspn~_Iter_pred_ZNSt6vectorISsSaISsEE6resizeEjSsoperator<< _ZNKSt6vectorIPN7testing17TestEventListenerESaIS2_EE5frontEvGetAnsiColorCode__copy_move_backward_a2__alloc_traits, std::allocator > > > >_ZNSt6vectorIPN7testing11EnvironmentESaIS2_EE18_M_fill_initializeEjRKS2__Rb_tree_ZNSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE5clearEv_ZN7testing8internal6String17WideCStringEqualsEPKwS3_streamraw_seed_ZNK7testing8internal12UnitTestImpl15start_timestampEvmax_length_ZNK7testing14TestPartResult6passedEv_ZNK9__gnu_cxx13new_allocatorIN7testing8internal9TraceInfoEE8max_sizeEvFOpen_sifields_ZN7testing17TestEventListener27OnEnvironmentsTearDownStartERKNS_8UnitTestEInfinitycan_be_nullwctyperesults_GetTestProperty__copy_move_backward_a_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE13_M_clone_nodeEPKSt13_Rb_tree_nodeIS1_E_ZNKSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE4dataEv_Destroy_ZN9__gnu_cxx14__alloc_traitsISaISt13_Rb_tree_nodeISsEEE7destroyERS3_PS2_HandleSehExceptionsInMethodIfSupported_ZNKSt3setIPKcSt4lessIS1_ESaIS1_EE5countERKS1_TEST_name__xstat_ZN9__gnu_cxx17__normal_iteratorIPN7testing14TestPartResultESt6vectorIS2_SaIS2_EEEppEi_ZN7testing8internal24XmlUnitTestResultPrinter18OutputXmlAttributeEPSoRKSsS4_S4__ZNSs12_M_leak_hardEv_M_insert_unique__Ios_Iostate_ZN9__gnu_cxx17__normal_iteratorIPN7testing14TestPartResultESt6vectorIS2_SaIS2_EEEppEviterator_traits_ZN9__gnu_cxx13new_allocatorIN7testing12TestPropertyEE9constructEPS2_RKS2__ZNSsixEj_ZN7testing8internal6String10FormatByteEh_ZNSt6vectorIN7testing12TestPropertyESaIS1_EEaSERKS3__ZN9__gnu_cxx13new_allocatorIPN7testing8TestInfoEE8allocateEjPKvSetTestPartResultReporterForCurrentThreadOnEnvironmentsSetUpEnd_ZNSspLERKSsAddArguments >size_typeEnvironment_ZN9__gnu_cxx17__normal_iteratorIPPN7testing8TestCaseESt6vectorIS3_SaIS3_EEEmmEvfull_regex_srand_Destroy__delta_ZN9__gnu_cxx17__normal_iteratorIPPcSt6vectorIS1_SaIS1_EEEmmEifreeset_catch_exceptionspart_ZN9__gnu_cxx14__alloc_traitsISaIPcEE8max_sizeERKS2_TypedTestCasePState_ZN7testing8internal14GTestMutexLockaSERKS1__ZN9__gnu_cxx17__normal_iteratorIPPcSt6vectorIS1_SaIS1_EEEmmEv_ZN7testing8internal9DeathTest24last_death_test_message_EtypeCreateCodePointFromUtf16SurrogatePair_ZNSt13_Bit_iteratormmEiConfigureXmlOutputalso_run_disabled_tests__ZNSt13_Bit_iteratormmEv_ZNSt6vectorIPN7testing8TestCaseESaIS2_EE2atEj_ZNSt6vectorIPN7testing8TestCaseESaIS2_EEixEjinit_ZNKSt9basic_iosIcSt11char_traitsIcEE4fillEvother_ZNKSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE4findERKSs_ZNK7testing8internal13DeathTestImpl7spawnedEvOnTestProgramStart_Unwind_Resumeai_flagskDeathTestThrew_ZNSbIwSt11char_traitsIwESaIwEE7_M_copyEPwPKwj_ZN7testing11EnvironmentD0EvTearDown_Rb_tree_node_ZNSs4_Rep10_M_refdataEv__cxxabiv1_ZN7testing8internal17Int32FromEnvOrDieEPKci__pos_ZNSt6vectorIN7testing14TestPartResultESaIS1_EE3endEvtype_info_ZNK9__gnu_cxx17__normal_iteratorIPN7testing14TestPartResultESt6vectorIS2_SaIS2_EEEmiEi_ZNSt6vectorIPcSaIS0_EE4backEvwcsstrTesthost_name__ZNKSt6vectorIPN7testing11EnvironmentESaIS2_EE4sizeEvkReservedTestSuitesAttributes_ZN7testing7MessagelsERKSbIwSt11char_traitsIwESaIwEEpath_ZN7testing8internal16ForkingDeathTest4WaitEv_ZNKSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE5emptyEvClearAdHocTestResultst_size_ZN7testing8internal24XmlUnitTestResultPrinter18OnTestIterationEndERKNS_8UnitTestEi_ZNKSt6vectorIPN7testing8TestCaseESaIS2_EE4backEv_ZNK9__gnu_cxx13new_allocatorISt13_Rb_tree_nodeISsEE8max_sizeEv_ZNSt6vectorISsSaISsEE2atEj_ZNKSt13_Rb_tree_nodeIPKcE9_M_valptrEvFLAGS_gtest_death_test_use_fork_ZN7testing8internal12UnitTestImpl18death_test_factoryEv_Rb_tree_impl, std::allocator > >, false>_ZN7testing8UnitTest18GetMutableTestCaseEi_ZNKSs5c_strEvreverse_iterator<__gnu_cxx::__normal_iterator > > >exit_code_ZNSt12_Vector_baseIN7testing14TestPartResultESaIS1_EE11_M_allocateEjtest_properties__ZN7testing8TestCaseD0Ev_ZNKSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE7_M_rootEvfraction_bits_ZN7testing8internal10scoped_ptrINS0_17StreamingListener20AbstractSocketWriterEE5resetEPS3_testing_Result_ZN9__gnu_cxx17__normal_iteratorIPPN7testing8TestInfoESt6vectorIS3_SaIS3_EEEpLEitm_mday_ZNK9__gnu_cxx17__normal_iteratorIPN7testing12TestPropertyESt6vectorIS2_SaIS2_EEEdeEv__niter_baseAppend_ZNKSt12_Vector_baseIPcSaIS0_EE19_M_get_Tp_allocatorEv_Iter_predsi_addr_ZN9__gnu_cxx13new_allocatorIwE9constructEPwRKw_ZN7testing8internal2RE12PartialMatchERKSsRKS1_RunAllTests__miter_base_ZNKSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE3endEvGetTestCase_M_swap_data_ZNSt10_Iter_baseIPPN7testing11EnvironmentELb0EE7_S_baseES3_~basic_iostream_M_erase_at_enditerator_traitschild_pidallocator_ZNK9__gnu_cxx13new_allocatorIPcE7addressERS1__ZNK7testing8internal8FilePath11IsDirectoryEv_ZNKSt4lessISsEclERKSsS2_precisioncopy<__gnu_cxx::__normal_iterator >, __gnu_cxx::__normal_iterator > >MSG_NOSIGNALkOutputFlag_ZN7testing7MessagelsEPFRSoS1_E_ZNSt6vectorIN7testing14TestPartResultESaIS1_EE6assignEjRKS1_ad_hoc_test_result_ZNSt3setISsSt4lessISsESaISsEE5clearEvsingular_form_Iter_base_ZN7testing31TestPartResultReporterInterface20ReportTestPartResultERKNS_14TestPartResultEoperator<< _ZN9__gnu_cxx17__normal_iteratorIPPN7testing17TestEventListenerESt6vectorIS3_SaIS3_EEEpLEi__are_samebinary_function__resoperator<< kTestTotalShardsiterator_traits_ZN9__gnu_cxx17__normal_iteratorIPcSsEpLEibasic_streambuf >_ZNSt6vectorISsSaISsEE18_M_fill_initializeEjRKSs_call_addroriginal_working_dir_ZN7testing18TestEventListeners23SuppressEventForwardingEv_ZNSbIwSt11char_traitsIwESaIwEE9push_backEw_ZNKSs7compareERKSsExitSummary_ZNK9__gnu_cxx17__normal_iteratorIPKN7testing8internal9TraceInfoESt6vectorIS3_SaIS3_EEE4baseEvtimeval_ZNKSt6vectorIPN7testing8TestCaseESaIS2_EE4sizeEv_ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EEixEj_ZNSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE9push_backERKS3___normal_iterator > >~DeathTest_ZNSbIwSt11char_traitsIwESaIwEE6resizeEjwvector, std::allocator >, std::allocator, std::allocator > > >fopen_ZNSbIwSt11char_traitsIwESaIwEEaSEPKw_ZNSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE4dataEvdifference_typerebind_ZNSo5flushEvsetprecision_M_value_field_ZN9__gnu_cxx14__alloc_traitsISaIPcEE10deallocateERS2_PS1_j_S_badbit~OsStackTraceGetterInterfacecaller_frame__ZNSs7_M_dataEPcwcslenline_endtype_param__ZNSbIwSt11char_traitsIwESaIwEE10_S_compareEjj_ZNK7testing8internal12UnitTestImpl17failed_test_countEvenvironSOCK_CLOEXEClisteners_kInternalRunDeathTestFlag5div_tGetGlobalTestPartResultReporterScopedTracewcstoullboolalpha_ZN7testing8internal16ForkingDeathTest13set_child_pidEi_ZN7testing8internal13FloatingPointIfE24SignAndMagnitudeToBiasedERKj_Link_type_ZN7testing8internal14StackGrowsDownEv_ZSt9__find_ifIN9__gnu_cxx17__normal_iteratorIPKSsSt6vectorISsSaISsEEEENS0_5__ops16_Iter_equals_valIS2_EEET_SB_SB_T0_St26random_access_iterator_tag_ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EE6resizeEjS2_Normalizetest_propertywrite_fd_swapreverse_iterator, std::allocator > > >_ZNKSt6vectorIPN7testing8TestInfoESaIS2_EE12_M_check_lenEjPKcscientificCaptureStream_S_showposGTEST_TOTAL_SHARDS_ZN7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEE3setERKS5_predicate_ZNK9__gnu_cxx17__normal_iteratorIPKPN7testing11EnvironmentESt6vectorIS3_SaIS3_EEEdeEvpair, std::allocator > >, std::_Rb_tree_iterator, std::allocator > > >_ZNSs13_S_copy_charsEPcN9__gnu_cxx17__normal_iteratorIS_SsEES2__ZNKSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE5beginEv_ZNKSbIwSt11char_traitsIwESaIwEE7compareEPKw_ZNSbIwSt11char_traitsIwESaIwEE7replaceEjjPKwDelete_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE8_S_valueEPKSt18_Rb_tree_node_baselldiv_t_ZN7testing8internal30GetBoolAssertionFailureMessageERKNS_15AssertionResultEPKcS5_S5_~_Alloc_hider_M_create_nodedeath_test_count_ZN9__gnu_cxx17__normal_iteratorIPPN7testing8TestCaseESt6vectorIS3_SaIS3_EEEpLEi_ZNKSt6vectorIN7testing8internal9TraceInfoESaIS2_EE5frontEv_ZN7testing8UnitTest27parameterized_test_registryEv_ZNSbIwSt11char_traitsIwESaIwEE5eraseEjj_ZN9__gnu_cxx17__normal_iteratorIPPcSt6vectorIS1_SaIS1_EEEpLEiBiggestConvertible_ZNKSt6vectorIN7testing14TestPartResultESaIS1_EE4dataEv_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE3endEvMSG_TRYHARD_ZN7testing8internal18OsStackTraceGetter17CurrentStackTraceEii_IO_buf_basematches_filter_ZNSt13_Bit_iteratorpLEi__FILE__pthread_internal_slist~InternalRunDeathTestFlag_ZNKSt18_Bit_iterator_baseneERKS__ZNK9__gnu_cxx17__normal_iteratorIPN7testing12TestPropertyESt6vectorIS2_SaIS2_EEEixEifilename__ZNSt18_Bit_iterator_base10_M_bump_upEv_ZNSbIwSt11char_traitsIwESaIwEE5clearEv_S_endTestBody_ZNKSt6vectorIN7testing12TestPropertyESaIS1_EE4backEv_ZNK9__gnu_cxx17__normal_iteratorIPKSsSt6vectorISsSaISsEEEdeEvget_allocator_ZNKSt6vectorIN7testing14TestPartResultESaIS1_EE12_M_check_lenEjPKc_ZNSt14_Bit_reference4flipEv_ZN9__gnu_cxx13new_allocatorIPN7testing17TestEventListenerEE8allocateEjPKvcaptured_stream_ZNK9__gnu_cxx17__normal_iteratorIPKPN7testing11EnvironmentESt6vectorIS3_SaIS3_EEEixEikUnknownFile_ZNKSt12_Vector_baseISsSaISsEE19_M_get_Tp_allocatorEv_ZNSt6vectorIPcSaIS0_EEaSERKS2_test_indices_operator!=<__gnu_cxx::__normal_iterator > >_ZNK9__gnu_cxx13new_allocatorISsE7addressERSsPrintTo_ZN7testing8internal17StreamingListener16OnTestPartResultERKNS_14TestPartResultE_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE16_M_insert_uniqueERKS1__ZN9__gnu_cxx17__normal_iteratorIPPN7testing11EnvironmentESt6vectorIS3_SaIS3_EEEmmEikStdErrFileno_ZN7testing8internal13DeathTestImpl26ReadAndInterpretStatusByteEv~DefaultDeathTestFactory_ZN9__gnu_cxx17__normal_iteratorIPPN7testing11EnvironmentESt6vectorIS3_SaIS3_EEEmmEv_ZNKSt13_Rb_tree_nodeISsE9_M_valptrEv_ZN9__gnu_cxx13new_allocatorIPN7testing8internal29ParameterizedTestCaseInfoBaseEE7destroyEPS4_SuppressTestEventsIfInSubprocessAddArgument_ZN9__gnu_cxx17__normal_iteratorIPN7testing12TestPropertyESt6vectorIS2_SaIS2_EEEppEv_M_initializefastmap_accurate_ZNSbIwSt11char_traitsIwESaIwEE7_M_leakEvreverse_iterator<__gnu_cxx::__normal_iterator > > >_ZNSs7replaceEjjPKcjkBreakOnFailureFlaglong unsigned int__uninitialized_copy_a_ZN7testing8internal20SingleFailureCheckerC2EPKNS_19TestPartResultArrayENS_14TestPartResult4TypeERKSsword_list_ZN7testing8internal12UnitTestImpl41SetTestPartResultReporterForCurrentThreadEPNS_31TestPartResultReporterInterfaceEtm_isdst_ZNK9__gnu_cxx13new_allocatorISt13_Rb_tree_nodeIPKcEE8max_sizeEvint_n_sign_posn_ZNSt6vectorIPN7testing8TestInfoESaIS2_EE9push_backERKS2_operator!= >HasGoogleTestFlagPrefix_ZNKSt6vectorIPcSaIS0_EE2atEj_ZNKSbIwSt11char_traitsIwESaIwEE9_M_ibeginEv_ZNK7testing8internal10scoped_ptrISt18basic_stringstreamIcSt11char_traitsIcESaIcEEE3getEv_ZN7testing8internal16InDeathTestChildEv_ZNSt6vectorIN7testing12TestPropertyESaIS1_EE9push_backERKS1_TypeParam_ZNK9__gnu_cxx17__normal_iteratorIPKSsSt6vectorISsSaISsEEEixEiegptr_ZNKSt9type_infoeqERKS__ZNSt6vectorIPN7testing8TestCaseESaIS2_EE8_M_eraseEN9__gnu_cxx17__normal_iteratorIPS2_S4_EE__intptr_tClearTestPartResultsoperator==<__gnu_cxx::__normal_iterator > >CharFormatvfwprintf_ZN7testing17TestEventListener16OnTestPartResultERKNS_14TestPartResultE_ZNK7testing8UnitTest11GetTestCaseEi_ZN7testing8internal7g_argvsE_ZNSt14_Bit_referenceaSERKS_EscapeXmlText_ZNSbIwSt11char_traitsIwESaIwEE6insertEjjw_ZNKSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE11lower_boundERKSsstrchr_ZNKSt5ctypeIcE8do_widenEc__normal_iterator > >fixed_IO_read_base_ZNSt6vectorIN7testing14TestPartResultESaIS1_EE4rendEv__find_if<__gnu_cxx::__normal_iterator >, __gnu_cxx::__ops::_Iter_pred >_ZNKSt16reverse_iteratorIN9__gnu_cxx17__normal_iteratorIPPN7testing11EnvironmentESt6vectorIS4_SaIS4_EEEEEptEv_ZNSbIwSt11char_traitsIwESaIwEE4swapERS2__ZNKSt6vectorIPN7testing8TestInfoESaIS2_EE4rendEv_ZNKSt6vectorIiSaIiEE5emptyEvScopedFakeTestPartResultReporterkThrowOnFailureFlag__alloc_ZNSt11char_traitsIcE2ltERKcS2__ZNK7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE3getEvIsSubstringPred_M_insert_ZNK7testing8TestInfo13is_reportableEv_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE4rendEvsockaddr_ZN7testing8DoubleLEEPKcS1_dd__debug_ZN7testing8internal27PrettyUnitTestResultPrinter18OnTestProgramStartERKNS_8UnitTestE_ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EE4backEvfull_name_Swallow_assignwcstod_ZNK7testing14TestPartResult7messageEvreset_ZNK9__gnu_cxx13new_allocatorIPN7testing11EnvironmentEE8max_sizeEv_ZNSt6vectorIiSaIiEE4dataEv_ZNK9__gnu_cxx13new_allocatorIN7testing8internal9TraceInfoEE7addressERKS3___addressofuninitialized_copy_ZNKSt15basic_stringbufIcSt11char_traitsIcESaIcEE3strEv_ZN7testing8internal15UnitTestOptions13MatchesFilterERKSsPKcreg_syntax_t_ZNSt9basic_iosIcSt11char_traitsIcEE8setstateESt12_Ios_Iostate_ZNK7testing8internal8FilePath15RemoveExtensionEPKc_vptr.Test_ZN7testing8internal13FloatingPointIfE3MaxEvwmemcmp_ZNSbIwSt11char_traitsIwESaIwEE7replaceEN9__gnu_cxx17__normal_iteratorIPwS2_EES6_S5_S5_value_type_ZNSs15_M_replace_safeEjjPKcjsuffix_Const_Link_type_ZNSt3setIPKcSt4lessIS1_ESaIS1_EE5eraseERKS1_this_test_info_ZN7testing8internal13ExecDeathTest32GetArgvsForDeathTestChildProcessEvconstructInitGoogleTestImpl_ZNK9__gnu_cxx17__normal_iteratorIPPN7testing11EnvironmentESt6vectorIS3_SaIS3_EEEmiEi_ZN9__gnu_cxx13new_allocatorISt13_Rb_tree_nodeISsEE10deallocateEPS2_j_ZNSt6vectorIPN7testing8TestInfoESaIS2_EE8_M_eraseEN9__gnu_cxx17__normal_iteratorIPS2_S4_EEStreamableToStringskipwshas_owner_operator!=_Iter_base__is_move_iterator_ZNKSt6vectorIN7testing12TestPropertyESaIS1_EE4sizeEv__cxa_rethrow_ZN9__gnu_cxx14__alloc_traitsISaIPN7testing8TestInfoEEE7destroyERS4_PS3__ZNSt6vectorIN7testing14TestPartResultESaIS1_EEixEjsocket_ZN9__gnu_cxx17__normal_iteratorIPPN7testing8TestCaseESt6vectorIS3_SaIS3_EEEmmEi_ZNSt6vectorIPN7testing8TestCaseESaIS2_EE18_M_fill_initializeEjRKS2_property_ZNSbIwSt11char_traitsIwESaIwEE6appendEPKw~EmptyTestEventListener_ZN7testing11EnvironmentD2Ev_ZNK7testing10TestResult17GetTestPartResultEirebind_Iter_base_Rb_tree_colortv_sec_ZNSs7replaceEN9__gnu_cxx17__normal_iteratorIPcSsEES2_PKcjuse_color_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE5clearEv_ZN7testing8UnitTest17AddTestPartResultENS_14TestPartResult4TypeEPKciRKSsS6__ZNSt6vectorIPcSaIS0_EE7reserveEj_ZNSt12_Vector_baseIN7testing8internal9TraceInfoESaIS2_EE12_Vector_impl12_M_swap_dataERS5_test_properites_mutex__unused2IN_PROGRESSpid_t__are_same__destroyUniversalTersePrinterPrintCharsAsStringToIsSubstringImpl >GetStreamset_should_run_ZNKSt6vectorIN7testing14TestPartResultESaIS1_EE5beginEvbtowc_ZNKSt6vectorIPN7testing8TestInfoESaIS2_EE5frontEv_ZStplIcSt11char_traitsIcESaIcEESbIT_T0_T1_ERKS6_PKS3__M_node_counttm_ming_init_gtest_countMSG_WAITALLoperator<< _ZNSt6vectorIPN7testing8TestCaseESaIS2_EE5beginEv_ZN9__gnu_cxx14__alloc_traitsISaIN7testing12TestPropertyEEE8max_sizeERKS3__ZNSbIwSt11char_traitsIwESaIwEE6appendERKS2_jjbasic_stringstrcmp_ZNK7testing8internal12UnitTestImpl6FailedEv_ZN7testing8internal12UnitTestImpl24ConfigureStreamingOutputEv_ZNSt6vectorIiSaIiEE6rbeginEv_ZN7testing8internal30WriteToShardStatusFileIfNeededEv_ZN7testing8internal35HandleExceptionsInMethodIfSupportedINS0_15TestFactoryBaseEPNS_4TestEEET0_PT_MS6_FS5_vEPKc_ZN7testing8internal24HasNewFatalFailureHelper20ReportTestPartResultERKNS_14TestPartResultE_ZNK9__gnu_cxx13new_allocatorIPKcE8max_sizeEv_ZNSt3setIPKcSt4lessIS1_ESaIS1_EE5eraseESt23_Rb_tree_const_iteratorIS1_ES7_ai_addr_ZNK9__gnu_cxx13new_allocatorISsE8max_sizeEv__strThreadLocalfailuresfwscanf~AbstractSocketWriter_DestroyCreateFolder_ZN7testing9internal220PrintBytesInObjectToEPKhjPSoisspace_ZNKSs8_M_limitEjj_ZN7testing16AssertionFailureERKNS_7MessageEglobal_test_part_result_repoter__ZNSs4swapERSs_ZNKSt3setISsSt4lessISsESaISsEE4rendEv_ZNSt12_Vector_baseIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE17_M_create_storageEj__uninitialized_move_if_noexcept_a >_ZN7testing8internal12UnitTestImpl11FilterTestsENS1_18ReactionToShardingE_ZNK9__gnu_cxx17__normal_iteratorIPKN7testing8internal9TraceInfoESt6vectorIS3_SaIS3_EEEplEifailure_message_ZNKSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE14_M_lower_boundEPKSt13_Rb_tree_nodeIS1_ESB_RKS1__ZNSbIwSt11char_traitsIwESaIwEE7replaceEjjRKS2_jjStreamableToStringAlmostEqualsInDeathTestChild_ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EE6rbeginEvShouldShardoperator<< _ZNK9__gnu_cxx13new_allocatorIwE7addressERKw_ZNSt16reverse_iteratorIN9__gnu_cxx17__normal_iteratorIPPN7testing11EnvironmentESt6vectorIS4_SaIS4_EEEEEppEi_ZNKSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE8max_sizeEv_ZNKSt17_Rb_tree_iteratorISsEeqERKS0__ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE21_M_get_Node_allocatorEv_ZN7testing14InitGoogleTestEPiPPcfind_if<__gnu_cxx::__normal_iterator >, testing::internal::TestPropertyKeyIs>GetEnviron_ZNSt16reverse_iteratorIN9__gnu_cxx17__normal_iteratorIPPN7testing11EnvironmentESt6vectorIS4_SaIS4_EEEEEppEvdefault_val_ZNK7testing8TestInfo11value_paramEv_ZNSt3setISsSt4lessISsESaISsEE11lower_boundERKSs_ZNSs6insertEjRKSsjj_ZN7testing14InitGoogleTestEPiPPwCmpHelperSTRNEMSG_WAITFORONE_ZN7testing8internal9MutexBase6UnlockEv_ZNSbIwSt11char_traitsIwESaIwEE5eraseEN9__gnu_cxx17__normal_iteratorIPwS2_EEoperator&=pattern_DeathTestFactory_ZNSt3setIPKcSt4lessIS1_ESaIS1_EE5eraseESt23_Rb_tree_const_iteratorIS1_E_ZNK9__gnu_cxx13new_allocatorIPN7testing11EnvironmentEE7addressERS3__ZN7testing8internal24XmlUnitTestResultPrinterD2Ev_ZN7testing8internal18OsStackTraceGetterD0EvTestEventListeners_ZNSt11char_traitsIcE4moveEPcPKcj~AssertHelperkTestShardIndex_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE11upper_boundERKSs_ZN7testing8internal17StreamingListener12SocketWriter14MakeConnectionEv_ZNK7testing8internal13FloatingPointIfE13fraction_bitsEv_M_refcopysi_uid_ZNKSt15basic_streambufIcSt11char_traitsIcEE5pbaseEv_Destroy_ZN9__gnu_cxx13new_allocatorIPN7testing8TestInfoEE7destroyEPS3__ZN7testing8internal26GoogleTestFailureExceptionC2ERKNS_14TestPartResultEsa_mask_S_floatfieldsizetypeIsSubstringImpl_ZN7testing4TestC2Ev_ZNSs4_Rep10_M_refcopyEv~TestPartResultReporterInterfacepremature_exit_file_ZNKSbIwSt11char_traitsIwESaIwEE5rfindEPKwjj__errno_location_ZNSt11char_traitsIwE3eofEv_ZNKSt23_Rb_tree_const_iteratorIPKcEeqERKS2_new_allocator_ZNKSt6vectorIPcSaIS0_EE6rbeginEvoperator()_ZNKSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE12_M_rightmostEv_ZNK7testing10TestResult6FailedEv_M_get_insert_unique_pos_ZNSt12_Vector_baseIN7testing14TestPartResultESaIS1_EE19_M_get_Tp_allocatorEv_ZN7testing16AssertionFailureEvMSG_SYN__value_ZN9__gnu_cxx17__normal_iteratorIPN7testing14TestPartResultESt6vectorIS2_SaIS2_EEEmmEi_ZN7testing15AssertionResultlsINS_14TestPartResultEEERS0_RKT__ZN9__gnu_cxx14__alloc_traitsISaIN7testing8internal9TraceInfoEEE17_S_select_on_copyERKS4_success_scoped_ptr, std::allocator > >sigactiondirectory_ZN9__gnu_cxx17__normal_iteratorIPN7testing14TestPartResultESt6vectorIS2_SaIS2_EEEmmEveofbit_ZNSt3tr110tuple_sizeINS_5tupleIIEEEE5valueE_ZNSs4_Rep26_M_set_length_and_sharableEj_ZNSt6vectorIPcSaIS0_EE5eraseEN9__gnu_cxx17__normal_iteratorIPS0_S2_EES6_CaseInsensitiveWideCStringEquals_ZNKSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE8key_compEv_ZNSt13_Rb_tree_nodeIPKcE9_M_valptrEvgtest_trace_stack_should_ZNSt11char_traitsIwE4copyEPwPKwj_ZNSt10_Iter_baseIPPcLb0EE7_S_baseES1_printf_ZNSt12_Vector_baseISsSaISsEE12_Vector_impl12_M_swap_dataERS2__ZN7testing8internal13DeathTestImpl10set_statusEi__lentm_monrepeat__ZN7testing8TestCase22TestReportableDisabledEPKNS_8TestInfoEsi_pid__off_t_M_get_Node_allocator__resultdefault_global_test_part_result_reporter_factory_new_allocatorrebindDoubleNearPredFormatreverse_iterator<__gnu_cxx::__normal_iterator > > >_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE8_S_valueEPKSt13_Rb_tree_nodeIS1_Eflag_str_ZN9__gnu_cxx14__alloc_traitsISaISt13_Rb_tree_nodeISsEEE8allocateERS3_j_ZNSt6vectorIPN7testing11EnvironmentESaIS2_EE5eraseEN9__gnu_cxx17__normal_iteratorIPS2_S4_EES8__ZN7testing8internal24ParseGoogleTestFlagsOnlyEPiPPc_ZNKSt23_Rb_tree_const_iteratorISsE13_M_const_castEv_ZNKSt12_Vector_baseIPN7testing8TestCaseESaIS2_EE19_M_get_Tp_allocatorEv_M_rightmostIsSpace_ZNSolsEd_ZNSolsEf_ZNSolsEi_ZNSolsEj_ZN7testing8internal24ParseGoogleTestFlagsOnlyEPiPPwobj_bytesShuffleRange_syscall_ZNSolsEx_ZNSt6vectorIiSaIiEE8_M_eraseEN9__gnu_cxx17__normal_iteratorIPiS1_EEkBitCountmarker__wch_ZN7testing8internal12UnitTestImpl14UnshuffleTestsEvlistener_Arg__copy_move_boperator== >_ZdaPv__alloc_swap, std::allocator > >, true>StackGrowsDownFloatingPointUnionoperator++ignore_ZNSt10_Iter_baseIPPN7testing8TestCaseELb0EE7_S_baseES3_operator+=__glibc_reserved4__glibc_reserved5range_width~Test_ZNK7testing8TestCase18ad_hoc_test_resultEv__string_typePrintFailedTestsallocator, std::allocator > >trace_ZNKSt14_Bit_referenceltERKS__ZN7testing8internal27PrettyUnitTestResultPrinter15OnTestCaseStartERKNS_8TestCaseE_ZN7testing8internal21UniversalTersePrinterIPKwE5PrintES3_PSoInitGoogleTestImpl_ZN9__gnu_cxx17__normal_iteratorIPPN7testing8TestInfoESt6vectorIS3_SaIS3_EEEmIEibasic_string, std::allocator >flag_lenCapturedStreamwcsncat__lhs_ZN7testing8internal10scoped_ptrINS0_17StreamingListener20AbstractSocketWriterEEaSERKS4__ZNSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE8_M_eraseEN9__gnu_cxx17__normal_iteratorIPS3_S5_EEnew_allocatorsetstate_ZNSt6vectorIiSaIiEE14_M_fill_assignEjRKi_ZN7testing8internal9DeathTestC2Ev_ZN7testing8internal9Arguments4ArgvEv_ZNSbIwSt11char_traitsIwESaIwEE6resizeEj_ZNK7testing8TestCase11GetTestInfoEi_ZNSt11char_traitsIwE7compareEPKwS2_j_ZNK7testing8internal10scoped_ptrINS0_24InternalRunDeathTestFlagEEptEv_ZNSt6vectorIPN7testing11EnvironmentESaIS2_EE5frontEvoperator--Delete_ZNKSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE8max_sizeEv__elision_data_Containeroperator-=operator->FormatTimeInMillisAsSecondsShuffleoperator<< _ZN7testing8internal15GetTimeInMillisEvtm_year_ZNSt6vectorIN7testing12TestPropertyESaIS1_EE5frontEvLIVED_ZNSs16_S_construct_auxIPcEES0_T_S1_RKSaIcESt12__false_typereverse_iterator<__gnu_cxx::__normal_iterator, std::allocator > > >GetMutableTestInfo_ZNK9__gnu_cxx17__normal_iteratorIPcSsEdeEvMSG_DONTROUTE_ZNSt6vectorIN7testing14TestPartResultESaIS1_EE8pop_backEv~_Vector_impl_M_widen_initargsto_int_type_ZNKSt6vectorIN7testing12TestPropertyESaIS1_EE12_M_check_lenEjPKc_M_set_sharableenvironments_ZSt7nothrow_ZNSt12_Vector_baseIPN7testing11EnvironmentESaIS2_EE12_Vector_impl12_M_swap_dataERS5___iter_equals_val >unit_test__ZN9__gnu_cxx17__normal_iteratorIPPN7testing17TestEventListenerESt6vectorIS3_SaIS3_EEEmIEi_ZNKSbIwSt11char_traitsIwESaIwEE4dataEvallocateoperator<< ai_nextParseInt32Flagnew_value_ZN9__gnu_cxx17__normal_iteratorIPcSsEmIEi__is_move_iterator, std::allocator >*>__builtin_strstr_ZNSt6vectorISsSaISsEE9push_backERKSs_IO_write_end~TestCaseNameIs__uninitialized_copy_a_IO_save_basepptrtm_wday_ZN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE3setERKS3_kExponentBitMask_ZNSt11char_traitsIwE7not_eofERKj_ZNSt6vectorIN7testing14TestPartResultESaIS1_EE5frontEv_ZN7testing32ScopedFakeTestPartResultReporterC2ENS0_13InterceptModeEPNS_19TestPartResultArrayE__are_same_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE10_S_minimumEPKSt18_Rb_tree_node_base_ZN7testing8internal18g_init_gtest_countE_ZN7testing8UnitTest4implEva_typetest_part_resultlast_death_test_case__ZNSt12_Vector_baseISsSaISsEE13_M_deallocateEPSsj_ZNK9__gnu_cxx17__normal_iteratorIPcSsEixEi_ZN9__gnu_cxx13new_allocatorIPN7testing11EnvironmentEE7destroyEPS3__ZNKSt6vectorIPcSaIS0_EE8capacityEv_ZNSt11char_traitsIwE12to_char_typeERKjdistance__new_start_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE6_S_keyEPKSt18_Rb_tree_node_baseSetInjectableArgvsos_stack_trace_ZNK9__gnu_cxx17__normal_iteratorIPPN7testing8TestCaseESt6vectorIS3_SaIS3_EEE4baseEv_ZNK9__gnu_cxx13new_allocatorIPcE8max_sizeEvint_type~TestEventListeners_ZN7testing8internal17StreamingListener20AbstractSocketWriter15CloseConnectionEvMSG_PEEKremoveval1val2_ZN7testing8internal24XmlUnitTestResultPrinter29TestPropertiesAsXmlAttributesERKNS_10TestResultEsegmentn_sign_posnactual_message_ZNSt6vectorIPN7testing8TestCaseESaIS2_EE4backEva_key_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE8_S_rightEPKSt18_Rb_tree_node_base_ZNK7testing8internal8FilePath14RemoveFileNameEvwrite_fdrebind, std::allocator > > >captured_fd_ZNSt12_Vector_baseIN7testing12TestPropertyESaIS1_EE13_M_deallocateEPS1_jWait_ZN7testing17TestEventListener18OnTestProgramStartERKNS_8UnitTestEOnTestIterationStartuninitialized_copy*, std::basic_string*>_ZNKSt6vectorIPcSaIS0_EE8max_sizeEv_M_end_ZNSt6vectorIPcSaIS0_EE6insertEN9__gnu_cxx17__normal_iteratorIPS0_S2_EERKS0__ZNSt12_Vector_baseIN7testing8internal9TraceInfoESaIS2_EE19_M_get_Tp_allocatorEvFormatByteiterator_traits_ZNK9__gnu_cxx17__normal_iteratorIPPcSt6vectorIS1_SaIS1_EEE4baseEv_ZSt18_Rb_tree_incrementPKSt18_Rb_tree_node_basekDeathTestReturned_S_copy_chars_ZNKSt6vectorIPcSaIS0_EE5emptyEvtotal_test_count_ZNSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE14_M_fill_insertEN9__gnu_cxx17__normal_iteratorIPS3_S5_EEjRKS3_IsValidXmlCharacter_ZNSt6vectorIPN7testing8TestCaseESaIS2_EEaSERKS4__ZN7testing8internal21ImplicitlyConvertibleIPKvS3_E8MakeFromEv_ZNSt6vectorIN7testing14TestPartResultESaIS1_EE6insertEN9__gnu_cxx17__normal_iteratorIPS1_S3_EEjRKS1__ZN9__gnu_cxx17__normal_iteratorIPN7testing14TestPartResultESt6vectorIS2_SaIS2_EEEpLEiArguments__throw_logic_errorstreamable_ZNSs7_M_copyEPcPKcj_ZN7testing8internal10scoped_ptrISt18basic_stringstreamIcSt11char_traitsIcESaIcEEEaSERKS7_signum__Rb_tree_impl_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE10_S_minimumEPSt18_Rb_tree_node_baseColoredPrintfkColorFlag~Environmentsa_sigaction_ZN9__gnu_cxx17__normal_iteratorIPPN7testing8TestCaseESt6vectorIS3_SaIS3_EEEmIEi_IteratorL_ZN7testing8internal10scoped_ptrIKSsE5resetEPS2__ZN7testing8internal26ThreadLocalValueHolderBaseD2Ev_ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EE9push_backERKS2__ZNKSbIwSt11char_traitsIwESaIwEE13find_first_ofEwjstack_sizesi_stimeshard_testsGetNextRandomSeed__arg_ZN9__gnu_cxx17__normal_iteratorIPPcSt6vectorIS1_SaIS1_EEEmIEi_Iter_baseallocator >_ZN7testing10TestResultD2Ev_M_insert_equal_lowerreverse_iterator<__gnu_cxx::__normal_iterator, std::allocator > > >_ZNSt13_Bit_iteratormIEi_ZN7testing15AssertionResultlsIA11_cEERS0_RKT__ZNK7testing8UnitTest4implEv_ZN9__gnu_cxx13new_allocatorISsE9constructEPSsRKSs_ZNK7testing8internal10scoped_ptrINS0_17StreamingListener20AbstractSocketWriterEEdeEv_ZNSt11char_traitsIcE3eofEvfastmap_ZNKSt3setISsSt4lessISsESaISsEE11equal_rangeERKSspthread_key_tmmap_ZNK7testing8UnitTest30reportable_disabled_test_countEvgetaddrinfo_Iter_base, std::allocator >*, false>TestReportablefull_flag__niter_base*>_ZNKSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE5countERKSs_ZNSbIwSt11char_traitsIwESaIwEE6assignEPKwjst_uid__builtin_strrchrstr_valdefault_per_thread_test_part_result_reporter_thousands_sep_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE15_M_destroy_nodeEPSt13_Rb_tree_nodeISsE_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE15_M_insert_lowerEPSt18_Rb_tree_node_baseRKS1__ZN7testing8internal17TestEventRepeater7ReleaseEPNS_17TestEventListenerE_ZNK7testing8internal24InternalRunDeathTestFlag4lineEv__copy_move_bPrintByteSegmentInObjectTo_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE4rendEvInt32_ZNK7testing8internal2RE7patternEv_ZN9__gnu_cxx17__normal_iteratorIPN7testing12TestPropertyESt6vectorIS2_SaIS2_EEEmmEv_ZNSt6vectorISsSaISsEED2Ev_ZNSs7replaceEN9__gnu_cxx17__normal_iteratorIPcSsEES2_PKccopya_test_case_name_ZNSbIwSt11char_traitsIwESaIwEE13_S_copy_charsEPwPKwS5___copy_move_bEscapeXmlAttribute_ForwardIterator_ZNK9__gnu_cxx17__normal_iteratorIPKPN7testing17TestEventListenerESt6vectorIS3_SaIS3_EEE4baseEv_ZNSt6vectorIN7testing12TestPropertyESaIS1_EE5eraseEN9__gnu_cxx17__normal_iteratorIPS1_S3_EE_Bit_reference_ZN7testing8internal24XmlUnitTestResultPrinteraSERKS1_gtest_trace_stack_ZNSt8ios_base4setfESt13_Ios_Fmtflags_ZN7testing8internal12UnitTestImpl20ClearAdHocTestResultEv_ZN7testing8internal15NoExecDeathTestD2Evwords_ZNK7testing8internal10scoped_ptrINS0_16DeathTestFactoryEEdeEvstart_timestamp__ZNKSt17_Rb_tree_iteratorISsEdeEv_ZNKSs7compareEjjPKcj_ZNK7testing8UnitTest6PassedEv_Destroy_aux_ZNKSt6vectorIPN7testing17TestEventListenerESaIS2_EE5beginEvcopy_backward_ZNSt12_Vector_baseIPN7testing8TestInfoESaIS2_EE11_M_allocateEjdestroy_ZNSs6insertEjPKc_ZN7testing8internal10scoped_ptrINS0_16DeathTestFactoryEE5resetEPS2__ZNKSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE6rbeginEv_ZN7testing8internal17StreamingListener20OnTestIterationStartERKNS_8UnitTestEig_help_flagFlagToEnvVar_ZN9__gnu_cxx17__normal_iteratorIPN7testing12TestPropertyESt6vectorIS2_SaIS2_EEEppEia_file_name_ZNKSt6vectorIPN7testing8TestCaseESaIS2_EE5emptyEvwidenF_OWNER_TIDnonfatally_failed_ZN7testing8internal19UniversalPrintArrayEPKcjPSoReactionToSharding__quad_tenable_ZN9__gnu_cxx13new_allocatorIPN7testing8TestInfoEE10deallocateEPS3_j_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE14_M_upper_boundEPSt13_Rb_tree_nodeISsES8_RKSs_ZNSt3setIPKcSt4lessIS1_ESaIS1_EEaSERKS5_file_stat_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE8_M_beginEvgai_strerror__new_finishcopy_backwardtest_case_to_run_countFLAGS_gtest_show_internal_stack_framesnew_allocator_ZNSt6vectorIPN7testing8TestCaseESaIS2_EE6rbeginEvgtest_flag_saver__ZNSt6vectorISsSaISsEE7reserveEjoperator<< kPathSeparatorString_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE8_M_eraseEPSt13_Rb_tree_nodeISsEOnTestEndbitsRemoveTrailingPathSeparator~ScopedTracereverse_iteratoris_attribute_ZNKSt6vectorIiSaIiEE4rendEv_ZN9__gnu_cxx13new_allocatorISt13_Rb_tree_nodeISsEE7destroyEPS2__ZNKSt6vectorIPcSaIS0_EE12_M_check_lenEjPKcdistance__normal_iterator > >wcsncmp_ZNKSt18_Bit_iterator_baseleERKS__ZN9__gnu_cxx14__alloc_traitsISaIN7testing14TestPartResultEEE10deallocateERS3_PS2_j_ZNK7testing8internal8FilePath7IsEmptyEv__normal_iterator > >_ZNK9__gnu_cxx17__normal_iteratorIPPcSt6vectorIS1_SaIS1_EEEdeEv_ZNSt6vectorIPN7testing8TestInfoESaIS2_EE5frontEv_M_right_ZNKSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE4findERKS1___copy_move_a2_ZNK7testing8internal8FilePath27RemoveTrailingPathSeparatorEvbase_name_M_get_insert_hint_unique_pos_ZN7testing8internal15NoExecDeathTestD0Ev_ZN7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEED2Evtowctrans_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE8_M_beginEv_ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EE8_M_eraseEN9__gnu_cxx17__normal_iteratorIPS2_S4_EE_ZNSs2atEj__uninitialized_copy_afilenoRunTearDownTestCase_ZN7testing17TestEventListener13OnTestCaseEndERKNS_8TestCaseE_ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EE4swapERS4__ZN7testing8internal11CmpHelperLEEPKcS2_xxcharoperator- >_S_refcount__digits_ZNKSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE21_M_get_Node_allocatorEv__normal_iterator > >_ZNSbIwSt11char_traitsIwESaIwEE7replaceEN9__gnu_cxx17__normal_iteratorIPwS2_EES6_PKwj__is_normal_iteratorfixture_class_id_ZN7testing8internal27PrettyUnitTestResultPrinter27OnEnvironmentsTearDownStartERKNS_8UnitTestE_ZNSt6vectorIPN7testing8TestCaseESaIS2_EE5eraseEN9__gnu_cxx17__normal_iteratorIPS2_S4_EEvswprintf_Value_ZNSs4_Rep10_M_destroyERKSaIcE_ZN7testing4Test8TestBodyEvUniversalPrinterdetailexpr1expr2_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE28_M_get_insert_hint_equal_posESt23_Rb_tree_const_iteratorISsERKSs__uninit_copy_ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EE15_M_erase_at_endEPS2___are_samefixture_class_id__ZN7testing28FLAGS_gtest_break_on_failureEFLAGS_gtest_print_timeType_IsMove_ZN7testing8internal29PrintFullTestCommentIfPresentERKNS_8TestInfoEoperator<< __copy_move_backward_a__is_normal_iterator_ZNKSt6vectorIN7testing12TestPropertyESaIS1_EEixEjtest_info_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE23_M_get_insert_equal_posERKSs_ZNSt6vectorIiSaIiEE3endEvMutexBase_ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EE6resizeEjS2__ZN7testing14IsNotSubstringEPKcS1_RKSsS3_tv_usec_ZNKSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE3endEvHelpermemmoveFindLastPathSeparatorpair, std::_Rb_tree_iterator >diff_ZN9__gnu_cxx14__alloc_traitsISaIPN7testing11EnvironmentEEE10deallocateERS4_PS3_j_ZNSbIwSt11char_traitsIwESaIwEE4_Rep8_M_cloneERKS1_j_ZNSt6vectorIPN7testing8TestInfoESaIS2_EE4rendEvCOLOR_DEFAULT_ZNK7testing8internal12UnitTestImpl21reportable_test_countEvto_char_type_ZN9__gnu_cxx13new_allocatorIPN7testing8TestCaseEE7destroyEPS3_length_ZN7testing8internal13CaptureStderrEvwide_c_str_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE16_M_insert_equal_ESt23_Rb_tree_const_iteratorISsERKSs_ZN7testing8internal6String32CaseInsensitiveWideCStringEqualsEPKwS3_operator<<_M_set_leaked_ZNSt6vectorIiSaIiEE15_M_erase_at_endEPi_ZN7testing8internal11CmpHelperGTEPKcS2_xx_M_clonesigset_t_ZNK7testing14TestPartResult11line_numberEvcapacityoperator()<__gnu_cxx::__normal_iterator*, std::vector > > >_ZN7testing8internal26GoogleTestFailureExceptionD0Ev_ZNK9__gnu_cxx17__normal_iteratorIPKN7testing8internal9TraceInfoESt6vectorIS3_SaIS3_EEEmiEi_ZN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE11ValueHolderD2Evsetf_ZN7testing8TestCase19RunTearDownTestCaseEvFileOrDirectoryExists_ZNSbIwSt11char_traitsIwESaIwEE6appendEjw_ZN7testing8internal17TestEventRepeater11OnTestStartERKNS_8TestInfoEthis_fixture_id_ZNK9__gnu_cxx17__normal_iteratorIPKN7testing14TestPartResultESt6vectorIS2_SaIS2_EEEdeEv_ZNKSbIwSt11char_traitsIwESaIwEE11_M_disjunctEPKwsetwhas_tests_to_run_ZNK7testing8internal8FilePath21FindLastPathSeparatorEvsigemptyset_ZNSspLEPKcoperator==_ZNKSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE6_M_endEv_ZNSt16reverse_iteratorIN9__gnu_cxx17__normal_iteratorIPPN7testing11EnvironmentESt6vectorIS4_SaIS4_EEEEEmmEi_ZN9__gnu_cxx17__normal_iteratorIPPN7testing11EnvironmentESt6vectorIS3_SaIS3_EEEmIEiis_nan_ZNKSt12_Vector_baseIiSaIiEE19_M_get_Tp_allocatorEvvalue_compparent_ZN9__gnu_cxx17__normal_iteratorIPN7testing12TestPropertyESt6vectorIS2_SaIS2_EEEpLEi__first_ZN7testing24ValidateTestPropertyNameERKSsRKSt6vectorISsSaISsEECOLOR_RED__copy_move_backward_a2ExecDeathTestoperator<< _ZN7testing8internal17TestEventRepeater22set_forwarding_enabledEb_ZN7testing8internal13ExecDeathTestD2Ev__tmpkRepeatFlag_ZN7testing8internal12UnitTestImplD2Ev_ZNKSs6substrEjjhaystack_ZN7testing8internal12UnitTestImpl19current_test_resultEvkey_type_M_rootExtractSummarymbsrtowcsDefinedTestIter_S_beg_ZN7testing8internal24XmlUnitTestResultPrinter16PrintXmlUnitTestEPSoRKNS_8UnitTestE_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE21_M_insert_equal_lowerERKSsoperator>=number_ZNK7testing8internal12UnitTestImpl22failed_test_case_countEvvalue_str_ZNKSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE11__rb_verifyEvOtherOperand_ZN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE9CreateKeyEv_ZN7testing8internal13PrintStringToERKSsPSo_ZNKSt6vectorIPN7testing8TestInfoESaIS2_EE4dataEvWideCStringEquals_ZNSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE5frontEvkAlsoRunDisabledTestsFlagbasic_ostream_ZN9__gnu_cxx14__alloc_traitsISaISsEE8allocateERS1_j~UnitTestImpl_ZN9__gnu_cxx17__normal_iteratorIPiSt6vectorIiSaIiEEEppEi_S_construct_ZNSt10_Iter_baseIPiLb0EE7_S_baseES0_listeners_ZNK9__gnu_cxx17__normal_iteratorIPKN7testing14TestPartResultESt6vectorIS2_SaIS2_EEEixEi_ZN9__gnu_cxx17__normal_iteratorIPiSt6vectorIiSaIiEEEppEv_ZN7testing8internal11CmpHelperEQEPKcS2_xx_ZNSt6vectorISsSaISsEE5clearEv_ZNKSt3setIPKcSt4lessIS1_ESaIS1_EE11lower_boundERKS1__ZNSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE6rbeginEv_ZN7testing8internal29ParameterizedTestCaseRegistryD2Ev_ZNK9__gnu_cxx17__normal_iteratorIPKPN7testing8TestInfoESt6vectorIS3_SaIS3_EEEixEi__pid_tAbortReason_ConstructkReservedTestCaseAttributes_ZNK7testing8internal10scoped_ptrIKSsEptEv_ZNKSt6vectorISsSaISsEE4backEvint_frac_digits_ZNSt12_Vector_baseIPcSaIS0_EE11_M_allocateEj_ZN7testing8internal16GetAnsiColorCodeENS0_10GTestColorE_ZN9__gnu_cxx17__normal_iteratorIPPN7testing8internal29ParameterizedTestCaseInfoBaseESt6vectorIS4_SaIS4_EEEppEi_ZNSbIwSt11char_traitsIwESaIwEE7replaceEN9__gnu_cxx17__normal_iteratorIPwS2_EES6_PKw_ZNKSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE5emptyEv_ZNKSt17_Rb_tree_iteratorIPKcEptEv_ZN9__gnu_cxx17__normal_iteratorIPPN7testing8internal29ParameterizedTestCaseInfoBaseESt6vectorIS4_SaIS4_EEEppEv_ZNSt20__uninitialized_copyILb0EE13__uninit_copyIPN7testing14TestPartResultES4_EET0_T_S6_S5___is_normal_iterator_ZNK7testing8internal10scoped_ptrISt18basic_stringstreamIcSt11char_traitsIcESaIcEEEdeEv__copy_move_b_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE5eraseERKS1_vector >PrintCharAndCodeTo_ZNKSt6vectorIPN7testing11EnvironmentESaIS2_EE3endEv_ZN9__gnu_cxx13new_allocatorIcE7destroyEPcs1_expressionOutputXmlTestInfo_ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EE5clearEv_ZNSt8ios_base9precisionEi_ZN7testing8internal13DeathTestImplD0Ev_ZN7testing8internal19UniversalPrintArrayEPKwjPSo_ZNSt6vectorIN7testing14TestPartResultESaIS1_EE4dataEv__uninitialized_move_if_noexcept_a >_M_iend_ZNK7testing8internal10scoped_ptrINS0_24InternalRunDeathTestFlagEE3getEvTearDownEnvironmentkDeathTestCaseFiltersi_tidnewline_anchorst_rdev__sigaction_handler_S_empty_rep_storage__copy_move_a2_ZN7testing8UnitTest3RunEviterator_traitsg_argvs_ZN9__gnu_cxx13new_allocatorIPcE7destroyEPS1__ZNSs6assignEPKcExecDeathTestChildMainlocaltime_ZNKSt6vectorIPN7testing11EnvironmentESaIS2_EE8capacityEv_ZNKSbIwSt11char_traitsIwESaIwEE7_M_dataEv_ZN7testing8internal14DeathTestAbortERKSs_ZN7testing8internal14CmpHelperSTRNEEPKcS2_S2_S2_value_param___pfnStreamableToStringold_reporter__ZNSs6resizeEjcTimeInMillis_ZN7testing32ScopedFakeTestPartResultReporterD2Ev_DestroykMaxUlpsmemcmp_ZN7testing8internal18PrintCharAndCodeToIhhEEvT0_PSoforwarding_enabled__M_check_len__is_normal_iterator_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE11lower_boundERKS1___rb_verify_ZN7testing28FLAGS_gtest_throw_on_failureE_S_bin~ScopedFakeTestPartResultReporterint_n_sep_by_space_ZNSt12_Destroy_auxILb0EE9__destroyIPN7testing8internal9TraceInfoEEEvT_S6__ZNKSt6vectorIPN7testing8TestCaseESaIS2_EE2atEj_IO_marker_ZNKSt6vectorIPN7testing11EnvironmentESaIS2_EE8max_sizeEv_ZNK7testing14ExitedWithCodeclEi_ZNK9__gnu_cxx17__normal_iteratorIPPN7testing11EnvironmentESt6vectorIS3_SaIS3_EEEdeEvtest_case_indices__ZN7testing8internal11g_help_flagE_FacetDeathTestOutcome_ZN7testing8internal10scoped_ptrISt18basic_stringstreamIcSt11char_traitsIcESaIcEEE5resetEPS6_print_time__ZNSt6vectorIN7testing14TestPartResultESaIS1_EE18_M_fill_initializeEjRKS1__ZNKSt6vectorIN7testing8internal9TraceInfoESaIS2_EE5beginEv_ZNSs6appendERKSsjjIsNotContainer_ZN7testing8internal10ParseInt32ERKNS_7MessageEPKcPiAssertHelperDataFLAGS_gtest_break_on_failure_Destroy_ZNK9__gnu_cxx13new_allocatorIPN7testing8internal29ParameterizedTestCaseInfoBaseEE7addressERS4__ZNSt12_Vector_baseIPN7testing17TestEventListenerESaIS2_EE12_Vector_impl12_M_swap_dataERS5_re_nsubGetAbsolutePathToOutputFilehas_new_fatal_failure_INTERCEPT_ONLY_CURRENT_THREADiterator_traits_ZNKSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE11lower_boundERKS1__ZNK9__gnu_cxx17__normal_iteratorIPPN7testing17TestEventListenerESt6vectorIS3_SaIS3_EEEdeEvDefaultPerThreadTestPartResultReporter_ZNSt6vectorIPN7testing8TestCaseESaIS2_EE4swapERS4_bytes_last_read_BI1_BI2_ZNKSt12_Vector_baseIN7testing14TestPartResultESaIS1_EE19_M_get_Tp_allocatorEvptr__ZN7testing8UnitTest9listenersEv_ZNK9__gnu_cxx17__normal_iteratorIPPN7testing11EnvironmentESt6vectorIS3_SaIS3_EEE4baseEvai_socktype__is_move_iterator_ZN9__gnu_cxx17__normal_iteratorIPKPN7testing11EnvironmentESt6vectorIS3_SaIS3_EEEppEiPrintFullTestCommentIfPresentwctrans_S_truncscoped_ptr, std::allocator > >_ZN9__gnu_cxx17__normal_iteratorIPKPN7testing11EnvironmentESt6vectorIS3_SaIS3_EEEppEv_ZNKSs7compareEPKc__pad4_ZNKSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE5beginEvset_elapsed_time_ZNK9__gnu_cxx17__normal_iteratorIPPN7testing11EnvironmentESt6vectorIS3_SaIS3_EEEixEi_S_ios_iostate_end_ZN7testing8internal17GetCapturedStderrEvFLAGS_gtest_coloroperator<< ~new_allocator~ThreadLocal_ZN7testing8internal8FilePath22GenerateUniqueFileNameERKS1_S3_PKcwidth_ZNSbIwSt11char_traitsIwESaIwEE4_Rep12_S_empty_repEvreverse_iterator<__gnu_cxx::__normal_iterator > > >_ZN9__gnu_cxx13new_allocatorIwE7destroyEPw_ZNKSt6vectorISsSaISsEE4sizeEv__uninitialized_move_if_noexcept_a >_ZNKSt12_Vector_baseIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE13get_allocatorEvoperator<< strtoll~UnitTestReadReportFailureInUnknownLocation_ZN7testing8internal12UnitTestImpl28CurrentOsStackTraceExceptTopEi__baseInt32FromGTestEnv_ZNK9__gnu_cxx17__normal_iteratorIPKPN7testing8TestCaseESt6vectorIS3_SaIS3_EEEdeEv__is_move_iterator<__gnu_cxx::__normal_iterator > > >user_msgerrnum_ZNK9__gnu_cxx17__normal_iteratorIPPN7testing17TestEventListenerESt6vectorIS3_SaIS3_EEEixEi__copy_move_backward_a2emptyinstance_ZN7testing8internal29ParameterizedTestCaseRegistryaSERKS1_val1_ss__copy_move_b__end_ZN9__gnu_cxx14__alloc_traitsISaIPKcEE10deallocateERS3_PS2_jobject_ZN7testing8internal14CapturedStream11GetFileSizeEP8_IO_FILE_ZN7testing18FLAGS_gtest_repeatE_ZNK9__gnu_cxx17__normal_iteratorIPPN7testing8internal29ParameterizedTestCaseInfoBaseESt6vectorIS4_SaIS4_EEEdeEv__mbstate_t_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE10_S_maximumEPKSt18_Rb_tree_node_baseDeleteSelf___normal_iterator > >_ZNSbIwSt11char_traitsIwESaIwEE7replaceEN9__gnu_cxx17__normal_iteratorIPwS2_EES6_S6_S6_tz_minuteswestkDefaultOutputFile_M_valptr_ZNSt6vectorIN7testing12TestPropertyESaIS1_EE18_M_fill_initializeEjRKS1__ZN7testing8internal17TestEventRepeaterD0Ev_ZNKSt23_Rb_tree_const_iteratorIPKcE13_M_const_castEv_ZNSt16reverse_iteratorIN9__gnu_cxx17__normal_iteratorIPPN7testing11EnvironmentESt6vectorIS4_SaIS4_EEEEEpLEitype_param_S_internal_ZN7testing8internal10scoped_ptrISsE7releaseEv_ZNK9__gnu_cxx17__normal_iteratorIPN7testing8internal9TraceInfoESt6vectorIS3_SaIS3_EEEdeEvconst_referenceOnEnvironmentsTearDownStart__uninit_copy_ZN9__gnu_cxx14__alloc_traitsISaIPN7testing17TestEventListenerEEE10_S_on_swapERS4_S6__ZNK9__gnu_cxx13new_allocatorIN7testing12TestPropertyEE7addressERKS2_output_dir_ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EE3endEvset_last_death_test_message_ZNKSt3setIPKcSt4lessIS1_ESaIS1_EE5beginEv_ZN7testing16AssertionSuccessEvport_num_COLOR_YELLOWrebindreverse_iterator<__gnu_cxx::__normal_iterator > > >_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE4findERKSsreservedeath_test_index_ZN9__gnu_cxx17__normal_iteratorIPN7testing8internal9TraceInfoESt6vectorIS3_SaIS3_EEEppEi_ZNK9__gnu_cxx17__normal_iteratorIPKPN7testing8TestCaseESt6vectorIS3_SaIS3_EEEixEi_M_disjunct_ZNKSbIwSt11char_traitsIwESaIwEE12find_last_ofEwj_M_leak_ZNSs7_M_leakEv~Arguments_ZN9__gnu_cxx17__normal_iteratorIPN7testing8internal9TraceInfoESt6vectorIS3_SaIS3_EEEppEv_ZNSt6vectorIiSaIiEE6insertEN9__gnu_cxx17__normal_iteratorIPiS1_EERKierrors_str__is_move_iteratorfloatfieldg_executable_path_ZNKSt12_Vector_baseIPN7testing17TestEventListenerESaIS2_EE13get_allocatorEvForEach, void (*)(testing::TestInfo*)>_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE15_M_insert_equalERKSsrm_so_ZNSt6vectorIPcSaIS0_EE4swapERS2_elapsedfclose_ZN7testing8internal8FilePath11ConcatPathsERKS1_S3__S_unitbuf_ZNK9__gnu_cxx17__normal_iteratorIPPN7testing8internal29ParameterizedTestCaseInfoBaseESt6vectorIS4_SaIS4_EEEixEi_ZNKSt4lessIPKcEclERKS1_S4_kHexEscapeFLAGS_gtest_internal_run_death_testAssertionSuccessright_ZNKSbIwSt11char_traitsIwESaIwEEixEj_ZNSt6vectorIPcSaIS0_EE6insertEN9__gnu_cxx17__normal_iteratorIPS0_S2_EEjRKS0__ZNKSs2atEj_ZN7testing8internal10scoped_ptrINS0_24InternalRunDeathTestFlagEE7releaseEv_ZNK7testing8internal13FloatingPointIdE4bitsEv_ZNKSbIwSt11char_traitsIwESaIwEE6_M_repEvallocatorline__ZNKSt6vectorIN7testing14TestPartResultESaIS1_EE5emptyEvoperator< , std::allocator >_ZN9__gnu_cxx14__alloc_traitsISaISt13_Rb_tree_nodeISsEEE17_S_select_on_copyERKS3__ZNK9__gnu_cxx17__normal_iteratorIPN7testing8internal9TraceInfoESt6vectorIS3_SaIS3_EEEixEioriginal_dir_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEED2Ev_ZN7testing8internal7PrintToEwPSo_ZNSbIwSt11char_traitsIwESaIwEE6rbeginEv_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE15_M_insert_lowerEPSt18_Rb_tree_node_baseRKSsMessage_M_parent_ZNKSt6vectorIPN7testing8TestInfoESaIS2_EE5beginEv_ZNKSbIwSt11char_traitsIwESaIwEE6rbeginEv6ldiv_t_ZNKSt17_Rb_tree_iteratorIPKcEeqERKS2_EmptyTestEventListener_Destroyaddrinfoiterator_ZNKSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE14_M_lower_boundEPKSt13_Rb_tree_nodeISsES9_RKSsmemset_ZNK9__gnu_cxx13new_allocatorIPN7testing8internal29ParameterizedTestCaseInfoBaseEE8max_sizeEv_M_length_ZN7testing8internal11CmpHelperGEEPKcS2_xxchar_traitsFLAGS_gtest_random_seed_ZN9__gnu_cxx14__alloc_traitsISaIN7testing12TestPropertyEEE10deallocateERS3_PS2_jfactoryregex__Setfill_ZNKSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE4backEvreverse_iterator >pthread_mutex_init_ZNKSs9_M_ibeginEv_ZN7testing8internal6String28CaseInsensitiveCStringEqualsEPKcS3_insert_ZN7testing8internal17TestEventRepeater13OnTestCaseEndERKNS_8TestCaseE__miter_baseTypeWithSize<4u>_ZNSt12_Vector_baseISsSaISsEE19_M_get_Tp_allocatorEv_ZNSt3setIPKcSt4lessIS1_ESaIS1_EE6insertERKS1__ZN7testinglsERSoRKNS_14TestPartResultEHasOneFailureCmpHelperSTREQ_ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EE8pop_backEvdefined_test_names__ZNK7testing10TestResult15test_propertiesEvCmpHelperSTRCASENE_ZN7testing8UnitTestD2Ev_ZNSt11char_traitsIwE2ltERKwS2__ZN7testing18FLAGS_gtest_outputE_Iter_equals_valexit_code__ZNSt6vectorIiSaIiEE7reserveEj_ZN9__gnu_cxx17__normal_iteratorIPKN7testing14TestPartResultESt6vectorIS2_SaIS2_EEEppEi_Ios_SeekdirListTestsMatchingFilter_ZNSt6vectorIN7testing14TestPartResultESaIS1_EE6insertEN9__gnu_cxx17__normal_iteratorIPS1_S3_EERKS1_rebind, std::allocator > >_ZN7testing8internal37FormatCompilerIndependentFileLocationEPKci_ZN9__gnu_cxx17__normal_iteratorIPKN7testing14TestPartResultESt6vectorIS2_SaIS2_EEEppEvGenerateUniqueFileName_ZNKSt6vectorISsSaISsEE2atEjchar_traitskMaxBiggestInt__builtin_puts_ZN7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEE11ValueHolder7pointerEvoutput_name__addressoffile_size_ZNSt8ios_base5widthEi_ZN7testing8internal12UnitTestImpl23ClearNonAdHocTestResultEv_ZNSt6vectorIPN7testing8TestInfoESaIS2_EE14_M_fill_insertEN9__gnu_cxx17__normal_iteratorIPS2_S4_EEjRKS2___alloc_traits >GetThreadCount_ZN7testing8UnitTest14RecordPropertyERKSsS2_~GTestMutexLock_M_dataplusallocator__uninitialized_move_if_noexcept_a >_ZNSt6vectorIN7testing12TestPropertyESaIS1_EE7reserveEj~basic_ostreamequal_range_ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EE6insertEN9__gnu_cxx17__normal_iteratorIPS2_S4_EERKS2_plural_form_M_predinternal_ZN9__gnu_cxx14__alloc_traitsISaIPN7testing11EnvironmentEEE10_S_on_swapERS4_S6__ZNK7testing8internal12UnitTestImpl11GetTestCaseEi_M_left__builtin_putcharnothrow_t__destroyTestEventRepeater__builtin_fputsnew_test_case_ZNK9__gnu_cxx13new_allocatorIPN7testing17TestEventListenerEE8max_sizeEv_ZNKSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EEixEjkDeathTestLivedparameterized_tests_registered_ldiv_t_ZNKSs13find_first_ofEPKcjForEach, void (*)(testing::TestCase*)>_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE5eraseESt23_Rb_tree_const_iteratorISsE_ZNSs18_S_construct_aux_2EjcRKSaIcE_ZN7testing10TestResult20ValidateTestPropertyERKSsRKNS_12TestPropertyE_Vector_base >INTERCEPT_ALL_THREADSva_listinfoline_number_ZN7testing8TestInfoC2ERKSsS2_PKcS4_PKvPNS_8internal15TestFactoryBaseEShouldRunTestOnShard_S_synced_with_stdioInt32FromEnvOrDieIsEmptyTestFailedpositive_sign_ZN9__gnu_cxx13new_allocatorIcE9constructEPcRKcshard_index_env__lockmkstempKilledBySignal__in_chrg_ZN7testing8internal27PrettyUnitTestResultPrinterD0Evclone_ZNSbIwSt11char_traitsIwESaIwEE6appendERKS2__ZNSt11char_traitsIwE11to_int_typeERKw__normal_iterator, std::allocator > >_ZNKSt6vectorIN7testing8internal9TraceInfoESaIS2_EE14_M_range_checkEj_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE8_M_eraseEPSt13_Rb_tree_nodeIS1_Estatement__ZN7testing8internal13ExecDeathTest10AssumeRoleEv__builtin_strchr_ZN9__gnu_cxx14__alloc_traitsISaIPcEE17_S_select_on_copyERKS2_kFatalFailuretest_idMSG_CMSG_CLOEXEC_ZNK9__gnu_cxx17__normal_iteratorIPSsSt6vectorISsSaISsEEEdeEvGetEnvchild_pid___miter_basescoped_ptr_ZNSt12_Vector_baseIiSaIiEE19_M_get_Tp_allocatorEv~AssertionResultRegisterTests_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE29_M_get_insert_hint_unique_posESt23_Rb_tree_const_iteratorIS1_ERKS1__ZNSt6vectorIPN7testing11EnvironmentESaIS2_EE6insertEN9__gnu_cxx17__normal_iteratorIPS2_S4_EEjRKS2__ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EE5eraseEN9__gnu_cxx17__normal_iteratorIPS2_S4_EE_ZNK7testing8TestCase12elapsed_timeEv_ZNSs5clearEvSetUpEnvironmentin_color_moderange_ZNK9__gnu_cxx13new_allocatorIN7testing14TestPartResultEE8max_sizeEv_M_lower_bound_ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EE8_M_eraseEN9__gnu_cxx17__normal_iteratorIPS2_S4_EE__ptrContainer_ZNKSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE4sizeEvStreamingListener_ZN7testing8internal17TestEventRepeater6AppendEPNS_17TestEventListenerECreateKey__copy_move_b_ZN7testing8internal12UnitTestImplC2EPNS_8UnitTestEoperator<< _ZNSt3setISsSt4lessISsESaISsEE11equal_rangeERKSs_ZNSt6vectorIN7testing12TestPropertyESaIS1_EEixEj_ZNKSt6vectorISsSaISsEE5frontEv_ZNSt12_Vector_baseIPN7testing11EnvironmentESaIS2_EE17_M_create_storageEj_ZN7testing8internal13FloatingPointIdE24SignAndMagnitudeToBiasedERKyxmloutThreadLocal > >_ZN7testing8internal17Int32FromGTestEnvEPKci_ZNKSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE14_M_upper_boundEPKSt13_Rb_tree_nodeIS1_ESB_RKS1__Predicateiterationvector >_ZN7testing8internal35HandleExceptionsInMethodIfSupportedINS_4TestEvEET0_PT_MS4_FS3_vEPKc_ZNK7testing8internal10scoped_ptrINS0_17StreamingListener20AbstractSocketWriterEE3getEv_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE5eraseESt17_Rb_tree_iteratorIS1_E_ZN7testing15AssertionResultC2ERKS0__ZNSbIwSt11char_traitsIwESaIwEE5eraseEN9__gnu_cxx17__normal_iteratorIPwS2_EES6_string_value__c1__c2__alloc_traits >_ZNKSt6vectorIPN7testing8TestInfoESaIS2_EE14_M_range_checkEj_ZNK9__gnu_cxx17__normal_iteratorIPSsSt6vectorISsSaISsEEEixEi_ZN9__gnu_cxx14__alloc_traitsISaIPN7testing8TestCaseEEE8max_sizeERKS4__ZN9__gnu_cxx14__alloc_traitsISaISt13_Rb_tree_nodeISsEEE8max_sizeERKS3__M_finishactual_predicate_valuewcstof_ZN7testing8internal17StreamingListener13OnTestCaseEndERKNS_8TestCaseE_ZNK7testing8internal12UnitTestImpl17current_test_caseEvwcstokwcstol_ZNKSs16find_last_not_ofERKSsj_ZNKSbIwSt11char_traitsIwESaIwEE6lengthEv_ZN9__gnu_cxx13new_allocatorIPKcE9constructEPS2_RKS2_operator== >iterator_typeInitDeathTestSubprocessControlInfo_S_failbit__normal_iterator__ch_ZN7testing8internal23DefaultDeathTestFactory6CreateEPKcPKNS0_2REES3_iPPNS0_9DeathTestE_vptr.DeathTest_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE14_M_create_nodeERKS1__ZN7testing29FLAGS_gtest_stack_trace_depthESOCK_SEQPACKETGetElementOrtest_to_run_count_ZN9__gnu_cxx14__alloc_traitsISaIPN7testing8TestCaseEEE10deallocateERS4_PS3_j_ZN7testing8internal35DefaultGlobalTestPartResultReporteraSERKS1__ZN7testing13PrintToStringIPKcEESsRKT___int32_t__normal_iterator > >kMaxStackAlignment_ZN9__gnu_cxx13new_allocatorISt13_Rb_tree_nodeIPKcEE7destroyEPS4_operator<< UnshuffleTests_ZNSt6vectorIN7testing14TestPartResultESaIS1_EE9push_backERKS1__ZNK7testing8internal12UnitTestImpl17gtest_trace_stackEvpthread_key_deletest_mtimuncaptured_fd__ZN7testing8internal17StreamingListener20AbstractSocketWriter6SendLnERKSs_ZNSt6vectorISsSaISsEEixEjtm_zone_Bit_type_ZN7testing8UnitTestaSERKS0__ZNKSt12_Vector_baseISsSaISsEE13get_allocatorEv_ZNSt6vectorIPN7testing11EnvironmentESaIS2_EE5beginEv_ZNSt12_Vector_baseIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE19_M_get_Tp_allocatorEv_ZNSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE4backEv_ZNSs5eraseEN9__gnu_cxx17__normal_iteratorIPcSsEE__distance_ZN7testing8internal9Arguments11AddArgumentEPKcclose_ZNSt6vectorIPcSaIS0_EE6resizeEjS0__ZNKSt12_Vector_baseIN7testing8internal9TraceInfoESaIS2_EE13get_allocatorEvfunctorVerifyRegisteredTestNamesFormatCountableNounPrintBytesInObjectToPrintCharAndCodeTo_ZNSt6vectorIPN7testing11EnvironmentESaIS2_EE6resizeEjS2__ZN7testing8internal11CmpHelperLTEPKcS2_xx__is_move_iteratorbinary_ZNK7testing8TestInfo10should_runEv_ZN7testing8internal11ScopedTraceaSERKS1_rebindEscapeXmlFormatIntWidth2_ZNK9__gnu_cxx17__normal_iteratorIPKN7testing8internal9TraceInfoESt6vectorIS3_SaIS3_EEEptEvallocator_ZNSt12_Vector_baseIN7testing12TestPropertyESaIS1_EE17_M_create_storageEj__uninitialized_copy_a_ZNKSt6vectorIN7testing14TestPartResultESaIS1_EE4backEv_Rb_tree_node, std::allocator > >_ZNSt12_Vector_baseIN7testing14TestPartResultESaIS1_EE13_M_deallocateEPS1_jcopy_backwardStatStruct__pthread_mutex_sGetInstance_S_construct_aux_2skip_count_ZN7testing8internal25ReportInvalidTestCaseTypeEPKcS2_ifile_name__ZNK7testing10TestResult16total_part_countEvsa_familyFLAGS_gtest_filter_ZNSt6vectorIPcSaIS0_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS0_S2_EERKS0_shard_index_ZNSt6vectorIN7testing14TestPartResultESaIS1_EE5beginEv_ZN9__gnu_cxx17__normal_iteratorIPN7testing12TestPropertyESt6vectorIS2_SaIS2_EEEmIEiGNU C++ 4.9.2 20150212 (Red Hat 4.9.2-6) -mtune=generic -march=i686 -g -O2 -fPIC__dso_handle_ZN7testing8internal18CmpHelperSTRCASEEQEPKcS2_S2_S2__ZNK9__gnu_cxx17__normal_iteratorIPKPN7testing11EnvironmentESt6vectorIS3_SaIS3_EEEplEi_ZN7testing8internal17TestEventRepeater16OnTestProgramEndERKNS_8UnitTestEtime_t_Alloc_hider_ZNSs10_S_compareEjj_ZNK9__gnu_cxx17__normal_iteratorIPiSt6vectorIiSaIiEEEmiEi_ZNSt6vectorIPN7testing11EnvironmentESaIS2_EE5eraseEN9__gnu_cxx17__normal_iteratorIPS2_S4_EE_ZNSt6vectorIN7testing12TestPropertyESaIS1_EE8_M_eraseEN9__gnu_cxx17__normal_iteratorIPS1_S3_EES7_a_current_test_case_ZNSt6vectorIN7testing14TestPartResultESaIS1_EE4swapERS3_for_each<__gnu_cxx::__normal_iterator >, void (*)(testing::TestCase*)>_ZNKSt12_Vector_baseIPN7testing8TestInfoESaIS2_EE19_M_get_Tp_allocatorEv_ZNSt6vectorIPN7testing8TestCaseESaIS2_EE15_M_erase_at_endEPS2__ZNK7testing8TestCase14test_info_listEvRemoveInvalidXmlCharactersnew_allocator >_ZNKSt13_Bit_iterator13_M_const_castEv_ZNSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE14_M_fill_assignEjRKS3__ZN7testing32ScopedFakeTestPartResultReporteraSERKS0_ForEach, void (*)(testing::TestEventListener*)>_ZNKSt6vectorIPN7testing17TestEventListenerESaIS2_EE14_M_range_checkEj_ZNSt12_Vector_baseISsSaISsEE17_M_create_storageEj_ZNKSs17find_first_not_ofERKSsj_ZN9__gnu_cxx13new_allocatorISsE7destroyEPSs7lldiv_tregs_allocated_ZN9__gnu_cxx17__normal_iteratorIPiSt6vectorIiSaIiEEEmmEi_ZN7testing18TestEventListeners23SetDefaultResultPrinterEPNS_17TestEventListenerErandom_access_iterator_tag_M_offset_ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EE4dataEv_ZN9__gnu_cxx17__normal_iteratorIPiSt6vectorIiSaIiEEEmmEvuninitialized_copy_ZNK7testing8TestInfo10type_paramEvint_p_cs_precedes_ZN7testing8internal18PrintCharAndCodeToIwwEEvT0_PSo_ZNKSt6vectorIPN7testing8TestCaseESaIS2_EE6rbeginEv__uninitialized_copy_a<__gnu_cxx::__normal_iterator >, testing::internal::TraceInfo*, testing::internal::TraceInfo>bsearch_ZNKSt6vectorIPN7testing8TestCaseESaIS2_EE14_M_range_checkEjshould_shard_ZNKSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE12_M_check_lenEjPKc_ZNK9__gnu_cxx17__normal_iteratorIPKSsSt6vectorISsSaISsEEEplEimon_grouping_M_deallocate_Node_allocator_ZN9__gnu_cxx17__normal_iteratorIPPN7testing8internal29ParameterizedTestCaseInfoBaseESt6vectorIS4_SaIS4_EEEmmEiParseGoogleTestFlagsOnlyImpl_ZNKSs4rendEv_ZNKSbIwSt11char_traitsIwESaIwEE5rfindEwj_ZN9__gnu_cxx17__normal_iteratorIPPN7testing8internal29ParameterizedTestCaseInfoBaseESt6vectorIS4_SaIS4_EEEmmEv_ZNSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE5eraseEN9__gnu_cxx17__normal_iteratorIPS3_S5_EETestCasePassed_offset_ZN7testing28FLAGS_gtest_death_test_styleE_M_replace_safe_ZNK7testing8internal12UnitTestImpl22test_case_to_run_countEvGetCapturedStdout__numeric_traits_integer_ZN7testing8internal24HasNewFatalFailureHelperD2Ev_ZNSbIwSt11char_traitsIwESaIwEE6insertEN9__gnu_cxx17__normal_iteratorIPwS2_EEjw_M_beginbasic_istream >_ZN7testing8internal38DefaultPerThreadTestPartResultReporteraSERKS1___kindlow_byte_Destroy >_old_offsetfile_namembstowcs_ZNSt6vectorIN7testing14TestPartResultESaIS1_EE15_M_erase_at_endEPS1__ZNSt6vectorIPN7testing11EnvironmentESaIS2_EE4rendEv_ZNKSt12_Vector_baseIPN7testing11EnvironmentESaIS2_EE13get_allocatorEvrepeat_ZN9__gnu_cxx14__alloc_traitsISaIN7testing8internal9TraceInfoEEE8max_sizeERKS4__ZNSs7replaceEjjPKcFormatBooloperator<< basic_ios >_ZNKSt6vectorIN7testing8internal9TraceInfoESaIS2_EE3endEvuninitialized_copy~basic_streambuf_ZN9__gnu_cxx14__alloc_traitsISaIPKcEE7destroyERS3_PS2__ZNKSt18_Bit_iterator_baseeqERKS__cur_column_ZN7testing4Test18HasNonfatalFailureEvGetArgvsForDeathTestChildProcessoperator<< spawnedthrow_on_failure_ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EE3endEvFormatEpochTimeInMillisAsIso8601_ZNKSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE11_M_leftmostEv_ZNSt11char_traitsIcE6lengthEPKcFormatTestCount_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE23_M_get_insert_equal_posERKS1__ZN7testing8internal7PrintToEaPSo_S_construct_auxOnTestProgramEndreverse_iterator<__gnu_cxx::__normal_iterator > > >_M_value_ZNKSt6vectorIN7testing14TestPartResultESaIS1_EE4sizeEvpthread_self_ZN7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEE11ValueHolderD0Evsizelist_tests~_Rb_tree_implextension_Tp1ShouldRunTestCase_ZNK7testing10TestResult16death_test_countEv__pred_iter_ZN9__gnu_cxx14__alloc_traitsISaIN7testing14TestPartResultEEE17_S_select_on_copyERKS3__ZNK7testing8internal24InternalRunDeathTestFlag4fileEv__copy_move_b_ZNSbIwSt11char_traitsIwESaIwEE12_M_leak_hardEv__destroyset_spawned_ZNKSt6vectorIPN7testing17TestEventListenerESaIS2_EE5emptyEv_ZNSt6vectorIPN7testing8TestCaseESaIS2_EE8pop_backEv__copy_move_a2exitGTEST_INFOtime_structFileNo_ZN7testing8internal14CapturedStreamaSERKS1_key_compDefaultPrintNonContainerTo_ZN9__gnu_cxx14__alloc_traitsISaIPN7testing8internal29ParameterizedTestCaseInfoBaseEEE8max_sizeERKS5__ZNSt6vectorIiSaIiEE8pop_backEv_ZN9__gnu_cxx24__numeric_traits_integerImE8__digitsE_ZNSt6vectorIiSaIiEE4backEvcopyvalue_messageGTEST_FATAL_ZNKSs4_Rep12_M_is_leakedEv_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE11lower_boundERKSs_ZN7testing8TestCase10TestFailedEPKNS_8TestInfoEoperator[]_ZN7testing8internal24XmlUnitTestResultPrinter19IsValidXmlCharacterEc_ZNSt6vectorIPN7testing11EnvironmentESaIS2_EE4swapERS4__ZN7testing10TestResult5ClearEv_ZN9__gnu_cxx17__normal_iteratorIPKPN7testing11EnvironmentESt6vectorIS3_SaIS3_EEEmmEi_ZNK9__gnu_cxx13new_allocatorIPKcE7addressERKS2_strncmp_ZNKSs16find_last_not_ofEPKcjj__n2_ZN9__gnu_cxx17__normal_iteratorIPKPN7testing11EnvironmentESt6vectorIS3_SaIS3_EEEmmEvp_cs_precedeswint_t_ZNK7testing8internal24InternalRunDeathTestFlag8write_fdEv__cxa_guard_releasePrintCharsAsStringTo_ZNSt6vectorIN7testing12TestPropertyESaIS1_EE5eraseEN9__gnu_cxx17__normal_iteratorIPS1_S3_EES7__ZN7testing8internal27PrettyUnitTestResultPrinter25OnEnvironmentsTearDownEndERKNS_8UnitTestE_ZNSt12_Vector_baseIiSaIiEE12_Vector_impl12_M_swap_dataERS2_mblen__blkcnt_t__are_samebasic_iosGetBoolAssertionFailureMessage_ZN7testing8internal23DefaultDeathTestFactoryD2Evoperator<< decimal_pointkey_compareIsDirconnect_S_select_on_copy_ZNKSbIwSt11char_traitsIwESaIwEE8capacityEv_ZN7testing28FLAGS_gtest_catch_exceptionsE__uninitialized_copy_a_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE11_M_get_nodeEv_ZNSt6vectorIPN7testing8TestInfoESaIS2_EE4dataEv_ZN7testing8internal11ScopedTraceC2EPKciRKNS_7MessageE__nlink_tUniversalPrintexpected_value_ZN7testing8internal27PrettyUnitTestResultPrinter13OnTestCaseEndERKNS_8TestCaseE_ZNKSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE4sizeEv_ZN9__gnu_cxx14__alloc_traitsISaIN7testing12TestPropertyEEE7destroyERS3_PS2__S_ios_fmtflags_end_ZNKSbIwSt11char_traitsIwESaIwEE4findERKS2_jAssertionFailure_ZNSt6vectorIiSaIiEE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPiS1_EERKi_M_c__niter_base_ZNSt12_Vector_baseIPN7testing8TestInfoESaIS2_EE12_Vector_impl12_M_swap_dataERS5__ZNSt16reverse_iteratorIN9__gnu_cxx17__normal_iteratorIPPN7testing11EnvironmentESt6vectorIS4_SaIS4_EEEEEmIEi~scoped_ptr_M_n_M_p_ZNSt10_Iter_baseIPN7testing12TestPropertyELb0EE7_S_baseES2__M_t_ZNKSbIwSt11char_traitsIwESaIwEE8max_sizeEv_ZNKSt6vectorISsSaISsEEixEjMakeFileName_ZNKSt5ctypeIcE5widenEc_M_set_length_and_sharable_ZNSbIwSt11char_traitsIwESaIwEE7replaceEN9__gnu_cxx17__normal_iteratorIPwS2_EES6_NS4_IPKwS2_EES9___next_Rb_tree_const_iterator~_Vector_base_ZNKSbIwSt11char_traitsIwESaIwEE5beginEv__pfa_line_ZNSt11char_traitsIwE6lengthEPKw_ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EE6insertEN9__gnu_cxx17__normal_iteratorIPS2_S4_EEjRKS2__ZNKSt3setISsSt4lessISsESaISsEE8max_sizeEv_ZN7testing8TestCase14set_should_runEb_ZN9__gnu_cxx17__normal_iteratorIPN7testing8internal9TraceInfoESt6vectorIS3_SaIS3_EEEmmEi_ZN9__gnu_cxx17__normal_iteratorIPN7testing8internal9TraceInfoESt6vectorIS3_SaIS3_EEEmmEvdisabled_test_count_M_dataintercept_mode~TestCase_ZNKSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE8capacityEvexpected_predicate_value_IO_buf_endshort unsigned int_ZN9__gnu_cxx17__normal_iteratorIPiSt6vectorIiSaIiEEEpLEi_IO_backup_base_ZNSs6appendEPKcj_ZNSs12_S_constructIPcEES0_T_S1_RKSaIcESt20forward_iterator_tagTestPartFatallyFailed_ZN7testing11Environment8TearDownEv_ZNK7testing8internal10scoped_ptrISsE3getEv_ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EE8_M_eraseEN9__gnu_cxx17__normal_iteratorIPS2_S4_EES8_key_reportable_disabled_test_count_M_create_storageconstruct_ZNSt6vectorIPN7testing8TestInfoESaIS2_EE5beginEv__copy_move_a2_ZN7testing8internal6String23EndsWithCaseInsensitiveERKSsS3__ZN9__gnu_cxx13new_allocatorIPN7testing17TestEventListenerEE9constructEPS3_RKS3_iterator_traits_ZN9__gnu_cxx17__normal_iteratorIPPN7testing8internal29ParameterizedTestCaseInfoBaseESt6vectorIS4_SaIS4_EEEpLEi_ZNKSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE8max_sizeEv_ZN7testing8internal13CaptureStdoutEv__normal_iterator > >StringFromGTestEnv__s2_M_insert_equal__ZNKSs17find_first_not_ofEPKcjj_S_ios_seekdir_end_ZN7testing8internal35FLAGS_gtest_internal_run_death_testE_M_disposeGetCurrentOsStackTraceExceptTopreverse_iterator<__gnu_cxx::__normal_iterator, std::allocator >*, std::vector, std::allocator >, std::allocator, std::allocator > > > > >ios_base__copy_move_backward_a2_ZNSt17_Rb_tree_iteratorISsEppEv_shortbuf_ZN9__gnu_cxx14__alloc_traitsISaIPN7testing17TestEventListenerEEE8allocateERS4_j_ZNSt6vectorIPN7testing11EnvironmentESaIS2_EEaSERKS4_kDisableTestFilter_S_goodbitn_sep_by_space_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE14_M_create_nodeERKSs_M_insert_timespecAssertHelper_ZNKSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE5countERKS1__ZNSt12_Vector_baseIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE12_Vector_impl12_M_swap_dataERS6__ZN9__gnu_cxx14__alloc_traitsISaIPN7testing17TestEventListenerEEE10deallocateERS4_PS3_j_ZNKSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE4sizeEvTypeWithSize<8u>kTestsuites_vptr.TestPartResultReporterInterface_ZNSt6vectorIN7testing14TestPartResultESaIS1_EE8_M_eraseEN9__gnu_cxx17__normal_iteratorIPS1_S3_EES7__ZNK9__gnu_cxx13new_allocatorISt13_Rb_tree_nodeISsEE7addressERS2_this_test_name_Destroy*>_ZNSt6vectorIiSaIiEE5eraseEN9__gnu_cxx17__normal_iteratorIPiS1_EES5__ZNSt6vectorIN7testing12TestPropertyESaIS1_EE14_M_fill_assignEjRKS1_ChopLowBits_ZN7testing8internal13ColoredPrintfENS0_10GTestColorEPKczFDOpenIsNormalizableWhitespaceelapsed_timeParseNaturalNumber_ZNKSbIwSt11char_traitsIwESaIwEE4findEPKwjjTEST_THREW_EXCEPTION_ZNSt6vectorIN7testing14TestPartResultESaIS1_EEaSERKS3_FormatCxxExceptionMessage_ZN7testing8internal24XmlUnitTestResultPrinter13EscapeXmlTextEPKcnegative_signoperator delete []__miter_basebegin_string_quoteoperator!= >__copy_move_a2showpointtermdouble_ZNK7testing8UnitTest17current_test_infoEvlock__destroy_ZN7testing18TestEventListeners7ReleaseEPNS_17TestEventListenerE_ZNK9__gnu_cxx13new_allocatorIPN7testing8TestInfoEE7addressERS3__ZN7testing22EmptyTestEventListener27OnEnvironmentsTearDownStartERKNS_8UnitTestEkProtobufOneLinerMaxLength_ZN9__gnu_cxx17__normal_iteratorIPN7testing12TestPropertyESt6vectorIS2_SaIS2_EEEmmEiset_statusresult__ZN7testing8internal13FloatingPointIdE8InfinityEvCmpHelperEQallowed_names_ZN9__gnu_cxx14__alloc_traitsISaIPN7testing17TestEventListenerEEE7destroyERS4_PS3__ZNK7testing14KilledBySignalclEi_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE5beginEvresults_ZNK9__gnu_cxx17__normal_iteratorIPKPN7testing17TestEventListenerESt6vectorIS3_SaIS3_EEEmiEioperator<< _ZNK7testing15AssertionResult15failure_messageEvuse_forklesselement_namefatally_failedallocatorStringStreamToStringFailed_ZN7testing8internal29ParseInternalRunDeathTestFlagEvGeneratecopy_ZNK9__gnu_cxx13new_allocatorIN7testing12TestPropertyEE8max_sizeEvpassed_ZN7testing8internal17TestEventRepeater9OnTestEndERKNS_8TestInfoE_ZNKSt13_Bit_iteratordeEv_ZN7testing8internal20SingleFailureCheckerD2Evtuple<>case_listcondition_ZN7testing8internal10scoped_ptrISsE5resetEPSs_ZN7testing8internal5MutexD2Ev~vector_ZN9__gnu_cxx14__alloc_traitsISaIPN7testing8internal29ParameterizedTestCaseInfoBaseEEE7destroyERS5_PS4__ZNSt6vectorIPN7testing8TestCaseESaIS2_EE5eraseEN9__gnu_cxx17__normal_iteratorIPS2_S4_EES8_mbtowccopy_backward_ZNSs4rendEv__cxa_end_catch__normal_iterator > >_ZNSt12_Vector_baseIPN7testing8TestCaseESaIS2_EE19_M_get_Tp_allocatorEv__is_move_iterator_ZN9__gnu_cxx17__normal_iteratorIPKPN7testing11EnvironmentESt6vectorIS3_SaIS3_EEEpLEi_ZNSs7replaceEjjRKSsjjCmpHelperGE_ZN7testing8internal12UnitTestImpl32SuppressTestEventsIfInSubprocessEvmax_ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EE18_M_fill_initializeEjRKS2___compar_fn_t__copy_move_backward_a*, std::basic_string*>CmpHelperGT_ZN7testing8internal24HasNewFatalFailureHelperaSERKS1_parent_ldivtable_sizetotal_shardsholder__pid_type__pathGTestColoroperator()<__gnu_cxx::__normal_iterator > >_ZN7testing8internal26ThreadLocalValueHolderBaseD0Evoperator<< _ZN7testing8internal14CapturedStream17GetCapturedStringEv_ZNSt6vectorIN7testing12TestPropertyESaIS1_EE4rendEv__align__alloc_traits >_ZN7testing17TestEventListener22OnEnvironmentsSetUpEndERKNS_8UnitTestEiterator_traits_ZNSt11char_traitsIcE11eq_int_typeERKiS2__ZN9__gnu_cxx13new_allocatorISsE8allocateEjPKv_ZNKSt13_Bit_iteratorixEi_ZN9__gnu_cxx13new_allocatorIPN7testing11EnvironmentEE8allocateEjPKvstdoutflush >_ZNKSt6vectorISsSaISsEE14_M_range_checkEjmutex_ZN7testing8internal12UnitTestImpl23ListTestsMatchingFilterEv_ZNSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE5beginEv~MessageSetValue_ZNK7testing14TestPartResult17nonfatally_failedEv_ZN7testing8internal15ParseStringFlagEPKcS2_PSs~NoExecDeathTest_ZNSt6vectorIPN7testing8TestInfoESaIS2_EE7reserveEj_ZNSs6assignERKSs_ZNSs6appendEjc_ZN7testing8internal18OsStackTraceGetter16UponLeavingGTestEvregistered___normal_iterator > >_ZNSs4_Rep8_M_cloneERKSaIcEj_ZN7testing23FLAGS_gtest_random_seedE_ZNSt6vectorIPN7testing8TestCaseESaIS2_EE6assignEjRKS2_st_nlink_ZNK7testing18TestEventListeners22EventForwardingEnabledEvkFilterFlag__copy_move_backward_a2_ZNSt6vectorIPN7testing8TestInfoESaIS2_EE18_M_fill_initializeEjRKS2_basic_stringbuf, std::allocator >_ZN7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEEaSERKS6_MSG_PROXY_ZNSt11char_traitsIwE6assignEPwjw_S_compare_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE10_M_insert_EPSt18_Rb_tree_node_baseS9_RKS1__ZN7testing8internal16BoolFromGTestEnvEPKcb_ZNKSs5rfindEcj_ZNSt6vectorIPN7testing8TestInfoESaIS2_EE5eraseEN9__gnu_cxx17__normal_iteratorIPS2_S4_EES8__ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE10_S_minimumEPKSt18_Rb_tree_node_base__miter_base_ZN9__gnu_cxx14__alloc_traitsISaIPcEE8allocateERS2_j_ZN7testing8internal24XmlUnitTestResultPrinter21OutputXmlCDataSectionEPSoPKc__uninitialized_copy_a<__gnu_cxx::__normal_iterator*, std::vector > >, std::basic_string*, std::basic_string >_ZNSbIwSt11char_traitsIwESaIwEE7_M_moveEPwPKwjpipe_fd__sighandler_ttz_dsttime_M_put_node_ZNKSt3setIPKcSt4lessIS1_ESaIS1_EE4sizeEv__max_ZN9__gnu_cxx17__normal_iteratorIPN7testing8internal9TraceInfoESt6vectorIS3_SaIS3_EEEpLEi_S_leftai_family__begfdopen__copy_mfind_first_not_ofhas_new_fatal_failure_ZN9__gnu_cxx13new_allocatorIPN7testing11EnvironmentEE10deallocateEPS3_jlong double_Vector_impl_ZNKSt6vectorIN7testing8internal9TraceInfoESaIS2_EE5emptyEvupper_boundDirectoryExistsa_status_ZN7testing8TestCase14test_info_listEvabortfilter_flaga_line_number_ZNK7testing8TestCase6FailedEv_ZNK9__gnu_cxx17__normal_iteratorIPcSsEplEi_Iter_ZNKSs13get_allocatorEv_ZNSt12_Vector_baseIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE11_M_allocateEj_ZN7testing17FLAGS_gtest_colorEreverse_iterator<__gnu_cxx::__normal_iterator > > >__k1munmap_ZN7testing8internal17StreamingListener9UrlEncodeEPKclocaleconvUniversalPrintCharArrayScopedPrematureExitFileoperator!= >_ZN9__gnu_cxx14__alloc_traitsISaIPN7testing8TestCaseEEE8allocateERS4_j_ZNK7testing8internal14TestCaseNameIsclEPKNS_8TestCaseE__cxa_free_exception_M_mutatecopy_Rb_tree_decrement_ZNKSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE11_M_leftmostEvkMaxCodePoint1kMaxCodePoint2kMaxCodePoint3kMaxCodePoint4beginwstring_S_construct__pred_iter__copy_move_backward_a__clock_t__fmtfl_ZNKSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE5emptyEvkStackTraceMarker_ZN7testing8internal17StreamingListener11OnTestStartERKNS_8TestInfoECmpHelperLE_ZNSt18_Rb_tree_node_base10_S_minimumEPS_rebindp_sign_posn_ZN7testing8internal15TestFactoryBaseaSERKS1_CmpHelperLTinternal_run_death_test_flag_ZNKSt3setISsSt4lessISsESaISsEE5countERKSsallocated_ZN7testing8internal21UniversalTersePrinterIPKcE5PrintES3_PSos2_expression_ZN7testing8internal18InitGoogleTestImplIwEEvPiPPT__Rb_tree, std::less, std::allocator >_S_on_swapfirst_fixture_id_ZN7testing4Test14RecordPropertyERKSsS2___copy_move_a__copy_move_backward_a2_ZN9__gnu_cxx14__alloc_traitsISaIPN7testing8internal29ParameterizedTestCaseInfoBaseEEE10deallocateERS5_PS4_j_ZNKSt15basic_streambufIcSt11char_traitsIcEE5egptrEv_ZNSt6vectorISsSaISsEE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPSsS1_EERKSs__uninit_copy_ZN7testing14IsNotSubstringEPKcS1_RKSbIwSt11char_traitsIwESaIwEES7__ZN9__gnu_cxx17__normal_iteratorIPKN7testing14TestPartResultESt6vectorIS2_SaIS2_EEEpLEi_M_get_nodeflush__mempositive_ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EE4swapERS4__ZNKSt3setIPKcSt4lessIS1_ESaIS1_EE10value_compEv_ZNSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE15_M_erase_at_endEPS3_valuetest_part_results_name_CmpHelperNEmessage_TestPartNonfatallyFailed_S_uppercase_ZN7testing8internal21ImplicitlyConvertibleIPKvS3_E5valueEgrouping_ZNK7testing8TestCase10should_runEvcopy_backwardGetTimeInMillis_ZNSt6vectorIPN7testing8TestInfoESaIS2_EEaSERKS4__ZNKSt6vectorIiSaIiEE6rbeginEv_ZNK9__gnu_cxx17__normal_iteratorIPiSt6vectorIiSaIiEEEplEiresult_typeoperator<< >_ZNSs12_S_constructIPKcEEPcT_S3_RKSaIcE_ZNKSt3setIPKcSt4lessIS1_ESaIS1_EE5emptyEvflip_ZN7testing8TestInfo3RunEvoperator- >_ZNSt6vectorIPN7testing11EnvironmentESaIS2_EE14_M_fill_assignEjRKS2__ZNK9__gnu_cxx17__normal_iteratorIPKPN7testing11EnvironmentESt6vectorIS3_SaIS3_EEEmiEiFLAGS_gtest_also_run_disabled_testsaddressHasNewFatalFailureHelperlconvregfreeflag_enda_regexReadEntireFile_ZNK9__gnu_cxx17__normal_iteratorIPiSt6vectorIiSaIiEEEptEv_ZNKSbIwSt11char_traitsIwESaIwEE4sizeEv_ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EE5frontEvmkdir_ZNKSbIwSt11char_traitsIwESaIwEE3endEv_ZNSt6vectorISsSaISsEE6insertEN9__gnu_cxx17__normal_iteratorIPSsS1_EERKSsDIEDkQuoteBegin_ZNSt12_Vector_baseIPcSaIS0_EE19_M_get_Tp_allocatorEvreverse_iterator<__gnu_cxx::__normal_iterator > > >_ZN9__gnu_cxx13new_allocatorISt13_Rb_tree_nodeIPKcEE10deallocateEPS4_jeq_int_type_ZNK7testing8internal13FloatingPointIdE8sign_bitEvgtest_output_flagnpos_ZN7testing8TestCase10TestPassedEPKNS_8TestInfoE_ZNKSt6vectorIN7testing12TestPropertyESaIS1_EE6rbeginEvabs_error_expr_ZNSt6vectorISsSaISsEE5frontEvHasFatalFailure_ZNSt18_Rb_tree_node_base10_S_maximumEPKS_strdupinternal2__uninitialized_copy_aoperator- >_ZN7testing4Test10HasFailureEv_ZNK9__gnu_cxx17__normal_iteratorIPKSsSt6vectorISsSaISsEEEmiEi_ZNKSs6_M_repEv__uninit_copytext_ZN9__gnu_cxx13new_allocatorIN7testing14TestPartResultEE8allocateEjPKv__normal_iteratorpost_flag_parse_init_performed__ZN7testing8internal32FormatEpochTimeInMillisAsIso8601ExTestPropertyKeyIs_ZN7testing8internal10scoped_ptrINS0_16DeathTestFactoryEE7releaseEv_ZN7testing8internal17g_executable_pathEParameterizedTestCaseInfoBasestack_grows_down_ZNSt3setIPKcSt4lessIS1_ESaIS1_EE11upper_boundERKS1_posix_ZNSt6vectorIPN7testing11EnvironmentESaIS2_EE3endEvvector_ZN7testing8internal18ParseNaturalNumberIiEEbRKSsPT_allocator_ZNK7testing8internal9MutexBase10AssertHeldEv_ZN7testing8internal17TestEventRepeater15OnTestCaseStartERKNS_8TestCaseE_M_allocate_ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EE14_M_fill_insertEN9__gnu_cxx17__normal_iteratorIPS2_S4_EEjRKS2__ZNKSs6rbeginEvnum_readtest_countpstr_M_erase_aux_Construct_ZNSt6vectorIiSaIiEE9push_backERKi__minOutputXmlAttribute_ZNSt6vectorIPN7testing8TestInfoESaIS2_EE6rbeginEvkTestShardStatusFile_ZNKSt6vectorIPN7testing17TestEventListenerESaIS2_EE3endEv__ownerSetup_should_be_spelled_SetUpoperator<< _ZNSt6vectorIPN7testing11EnvironmentESaIS2_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS2_S4_EERKS2__ZN7testing8internal17GetCapturedStreamEPPNS0_14CapturedStreamE_Construct, char const*>_ZNKSbIwSt11char_traitsIwESaIwEE7_M_iendEv_ZN7testing8internal11ShouldShardEPKcS2_b_ZNSt12_Vector_baseIPN7testing8TestInfoESaIS2_EE17_M_create_storageEj_ZN7testing10TestResultC2Ev_ZNSs4_Rep15_M_set_sharableEvsa_family_t_M_bump_up_ZN7testing8internal18StreamableToStringIiEESsRKT__ZN7testing8internal17TestEventRepeater18OnTestIterationEndERKNS_8UnitTestEi_ZNSbIwSt11char_traitsIwESaIwEE5beginEvPredicateswapiterator_traits_ZNKSt6vectorIPN7testing8TestInfoESaIS2_EE5emptyEv_ZSt16__throw_bad_castv_ZNK7testing8internal12UnitTestImpl16total_test_countEv_vtable_offsetSetUpTestCaseFuncTestResultwctrans_t_ZNK7testing8UnitTest11random_seedEv__addressofOVERSEE_TEST_ZNKSt3setISsSt4lessISsESaISsEE8key_compEv_ZN7testing8internal24XmlUnitTestResultPrinterC2EPKcdot_extension_ZNSs7replaceEN9__gnu_cxx17__normal_iteratorIPcSsEES2_PKcS4_set_forwarding_enabled_M_impl_ZN7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEE11ValueHolderD2Evsi_sigvalvwprintf_ZN7testing8TestInfo26increment_death_test_countEv_M_range_check_ZNSt23_Rb_tree_const_iteratorIPKcEppEipremature_exit_filepath~GTestFlagSaver_ZNSs7replaceEN9__gnu_cxx17__normal_iteratorIPcSsEES2_NS0_IPKcSsEES5_CheckedDowncastToActualType::ValueHolder, testing::internal::ThreadLocalValueHolderBase>_ZNSt23_Rb_tree_const_iteratorIPKcEppEv_ZNK7testing8internal12UnitTestImpl12elapsed_timeEv_ZNKSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE8key_compEv_ZNKSt6vectorIPN7testing8TestInfoESaIS2_EE8capacityEv_ZNK9__gnu_cxx13new_allocatorIPN7testing8TestInfoEE7addressERKS3__ZNK7testing15AssertionResultcvbEvCountIf, bool (*)(const testing::TestInfo*)>_ZNK7testing8TestInfo14test_case_nameEvPassed_ZN7testing8internal2RE9FullMatchERKSsRKS1__ZN7testing8internal13FloatingPointIdE38DistanceBetweenSignAndMagnitudeNumbersERKyS4__ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EE18_M_fill_initializeEjRKS2__ZNK9__gnu_cxx17__normal_iteratorIPPN7testing8TestInfoESt6vectorIS3_SaIS3_EEEdeEvpointerkStdOutFileno_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEEaSERKS5__ZNKSt6vectorISsSaISsEE8capacityEv_ZNSbIwSt11char_traitsIwESaIwEE13_S_copy_charsEPwS3_S3_forward_iterator_tagfastst_modean_index_ZNKSt6vectorIN7testing8internal9TraceInfoESaIS2_EE8capacityEv_ZN9__gnu_cxx14__alloc_traitsISaIN7testing8internal9TraceInfoEEE8allocateERS4_jiterator_traits_ZNSbIwSt11char_traitsIwESaIwEE7replaceEjjjw_ZN9__gnu_cxx24__numeric_traits_integerIsE5__maxE_ZNSt6vectorISsSaISsEE8pop_backEv_ZNK9__gnu_cxx17__normal_iteratorIPPcSt6vectorIS1_SaIS1_EEEplEi_ZNKSt6vectorIiSaIiEE14_M_range_checkEjtest_result_ZNSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EEaSERKS5__InputIterator_S_skipws_GLOBAL__sub_I_gtest_all.ccdest_ptrClosepthread_getspecificTestFactoryBase_ZNKSt6vectorISsSaISsEE8max_sizeEv_ZNK7testing8internal12UnitTestImpl17current_test_infoEv_ZN9__gnu_cxx14__alloc_traitsISaIiEE10deallocateERS1_Pij__copy_move_backward_a2_ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EE14_M_fill_insertEN9__gnu_cxx17__normal_iteratorIPS2_S4_EEjRKS2__M_leftmost_ZNKSt3setIPKcSt4lessIS1_ESaIS1_EE6rbeginEv_ZN7testing8internal27CheckedDowncastToActualTypeINS0_11ThreadLocalISt6vectorINS0_9TraceInfoESaIS4_EEE11ValueHolderENS0_26ThreadLocalValueHolderBaseEEEPT_PT0__ZNKSt6vectorIN7testing8internal9TraceInfoESaIS2_EE8max_sizeEv_ZNSt6vectorIN7testing12TestPropertyESaIS1_EE8pop_backEv_ZN7testing8TestCase12TestDisabledEPKNS_8TestInfoE_ZNK9__gnu_cxx17__normal_iteratorIPPN7testing8TestInfoESt6vectorIS3_SaIS3_EEEixEibits__ZN7testing22EmptyTestEventListenerD0Ev__uninitialized_move_if_noexcept_a >allocator_ZN7testing17TestEventListeneraSERKS0___uninit_copy_ZNSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE4swapERS5__ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE24_M_get_insert_unique_posERKSs_M_get_insert_hint_equal_pos_M_move_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE8_S_rightEPSt18_Rb_tree_node_base__niter_base_ZNK7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE16GetOrCreateValueEv_ZNSs13_S_copy_charsEPcS_S__ZNSt10_Iter_baseIPPN7testing17TestEventListenerELb0EE7_S_baseES3__ZNSt6vectorIN7testing14TestPartResultESaIS1_EE6resizeEjS1__ZNK9__gnu_cxx17__normal_iteratorIPSsSt6vectorISsSaISsEEE4baseEvoperator<< >_ZN7testing8internal38DefaultPerThreadTestPartResultReporterD0Ev_ZNKSbIwSt11char_traitsIwESaIwEE17find_first_not_ofERKS2_jnext_seed_ZNKSt12_Vector_baseIPN7testing17TestEventListenerESaIS2_EE19_M_get_Tp_allocatorEv_ZNKSt6vectorIN7testing14TestPartResultESaIS1_EE14_M_range_checkEjcerrdefault_result_printer_pfile_ZNSs12_S_constructIPKcEEPcT_S3_RKSaIcESt20forward_iterator_tag_ZN9__gnu_cxx13new_allocatorIPKcE10deallocateEPS2_jtest_case_count_ZN7testing8internal24XmlUnitTestResultPrinter9EscapeXmlERKSsbwctob_ZNKSt6vectorISsSaISsEE5beginEv_IO_save_end_ZNK7testing8internal12UnitTestImpl19disabled_test_countEvst_gidrelative_path__are_same_ZN7testing8internal9DeathTest11LastMessageEv__normal_iterator > >_ZN7testing8internal12UnitTestImpl20set_catch_exceptionsEb_ZN7testing22EmptyTestEventListener16OnTestProgramEndERKNS_8UnitTestE__ioinit_ZNKSs8capacityEv_DestroykFractionBitCount__gid_t__are_same, std::allocator >*, std::basic_string, std::allocator >*>new_allocatorFClose_ZN7testing8internal9EqFailureEPKcS2_RKSsS4_bIsUtf16SurrogatePair_ZNK7testing8UnitTest17current_test_caseEv_ZNSs5eraseEjj_ZNKSs4dataEv_ZN7testing8internal18OsStackTraceGetteraSERKS1_construct_ZNSt23_Rb_tree_const_iteratorISsEppEi_ZN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEEaSERKS4_PrintAsCharLiteralTo_ZN9__gnu_cxx17__normal_iteratorIPiSt6vectorIiSaIiEEEmIEistr_len_ZNSt23_Rb_tree_const_iteratorISsEppEv__uninitialized_move_if_noexcept_a >UniversalPrint >ClearNonAdHocTestResult_ZNKSt23_Rb_tree_const_iteratorIPKcEptEv_ZN7testing17TestEventListener16OnTestProgramEndERKNS_8UnitTestE_ZN7testing8internal6String15FormatIntWidth2Eioperator== >_ZNKSs6lengthEvSetDefaultXmlGenerator_ZN7testing8internal16WideStringToUtf8EPKwiwcsftime_ZNKSs8max_sizeEv~DefaultGlobalTestPartResultReporter_FwdIterator_ZN7testing8internal14CmpHelperSTREQEPKcS2_PKwS4__ZN7testing8internal6IsTrueEbtear_down_tc_ZNSt12_Vector_baseIN7testing14TestPartResultESaIS1_EE17_M_create_storageEj_ZNSt6vectorIPN7testing8TestInfoESaIS2_EE6resizeEjS2__ZN7testing8internal17StreamingListener6SendLnERKSs_ZNK9__gnu_cxx17__normal_iteratorIPKN7testing14TestPartResultESt6vectorIS2_SaIS2_EEEplEi_ZNK7testing8TestCase19disabled_test_countEv_ZNKSbIwSt11char_traitsIwESaIwEE4_Rep12_M_is_leakedEv_ZNK9__gnu_cxx17__normal_iteratorIPKPN7testing8TestInfoESt6vectorIS3_SaIS3_EEE4baseEv_ZNSt17_Rb_tree_iteratorISsEmmEi_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE10_S_maximumEPSt18_Rb_tree_node_base_ZN7testing8TestCase18GetMutableTestInfoEi_ZNK9__gnu_cxx17__normal_iteratorIPKPN7testing8TestInfoESt6vectorIS3_SaIS3_EEEplEiBaseholder_base_ZNSt17_Rb_tree_iteratorISsEmmEv_ZNSt12__alloc_swapISaISsELb1EE8_S_do_itERS0_S2_argumentpartial_regex__ZN7testing8internal19TypedTestCasePState11AddTestNameEPKciS3_S3_ConcatPaths_ZN7testing8internal15TestFactoryBase10CreateTestEv__pointer_ZN7testing8internal35DefaultGlobalTestPartResultReporterD2Evtestsnegative_ZN9__gnu_cxx14__alloc_traitsISaIPN7testing8internal29ParameterizedTestCaseInfoBaseEEE10_S_on_swapERS5_S7__ZN9__gnu_cxx13new_allocatorIN7testing8internal9TraceInfoEE9constructEPS3_RKS3__S_boolalpha_ZNSbIwSt11char_traitsIwESaIwEE6assignEjw_ZNK7testing8internal12UnitTestImpl17test_to_run_countEvtest_shard_file__uninit_copy__initialize_pAppendMessage_ZN9__gnu_cxx14__alloc_traitsISaISsEE10_S_on_swapERS1_S3_targetmutex_arg_string_ZN7testing8TestCase12ShuffleTestsEPNS_8internal6RandomE_ZNK7testing8UnitTest17test_to_run_countEv_ZN7testing8internal27OsStackTraceGetterInterface17CurrentStackTraceEii__copy_move_backward_anew_allocatortest_info_listHONOR_SHARDING_PROTOCOL_ZNSt6vectorIN7testing14TestPartResultESaIS1_EE4backEv_ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EE4rendEvelapsed_time__ZNSt6vectorIPN7testing11EnvironmentESaIS2_EE4dataEv_ZNKSt6vectorIPN7testing8TestInfoESaIS2_EE4backEv_ZNSt6vectorIN7testing14TestPartResultESaIS1_EE5eraseEN9__gnu_cxx17__normal_iteratorIPS1_S3_EES7_execveg_in_fast_death_test_childTestPropertiesAsXmlAttributesdummy__ZN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEED2Ev_ZN7testing8internal20StringStreamToStringEPSt18basic_stringstreamIcSt11char_traitsIcESaIcEEstream_name_ZN9__gnu_cxx13new_allocatorIiE10deallocateEPij_Pointer_Rb_tree_insert_and_rebalance_ZNSt11char_traitsIwE6assignERwRKwuninitialized_copyin_subprocess_for_death_testpthread_mutexattr_t_ZNK9__gnu_cxx13new_allocatorIPKcE7addressERS2_for_each > >, void (*)(testing::Environment*)>_ZN9__gnu_cxx17__normal_iteratorIPN7testing14TestPartResultESt6vectorIS2_SaIS2_EEEmIEifound_Destroy_ZNK9__gnu_cxx17__normal_iteratorIPPN7testing8TestCaseESt6vectorIS3_SaIS3_EEEdeEv_ZN7testing8internal29ParameterizedTestCaseInfoBase13RegisterTestsEvShouldUseColorcopy_backwarditerator_categoryPrintXmlUnitTest_S_eofbit_ZN7testing8internal17TestEventRepeater16OnTestPartResultERKNS_14TestPartResultEoperator<< _Iter_predfailed_test_countassertion_result_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE8_S_valueEPKSt13_Rb_tree_nodeISsE__nusersconst_iterator_ZNKSt12_Vector_baseIPN7testing8TestInfoESaIS2_EE13get_allocatorEv_M_capacityTestCaseoperator== >~Init_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE7_S_leftEPKSt18_Rb_tree_node_baseFILE_filenoDoubleLEoperator|=severity_ZNKSt6vectorIPN7testing11EnvironmentESaIS2_EEixEj_ZNSt11char_traitsIcE6assignERcRKcCaptureStderrallocator_ZNK7testing8internal8FilePath19RemoveDirectoryNameEvCreateTest~TestPartResult_ZNK7testing8internal13FloatingPointIdE6is_nanEvoperator<< _ZN7testing8internal18StreamableToStringIPcEESsRKT__ZNKSt6vectorIN7testing12TestPropertyESaIS1_EE5beginEv_ZN9__gnu_cxx17__normal_iteratorIPKPN7testing11EnvironmentESt6vectorIS3_SaIS3_EEEmIEi_ZN7testing8internal9DeathTest10AssumeRoleEv_ZNKSt6vectorIiSaIiEE2atEjHasNonfatalFailureFormatWordListvector >filter_outcome_ZNSt6vectorIiSaIiEE5clearEv_M_color_ZN7testing8TestCase13ShouldRunTestEPKNS_8TestInfoE_ZNK9__gnu_cxx17__normal_iteratorIPPN7testing8TestCaseESt6vectorIS3_SaIS3_EEEixEi_ZNSbIwSt11char_traitsIwESaIwEEaSERKS2__ZN7testing8internal8GTestLog9GetStreamEv_ZN7testing8internal27OsStackTraceGetterInterfaceaSERKS1_internal_flag_ZNSt12_Vector_baseISsSaISsEE11_M_allocateEjignore_sigprof_actionOnTestIterationEnd_ZNKSt6vectorIN7testing12TestPropertyESaIS1_EE5frontEvscoped_ptr_ZNKSs3endEv_ZNK7testing8internal8FilePath6stringEv_ZNSt6vectorIPcSaIS0_EE6assignEjRKS0__ZN9__gnu_cxx13new_allocatorIPN7testing17TestEventListenerEE10deallocateEPS3_j_ZN7testing8internal13FloatingPointIfE38DistanceBetweenSignAndMagnitudeNumbersERKjS4_getpagesize_ZNKSt6vectorIPcSaIS0_EE14_M_range_checkEj_ZNSt6vectorIPcSaIS0_EE14_M_fill_assignEjRKS0__ZNK7testing8internal10scoped_ptrISsEdeEv_ZNSo5writeEPKci_ZN7testing22FLAGS_gtest_list_testsE_ZNKSbIwSt11char_traitsIwESaIwEE16find_last_not_ofERKS2_jctype__socklen_t_ZNSt11char_traitsIwE4moveEPwPKwj_ZNK9__gnu_cxx17__normal_iteratorIPPN7testing11EnvironmentESt6vectorIS3_SaIS3_EEEplEiFloatLEStreamWideCharsToMessage_ZNSt6vectorIN7testing12TestPropertyESaIS1_EE6resizeEjS1__ZN7testing10TestResult26increment_death_test_countEv_ZNSt6vectorIN7testing12TestPropertyESaIS1_EE8_M_eraseEN9__gnu_cxx17__normal_iteratorIPS1_S3_EEoperator==, std::allocator >partial_regexsival_ptrHasSameFixtureClass_Destroyproperty_name_ZNSt6vectorIPN7testing11EnvironmentESaIS2_EE2atEj_M_refcountis_runnable_ZN7testing8internal17TestEventRepeater22OnEnvironmentsSetUpEndERKNS_8UnitTestE_ZNK7testing14TestPartResult4typeEv_ZNK9__gnu_cxx17__normal_iteratorIPPN7testing17TestEventListenerESt6vectorIS3_SaIS3_EEEplEi~TestInfo__dev_t_Base_ptr_ZN7testing8internal17StreamingListener12SocketWriterD2Ev_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE14_M_lower_boundEPSt13_Rb_tree_nodeISsES8_RKSsIsTrue_ZNSt12_Vector_baseIPN7testing17TestEventListenerESaIS2_EE19_M_get_Tp_allocatorEvfilter_M_bump_downfull_pathnameEXECUTE_TESTMSG_ERRQUEUE__uninitialized_copy_a*, std::basic_string*, std::basic_string >new_allocator_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE5eraseESt23_Rb_tree_const_iteratorISsES7__ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EE5eraseEN9__gnu_cxx17__normal_iteratorIPS2_S4_EES8__ZN7testing8internal20ExitedUnsuccessfullyEineedle_ZNKSt6vectorIPN7testing8TestInfoESaIS2_EE4sizeEv_ZN7testing7MessagelsEPKw_Bit_iterator_ZN9__gnu_cxx17__normal_iteratorIPN7testing8internal9TraceInfoESt6vectorIS3_SaIS3_EEEmIEi_ZNK7testing8UnitTest16total_test_countEvper_thread_test_part_result_reporter_fseek~DeathTestFactory_ZN7testing18TestEventListenersC2Evbasic_stringstream, std::allocator >ptrdiff_t_ZN7testing8internal14ShouldUseColorEb_ZN7testing8internal12ShuffleRangeIiEEvPNS0_6RandomEiiPSt6vectorIT_SaIS5_EEset, std::allocator >_Distance_archF_OWNER_PIDwmemmove~TestResultset_outcome__destroy__alloc_traits >_ZNK9__gnu_cxx17__normal_iteratorIPcSsEmiEi_ZSt24__throw_out_of_range_fmtPKczbasic_iostream_ZNSt6vectorIN7testing12TestPropertyESaIS1_EE6insertEN9__gnu_cxx17__normal_iteratorIPS1_S3_EERKS1_GetLastErrnoDescriptionwcrtombwstrclear_ZNKSt6vectorIPN7testing8TestInfoESaIS2_EE3endEv_ZN9__gnu_cxx13new_allocatorIPN7testing8internal29ParameterizedTestCaseInfoBaseEE9constructEPS4_RKS4_failure_ZN9__gnu_cxx13new_allocatorIPN7testing8internal29ParameterizedTestCaseInfoBaseEE10deallocateEPS4_j__check_facet >_ZN7testing8internal17TestEventRepeater18OnTestProgramStartERKNS_8UnitTestE_ZNK9__gnu_cxx17__normal_iteratorIPPN7testing8internal29ParameterizedTestCaseInfoBaseESt6vectorIS4_SaIS4_EEEplEi_ZNK7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEE16GetOrCreateValueEv__espins_ZNSsaSEPKcdefault_result_printer_ZNK9__gnu_cxx17__normal_iteratorIPN7testing8internal9TraceInfoESt6vectorIS3_SaIS3_EEEplEi_ZNSbIwSt11char_traitsIwESaIwEE3endEvrm_eo_ZN7testing8TestCase19ClearTestCaseResultEPS0_operator<< _ZNSs14_M_replace_auxEjjjcWriteToShardStatusFileIfNeeded_Rep_baseenv_varvalue_holderfirst_test_info_ZNSspLEckPrintTimeFlag_ZNSt3setIPKcSt4lessIS1_ESaIS1_EE6insertESt23_Rb_tree_const_iteratorIS1_ERKS1__ZN7testing10TestResult20ClearTestPartResultsEv__copy_move_backward_anew_allocator, std::allocator > >MSG_FINreverse_iterator<__gnu_cxx::__normal_iterator > > >st_atim_ZN7testing11Environment5SetUpEvst_dev_ZNSt6vectorIPN7testing11EnvironmentESaIS2_EE14_M_fill_insertEN9__gnu_cxx17__normal_iteratorIPS2_S4_EEjRKS2__ZN9__gnu_cxx17__normal_iteratorIPKN7testing14TestPartResultESt6vectorIS2_SaIS2_EEEmIEi__is_signedcountsCloseConnection__state_ZNKSt3setISsSt4lessISsESaISsEE4sizeEv_ZN7testing18TestEventListeners6AppendEPNS_17TestEventListenerEfirst_ZNSt6vectorIPN7testing8TestInfoESaIS2_EE15_M_erase_at_endEPS2__ZN9__gnu_cxx24__numeric_traits_integerIcE5__maxE_ZNKSbIwSt11char_traitsIwESaIwEE17find_first_not_ofEPKwjjInit_ZN7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEE7pointerEvGetTestCaseName_ZNKSt14_Bit_referenceeqERKS__ZNKSbIwSt11char_traitsIwESaIwEE5emptyEvMSG_CTRUNC__normal_iterator > >_ZNK9__gnu_cxx17__normal_iteratorIPKPN7testing11EnvironmentESt6vectorIS3_SaIS3_EEEptEv__alloc_traits >_ZN7testing8internal2REaSERKS1__ZN7testing8internal12UnitTestImpl17gtest_trace_stackEvnum_failuresenvironments_Delete__copy_move_b_M_insert_ZN9__gnu_cxx13new_allocatorIwE10deallocateEPwj_ZN7testing8internal10scoped_ptrIKSsEaSERKS3__ZN9__gnu_cxx14__alloc_traitsISaIPN7testing8TestCaseEEE7destroyERS4_PS3_PrintTestPartResult__copy_move_backward_a2*, std::basic_string*>_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE11equal_rangeERKSsgtest_ar__Identity, std::allocator > >AlwaysTrueoperator<< >set_current_test_infoTEST_DID_NOT_DIEwcscollopenmode_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE11_M_leftmostEvvalue_~TestPropertyoperator!= >_ZN7testing8internal27FormatTimeInMillisAsSecondsEx_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE13_Rb_tree_implIS3_Lb0EE13_M_initializeEv__last_ZNK9__gnu_cxx17__normal_iteratorIPKPN7testing8TestInfoESt6vectorIS3_SaIS3_EEEdeEv_ZNK9__gnu_cxx17__normal_iteratorIPKSsSt6vectorISsSaISsEEEptEv_ZNK7testing8internal12UnitTestImpl30reportable_disabled_test_countEvOnTestCaseStart__prioritydeath_test_style_kCatchExceptionsFlag_ZNSs12_S_constructEjcRKSaIcE__addressofuninitialized_copy*>ForkingDeathTestdeath_test_factory_ZN9__gnu_cxx14__alloc_traitsISaIN7testing14TestPartResultEEE8max_sizeERKS3_OsStackTraceGetterInterface_ZNSs7_M_moveEPcPKcj__copy_move_backward_a_ZNSt18_Rb_tree_node_base10_S_minimumEPKS_ParameterizedTestCaseRegistry_ZNSt12_Vector_baseIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE13_M_deallocateEPS3_j__time_t_ZN7testing8internal17StreamingListener20AbstractSocketWriteraSERKS2_signumMutexpathname__miter_base*>_ZN7testing8TestCase3RunEv_ZNKSbIwSt11char_traitsIwESaIwEE7compareEjjRKS2_jj_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE8_S_valueEPKSt18_Rb_tree_node_baseFloatingPoint_ZN9__gnu_cxx14__alloc_traitsISaIPN7testing17TestEventListenerEEE17_S_select_on_copyERKS4_fgetwc_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE4swapERS5__ZN7testing8internal12UnitTestImpl18GetMutableTestCaseEi_ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EE4rendEv_ZNKSt6vectorIN7testing8internal9TraceInfoESaIS2_EE6rbeginEv_ZNSt6vectorIN7testing12TestPropertyESaIS1_EE4dataEvrelease_ZNSt6vectorIPN7testing11EnvironmentESaIS2_EE6insertEN9__gnu_cxx17__normal_iteratorIPS2_S4_EERKS2__ZNK7testing8internal12UnitTestImpl26successful_test_case_countEvnew_allocator_ZN9__gnu_cxx17__normal_iteratorIPKN7testing14TestPartResultESt6vectorIS2_SaIS2_EEEmmEiParseBoolFlagParseInt32OnTestStartread_fd__ZN7testing8internal27PrettyUnitTestResultPrinter18OnTestIterationEndERKNS_8UnitTestEistrstrcolor__ZN9__gnu_cxx17__normal_iteratorIPKN7testing14TestPartResultESt6vectorIS2_SaIS2_EEEmmEv_ZNSs6resizeEj__vtbl_ptr_typeGTestIsInitialized_Is_pod_comparator__destroy_ZN7testing19FLAGS_gtest_shuffleEGetInjectableArgvsFormatDeathTestOutput_ZNKSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE11equal_rangeERKSs_ZNSbIwSt11char_traitsIwESaIwEEaSEwunary_function, std::allocator >, std::basic_string, std::allocator > >puts_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE7_S_leftEPSt18_Rb_tree_node_base__gnuc_va_listdeath_test_factory__ZNKSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE8_M_beginEv__builtin_memmoveGetOrCreateValue_ZNK7testing8internal8FilePath15DirectoryExistsEvThreadLocal_ZN9__gnu_cxx14__alloc_traitsISaIPcEE7destroyERS2_PS1__ZNKSt6vectorIN7testing14TestPartResultESaIS1_EE3endEv_ZNSt23_Rb_tree_const_iteratorIPKcEmmEiAbortSingleFailureChecker_ZN7testing11IsSubstringEPKcS1_RKSsS3__flags2_ZNSt23_Rb_tree_const_iteratorIPKcEmmEv_ZNKSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE21_M_get_Node_allocatorEv~HasNewFatalFailureHelper_ZN9__gnu_cxx14__alloc_traitsISaIPN7testing8TestInfoEEE8max_sizeERKS4__flagsthisbasic_ostream >_ZNKSt6vectorIPN7testing11EnvironmentESaIS2_EE4dataEv_ZNSt6vectorIPN7testing8TestInfoESaIS2_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS2_S4_EERKS2__ZStplIcSt11char_traitsIcESaIcEESbIT_T0_T1_EPKS3_RKS6__ZNK9__gnu_cxx17__normal_iteratorIPSsSt6vectorISsSaISsEEEplEiclose_fd_ZN9__gnu_cxx17__normal_iteratorIPPN7testing17TestEventListenerESt6vectorIS3_SaIS3_EEEppEikDeathTestInternalErrorrandom___is_move_iterator_ZN7testing8internal30ReportFailureInUnknownLocationENS_14TestPartResult4TypeERKSs_ZNSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE3endEv_ZNK9__gnu_cxx13new_allocatorISt13_Rb_tree_nodeIPKcEE7addressERKS4__ZNK7testing8UnitTest6FailedEv_ZN9__gnu_cxx13new_allocatorISt13_Rb_tree_nodeIPKcEE8allocateEjPKvtest_casesrcfile__miter_basewmemchr_ZN7testing18TestEventListeners8repeaterEvIsPrintableAsciiGetTypeId_ZNK9__gnu_cxx17__normal_iteratorIPPcSt6vectorIS1_SaIS1_EEEmiEiiswctypethis_is_TEST_ZNKSt9basic_iosIcSt11char_traitsIcEE7rdstateEv_Rb_tree_iterator__builtin_strlen_ZNKSs4copyEPcjj_ZN9__gnu_cxx14__alloc_traitsISaIPN7testing8TestInfoEEE10deallocateERS4_PS3_j__is_normal_iterator, std::allocator >*>__uninitialized_copy_ZN7testing8internal15NoExecDeathTest10AssumeRoleEv_ZN7testing15AssertionResultaSERKS0__ZNK9__gnu_cxx17__normal_iteratorIPN7testing12TestPropertyESt6vectorIS2_SaIS2_EEEplEicatch_exceptions__ZN7testing11Environment5SetupEv__ssize_t__niter_base<__gnu_cxx::__normal_iterator > >_ZNKSt6vectorIPN7testing8TestInfoESaIS2_EE8max_sizeEv_InIteratorseedgtest_msgallocator_ZN7testing8internal16UniversalPrinterIxE5PrintERKxPSo_ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EE5eraseEN9__gnu_cxx17__normal_iteratorIPS2_S4_EES8_chdirsival_intstrtod_ZNK7testing8TestCase21successful_test_countEvStreamableToString_ZNKSbIwSt11char_traitsIwESaIwEE4findEPKwjReportInvalidTestCaseTypeUnsignedChar_ZN7testing8internal10scoped_ptrINS0_17StreamingListener20AbstractSocketWriterEE7releaseEv_ZN7testing8internal17StreamingListenerD2Ev_ZNKSs16find_last_not_ofEcjPatternMatchesStringgtest_retval_ZN7testing8internal18StringFromGTestEnvEPKcS2_Fromstrlen_ZN7testing8internal13FloatingPointIfE15ReinterpretBitsEjstack_top_ZN7testing8internal38DefaultPerThreadTestPartResultReporter20ReportTestPartResultERKNS_14TestPartResultEPrintOnOneLinebasic_iostream >_ZNKSbIwSt11char_traitsIwESaIwEE4findEwj_ZNSs6insertEjjc__fmtkFractionBitMaskUnitTestImpl_ZN7testing22EmptyTestEventListener18OnTestIterationEndERKNS_8UnitTestEi_ZNSbIwSt11char_traitsIwESaIwEE4_Rep13_M_set_leakedEv_ZN7testing8internal29ParameterizedTestCaseRegistry13RegisterTestsEv_ZNKSt6vectorIPcSaIS0_EE4rendEvkSuccessOutputXmlCDataSectionGetCapturedStreamRemoveFileName__uninitialized_move_if_noexcept_a >_ZNSbIwSt11char_traitsIwESaIwEE2atEj_ZNSbIwSt11char_traitsIwESaIwEEixEj_ZNSbIwSt11char_traitsIwESaIwEE6insertEjPKw_ZNSt23_Rb_tree_const_iteratorISsEmmEiparse_success_ZNSbIwSt11char_traitsIwESaIwEE7replaceEN9__gnu_cxx17__normal_iteratorIPwS2_EES6_PKwS8_DeathTestAbort_ZNSt23_Rb_tree_const_iteratorISsEmmEvcoloncolor__uninitialized_move_if_noexcept_a >_vptr.Environment_Destroybasefield_ZNSt11char_traitsIcE7compareEPKcS2_j_ZN7testing8internal14CmpHelperSTREQEPKcS2_S2_S2__ZNSt6vectorIPN7testing11EnvironmentESaIS2_EE4backEvreverse_iterator<__gnu_cxx::__normal_iterator > > >RemoveDirectoryName_ZN7testing8internal21ImplicitlyConvertibleIPKvS3_E6HelperES3__Rep_typeis_disabled~basic_ios__niter_base_ZNSt12_Vector_baseIPN7testing8TestInfoESaIS2_EE13_M_deallocateEPS2_jcontentShouldRunTestReportTestPartResultcurrent_ZNSt6vectorIN7testing14TestPartResultESaIS1_EE2atEj__normal_iterator > >_ZN9__gnu_cxx17__normal_iteratorIPKN7testing8internal9TraceInfoESt6vectorIS3_SaIS3_EEEppEi_ZNK9__gnu_cxx17__normal_iteratorIPKN7testing14TestPartResultESt6vectorIS2_SaIS2_EEEmiEi_ZNKSt23_Rb_tree_const_iteratorISsEdeEv_ZNKSt6vectorIPN7testing8TestInfoESaIS2_EE6rbeginEv_M_fill_insertbasic_stringbufAddTestName_ZN9__gnu_cxx17__normal_iteratorIPKN7testing8internal9TraceInfoESt6vectorIS3_SaIS3_EEEppEvnothrow_ZNK9__gnu_cxx17__normal_iteratorIPKPN7testing8TestInfoESt6vectorIS3_SaIS3_EEEmiEiis_spawnedoperator<< _ZN7testing8internal23DefaultDeathTestFactoryD0Evvector >_ZNSs5eraseEN9__gnu_cxx17__normal_iteratorIPcSsEES2_Argvoperator<< _ZN7testing8internal27PrettyUnitTestResultPrinter16OnTestPartResultERKNS_14TestPartResultE_ZSt19__throw_logic_errorPKc__prec__pred_ZNKSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE8_M_beginEv_ZN7testing4Test16TearDownTestCaseEv_ZNSt12_Vector_baseIPN7testing8TestInfoESaIS2_EE19_M_get_Tp_allocatorEvSecretSOCK_DCCP_ZNK9__gnu_cxx17__normal_iteratorIPPN7testing17TestEventListenerESt6vectorIS3_SaIS3_EEEptEv_Ios_OpenmodeDelete_ZN7testing4Test5SetUpEv_ZN7testing18TestEventListenersaSERKS0__ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE11_M_put_nodeEPSt13_Rb_tree_nodeISsE_ZNSs6appendEPKc_S_cur_ZNKSt6vectorIPN7testing11EnvironmentESaIS2_EE14_M_range_checkEjshowposSetUpTestCasestdin__pthread_slist_t_ZNKSs4_Rep12_M_is_sharedEv_ZNSt11char_traitsIcE12to_char_typeERKi_ZNKSt6vectorIPN7testing11EnvironmentESaIS2_EE12_M_check_lenEjPKc_ZNSolsEPFRSt8ios_baseS0_E_ZN7testing15AssertionResultlsEPFRSoS1_E_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE5eraseEPKS1_S9_GetFileSize_ZNSt6vectorISsSaISsEE4rendEv_ZN9__gnu_cxx14__alloc_traitsISaIPKcEE8allocateERS3_j_ZNKSbIwSt11char_traitsIwESaIwEE15_M_check_lengthEjjPKc_ZNKSt23_Rb_tree_const_iteratorISsEeqERKS0__ZN7testing8internal27CheckedDowncastToActualTypeINS0_11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE11ValueHolderENS0_26ThreadLocalValueHolderBaseEEEPT_PT0__ZNK9__gnu_cxx13new_allocatorIiE8max_sizeEvvfwscanf_ZNKSbIwSt11char_traitsIwESaIwEE13find_first_ofEPKwjj_ZNSbIwSt11char_traitsIwESaIwEE4_Rep10_M_destroyERKS1_reverse_iterator<__gnu_cxx::__normal_iterator > > >_ZSt17__throw_bad_allocv_ZNKSt12_Vector_baseIN7testing14TestPartResultESaIS1_EE13get_allocatorEvdummyatoll_ZNSo9_M_insertImEERSoT_num_selected_tests_ZNKSbIwSt11char_traitsIwESaIwEE4copyEPwjjoperator<< _ZNSt12_Vector_baseIiSaIiEE17_M_create_storageEjfind<__gnu_cxx::__normal_iterator*, std::vector > >, std::basic_string >_ZNKSt6vectorIiSaIiEE4backEvbuffershort intsnprintf_ZNKSbIwSt11char_traitsIwESaIwEE5c_strEvwmemcpy~FilePathcurrent_test_info_ZNK7testing8internal13DeathTestImpl8write_fdEvForEach, void (*)(testing::Environment*)>_ZN7testing8internal13FloatingPointIdE15ReinterpretBitsEy_Iter_basefind_last_not_of_ZNSt6vectorIN7testing12TestPropertyESaIS1_EE6rbeginEv_ZNK7testing10TestResult12elapsed_timeEv_ZNKSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE7_M_rootEv_ZNKSt6vectorIPN7testing8TestCaseESaIS2_EE3endEvuninitialized_copy<__gnu_cxx::__normal_iterator >, testing::internal::TraceInfo*>ThreadLocalValueHolderBase__normal_iterator, std::allocator > >sa_flagstestoperator<< GetCapturedStderr_ZN9__gnu_cxx17__normal_iteratorIPPN7testing11EnvironmentESt6vectorIS3_SaIS3_EEEppEv_ZNKSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE14_M_upper_boundEPKSt13_Rb_tree_nodeISsES9_RKSs_ZNSbIwSt11char_traitsIwESaIwEE4_Rep10_M_refdataEvNoExecDeathTest_ZNSt6vectorISsSaISsEE5beginEv_ZNKSs8_M_checkEjPKc_ZNSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE6resizeEjS3__vptr.DeathTestFactorybasic_istream_ZNSt12_Vector_baseIN7testing8internal9TraceInfoESaIS2_EE11_M_allocateEj_ZNK9__gnu_cxx17__normal_iteratorIPKcSsEixEi__exchange_and_add_dispatchReseed_ZNK9__gnu_cxx17__normal_iteratorIPKPN7testing17TestEventListenerESt6vectorIS3_SaIS3_EEEptEvcopy_backwardconstructParseFlagValue_ZN7testing8internal24XmlUnitTestResultPrinterD0Ev_ZNK9__gnu_cxx17__normal_iteratorIPKcSsE4baseEv_Construct, std::basic_string >_ZNKSt6vectorIN7testing8internal9TraceInfoESaIS2_EE2atEj_ZNSbIwSt11char_traitsIwESaIwEE4rendEv_ZN7testing8internal18CmpHelperSTRCASENEEPKcS2_S2_S2__ZN7testing8internal17GetCapturedStdoutEv__iterator_category<__gnu_cxx::__normal_iterator > >PushGTestTrace_ZN7testing8internal17TestEventRepeater24OnEnvironmentsSetUpStartERKNS_8UnitTestE_ZN9__gnu_cxx13new_allocatorIcE8allocateEjPKvAssertionResult_ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EE5beginEvuninitialized_copy_ZN9__gnu_cxx14__alloc_traitsISaISsEE17_S_select_on_copyERKS1_operator- >dup2rbegin__gthread_active_pnames_ZNSbIwSt11char_traitsIwESaIwEE6insertEjPKwj_ZNK9__gnu_cxx17__normal_iteratorIPN7testing12TestPropertyESt6vectorIS2_SaIS2_EEE4baseEv_ZNSt12_Vector_baseIPN7testing8TestCaseESaIS2_EE12_Vector_impl12_M_swap_dataERS5_CountIf, bool (*)(const testing::TestCase*)>_sigchldoutput_file_vptr.ParameterizedTestCaseInfoBase__uid_tGTEST_SHARD_STATUS_FILEerrorPrintXmlTestCase_ZN9__gnu_cxx17__normal_iteratorIPKcSsEppEicode_point_ZNSs6assignERKSsjj_ZNKSt6vectorIiSaIiEE4sizeEv_ZNSt10_Iter_baseIPN7testing8internal9TraceInfoELb0EE7_S_baseES3_mon_thousands_sep_ZN7testing8UnitTest13PopGTestTraceEv_ZN9__gnu_cxx17__normal_iteratorIPKcSsEppEv_ZNKSt6vectorIPN7testing17TestEventListenerESaIS2_EEixEj_ZNK7testing18TestEventListeners22default_result_printerEv_ZNK9__gnu_cxx17__normal_iteratorIPPN7testing17TestEventListenerESt6vectorIS3_SaIS3_EEEmiEiLogToStderrwcscatUponLeavingGTest_Vector_base >_ZNSo9_M_insertIxEERSoT__ZN7testing8internal9DeathTest27set_last_death_test_messageERKSs_ZNSbIwSt11char_traitsIwESaIwEE7replaceEjjRKS2_MutexLock_ZNSt6vectorIPN7testing8TestInfoESaIS2_EE4backEvrepeater__Const_Base_ptroperator!= >getcwdSendLn_ZN7testing8internal28ParseGoogleTestFlagsOnlyImplIwEEvPiPPT__ZNSt3setISsSt4lessISsESaISsEEaSERKS3_set_os_stack_trace_getter_ZNKSt23_Rb_tree_const_iteratorISsEneERKS0__ZN7testing8internal15UnitTestOptions27GetAbsolutePathToOutputFileEv_ZNK9__gnu_cxx17__normal_iteratorIPKN7testing14TestPartResultESt6vectorIS2_SaIS2_EEE4baseEv__normal_iterator > >pair, bool>repeaterbasic_stringstatus_valuePrintTestPartResultToStringa_name_ZNSt6vectorIPN7testing8TestCaseESaIS2_EE6insertEN9__gnu_cxx17__normal_iteratorIPS2_S4_EEjRKS2__ZNKSsixEj_ZNSs7replaceEN9__gnu_cxx17__normal_iteratorIPcSsEES2_S1_S1__ZNK9__gnu_cxx13new_allocatorIcE8max_sizeEv_ZN7testing8internal21UniversalTersePrinterIxE5PrintERKxPSo_ZN7testing8internal14GetThreadCountEvreplace_ZNSbIwSt11char_traitsIwESaIwEE18_S_construct_aux_2EjwRKS1_XmlUnitTestResultPrinter_ZNK9__gnu_cxx17__normal_iteratorIPcSsEptEv_ZN7testing8internal2RE4InitEPKc_ZNK9__gnu_cxx13new_allocatorIPN7testing11EnvironmentEE7addressERKS3_AppendUserMessageUniversalTersePrinter_ZNKSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE13get_allocatorEv_ZNKSs7compareEjjPKc__suseconds_t_ZNK9__gnu_cxx17__normal_iteratorIPKPN7testing8TestCaseESt6vectorIS3_SaIS3_EEEmiEi_ZN9__gnu_cxx24__numeric_traits_integerIsE5__minE_ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EE5clearEvshuffle_RandomAccessIterator_ZN9__gnu_cxx14__alloc_traitsISaIiEE7destroyERS1_Pi_ZNSbIwSt11char_traitsIwESaIwEE13_S_copy_charsEPwN9__gnu_cxx17__normal_iteratorIS3_S2_EES6_PrintColorEncoded_M_is_sharediterator_traits_ZN7testing8internal27PrettyUnitTestResultPrinter16OnTestProgramEndERKNS_8UnitTestE_ZNK9__gnu_cxx17__normal_iteratorIPPN7testing8internal29ParameterizedTestCaseInfoBaseESt6vectorIS4_SaIS4_EEEmiEi_ZNSt6vectorIiSaIiEE18_M_fill_initializeEjRKi_ZNSt6vectorISsSaISsEE14_M_fill_assignEjRKSsscoped_ptr_ZN7testing8internal17kStackTraceMarkerE_ZN7testing8internal12UnitTestImpl11GetTestCaseEPKcS3_PFvvES5_premature_exit_filepath__S_constructparameterized_test_registry_ZN7testing8internal6Random8GenerateEj_ZN9__gnu_cxx17__normal_iteratorIPKPN7testing8TestInfoESt6vectorIS3_SaIS3_EEEppEi_Vector_baseiterator_traits<__gnu_cxx::__normal_iterator > > >_ZN7testing18FLAGS_gtest_filterE_ZNK9__gnu_cxx17__normal_iteratorIPN7testing8internal9TraceInfoESt6vectorIS3_SaIS3_EEEmiEi__copy_m_ZN9__gnu_cxx17__normal_iteratorIPKPN7testing8TestInfoESt6vectorIS3_SaIS3_EEEppEva_message__are_same_ZNSt6vectorIPcSaIS0_EE18_M_fill_initializeEjRKS0_TestCaseNameIs_M_insert_M_mask_ZN7testing8internal10scoped_ptrIKSsE7releaseEvis_reportableTestReportableDisabled_ZNK9__gnu_cxx17__normal_iteratorIPiSt6vectorIiSaIiEEE4baseEvreverse_iterator<__gnu_cxx::__normal_iterator, std::allocator > > >_ZN9__gnu_cxx13new_allocatorIPN7testing8TestCaseEE10deallocateEPS3_j_ZNSbIwSt11char_traitsIwESaIwEE9_M_mutateEjjj_ZN7testing4Test3RunEvIsSubstring_ZSt9__find_ifIN9__gnu_cxx17__normal_iteratorIPN7testing12TestPropertyESt6vectorIS3_SaIS3_EEEENS0_5__ops10_Iter_predINS2_8internal17TestPropertyKeyIsEEEET_SE_SE_T0_St26random_access_iterator_tagallocator_typeSetUp__comp_ZN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE7pointerEvpthread_mutex_lockassignrandom_seed__ZN7testing8internal15UnitTestOptions15GetOutputFormatEv_ZSt4cerr_ZNSbIwSt11char_traitsIwESaIwEE7_M_dataEPwfilefillCurrentOsStackTraceExceptTop_ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EE5eraseEN9__gnu_cxx17__normal_iteratorIPS2_S4_EE_ZN7testing8internal35DefaultGlobalTestPartResultReporter20ReportTestPartResultERKNS_14TestPartResultE_ZNSt12_Vector_baseIPN7testing8TestCaseESaIS2_EE17_M_create_storageEj_ZN7testing15AssertionResultlsIPKcEERS0_RKT__ZNSt12_Vector_baseIPcSaIS0_EE13_M_deallocateEPS0_j_exit_ZN7testing11IsSubstringEPKcS1_PKwS3_DistanceBetweenSignAndMagnitudeNumbers_ZNK7testing14TestPartResult6failedEvImplicitlyConvertible_ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EE6assignEjRKS2__ZN7testing8internal27PrettyUnitTestResultPrinter16PrintFailedTestsERKNS_8UnitTestE_ZNSt6vectorIPN7testing11EnvironmentESaIS2_EE8_M_eraseEN9__gnu_cxx17__normal_iteratorIPS2_S4_EES8__ZNKSt6vectorIPN7testing17TestEventListenerESaIS2_EE12_M_check_lenEjPKcerror_num_M_initialize_dispatch10regmatch_t_ZN7testing17TestEventListener15OnTestCaseStartERKNS_8TestCaseE_ZN7testing19TestPartResultArray6AppendERKNS_14TestPartResultE_S_red~ThreadLocalValueHolderBase_ZN9__gnu_cxx14__alloc_traitsISaIPKcEE10_S_on_swapERS3_S5__ZNK9__gnu_cxx13new_allocatorIN7testing12TestPropertyEE7addressERS2__ZN7testing10TestResult16set_elapsed_timeExarguments_ZN9__gnu_cxx24__numeric_traits_integerIiE5__maxEoperator!= >_ZNSt6vectorIN7testing12TestPropertyESaIS1_EE5beginEvgtest_error_ZNSbIwSt11char_traitsIwESaIwEEpLERKS2__ZN7testing8internal20DoubleNearPredFormatEPKcS2_S2_ddd_ZN7testing8internal8GTestLogaSERKS1__ZN7testing8internal35HandleExceptionsInMethodIfSupportedINS0_12UnitTestImplEbEET0_PT_MS4_FS3_vEPKcClearTestCaseResult_M_insert_aux~TraceInfo_ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS2_S4_EERKS2_state__S_adjustfield~AssertHelperData_ZNSt10_Iter_baseIPPN7testing8TestInfoELb0EE7_S_baseES3_ai_protocol_ZN7testing8internal16UniversalPrinterISbIwSt11char_traitsIwESaIwEEE5PrintERKS5_PSoTestInfo_Iter_base_vptr.OsStackTraceGetterInterfacefind_ZN7testing8internal8FilePath12MakeFileNameERKS1_S3_iPKc_ZN9__gnu_cxx14__alloc_traitsISaIPN7testing8TestCaseEEE17_S_select_on_copyERKS4__ZN7testing8internal8FilePath13GetCurrentDirEvparsedgetenv_ZNSt17_Rb_tree_iteratorIPKcEppEiParseGoogleTestFlagsOnlyImplintercept_mode__ZN7testing8internal10SkipPrefixEPKcPS2__Bit_iterator_base_ZNSt17_Rb_tree_iteratorIPKcEppEv_ZNK7testing12TestProperty5valueEv__wide_IO_read_endHandleExceptionsInMethodIfSupported_ZNK7testing8internal10scoped_ptrINS0_17StreamingListener20AbstractSocketWriterEEptEvwcschrIsSubstringPred >__builtin_va_list_ZNKSt3setISsSt4lessISsESaISsEE13get_allocatorEv__cxa_allocate_exceptionoperator new []val2_ss_ZNSt14_Bit_referenceaSEbpathname__ZNKSt6vectorISsSaISsEE5emptyEvstream_result_to__copy_m_S_minimumnew_allocator_ZNK7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEE3getEvIsXDigit_IO_FILE_ZN7testing8internal24InternalRunDeathTestFlagaSERKS1_uninitialized_copy_ZNKSt6vectorIN7testing8internal9TraceInfoESaIS2_EE4rendEv_ZN7testing8internal24GetCurrentExecutableNameEv_ZNKSt6vectorIPN7testing11EnvironmentESaIS2_EE2atEj__statbufis_previous_hex_ZN7testing22EmptyTestEventListener11OnTestStartERKNS_8TestInfoE_ZNKSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE13get_allocatorEvservinfo__false_typewcsrchr__uninitialized_move_if_noexcept_a*, std::basic_string*, std::allocator > >_ZN9__gnu_cxx13new_allocatorIPN7testing8TestCaseEE8allocateEjPKv__is_null_pointerbiased1biased2_ZNKSbIwSt11char_traitsIwESaIwEE12find_last_ofERKS2_jValueHolder_ZNK7testing8internal13DeathTestImpl9statementEv_ZNSt6vectorISsSaISsEEaSERKS1_PrintWideStringTo_Vector_base >bool_valuepattern_ZN7testing22EmptyTestEventListener9OnTestEndERKNS_8TestInfoE_ZNKSt17_Rb_tree_iteratorISsEptEv_ZN7testing22EmptyTestEventListener15OnTestCaseStartERKNS_8TestCaseE_ZNKSt13_Bit_iteratorplEi__is_move_iterator__alloc_traits >IsATTY~basic_stringstream_ZN9__gnu_cxx13new_allocatorIN7testing14TestPartResultEE7destroyEPS2__ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE13_M_clone_nodeEPKSt13_Rb_tree_nodeISsE_M_const_castlldiv_ZN7testing8internal9MutexBase4LockEv_ZN7testing8internal12UnitTestImpl41GetTestPartResultReporterForCurrentThreadEvstatus_ch_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE6_M_endEvSuppressEventForwardingoperator<< >adjustfield_ZNSt6vectorIN7testing14TestPartResultESaIS1_EE14_M_fill_assignEjRKS1__ZNKSbIwSt11char_traitsIwESaIwEE12find_last_ofEPKwjwctomb_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE6_S_keyEPKSt18_Rb_tree_node_baseIsSubstringImplsi_utimeUniversalTersePrinter_Key_compare_ZN7testing8internal6String15ShowWideCStringEPKwswscanfwcscspn_ZN7testing8internal9DeathTest6PassedEbhaystack_exprtest_case_nameformatiterator_traitsDISABLED_*:*/DISABLED_*Clear_ZNSt6vectorIPN7testing8TestInfoESaIS2_EE6insertEN9__gnu_cxx17__normal_iteratorIPS2_S4_EEjRKS2___uninitialized_copy_a_ZN9__gnu_cxx17__normal_iteratorIPKPN7testing8TestCaseESt6vectorIS3_SaIS3_EEEppEi_ZNK9__gnu_cxx17__normal_iteratorIPSsSt6vectorISsSaISsEEEmiEi_Funct_ZNK7testing8internal13FloatingPointIfE4bitsEv_ZN9__gnu_cxx17__normal_iteratorIPKPN7testing8TestCaseESt6vectorIS3_SaIS3_EEEppEv__uninit_copy<__gnu_cxx::__normal_iterator >, testing::internal::TraceInfo*>_S_showbase~basic_istreamconstruct_ZNSbIwSt11char_traitsIwESaIwEE7reserveEj_ZNKSt6vectorIN7testing12TestPropertyESaIS1_EE5emptyEvsigval_t_ZNKSt14_Bit_referencecvbEvsi_bandsigvalGetUnitTestImpl_ZN9__gnu_cxx14__alloc_traitsISaIPN7testing8TestInfoEEE8allocateERS4_jwcscmpsyntax_ValueT_ZNK9__gnu_cxx17__normal_iteratorIPPcSt6vectorIS1_SaIS1_EEEptEv_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE10_M_insert_EPSt18_Rb_tree_node_baseS7_RKSsiterator_traitsGetTestCaseTypeIdstrerrorstderr_ZNSt6vectorIN7testing12TestPropertyESaIS1_EE5clearEv_ZNKSbIwSt11char_traitsIwESaIwEE7compareEjjRKS2__ZNK7testing8internal10scoped_ptrINS0_16DeathTestFactoryEEptEvstreamsize_S_max_size_lock_ZN7testing7MessagelsEb__uninit_copy_ZN9__gnu_cxx13new_allocatorIPcE8allocateEjPKv_ZNK9__gnu_cxx17__normal_iteratorIPKPN7testing8TestCaseESt6vectorIS3_SaIS3_EEE4baseEvInterceptMode10__sigset_t_ZNKSt6vectorIPN7testing11EnvironmentESaIS2_EE5frontEv_ZNSs12_S_empty_repEv_ZNSs6assignEjc_ZNSt6vectorIPN7testing8TestInfoESaIS2_EE8pop_backEv_ZN9__gnu_cxx13new_allocatorIN7testing12TestPropertyEE8allocateEjPKvnum_disabled_ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EEaSERKS4__ZNSt6vectorIPN7testing11EnvironmentESaIS2_EE9push_backERKS2__ZNSt6vectorIPN7testing8TestCaseESaIS2_EE14_M_fill_insertEN9__gnu_cxx17__normal_iteratorIPS2_S4_EEjRKS2__ZN7testing8internal17StreamingListener12SocketWriter4SendERKSs_ZNSolsEPKv_ZNK7testing8internal29ParameterizedTestCaseInfoBase15GetTestCaseNameEv_ZN7testing8internal17TestEventRepeater27OnEnvironmentsTearDownStartERKNS_8UnitTestE_ZN7testing8internal13DeathTestImpl11set_read_fdEi_ZNK7testing15AssertionResultntEvGetCurrentDir__is_normal_iterator_ZNSt18_Bit_iterator_base7_M_incrEivswscanf_ZNSo9_M_insertIdEERSoT__ZNK7testing14TestPartResult7summaryEv__normal_iterator > >_ZNSs5beginEvkMaxStackTraceDepth_ZNSs13_S_copy_charsEPcPKcS1_IGNORE_SHARDING_PROTOCOL_chainDefaultDeathTestFactoryfor_each<__gnu_cxx::__normal_iterator >, void (*)(testing::TestInfo*)>_ZNK7testing8TestCase16total_test_countEv_ZNSt6vectorISsSaISsEE4swapERS1__ZNSs6rbeginEvuninitialized_copy_ZNK7testing8UnitTest12elapsed_timeEv_ZNK9__gnu_cxx17__normal_iteratorIPN7testing8internal9TraceInfoESt6vectorIS3_SaIS3_EEE4baseEv_ZN7testing8internal27PrettyUnitTestResultPrinter13PrintTestNameEPKcS3_wcstollwcsxfrm_ZNKSbIwSt11char_traitsIwESaIwEE5rfindERKS2_jdistance_ZN9__gnu_cxx13new_allocatorIN7testing12TestPropertyEE7destroyEPS2__ZNKSt9_IdentityISsEclERSsleftfmtflagskTestsuitewcscpy_S_maximum_ZNKSt3setISsSt4lessISsESaISsEE10value_compEv_ZNKSt6vectorIN7testing8internal9TraceInfoESaIS2_EE12_M_check_lenEjPKc_ZN7testing11IsSubstringEPKcS1_S1_S1_fflushpair, std::allocator > >, std::_Rb_tree_const_iterator, std::allocator > > >vectorst_blksize_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE6rbeginEvkListTestsFlagreverse_iterator, std::allocator > > >_ZNK7testing12TestProperty3keyEv_ZNK9__gnu_cxx17__normal_iteratorIPPN7testing17TestEventListenerESt6vectorIS3_SaIS3_EEE4baseEv_M_assign_ZNSbIwSt11char_traitsIwESaIwEE4_Rep10_M_refcopyEv_ZN9__gnu_cxx14__alloc_traitsISaISsEE10deallocateERS1_PSsj_ZNKSt12_Vector_baseIN7testing12TestPropertyESaIS1_EE19_M_get_Tp_allocatorEv~PrettyUnitTestResultPrintersa_handlerg_linked_ptr_mutex_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE7_M_rootEv_ZNKSt6vectorIPN7testing11EnvironmentESaIS2_EE4rendEvkMaxRandomSeed_ZN7testing8internal12UnitTestImplaSERKS1_PrintAsCharLiteralTo_ZN7testing8internal10AlwaysTrueEv__mode_ZNSt6vectorIN7testing12TestPropertyESaIS1_EE6insertEN9__gnu_cxx17__normal_iteratorIPS1_S3_EEjRKS1__ZN7testing8internal24XmlUnitTestResultPrinter16PrintXmlTestCaseEPSoRKNS_8TestCaseE_IO_read_ptrset, std::allocator >, std::less, std::allocator > >, std::allocator, std::allocator > > >_ZN7testing13PrintToStringIxEESsRKT__ZN7testing8internal12UnitTestImpl6randomEvconstruct_ZN9__gnu_cxx17__normal_iteratorIPKN7testing8internal9TraceInfoESt6vectorIS3_SaIS3_EEEmmEi_ZNK9__gnu_cxx17__normal_iteratorIPKN7testing14TestPartResultESt6vectorIS2_SaIS2_EEEptEvfalse_type_ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EE4dataEv_ZNSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EEixEj_ZN9__gnu_cxx17__normal_iteratorIPKN7testing8internal9TraceInfoESt6vectorIS3_SaIS3_EEEmmEvHandleSehExceptionsInMethodIfSupported_ZNSbIwSt11char_traitsIwESaIwEE12_S_constructEjwRKS1__M_incr_ZNK7testing8internal13DeathTestImpl5regexEv_ZNK9__gnu_cxx17__normal_iteratorIPKPN7testing8TestInfoESt6vectorIS3_SaIS3_EEEptEv_ZN7testing8TestCase11AddTestInfoEPNS_8TestInfoEPrintBytesInObjectToImpl~allocatorrandom_seed_flag_ZN7testing8internal9DeathTest5AbortENS1_11AbortReasonEshowbase__copy_move_a_ZN7testing4Test19HasSameFixtureClassEvFLAGS_gtest_throw_on_failureAlwaysFalsekSpecialEscape_ZNK9__gnu_cxx17__normal_iteratorIPKPN7testing17TestEventListenerESt6vectorIS3_SaIS3_EEEdeEv_Vector_base >_ZN9__gnu_cxx14__alloc_traitsISaIPN7testing11EnvironmentEEE17_S_select_on_copyERKS4_rebind >_ZN7testing8UnitTest11GetInstanceEv_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE10_S_minimumEPSt18_Rb_tree_node_base_ZNKSt16reverse_iteratorIN9__gnu_cxx17__normal_iteratorIPPN7testing11EnvironmentESt6vectorIS4_SaIS4_EEEEEdeEv_ZN9__gnu_cxx13new_allocatorIPN7testing17TestEventListenerEE7destroyEPS3_new_allocator_ZN7testing8internal12UnitTestImpl17current_test_infoEv_ZNSt3setISsSt4lessISsESaISsEE6insertERKSs_ZNKSs12find_last_ofEPKcjBits__uninitialized_copy_S_fixed_ZNSbIwSt11char_traitsIwESaIwEE7replaceEN9__gnu_cxx17__normal_iteratorIPwS2_EES6_RKS2_UnitTest_ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EE4backEv_ZNK9__gnu_cxx17__normal_iteratorIPKcSsEdeEvmax_size_ZN7testing8internal20SingleFailureCheckeraSERKS1__Traits_ZN7testing8internal9DeathTestaSERKS1_default_valuesigned char_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE11_M_get_nodeEvisattybidirectional_iterator_tag_ZNKSbIwSt11char_traitsIwESaIwEE7compareEjjPKwj_ZN7testing8internal27PrettyUnitTestResultPrinter20OnTestIterationStartERKNS_8UnitTestEiHandleExceptionsInMethodIfSupportedFLAGS_gtest_output_ZN7testing8internal10scoped_ptrINS0_16DeathTestFactoryEEaSERKS3_FloatingPoint__copy_m_ZN9__gnu_cxx14__alloc_traitsISaIPcEE10_S_on_swapERS2_S4_wcspbrka_statement_ZNK9__gnu_cxx17__normal_iteratorIPKPN7testing17TestEventListenerESt6vectorIS3_SaIS3_EEEixEioperator<< Sendsubstr__ZN7testing11IsSubstringEPKcS1_RKSbIwSt11char_traitsIwESaIwEES7_negation_ZNSt11char_traitsIcE2eqERKcS2__ZNKSt16reverse_iteratorIN9__gnu_cxx17__normal_iteratorIPPN7testing11EnvironmentESt6vectorIS4_SaIS4_EEEEEixEi_ZNK7testing8internal10scoped_ptrISt18basic_stringstreamIcSt11char_traitsIcESaIcEEEptEvHandleExceptionsInMethodIfSupported_M_refdataendl >_ZNK7testing8TestCase4nameEv__throw_bad_alloc_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE11_M_leftmostEvprint_timeregcomp_ZNSt10_Iter_baseIPSsLb0EE7_S_baseES0__ZNK9__gnu_cxx13new_allocatorIN7testing14TestPartResultEE7addressERKS2_scoped_ptrChar_kill_ZN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE11ValueHolderD0Ev_ZNK9__gnu_cxx13new_allocatorISt13_Rb_tree_nodeISsEE7addressERKS2_severity_pthread_mutex_destroy_ZNSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE6insertEN9__gnu_cxx17__normal_iteratorIPS3_S5_EEjRKS3__ZNSolsEPFRSoS_Evprintf_ZNSt12_Vector_baseIN7testing12TestPropertyESaIS1_EE12_Vector_impl12_M_swap_dataERS4_operator<< _sbuf_ZNSt3setIPKcSt4lessIS1_ESaIS1_EE11equal_rangeERKS1_FLAGS_gtest_catch_exceptions_ZN7testing8internal27PrettyUnitTestResultPrinter24OnEnvironmentsSetUpStartERKNS_8UnitTestEdef_optional_ZNSt6vectorIiSaIiEE5frontEvtruncreporter_ZNSbIwSt11char_traitsIwESaIwEE4_Rep9_S_createEjjRKS1__ZN7testing8internal18g_linked_ptr_mutexE_ZNSt6vectorIPcSaIS0_EE4rendEv_ZN7testing8internal18OsStackTraceGetterD2Ev_ZNKSbIwSt11char_traitsIwESaIwEE7compareERKS2___throw_bad_cast__uninitialized_copy_a_ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EE6assignEjRKS2_strtoull__ostream_insert >fwprintf_Destroy__is_normal_iterator_ZN9__gnu_cxx14__alloc_traitsISaIN7testing14TestPartResultEEE7destroyERS3_PS2__ZN7testing8internal17StreamingListener18OnTestProgramStartERKNS_8UnitTestElong int_ZNSt11char_traitsIcE6assignEPcjc_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE7_M_copyEPKSt13_Rb_tree_nodeIS1_EPS9_ToUppervector >_ZN7testing13PrintToStringIPKwEESsRKT_operator-*, std::vector > >default_xml_generatorFormatHexIntstatus_ZN9__gnu_cxx14__alloc_traitsISaISt13_Rb_tree_nodeISsEEE10_S_on_swapERS3_S5__ZNK9__gnu_cxx17__normal_iteratorIPPN7testing11EnvironmentESt6vectorIS3_SaIS3_EEEptEv_ZNSt6vectorIiSaIiEE14_M_fill_insertEN9__gnu_cxx17__normal_iteratorIPiS1_EEjRKi_ZN7testing8internal10scoped_ptrISt18basic_stringstreamIcSt11char_traitsIcESaIcEEE7releaseEv_ZN9__gnu_cxx13new_allocatorIN7testing8internal9TraceInfoEE8allocateEjPKv_ZN7testing4Test8TearDownEvarray_ZNKSt12_Vector_baseIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE19_M_get_Tp_allocatorEv_ZNSt6vectorISsSaISsEE6insertEN9__gnu_cxx17__normal_iteratorIPSsS1_EEjRKSs_ZNKSs7_M_dataEv_ZNSt12_Vector_baseIiSaIiEE13_M_deallocateEPijiteratoroperator!= >__destroy_ZN7testing8internal18StreamableToStringIxEESsRKT_socket_writer__ZN9__gnu_cxx17__normal_iteratorIPKcSsEmmEidescriptionGetDefaultFilter_ZN9__gnu_cxx17__normal_iteratorIPKcSsEmmEvbasic_string, std::allocator >_ZNK9__gnu_cxx17__normal_iteratorIPPN7testing8TestInfoESt6vectorIS3_SaIS3_EEEplEi_ZNKSt15basic_streambufIcSt11char_traitsIcEE4pptrEvIsContainerTest_ZNSs4_Rep13_M_set_leakedEvreverse_iterator >_ZNKSbIwSt11char_traitsIwESaIwEE4_Rep12_M_is_sharedEv_ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EE8_M_eraseEN9__gnu_cxx17__normal_iteratorIPS2_S4_EES8___uninit_copy*, std::basic_string*>_ZN7testing8internal13DeathTestImpl6PassedEb_ZNKSt6vectorIPN7testing17TestEventListenerESaIS2_EE4backEv_ZNK7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE7pointerEv_ZN7testing8internal5MutexaSERKS1_no_sub_ZNSs6insertEjRKSs_Rb_tree, std::allocator >, std::basic_string, std::allocator >, std::_Identity, std::allocator > >, std::less, std::allocator > >, std::allocator, std::allocator > > >_ZNSbIwSt11char_traitsIwESaIwEE15_M_replace_safeEjjPKwj_ZN7testing8internal10scoped_ptrISsEaSERKS2__ZNSt6vectorIPcSaIS0_EE5clearEv_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE24_M_get_insert_unique_posERKS1__ZN7testing8internal17TestEventRepeater20OnTestIterationStartERKNS_8UnitTestEi_S_do_ituninitialized_copySOCK_NONBLOCK_ZNK9__gnu_cxx13new_allocatorIPN7testing8TestInfoEE8max_sizeEvRunSetUpTestCase_ZNSt6vectorIPN7testing11EnvironmentESaIS2_EE8pop_backEv_ZNKSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE3endEv_ZN7testing8UnitTestD0Ev_ZN7testing8internal31GetCurrentOsStackTraceExceptTopEPNS_8UnitTestEi_ZN7testing8internal9DeathTest6CreateEPKcPKNS0_2REES3_iPPS1_random_seed_ZNK9__gnu_cxx17__normal_iteratorIPN7testing12TestPropertyESt6vectorIS2_SaIS2_EEEmiEiFilePath_Atomic_wordimpl_Format_ZNK7testing18TestEventListeners21default_xml_generatorEvos_stack_trace_getter__ZN9__gnu_cxx13new_allocatorIPcE10deallocateEPS1_j_ZN7testing17TestEventListener25OnEnvironmentsTearDownEndERKNS_8UnitTestE__is_normal_iterator_ZN7testing22EmptyTestEventListener16OnTestPartResultERKNS_14TestPartResultEpipe_ZNKSt6vectorIPcSaIS0_EE4dataEvsi_signo_ZNSt12_Destroy_auxILb0EE9__destroyIPSsEEvT_S3__ZNK9__gnu_cxx17__normal_iteratorIPKPN7testing8TestCaseESt6vectorIS3_SaIS3_EEEptEvCreateSOCK_PACKETiterator_S_keyTestRoleless, std::allocator > >allocator_KeyOfValue_ZN7testing8internal15UnitTestOptions20PatternMatchesStringEPKcS3__ZNKSt12_Vector_baseIPN7testing11EnvironmentESaIS2_EE19_M_get_Tp_allocatorEvwprintf_ZNK9__gnu_cxx17__normal_iteratorIPKSsSt6vectorISsSaISsEEE4baseEvvector >_ZN9__gnu_cxx17__normal_iteratorIPKN7testing8internal9TraceInfoESt6vectorIS3_SaIS3_EEEpLEi_ZNSt6vectorIPN7testing8TestCaseESaIS2_EE14_M_fill_assignEjRKS2_operator- >__normal_iterator > >floatdeath_test_use_forktest_cases__ZN9__gnu_cxx17__normal_iteratorIPKPN7testing8TestInfoESt6vectorIS3_SaIS3_EEEmmEv_ZNK9__gnu_cxx17__normal_iteratorIPN7testing8internal9TraceInfoESt6vectorIS3_SaIS3_EEEptEv_ZNSt6vectorISsSaISsEE4dataEv__needlenum_chars_M_repBiggestInt_ZN7testing7FloatLEEPKcS1_ff_Iter_base<__gnu_cxx::__normal_iterator > >, true>set_child_pid__copy_mFLAGS_gtest_list_testsmbrlen_ZNSs9push_backEc_ZN9__gnu_cxx17__normal_iteratorIPKPN7testing17TestEventListenerESt6vectorIS3_SaIS3_EEEppEiGetParam()re_pattern_buffer_ZN7testing4TestD2Ev_ZNK7testing8internal13FloatingPointIfE13exponent_bitsEvssize_t_ZN9__gnu_cxx17__normal_iteratorIPKPN7testing17TestEventListenerESt6vectorIS3_SaIS3_EEEppEvreverse_iterator<__gnu_cxx::__normal_iterator > > >_ZNKSt12_Vector_baseIPN7testing8TestCaseESaIS2_EE13get_allocatorEvargc_Ios_Fmtflags_M_replace_aux_ZN7testing8internal7PrintToEPKcPSo~CapturedStream__niter_baseresize_ZSt18_Rb_tree_decrementPSt18_Rb_tree_node_base_ZNSt11char_traitsIcE11to_int_typeERKc_ZN7testing14ExitedWithCodeaSERKS0_argvoperator<< _ZN7testing32ScopedFakeTestPartResultReporterC2EPNS_19TestPartResultArrayE_ZNSt6vectorISsSaISsEE15_M_erase_at_endEPSserrors_ZNKSt6vectorIPN7testing8TestInfoESaIS2_EEixEj_ZN7testing8internal12UnitTestImpl26RegisterParameterizedTestsEvDerivedforever_ZNK7testing19TestPartResultArray17GetTestPartResultEi_ZNKSs17find_first_not_ofEcjseconds_IIter__niter_base_ZN7testing7MessageaSERKS0___elision_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE12_M_erase_auxESt23_Rb_tree_const_iteratorIS1_E_ZNSt6vectorIiSaIiEE6resizeEji_ZNSt12_Vector_baseIPN7testing8TestCaseESaIS2_EE11_M_allocateEjUrlEncode_ZNK9__gnu_cxx13new_allocatorIcE7addressERc_ZNSt10_Iter_baseIN9__gnu_cxx17__normal_iteratorIPPN7testing17TestEventListenerESt6vectorIS4_SaIS4_EEEELb1EE7_S_baseES9_CurrentStackTrace_ZN7testing8internal16DeathTestFactory6CreateEPKcPKNS0_2REES3_iPPNS0_9DeathTestE__data_ZNK9__gnu_cxx17__normal_iteratorIPN7testing14TestPartResultESt6vectorIS2_SaIS2_EEEdeEvtest_part_resultsTestCaseFaileddiv_t__normal_iterator > >reverse_iterator<__gnu_cxx::__normal_iterator > > >_ZNSt17_Rb_tree_iteratorIPKcEmmEi_ZN7testing4Test11DeleteSelf_EvStrDup__copy_move_ZNK7testing8TestInfo4nameEv_ZNSt6vectorIPN7testing8TestInfoESaIS2_EE5eraseEN9__gnu_cxx17__normal_iteratorIPS2_S4_EE_ZNSs16_S_construct_auxIPKcEEPcT_S3_RKSaIcESt12__false_type_ZNSt17_Rb_tree_iteratorIPKcEmmEv__dynamic_cast__is_move_iterator~XmlUnitTestResultPrinterBasicNarrowIoManip__list_ZNSt9basic_iosIcSt11char_traitsIcEE4fillEctv_nsec_ZN7testing38FLAGS_gtest_show_internal_stack_framesEUnlock_ZNK7testing10TestResult15HasFatalFailureEvpthread_setspecific__dnewinput_iterator_tag~ParameterizedTestCaseRegistryprinted_test_case_name_M_start_ZNK9__gnu_cxx13new_allocatorIwE8max_sizeEvusedSkipCommaTestPartResultReporterInterface__numeric_traits_integer_ZNSt6vectorIN7testing14TestPartResultESaIS1_EE8_M_eraseEN9__gnu_cxx17__normal_iteratorIPS1_S3_EE_ZN7testing8TestCase14TestReportableEPKNS_8TestInfoEUInt_ZNK7testing8internal13FloatingPointIfE6is_nanEv_ZNK9__gnu_cxx17__normal_iteratorIPPN7testing8TestCaseESt6vectorIS3_SaIS3_EEEplEioperator!= >_ZNK9__gnu_cxx17__normal_iteratorIPN7testing14TestPartResultESt6vectorIS2_SaIS2_EEEixEidefault_xml_generator__ZN7testing8internal17StreamingListener15OnTestCaseStartERKNS_8TestCaseE_ZNSt6vectorIPN7testing8TestInfoESaIS2_EEixEjstackset_up_tc_TEST_F_namesecond_ZNSsaSERKSsis_disabled_OnEnvironmentsTearDownEnd~SocketWriter_Num_ZNSt6vectorIPN7testing11EnvironmentESaIS2_EE15_M_erase_at_endEPS2__ZNKSt6vectorIiSaIiEE12_M_check_lenEjPKc_ZN9__gnu_cxx14__alloc_traitsISaIiEE10_S_on_swapERS1_S3__ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEED0Evdashstatement_ZN7testing22FLAGS_gtest_print_timeE_ZNSt12_Vector_baseIN7testing12TestPropertyESaIS1_EE19_M_get_Tp_allocatorEv_ZNKSt13_Bit_iteratormiEiExitedWithCodehintstm_gmtoff_ZN9__gnu_cxx14__alloc_traitsISaIPN7testing8TestInfoEEE17_S_select_on_copyERKS4__ZN7testing8internal14CmpHelperSTRNEEPKcS2_PKwS4__ZNKSt3setISsSt4lessISsESaISsEE3endEvoperator<< _ZN7testing7MessageC2ERKS0_UniversalPrintArrayst_blocks_ZN7testing8internal12UnitTestImpl25set_os_stack_trace_getterEPNS0_27OsStackTraceGetterInterfaceEpthread_tprefix_ZN9__gnu_cxx14__alloc_traitsISaIPN7testing8internal29ParameterizedTestCaseInfoBaseEEE8allocateERS5_jDeathTestThreadWarningdata_ZN9__gnu_cxx17__normal_iteratorIPPcSt6vectorIS1_SaIS1_EEEppEv_ZNKSs4sizeEv__miter_base_ZN7testing8internal17StreamingListener20AbstractSocketWriter4SendERKSsallocator > >_ZNSt6vectorIPcSaIS0_EE9push_backERKS0_ai_addrlenkNonFatalFailure_ZNKSbIwSt11char_traitsIwESaIwEE2atEj_ZN7testing8internal21StackLowerThanAddressEPKvPbStat_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE29_M_get_insert_hint_unique_posESt23_Rb_tree_const_iteratorISsERKSs_ZNSt17_Rb_tree_iteratorISsEppEic_str_ZN7testing8internal13CaptureStreamEiPKcPPNS0_14CapturedStreamEsi_statusParseGoogleTestFlagsOnly_ZNK7testing8UnitTest19disabled_test_countEv__niter_baseoperator<< _ZNKSt6vectorIPN7testing8TestInfoESaIS2_EE2atEjg_captured_stdout_ZN9__gnu_cxx14__alloc_traitsISaIPKcEE8max_sizeERKS3__ZN7testing22EmptyTestEventListener25OnEnvironmentsTearDownEndERKNS_8UnitTestEdeath_test_style_ZNKSs15_M_check_lengthEjjPKc_ZN9__gnu_cxx14__alloc_traitsISaIPN7testing8TestCaseEEE10_S_on_swapERS4_S6__ZNK9__gnu_cxx13new_allocatorIwE7addressERwoperator new_ZN9__gnu_cxx17__normal_iteratorIPKPN7testing8TestCaseESt6vectorIS3_SaIS3_EEEmmEi__class_type_info_ZNK9__gnu_cxx17__normal_iteratorIPSsSt6vectorISsSaISsEEEptEvbadbit_ZN7testing8TestInfoD2EvGetTestInfo_ZN9__gnu_cxx17__normal_iteratorIPKPN7testing8TestCaseESt6vectorIS3_SaIS3_EEEmmEvruntime_errorEndsWithCaseInsensitivevector >__countGTestMutexLocksam1ostreamsam2long_value_ZN7testing8internal8GTestLogD2Ev_Vector_base >_ZN7testing8internal18GetInjectableArgvsEv_ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EE6insertEN9__gnu_cxx17__normal_iteratorIPS2_S4_EERKS2__ZN9__gnu_cxx17__normal_iteratorIPKSsSt6vectorISsSaISsEEEppEi_ZN9__gnu_cxx17__normal_iteratorIPKPN7testing8TestInfoESt6vectorIS3_SaIS3_EEEpLEi_ZNKSt6vectorIN7testing12TestPropertyESaIS1_EE4rendEvrebind_ZN9__gnu_cxx17__normal_iteratorIPKSsSt6vectorISsSaISsEEEppEv_ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EE7reserveEj_ZNSt12_Vector_baseIPN7testing8TestCaseESaIS2_EE13_M_deallocateEPS2_j_ZNSt12_Vector_baseIN7testing14TestPartResultESaIS1_EE12_Vector_impl12_M_swap_dataERS4_Setupsuccessful_test_case_countstat_ZNSt6vectorIiSaIiEE4swapERS1_exceptionReadAndInterpretStatusByte_ZN7testing8internal18OsStackTraceGetter19kElidedFramesMarkerEsa_restorerallocator_ZNSt3setIPKcSt4lessIS1_ESaIS1_EE4swapERS5__M_node_ZNSs6assignEPKcj_ZN7testing8internal15GetUnitTestImplEvShuffleTests__iterator_categoryconst_pointer_ZNK9__gnu_cxx13new_allocatorIPN7testing8internal29ParameterizedTestCaseInfoBaseEE7addressERKS4_fgetws_ZNKSt3setIPKcSt4lessIS1_ESaIS1_EE13get_allocatorEvrand__cursummaryArrayAsVector<8>int_p_sign_posn_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE5eraseESt23_Rb_tree_const_iteratorIS1_E_ZN7testing8internal12UnitTestImpl11AddTestInfoEPFvvES3_PNS_8TestInfoE_ZNSt6vectorISsSaISsEE5eraseEN9__gnu_cxx17__normal_iteratorIPSsS1_EE_ZN9__gnu_cxx13new_allocatorIPN7testing11EnvironmentEE9constructEPS3_RKS3_GetReservedAttributesForElementmode_ZN9__gnu_cxx13new_allocatorIiE7destroyEPioperator<< _ZNSt6vectorIN7testing12TestPropertyESaIS1_EE4swapERS3_operator<< tm_sec__size_typekMaxParamLength_ZN9__gnu_cxx13new_allocatorIPKcE8allocateEjPKv__static_initialization_and_destruction_0new_allocator_ZN7testing8internal8GTestLogC2ENS0_16GTestLogSeverityEPKciactual_valueoperator<< _ZNSo3putEc_ZNK7testing10TestResult17test_part_resultsEvmessageTraceInfo__normal_iterator > >_ZN7testing22EmptyTestEventListener20OnTestIterationStartERKNS_8UnitTestEiFLAGS_gtest_shuffle_ZNSs7replaceEjjRKSs_ZN7testing8internal17StreamingListener12SocketWriteraSERKS2_new_allocator, std::allocator > > >value_paramArrayAsVector<6>_ZNSs4_Rep9_S_createEjjRKSaIcE__addressof >kValueParamLabel_Destroy_ZdlPv_ZNKSt3setIPKcSt4lessIS1_ESaIS1_EE8key_compEv_ZNKSbIwSt11char_traitsIwESaIwEE16find_last_not_ofEwjlist_tests__ZN9__gnu_cxx14__alloc_traitsISaIiEE8max_sizeERKS1_~ValueHolder_ZN7testing8internal18PrintCharAndCodeToIhaEEvT0_PSo_ZNKSt3setIPKcSt4lessIS1_ESaIS1_EE11upper_boundERKS1_term_supports_color_Rb_tree_increment_ZNKSt9_IdentityIPKcEclERS1__ZN9__gnu_cxx13new_allocatorISt13_Rb_tree_nodeIPKcEE9constructEPS4_RKS4__S_base_ZNSs7replaceEN9__gnu_cxx17__normal_iteratorIPcSsEES2_S2_S2__ZNKSt6vectorIN7testing8internal9TraceInfoESaIS2_EE4dataEv_ZNK7testing8internal12UnitTestImpl21total_test_case_countEv_ZNSt6vectorIPcSaIS0_EEixEj~OsStackTraceGetterkTestTypeIdInGoogleTestdeallocatemask_ZNKSt3setIPKcSt4lessIS1_ESaIS1_EE3endEv_Reppbase_ZN7testing8internal14ParseInt32FlagEPKcS2_Pi_ZN7testing8TestCaseC2EPKcS2_PFvvES4_AddTestPartResult__is_normal_iteratorfprintf_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE6_M_endEvtotal_part_count_ZNSt12_Vector_baseIN7testing8internal9TraceInfoESaIS2_EE17_M_create_storageEjnot_eofSkipSpacesnot_eolPrintToString_ZNSs4_Rep12_S_empty_repEvmon_decimal_pointcurrent_test_case_operator<< _ZNKSs17find_first_not_ofEPKcjoperator<< vector >unitbuf_ZNKSbIwSt11char_traitsIwESaIwEE8_M_checkEjPKcPartialMatchiterator_traits<__gnu_cxx::__normal_iterator > > >in_death_test_child_process~DefaultPerThreadTestPartResultReporter_ZNSs9_M_assignEPcjc_ZNK7testing8internal8FilePath14IsAbsolutePathEv_ZNSt11char_traitsIwE4findEPKwjRS1_ValidateTestPropertyNamereferencerfind_Referencewscanf_ZN7testing8internal12AssertHelperC2ENS_14TestPartResult4TypeEPKciS5___osize_DestroyToPrint_ZNK9__gnu_cxx13new_allocatorIiE7addressERKi_ZN7testing8internal8FilePath9NormalizeEv_ZN9__gnu_cxx17__normal_iteratorIPSsSt6vectorISsSaISsEEEppEi_ZNKSt6vectorIiSaIiEE5frontEv_ZN7testing8internal24XmlUnitTestResultPrinter26RemoveInvalidXmlCharactersERKSs__are_same_ZNK7testing8internal12UnitTestImpl16catch_exceptionsEvkRandomSeedFlag__iterator_category<__gnu_cxx::__normal_iterator*, std::vector > > >_ZlsRKN7testing8internal6SecretEi_ZN9__gnu_cxx17__normal_iteratorIPSsSt6vectorISsSaISsEEEppEv_ZNK7testing8UnitTest26successful_test_case_countEvoperator()<__gnu_cxx::__normal_iterator > >_S_showpoint_ZN7testing8internal17TestEventRepeater25OnEnvironmentsTearDownEndERKNS_8UnitTestE_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE11upper_boundERKS1__IO_lock_t_ZN9__gnu_cxx14__alloc_traitsISaIN7testing12TestPropertyEEE10_S_on_swapERS3_S5__ZN9__gnu_cxx13new_allocatorIPN7testing8internal29ParameterizedTestCaseInfoBaseEE8allocateEjPKv_ZN7testing8internal13DeathTestImpl11set_outcomeENS0_16DeathTestOutcomeE_ZN9__gnu_cxx24__numeric_traits_integerIiE5__minE_ZN7testing31TestPartResultReporterInterfaceaSERKS0__ZNSt12_Vector_baseIPN7testing11EnvironmentESaIS2_EE19_M_get_Tp_allocatorEv__copy_m_ZN7testing8internal23MakeAndRegisterTestInfoEPKcS2_S2_S2_PKvPFvvES6_PNS0_15TestFactoryBaseEnew_allocator_ZNK9__gnu_cxx13new_allocatorIN7testing14TestPartResultEE7addressERS2__ZNSt6vectorIN7testing12TestPropertyESaIS1_EE4backEvEventForwardingEnabled__alloc_traits >_Rb_tree_impl, false>_ZN7testing8internal8FilePath3SetERKS1_should_runstring_ZNKSt17_Rb_tree_iteratorISsEneERKS0_kTypeParamLabel__simplefork_ZNSt11char_traitsIcE4findEPKcjRS1___is_move_iteratorproperty_with_matching_keylong long int_ZNKSt3setIPKcSt4lessIS1_ESaIS1_EE8max_sizeEv_ZNSt16reverse_iteratorIN9__gnu_cxx17__normal_iteratorIPPN7testing11EnvironmentESt6vectorIS4_SaIS4_EEEEEmmEv_ZNSt6vectorIiSaIiEE8_M_eraseEN9__gnu_cxx17__normal_iteratorIPiS1_EES5_intptr_t_ZNKSt16reverse_iteratorIN9__gnu_cxx17__normal_iteratorIPPN7testing11EnvironmentESt6vectorIS4_SaIS4_EEEEE4baseEv_ZN7testing8internal26GoogleTestFailureExceptionD2Ev_ZNSt6vectorIPN7testing8TestCaseESaIS2_EE5clearEv_ZN7testing8internal13DeathTestImplD2Ev_ZNKSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE11upper_boundERKS1__ZNSs7replaceEN9__gnu_cxx17__normal_iteratorIPcSsEES2_RKSs_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE6rbeginEv_ZN9__gnu_cxx17__normal_iteratorIPKPN7testing8TestCaseESt6vectorIS3_SaIS3_EEEpLEi_ZNK7testing8UnitTest21successful_test_countEv_ZN9__gnu_cxx13new_allocatorIN7testing8internal9TraceInfoEE7destroyEPS3__ZN9__gnu_cxx14__alloc_traitsISaIiEE8allocateERS1_jcopyMatchesFilteroperator<=19pthread_mutexattr_t_ZN7testing8internal2RED2Ev_ZN7testing10TestResult14RecordPropertyERKSsRKNS_12TestPropertyECountIf, bool (*)(const testing::TestPartResult&)>_ZNSt6vectorIN7testing12TestPropertyESaIS1_EE2atEjLastMessage_ZNKSt6vectorIPN7testing17TestEventListenerESaIS2_EE4rendEv_ZNK7testing8TestCase17failed_test_countEvscoped_ptr, std::allocator > >_Iter_basegtest_color_ZNKSs12find_last_ofEcj_ZNKSt23_Rb_tree_const_iteratorIPKcEneERKS2__ZN9__gnu_cxx13new_allocatorIN7testing8internal9TraceInfoEE10deallocateEPS3_j_ZNK7testing8internal13FloatingPointIdE13fraction_bitsEv_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE4swapERS7__ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE8_S_rightEPKSt18_Rb_tree_node_base_ZN7testing8internal8FilePathaSERKS1_vector >_ZNKSbIwSt11char_traitsIwESaIwEE6substrEjj_ZN7testing8internal11CmpHelperNEEPKcS2_xx_S_dec_DestroyFilterTestsfirst_test_nameTestCaseInfoContainer_ZNSt3setIPKcSt4lessIS1_ESaIS1_EE5clearEva_type_param_ZNK9__gnu_cxx13new_allocatorIN7testing8internal9TraceInfoEE7addressERS3__ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE12_M_rightmostEv_ZNKSt18_Bit_iterator_basegtERKS_GCC: (GNU) 4.9.2 20150212 (Red Hat 4.9.2-6)zR| 0DCKC FCdCKC FCCJCJ,@Th|0DXl 0AnP*Ah*Ah*Ah,@T%CWCA Ft AND HA AND HA AND HA DAND HA hAND HA AND HA AND HA AND HAzPLR| 4$0AB Cv.g AAA A (P(AA NE P AA0|0AA N$I(G,A0H CA )ANP HA(3AA NP P AA4 NAA AkFA LJ AA48pNAA AkFA LJ AA4pNAA AkFA LJ AA4NAA AkFA LJ AA4`NAA AkFA LJ AA4NAA AkFA LJ AA4POAA AvFA FF AA4POAA AvFA FF AA4OAA AvFA FF AA4OAA AvFA FF AA40@OAA AvFA FF AA8hRAA AkFDA LJ AA8SAA AvFDA FF AA<PrAA CC D,D0L L C AAA h AA CAN _,G0K T,G0K G AA AAJ I,A0H CAA AA@ pPAA N[  AAC PAA HC AAD XAA N `,A0H AAE L,A0H AAD AA AAN@dLAPH@CAA AAH` AA AAN@hLAPH@GLAPHAA AAD nAA AAN@KLAPH@CAA AA@ AD Cy. AAA A O AAA A t8 ` AA AAN@IDDHBLAPPDAHALAPH@\DBHELAPH@ODBHDLAPH@LAA AA\ @ `AA CTA HACD HC  AAI IBAF HC AA4 uAA N `  AAF ](E,A0H 4Tq9AB Cf.d AAA A 4 dEAB Cv.Q AAA A 4  MAA N [,A0H C  AAG 4` UAB Cx.N AAA I D( AA Au  AAF gAA HR DAPp SAA AAN Q(B,A0H J(B,A0H ICA AA $  2ANXA HAP " "( < *Ah4X .AA CNKA KA AA4 .AA CNKA KA AA4P.AA CNKA KA AA4.AA CNKA KA AA48.AA CNKA KA AA4p.AA CNKA KA AA4.AA CNKA KA AA0@0AA N$I(G,A0H CA4pWAA FN8BANGB TH HA(!>ANGB TH HA@!VAA NKB NCBA RH H AA`P"AA AAN0y AA AAA My AB CB.c AAA J l AAA I 4>/ AB CC.S AAA I D>@* AB C\. AAA K ~ AAA A 4?M AB Fg.~ AAA G <@?d AB B[ AA F N.u AA C @?t AB Cu.M.T.e.T.z AAA A 4? AB Cm. AAA J 4? AB Cl.B AAA C D4@| AB Cn. AAA B  AAA A D|@| AB Ck. AAA E  AAA A 4@C> AB C.m AAA H 4@`3R AB C` AAA G t.44A2p AB CL. AAA G DlA| AB Cm. AAA C  AAA A 4Ad AB Cu.x AAA J 4APAB F|.a AAA C D$BQ6AB C. AAA K L AAA A llBPfAB Cc AAA D \..V. AAA E _.U.H.V..V..^.b.Q.DB0=AB FH AAA D _. AAA H D$CpCAB CF.X AAA I _ AAA A @lCpZAB CZ AAA E g AAA A a.4C$AB C.p AAA A DCAB CK.n AAA F H AAA E @0Dз|/AB Cr. AAA A j AAA A LhIPAA AN T,D0H j C AAH dC AA<IaAA N P,D0H [  CAE L CADE`bAB FD. AAA F  AAA H 4LEAB Cb.B AAA A 4E AB F[. AAA J 4E 3AB Cy. AAA G DE`&AB CB.W. l AAA J R AAA C D/AB Fl.g. w AAA J S.xcAA AAN0] r A@r ACr AIr APr AQr ARr AUr A`r  Acr Aer$ A{r0 Ar< ArH ArT Ar` Arl Arx Ar Ar Ar Ar Ar ArA.rAFrArArArArArArArArArAr Ar(Ar0Ar8Ar@ArHArPArXAr`ArhArpArxArArArArArArArArArArArArArArArArArArArArAr Ar(Ar0Ar8Ar@ArHArPArXAr`ArhArpArxArArArArAErADrAgrAfrArArA+rArArArArArAr Ar Ar Ar Anr A3r( A6r0 Adr8 Ar@ A rH ArP A rX Ar` Arh Arp A rx A$r A4r A5r Ar Avr Ar Air A-r Ar Ar Ar A  A%+ 0Z{ =l $0@>{@NPR,`Sbpr^Wc TG+ }  &  } " 00 2 @ B, Px R `/ bf p r A Z `hbp1rc'Ff LA0y dA3.,0( |A6ONP A9n p A<g A?EA AB AE:- @AG2* HrW)S L AK3 l(AN[XW 8AQHP 0ATY 8AWxLnH 4(AZm2|..u \0A^&/F0/qB (Aa// 0Ad0000`  (Ag20z0[v 8Aj00c D@Am8T1z`1kv 0Ap11 hAs>22 PAv=3; @3e7 l@Ayx 3 3 PA|!@4 @ A~ !AE!AA! HAr!E!E+! 0A!I!"IZ" D8A\":J"@J" |A"Mt" DA #DOh#POd# ,A#Rt# A#lT,$pT($ Ag$U$UC$ A<%U}%U[y% A%88- 8 0A8.Z90V9 LA9::6: A:X:`k: 0A &;̢;Т; 8A  <bn<pzj< ,8A<F=B= d8A=;>7> 8A>"?0C? AO?t?y? A??(? t  A!@(\@0)X@  A!@Z@`3@ (A$@0A),A  A'`AʭAЭ3A (A*AGBCB $ 8A-BBB \ XA05CnCpC 8A3CXDnTD A6D~ExE  0A9pEEE 4  A< FkFgF T xA?FpGlG ABHMHmIH L AExH]NI`pJI 4 HAHJлJлJ | HAKXK'L#L HANLHrDЀB a߽      !"#$%&'()*+,-./0235689;<>?ABDEGZ(IJKMNPr3pPPQSTVWYZ\Y` @ `]^`aC ~ ~cdfg ~B 0u~,ijlmoprsuvxy{|Z@^~`g`@bGp;q ~@ ~7 ~W ~wз|0Xp D`(  lP(( ~ !#$&')*$ #,-/0235689;<>?ABDEGHJKMNU ~PQy  ~ J@  ~ST O ~9 > ~e - ~ ' ~ ~  ~ ~/ g ~a  ~  ~  ~ ~ ~ ~D ~q ~ ~VWYZ\]  ] 0y  @  _`bcefhiklnoqrtuwxz{}~0? ~e@ <~   !#%'()*,-/13568:=0_>IIIII\+I0I7I8\>I:I <I@IEI!JI(I/PI6\I=kIDrIKIRIYI`IgInIuI|\\IIIII\IIIII\III$I7I'I;IBI9III$TI+VI2XI9gI@mIGINIUoI\IcIjIqL\x'IIIIIIIIIIIIIIIIIIII I%II 9I'DI.OI5YI<dICrIJuIQwIX}I_IfImItI{IIIIII|\\\I\I\\\(\II\II\\BI#&I*UI1\8I?IFIMITI[Ib\iIp<\w|\~I\\\\\*I6I~IIIIIIIII IIII $I4IUIPI&`I-ZI4gI;nIBrIItIPvIW\^IeIlIsD\zIIIIx\\I\I+I\5IBIFIIIUI\ \iImI~I 8\II"I)h\0I7I>IE\L\SIZ@IaIh\oIvI}I2I7IHIQI`IcIjIIIIIIIIII \8 \I p \I \ I% I,' I3? I:( \A \HIOIV \]IdT \k| \r \y \ \U I_ Ii I} I ID \ I Il \ I I I I I I I$ I/ IvI 9 I? IF I! I( \/ \6 I=L IDh IKX \Rw IY I`| \g \n Iu \| I \p \ \ I I I I \ \ I I I! I/ I= IB IN I( I$ IY I` Ie Io I$r I+ I2 I9 I@ IG IN IU I\ Ic IjL\q Ix I I I I It\ I I( I. I8 I\= IO I\V In It I\,\ I  I Il\ \'\.,\5 I< IC IJh\Q IX I_ If Im It\{ I# I3 I\(\F I[ II`\n I\II^^^^^^__ _p^#Р*18H? IFMT[(bHihpw~P(HhPI \D\|\\sII\ IIL\P\&&I-BI4_I;zIBIIIP\WI^<IeRIlaIsdIz\}IF I \, \ I I I I I I I I I I I I I III #I4IPm "!X"#$ %?&'()*&+[AzDEGKHxIU`a b<      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~: "U " " " " "!"8!"d!"!"!"!"!"""L""""""1#"v#"#" $" B$"$"$"%%"n%"%"&"-&"U&n&& 0&P*&*'*I's'"'" #(""("$()%m)"&)"&#*"(U*"(*"**"**",4+",u+".+".+"0L,)b,x,,"3,"6,"9-"<D-"?-"B-"E-0 .!:(.D! S.b.w.0.(.0/!/)"KV/!//)"K/3"N 0 NY0pN0N0N91`N1N1O/2PO2O2O 3@OU3R3S3344X"QR4D!44"T4!#Q5"T5"W5n"Z6n"Z36B6T6c6u66666u"^)7u"^\7q"a7q"a7 d88 d^8 M8 M8` 89 9!9 d9 S9 9(9: 2y:: 2:P "=;!z;P "; "<!_< "< < *.= .k=@N= .=N=P.D>.>.>.>.-?@0p?pW??T??0b@0b(@H@h@T@@@T@@=6AAA;~A IAB#Bp*DBtBpXB4B4BPCpdJCPCYrCPC0PC"DTNDcD !wDDDDE1E\EEEE F|0FxVFtwFpFlFhFdG0GREGRZG0(oG`@G/G/HL$HP$KH@HHHP HHHIII2IDIp!>III!> J!VZJP"J@#JJ#$K+K2K7K#lK$K% LL!LYLp&U}Lp&UL&WL&WL0'g*M'UM' M' M' M' /N( ^N0( NP( Np( N(  O( MO( |O( O) O0)OP) Pp)O?P)T^P *2P`*P+ Q+2.Q+ OQ"doQ"dQ`"gQ`"gQ+ Q+R, RR,3RP,wRRR, S,JS.3S.S/RTp/9T/C\TuTT/OTT0T2W U3O/"QB_~0@ƚ@CEx@| ~i`Fi"T-PL!"WÜ@L!"ZV! !PpL!%pM N\N7!4N7 O7ޠ O7=`O]o`O]O(ӡOP!!8OPk@P9@P9ѢP(X"]4Py(fls0|2p~ ipAe2"`P'"c[`!"fۦ !`"iH"l"oP8"^"Ѩ !O~4`u Ϊ0*$0KPsp^п"rI!8a!6`"u#`N>"x["{Mhޮ"~r"߯$yJ":R\0!0!BX!z!!Ʋ&!-!! !R!,!.! !!*!>!V!n!!!ȴ! !#!8!P!h-! !ʵ!1!4(!` !9!ɶ !<!F !"!!ҷ!=!T !5!Ƹ !'!1!Q !'! !ܹ.! !@#!g !&! !%! !4#![ !!ӻ!!@!\D!~D!!ڼ!`Z@ q νgtest-all.cc_ZN7testing8internal18OsStackTraceGetter16UponLeavingGTestEv.localalias.384_ZN7testing8internal17TestEventRepeaterD0Ev.localalias.388_ZN7testing8internalL19SumOverTestCaseListERKSt6vectorIPNS_8TestCaseESaIS3_EEMS2_KFivE.constprop.391_ZN7testing8internalL14PrintOnOneLineEPKci.constprop.393_ZNSs4_Rep10_M_disposeERKSaIcE.part.7_ZN7testing8internalL21FormatDeathTestOutputERKSs_ZN7testing12_GLOBAL__N_126PrintByteSegmentInObjectToEPKhjjPSo_ZN7testing7MessagelsIKcEERS0_RKPT_.isra.62_ZGVZN7testing8internal13ColoredPrintfENS0_10GTestColorEPKczE13in_color_mode_ZZN7testing8internal13ColoredPrintfENS0_10GTestColorEPKczE13in_color_mode_ZN7testing8internalL15kTypeParamLabelE_ZN7testing8internalL16kValueParamLabelE_ZN7testingL20kTestShardStatusFileE_ZTIN7testing8internal12_GLOBAL__N_123ClassUniqueToAlwaysTrueE_ZN7testing8internalL23HasGoogleTestFlagPrefixEPKc_ZN7testing8internalL26g_in_fast_death_test_childE_ZN7testing8internalL23kCurrentDirectoryStringE_ZN7testing8internalL17g_captured_stdoutE_ZN7testing8internalL17g_captured_stderrE_ZN7testing8internalL21g_injected_test_argvsE_ZN7testing8internalL20PrintAsCharLiteralToIwwEENS0_10CharFormatET0_PSo_ZN7testing8internalL22PrintAsStringLiteralToEwPSo_ZN7testing8internalL20PrintCharsAsStringToIcEEvPKT_jPSo_ZN7testing8internalL20PrintCharsAsStringToIwEEvPKT_jPSo_ZN7testingL19FormatCountableNounEiPKcS1__ZN7testing8internalL12kUnknownFileE_ZN7testing8internalL27PrintTestPartResultToStringERKNS_14TestPartResultE_ZN7testing8internalL25FormatCxxExceptionMessageEPKcS2__ZN7testingL15kTestShardIndexE_ZN7testingL16kTestTotalShardsE_ZN7testingL16kUniversalFilterE_ZN7testing8internalL12FlagToEnvVarEPKc_ZN7testing8internal18StreamableToStringIPwEESsRKT_.isra.349_ZN7testing12_GLOBAL__N_115IsSubstringImplIPKcEENS_15AssertionResultEbS3_S3_RKT_S7__ZN7testing12_GLOBAL__N_115IsSubstringImplISsEENS_15AssertionResultEbPKcS4_RKT_S7__ZN7testing12_GLOBAL__N_115IsSubstringImplISbIwSt11char_traitsIwESaIwEEEENS_15AssertionResultEbPKcS8_RKT_SB__ZN7testing12_GLOBAL__N_115IsSubstringImplIPKwEENS_15AssertionResultEbPKcS6_RKT_S9__ZN7testing8TestCaseD0Ev.localalias.385_ZN7testing8internal12UnitTestImplD0Ev.localalias.387_ZGVZN7testing8UnitTest11GetInstanceEvE8instance_ZZN7testing8UnitTest11GetInstanceEvE8instance_ZN7testingL18kDefaultOutputFileE_ZN7testing8internalL22ExecDeathTestChildMainEPv_ZN7testingL20kDeathTestCaseFilterE_ZN7testingL18kDisableTestFilterE_ZN7testing8internalL17PrintColorEncodedEPKc.constprop.390_ZN7testing8internalL24kColorEncodedHelpMessageE_ZN7testing8internalL25kAlsoRunDisabledTestsFlagE_ZN7testing8internalL19kBreakOnFailureFlagE_ZN7testing8internalL20kCatchExceptionsFlagE_ZN7testing8internalL10kColorFlagE_ZN7testing8internalL19kDeathTestStyleFlagE_ZN7testing8internalL17kDeathTestUseForkE_ZN7testing8internalL11kFilterFlagE_ZN7testing8internalL25kInternalRunDeathTestFlagE_ZN7testing8internalL14kListTestsFlagE_ZN7testing8internalL11kOutputFlagE_ZN7testing8internalL14kPrintTimeFlagE_ZN7testing8internalL15kRandomSeedFlagE_ZN7testing8internalL11kRepeatFlagE_ZN7testing8internalL12kShuffleFlagE_ZN7testing8internalL20kStackTraceDepthFlagE_ZN7testing8internalL19kStreamResultToFlagE_ZN7testing8internalL19kThrowOnFailureFlagE_ZGVZN7testing8internalL23ExecDeathTestSpawnChildEPKPciE16stack_grows_down_ZZN7testing8internalL23ExecDeathTestSpawnChildEPKPciE16stack_grows_down_ZN7testingL31GetReservedAttributesForElementERKSs_ZN7testingL28kReservedTestSuiteAttributesE_ZN7testingL29kReservedTestSuitesAttributesE_ZN7testingL27kReservedTestCaseAttributesE_GLOBAL__sub_I_gtest_all.cc_ZStL8__ioinit_ZN7testingL22kDefaultDeathTestStyleE_ZTSN7testing8internal12_GLOBAL__N_123ClassUniqueToAlwaysTrueE.L1650.L3537.L1888.L1934.LC54.LC73.LC72.LC80.LC81.LC82.LC84.LC86.LC118.LC126.LC145.LC143.LC144.LC147.LC148.LC149.LC156.LC150.LC151.LC152.LC153.LC154.LC155.LC157.LC158.LC160.LC161.LC163.LC164.LC166.LC168.LC169.LC171.LC172.LC173.LC176.LC179.LC180.LC181.LC205.LC216.LC217.LC222.LC221.LC220.LC230.LC232.LC231.LC234.LC235.LC233.LC240.LC266.LC275.LC281.LC282.LC283.LC286.LC287.LC285.LC288.LC289.LC290.LC293.LC298.LC308.LC309.LC317.LC318.LC319.LC322.LC323.LC320.LC321.LC316.LC324.LC326.LC327.LC329.LC330.LC332.LC335.LC334.LC339.LC345.LC349.LC366.LC365.LC367.LC368.LC369.LC370.LC371.LC372.LC376.LC378.LC379.LC380.LC381.LC383.LC385.LC390.LC392.LC391.LC389.LC394.LC395.LC396.LC397.LC398.LC399.LC400.LC401.LC429.LC430.LC431.LC432.LC439.LC440.LC441.LC443.LC445.LC408.LC449.LC410.LC409.LC412.LC414.LC479.LC480.LC352.LC481.LC483.LC484.LC492.LC493.LC494.LC495.LC496.LC497.LC498.LC499.LC500.LC501.LC502.LC511.LC512.LC514.LC518.LC519.LC520.LC521.LC522.LC523.LC524.LC525.LC517.LC516.LC526.LC527.LC532.LC531.LC534.LC533.LC535.LC536.LC537.LC539.LC542.LC545.LC544.LC551.LC552.LC553.LC554.LC549.LC543.LC555.LC556.LC546.LC550.LC547.LC548.LC558.LC559.LC560.LC561.LC562.LC563.LC564.LC566.LC568.LC569.LC570.LC571.LC572.LC573.LC574.LC423.LC576.LC581.LC577.LC578.LC580.LC579.LC583.LC458.LC588.LC589.LC593.LC594.LC600.LC601.LC602.LC603.LC604.LC605.LC606.LC608.LC614.LC615.LC611.LC617.LC618.LC620.LC622.LC623.LC624.LC655.LC656.LC434.LC665.LC670.LC671.LC683.LC684.LC685.LC686.LC682.LC677.LC678.LC679.LC680.LC681.LC688.LC690.LC699.LC703.LC704.LC706.LC707.LC708.LC709.LC710.LC705.LC711.LC713.LC714.LC715.LC716.LC717.LC719.LC720.LC721.LC722.LC723.LC724.LC609.LC739.LC741.LC743.LC403.LC749.LC750.LC761.LC757.LC758.LC759.LC760.LC763.LC774.LC786.LC787.LC788.LC789.LC790.LC791.LC792.LC794.LC795.LC796.LC797.LC798.LC800.LC801.LC802.LC803.LC804.LC808.LC809.LC810.LC811.LC807.LC806.LC812.LC813.LC814.LC815.LC816.LC817.LC818.LC819.LC820.LC822.LC823.LC824.LC825.LC826.LC828.LC829.LC830.LC831.LC832.LC833.LC835.LC838.LC850.LC853.LC854.LC855.LC857.LC858.LC859.LC860.LC868.LC869.LC870.LC871.LC872.LC873.LC874.LC875.LC876.LC877.LC878.LC879.LC880.LC883.LC882.LC884.LC885.LC886.LC887.LC891.LC893.LC892.LC896.LC897.LC900.LC901.LC903.LC904.LC905.LC906.LC419.LC910.LC909.LC488.LC489.LC490.L1651.L1653.L1654.L1655.L1656.L1657.L1658.L1659.L1660.L1661.L3538.L3540.L3541.L3542.L3543.LC351.L1889.L1891.L1892.L1893.L1894.L1895.L1896.L1897.L1898.L1899.L1935.L1937.L1938.L1939.L1940.L1941.L1942.L1943.L1944.L1945.LC357.LC404.LC405.LC406.LC416.LC417.LC418.LC420.LC421.LC422.LC427.LC437.LC456.LC459.LC461.LC462.LC463.LC472.LC474.LC476.LC505.LC506.LC507.LC509.LC529.LC610.LC692.LC733.LC752.LC768.LC765.LC766.LC767.LC920.LC921.LC922.LC923.LC924.LC925.LC926.LC927.LC928.LC929.LC930.LC931.LC932.LC933_ZN7testing8internal26ThreadLocalValueHolderBaseD5Ev_ZN7testing11EnvironmentD5Ev_ZN7testing22EmptyTestEventListenerD5Ev_ZN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE11ValueHolderD5Ev_ZN7testing8internal23DefaultDeathTestFactoryD5Ev_ZN7testing8internal27PrettyUnitTestResultPrinterD5Ev_ZN7testing8internal38DefaultPerThreadTestPartResultReporterD5Ev_ZN7testing8internal35DefaultGlobalTestPartResultReporterD5Ev_ZN7testing8internal26GoogleTestFailureExceptionD5Ev_ZN7testing8internal24XmlUnitTestResultPrinterD5Ev_ZN7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEE11ValueHolderD5Ev_ZNSt6vectorISsSaISsEED5Ev_ZN7testing8internal29ParameterizedTestCaseRegistryD5Ev_ZN7testing14TestPartResultD5Ev_ZN7testing12TestPropertyD5Ev_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEED5Ev_ZN7testing8internal5MutexD5Ev_ZN7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEED5Ev_ZN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEED5Ev_ZN7testing8internal17StreamingListener12SocketWriterD5Ev_ZN7testing8internal18OsStackTraceGetterD5Ev_ZN7testing8internal17StreamingListenerD5Ev_ZN7testing7MessageC5ERKS0__ZN7testing8internal13DeathTestImplD5Ev_ZN7testing8internal13ExecDeathTestD5Ev_ZN7testing8internal15NoExecDeathTestD5Ev_ZNKSt5ctypeIcE8do_widenEc_ZN7testing8internal26ThreadLocalValueHolderBaseD2Ev_ZN7testing8internal26ThreadLocalValueHolderBaseD1EvDeleteThreadLocalValue_ZN7testing4Test11DeleteSelf_Ev_ZN7testing4Test5SetupEv_ZN7testing8TestCase16RunSetUpTestCaseEv_ZN7testing8TestCase19RunTearDownTestCaseEv_ZN7testing11EnvironmentD2Ev_ZN7testing11EnvironmentD1Ev_ZN7testing11Environment5SetUpEv_ZN7testing11Environment8TearDownEv_ZN7testing11Environment5SetupEv_ZN7testing22EmptyTestEventListener18OnTestProgramStartERKNS_8UnitTestE_ZN7testing22EmptyTestEventListener20OnTestIterationStartERKNS_8UnitTestEi_ZN7testing22EmptyTestEventListener24OnEnvironmentsSetUpStartERKNS_8UnitTestE_ZN7testing22EmptyTestEventListener22OnEnvironmentsSetUpEndERKNS_8UnitTestE_ZN7testing22EmptyTestEventListener15OnTestCaseStartERKNS_8TestCaseE_ZN7testing22EmptyTestEventListener11OnTestStartERKNS_8TestInfoE_ZN7testing22EmptyTestEventListener16OnTestPartResultERKNS_14TestPartResultE_ZN7testing22EmptyTestEventListener9OnTestEndERKNS_8TestInfoE_ZN7testing22EmptyTestEventListener13OnTestCaseEndERKNS_8TestCaseE_ZN7testing22EmptyTestEventListener27OnEnvironmentsTearDownStartERKNS_8UnitTestE_ZN7testing22EmptyTestEventListener25OnEnvironmentsTearDownEndERKNS_8UnitTestE_ZN7testing22EmptyTestEventListener18OnTestIterationEndERKNS_8UnitTestEi_ZN7testing22EmptyTestEventListener16OnTestProgramEndERKNS_8UnitTestE_ZN7testing8internal17StreamingListener20AbstractSocketWriter15CloseConnectionEv_ZN7testing22EmptyTestEventListenerD2Ev_ZN7testing22EmptyTestEventListenerD1Ev_ZN7testing4Test5SetUpEv_ZN7testing4Test8TearDownEv_ZNK7testing8TestCase30reportable_disabled_test_countEv_ZNK7testing8TestCase19disabled_test_countEv_ZNK7testing8TestCase21reportable_test_countEv_ZNK7testing8TestCase17test_to_run_countEv_ZNK7testing8TestCase16total_test_countEv_ZN7testing8internal27PrettyUnitTestResultPrinter18OnTestProgramStartERKNS_8UnitTestE_ZN7testing8internal27PrettyUnitTestResultPrinter22OnEnvironmentsSetUpEndERKNS_8UnitTestE_ZN7testing8internal27PrettyUnitTestResultPrinter25OnEnvironmentsTearDownEndERKNS_8UnitTestE_ZN7testing8internal27PrettyUnitTestResultPrinter16OnTestProgramEndERKNS_8UnitTestE_ZN7testing8internal18OsStackTraceGetter16UponLeavingGTestEv_ZN7testing8internal24HasNewFatalFailureHelper20ReportTestPartResultERKNS_14TestPartResultE_ZN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE11ValueHolderD2Ev_ZN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE11ValueHolderD1Ev_ZN7testing8internal23DefaultDeathTestFactoryD2Ev_ZN7testing8internal23DefaultDeathTestFactoryD1Ev_ZN7testing8internal27PrettyUnitTestResultPrinterD2Ev_ZN7testing8internal27PrettyUnitTestResultPrinterD1Ev_ZN7testing8internal38DefaultPerThreadTestPartResultReporterD2Ev_ZN7testing8internal38DefaultPerThreadTestPartResultReporterD1Ev_ZN7testing8internal35DefaultGlobalTestPartResultReporterD2Ev_ZN7testing8internal35DefaultGlobalTestPartResultReporterD1Ev_ZN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE11ValueHolderD0Ev__x86.get_pc_thunk.bx_GLOBAL_OFFSET_TABLE__ZdlPv_ZN7testing8internal26ThreadLocalValueHolderBaseD0Ev_ZN7testing11EnvironmentD0Ev_ZN7testing8internal23DefaultDeathTestFactoryD0Ev_ZN7testing8internal38DefaultPerThreadTestPartResultReporterD0Ev_ZN7testing8internal35DefaultGlobalTestPartResultReporterD0Ev_ZN7testing8internal27PrettyUnitTestResultPrinterD0Ev_ZN7testing22EmptyTestEventListenerD0Ev_ZN7testing8internal17TestEventRepeaterD2EvDW.ref.__gxx_personality_v0_ZTVN7testing8internal17TestEventRepeaterE_Unwind_Resume__gxx_personality_v0_ZN7testing8internal17TestEventRepeaterD1Ev_ZN7testing8internal17TestEventRepeaterD0Ev_ZN7testing8internal18OsStackTraceGetter17CurrentStackTraceEii_ZNSsC1EPKcRKSaIcE_ZN7testing8internal26GoogleTestFailureExceptionD2Ev_ZTVN7testing8internal26GoogleTestFailureExceptionE_ZNSt13runtime_errorD2Ev_ZN7testing8internal26GoogleTestFailureExceptionD1Ev_ZN7testing8internal26GoogleTestFailureExceptionD0Ev_ZN7testing8internal17TestEventRepeater18OnTestProgramStartERKNS_8UnitTestE_ZN7testing8internal17TestEventRepeater24OnEnvironmentsSetUpStartERKNS_8UnitTestE_ZN7testing8internal17TestEventRepeater15OnTestCaseStartERKNS_8TestCaseE_ZN7testing8internal17TestEventRepeater11OnTestStartERKNS_8TestInfoE_ZN7testing8internal17TestEventRepeater16OnTestPartResultERKNS_14TestPartResultE_ZN7testing8internal17TestEventRepeater27OnEnvironmentsTearDownStartERKNS_8UnitTestE_ZN7testing8internal17TestEventRepeater22OnEnvironmentsSetUpEndERKNS_8UnitTestE_ZN7testing8internal17TestEventRepeater25OnEnvironmentsTearDownEndERKNS_8UnitTestE_ZN7testing8internal17TestEventRepeater9OnTestEndERKNS_8TestInfoE_ZN7testing8internal17TestEventRepeater13OnTestCaseEndERKNS_8TestCaseE_ZN7testing8internal17TestEventRepeater16OnTestProgramEndERKNS_8UnitTestE_ZN7testing8internal17TestEventRepeater20OnTestIterationStartERKNS_8UnitTestEi_ZN7testing8internal17TestEventRepeater18OnTestIterationEndERKNS_8UnitTestEiputcharprintf_ZNSs4_Rep10_M_destroyERKSaIcE_ZN7testing8internal24XmlUnitTestResultPrinterD0Ev_ZTVN7testing8internal24XmlUnitTestResultPrinterE_ZNSs4_Rep20_S_empty_rep_storageE_ZN7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEE11ValueHolderD2Ev_ZTVN7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEE11ValueHolderE_ZN7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEE11ValueHolderD1Ev_ZN7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEE11ValueHolderD0Ev_ZNSt6vectorISsSaISsEED2Ev_ZNSt6vectorISsSaISsEED1Ev_ZNKSs4findEcj_ZNSs6appendEPKcj_ZNSsC1ERKSsjj_ZNSs6appendERKSs_ZSt24__throw_out_of_range_fmtPKczsnprintfstrlen_ZSt16__ostream_insertIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_PKS3_i_ZN7testing8internal24XmlUnitTestResultPrinterD2Ev_ZN7testing8internal24XmlUnitTestResultPrinterD1Ev_ZN7testing8internal29ParameterizedTestCaseRegistryD2Ev_ZN7testing8internal29ParameterizedTestCaseRegistryD1Ev_ZN7testing8internal12AssertHelperC2ENS_14TestPartResult4TypeEPKciS5__Znwj_ZN7testing8internal12AssertHelperC1ENS_14TestPartResult4TypeEPKciS5__ZN7testing8internal12AssertHelperD2Ev_ZN7testing8internal12AssertHelperD1Ev_ZN7testing8internal15UnitTestOptions15GetOutputFormatEv_ZN7testing18FLAGS_gtest_outputEstrchr_ZNSsC1EPKcjRKSaIcE_ZN7testing8internal15UnitTestOptions20PatternMatchesStringEPKcS3__ZN7testing8internal15UnitTestOptions13MatchesFilterERKSsPKc_ZN7testing8internal13GetTestTypeIdEv__x86.get_pc_thunk.cx_ZN7testing8internal12TypeIdHelperINS_4TestEE6dummy_E_ZN7testing8internal20SingleFailureCheckerC2EPKNS_19TestPartResultArrayENS_14TestPartResult4TypeERKSs_ZNSsC1ERKSs_ZN7testing8internal20SingleFailureCheckerC1EPKNS_19TestPartResultArrayENS_14TestPartResult4TypeERKSs_ZN7testing8internal35DefaultGlobalTestPartResultReporterC2EPNS0_12UnitTestImplE_ZTVN7testing8internal35DefaultGlobalTestPartResultReporterE_ZN7testing8internal35DefaultGlobalTestPartResultReporterC1EPNS0_12UnitTestImplE_ZN7testing8internal38DefaultPerThreadTestPartResultReporterC2EPNS0_12UnitTestImplE_ZTVN7testing8internal38DefaultPerThreadTestPartResultReporterE_ZN7testing8internal38DefaultPerThreadTestPartResultReporterC1EPNS0_12UnitTestImplE_ZNK7testing8internal12UnitTestImpl21total_test_case_countEv_ZNK7testing8internal12UnitTestImpl22test_case_to_run_countEv_ZNK7testing8internal12UnitTestImpl21successful_test_countEv_ZNK7testing8TestCase21successful_test_countEv_ZNK7testing8internal12UnitTestImpl17failed_test_countEv_ZNK7testing8TestCase17failed_test_countEv_ZNK7testing8internal12UnitTestImpl30reportable_disabled_test_countEv_ZNK7testing8internal12UnitTestImpl19disabled_test_countEv_ZNK7testing8internal12UnitTestImpl21reportable_test_countEv_ZNK7testing8internal12UnitTestImpl16total_test_countEv_ZNK7testing8internal12UnitTestImpl17test_to_run_countEv_ZN7testing8internal12UnitTestImpl28CurrentOsStackTraceExceptTopEi_ZN7testing8internal15GetTimeInMillisEvgettimeofday_ZN7testing8internal6String13CStringEqualsEPKcS3_strcmp_ZN7testing15AssertionResultC2ERKS0__ZN7testing15AssertionResultC1ERKS0__ZN7testing16AssertionSuccessEv_ZN7testing16AssertionFailureEv_ZN7testing8internal6String17WideCStringEqualsEPKwS3_wcscmp_ZN7testing8internal6String28CaseInsensitiveCStringEqualsEPKcS3_strcasecmp_ZN7testing8internal6String32CaseInsensitiveWideCStringEqualsEPKwS3_wcscasecmp_ZN7testing8internal6String23EndsWithCaseInsensitiveERKSsS3__ZN7testing8internal20StringStreamToStringEPSt18basic_stringstreamIcSt11char_traitsIcESaIcEE_ZNKSt15basic_stringbufIcSt11char_traitsIcESaIcEE3strEv_ZNSs7reserveEj_ZNK7testing7Message9GetStringEv_ZN7testing10TestResult20ClearTestPartResultsEv_ZN7testing10TestResult5ClearEv_ZNK7testing10TestResult15HasFatalFailureEv_ZNK7testing10TestResult18HasNonfatalFailureEv_ZNK7testing10TestResult16total_part_countEv_ZNK7testing10TestResult17GetTestPartResultEiabort_ZNK7testing10TestResult6FailedEv_ZNK7testing8internal12UnitTestImpl26successful_test_case_countEv_ZNK7testing8internal12UnitTestImpl22failed_test_case_countEv_ZNK7testing10TestResult19test_property_countEv_ZNK7testing10TestResult15GetTestPropertyEi_ZN7testing4TestC2Ev_ZTVN7testing4TestE_ZN7testing35FLAGS_gtest_also_run_disabled_testsE_ZN7testing28FLAGS_gtest_break_on_failureE_ZN7testing28FLAGS_gtest_catch_exceptionsE_ZN7testing17FLAGS_gtest_colorE_ZNSs6assignERKSs_ZN7testing28FLAGS_gtest_death_test_styleE_ZN7testing31FLAGS_gtest_death_test_use_forkE_ZN7testing18FLAGS_gtest_filterE_ZN7testing8internal35FLAGS_gtest_internal_run_death_testE_ZN7testing22FLAGS_gtest_list_testsE_ZN7testing22FLAGS_gtest_print_timeE_ZN7testing23FLAGS_gtest_random_seedE_ZN7testing18FLAGS_gtest_repeatE_ZN7testing19FLAGS_gtest_shuffleE_ZN7testing29FLAGS_gtest_stack_trace_depthE_ZN7testing28FLAGS_gtest_stream_result_toE_ZN7testing28FLAGS_gtest_throw_on_failureE_ZN7testing4TestC1Ev_ZN7testing4TestD2Ev_ZN7testing4TestD1Ev_ZN7testing4TestD0Ev_ZN7testing8internal12UnitTestImpl26RegisterParameterizedTestsEv_ZNK7testing8TestCase11GetTestInfoEi_ZN7testing8TestCase18GetMutableTestInfoEi_ZN7testing8TestCase11ClearResultEv_ZN7testing8TestCase14UnshuffleTestsEv_ZN7testing8internal16GetAnsiColorCodeENS0_10GTestColorE_ZN7testing8internal14ShouldUseColorEbgetenv_ZN7testing8internal13ColoredPrintfENS0_10GTestColorEPKczstdoutvfprintf__cxa_guard_acquirefilenoisatty__cxa_guard_release__cxa_guard_abort_ZN7testing8internal27PrettyUnitTestResultPrinter24OnEnvironmentsSetUpStartERKNS_8UnitTestEputsfflush_ZN7testing8internal27PrettyUnitTestResultPrinter27OnEnvironmentsTearDownStartERKNS_8UnitTestE_ZN7testing8internal27PrettyUnitTestResultPrinter11OnTestStartERKNS_8TestInfoE_ZN7testing8internal29PrintFullTestCommentIfPresentERKNS_8TestInfoE_ZN7testing8internal17TestEventRepeater7ReleaseEPNS_17TestEventListenerEmemmove_ZN7testing8internal24XmlUnitTestResultPrinterC2EPKcstderrfwriteexit_ZN7testing8internal24XmlUnitTestResultPrinterC1EPKc_ZN7testing8internal24XmlUnitTestResultPrinter26RemoveInvalidXmlCharactersERKSs_ZN7testing8internal24XmlUnitTestResultPrinter21OutputXmlCDataSectionEPSoPKc_ZNSo5writeEPKcistrstr_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc_ZN7testing18TestEventListenersC2Ev_ZN7testing18TestEventListenersC1Ev_ZN7testing18TestEventListenersD2Ev_ZN7testing18TestEventListenersD1Ev_ZN7testing18TestEventListeners7ReleaseEPNS_17TestEventListenerE_ZN7testing18TestEventListeners8repeaterEv_ZNK7testing18TestEventListeners22EventForwardingEnabledEv_ZN7testing18TestEventListeners23SuppressEventForwardingEv_ZNK7testing8UnitTest26successful_test_case_countEv_ZNK7testing8UnitTest22failed_test_case_countEv_ZNK7testing8UnitTest21total_test_case_countEv_ZNK7testing8UnitTest22test_case_to_run_countEv_ZNK7testing8UnitTest21successful_test_countEv_ZNK7testing8UnitTest17failed_test_countEv_ZNK7testing8UnitTest30reportable_disabled_test_countEv_ZNK7testing8UnitTest19disabled_test_countEv_ZNK7testing8UnitTest21reportable_test_countEv_ZNK7testing8UnitTest16total_test_countEv_ZNK7testing8UnitTest17test_to_run_countEv_ZNK7testing8UnitTest15start_timestampEv_ZNK7testing8UnitTest12elapsed_timeEv_ZNK7testing8UnitTest6PassedEv_ZNK7testing8UnitTest6FailedEv_ZNK7testing8UnitTest11GetTestCaseEi_ZN7testing8internal27PrettyUnitTestResultPrinter16PrintFailedTestsERKNS_8UnitTestE_ZNK7testing8UnitTest18ad_hoc_test_resultEv_ZN7testing8UnitTest18GetMutableTestCaseEi_ZN7testing8UnitTest9listenersEv_ZN7testing14TestPartResultD2Ev_ZN7testing14TestPartResultD1Ev_ZN7testing12TestPropertyD2Ev_ZN7testing12TestPropertyD1Ev_ZNK7testing8UnitTest20original_working_dirEv_ZNK7testing8UnitTest11random_seedEv_ZN7testing8UnitTest27parameterized_test_registryEv_ZN7testing8internal12UnitTestImpl32SuppressTestEventsIfInSubprocessEv_ZN7testing8internal30WriteToShardStatusFileIfNeededEvfopenfclose_ZN7testing8internal20ShouldRunTestOnShardEiii_ZN7testing8internal12UnitTestImpl23ListTestsMatchingFilterEv_ZN7testing8internal12UnitTestImpl25set_os_stack_trace_getterEPNS0_27OsStackTraceGetterInterfaceE_ZN7testing8internal12UnitTestImpl19current_test_resultEv_ZN7testing8internal12UnitTestImpl14UnshuffleTestsEv_ZN7testing8internal6IsTrueEb_ZN7testing8internal10AlwaysTrueEv__cxa_allocate_exception__cxa_throw_ZN7testing8internal10SkipPrefixEPKcPS2_strncmp_ZN7testing8internal14ParseFlagValueEPKcS2_b_ZN7testing8internal13ParseBoolFlagEPKcS2_Pb_ZN7testing8internal15ParseStringFlagEPKcS2_PSs_ZNSs6assignEPKcj_ZN7testing8internal16InDeathTestChildEv_ZNKSs7compareEPKc_ZN7testing14ExitedWithCodeC2Ei_ZN7testing14ExitedWithCodeC1Ei_ZNK7testing14ExitedWithCodeclEi_ZN7testing14KilledBySignalC2Ei_ZN7testing14KilledBySignalC1Ei_ZNK7testing14KilledBySignalclEi_ZN7testing8internal20ExitedUnsuccessfullyEi_ZN7testing8internal23GetLastErrnoDescriptionEv__errno_locationstrerror_ZN7testing8internal9DeathTest11LastMessageEv_ZN7testing8internal9DeathTest24last_death_test_message_E_ZN7testing8internal9DeathTest27set_last_death_test_messageERKSs_ZN7testing8internal21StackLowerThanAddressEPKvPb_ZN7testing8internal14StackGrowsDownEv_ZNK7testing8internal8FilePath21FindLastPathSeparatorEvstrrchr_ZNK7testing8internal8FilePath21FileOrDirectoryExistsEv__xstat_ZNK7testing8internal8FilePath15DirectoryExistsEv_ZNK7testing8internal8FilePath15IsRootDirectoryEv_ZNK7testing8internal8FilePath14IsAbsolutePathEv_ZNK7testing8internal8FilePath11IsDirectoryEv_ZNK7testing8internal8FilePath12CreateFolderEvmkdir_ZN7testing8internal8FilePath9NormalizeEv_Znajmemset_ZdaPv_ZN7testing8internal8FilePath13GetCurrentDirEvgetcwd_ZNK7testing8internal8FilePath19RemoveDirectoryNameEv_ZN7testing8internal24GetCurrentExecutableNameEv_ZN7testing8internal17g_executable_pathE_ZNK7testing8internal8FilePath14RemoveFileNameEv_ZNK7testing8internal8FilePath27RemoveTrailingPathSeparatorEv_ZNK7testing8internal8FilePath28CreateDirectoriesRecursivelyEv_ZNK7testing8internal8FilePath15RemoveExtensionEPKc_ZN7testing8internal14GetThreadCountEv_ZN7testing8internal2RED2Evregfreefree_ZN7testing8internal2RED1Ev_ZN7testing8internal2RE9FullMatchEPKcRKS1_regexec_ZN7testing8internal2RE12PartialMatchEPKcRKS1__ZN7testing8internal8GTestLogD2Ev_ZSt4cerr_ZNSo3putEc_ZNSo5flushEv_ZNKSt5ctypeIcE13_M_widen_initEv_ZSt16__throw_bad_castv_ZN7testing8internal8GTestLogD1Ev_ZN7testing8internal14CapturedStream11GetFileSizeEP8_IO_FILEfseekftell_ZN7testing8internal14CapturedStream14ReadEntireFileEP8_IO_FILEfread_ZN7testing8internal17GetCapturedStreamEPPNS0_14CapturedStreamEdup2closeremove_ZN7testing8internal17GetCapturedStdoutEv_ZN7testing8internal17GetCapturedStderrEv_ZN7testing8internal18SetInjectableArgvsEPKSt6vectorISsSaISsEE_ZN7testing8internal18GetInjectableArgvsEv_ZN7testing8internal7g_argvsE_ZN7testing9internal220PrintBytesInObjectToEPKhjPSo_ZNSo9_M_insertImEERSoT__ZN7testinglsERSoRKNS_14TestPartResultE_ZNSolsEi_ZNSt9basic_iosIcSt11char_traitsIcEE5clearESt12_Ios_Iostate_ZNK7testing19TestPartResultArray4sizeEv_ZNK7testing19TestPartResultArray17GetTestPartResultEi_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEED2Ev_ZTVSt15basic_stringbufIcSt11char_traitsIcESaIcEE_ZTVSt15basic_streambufIcSt11char_traitsIcEE_ZNSt6localeD1Ev_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEED1Ev_ZN7testing7MessageC2Ev_ZNSt8ios_baseC2Ev_ZTVSt9basic_iosIcSt11char_traitsIcEE_ZTTSt18basic_stringstreamIcSt11char_traitsIcESaIcEE_ZNSt9basic_iosIcSt11char_traitsIcEE4initEPSt15basic_streambufIcS1_E_ZTVSt18basic_stringstreamIcSt11char_traitsIcESaIcEE_ZNSt6localeC1Ev_ZNSt8ios_baseD2Ev_ZNSdD2Ev_ZN7testing7MessageC1Ev_ZN7testing8internal6String12FormatHexIntEi_ZNSt18basic_stringstreamIcSt11char_traitsIcESaIcEED1Ev_ZN7testing8internal27FormatTimeInMillisAsSecondsEx_ZNSo9_M_insertIdEERSoT__ZN7testing8internal6String15FormatIntWidth2Ei_ZN7testing8internal6String10FormatByteEh_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEED0Ev_ZN7testing8internal10scoped_ptrISsE5resetEPSs_ZN7testing15AssertionResult13AppendMessageERKNS_7MessageE_ZN7testing8internal10scoped_ptrINS0_24InternalRunDeathTestFlagEE5resetEPS2__ZStplIcSt11char_traitsIcESaIcEESbIT_T0_T1_ERKS6_PKS3__ZStplIcSt11char_traitsIcESaIcEESbIT_T0_T1_EPKS3_RKS6__ZN7testing8internal15CodePointToUtf8Ej_ZN7testing8internal16WideStringToUtf8EPKwi_ZNSt18basic_stringstreamIcSt11char_traitsIcESaIcEEC1ESt13_Ios_Openmodewcslen_ZN7testing7MessagelsERKSbIwSt11char_traitsIwESaIwEE_ZN7testing8internal6String15ShowWideCStringEPKw_ZN7testing7MessagelsEPKw_ZN7testing7MessagelsEPwisxdigit_ZN7testing8internal19UniversalPrintArrayEPKcjPSo_ZN7testing8internal7PrintToEPKcPSo_ZNSo9_M_insertIPKvEERSoT__ZN7testing8internal13PrintStringToERKSsPSo_ZN7testing13PrintToStringIPKcEESsRKT__ZN7testing8internal19UniversalPrintArrayEPKwjPSo_ZN7testing8internal7PrintToEPKwPSo_ZN7testing8internal17PrintWideStringToERKSbIwSt11char_traitsIwESaIwEEPSo_ZN7testing13PrintToStringIPKwEESsRKT__ZNSbIwSt11char_traitsIwESaIwEEC1EPKwRKS1__ZNSbIwSt11char_traitsIwESaIwEE4_Rep20_S_empty_rep_storageE_ZNSbIwSt11char_traitsIwESaIwEE4_Rep10_M_destroyERKS1__ZN7testing8internal17StreamingListener9UrlEncodeEPKc_ZStplIcSt11char_traitsIcESaIcEESbIT_T0_T1_ERKS6_S8__ZN7testing8internal8FilePath11ConcatPathsERKS1_S3__ZNSs6appendEjc_ZN7testing8internal17AppendUserMessageERKSsRKNS_7MessageE_ZN7testing8internal18PrintCharAndCodeToIhhEEvT0_PSo_ZN7testing8internal7PrintToEhPSo_ZN7testing8internal18PrintCharAndCodeToIhaEEvT0_PSo_ZN7testing8internal7PrintToEaPSo_ZN7testing8internal18PrintCharAndCodeToIwwEEvT0_PSo_ZN7testing8internal7PrintToEwPSo_ZN7testing8internal10scoped_ptrISt18basic_stringstreamIcSt11char_traitsIcESaIcEEE5resetEPS6__ZN7testing15AssertionResultlsIA2_cEERS0_RKT__ZN7testing15AssertionResultlsISsEERS0_RKT__ZN7testing15AssertionResultlsIA11_cEERS0_RKT__ZN7testing15AssertionResultlsINS_14TestPartResultEEERS0_RKT__ZN7testing8internal13HasOneFailureEPKcS2_S2_RKNS_19TestPartResultArrayENS_14TestPartResult4TypeERKSs_ZN7testing15AssertionResultlsIPKcEERS0_RKT__ZN7testing8internal18StreamableToStringIiEESsRKT__ZN7testing8internal27PrettyUnitTestResultPrinter15OnTestCaseStartERKNS_8TestCaseE__divdi3_ZN7testing8internal32FormatEpochTimeInMillisAsIso8601Exlocaltime_ZN7testing8internal8FilePath12MakeFileNameERKS1_S3_iPKc_ZN7testing8internal8FilePath22GenerateUniqueFileNameERKS1_S3_PKc_ZN7testing8internal18FormatFileLocationEPKci_ZN7testing8internal8GTestLogC2ENS0_16GTestLogSeverityEPKci_ZN7testing8internal8GTestLogC1ENS0_16GTestLogSeverityEPKci_ZN7testing8internal6Random8GenerateEj_ZN7testing8internal17StreamingListener12SocketWriter4SendERKSswrite_ZN7testing8internal9MutexBase4LockEvpthread_mutex_lockpthread_self_ZN7testing8internal9MutexBase6UnlockEvpthread_mutex_unlock_ZN7testing8internal5MutexD2Evpthread_mutex_destroy_ZN7testing8internal5MutexD1Ev_ZN7testing8internal12ShuffleRangeIiEEvPNS0_6RandomEiiPSt6vectorIT_SaIS5_EE_ZN7testing8TestCase12ShuffleTestsEPNS_8internal6RandomE_ZN7testing8internal12UnitTestImpl12ShuffleTestsEv_ZN7testing8internal17StreamingListener12SocketWriter15CloseConnectionEv_ZN7testing8internal17StreamingListener12SocketWriter14MakeConnectionEvgetaddrinfosocketconnectfreeaddrinfogai_strerror_ZN7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEED2Evpthread_getspecificpthread_key_delete_ZN7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEED1Ev_ZN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEED2Ev_ZN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEED1Ev_ZN7testing8internal18ParseNaturalNumberIiEEbRKSsPT_strtoull_ZN7testing8internal13CaptureStreamEiPKcPPNS0_14CapturedStreamEdupmkstemp_ZN7testing8internal13CaptureStdoutEv_ZN7testing8internal13CaptureStderrEv_ZN7testing8internal17StreamingListener12SocketWriterD2Ev_ZTVN7testing8internal17StreamingListener12SocketWriterE_ZN7testing8internal17StreamingListener12SocketWriterD1Ev_ZN7testing8internal17StreamingListener12SocketWriterD0Ev_ZN7testing10TestResultC2Evpthread_mutex_init_ZN7testing10TestResultC1Ev_ZN7testing8internal18OsStackTraceGetterD2Ev_ZTVN7testing8internal18OsStackTraceGetterE_ZN7testing8internal18OsStackTraceGetterD1Ev_ZN7testing8internal18OsStackTraceGetterD0Ev_ZN7testing8internal17StreamingListenerD2Ev_ZTVN7testing8internal17StreamingListenerE_ZN7testing8internal17StreamingListenerD1Ev_ZN7testing8internal12UnitTestImpl21os_stack_trace_getterEv_ZN7testing8internal17StreamingListener20AbstractSocketWriter6SendLnERKSs_ZN7testing8internal17StreamingListener15OnTestCaseStartERKNS_8TestCaseE_ZN7testing8internal17StreamingListener16OnTestProgramEndERKNS_8UnitTestE_ZN7testing8internal17StreamingListener16OnTestPartResultERKNS_14TestPartResultE_ZN7testing8internal17StreamingListenerD0Ev_ZN7testing8internal12UnitTestImpl31SetGlobalTestPartResultReporterEPNS_31TestPartResultReporterInterfaceE_ZN7testing8internal12UnitTestImpl31GetGlobalTestPartResultReporterEv_ZN7testing8internal38DefaultPerThreadTestPartResultReporter20ReportTestPartResultERKNS_14TestPartResultE_ZNK7testing8UnitTest17current_test_infoEv_ZNK7testing8UnitTest17current_test_caseEv_ZN7testing10TestResultD2Ev_ZN7testing10TestResultD1Ev_ZN7testing8internal17StreamingListener18OnTestProgramStartERKNS_8UnitTestE_ZN7testing8internal17StreamingListener20OnTestIterationStartERKNS_8UnitTestEi_ZN7testing8internal17StreamingListener11OnTestStartERKNS_8TestInfoE_ZN7testing8internal37FormatCompilerIndependentFileLocationEPKci_ZN7testing8internal30GetBoolAssertionFailureMessageERKNS_15AssertionResultEPKcS5_S5__ZN7testing8internal26GoogleTestFailureExceptionC2ERKNS_14TestPartResultE_ZNSt13runtime_errorC2ERKSs_ZN7testing8internal26GoogleTestFailureExceptionC1ERKNS_14TestPartResultE_ZN7testing8internal27PrettyUnitTestResultPrinter16OnTestPartResultERKNS_14TestPartResultE_ZN7testing8internal25ReportInvalidTestCaseTypeEPKcS2_ifprintf_ZN7testing8internal18StreamableToStringIxEESsRKT__ZNSo9_M_insertIxEERSoT__ZN7testing8internal17StreamingListener9OnTestEndERKNS_8TestInfoE_ZN7testing8internal17StreamingListener13OnTestCaseEndERKNS_8TestCaseE_ZN7testing8internal27PrettyUnitTestResultPrinter9OnTestEndERKNS_8TestInfoE_ZN7testing8internal27PrettyUnitTestResultPrinter13OnTestCaseEndERKNS_8TestCaseE_ZN7testing8internal27PrettyUnitTestResultPrinter18OnTestIterationEndERKNS_8UnitTestEi_ZN7testing8internal17StreamingListener18OnTestIterationEndERKNS_8UnitTestEi_ZN7testing8internal24XmlUnitTestResultPrinter9EscapeXmlERKSsb_ZN7testing8internal24XmlUnitTestResultPrinter29TestPropertiesAsXmlAttributesERKNS_10TestResultE_ZN7testing7MessageC2ERKS0__ZN7testing7MessageC1ERKS0__ZN7testing8internal13DeathTestImpl6PassedEb_ZN7testing8internal10ParseInt32ERKNS_7MessageEPKcPistrtol_ZN7testing8internal17Int32FromEnvOrDieEPKci_ZN7testing8internal11ShouldShardEPKcS2_b_ZN7testing8internal27PrettyUnitTestResultPrinter20OnTestIterationStartERKNS_8UnitTestEi_ZN7testing8internal14ParseInt32FlagEPKcS2_Pitoupper_ZN7testing8internal16BoolFromGTestEnvEPKcb_ZN7testing8internal18StringFromGTestEnvEPKcS2__ZN7testing8internal17Int32FromGTestEnvEPKci_ZN7testing16AssertionFailureERKNS_7MessageE_ZN7testing8internal9EqFailureEPKcS2_RKSsS4_b_ZN7testing8internal14CmpHelperSTREQEPKcS2_S2_S2__ZN7testing8internal18CmpHelperSTRCASEEQEPKcS2_S2_S2__ZN7testing8internal14CmpHelperSTREQEPKcS2_PKwS4__ZNK7testing15AssertionResultntEv_ZN7testing8internal20DoubleNearPredFormatEPKcS2_S2_ddd_ZN7testing8internal15FloatingPointLEIdEENS_15AssertionResultEPKcS4_T_S5__ZN7testing8DoubleLEEPKcS1_dd_ZN7testing8internal14CmpHelperSTRNEEPKcS2_PKwS4__ZN7testing8internal14CmpHelperSTRNEEPKcS2_S2_S2__ZN7testing8internal18CmpHelperSTRCASENEEPKcS2_S2_S2__ZN7testing11IsSubstringEPKcS1_S1_S1__ZN7testing14IsNotSubstringEPKcS1_S1_S1__ZNKSs4findEPKcjj_ZN7testing11IsSubstringEPKcS1_RKSsS3__ZN7testing14IsNotSubstringEPKcS1_RKSsS3__ZN7testing8internal15FloatingPointLEIfEENS_15AssertionResultEPKcS4_T_S5__ZN7testing7FloatLEEPKcS1_ff_ZNKSbIwSt11char_traitsIwESaIwEE4findEPKwjj_ZN7testing11IsSubstringEPKcS1_RKSbIwSt11char_traitsIwESaIwEES7__ZN7testing14IsNotSubstringEPKcS1_RKSbIwSt11char_traitsIwESaIwEES7_wcsstr_ZN7testing11IsSubstringEPKcS1_PKwS3__ZN7testing14IsNotSubstringEPKcS1_PKwS3__ZN7testing8internal10scoped_ptrINS0_17StreamingListener20AbstractSocketWriterEE5resetEPS3__ZNSt6vectorIN7testing12TestPropertyESaIS1_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS1_S3_EERKS1___cxa_begin_catch__cxa_rethrow__cxa_end_catch_ZN7testing8internal10scoped_ptrIKSsE5resetEPS2__ZN7testing8TestInfoC2ERKSsS2_PKcS4_PKvPNS_8internal15TestFactoryBaseE_ZN7testing8TestInfoC1ERKSsS2_PKcS4_PKvPNS_8internal15TestFactoryBaseE_ZN7testing8TestCaseC2EPKcS2_PFvvES4__ZTVN7testing8TestCaseE_ZN7testing8TestCaseC1EPKcS2_PFvvES4__ZN7testing8TestInfoD2Ev_ZN7testing8TestInfoD1Ev_ZN7testing8TestCaseD2Ev_ZN7testing8TestCaseD1Ev_ZN7testing8TestCaseD0Ev_ZNSt6vectorIPN7testing8TestInfoESaIS2_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS2_S4_EERKS2__ZNSt6vectorIiSaIiEE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPiS1_EERKi_ZN7testing8TestCase11AddTestInfoEPNS_8TestInfoE_ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS2_S4_EERKS2__ZN7testing8internal17TestEventRepeater6AppendEPNS_17TestEventListenerE_ZN7testing18TestEventListeners6AppendEPNS_17TestEventListenerE_ZN7testing18TestEventListeners23SetDefaultResultPrinterEPNS_17TestEventListenerE_ZN7testing18TestEventListeners22SetDefaultXmlGeneratorEPNS_17TestEventListenerE_ZN7testing8internal12UnitTestImpl24ConfigureStreamingOutputEv_ZNSt6vectorIPN7testing11EnvironmentESaIS2_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS2_S4_EERKS2__ZN7testing8UnitTest14AddEnvironmentEPNS_11EnvironmentE_ZN7testing8internal10scoped_ptrINS0_16DeathTestFactoryEE5resetEPS2__ZN7testing8internal12UnitTestImplD2Ev_ZTVN7testing8internal12UnitTestImplE_ZN7testing8internal12UnitTestImplD1Ev_ZN7testing8internal12UnitTestImplD0Ev_ZN7testing8UnitTestD2Ev_ZTVN7testing8UnitTestE_ZN7testing8UnitTestD1Ev_ZN7testing8UnitTestD0Ev_ZN7testing8internal12UnitTestImplC2EPNS_8UnitTestEpthread_key_create_ZTVN7testing8internal23DefaultDeathTestFactoryE_ZTVN7testing8internal27PrettyUnitTestResultPrinterE_ZN7testing8internal12UnitTestImplC1EPNS_8UnitTestE_ZN7testing8UnitTestC2Ev_ZN7testing8UnitTestC1Ev_ZN7testing8UnitTest11GetInstanceEv__dso_handle__cxa_atexit_ZN7testing8internal15UnitTestOptions27GetAbsolutePathToOutputFileEv_ZN7testing8internal12UnitTestImpl18ConfigureXmlOutputEv_ZN7testing4Test15HasFatalFailureEv_ZN7testing4Test18HasNonfatalFailureEv_ZN7testing8internal31GetCurrentOsStackTraceExceptTopEPNS_8UnitTestEi_ZN7testing8internal14DeathTestAbortERKSsfdopenfputcfputs_exit_ZN7testing8internal13DeathTestImpl26ReadAndInterpretStatusByteEvread_ZN7testing8internal13DeathTestImpl5AbortENS0_9DeathTest11AbortReasonE_ZN7testing8internal16ForkingDeathTest4WaitEvwaitpid_ZN7testing8internal13DeathTestImplD2Ev_ZTVN7testing8internal13DeathTestImplE_ZN7testing8internal13DeathTestImplD1Ev_ZN7testing8internal13DeathTestImplD0Ev_ZN7testing8internal13ExecDeathTestD2Ev_ZTVN7testing8internal16ForkingDeathTestE_ZN7testing8internal13ExecDeathTestD1Ev_ZN7testing8internal13ExecDeathTestD0Ev_ZN7testing8internal15NoExecDeathTestD2Ev_ZN7testing8internal15NoExecDeathTestD1Ev_ZN7testing8internal15NoExecDeathTestD0Ev_ZN7testing8internal9DeathTestC2Ev_ZTVN7testing8internal9DeathTestE_ZN7testing8internal9DeathTestC1Ev_ZN7testing8internal16ForkingDeathTestC2EPKcPKNS0_2REE_ZN7testing8internal16ForkingDeathTestC1EPKcPKNS0_2REE_ZN7testing8internal9DeathTest6CreateEPKcPKNS0_2REES3_iPPS1__ZN7testing8internal15NoExecDeathTest10AssumeRoleEvpipefork_ZN7testing8internal23DefaultDeathTestFactory6CreateEPKcPKNS0_2REES3_iPPNS0_9DeathTestE_ZTVN7testing8internal15NoExecDeathTestE_ZTVN7testing8internal13ExecDeathTestEchdirenvironexecve_ZNSt6vectorIPN7testing8TestCaseESaIS2_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS2_S4_EERKS2__ZN7testing8internal18StreamableToStringIPcEESsRKT__ZNSt6vectorIPcSaIS0_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS0_S2_EERKS0__ZNSt6vectorIPcSaIS0_EE6insertEN9__gnu_cxx17__normal_iteratorIPS0_S2_EERKS0__ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE8_M_eraseEPSt13_Rb_tree_nodeISsE_ZNKSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE4findERKSsmemcmp_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE16_M_insert_uniqueERKSs_ZSt18_Rb_tree_decrementPSt18_Rb_tree_node_base_ZSt29_Rb_tree_insert_and_rebalancebPSt18_Rb_tree_node_baseS0_RS__ZN7testing8internal27CheckedDowncastToActualTypeINS0_11ThreadLocalISt6vectorINS0_9TraceInfoESaIS4_EEE11ValueHolderENS0_26ThreadLocalValueHolderBaseEEEPT_PT0__ZTSN7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEE11ValueHolderE_ZTIN7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEE11ValueHolderE_ZTIN7testing8internal26ThreadLocalValueHolderBaseE__dynamic_cast__cxa_bad_typeid_ZN7testing13PrintToStringIxEESsRKT__ZN7testing8internal11CmpHelperEQEPKcS2_xx_ZN7testing8internal11CmpHelperNEEPKcS2_xx_ZN7testing8internal11CmpHelperLEEPKcS2_xx_ZN7testing8internal11CmpHelperLTEPKcS2_xx_ZN7testing8internal11CmpHelperGEEPKcS2_xx_ZN7testing8internal11CmpHelperGTEPKcS2_xx_ZSt9__find_ifIN9__gnu_cxx17__normal_iteratorIPN7testing12TestPropertyESt6vectorIS3_SaIS3_EEEENS0_5__ops10_Iter_predINS2_8internal17TestPropertyKeyIsEEEET_SE_SE_T0_St26random_access_iterator_tag_ZSt9__find_ifIN9__gnu_cxx17__normal_iteratorIPKSsSt6vectorISsSaISsEEEENS0_5__ops16_Iter_equals_valIS2_EEET_SB_SB_T0_St26random_access_iterator_tag_ZSt9__find_ifIN9__gnu_cxx17__normal_iteratorIPPN7testing8TestCaseESt6vectorIS4_SaIS4_EEEENS0_5__ops10_Iter_predINS2_8internal14TestCaseNameIsEEEET_SF_SF_T0_St26random_access_iterator_tag_ZN7testing8internal12UnitTestImpl11GetTestCaseEPKcS3_PFvvES5__ZN7testing8internal23MakeAndRegisterTestInfoEPKcS2_S2_S2_PKvPFvvES6_PNS0_15TestFactoryBaseE_ZNSs12_S_constructIPKcEEPcT_S3_RKSaIcESt20forward_iterator_tag_ZSt19__throw_logic_errorPKc_ZNSs4_Rep9_S_createEjjRKSaIcEmemcpy_ZN7testing8internal15UnitTestOptions17FilterMatchesTestERKSsS3__ZN7testing8internal12UnitTestImpl11FilterTestsENS1_18ReactionToShardingE_ZN7testing14TestPartResult14ExtractSummaryEPKc_ZN7testing8internal17kStackTraceMarkerE_ZN7testing8internal19TypedTestCasePState25VerifyRegisteredTestNamesEPKciS3_isspace_ZSt18_Rb_tree_incrementPKSt18_Rb_tree_node_base_ZN7testing8internal28ParseGoogleTestFlagsOnlyImplIwEEvPiPPT__ZN7testing8internal11g_help_flagE_ZN7testing8internal24ParseGoogleTestFlagsOnlyEPiPPw_ZN7testing8internal28ParseGoogleTestFlagsOnlyImplIcEEvPiPPT__ZN7testing8internal24ParseGoogleTestFlagsOnlyEPiPPc_ZN7testing8internal27CheckedDowncastToActualTypeINS0_11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE11ValueHolderENS0_26ThreadLocalValueHolderBaseEEEPT_PT0__ZTSN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE11ValueHolderE_ZTIN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE11ValueHolderE_ZN7testing8internal12UnitTestImpl41GetTestPartResultReporterForCurrentThreadEv_ZTVN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE11ValueHolderEpthread_setspecific_ZN7testing8internal12UnitTestImpl41SetTestPartResultReporterForCurrentThreadEPNS_31TestPartResultReporterInterfaceE_ZN7testing32ScopedFakeTestPartResultReporter4InitEv_ZN7testing32ScopedFakeTestPartResultReporterC2EPNS_19TestPartResultArrayE_ZTVN7testing32ScopedFakeTestPartResultReporterE_ZN7testing32ScopedFakeTestPartResultReporterC1EPNS_19TestPartResultArrayE_ZN7testing32ScopedFakeTestPartResultReporterC2ENS0_13InterceptModeEPNS_19TestPartResultArrayE_ZN7testing32ScopedFakeTestPartResultReporterC1ENS0_13InterceptModeEPNS_19TestPartResultArrayE_ZN7testing32ScopedFakeTestPartResultReporterD2Ev_ZN7testing32ScopedFakeTestPartResultReporterD1Ev_ZN7testing32ScopedFakeTestPartResultReporterD0Ev_ZN7testing8internal24HasNewFatalFailureHelperC2Ev_ZTVN7testing8internal24HasNewFatalFailureHelperE_ZN7testing8internal24HasNewFatalFailureHelperC1Ev_ZN7testing8internal24HasNewFatalFailureHelperD2Ev_ZN7testing8internal24HasNewFatalFailureHelperD1Ev_ZN7testing8internal24HasNewFatalFailureHelperD0Ev_ZNSt12_Destroy_auxILb0EE9__destroyIPSsEEvT_S3__ZN7testing8internal13ExecDeathTest10AssumeRoleEvfcntlstrdupsigemptysetsigactiongetpagesizemmapclonemunmap_ZSt17__throw_bad_allocv_ZN7testing8internal24XmlUnitTestResultPrinter18OutputXmlAttributeEPSoRKSsS4_S4__ZN7testing8internal24XmlUnitTestResultPrinter17OutputXmlTestInfoEPSoPKcRKNS_8TestInfoE_ZN7testing8internal24XmlUnitTestResultPrinter16PrintXmlTestCaseEPSoRKNS_8TestCaseE_ZN7testing8internal24XmlUnitTestResultPrinter16PrintXmlUnitTestEPSoRKNS_8UnitTestE_ZN7testing8internal24XmlUnitTestResultPrinter18OnTestIterationEndERKNS_8UnitTestEi_ZNSt6vectorISsSaISsEE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPSsS1_EERKSs_ZN7testing8internal29ParseInternalRunDeathTestFlagEv_ZN7testing8internal12UnitTestImpl19PostFlagParsingInitEv_ZN7testing8internal18InitGoogleTestImplIcEEvPiPPT__ZN7testing8internal18g_init_gtest_countE_ZN7testing14InitGoogleTestEPiPPc_ZN7testing8internal18InitGoogleTestImplIwEEvPiPPT__ZN7testing14InitGoogleTestEPiPPw_ZNSt12_Destroy_auxILb0EE9__destroyIPN7testing8internal9TraceInfoEEEvT_S6__ZNK7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEE16GetOrCreateValueEv_ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS2_S4_EERKS2__ZN7testing8UnitTest13PopGTestTraceEv_ZN7testing8internal11ScopedTraceD2Ev_ZN7testing8internal11ScopedTraceD1Ev_ZN7testing8UnitTest17AddTestPartResultENS_14TestPartResult4TypeEPKciRKSsS6__ZTIN7testing8internal26GoogleTestFailureExceptionE__cxa_free_exception_ZNK7testing8internal12AssertHelperaSERKNS_7MessageE_ZN7testing8internal20SingleFailureCheckerD2Ev_ZN7testing8internal20SingleFailureCheckerD1Ev_ZN7testing24ValidateTestPropertyNameERKSsRKSt6vectorISsSaISsEE_ZN7testing10TestResult20ValidateTestPropertyERKSsRKNS_12TestPropertyE_ZN7testing10TestResult14RecordPropertyERKSsRKNS_12TestPropertyE_ZN7testing8internal12UnitTestImpl14RecordPropertyERKNS_12TestPropertyE_ZNSs6assignEPKc_ZN7testing8UnitTest14RecordPropertyERKSsS2__ZN7testing4Test14RecordPropertyERKSsS2__ZN7testing4Test14RecordPropertyERKSsi_ZN7testing4Test19HasSameFixtureClassEv_ZN7testing8internal2RE4InitEPKcregcomp_ZN7testing8internal30ReportFailureInUnknownLocationENS_14TestPartResult4TypeERKSs_ZN7testing8internal35HandleExceptionsInMethodIfSupportedINS_4TestEvEET0_PT_MS4_FS3_vEPKcDW.ref._ZTISt9exceptionDW.ref._ZTIN7testing8internal26GoogleTestFailureExceptionE_ZN7testing4Test3RunEv_ZN7testing8internal35HandleExceptionsInMethodIfSupportedINS0_15TestFactoryBaseEPNS_4TestEEET0_PT_MS6_FS5_vEPKc_ZN7testing8TestInfo3RunEv_ZN7testing8internal35HandleExceptionsInMethodIfSupportedINS_8TestCaseEvEET0_PT_MS4_FS3_vEPKc_ZN7testing8TestCase3RunEv_ZN7testing8internal12UnitTestImpl11RunAllTestsEv_ZN7testing8internal35HandleExceptionsInMethodIfSupportedINS0_12UnitTestImplEbEET0_PT_MS4_FS3_vEPKc_ZN7testing8UnitTest3RunEv_ZN7testing8UnitTest14PushGTestTraceERKNS_8internal9TraceInfoE_ZN7testing8internal11ScopedTraceC2EPKciRKNS_7MessageE_ZN7testing8internal11ScopedTraceC1EPKciRKNS_7MessageE_ZNSt20__uninitialized_copyILb0EE13__uninit_copyIPN7testing14TestPartResultES4_EET0_T_S6_S5__ZNSt6vectorIN7testing14TestPartResultESaIS1_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS1_S3_EERKS1__ZN7testing19TestPartResultArray6AppendERKNS_14TestPartResultE_ZN7testing32ScopedFakeTestPartResultReporter20ReportTestPartResultERKNS_14TestPartResultE_ZN7testing10TestResult17AddTestPartResultERKNS_14TestPartResultE_ZN7testing8internal35DefaultGlobalTestPartResultReporter20ReportTestPartResultERKNS_14TestPartResultE_ZNSt8ios_base4InitC1Ev_ZNSt8ios_base4InitD1Ev_ZNSsD1Ev_ZN7testing8internal23kTestTypeIdInGoogleTestE_ZTVN10__cxxabiv117__class_type_infoE_ZTSN7testing8internal26ThreadLocalValueHolderBaseE_ZTVN10__cxxabiv120__si_class_type_infoE_ZTSN7testing8internal26GoogleTestFailureExceptionE_ZTISt13runtime_error_ZTIN7testing8internal9DeathTestE_ZTSN7testing8internal9DeathTestE_ZTIN7testing8internal16DeathTestFactoryE_ZTSN7testing8internal16DeathTestFactoryE_ZTSN7testing8internal23DefaultDeathTestFactoryE_ZTIN7testing8internal23DefaultDeathTestFactoryE_ZTIN7testing31TestPartResultReporterInterfaceE_ZTSN7testing31TestPartResultReporterInterfaceE_ZTSN7testing8internal24HasNewFatalFailureHelperE_ZTIN7testing8internal24HasNewFatalFailureHelperE_ZTSN7testing4TestE_ZTIN7testing4TestE_ZTSN7testing8TestCaseE_ZTIN7testing8TestCaseE_ZTIN7testing11EnvironmentE_ZTSN7testing11EnvironmentE_ZTIN7testing17TestEventListenerE_ZTSN7testing17TestEventListenerE_ZTIN7testing22EmptyTestEventListenerE_ZTSN7testing22EmptyTestEventListenerE_ZTSN7testing8UnitTestE_ZTIN7testing8UnitTestE_ZTSN7testing32ScopedFakeTestPartResultReporterE_ZTIN7testing32ScopedFakeTestPartResultReporterE_ZTIN7testing8internal27OsStackTraceGetterInterfaceE_ZTSN7testing8internal27OsStackTraceGetterInterfaceE_ZTSN7testing8internal18OsStackTraceGetterE_ZTIN7testing8internal18OsStackTraceGetterE_ZTSN7testing8internal35DefaultGlobalTestPartResultReporterE_ZTIN7testing8internal35DefaultGlobalTestPartResultReporterE_ZTSN7testing8internal38DefaultPerThreadTestPartResultReporterE_ZTIN7testing8internal38DefaultPerThreadTestPartResultReporterE_ZTSN7testing8internal12UnitTestImplE_ZTIN7testing8internal12UnitTestImplE_ZTIN7testing8internal17StreamingListener20AbstractSocketWriterE_ZTSN7testing8internal17StreamingListener20AbstractSocketWriterE_ZTIN7testing8internal17StreamingListener12SocketWriterE_ZTSN7testing8internal17StreamingListener12SocketWriterE_ZTIN7testing8internal17StreamingListenerE_ZTSN7testing8internal17StreamingListenerE_ZTSN7testing8internal27PrettyUnitTestResultPrinterE_ZTIN7testing8internal27PrettyUnitTestResultPrinterE_ZTSN7testing8internal17TestEventRepeaterE_ZTIN7testing8internal17TestEventRepeaterE_ZTSN7testing8internal24XmlUnitTestResultPrinterE_ZTIN7testing8internal24XmlUnitTestResultPrinterE_ZTSN7testing8internal13DeathTestImplE_ZTIN7testing8internal13DeathTestImplE_ZTSN7testing8internal16ForkingDeathTestE_ZTIN7testing8internal16ForkingDeathTestE_ZTSN7testing8internal15NoExecDeathTestE_ZTIN7testing8internal15NoExecDeathTestE_ZTSN7testing8internal13ExecDeathTestE_ZTIN7testing8internal13ExecDeathTestE_ZTVN7testing8internal26ThreadLocalValueHolderBaseE_ZNKSt13runtime_error4whatEv__cxa_pure_virtual_ZTVN7testing8internal16DeathTestFactoryE_ZTVN7testing31TestPartResultReporterInterfaceE_ZTVN7testing11EnvironmentE_ZTVN7testing17TestEventListenerE_ZTVN7testing22EmptyTestEventListenerE_ZTVN7testing8internal27OsStackTraceGetterInterfaceE_ZTVN7testing8internal17StreamingListener20AbstractSocketWriterE_ZN7testing8internal18OsStackTraceGetter19kElidedFramesMarkerE_ZN7testing8internal18g_linked_ptr_mutexE_ZN7testing38FLAGS_gtest_show_internal_stack_framesE__pthread_key_create_ZTISt9exception7= I        1 R [ sy     AL[      ( B e k       H N [ k      "     2 = g m y ' ( )      j *   ( * -  .  9 0Q -W a 3 -  6  ;&, 5=V\ e    %CI [ by E G7= \"h0 MBH eO Q N*0 @TVgUm U<Resy S u{ Gx~ []  \[GM p^ ^  =7= ]= a]   d"8eCfOg`hfiqjwiklimin'iopqrst iu4J`v defg)h.i:j?iIkWl\ihmmiwn'iopqrstiu339 FxN X=X-     h N  F2 <Nb lFy F F F F F  N ' N8 B FZ ` i w }            !!!!1!;! C!\!d!r!x! ! !! !!!!! ! !! !!!!! " "" "" ." 5"<"U"[" " " " " " " " " " 4# E#K# ##$  $ $5$=$ G$N$U$a${$$$$ $$U?%U]%%%%% % %% % &#&3&F&U&s&y& &"&&& & &'2'8' X'v'''' '_'' (`(( '(82(8( G(9R(X( g(:r(x( (<(( (>(( (?(( (@(( )A)) ')Bs)y) )`)^)) )`*^e*k* w*}* ***=* +{ +^5+;+ J+ R+^+ ,, 7,T,Z, c, i,x, ,,, ,,,,,, &- s- - - - - - -  . . . 4. t.~./ / ?/~// /// |/// //#0)0 :0 A0N0 X0e0 o00 00 00 000 1 #1/1051 A1P10X1e1n11.2o2z22222 233 +3?3M3b3h3 q3 x3j}33 3m#4)4 84D4c4i4 q4}4 444-4 444 44i"5(5 :5R5X5 h555 555 5S6Y6 l6666 6687C7K7\7 h777 77 7707 8:8]8h888 888088901999]999 9 9999099i99M:X:w:}: :::):i:0:; $;k;;; ;;;0;;<0><]<g<<< <<<===/=U=t===== = !==0===>R=>H>0Q>>0>>?s?y? ????? ?@@ @@d@j@ p@@@@@@@@]@A A A "A 7A=A IA SAeA A A)AAA AAA B "B#B )B=BLBWBBBBB B BBB B BCC $C ACCCC C-C C CCC DD #D3D $?D[D %gDDD D &D 'D (DDE ) EE!E *-E5E@EFE +REfEqEEEEEEF FSFYF pF}F ,F F]FF F"F$F%G&XG'vG'G(G G)GG H'5H%FH*NHVHdH"pH+HH H$H%H&BI'uI'I(I J)J*JSJ'}JJTJJJ J!@K%UK*K%K*KK.KK"K+L#L SL$YL%L&L'M'M()M M)MMM'M -M0 NT.NFNRN iN!N%N*O%O*#O3O.;OKO"^O+OO O$O%O&:P'oP'P(P  Q)Q$QMQ'QQTQ(Q(Q(QQQ  R![R%pR*RRSS.S+S">S+GS%^S*fSSS S$S%S&CT'xT'T(T U)U-UVU'UUTU(U(U(UV#V :V!V%V*VV3WCW.KW[W"nW+wW%W*WWW W_X-fX .qX8zX0X /XX;Y~YYYYY Y;Z92ZDZmZSsZ(ZZZ Z!Z&[%2[*U[<[.[[[[ [: \\e\\\\\ \:]  ]3]9] >]>R]a]]]]] ]>]]^.^I^O^ b^ u^ 0^^ ^ 1^ 2^ 3^ ^ 4_ 5_ 6%_ 7G_-O_ 8Y_8h_q____``` +` 97`Z` :f``` ` ;`` <`A` a.aCaIa ua =aaa aDa >aaa ?bIbOb `b @mbzb <bAbbb ;bcc Cc =Occc cDc >cc<c ?c'd-d s1Ns1es1s`s s7sOs7sOs Ps7sOs )t7tO%t73tO}[}a}}}}}~ ~ ~ R7~ S=~ TU~g^~~~~~ K~~~~ *~#J Us  Vi" W.4 X@Ia Vi Y ZˀӀ [߀ \ ].6CKRX xu u؁uv)/ Bzς{|(}J V^idj ^v| _~ Vƒiȃ΃ `ڃ Vi a',<C )K[c{DŽ̈́  bi c&1: dFO\"kt [mu  Ȇ eІ   f + gi h iLJ̇Շڇ F"N` gi hÈ iψԈ݈'- ?nNofq gi j iˉԉ gi k i )2JR_gw} noqҊ gi j i$2 gFiLR k^d ipy‹ȋ ׋ no<qZ gnitz j iŒ g֌i܌ k i -5BJW] on~oq g΍iԍڍ j i " g6i<B kNT i`ir َ?_s g.i4: lFL iXaj  ِ`0 ) OP0Yʑ B,H mZn nƒג o /& p8QdsV ғ   "3Y;GM \ &t qg, Kєٔ+V?e r ̕ߕY  1:Caǖ %4@dw , sȗٗߗ t u  v$8IO wdj x| y z {Ęʘ |ܘVg }%HYb r ęY ,^= ~HQ _ g^xo  ʚ  <Ogm yo L M śϛ   $s~  ɜќ ۜ  L M + 4Vodw}    ԝ ݝ  )F O ir x   e ž Ϟ ؞& o ,9 M \xVY  ՠ  ?e2 С֡ 4Y<\b n,  ;ɢߢ&a=bUip K ۣVYYEW] , դޤ B CN ^d sVޥ3M,o  ĦVѦYئ   ( 5KT  ֧ߧ i (-6;FXc sz ب  H Rh~  ũ ҩ.YLxY~êӪ:@ U, VΫ׫  17 IUV\ e |Y, Ȭ߬V # 5FL ^jVq z YY%]w} , Ů֮IWY_w} , %, :B O^d sz  YVɰذ , * 7B LW dl y  Ʊױ t %Y.V9HT^t,|   ²Ȳ ײ޲   Y V+:BLYYųYͳ۳YYY%3GYO_YguY} q Ĵ ʹlش ߴF r% 08@ L ]d Lo M  ҵ ڵ  !,= EwǶͶ ޶, "3E[ Y·ٷ߷ ,  $7VDYM,qVYҸ *Y@YHTZ z ù .jp , ƺܺ!7`f,wV  Y Y:FoYx ,@VƼY# /K5,RVapVսI*5|"4ؾY4'- H,N m`t n˿Կ p  ,;H ZrK,V5I.=Q  Y40FYgm ~FFFJ.MXw} NFF J>]h LJJJNmx ,V)8K"4Y4'- fKl,r 5Y_, 5Y_, $50Y>,S0^5jYx,~ 5Y_, 5Y_ , $-57YB,W0`5jYu,{ 5Y_,5Y,05Y,# 5>5HYS_`,t}5Y,05Y !ZI4JY-45CYTYeYvYYYYYYYYY+YCI n LJJK, 5 Y_&,, >I5SYa_o,u 5Y[, 5Y[I*ArJY4=YNY_Yw} FK, 5Y_, 5'Y5_C,I [f5pY~_, 5Y_, ;5Y I!@MeJY4YYYY N;KA,J Yd5nY|_, 5Y_, 5Y_," 4?5IYW_e,k ;}5YIJ!Y149EYVYkY|Y  ;   K m\$_1,7 BLU5_Yg Fn\z__, J5Y E\_, 5Y&_4,HS5]Ye n\w__,5YI'JCYS4[mYYYY 8Q ;W h wK} m\_, B5Y F\_[, J$5.Y5 E?\K_Y,b q|5Y_,5Y \_[,5$Y/IC\gJY4YYYYsy   @  K m#\/_<,B BW`5jYr Fy\_,=5Y, J5Y E\_, )25<YH_U,ir5|Y \_,=5Y, ;5YI/:WJsY4YYYYYYw}  @  K m\_, B*55?YG FP\__q,|?5Y, J5Y E\_, 5Y$_1,EN5XY` g\r_,?5Y, ;5YIGJcYs4{YYYYYYgm 00"" BR^ "&'- RfsU^ 3I`y"4Gci v~ "( frx    #Ggm vt""*080@yS Zhq     =CPq} ^w}   f,BXnt2 gFiL X]c iot} 0FXjt69SY fn  s gi  l$ i09Bowt   4&79W] p"v"  gi" h.4 i@KTb grix~  i gi  i )8K]p6y t>gm y"  gi h i #8@KYtaw}        &';(bn0v0 0P iw&f004 ;G0OW `s0P09 BFN^z*0 9&? H[e"p    /LWc  Y  Z   C#) 1 D P\jr~] !7Di`x  7 7O *7 $71 ?7Esy i W,p i    $:Y i     /  O VU  l i       " A L      ' ; YC N V a s         l) J `Y  ` i  w 7   7 O  * 7   7   7 Y n   !1LYz`  7 7O *7 7 7<B^z %+2 \ ckz *$   W] e,    K  );VOo i 01A_`t} 7 7O *7 7  28 ` 7  7$O+ *97@ L7R)E Yly` 7 7O *7 7 #7)   &`8A N7U d7uO| *7 7 71GXrY&?_  ``   8 0  + ; OG 0M  /Y a j  !j! "!3! =!N!"_!-e!4! !8! !7!!!""- "5"""#3#^#k#s#}###### # #$$3$`B$P$ Z$7g$ r$7$O$ *$7$ $7$ $7$$$$ %%-%?%Q%c%q% z%%6%% %%7% %7%O%%& &2&D&&7&8&' ''7&' 2'7A'7H' T'7c'Oi'x'''''''U(k(((((((()*)@)V)))))*9*O*e*** *I*I*+5+Jm+++++ +J,I%,I.,K7,,=, O,X,5b,Yn,_|,,, ,,5,Y,_,,, ,,5,Y,[ -,- %-0-5:-YG-[R-Ij-----Y.4.A.I.b.Ys.Y.Y.. .J.I /I/K/,"/ 4/=/5G/YS/_a/,g/ y//5/Y/_/,/ //5/Y/[/,/  0050Y,0[70IO0e0x00001Y14"1B1YS1Yd1Y11 1J1I1I2K 2,2 $2-2572YC2_Q2,W2 i2t25~2Y2_2,2 2252Y2[2,2 2353Y3['3I?3U3h33333Y44424YC4YT4Yw4}4 4J4I4I4K4,5 555'5Y35_A5,G5 Y5d55n5Y|5_5,5 5555Y5[5,5 5555Y 6[6I/6E6X66666Y647"7Y37YD7Yg7m7 7J7I7I7K7,7 8 858Y#8_18,78 I8T85^8Yl8_z8,8 8858Y8[8,8 8858Y8[9I959H9z9999Y949:Y#:Y4:Y]:c: p:|:0:0:0:0::0:Rf;"{;;; ;+;9<9#=C=`=f===== >> &>6>B>"]>f>> >S>>>i?0? >?iE? M?R?Y? a?i?????@&@:@@@ Q@0W@ !c@r@0z@@@@l@(@U@iA$AiOA+A+B B(B9B?B NBBBBBCGCMC CDLDDD D+D+DYDe(EeE pEzE EEEEEE E\FFU:FRFgFmF F^F,F(FUG>-G ?GUG[G mGvGG(G^GH_H6H@BHjH |HHH HH H_II>=IWI]I trII IVI II=IY J=JYJ-JhJgqJ }xJJJJ]JJ J J K(!KU2K>KK KKK LLL (L`BLHL XLcwL}L LLeL"LiLjL gMi M MM#M i/M4M=MBMKM]MeMwM}M MMeM"MiMjN gNiN (N-N3N i?NDNMNRN[NmNuNNN N NhNkNNNN NnOl"O(O 1OnNOlcOiO rOnO OkOOO OsOOO PvP Ph*P 6PkCPIP VPvcP oPkPP PyPPP P (Q KQ`QuQQQQQQ1Q R`'R3R CR7QR [R7rROR *R7R R7RRRS S0SESZSoSSSS}SS`ST T7T /T7FTOVT *dT7zT T7TTU8U _UeU U7U U7U U7U7U ! V7 V72VGV\VqVVVV`V`V`W,W79W BW7WW7lW7sW W7WOW7WOW7WOXX-XBXWXlXXXXXXXXCY;KYY0Z~@Z<\ZhZ~Z<Z~Z<Z ZZZ[ [@[F[ a[[[[`[[ [7[ \7\O#\ *+\78\ A\7O\ W\7]\o\\\\\\\]]"^k!^ *^ 3^C^\^z^ ^^^^^__%_T_`n_z_ _7_ _7_O_ *_7_ _7__` ` ````aa'aOa~a`aa a7a a7aOa *a7a b7 bbb bb bb c"c7cLcWcsccc`cc c7c c7dOd *%d7,d ;d7AdSdd dde5e`Oe[e fe7me |e7eOe *e7e e7e e7eeff*f?fPfafrfg 3gHg]grgggggg`hh h7$h 3h7HhOVh *^h7eh th7zhhi !i7iDini`ii i7i i7iOi *i7i i7j  j7j$j9jNjcjxjjjjykkkkk2k@mIm Ommm{mmmmn4nPnlnnnnnnoo*oFobo~ooooop)pBp^pzpppppq*qFqqqqqr&r@rrrrs$s@s\ssssst"t>tZtttttu*uFuuuuuv.vNvvvvvw#w?w[wwwww x)xIxxxxy9y?y Ky Rycy myzy yyy"z z z zzez"{z zz zzz Vziz zzz zz{-{"C{ zI{ z_{}{{{{{{{{{{{{{{{{| ||:|@| k|Q|| V|i| ||| ||||| |}} $}-}D}K} KW}h}p} |}}} ;}}~*~2~@~Y~w~}~ ~ ~~ ~~~~~ ~Y_ r  # 9? Rd/ Ȁ /_p Á́ B77)=D !Pbh "t77 #I[c\) $5P %\    Ň &ˇׇ ,>Gp` LՈ=` ':N`U (cu  )ʼn׉ / .^ow {̊{ۊ *Xz   + ,ǍӍ `" L1CLu` 'ڎ` (B U[ )k}c -͏ߏ / /Ahrv` .ې // 6Ho ~ɑ֑ 0i̔  &0.COTgm 1s{ $%&c''( 4):@v'SΗԗ((($ ;!%* .\dw%*Ι"/+W] f mmrm0L0dћ0Gl{ 2m8ʜ"06bɝ  !/>V^l ž Ȟ՞ (<`tz֟ "( 8W] onoCՠq  gi!' j39 iEPXj g{i k i֡"z0j gĢi̢ Ӣآ i"DLW_lptѣ    ,,DUmkVä Ѥ[h2fIu[dppY\ BɥХ ޥ 3 ECggz Kͦ"0j gi    i'08p"¨ͨըpY2@PZxީ   )C@R^ r{ɪ  0 4< 5C 6J^f, V#%Bb Y4Ѭ% Q5,U 7x 9ܭ <VIYQ,Y 8f~ o 9Ʈ Ӯٮ / : V#%'Y6gz%YYʯЯ dǰͰ ۰n o(40R0c0o0x0P /iPqc gsiy k i² gֲiܲ j i :0L0ip YpanvǴ'- 9O a|  :@ L0Z0hqʶݶ  !:@ N,_kV}.Y6>W] e ,,, u ; <)IO dj = >ɹ ?  @" A4: :F VT#^f%pY, uźκ vݺ  B0PV Ck B D Eѻ׻ F G : V!#+3%=Yb r  ¼ Ҽ  #%3Y;GYO[%w} ~ Hʽ IF,O J^fw K  L M bо#ܾ%Y?J%Y4ܿ   I\dj o   N O P%ek   D  Q)/ R=ED    17 SDLDi|q}D T )9aU]w ~ ZnrpD/qq}Dr#Zf8 U&DR`jpr ^1w? SiZ Vbgn Wv X YD  m* Z5gDMh [    n2oPdC0q gi j  i(0B gSiY_ kkq i}"J0pj gi  i" &.9ANpVcmx Vi x 000)6U`  00 0=Jit   ,0 \<IQ ;]h ]u ^ !VYY        **++l+p+++   !)  '2EN 1Yx 1Y| %H_  ': \  Eam E]u =U '/ A!U '/ @!H] $=He )V2?Ndv"|4 $DXe 0'2NXa '<UKTpz _       ` a$ b( c, d0 e4 f8 < @ D H L P T X \ ` d h l p t x |         g                                   $ ( , 0 4 8 < @ D H L P T X \ ` d h l p ht ix |   j k                     l  m 1$7%=&''(:(I(X u){'ET('(6(E]i !%* ?'O\j.r{"+%* 1$7%=&''(F c)i'KILT2JV m!%* ? :Mu"+%*L. M 0'CMV # 9-D R 0^r{ o /  1  2* 36J Vj 4v 5 6 7- 88*3]q oz- n ?J\r o       p q$ r( s, t0 u4 v8 < @ D H L P T X \ ` d h l p t x |         w                                   $ ( , 0 4 8 < @ D H L P T X \ ` d h l p x  9(G R 0^r{ o /  1  2* 36J Vj 4v 5 6 7- 8#82;ex o- n (6U`r y       z {$ |( }, ~0 4 8 < @ D H L P T X \ ` d h l p t x |                                            $ ( , 0 4 8 < @ D H L P T X \ ` d h l p   %1: 9Fb onw /- n     ",?MjVs" 49COYW  ,4KVWfu"4 Y  ",?MjVs" 49COYW  ,-HVTcr"4 Y  ,8IfVo| " 49COYW  ,/8VL~Y  "/ @iF R[a owl i  ) '/8@ n'oB gVi\ jhms i q: gNiTZ kfl ix s2 gFiLR l^d ipy 4E Yi_e qw   YjR filr ~    Y '  "/ @iF RW] inv :I gZi` lqw i6Nky 7R gfilr ~ i 0Hj i  .; LiR ^ci uz! .; LiR ^ci uz&1 (sB gVi\b lnt i 's9R gfil lx} i 3T`u i  ,<Q]l~  '0- B9Ek]j ~i  l i  )$4=Lt  # *60>IW`  ' / @F S8^g  3NK`ZNd o8{0 O0 Od{ %3BTfx-@M 3T`u i   DTiu   $>0D BP\kt i  l i  '/ );KT`$   `( 08J0P B\hk i  l  i #3; )GW`l(1<HWa}  # *60>Ic0i Buk i  l $i*0 <LT )`py &8JS\k~  ,3<VPY  /5^> F Zc p8|0 O0 $;Sk)2:KWds  ,2=; C W` m8y0 O0 $;Sk)2:KWds  .4= E Yb o8{0 O0 $;Sk)2:KWds "*$0%e&''( 0)6<\'oV%* !Y)7"C+ $%J&''(G j)pv'0$%f''( %)+1g'0SSK, 5Y_+,1 FO5YYe_u,{ 5Y F\[, 5Y [I'49NZ(i(x( !%+*1(C(R(ay !%*'J ( Y; 4M Z i v  . .  % *  Y Y' YH "[ + % * " + $%&A'r'( )P's0$%'/'D(T )'*0DS]SqK}, 5Y_, 5Y_, ,55?YG FN\\[l,r 5Y[I4(((#;G ^!%*(((! 8!%*J'7GhY{4.. % * ? YS Yg Y " + % * " + (HTiv i  $7O[m 30B0g0v0iiiiI"a0p00000 Gr#-@JUmy (AKTt $=He a"7[ Y"> a"7[ a"7[    `  70  ,O80> *JY0_ mv49Tap$1BO]p ! $  $!) $  $!) a"7[  ,.?NVb Y a"7[ 7; 7J=\g d?? m??AM?e"y0B"  $DQ`EfFnG gi H  3$9%_&'' ()'T'3 J!%*%*'5.=Q"d+ H[n(>T ????l??? OGnGGGGG<G ( 1VGWcXp 0 Q]eia f  g0 9hBS \jev k l m n '% .o7H QpZk tq} r s t u  &:aIWb n{   - L:Weca f g( 1h:K Tj]n wk l m n '  &o/@ IpRc lqu r s t u 2aAOZ fs   $fQ`gfFnG gi H  H 30W0ii"020j0NY{amw{ {% I:RWifr:0+8Zdb m GQVieq0)BbJ Uq~  I *CN"Y0 j g0i7 ?DK iS\d|" D0u0ii4"_000)c 3;@I[et  99.8=S[gqv  9 9!0:?W_kuz  99.8=S[gqv  9 9!0:?W_kuz 40I0X0 ;0P0_0000iii6iOi`ii"00$0:On/>P[px.@IRals~    +07 @FeN X^fh pvg  h ll   ''!) 17o@ .IOpY agqp yr s tt u , # )4j9CjIP Y_kkmut___ _____ _$_(_,_@_D_H_L_P_T_X_\_`oDFfFF    $(,048<@  $(,048<@ kx  $(,048<@s t     a$(,048<@  $(,048<@   $(,048<@   ( )0% &| 3y zE g  !(/*=PWdt})5@KQo *1NUry !(Ge} '.KRjq)5Kf'4Tiu   % 7 B M X ^ g m             5 < Y _ w ~          ! 8 ? V ] t {         * 1 J Q j q           ) 0 R Y l s |     =] )0On !(@G_f$AHk;Bip")PWy LSz#*GNpw 7>jq,3_f*1\c/6NU| 'NUw~ 'IPry"IPry"DKmt"IP!DJWu|    # - 9 L Y y          ! !!%!1!>!P![!f!q!w!!!!!!!!!!! ""'"-"N"U"r"x"""""""""##3#:#Q#X#o#v######### $'$C$J$c$j$$$$$$$$$% %#%*%B%I%k%r%%%%%%%&1&V&v&&&&&&&'#'*'B'I'h'''''''''(("(:(A(Y(`(x((((((((()))6)=)Z)a))))))) **0*7*T*[*********++;+B+i+p+++++++ ,,2,9,e,l,,,,,,,--<-C-`-g-------".).P.W.......//E/L/x//////00C0J0u0|0000000 11)101H1O1g1n11111112292@2g2n22222223393@3b3i3333333 4444;4b4i4444444 5545;5]5d55555556646;6b6i6666666666666677777#7*71797A7H7O7V7_7k7q7w7}7777777777777777788828K8W8d8k888888889'9C9Q9m9{999999999::":0:>:m:::;;@;a;g;;;;;;;;;;<"<?<E<b<k<t<z<<<<<<<===8=>=P=d=j=|=========>>">->A>L>`>k>>>>>>>>>> ??!?:?I?R?k?z????????? @"@(@?@E@a@g@@@@@@@@@@AAA(A2ADAPA\A{AAAAAAAAAABB1B7BSBYBuB{BBBBBBBBCC/C5CLCRCnCtCCCCCCCCCDD:DAD_DhDDDDDDDDDDEE3ESEjEsE}EEEEEEEEEFF*F?FGFbFmFyFFFFFFFFFFFFF GG#G)G]|/6NUsz>a~ 8?X_sy29MTrx.4QW'1AIU`kv )5@KV`l2MVaq}%0<GMdj %+GMjp+7CO[q=D\c5<T[sz =Dc&>E]d}7>W^ry 3:SYv| '3?Up 5;Rfs +=IWdq~6=U\t{":AY`x29MTho %,@G[bv}>Efm*1W^$<C[b4;SZry")KRjq<Cah| 07T[x $0;FQ\q !'CIjp"BI`g~%FMsx&2>JVbnz&>E]d6=V]18U\y -4QXu$0;FQ[gr} "-7CNYdnz $-7JQmt#/5IS_hr$/CJ_u!*5ALWam|1@Ibqz*3>Teq| *;GRXkt(.AJUk| +AR^io'=Ndu(.AJUk|%Nw%Nw.?Uf|)@Gdk-=Qau#7GPYm}!*CRa&/8G_l2=_j~)4HSu';FZe .Lfq 6^mv-FUiyBRaq{  % > N ] m w           # - 6 O _ n ~           $ 4 > G e u        M ] l |           " 2 < E ^ n }        =M\lv",5N^m}#3=F_nw.Qajs 09B` 9IRk&DT]v!*>MVo-6]l/8_oxBR[t-6O_h=My,5>\lu8GPiy+Wg6FOXv Raj   5 @ P Y b v        !-!4!A!J!S!g!n!{!!!!!!!!!!!"!"5";"H"Q"o"u""""""""" ##>#N#W#p######### $$$$$-$=$C$S$Y$f$o$$$$$$$$$$$% %%*%1%8%?%F%M%T%[%b%i%p%w%|%%%%%%%%%%%&&&)&6&C&P&]&j&w&&&&&&&&&&&'''''2'A'R']'i'u'''''''(3(Y(t(((((():)e))))))*.*S*s*****++7+Q+++++++++++,,',F,e,,,,,-&-F-f------.2.I.O.g.n........ // /,/F/Y/m////////0 00"0<0T0l000000000 11$101<1H1T1j11111111222282P2V2t2z222222223363<3Y3_3|33333333 4484D4O4Z4e4p4z44444444455-545L5S5p5w5555555566&6C6J6g6n666666666677-747L7S7k7r7777777778!8>8E8b8i8888888888888999&919<9F9R9]9h9s9~999999999::":?:E:b:h:::::::::;*;5;@;F;^;d;};;;;;;;;;;<<<&<2<><J<V<l<<<<<<<<==4=:=R=X=v=|========>>8>>>[>a>~>>>>>>>> ??:?F?Q?\?g?r?}??????????@ @ @,@A@M@b@@@@@@@@@A A$A+ACAJAbAiAAAAAAAAABB5B`V`]`z````````a a)a0aMaTaqaxaaaaaabbb'b3b?bUbpbbbbbbbbbc#c;cAc_ceccccccccccc dd'd-d@dFdYd_dsdddddddddee7e>eVe]eue|eeeeeeeeff&fCfJfgfnffffffffff gg#g:gVg]gug|gggggggggh!h>hEhbhihhhhhhhhhi ii$i0iHUcp}ā܁!>E]dɂЂ5<T]gq}σ (.KQsyل߄)/GMfl̅ %?Ys݆͆ '7@TdmLJۇ!5ENbr{ˈڈ 4DMaqzʼnى3CL`pyʊӊ -6JV_tϋ*6BNZfr~ƌҌތ&2>KevÍ΍ٍ  -8CNYdozƎҎߎ !>JWbnzȏ.kepϑAJdr{ƒђߒ 3:FR^ēГܓ $0<HT`lxƔӔ"3DUfwŕҕ -:זޖ7>W^v}˗ؗ!9T[z̘Ә-D`{ҙ *7CNiw֚7OVnu՛#8>X^x~Ӝٜ '3Idȝ:@Z`~؞ޞ7=U[sy͟ӟ "=InàРޠ,>JWq¡̡ӡ )0HOgnĢӢ"/<NZgңܣ!9@X_w~Ԥ !(U\ɥХ (/D[lyƦ&,MStzȧϧڧ &2>JWdǨͨ !<C]krɩ9@\sêЪ 9@Zgt˫ҫ (/HcjѬ 2JQipЭ 'G^yȮ߮ 'DKcjۯ -4V]Ѱذ#*LSzıٱ 'Qmt߲6=Wco{dz*6BNZfr~ƴҴ޴$1>Za~ȵӵڵ %,BO\ivöԶ(5BO\ivķѷ޷,9FTcq͸Ը ,3KRjqǹι $+CJbiƺ޺!(ELdk»ɻ 8?biȼܼ18QXu|νս +2JQelžپ.5MThoܿ 8Eah %,DKj*7Sov &-R_l '@[b3@M[s(D`g '.Xer&-Fah*1SZw~ ,3T[ov!(JQsz!(JQsz1`msy!.JQn %,ELd":AT[n  =J_ls8FMk}&<]c !(b '1Mer-Fgn #<]07PWov ,3MTp1IVsz&GNy #0GNy:Agn-4HOho1Jbi(/QXz%GNu|2Ot6RZp %@Vbw/D[t&=T`i~0Og.DZ|)Hf&-7MT]dw~.DKho #)29LS\cls.ITnz4;T[ov  /8LR[dx~ +2ELdk$G^q )0MTr<Cel#ELnu 6LRls&HOqx '.BIRfm !(<CTip  :AKelv| %+5;EKU[eku{ '8CITZejv #0ITj ,2OUms(Ov+Ry<c&Mt7^!Ho 2YCj.:Fag '4ANTZamy !'?E]c{ & E Q ] s y          ' 4 P l s           + 2 J d       2 Z      % M u    =e,NU\cjq|8?IPs %Mel+8E\x29QXu|7>V]t{(5BO\iv5<T[sz07Rcmx,9Pls +2JQho &HOqx!CJls>Eiz#*KRe'-L^iv *1IPho  " ) A H ` g         !!!%!4[4f4444444455;;;;;><T<o<<<<<< =%=D=c=y=====>#>=>X>e>k>q>w>~>>>>>>>>>>>>>>>??8?>?D?J?P?V?\?b?i?p?w?~?????????????? @@#@0@GvIIIIIIJJ9J^JJJJJK0K:K\KfKKKKKKKL LL4L@L\LLLLLLLM/M9MCMgMqM{MMMMMMNNN[NNNNNNNO2OXOOOOPPPPPPP,QQQQ RR!R0RNRXRgRRRRRRS*SDSlS~SSSSS-TGTRTTTTTTTU"Uhѕ *DNhǖӖ'A`jvҗ &/9FzĘޘ%Ln'0:GiК#-GQkʛ֛jYs˝E{Þݞ5Tsӟ Xoyˠޠ*4NXzȡf /9E^q}ǣ "+@^v(2wХܥ &0MqǦ1:DQs|ħͧ*OXboʨ-Ga5?Ys}˪ iëݫ1Ke׬7mwʭӭ *BZv֮:T^t)C]wŰcױ)JTo޲]ѳ۳)C^gq~Ŵݴ-Lfǵܵ-7NXdĶ#0akxȷ&@U^hu̸ָ߸+5MW`jwݹM̺  *7DSlvŻ=WԼ %/GQZdq~Ƚҽ۽Xw*4=GTapȿտ;Zt  *7DSlv=W 2<Tq~ )Ckt~3=U_hr *f=G_ir| 4S Pgq}&E_y)3KU^huh .8AKXeKnw+DNfpy-U %3KTgt"=FP]D^<E,_$@IS_ky,Nh#-9ESkt#,6CPm(1DQ^ *D_hrMlv)5T}  ,lCMk[ >nx =G~R(zJ@ V*4Ahr7V` 6@ZtFn8Bak *4si _/Y-g ]C){aHwKU-6IVc)M#@MZ $2JSfs "/Lajt",Nu ;]vFPmw(E_y6PoZd/Nm&]g *6BPhq3=_y)6]w }       $ 1 > \ h u        ) C X a k x          ' H R r |    ( R    8ERaz;HUmv )6Xajt7@JW~ %>[hu'3?Men&0=Jg+Dan{7@JVby"+4>KXe-:GVo0=Jbku+MV_iv&/9FmwER_nHUbz )6Cenw *Qfoy 2 ? N j      !T!}!!!!!!!!!" ?" S"e"y"""""""###H#W#[#}######$ ($H$"\$|$$$$&$$($%*,%L%,`%%.%%0%%2%%&49&Y&6m&&&8&&&&& ''/'O']'c'q'{'''''''( ((%(6(L(^(r(((((((())1)?)E)S)a)u)));))=)*?/*O*Ac*******++D(+,+FN+R+Ht+x+J++L++N+N++P,P ,$,RA,RP,T,Tq,T,,V,V,,X,X,,Z-Z--\1-\i-s--------..,.C._.e.s.......//#/1/M/W/s/y////////0 00a-0a80<0c]0ca0q0w0c~0c0000000011181N1\1f1j1w1111111111222:2P2^2h2l2y2222222222333<3R3`3j3n3{3333333333444 4F4T4^4d4r4|444444444455 5.525X5f5p5v55555555555 66(626@6D6s666666666777%7+797C7T7^7l77777777777778 88!818I8S8]8a8x8~88888888888889$989<9h]9ha9r9|9h999h99h9999h9h9h::0:::F:Q:`:d:j:j:::j::::j:::j;j;;%;j);5;?;jC;O;Y;j];j;t;jx;;;;j;j;;j;j<<<j&<j<<F<P<jf<p<v<j<<l<l<<l<<<l< ===l-=7===lK=l[=e=o=ls===l===l===l====l=l >>l<>lR>\>b>lp>l>>l>>l>l>>? ??#?2?6?nW?nu???n???n?n???n???n?@@n@$@.@4@nL@n]@n@n@n@@@n@n@@@n@A An+ARA\A{AAAAAAAAAAAAB BBB&B0B6BFBJB[BeBoByB}BBBBBBBBBBBBBCCC'C1C5CFCQCUCbClCrCCCCCCCCCCCCD DD"D&D7DADGDVDZDkDuDyDDDDDDDDDDE EE(E.EFEeEEEEEEEEEFFF&F;FFFWFaFgF|FFFFFFFFFFG GG$G(G8GBGHGWGkGuGGGGGGGGGGG H$H(H8HBHLHaHgHrH}HHHHH_HHHHtHtHIIt$I.It?IKItOI\IfIlItzIIItIIItIIItIIItJJt-JtJJTJrJvJvJvJJvJJvJJJv KKv(K:KvKKWKvrKvKvKKvKvKKvKLvLv0LvGLvcLiLvwLvLLvLLvLvLLMMM4M8M}MMMMMMMMMMMMNNN6N:NKNUNYNfNpNNNNNNNNNNNNOO+O'6OIO'VOkOuO{OOOOOOOOOO PP'P2PlHlRlVlglql{lllllllm m/m3mTmXmimsmmmmmmmmnnnoDoSogoqowoooooooooooop ppp#p3p=pCpRpppppppppqq"q(q@q^q~qqqqqqqrrr.rLrlr}rrrrrrrrsss)sCsMsgsqsssssssssssss ttt*t.t>tHtNt]tatqt{ttttttttttttt uuu)u3u9uPuaumuquuuuuuuuuuuuvv"v&v3v=vCv[v_vovyvvvvvvvvvvvwww!w+w1wIwMw]wgw|wwwwwwwwwwxxxx7xUxuxxxxxxxxy y%yCycyty~yyyyyyyyz-zMz^zhznzzzzzzzzzz{ {{"{0{:{O{Y{j{t{{{{{{{{{|9|M|h|n|y||||||}8}U}_}p}v}}}}}}}}}}}~~~"~;~I~S~W~j~hu~y~~h~~~~~~~~~~~ (2<FPZgv 3=CRgm|ʀԀހ ",6J^t~с )9IOZ`kuyłς !,=GXaku΃ۃ#.CMX\|̈́ф#-7=GQUblv|˅υ)5Ttˆچ.8Uav}ˇׇۇ(37HSWdpzЈ.2CMSakuԉ %0DTdtz_ŠЊ,_7=HRat_ً)C`jy}Ό %9Nb|ōٍ %9FUivɎ֎)6EYfuƏՏ->]qƐА-1>DV`u|̑-7Xb̒ؒ (=H]cnxӓ"9L`(GK|l|p||ƕ|ו||!|%2<B|Z|^jt|x||ΖҖ~~~'17~N~_k~o|~~Ǘ~&Fk՘%5;FPTgnyęΙؙ(=Q^drƚ̚ךݚ&0AMQblśڛ 5@Q[luʜΜۜ 5I[o|˝۝'7GWalr|˞՞ߞ0FOXlƟџן !%6@FQcmq ΠҠ",AGR]oy}Ρ֡)/CQ[p{ɢӢ !+@KO\flͣףݣ "->HNbhs¤ȤӤ٤6FV`kuåإޥ/_<jCRdmommmۦ,@Ms}ħا#2F[alvƨԨ0P`j̩$7KXbvϪ -AKUfpvϫ#7DNcĬȬެ.;ALR\oíͭ )->HRVcmw{Į_Ϯٮ_ 8BZjͯѯ "(7;KUYjuyðͰ#-4Wkxұܱ 17FJZdhyѲ۲ *;EK_ip³ȳӳ%/9=ISYim~´ƴӴݴ+59JUYfpvȵݵ "7AQ[_p{Ͷ/9=Vbfv̷ַܷ  )-:DJbfvȸٸ&04EPTakq¹̹ҹ 1;AYwֺ̺ݺ)4IS]cnrʻջٻ #4>BS^boyǼܼ!';EWkx˽սٽ *0I^hxþݾ +6GQWmÿԿ޿ !+6G[hw "4>BS^boy  +?ISYdhx&04EPTakq$+=G\gx#8CT^dx~FP_tx ,V`os(28FPVg|%+6<GMX^io-=MWlp_2CMSgq{(3>M]l|!/?ISWcmq}!'5Q[w}$EIU_io_&,7Sx %/@Mak{);EOS`jt .8BW]hw "/9CWaht!+1?IO`u{ 2<FVapt !,0=GMeu{)KZ^  $;APqu%/5@DU_jn0:Dcmw 3=AX^mq)-FShnu#-7GQa|(,=CRVgqu*EOSjuy":DHY_jn(2<@PVaeq{+1@DU_ct~ 3=Xcz=AYcgx~%15FPZ^nt)-9CIS]anx|,6@DPZ`jw{!.8>Wgmy!3CSqu-3BYeiz #)48IS]amw} &06KO`jtx/9CIWar| (9CM]gw{!.8>Wgmy &*KO_im}26`duG\fw $1;AYnx)3Mr|4?CPZ`x  /G\fp&5>GQaqz $0EL^h} /3DNTfj{"3>BOY_s +6GQWos-7=Odn!';AKVe#->HYbqu +<FLaqu'7=Idn J^k/9?PT`jt )39QUlr(4K[ku'1BL]fw{.?IOcm#->HYbsw * ; E K _ i x              + 5 @ T ^ i }            ! + 6 J T _ s ~              ' + < G K X b h               * > H L ] h l y          (7O^h|_&0=_DOYp_{(=GM\mw}_ (QUblv'-<Q[ap_ (26CL $;EI`fu '1N[pv} &06HL]gk| )4EOUjuy,6<Uekw )8BM^s}__ (28G\bpv_ >NY/9NX^m_)->HLYcgt} !+/@FQUlvz"&6<GWa~    $ 1 ; E I V ` f x |             !!!&!0!6!H!R!\!l!v!!!!!!!!!!!!"""2"<"M"Y"]"j"t"z""""""""""" #'#<#I#T#X#i#o#~############# $$$4$D$J$V$q${$$$$$$$$$$%#%)%3%H%L%]%g%k%%%%%%%%%%%&+&@&J&U&p&&&&&&&&&&' '''/'9'='N'Y']'j't'z''''''''''' (()(>(I(Z(d(j(((((((((() ))-)I)Z)d)j)~)))))))))))*#*B*S*]*c*w*}*********++-+<+Y+m+w++++++++++++,,,,6,<,P,V,f,j,z,,,,,,,,,,,,----*-4-8-I-T-X-e-o-u-----------. ..#.'.3.=.R.].a.n.x.~..........//0/:/@/Y/m/w/////////000)0/0C0M0X0q00000000000111171L1V1\1p1t111111111111112 2$292C2X2c2t2~22222222222233 3+3J3S3w33333333_33444"4,4@4J4P4_4s4}44444444444 555+5?5I5O5^5r5|55555555555 666*6>6I6M6]6g6q666666666666777#7-737K7O7_7i7~77777777777 888)84888E8O8U8m8888888888889 999)989<9L9V9\9f9u9999999999999::/:9:J:S:b:f:v::::::::::: ;;(;2;8;L;V;`;k;z;;;;;;;$<.<><T<__<e<t<x<<<<<<<<<<<== =&=5=I=S=Y=h=|===========>>>%>4>H>R>X>g>{>>>>>>>>>>>???,?5?D?H?X?b?f?w????????????? @@@3@G@Q@W@f@z@@@@@@@@@@@@AA,A6A>AHAWA[AkAuA{AAAAAAAAAAAAB BBB,B6BSHS]ShSySSSSSSSSSSS TTT+TJT`TlTrTTTTTTTTTTUUU#U-UBULU]UiUmU~UUUUUUUUUUUUV VV!V'V?VTV^V{VVVVVVVVVVWWW3W=WMWWWhWrWxWWWWWWWXUX_XXXXXXXYY9YCYGYXYbYhYuYYYYYYYYYYYYYZZ*Z3ZDZHZYZcZiZvZZZZZZZZZZZZ[ [[%[+[8[D[[[e[i[z[[[[[[[[[[[[[[ \\#\'\8\B\L\P\a\k\q\\\\\\\\\\\\\]]"]1]5]E]O]S]d]o]s]]]]]]]]]]]]^ ^^0^4^E^O^Y^n^x^^^^^^^^^^^^___'_2_6_C_M_S_m_q__________```+`5`?`N`R`c`m`q`}````````````aa$a5a;aKa`aja{aaaaaaaaaaaaaab bb b1b;b?bPb[b_blbvb|bbbbbbbbbbbccc%c/c9c=cNcXc^cocsccccccccccccd dd$d.d2dCdIdTdcdgdxddddddddddddee+e5e;eSehereeeeeeeeeefff%f:fDfTfZfffqfufffffffffffffggg g*g?gIgZgfgjg{ggggggggggggghhhh$h|H|N|h|l|}|||||||||||}}!}%}2}<}B}\}`}q}{}}}}}}}}}}} ~~~&~0~6~P~T~e~o~~~~~~~~~~~~  $*CXbw 5JTitÀ̀'<F[fwԁ߁.8MXisyƂт  *?J[ekÃԃރ2=NX^wDŽфׄ$/@JPi~ÅɅޅ$.8BLV`jt~Ćӆ#-1JVZjtzLJˇ؇3>OYeÿֈڈ04DNcnrʼnˉډމ )39QUeoȊ̊܊ !'?CS]r}ʋԋ-1AK`ko|Œ׌/9NYjtzōЍ %/DO`jpǎ؎3>OY_wƏЏ֏ !,=GMakuΐސ)4>BSYdhy‘ڑޑ !%1;AM_iyĒݒ6GQWlvʓԓ !2<BM_im~ʔΔߔ$/JNimzɕ͕ޕ "&7AVaer|Ζٖݖ'15FQUblrɗڗ!6AR\bzʘԘژ&1BLRflv̙ۙ*8BFWaer~ʚښޚ%3=CTioz›ӛݛ06AOYcgt~Ȝ̜ݜ0;?LV\tĝΝԝ&:>O[jnʞΞߞ*.?IO^bs}ŸƟן$.4NXƠʠ۠ &*;EIV`dq~áӡ '6:KU[jnɢڢ '1KWjn_ǣ֣ڣ ")3MYlp_ɤؤܤ$+EO[swåoХߥ %+2AXhʦԦߦ$0?CT^dsw§ȧէ .CMSaiy}ʨ٨ݨ ",2=GMWagqw˩ߩ$BRfwЪڪު />Bcgxɫϫի߫/@KQ_jpzìǬج#'8BLak|ĭέح#,7AKU[akq{Ȯ 0ELZdhyʯЯگ )3=MW]k{ðǰ԰ް,>OYoyͱױݱ%/9CS]cqDzز0BS]sϳٳ߳)<@av}_ȴ̴ݴ%4C]mŵϵ $5CXczoƶͶ$CSg|ѷ׷%9CJVezӸݸ#'8BLP]gquƹ &;FLR\blvκغ !+/@L[_p|ǻѻջ *.?I^imzټݼ-IZdj~ǽѽս $5ALV\blw{ǾѾ׾#.2?IOgǿ߿+5;PZto(7;LXcms} 09HLmqo #26W[lvzo  )3PZt (26GQUfr (28PTeo "(@[{,2<FJ[gvzHL__jp_ $04EOU_im~!%6BQUfv "2GQbl})/G\f{ (9CTaev!04EOSdos 5?CT_cpz &:G[_pz7;LVZkvz)/Gf)3HRbl} '9CGXcgt~ %):EIV`fz 26GQUfqu "&7AEVaer|'15FQUblr!%6AER\bz&1BLRj!2<BZoy",2J_i~"8BLV`ju )->HL]gk| "-1>HNfj{!.8>Vq )3>HL]itx &6:GQUbhr| /<FQ[_p|",29IMZdhu{ .BO_s#/>BS_jtz,8CMS]cmw !%6BQUfr}*.?KV`fpv -BLaku-7=Ufrv(.<R\f| .8<HRVblp"&3=C\`lvz%;EOeouo !'17?Nb|_ "&7AGRdnr )8<MYhl}*4EO`ix| %0:@FPV\bnr %)6@FZjn!2<BV\p 1;AQUfpv#-7;LXgk|#4DYct~0:KT_iou*48ITXeou&0EPTakq 5@Q[au *.?IO_ct~*6:KU_ct %):EIV`fz#4>OYjw{ /3DNTcgx %):DHYdhu!%6@DU`dq{&0EPakq'7GQez*4:RVgq   % + C X b w               3 H R g r              ' 1 < V Z k u y             " ( 9 = N X b f v               # - 3 D H Y c m q            &*6@FW[lv &,=AR\bsw &6<LPako{ -8BFWaeq{ (9HL]gm~ &,=AMW]nr&0:>OVaq{,6KVZgqw&<HRXb *0HL]gk| 8W[w{BPZdhy *J[ek99 1;AN9^9s}99999 99,9AKQ9b9r999999999:9E9Tdtoo #'8BLP`jt .2CO`dpz   ! 1 ; E Z ` k v             !! !1!5!A!K!Q!b!f!w!!!!!!!!!!!!!"""(","="I"Z"^"j"t"z""""""""""""# ###*#.#?#I#M#^#i#m#z############$$/$9$I$O$_$t$~$$$$$$$$$$$ %%'%1%7%O%d%n%~%%%%%%%%%%& &&'&+&7&A&G&X&\&l&v&z&&&&&&&&&&'''&':'G'['w''''''''''''(((!('(2(N(R(n(r((((((((((((() )) )$)5)?)E)T)X)i)s)w))))))))))))* ***&*,*D*H*Y*c*g*x************** +++4+8+I+S+W+h+s+w+++++++++++++, ,$,9,C,G,X,c,g,t,~,,,,,,,,,,-)-3-H-S-d-n-t---------..#.8.C.T.^.d.|..........//"/6/C/W/l/v/////////////000!0'020N0R0n0r00000000000001 11 1$151?1E1T1X1i1s1w1111111111112 222&2,2D2H2Y2c2g2x22222222222222 3334383I3S3W3h3s3w33333333333334 4$494C4G4X4c4g4t4~44444444445)535H5S5d5n5t55555555566#686C6T6^6d6|666666666677"767C7W7l7w777777777777 888%8/858M8l88888888888899%999F9V9`9t9x999999999999: :: :+:<:F:L:e:z:::::::::;; ;-;7;=;Q;[;q;{;;;;;;;;;;<<<-<3<K<`<j<{<<<<<<<<<<<<< ===2=6=G=Q=U=f=q=u=============> >#>8>>>V>Z>k>u>y>>>>>>>>>>>>?%?)?:?D?H?Y?d?h?u???????????@@'@1@;@J@_@i@~@@@@@@@@@A AA(AGAKAgAkAxAAAAAAAAAAAAAB BBB(B2BPHPNPfP{PPPPPPPPPP QQQ/QDQNQ^QdQpQvQQQQQQQQQQQR R"R,R0R@RJRTRiRoRzRRRRRRRRRRRRRSS#S/S@SDSPSZS`SqSuSSSSSSSSSSSTTT,T0TATMT^TbTnTxT~TTTTTTTTTTTTU UU&U;UFUJUWUaUgUUUUUUUUUUUUUUVV,VCV]VrV|VVVVVVVVVVV WW%W/W5WIWSWZWiW~WWWWWWWWWWWX$XDXHXrXvXXXXXXXXXXXXYY-Y3YBYYYeYiYzYYYYYYYYYYYYY ZZZ#Z)Z4Z8ZHZRZ]ZaZqZ{ZZZZZZZZZZZ[ [[&[*[7[A[G[_[s[}[[[[[[[[[[\\\#\9\W\k\x\\\\\\\\\\]]]]#]4]8]O]Y]]]m]w]]]]]]]]]]]] ^^^$^*^;^?^P^Z^`^m^}^^^^^^^^^^^^^___._8_I_S_d_m_~______________`&`0`6`G`W`[`k`u`{``````````aa"a2adBdSd]dadrd}ddddddddddeee.e8eCeMeQebelepeeeeeeeeeeee ff f*f0f=fMfQfbflfrfffffffffffffg gg!g+g@gJg[gegvgggggggggh9hNhXhmhxhhhhhhhhhhhi ii+i@iJiPiaiqiuiiiiiiiiiiiiij j"j,j=jGjXjajrjvjjjjjjjjjjjjjj kkk/k9k?kLk\k`kqk{kkkkkkkkkkkl lll0l:l>lOlZl^lklullllllllllllm mm&m*m7mAmMmbmlmpmmmmmmmmmmmmmmn nn+n@nJnZndnunnnnnnnnnnnnno#o-o=oCoSohorooooooooop pp&p,p@pJpPpopypppppppppq"qBqRqlqwq}qqqqqqqqqqqqrrr(r2r8rIrMrYrcrmrqrrrrrrrrrrrr sss+s6s:sGsQsWsosssssssssssttt)t-t9tCtItZt^totyttttttttttttttuu#u)u4uDuHuYueuvuzuuuuuuuuuuuuuvv v5v?vOvUvevzvvvvvvvvvvvvw2wNRcms†҆,6:KVZgqwÇ·߇&6<HZdtzĈʈЈڈ ",2?OSdntÉӉ׉*4:GW[lv|ˊۊ  $5?CT_cpz̋׋%/?EQcm}͌ӌٌ !+5?IS]gv̍֍ڍl l"-7;LR]gvzǎ؎+59JUYfpv͏яޏ%:EV`f~ΐؐސ$.8BLVauʑԑ(.?CT^hl|ђג  $1;ARq͓ؓޓ #_.4IM[_fl}ǔ֔ *48ISWdnr͕ӕ+59EK[_pz~Ԗ$.4Lak{˗їۗ%5;KV`u{ɘ͘ژ.>NTdoy}™ƙ7GWgqКԚ  &7;LV\mq}˛ܛ %/3@JPaevٜݜ 0:>OZ^ku{Ýɝٝ3=R]nx~ʞ՞ٞ.DPnt~ӟן &,=[q}ʠΠߠ)-9CMQakuɡءܡ '17Ocm¢Ӣע,8<MWav|ʣգ٣%/LXmwΤؤ *;EK\q{ǥ˥إ &;FJWag{Ʀ̦ئ ,<L\z_ɧ_ԧڧ (2<QWbm}ͨרݨ #'3=CTXouũةܩ$9=ISYjnЪ֪'17LP\fl}ϫӫ %6:QWhl~Ь )/@DPZdhxƭ׭ "-1>HNfzŮٮ  #'4>DUjtʯίۯ )>IMZdj~ȰҰ#39I^hy˱۱$.2CNR_ioƲʲײ3>OY_wdzѳ׳ ,<L\lôдڴ ,7;HRXpʵе '+8BH\fpzͶݶ%04AKQim~÷ɷ 1;AYx|͸׸%2<QUfpz¹ӹݹ/9=TXkoкں 17BQUfptɻͻ޻&0EPakqǼ׼(2BHT[o IS|6FVfvſڿ#-3DHT^duy%/9=NX^os&,;?PZdhy%/?EQWfj{!'7LVflx~ !2<@LRbw'17H]gw} !+1BFR\bs#-7;RXimy &59JT^bs} )9?KQ`du%5JTdjv|,6FL\q{!+1BWaqw %+<@LV\m '15LRcgs} /3DNR_eu 2eo)->HRVgq %+5?IM^imz,0GM\s&,3=CNRcmw{  &15LVZqw'+7AE^k '-<@Q[eiz&0@FRXgk| &,<Q[kq} "7AQWg|  ,6<Mbl| .2CMQbmq~"&7AEV`dt~ $;F]imz #)CSYei &,<Q[p{*4>HR\fpz/aev &6KUekw}  1;?KQav&06G\fv|  *0AEQ[ar ",0=GKXblp/:>KU[sw *;EKcx '1;EOYcms}&0:>OY_pt'-<@Q[eiz&0@FRXgk| &,<Q[kq} "7AQWg|  ,6<Mbl| "&3=GK\f{ ",6@JTZd !%6@FW[gqw#'8BLPakq '-9?NRcmw{ #8BRXdjy} (8>Ncm}#4ISciy  $.2CMbmq~ '1;AKan '28MQblvz  &7LVfl| 15AKQbfw&*;EK\`lv|(,=GQUfpv,2>DSWhr|(=GW]io~ -7=Q[l&,7P`p .=GRXhx 2<MWhq&0@FVu %+<@Q[_kq    % 6 : F P V g k |               ! + / @ J P a e q {              - 1 B L V Z k u {             ! 1 7 C I X \ m w {                + 5 F [ e v |             *:JZjz#DS]m}%/@Lak| )37HNY]t~ *.>DOS_im #04EOUdhy #)8O[_pz*.?ISWcms} !-7=Ncm}'17HLXbhy})3=AR\bsw*0?CT^hl})3CIU[jn *.?I^imz $1;A[kq}#-1BLP`j '2IUYflx7LVkv    # 2 B R b r          !!.!8!C!I!^!b!s!}!!!!!!!!!!""","6"@"D"U"_"e"v"z""""""""""# ##!#-#3#B#F#W#a#k############$$$%$/$9$=$N$X$^$o$s$$$$$$$$$$$$%%&%,%;%?%P%Z%d%h%y%%%%%%%%%%%%%%&&%&/&?&E&Q&W&f&j&{&&&&&&&&&&&&& ''%'+';'P'Z'j'p'|''''''''''''((.(4(@(F(P(_(c(t(~(((((((((((()))$)4)I)S)c)i)u){))))))))))))))**(*,*9*C*I*]*g*x************+ +++$+/+H+X+h+x++++++++,=,J,\,k,u,,,,,,,,,,,, ---*-.-?-I-S-W-h-r-x------------....4.@.F.U.Y.p.z........////#/4/>/H/L/]/g/m/~///////////// 00#0)050;0J0N0_0i0s0w00000000000000 11141>1N1T1`1f1u1y111111111111122$242:2J2_2i2y222222222222 33)393?3K3Q3[3j3n3333333333333344)4/4?4T4^4n4t444444444444444 55(53575D5N5T5h5r5555555555556 666)6/6:6S6c6s666666666667771757_7c7t7~7777777777778 88"8(8.888C8G8X8b8f8w8888888888888 99939R9V9r9v99999999:::':1:N:m:v::::::;;;%;1;?;Q;e;r;;;;;;;;;;;;<<<!<+<5<J<T<i<t<<<<<<<<<<<<==$=5=?=E=Y=_=j===========>>>*>8>B>S>]>g>|>>>>>>>>>>>> ??'?+?8?D?T?X?i?s?w?????????????@@&@*@7@A@G@\@c@m@z@@@@@@@@@@@@@@A'A:A>AUA`AdAuAAAAAAAAAAAABBBB*B4B>BHBLBXBbBlBBBBBBBBBBBBCC(C,C?COCYC]CjCzCCCCCCCCCCCCCCCDD+D5DJDUDfDpDvDDDDDDDDDDDE EEE2E6EMEWEgEkE~EEEEEEEEEEEEEF FF'F1F5FGFQFfFpFFFFFFFFFFFF GG#G-G1G=GCGMGWGaGuGyGGGGGGGGGGGGHHHHH/H9H=HNHXH^HvHHHHHHHHHHHHI/I5ICI_IiIIIIIIIIIIJJ(JCJMJcJiJuJJJJJJJJJK KK!K+K5K@KJKiKKKKKKKKKKL LL%L/LLLVLcLpL}LLLLLMM#M-M8MSHSLSYScSmSqSSSSSSSSSSSSSSTTT+T5T?TCTTT^TsT~TTTTTTTTTTTU UUU'U-UEUIUZUdUyUUUUUUUUUUUUVV&V7VAVGV_VtV~VVVVVVVVVVW WAWKWZW^WWWWWWWWWWWXXX)X3XIXSXYXgX}XXXXXXXXXXYY%Y+Y9YOYYYcYyYYYYYYYYYYYYYZZZ Z$Z1Z;ZAZUZ_ZoZsZZZZZZZZZZZZ[[![7[A[G[U[k[u[[[[[[[[[[ \\\'\=\G\Q\g\q\w\\\\\\\\\\]]])]/]5]D]H]e]k]]]]]]] ^^+^6^L^V^a^k^^^^^^^^^^^^^^___"_,_0_=_G_Q_W_a_k_o_|______________` ``2`<`F`J`h`l`{``````````aaa&a8aMaWaaaka{aaaaaaaaaaaaaabbb"b,b6bHT Xis} ʆ Άۆ   #-7 ;GQ[e iv ɇӇ ׇ ' +<FPZd hu ˆȈ҈܈   $.8 <IS]g kx ˉщۉ   % 3 CMWa q{ Њ %/DNXbr|ŋߋ   _ix|Œߌ!3NXuÍǍ؍(26CMW[lvҎݎ&04EPTakqɏӏ׏ .8I[lxƐ̐ڐ"6Mdܑ֑!+AKQ_uÒؒ#1GQ[q{œϓ#-CMSgk|ϔ۔  &06=LPako{ƕߕ/9?McmwƖЖ 5?I_ioӗݗ1;AUjtɘϘ'-8>DJPV\bhnxęΙݙ#26GMWaevǚ͚ךݚ%+R~ "(2<@Q]lpĜȜߜ.:IM^juӝݝ*48DQfpǞ؞ 0:EZdosΟ؟ܟ !-<@Q]hrxˠ۠ (8BWbs}ơʡۡ *@JP^t~¢ע"0FPZpzģΣ",BLRbhntz֤ %/9=NZim~ǥͥץ  *0;OU_j|Ŧ٦''0:@OSdnxǧѧק )48EOUmqƨ̨Ҩ $.2>HN_ct~ɩө٩ #-BMQ^hnȪ̪٪"&2<Q\`mw}̫׫۫'15BJXbfr|֬ڬ &06NRcmq}­ȭ1<@MW]x|îԮ߮)->HRfptů˯گޯ (37DNTmqưʰװ!6AER\b|ʱձٱ&0EPakwDzѲײ(=HYciҳܳ)37HSWdntƴ۴ $5?COYny}ʵԵ)/H]g|¶׶,6<Wlvҷܷ '17RgqƸ̸0:@TfpŹ,6<QWagq{źϺٺߺ&0;E\_gm|ͻػܻ (28PTeosȼݼ "7AVar|νٽݽ",2<FP[o̾ݾ.?JY]vǿѿ!'2<FP\o  -7HS]y 59FRgm| (37DNTlp#'4>D\`q{$.4Lak$=R\q|/DNcn!6@DU`dq{(2GRcms2=AR\f{#)C^im~'<FWar{"7BS]cx 1:IM^hl}!:OYio )9?KQ[ekq}1<MW]r|!1;LVako "3=R]anx~#-BMQ^hn2=ANX^vz "->HNf{!.8>Vku (.F[ez6KUju",6<FPZdnx "&7AEV`f~(2GRVcms"7BFS]c{'26CMSk"3=C\q{ %/5Ncm!'@U_t 2QUqu'1@U_fq $(5AEV`du 37HRVgrv '+<FJ[fjw,6EIZdjz~'+<FL\`q{  (.>BS]cnz&1BLRj!2<BZoy",2J_i~ &,;?`dqw"&39IMnr "3BFWaev .4?Ycp"2BVgvz "-7;LReiy 15EOUfjv!26BLRcgw)-=GM^bnx~ '-9?OSdt '17QUfpt %+EIZdhy9=NX\mx| -1>HW[lvz *0HYhl}!%2<B\`q{ &06PTeos  $*DHU_nr ",0AKO`ko|#4>S^boy(2GRVcms &*;FJWag %/9CMWfjw *48ITXeou '<GKXbh0;?LV\vz$/3@JPj#4>D]r|  & 0 6 O d n            " ( A V ` u             3 H R g r                 ( 2 A V ` k            # - B M ^ h n         4?PZ`y&1BLRk#4>JN_im~  *4:DNXblr|.>NXcitz  &*;EK[_pz'-AEV`fq} )48EOUmq$(5?E]ar| %/;PZ`o*48ITXeou $.8BHWlv)/G\f{7LVkv '<FJ[fjw'1;EOYcmw %):EIV`f~ *59FPVnr  % ) 6 @ F ^ b s }            !!!&!0!6!N!c!m!!!!!!!!!!"" "&">"S"]"r"}"""""""""###.#C#M#b#m#~#########$$$3$=$R$]$n$x$~$$$$$$$$$%#%-%B%M%^%h%n%%%%%%%%%%%%%%& &&&0&:&>&O&Z&^&k&u&{&&&&&&&&&&& '' '*'?'J'N'['e'k'''''''''''( ((((,(9(C(I(a(r(v((((((((((((( ))))-):)D)J)b)f)w))))))))))))*****4*:*R*V*g*q*********** ++$+*+B+W+a+v++++++++++ ,,,2,G,Q,f,q,,,,,,,,,,- -"-7-A-V-a-r-|----------.'.1.F.Q.b.l.r.........//!/6/A/R/\/b/z/////////00&010B0L0R0j0000000000001 11 1*141>1H1N1X1b1l1v11111111"252 I2V2a2w2222 2222 2222 2 333(3 ,393C3M3W3 [3h3r3|3333 3333333 3 334 444&404 44G4]4g4q4 u44 444 444 445 5 5+5 ;5E5Q5 c5 x5555 5555 555556 666(626<6 @6M6W6a6g6q6{6 66666 66666 66667  77!7+717;7E7 I7V7`7j7p7z77 7 777777 777788 8 8*848:8D8N8 R8^8h8r8|8 88888 88888 8888999 9)939=9C9M9S9 l9 }9999 9 9999 9999 :"-:@:"D:T:^:h:"l:|:::"::":"::::"::::";";$;.;"2;>;H;"L;Y;c;i;"z;";";";";";";;<<5<[<n<$<<<<<<<$<<<=$==&=2=$6=C=M=W=a=$e=r=|===$=======$=====> >$>$%>2>=>C>N>T>_>i>$m>>>>>$>>$>>>$>??$?.?:?D?$T?d?$t?~??$?$????$????$@@@(@2@<@$@@M@W@a@k@u@$y@@@@@@@$@@@@@$@@@AA$A!A+A5A?A$CAPAZAdAjAtA~A$AAAAAAA$A$AAAABB$B B*B4B>BHB$LBYBcBmBsB}BB$BBBBB$BBBBB$BBBCC$C#C-C7C=CGCQC$UCbClCvC|CCC$C$CCCC$C$CCD D$D&D0D6D$OD&cDpDzDDDD&DD&DD&DEE&6E@E&`EhE&}E(EEEEE(EEEE(EFF(F(F2F(6FMFSF(kF(oF|FF(FFF(FFFF(FFGG(G(0G:GIGVGcGG*GGGG*GGG*G HHH'H1H*BHLHVH`H*qH{HH*HHH*HHHH*HHH*II*#I0I*4IQIWI*fI*jIII*IIII*III*I JJ*J'J7JAJ*EJVJ`J*qJ{J*JJ*JJJ*J*JJJ*KK**K4KRKKKK L,!L>LHLSL]L,aLrL|LLLLLLL,LLL,LLLLM, MM"M,M,0M=MGMMMWMaMqM{M,MM,MM,MM,MMMM, N,N&NfBfSf]fgfkf|ffffffffffffgg(g2gBgHgTgZgigmg~gggggggggggggghhh(h.h>hSh]hmhshhhhhhhhhhhhhhi ii$i9iCiSiYiii~iiiiiiiiiiiiij jj"j.j8j>jOjdjnj~jjjjjjjjjjjj k kk$k(k5k?kIkMk^khklk}kkkkkkkkkkkk lll(l2l8lPlelollllllllllmm"m(m@mUm_mpmvmmmmmmmmmmmmnnn"n,n6nwMw]wmw}wwwwwwwwwxx,x2xBxFxWxaxkxoxxxxxxxxxxxxyyy,y6yFyLyXy^ymyqyyyyyyyyyyyyyyzzz z,z2zBzWzazqzwzzzzzzzzzzzzzz{{{({={G{W{]{m{{{{{{{{{{{{{| ||"|&|2|<|B|S|h|r||||||||||||} }}}(},}9}C}M}Q}b}l}p}}}}}}}}}}}}}~~~,~6~<~T~i~s~~~~~~~~~ &,DYctz&0:@O_o€̀݀.4DHYcmqÁԁ .8HNZ`os΂҂ނ".4DYcsyÃǃ؃ *?IY_ońɄڄ $(4>DUjtɅυۅ *.;EOSdnrÆ͆ކ!.8>Vku· (.F[ev|ˈψ܈ (2<BQ2`isĉ2ȉډ22+5?2PZ`2q222Ί؊ފ22 2'1;2LV\2m222ʋԋڋ22 2)2=H2\fp222ƌ2ڌ2 2'12BLR2c2w22ʍ2ۍ274FOYhw4̎؎4܎4$49C4T^4o|444̏֏44#44>4O\4mw444ĐАڐ444/<4MWag4x44đ4ّ444-7AG4X4lw444ɒӒݒ44 41;4LY4jt~444ȓғܓ4440:4KX4is}444̔֔444+84<MW4hr444̕4ܕ6'0:IXqw66Ԗޖ666(26BLR6b6|666Зڗ66 6$.6>HN6^6r}666ј66 6$.46D6HXc6w6řҙ *6R\͚ښ $/5IM^hny}Лڛ&0EOU`duœ̜֜ڜ $1;?P[_lv|˝ϝ &*;QeoyÞǞӞݞ )39Q`duɟԟ؟%/3@JN_jn{Ġՠߠ 9JTdnġʡ !%6AER\b|̢֢ܢ )48EOUoģΣأ $.6FJ[eoƤΤݤ &0EOYcs}ҥݥ+5FPepɦަ  &06<FQ[u˧ۧ +;EPZ^oy}Ҩ֨",2J[jnƩ֩2=NXivzϪӪ (,9CIcgxϫ٫$.4JT^hrxѬܬ*4ITeouɭͭ99"2<FLV`j9n~99̮֮99.8BH9W9n{999ܯ999/?O_itѰ_ܰ _%7AVar|ұޱ(2<QWbmIJʲ޲  )-:DJbfwóҳֳ/9VbfwǴʹ״۴6BFWagvzƵеֵ "&7AEVaer|ʶԶ#-1BMQ^hnŷɷַ!2=ANX^vиԸ 39DTXis}ù͹)3HSdnt˺ܺ#8CT^d|ֻ̻ܻ 3GTdnyżϼӼ 0:>OY`fqwŽϽ-8<ISYsþ;Ӿ 2<GK\f{տ߿ 5=GRhx\ '1;AKO\fpv|  4AP_iox)3DNR_is}  *4>HL\fpv&*:DJ[_ku{09JN^hn #:DXbs 0:>OZ^ku  ,6@U_pz %:EV`f';EVbfv$(8BFWbfs}(28EPdnx"6@PVfz "2FPep"3=C[kz5IO]cs} ,6@FL_cz!'BLVbq>> %>)6>>U`>u>>>>>>!>0>4EO>Sdo>s>>>>>>A>K>U>_>i>s>}>>>>>>>>>>>>> >)9IXQgqQ Q%Q<GQ\flQ{QQQQQQQ,6Q:KVQZgqwQQQQQQ QQ!Q+Q5Q?QIQSQ]QgQqQ{QQQQQQQQQ$S3<FZS^oySSSSSSSSS /CWhl} '5?CVocrv*7KObmw{%/3FoSbfw'-8BS^hr|%)Xr| '-GVZ{'2AEbhw{UUUUUU$=W /9is*7Gfp /@Qbq '17QUfp %+EIZdy9=NXmx|-7=VZku *0JN_i~$>BS]r}26CM\`q{ -1BLP]gkx'+8BH^lv  &<JTitx(26GRVcms%04AKQgu)/ES]r} #1;P[_lv|.9=JTZp~ (28RVgq #4>BOY]iv $.2PTeoy ,6<FZ^o#7CMYcm/?T^dr| !6<KO`m|#4?CPZ`z$.2CNR_io!6AER\b| *59FPVpt )-:DJdy.8>Wlv *0I^h}";PZoz-BLal}(2<FR\`q{ &06PTeo   $ * D H Y c x                8 I X \ m w {             " , 2 L P a k                & @ D U _ t                4 8 I S h s w            (.HL]g|"<@Q[p{04EOdos $5DHYcgx8MWlw -7LWhrx !+@K\fl4?PZ`z (3DNZoy$.4Ncm"(BWav 6KUju+5JUfpv )>IZdj",6@JT^hrx *.;EKeiz"/9?Y]nx#-3MQbl   ! ' A V ` u           !!!5!J!T!i!t!!!!!!!!!! "")">"H"]"h"y""""""""""##2#<#Q#\#m#w#}#########$&$0$E$P$a$k$s$}$$$$$$$$$$$$%%%!%6%A%E%R%\%b%|%%%%%%%%%%%% &&*&5&9&F&P&V&p&t&&&&&&&&&&&& '')'-':'D'J'd'h'y'''''''''''(((!(2(=(N(X(^(x(|(((((((((())&)1)B)L)R)l))))))))))**%*6*@*F*`*u**********++*+4+:+T+i+s++++++++++++, ,, ,*,4,>,J,T,_,i,m,~,,,,,,,,,,,,--"-&-3-=-C-]-a-r-|----------- ...'.1.7.Q.U.f.p............ ///%/+/E/I/Z/d/y///////////00090N0X0m0x0000000001 11-1B1L1a1l1}11111111122!262@2U2`2q2{22222222223*343I3T3e3o3u333333333444#4)434=4G4Q4[4e4t4444444444444 55,565G5Q5]5r5|55555555566 6&646J6T6^6t6~66666666667777#7=7A7R7\7q7|77777777778 88(848I8S8d8v88888888888 9'919M9S9h9}999999999::!:2:<:B:[:p:z::::::::: ;;%;/;5;N;c;m;;;;;;;;;;<<!<'<@<U<_<t<<<<<<<<<< ===2=G=Q=f=q==========> > >2><>Q>\>m>w>}>>>>>>>>>?? ?5?@?Q?[?a?w??????????@@&@7@A@G@]@o@y@@@@@@@@@A AA'A-ACAUA_AtAAAAAAAAAAB BB)B;BEBZBeBvBBBBBBBBBBBC!C+C@CKC\CfClCCCCCCCCCCDD&D1DBDLDRDhDzDDDDDDDDDD EE(E2E8EME_EiE~EEEEEEEEEE FFF1FNFoFFFFFFFFFFFFFFGGG#G)G3G=GGGQG[GeGkGuGGGGGGGGGGGGGGGHHH%H/H5H;HEHOHVHoHyHHHHHHHHHII"I,ICI_NITIcIxIIIIIIIIIIIJJ"J&J7JAJEJXJbJlJvJzJJJJJJJJJJJJJJ KKK#K-K7K;KLKVK\KfKjKvKKKKKKKKKKKKKKKLLL$L*L4L>LBLNLXLbLhLrL|LLLLLLLLLLLLMM(M2M6MIMSM]McMqMuMMMMMMMMMMMMMMMN NNN$N.N8NOHONOYOmOwO}OOOOOOOOOOOPP!P7PAPGPUPkPuPPPPPPPPPPPPQQQ)Q3Q7QIQQQ[Q_QlQvQQQQQQQQQQQQQQQQRRR"R&R2RxBxSx^xbxoxyxxxxxxxxxxxxxyy(y2y6yGyRyVycymysyyyyyyyyyyyyz zz&z*z;zFzJzWzazgzzzzzzzzzzzzzz{{{/{:{>{K{U{[{u{y{{{{{{{{{{{{|||#|.|2|?|I|O|i|m|~||||||||||||}}}"}&}3}=}C}]}a}r}|}}}}}}}}}}}} ~~ ~5~?~P~Z~k~t~~~~~~~~~~~~~ *4CGXbl)/I^h}À؀)>H]hyց1;P[lv|ʂՂق%/DO`jvƃЃփ$/@JVZkuyĄЄ *0J_i~Ņυ +5JUfpvƆ̆ֆ$*4>DNXblwŇڇއ"3=NWfj{ƈވ!.8>VZkuyΉ҉ (.FJ[eizˊՊ04EOSdosɋ͋ދ $(9CGXcgt~Ҍ݌-7;LW[hrxƍэՍ !+/@KO\flŎɎ֎)>HYct}ˏϏ܏ %):EIV`fÐАڐ '1;JN_isǑ֑ڑ &06Peoʒߒ $0EOdoȓݓ #8BWbs}ǔ͔"7BS]c{˕Օە'2CMYnxӖ#-3MblǗܗ!-BLal}Ƙۘ!6@U`q{ؙ͙"3>BOY_syŚ˚՚ߚ#)3=GMWakq{ě؛'->Odhy˜ܜ+5;JN_iswٝߝ 5AEV`jn~ƞӞ%/3DOS`jpǟ˟۟  &>NT`{ ΠҠߠ *.?JN[ekԡߡ0:JTitĢ΢ޢ#)CXbw£̣֣#=FP]jƤϤ٤]%2R\p]t]ǥͥ]٥]ݥ] #3]7DNZdn]r]Ħʦ]ߦ]]]$.]2CN]R_io]]]Ƨ]ק]] $*5;FP]Teoy]]ƨ٨]ݨ] *]:J]Zdnt]]]ɩөݩ]] $](;KU]Yfv|]ʪ]ު]]]#]/]9]C]W][r|]]Ϋث]",6]JTZ]e]y]]]]]Ǭ]]]$]4>H]LXb]fr|]]]ʭۭ]]],6]RX]j]]]î]Ԯ]] ]%/]KQ]c]~]]¯]ׯ]]]#]-]7]B]aΰ_m!2<@MW[gtxʱԱر &0:>OValpȲز (=HYciɳӳݳ.8BWaku˴մ0EOdoǵܵ-BL]gwȶҶֶ  *0:FJV`fp~ƷзԷ ".8<HRVgqwø͸!+AKQakw{ǹѹ׹.8<MX\isyĺκԺߺ'1AKQ_oyֻ̻ܻ(2HRXf|ʼ߼ "3=H]gk|ս߽ 4:DNXblv|žϾӾ ,6JP_cs}ֿ)/DNYdnx____%/_3DO_S`jp_____ _!_1;E_IU__coy_____'17_O_`l_p____ _(_H_Yci_}_______a#-=QaUfryaaaaaaa#6@aDWakao{aaaa a(.aJ]gak|aaaa a(2<aLV`fana}aaaaaa)a4aTa^ahawccc c&0c4EOUcmc~>GQ]iweee e#0:DeHYcvezeee ee&e6KeOmeqee e-7eMSe_es}eeeeeeeee%/9eOY_ep~eeeeeeeeeeeee'4ag ,6Jg_is}gggggg#3g7DN^gboyggg g0g4EUgYfrggggggg'1gBLgalg}gg *4gVggzg~gggg'g+<FPZg^jt~ggggg,<BLVgZfv|ggggg gg g*g>gBYcsgwggg3=gSYgegygggggggg$g4>HgLXbgfr|gggggg,gHRgntggggggg%gAKggmggggggg*4:gQg[gegogzg )->JY]nz !+59QUfpz~!-7AEW]gk}#-7;GW]gq5KU[i #-7IMdh{ 7;LVZgmw !-7A^h|!1AQaq +/EI^o(28EUYjtz"(8<MW^doy}#-7;HR\`~$(:DHZdjt$.HRhnz *@JTjtz ,0AKQbfr| '8ARVgqw (2CM^gx|$/@JPdt *59FPVn,8<MW[lw{ #4>DQaev 5;J_iy &,6@Gh|*48ITXeou$(DHU_ey37HRVcm!26GQUblp} 5?OUez (28Peo/Caku !+1BFR\bsw "&=CTXjtx    # 4 E O U j n z             " ( 8 < M W ] j z ~                 ( 9 = N X ^ k {                ) : > O Y _ l |                # / 5 E I Z d h y              6 K U e k w }              ' 2 6 C M S k                ) - 9 C X c g t ~            2 < B V u           & 0 = J b l           / 9 D J U _ c t                 & 0 6 = M Q b l r }                * 4 8 I S Y d h y                  $ ( 5 ? C T _ c p z              ! % 6 L ` j t                 $ . 4 P d n ~               * . : D H U _ t                 & 0 6 P e o             * 4 I T e o u               ' + < F [ f j w               & , < @ Q [ _ p {                  / 3 D P [ e k u {                 " , 6 K U j u             # - B M ^ h n            ) H h              - 8 B F W a e ~                # ' 4 > D \ ` q {             ) : D J ^ i           ) 3 H R g r                  ' 1 7 O S ` j n             # - F f v                 ) 3 9 Q U f p              # 4 I S W h s w          !  ! $! 9! C! S! Y! e! k! u! {! ! ! ! ! ! ! ! ! ! ! ! ! "  " " " %" +" 6" @" Q" `" d" u" " " " " " " " " " " " " " " #  # # !# +# /# <# F# J# W# d# h# y# # # # # # # # # # # # # $ $ $ $ !$ 2$ 6$ G$ Q$ W$ h$ l$ x$ $ $ $ $ $ $ $ $ $ $ $ $ % % $% (% 4% >% D% U% Y% j% v% % % % % % % % % % % % % & & & && 2& C& G& S& ]& c& t& x& & & & & & & & & & & & & ' ' !' 0' 4' E' Q' b' f' r' |' ' ' ' ' ' ' ' ' ' ' ' '  ( ( (( ,( 8( B( H( Y( n( x( ( ( ( ( ( ( ( ( ( ( ( ( )  ) ) %) )) 6) @) D) Q) ^) b) s) }) ) ) ) ) ) ) ) ) ) ) ) ) )  * * * ,* 0* A* K* Q* e* k* v* * * * * * * * * * * * *  + + + *+ 4+ :+ K+ O+ `+ j+ p+ + + + + + + + + + + + + ,  , , &, ,, @, F, Q, `, d, u, , , , , , , , , , , , , - - - &- *- ;- G- X- \- h- r- x- - - - - - - - - - - - .  . . ". .. 8. >. O. d. n. ~. . . . . . . . . . . . . / / / !/ +/ // 4 R4 \4 m4 s4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 5 "5 &5 75 A5 E5 V5 a5 e5 r5 |5 5 5 5 5 5 5 5 6 6 6 (6 <6 iS6 Y6 i6 t6 z6 6 i6 i6 i6 6 6 6 6 i6 6 i7 7 7 i"7 37 >7 iO7 Y7 _7 iw7 i7 7 i7 7 i7 7 7 i7 i7 i 8 i8 i8 i.8 i28 C8 M8 iQ8 b8 m8 i~8 8 8 i8 8 i8 i8 i8 i8 8 i 9 9 i%9 /9 59 iI9 iR9 i[9 ie9 io9 i9 i9 i9 i9 i9 i9 9 9 : : !: +: 5: F: Q: [: e: o: y: : : : k: : : : : : k; k; k; (; 2; <; C; V; `; kd; u; ; k; ; ; k; ; ; k; k; ; k < < k(< 2< 8< kL< kV< kl< kv< k< k< k< < < k< < < k< < < k= = k= k'= k6= kK= U= kj= u= k= = = k= k= k= k= k= k= k= k> k > k> k-> 1> N> u> > > > > > > > > > > > ? ?  ? '? 1? ;? E? O? Y? c? m? w? ? ? ? m? ? ? ? ? ? m? m@ m@ #@ -@ 7@ >@ mU@ _@ mc@ t@ ~@ m@ @ @ m@ @ @ m@ m@ @ m A A m'A 1A 7A mKA mUA mkA muA mA mA mA A A mA A A mA A A mB B mB m&B m5B mJB TB miB tB mB B B mB mB mB mB mB mB mB mB m C mC m,C 0C MC nC xC ~C C C C C C C C C C C D  D D #D 8D BD ID SD ]D gD qD {D D D D D D  E E  E =E uE E E E E E E E E E E E E E F  F F  F &F 6F KF RF `F fF pF zF F F F F F F F F  G %G /G LG VG gG pG G G G G G G G G G G G H H .H CH MH ^H hH yH H H H H H H H I I ,I 0I DI HI UI aI eI vI I I I I I I I I I I I I J J J J %J /J 9J CJ MJ WJ aJ gJ sJ wJ J J J J J J J J J J J J J  K K $K o:K DK TK _K eK yK oK oK oK K K K K K K oK K L o L L %L o6L @L FL o^L osL }L oL L oL L L oL oL oL oL oM oM oM *M 4M o8M IM TM oeM oM uM oM M oM oM oM oM M oM M o N N N o0N o9N oBN oLN oVN orN o|N oN oN oN oN N N N O O 'O 4O >O IO OO `O wO mO O mO O mO O O O O P P P P *P 0P ?P CP TP ^P dP rP |P P P P P P P P P P P P Q 5Q IQ VQ fQ pQ {Q Q Q Q Q Q Q Q Q Q Q Q Q R R R %R 1R T BT TT ^T dT nT T T T T T T T T T T T T U U U (U BU LU bU hU tU U U U U U U U V  V V  V 6V @V JV `V jV pV V V V V V V V V V V V V V W W W %W @W JW TW jW tW ~W W W W W W W W W W W W W X X X !X 0X 4X EX QX \X fX lX vX |X X X X X X X X X X Y Y -Y 1Y iY Y Y Y Y Y Y Y Y Y Y Y Y Z  Z Z Z -Z 7Z ;Z LZ WZ [Z hZ rZ xZ Z Z Z Z Z Z Z Z Z Z Z Z [  [ $[ 9[ C[ T[ ^[ s[ ~[ [ [ [ [ [ [ \ \ \ ,\ 6\ @\ K\ g\ \ q\ \ \ \ \ \ \ \ \ \ q\ ]  ] ] q] &] 0] :] qN] X] q\] m] x] q|] ] ] ] q] q] ] q] ] q^  ^ ^ q$^ q*^ q0^ q<^ qP^ Z^ `^ qn^ q~^ ^ ^ q^ ^ q^ q^ q^ q^ q^ ^ ^ _ _ 2_ V_ |_ _ s_ _ _ _ _ s_ `  ` ` !` s%` 1` ;` E` O` sS` _` i` s` s` ` s` ` ` s` ` ` ` s` s` a sa (a s9a Ca Ia s]a sca sia sva sza a a a sa a sa a a sa a a a sb s*b 4b sIb Tb seb ob ub sb sb sb sb sb b b b sb b b c sc c 'c -c s;c Ec sVc `c jc pc s~c c sc c c sc c c c sc sc c d sd s#d -d 3d sId sMd ^d hd rd svd d d d sd sd d d d sd sd d d d se s e e 'e s+e ;e Ee sIe Ze ee sie ve e e se se e e se e se e e e sf sf %f /f sDf Of sSf `f jf pf sf sf f f f f f f f f sf f f g  g g g s?g sPg cg sgg ~g g sg g g g sg g sg g g g sh sh %h /h 9h Ch sGh Sh ]h gh qh suh h h h sh h sh h h sh h h h s i s i *i s?i Ji s[i ei ki si si si si si i i i si i i i sj j j %j /j 5j sGj sKj bj rj |j sj j j j sj j j j j j sj sj k k %k s)k =k Gk sKk ]k gk skk wk k sk k k sk k k sk k k k sk sl l sl (l 2l sGl Rl sVl cl ml sl sl sl l l sl l sl l l l sm s)m /m s=m sYm cm sm m sm sm m m m sm m s n n s"n sIn san son sn n sn n n sn sn n sn n sn so so so s%o s/o s:o sDo sNo smo o o o o o o o o o p  p p p #p /p 9p Cp Mp Qp ]p gp qp p p p p p p p p q  q &q *q 7q Aq Gq [q aq gq pq {q q q q q q q q  r r !r +r 5r 9r Jr Tr ^r hr lr xr r r r r r r r r r r r  s s s 1s Os Ss os ss s s s s s s s s s s s  t "t )t 3t =t Mt Qt tet tt tt t t tt t t tt t t tt u u t!u 4u ?u tCu Ru ]u tau ou yu tu tu tu tu tu tu tu tu tu tu tu tu tu tu tu t v tv tv t'v t1v t7v tAv tKv tUv t_v tiv tov tyv tv tv tv tv tv v v v v jv ev fw g w hw l%w n1w '=w oIw pUw qaw  mw ryw sw uw tw kw w w w w  x x ,x z=x zNx z_x rx x x \x mx x x x  x y y 'y 8y Iy Zy ky |y y y y y y y y az 6z Gz jz vz z _z z z z z  { { ${ .{ 8{ B{ L{ V{ \{ f{ l{ v{ { { .{ { { { { { { { { { | &| ,| @| D| \| || | | | | | } '} A} Q} a} e} x} } } } } } } } ~ !~ 7~ K~ d~ z~ ~ ~ ~ ~ ~ ~   , I O ^ z      ; V l    ܀    0 O y   ́   % K g     ق   - 1 J \ |    Ӄ    ? I f {   ܄   A [ v     #,09=HL]apt| %)48IMUYhluy   /3BFUYhclcscwc %)15<@IM\`tx")-6:IMaemq '+:>GKRVrv !26>BQU]apt} #'CGSWhltx  )-9=NRY]dhos}     " & 5 9 @ D K O X \ c g p t {                        * . 7 ; O S d h y }      h h h h h h h h h h h h h h h h. h2 h; h? hF hJ h[ h_ hf hj hy j} j j j j j j j j j j j j j j j j j j j j j' j+ j4 j8 jA jE jN jR jc jg jo js j j j j j j j j j j j j j l l l l* l. l7 l; lO lS lb lf lu ly l l l l l l l l l l l l l l l l l l l llll l$l4l8l?lClRlVltlxlllnnnnnnnnnnnnnnnnnn#n'n/n3nCnGnNnRnanennnnnnn"&.2;?HLUYbfw{  !%,0AEL_QU\_imuy )-59AEUY`_eip_uy_ (,=APT]arv}__ !%,09=FJQUfjrv~  #'8<CGSWcgsw &*15=AIMUYaeuy#'6:AERV]avz$(/3BFMQ`dx|ttttt tttt"t3t7t>tBtItMt\t`titmtttxttttttttttttttttttt&t*t3t7tNvRv[v_vhvlv}vvvvvvvvvvvvvvvv!%-19=MQY]eiy}  04=AJNbfos| !04;?NRcgvz#'/3>BUYbfrv !%.2CGVZaelpx|  ! % , 0 9 = D H W [ b _o s z ~               !!!#!'!6!:!N!R![!_!h!l!u!y!!!!!!!!!!!!!!!!!""""" "1"5"D"H"Q"U"\"`"q"u""""""""""""""""""" ####"#&#-#1#B#F#O#S#\#`#i#m#~##################$$$$,$0$9$=$N$R$Z$^$n$r$y$}$$$$$$$$$$$$$$$$$$%%%%!%*%.%5%9%J%N%W%[%d%h%q%u%%%%%%%%%%%%%%%%%&&&&!&%&4&8&A&E&V&Z&b&f&v&z&&&&&&&&&&&&&&&&&''''''''+':'>'E'I'R'V']'a'r'v''''''''''''''''''(( ((((#(4(8(@(D(T(X(_(c(r(v(~(((((((((((((((((( ))))-)1)9)=)L)P)\)`)q)u)})))))))))))))))))))* ***"*+*/*;*?*P*T*[*_*g*k*{****************** ++++"+&+7+;+B+F+N+R+c+g+p+t++++++++++++++++,, ,,,,-,1,8,<,D,H,Y,],d,q,u,,,,,,,,,,,,,,,,- ---$-(-<-@-H-L-[-_-h-l-}------------------...#.'...2.:.>.N.R.Y.].d.h.p.t................... / //"/+///8/6E6I6R6V6b6f6u6y6666t666666666666 7777#7'787<7K7O7X7\7c7g7x7|77777777777777777 8888#8'888<8K8O8X8\8c8g8x8|8888888888888888h888h 9999#9'989<9C9jH9L9S9j`9d9m9q9x9|999999l999l999999999m9: :m::$:(:/:3:<:@:Q:U:\:'a:e:l:'y:}::::::::::t:::t:::::; ;;;#;*;.;=;A;J;N;_;c;l;p;;;;;;;;;;;;;;;;;<<<<#<'<0<4<E<I<P<T<c<g<p<t<<<<<<<<<<<<<<<<< = ==='=+=4=8=?=C=T=X=g=k=t=x==================>>>'>+>4>8>?>C>T>X>g>k>t>x>>>>>>>>>>>>>>>?? ???$?1?5?D?H?W?[?h?l?u?y?????????????????@ @@@%@)@0@4@C@G@N@R@a@e@l@p@w@{@@@@@@_@@@_@@@@@@@@@@AAAA"A&A.A2ABAFAMAQAZA^AoAsA{AAAAAAAAAAAAAAAAAAB BBB'B+B3B7BGBKB[B_BfBjBzB~BBBBBBBBBBBBBBBBBCCCC&C*C:C>CJCNCWC[CoCsCCCCCCCCCCCCCCCCD DDD#D*D.D=DADHDLD[D_DfDjDqDuDDDDDDDDDDDDDDDDEEE%E)E9E=EFEJESEWE`EdEoEsE|EEEEEEEEEEEEEEEEEEFFFFFF,F0F7F;FBFFFUFYF`FdFlFpFFFFFFFFFFFFFFFFFFF GGG#G2G6GKGOGXG\GcGgGxG|GGGGGGGGGGGGGGGG_GG HHHH"H&H.H2HAHEHLHPH`HdHsHwHHHHHHHHHHHHHHHHHHH IIII-I1I8IXBXRXVXeXiXzX~XXXXXXXXXXXXXXXXXYYYYYY(Y,Y>YBYSYWYiYmYtYxYYYYYYYYYYYYYYYYYYYZZZZZZ/Z3Z:Z>ZNZRZaZeZlZpZZZZZZZZZZZZZZZZZZZZZ[ [[['[+[3[7[?[C[K[O[W[[[c[g[w[{[[[[[[[[[[[[[[[[[[[\\\!\+\/\9\=\O\S\Z\^\j\n\{\\\\\\\\\\\\\\\\]]]] ]$]-]1]:]>]E]I]P]T]]]a]h]l]}]]]]]]]]]]]]]]]]]]]]^^ ^^^^-^1^@^D^K^O^X^\^e^i^x^|^^^^^^^^^^^^^^^^^^^__#_'_0_4_;_?_P_T_c_g_p_t_{_____________________` ` ```!`%`,`0`9`=`L`P`W`[`d`h`q`u`|````````````````````a aaa(a,a3a7a@aDaMaQaXa\aeaiaza~aaaaaaaaaaaaaaaaaaabbb!b*b.b7b;bLbPbWb[bgbkbwb{bbbbbbbbbbbbbbbcc cc!c%c4c8c?cCcLcPc_ccclcpcwc{ccccccccccccccccccccdddd d)d-d6d:dKdOdVdZdbdfdndrdddddddddddddddddde eeee-e1e8etNtRtYt]tmtqtttttttttttttttttttuuuu!u%u4u8u?uCuSuWuousuuuuuuuuuuuuuuuuuuuvvvv&v*v1v5vMvQvXv_evivxv|vv_vvvvvvvvvvvvvvvvwwww'w+w2w6w>wBwIwMw]wawjwnwzw~wwwwwwwwwwwwwwwwwxx xxx#x3x7xFxJxZx^xmxqxxxx_xxx_xxxxxxxxx_xxx_xyy yyy%y)y0y4yCyGyNyRyayeyly_qyuy|y_yyyyyyyyyyyyyyyy zzz!z1z5zDzHzXz\zczgznzrzzzzzzzzzzzzzzzzzz{{{{"{2{6{={A{P{T{d{h{w{{{{{{{{{{{{{{{{{||||||/|3|:|>|M|Q|X|\|l|p|w|{||||||||||||||||||||} }}}}+}/}6}:}B}F}N}R}Z}^}g}k}{}}}}}}}}}}}}}}}}}} ~~~#~*~.~7~;~L~P~X~\~l~p~~~~~~~~~~~~~~  $-1:>GKRVgkuy(,=AIM]akovzĀ̀рހ/3<@IMVZko~āԁ؁ %)26GKUYko‚Ƃςӂ!%/3EISWaew{ǃ˃݃%)37IMW[bfos|ĄȄل݄"+/8<EIZ^fjz~υӅ݅ !6:LPkovzӆ׆ !%6:CGPTeirvÇLJчՇ߇'+26EISWimw{ÈՈو #,0AEOSZ^gktxƉʉщՉމ #'7;EIPT]ajnՊي 15FJQUdhy}ċȋыՋ܋#'8<CGPT[_hl}Ōόӌ+/FJRVfjy}ōɍӍ׍ )-7;EI[_imw{ώӎݎ%);?IM_cmqx|ď͏яڏޏ  ",07;DHQU^bswÐǐАԐ"&;?QUhluyʑΑߑ #*.7;BFOS\`gk|ŒΒҒ '+59KOY]gk}̓Г$(26HLVZdhz~ϔӔ (,6:LPZ^pt˕ϕٕݕ !%/3=ASWaeosǖ˖Ֆٖ!37AEW[bfnrė˗ϗ  !(,;?HLUY`duyǘ˘ܘ &*37@DUYbfos|ϙәܙ&*26FJY]eiy}Śٚݚ $(04<@GK[_gkswǛ˛қ֛ݛ  !%59AEMQaelpx|ĜȜϜӜ'+26AEPT[_koÝʝם۝___%)26EIP_UY`_mqy}ΞҞ !%,0?CTXim|ǟԟ؟(,<@GTXhls Ơՠ٠*.6:BFNRZ^eiy}Ρҡܡ '+59KOY]os}ʢ΢آܢ (,>BLPZ^pt~£ԣأߣ$(:>HL^blpäӤפ $(/3:>GKZ^gk|ť֥ڥ*.>BIMaenry}Ȧ̦զ٦ #'.2BFZ^gktxҧ֧ݧ!(,=APT]ajnw{ƨʨҨ֨ݨ  #'04EIRV_clpé̩Щש۩ #'15<@JNUYcgnr|Ǫ˪Ҫ֪!*.@DKOVZdhos}«_ϫӫ_ _%)8<C_PTcgn_{_Ĭ_Ѭլ__'+:>E_RVeipt~­ƭ׭ۭ$(9=DHW[lpʮήݮ #26GKTX_ctxįȯگޯ -18_EIPTfjquðʰΰ!15=ANRgksw_ɱͱܱ_ &*9=DHX\lpw{IJȲزܲ _%)9=EIPTdhpt{ͳѳس_+/9=DHQU^bswȴ̴մٴ!*.7;LPX\lpw{õ̵еڵ޵.2;?HLUYjnuyǶ˶ܶ -1;?QU\`osz_ŷ̷з'+59CGY]gkuy˸ϸٸݸ 15?CUYcgy}Ź̹й׹۹'+37?CKOW[kow{̺к׺ۺ_!%,0@DK_X\kovzĻԻػ߻ !%48?_LPW[kow{żͼѼؼܼ _*.59IM]akovz½˽Ͻؽܽ  *.59BFOS\`im~̾оھ޾ &*;?IMVZgkx|Ŀȿڿ޿04;?GKSW^bsw .2;?HLVZcgy} -1:>SWhl}_ $6:DHZ^eipt  #-1;?QU_cmq )-7;MQ[_qu %)04;?FJQU\`gkrv} "&:>FJZ^gkrv} ,07;JN_ctx  "15>BIM^bqu~$(9=DHPT\`imvz  '+37?CJNUYaelp .29=LPY]fjsw"+/@DKO^bjn~ "37FJ[_hlsw".2>BQU\_ael_y}__ "&59JNW[bfw{ $(/3CGNRZ^eiqu|_ _"15<_IM\`g_tx___ _ $37>_KO^bi_vz.2:>NR[_hlsw %)8<LPY]dhy}____ _ $+/7;BFMQX\cgw{____ _*.5_:>E_RV]ahl|#'.2:>EIQU\`hlsw #'/3:>EIPT\`gkrv}____*.=AH_UYhls_____,0?CPTaerv%)9=EIY]fjsw~ (,<@OScgpt{__ __#*_7;BFNRY]dhosz~____!_.2AEL_QU\_imtx'+:>EIQU]aimuy#'.29=MQX_eix|.2AELPW[bfvz #26FJQUjn~ $(15>BSW^bimtx"&.2BFW[dhos %)59HLSW`dmqx| "*.>BRV_clp&*;?NR[_pt '+26>BIMbfuy$(/3:>MQZ^gktx '+<@GKZ^eiqu 04;?HLUYhlsw &*26>BJN^brv .2;?FJ[_nr{____#'._;?HLUYbfos -18<LPW_\`g_lpw_|____ _!(_-18_EIRV_clpy}___ _"_/3<@IMVZcgx|_ $.2<@RV_clpy}!26@DNR\`jn #'6:DHRV`dvz *.8<NR[_hluy ",0:>PT]ajn"26HL]arv#-1;?QU^bkox|'+;?OSZ__cj_w{__ #48FJQUeirv  ")-6:CGX\lpy}#'.2:>NR[_hl}___ "&59@_EIP_UY`_mqz~ "15>BSW^bko  )-48IM\`qu !%7;JN_clpw{"&59JNU_bfrv"37>BIMTXgk{"&7;DHOSdhw{ )->BRV]aimuy _!(_-18_EIPT]ajnuy   '+BF]ax| $(15<@IMTXimtx    & * 2 6 > B R V _ c j n                        $ + / ; ? N R [ _ p t {                    - 1 @ D L P ` d p t                      # 2 6 ? C J N _ c r v }                          & * < @ G K Z ^ g k t x                  #48?CRV_clp ,07;JNW[dhy} '+26EISWaew{%)04CGQU_cuy#'.2AENR\`qu~  '+:>GKTXimvz#26GKUY`dvz$(7;LPZ^ei{ )-<@RV`dko15DHZ^hlsw  #26GKUY`dvz$(7;DHOS\`imvz #,07;DHQUfjqu~ &*37AENR[_pt}  )-6:CGPTeipt '+:>EIRV_cjn /3<@QU^bsw~"&7;BFUYjn   $ ( 9 = F J Q U f j y }                !! !$!-!1!8!/B/I/_V/Z/i/m/|///o///o///o///o/////o///o00 0o00-01080_E0I0P0T0d0h0y0}0000000000_000000000_1 1111 1/131:1_G1K1R1V1^1b1j1n1~11111111111o111o111o111_2 22_2"21252<2_I2M2\2`2g2k2s2w2222222222222222o33 3o33#3_0343;3_H3L3[3_3f3_s3w33333333333333333444444'4+4:4>4P4T4[4o`4d4k4ox4|44o444444444o444o444o55 5o555o)5-5>5B5Q5U5f5j5y5}5555555555_555_555_55 66%6)686<6K6O6V6Z6c6g6v6z6666666666666666666 7777*7.7B7F7d7h7w7{7777777777788 88"8&8/838D8H8Y8]8l8p88888888888889999"9_/939?9C9O9S9_9c9o9s99999999999999999999:::':+:2:_7:;:B:_O:S:Z:^:m:q::::::::::::o::::; ;;;; ;(;,;;;?;H;L;X;\;m;q;;;;;;;;;;;;;;;;;<o <<<o<<%<o2<6<=<oJ<N<Z<^<j<n<z<~<<<<<<<<<<<<<<<<< = ===)=-=9===Q=U=^=b=k=o=x=|================= >> >$>+>/>>>B>I>M>\>`>g>ol>p>w>o|>>>o>>>o>>>>>>>>>>>?? ???(?,?=?A?J?N?W?[?l?p?w?{????????????????? @@@@!@%@-@1@@@D@K@O@V@Z@a@e@t@x@@_@@@@@@@@@@@@@@A AAA&A*A6A:ANARAYA]AdAhAwA{AA_AAAAAAAAAAAAAAAABBBBBB$B(B7B;BBB_OBSB\B`BlBpBBBBBBBBBBBBoBBBoBBBoBBCoCCC!C2C6C?CCCTCXC_CcCrCvCCCCCCCCCCCCCCCCCDDDD!D%D,D0DADEDTDXD_DcDjDnDuDyDDDDDDDDDDDDDDDDDDDDDEEEoE"E)Eo6E:EAE_NEREZE^EfEjErEvE~EEEEEEEEEEEEEEEEEEEEFF FFFF-F1FBFFFOFSFZF^FoFsFFFFFFFFFFFFFFFFFFFFFGGGG*G.G5Go:G>GEGoJGNGUGobGfGmGozG~GGGGGGGGoGGGoGGGoGGGGH_HH!H%H6H:HCHGHPHTH]HaHrHvHHHHHHHHHHHHHHHHHHHII!I%I-I1I9I=IEIIIQIUIeIiIuIyIIIIIIIIIIIIIIIIIIJ J JJJ#J'J0J4J=JAJRJVJ]JaJpJtJ{JJJJJJJJJJJJJJJJJJJJJK KKKK"K&K/K3KDKHKOKSK[K_KgKkKsKwKKKKKKKKKKKKKKKKKKKLLLL L$L0L4LCLGLPLTLeLiLpLtLLLLLLLLLLLLLLLLLM MMM%M)M8Mf_KfOfVf_cfgfnfsfwf~ffffffffffffffffffffgg ggg"g)g_.g2g9g_FgJgQg_^gbgvgzggggggggggggggggghhhh#h'h0h4h=hAhJhNh_hchlhphhhhhhhhhhhhhhhhhhh i iii'i+i?iCiaieitixiiiiiiiiiiiii jjjj#j'j6j:jAjEjNjRjYj]jnjrj{jjjjjjjjjjjjjjjjjjk kk k)k-k>kBkIkMk\k`kikmk~kkkkkkkkkkkkkk ll-l1l@lDlLlPl`ldlklolvlzllll_llllllllllllllll mmmm%m)m1m5m=mAmQmUmamemqmummmmmmmmmmmmmmmmmmmnnnn n$n+n/n6n:nAnEnLnPn_ncnjn_onsnzn_nnn_nnnnnnnnnnnnnnnnnno ooo(o,o=oAoJoNoUoYojono}oooooooooooooooooooo pppopp&po3p7p>poKpOpXp\pepipzp~ppopppopppoppppp_ppppq qqq!q%q.q2q;q?qPqTq]qaqjqnqwq{qqqqqqqqqqqqqqqqq rrrr&r*r3r7rHrLrUrYrbrfrorsrrrrrrrrrrrrrrrrrssssss's+s4s8sAsEsNsRs[s_shsls}ssssssssssssssssssst ttt!t5t9t@tDtLtPtXt\tetitrtvtttttttttttttttttttttu uu_uu u_%u)u0u_=uAuHu_MuQuXu_]uauhu_muquxu_uuuuuuuuuuuuuuuuuuuuvvvv#v'v8vwBwIwoVwZwcwgwpwtwwwwowwwowwwowwwww_wwwxxxx#x,x0x9x=xFxJx[x_xhxlxuxyxxxxxxxxxxxxxxxxxxyyy'y+y4y8yIyMyVyZykyoyvyzyyyyyyyyyyyyyyyyyzz zzz#z4z8zAzEzLzPzazeztzxzzzzzzzzzzzzzzzzzzz{ {{{){-{9{={I{M{Y{]{i{m{{{{{{{{{{{{{{{{{{{{{{| ||!|%|,|0|7|;|J|N|U|Y|a|e|m|q|z|~||||||||||||||||||} }}}}*}.}=}A}H}L}T}X}`}d}m}q}z}~}}}}}}}}}}}}}}}}}}}~~ ~~ ~$~-~1~=~A~M~Q~]~a~u~y~~~~~~~~~~~~~~~~~~~~~ $+/6:AELPW[bfuy_____ '+48AEVZa_fjq_vz____€ɀ̀րڀ  $-1:>GKTXaevzˁρցځ #*.59@DKO^bqu|ooooł΂҂ۂ߂o oo(,=AH_UYhl}ƃʃӃ׃*.=ARV_cjnńքڄ04=AJNW[lpw{̅Ѕ߅ !%48?_DHO_TX__lpx|_†_džˆ҆_׆ۆ_  $48@DTXaevzÇLJ؇܇%):>EIX\mqz~ˆƈψӈڈވ$(/3DHW[cgosˉω։ډ__ $-1:>MQ]apt{ĊˊЊԊۊ  $37CGPTcgx|__Ћԋۋ (,59BFW[jnz~_njˌ܌ $(9=MQ]ajn}_ōɍЍ_Սٍ_  ,09=LPW\`gtxΎҎގ $59IMTXbfmqŏɏяՏ $04HLUYbfos|ŐΐҐېߐ *.5_:>E_RV]ajnw{Ǒˑґ֑ߑ$(7;GKTXgkrvĒȒϒӒ &_37CGVZcgpt}Ó̓Гٓݓ *.59EIUYhl}Ȕ̔Քٔ$(/3?CRV_ctxǕ˕ԕؕߕ #48GKSW_csw~ĖȖٖݖ "&7;BFUYbfmq99999999Ɨ9ʗ9ܗ99o999 9_9#92969=_B9F9M_Z9^9g9k9t9x999_9999_Θ9Ҙ99999(,;?KO^binryə͙ܙ !%,_15<_AEL_Y]imvzoooŚњ՚ޚo oo)-9=FJY]dimty}͛ћ%)0_59@_EIP_]amqz~oooŜɜ՜ٜo o o-1=AJN]ahomqxo}oŝɝНo՝ٝoo -18_=AH_MQX_eiuyў՞ܞ  #'8<CGVZcgptßҟ֟ߟ  !%6:IM^bkovzàˠϠߠ,0<@OSZ^gk|¡ʡΡ֡ڡ __"&-_26=_JNUYaemqz~Ȣ̢ݢ___ _!(_59@DMQZ^gktxǣˣң֣ݣ #26=_BFM_RV]_bfm_z~ĤȤѤդޤ __ $+_04;_HLSW`dmqx|ʥΥե٥ '+26>BJNVZbfvzȦ̦զ٦#26?CTX_ctxŧ֧ڧ#'8<CGVZcgx|Ũɨڨި /3<@GK\`osĩȩ٩ݩ .2;?FJ[_nrêǪتܪ #'/3;?GKSW_ckovzūɫѫիݫ_ _!(_-18_EIPT\`hluyìǬجܬ___ _#_04;?HLUYbfosz~­ƭͭѭحܭ -18_=AH_MQX_]ah_uyî̮Юٮݮ_ _&_+/6_CGNR[_hlswůɯЯԯݯ"&-19=EIQU]aqu|ðǰа԰ݰ -1:>OSZ^osz~ѱձܱ"37>BQU^bswIJղٲ*.7;BFW[jnóԳس)-6:AEVZim~´Ӵ״"+/6:KOVZimuyµƵ׵۵$(/3DHW[lpɶͶܶ  "15>BIM^bqu|ķ˷Ϸַڷ #37>BQU]aimuyɸ͸޸ .2:>OSZ^mqz~Ϲӹڹ޹ !%6:CGPT]ajnĺԺغ "&/3DHOSbfw{ɻͻܻ &*15FJY]lpx|ȼ̼Ӽ_ؼܼ___'+37@DMQZ^gktx__ýǽν_ӽ׽޽__  $-1:>EIRV]ajnuyžɾоԾ_ _#_(,3_@DKOW[cgpt}ƿʿѿ_ֿڿ___&*37>BKOX\eipt} (,<@GKTXaelpy} %):>EIX\eiz~   )->BKO`dko~ "&59JNW[bfw{ !%48IMVZaevz #*.>BIMX\dhsw !%04DHO_\`pt_ ,07_DHX\qu|__ /3;?OSbfvz_"&37FJQ_^brv (,37HL[_os /3DHO_TX__lp|__ #'6:A_FJQ_^bko~$(/3BFNRZ^nry_~__ '+26GKZ^os|  '+7;GKRVbfmq}  )-59BFRV^bnr)-<@IMY]imvz!%-1AELPX\dhpt|  $59@DPT`dko{  $,0@DMQZ^gktx '+:>OS\`gk| *.5_:>E_JNU_bfos|"+/8<EIZ^mq____   'o,07oDHQUfjq_~*.59HLS_`duy__(,3o8<CoHLSo`dmqz~__ !-1:>MQX_]ah_uy__%)59BFUYbfw{'+<@OSZo_cjow{___'+<@OSgk|_  _!%.2CGN_[_pt o"o/3<@QU\_im~*.?CRVgk| "&/3DHOSbfos}"15FJ\`jnuy'+:>E_JNU_Z^e_rv}#+/?CJN]aimuy  $59BFMQbfuyooo __#*_7;DHQUfjvz  ,09=LPW_\`g_lpw_  "37HL[_hl}___ -18<CGVZbfnr ,07;JNW[bfw{oo_ _#,0AEQUdhotx__#'.2AEVZko~ #'/3;?FJZ^eojnuo#+/7;KOVZbfnrz~"&-18<CGVZaelpw{ooo #*/3:?CJW[cgos{___ $)-49=DQU]aimuy___#'.37>KOW[cgos|___ !(-18=AHUYaemqy}___"'+27;BOS[_gksw___!%,15<IMUYaemqz~___ #'/3<@PT\`pt} /3DHOoTX_olpw{ !(,37?CLPW[cgnr__#*7;BFMQY]fjqu}__ )-49=DQU\`gksw__ $(/3CGNRY]eirv} (,37HL[_ptooo "&.29=EIZ^ejnuz~ _!(_-18_EIPT[_fjqu}$(04=AHLTX_csw~___ &*16:AFJQ^bimtx___ '+26=AIMVZaemqx| '+<@GKZ^os| #'.2AENR[_pt{ $-1BFOS\`qu|$(/3:>EIPTcgn_sw~_ (,<@OS`dmq    ) - 5 9 A E M Q Y ] m q ~                       ) - 6 : K O W [ j n                     % ) 2 6 ? C T X a e n r {                    # ' 8 < C G V Z j n w {                     # ' . 2 C G N R ^ b q u |           _   _   _   _  _!)-59BFNR[_gk|  *.7;JNVZbfnr{#'6:AFJQVZanry}(,=ARV_cjn (,<@HLUYaenr  !%59@DKO^bkox| &*;?FJY]nr{"+/@DKOX\eipt{ #'04;?NR[_hluy!*.?CKO_ctx!26=APTeiz~ %)059@EIPUY`mqy} 04;?NRbfm_z~__$(/_<@IMVZcgpt !%6:IMY]fjy}_ _+/;?HL[_pt$(15<@IMTXaelp (,=AHLUYbfmqx|    $ ( 1 5 > B S W ^ b q u                 !!!!"!&!7!;!D!H!Q!U!f!j!s!w!!!!!!!!!!!!!!!!!"""" "$"5"9"I"M"^"b"s"w"""""""""""""""""""# ###%#)#2#6#?#C#T#X#a#e#n#r#################$$$$#$'$6$:$A$E$N$R$[$_$n$r${$$$$$$$$$$$$$$$$$$%%%%$%(%7%;%L%P%Y%]%d%h%y%}%%%%%%%%%%%%%%%%%&&&&&"&3&7&>&B&Q&U&^&b&k&o&&&&&&&&&&&&&&&&&&&''"'&'/'3':'>'O'S'b'f'z'~''''''''''''''' ((((+(/(6(:(A(E(T(X(d(h(o(s((((((((((((((((((() )))')+)4)8)I)M)V)Z)k)o)v)z))))))))))))))))) * **"*2*6*G*K*R*V*e*i****_***_**************+_ + ++_++$+_1+5+<+@+J+N+X+\+f+j+t+x+++++++++++++++++ ,,,_,,&,_+,/,6,_C,G,N,R,Y,],l,p,w,_|,,,_,,,_,,,,,,,,,,,,,, ---"-1-5->-B-L-P-Z-^-h-l-~-----_---_---_---------- ..._..&._+./.6._C.G.P.T.^.b.l.p.z.~................./ //!/3/7/>/C/G/N/S/W/^/k/o/v/z//////////////////0 0 000+0/080<0K0O0X0\0f0j0t0x00000000_000_000_0000111_111_$1(1/1_<1@1I1M1W1[1e1i1s1w111111111111111112222,20272_<2@2G2_L2P2W2_d2h2o2s2|22222_222_222_2222222223 3333#3'393=3I3M3\3`3g3k3u3y3333333333_333_333_3344 4444!4%44484?4_D4H4O4_T4X4_4_l4p4w4{44444444444444444445 555*5.5?5C5J5O5S5Z5_5c5j5w5{555555555555555555556 6666&6*63676@6D6M6Q6Z6^6o6s6|66666666666666666_667_ 777_#7'7.727A7E7L7_Q7U7\7_a7e7l7_y7}77777777777777777778 888 8$85898J8N8U8_Z8^8e8_j8n8u8_8888888888888_888_888_8899999"9+9/989<9K9O9X9\9k9o9v9z9999999999999999999: ::::(:,:3:7:@:D:M:Q:Z:^:g:k:z:~:::::::::::::::::::; ;;;";&;7;;;L;P;W;_\;`;g;_l;p;w;_;;;;;;;_;;;_;;;_;;;;;;;< <<<<,<0<<<@<O<S<Z<^<g<k<t<x<<<<<<<<_<<<_<<<_<<<<<<===="=_'=+=2=_7=;=B=_O=S=Z=^=g=k=t=x===================> >> >'>,>0>7>D>H>O>S>b>f>m>q>z>~>>>>>>>>>>>>>>>>>?? ????/?3?D?H?Q?U?f?j?q?u?~?????????????????@@ @@@%@)@0@=@A@H@M@Q@X@]@a@h@u@y@@@@@@@@@@@@@@@@@@@@@A AAA!A5A9AEAIA]AaAhAmAqAxA}AAAAAAAAAAAAAAAAAAAAAA BBBB&B*B1B5B>BBBKBOBXB\BcBgBpBtB~BBBBBBBBBBBBBBBBBBBC CCCC#C'C0C4C=CACJCNCWC[CdChCrCvCCCCCCCCCCCCCCCCCCCCD DDDD$D(D1D5DIQIUIdIhIIIIIIIIIIIIIIIIIII JJJJ$J(J0J4JRBRIR_NRRRYR_^RbRiR_vRzRRRRRRRRRRRRRRRRRRRRSSS"S&S-S1S;S?SISMSWS[SeSiSsSwSSSSSS_SSS_SSS_SSS_SSS_SSTT TT T$T+T_0T4T;T_@TDTKT_PTTT[T_`TdTkT_xT|TTTTTTTTTTTTTTTTTTTUUUU$U(U/U3U=UAUKUOUYU]UgUkUuUyUUUUUU_UUU_UUU_UUU_UUU_UUVVVV"V&V-V_2V6V=V_BVFVMV_RVVV]V_bVfVmV_zV~VVVVVVVVVVVVVVVVVVVW WWW#W'W1W5W?WCWMWQWcWgWyW}WW_WWW_WWW_WWWWWWWWW_WWW_WWX_XXX!X+X/X9X=XGXKXRXVX]XaXiXmXXXXXXXXXXXXXXXXXYYYY$Y(Y/Y3Y=YAYKYOYaYeYnYrY{YYYYYYYYYYYYYYYYYYZ ZZ!Z+Z/Z9Z=ZGZKZ]ZaZhZlZ{ZZZZZZZZZZZZZZZZZZ [ [[[%[)[3[7[I[M[W[[[e[i[s[w[[[[[[[[[[[[[[[[[\\\\'\+\5\9\K\O\Y\]\g\k\}\\\\\\\\\\\\\\\\\] ]]!]%]/]3]=]A]S]W]a]e]o]s]]]]]]]]]]]]]]]]]^^^!^3^7^A^E^W^[^m^q^{^^^^^^^^^^^^^^^^ ____#_'_9_=_L_P_W__\_`_g__l_p_w__|________________________``````'`+`2`6`?`C`J`N`_`c`j`_o`s`z`_```_```_``````````````aa aa a$a0a4aCaGaNaRa[a_ahalauayaaaaaaaaaaaa_aaa_aaa_aab_b bb_b"b)b-b6b:bKbObVb_[b_bfb_kbobvb_{bbb_bbb_bbbbbbbbbbbbbbbbccc#c2c6c=cAcJcNcWc[cdchcqcuc~ccccccc_ccc_ccc_ccc_ccccd dd!d(d_-d1d8d_=dAdHd_MdQdXd_edidpdtd}ddddddddddddddddddde eeee&e*e;e?ePeTe[e_`edeke_pete{e_eeeeeeeeeee_eee_eee_eef ffff#f*f.f5f9fHfLfXf\fkfofvfzfffffffffffffffffffg ggg g$g-g1gBgFgNgRgbgfgmgqgxg|gggggggggggggggggh hhh'h+h2h6hEhIhRhVh_hchthxhhhhhhhhhhhhhhhhhiiii+i/i8ilBlQlUlaleltlxllllllllllllll_lll_lll_m mmmm#m3m7m>m_CmGmNm_SmWm^m_kmomvmzmmmmmmmmmmmmmmmmmmmn nnn'n+nzMzQzXz\zhzlzszwzzzzzzzzzzzzzzzzz{ {{{'{+{2{6{={A{R{V{]{a{p{t{{{{{{_{{{_{{{_{{{{{{{{|_| ||_||"|_/|3|:|>|G|K|T|X|_|c|k|o|x||||||||||||||||||| }}}_} }'}_,}0}7}_D}H}Y}]}d}_i}m}t}_y}}}}_}}}}}}}}}}}}}}}}}~~~~~'~+~4~8~I~M~T~_Y~]~d~_i~m~t~_~~~~~_~~~_~~~_~~~~~~~~ ,09=LPW[dhqu___ %_*.5_:>E_RV]ajnw{ЀԀۀ߀ #*_/3:_?CJ_W[bfmq___Áǁ΁ҁف݁ %)8<MQZ^os|ςӂڂނ  $-18<MQY]eirṽЃ؃܃ !*.7;KOVZlpx|Ȅ̄Ԅ؄ $(04DHO_TX__dho_tx__ŅɅЅ_Յم__ "&/3<@GKSWhlx|҆ֆ݆___ _/3:_?CJ_OSZ__cj_w{ćՇه /3DHO_TX__dho_|___Ɉ͈Ԉ؈ '+:>EIRV_ctx___ʼn̉Љى݉_ _&_37>BKOX\cgos|Ɋ͊֊ڊ __ $+_8<CGNRael_qu|__Ƌʋۋߋ .2;?PT]arv~ΌҌٌ݌.29>BIVZafjq~ɍ֍ڍ!(-18EIP]aim}Ȏ̎ӎ׎  $(15?CTXbfmqz~Ǐˏԏ؏ %)26@DMQZ^osz~ǐːԐؐ -1;?FJTXbfpt{ёՑ #-18<EISWaelpy}Ò̒Вْݒ%)37@DQU_cmqz~ÓǓѓՓ $15GK]akoy}ĔȔҔ֔ .2FJeiqu}̕Е&*26>BJN^bimw{Ӗזߖ%)04;?HLUYbfos}ėΗҗٗݗ !%.2;?IMVZdhquǘ˘Ԙؘ  $(26?CMQX\mq{™̙Йיۙ  "&8<NRZ^fjrv~ƚʚԚؚ &*<@JNW[hlvzÛ͛ћޛ &*48BFPTfjquœƜ͜ќ&*26>BRVpt|ĝȝНԝ '+59@DKOael_qu|___ŞΞҞ۞ߞ)-6:DHQUgkr_w{___ȟ̟֟ڟ "&8<HL[_fjtx Ơؠܠ___ _#_04;?FJY]d_imt_y}___ʡΡءܡ $(:>JN]ahlvzĢȢڢޢ___ _%_26=AHL[_f_kov_{___£̣Уڣޣ .2>BQU\`jnx|_¤Ƥͤ_Ҥ֤ݤ__#'._37>_KOVZdhrvȥ̥ۥߥ.2;?HL]ahlvzɦ֦ͦڦ$(26@DVZdhrv§ƧЧԧާ"48BFPT^blp¨ƨͨѨ  $.2<@RV`dnrĩȩҩ֩(,6:DHZ^hlvzªɪͪܪ$(26HLVZlpz~ëի٫-1CGQU\`rvƬʬҬ֬ެ&*:>FJRV^bjnvz_­ɭ_έҭ٭__#*_/3:_GKRV_clpy}Ȯ̮Ӯ׮$(04<@HLTX`dlpï̯Яٯݯ__#'._;?FJY]d_imt_y}_ðǰΰҰڰް!*.7;LPW_\`g_lpw__ȱ_ͱѱر_ "&.2CGSWfjqu~_Ųɲв_ղٲ_!_&*1_6:A_NRY]fjsw̳г׳۳ '+37GKRV]ahl{ȴ_ʹѴش___+/6:AEMQbfrvŵɵڵ޵  '+:>EIX\cgvzöǶѶնܶ!(,=AHL[_f_kov_{__÷_ȷ̷ӷ_طܷ__ %)26=ARV_crv}θҸٸݸ '+48IMT_Y]d_imt_y}__ùʹ_Ϲӹڹ_߹_ )-6:AEMQbfrvĺȺٺݺ_ __")_6:AELP_cj_osz___û̻лٻݻ"&/3BFMQZ^gktx__¼ɼ_μҼټ__#*_/3:_?CJ_W[bfos|½ƽսٽ$(/3:>EIX\cgpt__¾ƾ;Ѿ__ "*.?COS\`osz~Ŀȿѿտ $(/3BFMQ`duy !%-19=FJZ^fjrvoooo,09=NR[_pt{ !04=AHL]apt| $(15>BSW^bim|!%,08<DHX\mqz~ (,48HLUY`dmqx|!%48IM^bko &*37HLUYjnuy $(04<@HLTX`dlpx| $,0@DLPW[bfuy !%59IM]aqu| !%-18<LPW[dhqu|"&-19=EIQU]aimuy&*9=DHQUdhos|#'6:BFVZbfmqy}"*.6:BFVZbfnrz~   '+26EIX\eipt !(,;?FJRVgksw  $-1:>OS\`im~  !15EIY]mqy} #48?CRV^brv/3DHQU\`qu&*;?HL]arv04CGPT[_pt   $,08<LPY]nry}#+/7;CGW[dhy} /3:>MQX\kox| #48GKZ^gkrv '+26EIRVjn!%CGVZfjvz   )-9=FJ^bko  $8<Z^mq*.6:AELP_cjn} &*AELP_cko#+/;?FJQU\`hl| -18<KO^bnr %)48CG[_fjy}#7;JNeix| #'7;DHQUlpw{&*9=EIY]hl  $+/6:BFVZaemqx| +/7;KO[_fjy} +/:>IMaelp!%04HL[_vz/3<@LPY]qu *.7;GKTXlp                  # 3 7 H L [ _ f j q u                      0 4 ? C O S ^ b u y                          ! % - 1 @ D KP T [h l s w ~                     * . 5 9 A E T X _ c r v }                      . 2 : > N R Y ] l p x |                 1 5 DHPT\`hl|(,37>BJNVZcgnry} tt&*37HLSWfjqtvzt__ %)26>BKO_ckow{ $(04;?GKRVfjrv~'+;?FJRV]apt &*26>BRV]ahlsw !26?CJN_crv}#'/3CGPTeirv$(7;LPY]dhy}                      # 2 6 = A H L c g n r {                     & * 5 9 L P W [ c g v z                         "' + 2? C J N U Y h l {                       + / 6 : I M T X g k s w                      % ) 0 4 C G O S c g r v                '+37?CSW`dmqx| #'26HLVZnr{"-1:>GK^bim|.2:>NRY]lp !04>BVZcgpt$15DHW[jn}   9 = L P n r               . 2 9 = D H O S Z ^ e i x |  _   _   _              ' + 4 8 I M T X g k             # ' 6 : X \ k o                ! 2 6 E I V Z d h w {                  o o-18_EIRV]ajn{'+26?CTX_odhoo|_&*;?FoKOVocgn_{ )-7;EISWaew{%)37AEOS]asw )-59AEMQY]mq{ #-1?CQU_cmq{(,37@DMQZ^oszoo_ #,07;LP_cmqx|"&59KOim|%)04<@HL\`gkrv}o_' '+:>EIRV_clpy} '+48?CLPW[dhos| &*9=FJSW`dmqz~ !(,48AENR[_hluy%)15>BKOX\eirv '+48AENR[_pt} )-6:KOVZimvz    * . 5 9 H L U Y b f o s                    !!!!'!+!#G#K#\#`#i#m#~#################$ $$$$#$'$.$2$;$?$P$T$]$a$h$l$s$w$~$$$$$$$$$$$$$$$$$% %%%%$%(%9%=%D%H%O%S%Z%^%g%k%r%v%%%%%%%%%%%%%%%%%%% &&&&.&2&;&?&H&L&U&Y&b&f&o&s&&&&&&&&&&&&&&&&&'' ''"'&'/'3'D'H'O'S'b'f'o's'|''''''''''''''''(( (("(&(-(1(@(D(U(Y(j(n(}((((((((((((((((()))')+)<)@)I)M)T)X)i)m)|)))))))))))))))))***&***;*?*P*T*c*g*x*|*************** +++#+2+6+G+K+\+`+o+s++++++++++++++, ,,,,+,/,>,B,S,W,`,d,k,o,,,,,,,,,,,,,,,,,,,-----!-(-,-5-9-@-D-U-Y-b-f-o-s------------------....".3.7.@.D.U.Y.`.d.s.w.~._..._.............///'/+/4/8/?/C/T/X/g/k/r/v////////////////_0000 0$0+0/0>0B0L0P0Z0^0p0t00000000000000000 1111.121<1@1R1V1`1d1v1z111111111111111112 22"2,202B2F2M2Q2`2d2n2r222222222222222223333,303:3>3P3T3^3b3t3x3333333333333334444)4-4?4C4M4Q4X4\4n4r444444444444444455 55"51555G5K5U5Y5`5d5v5z5555555555555556 666&6*696=6O6S6]6a6h6l6~66666666666666 777#7*7.797=7N7R7Y7]7d7h7o7s7777777777777777778 8888-818@8D8N8R8d8h8w8{88888888888888899 99"9&95999C9G9Y9]9o9s999999999999999::::/:3:H:L:^:b:r:v:::::::::::::::;;;;";&;5;9;B;F;W;[;b;f;u;y;;;;;;;;;;;;;;;;;<<<!<2<6<=<A<P<T<]<a<r<v<<<<<<<<<<<<<<<<<====!=%=6=:=C=G=X=\=c=g=v=z===============>>>>*>.>7>;>B>F>W>[>j>n>>>>>>>>>>>>>>>>>????)?-?6?:?A?E?V?Z?i?m?~????????????????@@@@(@,@5@9@@@D@U@Y@h@l@}@@@@@@@@@@@@@@@@@AAAA!A0A4A=AAARAVA_AcAtAxAAAAAAAAAAAAAAAAABBBB#B'B8BDBDTDXDgDkD|DDDDDDDDDDDDDDDDEEEE*E.E8EGGGKG\G`GgGkGzG~GGGGGGGGGGGGGGGGH HH H$H+H/H>HBHKHOH`HdHmHqHHHHHHHHHHHHHHHHHIIII$I(I1I5IFIJIQIUIdIhIoI_tIxII_III_III_III_IIIIIIIIIIJ JJ_JJ J_%J)J0J_5J9J@J_EJIJPJ_]JaJjJnJwJ{JJJJJJJJJJJJJJJJ_JJK_K KK_KK!K_.K2K;K?KFKJKSKWK`KdKuKyKK_KKK_KKK_KKK_KKK_KKKKKKKKKKL LLLL"L)L-L>LBLSLWL`LdLkLoLLLLLL_LLL_LLL_LLL_LLLLLLLM M MMM)M-M4M_9M=MDM_IMMMTM_YM]MdM_qMuM~MMMMMMMMMMMMMMMMNNNN$N(N/N3NDNHNWN[NlNpNyN}NNNNNNNNNNNNNNNOOOO#O'O.O2OCOGOVOZOkOoOxO|OOOOOOOOOOOOOOOPP PPP#P*P.P>PBPIPMP]PaPhPlP|PPPPPPPPPPPPPPPPPP QQQQ"Q&Q7Q;QJQNQUQYQiQmQuQyQQQQQQQQQQQQQQQQQQQQRR RRR%R)R2R6R?RCRLRPRYR]RfRjRsRwRRRRRRRRRRRRRRRRRRoRRRoRSSo SSSoS!S(So-S1S8SoESISRSVS_ScSlSpSyS}SSSSSSSSSSoSSSoSSSoSSSoTT ToTT%T)T2T6T?TCTLTPTaTeTsTwTTTT_TTT_TTT_TTT_TTT_TTTTTTU UUU'U+U9U=ULUPUWU_\U`UgU_lUpUwU_|UUU_UUU_UUUUUUUUUUUUUVVVV_*V.V?VCVQVUVdVhVoV|VVVVVVVVVVV_VVVV WWWo#W'W8W_B_K_O_X_\_e_i_r_v_________________` ```&`*`3`7`@`D`U`Y`b`f`o`s`````````````````aa aaa"a+a/a8ahHhLhShWhihmh|hhhhhhhhhhhhhhhhiiii*i.i6i:iIiMiUiYiiimi}iiiiiiiiiiiiiiiij jjj!j%j7j;jJjNj_jcjmjqjxj|jjjjjjjjjjjjjjj kkkk&k*klOlSldlhlwl{llllllllllllllllmmo mmmom m'mo,m0m7mopBpQpUp^pbpkpoppppppppppppppppppq q qqq+q/q6q:qIqMqVqZqcqgqxq|qqqqqqqqqqqqqqqqq r rrr'r+rsBsIs_NsRsYs_^sbsis_nsrsys_sssjsssjsssjsssjsssssstt ttt#t*t.t=tAtJtNt_tctjtnt}ttttttttttttttttuu"u&u-u1u8u~B~Q~U~^~b~s~w~~~~~~~~~~~~~~~~~~"&7;BFUYjn#48?CRV_ctxŀրڀ#'8<EIZ^eix|ǁˁځށ,09=DHY]lpłւڂ+/8<CGX\koăՃك*.7;BFW[jnÄԄ؄)-6:AEVZim~…Ӆׅ   # * . 5 9 H L S W f j q u }        Ć Ȇ φ ӆ         * . 5 9 H L T X h l w {         Ӈ ׇ އ           $ ( / 3 : > E I Q U e i p t         ƈ ʈ ш Ո ܈        ! % 4 8 G K W [ j n u y           Љ ԉ ۉ ߉        ! , 0 D H O S b f m q x |         ʊ Ί ֊ ڊ          $ 3 7 N R a e t x   """"‹"Ƌ"͋"ы"ڋ"ދ""""" """!"*"."="A"Q"U"f"j"q_~""""""""Ì"nj"׌$ی$$$$$$$ $$$$*$.$5$9$A$E$U$Y$j$n$}$$$$$$$$$$ƍ$ʍ$Ӎ$׍$$$$$ $$$$,$0$;$?$R$V$a$e$q$u$$$$$$$$$$Ŏ$̎$Ў$؎$܎$$$$$$$ $ $$$)$-$4$8$C$G$O$S$b$f$mr$v$}$$$$$$$$Ə$ʏ$ڏ$ޏ$$$$$ $$$$.$2$9$=$L$P$W$[$c$g$v$z$$$$$$$$$$$Ґ$֐$$$$$$ $$$&$*$1$5$<$@$P$T$\$`$p$t${$$$$$$$$$$̑$Б$$$$$$$%$)$8$<$S$W$f&j&r&v&}&&&&&&&&&Œ&̒&В&ؒ&ܒ&&&(( ((((!(%(4(8(?(C(R(V(](a(p(t({((((((((((̓(Г(ߓ((((((((%*)*3*7*H*L*S*W*_*c*s*w*~*********”*ɔ*͔*Ԕ*ؔ******* ***!*1*5*E*I*R*V*b*f*w*{**********Õ*ʕ*Ε*ݕ********)*-*<*@*O*S*b*f*u*y*********ǖ,˖,ז,ۖ,,,,, ,,,",8,<,D,H,X,\,d,h,x,|,,,,,,,,,,,ė,ȗ,ח,ۗ,,,,,,,, ,,,,!,1,5,>,B,K,O,a,e,l,p,x,|,,,,,,,,,Ę,Ș,ܘ,,,,, ,,,-,1,8,<,K,O,V,Z,i,m,t,x,,,,,,,,,,,ʙ,Ι,ޙ,,,,, ,,,$,(,0,4,;,?,N,R,Y,],l,p,x,|,,,,,,,,,Ě,Ț,Ϛܚ,,,,,,, ,,,',+,3,7,>,B,R,V,^,b,r,v,~,,,,,,,,,,,›,ʛ,Λ,ݛ,,,,,,,,-,1,8,<,L,P,W,[,j,n,u,y,,,,,,,Ü,ǜ,֜,ڜ,,,,,,,,,,,.,2,:,>,N,R,Z,^,f,j,r,v,,,,,,,,,Ý.ǝ.Ν.ҝ.ޝ...... E..E).-.4o9.=.DoQ0U0_0c0j0n0u0y00000000000ʞ0Ξ0՞0ٞ0000000000 0)0-060:0A0E0V0Z0d0h0o0s0|0000000000Ο0ҟ0ڟ0ޟ000000 0000#0,00090=0F0J0S0W0`0d0u0y000000000à0Ǡ0Ԡ0ؠ0000000 0$0,00080<0D0H0X0\0e0i0r0v00000000000͡0ѡ0000000000!0*0.0?0C0L0P0Y0]0n0r0|0000000000Ң0֢0ݢ00000000"0&080<0F0J0\0`0j0n00000£ˣϣ '+48AEVZcgnr{¤Ƥդ٤"&/3<@QU^bkoĥ˥ϥ  $37AEW[eipt_ŦɦЦ_ݦ %)04=AHL]ah_mqx_ͧѧ "&-_26=_JNUYbfw{__¨ƨרۨ '+<@G_LPW_dhos|__ĩȩѩթ '+2_?CJNW[dhy}_Ǫ˪ڪު+/6:AEVZaetxǫ˫ګޫ,09=DHY]nr{ìǬЬԬ۬߬'+59@DVZdhos___ȭ̭ӭ׭(,37HLS_X\c_hls_Ůɮծٮ "&7;B_GKR_W[b_osz~__ǯ_ԯد߯ )-<@GKTXaevz___ðǰΰҰ۰߰_ __(,37@DMQ`dptűɱб_ձٱ_ '+2_7;B_OSZ^mq}˲ϲ #*.=AHL[_hl}ҳֳ '+<@OSdhqu|´Ӵ״ #'9=GKRVhls_x|__õǵεҵ۵ߵ +/6_;?F_KOV_cgnr{˶϶ֶڶ %_*.5_:>E_RV]ajn___·ƷϷӷܷ #*.7;DHY]nry_~__¸Ӹ׸޸___ #'04CGSWfjqu~_ù_йԹ۹߹ _%_26=APT`dswúǺ׺ۺ  $+/>BKO`dmqʻλݻ #26GKTX_ctxɼͼ׼ۼ  *.59KOV_[_f_kov_½ɽͽֽڽ_")_.29_FJQU^bkox|ƾʾӾ׾_ _!(_59@DMQbfm_rv}__ÿ̿п߿ '+<@QU\_ael_qu|____ &*6:IMTXaevz____ $37CGVZim~!%.2CGPTeipt*.7;BFW[lpy} .29_>BI_NRY_fjqu|_ __)-48AENR[_nr~__ _#'04EIP_UY`_eip_} #48?_DHO_TX__lpw{___  ,07;DHY]nry_~___&*9=LPaetx&*37HLSWfj{ %):>OS\`gk|2222222222222222 222 2+2/2=2A2L2P2[2_2m2q22222222222222222222222222 2,20292=2F2J2V2Z2k2o2w2{222222222222222222222&2*21252<2@2H2L2S2W2_2c2r2v2222222222222222222222 222*2.292=2H2L2U2Y2c2g2z2~2222222222222222222222222.222;2?2J2N2W2[2d2h2s2w22222222222222222222 2222#22262=2A2J2N2U2Y2`2d2m2q2x2|2222222222222222222 22&2*2162:2AN2R2Y^2b2iv2z222222222222222 222!20242<2@2H2L2\2`2gt2x222222222224444444 444&4*43474B4F4Y4]4di4m4t4444444444444444444 444.424=4A4L4P4[4_4r4v4}4444444444444444 4 44 4/434>4B4M4Q4\4`4s4w4~4444444444444444 444!40444=4A4L4P4Y4]4f4j4u4y4444444444444444444444 4'4+4<4@4O4S4b4f4u4y444444444444444444#4*74;4C4G4W4[4b4f4u4y44444444444444444&4*494=4L4P4_4c4l4p4{44444444444444444444%4)484<4K4O4Vc6g6n6r66666666666666666666 6666 6(6,6;6?6N6R6Y6]6d6h6p6t666666666666666666666!6%64686G6K6Z6^6er6v666666666666666 66$6(6/4686?L6P6W\6`6gtx '+37@DMQZ^gktx (,8<FJVZcgsw ".2>BNR\`lpw{ '+8<GKVZeitx  $-1:>GKTXaelp #,09=FJSW^bkox| )-6:CGPT]ajnw{  #'04=AJNW[dhqu~#26?CJN_crv  #'8<EIRV_clpy}%)26?CLPY]fjsw#'04=AJNW[dhqu!*.7;LPW[gkz~ -1:>EIZ^mq .2;?PT[_nr{"/3DHQUfjsw!%6:IMVZko{ #48BFX\nr %):>MQbfw{(,=AHL[_hluy !%,07;JNVZbfnr  &*6:FJVZnr{ .2;?HL]amqx|"&:>OSdhw{!9%9-919A9E9L9P9X9\9l9p9w9{9999999999999999999999999$9(979;9C9G9W9[9b9f9n9r9y9}9999999999999999999 9 99 9/939B9F9M9Q9a9e9t9x99999999999 #+/7;KOVZcgnry} '+48?CLPW[dhos  !(,37FJQU^bkovz"&/3<@HLUYbfnrz~ #'.2;?FJ[_hluylll l$(15>BKO`dmqx|  )-6:CGPT]ajnw{  !%.2;?HLUYjnuy "&/3<@IMVZkovz !(,;?HLUYjnw{-1:>OS\`qu~ $59BFW[bfuy_ $+/@DUYjn}'+<@IMTXim|    " & . 2 : > F J R V ^ b j n ~                          ( , 5 9 I M W [ g k u y                       % ) 2 6 G K S W ^ b q u ~                      " & - 1 A E M Q a e m q                      " ) - < @ Q U f j y }                    %):>EIX\mq  $59HLSW_cko~'+26?CJN_cjn%)9=EIQUeipt{ !%.2CGPT]ajn_  $+_8<MQ_crv'+37GK\`qu_*.?CQUdhoo| "15>BKO`dlp__ *.<@OSZgktx /3<@QUfjq_~__ )->BSWhl} #48GKTX_ctx  '+37>BQU\`os| !26?CJN_cjn>>>>>>>>>>>>>>>>>> > >_>>$_1>5>>>B>S>W>^_k>o>>>_>>>>_>>>>>>>> > >>">)>-><>@>I>M>T>X>i>m>|QQQQQQQQQQQQQQQQQQQ Q_QQ!_.Q2Q;Q?QPQTQ[_hQlQ}QQ_QQQQ_QQQQQQQQ Q Q Q Q& Q* Q9 Q= QF QJ QQ QU Qf Qj Qy S} S S S S S S S S S g S S g S S o S S o! !!!%!)!5!9!C!G!S!W!c!g!{!!!!!!!!!!!!!!!!!!" ""!"(","3"7"F"J"Q"U"\"`"g"k"z"~""_""""""""""""""####$#(#7#;#B#F#O#S#b#f#m#q##################$ $ $$$$#$2$6$=$_J$N$U$Y$j$n$u$y$$$$$$U$U$U$U$U$U$U$U$U$U$U$U$U$U%U%U%U%U!%U%%U5%U9%U@%UD%US%W%f%j%y%}%%%%%%%%%%%%%%%%%%&&&&&)&-&=&A&K&O&Y&]&o&s&}&&&&&&&&&&&&&&&&&' '''')'-'?'C'J'N']'a'k'o'y'}'''''''''''''''''(((#(-(1(C(G(N(R(a(e(o(s(}(((((((((((((((() )))+)/)6):)I)M)T)X)_)c)r)v)))))))))))))))))*****"*4*8*?*C*R*V*`*d*n*r*|*****************+ ++"+&+0+4+>+B+T+X+_+c+r+v+++++++++++++++++,,,,&,*,4,8,B,F,X,\,c,g,v,z,,,,,,,,,,,,,,,,,,----"-,-0-7-;-E-I-S-W-i-m-|----------------.. ..".&.0.4.>.B.L.P.Z.^.h.l.v.z................../ //"/&/0/4/>/B/L/P/Z/^/h/l/v/z//////////////////0 00000040>0B0L0P0Z0^0h0l0v0z0000000000000000001 1111(1,1>1B1L1P1Z1^1h1l1v1z1111111111111111112 2222(2,262:2L2P2Z2^2h2l2v2z2222222222222222223 3333(3,363:3D3H3Z3^3h3l3v3z3333333333333333333 4 444%4)43474>4B4L4P4Z4^4h4l4s4w4444444444444444455 555#5-515;5?5I5M5W5[5e5i5s5w55555555555555555556666-616;6?6I6M6W6[6e6i6s6w66666666666666666667 77!7(7,7;7?7I7M7W7[7e7i7s7w77777777777777777778 888+8/868:8I8M8W8[8e8i8s8w88888888888888888889 999#9'999=9D9H9W9[9e9i9s9w9999999999999999999: :::#:':1:5:G:K:R:V:e:i:s:w:::::::::::::::::::; ;;;#;';1;5;?;C;U;Y;`;d;s;w;;;;;;;;;;;;;;;;;;;< <<<#<'<1<5<?<C<M<Q<c<g<n<r<<<<<<<<<<<<<<<<<<<= ===#='=1=5=?=C=M=Q=[=_=q=u=|==================> >>>#>'>1>5>?>C>M>Q>[>_>i>m>>>>>>>>>>>>>>>>>>>>???#?'?1?5???C?M?Q?[?_?i?m?w?{??????????????????@ @@#@'@1@5@?@C@M@Q@[@_@i@m@w@{@@@@@@@@@@@@@@@@@@A AAAA1A5A?ACAMAQA[A_AiAmAwA{AAAAAAAAAAAAAAAAAAB BBBB)B-B?BCBMBQB[B_BiBmBwB{BBBBBBBBBBBBBBBBBBC CCCC/C3CECICcCgCvCzCCCCCCCCCCCCCCCCCCCCDDDD#D*D.D=DADHDLDWD[DbDfDqDuD|DDDDDDDDDDDDDDDDDEE EEE"E&E9E=EEEIEYE]EgEkEuEyEEEEEEEEEEEEEEEEEEEF FFF!F%F6F:FAFEFLFPFWF[FjFnFuFyFFFFFFFFFFFFFFFFFFFGGGG5G9GHGLGfGjGyG}GGGGGGGGGGGGGGGGG HHHH,H0H8HJBJJJNJVJZJjJnJuJyJJJJJJJJJJJJJJJJJJJK KKK"K&K0K4K>KBKLKPKZK^KhKlKvKzKKKKKKKKKKKKKKKKKL LLL L$L+L/L8LfBfLfPfbfffmfqfffffffffffffffffgggg&g*g4g8gJgNgUgYghglgvgzggggggggggggggghhhh!h%h4h8hBhFhXh\hfhjh|hhhhhhhhhhhhhhhhi iii.i2iDiHiZi^imiqiiiiiiiiiiiiijjjj*j.j@jDjVjZjijmjjjjjjjjjjjjjjjkkkk&k*k4k8kJkNkUkYkhklkvkzkkkkkkkkkkkkkkkllll!l%l4l8lBlFlXl\lfljl|llllllllllllllllmmmm$m(m2m6mHmLmSmWmfmjm|mmmmmmmmmmmmmmnn#n'n9n=nOnSnbnfnxn|nnnnnnnnnnnnn ooo#o5o9oKoOo^obotoxooooooooooooooopppp'p+p6p:pCpGpPpTpepipppupypppppppppppppppppq qq!q%q?qCqRqVqpqtqqqqqqqqqqqqqqqqqrrrrr#r-r1rCrGrNrRrarerorsr}rrrrrrrrrrrrrrrrs sss*s.s5sBsFsXs\snsrsysssssssssssss ttt#t5t9tCtGtNtRtdthtwt{tttttttttttttttuu$u(u2u6u=uAuSuWufuju|uuuuuuuuuuuuuuuuvvvv,v0v:v>vEvIv[v_vnvrvvvvvvvvvvvvvvvvv www"w4w8wBwFwMwQwcwgwvwzwwwwwwwwwwwwwww xx#x'x9x=xLxPxbxfxxx|xxxxxxxxxxxxx y yy#y5y9yHyLy^ybytyxyyyyyyyyyyyyyz zzz1z5zDzHzZz^zpztzzzzzzzzzzzzz{{{{%{){0{4{F{J{Y{]{o{s{}{{{{{{{{{{{{{{{{ | |||"|&|8|<|K|O|V|Z|a|e|o|s|z|~|||||||||||||||||||||} }}}&}*}1}5}<}@}J}N}U}Y}c}g}n}r}|}}}}}}}}}}}}}}}}}}}}~~ ~_~~~_!~%~,~_1~5~<~_A~E~L~_Y~]~d~h~r~v~}~~~~~~~~~~~~~~~~~~~~ _#_(,3_@DKOY]dhrv}zzzz!%,z15<zIMUYaeuyzzzzȀz̀р؀z!)-=AIMUYimuýЁׁz܁zzzz$(/z<@HLTXhlszx|ʂ΂Ղق #'6:AETX`dtxzzzzăȃЃԃ܃z z#'.z37>zKOW[cgnr„Ƅ΄҄ڄބ %)0z59@zEIPz]ahzmqxz}zŅ̅zхՅ܅ #'04CGNR[_fjy}ˆφ"15<zAELzQU\zaelzy}zzzzŇ͇ч؇܇z z#z(,3z@DKzPT[z`dkzpt{zÈˈψ׈ۈ/3;?GK[_fjrv~zzzʉΉՉzډމzz.29z>BIM\`gkrvȊ̊ӊ׊$(7;JNUYbfosҋ֋oo_(,<@G_TX_ctx_Ìˌόߌ__ '+2_?CJN]aimvz_ƍ΍ҍۍߍ  +/6:IMVZkox|Žˎώގ#'8<CGVZcgx|ÏǏ֏ڏ+/6:CGPT]ajnʐΐאې (,<@GKUYcgqu‘Ƒܑؑ &*37@DUY`dptȒ̒Ӓג ".2>BNRfjquȓ̓ӓד ,07;JN^bvzÔǔؔܔ'+<@GKZ^eiswĕȕҕ֕!*.7;DHQU^bsw~ĖȖіՖ"+/8<EIRV_ctx—Ɨϗӗ#48AEVZaetxʘΘטۘ  $+/=APT[_pt}ʙΙיۙ &*37@DMQZ^gk|Қ֚ݚ  #'04EIPT[_fjqu|śΛқۛߛ ")-48?CRV_clpy}œƜϜӜܜ -18<KOX\eirv____ǝ˝ҝ_ߝ &*;?F_KOV_[_f_kov_Ҟ֞ߞ,09=FJSW`duyŸɟ͟ܟ"+/8<MQZ^gktxŠΠҠ!04;_@DK_PT[_hltxġȡѡա"37@DMQbfmqĢȢϢӢ #48IM\`quãǣ֣ڣ(,=APTeiz~ʤΤؤܤ.2CGX\ko¥̥Хץۥ+/>BTXim|ϦӦ "&59KO`dswƧʧۧߧ+/AEVZim¨ƨШԨި !%.2<@QUdhos}ĩΩҩ %)26GKRVbfuyŪɪتܪ $(15>BKOX\eiz~ȫ̫ի٫#26?CUYbfw{ǬˬԬج߬  $59BFOS\`imvzíʭέڭޭ 15<@OSZ^gktxĮծٮ  #'04EIPT`dsw¯Ưկٯ  #'04EIRV_clpy}İҰְ '+26EIRV_clpy}±Ʊϱӱܱ #,0AENRcgnrIJȲѲղ޲ #,09=FJ[_hluyų̳г߳  #26@DNR\`rv̴д  "37FJ\`jnuyȵ̵۵ߵ .2CGVZlp¶Ѷն#'8<KO`duyŷɷ۷߷-1@DMQ[_imvzŸԸظ߸  "&04>BLPbfos|ҹֹݹ #'04EIPTcgnr|úͺѺۺߺ %)26?CLPaelp|ûԻػ߻ '+26@DNRY]gkuy¼˼ϼؼܼ #*.=AKOY]gkuy½ƽϽӽܽ%)04CGNR\`jnx|ɾ;߾  $-1:>GK\`gkw{οҿٿݿ  $-1:>GKTXaenr"+/8<EIRVgktx )-6:CGPT]ajn '+48AENR[_hluy #'6:CGX\cgvz .2:>NR[_hluy %)26?CTXaenr{  $+/>BLPZ^hl~ +/AEVZim~(,;?PTeix|  !%6:IM_ctx+/>BSWhl{ #'8<KOaevz )-6:CGOS\`im~ !*.:>JNbfpt{#*.@DSW^_cgn_sw~_  #'04;?HL]akovz %)04=ARV`dkox|!*.7;DHQU^bsw!+/9=DHRV`dnr  %);?IMW[eisw%)04CGQU_cmq{  -1;?IMW[ei{%)37AEOS]asw  #-1;?IM_cjn}-1CGQU\`rv]]]]]]]]]]]]]]]] ]]]],]0]7];]B]F]U]Y]b]f]o]s]z]~]]]]]]]]]]]]]]]]]]]&]*];]?]F]J]Y]]]n]r]{]]]]]]]]]]]]]]]]]]] ]]]']+]3]7]?]C]J]N]V]Z]b]f]n]r]z]~]]]]]]]]]]]]]]]]]]]]] ]]&]*]2]6]F]J]R]V]^]b]r]v]~]]]]]]]]]]]]]]]]]] ]]]#]*7];]C]G]O]S]c]g]w]{]]]]]]]]]]]]]]]]]] ]]]]"]*].]6]:]B]F]M]Q]a]e]l]p]x]|]]]]]]]]]]]]]]]]]]]]] ]]]]#]']/]3];]?]O]S]Z]^]e]i]x]|]]]]]]]]]]]]]]]]]]]] ]]]%])]0]4]<]@]H]L]T]X]`]d]t]x]]]]]]]]]]]]]]]]]]]]]] ]]]]!](],]3]7]F]J]Q]U]\]`]g]k]r]v]]]]]]]]]]]]]]]]]]]]]]]]]]!]0]4]<]@]H]L]\]`]h]l]|]]]]]]]]]]]]]]]]]]]]]]']+];]?]O]S]Z]^]n]r]]]]]]]]]]]]]]]]]]]#'04=AHL]ajnw{  !%.29=FJQU\`imtx&*37@DNR\`imvz  /3:>EIPT[_fjqu|"&/3<@QU\_ael_qu|__ %)04EIZ^mqz~ "&.2:>MQZ^gk|___ )-6:AENR[_fjy}"&7;DHOSdhw{  !%.2;?HLSW`dkox|!*.7;BFOSZ^gktx (,59BFOS\`imvz (,59FJSW`dmqz~&*15<@QU^bimvz !%.2;?FJSW^bkox|&*;?HLUYhlsw'+<@PTlpw{ "+/8<EIRV]ajnuy04;?NR[_hlsw 04;?HL]ajn *.59HLUYjn /3CGX\eipt"&-1AELPW[jnx| ,07;GKRVjnw{____________________&_*_2_6_>_B_Q_U_^_b_k_o______________________"_)_-_6_:_I_M_T_X_a_e_l_p_______________________%_)_2_6_G_K_R_V_b_f_u_y_______________ _ __ _)_-_4_8_I_M_\a`agakasawaaaaaaaaaaaaaaaaaaaaaaaaaa!a2a6a=aAaPaTa[halasawaaaaaaaaaaaaaaaaaaaaa aaaa,a0a9a=aNaRaYa]alapaxa|aaaaaaaaaaaaaaaaaaa aa a$a-a1a:a>aOaSaZ_acajoasazaaaaaaaaaaaaaac cccc"c+c/c>cBcIcMcVcZcacecvczccccccccccccccceeeeeeee%e)e1e5eEeIePeTeeeieueyeeeeeeeeeeeeeeeeeee eeee,e0e<e@eTeXe_eceueyeeeeeeeeeeeeeee eeee5e9eAeEeUeYeaeeemeqeye}eeeeeeeeeeeeeeeeeeee eee)e-e4e8e?eCeJeNeUeYe`edesewe~eeeeeeeeeeeeeeeeeeee e e e e& e* e: e> eZ e^ em eq e e e e e e e e e g g g g g g g g g g g g& g* g; g? gH gL gX g\ gm gq gx g| g g g g g g g g g g g g g g g g g g g g g" g& g= gA gI gM gU gY ga ge gu gy g g g g g g g g g g g g g g g g g g g g g$ g( g1 g5 gF gJ gS gW gh gl g{ g g g g g g g g g g g g g g g g g g g g# g' g0 g4 gE gI gP gT gc gg gx g| g g g g g g g g g g g g g g ggggggg&g*g2g6gFgJgRgVg^gbgigmgugyggggggggggggggggggggggg gg!g%g,9g=gEgIgQgUgegigqgug}gggggggggggggggggg ggg"g).g2g9>gBgIVgZgbgfgngrggggggggggggggggggggg)g-g4g8g@gDgLgPgWg[gcgggogsg{gggggggggggggggggggg g ggg g$g,g0g8g<gDgHgPgTg\g`ghglg|gggggggggggggggggggggg gg g$g+g/g8g<gKgOgVgZgcgggngrggggggggggggggggggggg gggg%g)g1g5gEgIgPgTg\g`ghglgtgxggggggggggggggggggggggggg"g&g/g3g:g>gEgIgXg\gcgggngrgyg}ggggggggggggggggg g ggg'g+g2g6g?gCgJgNg_gcglgpgyg}gggggggggggggggg ggg$g(g8g<gDgHgPgTgdghgxg|ggggggggggg )-?CJNVZbfnrz~ __(,3_@DKOW[cgos{"&59@DLP`dqu"&;?FJRV^brv .2:>FJZ^ei{!)-48HLTX`dtx37FJfjy} %)26?CTX_crv}      0 4 ; _@ D K _X \ c _p t {                 ! !!!)!-!4!9!=!D!I!M!T!a!e!p!t!}!!!!!!!!!!!!!!!!"_ """_""&"_+"/"6"_C"G"P"T"]"a"j"n""""_"""_"""_"""_""""""""###_###_##'#.#_3#7#>#_K#O#X#\#e#i#r#v############### $$ $$$+$/$6$:$I$M$V$Z$a$e$n$r${$$$$$$$$$$$$$$$$ %%%%+%/%6%:%C%G%X%\%j%n%|%%%%%%%%%%%%%%%%%%%&&&$&(&6&:&H&L&b&f&m&q&z&~&&&&&&&&&&&&&&&''''%')';'?'F'J'd'h'q'u'~'''''''''''''''' (((($(((1(5(>(B(S(W(^(b(k(o(v(z((((((((((((((((((( ))))!)%),)0)7);)J)N)U)Y)b)f)m)q))))))))))))))))))* *$*3*7*U*Y*h*l*s*w*~*****_***_***_********+ +++%+)+:+>+G+K+\+`+n+r++++_+++_+++++++++++,,,,#,4,8,F,J,Y,],f,j,{,,,,,,,,,,,,,,,,,,- ---'-+-3-7-?-C-K-O-_-c-j-n-u-y---------------------. ....!.).-.=.A.I.M.U.Y.a.e.m.q.....................////*/./=/A/R/V/_/c/j/n///////////////////0000"0&0/030:0>0G0K0T0X0i0m0t0x000000000\000000 111 1/131:1G1K1\1`1q1u1~11111111111111111122222!2*2.2?2C2J2N2Z2^2m2q2z2~2222222222222222233"3&3/333:3>3O3S3b3f3m3q3x3|333333333333333334444(4,45494B4F4W4[4d4h4q4u4~444444444444444444 5555*5.5?5C5T5X5a5e5l5p55555555555555555 66 6$6-616B6F6P6T6f6j6r6v66666666_666666667777 7_-717A7E7R7V7e7i7y7}777777_777777777_8888&8*898=8E8I8Q8U8e8i8y8}88o888o888o888o88888888889 999%9)91959=9A9Q9U9b9f9u9y99_999_999_999999999999: ::: :$:4:8:E:I:X:\:c:_h:l:s:_x:|::_:::::::::_:::_:::_::;; ;; ;$;+;_0;4;;;_@;D;K;_X;\;d;h;p;t;;;;;;;;;;;;;;;;;<<<<&<*<1<5<F<J<Y<]<m<q<x<|<<<<<<<<<<<<<<<<<<= == =$=-=1=B=F=U=Y=h=l=s=w=================== >>>>->1>I>M>\>`>x>|>>>>>>>>>>>>>>>>?? ????"?1?5?=?A?I?M?]?a?h?l?s?w?~???????_???_???_???????@ @@@@&@*@;@?@H@L@S@W@_@c@k@o@x@|@@@@@@@@@@@@@@@@@AAAA!A%A.A2AFAJA^AbAjAnAwA{AAAAAAAAAAAAAAAAAB BBB$B(B;B?BFBJBSBWB`BdBkBoBxB|BBBBBBBBBBBBBBBBBBBBBC CCC'C+C2C6C=CACJCNCWC[CdChCoCsCCCCCCCCCCCCCCCCCCCCCD DDD D$D-D1D8DIBIKIOIXI\IeIiIrIvIIIIIIIIIIIIIIIIIIIJ JJJ"J&J/J3JDJHJQJUJ^JbJkJoJxJ|JJJJJJJJJJJJJJJJJJJKK#K'K0K4K;K?KPKTKcKgKxK|KKKKKKKKKKKKKKKKKLLLLL!L2L6L=LALPLTL]LaLjLnLwL{LLLLLLLLLLLLLLLLLMMMMM!M-M1M:M>MOMSM_McMlMpM|MMMMMMMMMMMMMMMMMMMN N NNN#N'N8NUGUKUZU^UoUsU|UUUUUUUUUUUUUUUUUUV VVV'V+V4V8VAVEVNVRVcVgVnVrV~VVVVVVVVVVVVVVVVVW WWWW"W&W/W3W:W>WFWJWYW]WdWhWqWuW~WWWWWWWWWWWWWWWWWW XXXX'X+XYOYSYZY^YmYqYzY~YYYYYYYYYYYYYYYYY ZZZZ%Z)Z1Z5ZEZIZQZUZ]ZaZiZmZ}ZZZZZZZZZZZZZZZZZZZZZ[[[[[,[0[E[I[R[V[g[k[t[x[[[[[[[[[[[[[[[[[[[ \\\\(\,\;\?\F\oK\O\V\o[\_\f\os\w\~\\\\\\\\\\\\\\\o\\\o\\]o]]] ])]-]6]:]A]E]T]X]a]e]t]x]]_]]]_]]]_]]]]]]]]]]]]]^^^^^#^*^/^3^:^?^C^J^O^S^Z^g^k^r^v^^^^^^^^^^^^_^^^_^^^_^^_ ___'_+_2__7_;_B__G_K_R____c_o_s_|____________________`` `_``(`,`5`9`H`L`S`_X`\`c`_h`l`s`_````````````````````aaa)a-a4ao9a=aDaoQaUaaaeanaraaaaoaaaoaaaaaaaaa_aaa_bbbbb"b1b5b>bBbSbWbhblb{bbbobbbobbbobbbbbbbbbbbbc ccc$co)c-c4coAcEcLcPcYc]cfcjcyc}cccccccccccccccccccccd d ddd)d-d>dBdId_NdRdYd_^dbdid_vdzdddddddd_ddd_ddd_ddddddeeee(e,e5e9eJeNe_eceje_oeseze_eee_eeeeeeeeeeeeeeeef ffff&f*f;f?fPfTf[f_`fdfkf_xf|ffffffffofffoffffffgg gogggo(g,g8grkBrkKrkOrkVrkZrkkrkork~rkrkrkrkrkrkrkrkrkrkrkrkrkrkrkrkrksksksk&sk*sk;sk?skHskLskSskWskhsklsk{sssssssssssssssssstt tttt+t/t6t:tBtFtUtYthtlt|tmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtm um umumum2um6umCumGum[um_umlumpum{umumumumumumumumumumumumumumumumumvm vmvmvm#vm2vm6vmGvmKvmTvmXvm_vmcvmtvmxvmvmvmvmvmvmvmvmvmvmvmvmvmvmvmvmwmwm wmwm wm/w3w:w>wFwJwYw]wdwhwowsw{wwwwwwwwwwwwwwwwwwwwwx xxxx#x'x/x3x;x?xGxKxSxWxgxkxrxvx~xxxxxxxxxxxxxxxxxxy yyyy!y0y4y|N|R|Y|]|d|h|o|s|||||||||||||||||} }}}&}*}<}@}I}M}X}\}e}i}r}v}}}}}}}}}}}}}}}}}~ ~~~-~1~C~G~Y~]~o~s~~~~~~~~~~~~~~~~~~~  $37@DSWiomouoyoooooooooooooooooo oo#o0o4oHoLoYo]oholooooooooooòoЀo߀oooooo ooo#o4o8oAoEoLoPoaoeotoxoooooooooǁoˁo܁oooooo o o 'm:>EgIMTX_gko~_̂Ђׂ _%)8<EISWaeos}ƒƃ΃҃ (,48@DTX__dho_|_ÄDŽτӄۄ߄#04AERVkovzŅɅօڅ !)-59@DTXeivzƆʆ׆ۆ "&-1CGY]dhχӇ&*:>FJRVfjqu}Ȉ̈Ոو ")-6:IMTXgk͉щ؉܉ !%-1@DKOZ^os{Ȋ͊ъ؊݊ %)9=DHOS[_gk{___ƋӋ׋  )-48AENR[_hl}njˌҌ֌ &*37HLSW`dmqx|ō֍ڍ04=AJNW[lpy}Ǝʎێߎ !04=AHL]apqtq|qqqqqqqqqqqqϏqӏqڏqޏqqqqqq qqqq!q0q4q;q?qFqJqYq]qdqhqwq{qqqqqqqqq̐qАqqqqqqqqq!q%q,q0q?qCqSqWq_qcqkqoqqqqqssssssÑsǑsבsۑssssss ssss s/s3s<s@sIsMs^sbsismstsxsssssssssɒs͒sܒssssss s ss"s1s5s<s@sIsMsVsZscsgsvszsssssssssǓs˓sԓsؓsߓsssss ss s)s-s4s8sIsMs\s`sismsssssssssŔsɔsٔsݔssssssssss"s1s5s>sBsKsOs`sdsmsqsxs|sssssssssȕs̕sەsߕsssss ssss$s(s9s=sLsPsWs[sdshsys}sssssssssssÖsǖsؖsܖsssssss sss#s,s0s7s;sDsHsYs]sfsjsqsussssssssss×sҗs֗sߗssssssss$s(s1s5sFsJsSsWsfsjssswsssssssssʘsΘsטsۘsssssssss,s0s9s=sNsRs[s_spsts{ssssssssssҙs֙sݙssssssss%s)s1s5s=sAsIsMsUsYsismsusysssssssssssssɚs͚s՚sٚsssssss sss s',s0s7<s@sGTsXs`sdslspsxs|sssssssssěsțsϛsӛsڛsޛsssss sss!s(5s9s@EsIsPUsYs`esispusysssssssssɜs͜sݜsssss sss%s)s2s6s?sCsLsPsWs[sbsfsusysssssssssssssНsԝs۝sߝsssssss ssss+s/s6s:sAsEsLsPsWs[sjsnssssssssssÞsԞs؞sssssssss s$s,s0s8s<sLsPsXs\sdshsxs|sssssssssssƟsʟsٟsݟssssss ssss!s1s5s<s@sHsLs\s`sossszs~sssssssssssРsԠsݠssssssssss&s*s3s7sHsLs[s_shslsusysssssssssġsȡsסsۡsssssssss s$s-s1sBsFsMsQs`sdssswsssssssssŢsɢsѢsբsޢsssssss ss!s04;?GKSW^bjn~£ƣΣң$(/3BFMQY]dhptĤȤϤӤ$(7;BFNRZ^eiquͥѥݥ  '+37GKRVeipt|Ŧɦڦަ '+26GKZ^imtttt ( 0 8@HPX`hpx "$&(*,.02468;=?ADFH J(L0N8P@RHTPVXX`Zh\paxchjlntv|~ (08@HPX`hpx9 (08@HPX`hpx    "$&(*,.0246 9(>0Q8S@UH]P_Xa`chepgxikmoqstccc c $(,8<@DHLX\`dhlx|  $048<@DHLX\`dptx|hhhhhhhhhhhhhhjjjj(j,j0j4j8j<jHjLjPjTjXj\jhlllpltlllllllllllllnnnnnnnnnnnn (,048<@DHLX\`dhlptx| $(,8<@DPTX\`dptx|  $(,8<@DHLX\`dptx|tttttttttttt  $(,8<@DPTX\hlpt(,048<HLPT`dhlx| (,048<HLPT`dhlx|     $ ( , 0 4 8 < H L P T X \ h l p t x |                             ( , 0 4 @ D H L P T X \ h l p t x |                               ( , 0 4 @ D H L X \ ` d h l x |                             ( , 0 4 @ D H L X \ ` d p t x |                             ( , 0 4 @ D H L X \ ` d p t x |                       (,04@DHLX\`dptx|  $048<@DHLPT`dhlx|  $(,8<@DHLPT`dhlx|  $(,04@DHLX\`dptx|  $(,8<@DHLX\`dhlx|||||||||||||||| ||| |$|(|,|8|<|@|D|P|T|X|\|h|l|p|t|~~~~~~~~~~~~~~~~~~~~~~  $048<HLPT`dhlx| (,04@DHLX\`dhlx|  $048<HLPTX\`dptx|(,04@DHLX\`dptx|  $(,048<@DHLX\`dhlx|  $(,8<@DPTX\hlptx|(,048<HLPTX\hlpt(,04@DHLPTX\hlpt (,048<HLPT`dhlx|  $048<@DPTX\`dptx|  $(,8<@DHLX\`dptx|  $(,8<@DHLX\`dptx|      ( , 0 4 8 < H L P T ` d h l x |                         ! !!! !$!(!,!8!>>>>>(>,>0>4>@>D>H>L>X>\>`>d>p>t>x>|>>>>>>>>>>>>>>>>>>>>>>>? ????? ?$?(?,?0?4?@?D?H?L?P?T?`?d?h?l?p?t???????????????????????@@@ @@@ @$@(@,@0@4@@@D@H@L@P@T@`@d@h@l@x@|@@@@@@@@@@@@@@@@@@@@@@@@@AAA AAA A$A(A,A8A>> >>> >$>(>,>8><>@>D>H>L>P>T>`>d>h>l>p>t>>>>>>>>>>>>>>>>>>>>>>>>>? ????? ?$?0?4?8?K> K>$K>(K>,K>8K>@K>DK>PK>TK>XK>\K>hK>lK>pK>tK>K>K>K>K>K>K>K>K>KQKQKQKQKQKQKQKQKQKQKQKQKQKQLQLQLQLQLQLQ(LQ,LQ0LQ4LQ@LSDLSHLSLLSPLSTLS`LdLhLlLpLtLLLLLLLLLLLLLLLLLLLLLLLLLMMM MMM M$M0M4M8M>QQSSUľUȾ]̾]о_Ծ_ؾaܾacceeggiikkm mooqq s$s(t,tEXj   # 5 G  Y "k $} & ( * , . 0 2 4 6 81 p;=?ADFHJLN&P9RLT_VrXZ\achj<lntvT|~'P`>\q|'a3eNn)`&J 9S\\Q     "V$&Q(*@,s.07 2 4, 6 9 > QSU<]_acegiAkmo7qst  4H h 0D X"l$&(*,.02 4 648H\p;=?0ADXxDFHJLNP$RHTlVXZ\%]Tac<tT4l$   h jd l n  ]<   tL vU ]  ]   ], t   ,@\<tP](d] @|\4x]LU],l] dLU]]@l  4Hl DhDH\|~0DX   !!T!!$"-"]l"""$#8#L#`#t###$,$D$l$$$$%%,%x%& &]L&U&]&&]&&]'%']`'i']'']''((`(((()))]))0***,+,(,h,,,],,]--]H-Q-]--]--H.Q.]..]..]./]4/=/]l/u/]//]/40=0]t0}0]00]0@11 2p222]283334 4]84A4]p4y4]44]44]0595]h555]555]86`666]66]77]H7Q7]77]77]8 8]88A8]|88]88]9 9]L9U9]99]99]:!:]P:Y:]::]::]; ;]H;Q;];;<<]L<U<]<<]<<]==]H=Q=]====]>%>]T>]>]>>]>>]??]@?I?]??]??]@@]H@Q@]@@]@@]AA]XAAA]AA]B!B]`BiB]BB]BB]8CAC]CC]CC]D D]8DAD]xD9D]DD]DD],E5E]tE}E]EE]EE],F5F]dFmF]FF]FF]G%G]dGmG]GG]H%H]dHmH]HH]HH](I1I]lIIIJ]DJMJ]|JJ]JJ]JJ]4K=K]|KK]KK]KL]DLML]LLL]M!M]`MiM]MM]M N8NAN]pNNNN]OLOUO]OOOO]P@PlPuP]PP]P0Q9Q]hQqQ]QQ]QQ],RXRRXSS $TXTTT U)U]hU UV \VeV]VVV]W@WIW]xWW]WW]WW]e]eeQe](fPfSYf]ff]ff]gxggghD i LF yG  H %L .T /X 0\ 1` 2%d "4eh 6l@ S0  Vn yX0 \Te]O  ^C{ ( : e  !''std"  @[  O  f  |        6  R  h  t      &  <  ]  y       4 O o          $ O j      % ; [ { ɛ ʻ    & D c    0>   E e (17eq ] ' J77lt +' g77y }e==S =t ==7  CC= XCC=  C5Cp OI n7) $N' IIeof ( q ,I 0 5O 6| 70 e3n[b  L UP d\ Z gj v S  ZVfIC [ Z  ' !;A"# N""e$1 %tZ&dect%at&hex t%t%t &octt@%t' t' "t' &t')t'G,t'/t '3t@%6t%9tJ'<t(5J%r N o %'Q %V %qY ( in&appl  &ateo %t &inw &outz %}  (;&beg9  &cur9 &end9 RSTO \e3hMiby ) * tr1* +,F- . / 01=. 2_Tp  3>x 4J' e  5ca0j6 O | e6 O  86U   e 3 6O 3  62  e    3 64Ke  e6Re6   76{eR   76,O h  8} O 6 % !% [ 6' m%  !% 6M ie   [ 6%   % !6O & 3  6O < 3 6\e]  % 76(ey   76) O O  6de   6e   6Iqe  % 6e  6 le4 6eO 6r%o3  9   9e  9 e  9   9%  6"W% % !:tm,eewe#e eE eee2e $!(6% 9    %9e  %9P $  %6 %II%  6%j  6yA   6:  6   6 e6E e9i%%  %6e;O 6]Ee[  %6 I {  %6N   %6R  3 %6Ye 76e 7;  3  &  ;h h D 3 @@ c  U <U  3 %<    $,- 71 :. 1s;. 1 ?" 1@. )L e7B1 :1s;1 ?" 1@. )L E71 :'1s;'1 ?" 1@. )L 0071 :w1s;w1 ?" 1@. )L S6H  6l e6 s e<71=8>>((>O85|"95:@ F GTHIJ+K L$$M( N).P*R+$T,qV-].$ ^/ba0zc1:e2 g3n4io59|e!?Oz ^e_0`e fe o0B 9} h~   C1 eDE` 4EZ9< e3O 9<O MO 9Ab!9]w!SE^EF 8G XGP_' Gx`H;"^HB "^IfM"dF J=5" KK$t bt dx7) 2To5qlL 5M2M/3M 4 3Pc<  nNS }2:OdBPRunl e3"BN . dQ3 Rabi!j%e >SeT9 U&eU&eV"eY:W"eW "X9%'YA YJY0HY9FZ`8y[p"&\]^|Y___ _` a:da2b cccd c ee e-CeY$exee e+.fe_!gge% U: ; I$ > $ >   I : ;  : ; I8 : ;I8  : ; n  : ;  : ; I I!I/  I: ; &I9: ; : ; : ;9: ; .?: ; n<I.?: ; nI<.?: ;nI<.?: ;nI<.?: ;nI< : ; ( < : ;2  : ;I?<!.?: ;2 <d"I4#.?: ;2 <d$: ; I2 % : ;I?2 < & : ;I?2 < ' : ;I?2 <(: ;I2 )/I*/I+ : ; , : ;-9.4: ;I</:: ;0 : ; 1 : ; I?<2/I34: ; nI?<44: ; I<5: ;I6.?: ;I<78.?: ;I<9.?: ; I<: : ; ;.?: ; nI<<9: ; =:: ; > I?.?: ; I<@ : ; nA : ; B I8 CD&E9: ;F : ;G : ;I8 2 H.?: ;n2 <dI.?: ;n2 <dJ : ;I?2 <K.?: ;nI<L4: ;I<M4: ; I<N4: ; I< O.?: ;nI2 <P.?: ;nI2 <dQ.?: ;n<R: ;S.?: ;I T.4 U: ; IV.?: ; I@BW: ; IX1X Y Y1Z.4@B[1X Y \1 ]1^_4: ; I?<`4I?4<a4G b4Gc4Gd4Ge4Gnf.?nI4<g.?I4<$Y`8Y`S src./include/gtest/usr/include/c++/4.9.2/usr/lib/gcc/i686-redhat-linux/4.9.2/include/usr/include/bits/usr/include/usr/include/c++/4.9.2/bits/usr/include/c++/4.9.2/i686-redhat-linux/bits/usr/include/c++/4.9.2/tr1/usr/include/c++/4.9.2/debug/usr/include/c++/4.9.2/ext./include/gtest/internalgtest_main.ccgtest.hiostreamstddef.htypes.hlibio.hstdio.hwchar.hstdarg.hcwcharchar_traits.hc++config.hclocaleios_base.hcwctypetuple iosfwdtime.hdebug.h predefined_ops.hnew_allocator.h numeric_traits.h locale.hpthreadtypes.hatomic_word.hwctype.hgtest-port.h gtest-internal.h gtest-death-test-internal.h gtest-linked_ptr.h gtest-printers.hcxxabi.h!=n<.$\"long int__debug_GLOBAL__sub_I_gtest_main.cc_ZN7testing8internal21ImplicitlyConvertibleIPKvS3_E5valueEwcsxfrmgoodbit_shortbufvfwprintf_IO_lock_tUnitTeststderrGetInstanceRUN_ALL_TESTStm_ydayLock_ZNSt11char_traitsIcE11to_int_typeERKc_S_atepthread_tchar_type_S_uppercasevfwscanfeofbitp_cs_precedestowctrans_Swallow_assignunsigned int_ZN7testing8internal18g_linked_ptr_mutexE__gnu_cxx_S_fixed_S_floatfieldtuple_size >_flags__int32_t_cur_columnwchar_t_S_refcounttestingvwscanf_old_offset_markerstm_mday_ZNSt11char_traitsIcE2ltERKcS2_MakeFrommon_decimal_point_S_ios_iostate_end_IO_buf_end_ZN9__gnu_cxx24__numeric_traits_integerIiE5__minE__opswcscpy_ZN7testing8UnitTest11GetInstanceEvBiggestInt_ZNSt11char_traitsIcE7not_eofERKiwcscatlconvdecimal_point__numeric_traits_integer__pthread_slist_tAssertHeldn_sep_by_spaceg_linked_ptr_mutexcopy__gnu_debugfwscanftm_wday_poswcsncmpp_sep_by_spacetm_mon_IO_save_end__count__numeric_traits_integerinternal2floatignore__elisiongetwclong long unsigned int_S_endhas_owner__S_dec_S_hexint_n_sign_posn_IO_read_base_S_scientificunitbuflocaleconv__FILE__owneradjustfield_offsetto_int_type_ZNK7testing8internal9MutexBase10AssertHeldEvwcrtomb_ZN7testing8internal9MutexBase6UnlockEviostatevalue_S_ios_seekdir_end_S_failbitfixed__cxa_atexitHelper__gnuc_va_listp_sign_posn__initialize_pputsuppercasetuple<>Initsize_tmovefloatfieldshowposputwccerrputwchar_Ios_Seekdir__priority__lockargcstdin_nextint_frac_digitsfwideint_n_cs_precedes_S_right_S_showpointint_p_cs_precedesfindbasic_ostream >negative_sign__elision_data_ZN7testing14InitGoogleTestEPiPPc__valuefputwc__nextgroupingwscanf_S_showbase_S_inchar_modeswscanfptrdiff_t_IO_markerint_type_IO_write_basewctype_S_adjustfield__max__wch_S_boolalpha__builtin_putsmbsrtowcs_S_begwcstoulwctrans_tfwprintfrightpthread_mutex_twcstofwcsspn_ZN9__gnu_cxx24__numeric_traits_integerIsE5__maxE_S_ios_openmode_end_Atomic_word__listlong long intlength_S_eofbit_ZN7testing8internal21ImplicitlyConvertibleIPKvS3_E6HelperEz_IO_save_base_S_oct_S_badbitmon_groupingUnlock_ZNSt11char_traitsIcE6assignERcRKcboolboolalphashowbasefgetwc_ZN7testing8internal21ImplicitlyConvertibleIPKvS3_E6HelperES3_fgetws_S_basefield__quad_tbadbitcomparestdout_IO_backup_base_S_goodbit__dso_handle_ZNSt11char_traitsIcE6assignEPcjc__kindassign__pad1__pad2__pad3__pad4__pad5kInternalRunDeathTestFlag__is_signedungetwcfmtflagssrc/gtest_main.cc_Value_Ios_Iostatewctype_t_vtable_offset_ZSt4cerr_ZN9__gnu_cxx24__numeric_traits_integerIiE5__maxE__mbstate_t_Traitsargvlong doublewcsncatopenmodewcscoll__espins_S_synced_with_stdio_ZNSt11char_traitsIcE4moveEPcPKcjfputws__static_initialization_and_destruction_0GNU C++ 4.9.2 20150212 (Red Hat 4.9.2-6) -mtune=generic -march=i686 -g -O2 -fPIC/home/user/projects/ascgit/ascgit003.dlt-daemon/build/gtest-1.7.0ios_basebtowcvwprintfFromkMaxStackTraceDepthmbrtowc_IO_read_endiswctypetm_yearmbsinitwmemchr_ZNSt11char_traitsIcE2eqERKcS2_short int_ZN7testing8UnitTest3RunEvmutex__ZNSt11char_traitsIcE3eofEv_CharTwcsrtombsint_curr_symbolkMaxBiggestIntwcstoullfrac_digitsmbrlenwmemcpyscientificn_sign_posn11__mbstate_tchar_traits_S_skipws_Ios_Openmodewcsrchrto_char_typegetwchar__cxxabiv1_IO_write_end_S_internal__wchbint_n_sep_by_space__numeric_traits_integerinternal_run_death_testshowpointbinary_S_binleftmbstate_twcsftimepositive_sign__datawcsstrskipws_ZNSt11char_traitsIcE11eq_int_typeERKiS2_owner__lock_S_left_ZNSt11char_traitsIcE12to_char_typeERKiwmemmove_Ios_Fmtflags__nuserswprintfdeath_test_use_forksizetypelong unsigned int~Init_S_trunc_IO_FILE_ZN7testing8internal21ImplicitlyConvertibleIPKvS3_E8MakeFromEvwint_t_S_appnot_eofwcstodwcspbrktm_minfailbitwcstokwcstoltm_zonewmemset_S_ios_fmtflags_endsetlocale_ZNSt11char_traitsIcE6lengthEPKcunsigned char_sbufMutexBaseinternal_IO_write_ptreq_int_typethousands_sep_ZN9__gnu_cxx24__numeric_traits_integerImE8__digitsE_ZN9__gnu_cxx24__numeric_traits_integerIsE5__minEostreamwcstoldwctob_ZNSt11char_traitsIcE4findEPKcjRS1_death_test_stylecurrency_symbolwcstoll__minswprintf_fileno_ZN9__gnu_cxx24__numeric_traits_integerIcE5__maxE15pthread_mutex_t__size__off_ttm_hourtrunckDeathTestStyleFlagsigned charmon_thousands_sepInitGoogleTestbasefieldshort unsigned int__digitstm_sec_S_unitbufmainwcscspn__builtin_va_list_S_curn_cs_precedestm_isdstseekdir_IO_read_ptrwcsncpy_ZNSt11char_traitsIcE4copyEPcPKcjint_p_sep_by_spacedoublevswscanfwcscmp_ZN7testing8internal9MutexBase4LockEvtm_gmtoff__pthread_internal_slist__align_chainwcschr__numeric_traits_integerkDeathTestUseForkwctransvswprintfkProtobufOneLinerMaxLength_flags2_S_out_ZNSt11char_traitsIcE7compareEPKcS2_jint_p_sign_posn_S_showposImplicitlyConvertiblewcslen__off64_t__ioinit_unused2_IO_buf_base_ZNSt3tr110tuple_sizeINS_5tupleIIEEEE5valueE__pthread_mutex_swmemcmpGCC: (GNU) 4.9.2 20150212 (Red Hat 4.9.2-6)zR| @YD GuFupu|uxut@ AAAAC 4``8AA NG NAAF H AA.symtab.strtab.shstrtab.text.data.bss.rodata.str1.4.text.unlikely.rel.text.startup.rel.init_array.text.__x86.get_pc_thunk.bx.rel.debug_info.debug_abbrev.rel.debug_aranges.rel.debug_ranges.rel.debug_line.debug_str.comment.note.GNU-stack.rel.eh_frame.group 4<!<'<,2<";^N`J Cp`\ PD ly XD  y/"( XQW" pQ o"W Q0%e0+:-X:X: Q;@  B!`8,   ;@YE [qvgtest_main.cc_GLOBAL__sub_I_gtest_main.cc_ZStL8__ioinit.LC0main__x86.get_pc_thunk.bx_GLOBAL_OFFSET_TABLE_puts_ZN7testing14InitGoogleTestEPiPPc_ZN7testing8UnitTest11GetInstanceEv_ZN7testing8UnitTest3RunEv_ZNSt8ios_base4InitC1Ev__dso_handle_ZNSt8ios_base4InitD1Ev__cxa_atexit & ,5=Fci r x~  ! !&3:AHOV[ov{ '4AN[hu+9GXco{3Pho6=U\ov %,3:AIQX_fo{+B[g  ' 6 E S a p }                    * 6 = D K P \ g }      7 S i u     ' = ^ z     5Pp-9EQ]iu%Pk&<\|'-ELdk #.9COZep{P\ht(4@LXdp})5AMYex4Nc} ,9@IPcjy&;GNk(1;?Rjoz#,5>IM`  , d dlt-daemon-2.18.4/gtest-1.7.0/src/gtest-all.cc000066400000000000000000000041611353342203500204150ustar00rootroot00000000000000// Copyright 2008, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: mheule@google.com (Markus Heule) // // Google C++ Testing Framework (Google Test) // // Sometimes it's desirable to build Google Test by compiling a single file. // This file serves this purpose. // This line ensures that gtest.h can be compiled on its own, even // when it's fused. #include "gtest/gtest.h" // The following lines pull in the real gtest *.cc files. #include "src/gtest.cc" #include "src/gtest-death-test.cc" #include "src/gtest-filepath.cc" #include "src/gtest-port.cc" #include "src/gtest-printers.cc" #include "src/gtest-test-part.cc" #include "src/gtest-typed-test.cc" dlt-daemon-2.18.4/gtest-1.7.0/src/gtest-all.lo000066400000000000000000000004611353342203500204410ustar00rootroot00000000000000# src/gtest-all.lo - a libtool object file # Generated by libtool (GNU libtool) 2.4.2 Debian-2.4.2-1ubuntu1 # # Please DO NOT delete this file! # It is necessary for linking the library. # Name of the PIC object. pic_object='.libs/gtest-all.o' # Name of the non-PIC object non_pic_object='gtest-all.o' dlt-daemon-2.18.4/gtest-1.7.0/src/gtest-all.o000066400000000000000000120476641353342203500203100ustar00rootroot00000000000000ELFu4(&')*     89#$,-56 /0!"23>?ABDEGHJKMNPQTUWXZ[]^`ahicdklnoqrtuwxz{}~    !#$&')*,-/0235689;<>?ABDEGHJKMNPQSTVWYZ\]_`bcefhiklnoqrtuwxz{Í&'Í&'SD$P X19t& yty9u[SD$P X19t& y9u[ÍSD$P X19t& y9u[ÍSD$P X19t& y9u[ÍT$B+B fÍ&'T$D$:u@@T$D$AUWVS }w _9t t&t  PR9uwtue[^_]e[^_]ËWÅt R Sv'S\$S\$ [t&S\$$D$PhS([&'WVS|$t$t9WG )t*1ۍVPRWG )9r[^_fWVS|$t$t9WG )t*1ۍVPRWG )9r[^_fWVS|$t$t9WG )t*1ۍVPRWG )9r[^_fWVS|$t$t9WG )t*1ۍVPRWG )9r[^_fWVS|$t$t9WG )t*1ۍVPR WG )9r[^_fWVS|$t$t9WG )t*1ۍVPR,WG )9r[^_fWVSt$|$~t:F^ )x* v'FWPRu[^_ÐWVSt$|$~t:F^ )x* v'FWPR0u[^_ÐWVSt$|$~t:F^ )x* v'FWPR$u[^_ÐWVSt$|$~t:F^ )x* v'FWPR(u[^_ÐWVSt$|$~t:F^ )x* v'FWPR8u[^_ÐUWVS l$ \$$t$(}t:UE )t+1VSPR UE )9r݃ [^_]Ðt&UWVS t$ |$$l$(~t3F^ )x#fFUWPR4u [^_]ÍVSƃXl;Xpt  RQ;^puFx[^UWVSÃK)tR߉Ӊփ1\$ 1ې&T$ tD0 QЋOË)9rу[^_]1vVSÃtX1u-Mv' Rt*/ uڃ huփ[^Í& h[^Ív'StH~[ËHYɉXRP[ÐUWVS1,E v'Vj W j hutX)@9ERVWPXEZPuE =u 떍U&넍t&@9wy]jVWSY^SuE =u Eԍe[^_]ÍUEԍe[^_]PVhhËEԋ =tU SPVhhËE =tUv붉ËE =tU]띍t&'UWVS1׃,ɉL$t$@\$D$D$D$ D$ (Ph+jS$ PSV;l$tKD=tèuD$ jD$!PV륐t&D$-jD$"PV농,[^_]VSƉӃt+ R PSPR[^Í&jh0P[^Ð&UVSjËE ECECEPC uPEe[^]à S4$&S\$ tB =u R[Ít&T$ސfUVSutKj:St!U)RPSVe[^]t&EPSVݐ&EPhV P&'VSD$ t$$XCK<*t7~<:t\hlVu)h|VuhVv![^Ð&=WVS\$t$t|tQD$tID$Ph VS5$[^_ÐVS5[^_É' hl 5$$Ǣ$0t&1G&hj$D$ t&hj$D$ t&S\$hj s3h$ D$ [WVST$ BR 11ۅtÉ߉Éuu [^_ÍvL$ hL$tcVh ht hSh h[^_fR 11jzt&ukUW1VSD$0@$D$ T/GD$0P$JTBX)ȃ/D$ 5t&D$ x6{,u[Ðt&Sh5u뱉'UWVS,E] EԋEuEڃPh VY_VuV jh7VX}ZVW$ PSWE =u{E =u~]܃1CPSuEtC=uee[^_]ÍvUU}ttԃ<=Dōt&e1[^_]Ít&Uxv vt&뒉ËE܃ =tUE =tUE =tU SËE =tӍUɉ밉jt$t$t'Ѓv'UEoEhP_XEhPEă pPEPEă =&U@o'M (jQjRP Ejh0Pt&UnvUEoE܃ [PރF<~&E܃hP_XEVPtE܃hPẼuPE܃ t  PREhPEY[hPẼ pPEPE jhrPE j hPEЃ pPEPẼ =u2EЃ =2E܃hPUnmĉËẼ =tUUmEЃ =u@Ut RQE =tU m SËE؃ =tUm붉륉ËE܅t PR뎉ËEă =tʃ SuËE =b렉YeËE =?zËEȃ ='bv'UWVS$]jSuSCC C$C(C,C0C4C8C<C@e[^_]Ð&}huhDjW j!hh jhhXZVh<$S W$fUWVSut e[^_]f j(Í@Y_jPu CC$؉e[^_]Ðt&EhuhDjP j!hh jhhXZWhE$놉ƃ S4$ƍE Pܐ&UWVS8]s VEu1Ce[^_]Ít&Eh0P뚍v'Yae[^_]ÉËE =tU8a SËEtك PRː&UVSE]U uWEPuSXZSVE =uE =u)e[^]Ít&U`E =tڍv`e[^]ÉËE =tUm` SËE =tӍUM`ɐv'USU u]ÍvE uX5E =u 5]ÍvU_݉ËE =tU_ SUVSE]PE j$hP{ S PESPEjhPE j?hPE jh4P1 S PESPEj hPE j>hTPE j=hPE j=hPE jChPE j hPYE[uPX]uZuu S Vuh5E =uwE =uZEt PRe[^]ËEh0P&Eh0P&]띍&U]|ËE =tU]E =tUw]Et PR Sˉ܍vUWVSu}܃ U ]VDRWExoEPV<$}W jhW VWSE =u[E =u^E܃ =u+e[^_]t&WSE܃ =tՉ\e[^_]vUx\뛍i\뙉ËE܃ =tUP\ SËE =tU0\E =tU\ЉvUWVSu$E]} 0VE @u&WSE =uTe[^_]W}W jhrW VWSE =tU[륍Up[e[^_]ËE =tUM[ SËE =tӍU-['U:*WVSM}ԃ0}uQEPWE؉$^+ĩ8E؃hNPEԃ pPE؃PXEZhrPEY_hYPXEZSP_XEhdPF+1ۃ~P&SVNjE؃ jhrPXEZWPF+i9|E؃EEPEPY[PuXEZjPE؅t  PREԃ =Ee[^_]jVÃ9EtXEEhNEPZYWPY^hrP_ZhnPY^SP_ZPuPE 0st'E@7UXEe[^_]EEhNEPY^WPu܉lj4$E܃ j hyPXZVWE܃t  PRu W^_hPZYhnP^_SPY[PulËE܅t PREjPE؅t PREԃ =tUW S뿍&'UWVSÃe[^_]ÍUO>‰ËE 8PE@t PE@ t PEjPE@ =tU= S뛍t&S\$S\$ [t&UWVS,uFX~T9Eu%O& S$9}t,t@=t҃ SЃ9}u݉'~L^H9uDt& P9t-tRtڃ P҃9uݍv't  PR Pt  PRt/C x P = St$@=N S$ P^lFp9t$&t  PR;^puFlt PF`t PFTt PFHt P v@t  PR v@u(F PF =uqe[^_]Ít&}hhDjW jhYh jhhXZSh<$끃 SЃU:e[^_]ÍU:aËF =tU: SÍFl PF`t PFTt PFHt PF@ PF PuÍ P|ϋVlÅz RiÍjPt PR뙉Ëtȃ PR뺉Nj =tU9봃 W<Í P륐fS\$S\$ [t&UVS]s$t$@= V4$ Sue[^]Ð&uhyhDjV jhlh jhhXZSh4$e[^]Ít& VЃn V$ S4$&S\$S\$ [t&UWVSu0]}CVu P0 j EVWP{EC CCCCC$EC C,C0C4C(C8jPuQCPCXC\C`CdChClCpCtCxe[^_]ÍhuhDjV j!hh jhhZYWh4$X'CƋCt PC t PPPCjPC =tU6 V V뚃 uԉ뾉뺍UWVS4]u }uSXCZuP< jEԍE PWQ{ jǍE PVW{ ECCCCE CCjPuPC4C<C@CDCHCLCPCTCXC\e[^_]Ðt&}huhDjW j!hh jhhYXVh<$VC t&CƍC RRjPPPCjPC =tU4 =tU4 V W랉σ W뚉떃 uԉ딉fS\$ C;Ct@t T$$CCC+S;C T$ t9tC[Ð&T$(RPC P뼉'T$RPS뼐&HuÍvUWVS0jj:h uPjhV@9UEjShP$$XCZCVP^XEPC P$_E׍] PhSZYSwE =E}H ;Ht9H H E܃ =u^E؃ =u1e[^_]Ð5h X5Ӎt&Q2ƍ&U@2qv12뙍&URQPlPShhËE؃ =tU1 SËE =tU1Gt PR WE܃ =tU1땉ƃ SˉƋC =tUh1׉뺉몉ƋC =tҍUG1ȉw&' T$B ;Bt!t L$B B Ív'L$QPRې&D$ L$$L$ B ;BttB B Ít&L$QPRᐐ&VSt$ \$$F9tAPVt PRۉ^t\$ B ;BttB B [^Ðt&L$QPRސ&UWVS}@]E CCWhPC C [C[CC ZYjPECC8hEčEPEԃCHCLCPCTCXC@EC\C`CdChCDClCpCtCxC|ǃǃjPE ƃǃǃǃǃǃǃǃǃǃVǃƃǃǃǃǃǃǃǃ$YZEhPEE ǃǃǃ ƃjZYPVe[^_]Ð&EhuhDjP j!hh jhhYXVhEЉ$vhhDjW j1h8 h jhhXZuh<$&EhuhDjP j!hh jhhYXVhE܉$vEhhDjP j1h8 h jhhXZVhE؉$ƋC =tU+ VƍEЃ PωƋt PRPPjPt PR uCl PC`t PCTt PCHt PC@ P u W6|ƍE܃ Pf빉ƍE؃ P릉ƍ P&UWVS$]{jWu* ChXZSVs$e[^_]ÍEhuhDjP j!hh jhhYXVhE$yÍE P$ V W$v'=tÐUShu]Í h$ hhh]à h$t&UWVSLj:PxuE܃]PWVXZVS$E =EĀ8/EPW}WYXEWPljE<$M܃}Q@$pWXEZWPẺ$}؍Ẽ uPW<$SE؃ =]Ẽ = Eȃ = Eԃ = EЃ = EċPu/SuEă =oEe[^_]f|/uʃ VE}PEE܃ WuSPE =E =E܃PuE܃ =h1'\t&E̍]܃Ph} S^E_SPƉE4$UȃR@$pEPY}[VW<$u uWV4$uE =E؃ =Eԃ =E =E܃ =vI&t&U8&kvEPhuUt& &t&%t&%t&%t&%t&U%XvU%7vU%v%t&y%t&i%ËEԃ =tUM%E =tU8%E܃ =tU#% SɉËE =tύU$ʼnËE =tU$E؃ =oU$bËE؃ =t$Ẽ =t$Eȃ =t$Eԃ =tr$EЃ =u5Eă =1UL$$щ둉ËE܃ =tˉ)$ËEă =tU$E =U#뇉ډËE؃ =lU#_ËE =tU#E =4U#'މ& @$JE PÐt& @$JE PÐt&S\$L$QRp$S[S@$t>h p YXSjIXZSD$0$$PP5D$0Z5&UWVSL]'8jVst܅uC v8u& stCe[^_]Ít&DžPVXZPh* S hSWXZh WPY[VPSXZhSV_Xh VWY[h# WVVt& P hhjWY^h h rRP<$ = uljÍEЃuPEt PR SËẼ =tÍU볉ËEȃ =tU뜃uu W] Suh5Ẽ =tU 5ËẼ =tUhvvUWVS1@j@VEjPSV PhWF=umCs<@t2 CRfz둉먉뿉j~, P UWVSӃ4Eh Rh Sh SZuhhjV_Xh hZYh P rRP4$Eԃ@@Eԍe[^_]Ív}ԃ GGjÉEЃ G}䍴&tW6S uߋEԉXEԍe[^_]Í}ԃ GGj ÉEЃ  G}䍴&tW6S@ uߋEԉX농&}ԃ GGjÉEЃ G}䍴&tW6S uߋEԉXËEԋt P S V$˃ P^_Su뭉릃 PXYSu PXYSubV&UWVSE܃ APEԃ0EuԃPEjhPE jhV PEVPEjh\ PE jhV PZESPEj&hPE j=hPE jhz Pu$7 hhjVWV4$Et PR1ۍe[^_]Ðt&]W&} WEYMXhAPMXZAh4PMЃEuЃPEhPXEZh PEԃEuԃPEh P=EVPEhrPEY^h4PXEZhtPEY^hPXEZhPu$7 hhjVWV4$Eo PRe[^_]Ð&e[^_]ÐEh0P&Eh0P3&Eh0P&Eh0P&Eh0P&Eh0PH VEt PR SËEt PR VۉfUWVSH] uS$x <$Sh WPljEFjWPFtN; EÃjPF(PEFEt& ue[^_]Ðt&EEu܃ VE܃ jh P$ PESPE܃ j3h0PEԍU$h h RP]؃uhhjSVS$Eԃ =uAE܅t  PR] =u' S9붍&)ЉËE܅t PRPPEjP$ SEԃ =tUԍ뭉却&'USE]PhSSu jjuPE =u ]ÍUh]ÉËE =tUL SfSu [ÍX$ SR h jj t$t5 SR u\h jj t$[f SR u7h jjt$뛃 P҃of P҃뙐t& P҃뾐t&UWMbVSÃ,p$@$SWPXZjD$$P4$ȋL$,l$(D$ȉT$)ʉЙщT$L$T$L$R hdjj st  VR 1Ҹh RPUXZjD$$PȋL$,l$(D$T$ȺMb)ʉЙD$T$+D$T$Y]CXSWS\P$dž,[^_]Ív UN& P҃v' P҃>fD$xuÍt&Kv'UWVSÃ<@$D$ @$SWP4$R _1Ҹh RPS^]jD$4PkȋL$t Ve[^]Í& hV t8th PPjjh:$^t>t V Sv'UWVS8]sVEuaC C$ CPPJHB = CVuqe[^_]É'}h<hDjW jhh jhhYXuh<$Ct&}hHhDjW jhh jhhXZSh<$e[^_]ÍvU؀ W$ V$ W$v' D$ UWVS8]u {WEC C$ CPEԃ@;A!t$PVPVPEԃ@Uԃ B CWure[^_]Ív'Eh<hDjPE jhh jhhXZuhYuEhHhDjPljE jhh jhhXZSh<$e[^_]ÍVPu uԉ$ W$ uԉ$US],E E EEEE0SE$PE =u,URPE =u]Ðt&U(~ʍ~]ÉËE =tU} SËE =tӍU}ɐv'UWVSE} @JE^$;^(trtDGPCPGCYXG PC PXGZPCPE^$@^$WPR e[^_]É' WSVE@ÉƋC =tU} VƋC =tӍU|ɍ&'UWVS}u _$;_(tYt>FPCPFCYXF PC PXCZVP_$_$e[^_]É'G VSP܉ƋC =tU6| VƋC =tӍU|ɍt&UWVS}u _;_tYt>FPCPFCYXF PC PXCZVP__e[^_]É'VSW߉ƋC =tUy{ VƋC =tӍUY{ɐUWVSEu x _;_tVt>FPCPFCYXF PC PXCZVP__e[^_]ÍVSWƋC =tUz VƋC =tӍUzɐUWVSDuu ]ue[^_]Ív' SRCE˃CuPE0VXZVuVC0Y_EC,VuVEXEZVP_uXEPVE} =VWE$WuuPEuă =^E܃ =]E؃ =\EЃ =[Ẽ =ZC09EEPEpEPXEԃZPVEԃ =# Se[^_]Í&}h<hDjW jhh jhhYXVh<$T;s4t*uVEY^PEPC0EEC0@vIxqt&U8xv)xt&xt& xt&wt&wC,uVPƋE =tUwE؃ =tUwEЃ =tUwẼ =tUvw S4$ƋE =tމMwՃ W$뾉륉댉pƋE܃ =]U wPƋE =tӍUvɉƋEԃ =c냐UVS]E tDujh Vu VSE =u8e[^]Ðt6uj h V8밐t&U8ve[^]Ðuh VÈ|ËE =tUu SUVS]u SYE^uPXEZSp$E =uE =u#e[^]Ít&UuE =tvUxue[^]ÉËE =tUZu S S4$&' t$t$PÐfUSE PXEZu PYE[uPX]EZPuSSuPE =u*E =u5Et PR]Ðt&UxtE =t΍vat‰ËEt PR SËE =tU*tE =tUt붉D$D$tBD$tB1D$@$D$@(1UWVS}Ӊƃ8MWۋEtSQQh|Pډ RRhPPPEhXSUԃ SShPQQhPRXZuVE t, PRËUt RP Se[^_]Ð,Xq''Aq$Wo 0DR 0Qwm +@N6Y 5unl B Bh i5AQ]p\em-6>e&.7Q5A[c&'QxYMVo*%;|?\,BE.wIWmN"N"8,vA6*'2iv+9O)B,o(h          ''-K-S a*1+E`$82% +@o+1@n$Zt %8R,Vp/q%\t6P> %Wr %WrI9b+D9FRgFRg9FRg"!PAi+;DW"0#%TEml8F w5$Jr?W -G"'0=MV^b`?L Y f x           I-<HzOY."@L\jsAy)=?l,3%9U(2.T}p0D&|m8L&u@T&}#&!V;)EYj/,5 Nu .     a  .   " . [  E  p   w  6A 6<+(T!;3':H':H"?Ju:#8DXdt!/&@T&}Pd&%x&#`t(&&#`t(&&#h|(&&#h|(&&$K-&)&&0-=i!;FNTju$- &jP:&%%#"9EU`/.hs5#)%[gw5 &%Xdt<)2&eq(&5[q4c!'Vx4c! Oq4c!>&1_<@5d!"xN0Y&fN0Y2dD:F:tI-N4c!4c!Zp -   -  -  4c!FRmM"O7 )!O~ B]   >I  ] >  I  6d& .]&$bFP-m!>[!F[%*KS,&$,p&% 5E&4$9Nfv&H"'htc%   &(  &   &  "2=`t& @u>G O        8      7w           :  @   (     8C09'c/7EWhx/7EWhx0CQct0CQct *=B]&k                           $        Q IYj{y$K# 6AR(5Y%CW_*':F[+Vb}8+:Fa8+:Fa8+:Fa8+:Fa8. ;JVz2'3Lv[H6%1D?(i (eI\`E8~10A~0F2JCW_*g&n&v&&5&,(f&%$E (%(%+ *****)))////////(((&! $ # J# / #4444))#3222#22214443#6666666$#66666664##1 1 1 1 1 1 0 #!#!#!#!#!#!#!""#$6*+/+/+/+/+/,/,-,,/,/,/-/-/-/-/YNWw!%HWFU.Vg   '  ,( d v                 N &S           B"17QA7' s}JW1<Y 2pY$8E X$@N"90,!O(FCG1I(=fs-3|&/9 g 8  E E '%OR ]xU>+hI}}U>+hI}}U>+hI}}6 B N U>+hI}} 5I/7(&&E88-*}5>8('&#/D!3sHyWu}]R/DStx8}AVeP*?Ny**?Nv*-BQv*)T8V}YL'6R^<#}dbn,& *+ <D...\n[ DEATH ] basic_string::substr%02X(null)\0autoTERMxtermxterm-colorxterm-256colorscreenscreen-256colorlinuxcygwinyestruet1[0;3%sm[----------] [ RUN ] %s.%s, where %s = %s and [ FAILED ] ]]>]]>Non-fatal failureSuccessFatal failure:: : Value of: Actual: Expected: ()" thrown in Unknown C++ exceptionWARNING: has value "". %s has value , which overflows. The value of flag --0Environment variable = , but have left unset. < , but you have =, . <>&'"&#x; (ignoring case) Which is: (Invalid Unicode 0x\'\\\a\b\f\r\t\v\x'\"" (no terminating NUL)NULL pointing to L"%testtests%s from %s, where %s = %s Google TestNote: %s filter = %s [==========] test casetest casesRunning %s from %s. [ OK ] (%s ms) %s from %s (%s ms total) TESTTESTS%s from %s ran. (%s ms total)[ PASSED ] %s. %2d FAILED %s YOU HAVE %d DISABLED %s %s, listed below: T_[WARNING][ INFO ][ FATAL ][ ERROR ]./src/gtest-port.ccOnly one stdoutstderr./src/gtest.cc./src/gtest-internal-inl.hfailed with error pthread_mutex_unlock(&mutex_)pthread_mutex_lock(&mutex_)Condition range > 0 failed. ) was requested, ).Death test: Result: failed to die. Error msg: Expected: Actual msg: Exited with exit status Terminated by signal (core dumped) ./src/gtest-death-test.ccevent=TestStart&name=event=TestCaseStart&name=event=TestProgramEnd&passed=event=TestPartResult&file=&line=&message=event=TestProgramStartFailure Unknown result type, you tried test cases.%s %sevent=TestEnd&passed=&elapsed_time=msevent=TestCaseEnd&passed=1 fatal failure1 non-fatal failureExpected: Actual: failures Actual: containing "" not a substring of Which is: The difference between is , which exceeds , where evaluates to , , and Expected: () != (), actual: vs ), actual: "" vs ") (ignoring case), actual: ") <= () pthread_key_delete(key_)Invalid shuffle range start : must be in range [0, ].Invalid shuffle range finish : must be in range [, 0xL' []unexpected status byte (, line posix::Close(read_fd()) != -1CHECK failed: File read_fd_ == -1pipe(pipe_fd) != -1child_pid != -1close(pipe_fd[0])close(pipe_fd[1])Death test count (fastUnknown death test style "" encounteredclose(args->close_fd)chdir("") failed: execve(, ...) in failed: xml) < () >= () > ( is listed more than once. No test named You forgot to list test Test @-h-?/?--help|stack != MAP_FAILEDtestsuitestestsuitetestcaseCondition false failed. Attribute is not allowed for element <>.="runnotrun > <failuresdisablederrors this->size() (which is %zu)vector::_M_range_check: __n (which is %zu) >= this->size() (which is %zu)Global test environment set-up.Global test environment tear-downXML output file may not be null Could not write to the test shard status file "%s" specified by the %s environment variable. Invalid index (%d) into TestPartResultArray. C++ exception with description " is expected to be a 32-bit integer, but actuallyThe value of environment variable The default value %s is used. Invalid environment variables: you have Invalid environment variables: we require 0 <= Repeating all tests (iteration %d) . . . Note: This is test shard %d of %s. Note: Randomizing tests' orders with a seed of %d . capturer can exist at a time.Condition sockfd_ == -1 failed. MakeConnection() can't be called when there is already a connection.stream_result_to: getaddrinfo() failed: stream_result_to: failed to connect to Condition sockfd_ != -1 failed. CloseConnection() can be called only when there is a connection../include/gtest/internal/gtest-port.hpthread_mutex_destroy(&mutex_)Send() can be called only when there is a connection.stream_result_to: failed to stream to Cannot generate a number in the range [0, 0).Condition range <= kMaxRange failed. Generation of a number in [0, but this can only generate numbers in [0, Result: threw an exception. Result: illegal return in test statement. Result: died but not with expected error. Result: died but not with expected exit code: DeathTest::Passed somehow called before conclusion of testevent=TestIterationStart&iteration=pthread_mutex_init(&mutex_, NULL)Attempted redefinition of test case All tests in the same test case must use the same test fixture class. However, in test case to define a test using a fixture class different from the one used earlier. This can happen if the two fixture classes are from different namespaces and have the same name. You should probably rename one of the classes to put the tests into different event=TestIterationEnd&passed=Condition 0 <= begin && begin <= size failed. Condition begin <= end && end <= size failed. gtest_streaming_protocol_version=1.0WARNING: unrecognized streaming target "%s" ignored. pthread_key_create(&key, &DeleteThreadLocalValue)Error while reading death test internal: Death test child process reported Read from death test child process failed: posix::Write(write_fd(), &status_ch, 1)waitpid(child_pid_, &status_value, 0)Cannot run a death test outside of a TEST or TEST_F constructDeath tests use fork(), which is unsafe particularly in a threaded context. For this test, couldn't detect the number of threads.) somehow exceeded expected maximum (WARNING: unrecognized output format "%s" ignored. Condition typeid(*base) == typeid(Derived) failed. Condition !original_working_dir_.IsEmpty() failed. Failed to get the current working directory.basic_string::_S_construct null not valid can be found in this test case. pthread_setspecific(key_, holder_base)fcntl(pipe_fd[1], F_SETFD, 0) != -1sigaction( SIGPROF, &ignore_sigprof_action, &saved_sigprof_action)stack_size > kMaxStackAlignment && reinterpret_cast(stack_top) % kMaxStackAlignment == 0munmap(stack, stack_size) != -1sigaction(SIGPROF, &saved_sigprof_action, NULL)Unrecognized xml_element provided: Condition std::find(allowed_names.begin(), allowed_names.end(), name) != allowed_names.end() failed. Bad --gtest_internal_run_death_test flag: Reserved key used in RecordProperty(): class, so mixing TEST_F and TEST in the same test case is is defined using TEST. You probably want to change the TEST to TEST_F or move it to another test using two different test fixture classes. This can happen if the two classes are from different namespaces or translation units and have the same name. You should probably rename one of the classes to put the tests into different test cases." is not a valid POSIX Extended regular expression.the test fixture's constructor This test program did NOT call ::testing::InitGoogleTest before calling RUN_ALL_TESTS(). Please fix it.Condition 1 <= seed && seed <= kMaxRandomSeed failed. auxiliary test code (environments or event listeners)... Google Test internal frames ...UVSuF9t#&t  PR9^utEe[^]v'e[^]ÉËt R SUWVS,]Ct]uE 0VuV PVsE =ue[^_]ÍU\e[^_]Ð& j{E 9tutu =u WEԉC\\ËE =tU\ SS\$ C =u#C =u.C =uA[Ít&T$\C =tfT$\C =tɍv'T$\[S\$ C =u =u'[Ív'T$\ =t܍vT$\[S\$ C$ =u S([ÍT$\UWVS8}hÍ@4$E5ƃ C4ǃƃFǃǃǃǃ3 CYNXjQXZC@DjPs @C( C44C C CCCCC C$$C C,C0 YXVuXZU E2PXEZpPPE =ue[^_]ÍU\e[^_]É8dEV= Ɖ< C4u$4$E =tU\t PR S VY^hSX^^^^8^^^^^^^^^^^^^^^^^^^^^^]^]0nPoPoPoPoPoPoPnpnnnnnoPoPoPoPoPoPoPoPoPoPoPoPoPoPoPoPoPoPoPoPoPoPoPoPoPo0oPoPoPoPoPoPoPoPoPoPoPoPoPoPoPoPoPoPoPoPoPoPoPoPoPoPoPoPoPoPoPoPoPoPoPoPoPoPoPoPoPoPoPoPoPoPoPoPoPoPoPoPon02unknown file./This program contains tests written using Google Test. You can use the following command line flags to control its behavior: Test Selection: @G--gtest_list_tests@D List the names of all tests instead of running them. The name of TEST(Foo, Bar) is "Foo.Bar". @G--gtest_filter=@YPOSTIVE_PATTERNS[@G-@YNEGATIVE_PATTERNS]@D Run only the tests whose name matches one of the positive patterns but none of the negative patterns. '?' matches any single character; '*' matches any substring; ':' separates two patterns. @G--gtest_also_run_disabled_tests@D Run all disabled tests too. Test Execution: @G--gtest_repeat=@Y[COUNT]@D Run the tests repeatedly; use a negative count to repeat forever. @G--gtest_shuffle@D Randomize tests' orders on every iteration. @G--gtest_random_seed=@Y[NUMBER]@D Random number seed to use for shuffling test orders (between 1 and 99999, or 0 to use a seed based on the current time). Test Output: @G--gtest_color=@Y(@Gyes@Y|@Gno@Y|@Gauto@Y)@D Enable/disable colored output. The default is @Gauto@D. -@G-gtest_print_time=0@D Don't print the elapsed time of each test. @G--gtest_output=xml@Y[@G:@YDIRECTORY_PATH@G/@Y|@G:@YFILE_PATH]@D Generate an XML report in the given directory or with the given file name. @YFILE_PATH@D defaults to @Gtest_details.xml@D. @G--gtest_stream_result_to=@YHOST@G:@YPORT@D Stream test results to the given server. Assertion Behavior: @G--gtest_death_test_style=@Y(@Gfast@Y|@Gthreadsafe@Y)@D Set the default death test style. @G--gtest_break_on_failure@D Turn assertion failures into debugger break-points. @G--gtest_throw_on_failure@D Turn assertion failures into C++ exceptions. @G--gtest_catch_exceptions=0@D Do not report exceptions as test failures. Instead, allow them to crash the program or throw a pop-up (on Windows). Except for @G--gtest_list_tests@D, you can alternatively set the corresponding environment variable of a flag (all letters in upper-case). For example, to disable colored text output, you can either specify @G--gtest_color=no@D or set the @GGTEST_COLOR@D environment variable to @Gno@D. For more information, please read the Google Test documentation at @Ghttp://code.google.com/p/googletest/@D. If you find a bug in Google Test (not one in your own code or tests), please report it to @G@D. GetParam()TypeParamthrow_on_failurestream_result_tostack_trace_depthshufflerepeatrandom_seedprint_timeoutputlist_testsfiltercolorcatch_exceptionsbreak_on_failurealso_run_disabled_testsinternal_run_death_testdeath_test_use_forkdeath_test_stylefastM % A H 6 * % 9H % 9H GTEST_SHARD_STATUS_FILEGTEST_TOTAL_SHARDSGTEST_SHARD_INDEXtest_detail.xml**DeathTest:*DeathTest/*DISABLED_*:*/DISABLED_*` Stack trace: S\$ C$ =u%C P$([ÍT$\WVSt$ |$$9tt =u S>[^_Í&T$\UWVSu} 9t1t+C x P =u S>e[^_]fU\މƋ A=tU\ VUVS]uu S4$ PVSe[^]Ƌ A=tU\ VUWVS8} ]uWYZ UPRS uWSXZVSe[^_]Ƌ A=tU\ VUWVS`WE Dž`EECEEEE,,Dž0,CY^jPXZ44AjP5 F,TDž, Dž`4Dž4 $Dž8Dž<Dž@DžDDžHDžLDžPYX8Dž8DžXDž\ PWE 'RP(P(4P|p( = 8Pu\ Dž, Dž`4Dž4 Dž8 =T Dž8PF5,4@4C, <$,Dž`Ee[^_]4hPt&(\N&&\':[tË( =t &\, P$8 PX,ZhP Dž`W$S5 ,É,UWVS`WE Dž`EECEEEE,,Dž0X,CZjPY^44A50jP5 F,TDž, Dž`4Dž4 $Dž8Dž<Dž@DžDDžHDžLDžPX8Dž8DžXZPWDž\ E 'RP(P(4Ps(P8Pu\ Dž, Dž`4Dž4 Dž8 =T Dž8PF5,4@4C, <$,Dž`Ee[^_]&4hPt&(\Mt/Hȅ&P밍t&HQPЉLb)k8 PZ,YhP Dž`W$,S ,ˋ(pu, P$HtPP&PV뾋PJHUSE ]PYXE 0EPRXZuSU t RP؋]ËUt RP SUSE ]PE p0EPRXZuSU t RP؋]ËUt RP SUVS]u SXZuSe[^]Ƌ A=tU\ VUVS]Ct PCe[^]ÍvuhahjV j hh j@hh4$C떉à V$UVSuue[^]ÍuhyhDjV jhlh jhhXZSh4$e[^]Éà V$UVSE@Pu e[^]ÍvuhHhDjV jhh jhhXZSh4$e[^]Éà V$UWVS(]SuCCe[^_]Ð}h<hDjW jhh jhhXZVh<$딉à W$UWVS]CU rVRP9tjuhUhjV j&hhC pPh jhPC pPW4$e[^_]Ít&uhPhjV j hh j5hh4$C  V$ V$UVS]Ct PCC =uC =u"e[^]ÍvU\C =tvU\e[^]ÉƋC =tU\KA=tU\ VUVS]Ct PCC =u'C =u2 Se[^]Í&U\C =tэvU\ĉƋC =tU\KA=tU\ VUVSEXtS@=utCt PCC =u6C =u Se[^]ÍU\ݍU\ SЃe[^]ÉƋC =tU\KA=tU\ VUVSu^tS@=u|Ct PCC =u>C =u! S Ve[^]fU\ՍU\븍 SЃƋC =tU\KA=tU\ VUWVSu܃$]xu V jhrVCU܃rVRP9tjuhUhjV j&hhC pPh jhPC pPW4$E܃ =uie[^_]ÐuhPhjV j hh j5hh4$CVS뎍&U\e[^_]É VE܃ =tU\ SE܃ =tU\؃ VUVS]E pEPhSYXS]S4$ PVSXEZSpE =uE =u&e[^]Í&U\E =tݍv\e[^]ÉE =tU\E =tU\ SUVS]E pEPh2SYXS]S4$ PVSXEZSpE =uE =u&e[^]Í&U\E =tݍv\e[^]ÉE =tU\E =tU\ SUWVS(E uX$S~i:]}SPW WhLS$vE =uQE =u\F PR e[^_]Ðt& ÈSu|&U\E =tv\뛉ËE =tU\E =tU\ SUWVSuD} _KwVDG}ԉEЍEЉ$WEĉ$PX]ȍEZPhiS$]S jhSE؃ WSPYE[]hPSX}ZVSWE<$pE =E܃ =E؃ =Ẽ =Eȃ =Eă =Eԃ =E =e[^_]Í&U\E܃ =r&\E؃ =d&\Ẽ =U&\Eȃ =F&\Eă =7&\Eԃ =(&\E =&\e[^_]É>y!\C~E =tU\E܃ =tU\E؃ =tU\Ẽ =tU\Eȃ =tU\Eă =tU\Eԃ =tU\E =tU\ SẼ =tU\UVSEu]PVXZVhSE$pE =uE =u'e[^]Ð&U\E =t܍v\e[^]ÉËE =tU\E =tU\ SUVSEPu e[^]ÍuhyhDjV jhlh jhhXZSh4$e[^]Éà V$UWVS(]CPu Se[^_]Ð&}hyhDjW jhlh jhhXZVh<$덉à W$UWVSE֍u؃0PhVEXxXZVuV jhrVCU܃rVRP9tjuhUhjV j&hhC pPh jhPC pPW4$E܃ =E؃ =use[^_]ÍvuhPhjV j hh j5hh4$C&VSpt&U\e[^_]ÍU\cI\#à VE܃ =tU\E؃ =tU\ SE܃ =tՍU\˃ VUWVSuԃD] CXS\EEUPVS :}EURPW]̃ WhS$]S jhS}؃ VSW]܉<$S jh SXEZSpE܃ =uTE؃ =u_EЃ =ujẼ =uuEȃ =|Eԃ =e[^_]ÍvU\E؃ =tv\EЃ =tt&\Ẽ =tt&\Eȃ =tt&\Eԃ =}\e[^_]ÉCE܃ =tU\E؃ =tU\EЃ =tU\Ẽ =tU\Eȃ =tU\Eԃ =tU\ S량n͉ËEЃ =tU\UWVSuԃD] C0S4EEUPVS :}OURPW]̃ WhS$]S jhS}؃ VSW]܉<$S jh SXEZSpE܃ =uOE؃ =uZEЃ =ueẼ =upEȃ =u{Eԃ =e[^_]fU\E؃ =tv\EЃ =tt&\Ẽ =tt&\Eȃ =tt&\Eԃ =tt&\e[^_]ÉCE܃ =tU\E؃ =tU\EЃ =tU\Ẽ =tU\Eȃ =tU\Eԃ =tU\ S량n͉ËEЃ =tU\UWVSuԃD] C$EEUPV[$S:Eƍ}ȃPRW]̃ WhXS$]S jhS}؃ VSW]܉<$S jh SXEZSpE܃ =E؃ =EЃ =Ẽ =Eȃ =Eԃ =e[^_]Ð ÈSt&U\E؃ =r&\EЃ =d\Ẽ =]&\Eȃ =N&\Eԃ =?&\e[^_]É?EЃ =tU\Ẽ =tU\Eȃ =tU\Eԃ =tU\ S밋E܃ =tU\E؃ =tU\EЃ =uU\hv막UWVSE܍u(]PEYxXE 0VXEZpPWE =u^{twEuP}W PWsE =u2E܅t PRe[^_]Ðt&U\똍\ō& jZY PCPe3ËE =tU\E܅t PR SE =t׉\UWVSE(u ]PExts V PVWst}EuPuV PVsE =u8Et PRe[^_]Ív@xGPW뉍U\뾍 jZY PCP_ËE =tU\Et PR SUVSE]PE pPEPstjEuPuV PVsE =u%Et PRe[^]É'U\э jZY PCPrËE =tU\Et PR SUWVSE(u ]PExts V PVWst}EuPuV PVsE =u8Et PRe[^_]Ív@xGPW뉍U\뾍 jZY PCP_ËE =tU\Et PR SUVSE]PXEZu PstaEuPuV PVsE =uEt PRe[^]ÍU\ڍ jZY PCP{ËE =tU\Et PR SUWVSE(u ]PExts V PVWst}EuPuV PVsE =u8Et PRe[^_]Ív@xGPW뉍U\뾍 jZY PCP_ËE =tU\Et PR SUVSE]PE 0tx V PEVPst|EuPuV PVsE =u7Et PRe[^]ÍvEjh0P늍U\뿍 jZY PCP`ËE =tU\Et PR SUWVSE(u ]PExts V PVWst}EuPuV PVsE =u8Et PRe[^_]Ív@xGPW뉍U\뾍 jZY PCP_ËE =tU\Et PR SUWVSE(u ]PExts V PVWst}EuPuV PVsE =u8Et PRe[^_]Ív@xGPW뉍U\뾍 jZY PCP_ËE =tU\Et PR SUWVSE(u ]PExts V PVWst}EuPuV PVsE =u8Et PRe[^_]Ív@xGPW뉍U\뾍 jZY PCP_ËE =tU\Et PR SUWVSEEw_E_UсtTÁمIˉЉ HÉ)É)9Bƒw'E@Ee[^_]t&t Pƅ5 DžDžƅCDžDž Dž$Dž(ppDžtpCY^jPXx=Zx@8jP=@pDžp Dž4Džx $Dž|DžDžDžDžDžDžYDž|Dž_|Dž WPxE@\$4$DŽ|`$E5 CDž`_EEEEEE,,XDž0,CjP=Y^4@48jP=@,TDž, Dž`4Dž4 8$Dž8Dž<Dž@DžDDžHDžLDžPX`Dž8DžXZWPDž\ 4E@\$4$DŽ8Y\,^PWp$`Ph$ƅhDžlP^ZU RPZYhOPYU^RPdT4$d jhVAPXZVTdt  PRhYTZY`QPZYhPZYWPZYPult = W` =\ =\Dž, Dž`4Dž4 Dž8 =wT Dž8P5@,54@4C5 ,,`Dž`$Džp Dž4Džx Dž| = Dž|P5= @p5x@xCppDž$Ee[^_]v'h\I,\?h\yh\-\ qQS5 pÉp DžP$S5 ,É,` Dž`Pp P$볉à W_X,hP먉cDdt PRPPljP` =t h\\ =t h\, PF뜉à WXpZhPUWVSEݕPEݕHTPTLHLTTP ËLLH9s1)ڃwZwUvE@Ee[^_]w9r)ӉȉÐ&TP 2 Pƅ DžDžƅCDžDž Dž$Dž(ppDžtpCY^jPXxZx@jP=@pDžp Dž4Džx $Dž|DžDžDžDžDžDžYDž|Dž_|Dž WPx @TPVDŽ|`$E5 CDž`_EEEEEE,,XDž0,CjP=Y^4@48jP8@,TDž, Dž`4Dž4 $Dž8Dž<Dž@DžDDžHDžLDžPX`Dž8DžXZWPDž\ 4 @LHVDŽ8Y\,^PWp$`Ph$ƅhDžlP^ZU RPZYhOPYU^RPdP4$d jhVBPXZVPdt  PRhYPZ`YRPZYhPZYWPZYPult =1 W` =\ =\Dž, Dž`4Dž4 Dž8 =T Dž8P5@,54@4C5 ,,`Dž`$Džp Dž4Džx Dž| = Dž|P=5@px@xCp pDž$Ee[^_]t&LH A؃s؃ډAh\,\h\Oh\\ =OS= pÉp DžP$dt PRPPljP` =t h\\ =t h\, Pp P$븉ω= W_X,hP` Dž`P랋S= ,É,ȉĉy WXpZhPUVS]3t PR 3ue[^]ÐuhhDjV jhYh jhhXZSh4$e[^]Éà V$UWVS8}7t  PR 7tUuhhDjV jhYh jhhXZSh4$w_9u1 9t!C =tU \9u䐍t&wt Ve[^_]ÉEà V]ԃ_w9tF =tU\ 9u_t S uUWVS,}u G+9ƉErxnE9E;u]E)~=Eԉu &SuE Uԃmʃ20 uЍe[^_]ÍEh:hjPE j.hxh jhrhXZVh jhPYXuS[ZhPYuE9EEh=hjPE j.hh jhhXZuh jhPYXVS jhPXZuSZYhPXur u$ u$VSD$ stF0 w;j D$PSL$ 9uu 9t v1[^ËT$$UWVS0] ujhS<\$t&jhSt&jhS jhSXZWSF<jhSe[^_]Íjh7S jhS͍vjhSh&jhSH&jhS(&jhS&jhS&jhS&jhS&jhS&G^EWPEYXEPEhPXEZpPSE =E =jhSIVjhSXZWSEWPY^jhSE pPSE =U\U\jU\L'EEjPS jhSQLE =tU\E =u SËE =tU\0Pp8UWVS0] ujhS<\$v'jhSt&jhS jhSXZWSF<jhSe[^_]Íjh7S jhS͍vjhShjhSP&jhS0&jhS&jhS&jhS&jhS&jhS&G^ ERPEYXEPEhPXEZpPSE =E =jhSLVjhSXZWSvEVPY^jhSE pPSE =U\U\bU\Dt&EEjPS jhSQLE =tU\E =u SËE =tU\0Pp@UWVS ] ujhSډmjhSue[^_]Í&jhSYXVStFwjhSe[^_]Ít&EVPXZjhSE pPSE =tU\뛉ËE =tU\ SWVSt$ |$$9tt =u S>[^_Í&T$\UWVSt$0|$4l$8F;FtMtPFPVP])u[^_]Ð&)RWP܍)Љ9D$)щL$ t$L$ tE)ʼnuoL+n)u=ͅt P\$n^H&D$)fUWQL$L$ 뫐&UPS~=?6\$)1ۅF(UWVSt$0|$4^;^tItCCFD$80C)u7[^_]Ít&)PWS) 9)‰T$ SŋD$T$ )tD$8uhVL )u6<t P.~^Nf)눐t&RT$WQL$T$ L$몃QL$t$UL$ z?0)…*щD$1=UWVSt$0|$4l$8F;FtMtPFPVP])u[^_]Ð&)RWP܍)Љ9D$)щL$ t$L$ tE)ʼnuoL+n)u=ͅt P\$n^H&D$)fUWQL$L$ 뫐&UPS~=?6\$)1ۅF(UWVS WSS*E =tU\E =tU\E܃ =tU\EЃ =tU\Ẽ =tU\Eȃ =tU\E؃ =t\ S렉뱉‰UWVS WSS*E =tU\E =tU\E܃ =tU\EЃ =tU\Ẽ =tU\Eȃ =tU\E؃ =t\ S렉뱉‰UWVS WSS*E =tU\E =tU\E܃ =tU\EЃ =tU\Ẽ =tU\Eȃ =tU\E؃ =t\ S렉뱉‰UWVS WSS*E =tU\E =tU\E܃ =tU\EЃ =tU\Ẽ =tU\Eȃ =tU\E؃ =t\ S렉뱉‰UWVSt$0|$4l$8F;FtMtPFPVP])u[^_]Ð&)RWP܍)Љ9D$)щL$ t$L$ tE)ʼnuoL+n)u=ͅt P\$n^H&D$)fUWQL$L$ 뫐&UPS~=?6\$)1ۅF(UWVSt$0|$4l$8F;FtMtPFPVP])u[^_]Ð&)RWP܍)Љ9D$)щL$ t$L$ tE)ʼnuoL+n)u=ͅt P\$n^H&D$)fUWQL$L$ 뫐&UPS~=?6\$)1ۅF(UVSEuPE tP S PESPRuVU t RPe[^]Ejh0P벉ËUt RP SUWVSt$0|$4l$8F;FtMtPFPVP])u[^_]Ð&)RWP܍)Љ9D$)щL$ t$L$ tE)ʼnuoL+n)u=ͅt P\$n^H&D$)fUWQL$L$ 뫐&UPS~=?6\$)1ۅF(UWVS \$$L$(t$ l$,ϋC);Ct9t'UQS [^_]&t UCC [^_]WVS\$$|$ uDt& St.s WCs =tύT$\čt&[^_UWVSD$4pPT$ D$8T$8ol$mt-EX9F)QWPDÅyϋm uӋD$9D$ tF@X9FQPW)څD…xD$0T$D$0[^_]D$0T$ D$0[^_]UWVSE pE؅EExFt>ƋFXE9FӃRPuUU)مDxF 1Ʌu‹E܄ɉu܉EuA)RuuDÅE0@Ee[^_]u؍&E 9p t. V}Xu܉Ƌ?][}9F뉉u܋u9uEVrX9މF)QRPD1xt jÍ@uPuuSVE @E@Ee[^_]E܅f1 jÍ@녃 P$ SUWVS]tt@ptG>*tQt4uh{hDjV j3h\ h4$jhhSe[^_]à V$UWVS`WE Dž`EECEEEE,,Dž0X,CZjPY ‰44B^jP8@,TDž, Dž`4Dž4 $Dž8Dž<Dž@DžDDžHDžLDžPXZVWDž8DžXDž\ E p04PXZVu\ Dž, Dž`4Dž4 Dž8 =T Dž8P5  @,4@4C,<$,Dž`Ee[^_]t&+\k3S5 ,É, Dž`W$, P$밃 VY,^hPUWVS \$$|$(l$ t$,)߉@sVtUsVtJsVtO 9t`3Vu] [^_]&v] [^_]] [^_]D$()t2tt=D$(E [^_]7Vt*7Vt7Vu}F|$$UWVS l$$t$()D$,{.&E9xtPE9xtxE 9x9E9xuуWSPuD$ (D$ [^_]vWSPuD$ UD$ [^_]&WSPrD$ U랍&WSPVD$ U st&D$()ttVtFD$ L$(HD$,(]9Xt]9Xu׃SUPuŋD$ 0D$,(]ыL$,)P]9t밃RUPu뿃SUPu뫋t$$XUWVS \$$|$(l$ t$,)߉ft6pCt6pCt6pC t6p9zD$()t:ttMD$(E [^_]t6pt=t6pt t6puv] [^_]'] [^_]]˃ ]UWVS t$ D$$9tmut h &)t$,jPǍh t SVUu* [^_]G 損& [^_]ÐGD UWVS,Eu 8vEԍElm}hh WtnE9t!EԍTDv'8x9uEE =@E9z=te[^_]Ít&hh~ Wthhm WVhhg W8hh Whh Whh` Whh WhhU WhhN WhhC Wfhh7 WHhh0 W*hh( W hh Whh Whh WEh Pu-&E =U\Eh PtÍEh PtEh Pt*uJËE =tU\ SUWVS,E} 8v47PEPEZYhh PEtjE9tD7T'0p9uEE =`E9z=te[^_]Ít&hh~ uvhhm uVhhg u6hh uhh uhh` uhh uhhU uhhN uvhhC uVhh7 u6hh0 uhh( uhh uhh uhh uEh Pu-&E =U\Eh PtÍEh PtEh PtE*u)ËE =tU\ SUWVS]tt@ptG>*tVt4uh{hDjV j3h\ h4$jhhSe[^_]à V$UWVS(u6t Pe[^_]Í& jËFCY_S6u eC[^_]f}hhDjW j&hD h jhhXZVh<$뜉à W$VS\$ t$$9u-t&9t! =tT$\9u䐍t&[^UWVS<}u G;GtPRPGGEuPWBZ)э<~t&CPS9uEPVE =ue[^_]ÍU\))ˍŨ PE]Љ]tuu]9ƉEt%t&tuSEE9uߋOCEĉ9ΉMt't&t VS9uuGEԋ7;uuDt&9ut2 =tU\9vPE?)&EԋEԅt PEЋM̉_G2qH?w)˅EE PZYSuE =tU\ SMЉMă PEăt:uuEЅt P SEȋ =tȍU\뾉( P^_SunNtÐt&UWVS,E$}u W<$hE =! 59u.9t! =tM\9ދMuE1ۉ u uzv'E9tcVW ;tytWPE =tU\E9u'u u@$t&e[^_]ÍWPh둍t& hӍU\E =tU\ SE =tU\ SUWVS,}te[^_]Ív'~E ]lmShE =  9ȉEԉt8} 9t! =tڃ\9u捴&}E1u cv97tYE lm;twtSPE =tU\97ut&u W@$ hv'SPh듍U\E =tU\ SVS\$ t$$9u-t& 9t!C =tT$ \9ut&[^UWVS8E0t& PEԋEԍe[^_]É' j‰EЃEԋEX+XBBB iEE̋MÉAAY MyY9ƍtCFCPFP 9uՋEЃpPE0 uhhDjVY_hD h_ZhPZYSP4$&=UUUw SẼuh EЋ@t P u$ V$ PXZVuUVSu] @$utu9 VӃe[^]É'u Vv \Vf\뿃uz ]P$RMƒRRSjE =tU\kE =tU\ S ]PM1҉PPSjE =tU\& PE =tU\ S SUVSu] @$utu9 VӃe[^]É'u Vv \Vf\뿃u| ]P$RMƒRRSjE =tU\1iE =tU\ S ]PM1҉PPSjE =tU\1& PE =tU\ S SUVSu] @$utu9 VӃe[^]É'u Vv \Vf\뿃uz ]P$RMƒRRSjE =tU\kE =tU\ S ]PM1҉PPSjE =tU\& PE =tU\ S SUVSu] @$utu9 VӃe[^]É'u Vv \Vf\뿃u| ]P$RMƒRRSjE =tU\1iE =tU\ S ]PM1҉PPSjE =tU\1& PE =tU\ S SUWVS<}u ]G;Gt!PPPPRPG GCE܋CSEEPWZB))ziɫ~+'PXPPPSP9uދE܃FEFEPVE =ue[^_]ÍU\)i )ЉEԍIM PEЋEEЉEt MȃCAASP]9ƉEt4t"MԃACȃPCPE E9űOC Eĉ9ΉMtt WEUĉFEFR~G =tU\G =tU\ SMătM u Pt*E9Ét- V9u P WEąu묉 } )ׅEEEԃ P$E =tU\E؃ =tU\ S?ՉߋG =tU\G =tU\볉Ѓ PUăUWVSu} ]9t4v'tVSXFZPCP9u֍e[^_]Ƌ =tU\ P9]t uE9]u SUWVS,]u{;{t"GPWXGZPGP{E{VPYE_VPSB+E ~/Ѝr9ut@F =tߍU\Ս?9vJM E)U\븋t PEЋM̉{ȉCwM )҉EEE P$E =tU\ SA=tU\ۃ PttE9Ɖty S9ud=Eԋ =tU\ SEЃt& u PUЃuڃ uEЅuщ , =tU\؃ PEЃ9tEԉǃ S9u} SrS$h hhhXZjho Y[jh XZjh Y[h:h \$SPh hhhXZh h SPh hhhYXhh SPh hhhXZjh YXjh XZjh YXjh XZjdh YXhh SPh hhhXZjh  hhhYXh h  SPh hhhXZjh Shh hhh  hhh hhh([N7testing8internal26ThreadLocalValueHolderBaseEN7testing8internal26GoogleTestFailureExceptionEN7testing8internal9DeathTestEN7testing8internal16DeathTestFactoryEN7testing8internal23DefaultDeathTestFactoryEN7testing31TestPartResultReporterInterfaceEN7testing8internal24HasNewFatalFailureHelperEN7testing4TestEN7testing8TestCaseEN7testing17TestEventListenerEN7testing22EmptyTestEventListenerEN7testing8UnitTestEN7testing32ScopedFakeTestPartResultReporterEN7testing8internal27OsStackTraceGetterInterfaceEN7testing8internal18OsStackTraceGetterEN7testing8internal35DefaultGlobalTestPartResultReporterEN7testing8internal38DefaultPerThreadTestPartResultReporterEN7testing8internal12UnitTestImplEN7testing8internal17StreamingListener20AbstractSocketWriterEN7testing8internal17StreamingListener12SocketWriterEN7testing8internal17StreamingListenerEN7testing8internal27PrettyUnitTestResultPrinterEN7testing8internal17TestEventRepeaterEN7testing8internal24XmlUnitTestResultPrinterEN7testing8internal13DeathTestImplEN7testing8internal16ForkingDeathTestEN7testing8internal15NoExecDeathTestEN7testing8internal13ExecDeathTestEN7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEE11ValueHolderEN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE11ValueHolderEzD+g Xa{Sstd=$2@'2'2'2'2'2'2(2@(2[(2w(2(2(2(2(2)2!)2L)2g)2})2)2)2)2)2*2:*2Z*2u*2*2*2*2*2+2+28+2+2,2-,2L,2k,2,2,2,2,2 -2--2M-2l-2Ƃ-2Ǣ-2-2-2.2.20.2N.2m.2ϋ.2Ъ.2[2 v2 3S3\3^ ? ,4Y G4_)  4c<  4gO ) G#O0( \8v\8{\8\8\8\8 r*ŐvŐ{ŐŐŐŐ AvA{AAAA\"9v"9{"9"9"9"9 y%dX%5hdɋϋ4eq&$ϋϋlt$"$ϋϋZ%ՋՋՋF FSՋՋϋ!:ۋ)ۋՋh?ۋMۋՋ5- ۋqۋ4m:4?Q #?ϋ5$$eof(c?kH,v?%59%4y6$%dX7'5=c;eqAM=$^ltE>$|ZIM%MHFQJ!UohYB&5] JmaWdQe)5i$eofm+>kHqT6566267L7cv5%58\}08_@8`K8cev8dk;M8qDJ;M8sZe 8yq%8\28_K8cv8d;M8q;M8s 8y%p h !*"CS*#\%y$/6h!ʾ!x@zK{v|(a4Rg6ib Cq"  | $ %h%gh%qR %G  &V%2&s%7'&9%B'|9Hѐ(x$} ($ )Ǒ ː)eQ˴> ː)\ϴA ːh(E* ː(j'*$ 4 ː.%!CːX hh)`Rk v ː*W%y ː+;=* ː,%o* ːh+$* +(*  Ő*+,7ː1 7 +2#O U +6Ym s *:  Ő+Ah h'*K#7 hh'+IS2h  hh+ĭ[$$ ) '(dB_I *'hoNmji *'hvJ *h%#] *#]a *#]OO ***#] *'' %( hh*(%wI< Q Őhhh*%e k Ő-|9ѐ./ Ő//% Ő/% Őא/% Őאhh/% Őאhh/%'<Ő'h/%L\Ő'/%lŐh%.,S"Ő%01I*l/ݐŐא01I2x{ݐŐ'01I=,ݐ Ő%0)f"(Ő0)q5AG1endys`fŐ1endm0QŐ0Q;0(3Ő0(30u3h 0OXh9?0XhX^2#%LsŐh%2#XŐh0NTh2%HŐh2.y-FŐ05$0D)5@h0UYdŐh1atk|h1atvŐh0IݐŐא0I`ݐŐ'0I|ݐ Ő%0%D5ݐ/:Őא0%UݐShŐאhh0%)ݐŐ'h0ݐŐ'0%ݐŐh%2q-!Ő%35%zݐ!Őא05^=ݐ:OŐאhh05%=ݐhxŐ'h05z ݐŐ'05ݐŐh%2wK:Őh%0wݐŐhא0w8ݐ1KŐhאhh0w%g&ݐdyŐh'h0w"6lݐŐh'0w9ݐŐhh%0wKlŐ%0idaUݐ"Őhh0it;FŐ0i%ӧ_oŐ0BݐŐhhא0ݐŐhhאhh0%ݐŐhh'h0:ݐ!6Őhh'0ݐOiŐhhh%0UݐŐא0'+ݐŐ'h0<[hݐŐ'0Qݐ+Őh%0v4ݐD^Ő**0XAݐwŐ''0EݐŐ0BݐŐ+.#%k|ݐ)Őhhh%+R%&ݐA[Őhh'h*h%4)%[*h%0h%h*hh2 %3Őݐ0d5W' 013%pU'(.0,'&GM0F%hf{'hh0FIhאh0FXth'h0F%8h%h0$KvO hאh0$K% |3h8M'hh0$Khfv'h0$K%k!h%h06hאh06%/h'hh06h'h06 /h8H%h0Thaqאh0%>Fwh'hh0h'h0$Yh%h0$2h אh0$%Sh3H'hh0$QHhaq'h0$%_V%h%h0qhאh0%jh'hh0nh 'h0%$h3C%h0r`\lhh0Z %א0Z%:%hhא0Z%t%hhאhh0Z%%'0Z%t%3Hhh'0Z%Jk%a{hh'h$ 4%{Q*X'''7**'''1*'''<%)>CI'Ő''47%{*tX***O****7DK****% CI*Ő**!%5(56O6bKp6 !'"h x '# %y$/6  !ʾ!8 xK{v|8Rg8ib6Cq6 | =!% %g %qR %G " !&V%2 &s%7;(&9%B'|9S (xZ$!!($!!)f!!)eQ!!)\Ԍ! " (Eދ' "&"(j2'="M".%!b q"  )`L""*W%""+;'"",%o~'" +$' ##+(''#2#'+,=J#P#+2- h#n#+6= ##*:##+AI ## '*K##  '+ISN $$  +ĭ[ԃ$7$B$5((db$'5( oNm#$'5( vl$' $%#]$'  #]$'  #]F%'''#]h"%'5(5( & %A%  *(%U%j%   *%b~%%-|9_ ./%%//%%%/%%%/%%&  /%&0&  /%@&U&5( /%e&u&5(/%&& $%.,S"&&%01I*k&&01I2&&5(01I=P'"'$%0)fi? ;'A'0)q Z'`'1endy{ y''1endM4 ''0Q!''0Q ''0(3!''0(3 ((03 3(9(0 R(X(0 q(w(2#%(( $%2#tM(( 0N ((2%(( 2.y- ))05$/)5)0DC N)Y) 0Uؠ r)}) 1atkm4 )) 1at )) 0I))0IL* *5(0I$*/*$%0%DH*S*0%U`/l**  0%)#**5( 0***5(0%** $%2q- ++$%35%)/+:+05^1S+h+  05%e++5( 05z++5(05)^++ $%2w+,  $%0w]!,1, 0w7J,d,   0w%gq},, 5( 0w",, 5(0w90,,  $%0wKX -- $%0id+-;-  0itk9 T-_- 0i%8 x--  0--  0A5--    0%xy.!.  5( 0:.O.  5(0Gh..   $%0..  0'Tx..  5( 0<ʎ./  5(0Q[@*/D/   $%0vn&]/w/  ''0]//  5(5(09//    0w/0    +.#%(0B0   $%+R%`Z0t0  5( '0 $%4)%'0 $%0h%5 00'  2 %m!0 10d5d5("1(1013%}R5(A1G10,^ `1f10F%  115(  0FI" 11 0FXK 115( 0F% 12$% 0$Kv (282 0$K% = Q2f25(  0$Kz 225( 0$K% 22$% 06w 22 06%/ϭ 235(  06C (3835( 06[a Q3a3$% 0 z33 0%>|[ 335(  0G 335( 0$Э 3 4$% 0$2P #434 0$%Sŀ L4a45(  0$Q-3 z445( 0$%_R 44$% 0qn 44 0%j $ 4 55(  0& #5355( 0%lD L5\5$% 0r[, u55  0Z %550Z%%55  0Z%.%56    0Z%%(6365(0Z%%L6a6  5(0Z%%z66  5( =!!$%5566, R9>7 #!3^7 ^ \  P  w$  (9 [ v N  RI e )0 1 S= 7˩!g7 k C ՗ 9 C  U7!7   ,f  7!7   1 8:9!J8:[w!R:!$.!+818F;g!>8F%!6dec!9= !9>hex! 9=D!9=!9 >oct!9@==!9?n !9?!"9?v!&9?!)9?(!,9?{I!/9 ?x!39@=!69=!99J?!<9=h8!N:V8=A!Q:=i!V:=O!Y:>app!lY:8>ate!oY:= !tY:>in!wY:>out!zY:=S !}Y: !7>beg!::>cur!:>end!::RW:SL:T':\m:e:h:i8%=@];/;?;L%L.yP;`;L%L3wGPx;;L9%G;3lP;;L^3ɫGP;;L,3YGP;;L%3P<<L3qP3<><L]3cGPV<a<LU%!%5(3 O;nˑ<<L'3.;^ˑ<<LAput;Aˑ<<L<y>%3;? ˑ ==G%LG%3;imGˑ,=7=L%3;?ˑX=c=%L%3";?!+ˑ==]L]B@;?Tˑ=,L, l>Cp=!i777Cp>!i999Cvp!>!i|:|:|:Cwp@>!iBBBCI-p_>!iP@P@P@C=p~>!i@@@Dp!i555 0W?E0[B>CIB!iBBBBE80[9?CI9!i9999E8.0[|:9?CI|:!i|:|:|:|:Ez0[P@j?CIP@!iP@P@P@P@E0[@?CI@!i@@@@F@0[5CI5!i5555 i@ݑ(1I<AA)s<AA)<AA(l<>$AA('I<$BB((<_$%B0B(;I<2]$GBRB(W<}r$iBtBJ<˙$B1A u=JDDCJy"%0d"-=J EECJ0*G"T<=J,E2ECJ@"DGERE,L%."cEiE,L!%5(8oF0maDEEEaR%*\FMu>N#>O6FP^I>FQ>$FR>&/>%I_TpF6n9?; $F%$% z$מF%$%7+)ZF  + )\jG% k)aFr)^4%)bF%)cF%s)dF #)_44)g*F"GF4)nىF;GF4)uFTGFS)|6FFF b*`G%M*e4%e/*f4G*lGG4G*pGG444I_T14I_T248vwH1strG?HGH< JT  H5H4%L8U,4GKH[H4%L!%5(5|H)9D, u=8\Io98_oF8aF);M8qHH5;M8sHH558yHH5%V8h8i"IIH,b8\~I;;M8qEIKI+6;M8s[IfI+616 8yrI+6% l@vI8'>'3$@oI ~I+>@r$II555I_Tp'I )RJ F%y)'()BF)%J+J6()C*BJHJ60'I"IW9,)ZVXR) K "I!:-)I!U)F!.) K"_)JJ76"_)JJ76=6C62)rJJ76$IY$<)nKJ)];ZA)iJXK)5oF)*)V9{)tX )6"7)XX6]7)XY6X"7)YY66X+) 2X8Y>Y6+tH)rXVY\Y6+N)tWXtYzY6+SI)C6YY6+SI) _BXYY6%+eN)(@6YY6+eN)/ΒXYY6%+l)7G>$ZZ66X+();Z$D[[[60/AL/[\\60/E>([5\;\60)/N֫4[T\Z\61end/WF4[s\y\60Q/`KL[\\60(3/iXL[\\60/1$\\60/#X[\\60/SX[]]62 /=)]4]660w/ t_M]X]66[0w/|4[v]]6@[62i/\9]]64[0i/l'X[]]66Z2i/^1]]64[4[2.y/k\ ^^60/X[(^3^660F/X4[L^W^660F/Կ@[p^{^660%/l4[^^660%/+@[^^660j%/94[^^660j%/$E@[_ _660/{Z$_/_660/ZH_S_6632'5:tI5HZ *`_%M*etX%e/*f$G*l__6G*p__666I_T1tXI_T2$tX*J8\`=8_oF8aŐ">8bK8cݐv8dא;M8qC`I`>7;M8sY`d`>7D78yt``>7%a8h`8i_a>Z8h`8i 38w`>7D_ Hc !% Oa _%V,Ra%Sa%TaG!%V:a@aP7G!%ZOaZaP7V7)seCmaxaP7\7#PaP7%oFM-?a>K@%A`n_(eqb7aah7(euV7aan7(yabbn7G|%b+bh7G:bEbh7t7aGYbdbh7Gsbbh7t7Gbbh7%(5;Ilabbh7)<NVbbh7ab)bch7I_Tp_` ֻj֝bֿb֨aaa`&oFa">8?KC?vN?w@RgBibjCqj_9ccz7T9cdz77cT9/d0dz7c77Oc.9>FdQdz77.bdmdz7%31I7ddz77252ddz7c70)#δcddz70),XRcdd71end5c eez71end>Vc+e1e70QGLcJePez70QP-cieoe70(3Y>ceez70(3bGcee70?cee70Icee72#ffz7cOc0NFc)f/f70X$HfNf7bAhpbfmfz7c0 scffz7c0cff7c2PB ff7c1at6'scffz7c1atHcgg7c0pS6sc4g:gz70p[cSgYg70Ucscrgxgz70Ukҍcgg7013z[cggz7013wgcgg72q~Sggz7723\H hhz73wkt4c(h8hz7c72w0Mhbhz7cc70i}?c{hhz7c0ichhz7cc2 hhz772.y hhz72jShiz7c7bvXB#i3iz772Hi]iz7cc72F-riiz7cא0&ѽcii7c'2l$iiz7[c3O~?ciiz7c3Ocjjz7cc.&0jEj!i*z7**c.BdjyjCI*z7**.P:jjCI*z7**7I_Tp5_6 (6c s$j%$%!%;8\kD8_oF8a7">8b7K8c7v8d7;M8qKkQk7;M8saklk778y|kk7%VD8h8ij7j 9 Hm !% OOl j%V,ROl%SOl%TOlG!%Vkl7G!%Zll77)se /l:l77#PCl7%oFMdF_l>KJG%Aknj(eq47ll7(eu67ll8(y٢vlll8G|ll7Glm7 8vlGm&m7G5mEm7 8GTm_m7%(5;?&Olvmm7)<"mm7Olb)>3mm7I_Tp7jk t_mցmjl֞lֻlk&7oFOl">oFKzFvFiGRgIibtCqtj9nn8T9nn88nT9/nn8}n88n.9>oo8!8.$o/o8%31IH'8GoRo8!825Cgowo8}n80)#pMnoo80),џYnoo-81end5fMnoo81end>Ynoo-80QGaqn pp80QPlen+p1p-80(3YiqnJpPp80(3bfenipop-80C}npp-80}npp-82#pp8}nn0N}npp-80'*$ qq-8bA$q/q8}n0 5nHqSq8}n0Anlqwq-8}n2PB o/qq-8}n1at6o5nqq8}n1atHAnqq-8}n0pS5nqq80p[Anrr-80Uc5n4r:r80UkAnSrYr-8013znrrxr8013)nrr-82qrr8823rr83wkAMnrr8Mn82w0ps$s8Mn}n80i}Mn=sHs8Mn0iOMnasqs8MnMn2 Mss8'82.yZss82jrss8}n8bvXss882c] tt8Mn}n82FA4tDt8Mn70&}n]tmt-8}n'2}/tt8n3OiLMntt8Mn3OMntt8MnMnI_Tp75j6(6fm 41u@4oF47K47R7 `3oIuc3q ?h8\vI8_oF8a\8">8bb8K8ch8v8dn8;M8quu8;M8suu888yuu8%V;8h8iIuIu x H3x !% Ov Iu%V,Rv%Sv%TvG!%VYv_v8G!%Znvyv88)seh<vv88#Pv8%oFM4Kv>KL%AvnIu(eqE?8vv8(eu8ww8(yv/w5w8G|DwJw8GYwdw88vGxww8Gww88Gww8%(5; vww8)<Qwx8vb)LYx x8I_TpIuv1I Mּwwvvwv&oFv">?KKJKvUK]LRg|NibMCqRIu9yy8T9y$y88xT9/:yOy8x88nx.9>eypy88.yy8%31I$8yy8825yy8x80)#xyy80),-x zz81end5vx+z1z81end>xJzPz80QG8xizoz80QPrxzz80(3Y' xzz80(3bxzz80Xxzz80ۍx{ {82#O{/{8xnx0NRxH{N{80$g{m{8bA{{8x0 )x{{8x0rx{{8x2PB )Q{{8x1at6x ||8x1atH@Xx/|:|8x0pSTxS|Y|80p[٧xr|x|80Ucz`x||80Ukx||8013zƒzx||80131x||82q }}8823P)}/}83wk7xG}W}8x82w0p^l}}8xx80i}1x}}8x0iaax}}8xx2 }}882.y~ ~82j~.~8x8bvXB~R~882Sig~|~8xx82F47~~8xn80&x~~8x'2!~~8zx3O,x 8x3O x%58xxxI_Tp5Iu66f8xI-8\P8_oF8a"9">8b(9K8c.9v8d49;M8qL9;M8sL9R98yL9%VF+8h8i\\  HF !% O \%V,R%S%TG!%Vlr^9G!%Z^9d9)se^9j9#P^9%oFM=Rπ>K#S%A'n\(eq0p9v9(eud9%+|9(yBH|9G|W]v9Glwv99Gv9Gv99Gāρv9%(5;ʜv9)<Zv9b)(3v9I_Tp\+ eρڀ+&oF㿀">HRKSRv^RfSRgUibeCqj\99T9,799T9/Mb999.9>x99.9%31I9ƒ9925N׃990)#`90),iɂ%91end5Q>D91end>ɂ]c90QG|90QPe6Ղ90(3Y590(3bP;Ղل߄90Q)9092#o2B90N[a90$z9bAu90 Å90|܅92PB Ύ91at6mX*91atHfgBM90pSpOfl90p[l90UcQ90UkAÆɆ9013z9013=92q'9923 L<B93wkxZj992w0990i}i90iч92 @992.y92j1A99bvX Ue992z992F829490&#Q͈݈9'2l93O'p 93OF8H9I_Tp5\6&6K:8\.U8_oF8a9">8b9K8c9v8d:;M8qӉى:;M8s:":8y:%V+8h8it9t ? H^ !% O׊ t%V,R׊%S׊%T׊G!%V.:G!%Z.:4:)seŠ.:::#Pˊ.:%oFM9W>KX%A?nt(eq@: &F:(euy4:=CL:(yagZ`L:G|ouF:GF:R:GF:G͋F:R:G܋F:%(5;k׊ F:)<z,F:׊b)R>@KF:I_Tp9t3~[ x &C3&9oF׊">DWKOWvZWbXRgZibxCq}t9-3X:T9DOX:^:T9/ezX:d:^:.9>X:j:.X:%31I0p:ύڍX:j:25X:d:0)#JՌX:0),7=v:1end5LՌV\X:1end>4yu{v:0QGb<X:0QPKv:0(3Y~Ҏ؎X:0(3b!v:0cuv:0ٚ/5v:2#YJZX:0N6Dsyv:0?$v:bAFX:0 /ЏۏX:0$Ɍv:2PB v:1at6lk7BX:1atHK6ɌZev:0pSs~X:0p[..Ɍv:0UcX:0Uk/aɌېv:013zX:013ʉv:2qk4?X:d:23TZX:3wk_ՌrX:Ռd:2w0X:Ռd:0i}**ՌőБX:Ռ0i{!ՌX:ՌՌ2 DX:p:2.y.4X:2jIYX:d:bvXYm}X:d:2ؽX:Ռd:2F̒X:Ռ:0&0 v:'2S X:3Oi(Ռ-8X:Ռ3OՌP`X:ՌՌI_Tp95t66-c8\A\8_oF8a|:">8b'K8c:v8d:;M8q:;M8s::8y":%V9G8h8i% i Hq !% O %V,R%S%TG!%V:G!%Z::)se|ʔՔ::#Pޔ:%oFMB^>K(_%ARn(eq:39:(eu:PV:(yms:G|:G::G:GЕ::G:%(5; :)</?:b)wS^:I_Tp%F ֋9VF&%oF">M^KX^vc^k_RgaibꋝCq됝9@F:T9Wb::$T9/x:::.9>::.ʗ:%31IT:::25::0)#0+1:0),rJP:1end5}io:1end>s:0QG0 :0QP1Ƙ̘:0(3Y :0(3baq :0Q#):0i BH:2#'&]m:0N :0!$:bAʙ:0 +Ж:08ܖ:2PB H'2:1at6ЖJU:1atHvjܖmx:0pS6 Ж:0p[ILܖ:0UcЖϚ՚:0Uk-ܖ:013zp$ :013NĖ,2:2q&<GR::23]gm:3wk::2w0::0i}tP؛:0i  :2 <!,::2.ykAG:2j\l::bvXM::2::2F`Ϝߜ::0&/:'2(:3OG@K:3O_Tcs:I_Tp%566<vAvKAw|A{X;An;A;A;A;A;A;A <A$<A?<A_<A<A<A<A<A<A<A=A.=AN=AAaAi=A=A=A=A=A=*8\&a8_oF8aP@">8b\@K8cg@v8dm@;M8q˞ў@;M8s@@8y@%V]48h8ilV@l  HV !% Oϟ l%V,Rϟ%Sϟ%TϟG!%V|@G!%Z@@)seQ@@#Pß@%oFMcߟ>Kfd%A7nl(eqP@@(eu@5;@(yRX@G|gm@G|@@G@GŠ@@GԠߠ@%(5;Hϟ@)<$@ϟb)8C@I_TpV@l+ 9 pߠ;+&V@oFϟ">cKcvcdRgfibpCqul9%+@T9<G@@ T9/]r@@@.9>@@.@%31I @ǢҢ@@25١ms@0QG9@0QPL@0(3YgʣУ@0(3b@0D@0'-@2#BR@0NRkq@0`$@bAZ@0  ȤӤ@0hh@2PB  @1at6qq/:@1atH/R]@0pS/Nv|@0p[j@0Uc@0Ukӥ٥@013z`@013R@2q,7@@23=LR@3wk[͡jz@͡@2w0Z@͡@0i}͡Ȧ@͡0i1F͡@͡͡2 @@2.y&,@2jAQ@@bvX2eu@@2~@͡@2F!=ħ@͡m@0&bݧ@'2/ @3OA͡%0@͡3O͡HX@͡͡I_TpV@5l6="J aGd idd nd@ ooF p'K q2Cq yըۨC/Cq CCq CC3 T)/C3tH |GMC3N ekC3SI 8CC3SI @6uC%3eN SCĩʩC3eN ۷uC%3~H juC3I hC(3C3H uKVC0N *CozC0 FCRd[־8\gh8_oF8a@">8b@K8c@v8dA;M8q A;M8s"-A A8y=HA%V88h8i@ ! H !% O %V,R%S%TG!%Vë,AG!%Zҫݫ,A2A)se,A8A#P,A%oFMj >Kok%Axn(eq>AY_DA(euF2Av|JA(y"7JAG|DAGȬDAPA7GܬDAGDAPAG DA%(5;F&7BDA)<"<UeDAb)yDAI_Tp@lj ֶ B+_|l&@oF">jKjvjkRgmib궴Cq뻴9flVAT9}VA\AJT9/VA>bA\Aҭ.9>ɮԮVAhA.VA%31I]nAVAhA25(8VA>bA0)#.QWVA0),OpvtA1end5VA1end>DtA0QG#p2ͯӯVA0QPJ&tA0(3Y2 VA0(3b=F&*0tA0>IOtA0B>hntA2#ۘVA>ҭ0Nm=>tA0m$˰ѰtAbAVA>0  VA>0-8tA>2PB IMXtA>1at6op{VA>1atH\tA>0pSqVA0p[\RֱܱtA0UcpYVA0UktA013zޭ39VA013)RXtA2q{EmxVAbA23VA3wkJVAbA2w0вVA>bA0i}Dy VA0iO"2VA2 2GRVAnA2.yVUgmVA2jj*VA>bAbvXVAbA2˳VA>bA2F8_VAA0&>.tA>'2CNVAޭ3OfqVA3OVA>I_Tp@5656g8\"p8_oF8aA">8bAK8cAv8dA;M8q$*A;M8s:EAA8yU`A%VJ8h8iŴ)Ŵ ! H !% O( Ŵ%V,R(%S(%T(G!%Vյ۵AG!%ZAA)se,AA#PA%oFMq8>Kr%AnŴ(eq\AqwB(euA B(yO BG|ƶBGնBBOGBGBBG-8B%(5;|(OZB)<EGm}B(b)HBI_Tp)Ŵ= ɾ8ZCw֔&)oF(">qKqvqrRg uibɾCqξŴ9~BT9BBbT9/˸BV"BB.9>B(B.B%31I*.B +B(B25@PBV"B0)#&ioB0),K24B1end5&B1end>2ƹ̹4B0QGpJB0QP> 4B0(3YJ#)B0(3b>BH4B0Vag4B0KV4B2#Q BV0NIGVĺʺ4B0.%$4BbAߡBV0 !,BV0?qEP4BV2PB ep4BV1at6]BV1atHx4BV0pS ϻջB0p[F4B0Uc# B0Ukw,24B013z}KQB013,Fjp4B2qiB"B23B3wkȿ&üӼB&"B2w0U)B&V"B0i}&!B&0it&:JB&&2 /_jB.B2.yB2jEBV"BbvXνB"B2A;B&V"B2F2 B&A0&V6F4BV'2z[fB3Ou&~B&3O&B&&VI_Tp)5Ŵ6D6 4 f4<@4oF4"9K4.9R"9 {3o2c3q ? 4t f4<@4oF4K4אR YT3hc3j ?8\F5w8_oF8aB">8bBK8cBv8dB;M8qB;M8s BB8y'B%V_8h8i; Hv !% O %V,R%S%TG!%VBG!%ZBB)seBB#PB%oFMx>Ky%AWn(eqMsB8>B(euPBU[C(yrxCG|BGB CGBGB CGB%(5;"!B)<:4DBb)"XcBI_Tp;KF ֐! >[K&;oF">xKxvxzRg,|ibCq9EKCT9\gCC)T9/}CCC.9>C!C.C%31IN'CC!C25 CC0)#G06C0),kOU-C1end5ntC1end><-C0QG5C0QP-C0(3Y`C0(3bX -C0l(.-C0GM-C2#A}brC0N-C0$-CbA;C0 KC0 -C2PB ,7-C1at6OZC1atHVr}-C0pS 4C0p[-C0UcMC0Uk-C013zC013f17-C2qaLWCC23`lrC3wkW:CC2w0iCC0i}C0iC2 v&1C'C2.y=FLC2jaqCCbvXJCC2JCC2FCB0& -C'2Q"-C3OEPC3OhxCI_Tp;56~6{ 4@4oF4BK4BRB %3oc3q ? C40 f4<@4oF4'K4kR' *-3hHc3j ? q\4@4oF4@K4AR@ G4 f4<@4oF4@K4@R@ L3hc3j ? 4@4oF4P@K4g@RP@ MS4G@4doF4dK4dRd )4ve`ft'<I_TpV@w%bP@*Kg@u8\Sd~8_oF8a5">8bCK8cCv8dD;M8qD;M8sDD8y)4D%VP8h8i* e H !% O %V,R%S%TG!%V*DG!%Z*D0D)seg*D6D#P*D%oFM >K%Adn(eq4Kv'/RgNibCq9RXTDT9itTDZD6T9/TD*`DZD.9>TDfD.TD%31IlDTDfD25;m$TD*`D0)#a=CTD0),\brD1end5 {TD1end>\rD0QGDTD0QP>rD0(3Y TD0(3brD0*5;rD0[*TZrD2#roTD*0NV*rD01]$rDbA{,TD*0 FTD*0$rD*2PB n9DrD*1at6Z\gTD*1atHrD*0pSWTD0p[CrD0UcTD0UkچrD013z%TD013>DrD2q)4YdTD`D23%yTD3wk[TD`D2w0hTD*`D0i}=TD0iATD2 3>TDlD2.ySYTD2jn~TD*`DbvX=nTD`D2mTD*`D2FTDD0&q* rD*'2$/:TD3ObR]TD3OauTD*I_Tp*56S65 t4@4oF45K4CR5 _U3oc3q ?8\oX8_oF8aD;M8q6<D;M8sLWDD 8ycD% 6,@v8>3$@o o+>@r$DאאI_Tp )C F%y)() mŐD()39D0W)ZX) !:-)!U)F!.)"_)D"_)DDD2)ۆDeD%$Y$<)n$J)]4@ZA)ZKE0T)2o E0T) E0[)w E0[)wE[)fw4[)אO[w$) j>[w$)$gK[(9)(wN>[(9),[K[)0wK[)4אK[)8_> >[)<!K'K[)@5[>B>[)D^\K]K+,?)MoGu EEX+G)|oG EE+t)4oG EE+RN)MzoG EE+B )l% E>>א+)H=M E>א+tb)Iep Eא+()k E*O)p E+)r Eא+)Eא+[)n)> Eא+[)%VkEא.Q)| E.Q) ED%E.Q) E+E.u) E%01I)GF1E E+E0)C#E0))<B E0))][aE1end)iz E1end)vE0Q)K E0Q)ME0(3)" E0(3)PE0)$4:E0)t SYE0)6rxE2 )e. E1E0)\i Eא0Yb) Eא0)7R  Eא0)"2 Eא*;)D@FQ E*;)Rneu E2i)i E2i)mx E0i)_ Eא2i)Ɲ E2i)kt# E2i)k8H E2.y)]c E0F)v| Eא0F)Eא0)@eEא0%) EE0%)[ EE0j%);0; EE0j%)VT_EE0)*x Eא0)IEא0)$E320EY:t_ )}r)F%=)K)ݐoF)Ő9{) )DG|)RXF\|)grF8(tH)(kF(N)P"F(SI) FF(SI)C5-F%(eN)\FF(eN)[-*F%(l)6$ALFF-(()S$hsFFI_Tp Q)Zr)F!=)>K)אoF))9{)} )D"7)yE]7) yE"7)$yEE+) FAGE+tH)#_eE+N).}E+SI)VEyE+SI) UyE%+eN)(ġEyE+eN)/(yE%+l)7ʬ$(EE+();$EPEEI_Tp66 M ̹*`%M*e%e/*f$G*lFG*pFF6I_T1I_T2$^U ^eR/Z2/sM%/t/g&/h/i?=/j/k_/Rg/Cq//_set/}7E`set/7ED=E1_set/7ECE01I/ǿIE7ECE0/=@OE0/A%%OE0/E1>DOE0)/NI=]cOE1end/W1=|OE0Q/`5UOE0(3/i3UOE0/$OE0/aOE0/aOE2 /2=7EIE0w/Va7EUE 0w/=7EIUE2i/\N7E=0i/l`a7E[E2i/7E==2.y/ 7E0/+a1<OE[E0F/2@=U`7E[E0F/BIyOE[E0%/8=7E[E0%/IOE[E0j%/+o=7E[E0j%/ I OE[E0/X-87E[E0/dQ\OE[Efju7E%325:t5_ *`%M*e}%e/*f$G*lEG*pEE6I_T1}I_T2$V} Q4B@4oF4\8K4h8R\8 ?4y@4oF4b8K4n8Rb8 $4@4oF49K4:R9 l4@4oF49K49R9 H4@4oF4|:K4:R|: 4U@4oF4BK4BRB 4@4oF4AK4ARA U4@4oF4\@K4m@R\@ ۔4@4oF4ŐK4ݐRŐ @iOH'3'u@: +>@>E5ITF5+>@B5lwF5I_Tp' I4 f4S@4SRfS f4 f4B@4BRB 4  f4k@4kRk H8:8?\0J7J7_ t@iYOH3 @: :+>@>}ݐGݐ+>@BE אGאI_TpY k`FCd!i\8\8\8Cd !i"9"9"9Cd*!iAAADed!iŐŐŐЮ3mg3c ?I_Tp\8 d+4ѱd4\84E4Ԅy\8R\8YNE$&)3g3 ?I_Tp"9 (4d4"94E4ԭ"9R"9YNE$ 4H f4<@4R* \0@Eb 0DŐCIB!iŐBBŐE0DŐCI*!iŐ**ŐE0DŐCIŐ!iŐŐŐŐE0DACI u!iA u uAE^0DAICIA!iAAAA4z0D\8~CI\8!i\8\8\8\8ElM0D"9CI"9!i"9"9"9"9Y^$$3g3 ?I_Tp9 R4%d494E4R9R9YNE$3Lg3B ?I_Tp|: @4ѐd4|:4E4X||:R|:YNE$jS3g3 ?I_TpB 4d4ӤB4E4kOBRBYNE$73"g3 ?I_Tpz հ4fd4z4E4".RzRzYNE$3g3 ?I_TpP@ h4d4P@4E4ԀP@RP@YNE$*3g3 ?I_TpA Y4<d4ӰA4E4n(ARAYNE$Z3cg3Y ?I_Tp@ b4ѧd4@4E4eIo@R@YNE$&3g3 ?I_Tp5 4d454E4B5R5YNE$S39g3/ ?I_TpŐ d4}d4Ő4E4EiŐRŐYNE$ ;4 f4<@4oF4*K4eR* ,4@4oF4AK4ARA 3hc3j ?+335g35+ ?I_Tp\8^|33\g35R ?I_Tp"9_33g35y ?I_Tp933g35 ?I_Tp|:f;33g35 ?I_TpB3:g3= ?I_Tpz  4<d4z4E4ܼ&(zRzYNE$}33cg35Y ?I_TpP@N33g35 ?I_TpAx33g35 ?I_Tp@333g35 ?I_Tp533g35 ?I_TpŐQc5 TH995I_Tp9999 Rg9|:^I_Tp%''|: h9BI_Tp;BBB ڐ9P@I_TpV@\@\@P@ 9@I_Tp@@@@95I_Tp*CC5)m qB5I_Tp;BBB Qq9^I_Tp9999 $q|:I_Tp%''|: qP@I_TpV@\@\@P@ q@I_Tp@@@@q5I_Tp*CC53&g3 ?I_Tpg 33Mg35C ?I_TpG33tg35j ?I_TpB686=8o3.* LV8IUH ~[L%bL %[LV80 lIy K%. !'[L0m @KI%0 V+do[L!%5(b.yB)&M[LV8hB~S[L,L~DE M!O666EjH!K666E M!777 +Pˑ8(ˑ' +Pˑ\(ˑ%ETh![PvP66EM!W66E9!_PP6KCb|E8Bl+xj$RR p $!%('א  ˑT!%(ˑא p $!%(א'  v{%mRvmmvE84ɒ!&fS[wE:M4ɾ!&Btx  |*{%ZR|ZZ|E4H!&kQC(gI_TpŐE7z .~|EaR Jˑ!%(ˑE$(/*I_Tp058 S/b'8ia '%!%5(5Astr~9%F@F^  JNE M!w^7m^7^7El$lF%Ej$ˑ!%(ˑlFC ez!i777Cp!i7I_Tp7777C!Tz!i999CF!i9I_Tp999(:C`ze!i|:|:|:C!i|:I_Tp%|:|::C7z!iBBBCa!iBI_Tp;BBB J{%,|RJ,|,|JCF z/!iP@P@P@C<\!iP@I_TpV@P@P@@C\z{!i@@@C_!i@I_Tp@@@&A 6 {%fRff  $$RdCC H 0$"RdCCC%DzA!i555CȬn!i5I_Tp*55$DE_8$I_Tp%ET(/\8I_Tph8Cܳ\I_Tp\8CKz!i\8\8\8C`!i\8I_Tp\8\88Ey(/"93I_Tp.9CD\MI_Tp"9C zl!i"9"9"9C{!i"9I_Tp"9"9X9EC(/ŐI_TpݐC\I_TpŐC z!iŐŐŐCs>!iŐI_TpŐŐJ7C:OEI_T1I_T2ŐאE0kŐvCIB!iŐBBŐ "0ŐCIB!iŐI_TpBBŐJ7Ew BRBr/BB/EE;4!&'5Eo-Z-_'''<Eq-rPCI''' SyoR\8\8  I\8Y{$v\8{\8\8\8\8 p!yR\8\8 7[\8Y{$v\8{\8\8\8\8Ei)I_Tp9%ii HR"9"9 ҮI"9Y{$v"9{"9"9"9"9 X!R"9"9 wq["9Y{$v"9{"9"9"9"9E4ɉ{!&*DE&-Z_***<E)-rCI***E$F%E'q$j!%%Ej$ˑ%!%(ˑjEj$ˑQ!%(ˑFG  $!%(א'C?(I_Tp%::C=OI_T1I_T2'Ő5E0kŐCI*!iŐ**Ő 0ŐDCI*!iŐI_Tp**ŐJ7EY{$I_II@I_OI@@@@ Lt@zY{$I_II@I_OI@@@@ (@I_II@I_OI@@@@E;c0k@CI@!i@@@@ 0@CI@!i@I_Tp@@@@&A A0'@]CI@!i@@@@&A 0v@v@{@@@@ 05Y{$I_II5I_OI5555 N5Y{$I_II5I_OI5555 59I_II5I_OI5555E0k5jCI5!i5555 %v05CI5!i5I_Tp*555$D V0'5CI5!i5555$D kv5 v5{5555&2?G ̲u ] !%(א' P4ˑ !%(ˑ8 .x#>  a%LU#;   a%L!%5(jhex!@ @ x!k@!@̲%N!!%('א̲P H!!%(אא ̲ !!%(א%4 pfS!_fSr.fSfS.< _ "!%אא4w p BV"_Br/BB/<4^  pk"_kr/kk/< ^ k"{%krkkE^  k"Rkr/kk/  B%#{%BI_TpBBא vŐW#vŐ{ŐŐŐŐy v\8#v\8{\8\8\8\8 7 fS#{%fSr fSfS E fS#RfSr.fSfS.k7eQ$klQ1>aFlT1J7SDNtx:$'m4 ELZˑo$!%(ˑ'n> D8@4))#4$4b)N9$$443e RD?$'4nE)\4$4nD4$|&%ointw.$bQ"$  %>hF0n% 2G&%G%%EG*%G*% G* %oG*%^G*!SG*!G*!|G* !&TG*$!G*(!xRG*,!;cGR0!G X4!ChG %8!8G%J'''%'v$% RJ'($%' SJ %5(5('v;($% gJK%[('% = JR%w('5(m 1J{%('5(m J'('weJ' J'(''(v' +Jm')'''( a Ji%))v)' ԇJ'F)'F)'(v' wJ'g)$%' YJ'})$% @ J\%)''5(m bJ%)5(5(m վJ')'' pJd%)'5(& ƭJ%*'5(& yJq%:*''5(& J%Z*5(5(& BJl%u*5(& SJ%*5(& !yJr'**$%(v%EJ'*'5(EJ%*5(5(EJ%+5(5(EJ'+'5(EjJ'8+5(5( XJW']+''5(]+vc+h+xtm,K+%@K%%.K%%v?K%%K% %CK%%hOK%%9TK%%YK%%K% %=1K@%$%K'( J',5(ELJ'-,'5('EurJ%L,5(5('EڐJ'k,'5(' KJ',*,'(v5( J',5(5( #J%,5(,v' JU%,5(, J' -'5(, J@%--5(,% _JG%M-5(,%EJ'l-'5(' RRJ%-' f&JE%-5(5(' JI'-'5(' wJN'-'5(' qJR'.'$%' JY%.5(m 5KJ%0.5(m4J5(N.5($%GJG5(m.5(5(4J5(.5($%-J-5(.5(5(J<5(.5($%'y2[2[2v2y,$0 f,܎/%<, G,"/-/E zHN,$I/T/RfSEfSea/l/Eٓey//E%r  ,/%O,EG,//EאzW,$//RBEBy' S,܄0%<,G,0#0Fe00;0FeH0S0F%zN,$o0z0RkFkr./EQ,Ď/0y' אE),/0rF`,.r   , -L :2 =oF ?*"> @'K Aev Bkp OK1Q1qp Qa1l1qw V|11q%3Y3 Y& 111}#13Y3 ][^111}/13R c  111q0]bF mU 22q 103 qq01272}bs XK2[2q 1kb.l o2z2q 1I_Tp%0 :4 =oF ?'"> @5(K Av Bp O22p Q23 V33%3Y3 Y7253@323Y3 ]62X3c323R c)2{332]bF m33223 q_,233bs 332b.l 442I_Tp$%2 L7a4&I<L:%&$L;%&L?$&gwL@%y%WP 6Z *<@ <K \C78PC60~H  68%8VC60N $\C>8I8PC60H n6b8m8VC60  588VCR'N66 ,L78&I<L:;&$L;;&L?$&gwL@%yG% L7-9&I<L:'&$L;'&L?$&gwL@%y% L7o9&I<L:x&$L;x&L?$&gwL@%y+%T :; =oF ?F)"> @*K A5v B5p O995p Q9955 V9:5%3Y3 Yc9:&:593Y3 ]9>:I:593R cA9a:q:5{9]bF mQ::59{93 q01{9::5bs ::595b.l ::59I_Tp'o9 dM_;oFMHMH4RM\;E;5;FM:d;5;;.lM~;5;4M6;;54MHr5;5,M;55 M;MII_TpIHE := =oF ?6"> @6K A 6v B6p OM<S<6p Qc<n<66 V~<<6%3Y3 Ys <<<%6%<3Y3 ]<<<%61<3R c <<<6<]bF m5 ==6 <<3 q<3=9=%6bs EM=]=6 <6b.l /q=|=6 <I_TpI;} :? =oF ?Ő"> @K Aݐv Bאp O==,7p Q=>,727 V>>,7%3Y3 Y=7>B>87=3Y3 ]E{=Z>e>87=3R cH=}>>,7=]bF m*>>,7==3 q1=>>87bs oc>>,7=אb.l %??,7=I_Tp= M_w@oFM`">M`KM`vM'`M_4RM-??J7Y?FM?J7-?Y?.lM?J7-?4MLVY??D74MƹD7?D7,M_@J7J7 M(@MЌ`I_Tp >ZMI@MЮ`I_TpCMm@I_TpJ7-?א_WV BZ Ő<@ <K <@ I<K _ @7K A7v B7p OE E7p Q0E;E77 VKEVE7%3Y3 Y.DnEyE7D3Y3 ]0>DEE7D3R cODEE7D]bF myEE7DD3 qUDFF7bs eyF*F7D7b.l >FIF7DI_Tp7D HRM_iGoFM k">MkKM#kvM/kMj4RM2dFF7FFMD-F7dFF.lMF7dF4MF G74Mŭc7$G7,Ma]>G77 DM_GMАkI_Tp7jW IZ 7<@ u<K u @b8K Ah8v Bn8p OIIt8p QJ Jt8z8 VJ&Jt8%3Y3 YQI>JIJ8I3Y3 ]'IaJlJ8I3R c>8IJJt8I]bF mjJJt8II3 qyIJJ8bs JJt8In8b.l @KKt8II_TpI <M_]LoFMhu">MtuKMuvMuM\u4RM4KK8`KFMrK84K`K.lM K84K4M`KK84MŒ8K8,MWL88 ;M/LMuI_TpCUMSLI_Tp84Kn8IuWX |NZ \8<@ <K - @(9K A.9v B49p OPP:9p Q QQ:9@9 V$Q/Q:9%3Y3 YWPGQRQF9P3Y3 ]0PjQuQF9P3R cPQQ:9P]bF mQQ:9PP3 qPQQF9bs {QR:9P49b.l 9R"R:9PI_TpP M_fSoFM{">MKMvMMo4RME=RRX9iRFMRX9=RiR.lMRX9=R4M/iRRR94M6R9RR9,MhOSX9X9 F+M8SMI_TpCM\SI_TpX9=R49\W UZ "9< f <@ <K  :(W =oF ?9"> @9K A9v B:p OUU :p QVV :: V V+V :%3Y3 Y&UCVNV:U3Y3 ]lDUfVqV:U3R c0UVV :U]bF mUnVV :UU3 qUVV:bs >DVV :U:b.l <WW :UI_Tp9U M_bXoFM">MKMvMM4RMW9WW(:eWFMW(:9WeW.lM)W(:9W4MғeWW":4MG1":W":,MX(:(: +M4XMI_Tp9CZNMXXI_Tp9(:9W:tWs ZZ 9<@ <K  @'K A:v B:p O\\:p Q]]:: V)]4]:%3Y3 Y\L]W]:\3Y3 ]K\o]z]:\3R cV\]]:\]bF mb]]:\\3 q\]]:bs ]^:\:b.l ^@^'^:\I_Tp%\ M_k_oFM">MKMvMʓM4RM WB^^:n^FMI^:B^n^.lMu^:B^4M®Dn^^:4MS#:_:,M 0_:: 9GM=_M+I_Tp%C;Ma_I_Tp%:B^:W aZ |:<@ <K   @\@K Ag@v Bm@p O6bMKMvMM4RMucc@cFMj~c@cc.lMbd@c4MB$c'd@4M{@@d@,MMZd@@ ]4M{dMI_TpV@CMdI_TpV@@cm@lW fZ P@<@ <K fug{gF0SI aFggF0SI fggF%0eN FggF0eN 7fghF%0 fh%hFf0I AF>hIhFf0~H fbhmhFf0N iFhhFf0H 2fhhFf0 ^hFhhFR\@N[ :xj =oF ?@"> @@K A@v BAp O?iEiAp QUi`iAA Vpi{iA%3Y3 YlhiiAi3Y3 ] iiiA#i3R chiiAh]bF mYi jAhh3 qh%j+jAbs ?jOjAhAb.l zcjnjAhI_Tp@h xM_koFM̪">MتKMvMM4RM6(jj&AjFMj&Ajj.lM k&Aj4MXj0k A4Mń AIk A,MA7ck&A&A 8MτkMQI_Tp@CMkI_Tp@&AjAWS mZ @< f <@ <K  @AK AAv BAp OzppAp QppAA VppA%3Y3 Y\:pppARp3Y3 ]$FpppA^p3R c:pq$qA.p]bF m4Z8qHqA:p.p3 qY.p`qfqAbs ]zqqA:pAb.l VqqA:pI_Tp)"p M_roFM">MKMvMMش4RMGqrAqFM8rAqq.lMRrAq4MqkrA4MX@ArA,MǔrAA JMϿrMiI_Tp)C'MrI_Tp)AqAŴW  uZ A<@ a<K w @BK ABv BBp OwwBp QwwBB VwwB%3Y3 Y!MwwwBew3Y3 ]YwxxBqw3R c%Mw'x7xBAw]bF mamKx[xBMwAw3 qHAwsxyxBbs xxBMwBb.l xxBMwI_Tp;5w AM_zoFM">MKMÿvMϿM4RMC x,yByFM KyBxy.lMeyBx4M¿y~yB4M̋ByB,MڪyBB _MyM0I_Tp;CMyI_Tp;BxBW ,|Z B @CK ACv BDp O~~Dp Q~~D D V~~D%3Y3 Y,|~D~3Y3 ]:~3>D~3R c|~VfDp~]bF m%zD|~p~3 q7Xp~Dbs [<D|~Db.l D|~I_Tp*d~ M_/oFM">MKMvMM4RM]"[$D2FMz$D2.lM`$D4M2D4MŢDƀD,M $D$D PMM=I_Tp*CM%I_Tp*$DDW( NZ 5<@ <K D~D0eN /]h~D%0 [WDJ0I D~DJ0~H ~H/ɂԂDJ0N aD~DJ0H /DJ0 \D5;DR5N6/8C : =oF ?D"> @DK ADv BDp ODp QƃуDD VD%3Y3 YZ pD3Y3 ] |'2D3R c19pJZDd]bF m#(n~Dpd3 qdDbs DpDb.l ~qԄ߄DpI_TpX M_oFMM4RME.KGFMZsMKG.lMVgKG4MŸD4MDD,Mz KGKG]L|NZbXk_,|rfw@a4 u ;N/ N0${)0R&tK%{AR@K%{NRZK% ' =$R7Nmamam 3 =$R@Ntt  =$Rb8N8xQyQy < =$R9Nczz  =$;R'Nss  ShR"9NK[w[w ' =$RBN{ * =$‡R\@N[RR 0 kR@NQQ vH /$RP@N[SS =$IRNctxtx z BvRNctxtx  =$R5NE&:N$'' =$RBN{   @RŐNcpp  xLHR\8N8x  suRAN%%EN$%* ݾ (zRBN{  =$RAN  /$R"9NK[w[w w }XGR9Nc > _tR|:Nvss R2 dRP@N[SS X /$ΊR@NQQ . 6$`@C@NtQ l7 J1R5Ng /$R5N "J\%v5(, J,5(,% JN%5(,%yO7ɋ|O8O}4}dvdv4}}};v;v}d z38P52%P9*%eP:*%q0P@*%\PF* %_PG*%HPH*%PI*%/PJ*%JPK* %PL*$%PM%(% PN%)%@PP%*%PR%+%6PT%,% PV%-%!+P]%.%UYP^%/%Pa%0%QPc%1%$,Pe%2%Pg%3%>Pn%4%[Po%5ExP|*L%'~'PWvQ(%EnQ7,awQ8N%rQ|sϻQ}9%QTQ~9%QG%?`Q9%Q9%CQ@%˰Qh>Q%t%uy'*Q@%Q@%Q@%p[Q@%Q@%ZQ%Q@%Q%oQ9%KK M Kx%+Kz%+K{5$-R%֍tG%uy' SƎ%+S %}S!2T%o{Tt+%%%Tu+%sNTysO+Tz%T^%%R9T_9%%<T`%%Tf% %IgTo9%s'T}s6T~sjT@%t%ˏuy'X&TTWs6Ti'sjT%cT֏t%uy'/NdT9%t%0uy't%@uy'Lv@U %vc}%}'v0}2v2v}}}$%};(v2}4v4v}vv' vv$ }$ }' }t9%v{v8 v6v, v=!}=!}6}, v6*v0'v*G%}7v7V4G%@Vbvh]E6V%'LEeuV''WEVW'EVLˑ'};v@v?v@}?}@v$}$v1AvB}BvBvYD}Bv$qWb K%LWc%remWd%(We%qWj|%LWk@%remWl@%WmVqWvR%LWw,remWx,iWy!Xm*qY]ܒ%KY3YÒZ%ܒbWv%]]]OG  GR%GR%uGX%G%v!vn%t%nuy'vt%uy''%FO& <X[.x%~[0~%d[22%%s[5 %8G[:%+[;%e[@%R[A%[E~ %d[G2%(%Y[J,%@[N0%72[P4%~[[a8%#[\a@%F[]aH%I[mG%P%I[nG%T+%T\ @\K%]*G%y! ]e!J]j!+]mG%!,]pG%!]s !d]x*!._]~!]']9%[]9%]9%]9%k]9%~H]9%]9%v%#]s%]%]mǕ!]!|]]+1DREHy!9'!u$!M!y\(RE?J11RE[f11REw1'~RE1%0 g'1[+ME$ޖ11[I$11[+4$'1[I $>'1*R]1'L1Îm11% y  1 WW!P W.З1~'%. ]1%0-k1 1" 0;11L1I K11~W7} 8ZF_XˏZ(_$ZP`Ǝ28;12+BC9ȘΘ12M:17}1aW݊ r~a.݊t%+1.4x<G1%"݊}Wb11L1I}r11WZ9 !F_1TZ911.ʙՙ1%"Z911L1I@11K5:/M$Y$WڸT^IntZ%<}-[9%W `Intf,<}-gN%W@z!ϝ4T}~44.Κٚ4%0tH440N441getZ40640Sm4OU42'$ju44"}44*1IW_44ITG'^:K^El''^f$'' ^l165(^t$>5(5(^|6$^'''B^^$~5(5(8^$11^W6%f ^G6Ԝ%f\^6%'^-5;%N6=*035>@K3595/@[f35131IDX[?5~3595SetIR35953RMm1ǝE53d5N F'ߝE5oQ7WK 9595%'\_1@9595j e9595'37or$}E53qttE53ߣ|hE532ZמݞE536%E5'3O-e$E53^2$6<E536$TZE53v%$rxE53[$E53>o$E536RJ$̟ҟE5) K35(~'E535%    @Ut5'%56q ept5%G  t5z5H1I 5t5z5$& 赢@I Sߠ TU%L Uߠ PG 5?T 5+C 5 ߠ $T $͖ 5u_ zT it55[u ԝU%ߠ &XUU%Max +9&U%0q 0Y5̡ҡ50[ 3!ߠ50 6;ߠ 500G 9tߠ)/50y <-$HN505 He$gr55? gF ߠ5{ smߠ55U% Ť@I S T%L U yG 5?T 5+C 5 / /$T /$͖ 5u_ zƢT y55[u .% &;%Max +%0q 05ܣ50[ 3GC50 6Z 500G 959?50y <@i$X^505 Hy$w55? g%5{ syE55%W, g! $!ҹ Z., 60 \$!;6'%'' vm'Q6'%'W: +2Q 7x!* +T: 6+2 IťХ6+0 g+6+": 66L1I m66/mP+gGEA cm @ sFf   uG:iug6[Y$զ'1'%G.GO6@RA 6%mIjRA-36ZpD%ATZ6FEyr$A{6$|A6mX_R'cmا1GG6IH1I6I^?%6%%!8`%! % ^[u61%%%E6%3163 g%ƨ̨63S2%635ZU%6"^#67L1I;367 Wk-&kz&+'&7W&z&J5(&79 uGUA Ʃѩ7%KS }L;HK @H e=C7.9 TZ7"9 ju7HL1I C17HW ,<U\ _m!2 a. .ȪΪ38. , /ߪ38%2 W38" c 3898L1I c03898W^Yzq!ϝŐT}~lw8Ő.8%0tHlnݐ80NyŐ˫ѫ81getqŐ80SŐ 82'$$/8Ő"}?J89*1I^i89ITA\pkWz!ϝT}~9.ɬԬ9%0tH!א90N 91get+190S:JP92'$`ep9"}99*1I܃99IT' / ]I ȭ|puGU' ȭ9%K%i \ZHȭ(.9.I ?E9"I U`9IL1I -+p9IS vv!p $! r {.U Ʈ;U=w |ܮ;%2{ ;;0n f; +;;0&1\ G$DJ7H2A] _j;$t Xz|;HA[ @|;H%c |߯;H q|;H :|1<;+H &|Ze;94 6f|;n8 q  |;9]? ~ |հ;+H  | ;H/ N |'2;Hl ? |P`;H%U ;|~;H"t ;=HL1It N;=HWV 9ߚ!!0! %!-B\F "ߚ8;'%'.ߚIT;$;21INQit;$;#@};%ͱ!*;.V Ʋ/;'%'.;ײ/;%21IC5;5"V /;;;L1I-[-/;;; _`%_hA;%I _i%_j_c~F;8L;2_fF;%G_lȳF;R;H1I_l׳F;R;Rh6>U<%=$%$%'$%6%46%V$ %j6%_6%D$% 86%$ %<$%C(%Ux$,%0%Z64%L$8U @ B @%glBW9Z!g6T9_6A@10>bT$Ze@49f9s~@c@% Wt)UyI6~46[@Q$''[S4$ 11Wq%$1'5B !'! %!-B6e5BjuAAeA%1IAAA#5BA߿2n b` >uG!6G!:!D=V !e?!2B&@!E !AvI߿@!1M[H!QT!HWv`!\l!_$x!8Vc%|!Hi@!0o9!h&y! }!G!8$!<%!g!kv!`v!$!~9B'$TitDGUD%0  &@D2oFɸԸD&@0&@D2qD&@0<%,2G0ER%KQG0igF%jpG0ob%G0f3g %G0fU %ǹ͹G0 Ӈ%G0R% G0@0%$*G0R] @%CIG0S^%bhG0:vG0 =CvG0FE@$źG0ED/$޺G0gJzCG%0nQn@!,D%0DWe ;EKD0z9djD0^QY9G2A2DG0 +G»ȻD06D%0gM@D''2b?4ID90Ks5GbhD2:}D@2 D92u$üD0~D$ܼD2\WD2DmjD2le֒-8D4909\g4%Q\DͶ22qwD0TgVzCG0G9D0I9νԽG0uQ#@D05j.B D05j(B+1G2r#"FLD0g+6ekG0AD20D2*D2/վ۾D2ˡĞD0O%%G0EV!q6.4D2=N+IOD2HdjD0,L$G*3SD$"ÿDHL1IӿDHW)!@!!@EQQ!&@TE=HQG2@0oF8@agQG"EwQGWG*1I3QGWGDQG%.1,@T1,@2@. ,@%0oF8@%+,@0oF.>@DJD@1getD"2@ciD@setAT,@2@-H+N8@D@"1,@J@*1IU,@J@IT&@߿Woz4!ϝ6T}~/:zA6.KVzA%0tH2AouA0NM6A1get6A0S±6zA2'$;zA6"} zAA*1IJd!,zAAIT Wlzi!ϝAT}~doAA.A%0tHjAA0N AA1getGAA0S9AA2'$Hl'AA"}7BAA*1IVaAAITi9iWuGf9AHf9A@mviA%G'$iA'1'%G9)Wq:!@!ӾEQQ!TEx]G(B0oFB]G"E]GcG*1IT]GcGDA]G%.1 :BT1 +:B(B.<G:B%0oFB`f:B0oFR4B@B1get(B@Bset :B(B-+{B@B"1:BFB*1IT "-:BFBAITWozo!ϝLBT}~juRBLB.RB%0tHcXB^B0N9LB^B1get_LB^B0SLB RB2'$"-RBLB"}=HRBdB*1IL\gRBdBIT.vA1{EuGfLBHfLB1IXBLBHU23LB%63.9LBL;9XW]LB<:oLBL;\)!&AB! h%!9i!!j .DHL;L;U/IH%O10;HL;*Sn f;OUH`%rxH"lHHL1IlBHH[&[ e''.rHL;L;TuHLBtx o%0HHU|CtoNYHHA[lowHH%l oHH%.oH+H]? oH+H*o%0H9 q oNYH94owHn8*YHL;*?{mH+N̸H$"HH*1I y HHio+6H%?C m " c 8 +W' ! 0T' bC'.{4 bC%"' bChCL1I bChCmW2!/>6T5&1nC10>9}($JUtCzCfcnnCiSynC%Q$7 - 4 O  uW-_ wm!.-_yxD.} xD%2Q<!,xD'0NMCEKxD;aIStrxD7B!$C!d%WK fd_N%!+O%!Q6TKD%.a#4D%0-86!D3IT6;D2L~'UD"KSepDDL1ISDD7e|  -G=DWo&Cz&O&א&7ITW6&C$z&O&7IT, W' F$b $ITWEIK[M`6nEK,;,W $/ 5$-s9 1^]} %]} Gmȝ]ITo]W&z&E&7IT,Wy&CQz&OKIE&7IT,QouGf}IIfI1IEO$IIIQI%a3 WW%$%&@a3Y#G@`8CG%֤e0`kGn83$&$GGa3GGH1IGGidifGGfGK$)HG'1'%G=XG%,dA33!q0$!s%(fGG.fG'1'%KL_RiG-lD'c i'G%݈$A!M f݈grGG.݈G'1KZ%3G2  G-3G%i$-A3f"-GG./>NG'1K6xRouG5G%{. jALA!T0!lG!'$ !nm%! !%! %f{.#GG.{.l4DG'1UTvZeG%NvGmKFE$G$00{Q'G0a |1G0}E$G2~/,7G$0s %%PVG2(^CkvG%0j5G2wPG0Qa{e%G2DmG%05Z% G2\!(3G%=EG3WW!RlHT}HD֤AV}Hn8"}HH*1I}HHXV }H% WW!RlHT NYqHD֤wqHn8" qHwH*1IqHwHoJqH%N$uG.N GU#.G%K5'_O_G%%}G"NGHL1IlGHg@ 4+ 4't($0m 0!F_!$.'t(.HK5' O_H%% }H"'tHH*1I~UHHFH%D v\)! \FTD  %H'l a >N%HH%  <8$h%] $%C R61$*q gL61i C61" v6'O< t&7111  "/&7'+ hO&7'9 j&7+Hf &7HaG X69"D %H1H*1I i%H1H"+%H%|> vvf>&1CHIH.> BHCHu e''t O#CHHA[ CHH%c CHH CHH J,7CH+H Z U`CH94 $~CHn8 q 9 CH9]? - CH+H x CHH/  "-CHHl(  K[CHH%U OyCHHJ 9HQCH%VoiAȭp yQtfp IITp*5 In8)E I%Q QG$q%: $SS u%'' F'' %D %%% D'' 4%8'/^ .'W% eI%m% U%D d%%9% D%' d%%]9%)*'w0 v LU$$%$% +3$%$% e $I$ & '_F Fs($u$w_*${|\$% ݗ IT6^ .%IE%:%%  ITpZHNq' _ ZH9ITȭpZH9q'E cITp@Ir'  $ITp$DDs' I%9?uhAu1'9FQvhAv X%98x?y8y D%D9c? {j: {K$[zC (P$rzCg'9cFQ|j:|2'9{FQJ!CJwޏ7 c% r eIC,@% X +0%E̗$+$% )$A%{ˑ[%&7 J]yITo]]X1&7z"&1&7q&ITא&7 )$$%d!5&7z"&!5&70W&-IT, &7 v$C%V'9[FQ@޾OLIE%6:w6 \$%%% %%wVE.6IT'w $~~'hGw85w1I$5_}|:55b|:,{sH.*''vw<$v&OIT,E&7rQ&aIT,E&7&/IT,E&7 !'6ZIT1,IT2,EExw1%z7'% A%hA)'{36'٩SITv;61!V$zC0{Xb65 b"`= d QF'm؞p {g9|-07g$'F)$'ȶE'''$mk$''R$'''5$4?/u$>%- y0Qp6!4i]-J>y =6J-6WV7#q69'''\6''{$"5'%JCF'R|0G$j'';m6'?!$'$'''ң'5(>$''$O 6v U J''11$Č&6d+OvX65(%ox5('5{<$%$%$%&7{$%&7 ^%''&7'1^%''&7#2+nQ''&7z"6=#l'&7 '''':S ''''-^$%5('&7:< ^$%5('&7#21)5('&7z"GpD5(&7 X m''5(5(4&>6IT%:4s56IT,E# 86va6'%y {j5%'J@&{6(% 6?n8S Rn8v&r''%q6'%615wak '''8L;D '''%%%%91 ?''5(5(%9 h''''ط ''''%‡ U%''U%U%U%v %''%%G7w!IE%6%%: k:$I%1|:{8u%%%&7[ݖ%%%&7z""K%&7{KV%%%&7\D%%%&7z"2%&7^$%$%$%&7z"x$%&7pNSIT9SIT@?SITV@k6G%1K8 %1%$4(i6DIT*Dy,K]Gp%A \QImZ ''q,/{[ ''*~v ''[+  '' I'' r'' 1Q9''''9 (8 )6' , ''^$%|:,4#^%|:5ByQGO% \QIX[kC%-PmL6'kH`^%|:52Kk,^$%|:,i1 & ITpZHNq'*&d0ZH?ITȭpZH9q'&,lITp@Ir'EV%TrV@ޓsV@Ea%%& &($ITp$DDs'cμ5.;U%y*Y ۋkk%62Y 7f3Y  4 Z yr aF\\í_Y3Z ZDZ F[UZ 0`\fZ o]wZ s^Z _Z 7|`Z *MaZ O-bZ cZ W6*dZ FeZ x"f[ i%k/m[$u[96a)7p)7)7)7(Sm d[ Dn u[ n!1[ t{la{$'L]'R'Tȕ'I 5V'/pW[ /ZX[ ./wFQ%R%\ BPwDP{6xDP"7Uss_ෛ<+Y4]!5`1<55/eLW5'35oz53h55$3u555(3,;55'355!535b!s5IT5&6s5IT5n8rjs5IT25BRs5IT5 =s55@IT5*Os5\gIT5(٠s5ITj5z $s5IT5?s5IT5Gs5IT5qs5*IT55s5FQIT$54s5mxITX5h1s5IT5;s5IT5 s5ITN5^fs5 IT5s50;IT51s5WbITD5Tjs5~IT5Xs5ITi'5s5ITJ5Z{s5IT5s5%IT'57qis5ALITy5ps5hsIT5As5IT;5K s5ITt5s5IT5{s5IT!518s5+6IT05s`s5R]IT54s5yIT5^s5ITY5i#s5IT5Hs5IT5.s5 IT5As5<GIT 5 s5cnIT 5Ts5IT5ts5IT5Rs5ITQ5a(1`V%`%/(1` 7%3>`ј$0;7%H1I`#J77`̮%_`%/`7%B>`$ 7%[y 7&nnk2eQ'&7&52w/{3  \4 %I g%^o6%Pr%%%*s6 %0t6w<d~\8'%'3H rb83LC'b83R"%b83>U'b83-BX$'b83[3$,2b83^$JPb83ma$hnb83da'$b84Ňk 6'f0i\8%fw\8n81Ih8\8n8Q* ~ %8xQ*$ * 8b> I 8n837%n8a l 8%3F%  8GQ*  88H1I 88W7!@0$!05A.7   99T7 #  9$0C D$< B 902H M [ a 90-BG'z  904'  90!9   94*^)k   95*1I7   99f   9%97 B IT5( 9e9_ j IT 959  IT 9א0I#c9  IT 90Yß9  ITG 9 0&6@9  IT 9n8!90 ; IT 99X c IT> 9b0@9  IT' 9559  IT$ 94~19  IT,  9*O9  IT 9( $9# . IT 9R9K V IT 9 =9s ~ IT 9k9  IT% 95@9  IT 9٠9  ITj 9z?9IT 90T9>IIT9 9IG9fqIT 9q9IT 9 4[N<\F!/\F! ! !Z{í!e$!y/$!$!:D9!3.rqkv9%0tE'903w *'90թ{'90C8'90R$ 90j"$*0903S9IO9"_911''9+rB%9Run729$ 9"99L1IU99N<iuGU;`KVV@%~tzV@MV@<9HV@W: v!K;!qQM;!.O;.:   ;.mX ) ;%2 >I ;;0n;bm ;;0{M;;0P ';;+|5; ;*< ;;*_XC  ;;+1RG4$%;*H9? ;":ROZ ;;L1IRj ;;rv }uGfr;Hfr;1IEMH;HUv;%tZv"-;HA[;vK[;H%cIvy;Hv;Hzv;+Hٗv;94zv(;n8 qt vFQ;9]?nv voz;+H v;H/X v;Hl? v;H%UWv;H!_3WWO_7Q % W%W_Rd6%>_S&@%3_TH T!H8.!'H68Uܗ;%H%֤FIl%Hn8*."HG!_V1<HHH1I_VKHH,W uGf,&@Hf,&@1IPH&@H@=W&@%֤XW&@n8g|"uG!/6! !Wc !:v!N/$![(!e$,!`0!h&8.gV @''Ub @%03t'zC0թ'%zC0R z0$>DzC0f3+ %]czC0f0 3Y%|zC0 5 g%zC0: [Z%zC0@? %zC0D >%zC0R]I %  zC0FE#G$6 < zC0E&%$U [ zC0 ) t z zC08i M9  zC%01I9  zC+S`8%p:  @+S`;j:  zC+nPp [9!!@%*-D0!;!@$*w xO!Z!@9* n!t!@N"|!@Run} !!@*,W!!@*Zv[!!@W^46$!9?c]$ "9xiC$'"9nCL$A"9esH-$["9Ȥx)k$u"9*= X_""@6* #p""@"g""@+HL1I"@+HO}$8aF$#אא!$;#, eg;\#eQ''&7Nx#eQ'&7"$#'' #'$''55- #$''אאk 0$, $''"$L$5(5(j= 5($''eeQ"Q"|6"/D(_$W)$uG!F_!D$9G1Run%% %G0^T'"%(%H0Tgd/zCA%G%H0l9`%f%H0Os@%%%H0KyG%%G0<ON%%%H0ERT%%%H0iYÉ%%&H0o_2%& &H0f3dV%9&?&H0fi%X&^&H0 lad%w&}&H0q5%&&H0@v%&&H0R]{v%&&H0~_%&&H0v''H0 v1'7'H0FE`k$P'V'H0E$o'u'H0gzC''H%0i9''H0Dԝ H''G+O\V@''GV@*G.,(-(G'%11*leA(Q(G11+n,@i(t(G%+VD((G+RcG((H"D((GZ$((G%*]()GA*"G¼) )G"D0);)GHL1IK)GH$Iv+vfI))HHfI))H1IZH))HHt\)))HHA[B\) **HH%c\)9*D*HH \)b*m*HHr\)**H+H}\)**H94\)**Hn8 q \)++H9]? \)/+:+H+Hg \)X+c+HH/6 \)++HHl \)++HH%US\)++HH*\)+H%%\)vWwO w,  'G, 6^,% 6u,%m' >c,Yg% Cc,Yg%7@$,n80J$,n84:O1-1n8E1,-15O2 F-5?N&O_6g-IT'5H&O 6-IT5(e 6-%''8 -''''} -'''' $.''11}!} M.''11( v.''!5!5}.R. .''!5!5 U .''5(5(} .''5(5(oJ /''U%U%KhQ)# C/''%%u&OL6d/IT,E9@c{/1i7/|:59/|:,j 6/7K#$/17kU'6k53$kl{$k$kǠ͞&6kx6k ާn$k^6k{0$kk`ko+$B$ p$b6%dkj^$ X X n'Y *Y M;'Y +8Y <IY ׻PzZY P^.kY P|Y }SY 3Gv}y}\Fvyv}aF}\vavv}~1v} @a 2sa"%spa#a$1Ia:qa?=4rtaF3aKa2%CaL֍%M<aM aR2%aS%%"eaT%% BaU2 aZ2%Ca[֍%M<a\% Ba]2ab3%Cac֍%M<ad%5ae%%af 2 %aag 2al%3%am%c/an+%asG3%8at@%%au% azu3%a{%Ga|%%wa}9%saG4saN?2sULaVa2_rta^2sah2s+ao3sPav%3sNa~G3%/a@%%aA%% aC%%a72 t%4uy'91a+2#bU&4v,484% Ac4rcc4snc4sH`c!4%%c#D4%K=c+ܒ%c.%%i=c144%4v4v4v4vFvjGvoG}44vGv}Gv}v4151v}}}wHvvv}}vy8=a568V5v[5abiuK5v$}'v}5U%}v}v}5%}/vŤ}Ť}'}0vo9};v;vH}I}HvIvIvRJ}I}RJv;}=v=v"I}WJviJ}I}K}iK}Kv\Jv[Z}5K}wO}Q}[Z}\JvZ}[}o_}Zvo_}X]}]vʤvtX}Yv_}X}Zvt_}_}$vg}<6vAv v?}?vvV}Vv[vvaFv=}?v?v_}`}_v`}a}`}av`vc}Ebvc}d}0d}j}cvjv7vv77}7}7vD}SFvSFvj}k}jvk}Zl}k}_lvkvm}mvm}n}n}t}mvtv}<viG}K87vI}iGvv}}vI}#Kv#KvIu}v}Iuvv}v}v}vvvv3x}dwv8x}$y}Oy}W}8xvWvv } vAvq}qv }v} vv}}vP},Rv,Rv\}}\v'}ʀ}'}πvvF}wvK}7}b}o}Kvovv}vv}9vȭvv } v9v99}9}9vU}(Wv(Wvt}.}tv?}}?}v3v^}vc}O}z}}cvv%}%}%v\}1^v1^v}A}vR}}R}vFvq}vv}b}}}vvv|vvvv } vͱ};vv9}98v>}} -W%n;4E!Md%;' MW%;' MW@%;'EAe;]]''jdivWK;%% W4* <' W|$<@%@% W^%?<'' Wi'_<''' Wa%<'''W<''w>Wv%YWx<9%EW%<'5EW@%<'5%EtWG%='5% xKW%.=' OWl'N=*5(' {We%i=*$% W=,, W$,='ERW,='5%E WN%='5%EWU%='5EWW\% >'51f3> m w ݯ , g7X>%g9%%#g:%v3>7Eh> Z  J   e   >i2% #j>%j>%_j>t%>uy' j}? ] X P    Dv l H  . ~ ? + 4 s  W 49   k7?!k9%!$k:%!Nk;%!k<% !Q4k=!1k>?!k?*!Rk@?v>v}?v@}?vv v&@vWv߿}!@v&@v!@v}vV@vvb@V@}V@}b@va}ocvocvl}&}lv7}ڟ}7}ߟv+vV}v[}G}r}}[vv@vv@@}@}@vh}xjvxjv}g}vx}}x} vlv}Ȭv}}}}vv} v4}4viv9}iv}v)v})}v"p}qvqvŴ}}Ŵv}3}}8vv}v}}˸}Ӿ}vӾvv:}:vv?}vA}AvfS}vB"9v+w}fSvB}Bv0w}Bv;vB;};}Bv5w}xvxv}F}vW}}W}vKvv}v{}g}}}{vvz}?CBvK~}zv6vP~}6vm}vvv$vm}C@vU~}mvk}C@vZ~}kvd}CP@v_~}dvu}v}uvC*}*}Cvd~}vv}S}vd}}d} vXv}v}t}}}vvv/}D5vS}/vvc%}vvvvC}}CvX}vv}HvZ}}}r}$vMvd}>}}}d}Mv}}}v}a}vVv}$W}CXv}}$v}}(v}v`Z}}E,v]L}E\8v}]Lv.אv/v|N}Eb8v…}|NvZ}F9vDž}ZvbX}.F9v̅}bXvk_}KF|:vх}k_v,|}hFBvօ},|vr}FAvۅ}rvf}F\@v}fv/vw@}FŐv}w@vv}-}Lvi}vt%Guy'}Gvva4v}a4v u}:GAv} u}v}vA}-%uGmv{GpgiGvv}v}dv6vi}v}v3}L1v}QvQGv$vv}}vW)}}W)v}v}$}v}v}THvvv}+Dv}vV}8v%},vo}v}6};}v\)} ,}\)},}vv },}Wv}}}}v}QvQ}V}QN'WIrN'N' fIqI B II BII B"II I2#II I II IvJJ JIW =J__pvDvDXJcJ cJCJDwJJ cJEJJ cJ JJ JːJJ BJJ J%IK%K %K%QG59KNK b@%Xl%oKCloKvzKR K/0tKK0%vR&K/AKKA%DCR@L/NKKN%X L'L J__a'LvD2EALVL VL%,Lv~pLL L%[Lv;v];LL L%LLLv^DgDLM M%MLL?;M:M L%:ML{NMsM B1IsMpIhא(MM I(1MM I1MM I1IMpI p!N__pq"N&N &N__a+N5 ANVN VN% I jNN BpAh__sA'JNNNɋϋ NN J NN J__nh OO B0O__sՋ)cOۋՋ__n) O__dd*__sd'__ndh77O__p7s7OO__a!O6__b!O6P__a!K6__b!K6=P__a!7__b!7LPcP L V8P(!P__s'ˑ8P(!P__c%ˑ};`;PP L__n9%}v}6\'Q__a!['Q__b![6Pv7c8AQiQ iQ*!BJ8*!DJ8,Q{Q__a!W6Q__a!_Q__b!_6P8QQ iQ*!SJ8W!SJ8*!UJ88R*R iQ!v*!x89RaR iQ!*!vEvRR R__ca%aRv}RR Ra+xRRRRR GRS S1[ Sch%<%MS<'cMSv}~qSstqSSSSS F1*SאSS SrhsIS3595SS BST B'0T__s'__c%?TTT 6%cTxT xT%AHTT T%GTT T6̨TT TTT T~ UU E$U/U E2>UIU EPXUcU EnrU}U EUU !@%UU U%qHUU U%}H# VV V9'V2V 2V91FVQV QV9eVpV pV9VV pV%VV VzCVV B% VV V%CH+W%W %W%Ht(9WDW G(SW^W ^WH rWW W%GhWW lH@WW lH9wWW WGXX lH"X-X WtA{aa a__n >VAaa aA%,aa a ;aa aA0bb gaQ!b,b W;bFb WUb`b W͹obzb Wbb W bb W*bb WIbb WbIT6c!%(n 6c1 ;cˑאiVcwcIT% _valswc|c:7Mcc%}ccIT% _valsc|ckcc 5`}eZ dd dd@cTed!%( L ed 'אeydd d7fdd d__nczdd d8߄dd d9ۏde e__nv:)e4e e CeNe V]ehe Vwee e__n X: ee e:ʙee e__n :"ef @i 'f!f !f-C5fMf Mf__n Cjaff )[|% fi 'Hff )[|% fi 'Hff )[|% fi '+H<g5g )[|% 5gi '9eIgog )[|% ogi 'n8gg )[|% gi 'Hgg )[|% gi %H gh )[|% hi %H1hWh )[|% Whi %9khh )[|% hi %+H`hh )[|% hi %Hhi )[ i} %i 'H2&iYi )[ Yi} %i %HHmixi xi4Bii i__n VB}U2ii iinCi}i9%ijIT9% _valsj|ci1jIj Ij__n *TDmf]juj uj__n cz7{jj d__nxl Sjj A;I Ijj A;SI%Uj k  kp44k3k  k%;1BkMk Mkq4aklk lkl1kk Mk%ekk lk%kl *;te'9%msg'Al%2-l8l 8lLlWl Wl3kll 8l%ll Wl%Gll l__i l?8E8VIll lP8womm m8G"m-m lHmamammm mit XMn38mm lHnn e__nNnIE%v.Nni.% .%: bnxn xnpLBRBunn xn%;nn L__n,nnIT, _valsn|cE;o)o L__f%?o`oIT% _vals`o|c55Uwoo 2V|oo d__nHx0oo pVsoo 2V!o|^9!p|c9Åp6p d__nTZHpSp 2V*bpzp d__nHSpp p__i pjBpB`Upp p{BBpp p__i pBBe qq dd$q/q dD>qIq IqB=rq! bq!b%|qqZHvrqqITpw ZHD: Nq '=q!  r! %ZHqr9vq IrITȭpZHw 9D: q '=mr!  }r! %wr}r@vmr9rITpw @D: Ir 'fzrr r__i r3C9C6ss s__i  sPC5m84s?s ?sVC=hs! X|s!X%$vs|sDvhscsITp$w DD: Ds 'ss spAAlst t__i tCCm/t:t :tCoNtYt YtCSnmtxt Ytntt tC}U~tR@N L =t >tttvGS4vtu utu-u -u__i 2u~DDFuQu QuDeupu pu E7nuu t__i uCWuu gauu gavu$uzC@v9?uc@v u%ithAźTv_v Wnvyv Wv@vyvv{%mRv m: m__f vw9FQvc'w'vhAJNw%w %wEL9wQw Qw__i VwEE}+w{w!&fS{w[w=ww w,7>ww w%d`ww w%>73`wx w+ax x  xP7b4x?x ?xh7/Sxjx jx?,oxEא}0wx!&BxtxNxx x__i xEEyxx d1zxx diP yy yEN,y7y y/OFyQy x}…yRb8N8x L =y >yQyQyvy$yn8z98x?ycz y%itx8Zz0z 0z__i 5zF FIzTz e\cznz en\}zz zFZzz z4[zz 0z}DžzR9Nc L =z >{zzv{${9t{9c? {ct{  {%itj:< {{ V {{ VD{[KzC[{[PzC?&{{ ^Wu'|| ^Wi%-|8| V%G|R| ^W| |f %i %[ |j %| |H+H9|9v|}{%ZR| Z: Z__f |V,}O} O}__p UK T} ::4X}I_Tp9__aM}__pM9WaM}(::OZ}} }3FX}} }__i }"F(F]}~ ~__p \K #~::=_a~I_Tp%__aMa~__pMB^aMf~::Xaz~~ ~PF_~~ ~__i ~?FEF|~~ ~__i ~\FbFt~ !f6  !fyx/R R__p MwK WBByI_Tp;__aM__pMxaMBB{ DC"c __p aK s@m@{d3I_TpV@__aM3__pMcaM8@m@fLW WCek __i CC5 @ۨҀ Ҁ__x C ] FAfq'J J__p :pK OAArI_Tp)__aM__pMqaMAAt FFsŁ݁ ݁__i yFF!g __i FFT'2 2@FQ 2}Z~*q!&kqQ+j __p hK AAkI_Tp@__aM__pMjaM&AAe e) W,?VIT% _oFVDj __p |~K DDЃI_Tp*__aMЃ__pMaMՃ$DD>  w__p =K אI@JI_Tp__aMJ__pM-?aMOJ7אdBcn nF@ __i FF}ŐHI_TpŐ__a(__b('(Ő J7J7?4__aM4__bM9J7J7ZaMd  x__xed\7ax ?x}g~|E__f .aRą J!%(nJˑу %DW,A A%D___x)(>Ox__x) > __x)yE EX҆ __x)X69R   [6wR(  II_Tp0__r(/I5+J]h h6| __x@BGאQ1 MkwJч lk__a8s. BS. .%BW F%ti~ *;%w _% ^BJЈ __p IK t8n8/L6I_Tp__aM6__pM4KaM;8n8QOr r__p PK w:9498SI_Tp__aM__pM=RaMX949/Ή , E~Z d% 8 8-B=HL;)T_ %Wuq F%q J__p :p8rЊ__aMЊ__pMqA iWfd% 0- -,Fn2DY i%0h Srhs>95 [&0ɋ S;ڋ S%x'  [e& [5@ [mXfpD3g .*__ak {  F7'̌ ^Wی 8/$RE  VL' Lv<S Sb8'S|__a!w^7__b!w^7  kp~4m__n$%!%(n$__f$lFˑ( B6( ?sh?c %37NY sfhs B}P~R'N L = >ssʎ F__s'  F1 א2- 8l-AX Wl__a8sXG1lw Ix  %;EǏ Ǐ%7lkۏ %7=!i777A!i7z7:z7|!i7I_Tp77:7|7 J %uɐ ɐ%8 Jҡ 5$ r=sam g=5i9 sv9 t u v55/ Ñ Ñ5ב Ñsam g5Ci9 sCv9 tH u/ v/55?\g ÑQv r% %L9JÒڒ __p IK__aM__pM4K8S pA,D D bI@49;R"9NK L  [w[w-/RfS v,fS&TΓٓ p}0T/, ٓl/,+ %R:Q r__p PRu__aMu__pM=RX9V O}%” ”%:=!i999!i9z9:z9N!i9I_Tp99:9N(:]bw ~% %:>!i|:|:|:F!i|:z|::z|:e'!i|:I_Tp%|::|:':V;R O}__p UWv__aMv__pM9W(:^ ~__p \^Ŗ__aMŖ__pMB^:wٖ R%  %B!>6!iBBBc!iBzB:zB!iBI_Tp;B:BB~ mF|їܗ | ~}օh4RBN{ L =4 >9J;v>{%,|RJ ,|: ,|__f Jx R__p MwKyߘ__aMߘ__pMxB 2Fc $ __p acH__aMH__pMc@Wb\q % %@@>!iP@P@P@!iP@zP@:zP@/!!iP@I_TpV@P@:P@!@`i5J %-Yn n%A_>!i@@@\!i@z@:z@{!i@I_Tp@@:@&Ah F=g-8 {gGR }R\@N[ L = >RRV@v{%fR f: f__f 4l  :t12 2[9zCtC‡oR@N L o tQQrl t}0#0, -;0,М -%Oj  __p hj/__aM/__pMj&ACN NC}_~RP@N[ L / 0SSʝRd__x $ʝ__y %ϝCC/ N' dk  ҀFRd__x 0F__y 1KCC~_t % %D~>!i555"!i5z5:z5A$!i5I_Tp*5:5$$D8C CrDWn __p |~z__aM__pM$D> w__p =?__aM__pM-?J7j__x)$K__x),KX'> >__x)8F#R] pun|I_Tp%| E Ǐ;k kɠԠ Ԡ7l 7n mE!= Ǐ__p mDDFm__aMm__pMdF__nMF7m __pOl__n:lO̡ Ԡ%lۡ Em  %o. m%I=H uWb ɐJvq| |85w 8Jˢ __p mIIK__aM__pM4K__nM`K8w4 __pv__nvOEZ |%{I_Tp__r(/{h8I_Tp ]\\8Σ!i\8d\8:d\8!i\8z\8:z\88!i\8I_Tp\8:\888vLW wf{ %~ pzx8} PФۤ r ] ^9H#. .v9QB^ r__p mPPR__aM__pM=R__nMiRX9ǥ .__p__nOإ %I_Tp__r(/.934I_Tp ]\"9a!i"9d"9:d"9M!i"9z"9:z"9l˦!i"9I_Tp"9:"9˦X9ߦ . .%݈5 5p9IT 5r9cFQ|c''|j:v4\8v4"9>Χ w__p m==?__aM__pM-?__nMY?J7b.S ?x__pa__nxaOdy  x%I_Tp__r(/ݐI_Tp ]\Ő!iŐzŐ:zŐ*!iŐI_TpŐ:Ő*J7b>S ?x%ibz ujp[c= w27I`ĩ w__a8sĩD7@aة  x__aZV7C IqDI_T1I_T2__pOŐ?ODאVCXc pRNc L = >txtxECIB!iŐ0kB:0kBD0lŐDc0s$vICIB!iŐI_Tp0B:0BD0ŐIJ7ՋՋ__nIRNc L  txtx/۫RB jxv,B0y' K,אZRBr/ B: B /Uit O}É ”u .:`Ǭ ǬF:V۬ O}__p mUUW'__aM'__pM9W__nMeW(: ;` Ǭ__p׊__nŠOq %  Ǭ͋ĭ Ǭ%\ӭޭ ~֓  :s&1 1:]Ea ~__p m\\^__aM__pMB^__nMn^:ʮ 1__p__nՔOۮ %  1. 1%Fv49c^v4|:}wmx Rۿ  Bx˯ ˯B5߯ Mf )[7x/ R__p mMwAw,y___aM___pMx__nMyB!s ˯__p__nO %!Ͱذ ˯ ˯%29{FQJc'2'J!CF[ Mf%sv4ԤB9v4zv4P@bα __p maac__aM__pMc__nMc@7 7__pϟ__n@OMb b%@v 7Š 7%v4԰A$q̲ J__p m:p.pr__aM__pMq__nMqAZ,Q Q__p(__nB&bep  m bX 7/iͳس  n   ,A + +DAi?[ __p mhhj__aM__pMj__nMj&ABĴ +__p__nOմ  %B +( +%p7L J%E[p p%AO %Azv4@~ǵҵ   *D% %BDf9U __p m|~p~[__aM__pM__nM2$D. %__p__nO϶ %. % " %%$1< IjKV Quep -ub Ij}SvȷR5N L =ȷ >ͷ Ij%v45P&v4Ő5@ &OZ Ait tD tk puǸ `߸ wD (!&'(5__'-Z':-Z'<'3N'-CI'-r':-r' __p*Y''O'FX'$%|'4%|'__a%|F<,%__r%ːX''$'4'__aѺ'$'4'__aѺCI' F$%'4%'__a%eu1I I__i N.G4Gbm xio| xicܻv\8{\8\8:\8D\8__nPR\8v\8o]Y{$v\8{\8I\8:I\8DI\88SN$R\8v!\8μY{$v\8{\8[\8:[\8D[\8Jݼ 8K__aM8v$ $8z8C dpI_Tp9%__ap__buiilJ __n cI]kKɽ__aMɽ__nM`K8wݽ __na vB49)?R"9v"9HY{$v"9{"9I"9:I"9DI"98SN$R"9v!"9Y{$v"9{"9["9:["9D["9Q) )F9RF__aMFR9Ze e|9y duQ r__n cP]tRӿ__aMӿ__nMiRX9ρ .__n}% !&* W_*-Z*:-Z*<% yR9v9D Y{$v9{9I9:I9DI98SN$ R9v!9 IY{$v9{9[9:[9D[9VXc c:W__aM€":& L: eqV O}__n cU]pW __aM __nMeW(:!: Ǭ__n \R|:v|: Y{$v|:{|:I|::I|:DI|:8SN$6 R|:v!|:U ,Y{$v|:{|:[|::[|:D[|:];F F:^c__aMc:9w :) ez] ~__n c\]y^__aM__nMn^: 1__n ?RBvB Y{$vB{BIB:IBDIB8SN$ RBv!B Y{$vB{B[B:[BD[B[x) )BeyF__aMFB>Ze eC.y !fx R__n cAw]y__aM__nMyB ˯__nv4z dI_Tp;qB:qBDqB/xG L Rzvzk Y{$I_IIBI_OIBB:BDB8S$ Rzv!z VY{$I_IIzI_OIzz:zDzUep Mf{ __n (z}K~RBN{ L = > $I_IIzI_OIzz:zDz3> MfMe Mf}4 RP@vP@S Y{$vP@{P@IP@:IP@DIP@8SN$ RP@v!P@ WY{$vP@{P@[P@:[P@D[P@cfq q@d__aMŽ@ @ 2b __n ca]c__aM__nMc@ߠ/H 7__nZj FjA RAvA Y{$vA{AIA:IADIA8SN$E RAv!Ad aY{$vA{A[A:[AD[AHqp{ {Ap J__n c.p]q__aM__nMqA8 Q__nRr__aMAw(3 3 BgGR xi sI_Tp)__r(/sA I_Tp) ]\A !iAzA:zA !iAI_Tp)A:AAZ" Q1F Q%Xm m%]Gjp J pƵ  Q$R@v@C[Y{$v@{@I@:I@DI@8SN$}R@v!@Y{$v@{@[@:[@D[@ j Ak__aM A_" "JAO6A gaiPl __n ch]j__aM__nMj&A  +__nR5v5>Y{$v5{5I5:I5DI58SN$5`R5v!5TY{$v5{5[5:[5D[5 D__aMDK HD;$ C>3O __n cp~]=s__aMs__nM2$D  %__nvŐ{ŐŐ:ŐDŐ__nRŐvŐvY{$vŐ{ŐIŐ:IŐDIŐ8SN$RŐv!Ő Y{$vŐ{Ő[Ő:[ŐD[Ő> 87e>1 w__n c=]d?U__aMU__nMY?J7bi ?x__na n7?__aMŹD7db ?x__n__at7?__aMD7e(3 dFCIŐ!iŐ0kŐ:0kŐD0lŐDc0s$wCIŐ!iŐI_Tp0Ő:0ŐD0ŐJ77CIŐ!iŐ_0'Ő:0(ŐD0)Ő"0*7J7@KV ndep uj}RŐNc L  ppd ujc ujh uj__x7Z'C __p mpd.s__aMs__pM__nMKG pu[ pu__p) D pu__p))& t%5J pu%kI_Tp' __r(/kא D__x)__x)0KI_Tp9%__a__bii .`hh__d>8o!%( L o tאא __x@r__y@rDאא pu4__x)* __x)FFG.Q Q__a*pV__b*p[444oz >__x)4K __x)__y)__k)א   4 4__x)79EEntI_T1I_T2__pO\8?Otn8CI\8!i\80k\8:0k\8D0l\8Dc0s$CI\8!i\8I_Tp0\8:0\8D0\88}CI\8!i\8Iu0'\8:0(\8D0)\8"0*}8L %wy }R\8N8x L  z  K'2 lHD\ QV'V\n8s~ a* D H3Dn8GI_T1I_T2__pO"9?O49o7CI"9!i"90k"9:0k"9D0l"9Dc0s$CI"9!i"9I_Tp0"9:0"9D0"9X9CI"9!i"9\0'"9:0("9D0)"9"0*X9 4v"9{"9v"9:v"9Dv"9CN 5%]h 5RI_T1)I_T2)__pOA?OAzCIA!iA0kA:0kAD0lADc0s$GCIA!iAI_Tp)0A:0AD0AGACIA!iAŴ0'A:0(AD0)A"0*A+vA{AvA:vADvAbs  P% i}ۅHcRAN L c h%%| ip JA* p__a8sA۵ __aZAIC,@%]3!&*3D{j_*-Z*:-Z*<u%3N*CI*-r*:-r* __p*Y'*O*CDX*$%|*4%|*__a%|D,%__r%ːt*$*4*__a*$*4*__aCI* F$%*4%*__a%8__n$%Y!%__c$%!%(n$__f$jˑ%!%(n$__f$FˑvQG v@ @;0 L<v+jq0n%:7c$%+ch%Ac%os&7[ITo]xJ]< L__p]y!sX!osX&71Is&Ios&&71s/&Osos&O&7אIT/&os&&7אch$%%sdosd&7!5#s&#os&&7!5M/&OMos&O&7IT, /&os&&7& % F__c% _   '5S'HIT _valsH|c5zU^s _%,  `%t%uy' }IT _vals|cV4!%( L 4 'אt%Iuy' }9eIT9 _vals|cIIT _vals|cאt%uy'}IT _vals|c$,}G/<]ITG _vals]|c }>V~IT> _vals|cbt%uy'}}IT _vals|c -IT _vals-|cn8t%Buy' }2^IT2 _vals|cB}IT _vals|ct%uy'}IT _vals|ct%(uy'}@DeIT _valse|c(t%zuy'}jgITj _vals|czt%uy'} IT _vals |ct%uy'}:[IT _vals[|cO'%__x'%t%uy' }IT _vals|ct%uy'}IT _vals|ct%4uy'}$*PqIT$ _valsq|c4"\uqאא< [(oә BpDh-ch%C2|nAL i1^i XYx xnp~LB e% e% %9V59[FQc'5'@oI^ s%:m %zA   a%Ԯ a% % %H84? 1xNY hs 5 p~ e0 e QV W H,7 %K,F^ %K/^2@+r} }D@J }  ,@i /2@ ,11"7 %Fa lHI_Tp%__a(__b('(%::IE%EVL6vL: lHu" @EV 60,, `;S V3 Sn8t%huy' }XQITX _vals|cht%uy'}xIT _vals|ct% uy'$}(IIT _valsI|c t%^uy'?}NzITN _vals|c^t%uy'}IT _vals|ct%uy'>}?IT _vals?|ct%Tuy'=}D;pITD _vals|cTt%uy'C}bIT _vals|c 2V[  V&+6 ^WG,OR %&^i ^W^,; %' ^W & ^W^& ^W}i' ITi' _vals |c"!, `Estr E1t%Zuy'}JvITJ _vals|cZfd%buf9%t%uy'}IT _vals|ct%7uy'}'StIT' _valst|c7t%uy'.}y%ITy _vals|ct%uy'2}LIT _vals|c6-Bc61t%Kuy'4};sgIT; _vals|cK}tITt _vals|ct%uy'&}IT _vals|ct%1uy'1}!MnIT! _valsn|c1}0IT0 _vals|cst%uy'"}6IT _vals|ct%uy'(}]3TIT _valsT|ct%iuy'}YITY _vals|cit%uy'}IT _vals|c}:IT _vals:|cf%NY ^W!h @BD$  @\%\%\%t%uy'}IT _vals|c7ch%u,XTj jx o55>< L__fU%h x 559( I 1 I' _)y'!5#[, \u[q`}k5( IT5( `/e}'IT'7_I_T1I_T2'__pOŐ?O5^CI*!iŐ0k*:0k*D0lŐDc0s$CI*!iŐI_Tp0*:0*D0ŐJ7DCI*-r*:-r*j5!i* uj*:*__nEjJjMyCI* uj*:*+b ?x__at7}t'uy',Yg%0}t'uy',Yg%0/: E IT V&cn ^W&} ^W' ^WgY{$I_IIBI_OIBB:BDB6I_IIBI_OIBB:BDB>xCIB!iB0[B:0[BD0\BCIB!iB0kB:0kBD0lBDc0s$CIB!iBI_Tp;0B:0BD0BBF|CIB!iB0'B:0(BD0)B"0*|BvB{BvB:vBDvBz RBN{ L  1I )[FH{ ;) [s aFH ;  aFH ;| UD= UD /2@&1 V@K aZe mt  +6 p~6 TS sp~A :B1%0 V$LI$ %[f ^Wx [30f SrhsD95 lHY &@Ը  lH%= lHY &@LLW W|fd%Y@'fd%buf]9%K eA%@G%d%610 ^%dBW W%Gu-n %G# ]Ol'3l1r ^O'31k  lH'2;D5 M  ]`~$\ g  9v   T   WOf'3f1g' g%-   O/'3/1MY3 %3$E ]  aFH;1l w  lH   lH۾   lHh   uje #_|:$_5} #b|:$b,~ +  + D2? [  __n cd] __aM __nMKG<   pu{   pu__x) ')E    __a*p __b*p FF6 * B  v)B EV y  y __a*p~ __b*p EE6 str.*'m    7E    __x/ OE[E;\    6>Y )  ) 6zY= H  Z\W b   $Zq   ) __x); 6=    __x/ __p/iUEt% uy'!}   IT  _vals|c \/Z-B  %vQ\ \?Gup{ \u I}RAN L = >.CI u!iA0k u:0k uD0lADc0s$CI u!iAI_Tp)0 u:0 uD0AAkr__aMŞA Q__n__aB mg m/(BG/: IT lH} GpIT  _vals|cT  V% dkey_1R"9NK L / 0[w[wT-8 pAG_ vBR_1\keyy/y11t%uy':}nIT _vals|ct%uy'}3IT _vals3|cQsrc't%auy'3}Q}ITQ _vals|ca( `lHZH' G QV"1%g 9 lH| ; , !v @ lH| ; i % lH  + s*5 )z{%uR u: u__f ü  lHxc$$ $$|;%%$i%%/G lH/3$Yd Fy&ՉD&IT,E&7oIT,/&ڽos&&7|&EIT,/&Qos&Q&7E)IT,/&a)os&a&7E,S/&OSos&O&7EIT,/&os&&7E/&os&&7ES/ME/IT1,IT2,/EE5WI_Tp9q9:q9Dq9/xG [Y{$I_II9I_OI99:9D98S$Y{$I_II9I_OI99:9D9JI_II9I_OI99:9D9>CI9!i90[9:0[9D0\9CI9!i90k9:0k9D0l9Dc0s$60CI9!i9I_Tp909:09D090(:vCI9!i9t0'9:0(9D0)9"0*(:v9{9v9:v9Dv9X } e}̅LR9Nc L L Q=ep e^I_Tp%q':q'Dq|:/xG Y{$I_II|:I_OI|:|::|:D|:8S$$jY{$I_II|:I_OI|:|::|:D|:`I_II|:I_OI|:|::|:D|:?CI|:!i|:0[|::0[|:D0\|:BCI|:!i|:0k|::0k|:D0l|:Dc0s$CI|:!i|:I_Tp%0|::0|:D0|::CI|:!i|:0'|::0(|:D0)|:"0*:C?v|:{|:v|::v|:Dv|:_NY ~hs e}хGR|:Nv L  ssP e!I_TpV@q\@:q\@DqP@/xG uY{$I_IIP@I_OIP@P@:P@DP@8S$Y{$I_IIP@I_OIP@P@:P@DP@I_IIP@I_OIP@P@:P@DP@9?VCIP@!iP@0[P@:0[P@D0\P@CIP@!iP@0kP@:0kP@D0lP@Dc0s$PCIP@!iP@I_TpV@0P@:0P@D0P@@Z CIP@!iP@l0'P@:0(P@D0)P@"0*Z @ vP@{P@vP@:vP@DvP@t RP@N[ L    SSԽ ! lHL!I_Tp@q@:q@Dq@/xG !Y{$I_II@I_OI@@:@D@8S$>!Y{$I_II@I_OI@@:@D@z?"I_II@I_OI@@:@D@j?"CI@!i@0[@:0[@D0\@"CI@!i@0k@:0k@D0l@Dc0s$%#CI@!i@I_Tp@0@:0@D0@%#&A#CI@!i@0'@:0(@D0)@"0*#&A]#v@{@v@:v@Dv@8## av#$ a;$R@N L /;$ 0@$QQT$l$ i35l$1o$$!&@ t__i $QΊ$`@C@N L 6$ 7$tQ@m%% :t__n kd%I_Tp*qC:qCDq5/xG %Y{$I_II5I_OI55:5D58S$&Y{$I_II5I_OI55:5D5W&I_II5I_OI55:5D5?&CI5!i50[5:0[5D0\59&CI5!i50k5:0k5D0l5Dc0s$j='CI5!i5I_Tp*05:05D05='$D'CI5!i50'5:0(5D0)5"0*'$D'v5{5v5:v5Dv5(R5N L ( $(B8(C( Ij1{(R5N L /{( 0(7C(( Iq(( Qu__n J(Qmc,(( (xDZa)stra)v%$z7cposh1w)str'(%i%=)! B)!B%%))zCv)*}A*D:B)sumC%iD'hAd*str'Fp'ch'*e*'msgDA*^.n%).n%E** R__c3%**+**J`!+++JZ+$Cr++ ]++ ! ++ @! +, @*K*,),9KV8,C, b@),~_,i,8,zx,, b@i,M,,x,,, b@),, %W,H)-;- %W;-%H*X-o- %Wo-HD*-- %W-Hm*-- %W-+H*- . %W .9*(.?. %W?.n8*\.s. %Ws.9+.. %W.+H:+.. %W.Hc+./ %W/H+,/L/ %WL/%H+i// %W/H9// XV//W// 00  "60|i9 0N00 V{+#6 G{<{# +#V{>+#e{]0:(0'"0|n9P*0q1 V{[; G{<{# [V{[e{0h0 A"1|s9*11 V{@ G{<{# V{*e{I["2|x9*022 V{E G{<{# V{e{|22-|e J )e# )e# e23 V3H+3B3 VB3H_3v3 Vv3H[33 V3H_33 3333C#4&4 &43f+4Gn8JZL4V4K}TBr4|4TV744VU44UU]44UJ 5(5K\ JD5b5J\ *K~559K\ }T55T\ UPP56U\ Uv,6J6U\ Vf66V\ VL66W\ 6ITvxS;Ʈ67 )[%60v796H$x 7$PH$(zm/6R 6z7lw I8Fذldls}/p:RFpM)\ 7w 9Fذds}/:RFM)\ \ 6.9L967\ .!d99 %% 0N!U99AN0NɁ!9:AN0N :AN!\ RfXzN1::afkf6kfaf6zf3f0 fjfjfPN:;ffd6ffd6ffdP fff:N3;;ff6ff6ffp ffg&N;<gg6gg6(g f fWfW:g6f@N5<<IgSgT6SgIgT6bgofT fftgN<=gg6gg6gf ffgqO7==gg7g g,7gKf ffgN0O=->ghD7hgD7hfD ff"hOI>>1h;h7;hC1hb7Jhf ff\h~O>??khuh7uhkh7hf fTfTh; O[??hh47hyh47hf4 ffh@p[?X@hhh7hhh7if fKfKi?Tt@@&i0i=i0=i`0is&i0Lif ffm00 AAmm7m 7mC l7 XAm l7$l l;A-mE XB.D 8%BF  8TF MΧ8اTO\ LL F__s'C+LPL Bph__nhe`Q7`QgUQret68Pat' h 5aMԎʎKLLhLMBL45L+L[NMNtNjNICMI$$ M'T3_NBtqI@#&NItLX#LL:wBRu`L@xNBL5L+L[N@NN6tNjNI@CNI$$VX+O^a3aOB qIa#jOI Lj#L^LwBRud3PBqI#OIL#LL*wBRud3PBudqI#ZPIudL#L=Lj wBRu`P}X~qg} BqI#QIL#LL wBRu_\ 1v;# RG;eQ ;'A<'mos<&798=[0i>'Pj?5cPa IWRPwPOa LR"Oi 9] t :$P DRPP; :$P FRPNPz :$a Q] _ XRS___cP pWSPwPO LS"O 9]  :$ __cP P0wP+ :$ΪSS m%it 0MnStSdVS,TSCl 0^Tml$ll TGm  1TVml 6ll-m* 0Z3Zs' (Gk';T Y#TeTz ]  .Y1>'0 n-Z_Z _Z98rdZF;L;Z,@ %ZZ-Z7ZDZQZ e  up ZZ [[bgF 6[l[!ba b#Tb#T[[VzCp *[[ Wu vv#T "v 1v,bg \5\;b AP#TFbU  Q\p\Ub& AP#T`bӇ0 \\obF AP#TzbRP \\bf AP#Tb0p ]!]b AP#Tb @ =]\]b AP#TbS^ x]]b AP#TȻ !]] lH% X@OH^@Xh] lPDH^lhsl'rhsl'm]  Z^r^ `r^9H^S^_Z^d^`^*` _^_d _ r] \ \ u__ `____#s? __$ `__'__#@D`lhs5(rhs5(]*>.D`lhs.'rhs.';Y 3RY FY ] ^B0`lhsB5(rhsC5(] ~Z4astr[a!&[a4!XV\5T!W]5!_Yp\{anY!qII!WI-fI!_Y]anY!qII!WI-fI!9`11a b F__c-%C/v P!fss{ bfstr|f!}01"end~0D"36V|b"l(Sl}bS!WIlfI!_Yo~cnY"rec"Xr~qg"dech'#cԎE#ʎKLE#Lh0]#a0b]#a0b#I/sdIqIIWI-fIN2dN#N#qI3dIWI-fINH3VeN#N#N#N$J3eJN׃NN'$3`eB@$qI#eI@$Lx#L|$L$1wBRuc=EfBqI=# fILD#L$L#%SwBRuc3SfBudqIS#fIudLY#L6%Lc%hwBRucq\ 1cfg&b g/g `V)/g5CgYg _pŐgkugHjg!g,gv%$&bS$,gS%WI$fI%K',KhL%L&O'@h"O%-9] :h3:,hB&qI:#hI&LC#LW&L&`wBRuc4gz+oiMg&Cg&3diB&qI#+iI&L(#L&L'wBRv\ +i4'X~qS'g4'3,3jBudqI#iIudL#L'L'wBRuczr] \ {Wjoj d__n xBjk 2Vi%eojwo'dVd((d((o@kkoM(ow(Hj`JHkajM(Wjw($$zjxKjj( _^ kk d__n 2Bkl 2Vi%6p+lHp)d[di)di)Spllp)bp)kJlk)k)2$$pKp(p0* _ %^ /ll E%O@ mao QVKC*{Nh*Q2&**ΣQQQ~*`g +l`]l +3`/nnBE+qI`#5nIE+Lf #Lg+L+wBR_3m( /nB+qImH #nI+Ls` #L+L3,wBR_3/BQ,qI#oIQ,L#L,L,wBR_soo vB%i/os QV0q%-{J-2&i-|-Σ~- g-l ]l-3 / qB .qI #pI .L #L+.L}.QwBR_3  /qB.qI  #JqI.L #L.L.lwBR_3!/B/qI!#qI/L'#LQ/L/7wBR_:s`1I/s@ '0yWŦ000ayWuyW4yW~THC0X g'y0aoX ]soy03x WsB0qI #sI0L #L0L#1wBR_3BA1qI#sIA1L#L}1L1wBR_7`sct 2V i8%1eo 8Wtwo2d VdR2dR20ojDPB{tdu V{R , G{<{w2 V{2 e{2ojDuo2po3op( _&uoE3|sos_o3zze3cB|uIv V{@ 1 G{<{}3@ V{3@ e{3o)vp3p4odvo4szzK4DavFw WuX vvc4X "v4X 1v4{ &w{4 {4{ L{4y{ #{4duxt&t52@D^w'x WuBp vv5p "vN5p 1vm5{Zx{5` {5y{` Q{5iduxtvt5,@x3@@xn8E4`xx 2V5y Fyy5 y6 y<6,x3Jxn8O4x?y 2V6y Pyy6 y6 y6eoi[yywodVd# d# 6p0yyHpd4 [d#,d#,Ѵyy y @zz z=@8z=zyX dyC7Xz7XX~q8g?8_z8X_~q8g?8hA{`9Xh~q8g?8o{9Xo~qZ:g:v{;Xv~q;g;}"|P<X}~q<gP<vS X|SS<vS |Si=S=vS |S=S=vS |SR>Sj>vS $}S>S>vS6( W}S;?SS?A3Z}Bs4qIZ#}Is4L`#L?L?owBRuw3oE~BsqIo# ~IsLu#L?L#@wBRuw3~BsqI#~IsL#L6@Lc@wBRuw33BsqI#~IsL#Lv@L@wBRuw3BsqI#qIsL#L@L@wBRuw3BsqI#IsL#L@L#AwBRuwXr] \ \ La y%p %a!+p= @ iL6AvSX STASA7vS< /SASAGvSUx bS BSEB`vSe SmBSBpvS~ ȁSBSBvS S$CS^C3 rBCqI#9ICL #LCLC@wBRuw3 BCqI#ICL #L DL,DPwBRuw3 `BJDqI#'IJDL8 #LlDLD`wBRuw3P ׃BDqI#IDLh #LDLDpwBRuw3 NBEqI#IEL  #L0ELREwBRuw3 ńBpEqI#IpEL #LELEwBRuw3<Bs4qI#Is4L#LELEwBRuw3BsqI#zIsL#LFL?FwBRuw3*BsqI#IsL#LRFLFwBRuw3BsqI#hIsL#LFLFwBRuw3BsqI#߆IsL#LFLFwBRuw3BsqI#RIsL#LGL?GwBRuw(\ \ a ۇp.;\ m$@mRGO@Pz `/- Vii % Sj %qGnlj @n5n*n#es/ee /ƈG @ip % Sq %Gnq @n5n*n#e/ee`|9Z!>x @T  |qG| (}}|GG RGooe#p$ eee3He eRHeRH3Zvd0>ZYvP(ދY('YjHSU SWIUfI```^HӋYHHYHYYHyY# Y?;^^^+^@^U^j^j`5;= Ffmt= 'Hm`Q> HeD $+F $I Ze &Z\^ "] "] r^ NYa^ ,S Vދ^ ^ H,ڍ Vڍދ^ ^ H7Dg V| gZ HZIZI"] ދ ] $^ 9Q0ҏ|p ҏթq 0JCr 0!J`:q 0`?Jn`:|}`jJSE}SJWIEfIJ`Gr `Jn`Go}`JSY S!KWIY fI!K"] "] "] "] 9  WiJ%SK%R|9xΒ]|l|4K{( {Fb(iUbGK1AP\#TC=]|C=l|C={|uK8|CH $G|KbCHZ!bKaCHbKbKh|{` ߑ| L|+L׏` L?LVLnK@nL5n L*nLe/ee|L| 1-|eJ )e)e|Lo ao%Mo  oNM sG ދZ "] b ln ] du-ݒ Mf  ؔ )[FH ;i 'Mf  hfMfM&f  5fM?fM>  WMMΒ ~/NݒMp ē   H;. QNoNN N FQN9oN,N UN!^  yC 'ؔA0!SR! iSNWIR!fIN3! ߕBsqI!#IsL!#LVL0O!wBRvR!w!^ !^ !_ !\ !wstrr w8l7s 6! s COX! ~qWOgCOI!t IxOPitu O!pu OWI!prfIO(!v K3PZ! ZPY"u kh7P?"u NWPa#"w bPabPI#"/IqI#"IWI#"-fINQ"22NPNPqIV"3fIWIV"-fIN["3NQN$Q"NFQNYQJ"ȘJN"׃NNnQF"" aBqI"#(IL"#LQLQ"wBRug!"\ 1"{Қ &713 '"lMY 'QcP" PwPR":$"D 0cP" QP3RwPKR#:$*I#0 IIP.<lh. 1lcq._ Y._ ..m. (vS.dSS.N.pptr]3.%x  .. x$ w. /̷/ ^/ "^/^c/_ 6 //#/5^#/M^ d@^Ud S#/?S d2SUd5/_ Z@/5y [C/,3$jdy(o5^C/\M^d@^d SC/?Sd2SdU/_ YS^/ dSd95/ [_Y/nYqI/IWI/-fIfJ/ Nx/ [^/ f^[/jS/(SI/6IqI/IWI/-fI@/=5 [3I%d/`  0ҟ_0P Sesrcd'Ee$eCpe\If*eS0`ӻSeWI0fIe_Y20gnYeq^0(yw^f^7f0(3f7fO0@}k"Of09] 0Oq^0a׼^^Vf03Vf0O00 ` F09` 0W` K S@1e0 Xcwdn _11ouff31@BVqI1#IVL1#LIgLxg1wBRu_:1B153B1owBgqIB1#=IgLN1#LgL!hs1wBRu_31&oBqhqI1 #IqhL1#LhLh1wBRu_1l` 111\ t%y'17 [&0h1 h1 ^1 "^/^Mi1_ 1(jaii3r2@YB-jqIr2# I-jLw2#LLjLyj2wBRus12532HBjqI2h#IjL 2#LjLjH2wBRusY 2 rkhIHrLY4#L[rLrh4wBRut33533BrqI3#IrL3#LrLs4wBRutq^3X^Qs^is33Qsis 4O344 BsqI44#IsL:4#LsLsI4wBRuo3n4FButqIn4# IutLt4#LsL t4wBRuo3R4\ U4s# [4VtS4(StI46ItqI4ItWI4-fItY4 X@rTthst4L4 XwBLt5L+Lt44X(t u3*5@BVuqI*5#IVuL/5#LuuLu>5wBRo445348XBuqI4P#gIuL4#LuLu5wBRo3 5 XBvqI 5#IvL5#LvLJv5wBRo(5\ /P5>x [hm8X^50]vS^5(S]vI^56I]vqI^5I]vWI^5-fI]vɋ58ڋv35;BvqI5#NIvL5#LvLv6wBRu_ɋ59ڋw35;BwqI5#IwL5#L&wL;w5wBRwɋ69ڋNw36;BNwqI6#tINwL 6#LcwLxw6wBRw#6:ڋud3#6;BudqI#6#IudL)6#LwLw86wBRu_55X55#5!6\ ݞw@6 [w'JAx\FX^6 xʭwx ݭKk6@y YLxLAyOk6 N"Oxs69] 6hO7ByqIO7#IyLU7#LyLyd7wBRu_j6X?B zqI6x#I zL6#LzL{H7wBRu__Y6{^nY/{L6{BL[{5L|{+L/{66{C{{37@2BWqI7#IWL7#L|L-|7wBRu_66536{B@|qI6#I@|L6#Lb|L|87wBRu_360}1B|qI6P#I|L6p#L|L|#7wBRsY7}`r}h} 7d7B+}qId7#I+}Lj7#L@}LU}37}6Bh}qI7#Ih}L7#L}}L}7wBRu_37{B}qI7#tI}L7#L}L}7wBRu_^66`z7\  7 %1W77$L7` 8` 8`  84str're'8)ǕhH8` 1^ `84&^^g8^o8!^}^~o8!^h8` ] Q!%(n4Qˑ'e} J__c %_98&_^8_^&8qCV85uo e8 %-~69t$gR8 RK~vR_~8.R}~vR~8Eą85~8<8<9&_~ _,919^ ,9^ ;W@9&WDR9` _9a !]`9|]Dy^5~J_C~fa'k?b'1m\Fs9}9 ` 9` 9$a 99W` ! !AB\FBD5J !%vDy9ppJ(e\F9@P@c Z :AZRZ0:B_ @;:`C%KA:]_ :BqI:#UIL:#LL:wBRug:^  :Ia :da ;:&&J:xZ53U:4OBqIU:#ILX:#L>L`:wBRugU:za n:\ :\ ::P ::P;}O)7I;JI~;4$ ;4Ԩ;4I;4~II/;g3/;]BqI/;#IL4;#LLTG;wBR_/S;>rS;.D8S;W;  ЁW; MΧاЁ`;\ l;\ ,:;\#3GNeQN'osO&7,S5T5FY_5;)GneQn'oso&7;pC @P; QPP;<cP;QPTwPm;:$;9$cP;]iPwP;:$;kQPR0Q@;kQPR ? Q ? cP;(bPӂwP<:$i1/<kQPwR0Qs,@<os:3: ;_V<@J_SV<XSLWIV<fILU_m<<>d_Sm<MSăIm<6IăqIm<IăWIm<-fIăcP~<@<PwP1O~<"Og<9] H=( PwP=PJ=XVPLPPR= 0P$PԄ_=<:$cP<L>^ >"] zj>HOjjRjF > 8jd$>Tdd@I^ S%8ȳCzI3`@BzqI#IzL#LLوAwBRo2L@AL-H+W W%\__m84Lv  v %aLD M%L  _.@> S>I+ S>`Y`>g`>  vlj`>H #?lj> M>p #?/MM>L?#?LLS-? FZ<z? cXzZ?h?cNJXh?~qgNJaL?pL,?x???|x? An{? g֍Q{? $Rϋ R RS>r] ?\ ?\ ?fM?'' c'!aY'msg\T`?0!}c`J`?P!D*`jS@SWI@fI!@܌!@|ccP$@h!PwP 7@:$_:@!_._cPB@!nPՍwPOB@ c"OՍK@9] \@:$!__|AcPO\@!o-e!|ccPb@!P-wPUu@:$_x@"_u_͎cP@("yPwPO@ n"O@9] @:$H"__?AcP@`" Tl`"|ccP@x"PTwP@:$_@" 6__ɏ@cP&@" Fޏ<"|ccP@"PޏwP@:$O@ oe>@|ccP@"PwPm@:$_@# __ŐcPA#PwPOA "OA9]  A:$8#__7AcP#AP# L1A&bM1Ah# 7^nk1A#Uknj1A#jjnMA ^udkAUkudjAjjud!@A\ 9a''#-B\n#F0H#|c3cP&?F[<s?|cQcPOT#oe#|cgcPvv|ccP&ZF'<O|ccP#b&bM#^k$Ukj($jjMF^kUkjjj?RmPwRstRPwRuT\ -ossb15vA$%str'/@$end*P{9 3"Ox$msgTHcP-F*hPvwPO-F ]"Ov6F9] GF:$*__FcPMWF*^ΡkWF+UkΡjWF+jjΡMFI^udkFUkudjFjjudEFWFF\ jFta '0+V e\FX|\F37bF|ccPFX+P7wPF:$_Fp+_΢_+__LGcPGcPG+)G&bM)G+^ak)G+Ukj)G+jj,i',_YKG,nYKqIKG0,IKWIKGH,-fIK`G`,*`mGa cmGx,ccx,|cPvG,PPG:$G,8G&bMG,^kG,UkjG-j5j3G-BUqIG#IULG0-#LLͥGwBRud3G B qIG#PI LG#L LM HwBRu_MH^`kHUk`jHjuj`-HA ^udk-HUkudj-HjjudFKGH\ PHjv ' $H-|\Fl0yYgH  YsH;3Hh-Z BlqIH#! IlLH-#LLʦHwBRkgHsPlRHP ' '-|\Fl/ 0yYH-  YH;3H-!o BlqIH-#6 IlLH.#L L9 IwBRkHsPlRIr' .g| \FL 03PyY'IH.  Yg2I;NI`. {ç`.|ccPTI.P{wPdI:$dI.F F.|cbdI.(ccoIdI 9 IqIdIIWIdI-fIzI:$MI. ^kI/UkjI/j j3I0/B5qIIP/# I5LIp/#LWLy`JwBRud@cI/a`cVc/|cI=I/I&b3J/BqIJ/#ILJ#LL-JwBRwM Jd^@k JUk@j JjUj@MmJ^ikmJUkijmJj~ji3J$=BqIJ#ILJ#LLԪJwBRuSMJ^kJUkjJjj3JBudqIJ#IudLJ#Lu\LJwBRw'Is4PuTRuNIIIJ"] AJ^ J\ ! _msg`5r2/`I+# 0&g&00Yvy&h0#?oy M0#?/MMHL#?LL#-0XF6<b0cb*cX*~qpgaL~pL< >0aN&b|D`bO1ar(c(c~IO gI(qIOI(WIO-fI(b:$3b81aBqIbX1#ILkp1#LұLwBRuc3a`B!qI#'I!L#L6LcwBRuck`kvjjjvr] \ \ \ JK'q''xc$1'$"%"1msg:XpK;#&npK|ccPsK1P&wPK:$oK1<ų 1|cKcPK1<lA1|ccPK2PAwPK:$K82<ݴ%82|ccPKX2PݴwPYK:$:Kx2=:ZyPx2|ccPK2PywPK:$oK2=]2|ccPK2PwPK:$&K2=F<2|ccPK3PwP-L:$@cL83=J`cMVc83|cL=LX3>ٷ!X3|ccPLx3PٷwPU,L:$,L3>u3|ccP2L3PuwPBL:$&BL3>F<Y3|ccPHL3PwPXL:$@cZL4>`cVc4|cgL=gL 4>()q 4|ccPmL@4P)wP}L:$ML`4>^źkLx4UkjL4jRjL ?L&b3L4?+BqIL4#ILL4#LۻLNwBRu\*O^k*OUkj*Oj0jAO^DkAOUkDjAOjYjD3O?WBmqIO#ImLO#LLOwBRu\MO"A^¼kO"Uk¼jO"j׼j¼pKLLދL^ 4z"msg2TM539=335|cNcPN054{g05|cNcPNP54+P5|c-NcP@c-Np54`c_Vcp5|c#?3/MM(VLhY#?LL-V@>3F<Vh>c3FWiW cXiW ~qmgaLGY!3pL`YyW1YDYYyW>f5v1W>$11>18W> VX> poMeoX? 4Yt$gRX(? RvR H?RQvRsXEW`?f{5*RWx?$9RCR3?RRSW?g5W((W?g7 (8W?5}6I3W@@[6BqIW(@#!6ILW@@#LHLzXwBRu~2L X@AL"XD("XA56g(S(L+XX@#;6LLL1Xp@#;LLaLcX5pL({XW=Y Y\ hY\ ԜrY2>/r%@>sss ~Y@s@9I+e Y@7YgYAm8v4Y8A#?84Z MZhA#?J8/MMAZL]#?LL-WZA9F<WZAc8ZZ c~XZ ~qg~aL\!)9pL]Z\\YZAtW:!v81[A$1u1A1[B V8\(B poe;\HB :\t$gRE\hB RZvR|BRvRi\E'[Bt:)*R'[B$9RCRBRRP*[Bu:PP&a[< 8[t;#q'A['QA[!QQ QA[Q*QA[!VQ>Q`OA[!` P>P* G[t<#u'G['2QG[!mKQAQG[ZQQG[!EQQ`OG[!\OOb[Cv<r[((r[(Cv> (18r[HC5=Ic3r[hC@c=BqIr[C#)=IL[C#LL\wBRu~2L[@AL[D([A5=g(S(;L[#;=LL_L[#;LLaL \5pL#\\\\ ]\ @]FstrD FTqD $C FmE XCEiG 'IY]G >IqIY]IWIY]-fICchH '8.]"N p?N"D:]"|ccP]DP"wPO]:$c] De ?crc D|cP]8DPP^:$.] K B@ND] |ccP]XDPwP^:$^U @!9^|ccP^pDP!wPN0^:$8^ Q Aq8^ |ccP;^DPqwPN^:$^^"[ A^^"|ccPa^DPwPt^:$(^'` A3Z^ Zc^ ] &Bcc1^ |cP^DPFPf^:$c^ W Bccy^ |cP^DPP _:$(_Db BD|ccP,_EPwP<_:$<_(Eb C#(E|cb<_HE(cc8I<_ CIqI<_IWI<_-fIR_:$&R_pEc DF[<spE|ccPX_EP[wPh_:$3h_Eb DBqIh_E#YDILq_#LL_wBR[3_b EBqI_#DIL_#L-LZ_wBR['_47]Ek @Em]&bM]Ek E^k]FUkj](FjjM_ k F^k_ Ukj_ jjY]_\ 1_*M3H *M@FMI T`F(LiJ %6p_FJ FHp,d_F[dJdJF*K /My_`FL uG__cP`FSGPwPO` HG"O `9] `:$G__ acP&`0GL GF<0G|ccP `PGPwPV3`:$&3`pGM ;HFv<pG|ccP9`GPvwPI`:$I`GM HG|cbI`G(ccII` HIqII`IWII`-fI_`:$&_`GM YIF-<G|ccPe`HP-wPeu`:$3u`8HM IBqIu`XH#IIL~`pH#LLawBRu[3`HM IJBqI`#JIL`H#L#LE+awBRud,`HM sJ7s`2>&`HL JF<H|ccP`IPwPV`:$``L &K`S`SWI`fI3aM KBvqIa#eKIvLa#LLawBRu[3aM LBqIa#KILa#LL awBRu[`k`@aIO RL Na&bMNa0IO L^BkNaHIUkBjNa`IjdjBMaO M^xkaUkxjajjx_a\ 9498Y0KPMNI8xI@NI3I@MBqII#MILI#LL*IwBRo2L@ALH-5\ 4gK7NNCgMg3INBgqI#NIgLI#LLIwBRo-\ B NOIT `/OIT5ahZ''hZ AmZl"$J]ZmsgLbOb|ccPb(JPwP b:$_b@JP_/_cP"bXJ{PPwPO"b pP"O+b9] dW^k>dUkj>djj6czcgs%c \X_%c `_B_)c_~_zcM@Y~cM4gcMMgDCg3cN3YBdqIc#XIdLcN#LL7dwBRvc\ McY^kcUkjcjjzQdY~Qd ^d4gMad"HZ^:kad"Uk:jad"jOj:bcw^}d\ 11j ZZIT `/ZITאB d#Z_ V0Nw_ _dHN<[`c_{_d__`d\[*`rZd`N;_Z8ZLdxN0\xN|cbdN(ccId #\IqIdIWId-fId:$gdNn^!ggd,\d&bSd,\SCWIdfICKeN,]LrLOe ]"Ore9] eh3eN,]BqIeO#\]ILe0O#LLPewBRuode+]Xde~q<g3~e,Y^BPqI~e# ^IPLe#LeLewBRuober] te4gM$e^^k$eUkj$ejjMe0_^keUkjejjde~ee4ge\ ,-epf-BpfNeHOdN7NoeOa1'O|ceOJeOR`f&bbfO`(cscIf `IsqIfIsWIf-fIsf:$3fPTaBqIf P#aILf8P#L]LfwBRu\3\gBuXqI\g#aIuXLbg#LLqgwBRu\g)fPPd!gg34f,boCf&bSCf,YbSWICffIKFfxP,bLL1OFf b"OOf9] ^fh3^fP,/cBQqI^fP#bIQLgfP#LLfwBRvf+{cXf~qg3-g,cBqI-g#cIL3g#L*L?AgwBRvfr]  g4gMnfid^RknfUkRjnfjjRMAgd^kAgUkjAgjjeseP1e_eP`__e__zfPf(~fQW4gf8QMgCgW3fXQfBqIf#eILfpQ#LLfwBRwf\ zg[f~g#g4gfw^+g\ 5ff p6uff %uf;yf0hfffQhfF 4gd)da 3,QgBwqI,#rgIwL1Q#LLXwBRug3\BSqI\#gISLa#LLpwBRugA\ y\ a.WMiʭQBiݭKy hLLWO h"O9] *h:;iBuqI:#iIuL?#LLNwBRuwW\ !uk!%( L%'%kQk J%@%hC%ii1%iO % j"O9] %WjX~q% gI"%wjI9 XjB{ qIX#jI{ L]#L L lwBRug1>hGu\ אJgo2+ RostrX6gRkNW Ak R[6g0RkN A 0R[.hHRlʭ  HRݭK:hhRy -lL LE GhhhlBe qIh#elIe Lh#Ly L iwBRu[7h3GhRmB qIGhR#lI LPhR#L L hwBRu[3[h%mB qI[h#]mI Lah#L, LA shwBRv6hRmNT Ah R[6hRnN A R[ 6hS?nN A S[6h SvnN, A@  S[3inBX qIi#nIX L i#Lm L iwBRu[3i&foB qIi#-oI L i #L L /iwBRu[g hw(.hMi8i\ d@i-sstr5(%8S"s ~`Sqi%ExS&+biSp(ccIi pIqIiIWIi-fIi:$3iSqBqIiS#pILiS#L;LxiwBRu~3jqBu~qIj #RqIu~Lk#LLkwBRu~ik(iTs (8i0T5prI 3iPT@NrB<qIipT#rI<L&jT#LnLjwBRu~2L1j@ALJjD(JjK5rg(S(L_j#;rLLLzj#;LL*aLj5pLNjjii&bj+jj\  ku)yx5(x'msgy5Tuiz'0[kT|LtrT|cb[kT(crcI[k ?tIrqI[kIrWI[k-fIruk:$3ukU|tBqIuk U#tIL~k8U#LLkwBRucckPU'ucc/PU|cPkhUPCPWk:$3k|uBudqIk#fuIudLk#LzLkwBRuc[kok\ luNvlU;vIlUIIlU-Il-sQs lOv5(I*Lrs#L*L*swBRv3s B*qIs#I*Ls#L*L+swBRu_3sgBu`qIs#.Iu`Ls#L!+LN+swBRu_s`;s Gs \sOs\ s^$%)5(a+len'+os&7+s40/m$+cPs OP/wP+s:$s^S',[cur;(N,tĒx,tx,-ta cP8t[ P,wP,Kt:$cPKt ,P,wP,[t:$ tBRvktP\RvcPotPwP,t:$Γ^$%)5(len'os&7 tN)15(len1'os1&7t[2-D-z-cPt\'tP-wP-t:$tQstR1Q)tasG5(osG&7t K-.tc=cPtKBP;.wPS. u:$cP(uIyPwPf.8u:$u+#uPQ 5Pu2xMPu(\eMIPu@\IIPuX\-IbuQxWstr&5(os&&7g-IT5(/&Op\ss&P ~\&PgI+. \.g\/v8/ ]#?A8/ MP]#?q/MM/LW#?LL0-h]*F0<Q0]cQ06T c0XT ~q/1g0aL<PpLD1Oc&92k]&QNJZ1=1R]&q2dk2](]&@23k2]&X2 k2]&2k2xMeMk2IIk2I-Ik2Qu~]&2I^#I2I-I2N(^#N2N3P^ND3NZ3Kh^Ko3K3 K3K3K RK3K3K TK4K4 K>4"q^&=Q4Iq #KIQ4Iq-IQ4Nz^#Nu4N46Nu~NVK^0KKvK4K4KRK4K4K TKKv KR"cP^&Rx4((^&R (58_5PIE53(_@.Bw5qIH_#Iw5L`_#L5L5wBRu~2L @AL5&D(&x_5g(S(6L/_#;LLA6LQ_#;LLe6aL`_5pL6yW\ \ eDpuˠ ' ' 5(  5(u _u `6_6_u_6_63u_0B6qIu_#I6Lu`#L7L%7vwBRu_3uBC7qIu#oIC7Lu#LX7Lm7vwBRv3v  B7qIv#I7Lv#L7L7)vwBRu_34vBu`qI4v#_Iu`L:v#L7L8IvwBRu_u_uWuWuO2v\ Pvistr[ '8(`^3\ _v\ Wb8X_v~qv8gb8@`ch^ %8avh`g b8ah`b8Iv/IqIvIWIv-fINv2N9N/9qIv3PIWIv-fINv`3բNG9Ng9hwN9N9JkwղJNuw ׃NN9v3w`d YB9qIw`# I9Lw`#L9L:`wwBRu_3&w`d ѣB-:qI&w#I-:L,wa#LB:Lo:>wwBRud3wd IB:qIw#I:Lw#L:L:wwBRu_3wd B:qIw#I:Lw#L:L;wwBRu_v47 wMiwwIBqIw#ILw#L,;LY;wwBRu_kvr_ wvw\ mnӦIT%7_Ӧ@cإ`cl;Vc;|c&=(a;1&bM10aa^;k1HaUk;j1`aj <j;MR^utkRUkutjRjjutn\ :-w %<2 'n<0 'w ʭ<wݭKxy L<L#=xhxxxa ʭ=;>xaݭKxay )L>LH?Ox "O>!x9] ,xhxBWqIx#]IWLx#L?L?xwBRu_x3,xa B?qI,xa#ݨI?L5xa#L@LU@`xwBRu_3Fk5cUk>Fj5dj`Fj>FMV^utkVUkutjVjjutr\ E{2Ȳ V| o{ otFo{ /oF{sZ| cZFZG|"] 3Y|d ۳BGqIY|8d#IGLb|Pd#L8GLZG|wBRuk3| SBulqI|#IulL|#LxGLG|wBRuk{ދ|sK|Y|"] w|^ | ] |ދ|l}\ 9}˴@ V[ @hd5 \F`3}d zBGqI}d#AIGL}d#LGLG}wBRug3}d BHqI}d#IHL}#LHL*H}wBRv3}  jB=HqI}#1I=HL}#LRHLH}wBRup3} BulqI}#IulL~#LHLH~wBRug6}2M}ئ PuhQ4[}ދv}}"] }^ }\ +H- ~j]% V( %%e$6 %HA@ %I8~ - ٷ+:IA~[6A~- AIW~ئPu`QOW~ e- [^IbW~ e~bJJo~ASd~- SiJWId~fIiJio~- ӸtJ~ئPu\Q43~8e- KBJqI~Xe#IJL~pe#LJLHKwBRu[3~e- ùBvKqI~e#IvKL~e#LKLKwBRu\~0 KH[~W[ L3~e0 wB!LqI~e#>I!LLf#LCLLeLwBRu[$4 L,b$e;bL9Ai94 tLPئPu`Q43_ f4 qBLqI_@f#8ILLhXf#L;MLwMwBRu\{spf6 {MFbspfiUbMAf7 \M_vfnvMEvf@TvM(OTv'Nb[EDq['NsFwff8 %HN{f8 {qNFbfiUbNAi: tNئPu`RwQ43f: xBNqIg#?INLg#LNLO wBRu\3m: B#OqIm#I#OLs#L8OLeOwBRu\ދ"] R|""] (0g@ _xO`b(0gmobO7A3'Hg0 ׾BOqI'#IOL-`g#LOLOiwBRu[3?- OBOqI?#IOLE#LOL)PTwBRu[3T - B6/bX/~qcgbvSalS3cScm3mlBcqIm8l#OIcLyPl#LcLcwBRv3BdqI#IdL #L.dLCd&Vdd5ɋhlڋe3l;BeqIl#~IeLl#LfeLewBRu`3Ȉl/BeqIȈ#IeLΈl#L fLFfwBRvvS;mbSfSfG3G mB gqIG@m#I gLSXm#L/gLMgwBRv3ZpmPBkgqIZ#IkgL`m#LgLgwBRv3gmBgqIg#IgLmm#LgLhljwBRv3tm>B/hqIt#I/hLzm#LQhLsh׉wBRv3BhqI#|IhL#LhLhwBRv3n,BhqI#IhLn#LhLhnwBRud3$ B iqI$#jI iL*#L iLMi9wBRuC3DB`iqID#I`iLJ#LuiLiYwBRud3Y BiqIY#XIiL_#LiLiɋrڋi3r;BiqIr#IiLx#LjL4jwBRu`3BGjqI#OIGjL#L\jLjwBRud3BjqI#IjL#LjLjwBRud3vBjqI#=IjL#LkL3kΊwBRud3Ί6BFkqIΊ#IFkLԊ0#L[kLkwBRudRai *,;B\ 9595@At' 0ns%kPnk+8 vl8 5^8 M^8l@^jl S8 ?S8l2SjlE_ SghnS~lSlvSgnJS~lSlnɋnncڋl3nn;BlqInn#(IlLw#L$mLomwBRuڋm3;BmqI#ImL#LmLmwBRuɋڋu3;BuqI#LIuLË#LmLnҋwBRud'\ 9595' %n\FP%oʭnQnoݭK40oy ^LnLnAh}B:oqI}#I:oL#LOoLdowBRv1OHoʭwooHoݭK[hoy @L pLEphhBuqI#vIuL#LqpLpwBRuWX3ho/BpqIho#IpLqo#LpLpwBRuW3xoBqqIx#nIqL~o#L1qLSqwBRv3pBqqqI#IqqLp#LqLqwBRv30pBqqIPp#^IqLpp#LqLr֌wBRv3 B5rqI#I5rL#LJrLwr+wBRuW36BrqI6#NIrL<#LrLrKwBRuW3KBrqIK#IrLQ#LrL!s`wBRuW3`wB4sqI`#>I4sLf#LIsLvsuwBRuW%iO*4\  S_h~' %H0A}  ps^pX_^&pqCV p5"o e q st$gR"(q RsvRs8R tvR!tEą> 5L4tF<><SSGtWIfIGtcPK PtwPtT:$cPWPtwPtd:$cPg@qPuwP;uOk O"OYut9] XqPluwPu=PpqVPuLPuP 0Pu$Pu:$cPqPuwPu:$3q~BvqIq#EIvLq#LPvLvwBRuc3BudqI#IudL%#LvLv4wBRuc=\ O !fd%r*'Z,%@fd{%b{'{JcPn}PvwP:$cPq}PwwPO "O0w9] rPCwwP=P(rVPWwLPkwPPr y0PWw$P~wА:$cP~PwwP:$ ӏhrx%ww5wX~q/xgwr3D@Cxq^)r-^nx^x)r3nxxO)r}"OnxiO#a u^ Ia da 3mBsqI#4IsL#LuLLxwBRva nď}яr] }\ \ \ $O 0DO;P' r71r }?@v ?8z %xcPzo PxwP:$cPp PywP:$j5 ?&y# b ?*b Rda br (c9ycNyI I9yqII9yWI-fI9y:$bs (caycvyI IayqIIayWI-fIay+:$z}ܑTb tb b cP’cPʒ}cPcP3}I}\}o}Q\ d\ w\ HU %cPEaOPwPY:$cP\bPywPm:$da Eu}}\ + %y%1(sycP5yWPlwPI:$cPLyPywP]:$b 5j=r}}\  1H%C9 HsycP=H[PwPQ:$cPTHP zwPe:$b =r=z}}\  1<%hs#zcPE<_PwPY:$cP\<PWzwPm:$b Ez=}} b \  -BOlenS%L;1"/soz_YsSnYzqIsIzWIs-fIzcPGsVPzwP[:$b[sWe(czcI[ ZIzqI[IzWI[-fIzo:$cPtsWPzwPz:$btW!(c{cI I{qII{WI-fI{:$cPPQP.{wP:$cPQPV{wP:$+b G}} }}\ "\ Х#E s#+cPʓ)EPn{wPޓ:$cP*uP{wP:$P*P{P<cP*P{wP{:$cP+ P{wP|$:$P&+=P|P3<cP6 +qP0|wPH|C:$cPu'P[|wP:$cP(P|wP:$ʓK}u}\ }Ŕ\ =%mД&U ]=C$(t.\F$|J P Pt6"}Z}Pt|ccPhtP"}wP}#:$_&t__}cP.tP~wP)~O. "O~79] H:$t__Z~cPKtPp~wP~v:$&HtbF~<t|ccPNuP~wP~a:$n8u"<8u|ccPPu#`xPu|ccPpu#pu|cbu(ccI IqIIWI-fIЕ:$3Еu# BqIЕu#ILٕ #LLuD+$'S^+bS>WI^fI>^av+^p^a ^0^ŀ^0^XE` y v/ , v|ccP8v0bi8v|ccP&Xv0F<ȁXv|cĖcPƖpv1pv|c֖cP֖v1&v|cb֖v(cc9I֖ IqI֖IWI֖-fI:$3v1 BQqIv#IQL #LfL{31oBuHqI#JIuHL#Lu`LPvPLPuHRuRPuRs3w6 BLw#LLwBRu`qI#I0w5O#˂0w1T“|cӘcPӘPw.Pw|ccP@c՘`cVcC՘|c=$ZDX:p|ccPpw˃&bMw^kwUkjwjɃjMhC^khUkjhjj)w4:w|c=cP=w5^w|cPcPPx5 ̄x|cbP(x(ccIP IqIPIWIP-fIf:$&fPx5 F!<IPx|ccPlpxP!wPm|:$|x6` x|ccPxPwPم:$x6 x|cbx(cc?I  IqIIWI-fI:$3y5 BpqI8y#^ IpLPy#LLwBRu`35 B҆qI# I҆L#LL wBRu`3 6u B'qI #N I'L#L<LQ=hy ]dShy|c/cP/y ȇy|cBcPBy އy|cbBy(cއc IB IއqIBIއWIB-fIއX:$3XyB;qIXz# I;La#LQLf&dy|cϗcPїz'ň݈z|ccP0z'e0z|cbPz(ccI XIqIIWI-fI:$3xz'BOqIz#IOL#LdLy3'1BqI# IL #LL3#BɉqI#pIɉL#L߉L3Ț#BqIȚ#ILΚ#LL1?'D&bz?w(vSzdSS3z?B(qIz#I(L {#LkLwBRu`MP^ŋkUkŋjjjŋ3)({@BqI)#IL/@{#LILx wBRu`M)^kUkjjj3+ @BqI+#hIL1#L֌L@wBRu3K?BqIK#ILQ#L-LB`wBRu` PLBPu@RuPLaPuRucP}PLPuDRuPLPuPRu}I\  %r;KDU"da 3,X{IBuqI,#IuL2p{#LLXwBRuw39{I4B'qI9{#I'L?{#LOLqpwBRuw3yIBu# qIy#yIu# L#LLwBRuw3I0Bu#qI#Iu#L#LώLwBRuw\ W {LK-"da 3,{I!BKqI,#IKL2|#LmLhwBRuw39|IBʏqI90|#`IʏL?H|#LLwBRuw3IBs qI#Is L#L,LYwBRuw3IBsqI#LIsL#LlLwBRuwO\ \ . 8%}n `|.vnSn `|lnbn$|$|Li2K;da 3E|IB;qIE#I;LK|#L]LwBRuw3R|I|BqIR#CILX}#LLwBRuw3IBs qI#Is L#LL,wBRuw3IBsqI#/IsL#L?LlwBRuwh\ \ f (}.Q}n @}.nSn @}lnbn$`}ے$}LCے2Kf;da 3E}IB"qIE#I"LK}#LDLfwBRuw3R}IVBqIR#ILX}#LLȓwBRuw3IBs qI#Is L#LLwBRuw3IBsqI# IsL#L&LSwBRuwh\ t\ \ ]u X-B<L;f:P$u~= ʭrf~ݭKy / LrL-h B]qI#g I]L#LrLwBRud< ~=U# ~j_YHH~S9!nY}qIHI}WIH-fI}cPx`~Vi!PwP:$bx~W!(ccI !IqIIWI-fI:$cP~W%"PwP:$b~W"(c/cI "I/qII/WI-fI/:$cPP"PDwP :$cP Q #P|wP:$Yb u}%}a}}3~=#BqI##IL~#LЗL HwBRud3d&=E$B*qId# $I*Lj #L?LlywBRu[\ h$' 8|'LZ $[ZS wSØWI fIØ ~x%ʭD~ݭK,y p%LLٙO, e%"O49] ?h,@ %*[ Mf3M@$&BqIM`#%ILVx#LBL~wBRuo3]&BqI]#c&ILc#LΛLwBRs3'B qI#&I L#L!LNwBRuo3'BupqI#S'IupL#LaLwBRuo \ 9'* 8[*[ /([S SWI fI (ʭ=fݭK,y (LҝLO, ("Oҝ49] ?h,@(*} ϞMf3M(v)BqIMH#=)ILV`#LdLwBRuo3]x)BΟqI]#)IΟLc#LLwBRs3f*B.qI#-*I.L#LCLpwBRuo3*BupqI#*IupL#LLwBRuo \ +H0  +C. 8|C.+à_vnvEv@Tv+Tvb[E+q[sFw̌؀+ی05D.,*C Of3O,BqIO(#m,ILX@#LL#wBRu_3_X-BQqI_p#,IQLe#LqLwBRsl>-3-BĢqI#}-IĢL#L٢LwBRu_3..Bu`qI#-Iu`L#LLFwBRu_DMi \ HY1`.8 8'V88'YU_'/d_SMSݣI6IݣqIIݣWI-fIݣ]Ё 0ʭRЁݭKly /L=Lyh0BuLqI#/IuLL #LPL}/wBRudi=0* f3 0BHqI@#|0IHLX#LLاXwBRuC3p-1BqI#0IL#L&LFwwBRw31BdqIЂ#l1IdL#LLwBRw32BƨqI#1IƨL0#LL wBRw3H2B(qI`#\2I(Lx#LJLlwBRw3 3BqI#2IL#LLΩwBRw3؃3BqI#L3IL%#LL0wBRw30 3BNqI08#3INL6P#LpL7wBRw3iu4BqIi#<4ILo#LŪL~wBRuC3~4BqI~#4IL#LLGwBRuC3e5BZqI#,5IZL#LoLwBRuC35BqI#5IL#LīLwBRuC3U6BqI#6IL#LLFwBRuC36BYqI#6IYL#LnLwBRuC3E7BqI# 7IL#LìLwBRuC37BqI#7IL#LLEwBRuP(ˠ=iIˠ]Mi**\ n8Y,8: 8:}%&h8*X ­4f348BqI4#8IL=#LXLhwBRuo3DЄv9B®qID#=9I®LJ#LLwBRs39B qI#9I L#L5LbwBRuo3f:BupqI#-:IupL#LuLwBRuoi&Mi\ H:: u%>:X<: ;:0:cPu;;PwP:$cPuk;P+wP:$c =›}՛}?!;NC!Cb!}qCY6M<hx6#x6}xݛ\  t<N=HC=HcPEy<PlwPY:$cP\y=P.wPm:$b Ez=}}\ :j=j> hU>F pcPUy=PlwPi:$cPly >PwP}:$b U=}}-\ \ >? lH n?:ȅ:-:tcP`u ?PwPq:$cPtu9?PвwP:$c ]=}Ü} r] \ \ oFМ3?AAܜ(@&ܜ(&H@\cP5<Z@PwPI:$cPL<@P޳wP]:$b 5l=t}}b h"h.WcPH?APwP:$cPHoAPwP:$ b ʝ=ҝ}}\ \ 7 6ACFCR˴B R B?cPu<~BPwP:$cP<BPwP:$%b u=}+}4b 4("4(`"cP՞HcCPawP:$cPHCPwP:$Jb ՞ =}>}3\ F\ (%P>C F ^WEf\fE߶ D\߶ EcP<DPWwPџ:$cPԟ<DPwP:$eb =}s}tb zg"zϷ(cPHEP7wP1:$cP4HEP_wPE:$b R=Z}}{\ \ G%>!F4H ^WXHnwnCG8F7GcP<FP-wP:$cP<GPUwP%:$b 4=<}}b o"mιcP]HGP wPq:$cPtHGP5wP:$Рb ]=}ơ}\ Ρ\ YСILHJ U3J7ߡkJFMRߡ0IHߡ0XIӺcPH<IPwP\:$cP_<OIP:wPp:$b H}=}}b x"RxcPHJPwP:$cPH4JPwPҢ:$ b ߢ=}}\ \ n8JJ 5%pyJJ %JJ QV%JXb K9QJJ,wMJ'2aLŦI\a2au2a42a~THo@ȉg'ao@ȉ]so3@YLBҼqI@# LIҼLE #L L,wBRud3SBJqIS#LIJLY#LLhwBRud,^ i?u[3 MBX?L[\ JhPJnzO2&Σzzz~@gl@]l3`/NBqIx#NIL#L;L]wBRud3/qI#uI>L#LSLwBRuG3vBqI#HvIL#LLwBRuG3vBqI#vIL#LL*wBRuG3qwB=qI#8wI=L#LRLwBRuG3wBqI#wIL#LLwBRuG35axBqI#(xIL/#LL)%wBRuG(`Mi*.\ 9Tx 8[{%  y{<y{% #{<+dǔ.X:yیK]pzʭ!ipݭKly yLLTyh=zBuPqI=#yIuPLC#LLRwBRu\izʭ%mݭKy zLL(hؗz* f39{BVqI#{IVL0#LLwBRuG3H{BqI`#x{ILx#L2LR/wBRs3)|BpqI#{IpL#LLGwBRs3ؘ|BqI#h|IL#LL_wBRs3 }B4qI8#|I4LP#LVLxwwBRs3h}BqI#X}IL#LLwBRs3 ~BqI#}IL#L L:wBRuG3~BMqI#H~IML#LbLwBRuG3~BqI#~IL#LLwBRuG3qBqI#8IL#L L9wBRuG3BLqI#ILL#LaLwBRuG35aBqI#(IL/#LLwBRuG%]Mi*&\ +H* 8*% H[W[!15_v1nv`Ev1@Tv`0Tvb[3Eq[?s7Fw̌BșځیXjʭݭKyy CLLhBqI#{IL #LLwBRu\v -ʭl ݭK8y %LL7hPa*  f3pكBqI#IL#LpL`wBRuG3QBqIؚ#IL#LLwBRs3ɄB8qI #I8L8#LZL|wBRs3PABqIh#IL#LLwBRs3BqI#IL ț#LL@wBRs31B^qI#I^L#LLwBRs3BqI#pIL"#LL1wBRuG31!BqI1#IL7#L*LWFwBRuG3F&BjqIF#`IjLL #LL[wBRuG3lBqIl#؇ILr#LLwBRuG3BqI#PIL#L)LVwBRuG3/BiqI#ȈIiL)#L~LwBRuG.jMi*d\ HNU=KmNN (X1'(|c P%] %+&bb,k(ccI, `IqI,IWI,-fI::$3:ȜBqI:#ILC#LKLwBRud3BqI#IL#LL wBRudgJ!ggPQ,`&bS`,SWI`fIKc8,ELLJOc :"Oi9] vh3vP,B^qIvp#I^L#LLwBRv+ X~qg3',BudqI'#HIudL-#Lu`L;wBRvr] 4gM^,kUk,jjNj,M X^bk Ukbj jwjb'\  IT `/я|co_~_cPPwP&O% L"OT.9] ďPgwP{=P<VPLPP 0P$P9:$g9 !ggC,$IR&bSR,`SWIRfIKU@,LLOU "O[9] hh3hX,6BqIhx#ILq#L-L\wBRu_+zX~qgz3,BqI#IL#LLwBRu_r] 4gMxp^kxUkjxj0jMΒ^u`kUku`jjju`\ rZZZՓDd|cb(cDcI ȓIDqIIDWI-fID,:$g,(!gg6,(&E&bSE,dSbWIEfIbKHH,”LLOH "ON9] [h3[`,:BqI[#ILd#L L9wBRuo+WX~qgW3,BqI#ŕIL#LLwBRuor] 4gMkt^kkUkjkj jMҖ^upkUkupjjjup\  ]ITG `/]&KF!<W|co_x~_WcPПPwPO% Ɨ"O.9] >PwP=P<VP4LPHP 20P4$P[9:$g90!gogC,R&bSR,ژSWIRfIKUP,8LWLOU -"OW[9] hh3hh,BqIh#wILq#LLwBRu_+ X~q; g 3,tBO qI#;IO L#Ld L wBRu_r] 4gMx^ kxUk jxj j MH^u`kUku`jjju`\   IT `/   |c%)g%Р!g) ge /,3 >&bS>,oS WI>fI KA,͜L L: OA œ"O G9] Th3T,EBN qIT(# IN L]@#L} L wBRuo+ X~q g 3, B qI#НI L#L LK wBRuor] 4gMd^^ kdUk^ jdj j^ Mݞ^upkUkupjjjup\ n8  ,IT `/,ITj-M X  X|co_~_ cPxP wP/ O% "O] .9] zPp wP =P<VP LP P n0P $P 9:$g9ءŢ!g gC,ڠRR&bSR,SWIRfIKU,tLLOU i"O[9] hh3h,BqIh0#ILqH#L6LewBRu_+8X~qg3,BqI#wIL#LLwBRu_r] 4gMx&^kxUkjxj9jM^u`kUku`jjju`\ ; ǣIT> `/ǣb@Bݭ''' 9dݭerf`ҭg\FLmsgjPrtMjvkjdvTddl#|ccPȢlErȢ|cb(cEcI IEqIIEWI-fIE:$&lF<|cͬcPͬ0m.)0|ccP@cPml`cVcKP|c=Hhmhm^h|ccPin%jn jdTdd&$osF< |ccP*أPwP!::$;oA T|cI)"jsg q"_g `i__k__z|h~04gMjɨ^:kUk:jjvj:3HABqI#IL`#LLhwBRu`sxv_x`L_l___*I7{שII4gMAj^*kAUk*jAj?j*3T.!BSqIT#ISLZ(#LhLiwBRu`kv|Nw^ӭjmrZm'b2w^mrZrZm bw^r\ 8L;n8c  IT' `/_@__cP `PwPO "O)9] ::$__FcP=P[wPs:$g:3!ggD,HS&bSS,SBWISfIBKVإ,L~LOV ׯ"O~\9] ih3i,ZBqIi#!ILr(#LLwBRuo+7X~qbg73,BvqI#IvL#LLwBRuor] 4gMy^kyUkjyjjM^upkUkupjjjup\ 5x#2\u'q' H`IT$ `/`4#V'$';'\uq@$0H hY$*III(^8k>@Uk"9j>Xj9j"9Mq^9kqUk9jqj9j9>gpp9M^ :kUk :jjB:j :MZ^b:kZUkb:jZjw:jb:vgzݹЯ:~ݹ:4gݹMg:Cg:30B ;qI#I ;LH#L';LI;?wBRw\  d_ `g;_{;_ _;_;zC;~C;P4gImUbom{man{mԹݹw^X\ ee./ ' '\u 5(<q 5(J<PsR1Q.,0''\u5(<q5(<PsR0Q FeIT `/eIT(09FP.`N=DE=`|co_~_E=cPPt=wP=O% ;"O=.9] P=wP==P<VP">LP6>P 0P">$PI>9:$g9!g]>g>C,>R&bSR,OS ?WIRfI ?KU,LE?Ln?OU "OE?[9] hh3h,%B?qIh8#I?LqP#L?L?wBRu_+q?X~q)@g?3,B=@qI#I=@L#LR@L@wBRu_r] 4gMx_^@kxUk@jxj@j@M^u`kUku`jjju`\  IT `/IT-(thb@@h|co_~_@cPP-AwPcAO% "OA.9] UPAwPA=P<ȱVPALPAP I0PA$PB9:$g9!gBgRBC,BR&bSR,SBWIRfIBKU,OLBL'COU D"OB[9] hh3h ,B;CqIh@#I;CLqX#LjCLCwBRu_+CX~qCgC3,BCqI#RICL#L DL8DwBRu_r] 4gMx^KDkxUkKDjxjmDjKDM_^u`kUku`jjju`\ . IT `/V IT `/~ IT% `/5 #;IT `/; VnITj `/nz IT `/ 2z'z'6' X%X%k% p G5D`BUrDO _O `D_D_R_D_Dth! EJPExE|ccPȲPPEwPE:$M^EkUk;FjjGj;FM* ^ Hk*Uk Hj*j#Hj Hgsn }_n `_7H_r__~HĻ(HHѻH H&IH|ccP׻`PHwP|I:$Mxn^IkUkIjj}KjIMA^KkAUkKjAjKjKѻg GKK)o-pIo?oL|co3onLoLB7=MK^LkK(UkMjK@jNjMMX2^NkXUkNjXjNjN-Kg aX-N#NmpOQR|ccP¼ PQwPSRҼ:$Mۼ8^sRkۼPUkRjۼhjSjRM^SkUkSjjTjSۼgs|&TNT$ DwT:T|ccPPwTwPT!:$M*е^Uk*UkXUj*jVVjXUMg^vVkUkvVjjVjvV *g@VV)oL0Io?oV0|coRHo7WosWa7=Mj`i^WkjxUkWjjjXjWM^XkUkXjjXjXLjgsFX$Y$ȶoDMY:uYȶ|ccPPMYwPY:$Mƽ^YkƽUk.Zjƽ(jZj.ZMܿ1^[kܿUk[jܿj[j[ƽgܽ@+[S[)oXIo?oq[X|copo[o[7=M3^\kUkf\jj\jf\M^]kUk]jj*]j]gs6з>]f]$C9D]:]|ccPIP]wP ^Y:$Mb ^)^kb8Ukp^jbPj^jp^M^^kUk^jj_j^Cbgxhp#_K_)oIo?oi_|coo_o_7=M^`kȸUk`jj@`j`M6[^u\k6Uku\j6jju\gzϾTT`~Ͼ`4gϾ8Mg`Cg`3ݾXGB`qIݾ#I`Lp#L`LawBRw\ z1a~Fa 4gĻ 0*6ƾϾw^(\ 3IT9 `/Oxosaea|co_~_acPPawPbO% "O#L#LUwBRu|2LI@ALsbD(bF5g(S(Lw#;LLL#;LLaL5pLI((CG (8P5I3p@BqI#ZIL#LQLwBRu~2L@ALD(F5$g(S(ňL##;LLL3#;LL aL^5pL1vzAn~4g3BB̉qI#ỈL#LLwBRu|3CB$qI #EI$L#L:LiwBRu|&b&b %mrZ0rZw^t1\ |\ .'nzJ'zJ'XKU% XKU%^} Ñrhs H5 %%z%'z&'X'% X(%%lhs/Ťrhs/Ť8 |,< ~n(00|}M(P K\( ?ȑh ?ב̊ML K\L ?ȑ ?בp M 4l'4p uu v +_ `4_H__g_{8I+ 0E<)g)X4vl)#?l M#?/MML#?LLW-Fm<c?[} cX} ~qgaL!pL9$֑֍Q0$Ro RϒHRo`9Xoco7=x<&Iޓ+" gS>v^#?^- M-#?0/MMUL.#?LLw-p(F<ݖpPcݖ chX ~qghaLpLh==֍Q$R R%Rio=oo87=soA_o`W__v __.A| ěٛ!|ccPPٛwP:$M( ^k@UkjXjjMn^kUkjj3jgzBpAg G~By4gBMgCgy3OZ B˝qIO#! I˝LT#LL wBRvh\ 3kB B+qIk # I+Lt#L]L[wBRu|30CY!BqI #!ILH#LߞLwBRu|(`<" (/851"Ia3@"BqI#!IL#LL{wBRu|2L@AL1D(F5"g(S(qL#;|"LLL#;LLՠaL.5pLF(FC+$ (y8F05#I3FP@x#BݡqIFp#>#IݡLz#LLAkwBRu~2L@AL_D(F5$g(S(L#;#LLL#;LLˢaL5pLzAq$,~[4g3B$BqI#$IL #LLϣ%wBRu|3%Cc%BqI% #)%IL.#LL'@wBRu|M&bb&bm!rZ.07rZBw^Oa\ i\ //R&zQ'zQ'XR% XR%a&& %%R& b&'a&&$:u'w&McPU'PYwPi:$cPlB'PvwP}:$/^c U=}}tc \ +'' %%'u=','($('cPQG(PʤwPb:$cPew(PwPv:$0^c N=}}DM*D 7)2727 E7~*EEEx gp_ ]qp3 BqI#)IL8#LLwBRud"1<,BQ6m   Mֲ̲\ DD,Dw#+¦#¦# E#~*EEVxgզ_]qզ3BqI#+IL #LLDwBRuc""1w",BW6S"& s&M̲sֲ/\ tc =\ !0IE%EV76)7%end7%v8: P 09%eh9[-eاeا7Q-.IC%D%qE%GeoF-eeevF-eea~F!.ku~~gcP:].PwP:$cP;.PܨwP:$cP;.PwP :$cP8=.P*wPL:$cPO>!/PbwP`:$cPt>U/PzwP:$cP?/PwPȩ:$==cP}8o===cP}}}\ \ X_$=00  e M0ee ,4001 lH=0.aT1bYbY1i'qapS1bbӪ e M1ee,P,m,!m3%str3|:end*lN%Q242O$F3 %fS2SI6IqIIWI-fI3 "_ :=1IV3%%c%os&7ucX;%%c%os&70M;ءcP 3PwP:$#3H8J3@3lcP8>4PɭwPH:$cPq4PwP :$cP 4PwP7:$cP 4PJwPb:$cP  5PuwP :$cP0 =5PwP@:$cPP p5PˮwP`:$cPp 5PwP:$cP 5P!wP9:$cP  6PLwPd:$j(6uwb6(ccCI 6IqIIWI-fI:$3*7BqI#6IL#LLwBR[3#7BqI##h7IL)#L6LpwBR`P7PP:$3K8ḆqI#8I̱L%#LL4wBR[348B!qI4#8I!L:#L5LJw(MicPP 9P]wP`:$:$D:$:$cP`HS9P wPTp:$_:$cP9PwP:$cP}h9PwP:$b@:(ccI 5:IqIIWI-fI:$3:B&qI#~:I&L#L;LhwBR[3L.;B{qIL#:I{LR#LLawBR[y=h=}w(J\ ;c%os&7V3;%%c%os&7kC%%c%os&7CءcP ]<PwP״:$;?A;;;cP@<PAwPYP:$cP<PlwP:$cP=PwP:$cP Q=P¶wPڶ:$cP =PwP :$cP0 =PwP0@:$cPP =PCwP[`:$cPp >PnwP:$cP P>PwP:$cP >PķwPܷ:$j>ub -?(c]cI "?I]qII]WI-fI]:$3@?BqI`#k?ILx#L,LfwBR[3(@BqI(#?IL.#LL޹wBR`PN@PP':$3'@B:qI'#@I:L-#LOL|<wBR[3<*ABqI<#AILB#LLw(MicPXِAP˺wP#h:$:$I:$ :$cPhAPzwP»x:$d:$cPBPwP:$cP3BP-wPU:$b B(ccI BIqIIWI-fI:$3@1CBqIX#BIL#LLּwBR[3TCBqIT#oCILZ#LLiwBR[=m=w(R\ Dc%&os&7;2/G$%$%c$%os&7p$GءEcP רDPwPy:$cP(DPwPƽ::$cPPEPwP`:$cPyGEP=wPU:$cP}EPwPh:$bF(ccI EIqIIWI-fI:$3{FBqI#BFIL#LL޾wBRuc3FBudqI#FIudL#LLwBRuc({GPvRsi=w(\ ^}Gwc$%os&7DPGG p}G`KGSHGG3HHB1qI#HI1L(#LOLIwBRo-\ ZeHzH 9%SHo8AHLeH@gI}G@GֿG3$`[IBqI$#"IIL)x#LL*wBRuw=\ @/JH}G@GwGH3G#JBqIG#IILL#LLwBRuw\\ 3_JBqI_#nJILe#L LGwBRuw3lKBuqIl #JIuLq8#LLwBRuwPIK}GhsK}G3KB-qI#KI-L#LBLowBRuw3cLBqI#*LIL#LLwBRuwJ\ ,JxLITxS9LL @%LU@LLRLTX)d gM|q|X)(}}|Lb L5ozHw\ b 9NS Sxa lx6 ME[O\ b O,;QE /Q̬ M۬/Q\ b Od}GGGd3OBqI#OIL#LLwBRug\ 3b KPBqI #PIL(#LFLwBRug'b Q '--a1 lx61 ME[O:\ =b Q=,C;Q/EQCG d̬G M۬dP\ V@b Rd}G3d(b RBqIdX#XRILgp#LLwBRugJ$J\ LbRRLL\ SITxS@&SITxSV@t5SJS lH%&S9fSa5Sv^ Tvv!v^(vvvSR RLTLL\ &JT'&J(֛ɛVS0 S*K0T9K9\ :TIss>s^bVmuffffVVf0 kUYda 3UBlqI#UIlL(#LLuwBRud3BqI#VIL#LL wBRud\ @V6 6 7\ S$X+YSxWSl$ 0+Wml$$ll%Gm' 1mWVml'6l}l-mJ 0r] Skr] {\ \ \  lI_Tp999:99D99/@G ̒l m e__n__s'C`h%mt eGՌ)__xGtnQ9SY} Lmm}q}y}} M,}qB}6}3S"3;.!"y3_"@}l3Vlll"l`]^ hC^`0=``YWaoblh_olc llVl]eh ko)e)eCqc*oW`o>1(a;p!+(Mr] Y} ipm}}y}H} M,}B}6}H5@rirukh[@0.*k@0k@J@0~ksg@0]<k/"@kW@k~@ @9k,@H;^ 5Xy4tuhA[aX0.*AaX0AaXJX0~sAgaX0]</A"aXAaWXA~aX X9,AaXH^ ,;QE 4̬ M۬4\ :5*uI_Tp%9':9'D9|:/@G ߜ9unu e__n__s'Csfu:} eGG__xG:}xwQ%|(~ L2v<~T~H~} M}~~/S1+$\/+\\/_+\t/V u+t\tuU^ bC^s0=`s YWaRobp*ub_wPuc Cu9uV_uebweeCgcwWyz`xax?hMh{r] (~ ix<~T~H~} M}~~rz,B0.uh,0&,4X0~,j0],\OB,, Xp,x2^  y|B 0.uh 0& 4! 0~j 0] \OB   !p  A^ wa lx6 ME[O\ :N}f} e__xf}d:2z}} e__x}:;!}" @|w 9?}Hx d~X}1N}^Y} Y~m}}y}} M,}B}6}r me6y ~eek}>hy }z}Y(~G<~T~H~}GM}~~nu^nI_Tp;9B:9BD9B/@G } !f__n__s'Cxh~ MfG__xG~cQ;\ Lvp,J|_  M/,EJ9_3Sr3r?3_rsf"3VPrC6_]^ hC^x0=`xAYWaobnh_7c }Vfh ffCqcρW`] BajMr] \ iCp|  M/E9!rna&TPGn0. &Pnx0&Pn60~k&_PSn0](&Pn&Pn&PnF&9P,nU;^ !(yنnaTG(0. x(0(:6(0~k_S(0]((((:(F9,(UZ^ ds}/ :RF M)\ B 8rWrL;L;Ї DWDL;L; 87(@ Mf__x@C] lHH?_SˈSI6Ihpos5LBLf5L+LLBL5L +L3[NN[tN jN3ICI3b$$ f0s!ڇ)Ї3!EBqI#YIL#LLwBRud3E B)qI#ъI)L #L>LkwBRudHW_i_sGx~b8sy`* $f3xBMqI#ًIML#LkL wBRu`3BqI#QIL#LLwBRu`w}ns׌nSnlnbn-r] \ Iύe)[R" ;1| 2(\ pVk|  M/VEk9I3GBqI#IL0#LL/wBRs3HBqI#IL`#L1LSwBRs3d 7BqqId#IqLj#LLywBRuV3BqI#vIL#LLwBRuVr] "] ^ \ \ 1"0G1;7x| 2S(\? p| ? M/E9rI GҐ[e" ;1)| 2a(\ p|  M/E9swՒʒ 'Ie ['" ;E1c| 2(\ p&|;  M/E&9;Bkey%-key%X<T lHG- PWp<FV Nz} ғ }:@:p:cPu[PwP:$cPuPwP :$c =%}{}ՒLtcPDPwP:$cPtPwP-:$c :=E}{}87:p::mcPu(PwP:$cPuXPwP:$lc =}a}?Nb}qYhs#s}s&}1@m m}m<&}K-Zi- .i٠-i-}ɠie ٘~t*6 N#hTMZ%Z 5 X@cPEЙPwPV:$cPYP0wPj:$hc By=}D}2|AH|H|}H%ɋO <ڋ3O ;BqIO#ILU#LLdwBRuO:Isss^`m-uf̛\r ra lx6 ME[O\ p[ f~1rO0 M?U1IO\ Bbb(xα ٱ Mȱ\ Lr] r] sm\ J#1( G!T͞ҟ:x::cPu5P7wP):$cP,uePOwP=:$c J=U}k}r] Ts\ ~\ \ 0Y=r^ $c &N=^ c ,\ 0MB60g0H3TS9SWI9fITF/#TTQ] h 3=@ϡB\qI=#I\LC#LqLRwBR\|5MBqI8#ILP#L L (wBR\fx  SS WIfI .  5Lg[ [_[2 SNS2 WIfI2 hJ  58 a SES8 Sa vSJS8 Sa ɋڋ 3;B qI#xI L(#LL%wBRvɋ3(EڋC33@;BeqI3# IeL9X#LLWwBRv3DpBqID#ILJ#LLgwBRvɋUPڋ;3U;B;qIU#I;L[#L]L{wwBRv3fȦBqIf#ILl#LLwBRvz Sz(SIz6Iɋ0ڋh3H;BhqI#yIhL`#L{LwBRvSSWIfIxwڋ3;BqI#=IL#LMLwBRT3BqI#IL#LL wBRɋڋ(30;B(qIH#JI(L#L=LP/wBRvM`5c3L@$B\qIL#I\LR#LoLawBR`^f5Lu[[u_[SuNSWIufIxYD3 @HBxqI#IxL#LLwBR`5ɋڋ3;BqI#IL#L7LqwBRLɋڋ3(;BqI#EIL@#LLwBRv3XB!qI#I!Lp#LPLywBRvɋڋ3;BqI#PIL#LLwBRv3BqI#ɭIL#L L3hB0qI#/I0L#LELrwBRLɋڋ3;BqI#IL#LL(wBRL3($sBqI(#:IL.#LL=wBRLɋiڋ/3i;B/qIi#̯I/Lo#LBLo~wBRLɋ~ ڋ3~ ;BqI~#_IL#LLwBRLɋ,ڋ3;BqI#IL#LLwBRvɋڋ3;BqI#IL#L#L6wBRv37BIqI#IIL#L^LqwBRvɋʲڋ3;BqI#IL#LLwBRv3 0BqI# IL#LLɋ(ijڋ3(;BqI#IL"#LL>wBRɋ#WڋQ3#;BQqI##IQL)#LfLy7wBRvR/ȴBqIR#ILX)#LLkwBR\Tڋ3;BqI#IL#LL!wBRT2ŵB4qI#I4L,#LGLtwBRTs0[XSMn0DF\ &+t0t'Ex8 + #z(0+z'GxP*cG%XX]0q]x-BtT0= La a>tDWKn-bEc d *d ^ Gd  _ ^ *d ^ 1fd8%9J:J;;%^G%3] ]%}k?%Y.<Zd 2]L A]K]/%%Cb amda 3uBqI #;IL#LLwBR}3BqI #IL#LL,wBR}3,gB1qI, #-I1L5#LGLvGwBR}3GBqIG #ILP#LLbwBR}3b&YBqIb #ILk#LL&wBR}3+ҼB9qI #I9L"#LOL~wBR}3KBqI #IL#LL wBR}3 =ĽBqI #IL)4#LL( ?wBR}]_ i*)=Ccs]uO]; ]O b(۾(cd cz I оId qIId WI-fId :$3@SB qIX#I L#L L wBRw2] }A] K] p pȸ}ո};! >o!!""/Zd l"bI(c"c"I I"qII"WI-fI":$3IB"qI#I"L#L"L3#bwBR}3#IBQ#qI #VIQ#L#Lg#L#wBR}dmcPcP=cP}}E #&bb(E(c#cI I#qII#WI-fI#,:$34@E B#qI4X#I#L@#L$L($RwBRv3uEB;$qIu #JI;$L~#LQ$L$wBR}M&J^$k&Uk$j&j$j$`N@p$v$N|ccPpP$wP$Oc"O$^:$M5J^$k5Uk$j5j%j$H_ 4}r}2]f /A])%K]=%P cPQ%Pd%<2] A]w%K]%3$B%qI #I%L#L%L%wBR}%_ ]mrcP}cPcPcP}}}\ _ \ e` ]Jpmxm'm%%D&6&b 3OBJ&qIO#IJ&LU#L_&L&dwBR3d6B&qId#I&Lj#L&L&ywBR3yB&qIy#uI&L#L 'L:'wBR3(BM'qI#IM'L#Lb'L'wBR3B'qI#gI'L#L'L'wBR3B'qI#I'L#L(L?(wBR3BR(qI#YIR(L#Lg(L(wBR3C B(qI#I(L=#L(L(wBR_ i*%6GMcGd \ 0Q ^F%%&%)36 &WB)qI6#I)L<#L3)Lb)KwBR3V&Bu)qIV#Iu)L\#L)L)kwBR3k&IB)qIk#I)Lq#L)L*wBR3&B!*qI#I!*L#L6*Le*wBR3&;Bx*qI#Ix*L#L*L*wBR3&B*qI#zI*L#L*L+wBR3&-B&+qI#I&+L#L;+Lj+wBR39&B}+qI#lI}+L3#L+L+wBRm_ zd i* .4c\';\+]+\T\ D`u ]%\j\un  -j,Q `,3vLB1,qI#I1,L#LF,Ls,wBRuF3vB,qI#I,L#L,L,wBRuF3v<B,qI#I,L#L,L-wBRuF3vB0-qI#{I0-L#LE-Lr-wBRuF3v,B-qI#I-L #L-L-wBRuF3vB-qI#kI-L #L-L./wBRuF3/-vB/.qI/#I/.L5'#LD.LY.CwBRv<iJ\m}*cL\ 0\uB  8djl.Q 8`l.3vLB.qI#I.L#L.L.wBRuF3vB.qI#I.L#L/L./wBRuF3v<BA/qI#IA/L#LV/L/wBRuF3vB/qI#{I/L#L/L/wBRuF3v,B/qI#I/L #L0L-0wBRuF3vB@0qI#kI@0L #LU0L0/wBRuF3/-vB0qI/#I0L5'#L0L0CwBRv<iJ\m}*cL\ \thn\ P-n0  P-0Q P`03vgB 1qI#.I 1L#L51Lb1wBRuF3vBu1qI#Iu1L#L1L1wBRuF3vWB1qI#I1L#L1L 2wBRuF3vB2qI#I2L#L42La2wBRuF3vGBt2qI#It2L#L2L2&wBRuF3&vB2qI&#I2L,#L2L 3;wBRuF3;-v7B3qI;#I3LA'#L33LH3OwBRvHiVhy*c!\ X\ 0ahB0 hdB[3  hd[3Q h`[33vB3qI#TI3L#L3L3wBRuF3vB3qI#I3L#L4L@4wBRuF3v}BS4qI#DIS4L#Lh4L4wBRuF3vB4qI#I4L#L4L4wBRuF3vmB4qI#4I4L#L5L?5&wBRuF3&vBR5qI&#IR5L,#Lg5L5;wBRuF3;-v]B5qI;#$I5LA'#L5L5OwBRvHiVhy*c!\ X\ զ 6P9+Mb P@%03TSButqIT#IutLZ#L5L6iwBRusJRcr\ 8ND$620Y'a Y1Z' Z% ZG[0[C6aab6N e*75#<XJ6d*9o*}*XQ% qx g6 |ccP(8Px wP6;:$;X[7R7X|ccPAxP7wP7Q:$OQo7e8|ccPWP7wPd8g:$&g'F8<8|ccPmP8wP9}:$}ލ99q9|ccP8P99wP9:$X9&bMx^K:kUkK:jj:jK:MZv^:kZUk:jZj:j:%b9 (c:cI I:qII:WI-fI::$39B<qI#II<L#Li>L>_wBRv (?(>vS @dS>S?-3-X?JBg@qI-x#Ig@L6#LALmBPwBRT A@jUO U Ha^ N%B_ da $i8M`q*c]O:]B]BVZ0aVaB[ -[C[CZ%GC3VZ4BeCqIV#IeCL\#L{CLCkwBR3k ZBCqIk#sICLq#LCLDwBR3Z&BDqI#IDL#L)DLXDwBR3ZBkDqI#eIkDL#LDLDwBR3ZBDqI#IDL#LDLEwBR3$ZBEqI#WIEL#L.EL]EwBR3Z BpEqI#IpEL#LELEwBR33'ZBEqI3#IIEL9!#LEL FHwBR_ da i*0>Dcs][]F];F& \B? OF5 cF]tLl]F]G3KB)GqI#I)GL#L>GLmGwBR3K^BGqI#$IGL #LGLGwBR3KBGqI#IGL!#LGLH0wBR30KPB,HqI0#I,HL6#LAHLpHEwBR3EKBHqIE#IHLK#LHLHZwBR3ZKBBHqIZ#IHL`#LHLIowBR3o!KB2IqIo#I2ILu#LGILvIwBR3 ?3BIqI#IIL#LILI,wBRT}d  fd i*ci*c}\ , T0'a 1'  %GlHITI%@0=!LIaa0JM P]\ FJ7VPFVYJ>h(nJvS>dSnJSJK3K%BJqIK#IJLT#LJLKwBRuG3_B:KqI_#dI:KLe#LiKLKwBRs3pBKqIp#IKLv0#LKLLwBRs3HB2LqI#TI2LL`#LaLLLwBRs3xBLqI#ILL#LLLLwBRs3kBMqI#DIML #L%ML:M$d WdMMJdyM$dWdMJdM$dWd'NJdoN/ BD N N NB0NNNBNNNJ(OvSdSOS3O3mB[OqI(#4I[OL@#LyOLOwBRu\3(BOqI#IOL"#LOLOwBRs P O P *P >P RPXh*P>PRPp*P>PRP3BPqI#IPL#LPLPwBRu\3"BPqI#NIPL#LPL!QwBRu\3)B4QqI)#I4QL/#LIQLvQ>wBRuG3BwBQqIB#>IQLH#LQLQWwBRuG3[BQqI[#IQLa#LQL RpwBRuG3tgB3RqIt#.I3RLz#LHRLuRwBRuG3BRqI#IRL#LRLRwBRuG3WBudqI#IudL#LRL SwBRuGiiMi -*>@r] Mir] \ \ %\   > U3 Q> S0jS}%S3BSqI#ISL#LSL TwBR3<B3TqI#I3TL#LFTLuTwBR3BTqI#{ITL#LTLTwBR3.BTqI#ITL#LTL!UwBR3B4UqI#mI4UL#LIULxU wBR3  BUqI #IUL#LULUwBR3BUqI#_IUL%#LUL&V4wBR34B9VqI4#I9VL:#LNVL}VMwBR_ da i 2ER*evcL[V[_[VSNSVWIfIV3hBVqI#/IVL#LVL WwBRL3BWqI#IWL#L0WL]WwBRL3XBpWqI#IpWL#LWLWwBRL3BWqI#IWL#LWLXwBRL3 HBXqI#IXL#L-XLZXwBRL3BmXqI#ImXL #LXLXwBRD38BXqI#IXL#LXLY-wBRD3-BYqI-#wIYL3#L*YLWYBwBRD3B(BjYqIB#IjYLH#LYLYWwBRD3WBYqIW#gIYL]#LYLZlwBRD3l BZqIl#IZLr#L)ZLVZwBRD3  BiZqI#W IiZL#L|ZLZwBRD0d 'd /mJZkz*cm*c\ C vm3  we  E O (u O ZE ZI("eZ[Z"@ ;Z1[X| 2M[([\ g p[[|[  M/[E[9[BP8  lHx3\$da Wd Jd\nS3 Sx\WIfIx\|[S [\3 B\qI# I\L#L\L]8wBRuo3C B4]qI(# I4]LH#LV]Lx] wBRut &]]$d Wd]Jd]3?B]qI?# I]LE#L]L^TwBRuo3mB^qIm#TI^Ls#L-^LZ^wBRuoa[XYr] 3 "] ^ j\ ]\ 1:I_TpV@9\@:9\@D9P@/@G ħI~ 2__n__s'CXhJ G͡m^__xGJ`/QV@^ LB^&^^ M^^^_ 3xS ^ )_| f_3xI^<)_/f_3x_^)_f_x_3xV^)_f_x+_]^ hC^X0=`X_YWa`ob9`:h_`c SIVo`h CqcW `)  ` a/`9aMa/ar]  iCa&aaa MCaaaarL ? a2 a% a0.aaaV0aasab0~Ia=a1a0]aaaaaa!baUaHaqbaaa5b;^ yL ? [b2 b% b0.[bbbV0[bbsbb0~I[b=b1b0][bbb[bbb!b[bUbHbqb[bbbb^  c(c7cα ٱJc]cxc MJcȱ]cxc\ m@^v __xv@'Se GenvV@cOHhc^c =?d&Udjd M?dUdjd~  }dI_Tp@9@:9@D9@/@G  ga__n>__s'Ch   aGd__xG 8Q@d LƂeނe҂3ev Mee3e#3PS#Fe#te#e}3PFetee3P_=Fe0te#ePLee3PVFeteyePe]^ hC^0=`fYWaޭZfobޭfhh_zc Vhfah SbbCqcW7`aTga#>glwggAMPggfzgZr]  iƂgނg҂gv Mggg*#rQw#j#g]#$hP#Bh"0.##g#$h"Bh"0"g"$h"Bh"`h?"0~t"gh"$h\"Bh!0]1"g$"$h"Bh!!g!$h!BhL!!g!$hs!Bh!`h!.!g!!$h!Bh=!h;^ *#y w#j#h]#hP#h"0.##h#h"h"0"h"h"h"i?"0~t"hh"h\"h!0]1"h$"h"h!!h!h!hL!!h!hs!h!i!.!h!!h!h=!.i^ Tigii[ fi~iri0 M?iUiIi\ A$"IT*7_")!Ii?icP u!P%jwP8jO j!"O%j)9] ::$(Ihj?|jcP:@PjwPj:$=`!I&bMIxE"^jkIUkjjIjjjjM"^utkUkutjjjut\ D#I_Tp*9C:9CD95/@G #L# C__n*__s'Chd#+ IjGk__xG+$Q*,k L$JkÃhk}k[ MjJkhkt}k'3S'k'k'k`3kkk3_ kkk/l"3V"k"k"k"9l]^ hC^0=`_lYWalobl#h_%.#c !##V=#6m)h %88Cqci%W'`%((`mx(az&m(OZmf$M3mIm=r]  i&mÃm!n[ Mjmmt!nB'@r(''Dnu'nnh'n&@0.7'*'Dn'nn'n&@0&Dn&nn&n@&nW&@0~&Dn&nnt&n&@0]I&Dn<&nn/&n%@&Dn%nn%nd%@%Dn%nn%n@%n%@F%Dn9%nn,%n@U%n;^ B'Xys*''nu'oh':o&X0.7'*'n'o':o&X0&n&o&:oX&XoW&X0~&n&ot&:o&X0]I&n<&o/&:o%X&n%o%:od%X%n%o%:oX%Xo%XF%n9%o,%:oXU%xo^ oooU `oxol p* M9oOoC p\ Dt5+N, Ijo p__xoN, x__nrJp"r+1ppu$uppu'r+((B+PvB,pÃpp[PMjpptp4L#`D_k,- pu__x)p__y))--qKq )P-uqqC )NfqZq M'=q1q#\ 6")q36" BqqI6#-IqL9#LLqRwBRo6S,l-L. B1L.6KC__r%אi.2 __k)2__j)r().#r@)c0NryrrryC")rss.C"@sasTs-C" .s-sC".Fs#.es0.=.sICX/IsqICIsWIC-fIsNFp30sfsYs]d Syz$)1rst.z$@sasTt-z$ .s-tz$.t#.)t0.=.__p)p>__v)p2)s$__z)wא2a: pu__v)a:V:)oGt2)I6128u'2Xu@2xuM2uZ2ug21v()3Tvy>@) 5vvv.>@@savTv->@ .v-v@. w#.w0.=.=wI>4IvqI>XIvWI>X-fIvNNp4sf[wYw^d ^y)!6www.@sawTw- .w-w.w#.w0.=.xN5sf1xY]xd `.)ox$  )u6   x{2)-:2x2x2y27y2Wy2y *)t8yyy. *@sayTy- * .y-y *.y#.z0.=.$zI 7IyqI IyWI -fIyI(#8IBzqIIBzWI-fIBzN@]8sfjzY}z/d %XX =p)w!:  zp  =):9 [ =)f r z0 =MI z? U zGr] r] I)V9ڃO)9{@{[):C)NfZM'=1\ e 'e -e p$ s)   ^{\ אD3;%A \QyIR{:R}{R{cPH{:P{wP\:$Hd}y9e \e }\ C/*@IT,/&O*@@ss&P ~8&PC=I+{ h;+|gp<s|v|#?<| M#?M</MM|L`#?LLE}-(=F[}<}Hc<};S c}XS ~qo~g}aLx,=pL~bb`&Q{>~~Xb`&j~w~`.b`&9~F~b`&X~~b`&x~~Eb`&R~`|&nb`&nqn~y={x&R>((&R@ (85}?I3@[?B#qI#!?I#L#LULSwBRu~2L@ALD( 5?g(S(ɀL8#;?LLLP#;LLaLp5pL54\ \ EpzCZ'['\ ]f@Y/3;%f#A܁ % ;3;3PfABRqIP#bAIRLY#LLwBRu_3`fBBׂqI`#AIׂLf #LL5wBRv _uB_ `S_g___3 fBBqI#BIL#LЃLwBRu_3feCBu`qI#,CIu`L#LL=wBRu_PO\ 0\Kz{'z{'X{ X{, {0D_, `P_d_/_w_H8{DÄH8Ä[3;NP{Du NP g3;sq {3E_q `7_W_u__h{FӅE8|ccPPwPc:$M$F^kUkjjjMF^kUkjjjg0{HP%F=. *GNfD~ |ccP 8PfwP:$M$PG^k$hUkj$jćjMG^؇kUk؇jjj؇$gzP{H~P4gPMg+Cg3ZHB?qIZ#HI?L_#L]LwBRvo\ 3r({]IBqIr#$IILx@#LLLjwBRu`3!{IBqI#IIL#LL'wBRu`z {J:~ g4g3{JBqIX#ZJILp#LL։wBRu`3 { KBqI#JIL#LL+wBRu`rZGrZPw^\ 0C:Sz~'z~'X~ X~\~L>o\oo3;b~PLĊb{3;s ~L_ `"_Z___~N"ZBMo|ccPPowP:$MM^ k UkFj8jjFMN^kUkjj׍jg0 P~}OPF#.pNNLDp|ccPPLwP/:$M8 O^͎k8Uk͎j8jj͎M^hO^u\k^Uku\j^jju\8gzd~aP ~d-4gd(MgOCg-3nHTPBoqIn#PIoLs`#LLwBRv\ 3x~PB͏qI#PI͏L#LLwBRu`3~QQB/qI#QI/L#LDLqwBRu` ~Q_ `____z ~QԐ~ 4g3~qRB.qI#8RI.L!#LCLp6wBRu`36(~RBqI6#RIL<"#LLőKwBRu` rZ[rZdw^T\ C[z'z'X XSؑ  3;.T^3;s T_ `___H_U( U A(|ccP@P wP:$M!XU^k!pUkj!j0jMNU^\kNUk\jNjqj\!g0\[WPF.iVND|ccPoPwPG:$MV^gkUkgj jjgMFW^u\kUku\jjju\igz8?X~Xǖ4gxMgCgǖ32XB qI#WI L#L'LIGwBRv\ 3XBgqI#~XIgL#LL8wBRu`3/YBɗqI#XIɗL#LޗL wBRu` Y_ `_2__E_Yza Yn~a n4g3nOZBȘqIn#ZIȘLq#LݘL wBRu`3(ZBqI#ZIL"#L2L_wBRu`FS\rZrZw^\  Cbz'z'X X([r( 3; @ \ @ 3;s%  n\_%  `V__) __B X]VP x\ۛx|ccPV PwP f :$Mq _]^@kq Ukzjq jʜjzM ]^k Ukj j jP q g0 9_PFW. e^ND|ccP (PwP :$M @^^k XUkj pjjM $_^u\k Uku\j jju\  gz `?~ a4g MgCga3 `BqI #_IL #LL wBRv# \ 3& `BqI& #\`IL, 0#L#LE wBRu`33  aBcqI3 #`IcL9 #LxLH wBRu`R  oa_R  `_̟_U _ߟ_z  a~  5 4g3 -bBbqI H#aIbL `#LwL wBRu`3 (bBqI #lbIL "#L̠L wBRu`6 B    rZ rZ w^ \ I Cjz'z'X XL xc =L x=_ 3;R cR k 3;su  Ld_u  `_(_y _|_ e( d=u|ccP P=wP :$M =e^ڣk Ukj (jdjM e^k Ukj jj  g0 @gPF. `CfNDR`|ccP xPwP{ :$M( f^k( Ukj( jjMN g^u\kN Uku\jN jju\ ( gzT g٥~T 4gT MgCg3^ 8gB=qI^ #gI=Lc P#L[L} wBRvs \ 3v hshBqIv #:hIL| #LLߦ wBRu`3 hBqI #hIL #LL? wBRu`  Mi_  `R_f_ _y_z  i~  ϧ 4g3  jBqI #iIL #LL>& wBRu`3& (jBQqI& #JjIQL, "#LfL; wBRu`     rZK rZT w^D \ !Eo_fSr. pfS: pfS q. <? tN  tvkxjk k0 |k0 ,6,`0 c-a a<C rl=C ,6,=`C c-a= aOV l2V ,6Ƭ,`V c-a abp xnmEp ,6I,`p c-a a{0 zmΓH ~mΓ=` mΓe In ,6,` c-a aȯ  hnΓ n ! ,64,!` c-a! aG" oΓs% % ,6,`% c-a aư0!o!% L o oאא"lw_Br/ pB: pB q/ <x? t  t[pooë8 |;q6۫o8,ooޱI8 pIޱqI8IޱWI8-fIޱN s2fEYXd ë@ rk۫o@,oײoI@ qIqI@IWI@-fIN s3fFYYd ëH rl۫oH,oسoIH rIqIHIWIH-fIN s4fGYZd ë_ xsmִ۫o_,ooI_ sIqI_IWI_-fINg syfYrd I zsXI ~tXڵI 8tXë@ u*۫Lo@,otoI@ tIqI@IWI@-fIN sfŶYضd IG 7uXëJ v۫oJ,o0oDIJ uIDqIJIDWIJ-fIDNQ sWfjY}\d ëy Ow۫oy,oٷoIy( vIqIyHIWIyH-fII}` wIqI}IWI}-fIN s,f?YRd I XeS0wwRk -v,kV"x"{_kr/ pk: pk q/ <x? t}7  t=xawTwlw0 xxww 2,$ظC] lwN |xww  Q,$Uhb] lwm 9yww p,$ι] lw" yww ,$ ] lw yww; ,$Na] y ztlw Tzww ,$] y szźlw zwwݺ ,$.] yP zzyh ~{>yp f"g{{%kr k: k 0{r,"{Rkr/ k: k /{ | ao__xo |__nrbAX|7| a__x7|bAp |T|l lHM'թN'WO ?YPW[R:Z@XE$ T|^$T$) # (T>}#Ҽs (6tXs# T}#$s $ts"{ @TcY{HL{ٿ?{ci p }iHi g{  {{?i ,1~i?i  ,~ pi ,iip 2 ,D3 2BFqI  #~IFL 8#LLqwBRs2,Du`32Bu`qI#mIu`L#LLwBRud{ P {{{  'Ji  ,iiJ h ՀМ2,D32BqI#IL#L LmwBRvw  М2 ,D30 2BqI#TILH #LQL'wBRs2)`  #D3)x 2BqI) #IL/ #LMLoGwBRs2Q D3Q2BqIQ#}ILW#LLfwBRuO М2,D32BqI#'IL#LL wBRv2: TD3: 2BqI: #IL@ #LALcgwBRs3K ToBqIK8 #6ILQP #LLwBRs3h _BqI #IL #LL[wBRu\$ f  %y%{ f{{{- {[: vƂނ҂v: M| iU)|| JƂ/ނG҂\v M/G\eleoeok} l}z}(~ <~T~,H~A}M}~,~A5nu2fTDc3f2BcqIf#pIcLl#LxL{wBRuO3{&T"BqI{#IL #LLwBRuO zr] cpY\ \ \ { lHW?Y|9rώ'3'թ'C' xW?Yd90 |9 3AP ԉBAqIAp #IALJ #LLXwBRu_3U LBqIU#IL[ #L'LpGwBRvf lk0lq {= qSqoSIq6I`{ x`Fn`{|?}`oS}SWIfIS ыSSvS( JSSɋH dڋ33h ;B3qI #*I3L #LULwgwBRw SoSI6IɋNڋ3;BqI#IL#LLwBRw<|}"cP!cP)}w}3BqI#ލIL#LL<wBRu_3$BOqI#VIOL#LdLwBRu_ (r] Ah\ \ \ Q2   ,#/($   #$/{3 %-3 -vMAC %ҹŹ)cOC O]{OnO)0OPi]UOHO;O[fe Ns gNNNK%N{N^( %%NN6NSNWJJN׃NNws"# C4 a@ #np000/6TX]6Xh 7ʭPGh ݭK  y /LPLsh SsS%WIfI% ʭQz ݭK& y LLHO& "O.9] 9hwBuXqI#>IuXL#LLwBRu`&39 BqI9#ILB#LLwBRu`SM3S WIMfI TS0g#TQTa] hXh~qg5oXo~qgֺHߕ"`%巕"`K`y"l_`X%~qg^vSxS^S3BqI#RIL#L*LYwBRuWvSSwS37BqI(#IL@#LL>(wBRuWSS\I6I\qII\WI-fI\SS~WIfI~3X_BqIx#&IL #LLowBRs3טBqI#IL#LL9wBRs3OBWqI#IWL# #LyLwBRsq^ ^^ 3Oq^8-^^83O }!"O9] Oq^P^J^bP3JbO3/BqI/#ƚIL5#LL3IeBqII#,ILO#LL^wBRuW3^ݛBqI^#ILd#L)LVswBRuW3sUBiqIs#IiLy#L~LwBRu`3͜BqI#IL#LLwBRu`pYMpYE\ 1118eL lHagͶhAh"j"S]q%^"r%,is'asȝb}b}[t@uL jx'Vedx+)e)e(|y9az\F\<}$$q$YlK$yʞYHrh 3`lB)qI#3I)L#LKLmwBRu_3BudqI#IudL$#LL3wBRu_pY/2apYYjv4rh3BqI#sIL#LCLrwBRud3 $BqI#IL#LLwBRuda\ 13@g-B3'40*IN4¡II`%y>K`y>l_mXm%~qg"\ str )'& *' str '& ';.3M#W W.4' .4%2.4'@Lއ.5@[$.<R].=HŮ.`\T 8.: vS.+Se  #.=X #/y#)ZP)irhѫk.>'/F3.@\FDe.F$p.@¢ѢT *#T,T] ֺ& +&%嶥&K&yl_&3X9%~q8gK < .A ^ MQ.\.Bv|ccP_PvwPr:$r.BA|cbr(ccIr 4IqIrIWIr-fI:$=8.B]S-8|ccPPPwPC:$3h.V BcqI#IcL#LL .Tr9 Q|ccPP9wPg:$8#it.GhH .HʨW /X. (.G= 1$$d;.JWdJdG N(.Qc 2 E( _23s .CBLs #LL{wBRD$@.SDr:@|ccPXPrwP:$x.SҪx|cb(ccI ŪIqIIWI-fI:$3V.VBqIV# IL\#L$LQkwBRD>.>d>wT #TTd] S #Se 'it.XhH .Y)W ./X.. .XR= F$ .[ ^ |'Q.3'.[BqI'0#ìIL*H#LLwBRwA.\fCA|ccPDhPwPgW:$_].\____cPqcPq.\ |ccPwPwP:$.`P&b.a&CT$d WdCJdT3.` BkqI#IkL#LL"wBRw.=d-&/Z5S,M.hį^kUkjj j&.=- &&/Z5 5S,M5!.hh^Mk5!UkMj5!jcjM3s.`߰BwqIs#IwLy#LLwBR@S.cSWIfI3.cBqI0#XIL#LL wBR@ _.e^ 3.c#BWqI#IWL#LLLwBR@Bc ^ T\ 61!*,*_H;*PJ*U*Thڲ#T@T ] ֺ()c(%)cK(y)lc_53FBqIF#³ILL#LLwBRuf3rBqI#2IL#LLwBPvtRufFދދދ\ ]C^$%#|:$,.i%9[[[+M_\F\arg0cS5nSWI5fIR*jB%$dLWdJd$dLWd#Jd;$dM(WdJd$dM\WdJd &3ԶB:qI(#I:LH#L\L~wBRuc3?LBudqI?#IudLE#LLTwBRuc5~zpPuds2$v"K+++-K+i++;+Yw+45Pwa]\  X   %~^%#|:$5`i%[[[+M_\F\arg0S7\S1WI7fI1V&zjB%S$dLWdfJd$dLWdJd$dMWd=JdU.$d5MJWdJdF3ºBqI#IL#LL#wBRuc3`:BudqI`#IudLf#LALnuwBRuc7 O+++5U+u++5U+u+U5PuTa~\  F0`  5#-% \QyIR{RRcPH{PwP\:$Hd}y9e \e }\ < }*JW%K\J%-N <HUb),-7B8PMFP¾qcP_PD wP:$cPPwP:$Ze =}}f,tc #`Br] \ @( Lh4cLhr4-Lh<4hHUbdʿ,7PFJqscP;PD wP:$cPkPwP:$e = }},Ttc d`r] "\ 0%/</<-<<HFUdbdW,7zPF q+cP0PD wP:$cP`P_wP:$e = } },wDtc T`zr]  \ # &4%  45 bH: 0= 8b)/%= 8\= X-= X<XHU8b8X ,c7z <PFqcP PD wP :$cP PwP :$ e   =!}!} ,H tc X `z r]  !\ r !Pn.!;!\ } %<lHHni@!0};R!<W!0`!@/%`!`!-`!<H,UJbJ!,u7"8PFPqcP"6P wP #:$cP #fP; wP#:$"e "*#=2#}h#}",S n!tc !`"r] !p>g  p!  ! > cPU"<P wPi":$cPl"<P wP}":$!b U""="}B#}!b !" !  cP!HzP; wP":$cP"HPc wP":$!b !&"=."}U#}J#\ ]#\ p#\ np#;}~##\  JU &4;#qJ#\#0#(\ { #P c#Pr -#P< PH U b #L, 7$xvP0 FT q 3$e $%cP%cP%=&%}L%}A$, #tc #`$r] #]3#0#]/ %) #R  # -#< H U b #,7Z$ $P0FT8qs$e $$cP$cP$=$}9%}}$,#tc #`Z$r] A%\ T%\ `%, X/lHl%/7q%0z%x4 z%cz%r-z%<HUb%,:7Z&PMFpqs&e ''cP'cP'='}o(}&,%tc %`Z&r] %5C/%H%f%0-%0<0HUb%{,7&`P,FBxqv&e ((cP(cP'(=0(}Z(}& ,%tc %`&r] 7%1FR%e#W%#YcPH'<PwP\':$cP_'<&P wPp':$%b H''='}(}%b %"!&&(2Y(&H&Hp&cP&<BPtwP&:$cP&<rPwP':$&b &'=('}E(}/&"B&M(\ b(\ w(\ (\   38!$(%<Y(h (63(8YU(%hr(I8FIIg3]BqI#NIL$#L;Lu7wBRo (D Ij__x`D5d uj__x>7b ! ?x__nTrCIB!iŐ0DB:0DBD0EŐ>0GŐKIStr (ic7  (p\'O$Cd%Qm84vl84$X%9$a5H/!oK+5,oK@% (%i~( WMWNTPpVQ%z#X}%^\Fz;la\FzQf}r(M)0= )OLa )a] )T*]]LZz)`[ZSz)wSWIz)fIfZ})`uZ-S})tS-WI})fI-HB@qI6* #I@LB*8#LLL5wBR}PBjqIM* #|IjLV*h#LL5wBRz&B!qIa* #I!Lj*#L]L5wBRzBqIu* #ZIL~*#LLq5wBRzBqI* #IL*#LL^5wBRz sB|qI* #8I|L*( #LL5wBRz@ B3qI+` #I3L+x #LL5wBRz QB0qI+ #I0L, #L~Lq5wBRz BqI , #IL, #L3L|a5wBRz /BqI, #IL(,!#LL1Q5wBRz !BOqI3, #cIOL<,8!#LL6wBRzP! B qIG, #I LP,h!#L` L q6wBRz!|B qI[, #AI Ld,!#L0!L!a6wBRz!B!qIo, #I!Lx,!#L"LV"Q6wBRz!ZBt"qI, #It"L,!#L"L&#A6wBRz"BD#qI, #ID#L,("#L#L#16wBRz@"8B$qI, #I$L,X"#Lp$L$!6wBRzp"B$qI, #lI$L,"#L@%L%6wBRz3,"e!B%qI, #I%L,"#L)&L&A5wBRz,"f9&,"zt&I'%-L#)(,#y8(& ,#&,#}&ҷ9y'9 '9 ''9 (%-0#g0#(%-p#m7-#m'(7-#@u(((7-#t( (Z7-$is($15($<HW)5($M+)W),5r] :$ɩ>-u(ة(jd9-@$@ydyd-X$DC6))-X$0ڪ)ΪªX$)!-X$0~V)J>[*X$d*-0K7*+*- ; 0P5+ԨS+ ; ;I ;e ;'e RD-e /RD@>zXD.Dq+8+XD`D ++`DMΧ+ا+iD\ r-Pg\+e,-P,8-  C<--e (-x$0(\-(I.PX|-.+I%.$g?I-%.$$- -%.$-Ԩ-$I%.$~I-I).G.%gT.3G.%]BT.qIG.#LIT.LL. #L.L.^.wBRz/l.>.l..D>/8`/l.p.  s//p. MΧs/ا/y.\ |.;h//8|.C/.e (.$(:0(.+.$iG008. C0.e (.$<(@1(.+.%k(1vS. %dS1S[2 /3 /8%kB2qI /X%#I2L/p%#L3L 46wBRz  /m14/O 4/ pQ@/^ @/%rG*4?4%}U4}*~7^5%J53C?B5qIC #I5L%C#L5L 67CwBR|37CB6qI7C #~I6L@C#L46Lc6RCwBR|3RC1Bv6qIRC #Iv6L[C#L6L6mCwBR|3mCB6qImC #pI6LvC#L6L7CwBR|3C#B%7qIC #I%7LC#L;7Lj7CwBR|3CB}7qIC #bI}7LC#L7L7CwBR|3CB7qIC #I7LC#L7L8CwBR|3Ct{B-8qIC #TI-8LCk#LC8LX8/_ /e 4i4444*4455c&Jkk8x88N9^ 2c2 }$ }2 364B9qI6 #I9L6#L9L96wBRz364WB9qI6 #I9L6#L9L96wBRz364B :qI6 #I :L6#L :L5:6wBRz364KBH:qI6 #IH:L6#L^:Ls: 7wBRz3 74B:qI 7 #I:L7#L:L:(7wBRz3(74?B:qI(7 #I:L17#L:L:C7wBRz3C74B;qIC7 #~I;LL7 #L;L-;3}7/B@;qI}7 #I@;L7#LV;Lk;7wBRz37/B~;qI7 #^I~;L7#L;L;7wBRz37/B;qI7 #I;L7#L;L;7wBRz37/B;qI7 #RI;L7#L<L%<7wBRz37/B8<qI7 #I8<L7#LN<Lc<8wBRz38/mBv<qI8 #FIv<L 8 #L<L<318$/B<qI18 #I<L:8#L<L<P8wBRz3A#aB<qIA #&I<L A#L=L=AwBRz3A#B-=qIA #I-=L'A#L@=LU=9AwBRz39A#UBh=qI9A #Ih=LBA#L~=L=TAwBRz3TA#B=qITA #I=L]A#L=L=oAwBRz3oA#IB=qIoA #I=LxA#L=L>AwBRz3A#B">qIA #I">LA#L8>LM>AwBRz3A9#)B`>qIA #I`>LA0#Lv>L>/e /f -04f 80_f c0i|0000*000c2i2.2B2R2*f2z22c2r^ 2^ 8i88 99*/9C9I9cH&>3;@B>qI; #I>L(;#L>L>:;wBRz3:;@RB?qI:; #I?LC;#L?L-?U;wBRz3U;@B@?qIU; #I@?L^;#LV?Lk?p;wBRz3p;@FB~?qIp; # I~?Ly;#L?L?;wBRz3;@B?qI; #I?L;#L?L?;wBRz3;@:B?qI; #I?L;#L@L%@;wBRz3;@B8@qI; #yI8@L;#LN@Lc@;wBRz3;@Bv@qI; #Iv@L;#L@L@1_ 1e 3i33 44*.4B4V4\4c38h&DB@L8&#L@L@#8wBRzqI: #I@3:DyB@qI: #>I@L :#LALA:wBRz3:DB0AqI: #I0AL(:#LCALXA::wBRz3::DmBkAqI:: #2IkALC:#LALAU:wBRz3U:DBAqIU: #IAL^:#LALAp:wBRz3p:DaBAqIp: #&IALy:#LALB:wBRz3:DB%BqI: #I%BL:#L;BLPB:wBRzu/yf 0d 2h9i9999*999c&s%cB3AsBBqIA #IBLA#LBLBAwBRz3AsVBBqIA #IBLB#LBLBBwBRz3BsBBqIB #IBLB#LCL(C/BwBRz3/BNsJB;CqI/B #I;CL8BE#LQCLfCNBwBRz3}BsByCqI}B #IyCLB#LCLCBwBRz3Bs>BCqIB #ICLB#LCLCBwBRz3BsBCqIB #}ICLB#LDLDBwBRz3BNs2B0DqIB #I0DLBE#LCDLXDBwBRz51_ L1da 3i(3=3Q3a3*u3333c]T1&t]kD]s]W1&u]D]Dc1&f D'E"c1~f1Duc1$uDuREpp1~Dup16uEuV1~eE1` ҷ1}E1 E1E F1U1 `xFlAF*1 M9OFCAF1\ & i1v ? TF5 F31 'eF BFqI1 # IFL18'#LFL G5wBRz31P'w B+GqI1 # I+GL1h'#LOGLqG2wBRzW7'f/ GW7&h G"W7~= 1GuW7$uGuGVn7'~] eHv7` ҷU8}/HU8 /H[8DHfH[8U_8 `xlyH*_8 M9OCyHh8\ 3k8e BHqIk8 #n IHLt8#LHLH8wBR{38$w! BHqI8 # IHL8#LHL)I8wBRz; B#LMLM>wBR}>;BNqI> #jINL>2#L&NLUN5>wBR}3?\BhNqI? #IhNL?#L{NLN?wBR}3?\BNqI? #\INL?#LNLO?wBR}3?\BOqI? #IOL?#L+OLZO?wBR}3?\BmOqI? #NImOL@#LOLO@wBR}3@\BOqI@ #IOL @#LOL P2@wBR}32@\zBPqI2@ #@IPL;@#L3PLbPM@wBR}3M@\BuPqIM@ #IuPLV@#LPLPl@wBR}3@&kmBPqI@ #2IPL@#LPLP@wBRzG)d e)f )))) *&*6**i*i*i+++?+S+h+|++*++*++*.:r>i>>>>*>>>c?i:?O?e?w?*???c8\ yjGCI* uj*:*__aG7CI*!iŐ0D*:0D*D0EŐ>0GŐd/D's' Q$dD Wd JdQD$dD-WdRJd)SD$dDaWdSJd0TDb E'(cTcTI E ITqI EITWI E-fITE:$ E DT%x E4xTx E}xTHE'1  THE'7**UTbUyHE'bUɩHE'ةbU(5KE(dUWUM V(KE(UU V(&@VZKE0(i Vs@V0(1KE0(< VH@VKE0(M V+lV@ViEr] ^~EX( VVW ~EX(0BV6V*WX(P?WL~EX(0~VuVikWX(W~E0KWWEF 0P #XԨAXF FIFe F'e F-e Ep(# aXE(7*XaXX("5E(dXW5YMmY(E(X5YmY(&YZ3F(!imYsY(13F(<mYHY3F(MmY+YYQFr] ^fF ) Y(Z`Z fF )0BY6(Z*`Z )PZLfF )0~Yu(ZiZ )ZfF0Ks"&[\[FG 0P"[Ԩ[G (GIGe 0G'e CG-e y0F@) #Xɩ0F@)ةX/F>[F.D[8\FF \7\FMΧ\ا7\F\ EX)&J\Ex)7*\J\\yE)o$\ɩE)ة\)5E)d]WY]M])E)]Y]])&]ZE)x%i]s])1E)<]H]E)M]+^]Er] ^E* H^^^ E*0BH^6^*^*P^LE*0~H^u^i_*T_E0KY&}__FG 0P&_Ԩ`G  GIGe G'e 7G-e DDcP EcP E}F\ F}F\ 1"R'{%BI_Tp B: BK R'אPG. &7 .3 ./ .  *|.y .'` 'mG ((D'V`7'`*'`mG MA5Go,G R(7`G2>cPGH* (P`wP2aG:$bG`* )(c[acIG )I[aqIGI[aWIG-fI[aG:$cPGx* B)PnawPaG:$bG* )(cacIG )IaqIGIaWIG-fIaG:$cPG* )PawPbG:$3G* v*B2bqIG*#=*I2bLG*#LjbLbHwBRuTIHJ [,IbH4+$b bH4bԨbH4IH4~IbIbH+g*c3H+]B*cqIH#j+I*cLH(+#LbcLc-HwBRw/;H>c;H.Dc8c;H?H  cd?H MΧcاdHH\ bH@+ ,(c"dc5dIH ,I"dqIHI"dWIH-fI"dH:$cPHX+ -PHdwP`dH:$bHp+ -(cdcIH+ -IdqIH+IdWIH+-fIdH:$3I .BdqII#-IdLI#LdLd$IwBRuTjG9.Pu\Ru mH~HcPHcPHcPH}H}I I\ 1117/0I%I &7 '| %I+I3 *I5q \F1 %do D z TU_L 8d_qSLMSrIL6IrqILIrWIL-fIr cPL0 49PswPsL:$bL0 9(ctcIL 9ItqILItWIL-fItL:$cPL0 9PKtwPtL:$3L1 h:BtqIL 1#/:ItLL81#LtLuhNwBRud3LP1 :BB`xqIP#>I`xLP#LuxLxPwBRu`3P >BxqIP#z>IxLP#LxLxPwBRu`3P +?B yqIP#>I yLP#LyLLyPwBRuP3P$ ?B_yqIP#j?I_yLP#LtyLyPwBRuDP@ByqIP#?IyLP#LyLyPwBRud3P @ByqIP#S@IyLQ#LzL3zQwBRud3Q @BFzqIQ#@IFzLQ#L[zLpz)Q#cABzqI)Q#*AIzL/Q#LzLz>QwBRud8LiRLdLL MMAMMM|McPMoj3N2 >BBzqIN3#BIzLN83#LzL{NwBRud3O BB<{qIO#}BI<{LO#LQ{L~{OwBRud3O  CB{qIO#BI{LO#L{L{3O  CB{qIO#[CI{LO#L{L|OwBRu3O DB&|qIO#CI&|LP#L<|Li|PwBRud3P  sDB||qIP#LDI||LP#L|L|3PP3 DB|LPh3#DL|L|'PwBRudqILQ#I|3+P cEB|qI+P#*EI|L1P#L }L:}@PwBRud3@P EBM}qI@P#EIM}LFP#Lc}Lx}3UP AFB}qIUP#FI}L[P#L}L}jPwBRud3jP FB}qIjP#FI}LpP#L}L ~3rQ GB~qIrQ#FI~LxQ#L4~La~QwBRud3Q GBt~qIQ#^GIt~LQ#L~L~3Q GB~qIQ#GI~LQ#L~L~3Q" cHB~qIQ#*HI~LQ#LL2QwBRudTIcIcPvIIIW'IIJW'HJ]JnJW'JJJW'K-&K:KW'rKKKW'KFNcPNcPO\ 99n8OQZ &7[ Z3Z \FcPR3 IP wPER:$bR3 BJ(cncIR 7JInqIRInWIR-fIn!R:$3[R3 JBqI[R4#JILdR4#LqLԀeUwBRud3oR04 2KBqIoRH4#JILuR`4#L&LH~UwBRud3Rx4 KBfqIR4#qKIfLR4#LLUwBRu`3R4 "LBqIR4#KILR4#LLUwBRu`3'S5 LB$qI'S05#aLI$L0SH5#LLUwBRu`3;S`5 MBHqI;Sx5#LIHLAS5#LjLUwBRu`3S5 MBqIS5#QMILS5#L0LUwBRu`3S5 NB΅qIS6#MI΅LS(6#LLUwBRu`3S@6 zNB0qIS`6#ANI0LSx6#LLUwBRud3T6 NB$qIT6#NI$LT6#LDLfVwBRud3KT6 jOBqIKT6#1OILTT7#L͇L#VwBRud3_T(7 OBDqI_T@7#OIDLeTX7#LfL#dIL[(>#LL)\wBRu\3[@>; [eBWqI[X># eIWL[p>#LyL]wBRu[xfi> %8|[>> eG|آb[>Z!ba[>b%b%{[ ? f|N|n׏[ N[ n[>K@n5nN*nǣe[>/ee[1\4IcP,\>B fPwP <\:$b<\>B ^g(c(cI<\ SgI(qI<\I(WI<\-fI(L\:$3Y\?B gBhqIY\(?#gIhLb\@?#LL$]wBRud3]- NhBqI]#hIL]#LLE]wBRud3] - hBXqI]#hIXL]#LmL3] B -iBqI]#hIL]#LLڥ]wBRu3]0 iBqI]#liIL]#LL/]wBRud3] 0 jBBqI]#iIBL]#LWLl3]X?9 jBL]p?#fjLL^wBRudqI^#I3 ^, jBqI ^#jIL^#LҦL ^wBRu`3$^) skBqI$^#:kIL*^#LL=9^wBRu`39^) kBPqI9^#kIPL?^#LfL{3R^6 SlBqIR^#lILX^#LLg^wBRu3g^$6 lB˧qIg^#lI˧Lm^#LL^wBRu3^2 EmBqI^# mIL^#LLJ^wBRud3^2 mB]qI^#mI]L^#LrL3^; #nBqI^#mIL^#LLܨ^wBRu\3^$; nBqI^#bnIL^#LL1_wBRu\3 _ , oBDqI _#nIDL_#LZL&_wBRu`3-_' yoBqI-_#RoIL3_#LLũ3L_%' oBةqIL_#oIةLR_#LLa_wBRu`WWcP9XiMX\XW'XiXXW'Yi0Y?YW'~YYYW'YYZW'JZ-]ZlZW'ZiZZW'[FT[i[{[W'[cPY\cP]\ H _qNy yC Ny%?Cyj D. ~v ~1  ~_? 6rz3Mc@%rBqIMc #qILVc#L)LXhcwBRu~__5Z_? jrZkZ`B_ `?1 8tI+ `@r$`g$`8@esv;$`h@#?s;` M`@#?Bs/MM׮`Lc##?LLb-`@sFx<`@csBa^a c%X^a ~qg%aLlc!!tpLðcuacc3a@3 tBqIaA#wtILa A#LSLbwBRu~(a8A1 v (8a`A5uI 3aA@fuB[qIaA#-uI[LbA#LLbwBRw2L b@AL$bD($bA5ug(S(cL-bA#;uLLL?bA#;LLaLebB5pLM}bɋ}b B vڋ3}b@B;BqI}b`B#rvILbxB#L^LbwBRu~ɋbB4 Awڋʵ3bB;BʵqIb #wIʵLbB#L LJbwBRu~ɋc wڋh3c;BhqIc #wIhLc#L~L#cwBRu~ɋ#c*4 ixڋ3#c*;BqI#c #.xIL,c!#LֶL>cwBRu~3c&3 xBqIc #xILc#L.L]cwBRu~__#_Bc _^ __ a$Za&ba*d a]_ cGc\ H%#yvŐ{ŐvŐ:vŐDvŐiyy d__nc__s'CEj-zCIŐ!iŐ0DŐ:0DŐD0EŐ>0GŐ]iEzi ujGcp__xGiB#}Q\BLz%=1ڃBM,SyJCS{y.}yApyJC.AJC_X.KA>CgaJCV¸CvSk(CSS:xvS@CW,|SMS3XCW|BqIxC#k|ILC#LL˹wBRuc3(%W}BqI(#|IL.#LL+=wBRucGC^C^Ej0=`Ej>YWa[csob[cyC_}yryyֻCyjd}ydydCc7WvC`~oZDa~iǼsD1<HM+r] (Di %/=C1oڃ(DM/Co@Drp)d@D0.d3@D0h\Pd@Dvwy@D0~zzy߾@Dz90K7L+ 0PLԨ I-e e 'e 2hDy) 2hD0. 32hD0h\ PhDvZy2hD0~zz yhDz@0K~7+hN 0PԨ  Ie ('e -e d*$ d*Ԩd*Id*~II&xgD3x]BDqIx#IDL}#L|LwBRud.D8   MΧا\ f$ fԨftIw{.D81w~  ]~ MΧا]\ 5ȟԟqMq3 BqqI#IqL#LLwBRud\e 'e e -e F\ אg} uj__x7kdD  %S%ecH5Z%$d d5WdJddBd%xBd4x xBd}x )_dD{) &)O )D5)TB)_d/b%x_d4xbx_d}xbDQ)iLd EۇBL5L-+LV[Nd@EԇNtN-jNVId`ECɇIVyg$$dndxEx}1dm%=1ڃdMde-z3dBqId#ILd#LLJdwBRuLL eEBL]5L+L[N eEN+tNjNI eCvIg$$;en>eE%c}Je%=1ڃJeM[e-g-z3geEB*qIge#dI*LmeE#LsLgwBRH3gB qIg#܊I Lg#LLLgwBRH3gB_qIg#TI_Lg#LtLgwBRDdxeFE>xeFWMExe Fg ʄE F؄~e@FhZʄ8@F؄e`FiʄL`F؄IexFsIeF$9 meF9ԨmFIeF~I9IeFg3eF]BqIe#ILeF#LLewBRuP/e>;e.D8ee  ?[e MΧ?ا[e\ g3eFBnqIe#InLeF#LL\ gwBRXjdeG/ydzydzNj7f0G]jgjNjOf1q]jgjANjif2]jagjf G9>mfIfHG9ʑIfpG$ fpGԨpGIfpG~IIfGg3fG]BqIf#ِILfG#LMLfwBRu`/f>f.D8ff  f MΧاf\ 3:g4BB%qI:g# I%L@g#L:LgOgwBRX3gBzqIgG#IzLgG#LLgwBR@\d!fMi'fcAf1[f1uf1fr] [gg\ cg\  h0z ] "hGǔl uf'hHfWff7h Hf>h ʓGhda 3Jh8HABqIJh#ILOhPH#LL7hwBRug3hBVqIh#wIVLh#LULhwBRug_h\ 'hw hh) alh a[lh -[[mvhhH[mh@Psh hEh\  Ğh h{^%#k|:,$k5@vS=HsSTSrJ3JHsBqIJH#\ILSH#LL wBRuc ^Hw (SdIblpj6$ j6Ԩj6Ij6~IIIg3I]BqI#IL8I#LL9wBRwXIix%WnIy}%E=]1rڃME]ro-z3IyBqI#ۘIL I#LL wBRuc3yBudqI#SIudL#LL<wBRuc  0~˙ O {>> F0 II }3sBqI#TIL#LLwBRuc= \ \ {/i#|:$5i^$%#k|:$k,vSEIsrSSS3SIsBFqISJ#IFL\0J#LdL|wBRuc gHJw7 Sl`JblrJ$ rJԨJIrJ~IIJgK3J]BKqI#IKLJ#LLwBRsJix%nJy}L%=1ڃMo-z3KyeBqI#,IL  K#LL0wBRuc3yݞBudqI#IudL#LNL{wBRuc~zPsv2$u " ( ~3  44 S<0 ?!} QE~zPsu \ /i#|:$,i EFРE*Ex8Kg_8K]q38KBOqI#IOL%PK#LL8wBRoиߠ i__x>(B} " Q__nsCI u!iA0D u:0D uD0EA>0GA hK*JWm\J#K8JKo XРXKߠXK@JGuTX(L%G uTXPLGPL``L``LM(pr] $guT^i^xL@lmimi.LD{nHaTL0HL "L0~WHK?Leh$0KZ. S o 0P  E-e e 'e "@1,B6  (H M̲(ֲH\ Lѥ%[e !2cP?cPH=P}}tc #f:Jr] \ \ \ @BT#^ E V<m='%>%V?'' iv  Gr1'% -B W%Lmsg@3L5i̧D5i|cb5iL(ccI5iM IqI5i(MIWI5i@M-fIMi:$Si[i:[iXMFI/ cipM/Qkis^ikiMpmiumiu&jF<j|cjcPOjMoeM|cjcPZjM:z'pOM|cjcPMi%q:jMI kN/ ks^i kNémimi0N}J*:ii&ckNF#<[N|ccPgkNP#wPwk:$wkNdN|cbwkN(ccIwk WIqIwkIWIwk-fIk:$&k O˫F<9 O|ccPk@OPwP[k:$k`O{`O|cbkO(c{cIk }I{qIkI{WIk-fI{k:$3kOBqIkO#ɬILk#LL>kwBRP3kzBQqIk#AIQLk#LfLkwBRPbkSi­SWIifIiOi&biO8QEY9-#3ClDBqICl#qILIl#LLWlwBRv3WlD!BqIWl#IL]l#LL llwBRHiiQiSitSWIifI3i PBZqIi@P#IZLiXP#LLkwBRvjN  jpPc jpPrj-^jPx"=gjMgjPٰ^UkgjPUkUjgjPjjjU$jPD~:P|cjcPjQڱQ|cbj Q(ccIj@Q ͱIqIjXQIWIjpQ-fIj:$k"lM l"e^k l"Ukj l"j$jll"ֲB8qIll#I8Lrl#LMLzlwBRH5i^j8llf l\lf lf 'l\ 11AglJ -Bg30mQn߳BqI0mQ#IL9mQ#LL`mwBRu_3@mQnWBIqI@mQ#IILFmR#LiLwmwBRs3m nϴBqIm#ILm#LLmwBRu_3mnGBu`qIm#Iu`Lm#LL)mwBRu_l0l]mmm00m^m\ 5;5ŵ _Z%GFmX RXnHR<T`nHRc`<`nW*`pSnSWInfIM@n^k@nUkj@njjzVnhRַ~VnR14gVnRMgzCg13]nRɷBqI]n#ILbnR#LLnwBRu\rn\ Mn7^knUkjnj jzn}!~n6n4gṃn+nV8n/@nWnW3unR2BcqIun#IcL{nR#LLnwBRv3n)BqIn#qILn##LL owBRv o\ /j  i'7/ ocq*{# '&oSD'7'H*'j&oS MA5@ooLo(S{(SϹ\]o޹jd`o@SydydjdxoXSydyd&opSxF<pS|ccPoSPwPo:$dodd oSI*S|cboS(cc?Io <IqIoIWIo-fIo:$&oTFo<T|ccPo TPowPo:$oo|ccPo@TPwPp:$.p'ND1p'|ccPpXTPwPF/p:$@ppTvOp&bMOpT^kOpTUkjOpTjQjMqo^kqUkjqjjXoqpTT|cpcPpTh[T|cbpU(ccIp8U [IqIpPUIWIphU-fIp:$pUU|cpcPpUikU|cbpU(ckcIp \IkqIpIkWIp-fIkp:$opU +cU|cpcPOpV oeV|cpcP&p(V /FC<{(V|cpcPM/q^k/qUkj/qjj3Eq@VBqIEq#ILKqXV#LML|qqwBRud3uqBqIuq#GIL{q#LLqwBRu[Mq^kqUkjqjjqpqV'q//qWq\ qW17(qos(o )t3rpV+BqIrV#ILrV#LPLrwBRuWI&rS+I,rV$ ,rVԨVI,rV~II@rVg3@rV]BqI@r#ILErV#LTLvVrwBRv/fr>fr.D8frmr  mr MΧاvr\ 3r+0BuXqIr#IuXLr#L"LOrwBRuWqNPsRu rrrr\ 149rQWFlHb[V|pVu,íE\05'pVkí. 0Wr7r0LZr0W[ZSr0WwSWIr0WfILZrHW[ZSrHWwS WIrHWfI pWN$I?$gWy 0Y/0fZ"sWuZS"sWtSWI"sWfId0sWzW|ccP3sWPwPBFs:$FsX]eX|ccPLs0XPewP\s:$\sPXPX|ccPbspXPwPGrs:$_rsX_g_X__vcPscPsXX|ccPsXPwP5 s:$sYU Y|ccPs(YPU wP s:$_s@Y<_g_ `Y1__ vcPscPsxY xY|ccPsYP wP) s:$sYI Y|ccPsYPI wP  t:$_tY[_ _ ZP__ vcP&tcP&t Z  Z|ccP,t@ZP wPE ?t:$Z?t`Z!ze p`Z|ccPEtZPe wP Ut:$UtZ Z|ccP[tZP wP kt:$Mt^ ktUk jtj j M7wF^ k7wUk j7wj3 j 0stVt/tW4wWfZtZuZG StZtSG WItZfIG dtZZ z Z|ctcPt[U  [|cucP_u [_P _ H[__ wcP'ucP'u`[`[|c>ucPo?u[*H[|cQucP_Qu[_P _[x__$wcPqucPqu[[|cucP_u[_&_^\__vcPucP&u0\XF<0\|cucPuP\(P\|cucPZup\zpp\|cucPu\('\|cucPu\PO\|cvcPM4v^wk4vUkwj4vjjwMUw^kUwUkjUwjjt"vV,v/4vWuwWSw\ >wk a '\5PC8wC6we \p0_wf ]X_w(]g`__wH]__?x`]%M`]|ccPExx]P%wPUx:$_Ux]O__cPUx]PwP!OUx C"O]x9] nx:$gnx]±Q}]|ccPtx]PQwPyx:$3x^(BqIx^#ILx0^#LL'ywBRsMx^kxUkjxj&jzxP^kF~xh^h4gx^MgCgh3x^^BqIx#%ILy^#LL7ywBRvy\ M;y^k;yUkj;yjjzNy1~NyF[y4g3wyBsqIwy#NIsL}y#LLywBRuS?xxxVx/xWtyWwr_ w ` wQ] wf xW` cy\ y}Kr1-BK3y^BqIy^#uILy_#LLVywBRus3y&ButqIy#IutLz#LiLzwBRusyy0y^z\ 1ITpw'ZHD:'Nq''  ?0q"_Bqq%qvzJeH30_KBqIH_#RIL#LLwBRus3KB-qI#I-L#LBLowBRuse +PsQu-e -e 3`_OBqIx_#IL#LL-wBRus_He P'e z-e 3POiBqIP#0ILV#LLewBRus\s\ e  PsR0Qu2-e j-e s\ \ }W#I z $z 1)zy__*8z`p=z0Izj>ozPwzMzj>zPzj>zP EITȭpZHw'9D:'qH''  ?.0r"_Bb;r.r!r._eHEf3_KByqI`#IyL#LLwBRus3KkBqI#2IL#LLwBRuse PsQu-e -e 3 `O*B!qI8`#I!L #L4La/wBRusP`YJLe T'e ~-e 3TOBtqIT#ItLZ#LLiwBRus\s\ e  PsR0Qu4-e n-e w\ \ I{g%h`1>KXX{` `XXR{] { #{0W&{ WWRa1{` 1s~X|A e|AXX|] W[| % WW1{0{j>{{M{j>|Py|72|.%| #1>KX|O?ITpw'@D:'Ir''  ?0r"`BrrHrvz(eH3`KiBqI`#0IL#LL=wBRus3KBPqI#IPL#LeLwBRuse  PsQu-e -e 3aOBqI a#gIL#LL-wBRus8aHe P'e z-e 3POGBqIP#ILV#L L:ewBRus\s\ e  PsR0Qu2-e j-e s\ \ Ig|vMPa| #|0W|  MWWa|ha msX5}a aXXC}] aS |H}a -|9 eH}aJ )ee )ee } H%z }=1>KX}O}X}B }BXX}] W`~ W W |0 }j>5}.3~j>W~.g~6v~ +~lii %t![N@envrV@envsV@%P%zD~a?^ b b!u!!!B"" ~8b  ƒPsXWPbPbXXk] a]s"hbK,#b_vbnv#Evb@Tv#bTv#b[cEq[#sFw%R#v%vv$v%(vvv_$i t$ `X(c(cXX)] 7'$7(֛ɛ$ 4%@cR%bXcF!bq%aXcb%b%c%%c%ncR@nD&5n%*nY&e:/eeg"cvcU|mo&׀|Zo&\|$uo&k*&H&\6u&k5>Bl_Rc % c c &X"9v"9XX0] ނd&d'ZkcPxcP=cP=cP}U}(0d+'8'M٫=06̓HdAN'HdOl'['X`d`dXX#] ~-è]\ rITp$w'DD:'Ds'''  ?[0s"xdBs's((s(deHr(3dK B(qId#I(L#L(L)wBRus3KB0)qI#_I0)L#LE)Lr)wBRuse PsQu-e -e 3dOWB)qId#I)L #L)L)/wBRusewLe T'e ~-e 3TOB)qIT#I)LZ#L)L*iwBRus\s\ e  ?PsR0Qu4-e n-e w\ \ I B 'Q DbC %$` G eSJ$-*='_Y`LnY { -v9E*/\*@eYo*za yYȄXe)Y*Մ;|Մpe)Q**2*Ze ;Z*Z +B_  g  ]_  Y~)za 5\ )@3 Ge)+OeX+OeX+e+cPՅ<_P+wP:$cP<P,wP:$Ub Յ =}}db :gfI, j(f/H,|sՊ|Hfi,hf|,Ê,hfM|,,_hf q,3hfB,qI#I,Lf#L,L-wBRudf"6-fn-f-cP5HP-wPI:$cPLHP-wP]:$b 5j=r}}" .\ \ Ɔ\ U EZ Z%t53 YІ{E؆0vA{AA:ADA__na2 xi__nV__s'CCIA!iA0DA:0DAD0EA>0GA~  iG&#.__xG f@ Q)TT%Lqh..t.%M'.=.1."!  /I/=FgQ u/ehgS//hgS/F/9hg_//g-0hgVe00g1Hd(1ZJ1vS0gSl1S1HHgWd1ZvS`gS1S_gWq13gB2qIg#uI2Lg#L?2La2wBRu[_%Wq23%B2qI# I2L#L2L2wBRu[g C^0=`2YWa/3obs3h_ .4f44h#4^i  mimiCc4W+0h`9 UH+5`ha 5`h5M555#r] T)hiN h55tE6)hM'5=51E64h  66QLVhr #7r7Vh0.A4#7'7Vh0#77h72Vh0~g#7[O8huk8h`&0Ku ~8d"S 8Q 0P 9Q \ E-e Qe d'e Lhy\ 299rh0.A429'9h0299h92h0~g29[9Ohu:h!0K S:S : 0P8 ::  Ee 'e i-e + ;2;+;2;+ E+~*E;EE;xgc;_]qc;3B;qI#L I;L#L;L< wBRu\3 ,B61<3:  E<: Mֲ̲E<C\  Y<x<Y<x< E ,B6<  < Mֲ̲<\ * Ê<*M<_* q<3*B<qI* # I<L3#L<L%=BwBRu\e 'e 'e u-e \ Ap1 I  i__xI "B(f  G}J i 8= i t=  it=Hi =cP<) P>wṖ:$cPχ<Y P*>wP:$b =}}b :hi IB> !i/o>3s" ;i ; >1 >TG( h?3?tS?G(M'?=3?1S?K$  ??fuxi "?xi@i!@cPH PU@wP.:$cP1HJ P}@wPB:$b O=W}}"@\ \ \ A0   Z '  %-B  }J )5 ? t      ii  dĈ j @&bG͈  Y@͈FAX͈~qAgFAvS8j < SAS%B3Pj  BBqIpj#{ IBLj#LBLC8wBRug_j H q2C3jBnCqIj# InCLj#LCLCGwBRs_N   qD3N BDqIN# IDLT#L.DL[DcwBRug3n T BuhqIn# IuhLt#LnDLDwBRug 0N l\ /   E n8I CI\8!i\80D\8D:0D\8D0E\8k >0G\8D> (k0KV g E[CEt $@kS nE E3}/ BEqI}# IEL#LELEwBRug3/B B FqI#  I FL#LFLLFwBRug8M\Σ0P _F}F~_FF gFe 'e -e \ \#? v\8{\8v\8:v\8Dv\8/P `  E` n8~t   d__nx__s'C5|~h g#  Gx__xGg# Xk QLkL F) G8GkMЈF Gڈ8Gt k  aG G3/ BGqI# IGL"#LGLG1wBRuT31/{ BHqI1#B IHL7#L#HLPHFwBRuT4IXt ^kQ  cH H3/0 BHqI# IHL#LHLIwBRuS3// B,IqI#n I,IL)#LAILnIwBRuSy ZSc 1 I$ I IZIIIZ_?I2I%IZNIZV0J|JIZͻJ? :Z JP #KvSk/ SRKSeKvS/- SKSKvS /S8LSrL? kW" Z LP LvSl/ SLS2MvS%8l/ SbMSM4vS5Xl/SMSNFlFlW lIN3Fl/ BkNqIFl# IkNLOl#LNLNwBRuS3Vl// BNqIV# INL\m#LNLOwBRuS3c m/B/OqIc#i I/OLi8m#LQOLsOwBRuSPmR# C^50=`5OYWazxOobzx Pe pm_}  P~ Pt Qpm KQd Y ddCcQWm` Qνma* ݽ0Rm\RzM\RpRRr] mi R)RRmMЈRRڈRt m  KS S3/& BSqI# ISL#LSLTwBRuT3/ B-TqI#d I-TL#LBTLoT wBRuT " nra obTUTH n0. TTy n0TTnT "# ny obUUHGU# n0. UGUy# n0UGU ngU/ :8n! 2&UUΣ:8n8n:8n~U@PngUl@Pn]lU3@pn/, B1VqI@# I1VLFn#LmVLVwBRuT3Mn/ BVqIM#j IVLSn#LVLWwBRuT3a/B6WqIa# I6WLg#LWLWvwBRuT! %Wˢ ֢W MŢW\  n6" %Wnˢ ֢X MŢX+\ C" 2&ΣCCC~'XLngjXXڒm # Xm MÒ͒Xve 3'e <e je -e Ue \ \ n8|{# #  __x# 8# %  U3% # 'X2o% NXDXl# o# X{# 5Y8o% |Y)YY8oMЈ|YYڈYt ‰Po  Y Z3K /7% B#ZqIK#$ I#ZLQ#L8ZLeZ`wBRug3k/% Bs qIk#u% Is Lq#LxZLZwBRug։> a % sZi\ n82\L& ' DNl# ho' # Z{# [o' ^[)[[oMЈ^[[ڈ[t o  [ "\3 /R' B@\qI#' I@\L#LU\L\*wBRug35/' Bs qI5#' Is L;#L\L\JwBRugԊ 3\ ~P( ) l# _oE) # \{# #]go) Y])w]]goMЈY]w]ڈ]t ko  ] ^3ҋ /F) B7^qIҋ# ) I7^L؋#LL^Ly^wBRug3/) Bs qI#) Is L#L^L^wBRugˋ \ * ,  3G , ~"oH+ ^_l# "pE# ^{# _*(p+ 8_)V__*(pMЈ8_V_ڈ_t .@p  _ _3 /f+ B`qI#-+ I`L#L+`LX`wBRug3/+ Bs qI#+ Is L#Lk`L`njwBRugBWf \ n8~u, CI"9!i"90D"9:0D"9D0E"9b, >0G"9CI"9!i"9, ,  vB, 49, ;Z. +, `7, C, XpO. U, ` pp0K- `*au, $pS, Ua, sa3X- BaqIX#o- IaL]#LaLalwBRug.=aw0P0. auaw4w~TaH b g'7bwe 'e -e \ . v"9{"9"9:"9D"9__n. .  d__n__s'CH / =  5G__xG= p%4 QX|pL^0 Wbbb@pMOWbebYbu, p , b, :c3O0 BccqI#0 IccL#LvcLcwBRu`,;u, ApQ 1 , c, d3$0 BBdqI#0 IBdL#LWdLdwBRu_Wcl9S2 &dd dl9ddd?l9_dsdfdl9eZ. l9V. d. Few. dl9. eeevSM2 SeS fvS SfS4fqW3 IffvS0q2 SIfSfvSHqSfSfaopqW4 sog3q3 B:gqIq#p3 I:gLq#L\gL~gwBRu_3qBgqI#3 IgLq#LgLgwBRu_zr= C^H0=`HgYWa3hobkh. (r_4 . h. 6i. bi(r. id4 ddCciWNPr`5 xkiؿ$ra5 Sjr$jƿ$Mjjj-r] |3ri6 jjk@3rMOjejYku, ?r , k, k36 B$lqI#i6 I$lL#L8lLelwBRu`IZ_rr9 xlll7_r0.wxljl]l_r0xlllr)l, _r0~C, xl7, l+, ?mrU, ~mpr0Kn8 mnu, tsS, Fn, on3k`8 BnqIk#'8 InLp#LnLnwBRu`~a'0P8 VuuP'4'~TVHnsg'.oe 'e -e 0sy9 Zoo70s0.wZoj]o0s0Zoo0s)o, PsM; ŦopaPsuPs4Ps~THphsg'7paohs]so7p3s: BzpLs#: LpL qwBRu`qI#Izp3sBqqI#; IqLs#LUqLwqwBRu`; q^ iuq3 MBXLq#\ $n< Ŧa$u$4$~THqsg'qt< *rt^iu>r3MBXL>r%\ Q@F= \hRr+@M:DRrKe e -'e 6e f-e e \ \ 49#= {%fSr  fS: fS  0> r , #E> RfSr. fS: fS .T> l>  5__xl> 9Ќ> lL  QVslL  qL tWL frSMr@t? r> @trht? "scP}<p? PaswP:$cP<? PswP:$ b }=} }b 9t@ s tCNCtQ@ ]tzpCt6ptp4Kt@ C uzpKt$p up= Nt$G = Eu= u= ucNu @ dEu d:v[= \ u B = vc\Hu,DA dv dwghhu,A ؉|wΉwchhu,d|w dwvvu,+B x3vuZBxqIvu#A IxLu#LyL zwBRw,+z3ZB+zqI#B I+zL#L@zLmzwBRud> u D 8> z,>  > ߓ :C zzc ,dz dzv C ,{8v,{3XvZB{qIxv#C I{Lv#L|L|(wBRu`] D  }], }3]ZB }qI]#[D I }Lc#L}LL}rwBRu`jv PE _}v,_}3vZB}qI#E I}Lȍv#L?~L~7wBRwӍw E ~3Ӎ wZB qIӍ#E I Lٍ8w#LyLGwBRw xF 3ZBqI#>F IL#LL/wBRuT= B= ,B3= ZBBqI=#F IBLC#LWLVwBRu`PwG 3hwZBqI#~G ILw#LLCWwBRw3w0H BaqI#G IaLw#LL gwBRwNwrH ]+zpw6ptp8+wH QGvS+xSS939 x ȎpxJ ^> qT> |юxJ ؃&@юxMO؃eY&u, Վx , 9, e3zJ BxqI#SJ IxL#LL. (K 3ZBqI#J ILƏ#LɄLՏwBRuT3ՏK B qIՏ#gK I Lۏ#LLKwBRuTK "^3 x@L BuTL x##L LudLPwBRwqIv#IuT(7*\ (\ 149L O  lH O xO s6lH9v"M X~qgq^y|M ^8^Py38PO3ؐ(yM BpqIؐHy#M IpL`y#LL(wBRusq^xyNN ^^xy3 Oq^0N ^>^VA3QN ButqIQ#N IutLW#LvLfwBRusؐq> o\ 49$O IO  vBYIO NO 11-(pkO Q  GkeyQ /Q O uyPP ;O .O $O >3CP BqI# P IL#LՈLwBRuoaoy\Q so3yP BgqIy#P IgLz#LL߉БwBRuo3(zB qI@z#"Q I LXz#L-LOwBRuovL \ "\ 11d,0Q o|80ISO yPU key~U /~%pzxU d@c`z]R `cQ Vcmz|cq=rzR &bdzR |؊o(0SO 3z=S B`qI{#S I`L{#LLNjwBRuk30{S BqIH{#|S IL`{#LL7wBRsMÒT ^UkÒUkUjÒjwjUMwT ^kUkjjj3!T BqI!#T IL'#LɌL6wBRuk36gU B qI6#.U I L<#LLKKwBRuk`\ 11W *.n** u V X ~q^gR g\V XR ~qgsx{V %xsx{4xxsx{}x%c 3a Fa Ya ov c v c v c a ( ; Na a wv c a c v c  a 8Oc pc c FXFXFX//00#020A0P0_0n0}0000000d00  1 G1 $)1} Y91k I1X Y1@ i1 u1 1 1 2,@O 0_ o  ~ m g ` U N C 9!7 10  A( YQ a q 2  t%[ y' [ @!,L9RFTSIm/Gz5$)F+4aPx648} 999~D9*H*=FFA1<60s77D\  ] i%"] % CFj%9] 'm͝9%Q] ' [F%r] *''m4779] *] '%EǿgG%] ] X>vE/%] '' ;%] ''E J%^ 5(5(vo$%W ҔFs%F^ D'& SvFZ%\^ D \ %r^ %5%^ ^ v,^ ^ ݼ%^ 'E^F%^ Dԑ}^ ]9%'/9%_ ]''DtW%_ %mS*B_ '' FD]_ ''E*F%r_ D ͝'_ 'E%_ ''' *_ %~>m2|:e6D*_ '% %` %'MS G4@% ` '47~O9` NW` %y'7Hl`  {\*` *'3]>` ` vW`  ]6%` ` ''` %v` vǕ gvF%a D@%% ZF@%$a D K*F'Ia ''D L\%da %% l\a%za %EXF%a 'Egn%a %E;nx%a %EHKa a a vh+va V Wk%a *jdup\% b %E*oq%*b %%%Eo%Ib %Ib vOb > dk%yb ''?yb v?<kb ? sok'b % Zp%b b vˏ \p%b b "p%b b wpƎ O\nc %]' p%7c b 7c v=c  GFd%^c D'm p^%tc  kIpac vector::_M_insert_aux ^pY%c c Lv<+c ^ 5%c L $F2Dd %' dHF=%*d %D*H%Gd 'DO\[Zd % 7\hzd %'Eq֍d ֍|:% \%d |:wAS\֍ \%d ' a\'%d 'CCp֖%e ]]9%'e )}F*\e ]a5a5%|`RNe ]y'E2nv%e % +pd%e ]E7*e ' Ab%e %e e ve 84v84wn\%E\dr94f '%%%EsQ%Yf Yf %mvE^'rL%yf 'ETb%f f vETt%f %%mf 9%)f L(f  ]2% g ` '%/F']''D% U$ > 9: ; : ; : ; : ;  : ; : ; (  : ;  I8 9: ; .?: ;I</II.?: ;I<: ; I.?: ; n<&I.?: ; nI<.?: ;nI<.?: ;nI<.?: ;nI<: ;I.?: ;n<.?: ;nI< : ; I8 2 : ; I2 .?: ; 2 <dI4 .?: ; 2 <d! : ;I8 ".?: ;<d#.?4<d$ : ;I?2 <% : ; I8 & : ; I?<'.?: ; nI<(.?: ; nI<d).?: ; n<d*.?: ;n<d+.?: ;nI<d,.?: ;nI<d-.?: ;nI<..?: ;2 <d/.?: ; 2 <cd0.?: ;nI2 <d1.?: ;nI2 <d2.?: ;n2 <d3.?: ; nI2 <d4.?: ; nI<5/I6<7 : ; 8<9 : ;2 : : ;I?<;.?: ;2 <d<: ;I2 = : ;I?2 < > : ;I?2 < ? : ;I?2 <@.?: ; L 2 <dA.?: ; nI2 <dB.?: ; nI2 <dC.?: ; <D.?: ; <E.?: ; I<F.?: ; I<G.?: ; <dH.?: ; n<dI/IJ.?: ; nI<dK.?: ;nIL M2 <dL.?: ;n<dM : ; N : ;O9P4: ;I<Q:: ;R : ; S.?: ; nI<T.?: ;2 <cdU.?: ;L 2 <dV : ; 2 W : ;X : ;2 Y0I Z : ;I8 2 [.?: ;nI2 <\.?: ; <cd].?: ;<cd^<_.?: ; 2 <d`.?: ; 2 <cda : ; 2 b.?: ; n2 <dc : ; d : ; I8 2 e.?4<df.?42 <dg : ;h.?: ; n2 <di.?L 42 <dj.?: ;I<k4: ; nI?<l4: ; I<mn.?: ; n<o$ > p Iq : ; nr : ; s : ; ItIu!I/ v Iw.?: ;I<x : ; y9: ; z.?: ; I<d{.: ; I<|:: ; } I~.?: ; I<  : ; n : ;  I8 &! : ; I8 I: ;  : ;I 8  : ;n9: ; : ;.?: ;2 <d : ;.?42 <d: ;I2 .?: ; nI2 <.?: ; <d.?: ; n2 <d.?: ; nI2 < : ; : ;I : ; I?2 < : ;I8 .?: ;nI2 <.?: ;nI2 <.?: ;nI2 <d : ;I?2 <  : ;  : ; 2  I8 42 .?: ; nIL M2 <d.?: ; nL M2 <d.?: ;n2 <.?: ;n2 < : ;.?: ;nL M2 <d.?: ;nI2 <.?I4<d : ; : ;2  : ;I8.?L 42 <d.?: ;n2 <d.?: ; nIL M2 <d : ;2 .?nI42 <d.?: ;n2 <d.?: ;nL M<d9.?: ;L 2 <d.?: ;<.?: ;</.: ;I<.G<.: ;I<.: ;<.?: ;n<.: ; <4: ;nI?<4: ;I<4: ; nI?<4: ; I<4: ; I<4: ;I< 4: ;I<4: ;I<4: ;I<4: ; I< 4: ;I?<4: ; I<.?: ; I2 <d.?: ; I2 <d.?I42 <d.?: ;I2 <d.?: ;I2 <d.?: ;n2 <.?: ;n<d.?: ;nIL M<d.?I42 <d.?: ;nIL M<d.?: ;nL M2 <d.?: ; nL M2 <d.: ;I<.?: ;L <d.: ; I< : ;  : ; I: ; : ; .?: ;I : ;I.G dI4.G  4: ; I.G: ; d.: ; I 4: ; I5I: ; I: ; I.G: ; d: ;I.?: ; I .?: ; 4: ;I4: ;I.G .G: ; dId  .4 .1n@dB1.1@B1BB.G@dBI4I4.G@dI1X Y1 41: ; IB1.1n@dB1X Y1RUX Y1RUX Y1RUX Y  UB11X Y 11X Y .1@dB.1@B1 .1@dB1RUX Y 1  1.G@B: ;I U4: ;I4: ;I: ; I4: ; I4: ; I.G: ;@B: ;I: ;I.1n@B.1n@B41: ;I4: ;I.G: ;@dB41.1n@d4: ;I .G@dB.G: ; @dB: ; I.G@B4: ; I.G: ; @B4: ; I!I/.G;@B41 1.G@B4: ;I.G: ;@B.G: ;@dB: ; I.G: ; @dB1B 1RUX Y4IB.4@B14: ; I?<4I?4<4G4G 4G4G4G4G4Gn 4Gn4Gn 4Gn4Gn.?n4<.?nI4<.?I4<.?4<6.?4<.?I4<PP%101NP(1R1GRGJrJNR:NQUa0axPXaRaqRqtrtxRatrtxQ0PRRrR0PRRrR"RHLu#HLSLbSbeselSSR^PlxVxzuz~VpxVxzuz~RRS "0"1S18s8JSJ#ar0rSsSd#0SsS#0!S!(s(:S:#Qb0bqSqxsxST#0SsS#+W+VsS# p2&1#+vAVV{WAVV{VLOsOTSTV# p2&1DV#V{vWVsS# p2&1#vWVsS# p2&1#v1FFkW1FFkV<?s?DSDF# p2&14F#Fkv0WwWuUWVsS v p2&1v0?P?_V_`P0?p?_v_`P#l:HSHNs|N^SNV;A`kPk{S{WPSP`RQRQ`0S0`0UuU0k{S{WPSPPSsS/s/7S9TS0VvV)v~)3V9UV`PP`RR`pP#m{ m{p pQ p-#$o$(R(-o(P(S())FSFG(s()#)FsFG#4o48R8Go#P)8Pawab#KVS;S;@st@_S#S#'st';S;Dst#s#'s|';s;Ds|'o-8o8?R?Ko'P-?PKawab#KS w w<K`VOS w w<O[V jWjkjwjk#KVS;S;@st@hS#S#'st';S;Dst#s#'s|';s;Ds|'o-8o8?R?Ko'P-?PKjwjk#KS w w<KiVOS w w<O[VBVS2S27s|7VSSs|2S2;s|o$/o/6R6BoP$6PBXWXYBJ ww4BWVFJ ww4FRVRzWz|R|WR Wp{uT{|tP|uTtP uT&V&*S*5V:XVVV VPS<s<LSsSs {uT{|tP|uTtPuT uTR(sv*5svRsvsv(V*5VV V<WW W<  P<ud ud <uT uT<ud<u`9P<  <XVV<zWz|R|WRW<XxSx{u`{|t\|Su`t\Su`X{uT{|tP|uTtPuTgxSx{u`{|t\|Su`t\j{ud{|t`|udt`jtPtxs<x{u`<{|t\<|Pu`udRudPu` R  u` PP{uT{|tP|uTtP uTuTu_Ru_P  P P B RB W R B QB H8 B 0t U P uw" P uw"a Sa V Y p Y V Z p Z V P V  P ' V' ( P R S p#  P ' V' ( P p# -S-?SFTSWYSu@VFUVWtV u@VFUVWtV u#4vWtv*4 T4@VFUV4; vv4FU vv44EPFWP8; vv48EP[c vv4R_c vv4_gRA s us t tt uA s us t tt uA s us t t t uA s u s t tt u A D PD q Sq t pt S R R s r r s# o o R o P P  S R S  : ( :G R :  S ( SG R S   S ( S  :  S@ \ \ d px@ `  0 P R R r Rpu #t#u #Svu#t#vu#t#RP39D-9D )P)-rt9BPBDrt#8Q9DQ39D -9Dl&ud&)\):ud:=\=qudoSRV&uT&)L):uT:=L=quTSu o&ud&)\):ud:=\=quduSs#S)7S7PVQQuPdpr"uPptuPptpuP"&ud&)\):ud:=\&uc&)[):uc:=["P"&ud<&)\<)0PDNucNRRRqucDRPYcuccgRgqucYgPu #P$QudQR\Rgudgh\ud'OVReVV'(s@QudQR\Rgudgh\CQucQR[Rgucgh[C_PPuTsWWVVPPPuTpuTuTucRucPPttttttt p t# RRt$t# t# t# t# t# t# t # RPtt%&t&'t'(t(-t-2t p,t#,R%1R12t$t#,t#,%&t#,&'t#,'(t#,(-t#,-2t #,RKw # NVw$#$QUQVw$#$QYVYSslSY}S}slSslYms s f__R_R_fpPPmzsss__R_sPPY}s}s|ss|Y__R_R_R_YcPcms<Pv # yWyv$vUyWyv$WgSglsll}SS!sl!gSgpsl s 7Ds !_=L_LPRPd_dkRkp_P=PP sQ^s!_Wd_dkRkp_!PWkPs!s|!gsgps|!_'2_26R6L_LPRPd_dkRkp_P s<'6Psv,#,yW#0yUyWSsxSSsxSsxSsxSsx__R_PPss|ss|__R_R_Ps<P0BSCVCDDOVOPCv CD# Y# w # Ya0aV\SSjvRvwsw{rdpvRvwsw{rdpvrv{Rt# w # 0VSSRsrdRsrdu.#T.2v24#T0.W)S)1S RR&.vI~#T~v#TIQ0Q~WLySySZhR`hRv~wR# r 0R0PPplPr R# r 0R0PPplPr hPUSUVvVWu#WXt#XShpsPUsUVv#VW u##WX t##Xshpsphopovpv}p}p46s46@P@Us4UVv#4VW u##4WX t##4Xs4hpsPUsUVv#VW u##WX t##XshpsPUsUVv#VW u##WX t##XsopsPUsUVv#VW u##WX t##Xsopspovpv}p}p46s46@P@Us4UVv#4VW u##4WX t##4Xs4vpsPUsUVv#VW u##WX t##Xsvpspv}p}p46s46@P@Us4UVv#4VW u##4WX t##4Xs4}p46s46@P@Us4UVv#4VW u##4WX t##4Xs4}pspsPUsUVv#VW u##WX t##XsXPUsUVv#VW u##WX t##XsPUsUVv#VW u##WX t##XPUsUVv#VW u##WX t##XsPUsUVv#VW u##WX t##3X36s46@P@Us4UVv#4VW u##4WX t##4`juwjnRnuw`nPuuwRuwuPuwRuwPuwRuwPuwRuwPuwRuwP +S2S),s,6P6+s2s)+2<FPF+s2s<+2RUsU_P_+s2sR+2eoPo+s2se+2{~s~P+s2s{+2s4P+s42s4+2+s42s4+uw2uwP2?P+sBs+uwBuwPBOP+sRs+uwRuwPR_P+sbs+uwbuwPboP+srs +uwruw PrP+ss+uwuwPPuwRuwPuwRuwPuwRuwPuwRuwPuwRuwP uw RuwP@OORPRRs # s SSs|sPs|pd0"P"#[VVvSpuPwSVVwV10kw1VVS6=PstdsGYP0dfPfjS6R6#r#EGPGY#GRGY# r # YjR1=P),P,0#$0Y\9[0[\Vy \9y @[R#$C[r #$#T[\y \[y #$[g\2$s"gt \2$r" p2$r"[y   #$#`0! U4 y UWP! W4 y WP! W4 y Wp P ! w4 y w 0 Q u u 0 Q q !u!!#!#!u !S!#!S S!#!S P!!P R!!R!#!s 1!#!1 q4!!q4R!!s!!#!!s!!P!!u!!p!!u!!u !!P!"S"h"Sh"j"sj"z"S""S!!P!!u ! "V"b"Vb"s"Q""Q!A"u j"s"u " "Öj"s"Ö#"b"Vb"s"Q""Q."s"W""WQ"b"""Q"Y"pr"["s"W""W["e"pt""pt""W""pt""pw"""ug""R""ug""P""""S""t""`#8#S"##:#W:#;#"#"#""S""t""`#8#S$#:#W:#;#####S####$$P$$$-$P-$1$###$R$$R$5$R`$j$j$k$Pp${$$$$$$$P$$#$$$P$$#$%%P%%#$1%4%P4%8%#$Q%T%PT%X%#$q%t%Pt%x%#$%%P%%#$%&S&&S&%&s~&&S&%&s~;&Q&SR&^&S^&f&s~f&j&R&^&S^&f&s~f&j&}&&S&&#$&&2$v"}&&s&& #$#`&&R3s34#4}s}~#<o<@R@ToTXRXtotxRx~oP"s<4@P"s ANs 4oGToTXRXtotxRx~o%PGXP"/sYfs(4o_totxRx~o(4P_xP%s%&#&UsUV#4o48R8LoLPRPVoP!s<&8P%S%&9USUV&o>LoLPRPVo&P>PPN'X'#N'X'0N'X'#''P''Pw'' '' w''P''S''S'(0(H)U])t)U ((#T(H)\#T])t)\#T+(H)W])t)W+(A(0A((1((Q()1)')Q])t)1+(A(0A(2)S])t)SA((V()V])t)VX((V])g)VX((v ])g)v z((V])g)Vz((v ])g)v ((P()Wg)t)W()wg)t)w()Wg)t)W()wg)t)w()P))0)-*S)-*#T* *P *)*s2$w")*-*s2$w"**0*"*P* *p *"* s2$w"#|**P**S**P**s**tp*+s++tp+7+s++P+,uP,,tL,,,uP\,i,uP, ,R ,,,rz+,,7<,,7z++V++t++t+,u`,,t\,,,u`<,,u`+,,7<,,7,,7+,V,,ud,,t`,,,V<,,V,,V,,ud,,u\,,R,,u\,,P++S+,u ,,t,,,u <,\,S\,i,u i,k,Sk,,u ,,S,,u +,V,,ud,,t`,,,V<,,V,,V++S+,u ,,t,,,u <,\,S\,i,u i,k,Sk,,u ++W+,u\,,tX,,,u\<,\,W\,i,u\i,,Wk,,u\q,{,u[{,,R,,u[q,,P+,V,,ud,,t`,,,V<,i,V+,u[,,tW,,,u[<,i,u[++P<,G,P+,u`,,t\,,,u`M,i,u`+,ud,,t`,,,udM,i,ud++PM,V,P+,u\,,tX,,,u\\,i,u\+,u\,,tX\,i,u\+,ud,,t`\,i,ud++P+,st\,f,Pf,i,st,,ud,,u[,,R,,u[,,P,,u`,,u[,,R,,u[,,P,,P-"-PE-J-PJ-q-SN-m-SN-m---h.p.R//#/'/'/,/P,/./t./4/4/>/#/(/@/o/0o/u/RC/G/G/L/PL/N/tN/T/T/u/C/H/^/o///P/ 0P0000W00!0T0ST0_0s_00S2040P400V002040P40T0VT00P0000W00W0020000W00V000000W00W0011[1S[1^1u_^1a1t_a1y1Sy1|1u_|11t_11S11u_11S11u_11\1V\1a1Pa1z1Vz1|1u|11t11V11u_11R11u_11PK1[1S[1^1u_^1a1t_a1y1Sy1|1u_|11t_N1^1u_^1a1t_a1|1u_|11t_N1Z1PZ1[1s<[1^1u_<^1a1t_<a1r1P11u_11u_11R11u_11P11P2)2P11V12u 22t242V4252u 5282t82P2u U22u 11v12V22ut22tp82J2VU2W2VW2n2utp2r2Vr22ut12S22u22t82J2SU2W2SW2n2up22S22ur22S22uw22us22R22usw22P 22V22ut22tp82J2V 22us22to82J2us 22P82G2P242V4252u 5282t232S3282PW2n2ut]2g2usg2k2Rk2n2us]2k2P22u`22W22u`23X3'3W'3(3u`(3+3t\+3f3W22S22ud23\3%3S%3(3ud(3+3t`+3-3S-3K3udK3M3SM3d3udd3f3S22S22ud23\3%3S%3(3ud(3+3t`22W22u`23X3'3W'3(3u`(3+3t\22S22ud23\3%3S%3(3ud(3+3t`22S22u`23X33S3(3u`(3+3t\22u_23W3(3u_(3+3t[22P33P22u`23X3(3u`(3+3t\22ud23\3(3ud(3+3t`22P22u`<23X<33P-3K3u`33=3u_=3A3RA3K3u_33A3PM3d3udS3]3u_]3a3Ra3d3u_S3a3P33P3 4P~33P33u 34u #424u l44u 33V33t33t33V33up33V33up33h3 4up 4#4h#424V24l4upl44V33up3 4up33V33t33t33ut#424utl44ut33up33V#424Vl44V33ut#424ut33uo#424uo33P#4/4P33up33h4 4up 4#4hR4l4up33S33P44S4#4PR4j4ST4j4SY4c4utc4g4Rg4l4utY4g4P33up33h4 4up 4#4h33ut33l4 4ut 4#4l33P33up<33h<44P3433up34V44R4up:4D4uoD4H4RH4R4uo:4H4Pt4~4uo~44R44uot44P44P4444P4B544P4444S44V44t44t44t44t 44P4B54 5V 5(5p(5*5V*5B5p4 5S 5(5(5@5S@5B5*5@5S@5B5/595o95=5R=5B5o/5=5P45V45o55R55o45P 5(5p55o55R5(5o55P^5u5Vu5w5uw5x5tx5:6V56W55W55u`56W66u`56u_55P55P55u`55ud55P66u` 66ud 66P)636u_3676R76:6u_)676P^66u66t 6,7u,7/7t /7u7uz77u^66S66ud66t`6)7S)7,7ud,7/7t`/7O7SO7z7udz7|7S|7~7ud~77S77ud77S77ud77S77udk66u66t 6,7u,7/7t /7d7u~77u77uk66V66u`66t\6*7V*7,7u`,7/7t\/7d7V~77V77VO7d7u`U7_7u__7c7Rc7d7u_U7c7P66S66ud66t`6)7S)7,7ud,7/7t`/7M7S~77S77ud77S77ud77S77ud66u_66t[6,7u_,7/7t[/7M7u_~77u_77u_66P:7G7P66u /7:7u 77u 66u <u`<660/7:7077066ud/7:7ud77ud66W/7:7W77W77u_77R77u_77P66ud/7:7ud66u_/7:7u_66P/777P66u`77u`66ud77ud66P7"7P67u 67Wd7q7udj7q7u_j7q7P77u`77u_77P77ud77u_77R77u_77Po8u8Ru88o8888S869S819:88S819S89:89S88P919x9|9P|99U99P99V99099P99P99099S92:S2:3:P3:C:S::S :(:s;:C:S::S::ug::R::ug::PJ:q:S::SU:q:s::s^:q:ug::ug^:e:P::P;o;U;S;V;%;S;B;SB;G;s|G;o;S%;+;S+;/;s|/;B;SB;K;s|%;/;_4;?;_?;F;RF;S;_%;/;P4;F;PS;o;US;[; uu4S;o;VW;[; uu4W;c;V;<<<V<<<4<V; < <<S<4<S;<<<W<4<W;;P;;R;; ? ;;c;;;<i;<<<V<<T<<P<B=B=J=PJ==T<<p<B=#B=J=pJ==#s<<P<B=B=J=PJ==s<<p<B=#B=J=pJ==#~<<R<<\B=g=0~<<S<6=B=g=Sg==~<<R<<\B=g=0B=g=SR=g=1R=^=RR=Y=r<B=g==<<S<6=g==<B=g==<<P<:=Sg==S<=V==V<:=Sg==S<B=g==<:=Sg==S<<=Wg==W<:=Sg==S< =W==0==S==1==R==r =:=Sg==S==S =B=:g==:==: =(= ss<"g=x=sp"==sp"=;=Vg==V==V=B=:g==:=;=Vg==Vg==:g==V2=A=P==P==>>==P==>>=>=>R>>'s$'2#$2Cs$<o<@R@CoP2@P'S'2X>_>P_>?S??u??t??SX>~?W~??s4??u#4??t#4??W??t??u>?S??u??t??S>>P>>Q>?ud??t`??ud??s??ud!??H??H!??V??u# ??t# ??V??s h??v$??u#0??t#0??v$??s0o?r?s0??s4??S??u??t??u??t??A??W??ud??t`?? wud<"??A?? wud<"#@QAuTQATAtPdAAuT?l@u TAAu ?l@u #TAAu #@@P@@u #!@TAdAA!@QAudQATAt`dAAud!@1@ud#1@6@P:@x@x@@@@@TAdAAAAAA:@QAudQATAt`dAAudB@\@WB@J@ud#R@V@pV@[@PdAAudb@TAAAb@o@po@t@Px@@@@@TAAAAAx@QAudQATAt`AAud@@V@@ud#@@p@@PAAud@@@@ud@@ud#@@p@@P@@@@ud@@@@p@@P@TAAA@QAudQATAt`AAud@@ud#@@p@@P@TAAA@QAudQATAt`AAudA ASA Aud#AApAAPAAud#AQAudQATAt`7AQAudQATAt`7ATA0RQSQvRvySyRQUuTUvQvuTQ#Q|#QW?Q?HPTvTvudududt`vvudPPPududt`ududt`00ud0A&BP&B+Br+B3BP:CCCPCCKCrx B&BP&B+Br:CCCPCCKCrxvSvwvtwyuT4yztP4zSvtuT4tP4SvtSvtvt>xWxyuyztzWutWWWSyudyzt`zudt`ududSVw#hyudyzt`zudt`kyucyzt_zuct_kPuducRucPW0KKPKLVL"MVMPNVNNV*OXOVOOV K&KP&KYLSLMSM NSpKLDNND*OXODOODpKLWNNW*OXOWOOWpKKw#KKPKLk NNk *OAOk OOk KLWNNW*OAOWOOWKLpNNp*OAOpOOpKLWNNW*OAOWOOWKKpKKPKLX NNX *OAOX OOX KLWNNW*OAOWOOWKKpKKPKLtNNt*OAOtOOtKLWNNW*OAOWOOWKKpKKPKLk NNk *OAOk OOk KLWNNW*OAOWOOWKKpKKPKLNN*OAOOOKLWNNW*OAOWOOWKLpLLP LZL-ZLLNN*OAOOO LLWNNW*OAOWOOWLLNN*OAOOOLLWNNW*OAOWOOWL&Lp&L+LP2LLX NNX *OAOX OOX 2LLWNNW*OAOWOOW2LY?Yt?YCYtmVVu~VVPVXu~XX~XYu~VWu~WWVWXu~XX~XGYu~hYYu~hYYu~VGYHVMWu~MWiWPiWtWttWxWtxWXu~XX~XGYu~aWiWp$iWtWt#$tWxWt#$xWXu~XX~XGYu~sWxWu~GYMYu~MY_YP_YhYu~W Y0WWVWXu~XX~X Yu~W Y0WXVX YVWWvXX XY XXVXYVXXQXXu~XXRXXu~XYu~YYQYYu~XX XY XXQXXu~XXRXXu~XYu~XX XY XXu~XYu~WX2XX2WWu~WWPWXu~XX~XXu~WW upt"WW up"WX2XX2WW upt"WWup"WXu~XX~XXu~WXu~XX~XXu~WXu~XX~XXu~WXu~XX~XXu~WXu~XX~XXu~W XPXXP XXu~XX~"XXu~XX~>XXu~XX~SXXu~XX~cXiXu~iXzXPzXXu~XX~Y Zu~ ZZPZ0\u~0\3\~3\6]u~YYu~YYPYZu~ZZPZ0\u~0\3\~3\6]u~\\t\\tY Zu~ ZZPZ0\u~0\3\~3\6]u~ Z.Zu~.Z1ZP1Z[u~[[V[0\u~0\3\~3\\u~]2]u~]2]u~{Z\H{ZZu~ZZPZZtZZtZ0\u~0\3\~3\\u~ZZp$ZZt#$ZZt#$Z0\u~0\3\~3\\u~ZZu~\\u~\]P]]u~[\0[[V[0\u~0\3\~3\\u~[\0[.\V3\\V#['[v3\\ \\ 3\\V\\VC\Q\QQ\Z\u~Z\h\Rh\\u~\\u~\\Q\\u~E\\ \\ E\Q\QQ\Z\u~Z\h\Rh\\u~\\u~Z\\ \\ Z\\u~\\u~'[3\2\\2'[>[u~>[A[RA[U[u~U[`[P`[0\u~0\3\~\\u~'[8[ upt"8[>[ ur"'[3\2\\2'[8[ upt"O[0\u~0\3\~\\u~O[U[u~U[`[P`[0\u~0\3\~\\u~8[>[u~>[A[RA[U[u~U[`[P`[0\u~0\3\~\\u~A[`[RA[3\J\\JA[3\8\\8A[O[r A[3\ \\ A[`[r A[U[u~U[`[P`[0\u~0\3\~\\u~A[3\ @\\ @A[O[ r  8!i[0\u~0\3\~\\u~{[0\u~0\3\~\\u~[0\u~0\3\~\\u~[0\u~0\3\~\\u~[0\u~0\3\~\\u~[[P\\P[0\u~0\3\~[0\u~0\3\~[0\u~0\3\~[0\u~0\3\~ \\u~\"\P"\0\u~0\3\~Y]g]0g]]S]_SY]]V]]]_Vz]]R]]S]^R^^S^/^R/^5^S5^M^RM^S^SS^s^Rs^y^Sy^^R^^ps"^^S^^R^^S^^R^_S__ps"__S]]]]\]]\#]]P^^>^^\^^Q^^Z^^P]^]^\]^\#^^P^5^^5^\^*^\#*^/^P5^S^5^S^\5^H^\#H^M^P^^y^^^y^\^^n^\#n^s^Py^^S__S^^\^^r^^Y^^P^_\__r__X__P,__,__\,_6_p6_;_PB__`B__\B_L_\#L_Q_PX__X__\X_b_pb_g_Pn__`q__[__R__[q_z_Pz__`<__P__`__[__R__[__P]]\]]\]]0__\__0__0_&aS&a+as+acWcdWPb~bPb~buTPbXbuT#Xb`bp`bebPkb~bWkb~buTkbnbuT#rbubpubzbP~bccad}dd~bcuTcctPcaduT}dduT~bbuT#bbpbbPbcOcadO}ddObcuTcctPcaduT}dduTbbSbbuT#bbpbbPcduTbbbbuTbbuT#bbpbbPb"cSbcbcuTbbuT#bbpbcP ccuT ccuT#ccpccP0ccuTcctPdaduT}dduT0ccu`cct\dadu`}ddu`>ccuTcctPdQduTdduT>ctcStcuctucyctyccuXcctTd-dS-dQduXddSdduXEccuTcctPdQduTdduTEccWdQdWddWOccVccu\cctXddQduX>dQd0cc0dad0}dd0ccu`cct\dadu`}ddu`)cc0dad0}dd0)ccudcct`dadud}ddudccu`cct\-du~>bPbu~t~u~7u~Rbp$bu~t~u~7u~\bu~7Ru~ku~Qu~t~u~u~kPttPu Qu~u~u~u~u~u~u~u~u~u~PPu~u~Ru~Pu~t~u~u~t~u~u~t~u~u~t~u~u~t~u~PPu~t~u~t~5u~t~Ju~t~cu~t~.r8r1.r8rS1r8r01r8rsrrVrru_rrPrrPrrudrru`rrPrrudrru_rrRrru_rrPrru_rrRrru_rrPss1ssSss0sssbssVessu_eslsPssPlssudrssu`rssPssudssu_ssRssu_ssPssu_ssRssu_ssPssPstUttPssRstWttRssQstVttQss0 ttp1)ktotp1)ss0 t>tS>tktsktotSs tQt,tQ,tot\t,tQ,tot\8tot8totVKtot/KtotVottVttQttSttttSttttRttttRttttPttttPttttttStttuSu"uP"u#utuVu"uQ"u#ut#u!t uP#u@uV@uAuzu~z}P}u~t~u~ u~ Wu~t~W34t48t\zu~z}P}u~t~u~u~Pu~Qu~t~u~<u~Wu~Wqu~ H H<HqH=u~=bPbu~t~ u~ u~<u~qu~Qbp$bu~t~ u~ u~<u~qu~^bu~<Wu~ku~Qu~t~u~ u~u~qu~kPttPu Qu~u~ u~qu~u~u~u~ u~qu~u~u~u~u~u~RRu~Ru~u~u~ p|u~4u~#p|u~4 p| p|u~4Qqu~u~zu~u~zVV vu~t~u~u~t~u~u~t~u~u~t~u~u~t~u~ PP u~t~&u~t~<u~t~Qu~t~ju~t~uu1uuSuu0uusuvVuvu_uuPvvPuvuduvu`uuPv2vudv$vu_$v(vR(v2vu_v(vP:vDvu_DvHvRHvKvu_:vHvPPvzvzv9wV9w>wv>wOwVTw~wVwwVSvvuevfvwzvvSvvSAwNwSbw~wSvvSbw~wSvvQvvuTbw~wuTvvbwuwvvpr"vvuTbw~wuTvvptbw~wptbw~wuTbw~wptuw~wpuT"wEwudTwbwudwEwu_Twbwu_w&wPTw_wP&wEwu`,w6wud6w=wR=wEwud,w=wPwwudwwu_wwRwwu_wwPwwu`wwu_wwRwwu_wwPwwu_wwRwwu_wwPMu MPP_u MutMPlPnut(MutMPl7MutMPl7P0wwRwRxuTRxSxtPSxxuTxxtPxxuTwwQwxQwwVwwtwwtwRxu`RxSxt\Sxxu`xxt\xxu`xxxxxPxVPxRxudRxSxt`Sx~xV~xxudxxt`xxVxxVxOxSOxRxQuR1)(RxSxQtR1)(Sx}xS}xxQuR1)(xxQtR1)(xxSxxQuR1)(xPxVPxRxudRxSxt`Sx~xV~xxudxxt`xxVxOxSOxRxQuR1)(RxSxQtR1)(Sx}xS}xxQuR1)(xxQtR1)(xxSxxQuR1)(xQxWQxSxPSxxWxxPxxWxxu_xxRxxu_xxP2xPxVPxRxudRxSxt`Sx~xV~xxudxxt`5xRxu_RxSxt[Sxxu_xxt[5x?xP?xIxv<Sx_xPuw>BRBLuw4BPP&u &)t);P;Hu HKtKu u )/K/ՁVՁ&u\&)tXKyu\y{V{u\VudRudP$V$&ud&)t`KyVVƂud݂V#S#&u&)tKySSƂu݂߂S߂uSu[Ru[P$V$&ud&)t`KyV&u[&)tWKyu[PYgP&u`&)t\KYu`jyu` &ud&)t`KYudjyud PjvP&u\&)tXKYu\&ud&)t`KYudPKVP)HuHKt )ESEKP{u\u[Ru[PƂudu[łRłƂu[łPƂ݂u`̂ւu[ւڂRڂ݂u[̂ڂP@NPNVWcPcVVNQSQTu`TWt\tSQTuTWttuQ\PP\Tu\TWtXtu\bTu`TWt\tu`bmPPmTuTTWtPtuTsTu`TWt\tu`s~PP~TuPTWtLtuPTu`TWt\tu`PPTuHTWtDątuHTu`TWt\ątu`Pą΅PTuDTWt@ԅtuDTu`TWt\ԅtu`PԅޅPTuTWttuTu`TWt\tu`„PP„TuTWttuȄTu`TWt\tu`ȄӄPPӄTuTWttuلTu`TWt\tu`لPPTuTWttuTu`TWt\tu`PPTuTWt$tuTu`TWt\$tu`P$.PTu@TWt4tu@ Tu`TWt\4tu` P4>PTuLTWtHDtuLTu`TWt\Dtu`(PDNP(TuXTWtTTtuX.Tu`TWt\Ttu`.9PT^P9TudTWt`dtud?Tu`TWt\dtu`?JPdnPvu`|uRu|Pu\uRuPuTuRuPʆuPņuņɆRɆʆuɆPʆ߆uHІچuچކRކ߆uІކP߆uDuRuP uuR uP uuRuP3u$.u.2R23u$2P3Hu9CuCGRGHu9GPH]uNXuX\R\]uN\P]ru@cmumqRqrucqPruLxuRuxPuXuRuPuduRuP#guDgWuDىuDىWuDt@BuDBYWYuD6QuDuDagWghthltluLىuLBYuLaguDgWىWBYWsuLىuLyVىVyPىPuHudPuDuDt@uDpuDuDud\udt`udpududud\udt`udu`Xu`t\u`ȈPPȈuDuDt@Έud\udt`ΈވPވuD<<P;AWABtBFtFu`ىu`u`;AuDAWىWWMu`ىu`SVىVSZPPZu\ىu\`udىud`gPPguXىuXmudىudmtPƉPtuPɉىuPzudɉىudzPɉ։PuTudP$uT$ud$P$BuD*4uC48R8BuC*8PDYuLJTudTXRXYudJXPYfuH_fud_fPrudxu`Ru`xPu`udRudPu\udRudPΊuXɊudɊ͊R͊Ίud͊PΊuPԊudRudԊP+202NWNWRWWRԋWVPԋV2NVVP2Nuut2<v2Nugutԋu2NVgVPԋV2Nutut2NuwuRutwPVuRuPË͋u͋ыRыԋuËыP%4%+W+,t,0t0uXuX4uX44`w4WW4`WwWW}u\udPO4KOVV46V6KudVud[[uuuuWRuWPnVVquWuWqxPPxu\u\~udud~PPu`u`ududPPuXŌόuXudȌόudPȌՌP4uX&uW&*R*4uW*P6Kud<FuWFJRJKuW<JPK`u\Q[uW[_R_`uWQ_P`wu`fpuWptRtwuWftPVV=VKSSS":"KSS:S>EPudt`udt`=udIVVISPSSSWWSSgWWgSSkW0S1RrSSudt`udt`uct_uct_PP%/uc/3R3=uc%3PnǏǏSՐSSՐ0Ր1ƐϐPƐɐRǏӏۏuۏߏPӏ֏P֏SwSsw#ss)+P+uDt@)uLtH)sw#PܑPPzQd@kS;v P!;v !*P\}4P4yS|~SL|<P<SSTP,V/DPDV\#5V%u G"asrrPWs ʓCCDCSCPuTCdCuT&C@K$6Cb6BPu3Ŕ30<S<DPD0'S'{0{S0IKSb0ƚ0+eIeƚeCuCDtD+uIuƚup"P&CuCDtDuIuƚu.HV.6u#>BpBGPZ{uZ{0Zpu#puPNZr{rIrƚrN[p[`Pƚޚuƚޚuuu@uÕu#ǕʕpʕϕP֕u@ٕu`ٕPHZp0)^u'ZuޚuakP'9P9<s<DpXakR'DR'9P9<s<DpX'DR~ޚ~uPuޚuuPurPSƖƖSܖuHܖSܖߖs#uHu`PΙuPΙu`ΙPSΙSӘӘu\ייu\՘u\u\Ιu\ u\Ιu\ u\Ι0 0h}u\h}0)Ι )Ιu uBΙBΙuuVΙuLuLVΙuuVYu#]`p`ePlΙrrlΙuulvpv{PΙΙuupPΙuPuPΙuuu#pPΙuLuLΙu`u`PP uLu` R u` P uPu`Pnttnuu4n4nuHnuHnuHKu#ORpRWP^nuanu`anP}u}uїїuuDuu#pPuDu`PuDu`Puu`PȚޚu@Κޚu`ΚޚPCuCDt'u{uIXuAVACuXCDtT'V{VIXVD'{IXAVACuXCDtT'V{V Cu`CDt\'u`{u` P{PCuCDt'uD0'0)CuCDt'u/Cu`CDt\'u`/<PP+u+0+Iu1;u;?R?Iu1?PKXuXQXu`QXP,uwu,Lu# LMt# Mvu# vwt# 2LuwLMtsMvuwvwts2<P<Fs <MWP9Fu#Xeu#?Fuw^euw?MP^oPuwRuwPuwRuwP VSYS,SS,Vs Ys 2XuwXYoYuw2<P<Fs <YgP9Fshus?Fuwnuuw?FPnPuwRuwPuwRuwPcu#ru#t#u#$kSrSS2ESSEks rs KkuwruwKRPPRksrsXkuwruwX_PrPuwRuwPuwRuwP |V~Vu|v~vu#$kS~SS2ESSEks ~s Kkuw~uwKRPPRks~sXkuw~uwX_P~PuwRuwPuwRuwPSu 9u PTu X\u u u HVHu\TV0u\09V9Ou\OPTPu\Vu\Vu\u\udRudP<HVHu\V0u\PTu\Xdu\u\u\<S0SPRSRTuX\uSQcVHu\u\u\xsPWs 0PTXd 0u\T9Ou\OPTud\9OudOP\P9GPdyu\jtu[txRxyu[jxPpu pqtqu u pu #pqt#qu ##u # oVqVV &S&'t'+t+puppqtlquphup,oVqVV,nSnputpqtpqSutlSutSutDnSnputpqtpqSutlDLPLpupqtquSnSnputpqtpqSutlVpuopqtkquogV`P`js<qP]jupupcjSutcqPPutuoRuoPuoRuoPpu pqtqu tu pu #pqt#qu #t#u # oVqVV &S&'t'+t+puppqtlquptlup,oVqVV,nSnputpqtpqSuttpSutSutDnSnputpqtpqSuttpDLPLpupqtqutSnSnputpqtpqSuttpVpuopqtkquotkV`P`js<qP]jupupcjSutcqPPutuoRuoPuoRuoP.u u SSs~Ss~$VDSud\SSudDVVVUSud\SXu_Wu_XbPbls<P_lWu`elSudelPPlvudu_Ru_Pu_R u_P#MS?ASegS.W.Hu HItI>u >??u 1u .w.Hu #HIt#I>u #>?#?u #1u #]?FUYei1]cScdtdhthHuHHItDI>uH>?@FUuHYeuHiuH1uHl?FUY]aei1lSHuLHItHI>uL>?DFJuLJLSLUuLY]uLacSceuLiuL1uL *ud*.R.1ud .PGWGHudHIt`I=W=>ud>?\FJWi~WHuHItI>u>?FJui~uGWGHudHIt`I=W=>ud>?\HuCHItI>uC>?Pw<IWPSXiu\W^iudP^vPuXwuXud}udP}PuLuLududPPuHuHududPPuDuDudud"PP0uTuT%0udud%3PP0Au`(u`6Aud(ud6IP6Pi~udoyuCy}R}~uCo}P~u\uCRuCPuXuCRuCPuLuCRuCPuHuCRuCPuDuCRuCPuTuCRuCPu` uP RuPP&USUWutWXtpXSuttpSut&WuWXtXutu:USUWutWXtpXSuttp=WuoWXtkXuotk=GPGQs<XgPDQVhuupJQSnuutJXPn~PutuoRuoPuoRuoP dSdgughthϛSϛЛuPeVhPݛVʛ!ds dgu# ght# 6ds,dgu#,ght#,)u#)*t#*u#t#u#!DPDSS\ 4S8SuP4s8su#"$P$5V8TPTVlP?S?CPCȜSpP?s?CpCȜs&(P(AWCKPKȜW`Ȝtܜߜs ߜVڝVݝVܜߜs ߜVڝVݝVPuTtP4P4ܝuTܝݝLݝuT5|ݝL||ݝV|ڝVVP|PٝSSݝݝs [V^V FVs [V^V FV-/P/EuT^tPtuT 3uTu 3E^R R3FRE[VV3FVQVPVZSԞPԞS38S՞ 3F \_s_VeVhV\_s_VeVhVmoPouTPuTh{uTh{ԟ Dh D{ DVeV{VPSPdS{Sh{4hsVVΡVsVVΡVPˠuTPDuTuTDDˠ8FD8FΡ8FˠVDVΡVנܠPܠSD\P\SS]ΡtߡSw`)Sw`Sw`ߡs W)WWPV)3P3VVH_)HHHWWP%SPS S,Jv,MSv,2W28S2~S~sxS8OSOSsxS~S~sx8OSOSsxh~S~sxELudmtudESPmP8OsOSs|S~s~s|8SudYcudcgRgud8BPBLs<YgPJv,MSv, v4v,8W v4v,8WJv MSv #WSSslCSͣSͣѣslѣSsls s ududPPʣs sãʣud udãѣPPͣsͣѣs|ѣss|ѣudףudR#udPs<ףP#Jv MSv #+ v(v D#KWMWW'+ v(v D'3W3JVMSVCdPdSS|,V,-t-1t1uXtTuXtTuXhuluuuuhu#lu#u#u#u#!,V,-t-1t1uXtTuXtTuX!S|SSSSSS&,V,-t-1t1uXtTuXtTuX5rrr5]V]u\tX V Xu\XlVlu\tXu\Vu\u\Vu\u\udRudPQ]V]u\ V Xu\u\u\u\QSXSSSfxV]u\u\u\sPWs X4Xu\tXlu\tXu\udt`ludt`udPPu\uWRuWPuXtTluXtTudt`ludt`PlwPuXuWRuWPR̥R̥ڥRڥHR֤ r̥ڥPr̥R#̥ڥrڥHR#R̥RڥHRr̥R#ڥHR#˥ud˥̥t`ڥudt`1HudɥVɥ˥u`˥̥t\ڥVu`t\1HV)v#).P5̥ڥ5ɥVɥ˥u`˥̥t\ڥVu`t\5?p?DPEɥVɥ˥u`˥̥t\ڥVu`t\EkWڥWELv#TXpX]PdɥVɥ˥u`˥̥t\ڥVu`t\hpQprWruThv#Pڥu`˥u`˥̥t\u`t\̥00˥ud˥̥t`udt`˥u`˥̥t\u`t\ǥPǥ˥ud<˥̥t`<P1ud#u_#'R'1u_'PSuph٦S٦ۦupۦܦhuogۦuoۦܦgPs<PutŦutSŦupPΦPަutuoRuoPuoRuoP5|u|}t}u5?R?|u |}t}u @|ut|}tp}ut]|ut|}tp}ut`|us|}to}us`gP}PusRusPħ_ul_`th` ulħԧul#ԧ٧Pݧ)a )aݧ_ul_`th`ul ulSul#pP`yul`y pP`y (p(-P4`4y4 44>p>CPG`)ay)a )aG_ul_`thyul ulOiSOSul#_cpchPyulo` o|p|P`TT TpP` pP` pèPʨ` ʨԨpԨ٨P` pP_ul_`thul ul_ut_`tput ut/]S]_up_`tlS2_uk_`tguk29PP9_ut_`tput?_up_`tlup?FPPF_ul_`thF`0ԩupũϩukϩөRөԩukũөPԩutکukRukکPul0NݪMNTWTUtUYtYu\ݪu\Mu\]ݪ0GI]WݪW0WGIW{WݪW~u[ݪu[~PݪPududu`u`PPu\ʪu\udêʪudPêЪPu\ u[ Ru[P0u`!+u[+/R/0u[!/P0Gud6@u[@DRDGu[6DPSuuu7uu`Xu`Xud\ud\Pu`<X<Pr7rWttu 7u r7rW7WΫWѫ۫u_۫߫R߫u_ѫ߫Pu`u_Ru_P5ud$.u_.2R25u_$2P1=p 1ututu.?uC\u`.9=?C\`fSfgtgkukuLtHuLtHuL.9uL=?uLC\uLo.9=?C\oSuPtLuPtLuP.0S09uP=?uPCESE\uPKUu\UYRY\u\KYP  29 =? WuXtTWuXtTW29W=?W  29 =? Su\tXSu\tXu\24S49u\=?SSu\tXSu\tX=?SPutut=?uSu\tXSu\tXuGtCuGtCPs<PW -uXS&-u\P&6PuP7DuPu\=Du\P=NPuLO\uLu\U\u\PUfPuHgtuHu\mtu\Pm~P uTuT u\u\PPu\uGRuGPuXuGRuGPuPuGRuGPuLuGRuGPuH uG RuGP.uT uG $R$.uG$P%NSN u tu t!u &7u 79S9Tu .:p0). u tutu&7u;Tu]&157;T]cScdtdhth uL tHuLtHuL&1uL57uL;TuLl&157;TlS uP tLuPtLuP&(S(1uP57uP;=S=TuPCMu\MQRQTu\CQP  *1 57  W  uX tTWuXtTW*1W57W  *1 57  S  u\ tXSu\tXu\*,S,1u\57S S  u\ tXSu\tX57SP u tut57u S  u\ tXSu\tX uG tCuGtCPs<PW%uXS%u\P.PuP/<uPu\5<u\P5FPuLGTuLu\MTu\PM^PuH_luHu\elu\PevPuTwuTu\}u\P}Pu\uGRuGPuXuGRuGPuPuGRuGPuLuGRuGPuHuGRuGP&uTuGR&uGP1S1Qu /Tu (s$.1S1Qu /Tu 1BS/9S9Ts~/9S9Ts~BGuj/T1djpSpqtqutu.uL./tHTuLtHuL1uLduLuLy/TdhlyS.uP./tLTuPtLSuPuPdhuPluPuPSuPuP u\Ru\ P/ T dh l  -W-.uX./tTTWuXtTdhWlWW/ T dh l  +S+.u\./tXTSu\tXdfSfhu\lu\S+S+.u\./tXTSu\tXP+S+.u\./tXTSu\tX.uG./tCTuGtCPs<T_PW`quXSfqu\Pf~PuPuPu\u\PPuLuLu\u\PPuHuH u\u\ PP'uTuT'u\u\/PP1uL",uG,0R01uG"0P1FuH7AuGAEREFuG7EPFduTLVuGVZRZduGLZPlu\r|uG|RuGrPuXuGRuGPuPuGRuGPZu u u u u\tX=u\Zu u u u MWW W0Vu`t\V V'=V0MWW W@Vu`t\VV'=VCudt`udud'=udCJPP u`ud R  ud PJu\tXu\u\'=u\JSPSSQu\tXu\u\'=u\`udt`udud'=udcWWW'=Wcds|udt`udu`t\u`PPPttp-:Pu\tX0 'u\ '0<V<Cu Vu u`t\u`#<V<Cu Vu #9WWu`#%9V0Wu`#1Ww?u`t\u`u`?SPSSCu`t\u`u`Rudt`ududUVVVUVsnudt`udqu_t[u_qxPPPttpudu_Ru_Pxu`t\x0?u u uptlup&up#&+P2uptlupup2SPSS6uptlupupEuttpututHVVVHIsauttputduotkuodkPPPttputuoRuoPkuptlk0<V<Cu Vu u`t\u`#<V<Cu Vu #9WWu`#%9V0Wu`#1Ww?u`t\u`u`?SPSSCu`t\u`u`Rudt`ududUVVVUVsnudt`udqu_t[u_qxPPPttpudu_Ru_Pxu`t\x08u u uptlup+uptlupup+}S}PSS/uptlupup>uttpututA~VVVABsZuttput]uotkuo]dPPPttputuoRuoPduptld0<V<Cu Vu u`t\u`#<V<Cu Vu #9WWu`#%9V0Wu`#1Ww?u`t\u`u`?SPSSCu`t\u`u`Rudt`ududUVVVUVsnudt`udqu_t[u_qxPPPttpudu_Ru_Pxu`t\x0حڭPڭ`Su SSvxS~VȭV7u7`VuVu*uvxu|VN|~NuX|~uXҬWҬuT|~uTuX|~uXuX#Pr|~ruX|~uXҬY|~YҬuX|~uXuX|~uXd|~duX|~uX 0aS V|~V*ar*auX*4p49P?aW?auXa0|~0avu`v{P{u`|~u`k0|~0kud|~udu`PudŭuXŭȭtT`ruXrutTȭ0`u0ŭuTŭȭtP`ruTrutPŭu`ŭȭt\`ru`rut\PŭuT<ŭȭtP<`gP߭70vx0߭u`P7u`vxu`70vx07udvxud7?u ?BtBFt7?sN`1N`uT`0T`u#u00uxu`xP0u`000ud0yPW0W0yVu\0VpP̮Vu\̮00u\000Au`03ud3=P=AudATuXAT0TruTZdu`dhRhru`ZhPDu u u uptlup :V (up#04p49Pup0up#P@uptlupup@SPSSDuptlupupSuttpututVVVVVWsouttputruotkuoryPPPttputuoRuoPyuptly0įRįmRm}R}RQluDlmt@muDt@uDدm00įPmuPu}uįQm}QįQįPm00u` P lu`lmt\u`m00ludlmt`udHmHNu@\m\VluXlmtTuXϱuXϱV\fqfkP}VluXlmtTuXϱuX}VްuXްjVjlu\lmtXVuXϱu\}m00ϱ0mϱu@mϱjVjlu\lmtXVϱVǰqǰ̰PްjVjlu\lmtXVްm00ϱu\ϱ0Glu`lmt\u`Gludlmt`udGm00KcWWPcu\u\PWPP}1}SP0spu`udPud  p ` ptd 3 3:p:B`BL **3p34t4BdBLPrRrRPrQruDƲrƲuDt@3uD34t@4uD040`Cu3u34t kzu`VCu 1V13u 34tkzu 040u`Pu`t\4u`040udt`4ud4Vku@ 4Vk PVPuXtT4VuXkV qP+PVPuXtT4VuX+PVPuXVu\tX4AVACuXCVu\+04V0muXm0W4VW]u@k4VkVu\tX4VVkuquzPVu\tX4AV04A0CVu\CV0u`t\4Au`udt`4Aud04A0W4AWu\4Au\P4>P410S04P#40#0s04pVku`V[ud[bPbkudRmRQ^uD^drduDt@uDt@muD$1m1ҵuut ?NuPҵu u t?Nu @0m0@Cu`CXPXu`t\mu`L0m0Ludt`mudҵu ?Nu PٵW?VWҵu ?Nu SuTtPuT(?uT?ASAmuTSuTtPuT(?uTVmuTS#uT#ASAuXSu\tXS(*uT*?uXVXuXXmu\00(?0Vm0AVuTAV0(?VmPBW(?W(?VmASAuXtTuX(*S*?uXVmuXpP#ASAuXtTuXVmuX#ASAuXSu\tXSVXuXXmu\#00Vm0*?uX*?0krPrWVmWySu\tXSVXSXmu\Su\tXS00¶u`t\u`¶udt`ud¶00ƶ޶WW˶޶u\u\˶ҶPP1VP0vp(u`udP(udзRRзQuD t@ Q0uD01t@1uD 111P PuR R0 01003u`3HPHu` t\1u`< 010<ud t`1ud}P SSSuP tL1AuPXuPuPWDuTDcScuXWu\ tX1AWXZuXZou\oquTquXuPuT 01A0X0 1AX SSɸ 1AXɸWuT tP1AuTXuTWɸӸpӸظPWuT tP1AuTXuTWDuTDcScuXWu\ tX1AWXZuXZou\oquTquX 01A0X0uT0 1AXPoWoW% 1AX%cScuX tT1AuXXouXoqSquX%/p/4PDcScuX tT1AuXXouXDcScuXWu\ tX1AWXZuXZou\D 01A0Xo0quXq0PSXZSWu\ tX1AW 01A0Zou\Zo0u` t\1Au`ud t`1Aud 01A0S1ASu\1Au\P1>P11.V.1P 10 .v.1pCXu`CHudHOPOXudֺ ֺݺpݺ` ͺͺֺpֺ׺t׺d  p ` ptd<V<Cu Vu u`t\u`#<V<Cu Vu #9WWu`#%9V0Wu`#1Ww?u`t\u`u`?SPSSCu`t\u`u`Rudt`ududUVVVUVsnudt`udqu_t[u_qxPPPttpudu_Ru_Pxu`t\x0<V<Cu Vu u`t\u`#<V<Cu Vu #9WWu`#%9V0Wu`#1Ww?u`t\u`u`?SPSSCu`t\u`u`Rudt`ududUVVVUVsnudt`udqu_t[u_qxPPPttpudu_Ru_Pxu`t\x0IY[e~[@B % %OY1OYSRY0RYsyu`ɻVɻu`t\Ru`(RVttutu(RupPutu?Ruu#W#QuQdWduWu@W0uD0CWCpuHpW̽uL߽̽W߽ uP 9W9huTh{W{uXWu\tXW?AuAXuXouou@uDuHܿuLܿuPuT6uX6Ru\0?R0*?u*?0eu`ɻVɻu`t\Ru`rudt`Rudɻ?RɻлPлV?VV׻?R׻#W#utu?VWVRu׻pP#W#utuVRu#W#QuQdWduWu@W0uD0CWCpuHpW̽uL߽̽W߽ uP 9W9huTh{W{uXWu\tXWVXuXouou@uDuHܿuLܿuPuT6uX6Ru\0VR0AVuAV0%$VR$%,P,VVV3dWdutuVmWmRu3utuVRu3<p<APQdWdutumRuQdWduWu@W0uD0CWCpuHpW̽uL߽̽W߽ uP 9W9huTh{W{uXWu\tXWmouou@uDuHܿuLܿuPuT6uX6Ru\Q0mR0XmuXm0amRaVmVsmRsWu@tu@mWRu@s}p}PWu@tu@Ru@Wu@W0uD0CWCpuHpW̽uL߽̽W߽ uP 9W9huTh{W{uXWu\tXWu@uDuHܿuLܿuPuT6uX6Ru\0R0ou@o0RPVV¼R¼WuDt@uDWRuD¼̼p̼ѼPWuDt@uDRuDW0uD0CWCpuHpW̽uL߽̽W߽ uP 9W9huTh{W{uXWu\tXWuDuHܿuLܿuPuT6uX6Ru\0R0uD0R P VڿVRCWCuHtDuHWRuHp P0CWCuHtDuHRuH0CWCpuHpW̽uL߽̽W߽ uP 9W9huTh{W{uXWu\tXWuHܿuLܿuPuT6uX6Ru\00R0uH0@R@VڿVRWuLtHuLڿWڿRuLRutuRuR[p[`PpWuLtHuLڿRuLpW̽uL߽̽W߽ uP 9W9huTh{W{uXWu\tXWڿܿuLܿuPuT6uX6Ru\p0ڿR0ڿuLڿ0ڿRP;VڿVڿR߽W߽uPtLuPڿWRuPpP߽̽W߽uPtLuPRuP߽̽W߽ uP 9W9huTh{W{uXWu\tXWuPuT6uX6Ru\̽0R0ܿuPܿ0ܽRܽ;VV9W9uTtPuTWRuTutuRupP 9W9uTtPuTRuT 9W9huTh{W{uXWu\tXWuT6uX6Ru\ 0R0uT0;R;BPBҾVRVIRI{W{uXtTuX4W4RuXISpSXRh{W{uXtTuX4RuXh{W{uXWu\tXW46uX6Ru\h04R04uX40x 4R xҾV4RVWu\tXW4RWutu4RupPWu\tXW0վu`t\u`վudt`udվ0ݾVVu\tXu\PP(u`udP(ud<V<Cu Vu u`t\u`#<V<Cu Vu #9WWu`#%9V0Wu`#1Ww?u`t\u`u`?SPSSCu`t\u`u`Rudt`ududUVVVUVsnudt`udqu_t[u_qxPPPttpudu_Ru_Pxu`t\x0~1~S0s010u`Pu`1u`010ud1ud1PhW1W 1 V1V *p*/P?V?0ku`kudk0oWWtu\u\t{PPuTu`PPuXu`Ru`PuXu`Ru`Pu`Ru`udPuduT u`Ru` P^h1^hSah0ahsx{u`{Pu`t\u`udt`udP VV W uXtTuXWuXpR W uXtTuXuX W :uX:Wu\tXWuXu\00uX0 ++ PXVV++Wu\tXWW%p%*Q:Wu\tXW:0su`t\u`sudt`uds0{VVu\tXu\PPu`udPud1S0s(+u`+CPCLu`LOt\Ou`2LudLOt`OudUYpU\P\VpVcYpcWLuXLOtTOYuXpWuXcmpmrRWLuXLOtTOYuXuXWuXKWKLu\LOtXOYWuXu\Y00ruXr0Y22PVVY22KWKLu\LOtXOYWWpQKWKLu\LOtXOYWY0#Lu`LOt\OYu`#LudLOt`OYud#Y0+JVOYV0Lu\LOtXOYu\07POVP[pu`[`ud`gPgpudyfRfyYRY1yffDyYDyfDUYUyfUyfy1yuP0u#pHRH%u|%(P(u|Pttu||Ru|u}Pu}P7u}7=u~=DPDiu~iPu~~u~u}u~1u}1eu~|'u~'Ru}ttDEtEIt%u|%(P(u|Pttu||Ru|EOVOu||u|u|Vu|1'u|'RVu|HHH1'H,RHu|]W]u|u~Wu~~u~u|1Iu||~u|~W'u~,RWu}]w$]u}u~w$u~~u~u}1Iu}|~u}~w$'u~,Rw$ u}u~u}(P(1u}8881'8OVOu||u|u|1'u|$uv<"  uv<"8881'8$ uv<"  uv<"2u uu1eu|u'u2OVOu||u|u|1'u|7HHH1eH|'H7u~Pu~Pu~~u~u~1eu~|'u~7=u~=DPDiu~iPu~~u~u~1eu~|'u~ttu~Pu~Pu~~u~u~1eu~|'u~u~Vu~~u~1:V:Iu~|V'u~1Iu~HH~'Hu~Wu~~u~~W'u~}w$u~~u~~w$'u~u~IOu~OaPaeu~88'8Vu~~u~'u~ uv<"88'8 uv<"uuu'uVu~~u~'u~000'0u|Pu||u|u|'u|000'0u||u|u|'u|%VVV#'V%1u|BVVV#'VBmVmu||Vu|VV#'VBLqLQPimVmu||Vu|Vi00u|0u||u|u||u|00WWu|u|PPu||u|u||u|PPu||u|u||u| PP u~~u~1u~~u~;u~u}}u}u~>u||u|>IPPIu~u||u~bu~~u~wu~~u~u~~u~u~P^u~^du}duPuu}}u~u||u|u||u|u}}u}u~~u~PPu||u||Nu||3u||^du}duPuu}}u|Ru|u|Pu|u|u|Ru|Pu|u|Ru|P( ( L P /p/Pp/Pp/@@P/@1uP0u#p HP Hu|PSu|S\P\]t]ata u|  t|P u| u} (P(bu}bPu}u~Pu~P u~  t~Pu~u}u~u}Ru~iu~ u}ttttu|PSu|S\P\]t]ata u|  t|P u|V u|  t|Pu|u|Vu| Vu|  HPHHH H }u|}Wu|?W? u~  t~Pu~u~Ru~iqu~quWuwu|wWu~u|W Wv}u}}w$u}?w$? u~  t~Pu~u~Ru~iqu~quw$uwu}ww$u~u}w$ w$u} u~u}Pu} APAAAV u|  t|Pu|u|u| upt" uv<"  upt"! uv<" APAAA upt"  uv<"  upt"! uv<"u|iu|V u|  t|Pu|u|u| HPHHRHiH"u~"%P%Eu~ELPL u~  t~Pu~u~Ru~iu~u~Pu~P u~  t~Pu~u~Ru~iu~tt"u~"%P%Eu~ELPL u~  t~Pu~u~Ru~iu~:Iu~IFVF u~  t~Pu~u~Ru~iqu~qVVu~ HPHHRHiuHwH?W? u~  t~Pu~u~Ru~iqu~quWwWu~?w$? u~  t~Pu~u~Ru~iqu~quw$ww$u~ u~u~Pu~ APAARAiqAFVF u~  t~Pu~u~Ru~iqu~ upt"! uv<" APAARAiqA upt"! uv<"3 u|  t|Pu|u|u|iqu|3FVF u~  t~Pu~u~Ru~iqu~b 0P00%0bhu|hP u|  t|Pu|u|%u|v 0P00%0v u|  t|Pu|u|%u| VPVVVu| VPVVVV u|  t|P`V`pu|pVVVrPV u|  t|P`V`pu|pV 0P0u|0K u|  t|Pu|K u|  t|Pu|K 0P0OkWWTku|u|T_PPk u|  t|Pu|t u|  t|Pu|tPPZP u|  t|`u| u|  t|`u|PP u~  t~`u~ u~  t~`u~wu~w u}  t}`pu}pu~ u|  t|`u|PpzPu~ u|  t|`pu~ u~  t~`pu~ u~  t~`pu~ u~  t~`pu~.4u~4EPEu~u}P u}  t}`pu~O u|  t|`pu|m u|  t|`pu|w u}  t}`pu}z u~  t~`pu~zP`jP u|  t| u|  t| u|  t| u|  t|u}P u}  t} u| $R$%u|u|P%u|%u| u| $R$%u|$P%@u|.;u|;?R?@u|.?P!P6TPTSSl"P7MPMSSQYYewVSSstSSstSstss|ss|ududRudPPw w w<V w w<V"SVV"vtv"v| ucR"uc P"* w w<&* w w<&2S.P.NuTPuT7u-uuu?bSbftfsSgjpu "jyP{R{PQxxxrPS8OrrPSPS r Pth$#=WP#Tm0VvVp#TSRrPth:UPR`dPRLU1`m1LUP`kPkmr!s SSSJJLSLc&SSSJJLSLc&GPGVWPVPVPVP(V(?P?HVH_P_hVhPVPVPVPQVQ^P^pWpVWVPAVAcW8K8KS7SSS((S(H(HSHhHhShhSSSpQvQ^p^pwvpAvp``R``4`pSSS4p``R`p[[R[#PP#pPP)p``R`)4PPPp\S4`%/[/3R34[%3P4AP:A[:APK4JYKSS4SSJLSLY`QJY`SQSSJLSLYS}JY}SJLSLY``[R[PLY`RY[RYPP S!S!##%S%RRTSTk&S!S!##%S%RRTSTk&/P/VWVVVcPcuWuVQVWVPIVIkW@S@SS7SSS((S(H(HSHhHhShhSSSVvH$H&VcpH$H&cuwH$H&vH$H&pH$H&IvH$H& u``R`#`'<` uSS!S!#'<u``R`u[[R[(PP(uPP.u``R`.9PPPp\S'<`-7[7;R;<[-;P<IPBI[BIPS9RaSSS9SSRTSTahVRahSVSSRTSTaSRaSRTSTa``[R[PTa`Za[ZaPP-9P9GWIWW ESEHu HItISSu -ESEHu HItISSu ISSu yySSu ududucRucPucRucP0S9KS0o9DoDHRHKo$P9HP |s s s 0$@VV)@uwuw)4PP@|sss@0G_VVL_uwuwLSPP_|sse~uw~tsuwtsenPnxs<Pl|SSqxuwuwqPPs Ps sPssuwRuwPSuwRuwPX\p X\S\zSz}s}SSbV'Vpu#u# u#4Pu# u#4Pu# u#u# 4Pu#u# 4Pu# u#0S Sug ugP Pu##u# t#ug_ug tcP'5u#-5u# u#4-9P15u# u#419P=Ku# CKu#u# 4COPGKu#u# 4GOPS[u#[^p^cPdu#pzugz~R~ugp~PvjvmvWwWWwWSSSvjvm|vv v Dvprvv&<S<?s?CSC_S_bs|,8PE[P,8Pvjvm|vv v Dvv|00 0 D00vjvm|vv v Bvv|00 0 B00SmzSSPSmzSudmzudPmtPSudRudPvjvz|vv v BvvS-vOv]jvz|v Bvv-MSMS$)S-OV]mVz|V BVV-Uv$BvJUVUvOv]jvz|v $vvU] vv4UaPY] vv4YaP)Bv)5 vv4)9R15 vv419RevOv]jvz|v $vvhp vv4htPlp vv4ltPxvOv]jvz|v $vv{ vv4{P vv4PvOv]jvz|v $vv vv4P vv4PvOv]jvz|v $vvPPS P OS]iSz|SSOYY$Ov]jvudt`]ludlmt`P]dP|vucRucPv vv4P vv4Pv vv4P vv4Pv vv4P vv4PDJvJTPTXvXpvrvr0,V,2s2?S?dPdSSell|]`Wg|0]`sg|ss8Ps8 gs8|s8s8PW !P!gW|~WW%g9gss`s gs |s s {s gs|ss~s s s4P s s4Ps ss 4P ss 4PsPssucRucPVYWl|0VYsl|s~WZl0~s Zls sPsZs|ssPVPZV|~VVZ,Zs<s~s Ps sPssucRucPSucRucPFWHhW3@SHbS@VHbV'p|'P3>PHUPUWv435R5>p|HUp|UWv83@WHbW3@1Hb15>r4H\r4q4\4 q4Yhq4SvCSS0su"QUQ(\(C0|P1ChPC2mWh2mV CVYhVV0VCVUCsq"QSvCSWCWP(:P1C1u4(Cu4QQ(\vvW(W1(1u4(u4V vp4PV vp4PBWDWfW,<VDZV,V,<DZ:s|DMs|MO #8:SDMSMO #4,:SDMSMO #4,/s|/1P1:s|DMs|MO #8,<WDZW,<1DZ11:p4DTp4r4\4r4Qfr4U>UU0uq"QWQ X >0rQ1>[Q[f vp2&1$z>uOfuV>VQfVV0V>V>ur"RU>UW>WXX >X1>1q4 1q41>\4QQ XRv vW W1 1r4r4 \4V vp4PV vp4P*XggqrqwggqRqSs SX# Xs # 3s 3 -P6SsSX#ws#EXlwlRlESsSX#ws#GSsGSlGPPPSsFWHhW3@SHbS@VHbV'p|'P3>PHUPUWv435R5>p|HUp|UWv83@WHbW3@1Hb15>r4H\r4q4\4 q4Yhq4SvCSS0su"QUQ(\(C0|P1ChPCWhV CVYhVV0VCVUCsq"QSvCSWCWP(:P1C1u4(Cu4QQ(\vvW(W1(1u4(u4V vp4PV vp4PP/sPSQdssP/sQdss0"0" " /SQdSS""!Mu\MQPQRtRVtVu\Qu\u\u\"u\!IVIuXQuXuXVuXV"uX!,P,WQWWW"W4Mu\MQPQRtRVtVu\Qu\u\u\"u\4IVIuXQuXuXVuX"uX4hShlwStSSsudRudPs udRud PkwQww"wkWQWW"WySQSSudyWQWWSQSu`Qu`PPudu`Ru`Pw0WW%QWu#u#%Qu#W1QWP1APABu#BHpxu`u`%Qu`p1ApAB u##BHPpu`Qu\u\%1u\udud%1udP%.PuXuXududPPduXjtuVtxRxuVjxPu\uVRuVP0IVjjqqqw7jjqQqw7RrRV#Vfrfw#?Rr?R?LPQQRRrxlQlrr#RrlP%S+GS%V+GV%S+GS %R+6R6;v;Arx%l+:l:AQAGl%r+6r6;v#;AR%r%lPehshyPysv~u@HtszSv~u@ tSz}s }Pss v~u@Dt|s Sv~u@ tSsv~u@<ttsPu@tOu@Oms mu@9s 9u@PVP-VMOVmoV-m-sv~u@# tH-MssPsVPMVikVmoVM8 m8 MakPkut-uu&s9iuusyPyVPVLNVSUVSiu# t# -u# u# s9Lu# u# u#,t#,-u#,u#,s9Lu#,u#,'sv~u@#(t@-s&s9iss'svu@#4t4-s&s9iss'svu@#@t(-s&s9iss'svu@#LtL-s&s9iss0-009L00svu@#t#\-ss9Lss60-009L006sv,u@#t#p-ss9LssN]P]bsT]P]bsTsv0u@#t#t-ss9LssZsv4u@#t#x-ss9LsspvPvuDt@-APAuDuD9LuDuDE8 9L8 Ysv8u@#t#|sPOmsU_uO_cRcmuOUcPs0sPss&s ss4P ss4P&s ss4P ss4P&s ss4P  ss4 PWWPVPsVVs,]>PP-3P3CF:-:L:FPPsV4V-VLVxVVsS4S-SLSS@S@S!@!#S#9@9=S=p@prSrt@tvSvx@S@S@S@S@=R@CM\MQRQR\CQPV4V-VLV;VptVV\P\\P4#\#'R'-\L\!\!00;\pt\\P'PS4SLSS@S@S!@!#S#9@9;SprSrt@S@S@S@S@PsWtzLLLL!L9;LLPPWzLW!9;Pp$#WzDLDD!D9;WWPHP H PzHLHH!H9;HHzWLWWzSLSS@%zWLW%3W3UHUzLlHlW(zVLV(3PP3zHLH3UHUzLlHl9zVLV9DPLVPDzD\DJzV\VJUP\fPUzl[zVlV[fPlvPfzL|LlzV|VlwP|PzS4SS!#S#0@S@S@SVP4VV!0VV4!04X!##0X4TTRT!0TPP4VV!0V4!0PP4X4V.PMS X=XFHSHJXJLSLcXceSeXxXMQ\Q]P]V =FJJgVgxLcVR\`\`R`c`R`PnxPnup$#V PPVPgPxPV WWgWxWW`R`P VVVW VW LLRLPP WWW W VVPP PPP VVVPP  VVPP X V PPLRLP(#L#'R'(L'P(=X.8L8<R<=L.<Pi~VoyLy}R}~Lo}P~WLRLPWVPHVPDVPVPLVP@RP#0X)0V)0PRpVXf\fjRjp\XjPTRTPVTRTPPp~+6P6>p~PPp$Pp$#p p $P<UPPUVUC}CtVt} V f}fxVx}V]}.3sLULU1U\PmPbhshlt} } R}P,}'}'+R+,}+P,G}5B}BFRFG}5FPGb}P]}]aRab}PaPb}k|}|R}kP}}R}P V}R }P DW):}:>R>D})>Puu }P}WP4W fWWWgWWW2GP PPP f jVj } fVV}}V}V W fWWWgWWWU}Wg}}}Wg}P}Wg}}W]}]aRag}PWaP}}R}PW}g}}W}gu}=W}@WV@QPu}~}R}~P } 0fVf}]}#}0frfr2WP3}}R}PPPS%vOd`U__cRcdUcPdyVjttxRxyjxPyXRPTRPHRPDRP@RPPRPalPP6TP<FFJRJT<JPVk`\ffjRjk\jPkVq{{RqPXRPTRPHRPDRP@RPSP P GuL\uuduFRuFPu`uFRuFPu\uFRuFPuPuFRuFPuL uFRuF P/uH *uF*.R./uF .P/LuX5LuG5BP P GuL\uuduFRuFPu`uFRuFPu\uFRuFPuPuFRuFPuL uFRuF P/uH *uF*.R./uF .P/LuX5LuG5BP P +u+,t,,P,SuXhuuduFRuFPu`uFRuFPu\uFRuFPuP uF RuFP&uL!uF!%R%&uF%P&;uH,6uF6:R:;uF,:P;XuXAXuGANP P +u+,t,,P,SuXhuuduFRuFPu`uFRuFPu\uFRuFPuP uF RuFP&uL!uF!%R%&uF%P&;uH,6uF6:R:;uF,:P;XuXAXuGANPZdusdhRhrusZhPSp$Pp$#pf{PP%VU\UVZ\ZV\%5v#5:PA Z x AVU\UV\Z\xV\AKpKPPW[Z[x[WVU\UV\Z\xV\WapafPmZxmVU\UV\Z\xV\mwpw|P Z x VU\UV\Z\xV\pPVU\UV\Z\xV\VU\UV\Z\xV\0Z0x0_xV_x0SXSXSX"S"'X')S).X.0S05X57S7<X<>S>CXCESEJXJVSVXSXSXSXSXSX13S3JXJUSUZXx}S}XSSXSXSX"S"'X')S).X.0S05X57S7<X<>S>CXCESEJXJVSVXSXSXSXSXSX13S3JXJUSUZXSVU\UV\\1Z\\PU^P SXSXUS STVSVXSXSXSXSXSX13S3JXJUSUZXS U T1Z3SXSXUS STVSVXSXSXSXSXSX13S3JXJUSUZXS6TW$T$DWDKTKOROUTT WTTWTW1JWJOTOSWSZTTW6APDOP{PPW`p$#p0p$#pPPPVk\ffjRjk\jPkqRqPRP@RPLRPPRPW  RP3JX9CCGRGJ9GPW\1WrWW)W)WDT1Zr{PXRPW R P0P!++/R/0!/P0ED6@@DRDE6DPEZ@KUUYRYZKYPZo`jjnRno`nPouRuP1X'T'+R+1T+PPSSBSSSpRr>SvSSud>vQSvSTuGvuGT_PP_u`vu`u`eudvududepPPpuTvuTuTvudvududvPPuPvuPuPudvududPPuLvuLudvudPvPu\udPutuSSEvEE'Ev'   %' %'BEuBEu BIPIS%'SSSudSSu\u\PPu`udPuuuvuuu PrSruuuvudu\Ru\Pu`u\Ru\P)@u\/9uG9=R=@uG/=PBYuLHRuGRVRVYuGHVP[ruPakuGkoRoruGaoPtuTzuGRuGzPu`uGRuGPuGRuGP4S4SSPRnPP`RPVRPWRPTRP H R  P DRP4@%//3R34%3P4RP:HHLRLR:LPPp$#p`LRLPWLRLPTLRLPPLRLPVLRLP` DRD P-W(D(,R,-D,P-BT3=D=ARABD3APBWPHRDRVRVWDHVPWlL]gDgkRklD]kPlr|D|RDrPVDRDP%S+GS%V+GV%S+GS %R+6R6;v;Arx%l+:l:AQAGl%r+6r6;v#;AR%r%lPaSuptlS&up&'tl'=up=?S?uput'=ut]utPu'=uut'=utuo'=uoP'7Pupuput utP Pup?]upEOuoOSRS]uoESPmuts}uo}RuosPFWHhW3@SHbS@VHbV'p|'P3>PHUPUWv435R5>p|HUp|UWv83@WHbW3@1Hb15>r4H\r4q4\4 q4Yhq4SvCSS0su"QUQ(\(C0|P1ChPCWhV CVYhVV0VCVUCsq"QSvCSWCWP(:P1C1u4(Cu4QQ(\vvW(W1(1u4(u4V vp4PV vp4PpPqq #$#HQqRQQ#$qFWHhW3@SHbS@VHbV'p|'P3>PHUPUWv435R5>p|HUp|UWv83@WHbW3@1Hb15>r4H\r4q4\4 q4Yhq4SvCSS0su"QUQ(\(C0|P1ChPCWhV CVYhVV0VCVUCsq"QSvCSWCWP(:P1C1u4(Cu4QQ(\vvW(W1(1u4(u4V vp4PV vp4PCu ju gutgjtpjut :S (ut#04p49Rju jutj0jut#POgutgjtpOj0FWHhW3@SHbS@VHbV'p|'P3>PHUPUWv435R5>p|HUp|UWv83@WHbW3@1Hb15>r4H\r4q4\4 q4Yhq4SvCSS0su"QUQ(\(C0|P1ChPCq#Whq#V CVYhVV0VCVUCsq"QSvCSWCWP(:P1C1u4(Cu4QQ(\vvW(W1(1u4(u4V vp4PV vp4P3QItQ Ew4Ipw4CSCIIlSltIlSltIqUqt I\P  S"t#\S*W?TWS"t?TS*WS"t*1s"t#?TsBQPpXR !P!!P!2R2?U?X.V.2P?Uz22?u?CX#CluNUSUVpt2CVNSQSV2CPetP2CWNWN\PzX#rzzVSPPW\RP00u\0tX0u\0V0u\*uu*u u 8>Pv}PuX P *uX<>PP*1*808>Q>m1mv0vQ1P0P*u *uX4tT4u uX4tT4uX4>Su <>p>Su*W*>SFS*3PmtP*>u\N]P]u\*>u`Nu`u u@SWWPPu`t\u`udt`ud{3uP)uuu\tXVu\00)u u =fVfoPoVV1V )u =u\#u\# )u'S'(pt9V7=PP=u\#u\#.R.P=UuUVtVZtu=11=00LUuUVtVZtuLZPPzuPGPHg\ \ zu~z}P}Au~AD~Du~ u~ @W@Au~AD~DWtt\zu~z}P}Au~AD~Du~su~sxPxAu~AD~DXu~\xu~u~`xu~XH\`HHHVAu~AD~DXV\`VVVu~Sv$Au~AD~DXv$\`v$v$v$u~]au~xu~hAu ADDXu \`u u hsu~sxPxAu~AD~DXu~\`u~u~hX0\`00hkp{Au~AD~DXu~Au~AD~DXu~VAu~AD~DXVAu~AD~DXu~Au~AD~DXu~PDRPAu~AD~Au~AD~Au~AD~Au~AD~%Au~AD~/uP/vuHvytDuHuH.P.vuHvytDuH/vuHvytDuH/2uP2:P:vuPvytLuPVtVtvu`vyt\VYvu_vyt[u_Y`PP`vudvyt`udfvu`vyt\u`fmPPy1ySP0spudu_Ru_Pu_Ru_P,61,6S/60/6sH[u@[0uHKuKUPUVtVZtZ0u[^u@^fPf0u@g0,0gju`jPu`,u`u0,0uud,ud(u(WuX(WqPWuXW*uX*VuXu\0(uX(0PSWW  V pP*V*0u\0Vu`VudV0ZrWW_ru\u\_fPPruPxu`xPPuTu`Ru`Pu`Ru`udPuduPu`Ru`PuTu`Ru`P\ou@ousu\_u_iPijtjntnusuousuoru@rzPzu@su@{060TX0\s0{~u`~Pu`6u`TXu`\su`060TX0\s0ud6udTXud\sudOO\sOuOO\sOWuXuXW\suXqPWuXuX\suXW>uX>VV\^uX^su\00\s0uX0\sPgW\sW\sVV\sV)p).P>VV>00ju`u`jududj00nWWsu\u\szPPuPuPu`u`PPuTu`Ru`P1S0s1u`15R56u`udP6ud6uP'1u`15R56u`'5P6TuT<Fu`FJRJTu`<JPu@u+uuPttu+uu+uu@Pu@+u@0+000u`Pu`+u`u`u`0+000ud+ududud! +a! ! u! +a! ! UWUuX+LuXLaWuXqP'UWUuX+LuXuX'UWUuXV+LVuXu\'0+L00NauXNa0a+LahPhWWo+LoV+LVVoypy~PV+LV0+L0u`+Lu`ud+Lud0+L0W:LWu\:Lu\P:FPuP+:uPu`+:u`P+7PuTu`Ru`P 1 S 0 sau`Ru`afudfmPmudnuPwu`Ru`wPuTu`Ru`P u@ J u{  uu P  t  t J u{  u J u{  u  u@  P J u@{  u@ J 0{  0  0  0  u` 5 P5 J u`{  u`  u`  u`) J 0{  0  0  0) J ud{  ud  ud  udB J ' {  '  ' B H uV J ' {  '  ' V  W J uX{  uX  W  uXV ` q` e Pw  W J uX{  uX  uXw  W  uX J V{  V  uX  u\w J 0{  0  0  uX  0 J {      P  W  W J {     J V{  V  V  p  P J V{  V J 0{  0 J u`{  u` J ud{  ud J 0{  0 & W  W & u\  u\  P  P& J uP{  uP, J u`{  u`, 3 P{  P3 J uT9 C u`C G RG J u`9 G PR \ 1R \ SU \ 0U \ s  u`  R  u`  ud  P  ud  uP  u`  R  u`  P  uT  u`  R  u`  PL _ u@_  u c uL O uO Y PY Z tZ ^ t^  u c u_  u c u_ b u@b j Pj  u@ c u@k  0 & 0D H 0L c 0k n u`n  P  u` & u`D H u`L c u`y  0 & 0D H 0L c 0y  ud & udD H udL c ud  .  . L c .  u  .  . L c .  W  uX  uX  WL c uX  q  P  W  uX  uXL c uX  W . uX.  V  VL N uXN c u\  0  0L c 0  uX  0    L c   P W WL c W    L c   V  VL c V  p  P.  V  V.  0  0Z  u`  u`Z  ud  udZ  0  0^ v W  Wc v u\  u\c j P  Pv  uP  uP|  u`  u`|  P  P  uT  u`  R  u`  P  1  S  0  s ! u`! % R% & u`  ud  P & ud & uP ! u`! % R% & u` % P& D uT, 6 u`6 : R: D u`, : P,W,0 s5&?CWCE s5&0lslpshsSssxp8sspp@sh0pVV V V0lslpshsSssxp8sspp@sh06s67t7;PClslpspsSpssxp8spCpVV V VClslpspsSpssxp8spCIsIJtJNPVlslpsxsSpsxVpVV VVlslpsxsSpsxV\s\]t]aP0lSlps`pSSsxSspp@SshpHs`0VV V V0lSlps`pSSsxSspp@SshpHs`pusuvtvzP0pjjCpjjVpjjWVWwtP j%W%V%WwtP"%j%7W%7V%7W%*w*+t+/P(V(1 u4&V u4&1WuW_utuR u ut1_oo1_  1WuW_utuR u utWSP@WuW_ux u ux@_oo@_  @WuW_ux u uxWSPHWu W_u| u  u|H_ooH_  HWu W_u| u u| W SP1WUW_up_UUr| U up1oo1  1WUW_up_UUr| U upgWgSgqP1_oo@_ooH_oo@JVV@Joo@J  @JVVSUPGJoJcVJcoJc JcVQcSQcUQ[PyVv|Vyoy yVv|V RUPo,W,. s4&.VG]V]b bxV2BP2VG]V]b bxVNVG]V]b bxVQaPQVG]V]b bxVmVbxVpPpVbxVVpxVPVpxVVPVwVPVw5V-P5VNwGxwmwbxwwpxw:lWnWGW  S  t  t muPmntLnuPtLuP  uT  S muTmntPnuTtPOuTOQSQuTSuTSuT  p mu#Tmnt#Tnu#T(u#T:{u#Tu#Tu#T  p mu#Xmnt#Xnypyu#Xqu#Xq$u#X:OqO{u#Xu#Xu#X mu#Tmnt#Tnu#T(u#T:{u#Tu#Tu#T mu#Tmnt#Tnu#TqQu#T$u#T:OQO{u#Tu#Tu#T  S muTmntPnuTtPOuTOQSQ{uTSuTuT  u#X mu@mntnu@u@ u@O{u@u@u@  WWO{WWW  uX  P  uX  P muXmntTnuXtT{uXuXuX  P muXmntTnuXtTfuXuX kVkmu`mnt\nVu`t\fVV kVkmu`mnt\nVu`t\OVV  u\  P mu\mntXnu\tXOu\u\ kVkmu`mnt\nVu`t\OVV  V ud)u\):uX:KuTV'u\'8uXGXuTudVu\ jSjmudmnt`nSudt`OSSudSud  PPudRudP  u\  P mu\mntXnu\u\tXOu\u\ mudmnt`nududt`Oudud mudmnt`nududt`Oudud udmu\mntXnu\u\udu\tXOu\u\ ud)u\):uX:KuT'u\'8uXGXuTud mu`mnt\nu`u`t\Ou`u` PPmu\mntXnu\u\u\tXOu\u\)u\):uX:KuT'u\'8uXGXuTmudmnt`nudududt`Oudud,P,:u\<&P):uX'8uX):uX:KuT'8uXGXuT/:ud-8ud/=P-FPQfuXWauOaeRefuOWePu\u`P:KuTGXuT@KudMXud@NPMfPK\uPgxuPQ\udmxudQ\PmPududt`Oudu\u\tXOu\P PPqpu#|u@#:Owu`:Ou`R:ARAC w2$q"Qu#T:OQ rq4:A rq4AC w2$4:OQ:Ou`:FPu` u`u#Tq u#Tu#Tu`Pqu#`$4qudt`$:udqu#`$4qqu#`udPu#df{uTlvuOvzRz{uOlzP{uPuORuOPGSPqSSGVudt`VVJu_t[u_u_JUPLWPUu`t\Lu`]u`u`[udt`Lud]udud[fP?FPqSP?S]qSSqu ?u ]ru u qu?u]ruuqtPtuTtP?uT]uTuTqtptuT#tP#?uT#]uT#uT#qtpt{uT#1uT#]uT#uT#{SP1?S{sp1?sP1ud]ududuT#P1uT#]uT#uT#1ud]ud1u`]u`P]fP1uT#luT#udu`Pudu_Ru_Pu`u_Ru_P(x(5P5x(mVmppxVV=BPBlSlmvmppxSSKZPZnWnoutopptpsPsxWWNxNmVmppxVVNoUopPpxUUNlSlmvmppxSSP^SP^VP^UsxU^lSlmvmpS^nWnoutopptW?4W45uX56tT6WuXtT-WGWWS`R`uDuDRuD -uDGuDuDu@uEu 2S25ud56t`6Sudt`/S/EudEISIudSudSudu @u Eu hV VV2S25ud56t`6Sudt`-SGISIudSudSud&hV VV&4W45uX56tT6WuXtT-WGWWu`Ru`P?2S25ud56t`6Sudt`-SGISIudSudB5u`56t\6u`t\-u`Gu`u`BMPPM -GS- --G--hu\P5u\56tX6u\tXu\ -u\Gu\u\ou\u`hou\o5u`56t\6u`t\u` -u`Gu`u`o5u`56t\6u`t\u` -u`Gu`u`uVPuVuV -uVG^uVuVPVv V-vVuDuD -uDG^uDuDudud -udG^udududud -udG^ududPu\u\ -u\G^u\u\udud -uduWuW -uWP Pudud-udPu`u`-u`udud-uduWuW-uWP'Pu\u\6au` u`Wau` udZaud PZnPu\r|u\udu|ud PuP*uXuX#*udud#.PP u\Pu\RuDu\Pu\Pu`/<ud5<u`5<PI^udOYuWY]R]^uWO]P^u`dnuWnrRruWdrPsu\yu`Ru`yPuXu`P  P uHuLDuLtH5uLB0BuP}uPuPH05uPB0BuDuDuDP05uDB0Bu@Wu@u@05u@pUu#Tpu#T#Tu#Tt#TQWW5Wau`Xu`5u`n0uTQuT5uTSSSSQVJVhQV5VPs2EPEJshs1h10h1uPuLuHPw,yPsWyWududu_u_PP$.u_.2R25u_$2Pa050aWW5Wu`Xu`ud\udPPu`udRudPKyVyzu z}t}Vu V`cuwclRlzuwz}tsuw`lP`yVyzu z}tV`xSx}PSrwPwxsx}prxSx}P $qVvP?L?GPGHtHLtLTLT^R^L!P!"t"&t&LP)L)4P4L?L?GPGHtHLtLTLT^R^L!P!"t"&t&LP)L)4P4LVV$0ToVo0 N0Ns10VVToV&)D)2R2<D&2P&<V&6H6<W9<P9<W<W WH$WTmWoW<?L?GPGHtHLtLL TLT^R^L!P!"t"&t&LP$LTmLoL\x \\l#lqPxWxx#P4 pPWeWWH$WoWDhvDvzRzDDP$oPhzP pP9S9;P;sSSs#";;AsABtBFt"sWNsWNTLT^R^sLP #PW#PVmW\fDfjRjmD\jPVV,$,o,vPSPS$SoqSS#߫VVL!P!"t"&t&LV0VW3W3:PPA_ _ AAQ#QVPZssZwwpP$q$q$WH$WP!PLPL0&)L)4P4TL5T5T0sy@R@yPW@R@P@R@P@:VZVVzW|WWWWWWPPP:VV(+ug+4P4ugug(+P+SS(:VLufLSPSZvtPvt uf  R uf P vt1S?S8fWW]W5ud]udRfS = udPud=ud= udPud P ud%P%=ud= ud P ud%P%=ud= ud%P%=udududucucPPEOucOSRS]ucESP1S`SJNPNuT~uT7ud~udVgS ^ udPud^ud^ udP ud -P-8ud8EPE^ud^  ud -P-8ud8EPE^ud5^ 58ud8EPE^udududucucPPfpucptRt~ucftPGPHg\ \ "P1APPjSjnp|nS#,P,1p|Javamu#mnt#nu#JMPMjSjnp|nSacPckVnPVcjSjnp|Lqvqsu#@stt#@tvu#@t#@u#@TcPtPSSdgPglp|vu#Dt#Du#DPSSPVP"VS<dvdfu#@fgt#@gvu#@t#@ u#@DSPgyPSp| STZPZgp|vu#Dt#D u#DPSp| SPVP V Sp|= e Ve h ph  V  p  !V= f Wh  W= f wh  wH W Ph y P  S  p|  !SX [ P[ h p|  w  P  S  p|  !S  P  W  P  !W  !  S  p|^!!S!!S!6"v`9""S7#<#S<#]#v`f!!V"7#V]#p#Vf!!S""Sf!!"7#]#p#f!!s""sn!!P""P""R"7#uT]#p#uT!!P""s""P""R"7#uT]#p#uT""P""S""P"7#S]#b#S"7#D ]#p#D #7#""uT!!P!8"uT8"9"tP9""uT7#]#uT!!S!6"v`9""S7#<#S<#]#v`!6"V9""V7#]#V!"7#]#!!P!8"uP8"9"tL9"T"PT""uP7#]#uPU""7#J#l""!9"J#]#!6"VJ#]#V!!P!5"SJ#O#S!9"J#]#"9"##W$A$W$$W##w$A$w$$w##P$$P($F$V$.%VA%T%V##P"$A$w$$w"$%$P%$F$V$.%VA%T%V;$A$PA$F$uT$$P$.%uTA%T%uTA$F$V#$S$$pF$$S$$p$$S.%3%S#$WF$}$W$$W#$GF$$G.%A%G#$wF$}$w$$w##PF$Y$Ph$$V$$p|$$V.%A%V##P#$p|b$}$w$$wb$e$Pe$$V$$p|$$V.%A%V{$}$P}$$uT$$tP$$P$$uT.%A%uT}$$V$$p|t%%S%I&SI&K&w`M&&S&'S8(@(S@(M(w`b(j(Sw((S((w`z%%SM&&S''Sb(j(Sz%%sM&&s''sb(j(s%%PM&Y&Ph&&W''Wb(w(W%%Pb&&s''sb(j(sb&e&Pe&&W''Wb(w(W{&&P&&uP''P''uPb(w(uP&&W%%V%%p&&V'8(VM(b(V%%S&&S%%&&'8(M(b(%%s&&s%%P&&P&&W'8(WM(b(W%%P&&s&&P&&W'8(WM(b(W&&P&&S''P'8(SM(U(S&&W%I&SI&K&w`&'S8(@(S@(M(w`w((S((w`%K&W&'W8(M(Ww((W%M&h&'h8(M(hw((h%%P%&uP0'3'P3''uPw((uPH''w((_''%M&h&0'h8(M(h&J&V&0'V8(M(V&I&SI&K&w`&0'S8(@(S@(M(w`&K&W&0'W8(M(W&M&&0'8(M(&&,&P,&L&uLL&M&tH&&P&0'uL8(M(uL&0'8(M(&0'5&M&  2S27s|7DSSs|2S2;s|o$/o/6R6;oP$6P))P)F)R))p )3) ).)P.)3)#q))Vq))v}))V?**W*5z55W58z8=z==W@qDzB*4}45S55}55R58}8=}@C}CCSCC}CCSCC}CCSCqD}B*M*P55PM*5z58z8=z@qDzV**W*5z55W58z8=z==W@qDzV*a*P55Pa*5z58z8=z@qDzj**W*5z55W58z8=z==W@qDzj*u*P55Pu*5z58z8=z@qDz~**W*5z55W58z8=z==W@qDz~**P55P*0}0,0Q,02}22P25}58}8=}@qD}**W*5z55W58z8=z==W@qDz**P55P*5z58z8=z@qDz**W*5z55W58z8=z==W@qDz**P55P+<-V<-65{655V56{66V68{89{99V9;{t=={@qD{+5z58z8;zt==z@qDz++Pv55P+v5{58{8;{t=={@qD{,v5z58z8;zt==z@qDz, ,Pf5p5P ,f5{58{8;{t=={@qD{,f5z58z8;zt==z@qDz,,PV5`5P,V5{58{8;{t=={@qD{(,V5z58z8;zt==z@qDz(,3,PF5P5P3,F5{58{8;{t=={@qD{<,F5z58z8;zt==z@qDz<,G,Pv66PG,F5{5v6{68{8;{t=={@qD{P,F5z5v6z68z8;zt==z@qDzP,[,Pf6p6P[,F5{5f6{68{8;{t=={@qD{d,F5z5f6z68z8;zt==z@qDzd,o,PV6`6Po,F5{5V6{68{8;{t=={@qD{x,F5z5V6z68z8;zt==z@qDzx,,PF6P6P,F5z5F6z68z8;zt==z@qDz,F5z5F6z68z8;zt==z@qDz,,P66@6P,F5z566z68z8;zt==z@qDz,F5z566z68z8;zt==z@qDz,,P&606P,F5{5&6{68{8;{t=={@qD{,F5z5&6z68z8;zt==z@qDz,,P6 6P,F5{56{68{8;{t=={@qD{,F5z56z68z8;zt==z@qDz,,P66P,F5{56{68{88R88{8;{t=={@qD{,F5z56z68z8;zt==z@qDz,,P65@5P,65z56z68z8;zt==z@qDz -65z56z68z8;zt==z@qDz -65z56z68z8;zt==z@qDz99z99z#z499P7--S565S9:S7-65z56z6_8z89z9;zt==z@qDza--S565S9:Sa-i-Pi-k-v2&5+5P+565v2&9:P::v2&a-65z56z6_8z89z9;zt==z@qDz5+5P+565v2&9:P::v2&56509:0--W66W;;WKDqDW-515616W71{7U81891::1:;1t==1@qD1--S;;SKDMDS--W--V66W;;VKDqDV--S--s|;;SKDMDS--V--v|;;VKDqDV ;;VKDqDV ;;WKDqDWXDdDz#z4XDhDP`DdDz#z4`DhDP-5z56z6W7z{7U8z89z::z:;z;;zt==z@KDz-5z56z6W7z{7U8z89z::z:;z;;zt==z@KDz-.S..s|.5.S66}::S--s--t-l.1:;1.l.::%.l.z66z::z%.5.S66}::S%.7.W66}::W%.l.W66}::W7.C.WC.G.w|G.`.W`.l.w|7.G.zL.l.zL.].Pl.5z56z6W7z{7U8z89z::z;;zt==z@KDzl.t.z#z4l..Vp.t.z#z4p.|.V|..z|.5z56z6W7z{7U8z89z::z;;zt==z@KDz.515616W71{7U81891::1;;1t==1@KD1..z.5z56z6W7z{7U8z89z::z;;zt==z@KDz.515616W71{7U81891::1;;1t==1@KD1./S/5{55{56S6W7{{7U8{89{::{;;{t=={@@S@KD{.5566W7{7U889::;;t==@KD//S/5{55{56S6W7{{7U8{89{::{;;{t=={AKD{/5z56z6W7z{7U8z89z::z;;zt==zAKDz/ /P56P@/t/}@/t/zc//0 /000P000S00 00P0i1Si1z1# 12 22 22S33S\45 {78 (8U8 8I9 I99S::SAA _B{B CCSCD //0022//P//P00P22PC7Cz%C2C|2C6CR6C7C|%C6CP7CRC}@CMC|MCQCRQCRC|@CQCPRCmCz[ChC|hClCRlCmC|[ClCPmCC}vCC|CCRCC|vCCPCC}CC|CCRCC|CCPCC}CC|CCRCC|CCPCC}CC|CCRCC|CCPCC}CCzCCP//P/j0V11V88V//P/J0W12W88PtB{BW/0@12@6W7@{78@(8U8@t==@_B{B@BC@00wp"0,0P11v@r0.(w"66|66z66P66V66z66P66|66z66P6 7|6 7z6 7P 7(7|7(7z7'7P(7C7|17C7z17B7PC7W7|L7W7zL7W7P}77|77z77P77|77z77P77|77z77P77|77z77P78|78z78P88| 88z 88P18U8V:8U8z:8O8PAA| AAz AAPA9AV'A9Az'A8AP9ATA|BATAzBASAPTAoA|]AoAz]AnAPoAA|xAAzxAAPAA|AAzAAPAA|AAzAAP01P1-1PI9U9P;:;|(;:;z(;9;P:;U;VC;U;zC;T;PU;p;|^;p;z^;o;Pp;;|y;;zy;;P;;|;;z;;P;;|;;z;;P;;{;;z;;P;;|;;z;;P::{::z::P::{ ::z ::P:::V(:::z(:9:P::U:{C:U:zC:T:PU:p:{^:p:z^:o:Pp::{y::zy::P::{::z::P-141PO1W1PAA{AAzAAPAB{BBzBBPB/B{B/BzB.BP/BSB{8BSBz8BMBP}BB{BBzBBPBBVBBzBBPBB{BBzBBPBBWBBzBBPT112255]112255]1z1}p11z22z55zp11S11s|11S22S55Sp112255p11z#1111z22z55z11z#z411P11z#z411Pp111221551p11225511z22z55z11z22z55z11P55P11z22z11z22z11P22PW7{7zU8_8z]7q7Vq7v7v|v7{7VU8_8VW7{7 U8_8 v7{7 U8_8z[8_8z#z4[8_8P_8g8Pk88zt88{88R88{t88P88z88z88R88z88P;<V<<z<<P<-<{<-<z<,<P-<H<{6<H<z6<G<PH<c<{Q<c<zQ<b<Pc<~<{l<~<zl<}<P~<<{<<z<<P<<{<<z<<P<<{<<z<<P<<z<<z<<P<=z<=z<=P= ={= =z==P =;={)=;=z)=:=P;=_={D=_=zD=Y=P==W==}==R==}==P==z==}==R==}==P==z==}==R==}==P==z==}==R==}==P=>}>>}>>R>>}>>P>:>z>0>}0>4>R4>:>}>4>P??W??}??R??}??P??}??}??R??}??P??}??}??R??}??P?@}@@}@@R@@}@@P@2@} @-@}-@1@R1@2@} @1@P2@M@};@H@}H@L@RL@M@};@L@PM@q@}V@g@}g@k@Rk@q@}V@k@P@A{@Az@@PDDRDAESAEEEREEmESmEEREESE)FR)FUFSUFFRFFSFFRFFSFFRFFSFFRFFSFHGRDDRDAESAEEEREEmESmEEREESE)FR)FUFSUFFRFFSFFRFFSFFRFFSFFRFFSFHGRDE )FF FF FF G0G GSiFFVFFv|G0GVGSG0GSGSG0GuPSP>SLSw<UUP;SLSuDUUuDASLSu`UUu`ASLSPUUPSSWS\UuP\U]UtLUUWU]VuP]V^VtL^VVuPW*WuP5WbWuPWWuPS\Uu`\U]Ut\U]Vu`]V^Vt\^VVu`W*Wu`5WbWu`WWu`SSPSSw<UUPSSuLUUuLSSu`UUu`SSPUUPS\UuT\U]UtPU]VuT]V^VtP^VVuTW*WuTWWuTS\Uud\U]Ut`U]Vud]V^Vt`^VVudW*WudWWudSTPTTuT<UUPTTWUVuXTTudVVudTTPVVPQT\Uu`\U]Ut\V]Vu`]V^Vt\W*Wu`TT\Uud\U]Ut`V]Vud]V^Vt`W*WudTTbTPbTpTu`<V"VP_TpTu\#V4Vu\eTpTud)V4VudeTpTP)V;VPpTYUSAVZVSWWSW*Wu T\Uud\U]Ut`AV]Vud]V^Vt`W*WudTZUVAV[VVW*WVT]U\ AV^V\ TTPT\Uud\U]Ut`AV]Vud]V^Vt`T\Uu`\U]Ut\AV]Vu`]V^Vt\TTPAVHVPTT0TUWTYUSNVZVSTUs U]U NV^V UZUVNV[VV'U\Uu\U]UtNV]Vu]V^Vt4U]U\ NV^V\ 4U@UPGU\Uu\U]UtNV]Vu]V^VtJU\Uud\U]Ut`NV]Vud]V^Vt`JU]UPNVUVP`VuVu`fVpVudpVtVRtVuVudfVtVPuVVu\{VVud{VVPVVuVVuVVRVVuVVPVVuVVudVVRVVudVVPVVuVVudVVPVVuDVVu`VVPW*WudW*Wu`W*WPVVuPVVu`VVRVVu`VVPVWuLWWu`WWP7WLWuT=WGWudGWKWRKWLWud=WKWPLWbWuXRWbWudRWbWPdWzWujWzWu`jWzWP|WWuHWWu`WWRWWu`WWPWWu@WWu`WWRWWu`WWPW] ]C_ J_q_ Ws\Wu\*]W,]]W]C_WJ_q_WXPXuPX[XP[Xt\ut\u\tu\+]u+],]t,]]u]C_uJ_q_uXXPX[u u\\u ,]]u ]]u ]]u ^^u _C_u J_q_u X!XP!X%Xu #$%XXu,]V]u+_C_uJ_c_ubXXSXt\ut\u\tu\+]u+],]t,]V]SV]]u]^u"^+_uc_q_ueXt\u`t\u\t\u\+]u`+],]t\,]]u`]^u`"^+_u`c_q_u`eXsXPsXXs<,]5]PpXXV6]G]uvXXu`<]G]u`vXXP<]P]PX[u u\\u V]]u ]]u ]]u ^^u "^^u _+_u c_q_u XXPXXu #$XKYuV]]u ^^u"^P^u _+_uX YS Yt\ut\u\tu\+]u+],]tV]]S]]u]^uP^+_uc_q_uXt\u`t\u\t\u\+]u`+],]t\V]]u`]^u`P^+_u`c_q_u`XXPXXs<V]_]PXXV`]q]uXXu`f]q]u`XXPf]z]PX[u u\\u ]]u ]]u ]]u ^^u P^^u _+_u c_q_u YKYu ^^u _+_uHYYSYt\ut\u\tu\\u\\S\+]u+],]t]]S]]u] ^uP^ _uc_q_uNYYYQYY[u[t\u`t\u\t\u\]u]+]u`+],]t\]]Q]]u] ^uP^ _uc_q_uNYYYP]]PYYt\ut\u\tu\+]u+],]t]]u] ^uP^ _uc_q_u_Yt\u`t\u\t\u\+]u`+],]t\]]u`] ^u`P^ _u`c_q_u`_YjYP\\PYYSYt\ut\u\tu\\u\\S\+]u+],]t]]u]]uP^ _uj_q_uYt\udt\u\t`u\\ud\+]ud+],]t`]]ud]]udP^ _udj_q_udYYPYYs<\\PYYV\\u@YYud\\udYYP\\PY[u u\\u \\u ]]u P^^u j_q_u YYu #$YYP ZNZSNZt\uHt\u\tDu\\uH\\S\\uH\\S\+]uH+],]tD]]uHP^ _uHZt\udt\u\t`u\\ud\+]ud+],]t`]]udP^ _udZZP\\PZt\uDt\u\t@u\\uD\+]uD+],]t@]]uDP^ _uD!Zt\udt\u\t`u\\ud\+]ud+],]t`]]udP^ _ud!Z,ZP\\P,Z[u u\\u \\u P^^u ,Z>Zu #$>ZIZPrZZSZt\uPt\u\tLu\\uP\\S\\S\+]uP+],]tL]]uPP^^uP^ _uPuZt\udt\u\t`u\\ud\\ud\+]ud+],]t`]]udP^^ud^ _uduZZP\\PZt\uLt\u\tHu\\uL\+]uL+],]tH]]uLP^^uL^ _uLZt\udt\u\t`u\\ud\+]ud+],]t`]]udP^^ud^ _udZZP\\PZ[Su\\SZ[u`u\\u`ZZP\\PZ[uTu\\uTZ[u`u\\u`Z[Pu\|\P[[u [[u #$[t\ut\u\t\+]u+],]t]]u^ _u![t\u\t\u\tX\+]u\+],]tX]]u\^ _u\![s\W\*]W]]W^ _W1[t\u\t\u\tX\+]u\+],]tX]]u\^ _u\4[t\udt\u\t`\+]ud+],]t`]]ud^ _ud4[?[P]]P[t\u`t\u\t\\+]u`+],]t\[t\u\t\u\tX\+]u\+],]tX[[P[[u`<\\P[[ud\]ud[[u`]]u`[[P]]P[[0[,\S[[P[[u #\,\u [[V#\,\u #$[[v#\,\ u #$#T[#\S#\,\s[[u #\,\u #$[[s2$q"[,\ #\,\ u #$#`,\u\ ],] ,\s\W]*]WB\t\ut\u\t]+]u+],]t_\t\ut\u\t]+]u+],]tb\t\udt\u\t`]+]ud+],]t`b\u\P]#]P]]u]]ud]]R]]ud]]P]]u@]]ud]]P]]u]]u]]R]]u]]P]]uH]]ud]]R]]ud]]P]]uD]]ud]]P^^u\^^ud^^P ^^u^^u`^^P$^9^u*^4^u`4^8^R8^9^u`*^8^P9^L^u?^L^u`?^L^PR^g^uXX^g^u`X^f^Pg^^uTm^^u`m^^P^^uP^^ud^^R^^ud^^P^^uL^^ud^^P^^u`^^u\^^R^^u\^^P^_ud^^u\^_R__u\^_P _+_u_!_u`!_%_R%_+_u`_%_P-_C_u3_C_u`3_C_PL_c_uR_\_u`\_`_R`_c_u`R_`_P__0_ `0 ``P`bu~bbt~bbu~bbt~bcu~Gcjc0jccu~cdu~__v__P_`v`bu#bbt#bbu#bbt#bcu#Gcjcvjccu#ccu#cdu#__u~_*`S*`bu~bbt~bbu~bbt~bGcu~GcIcSIcKcu~KcMcSMcdu~Mcjcu~Vcccu~ccgcRgcjcu~VcgcP_c jcc cd _`v`cHjccHcdH``u~``P`au~aaPabu~bbt~bbu~bbt~bcu~jccu~cdu~``u~`#`P#`oau~oataPtabu~bbt~bbu~bbt~bcu~jccu~cdu~cctccth``u~``P`au~aaPabu~bbt~bbu~bbt~bcu~jccu~cdu~`aWabu~bbt~bbu~bbt~bcu~ccWccu~ccWcdu~ccu~`cHcdH`Jau~JaoaPoapatpatattabu~bbt~bbu~bbt~bcu~cdu~^aoap$oapat#$patat#$tabu~bbt~bbu~bbt~bcu~cdu~hatau~lcrcu~rccPccu~abWbbu~bbt~bbWbbu~bbt~bbWabu~bbt~bbu~bbt~bbu~aaPbbPabu~bbt~bbu~bbt~bbu~abu~bbt~bbu~bbt~bbu~abu~bbt~bbu~bbt~bbu~bbu~bbt~bbu~bbt~bbu~b bPbbP bbu~bbt~bbu~bbt~bbu~$bbu~bbt~bbu~bbt~bbu~:bbu~bbt~bbu~bbt~bbu~Ubbu~bbt~bbu~bbt~bbu~ebkbu~kb|bP|bbu~bbt~bbu~bbt~bbu~bbu~bbt~bbu~bbt~bbu~bbu~bbu~bbt~bbu~bbt~bbu~bbu~bbt~bbu~bbt~bbu~bbPbbPbbu~bbt~bbu~bbt~bbu~bbt~bbu~bbt~bbPbbPc#cu~ccu~c"cR"c#cu~c"cP#c>cu~,c9cu~9c=cR=c>cu~,c=cPccu~ccu~ccRccu~ccPV;VbdVV V(FVMVVVAu"p|"+R+PScSSUPUcrxS000(=0SSSSSUPUcrxcks|kwPws|XcPqwPws|qSudPududududucucPP(=ud.8uc8<R<=uc.<Ps4s4 s4uPuPuP (uPFuPuP)02;P;buDuDuP0 (uDFMuDMSuPSwuD00uD0c (c Fc 1(1F1uu u1RR R}(}F}RzRzRz(RzFRzuu uu0uLuuttuPs"SuHuHSuH (uHFMuHMSSSuHSuPuPuP (uPFMuPuPuPuPP111 (1FM1111PuT%/PuTuTuTuTSuTuTuTuTuTuPuPuP9;P;uDuD (uDFMuDuD9;Q;buTuT (uTFMuTuT911 (1FM11;QVV (VFMVV9;P;SS (SFHS;WVWbv|V (VFMVV;TSTbs|S (SFHS(SFHS(uDFMuDuDduTuTdkVdVVksVsxv|xVv|kxud}udRudud}PuTuTfsPswuDfwuPwuPuPuP~uPuHudRudP:d'fuT1fguTgRgLRgZgPZghL:d_duT_ddu`ddSdeu`eeSeVeu`VeaeSae'fu`1ffu`ffRfgu`ggXg gR g&gX&g5gS5gJgXJgNgRNgOgXcg|gX|ggSggXggS_d'f|1fOg|cgg|_d'fuT1fguTgOgLcggL_d'fW1ffWfgu@gggOgWcggWggggWtdxd0ddSdeSe4eS4e5et5e6et6e:etcgygSggS_ddu`ddSdeu`eeSeVeu`VeaeSae'fu`1ffu`ffRfgu`ggXg gR g&gX&g5gS5gJgXJgNgRNgOgXcg|gX|ggSggXggSxddVddPdeVe#eP#eeVg5gVcgygVggVggVggVddRddvsdevscgxgRxgygvsddSdeScgygSxddWdeWcgygWggWxdddecgygggxdduPdduPddQdeuPeeQeeuPggHxddu`ddu`ddSdeu`eeSggSddu`ddSddu`dduPddQdduPddPxdduPdduPxdduLdduLddRdduLddPe'f 1fOg gg e4eS4e5et5e6et6e:etggSe'fW1ffWfgu@gggOgWggWgge'f1fOggg>eVeSVeZetZe'fuL1fguLggDg&gS&g'gt'g(gt(g,gt,gOgDggDggD>eVeu`VeaeSae'fu`1ffu`ffRfgu`ggXg gR g&gX&g5gS5gJgXJgNgRNgOgXggSggXJeVeu`VeaeSaegeu`JeVeSVeZetZegeuLJeZePge'fuL1fguLggD5gOgDggDmeeuPeeRe'fuP1fguPggHggRggH5gOgHggHmexePggPggDggHggRggHggPggHggDggRggDggPxe'fu`1ffu`ffRfgu`ggXg gR ggX5gJgXJgNgRNgOgXggXxe'fuT1fguTggL5gOgLggL~eeSe'fud1ffudffrfgudgg\g gr gg\5gJg\JgNgrNgOg\gg\e'fuX1fguXggP5gOgPggPe'fV1ffVggV5gOgVe'fuh1ffuhffrfguhgg`g gr gg`5gJg`JgNgrNgOg`gg`e'fu\1fgu\ggT5gOgTggTeePe'fu`1ffu`ffRfgu`ggXg gR ggX5gJgXJgNgRNgOgXggXe'fV1ffVggV5gOgVeeSeeSees|eeSeeSees|eeSees|eeuPeeuPeeReeuPeePeePe'fu`1ffu`ffRffu`fguTggLggXg gR ggX5gJgXJgNgRNgOgXggXee uhu`4ff u\uT4efS1ffSggSee uhu`4eeSe'fW1ffWfgu@ggggW5gOgWgge'fu`1ffu`ffRfgu`ggXg gR ggX5gJgXJgNgRNgOgXggXeePg gPe'fuT1fguTggL5gOgLggL1fguTggLggL1fg1gg1HfguTggLggLHfg2gg2bfguTggLggLbfg3gg3ffQfguggggffVffsggVffWffsggWfguggggfgSggPggSggtfguTggLffWffVffVffv|fgVffVffv|ffVffv|ffu`ffu`ffRffu`ffPffPfguTggLff u\uT4fgWff u\uT4ffW:gOg@@gJgXJgNgRNgOgX@gNgPggWgg@ggRgg@ggPh&hP&hhShhPhhShhP"h&hP&hhShhPhhShhP/h:hP:hhWhhW/hhshhP#hhshhP#7hbhVhhV>hFhPJhbhVhhVOhbhughhugOhVhPhhPhhughhRhhughhPhhhShhPhhSlhvhslhvh0lhvhsvhhShhPhhS=RWZW=RZPRWZWWWSRucZucucucS^PP^RZdrQjVjrQjrQrSs|Sr{S{s|Ss|rududrPP0S s 'SZtSSud'udZtududud'ZtudPud'uduc ucR'ucPud< PucRucP'6u 69t9=t'6u9=tIRPt|PuducRucPESudSudYSS\ucuc\gPt{PgtwPtuTuTwQWwPVv|VVv|Vv|ududPP0Vv#VVtVVud#udVtudud#VtudPud#uduc ucR#ucP PucRucP#.u ./t/3t#VW?PP  3S38st8DSSst3S3<stss|3s3<s|o%0o07R7<oP%7P"P7IPPXuPuPuP#&P&,p|Uu#Xu#UXPXRXuPXoRouPRuP^u#Xu#^aPauTu#Xu#P s2&ժzXoPo{ s2&ժz s2&ժzP s2&ժzXoPo{ s2&ժz s2&ժzP s2&ժzX{00PXuL{PuLuLX1{111S{SPV{PVVVVvtVVVVVVVVVuLuLuTuT#uT<PuT#uT<P P XSSSiZiPZi l+ll5iGiD#GiLiPSiZiPZi l+llSi l+ll[ifiw$fijip~[iciw$#cijiPsiuiPkkPjkrkkrjkDkkDjk[kk[jkDkkDjk kk jkDkkDk.kPjkw$k kp~jkw$#k kPkkP ovv> )w7w> bstWovvW)w7wWbslsqlsqsPst&ttovvvv&)w7wxstWovvW)w7wWvvudstovv)w7wsspssPstV ovvV )w7wV sspssPstudovvud)w7wudvvudst\ ovv\ )w7w\ sspssPstV ovvV )w7wV stpt tPttovv)w7wttudovvud)w7wudovvud,tt)w7w,t9tp9t>tPEtt)w7wEtOtpOtTtP[ttz )w7wz [tetpetjtPttudtt07wJwud7wJw0ttPtXvv)wSwzwtVvWVvWvudWvXvt`v)wWSwzwWtXv4v)w4jwzw4tVvWVvWvudWvXvt`v)wWjwzwWWuuuXvvv w)wjwzw uVvWVvWvudWvXvt`v)wWjwzwWv wud-uXvvv w)wjwzwCuXv vv w)w jwzw WuWvudWvXvt`vvud w)wudjwzwud w)wudwuXv vv jwzw uXvvvjwzwuWvudWvXvt`vvudjwzwudvvuduXvrjwzwruXv4jwzw4uXvtjwzwtuXvjwzwuXvjwzw4vWvudWvXvt`4vXv0UwjwudUwjw0wwWwwtwwPw!xW!x"xuD"x#xt@#xyWw xS#xxS9y;ySwwPwwtwwtx xP#x3x0x xu`#xxu`xxRxyu` x#x0,xy0 x xud,xyudExNy gyy Ex;yV;yNyu\gylyVlyyu\yyVExOxpOxTxPUx9yxgyyxUx9yVgylyVlyyu\yyVUxxSUxXxv#dxhxphxmxPtx9y0gyy0tx~xp~xxPx9yuTxxSxyuXy)yS)y9yuXxxPy&yPxyu\)y9yu\xy0)y9y0xyu`)y9yu`xyud)y9yudxy0)y9y0xyS)y9ySyyu\)y9yu\y yP)y6yP;yNyu\;yNy0Nycyu`NySyudSyZyPZycyudwyyuT}yyuSyyRyyuS}yyPyySyyutyytpyySyyutyytpyyusyytoyyusyytoyyPzzuszzRzzuszzPSV"-SV^fSV"-u^unusu"-u V^u VVnu VnsVsu V"-u^unusuPSusRusPutusRusP7S(us(,R,7us,PPeutV`us`dRdeusVdP@zzSz {SSV"-SV^fSV"-u^uruwu"-u V^u VVru VrwVwu V"-u^uruwuPSusRusPutusRusP;S *us*.R.;us .PTiutZdusdhRhiusZhP{"{P"{i|Si|m|Pm||S&{j|Vm||V{{P{K|Um||U||U&{i|Si|m|Pm||S1{4{p$#4{?{pX|j|VX|m|0SV"-SV^fSV"-u^unusu"-u V^u VVnu VnsVsu V"-u^unusuPSusRusPutusRusP7S(us(,R,7us,PPeutV`us`dRdeusVdP||P|r~Sr~v~Pv~~S||P|6}V6}v~v~~V~~|r~Sr~v~Pv~~S||p$#|}p}}0}}V}r~Sr~v~P~~S}}s }}P}}P`~v~`~v~0~SS u  t ISI]u~ 0 PWPWPǃ W GW"P07p0.7uH0.uH0.ǃ uH0.  tD0. ]uH0.W0́u0u 0G]uṔuu PG]uQ́uu QG]uWss sGIsI]u#D0uLʁPʁ́uLuL 0G]uL|́SԂ#SESGISI]u#ŚSSGISI]ússGIsI]u4P uP uP#uPuP t sԂsWwWĀWĀʀw|RƀR 0mW SmS sms.W.7w7^W^mwmS"P".w2$q".7w2$q"OTw2$q"m ms|ԂsԂsԂsRRނWwEWG]WW#8s8<P#Es̓уQ"QуԃQԃqqPSV"-SV^fSV"-u^uruwu"-u V^u VVru VrwVwu V"-u^uruwuPSusRusPutusRusP;S *us*.R.;us .PTiutZdusdhRhiusZhPhipt0.{{QV ܄PV܄PS PVOVzV}ƆVOVzV}ƆV]_P_uTLԅPԅ|uT|}tP}ƆuTՅƆqvPvws$w{p~qvpv{PPPQ}Qq}qud\|ud|}t`}udP}P}VzVVP4P4ySS5}L}VVVV.VaVVV*RVpzVYu6pt67w<7<pl6P67w7<px"6pt67w<7<pl"6P67w7<pxOu\u\cgu\u\hwrtw}w<}phnrhnsSswrhw}wH}pxh00cg00hwrtw}w<}ppxshnrhnsSswrhw}wH}pxplsxQplsxpxsSPs u\u\udPududu\u\ududu[u[PPu\udu[Ru[P)uT<$)p<).uT<}p<)uP.cuPgluPuP~uP)TuPT0PuD_auDacuPgl0uDuDuPuDD0Hd0dpuDz~0cc gc ~c c1g1~1Ku.ulu1"Q.QlQc g ~ cglt~Ku$.u}u)u)0)uL)Ku)?S?KuKTsxacsxsx)/uPuT"/6P6uH.cuHgluHuH~uH4?S?KuKTsxacsxsx46P6TuHacuHuH^`S`uP.auPgluPuPuP*uPHpuPz~uP^`P^1.a1gl111*1Hp1z~1^`P`uTPgluT*uTHduTz~uT^`S`uTgluT*uTHduTz~uTduTgluT*uTHduTz~uT*uPQduPz~uPPuD.auDuDuDdpuDQuT_auTuTuTdpuT1.a111dp1PS.aSSSSst_aSSSS_aSSSSSuDuDdpuDuT.3uTVV._VVvtV.3vtvv|v.3v|u\u\ R u\.3u\ P3_uT:FuTPuDuPuPDHuPpzuPuP*DuH*DuH#3=u\=ARADu\3APWWb}WWWWb}WWPuPtLPauPabHbuPχ(-P-.s$.2p~(-p-2P;SVSovxb}V;>P>eQeuTtPuTbtQt}uTGeQexuTGSVSovxGVPV`q`epxKSVSovxKVPV`q`epxx b } xWWPP^S}Sb}1b ݈*u*+ +KuKLtLguluÈ*ul*+d+KulKLthLulÈutP*ut*+l+KutKLtpLutԈut)S)*uh*+`+JSJKuhKLtdlnSnuhutP*ut*+l+KutKLtplut)S)*uh*+`+JSJKuhKLtd*ug*+_+KugKLtcP+7P*ul*+d:KulKLth*ut*+l:KutKLtp*uh*+`:KuhKLtd+P:FPNlulNlutT^ug^bRblugTbPt~ug~RugtP  pVswVy{VuiSsSbVbivlswVy{VeSeislsS$_VswVy{V$_SsS}s ugRugPsugRugPSSuutuutpuuLu[wlwlLwl[WWLW[wlwlLwl[WWLW1w ",uT,0R01uT"0P1Hw7AuTAEREHuT7EPiSspsp SipuTxuTuT uTu`uSRuSPuXuSRuSPplvDpXQpXv(u p0x000plvDs|spvpXQpXv(shs\v|Rshs\v|s|spvVSstvstPttstshvsPss|vsxPslv s Sv puTxuTu Q uXPttpuXxuX u #qP%(u`(+P+/t/3t3pu`xu`%.q .3P9=P=AtAEtEpudxud9:u #=@p@EPLpuTxuTLpudxudOpuSxuSOVPxPVpu`u`\puSuS\cPPcpuXuXipuSuSipPPwDwDwDxuDuD uDuDLhuD uD #0#4S7:u@uDS0 uD3aSam0 uDLhuDc  c c Lhc 1 11Lh1uxuu1Q{QQ    Lh x      Lh uuuu0uuS spspS  SLhSuDw"2WW WWLhWS spspS  SLhS WW W WLhWw uTRuTP wuT R  uT P xuDuDuD3muD u tt x1113m1#4SS3aS#$u *.t#x1113a17xWW7@S7xSS@]S]aslaxSSsl@]s ]asxs sxFauTuTFMPPM]s]aspsspSauTuTuTSZPP@]s]as|axsss|@auTgquTquRuxuTuTguPWWyuD .uDCLuDLSVSWtWXvlXaVLSVSWtWavlmyWĉPĉ͉u#'=P%W'W V'6V6Iv`IKVikV v '6v 6IVIKv ikv  v IKv ikv  WIWSIS‰WIW‰SISKisQ[ug[_R_iugQ_Pq{ug{RugqP pۊVۊu tV.u 3Lu w u# t# Lw w Lw ۊVۊu V.u 3Lu SLSۊVۊu V.u 3Lu SLS3s%ug%)R)3ug)P;EugEIRILug;IP_Vu tҋVҋu  u \Wut WgWЋ WgVu ЋҋVҋu  u gSЋ SkVu ЋҋVҋu  u kSЋ Sҋs؋ugRug؋PugR ugP"^V^yu yztzVu Ɍu "xWzɌW*rWɌW*^V^ru Vu Ɍu *iSɌS.^V^lu Vu Ɍu .iSɌSsugRugPŒugŒƌRƌɌugƌP  QVTXVuJSTSCVCJvxTXVFSFJsxTS$@VTXV$@STSXnS]guggkRknug]kPwSwuwutuutNuuu"wx"+P+>wxwxwx>WWW"wx"+P+>wxwxwx>WWWWu`Ru`PMQVQRtRVtV{v|jnv|v|MVPVu`u`fu`u`u_Ru_Pf~rx~VSflrploPo{rp{~Vf~u f00fj0n0flrploPo{rp{~V~vpsprxPx~p vpspVSVSs|su`Pu`u`u tPttududu #pPu`u`ududu_u_PPu`u`u_u_PP3w8 q8Mfq83uP <uPuPuP3]uP]0VW <WVVuP-@uP@N0[a0k0fc c c f111Cu u<fu1,R R<fRf4 4 4 / </ Df/ / / Cu uMfu$3u$30$3uL3Cu3OVO]v|v|Vv|-@V38uPw"8HPH_W_uTuTuTW-@W[auTkuT?OVO]v|v|Vv|-@V?HPH]WW-@WuTu`Ru`P_uP <uPuPuP[auPkuP_gu _gW_1 <111[a1k1_WWW[aWkW_guPgVvxvxvx[aVkVgWwx[aWkWgVvx[aVkVtW[aWkWtV[aVkVkVpzu`z~R~u`p~PuPStsxSStsxVVVu t1 <111PuT uTVV <VVvxV Vvxvv|v vv|u`u`Ru` u`PVvx Vvxu` u`P P"P"PuPStsxSStsxNWuP(uP@NuT]SaSu(S 1VM^VŽV V|V(*V]SaSu(SP+Va|P|ŽV(V}Ž(Ž9=V=>t>BtB`uL`atHŽuLuL,uL9=uP=RVRStSZtZ`uP`atLŽuPuP,.V.uPH]s,ŽՏs,s,0s,HMs0ŽՏs0s00s0K]s,ŽՏs,s,0s,VZtZ`uP`atLŽՏuPuP0uPVu@ lu@Տu@0tu@VZPZ`u`atŽՏuu0uVkVk`uX`atTŽՏuXuX02V24uX46V6uX`kVk`uX`atTŽuXuX46V6uX`fPfou`ouPu`u``at\Žu`u`4u`lou`ouPu`u``at\Žu`u`;u`lV`u\`atXŽ u\ Vu\Vu\u\;=V=[u\[]V]u\|`u``at\Žu`u`;u`|u`udӍu\ӍuX`uP`atLŽ uP u`-ud-<u\<LuXLuPuP;=u`=[u\[]u`]tudtuP_W_`ud`at`ŽWW;WP Pu`udRudP`u\`atXŽ u\u\u\;u\`ud`at`Ž ududud;ud`ud`at`Ž udududtudud`u\`atXŽ u\-ud-u\u\tu\udӍu\ӍuX`uP`atLŽ uP-ud-<u\<LuXLuPuPtuP`u``at\Ž u`u`u`tu`P'P]tudcmu`mqRqtu`cqP`u\`atXŽ u\-u\u\tu\Ӎu\ӍuX`uP`atLŽ uP-<u\<LuXLuPuPtuPȍ`ud`at`Ž ud-ududtudȍӍP-6PӍ`uX`atTŽ uX<uXuXtuXӍuX`uP`atLŽ uP<LuXLuPuPtuPٍ`ud`at`Ž ud<ududtudٍP<FPuXuTRuTP=[u\CQu`QURU[u`CUP`uP`atLŽ uPLuPuPtuP`ud`at`Ž udLududtudPLVP`uL`atHŽ uL\uLuLtuL`ud`at`Ž ud\ududtudP\fP]s,Ž s,ls,s,ts,Ms0Ž s0ls0s0ts028P8MuTl|uTtuT?MuTl|uTBMudl|udBMPlvPMa> Žێuێ܎t܎t|uŽ s,|s, s,ю s, s,юێuێ܎t܎tюVՎێuێ܎t܎tՎV u@ ud PՏuPƏЏuTЏԏRԏՏuTƏԏPՏuLۏuTRuTۏP> ːS,SJOSutːVːutl.ut./tp/oututv ut/@utː utːVސutl.ut./tpusk.us./toP'P utV/O /3ut3OVWausaeReousWePsÑuÑđt đut "usÑu Ñđtđu t"u sxupxSÑupÑđtlđSuptlSup"SupuoRuoPSÑupÑđtlđSuptlÑutÑđtpđuttpÑuoÑđtkđuotkPut<đϑPSБݑupuo֑ݑuođP֑P`ڒulڒےdےQulvڒulڒےdےulQulْSْڒutڒےlےS!S!6utڒuڒےےu6uْSْڒutڒےlےSڒukڒےcےukPÒs<ےPÒupupÒSutÒPPÒڒulڒےdÒے0ul0!6ut'1uk15R56uk'5P6Mup<FukFJRJMuk<JP\oOO\oQ !-GbkYt~VCKKyWulnrL" 1\T=R =mckKhfh\\hhhhht_Ex]~FF~hlszpsz;>AFdl +.16T\{~kks3@Pafiw  ) )09 09 09 ['8;@-8;@ ['8;@-8;@/27$/27q| q| (0q|       &035@&035@@X@IXadgadgq|adgjjq|    +     < H P S t }    4;AP8;APA e h k   R  C34@  #VY\_b)1=qVY\_bl  )1)1':=@:=@JX`:=@CCJX`z%2%2`z`m`ffmmzmssz!dgl 7Q7= =Q Qdgl QWWdglsvy9<A"RT\psv|.BDL~XfhNZ 6AHK 8,8;<Uade~8H8HHXHXXhXhhxhxx xbdl  U[_psuw:n|:GLQGLQdGL)C)1CHwz`w `n   8 !#! !#! !#!!s"""!!!s"""!!!!!!!""#"!!""""""""j"o"""e"j"#"e"""["e"""########%%&&;&H&X&b&f&k&X&b&f&k&8A8A"AYAG"GY"/Yy"(Y_(/_y0909!9Q9>!>Qd''''d'n's'u'w''''''(Q)X)t)''(H)`)t)((2):)=)@) (2)`)t)$(((+(2)`)t)+(8(((((H(((2)`)t)z((`)p)()p)t)* * **R++,0,3,5,@,,z++++,,++++++++++k,,++++++++@,P,++++++@,P,++P,`,++P,`,++++++++`,k,++`,k,,- -"-//////000 0000000000000000000000U1h1s11111B1H1K111B1H1K1U1h1s1B1H1K1N1N1U1h1s112 2-2@22122 2r2222 22@2W222 2 2 22@2W2222233-3f32222222222222222332222332222223322223322223322222233x3{3~3334(44x3{3~33x3{3~3333333333(444333333(4443333T4n4333344333333444444*5B5444 54444V5X5^5n55:655555655555655555556F6L6R667#7077^6666O7d7k66666666@7O7666666@7O76666666677666607@766666607@766 777#766 7777667#77 77788891969888919698819698889d9f9m999w:::9A:C:F:::;:A:C:F:J:e:::U:e:::U:X:[:^:X:[:^:e:::/;?;B;G;4;?;B;G;;<<4<;<< <~<<H=p=J=M=R=p=<<<<< ======= =6===H=p=====(=p=========(=p==2=6===H=>>>> 8C 8CS>V>X>x?~??????S>V>X>`>f>m>s>>>>`>f>m>s>>>>?? ???`>f>m>s>>>>>>>>>?? ? ?!?o??? ? ?!?Z?x?{???{?~???{?~?????@GAXAA??@@XAhA??@@$@.@1@:@:@\@_@b@hAAB@O@R@S@V@\@_@b@hAA\@_@b@x@b@l@o@x@x@@@@AA@@@@@@@@AA@@@@@@@@@@@@@@@@@@@@@@@@@@@@@#AAAAAAAA A A#AAA#A1A4A7A1A4A7AGA1A4A7AGA1A4A7AGA TgjmAAAB!B&B0B0C3C5C@CE0BCPDDDDFAFGFGFJFFFWFZF]FtFWFZF]FtFWFZF]FtFFFFGGGGDHFFFFFGGGGGGGG)G,G/G)G,G/G?G)G,G/G?G)G,G/G?GKGNGQGGKGNGGGKGNGGGKGNGGG`GmGpGvGmGpGvGGGGvGyG|GGGGGGGGGGGGGGGGGGGGGGGGGGGGVH^HbHHHHHHHHHHHHHHI IHHHHHHHHI IHHHHHHI IIIII"III`JmJJ'I2I7I9INIQITIdIgIjITI[I^IdIgIjIdIgIjIzI}IIdIgIjInItIzI}IIIIIIIIIIIIIIIIDJGJJJ`JIIDJGJJJMJIIMJ`JIIIIIIIIJ J J JJ J JJ>&,39QT|&,39QT|&,39QT|1>DFORSORSW\behbehrbehkkrJJK+PdKLNN*OXOOOsK}KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKL L LKKLL L LL L LLLLLLL,L/L2LL#L&L,L/L2L,L/L2LBLELHL2L9LXSX1X7XSXcXYYY#\&\)\8\6]YYYZ[[\6]YYYYYYYYYYYYYYYYYWZ]6]YYYYYYYZZ ZZZ ZAZWZ]Z{ZZZZZZWZ]Z{ZZZ[['[8\\\\['[8\\\\[#[8\\\\8\Q\`\\\\;\=\C\E\\\E\Q\`\\\\`\\\\'[*[-[8['[*[-[8['[*[-[8[*[-[O[b[h[i[b[h[i[r[x[{[r[x[{[#\\\r[x[[[\\r[x[[[\\r[x[[[[[\\F]I]S]]]_Y]]]_p]]]_]]]]]]^^]]^^^^]]^^^'^*^8^;^E^H^X^a^k^n^^^^^^^___(_+_,_<_?_B_,_3_6_<_?_B_<_?_B_R_U_X_<_?_B_F_L_R_U_X_R_U_X_h_k_n_X___b_h_k_n_h_k_n__h_k_n_q_]]]]]]]]]]]]]]]]___daxaa_@axaaaa__````+a4a```#a&a+axaaaa``` `` a` `````` `a a`` `3`6`9` `*`-`3`6`9`3`6`9`I`L`O`9`@`C`I`L`O`I`L`O`_`b`e`I`L`O`S`Y`_`b`e`_`b`e`u`x`{`e`l`o`u`x`{`u`x`{``xaau`x`{`~`~``xaa`` a#a&a+a`` a#a&a+a``````````````@aNaQaTaNaQaTadaNaQaTadaNaQaTada-@K @K @K$@K$@Kaccdbbbbb?bcd"b/b2b3b6bdQddd7c=c>cmc d0ddd7c:c>cBcEcmc d0ddd7c:c>cBcEcJcMcOcJcMcOcYc\c_cYc\c_cmc d0dYc\c_cbcbcmc d0dzc}ccczc}ccczc}ccccccc0d>dcccc0d>dcccc0d>dcc0d>dcc0d>dd7eHeeddddd7eHeeddddddddddddddddd$eHeeeeeeeee$eHeXeeeeee$eHeXeeeeeeffffg-gsgeee)fff\gsge)fff\gsgef f ff f fffffff)ffffffff)fff)fnffffg-gAgFf^fafdf^fafdfnfff^fafdfgfgfnfffeeeeffffffffffffffffffffffffff8Py,8P\18P\-:WJXuggg@igggggggg.hGhJhMhhi:hGhJhMhGhJhMh[hhhGhJhMhPhPh[hhhhhhhhhhhhhhhhhhhhhLiPiSijjjjkjiijktiiiiiijkiiiiiiiiiiiiiiiiiiiiiiijjjiijJjjjii#j1jjjii#j&j&j1jjj&k(k/k1k4kkkk[kukxk{k[kdkokukxk{kukxk{kkkkukxk{k~k~kkkkkkkkkkkkkkll llll llll llllllllllllllllllllllllllmmm mmmmmm mmm m*m8m@mmm m#m#m*m8m@mmmmmmmmmmmmmmmmmwozo{oooooooooooooooooooooooooo1qZq_qhqkqmqoqtqFqZq_qhqqqqqqqqqqqqq ruxl cfil "(=@\"(=@\Rl"(=@\6>\6krY\c(.5JJY\cY\cr|rrrrrr|rrrrrrrr\s_sbslsss\s_sbseseslsssstt tt;t>tkt8t;t>tKtttttttttttttPuTuXuZuPuTuXuZuPuTuXuZu y| cfiq "(=@\"(=@\Wq"(=@\6=QT^6kqqzy&  &`cj/5<QQ`cj`cjyuuuuvvuuuuuuvv_vHwXwwwvzv}vHwXwwwwvvhwwvvhwwwww&wXwhwwwwww&wXwhw&w6w9w>w,w6w9w>w(147147G147G147Gx,x/x2xxxx,x/x2x,x/x2xw!+ u~(} 0 "# G[^a[^attєӔ<H &&&HKN`.;>?BHKN`KNcmpHKNadgNX[adgЕӕ֕ĕʕЕӕ֕Еӕ֕Еӕٕ֕^0`ak0HyƖƖ֖ٖܖ֖ٖܖ֖ٖܖΙΙ)ΙhӘ՘Ιԙי))))=@B=@BPSVPSVfilPSVZ`filfil|lsv||/24/24BEHBEHX[^BEHLRX[^X[^pX[^aї ): /: ,9PX29PX9FXp9?X^?F^p F`,9`h29`h9Fh9?hn?Fn kx$kx$_xERKRR_xX_x k k$k$_ERKRR_X_ <<0XdHKNQx@H@H @CD,@CD@CDMPSMPS]xMPSVV]x]j]ccj @CD,@CD@CDMPSMPS]xMPSVV]x]j]ccj5DORUORU_ORUXX__l_eel AP7i1]y|1ly|PXPXXwX^^www}}0%%00A7066A7&47:47:D`h47:==D`hDQhDJhnJQn !pݛ pݛ#0 $@ $@ 3HȜ,HȜ(HȜܜ ՝ݝܜ ݝܜ ݝ՝՝S` F47:` 3/` 347=BES3F47ABES3F\Z]`h\zh{\oh{zZ]`{zZ]`{٠ΡHH٠HΡàǠ٠HΡߡ0ߡ0ߡ0@LS{~@Lh{~@EhmELm{~ʣѣʣããʣ3EPp!p&QQ`]`cfpxpxȤ֤ͤХ/25#)/25/25E5<?EE^adEQTUX^ad^adh{~hrsz¥¥ϦϦ8x8gWZ]gWZ]``gY` ǧѧԧݧݧ``.14%(.14.14G4;>GGiloO\_`ciloilooy|ĨǨʨĨǨʨĨǨʨڨݨʨѨԨڨݨڨݨ),/9),/2299F?F!*ѪMux{ux{~~ѪêêѪVY\_e7VY\_emȫ˫Ϋȫ˫Ϋѫ1NQT`|E\o|   7 &&77O7==OOgOUUgggmm  .KNQ]y|=Tly|///G/55GG_GMM__w_eewww}}1B0JBX[^JXjyX`X```ff  '' J  J  ,/0,/0:=@:=@J:=@CCJJ'=cvy|vy|vy|9<? #9<?<?<?9<?xUhknhknxhknqqx,/2 &,/2,/2kH[^a[^ak[^addk9<? #9<?<?<?9<?xUhknhknxhknqqx%(+%(+dATWZTWZdTWZ]]d9<? #9<?<?<?9<?xUhknhknxhknqqxAKPVY]`ȭhuv{~ͬЬҬͬЬҬ  aINT]$'*;>?*14;>?;>?IQT`h`h{ܮ0Ʈɮ̮ܮƮɮ̮ܮƮɮ̮ܮ:=@ -014:=@=@:=@yViloiloyilorrycpЯpuůȯ˯HKNѱVY\n\cfnwz}wz}wz}ѱϰİǰϰذ۰ްذ۰ްذ۰ްADGcADGcADGcKWPWc *8cy{~;m  %(+;%(+;%(+;WZ]CVehk}kru}8C8C8C8C8C޶mʵAXʵʵʵ3*A  #3 #3 #3fikXmsvysv{}sv{}sv{}¶޶¶޶¶޶ƶҶ˶Ҷݷ'8 øƸɸ۸ɸиӸ۸Tq"%7%,/7>ADT>ADT>ADTƹZqƹƹƹݹ8Cݹ8Cݹ8C8C8C9<? #9<?<?<?9<?xUhknhknxhknqqx9<? #9<?<?<?9<?xUhknhknxhknqqx@YhRhny*AĻǻɻAXѻԻ׻׻޻ #%aXo-03D39<DKNQaKNQaKNQaaompssz}¼Լ¼ɼ̼Լۼ޼ۼ޼ۼ޼@ ##*-0@*-0@*-0@@ܿLORcRX[cjmpjmpjmpܽܿƽɽ̽ܽƽɽ̽ܽƽɽ̽ܽܽ   69;x6CFI[IPS[behxbehxbehxx6RϾҾվϾҾվϾҾվݾ9<? #9<?<?<?9<?xUhknhknxhknqqx O1 2 '*29<?O9<?O9<?Oehkehkehko{t{  ~ J-"%-47:J47:J47:Jmpsmpsmps{.27>PSUr]`cucjmu||| #CP[ #CP[ #CP[+7P[07P[ vy|Rt41.Ro3DE3DEZou ou '2 '2 '2 '2771e7IR\]IR\]1IIR\]bi}b%+1y9?BTBILT`fiy`fiy`fiy    1b ;I ;>>Ivy|#)N^ (P(L Lp""p0Pp@P0@ )/6<WZ)/6<WZ)/6<WZ [bv} [w`fp-8:-8:Upv pv(3(3(3(39EFBHKkBHKkBHKkO_T_kP`tP`FLOpppp.FLOFLO`pFLm`pFLw`pFLwzz`p  %%8@&X_blo{~ovy{TWY_WYppsv{Z`mc#&P4L###4)4P`4D`pQ_}k#&X9'T  (((9.9Xh9I hxVd'AP(+-:$@K$@K @$4)4@_GSLS_lellxlqqx   V[^ddgjpgjp0?Ebm|m|m|m|O]$*-e$D$*-UOO]e]e,AP]`p~cfpcfpcfp{VYp~~`p```@Ph3>PhhCQQYYh0C0<Hb/:Hbbz>JzJQY[QY[f > 6`il>AES@Ph3>PhhCQQYYh0C0"" QdQd!("034_hk"bhk(y((8Q8Q8>AQ(8(87R`cfw%0G%0G%036GVYehnz0o0o$'OoOoOo'-ayUo'-ayUo'-ayUoZy|09UZy09UZv09Uss,9hks=R 0 0 "%"%"%3"%3"%((33DP`3DP`9DP`DU`pJU`pUfpUfp[fpfzlzz   88MiLi |]XuH]fUWgWgWg,4:=W4:=@EKSVfEKNQSaft%%13>DP h  \  \ ,h ,h 27rZx%;>A(25;>A;>AQTWAHKQTWQTWgjmW^agjmgjm}mtw}}XdXd -03 -03-03AHX-0366AHXHV3Zilq>KNQ>KNQKNQ_KNQTT__peppvB}BvOUXHUX%0G%0G%036GUX[ 00?0?    @Ph3>PhhCQQYYh0C0@Ph3>PhhCQQYYh0C0=p -014::=p:=s}=ILOILO_ILO_ILO_@Ph3>PhhCQQYYh0C09;?Ph #*X#6X69?B9?BX!8!8pCFKSFKU`SU`ez}}>cfm>CFNN^`c^`fmsvz % '2%'27=[]`=IIOO[]`svz 47:H beh` "(=@\"(=@\`x"(=@\;?];beh{{4H`H`H`H`%%%4%(/%(/;PSV`PSVYY``mfmHNQ[NQ[g0:  $'*:$'*:$'*:PSVrPSVrPSVrZf_frx\beobeo{ N^s1&)18;>N8;>N8;>Ndgjdgjdgjnzsz!$'!$'67Na !$'7!$'7!$'7\_ailoovy@N@N@N@N@N0@0@nqtwqtw       B E H    P S V h V ] ` h q t w  q t w  q t w                               &      &      &           & 3   , 3           L R U _ R U _ k                              > N c    !    ! ( + . > ( + . > ( + . > T W Z v   T W Z v   T W Z v   ^ j   c j   v    |           &  E !  8@@HHW@Gyy}y}} ;PSUXhx !PSUXv |  fp         :GQf                                         ) ') ') ') '):'G):'G)/'-/:-G:KGg:KGg:@GM@KMgK\gKQgmQ\m$$:Q$)/:ADGUP`ADGJJUP`Uf@P[f@Pq@`{8@`l`l`l00fs35;=CIN^s^f*@ 9<?&9<?9<?M9<?BBMSdfh   / / WrWZ Zrrruu*##*55%H5djn5dgns5}Nr`morVsVs<\rux_ilruxruxrux|_bes_behhs(479N_be'-0'-0:'*03*-3:DNQ]]qtwtwqtww&&  "(58:FILSLS ] ] ~ ~7:GJ &),8cfipBHJPPcpLjx""<_p <TW]p z = ` p    != [ ] ` p    !X [ ] ` z        !R!!!1"@"p#`!c!f!!"7#]#p#`!c!f!!"7#]#p#"""""""7#]#p#!!!1"@""7#]#!!!!@""7#J#!!!!@""7#J#!!!1"J#]#!!!1"J#]###$P$$.%A%T%##$P$$.%A%T%$ $"$($($A$$.%A%T%##P$$$$.%A%####P$$$$.%A%####Z$`$b$h$h$}$$$.%A%l%%%E&P&(z%%P&&''b(w(z%%P&&''b(w(Z&`&b&h&h&&''b(w(%%%%&&'8(M(b(%%%%&&'8(M(b(&&&&&&'8(M(b(%&0''w((%%%&&&0''w((%%0''w((%%&& &&&E&&0'8(M(&/&5&<&&0'8(M(&,&&0'8(M(/&2&<&E&/27$/27(&))).)8)11qD6*<*?*M*556*<*?*B*B*M*55M*a*55V*a*55a*u*55j*u*55u**55~**55**55**55**55**55++++v55++++++v55+ ,f5v5, ,f5v5 ,,V5f5,,V5f5,3,F5V5(,3,F5V53,G,v66<,G,v66G,[,f6v6P,[,f6v6[,o,V6f6d,o,V6f6o,,F6V6x,,F6V6,,66F6,,66F6,,&666,,&666,,6&6,,6&6,,66,,66,,65F5,,65F5,%-*---99,,,- -%-*---,,--%-*----565669:;;MDqD%-*---7-7--565669:;;MDqD7-9->-\-a--5659:7-9-a--5659:7-9-a-i-5659:9->-\-a---;;MDRD----%.|.::%.l.::............. ///. /// /// /56 ///// /56@/0112356W7}7U889::;;AACMD//`45CMD/012226W7}7818U88I9AA1#13`4;;818::818::01T123ACT1W1Z1]1W1Z1]1c1m1p1c1i1p11c1i1p111155115511221122W7}7U8k8n7q7v7}7 E EEEHEEFFHEEFFHEKENEbEKENEbEEFFKENEbEiEkEpEsEvE~EEFFEE!FFG2G>GHGEE!FFG2G>GHGEE!F0F3F6FJFFG2G>GHG3F6FJFQFSFXF[F^FfFFG2G>GHG0F3F6FJFE!FFG2G>GE!FFG2G>GEEEEEEE!FFG2G>GEEEEEEEEE!FFG2G>GVGYG\G_GeGKHXH*IGGGGGGGGGGGGGGGGGGGGGGGHHHGGGGGHHHH%H(H-HH%H(H-HHHHHHHHHHHHHHHHHHHHHHHHHegg e.egg>egeg:ggexeggmexeggxeeeexe~eeeee~eeeeeeeeeeeeeeeeeeeeeeeeeeeeggeeggeefffffffffffffffffgffffffffffffgggggggg"hhhhh'h-h/hhhhh7hVhhhJhVhhhOhVhhhvh|hhh=JMPJMP^JMPSS^^d0`x`x   IRxESVYSVYgtSVY\\gtgltwrtw(`t`t 038%038 ,@#&),JPU`X[^`X[g|`{X[`{X[`{^g|{`&i)i/i}jjl5iAiGiMi5i8i;i=i5i8i;i=i5i8i;i=i[ikipisicikipisikipisi~ijjjjjjjjjkkkj kkkk kkk kkkktuple iosfwdstl_function.hcstdlibbasic_ios.tccpostypes.hfunctexcept.hostream_insert.hstdio.hlibio.hstdarg.h stddef.h wchar.htime.hnumeric_traits.halloc_traits.htype_traits.hdebug.h locale.htypes.hsched.htime.hpthreadtypes.hatomic_word.h wctype.hstdlib.htypes.h sigset.hselect.h stat.hunistd.hregex.hgtest-string.hgtest-spi.hgtest-death-test.hsiginfo.hsignal.hsigaction.hstdlib-float.hstdlib-bsearch.hfcntl-linux.htime.h socket_type.hsockaddr.hsocket.hnetdb.hgthr-default.h errno.hctype.hsocket.h pthread.hwait.h mman.h sched.hfcntl.hcxxabi.h  KJ     o.{fJ1 o{.J oJ oJrJ <eYK֐ e. .dt J< itfjX JJLtJK{t<mm<m<X<mm<m<X<mm<m<X<mm<m<X<mm<m<X<mm<m<X<m4<m4<m4<m4<m4tme=m<m<XNtmz< st ~~JJo/0Ons JufJ' Xt~Os<.0P ,KK,AJ@ |J=/=/>/=/=/=/=/ JLw- SX,<./wYo3L\Y[.<m[q.{X3QtK#PJ2 KsK t-<~>?y<><~ Zj<~  t-Zf,h ~ffJi.|<JJ J9MG<FJ;.}."[ <su Z;Yd{<|<|f<|.<z< l<l<C<<|<|f<|<}f<}.j<<|t<t|< ~|<|<C<~<U1i[<|<|J} <} <}f#<b<b}<}<i <.l |t<|"jlY'<Y<=z..z. v.<kJflf<l<Jzb<z<z<C<tv7zhf>Cfvz<'zf<z<Jz< {t~X<~.<z< l<l<C<:zb<z<z<C<tv<<{JCXtz@hf<{fCfv{<Cf ȐgYK<=oi-/e<d<<;L;>;ruz<z<C<=Cf /<kJ<;=;j/.bJ=<a<<b<>^< <>;vCX=Cf=Cf I=i9 tv f lfl<C< v  fx<|C<"V#zJ#   t;=m&vCtg-u-={ <kflf<l<C<u;Qy<z<.}<ffy<{tCf{JJ{J.JL[{K;=;={f<kfXlf<l<C<t{CfK;=;={f<kfXlf<l<C<t{Cfg;uY'<Ys->-FXu otz<z<C<=tCftnfCfnCf=Cf=CXt>q<p<|J.M,@l<l<C<tlCf$s=/mffvr|< l<l<C<=Cfj#v%xtx<X l? Cf=Cfo<~<f  1l*<l<C<tvtl$Cf&s= .zc#l)<l<C<tl<l<C<=)Cf=CfȐ=vrX|< l<l<C<=Cfn<k0<k<C<o Jfk<k<C<~J<~. o<.|Xk<k<C<o%o...Pm<gfk0Cf=1Cf= Cf = Cf=.CfSf{.fn<tn<n<~~<<C<=tCf=tCfXt~. < Cf=CX=Cf=Cf=Cf#RV0 fǹ,/!;!!;!/!;!i<i<C<=Cf=Cf=Cf=Cf=Cf=Cf=Cf=Cf=Cf=Cf=Cf=Cf=Cf=CfwX <w< <iCf=Cf=Cf=Cf=Cf=Cf=Cf=Cf=Cf = Cf = Cf=Cf=Cf=Cf=CfE~:<t#~<~fC<=Cf~<<C<=CfN0!;!~<~fC<=tCf=tCf=tCf=tCfNpCf=tCf=Cf=Cf=.Cf=fCf=Cf=Cf=Cf+<~f<<~<~Y-/~t<~<C<2 CX=Cf!WYe:>r <r<C<=tCftrCf r Cf=Cft>l}n<n<C<tl<CfY;<=of<|<|} <} <|f<<|<|f<|<|f<|<|} <} <|f<<|<|f<|<|f<|<|f<|<|f<|<|f<|<t|<  p<< p#<p<C<=tCftv ot_Cf = Cf v|!WYet{<t{<t{<t{<>r!;!!;!{~<~<C<=Cf=Cf=Cf=Cf=Cf2 usc<Xa u  u uy4t|f< Xg;z~<~<C<=Cf"y4t|f<X;YxjCf=CfyfCf=.Cf=.Cf=.Cf=.Cf=.Cf<v*4zX<z<<z < 0:+!;!sf0.vf < ..zCf=Cf = Cf = Cf=Cf=Cf=Cf=Cf=Cf = Cf = Cf=Cf=Cf=Cf=Cf=Cf=Cf!=!Cf#=#Cf%=%CfXw-=S.kf yfj<p<Y;=sf Lb<d<d.Xbt<b<C<=tCfts Lb<b<C<XbCftbCf=it yfi~<<.k~yJ<y<C<=tCfty.<ty2Cf=CfȐy#<t ~yJty <y<~<<|t<~{<b=;=b.<c<~JXJP1?c{<Cf<btX=;=7%?28@?w.WGcJ{< <_JC<=Cf!b'XJ(t_Cf=Cf~f} Jt .r<.Ӓ:>v <.sJof<)fk<J;=~X  t./<{<|<~f<<kJfkf<n<|t<~f<~<C<v }. .< w)&.zf).~)<.~...l/J~/<~<C<t<|<~f<<kJfkf<n<|t<).zf).~)<.~.i/.{</<}C</<}<C<.~t(t<|<|Mj<<|<}X .l<Cf)t.y)X{fCf=fCf.~.~<.~<<C<.~ ttCf#fgs\<#\.#.hfh<.\#<\<#tK=LLLLMxo<\C<$^,hzXf]<#X#a"yXW/Xyfy<C<=C=C=C=C=CWIg;eX)<!e!<X</<!!yfy<C<=C=C=C=C=C=C=C=C=C=C=C=Cyy<#~XX~<{.{X|X,gg0 0w y ff J< ~t<9y"CXA J y ff X<y ff <~f {.~f~<C<<W(fX( K"[91e/ f"/Zz#/,}X|<<|< f}fP <f ~Xt$ 8 J <<<<MV xlJC= C= C= C= C= C= C f ~X< ~X|tC= C= C= C= C= C=$Cf JC= C!xf tC= C= C= C= C= C= C~5t0wt00SC= C= C= C= C= C= C= C= C= C= C= C= C= C= C= C= C= C= C= C= C=KC= C= C= C= C= C2R X   XXcRX   XXyC= C= C= C= C= C= C=C=C= C= C= C= C= C= C =0 C"= "C$= $C&= &C=EC= C= C= C=EC= C= C= C= C= C= C= C0~kXf  <zzzt3 .<xr r  <s<  < t v. X v< <v0w fr  <s<  < t v. X v< <v0w v  <s<  < t v. X v< <v0w wX J J0rJ00S00S00Sh:>:h g.~l.~.<n~<<n~<~<C<}fCX~X J z&0h.|<n<~<~<.֩ +hXCfk<f"e=h<h<C<=Cf~<}J.L&h<h<C<=Cf}<}J.K&h<h<C<=Cf"Jh<h<C<=Cf&h<<h<C<=Cf(hf<h<C<=Cfh<{ l<l<C<fh~<;h jfjJ~<<n~<~<C<hCf=Cf=Cf=Cf=Cf=Cf-hCf=Cf=tCf=Cf = Cf=.Cf=.Cf=Cf=.Cf=Cf=Cf= Cf= Cf=Cfg;<=i~<<pJ'h<h<C<=CfJ'h<h<C<=Cf 'hfhfC<=Cf)h<h<C<=Cf<jf<%g<g<C<=Cf<jf<%g<g<C<=Cf0g<g<C<=Cf<j<g<{ l<l<C<*g <g<C<=Cf>jXj <t}XJ!jt<j<XiJ~<<g<g<C<g^Cf=-Cfg Cf=$Cf=5Cf=Cf=tCf=Cf=Cf=.Cf=.Cf=Cf=.Cf=Cf=Cf=Cf=XCf= Cf=Cf=Cf=Cf=Cf.hfff>hP "im|<|rx{Cf t91YtCf txvԒhd>%t. <t<C<t}f.}<CX~t t Wt.Cf txY fw. ,<<2JztB><<|t<}f} <} <|f<|<}f<rC<=<C<tv{CXt2vqzCf #RxfDs( <s<C< tsCfKv " Kutzf xt. Xut~ f Xv< <vftt Xt< 5T2t< 3+?G?\<s< ptttbKt~  Xw<<wfus<~X<~2 Xs. r< Xr< r p  mKd>_824#'eJfjf-",>=-=cffc i i/df . {g. |tfctd +i9i+ib. JD[<<.XH`<trf<c<Xct}JJcf{ c f h ;gk<={<~<{JX{ yJ$;Kk yt* y*XhJJ.lJfy<{ Cf=Cf~Jf yJ>yf{ Cf=Cft;=< yJ>}f{ Cf=Cf te= | Y|fJu }< .}f X}<XS-<SfC< ~< ~<fC<=Cf=Cf=Cf=Cf < x.yJ(.=y<y<.<{J~<<<n.~<<rw{J(=;gXytCf=tCfty Cf yCf=Cf=;gXytCf=tCfty"Cf=XCf=Cf~<<~fL;gXytCf=tCftb~-yCf=Cf~<<~fL;gXytCf=tCftb~5{Cf=Cf fu<<= Xuy<}<<{t~<<n.~<<rhy<Cft{t%m.uyCf=Cf Y;y<f o~< x<x<C<=tCftyXCfyCf=Cf Y;y<f o~< x<x<C<=tCftyXCfyCf=Cf{fIX1x<x<C<=tCft<{<gfxCf=Cf=Cf #U^z<<y<}X_!<_< u~<< u~< x<x<C<=tCf=tCf=tCf=tCf=tCfy Cf=Cf= Cf= Cf= Cf yCf=Cf=Cf=Cf=Cf=Cf=/Cf h:<{<<{UX+<U< u~<< u~< x<x<C<=Cf=Cf=Cf=Cf=Cf{<gfxXCf=Cf= Cf=Cf=CfyCf=Cf=Cf=Cf=Cf=Cf=Cf)g<z<<=~f<y <z< l<l<C<:ttzb<z<z<C<tv{/hfCfv{JCfg;Vt../xJ(.Y >Vt...xtX.w<}f.Cf~< J w}fJCf~ Jf}.}<iPr><|(~<-//.3rt(~.~t(~. ~~1zXftzf[Xq<md!.bgf}.X< }87A}.|)<%< l<l<C<=Cf}}~<<l<l<C<=4 }~Cf=Cf= Cff}.X<}87A}.|)<*< l<l<C<=Cf}}D ~<<l<l<C<84 }~Cf=Cf= Cff}}<.} t}}.~<<l<l<C<=.Cffh{JCXt0t ~j: {zt z. t ~j:J+xYJ{J<N}t& |f&f |f#f ~f#J ~f#J ~<#g~.#X~ #f~ #}#f"}f"N|J<}X<}<.}fm<|C<"V#z# ffz# J #~< t&;=#z& t&}!   yJ  yJ < y< mt mt mrJ m t {< . { . {<  {< . {<nv m t < m t < mua   y < y<<nX<nX< m<nX mJ"f rJ {J r { r {$t. rX|<.nX mJX f rJ|Xnf mf    yJ  yJ < y<,.,a<,a<,a< `v,. et,{<. et,{<. `B J {< . {<  {f . {f%tNO-V<%*.-Vf%*.f%~f.<.%B%m<X8 t.&;=\J#<WJOj8[.Cf$;֔ZKUSzXxX vX uX sXrXqXpXoXnXmXkXiXgXm<[$<[tC<t<mJ<mJ<Lr[Cf&;=\f#<\#<JOj8[.Cf$;֔ZKqoztxt vt ut strtqtptotntmtktitgtm<[$<[tC<t<mJ<mJ<L[Cf>J+xYJ{J<N}t >uue<<gfg.f0e<<rxJ(.X CX~j ~J ~<>:><~<fK <t< <s J~<~<C<t |t . {X y0}.X0}< f0w.70}fJ0}< t0w}.<CX = {Jz t>;;0t {zJ000SCf f}3 t0}XXC0~J00S&9[.kf]~<~<C<fufJCX~&.dX` yX{Cf%h``{4Cf=tCf&W=?9[.q h]~<~<C<Xuf.w<tCX~ X<d.X!` yX{Cf%k`g{'CfX Cf~ ul<l<<8gfgXu< <y<{J|h,==0 J0|t <v< <t3 ttw0_< 0hXXf J 0t00S wf _8>XH*X?9idq<q<C<q Cf?9iq<q<C<w qCfwwf _8>XH*X?9idq<q<C< XqCf?9iq<q<C<]rqCfwwf _8>XH*X?9idq<q<C<q Cf?9iq<q<C<w qCfwwf _8>XH*X?9idq<q<C< XqCf?9iq<q<C<]rqCfw ~J~<~f<X<~<ff<sf<<~<~<C<t | . {X y0}.X0}< .J0|"70}fJ0}< J0|}.<Cf = {Jz t:==:0t {zJ .z<000SCff}3 t0}XXC0~J00S0l \J0; <Cf=Cf0~w 0kj ~JD}f4}<<<|f|<<|<| fs|ff|<.|JX|tf| <|JX|f~f<~<C<=tCf=tCft&| < {X yX0;0~<0}XhffCf=tCf~ttCf = {z, J;==:0XCf=Cf }xX}tw Jw< X ~,  {zX#V<Cf=Cf)tCf=CfJ0l J0| CX0~w 0kqj ~J(fX<<<= .s JJf~f<~<C<=tCft|t < {X y0}. J0|4<0~<0}Xh<CX~tCf = {Jz$ J>;;0 {zX .z.V<Cf=CX}tw Jw< XC }xX ~,.CX0~w Jw< X0kqX.1\Jۋ]z^/ 7 7z ^& u  X&z ^6<T}<{ + s< X'<<{<<{.{Xnext_segmentline_ZNSt6vectorIiSaIiEE6assignEjRKi__sigset_tPrettyUnitTestResultPrinter_ZN7testing22EmptyTestEventListeneraSERKS0_current_test_resultbreak_on_failureCStringEquals_ZN9__gnu_cxx13new_allocatorIN7testing12TestPropertyEE10deallocateEPS2_jiterator_traits_ZNK7testing8internal24HasNewFatalFailureHelper21has_new_fatal_failureEv_ZNSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE2atEjPrintAsStringLiteralTotesting_internalRawType_ZNK9__gnu_cxx17__normal_iteratorIPPN7testing8TestInfoESt6vectorIS3_SaIS3_EEEmiEi_ZNSt11char_traitsIcE4copyEPcPKcj_ZNSt6vectorIPcSaIS0_EE8_M_eraseEN9__gnu_cxx17__normal_iteratorIPS0_S2_EES6__S_oct_ZN7testing8TestCase11ClearResultEv_TypestartPrintStringTo__copy_move_backwardread_ZN7testing8internal12TypeIdHelperINS_4TestEE6dummy_E_ZN7testing8internal24HasNewFatalFailureHelperD0Ev_ZNSbIwSt11char_traitsIwESaIwEE6assignEPKw_ZN7testing22EmptyTestEventListener13OnTestCaseEndERKNS_8TestCaseE_ZN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE11ValueHolder7pointerEv_ZNK7testing8internal13FloatingPointIfE8sign_bitEv_ZN7testing8TestCase16RunSetUpTestCaseEvstrtof_ZNKSbIwSt11char_traitsIwESaIwEE7compareEjjPKw__alloc_traits >_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE6_S_keyEPKSt13_Rb_tree_nodeIS1_E_ZN7testing32ScopedFakeTestPartResultReporter4InitEvstrtoloperator<< _ZN9__gnu_cxx14__alloc_traitsISaIPN7testing8TestInfoEEE10_S_on_swapERS4_S6__ZN7testing8internal13DeathTestImpl12set_write_fdEi_ZN7testing8TestInfoaSERKS0___haystackIsNotSubstringallocatorgetwcconstruct >ImplicitCast__ZNKSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE2atEjgtest_arline_number__ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EE2atEj_ZNK9__gnu_cxx17__normal_iteratorIPN7testing12TestPropertyESt6vectorIS2_SaIS2_EEEptEvCheckedDowncastToActualType >::ValueHolder, testing::internal::ThreadLocalValueHolderBase>socklen_t_ZNSt6vectorIPN7testing8TestCaseESaIS2_EE7reserveEj_Rb_tree_node_base__niter_base_ZNKSt6vectorIiSaIiEE8capacityEvHandleExceptionsInMethodIfSupported_ZN9__gnu_cxx17__normal_iteratorIPKPN7testing17TestEventListenerESt6vectorIS3_SaIS3_EEEmmEi_ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EE5frontEv__copy_move_backward_a_ZN7testing8internal27PrettyUnitTestResultPrinter11OnTestStartERKNS_8TestInfoE_ZN7testing18TestEventListeners22SetDefaultXmlGeneratorEPNS_17TestEventListenerEHandleSehExceptionsInMethodIfSupportedMSG_EOR_ZNKSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE12_M_rightmostEv_ZN7testing8internal12UnitTestImpl21set_current_test_infoEPNS_8TestInfoE_ZN9__gnu_cxx17__normal_iteratorIPKN7testing8internal9TraceInfoESt6vectorIS3_SaIS3_EEEmIEiswprintftype__ZNKSs5rfindERKSsj__uninit_copy<__gnu_cxx::__normal_iterator*, std::vector > >, std::basic_string*>si_codebasic_stringstreamsockfd__ZNKSt3setISsSt4lessISsESaISsEE11upper_boundERKSs_ZNKSt9_IdentityISsEclERKSsmbsinit_ZNKSt6vectorIiSaIiEE8max_sizeEv~ExecDeathTest_ZNSt6vectorIPN7testing11EnvironmentESaIS2_EEixEj__numeric_traits_integerfrac_digits_ZN7testing22EmptyTestEventListener22OnEnvironmentsSetUpEndERKNS_8UnitTestEoperator<< last_errorfailbitUniversalPrint >_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE5eraseESt17_Rb_tree_iteratorISsEuninitialized_copybreak_on_failure__ZNK7testing8internal10scoped_ptrIKSsEdeEv_ZNSbIwSt11char_traitsIwESaIwEEpLEPKwTestEventListenerswap*>expected_expressiondata_internal_run_death_test__rhsactual_ZNKSt17_Rb_tree_iteratorIPKcEdeEv_ZNSt6vectorIPN7testing8TestCaseESaIS2_EE4rendEv_ZNK7testing8internal8FilePath21FileOrDirectoryExistsEv11__mbstate_tIsPathSeparator_ZNSt12_Vector_baseIPN7testing11EnvironmentESaIS2_EE13_M_deallocateEPS2_j_ZN7testing8internal17StreamingListener12SocketWriterD0Ev_ZN9__gnu_cxx17__normal_iteratorIPKPN7testing17TestEventListenerESt6vectorIS3_SaIS3_EEEmmEv_ZNSt6vectorIN7testing12TestPropertyESaIS1_EE15_M_erase_at_endEPS1_si_errno_ZN7testing8internal12UnitTestImpl21set_current_test_caseEPNS_8TestCaseE_ZNK7testing8internal10scoped_ptrIKSsE3getEv_ZN7testing8internal13DeathTestImpl11set_spawnedEbpair_ZN7testing19TestPartResultArrayaSERKS0_impl__normal_iterator, std::allocator > >vector >_ZNKSt12_Vector_baseIN7testing12TestPropertyESaIS1_EE13get_allocatorEvcopy_backward*, std::basic_string*>_ZNSt6vectorISsSaISsEE8_M_eraseEN9__gnu_cxx17__normal_iteratorIPSsS1_EES5_should_run__ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE15_M_insert_equalERKS1_FloatingPointLE_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE6_S_keyEPKSt13_Rb_tree_nodeISsETypeIdfor_each<__gnu_cxx::__normal_iterator >, void (*)(testing::Environment*)>_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE12_M_erase_auxESt23_Rb_tree_const_iteratorIS1_ES9_StrError_Destroy_ZNKSbIwSt11char_traitsIwESaIwEE13get_allocatorEv_M_insert_lower_ZNSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE8pop_backEv~StreamingListeneroperator- >_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE16_M_insert_uniqueERKSsTEST_ENCOUNTERED_RETURN_STATEMENT_ZNK9__gnu_cxx17__normal_iteratorIPPN7testing8internal29ParameterizedTestCaseInfoBaseESt6vectorIS4_SaIS4_EEE4baseEv_ZN7testing4Test14RecordPropertyERKSsiiterator_traits<__gnu_cxx::__normal_iterator, std::allocator >*, std::vector, std::allocator >, std::allocator, std::allocator > > > > >_ZN9__gnu_cxx14__alloc_traitsISaIN7testing8internal9TraceInfoEEE10_S_on_swapERS4_S6__ZNSt11char_traitsIwE11eq_int_typeERKjS2___cxa_begin_catchsrc_texterror_message_ZNKSt6vectorIPN7testing11EnvironmentESaIS2_EE5beginEvoperator delete_ZNKSt12_Vector_baseIPcSaIS0_EE13get_allocatorEv_ZNSt6vectorIPcSaIS0_EE4dataEv_Allocator_ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EE2atEjoriginal_reporter__ZN9__gnu_cxx13new_allocatorISsE10deallocateEPSsj_ZN7testing8internal23kTestTypeIdInGoogleTestE_ZN9__gnu_cxx13new_allocatorIPKcE7destroyEPS2_operator<< , std::allocator >file__ZN7testing8TestCaseaSERKS0_AssertHeld_ZNKSt6vectorIPN7testing8TestCaseESaIS2_EE4dataEv_ZNK9__gnu_cxx17__normal_iteratorIPcSsE4baseEv_ZN7testing8internal17TestEventRepeaterD2Ev_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE7_S_leftEPKSt18_Rb_tree_node_basereverse_iterator<__gnu_cxx::__normal_iterator, std::allocator > > >TestPartResultTypeToString_ZN9__gnu_cxx14__alloc_traitsISaIPN7testing17TestEventListenerEEE8max_sizeERKS4__ZN7testing8UnitTest14AddEnvironmentEPNS_11EnvironmentE_ZNSs7reserveEj_ZNSt12_Vector_baseIPcSaIS0_EE17_M_create_storageEj_Iter_equals_val, std::allocator > >InitGoogleTestRETURNED_ZNKSt12_Vector_baseIiSaIiEE13get_allocatorEvregistered_testsoperator booluser_msg_string_ZN7testing8internal13ExecDeathTestD0EvAbstractSocketWriter__ino_toriginal_working_dir_iterator_traits, std::allocator >*>_ZN7testing8internal12UnitTestImpl31GetGlobalTestPartResultReporterEvregex_ZNK7testing8internal12UnitTestImpl21successful_test_countEv_ZNK9__gnu_cxx17__normal_iteratorIPKcSsEplEinormalized_seed_ZN7testing14TestPartResult14ExtractSummaryEPKcStackLowerThanAddress_ZNK9__gnu_cxx17__normal_iteratorIPPN7testing8TestCaseESt6vectorIS3_SaIS3_EEEmiEitest_propertiesmove_ZNK9__gnu_cxx13new_allocatorIPN7testing17TestEventListenerEE7addressERS3__CharToperator<< _ZN7testing14ExitedWithCodeC2Eiunsigned int_ZN7testing8internal12UnitTestImpl34InitDeathTestSubprocessControlInfoEvignoring_casePrintTowcstold_ZNSt12_Vector_baseIPN7testing17TestEventListenerESaIS2_EE17_M_create_storageEj_ZNSt10_Iter_baseIN9__gnu_cxx17__normal_iteratorIPPN7testing17TestEventListenerESt6vectorIS4_SaIS4_EEEELb0EE7_S_baseES9__ZN9__gnu_cxx14__alloc_traitsISaIiEE17_S_select_on_copyERKS1_copy_backward_ZNSbIwSt11char_traitsIwESaIwEE6appendEPKwj_ZNKSbIwSt11char_traitsIwESaIwEE16find_last_not_ofEPKwjj_ZN9__gnu_cxx14__alloc_traitsISaIPN7testing11EnvironmentEEE8max_sizeERKS4__ZN9__gnu_cxx17__normal_iteratorIPKcSsEmIEiClearTestResult_ZNKSs11_M_disjunctEPKc_vptr.UnitTestdestinternal_run_death_test_flag_size_t_ZN7testing8internal17StreamingListener12SocketWriter15CloseConnectionEv_M_destroy_noderegoff_tparameterlower_bound_ZNSt6vectorIPcSaIS0_EE8pop_backEv_ZNK7testing8internal12UnitTestImpl11random_seedEv_ZNK7testing8internal13DeathTestImpl6statusEvlast_sep_ZN7testing8internal16UniversalPrinterISsE5PrintERKSsPSopthread_mutex_tad_hoc_test_result_bool_ZN7testing8internal15CodePointToUtf8Ejunicode_code_pointcomma__distanceFloatingPoint_ZNKSbIwSt11char_traitsIwESaIwEE16find_last_not_ofEPKwjFormatForComparisonFailureMessage_ZNK7testing14TestPartResult14fatally_failedEvString_Category~TestFactoryBasekUniversalFilter__builtin_fwrite_ZN7testing8internal13GetTestTypeIdEv_ZNSs4_Rep7_M_grabERKSaIcES2__M_copyreverse_iterator<__gnu_cxx::__normal_iterator, std::allocator >*, std::vector, std::allocator >, std::allocator, std::allocator > > > > >argvs_ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EE6insertEN9__gnu_cxx17__normal_iteratorIPS2_S4_EEjRKS2___cxa_throw_ZN9__gnu_cxx13new_allocatorIwE8allocateEjPKv_ZNSbIwSt11char_traitsIwESaIwEE6assignERKS2_summary_rdstatekStackTraceDepthFlagfreadTestPartResultArraythread_count__copy_move_b*, std::basic_string*>operator!= >_S_blackos_stack_trace_getter_ZNSo9_M_insertIPKvEERSoT___cxa_guard_abort_ZN7testing8internal12UnitTestImpl12ShuffleTestsEv_sigfaultGTEST_SHARD_INDEXMSG_CONFIRM__is_normal_iterator_ZNSt6vectorIiSaIiEEixEjTearDownTestCaseFunc__miter_basekThresholdint_n_cs_precedesbinary_function, std::allocator >, std::basic_string, std::allocator >, bool>_ZN7testing8internal35HandleExceptionsInMethodIfSupportedINS_8TestCaseEvEET0_PT_MS4_FS3_vEPKc_M_key_compareallocator_ZN7testing15AssertionResultlsIA3_cEERS0_RKT_~ForkingDeathTest_ZNKSt6vectorISsSaISsEE6rbeginEvatexitreverse_iterator<__gnu_cxx::__normal_iterator > > >kReservedTestSuiteAttributesDeathTestImpl_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE15_M_destroy_nodeEPSt13_Rb_tree_nodeIS1_E_ZN7testing7MessageC2Evfwrite_ZNKSs13find_first_ofEcj_ZN9__gnu_cxx17__normal_iteratorIPKSsSt6vectorISsSaISsEEEmmEisi_addr_lsb_ZNKSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE14_M_range_checkEj_ZN9__gnu_cxx17__normal_iteratorIPKPN7testing8TestInfoESt6vectorIS3_SaIS3_EEEmIEi_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE16_M_insert_equal_ESt23_Rb_tree_const_iteratorIS1_ERKS1__ZNSt6vectorIiSaIiEE5beginEv_ZN9__gnu_cxx17__normal_iteratorIPKSsSt6vectorISsSaISsEEEmmEv_Valcurrent_test_info_operator<< GTEST_ERRORforwarding_enabledsiginfo_t_ZN7testing8internal29ParameterizedTestCaseInfoBaseaSERKS1_kColorEncodedHelpMessage_ZNSt6vectorIN7testing14TestPartResultESaIS1_EE5eraseEN9__gnu_cxx17__normal_iteratorIPS1_S3_EE_ZNSbIwSt11char_traitsIwESaIwEE6assignERKS2_jjstringstream_Key_ZNSt6vectorIN7testing12TestPropertyESaIS1_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS1_S3_EERKS1__ZNSbIwSt11char_traitsIwESaIwEE4_Rep7_M_grabERKS1_S5_~SingleFailureChecker_ZNK7testing8UnitTest22test_case_to_run_countEvpop_backrend_ZNKSbIwSt11char_traitsIwESaIwEE17find_first_not_ofEPKwjsuccessful_test_count_ZNKSs5rfindEPKcjjname_ZN9__gnu_cxx17__normal_iteratorIPKPN7testing17TestEventListenerESt6vectorIS3_SaIS3_EEEpLEioutput_format_ZN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE11ValueHolderaSERKS5_rebind~ScopedPrematureExitFileoperator<< _ZN7testing8internal2RE9FullMatchEPKcRKS1_MSG_RSTOnTestPartResult_ZN7testing4Test15HasFatalFailureEv__cxa_atexit_ZN7testing8internal17PrintWideStringToERKSbIwSt11char_traitsIwESaIwEEPSocur_addr_ZN7testing8internal12UnitTestImpl27parameterized_test_registryEv_ZNKSs5beginEv_ZNK7testing8internal13DeathTestImpl7outcomeEv__cxa_guard_acquirefind_first_ofn_cs_precedes__normal_iterator, std::allocator >*, std::vector, std::allocator >, std::allocator, std::allocator > > > >_ZNSt6vectorIN7testing14TestPartResultESaIS1_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS1_S3_EERKS1_output_ZN7testing8internal27PrettyUnitTestResultPrinterD2EvGetTestPartResult_ZNSbIwSt11char_traitsIwESaIwEE6insertEjRKS2_jjoutput_GetPrefixUntilComma_ZN7testing8internal24XmlUnitTestResultPrinter24IsNormalizableWhitespaceEcLock_ZNSt6vectorIN7testing14TestPartResultESaIS1_EE6rbeginEvCOLOR_GREENoperator<< _ZN7testing8internal16ForkingDeathTestC2EPKcPKNS0_2REEline_num_S_right_ZN9__gnu_cxx13new_allocatorISt13_Rb_tree_nodeISsEE8allocateEjPKvMakeFrom_S_empty_rep_ZSt29_Rb_tree_insert_and_rebalancebPSt18_Rb_tree_node_baseS0_RS__Znwj_ZN9__gnu_cxx17__normal_iteratorIPPN7testing11EnvironmentESt6vectorIS3_SaIS3_EEEpLEi__is_null_pointermethod_ZNSs6insertEN9__gnu_cxx17__normal_iteratorIPcSsEEjc_ZNK9__gnu_cxx13new_allocatorIPcE7addressERKS1__ZNKSs7compareEjjRKSsset_current_test_case_ZNSt12_Vector_baseIPN7testing17TestEventListenerESaIS2_EE13_M_deallocateEPS2_j_ZN7testing7MessagelsEPw__iterator_category__is_normal_iterator_ZN7testing8internal10scoped_ptrINS0_24InternalRunDeathTestFlagEE5resetEPS2_iterator_traitsallocatorUniversalPrintCharArray_ZN9__gnu_cxx13new_allocatorIPcE9constructEPS1_RKS1___alloc_traits >operator!= >__destroy__elems_beforevalue_compare_ZNSt11char_traitsIwE2eqERKwS2__ZNKSt6vectorIPN7testing8TestCaseESaIS2_EE8capacityEv9siginfo_t~TestEventRepeater_ZN7testing10TestResultaSERKS0__ZNKSt6vectorIN7testing12TestPropertyESaIS1_EE4dataEv_ZNK7testing8TestCase17test_to_run_countEvseekdirGetCurrentExecutableNametest_case_name__Destroy*, std::basic_string >operator- >_vptr.UnitTestImpl_ZN9__gnu_cxx17__normal_iteratorIPKcSsEpLEi_ZNKSt18basic_stringstreamIcSt11char_traitsIcESaIcEE3strEvexpression_textOnTestCaseEndbytes_readtm_hour_ZNSt6vectorISsSaISsEE8_M_eraseEN9__gnu_cxx17__normal_iteratorIPSsS1_EESignAndMagnitudeToBiasedoperator<< __trip_countreportable_test_count_M_insert_ZNSt3setISsSt4lessISsESaISsEE4findERKSs_ZNSbIwSt11char_traitsIwESaIwEE7replaceEN9__gnu_cxx17__normal_iteratorIPwS2_EES6_jw_ZNK7testing8internal29ParameterizedTestCaseInfoBase17GetTestCaseTypeIdEvCaptureStdout_ZNSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE6insertEN9__gnu_cxx17__normal_iteratorIPS3_S5_EERKS3__ZNSt6vectorIPN7testing11EnvironmentESaIS2_EE8_M_eraseEN9__gnu_cxx17__normal_iteratorIPS2_S4_EE_ZNSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS3_S5_EERKS3___addressof >_ZNKSt3setISsSt4lessISsESaISsEE4findERKSsunknown fileExecDeathTestArgs_ZNKSt6vectorIPN7testing8TestCaseESaIS2_EE8max_sizeEv__gthread_active_ptrkExponentBitCountstatus_ok_ZNK7testing8internal13FloatingPointIdE13exponent_bitsEv_ZNKSbIwSt11char_traitsIwESaIwEE13find_first_ofEPKwj_ZNKSt6vectorIPcSaIS0_EE5frontEv_S_out_ZN7testing8internal24XmlUnitTestResultPrinter18EscapeXmlAttributeERKSs_Destroystrrchr_ZN9__gnu_cxx13new_allocatorIPN7testing8TestInfoEE9constructEPS3_RKS3__ZN7testing8internal12UnitTestImpl11RunAllTestsEv_ZNSt6vectorIPN7testing8TestInfoESaIS2_EE4swapERS4__ZN7testing8internal9DeathTest4WaitEv_ZN9__gnu_cxx17__normal_iteratorIPSsSt6vectorISsSaISsEEEmmEi_HasBase_ZN7testing18TestEventListenersD2Ev_ZNSt6vectorIPN7testing8TestCaseESaIS2_EE9push_backERKS2__vptr.AbstractSocketWriter_ZN9__gnu_cxx17__normal_iteratorIPSsSt6vectorISsSaISsEEEmmEv_ZNK7testing8internal8FilePath5c_strEvdo_widen_ZNKSt6vectorIPN7testing8TestCaseESaIS2_EE4rendEv_ZN7testing8internal12UnitTestImpl31SetGlobalTestPartResultReporterEPNS_31TestPartResultReporterInterfaceE_ZNK7testing19TestPartResultArray4sizeEv_ZNK7testing8TestCase6PassedEvPopGTestTracesign_bitrebind_ZNSt12_Vector_baseIN7testing8internal9TraceInfoESaIS2_EE13_M_deallocateEPS2_jDeathTest_ZNKSt6vectorISsSaISsEE4rendEv_ZNK7testing15AssertionResult7messageEv_ZNK7testing8internal17TestEventRepeater18forwarding_enabledEva_value_paramoperator!__iterator_categoryfputcoperator&operator*operator+iterator_traitsoperator-_ZNSt12_Vector_baseIPN7testing11EnvironmentESaIS2_EE11_M_allocateEjfputs_ZStplIcSt11char_traitsIcESaIcEESbIT_T0_T1_ERKS6_S8_operator<operator=operator>FormatForComparison_ZNSs9_M_mutateEjjj_ZN7testing17TestEventListener24OnEnvironmentsSetUpStartERKNS_8UnitTestE_ZNKSt3setISsSt4lessISsESaISsEE5beginEv_ZN7testing8internal6Random6ReseedEj_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE17_M_insert_unique_ESt23_Rb_tree_const_iteratorIS1_ERKS1_rebindSOCK_RAW_ZNSt6vectorIPN7testing8TestCaseESaIS2_EE6insertEN9__gnu_cxx17__normal_iteratorIPS2_S4_EERKS2__ZN7testing8internal7PrintToEhPSo_ZNSs12_S_constructIPcEES0_T_S1_RKSaIcEis_selectedsystemwcsrtombsTestProperty_ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EEixEj__valFailFromInternalError_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE14_M_lower_boundEPSt13_Rb_tree_nodeIS1_ESA_RKS1__timer_ZN7testing10TestResult17AddTestPartResultERKNS_14TestPartResultEquot_ZNSt6vectorISsSaISsEE6rbeginEv_ZNKSt6vectorIPN7testing11EnvironmentESaIS2_EE6rbeginEvthrow_on_failure_operator|operator~atof_ZNSt9basic_iosIcSt11char_traitsIcEE5clearESt12_Ios_Iostate_ZN9__gnu_cxx17__normal_iteratorIPKPN7testing8TestCaseESt6vectorIS3_SaIS3_EEEmIEiatoiatol_ZNKSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE6rbeginEv_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE3endEvPrintToStringconstruct_ZN7testing4Test13SetUpTestCaseEv_ZN7testing8internal17TestEventRepeateraSERKS1__ZNSt3setISsSt4lessISsESaISsEE5eraseESt23_Rb_tree_const_iteratorISsEgoodbitwcstombswrite_Rb_tree_iterator_ZN7testing8internal26ThreadLocalValueHolderBaseaSERKS1__Znaj_ZN9__gnu_cxx17__normal_iteratorIPKSsSt6vectorISsSaISsEEEpLEi__k2_M_eraseCreateDirectoriesRecursively_ZNSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE5eraseEN9__gnu_cxx17__normal_iteratorIPS3_S5_EES9_exit_status_ZNSt6vectorIiSaIiEE5eraseEN9__gnu_cxx17__normal_iteratorIPiS1_EEfull_pattern_S_hexowner__sigpoll_ZNKSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE6_M_endEvint_p_sep_by_spacekMaxRangeGetStringFunctor_ZN7testing8internal12AssertHelper16AssertHelperDataaSERKS2__Rb_tree_const_iterator, std::allocator > >_ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EE15_M_erase_at_endEPS2_IsAbsolutePathfailed_test_case_count_ZNKSt6vectorIPN7testing8TestCaseESaIS2_EE5frontEv_ZNSs4_Rep10_M_disposeERKSaIcEfputwc_Iterator_Iter_base_M_clone_nodeParseStringFlagFilterMatchesTestfputwsMakeConnection~basic_stringCmpHelperSTRCASEEQiterator_traits<__gnu_cxx::__normal_iterator > > >index_ZNK7testing8TestInfo6resultEv_ZNKSs12find_last_ofERKSsj_ZN7testing8UnitTestC2Ev_ZNK9__gnu_cxx17__normal_iteratorIPPN7testing8TestInfoESt6vectorIS3_SaIS3_EEEptEv_ZNSt6vectorIiSaIiEEaSERKS1_fcntl_ZNK7testing8internal17TestPropertyKeyIsclERKNS_12TestPropertyE~DeathTestImpl_ZN7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEE11ValueHolderaSERKS7__ZN7testing8internal13FloatingPointIfE8InfinityEv_S_ios_openmode_end_ZN7testing8TestCaseD2EvGTestFlagSaverGetOutputFormat_ZN9__gnu_cxx13new_allocatorIcE10deallocateEPcj_ZN7testing8internal18SetInjectableArgvsEPKSt6vectorISsSaISsEErandom_ZN9__gnu_cxx14__alloc_traitsISaISsEE8max_sizeERKS1__ZNKSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE11upper_boundERKSs_ZNKSt6vectorIPN7testing17TestEventListenerESaIS2_EE2atEjstrtold_ZNK9__gnu_cxx17__normal_iteratorIPKN7testing8internal9TraceInfoESt6vectorIS3_SaIS3_EEEdeEvoperator<< suffix_len_ZNSt6vectorIPcSaIS0_EE5frontEvportset_up_tc__maskTestPassed_M_destroyMSG_MOREnew_holder_ZN9__gnu_cxx14__alloc_traitsISaIN7testing14TestPartResultEEE10_S_on_swapERS3_S5__ZNKSt6vectorIN7testing14TestPartResultESaIS1_EE2atEj_M_fill_assign_ZNSt3setIPKcSt4lessIS1_ESaIS1_EE4findERKS1_operator<< _ZN7testing8internal24ParseGoogleTestFlagsOnlyEPiPPwoperator<< _ZNKSs7_M_iendEv_ZN7testing8internal11ScopedTraceD2Evresume_pos_ZNK7testing8internal12UnitTestImpl18ad_hoc_test_resultEvtm_yday_ZNSt6vectorIPN7testing8TestInfoESaIS2_EE14_M_fill_assignEjRKS2__ZNSt8ios_base4setfESt13_Ios_FmtflagsS0_putwcharftell__miter_base<__gnu_cxx::__normal_iterator > >SOCK_STREAM_ZSt16__ostream_insertIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_PKS3_icomparestream_result_to__ZNSt6vectorIPN7testing11EnvironmentESaIS2_EE7reserveEj_ZN7testing8internal12AssertHelperaSERKS1_ExecDeathTestSpawnChild__blksize_t_ZNKSbIwSt11char_traitsIwESaIwEE12find_last_ofEPKwjj_M_upper_bound_ZNK9__gnu_cxx17__normal_iteratorIPPcSt6vectorIS1_SaIS1_EEEixEiPrintCharAndCodeTo_ZN7testing14TestPartResultD2EvAddEnvironment_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE10_S_maximumEPKSt18_Rb_tree_node_basepthread_mutex_unlock_ZNKSt6vectorIPcSaIS0_EE3endEvint_curr_symbolset_write_fd~GTestLog_ZN7testing8UnitTest14PushGTestTraceERKNS_8internal9TraceInfoEnum_runnable_tests_ZNK9__gnu_cxx17__normal_iteratorIPKN7testing8internal9TraceInfoESt6vectorIS3_SaIS3_EEEixEi_ZNSbIwSt11char_traitsIwESaIwEE6insertEjRKS2__ZNKSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE5beginEv_ZN7testing8internal12AssertHelperD2Ev_ZNK9__gnu_cxx13new_allocatorIcE7addressERKcpthread_key_create_TrivialValueTypesfind_if<__gnu_cxx::__normal_iterator >, testing::internal::TestCaseNameIs>translate_ZNSt6vectorIPN7testing8TestCaseESaIS2_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS2_S4_EERKS2_wcstoul__is_normal_iteratorsa_data_ZNSt6vectorIPN7testing8TestInfoESaIS2_EE6insertEN9__gnu_cxx17__normal_iteratorIPS2_S4_EERKS2_index___mode_t_ZN7testing8internal18InitGoogleTestImplIcEEvPiPPT___cxa_bad_typeid_DestroyFLAGS_gtest_repeat__n1pair, std::_Rb_tree_const_iterator >_ZNSs13_S_copy_charsEPcN9__gnu_cxx17__normal_iteratorIPKcSsEES4_read_fd_ZN9__gnu_cxx17__normal_iteratorIPSsSt6vectorISsSaISsEEEpLEi_Destroysrc/gtest-all.cc~basic_stringbufFormatFileLocation_ZNSt6vectorIPcSaIS0_EE8_M_eraseEN9__gnu_cxx17__normal_iteratorIPS0_S2_EE_M_insert_equalconst_reverse_iteratorwchar_t_ZN9__gnu_cxx14__alloc_traitsISaIPN7testing11EnvironmentEEE7destroyERS4_PS3__ZNKSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE6rbeginEv_ZNK7testing7Message9GetStringEv_markers__assignable__copy_move_backwardOnEnvironmentsSetUpStart_ZN9__gnu_cxx14__alloc_traitsISaIPN7testing8internal29ParameterizedTestCaseInfoBaseEEE17_S_select_on_copyERKS5___alloc_traits >_ZN7testing8internal10scoped_ptrINS0_24InternalRunDeathTestFlagEEaSERKS3_iostatea_write_fd__pad1__pad2__pad3__copy_move_a__pad5a_filefieldssi_overrun_ZNK7testing8internal8FilePath28CreateDirectoriesRecursivelyEvRecordProperty_ZNK7testing8internal13DeathTestImpl7read_fdEv_M_get_Tp_allocatorgetwchar__destroy*>_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE7_M_rootEv_ZN9__gnu_cxx17__normal_iteratorIPPN7testing8internal29ParameterizedTestCaseInfoBaseESt6vectorIS4_SaIS4_EEEmIEi_ZNKSt6vectorIPN7testing17TestEventListenerESaIS2_EE4dataEv_ZNKSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE4rendEv_ZNKSt17_Rb_tree_iteratorIPKcEneERKS2_current_test_case_ZNKSt6vectorIN7testing12TestPropertyESaIS1_EE2atEj_ZN9__gnu_cxx3divExxkSizestdout_is_ttycopy_backward_ZNK9__gnu_cxx17__normal_iteratorIPKPN7testing17TestEventListenerESt6vectorIS3_SaIS3_EEEplEi_ZNK9__gnu_cxx17__normal_iteratorIPKPN7testing11EnvironmentESt6vectorIS3_SaIS3_EEE4baseEv_ZN7testing8internal24XmlUnitTestResultPrinter17OutputXmlTestInfoEPSoPKcRKNS_8TestInfoE_ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EE9push_backERKS2__ZNSt6vectorIN7testing14TestPartResultESaIS1_EE14_M_fill_insertEN9__gnu_cxx17__normal_iteratorIPS1_S3_EEjRKS1__ZNK7testing8UnitTest18ad_hoc_test_resultEvtotal_test_case_count_ZNKSt16reverse_iteratorIN9__gnu_cxx17__normal_iteratorIPPN7testing11EnvironmentESt6vectorIS4_SaIS4_EEEEEplEioperator<< __copy_move_backward_aoperator<< _ZN9__gnu_cxx13new_allocatorIN7testing14TestPartResultEE10deallocateEPS2_jcur_pattern_ZN7testing4TestaSERKS0__ZNSt6vectorIPN7testing8TestInfoESaIS2_EE2atEj_ZN7testing15AssertionResult13AppendMessageERKNS_7MessageEIsSubstringImpl >__copy_move_a2_ZN7testing32ScopedFakeTestPartResultReporter20ReportTestPartResultERKNS_14TestPartResultEMSG_DONTWAITiterator_traits_ZNSt3setIPKcSt4lessIS1_ESaIS1_EE11lower_boundERKS1__ZNSt13_Rb_tree_nodeISsE9_M_valptrEvkElidedFramesMarkerset_read_fdParseInternalRunDeathTestFlagstatus__ZN7testing8internal19TypedTestCasePState25VerifyRegisteredTestNamesEPKciS3__ZNSt6vectorIPcSaIS0_EE14_M_fill_insertEN9__gnu_cxx17__normal_iteratorIPS0_S2_EEjRKS0__ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE12_M_erase_auxESt23_Rb_tree_const_iteratorISsES7_GetMutableTestCase*DeathTest:*DeathTest/*_ZNKSs16find_last_not_ofEPKcj__osRelease_ZNK9__gnu_cxx17__normal_iteratorIPKcSsEmiEi_IO_write_base__distance_ZNSt3setISsSt4lessISsESaISsEE11upper_boundERKSs_ZNK9__gnu_cxx17__normal_iteratorIPPN7testing8TestCaseESt6vectorIS3_SaIS3_EEEptEvUniversalPrinter, std::allocator > >GoogleTestFailureException_ZN7testing8TestCase14UnshuffleTestsEvreason_ZN7testing8internal23GetLastErrnoDescriptionEv__miter_base__builtin_memcmp_ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EE6rbeginEvfront_ZN7testing8internal7PrintToEPKwPSowmemsetsetfillkTestcase_ZNKSt6vectorIN7testing8internal9TraceInfoESaIS2_EEixEj__copy_move_backward_a2FormatCompilerIndependentFileLocationpush_backtotal_shards_envsubstr_ZNKSt6vectorIN7testing14TestPartResultESaIS1_EE6rbeginEv_ZN9__gnu_cxx14__alloc_traitsISaIPKcEE17_S_select_on_copyERKS3__ZNKSt6vectorIN7testing14TestPartResultESaIS1_EEixEjincrement_death_test_count_ZNKSt6vectorIiSaIiEE5beginEv_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE13_Rb_tree_implIS5_Lb0EE13_M_initializeEv_ZN9__gnu_cxx14__alloc_traitsISaISt13_Rb_tree_nodeISsEEE10deallocateERS3_PS2_jst_ino_ZNKSt6vectorIiSaIiEE3endEvxml_element_S_terminal_ZNK9__gnu_cxx13new_allocatorISt13_Rb_tree_nodeIPKcEE7addressERS4_OsStackTraceGetter_Compare_ZN7testing8internal17StreamingListener16OnTestProgramEndERKNS_8UnitTestEstrtouliterator_traits_ZNKSs4findEPKcjmbstate_t_ZN7testing17TestEventListener9OnTestEndERKNS_8TestInfoEPrintToString_ZN9__gnu_cxx14__alloc_traitsISaIPN7testing11EnvironmentEEE8allocateERS4_jlast_death_test_message_~_Rb_treeStrCaseCmp_ZN7testing8internal35DefaultGlobalTestPartResultReporterC2EPNS0_12UnitTestImplETHREWPrintTestNameis_valid__ZN7testing8internal35DefaultGlobalTestPartResultReporterD0EvMSG_TRUNC_ZN7testing8internal13DeathTestImpl5AbortENS0_9DeathTest11AbortReasonEDefaultPrintTodelimiterIsDigit_ZNSt11char_traitsIcE7not_eofERKi__it__destroy_ZN7testing8internal15FloatingPointLEIdEENS_15AssertionResultEPKcS4_T_S5__ZNKSs12find_last_ofEPKcjj__u_quad_t_ZN9__gnu_cxx17__normal_iteratorIPPN7testing8TestInfoESt6vectorIS3_SaIS3_EEEppEiputwcTestPartResult__normal_iterator > >shuffle__ZN9__gnu_cxx17__normal_iteratorIPPN7testing8TestInfoESt6vectorIS3_SaIS3_EEEppEv_Vector_base >_M_is_leaked_ZN7testing8internal17StreamingListeneraSERKS1__ZNSt6vectorIPN7testing11EnvironmentESaIS2_EE6assignEjRKS2__ZNSbIwSt11char_traitsIwESaIwEE7replaceEjjPKwj_ZN7testing8internal20ShouldRunTestOnShardEiii_ZNK7testing8internal10scoped_ptrISsEptEvPrint_ZNKSbIwSt11char_traitsIwESaIwEE5rfindEPKwj_ZN9__gnu_cxx17__normal_iteratorIPPN7testing8TestCaseESt6vectorIS3_SaIS3_EEEppEioperator-*, std::vector > >__uninit_copyoperator<< reserved_names_SelfStart_ZNK9__gnu_cxx13new_allocatorISsE7addressERKSsThis program contains tests written using Google Test. You can use the following command line flags to control its behavior: Test Selection: @G--gtest_list_tests@D List the names of all tests instead of running them. The name of TEST(Foo, Bar) is "Foo.Bar". @G--gtest_filter=@YPOSTIVE_PATTERNS[@G-@YNEGATIVE_PATTERNS]@D Run only the tests whose name matches one of the positive patterns but none of the negative patterns. '?' matches any single character; '*' matches any substring; ':' separates two patterns. @G--gtest_also_run_disabled_tests@D Run all disabled tests too. Test Execution: @G--gtest_repeat=@Y[COUNT]@D Run the tests repeatedly; use a negative count to repeat forever. @G--gtest_shuffle@D Randomize tests' orders on every iteration. @G--gtest_random_seed=@Y[NUMBER]@D Random number seed to use for shuffling test orders (between 1 and 99999, or 0 to use a seed based on the current time). Test Output: @G--gtest_color=@Y(@Gyes@Y|@Gno@Y|@Gauto@Y)@D Enable/disable colored output. The default is @Gauto@D. -@G-gtest_print_time=0@D Don't print the elapsed time of each test. @G--gtest_output=xml@Y[@G:@YDIRECTORY_PATH@G/@Y|@G:@YFILE_PATH]@D Generate an XML report in the given directory or with the given file name. @YFILE_PATH@D defaults to @Gtest_details.xml@D. @G--gtest_stream_result_to=@YHOST@G:@YPORT@D Stream test results to the given server. Assertion Behavior: @G--gtest_death_test_style=@Y(@Gfast@Y|@Gthreadsafe@Y)@D Set the default death test style. @G--gtest_break_on_failure@D Turn assertion failures into debugger break-points. @G--gtest_throw_on_failure@D Turn assertion failures into C++ exceptions. @G--gtest_catch_exceptions=0@D Do not report exceptions as test failures. Instead, allow them to crash the program or throw a pop-up (on Windows). Except for @G--gtest_list_tests@D, you can alternatively set the corresponding environment variable of a flag (all letters in upper-case). For example, to disable colored text output, you can either specify @G--gtest_color=no@D or set the @GGTEST_COLOR@D environment variable to @Gno@D. For more information, please read the Google Test documentation at @Ghttp://code.google.com/p/googletest/@D. If you find a bug in Google Test (not one in your own code or tests), please report it to @G@D. BoolFromGTestEnv_ZNSt6vectorIPcSaIS0_EE15_M_erase_at_endEPS0__ZNKSbIwSt11char_traitsIwESaIwEE17find_first_not_ofEwjInteger__find_if<__gnu_cxx::__normal_iterator >, __gnu_cxx::__ops::_Iter_pred >strcasecmpst_ctim_ZNSt6vectorIN7testing12TestPropertyESaIS1_EE6assignEjRKS1__ZNSt6vectorIPN7testing8TestCaseESaIS2_EE4dataEvtuple_size >_ZNKSt6vectorIPcSaIS0_EE4backEv_Vector_base >_ZNKSt6vectorIN7testing14TestPartResultESaIS1_EE8capacityEv_M_leak_hardprefix_len_ZNKSs13find_first_ofERKSsj_ZN7testing8internal15FloatingPointLEIfEENS_15AssertionResultEPKcS4_T_S5__ZN7testing4Test5SetupEvGTestLogSeverity_ZN9__gnu_cxx14__alloc_traitsISaIN7testing12TestPropertyEEE17_S_select_on_copyERKS3__ZNSt6vectorIN7testing12TestPropertyESaIS1_EE14_M_fill_insertEN9__gnu_cxx17__normal_iteratorIPS1_S3_EEjRKS1__ZSt9__find_ifIN9__gnu_cxx17__normal_iteratorIPPN7testing8TestCaseESt6vectorIS4_SaIS4_EEEENS0_5__ops10_Iter_predINS2_8internal14TestCaseNameIsEEEET_SF_SF_T0_St26random_access_iterator_tag_vptr.TestCase_ZNK7testing8UnitTest21total_test_case_countEv_ZNKSt9_IdentityIPKcEclERKS1__ZNSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE8_M_eraseEN9__gnu_cxx17__normal_iteratorIPS3_S5_EES9__ZNSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE7reserveEj_ZN9__gnu_cxx17__normal_iteratorIPPN7testing17TestEventListenerESt6vectorIS3_SaIS3_EEEppEv_ZN9__gnu_cxx17__normal_iteratorIPcSsEppEitoupper_vptr.ThreadLocalValueHolderBase_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE12_M_rightmostEv Stack trace: _ZN9__gnu_cxx17__normal_iteratorIPcSsEppEv__normal_iterator, std::allocator > >_ZNK9__gnu_cxx17__normal_iteratorIPiSt6vectorIiSaIiEEEixEi__datCodePointToUtf8_ZNSbIwSt11char_traitsIwESaIwEE4_Rep26_M_set_length_and_sharableEj_ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EE14_M_fill_assignEjRKS2_test_namenot_bol_ZNSs3endEv_ZN9__gnu_cxx17__normal_iteratorIPKPN7testing17TestEventListenerESt6vectorIS3_SaIS3_EEEmIEi_ZNKSt6vectorIN7testing14TestPartResultESaIS1_EE8max_sizeEv_ZN7testing8internal12UnitTestImplD0EvIsRootDirectorymemcpyFloatingPointLE_ZN7testing8internal6RandomaSERKS1__ZN7testing8internal21ImplicitlyConvertibleIPKvS3_E6HelperEz_ZNKSt6vectorIN7testing12TestPropertyESaIS1_EE14_M_range_checkEj_ZNSbIwSt11char_traitsIwESaIwEE4_Rep15_M_set_sharableEvFlushInfoLog_ZN7testing15AssertionResultlsIA12_cEERS0_RKT___s1construct_ZNSt3setISsSt4lessISsESaISsEE6insertESt23_Rb_tree_const_iteratorISsERKSsreverse_iterator<__gnu_cxx::__normal_iterator > > >_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE5eraseERKSsHasFailurewcsncpy_ZNKSt6vectorIN7testing12TestPropertyESaIS1_EE3endEv_ZN7testing8internal28ParseGoogleTestFlagsOnlyImplIcEEvPiPPT_back_ZNK7testing10TestResult6PassedEvcopy_ZN7testing8internal12UnitTestImpl21os_stack_trace_getterEv_S_construct_aux15pthread_mutex_tregex_tmbrtowcresultRandom~ParameterizedTestCaseInfoBase_ZNSt3setISsSt4lessISsESaISsEE5eraseERKSs_ZNK9__gnu_cxx13new_allocatorIPN7testing17TestEventListenerEE7addressERKS3__ZN7testing8internal12UnitTestImpl14RecordPropertyERKNS_12TestPropertyE__numeric_traits_integerfreeaddrinfo_M_limitoperator<< _ZNSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE4rendEv_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE5eraseESt17_Rb_tree_iteratorIS1_ES9__ZNK7testing8internal8FilePath12CreateFolderEv_ZNK7testing8internal10scoped_ptrINS0_16DeathTestFactoryEE3getEv_ZNSt6vectorISsSaISsEE3endEvkPathSeparator_ZN7testing12TestPropertyD2Evvfprintfiterator_traits, std::allocator >*>~Mutexisxdigitmatched_ZNSbIwSt11char_traitsIwESaIwEE4_Rep10_M_disposeERKS1__ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE10_S_maximumEPSt18_Rb_tree_node_basesi_fd_ZNSt6vectorISsSaISsEE4backEv_next_S_basefieldStringType__is_move_iterator_ZNSt6vectorIPN7testing8TestInfoESaIS2_EE3endEv__niter_base_ZNSt6vectorIPN7testing8TestCaseESaIS2_EE8_M_eraseEN9__gnu_cxx17__normal_iteratorIPS2_S4_EES8___uninitialized_copy_a_S_scientificerase_ZNK7testing8internal8FilePath15IsRootDirectoryEv_ZNKSt6vectorIN7testing14TestPartResultESaIS1_EE4rendEv_ZN7testing17TestEventListener11OnTestStartERKNS_8TestInfoEallocator, std::allocator > > >_ZNK7testing10TestResult15GetTestPropertyEi_ZN7testing32ScopedFakeTestPartResultReporterD0Ev_ZNSt6vectorIPN7testing8TestCaseESaIS2_EE6resizeEjS2_is_wide_stringstack_trace_depth_ZNK7testing8internal10scoped_ptrINS0_24InternalRunDeathTestFlagEEdeEvchar_type_ZN7testing4TestD0Evwctype_t_ZNKSs5rfindEPKcj_ZNSt6vectorISsSaISsEE14_M_fill_insertEN9__gnu_cxx17__normal_iteratorIPSsS1_EEjRKSs_ZNSt6vectorIiSaIiEE6insertEN9__gnu_cxx17__normal_iteratorIPiS1_EEjRKi_DestroyReinterpretBitsai_canonnameConfigureStreamingOutputalso_run_disabled_tests_ZN9__gnu_cxx17__normal_iteratorIPPN7testing8TestCaseESt6vectorIS3_SaIS3_EEEppEv_ZN7testing15AssertionResultlsISsEERS0_RKT__ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE12_M_erase_auxESt23_Rb_tree_const_iteratorISsESkipPrefix_ZN9__gnu_cxx17__normal_iteratorIPPcSt6vectorIS1_SaIS1_EEEppEi_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE14_M_upper_boundEPSt13_Rb_tree_nodeIS1_ESA_RKS1__ZNK9__gnu_cxx17__normal_iteratorIPPN7testing8internal29ParameterizedTestCaseInfoBaseESt6vectorIS4_SaIS4_EEEptEv_ZNSt12_Vector_baseIN7testing12TestPropertyESaIS1_EE11_M_allocateEjsaved_sigprof_actionoperator<< low_bits_IteratorR_ZNKSbIwSt11char_traitsIwESaIwEE8_M_limitEjj_ZNKSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE11__rb_verifyEv_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE5eraseESt17_Rb_tree_iteratorISsES7_successspawned__ZNSt13_Bit_iteratorppEi__sigchld_clock_ttear_down_tc__Vector_base >_ZNKSt5ctypeIcE13_M_widen_initEv__destroy_ZN7testing8internal12UnitTestImpl19PostFlagParsingInitEvmatchFLAGS_gtest_stack_trace_depth_ZNSt13_Bit_iteratorppEv_ZN7testing17TestEventListener20OnTestIterationStartERKNS_8UnitTestEikDeathTestStyleFlag_ZN7testing8internal18FormatFileLocationEPKci_ZN7testing15AssertionResultlsIA2_cEERS0_RKT__ZNKSt6vectorIPcSaIS0_EE4sizeEvcatch_exceptionsg_injected_test_argvs_ZNKSs4findEcj_M_get_insert_equal_pos_ZNSbIwSt11char_traitsIwESaIwEE12_S_empty_repEv_ZN7testing28FLAGS_gtest_stream_result_toEreverse_iterator<__gnu_cxx::__normal_iterator > > >_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE28_M_get_insert_hint_equal_posESt23_Rb_tree_const_iteratorIS1_ERKS1_PostFlagParsingInit_ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EE7reserveEj_ZNK7testing8internal12UnitTestImpl28internal_run_death_test_flagEv_ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EE8pop_backEv_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE5beginEv__positionqsortSocketWriter_ZNK9__gnu_cxx17__normal_iteratorIPN7testing14TestPartResultESt6vectorIS2_SaIS2_EEEplEi_ZNSbIwSt11char_traitsIwESaIwEE6insertEN9__gnu_cxx17__normal_iteratorIPwS2_EEw_ZNKSs4findERKSsj_ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EE5beginEvkAsIs_ZNK7testing8internal12UnitTestImpl6PassedEv_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE5eraseESt23_Rb_tree_const_iteratorIS1_ES9__ZNSt18_Rb_tree_node_base10_S_maximumEPS__ZNK7testing8UnitTest22failed_test_case_countEv_M_end_of_storage_ZN7testing8internal27PrettyUnitTestResultPrinter22OnEnvironmentsSetUpEndERKNS_8UnitTestE_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE17_M_insert_unique_ESt23_Rb_tree_const_iteratorISsERKSs__exchange_and_add_singleTearDownTestCase__x_copy_ZN9__gnu_cxx14__alloc_traitsISaIN7testing8internal9TraceInfoEEE7destroyERS4_PS3__ZN9__gnu_cxx14__alloc_traitsISaIN7testing12TestPropertyEEE8allocateERS3_j_Alloc_pad__uninitialized_copy_a*, std::basic_string >_ZN7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEE9CreateKeyEvgettervwscanfexponent_bitsputcharselected_Setwoperator<< _ZNK7testing8TestCase21reportable_test_countEvdeath_test_count__ZNKSt6vectorIN7testing14TestPartResultESaIS1_EE5frontEv_ZNKSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE4rendEv_M_headerinternal_run_death_test_SplitStringfind_last_of~TestEventListener__is_normal_iterator<__gnu_cxx::__normal_iterator > > >WideStringToUtf8_ZNKSt6vectorIPN7testing11EnvironmentESaIS2_EE5emptyEvuninitialized_copy<__gnu_cxx::__normal_iterator*, std::vector > >, std::basic_string*>__oldoperator- >_ZNSt6vectorIPN7testing8TestCaseESaIS2_EE5frontEvneedle_expr_ZN7testing8internal12UnitTestImpl18ConfigureXmlOutputEvunit_test__uninitialized_move_if_noexcept_a >reverse_iterator<__gnu_cxx::__normal_iterator > > >~set_ZN7testing22EmptyTestEventListener24OnEnvironmentsSetUpStartERKNS_8UnitTestE_Rb_tree_const_iteratorfabs_ZN7testing8internal14CapturedStream14ReadEntireFileEP8_IO_FILE_ZNSt3setISsSt4lessISsESaISsEE4swapERS3___vtt_parm_Destroy_M_ibeginactual_expression_ZNSt6vectorIPN7testing11EnvironmentESaIS2_EE5clearEv_ZNSt6vectorISsSaISsEE6assignEjRKSsGetRandomSeedFromFlag_ZNK9__gnu_cxx13new_allocatorIPN7testing8TestCaseEE7addressERS3__ZN7testing8internal17AppendUserMessageERKSsRKNS_7MessageEoperator!=*, std::vector > >__enable_if__throw_out_of_range_fmt_ZNKSt6vectorIPN7testing17TestEventListenerESaIS2_EE4sizeEvGetTestPartResultReporterForCurrentThread__copy_move_backward_a_ZN9__gnu_cxx17__normal_iteratorIPKSsSt6vectorISsSaISsEEEmIEiInternalRunDeathTestFlag_ZNKSbIwSt11char_traitsIwESaIwEE13find_first_ofERKS2_j_ZNK7testing8UnitTest21reportable_test_countEvF_OWNER_PGRP_ZNSt6vectorISsSaISsEE5eraseEN9__gnu_cxx17__normal_iteratorIPSsS1_EES5__ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS2_S4_EERKS2__ZN7testing14IsNotSubstringEPKcS1_S1_S1___off64_t_Iter_base<__gnu_cxx::__normal_iterator > >, false>__copy_move_a_ZNKSt6vectorIPN7testing8TestCaseESaIS2_EE12_M_check_lenEjPKc__gnu_cxx__typeEqFailureexpected_to_be_substringGetCapturedStringExitedUnsuccessfully_ZNK7testing8UnitTest20original_working_dirEvDeleteThreadLocalValue_ZN7testing8internal24HasNewFatalFailureHelperC2Evoperator+, std::allocator >_ZN7testing8internal38DefaultPerThreadTestPartResultReporterC2EPNS0_12UnitTestImplEoperator==_vptr.TestFactoryBase_M_current_ZNSs7replaceEjjjc_ZNSt6vectorIN7testing14TestPartResultESaIS1_EE5clearEv_Destroy_ZNKSs13find_first_ofEPKcjj_ZNSt6vectorIPN7testing8TestInfoESaIS2_EE8_M_eraseEN9__gnu_cxx17__normal_iteratorIPS2_S4_EES8__ZNK7testing8internal13FloatingPointIdE12AlmostEqualsERKS2__Iter_pred__copy_move_aoperator<< _ZNSt6vectorIiSaIiEE4rendEvtest_case_infos__ZNK9__gnu_cxx17__normal_iteratorIPN7testing14TestPartResultESt6vectorIS2_SaIS2_EEE4baseEv_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE11_M_put_nodeEPSt13_Rb_tree_nodeIS1_Earray___copy_move_backward_a2_sigsys_ZN9__gnu_cxx13new_allocatorIiE8allocateEjPKvreverse_iterator<__gnu_cxx::__normal_iterator > > >_S_create_Arg1_Arg2_ZNSt6vectorIPcSaIS0_EE6rbeginEv_ZNK7testing8internal13FloatingPointIfE12AlmostEqualsERKS2__Vector_base, std::allocator >, std::allocator, std::allocator > > >_ZNKSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE4rendEvattributesstack_trace_depth_MSG_FASTOPEN_Destroy_aux_ZN7testing8internal17StreamingListener10FormatBoolEbdefault__ZN7testing14KilledBySignalC2EiFullMatchreverse_iterator<__gnu_cxx::__normal_iterator > > >g_captured_stderrSetGlobalTestPartResultReporterpair, std::allocator > >, bool>PrintAsCharLiteralToabs_errorRegisterParameterizedTests_ZNKSt6vectorIPcSaIS0_EEixEjGetTestTypeId/home/user/projects/ascgit/ascgit003.dlt-daemon/build/gtest-1.7.0__copy_move_a2 >, __gnu_cxx::__normal_iterator > >test_indexValidateTestPropertyargs__M_insert_uniqueoperator<< UInt32RemoveExtensionkStreamResultToFlagkCurrentDirectoryStringname_template_ZNSt6vectorIiSaIiEE2atEjflag_ZN7testing8internal17StreamingListener18OnTestIterationEndERKNS_8UnitTestEiiterator_traits_ZNK9__gnu_cxx17__normal_iteratorIPiSt6vectorIiSaIiEEEdeEv_ZN7testing8internal13HasOneFailureEPKcS2_S2_RKNS_19TestPartResultArrayENS_14TestPartResult4TypeERKSs_ZNKSt6vectorISsSaISsEE12_M_check_lenEjPKcbool_constantkShuffleFlag_ZNKSt18_Bit_iterator_baseltERKS___uninit_copyCharType_ZNK7testing8TestCase30reportable_disabled_test_countEv_ZN9__gnu_cxx14__alloc_traitsISaISsEE7destroyERS1_PSsungetwcoperator- >__copy_move_achild_argcurrency_symbol_ZNK9__gnu_cxx17__normal_iteratorIPN7testing14TestPartResultESt6vectorIS2_SaIS2_EEEptEvgettimeofday_ZNKSt3setIPKcSt4lessIS1_ESaIS1_EE4findERKS1_locationShowWideCString__wchb_ZNSt12_Vector_baseIPN7testing17TestEventListenerESaIS2_EE11_M_allocateEj_ZNSbIwSt11char_traitsIwESaIwEE9_M_assignEPwjwoperator!= >_ZN7testing35FLAGS_gtest_also_run_disabled_testsEIsSubstringPred >_ZNKSt6vectorIiSaIiEE4dataEv_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE7_M_copyEPKSt13_Rb_tree_nodeISsEPS7__S_value~TestPropertyKeyIs_ZN9__gnu_cxx13new_allocatorISt13_Rb_tree_nodeISsEE9constructEPS2_RKS2___exchange_and_addbasic_string__normal_iterator, std::allocator >*, std::vector, std::allocator >, std::allocator, std::allocator > > > >_ZNSt6vectorIPcSaIS0_EE5beginEv_ZN9__gnu_cxx17__normal_iteratorIPSsSt6vectorISsSaISsEEEmIEinew_allocator_ZNK9__gnu_cxx13new_allocatorIiE7addressERi_Iter_base_M_range_initializefirst_is_TEST_ZN9__gnu_cxx17__normal_iteratorIPPN7testing11EnvironmentESt6vectorIS3_SaIS3_EEEppEi_M_checkglobal_test_part_result_reporter_mutex_AddTestInfo_ZNSt3setISsSt4lessISsESaISsEE5eraseESt23_Rb_tree_const_iteratorISsES5___size_ZNSt6vectorIPcSaIS0_EE5eraseEN9__gnu_cxx17__normal_iteratorIPS0_S2_EE_ZNSt10_Iter_baseIPN7testing14TestPartResultELb0EE7_S_baseES2__ZNK7testing10TestResult18HasNonfatalFailureEv_ZN9__gnu_cxx17__normal_iteratorIPKPN7testing8TestInfoESt6vectorIS3_SaIS3_EEEmmEi_ZNK9__gnu_cxx17__normal_iteratorIPPN7testing8TestInfoESt6vectorIS3_SaIS3_EEE4baseEv_ZNKSt18_Bit_iterator_basegeERKS__ZNKSs5emptyEv__builtin_unwind_resume_ZN7testing31FLAGS_gtest_death_test_use_forkEunary_function_ZNSt6vectorIPN7testing11EnvironmentESaIS2_EE6rbeginEvResult_ZNKSt6vectorIN7testing8internal9TraceInfoESaIS2_EE4backEv_ZNK7testing8TestCase10type_paramEva_current_test_infoAssumeRole_ZNSbIwSt11char_traitsIwESaIwEE13_S_copy_charsEPwN9__gnu_cxx17__normal_iteratorIPKwS2_EES8__ZNSt6vectorIN7testing12TestPropertyESaIS1_EE3endEv_ZNKSt3setIPKcSt4lessIS1_ESaIS1_EE11equal_rangeERKS1__ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE5eraseEPKSsS7___ostream_type__insert_left_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE7_S_leftEPSt18_Rb_tree_node_base_ZNKSt6vectorISsSaISsEE4dataEv_ZNSt6vectorIPN7testing8TestCaseESaIS2_EE3endEv_M_check_length_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE21_M_insert_equal_lowerERKS1__ZNKSt23_Rb_tree_const_iteratorISsEptEvdeath_test_use_fork__S_app_ZNSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE18_M_fill_initializeEjRKS3__ZNKSs4findEPKcjj_ZN7testing22EmptyTestEventListenerD2Ev_ZN9__gnu_cxx14__alloc_traitsISaIN7testing14TestPartResultEEE8allocateERS3_jMSG_OOB_ZN7testing8internal12UnitTestImpl9listenersEv__syscall_slong_t__alloc_traits, std::allocator > > >__alloc_traits >_ZN7testing8internal15UnitTestOptions17FilterMatchesTestERKSsS3__Identityp_sep_by_space_ZNKSt6vectorIN7testing12TestPropertyESaIS1_EE8capacityEvstart_timestampappendIsDirectoryTestDisabled_ZNKSt6vectorIPN7testing17TestEventListenerESaIS2_EE6rbeginEv_ZNK7testing8internal12AssertHelperaSERKNS_7MessageEsetlocale_ZNK7testing8UnitTest17failed_test_countEvbase_ZN7testing8internal17StreamingListenerD0Ev_ZNSt6vectorIPN7testing8TestInfoESaIS2_EE6assignEjRKS2_host_ZNKSt16reverse_iteratorIN9__gnu_cxx17__normal_iteratorIPPN7testing11EnvironmentESt6vectorIS4_SaIS4_EEEEEmiEi_Setprecisionfailed_ZN7testing8internal38DefaultPerThreadTestPartResultReporterD2Ev__copy_move_bbasic_streambufDefaultGlobalTestPartResultReporter_ZNKSt3setISsSt4lessISsESaISsEE6rbeginEv_IO_write_ptr_ZNSs6insertEN9__gnu_cxx17__normal_iteratorIPcSsEEcGTEST_WARNING_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE8_S_rightEPSt18_Rb_tree_node_base_ZN7testing8internal2RE12PartialMatchEPKcRKS1__S_in_ZN7testing17TestEventListener18OnTestIterationEndERKNS_8UnitTestEicopynew_allocator_mode_ZNKSt6vectorIN7testing12TestPropertyESaIS1_EE8max_sizeEvwcscasecmpGTestLog_ZN7testing12TestProperty8SetValueERKSs__socket_type_ZNSt9basic_iosIcSt11char_traitsIcEE4initEPSt15basic_streambufIcS1_E_ZN7testing8internal13FloatingPointIdE3MaxEvminpair, bool>SumOverTestCaseList_Vector_base >_ZNSt12_Vector_baseIPcSaIS0_EE12_Vector_impl12_M_swap_dataERS3__ZNK9__gnu_cxx17__normal_iteratorIPKcSsEptEv__ops_ZNK9__gnu_cxx13new_allocatorIPN7testing8TestCaseEE8max_sizeEvpair_ZN7testing8internal17StreamingListener9OnTestEndERKNS_8TestInfoE_ZN7testing8internal19FormatForComparisonIxxE6FormatERKx_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE11equal_rangeERKS1__ZN9__gnu_cxx14__alloc_traitsISaIN7testing8internal9TraceInfoEEE10deallocateERS4_PS3_j_Tp_alloc_typetest_detail.xml_Constructfull_regex_len_ZNSt6vectorIPN7testing8TestInfoESaIS2_EE5clearEv_ZNKSt3setISsSt4lessISsESaISsEE11lower_boundERKSsSOCK_RDM_ZNSt12_Vector_baseIiSaIiEE11_M_allocateEjCloneCString_ZNKSt3setIPKcSt4lessIS1_ESaIS1_EE4rendEv_ZNKSt6vectorIPcSaIS0_EE5beginEv_ZNKSt9basic_iosIcSt11char_traitsIcEE5widenEcoperator!=, std::allocator >_ZNK9__gnu_cxx17__normal_iteratorIPKPN7testing8TestCaseESt6vectorIS3_SaIS3_EEEplEiWrite_M_fill_initializekDefaultDeathTestStyle__normal_iterator > >waitpidtimezonetest_property_count_ZNK7testing10TestResult19test_property_countEv_ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EEaSERKS4__Vector_base >reverse_iterator<__gnu_cxx::__normal_iterator > > >an_outcome_S_ate_ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EE14_M_fill_assignEjRKS2_regexecmatches_filter__ZNKSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE11equal_rangeERKS1_expected_posoutcome__ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EEaSERKS7__ZNKSt6vectorISsSaISsEE3endEv_ZNKSs7compareEjjRKSsjj_ZN9__gnu_cxx13new_allocatorIiE9constructEPiRKi_ZNSt18_Bit_iterator_base12_M_bump_downEv_ZNSbIwSt11char_traitsIwESaIwEE14_M_replace_auxEjjjw_ZNKSt3setISsSt4lessISsESaISsEE5emptyEv_ZNSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE6assignEjRKS3__ZN7testing8internal23ScopedPrematureExitFileaSERKS1__Destroy_ZN7testing8internal6String13CStringEqualsEPKcS3__Rb_tree_iterator, std::allocator > >_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE21_M_get_Node_allocatorEvlast_in_range_ZN9__gnu_cxx17__normal_iteratorIPPN7testing8TestInfoESt6vectorIS3_SaIS3_EEEmmEi_ZNKSt6vectorIN7testing8internal9TraceInfoESaIS2_EE4sizeEv_ZNSt6vectorIPcSaIS0_EE2atEj__find_if<__gnu_cxx::__normal_iterator*, std::vector > >, __gnu_cxx::__ops::_Iter_equals_val > >_ZNSsaSEcUniversalPrinter, std::allocator > >_ZN9__gnu_cxx17__normal_iteratorIPPN7testing8TestInfoESt6vectorIS3_SaIS3_EEEmmEv_ZNSs7replaceEN9__gnu_cxx17__normal_iteratorIPcSsEES2_jc_ZN7testing8internal12UnitTestImpl12environmentsEv_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE4findERKS1_kSignBitMaska_value__uninit_copy*>countlong long unsigned int_ZN7testing8TestInfo15ClearTestResultEPS0__ZNSs6appendERKSs_ZN7testing8internal6String12FormatHexIntEiconstruct_vptr.TestEventListenerCaseInsensitiveCStringEquals_ZNK9__gnu_cxx13new_allocatorIPN7testing8TestCaseEE7addressERKS3_pair, std::allocator > >, bool>kDeathTestUseForkuppercase_ZNSbIwSt11char_traitsIwESaIwEEpLEwparameterized_test_registry__ZNKSbIwSt11char_traitsIwESaIwEE4rendEvconstructFormatTestCaseCount_ZNKSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE5frontEvFLAGS_gtest_stream_result_to_ZNKSt6vectorIPN7testing17TestEventListenerESaIS2_EE8capacityEv_ZN9__gnu_cxx13new_allocatorIN7testing14TestPartResultEE9constructEPS2_RKS2_MakeAndRegisterTestInfounsigned char_ZNK7testing8internal24InternalRunDeathTestFlag5indexEv_M_grab_ZNKSt23_Rb_tree_const_iteratorIPKcEdeEv_ZN7testing14IsNotSubstringEPKcS1_PKwS3_stack_traceoperator<< ClearResultregmatch_tFLAGS_gtest_death_test_style_ZNKSt6vectorIPN7testing8TestCaseESaIS2_EEixEj_ZN9__gnu_cxx17__normal_iteratorIPPN7testing17TestEventListenerESt6vectorIS3_SaIS3_EEEmmEi_ZN7testing8internal13ParseBoolFlagEPKcS2_Pb_ZN7testing8internal14ParseFlagValueEPKcS2_bUnitTestOptions_ZN9__gnu_cxx17__normal_iteratorIPPN7testing17TestEventListenerESt6vectorIS3_SaIS3_EEEmmEv_ZN9__gnu_cxx17__normal_iteratorIPcSsEmmEi__gnu_debug_ZN9__gnu_cxx17__normal_iteratorIPcSsEmmEvSOCK_DGRAM_ZNSt6vectorIN7testing14TestPartResultESaIS1_EE7reserveEj__is_char__outTypeIdHelper_ZNK7testing14TestPartResult9file_nameEv_ZN7testing8internal6String12CloneCStringEPKc_ZNKSt6vectorIPN7testing17TestEventListenerESaIS2_EE8max_sizeEv_ZNKSt6vectorIPN7testing11EnvironmentESaIS2_EE4backEv_ZN9__gnu_cxx13new_allocatorIPN7testing8TestCaseEE9constructEPS3_RKS3_test_info_list_fwide_ZN7testing8internal17StreamingListener5StartEv__iterator_category<__gnu_cxx::__normal_iterator > >_ZN7testing22EmptyTestEventListener18OnTestProgramStartERKNS_8UnitTestE_ZNKSt6vectorIPN7testing8TestCaseESaIS2_EE5beginEvoutput_file_for_each<__gnu_cxx::__normal_iterator >, void (*)(testing::TestEventListener*)>F_OWNER_GID_ZNKSt6vectorIiSaIiEEixEj_ZNK7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEE7pointerEv_ZN7testing8internal27OsStackTraceGetterInterface16UponLeavingGTestEv_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE5clearEv_ZNSs6insertEjPKcj_ZN7testing8internal27PrettyUnitTestResultPrinter9OnTestEndERKNS_8TestInfoE_ZNK7testing8UnitTest15start_timestampEv_ZNKSt12_Vector_baseIN7testing8internal9TraceInfoESaIS2_EE19_M_get_Tp_allocatorEvkChunkSize_ZNSt6vectorIPcSaIS0_EE3endEv~GoogleTestFailureExceptionHandleSehExceptionsInMethodIfSupportedSetDefaultResultPrinterwcsspn~_Iter_pred_ZNSt6vectorISsSaISsEE6resizeEjSsoperator<< _ZNKSt6vectorIPN7testing17TestEventListenerESaIS2_EE5frontEvGetAnsiColorCode__copy_move_backward_a2__alloc_traits, std::allocator > > > >_ZNSt6vectorIPN7testing11EnvironmentESaIS2_EE18_M_fill_initializeEjRKS2__Rb_tree_ZNSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE5clearEv_ZN7testing8internal6String17WideCStringEqualsEPKwS3_streamraw_seed_ZNK7testing8internal12UnitTestImpl15start_timestampEvmax_length_ZNK7testing14TestPartResult6passedEv_ZNK9__gnu_cxx13new_allocatorIN7testing8internal9TraceInfoEE8max_sizeEvFOpen_sifields_ZN7testing17TestEventListener27OnEnvironmentsTearDownStartERKNS_8UnitTestEInfinitycan_be_nullwctyperesults_GetTestProperty__copy_move_backward_a_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE13_M_clone_nodeEPKSt13_Rb_tree_nodeIS1_E_ZNKSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE4dataEv_Destroy_ZN9__gnu_cxx14__alloc_traitsISaISt13_Rb_tree_nodeISsEEE7destroyERS3_PS2_HandleSehExceptionsInMethodIfSupported_ZNKSt3setIPKcSt4lessIS1_ESaIS1_EE5countERKS1_TEST_name__xstat_ZN9__gnu_cxx17__normal_iteratorIPN7testing14TestPartResultESt6vectorIS2_SaIS2_EEEppEi_ZN7testing8internal24XmlUnitTestResultPrinter18OutputXmlAttributeEPSoRKSsS4_S4__ZNSs12_M_leak_hardEv_M_insert_unique__Ios_Iostate_ZN9__gnu_cxx17__normal_iteratorIPN7testing14TestPartResultESt6vectorIS2_SaIS2_EEEppEviterator_traits_ZN9__gnu_cxx13new_allocatorIN7testing12TestPropertyEE9constructEPS2_RKS2__ZNSsixEj_ZN7testing8internal6String10FormatByteEh_ZNSt6vectorIN7testing12TestPropertyESaIS1_EEaSERKS3__ZN9__gnu_cxx13new_allocatorIPN7testing8TestInfoEE8allocateEjPKvSetTestPartResultReporterForCurrentThreadOnEnvironmentsSetUpEnd_ZNSspLERKSsAddArguments >size_typeEnvironment_ZN9__gnu_cxx17__normal_iteratorIPPN7testing8TestCaseESt6vectorIS3_SaIS3_EEEmmEvfull_regex_srand_Destroy__delta_ZN9__gnu_cxx17__normal_iteratorIPPcSt6vectorIS1_SaIS1_EEEmmEifreeset_catch_exceptionspart_ZN9__gnu_cxx14__alloc_traitsISaIPcEE8max_sizeERKS2_TypedTestCasePState_ZN7testing8internal14GTestMutexLockaSERKS1__ZN9__gnu_cxx17__normal_iteratorIPPcSt6vectorIS1_SaIS1_EEEmmEv_ZN7testing8internal9DeathTest24last_death_test_message_EtypeCreateCodePointFromUtf16SurrogatePair_ZNSt13_Bit_iteratormmEiConfigureXmlOutputalso_run_disabled_tests__ZNSt13_Bit_iteratormmEv_ZNSt6vectorIPN7testing8TestCaseESaIS2_EE2atEj_ZNSt6vectorIPN7testing8TestCaseESaIS2_EEixEjinit_ZNKSt9basic_iosIcSt11char_traitsIcEE4fillEvother_ZNKSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE4findERKSs_ZNK7testing8internal13DeathTestImpl7spawnedEvOnTestProgramStart_Unwind_Resumeai_flagskDeathTestThrew_ZNSbIwSt11char_traitsIwESaIwEE7_M_copyEPwPKwj_ZN7testing11EnvironmentD0EvTearDown_Rb_tree_node_ZNSs4_Rep10_M_refdataEv__cxxabiv1_ZN7testing8internal17Int32FromEnvOrDieEPKci__pos_ZNSt6vectorIN7testing14TestPartResultESaIS1_EE3endEvtype_info_ZNK9__gnu_cxx17__normal_iteratorIPN7testing14TestPartResultESt6vectorIS2_SaIS2_EEEmiEi_ZNSt6vectorIPcSaIS0_EE4backEvwcsstrTesthost_name__ZNKSt6vectorIPN7testing11EnvironmentESaIS2_EE4sizeEvkReservedTestSuitesAttributes_ZN7testing7MessagelsERKSbIwSt11char_traitsIwESaIwEEpath_ZN7testing8internal16ForkingDeathTest4WaitEv_ZNKSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE5emptyEvClearAdHocTestResultst_size_ZN7testing8internal24XmlUnitTestResultPrinter18OnTestIterationEndERKNS_8UnitTestEi_ZNKSt6vectorIPN7testing8TestCaseESaIS2_EE4backEv_ZNK9__gnu_cxx13new_allocatorISt13_Rb_tree_nodeISsEE8max_sizeEv_ZNSt6vectorISsSaISsEE2atEj_ZNKSt13_Rb_tree_nodeIPKcE9_M_valptrEvFLAGS_gtest_death_test_use_fork_ZN7testing8internal12UnitTestImpl18death_test_factoryEv_Rb_tree_impl, std::allocator > >, false>_ZN7testing8UnitTest18GetMutableTestCaseEi_ZNKSs5c_strEvreverse_iterator<__gnu_cxx::__normal_iterator > > >exit_code_ZNSt12_Vector_baseIN7testing14TestPartResultESaIS1_EE11_M_allocateEjtest_properties__ZN7testing8TestCaseD0Ev_ZNKSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE7_M_rootEvfraction_bits_ZN7testing8internal10scoped_ptrINS0_17StreamingListener20AbstractSocketWriterEE5resetEPS3_testing_Result_ZN9__gnu_cxx17__normal_iteratorIPPN7testing8TestInfoESt6vectorIS3_SaIS3_EEEpLEitm_mday_ZNK9__gnu_cxx17__normal_iteratorIPN7testing12TestPropertyESt6vectorIS2_SaIS2_EEEdeEv__niter_baseAppend_ZNKSt12_Vector_baseIPcSaIS0_EE19_M_get_Tp_allocatorEv_Iter_predsi_addr_ZN9__gnu_cxx13new_allocatorIwE9constructEPwRKw_ZN7testing8internal2RE12PartialMatchERKSsRKS1_RunAllTests__miter_base_ZNKSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE3endEvGetTestCase_M_swap_data_ZNSt10_Iter_baseIPPN7testing11EnvironmentELb0EE7_S_baseES3_~basic_iostream_M_erase_at_enditerator_traitschild_pidallocator_ZNK9__gnu_cxx13new_allocatorIPcE7addressERS1__ZNK7testing8internal8FilePath11IsDirectoryEv_ZNKSt4lessISsEclERKSsS2_precisioncopy<__gnu_cxx::__normal_iterator >, __gnu_cxx::__normal_iterator > >MSG_NOSIGNALkOutputFlag_ZN7testing7MessagelsEPFRSoS1_E_ZNSt6vectorIN7testing14TestPartResultESaIS1_EE6assignEjRKS1_ad_hoc_test_result_ZNSt3setISsSt4lessISsESaISsEE5clearEvsingular_form_Iter_base_ZN7testing31TestPartResultReporterInterface20ReportTestPartResultERKNS_14TestPartResultEoperator<< _ZN9__gnu_cxx17__normal_iteratorIPPN7testing17TestEventListenerESt6vectorIS3_SaIS3_EEEpLEi__are_samebinary_function__resoperator<< kTestTotalShardsiterator_traits_ZN9__gnu_cxx17__normal_iteratorIPcSsEpLEibasic_streambuf >_ZNSt6vectorISsSaISsEE18_M_fill_initializeEjRKSs_call_addroriginal_working_dir_ZN7testing18TestEventListeners23SuppressEventForwardingEv_ZNSbIwSt11char_traitsIwESaIwEE9push_backEw_ZNKSs7compareERKSsExitSummary_ZNK9__gnu_cxx17__normal_iteratorIPKN7testing8internal9TraceInfoESt6vectorIS3_SaIS3_EEE4baseEvtimeval_ZNKSt6vectorIPN7testing8TestCaseESaIS2_EE4sizeEv_ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EEixEj_ZNSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE9push_backERKS3___normal_iterator > >~DeathTest_ZNSbIwSt11char_traitsIwESaIwEE6resizeEjwvector, std::allocator >, std::allocator, std::allocator > > >fopen_ZNSbIwSt11char_traitsIwESaIwEEaSEPKw_ZNSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE4dataEvdifference_typerebind_ZNSo5flushEvsetprecision_M_value_field_ZN9__gnu_cxx14__alloc_traitsISaIPcEE10deallocateERS2_PS1_j_S_badbit~OsStackTraceGetterInterfacecaller_frame__ZNSs7_M_dataEPcwcslenline_endtype_param__ZNSbIwSt11char_traitsIwESaIwEE10_S_compareEjj_ZNK7testing8internal12UnitTestImpl17failed_test_countEvenvironSOCK_CLOEXEClisteners_kInternalRunDeathTestFlag5div_tGetGlobalTestPartResultReporterScopedTracewcstoullboolalpha_ZN7testing8internal16ForkingDeathTest13set_child_pidEi_ZN7testing8internal13FloatingPointIfE24SignAndMagnitudeToBiasedERKj_Link_type_ZN7testing8internal14StackGrowsDownEv_ZSt9__find_ifIN9__gnu_cxx17__normal_iteratorIPKSsSt6vectorISsSaISsEEEENS0_5__ops16_Iter_equals_valIS2_EEET_SB_SB_T0_St26random_access_iterator_tag_ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EE6resizeEjS2_Normalizetest_propertywrite_fd_swapreverse_iterator, std::allocator > > >_ZNKSt6vectorIPN7testing8TestInfoESaIS2_EE12_M_check_lenEjPKcscientificCaptureStream_S_showposGTEST_TOTAL_SHARDS_ZN7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEE3setERKS5_predicate_ZNK9__gnu_cxx17__normal_iteratorIPKPN7testing11EnvironmentESt6vectorIS3_SaIS3_EEEdeEvpair, std::allocator > >, std::_Rb_tree_iterator, std::allocator > > >_ZNSs13_S_copy_charsEPcN9__gnu_cxx17__normal_iteratorIS_SsEES2__ZNKSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE5beginEv_ZNKSbIwSt11char_traitsIwESaIwEE7compareEPKw_ZNSbIwSt11char_traitsIwESaIwEE7replaceEjjPKwDelete_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE8_S_valueEPKSt18_Rb_tree_node_baselldiv_t_ZN7testing8internal30GetBoolAssertionFailureMessageERKNS_15AssertionResultEPKcS5_S5_~_Alloc_hider_M_create_nodedeath_test_count_ZN9__gnu_cxx17__normal_iteratorIPPN7testing8TestCaseESt6vectorIS3_SaIS3_EEEpLEi_ZNKSt6vectorIN7testing8internal9TraceInfoESaIS2_EE5frontEv_ZN7testing8UnitTest27parameterized_test_registryEv_ZNSbIwSt11char_traitsIwESaIwEE5eraseEjj_ZN9__gnu_cxx17__normal_iteratorIPPcSt6vectorIS1_SaIS1_EEEpLEiBiggestConvertible_ZNKSt6vectorIN7testing14TestPartResultESaIS1_EE4dataEv_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE3endEvMSG_TRYHARD_ZN7testing8internal18OsStackTraceGetter17CurrentStackTraceEii_IO_buf_basematches_filter_ZNSt13_Bit_iteratorpLEi__FILE__pthread_internal_slist~InternalRunDeathTestFlag_ZNKSt18_Bit_iterator_baseneERKS__ZNK9__gnu_cxx17__normal_iteratorIPN7testing12TestPropertyESt6vectorIS2_SaIS2_EEEixEifilename__ZNSt18_Bit_iterator_base10_M_bump_upEv_ZNSbIwSt11char_traitsIwESaIwEE5clearEv_S_endTestBody_ZNKSt6vectorIN7testing12TestPropertyESaIS1_EE4backEv_ZNK9__gnu_cxx17__normal_iteratorIPKSsSt6vectorISsSaISsEEEdeEvget_allocator_ZNKSt6vectorIN7testing14TestPartResultESaIS1_EE12_M_check_lenEjPKc_ZNSt14_Bit_reference4flipEv_ZN9__gnu_cxx13new_allocatorIPN7testing17TestEventListenerEE8allocateEjPKvcaptured_stream_ZNK9__gnu_cxx17__normal_iteratorIPKPN7testing11EnvironmentESt6vectorIS3_SaIS3_EEEixEikUnknownFile_ZNKSt12_Vector_baseISsSaISsEE19_M_get_Tp_allocatorEv_ZNSt6vectorIPcSaIS0_EEaSERKS2_test_indices_operator!=<__gnu_cxx::__normal_iterator > >_ZNK9__gnu_cxx13new_allocatorISsE7addressERSsPrintTo_ZN7testing8internal17StreamingListener16OnTestPartResultERKNS_14TestPartResultE_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE16_M_insert_uniqueERKS1__ZN9__gnu_cxx17__normal_iteratorIPPN7testing11EnvironmentESt6vectorIS3_SaIS3_EEEmmEikStdErrFileno_ZN7testing8internal13DeathTestImpl26ReadAndInterpretStatusByteEv~DefaultDeathTestFactory_ZN9__gnu_cxx17__normal_iteratorIPPN7testing11EnvironmentESt6vectorIS3_SaIS3_EEEmmEv_ZNKSt13_Rb_tree_nodeISsE9_M_valptrEv_ZN9__gnu_cxx13new_allocatorIPN7testing8internal29ParameterizedTestCaseInfoBaseEE7destroyEPS4_SuppressTestEventsIfInSubprocessAddArgument_ZN9__gnu_cxx17__normal_iteratorIPN7testing12TestPropertyESt6vectorIS2_SaIS2_EEEppEv_M_initializefastmap_accurate_ZNSbIwSt11char_traitsIwESaIwEE7_M_leakEvreverse_iterator<__gnu_cxx::__normal_iterator > > >_ZNSs7replaceEjjPKcjkBreakOnFailureFlaglong unsigned int__uninitialized_copy_a_ZN7testing8internal20SingleFailureCheckerC2EPKNS_19TestPartResultArrayENS_14TestPartResult4TypeERKSsword_list_ZN7testing8internal12UnitTestImpl41SetTestPartResultReporterForCurrentThreadEPNS_31TestPartResultReporterInterfaceEtm_isdst_ZNK9__gnu_cxx13new_allocatorISt13_Rb_tree_nodeIPKcEE8max_sizeEvint_n_sign_posn_ZNSt6vectorIPN7testing8TestInfoESaIS2_EE9push_backERKS2_operator!= >HasGoogleTestFlagPrefix_ZNKSt6vectorIPcSaIS0_EE2atEj_ZNKSbIwSt11char_traitsIwESaIwEE9_M_ibeginEv_ZNK7testing8internal10scoped_ptrISt18basic_stringstreamIcSt11char_traitsIcESaIcEEE3getEv_ZN7testing8internal16InDeathTestChildEv_ZNSt6vectorIN7testing12TestPropertyESaIS1_EE9push_backERKS1_TypeParam_ZNK9__gnu_cxx17__normal_iteratorIPKSsSt6vectorISsSaISsEEEixEiegptr_ZNKSt9type_infoeqERKS__ZNSt6vectorIPN7testing8TestCaseESaIS2_EE8_M_eraseEN9__gnu_cxx17__normal_iteratorIPS2_S4_EE__intptr_tClearTestPartResultsoperator==<__gnu_cxx::__normal_iterator > >CharFormatvfwprintf_ZN7testing17TestEventListener16OnTestPartResultERKNS_14TestPartResultE_ZNK7testing8UnitTest11GetTestCaseEi_ZN7testing8internal7g_argvsE_ZNSt14_Bit_referenceaSERKS_EscapeXmlText_ZNSbIwSt11char_traitsIwESaIwEE6insertEjjw_ZNKSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE11lower_boundERKSsstrchr_ZNKSt5ctypeIcE8do_widenEc__normal_iterator > >fixed_IO_read_base_ZNSt6vectorIN7testing14TestPartResultESaIS1_EE4rendEv__find_if<__gnu_cxx::__normal_iterator >, __gnu_cxx::__ops::_Iter_pred >_ZNKSt16reverse_iteratorIN9__gnu_cxx17__normal_iteratorIPPN7testing11EnvironmentESt6vectorIS4_SaIS4_EEEEEptEv_ZNSbIwSt11char_traitsIwESaIwEE4swapERS2__ZNKSt6vectorIPN7testing8TestInfoESaIS2_EE4rendEv_ZNKSt6vectorIiSaIiEE5emptyEvScopedFakeTestPartResultReporterkThrowOnFailureFlag__alloc_ZNSt11char_traitsIcE2ltERKcS2__ZNK7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE3getEvIsSubstringPred_M_insert_ZNK7testing8TestInfo13is_reportableEv_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE4rendEvsockaddr_ZN7testing8DoubleLEEPKcS1_dd__debug_ZN7testing8internal27PrettyUnitTestResultPrinter18OnTestProgramStartERKNS_8UnitTestE_ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EE4backEvfull_name_Swallow_assignwcstod_ZNK7testing14TestPartResult7messageEvreset_ZNK9__gnu_cxx13new_allocatorIPN7testing11EnvironmentEE8max_sizeEv_ZNSt6vectorIiSaIiEE4dataEv_ZNK9__gnu_cxx13new_allocatorIN7testing8internal9TraceInfoEE7addressERKS3___addressofuninitialized_copy_ZNKSt15basic_stringbufIcSt11char_traitsIcESaIcEE3strEv_ZN7testing8internal15UnitTestOptions13MatchesFilterERKSsPKcreg_syntax_t_ZNSt9basic_iosIcSt11char_traitsIcEE8setstateESt12_Ios_Iostate_ZNK7testing8internal8FilePath15RemoveExtensionEPKc_vptr.Test_ZN7testing8internal13FloatingPointIfE3MaxEvwmemcmp_ZNSbIwSt11char_traitsIwESaIwEE7replaceEN9__gnu_cxx17__normal_iteratorIPwS2_EES6_S5_S5_value_type_ZNSs15_M_replace_safeEjjPKcjsuffix_Const_Link_type_ZNSt3setIPKcSt4lessIS1_ESaIS1_EE5eraseERKS1_this_test_info_ZN7testing8internal13ExecDeathTest32GetArgvsForDeathTestChildProcessEvconstructInitGoogleTestImpl_ZNK9__gnu_cxx17__normal_iteratorIPPN7testing11EnvironmentESt6vectorIS3_SaIS3_EEEmiEi_ZN9__gnu_cxx13new_allocatorISt13_Rb_tree_nodeISsEE10deallocateEPS2_j_ZNSt6vectorIPN7testing8TestInfoESaIS2_EE8_M_eraseEN9__gnu_cxx17__normal_iteratorIPS2_S4_EEStreamableToStringskipwshas_owner_operator!=_Iter_base__is_move_iterator_ZNKSt6vectorIN7testing12TestPropertyESaIS1_EE4sizeEv__cxa_rethrow_ZN9__gnu_cxx14__alloc_traitsISaIPN7testing8TestInfoEEE7destroyERS4_PS3__ZNSt6vectorIN7testing14TestPartResultESaIS1_EEixEjsocket_ZN9__gnu_cxx17__normal_iteratorIPPN7testing8TestCaseESt6vectorIS3_SaIS3_EEEmmEi_ZNSt6vectorIPN7testing8TestCaseESaIS2_EE18_M_fill_initializeEjRKS2_property_ZNSbIwSt11char_traitsIwESaIwEE6appendEPKw~EmptyTestEventListener_ZN7testing11EnvironmentD2Ev_ZNK7testing10TestResult17GetTestPartResultEirebind_Iter_base_Rb_tree_colortv_sec_ZNSs7replaceEN9__gnu_cxx17__normal_iteratorIPcSsEES2_PKcjuse_color_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE5clearEv_ZN7testing8UnitTest17AddTestPartResultENS_14TestPartResult4TypeEPKciRKSsS6__ZNSt6vectorIPcSaIS0_EE7reserveEj_ZNSt12_Vector_baseIN7testing8internal9TraceInfoESaIS2_EE12_Vector_impl12_M_swap_dataERS5_test_properites_mutex__unused2IN_PROGRESSpid_t__are_same__destroyUniversalTersePrinterPrintCharsAsStringToIsSubstringImpl >GetStreamset_should_run_ZNKSt6vectorIN7testing14TestPartResultESaIS1_EE5beginEvbtowc_ZNKSt6vectorIPN7testing8TestInfoESaIS2_EE5frontEv_ZStplIcSt11char_traitsIcESaIcEESbIT_T0_T1_ERKS6_PKS3__M_node_counttm_ming_init_gtest_countMSG_WAITALLoperator<< _ZNSt6vectorIPN7testing8TestCaseESaIS2_EE5beginEv_ZN9__gnu_cxx14__alloc_traitsISaIN7testing12TestPropertyEEE8max_sizeERKS3__ZNSbIwSt11char_traitsIwESaIwEE6appendERKS2_jjbasic_stringstrcmp_ZNK7testing8internal12UnitTestImpl6FailedEv_ZN7testing8internal12UnitTestImpl24ConfigureStreamingOutputEv_ZNSt6vectorIiSaIiEE6rbeginEv_ZN7testing8internal30WriteToShardStatusFileIfNeededEv_ZN7testing8internal35HandleExceptionsInMethodIfSupportedINS0_15TestFactoryBaseEPNS_4TestEEET0_PT_MS6_FS5_vEPKc_ZN7testing8internal24HasNewFatalFailureHelper20ReportTestPartResultERKNS_14TestPartResultE_ZNK9__gnu_cxx13new_allocatorIPKcE8max_sizeEv_ZNSt3setIPKcSt4lessIS1_ESaIS1_EE5eraseESt23_Rb_tree_const_iteratorIS1_ES7_ai_addr_ZNK9__gnu_cxx13new_allocatorISsE8max_sizeEv__strThreadLocalfailuresfwscanf~AbstractSocketWriter_DestroyCreateFolder_ZN7testing9internal220PrintBytesInObjectToEPKhjPSoisspace_ZNKSs8_M_limitEjj_ZN7testing16AssertionFailureERKNS_7MessageEglobal_test_part_result_repoter__ZNSs4swapERSs_ZNKSt3setISsSt4lessISsESaISsEE4rendEv_ZNSt12_Vector_baseIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE17_M_create_storageEj__uninitialized_move_if_noexcept_a >_ZN7testing8internal12UnitTestImpl11FilterTestsENS1_18ReactionToShardingE_ZNK9__gnu_cxx17__normal_iteratorIPKN7testing8internal9TraceInfoESt6vectorIS3_SaIS3_EEEplEifailure_message_ZNKSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE14_M_lower_boundEPKSt13_Rb_tree_nodeIS1_ESB_RKS1__ZNSbIwSt11char_traitsIwESaIwEE7replaceEjjRKS2_jjStreamableToStringAlmostEqualsInDeathTestChild_ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EE6rbeginEvShouldShardoperator<< _ZNK9__gnu_cxx13new_allocatorIwE7addressERKw_ZNSt16reverse_iteratorIN9__gnu_cxx17__normal_iteratorIPPN7testing11EnvironmentESt6vectorIS4_SaIS4_EEEEEppEi_ZNKSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE8max_sizeEv_ZNKSt17_Rb_tree_iteratorISsEeqERKS0__ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE21_M_get_Node_allocatorEv_ZN7testing14InitGoogleTestEPiPPcfind_if<__gnu_cxx::__normal_iterator >, testing::internal::TestPropertyKeyIs>GetEnviron_ZNSt16reverse_iteratorIN9__gnu_cxx17__normal_iteratorIPPN7testing11EnvironmentESt6vectorIS4_SaIS4_EEEEEppEvdefault_val_ZNK7testing8TestInfo11value_paramEv_ZNSt3setISsSt4lessISsESaISsEE11lower_boundERKSs_ZNSs6insertEjRKSsjj_ZN7testing14InitGoogleTestEPiPPwCmpHelperSTRNEMSG_WAITFORONE_ZN7testing8internal9MutexBase6UnlockEv_ZNSbIwSt11char_traitsIwESaIwEE5eraseEN9__gnu_cxx17__normal_iteratorIPwS2_EEoperator&=pattern_DeathTestFactory_ZNSt3setIPKcSt4lessIS1_ESaIS1_EE5eraseESt23_Rb_tree_const_iteratorIS1_E_ZNK9__gnu_cxx13new_allocatorIPN7testing11EnvironmentEE7addressERS3__ZN7testing8internal24XmlUnitTestResultPrinterD2Ev_ZN7testing8internal18OsStackTraceGetterD0EvTestEventListeners_ZNSt11char_traitsIcE4moveEPcPKcj~AssertHelperkTestShardIndex_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE11upper_boundERKSs_ZN7testing8internal17StreamingListener12SocketWriter14MakeConnectionEv_ZNK7testing8internal13FloatingPointIfE13fraction_bitsEv_M_refcopy_ZNSt20__uninitialized_copyILb0EE13__uninit_copyIPN7testing12TestPropertyES4_EET0_T_S6_S5_si_uid_ZNKSt15basic_streambufIcSt11char_traitsIcEE5pbaseEv_Destroy_ZN9__gnu_cxx13new_allocatorIPN7testing8TestInfoEE7destroyEPS3__ZN7testing8internal26GoogleTestFailureExceptionC2ERKNS_14TestPartResultEsa_mask_S_floatfieldsizetypeIsSubstringImpl_ZN7testing4TestC2Ev_ZNSs4_Rep10_M_refcopyEv~TestPartResultReporterInterfacepremature_exit_file_ZNKSbIwSt11char_traitsIwESaIwEE5rfindEPKwjj__errno_location_ZNSt11char_traitsIwE3eofEv_ZNKSt23_Rb_tree_const_iteratorIPKcEeqERKS2_new_allocator_ZNKSt6vectorIPcSaIS0_EE6rbeginEvoperator()_ZNKSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE12_M_rightmostEv_ZNK7testing10TestResult6FailedEv_M_get_insert_unique_pos_ZNSt12_Vector_baseIN7testing14TestPartResultESaIS1_EE19_M_get_Tp_allocatorEv_ZN7testing16AssertionFailureEvMSG_SYN__value_ZN9__gnu_cxx17__normal_iteratorIPN7testing14TestPartResultESt6vectorIS2_SaIS2_EEEmmEi_ZN7testing15AssertionResultlsINS_14TestPartResultEEERS0_RKT__ZN9__gnu_cxx14__alloc_traitsISaIN7testing8internal9TraceInfoEEE17_S_select_on_copyERKS4_success_scoped_ptr, std::allocator > >sigactiondirectory_ZN9__gnu_cxx17__normal_iteratorIPN7testing14TestPartResultESt6vectorIS2_SaIS2_EEEmmEveofbit_ZNSt3tr110tuple_sizeINS_5tupleIIEEEE5valueE_ZNSs4_Rep26_M_set_length_and_sharableEj_ZNSt6vectorIPcSaIS0_EE5eraseEN9__gnu_cxx17__normal_iteratorIPS0_S2_EES6_CaseInsensitiveWideCStringEquals_ZNKSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE8key_compEv_ZNSt13_Rb_tree_nodeIPKcE9_M_valptrEvgtest_trace_stack_should_ZNSt11char_traitsIwE4copyEPwPKwj_ZNSt10_Iter_baseIPPcLb0EE7_S_baseES1_printf_ZNSt12_Vector_baseISsSaISsEE12_Vector_impl12_M_swap_dataERS2__ZN7testing8internal13DeathTestImpl10set_statusEi__lentm_monrepeat__ZN7testing8TestCase22TestReportableDisabledEPKNS_8TestInfoEsi_pid__off_t_M_get_Node_allocator__resultdefault_global_test_part_result_reporter_factory_new_allocatorrebindDoubleNearPredFormatreverse_iterator<__gnu_cxx::__normal_iterator > > >_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE8_S_valueEPKSt13_Rb_tree_nodeIS1_Eflag_str_ZN9__gnu_cxx14__alloc_traitsISaISt13_Rb_tree_nodeISsEEE8allocateERS3_j_ZNSt6vectorIPN7testing11EnvironmentESaIS2_EE5eraseEN9__gnu_cxx17__normal_iteratorIPS2_S4_EES8__ZN7testing8internal24ParseGoogleTestFlagsOnlyEPiPPc_ZNKSt23_Rb_tree_const_iteratorISsE13_M_const_castEv_ZNKSt12_Vector_baseIPN7testing8TestCaseESaIS2_EE19_M_get_Tp_allocatorEv_M_rightmostIsSpace_ZNSolsEd_ZNSolsEf_ZNSolsEi_ZNSolsEjdiffobj_bytesShuffleRange_syscall_ZNSolsEx_ZNSt6vectorIiSaIiEE8_M_eraseEN9__gnu_cxx17__normal_iteratorIPiS1_EEkBitCountmarker__wch_ZN7testing8internal12UnitTestImpl14UnshuffleTestsEvlistener_Arg__copy_move_boperator== >_ZdaPv__alloc_swap, std::allocator > >, true>StackGrowsDownFloatingPointUnionoperator++ignore_ZNSt10_Iter_baseIPPN7testing8TestCaseELb0EE7_S_baseES3_operator+=__glibc_reserved4__glibc_reserved5range_width~Test_ZNK7testing8TestCase18ad_hoc_test_resultEv__string_typePrintFailedTestsallocator, std::allocator > >trace_ZNKSt14_Bit_referenceltERKS__ZN7testing8internal27PrettyUnitTestResultPrinter15OnTestCaseStartERKNS_8TestCaseE_ZN7testing8internal21UniversalTersePrinterIPKwE5PrintES3_PSoInitGoogleTestImpl_ZN9__gnu_cxx17__normal_iteratorIPPN7testing8TestInfoESt6vectorIS3_SaIS3_EEEmIEibasic_string, std::allocator >flag_lenCapturedStreamwcsncat__lhs_ZN7testing8internal10scoped_ptrINS0_17StreamingListener20AbstractSocketWriterEEaSERKS4__ZNSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE8_M_eraseEN9__gnu_cxx17__normal_iteratorIPS3_S5_EEnew_allocatorsetstate_ZNSt6vectorIiSaIiEE14_M_fill_assignEjRKi_ZN7testing8internal9DeathTestC2Ev_ZN7testing8internal9Arguments4ArgvEv_ZNSbIwSt11char_traitsIwESaIwEE6resizeEj_ZNK7testing8TestCase11GetTestInfoEi_ZNSt11char_traitsIwE7compareEPKwS2_j_ZNK7testing8internal10scoped_ptrINS0_24InternalRunDeathTestFlagEEptEv_ZNSt6vectorIPN7testing11EnvironmentESaIS2_EE5frontEvoperator--Delete_ZNKSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE8max_sizeEv__elision_data_Containeroperator-=operator->FormatTimeInMillisAsSecondsShuffleoperator<< _ZN7testing8internal15GetTimeInMillisEvtm_year_ZNSt6vectorIN7testing12TestPropertyESaIS1_EE5frontEvLIVED_ZNSs16_S_construct_auxIPcEES0_T_S1_RKSaIcESt12__false_typereverse_iterator<__gnu_cxx::__normal_iterator, std::allocator > > >GetMutableTestInfo_ZNK9__gnu_cxx17__normal_iteratorIPcSsEdeEvMSG_DONTROUTE_ZNSt6vectorIN7testing14TestPartResultESaIS1_EE8pop_backEv~_Vector_impl_M_widen_initargsto_int_type_ZNKSt6vectorIN7testing12TestPropertyESaIS1_EE12_M_check_lenEjPKc_M_set_sharableenvironments_ZSt7nothrow_ZNSt12_Vector_baseIPN7testing11EnvironmentESaIS2_EE12_Vector_impl12_M_swap_dataERS5___iter_equals_val >unit_test__ZN9__gnu_cxx17__normal_iteratorIPPN7testing17TestEventListenerESt6vectorIS3_SaIS3_EEEmIEi_ZNKSbIwSt11char_traitsIwESaIwEE4dataEvallocateoperator<< ai_nextParseInt32Flagnew_value_ZN9__gnu_cxx17__normal_iteratorIPcSsEmIEi__is_move_iterator, std::allocator >*>__builtin_strstr_ZNSt6vectorISsSaISsEE9push_backERKSs_IO_write_end~TestCaseNameIs__uninitialized_copy_a_IO_save_basepptrtm_wday_ZN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE3setERKS3_kExponentBitMask_ZNSt11char_traitsIwE7not_eofERKj_ZNSt6vectorIN7testing14TestPartResultESaIS1_EE5frontEv_ZN7testing32ScopedFakeTestPartResultReporterC2ENS0_13InterceptModeEPNS_19TestPartResultArrayE__are_same_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE10_S_minimumEPKSt18_Rb_tree_node_base_ZN7testing8internal18g_init_gtest_countE_ZN7testing8UnitTest4implEva_typetest_part_resultlast_death_test_case__ZNSt12_Vector_baseISsSaISsEE13_M_deallocateEPSsj_ZNK9__gnu_cxx17__normal_iteratorIPcSsEixEi_ZN9__gnu_cxx13new_allocatorIPN7testing11EnvironmentEE7destroyEPS3__ZNKSt6vectorIPcSaIS0_EE8capacityEv_ZNSt11char_traitsIwE12to_char_typeERKjdistance__new_start_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE6_S_keyEPKSt18_Rb_tree_node_baseSetInjectableArgvsos_stack_trace_ZNK9__gnu_cxx17__normal_iteratorIPPN7testing8TestCaseESt6vectorIS3_SaIS3_EEE4baseEv_ZNK9__gnu_cxx13new_allocatorIPcE8max_sizeEvint_type~TestEventListeners_ZN7testing8internal17StreamingListener20AbstractSocketWriter15CloseConnectionEvMSG_PEEKremoveval1val2_ZN7testing8internal24XmlUnitTestResultPrinter29TestPropertiesAsXmlAttributesERKNS_10TestResultEsegmentn_sign_posnactual_message_ZNSt6vectorIPN7testing8TestCaseESaIS2_EE4backEva_key_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE8_S_rightEPKSt18_Rb_tree_node_base_ZNK7testing8internal8FilePath14RemoveFileNameEvwrite_fdrebind, std::allocator > > >captured_fd_ZNSt12_Vector_baseIN7testing12TestPropertyESaIS1_EE13_M_deallocateEPS1_jWait_ZN7testing17TestEventListener18OnTestProgramStartERKNS_8UnitTestEOnTestIterationStartuninitialized_copy*, std::basic_string*>_ZNKSt6vectorIPcSaIS0_EE8max_sizeEv_M_end_ZNSt6vectorIPcSaIS0_EE6insertEN9__gnu_cxx17__normal_iteratorIPS0_S2_EERKS0__ZNSt12_Vector_baseIN7testing8internal9TraceInfoESaIS2_EE19_M_get_Tp_allocatorEvFormatByteiterator_traits_ZNK9__gnu_cxx17__normal_iteratorIPPcSt6vectorIS1_SaIS1_EEE4baseEv_ZSt18_Rb_tree_incrementPKSt18_Rb_tree_node_basekDeathTestReturned_S_copy_chars_ZNKSt6vectorIPcSaIS0_EE5emptyEvtotal_test_count_ZNSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE14_M_fill_insertEN9__gnu_cxx17__normal_iteratorIPS3_S5_EEjRKS3_IsValidXmlCharacter_ZNSt6vectorIPN7testing8TestCaseESaIS2_EEaSERKS4__ZN7testing8internal21ImplicitlyConvertibleIPKvS3_E8MakeFromEv_ZNSt6vectorIN7testing14TestPartResultESaIS1_EE6insertEN9__gnu_cxx17__normal_iteratorIPS1_S3_EEjRKS1__ZN9__gnu_cxx17__normal_iteratorIPN7testing14TestPartResultESt6vectorIS2_SaIS2_EEEpLEiArgumentsstreamable_ZNSs7_M_copyEPcPKcj_ZN7testing8internal10scoped_ptrISt18basic_stringstreamIcSt11char_traitsIcESaIcEEEaSERKS7_signum__Rb_tree_impl_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE10_S_minimumEPSt18_Rb_tree_node_baseColoredPrintfkColorFlag~Environmentsa_sigaction_ZN9__gnu_cxx17__normal_iteratorIPPN7testing8TestCaseESt6vectorIS3_SaIS3_EEEmIEi_IteratorL_ZN7testing8internal10scoped_ptrIKSsE5resetEPS2__ZN7testing8internal26ThreadLocalValueHolderBaseD2Ev_ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EE9push_backERKS2__ZNKSbIwSt11char_traitsIwESaIwEE13find_first_ofEwjstack_sizesi_stimeshard_testsGetNextRandomSeed__arg_ZN9__gnu_cxx17__normal_iteratorIPPcSt6vectorIS1_SaIS1_EEEmIEi_Iter_baseallocator >_ZN7testing10TestResultD2Ev_M_insert_equal_lowerreverse_iterator<__gnu_cxx::__normal_iterator, std::allocator > > >_ZNSt13_Bit_iteratormIEi_ZN7testing15AssertionResultlsIA11_cEERS0_RKT__ZNK7testing8UnitTest4implEv_ZN9__gnu_cxx13new_allocatorISsE9constructEPSsRKSs_ZNK7testing8internal10scoped_ptrINS0_17StreamingListener20AbstractSocketWriterEEdeEv_ZNSt11char_traitsIcE3eofEvfastmap_ZNKSt3setISsSt4lessISsESaISsEE11equal_rangeERKSspthread_key_tmmap_ZNK7testing8UnitTest30reportable_disabled_test_countEvgetaddrinfo_Iter_base, std::allocator >*, false>TestReportablefull_flag__niter_base*>_ZNKSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE5countERKSs_ZNSbIwSt11char_traitsIwESaIwEE6assignEPKwjst_uid__builtin_strrchrstr_valdefault_per_thread_test_part_result_reporter_thousands_sep_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE15_M_destroy_nodeEPSt13_Rb_tree_nodeISsE_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE15_M_insert_lowerEPSt18_Rb_tree_node_baseRKS1__ZN7testing8internal17TestEventRepeater7ReleaseEPNS_17TestEventListenerE_ZNK7testing8internal24InternalRunDeathTestFlag4lineEv__copy_move_bPrintByteSegmentInObjectTo_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE4rendEvInt32_ZNK7testing8internal2RE7patternEv_ZN9__gnu_cxx17__normal_iteratorIPN7testing12TestPropertyESt6vectorIS2_SaIS2_EEEmmEv_ZNSt6vectorISsSaISsEED2Ev_ZNSs7replaceEN9__gnu_cxx17__normal_iteratorIPcSsEES2_PKccopya_test_case_name_ZNSbIwSt11char_traitsIwESaIwEE13_S_copy_charsEPwPKwS5___copy_move_bEscapeXmlAttribute_ForwardIterator_ZNK9__gnu_cxx17__normal_iteratorIPKPN7testing17TestEventListenerESt6vectorIS3_SaIS3_EEE4baseEv_ZNSt6vectorIN7testing12TestPropertyESaIS1_EE5eraseEN9__gnu_cxx17__normal_iteratorIPS1_S3_EE_Bit_reference_ZN7testing8internal24XmlUnitTestResultPrinteraSERKS1_gtest_trace_stack_ZNSt8ios_base4setfESt13_Ios_Fmtflags_ZN7testing8internal12UnitTestImpl20ClearAdHocTestResultEv_ZN7testing8internal15NoExecDeathTestD2Evwords_ZNK7testing8internal10scoped_ptrINS0_16DeathTestFactoryEEdeEvstart_timestamp__ZNKSt17_Rb_tree_iteratorISsEdeEv_ZNKSs7compareEjjPKcj_ZNK7testing8UnitTest6PassedEv_Destroy_aux_ZNKSt6vectorIPN7testing17TestEventListenerESaIS2_EE5beginEvcopy_backward_ZNSt12_Vector_baseIPN7testing8TestInfoESaIS2_EE11_M_allocateEjdestroy_ZNSs6insertEjPKc_ZN7testing8internal10scoped_ptrINS0_16DeathTestFactoryEE5resetEPS2__ZNKSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE6rbeginEv_ZN7testing8internal17StreamingListener20OnTestIterationStartERKNS_8UnitTestEig_help_flagFlagToEnvVar_ZN9__gnu_cxx17__normal_iteratorIPN7testing12TestPropertyESt6vectorIS2_SaIS2_EEEppEia_file_name_ZNKSt6vectorIPN7testing8TestCaseESaIS2_EE5emptyEvwidenF_OWNER_TIDnonfatally_failed_ZN7testing8internal19UniversalPrintArrayEPKcjPSoReactionToSharding__quad_tenable_ZN9__gnu_cxx13new_allocatorIPN7testing8TestInfoEE10deallocateEPS3_j_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE14_M_upper_boundEPSt13_Rb_tree_nodeISsES8_RKSs_ZNSt3setIPKcSt4lessIS1_ESaIS1_EEaSERKS5_file_stat_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE8_M_beginEvgai_strerror__new_finishcopy_backwardtest_case_to_run_countFLAGS_gtest_show_internal_stack_framesnew_allocator_ZNSt6vectorIPN7testing8TestCaseESaIS2_EE6rbeginEvgtest_flag_saver__ZNSt6vectorISsSaISsEE7reserveEjoperator<< kPathSeparatorString_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE8_M_eraseEPSt13_Rb_tree_nodeISsEOnTestEndbitsRemoveTrailingPathSeparator~ScopedTracereverse_iteratoris_attribute_ZNKSt6vectorIiSaIiEE4rendEv_ZN9__gnu_cxx13new_allocatorISt13_Rb_tree_nodeISsEE7destroyEPS2__ZNKSt6vectorIPcSaIS0_EE12_M_check_lenEjPKcdistance__normal_iterator > >wcsncmp_ZNKSt18_Bit_iterator_baseleERKS__ZN9__gnu_cxx14__alloc_traitsISaIN7testing14TestPartResultEEE10deallocateERS3_PS2_j_ZNK7testing8internal8FilePath7IsEmptyEv__normal_iterator > >_ZNK9__gnu_cxx17__normal_iteratorIPPcSt6vectorIS1_SaIS1_EEEdeEv_ZNSt6vectorIPN7testing8TestInfoESaIS2_EE5frontEv_M_right_ZNKSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE4findERKS1___copy_move_a2_ZNK7testing8internal8FilePath27RemoveTrailingPathSeparatorEvbase_name_M_get_insert_hint_unique_pos_ZN7testing8internal15NoExecDeathTestD0Ev_ZN7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEED2Evtowctrans_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE8_M_beginEv_ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EE8_M_eraseEN9__gnu_cxx17__normal_iteratorIPS2_S4_EE_ZNSs2atEj__uninitialized_copy_afilenoRunTearDownTestCase_ZN7testing17TestEventListener13OnTestCaseEndERKNS_8TestCaseE_ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EE4swapERS4__ZN7testing8internal11CmpHelperLEEPKcS2_xxcharoperator- >_S_refcount__digits_ZNKSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE21_M_get_Node_allocatorEv__normal_iterator > >_ZNSbIwSt11char_traitsIwESaIwEE7replaceEN9__gnu_cxx17__normal_iteratorIPwS2_EES6_PKwj__is_normal_iteratorfixture_class_id_ZN7testing8internal27PrettyUnitTestResultPrinter27OnEnvironmentsTearDownStartERKNS_8UnitTestE_ZNSt6vectorIPN7testing8TestCaseESaIS2_EE5eraseEN9__gnu_cxx17__normal_iteratorIPS2_S4_EEvswprintf_Value_ZNSs4_Rep10_M_destroyERKSaIcE_ZN7testing4Test8TestBodyEvUniversalPrinterdetailexpr1expr2_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE28_M_get_insert_hint_equal_posESt23_Rb_tree_const_iteratorISsERKSs__uninit_copy_ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EE15_M_erase_at_endEPS2___are_samefixture_class_id__ZN7testing28FLAGS_gtest_break_on_failureEFLAGS_gtest_print_timeType_IsMove_ZN7testing8internal29PrintFullTestCommentIfPresentERKNS_8TestInfoEoperator<< __copy_move_backward_a__is_normal_iterator_ZNKSt6vectorIN7testing12TestPropertyESaIS1_EEixEjtest_info_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE23_M_get_insert_equal_posERKSs_ZNSt6vectorIiSaIiEE3endEvMutexBase_ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EE6resizeEjS2__ZN7testing14IsNotSubstringEPKcS1_RKSsS3_tv_usec_ZNKSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE3endEvHelpermemmoveFindLastPathSeparatorpair, std::_Rb_tree_iterator >_ZN9__gnu_cxx14__alloc_traitsISaIPN7testing11EnvironmentEEE10deallocateERS4_PS3_j_ZNSbIwSt11char_traitsIwESaIwEE4_Rep8_M_cloneERKS1_j_ZNSt6vectorIPN7testing8TestInfoESaIS2_EE4rendEvCOLOR_DEFAULT_ZNK7testing8internal12UnitTestImpl21reportable_test_countEvto_char_type_ZN9__gnu_cxx13new_allocatorIPN7testing8TestCaseEE7destroyEPS3_length_ZN7testing8internal13CaptureStderrEvwide_c_str_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE16_M_insert_equal_ESt23_Rb_tree_const_iteratorISsERKSs_ZN7testing8internal6String32CaseInsensitiveWideCStringEqualsEPKwS3_operator<<_M_set_leaked_ZNSt6vectorIiSaIiEE15_M_erase_at_endEPi_ZN7testing8internal11CmpHelperGTEPKcS2_xx_M_clonesigset_t_ZNK7testing14TestPartResult11line_numberEvcapacityoperator()<__gnu_cxx::__normal_iterator*, std::vector > > >_ZN7testing8internal26GoogleTestFailureExceptionD0Ev_ZNK9__gnu_cxx17__normal_iteratorIPKN7testing8internal9TraceInfoESt6vectorIS3_SaIS3_EEEmiEi_ZN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE11ValueHolderD2Evsetf_ZN7testing8TestCase19RunTearDownTestCaseEvFileOrDirectoryExists_ZNSbIwSt11char_traitsIwESaIwEE6appendEjw_ZN7testing8internal17TestEventRepeater11OnTestStartERKNS_8TestInfoEthis_fixture_id_ZNK9__gnu_cxx17__normal_iteratorIPKN7testing14TestPartResultESt6vectorIS2_SaIS2_EEEdeEv_ZNKSbIwSt11char_traitsIwESaIwEE11_M_disjunctEPKwsetwhas_tests_to_run_ZNK7testing8internal8FilePath21FindLastPathSeparatorEvsigemptyset_ZNSspLEPKcoperator==_ZNKSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE6_M_endEv_ZNSt16reverse_iteratorIN9__gnu_cxx17__normal_iteratorIPPN7testing11EnvironmentESt6vectorIS4_SaIS4_EEEEEmmEi_ZN9__gnu_cxx17__normal_iteratorIPPN7testing11EnvironmentESt6vectorIS3_SaIS3_EEEmIEiis_nan_ZNKSt12_Vector_baseIiSaIiEE19_M_get_Tp_allocatorEvvalue_compparent_ZN9__gnu_cxx17__normal_iteratorIPN7testing12TestPropertyESt6vectorIS2_SaIS2_EEEpLEi__first_ZN7testing24ValidateTestPropertyNameERKSsRKSt6vectorISsSaISsEECOLOR_RED__copy_move_backward_a2ExecDeathTestoperator<< _ZN7testing8internal17TestEventRepeater22set_forwarding_enabledEb_ZN7testing8internal13ExecDeathTestD2Ev__tmpkRepeatFlag_ZN7testing8internal12UnitTestImplD2Ev_ZNKSs6substrEjjhaystack_ZN7testing8internal12UnitTestImpl19current_test_resultEvkey_type_M_rootExtractSummarymbsrtowcsDefinedTestIter_S_beg_ZN7testing8internal24XmlUnitTestResultPrinter16PrintXmlUnitTestEPSoRKNS_8UnitTestE_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE21_M_insert_equal_lowerERKSsoperator>=number_ZNK7testing8internal12UnitTestImpl22failed_test_case_countEvvalue_str_ZNKSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE11__rb_verifyEvOtherOperand_ZN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE9CreateKeyEv_ZN7testing8internal13PrintStringToERKSsPSo_ZNKSt6vectorIPN7testing8TestInfoESaIS2_EE4dataEvWideCStringEquals_ZNSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE5frontEvkAlsoRunDisabledTestsFlagbasic_ostream_ZN9__gnu_cxx14__alloc_traitsISaISsEE8allocateERS1_j~UnitTestImpl_ZN9__gnu_cxx17__normal_iteratorIPiSt6vectorIiSaIiEEEppEi_S_construct_ZNSt10_Iter_baseIPiLb0EE7_S_baseES0_listeners_ZNK9__gnu_cxx17__normal_iteratorIPKN7testing14TestPartResultESt6vectorIS2_SaIS2_EEEixEi_ZN9__gnu_cxx17__normal_iteratorIPiSt6vectorIiSaIiEEEppEv_ZN7testing8internal11CmpHelperEQEPKcS2_xx_ZNSt6vectorISsSaISsEE5clearEv_ZNKSt3setIPKcSt4lessIS1_ESaIS1_EE11lower_boundERKS1__ZNSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE6rbeginEv_ZN7testing8internal29ParameterizedTestCaseRegistryD2Ev_ZNK9__gnu_cxx17__normal_iteratorIPKPN7testing8TestInfoESt6vectorIS3_SaIS3_EEEixEi__pid_tAbortReason_ConstructkReservedTestCaseAttributes_ZNK7testing8internal10scoped_ptrIKSsEptEv_ZNKSt6vectorISsSaISsEE4backEvint_frac_digits_ZNSt12_Vector_baseIPcSaIS0_EE11_M_allocateEj_ZNK7testing8UnitTest17current_test_caseEv_ZN9__gnu_cxx17__normal_iteratorIPPN7testing8internal29ParameterizedTestCaseInfoBaseESt6vectorIS4_SaIS4_EEEppEi_ZNSbIwSt11char_traitsIwESaIwEE7replaceEN9__gnu_cxx17__normal_iteratorIPwS2_EES6_PKw_ZNKSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE5emptyEv_ZNKSt17_Rb_tree_iteratorIPKcEptEv_ZN9__gnu_cxx17__normal_iteratorIPPN7testing8internal29ParameterizedTestCaseInfoBaseESt6vectorIS4_SaIS4_EEEppEv_ZNSt20__uninitialized_copyILb0EE13__uninit_copyIPN7testing14TestPartResultES4_EET0_T_S6_S5___is_normal_iterator_ZNK7testing8internal10scoped_ptrISt18basic_stringstreamIcSt11char_traitsIcESaIcEEEdeEv__copy_move_b_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE5eraseERKS1_vector >PrintCharAndCodeTo_ZNKSt6vectorIPN7testing11EnvironmentESaIS2_EE3endEv_ZN9__gnu_cxx13new_allocatorIcE7destroyEPcs1_expressionOutputXmlTestInfo_ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EE5clearEv_ZNSt8ios_base9precisionEi_ZN7testing8internal19UniversalPrintArrayEPKwjPSo_ZNSt6vectorIN7testing14TestPartResultESaIS1_EE4dataEv__uninitialized_move_if_noexcept_a >_M_iend_ZNK7testing8internal10scoped_ptrINS0_24InternalRunDeathTestFlagEE3getEvTearDownEnvironmentkDeathTestCaseFiltersi_tidnewline_anchorst_rdev__sigaction_handler_S_empty_rep_storage__copy_move_a2_ZN7testing8UnitTest3RunEviterator_traitsg_argvs_ZN9__gnu_cxx13new_allocatorIPcE7destroyEPS1__ZNSs6assignEPKcExecDeathTestChildMainlocaltime_ZNKSt6vectorIPN7testing11EnvironmentESaIS2_EE8capacityEv_ZNKSbIwSt11char_traitsIwESaIwEE7_M_dataEv_ZN7testing8internal14DeathTestAbortERKSs_ZN7testing8internal14CmpHelperSTRNEEPKcS2_S2_S2_value_param___pfnStreamableToStringold_reporter__ZNSs6resizeEjcTimeInMillis_ZN7testing32ScopedFakeTestPartResultReporterD2Ev_DestroykMaxUlpsmemcmp_ZN7testing8internal18PrintCharAndCodeToIhhEEvT0_PSoforwarding_enabled__M_check_len__is_normal_iterator_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE11lower_boundERKS1___rb_verify_ZN7testing28FLAGS_gtest_throw_on_failureE_S_bin~ScopedFakeTestPartResultReporterint_n_sep_by_space_ZNSt12_Destroy_auxILb0EE9__destroyIPN7testing8internal9TraceInfoEEEvT_S6__ZNKSt6vectorIPN7testing8TestCaseESaIS2_EE2atEj_IO_marker_ZNKSt6vectorIPN7testing11EnvironmentESaIS2_EE8max_sizeEv_ZNK7testing14ExitedWithCodeclEi_ZNK9__gnu_cxx17__normal_iteratorIPPN7testing11EnvironmentESt6vectorIS3_SaIS3_EEEdeEvtest_case_indices__ZN7testing8internal11g_help_flagE_FacetDeathTestOutcome_ZN7testing8internal10scoped_ptrISt18basic_stringstreamIcSt11char_traitsIcESaIcEEE5resetEPS6_print_time__ZNSt6vectorIN7testing14TestPartResultESaIS1_EE18_M_fill_initializeEjRKS1__ZNKSt6vectorIN7testing8internal9TraceInfoESaIS2_EE5beginEv_ZNSs6appendERKSsjjIsNotContainer_ZN7testing8internal10ParseInt32ERKNS_7MessageEPKcPiAssertHelperDataFLAGS_gtest_break_on_failure_Destroy_ZNK9__gnu_cxx13new_allocatorIPN7testing8internal29ParameterizedTestCaseInfoBaseEE7addressERS4__ZNSt12_Vector_baseIPN7testing17TestEventListenerESaIS2_EE12_Vector_impl12_M_swap_dataERS5_re_nsubGetAbsolutePathToOutputFilehas_new_fatal_failure_INTERCEPT_ONLY_CURRENT_THREADiterator_traits_ZNKSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE11lower_boundERKS1__ZNK9__gnu_cxx17__normal_iteratorIPPN7testing17TestEventListenerESt6vectorIS3_SaIS3_EEEdeEvDefaultPerThreadTestPartResultReporter_ZNSt6vectorIPN7testing8TestCaseESaIS2_EE4swapERS4_bytes_last_read_BI1_BI2_ZNKSt12_Vector_baseIN7testing14TestPartResultESaIS1_EE19_M_get_Tp_allocatorEvptr__ZN7testing8UnitTest9listenersEv_ZNK9__gnu_cxx17__normal_iteratorIPPN7testing11EnvironmentESt6vectorIS3_SaIS3_EEE4baseEvai_socktype__is_move_iterator_ZN9__gnu_cxx17__normal_iteratorIPKPN7testing11EnvironmentESt6vectorIS3_SaIS3_EEEppEiPrintFullTestCommentIfPresentwctrans_S_truncscoped_ptr, std::allocator > >_ZN9__gnu_cxx17__normal_iteratorIPKPN7testing11EnvironmentESt6vectorIS3_SaIS3_EEEppEv_ZNKSs7compareEPKc__pad4_ZNKSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE5beginEvset_elapsed_time_ZNK9__gnu_cxx17__normal_iteratorIPPN7testing11EnvironmentESt6vectorIS3_SaIS3_EEEixEi_S_ios_iostate_end_ZN7testing8internal17GetCapturedStderrEvFLAGS_gtest_coloroperator<< ~new_allocator~ThreadLocal_ZN7testing8internal8FilePath22GenerateUniqueFileNameERKS1_S3_PKcwidth_ZNSbIwSt11char_traitsIwESaIwEE4_Rep12_S_empty_repEvreverse_iterator<__gnu_cxx::__normal_iterator > > >_ZN9__gnu_cxx13new_allocatorIwE7destroyEPw_ZNKSt6vectorISsSaISsEE4sizeEv__uninitialized_move_if_noexcept_a >_ZNKSt12_Vector_baseIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE13get_allocatorEvoperator<< strtoll~UnitTestReadReportFailureInUnknownLocation_ZN7testing8internal12UnitTestImpl28CurrentOsStackTraceExceptTopEi__baseInt32FromGTestEnv_ZNK9__gnu_cxx17__normal_iteratorIPKPN7testing8TestCaseESt6vectorIS3_SaIS3_EEEdeEv__is_move_iterator<__gnu_cxx::__normal_iterator > > >user_msgerrnum_ZNK9__gnu_cxx17__normal_iteratorIPPN7testing17TestEventListenerESt6vectorIS3_SaIS3_EEEixEi__copy_move_backward_a2emptyinstance_ZN7testing8internal29ParameterizedTestCaseRegistryaSERKS1_val1_ss__copy_move_b__end_ZN9__gnu_cxx14__alloc_traitsISaIPKcEE10deallocateERS3_PS2_jobject_ZN7testing8internal14CapturedStream11GetFileSizeEP8_IO_FILE_ZN7testing18FLAGS_gtest_repeatE_ZNK9__gnu_cxx17__normal_iteratorIPPN7testing8internal29ParameterizedTestCaseInfoBaseESt6vectorIS4_SaIS4_EEEdeEv__mbstate_t_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE10_S_maximumEPKSt18_Rb_tree_node_baseDeleteSelf___normal_iterator > >_ZNSbIwSt11char_traitsIwESaIwEE7replaceEN9__gnu_cxx17__normal_iteratorIPwS2_EES6_S6_S6_tz_minuteswestkDefaultOutputFile_M_valptr_ZNSt6vectorIN7testing12TestPropertyESaIS1_EE18_M_fill_initializeEjRKS1__ZN7testing8internal17TestEventRepeaterD0Ev_ZNKSt23_Rb_tree_const_iteratorIPKcE13_M_const_castEv_ZNSt16reverse_iteratorIN9__gnu_cxx17__normal_iteratorIPPN7testing11EnvironmentESt6vectorIS4_SaIS4_EEEEEpLEitype_param_S_internal_ZN7testing8internal10scoped_ptrISsE7releaseEv_ZNK9__gnu_cxx17__normal_iteratorIPN7testing8internal9TraceInfoESt6vectorIS3_SaIS3_EEEdeEvconst_referenceOnEnvironmentsTearDownStart__uninit_copy_ZN9__gnu_cxx14__alloc_traitsISaIPN7testing17TestEventListenerEEE10_S_on_swapERS4_S6__ZNK9__gnu_cxx13new_allocatorIN7testing12TestPropertyEE7addressERKS2_output_dir_ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EE3endEvset_last_death_test_message_ZNKSt3setIPKcSt4lessIS1_ESaIS1_EE5beginEv_ZN7testing16AssertionSuccessEvport_num_COLOR_YELLOWrebindreverse_iterator<__gnu_cxx::__normal_iterator > > >_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE4findERKSsreservedeath_test_index_ZN9__gnu_cxx17__normal_iteratorIPN7testing8internal9TraceInfoESt6vectorIS3_SaIS3_EEEppEi_ZNK9__gnu_cxx17__normal_iteratorIPKPN7testing8TestCaseESt6vectorIS3_SaIS3_EEEixEi_M_disjunct_ZNKSbIwSt11char_traitsIwESaIwEE12find_last_ofEwj_M_leak_ZNSs7_M_leakEv~Arguments_ZN9__gnu_cxx17__normal_iteratorIPN7testing8internal9TraceInfoESt6vectorIS3_SaIS3_EEEppEv_ZNSt6vectorIiSaIiEE6insertEN9__gnu_cxx17__normal_iteratorIPiS1_EERKierrors_str__is_move_iteratorfloatfieldg_executable_path_ZNKSt12_Vector_baseIPN7testing17TestEventListenerESaIS2_EE13get_allocatorEvForEach, void (*)(testing::TestInfo*)>_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE15_M_insert_equalERKSsrm_so_ZNSt6vectorIPcSaIS0_EE4swapERS2_elapsedfclose_ZN7testing8internal8FilePath11ConcatPathsERKS1_S3__S_unitbuf_ZNK9__gnu_cxx17__normal_iteratorIPPN7testing8internal29ParameterizedTestCaseInfoBaseESt6vectorIS4_SaIS4_EEEixEi_ZNKSt4lessIPKcEclERKS1_S4_kHexEscapeFLAGS_gtest_internal_run_death_testAssertionSuccessright_ZNKSbIwSt11char_traitsIwESaIwEEixEj_ZNSt6vectorIPcSaIS0_EE6insertEN9__gnu_cxx17__normal_iteratorIPS0_S2_EEjRKS0__ZNKSs2atEj_ZN7testing8internal10scoped_ptrINS0_24InternalRunDeathTestFlagEE7releaseEv_ZNK7testing8internal13FloatingPointIdE4bitsEv_ZNKSbIwSt11char_traitsIwESaIwEE6_M_repEvallocatorline__ZNKSt6vectorIN7testing14TestPartResultESaIS1_EE5emptyEvoperator< , std::allocator >_ZN9__gnu_cxx14__alloc_traitsISaISt13_Rb_tree_nodeISsEEE17_S_select_on_copyERKS3__ZNK9__gnu_cxx17__normal_iteratorIPN7testing8internal9TraceInfoESt6vectorIS3_SaIS3_EEEixEioriginal_dir_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEED2Ev_ZN7testing8internal7PrintToEwPSo_ZNSbIwSt11char_traitsIwESaIwEE6rbeginEv_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE15_M_insert_lowerEPSt18_Rb_tree_node_baseRKSsMessage_M_parent_ZNKSt6vectorIPN7testing8TestInfoESaIS2_EE5beginEv_ZNKSbIwSt11char_traitsIwESaIwEE6rbeginEv6ldiv_t_ZNKSt17_Rb_tree_iteratorIPKcEeqERKS2_EmptyTestEventListener_Destroyaddrinfoiterator_ZNKSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE14_M_lower_boundEPKSt13_Rb_tree_nodeISsES9_RKSsmemset_ZNK9__gnu_cxx13new_allocatorIPN7testing8internal29ParameterizedTestCaseInfoBaseEE8max_sizeEv_M_length_ZN7testing8internal11CmpHelperGEEPKcS2_xxchar_traitsFLAGS_gtest_random_seed_ZN9__gnu_cxx14__alloc_traitsISaIN7testing12TestPropertyEEE10deallocateERS3_PS2_jfactoryregex__Setfill_ZNKSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE4backEvreverse_iterator >pthread_mutex_init_ZNKSs9_M_ibeginEv_ZN7testing8internal6String28CaseInsensitiveCStringEqualsEPKcS3_insert_ZN7testing8internal17TestEventRepeater13OnTestCaseEndERKNS_8TestCaseE__miter_baseTypeWithSize<4u>_ZNSt12_Vector_baseISsSaISsEE19_M_get_Tp_allocatorEv_ZNSt3setIPKcSt4lessIS1_ESaIS1_EE6insertERKS1__ZN7testinglsERSoRKNS_14TestPartResultEHasOneFailureCmpHelperSTREQ_ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EE8pop_backEvdefined_test_names__ZNK7testing10TestResult15test_propertiesEvCmpHelperSTRCASENE_ZN7testing8UnitTestD2Ev_ZNSt11char_traitsIwE2ltERKwS2__ZN7testing18FLAGS_gtest_outputE_Iter_equals_valexit_code__ZNSt6vectorIiSaIiEE7reserveEj_ZN9__gnu_cxx17__normal_iteratorIPKN7testing14TestPartResultESt6vectorIS2_SaIS2_EEEppEi_Ios_SeekdirListTestsMatchingFilter_ZNSt6vectorIN7testing14TestPartResultESaIS1_EE6insertEN9__gnu_cxx17__normal_iteratorIPS1_S3_EERKS1_rebind, std::allocator > >_ZN7testing8internal37FormatCompilerIndependentFileLocationEPKci_ZN9__gnu_cxx17__normal_iteratorIPKN7testing14TestPartResultESt6vectorIS2_SaIS2_EEEppEvGenerateUniqueFileName_ZNKSt6vectorISsSaISsEE2atEjchar_traitskMaxBiggestInt__builtin_puts_ZN7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEE11ValueHolder7pointerEvoutput_name__addressoffile_size_ZNSt8ios_base5widthEi_ZN7testing8internal12UnitTestImpl23ClearNonAdHocTestResultEv_ZNSt6vectorIPN7testing8TestInfoESaIS2_EE14_M_fill_insertEN9__gnu_cxx17__normal_iteratorIPS2_S4_EEjRKS2___alloc_traits >GetThreadCount_ZN7testing8UnitTest14RecordPropertyERKSsS2_~GTestMutexLock_M_dataplusallocator__uninitialized_move_if_noexcept_a >_ZNSt6vectorIN7testing12TestPropertyESaIS1_EE7reserveEj~basic_ostreamequal_range_ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EE6insertEN9__gnu_cxx17__normal_iteratorIPS2_S4_EERKS2_plural_form_M_predinternal_ZN9__gnu_cxx14__alloc_traitsISaIPN7testing11EnvironmentEEE10_S_on_swapERS4_S6__ZNK7testing8internal12UnitTestImpl11GetTestCaseEi_M_left__builtin_putcharnothrow_t__destroyTestEventRepeater__builtin_fputsnew_test_case_ZNK9__gnu_cxx13new_allocatorIPN7testing17TestEventListenerEE8max_sizeEv_ZNKSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EEixEjkDeathTestLivedparameterized_tests_registered_ldiv_t_ZNKSs13find_first_ofEPKcjForEach, void (*)(testing::TestCase*)>_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE5eraseESt23_Rb_tree_const_iteratorISsE_ZNSs18_S_construct_aux_2EjcRKSaIcE_ZN7testing10TestResult20ValidateTestPropertyERKSsRKNS_12TestPropertyE_Vector_base >INTERCEPT_ALL_THREADSva_listinfoline_number_ZN7testing8TestInfoC2ERKSsS2_PKcS4_PKvPNS_8internal15TestFactoryBaseEShouldRunTestOnShard_S_synced_with_stdioInt32FromEnvOrDieIsEmptyTestFailedpositive_sign_ZN9__gnu_cxx13new_allocatorIcE9constructEPcRKcshard_index_env__lockmkstempKilledBySignal__in_chrg_ZN7testing8internal27PrettyUnitTestResultPrinterD0Evclone_ZNSbIwSt11char_traitsIwESaIwEE6appendERKS2__ZNSt11char_traitsIwE11to_int_typeERKw__normal_iterator, std::allocator > >_ZNKSt6vectorIN7testing8internal9TraceInfoESaIS2_EE14_M_range_checkEj_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE8_M_eraseEPSt13_Rb_tree_nodeIS1_Estatement__ZN7testing8internal13ExecDeathTest10AssumeRoleEv__builtin_strchr_ZN9__gnu_cxx14__alloc_traitsISaIPcEE17_S_select_on_copyERKS2_kFatalFailuretest_idMSG_CMSG_CLOEXEC_ZNK9__gnu_cxx17__normal_iteratorIPSsSt6vectorISsSaISsEEEdeEvGetEnvchild_pid___miter_basescoped_ptr_ZNSt12_Vector_baseIiSaIiEE19_M_get_Tp_allocatorEv~AssertionResultRegisterTests_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE29_M_get_insert_hint_unique_posESt23_Rb_tree_const_iteratorIS1_ERKS1__ZNSt6vectorIPN7testing11EnvironmentESaIS2_EE6insertEN9__gnu_cxx17__normal_iteratorIPS2_S4_EEjRKS2__ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EE5eraseEN9__gnu_cxx17__normal_iteratorIPS2_S4_EE_ZNK7testing8TestCase12elapsed_timeEv_ZNSs5clearEvSetUpEnvironmentin_color_moderange_ZNK9__gnu_cxx13new_allocatorIN7testing14TestPartResultEE8max_sizeEv_M_lower_bound_ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EE8_M_eraseEN9__gnu_cxx17__normal_iteratorIPS2_S4_EE__ptrContainer_ZNKSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE4sizeEvStreamingListener_ZN7testing8internal17TestEventRepeater6AppendEPNS_17TestEventListenerECreateKey__copy_move_b_ZN7testing8internal12UnitTestImplC2EPNS_8UnitTestEoperator<< _ZNSt3setISsSt4lessISsESaISsEE11equal_rangeERKSs_ZNSt6vectorIN7testing12TestPropertyESaIS1_EEixEj_ZNKSt6vectorISsSaISsEE5frontEv_ZNSt12_Vector_baseIPN7testing11EnvironmentESaIS2_EE17_M_create_storageEj_ZN7testing8internal13FloatingPointIdE24SignAndMagnitudeToBiasedERKyxmloutThreadLocal > >_ZN7testing8internal17Int32FromGTestEnvEPKci_ZNKSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE14_M_upper_boundEPKSt13_Rb_tree_nodeIS1_ESB_RKS1__Predicateiterationvector >_ZN7testing8internal35HandleExceptionsInMethodIfSupportedINS_4TestEvEET0_PT_MS4_FS3_vEPKc_ZNK7testing8internal10scoped_ptrINS0_17StreamingListener20AbstractSocketWriterEE3getEv_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE5eraseESt17_Rb_tree_iteratorIS1_E_ZN7testing15AssertionResultC2ERKS0__ZNSbIwSt11char_traitsIwESaIwEE5eraseEN9__gnu_cxx17__normal_iteratorIPwS2_EES6_string_value__c1__c2__alloc_traits >_ZNKSt6vectorIPN7testing8TestInfoESaIS2_EE14_M_range_checkEj_ZNK9__gnu_cxx17__normal_iteratorIPSsSt6vectorISsSaISsEEEixEi_ZN9__gnu_cxx14__alloc_traitsISaIPN7testing8TestCaseEEE8max_sizeERKS4__ZN9__gnu_cxx14__alloc_traitsISaISt13_Rb_tree_nodeISsEEE8max_sizeERKS3__M_finishactual_predicate_valuewcstof_ZN7testing8internal17StreamingListener13OnTestCaseEndERKNS_8TestCaseE_ZNK7testing8internal12UnitTestImpl17current_test_caseEvwcstokwcstol_ZNKSs16find_last_not_ofERKSsj_ZNKSbIwSt11char_traitsIwESaIwEE6lengthEv_ZN9__gnu_cxx13new_allocatorIPKcE9constructEPS2_RKS2_operator== >iterator_typeInitDeathTestSubprocessControlInfo_S_failbit__normal_iterator__ch_ZN7testing8internal23DefaultDeathTestFactory6CreateEPKcPKNS0_2REES3_iPPNS0_9DeathTestE_vptr.DeathTest_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE14_M_create_nodeERKS1__ZN7testing29FLAGS_gtest_stack_trace_depthESOCK_SEQPACKETGetElementOrtest_to_run_count_ZN9__gnu_cxx14__alloc_traitsISaIPN7testing8TestCaseEEE10deallocateERS4_PS3_j_ZN7testing8internal35DefaultGlobalTestPartResultReporteraSERKS1__ZN7testing13PrintToStringIPKcEESsRKT___int32_t__normal_iterator > >kMaxStackAlignment_ZN9__gnu_cxx13new_allocatorISt13_Rb_tree_nodeIPKcEE7destroyEPS4_operator<< UnshuffleTests_ZNSt6vectorIN7testing14TestPartResultESaIS1_EE9push_backERKS1__ZNK7testing8internal12UnitTestImpl17gtest_trace_stackEvpthread_key_deletest_mtimuncaptured_fd__ZN7testing8internal17StreamingListener20AbstractSocketWriter6SendLnERKSs_ZNSt6vectorISsSaISsEEixEjtm_zone_Bit_type_ZN7testing8UnitTestaSERKS0__ZNKSt12_Vector_baseISsSaISsEE13get_allocatorEv_ZNSt6vectorIPN7testing11EnvironmentESaIS2_EE5beginEv_ZNSt12_Vector_baseIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE19_M_get_Tp_allocatorEv_ZNSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE4backEv_ZNSs5eraseEN9__gnu_cxx17__normal_iteratorIPcSsEE__distance_ZN7testing8internal9Arguments11AddArgumentEPKcclose_ZNSt6vectorIPcSaIS0_EE6resizeEjS0__ZNKSt12_Vector_baseIN7testing8internal9TraceInfoESaIS2_EE13get_allocatorEvfunctorVerifyRegisteredTestNamesFormatCountableNounPrintBytesInObjectTo_ZN7testing15AssertionResultlsIA7_cEERS0_RKT_PrintCharAndCodeTo_ZNSt6vectorIPN7testing11EnvironmentESaIS2_EE6resizeEjS2__ZN7testing8internal11CmpHelperLTEPKcS2_xx__is_move_iteratorbinary_ZNK7testing8TestInfo10should_runEv_ZN7testing8internal11ScopedTraceaSERKS1_rebindEscapeXmlFormatIntWidth2_ZNK9__gnu_cxx17__normal_iteratorIPKN7testing8internal9TraceInfoESt6vectorIS3_SaIS3_EEEptEvallocator_ZNSt12_Vector_baseIN7testing12TestPropertyESaIS1_EE17_M_create_storageEj__uninitialized_copy_a_ZNKSt6vectorIN7testing14TestPartResultESaIS1_EE4backEv_Rb_tree_node, std::allocator > >_ZNSt12_Vector_baseIN7testing14TestPartResultESaIS1_EE13_M_deallocateEPS1_jcopy_backwardStatStruct__pthread_mutex_sGetInstance_S_construct_aux_2skip_count_ZN7testing8internal25ReportInvalidTestCaseTypeEPKcS2_ifile_name__ZNK7testing10TestResult16total_part_countEvsa_familyFLAGS_gtest_filter_ZNSt6vectorIPcSaIS0_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS0_S2_EERKS0_shard_index_ZNSt6vectorIN7testing14TestPartResultESaIS1_EE5beginEv_ZN9__gnu_cxx17__normal_iteratorIPN7testing12TestPropertyESt6vectorIS2_SaIS2_EEEmIEi__dso_handle_ZN7testing8internal18CmpHelperSTRCASEEQEPKcS2_S2_S2__ZNK9__gnu_cxx17__normal_iteratorIPKPN7testing11EnvironmentESt6vectorIS3_SaIS3_EEEplEi_ZN7testing8internal17TestEventRepeater16OnTestProgramEndERKNS_8UnitTestEtime_t_Alloc_hider_ZNSs10_S_compareEjj_ZNK9__gnu_cxx17__normal_iteratorIPiSt6vectorIiSaIiEEEmiEi_ZNSt6vectorIPN7testing11EnvironmentESaIS2_EE5eraseEN9__gnu_cxx17__normal_iteratorIPS2_S4_EE_ZNSt6vectorIN7testing12TestPropertyESaIS1_EE8_M_eraseEN9__gnu_cxx17__normal_iteratorIPS1_S3_EES7_a_current_test_case_ZNSt6vectorIN7testing14TestPartResultESaIS1_EE4swapERS3_for_each<__gnu_cxx::__normal_iterator >, void (*)(testing::TestCase*)>_ZNKSt12_Vector_baseIPN7testing8TestInfoESaIS2_EE19_M_get_Tp_allocatorEv_ZNSt6vectorIPN7testing8TestCaseESaIS2_EE15_M_erase_at_endEPS2__ZNK7testing8TestCase14test_info_listEvRemoveInvalidXmlCharactersnew_allocator >_ZNKSt13_Bit_iterator13_M_const_castEv_ZNSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE14_M_fill_assignEjRKS3__ZN7testing32ScopedFakeTestPartResultReporteraSERKS0_ForEach, void (*)(testing::TestEventListener*)>_ZNKSt6vectorIPN7testing17TestEventListenerESaIS2_EE14_M_range_checkEj_ZNSt12_Vector_baseISsSaISsEE17_M_create_storageEj_ZNKSs17find_first_not_ofERKSsj_ZN9__gnu_cxx13new_allocatorISsE7destroyEPSs7lldiv_tregs_allocated_ZN9__gnu_cxx17__normal_iteratorIPiSt6vectorIiSaIiEEEmmEi_ZN7testing18TestEventListeners23SetDefaultResultPrinterEPNS_17TestEventListenerErandom_access_iterator_tag_M_offset_ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EE4dataEv_ZN9__gnu_cxx17__normal_iteratorIPiSt6vectorIiSaIiEEEmmEvuninitialized_copy_ZNK7testing8TestInfo10type_paramEvint_p_cs_precedes_ZN7testing8internal18PrintCharAndCodeToIwwEEvT0_PSo_ZNKSt6vectorIPN7testing8TestCaseESaIS2_EE6rbeginEv__uninitialized_copy_a<__gnu_cxx::__normal_iterator >, testing::internal::TraceInfo*, testing::internal::TraceInfo>bsearch_ZNKSt6vectorIPN7testing8TestCaseESaIS2_EE14_M_range_checkEjshould_shard_ZNKSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE12_M_check_lenEjPKc_ZNK9__gnu_cxx17__normal_iteratorIPKSsSt6vectorISsSaISsEEEplEimon_grouping_M_deallocate_Node_allocator_ZN9__gnu_cxx17__normal_iteratorIPPN7testing8internal29ParameterizedTestCaseInfoBaseESt6vectorIS4_SaIS4_EEEmmEiParseGoogleTestFlagsOnlyImpl_ZNKSs4rendEv_ZNKSbIwSt11char_traitsIwESaIwEE5rfindEwj_ZN9__gnu_cxx17__normal_iteratorIPPN7testing8internal29ParameterizedTestCaseInfoBaseESt6vectorIS4_SaIS4_EEEmmEv_ZNSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE5eraseEN9__gnu_cxx17__normal_iteratorIPS3_S5_EETestCasePassed_offset_ZN7testing28FLAGS_gtest_death_test_styleE_M_replace_safe_ZNK7testing8internal12UnitTestImpl22test_case_to_run_countEvGetCapturedStdout__numeric_traits_integer_ZN7testing8internal24HasNewFatalFailureHelperD2Ev_ZNSbIwSt11char_traitsIwESaIwEE6insertEN9__gnu_cxx17__normal_iteratorIPwS2_EEjw_M_beginbasic_istream >_ZN7testing8internal38DefaultPerThreadTestPartResultReporteraSERKS1___kindlow_byte_Destroy >_old_offsetfile_namembstowcs_ZNSt6vectorIN7testing14TestPartResultESaIS1_EE15_M_erase_at_endEPS1__ZNSt6vectorIPN7testing11EnvironmentESaIS2_EE4rendEv_ZNKSt12_Vector_baseIPN7testing11EnvironmentESaIS2_EE13get_allocatorEvrepeat_ZN9__gnu_cxx14__alloc_traitsISaIN7testing8internal9TraceInfoEEE8max_sizeERKS4__ZNSs7replaceEjjPKcFormatBooloperator<< basic_ios >_ZNKSt6vectorIN7testing8internal9TraceInfoESaIS2_EE3endEvuninitialized_copy~basic_streambuf_ZN9__gnu_cxx14__alloc_traitsISaIPKcEE7destroyERS3_PS2__ZNKSt18_Bit_iterator_baseeqERKS__cur_column_ZN7testing4Test18HasNonfatalFailureEvGetArgvsForDeathTestChildProcessoperator<< spawnedthrow_on_failure_ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EE3endEvFormatEpochTimeInMillisAsIso8601_ZNKSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE11_M_leftmostEv_ZNSt11char_traitsIcE6lengthEPKcFormatTestCount_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE23_M_get_insert_equal_posERKS1__ZN7testing8internal7PrintToEaPSo_S_construct_auxOnTestProgramEndreverse_iterator<__gnu_cxx::__normal_iterator > > >_M_value_ZNKSt6vectorIN7testing14TestPartResultESaIS1_EE4sizeEvpthread_self_ZN7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEE11ValueHolderD0Evsizelist_tests~_Rb_tree_implextension_Tp1ShouldRunTestCase_ZNK7testing10TestResult16death_test_countEv__pred_iter_ZN9__gnu_cxx14__alloc_traitsISaIN7testing14TestPartResultEEE17_S_select_on_copyERKS3__ZNK7testing8internal24InternalRunDeathTestFlag4fileEv__copy_move_b_ZNSbIwSt11char_traitsIwESaIwEE12_M_leak_hardEv__destroyset_spawned_ZNKSt6vectorIPN7testing17TestEventListenerESaIS2_EE5emptyEv_ZNSt6vectorIPN7testing8TestCaseESaIS2_EE8pop_backEv__copy_move_a2exitGTEST_INFOtime_structFileNo_ZN7testing8internal14CapturedStreamaSERKS1_key_compDefaultPrintNonContainerTo_ZN9__gnu_cxx14__alloc_traitsISaIPN7testing8internal29ParameterizedTestCaseInfoBaseEEE8max_sizeERKS5__ZNSt6vectorIiSaIiEE8pop_backEv_ZN9__gnu_cxx24__numeric_traits_integerImE8__digitsE_ZNSt6vectorIiSaIiEE4backEvcopyvalue_messageGTEST_FATAL_ZNKSs4_Rep12_M_is_leakedEv_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE11lower_boundERKSs_ZN7testing8TestCase10TestFailedEPKNS_8TestInfoEoperator[]_ZN7testing8internal24XmlUnitTestResultPrinter19IsValidXmlCharacterEc_ZNSt6vectorIPN7testing11EnvironmentESaIS2_EE4swapERS4__ZN7testing10TestResult5ClearEv_ZN9__gnu_cxx17__normal_iteratorIPKPN7testing11EnvironmentESt6vectorIS3_SaIS3_EEEmmEi_ZNK9__gnu_cxx13new_allocatorIPKcE7addressERKS2_strncmp_ZNKSs16find_last_not_ofEPKcjj__n2_ZN9__gnu_cxx17__normal_iteratorIPKPN7testing11EnvironmentESt6vectorIS3_SaIS3_EEEmmEvp_cs_precedeswint_t_ZNK7testing8internal24InternalRunDeathTestFlag8write_fdEv__cxa_guard_releasePrintCharsAsStringTo_ZNSt6vectorIN7testing12TestPropertyESaIS1_EE5eraseEN9__gnu_cxx17__normal_iteratorIPS1_S3_EES7__ZN7testing8internal27PrettyUnitTestResultPrinter25OnEnvironmentsTearDownEndERKNS_8UnitTestE_ZNSt12_Vector_baseIiSaIiEE12_Vector_impl12_M_swap_dataERS2_mblen__blkcnt_t__are_samebasic_iosGetBoolAssertionFailureMessage_ZN7testing8internal23DefaultDeathTestFactoryD2Evoperator<< decimal_pointkey_compareIsDirconnect_S_select_on_copy_ZNKSbIwSt11char_traitsIwESaIwEE8capacityEv_ZN7testing28FLAGS_gtest_catch_exceptionsE__uninitialized_copy_a_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE11_M_get_nodeEv_ZNSt6vectorIPN7testing8TestInfoESaIS2_EE4dataEv_ZN7testing8internal11ScopedTraceC2EPKciRKNS_7MessageE__nlink_tUniversalPrintexpected_value_ZN7testing8internal27PrettyUnitTestResultPrinter13OnTestCaseEndERKNS_8TestCaseE_ZNKSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE4sizeEv_ZN9__gnu_cxx14__alloc_traitsISaIN7testing12TestPropertyEEE7destroyERS3_PS2__S_ios_fmtflags_end_ZNKSbIwSt11char_traitsIwESaIwEE4findERKS2_jAssertionFailure_ZNSt6vectorIiSaIiEE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPiS1_EERKi_M_c__niter_base_ZNSt12_Vector_baseIPN7testing8TestInfoESaIS2_EE12_Vector_impl12_M_swap_dataERS5__ZNSt16reverse_iteratorIN9__gnu_cxx17__normal_iteratorIPPN7testing11EnvironmentESt6vectorIS4_SaIS4_EEEEEmIEi~scoped_ptr_M_n_M_p_ZNSt10_Iter_baseIPN7testing12TestPropertyELb0EE7_S_baseES2__M_t_ZNKSbIwSt11char_traitsIwESaIwEE8max_sizeEv_ZNKSt6vectorISsSaISsEEixEjMakeFileName_ZNKSt5ctypeIcE5widenEc_M_set_length_and_sharable_ZNSbIwSt11char_traitsIwESaIwEE7replaceEN9__gnu_cxx17__normal_iteratorIPwS2_EES6_NS4_IPKwS2_EES9___next_Rb_tree_const_iterator~_Vector_base_ZNKSbIwSt11char_traitsIwESaIwEE5beginEv__pfa_line_ZNSt11char_traitsIwE6lengthEPKw_ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EE6insertEN9__gnu_cxx17__normal_iteratorIPS2_S4_EEjRKS2__ZNKSt3setISsSt4lessISsESaISsEE8max_sizeEv_ZN7testing8TestCase14set_should_runEb_ZN9__gnu_cxx17__normal_iteratorIPN7testing8internal9TraceInfoESt6vectorIS3_SaIS3_EEEmmEi_ZN9__gnu_cxx17__normal_iteratorIPN7testing8internal9TraceInfoESt6vectorIS3_SaIS3_EEEmmEvdisabled_test_count_M_dataintercept_mode~TestCase_ZNKSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE8capacityEvexpected_predicate_value_IO_buf_endshort unsigned int_ZN9__gnu_cxx17__normal_iteratorIPiSt6vectorIiSaIiEEEpLEi_IO_backup_base_ZNSs6appendEPKcj_ZNSs12_S_constructIPcEES0_T_S1_RKSaIcESt20forward_iterator_tagTestPartFatallyFailed_ZN7testing11Environment8TearDownEv_ZNK7testing8internal10scoped_ptrISsE3getEv_ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EE8_M_eraseEN9__gnu_cxx17__normal_iteratorIPS2_S4_EES8_key_reportable_disabled_test_count_M_create_storageconstruct_ZNSt6vectorIPN7testing8TestInfoESaIS2_EE5beginEv__copy_move_a2_ZN7testing8internal6String23EndsWithCaseInsensitiveERKSsS3__ZN9__gnu_cxx13new_allocatorIPN7testing17TestEventListenerEE9constructEPS3_RKS3_iterator_traits_ZN9__gnu_cxx17__normal_iteratorIPPN7testing8internal29ParameterizedTestCaseInfoBaseESt6vectorIS4_SaIS4_EEEpLEi_ZNKSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE8max_sizeEv_ZN7testing8internal13CaptureStdoutEv__normal_iterator > >StringFromGTestEnv__s2_M_insert_equal__ZNKSs17find_first_not_ofEPKcjj_S_ios_seekdir_end_ZN7testing8internal35FLAGS_gtest_internal_run_death_testE_M_disposeGetCurrentOsStackTraceExceptTopreverse_iterator<__gnu_cxx::__normal_iterator, std::allocator >*, std::vector, std::allocator >, std::allocator, std::allocator > > > > >ios_base__copy_move_backward_a2_ZNSt17_Rb_tree_iteratorISsEppEv_shortbuf_ZN9__gnu_cxx14__alloc_traitsISaIPN7testing17TestEventListenerEEE8allocateERS4_j_ZNSt6vectorIPN7testing11EnvironmentESaIS2_EEaSERKS4_kDisableTestFilter_S_goodbitn_sep_by_space_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE14_M_create_nodeERKSs_M_insert_timespecAssertHelper_ZNKSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE5countERKS1__ZNSt12_Vector_baseIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE12_Vector_impl12_M_swap_dataERS6__ZN9__gnu_cxx14__alloc_traitsISaIPN7testing17TestEventListenerEEE10deallocateERS4_PS3_j_ZNKSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE4sizeEvTypeWithSize<8u>kTestsuites_vptr.TestPartResultReporterInterface_ZNSt6vectorIN7testing14TestPartResultESaIS1_EE8_M_eraseEN9__gnu_cxx17__normal_iteratorIPS1_S3_EES7__ZNK9__gnu_cxx13new_allocatorISt13_Rb_tree_nodeISsEE7addressERS2_this_test_name_Destroy*>_ZNSt6vectorIiSaIiEE5eraseEN9__gnu_cxx17__normal_iteratorIPiS1_EES5__ZNSt6vectorIN7testing12TestPropertyESaIS1_EE14_M_fill_assignEjRKS1_ChopLowBits_ZN7testing8internal13ColoredPrintfENS0_10GTestColorEPKczFDOpenIsNormalizableWhitespaceelapsed_timeParseNaturalNumber_ZNKSbIwSt11char_traitsIwESaIwEE4findEPKwjjTEST_THREW_EXCEPTION_ZNSt6vectorIN7testing14TestPartResultESaIS1_EEaSERKS3_FormatCxxExceptionMessage_ZN7testing8internal24XmlUnitTestResultPrinter13EscapeXmlTextEPKcnegative_signoperator delete []__miter_basebegin_string_quoteoperator!= >__copy_move_a2showpointtermdouble_ZNK7testing8UnitTest17current_test_infoEvlock__destroy_ZN7testing18TestEventListeners7ReleaseEPNS_17TestEventListenerE_ZNK9__gnu_cxx13new_allocatorIPN7testing8TestInfoEE7addressERS3__ZN7testing22EmptyTestEventListener27OnEnvironmentsTearDownStartERKNS_8UnitTestEkProtobufOneLinerMaxLength_ZN9__gnu_cxx17__normal_iteratorIPN7testing12TestPropertyESt6vectorIS2_SaIS2_EEEmmEiset_statusresult__ZN7testing8internal13FloatingPointIdE8InfinityEvCmpHelperEQallowed_names_ZN9__gnu_cxx14__alloc_traitsISaIPN7testing17TestEventListenerEEE7destroyERS4_PS3__ZNK7testing14KilledBySignalclEi_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE5beginEvresults_ZNK9__gnu_cxx17__normal_iteratorIPKPN7testing17TestEventListenerESt6vectorIS3_SaIS3_EEEmiEioperator<< _ZNK7testing15AssertionResult15failure_messageEvuse_forklesselement_namefatally_failedallocatorStringStreamToStringFailed_ZN7testing8internal29ParseInternalRunDeathTestFlagEvGeneratecopy_ZNK9__gnu_cxx13new_allocatorIN7testing12TestPropertyEE8max_sizeEvpassed_ZN7testing8internal17TestEventRepeater9OnTestEndERKNS_8TestInfoE_ZNKSt13_Bit_iteratordeEv_ZN7testing8internal20SingleFailureCheckerD2Evtuple<>case_listcondition_ZN7testing8internal10scoped_ptrISsE5resetEPSs_ZN7testing8internal5MutexD2Ev~vector_ZN9__gnu_cxx14__alloc_traitsISaIPN7testing8internal29ParameterizedTestCaseInfoBaseEEE7destroyERS5_PS4__ZNSt6vectorIPN7testing8TestCaseESaIS2_EE5eraseEN9__gnu_cxx17__normal_iteratorIPS2_S4_EES8_mbtowccopy_backward_ZNSs4rendEv__cxa_end_catch__normal_iterator > >_ZNSt12_Vector_baseIPN7testing8TestCaseESaIS2_EE19_M_get_Tp_allocatorEv__is_move_iterator_ZN9__gnu_cxx17__normal_iteratorIPKPN7testing11EnvironmentESt6vectorIS3_SaIS3_EEEpLEi_ZNSs7replaceEjjRKSsjjCmpHelperGE_ZN7testing8internal12UnitTestImpl32SuppressTestEventsIfInSubprocessEvmax_ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EE18_M_fill_initializeEjRKS2___compar_fn_t__copy_move_backward_a*, std::basic_string*>CmpHelperGT_ZN7testing8internal24HasNewFatalFailureHelperaSERKS1_parent_ldivtable_sizetotal_shardsholder__pid_type__pathGTestColoroperator()<__gnu_cxx::__normal_iterator > >_ZN7testing8internal26ThreadLocalValueHolderBaseD0Evoperator<< _ZN7testing8internal14CapturedStream17GetCapturedStringEv_ZNSt6vectorIN7testing12TestPropertyESaIS1_EE4rendEv__align__alloc_traits >_ZN7testing17TestEventListener22OnEnvironmentsSetUpEndERKNS_8UnitTestEiterator_traits_ZNSt11char_traitsIcE11eq_int_typeERKiS2__ZN9__gnu_cxx13new_allocatorISsE8allocateEjPKv_ZNKSt13_Bit_iteratorixEi_ZN9__gnu_cxx13new_allocatorIPN7testing11EnvironmentEE8allocateEjPKvstdoutflush >_ZNKSt6vectorISsSaISsEE14_M_range_checkEjmutex_ZN7testing8internal12UnitTestImpl23ListTestsMatchingFilterEv_ZNSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE5beginEv~MessageSetValue_ZNK7testing14TestPartResult17nonfatally_failedEv_ZN7testing8internal15ParseStringFlagEPKcS2_PSs~NoExecDeathTest_ZNSt6vectorIPN7testing8TestInfoESaIS2_EE7reserveEj_ZNSs6assignERKSs_ZNSs6appendEjc_ZN7testing8internal18OsStackTraceGetter16UponLeavingGTestEvregistered___normal_iterator > >_ZNSs4_Rep8_M_cloneERKSaIcEj_ZN7testing23FLAGS_gtest_random_seedE_ZNSt6vectorIPN7testing8TestCaseESaIS2_EE6assignEjRKS2_st_nlink_ZNK7testing18TestEventListeners22EventForwardingEnabledEvkFilterFlag__copy_move_backward_a2_ZNSt6vectorIPN7testing8TestInfoESaIS2_EE18_M_fill_initializeEjRKS2_basic_stringbuf, std::allocator >_ZN7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEEaSERKS6_MSG_PROXY_ZNSt11char_traitsIwE6assignEPwjw_S_compare_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE10_M_insert_EPSt18_Rb_tree_node_baseS9_RKS1__ZN7testing8internal16BoolFromGTestEnvEPKcb_ZNKSs5rfindEcj_ZNSt6vectorIPN7testing8TestInfoESaIS2_EE5eraseEN9__gnu_cxx17__normal_iteratorIPS2_S4_EES8__ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE10_S_minimumEPKSt18_Rb_tree_node_base__miter_base_ZN9__gnu_cxx14__alloc_traitsISaIPcEE8allocateERS2_j_ZN7testing8internal24XmlUnitTestResultPrinter21OutputXmlCDataSectionEPSoPKc__uninitialized_copy_a<__gnu_cxx::__normal_iterator*, std::vector > >, std::basic_string*, std::basic_string >_ZNSbIwSt11char_traitsIwESaIwEE7_M_moveEPwPKwjpipe_fd__sighandler_ttz_dsttime_M_put_node_ZNKSt3setIPKcSt4lessIS1_ESaIS1_EE4sizeEv__max_ZN9__gnu_cxx17__normal_iteratorIPN7testing8internal9TraceInfoESt6vectorIS3_SaIS3_EEEpLEi_S_leftai_family__begfdopen__copy_mfind_first_not_ofhas_new_fatal_failure_ZN9__gnu_cxx13new_allocatorIPN7testing11EnvironmentEE10deallocateEPS3_jlong double_Vector_impl_ZNKSt6vectorIN7testing8internal9TraceInfoESaIS2_EE5emptyEvupper_boundDirectoryExistsa_status_ZN7testing8TestCase14test_info_listEvabortfilter_flaga_line_number_ZNK7testing8TestCase6FailedEv_ZNK9__gnu_cxx17__normal_iteratorIPcSsEplEi_Iter_ZNKSs13get_allocatorEv_ZNSt12_Vector_baseIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE11_M_allocateEj_ZN7testing17FLAGS_gtest_colorEreverse_iterator<__gnu_cxx::__normal_iterator > > >__k1munmap_ZN7testing8internal17StreamingListener9UrlEncodeEPKclocaleconvUniversalPrintCharArrayScopedPrematureExitFileoperator!= >_ZN9__gnu_cxx14__alloc_traitsISaIPN7testing8TestCaseEEE8allocateERS4_j_ZNK7testing8internal14TestCaseNameIsclEPKNS_8TestCaseE__cxa_free_exception_M_mutatecopy_Rb_tree_decrement_ZNKSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE11_M_leftmostEvkMaxCodePoint1kMaxCodePoint2kMaxCodePoint3kMaxCodePoint4beginwstring_S_construct__pred_iter__copy_move_backward_a__clock_t__fmtfl_ZNKSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE5emptyEvkStackTraceMarker_ZN7testing8internal17StreamingListener11OnTestStartERKNS_8TestInfoECmpHelperLE_ZNSt18_Rb_tree_node_base10_S_minimumEPS_rebindp_sign_posn_ZN7testing8internal15TestFactoryBaseaSERKS1_CmpHelperLTinternal_run_death_test_flag_ZNKSt3setISsSt4lessISsESaISsEE5countERKSsallocated_ZN7testing8internal21UniversalTersePrinterIPKcE5PrintES3_PSos2_expression_ZN7testing8internal18InitGoogleTestImplIwEEvPiPPT__Rb_tree, std::less, std::allocator >_S_on_swapfirst_fixture_id_ZN7testing4Test14RecordPropertyERKSsS2___copy_move_a__copy_move_backward_a2_ZN9__gnu_cxx14__alloc_traitsISaIPN7testing8internal29ParameterizedTestCaseInfoBaseEEE10deallocateERS5_PS4_j_ZNKSt15basic_streambufIcSt11char_traitsIcEE5egptrEv_ZNSt6vectorISsSaISsEE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPSsS1_EERKSs__uninit_copy_ZN7testing14IsNotSubstringEPKcS1_RKSbIwSt11char_traitsIwESaIwEES7__ZN9__gnu_cxx17__normal_iteratorIPKN7testing14TestPartResultESt6vectorIS2_SaIS2_EEEpLEi_M_get_nodeflush__mempositive_ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EE4swapERS4__ZNKSt3setIPKcSt4lessIS1_ESaIS1_EE10value_compEv_ZNSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE15_M_erase_at_endEPS3_valuetest_part_results_name_CmpHelperNEmessage_TestPartNonfatallyFailed_S_uppercase_ZN7testing8internal21ImplicitlyConvertibleIPKvS3_E5valueEgrouping_ZNK7testing8TestCase10should_runEvcopy_backwardGetTimeInMillis_ZNSt6vectorIPN7testing8TestInfoESaIS2_EEaSERKS4__ZNKSt6vectorIiSaIiEE6rbeginEv_ZNK9__gnu_cxx17__normal_iteratorIPiSt6vectorIiSaIiEEEplEiresult_typeoperator<< >_ZNSs12_S_constructIPKcEEPcT_S3_RKSaIcE_ZNKSt3setIPKcSt4lessIS1_ESaIS1_EE5emptyEv_GLOBAL__sub_I__ZN7testing8internal17kStackTraceMarkerEflip_ZN7testing8TestInfo3RunEvoperator- >_ZNSt6vectorIPN7testing11EnvironmentESaIS2_EE14_M_fill_assignEjRKS2__ZNK9__gnu_cxx17__normal_iteratorIPKPN7testing11EnvironmentESt6vectorIS3_SaIS3_EEEmiEiFLAGS_gtest_also_run_disabled_testsaddressHasNewFatalFailureHelperlconvregfreeflag_enda_regexReadEntireFile_ZNK9__gnu_cxx17__normal_iteratorIPiSt6vectorIiSaIiEEEptEv_ZNKSbIwSt11char_traitsIwESaIwEE4sizeEv_ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EE5frontEvmkdir_ZNKSbIwSt11char_traitsIwESaIwEE3endEv_ZNSt6vectorISsSaISsEE6insertEN9__gnu_cxx17__normal_iteratorIPSsS1_EERKSsDIEDkQuoteBegin_ZNSt12_Vector_baseIPcSaIS0_EE19_M_get_Tp_allocatorEvreverse_iterator<__gnu_cxx::__normal_iterator > > >_ZN9__gnu_cxx13new_allocatorISt13_Rb_tree_nodeIPKcEE10deallocateEPS4_jeq_int_type_ZNK7testing8internal13FloatingPointIdE8sign_bitEvgtest_output_flagnpos_ZN7testing8TestCase10TestPassedEPKNS_8TestInfoE_ZNKSt6vectorIN7testing12TestPropertyESaIS1_EE6rbeginEvabs_error_expr_ZNSt6vectorISsSaISsEE5frontEvHasFatalFailure_ZNSt18_Rb_tree_node_base10_S_maximumEPKS_strdupinternal2__uninitialized_copy_aoperator- >_ZN7testing4Test10HasFailureEv_ZNK9__gnu_cxx17__normal_iteratorIPKSsSt6vectorISsSaISsEEEmiEi_ZNKSs6_M_repEv__uninit_copytext_ZN9__gnu_cxx13new_allocatorIN7testing14TestPartResultEE8allocateEjPKv__normal_iteratorpost_flag_parse_init_performed__ZN7testing8internal32FormatEpochTimeInMillisAsIso8601ExTestPropertyKeyIs_ZN7testing8internal10scoped_ptrINS0_16DeathTestFactoryEE7releaseEv_ZN7testing8internal17g_executable_pathE_ZN7testing15AssertionResultlsIA5_cEERS0_RKT_ParameterizedTestCaseInfoBasestack_grows_down_ZNSt3setIPKcSt4lessIS1_ESaIS1_EE11upper_boundERKS1_posix_ZNSt6vectorIPN7testing11EnvironmentESaIS2_EE3endEvvector_ZN7testing8internal18ParseNaturalNumberIiEEbRKSsPT_allocator_ZNK7testing8internal9MutexBase10AssertHeldEv_ZN7testing8internal17TestEventRepeater15OnTestCaseStartERKNS_8TestCaseE_M_allocate_ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EE14_M_fill_insertEN9__gnu_cxx17__normal_iteratorIPS2_S4_EEjRKS2__ZNKSs6rbeginEvnum_readtest_countpstr_M_erase_aux_Construct_ZNSt6vectorIiSaIiEE9push_backERKi__minOutputXmlAttribute_ZNSt6vectorIPN7testing8TestInfoESaIS2_EE6rbeginEvkTestShardStatusFile_ZNKSt6vectorIPN7testing17TestEventListenerESaIS2_EE3endEv__ownerSetup_should_be_spelled_SetUpoperator<< _ZNSt6vectorIPN7testing11EnvironmentESaIS2_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS2_S4_EERKS2__ZN7testing8internal17GetCapturedStreamEPPNS0_14CapturedStreamE_Construct, char const*>_ZNKSbIwSt11char_traitsIwESaIwEE7_M_iendEv_ZN7testing8internal11ShouldShardEPKcS2_b_ZNSt12_Vector_baseIPN7testing8TestInfoESaIS2_EE17_M_create_storageEj_ZN7testing10TestResultC2Ev_ZNSs4_Rep15_M_set_sharableEvsa_family_t_M_bump_up_ZN7testing8internal18StreamableToStringIiEESsRKT__ZN7testing8internal17TestEventRepeater18OnTestIterationEndERKNS_8UnitTestEi_ZNSbIwSt11char_traitsIwESaIwEE5beginEvPredicateswapiterator_traits_ZNKSt6vectorIPN7testing8TestInfoESaIS2_EE5emptyEv_ZSt16__throw_bad_castv_ZNK7testing8internal12UnitTestImpl16total_test_countEv_vtable_offsetSetUpTestCaseFuncTestResultwctrans_t_ZNK7testing8UnitTest11random_seedEv__addressofOVERSEE_TEST_ZNKSt3setISsSt4lessISsESaISsEE8key_compEv_ZN7testing8internal24XmlUnitTestResultPrinterC2EPKcdot_extension_ZNSs7replaceEN9__gnu_cxx17__normal_iteratorIPcSsEES2_PKcS4_set_forwarding_enabled_M_impl_ZN7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEE11ValueHolderD2Evsi_sigvalvwprintf_ZN7testing8TestInfo26increment_death_test_countEv_M_range_check_ZNSt23_Rb_tree_const_iteratorIPKcEppEipremature_exit_filepath~GTestFlagSaver_ZNSs7replaceEN9__gnu_cxx17__normal_iteratorIPcSsEES2_NS0_IPKcSsEES5_CheckedDowncastToActualType::ValueHolder, testing::internal::ThreadLocalValueHolderBase>_ZNSt23_Rb_tree_const_iteratorIPKcEppEv_ZNK7testing8internal12UnitTestImpl12elapsed_timeEv_ZNKSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE8key_compEv_ZNKSt6vectorIPN7testing8TestInfoESaIS2_EE8capacityEv_ZNK9__gnu_cxx13new_allocatorIPN7testing8TestInfoEE7addressERKS3__ZNK7testing15AssertionResultcvbEvCountIf, bool (*)(const testing::TestInfo*)>_ZNK7testing8TestInfo14test_case_nameEvPassed_ZN7testing8internal2RE9FullMatchERKSsRKS1__ZN7testing8internal13FloatingPointIdE38DistanceBetweenSignAndMagnitudeNumbersERKyS4__ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EE18_M_fill_initializeEjRKS2__ZNK9__gnu_cxx17__normal_iteratorIPPN7testing8TestInfoESt6vectorIS3_SaIS3_EEEdeEvpointerkStdOutFileno_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEEaSERKS5__ZNKSt6vectorISsSaISsEE8capacityEv_ZNSbIwSt11char_traitsIwESaIwEE13_S_copy_charsEPwS3_S3_forward_iterator_tagfastst_modean_index_ZNKSt6vectorIN7testing8internal9TraceInfoESaIS2_EE8capacityEv_ZN9__gnu_cxx14__alloc_traitsISaIN7testing8internal9TraceInfoEEE8allocateERS4_jiterator_traits_ZNSbIwSt11char_traitsIwESaIwEE7replaceEjjjw_ZN9__gnu_cxx24__numeric_traits_integerIsE5__maxE_ZNSt6vectorISsSaISsEE8pop_backEv_ZNK9__gnu_cxx17__normal_iteratorIPPcSt6vectorIS1_SaIS1_EEEplEi_ZNKSt6vectorIiSaIiEE14_M_range_checkEjtest_result_ZNSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EEaSERKS5__InputIterator_S_skipwsdest_ptrClosepthread_getspecificTestFactoryBase_ZNKSt6vectorISsSaISsEE8max_sizeEv_ZNK7testing8internal12UnitTestImpl17current_test_infoEv_ZN9__gnu_cxx14__alloc_traitsISaIiEE10deallocateERS1_Pij__copy_move_backward_a2_ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EE14_M_fill_insertEN9__gnu_cxx17__normal_iteratorIPS2_S4_EEjRKS2__M_leftmost_ZNKSt3setIPKcSt4lessIS1_ESaIS1_EE6rbeginEv_ZN7testing8internal27CheckedDowncastToActualTypeINS0_11ThreadLocalISt6vectorINS0_9TraceInfoESaIS4_EEE11ValueHolderENS0_26ThreadLocalValueHolderBaseEEEPT_PT0__ZNKSt6vectorIN7testing8internal9TraceInfoESaIS2_EE8max_sizeEv_ZNSt6vectorIN7testing12TestPropertyESaIS1_EE8pop_backEv_ZN7testing8TestCase12TestDisabledEPKNS_8TestInfoE_ZNK9__gnu_cxx17__normal_iteratorIPPN7testing8TestInfoESt6vectorIS3_SaIS3_EEEixEibits__ZN7testing22EmptyTestEventListenerD0Ev__uninitialized_move_if_noexcept_a >allocator_ZN7testing17TestEventListeneraSERKS0___uninit_copy_ZNSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE4swapERS5__ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE24_M_get_insert_unique_posERKSs_M_get_insert_hint_equal_pos_M_move_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE8_S_rightEPSt18_Rb_tree_node_base__niter_base_ZNK7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE16GetOrCreateValueEv_ZNSs13_S_copy_charsEPcS_S__ZNSt10_Iter_baseIPPN7testing17TestEventListenerELb0EE7_S_baseES3__ZNSt6vectorIN7testing14TestPartResultESaIS1_EE6resizeEjS1__ZNK9__gnu_cxx17__normal_iteratorIPSsSt6vectorISsSaISsEEE4baseEvoperator<< >_ZN7testing8internal38DefaultPerThreadTestPartResultReporterD0Ev_ZNKSbIwSt11char_traitsIwESaIwEE17find_first_not_ofERKS2_jnext_seed_ZNKSt12_Vector_baseIPN7testing17TestEventListenerESaIS2_EE19_M_get_Tp_allocatorEv_ZNKSt6vectorIN7testing14TestPartResultESaIS1_EE14_M_range_checkEjcerrdefault_result_printer_pfile_ZNSs12_S_constructIPKcEEPcT_S3_RKSaIcESt20forward_iterator_tag_ZN9__gnu_cxx13new_allocatorIPKcE10deallocateEPS2_jtest_case_count_ZN7testing8internal24XmlUnitTestResultPrinter9EscapeXmlERKSsbwctob_ZNKSt6vectorISsSaISsEE5beginEv_IO_save_end_ZNK7testing8internal12UnitTestImpl19disabled_test_countEvst_gidrelative_path__throw_logic_error_ZN7testing8internal9DeathTest11LastMessageEv__normal_iterator > >_ZN7testing8internal12UnitTestImpl20set_catch_exceptionsEb_ZN7testing22EmptyTestEventListener16OnTestProgramEndERKNS_8UnitTestE__ioinit_ZNKSs8capacityEv_DestroykFractionBitCount__gid_t__are_same, std::allocator >*, std::basic_string, std::allocator >*>new_allocatorFClose_ZN7testing8internal9EqFailureEPKcS2_RKSsS4_bIsUtf16SurrogatePair_ZNSs5eraseEjj_ZNKSs4dataEv_ZN7testing8internal18OsStackTraceGetteraSERKS1_construct_ZNSt23_Rb_tree_const_iteratorISsEppEi_ZN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEEaSERKS4_PrintAsCharLiteralTo_ZN9__gnu_cxx17__normal_iteratorIPiSt6vectorIiSaIiEEEmIEistr_len_ZNSt23_Rb_tree_const_iteratorISsEppEv__uninitialized_move_if_noexcept_a >UniversalPrint >ClearNonAdHocTestResult_ZNKSt23_Rb_tree_const_iteratorIPKcEptEv_ZN7testing17TestEventListener16OnTestProgramEndERKNS_8UnitTestE_ZN7testing8internal6String15FormatIntWidth2Eioperator== >_ZNKSs6lengthEvSetDefaultXmlGenerator_ZN7testing8internal16WideStringToUtf8EPKwiwcsftime_ZNKSs8max_sizeEv~DefaultGlobalTestPartResultReporter_FwdIterator_ZN7testing8internal14CmpHelperSTREQEPKcS2_PKwS4__ZN7testing8internal6IsTrueEbtear_down_tc_ZNSt12_Vector_baseIN7testing14TestPartResultESaIS1_EE17_M_create_storageEj_ZNSt6vectorIPN7testing8TestInfoESaIS2_EE6resizeEjS2__ZN7testing8internal17StreamingListener6SendLnERKSs_ZNK9__gnu_cxx17__normal_iteratorIPKN7testing14TestPartResultESt6vectorIS2_SaIS2_EEEplEi_ZNK7testing8TestCase19disabled_test_countEv_ZNKSbIwSt11char_traitsIwESaIwEE4_Rep12_M_is_leakedEv_ZNK9__gnu_cxx17__normal_iteratorIPKPN7testing8TestInfoESt6vectorIS3_SaIS3_EEE4baseEv_ZNSt17_Rb_tree_iteratorISsEmmEi_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE10_S_maximumEPSt18_Rb_tree_node_base_ZN7testing8TestCase18GetMutableTestInfoEi_ZNK9__gnu_cxx17__normal_iteratorIPKPN7testing8TestInfoESt6vectorIS3_SaIS3_EEEplEiBaseholder_base_ZNSt17_Rb_tree_iteratorISsEmmEv_ZNSt12__alloc_swapISaISsELb1EE8_S_do_itERS0_S2_argumentpartial_regex__ZN7testing8internal19TypedTestCasePState11AddTestNameEPKciS3_S3_ConcatPaths_ZN7testing8internal15TestFactoryBase10CreateTestEv__pointer_ZN7testing8internal35DefaultGlobalTestPartResultReporterD2Evtestsnegative_ZN9__gnu_cxx14__alloc_traitsISaIPN7testing8internal29ParameterizedTestCaseInfoBaseEEE10_S_on_swapERS5_S7__ZN9__gnu_cxx13new_allocatorIN7testing8internal9TraceInfoEE9constructEPS3_RKS3__S_boolalpha_ZNSbIwSt11char_traitsIwESaIwEE6assignEjw_ZNK7testing8internal12UnitTestImpl17test_to_run_countEvtest_shard_file__uninit_copy__initialize_pAppendMessage_ZN9__gnu_cxx14__alloc_traitsISaISsEE10_S_on_swapERS1_S3_targetmutex_arg_string_ZN7testing8TestCase12ShuffleTestsEPNS_8internal6RandomE_ZNK7testing8UnitTest17test_to_run_countEv_ZN7testing8internal27OsStackTraceGetterInterface17CurrentStackTraceEii__copy_move_backward_anew_allocatortest_info_listHONOR_SHARDING_PROTOCOL_ZNSt6vectorIN7testing14TestPartResultESaIS1_EE4backEv_ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EE4rendEvelapsed_time__ZNSt6vectorIPN7testing11EnvironmentESaIS2_EE4dataEv_ZNKSt6vectorIPN7testing8TestInfoESaIS2_EE4backEv_ZNSt6vectorIN7testing14TestPartResultESaIS1_EE5eraseEN9__gnu_cxx17__normal_iteratorIPS1_S3_EES7_execveg_in_fast_death_test_childTestPropertiesAsXmlAttributesdummy__ZN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEED2Ev_ZN7testing8internal20StringStreamToStringEPSt18basic_stringstreamIcSt11char_traitsIcESaIcEEstream_name_ZN9__gnu_cxx13new_allocatorIiE10deallocateEPij_Pointer_Rb_tree_insert_and_rebalance_ZNSt11char_traitsIwE6assignERwRKwuninitialized_copyin_subprocess_for_death_testpthread_mutexattr_t_ZNK9__gnu_cxx13new_allocatorIPKcE7addressERS2_for_each > >, void (*)(testing::Environment*)>_ZN7testing8internal16GetAnsiColorCodeENS0_10GTestColorE_ZN9__gnu_cxx17__normal_iteratorIPN7testing14TestPartResultESt6vectorIS2_SaIS2_EEEmIEifound_Destroy_ZNK9__gnu_cxx17__normal_iteratorIPPN7testing8TestCaseESt6vectorIS3_SaIS3_EEEdeEv_ZN7testing8internal29ParameterizedTestCaseInfoBase13RegisterTestsEvShouldUseColorcopy_backwarditerator_categoryPrintXmlUnitTest_S_eofbit_ZN7testing8internal17TestEventRepeater16OnTestPartResultERKNS_14TestPartResultEoperator<< _Iter_predfailed_test_countassertion_result_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE8_S_valueEPKSt13_Rb_tree_nodeISsE__nusersconst_iterator_ZNKSt12_Vector_baseIPN7testing8TestInfoESaIS2_EE13get_allocatorEv_M_capacityTestCaseoperator== >~Init_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE7_S_leftEPKSt18_Rb_tree_node_baseFILE_filenoDoubleLEoperator|=severity_ZNKSt6vectorIPN7testing11EnvironmentESaIS2_EEixEj_ZNSt11char_traitsIcE6assignERcRKcCaptureStderrallocator_ZNK7testing8internal8FilePath19RemoveDirectoryNameEvCreateTest~TestPartResult_ZNK7testing8internal13FloatingPointIdE6is_nanEvoperator<< _ZN7testing8internal18StreamableToStringIPcEESsRKT__ZNKSt6vectorIN7testing12TestPropertyESaIS1_EE5beginEv_ZN9__gnu_cxx17__normal_iteratorIPKPN7testing11EnvironmentESt6vectorIS3_SaIS3_EEEmIEi_ZN7testing8internal9DeathTest10AssumeRoleEv_ZNKSt6vectorIiSaIiEE2atEjHasNonfatalFailureFormatWordListvector >filter_outcome_ZNSt6vectorIiSaIiEE5clearEv_M_color_ZN7testing8TestCase13ShouldRunTestEPKNS_8TestInfoE_ZNK9__gnu_cxx17__normal_iteratorIPPN7testing8TestCaseESt6vectorIS3_SaIS3_EEEixEi_ZNSbIwSt11char_traitsIwESaIwEEaSERKS2__ZN7testing8internal8GTestLog9GetStreamEv_ZN7testing8internal27OsStackTraceGetterInterfaceaSERKS1_internal_flag_ZNSt12_Vector_baseISsSaISsEE11_M_allocateEjignore_sigprof_actionOnTestIterationEnd_ZNKSt6vectorIN7testing12TestPropertyESaIS1_EE5frontEvscoped_ptr_ZNKSs3endEv_ZNK7testing8internal8FilePath6stringEv_ZNSt6vectorIPcSaIS0_EE6assignEjRKS0__ZN9__gnu_cxx13new_allocatorIPN7testing17TestEventListenerEE10deallocateEPS3_j_ZN7testing8internal13FloatingPointIfE38DistanceBetweenSignAndMagnitudeNumbersERKjS4_getpagesize_ZNKSt6vectorIPcSaIS0_EE14_M_range_checkEj_ZNSt6vectorIPcSaIS0_EE14_M_fill_assignEjRKS0__ZNK7testing8internal10scoped_ptrISsEdeEv_ZNSo5writeEPKci_ZN7testing22FLAGS_gtest_list_testsE_ZNKSbIwSt11char_traitsIwESaIwEE16find_last_not_ofERKS2_jctype__socklen_t_ZNSt11char_traitsIwE4moveEPwPKwj_ZNK9__gnu_cxx17__normal_iteratorIPPN7testing11EnvironmentESt6vectorIS3_SaIS3_EEEplEiFloatLEStreamWideCharsToMessage_ZNSt6vectorIN7testing12TestPropertyESaIS1_EE6resizeEjS1__ZN7testing10TestResult26increment_death_test_countEv_ZNSt6vectorIN7testing12TestPropertyESaIS1_EE8_M_eraseEN9__gnu_cxx17__normal_iteratorIPS1_S3_EEoperator==, std::allocator >partial_regexsival_ptrHasSameFixtureClass_Destroyproperty_name_ZNSt6vectorIPN7testing11EnvironmentESaIS2_EE2atEj_M_refcountis_runnable_ZN7testing8internal17TestEventRepeater22OnEnvironmentsSetUpEndERKNS_8UnitTestE_ZNK7testing14TestPartResult4typeEv_ZNK9__gnu_cxx17__normal_iteratorIPPN7testing17TestEventListenerESt6vectorIS3_SaIS3_EEEplEi~TestInfo__dev_t_Base_ptr_ZN7testing8internal17StreamingListener12SocketWriterD2Ev_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE14_M_lower_boundEPSt13_Rb_tree_nodeISsES8_RKSsIsTrue_ZNSt12_Vector_baseIPN7testing17TestEventListenerESaIS2_EE19_M_get_Tp_allocatorEvfilter_M_bump_downfull_pathnameEXECUTE_TESTMSG_ERRQUEUE__uninitialized_copy_a*, std::basic_string*, std::basic_string >new_allocator_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE5eraseESt23_Rb_tree_const_iteratorISsES7__ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EE5eraseEN9__gnu_cxx17__normal_iteratorIPS2_S4_EES8__ZN7testing8internal20ExitedUnsuccessfullyEineedle_ZNKSt6vectorIPN7testing8TestInfoESaIS2_EE4sizeEv_ZN7testing7MessagelsEPKw_Bit_iterator_ZN9__gnu_cxx17__normal_iteratorIPN7testing8internal9TraceInfoESt6vectorIS3_SaIS3_EEEmIEi_ZNK7testing8UnitTest16total_test_countEvper_thread_test_part_result_reporter_fseek~DeathTestFactory_ZN7testing18TestEventListenersC2Evbasic_stringstream, std::allocator >ptrdiff_t_ZN7testing8internal14ShouldUseColorEb_ZN7testing8internal12ShuffleRangeIiEEvPNS0_6RandomEiiPSt6vectorIT_SaIS5_EEset, std::allocator >_Distance_archF_OWNER_PIDwmemmove~TestResultset_outcome__destroy__alloc_traits >_ZNK9__gnu_cxx17__normal_iteratorIPcSsEmiEi_ZSt24__throw_out_of_range_fmtPKczbasic_iostream_ZNSt6vectorIN7testing12TestPropertyESaIS1_EE6insertEN9__gnu_cxx17__normal_iteratorIPS1_S3_EERKS1_GetLastErrnoDescriptionwcrtombwstrclear_ZNKSt6vectorIPN7testing8TestInfoESaIS2_EE3endEv_ZN9__gnu_cxx13new_allocatorIPN7testing8internal29ParameterizedTestCaseInfoBaseEE9constructEPS4_RKS4_failure_ZN9__gnu_cxx13new_allocatorIPN7testing8internal29ParameterizedTestCaseInfoBaseEE10deallocateEPS4_j__check_facet >_ZN7testing8internal17TestEventRepeater18OnTestProgramStartERKNS_8UnitTestE_ZNK9__gnu_cxx17__normal_iteratorIPPN7testing8internal29ParameterizedTestCaseInfoBaseESt6vectorIS4_SaIS4_EEEplEi_ZNK7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEE16GetOrCreateValueEv__espins_ZNSsaSEPKcdefault_result_printer_ZNK9__gnu_cxx17__normal_iteratorIPN7testing8internal9TraceInfoESt6vectorIS3_SaIS3_EEEplEi_ZNSbIwSt11char_traitsIwESaIwEE3endEvrm_eo_ZN7testing8TestCase19ClearTestCaseResultEPS0_operator<< _ZNSs14_M_replace_auxEjjjcWriteToShardStatusFileIfNeeded_Rep_baseenv_varvalue_holderfirst_test_info_ZNSspLEckPrintTimeFlag_ZNSt3setIPKcSt4lessIS1_ESaIS1_EE6insertESt23_Rb_tree_const_iteratorIS1_ERKS1__ZN7testing10TestResult20ClearTestPartResultsEv__copy_move_backward_anew_allocator, std::allocator > >MSG_FINreverse_iterator<__gnu_cxx::__normal_iterator > > >st_atim_ZN7testing11Environment5SetUpEvst_dev_ZNSt6vectorIPN7testing11EnvironmentESaIS2_EE14_M_fill_insertEN9__gnu_cxx17__normal_iteratorIPS2_S4_EEjRKS2__ZN9__gnu_cxx17__normal_iteratorIPKN7testing14TestPartResultESt6vectorIS2_SaIS2_EEEmIEi__is_signedcountsCloseConnection__state_ZNKSt3setISsSt4lessISsESaISsEE4sizeEv_ZN7testing18TestEventListeners6AppendEPNS_17TestEventListenerEfirst_ZNSt6vectorIPN7testing8TestInfoESaIS2_EE15_M_erase_at_endEPS2__ZN9__gnu_cxx24__numeric_traits_integerIcE5__maxE_ZNKSbIwSt11char_traitsIwESaIwEE17find_first_not_ofEPKwjjInit_ZN7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEE7pointerEvGetTestCaseName_ZNKSt14_Bit_referenceeqERKS__ZNKSbIwSt11char_traitsIwESaIwEE5emptyEvMSG_CTRUNC__normal_iterator > >_ZNK9__gnu_cxx17__normal_iteratorIPKPN7testing11EnvironmentESt6vectorIS3_SaIS3_EEEptEv__alloc_traits >_ZN7testing8internal2REaSERKS1__ZN7testing8internal12UnitTestImpl17gtest_trace_stackEvnum_failuresenvironments_Delete__copy_move_b_M_insert_ZN9__gnu_cxx13new_allocatorIwE10deallocateEPwj_ZN7testing8internal10scoped_ptrIKSsEaSERKS3__ZN9__gnu_cxx14__alloc_traitsISaIPN7testing8TestCaseEEE7destroyERS4_PS3_PrintTestPartResult__copy_move_backward_a2*, std::basic_string*>_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE11equal_rangeERKSsgtest_ar__Identity, std::allocator > >AlwaysTrueoperator<< >set_current_test_infoTEST_DID_NOT_DIEwcscollopenmode_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE11_M_leftmostEvvalue_~TestPropertyoperator!= >_ZN7testing8internal27FormatTimeInMillisAsSecondsEx_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE13_Rb_tree_implIS3_Lb0EE13_M_initializeEv__last_ZNK9__gnu_cxx17__normal_iteratorIPKPN7testing8TestInfoESt6vectorIS3_SaIS3_EEEdeEv_ZNK9__gnu_cxx17__normal_iteratorIPKSsSt6vectorISsSaISsEEEptEv_ZNK7testing8internal12UnitTestImpl30reportable_disabled_test_countEvOnTestCaseStart__prioritydeath_test_style_kCatchExceptionsFlag_ZNSs12_S_constructEjcRKSaIcE__addressofuninitialized_copy*>ForkingDeathTestdeath_test_factory_ZN9__gnu_cxx14__alloc_traitsISaIN7testing14TestPartResultEEE8max_sizeERKS3_OsStackTraceGetterInterface_ZNSs7_M_moveEPcPKcj__copy_move_backward_a_ZNSt18_Rb_tree_node_base10_S_minimumEPKS_ParameterizedTestCaseRegistry_ZNSt12_Vector_baseIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE13_M_deallocateEPS3_j__time_t_ZN7testing8internal17StreamingListener20AbstractSocketWriteraSERKS2_signumMutexpathname__miter_base*>_ZN7testing8TestCase3RunEv_ZNKSbIwSt11char_traitsIwESaIwEE7compareEjjRKS2_jj_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE8_S_valueEPKSt18_Rb_tree_node_baseFloatingPoint_ZN9__gnu_cxx14__alloc_traitsISaIPN7testing17TestEventListenerEEE17_S_select_on_copyERKS4_fgetwc_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE4swapERS5__ZN7testing8internal12UnitTestImpl18GetMutableTestCaseEi_ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EE4rendEv_ZNKSt6vectorIN7testing8internal9TraceInfoESaIS2_EE6rbeginEv_ZNSt6vectorIN7testing12TestPropertyESaIS1_EE4dataEvrelease_ZNSt6vectorIPN7testing11EnvironmentESaIS2_EE6insertEN9__gnu_cxx17__normal_iteratorIPS2_S4_EERKS2__ZNK7testing8internal12UnitTestImpl26successful_test_case_countEvnew_allocator_ZN9__gnu_cxx17__normal_iteratorIPKN7testing14TestPartResultESt6vectorIS2_SaIS2_EEEmmEiParseBoolFlagParseInt32OnTestStartread_fd__ZN7testing8internal27PrettyUnitTestResultPrinter18OnTestIterationEndERKNS_8UnitTestEistrstrcolor__ZN9__gnu_cxx17__normal_iteratorIPKN7testing14TestPartResultESt6vectorIS2_SaIS2_EEEmmEv_ZNSs6resizeEj__vtbl_ptr_typeGTestIsInitialized_Is_pod_comparator__destroy_ZN7testing19FLAGS_gtest_shuffleEGetInjectableArgvsFormatDeathTestOutput_ZNKSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE11equal_rangeERKSs_ZNSbIwSt11char_traitsIwESaIwEEaSEwunary_function, std::allocator >, std::basic_string, std::allocator > >puts_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE7_S_leftEPSt18_Rb_tree_node_base__gnuc_va_listdeath_test_factory__ZNKSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE8_M_beginEv__builtin_memmoveGetOrCreateValue_ZNK7testing8internal8FilePath15DirectoryExistsEvThreadLocal_ZN9__gnu_cxx14__alloc_traitsISaIPcEE7destroyERS2_PS1__ZNKSt6vectorIN7testing14TestPartResultESaIS1_EE3endEv_ZNSt23_Rb_tree_const_iteratorIPKcEmmEiAbortSingleFailureChecker_ZN7testing11IsSubstringEPKcS1_RKSsS3__flags2_ZNSt23_Rb_tree_const_iteratorIPKcEmmEv_ZNKSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE21_M_get_Node_allocatorEv~HasNewFatalFailureHelper_ZN9__gnu_cxx14__alloc_traitsISaIPN7testing8TestInfoEEE8max_sizeERKS4__flagsthisbasic_ostream >_ZNKSt6vectorIPN7testing11EnvironmentESaIS2_EE4dataEv_ZNSt6vectorIPN7testing8TestInfoESaIS2_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS2_S4_EERKS2__ZStplIcSt11char_traitsIcESaIcEESbIT_T0_T1_EPKS3_RKS6__ZNK9__gnu_cxx17__normal_iteratorIPSsSt6vectorISsSaISsEEEplEiclose_fd_ZN9__gnu_cxx17__normal_iteratorIPPN7testing17TestEventListenerESt6vectorIS3_SaIS3_EEEppEikDeathTestInternalErrorrandom___is_move_iterator_ZN7testing8internal30ReportFailureInUnknownLocationENS_14TestPartResult4TypeERKSs_ZNSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE3endEv_ZNK9__gnu_cxx13new_allocatorISt13_Rb_tree_nodeIPKcEE7addressERKS4__ZNK7testing8UnitTest6FailedEv_ZN9__gnu_cxx13new_allocatorISt13_Rb_tree_nodeIPKcEE8allocateEjPKvtest_casesrcfile__miter_basewmemchr_ZN7testing18TestEventListeners8repeaterEvIsPrintableAsciiGetTypeId_ZNK9__gnu_cxx17__normal_iteratorIPPcSt6vectorIS1_SaIS1_EEEmiEiiswctypethis_is_TEST_ZNKSt9basic_iosIcSt11char_traitsIcEE7rdstateEv_Rb_tree_iterator__builtin_strlen_ZNKSs4copyEPcjj_ZN9__gnu_cxx14__alloc_traitsISaIPN7testing8TestInfoEEE10deallocateERS4_PS3_j__is_normal_iterator, std::allocator >*>__uninitialized_copy_ZN7testing8internal15NoExecDeathTest10AssumeRoleEv_ZN7testing15AssertionResultaSERKS0__ZNK9__gnu_cxx17__normal_iteratorIPN7testing12TestPropertyESt6vectorIS2_SaIS2_EEEplEicatch_exceptions__ZN7testing11Environment5SetupEv__ssize_t__niter_base<__gnu_cxx::__normal_iterator > >_ZNKSt6vectorIPN7testing8TestInfoESaIS2_EE8max_sizeEv_InIteratorseedgtest_msgallocator_ZN7testing8internal16UniversalPrinterIxE5PrintERKxPSo_ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EE5eraseEN9__gnu_cxx17__normal_iteratorIPS2_S4_EES8_chdirsival_intstrtod_ZNK7testing8TestCase21successful_test_countEvStreamableToString_ZNKSbIwSt11char_traitsIwESaIwEE4findEPKwjReportInvalidTestCaseTypeUnsignedChar_ZN7testing8internal10scoped_ptrINS0_17StreamingListener20AbstractSocketWriterEE7releaseEv_ZN7testing8internal17StreamingListenerD2Ev_ZNKSs16find_last_not_ofEcjPatternMatchesString_ZN7testing15AssertionResultlsINS_7MessageEEERS0_RKT_gtest_retval_ZN7testing8internal18StringFromGTestEnvEPKcS2_Fromstrlen_ZN7testing8internal13FloatingPointIfE15ReinterpretBitsEjstack_top_ZN7testing8internal38DefaultPerThreadTestPartResultReporter20ReportTestPartResultERKNS_14TestPartResultEPrintOnOneLinebasic_iostream >_ZNKSbIwSt11char_traitsIwESaIwEE4findEwj_ZNSs6insertEjjc__fmtkFractionBitMaskUnitTestImpl_ZN7testing22EmptyTestEventListener18OnTestIterationEndERKNS_8UnitTestEi_ZNSbIwSt11char_traitsIwESaIwEE4_Rep13_M_set_leakedEv_ZN7testing8internal29ParameterizedTestCaseRegistry13RegisterTestsEv_ZNKSt6vectorIPcSaIS0_EE4rendEvkSuccessOutputXmlCDataSectionGetCapturedStreamRemoveFileName__uninitialized_move_if_noexcept_a >_ZNSbIwSt11char_traitsIwESaIwEE2atEj_ZNSbIwSt11char_traitsIwESaIwEEixEj_ZNSbIwSt11char_traitsIwESaIwEE6insertEjPKw_ZNSt23_Rb_tree_const_iteratorISsEmmEiparse_success_ZNSbIwSt11char_traitsIwESaIwEE7replaceEN9__gnu_cxx17__normal_iteratorIPwS2_EES6_PKwS8_DeathTestAbort_ZNSt23_Rb_tree_const_iteratorISsEmmEvcoloncolor__uninitialized_move_if_noexcept_a >_vptr.Environment_Destroybasefield_ZNSt11char_traitsIcE7compareEPKcS2_j_ZN7testing8internal14CmpHelperSTREQEPKcS2_S2_S2__ZNSt6vectorIPN7testing11EnvironmentESaIS2_EE4backEvreverse_iterator<__gnu_cxx::__normal_iterator > > >RemoveDirectoryName_ZN7testing8internal21ImplicitlyConvertibleIPKvS3_E6HelperES3__Rep_typeis_disabled~basic_ios__niter_base_ZNSt12_Vector_baseIPN7testing8TestInfoESaIS2_EE13_M_deallocateEPS2_jcontentShouldRunTestReportTestPartResultcurrent_ZNSt6vectorIN7testing14TestPartResultESaIS1_EE2atEj__normal_iterator > >_ZN9__gnu_cxx17__normal_iteratorIPKN7testing8internal9TraceInfoESt6vectorIS3_SaIS3_EEEppEi_ZNK9__gnu_cxx17__normal_iteratorIPKN7testing14TestPartResultESt6vectorIS2_SaIS2_EEEmiEi_ZNKSt23_Rb_tree_const_iteratorISsEdeEv_ZNKSt6vectorIPN7testing8TestInfoESaIS2_EE6rbeginEv_M_fill_insertbasic_stringbufAddTestName_ZN9__gnu_cxx17__normal_iteratorIPKN7testing8internal9TraceInfoESt6vectorIS3_SaIS3_EEEppEvnothrow_ZNK9__gnu_cxx17__normal_iteratorIPKPN7testing8TestInfoESt6vectorIS3_SaIS3_EEEmiEiis_spawnedoperator<< _ZN7testing8internal23DefaultDeathTestFactoryD0Evvector >_ZNSs5eraseEN9__gnu_cxx17__normal_iteratorIPcSsEES2_Argvoperator<< _ZN7testing8internal27PrettyUnitTestResultPrinter16OnTestPartResultERKNS_14TestPartResultE_ZSt19__throw_logic_errorPKc__prec__pred_ZNKSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE8_M_beginEv_ZN7testing4Test16TearDownTestCaseEv_ZNSt12_Vector_baseIPN7testing8TestInfoESaIS2_EE19_M_get_Tp_allocatorEvSecretSOCK_DCCP_ZNK9__gnu_cxx17__normal_iteratorIPPN7testing17TestEventListenerESt6vectorIS3_SaIS3_EEEptEv_Ios_OpenmodeDelete_ZN7testing4Test5SetUpEv_ZN7testing18TestEventListenersaSERKS0__ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE11_M_put_nodeEPSt13_Rb_tree_nodeISsE_ZNSs6appendEPKc_S_cur_ZNKSt6vectorIPN7testing11EnvironmentESaIS2_EE14_M_range_checkEjshowposSetUpTestCasestdin__pthread_slist_t_ZNKSs4_Rep12_M_is_sharedEv_ZNSt11char_traitsIcE12to_char_typeERKi_ZNKSt6vectorIPN7testing11EnvironmentESaIS2_EE12_M_check_lenEjPKc_ZNSolsEPFRSt8ios_baseS0_E_ZN7testing15AssertionResultlsEPFRSoS1_E_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE5eraseEPKS1_S9_GetFileSize_ZNSt6vectorISsSaISsEE4rendEv_ZN9__gnu_cxx14__alloc_traitsISaIPKcEE8allocateERS3_j_ZNKSbIwSt11char_traitsIwESaIwEE15_M_check_lengthEjjPKc_ZNKSt23_Rb_tree_const_iteratorISsEeqERKS0__ZN7testing8internal27CheckedDowncastToActualTypeINS0_11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE11ValueHolderENS0_26ThreadLocalValueHolderBaseEEEPT_PT0__ZNK9__gnu_cxx13new_allocatorIiE8max_sizeEvvfwscanf_ZNKSbIwSt11char_traitsIwESaIwEE13find_first_ofEPKwjj_ZNSbIwSt11char_traitsIwESaIwEE4_Rep10_M_destroyERKS1_reverse_iterator<__gnu_cxx::__normal_iterator > > >_ZSt17__throw_bad_allocv_ZNKSt12_Vector_baseIN7testing14TestPartResultESaIS1_EE13get_allocatorEvdummyatoll_ZNSo9_M_insertImEERSoT_num_selected_tests_ZNKSbIwSt11char_traitsIwESaIwEE4copyEPwjjoperator<< _ZNSt12_Vector_baseIiSaIiEE17_M_create_storageEjfind<__gnu_cxx::__normal_iterator*, std::vector > >, std::basic_string >_ZNKSt6vectorIiSaIiEE4backEvbuffershort intsnprintf_ZNKSbIwSt11char_traitsIwESaIwEE5c_strEvwmemcpy~FilePathcurrent_test_info_ZNK7testing8internal13DeathTestImpl8write_fdEvForEach, void (*)(testing::Environment*)>_ZN7testing8internal13FloatingPointIdE15ReinterpretBitsEy_Iter_basefind_last_not_of_ZNSt6vectorIN7testing12TestPropertyESaIS1_EE6rbeginEv_ZNK7testing10TestResult12elapsed_timeEv_ZNKSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE7_M_rootEv_ZNKSt6vectorIPN7testing8TestCaseESaIS2_EE3endEvuninitialized_copy<__gnu_cxx::__normal_iterator >, testing::internal::TraceInfo*>ThreadLocalValueHolderBase__normal_iterator, std::allocator > >sa_flagstestoperator<< GetCapturedStderr_ZN9__gnu_cxx17__normal_iteratorIPPN7testing11EnvironmentESt6vectorIS3_SaIS3_EEEppEv_ZNKSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE14_M_upper_boundEPKSt13_Rb_tree_nodeISsES9_RKSs_ZNSbIwSt11char_traitsIwESaIwEE4_Rep10_M_refdataEvNoExecDeathTest_ZNSt6vectorISsSaISsEE5beginEv_ZNKSs8_M_checkEjPKc_ZNSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE6resizeEjS3__vptr.DeathTestFactorybasic_istream_ZNSt12_Vector_baseIN7testing8internal9TraceInfoESaIS2_EE11_M_allocateEj_ZNK9__gnu_cxx17__normal_iteratorIPKcSsEixEi__exchange_and_add_dispatchReseed_ZNK9__gnu_cxx17__normal_iteratorIPKPN7testing17TestEventListenerESt6vectorIS3_SaIS3_EEEptEvcopy_backwardconstructParseFlagValue_ZN7testing8internal24XmlUnitTestResultPrinterD0Ev_ZNK9__gnu_cxx17__normal_iteratorIPKcSsE4baseEv_Construct, std::basic_string >_ZNKSt6vectorIN7testing8internal9TraceInfoESaIS2_EE2atEj_ZNSbIwSt11char_traitsIwESaIwEE4rendEv_ZN7testing8internal18CmpHelperSTRCASENEEPKcS2_S2_S2__ZN7testing8internal17GetCapturedStdoutEv__iterator_category<__gnu_cxx::__normal_iterator > >PushGTestTrace_ZN7testing8internal17TestEventRepeater24OnEnvironmentsSetUpStartERKNS_8UnitTestE_ZN9__gnu_cxx13new_allocatorIcE8allocateEjPKvAssertionResult_ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EE5beginEvuninitialized_copy_ZN9__gnu_cxx14__alloc_traitsISaISsEE17_S_select_on_copyERKS1_operator- >dup2rbegin__gthread_active_pnames_ZNSbIwSt11char_traitsIwESaIwEE6insertEjPKwj_ZNK9__gnu_cxx17__normal_iteratorIPN7testing12TestPropertyESt6vectorIS2_SaIS2_EEE4baseEv_ZNSt12_Vector_baseIPN7testing8TestCaseESaIS2_EE12_Vector_impl12_M_swap_dataERS5_CountIf, bool (*)(const testing::TestCase*)>_sigchldoutput_file_vptr.ParameterizedTestCaseInfoBase__uid_tGTEST_SHARD_STATUS_FILEerrorPrintXmlTestCase_ZN9__gnu_cxx17__normal_iteratorIPKcSsEppEicode_point_ZNSs6assignERKSsjj_ZNKSt6vectorIiSaIiEE4sizeEv_ZNSt10_Iter_baseIPN7testing8internal9TraceInfoELb0EE7_S_baseES3_mon_thousands_sep_ZN7testing8UnitTest13PopGTestTraceEv_ZN9__gnu_cxx17__normal_iteratorIPKcSsEppEv_ZNKSt6vectorIPN7testing17TestEventListenerESaIS2_EEixEj_ZNK7testing18TestEventListeners22default_result_printerEv_ZNK9__gnu_cxx17__normal_iteratorIPPN7testing17TestEventListenerESt6vectorIS3_SaIS3_EEEmiEiLogToStderrwcscatUponLeavingGTest_Vector_base >_ZNSo9_M_insertIxEERSoT__ZN7testing8internal9DeathTest27set_last_death_test_messageERKSs_ZNSbIwSt11char_traitsIwESaIwEE7replaceEjjRKS2_MutexLock_ZNSt6vectorIPN7testing8TestInfoESaIS2_EE4backEvrepeater__Const_Base_ptroperator!= >getcwdSendLn_ZN7testing8internal28ParseGoogleTestFlagsOnlyImplIwEEvPiPPT__ZNSt3setISsSt4lessISsESaISsEEaSERKS3_set_os_stack_trace_getter_ZNKSt23_Rb_tree_const_iteratorISsEneERKS0__ZN7testing8internal15UnitTestOptions27GetAbsolutePathToOutputFileEv_ZNK9__gnu_cxx17__normal_iteratorIPKN7testing14TestPartResultESt6vectorIS2_SaIS2_EEE4baseEv__normal_iterator > >pair, bool>repeaterbasic_stringstatus_valuePrintTestPartResultToStringa_name_ZNSt6vectorIPN7testing8TestCaseESaIS2_EE6insertEN9__gnu_cxx17__normal_iteratorIPS2_S4_EEjRKS2__ZNKSsixEj_ZNSs7replaceEN9__gnu_cxx17__normal_iteratorIPcSsEES2_S1_S1__ZNK9__gnu_cxx13new_allocatorIcE8max_sizeEv_ZN7testing8internal21UniversalTersePrinterIxE5PrintERKxPSo_ZN7testing8internal14GetThreadCountEvreplace_ZNSbIwSt11char_traitsIwESaIwEE18_S_construct_aux_2EjwRKS1_XmlUnitTestResultPrinter_ZNK9__gnu_cxx17__normal_iteratorIPcSsEptEv_ZN7testing8internal2RE4InitEPKc_ZNK9__gnu_cxx13new_allocatorIPN7testing11EnvironmentEE7addressERKS3_AppendUserMessageUniversalTersePrinter_ZNKSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE13get_allocatorEv_ZNKSs7compareEjjPKc__suseconds_t_ZNK9__gnu_cxx17__normal_iteratorIPKPN7testing8TestCaseESt6vectorIS3_SaIS3_EEEmiEi_ZN9__gnu_cxx24__numeric_traits_integerIsE5__minE_ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EE5clearEvshuffle_RandomAccessIterator_ZN9__gnu_cxx14__alloc_traitsISaIiEE7destroyERS1_Pi_ZNSbIwSt11char_traitsIwESaIwEE13_S_copy_charsEPwN9__gnu_cxx17__normal_iteratorIS3_S2_EES6_PrintColorEncoded_M_is_sharediterator_traits_ZN7testing8internal27PrettyUnitTestResultPrinter16OnTestProgramEndERKNS_8UnitTestE_ZNK9__gnu_cxx17__normal_iteratorIPPN7testing8internal29ParameterizedTestCaseInfoBaseESt6vectorIS4_SaIS4_EEEmiEi_ZNSt6vectorIiSaIiEE18_M_fill_initializeEjRKi_ZNSt6vectorISsSaISsEE14_M_fill_assignEjRKSsscoped_ptr_ZN7testing8internal17kStackTraceMarkerE_ZN7testing8internal12UnitTestImpl11GetTestCaseEPKcS3_PFvvES5_premature_exit_filepath__S_constructparameterized_test_registry_ZN7testing8internal6Random8GenerateEj_ZN9__gnu_cxx17__normal_iteratorIPKPN7testing8TestInfoESt6vectorIS3_SaIS3_EEEppEi_Vector_baseiterator_traits<__gnu_cxx::__normal_iterator > > >_ZN7testing18FLAGS_gtest_filterE_ZNK9__gnu_cxx17__normal_iteratorIPN7testing8internal9TraceInfoESt6vectorIS3_SaIS3_EEEmiEi__copy_m_ZN9__gnu_cxx17__normal_iteratorIPKPN7testing8TestInfoESt6vectorIS3_SaIS3_EEEppEva_message__are_same_ZNSt6vectorIPcSaIS0_EE18_M_fill_initializeEjRKS0_TestCaseNameIs_M_insert_M_mask_ZN7testing8internal10scoped_ptrIKSsE7releaseEvis_reportableTestReportableDisabled_ZNK9__gnu_cxx17__normal_iteratorIPiSt6vectorIiSaIiEEE4baseEvreverse_iterator<__gnu_cxx::__normal_iterator, std::allocator > > >_ZN9__gnu_cxx13new_allocatorIPN7testing8TestCaseEE10deallocateEPS3_j_ZNSbIwSt11char_traitsIwESaIwEE9_M_mutateEjjj_ZN7testing4Test3RunEvIsSubstring_ZSt9__find_ifIN9__gnu_cxx17__normal_iteratorIPN7testing12TestPropertyESt6vectorIS3_SaIS3_EEEENS0_5__ops10_Iter_predINS2_8internal17TestPropertyKeyIsEEEET_SE_SE_T0_St26random_access_iterator_tagallocator_typeSetUp__comp_ZN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE7pointerEvpthread_mutex_lockassignrandom_seed__ZN7testing8internal15UnitTestOptions15GetOutputFormatEv_ZSt4cerr_ZNSbIwSt11char_traitsIwESaIwEE7_M_dataEPwfilefillCurrentOsStackTraceExceptTop_ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EE5eraseEN9__gnu_cxx17__normal_iteratorIPS2_S4_EE_ZN7testing8internal35DefaultGlobalTestPartResultReporter20ReportTestPartResultERKNS_14TestPartResultE_ZNSt12_Vector_baseIPN7testing8TestCaseESaIS2_EE17_M_create_storageEj_ZN7testing15AssertionResultlsIPKcEERS0_RKT__ZNSt12_Vector_baseIPcSaIS0_EE13_M_deallocateEPS0_j_exit_ZN7testing11IsSubstringEPKcS1_PKwS3_DistanceBetweenSignAndMagnitudeNumbers_ZNK7testing14TestPartResult6failedEvImplicitlyConvertible_ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EE6assignEjRKS2__ZN7testing8internal27PrettyUnitTestResultPrinter16PrintFailedTestsERKNS_8UnitTestE_ZNSt6vectorIPN7testing11EnvironmentESaIS2_EE8_M_eraseEN9__gnu_cxx17__normal_iteratorIPS2_S4_EES8__ZNKSt6vectorIPN7testing17TestEventListenerESaIS2_EE12_M_check_lenEjPKcerror_num_M_initialize_dispatch10regmatch_t_ZN7testing17TestEventListener15OnTestCaseStartERKNS_8TestCaseE_ZN7testing19TestPartResultArray6AppendERKNS_14TestPartResultE_S_red~ThreadLocalValueHolderBase_ZN9__gnu_cxx14__alloc_traitsISaIPKcEE10_S_on_swapERS3_S5__ZNK9__gnu_cxx13new_allocatorIN7testing12TestPropertyEE7addressERS2__ZN7testing10TestResult16set_elapsed_timeExarguments_ZN9__gnu_cxx24__numeric_traits_integerIiE5__maxEoperator!= >_ZNSt6vectorIN7testing12TestPropertyESaIS1_EE5beginEvgtest_error_ZNSbIwSt11char_traitsIwESaIwEEpLERKS2__ZN7testing8internal20DoubleNearPredFormatEPKcS2_S2_ddd_ZN7testing8internal8GTestLogaSERKS1__ZN7testing8internal35HandleExceptionsInMethodIfSupportedINS0_12UnitTestImplEbEET0_PT_MS4_FS3_vEPKcClearTestCaseResult_M_insert_aux~TraceInfo_ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS2_S4_EERKS2_state__S_adjustfield~AssertHelperData_ZNSt10_Iter_baseIPPN7testing8TestInfoELb0EE7_S_baseES3_ai_protocol_ZN7testing8internal16UniversalPrinterISbIwSt11char_traitsIwESaIwEEE5PrintERKS5_PSoTestInfo_Iter_base_vptr.OsStackTraceGetterInterfacefind_ZN7testing8internal8FilePath12MakeFileNameERKS1_S3_iPKc_ZN9__gnu_cxx14__alloc_traitsISaIPN7testing8TestCaseEEE17_S_select_on_copyERKS4__ZN7testing8internal8FilePath13GetCurrentDirEvparsedgetenv_ZNSt17_Rb_tree_iteratorIPKcEppEiParseGoogleTestFlagsOnlyImplintercept_mode__ZN7testing8internal10SkipPrefixEPKcPS2__Bit_iterator_base_ZNSt17_Rb_tree_iteratorIPKcEppEv_ZNK7testing12TestProperty5valueEv__wide_IO_read_endHandleExceptionsInMethodIfSupported_ZNK7testing8internal10scoped_ptrINS0_17StreamingListener20AbstractSocketWriterEEptEvwcschrIsSubstringPred >__builtin_va_list_ZNKSt3setISsSt4lessISsESaISsEE13get_allocatorEv__cxa_allocate_exceptionoperator new []val2_ss_ZNSt14_Bit_referenceaSEbpathname__ZNKSt6vectorISsSaISsEE5emptyEvstream_result_to__copy_m_S_minimumnew_allocator_ZNK7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEE3getEvIsXDigit_IO_FILE_ZN7testing8internal24InternalRunDeathTestFlagaSERKS1_uninitialized_copy_ZNKSt6vectorIN7testing8internal9TraceInfoESaIS2_EE4rendEv_ZN7testing8internal24GetCurrentExecutableNameEv_ZNKSt6vectorIPN7testing11EnvironmentESaIS2_EE2atEj__statbufis_previous_hex_ZN7testing22EmptyTestEventListener11OnTestStartERKNS_8TestInfoE_ZNKSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE13get_allocatorEvservinfo__false_typewcsrchr__uninitialized_move_if_noexcept_a*, std::basic_string*, std::allocator > >_ZN9__gnu_cxx13new_allocatorIPN7testing8TestCaseEE8allocateEjPKv__is_null_pointerbiased1biased2_ZNKSbIwSt11char_traitsIwESaIwEE12find_last_ofERKS2_jValueHolder_ZNK7testing8internal13DeathTestImpl9statementEv_ZNSt6vectorISsSaISsEEaSERKS1_PrintWideStringTo_Vector_base >bool_valuepattern_ZN7testing22EmptyTestEventListener9OnTestEndERKNS_8TestInfoE_ZNKSt17_Rb_tree_iteratorISsEptEv_ZN7testing22EmptyTestEventListener15OnTestCaseStartERKNS_8TestCaseE_ZNKSt13_Bit_iteratorplEi__is_move_iterator__alloc_traits >IsATTY~basic_stringstream_ZN9__gnu_cxx13new_allocatorIN7testing14TestPartResultEE7destroyEPS2__ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE13_M_clone_nodeEPKSt13_Rb_tree_nodeISsE_M_const_castlldiv_ZN7testing8internal9MutexBase4LockEv_ZN7testing8internal12UnitTestImpl41GetTestPartResultReporterForCurrentThreadEvstatus_ch_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE6_M_endEvSuppressEventForwardingoperator<< >adjustfield_ZNSt6vectorIN7testing14TestPartResultESaIS1_EE14_M_fill_assignEjRKS1__ZNKSbIwSt11char_traitsIwESaIwEE12find_last_ofEPKwjwctomb_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE6_S_keyEPKSt18_Rb_tree_node_baseIsSubstringImplsi_utimeUniversalTersePrinter_Key_compare_ZN7testing8internal6String15ShowWideCStringEPKwswscanfwcscspn_ZN7testing8internal9DeathTest6PassedEbhaystack_exprtest_case_nameformatiterator_traitsDISABLED_*:*/DISABLED_*Clear_ZNSt6vectorIPN7testing8TestInfoESaIS2_EE6insertEN9__gnu_cxx17__normal_iteratorIPS2_S4_EEjRKS2___uninitialized_copy_a_ZN9__gnu_cxx17__normal_iteratorIPKPN7testing8TestCaseESt6vectorIS3_SaIS3_EEEppEi_ZNK9__gnu_cxx17__normal_iteratorIPSsSt6vectorISsSaISsEEEmiEi_Funct_ZNK7testing8internal13FloatingPointIfE4bitsEv_ZN9__gnu_cxx17__normal_iteratorIPKPN7testing8TestCaseESt6vectorIS3_SaIS3_EEEppEv__uninit_copy<__gnu_cxx::__normal_iterator >, testing::internal::TraceInfo*>_S_showbase~basic_istreamconstruct_ZNSbIwSt11char_traitsIwESaIwEE7reserveEj_ZNKSt6vectorIN7testing12TestPropertyESaIS1_EE5emptyEvsigval_t_ZNKSt14_Bit_referencecvbEvsi_bandsigvalGetUnitTestImpl_ZN9__gnu_cxx14__alloc_traitsISaIPN7testing8TestInfoEEE8allocateERS4_jwcscmpsyntax_ValueT_ZNK9__gnu_cxx17__normal_iteratorIPPcSt6vectorIS1_SaIS1_EEEptEv_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE10_M_insert_EPSt18_Rb_tree_node_baseS7_RKSsiterator_traitsGetTestCaseTypeIdstrerrorstderr_ZNSt6vectorIN7testing12TestPropertyESaIS1_EE5clearEv_ZNKSbIwSt11char_traitsIwESaIwEE7compareEjjRKS2__ZNK7testing8internal10scoped_ptrINS0_16DeathTestFactoryEEptEvstreamsize_S_max_size_lock_ZN7testing7MessagelsEb__uninit_copy_ZN9__gnu_cxx13new_allocatorIPcE8allocateEjPKv_ZNK9__gnu_cxx17__normal_iteratorIPKPN7testing8TestCaseESt6vectorIS3_SaIS3_EEE4baseEvInterceptMode10__sigset_t_ZNKSt6vectorIPN7testing11EnvironmentESaIS2_EE5frontEv_ZNSs12_S_empty_repEv_ZNSs6assignEjc_ZNSt6vectorIPN7testing8TestInfoESaIS2_EE8pop_backEv_ZN9__gnu_cxx13new_allocatorIN7testing12TestPropertyEE8allocateEjPKvnum_disabled_ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EEaSERKS4__ZNSt6vectorIPN7testing11EnvironmentESaIS2_EE9push_backERKS2__ZNSt6vectorIPN7testing8TestCaseESaIS2_EE14_M_fill_insertEN9__gnu_cxx17__normal_iteratorIPS2_S4_EEjRKS2__ZN7testing8internal17StreamingListener12SocketWriter4SendERKSs_ZNSolsEPKv_ZNK7testing8internal29ParameterizedTestCaseInfoBase15GetTestCaseNameEv_ZN7testing8internal17TestEventRepeater27OnEnvironmentsTearDownStartERKNS_8UnitTestE_ZN7testing8internal13DeathTestImpl11set_read_fdEi_ZNK7testing15AssertionResultntEvGetCurrentDir__is_normal_iterator_ZNSt18_Bit_iterator_base7_M_incrEivswscanf_ZNSo9_M_insertIdEERSoT__ZNK7testing14TestPartResult7summaryEv__normal_iterator > >_ZNSs5beginEvkMaxStackTraceDepth_ZNSs13_S_copy_charsEPcPKcS1_IGNORE_SHARDING_PROTOCOL_chainDefaultDeathTestFactoryfor_each<__gnu_cxx::__normal_iterator >, void (*)(testing::TestInfo*)>_ZNK7testing8TestCase16total_test_countEv_ZNSt6vectorISsSaISsEE4swapERS1__ZNSs6rbeginEvuninitialized_copy_ZNK7testing8UnitTest12elapsed_timeEv_ZNK9__gnu_cxx17__normal_iteratorIPN7testing8internal9TraceInfoESt6vectorIS3_SaIS3_EEE4baseEv_ZN7testing8internal27PrettyUnitTestResultPrinter13PrintTestNameEPKcS3_wcstollwcsxfrm_ZNKSbIwSt11char_traitsIwESaIwEE5rfindERKS2_jdistance_ZN9__gnu_cxx13new_allocatorIN7testing12TestPropertyEE7destroyEPS2__ZNKSt9_IdentityISsEclERSsleftfmtflagskTestsuitewcscpy_S_maximum_ZNKSt3setISsSt4lessISsESaISsEE10value_compEv_ZNKSt6vectorIN7testing8internal9TraceInfoESaIS2_EE12_M_check_lenEjPKc_ZN7testing11IsSubstringEPKcS1_S1_S1_fflushpair, std::allocator > >, std::_Rb_tree_const_iterator, std::allocator > > >vectorst_blksize_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE6rbeginEvkListTestsFlagreverse_iterator, std::allocator > > >_ZNK7testing12TestProperty3keyEv_ZNK9__gnu_cxx17__normal_iteratorIPPN7testing17TestEventListenerESt6vectorIS3_SaIS3_EEE4baseEv_M_assign_ZNSbIwSt11char_traitsIwESaIwEE4_Rep10_M_refcopyEv_ZN9__gnu_cxx14__alloc_traitsISaISsEE10deallocateERS1_PSsj_ZNKSt12_Vector_baseIN7testing12TestPropertyESaIS1_EE19_M_get_Tp_allocatorEv~PrettyUnitTestResultPrintersa_handlerg_linked_ptr_mutex_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE7_M_rootEv_ZNKSt6vectorIPN7testing11EnvironmentESaIS2_EE4rendEvkMaxRandomSeed_ZN7testing8internal12UnitTestImplaSERKS1_PrintAsCharLiteralTo_ZN7testing8internal10AlwaysTrueEv__mode_ZNSt6vectorIN7testing12TestPropertyESaIS1_EE6insertEN9__gnu_cxx17__normal_iteratorIPS1_S3_EEjRKS1__ZN7testing8internal24XmlUnitTestResultPrinter16PrintXmlTestCaseEPSoRKNS_8TestCaseE_IO_read_ptrset, std::allocator >, std::less, std::allocator > >, std::allocator, std::allocator > > >_ZN7testing13PrintToStringIxEESsRKT__ZN7testing8internal12UnitTestImpl6randomEvconstruct_ZN9__gnu_cxx17__normal_iteratorIPKN7testing8internal9TraceInfoESt6vectorIS3_SaIS3_EEEmmEi_ZNK9__gnu_cxx17__normal_iteratorIPKN7testing14TestPartResultESt6vectorIS2_SaIS2_EEEptEvfalse_type_ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EE4dataEv_ZNSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EEixEj_ZN9__gnu_cxx17__normal_iteratorIPKN7testing8internal9TraceInfoESt6vectorIS3_SaIS3_EEEmmEvHandleSehExceptionsInMethodIfSupported_ZNSbIwSt11char_traitsIwESaIwEE12_S_constructEjwRKS1__M_incr_ZNK7testing8internal13DeathTestImpl5regexEv_ZNK9__gnu_cxx17__normal_iteratorIPKPN7testing8TestInfoESt6vectorIS3_SaIS3_EEEptEv_ZN7testing8TestCase11AddTestInfoEPNS_8TestInfoEPrintBytesInObjectToImpl~allocatorrandom_seed_flag_ZN7testing8internal9DeathTest5AbortENS1_11AbortReasonEshowbase__copy_move_a_ZN7testing4Test19HasSameFixtureClassEvFLAGS_gtest_throw_on_failureAlwaysFalsekSpecialEscape_ZNK9__gnu_cxx17__normal_iteratorIPKPN7testing17TestEventListenerESt6vectorIS3_SaIS3_EEEdeEv_Vector_base >_ZN9__gnu_cxx14__alloc_traitsISaIPN7testing11EnvironmentEEE17_S_select_on_copyERKS4_rebind >_ZN7testing8UnitTest11GetInstanceEv_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE10_S_minimumEPSt18_Rb_tree_node_base_ZNKSt16reverse_iteratorIN9__gnu_cxx17__normal_iteratorIPPN7testing11EnvironmentESt6vectorIS4_SaIS4_EEEEEdeEv_ZN9__gnu_cxx13new_allocatorIPN7testing17TestEventListenerEE7destroyEPS3_new_allocator_ZN7testing8internal12UnitTestImpl17current_test_infoEv_ZNSt3setISsSt4lessISsESaISsEE6insertERKSs_ZNKSs12find_last_ofEPKcjBits__uninitialized_copy_S_fixed_ZNSbIwSt11char_traitsIwESaIwEE7replaceEN9__gnu_cxx17__normal_iteratorIPwS2_EES6_RKS2_UnitTest_ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EE4backEv_ZNK9__gnu_cxx17__normal_iteratorIPKcSsEdeEvmax_size_ZN7testing8internal20SingleFailureCheckeraSERKS1__Traits_ZN7testing8internal9DeathTestaSERKS1_default_valuesigned char_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE11_M_get_nodeEvisattybidirectional_iterator_tag_ZNKSbIwSt11char_traitsIwESaIwEE7compareEjjPKwj_ZN7testing8internal27PrettyUnitTestResultPrinter20OnTestIterationStartERKNS_8UnitTestEiHandleExceptionsInMethodIfSupportedFLAGS_gtest_output_ZN7testing8internal10scoped_ptrINS0_16DeathTestFactoryEEaSERKS3_FloatingPoint__copy_m_ZN9__gnu_cxx14__alloc_traitsISaIPcEE10_S_on_swapERS2_S4_wcspbrka_statement_ZNK9__gnu_cxx17__normal_iteratorIPKPN7testing17TestEventListenerESt6vectorIS3_SaIS3_EEEixEioperator<< Sendsubstr__ZN7testing11IsSubstringEPKcS1_RKSbIwSt11char_traitsIwESaIwEES7_negation_ZNSt11char_traitsIcE2eqERKcS2__ZNKSt16reverse_iteratorIN9__gnu_cxx17__normal_iteratorIPPN7testing11EnvironmentESt6vectorIS4_SaIS4_EEEEEixEi_ZNK7testing8internal10scoped_ptrISt18basic_stringstreamIcSt11char_traitsIcESaIcEEEptEvHandleExceptionsInMethodIfSupported_M_refdataendl >_ZNK7testing8TestCase4nameEv__throw_bad_alloc_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE11_M_leftmostEvprint_timeregcomp_ZNSt10_Iter_baseIPSsLb0EE7_S_baseES0__ZNK9__gnu_cxx13new_allocatorIN7testing14TestPartResultEE7addressERKS2_scoped_ptrChar_kill_ZN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE11ValueHolderD0Ev_ZNK9__gnu_cxx13new_allocatorISt13_Rb_tree_nodeISsEE7addressERKS2_severity_pthread_mutex_destroy_ZNSt6vectorIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE6insertEN9__gnu_cxx17__normal_iteratorIPS3_S5_EEjRKS3__ZNSolsEPFRSoS_Evprintf_ZNSt12_Vector_baseIN7testing12TestPropertyESaIS1_EE12_Vector_impl12_M_swap_dataERS4_operator<< _sbuf_ZNSt3setIPKcSt4lessIS1_ESaIS1_EE11equal_rangeERKS1_FLAGS_gtest_catch_exceptions_ZN7testing8internal27PrettyUnitTestResultPrinter24OnEnvironmentsSetUpStartERKNS_8UnitTestEdef_optional_ZNSt6vectorIiSaIiEE5frontEvtruncreporter_ZNSbIwSt11char_traitsIwESaIwEE4_Rep9_S_createEjjRKS1__ZN7testing8internal18g_linked_ptr_mutexE_ZNSt6vectorIPcSaIS0_EE4rendEv_ZN7testing8internal18OsStackTraceGetterD2Ev_ZNKSbIwSt11char_traitsIwESaIwEE7compareERKS2___throw_bad_cast__uninitialized_copy_a_ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EE6assignEjRKS2_strtoull__ostream_insert >fwprintf_Destroy__is_normal_iterator_ZN9__gnu_cxx14__alloc_traitsISaIN7testing14TestPartResultEEE7destroyERS3_PS2__ZN7testing8internal17StreamingListener18OnTestProgramStartERKNS_8UnitTestElong int_ZNSt11char_traitsIcE6assignEPcjc_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE7_M_copyEPKSt13_Rb_tree_nodeIS1_EPS9_ToUppervector >_ZN7testing13PrintToStringIPKwEESsRKT_operator-*, std::vector > >default_xml_generatorFormatHexIntstatus_ZN9__gnu_cxx14__alloc_traitsISaISt13_Rb_tree_nodeISsEEE10_S_on_swapERS3_S5__ZNK9__gnu_cxx17__normal_iteratorIPPN7testing11EnvironmentESt6vectorIS3_SaIS3_EEEptEv_ZNSt6vectorIiSaIiEE14_M_fill_insertEN9__gnu_cxx17__normal_iteratorIPiS1_EEjRKi_ZN7testing8internal10scoped_ptrISt18basic_stringstreamIcSt11char_traitsIcESaIcEEE7releaseEv_ZN9__gnu_cxx13new_allocatorIN7testing8internal9TraceInfoEE8allocateEjPKv_ZN7testing4Test8TearDownEvarray_ZNKSt12_Vector_baseIPN7testing8internal29ParameterizedTestCaseInfoBaseESaIS3_EE19_M_get_Tp_allocatorEv_ZNSt6vectorISsSaISsEE6insertEN9__gnu_cxx17__normal_iteratorIPSsS1_EEjRKSs_ZNKSs7_M_dataEv_ZNSt12_Vector_baseIiSaIiEE13_M_deallocateEPijiteratoroperator!= >__destroy_ZN7testing8internal18StreamableToStringIxEESsRKT_socket_writer__ZN9__gnu_cxx17__normal_iteratorIPKcSsEmmEidescriptionGetDefaultFilter_ZN9__gnu_cxx17__normal_iteratorIPKcSsEmmEvbasic_string, std::allocator >_ZNK9__gnu_cxx17__normal_iteratorIPPN7testing8TestInfoESt6vectorIS3_SaIS3_EEEplEi_ZNKSt15basic_streambufIcSt11char_traitsIcEE4pptrEvIsContainerTest_ZNSs4_Rep13_M_set_leakedEvreverse_iterator >_ZNKSbIwSt11char_traitsIwESaIwEE4_Rep12_M_is_sharedEv_ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EE8_M_eraseEN9__gnu_cxx17__normal_iteratorIPS2_S4_EES8___uninit_copy*, std::basic_string*>_ZN7testing8internal13DeathTestImpl6PassedEb_ZNKSt6vectorIPN7testing17TestEventListenerESaIS2_EE4backEv_ZNK7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE7pointerEv_ZN7testing8internal5MutexaSERKS1_no_sub_ZNSs6insertEjRKSs_Rb_tree, std::allocator >, std::basic_string, std::allocator >, std::_Identity, std::allocator > >, std::less, std::allocator > >, std::allocator, std::allocator > > >_ZNSbIwSt11char_traitsIwESaIwEE15_M_replace_safeEjjPKwj_ZN7testing8internal10scoped_ptrISsEaSERKS2__ZNSt6vectorIPcSaIS0_EE5clearEv_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE24_M_get_insert_unique_posERKS1__ZN7testing8internal17TestEventRepeater20OnTestIterationStartERKNS_8UnitTestEi_S_do_ituninitialized_copySOCK_NONBLOCK_ZNK9__gnu_cxx13new_allocatorIPN7testing8TestInfoEE8max_sizeEvRunSetUpTestCase_ZNSt6vectorIPN7testing11EnvironmentESaIS2_EE8pop_backEv_ZNKSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE3endEv_ZN7testing8UnitTestD0Ev_ZN7testing8internal31GetCurrentOsStackTraceExceptTopEPNS_8UnitTestEi_ZN7testing8internal9DeathTest6CreateEPKcPKNS0_2REES3_iPPS1_random_seed_ZNK9__gnu_cxx17__normal_iteratorIPN7testing12TestPropertyESt6vectorIS2_SaIS2_EEEmiEiFilePath_Atomic_wordimpl_Format_ZNK7testing18TestEventListeners21default_xml_generatorEvos_stack_trace_getter__ZN9__gnu_cxx13new_allocatorIPcE10deallocateEPS1_j_ZN7testing17TestEventListener25OnEnvironmentsTearDownEndERKNS_8UnitTestE__is_normal_iterator_ZN7testing22EmptyTestEventListener16OnTestPartResultERKNS_14TestPartResultEpipe_ZNKSt6vectorIPcSaIS0_EE4dataEvsi_signo_ZNSt12_Destroy_auxILb0EE9__destroyIPSsEEvT_S3__ZNK9__gnu_cxx17__normal_iteratorIPKPN7testing8TestCaseESt6vectorIS3_SaIS3_EEEptEvCreateSOCK_PACKETiterator_S_keyTestRoleless, std::allocator > >allocator_KeyOfValue_ZN7testing8internal15UnitTestOptions20PatternMatchesStringEPKcS3__ZNKSt12_Vector_baseIPN7testing11EnvironmentESaIS2_EE19_M_get_Tp_allocatorEvwprintf_ZNK9__gnu_cxx17__normal_iteratorIPKSsSt6vectorISsSaISsEEE4baseEvvector >_ZN9__gnu_cxx17__normal_iteratorIPKN7testing8internal9TraceInfoESt6vectorIS3_SaIS3_EEEpLEi_ZNSt6vectorIPN7testing8TestCaseESaIS2_EE14_M_fill_assignEjRKS2_operator- >__normal_iterator > >floatdeath_test_use_forktest_cases__ZN9__gnu_cxx17__normal_iteratorIPKPN7testing8TestInfoESt6vectorIS3_SaIS3_EEEmmEv_ZNK9__gnu_cxx17__normal_iteratorIPN7testing8internal9TraceInfoESt6vectorIS3_SaIS3_EEEptEv_ZNSt6vectorISsSaISsEE4dataEv__needlenum_chars_M_repBiggestInt_ZN7testing7FloatLEEPKcS1_ff_Iter_base<__gnu_cxx::__normal_iterator > >, true>set_child_pid__copy_mFLAGS_gtest_list_testsmbrlen_ZNSs9push_backEc_ZN9__gnu_cxx17__normal_iteratorIPKPN7testing17TestEventListenerESt6vectorIS3_SaIS3_EEEppEiGetParam()re_pattern_buffer_ZN7testing4TestD2Ev_ZNK7testing8internal13FloatingPointIfE13exponent_bitsEvssize_t_ZN9__gnu_cxx17__normal_iteratorIPKPN7testing17TestEventListenerESt6vectorIS3_SaIS3_EEEppEvreverse_iterator<__gnu_cxx::__normal_iterator > > >_ZNKSt12_Vector_baseIPN7testing8TestCaseESaIS2_EE13get_allocatorEvargc_Ios_Fmtflags_M_replace_aux_ZN7testing8internal7PrintToEPKcPSo~CapturedStream__niter_baseresize_ZSt18_Rb_tree_decrementPSt18_Rb_tree_node_base_ZNSt11char_traitsIcE11to_int_typeERKc_ZN7testing14ExitedWithCodeaSERKS0_argvoperator<< _ZN7testing32ScopedFakeTestPartResultReporterC2EPNS_19TestPartResultArrayE_ZNSt6vectorISsSaISsEE15_M_erase_at_endEPSserrors_ZNKSt6vectorIPN7testing8TestInfoESaIS2_EEixEj_ZN7testing8internal12UnitTestImpl26RegisterParameterizedTestsEvDerivedforever_ZNK7testing19TestPartResultArray17GetTestPartResultEi_ZNKSs17find_first_not_ofEcjseconds_IIter__niter_base_ZN7testing7MessageaSERKS0___elision_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE12_M_erase_auxESt23_Rb_tree_const_iteratorIS1_E_ZNSt6vectorIiSaIiEE6resizeEji_ZNSt12_Vector_baseIPN7testing8TestCaseESaIS2_EE11_M_allocateEjUrlEncode_ZNK9__gnu_cxx13new_allocatorIcE7addressERc_ZNSt10_Iter_baseIN9__gnu_cxx17__normal_iteratorIPPN7testing17TestEventListenerESt6vectorIS4_SaIS4_EEEELb1EE7_S_baseES9_CurrentStackTrace_ZN7testing8internal16DeathTestFactory6CreateEPKcPKNS0_2REES3_iPPNS0_9DeathTestE__data_ZNK9__gnu_cxx17__normal_iteratorIPN7testing14TestPartResultESt6vectorIS2_SaIS2_EEEdeEvtest_part_resultsTestCaseFaileddiv_t__normal_iterator > >reverse_iterator<__gnu_cxx::__normal_iterator > > >_ZNSt17_Rb_tree_iteratorIPKcEmmEi_ZN7testing4Test11DeleteSelf_EvStrDup__copy_move_ZNK7testing8TestInfo4nameEv_ZNSt6vectorIPN7testing8TestInfoESaIS2_EE5eraseEN9__gnu_cxx17__normal_iteratorIPS2_S4_EE_ZNSs16_S_construct_auxIPKcEEPcT_S3_RKSaIcESt12__false_type_ZNSt17_Rb_tree_iteratorIPKcEmmEv__dynamic_cast__is_move_iterator~XmlUnitTestResultPrinterBasicNarrowIoManip__list_ZNSt9basic_iosIcSt11char_traitsIcEE4fillEctv_nsec_ZN7testing38FLAGS_gtest_show_internal_stack_framesEUnlock_ZNK7testing10TestResult15HasFatalFailureEvpthread_setspecific__dnewinput_iterator_tag~ParameterizedTestCaseRegistryprinted_test_case_name_M_start_ZNK9__gnu_cxx13new_allocatorIwE8max_sizeEvusedSkipCommaTestPartResultReporterInterface__numeric_traits_integer_ZNSt6vectorIN7testing14TestPartResultESaIS1_EE8_M_eraseEN9__gnu_cxx17__normal_iteratorIPS1_S3_EE_ZN7testing8TestCase14TestReportableEPKNS_8TestInfoEUInt_ZNK7testing8internal13FloatingPointIfE6is_nanEv_ZNK9__gnu_cxx17__normal_iteratorIPPN7testing8TestCaseESt6vectorIS3_SaIS3_EEEplEioperator!= >_ZNK9__gnu_cxx17__normal_iteratorIPN7testing14TestPartResultESt6vectorIS2_SaIS2_EEEixEidefault_xml_generator__ZN7testing8internal17StreamingListener15OnTestCaseStartERKNS_8TestCaseE_ZNSt6vectorIPN7testing8TestInfoESaIS2_EEixEjstackset_up_tc_TEST_F_namesecond_ZNSsaSERKSsis_disabled_OnEnvironmentsTearDownEnd~SocketWriter_Num_ZNSt6vectorIPN7testing11EnvironmentESaIS2_EE15_M_erase_at_endEPS2__ZNKSt6vectorIiSaIiEE12_M_check_lenEjPKc_ZN9__gnu_cxx14__alloc_traitsISaIiEE10_S_on_swapERS1_S3__ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEED0Evdashstatement_ZN7testing22FLAGS_gtest_print_timeE_ZNSt12_Vector_baseIN7testing12TestPropertyESaIS1_EE19_M_get_Tp_allocatorEv_ZNKSt13_Bit_iteratormiEiExitedWithCodehintstm_gmtoff_ZN9__gnu_cxx14__alloc_traitsISaIPN7testing8TestInfoEEE17_S_select_on_copyERKS4__ZN7testing8internal14CmpHelperSTRNEEPKcS2_PKwS4__ZNKSt3setISsSt4lessISsESaISsEE3endEvoperator<< _ZN7testing7MessageC2ERKS0_UniversalPrintArrayst_blocks_ZN7testing8internal12UnitTestImpl25set_os_stack_trace_getterEPNS0_27OsStackTraceGetterInterfaceEpthread_tprefix_ZN9__gnu_cxx14__alloc_traitsISaIPN7testing8internal29ParameterizedTestCaseInfoBaseEEE8allocateERS5_jDeathTestThreadWarningdata_ZN9__gnu_cxx17__normal_iteratorIPPcSt6vectorIS1_SaIS1_EEEppEv_ZNKSs4sizeEv__miter_base_ZN7testing8internal17StreamingListener20AbstractSocketWriter4SendERKSsallocator > >_ZNSt6vectorIPcSaIS0_EE9push_backERKS0_ai_addrlenkNonFatalFailure_ZNKSbIwSt11char_traitsIwESaIwEE2atEj_ZN7testing8internal21StackLowerThanAddressEPKvPbStat_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE29_M_get_insert_hint_unique_posESt23_Rb_tree_const_iteratorISsERKSs_ZNSt17_Rb_tree_iteratorISsEppEic_str_ZN7testing8internal13CaptureStreamEiPKcPPNS0_14CapturedStreamEsi_statusParseGoogleTestFlagsOnly_ZNK7testing8UnitTest19disabled_test_countEv__niter_baseoperator<< _ZNKSt6vectorIPN7testing8TestInfoESaIS2_EE2atEjg_captured_stdout_ZN9__gnu_cxx14__alloc_traitsISaIPKcEE8max_sizeERKS3__ZN7testing22EmptyTestEventListener25OnEnvironmentsTearDownEndERKNS_8UnitTestEdeath_test_style_ZNKSs15_M_check_lengthEjjPKc_ZN9__gnu_cxx14__alloc_traitsISaIPN7testing8TestCaseEEE10_S_on_swapERS4_S6__ZNK9__gnu_cxx13new_allocatorIwE7addressERwoperator new_ZN9__gnu_cxx17__normal_iteratorIPKPN7testing8TestCaseESt6vectorIS3_SaIS3_EEEmmEi__class_type_info_ZNK9__gnu_cxx17__normal_iteratorIPSsSt6vectorISsSaISsEEEptEvbadbit_ZN7testing8TestInfoD2EvGetTestInfo_ZN9__gnu_cxx17__normal_iteratorIPKPN7testing8TestCaseESt6vectorIS3_SaIS3_EEEmmEvruntime_errorEndsWithCaseInsensitivevector >__countGTestMutexLocksam1ostreamsam2long_value_ZN7testing8internal8GTestLogD2Ev_Vector_base >_ZN7testing8internal18GetInjectableArgvsEv_ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EE6insertEN9__gnu_cxx17__normal_iteratorIPS2_S4_EERKS2__ZN9__gnu_cxx17__normal_iteratorIPKSsSt6vectorISsSaISsEEEppEi_ZN9__gnu_cxx17__normal_iteratorIPKPN7testing8TestInfoESt6vectorIS3_SaIS3_EEEpLEi_ZNKSt6vectorIN7testing12TestPropertyESaIS1_EE4rendEvrebind_ZN9__gnu_cxx17__normal_iteratorIPKSsSt6vectorISsSaISsEEEppEv_ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EE7reserveEj_ZNSt12_Vector_baseIPN7testing8TestCaseESaIS2_EE13_M_deallocateEPS2_j_ZNSt12_Vector_baseIN7testing14TestPartResultESaIS1_EE12_Vector_impl12_M_swap_dataERS4_Setupsuccessful_test_case_countstat_ZNSt6vectorIiSaIiEE4swapERS1_exceptionReadAndInterpretStatusByte_ZN7testing8internal18OsStackTraceGetter19kElidedFramesMarkerEsa_restorerallocator_ZNSt3setIPKcSt4lessIS1_ESaIS1_EE4swapERS5__M_node_ZNSs6assignEPKcj_ZN7testing8internal15GetUnitTestImplEvShuffleTests__iterator_categoryconst_pointer_ZNK9__gnu_cxx13new_allocatorIPN7testing8internal29ParameterizedTestCaseInfoBaseEE7addressERKS4_fgetws_ZNKSt3setIPKcSt4lessIS1_ESaIS1_EE13get_allocatorEvrand__cursummaryArrayAsVector<8>int_p_sign_posn_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE5eraseESt23_Rb_tree_const_iteratorIS1_E_ZN7testing8internal12UnitTestImpl11AddTestInfoEPFvvES3_PNS_8TestInfoE_ZNSt6vectorISsSaISsEE5eraseEN9__gnu_cxx17__normal_iteratorIPSsS1_EE_ZN9__gnu_cxx13new_allocatorIPN7testing11EnvironmentEE9constructEPS3_RKS3_GetReservedAttributesForElementmode_ZN9__gnu_cxx13new_allocatorIiE7destroyEPioperator<< _ZNSt6vectorIN7testing12TestPropertyESaIS1_EE4swapERS3_operator<< tm_sec__size_typekMaxParamLength_ZN9__gnu_cxx13new_allocatorIPKcE8allocateEjPKv__static_initialization_and_destruction_0new_allocator_ZN7testing8internal8GTestLogC2ENS0_16GTestLogSeverityEPKciactual_valueoperator<< _ZNSo3putEc_ZNK7testing10TestResult17test_part_resultsEvmessageTraceInfo__normal_iterator > >_ZN7testing22EmptyTestEventListener20OnTestIterationStartERKNS_8UnitTestEiFLAGS_gtest_shuffle_ZNSs7replaceEjjRKSs_ZN7testing8internal17StreamingListener12SocketWriteraSERKS2_new_allocator, std::allocator > > >value_paramArrayAsVector<6>_ZNSs4_Rep9_S_createEjjRKSaIcE__addressof >kValueParamLabel_Destroy_ZdlPv_ZNKSt3setIPKcSt4lessIS1_ESaIS1_EE8key_compEv_ZNKSbIwSt11char_traitsIwESaIwEE16find_last_not_ofEwjlist_tests__ZN9__gnu_cxx14__alloc_traitsISaIiEE8max_sizeERKS1_~ValueHolder_ZN7testing8internal18PrintCharAndCodeToIhaEEvT0_PSo_ZNKSt3setIPKcSt4lessIS1_ESaIS1_EE11upper_boundERKS1_term_supports_color_Rb_tree_increment_ZNKSt9_IdentityIPKcEclERS1__ZN9__gnu_cxx13new_allocatorISt13_Rb_tree_nodeIPKcEE9constructEPS4_RKS4__S_base_ZNSs7replaceEN9__gnu_cxx17__normal_iteratorIPcSsEES2_S2_S2__ZNKSt6vectorIN7testing8internal9TraceInfoESaIS2_EE4dataEv_ZNK7testing8internal12UnitTestImpl21total_test_case_countEv_ZNSt6vectorIPcSaIS0_EEixEj~OsStackTraceGetterkTestTypeIdInGoogleTestdeallocatemask_ZNKSt3setIPKcSt4lessIS1_ESaIS1_EE3endEv_Reppbase_ZN7testing8internal14ParseInt32FlagEPKcS2_Pi_ZN7testing8TestCaseC2EPKcS2_PFvvES4_AddTestPartResult__is_normal_iteratorfprintf_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE6_M_endEvtotal_part_count_ZNSt12_Vector_baseIN7testing8internal9TraceInfoESaIS2_EE17_M_create_storageEjnot_eofSkipSpacesnot_eolPrintToString_ZNSs4_Rep12_S_empty_repEvmon_decimal_pointcurrent_test_case_operator<< _ZNKSs17find_first_not_ofEPKcjoperator<< vector >unitbuf_ZNKSbIwSt11char_traitsIwESaIwEE8_M_checkEjPKcPartialMatchiterator_traits<__gnu_cxx::__normal_iterator > > >in_death_test_child_process~DefaultPerThreadTestPartResultReporter_ZNSs9_M_assignEPcjc_ZNK7testing8internal8FilePath14IsAbsolutePathEv_ZNSt11char_traitsIwE4findEPKwjRS1_ValidateTestPropertyNamereferencerfind_Referencewscanf_ZN7testing8internal12AssertHelperC2ENS_14TestPartResult4TypeEPKciS5___osize_DestroyToPrint_ZNK9__gnu_cxx13new_allocatorIiE7addressERKi_ZN7testing8internal8FilePath9NormalizeEv_ZN9__gnu_cxx17__normal_iteratorIPSsSt6vectorISsSaISsEEEppEi_ZNKSt6vectorIiSaIiEE5frontEv_ZN7testing8internal24XmlUnitTestResultPrinter26RemoveInvalidXmlCharactersERKSs__are_same_ZNK7testing8internal12UnitTestImpl16catch_exceptionsEvkRandomSeedFlag__iterator_category<__gnu_cxx::__normal_iterator*, std::vector > > >_ZlsRKN7testing8internal6SecretEi_ZN9__gnu_cxx17__normal_iteratorIPSsSt6vectorISsSaISsEEEppEv_ZNK7testing8UnitTest26successful_test_case_countEvoperator()<__gnu_cxx::__normal_iterator > >_S_showpoint_ZN7testing8internal17TestEventRepeater25OnEnvironmentsTearDownEndERKNS_8UnitTestE_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE11upper_boundERKS1__IO_lock_t_ZN9__gnu_cxx14__alloc_traitsISaIN7testing12TestPropertyEEE10_S_on_swapERS3_S5__ZN9__gnu_cxx13new_allocatorIPN7testing8internal29ParameterizedTestCaseInfoBaseEE8allocateEjPKv_ZN7testing8internal13DeathTestImpl11set_outcomeENS0_16DeathTestOutcomeE_ZN9__gnu_cxx24__numeric_traits_integerIiE5__minE_ZN7testing31TestPartResultReporterInterfaceaSERKS0__ZNSt12_Vector_baseIPN7testing11EnvironmentESaIS2_EE19_M_get_Tp_allocatorEv__copy_m_ZN7testing8internal23MakeAndRegisterTestInfoEPKcS2_S2_S2_PKvPFvvES6_PNS0_15TestFactoryBaseEnew_allocator_ZNK9__gnu_cxx13new_allocatorIN7testing14TestPartResultEE7addressERS2__ZNSt6vectorIN7testing12TestPropertyESaIS1_EE4backEvEventForwardingEnabled__alloc_traits >_Rb_tree_impl, false>_ZN7testing8internal8FilePath3SetERKS1_should_runstring_ZNKSt17_Rb_tree_iteratorISsEneERKS0_kTypeParamLabel__simplefork_ZNSt11char_traitsIcE4findEPKcjRS1___is_move_iteratorproperty_with_matching_keylong long int_ZNKSt3setIPKcSt4lessIS1_ESaIS1_EE8max_sizeEv_ZNSt16reverse_iteratorIN9__gnu_cxx17__normal_iteratorIPPN7testing11EnvironmentESt6vectorIS4_SaIS4_EEEEEmmEv_ZNSt6vectorIiSaIiEE8_M_eraseEN9__gnu_cxx17__normal_iteratorIPiS1_EES5_intptr_t_ZNKSt16reverse_iteratorIN9__gnu_cxx17__normal_iteratorIPPN7testing11EnvironmentESt6vectorIS4_SaIS4_EEEEE4baseEv_ZN7testing8internal26GoogleTestFailureExceptionD2Ev_ZNSt6vectorIPN7testing8TestCaseESaIS2_EE5clearEv_ZNKSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE11upper_boundERKS1__ZNSs7replaceEN9__gnu_cxx17__normal_iteratorIPcSsEES2_RKSs_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE6rbeginEv_ZN9__gnu_cxx17__normal_iteratorIPKPN7testing8TestCaseESt6vectorIS3_SaIS3_EEEpLEi_ZNK7testing8UnitTest21successful_test_countEv_ZN9__gnu_cxx13new_allocatorIN7testing8internal9TraceInfoEE7destroyEPS3__ZN9__gnu_cxx14__alloc_traitsISaIiEE8allocateERS1_jcopyMatchesFilteroperator<=19pthread_mutexattr_t_ZN7testing8internal2RED2Ev_ZN7testing10TestResult14RecordPropertyERKSsRKNS_12TestPropertyECountIf, bool (*)(const testing::TestPartResult&)>_ZNSt6vectorIN7testing12TestPropertyESaIS1_EE2atEjGNU C++ 4.9.2 20150212 (Red Hat 4.9.2-6) -mtune=generic -march=i686 -g -O2LastMessage_ZNKSt6vectorIPN7testing17TestEventListenerESaIS2_EE4rendEv_ZNK7testing8TestCase17failed_test_countEvscoped_ptr, std::allocator > >_Iter_basegtest_color_ZNKSs12find_last_ofEcj_ZNKSt23_Rb_tree_const_iteratorIPKcEneERKS2__ZN9__gnu_cxx13new_allocatorIN7testing8internal9TraceInfoEE10deallocateEPS3_j_ZNK7testing8internal13FloatingPointIdE13fraction_bitsEv_ZNSt8_Rb_treeIPKcS1_St9_IdentityIS1_ESt4lessIS1_ESaIS1_EE4swapERS7__ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE8_S_rightEPKSt18_Rb_tree_node_base_ZN7testing8internal8FilePathaSERKS1_vector >_ZNKSbIwSt11char_traitsIwESaIwEE6substrEjj_ZN7testing8internal11CmpHelperNEEPKcS2_xx_S_dec_DestroyFilterTestsfirst_test_nameTestCaseInfoContainer_ZNSt3setIPKcSt4lessIS1_ESaIS1_EE5clearEva_type_param_ZNK9__gnu_cxx13new_allocatorIN7testing8internal9TraceInfoEE7addressERS3__ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE12_M_rightmostEv_ZNKSt18_Bit_iterator_basegtERKS_GCC: (GNU) 4.9.2 20150212 (Red Hat 4.9.2-6)zR| 0DXl    4H\p$8L 0AnhP*Ah*Ah*Ah  4#H\p$8zPLR| @$0vAB Fc.[ AAA F D AAA A ACE LA(!AC$I(E,A0HC !ACK LA48NAA AkFA LJ AA4pPNAA AkFA LJ AA4NAA AkFA LJ AA4NAA AkFA LJ AA4@NAA AkFA LJ AA4PNAA AkFA LJ AA4OAA AvFA FF AA40OAA AvFA FF AA4OAA AvFA FF AA40OAA AvFA FF AA4h OAA AvFA FF AAHp[AA AAC o$F(A,A0L LAA AAHTAA AAC r$F(A,A0F HAA AA0800AA ENF FL AADl`mAA AAE0}AA APBA HJAA HI AA 0  @ % p   ( *AhD CV\  CVt 0 CV P CV p CV CV CV( !AC$I(E,A0HC$HAH8BAA CH NJG HG AA$0P(AA COA HGEA HG  AAE CEA HGEA HGEA HHE HAEA HGEA HGEA HGEA HGEA HGEA HGEA HF CAtHA AwAE HAAF TA  AAB CAAF HA  AAJ CE HKF s,CEB ]0,CEB ]0PDACIB HCBE ]At0AA AC { A AAD G,E0H L$A(E,E0J G,E0H C$A(E,E0H C A AAC pxAA CAH0(H&CAC `,D0HAG 4,"@>AB F. AAA A 4d"?AB Fy. AAA G <"AB Ch.L.R.c.R.`AAA @"A$2AB I{ AAA F ]. AAA G @ #EAB Fo.O AAA F G AAA A @d#EAB Fx.W AAA E F AAA G @#FtAB Ca. AAA A g AAA A L4(PHjAA AC T,D0H f C AAG LC AA0(HPAC P,D0H Z CC LCDp$IAB Im.y AAA K  AAA A D$AB F. AAA G L AAA A 4%JK?AB FL AAA H .48%0PAB Oo. AAA D 4p% SAB C. AAA F 8%VvAB Oo. AAA H r.8%Y9AB Or. AAA H z.4 &@]jAB IU.G AAA E 4X&_AB Iy.V AAA J (*KAC ],G0PAG <+KAA AC a,A0H E A AAH 4&aAB Fi. AAA E 04'd#AB Ec.r AA I 4h'eAB IO. AAA G 4'yLAB F[.f AAA C 0'WXAB E].N AA C 4 (uhAB Fc.d AAA C 4D(gtAB Ft AAA H a.4|(@iAB IP. AAA F 4( kAB CJ.j AAA C 4-lACWCHT- lOAC O$B(A,A0E,C E AK C$E(E,A0H EA4X)plwAB G[.[ H N A 4)lwAB G[.[ H N A 4)pmgAB CT.k AAA A 4*m5AB C~ AAA I A.@. p\CMBEA HE K C M CBEA HHx.pAA CAG$B(E,A0H ^,A0H G$B(E,A0H$B(E,A0H S$B(E,A0H CAA AA4@/ qTAA Cx  AAI C CA\x/qaAA COAA HBEA P GAJCBEA HC AA/q<+lAB C{..f. AAA I 4+rRAB Fe AAA G Z.U. 4,riAB Fe AAA G Z.U. x0sAA CAG4B8EJ AB FG AAA E d. AAA A D`8>q AB FG AAA E d. AAA A 48СI AB FL AAA H g.D8  AB F  AAA D d.u AAA A D(9 AB Fd. AAA D t AAA A Dp9 AB CN. AAA E } AAA A <9P0 AB E\.u AA E i AA A 49 G AB DM D N.v D 00:]W AB HZ. AA A @d:= AG Cn.\ AAA H g AAA F @:P AB Ci.[ AAA C V AAA C D:\ AB Cc. AAA D  AAA A D4;T AB C`. AAA C  AAA A D|;6AB Cl. AAA B  AAA A 4;=vAB F].y AAA F 4;AB Ih.] AAA D 04<AB H\.] AA J 4h<AB Ih.] AAA D 0<AB HU.] AA A 4<(AB Ih.] AAA D D =@BJAL F^.Q AAA C  AAA C 0T=AB Hj.] AA D D=VAB Cr.a AAA D ] AAA H (B/AHIED NC(DB ,AEIED NCD(>P6AB C`.a AAA F P AAA E (B-AHHDD NC(B*AEHDD NCP>}AB C^.Q.J..J.Z AAA I P AAA E (dCp-AHHDD NC(C*AEHDD NCDt?з4AB Cn. AAA H ] AAA H (D/AHIED NC(0D,AEIED NC4@rAB Ih.] AAA D 4L@AB Ih.] AAA D D@ 2AB Fv AAA F R. AAA J 4@HAB Ih.] AAA D 4A`jAB Fe AAA G Z.D"AB IZ.{.S.`.S.].S.Z AAA A  AAA A D]_"AB C\. AAA I _ AAA F 8 ^4#AB Fj.m AAA A .DH^dx#AB FN. AAA A  AAA A 4^h#AB Cl.R AAA I ch4^#YB Fd. AAA G \ci4(_#AB FY AAA K ^.ci(cFAA C ~ AA8_($AB Fj AAA J ..4_ id$AB I\.9 AAA D H`l$AB Ck.X.R. f AAA D c AAA A L``mX$AB Cb. U.i. M.S AAA G [ AAA B H` o$AB Ip.y. M.v AAA A I AAA A 4`q"%AB C`.y AAA A `4ar9%AB Fx.A. J.k AAA F ]. J.m AAA I K AAA B <awv%AB F AAA F R.c. e.4ay}%AB Di. Y G L A @b%AB Ec.I AA J T.J.h.J.{.f zACL AG KA JTBBD HLA JPBBD HC AC CA JPBBD HEA EJA EJA E@b &AB Ec.I AA J T.J.j.J.}.pg{AA FAE@YHILAPDLAHBLEPL@TDBHBLCPH@VLAPJ@[DAHALAPFLAHBLEPALAHFLAPI@M AA AAD CLAPH@OLAPE@RLAPE@$h|@cd&AB Ec.I AA J T.J.h.J.{.|h|AA AAEP_XI\A`PP[TAXA\A`F\AXB\E`QPcXA\A`HP`XB\E`A\D`PPWTAXA\A`F\CXA\A`TAA AAKPC\A`EPJ\A`EP4i~Te~&AB F AAA A V AAA A a. AAA A @Xe&AB Ec.I AA J T.J.j.J.}.0e`0'FB Bk.i AA H @e@>'AB Fn.| AAA J  AAA D \jІCL8,f~t'AB F.~ AAA A .Dhf'AB Fu.d AAA K  AAA G 8f'AB A_.a.M.Y F [ A 8f(AB Fj.| AAA A ^.8(gh4(AB F{.0 AAA A .4dg(AB FM.} AAA J 4g(AB Fv.d AAA J 4gP(AB Fv.d AAA J 4 h(AB Fy.d AAA G 8Dh(AB F`.g AAA A B.8h)AB Fm. AAA A =.HhЌl)AB FY AAA K r.t. .x AAA H <i)AB Eb.r AA B | AA B <Hip)AB BX.t AA E d AA A m0CHDDA H0iP)AB GR.h.M.y F (nAC,E0H$E(E,E0F,A(B,E0F,A(B,E0P,A(B,E0F,A(E,E0M$E(A,E0H$E(E,E0F,A(E,E0H$A(A,E0H$E(E,E0F,A(E,E0H$A(A,E0H$E(E,E0F,A(B,E0F,F(B,E0K,A(B,E0F,F(B,E0K,A(B,E0F,F(E,E0H$A(A,E0H$E(E,E0F,A(B,E0H$T(E,E0F,A(E,E0R$A(A,E0H$E(E,E0F,A(B,E0H$F(E,E0H$E(E,E0H$O(E,E0H$Y(E,E0RA.symtab.strtab.shstrtab.rel.text.data.bss.text.unlikely._ZNKSt5ctypeIcE8do_widenEc.text._ZNKSt5ctypeIcE8do_widenEc.text.unlikely._ZN7testing8internal26ThreadLocalValueHolderBaseD2Ev.text._ZN7testing8internal26ThreadLocalValueHolderBaseD2Ev.text.unlikely.DeleteThreadLocalValue.text.DeleteThreadLocalValue.text.unlikely._ZN7testing4Test11DeleteSelf_Ev.text._ZN7testing4Test11DeleteSelf_Ev.text.unlikely._ZN7testing4Test5SetupEv.text._ZN7testing4Test5SetupEv.text.unlikely._ZN7testing8TestCase16RunSetUpTestCaseEv.text._ZN7testing8TestCase16RunSetUpTestCaseEv.text.unlikely._ZN7testing8TestCase19RunTearDownTestCaseEv.text._ZN7testing8TestCase19RunTearDownTestCaseEv.text.unlikely._ZN7testing11EnvironmentD2Ev.text._ZN7testing11EnvironmentD2Ev.text.unlikely._ZN7testing11Environment5SetUpEv.text._ZN7testing11Environment5SetUpEv.text.unlikely._ZN7testing11Environment8TearDownEv.text._ZN7testing11Environment8TearDownEv.text.unlikely._ZN7testing11Environment5SetupEv.text._ZN7testing11Environment5SetupEv.text.unlikely._ZN7testing22EmptyTestEventListener18OnTestProgramStartERKNS_8UnitTestE.text._ZN7testing22EmptyTestEventListener18OnTestProgramStartERKNS_8UnitTestE.text.unlikely._ZN7testing22EmptyTestEventListener20OnTestIterationStartERKNS_8UnitTestEi.text._ZN7testing22EmptyTestEventListener20OnTestIterationStartERKNS_8UnitTestEi.text.unlikely._ZN7testing22EmptyTestEventListener24OnEnvironmentsSetUpStartERKNS_8UnitTestE.text._ZN7testing22EmptyTestEventListener24OnEnvironmentsSetUpStartERKNS_8UnitTestE.text.unlikely._ZN7testing22EmptyTestEventListener22OnEnvironmentsSetUpEndERKNS_8UnitTestE.text._ZN7testing22EmptyTestEventListener22OnEnvironmentsSetUpEndERKNS_8UnitTestE.text.unlikely._ZN7testing22EmptyTestEventListener15OnTestCaseStartERKNS_8TestCaseE.text._ZN7testing22EmptyTestEventListener15OnTestCaseStartERKNS_8TestCaseE.text.unlikely._ZN7testing22EmptyTestEventListener11OnTestStartERKNS_8TestInfoE.text._ZN7testing22EmptyTestEventListener11OnTestStartERKNS_8TestInfoE.text.unlikely._ZN7testing22EmptyTestEventListener16OnTestPartResultERKNS_14TestPartResultE.text._ZN7testing22EmptyTestEventListener16OnTestPartResultERKNS_14TestPartResultE.text.unlikely._ZN7testing22EmptyTestEventListener9OnTestEndERKNS_8TestInfoE.text._ZN7testing22EmptyTestEventListener9OnTestEndERKNS_8TestInfoE.text.unlikely._ZN7testing22EmptyTestEventListener13OnTestCaseEndERKNS_8TestCaseE.text._ZN7testing22EmptyTestEventListener13OnTestCaseEndERKNS_8TestCaseE.text.unlikely._ZN7testing22EmptyTestEventListener27OnEnvironmentsTearDownStartERKNS_8UnitTestE.text._ZN7testing22EmptyTestEventListener27OnEnvironmentsTearDownStartERKNS_8UnitTestE.text.unlikely._ZN7testing22EmptyTestEventListener25OnEnvironmentsTearDownEndERKNS_8UnitTestE.text._ZN7testing22EmptyTestEventListener25OnEnvironmentsTearDownEndERKNS_8UnitTestE.text.unlikely._ZN7testing22EmptyTestEventListener18OnTestIterationEndERKNS_8UnitTestEi.text._ZN7testing22EmptyTestEventListener18OnTestIterationEndERKNS_8UnitTestEi.text.unlikely._ZN7testing22EmptyTestEventListener16OnTestProgramEndERKNS_8UnitTestE.text._ZN7testing22EmptyTestEventListener16OnTestProgramEndERKNS_8UnitTestE.text.unlikely._ZN7testing8internal17StreamingListener20AbstractSocketWriter15CloseConnectionEv.text._ZN7testing8internal17StreamingListener20AbstractSocketWriter15CloseConnectionEv.text.unlikely._ZN7testing22EmptyTestEventListenerD2Ev.text._ZN7testing22EmptyTestEventListenerD2Ev.rel.text.unlikely.text.unlikely._ZN7testing8internal27PrettyUnitTestResultPrinter18OnTestProgramStartERKNS_8UnitTestE.text._ZN7testing8internal27PrettyUnitTestResultPrinter18OnTestProgramStartERKNS_8UnitTestE.text.unlikely._ZN7testing8internal27PrettyUnitTestResultPrinter22OnEnvironmentsSetUpEndERKNS_8UnitTestE.text._ZN7testing8internal27PrettyUnitTestResultPrinter22OnEnvironmentsSetUpEndERKNS_8UnitTestE.text.unlikely._ZN7testing8internal27PrettyUnitTestResultPrinter25OnEnvironmentsTearDownEndERKNS_8UnitTestE.text._ZN7testing8internal27PrettyUnitTestResultPrinter25OnEnvironmentsTearDownEndERKNS_8UnitTestE.text.unlikely._ZN7testing8internal27PrettyUnitTestResultPrinter16OnTestProgramEndERKNS_8UnitTestE.text._ZN7testing8internal27PrettyUnitTestResultPrinter16OnTestProgramEndERKNS_8UnitTestE.text.unlikely._ZN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE11ValueHolderD2Ev.text._ZN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE11ValueHolderD2Ev.text.unlikely._ZN7testing8internal23DefaultDeathTestFactoryD2Ev.text._ZN7testing8internal23DefaultDeathTestFactoryD2Ev.text.unlikely._ZN7testing8internal27PrettyUnitTestResultPrinterD2Ev.text._ZN7testing8internal27PrettyUnitTestResultPrinterD2Ev.text.unlikely._ZN7testing8internal38DefaultPerThreadTestPartResultReporterD2Ev.text._ZN7testing8internal38DefaultPerThreadTestPartResultReporterD2Ev.text.unlikely._ZN7testing8internal35DefaultGlobalTestPartResultReporterD2Ev.text._ZN7testing8internal35DefaultGlobalTestPartResultReporterD2Ev.text.unlikely._ZN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE11ValueHolderD0Ev.rel.text._ZN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE11ValueHolderD0Ev.text.unlikely._ZN7testing8internal26ThreadLocalValueHolderBaseD0Ev.rel.text._ZN7testing8internal26ThreadLocalValueHolderBaseD0Ev.text.unlikely._ZN7testing11EnvironmentD0Ev.rel.text._ZN7testing11EnvironmentD0Ev.text.unlikely._ZN7testing8internal23DefaultDeathTestFactoryD0Ev.rel.text._ZN7testing8internal23DefaultDeathTestFactoryD0Ev.text.unlikely._ZN7testing8internal38DefaultPerThreadTestPartResultReporterD0Ev.rel.text._ZN7testing8internal38DefaultPerThreadTestPartResultReporterD0Ev.text.unlikely._ZN7testing8internal35DefaultGlobalTestPartResultReporterD0Ev.rel.text._ZN7testing8internal35DefaultGlobalTestPartResultReporterD0Ev.text.unlikely._ZN7testing8internal27PrettyUnitTestResultPrinterD0Ev.rel.text._ZN7testing8internal27PrettyUnitTestResultPrinterD0Ev.text.unlikely._ZN7testing22EmptyTestEventListenerD0Ev.rel.text._ZN7testing22EmptyTestEventListenerD0Ev.rel.gcc_except_table.rodata.str1.1.text.unlikely._ZN7testing8internal26GoogleTestFailureExceptionD2Ev.rel.text._ZN7testing8internal26GoogleTestFailureExceptionD2Ev.text.unlikely._ZN7testing8internal26GoogleTestFailureExceptionD0Ev.rel.text._ZN7testing8internal26GoogleTestFailureExceptionD0Ev.text.unlikely._ZN7testing8internal24XmlUnitTestResultPrinterD2Ev.rel.text._ZN7testing8internal24XmlUnitTestResultPrinterD2Ev.text.unlikely._ZN7testing8internal24XmlUnitTestResultPrinterD0Ev.rel.text._ZN7testing8internal24XmlUnitTestResultPrinterD0Ev.text.unlikely._ZN7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEE11ValueHolderD2Ev.rel.text._ZN7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEE11ValueHolderD2Ev.text.unlikely._ZN7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEE11ValueHolderD0Ev.rel.text._ZN7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEE11ValueHolderD0Ev.text.unlikely._ZNSt6vectorISsSaISsEED2Ev.rel.text._ZNSt6vectorISsSaISsEED2Ev.rodata.str1.4.text.unlikely._ZN7testing8internal29ParameterizedTestCaseRegistryD2Ev.rel.text._ZN7testing8internal29ParameterizedTestCaseRegistryD2Ev.text.unlikely._ZN7testing15AssertionResult13AppendMessageERKNS_7MessageE.rel.text._ZN7testing15AssertionResult13AppendMessageERKNS_7MessageE.text.unlikely._ZN7testing14TestPartResultD2Ev.rel.text._ZN7testing14TestPartResultD2Ev.text.unlikely._ZN7testing12TestPropertyD2Ev.rel.text._ZN7testing12TestPropertyD2Ev.text.unlikely._ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEED2Ev.rel.text._ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEED2Ev.text.unlikely._ZN7testing7MessageC2ERKS0_.rel.text._ZN7testing7MessageC2ERKS0_.rel.rodata.text.unlikely._ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEED0Ev.rel.text._ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEED0Ev.text.unlikely._ZN7testing8internal10scoped_ptrISsE5resetEPSs.rel.text._ZN7testing8internal10scoped_ptrISsE5resetEPSs.text.unlikely._ZN7testing8internal10scoped_ptrINS0_24InternalRunDeathTestFlagEE5resetEPS2_.rel.text._ZN7testing8internal10scoped_ptrINS0_24InternalRunDeathTestFlagEE5resetEPS2_.text.unlikely._ZStplIcSt11char_traitsIcESaIcEESbIT_T0_T1_ERKS6_PKS3_.rel.text._ZStplIcSt11char_traitsIcESaIcEESbIT_T0_T1_ERKS6_PKS3_.text.unlikely._ZStplIcSt11char_traitsIcESaIcEESbIT_T0_T1_EPKS3_RKS6_.rel.text._ZStplIcSt11char_traitsIcESaIcEESbIT_T0_T1_EPKS3_RKS6_.text.unlikely._ZN7testing13PrintToStringIPKcEESsRKT_.rel.text._ZN7testing13PrintToStringIPKcEESsRKT_.text.unlikely._ZN7testing13PrintToStringIPKwEESsRKT_.rel.text._ZN7testing13PrintToStringIPKwEESsRKT_.text.unlikely._ZN7testing8internal18StreamableToStringIiEESsRKT_.rel.text._ZN7testing8internal18StreamableToStringIiEESsRKT_.text.unlikely._ZN7testing8internal18StreamableToStringIxEESsRKT_.rel.text._ZN7testing8internal18StreamableToStringIxEESsRKT_.text.unlikely._ZStplIcSt11char_traitsIcESaIcEESbIT_T0_T1_ERKS6_S8_.rel.text._ZStplIcSt11char_traitsIcESaIcEESbIT_T0_T1_ERKS6_S8_.text.unlikely._ZN7testing8internal17StreamingListener12SocketWriter15CloseConnectionEv.rel.text._ZN7testing8internal17StreamingListener12SocketWriter15CloseConnectionEv.text.unlikely._ZN7testing8internal5MutexD2Ev.rel.text._ZN7testing8internal5MutexD2Ev.text.unlikely._ZN7testing8internal9MutexBase6UnlockEv.rel.text._ZN7testing8internal9MutexBase6UnlockEv.text.unlikely._ZN7testing8internal9MutexBase4LockEv.rel.text._ZN7testing8internal9MutexBase4LockEv.text.unlikely._ZN7testing8internal17StreamingListener12SocketWriter4SendERKSs.rel.text._ZN7testing8internal17StreamingListener12SocketWriter4SendERKSs.text.unlikely._ZN7testing8internal17StreamingListener12SocketWriterD2Ev.rel.text._ZN7testing8internal17StreamingListener12SocketWriterD2Ev.text.unlikely._ZN7testing8internal17StreamingListener12SocketWriterD0Ev.rel.text._ZN7testing8internal17StreamingListener12SocketWriterD0Ev.text.unlikely._ZN7testing8internal17StreamingListenerD2Ev.rel.text._ZN7testing8internal17StreamingListenerD2Ev.text.unlikely._ZN7testing8internal17StreamingListenerD0Ev.rel.text._ZN7testing8internal17StreamingListenerD0Ev.text.unlikely._ZN7testing8internal17StreamingListener20AbstractSocketWriter6SendLnERKSs.rel.text._ZN7testing8internal17StreamingListener20AbstractSocketWriter6SendLnERKSs.text.unlikely._ZN7testing8internal17StreamingListener11OnTestStartERKNS_8TestInfoE.rel.text._ZN7testing8internal17StreamingListener11OnTestStartERKNS_8TestInfoE.text.unlikely._ZN7testing8internal17StreamingListener15OnTestCaseStartERKNS_8TestCaseE.rel.text._ZN7testing8internal17StreamingListener15OnTestCaseStartERKNS_8TestCaseE.text.unlikely._ZN7testing8internal17StreamingListener16OnTestProgramEndERKNS_8UnitTestE.rel.text._ZN7testing8internal17StreamingListener16OnTestProgramEndERKNS_8UnitTestE.text.unlikely._ZN7testing8internal17StreamingListener16OnTestPartResultERKNS_14TestPartResultE.rel.text._ZN7testing8internal17StreamingListener16OnTestPartResultERKNS_14TestPartResultE.text.unlikely._ZN7testing8internal17StreamingListener20OnTestIterationStartERKNS_8UnitTestEi.rel.text._ZN7testing8internal17StreamingListener20OnTestIterationStartERKNS_8UnitTestEi.text.unlikely._ZN7testing8internal18OsStackTraceGetterD2Ev.rel.text._ZN7testing8internal18OsStackTraceGetterD2Ev.text.unlikely._ZN7testing8internal18OsStackTraceGetterD0Ev.rel.text._ZN7testing8internal18OsStackTraceGetterD0Ev.text.unlikely._ZN7testing8internal17StreamingListener18OnTestProgramStartERKNS_8UnitTestE.rel.text._ZN7testing8internal17StreamingListener18OnTestProgramStartERKNS_8UnitTestE.text.unlikely._ZN7testing8internal17StreamingListener9OnTestEndERKNS_8TestInfoE.rel.text._ZN7testing8internal17StreamingListener9OnTestEndERKNS_8TestInfoE.text.unlikely._ZN7testing8internal17StreamingListener13OnTestCaseEndERKNS_8TestCaseE.rel.text._ZN7testing8internal17StreamingListener13OnTestCaseEndERKNS_8TestCaseE.text.unlikely._ZN7testing8internal17StreamingListener18OnTestIterationEndERKNS_8UnitTestEi.rel.text._ZN7testing8internal17StreamingListener18OnTestIterationEndERKNS_8UnitTestEi.text.unlikely._ZN7testing15AssertionResultlsINS_7MessageEEERS0_RKT_.rel.text._ZN7testing15AssertionResultlsINS_7MessageEEERS0_RKT_.text.unlikely._ZN7testing15AssertionResultlsIA11_cEERS0_RKT_.rel.text._ZN7testing15AssertionResultlsIA11_cEERS0_RKT_.text.unlikely._ZN7testing15AssertionResultlsISsEERS0_RKT_.rel.text._ZN7testing15AssertionResultlsISsEERS0_RKT_.text.unlikely._ZN7testing15AssertionResultlsIA2_cEERS0_RKT_.rel.text._ZN7testing15AssertionResultlsIA2_cEERS0_RKT_.text.unlikely._ZN7testing15AssertionResultlsINS_14TestPartResultEEERS0_RKT_.rel.text._ZN7testing15AssertionResultlsINS_14TestPartResultEEERS0_RKT_.text.unlikely._ZN7testing15AssertionResultlsIA3_cEERS0_RKT_.rel.text._ZN7testing15AssertionResultlsIA3_cEERS0_RKT_.text.unlikely._ZN7testing15AssertionResultlsIPKcEERS0_RKT_.rel.text._ZN7testing15AssertionResultlsIPKcEERS0_RKT_.text.unlikely._ZN7testing15AssertionResultlsIA5_cEERS0_RKT_.rel.text._ZN7testing15AssertionResultlsIA5_cEERS0_RKT_.text.unlikely._ZN7testing15AssertionResultlsIA7_cEERS0_RKT_.rel.text._ZN7testing15AssertionResultlsIA7_cEERS0_RKT_.text.unlikely._ZN7testing15AssertionResultlsIA12_cEERS0_RKT_.rel.text._ZN7testing15AssertionResultlsIA12_cEERS0_RKT_.text.unlikely._ZN7testing8internal15FloatingPointLEIfEENS_15AssertionResultEPKcS4_T_S5_.rel.text._ZN7testing8internal15FloatingPointLEIfEENS_15AssertionResultEPKcS4_T_S5_.text.unlikely._ZN7testing8internal15FloatingPointLEIdEENS_15AssertionResultEPKcS4_T_S5_.rel.text._ZN7testing8internal15FloatingPointLEIdEENS_15AssertionResultEPKcS4_T_S5_.text.unlikely._ZN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEED2Ev.rel.text._ZN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEED2Ev.text.unlikely._ZN7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEED2Ev.rel.text._ZN7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEED2Ev.text.unlikely._ZN7testing8internal12ShuffleRangeIiEEvPNS0_6RandomEiiPSt6vectorIT_SaIS5_EE.rel.text._ZN7testing8internal12ShuffleRangeIiEEvPNS0_6RandomEiiPSt6vectorIT_SaIS5_EE.text.unlikely._ZN7testing8internal18ParseNaturalNumberIiEEbRKSsPT_.rel.text._ZN7testing8internal18ParseNaturalNumberIiEEbRKSsPT_.text.unlikely._ZN7testing8internal18PrintCharAndCodeToIhhEEvT0_PSo.rel.text._ZN7testing8internal18PrintCharAndCodeToIhhEEvT0_PSo.rel.rodata._ZN7testing8internal18PrintCharAndCodeToIhhEEvT0_PSo.text.unlikely._ZN7testing8internal18PrintCharAndCodeToIhaEEvT0_PSo.rel.text._ZN7testing8internal18PrintCharAndCodeToIhaEEvT0_PSo.rel.rodata._ZN7testing8internal18PrintCharAndCodeToIhaEEvT0_PSo.text.unlikely._ZN7testing8internal18PrintCharAndCodeToIwwEEvT0_PSo.rel.text._ZN7testing8internal18PrintCharAndCodeToIwwEEvT0_PSo.text.unlikely._ZN7testing8internal10scoped_ptrIKSsE5resetEPS2_.rel.text._ZN7testing8internal10scoped_ptrIKSsE5resetEPS2_.text.unlikely._ZNSt6vectorIPN7testing8TestInfoESaIS2_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS2_S4_EERKS2_.rel.text._ZNSt6vectorIPN7testing8TestInfoESaIS2_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS2_S4_EERKS2_.text.unlikely._ZNSt6vectorIiSaIiEE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPiS1_EERKi.rel.text._ZNSt6vectorIiSaIiEE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPiS1_EERKi.text.unlikely._ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS2_S4_EERKS2_.rel.text._ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS2_S4_EERKS2_.text.unlikely._ZN7testing8internal15NoExecDeathTestD2Ev.rel.text._ZN7testing8internal15NoExecDeathTestD2Ev.text.unlikely._ZN7testing8internal13ExecDeathTestD2Ev.rel.text._ZN7testing8internal13ExecDeathTestD2Ev.text.unlikely._ZN7testing8internal15NoExecDeathTestD0Ev.rel.text._ZN7testing8internal15NoExecDeathTestD0Ev.text.unlikely._ZN7testing8internal13ExecDeathTestD0Ev.rel.text._ZN7testing8internal13ExecDeathTestD0Ev.text.unlikely._ZNSt6vectorIPN7testing11EnvironmentESaIS2_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS2_S4_EERKS2_.rel.text._ZNSt6vectorIPN7testing11EnvironmentESaIS2_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS2_S4_EERKS2_.text.unlikely._ZNSt6vectorIPN7testing8TestCaseESaIS2_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS2_S4_EERKS2_.rel.text._ZNSt6vectorIPN7testing8TestCaseESaIS2_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS2_S4_EERKS2_.text.unlikely._ZN7testing8internal18StreamableToStringIPcEESsRKT_.rel.text._ZN7testing8internal18StreamableToStringIPcEESsRKT_.text.unlikely._ZNSt6vectorIPcSaIS0_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS0_S2_EERKS0_.rel.text._ZNSt6vectorIPcSaIS0_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS0_S2_EERKS0_.text.unlikely._ZNSt6vectorIPcSaIS0_EE6insertEN9__gnu_cxx17__normal_iteratorIPS0_S2_EERKS0_.rel.text._ZNSt6vectorIPcSaIS0_EE6insertEN9__gnu_cxx17__normal_iteratorIPS0_S2_EERKS0_.text.unlikely._ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE8_M_eraseEPSt13_Rb_tree_nodeISsE.rel.text._ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE8_M_eraseEPSt13_Rb_tree_nodeISsE.text.unlikely._ZNKSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE4findERKSs.rel.text._ZNKSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE4findERKSs.text.unlikely._ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE16_M_insert_uniqueERKSs.rel.text._ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE16_M_insert_uniqueERKSs.text.unlikely._ZN7testing8internal27CheckedDowncastToActualTypeINS0_11ThreadLocalISt6vectorINS0_9TraceInfoESaIS4_EEE11ValueHolderENS0_26ThreadLocalValueHolderBaseEEEPT_PT0_.rel.text._ZN7testing8internal27CheckedDowncastToActualTypeINS0_11ThreadLocalISt6vectorINS0_9TraceInfoESaIS4_EEE11ValueHolderENS0_26ThreadLocalValueHolderBaseEEEPT_PT0_.text.unlikely._ZN7testing13PrintToStringIxEESsRKT_.rel.text._ZN7testing13PrintToStringIxEESsRKT_.text.unlikely._ZSt9__find_ifIN9__gnu_cxx17__normal_iteratorIPN7testing12TestPropertyESt6vectorIS3_SaIS3_EEEENS0_5__ops10_Iter_predINS2_8internal17TestPropertyKeyIsEEEET_SE_SE_T0_St26random_access_iterator_tag.rel.text._ZSt9__find_ifIN9__gnu_cxx17__normal_iteratorIPN7testing12TestPropertyESt6vectorIS3_SaIS3_EEEENS0_5__ops10_Iter_predINS2_8internal17TestPropertyKeyIsEEEET_SE_SE_T0_St26random_access_iterator_tag.text.unlikely._ZSt9__find_ifIN9__gnu_cxx17__normal_iteratorIPKSsSt6vectorISsSaISsEEEENS0_5__ops16_Iter_equals_valIS2_EEET_SB_SB_T0_St26random_access_iterator_tag.rel.text._ZSt9__find_ifIN9__gnu_cxx17__normal_iteratorIPKSsSt6vectorISsSaISsEEEENS0_5__ops16_Iter_equals_valIS2_EEET_SB_SB_T0_St26random_access_iterator_tag.text.unlikely._ZSt9__find_ifIN9__gnu_cxx17__normal_iteratorIPPN7testing8TestCaseESt6vectorIS4_SaIS4_EEEENS0_5__ops10_Iter_predINS2_8internal14TestCaseNameIsEEEET_SF_SF_T0_St26random_access_iterator_tag.rel.text._ZSt9__find_ifIN9__gnu_cxx17__normal_iteratorIPPN7testing8TestCaseESt6vectorIS4_SaIS4_EEEENS0_5__ops10_Iter_predINS2_8internal14TestCaseNameIsEEEET_SF_SF_T0_St26random_access_iterator_tag.text.unlikely._ZNSs12_S_constructIPKcEEPcT_S3_RKSaIcESt20forward_iterator_tag.rel.text._ZNSs12_S_constructIPKcEEPcT_S3_RKSaIcESt20forward_iterator_tag.text.unlikely._ZN7testing8internal28ParseGoogleTestFlagsOnlyImplIwEEvPiPPT_.rel.text._ZN7testing8internal28ParseGoogleTestFlagsOnlyImplIwEEvPiPPT_.text.unlikely._ZN7testing8internal28ParseGoogleTestFlagsOnlyImplIcEEvPiPPT_.rel.text._ZN7testing8internal28ParseGoogleTestFlagsOnlyImplIcEEvPiPPT_.text.unlikely._ZN7testing8internal27CheckedDowncastToActualTypeINS0_11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE11ValueHolderENS0_26ThreadLocalValueHolderBaseEEEPT_PT0_.rel.text._ZN7testing8internal27CheckedDowncastToActualTypeINS0_11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE11ValueHolderENS0_26ThreadLocalValueHolderBaseEEEPT_PT0_.text.unlikely._ZNK7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE16GetOrCreateValueEv.rel.text._ZNK7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE16GetOrCreateValueEv.text.unlikely._ZNSt12_Destroy_auxILb0EE9__destroyIPSsEEvT_S3_.rel.text._ZNSt12_Destroy_auxILb0EE9__destroyIPSsEEvT_S3_.text.unlikely._ZNSt6vectorISsSaISsEE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPSsS1_EERKSs.rel.text._ZNSt6vectorISsSaISsEE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPSsS1_EERKSs.text.unlikely._ZN7testing8internal18InitGoogleTestImplIcEEvPiPPT_.rel.text._ZN7testing8internal18InitGoogleTestImplIcEEvPiPPT_.text.unlikely._ZN7testing8internal18InitGoogleTestImplIwEEvPiPPT_.rel.text._ZN7testing8internal18InitGoogleTestImplIwEEvPiPPT_.text.unlikely._ZNSt12_Destroy_auxILb0EE9__destroyIPN7testing8internal9TraceInfoEEEvT_S6_.rel.text._ZNSt12_Destroy_auxILb0EE9__destroyIPN7testing8internal9TraceInfoEEEvT_S6_.text.unlikely._ZNK7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEE16GetOrCreateValueEv.rel.text._ZNK7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEE16GetOrCreateValueEv.text.unlikely._ZN7testing8internal35HandleExceptionsInMethodIfSupportedINS_4TestEvEET0_PT_MS4_FS3_vEPKc.rel.text._ZN7testing8internal35HandleExceptionsInMethodIfSupportedINS_4TestEvEET0_PT_MS4_FS3_vEPKc.text.unlikely._ZN7testing8internal35HandleExceptionsInMethodIfSupportedINS0_15TestFactoryBaseEPNS_4TestEEET0_PT_MS6_FS5_vEPKc.rel.text._ZN7testing8internal35HandleExceptionsInMethodIfSupportedINS0_15TestFactoryBaseEPNS_4TestEEET0_PT_MS6_FS5_vEPKc.text.unlikely._ZN7testing8internal35HandleExceptionsInMethodIfSupportedINS_8TestCaseEvEET0_PT_MS4_FS3_vEPKc.rel.text._ZN7testing8internal35HandleExceptionsInMethodIfSupportedINS_8TestCaseEvEET0_PT_MS4_FS3_vEPKc.text.unlikely._ZN7testing8internal35HandleExceptionsInMethodIfSupportedINS0_12UnitTestImplEbEET0_PT_MS4_FS3_vEPKc.rel.text._ZN7testing8internal35HandleExceptionsInMethodIfSupportedINS0_12UnitTestImplEbEET0_PT_MS4_FS3_vEPKc.text.unlikely._ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS2_S4_EERKS2_.rel.text._ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS2_S4_EERKS2_.text.unlikely._ZNSt20__uninitialized_copyILb0EE13__uninit_copyIPN7testing14TestPartResultES4_EET0_T_S6_S5_.rel.text._ZNSt20__uninitialized_copyILb0EE13__uninit_copyIPN7testing14TestPartResultES4_EET0_T_S6_S5_.text.unlikely._ZNSt6vectorIN7testing14TestPartResultESaIS1_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS1_S3_EERKS1_.rel.text._ZNSt6vectorIN7testing14TestPartResultESaIS1_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS1_S3_EERKS1_.text.unlikely._ZNSt20__uninitialized_copyILb0EE13__uninit_copyIPN7testing12TestPropertyES4_EET0_T_S6_S5_.rel.text._ZNSt20__uninitialized_copyILb0EE13__uninit_copyIPN7testing12TestPropertyES4_EET0_T_S6_S5_.text.unlikely._ZNSt6vectorIN7testing12TestPropertyESaIS1_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS1_S3_EERKS1_.rel.text._ZNSt6vectorIN7testing12TestPropertyESaIS1_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS1_S3_EERKS1_.rel.text.startup.rel.init_array.bss._ZN7testing8internal12TypeIdHelperINS_4TestEE6dummy_E.rel.rodata._ZTIN7testing8internal26ThreadLocalValueHolderBaseE.rodata._ZTSN7testing8internal26ThreadLocalValueHolderBaseE.rel.rodata._ZTIN7testing8internal26GoogleTestFailureExceptionE.rodata._ZTSN7testing8internal26GoogleTestFailureExceptionE.rel.rodata._ZTIN7testing8internal9DeathTestE.rodata._ZTSN7testing8internal9DeathTestE.rel.rodata._ZTIN7testing8internal16DeathTestFactoryE.rodata._ZTSN7testing8internal16DeathTestFactoryE.rodata._ZTSN7testing8internal23DefaultDeathTestFactoryE.rel.rodata._ZTIN7testing8internal23DefaultDeathTestFactoryE.rel.rodata._ZTIN7testing31TestPartResultReporterInterfaceE.rodata._ZTSN7testing31TestPartResultReporterInterfaceE.rodata._ZTSN7testing8internal24HasNewFatalFailureHelperE.rel.rodata._ZTIN7testing8internal24HasNewFatalFailureHelperE.rodata._ZTSN7testing4TestE.rel.rodata._ZTIN7testing4TestE.rodata._ZTSN7testing8TestCaseE.rel.rodata._ZTIN7testing8TestCaseE.rel.rodata._ZTIN7testing17TestEventListenerE.rodata._ZTSN7testing17TestEventListenerE.rel.rodata._ZTIN7testing22EmptyTestEventListenerE.rodata._ZTSN7testing22EmptyTestEventListenerE.rodata._ZTSN7testing8UnitTestE.rel.rodata._ZTIN7testing8UnitTestE.rodata._ZTSN7testing32ScopedFakeTestPartResultReporterE.rel.rodata._ZTIN7testing32ScopedFakeTestPartResultReporterE.rel.rodata._ZTIN7testing8internal27OsStackTraceGetterInterfaceE.rodata._ZTSN7testing8internal27OsStackTraceGetterInterfaceE.rodata._ZTSN7testing8internal18OsStackTraceGetterE.rel.rodata._ZTIN7testing8internal18OsStackTraceGetterE.rodata._ZTSN7testing8internal35DefaultGlobalTestPartResultReporterE.rel.rodata._ZTIN7testing8internal35DefaultGlobalTestPartResultReporterE.rodata._ZTSN7testing8internal38DefaultPerThreadTestPartResultReporterE.rel.rodata._ZTIN7testing8internal38DefaultPerThreadTestPartResultReporterE.rodata._ZTSN7testing8internal12UnitTestImplE.rel.rodata._ZTIN7testing8internal12UnitTestImplE.rel.rodata._ZTIN7testing8internal17StreamingListener20AbstractSocketWriterE.rodata._ZTSN7testing8internal17StreamingListener20AbstractSocketWriterE.rel.rodata._ZTIN7testing8internal17StreamingListener12SocketWriterE.rodata._ZTSN7testing8internal17StreamingListener12SocketWriterE.rel.rodata._ZTIN7testing8internal17StreamingListenerE.rodata._ZTSN7testing8internal17StreamingListenerE.rodata._ZTSN7testing8internal27PrettyUnitTestResultPrinterE.rel.rodata._ZTIN7testing8internal27PrettyUnitTestResultPrinterE.rodata._ZTSN7testing8internal17TestEventRepeaterE.rel.rodata._ZTIN7testing8internal17TestEventRepeaterE.rodata._ZTSN7testing8internal24XmlUnitTestResultPrinterE.rel.rodata._ZTIN7testing8internal24XmlUnitTestResultPrinterE.rodata._ZTSN7testing8internal13DeathTestImplE.rel.rodata._ZTIN7testing8internal13DeathTestImplE.rodata._ZTSN7testing8internal16ForkingDeathTestE.rel.rodata._ZTIN7testing8internal16ForkingDeathTestE.rodata._ZTSN7testing8internal15NoExecDeathTestE.rel.rodata._ZTIN7testing8internal15NoExecDeathTestE.rodata._ZTSN7testing8internal13ExecDeathTestE.rel.rodata._ZTIN7testing8internal13ExecDeathTestE.rel.rodata._ZTIN7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEE11ValueHolderE.rodata._ZTSN7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEE11ValueHolderE.rel.rodata._ZTIN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE11ValueHolderE.rodata._ZTSN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE11ValueHolderE.rel.rodata._ZTVN7testing8internal26GoogleTestFailureExceptionE.rel.rodata._ZTVN7testing8internal9DeathTestE.rel.rodata._ZTVN7testing8internal17StreamingListener12SocketWriterE.rel.rodata._ZTVN7testing8internal17StreamingListenerE.rel.rodata._ZTVN7testing32ScopedFakeTestPartResultReporterE.rel.rodata._ZTVN7testing8internal35DefaultGlobalTestPartResultReporterE.rel.rodata._ZTVN7testing8internal38DefaultPerThreadTestPartResultReporterE.rel.rodata._ZTVN7testing4TestE.rel.rodata._ZTVN7testing8TestCaseE.rel.rodata._ZTVN7testing8internal27PrettyUnitTestResultPrinterE.rel.rodata._ZTVN7testing8internal17TestEventRepeaterE.rel.rodata._ZTVN7testing8internal24XmlUnitTestResultPrinterE.rel.rodata._ZTVN7testing8internal18OsStackTraceGetterE.rel.rodata._ZTVN7testing8UnitTestE.rel.rodata._ZTVN7testing8internal12UnitTestImplE.rel.rodata._ZTVN7testing8internal13DeathTestImplE.rel.rodata._ZTVN7testing8internal16ForkingDeathTestE.rel.rodata._ZTVN7testing8internal15NoExecDeathTestE.rel.rodata._ZTVN7testing8internal13ExecDeathTestE.rel.rodata._ZTVN7testing8internal23DefaultDeathTestFactoryE.rel.rodata._ZTVN7testing8internal24HasNewFatalFailureHelperE.rel.rodata._ZTVN7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEE11ValueHolderE.rel.rodata._ZTVN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE11ValueHolderE.rodata.cst4.rel.debug_info.debug_abbrev.rel.debug_loc.rel.debug_aranges.rel.debug_ranges.rel.debug_line.debug_str.comment.note.GNU-stack.rel.eh_frame.groupn4 n@nT n` nl nx n nn n n n n n n n n n n n( n4 n@ nL nX nd npn n n n nnnnnnn,n@nT n` nl pnx n nn n Yn ]n ^n _n mn sn yn |n n n( n4 n@ nL nXnln n n n n n nn n n n n  n n$ n0 n< nH nT n` nl nx n n n n n n nnn n n n n n(n<nP In\ Knh Lnt Mn Nn On Pn Rn Xn ^n en fn gn jn un xn zn }n( n4 n@ nL nX nd np n| n n n n n n n nGn[nnnnn nnn$n,n4n<nDnLnTn\ndnlntn|nnnnnnnnnnnnnnnnnn nnn$n,n4n<nD nL nT n\ nd nlntn|nnnnnZnYn|n{nn8nnnnLnOn~n n n  n 'n$ n, n4 n< 1nD ;nL BnT Cn\ nd nl ,nt ~ Q $`%ќ+ 0Z{ =l 2@DP @Z{` jpr,S^WНҝc TG + "} 0 2& @} B P0 R ` b, px r / f   x x h1c'ŸПҟFf $y  '&,0( *O6@ -F P 0gV` $3fEpA ,6v 49* <@;24WS |?! B[ -W ENPG (H|bx  KAk= (N|Y ,Q2`F`tB DU \hXF~B ģ@[lNPV (^ C ,(aDso Td@ @ df K 0i$lfpKb $ly <8oN 9 @W t0r !u! @u\!! l! x!!! t{*"_p"`nl"  ~""r" 4 (#B p#P Ll# T(# $ $ |`V$0 $0 $ ܮp$ $ $ Lp%X O%` K% x{% % "% 4&" a&0 ]& `& & & \h.'m'i' ıp'~'' 4x(`m(`i( ()) `))) < *h* d* *+1+ Ls++ + p*,j,f, |x,,, -*o-0k- t@-4.@\. x^..T. ,x/ e/!a/ /#0#=/ $=0%0%{0 x0,&00&0 ,h%1,'f10'b1 x1L(1P(1 h/2<)p2@)l2 tx2\*2`*2 3|+X3+T3 lx3,3,3 x4-C4-?4 \xx4.4.R4 %5275@7 ~5 d5F@36P@/6 x6A6A=6 l27=B7@B7 @73D+8@Dm'8 Tf8D8Dc8 d8Ht8 D*9Ir9Ikn9 ,9Lt9 9pN6:pN2: q:nO:pOK: :Of;Ohb; (;(Q4<0Qf0< ( <R =Rh= ( =T=T\= =lU+>pU\'> Y>V>Vh> >8X?@Xh> /?Y?Yh? (@[@ [h@ (A\LA\HA 8!A6]A@]hA T($IB^B^tB |'B$_eC0__aC  *C_D_D -\Dh`Dp`D h0EcbEpbE p3fF cFcF `6FeGeEG 89hH5gI@g I $8<IixJixtJ \8?:KjKjK 0BK0k$L0k] L 0EhLnLn~L 0HLrMrM $pK^NrNrN N5OsxOsFtO $QOsPsP 4TkPvPvP 4WPx3Qx/Q ,ZmQUzQ`zFQ ]RzRzR `R|VS|RS cS3~9T@~5T fT UU |iUSU`U DleVV~V o^WnWpW `r1XXX`hX lu$YȋYЋY $HxY|qZmZ lx{ZPZ h}ZZ L[C[?[ T[ 0 [P [ d[`0 ;\7\ |e\\\ \& \- 4]0 0] q]<m] ]`, ]. ^Д ^ Y^ܔy^u^ ^^^ ^^ _5_8 1_ d_`# ___ $_- `Е ` 4Q`ܕM` L`1 `@( ah ` \7a9 a |a ta< b  b Yb@" bdb blb c= Sc Oc c5 c c  d@' ?d1 d |d d' d d 'e. ee0 ae $e@# ed e <f& 7f 3f Tif% f f lf# g$ f 5g0 1g g@Q@g g UhV@hh  h@ h ()i`%i (niD@ji <iți  ii  +j'j  wj  sj (j@j DjD@j \jD@j 3kD@/k \qkȝmk (kk kk k k 4(2l  .l \(hl@ dl 8l` l 8ll   m m  KmGm 4mm LnОnԞ/g n d0 +n \=n_ Í9n \+ Ln"Hn t&_nH[n , &@'qn2/ mn l3(}n09T]n0%-nRnTon 8(nxa (T      !"#$&')*,-/0235689;=>?AB00X`m`?DEGHJKMNPQSeN  XTUWX f] f fZ[]^@ f*8fh`a"FtcdJk fiX ffhiklnoqrtu kpmgm5P p\pwxsz{}~w f? fdVP6U}з   G(v} f  !#$&')*,-/0235689;<>? fAB f J @ fDE{ f ~ f m f g f) fU f ` f f U f N f C fG 7 fo 0 f ( f  f  f fGHJKMNPQ=   D  f0 f] fST hVWYZ\]_`bcef {hi |klnoqrtuwxz{}}KZ f   U !"#<$q%&'(M*m+,-8<5=aDUV%`Oa      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~w"""""3"L "u """"" "A"""""n"""A""""b"" " B"j" 0P*,*[*""`""N#""`""""0" q" """"."$"'"*"- "0U "3 "6 "9 0v!2!D!]!l!0v!!!"""?K"!"""?"!"B#NN#PN#N#N.$@N$N$O$%0Ow%O%O& OJ&p[&T&&&'-"EG'D!y''-"E'G"H(b"KW(!(b"K)k"NX)Y"Qs)Y"Q)))))))*Q*t"U*t"U*0 W+ +0 WS+ =z+ =+ ++,,` Y, >,0 ,,@ %X-e-@ %-p .!Y.p . .!>/ / / * 0 J0PBy0 0B00 #1P ^1p 1 1  2 !O2Hw22PD22S2S3'3 G3@D}33D3304 44]4P!445#5"X^5B55B5@56`06Dr6@D6464 7870h7@}7 !777898K8v8889%9|J9xp9t9p9l9h :d5:@J:+_:+t: :@:`/:/;>>;$e;0;P(;;< <<*<1<8<L<,<<<,=Db=0=x= C>K>0!>>>>0!>!?"{e?v?}??@#C?@#C?#B!@#BE@#V@@$@P$ @`$ 'Ap$[A$A$A$A$B$DB%|B %B@%B`%C%-C%VC%|C%FC0&;Cp&2C&  D&26D' WD~"[wD~"[DV"^DV"^D' E '&E0' ZE@'E`'gEEE'F'RF)3F)F)R#G@*AGP*dG`*@GG@+G,FG0-BH1H-3ZHmH- H- H-H- H- I.!/I0.\IP.<III.I J.OJ.J.J/JJ / K(K@/5ZK/K/ K/K/=L L0JLPLWL^L0LL1L2L $Mp3UM4MP5M@6N7-N77INQNVN77rN 84NN`84N8NO OO;OSO8uO@9OOO`9|OP9DPIPOPVP:P:P;}P;Q 2Q;fQQ@<QQQ=J$R >MRC"aRRRRC"a'S@>?SRSSSS'T8TKTUT@>mT?TA$TTE,UEZUbUPHjUHPUIU"dV"d#VJKMV0PyVV SVVVv-WYWW@]W_WK"i,XK"l[XaXd#XeXy"o%YW"r\Yu"uYgY@iY/Z6ZlkZ lOZplwZlwZZ qT [qa.[I[qu[l"x[r[r\tN6\taZ\Pu\"{\\2]i]pu]Pv]n"~^xW^y^r"^^{2H_}_ ~j_L"%`qY`i`r` `` `0a^a}a}a@bb"bHb0nbP'bbbbbb"4c"Scic"c"cc"cc d""KdQdExdД&d"d!e"Re"e"eD!e"f";f"f"f"g "]g1"g"gh,hHh"uh!h"h"h7iМ3i6iP>j>>jСIj j j",kPvkkPk 7l]olwl=lPl\"5mT"|m"m="m".n"Zn"n"n"n@BZo"o/o ,oo-p*9pepp-p*pp/q,@q"nq"q 2q"r`5r@grrR"r's "Ns/ls"sss"/t="xt="t" u$Fu0yum"uuc"uvk"Cvev"vvK"vAwAw@L8w!Pw@Liwww!wwx6x!NxgxxxxyZyh"yf" z@zh" zz0G8{Gx{w{PW{|!B|D!w|PW|||}}}-}0r}+} +}P*~x-~4~:~@~F~]~~`~0 \"4 ![\"\"\"h"h"'bJ !lbNƀ !N'2d !# !JPX_wP8h"TSh""!'h"$|t"'Ʉ_"*"-`g"0&8FV"3Q!J !!Ӈ"6C0n0CCĈC CE"9݉"<qx"?-p |lɋ"B &ELe׌@g f0M}]"E L~"H0"KcV! !"Nv!А@40 ܑ! A !t@!0!ג@!0 p#;#n#`%,֓(%!(%l(%˔(%*F"QZ(ƕ͕PG70IQW7_"TݗdhM"W`i͘"Zi#F"]n"`ș i. !bnlmXmX oVqrśwy}A"c zÜ"f3|N"i~ǝ~"l]`x@ІĞІ~"oZП"rdh"uѠ8zP"xo"{ڢЌctp0ʣP !+Z0!ݤ0!'!I!k!&!-! !!!Q,!.! !!! !%!=!_! !#!ϧ!!-!0 !a!1!˨(! !#9!` !<!ݩ !"!C!i!=! !$5!] !'!1! !'!H !s.! !׬#! !%&!O !y%! !˭#! !6I f@ q gtest-all.cc_ZN7testing8internal12UnitTestImpl26RegisterParameterizedTestsEv.part.102_ZN7testing8internalL19SumOverTestCaseListERKSt6vectorIPNS_8TestCaseESaIS3_EEMS2_KFivE.constprop.389_ZN7testing8internalL14PrintOnOneLineEPKci.constprop.390_ZNSs4_Rep10_M_disposeERKSaIcE.part.7_ZN7testing8internalL21FormatDeathTestOutputERKSs_ZN7testing12_GLOBAL__N_126PrintByteSegmentInObjectToEPKhjjPSo_ZN7testing7MessagelsIKcEERS0_RKPT_.isra.62CSWTCH.1179_ZGVZN7testing8internal13ColoredPrintfENS0_10GTestColorEPKczE13in_color_mode_ZZN7testing8internal13ColoredPrintfENS0_10GTestColorEPKczE13in_color_mode_ZN7testing8internalL15kTypeParamLabelE_ZN7testing8internalL16kValueParamLabelE_ZN7testingL20kTestShardStatusFileE_ZN7testing8internalL23HasGoogleTestFlagPrefixEPKc_ZN7testing8internalL26g_in_fast_death_test_childE_ZN7testing8internalL23kCurrentDirectoryStringE_ZN7testing8internalL17g_captured_stdoutE_ZN7testing8internalL17g_captured_stderrE_ZN7testing8internalL21g_injected_test_argvsE_ZN7testing8internalL25FormatCxxExceptionMessageEPKcS2__ZN7testing8internalL12FlagToEnvVarEPKc_ZN7testingL15kTestShardIndexE_ZN7testingL16kTestTotalShardsE_ZN7testing8internalL24StreamWideCharsToMessageEPKwjPNS_7MessageE_ZN7testing8internal18StreamableToStringIPwEESsRKT_.isra.349_ZN7testing8internalL20PrintAsCharLiteralToIwwEENS0_10CharFormatET0_PSo_ZN7testing8internalL22PrintAsStringLiteralToEwPSo_ZN7testing8internalL20PrintCharsAsStringToIcEEvPKT_jPSo_ZN7testing8internalL20PrintCharsAsStringToIwEEvPKT_jPSo_ZN7testingL19FormatCountableNounEiPKcS1__ZN7testingL16kUniversalFilterE_ZN7testing8internalL12kUnknownFileE_ZN7testing8internalL27PrintTestPartResultToStringERKNS_14TestPartResultE_ZN7testing12_GLOBAL__N_115IsSubstringImplIPKcEENS_15AssertionResultEbS3_S3_RKT_S7__ZN7testing12_GLOBAL__N_115IsSubstringImplISsEENS_15AssertionResultEbPKcS4_RKT_S7__ZN7testing12_GLOBAL__N_115IsSubstringImplISbIwSt11char_traitsIwESaIwEEEENS_15AssertionResultEbPKcS8_RKT_SB__ZN7testing12_GLOBAL__N_115IsSubstringImplIPKwEENS_15AssertionResultEbPKcS6_RKT_S9__ZGVZN7testing8UnitTest11GetInstanceEvE8instance_ZZN7testing8UnitTest11GetInstanceEvE8instance_ZN7testingL18kDefaultOutputFileE_ZN7testing8internalL22ExecDeathTestChildMainEPv_ZN7testingL20kDeathTestCaseFilterE_ZN7testingL18kDisableTestFilterE_ZN7testing8internalL17PrintColorEncodedEPKc.constprop.388_ZN7testing8internalL24kColorEncodedHelpMessageE_ZN7testing8internalL25kAlsoRunDisabledTestsFlagE_ZN7testing8internalL19kBreakOnFailureFlagE_ZN7testing8internalL20kCatchExceptionsFlagE_ZN7testing8internalL10kColorFlagE_ZN7testing8internalL19kDeathTestStyleFlagE_ZN7testing8internalL17kDeathTestUseForkE_ZN7testing8internalL11kFilterFlagE_ZN7testing8internalL25kInternalRunDeathTestFlagE_ZN7testing8internalL14kListTestsFlagE_ZN7testing8internalL11kOutputFlagE_ZN7testing8internalL14kPrintTimeFlagE_ZN7testing8internalL15kRandomSeedFlagE_ZN7testing8internalL11kRepeatFlagE_ZN7testing8internalL12kShuffleFlagE_ZN7testing8internalL20kStackTraceDepthFlagE_ZN7testing8internalL19kStreamResultToFlagE_ZN7testing8internalL19kThrowOnFailureFlagE_ZGVZN7testing8internalL23ExecDeathTestSpawnChildEPKPciE16stack_grows_down_ZZN7testing8internalL23ExecDeathTestSpawnChildEPKPciE16stack_grows_down_ZN7testingL31GetReservedAttributesForElementERKSs_ZN7testingL28kReservedTestSuiteAttributesE_ZN7testingL29kReservedTestSuitesAttributesE_ZN7testingL27kReservedTestCaseAttributesE_ZN7testing8internal12UnitTestImpl19PostFlagParsingInitEv.part.358_ZN7testing8TestInfo3RunEv.part.366_ZN7testing8TestCase3RunEv.part.367_GLOBAL__sub_I__ZN7testing8internal17kStackTraceMarkerE_ZStL8__ioinit_ZN7testingL22kDefaultDeathTestStyleE_ZN7testing8internal26ThreadLocalValueHolderBaseD5Ev_ZN7testing11EnvironmentD5Ev_ZN7testing22EmptyTestEventListenerD5Ev_ZN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE11ValueHolderD5Ev_ZN7testing8internal23DefaultDeathTestFactoryD5Ev_ZN7testing8internal27PrettyUnitTestResultPrinterD5Ev_ZN7testing8internal38DefaultPerThreadTestPartResultReporterD5Ev_ZN7testing8internal35DefaultGlobalTestPartResultReporterD5Ev_ZN7testing8internal26GoogleTestFailureExceptionD5Ev_ZN7testing8internal24XmlUnitTestResultPrinterD5Ev_ZN7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEE11ValueHolderD5Ev_ZNSt6vectorISsSaISsEED5Ev_ZN7testing8internal29ParameterizedTestCaseRegistryD5Ev_ZN7testing14TestPartResultD5Ev_ZN7testing12TestPropertyD5Ev_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEED5Ev_ZN7testing7MessageC5ERKS0__ZN7testing8internal5MutexD5Ev_ZN7testing8internal17StreamingListener12SocketWriterD5Ev_ZN7testing8internal17StreamingListenerD5Ev_ZN7testing8internal18OsStackTraceGetterD5Ev_ZN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEED5Ev_ZN7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEED5Ev_ZN7testing8internal15NoExecDeathTestD5Ev_ZN7testing8internal13ExecDeathTestD5Ev_ZNKSt5ctypeIcE8do_widenEc_ZN7testing8internal26ThreadLocalValueHolderBaseD2Ev_ZN7testing8internal26ThreadLocalValueHolderBaseD1EvDeleteThreadLocalValue_ZN7testing4Test11DeleteSelf_Ev_ZN7testing4Test5SetupEv_ZN7testing8TestCase16RunSetUpTestCaseEv_ZN7testing8TestCase19RunTearDownTestCaseEv_ZN7testing11EnvironmentD2Ev_ZN7testing11EnvironmentD1Ev_ZN7testing11Environment5SetUpEv_ZN7testing11Environment8TearDownEv_ZN7testing11Environment5SetupEv_ZN7testing22EmptyTestEventListener18OnTestProgramStartERKNS_8UnitTestE_ZN7testing22EmptyTestEventListener20OnTestIterationStartERKNS_8UnitTestEi_ZN7testing22EmptyTestEventListener24OnEnvironmentsSetUpStartERKNS_8UnitTestE_ZN7testing22EmptyTestEventListener22OnEnvironmentsSetUpEndERKNS_8UnitTestE_ZN7testing22EmptyTestEventListener15OnTestCaseStartERKNS_8TestCaseE_ZN7testing22EmptyTestEventListener11OnTestStartERKNS_8TestInfoE_ZN7testing22EmptyTestEventListener16OnTestPartResultERKNS_14TestPartResultE_ZN7testing22EmptyTestEventListener9OnTestEndERKNS_8TestInfoE_ZN7testing22EmptyTestEventListener13OnTestCaseEndERKNS_8TestCaseE_ZN7testing22EmptyTestEventListener27OnEnvironmentsTearDownStartERKNS_8UnitTestE_ZN7testing22EmptyTestEventListener25OnEnvironmentsTearDownEndERKNS_8UnitTestE_ZN7testing22EmptyTestEventListener18OnTestIterationEndERKNS_8UnitTestEi_ZN7testing22EmptyTestEventListener16OnTestProgramEndERKNS_8UnitTestE_ZN7testing8internal17StreamingListener20AbstractSocketWriter15CloseConnectionEv_ZN7testing22EmptyTestEventListenerD2Ev_ZN7testing22EmptyTestEventListenerD1Ev_ZN7testing4Test5SetUpEv_ZN7testing4Test8TearDownEv_ZNK7testing8TestCase30reportable_disabled_test_countEv_ZNK7testing8TestCase19disabled_test_countEv_ZNK7testing8TestCase21reportable_test_countEv_ZNK7testing8TestCase17test_to_run_countEv_ZNK7testing8TestCase16total_test_countEv_ZN7testing8internal27PrettyUnitTestResultPrinter18OnTestProgramStartERKNS_8UnitTestE_ZN7testing8internal27PrettyUnitTestResultPrinter22OnEnvironmentsSetUpEndERKNS_8UnitTestE_ZN7testing8internal27PrettyUnitTestResultPrinter25OnEnvironmentsTearDownEndERKNS_8UnitTestE_ZN7testing8internal27PrettyUnitTestResultPrinter16OnTestProgramEndERKNS_8UnitTestE_ZN7testing8internal18OsStackTraceGetter16UponLeavingGTestEv_ZN7testing8internal24HasNewFatalFailureHelper20ReportTestPartResultERKNS_14TestPartResultE_ZN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE11ValueHolderD2Ev_ZN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE11ValueHolderD1Ev_ZN7testing8internal23DefaultDeathTestFactoryD2Ev_ZN7testing8internal23DefaultDeathTestFactoryD1Ev_ZN7testing8internal27PrettyUnitTestResultPrinterD2Ev_ZN7testing8internal27PrettyUnitTestResultPrinterD1Ev_ZN7testing8internal38DefaultPerThreadTestPartResultReporterD2Ev_ZN7testing8internal38DefaultPerThreadTestPartResultReporterD1Ev_ZN7testing8internal35DefaultGlobalTestPartResultReporterD2Ev_ZN7testing8internal35DefaultGlobalTestPartResultReporterD1Ev_ZN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE11ValueHolderD0Ev_ZdlPv_ZN7testing8internal26ThreadLocalValueHolderBaseD0Ev_ZN7testing11EnvironmentD0Ev_ZN7testing8internal23DefaultDeathTestFactoryD0Ev_ZN7testing8internal38DefaultPerThreadTestPartResultReporterD0Ev_ZN7testing8internal35DefaultGlobalTestPartResultReporterD0Ev_ZN7testing8internal27PrettyUnitTestResultPrinterD0Ev_ZN7testing22EmptyTestEventListenerD0Ev_ZN7testing8internal17TestEventRepeaterD2Ev__gxx_personality_v0_ZTVN7testing8internal17TestEventRepeaterE_Unwind_Resume_ZN7testing8internal17TestEventRepeaterD1Ev_ZN7testing8internal17TestEventRepeaterD0Ev_ZN7testing8internal18OsStackTraceGetter17CurrentStackTraceEii_ZNSsC1EPKcRKSaIcE_ZN7testing8internal26GoogleTestFailureExceptionD2Ev_ZTVN7testing8internal26GoogleTestFailureExceptionE_ZNSt13runtime_errorD2Ev_ZN7testing8internal26GoogleTestFailureExceptionD1Ev_ZN7testing8internal26GoogleTestFailureExceptionD0Ev_ZN7testing8internal17TestEventRepeater18OnTestProgramStartERKNS_8UnitTestE_ZN7testing8internal17TestEventRepeater24OnEnvironmentsSetUpStartERKNS_8UnitTestE_ZN7testing8internal17TestEventRepeater15OnTestCaseStartERKNS_8TestCaseE_ZN7testing8internal17TestEventRepeater11OnTestStartERKNS_8TestInfoE_ZN7testing8internal17TestEventRepeater16OnTestPartResultERKNS_14TestPartResultE_ZN7testing8internal17TestEventRepeater27OnEnvironmentsTearDownStartERKNS_8UnitTestE_ZN7testing8internal17TestEventRepeater22OnEnvironmentsSetUpEndERKNS_8UnitTestE_ZN7testing8internal17TestEventRepeater25OnEnvironmentsTearDownEndERKNS_8UnitTestE_ZN7testing8internal17TestEventRepeater9OnTestEndERKNS_8TestInfoE_ZN7testing8internal17TestEventRepeater13OnTestCaseEndERKNS_8TestCaseE_ZN7testing8internal17TestEventRepeater16OnTestProgramEndERKNS_8UnitTestE_ZN7testing8internal17TestEventRepeater20OnTestIterationStartERKNS_8UnitTestEi_ZN7testing8internal17TestEventRepeater18OnTestIterationEndERKNS_8UnitTestEiputcharprintf_ZNSs4_Rep10_M_destroyERKSaIcE_ZN7testing8internal24XmlUnitTestResultPrinterD2Ev_ZTVN7testing8internal24XmlUnitTestResultPrinterE_ZNSs4_Rep20_S_empty_rep_storageE_ZN7testing8internal24XmlUnitTestResultPrinterD1Ev_ZN7testing8internal24XmlUnitTestResultPrinterD0Ev_ZN7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEE11ValueHolderD2Ev_ZTVN7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEE11ValueHolderE_ZN7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEE11ValueHolderD1Ev_ZN7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEE11ValueHolderD0Ev_ZNSt6vectorISsSaISsEED2Ev_ZNSt6vectorISsSaISsEED1Ev_ZNKSs4findEcj_ZNSs6appendEPKcj_ZNSsC1ERKSsjj_ZNSs6appendERKSs_ZSt24__throw_out_of_range_fmtPKczsnprintfstrlen_ZSt16__ostream_insertIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_PKS3_i_ZN7testing8internal29ParameterizedTestCaseRegistryD2Ev_ZN7testing8internal29ParameterizedTestCaseRegistryD1Ev_ZN7testing8internal12AssertHelperC2ENS_14TestPartResult4TypeEPKciS5__Znwj_ZN7testing8internal12AssertHelperC1ENS_14TestPartResult4TypeEPKciS5__ZN7testing8internal12AssertHelperD2Ev_ZN7testing8internal12AssertHelperD1Ev_ZN7testing8internal15UnitTestOptions15GetOutputFormatEv_ZN7testing18FLAGS_gtest_outputEstrchr_ZNSsC1EPKcjRKSaIcE_ZN7testing8internal15UnitTestOptions20PatternMatchesStringEPKcS3__ZN7testing8internal15UnitTestOptions13MatchesFilterERKSsPKc_ZN7testing8internal13GetTestTypeIdEv_ZN7testing8internal12TypeIdHelperINS_4TestEE6dummy_E_ZN7testing8internal20SingleFailureCheckerC2EPKNS_19TestPartResultArrayENS_14TestPartResult4TypeERKSs_ZNSsC1ERKSs_ZN7testing8internal20SingleFailureCheckerC1EPKNS_19TestPartResultArrayENS_14TestPartResult4TypeERKSs_ZN7testing8internal35DefaultGlobalTestPartResultReporterC2EPNS0_12UnitTestImplE_ZTVN7testing8internal35DefaultGlobalTestPartResultReporterE_ZN7testing8internal35DefaultGlobalTestPartResultReporterC1EPNS0_12UnitTestImplE_ZN7testing8internal38DefaultPerThreadTestPartResultReporterC2EPNS0_12UnitTestImplE_ZTVN7testing8internal38DefaultPerThreadTestPartResultReporterE_ZN7testing8internal38DefaultPerThreadTestPartResultReporterC1EPNS0_12UnitTestImplE_ZNK7testing8internal12UnitTestImpl21total_test_case_countEv_ZNK7testing8internal12UnitTestImpl22test_case_to_run_countEv_ZNK7testing8internal12UnitTestImpl21successful_test_countEv_ZNK7testing8TestCase21successful_test_countEv_ZNK7testing8internal12UnitTestImpl17failed_test_countEv_ZNK7testing8TestCase17failed_test_countEv_ZNK7testing8internal12UnitTestImpl30reportable_disabled_test_countEv_ZNK7testing8internal12UnitTestImpl19disabled_test_countEv_ZNK7testing8internal12UnitTestImpl21reportable_test_countEv_ZNK7testing8internal12UnitTestImpl16total_test_countEv_ZNK7testing8internal12UnitTestImpl17test_to_run_countEv_ZN7testing8internal12UnitTestImpl28CurrentOsStackTraceExceptTopEi_ZN7testing8internal15GetTimeInMillisEvgettimeofday_ZN7testing8internal6String13CStringEqualsEPKcS3_strcmp_ZN7testing15AssertionResultC2ERKS0__ZN7testing15AssertionResultC1ERKS0__ZN7testing16AssertionSuccessEv_ZN7testing16AssertionFailureEv_ZN7testing8internal6String17WideCStringEqualsEPKwS3_wcscmp_ZN7testing8internal6String28CaseInsensitiveCStringEqualsEPKcS3_strcasecmp_ZN7testing8internal6String32CaseInsensitiveWideCStringEqualsEPKwS3_wcscasecmp_ZN7testing8internal6String23EndsWithCaseInsensitiveERKSsS3__ZN7testing8internal20StringStreamToStringEPSt18basic_stringstreamIcSt11char_traitsIcESaIcEE_ZNKSt15basic_stringbufIcSt11char_traitsIcESaIcEE3strEv_ZNSs7reserveEj_ZNK7testing7Message9GetStringEv_ZN7testing15AssertionResult13AppendMessageERKNS_7MessageE_ZNK7testing10TestResult17GetTestPartResultEiabort_ZNK7testing10TestResult15GetTestPropertyEi_ZN7testing10TestResult20ClearTestPartResultsEv_ZN7testing10TestResult5ClearEv_ZNK7testing10TestResult6FailedEv_ZNK7testing8internal12UnitTestImpl26successful_test_case_countEv_ZNK7testing8internal12UnitTestImpl22failed_test_case_countEv_ZNK7testing10TestResult15HasFatalFailureEv_ZNK7testing10TestResult18HasNonfatalFailureEv_ZNK7testing10TestResult16total_part_countEv_ZNK7testing10TestResult19test_property_countEv_ZN7testing4TestC2Ev_ZTVN7testing4TestE_ZN7testing35FLAGS_gtest_also_run_disabled_testsE_ZN7testing28FLAGS_gtest_break_on_failureE_ZN7testing28FLAGS_gtest_catch_exceptionsE_ZN7testing17FLAGS_gtest_colorE_ZNSs6assignERKSs_ZN7testing28FLAGS_gtest_death_test_styleE_ZN7testing31FLAGS_gtest_death_test_use_forkE_ZN7testing18FLAGS_gtest_filterE_ZN7testing8internal35FLAGS_gtest_internal_run_death_testE_ZN7testing22FLAGS_gtest_list_testsE_ZN7testing22FLAGS_gtest_print_timeE_ZN7testing23FLAGS_gtest_random_seedE_ZN7testing18FLAGS_gtest_repeatE_ZN7testing19FLAGS_gtest_shuffleE_ZN7testing29FLAGS_gtest_stack_trace_depthE_ZN7testing28FLAGS_gtest_stream_result_toE_ZN7testing28FLAGS_gtest_throw_on_failureE_ZN7testing4TestC1Ev_ZN7testing4TestD2Ev_ZN7testing4TestD1Ev_ZN7testing4TestD0Ev_ZN7testing8internal12UnitTestImpl26RegisterParameterizedTestsEv_ZNK7testing8TestCase11GetTestInfoEi_ZN7testing8TestCase18GetMutableTestInfoEi_ZN7testing8TestCase11ClearResultEv_ZN7testing8TestCase14UnshuffleTestsEv_ZN7testing8internal16GetAnsiColorCodeENS0_10GTestColorE_ZN7testing8internal14ShouldUseColorEbgetenv_ZN7testing8internal13ColoredPrintfENS0_10GTestColorEPKczstdoutvfprintf__cxa_guard_acquirefilenoisatty__cxa_guard_release_ZN7testing8internal27PrettyUnitTestResultPrinter24OnEnvironmentsSetUpStartERKNS_8UnitTestEputsfflush_ZN7testing8internal27PrettyUnitTestResultPrinter27OnEnvironmentsTearDownStartERKNS_8UnitTestE_ZN7testing8internal27PrettyUnitTestResultPrinter11OnTestStartERKNS_8TestInfoE_ZN7testing8internal29PrintFullTestCommentIfPresentERKNS_8TestInfoE_ZN7testing8internal27PrettyUnitTestResultPrinter16PrintFailedTestsERKNS_8UnitTestE_ZN7testing8internal17TestEventRepeater7ReleaseEPNS_17TestEventListenerEmemmove_ZN7testing8internal24XmlUnitTestResultPrinterC2EPKcstderrfwriteexit_ZN7testing8internal24XmlUnitTestResultPrinterC1EPKc_ZN7testing8internal24XmlUnitTestResultPrinter26RemoveInvalidXmlCharactersERKSs_ZN7testing8internal24XmlUnitTestResultPrinter21OutputXmlCDataSectionEPSoPKc_ZNSo5writeEPKcistrstr_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc_ZN7testing18TestEventListenersC2Ev_ZN7testing18TestEventListenersC1Ev_ZN7testing18TestEventListenersD2Ev_ZN7testing18TestEventListenersD1Ev_ZN7testing18TestEventListeners7ReleaseEPNS_17TestEventListenerE_ZN7testing18TestEventListeners8repeaterEv_ZNK7testing18TestEventListeners22EventForwardingEnabledEv_ZN7testing18TestEventListeners23SuppressEventForwardingEv_ZNK7testing8UnitTest26successful_test_case_countEv_ZNK7testing8UnitTest22failed_test_case_countEv_ZNK7testing8UnitTest21total_test_case_countEv_ZNK7testing8UnitTest22test_case_to_run_countEv_ZNK7testing8UnitTest21successful_test_countEv_ZNK7testing8UnitTest17failed_test_countEv_ZNK7testing8UnitTest30reportable_disabled_test_countEv_ZNK7testing8UnitTest19disabled_test_countEv_ZNK7testing8UnitTest21reportable_test_countEv_ZNK7testing8UnitTest16total_test_countEv_ZNK7testing8UnitTest17test_to_run_countEv_ZNK7testing8UnitTest15start_timestampEv_ZNK7testing8UnitTest12elapsed_timeEv_ZNK7testing8UnitTest6PassedEv_ZNK7testing8UnitTest6FailedEv_ZNK7testing8UnitTest11GetTestCaseEi_ZNK7testing8UnitTest18ad_hoc_test_resultEv_ZN7testing8UnitTest18GetMutableTestCaseEi_ZN7testing8UnitTest9listenersEv_ZN7testing14TestPartResultD2Ev_ZN7testing14TestPartResultD1Ev_ZN7testing12TestPropertyD2Ev_ZN7testing12TestPropertyD1Ev_ZNK7testing8UnitTest20original_working_dirEv_ZNK7testing8UnitTest11random_seedEv_ZN7testing8UnitTest27parameterized_test_registryEv_ZN7testing8internal12UnitTestImpl32SuppressTestEventsIfInSubprocessEv_ZN7testing8internal30WriteToShardStatusFileIfNeededEvfopenfclose_ZN7testing8internal20ShouldRunTestOnShardEiii_ZN7testing8internal12UnitTestImpl23ListTestsMatchingFilterEv_ZN7testing8internal12UnitTestImpl25set_os_stack_trace_getterEPNS0_27OsStackTraceGetterInterfaceE_ZN7testing8internal12UnitTestImpl19current_test_resultEv_ZN7testing8internal12UnitTestImpl14UnshuffleTestsEv_ZN7testing8internal6IsTrueEb_ZN7testing8internal10AlwaysTrueEv_ZN7testing8internal10SkipPrefixEPKcPS2_strncmp_ZN7testing8internal14ParseFlagValueEPKcS2_b_ZN7testing8internal13ParseBoolFlagEPKcS2_Pb_ZN7testing8internal15ParseStringFlagEPKcS2_PSs_ZNSs6assignEPKcj_ZN7testing8internal16InDeathTestChildEv_ZNKSs7compareEPKc_ZN7testing14ExitedWithCodeC2Ei_ZN7testing14ExitedWithCodeC1Ei_ZNK7testing14ExitedWithCodeclEi_ZN7testing14KilledBySignalC2Ei_ZN7testing14KilledBySignalC1Ei_ZNK7testing14KilledBySignalclEi_ZN7testing8internal20ExitedUnsuccessfullyEi_ZN7testing8internal23GetLastErrnoDescriptionEv__errno_locationstrerror_ZN7testing8internal9DeathTest11LastMessageEv_ZN7testing8internal9DeathTest24last_death_test_message_E_ZN7testing8internal9DeathTest27set_last_death_test_messageERKSs_ZN7testing8internal21StackLowerThanAddressEPKvPb_ZN7testing8internal14StackGrowsDownEv_ZNK7testing8internal8FilePath21FindLastPathSeparatorEvstrrchr_ZNK7testing8internal8FilePath21FileOrDirectoryExistsEv__xstat_ZNK7testing8internal8FilePath15DirectoryExistsEv_ZNK7testing8internal8FilePath15IsRootDirectoryEv_ZNK7testing8internal8FilePath14IsAbsolutePathEv_ZNK7testing8internal8FilePath11IsDirectoryEv_ZNK7testing8internal8FilePath12CreateFolderEvmkdir_ZN7testing8internal8FilePath9NormalizeEv_Znajmemset_ZdaPv_ZN7testing8internal8FilePath13GetCurrentDirEvgetcwd_ZNK7testing8internal8FilePath19RemoveDirectoryNameEv_ZN7testing8internal24GetCurrentExecutableNameEv_ZN7testing8internal17g_executable_pathE_ZNK7testing8internal8FilePath14RemoveFileNameEv_ZNK7testing8internal8FilePath27RemoveTrailingPathSeparatorEv_ZNK7testing8internal8FilePath28CreateDirectoriesRecursivelyEv_ZNK7testing8internal8FilePath15RemoveExtensionEPKc_ZN7testing8internal14GetThreadCountEv_ZN7testing8internal2RED2Evregfreefree_ZN7testing8internal2RED1Ev_ZN7testing8internal2RE9FullMatchEPKcRKS1_regexec_ZN7testing8internal2RE12PartialMatchEPKcRKS1__ZN7testing8internal8GTestLogD2Ev_ZSt4cerr_ZNSo3putEc_ZNSo5flushEv_ZNKSt5ctypeIcE13_M_widen_initEv_ZSt16__throw_bad_castv_ZN7testing8internal8GTestLogD1Ev_ZN7testing8internal14CapturedStream11GetFileSizeEP8_IO_FILEfseekftell_ZN7testing8internal14CapturedStream14ReadEntireFileEP8_IO_FILEfread_ZN7testing8internal17GetCapturedStreamEPPNS0_14CapturedStreamEdup2closeremove_ZN7testing8internal17GetCapturedStdoutEv_ZN7testing8internal17GetCapturedStderrEv_ZN7testing8internal18SetInjectableArgvsEPKSt6vectorISsSaISsEE_ZN7testing8internal18GetInjectableArgvsEv_ZN7testing8internal7g_argvsE_ZN7testing9internal220PrintBytesInObjectToEPKhjPSo_ZNSo9_M_insertImEERSoT__ZN7testinglsERSoRKNS_14TestPartResultE_ZNSolsEi_ZNSt9basic_iosIcSt11char_traitsIcEE5clearESt12_Ios_Iostate_ZNK7testing19TestPartResultArray17GetTestPartResultEi_ZNK7testing19TestPartResultArray4sizeEv_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEED2Ev_ZTVSt15basic_stringbufIcSt11char_traitsIcESaIcEE_ZTVSt15basic_streambufIcSt11char_traitsIcEE_ZNSt6localeD1Ev_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEED1Ev_ZN7testing7MessageC2Ev_ZNSt8ios_baseC2Ev_ZTTSt18basic_stringstreamIcSt11char_traitsIcESaIcEE_ZTVSt9basic_iosIcSt11char_traitsIcEE_ZNSt9basic_iosIcSt11char_traitsIcEE4initEPSt15basic_streambufIcS1_E_ZTVSt18basic_stringstreamIcSt11char_traitsIcESaIcEE_ZNSt6localeC1Ev_ZNSt8ios_baseD2Ev_ZNSdD2Ev_ZN7testing7MessageC1Ev_ZN7testing8internal30GetBoolAssertionFailureMessageERKNS_15AssertionResultEPKcS5_S5__ZN7testing8internal10ParseInt32ERKNS_7MessageEPKcPistrtol_ZN7testing8internal17Int32FromEnvOrDieEPKci_ZN7testing8internal14ParseInt32FlagEPKcS2_Pitoupper_ZN7testing8internal16BoolFromGTestEnvEPKcb_ZN7testing8internal18StringFromGTestEnvEPKcS2__ZN7testing8internal17Int32FromGTestEnvEPKci_ZN7testing7MessageC2ERKS0__ZN7testing7MessageC1ERKS0__ZN7testing8internal11ShouldShardEPKcS2_b_ZN7testing8internal6String12FormatHexIntEi_ZNSt18basic_stringstreamIcSt11char_traitsIcESaIcEED1Ev_ZN7testing8internal27FormatTimeInMillisAsSecondsEx_ZNSo9_M_insertIdEERSoT__ZN7testing8internal6String15FormatIntWidth2Ei_ZN7testing8internal6String10FormatByteEh_ZN7testing8internal24XmlUnitTestResultPrinter9EscapeXmlERKSsb_ZN7testing8internal24XmlUnitTestResultPrinter29TestPropertiesAsXmlAttributesERKNS_10TestResultE_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEED0Ev_ZN7testing8internal10scoped_ptrISsE5resetEPSs_ZN7testing8internal9EqFailureEPKcS2_RKSsS4_b_ZNK7testing15AssertionResultntEv_ZN7testing16AssertionFailureERKNS_7MessageE_ZN7testing8internal10scoped_ptrINS0_24InternalRunDeathTestFlagEE5resetEPS2__ZStplIcSt11char_traitsIcESaIcEESbIT_T0_T1_ERKS6_PKS3__ZStplIcSt11char_traitsIcESaIcEESbIT_T0_T1_EPKS3_RKS6__ZN7testing8internal15CodePointToUtf8Ej_ZN7testing8internal16WideStringToUtf8EPKwi_ZNSt18basic_stringstreamIcSt11char_traitsIcESaIcEEC1ESt13_Ios_Openmodewcslen_ZN7testing7MessagelsERKSbIwSt11char_traitsIwESaIwEE_ZN7testing8internal6String15ShowWideCStringEPKw_ZN7testing7MessagelsEPKw_ZN7testing7MessagelsEPwisxdigit_ZN7testing8internal19UniversalPrintArrayEPKcjPSo_ZN7testing8internal7PrintToEPKcPSo_ZNSo9_M_insertIPKvEERSoT__ZN7testing8internal13PrintStringToERKSsPSo_ZN7testing13PrintToStringIPKcEESsRKT__ZN7testing8internal14CmpHelperSTREQEPKcS2_S2_S2__ZN7testing8internal18CmpHelperSTRCASEEQEPKcS2_S2_S2__ZN7testing8internal19UniversalPrintArrayEPKwjPSo_ZN7testing8internal7PrintToEPKwPSo_ZN7testing8internal17PrintWideStringToERKSbIwSt11char_traitsIwESaIwEEPSo_ZN7testing13PrintToStringIPKwEESsRKT__ZNSbIwSt11char_traitsIwESaIwEEC1EPKwRKS1__ZNSbIwSt11char_traitsIwESaIwEE4_Rep20_S_empty_rep_storageE_ZNSbIwSt11char_traitsIwESaIwEE4_Rep10_M_destroyERKS1__ZN7testing8internal14CmpHelperSTREQEPKcS2_PKwS4__ZN7testing8internal17StreamingListener9UrlEncodeEPKc_ZN7testing8internal18StreamableToStringIiEESsRKT__ZN7testing8internal27PrettyUnitTestResultPrinter15OnTestCaseStartERKNS_8TestCaseE_ZN7testing8internal27PrettyUnitTestResultPrinter20OnTestIterationStartERKNS_8UnitTestEi_ZN7testing8internal18StreamableToStringIxEESsRKT__ZNSo9_M_insertIxEERSoT__ZN7testing8internal27PrettyUnitTestResultPrinter9OnTestEndERKNS_8TestInfoE_ZN7testing8internal27PrettyUnitTestResultPrinter13OnTestCaseEndERKNS_8TestCaseE_ZN7testing8internal27PrettyUnitTestResultPrinter18OnTestIterationEndERKNS_8UnitTestEi_ZStplIcSt11char_traitsIcESaIcEESbIT_T0_T1_ERKS6_S8__ZN7testing8internal8FilePath11ConcatPathsERKS1_S3__ZNSs6appendEjc__divdi3_ZN7testing8internal32FormatEpochTimeInMillisAsIso8601Exlocaltime_ZN7testing8internal8FilePath12MakeFileNameERKS1_S3_iPKc_ZN7testing8internal8FilePath22GenerateUniqueFileNameERKS1_S3_PKc_ZN7testing8internal18FormatFileLocationEPKci_ZN7testing8internal8GTestLogC2ENS0_16GTestLogSeverityEPKci_ZN7testing8internal8GTestLogC1ENS0_16GTestLogSeverityEPKci_ZN7testing8internal13CaptureStreamEiPKcPPNS0_14CapturedStreamEdupmkstemp_ZN7testing8internal13CaptureStdoutEv_ZN7testing8internal13CaptureStderrEv_ZN7testing8internal17StreamingListener12SocketWriter14MakeConnectionEvgetaddrinfosocketconnectfreeaddrinfogai_strerror_ZN7testing8internal17StreamingListener12SocketWriter15CloseConnectionEv_ZN7testing8internal5MutexD2Evpthread_mutex_destroy_ZN7testing8internal5MutexD1Ev_ZN7testing8internal9MutexBase6UnlockEvpthread_mutex_unlock_ZN7testing8internal9MutexBase4LockEvpthread_mutex_lockpthread_self_ZN7testing8internal17StreamingListener12SocketWriter4SendERKSswrite_ZN7testing8internal6Random8GenerateEj_ZN7testing8internal13DeathTestImpl6PassedEb_ZN7testing8internal17StreamingListener12SocketWriterD2Ev_ZTVN7testing8internal17StreamingListener12SocketWriterE_ZN7testing8internal17StreamingListener12SocketWriterD1Ev_ZN7testing8internal17StreamingListener12SocketWriterD0Ev_ZN7testing8internal17StreamingListenerD2Ev_ZTVN7testing8internal17StreamingListenerE_ZN7testing8internal17StreamingListenerD1Ev_ZN7testing8internal17StreamingListenerD0Ev_ZN7testing8internal17StreamingListener20AbstractSocketWriter6SendLnERKSs_ZN7testing8internal17StreamingListener11OnTestStartERKNS_8TestInfoE_ZN7testing8internal17StreamingListener15OnTestCaseStartERKNS_8TestCaseE_ZN7testing8internal17StreamingListener16OnTestProgramEndERKNS_8UnitTestE_ZN7testing8internal17StreamingListener16OnTestPartResultERKNS_14TestPartResultE_ZN7testing8internal17StreamingListener20OnTestIterationStartERKNS_8UnitTestEi_ZN7testing10TestResultC2Evpthread_mutex_init_ZN7testing10TestResultC1Ev_ZN7testing8internal18OsStackTraceGetterD2Ev_ZTVN7testing8internal18OsStackTraceGetterE_ZN7testing8internal18OsStackTraceGetterD1Ev_ZN7testing8internal18OsStackTraceGetterD0Ev_ZN7testing8internal12UnitTestImpl21os_stack_trace_getterEv_ZN7testing8internal12UnitTestImpl31SetGlobalTestPartResultReporterEPNS_31TestPartResultReporterInterfaceE_ZN7testing8internal12UnitTestImpl31GetGlobalTestPartResultReporterEv_ZNK7testing8UnitTest17current_test_caseEv_ZNK7testing8UnitTest17current_test_infoEv_ZN7testing8internal38DefaultPerThreadTestPartResultReporter20ReportTestPartResultERKNS_14TestPartResultE_ZN7testing10TestResultD2Ev_ZN7testing10TestResultD1Ev_ZN7testing8internal17StreamingListener18OnTestProgramStartERKNS_8UnitTestE_ZN7testing8internal26GoogleTestFailureExceptionC2ERKNS_14TestPartResultE_ZNSt13runtime_errorC2ERKSs_ZN7testing8internal26GoogleTestFailureExceptionC1ERKNS_14TestPartResultE_ZN7testing8internal27PrettyUnitTestResultPrinter16OnTestPartResultERKNS_14TestPartResultE_ZN7testing8internal25ReportInvalidTestCaseTypeEPKcS2_ifprintf_ZN7testing8internal37FormatCompilerIndependentFileLocationEPKci_ZN7testing8internal17AppendUserMessageERKSsRKNS_7MessageE_ZN7testing8internal17StreamingListener9OnTestEndERKNS_8TestInfoE_ZN7testing8internal17StreamingListener13OnTestCaseEndERKNS_8TestCaseE_ZN7testing8internal17StreamingListener18OnTestIterationEndERKNS_8UnitTestEi_ZN7testing15AssertionResultlsINS_7MessageEEERS0_RKT__ZN7testing15AssertionResultlsIA11_cEERS0_RKT__ZN7testing15AssertionResultlsISsEERS0_RKT__ZN7testing15AssertionResultlsIA2_cEERS0_RKT__ZN7testing15AssertionResultlsINS_14TestPartResultEEERS0_RKT__ZN7testing15AssertionResultlsIA3_cEERS0_RKT__ZN7testing8internal13HasOneFailureEPKcS2_S2_RKNS_19TestPartResultArrayENS_14TestPartResult4TypeERKSs_ZN7testing15AssertionResultlsIPKcEERS0_RKT__ZN7testing11IsSubstringEPKcS1_S1_S1__ZN7testing14IsNotSubstringEPKcS1_S1_S1__ZNKSs4findEPKcjj_ZN7testing11IsSubstringEPKcS1_RKSsS3__ZN7testing14IsNotSubstringEPKcS1_RKSsS3__ZNKSbIwSt11char_traitsIwESaIwEE4findEPKwjj_ZN7testing11IsSubstringEPKcS1_RKSbIwSt11char_traitsIwESaIwEES7__ZN7testing14IsNotSubstringEPKcS1_RKSbIwSt11char_traitsIwESaIwEES7_wcsstr_ZN7testing11IsSubstringEPKcS1_PKwS3__ZN7testing14IsNotSubstringEPKcS1_PKwS3__ZN7testing15AssertionResultlsIA5_cEERS0_RKT__ZN7testing15AssertionResultlsIA7_cEERS0_RKT__ZN7testing8internal20DoubleNearPredFormatEPKcS2_S2_ddd_ZN7testing15AssertionResultlsIA12_cEERS0_RKT__ZN7testing8internal14CmpHelperSTRNEEPKcS2_PKwS4__ZN7testing8internal14CmpHelperSTRNEEPKcS2_S2_S2__ZN7testing8internal18CmpHelperSTRCASENEEPKcS2_S2_S2__ZN7testing8internal15FloatingPointLEIfEENS_15AssertionResultEPKcS4_T_S5__ZN7testing7FloatLEEPKcS1_ff_ZN7testing8internal15FloatingPointLEIdEENS_15AssertionResultEPKcS4_T_S5__ZN7testing8DoubleLEEPKcS1_dd_ZN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEED2Evpthread_getspecificpthread_key_delete_ZN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEED1Ev_ZN7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEED2Ev_ZN7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEED1Ev_ZN7testing8internal12ShuffleRangeIiEEvPNS0_6RandomEiiPSt6vectorIT_SaIS5_EE_ZN7testing8TestCase12ShuffleTestsEPNS_8internal6RandomE_ZN7testing8internal12UnitTestImpl12ShuffleTestsEv_ZN7testing8internal18ParseNaturalNumberIiEEbRKSsPT_strtoull_ZN7testing8internal18PrintCharAndCodeToIhhEEvT0_PSo_ZN7testing8internal7PrintToEhPSo_ZN7testing8internal18PrintCharAndCodeToIhaEEvT0_PSo_ZN7testing8internal7PrintToEaPSo_ZN7testing8internal18PrintCharAndCodeToIwwEEvT0_PSo_ZN7testing8internal7PrintToEwPSo_ZN7testing8internal10scoped_ptrIKSsE5resetEPS2__ZN7testing8TestInfoD2Ev_ZN7testing8TestInfoD1Ev_ZN7testing8TestCaseD2Ev_ZTVN7testing8TestCaseE_ZN7testing8TestCaseD1Ev_ZN7testing8TestCaseD0Ev_ZN7testing8internal12UnitTestImplD2Ev_ZTVN7testing8internal12UnitTestImplE_ZN7testing8internal12UnitTestImplD1Ev_ZN7testing8internal12UnitTestImplD0Ev_ZN7testing8UnitTestD2Ev_ZTVN7testing8UnitTestE_ZN7testing8UnitTestD1Ev_ZN7testing8UnitTestD0Ev_ZN7testing8TestCaseC2EPKcS2_PFvvES4__ZN7testing8TestCaseC1EPKcS2_PFvvES4__ZN7testing8TestInfoC2ERKSsS2_PKcS4_PKvPNS_8internal15TestFactoryBaseE_ZN7testing8TestInfoC1ERKSsS2_PKcS4_PKvPNS_8internal15TestFactoryBaseE_ZNSt6vectorIPN7testing8TestInfoESaIS2_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS2_S4_EERKS2__ZNSt6vectorIiSaIiEE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPiS1_EERKi_ZN7testing8TestCase11AddTestInfoEPNS_8TestInfoE_ZNSt6vectorIPN7testing17TestEventListenerESaIS2_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS2_S4_EERKS2__ZN7testing8internal12UnitTestImpl24ConfigureStreamingOutputEv_ZN7testing8internal17TestEventRepeater6AppendEPNS_17TestEventListenerE_ZN7testing18TestEventListeners6AppendEPNS_17TestEventListenerE_ZN7testing18TestEventListeners23SetDefaultResultPrinterEPNS_17TestEventListenerE_ZN7testing8internal12UnitTestImplC2EPNS_8UnitTestEpthread_key_create_ZTVN7testing8internal23DefaultDeathTestFactoryE_ZTVN7testing8internal27PrettyUnitTestResultPrinterE_ZN7testing8internal12UnitTestImplC1EPNS_8UnitTestE_ZN7testing8UnitTestC2Ev_ZN7testing8UnitTestC1Ev_ZN7testing8UnitTest11GetInstanceEv__dso_handle__cxa_atexit__cxa_guard_abort_ZN7testing8internal15UnitTestOptions27GetAbsolutePathToOutputFileEv_ZN7testing4Test15HasFatalFailureEv_ZN7testing4Test18HasNonfatalFailureEv_ZN7testing8internal31GetCurrentOsStackTraceExceptTopEPNS_8UnitTestEi_ZN7testing8internal14DeathTestAbortERKSsfdopenfputcfputs_exit_ZN7testing8internal13DeathTestImpl26ReadAndInterpretStatusByteEvread_ZN7testing8internal13DeathTestImpl5AbortENS0_9DeathTest11AbortReasonE_ZN7testing8internal16ForkingDeathTest4WaitEvwaitpid_ZN7testing8internal15NoExecDeathTestD2Ev_ZTVN7testing8internal13DeathTestImplE_ZN7testing8internal15NoExecDeathTestD1Ev_ZN7testing8internal13ExecDeathTestD2Ev_ZN7testing8internal13ExecDeathTestD1Ev_ZN7testing8internal15NoExecDeathTestD0Ev_ZN7testing8internal13ExecDeathTestD0Ev_ZN7testing8internal9DeathTestC2Ev_ZTVN7testing8internal9DeathTestE_ZN7testing8internal9DeathTestC1Ev_ZN7testing8internal16ForkingDeathTestC2EPKcPKNS0_2REE_ZTVN7testing8internal16ForkingDeathTestE_ZN7testing8internal16ForkingDeathTestC1EPKcPKNS0_2REE_ZN7testing8internal9DeathTest6CreateEPKcPKNS0_2REES3_iPPS1__ZN7testing8internal15NoExecDeathTest10AssumeRoleEvpipefork_ZN7testing8internal23DefaultDeathTestFactory6CreateEPKcPKNS0_2REES3_iPPNS0_9DeathTestE_ZTVN7testing8internal15NoExecDeathTestE_ZTVN7testing8internal13ExecDeathTestEchdirenvironexecve_ZN7testing18TestEventListeners22SetDefaultXmlGeneratorEPNS_17TestEventListenerE_ZN7testing8internal12UnitTestImpl18ConfigureXmlOutputEv_ZNSt6vectorIPN7testing11EnvironmentESaIS2_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS2_S4_EERKS2__ZN7testing8UnitTest14AddEnvironmentEPNS_11EnvironmentE_ZNSt6vectorIPN7testing8TestCaseESaIS2_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS2_S4_EERKS2__ZN7testing8internal18StreamableToStringIPcEESsRKT__ZNSt6vectorIPcSaIS0_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS0_S2_EERKS0__ZNSt6vectorIPcSaIS0_EE6insertEN9__gnu_cxx17__normal_iteratorIPS0_S2_EERKS0__ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE8_M_eraseEPSt13_Rb_tree_nodeISsE_ZNKSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE4findERKSsmemcmp_ZNSt8_Rb_treeISsSsSt9_IdentityISsESt4lessISsESaISsEE16_M_insert_uniqueERKSs_ZSt18_Rb_tree_decrementPSt18_Rb_tree_node_base_ZSt29_Rb_tree_insert_and_rebalancebPSt18_Rb_tree_node_baseS0_RS___cxa_begin_catch__cxa_rethrow__cxa_end_catch_ZN7testing8internal27CheckedDowncastToActualTypeINS0_11ThreadLocalISt6vectorINS0_9TraceInfoESaIS4_EEE11ValueHolderENS0_26ThreadLocalValueHolderBaseEEEPT_PT0__ZTSN7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEE11ValueHolderE_ZTIN7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEE11ValueHolderE_ZTIN7testing8internal26ThreadLocalValueHolderBaseE__dynamic_cast__cxa_bad_typeid_ZN7testing13PrintToStringIxEESsRKT__ZN7testing8internal11CmpHelperEQEPKcS2_xx_ZN7testing8internal11CmpHelperNEEPKcS2_xx_ZN7testing8internal11CmpHelperLEEPKcS2_xx_ZN7testing8internal11CmpHelperLTEPKcS2_xx_ZN7testing8internal11CmpHelperGEEPKcS2_xx_ZN7testing8internal11CmpHelperGTEPKcS2_xx_ZSt9__find_ifIN9__gnu_cxx17__normal_iteratorIPN7testing12TestPropertyESt6vectorIS3_SaIS3_EEEENS0_5__ops10_Iter_predINS2_8internal17TestPropertyKeyIsEEEET_SE_SE_T0_St26random_access_iterator_tag_ZSt9__find_ifIN9__gnu_cxx17__normal_iteratorIPKSsSt6vectorISsSaISsEEEENS0_5__ops16_Iter_equals_valIS2_EEET_SB_SB_T0_St26random_access_iterator_tag_ZSt9__find_ifIN9__gnu_cxx17__normal_iteratorIPPN7testing8TestCaseESt6vectorIS4_SaIS4_EEEENS0_5__ops10_Iter_predINS2_8internal14TestCaseNameIsEEEET_SF_SF_T0_St26random_access_iterator_tag_ZN7testing8internal12UnitTestImpl11GetTestCaseEPKcS3_PFvvES5__ZN7testing8internal23MakeAndRegisterTestInfoEPKcS2_S2_S2_PKvPFvvES6_PNS0_15TestFactoryBaseE_ZNSs12_S_constructIPKcEEPcT_S3_RKSaIcESt20forward_iterator_tag_ZSt19__throw_logic_errorPKc_ZNSs4_Rep9_S_createEjjRKSaIcEmemcpy_ZN7testing8internal15UnitTestOptions17FilterMatchesTestERKSsS3__ZN7testing8internal12UnitTestImpl11FilterTestsENS1_18ReactionToShardingE_ZN7testing14TestPartResult14ExtractSummaryEPKc_ZN7testing8internal17kStackTraceMarkerE_ZN7testing8internal19TypedTestCasePState25VerifyRegisteredTestNamesEPKciS3_isspace_ZSt18_Rb_tree_incrementPKSt18_Rb_tree_node_base_ZN7testing8internal28ParseGoogleTestFlagsOnlyImplIwEEvPiPPT__ZN7testing8internal11g_help_flagE_ZN7testing8internal24ParseGoogleTestFlagsOnlyEPiPPw_ZN7testing8internal28ParseGoogleTestFlagsOnlyImplIcEEvPiPPT__ZN7testing8internal24ParseGoogleTestFlagsOnlyEPiPPc_ZN7testing8internal27CheckedDowncastToActualTypeINS0_11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE11ValueHolderENS0_26ThreadLocalValueHolderBaseEEEPT_PT0__ZTSN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE11ValueHolderE_ZTIN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE11ValueHolderE_ZNK7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE16GetOrCreateValueEv_ZTVN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE11ValueHolderEpthread_setspecific_ZN7testing8internal12UnitTestImpl41GetTestPartResultReporterForCurrentThreadEv_ZN7testing8internal12UnitTestImpl41SetTestPartResultReporterForCurrentThreadEPNS_31TestPartResultReporterInterfaceE_ZN7testing8internal24HasNewFatalFailureHelperD2Ev_ZTVN7testing8internal24HasNewFatalFailureHelperE_ZN7testing8internal24HasNewFatalFailureHelperD1Ev_ZN7testing8internal24HasNewFatalFailureHelperD0Ev_ZN7testing32ScopedFakeTestPartResultReporterD2Ev_ZTVN7testing32ScopedFakeTestPartResultReporterE_ZN7testing32ScopedFakeTestPartResultReporterD1Ev_ZN7testing32ScopedFakeTestPartResultReporterD0Ev_ZN7testing8internal24HasNewFatalFailureHelperC2Ev_ZN7testing8internal24HasNewFatalFailureHelperC1Ev_ZN7testing32ScopedFakeTestPartResultReporter4InitEv_ZN7testing32ScopedFakeTestPartResultReporterC2EPNS_19TestPartResultArrayE_ZN7testing32ScopedFakeTestPartResultReporterC1EPNS_19TestPartResultArrayE_ZN7testing32ScopedFakeTestPartResultReporterC2ENS0_13InterceptModeEPNS_19TestPartResultArrayE_ZN7testing32ScopedFakeTestPartResultReporterC1ENS0_13InterceptModeEPNS_19TestPartResultArrayE_ZNSt12_Destroy_auxILb0EE9__destroyIPSsEEvT_S3__ZN7testing8internal13ExecDeathTest10AssumeRoleEvfcntlstrdupsigemptysetsigactiongetpagesizemmapclonemunmap_ZSt17__throw_bad_allocv_ZN7testing8internal24XmlUnitTestResultPrinter18OutputXmlAttributeEPSoRKSsS4_S4__ZN7testing8internal24XmlUnitTestResultPrinter17OutputXmlTestInfoEPSoPKcRKNS_8TestInfoE_ZN7testing8internal24XmlUnitTestResultPrinter16PrintXmlTestCaseEPSoRKNS_8TestCaseE_ZN7testing8internal24XmlUnitTestResultPrinter16PrintXmlUnitTestEPSoRKNS_8UnitTestE_ZN7testing8internal24XmlUnitTestResultPrinter18OnTestIterationEndERKNS_8UnitTestEi_ZNSt6vectorISsSaISsEE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPSsS1_EERKSs_ZN7testing8internal29ParseInternalRunDeathTestFlagEv_ZN7testing8internal12UnitTestImpl19PostFlagParsingInitEv_ZN7testing8internal18InitGoogleTestImplIcEEvPiPPT__ZN7testing8internal18g_init_gtest_countE_ZN7testing14InitGoogleTestEPiPPc_ZN7testing8internal18InitGoogleTestImplIwEEvPiPPT__ZN7testing14InitGoogleTestEPiPPw_ZNSt12_Destroy_auxILb0EE9__destroyIPN7testing8internal9TraceInfoEEEvT_S6__ZNK7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEE16GetOrCreateValueEv_ZN7testing8UnitTest17AddTestPartResultENS_14TestPartResult4TypeEPKciRKSsS6___cxa_allocate_exception_ZTIN7testing8internal26GoogleTestFailureExceptionE__cxa_throw__cxa_free_exception_ZNK7testing8internal12AssertHelperaSERKNS_7MessageE_ZN7testing8internal20SingleFailureCheckerD2Ev_ZN7testing8internal20SingleFailureCheckerD1Ev_ZN7testing24ValidateTestPropertyNameERKSsRKSt6vectorISsSaISsEE_ZN7testing10TestResult20ValidateTestPropertyERKSsRKNS_12TestPropertyE_ZN7testing4Test19HasSameFixtureClassEv_ZN7testing8internal2RE4InitEPKcregcomp_ZN7testing8internal30ReportFailureInUnknownLocationENS_14TestPartResult4TypeERKSs_ZN7testing8internal35HandleExceptionsInMethodIfSupportedINS_4TestEvEET0_PT_MS4_FS3_vEPKc_ZTISt9exception_ZN7testing4Test3RunEv_ZN7testing8internal35HandleExceptionsInMethodIfSupportedINS0_15TestFactoryBaseEPNS_4TestEEET0_PT_MS6_FS5_vEPKc_ZN7testing8TestInfo3RunEv_ZN7testing8internal35HandleExceptionsInMethodIfSupportedINS_8TestCaseEvEET0_PT_MS4_FS3_vEPKc_ZN7testing8TestCase3RunEv_ZN7testing8internal12UnitTestImpl11RunAllTestsEv_ZN7testing8internal35HandleExceptionsInMethodIfSupportedINS0_12UnitTestImplEbEET0_PT_MS4_FS3_vEPKc_ZN7testing8UnitTest3RunEv_ZN7testing8UnitTest13PopGTestTraceEv_ZN7testing8internal11ScopedTraceD2Ev_ZN7testing8internal11ScopedTraceD1Ev_ZNSt6vectorIN7testing8internal9TraceInfoESaIS2_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS2_S4_EERKS2__ZN7testing8UnitTest14PushGTestTraceERKNS_8internal9TraceInfoE_ZN7testing8internal11ScopedTraceC2EPKciRKNS_7MessageE_ZN7testing8internal11ScopedTraceC1EPKciRKNS_7MessageE_ZNSt20__uninitialized_copyILb0EE13__uninit_copyIPN7testing14TestPartResultES4_EET0_T_S6_S5__ZNSt6vectorIN7testing14TestPartResultESaIS1_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS1_S3_EERKS1__ZN7testing8internal35DefaultGlobalTestPartResultReporter20ReportTestPartResultERKNS_14TestPartResultE_ZN7testing10TestResult17AddTestPartResultERKNS_14TestPartResultE_ZN7testing19TestPartResultArray6AppendERKNS_14TestPartResultE_ZN7testing32ScopedFakeTestPartResultReporter20ReportTestPartResultERKNS_14TestPartResultE_ZNSt20__uninitialized_copyILb0EE13__uninit_copyIPN7testing12TestPropertyES4_EET0_T_S6_S5__ZNSt6vectorIN7testing12TestPropertyESaIS1_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS1_S3_EERKS1__ZN7testing10TestResult14RecordPropertyERKSsRKNS_12TestPropertyE_ZN7testing8internal12UnitTestImpl14RecordPropertyERKNS_12TestPropertyE_ZNSs6assignEPKc_ZN7testing8UnitTest14RecordPropertyERKSsS2__ZN7testing4Test14RecordPropertyERKSsS2__ZN7testing4Test14RecordPropertyERKSsi_ZNSt8ios_base4InitC1Ev_ZNSt8ios_base4InitD1Ev_ZNSsD1Ev_ZN7testing8internal23kTestTypeIdInGoogleTestE_ZTVN10__cxxabiv117__class_type_infoE_ZTSN7testing8internal26ThreadLocalValueHolderBaseE_ZTVN10__cxxabiv120__si_class_type_infoE_ZTSN7testing8internal26GoogleTestFailureExceptionE_ZTISt13runtime_error_ZTIN7testing8internal9DeathTestE_ZTSN7testing8internal9DeathTestE_ZTIN7testing8internal16DeathTestFactoryE_ZTSN7testing8internal16DeathTestFactoryE_ZTSN7testing8internal23DefaultDeathTestFactoryE_ZTIN7testing8internal23DefaultDeathTestFactoryE_ZTIN7testing31TestPartResultReporterInterfaceE_ZTSN7testing31TestPartResultReporterInterfaceE_ZTSN7testing8internal24HasNewFatalFailureHelperE_ZTIN7testing8internal24HasNewFatalFailureHelperE_ZTSN7testing4TestE_ZTIN7testing4TestE_ZTSN7testing8TestCaseE_ZTIN7testing8TestCaseE_ZTIN7testing17TestEventListenerE_ZTSN7testing17TestEventListenerE_ZTIN7testing22EmptyTestEventListenerE_ZTSN7testing22EmptyTestEventListenerE_ZTSN7testing8UnitTestE_ZTIN7testing8UnitTestE_ZTSN7testing32ScopedFakeTestPartResultReporterE_ZTIN7testing32ScopedFakeTestPartResultReporterE_ZTIN7testing8internal27OsStackTraceGetterInterfaceE_ZTSN7testing8internal27OsStackTraceGetterInterfaceE_ZTSN7testing8internal18OsStackTraceGetterE_ZTIN7testing8internal18OsStackTraceGetterE_ZTSN7testing8internal35DefaultGlobalTestPartResultReporterE_ZTIN7testing8internal35DefaultGlobalTestPartResultReporterE_ZTSN7testing8internal38DefaultPerThreadTestPartResultReporterE_ZTIN7testing8internal38DefaultPerThreadTestPartResultReporterE_ZTSN7testing8internal12UnitTestImplE_ZTIN7testing8internal12UnitTestImplE_ZTIN7testing8internal17StreamingListener20AbstractSocketWriterE_ZTSN7testing8internal17StreamingListener20AbstractSocketWriterE_ZTIN7testing8internal17StreamingListener12SocketWriterE_ZTSN7testing8internal17StreamingListener12SocketWriterE_ZTIN7testing8internal17StreamingListenerE_ZTSN7testing8internal17StreamingListenerE_ZTSN7testing8internal27PrettyUnitTestResultPrinterE_ZTIN7testing8internal27PrettyUnitTestResultPrinterE_ZTSN7testing8internal17TestEventRepeaterE_ZTIN7testing8internal17TestEventRepeaterE_ZTSN7testing8internal24XmlUnitTestResultPrinterE_ZTIN7testing8internal24XmlUnitTestResultPrinterE_ZTSN7testing8internal13DeathTestImplE_ZTIN7testing8internal13DeathTestImplE_ZTSN7testing8internal16ForkingDeathTestE_ZTIN7testing8internal16ForkingDeathTestE_ZTSN7testing8internal15NoExecDeathTestE_ZTIN7testing8internal15NoExecDeathTestE_ZTSN7testing8internal13ExecDeathTestE_ZTIN7testing8internal13ExecDeathTestE_ZNKSt13runtime_error4whatEv__cxa_pure_virtual_ZN7testing8internal18OsStackTraceGetter19kElidedFramesMarkerE_ZN7testing8internal18g_linked_ptr_mutexE_ZN7testing38FLAGS_gtest_show_internal_stack_framesE__pthread_key_createD   ]# ]%$D]I$b%(1]234 (R3]4k(]p5( ]p5((U ]] 6e 7p 8 8 8 7 8 ] 8; <a {    (  A B C" 8 ]> L   D B D1 Gz L O T V4 T t    ] ^i`<I Yfhjhmt(n]2n((E(Z(m lrp5!r)p.5g(t((((((((>(X((((,qxvvVeVM~T<[(b(k(r(y((A $,7=Da(v((((( ~%.3>CNW\glwA(((( (($(((((( *uuAW`]fgu]{g]g]g]_]]_]_ ]_!]'_6]<_K]Q_`]f_]$]$-2:JQX]]p]p]]$#]$]$]$]$VV v< ]C Q ]V $^ j #!D!'N!e!n!ps!z!!!!(! !(!nB"n\"("(" "]"8""]"8#] # #*#]0#8K#<Q# ## $T$V%$%D%d%%%x&v=&xe'j'{']''''p''''O(]T($l(q(]v($(#(]($((]($ )#I)q*7**]**]**]**]* +]+%+]*+p+]v++I+]+2+I+7+2+(+(++(r,(,(,(, ,(,?-S-7a--]----U.`.]m...... /1/Q//,0B00700]0 1 1]-161I>1O1(1(1 1(111I1 2(&2IQ2 ^2(x2(2]22 2I222(2 2(43(G3 T3(33(3C33(3I33(44;4(N4 Z4(u4(4I434I44(5($5 05(555 5(55(5 6(6 *6(T6]Z6f6Io67|626(6k636I66(6(7I7(V7(k7(v7 7(7(7(78D888888889#9(9-9r29N9!o9 y99!9$9C99 :&:'$:],:7:#=:Q:(_:(j::(: ::%::% ;5;(\;h;q;;;-;/;];8;];8 <]E<]a<]f<]<7<8<]<8<1<]<8<7<8<]<8<7=8.=[=2u===2==p=$>rO><\>;b><o><v>=>>><><>>><><??????$?7V?@]?6k?(t?>?=?A?? ?9?<?B?<@:*@]3@8G@7X@8h@]q@8@7@8@]@8@@]@8@]@8 A7A8-Al[A]oA]xAA]AA]AA AF8B:EB]NB8dBlsB8B(BpB8B]B8BB]B8BlB]B$C(CCHC:UC]^C8tClC8C(CpC8C]C8CC]C8ClC]D$D(D"DD D(D(D(D(E3E:@EpIE8QE7bE8pEEEE E F:F]"F82F7CF8SFEF]FF F:F]F8G%GlGG:iGI~G8GlG(G]GG(H oH{H]H(HH(.IJI:WI]`I8vI8IEI(I:I1IlIpJ$J(8J=JNJ(J(J J( KGKGlK:yKpK8KKK]K8KK8K]K8KK8K]L8L1L](L85L>L8KL]TL8cL1pL]yL8LNLlLL(LLLL:LpM8MM&M],M;M1HM]QM8^MgM8tM]}M8MNMlMM(MMM:MpNNN N])N8N1BN]KNUN^NkN]qN}NNNlNN(NNO O(O(O(DP;JP<TP<^P=P>P<P<P>P<P<Q? Q?Q?!Q7bQ@tQ6Q(Q>Q1QmQ?Q?Q?Q6R(R7"R8+R<1R<=R<CR<sR={RAR=RAR RQR R9R<RBS<FS;LS<VS<`S=S>S<S<S>S<S<T? T?T?(T7iT@wT6T(T>TTSTmT?T?T?T6T( U7U8U<U<"U<(U<7U<dU=iUAU=UAU UQU U9U<UBU<$V;*V<4V<>V=V>V<V<V>V<V<V?V?V?W7BW@SW6oW(uW>W1WmW?W?W?W6W(X7X8'X<-X<3X<?X<oX=wXAXXYYQY -Y9:Y<@YBVY=\YAdY sY<Y;Y<Y<Y=Z>Z<3Z<=Z>CZ<IZ<cZ?mZ?wZ?Z7Z@Z6Z(Z>][/n[m[?[?[?[6[([7[8[<[<[<\<\=\Ae\x\\\Q\ \9\<\B]= ]A] #]<U]:]]]]8]l]]^8#^],^8A^]J^8g^]p^8^8^8_8#_U/_]8_8N_8[_]d_8r_(_(_ _:`7`8&`]/`8<`]E`8[`8h`]q`8`(`(`s``V`]`8a]aJala a(a(a: b]b8'b78b8EbYb]bb8wb8b]b8b7b8b]b8bb]c8c82c:FclUc8cc(vcpcac(cc]cd]dZdYyd d(d:d8dle7e2e(^e<fe(peYe(eYe e:flf8f(?flKf7Zf2hf(faf(ff<f(gYgY'g 4g(cg(ghP$h]*h_3hI=h]Ch2Qh(bh(h( i(!i(4i fibi`i8i(ilj? j?j?j6'j(@j7Fj8Kj<Qj<`j<fj<{j<j<j=jAjcjQj  k(Wkaqk8k(k8k(k 8laYl]_llel8l(l(l mem8$m(Pm(cm m:mgmlm mn] n86n] K(`(y((((Պ(!]'A`jx(( ċ(!y-I7]=2KTI^]d2r((((]^Ɍ((0 =(R(g(((Ǎ]ލ]]]5:BP8Z]`8p7{8]8(Ȏ2&(9 b]jt]y~878p8͏<܏(eq}&'̐2ܐ (  ] 49]@n]vp8p8ؑ;N'p]pƒ]p 8]'8/EM X` ks ]ƓГpՓړ8p8/]8p 8//9]?8Gi]q{]8p8  %:]837D8T]]8p]̕8ڕ(l (0(p]]ǖ]Җ8("]+8]>T8b(y]p—p˗՗]ޗ8(Ai]r8:Ƙ]Ϙޘ1]l0p9F]Lb8o]x8]88((ؙ]((2(E R(((Ϛ((ypp8]81ћٛ < QpYcphm8w]|81 )p1;]@E8O]TY8ch1pp]8]8Ɲ1Ν  !0Fipq{]8]81ɞpў۞]8]81'/ :B appß]ȟ͟8ן]ܟ81p#](-87]<A8IN1Vow  ̠p] 8]!8+018QpYc]hm8w]|81 ¡ʡ 9pDN]SX8b]gl8ty1p]8Ģ]ɢ΢8֢ۢ1   F(Z(n((ģ(أ(((,8Ypakppu8]81 ɤ]]:+88]A8I7Z88l(ѥ]](- u~(((Ѧ( (GNSa(lq( :ͧp֧878 ]8!p*87p@8T7e8u]~8p8p8p8ͨp֨8]8l] %3(@(g]p]Ʃ(۩( 3JyVI`]f2q(((IĪ(( "(7(ilI(I]2īҫ(( %(B]G]gr:]8]ɬ֬]ܬ1]3-]68E0xaY(ϭ3]] ]#.aC]:]8®p]]a:Y[(n ۯ]]]] ]")]/;DR:_]h8sp]:]ɰ8԰p] ]'.]4=aQ(\Y o]]]]òʲ]вײ]ݲ: ]8!p?]GSa:n]w8p]]ʳճܳ]a( _Yg '],]9]D]Uah]nu]{:pε]Ե۵]:]8p<C]IP]Vbo:p]a̶(׶Y$ ]])]4]EQX]^e]kw:fp:̸]ո8޸p]:(]18:p]d]jq]w:fpʹ]йٹa(LYT {:]8pͻ:ڻ]8p]):>SGpi:v]8p:ż]μ8׼p:]8&pH:]Sfp]:]8½p:Sp ]&2?:L]U8^p:Sp]¾˾a(Y$ sess]]] :#],85pXaau(((( Y (S_]]:]8p:]'80pSZ]`ia(Y g3]@LY:f]o8xp:]8p] ]a1(<dYl Li*(9M(Xf(r(((( (Tks(( 6L`q( 5P'(  ^q(p ]8'],189>1F( :6Q](%4Ypakppu8]81  '1F<Vp(p-28<]AF8NS1[( I%I:<Og<w pp %8/]498AF1N(( n13 3<)<6DISI[mps~(((p$ET]Yp^5k(~ ((( (n>jp]vLOhH<P^d<pp8] 81!6p>HpMR8\]af8pu1}pp8]81p p8]$)8161AV(i w]:-@]w< pp %8/]498AF1Qgo z     !( :AMBoxI(II)(:(K(\(m(I(@ ((I(CIZIbjII(((((8]@((/(B S(p((((((((*(D(Y((((y$CzYm\]'()*)r!8,Yi'y]]^]^ ]^]%^2]9^?&Yf]nupz8(:+,D`s]{p8]1](Z8~]p]/]l ]#(80A(n( (((6(Q(l(( ((*(*y]]^]^]!^+p2^<]C^I&V(k((((((( X+i|/y]]^]^]^p^#]*^0&=(P ](r((((((8!@pFN&[(n 7;!:.p78DpM8Z]c8p]y8p8l]8(?]$)7(EJ]Q]b@'' y.]4?]I^S]\^mt]{^]^]^&y]]^]^ ]^%],^3]:^@&|y]]^]^]^]^&( ("(7(L(a(v( y]]^]^]^ ]^&](r(((((((:(yy] _p^)3]:^BGU(f(w((((] !]&+<<F7B]_]^((<7QC((  ! 0(I(b({((('DE#F+=]FV^`]g^v^]^&]^]^& y]'].^8]A^NX]a^k]r^|]^&(((((  ((4(I(^(s((((((((&(;(>]@d]j}"<G((]p$ (F(Y ft(I+^7^LZZ(g(( (W^c^m]~:]8p]:]8 pCLa`(ky((Y((  k^w^]:]8p]:"]+84pW`at(((Y((=(P ^^]: ]8pBI]OXe:r]{8pa(((jYx((  ^ ^! ]2 > L :Y ]b 8m p  ]   : ] 8 p  a ( - (: ( Y ( (  [ ^g ^q ]   : ] 8 p  ]   : ] 8$ pG P ad (o } ( ( Y (- (@    I I I I ( I g((0(A(R(v< E(K.(N(n(K1X(m((  (($<= K(\(gh(]p p%s{ (( (I]2"I*752C(O]Bk(r(j((E (($(IE[(v((7]6(A P(e(z(((G G]( E+n6W]E((( %(OqUij s:B/jIPe]n88]8(Bs-tC[Ri(]88p8t#P4(J]S8m}]8]l](O1OP ](z(](r( B1j<]BM(]]( P`z~<~pp8]81 @Pzv<|~pp8]81   . 6 D T zv <| ~  p  p  8 ]  8  1!!! *!N!S!j!~!z!!!!p!!]!"8 "]""8"""1*"I"pQ"["]`"e"8o"]t"y"8""1""<"~""p""p##8#]##8!#&#1.#>#F# Q#Y# d#l# z#####z###z$<$~/$V$<\$~o$$p$$p$$$]$$1$$p$$p$% %]%%1"%5%=% H%P% m%%%z%%z%% &&>&V&<\&~o&&<&~&&p&&]&&8']' '8''1$'9'pD'N']S'X'8b']g'l'8v'{'1''p''p''']''1''p'(p( ((](#(1,(A(I( V(^( k(s( (( (((((C)?a))]))])^))^)])^*^*]"*^2*^C*(W*(k*(*(*(*(*y*y*y+]+ +]'+^4+;+^H+]O+^d+^q+]x+^++]+^++]+^++(,(,(),(=,(Q,(e,(y,(,(,(,(,(,(!-M&-.---I- .NM.(u...N..N.].///($/)/]0/2^N2[2]b2^o2pv2^|2&222222 3y3]$323]93^F3]M3^]3j3]q3^~3]3^3]3^3&3y3]33]3^3]4^4#4]*4^74p>4^K4]R4^X4&|4y4]44]4^4]4^44]4^4p4^5] 5^5&(5<6(6(6(6(7(27(M7(r77(7(7(7(7(8(;8(d8u8(8(8 8y8]88]8^9]9^9$9]+9^89]?9^E9&d9yw9]}99]9^9]9^99]9^9]9^9&9:():(D:(_:(z:(:(:(:0;U;;V);(D;(_;(z;(;(;(;(;(<(<(7<(R<(m<(<(<(<(<(<(=(*=(E=(=(=(=(=(>( >(n>y>]>>]>^>]>^>>]>^>p>^>&?y.?]6?D?]K?^X?]a?^s??]?^?]?^?&?(?(?(@(!@(<@(W@(@( A((A(CA(^A(yA(A(A(A(B(B(9B(B(B(B(B(&C(AC(\C(wC(C(C(C(C(NDWeDD]DD]DD]DD]DD]DDDpEE8EeE<wEEEE<E FFMF<_F|FFFF FF FUFFVFWFUGGVGU$G,GV3GW?GW|GfGVG]G8G8G]G8G8G]G8G(H(DHaH]iHpHpuHzHH]HH8H]H8H8H]HHHI0 I I(JI]PIWI]_IrII]III(I(II]IJJ( J(DJSJ]YJjJxJ(J(J]J]JJ]JJJ(J(KRK]"K6KDK(UK(nK}K]KKK(K(KWK8K(4LAL]NL^`L^nL(LLVL]L8L8L]L8L(L(L] M^M^'M(=MIMWM(gM]oM8}M(M(M(MqM]MN]NN(N]NN(N(O(;O(aO(O(O(O(O P(P(2P(GP(\P(qP(P(P(P(P(P(Q(Q(0Q(SQ(yQ(Q(Q(Q(Q]QR] R8R80R?R]ERWReR(vR(RRyR]RRR(R(RVRy S]S#S1S(BS(QScSyqS]wSSS(S(S]SS]SSS( T(!TR,T]2TGTUT(fT(|TWT8T]T8T(TTU]U8-U87U]=U8KU(lU(U(U(U(V(*V(gV(|V(V(V V(V(V(V(W(W(>W(SW(kW(W(W(W]WWpWW]W8X8X5XyCX]IXXXfX(wX(XVXyX]XXX(X(XYy&Y],Y;YOY(`Y(tY]zYY]YYY(Y(YY]YZZ("Z(FZRSZ]YZhZvZ(Z(ZZyZ]ZZZ(Z([W'[85[(J[]P[_[]e[w[[([([][[ \2\]8\8H\8O\]U\c\(\(](=](g](](](](] ](](^(+^(@^(Y^(n^(^(^(^(^(^(_(4_(S_(_I__ __]______]` `;&`<0`<:`=`>`<`<`>`<`<`?`?`?`7>a@Pa6da(qa>|aala)a(aa?a?a?a6b(b7 b8)b</b<;b<Ab<qb=ybAb(b(cQc(-c(Cc Wc({c=cAc<c(c9c<cB d]dd=dXdd1d3dId( e7e3WeIne(e(ee(ffpf_#f&=fWfqff<fIf(f)gAg(Wg0_g kg]pgpug5g0g(g(g]gpg5gg(#hCh'Ph([hhHhh(h 1i:Ii8Wigiili]iipii(j}/jJjZjcjjqjj8j]jj]jj]jkIk^kjk]sk8k8k]k8k8k(k(l#l 4lJl(^l(sl(llllllll\mm,m:m(Gm(gm(m(m m(m]m]m]mm:n]'n;4ncn(nn|n(n]n>nYn(o Lq(|q(q q>rr r(Fr(rrr0r r(rrGsG,s:9spBs8OspXs8es]ns8ss]s8s]s8ss]s8s]t8"t2tp;t8HtpQt8^t]gt8qt]{t]t;tt>t:tpttpu#u1u]:uDu]Mumu{u]uuu]uupuupuupuupv v]v]v;(v0v>wv]vv]vv]vv]vv]ww] w0w>Ow qw>ww7ww]w6ww]wx;x:Hx]Qx8Yx7jx8wxpx8x]x]x]xDx]x;xx>x(y(yWyY_y py>~y(y]yyyy(z(z %z9zEzSz^z]kzsz#zzz]zzzz]z{-{N{^{{{p{{#{{{{]{ |^u||| }}$})}]1}?}^}}^/~=~D~K~]S~~~v~O)o3Fg^ %^n#,^xpv9N]V]pbgn]t}1]1]Ƀ^QY a~p(̄]ф]] %(1 Q`x(Ʌpхۅ]8]81)p1;]@E8O]TY8af1n  † Ԇ/bIp]Çȇ8҇]ׇ܇81 p ]%*84]9>8FK1Sq   Ј(l( (U(h u(҉III:R(e r(IЊIߊI (/ <({IIINjً( (>ISIbI( (3?IWIcIrI(Ie(ɍ(ڍ(((&5C(Rqpy]8]81ݎII((Ǐ(܏( ($ D(d(}((]Ԑ(] 7]=X(k II((ב((   4E\:m1{l((( ((=({a I5g7 ##$2$|$w$x$Rg&vY) 008[9"<8>=`q8t8!u1x7!#ii:)p/;B]MZ]cp|]]l &&\&`&&&(','   '(% '( 5>,.(<T,.(<T`%(3Kdp B l)762D(\v<((( (()(=H(U`(u((5?(M 6(7)8=<";(<5<<=><<><<???7@6-(8>Jl^8l(<=A ( 9 <B  $(,048<@DHLPTX\`dhlptx|  $(,048<@DHLPTX\`dhlptx|]]] ] ] ] ] ] ] ] ] ] ] ] ] ]$ ]( ], ]0 ]4 ]8 ]< ] p 6(#7)81E()E%'2(=Tb(lu I7&2@(JS 7(-n:2C4^(hq ;<$<.=><<><<???72@D6X(_>(m???6(78$<*<6<U<i=nA](Q 9*<0B@=FAN W<;<$<.=><<><<???72@C6Z(_>tum???6(7"8+<1<=<\<p=uA]v"9/<5BE=KAS b<|uQ v:"1-lj :&}1ln I45(?H '9]AKpPU8_pdi8q  )p1;p@E8O]TY8af1n 1p9C]HM8W]\a8in1v 9pAK]PU8_]di8qv1~ ';]CMpRW8fk8w]}88]p8p8   '3(@(T_(l(( '3(@(Kdo(|(( )7'L(Y(d|(( )7'L(Y(dp(( I#])22Ui]q{p88]88(]p8p8!D]k(u~ (](I07;2IW(d(|((( ](I07;2IW(d(|((( x ]1:]@_KY(f(v]((( ]$x9yExS]Y_eIo]u2]^((((((&(7(T_(s~((((((3p(z(((((((  !(+yp"_0>(K(do({((  9pAKpPU8_]di8qv1~ )IpQ[p`e8o]ty81 ].I8]>2Gj~]p88]88((]#p(-87p<A8It(( ($|*v2]9]JV]\_hIr]x2I]2(((((('(3>(KV(cn({(((((( (!* L(V!|'V/]6]GS]Y_eIo]u2I]2(((((((+6(CN([f(s~(((((((" D(N*|3xC]T`pf_rI|]2I]2(((( ((;vK]\g({(((((#(-8(BM(W` s(}((:'l68D(\le7r2(<(Y(# .(7:*758NlW7d2r(2<(Y( :(8AlJ7W2e(<(Y( :*758NlW7d2r(2<(Y( :!0:lC7P2^(<(Y( :*758NlW7d2r(2<(Y( :%768OlX7e2s(]8<(Y( :*758NlW7d2r(2<(Y( :*758NlW7d2r(2<(Y( :*758NlW7d2r(2<(Y( ;<<=.>4<@<V>[<a<{???7@6 (>3SA;K<X=><<><<?? ?7^@o6(>Sll]]!5:E]N8\p}]]a(((?#?-?76?(X7^8c<i<x<~<<=A???6(78<<%<4<:<j=rA<=%A- 6<X=^ApQx 9<BY((Q39@<FB%;+<8<B=><<><<?? ?7W@h6(>S;<=)>.<4<Q>V<\<|???7@6( >4SIl^lk]]:]8p]$]*3>aU(du((???6(78<<<<<:=BAU?_?i?s6{(78<<<<<=AWgw<=A Y(!/(<KQ]Qe |9<B=A<9<B+IpQ[]`e8o]ty81 ,BpJT]Y^8h]mr8z1( (+9 c]p8]81]81] )]4>pCH8R]W\8fk1w]}81]81]  6]8/>]D8V]\8f]l8u1]8]8]8]8]8]86]<8V]\8v]|8]8]8P]_ 8(*(:]@8U][8d1yP]88(8]8&(0;(F S(]  $(,048<@DHLPTX\`dhlptx|  $(,048<@DHLPTX\`dhlp]82F]L8^]d8n]t8}1]8]8]8]8]8]86]<8V]\8v]|8]8]8P]_8(/(?]E8Z]`8i1P]88(8]8.(8C(N [(e  $(,048<@DHLPTX\`dhlptx|  $(,048<@DHLPTX\`dhlp]8$0]68V]\8e1]8P]88(( ()EY<7Q<.Y<718y@]FQ]X^b]i^y]^]^&(((( (!(+6(?H 18y@]FQ]X^b]i^y]^]^&(((( (!(+6(?H 1DyL]R]]d^n]u^]^]^&(((( ("-(7B(KT 1DyL]R]]d^n]u^]^]^&(((( ("-(7B(KT Y<7Y<7:%768Ely]8 Y<70M2OC(NYQQZQQS+QC<WIlT<UVW Y&Y<pDNpSX8`jZo[u\] ;<$<.=><<><<???77@E6Y(^>u}m???6(78<<<<<+=0AOe<=A Q 9<B8K^w,nQQQQXQQQ?`^`}``` `*`p$k?lWm`((1<AG(v #)<AGZ_ex}AHH,17JOUHhms]v(]] ]"0F(PY 3L=BK(v $)1DIQdiqA H$)1HDIQdiqH]v( ]$]*<]BQg(qz {&{<pDNpSX8`j|o[u\] z><D~Vypp8]81 %(3(ICIt(<IIJI~(U$V/(9B XUpVWU(UVWW 9LA FT(`-f-(-L--I-- (:xBf-ky( (  AJ O](h-n-(---I--(0u8Mf-kx( &(4XF<L,Ip$p).5];D1Ll<W  UV~U9(W(W U9().WDULVW(afWo vW ~U9(W(W U 9!(+0WHUPV[(ejWs zW ~U9(W(W U9().WDULVW(afWo vW ~U9(W(W U 9!(+0WHUPV[(ejWs zW 9IaI(<MIII( ?UV( U VW#U4(>MUX`VeWqW4IIIXI((UVW 0IEITIuIII0BP(](j(|<III+G(T(h(r(( U'/V8UTfUr (( W#(-8(BQU*I9I^(hsUVW (I7ISI_I(()<EIVIzII((v~ ( (U( U!)V2UGbWq({UVWU ! *]/J8]=BJGP]UJ\]a]fkKy~ ]K ]]KAA  ]J]$L)2]7L=E]JJOX]]Lci]n]sK} ]J (  ]GK  ]J$*]/4<AFK TX(]bgl u---0- y   Y[{[    $(,048<@     { z$(,~048<@   ! $(,048<"@  ) * $(,048<@     -.-2 5>.-4 6.- A Z- .|  !(/*=PWdt})5@KQo *1NUry !(Ge} '.KRjq)5Kf'4Tiu   % 7 B M X ^ g m             5 < Y _ w ~          ! 8 ? V ] t {         * 1 J Q j q           ) 0 R Y l s |     =] )0On !(@G_f$AHk;Bip")PWy LSz#*GNpw 7>jq,3_f*1\c/6NU| 'NUw~ 'IPry"IPry"DKmt"IP!DJWu|    # - 9 L Y y          ! !!%!1!>!P![!f!q!w!!!!!!!!!!! ""'"-"N"U"r"x"""""""""##3#:#Q#X#o#v######### $'$C$J$c$j$$$$$$$$$% %#%*%B%I%k%r%%%%%%%&1&V&v&&&&&&&'#'*'B'I'h'''''''''(("(:(A(Y(`(x((((((((()))6)=)Z)a))))))) **0*7*T*[*********++;+B+i+p+++++++ ,,2,9,e,l,,,,,,,--<-C-`-g-------".).P.W.......//E/L/x//////00C0J0u0|0000000 11)101H1O1g1n11111112292@2g2n22222223393@3b3i3333333 4444;4b4i4444444 5545;5]5d55555556646;6b6i6666666666666677777#7*71797A7H7O7V7_7k7q7w7}7777777777777777788828K8W8d8k888888889'9C9Q9m9{999999999::":0:>:m:::;;@;a;g;;;;;;;;;;<"<?<E<b<k<t<z<<<<<<<===8=>=P=d=j=|=========>>">->A>L>`>k>>>>>>>>>> ??!?:?I?R?k?z????????? @"@(@?@E@a@g@@@@@@@@@@AAA(A2ADAPA\A{AAAAAAAAAABB1B7BSBYBuB{BBBBBBBBCC/C5CLCRCnCtCCCCCCCCCDD:DAD_DhDDDDDDDDDDEE3ESEjEsE}EEEEEEEEEFF*F?FGFbFmFyFFFFFFFFFFFFF GG#G)G]|/6NUsz>a~ 8?X_sy29MTrx.4QW'1AIU`kv(3>HTgy5>IYew $/5LRio /5RXz+7CYz%,DKj$<C[b%,Kn&-ELel&?FZa";A^d'=Xp|#:N[o|%1?LYfx%=D\c| ")AH`g!5<PWkr (/CJ^e&-NUqx?Fl $+CJi#;BZay 3:RYv}$+IPdk<C`g #.9DYsy +1RX~ *1HOfm .5[`jv&2>JVb&-ELk%>Egn =Dah9@]v #.9COZepz +6ALVbmx 29U\ 1;GPZmt +2G]nz )4?IUdm(1JP]f&<MYdj}#/:@S\g})2=Sdp{):FQWjs~%6L]s)2=Sdz 6_ 6_'=Nduz(/LSpy%9I]| /8AUenw +:Ihw /GTn%GRfq0;]h|#.BMo4NYmxFU^w.=Qap*:IYcl & 6 E U _ h             7 G V f p y           & / M ] l |      5 E T d n w           $ - F V e u        %5DT^g 6FUeox %.GV_x9IR[o!*Hp!1:S{,<E^m| &5>WgpyEThx GW`i*:C\l7GPw%5a&DT]v /8Qaj?O{.7@^nw:IRk{  ( 8 A J ^ n w       !!)!2!;!O!V!c!l!u!!!!!!!!!! ""#"0"9"W"]"j"s""""""""#&#6#?#]#m#v#########$ $$%$+$;$A$N$W$u${$$$$$$$$$$$$%% %'%.%5%<%C%J%Q%X%_%d%o%{%%%%%%%%%%%&&&+&8&E&R&_&l&y&&&&&&&&&&&''')':'E'Q']'|''''''((A(\(x((((()")M)h)~)))))*;*[*v*****++9+t++++++++++++,.,M,l,,,,,-.-N-m-----..1.7.O.V.n.t........//./A/U/m////////// 0$0<0T0g0{000000001 11$101<1R1m1111111112 282>2\2b22222222233$3A3G3d3j333333333 4,474B4M4X4b4o4}4444444445545;5X5_5w5~555555566+626O6V6n6w66666666667747;7S7Z7w7~77777778 8&8-8J8Q8n8u8888888888888999$9.9:9E9P9[9f9p9|99999999: :':-:J:P:r:x:::::::;;;(;.;F;L;e;k;;;;;;;;;;;<<<&<2<><T<o<<<<<<<<<="=:=@=^=d=========> >&>C>I>f>l>>>>>>>>>"?.?9?D?O?Z?e?k???????????@@)@5@J@n@x@@@@@@@@@ AA+A2AJAQAnAuAAAAAAAABB$BABHBeBlBBBBBBBBBBBC C8C?CWC^CvC}CCCCCCCDD%D,DIDPDmDtDDDDDDDDDDD E!ERIRTR_RjRuR{RRRRRRRRRRSS$S9S]SgStSSSSSSSSSTT'T.TFTMTjTqTTTTTTTTTU U=UDUaUhUUUUUUUUUUUUV,V2VOVUVrVxVVVVVVVWW.W:WEWPW[WfWqWwWWWWWWWWWWXX X5XYXcXpX~XXXXXXXXXYY5Y_b_l_y________```&`>`E`b`i`````````aa5aeEe]ede|eeeeeeeeff+f2fOfVfsfzffffffffff g"g>gEg]gdg|ggggggggh h&h-hJhQhnhuhhhhhhhhhi ii$i0iFiai|iiiiiiiijj,j2jPjVj~jjjjjjjjjjjkkk1k7kJkPkdkpkkkkkkkkkll5lx\xbxzxxxxxxxxxyyy-y3yLyRyfylyyyyyyyyyzzz)z6zCzPzgzzzzzzzzz{ {#{*{G{N{k{r{{{{{{{{||#|-|:|H|U|b|o|||||||||}#}*}B}I}f}m}}}}}}}}}~!~9~B~e~q~}~~~~~~~~~"?Egm(3>D\b{ǀ̀&0=KXerāˁ &-ELipՂ܂$<EOYeq}҃39[aDŽ/5NThn 'A[ktņΆ(<LUiyÇӇ܇ -6JZcwˆ҈ۈ,5IYbvщډ+4HXauϊߊ2>G\w*6BNZfr~ƌҌތ&3M^it̍׍ +6ALWbnzǎҎގ &2?JVbnz̏ۏSMXn)2LZc}ǒВݒ".:FēГܓ $0<HT`l~ȔՔ ,=N_pȕՕ"Ɩߖ&?F^e !<Cbo}Ϙ֘,Hcj֙+6Q_zښ7>V]vʛЛ  &@F`f֜ܜ1LgmȝΝ"(BHflƞޞ%=C[ayӟٟ %1VqƠӠ&2?Yu|ӡڡ07OVszȢ֢ $6BOiģˣ !(@G_fˤؤ =Dhvѥإ,CTago|֦5;\b§ɧ٧&2?LvͨӨ $+ESZlzҩ٩!(D[v}Ϫ!(BO\x٫0KRwլܬ29QXqʭܭ/Fah~Ǯ,3KRlsïʯ>Egn 4;biα۱9U\uDz%?KWcoɳϳ*6BNZfr~ƴҴ &BIfµ̵ӵ *7DQ^v϶ݶ*7DQ^kxƷӷ!.<KYuոܸ3:RYqxιչ +2JQipƺͺ -4LSkrɻл 'JQipļ˼ 9@]dxսܽ29MTlsȾܾ5<PWkrĿ˿ -IPh ,3Rr;W^v}:GTp(CJk|(5C[h,HOgn@MZv.IPq;B_f<CW^y 29[b 29[bHU[agn{ 29Vp -4Ln{ ")<CVqx%2GT[ox .5Sep$EKlr Jk5MZs.OVw $Egn8?W^w~5<Xp}1>[b/6ah /6ah")OVip07PWkr2JQgn9@bi /6]d7\s:BXn4J`v !;Od{(1F]t,B\{.EXdm(4=FNZg0\y#6=RYipu|&,?FOVjqz(/GNl $KRel 29RYmt *1ELnt*ASZsz@Gip")6JYbv|39BK_ez%+ELYbqx!(JQsz$+8AQls| '@GXm$.4<AGQ[akq{ #-3=CMS]cms} ".;HUbo| "=X^{ %+Dk.U{ 1XBi,Sz=d'Nu8_"Ip<B\ht %1=IU39QWou  + 1 J P m s         $ + C J b i           D l        = d k     0 X     &Ks !(/:ALS^e{1DK_f #*BIc6=U\t{3:W^u|29PWjq '4AN[w~18P!+6X_|*1JQnu&-@[bx /6]d*1SZ|'8EKYjv #=CYju '4AN[hu&-ELdk  % = D \ c {         !!$!>!>'>->4>@>L>_>k>q>w>}>>>>>>>>>>>>>?? ????&?-?4?;?B?I?Q?Y?a?i?s?~?????????}G,I>IKIhIIIIIIJZJyJJJJJJKK;KEKPKcKKKKKKKKLCLMLrL|LLLLLLLM'M1MPMZMgMMMMMMNCNMNlNvNNNNNO=OJOOONPXPoPyPPPPCQMQ\QQQQQRRR;RERTRxRRRRR"S4SASSSSSSTATKTeToTTTTTT U&U@UZUtUUUUUUU V)VHVgVVVVVVVWW;WUWtW~WWWWWW X$X>XXXrX|XXXXXYY.YpYYYYYYY ZZ(Z@Z]ZwZZZZZZ[[?[Y[s[[[[[[\8\B\e\o\\\\\\])]C]M]j]]]]]]^B^^^^_(_2_L_f_____` `,`K`e``````aaa"a/aQa}aaaa b#b=bWbqbbbbbc ccc*cXc}cccc d0d9dBdLdYd{ddddd+eEe_eyeeeef7fcfmfffffggKgUggggggh3h=hmhwhhhhhh(i2i?ioiiii3j_jjjjjj k*kDkckkkkkkkkl/lNlmlwlllllm$m>mXmsm|mmmmmnBndnnnnnoAoyooooop pJpdpppp q&q@qXqeqqqqqqqr#r0r=rSr`rrrrrrs6sNs[sssssst1tPtotttttttuHuguuuuuvv$vVvpvvvvvvvvw;wmwwwwwwwx6xUx_xxxxxy.yHycylyvyyyyyyzKzezzzzzzzz+{4{I{X{{{{{{ |/|I|_|n||||||}.}D}}}}}~V~|~~~~1G(Nm)?ǁ)Hc AKlŃ?eڄOzЅم.8Ԇ_~Ӈ%DNku҈+QgЉډ",Vs}"FPj܋7isÌ݌>Hō΍؍Pj̎Cnݏ *6M`lO\kxّ )6^xŒ.8ZcmzГ"<Ӕ2>dn˕Օ =ۖ #BLXoӗ(\eo|^hřϙۙ7A[e˚ޚ/Idmw˛؛&CLVcҜܜEenx#akȞҞޞ:Y)Tˠ #áݡ%?YsGQãڣ (NhrҤ%Dڥ)@JVmw)K`i~Ч0fp̨֨@Jdnک9ZoxĪЪܪ +8[hӫݫ$-7COkݬ=s}խ (Gݮ%;So¯uϰ&HRhOYxβ.gϳ"A״9C]gɵ;Ѷ۶3Mg7Qk׸9COkuǹԹ%=Wan3d~ '4APis¼߼:߽ )3KU^hu̾־߾ \{1;Gcm#0=Z#FPhr{ =y)3KU^hu \{ .;HWpz0=Jg 5OYq{'1>Kh1\{(1;HUr*I3=Zd%2?Ngq8R"1JTlv5 #-6@MZik*?HR^jx+Mg)7A:CLVc0qi .7@JWdq)FPu+CL_ly(E_ )6Xajt7@JW~%DNZv ,U_lDenx%C][5f)`j(g>`F<bR&C`z )KUoy 6Pj.HRt$.HT =G*| r-C`v#xU*iO5PjtV8BO",8DRjsEOYf1Ke*BKUam -6?IVcp 3=]g(B\v'?]z '1Np'DNpz 7 A ^ x          & G Q n        " A     , 6 X     ? Y s   /9Sr":CVcp1Kr/IS~'3@MZx,AJTa1;[ep;l!.;Jc$1>V_iuAJS]jw )3@g'DQ^(6NWjw&3Pj-JWds )3?Kbku   ' 4 A N k t ~        !#!0!?!X!u!!!!!!!!"&"3"K"T"^"j"v""""""""""##6#?#H#R#_#l#y########$$"$/$V$`$$$$$$$$%.%;%H%W%p%%%%%%%%&1&>&K&c&l&v&&&&&&&&&&&'','N'W'`'j'w''''''''''((:(O(X(b(o((((()()7)S))))))=*q******* ++1+ E+K+ `+ t+|++ ++++++ , ,:,I,M,z,,,,,,, --F- Z-z-"--$--&-.(*.J.*^.~.,.....0./2./W/4k//6///8///0*0<0P0a0000000000 1+191?1M1W1h1~11111111 2222C2c2q2w222222;23=-3M3?a33A33333 444!464:4C\4`4E44G44I44K44M5M.525OO5Oh5l5Q5Q55S5S55U5U66W76WP6T6Yq6Y66[6[667 7+7F7P7m7w77777777777788858;8O8j888888888 99999C9R9f9999_9_99a9a9:a :a::E:[:i:s:w::::::::::;;;!;G;];k;u;y;;;;;;;;;;<<<#<I<_<m<w<{<<<<<<<<<< ==!=%=K=Y=c=i=w==========> >>%>3>7>]>k>u>{>>>>>>>>>>???-?7?E?I?o?}?????????@@+@5@9@F@P@^@b@@@@@@@@@@@AA-A3AAAKA`AjA{AAAAAAAAAAAABBB(BaHaLaYacagataaaaaaaaaaaab,bKb`bfbqbbbbbbbbbbbcc#c8cBc_cgcccccccccccd dd#d-dHd_dydddddddddd eee9eOeXejeneeeeeeeeeeef#f-f3fKfjffffffffffg#gEg_gcgwgwggwgwggwggwghhhw1h7hwBhwQhwUhfhphwthhhwhhhhwhwhhhhwhiiw&i1iw5iBiLiRiwfiwuiwiiwiiiwiwjwjj!jw5jw?jwYjxjjjjjjjjjkkkk/k9k?kNkRkekqk~kkkkkl ll%l1l5lFlPlZl^lolylllllllll mm-m7mNmXmomymmmmmmmmmmmmnnnn0n;n?nLnVn\ntnxnnnnnnnnnnnnoo%o6o@oFouooooooooo pp!p9pGp]pgpkpwpppppppppppppppqq&q0q4qEqPqTqaqkqqqqqqqqqqqrrr#r6r@rWrarkrrrrrrrrrrrrrsss$s(s5s?sEs]snsxsssssssss ttt,t6t:tGtQtYtit}ttttttttttttuuuu,u=uJu[uju~uuuuuuuuuuuuvvv/v@vOvcvtvxvvvvvvvvvvvvwww,w=wLw`wqwuwwwwwwwwwwwww xx4xNxbxjxtxxxxxxxxxxxxyyyy'y-y7yEyIyjyyyyyz"z&zGzKz\zfzzzzzzzzzzzz{{1{;{G{[{e{|{{{{{{{{{{||(|,|>|I|O|^|r||||||||||||||| }}}*}.}>}H}N}]}{}}}}}}}~#~-~3~K~i~~~~~~~!9Ww  *4NXr|ŀπӀ &59ISYh|΁ҁ4?CPZ`x|ǂтׂ "-1>HNfjzŃ݃,6<TXhr˄ $*B`ׅ0Nnņ8Xisyȇ҇/JP[eȈ,Tfz͉׉ +9CGT^koŠي )7=IYcz]ȋՋ'-:@KUjtzԌ '1AUkuǍэ/9?JT^rŽӎݎ)6:KUYjuȏ/=GKaerxȐ̐ݐ&6:KU_cpzÑ3=G\g|ߒ+:DYcnʓԓޓ )-LP]gqwƔ 3HRcoǕ͕4>Shrϖٖݖ *48EQUfqu—ݗ#-8SlpΘ.?IOcnǙљ]#8BHW[n]y]ǚ0Kfƛ̛֛ &0?Ch|Мܜ !)/>Bc|ȝם۝ #'HY_osϞ ,=CSgxğ՟۟/3TswĠʠܠ 2CGTZhrס0:\`¢բ&4>jУԣ~~ ~(3~7DNT~l~p~~Ťˤ~~~~!.8>~W[|̥֥ܥ$/3@JPimϦ.?^bƧ֧ܧ '1FPVakuɨݨ0:AGRXcixЩک +6GQboʪߪ)3=GQ[es߫2<GX^lvz¬Ƭ֬!+;V\fpz̭߭;K[euЮԮ1<MW]q}ǯѯۯ (=HYci}ΰذް *.;EKcgxбڱ /AK`k|Ѳܲ"1Qaqwų$9CM^hrȴ޴],9=hlĵȵ /?Rs¶Ҷֶ&FV`vz׷:Rblv̸ָ '1BLRbrĹ޹5TXy}Ǻ !+>RZ`qwͻٻ"&3=GK\bm}]]Ǽͼټ*:X\lv˽ս۽ #'8CGT^d}̾־ܾ%9FPZdx~ĿԿ޿&7AG[apt *4ITeou  !04EOY]isy 1;?KUYjuy#)BWaq{";?OUeiy(48HRXgk{$9DU_ey#->HN^r|$.4HOau+5;F[lr}.2CMQbm~,@MWk*48ITXeou!6@PZoz!'<FPZdo *?EP[mw '-EIYdx 4:IM]gk|7;KU[bt~$<PZoz/9CT2;Eg+/<FLZdj{.>NT_epv 7AVfv]'?[lv| -7=Q\gv *:DJXhr|)?IO]s} &9IXy}] 2<PZ`k] /M`t~ $5DHXbl1;APTdnt'1;PVas} &*;EOSdjy}BV`pzKUdh-7Ax6@DU[fj{%/9=MS^nx ",6:FPV`is}  *.?J[ev +5?TZep"&6@J_ep{ '-<@Q]nr~ )37GQ[pv &0=\v99%+9<9L9akq999999 99/9?9P9`9du{99999 9$95?H9R9o99 %06AGeiz&*:@OScmw )39Qak .2CMSdht~ ,0AGVZkuy"/DNcn*4AEV`fw{+/?IShr-Ggx )/@DPZ`qu #26GQUfqu "7AQ[lv !28G\fl%59JTXdnr>N^hs}%/9NT_jz*KU_jy] ]"(9=NX^rx (26GQUblp})/>BS]amw{,6KVgqw " C M X g w           ' + 8 B H \ |              < @ M W ] q            & * ; E K \ ` l v |              ! 2 ; L P a k o {               %):DJWgk| (8BS]j %+CXbr|6@JT^i  1;EI`fuy &0GQ^sy *4EO`ix| "->HNfz)/:@^s}  *0AEQ[arv)/@DU_evz#-3@PTeou "3=CTXdnt .2CMQ]gkx -?IYct~$5?E]r|"/?CT^dq $*7GK\fly    , A G V Z k u y           !!!$!6!@!P!Z!k!u!!!!!!!!!!"")"3"D"N"W"a"g"q"|"""""""""""### #&#3#C#G#X#b#h#u#############$ $$$.$2$C$M$S$d$h$t$~$$$$$$$$$$$$$%%%%+%5%9%F%P%]%r%x%%%%%%%%%%%%% &&'&1&B&L&U&g&q&&&&&&&&&&' ''+'@'J'Z'd'u'''''''''''("(,(6(U(_(i((((((((((( )))))3)7)N)T)c)g)~)))))))))))***6*@*M*b*h*o*y************+ ++'+1+A+K+[+v++++++++++++,,",&,7,=,L,P,a,k,o,,,,,,,,,,,,,---$-?-I-M-d-o-s-----------..4.>.B.S.Y.d.h.y...........//&/0/:/>/N/T/_/o/y////////////0 000-030B0F0W0a0e0v0000000000000111151?1C1Z1e1i1|1111111111122!2?2C2[2e2i2z222222222222233+373;3L3V3`3d3t3z333333333333 444)43474C4M4S4]4g4k4x4444444444444445 5!5%565@5J5N5Z5d5j5t555555555555556 66'6+686B6H6a6q6w66666666667777!7+7=7M7]7{7777777777777 88 8$8;8A8P8g8s8w888888888888 99$9+959;9F9J9[9e9o9s9999999999999999 :::(:.:8:B:H:]:a:r:|::::::::::::: ;;&;0;A;K;U;[;i;s;;;;;;;;;;<<<"<0<:<K<U<_<o<y<<<<<<<<<<<<<===$=/=3=@=J=P=i=y========= >>>>)>8>X>h>>>>>>>>>>? ? ?*?0?E?I?U?_?e?v?z????????????@@@'@1@7@H@]@g@m@@@@@@@@@@@@@A AA3A=ACAXA\AhArAxAAAAAAAAAA BBB,BGBMBbBfBrB|BBBBBBBBBBBBBBCCC0C4C@CJCTCiCsCCCCCCCCCCCCC DD D$D5D?DCDTD_DpDzDDDDDDDDDD EE E1E7EFEJE[EeEiEuEEEEEEEEEEEEFF#F3FCFMF]FpFzF~FFFFFFFFFFFFFGGG$G9G?GJGUGeGkG{GGGGGGGGGGGGGHH H*H0HAHEHVHbHsHwHHHHHHHHHHHIII.I2I>IHINI_IcItI~IIIIIIIIIIII JJJ'J1J7JOJSJdJjJyJ}JJJJJJJJJJJK,KAKKK`KkK|KKKKKKKKKKLL"L.L2LCLILXL\LmLwL{LLLLLLLLLLLM MM!M:M>M_McMsM}MMMMMMMMMMMMN NN!N%NONSNdNnNNNNNNNNNN OO,OWHWLWXWbWfWsW}WWWWWWWWWWXX&X0X:XKXUXbXfXwXXXXXXXXXXXXXYYYY!Y5YFY[YeYuYYYYYYYYYYZ ZZ&Z7ZAZJZTZ_ZZZZZZZZZ [[[6[B[W[b[f[w[[[[[[[[[[[\%\6\:\K\U\_\t\z\\\\\\\\\\] ]]#]']8]B]F]W]b]f]s]}]]]]]]]]]^^&^7^A^G^[^e^t^^^^^^^^^^___)_2_=_K_U_f_l_y____________ ```%`/`3`C`I`X`\`l`v```````````aaa!a%a2agNgXgmgxg|gggggggghhh'h6h:h\hthhhhhhhhhii#i)i=iDiSibikiti~iiiiiiiiijj&j0jGjQj]jrjyjjjjjjjjjjj kk-k8k>k\k`kqk{kkkkkkkkkkkkklll$l/lAlKl`lkl|lllllllllllllm m$m9mCmXmcmtm~mmmmmmmmmmmmnnn#n-n3nEnInZndnjn|nnnnnnnnn oo(o3oDoNoTohonoxoooooooooooppp'p1p;pPpZpkpuppppppppppppppq7qXqiqsqyqqqqqqqqqqqqqrrr+r5r;rTrdrjrvrrrrrrrrrs sss$s3sCsNsTs_spsvsssssssssssst tt't8tAtRtVtgtqtuttttttttttttu uuu-uLulu}uuuuuuuuuuv vv#v'v4v=vWvgvwvvvvvvvvvvvv www3w=wNwXwiwrwwwwwwwwwwwwwx:xKxUx[xoxyxxxxxxxxxxxyyy/y9yJyTyeynyyyyyyyyyyyyyz6zGzQzWzkzuzzzzzzzzzzzz{ {{!{.{L{f{{{{{{{{{{| || |4|>|D|S|g|q|w||||||||||} }}}3}=}C}R}f}p}v}}}}}}}}}}} ~~~(~2~G~Q~b~l~}~~~~~~~~~~~~~  *?JN[ek-AK`k|Àۀ'=]HNYhwʁ]с܁]'28MWlrʂԂڂ *=]HNeo݃ !+1<FaƄۄ]"-7W[҅&6TXpz~Ɇ͆)MQblvżև $5?IM^hnx|ˆƈӈ݈!2;W[lvЉ *0EKZ^ouŠƊ֊!:JP\`wʋ΋ۋ.>NbwČȌٌ$<Q[p{ɍӍ,Kk|Ȏ׎+@Q[ev̏Џݏ$9DU_e}͐אݐ4EOUis}đՑ] 5]@FQ_jpʒΒߒ#.Ddw]ԓ(2<FJ[ekv)39H_]jp{ϕӕ  ]tȖ̖ݖ 28GKbhw×Ǘחݗ#0EKR\bmqŘɘ֘ *4ISdnÙǙؙ *4>BR\bt~ȚΚܚ *4EQUblrƛЛڛ2?ETXio~Мڜޜ 4DJVZq{ĝȝ՝۝(8H\qžӞݞ6KUjuß͟&Eev Ѡ&0GQYmw{ǡޡ "=VZku{΢ע &*7AG_ct~ף '17Odnäͤפ'17KU`oΥޥ %)5?CPZgʦަ $;]FL`uѧէ +Ect~èǨب 1;?P[_lv|ȩө !+@K\flʪԪ'8BS`duث(28LVo]vѬެ4?R[it~ҭح]#'8BFSYi~ծ] $1;AY]nxѯ!+1IhǰѰ۰"9L`jpʱб߱ (2?]wʲײ  &5JTZim~óɳ 1;AU_is}ʹڴ '+<GKXbhеڵ ,7HRXpʶж]",7K_lʷз߷]0:>KQav͸]ٸݸ )39QUfptɹ޹ $(9DHU_e}úغ޺]"3>BOY_w{һܻ *?FQ^hs}üؼ޼] %):EIV`f~νؽ޽#4>BOUeizžݾ-7=Ujt˿տ߿0?HQ[k{ 5>GQ^ly0=AQ[am0:OZku{/9NY]jtz $8BHSgq#4>D\pz&7BLPako%=AR\q|-1BLalp}!2<Q\`mw} ",ALP]gm1<@MW]uy !,0=GMeiz -7=Ujt (.G\f{ 9NXmx +@J_j{2<Q\mw}$.CN_io 5@Q[az'2CMShr|/?N]l{+59JUYfpv,0@JNZdhy 59ISYhl|!.8>VZjt &,DXbw 2FPep 4>S^oy+5JUfpv#8CT^d| !+5@\l| %5?IZdj|#.?IOew1Rcms 04EOU`r|'17B]| 59JTitx %):DHYdhu*4ITeou$9DU_ey=KUYvz(=CN^s}!+@FQ_isw !+/@KO\fl5BUt!15BLVZjt{%/7NX\mw:U[oz(2BS^h} %/DN_iz$.8BLV`jt~"9pFUjv *ApN]r~$.E]Rav(2I]VezCQ[_pz~'8BS\ko'<HWlx0<K`l{(4CXbhw%CWdt~ %+<@Waeu &7;GQWhl} "&2<F[ev ",AK\hl} &*;EKXhl} "&2<F[ev0Pq &*;AThrx /9?P`dtz!2<EUYjtz   ) 3 H R c m ~                $ 5 9 E O U f j {              % ) : D H Y d h u            * 4 I T e o {                $ 5 9 E O Y n x            $9CIZjn%6@QZko!+7LVkv-1BLP]gm} $.?IVZku"/DNcn&Dcmw 5;JN_i~":\2AEfj{ '+<FJ[fjw2Rcms $.2?IM^h} )>IMZdj5FPVkx #'8BW]lp#'4>D\{ *0ES]w] ] & 1 C M b m ~             !!!!2!?!C!T!`!o!s!!!!!!!!!!! """+"/"@"P"e"o""""""""""#####-#7#A#K#[#_#p#z##########$$#$-$3$G$V$j$w$$$$$$$$$$%%%%-%7%A%V%\%g%r%~%%%%%%%%%%%%%& &&*&.&?&I&M&^&i&m&z&&&&&&&&&&''9'Y'j't'z''''''''' ((((5(9(J(T(Z(j(n((((((((((((()))#)')8)C)G)T)^)d)|)))))))))))) **(*3*D*N*T*l*********++/+3+D+N+R+_+i+m+z+++++++++++,,,,%,4,8,I,S,W,h,s,w,,,,,,,,,,,,,- -$-9-D-Y-c-x-------- ...0.:.N.b.o.........../ //-/1/B/L/R/b/f/w/////////000$0.040C0G0X0b0f0w00000000000000 1113171H1R1V1g1r1v11111111111112 2#2'282B2F2W2b2f2s2}222222222222233(32363G3R3V3c3m3s33333333333344"474B4S4]4c4{44444444455'525C5M5S5k555555555566"636=6C6[6p6z66666666677#7-737K7`7j777777777777788.8D8X8\8m8w8}888888888888999#9'989C9G9T9^9d9|999999999:3:D:N:T:h:r:|:::::::::;;%;p2;A;V;b;m;w;;;;;;;;;;;<<,<6<F<O<^<b<<<<<<<<p<<<===%=/=9=E=T=X=y=}=========p== >>">,>6>@>J>W>a>p>>>>>>>>>>>>??$?0?;?E?O?Y?c?p?z??????????@@@@&@0@E@Q@`@u@@@@@@@@@@@@@@A AA*A6AEAZAfAqA{AAAAAAAAAAAABB%B)B6BKYKcKmKKKKKKKKKKKKKL LL&L*L7LALGL_LpLzLLLLLLLLL MMM(M>MHMRMhMrMxMMMMMMMMNN N$N0N:N>NJNTNXNhNrNvNNNNNNNNNNNNN O OO$O*OBORO\OqO|OOOOOOOOOO P P*P4PJPTPZPnPrPPPPPPpPPPPPQQQ$Q0Q?QSQmQqQQQQQQQQQQQQ]QRR(R2R8RCRUR_RtRRRRRRRRRRRRRRSS)S3SDSQSUSfSrSSSSSSSSSSS T TT(T.T=TATRTbTwTTTTTTTTTT UU!U+U5U?UIUSU]UmUqUUUUUUUUUUUVV V1V;VAV[V_VpVzVVVVVVVVVVWW#W-W3WGWMWaWqW|WWWWWWWWWWWXXX,X6XGXQXbXlX}XXXXXXXXXXXXYY Y1Y:YKYOY`YjYpYYYYYYYYYYYYYYZZ!Z1Z5ZLZVZZZjZtZ~ZZZZZZZZZZZZ[[[ [*[.[;[E[R[V[g[q[[[[[[[[[[[ \\$\*\B\a\{\\\\\\\\]"]3]=]A]R]]]a]n]x]~]]]]]]]]]]]]^#^-^B^M^^^h^n^^^^^^^^__$_:_I_f_j____________``` `$`1`;`A`Y`x````````a aa+a;aKa[aeayaapaaaaapaaaaa bbb'b1b;bPbVbablb|bbbbbbbbbbbbb cc'c+c7cAcGcXc\cmcycccccccccccccd d!d'd2d=dMdSdcdgdxdddddddddddddeee)e-e>eJe[e_ekeue{eeeeeeeeeeeeff!f%f1f;fAfRfVfgfsfffffffffffffggg0g:g>gOgZg^gkgug{ggggggggggg h h*h:hDhUh_hlhhhhhhhhhhii#i4i>iDi\iqi{iiiiiiiiiiijj!j5jJjTjZjnjjjjjjjjjjjjjjk k"k&k7kAkVkakekrk|kkkkkkkkkkkkkl'l1lFlQlblllrlllllllllmm!m6mAmRm\mbmvm|mmmmmmmmmmm nnn"n3n=nRn]nannnxn~nnnnnnnnnn oo o*o.o?oJo[oeokoooooooooopp/p:pKpUp[popupppppppqqq%q/q5q@qDqUq_qequqyqqqqqqqqqrr"r&r7rArGrWr[rlrvr|rrrrrrrrrrrrrs ss!s's?sCsTs^sbsss~sssssssssssssttt/t3tDtNtRtctntrtttttttttttttuuu#u4u>uBuSu^ubuouyuuuuuuuuuuv$v.vCvNv_vivovvvvvvvvvvww3w>wOwYw_wwwwwwwwwwwxx#x.x?xIxOxcxmxwxxxxxxxxxyyy%y/y5y@yDyUy_yeyuyyyyyyyyyyyzz"z&z7zAzGzWz[zlzvz|zzzzzzzzzzzzz{ {{!{'{?{C{T{^{b{s{~{{{{{{{{{{{{{|||/|3|D|N|R|c|n|r|||||||||||||}}}#}4}>}B}S}^}b}o}y}}}}}}}}}}~$~.~C~N~_~i~o~~~~~~~~~~3>OY_w#.?IOcmwӀ$.2?IMZ`r|ρՁ*4:EWav‚Ƃׂ '37HRXgk|ǃ߃"/9?W[lvzτӄ)/GK\fj{Åԅޅ7LVkvĆΆ '<F[fwӇއ,6KVgqwÈΈ߈ !59cgxщ׉#->HYbquʊЊ"3=C^bs}ƋЋ +1<KO`jnÌ،.NioˍՍ,6GQZdsĎΎԎ(=CN\fptƏ׏ۏ*?IZfj{ĐȐِ$<Q[r|Ǒؑ*4DN_ivВڒ 1;ARVblvzʓۓߓ.CM^jnȔ̔ݔ "(@U_v˕ܕ .8HRcmzԖޖ)->HN_s~ȗ֗#-4@QUfpzØԘ $/>BS]ar}˙ՙ!6AR\bvȚٚ)JThÛɛ֛$*9NXiuyĜӜל#-3K`j˝֝ $9CS]nxߞ7;eizʟԟޟ&*7AK_ip|ˠѠ 1;EZ`kz~ʡԡڡ(2>S]r}ˢ,Keң -7`jnĤΤԤ'+7AK`j{ťϥե$48OUbrvæͦѦ'17HLXbhy}Ƨۧ(,=GKX^n¨ϨӨ)/GK\`mwȩΩݩ (2?CTXeoyʪΪߪ 15FPT`jn{˫ܫ'8>Ncm}Ĭά #)3=GQ[eoyɭԭ .2CMW[kuʮήڮ$9?Ncm~ȯίٯ '+8BH`u˰  *9NXhrӱ&JTkzƲֲ $.2?IO_tųֳ  $0:@QUfptѴ %):DNRcmsʵԵص +5EO`js}ƶʶ׶ *.;EK_pŷҷ(2<FPZdnxĸԸ;K[kv|˹ֹܹ '28LPakuѺۺ+5?PZgk|ƻʻֻ &04AKXmwμҼ -1=GM^bs}Խ޽ &59JTXeosȾӾ׾.?ISdn{ǿѿۿ !+5?ITm} ,<} $8<MWaey!+<FSWhr|%/3?IMZdq%/5FJV`fw{",5?NRisw &04AKXw  *.?I^imz&0AGS]gq{ )9Ix ,6AGRXhx%6@MQhrv -7APTeoy}*4AV`pz&06GK\fjv"9CGXbfr| $(9CGT^boy.8BS]j$/HXhx HRpt ,2=KU_cpz .8IUYjt~ +@Jakw#3=NXe@DU_ev&:DKWhl}  5;FUYjtx .8MXisy&@ak%/Xb &1;P[p]#/9?PTeos'<T^v(26BLP]gt .4EIU_evz!+4>MQblvz '1>S]mw#-3DHYcgs} 0:DHYciz~ !+;EV`is#-1=GKXbo#-3DHT^duy *3=LPakuy",9NXhr(.?CT^bnx|+5?CZ`qu"<]gvz %/5IZoy 5BVZku{ (2<PZam~ ",6KQ\ko#/DNcn<Vw !2<I^oy $*;?PZ^jtx$.2?IMZdnr'26CMSk"3=C[pz)3=GQ[eoy,=GQbly}#48DNTeiz#-<@Q[eiz  -Lf3>BOY_s  AKbr +/CMerv!%1;?LVcx!'8<HRXim~$.=AR\`mw{!6@QWcmw!1AQu0<MW]w    - 7 A E V \ g k |              ( 2 < @ P V a q {                ) / 9 F J [ e k z ~               " & = C R i u y              & - 7 = H L ] g q u             '1>BS]gk| "/DN^hy#8CGT^dx!6AER\b{1AGSnx"&6@DU`dq{*;AMbl} !+@K\fl%5EUe.CGXblp $(5?E[_p{%):@KO`jtx  $4:EU_v *.?IO^bs} !'6MY]nx !,0AKUYeou "&7AKO`jp(2BL]gpz  ' + 8 B H \ m q            !!%!)!6!@!F!_!c!t!~!!!!!!!!!!!!!!"%"+"7"R"\"w"""""""""""""# ##$#(#9#D#H#U#_#e#~#########$$$%$1$F$P$a$g$w$$$$$$$$$$$%%$%/%@%J%P%e%o%y%%%%%%%%%%%%%% &&)&9&I&c&m&y&&&&&&&&&] ''-'9'D'N'X'b'l'w'''''''''(((2(>(M(b(n(y((((((((((())),)<)F)P)T)`)j)n)z))))))))))))**/*9*?*M*c*m*w*********+++-+=+O+_+i+y++++++++++,.,<,J,`,j,t,,,,,,,,,-"---7-;-L-V-]-k-v-|---------. ..#.3.H.T.c.x.......... //'/>>#>7>A>G>V>j>t>z>>>>>>>>>>? ??$?3?7?G?Q?U?f?q?u????????????@ @!@5@?@E@T@h@r@@@@@@@@@@ AA$A,A6AEAIAYAcAiAsA}AAAAAAAAAAAAB BB$B*B9B=BMB]BrB|BBBBBBBBBBBBCCC7CKCUCjCuCCCCCCCCCCDD,D5DZDdDnDxDD]DDDDD]DDDD]E EE.E8E>EMEQEcE]nEtEEEEEEEEEEE FFF(F,F=FHFYFcFiFFFFFFFFGG&G5GaGGGGGGGG HHH&H0H6HJHgHqHHHHHHHHHHHHHII(I,I9ICIII]ImIqIIIIIIIIIIIIIJ JJ%J5J9JJJTJiJtJxJJJJJJJJJJJJJK K%K)K:K@KOKSKdKjKyKKKKKKKKKKKLL%L0LALKLQLeLoLyLLLLLL MM1M;MLMRM\MmMqMMMMMMMMMMMMNN%N+N?NTN^NoNyNNNNNNNNNNNOO&O0O4OAOKOUOYOjOtOOOOOOOOOOOO PPP)P3P9PQPfPpPPPPPPPPPPP QQ#Q8QBQSQ]QsQ}QQQQQQQQQQQ RRR4R>RBRSR^RbRoRyRRRRRRRRR7SASPSTSuSSSSSSSSSSST*T4TQT[T_TlTvTTTTTTTTTTTTTUUUU)U-U>UHU\UbUqUuUUUUUUUUUUUVV"V3V=VCVXVhVlV}VVVVVVVVVVVW WW%W1WFWPWaWsWWWWWWWWWWWXX(X>XHXNXbXsX}XXXXXXXXXX YYY1YFYPYaYkYYYYYYYYYYYZZ"Z3Z=ZSZ]ZcZqZZZZZZZZZZ[[%[/[5[C[Y[c[m[[[[[[[[[[[[\\*\?\K\V\`\j\t\~\\\\\\\\\\\\\] ]]+]@]J]Z]d]y]]]]]]]]]]^^^,^B^L^V^l^v^|^^^^^^^^^^__(_>_H_N_b_w___________`` `4`I`O`^`s`~``````````````a a(a2aLaVaeaiaaaaaaaaaaabbb2b>bIbSb]bgbqb}bbbbbbbbbbcc$c(cmcqcccccccccccccdd*d6dAdKdUd_didyddddddddddee$e9eCeTe^ene{eeeeeeeeeeeef f"f,f2f@fVf`fjfffffffffffgg(g2gy ByUy_yiysy wyyyyyyy yyyyy yyyzz zz)z3z=z AzNzXzbzhzrz|z zzzzzzz z zzzz {  { {*{4{>{ B{O{Y{c{i{s{}{ {{{{{ {{{{{ {{{{|  ||#|-|3|=|G| K|X|b|l|r|||| | |||| | |||} }}&},} P}|}}}}}}}}}}~~%~/~?~I~S~[~j~~~~~~~~~~~~~8ERa  .8BL \fp|  ƀЀڀ ހ *4>DNT e o| ʁ  )= AXc gx  ȂԂ   )3=I Mdnx  ȃ҃܃ $ (4>HR Vcmw  Ąфۄ  /9CM Qdnx  Ņхۅ   !.8BL P]gqw Ɔ ߆    (2<F V`jp ҇܇*K_gmwĈ͈ވ"&7AKUYjt~ωى  5?T_pz̊׊ 'BMQblpËԋߋ-7LWhrxnjьٌ,6@DQ[ezčՍٍ %/5MQblŎڎ%=R\q|ŏϏُ(,9CMblv *4IS]gwΑܑ &0:>KU_t~̒>HZ^Ó͓ؓ'1FRavŔɔ/;J_kvŕϕӕ.COZdnx–̖ܖ/=R\mwėΗҗޗ %5BWar|ʘԘߘ )>HSWhrvǙ֙  *;LVgqĚΚޚ#)BWar|Ǜқ ",2@V`jÜԜޜ(2<R\bvƝН֝$.4DNXblvܞ  ,;P\gq{ßɟ؟ܟ !5;EPbr|֠AA &59JT^r|ѡס+5;Shn|բߢ*4DN_mqƣУԣ%):DHT^bs~ͤפۤ",2KO`jåǥإ -7=VZkuΦҦ&*;EIU_tΧا  #'8CGT^d}ͨרݨ &04EPakqǩѩ &,;PZkuêͪת &06JP_ct~ɫӫ٫!+@KO\flĬȬլ߬ ,6KVZgqwĭϭ *5FPVnǮخ 5@Q[ayǯү !+;EZevΰذ 2GQakűڱ%=R\lvв *6KUeoʳ߳#4>DYkuʴܴ 1;AVhrǵ͵ӵݵ'-7=DSgxƶ׶*>OZiyƷ۷ !2<BMWakzʸ׸(2CNXt~ùιع!6AR\b{˺պۺ (3DNTmǻͻ%6@F_t~ؼ (28Qfpƽнڽ+@JUYjt~ɾҾ 1;AYnxƿۿ-7AV`q{2<Q\mw}&6KUfp&0EPakq %)5?IM^ev  *5JTZi~&0:DNXblv+5;J_i~#<Q[p{.CMbm~ 5?T_pz"(2<FPZdoz#4>D]r| &06Odn"(AV`u 3HRgr,6=Hbl{*4:Rgq $*BWav 2GQfq (.8BLV`l{*4:Rgq $*BWav 2GQfq (.8BLV`l{ )4EOUm$5?E]r| %/5Mbl%9CIS]gq{0:OZku{  *?J[ek/:KU[s *;EK_ioy&7Fe4:JZjz(2?OZdh|pp04@JPaeu -1AKQbfr|0:JTeox%/3DOS`jp (28Pap+5@Q`du!:OYny ,AK`k|3=R]nx~%/DO`jp 3=H]gr *;EKdy-7=Vku)/H]g|!5?ISYcms}.;K[k{ '+<FJWcgx +/@J_jn{0:OZ^ku{  *?J[eq ",6@DQ[eos/:>KU[s (26CMWaer|*4ITeou$9DU_e} )4EOUm$5?EYcmw +1;FPeo#)BWav 4IShs &;EZev(28BLV`jt *5FPVn%6@F^s} &06Ncm &>S]r}.CMbm~   3 = R ] n x ~                 * 5 O S y                 ) 3 = M W a i w        ]     - 9 = N Y ] n x |               ! + 1 I ^ h r           0:OZku{-Kq(2<HLYcmw{  1;HSYdju  $/3DPZjz 0:DNReoy "/9CMQ^hrx0:DNR_isy)3=CMW[hr|",6<` #-7?N_{'=GR\q{ !.8BHR\`mw #-7Yl )>HR\lv %/9=IS]gkw(.8>W[r|(26BLV`dq{  " 3 = G M [ k u            !!!"!2!"K"i""""""""#?#R# f#s#~##### #### #$ $$ $'$1$;$E$ I$V$`$j$t$ x$$$$$$$ $$$$$$$ $  %%!%'%2%8%C%M% Q%d%z%%% % %% %%% &&&(& 8&H& X&b&n& & &&&& &&&& &&'''  '3'='G'Q' U'b'l'v'|''' ''''' ''''' ''((( (,(6(@(F(P(Z( ^(k(u((((( ( ((((( (()))  )-)7)A)G)Q)[) _)k)u))) ))))) ))))) ))* ***%* )*6*@*J*P*Z*`* y* **** * **** **+ + #+"7+D+N+c+s+}+"++"++"+++"+,,,"(,2,<,D,"Y,$m,,,,$,,,,$,,,$ ---$5-?-E-$V-$m-w-$--$---$---$-$- ..%.2.W.&k....&...&...../&//%///&@/J/T/&e/o/u/&////&///&//&//&00$0*0&90&=0R0i0&~0000&000&000&00 11&1)131&D1N1&_1l1&p1111&1&111&11&2 2)2\2222(233*343(83I3S3Y3c3m3w333(333(33333(3334(444$4.484H4R4(g4q4(u444(444(4444(4(445((525<5F5(W5a5k5(|555(5555(5555(5(56'6(86>6(O6(p6{6(66666666(6667(77&7(77A7G7(U7_7o7y7(}777(777(777(777(8 8(8)8(-8D8N8T8(c8(g8|88(8888(88(888(999%9(/9(@9(D9\9(`9w999(9(9(9(9(:( :(:(#:(3:(7:P:X:(l:*{::::*:::*::*:*;* ;*;* ;**;*9;,P;`;~;,;;;,;;;,;,;;;;,;<<,#<,'<><D<,S<,j<v<,z<<<<,<<<,<,<<,<< =,!='=,.=,8=,>=,I=,M=^=h=r=,v=====,====,====,==>>>, >3>9>J>,N>Z>d>j>,>,>>>,>,>>>,>>>,>>?, ??'?,+?8?B?H?,a?,q?w?,?,???,???,???,?@@,@,@,!@,5@E@U@e@u@@@@@@@@@@@@@AAAA)A-A>AHALA]AhAlAyAAAAAAAAAAAABB.B?BIBSBdBnB{BBBBBBBBBC2CCCMCSCgCqCCCCCCCCCDDD)D6D:DKDUD_DcDpDvDDDDDDDDDDDEE"E,E9E=ENEXEbEfEwEEEEEEEEEEEEEEFFFF*F?FIFYFcFtF~FFFFFFFFFFFFFGGGG0G4GEGOGSG_GiGmGzGGGGGGGGGGGH HH&H*H7HAHEHRH\HfHjH{HHHHHHHHHHHI II*I.I;IEIKIcIxIIIIIIIIII JJ!J6J@JDJUJ`JdJqJ{JJJJJJJJJJ KK!K+K5K?KIKSKbKrKKKKKKKKKKKKL LL%L/L3L@LFLVLkL|LLLLLLLLLLLLMMMM'M1M7MHMLM]MgMkMwMMMMMMMMMMMMNNN#N4N>NHNLN]NgNmN~NNNNNNNNNNNNNNOO/OIOjOtOOOOOOOOOOOOOOPP!P%P2PRBRORYR_RwRRRRRRRRRRR SSS'S1S@SPS`SpSSSSSSSSSSSSST TTT$T4TITZTdTnTTTTTTTTTTTTTTUUU&U*U;UEUIUUU_UcUpUzUUUUUUUUUUUVVV&V*V;VEVKV\V`VlVvV|VVVVVVVVVVVV W'WHWRWaWeWvWWWWWWWWWWWWWWXXX X4XEXIXZXdXyXXXXXXXXXXX YYY5YJY[YeYoYYYYYYYYYYYZZZ Z-Z7Z=ZUZjZtZZZZZZZZZZZZ[[[.[>[N[^[r[v[[[[[[[[[[[[[[\\'\8\B\L\]\g\t\x\\\\\\\\\\\\\]]]#]']3]=]A]N]X]e]z]]]]]]]]]]]]^^^#^)^:^>^J^T^Z^k^o^^^^^^^^^^^_&_0_?_C_T_^_b_o_y_}_____________`#`'`8`B`W`b`f`s`}``````````a(a9aCaMa^ahauaaaaaaaaaaaa bbb3bHbRbgbrbbbbbbbbbbbbb cc,cn.On.cnnn.nnn.nnn.nnn.n.o o.o%o/o.?oIoSo.donoto.oooo0ooooppp(p2p06pHpUpap0epuppp0pppp0pp0pp0pq0q q*q0q0Aq0EqUq_qiq0mqyqqq0qq0qq0qq0qr rr0!r0%r5r?rIr0MrYrcrmr0rr0rr0rr0rrrr0s0ss)s09sCsMs0bsls0}ss0ss0ssss0s0st0tt03t>t0BtRt\tft0jtvttt0tt0tt0tt0ttu u0u02u=u0Qu[ueu0uuuu0uu0uu0uu0uuv v0v0!v1v;vEv0IvUv_viv0mv~vv0vvv0vvv0vvv0vv0 ww0*w4w>wDw0Uw0ew|wwww2wwwwwwx xx2x*x7xCx2]xgx2wxxx2x2xx2xxx2x2yy2y)y/y2?y2Yycy2sy}yy2y2yy2yyy2y2yz2 z*z2:zDzJz2Zz2nzyz2zz2zzz2z2zzz2{ {2{.{7{A{N{[{s{}{{{{{{{{!|B|V|c|s||||||||||||}}}!}%}2}D}Y}c}t}}}}}}}}}}}}}}~ ~~&~,~7~;~K~U~_~c~o~y~~~~~~~~~~~~~~~8Ss!-1AKO[eiv׀ #0:OZ^ku{ŁρӁ )>HYcx΂؂ "->HNim~Ãǃԃރ 1<@MW]uyńτՄ(2<BLVjt~ąȅم  0:DL[pzÆ͆׆ 1;LVkvŇχ $*4>DNYc}Èӈ#3CMXbfw‰ډމ*4:RcrvĊΊފ %:EV`q~Nj׋ۋ%04AKQj֌+5;PZdnxčٍ2<Q\mw}ƎՎَ5 #5.>HRXblv5z5ď5ȏ؏5%5:DNT5c5z55Đʐ555'5;K[kuƑʑݑ]] &1=R\my}Ò͒ג$DU_eyēȓՓߓ-9=NX^mΔؔ $.8BFV`jpz~ٕ .8<MX\isyŖɖږ%=R\mwƗЗ !,0=GMeizŘݘ -7=Ujt~ęΙؙܙ#37HR\`mw}̚ݚ'2CMSkś˛"3=C[pzϜ՜ߜ)9CNT_epvÝʝН۝-3>DT_epvŞОԞ.9=JTZrŸ̟ҟ%/:>OYny}ǠѠ &.8CYixqȡܡ",2<@MWagmӢ%2APZ`iuƣ֣ܣ $5?CPZdnt~ˤ%/9MWaguҥܥ#'7AGX\hrx¦Φئ-6GK[ek|˧ϧ&06GKWagtĨШԨ )-=GMYiȩҩة .8>OS_isǪت#-3L\bpz~ūӫ#/3CIX\lv|ɬͬڬ &;?KU[lpĭȭح"-AGVjt~îͮ&:DTZj~ʯޯ",<FWanǰͰ $4>BS^oyұ %/9CNg{˲Ѳ )3=CMQ^hrx~ȳ̳ٳ8ISYt~:̴ܴ.8:MW:hp:::Ƶ:۵:::.:CMS:b:fw::¶:ڶ:::*4::N:r:|:::::::·:̷:ַ::::::::0:::IMoMʸݸ&M*;EMIV^MuMMMɹӹٹMM MM1;AMPMTeoMsMMȺMMM"(M<MFMPMZMdMnMxMMMMMMMMȻMһMܻMMMMM"DfOu~OƼOۼOOOOOO$O>JWdsQʽԽQQ (2QIpVQeQzQQQQQQȾQݾQQQQ7;LVZgquſпԿ%p2AVbmw#6AKO\fjw}p'6KWblv /?NRblvz -7>LVmpz+:>[e %/3@JTXeos !-<Q]hr|(2<@MSak %)6<FPeq (2L[_ (2GRVgqx*9=MWaer|&4:DNXblv.=AR\`mw{%+5?IS]gv "&39CMWav",6IM^dtx(2<FP[ko|-9H]it~ &*PjtSSS*4SITSXeouS -6@LXf,9L`mz  &17DUfw%0EO`j{ %/5JXbw (6@U`dq{3>BOY_u -7=Sak 1?I^imz'<GKXbh~%)6@F\jt$:HRgrv '+<FJ[ekz~'-?CP`dqu -7;MW]gz *.:JPZdx%/5CYcm%6KRbfw(2GRcms !+1EZdn  1>MQblp}(7HW[lv| &,EZdy7LVkv )>H]hy0:OZku}  *;Yi~"3=C]r| '17Qfp %+EZdy %:DYdu.8MXisy ",AL]gs !,=GMg| 1;A[pz %/5Odn#+5?IS]cmw #-7ALZdy.8>Xmw",2Lak &@U_t &0:@JT^hr|$9DU_e-8ISYs !,=GMg| )3=IS^h}!2<B\q{ &06Peo $*DYcx4>HRXblv&;EV`l  % / 5 C Y c m              " , 2 L P a k               - 7 C G X _ n             5 J T i t            # 5 ? T _ p z           %:EV`f|  +<FLbt~",2HZdy.@J_j{&0EPakq +6GQWl~+5;Pbl4FPep #8BWbs}*4ITeou&;FWag-8ISYoy%/9CMSYcis} ,Xakw]$3HRXgk|#-=JN_im $1;EKU_ct~#'4>HNXbfr|   7 ; L V Z m w                 ! !!(!.!8!/B/S/]/a/r/}/////////////000.0C0M0b0m0~000000000000111"131=1R1]1a1n1x1~11111111222#2-212B2M2Q2^2h2n222222222222333!323=3A3N3X3^3v3z3333333333334 44"4-414>4H4N4f4j4{4444444444444555!5.585>5V5Z5k5u5y555555555555 66'616B6K6Z6^6o6y6}666666666667 777%7-737@7J7Z7j7~7777777777 88"8,808<8F8J8W8d8h8y88888888888889 99%9+9:9>9O9_9t9~999999999999 :::*:5:9:F:P:V:n:r:::::::::::;;;0;=;A;R;\;`;q;|;;;;;;;;;;;;;<<<-<1<B<L<R<a<e<v<<<<<<<<<<<<< ===)=3=9=Q=U=f=p===========>>#>)>A>V>`>u>>>>>>>>>> ???1?F?P?e?p???????????@@/@9@N@Y@j@t@z@@@@@@@@@AA%A0AAAKAQAeAoAyAAAAAAAAAAAAAB BBB&B,BDBYBcBxBBBBBBBBBB CC"C7CACVCaCrC|CCCCCCCCCCD(D2DGDRDcDmDyD}DDDDDDDDDDEE%E0EAEKEQEiE~EEEEEEEEEFFF)F/FGF\FfF{FFFFFFFFFFG G%G:GDGYGdGuGGGGGGGGGGHH%H0HAHKHQHeHkHuH{HHHHHHHHHHHHHHHHHHIII:IJIZIjItIIII]IIIIIIIJJJ0J9JHJLJ]JgJkJ|JJJJJJJJJJJJJKKK K8K\B\O\Y\_\w\\\\\\\\\\\] ]]#])]A]E]V]`]d]u]]]]]]]]]]]]^^^"^3^>^B^O^Y^_^y^}^^^^^^^^^^^___'_2_6_C_M_S_k_o_____________````#`4`>`B`S`^`b`o`y````````````aa$a.a2a?aKaOa`ajanaaaaaaaaaaaabbbb#b;b?bPbZb^bobzb~bbbbbbbbbbbccc/c3cDcNcRc_ckcocccccccccccc ddd+d6d:dGdQdWdodsddddddddddddde ee&e*e7eAeGe]ete~eeeeeeeeeeeee ff$f*f8fBfFfSf]fgfqfufffffffffffgg g1g;gLgUgdghgygggggggggggghh,h6hnHn]nhnynnnnnnnnnnoo.o8oMoXoiosooooooooooop ppp'p-p7pApGpQpWp]pgpqpwpppppppppppppppqq8qBqMqSqdquqqqqqqqqqqr rr'r-rtBtSt]tatrt}ttttttttttttt uuu(u3u7uDuNuTulu|uuuuuuuuuuuv vvv#v4v>vBvNvXv\vmvxv|vvvvvvvvvvvw www'w-wGw\wfwvwwwwwwwwww xx)x4xExOxUxoxxxxxxxxxxxy yy y*y4y>yEy_yhyryyyyyyyyzz!z3z[GzTz_zuzzz[zzzzz[zzzzz[z[{{{+{[/{<{F{V{[Z{g{q{}{{{[{{{{{{[{{{{[|[||#|[2|[6|G|Q|[U|f|q|[u||||[|[||[||[|} }[}[%}/}<}G}M}X}^}i}s}[w}}}}}}}[}[}}[~~"~[&~7~C~M~[]~m~[}~~~~[~[~~~~~[~~~[[-=G[K^nx[|[[ [[28[B[N[X[b[v[z[€̀܀[ ['1;AKU[isy[[[[[ȁ[ҁ[[ [%/5[C[S]g[w[[[̂ւ܂[[ [.[JT[pv[[[ǃу׃[[[['[CM[io[[[Ƅ[ք[[![7[A[K[U[`[˅܅]%,;PZkuԆކ(1?IM^hr|ćˇև )3=MWago~Έ؈ވ )->HR\qx̉։+/@J_jn{Š׊0:OZku{Njˋ؋ &*:DJT`dpzҌ܌ *48DNR^h}ƍ׍+5?U_euĎюێ#8BMblwʏԏޏ)3=AMW]gkwԐߐ.8NX^lБ *0H]gk|’̒֒6@DU_ct~Гԓ)/G_}͔"/3DJ]gq^ɕԕڕ^^#^'8B^FWb^fs}^^^іۖ^^ &^4^DNX^\hr^v^^Ǘ͗^^ $.^CMWa^q{^^^^֘^^^9^Y^jtz^^^™^љ^^^ ^^0:^OZ^ku{^^^^šҚ`-A`EVb i`x`|``țқ؛```&0`4GQ[`_ku{``Ü`ǜӜݜ```9LV`Zku``̝֝ܝ````'2`6CMS`k```Ş˞`ߞ``$*`9`J`Y`nt```Οޟb+b/;EbIU_bcpzbbb .7AMYgydơѡۡdߡd$d(5?IdM^h{ddȢd̢ޢddd+d;PdTrdvdƣУڣdޣ d.8dNTd`dt~ddddddҤܤddd&0:dPZ`dq{ddddddȥdӥdݥddddd%/;GSdxŦզ8MQfptҧ %)6<LPakvѨۨ#0<OY]nx|ũ˩ܩ "&DHYciz~ʪЪ$5?PYjnѫի !+@J[evĬϬ'<GXbh|ȭ̭ݭ%/9MWlwĮή #)3>S]nz~ʯԯگ",0=CTXio~ȰҰ߰!%6@FW[gq{Ʊϱ )9CT^gyIJز 8LYmqdzͳ$(5?E]r|մ%/5IS]gq{˵ϵ"&3=R]nxƶж (26CMW[lv˷ܷ &0=R\msĸո߸ 8MWlw¹ѹ+/@JT^b}ɺӺ׺,6<MQ]gm~Żֻڻ(>OSdnt˼ռۼ !2<BW[gqwȽҽֽ)3CM^hqþǾ޾ 04GK]nrſϿտ ):DU^os%5JTdn#-BM^hn 1AQeiz!+/;EKUYeoy} &<FLZpz2PV`f.=AR\`mw{ (3=AR\`mw{!26BLRcgx #'8DUYeou"(3BFWctx '-AGRaev'+<HY]isy $5?HR\fp .8>K[_pz 04EOUioz $5AN^bs-9FVku (2<HYmz "2<FJWamq 4:EUYiu.BL\fw  +/<FL`q*4ITeou(<@Q[_p{(.8BVfmsfffff.8f<MXfisyfffffff-f7fAfPfTeofsffffff f+6fGQWfkftf~fffffff(3BLVgr|hh%h4h8IS]dwhhhhhh-8hISYhmhwhhhhhhhh,<hFhPh_ht~hhhhhhhhh(h2h<hUms} ,7H[k%4kKQalrkkkkk k+6kGQWkokkkkkk kkk.k2CMkQbmk~kkkkkk k%/5kIkRk\kfkkkkkk )>HSWhsw?JYj} -CQ]v6AOU_is}-3CGXbfsy%/@FX\ix %)6@LPakq{*4EO`s+/<HYl| &-7AQUflvn '-AnRnanevnnnn&n;EnZenvnnnnnnnn$n5?EnYinsn}nnnnnn nnnAnKnUn_nin /FRgq| ",2=GWnu +5JVez /9=JT^bnx)37DJT^s  *GQei%>GQ]iwppp,6@JpZdjpwp{pppp$.8p<IS_ispppppp!p%6@pDQ[p_p{ppppp  p & , pB L Y d j u {   p       p p  p 4 ? pC T ` j pz  p    p p     p     ' p+ 7 A G pT pX o   p    p      p    % / pC S pc o p{ p  p p p p p p    p % / ? pC P Z f p z p~      p  p  p p  $ p. p: pD pN pb p}   p   p p   p  p   p( 2 pG R pc m s p p  p p  p  p  p; E O p_ i o py p p  p p  p  p p4 > pT ^ pn x p  p  p   p p p p p p3 T h u                / D P [ e o y               " , 6 @ P Z d n ~                5 A L V ` j t            ) - e |             # - 3 B F W a e v                  % / 5 N c m ~         ! 2 < B V ` k   r          r " , 6 r: F P Z rn x r  r   r r  r  r  * 0 rD rJ rP r\ rp z  r r   r  r r r r r   & 3 R v   t     t # - 7 A tE Q [ e o ts    t  t  t   t  t ( t= H tY c i t} t t t t    t  t  t   t6 tJ T ti t t   t t t t t    t   " t3 = G M t[ e tv    t  t   t    t t  $ t3 tC M S ti tm ~   t    t t    t t    t( t, = G tK [ e ti z  t    t t   t  t     t5 t9 E O td o ts    t t         t   # ) 3 = t_ tp  t   t    t  t    t0 t4 E O Y c tg s }   t    t  t  t   t, t@ J t_ j t{   t t t t t    t    t" / 9 E O U tg tk    t    t      t t 1 ; E tI ] g tk }  t   t   t   t  t    t2 t6 F P te p tt    t t  t  t  ! t"! tC! I! tW! ts! }! t! ! t! t! ! ! ! t! " t$" *" t<" tc" t{" t" t" " t" " " t" t" " t # # t# t!# t+# t5# t?# tI# tT# t^# t}# # # # # # # # $ $ $  $ -$ 7$ A$ E$ V$ `$ j$ t$ x$ $ $ $ $ $ $ $ $ $ $ $ % % % %% =% [% {% % % % % % % % % % % &  & 3& 7& H& R& \& `& q& {& & & & & & & & & & & & & & ' ' 0' :' @' X' v' ' ' ' ' ' ' ' ' ' ' ' (( ,( <( F( P( T( e( o( y( ( ( ( ( ( ( ( ( ( ( ( ( ) ) $) .) 4) L) j) ) ) ) ) ) ) ) ) ) ) * * #* '* 8* B* L* P* \* f* p* t* * * * * * * * * * * * * *  + + (+ 3+ D+ N+ T+ l+ + + + + + + + + + , , #, -, 9, E, W, c, l, , , , v, , , , v, , - - v- "- ,- 6- vK- U- vj- u- v- - - v- v- v- v- - - v- v- . . v". (. v2. v<. vF. vQ. vf. o. y. . . . . . x / / :/ D/ X/ x\/ m/ w/ / / x/ / / / / x/ / / / x/ / x0 0 x-0 70 =0 xQ0 xW0 xd0 xh0 y0 0 0 x0 0 x0 0 x0 0 0 x1 x1 x1 x'1 11 ;1 E1 xV1 `1 j1 t1 x1 1 1 1 x1 1 x1 1 1 1 x1 1 x 2 2 2 x42 >2 D2 xS2 xd2 n2 t2 x2 x2 2 2 2 x2 2 2 2 x2 x2 2 3 3 x3 x3 -3 73 x;3 L3 V3 xZ3 k3 v3 xz3 3 3 3 x3 x3 3 3 x3 3 x3 3 4  4 x 4 x'4 14 >4 I4 O4 Z4 `4 k4 u4 xy4 4 4 4 4 4 4 x4 x4 4 x5 5 $5 x(5 95 E5 O5 x_5 o5 x5 5 5 5 x5 x5 5 5 5 5 x5 5 5 6  6 x6 6 &6 06 xE6 O6 xd6 o6 x6 6 6 x6 x6 x6 x6 6 6 6 6 x6 7 7 7 %7 x)7 67 @7 J7 P7 Z7 d7 xh7 t7 ~7 7 7 7 7 x7 7 7 7 x7 7 7 7 x8  8 x"8 -8 x>8 H8 N8 xb8 xh8 xt8 x8 x8 x8 8 x8 8 8 x8 x8 x8 x 9 x9 (9 89 B9 xF9 Y9 i9 s9 xw9 9 9 9 9 9 x9 x9 9 9 9 x9 :  : x: #: -: x1: =: G: xK: W: a: xe: v: : x: : : : x: x: : x: : : x ; ; x; %; /; 5; xS; xt; z; x; x; ; x; ; x; x < x!< x/< xE< O< xS< _< e< xt< xx< < < < x< < x< < x< x= $= x:= @= xH= xR= x\= xf= xp= xz= x= x= x= = = = = = = > > "> .> :> V> z> > > > > > > > > > > ?  ? ? ? (? .? N DN TN iN sN yN N N N N N N N O &O 0O =O YO mO O O O O O O O O O P P !P +P 1P EP KP VP ZP kP uP yP P P P P P P P P P P P P Q  Q Q (Q ,Q 9Q CQ IQ ^Q hQ rQ xQ Q Q Q Q Q Q R  R R "R 5R @R FR SR cR gR xR ~R R R R R R R R R R R R R  S S S %S +S CS GS XS bS fS wS S S S S S S S S S S T T T 1T ;T KT UT fT pT }T T T T T T T T T  U U )U 4U EU OU UU iU sU zU U U yU yU yU  U yU V V y'V 2V yIV UV bV yfV yV -V yV V -V yV V -V yV yV yV yV yV yV yV yW yW yW y W y*W y0W y:W yDW yNW yXW ybW ylW yvW y|W yW yW yW yW yW yW yW yW yW yW yW W W X X $X 0X BJN]ajnw{ *.6:IMVZcgrv/3<@IMX\eiz~aaa#a37?CJNW[jn  $,07;DHW[os{ ,08<KOX\cg".2CGOSbfnr   )-48TXdhy} $+/8<KO`dsw   ! + / C G P T _ c t x                        / 3 ; ? F J S W ^ b r v }                          ' + 4 8 ? C L P W [ j n u y                 % ) 8 g< gE gI g] ga gj gn gu gy g g g i i i i i i i i i i i i i i i i i i" i& i- i1 iB iF iM iQ i` kd km kq k k k k k k k k k k k k k k k k k k kkkkk(k,k5k9kJkNkWk[kdkhkokskkkkkkkkkkkkkkkkk%m)m0m4mDmHmQmUmimmm|mmmmmmmmmmmmmmmmmmmm mmmm.m2m;m?mHmLmSmWmhmlmsmwmmmmmmmmmmmmm o oo o/o3o:o>oGoKoZo^oeoiorovo}oooooooooooooooooo o o%o)o8o<oToXogkrv} "&-18<CGNRaelpw{]]  $48?COS_cjnz~] ]]'+26?CTX`dtx #'6:A]FJQ]^bimvz $(15<@IM^bkox| *.=AJNUYjn}  $+/AELPW[mqx|'+;?NRZ^fjz~ +/CuGuPuTu]uaujunuuuuuuuuuuuuuuuuuuuuuu uuu&3u7u>uBuQuUueuiuuuuuuuuuuuuuuuuu,08<DHX\dhpt '+;?HLUYmqz~!(,;?GKRVeiz~   # , 0 < @ L P d h o s {                !!!! !$!4!8!@!D!T!X!_!c!k!o!v!z!!!!!!!!!!!!!!!!!""""" "1"5"D"H"O"S"Z"^"f"j"r"v"~""""""""""""""""""####'#+#2#6#E#I#P#]]#a#h#l#s#w###############$$$'$+$@$D$M$Q$Z$^$g$k$|$$$$$$$$$$$$$$$$$$%%%%#%'%6%:%C%G%N%R%c%g%v%wz%w%w%w%w%w%w%w%w%w%w%w%w%w%w%w%w%w%w%w&w &w&w&w(&w,&w5&w9&wB&wF&wW&w[&wd&wh&wq&wu&w~&w&w&w&w&w&w&w&w&w&w&w&w&w&w&w&w'w'w'w'w!'w%'w4'w8'w?'wC'wS'wW'w_'wc'wl'wp'w'w'w'w'w'w'w'w'w'''''''''''(( (((((,(5(9(M(Q(X(\(c(g(w({((((((((((((((()) ))))%)))1)5)=)A)I)M)U)Y)i)m)v)z)))))))))))))))))* ***0*4*C*G*P*T*h*l*s*w******************* ++++%+)+0+4+E+I+R+V+g+k+t+x+++++++++++++++++++, ,,,,",3,7,>,B,Q,U,^,b,k,o,x,|,,,,,,,,,,,,,,,,,,,----%-)-2-6-J-N-U-Y-i-m-|-------------------- . ...+./.8.<.E.I.P.T.].a.h.l.}..................////"/&///3/2B2R2V2_2c2w2{222222222222222223333$3(30343E3I3R3V3e3i3p3}333333333333333334 444#4*4.464:4K4O4V4c4g4s4w44444444444444455 555(5,565:5N5R5Z5^5m5q5z5~5555555555555556666!6(6,6<6@6I6M6V6Z6e6i6r6v666666666666666667777 7$7-717C7G7N7R7Y7]7e7i7t7x7777777777777777778888#8+8/8?8C8L8P8Y8]8f8j8s8w88888888888888888899 999%9)989<9K9O9`9d9m9q9z9~99999999999999999:::::#:2:6:E:I:Z:^:f:j:r:v:::::::::::::::::::; ;;!;*;.;7;;;B;F;O;S;_;c;r;v;;;;;;;;;;;;;;;;;;;< <<<(<,<;<?<P<T<]<a<j<n<u<y<<<<<<<<<<<<<<<<<= ===="=.=2=A=E=T=X=i=m=t=================>> >>>$>(>7>;>R>V>]>j>n>u>y>>>>>>>>>>A>>>>>>>? ?? ?$?;???F?S?W?`?d?k?o?x?|???????????????@@@@#@'@6@:@C@G@N@R@c@g@v@z@@@@@@@@@@@@@@@@@AAAA#A'A6A:AAAEATAXAaAeAlApAyA}AAAAAAAAAAAAAAAAAAA BBBB#B'B0B4BEBIBPBUBYB`BmBqBxB|BBBBBBBBBBBBBBBBBBCCA CCCA$C(C1C5CR]KROR_RcRjRnRvRzRRRRRRRRRRRRRRRRRRS SSSS)S-S5S9S@SDSKSOS^SbSkSoS~SSSSSSSSSSSSSSST T T T$T+T/TBTFTMTQTdThToTsTTTTTTTTTTTTTTTTTUU UUUU2U6U=UAUKUOUdUhUoUsUUUUUUUUUU~U~U~U~U~U~V~ V~V~"V~+V~/V~6V~:V~CV~GV~NV~RV~[V~_V~fV~jV~{V~V~V~V~V~V~V~V~V~V~V~V~V~V~V~V~V~V~V~W~W~ W~W~!W~(W~,W~;W~?W~HW~LW~]W~aW~jW~nW~wW~{W~W~W~W~W~W~W~WWWWWWWWWWXXXXX X'X+XaEaIaXa\aeaiaravaaaaaaaaaaaaaaaaaaab bbb*b.b7b;bDbHbYb]bfbjbsbwbbbbbbbbbbbbbbbbbcccc*c.c7c;cBcFcWc[cjcncucycccccccccccccccc dddd&d*d2d6d?dCdUdYdjdndvdzddddddddddddddddee eee&e*e1e5eEeIePeTe]eaepete{eeeeeeeeeeeeeeeeeeeef fff#f'f7f;fCfGfVfZfafefufyffffffffffffffffffffgg gggg"g*g.g6g:gIgMgWg[gbgfgxg|ggggggggggggggggggh hh!h%h,h0hlBlIlMlVlZlclglnlrl{llllllllllllllllllllmmmmm!m(m,m5m9mJmNmUmYmbmfmomsmzm~mmmmmmmmmmmmmmmmmmmn nnn*n.n5n9nHnLnUnYnbnfnonsnnnnnnnnnnnnnnnnnnooo o$o+o/o@oDoSoWoholouoyooooooooooooooooooo p ppp p$p,p0p?pCpLpPpWp[pdphpqpup~ppppppppppppppppppppq qqq(q,q5q9q@qDqKqOq^qbqkqoqqqqqqqqqqqqqqqqqqq r rrrr#r*r.r5r9rHrLr[r_rhrlrsrwrrrrrrrrrrrrrrrrrrssss"s.s2s>sBsQsUs\sismsvszsssssssssssssssss ttt"t)t-t5t9t@tDtTtXt_tctstwtttttttttttttttttttuu uu u$u+u/u7u;uBuFuVuZuaueuuuyuuuuuuuuuuuuuuuuuv vv!v*v.v5v9vJvNv]vavhvlvtvxvvvvvvvvvvvvvvvvvvwww&w*w;w?wNwRwcwgwxw|wwwwwwwwwwwwwwwwwwwx xxx&x*x3x7x@xDxKxOxXx\xexixpxtx}xxxxxxxxxxxxxxxxxxxxxy y yyy!y%y-y1yAyEyLyPyYy]yfyjyqyuy~yyyyyyyyyyyyyyyyyy z zzz!z%z.z2z9z=zFzJzSzWz^zbzizmzvzzzzzzzzzzzzzzzzzzzzzz{{{{ {/{3{;{?{G{K{[{_{|{{{{{{{{{{{{{{{{{{|| ||||-|1|@|D|M|Q|b|f|o|s|||||||||||||||||}}}}+}/}@}D}U}Y}h}l}}}}}}}}}}}}}}}}}}~ ~~~-~1~8~<~K~O~_~c~j~n~}~~~~~~~~~~~~~~~~ "15=APTcgnry}   )->BKO`dko~€ƀπӀ '+48?CTX_crvЁԁ %)04CGOSZ^mq]Âӂׂނ]!%-18<LPY]imvzăȃуՃ !15<@HLSWgkrvńԄ؄]]'+;?F]KOV]cgnry}ȅ̅Ӆ]؅܅],07;JN]aquÆʆΆՆن(,8<PT[_fjy}ˇχއ  '+37GK[_fjz~ĈȈو݈!%,09=FJY]dhquljˉ҉։߉ !%-19=FJZ^fjz~NJˊԊ؊,0AELPY]nrz~ϋӋ"*.6:JNVZjnz~]ČȌό]܌ .29>BINRY^binry~čՍٍ -18]=AH]UYbfuy͎юڎގ#,0?CTX_]lpɏ͏ޏ]!]&*1]>BKOX\mq}ŐɐҐ֐ߐ $(7;LPY]nr{999999ȑ9̑9ӑ9ב999999999990949;pH9L9[9_9f]s9w999]99]99]9’9˒9ϒ9ؒ9ܒ99999]99'9+92]79;9B]O9S9b9f9o9s9|999999999ē9̓9Г99999   $+/6:OSZ^fjqu]]]”ƔϔӔܔ $,0@DMQZ^os{ĕȕϕӕڕޕ!%,0?CLPY]nry}ΖҖpp p&*37HLX\kov]{]]җ֗ߗ *.7;DHY]d]imt]y}]˜˘Ϙ$(/3BFW[koʙΙޙ]] ]#'04EIUYhltxÚǚϚӚۚߚ #'.2AELPW[jnuyț̛՛ٛ p#p04=ARVbfuy]]Ü̜Мߜ )-4]9=D]QU^bqu~ȝ̝۝ߝ -1AELPX\dhos{pžƞ͞pڞޞ"&59@EIP]ahluy̟Пܟ !%48@DTX_cjnuy]]ƠʠӠנ!&*1>BIMVZcgvzΡҡۡߡ(,37AELPbfos|΢Ң٢ޢ!*.7;LPaenr{ģȣѣգޣ ,08<KO`dosʤΤפۤ  $59AEUYbfos|ͥѥإܥ  $-18<MQ`duyʦΦզ٦ $(9=DHTXgk{]]]]çǧΧҧ٧ݧ$(15FJQU\`osƨʨѨըި  !%59BFW[dhy}é̩Щ-1@DUYim~êԪت#'.29=FJW[hlswūɫҫ֫ݫ !%-19=EIY]eiy}¬ˬϬܬ !(,59HLUYbfswĭͭѭڭޭ#'6:BFNRbfmq~ǮˮҮ֮!%15AENR[_ptȯ̯ԯد )-:>EIRVcgtxİȰа԰ܰ (,59BFOS\`im~ұֱ߱!%6:CGNRcgvz²ɲͲԲز߲ &*1p6:ApFJQpVZapnry}ųɳгճٳ #'.2AEL]QU\]ael]qu|]ʴδݴ %)04;?FJY]fjy}]]]]ŵ̵е׵۵ %)059@EIP]ahlsw~]Ŷ̶]Ѷնܶ]]-1:>MQX]ahmqx}Ʒʷٷݷ]]]  ]!%,07;BFUYbfuyȸ̸Ӹ׸޸]!%,]15<]AEL]Y]dhosz~ȹ͹ѹعݹ )-4]9=D]IMT]Y]d]qu|źɺкԺۺߺ'+26?CRV^bjnvzƻʻۻ߻ 04DHY]mq¼Ƽ׼ۼpp p&p37>BIMTXgkrw{ŽɽнԽ]]]]+/6:AELP_cjoszȾ̾۾߾]]] ]#'.29=DHW[bgkrw{Ŀӿ׿޿]]]]&*15<@OSZ^eipt!%.2CGPTeirv $(9=LPaeuypppp$(/48?DHO\`gkrv}]]]]  ',07<@GTX_cjnuy]]]]$(/48?DHOTX_lpw{]]]] ")-<@IM\`gkrv} !%.2;?PT]arv&*15FJY]nr 15=AQU_cjnx| (,37?CKOY]dhrv ,0AEOSZ^pt{ "+/@DUY`dnr| '+=AKOY]os}#'9=GK]ako  "&04>BQU]aqu .2:>NR\`gkuy !37RV]a| $(:>HLVZlpz~ &*<@GKZ^hl~ '+59CGY]gkrv(,6:AEOS]ako+/;?IMW[mq %)8<MQZ^osz~ $(/3<@QU^bsw37?CSWfj$(26HLVZdhz~(,6:AEOSeisw~ $48BFMQ[_im )-48@DLPZ^hl~ !%8<CGQU_cuy  $-1:>EIZ^gk| )-7;BFPT[_imw{&*48?CMQ[_qu *.>BKO`duy 15?CMQcgqu%);?IM_cmq%)8<CGOSZ^fjqu}"&-]:>OS_crv}]!%,]9=NR^bqu|]]!15FJRVfjy}]#'8<HL[_f]sw -1:>EIZ^mq,07;JNW[dhy}  ")].29]>BI]VZcgvz]]] -18]=AH]MQX]eirv#'04EIPT`dsw]]] ]'+48AEVZcgvz  $-1BFOSdhx| *.59HLSWgkrv  /3:?CJOSZ_cjosz &*9=DHW[b]os ] '],07]DHQU^bko$(7;GKTXgk|]])-6:IM^bnr{  $-1BFMQY]eirv   '+48AELP_cjnuy "&/3:>OSbfos|"&.2BFOS\`im~"&/3DHPTdhos %):>OScg{ $8<LPW[bfos!%.2CGPT]arv} (,<@PTeirv}$(7;CGOS[_os|"*.6:JNUY`dsw~ '+26?CJN]ajnw{"37@DMQZ^os| !15=AQU\`imvz*.?CRV_clp (,59BFW[dhqu&*15FJQUdhw{ $,08<CGW[cgos    % ) 9 = D H P T \ ` g k {                        ( , 3 7 C G W [ k o v         ]   ]   ]         ! ( ]- 1 8 ]E I Q U e i y }                     , 0 A E T X h l s                     , 0 @ D K X \ m q z ~               &*15EIQU\`imtx%);?IMW[bfx| &*<@JNX\nr| *.8<NR\`gkuy 04<@GKRV_crv /3CGW[bfz~ "&-18<CGOS[_fjz~ %)59HLUY`duy )-AENR[_hl}$(7;JNUYbfw{ !%,0:>EISW^blpw{  '+26=AHLSW^bimtx]"15<]IMTXgkr]]]  ]!%,0?CJ]W[bfuy]]]"&04;?HL^bim|#'6:AEMQaetx ")-7;BFPT[_qu|] ")-48AEW[bfmq   # ' / 3 ; ? N R Z ^ m q x ]     ]          !!!!!!%!-!1!8!4B4Q4U4_4c4u4y4444444444444444555!5%5/535E5I5S5W5a5e5w5{555555555555555556 66!6+6/6A6E6O6S6e6i6s6w66666666666666777%7)70747C7G7X7\7m7q777777777777777778888!8%8,80898=8D8H8O8S8b8f8v8z88888888888888888889 9999"9/939G9K9S9W9g9k9t9x999999999999999::::-:1:B:F:O:S:Z:^:o:s:::::::::::::::::;;;;,;0;9;=;D;H;Y;];l;p;x;|;;;;;;;;;;;;;;;;; <<<#<*<.<6<:<B<F<N<R<Z<^<n<r<y<}<<<<<<<<<<<<<<<<<<<=] ===]#='=.=2=;=?=H=L=S=W=`=d=m=q=x=|============= >>>>;>?>F>J>S>W>`>d>k>o>x>|>>>>>>>>>>>>>>???%?)?H?L?S?W?^?b?i?m?t?x???????????????????@@@@&@*@3@7@@@D@U@Y@`@d@p@t@@@@@@@@@@@@@@@@@A AAA%A)A8AFBFKFOF`FdFtFxFFFFFFFFFFFFFFFFFFFGGGG#G'G8GIEIIIPITI[I_IgIkIrIvI~IIIIIIIIIIIIIIIIIIIIIJ J JJJ J$J+J/J7J;JJJNJUJYJiJmJvJzJJJJJJJJJJJJJJJJJJK KKKK&K*K3K7KHKLKSKWKcKgKvKzKKKKKKKKKKKKKKKKKKK LL!L%L.L2LCLGLPLTLeLiLpLtLLLLLLLLLLLLLLLLLLLLM MMMM&M*M;M?MHMLMUMYMbMfMwM{MMMMMMMMMMMMMMMMMMMN NNN'N+N2N6NHNLNSNWN^NbNqNuN|NNNNNNNNNNNNNNNNO OOO#O'O8OTGTKTTTXTiTmTtTxTTTTTTTTTTTTTTTTTU UUU/U3UaHaLaSaWaiama|aaaaaaaaaaaaaaaabbbb*b.b?bCbMbQbXb\bnbrbbbbbbbbbbbbbbbbbbbbbbcccc#c3c7c>cBcJcNcVcZcccgcpctcccccccccccccccccccd ddd.d2dCdGdVdZdcdgdqdud~dddddddddddddddddddde ee!e*e.e7e;eDeHeQeUefejeseweeeeeeeeeeeeeeeeeee ffff$f(f1f5fFfJfQfUfafefrfvfffffffffffffffffffff gggg/g3g:g>gMgQgXg\gkgogxg|gggggggggggggggghhhh h/h3hoOoSodohowo{oo]ooo]ooo]ooo]oooooooooooo ppp]p!p(p]-p1p8p]EpIpQpUp]papqpup~pppppppppppppppppqqqq q1q5q>qBqSqWq^qbqqquq~qqqqqqqqqqqqqqqqrrrr"r&r5r9rJrNrWr[rbrfrwr{rrrrrrrrrrrrrrrss ss!s%s4s8sIsMsVsZsasesvszsssssssssssssssssss tt!t%t4t8tGtKtTtXtatetntrt{ttttttttttttttt]ttt]tu uuu!u(u,u;u?uFuJuYu]ulupuuuuuuuuuuuu]uuu]uuvvvv!v%v.v2v;v?vPvTv]vavjvnvwv{vvvvvvvvvvvvvvvv]vvw]www!w0w4wCwGwWw[wkwow~wwwwwpwwwwwwwwwwwwwx xxxx/x3xCxGxNxRxZx^xnxrx{xxxxxxxxxxxxxxxpxxypyyyp&y*y9y=yNyRyayeyvyzyyyypyyyyyyyyy]yyyyyy zzz]#z'z.z2z9z=zDzHzWz[zbz]ozszzzzzzpzzzpzzzpzzzzz]zz{ {{{.{2{9{p>{B{I{pV{Z{a{pn{r{y{p~{{{p{{{p{{{{{]{{{{{p| |||0|4|;|]H|L|[|_|f|]k|o|v|]|||p||||||||||||||||||}}}}"}&}-}]2}6}=}]B}F}M}]Z}^}h}l}v}z}}}}}}}}}}}}}}}}}~~~~)~-~:~>~G~K~Z~^~p~t~{~]~~~~~~~]~~~]~~~]~~~]~~p$(/p<@JN`dk]x|'+>BLPZ^pt{ŀɀЀԀ܀pp,0:>EISWimt]]ȁ́Ӂׁ]&*9=QUfj{˂ςւڂ]!].2CGX\c]ptɃ̓Ճكp"&-p:>HL^bi]nry]̄Єڄބ!%,]15<]IMW[mqz~]]ÅDžم݅ )-?CPT]apt}Æ҆ֆ'+<@QUdho]tx]]ȇ̇އ (,;?QUfjy}ppňɈЈ]݈ "/3<@OSdhy}ɉ͉߉  15DHRV`dnr|ŠƊ͊ъ (,37@DMQX\kox|ŋɋӋ׋%)37IMVZcgx|Č֌ڌ -1BFUYaeuyʍ΍׍ۍ'+7;OS\`qu|ώӎ܎-18<KOX\mqz~ʏΏ׏ۏ,09=DHY]lpy}̐Аܐ !(,;?HL]ajnÑ̑Б ,0?CLPW[lpÒǒےߒ"&/3DHQUfjquȓ̓ӓד&*37>BSWfjrv~ŔΔҔ۔ߔ %)04=AHL]arvʕΕՕٕ  ")-48?CKOW[jn}pǖp̖Жזp] /3DHOpTX_pdhop|pЗԗݗ *.?CLPW[lpØǘӘט&*15DHOS[_gktxƙʙٙݙ  #'.2;?FJ[_fjswĚȚКԚܚ  $-1BFOS\`im~Λқٛݛ !%.29=NRaenry}Ŝɜќ՜ %)=AHLSWfjqu}ҝ֝ݝ  $+/8<EIPT]ahl}ϞӞڞޞ!*.7;BFOSdhqu~Οҟ۟ߟ.2CGPT[_ptàǠϠӠ04CGNR[_hlsw~ǡˡԡء#'.2>BQU\`qu|ĢȢ٢ݢ &*15FJY]dhosɣͣݣ *.:>RV]]bfm]rv}]]]ŤͤѤڤޤ(,=AH]MQX]]ah]mqx]}]]ʥΥץۥ  !%.2;?PT]ahl}ĦͦѦڦަ (,48HLSW`dmqx|§Ƨاܧ &*15FJQUdhquƨʨӨר (,59JNW[lpw{Ωҩ٩ݩ04;?NR[_pt}ŪɪҪ֪ݪ '+26GKZ^os|īȫѫիܫ&*15FJY]nr{ìǬЬԬ۬߬%)04EIX\cgpt}­ƭέҭڭޭ "+/6:CGX\eirv®ƮͮѮ  $59BFMQbfuyį̯Яدܯ +/6]CGPT`dx|ͰѰݰ .29]FJQU\`pt{ñDZαұ]-1:>EIRV_ctxpòpвԲ۲]&*37>BIM\`gksw]Ƴʳѳ]޳] !.29=DHW[bfmqx|]]]˴ϴڴ޴  !%,0?CJNVZaemq]]]ŵ̵ѵյܵ"&-18<CGNRael]qu|]]ʶζ߶ $,07;CGW[b]gkr]]·Ϸӷڷ޷$(7;B]GKR]_cj]w{¸Ƹ͸Ѹظܸ -18]=AH]UY`]mqx}ιҹٹݹ ]!(]59@]MQX\eipt}ĺӺ׺޺]"&-]:>E]RV]bfmrv}»ɻͻԻػ]]]'+48IM\`osz~Ҽּݼ ,07;JNW[dhquĽ˽Ͻ۽߽,0?C[_nr{žξҾ&*;?HL]ahl{ÿʿοݿ&*37>BSW^bnr"&59@DKO^bi]vz &*6:FJVZfj~ !%,0?CJNVZbfos|]]]  $+/8<EIRV]ajnw{ )-6:KOVZaelpppp]&*15DHY]dpimtpp  +/6:IM^bkovz!%48IMVZaevz $(/3=ASW`dpt.2>BQU\]ael]y}(,=AHL[_kox| *.?CLPY]fj{".2>BQUfjsw~ #48?COSbfos$(/3DHW[cgos%)26GKRVeirv} #,09=FJ[_nr~]]] p&p+/6pCGPTcgnpsw~pp /3BFRV_crv]]]pp p$(7;BpGKRpW[bpos|ppppp p#,0?CJ]OSZ]_cj]w{'+48GKTXaevz!26FJ[_hlsw $])-4]9=D]QU\`hltx]]]] #*.=AJN_cjn}#'.2AEVZcgnr -1@DLPX\dhpt| #'37FJQ]VZa]nry}]] "&7;JN_clpw{ "&.2:>FJRVfjq]vz]]]  $-1BFM]RV]]bfm]rv}]] +/8<CGX\kov]{]]] &*1]6:A]FJQ]VZa]nry}  $-1:>MQX\dhpt| *.59EIX\cgx| %):>GK\`gkz~  $+/>BSW`dko *.=ARV_cjn  )-<@GKSW_ckow{ !%,]15<]AEL]QU\]imtx] ] '],07]<@G]TX_clpy}%)0]59@]EIP]UY`]mqx|]] ]](,37@DMQX\eirv "*.6:BFVZaenr{!26=ARV]apt}!%48AEVZcgx| %):>MQbfosz~ $(9=LPaenry} !%59@DLP`dkovz]]]] ]$(04<@IMVZcgpt}]]]]]]#,09=FJSW^bkox|]$(/]48?]DHO]TX_]lpw{]] ]]#*]7;BFOS\`gktx ")-6:CGNR[_pt} %)8<EIZ^gk|  "+/@DKO^bko*.7;BFW[jn)-6:AEVZim~%)15=AIM]ahlsw "&-18<KOX\eirv !%.2;?PT[_fjqu!%,07;JN^bkox| ,09=NRbfw{ &*15<@TXgk{ $+/6:IMVZcgpt -1:>GK\`gkz~04DHPTdhqu~ &*37@DMQbfos| $(9=DHW[bfnr !%,08<CGW[dhqu 48HL[_os| (,59BFW[bfmq     ' + ; ? O S d h q u |                    ) - 6 : C G P T e i p t {                        ' + : > N R [ _ h l }                     " + / 6 : K O ^ b k o                         / 3 : > E I ] a p t                  ")-48?CRV_clpy} !%6:CGPTeipt$(9=MQX\cgnry}] ]#'04EIPT]arv]] ]])-6:KOX\mqx]}]] !%.2AETXimuy %):>GKTXaevz)-9=LPX\lpy})-=AQUei}] (,3]@DKOX\kox| *.?CSWhluy&*37FJ[_f]sw  $-1BFOS\`im~$(7;BFNRbfvz %);?FJRV^bjnvz %)9=FJQU^bko]]] &]+/6];?F]SW^bkox| $(/3<@IMTXaevz]]]]  ]   ]& * 1 5 > B K O V Z i m v z                  !!!!$!(!9!=!F!J!S!W!h!l!t!x!!!!!!!!!!!!!!!!!" ""","0"9"="N"R"c"g"p"t"{""""""""""""""""""""####'#+#4#8#H#L#T#X#`#d#m#q#z#~###################$$$$"$&$6$:$B$F$N$R$Z$^$n$r$y$}$$$$$$$$$$$$$$$$$$$%%%%#%'%/%3%C%G%P%T%]%a%r%v%}%]%%%]%%%]%%%%%]%%%]%%%]%%&&&&&&(&,&;&?&H&L&[&_&f&j&s&w&&&&&&&&&&&&&&&&&&&&' '''#'4'8'H'L'S']X'\'c']p't'''']''']''''''''''''((((( ()(-(<(@(H(L(\(`(q(u((((((((((((((((())))!)%).)2)C)G)N)R)a)e)u)y))))))))))))))))) ****,*0*7*;*C*G*O*S*[*_*g*k*s*w*******************++++++.+2+:+>+N+R+[+_+f+j+s+w+++++++++++++++++,,,,,,-,1,9,=,M,Q,X,\,e,i,r,v,,,,,,,,,,,,,,,,,,,-- ----#-'-0-4-;-?-H-L-U-Y-`-d-m-q-z-~----------------..] ...].!.(.]-.1.8.]E.I.P.T.[._.n.r.y.]~...]...]...]............////"/&/5/9/@/D/M/Q/Z/^/g/k/|/////////////////////000'0+0;0?0F0J0Q0U0d0h0o0s0|00000000000000000000 1111&1*1;1?1H1L1U1Y1j1n1v1z111111111111111122 222.222;2?2P2T2e2i2r2v2}22222222222222222222 3333-31383<3C3G3X3\3c3g3v3z3333333333333333334 4444,40474;4B4F4M4Q4`4d4m4q4z4~444444444444444444445 5 555#5'50545=5A5J5N5_5c5k5o5w5{5555]555]555]5555555]555]66 6]66$6(61656>6B6K6O6X6\6k6o6x6|666666666666666666677 7777'7+72767?7C7L7P7Y7]7n7r7z7~7777777777]777]777]778 888$8(8/8]4888?8]D8H8O8]\8`8g8k8t8x888888888888888888899 99"9&9-919:9>9E9I9R9V9_9c9j9n9w9{99999999999999999 ::::":&:/:3:B:F:N:R:b:f:w:{::::::::::::::::: ; ;;;';+;4;8;I;M;T;X;g;k;{;;;;;;;;;;;;;;;;;<<<<!<)<-<6<:<J<N<V<Z<b<f<o<s<|<<<<<<<<<<<<<<<<<<<<====&=*=1=5=E=I=R=V=_=c=t=x==================> >>">&>6>:>I>M>]>a>j>n>w>{>>>>>>>>>>>>>>>>>>> ? ???#?'?0?4?E?I?P?T?[?_?n?r??????????????????@ @ @@@)@-@=@A@R@V@_@c@j@n@@@@@@@@@@@@@@@@@@A AAAA-A1A8ARBRSRWR`RdRsRwR~RRRRRRRRRRRRRRRRRRRRSS SSSS%S)S2S6S=SASJSNSUSYSbSfSoSsSzS~SSSSSSSSSSSSSSSSSSTTT&T*T1T]6T:TAT]NTRTYT]TdThTwT{TT]TTT]TTTTTTTTTTTTTTTUUUU U)U-U6U:UCUGUXU\UcUgUpUtU{UUUUUUUUUUUUUUUUUUUUUUVV VVVV'V+V4V8VAVEVVVZVbVfVvVzVVVVVVVVVVVVVVVVVVW WWWW"W&W7W;WDWHWQWUW^WbWsWwWWWWWWWWWWWWWWWWWWWWX XXXX"X&X-X1X:X>XEXIXRXVX_XcXjXnXwX{XXXXXXXXXXXXXXXXYY] YYY]$Y(Y/Y3Y:Y>YMYQYXY]]YaYhY]uYyYYYYYYYYYYYYYYYYYYYYZ ZZZZ.Z2Z9Z=ZFZJZQZUZ^ZbZiZmZvZzZZZZZZZZZZZZZZZZZZZ[[[[+[/[6[;[?[F[S[W[^[b[q[u[|[[[[[[[[[[[[[[[[[[[\ \\\#\*\.\7\;\D\H\Q\U\f\j\q\u\~\\\\\\\\\\\\\\\\\\\\]]]]*].]>]B]I]]N]R]Y]]f]j]q]u]|]]]]]]]]]]]]]]]]]]]]]] ^ ^^^)^-^4^8^A^E^N^R^[^_^p^t^{^^^^^^^^^^^^^^^^^^^^__#_'_._3_7_>_K_O_V_Z_i_m_t_x___________________` ``` `$`-`1`@`D`T`X`a`e`n`r``````````````````aaaa"a1a5aFaJaSaWa^abasawa~aaaaaaaaaaaaaaaaaaaabbbb$b(bcBcKcOcXc\cmcqczc~cccccccccccccccccdddd"d&d/d3dDdHdOdSdbdfdmdqdyd}dddddddddddddddeeee,e0e@eDeSeWegeke|eeeeeeeeeeeeeeeeeeffff#f](f,f3f]@fDfKfOfVfZfifmftf]yf}ff]ffffffffffffff gg g$g4g8g?gCgRgVg_gcgtgxgggggggggggggggghh hh h/h3hDhHhQhUh\h`hqhuhhhhhhhhhhhhhhhhhii ii i$i3i7iGiKiZi^iniriiiiiiiiiiiiiiiiiiij] j jj]!j%j,j0j7j;jJjNjUj]Zj^jej]rjvj}jjjjjjjjjjjjjjjjjjjk k kkk+k/k6k:kCkGkNkRk[k_khklkskwkkkkkkkkkkkkkk]kkk]l llll l/l3l:l]?lClJl]Wl[lblflolsl|llllllllllllllllllm mmm m$m5m9mBmFmOmSmdmhmxm|mmmmmmmmmmmmmmmmmn nnn%n)n9n=nLnPn`ndnunynnnnnnnnnnnnnnnnnn]nno]ooo"o)o-oNRY]gkuyрՀ߀ "&8<DHPT\`pt~Ɂ]΁ҁف]ށ]] &]+/6];?F]KOV]cgnr|̂Ђق݂ ",0?CKO_cuyɃ̓׃ۃ +/9=OSZ^mq{фՄ܄ !%/3=ASW^bquÅՅم #'15?CUY`dswņφӆ%)37IMW[bfpt~ɇׇ͇ۇ  #-1;?QU_cmqňɈӈ׈ 15?CJNX\nr|̉Љ$(:>HLSWim|̊Њ׊ '48?DHOTX_lpw|ċȋϋԋ؋ߋ  '48HLTXgk{ČΌҌٌ݌ &*<@JNUYcgnr|ʍ΍؍܍"48@DLPX\lpz~ĎȎҎ֎!+/6:DHW[mqy}ÏʏΏ؏܏ )-7;BFPT[_imw{ːϐِݐ#,0:>GKUYcgptđ֑ڑ!%/3=AKOY]osϒӒےߒ 26EIcgptȓ̓ޓ"&04;?IMTXbfpt~”ɔ͔ה۔ (,>BJN^blpw{ȕ֕̕ڕ !%/3=AKOY]dhw{ɖ͖ݖ $.2<@GKRVhluyɗ͗֗ڗ '+=AKOY]gkuyĘΘҘܘ %)15=AIMUYim|řΙҙۙߙ  %)37AEW[cgos{ĚȚҚ֚.2<@JNX\fj|]]]]ěțٛݛ]]]  ]!%,0:>HLSWaelpw{Üǜќ՜ܜ  !37GKUYcgy}˝ϝ֝ڝ +/9=GK]akoy}ɞ͞ߞ /3=AKOaeos}˟ϟ"15?CMQ[_quàՠ٠  $.2<@GKUYcgy}ǡˡݡ!+/AELP_cmqˢϢ٢ݢ ,0:>EI[_imtxϣӣ '+:>MQX\cgvz]ʤΤդ]ڤޤ]] #26EIPT]apt{¥ƥϥӥ  ")-<@QUmq¦Ʀզ٦$(/3DHW[swħȧاܧ'+48GKX\ko~ppĨȨϨpܨ]] *.5p:>EpJNUpbfm]z~]]ȩ̩өש .2:>EIY]qu}ĪӪת ".2FJRVfjqu|ƫʫҫ֫ݫ #*.6:AEMQX\lpw{ĬȬϬӬڬެ  '+26=AHLSW^bimtxɭͭԭ]] #*]7;JNU]bfuy]]ˮϮ֮]]!%,]9=LPW]dhw{ǯ˯ׯۯ  !%.2CGNRY]dhpt°˰ϰذܰ"&6:CGPT[_pt{̱б!%59JN]ah]mqx]}]]]IJ̲вײ۲ ] '],07]<@G]TX_cjnuy]óʳ]ϳӳڳ]&*;?HLSWhl{Ĵȴ״۴  '+;?FJRV]aimtxĵ˵ϵֵڵ #'.2AEL]Y]lpw]]¶ƶͶ]ڶ޶] #]04CGN][_nry]]ķȷϷ]ܷ"&37DH]ajnw{Ǹ˸Ҹָ޸ ,09=FJQUfjqu¹ɹ͹޹ '+:>OS\`gk|˺Ϻֺ]ۺߺ]]] ]#'.2:>EIPT[_fjz~]]]]»ƻͻѻػܻ ]-18]=AH]UY`dkożּڼ&*26EIPT[_fjy}ƽʽѽսݽ")-=AH]UYhlsw¾ɾ;޾  "15<@OS\`imtxſֿڿ *.59HLUYbfw{ %)26GKRVbfuy -1BFOSZ^os $59@DSW`dx| /3QUdhtx".2FJSW`dmq/3QUdh!%/3=ASW`dos| $(26@DVZcgrv (,>BJNVZbfnr 04;?FJY]lpw{ !+/9=GKUYcgqu%)059@EIPUY`eip}37FJdhw{ '+59KOim|  '+:>X\koy})-7;EISWaeos]] ]-1:>OS\`imvz26EIcgvz"&59SWfjtx "15<pAELpY]d]qu|  '+26=APT[p`dkpx|] #48IMeix| '+26GK\`imtx  "+/6:CGPT]arv}pp]'+48?CTXaelp)-59@DSW^bqu| "&-1@DLP`dos  '+26=AIM]ahltx !(,48HLX\kovz"&-1AEMQaelp 48G K S W ^ b i m |                       + / 6 : A E \ ` i m t x                       , 0 ; ? R V ] a p t {                        "' + 2? C J N U Y h l {                      , 0 8 < D H X \ d h x |                     ! % - 1 A E P T _ c w {            !15>BIM^bko{ #,09=DHY]fjvz          , 0 7 ; J N _ c r v }                       * . A E P T ` d o s                         # ' / 3 B F MR V ]j n u y                     & * 1 5 = A P T [ _ n r y }                       ' + : > F J Z ^ i m             !%.29=DHQUfjqu~  $37>CGN[_f]kov] !%.29=FJQUfjqu| )-48AENR[_fjsw)->BKOVZko~$(/3:>MQX\kox|)-48?CRVcgtx"&/3CGVZko 15>BSW^bqu '+37?CSW`dko )-48?CLPaenry}  '+26EIPTcgnry}&*;?NR[_fjsw #+/8<FJVZhl}  ")-59BFNR[_gktxpp] $.2>BPT^btxpp]  #'04=AKOX\mqx|pp] *.;?IMZ^sw -1;?IMW[mq{ )-7;EISWimw{ *.8<EIVZgkuy (,6:DHRVhlsw%)37@DQUbfpt~ p#p04;]HLVZcgtx-1;?FJ\`rv"15OSbfx|$(7;BpOSZ]gkrv}A  $+/6:AELPW[dhos| $(/3<@GK\`qu~     " + / 8 < C G P T ] a h l u y                         $ ( / 3 < @ G K T X _ c l p w {                           . 2 9 = E I R V _ c l p y }                        # 2 6 J N U Y b f o s |                          # ' 8 < C G N R a e l p w {                    %)04CGPTeirv !(,;?HL]ahl{ #'04;?HLSWhl{"+/8<MQZ^gkrv (,=APTcgnr{ "&/3:>GK\`os| $(15DHOSZ^eix| "&7;DHQU\`qu|!%.2;?PT[_fjy} !04EIRV]arv  /3BFOSZ^os#'6:IM^bqu!(,>BQUfjy} !%48GKTX_ctx -18]EIY]dhos /3CGNRaemq "15GKUY`dvz &*9=OS]ahl~    ( , ; ? O S d h z ~              !! !!!!!!(!,!;!?!F!J!Q!U!\!`!o!s!|!!!!!!!!!!!!!!!!!!!!""""""&"-"1"8"<"C"G"N"R"Y"]"l"p"y"}"""""""""""""""#####!#3#7#>#B#Q#U#g#k#u#y################$$$($,$;$?$Q$U$_$c$j$n$$$$$$$$$$$$$$%%%)%-%=%A%Q%U%d%h%w%{%%%%%%%%%%%%%%%&&&& &$&6&:&J&N&_&c&m&q&x&|&&&&&&&&&&&&&&& ''''$'(':'>'M'Q'b'f'p't'{''''''''''''''''((("()(-(?(C(R(V(g(k(u(y((((((((((((((()) )))")3)7)A)E)L)P)b)f)u)y)))))))))))))))))**!*%*6*:*D*H*O*S*e*i*x*|****************+++&+*+;+?+I+M+T+X+j+n+}++++++++++++++++, ,,,,!,1,5,F,J,S,W,^,b,s,w,,,,,,,,,,,,,,,,-- --!-0-4-E-I-R-V-]-a-r-v----------------.. .. ./.3.D.H.Y.].l.p.w.{...............//////./2/A/E/V/Z/c/g/n/r///////////////00 0000-010@0D0U0Y0b0f0m0q0000000000000000011 11 1$15191B1F1M1Q1b1f1u1y11111111111111111 222#24282A2E2L2P2a2e2t2x22222222222222222 333"33373H3L3[3_3f3j3r3v3~33333333333333333444 4$4+4/4@4D4S4W4h4l4u4y44444444444444445555#5*5.5?5C5R5V5g5k5t5x5555555555555555666$6(6/636C6G6O6S6b6f6s6w66666666666666666667 777%7p*7.757p:7>7E7pR7V7]7a7j7n7u7y77777777777777]777]777]8 8888#8*8.878;8D8H8O8S8d8h8q8u8888]888]888]8888888888889999&9*999=9D9pI9M9T9pY9]9d9pq9u9|99999999999999999999: ::::":+:/:6:::K:O:V:Z:c:g:n:r:{::::::::::::::::::; ;;;;";+;/;6;:;C;G;N;R;[;_;f;j;s;w;~;;;;;;;;;;;;;;;;;;;;;;<<<<<<&<*<3<7<><B<K<O<V<Z<c<g<n<r<{<<<<<<<<<<<<<<<<<<<<<<= ===="=)=-=6=:=A=E=N=R=Y=]=f=j=q=u=~======================>>>>>>&>*>1>5>>>B>I>M>V>Z>i>m>t>x>>>>>>>>>>>>>>>>>>>>? ? ???!?%?,?0?7?;?D?H?O?S?\?`?g?k?t?x??????????????????????@ @@@@@#@*@/@3@:@?@C@J@O@S@Z@g@k@r@v@@@@@@@@@@@@@@@@@@@@@@@AA AAAA%A)A0A4A=AAAHALAUAYA`AdAmAqAAAAAAAAAAAAAAAAAAAAAAAB BBBB!B(B,B5B9B@BDBMBQBZB^BmBqBxB|BBBBBBBBBBBBBBBCCCC'C+C4C8CGCKCRCVCeCiC{CCCCCCCCCCCCCCCCDDDD)D-D7D;DBDFDXD\DkDoDDDDDDDDDDDDDDDDDE EEE.E2EGBGLGPGWG[GmGqGGGGGGGGGGGGGGGGGHHHH,H0HAHEHOHSHZH^HpHtHHHHHHHHHHHHHHHHI I II#I2I6IGIKIUIYI`IdIvIzIIIIIIIIIIIIIIIIJJ JJJJ!J0J4JFJJJYJ]JnJrJyJ}JJJJJJJJJJJJJJJJJJJJK KK K'K+K:K>KGKKKTKXKiKmKvKzKKKKKKKKKKKKKKKKKKLLLL#L2L6L?LCLLLPLaLeLnLrL{LLLLLLLLLLLLLLLLLMMM%M)M:M>MMMQMYM]MeMiMyM}MMMMMM]MMM]MMM]MMM]MMMMMMMN NNNN'N+N2N]7N;NBN]GNKNRN]WN[NbN]oNsNzNNNNNNNNNNNNNNNNNNNNO OOOO"O3O7O>OCOGONO[O_OfOjOyO}OOOOOOOOOOOOOOOPPPP*P.P>PBPRPVP]PaPhPlPuPyPPPPPPPPPPPPPPPQQ QQ!Q%Q4Q8QIQMQVQZQaQeQvQzQQQQQQQQQQQQQQQRR RR R$R3R7RHRLRURYR`RdRuRyRRRRRRRRRRRRRRRRR SSS!S(S,S4S8S?SCSKSOSVSZSjSnSuSySSSSSSSSSSSSSSSSSST TT T$T3T7TFTJTTTXT_TcTuTyTTTTTTTTTTTTTTTUU UU!U%U4U8UIUMUWU[UbUfUxU|UUUUUUUUUUUUUUUV VVV&V*V9V=VNVRV\V`VgVkV}VVVVVVVVVVVVVVVV WWW!W0W4W=WAWHWLW]WaWpWtWWWWWWWWWWWWWWWWWX XXX-X1X:X>XEXIXZX^XmXqXXXXXXXXXXXXXXXXXYYYY*Y.Y7Y;YBYFYWY[YjYnYYYYYYYYYYYYYYYYYZZZZ)Z-Z6Z:ZAZEZVZZZiZmZ|ZZZZZZZZZZZZZZZZZZ[[[[![%[,[0[8[<[M[Q[Z[^[g[k[r[v[[[[[[[[[[[[[[[\\ \\\\&\*\1\5\>\B\K\O\X\\\c\g\x\|\\\\\\\\\\\\\\\\\]]]]!]%]4]8]A]E]V]Z]c]g]x]|]]]]]]]]]]]]]]]]]^ ^^^-^1^:^>^E^I^Z^^^m^q^y^}^^^^^^^^^^^^^^^^^_ ___)_-_4_8_A_E_N_R_f_j_q_u_________________````&`*`9`=`D`H`P`T```d`k`o`v`z````````````````````a a aa a/a3aCaGaNaRaaaealapaxa|aaaaaaaaaaaaaaaaabbbb!b%b5b9bDbHb[b_bfbjbqbubbbbbbbbbbbbbbbbb c cc c7c;cJcNc]cacxc|ccccccccccccccccccd dddd,d0d?dCdUdYdjdnd}ddddddddddddddddddee eee"e3e7eFeJeQeUe\e`etexeeeeeeeeeeeeeeeeeefff$f(f4f8fCfGfZf^fefifqfufffffffffffffffffffffgggg!g&g*g1g>gBgIgMgTgXgggkgzg~gggggggggggggggggh hhh$h(h/h3hBhFhMhQh`hdhlhphhhhhhhhhhhhhhhhhhhiiii.i2i=iAiTiXigikiiiiiiiiiiiiiiijjjj%j)j8jo Eo Io Xo \o do ho xo |o o o o o o o o o o o o o  p p  p"$p",p"0p"7p";p"Jp"Np"Yp"]p"pp"tp"{p"p"p"p"p"p"p"p"p"p"p"p"p"p"p"p"p$p$q$q$q$q$q$q$-q$1q$8q$r&Nr&Rr&Yr&]r&er&ir&yr&}r&r&r&r&r&r&r&r&r&r&r&r&r&r&r&r&r&s&s&s&s&!s&%s&1s&5s&Fs&Js&Qs&Us&es&is&ps&ts&{s&s&s&s&s&s&s&s&s&s&s&s&s&s&s&s&t&t&t&t&)t&-t&v(Bv(Tv(Xv(_v(cv(kv(ov({v(v(v(v(v(v(v(v(v(v(v(v(v(v(v(v( w(w(w(#w(*w(.w(=w(Aw(Hw(Lw([w(_w(gw(kw(rw(vw(w(w(w(w(w(w(w(w(w(w(w(w(w(w(x(x(x(x(x("x(1x(5x(=x(Ax(Ix(Mx(]x(ax(ix(mx(ux(yx(x(x(xx(x(x(x(x(x(x(x(x(x(x(x(x(x(y(y(y(y(#y('y(7y(;y(Cy(Gy(Wy([y(by(fy(my(qy(xy(|y(y(y(y(y(y(y(y(y(y(y(y(y(y(y(y(z(z(z($z((z(/z(3z(Bz(Fz(Rz(Vz(jz(nz(}z(z(z(z(z(z(z(z(z(z(z(z(z(z(z(z(z(z({( {({({( {(${(,{(0{(@{(D{(K{(O{(^{(b{(j{(n{(}{*{*{*{*{Z{*{*{Z{*{*{p{*{*{p{,{,{,{,{,{,|, |,|,|,+|,/|,9|,=|,D|,H|,R|,V|,`|,d|,s|,w|,|,|,|,|,|,|,|,|,|,|,|,|,|,|,|,|,|,|,}, },},},!},%},/},3},E},I},[},_},g},k},s},w},},},},},},},},},},},},},},},},},},},},~, ~, ~,~,~,%~,)~,2~,6~,?~,C~,L~,P~,Y~,]~,o~,s~,~,~,~,~,~,~,~,~,~,~,~,~,~,~,~,~,~,~,, ,,,!,%,/,3,E,I,Q,U,],a,q,u,,,,,,,,,,,,,,,,,,,,,#,',1,5,?,C,U,Y,c,g,q,u,,,,,,,,,ɀ,̀,׀,ۀ,,,,,,,,#,5,9,C,G,Y]fjswǁˁ܁ #'04=ARV]ajnw{ĂȂׂۂ  $59@DSWgkrvЃԃ݃!(,=APTdhw{ÄDŽфՄ܄ "&7;CGW[dhos|…Ӆׅޅ]]] $+]8<CGPTcgptƆʆӆ׆%)0]=AHLSWfjq]~ćȇ؇܇+/?CJN]ajnLjˈ҈ֈ '+:>GKRVgktxʼn։ډ +/>BKOY]os}ĊȊҊ֊ "&.2:>FJZ^gkrvƋʋҋ֋ "&-]26=]BFM]Z^osz]]]Ì̌Ќ׌ی $(15FJQU^bimtxƍ׍ۍ]] ]#'.29=LPW]\`g]lpw]͎ю؎܎ -1:>OS[_osz~͏яڏޏ /3DHQU\`quÐԐؐ.2CGPT[_ptőɑܑؑ  "&.2:>HL^blpȒ̒Ԓؒ &*37HLTX`dlpǓ]̓Гד]ܓ]  ]$])-4]AELPY]fjqu”˔ϔ04<@HL\`qu]]]ȕ̕ӕו]] ]")-48GKTXgkrvǖ˖Ԗؖ  '+48IMTXgktxɗ͗ޗ "26EIY]nr{Ș̘ݘ !26?CJN_crvș̙ԙؙ  )-48AEVZbfnrz~Ě͚њ '+48AEVZa]fjq]vz]]]ÛǛΛ]ۛߛ  $-1@DKOX\eiz~ʜΜ֜ڜ #*]/3:]?CJ]W[bfmq]]]ÝǝΝҝ #+/?CLPaenrŞΞҞ#'04EIPTcgx|̟Пߟ  $59BFMQbfw{̠Р٠ݠ '+=AKOVZbfnr|áǡΡҡۡߡ (,59@DMQZ^gk|Ţ΢Ңۢߢ] ]](,=AH]MQX]]ah]uyǣˣڣޣ#,07;BFOSdhpt|Ĥ]ɤͤԤ]٤ݤ] %]*.5]:>E]RV]ahl{ťɥ٥ݥ !)-=AHL[_hl}ʦΦߦ#*.?CRVfjy}ϧӧܧ")->BQUfjsw~....Ĩ.Ȩ.Ϩ.Ө...... ...$.(.3.7.B.F.T.X.c.g.r.v...........ȩ.̩.ԩ.ة...........&.*.3.7.C.G.P.T.].a.m.q...........̪.Ъ.۪.ߪ...... ...&.*.=.A.H.L.S.W._.c.j.n.v.z...........ǫ.˫.ԫ.ث...... ....".2.6.A.E.P.T._.c.l.p.z.~.........Ƭ.ʬ.Ӭ.׬...........%.).1.5.E.I.R.V.a.e.n.r.{..........ŭ.ɭ.ԭ.ح...... ....#.*...6.:.I.M.T.X.a.e.l.p.w.{...........Į.Ȯ.Ԯ.خ......... %.).0=.A.HM.Q.Xe.i.pu.y.......ȯ.̯.ԯ.د..... ..!.%.4.8.G.K.S.W._.c.s.w.~......ư.ʰ.Ұ.ְ.ް..0000000060:0E0I0T0X0c0g0p0t00000000±0ʱ0α0ޱ0000000 0000!02060E0I0X0\0k0o0z0~00000000ò0ʲײ0۲0000000000"03070F0J0Y0]0l0p0{000000000ij0˳س0ܳ000000 0000#04080G0K0Z0^0m0q0z0~0000000000ô0ִ0ڴ00000 000"0)0-060:0A0E0L0P0Y0]0d0h0y0}0000000µ0Ƶ0͵ڵ0޵00000 00*0.070;0L0P0W\0`0gt0x000000000Ŷ0ɶ0ض0ܶ0000000#0040D0H0W0[0j0n0}000000000ŷ0̷ٷ0ݷ000000 000,000?0C0R0V0e0i0p}2222222222Ÿ2ɸ2ظ2ܸ2222222 22 2$2+2/262:2B2F2U2Y2h2l2s2w2~2222222222ι2ҹ2ٹ2ݹ22222 222!2(2,2;2?2N2R2a2e2t2x2222222ź2ɺ2кݺ22222222!&2*21>2B2IN2R2Yf2j2qv2z2Ȼ̻Իػ )-6:AENR[_hluyҼּ $04@DX\fjvzŽϽӽ߽ $(48DHTXdhtx̾оھ޾  $04HLSW`dmqz~Ŀȿٿݿ #'15?CMQcgpt}!*.?CJNW[dhqu~  $-18<EIRV]apt}(,37FJQU^bkox|  !%.29=DHQU\`qu|(,59JNW[dhqu~!*.7;DHQU^bkox| $(15>BKOX\mqx| "&/3<@QU^bkox|"+/8<MQZ^osz~ #,0AENRcgnr #,09=FJ[_fjy}-18<HL[_nr  /3GK\`os} ,0AELPcgx| #'.2AELPY]fjqu '+48AENR[_pt{ !)-=AHLTX`dlpx|".2FJQU\`os| 37@DUYbfw{ '+<@OSdhqu|555555555555555 555$5(5/535:5>5K5O5]5a5h5l5{5555555555555555555555 5555)5-54585?5C5J5N5]5a5h5l5y5}5555555555555555555#5'565:5A5E5N5R5[5_5nry}'+37GKSW_csw~ %)15=AQU\`gkz~ #*.59HLSW`dmqx|  $+/8<EIPT[_hlsw  $)-49=DQU^bkox|!%59BFOS\`imvz "&/3:>GKTXaenr"&/3<@IM^bkox| *.7;DHY]dhw{ )->BIM\`im~$(9=DHW[dhy}  !*.59JNU]bfmq)-6:AEVZim~ &*26>BJN^bjnvz!%-18<DHQU]aim} '+48AEVZbfnry}"&.29=EIY]eiy} )-6:KOX\mqx|!%.2CGPT]arv} #+/>BKOVZcgpt"&-1@DTXaevz !%-1:>EIRV]arv/3:>EIQU\`pt| %)8<KO^bimtx #'/3<@GKTXaevz] ]-1CGPTcgnry} &*9=DpQUgktx #26EIRV]arv}]$(15<@QUdhw{ .2FJQ^bim| &]+/6]CGQUgkx|] #-1CGN]SW^]ko  $-18<MQcgw{ #,07;LP_cjosz~ )-6:AENRcgnry}$(9:=:E:I:P:T:c:g:n:r:y:}:::::::::]::]::::::::#:':.];:?:H:L:S:W:`:d:k:o:x:|:::::]::::::::::::] ::::%:):::>:G:K:\:`:i:m:~::::::::::::MMMMMMM MMMM!M1M5M>MBMSMWMfMjMq]vMzM]MMMMMMMMMM]MMMMMMM MMMM!M(M,M=MAMH]UMYMbMfMmMqMzM~MMMMM]MMMMMMMMMMMMMM#M'M.M2MAMEMNMRMYM]MnMrMOOOO|OO|OOpOOpQQQQQQ QQQQ-Q1Q8Q<QMQQQZQ^QjQnQzQ~QQQQQQQQQQQQQQQQQQQ]QQQ#Q48BFRVbfpt"&26JNUY`dsw~]".2FJQUdhos| +/6:AELP_cj]w{%)8<CGPTcgnr]&*;?FJQU^bimtx ,07;JNUYaeuy     p# ' . p; ? F ]S W g k r v ~                        ! & * 1 > B I M U Y a e l p x |    ]   ]   ]             ! ( , ; ? F ]K O V ]c g n ]{                       ! 0 4 > B T X _ c j n u y                         ) - 4 8 ? C R V ] b f m r v }                  04>BTX_cjnw{&*15<@GKTX_cjn '+:>MQ[_im #*.59HLSWfjqvz ,0BFMQX\cgvz#'.29=DHW[bgkrw{]]  ]!%,15<AELY]dhos &*15=AIMTX`dtx]]]SSSSSSSSSSSSSS&S*S;S?SHSLSUSYS`SdSuSySSS -1@DKOX\cgpt}!+/6:LPW[jnw{!%.2;?HL]ahluy#,07;DHQU\`qu| $(15>BIM^bim| $37>BLPW[eipt~!04>BLPZ^hl~!37@DMQZ^gk| 15<@OS]akoy}     $ . 2 < @ J N ` d m q z ~                  ! !!!!0!4!=!A!J!N!W![!d!h!q!u!!!!!!!!!!!!!!!!!"" """"'"+"4"8"A"E"V"Z"a"e"t"x"""""""""""""""""""####&#*#1#5#D#H#R#V#`#d#n#r#|##################$$$$"$&$0$4$>$B$L$P$Z$^$p$t$}$$$$$$$$$$$$$$$$$$%%%%% %*%.%@%D%M%Q%Z%^%g%k%t%x%%%%%%%%%%%%%%%%%%%& &&&)&-&6&:&C&G&P&T&]&a&j&n&&&&&&&&&&&&&&&&&&&'' ''''''+'4'8'I'M'V'Z'c'g'p't'}'''''''''''''''((((#(,(0(9(=(F(J(S(W(`(d(u(y((((((((((((((((((())))))(),)5)9)B)F)W)[)b)f)q)u)|)))))))))))))))))))* ****#*'*/*3*;*?*G*K*[*_*h*l*u*y********************+ ++++"+&+5+9+@+D+S+W+^+b+q+u+++++++++++++,,,,, ,),-,6,:,C,G,P,T,e,i,r,v,,,,,,,,,,,,,,,,,,,,- ----'-+-<-@-H-L-\-`-h-l-|-------------------. . ...).-.4.8.A.E.T.X._.c.l.p.w.{.................///// /)/-/>/B/`/d/s/w////////////////0 0000%0)0:0>0F0J0R0V0^0b0j0n0v0z000000000000000000011111"1+1/1@1D1L1P1X1\1d1h1p1t1|1111111111111111111122222"2,202:2>2E2I2[2_2f2k2o2v2{2222222222222222222222223 3333%3)33373A3E3O3S3]3a3k3o3y3}3333333333333333333 4444*4.4?4C4U4Y4b4f4m4q4x4|444444444444444444444555555$5(51555>5B5I5M5^5b5i5m5q5x5|5555555555555555555 666"64686B6F6M6Q6c6g6v6z6666666666666666777%7)7;7?7I7M7T7X7j7n7}77777777777777778888-818C8G8X8\8k8o8v8z8888888888888888888889 9999#9,90999=9N9R9^9b9i9m9x9999999999999 :: :$:5:9:H:L:^:b:s:w:::::::::::::;;;;-;1;@;D;V;Z;k;o;~;;;;;;;;;;;;;;<<%<)<8<<<N<R<c<g<v<z<<<<<<<<<<<<<= ===-=1=@=D=U=Y=h=l=~==============>>">&>8><>M>Q>`>d>v>z>>>>>>>>>>>>>>>? ???-?1?@?D?V?Z?k?o?~??????????????@@%@)@8@<@N@R@c@g@v@z@@@@@@@@@@@@@A AA!A0A4ACAGAXA\AkAoAAAAAAAAAAAAAABBB%B)B;B?BPBTBcBgBnBrBBBBBBBBBBBBBBCCC(C,C;C?CQCUCfCjCyC}CCCCCCCCCCCCCD DD!D0D4DCDGDXD\DkDoDwD{DDDDDDDDDDDDDDDDDE EEE#E'E0E4E=EAEREVE]EbEfEmErEvE}EEEEEEEEEEEEEE FFF#FAFEFTFXF`FdFlFpFFFFFFFFFFFFFFFFFFF GGGG+G/G9G=GOGSG\G`GqGuG|GGGGGGGGGGGGGGGGGGH HHH"H/H3HDHHHfHjHyH}HHHHHHHHHHHHHHHI III)I-IQHQLQSQWQaQeQlQpQzQ~QQQQQQQQQQQQQQQQQQQQR RRRR#R'R.R2RUEUJUNUUUbUfUnUrUyU}UUUUUUUUUUUUUUUUUUUUU V VVV V$V,V0V@VDVLVPVXV\VlVpVxV|VVVVVVVVVVVVVVVVVVVVW WWWW"W'W+W2W?WCWKWOWWW[WkWoWvW{WWWWWWWWWWWWWWWWWWWWX XXX#X'X.X2XAXEXMXQXaXeXlXqXuX|XXXXXXXXXXXXXXXXXXXXYY YYYY!Y(Y5Y9Y@YEYIYPYUYYY`YmYqYyY}YYYYYYYYYYYYYYYYYYZZ ZZZ(Z,Z3Z8Z[B[I[M[\[`[g[k[t[x[[[[[[[[[[[[[[[\\\\7\;\J\N\U\Z\^\e\j\n\u\z\~\\\\\\\\\\\\\\\\\\\\\]]]]!]%],]1]5]<]A]E]L]Y]]]d]i]m]t]y]}]]]]]]]]]]]]]]]]]]]]^^^^ ^(^,^4^8^H^L^S^W^_^c^k^o^^^^^^^^^^^^^^^^^^^^^^^_ ___&_+_/_6_:_A_E_T_X___c_j_n_}____________________` ```'`+`4`8`A`E`V`Z`a`e`l`p`w`{`````````````````a] aaa]aa%a]2a6a=aAaHaLa[a_anaraya]~aaa]aaaaaaaaaaaaaaaab]b bb]b#b2b6b=bAbJbNbWb[bjbnbwb{bbbbbbbbbbbbbbbbc cccc*c.c5c9cBcFcMcQcbcfcocscccccccccccccccdd"d&d5d9dHdLdSd]`dddkdodddddddddddddddddee eeee.e2e9e=eJeNe[e_efejewe{eeeeeeeeeeeeeeeeeeef fff!f%f7f;fDfHfQfUf^fbfkfofxf|fffffffffffffffffgggg%g)g0g4gCgGgNgRg_gcgpgtg{gggggggggggggggggggg hhhh)h-h:h>hGhKhThXhahehnhrhhhhhhhhhhhhhhhhhiiii$i(i1i5iFiJiQiUidihioisiiiiiiiiiiiiiiiiiiiij jjjj,j0j9j=jJjNj[j_jhjljujyjjjjjjjjjjjjjjjjjkkkk!k%k/k3kEkIkRkVkgkkkrkvkkkkkkkkkkkkkkkkkkkkl ll!l%l.l2l;l?lHlLlUlYlblflolsl|llllllllllllllllllmmmm-m1m:m>mGmKmTmXmamemnmrm{mmmmmmmmmmmmmmmmmmmm nnnn(n,n;n?nFnJn[n_nhnln}nnnnnnnnnnnnnnnnnnno oooo%o)o2o6oGoKoRoVobofouoyoooooooooooooooooop pppp-p1p9p=pMpQpZp^pgpkptpxpppppppppppppppppppqqqq#q'q.q2q9q=qDqHqOqSqZq^qeqiqpqtq{qqqqqqqqqqqqqqqqqqrrrr(r,r5r9rJrNrUrYr`rdrkror~rrrrrrrrrrrrrrrrrrsssss!s2s6s=sAsPsTs[s_shslsusyssssss]sss]sss]sss]sss]ssssttt t)t-t6t:tKtOtVt][t_tft]ktotvt]{ttt]tttttttttttttttu u uu"u)u-uwGwKw\w`wiwmw~wwwwwwwwwwwwwwwwwx xx x$x-x1xBxFxMxQx`xdxuxyxxxxxxxxxxxxxxxxx yyy#y,y0y7y;yLyPy_ycytyxyyyyyyyyyyyyyyyz zzzz"z3z7zFzJz[z_zpztzzzzzzzzzzzzzzzz{ { {{"{){-{<{@{Q{U{^{b{i{m{~{{{{{{{{{{{{{{{|||&|*|<|@|I|M|T|X|i|m|||||||||||||||| }}}}%})}:}>}M}Q}c}g}x}|}}}}}}}}}}}}}}} ~~~#~4~8~A~E~L~P~a~e~t~x~~~~~~~~~~~~~ !26EIPT[_nr| #'15?CMQ[_qu~ÀԀ؀߀&*37HLSWfjqu~Á́Ёف݁ "&/3<@IMVZcgpt}Ă΂҂ $(/3<@IMTXaenr{ăȃуՃރ %)59HLUYjnw{„Ƅτӄڄބ04=AJNW[dhqu~΅҅ۅ߅!04=AJNW[dhqu~džˆԆ؆$(/3DHQUfjqu͇чڇއ!%15DHQUfjswLjˈۈ߈$(/3:>MQX]]ah]uyĉȉщՉމ "*.=AHL[_pt{]]ĊȊҊ֊] ]"15?CMQ[_qu~ˋϋ  $59JN]aswˌό،܌ !%6:IM^bswÍǍ؍܍ -1BFUYjnw{ÎԎ؎%):>GKRVgkz~Ϗӏڏ]ߏ]] !(,37FJTX_cmq{ɐ͐Ԑؐ (,<@GKVZcgpt}ǑˑՑّ  $-1:>GKTXaenr{’ɒ͒ߒ #+/7;CGOS[_gkswǓ˓ԓؓ!+/9=DHRV`dnrŔɔҔ֔ߔ"&-1CGPTeiptÕ˕ϕוە&*15?CMQ[_fjtx͖іؖܖ &*15>BKOX\mqx|×Ǘї՗ߗ!*.7;DHQU^bsw~Ƙʘј՘ߘ  -1:>GKTXaenr{řəؙܙ %)8<DHPT\`hltxšƚϚӚܚ &*;?HLUYbfos|ɛ֛͛ڛ #,09=FJSW`dmqĜȜ؜ܜ #,07;BFOS\`imvzÝ̝Нٝݝ &*37@DMQZ^gktxʞΞמ۞ $(/3BFOSdhosƟʟџ՟ !%.2;?HL]ajnw{ ɠ͠Ԡؠ(,=AJNW[dhqu~¡ˡϡءܡ )-48DHW[dhy}Ţɢآܢ%)37NRY]nrǣˣ]] (,6:DHRVhlvz¤ƤϤӤ%)04EIX\mqĥȥڥޥ/3BFW[lpҦ֦!(,=APTfj{˧ϧ !*.59JN]arvǨ˨ܨ 15DHZ^gkrvũɩةܩ .2:>FJQU^bkox|ĪͪѪتܪ %)59BFRVbfz~˫ϫ٫ݫ)-7;BFX\kov]{]]ìǬϬӬ #'15?CMQ[_imíͭѭۭ߭ '+;?IMTXbfmq{Ů׮ۮ (,37AELPbfx|ɯͯׯۯ%)26BFRV`dnr|ðǰѰհܰ $(26@DSWaeos}ñͱѱ۱߱ )-7;EI[_imw{ŲɲӲײ#'15?CMQcgquóͳѳ۳߳ )-7;MQ[_fjtx´ƴдԴ޴",0:>HL^blpz~ʵεصܵ &*48JNUYhl~Ķֶڶ .2<@GK]ap[t[|[[[[[[[[[[[[[·[ɷ[ͷ[Է[ط[[[[[[ [[[.[2[A[E[L[P[a[e[m[q[y[}[[[[[[[[[¸[Ƹ[͸[Ѹ[ڸ[޸[[[[[[ [[[%[)[:[>[M[Q[Z[^[e[i[r[v[[[[[[[[[˹[Ϲ[ֹ[ڹ[[[[[ [[[[+[/[>[B[M[Q[\[`[s[w[[[[[[[[[[[ú[Ǻ[Ϻ[Ӻ[ں[޺[[[[[[[ [[[["[&[.[2[:[>[F[J[R[V[^[b[r[v[}[[[[[[[[»[ƻ[ֻ[ڻ[[[[[[[[[[[$[([7[;[BG[K[RW[[[bo[s[z[[[[[[[[Ǽ[˼[Ӽ[׼[߼[[[[[ [[[/[3[C[G[O[S[[[_[o[s[[[[[[[[[[[[[ƽ[ʽ[ҽ[ֽ[ݽ[[[[[[[ [[[ [$[,[0[8[<[D[H[P[T[d[h[w[{[[[[[[[[[[[[þ[˾[Ͼ[߾[[[[[[[[ [[[[%[)[9[=[L[P[X[\[d[h[p[t[|[[[[[[[[[[ǿ[˿[ӿ[׿[߿[[[[[[ [[[["[&[.[2[:[>[F[J[Z[^[f[j[r[v[~[[[[[[[[[[[[[[[[[[[[[[ [ [[ ['[+[4[8[?[C[J[N[U[Y[h[l[s[w[[[[[[[[[[[[[[[[[[[[[[[&[*[1[5[D[H[O[S[\[`[g[k[|[[[[[[[[[[[[[[[[[[ [ [[![1[5[=[A[I[M[][a[q[u[[[[[[[[[ &*15>BIMVZaenr{  $-1:>OS\`imvz  $,08<DHOSbfosz~ $(15>BIMVZimtx -18<CGVZaelpw{]]]] 15>BKOVZcgnr!*.59JN]ajnw{ +/6];?F]KOV]cgnrz~ $(15<@IMVZaenry}*.7;DHQU^bsw #,07;LP_ctx #'04EIRV_clpy}  #'8<EIRV_clp!*.7;LPY]fjsw $(9=DHOSZ^mq !(,;?HLUY`dmqz~!%,0?C[_nry} "&/3:>GK\`gkz~#,0AEMQaenr{#+/>BKOX\mqx| $-18<MQZ^gkrv%):>GKRVgkz~!(,6:AEW[bfmq"&7;BFUYbfmq ,^0^@^D^T^X^_^c^r^v^} ^^ ^^^^^^^^^^^^^^^^ ^^^^(^,^3-8^<^C-H^L^S-X^\^c-p^t^^^^^^^^^^^^^^^^^^^^^^^$^(^9^=^D^H^W^[^c^g^n^r^{^^^^^^^^^^^^^^^^^^-^^- ^^-^!^(--^1^8-E^I^P-]^a^r^v^^^^^^^^^^^^^^^^^^^^^^ ^'^+^<^@^O^S^[^_^g^k^{^^^^^^^^^^^^^^^^^^````&`*`1`5`F`J`Q`U`d`h`q`u```````-``-```````````` `$`+`/`8`<`K`O`V`Z`c`g`n`r````````````````````````!`*`.`7`;`L`P`W-\```g-l`p`w-|``-``-````````````````0`4`;`?`N`R`[`_`f`j`{````````````bbbbbbbbbb"b&b/b3b:b>bObSb\b`bibmbvbzbbbbbbbbbbbbbdddddd dddd$d(d8d<dCdGdXd\dhdlddddddddddddddddddddd ddd#d/d3dGdKdRdVdhdldsdwddddddddddddddd dd(d,d4d8dHdLdSdWd_dcdjdndvdzdddddddddddddddddddd ddddd.d2d9d=dFdJdQdUd\d`dodsdzd~ddddddddddddddddddd(d,dHdLd[d_dfdjdqdud "/3;?QUbfuy]]]] '+2]7;B]OS\`qu#'.]37>]CGN][_hluy]!%,]9=FJ[_hl{")->BQUfjsw~ %)04;?FJY]eiqu}%)04=AJNUYaenr{ "+/8<EIZ^gktx *.=AHUYjn~q$(8<MQZ^eiz~ &*6:IMTXimtx  )-<@GKRV]apt} 15>BKOX\eiz~ !%6:CGNRcgpt   (,48HLUYjn] *.?COS\`osz]] $]15FJVZcgvz "&/3<@QU]aimuypppp #,09=FJ[_hlsw]] ]$(/3<@IMVZkox| +/6];?F]KOV]cgpt{]]] !%.2CGN]SW^]cgn]{ "+/8<MQZ^gk|#'04=APT]ajn   '+48?CTXaevz"&/3:>OSbfuy.29=DHW[bfnry} '+48IMTXgktGz~Gpppp$(/3BFRVeippuypp]] ]")-48GKTXgkrw{  ]   ] ! ( ]5 9 B F U Y ` ]e i p ]u y  ]               ]   ]   ]) - 6 : I M T ]Y ] d ]i m t ]                      ! ( p- 1 8 pE I R V e i p pu y  p       ]   ]         " 3 7 G K Z ^ e pj n u pz ~  p             p   p   p    % ) 2 6 = A P T [ ` d k p t {                    ]] $+]04;]HLS]X\c]hls]x|]] ]]&*16:AFJQ^bkox|]]pp pp'+2p7;BpOSZp_cjpw{ #'6:AELP_cjnvz%)0]59@]MQX\eipt}!%15>BQU\paelpy}&*26FJSWhluy !15FJSW^bsw '+48AEVZimvzfffffffffffff fff%f)f6f:fGfKfVfZfgfkfvfzffffffffffffffffff fff-f1fBfFfOfSfZf^fofsfffffffffffffffffffff*.59HhLhThXhdhhhthxhhhhhhhhhhhhhhhhhh hhh.h2h:h>hFhJhRhVhfhjhyh}hhhhhhhhhhhhhhhhhhh!h%h4h8hAhEhLhPhahehthxhhhhhhhhh ")-48?CRV]ako~kkkkkkkkkkk k(k,k4k8kHkLkYk]kjknkyk}kkkkkkkkkkkkkkkkkkkk!k(k,k=kAkPkTkekikrkvk}kkkkkkkkkkkkkkkk kkkk%k)k:k>kMQX\cgqu    & * 9 = D H R V e i z ~                   !! !$!+!/!6!:!A!E!L!P!W![!b!f!u!y!!!!!!!!!!!!!!!!!" """!"%"-"1"B"F"M"Q"Z"^"g"k"r"v"}"""""""""""""""""""# ###,#0#8#<#D#H#O#S#[#_#g#k#s#w###################$$$$)$-$7$;$E$I$_$c$l$p$z$~$$$$$$$$$$$$$$$%%%%%!%4%8%?%C%R%V%^%b%q%u%|%%%%%%%%%%%%%%%%%& & &&&+&/&D&H&Y&]&o&s&&&&&&&&&&&&&&&&&' '''%')'8'<'N'R'Y']'l'p'w'{''''''n'n'n'n'n'n'n'n'n'n'n(n(n (n(n(n((n,(n9(n=(nJ(nN(nY(n](nj(nn(ny(n}(n(n(n(n(n(n(n(n(n(n(n(n(n(n(n(n)n)n )n)n!)n0)n4)nE)nI)nR)nV)n])na)nr)nv)n)n)n)n)n)n)n)n)n)n)n)n)n)n)n)n)n*n *n*n*n-*1*E*I*P*\*`*o*s*z****]**************] ++++)+-+6+:+C+G+X+\+c+g+n+r++++++++++++++++++]+++],,,],,&,*,2,6,H,L,V,Z,i,m,|,,,,,,,,,,,,,,,,,,----#-'-6-:-A-F-J-Q-V-Z-a-n-r-y-}--------------]---]---] ...#.p'.p/.p3.p:.p>.pE.pI.pP.pT.p[.p_.pf.pj.pq.pu.p|.p.p.p.p.p.p.p.p.p.p.p.p.p.p.p.p.p.p/p/p/p/p$/p(/p4/p8/pI/pM/pT/pX/p`/pd/pu/py/p/p/p/p/p/p/p/p/p/p/p/p/p/p/p/p/p/p/p0p 0p0p0p-0p10p90p=0pE0pI0pQ0pU0pe0pi0pr0pv0p0p0p0p0p0p0p0p0p0p0p0p0p0p0p0p0p0p0p1p1p1p1p(1p,1p51p91pJ1pN1pW1p[1pl1pp1p1p1p1p1p1p1p1p1p1p1p1p1p1p1p1p1p1p1p2p 2p2p!2p*2p.2p?2pC2pL2pP2pa2pe2pl2pp2p2p2p2p2p2p2p2p2p2p2p2p2p2p2p2p2p3p 3p3p3p/3p33p;3p?3pG3pK3pS3pW3p_3pc3ps3pw3p3p3p3p3p3p3p3p3p3p3p3p3p3p3p3p3p3p3p3p3p3p3p4p4p4p4p4p4p.4p24p94>4pB4pI4N4pR4pY4f4pj4pr4pv4p~4p4p4p4p4p4p4p4p4p4p4p4p4p4p4p4p4p4p45p5p55p5p5+5p/5p65;5p?5pF5K5pO5pV5[5p_5pf5k5po5pv55p5p5p5p5p5p5p5p5p5p5p5p5p5p5p6p 6p6p6p6p#6p'6p06p46pE6pI6pW6p[6pb6pf6pn6pr6pz6p~6p6p6p6p6p6p6p6p6p6p6p6p6p6p6p6p6p6p6p7p7p7p7p#7p'7p.7p27p:7p>7pF7pJ7pR7pV7p^7pb7pj7pn7pv7pz7p7p7p7p7p7p7p7p7p7p7p7p7p7p7p7p7p7p7p7p8p8p8p8p 8p(8p,8p38p78p?8pC8pK8pO8pW8p[8pk8po8p~8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p9p 9p9p9p9p"9p29p69p=9pA9pI9pM9pU9pY9pa9pe9pm9pq9p9p9p9p9p9p9p9p9p9p9p9p9p9p9p9p9p9p9p9p9p:p:p:p:p:p#:p*:p.:p5:p9:p@:pD:pS:pW:p^:pb:pk:po:pv:pz:p:p:p:p:p:p:p:p:p:p:p:p:p:p:p:p:p:p:p:p;p;p;p;p";p2;p6;pE;pI;pP;pT;pc;pg;pn;pr;p{;p;p;p;p;p;p;p;p;p;p;p;p;p;p;p;p;p;p;p<p <p <p<p"<p1<p5<pE<pI<pY<p]<pd<ph<px<p|<p<p<p<p<p<p<p<p<p<p<p<p<p<p<p=p =p=p=p%=p)=p8=<=E=I=R=V=_=c=t=x=====================>> >]>>>]*>.>5>]B>F>M>Q>Y>]>o>s>}>>>>>>>>>>>>>>>>>>>>?????#?3?7?>?B?S?W?^?b?j?n????????????????????@@@@!@%@,@0@7@;@B@F@U@Y@`@]e@i@p@]}@@@]@@@@@@@@@@@@@@@@A AAAA$A(A1A5AFAJASAWA^AbAkAoAxA|AAAAAAAAAAAAAAAAAAAB BBB%B)B2B6B=BABJBNBWB[BdBhBqBuBBBBBBBBBBBBBBBBBBBBCCCC#C2C6C?CCCLCPCYC]CnCrC{CCCCCCCCCCCCCCCCCCDDDD.D2D;D?DFDJD[D_DnDrD{DDDDDDDrDrDrDrDrDrDrDrDrDrDrDrDrDr ErErErEr%Er)Er0Er4ErCErGErNErREr[Er_ErnErrEryEr}ErErErErErErErErErErErErErErErErEr FrFrFr#Fr,Fr0Fr7Fr;FrLFrPFr_FrcFrjFrnFr}FrFrFrFrFrFrFrFrFrFrFrFrFtFtFtFtFtFt Gt GtGtGt#Gt'Gt8GtVtBVtKVtOVtXVt\VtmVtqVtzVt~VtVtVtVtVtVtVtVtVtVtVtVtVtVtVtVtVtWtWtWtWt#Wt'Wt6Wt:WtCWtGWtPWtTWt]WtaWtjWtnWtWtWtWtWtWtWtWtWtWtWtWtWtWtWtWtWtWtXtXtXt'Xt+Xt3Xt7Xt>XtBXtJXtNXtWXt[XtjXtnXtuXtyXtXtXtXtXtXXXXXXXXXXXXXY YYYY"Y&Y5Y9YBYFYOYSYZY^YgYkY|YYYYYYYYYYYYYYYYYYZ ZZZ#Z'Z8Z]F]J]Y]]]d]h]w]{]]]]]]]]]]]]]]]]]]]]]^ ^^^$^(^7^;^L^P^Y^]^d^h^y^}^^^^^^^^^^^^^^^^^^^_ ___%_)_8_<_C_G_V_Z_a_e_m_q_x_|___________________````+`/`8`<`C`G`X`\`k`o`x`|``````v`v`v`v`v`v`v`v`v`v`v`v`vav avavavav*av.av5av9avBavFavUavYav`avdavsavwav~avavavavavavavavavavavavavavavav bvbvbvbv#bv'bv7bv;bvCbvGbvWbx[bxcbxgbxobxsbxbxbxbxbxbxbxbxbxbxbxbxbxbxbxbxbxbxbxcxcx cxcxcxcx%cx)cx:cx>cxEcxIcxPcxTcxccxgcxvcxzcxcxcxcxcxcxcxcxcxcxcxcxcxcxcxcxcxcxcxdx dxdxdx dx$dx-dx1dxBdxFdxWdx[dxddxhdxodxsdxdxdxdxdxdxdxdxdxdxdxdxdxdxdxdxdxdxdxexexexex&ex*ex2ex6exFexJexSexWex^exbexkexoexvexzexexexexexexexexexexexexexexexexex fxfxfx#fx4fx8fxIfxMfxVfxZfxafxefxnfxrfxfxfxfxfxfxfxfxfxfxfxfxfxfxfxfxfxfxfxgx gxgxgx%gx)gx:gx>gxGgxKgx\gx`gxigxmgx~gxgxgxgxgxgxgxgxgxgxgxgxgxgxgxgxgxhx hxhxhx hx3hx7hx?hxChxKhxOhxWhx[hxkhxohxwhx{hxhxhxhxhxhxhxhxhxhxhxhxhxhxhxhxhxhxhxhxhxhxix iixixiix"ix)i6ix:ixBixFixNixRixbixfixnixrixzix~ixixixixixixixixixixixiixixiixixiixixj jxjxjjxjx&j+jx/jx6j;jx?jxFjSjxWjx_jxcjxkjxojxjxjxjxjxjxjxjxjxjxjxjxjxjxjxjxjxjxkx kxkxkx#kx0kx4kx;kx?kxFkxJkxRkxVkx^kxbkxjkxnkxukxykxkxkxkxkxkxkxkxkxkxkxkxkxkxkxkxkxkxkxkxkxlx lxlxlx$lx(lx8lxrxBrxRrxVrxfrjrsrwrrrrrrrrrrrrrrrrrrrrrssss"s&s-s1s8svEvIvRvVv_vcvlvpvyv}vvvvvvvvvvvvvvvvvvvvvwwww(w,w3w7w@wDwMwQwZw^wgwkw|wwwwwwwwwwwwwwwwwwwwxxxxxx'x+x2x6x?xCxLxPxWx[xdxhxoxsxxxxxxxxxxxxxxxxxxxyyyyyy(y,y5y9yByFyOySy\y`yiymyvyzyyyyyyyyyyyyyyyyyyyyy zzzz+z/z@zDzMzQzXz\zmzqzzzzzzzzzzzzzzzzzzzz{ {{{{,{0{9{={F{J{S{W{`{d{m{q{{{{{{{{{{{{{{{{{{{{| ||||&|*|3|7|@|D|M|Q|Z|^|g|k|t|x||||||||||||||||||| }}}#},}0}7};}L}P}_}c}l}p}y}}}}}}}}}}}}}}}}}}}}}~~~~~!~*~.~?~C~L~P~Y~]~f~j~s~w~~~~~~~~~~~~~~~~~~~  #'04=AJNW[dhy}/3BFW[dhos€ˀπ؀܀ !%.2CGNRaenr{āȁсՁށ +/8<EIRV_ctxȂ̂Ղق&*;?FJY]dqu}Ãǃ؃܃ &*9=EIQUeix|Ʉ̈́քڄ  "+/6:KO^bivząȅхՅޅ $(8<C]PT]apt}Ɔʆӆ׆ ]"+/>BI]VZcgvz‡Ƈ·҇ڇއ "*.>BKOVZcgpt{ĈՈو $-1:>EIRVgktxʉΉ߉ -1:>OSZ^mqz~ÊNJ؊܊ (,48@DLP`dkox|Njˋҋ֋"&7;BFUYbfw{Ɍ͌֌ڌ  "+/6:KO^ybyi myqyxyy yyyy ( 0 8@HPX`hpx "$&(*,.02468;=?ACEG I(K0M8O@QHSPUXW`Yh[p_xagikmouw~9 (08@HPX`hpx (08@HPX`hpx   "$&(*,.025 :(M0O8Q@SH[P^X``bhdpfxhknprtvxy  $048<@DPTX\`dptx|(,048<HLPT`dhlptx|ggggggggiiiiiii iii i$i(i,i8i<i@iDiPkTkXk\khklkpktkkkkkmmmmmmmmmmmmoooooooo $(,8<@DHLPTX\hlptx|  $(,04@DHLX\`dhlx| $048<@DPTX\`dptx|uuuuuuuu  $(,04@DHLX\`dptx| $048<HLPT`dhlx|wwwwwwwwwwwwwwwwwwwwwwwwww(w,w0w4w@DHLPT`dhlx|      ( , 0 4 8 < H L P T ` d h l p t                              $ ( , 0 4 @ D H L X \ ` d h l x |                               ( , 0 4 @ D H L X \ ` d p t x |                             ( , 0 4 @ D H L X \ ` d h l x |                            $ ( , 8 < @ D P T X \ h l p t                       (,048<HLPT`dhlptx| (,048<HLPTX\hlpt  $(,8<@DPTX\`dptx|  $048<HLPT`dhlx|~~~~~~~~~~~~~~~~~~~~(~,~0~4~@~D~H~L~X~\~`~d~ptx|  $048<@DPTX\`dptx|  $(,8<@DPTX\`dhlx|(,04@DHLX\`dptx|(,04@DHLX\`dhlptx| (,048<HLPTX\hlpt (,048<HLPT`dhlx|(,04@DHLX\`dhlx|  $(,8<@DPTX\hlptx|  $(,04@DHLX\`dhlx|  $048<@DPTX\`dptx|(,04@DHLPT`dhlx|(,04@DHLX\`dptx|  $048<HLPT`dhlpt       $ ( , 0 4 8 < H L P T X \ ` d p t x |                       !!!!!! !$!0!4!8!>> >>> >$>(>,>0>4>@>D>H>L>P>T>X>\>h>l>p>t>>>>>>>>>>>>>>>>>>>>>>>>>>>? ?????(?,?0?4?8?>>>>>(>,>0>4>@>D>H>L>X>\>`>d>p>t>x>|>>>>>>>>>>>>>>>>>>>>>>>? ?????(?,?0?4?@?D?H?L?X?\?`?d?p?t?x?|?????????????????????????@@@@@@ @$@(@,@8@<@@@D@H@L@P@T@X@\@h@l@p@t@x@|@@@@@@@@@@@@@@@@@@@@@@@@@A AAA A$A(A,A8A,|(P "F$}&3(d*,.025K:WMnOQ S2[^`zbdyfhkjnprmtvx y 4H \ p$ 8"L$`&t(*,.02468(<Pl;=?A$8LC`EtGIKMOQSUW(Y<[[ py\_a<tT4l<p D gd i k m oX a \  l uu \  \   \@       , H ` x      Dpy\(Lpy\w\$Lt4l8\p\\$Hl4Tt\\H$8L`t $<Tl$8\p~h|4Hlu\ @Th|(Hh   \  \ !)!\d!m!\!!\!!\""\T"h""""<#h###\$4$`$$$,%&8&L&x&&\&&\&9&\('1'\l'u'\''\''\8((((\) )\L)U)\))\))\))\0*9*\l*u*\**\*+H+Q+\++\++\++\$,-,\X,a,\,,\,,\- -\8-X---\--\..\L.U.\..D/|////\0090\h0q0\01H1111\12\42=2\l2u2\22\22\33\H3Q3\t3}3\33\33\44\H4Q4\44\44\5%5\X5a5\55\55\6<6\6e6\66\66\7!7\X7a7\77\77\8 8\t8}8\88\88\(919\\9e9\99\99\$:-:\\:e:\::\::\;%;\\;e;\;;\;;\<%<\d<m<\<<\<<\,=5=\t=}=\==\> >\D>M>\|>>\>>\>>\8?A?\??\??\@@\H@Q@\@@\@@\@@\ A)A\XAaA\AA\AA\BHBtB}B\BBCC\hCCCC\D4D`DiD\DD\DD\E!E\PEYE\EE\EE\F!F\`FFF\FGG\TG]G\GG\GGDHHH\HHH\II!I\\IpIII\II\4JXJaJ\JJJ\K(K1K\`KiK\KL LL \MeM\MMM # endif // GTEST_OS_MAC # include # include # include # if GTEST_OS_LINUX # include # endif // GTEST_OS_LINUX # include # if GTEST_OS_WINDOWS # include # else # include # include # endif // GTEST_OS_WINDOWS # if GTEST_OS_QNX # include # endif // GTEST_OS_QNX #endif // GTEST_HAS_DEATH_TEST #include "gtest/gtest-message.h" #include "gtest/internal/gtest-string.h" // Indicates that this translation unit is part of Google Test's // implementation. It must come before gtest-internal-inl.h is // included, or there will be a compiler error. This trick is to // prevent a user from accidentally including gtest-internal-inl.h in // his code. #define GTEST_IMPLEMENTATION_ 1 #include "src/gtest-internal-inl.h" #undef GTEST_IMPLEMENTATION_ namespace testing { // Constants. // The default death test style. static const char kDefaultDeathTestStyle[] = "fast"; GTEST_DEFINE_string_( death_test_style, internal::StringFromGTestEnv("death_test_style", kDefaultDeathTestStyle), "Indicates how to run a death test in a forked child process: " "\"threadsafe\" (child process re-executes the test binary " "from the beginning, running only the specific death test) or " "\"fast\" (child process runs the death test immediately " "after forking)."); GTEST_DEFINE_bool_( death_test_use_fork, internal::BoolFromGTestEnv("death_test_use_fork", false), "Instructs to use fork()/_exit() instead of clone() in death tests. " "Ignored and always uses fork() on POSIX systems where clone() is not " "implemented. Useful when running under valgrind or similar tools if " "those do not support clone(). Valgrind 3.3.1 will just fail if " "it sees an unsupported combination of clone() flags. " "It is not recommended to use this flag w/o valgrind though it will " "work in 99% of the cases. Once valgrind is fixed, this flag will " "most likely be removed."); namespace internal { GTEST_DEFINE_string_( internal_run_death_test, "", "Indicates the file, line number, temporal index of " "the single death test to run, and a file descriptor to " "which a success code may be sent, all separated by " "the '|' characters. This flag is specified if and only if the current " "process is a sub-process launched for running a thread-safe " "death test. FOR INTERNAL USE ONLY."); } // namespace internal #if GTEST_HAS_DEATH_TEST namespace internal { // Valid only for fast death tests. Indicates the code is running in the // child process of a fast style death test. static bool g_in_fast_death_test_child = false; // Returns a Boolean value indicating whether the caller is currently // executing in the context of the death test child process. Tools such as // Valgrind heap checkers may need this to modify their behavior in death // tests. IMPORTANT: This is an internal utility. Using it may break the // implementation of death tests. User code MUST NOT use it. bool InDeathTestChild() { # if GTEST_OS_WINDOWS // On Windows, death tests are thread-safe regardless of the value of the // death_test_style flag. return !GTEST_FLAG(internal_run_death_test).empty(); # else if (GTEST_FLAG(death_test_style) == "threadsafe") return !GTEST_FLAG(internal_run_death_test).empty(); else return g_in_fast_death_test_child; #endif } } // namespace internal // ExitedWithCode constructor. ExitedWithCode::ExitedWithCode(int exit_code) : exit_code_(exit_code) { } // ExitedWithCode function-call operator. bool ExitedWithCode::operator()(int exit_status) const { # if GTEST_OS_WINDOWS return exit_status == exit_code_; # else return WIFEXITED(exit_status) && WEXITSTATUS(exit_status) == exit_code_; # endif // GTEST_OS_WINDOWS } # if !GTEST_OS_WINDOWS // KilledBySignal constructor. KilledBySignal::KilledBySignal(int signum) : signum_(signum) { } // KilledBySignal function-call operator. bool KilledBySignal::operator()(int exit_status) const { return WIFSIGNALED(exit_status) && WTERMSIG(exit_status) == signum_; } # endif // !GTEST_OS_WINDOWS namespace internal { // Utilities needed for death tests. // Generates a textual description of a given exit code, in the format // specified by wait(2). static std::string ExitSummary(int exit_code) { Message m; # if GTEST_OS_WINDOWS m << "Exited with exit status " << exit_code; # else if (WIFEXITED(exit_code)) { m << "Exited with exit status " << WEXITSTATUS(exit_code); } else if (WIFSIGNALED(exit_code)) { m << "Terminated by signal " << WTERMSIG(exit_code); } # ifdef WCOREDUMP if (WCOREDUMP(exit_code)) { m << " (core dumped)"; } # endif # endif // GTEST_OS_WINDOWS return m.GetString(); } // Returns true if exit_status describes a process that was terminated // by a signal, or exited normally with a nonzero exit code. bool ExitedUnsuccessfully(int exit_status) { return !ExitedWithCode(0)(exit_status); } # if !GTEST_OS_WINDOWS // Generates a textual failure message when a death test finds more than // one thread running, or cannot determine the number of threads, prior // to executing the given statement. It is the responsibility of the // caller not to pass a thread_count of 1. static std::string DeathTestThreadWarning(size_t thread_count) { Message msg; msg << "Death tests use fork(), which is unsafe particularly" << " in a threaded context. For this test, " << GTEST_NAME_ << " "; if (thread_count == 0) msg << "couldn't detect the number of threads."; else msg << "detected " << thread_count << " threads."; return msg.GetString(); } # endif // !GTEST_OS_WINDOWS // Flag characters for reporting a death test that did not die. static const char kDeathTestLived = 'L'; static const char kDeathTestReturned = 'R'; static const char kDeathTestThrew = 'T'; static const char kDeathTestInternalError = 'I'; // An enumeration describing all of the possible ways that a death test can // conclude. DIED means that the process died while executing the test // code; LIVED means that process lived beyond the end of the test code; // RETURNED means that the test statement attempted to execute a return // statement, which is not allowed; THREW means that the test statement // returned control by throwing an exception. IN_PROGRESS means the test // has not yet concluded. // TODO(vladl@google.com): Unify names and possibly values for // AbortReason, DeathTestOutcome, and flag characters above. enum DeathTestOutcome { IN_PROGRESS, DIED, LIVED, RETURNED, THREW }; // Routine for aborting the program which is safe to call from an // exec-style death test child process, in which case the error // message is propagated back to the parent process. Otherwise, the // message is simply printed to stderr. In either case, the program // then exits with status 1. void DeathTestAbort(const std::string& message) { // On a POSIX system, this function may be called from a threadsafe-style // death test child process, which operates on a very small stack. Use // the heap for any additional non-minuscule memory requirements. const InternalRunDeathTestFlag* const flag = GetUnitTestImpl()->internal_run_death_test_flag(); if (flag != NULL) { FILE* parent = posix::FDOpen(flag->write_fd(), "w"); fputc(kDeathTestInternalError, parent); fprintf(parent, "%s", message.c_str()); fflush(parent); _exit(1); } else { fprintf(stderr, "%s", message.c_str()); fflush(stderr); posix::Abort(); } } // A replacement for CHECK that calls DeathTestAbort if the assertion // fails. # define GTEST_DEATH_TEST_CHECK_(expression) \ do { \ if (!::testing::internal::IsTrue(expression)) { \ DeathTestAbort( \ ::std::string("CHECK failed: File ") + __FILE__ + ", line " \ + ::testing::internal::StreamableToString(__LINE__) + ": " \ + #expression); \ } \ } while (::testing::internal::AlwaysFalse()) // This macro is similar to GTEST_DEATH_TEST_CHECK_, but it is meant for // evaluating any system call that fulfills two conditions: it must return // -1 on failure, and set errno to EINTR when it is interrupted and // should be tried again. The macro expands to a loop that repeatedly // evaluates the expression as long as it evaluates to -1 and sets // errno to EINTR. If the expression evaluates to -1 but errno is // something other than EINTR, DeathTestAbort is called. # define GTEST_DEATH_TEST_CHECK_SYSCALL_(expression) \ do { \ int gtest_retval; \ do { \ gtest_retval = (expression); \ } while (gtest_retval == -1 && errno == EINTR); \ if (gtest_retval == -1) { \ DeathTestAbort( \ ::std::string("CHECK failed: File ") + __FILE__ + ", line " \ + ::testing::internal::StreamableToString(__LINE__) + ": " \ + #expression + " != -1"); \ } \ } while (::testing::internal::AlwaysFalse()) // Returns the message describing the last system error in errno. std::string GetLastErrnoDescription() { return errno == 0 ? "" : posix::StrError(errno); } // This is called from a death test parent process to read a failure // message from the death test child process and log it with the FATAL // severity. On Windows, the message is read from a pipe handle. On other // platforms, it is read from a file descriptor. static void FailFromInternalError(int fd) { Message error; char buffer[256]; int num_read; do { while ((num_read = posix::Read(fd, buffer, 255)) > 0) { buffer[num_read] = '\0'; error << buffer; } } while (num_read == -1 && errno == EINTR); if (num_read == 0) { GTEST_LOG_(FATAL) << error.GetString(); } else { const int last_error = errno; GTEST_LOG_(FATAL) << "Error while reading death test internal: " << GetLastErrnoDescription() << " [" << last_error << "]"; } } // Death test constructor. Increments the running death test count // for the current test. DeathTest::DeathTest() { TestInfo* const info = GetUnitTestImpl()->current_test_info(); if (info == NULL) { DeathTestAbort("Cannot run a death test outside of a TEST or " "TEST_F construct"); } } // Creates and returns a death test by dispatching to the current // death test factory. bool DeathTest::Create(const char* statement, const RE* regex, const char* file, int line, DeathTest** test) { return GetUnitTestImpl()->death_test_factory()->Create( statement, regex, file, line, test); } const char* DeathTest::LastMessage() { return last_death_test_message_.c_str(); } void DeathTest::set_last_death_test_message(const std::string& message) { last_death_test_message_ = message; } std::string DeathTest::last_death_test_message_; // Provides cross platform implementation for some death functionality. class DeathTestImpl : public DeathTest { protected: DeathTestImpl(const char* a_statement, const RE* a_regex) : statement_(a_statement), regex_(a_regex), spawned_(false), status_(-1), outcome_(IN_PROGRESS), read_fd_(-1), write_fd_(-1) {} // read_fd_ is expected to be closed and cleared by a derived class. ~DeathTestImpl() { GTEST_DEATH_TEST_CHECK_(read_fd_ == -1); } void Abort(AbortReason reason); virtual bool Passed(bool status_ok); const char* statement() const { return statement_; } const RE* regex() const { return regex_; } bool spawned() const { return spawned_; } void set_spawned(bool is_spawned) { spawned_ = is_spawned; } int status() const { return status_; } void set_status(int a_status) { status_ = a_status; } DeathTestOutcome outcome() const { return outcome_; } void set_outcome(DeathTestOutcome an_outcome) { outcome_ = an_outcome; } int read_fd() const { return read_fd_; } void set_read_fd(int fd) { read_fd_ = fd; } int write_fd() const { return write_fd_; } void set_write_fd(int fd) { write_fd_ = fd; } // Called in the parent process only. Reads the result code of the death // test child process via a pipe, interprets it to set the outcome_ // member, and closes read_fd_. Outputs diagnostics and terminates in // case of unexpected codes. void ReadAndInterpretStatusByte(); private: // The textual content of the code this object is testing. This class // doesn't own this string and should not attempt to delete it. const char* const statement_; // The regular expression which test output must match. DeathTestImpl // doesn't own this object and should not attempt to delete it. const RE* const regex_; // True if the death test child process has been successfully spawned. bool spawned_; // The exit status of the child process. int status_; // How the death test concluded. DeathTestOutcome outcome_; // Descriptor to the read end of the pipe to the child process. It is // always -1 in the child process. The child keeps its write end of the // pipe in write_fd_. int read_fd_; // Descriptor to the child's write end of the pipe to the parent process. // It is always -1 in the parent process. The parent keeps its end of the // pipe in read_fd_. int write_fd_; }; // Called in the parent process only. Reads the result code of the death // test child process via a pipe, interprets it to set the outcome_ // member, and closes read_fd_. Outputs diagnostics and terminates in // case of unexpected codes. void DeathTestImpl::ReadAndInterpretStatusByte() { char flag; int bytes_read; // The read() here blocks until data is available (signifying the // failure of the death test) or until the pipe is closed (signifying // its success), so it's okay to call this in the parent before // the child process has exited. do { bytes_read = posix::Read(read_fd(), &flag, 1); } while (bytes_read == -1 && errno == EINTR); if (bytes_read == 0) { set_outcome(DIED); } else if (bytes_read == 1) { switch (flag) { case kDeathTestReturned: set_outcome(RETURNED); break; case kDeathTestThrew: set_outcome(THREW); break; case kDeathTestLived: set_outcome(LIVED); break; case kDeathTestInternalError: FailFromInternalError(read_fd()); // Does not return. break; default: GTEST_LOG_(FATAL) << "Death test child process reported " << "unexpected status byte (" << static_cast(flag) << ")"; } } else { GTEST_LOG_(FATAL) << "Read from death test child process failed: " << GetLastErrnoDescription(); } GTEST_DEATH_TEST_CHECK_SYSCALL_(posix::Close(read_fd())); set_read_fd(-1); } // Signals that the death test code which should have exited, didn't. // Should be called only in a death test child process. // Writes a status byte to the child's status file descriptor, then // calls _exit(1). void DeathTestImpl::Abort(AbortReason reason) { // The parent process considers the death test to be a failure if // it finds any data in our pipe. So, here we write a single flag byte // to the pipe, then exit. const char status_ch = reason == TEST_DID_NOT_DIE ? kDeathTestLived : reason == TEST_THREW_EXCEPTION ? kDeathTestThrew : kDeathTestReturned; GTEST_DEATH_TEST_CHECK_SYSCALL_(posix::Write(write_fd(), &status_ch, 1)); // We are leaking the descriptor here because on some platforms (i.e., // when built as Windows DLL), destructors of global objects will still // run after calling _exit(). On such systems, write_fd_ will be // indirectly closed from the destructor of UnitTestImpl, causing double // close if it is also closed here. On debug configurations, double close // may assert. As there are no in-process buffers to flush here, we are // relying on the OS to close the descriptor after the process terminates // when the destructors are not run. _exit(1); // Exits w/o any normal exit hooks (we were supposed to crash) } // Returns an indented copy of stderr output for a death test. // This makes distinguishing death test output lines from regular log lines // much easier. static ::std::string FormatDeathTestOutput(const ::std::string& output) { ::std::string ret; for (size_t at = 0; ; ) { const size_t line_end = output.find('\n', at); ret += "[ DEATH ] "; if (line_end == ::std::string::npos) { ret += output.substr(at); break; } ret += output.substr(at, line_end + 1 - at); at = line_end + 1; } return ret; } // Assesses the success or failure of a death test, using both private // members which have previously been set, and one argument: // // Private data members: // outcome: An enumeration describing how the death test // concluded: DIED, LIVED, THREW, or RETURNED. The death test // fails in the latter three cases. // status: The exit status of the child process. On *nix, it is in the // in the format specified by wait(2). On Windows, this is the // value supplied to the ExitProcess() API or a numeric code // of the exception that terminated the program. // regex: A regular expression object to be applied to // the test's captured standard error output; the death test // fails if it does not match. // // Argument: // status_ok: true if exit_status is acceptable in the context of // this particular death test, which fails if it is false // // Returns true iff all of the above conditions are met. Otherwise, the // first failing condition, in the order given above, is the one that is // reported. Also sets the last death test message string. bool DeathTestImpl::Passed(bool status_ok) { if (!spawned()) return false; const std::string error_message = GetCapturedStderr(); bool success = false; Message buffer; buffer << "Death test: " << statement() << "\n"; switch (outcome()) { case LIVED: buffer << " Result: failed to die.\n" << " Error msg:\n" << FormatDeathTestOutput(error_message); break; case THREW: buffer << " Result: threw an exception.\n" << " Error msg:\n" << FormatDeathTestOutput(error_message); break; case RETURNED: buffer << " Result: illegal return in test statement.\n" << " Error msg:\n" << FormatDeathTestOutput(error_message); break; case DIED: if (status_ok) { const bool matched = RE::PartialMatch(error_message.c_str(), *regex()); if (matched) { success = true; } else { buffer << " Result: died but not with expected error.\n" << " Expected: " << regex()->pattern() << "\n" << "Actual msg:\n" << FormatDeathTestOutput(error_message); } } else { buffer << " Result: died but not with expected exit code:\n" << " " << ExitSummary(status()) << "\n" << "Actual msg:\n" << FormatDeathTestOutput(error_message); } break; case IN_PROGRESS: default: GTEST_LOG_(FATAL) << "DeathTest::Passed somehow called before conclusion of test"; } DeathTest::set_last_death_test_message(buffer.GetString()); return success; } # if GTEST_OS_WINDOWS // WindowsDeathTest implements death tests on Windows. Due to the // specifics of starting new processes on Windows, death tests there are // always threadsafe, and Google Test considers the // --gtest_death_test_style=fast setting to be equivalent to // --gtest_death_test_style=threadsafe there. // // A few implementation notes: Like the Linux version, the Windows // implementation uses pipes for child-to-parent communication. But due to // the specifics of pipes on Windows, some extra steps are required: // // 1. The parent creates a communication pipe and stores handles to both // ends of it. // 2. The parent starts the child and provides it with the information // necessary to acquire the handle to the write end of the pipe. // 3. The child acquires the write end of the pipe and signals the parent // using a Windows event. // 4. Now the parent can release the write end of the pipe on its side. If // this is done before step 3, the object's reference count goes down to // 0 and it is destroyed, preventing the child from acquiring it. The // parent now has to release it, or read operations on the read end of // the pipe will not return when the child terminates. // 5. The parent reads child's output through the pipe (outcome code and // any possible error messages) from the pipe, and its stderr and then // determines whether to fail the test. // // Note: to distinguish Win32 API calls from the local method and function // calls, the former are explicitly resolved in the global namespace. // class WindowsDeathTest : public DeathTestImpl { public: WindowsDeathTest(const char* a_statement, const RE* a_regex, const char* file, int line) : DeathTestImpl(a_statement, a_regex), file_(file), line_(line) {} // All of these virtual functions are inherited from DeathTest. virtual int Wait(); virtual TestRole AssumeRole(); private: // The name of the file in which the death test is located. const char* const file_; // The line number on which the death test is located. const int line_; // Handle to the write end of the pipe to the child process. AutoHandle write_handle_; // Child process handle. AutoHandle child_handle_; // Event the child process uses to signal the parent that it has // acquired the handle to the write end of the pipe. After seeing this // event the parent can release its own handles to make sure its // ReadFile() calls return when the child terminates. AutoHandle event_handle_; }; // Waits for the child in a death test to exit, returning its exit // status, or 0 if no child process exists. As a side effect, sets the // outcome data member. int WindowsDeathTest::Wait() { if (!spawned()) return 0; // Wait until the child either signals that it has acquired the write end // of the pipe or it dies. const HANDLE wait_handles[2] = { child_handle_.Get(), event_handle_.Get() }; switch (::WaitForMultipleObjects(2, wait_handles, FALSE, // Waits for any of the handles. INFINITE)) { case WAIT_OBJECT_0: case WAIT_OBJECT_0 + 1: break; default: GTEST_DEATH_TEST_CHECK_(false); // Should not get here. } // The child has acquired the write end of the pipe or exited. // We release the handle on our side and continue. write_handle_.Reset(); event_handle_.Reset(); ReadAndInterpretStatusByte(); // Waits for the child process to exit if it haven't already. This // returns immediately if the child has already exited, regardless of // whether previous calls to WaitForMultipleObjects synchronized on this // handle or not. GTEST_DEATH_TEST_CHECK_( WAIT_OBJECT_0 == ::WaitForSingleObject(child_handle_.Get(), INFINITE)); DWORD status_code; GTEST_DEATH_TEST_CHECK_( ::GetExitCodeProcess(child_handle_.Get(), &status_code) != FALSE); child_handle_.Reset(); set_status(static_cast(status_code)); return status(); } // The AssumeRole process for a Windows death test. It creates a child // process with the same executable as the current process to run the // death test. The child process is given the --gtest_filter and // --gtest_internal_run_death_test flags such that it knows to run the // current death test only. DeathTest::TestRole WindowsDeathTest::AssumeRole() { const UnitTestImpl* const impl = GetUnitTestImpl(); const InternalRunDeathTestFlag* const flag = impl->internal_run_death_test_flag(); const TestInfo* const info = impl->current_test_info(); const int death_test_index = info->result()->death_test_count(); if (flag != NULL) { // ParseInternalRunDeathTestFlag() has performed all the necessary // processing. set_write_fd(flag->write_fd()); return EXECUTE_TEST; } // WindowsDeathTest uses an anonymous pipe to communicate results of // a death test. SECURITY_ATTRIBUTES handles_are_inheritable = { sizeof(SECURITY_ATTRIBUTES), NULL, TRUE }; HANDLE read_handle, write_handle; GTEST_DEATH_TEST_CHECK_( ::CreatePipe(&read_handle, &write_handle, &handles_are_inheritable, 0) // Default buffer size. != FALSE); set_read_fd(::_open_osfhandle(reinterpret_cast(read_handle), O_RDONLY)); write_handle_.Reset(write_handle); event_handle_.Reset(::CreateEvent( &handles_are_inheritable, TRUE, // The event will automatically reset to non-signaled state. FALSE, // The initial state is non-signalled. NULL)); // The even is unnamed. GTEST_DEATH_TEST_CHECK_(event_handle_.Get() != NULL); const std::string filter_flag = std::string("--") + GTEST_FLAG_PREFIX_ + kFilterFlag + "=" + info->test_case_name() + "." + info->name(); const std::string internal_flag = std::string("--") + GTEST_FLAG_PREFIX_ + kInternalRunDeathTestFlag + "=" + file_ + "|" + StreamableToString(line_) + "|" + StreamableToString(death_test_index) + "|" + StreamableToString(static_cast(::GetCurrentProcessId())) + // size_t has the same width as pointers on both 32-bit and 64-bit // Windows platforms. // See http://msdn.microsoft.com/en-us/library/tcxf1dw6.aspx. "|" + StreamableToString(reinterpret_cast(write_handle)) + "|" + StreamableToString(reinterpret_cast(event_handle_.Get())); char executable_path[_MAX_PATH + 1]; // NOLINT GTEST_DEATH_TEST_CHECK_( _MAX_PATH + 1 != ::GetModuleFileNameA(NULL, executable_path, _MAX_PATH)); std::string command_line = std::string(::GetCommandLineA()) + " " + filter_flag + " \"" + internal_flag + "\""; DeathTest::set_last_death_test_message(""); CaptureStderr(); // Flush the log buffers since the log streams are shared with the child. FlushInfoLog(); // The child process will share the standard handles with the parent. STARTUPINFOA startup_info; memset(&startup_info, 0, sizeof(STARTUPINFO)); startup_info.dwFlags = STARTF_USESTDHANDLES; startup_info.hStdInput = ::GetStdHandle(STD_INPUT_HANDLE); startup_info.hStdOutput = ::GetStdHandle(STD_OUTPUT_HANDLE); startup_info.hStdError = ::GetStdHandle(STD_ERROR_HANDLE); PROCESS_INFORMATION process_info; GTEST_DEATH_TEST_CHECK_(::CreateProcessA( executable_path, const_cast(command_line.c_str()), NULL, // Retuned process handle is not inheritable. NULL, // Retuned thread handle is not inheritable. TRUE, // Child inherits all inheritable handles (for write_handle_). 0x0, // Default creation flags. NULL, // Inherit the parent's environment. UnitTest::GetInstance()->original_working_dir(), &startup_info, &process_info) != FALSE); child_handle_.Reset(process_info.hProcess); ::CloseHandle(process_info.hThread); set_spawned(true); return OVERSEE_TEST; } # else // We are not on Windows. // ForkingDeathTest provides implementations for most of the abstract // methods of the DeathTest interface. Only the AssumeRole method is // left undefined. class ForkingDeathTest : public DeathTestImpl { public: ForkingDeathTest(const char* statement, const RE* regex); // All of these virtual functions are inherited from DeathTest. virtual int Wait(); protected: void set_child_pid(pid_t child_pid) { child_pid_ = child_pid; } private: // PID of child process during death test; 0 in the child process itself. pid_t child_pid_; }; // Constructs a ForkingDeathTest. ForkingDeathTest::ForkingDeathTest(const char* a_statement, const RE* a_regex) : DeathTestImpl(a_statement, a_regex), child_pid_(-1) {} // Waits for the child in a death test to exit, returning its exit // status, or 0 if no child process exists. As a side effect, sets the // outcome data member. int ForkingDeathTest::Wait() { if (!spawned()) return 0; ReadAndInterpretStatusByte(); int status_value; GTEST_DEATH_TEST_CHECK_SYSCALL_(waitpid(child_pid_, &status_value, 0)); set_status(status_value); return status_value; } // A concrete death test class that forks, then immediately runs the test // in the child process. class NoExecDeathTest : public ForkingDeathTest { public: NoExecDeathTest(const char* a_statement, const RE* a_regex) : ForkingDeathTest(a_statement, a_regex) { } virtual TestRole AssumeRole(); }; // The AssumeRole process for a fork-and-run death test. It implements a // straightforward fork, with a simple pipe to transmit the status byte. DeathTest::TestRole NoExecDeathTest::AssumeRole() { const size_t thread_count = GetThreadCount(); if (thread_count != 1) { GTEST_LOG_(WARNING) << DeathTestThreadWarning(thread_count); } int pipe_fd[2]; GTEST_DEATH_TEST_CHECK_(pipe(pipe_fd) != -1); DeathTest::set_last_death_test_message(""); CaptureStderr(); // When we fork the process below, the log file buffers are copied, but the // file descriptors are shared. We flush all log files here so that closing // the file descriptors in the child process doesn't throw off the // synchronization between descriptors and buffers in the parent process. // This is as close to the fork as possible to avoid a race condition in case // there are multiple threads running before the death test, and another // thread writes to the log file. FlushInfoLog(); const pid_t child_pid = fork(); GTEST_DEATH_TEST_CHECK_(child_pid != -1); set_child_pid(child_pid); if (child_pid == 0) { GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[0])); set_write_fd(pipe_fd[1]); // Redirects all logging to stderr in the child process to prevent // concurrent writes to the log files. We capture stderr in the parent // process and append the child process' output to a log. LogToStderr(); // Event forwarding to the listeners of event listener API mush be shut // down in death test subprocesses. GetUnitTestImpl()->listeners()->SuppressEventForwarding(); g_in_fast_death_test_child = true; return EXECUTE_TEST; } else { GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[1])); set_read_fd(pipe_fd[0]); set_spawned(true); return OVERSEE_TEST; } } // A concrete death test class that forks and re-executes the main // program from the beginning, with command-line flags set that cause // only this specific death test to be run. class ExecDeathTest : public ForkingDeathTest { public: ExecDeathTest(const char* a_statement, const RE* a_regex, const char* file, int line) : ForkingDeathTest(a_statement, a_regex), file_(file), line_(line) { } virtual TestRole AssumeRole(); private: static ::std::vector GetArgvsForDeathTestChildProcess() { ::std::vector args = GetInjectableArgvs(); return args; } // The name of the file in which the death test is located. const char* const file_; // The line number on which the death test is located. const int line_; }; // Utility class for accumulating command-line arguments. class Arguments { public: Arguments() { args_.push_back(NULL); } ~Arguments() { for (std::vector::iterator i = args_.begin(); i != args_.end(); ++i) { free(*i); } } void AddArgument(const char* argument) { args_.insert(args_.end() - 1, posix::StrDup(argument)); } template void AddArguments(const ::std::vector& arguments) { for (typename ::std::vector::const_iterator i = arguments.begin(); i != arguments.end(); ++i) { args_.insert(args_.end() - 1, posix::StrDup(i->c_str())); } } char* const* Argv() { return &args_[0]; } private: std::vector args_; }; // A struct that encompasses the arguments to the child process of a // threadsafe-style death test process. struct ExecDeathTestArgs { char* const* argv; // Command-line arguments for the child's call to exec int close_fd; // File descriptor to close; the read end of a pipe }; # if GTEST_OS_MAC inline char** GetEnviron() { // When Google Test is built as a framework on MacOS X, the environ variable // is unavailable. Apple's documentation (man environ) recommends using // _NSGetEnviron() instead. return *_NSGetEnviron(); } # else // Some POSIX platforms expect you to declare environ. extern "C" makes // it reside in the global namespace. extern "C" char** environ; inline char** GetEnviron() { return environ; } # endif // GTEST_OS_MAC # if !GTEST_OS_QNX // The main function for a threadsafe-style death test child process. // This function is called in a clone()-ed process and thus must avoid // any potentially unsafe operations like malloc or libc functions. static int ExecDeathTestChildMain(void* child_arg) { ExecDeathTestArgs* const args = static_cast(child_arg); GTEST_DEATH_TEST_CHECK_SYSCALL_(close(args->close_fd)); // We need to execute the test program in the same environment where // it was originally invoked. Therefore we change to the original // working directory first. const char* const original_dir = UnitTest::GetInstance()->original_working_dir(); // We can safely call chdir() as it's a direct system call. if (chdir(original_dir) != 0) { DeathTestAbort(std::string("chdir(\"") + original_dir + "\") failed: " + GetLastErrnoDescription()); return EXIT_FAILURE; } // We can safely call execve() as it's a direct system call. We // cannot use execvp() as it's a libc function and thus potentially // unsafe. Since execve() doesn't search the PATH, the user must // invoke the test program via a valid path that contains at least // one path separator. execve(args->argv[0], args->argv, GetEnviron()); DeathTestAbort(std::string("execve(") + args->argv[0] + ", ...) in " + original_dir + " failed: " + GetLastErrnoDescription()); return EXIT_FAILURE; } # endif // !GTEST_OS_QNX // Two utility routines that together determine the direction the stack // grows. // This could be accomplished more elegantly by a single recursive // function, but we want to guard against the unlikely possibility of // a smart compiler optimizing the recursion away. // // GTEST_NO_INLINE_ is required to prevent GCC 4.6 from inlining // StackLowerThanAddress into StackGrowsDown, which then doesn't give // correct answer. void StackLowerThanAddress(const void* ptr, bool* result) GTEST_NO_INLINE_; void StackLowerThanAddress(const void* ptr, bool* result) { int dummy; *result = (&dummy < ptr); } bool StackGrowsDown() { int dummy; bool result; StackLowerThanAddress(&dummy, &result); return result; } // Spawns a child process with the same executable as the current process in // a thread-safe manner and instructs it to run the death test. The // implementation uses fork(2) + exec. On systems where clone(2) is // available, it is used instead, being slightly more thread-safe. On QNX, // fork supports only single-threaded environments, so this function uses // spawn(2) there instead. The function dies with an error message if // anything goes wrong. static pid_t ExecDeathTestSpawnChild(char* const* argv, int close_fd) { ExecDeathTestArgs args = { argv, close_fd }; pid_t child_pid = -1; # if GTEST_OS_QNX // Obtains the current directory and sets it to be closed in the child // process. const int cwd_fd = open(".", O_RDONLY); GTEST_DEATH_TEST_CHECK_(cwd_fd != -1); GTEST_DEATH_TEST_CHECK_SYSCALL_(fcntl(cwd_fd, F_SETFD, FD_CLOEXEC)); // We need to execute the test program in the same environment where // it was originally invoked. Therefore we change to the original // working directory first. const char* const original_dir = UnitTest::GetInstance()->original_working_dir(); // We can safely call chdir() as it's a direct system call. if (chdir(original_dir) != 0) { DeathTestAbort(std::string("chdir(\"") + original_dir + "\") failed: " + GetLastErrnoDescription()); return EXIT_FAILURE; } int fd_flags; // Set close_fd to be closed after spawn. GTEST_DEATH_TEST_CHECK_SYSCALL_(fd_flags = fcntl(close_fd, F_GETFD)); GTEST_DEATH_TEST_CHECK_SYSCALL_(fcntl(close_fd, F_SETFD, fd_flags | FD_CLOEXEC)); struct inheritance inherit = {0}; // spawn is a system call. child_pid = spawn(args.argv[0], 0, NULL, &inherit, args.argv, GetEnviron()); // Restores the current working directory. GTEST_DEATH_TEST_CHECK_(fchdir(cwd_fd) != -1); GTEST_DEATH_TEST_CHECK_SYSCALL_(close(cwd_fd)); # else // GTEST_OS_QNX # if GTEST_OS_LINUX // When a SIGPROF signal is received while fork() or clone() are executing, // the process may hang. To avoid this, we ignore SIGPROF here and re-enable // it after the call to fork()/clone() is complete. struct sigaction saved_sigprof_action; struct sigaction ignore_sigprof_action; memset(&ignore_sigprof_action, 0, sizeof(ignore_sigprof_action)); sigemptyset(&ignore_sigprof_action.sa_mask); ignore_sigprof_action.sa_handler = SIG_IGN; GTEST_DEATH_TEST_CHECK_SYSCALL_(sigaction( SIGPROF, &ignore_sigprof_action, &saved_sigprof_action)); # endif // GTEST_OS_LINUX # if GTEST_HAS_CLONE const bool use_fork = GTEST_FLAG(death_test_use_fork); if (!use_fork) { static const bool stack_grows_down = StackGrowsDown(); const size_t stack_size = getpagesize(); // MMAP_ANONYMOUS is not defined on Mac, so we use MAP_ANON instead. void* const stack = mmap(NULL, stack_size, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0); GTEST_DEATH_TEST_CHECK_(stack != MAP_FAILED); // Maximum stack alignment in bytes: For a downward-growing stack, this // amount is subtracted from size of the stack space to get an address // that is within the stack space and is aligned on all systems we care // about. As far as I know there is no ABI with stack alignment greater // than 64. We assume stack and stack_size already have alignment of // kMaxStackAlignment. const size_t kMaxStackAlignment = 64; void* const stack_top = static_cast(stack) + (stack_grows_down ? stack_size - kMaxStackAlignment : 0); GTEST_DEATH_TEST_CHECK_(stack_size > kMaxStackAlignment && reinterpret_cast(stack_top) % kMaxStackAlignment == 0); child_pid = clone(&ExecDeathTestChildMain, stack_top, SIGCHLD, &args); GTEST_DEATH_TEST_CHECK_(munmap(stack, stack_size) != -1); } # else const bool use_fork = true; # endif // GTEST_HAS_CLONE if (use_fork && (child_pid = fork()) == 0) { ExecDeathTestChildMain(&args); _exit(0); } # endif // GTEST_OS_QNX # if GTEST_OS_LINUX GTEST_DEATH_TEST_CHECK_SYSCALL_( sigaction(SIGPROF, &saved_sigprof_action, NULL)); # endif // GTEST_OS_LINUX GTEST_DEATH_TEST_CHECK_(child_pid != -1); return child_pid; } // The AssumeRole process for a fork-and-exec death test. It re-executes the // main program from the beginning, setting the --gtest_filter // and --gtest_internal_run_death_test flags to cause only the current // death test to be re-run. DeathTest::TestRole ExecDeathTest::AssumeRole() { const UnitTestImpl* const impl = GetUnitTestImpl(); const InternalRunDeathTestFlag* const flag = impl->internal_run_death_test_flag(); const TestInfo* const info = impl->current_test_info(); const int death_test_index = info->result()->death_test_count(); if (flag != NULL) { set_write_fd(flag->write_fd()); return EXECUTE_TEST; } int pipe_fd[2]; GTEST_DEATH_TEST_CHECK_(pipe(pipe_fd) != -1); // Clear the close-on-exec flag on the write end of the pipe, lest // it be closed when the child process does an exec: GTEST_DEATH_TEST_CHECK_(fcntl(pipe_fd[1], F_SETFD, 0) != -1); const std::string filter_flag = std::string("--") + GTEST_FLAG_PREFIX_ + kFilterFlag + "=" + info->test_case_name() + "." + info->name(); const std::string internal_flag = std::string("--") + GTEST_FLAG_PREFIX_ + kInternalRunDeathTestFlag + "=" + file_ + "|" + StreamableToString(line_) + "|" + StreamableToString(death_test_index) + "|" + StreamableToString(pipe_fd[1]); Arguments args; args.AddArguments(GetArgvsForDeathTestChildProcess()); args.AddArgument(filter_flag.c_str()); args.AddArgument(internal_flag.c_str()); DeathTest::set_last_death_test_message(""); CaptureStderr(); // See the comment in NoExecDeathTest::AssumeRole for why the next line // is necessary. FlushInfoLog(); const pid_t child_pid = ExecDeathTestSpawnChild(args.Argv(), pipe_fd[0]); GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[1])); set_child_pid(child_pid); set_read_fd(pipe_fd[0]); set_spawned(true); return OVERSEE_TEST; } # endif // !GTEST_OS_WINDOWS // Creates a concrete DeathTest-derived class that depends on the // --gtest_death_test_style flag, and sets the pointer pointed to // by the "test" argument to its address. If the test should be // skipped, sets that pointer to NULL. Returns true, unless the // flag is set to an invalid value. bool DefaultDeathTestFactory::Create(const char* statement, const RE* regex, const char* file, int line, DeathTest** test) { UnitTestImpl* const impl = GetUnitTestImpl(); const InternalRunDeathTestFlag* const flag = impl->internal_run_death_test_flag(); const int death_test_index = impl->current_test_info() ->increment_death_test_count(); if (flag != NULL) { if (death_test_index > flag->index()) { DeathTest::set_last_death_test_message( "Death test count (" + StreamableToString(death_test_index) + ") somehow exceeded expected maximum (" + StreamableToString(flag->index()) + ")"); return false; } if (!(flag->file() == file && flag->line() == line && flag->index() == death_test_index)) { *test = NULL; return true; } } # if GTEST_OS_WINDOWS if (GTEST_FLAG(death_test_style) == "threadsafe" || GTEST_FLAG(death_test_style) == "fast") { *test = new WindowsDeathTest(statement, regex, file, line); } # else if (GTEST_FLAG(death_test_style) == "threadsafe") { *test = new ExecDeathTest(statement, regex, file, line); } else if (GTEST_FLAG(death_test_style) == "fast") { *test = new NoExecDeathTest(statement, regex); } # endif // GTEST_OS_WINDOWS else { // NOLINT - this is more readable than unbalanced brackets inside #if. DeathTest::set_last_death_test_message( "Unknown death test style \"" + GTEST_FLAG(death_test_style) + "\" encountered"); return false; } return true; } // Splits a given string on a given delimiter, populating a given // vector with the fields. GTEST_HAS_DEATH_TEST implies that we have // ::std::string, so we can use it here. static void SplitString(const ::std::string& str, char delimiter, ::std::vector< ::std::string>* dest) { ::std::vector< ::std::string> parsed; ::std::string::size_type pos = 0; while (::testing::internal::AlwaysTrue()) { const ::std::string::size_type colon = str.find(delimiter, pos); if (colon == ::std::string::npos) { parsed.push_back(str.substr(pos)); break; } else { parsed.push_back(str.substr(pos, colon - pos)); pos = colon + 1; } } dest->swap(parsed); } # if GTEST_OS_WINDOWS // Recreates the pipe and event handles from the provided parameters, // signals the event, and returns a file descriptor wrapped around the pipe // handle. This function is called in the child process only. int GetStatusFileDescriptor(unsigned int parent_process_id, size_t write_handle_as_size_t, size_t event_handle_as_size_t) { AutoHandle parent_process_handle(::OpenProcess(PROCESS_DUP_HANDLE, FALSE, // Non-inheritable. parent_process_id)); if (parent_process_handle.Get() == INVALID_HANDLE_VALUE) { DeathTestAbort("Unable to open parent process " + StreamableToString(parent_process_id)); } // TODO(vladl@google.com): Replace the following check with a // compile-time assertion when available. GTEST_CHECK_(sizeof(HANDLE) <= sizeof(size_t)); const HANDLE write_handle = reinterpret_cast(write_handle_as_size_t); HANDLE dup_write_handle; // The newly initialized handle is accessible only in in the parent // process. To obtain one accessible within the child, we need to use // DuplicateHandle. if (!::DuplicateHandle(parent_process_handle.Get(), write_handle, ::GetCurrentProcess(), &dup_write_handle, 0x0, // Requested privileges ignored since // DUPLICATE_SAME_ACCESS is used. FALSE, // Request non-inheritable handler. DUPLICATE_SAME_ACCESS)) { DeathTestAbort("Unable to duplicate the pipe handle " + StreamableToString(write_handle_as_size_t) + " from the parent process " + StreamableToString(parent_process_id)); } const HANDLE event_handle = reinterpret_cast(event_handle_as_size_t); HANDLE dup_event_handle; if (!::DuplicateHandle(parent_process_handle.Get(), event_handle, ::GetCurrentProcess(), &dup_event_handle, 0x0, FALSE, DUPLICATE_SAME_ACCESS)) { DeathTestAbort("Unable to duplicate the event handle " + StreamableToString(event_handle_as_size_t) + " from the parent process " + StreamableToString(parent_process_id)); } const int write_fd = ::_open_osfhandle(reinterpret_cast(dup_write_handle), O_APPEND); if (write_fd == -1) { DeathTestAbort("Unable to convert pipe handle " + StreamableToString(write_handle_as_size_t) + " to a file descriptor"); } // Signals the parent that the write end of the pipe has been acquired // so the parent can release its own write end. ::SetEvent(dup_event_handle); return write_fd; } # endif // GTEST_OS_WINDOWS // Returns a newly created InternalRunDeathTestFlag object with fields // initialized from the GTEST_FLAG(internal_run_death_test) flag if // the flag is specified; otherwise returns NULL. InternalRunDeathTestFlag* ParseInternalRunDeathTestFlag() { if (GTEST_FLAG(internal_run_death_test) == "") return NULL; // GTEST_HAS_DEATH_TEST implies that we have ::std::string, so we // can use it here. int line = -1; int index = -1; ::std::vector< ::std::string> fields; SplitString(GTEST_FLAG(internal_run_death_test).c_str(), '|', &fields); int write_fd = -1; # if GTEST_OS_WINDOWS unsigned int parent_process_id = 0; size_t write_handle_as_size_t = 0; size_t event_handle_as_size_t = 0; if (fields.size() != 6 || !ParseNaturalNumber(fields[1], &line) || !ParseNaturalNumber(fields[2], &index) || !ParseNaturalNumber(fields[3], &parent_process_id) || !ParseNaturalNumber(fields[4], &write_handle_as_size_t) || !ParseNaturalNumber(fields[5], &event_handle_as_size_t)) { DeathTestAbort("Bad --gtest_internal_run_death_test flag: " + GTEST_FLAG(internal_run_death_test)); } write_fd = GetStatusFileDescriptor(parent_process_id, write_handle_as_size_t, event_handle_as_size_t); # else if (fields.size() != 4 || !ParseNaturalNumber(fields[1], &line) || !ParseNaturalNumber(fields[2], &index) || !ParseNaturalNumber(fields[3], &write_fd)) { DeathTestAbort("Bad --gtest_internal_run_death_test flag: " + GTEST_FLAG(internal_run_death_test)); } # endif // GTEST_OS_WINDOWS return new InternalRunDeathTestFlag(fields[0], line, index, write_fd); } } // namespace internal #endif // GTEST_HAS_DEATH_TEST } // namespace testing dlt-daemon-2.18.4/gtest-1.7.0/src/gtest-filepath.cc000066400000000000000000000336361353342203500214520ustar00rootroot00000000000000// Copyright 2008, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Authors: keith.ray@gmail.com (Keith Ray) #include "gtest/gtest-message.h" #include "gtest/internal/gtest-filepath.h" #include "gtest/internal/gtest-port.h" #include #if GTEST_OS_WINDOWS_MOBILE # include #elif GTEST_OS_WINDOWS # include # include #elif GTEST_OS_SYMBIAN // Symbian OpenC has PATH_MAX in sys/syslimits.h # include #else # include # include // Some Linux distributions define PATH_MAX here. #endif // GTEST_OS_WINDOWS_MOBILE #if GTEST_OS_WINDOWS # define GTEST_PATH_MAX_ _MAX_PATH #elif defined(PATH_MAX) # define GTEST_PATH_MAX_ PATH_MAX #elif defined(_XOPEN_PATH_MAX) # define GTEST_PATH_MAX_ _XOPEN_PATH_MAX #else # define GTEST_PATH_MAX_ _POSIX_PATH_MAX #endif // GTEST_OS_WINDOWS #include "gtest/internal/gtest-string.h" namespace testing { namespace internal { #if GTEST_OS_WINDOWS // On Windows, '\\' is the standard path separator, but many tools and the // Windows API also accept '/' as an alternate path separator. Unless otherwise // noted, a file path can contain either kind of path separators, or a mixture // of them. const char kPathSeparator = '\\'; const char kAlternatePathSeparator = '/'; const char kPathSeparatorString[] = "\\"; const char kAlternatePathSeparatorString[] = "/"; # if GTEST_OS_WINDOWS_MOBILE // Windows CE doesn't have a current directory. You should not use // the current directory in tests on Windows CE, but this at least // provides a reasonable fallback. const char kCurrentDirectoryString[] = "\\"; // Windows CE doesn't define INVALID_FILE_ATTRIBUTES const DWORD kInvalidFileAttributes = 0xffffffff; # else const char kCurrentDirectoryString[] = ".\\"; # endif // GTEST_OS_WINDOWS_MOBILE #else const char kPathSeparator = '/'; const char kPathSeparatorString[] = "/"; const char kCurrentDirectoryString[] = "./"; #endif // GTEST_OS_WINDOWS // Returns whether the given character is a valid path separator. static bool IsPathSeparator(char c) { #if GTEST_HAS_ALT_PATH_SEP_ return (c == kPathSeparator) || (c == kAlternatePathSeparator); #else return c == kPathSeparator; #endif } // Returns the current working directory, or "" if unsuccessful. FilePath FilePath::GetCurrentDir() { #if GTEST_OS_WINDOWS_MOBILE // Windows CE doesn't have a current directory, so we just return // something reasonable. return FilePath(kCurrentDirectoryString); #elif GTEST_OS_WINDOWS char cwd[GTEST_PATH_MAX_ + 1] = { '\0' }; return FilePath(_getcwd(cwd, sizeof(cwd)) == NULL ? "" : cwd); #else char cwd[GTEST_PATH_MAX_ + 1] = { '\0' }; return FilePath(getcwd(cwd, sizeof(cwd)) == NULL ? "" : cwd); #endif // GTEST_OS_WINDOWS_MOBILE } // Returns a copy of the FilePath with the case-insensitive extension removed. // Example: FilePath("dir/file.exe").RemoveExtension("EXE") returns // FilePath("dir/file"). If a case-insensitive extension is not // found, returns a copy of the original FilePath. FilePath FilePath::RemoveExtension(const char* extension) const { const std::string dot_extension = std::string(".") + extension; if (String::EndsWithCaseInsensitive(pathname_, dot_extension)) { return FilePath(pathname_.substr( 0, pathname_.length() - dot_extension.length())); } return *this; } // Returns a pointer to the last occurence of a valid path separator in // the FilePath. On Windows, for example, both '/' and '\' are valid path // separators. Returns NULL if no path separator was found. const char* FilePath::FindLastPathSeparator() const { const char* const last_sep = strrchr(c_str(), kPathSeparator); #if GTEST_HAS_ALT_PATH_SEP_ const char* const last_alt_sep = strrchr(c_str(), kAlternatePathSeparator); // Comparing two pointers of which only one is NULL is undefined. if (last_alt_sep != NULL && (last_sep == NULL || last_alt_sep > last_sep)) { return last_alt_sep; } #endif return last_sep; } // Returns a copy of the FilePath with the directory part removed. // Example: FilePath("path/to/file").RemoveDirectoryName() returns // FilePath("file"). If there is no directory part ("just_a_file"), it returns // the FilePath unmodified. If there is no file part ("just_a_dir/") it // returns an empty FilePath (""). // On Windows platform, '\' is the path separator, otherwise it is '/'. FilePath FilePath::RemoveDirectoryName() const { const char* const last_sep = FindLastPathSeparator(); return last_sep ? FilePath(last_sep + 1) : *this; } // RemoveFileName returns the directory path with the filename removed. // Example: FilePath("path/to/file").RemoveFileName() returns "path/to/". // If the FilePath is "a_file" or "/a_file", RemoveFileName returns // FilePath("./") or, on Windows, FilePath(".\\"). If the filepath does // not have a file, like "just/a/dir/", it returns the FilePath unmodified. // On Windows platform, '\' is the path separator, otherwise it is '/'. FilePath FilePath::RemoveFileName() const { const char* const last_sep = FindLastPathSeparator(); std::string dir; if (last_sep) { dir = std::string(c_str(), last_sep + 1 - c_str()); } else { dir = kCurrentDirectoryString; } return FilePath(dir); } // Helper functions for naming files in a directory for xml output. // Given directory = "dir", base_name = "test", number = 0, // extension = "xml", returns "dir/test.xml". If number is greater // than zero (e.g., 12), returns "dir/test_12.xml". // On Windows platform, uses \ as the separator rather than /. FilePath FilePath::MakeFileName(const FilePath& directory, const FilePath& base_name, int number, const char* extension) { std::string file; if (number == 0) { file = base_name.string() + "." + extension; } else { file = base_name.string() + "_" + StreamableToString(number) + "." + extension; } return ConcatPaths(directory, FilePath(file)); } // Given directory = "dir", relative_path = "test.xml", returns "dir/test.xml". // On Windows, uses \ as the separator rather than /. FilePath FilePath::ConcatPaths(const FilePath& directory, const FilePath& relative_path) { if (directory.IsEmpty()) return relative_path; const FilePath dir(directory.RemoveTrailingPathSeparator()); return FilePath(dir.string() + kPathSeparator + relative_path.string()); } // Returns true if pathname describes something findable in the file-system, // either a file, directory, or whatever. bool FilePath::FileOrDirectoryExists() const { #if GTEST_OS_WINDOWS_MOBILE LPCWSTR unicode = String::AnsiToUtf16(pathname_.c_str()); const DWORD attributes = GetFileAttributes(unicode); delete [] unicode; return attributes != kInvalidFileAttributes; #else posix::StatStruct file_stat; return posix::Stat(pathname_.c_str(), &file_stat) == 0; #endif // GTEST_OS_WINDOWS_MOBILE } // Returns true if pathname describes a directory in the file-system // that exists. bool FilePath::DirectoryExists() const { bool result = false; #if GTEST_OS_WINDOWS // Don't strip off trailing separator if path is a root directory on // Windows (like "C:\\"). const FilePath& path(IsRootDirectory() ? *this : RemoveTrailingPathSeparator()); #else const FilePath& path(*this); #endif #if GTEST_OS_WINDOWS_MOBILE LPCWSTR unicode = String::AnsiToUtf16(path.c_str()); const DWORD attributes = GetFileAttributes(unicode); delete [] unicode; if ((attributes != kInvalidFileAttributes) && (attributes & FILE_ATTRIBUTE_DIRECTORY)) { result = true; } #else posix::StatStruct file_stat; result = posix::Stat(path.c_str(), &file_stat) == 0 && posix::IsDir(file_stat); #endif // GTEST_OS_WINDOWS_MOBILE return result; } // Returns true if pathname describes a root directory. (Windows has one // root directory per disk drive.) bool FilePath::IsRootDirectory() const { #if GTEST_OS_WINDOWS // TODO(wan@google.com): on Windows a network share like // \\server\share can be a root directory, although it cannot be the // current directory. Handle this properly. return pathname_.length() == 3 && IsAbsolutePath(); #else return pathname_.length() == 1 && IsPathSeparator(pathname_.c_str()[0]); #endif } // Returns true if pathname describes an absolute path. bool FilePath::IsAbsolutePath() const { const char* const name = pathname_.c_str(); #if GTEST_OS_WINDOWS return pathname_.length() >= 3 && ((name[0] >= 'a' && name[0] <= 'z') || (name[0] >= 'A' && name[0] <= 'Z')) && name[1] == ':' && IsPathSeparator(name[2]); #else return IsPathSeparator(name[0]); #endif } // Returns a pathname for a file that does not currently exist. The pathname // will be directory/base_name.extension or // directory/base_name_.extension if directory/base_name.extension // already exists. The number will be incremented until a pathname is found // that does not already exist. // Examples: 'dir/foo_test.xml' or 'dir/foo_test_1.xml'. // There could be a race condition if two or more processes are calling this // function at the same time -- they could both pick the same filename. FilePath FilePath::GenerateUniqueFileName(const FilePath& directory, const FilePath& base_name, const char* extension) { FilePath full_pathname; int number = 0; do { full_pathname.Set(MakeFileName(directory, base_name, number++, extension)); } while (full_pathname.FileOrDirectoryExists()); return full_pathname; } // Returns true if FilePath ends with a path separator, which indicates that // it is intended to represent a directory. Returns false otherwise. // This does NOT check that a directory (or file) actually exists. bool FilePath::IsDirectory() const { return !pathname_.empty() && IsPathSeparator(pathname_.c_str()[pathname_.length() - 1]); } // Create directories so that path exists. Returns true if successful or if // the directories already exist; returns false if unable to create directories // for any reason. bool FilePath::CreateDirectoriesRecursively() const { if (!this->IsDirectory()) { return false; } if (pathname_.length() == 0 || this->DirectoryExists()) { return true; } const FilePath parent(this->RemoveTrailingPathSeparator().RemoveFileName()); return parent.CreateDirectoriesRecursively() && this->CreateFolder(); } // Create the directory so that path exists. Returns true if successful or // if the directory already exists; returns false if unable to create the // directory for any reason, including if the parent directory does not // exist. Not named "CreateDirectory" because that's a macro on Windows. bool FilePath::CreateFolder() const { #if GTEST_OS_WINDOWS_MOBILE FilePath removed_sep(this->RemoveTrailingPathSeparator()); LPCWSTR unicode = String::AnsiToUtf16(removed_sep.c_str()); int result = CreateDirectory(unicode, NULL) ? 0 : -1; delete [] unicode; #elif GTEST_OS_WINDOWS int result = _mkdir(pathname_.c_str()); #else int result = mkdir(pathname_.c_str(), 0777); #endif // GTEST_OS_WINDOWS_MOBILE if (result == -1) { return this->DirectoryExists(); // An error is OK if the directory exists. } return true; // No error. } // If input name has a trailing separator character, remove it and return the // name, otherwise return the name string unmodified. // On Windows platform, uses \ as the separator, other platforms use /. FilePath FilePath::RemoveTrailingPathSeparator() const { return IsDirectory() ? FilePath(pathname_.substr(0, pathname_.length() - 1)) : *this; } // Removes any redundant separators that might be in the pathname. // For example, "bar///foo" becomes "bar/foo". Does not eliminate other // redundancies that might be in a pathname involving "." or "..". // TODO(wan@google.com): handle Windows network shares (e.g. \\server\share). void FilePath::Normalize() { if (pathname_.c_str() == NULL) { pathname_ = ""; return; } const char* src = pathname_.c_str(); char* const dest = new char[pathname_.length() + 1]; char* dest_ptr = dest; memset(dest_ptr, 0, pathname_.length() + 1); while (*src != '\0') { *dest_ptr = *src; if (!IsPathSeparator(*src)) { src++; } else { #if GTEST_HAS_ALT_PATH_SEP_ if (*dest_ptr == kAlternatePathSeparator) { *dest_ptr = kPathSeparator; } #endif while (IsPathSeparator(*src)) src++; } dest_ptr++; } *dest_ptr = '\0'; pathname_ = dest; delete[] dest; } } // namespace internal } // namespace testing dlt-daemon-2.18.4/gtest-1.7.0/src/gtest-internal-inl.h000066400000000000000000001326011353342203500221040ustar00rootroot00000000000000// Copyright 2005, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // Utility functions and classes used by the Google C++ testing framework. // // Author: wan@google.com (Zhanyong Wan) // // This file contains purely Google Test's internal implementation. Please // DO NOT #INCLUDE IT IN A USER PROGRAM. #ifndef GTEST_SRC_GTEST_INTERNAL_INL_H_ #define GTEST_SRC_GTEST_INTERNAL_INL_H_ // GTEST_IMPLEMENTATION_ is defined to 1 iff the current translation unit is // part of Google Test's implementation; otherwise it's undefined. #if !GTEST_IMPLEMENTATION_ // A user is trying to include this from his code - just say no. # error "gtest-internal-inl.h is part of Google Test's internal implementation." # error "It must not be included except by Google Test itself." #endif // GTEST_IMPLEMENTATION_ #ifndef _WIN32_WCE # include #endif // !_WIN32_WCE #include #include // For strtoll/_strtoul64/malloc/free. #include // For memmove. #include #include #include #include "gtest/internal/gtest-port.h" #if GTEST_CAN_STREAM_RESULTS_ # include // NOLINT # include // NOLINT #endif #if GTEST_OS_WINDOWS # include // NOLINT #endif // GTEST_OS_WINDOWS #include "gtest/gtest.h" // NOLINT #include "gtest/gtest-spi.h" namespace testing { // Declares the flags. // // We don't want the users to modify this flag in the code, but want // Google Test's own unit tests to be able to access it. Therefore we // declare it here as opposed to in gtest.h. GTEST_DECLARE_bool_(death_test_use_fork); namespace internal { // The value of GetTestTypeId() as seen from within the Google Test // library. This is solely for testing GetTestTypeId(). GTEST_API_ extern const TypeId kTestTypeIdInGoogleTest; // Names of the flags (needed for parsing Google Test flags). const char kAlsoRunDisabledTestsFlag[] = "also_run_disabled_tests"; const char kBreakOnFailureFlag[] = "break_on_failure"; const char kCatchExceptionsFlag[] = "catch_exceptions"; const char kColorFlag[] = "color"; const char kFilterFlag[] = "filter"; const char kListTestsFlag[] = "list_tests"; const char kOutputFlag[] = "output"; const char kPrintTimeFlag[] = "print_time"; const char kRandomSeedFlag[] = "random_seed"; const char kRepeatFlag[] = "repeat"; const char kShuffleFlag[] = "shuffle"; const char kStackTraceDepthFlag[] = "stack_trace_depth"; const char kStreamResultToFlag[] = "stream_result_to"; const char kThrowOnFailureFlag[] = "throw_on_failure"; // A valid random seed must be in [1, kMaxRandomSeed]. const int kMaxRandomSeed = 99999; // g_help_flag is true iff the --help flag or an equivalent form is // specified on the command line. GTEST_API_ extern bool g_help_flag; // Returns the current time in milliseconds. GTEST_API_ TimeInMillis GetTimeInMillis(); // Returns true iff Google Test should use colors in the output. GTEST_API_ bool ShouldUseColor(bool stdout_is_tty); // Formats the given time in milliseconds as seconds. GTEST_API_ std::string FormatTimeInMillisAsSeconds(TimeInMillis ms); // Converts the given time in milliseconds to a date string in the ISO 8601 // format, without the timezone information. N.B.: due to the use the // non-reentrant localtime() function, this function is not thread safe. Do // not use it in any code that can be called from multiple threads. GTEST_API_ std::string FormatEpochTimeInMillisAsIso8601(TimeInMillis ms); // Parses a string for an Int32 flag, in the form of "--flag=value". // // On success, stores the value of the flag in *value, and returns // true. On failure, returns false without changing *value. GTEST_API_ bool ParseInt32Flag( const char* str, const char* flag, Int32* value); // Returns a random seed in range [1, kMaxRandomSeed] based on the // given --gtest_random_seed flag value. inline int GetRandomSeedFromFlag(Int32 random_seed_flag) { const unsigned int raw_seed = (random_seed_flag == 0) ? static_cast(GetTimeInMillis()) : static_cast(random_seed_flag); // Normalizes the actual seed to range [1, kMaxRandomSeed] such that // it's easy to type. const int normalized_seed = static_cast((raw_seed - 1U) % static_cast(kMaxRandomSeed)) + 1; return normalized_seed; } // Returns the first valid random seed after 'seed'. The behavior is // undefined if 'seed' is invalid. The seed after kMaxRandomSeed is // considered to be 1. inline int GetNextRandomSeed(int seed) { GTEST_CHECK_(1 <= seed && seed <= kMaxRandomSeed) << "Invalid random seed " << seed << " - must be in [1, " << kMaxRandomSeed << "]."; const int next_seed = seed + 1; return (next_seed > kMaxRandomSeed) ? 1 : next_seed; } // This class saves the values of all Google Test flags in its c'tor, and // restores them in its d'tor. class GTestFlagSaver { public: // The c'tor. GTestFlagSaver() { also_run_disabled_tests_ = GTEST_FLAG(also_run_disabled_tests); break_on_failure_ = GTEST_FLAG(break_on_failure); catch_exceptions_ = GTEST_FLAG(catch_exceptions); color_ = GTEST_FLAG(color); death_test_style_ = GTEST_FLAG(death_test_style); death_test_use_fork_ = GTEST_FLAG(death_test_use_fork); filter_ = GTEST_FLAG(filter); internal_run_death_test_ = GTEST_FLAG(internal_run_death_test); list_tests_ = GTEST_FLAG(list_tests); output_ = GTEST_FLAG(output); print_time_ = GTEST_FLAG(print_time); random_seed_ = GTEST_FLAG(random_seed); repeat_ = GTEST_FLAG(repeat); shuffle_ = GTEST_FLAG(shuffle); stack_trace_depth_ = GTEST_FLAG(stack_trace_depth); stream_result_to_ = GTEST_FLAG(stream_result_to); throw_on_failure_ = GTEST_FLAG(throw_on_failure); } // The d'tor is not virtual. DO NOT INHERIT FROM THIS CLASS. ~GTestFlagSaver() { GTEST_FLAG(also_run_disabled_tests) = also_run_disabled_tests_; GTEST_FLAG(break_on_failure) = break_on_failure_; GTEST_FLAG(catch_exceptions) = catch_exceptions_; GTEST_FLAG(color) = color_; GTEST_FLAG(death_test_style) = death_test_style_; GTEST_FLAG(death_test_use_fork) = death_test_use_fork_; GTEST_FLAG(filter) = filter_; GTEST_FLAG(internal_run_death_test) = internal_run_death_test_; GTEST_FLAG(list_tests) = list_tests_; GTEST_FLAG(output) = output_; GTEST_FLAG(print_time) = print_time_; GTEST_FLAG(random_seed) = random_seed_; GTEST_FLAG(repeat) = repeat_; GTEST_FLAG(shuffle) = shuffle_; GTEST_FLAG(stack_trace_depth) = stack_trace_depth_; GTEST_FLAG(stream_result_to) = stream_result_to_; GTEST_FLAG(throw_on_failure) = throw_on_failure_; } private: // Fields for saving the original values of flags. bool also_run_disabled_tests_; bool break_on_failure_; bool catch_exceptions_; std::string color_; std::string death_test_style_; bool death_test_use_fork_; std::string filter_; std::string internal_run_death_test_; bool list_tests_; std::string output_; bool print_time_; internal::Int32 random_seed_; internal::Int32 repeat_; bool shuffle_; internal::Int32 stack_trace_depth_; std::string stream_result_to_; bool throw_on_failure_; } GTEST_ATTRIBUTE_UNUSED_; // Converts a Unicode code point to a narrow string in UTF-8 encoding. // code_point parameter is of type UInt32 because wchar_t may not be // wide enough to contain a code point. // If the code_point is not a valid Unicode code point // (i.e. outside of Unicode range U+0 to U+10FFFF) it will be converted // to "(Invalid Unicode 0xXXXXXXXX)". GTEST_API_ std::string CodePointToUtf8(UInt32 code_point); // Converts a wide string to a narrow string in UTF-8 encoding. // The wide string is assumed to have the following encoding: // UTF-16 if sizeof(wchar_t) == 2 (on Windows, Cygwin, Symbian OS) // UTF-32 if sizeof(wchar_t) == 4 (on Linux) // Parameter str points to a null-terminated wide string. // Parameter num_chars may additionally limit the number // of wchar_t characters processed. -1 is used when the entire string // should be processed. // If the string contains code points that are not valid Unicode code points // (i.e. outside of Unicode range U+0 to U+10FFFF) they will be output // as '(Invalid Unicode 0xXXXXXXXX)'. If the string is in UTF16 encoding // and contains invalid UTF-16 surrogate pairs, values in those pairs // will be encoded as individual Unicode characters from Basic Normal Plane. GTEST_API_ std::string WideStringToUtf8(const wchar_t* str, int num_chars); // Reads the GTEST_SHARD_STATUS_FILE environment variable, and creates the file // if the variable is present. If a file already exists at this location, this // function will write over it. If the variable is present, but the file cannot // be created, prints an error and exits. void WriteToShardStatusFileIfNeeded(); // Checks whether sharding is enabled by examining the relevant // environment variable values. If the variables are present, // but inconsistent (e.g., shard_index >= total_shards), prints // an error and exits. If in_subprocess_for_death_test, sharding is // disabled because it must only be applied to the original test // process. Otherwise, we could filter out death tests we intended to execute. GTEST_API_ bool ShouldShard(const char* total_shards_str, const char* shard_index_str, bool in_subprocess_for_death_test); // Parses the environment variable var as an Int32. If it is unset, // returns default_val. If it is not an Int32, prints an error and // and aborts. GTEST_API_ Int32 Int32FromEnvOrDie(const char* env_var, Int32 default_val); // Given the total number of shards, the shard index, and the test id, // returns true iff the test should be run on this shard. The test id is // some arbitrary but unique non-negative integer assigned to each test // method. Assumes that 0 <= shard_index < total_shards. GTEST_API_ bool ShouldRunTestOnShard( int total_shards, int shard_index, int test_id); // STL container utilities. // Returns the number of elements in the given container that satisfy // the given predicate. template inline int CountIf(const Container& c, Predicate predicate) { // Implemented as an explicit loop since std::count_if() in libCstd on // Solaris has a non-standard signature. int count = 0; for (typename Container::const_iterator it = c.begin(); it != c.end(); ++it) { if (predicate(*it)) ++count; } return count; } // Applies a function/functor to each element in the container. template void ForEach(const Container& c, Functor functor) { std::for_each(c.begin(), c.end(), functor); } // Returns the i-th element of the vector, or default_value if i is not // in range [0, v.size()). template inline E GetElementOr(const std::vector& v, int i, E default_value) { return (i < 0 || i >= static_cast(v.size())) ? default_value : v[i]; } // Performs an in-place shuffle of a range of the vector's elements. // 'begin' and 'end' are element indices as an STL-style range; // i.e. [begin, end) are shuffled, where 'end' == size() means to // shuffle to the end of the vector. template void ShuffleRange(internal::Random* random, int begin, int end, std::vector* v) { const int size = static_cast(v->size()); GTEST_CHECK_(0 <= begin && begin <= size) << "Invalid shuffle range start " << begin << ": must be in range [0, " << size << "]."; GTEST_CHECK_(begin <= end && end <= size) << "Invalid shuffle range finish " << end << ": must be in range [" << begin << ", " << size << "]."; // Fisher-Yates shuffle, from // http://en.wikipedia.org/wiki/Fisher-Yates_shuffle for (int range_width = end - begin; range_width >= 2; range_width--) { const int last_in_range = begin + range_width - 1; const int selected = begin + random->Generate(range_width); std::swap((*v)[selected], (*v)[last_in_range]); } } // Performs an in-place shuffle of the vector's elements. template inline void Shuffle(internal::Random* random, std::vector* v) { ShuffleRange(random, 0, static_cast(v->size()), v); } // A function for deleting an object. Handy for being used as a // functor. template static void Delete(T* x) { delete x; } // A predicate that checks the key of a TestProperty against a known key. // // TestPropertyKeyIs is copyable. class TestPropertyKeyIs { public: // Constructor. // // TestPropertyKeyIs has NO default constructor. explicit TestPropertyKeyIs(const std::string& key) : key_(key) {} // Returns true iff the test name of test property matches on key_. bool operator()(const TestProperty& test_property) const { return test_property.key() == key_; } private: std::string key_; }; // Class UnitTestOptions. // // This class contains functions for processing options the user // specifies when running the tests. It has only static members. // // In most cases, the user can specify an option using either an // environment variable or a command line flag. E.g. you can set the // test filter using either GTEST_FILTER or --gtest_filter. If both // the variable and the flag are present, the latter overrides the // former. class GTEST_API_ UnitTestOptions { public: // Functions for processing the gtest_output flag. // Returns the output format, or "" for normal printed output. static std::string GetOutputFormat(); // Returns the absolute path of the requested output file, or the // default (test_detail.xml in the original working directory) if // none was explicitly specified. static std::string GetAbsolutePathToOutputFile(); // Functions for processing the gtest_filter flag. // Returns true iff the wildcard pattern matches the string. The // first ':' or '\0' character in pattern marks the end of it. // // This recursive algorithm isn't very efficient, but is clear and // works well enough for matching test names, which are short. static bool PatternMatchesString(const char *pattern, const char *str); // Returns true iff the user-specified filter matches the test case // name and the test name. static bool FilterMatchesTest(const std::string &test_case_name, const std::string &test_name); #if GTEST_OS_WINDOWS // Function for supporting the gtest_catch_exception flag. // Returns EXCEPTION_EXECUTE_HANDLER if Google Test should handle the // given SEH exception, or EXCEPTION_CONTINUE_SEARCH otherwise. // This function is useful as an __except condition. static int GTestShouldProcessSEH(DWORD exception_code); #endif // GTEST_OS_WINDOWS // Returns true if "name" matches the ':' separated list of glob-style // filters in "filter". static bool MatchesFilter(const std::string& name, const char* filter); }; // Returns the current application's name, removing directory path if that // is present. Used by UnitTestOptions::GetOutputFile. GTEST_API_ FilePath GetCurrentExecutableName(); // The role interface for getting the OS stack trace as a string. class OsStackTraceGetterInterface { public: OsStackTraceGetterInterface() {} virtual ~OsStackTraceGetterInterface() {} // Returns the current OS stack trace as 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. virtual string CurrentStackTrace(int max_depth, int skip_count) = 0; // UponLeavingGTest() should be called immediately before Google Test calls // user code. It saves some information about the current stack that // CurrentStackTrace() will use to find and hide Google Test stack frames. virtual void UponLeavingGTest() = 0; private: GTEST_DISALLOW_COPY_AND_ASSIGN_(OsStackTraceGetterInterface); }; // A working implementation of the OsStackTraceGetterInterface interface. class OsStackTraceGetter : public OsStackTraceGetterInterface { public: OsStackTraceGetter() : caller_frame_(NULL) {} virtual string CurrentStackTrace(int max_depth, int skip_count) 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; private: Mutex mutex_; // protects all internal state // We save the stack frame below the frame that calls user code. // We do this because the address of the frame immediately below // the user code changes between the call to UponLeavingGTest() // and any calls to CurrentStackTrace() from within the user code. void* caller_frame_; GTEST_DISALLOW_COPY_AND_ASSIGN_(OsStackTraceGetter); }; // Information about a Google Test trace point. struct TraceInfo { const char* file; int line; std::string message; }; // This is the default global test part result reporter used in UnitTestImpl. // This class should only be used by UnitTestImpl. class DefaultGlobalTestPartResultReporter : public TestPartResultReporterInterface { public: explicit DefaultGlobalTestPartResultReporter(UnitTestImpl* unit_test); // Implements the TestPartResultReporterInterface. Reports the test part // result in the current test. virtual void ReportTestPartResult(const TestPartResult& result); private: UnitTestImpl* const unit_test_; GTEST_DISALLOW_COPY_AND_ASSIGN_(DefaultGlobalTestPartResultReporter); }; // This is the default per thread test part result reporter used in // UnitTestImpl. This class should only be used by UnitTestImpl. class DefaultPerThreadTestPartResultReporter : public TestPartResultReporterInterface { public: explicit DefaultPerThreadTestPartResultReporter(UnitTestImpl* unit_test); // Implements the TestPartResultReporterInterface. The implementation just // delegates to the current global test part result reporter of *unit_test_. virtual void ReportTestPartResult(const TestPartResult& result); private: UnitTestImpl* const unit_test_; GTEST_DISALLOW_COPY_AND_ASSIGN_(DefaultPerThreadTestPartResultReporter); }; // The private implementation of the UnitTest class. We don't protect // the methods under a mutex, as this class is not accessible by a // user and the UnitTest class that delegates work to this class does // proper locking. class GTEST_API_ UnitTestImpl { public: explicit UnitTestImpl(UnitTest* parent); virtual ~UnitTestImpl(); // There are two different ways to register your own TestPartResultReporter. // You can register your own repoter to listen either only for test results // from the current thread or for results from all threads. // By default, each per-thread test result repoter just passes a new // TestPartResult to the global test result reporter, which registers the // test part result for the currently running test. // Returns the global test part result reporter. TestPartResultReporterInterface* GetGlobalTestPartResultReporter(); // Sets the global test part result reporter. void SetGlobalTestPartResultReporter( TestPartResultReporterInterface* reporter); // Returns the test part result reporter for the current thread. TestPartResultReporterInterface* GetTestPartResultReporterForCurrentThread(); // Sets the test part result reporter for the current thread. void SetTestPartResultReporterForCurrentThread( TestPartResultReporterInterface* reporter); // Gets the number of successful test cases. int successful_test_case_count() const; // Gets the number of failed test cases. int failed_test_case_count() const; // Gets the number of all test cases. int total_test_case_count() const; // Gets the number of all test cases that contain at least one test // that should run. int test_case_to_run_count() const; // Gets the number of successful tests. int successful_test_count() const; // Gets the number of failed tests. int failed_test_count() const; // Gets the number of disabled tests that will be reported in the XML report. int reportable_disabled_test_count() const; // Gets the number of disabled tests. int disabled_test_count() const; // Gets the number of tests to be printed in the XML report. int reportable_test_count() const; // Gets the number of all tests. int total_test_count() const; // Gets the number of tests that should run. int test_to_run_count() const; // Gets the time of the test program start, in ms from the start of the // UNIX epoch. TimeInMillis start_timestamp() const { return start_timestamp_; } // Gets the elapsed time, in milliseconds. TimeInMillis elapsed_time() const { return elapsed_time_; } // Returns true iff the unit test passed (i.e. all test cases passed). bool Passed() const { return !Failed(); } // Returns true iff the unit test failed (i.e. some test case failed // or something outside of all tests failed). bool Failed() const { return failed_test_case_count() > 0 || ad_hoc_test_result()->Failed(); } // Gets the i-th test case among all the test cases. i can range from 0 to // total_test_case_count() - 1. If i is not in that range, returns NULL. const TestCase* GetTestCase(int i) const { const int index = GetElementOr(test_case_indices_, i, -1); return index < 0 ? NULL : test_cases_[i]; } // Gets the i-th test case among all the test cases. i can range from 0 to // total_test_case_count() - 1. If i is not in that range, returns NULL. TestCase* GetMutableTestCase(int i) { const int index = GetElementOr(test_case_indices_, i, -1); return index < 0 ? NULL : test_cases_[index]; } // Provides access to the event listener list. TestEventListeners* listeners() { return &listeners_; } // Returns the TestResult for the test that's currently running, or // the TestResult for the ad hoc test if no test is running. TestResult* current_test_result(); // Returns the TestResult for the ad hoc test. const TestResult* ad_hoc_test_result() const { return &ad_hoc_test_result_; } // Sets the OS stack trace getter. // // Does nothing if the input and the current OS stack trace getter // are the same; otherwise, deletes the old getter and makes the // input the current getter. void set_os_stack_trace_getter(OsStackTraceGetterInterface* getter); // Returns the current OS stack trace getter if it is not NULL; // otherwise, creates an OsStackTraceGetter, makes it the current // getter, and returns it. OsStackTraceGetterInterface* os_stack_trace_getter(); // Returns the current OS stack trace as an std::string. // // The maximum number of stack frames to be included is specified by // the gtest_stack_trace_depth flag. The skip_count parameter // specifies the number of top frames to be skipped, which doesn't // count against the number of frames to be included. // // For example, if Foo() calls Bar(), which in turn calls // CurrentOsStackTraceExceptTop(1), Foo() will be included in the // trace but Bar() and CurrentOsStackTraceExceptTop() won't. std::string CurrentOsStackTraceExceptTop(int skip_count) GTEST_NO_INLINE_; // Finds and returns a TestCase with the given name. If one doesn't // exist, creates one and returns it. // // Arguments: // // test_case_name: name of the test case // type_param: the name of the test's type parameter, or NULL if // this is not a typed or a type-parameterized test. // set_up_tc: pointer to the function that sets up the test case // tear_down_tc: pointer to the function that tears down the test case TestCase* GetTestCase(const char* test_case_name, const char* type_param, Test::SetUpTestCaseFunc set_up_tc, Test::TearDownTestCaseFunc tear_down_tc); // Adds a TestInfo to the unit test. // // Arguments: // // set_up_tc: pointer to the function that sets up the test case // tear_down_tc: pointer to the function that tears down the test case // test_info: the TestInfo object void AddTestInfo(Test::SetUpTestCaseFunc set_up_tc, Test::TearDownTestCaseFunc tear_down_tc, TestInfo* test_info) { // In order to support thread-safe death tests, we need to // remember the original working directory when the test program // was first invoked. We cannot do this in RUN_ALL_TESTS(), as // the user may have changed the current directory before calling // RUN_ALL_TESTS(). Therefore we capture the current directory in // AddTestInfo(), which is called to register a TEST or TEST_F // before main() is reached. if (original_working_dir_.IsEmpty()) { original_working_dir_.Set(FilePath::GetCurrentDir()); GTEST_CHECK_(!original_working_dir_.IsEmpty()) << "Failed to get the current working directory."; } GetTestCase(test_info->test_case_name(), test_info->type_param(), set_up_tc, tear_down_tc)->AddTestInfo(test_info); } #if GTEST_HAS_PARAM_TEST // Returns ParameterizedTestCaseRegistry object used to keep track of // value-parameterized tests and instantiate and register them. internal::ParameterizedTestCaseRegistry& parameterized_test_registry() { return parameterized_test_registry_; } #endif // GTEST_HAS_PARAM_TEST // Sets the TestCase object for the test that's currently running. void set_current_test_case(TestCase* a_current_test_case) { current_test_case_ = a_current_test_case; } // Sets the TestInfo object for the test that's currently running. If // current_test_info is NULL, the assertion results will be stored in // ad_hoc_test_result_. void set_current_test_info(TestInfo* a_current_test_info) { current_test_info_ = a_current_test_info; } // Registers all parameterized tests defined using TEST_P and // INSTANTIATE_TEST_CASE_P, creating regular tests for each test/parameter // combination. This method can be called more then once; it has guards // protecting from registering the tests more then once. If // value-parameterized tests are disabled, RegisterParameterizedTests is // present but does nothing. void RegisterParameterizedTests(); // Runs all tests in this UnitTest object, prints the result, and // returns true if all tests are successful. If any exception is // thrown during a test, this test is considered to be failed, but // the rest of the tests will still be run. bool RunAllTests(); // Clears the results of all tests, except the ad hoc tests. void ClearNonAdHocTestResult() { ForEach(test_cases_, TestCase::ClearTestCaseResult); } // Clears the results of ad-hoc test assertions. void ClearAdHocTestResult() { ad_hoc_test_result_.Clear(); } // Adds a TestProperty to the current TestResult object when invoked in a // context of a test or a test case, or to the global property set. If the // result already contains a property with the same key, the value will be // updated. void RecordProperty(const TestProperty& test_property); enum ReactionToSharding { HONOR_SHARDING_PROTOCOL, IGNORE_SHARDING_PROTOCOL }; // Matches the full name of each test against the user-specified // filter to decide whether the test should run, then records the // result in each TestCase and TestInfo object. // If shard_tests == HONOR_SHARDING_PROTOCOL, further filters tests // based on sharding variables in the environment. // Returns the number of tests that should run. int FilterTests(ReactionToSharding shard_tests); // Prints the names of the tests matching the user-specified filter flag. void ListTestsMatchingFilter(); const TestCase* current_test_case() const { return current_test_case_; } TestInfo* current_test_info() { return current_test_info_; } const TestInfo* current_test_info() const { return current_test_info_; } // Returns the vector of environments that need to be set-up/torn-down // before/after the tests are run. std::vector& environments() { return environments_; } // Getters for the per-thread Google Test trace stack. std::vector& gtest_trace_stack() { return *(gtest_trace_stack_.pointer()); } const std::vector& gtest_trace_stack() const { return gtest_trace_stack_.get(); } #if GTEST_HAS_DEATH_TEST void InitDeathTestSubprocessControlInfo() { internal_run_death_test_flag_.reset(ParseInternalRunDeathTestFlag()); } // Returns a pointer to the parsed --gtest_internal_run_death_test // flag, or NULL if that flag was not specified. // This information is useful only in a death test child process. // Must not be called before a call to InitGoogleTest. const InternalRunDeathTestFlag* internal_run_death_test_flag() const { return internal_run_death_test_flag_.get(); } // Returns a pointer to the current death test factory. internal::DeathTestFactory* death_test_factory() { return death_test_factory_.get(); } void SuppressTestEventsIfInSubprocess(); friend class ReplaceDeathTestFactory; #endif // GTEST_HAS_DEATH_TEST // Initializes the event listener performing XML output as specified by // UnitTestOptions. Must not be called before InitGoogleTest. void ConfigureXmlOutput(); #if GTEST_CAN_STREAM_RESULTS_ // Initializes the event listener for streaming test results to a socket. // Must not be called before InitGoogleTest. void ConfigureStreamingOutput(); #endif // Performs initialization dependent upon flag values obtained in // ParseGoogleTestFlagsOnly. Is called from InitGoogleTest after the call to // ParseGoogleTestFlagsOnly. In case a user neglects to call InitGoogleTest // this function is also called from RunAllTests. Since this function can be // called more than once, it has to be idempotent. void PostFlagParsingInit(); // Gets the random seed used at the start of the current test iteration. int random_seed() const { return random_seed_; } // Gets the random number generator. internal::Random* random() { return &random_; } // Shuffles all test cases, and the tests within each test case, // making sure that death tests are still run first. void ShuffleTests(); // Restores the test cases and tests to their order before the first shuffle. void UnshuffleTests(); // Returns the value of GTEST_FLAG(catch_exceptions) at the moment // UnitTest::Run() starts. bool catch_exceptions() const { return catch_exceptions_; } private: friend class ::testing::UnitTest; // Used by UnitTest::Run() to capture the state of // GTEST_FLAG(catch_exceptions) at the moment it starts. void set_catch_exceptions(bool value) { catch_exceptions_ = value; } // The UnitTest object that owns this implementation object. UnitTest* const parent_; // The working directory when the first TEST() or TEST_F() was // executed. internal::FilePath original_working_dir_; // The default test part result reporters. DefaultGlobalTestPartResultReporter default_global_test_part_result_reporter_; DefaultPerThreadTestPartResultReporter default_per_thread_test_part_result_reporter_; // Points to (but doesn't own) the global test part result reporter. TestPartResultReporterInterface* global_test_part_result_repoter_; // Protects read and write access to global_test_part_result_reporter_. internal::Mutex global_test_part_result_reporter_mutex_; // Points to (but doesn't own) the per-thread test part result reporter. internal::ThreadLocal per_thread_test_part_result_reporter_; // The vector of environments that need to be set-up/torn-down // before/after the tests are run. std::vector environments_; // The vector of TestCases in their original order. It owns the // elements in the vector. std::vector test_cases_; // Provides a level of indirection for the test case list to allow // easy shuffling and restoring the test case order. The i-th // element of this vector is the index of the i-th test case in the // shuffled order. std::vector test_case_indices_; #if GTEST_HAS_PARAM_TEST // ParameterizedTestRegistry object used to register value-parameterized // tests. internal::ParameterizedTestCaseRegistry parameterized_test_registry_; // Indicates whether RegisterParameterizedTests() has been called already. bool parameterized_tests_registered_; #endif // GTEST_HAS_PARAM_TEST // Index of the last death test case registered. Initially -1. int last_death_test_case_; // This points to the TestCase for the currently running test. It // changes as Google Test goes through one test case after another. // When no test is running, this is set to NULL and Google Test // stores assertion results in ad_hoc_test_result_. Initially NULL. TestCase* current_test_case_; // This points to the TestInfo for the currently running test. It // changes as Google Test goes through one test after another. When // no test is running, this is set to NULL and Google Test stores // assertion results in ad_hoc_test_result_. Initially NULL. TestInfo* current_test_info_; // Normally, a user only writes assertions inside a TEST or TEST_F, // or inside a function called by a TEST or TEST_F. Since Google // Test keeps track of which test is current running, it can // associate such an assertion with the test it belongs to. // // If an assertion is encountered when no TEST or TEST_F is running, // Google Test attributes the assertion result to an imaginary "ad hoc" // test, and records the result in ad_hoc_test_result_. TestResult ad_hoc_test_result_; // The list of event listeners that can be used to track events inside // Google Test. TestEventListeners listeners_; // The OS stack trace getter. Will be deleted when the UnitTest // object is destructed. By default, an OsStackTraceGetter is used, // but the user can set this field to use a custom getter if that is // desired. OsStackTraceGetterInterface* os_stack_trace_getter_; // True iff PostFlagParsingInit() has been called. bool post_flag_parse_init_performed_; // The random number seed used at the beginning of the test run. int random_seed_; // Our random number generator. internal::Random random_; // The time of the test program start, in ms from the start of the // UNIX epoch. TimeInMillis start_timestamp_; // How long the test took to run, in milliseconds. TimeInMillis elapsed_time_; #if GTEST_HAS_DEATH_TEST // The decomposed components of the gtest_internal_run_death_test flag, // parsed when RUN_ALL_TESTS is called. internal::scoped_ptr internal_run_death_test_flag_; internal::scoped_ptr death_test_factory_; #endif // GTEST_HAS_DEATH_TEST // A per-thread stack of traces created by the SCOPED_TRACE() macro. internal::ThreadLocal > gtest_trace_stack_; // The value of GTEST_FLAG(catch_exceptions) at the moment RunAllTests() // starts. bool catch_exceptions_; GTEST_DISALLOW_COPY_AND_ASSIGN_(UnitTestImpl); }; // class UnitTestImpl // Convenience function for accessing the global UnitTest // implementation object. inline UnitTestImpl* GetUnitTestImpl() { return UnitTest::GetInstance()->impl(); } #if GTEST_USES_SIMPLE_RE // Internal helper functions for implementing the simple regular // expression matcher. GTEST_API_ bool IsInSet(char ch, const char* str); GTEST_API_ bool IsAsciiDigit(char ch); GTEST_API_ bool IsAsciiPunct(char ch); GTEST_API_ bool IsRepeat(char ch); GTEST_API_ bool IsAsciiWhiteSpace(char ch); GTEST_API_ bool IsAsciiWordChar(char ch); GTEST_API_ bool IsValidEscape(char ch); GTEST_API_ bool AtomMatchesChar(bool escaped, char pattern, char ch); GTEST_API_ bool ValidateRegex(const char* regex); GTEST_API_ bool MatchRegexAtHead(const char* regex, const char* str); GTEST_API_ bool MatchRepetitionAndRegexAtHead( bool escaped, char ch, char repeat, const char* regex, const char* str); GTEST_API_ bool MatchRegexAnywhere(const char* regex, const char* str); #endif // GTEST_USES_SIMPLE_RE // Parses the command line for Google Test flags, without initializing // other parts of Google Test. GTEST_API_ void ParseGoogleTestFlagsOnly(int* argc, char** argv); GTEST_API_ void ParseGoogleTestFlagsOnly(int* argc, wchar_t** argv); #if GTEST_HAS_DEATH_TEST // Returns the message describing the last system error, regardless of the // platform. GTEST_API_ 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 // it here. template bool ParseNaturalNumber(const ::std::string& str, Integer* number) { // Fail fast if the given string does not begin with a digit; // this bypasses strtoXXX's "optional leading whitespace and plus // or minus sign" semantics, which are undesirable here. if (str.empty() || !IsDigit(str[0])) { return false; } errno = 0; char* end; // BiggestConvertible is the largest integer type that system-provided // string-to-number conversion routines can return. # if GTEST_OS_WINDOWS && !defined(__GNUC__) // MSVC and C++ Builder define __int64 instead of the standard long long. typedef unsigned __int64 BiggestConvertible; const BiggestConvertible parsed = _strtoui64(str.c_str(), &end, 10); # else typedef unsigned long long BiggestConvertible; // NOLINT const BiggestConvertible parsed = strtoull(str.c_str(), &end, 10); # endif // GTEST_OS_WINDOWS && !defined(__GNUC__) const bool parse_success = *end == '\0' && errno == 0; // TODO(vladl@google.com): Convert this to compile time assertion when it is // available. GTEST_CHECK_(sizeof(Integer) <= sizeof(parsed)); const Integer result = static_cast(parsed); if (parse_success && static_cast(result) == parsed) { *number = result; return true; } return false; } #endif // GTEST_HAS_DEATH_TEST // TestResult contains some private methods that should be hidden from // Google Test user but are required for testing. This class allow our tests // to access them. // // This class is supplied only for the purpose of testing Google Test's own // constructs. Do not use it in user tests, either directly or indirectly. class TestResultAccessor { public: static void RecordProperty(TestResult* test_result, const std::string& xml_element, const TestProperty& property) { test_result->RecordProperty(xml_element, property); } static void ClearTestPartResults(TestResult* test_result) { test_result->ClearTestPartResults(); } static const std::vector& test_part_results( const TestResult& test_result) { return test_result.test_part_results(); } }; #if GTEST_CAN_STREAM_RESULTS_ // Streams test results to the given port on the given host machine. class StreamingListener : public EmptyTestEventListener { public: // Abstract base class for writing strings to a socket. class AbstractSocketWriter { public: virtual ~AbstractSocketWriter() {} // Sends a string to the socket. virtual void Send(const string& message) = 0; // Closes the socket. virtual void CloseConnection() {} // Sends a string and a newline to the socket. void SendLn(const string& message) { Send(message + "\n"); } }; // Concrete class for actually writing strings to a socket. class SocketWriter : public AbstractSocketWriter { public: SocketWriter(const string& host, const string& port) : sockfd_(-1), host_name_(host), port_num_(port) { MakeConnection(); } virtual ~SocketWriter() { if (sockfd_ != -1) CloseConnection(); } // Sends a string to the socket. virtual void Send(const string& message) { GTEST_CHECK_(sockfd_ != -1) << "Send() can be called only when there is a connection."; const int len = static_cast(message.length()); if (write(sockfd_, message.c_str(), len) != len) { GTEST_LOG_(WARNING) << "stream_result_to: failed to stream to " << host_name_ << ":" << port_num_; } } private: // Creates a client socket and connects to the server. void MakeConnection(); // Closes the socket. void CloseConnection() { GTEST_CHECK_(sockfd_ != -1) << "CloseConnection() can be called only when there is a connection."; close(sockfd_); sockfd_ = -1; } int sockfd_; // socket file descriptor const string host_name_; const string port_num_; GTEST_DISALLOW_COPY_AND_ASSIGN_(SocketWriter); }; // class SocketWriter // Escapes '=', '&', '%', and '\n' characters in str as "%xx". static string UrlEncode(const char* str); StreamingListener(const string& host, const string& port) : socket_writer_(new SocketWriter(host, port)) { Start(); } explicit StreamingListener(AbstractSocketWriter* socket_writer) : socket_writer_(socket_writer) { Start(); } void OnTestProgramStart(const UnitTest& /* unit_test */) { SendLn("event=TestProgramStart"); } void OnTestProgramEnd(const UnitTest& unit_test) { // Note that Google Test current only report elapsed time for each // test iteration, not for the entire test program. SendLn("event=TestProgramEnd&passed=" + FormatBool(unit_test.Passed())); // Notify the streaming server to stop. socket_writer_->CloseConnection(); } void OnTestIterationStart(const UnitTest& /* unit_test */, int iteration) { SendLn("event=TestIterationStart&iteration=" + StreamableToString(iteration)); } void OnTestIterationEnd(const UnitTest& unit_test, int /* iteration */) { SendLn("event=TestIterationEnd&passed=" + FormatBool(unit_test.Passed()) + "&elapsed_time=" + StreamableToString(unit_test.elapsed_time()) + "ms"); } void OnTestCaseStart(const TestCase& test_case) { SendLn(std::string("event=TestCaseStart&name=") + test_case.name()); } void OnTestCaseEnd(const TestCase& test_case) { SendLn("event=TestCaseEnd&passed=" + FormatBool(test_case.Passed()) + "&elapsed_time=" + StreamableToString(test_case.elapsed_time()) + "ms"); } void OnTestStart(const TestInfo& test_info) { SendLn(std::string("event=TestStart&name=") + test_info.name()); } void OnTestEnd(const TestInfo& test_info) { SendLn("event=TestEnd&passed=" + FormatBool((test_info.result())->Passed()) + "&elapsed_time=" + StreamableToString((test_info.result())->elapsed_time()) + "ms"); } void OnTestPartResult(const TestPartResult& test_part_result) { const char* file_name = test_part_result.file_name(); if (file_name == NULL) file_name = ""; SendLn("event=TestPartResult&file=" + UrlEncode(file_name) + "&line=" + StreamableToString(test_part_result.line_number()) + "&message=" + UrlEncode(test_part_result.message())); } private: // Sends the given message and a newline to the socket. void SendLn(const string& message) { socket_writer_->SendLn(message); } // Called at the start of streaming to notify the receiver what // protocol we are using. void Start() { SendLn("gtest_streaming_protocol_version=1.0"); } string FormatBool(bool value) { return value ? "1" : "0"; } const scoped_ptr socket_writer_; GTEST_DISALLOW_COPY_AND_ASSIGN_(StreamingListener); }; // class StreamingListener #endif // GTEST_CAN_STREAM_RESULTS_ } // namespace internal } // namespace testing #endif // GTEST_SRC_GTEST_INTERNAL_INL_H_ dlt-daemon-2.18.4/gtest-1.7.0/src/gtest-port.cc000066400000000000000000000655121353342203500206400ustar00rootroot00000000000000// Copyright 2008, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: wan@google.com (Zhanyong Wan) #include "gtest/internal/gtest-port.h" #include #include #include #include #if GTEST_OS_WINDOWS_MOBILE # include // For TerminateProcess() #elif GTEST_OS_WINDOWS # include # include #else # include #endif // GTEST_OS_WINDOWS_MOBILE #if GTEST_OS_MAC # include # include # include #endif // GTEST_OS_MAC #if GTEST_OS_QNX # include # include #endif // GTEST_OS_QNX #include "gtest/gtest-spi.h" #include "gtest/gtest-message.h" #include "gtest/internal/gtest-internal.h" #include "gtest/internal/gtest-string.h" // Indicates that this translation unit is part of Google Test's // implementation. It must come before gtest-internal-inl.h is // included, or there will be a compiler error. This trick is to // prevent a user from accidentally including gtest-internal-inl.h in // his code. #define GTEST_IMPLEMENTATION_ 1 #include "src/gtest-internal-inl.h" #undef GTEST_IMPLEMENTATION_ namespace testing { namespace internal { #if defined(_MSC_VER) || defined(__BORLANDC__) // MSVC and C++Builder do not provide a definition of STDERR_FILENO. const int kStdOutFileno = 1; const int kStdErrFileno = 2; #else const int kStdOutFileno = STDOUT_FILENO; const int kStdErrFileno = STDERR_FILENO; #endif // _MSC_VER #if GTEST_OS_MAC // Returns the number of threads running in the process, or 0 to indicate that // we cannot detect it. size_t GetThreadCount() { const task_t task = mach_task_self(); mach_msg_type_number_t thread_count; thread_act_array_t thread_list; const kern_return_t status = task_threads(task, &thread_list, &thread_count); if (status == KERN_SUCCESS) { // task_threads allocates resources in thread_list and we need to free them // to avoid leaks. vm_deallocate(task, reinterpret_cast(thread_list), sizeof(thread_t) * thread_count); return static_cast(thread_count); } else { return 0; } } #elif GTEST_OS_QNX // Returns the number of threads running in the process, or 0 to indicate that // we cannot detect it. size_t GetThreadCount() { const int fd = open("/proc/self/as", O_RDONLY); if (fd < 0) { return 0; } procfs_info process_info; const int status = devctl(fd, DCMD_PROC_INFO, &process_info, sizeof(process_info), NULL); close(fd); if (status == EOK) { return static_cast(process_info.num_threads); } else { return 0; } } #else size_t GetThreadCount() { // There's no portable way to detect the number of threads, so we just // return 0 to indicate that we cannot detect it. return 0; } #endif // GTEST_OS_MAC #if GTEST_USES_POSIX_RE // Implements RE. Currently only needed for death tests. RE::~RE() { if (is_valid_) { // regfree'ing an invalid regex might crash because the content // of the regex is undefined. Since the regex's are essentially // the same, one cannot be valid (or invalid) without the other // being so too. regfree(&partial_regex_); regfree(&full_regex_); } free(const_cast(pattern_)); } // Returns true iff regular expression re matches the entire str. bool RE::FullMatch(const char* str, const RE& re) { if (!re.is_valid_) return false; regmatch_t match; return regexec(&re.full_regex_, str, 1, &match, 0) == 0; } // Returns true iff regular expression re matches a substring of str // (including str itself). bool RE::PartialMatch(const char* str, const RE& re) { if (!re.is_valid_) return false; regmatch_t match; return regexec(&re.partial_regex_, str, 1, &match, 0) == 0; } // Initializes an RE from its string representation. void RE::Init(const char* regex) { pattern_ = posix::StrDup(regex); // Reserves enough bytes to hold the regular expression used for a // full match. const size_t full_regex_len = strlen(regex) + 10; char* const full_pattern = new char[full_regex_len]; snprintf(full_pattern, full_regex_len, "^(%s)$", regex); is_valid_ = regcomp(&full_regex_, full_pattern, REG_EXTENDED) == 0; // We want to call regcomp(&partial_regex_, ...) even if the // previous expression returns false. Otherwise partial_regex_ may // not be properly initialized can may cause trouble when it's // freed. // // Some implementation of POSIX regex (e.g. on at least some // versions of Cygwin) doesn't accept the empty string as a valid // regex. We change it to an equivalent form "()" to be safe. if (is_valid_) { const char* const partial_regex = (*regex == '\0') ? "()" : regex; is_valid_ = regcomp(&partial_regex_, partial_regex, REG_EXTENDED) == 0; } EXPECT_TRUE(is_valid_) << "Regular expression \"" << regex << "\" is not a valid POSIX Extended regular expression."; delete[] full_pattern; } #elif GTEST_USES_SIMPLE_RE // Returns true iff ch appears anywhere in str (excluding the // terminating '\0' character). bool IsInSet(char ch, const char* str) { return ch != '\0' && strchr(str, ch) != NULL; } // Returns true iff ch belongs to the given classification. Unlike // similar functions in , these aren't affected by the // current locale. bool IsAsciiDigit(char ch) { return '0' <= ch && ch <= '9'; } bool IsAsciiPunct(char ch) { return IsInSet(ch, "^-!\"#$%&'()*+,./:;<=>?@[\\]_`{|}~"); } bool IsRepeat(char ch) { return IsInSet(ch, "?*+"); } bool IsAsciiWhiteSpace(char ch) { return IsInSet(ch, " \f\n\r\t\v"); } bool IsAsciiWordChar(char ch) { return ('a' <= ch && ch <= 'z') || ('A' <= ch && ch <= 'Z') || ('0' <= ch && ch <= '9') || ch == '_'; } // Returns true iff "\\c" is a supported escape sequence. bool IsValidEscape(char c) { return (IsAsciiPunct(c) || IsInSet(c, "dDfnrsStvwW")); } // Returns true iff the given atom (specified by escaped and pattern) // matches ch. The result is undefined if the atom is invalid. bool AtomMatchesChar(bool escaped, char pattern_char, char ch) { if (escaped) { // "\\p" where p is pattern_char. switch (pattern_char) { case 'd': return IsAsciiDigit(ch); case 'D': return !IsAsciiDigit(ch); case 'f': return ch == '\f'; case 'n': return ch == '\n'; case 'r': return ch == '\r'; case 's': return IsAsciiWhiteSpace(ch); case 'S': return !IsAsciiWhiteSpace(ch); case 't': return ch == '\t'; case 'v': return ch == '\v'; case 'w': return IsAsciiWordChar(ch); case 'W': return !IsAsciiWordChar(ch); } return IsAsciiPunct(pattern_char) && pattern_char == ch; } return (pattern_char == '.' && ch != '\n') || pattern_char == ch; } // Helper function used by ValidateRegex() to format error messages. std::string FormatRegexSyntaxError(const char* regex, int index) { return (Message() << "Syntax error at index " << index << " in simple regular expression \"" << regex << "\": ").GetString(); } // Generates non-fatal failures and returns false if regex is invalid; // otherwise returns true. bool ValidateRegex(const char* regex) { if (regex == NULL) { // TODO(wan@google.com): fix the source file location in the // assertion failures to match where the regex is used in user // code. ADD_FAILURE() << "NULL is not a valid simple regular expression."; return false; } bool is_valid = true; // True iff ?, *, or + can follow the previous atom. bool prev_repeatable = false; for (int i = 0; regex[i]; i++) { if (regex[i] == '\\') { // An escape sequence i++; if (regex[i] == '\0') { ADD_FAILURE() << FormatRegexSyntaxError(regex, i - 1) << "'\\' cannot appear at the end."; return false; } if (!IsValidEscape(regex[i])) { ADD_FAILURE() << FormatRegexSyntaxError(regex, i - 1) << "invalid escape sequence \"\\" << regex[i] << "\"."; is_valid = false; } prev_repeatable = true; } else { // Not an escape sequence. const char ch = regex[i]; if (ch == '^' && i > 0) { ADD_FAILURE() << FormatRegexSyntaxError(regex, i) << "'^' can only appear at the beginning."; is_valid = false; } else if (ch == '$' && regex[i + 1] != '\0') { ADD_FAILURE() << FormatRegexSyntaxError(regex, i) << "'$' can only appear at the end."; is_valid = false; } else if (IsInSet(ch, "()[]{}|")) { ADD_FAILURE() << FormatRegexSyntaxError(regex, i) << "'" << ch << "' is unsupported."; is_valid = false; } else if (IsRepeat(ch) && !prev_repeatable) { ADD_FAILURE() << FormatRegexSyntaxError(regex, i) << "'" << ch << "' can only follow a repeatable token."; is_valid = false; } prev_repeatable = !IsInSet(ch, "^$?*+"); } } return is_valid; } // Matches a repeated regex atom followed by a valid simple regular // expression. The regex atom is defined as c if escaped is false, // or \c otherwise. repeat is the repetition meta character (?, *, // or +). The behavior is undefined if str contains too many // characters to be indexable by size_t, in which case the test will // probably time out anyway. We are fine with this limitation as // std::string has it too. bool MatchRepetitionAndRegexAtHead( bool escaped, char c, char repeat, const char* regex, const char* str) { const size_t min_count = (repeat == '+') ? 1 : 0; const size_t max_count = (repeat == '?') ? 1 : static_cast(-1) - 1; // We cannot call numeric_limits::max() as it conflicts with the // max() macro on Windows. for (size_t i = 0; i <= max_count; ++i) { // We know that the atom matches each of the first i characters in str. if (i >= min_count && MatchRegexAtHead(regex, str + i)) { // We have enough matches at the head, and the tail matches too. // Since we only care about *whether* the pattern matches str // (as opposed to *how* it matches), there is no need to find a // greedy match. return true; } if (str[i] == '\0' || !AtomMatchesChar(escaped, c, str[i])) return false; } return false; } // Returns true iff regex matches a prefix of str. regex must be a // valid simple regular expression and not start with "^", or the // result is undefined. bool MatchRegexAtHead(const char* regex, const char* str) { if (*regex == '\0') // An empty regex matches a prefix of anything. return true; // "$" only matches the end of a string. Note that regex being // valid guarantees that there's nothing after "$" in it. if (*regex == '$') return *str == '\0'; // Is the first thing in regex an escape sequence? const bool escaped = *regex == '\\'; if (escaped) ++regex; if (IsRepeat(regex[1])) { // MatchRepetitionAndRegexAtHead() calls MatchRegexAtHead(), so // here's an indirect recursion. It terminates as the regex gets // shorter in each recursion. return MatchRepetitionAndRegexAtHead( escaped, regex[0], regex[1], regex + 2, str); } else { // regex isn't empty, isn't "$", and doesn't start with a // repetition. We match the first atom of regex with the first // character of str and recurse. return (*str != '\0') && AtomMatchesChar(escaped, *regex, *str) && MatchRegexAtHead(regex + 1, str + 1); } } // Returns true iff regex matches any substring of str. regex must be // a valid simple regular expression, or the result is undefined. // // The algorithm is recursive, but the recursion depth doesn't exceed // the regex length, so we won't need to worry about running out of // stack space normally. In rare cases the time complexity can be // exponential with respect to the regex length + the string length, // but usually it's must faster (often close to linear). bool MatchRegexAnywhere(const char* regex, const char* str) { if (regex == NULL || str == NULL) return false; if (*regex == '^') return MatchRegexAtHead(regex + 1, str); // A successful match can be anywhere in str. do { if (MatchRegexAtHead(regex, str)) return true; } while (*str++ != '\0'); return false; } // Implements the RE class. RE::~RE() { free(const_cast(pattern_)); free(const_cast(full_pattern_)); } // Returns true iff regular expression re matches the entire str. bool RE::FullMatch(const char* str, const RE& re) { return re.is_valid_ && MatchRegexAnywhere(re.full_pattern_, str); } // Returns true iff regular expression re matches a substring of str // (including str itself). bool RE::PartialMatch(const char* str, const RE& re) { return re.is_valid_ && MatchRegexAnywhere(re.pattern_, str); } // Initializes an RE from its string representation. void RE::Init(const char* regex) { pattern_ = full_pattern_ = NULL; if (regex != NULL) { pattern_ = posix::StrDup(regex); } is_valid_ = ValidateRegex(regex); if (!is_valid_) { // No need to calculate the full pattern when the regex is invalid. return; } const size_t len = strlen(regex); // Reserves enough bytes to hold the regular expression used for a // full match: we need space to prepend a '^', append a '$', and // terminate the string with '\0'. char* buffer = static_cast(malloc(len + 3)); full_pattern_ = buffer; if (*regex != '^') *buffer++ = '^'; // Makes sure full_pattern_ starts with '^'. // We don't use snprintf or strncpy, as they trigger a warning when // compiled with VC++ 8.0. memcpy(buffer, regex, len); buffer += len; if (len == 0 || regex[len - 1] != '$') *buffer++ = '$'; // Makes sure full_pattern_ ends with '$'. *buffer = '\0'; } #endif // GTEST_USES_POSIX_RE const char kUnknownFile[] = "unknown file"; // Formats a source file path and a line number as they would appear // in an error message from the compiler used to compile this code. GTEST_API_ ::std::string FormatFileLocation(const char* file, int line) { const std::string file_name(file == NULL ? kUnknownFile : file); if (line < 0) { return file_name + ":"; } #ifdef _MSC_VER return file_name + "(" + StreamableToString(line) + "):"; #else return file_name + ":" + StreamableToString(line) + ":"; #endif // _MSC_VER } // Formats a file location for compiler-independent XML output. // Although this function is not platform dependent, we put it next to // FormatFileLocation in order to contrast the two functions. // Note that FormatCompilerIndependentFileLocation() does NOT append colon // to the file location it produces, unlike FormatFileLocation(). GTEST_API_ ::std::string FormatCompilerIndependentFileLocation( const char* file, int line) { const std::string file_name(file == NULL ? kUnknownFile : file); if (line < 0) return file_name; else return file_name + ":" + StreamableToString(line); } GTestLog::GTestLog(GTestLogSeverity severity, const char* file, int line) : severity_(severity) { const char* const marker = severity == GTEST_INFO ? "[ INFO ]" : severity == GTEST_WARNING ? "[WARNING]" : severity == GTEST_ERROR ? "[ ERROR ]" : "[ FATAL ]"; GetStream() << ::std::endl << marker << " " << FormatFileLocation(file, line).c_str() << ": "; } // Flushes the buffers and, if severity is GTEST_FATAL, aborts the program. GTestLog::~GTestLog() { GetStream() << ::std::endl; if (severity_ == GTEST_FATAL) { fflush(stderr); posix::Abort(); } } // Disable Microsoft deprecation warnings for POSIX functions called from // this class (creat, dup, dup2, and close) #ifdef _MSC_VER # pragma warning(push) # pragma warning(disable: 4996) #endif // _MSC_VER #if GTEST_HAS_STREAM_REDIRECTION // Object that captures an output stream (stdout/stderr). class CapturedStream { public: // The ctor redirects the stream to a temporary file. explicit CapturedStream(int fd) : fd_(fd), uncaptured_fd_(dup(fd)) { # if GTEST_OS_WINDOWS char temp_dir_path[MAX_PATH + 1] = { '\0' }; // NOLINT char temp_file_path[MAX_PATH + 1] = { '\0' }; // NOLINT ::GetTempPathA(sizeof(temp_dir_path), temp_dir_path); const UINT success = ::GetTempFileNameA(temp_dir_path, "gtest_redir", 0, // Generate unique file name. temp_file_path); GTEST_CHECK_(success != 0) << "Unable to create a temporary file in " << temp_dir_path; const int captured_fd = creat(temp_file_path, _S_IREAD | _S_IWRITE); GTEST_CHECK_(captured_fd != -1) << "Unable to open temporary file " << temp_file_path; filename_ = temp_file_path; # else // There's no guarantee that a test has write access to the current // directory, so we create the temporary file in the /tmp directory // instead. We use /tmp on most systems, and /sdcard on Android. // That's because Android doesn't have /tmp. # if GTEST_OS_LINUX_ANDROID // Note: Android applications are expected to call the framework's // Context.getExternalStorageDirectory() method through JNI to get // the location of the world-writable SD Card directory. However, // this requires a Context handle, which cannot be retrieved // globally from native code. Doing so also precludes running the // code as part of a regular standalone executable, which doesn't // run in a Dalvik process (e.g. when running it through 'adb shell'). // // The location /sdcard is directly accessible from native code // and is the only location (unofficially) supported by the Android // team. It's generally a symlink to the real SD Card mount point // which can be /mnt/sdcard, /mnt/sdcard0, /system/media/sdcard, or // other OEM-customized locations. Never rely on these, and always // use /sdcard. char name_template[] = "/sdcard/gtest_captured_stream.XXXXXX"; # else char name_template[] = "/tmp/captured_stream.XXXXXX"; # endif // GTEST_OS_LINUX_ANDROID const int captured_fd = mkstemp(name_template); filename_ = name_template; # endif // GTEST_OS_WINDOWS fflush(NULL); dup2(captured_fd, fd_); close(captured_fd); } ~CapturedStream() { remove(filename_.c_str()); } std::string GetCapturedString() { if (uncaptured_fd_ != -1) { // Restores the original stream. fflush(NULL); dup2(uncaptured_fd_, fd_); close(uncaptured_fd_); uncaptured_fd_ = -1; } FILE* const file = posix::FOpen(filename_.c_str(), "r"); const std::string content = ReadEntireFile(file); posix::FClose(file); return content; } 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. ::std::string filename_; GTEST_DISALLOW_COPY_AND_ASSIGN_(CapturedStream); }; // Returns the size (in bytes) of a file. size_t CapturedStream::GetFileSize(FILE* file) { fseek(file, 0, SEEK_END); return static_cast(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 static CapturedStream* g_captured_stderr = NULL; static CapturedStream* g_captured_stdout = NULL; // Starts capturing an output stream (stdout/stderr). void CaptureStream(int fd, const char* stream_name, CapturedStream** stream) { if (*stream != NULL) { GTEST_LOG_(FATAL) << "Only one " << stream_name << " capturer can exist at a time."; } *stream = new CapturedStream(fd); } // Stops capturing the output stream and returns the captured string. std::string GetCapturedStream(CapturedStream** captured_stream) { const std::string content = (*captured_stream)->GetCapturedString(); delete *captured_stream; *captured_stream = NULL; return content; } // Starts capturing stdout. void CaptureStdout() { CaptureStream(kStdOutFileno, "stdout", &g_captured_stdout); } // Starts capturing stderr. void CaptureStderr() { CaptureStream(kStdErrFileno, "stderr", &g_captured_stderr); } // Stops capturing stdout and returns the captured string. std::string GetCapturedStdout() { return GetCapturedStream(&g_captured_stdout); } // Stops capturing stderr and returns the captured string. std::string GetCapturedStderr() { return GetCapturedStream(&g_captured_stderr); } #endif // GTEST_HAS_STREAM_REDIRECTION #if GTEST_HAS_DEATH_TEST // A copy of all command line arguments. Set by InitGoogleTest(). ::std::vector g_argvs; static const ::std::vector* g_injected_test_argvs = NULL; // Owned. void SetInjectableArgvs(const ::std::vector* argvs) { if (g_injected_test_argvs != argvs) delete g_injected_test_argvs; g_injected_test_argvs = argvs; } const ::std::vector& GetInjectableArgvs() { if (g_injected_test_argvs != NULL) { return *g_injected_test_argvs; } return g_argvs; } #endif // GTEST_HAS_DEATH_TEST #if GTEST_OS_WINDOWS_MOBILE namespace posix { void Abort() { DebugBreak(); TerminateProcess(GetCurrentProcess(), 1); } } // namespace posix #endif // GTEST_OS_WINDOWS_MOBILE // Returns the name of the environment variable corresponding to the // given flag. For example, FlagToEnvVar("foo") will return // "GTEST_FOO" in the open-source version. static std::string FlagToEnvVar(const char* flag) { const std::string full_flag = (Message() << GTEST_FLAG_PREFIX_ << flag).GetString(); Message env_var; for (size_t i = 0; i != full_flag.length(); i++) { env_var << ToUpper(full_flag.c_str()[i]); } return env_var.GetString(); } // Parses 'str' for a 32-bit signed integer. If successful, writes // the result to *value and returns true; otherwise leaves *value // unchanged and returns false. bool ParseInt32(const Message& src_text, const char* str, Int32* value) { // Parses the environment variable as a decimal integer. char* end = NULL; const long long_value = strtol(str, &end, 10); // NOLINT // Has strtol() consumed all characters in the string? if (*end != '\0') { // No - an invalid character was encountered. Message msg; msg << "WARNING: " << src_text << " is expected to be a 32-bit integer, but actually" << " has value \"" << str << "\".\n"; printf("%s", msg.GetString().c_str()); fflush(stdout); return false; } // Is the parsed value in the range of an Int32? const Int32 result = static_cast(long_value); if (long_value == LONG_MAX || long_value == LONG_MIN || // The parsed value overflows as a long. (strtol() returns // LONG_MAX or LONG_MIN when the input overflows.) result != long_value // The parsed value overflows as an Int32. ) { Message msg; msg << "WARNING: " << src_text << " is expected to be a 32-bit integer, but actually" << " has value " << str << ", which overflows.\n"; printf("%s", msg.GetString().c_str()); fflush(stdout); return false; } *value = result; return true; } // Reads and returns the Boolean environment variable corresponding to // the given flag; if it's not set, returns default_value. // // The value is considered true iff it's not "0". bool BoolFromGTestEnv(const char* flag, bool default_value) { const std::string env_var = FlagToEnvVar(flag); const char* const string_value = posix::GetEnv(env_var.c_str()); return string_value == NULL ? default_value : strcmp(string_value, "0") != 0; } // Reads and returns a 32-bit integer stored in the environment // variable corresponding to the given flag; if it isn't set or // doesn't represent a valid 32-bit integer, returns default_value. Int32 Int32FromGTestEnv(const char* flag, Int32 default_value) { const std::string env_var = FlagToEnvVar(flag); const char* const string_value = posix::GetEnv(env_var.c_str()); if (string_value == NULL) { // The environment variable is not set. return default_value; } Int32 result = default_value; if (!ParseInt32(Message() << "Environment variable " << env_var, string_value, &result)) { printf("The default value %s is used.\n", (Message() << default_value).GetString().c_str()); fflush(stdout); return default_value; } return result; } // Reads and returns the string environment variable corresponding to // the given flag; if it's not set, returns default_value. const char* StringFromGTestEnv(const char* flag, const char* default_value) { const std::string env_var = FlagToEnvVar(flag); const char* const value = posix::GetEnv(env_var.c_str()); return value == NULL ? default_value : value; } } // namespace internal } // namespace testing dlt-daemon-2.18.4/gtest-1.7.0/src/gtest-printers.cc000066400000000000000000000277631353342203500215300ustar00rootroot00000000000000// Copyright 2007, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: wan@google.com (Zhanyong Wan) // Google Test - The Google C++ Testing Framework // // This file implements a universal value printer that can print a // value of any type T: // // void ::testing::internal::UniversalPrinter::Print(value, ostream_ptr); // // It uses the << operator when possible, and prints the bytes in the // object otherwise. A user can override its behavior for a class // type Foo by defining either operator<<(::std::ostream&, const Foo&) // or void PrintTo(const Foo&, ::std::ostream*) in the namespace that // defines Foo. #include "gtest/gtest-printers.h" #include #include #include // NOLINT #include #include "gtest/internal/gtest-port.h" namespace testing { namespace { using ::std::ostream; // Prints a segment of bytes in the given object. void PrintByteSegmentInObjectTo(const unsigned char* obj_bytes, size_t start, size_t count, ostream* os) { char text[5] = ""; for (size_t i = 0; i != count; i++) { const size_t j = start + i; if (i != 0) { // Organizes the bytes into groups of 2 for easy parsing by // human. if ((j % 2) == 0) *os << ' '; else *os << '-'; } GTEST_SNPRINTF_(text, sizeof(text), "%02X", obj_bytes[j]); *os << text; } } // Prints the bytes in the given value to the given ostream. void PrintBytesInObjectToImpl(const unsigned char* obj_bytes, size_t count, ostream* os) { // Tells the user how big the object is. *os << count << "-byte object <"; const size_t kThreshold = 132; const size_t kChunkSize = 64; // If the object size is bigger than kThreshold, we'll have to omit // some details by printing only the first and the last kChunkSize // bytes. // TODO(wan): let the user control the threshold using a flag. if (count < kThreshold) { PrintByteSegmentInObjectTo(obj_bytes, 0, count, os); } else { PrintByteSegmentInObjectTo(obj_bytes, 0, kChunkSize, os); *os << " ... "; // Rounds up to 2-byte boundary. const size_t resume_pos = (count - kChunkSize + 1)/2*2; PrintByteSegmentInObjectTo(obj_bytes, resume_pos, count - resume_pos, os); } *os << ">"; } } // namespace namespace internal2 { // Delegates to PrintBytesInObjectToImpl() to print the bytes in the // given object. The delegation simplifies the implementation, which // uses the << operator and thus is easier done outside of the // ::testing::internal namespace, which contains a << operator that // sometimes conflicts with the one in STL. void PrintBytesInObjectTo(const unsigned char* obj_bytes, size_t count, ostream* os) { PrintBytesInObjectToImpl(obj_bytes, count, os); } } // namespace internal2 namespace internal { // Depending on the value of a char (or wchar_t), we print it in one // of three formats: // - as is if it's a printable ASCII (e.g. 'a', '2', ' '), // - as a hexidecimal escape sequence (e.g. '\x7F'), or // - as a special escape sequence (e.g. '\r', '\n'). enum CharFormat { kAsIs, kHexEscape, kSpecialEscape }; // Returns true if c is a printable ASCII character. We test the // value of c directly instead of calling isprint(), which is buggy on // Windows Mobile. inline bool IsPrintableAscii(wchar_t c) { return 0x20 <= c && c <= 0x7E; } // Prints a wide or narrow char c as a character literal without the // quotes, escaping it when necessary; returns how c was formatted. // The template argument UnsignedChar is the unsigned version of Char, // which is the type of c. template static CharFormat PrintAsCharLiteralTo(Char c, ostream* os) { switch (static_cast(c)) { case L'\0': *os << "\\0"; break; case L'\'': *os << "\\'"; break; case L'\\': *os << "\\\\"; break; case L'\a': *os << "\\a"; break; case L'\b': *os << "\\b"; break; case L'\f': *os << "\\f"; break; case L'\n': *os << "\\n"; break; case L'\r': *os << "\\r"; break; case L'\t': *os << "\\t"; break; case L'\v': *os << "\\v"; break; default: if (IsPrintableAscii(c)) { *os << static_cast(c); return kAsIs; } else { *os << "\\x" + String::FormatHexInt(static_cast(c)); return kHexEscape; } } return kSpecialEscape; } // Prints a wchar_t c as if it's part of a string literal, escaping it when // necessary; returns how c was formatted. static CharFormat PrintAsStringLiteralTo(wchar_t c, ostream* os) { switch (c) { case L'\'': *os << "'"; return kAsIs; case L'"': *os << "\\\""; return kSpecialEscape; default: return PrintAsCharLiteralTo(c, os); } } // Prints a char c as if it's part of a string literal, escaping it when // necessary; returns how c was formatted. static CharFormat PrintAsStringLiteralTo(char c, ostream* os) { return PrintAsStringLiteralTo( static_cast(static_cast(c)), os); } // Prints a wide or narrow character c and its code. '\0' is printed // as "'\\0'", other unprintable characters are also properly escaped // using the standard C++ escape sequence. The template argument // UnsignedChar is the unsigned version of Char, which is the type of c. template void PrintCharAndCodeTo(Char c, ostream* os) { // First, print c as a literal in the most readable form we can find. *os << ((sizeof(c) > 1) ? "L'" : "'"); const CharFormat format = PrintAsCharLiteralTo(c, os); *os << "'"; // To aid user debugging, we also print c's code in decimal, unless // it's 0 (in which case c was printed as '\\0', making the code // obvious). if (c == 0) return; *os << " (" << static_cast(c); // For more convenience, we print c's code again in hexidecimal, // unless c was already printed in the form '\x##' or the code is in // [1, 9]. if (format == kHexEscape || (1 <= c && c <= 9)) { // Do nothing. } else { *os << ", 0x" << String::FormatHexInt(static_cast(c)); } *os << ")"; } void PrintTo(unsigned char c, ::std::ostream* os) { PrintCharAndCodeTo(c, os); } void PrintTo(signed char c, ::std::ostream* os) { PrintCharAndCodeTo(c, os); } // Prints a wchar_t as a symbol if it is printable or as its internal // code otherwise and also as its code. L'\0' is printed as "L'\\0'". void PrintTo(wchar_t wc, ostream* os) { PrintCharAndCodeTo(wc, os); } // Prints the given array of characters to the ostream. CharType must be either // char or wchar_t. // The array starts at begin, the length is len, it may include '\0' characters // and may not be NUL-terminated. template static void PrintCharsAsStringTo( const CharType* begin, size_t len, ostream* os) { const char* const kQuoteBegin = sizeof(CharType) == 1 ? "\"" : "L\""; *os << kQuoteBegin; bool is_previous_hex = false; for (size_t index = 0; index < len; ++index) { const CharType cur = begin[index]; if (is_previous_hex && IsXDigit(cur)) { // Previous character is of '\x..' form and this character can be // interpreted as another hexadecimal digit in its number. Break string to // disambiguate. *os << "\" " << kQuoteBegin; } is_previous_hex = PrintAsStringLiteralTo(cur, os) == kHexEscape; } *os << "\""; } // Prints a (const) char/wchar_t array of 'len' elements, starting at address // 'begin'. CharType must be either char or wchar_t. template static void UniversalPrintCharArray( const CharType* begin, size_t len, ostream* os) { // The code // const char kFoo[] = "foo"; // generates an array of 4, not 3, elements, with the last one being '\0'. // // Therefore when printing a char array, we don't print the last element if // it's '\0', such that the output matches the string literal as it's // written in the source code. if (len > 0 && begin[len - 1] == '\0') { PrintCharsAsStringTo(begin, len - 1, os); return; } // If, however, the last element in the array is not '\0', e.g. // const char kFoo[] = { 'f', 'o', 'o' }; // we must print the entire array. We also print a message to indicate // that the array is not NUL-terminated. PrintCharsAsStringTo(begin, len, os); *os << " (no terminating NUL)"; } // Prints a (const) char array of 'len' elements, starting at address 'begin'. void UniversalPrintArray(const char* begin, size_t len, ostream* os) { UniversalPrintCharArray(begin, len, os); } // Prints a (const) wchar_t array of 'len' elements, starting at address // 'begin'. void UniversalPrintArray(const wchar_t* begin, size_t len, ostream* os) { UniversalPrintCharArray(begin, len, os); } // Prints the given C string to the ostream. void PrintTo(const char* s, ostream* os) { if (s == NULL) { *os << "NULL"; } else { *os << ImplicitCast_(s) << " pointing to "; PrintCharsAsStringTo(s, strlen(s), os); } } // MSVC compiler can be configured to define whar_t as a typedef // of unsigned short. Defining an overload for const wchar_t* in that case // would cause pointers to unsigned shorts be printed as wide strings, // possibly accessing more memory than intended and causing invalid // memory accesses. MSVC defines _NATIVE_WCHAR_T_DEFINED symbol when // wchar_t is implemented as a native type. #if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED) // Prints the given wide C string to the ostream. void PrintTo(const wchar_t* s, ostream* os) { if (s == NULL) { *os << "NULL"; } else { *os << ImplicitCast_(s) << " pointing to "; PrintCharsAsStringTo(s, wcslen(s), os); } } #endif // wchar_t is native // Prints a ::string object. #if GTEST_HAS_GLOBAL_STRING void PrintStringTo(const ::string& s, ostream* os) { PrintCharsAsStringTo(s.data(), s.size(), os); } #endif // GTEST_HAS_GLOBAL_STRING void PrintStringTo(const ::std::string& s, ostream* os) { PrintCharsAsStringTo(s.data(), s.size(), os); } // Prints a ::wstring object. #if GTEST_HAS_GLOBAL_WSTRING void PrintWideStringTo(const ::wstring& s, ostream* os) { PrintCharsAsStringTo(s.data(), s.size(), os); } #endif // GTEST_HAS_GLOBAL_WSTRING #if GTEST_HAS_STD_WSTRING void PrintWideStringTo(const ::std::wstring& s, ostream* os) { PrintCharsAsStringTo(s.data(), s.size(), os); } #endif // GTEST_HAS_STD_WSTRING } // namespace internal } // namespace testing dlt-daemon-2.18.4/gtest-1.7.0/src/gtest-test-part.cc000066400000000000000000000100771353342203500215730ustar00rootroot00000000000000// Copyright 2008, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: mheule@google.com (Markus Heule) // // The Google C++ Testing Framework (Google Test) #include "gtest/gtest-test-part.h" // Indicates that this translation unit is part of Google Test's // implementation. It must come before gtest-internal-inl.h is // included, or there will be a compiler error. This trick is to // prevent a user from accidentally including gtest-internal-inl.h in // his code. #define GTEST_IMPLEMENTATION_ 1 #include "src/gtest-internal-inl.h" #undef GTEST_IMPLEMENTATION_ namespace testing { using internal::GetUnitTestImpl; // Gets the summary of the failure message by omitting the stack trace // in it. std::string TestPartResult::ExtractSummary(const char* message) { const char* const stack_trace = strstr(message, internal::kStackTraceMarker); return stack_trace == NULL ? message : std::string(message, stack_trace); } // Prints a TestPartResult object. std::ostream& operator<<(std::ostream& os, const TestPartResult& result) { return os << result.file_name() << ":" << result.line_number() << ": " << (result.type() == TestPartResult::kSuccess ? "Success" : result.type() == TestPartResult::kFatalFailure ? "Fatal failure" : "Non-fatal failure") << ":\n" << result.message() << std::endl; } // Appends a TestPartResult to the array. void TestPartResultArray::Append(const TestPartResult& result) { array_.push_back(result); } // Returns the TestPartResult at the given index (0-based). const TestPartResult& TestPartResultArray::GetTestPartResult(int index) const { if (index < 0 || index >= size()) { printf("\nInvalid index (%d) into TestPartResultArray.\n", index); internal::posix::Abort(); } return array_[index]; } // Returns the number of TestPartResult objects in the array. int TestPartResultArray::size() const { return static_cast(array_.size()); } namespace internal { HasNewFatalFailureHelper::HasNewFatalFailureHelper() : has_new_fatal_failure_(false), original_reporter_(GetUnitTestImpl()-> GetTestPartResultReporterForCurrentThread()) { GetUnitTestImpl()->SetTestPartResultReporterForCurrentThread(this); } HasNewFatalFailureHelper::~HasNewFatalFailureHelper() { GetUnitTestImpl()->SetTestPartResultReporterForCurrentThread( original_reporter_); } void HasNewFatalFailureHelper::ReportTestPartResult( const TestPartResult& result) { if (result.fatally_failed()) has_new_fatal_failure_ = true; original_reporter_->ReportTestPartResult(result); } } // namespace internal } // namespace testing dlt-daemon-2.18.4/gtest-1.7.0/src/gtest-typed-test.cc000066400000000000000000000072621353342203500217540ustar00rootroot00000000000000// Copyright 2008 Google Inc. // All Rights Reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: wan@google.com (Zhanyong Wan) #include "gtest/gtest-typed-test.h" #include "gtest/gtest.h" namespace testing { namespace internal { #if GTEST_HAS_TYPED_TEST_P // Skips to the first non-space char in str. Returns an empty string if str // contains only whitespace characters. static const char* SkipSpaces(const char* str) { while (IsSpace(*str)) str++; return str; } // Verifies that registered_tests match the test names in // defined_test_names_; returns registered_tests if successful, or // aborts the program otherwise. const char* TypedTestCasePState::VerifyRegisteredTestNames( const char* file, int line, const char* registered_tests) { typedef ::std::set::const_iterator DefinedTestIter; registered_ = true; // Skip initial whitespace in registered_tests since some // preprocessors prefix stringizied literals with whitespace. registered_tests = SkipSpaces(registered_tests); Message errors; ::std::set tests; for (const char* names = registered_tests; names != NULL; names = SkipComma(names)) { const std::string name = GetPrefixUntilComma(names); if (tests.count(name) != 0) { errors << "Test " << name << " is listed more than once.\n"; continue; } bool found = false; for (DefinedTestIter it = defined_test_names_.begin(); it != defined_test_names_.end(); ++it) { if (name == *it) { found = true; break; } } if (found) { tests.insert(name); } else { errors << "No test named " << name << " can be found in this test case.\n"; } } for (DefinedTestIter it = defined_test_names_.begin(); it != defined_test_names_.end(); ++it) { if (tests.count(*it) == 0) { errors << "You forgot to list test " << *it << ".\n"; } } const std::string& errors_str = errors.GetString(); if (errors_str != "") { fprintf(stderr, "%s %s", FormatFileLocation(file, line).c_str(), errors_str.c_str()); fflush(stderr); posix::Abort(); } return registered_tests; } #endif // GTEST_HAS_TYPED_TEST_P } // namespace internal } // namespace testing dlt-daemon-2.18.4/gtest-1.7.0/src/gtest.cc000066400000000000000000005475161353342203500176670ustar00rootroot00000000000000// Copyright 2005, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: wan@google.com (Zhanyong Wan) // // The Google C++ Testing Framework (Google Test) #include "gtest/gtest.h" #include "gtest/gtest-spi.h" #include #include #include #include #include #include #include #include #include #include #include #include // NOLINT #include #include #if GTEST_OS_LINUX // TODO(kenton@google.com): Use autoconf to detect availability of // gettimeofday(). # define GTEST_HAS_GETTIMEOFDAY_ 1 # include // NOLINT # include // NOLINT # include // NOLINT // Declares vsnprintf(). This header is not available on Windows. # include // NOLINT # include // NOLINT # include // NOLINT # include // NOLINT # include #elif GTEST_OS_SYMBIAN # define GTEST_HAS_GETTIMEOFDAY_ 1 # include // NOLINT #elif GTEST_OS_ZOS # define GTEST_HAS_GETTIMEOFDAY_ 1 # include // NOLINT // On z/OS we additionally need strings.h for strcasecmp. # include // NOLINT #elif GTEST_OS_WINDOWS_MOBILE // We are on Windows CE. # include // NOLINT #elif GTEST_OS_WINDOWS // We are on Windows proper. # include // NOLINT # include // NOLINT # include // NOLINT # include // NOLINT # if GTEST_OS_WINDOWS_MINGW // MinGW has gettimeofday() but not _ftime64(). // TODO(kenton@google.com): Use autoconf to detect availability of // gettimeofday(). // TODO(kenton@google.com): There are other ways to get the time on // Windows, like GetTickCount() or GetSystemTimeAsFileTime(). MinGW // supports these. consider using them instead. # define GTEST_HAS_GETTIMEOFDAY_ 1 # include // NOLINT # endif // GTEST_OS_WINDOWS_MINGW // cpplint thinks that the header is already included, so we want to // silence it. # include // NOLINT #else // Assume other platforms have gettimeofday(). // TODO(kenton@google.com): Use autoconf to detect availability of // gettimeofday(). # define GTEST_HAS_GETTIMEOFDAY_ 1 // cpplint thinks that the header is already included, so we want to // silence it. # include // NOLINT # include // NOLINT #endif // GTEST_OS_LINUX #if GTEST_HAS_EXCEPTIONS # include #endif #if GTEST_CAN_STREAM_RESULTS_ # include // NOLINT # include // NOLINT #endif // Indicates that this translation unit is part of Google Test's // implementation. It must come before gtest-internal-inl.h is // included, or there will be a compiler error. This trick is to // prevent a user from accidentally including gtest-internal-inl.h in // his code. #define GTEST_IMPLEMENTATION_ 1 #include "src/gtest-internal-inl.h" #undef GTEST_IMPLEMENTATION_ #if GTEST_OS_WINDOWS # define vsnprintf _vsnprintf #endif // GTEST_OS_WINDOWS namespace testing { using internal::CountIf; using internal::ForEach; using internal::GetElementOr; using internal::Shuffle; // Constants. // A test whose test case name or test name matches this filter is // disabled and not run. static const char kDisableTestFilter[] = "DISABLED_*:*/DISABLED_*"; // A test case whose name matches this filter is considered a death // test case and will be run before test cases whose name doesn't // match this filter. static const char kDeathTestCaseFilter[] = "*DeathTest:*DeathTest/*"; // A test filter that matches everything. static const char kUniversalFilter[] = "*"; // The default output file for XML output. static const char kDefaultOutputFile[] = "test_detail.xml"; // The environment variable name for the test shard index. static const char kTestShardIndex[] = "GTEST_SHARD_INDEX"; // The environment variable name for the total number of test shards. static const char kTestTotalShards[] = "GTEST_TOTAL_SHARDS"; // The environment variable name for the test shard status file. static const char kTestShardStatusFile[] = "GTEST_SHARD_STATUS_FILE"; namespace internal { // The text used in failure messages to indicate the start of the // stack trace. const char kStackTraceMarker[] = "\nStack trace:\n"; // g_help_flag is true iff the --help flag or an equivalent form is // specified on the command line. bool g_help_flag = false; } // namespace internal static const char* GetDefaultFilter() { return kUniversalFilter; } GTEST_DEFINE_bool_( also_run_disabled_tests, internal::BoolFromGTestEnv("also_run_disabled_tests", false), "Run disabled tests too, in addition to the tests normally being run."); GTEST_DEFINE_bool_( break_on_failure, internal::BoolFromGTestEnv("break_on_failure", false), "True iff a failed assertion should be a debugger break-point."); GTEST_DEFINE_bool_( catch_exceptions, internal::BoolFromGTestEnv("catch_exceptions", true), "True iff " GTEST_NAME_ " should catch exceptions and treat them as test failures."); GTEST_DEFINE_string_( color, internal::StringFromGTestEnv("color", "auto"), "Whether to use colors in the output. Valid values: yes, no, " "and auto. 'auto' means to use colors if the output is " "being sent to a terminal and the TERM environment variable " "is set to a terminal type that supports colors."); GTEST_DEFINE_string_( filter, internal::StringFromGTestEnv("filter", GetDefaultFilter()), "A colon-separated list of glob (not regex) patterns " "for filtering the tests to run, optionally followed by a " "'-' and a : separated list of negative patterns (tests to " "exclude). A test is run if it matches one of the positive " "patterns and does not match any of the negative patterns."); GTEST_DEFINE_bool_(list_tests, false, "List all tests without running them."); GTEST_DEFINE_string_( output, internal::StringFromGTestEnv("output", ""), "A format (currently must be \"xml\"), optionally followed " "by a colon and an output file name or directory. A directory " "is indicated by a trailing pathname separator. " "Examples: \"xml:filename.xml\", \"xml::directoryname/\". " "If a directory is specified, output files will be created " "within that directory, with file-names based on the test " "executable's name and, if necessary, made unique by adding " "digits."); GTEST_DEFINE_bool_( print_time, internal::BoolFromGTestEnv("print_time", true), "True iff " GTEST_NAME_ " should display elapsed time in text output."); GTEST_DEFINE_int32_( random_seed, internal::Int32FromGTestEnv("random_seed", 0), "Random number seed to use when shuffling test orders. Must be in range " "[1, 99999], or 0 to use a seed based on the current time."); GTEST_DEFINE_int32_( repeat, internal::Int32FromGTestEnv("repeat", 1), "How many times to repeat each test. Specify a negative number " "for repeating forever. Useful for shaking out flaky tests."); GTEST_DEFINE_bool_( show_internal_stack_frames, false, "True iff " GTEST_NAME_ " should include internal stack frames when " "printing test failure stack traces."); GTEST_DEFINE_bool_( shuffle, internal::BoolFromGTestEnv("shuffle", false), "True iff " GTEST_NAME_ " should randomize tests' order on every run."); GTEST_DEFINE_int32_( stack_trace_depth, internal::Int32FromGTestEnv("stack_trace_depth", kMaxStackTraceDepth), "The maximum number of stack frames to print when an " "assertion fails. The valid range is 0 through 100, inclusive."); GTEST_DEFINE_string_( stream_result_to, internal::StringFromGTestEnv("stream_result_to", ""), "This flag specifies the host name and the port number on which to stream " "test results. Example: \"localhost:555\". The flag is effective only on " "Linux."); GTEST_DEFINE_bool_( throw_on_failure, internal::BoolFromGTestEnv("throw_on_failure", false), "When this flag is specified, a failed assertion will throw an exception " "if exceptions are enabled or exit the program with a non-zero code " "otherwise."); namespace internal { // Generates a random number from [0, range), using a Linear // Congruential Generator (LCG). Crashes if 'range' is 0 or greater // than kMaxRange. UInt32 Random::Generate(UInt32 range) { // These constants are the same as are used in glibc's rand(3). state_ = (1103515245U*state_ + 12345U) % kMaxRange; GTEST_CHECK_(range > 0) << "Cannot generate a number in the range [0, 0)."; GTEST_CHECK_(range <= kMaxRange) << "Generation of a number in [0, " << range << ") was requested, " << "but this can only generate numbers in [0, " << kMaxRange << ")."; // Converting via modulus introduces a bit of downward bias, but // it's simple, and a linear congruential generator isn't too good // to begin with. return state_ % range; } // GTestIsInitialized() returns true iff the user has initialized // Google Test. Useful for catching the user mistake of not initializing // Google Test before calling RUN_ALL_TESTS(). // // A user must call testing::InitGoogleTest() to initialize Google // Test. g_init_gtest_count is set to the number of times // InitGoogleTest() has been called. We don't protect this variable // under a mutex as it is only accessed in the main thread. GTEST_API_ int g_init_gtest_count = 0; static bool GTestIsInitialized() { return g_init_gtest_count != 0; } // Iterates over a vector of TestCases, keeping a running sum of the // results of calling a given int-returning method on each. // Returns the sum. static int SumOverTestCaseList(const std::vector& case_list, int (TestCase::*method)() const) { int sum = 0; for (size_t i = 0; i < case_list.size(); i++) { sum += (case_list[i]->*method)(); } return sum; } // Returns true iff the test case passed. static bool TestCasePassed(const TestCase* test_case) { return test_case->should_run() && test_case->Passed(); } // Returns true iff the test case failed. static bool TestCaseFailed(const TestCase* test_case) { return test_case->should_run() && test_case->Failed(); } // Returns true iff test_case contains at least one test that should // run. static bool ShouldRunTestCase(const TestCase* test_case) { return test_case->should_run(); } // AssertHelper constructor. AssertHelper::AssertHelper(TestPartResult::Type type, const char* file, int line, const char* message) : data_(new AssertHelperData(type, file, line, message)) { } AssertHelper::~AssertHelper() { delete data_; } // Message assignment, for assertion streaming support. void AssertHelper::operator=(const Message& message) const { UnitTest::GetInstance()-> AddTestPartResult(data_->type, data_->file, data_->line, AppendUserMessage(data_->message, message), UnitTest::GetInstance()->impl() ->CurrentOsStackTraceExceptTop(1) // Skips the stack frame for this function itself. ); // NOLINT } // Mutex for linked pointers. GTEST_API_ GTEST_DEFINE_STATIC_MUTEX_(g_linked_ptr_mutex); // Application pathname gotten in InitGoogleTest. std::string g_executable_path; // Returns the current application's name, removing directory path if that // is present. FilePath GetCurrentExecutableName() { FilePath result; #if GTEST_OS_WINDOWS result.Set(FilePath(g_executable_path).RemoveExtension("exe")); #else result.Set(FilePath(g_executable_path)); #endif // GTEST_OS_WINDOWS return result.RemoveDirectoryName(); } // Functions for processing the gtest_output flag. // Returns the output format, or "" for normal printed output. std::string UnitTestOptions::GetOutputFormat() { const char* const gtest_output_flag = GTEST_FLAG(output).c_str(); if (gtest_output_flag == NULL) return std::string(""); const char* const colon = strchr(gtest_output_flag, ':'); return (colon == NULL) ? std::string(gtest_output_flag) : std::string(gtest_output_flag, colon - gtest_output_flag); } // Returns the name of the requested output file, or the default if none // was explicitly specified. std::string UnitTestOptions::GetAbsolutePathToOutputFile() { const char* const gtest_output_flag = GTEST_FLAG(output).c_str(); if (gtest_output_flag == NULL) return ""; const char* const colon = strchr(gtest_output_flag, ':'); if (colon == NULL) return internal::FilePath::ConcatPaths( internal::FilePath( UnitTest::GetInstance()->original_working_dir()), internal::FilePath(kDefaultOutputFile)).string(); internal::FilePath output_name(colon + 1); if (!output_name.IsAbsolutePath()) // TODO(wan@google.com): on Windows \some\path is not an absolute // path (as its meaning depends on the current drive), yet the // following logic for turning it into an absolute path is wrong. // Fix it. output_name = internal::FilePath::ConcatPaths( internal::FilePath(UnitTest::GetInstance()->original_working_dir()), internal::FilePath(colon + 1)); if (!output_name.IsDirectory()) return output_name.string(); internal::FilePath result(internal::FilePath::GenerateUniqueFileName( output_name, internal::GetCurrentExecutableName(), GetOutputFormat().c_str())); return result.string(); } // Returns true iff the wildcard pattern matches the string. The // first ':' or '\0' character in pattern marks the end of it. // // This recursive algorithm isn't very efficient, but is clear and // works well enough for matching test names, which are short. bool UnitTestOptions::PatternMatchesString(const char *pattern, const char *str) { switch (*pattern) { case '\0': case ':': // Either ':' or '\0' marks the end of the pattern. return *str == '\0'; case '?': // Matches any single character. return *str != '\0' && PatternMatchesString(pattern + 1, str + 1); case '*': // Matches any string (possibly empty) of characters. return (*str != '\0' && PatternMatchesString(pattern, str + 1)) || PatternMatchesString(pattern + 1, str); default: // Non-special character. Matches itself. return *pattern == *str && PatternMatchesString(pattern + 1, str + 1); } } bool UnitTestOptions::MatchesFilter( const std::string& name, const char* filter) { const char *cur_pattern = filter; for (;;) { if (PatternMatchesString(cur_pattern, name.c_str())) { return true; } // Finds the next pattern in the filter. cur_pattern = strchr(cur_pattern, ':'); // Returns if no more pattern can be found. if (cur_pattern == NULL) { return false; } // Skips the pattern separater (the ':' character). cur_pattern++; } } // Returns true iff the user-specified filter matches the test case // name and the test name. bool UnitTestOptions::FilterMatchesTest(const std::string &test_case_name, const std::string &test_name) { const std::string& full_name = test_case_name + "." + test_name.c_str(); // Split --gtest_filter at '-', if there is one, to separate into // positive filter and negative filter portions const char* const p = GTEST_FLAG(filter).c_str(); const char* const dash = strchr(p, '-'); std::string positive; std::string negative; if (dash == NULL) { positive = GTEST_FLAG(filter).c_str(); // Whole string is a positive filter negative = ""; } else { positive = std::string(p, dash); // Everything up to the dash negative = std::string(dash + 1); // Everything after the dash if (positive.empty()) { // Treat '-test1' as the same as '*-test1' positive = kUniversalFilter; } } // A filter is a colon-separated list of patterns. It matches a // test if any pattern in it matches the test. return (MatchesFilter(full_name, positive.c_str()) && !MatchesFilter(full_name, negative.c_str())); } #if GTEST_HAS_SEH // Returns EXCEPTION_EXECUTE_HANDLER if Google Test should handle the // given SEH exception, or EXCEPTION_CONTINUE_SEARCH otherwise. // This function is useful as an __except condition. int UnitTestOptions::GTestShouldProcessSEH(DWORD exception_code) { // Google Test should handle a SEH exception if: // 1. the user wants it to, AND // 2. this is not a breakpoint exception, AND // 3. this is not a C++ exception (VC++ implements them via SEH, // apparently). // // SEH exception code for C++ exceptions. // (see http://support.microsoft.com/kb/185294 for more information). const DWORD kCxxExceptionCode = 0xe06d7363; bool should_handle = true; if (!GTEST_FLAG(catch_exceptions)) should_handle = false; else if (exception_code == EXCEPTION_BREAKPOINT) should_handle = false; else if (exception_code == kCxxExceptionCode) should_handle = false; return should_handle ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH; } #endif // GTEST_HAS_SEH } // namespace internal // The c'tor sets this object as the test part result reporter used by // Google Test. The 'result' parameter specifies where to report the // results. Intercepts only failures from the current thread. ScopedFakeTestPartResultReporter::ScopedFakeTestPartResultReporter( TestPartResultArray* result) : intercept_mode_(INTERCEPT_ONLY_CURRENT_THREAD), result_(result) { Init(); } // The c'tor sets this object as the test part result reporter used by // Google Test. The 'result' parameter specifies where to report the // results. ScopedFakeTestPartResultReporter::ScopedFakeTestPartResultReporter( InterceptMode intercept_mode, TestPartResultArray* result) : intercept_mode_(intercept_mode), result_(result) { Init(); } void ScopedFakeTestPartResultReporter::Init() { internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); if (intercept_mode_ == INTERCEPT_ALL_THREADS) { old_reporter_ = impl->GetGlobalTestPartResultReporter(); impl->SetGlobalTestPartResultReporter(this); } else { old_reporter_ = impl->GetTestPartResultReporterForCurrentThread(); impl->SetTestPartResultReporterForCurrentThread(this); } } // The d'tor restores the test part result reporter used by Google Test // before. ScopedFakeTestPartResultReporter::~ScopedFakeTestPartResultReporter() { internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); if (intercept_mode_ == INTERCEPT_ALL_THREADS) { impl->SetGlobalTestPartResultReporter(old_reporter_); } else { impl->SetTestPartResultReporterForCurrentThread(old_reporter_); } } // Increments the test part result count and remembers the result. // This method is from the TestPartResultReporterInterface interface. void ScopedFakeTestPartResultReporter::ReportTestPartResult( const TestPartResult& result) { result_->Append(result); } namespace internal { // Returns the type ID of ::testing::Test. We should always call this // instead of GetTypeId< ::testing::Test>() to get the type ID of // testing::Test. This is to work around a suspected linker bug when // using Google Test as a framework on Mac OS X. The bug causes // GetTypeId< ::testing::Test>() to return different values depending // on whether the call is from the Google Test framework itself or // from user test code. GetTestTypeId() is guaranteed to always // return the same value, as it always calls GetTypeId<>() from the // gtest.cc, which is within the Google Test framework. TypeId GetTestTypeId() { return GetTypeId(); } // The value of GetTestTypeId() as seen from within the Google Test // library. This is solely for testing GetTestTypeId(). extern const TypeId kTestTypeIdInGoogleTest = GetTestTypeId(); // This predicate-formatter checks that 'results' contains a test part // failure of the given type and that the failure message contains the // given substring. AssertionResult HasOneFailure(const char* /* results_expr */, const char* /* type_expr */, const char* /* substr_expr */, const TestPartResultArray& results, TestPartResult::Type type, const string& substr) { const std::string expected(type == TestPartResult::kFatalFailure ? "1 fatal failure" : "1 non-fatal failure"); Message msg; if (results.size() != 1) { msg << "Expected: " << expected << "\n" << " Actual: " << results.size() << " failures"; for (int i = 0; i < results.size(); i++) { msg << "\n" << results.GetTestPartResult(i); } return AssertionFailure() << msg; } const TestPartResult& r = results.GetTestPartResult(0); if (r.type() != type) { return AssertionFailure() << "Expected: " << expected << "\n" << " Actual:\n" << r; } if (strstr(r.message(), substr.c_str()) == NULL) { return AssertionFailure() << "Expected: " << expected << " containing \"" << substr << "\"\n" << " Actual:\n" << r; } return AssertionSuccess(); } // The constructor of SingleFailureChecker remembers where to look up // test part results, what type of failure we expect, and what // substring the failure message should contain. SingleFailureChecker:: SingleFailureChecker( const TestPartResultArray* results, TestPartResult::Type type, const string& substr) : results_(results), type_(type), substr_(substr) {} // The destructor of SingleFailureChecker verifies that the given // TestPartResultArray contains exactly one failure that has the given // type and contains the given substring. If that's not the case, a // non-fatal failure will be generated. SingleFailureChecker::~SingleFailureChecker() { EXPECT_PRED_FORMAT3(HasOneFailure, *results_, type_, substr_); } DefaultGlobalTestPartResultReporter::DefaultGlobalTestPartResultReporter( UnitTestImpl* unit_test) : unit_test_(unit_test) {} void DefaultGlobalTestPartResultReporter::ReportTestPartResult( const TestPartResult& result) { unit_test_->current_test_result()->AddTestPartResult(result); unit_test_->listeners()->repeater()->OnTestPartResult(result); } DefaultPerThreadTestPartResultReporter::DefaultPerThreadTestPartResultReporter( UnitTestImpl* unit_test) : unit_test_(unit_test) {} void DefaultPerThreadTestPartResultReporter::ReportTestPartResult( const TestPartResult& result) { unit_test_->GetGlobalTestPartResultReporter()->ReportTestPartResult(result); } // Returns the global test part result reporter. TestPartResultReporterInterface* UnitTestImpl::GetGlobalTestPartResultReporter() { internal::MutexLock lock(&global_test_part_result_reporter_mutex_); return global_test_part_result_repoter_; } // Sets the global test part result reporter. void UnitTestImpl::SetGlobalTestPartResultReporter( TestPartResultReporterInterface* reporter) { internal::MutexLock lock(&global_test_part_result_reporter_mutex_); global_test_part_result_repoter_ = reporter; } // Returns the test part result reporter for the current thread. TestPartResultReporterInterface* UnitTestImpl::GetTestPartResultReporterForCurrentThread() { return per_thread_test_part_result_reporter_.get(); } // Sets the test part result reporter for the current thread. void UnitTestImpl::SetTestPartResultReporterForCurrentThread( TestPartResultReporterInterface* reporter) { per_thread_test_part_result_reporter_.set(reporter); } // Gets the number of successful test cases. int UnitTestImpl::successful_test_case_count() const { return CountIf(test_cases_, TestCasePassed); } // Gets the number of failed test cases. int UnitTestImpl::failed_test_case_count() const { return CountIf(test_cases_, TestCaseFailed); } // Gets the number of all test cases. int UnitTestImpl::total_test_case_count() const { return static_cast(test_cases_.size()); } // Gets the number of all test cases that contain at least one test // that should run. int UnitTestImpl::test_case_to_run_count() const { return CountIf(test_cases_, ShouldRunTestCase); } // Gets the number of successful tests. int UnitTestImpl::successful_test_count() const { return SumOverTestCaseList(test_cases_, &TestCase::successful_test_count); } // Gets the number of failed tests. int UnitTestImpl::failed_test_count() const { return SumOverTestCaseList(test_cases_, &TestCase::failed_test_count); } // Gets the number of disabled tests that will be reported in the XML report. int UnitTestImpl::reportable_disabled_test_count() const { return SumOverTestCaseList(test_cases_, &TestCase::reportable_disabled_test_count); } // Gets the number of disabled tests. int UnitTestImpl::disabled_test_count() const { return SumOverTestCaseList(test_cases_, &TestCase::disabled_test_count); } // Gets the number of tests to be printed in the XML report. int UnitTestImpl::reportable_test_count() const { return SumOverTestCaseList(test_cases_, &TestCase::reportable_test_count); } // Gets the number of all tests. int UnitTestImpl::total_test_count() const { return SumOverTestCaseList(test_cases_, &TestCase::total_test_count); } // Gets the number of tests that should run. int UnitTestImpl::test_to_run_count() const { return SumOverTestCaseList(test_cases_, &TestCase::test_to_run_count); } // Returns the current OS stack trace as an std::string. // // The maximum number of stack frames to be included is specified by // the gtest_stack_trace_depth flag. The skip_count parameter // specifies the number of top frames to be skipped, which doesn't // count against the number of frames to be included. // // For example, if Foo() calls Bar(), which in turn calls // CurrentOsStackTraceExceptTop(1), Foo() will be included in the // trace but Bar() and CurrentOsStackTraceExceptTop() won't. std::string UnitTestImpl::CurrentOsStackTraceExceptTop(int skip_count) { (void)skip_count; return ""; } // Returns the current time in milliseconds. TimeInMillis GetTimeInMillis() { #if GTEST_OS_WINDOWS_MOBILE || defined(__BORLANDC__) // Difference between 1970-01-01 and 1601-01-01 in milliseconds. // http://analogous.blogspot.com/2005/04/epoch.html const TimeInMillis kJavaEpochToWinFileTimeDelta = static_cast(116444736UL) * 100000UL; const DWORD kTenthMicrosInMilliSecond = 10000; SYSTEMTIME now_systime; FILETIME now_filetime; ULARGE_INTEGER now_int64; // TODO(kenton@google.com): Shouldn't this just use // GetSystemTimeAsFileTime()? GetSystemTime(&now_systime); if (SystemTimeToFileTime(&now_systime, &now_filetime)) { now_int64.LowPart = now_filetime.dwLowDateTime; now_int64.HighPart = now_filetime.dwHighDateTime; now_int64.QuadPart = (now_int64.QuadPart / kTenthMicrosInMilliSecond) - kJavaEpochToWinFileTimeDelta; return now_int64.QuadPart; } return 0; #elif GTEST_OS_WINDOWS && !GTEST_HAS_GETTIMEOFDAY_ __timeb64 now; # ifdef _MSC_VER // MSVC 8 deprecates _ftime64(), so we want to suppress warning 4996 // (deprecated function) there. // TODO(kenton@google.com): Use GetTickCount()? Or use // SystemTimeToFileTime() # pragma warning(push) // Saves the current warning state. # pragma warning(disable:4996) // Temporarily disables warning 4996. _ftime64(&now); # pragma warning(pop) // Restores the warning state. # else _ftime64(&now); # endif // _MSC_VER return static_cast(now.time) * 1000 + now.millitm; #elif GTEST_HAS_GETTIMEOFDAY_ struct timeval now; gettimeofday(&now, NULL); return static_cast(now.tv_sec) * 1000 + now.tv_usec / 1000; #else # error "Don't know how to get the current time on your system." #endif } // Utilities // class String. #if GTEST_OS_WINDOWS_MOBILE // Creates a UTF-16 wide string from the given ANSI string, allocating // memory using new. The caller is responsible for deleting the return // value using delete[]. Returns the wide string, or NULL if the // input is NULL. LPCWSTR String::AnsiToUtf16(const char* ansi) { if (!ansi) return NULL; const int length = strlen(ansi); const int unicode_length = MultiByteToWideChar(CP_ACP, 0, ansi, length, NULL, 0); WCHAR* unicode = new WCHAR[unicode_length + 1]; MultiByteToWideChar(CP_ACP, 0, ansi, length, unicode, unicode_length); unicode[unicode_length] = 0; return unicode; } // Creates an ANSI string from the given wide string, allocating // memory using new. The caller is responsible for deleting the return // value using delete[]. Returns the ANSI string, or NULL if the // input is NULL. const char* String::Utf16ToAnsi(LPCWSTR utf16_str) { if (!utf16_str) return NULL; const int ansi_length = WideCharToMultiByte(CP_ACP, 0, utf16_str, -1, NULL, 0, NULL, NULL); char* ansi = new char[ansi_length + 1]; WideCharToMultiByte(CP_ACP, 0, utf16_str, -1, ansi, ansi_length, NULL, NULL); ansi[ansi_length] = 0; return ansi; } #endif // GTEST_OS_WINDOWS_MOBILE // Compares two C strings. Returns true iff they have the same content. // // Unlike strcmp(), this function can handle NULL argument(s). A NULL // C string is considered different to any non-NULL C string, // including the empty string. bool String::CStringEquals(const char * lhs, const char * rhs) { if ( lhs == NULL ) return rhs == NULL; if ( rhs == NULL ) return false; return strcmp(lhs, rhs) == 0; } #if GTEST_HAS_STD_WSTRING || GTEST_HAS_GLOBAL_WSTRING // Converts an array of wide chars to a narrow string using the UTF-8 // encoding, and streams the result to the given Message object. static void StreamWideCharsToMessage(const wchar_t* wstr, size_t length, Message* msg) { for (size_t i = 0; i != length; ) { // NOLINT if (wstr[i] != L'\0') { *msg << WideStringToUtf8(wstr + i, static_cast(length - i)); while (i != length && wstr[i] != L'\0') i++; } else { *msg << '\0'; i++; } } } #endif // GTEST_HAS_STD_WSTRING || GTEST_HAS_GLOBAL_WSTRING } // namespace internal // Constructs an empty Message. // We allocate the stringstream separately because otherwise each use of // ASSERT/EXPECT in a procedure adds over 200 bytes to the procedure's // stack frame leading to huge stack frames in some cases; gcc does not reuse // the stack space. Message::Message() : ss_(new ::std::stringstream) { // By default, we want there to be enough precision when printing // a double to a Message. *ss_ << std::setprecision(std::numeric_limits::digits10 + 2); } // These two overloads allow streaming a wide C string to a Message // using the UTF-8 encoding. Message& Message::operator <<(const wchar_t* wide_c_str) { return *this << internal::String::ShowWideCString(wide_c_str); } Message& Message::operator <<(wchar_t* wide_c_str) { return *this << internal::String::ShowWideCString(wide_c_str); } #if GTEST_HAS_STD_WSTRING // Converts the given wide string to a narrow string using the UTF-8 // encoding, and streams the result to this Message object. Message& Message::operator <<(const ::std::wstring& wstr) { internal::StreamWideCharsToMessage(wstr.c_str(), wstr.length(), this); return *this; } #endif // GTEST_HAS_STD_WSTRING #if GTEST_HAS_GLOBAL_WSTRING // Converts the given wide string to a narrow string using the UTF-8 // encoding, and streams the result to this Message object. Message& Message::operator <<(const ::wstring& wstr) { internal::StreamWideCharsToMessage(wstr.c_str(), wstr.length(), this); return *this; } #endif // GTEST_HAS_GLOBAL_WSTRING // Gets the text streamed to this object so far as an std::string. // Each '\0' character in the buffer is replaced with "\\0". std::string Message::GetString() const { return internal::StringStreamToString(ss_.get()); } // AssertionResult constructors. // Used in EXPECT_TRUE/FALSE(assertion_result). AssertionResult::AssertionResult(const AssertionResult& other) : success_(other.success_), message_(other.message_.get() != NULL ? new ::std::string(*other.message_) : static_cast< ::std::string*>(NULL)) { } // Returns the assertion's negation. Used with EXPECT/ASSERT_FALSE. AssertionResult AssertionResult::operator!() const { AssertionResult negation(!success_); if (message_.get() != NULL) negation << *message_; return negation; } // Makes a successful assertion result. AssertionResult AssertionSuccess() { return AssertionResult(true); } // Makes a failed assertion result. AssertionResult AssertionFailure() { return AssertionResult(false); } // Makes a failed assertion result with the given failure message. // Deprecated; use AssertionFailure() << message. AssertionResult AssertionFailure(const Message& message) { return AssertionFailure() << message; } namespace internal { // Constructs and returns the message for an equality assertion // (e.g. ASSERT_EQ, EXPECT_STREQ, etc) failure. // // The first four parameters are the expressions used in the assertion // and their values, as strings. For example, for ASSERT_EQ(foo, bar) // where foo is 5 and bar is 6, we have: // // expected_expression: "foo" // actual_expression: "bar" // expected_value: "5" // actual_value: "6" // // The ignoring_case parameter is true iff the assertion is a // *_STRCASEEQ*. When it's true, the string " (ignoring case)" will // be inserted into the message. AssertionResult EqFailure(const char* expected_expression, const char* actual_expression, const std::string& expected_value, const std::string& actual_value, bool ignoring_case) { Message msg; msg << "Value of: " << actual_expression; if (actual_value != actual_expression) { msg << "\n Actual: " << actual_value; } msg << "\nExpected: " << expected_expression; if (ignoring_case) { msg << " (ignoring case)"; } if (expected_value != expected_expression) { msg << "\nWhich is: " << expected_value; } return AssertionFailure() << msg; } // Constructs a failure message for Boolean assertions such as EXPECT_TRUE. std::string GetBoolAssertionFailureMessage( const AssertionResult& assertion_result, const char* expression_text, const char* actual_predicate_value, const char* expected_predicate_value) { const char* actual_message = assertion_result.message(); Message msg; msg << "Value of: " << expression_text << "\n Actual: " << actual_predicate_value; if (actual_message[0] != '\0') msg << " (" << actual_message << ")"; msg << "\nExpected: " << expected_predicate_value; return msg.GetString(); } // Helper function for implementing ASSERT_NEAR. AssertionResult DoubleNearPredFormat(const char* expr1, const char* expr2, const char* abs_error_expr, double val1, double val2, double abs_error) { const double diff = fabs(val1 - val2); if (diff <= abs_error) return AssertionSuccess(); // TODO(wan): do not print the value of an expression if it's // already a literal. return AssertionFailure() << "The difference between " << expr1 << " and " << expr2 << " is " << diff << ", which exceeds " << abs_error_expr << ", where\n" << expr1 << " evaluates to " << val1 << ",\n" << expr2 << " evaluates to " << val2 << ", and\n" << abs_error_expr << " evaluates to " << abs_error << "."; } // Helper template for implementing FloatLE() and DoubleLE(). template AssertionResult FloatingPointLE(const char* expr1, const char* expr2, RawType val1, RawType val2) { // Returns success if val1 is less than val2, if (val1 < val2) { return AssertionSuccess(); } // or if val1 is almost equal to val2. const FloatingPoint lhs(val1), rhs(val2); if (lhs.AlmostEquals(rhs)) { return AssertionSuccess(); } // Note that the above two checks will both fail if either val1 or // val2 is NaN, as the IEEE floating-point standard requires that // any predicate involving a NaN must return false. ::std::stringstream val1_ss; val1_ss << std::setprecision(std::numeric_limits::digits10 + 2) << val1; ::std::stringstream val2_ss; val2_ss << std::setprecision(std::numeric_limits::digits10 + 2) << val2; return AssertionFailure() << "Expected: (" << expr1 << ") <= (" << expr2 << ")\n" << " Actual: " << StringStreamToString(&val1_ss) << " vs " << StringStreamToString(&val2_ss); } } // namespace internal // Asserts that val1 is less than, or almost equal to, val2. Fails // otherwise. In particular, it fails if either val1 or val2 is NaN. AssertionResult FloatLE(const char* expr1, const char* expr2, float val1, float val2) { return internal::FloatingPointLE(expr1, expr2, val1, val2); } // Asserts that val1 is less than, or almost equal to, val2. Fails // otherwise. In particular, it fails if either val1 or val2 is NaN. AssertionResult DoubleLE(const char* expr1, const char* expr2, double val1, double val2) { return internal::FloatingPointLE(expr1, expr2, val1, val2); } namespace internal { // The helper function for {ASSERT|EXPECT}_EQ with int or enum // arguments. AssertionResult CmpHelperEQ(const char* expected_expression, const char* actual_expression, BiggestInt expected, BiggestInt actual) { if (expected == actual) { return AssertionSuccess(); } return EqFailure(expected_expression, actual_expression, FormatForComparisonFailureMessage(expected, actual), FormatForComparisonFailureMessage(actual, expected), false); } // A macro for implementing the helper functions needed to implement // ASSERT_?? and EXPECT_?? with integer or enum arguments. It is here // just to avoid copy-and-paste of similar code. #define GTEST_IMPL_CMP_HELPER_(op_name, op)\ AssertionResult CmpHelper##op_name(const char* expr1, const char* expr2, \ BiggestInt val1, BiggestInt val2) {\ if (val1 op val2) {\ return AssertionSuccess();\ } else {\ return AssertionFailure() \ << "Expected: (" << expr1 << ") " #op " (" << expr2\ << "), actual: " << FormatForComparisonFailureMessage(val1, val2)\ << " vs " << FormatForComparisonFailureMessage(val2, val1);\ }\ } // Implements the helper function for {ASSERT|EXPECT}_NE with int or // enum arguments. GTEST_IMPL_CMP_HELPER_(NE, !=) // Implements the helper function for {ASSERT|EXPECT}_LE with int or // enum arguments. GTEST_IMPL_CMP_HELPER_(LE, <=) // Implements the helper function for {ASSERT|EXPECT}_LT with int or // enum arguments. GTEST_IMPL_CMP_HELPER_(LT, < ) // Implements the helper function for {ASSERT|EXPECT}_GE with int or // enum arguments. GTEST_IMPL_CMP_HELPER_(GE, >=) // Implements the helper function for {ASSERT|EXPECT}_GT with int or // enum arguments. GTEST_IMPL_CMP_HELPER_(GT, > ) #undef GTEST_IMPL_CMP_HELPER_ // The helper function for {ASSERT|EXPECT}_STREQ. AssertionResult CmpHelperSTREQ(const char* expected_expression, const char* actual_expression, const char* expected, const char* actual) { if (String::CStringEquals(expected, actual)) { return AssertionSuccess(); } return EqFailure(expected_expression, actual_expression, PrintToString(expected), PrintToString(actual), false); } // The helper function for {ASSERT|EXPECT}_STRCASEEQ. AssertionResult CmpHelperSTRCASEEQ(const char* expected_expression, const char* actual_expression, const char* expected, const char* actual) { if (String::CaseInsensitiveCStringEquals(expected, actual)) { return AssertionSuccess(); } return EqFailure(expected_expression, actual_expression, PrintToString(expected), PrintToString(actual), true); } // The helper function for {ASSERT|EXPECT}_STRNE. AssertionResult CmpHelperSTRNE(const char* s1_expression, const char* s2_expression, const char* s1, const char* s2) { if (!String::CStringEquals(s1, s2)) { return AssertionSuccess(); } else { return AssertionFailure() << "Expected: (" << s1_expression << ") != (" << s2_expression << "), actual: \"" << s1 << "\" vs \"" << s2 << "\""; } } // The helper function for {ASSERT|EXPECT}_STRCASENE. AssertionResult CmpHelperSTRCASENE(const char* s1_expression, const char* s2_expression, const char* s1, const char* s2) { if (!String::CaseInsensitiveCStringEquals(s1, s2)) { return AssertionSuccess(); } else { return AssertionFailure() << "Expected: (" << s1_expression << ") != (" << s2_expression << ") (ignoring case), actual: \"" << s1 << "\" vs \"" << s2 << "\""; } } } // namespace internal namespace { // Helper functions for implementing IsSubString() and IsNotSubstring(). // This group of overloaded functions return true iff needle is a // substring of haystack. NULL is considered a substring of itself // only. bool IsSubstringPred(const char* needle, const char* haystack) { if (needle == NULL || haystack == NULL) return needle == haystack; return strstr(haystack, needle) != NULL; } bool IsSubstringPred(const wchar_t* needle, const wchar_t* haystack) { if (needle == NULL || haystack == NULL) return needle == haystack; return wcsstr(haystack, needle) != NULL; } // StringType here can be either ::std::string or ::std::wstring. template bool IsSubstringPred(const StringType& needle, const StringType& haystack) { return haystack.find(needle) != StringType::npos; } // This function implements either IsSubstring() or IsNotSubstring(), // depending on the value of the expected_to_be_substring parameter. // StringType here can be const char*, const wchar_t*, ::std::string, // or ::std::wstring. template AssertionResult IsSubstringImpl( bool expected_to_be_substring, const char* needle_expr, const char* haystack_expr, const StringType& needle, const StringType& haystack) { if (IsSubstringPred(needle, haystack) == expected_to_be_substring) return AssertionSuccess(); const bool is_wide_string = sizeof(needle[0]) > 1; const char* const begin_string_quote = is_wide_string ? "L\"" : "\""; return AssertionFailure() << "Value of: " << needle_expr << "\n" << " Actual: " << begin_string_quote << needle << "\"\n" << "Expected: " << (expected_to_be_substring ? "" : "not ") << "a substring of " << haystack_expr << "\n" << "Which is: " << begin_string_quote << haystack << "\""; } } // namespace // IsSubstring() and IsNotSubstring() check whether needle is a // substring of haystack (NULL is considered a substring of itself // only), and return an appropriate error message when they fail. AssertionResult IsSubstring( const char* needle_expr, const char* haystack_expr, const char* needle, const char* haystack) { return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack); } AssertionResult IsSubstring( const char* needle_expr, const char* haystack_expr, const wchar_t* needle, const wchar_t* haystack) { return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack); } AssertionResult IsNotSubstring( const char* needle_expr, const char* haystack_expr, const char* needle, const char* haystack) { return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack); } AssertionResult IsNotSubstring( const char* needle_expr, const char* haystack_expr, const wchar_t* needle, const wchar_t* haystack) { return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack); } AssertionResult IsSubstring( const char* needle_expr, const char* haystack_expr, const ::std::string& needle, const ::std::string& haystack) { return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack); } AssertionResult IsNotSubstring( const char* needle_expr, const char* haystack_expr, const ::std::string& needle, const ::std::string& haystack) { return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack); } #if GTEST_HAS_STD_WSTRING AssertionResult IsSubstring( const char* needle_expr, const char* haystack_expr, const ::std::wstring& needle, const ::std::wstring& haystack) { return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack); } AssertionResult IsNotSubstring( const char* needle_expr, const char* haystack_expr, const ::std::wstring& needle, const ::std::wstring& haystack) { return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack); } #endif // GTEST_HAS_STD_WSTRING namespace internal { #if GTEST_OS_WINDOWS namespace { // Helper function for IsHRESULT{SuccessFailure} predicates AssertionResult HRESULTFailureHelper(const char* expr, const char* expected, long hr) { // NOLINT # if GTEST_OS_WINDOWS_MOBILE // Windows CE doesn't support FormatMessage. const char error_text[] = ""; # else // Looks up the human-readable system message for the HRESULT code // and since we're not passing any params to FormatMessage, we don't // want inserts expanded. const DWORD kFlags = FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS; const DWORD kBufSize = 4096; // Gets the system's human readable message string for this HRESULT. char error_text[kBufSize] = { '\0' }; DWORD message_length = ::FormatMessageA(kFlags, 0, // no source, we're asking system hr, // the error 0, // no line width restrictions error_text, // output buffer kBufSize, // buf size NULL); // no arguments for inserts // Trims tailing white space (FormatMessage leaves a trailing CR-LF) for (; message_length && IsSpace(error_text[message_length - 1]); --message_length) { error_text[message_length - 1] = '\0'; } # endif // GTEST_OS_WINDOWS_MOBILE const std::string error_hex("0x" + String::FormatHexInt(hr)); return ::testing::AssertionFailure() << "Expected: " << expr << " " << expected << ".\n" << " Actual: " << error_hex << " " << error_text << "\n"; } } // namespace AssertionResult IsHRESULTSuccess(const char* expr, long hr) { // NOLINT if (SUCCEEDED(hr)) { return AssertionSuccess(); } return HRESULTFailureHelper(expr, "succeeds", hr); } AssertionResult IsHRESULTFailure(const char* expr, long hr) { // NOLINT if (FAILED(hr)) { return AssertionSuccess(); } return HRESULTFailureHelper(expr, "fails", hr); } #endif // GTEST_OS_WINDOWS // Utility functions for encoding Unicode text (wide strings) in // UTF-8. // A Unicode code-point can have upto 21 bits, and is encoded in UTF-8 // like this: // // Code-point length Encoding // 0 - 7 bits 0xxxxxxx // 8 - 11 bits 110xxxxx 10xxxxxx // 12 - 16 bits 1110xxxx 10xxxxxx 10xxxxxx // 17 - 21 bits 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx // The maximum code-point a one-byte UTF-8 sequence can represent. const UInt32 kMaxCodePoint1 = (static_cast(1) << 7) - 1; // The maximum code-point a two-byte UTF-8 sequence can represent. const UInt32 kMaxCodePoint2 = (static_cast(1) << (5 + 6)) - 1; // The maximum code-point a three-byte UTF-8 sequence can represent. const UInt32 kMaxCodePoint3 = (static_cast(1) << (4 + 2*6)) - 1; // The maximum code-point a four-byte UTF-8 sequence can represent. const UInt32 kMaxCodePoint4 = (static_cast(1) << (3 + 3*6)) - 1; // Chops off the n lowest bits from a bit pattern. Returns the n // lowest bits. As a side effect, the original bit pattern will be // shifted to the right by n bits. inline UInt32 ChopLowBits(UInt32* bits, int n) { const UInt32 low_bits = *bits & ((static_cast(1) << n) - 1); *bits >>= n; return low_bits; } // Converts a Unicode code point to a narrow string in UTF-8 encoding. // code_point parameter is of type UInt32 because wchar_t may not be // wide enough to contain a code point. // If the code_point is not a valid Unicode code point // (i.e. outside of Unicode range U+0 to U+10FFFF) it will be converted // to "(Invalid Unicode 0xXXXXXXXX)". std::string CodePointToUtf8(UInt32 code_point) { if (code_point > kMaxCodePoint4) { return "(Invalid Unicode 0x" + String::FormatHexInt(code_point) + ")"; } char str[5]; // Big enough for the largest valid code point. if (code_point <= kMaxCodePoint1) { str[1] = '\0'; str[0] = static_cast(code_point); // 0xxxxxxx } else if (code_point <= kMaxCodePoint2) { str[2] = '\0'; str[1] = static_cast(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx str[0] = static_cast(0xC0 | code_point); // 110xxxxx } else if (code_point <= kMaxCodePoint3) { str[3] = '\0'; str[2] = static_cast(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx str[1] = static_cast(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx str[0] = static_cast(0xE0 | code_point); // 1110xxxx } else { // code_point <= kMaxCodePoint4 str[4] = '\0'; str[3] = static_cast(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx str[2] = static_cast(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx str[1] = static_cast(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx str[0] = static_cast(0xF0 | code_point); // 11110xxx } return str; } // The following two functions only make sense if the the system // uses UTF-16 for wide string encoding. All supported systems // with 16 bit wchar_t (Windows, Cygwin, Symbian OS) do use UTF-16. // Determines if the arguments constitute UTF-16 surrogate pair // and thus should be combined into a single Unicode code point // using CreateCodePointFromUtf16SurrogatePair. inline bool IsUtf16SurrogatePair(wchar_t first, wchar_t second) { return sizeof(wchar_t) == 2 && (first & 0xFC00) == 0xD800 && (second & 0xFC00) == 0xDC00; } // Creates a Unicode code point from UTF16 surrogate pair. inline UInt32 CreateCodePointFromUtf16SurrogatePair(wchar_t first, wchar_t second) { const UInt32 mask = (1 << 10) - 1; return (sizeof(wchar_t) == 2) ? (((first & mask) << 10) | (second & mask)) + 0x10000 : // This function should not be called when the condition is // false, but we provide a sensible default in case it is. static_cast(first); } // Converts a wide string to a narrow string in UTF-8 encoding. // The wide string is assumed to have the following encoding: // UTF-16 if sizeof(wchar_t) == 2 (on Windows, Cygwin, Symbian OS) // UTF-32 if sizeof(wchar_t) == 4 (on Linux) // Parameter str points to a null-terminated wide string. // Parameter num_chars may additionally limit the number // of wchar_t characters processed. -1 is used when the entire string // should be processed. // If the string contains code points that are not valid Unicode code points // (i.e. outside of Unicode range U+0 to U+10FFFF) they will be output // as '(Invalid Unicode 0xXXXXXXXX)'. If the string is in UTF16 encoding // and contains invalid UTF-16 surrogate pairs, values in those pairs // will be encoded as individual Unicode characters from Basic Normal Plane. std::string WideStringToUtf8(const wchar_t* str, int num_chars) { if (num_chars == -1) num_chars = static_cast(wcslen(str)); ::std::stringstream stream; for (int i = 0; i < num_chars; ++i) { UInt32 unicode_code_point; if (str[i] == L'\0') { break; } else if (i + 1 < num_chars && IsUtf16SurrogatePair(str[i], str[i + 1])) { unicode_code_point = CreateCodePointFromUtf16SurrogatePair(str[i], str[i + 1]); i++; } else { unicode_code_point = static_cast(str[i]); } stream << CodePointToUtf8(unicode_code_point); } return StringStreamToString(&stream); } // Converts a wide C string to an std::string using the UTF-8 encoding. // NULL will be converted to "(null)". std::string String::ShowWideCString(const wchar_t * wide_c_str) { if (wide_c_str == NULL) return "(null)"; return internal::WideStringToUtf8(wide_c_str, -1); } // Compares two wide C strings. Returns true iff they have the same // content. // // Unlike wcscmp(), this function can handle NULL argument(s). A NULL // C string is considered different to any non-NULL C string, // including the empty string. bool String::WideCStringEquals(const wchar_t * lhs, const wchar_t * rhs) { if (lhs == NULL) return rhs == NULL; if (rhs == NULL) return false; return wcscmp(lhs, rhs) == 0; } // Helper function for *_STREQ on wide strings. AssertionResult CmpHelperSTREQ(const char* expected_expression, const char* actual_expression, const wchar_t* expected, const wchar_t* actual) { if (String::WideCStringEquals(expected, actual)) { return AssertionSuccess(); } return EqFailure(expected_expression, actual_expression, PrintToString(expected), PrintToString(actual), false); } // Helper function for *_STRNE on wide strings. AssertionResult CmpHelperSTRNE(const char* s1_expression, const char* s2_expression, const wchar_t* s1, const wchar_t* s2) { if (!String::WideCStringEquals(s1, s2)) { return AssertionSuccess(); } return AssertionFailure() << "Expected: (" << s1_expression << ") != (" << s2_expression << "), actual: " << PrintToString(s1) << " vs " << PrintToString(s2); } // Compares two C strings, ignoring case. Returns true iff they have // the same content. // // Unlike strcasecmp(), this function can handle NULL argument(s). A // NULL C string is considered different to any non-NULL C string, // including the empty string. bool String::CaseInsensitiveCStringEquals(const char * lhs, const char * rhs) { if (lhs == NULL) return rhs == NULL; if (rhs == NULL) return false; return posix::StrCaseCmp(lhs, rhs) == 0; } // Compares two wide C strings, ignoring case. Returns true iff they // have the same content. // // Unlike wcscasecmp(), this function can handle NULL argument(s). // A NULL C string is considered different to any non-NULL wide C string, // including the empty string. // NB: The implementations on different platforms slightly differ. // On windows, this method uses _wcsicmp which compares according to LC_CTYPE // environment variable. On GNU platform this method uses wcscasecmp // which compares according to LC_CTYPE category of the current locale. // On MacOS X, it uses towlower, which also uses LC_CTYPE category of the // current locale. bool String::CaseInsensitiveWideCStringEquals(const wchar_t* lhs, const wchar_t* rhs) { if (lhs == NULL) return rhs == NULL; if (rhs == NULL) return false; #if GTEST_OS_WINDOWS return _wcsicmp(lhs, rhs) == 0; #elif GTEST_OS_LINUX && !GTEST_OS_LINUX_ANDROID return wcscasecmp(lhs, rhs) == 0; #else // Android, Mac OS X and Cygwin don't define wcscasecmp. // Other unknown OSes may not define it either. wint_t left, right; do { left = towlower(*lhs++); right = towlower(*rhs++); } while (left && left == right); return left == right; #endif // OS selector } // Returns true iff str ends with the given suffix, ignoring case. // Any string is considered to end with an empty suffix. bool String::EndsWithCaseInsensitive( const std::string& str, const std::string& suffix) { const size_t str_len = str.length(); const size_t suffix_len = suffix.length(); return (str_len >= suffix_len) && CaseInsensitiveCStringEquals(str.c_str() + str_len - suffix_len, suffix.c_str()); } // Formats an int value as "%02d". std::string String::FormatIntWidth2(int value) { std::stringstream ss; ss << std::setfill('0') << std::setw(2) << value; return ss.str(); } // Formats an int value as "%X". std::string String::FormatHexInt(int value) { std::stringstream ss; ss << std::hex << std::uppercase << value; return ss.str(); } // Formats a byte as "%02X". std::string String::FormatByte(unsigned char value) { std::stringstream ss; ss << std::setfill('0') << std::setw(2) << std::hex << std::uppercase << static_cast(value); return ss.str(); } // Converts the buffer in a stringstream to an std::string, converting NUL // bytes to "\\0" along the way. std::string StringStreamToString(::std::stringstream* ss) { const ::std::string& str = ss->str(); const char* const start = str.c_str(); const char* const end = start + str.length(); std::string result; result.reserve(2 * (end - start)); for (const char* ch = start; ch != end; ++ch) { if (*ch == '\0') { result += "\\0"; // Replaces NUL with "\\0"; } else { result += *ch; } } return result; } // Appends the user-supplied message to the Google-Test-generated message. std::string AppendUserMessage(const std::string& gtest_msg, const Message& user_msg) { // Appends the user message if it's non-empty. const std::string user_msg_string = user_msg.GetString(); if (user_msg_string.empty()) { return gtest_msg; } return gtest_msg + "\n" + user_msg_string; } } // namespace internal // class TestResult // Creates an empty TestResult. TestResult::TestResult() : death_test_count_(0), elapsed_time_(0) { } // D'tor. TestResult::~TestResult() { } // Returns the i-th test part result among all the results. i can // range from 0 to total_part_count() - 1. If i is not in that range, // aborts the program. const TestPartResult& TestResult::GetTestPartResult(int i) const { if (i < 0 || i >= total_part_count()) internal::posix::Abort(); return test_part_results_.at(i); } // Returns the i-th test property. i can range from 0 to // test_property_count() - 1. If i is not in that range, aborts the // program. const TestProperty& TestResult::GetTestProperty(int i) const { if (i < 0 || i >= test_property_count()) internal::posix::Abort(); return test_properties_.at(i); } // Clears the test part results. void TestResult::ClearTestPartResults() { test_part_results_.clear(); } // Adds a test part result to the list. void TestResult::AddTestPartResult(const TestPartResult& test_part_result) { test_part_results_.push_back(test_part_result); } // Adds a test property to the list. If a property with the same key as the // supplied property is already represented, the value of this test_property // replaces the old value for that key. void TestResult::RecordProperty(const std::string& xml_element, const TestProperty& test_property) { if (!ValidateTestProperty(xml_element, test_property)) { return; } internal::MutexLock lock(&test_properites_mutex_); const std::vector::iterator property_with_matching_key = std::find_if(test_properties_.begin(), test_properties_.end(), internal::TestPropertyKeyIs(test_property.key())); if (property_with_matching_key == test_properties_.end()) { test_properties_.push_back(test_property); return; } property_with_matching_key->SetValue(test_property.value()); } // The list of reserved attributes used in the element of XML // output. static const char* const kReservedTestSuitesAttributes[] = { "disabled", "errors", "failures", "name", "random_seed", "tests", "time", "timestamp" }; // The list of reserved attributes used in the element of XML // output. static const char* const kReservedTestSuiteAttributes[] = { "disabled", "errors", "failures", "name", "tests", "time" }; // The list of reserved attributes used in the element of XML output. static const char* const kReservedTestCaseAttributes[] = { "classname", "name", "status", "time", "type_param", "value_param" }; template std::vector ArrayAsVector(const char* const (&array)[kSize]) { return std::vector(array, array + kSize); } static std::vector GetReservedAttributesForElement( const std::string& xml_element) { if (xml_element == "testsuites") { return ArrayAsVector(kReservedTestSuitesAttributes); } else if (xml_element == "testsuite") { return ArrayAsVector(kReservedTestSuiteAttributes); } else if (xml_element == "testcase") { return ArrayAsVector(kReservedTestCaseAttributes); } else { GTEST_CHECK_(false) << "Unrecognized xml_element provided: " << xml_element; } // This code is unreachable but some compilers may not realizes that. return std::vector(); } static std::string FormatWordList(const std::vector& words) { Message word_list; for (size_t i = 0; i < words.size(); ++i) { if (i > 0 && words.size() > 2) { word_list << ", "; } if (i == words.size() - 1) { word_list << "and "; } word_list << "'" << words[i] << "'"; } return word_list.GetString(); } bool ValidateTestPropertyName(const std::string& property_name, const std::vector& reserved_names) { if (std::find(reserved_names.begin(), reserved_names.end(), property_name) != reserved_names.end()) { ADD_FAILURE() << "Reserved key used in RecordProperty(): " << property_name << " (" << FormatWordList(reserved_names) << " are reserved by " << GTEST_NAME_ << ")"; return false; } return true; } // Adds a failure if the key is a reserved attribute of the element named // xml_element. Returns true if the property is valid. bool TestResult::ValidateTestProperty(const std::string& xml_element, const TestProperty& test_property) { return ValidateTestPropertyName(test_property.key(), GetReservedAttributesForElement(xml_element)); } // Clears the object. void TestResult::Clear() { test_part_results_.clear(); test_properties_.clear(); death_test_count_ = 0; elapsed_time_ = 0; } // Returns true iff the test failed. bool TestResult::Failed() const { for (int i = 0; i < total_part_count(); ++i) { if (GetTestPartResult(i).failed()) return true; } return false; } // Returns true iff the test part fatally failed. static bool TestPartFatallyFailed(const TestPartResult& result) { return result.fatally_failed(); } // Returns true iff the test fatally failed. bool TestResult::HasFatalFailure() const { return CountIf(test_part_results_, TestPartFatallyFailed) > 0; } // Returns true iff the test part non-fatally failed. static bool TestPartNonfatallyFailed(const TestPartResult& result) { return result.nonfatally_failed(); } // Returns true iff the test has a non-fatal failure. bool TestResult::HasNonfatalFailure() const { return CountIf(test_part_results_, TestPartNonfatallyFailed) > 0; } // Gets the number of all test parts. This is the sum of the number // of successful test parts and the number of failed test parts. int TestResult::total_part_count() const { return static_cast(test_part_results_.size()); } // Returns the number of the test properties. int TestResult::test_property_count() const { return static_cast(test_properties_.size()); } // class Test // Creates a Test object. // The c'tor saves the values of all Google Test flags. Test::Test() : gtest_flag_saver_(new internal::GTestFlagSaver) { } // The d'tor restores the values of all Google Test flags. Test::~Test() { delete gtest_flag_saver_; } // Sets up the test fixture. // // A sub-class may override this. void Test::SetUp() { } // Tears down the test fixture. // // A sub-class may override this. void Test::TearDown() { } // Allows user supplied key value pairs to be recorded for later output. void Test::RecordProperty(const std::string& key, const std::string& value) { UnitTest::GetInstance()->RecordProperty(key, value); } // Allows user supplied key value pairs to be recorded for later output. void Test::RecordProperty(const std::string& key, int value) { Message value_message; value_message << value; RecordProperty(key, value_message.GetString().c_str()); } namespace internal { void ReportFailureInUnknownLocation(TestPartResult::Type result_type, const std::string& message) { // This function is a friend of UnitTest and as such has access to // AddTestPartResult. UnitTest::GetInstance()->AddTestPartResult( result_type, NULL, // No info about the source file where the exception occurred. -1, // We have no info on which line caused the exception. message, ""); // No stack trace, either. } } // namespace internal // Google Test requires all tests in the same test case to use the same test // fixture class. This function checks if the current test has the // same fixture class as the first test in the current test case. If // yes, it returns true; otherwise it generates a Google Test failure and // returns false. bool Test::HasSameFixtureClass() { internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); const TestCase* const test_case = impl->current_test_case(); // Info about the first test in the current test case. const TestInfo* const first_test_info = test_case->test_info_list()[0]; const internal::TypeId first_fixture_id = first_test_info->fixture_class_id_; const char* const first_test_name = first_test_info->name(); // Info about the current test. const TestInfo* const this_test_info = impl->current_test_info(); const internal::TypeId this_fixture_id = this_test_info->fixture_class_id_; const char* const this_test_name = this_test_info->name(); if (this_fixture_id != first_fixture_id) { // Is the first test defined using TEST? const bool first_is_TEST = first_fixture_id == internal::GetTestTypeId(); // Is this test defined using TEST? const bool this_is_TEST = this_fixture_id == internal::GetTestTypeId(); if (first_is_TEST || this_is_TEST) { // The user mixed TEST and TEST_F in this test case - we'll tell // him/her how to fix it. // Gets the name of the TEST and the name of the TEST_F. Note // that first_is_TEST and this_is_TEST cannot both be true, as // the fixture IDs are different for the two tests. const char* const TEST_name = first_is_TEST ? first_test_name : this_test_name; const char* const TEST_F_name = first_is_TEST ? this_test_name : first_test_name; ADD_FAILURE() << "All tests in the same test case must use the same test fixture\n" << "class, so mixing TEST_F and TEST in the same test case is\n" << "illegal. In test case " << this_test_info->test_case_name() << ",\n" << "test " << TEST_F_name << " is defined using TEST_F but\n" << "test " << TEST_name << " is defined using TEST. You probably\n" << "want to change the TEST to TEST_F or move it to another test\n" << "case."; } else { // The user defined two fixture classes with the same name in // two namespaces - we'll tell him/her how to fix it. ADD_FAILURE() << "All tests in the same test case must use the same test fixture\n" << "class. However, in test case " << this_test_info->test_case_name() << ",\n" << "you defined test " << first_test_name << " and test " << this_test_name << "\n" << "using two different test fixture classes. This can happen if\n" << "the two classes are from different namespaces or translation\n" << "units and have the same name. You should probably rename one\n" << "of the classes to put the tests into different test cases."; } return false; } return true; } #if GTEST_HAS_SEH // Adds an "exception thrown" fatal failure to the current test. This // function returns its result via an output parameter pointer because VC++ // prohibits creation of objects with destructors on stack in functions // using __try (see error C2712). static std::string* FormatSehExceptionMessage(DWORD exception_code, const char* location) { Message message; message << "SEH exception with code 0x" << std::setbase(16) << exception_code << std::setbase(10) << " thrown in " << location << "."; return new std::string(message.GetString()); } #endif // GTEST_HAS_SEH namespace internal { #if GTEST_HAS_EXCEPTIONS // Adds an "exception thrown" fatal failure to the current test. static std::string FormatCxxExceptionMessage(const char* description, const char* location) { Message message; if (description != NULL) { message << "C++ exception with description \"" << description << "\""; } else { message << "Unknown C++ exception"; } message << " thrown in " << location << "."; return message.GetString(); } static std::string PrintTestPartResultToString( const TestPartResult& test_part_result); GoogleTestFailureException::GoogleTestFailureException( const TestPartResult& failure) : ::std::runtime_error(PrintTestPartResultToString(failure).c_str()) {} #endif // GTEST_HAS_EXCEPTIONS // We put these helper functions in the internal namespace as IBM's xlC // compiler rejects the code if they were declared static. // Runs the given method and handles SEH exceptions it throws, when // SEH is supported; returns the 0-value for type Result in case of an // SEH exception. (Microsoft compilers cannot handle SEH and C++ // exceptions in the same function. Therefore, we provide a separate // wrapper function for handling SEH exceptions.) template Result HandleSehExceptionsInMethodIfSupported( T* object, Result (T::*method)(), const char* location) { #if GTEST_HAS_SEH __try { return (object->*method)(); } __except (internal::UnitTestOptions::GTestShouldProcessSEH( // NOLINT GetExceptionCode())) { // We create the exception message on the heap because VC++ prohibits // creation of objects with destructors on stack in functions using __try // (see error C2712). std::string* exception_message = FormatSehExceptionMessage( GetExceptionCode(), location); internal::ReportFailureInUnknownLocation(TestPartResult::kFatalFailure, *exception_message); delete exception_message; return static_cast(0); } #else (void)location; return (object->*method)(); #endif // GTEST_HAS_SEH } // Runs the given method and catches and reports C++ and/or SEH-style // exceptions, if they are supported; returns the 0-value for type // Result in case of an SEH exception. template Result HandleExceptionsInMethodIfSupported( T* object, Result (T::*method)(), const char* location) { // NOTE: The user code can affect the way in which Google Test handles // exceptions by setting GTEST_FLAG(catch_exceptions), but only before // RUN_ALL_TESTS() starts. It is technically possible to check the flag // after the exception is caught and either report or re-throw the // exception based on the flag's value: // // try { // // Perform the test method. // } catch (...) { // if (GTEST_FLAG(catch_exceptions)) // // Report the exception as failure. // else // throw; // Re-throws the original exception. // } // // However, the purpose of this flag is to allow the program to drop into // the debugger when the exception is thrown. On most platforms, once the // control enters the catch block, the exception origin information is // lost and the debugger will stop the program at the point of the // re-throw in this function -- instead of at the point of the original // throw statement in the code under test. For this reason, we perform // the check early, sacrificing the ability to affect Google Test's // exception handling in the method where the exception is thrown. if (internal::GetUnitTestImpl()->catch_exceptions()) { #if GTEST_HAS_EXCEPTIONS try { return HandleSehExceptionsInMethodIfSupported(object, method, location); } catch (const internal::GoogleTestFailureException&) { // NOLINT // This exception type can only be thrown by a failed Google // Test assertion with the intention of letting another testing // framework catch it. Therefore we just re-throw it. throw; } catch (const std::exception& e) { // NOLINT internal::ReportFailureInUnknownLocation( TestPartResult::kFatalFailure, FormatCxxExceptionMessage(e.what(), location)); } catch (...) { // NOLINT internal::ReportFailureInUnknownLocation( TestPartResult::kFatalFailure, FormatCxxExceptionMessage(NULL, location)); } return static_cast(0); #else return HandleSehExceptionsInMethodIfSupported(object, method, location); #endif // GTEST_HAS_EXCEPTIONS } else { return (object->*method)(); } } } // namespace internal // Runs the test and updates the test result. void Test::Run() { if (!HasSameFixtureClass()) return; internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); impl->os_stack_trace_getter()->UponLeavingGTest(); internal::HandleExceptionsInMethodIfSupported(this, &Test::SetUp, "SetUp()"); // We will run the test only if SetUp() was successful. if (!HasFatalFailure()) { impl->os_stack_trace_getter()->UponLeavingGTest(); internal::HandleExceptionsInMethodIfSupported( this, &Test::TestBody, "the test body"); } // However, we want to clean up as much as possible. Hence we will // always call TearDown(), even if SetUp() or the test body has // failed. impl->os_stack_trace_getter()->UponLeavingGTest(); internal::HandleExceptionsInMethodIfSupported( this, &Test::TearDown, "TearDown()"); } // Returns true iff the current test has a fatal failure. bool Test::HasFatalFailure() { return internal::GetUnitTestImpl()->current_test_result()->HasFatalFailure(); } // Returns true iff the current test has a non-fatal failure. bool Test::HasNonfatalFailure() { return internal::GetUnitTestImpl()->current_test_result()-> HasNonfatalFailure(); } // class TestInfo // Constructs a TestInfo object. It assumes ownership of the test factory // object. 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::TypeId fixture_class_id, internal::TestFactoryBase* factory) : test_case_name_(a_test_case_name), name_(a_name), type_param_(a_type_param ? new std::string(a_type_param) : NULL), value_param_(a_value_param ? new std::string(a_value_param) : NULL), fixture_class_id_(fixture_class_id), should_run_(false), is_disabled_(false), matches_filter_(false), factory_(factory), result_() {} // Destructs a TestInfo object. TestInfo::~TestInfo() { delete factory_; } namespace internal { // Creates a new TestInfo object and registers it with Google Test; // returns the created object. // // Arguments: // // test_case_name: name of the test case // name: name of the test // type_param: the name of the test's type parameter, or NULL if // this is not a typed or a type-parameterized test. // value_param: text representation of the test's value parameter, // or NULL if this is not a value-parameterized test. // fixture_class_id: ID of the test fixture class // set_up_tc: pointer to the function that sets up the test case // tear_down_tc: pointer to the function that tears down the test case // factory: pointer to the factory that creates a test object. // The newly created TestInfo instance will assume // ownership of the factory object. TestInfo* MakeAndRegisterTestInfo( const char* test_case_name, const char* name, const char* type_param, const char* value_param, TypeId fixture_class_id, SetUpTestCaseFunc set_up_tc, TearDownTestCaseFunc tear_down_tc, TestFactoryBase* factory) { TestInfo* const test_info = new TestInfo(test_case_name, name, type_param, value_param, fixture_class_id, factory); GetUnitTestImpl()->AddTestInfo(set_up_tc, tear_down_tc, test_info); return test_info; } #if GTEST_HAS_PARAM_TEST void ReportInvalidTestCaseType(const char* test_case_name, const char* file, int line) { Message errors; errors << "Attempted redefinition of test case " << test_case_name << ".\n" << "All tests in the same test case must use the same test fixture\n" << "class. However, in test case " << test_case_name << ", you tried\n" << "to define a test using a fixture class different from the one\n" << "used earlier. This can happen if the two fixture classes are\n" << "from different namespaces and have the same name. You should\n" << "probably rename one of the classes to put the tests into different\n" << "test cases."; fprintf(stderr, "%s %s", FormatFileLocation(file, line).c_str(), errors.GetString().c_str()); } #endif // GTEST_HAS_PARAM_TEST } // namespace internal namespace { // A predicate that checks the test name of a TestInfo against a known // value. // // This is used for implementation of the TestCase class only. We put // it in the anonymous namespace to prevent polluting the outer // namespace. // // TestNameIs is copyable. class TestNameIs { public: // Constructor. // // TestNameIs has NO default constructor. explicit TestNameIs(const char* name) : name_(name) {} // Returns true iff the test name of test_info matches name_. bool operator()(const TestInfo * test_info) const { return test_info && test_info->name() == name_; } private: std::string name_; }; } // namespace namespace internal { // This method expands all parameterized tests registered with macros TEST_P // and INSTANTIATE_TEST_CASE_P into regular tests and registers those. // This will be done just once during the program runtime. void UnitTestImpl::RegisterParameterizedTests() { #if GTEST_HAS_PARAM_TEST if (!parameterized_tests_registered_) { parameterized_test_registry_.RegisterTests(); parameterized_tests_registered_ = true; } #endif } } // namespace internal // Creates the test object, runs it, records its result, and then // deletes it. void TestInfo::Run() { if (!should_run_) return; // Tells UnitTest where to store test result. internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); impl->set_current_test_info(this); TestEventListener* repeater = UnitTest::GetInstance()->listeners().repeater(); // Notifies the unit test event listeners that a test is about to start. repeater->OnTestStart(*this); const TimeInMillis start = internal::GetTimeInMillis(); impl->os_stack_trace_getter()->UponLeavingGTest(); // Creates the test object. Test* const test = internal::HandleExceptionsInMethodIfSupported( factory_, &internal::TestFactoryBase::CreateTest, "the test fixture's constructor"); // Runs the test only if the test object was created and its // constructor didn't generate a fatal failure. if ((test != NULL) && !Test::HasFatalFailure()) { // This doesn't throw as all user code that can throw are wrapped into // exception handling code. test->Run(); } // Deletes the test object. impl->os_stack_trace_getter()->UponLeavingGTest(); internal::HandleExceptionsInMethodIfSupported( test, &Test::DeleteSelf_, "the test fixture's destructor"); result_.set_elapsed_time(internal::GetTimeInMillis() - start); // Notifies the unit test event listener that a test has just finished. repeater->OnTestEnd(*this); // Tells UnitTest to stop associating assertion results to this // test. impl->set_current_test_info(NULL); } // class TestCase // Gets the number of successful tests in this test case. int TestCase::successful_test_count() const { return CountIf(test_info_list_, TestPassed); } // Gets the number of failed tests in this test case. int TestCase::failed_test_count() const { return CountIf(test_info_list_, TestFailed); } // Gets the number of disabled tests that will be reported in the XML report. int TestCase::reportable_disabled_test_count() const { return CountIf(test_info_list_, TestReportableDisabled); } // Gets the number of disabled tests in this test case. int TestCase::disabled_test_count() const { return CountIf(test_info_list_, TestDisabled); } // Gets the number of tests to be printed in the XML report. int TestCase::reportable_test_count() const { return CountIf(test_info_list_, TestReportable); } // Get the number of tests in this test case that should run. int TestCase::test_to_run_count() const { return CountIf(test_info_list_, ShouldRunTest); } // Gets the number of all tests. int TestCase::total_test_count() const { return static_cast(test_info_list_.size()); } // Creates a TestCase with the given name. // // Arguments: // // name: name of the test case // a_type_param: the name of the test case's type parameter, or NULL if // this is not a typed or a type-parameterized test case. // set_up_tc: pointer to the function that sets up the test case // tear_down_tc: pointer to the function that tears down the test case TestCase::TestCase(const char* a_name, const char* a_type_param, Test::SetUpTestCaseFunc set_up_tc, Test::TearDownTestCaseFunc tear_down_tc) : name_(a_name), type_param_(a_type_param ? new std::string(a_type_param) : NULL), set_up_tc_(set_up_tc), tear_down_tc_(tear_down_tc), should_run_(false), elapsed_time_(0) { } // Destructor of TestCase. TestCase::~TestCase() { // Deletes every Test in the collection. ForEach(test_info_list_, internal::Delete); } // Returns the i-th test among all the tests. i can range from 0 to // total_test_count() - 1. If i is not in that range, returns NULL. const TestInfo* TestCase::GetTestInfo(int i) const { const int index = GetElementOr(test_indices_, i, -1); return index < 0 ? NULL : test_info_list_[index]; } // Returns the i-th test among all the tests. i can range from 0 to // total_test_count() - 1. If i is not in that range, returns NULL. TestInfo* TestCase::GetMutableTestInfo(int i) { const int index = GetElementOr(test_indices_, i, -1); return index < 0 ? NULL : test_info_list_[index]; } // Adds a test to this test case. Will delete the test upon // destruction of the TestCase object. void TestCase::AddTestInfo(TestInfo * test_info) { test_info_list_.push_back(test_info); test_indices_.push_back(static_cast(test_indices_.size())); } // Runs every test in this TestCase. void TestCase::Run() { if (!should_run_) return; internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); impl->set_current_test_case(this); TestEventListener* repeater = UnitTest::GetInstance()->listeners().repeater(); repeater->OnTestCaseStart(*this); impl->os_stack_trace_getter()->UponLeavingGTest(); internal::HandleExceptionsInMethodIfSupported( this, &TestCase::RunSetUpTestCase, "SetUpTestCase()"); const internal::TimeInMillis start = internal::GetTimeInMillis(); for (int i = 0; i < total_test_count(); i++) { GetMutableTestInfo(i)->Run(); } elapsed_time_ = internal::GetTimeInMillis() - start; impl->os_stack_trace_getter()->UponLeavingGTest(); internal::HandleExceptionsInMethodIfSupported( this, &TestCase::RunTearDownTestCase, "TearDownTestCase()"); repeater->OnTestCaseEnd(*this); impl->set_current_test_case(NULL); } // Clears the results of all tests in this test case. void TestCase::ClearResult() { ad_hoc_test_result_.Clear(); ForEach(test_info_list_, TestInfo::ClearTestResult); } // Shuffles the tests in this test case. void TestCase::ShuffleTests(internal::Random* random) { Shuffle(random, &test_indices_); } // Restores the test order to before the first shuffle. void TestCase::UnshuffleTests() { for (size_t i = 0; i < test_indices_.size(); i++) { test_indices_[i] = static_cast(i); } } // Formats a countable noun. Depending on its quantity, either the // singular form or the plural form is used. e.g. // // FormatCountableNoun(1, "formula", "formuli") returns "1 formula". // FormatCountableNoun(5, "book", "books") returns "5 books". static std::string FormatCountableNoun(int count, const char * singular_form, const char * plural_form) { return internal::StreamableToString(count) + " " + (count == 1 ? singular_form : plural_form); } // Formats the count of tests. static std::string FormatTestCount(int test_count) { return FormatCountableNoun(test_count, "test", "tests"); } // Formats the count of test cases. static std::string FormatTestCaseCount(int test_case_count) { return FormatCountableNoun(test_case_count, "test case", "test cases"); } // Converts a TestPartResult::Type enum to human-friendly string // representation. Both kNonFatalFailure and kFatalFailure are translated // to "Failure", as the user usually doesn't care about the difference // between the two when viewing the test result. static const char * TestPartResultTypeToString(TestPartResult::Type type) { switch (type) { case TestPartResult::kSuccess: return "Success"; case TestPartResult::kNonFatalFailure: case TestPartResult::kFatalFailure: #ifdef _MSC_VER return "error: "; #else return "Failure\n"; #endif default: return "Unknown result type"; } } namespace internal { // Prints a TestPartResult to an std::string. static std::string PrintTestPartResultToString( const TestPartResult& test_part_result) { return (Message() << internal::FormatFileLocation(test_part_result.file_name(), test_part_result.line_number()) << " " << TestPartResultTypeToString(test_part_result.type()) << test_part_result.message()).GetString(); } // Prints a TestPartResult. static void PrintTestPartResult(const TestPartResult& test_part_result) { const std::string& result = PrintTestPartResultToString(test_part_result); printf("%s\n", result.c_str()); fflush(stdout); // If the test program runs in Visual Studio or a debugger, the // following statements add the test part result message to the Output // window such that the user can double-click on it to jump to the // corresponding source code location; otherwise they do nothing. #if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE // We don't call OutputDebugString*() on Windows Mobile, as printing // to stdout is done by OutputDebugString() there already - we don't // want the same message printed twice. ::OutputDebugStringA(result.c_str()); ::OutputDebugStringA("\n"); #endif } // class PrettyUnitTestResultPrinter enum GTestColor { COLOR_DEFAULT, COLOR_RED, COLOR_GREEN, COLOR_YELLOW }; #if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE // Returns the character attribute for the given color. WORD GetColorAttribute(GTestColor color) { switch (color) { case COLOR_RED: return FOREGROUND_RED; case COLOR_GREEN: return FOREGROUND_GREEN; case COLOR_YELLOW: return FOREGROUND_RED | FOREGROUND_GREEN; default: return 0; } } #else // Returns the ANSI color code for the given color. COLOR_DEFAULT is // an invalid input. const char* GetAnsiColorCode(GTestColor color) { switch (color) { case COLOR_RED: return "1"; case COLOR_GREEN: return "2"; case COLOR_YELLOW: return "3"; default: return NULL; }; } #endif // GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE // Returns true iff Google Test should use colors in the output. bool ShouldUseColor(bool stdout_is_tty) { const char* const gtest_color = GTEST_FLAG(color).c_str(); if (String::CaseInsensitiveCStringEquals(gtest_color, "auto")) { #if GTEST_OS_WINDOWS // On Windows the TERM variable is usually not set, but the // console there does support colors. return stdout_is_tty; #else // On non-Windows platforms, we rely on the TERM variable. const char* const term = posix::GetEnv("TERM"); const bool term_supports_color = String::CStringEquals(term, "xterm") || String::CStringEquals(term, "xterm-color") || String::CStringEquals(term, "xterm-256color") || String::CStringEquals(term, "screen") || String::CStringEquals(term, "screen-256color") || String::CStringEquals(term, "linux") || String::CStringEquals(term, "cygwin"); return stdout_is_tty && term_supports_color; #endif // GTEST_OS_WINDOWS } return String::CaseInsensitiveCStringEquals(gtest_color, "yes") || String::CaseInsensitiveCStringEquals(gtest_color, "true") || String::CaseInsensitiveCStringEquals(gtest_color, "t") || String::CStringEquals(gtest_color, "1"); // We take "yes", "true", "t", and "1" as meaning "yes". If the // value is neither one of these nor "auto", we treat it as "no" to // be conservative. } // Helpers for printing colored strings to stdout. Note that on Windows, we // cannot simply emit special characters and have the terminal change colors. // This routine must actually emit the characters rather than return a string // that would be colored when printed, as can be done on Linux. void ColoredPrintf(GTestColor color, const char* fmt, ...) { va_list args; va_start(args, fmt); #if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_SYMBIAN || GTEST_OS_ZOS || GTEST_OS_IOS const bool use_color = false; #else static const bool in_color_mode = ShouldUseColor(posix::IsATTY(posix::FileNo(stdout)) != 0); const bool use_color = in_color_mode && (color != COLOR_DEFAULT); #endif // GTEST_OS_WINDOWS_MOBILE || GTEST_OS_SYMBIAN || GTEST_OS_ZOS // The '!= 0' comparison is necessary to satisfy MSVC 7.1. if (!use_color) { vprintf(fmt, args); va_end(args); return; } #if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE const HANDLE stdout_handle = GetStdHandle(STD_OUTPUT_HANDLE); // Gets the current text color. CONSOLE_SCREEN_BUFFER_INFO buffer_info; GetConsoleScreenBufferInfo(stdout_handle, &buffer_info); const WORD old_color_attrs = buffer_info.wAttributes; // We need to flush the stream buffers into the console before each // SetConsoleTextAttribute call lest it affect the text that is already // printed but has not yet reached the console. fflush(stdout); SetConsoleTextAttribute(stdout_handle, GetColorAttribute(color) | FOREGROUND_INTENSITY); vprintf(fmt, args); fflush(stdout); // Restores the text color. SetConsoleTextAttribute(stdout_handle, old_color_attrs); #else printf("\033[0;3%sm", GetAnsiColorCode(color)); vprintf(fmt, args); printf("\033[m"); // Resets the terminal to default. #endif // GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE va_end(args); } // Text printed in Google Test's text output and --gunit_list_tests // output to label the type parameter and value parameter for a test. static const char kTypeParamLabel[] = "TypeParam"; static const char kValueParamLabel[] = "GetParam()"; void PrintFullTestCommentIfPresent(const TestInfo& test_info) { const char* const type_param = test_info.type_param(); const char* const value_param = test_info.value_param(); if (type_param != NULL || value_param != NULL) { printf(", where "); if (type_param != NULL) { printf("%s = %s", kTypeParamLabel, type_param); if (value_param != NULL) printf(" and "); } if (value_param != NULL) { printf("%s = %s", kValueParamLabel, value_param); } } } // This class implements the TestEventListener interface. // // Class PrettyUnitTestResultPrinter is copyable. class PrettyUnitTestResultPrinter : public TestEventListener { public: PrettyUnitTestResultPrinter() {} static void PrintTestName(const char * test_case, const char * test) { printf("%s.%s", test_case, test); } // The following methods override what's in the TestEventListener class. virtual void OnTestProgramStart(const UnitTest& /*unit_test*/) {} virtual void OnTestIterationStart(const UnitTest& unit_test, int iteration); virtual void OnEnvironmentsSetUpStart(const UnitTest& unit_test); virtual void OnEnvironmentsSetUpEnd(const UnitTest& /*unit_test*/) {} virtual void OnTestCaseStart(const TestCase& test_case); virtual void OnTestStart(const TestInfo& test_info); virtual void OnTestPartResult(const TestPartResult& result); virtual void OnTestEnd(const TestInfo& test_info); virtual void OnTestCaseEnd(const TestCase& test_case); virtual void OnEnvironmentsTearDownStart(const UnitTest& unit_test); virtual void OnEnvironmentsTearDownEnd(const UnitTest& /*unit_test*/) {} virtual void OnTestIterationEnd(const UnitTest& unit_test, int iteration); virtual void OnTestProgramEnd(const UnitTest& /*unit_test*/) {} private: static void PrintFailedTests(const UnitTest& unit_test); }; // Fired before each iteration of tests starts. void PrettyUnitTestResultPrinter::OnTestIterationStart( const UnitTest& unit_test, int iteration) { if (GTEST_FLAG(repeat) != 1) printf("\nRepeating all tests (iteration %d) . . .\n\n", iteration + 1); const char* const filter = GTEST_FLAG(filter).c_str(); // Prints the filter if it's not *. This reminds the user that some // tests may be skipped. if (!String::CStringEquals(filter, kUniversalFilter)) { ColoredPrintf(COLOR_YELLOW, "Note: %s filter = %s\n", GTEST_NAME_, filter); } if (internal::ShouldShard(kTestTotalShards, kTestShardIndex, false)) { const Int32 shard_index = Int32FromEnvOrDie(kTestShardIndex, -1); ColoredPrintf(COLOR_YELLOW, "Note: This is test shard %d of %s.\n", static_cast(shard_index) + 1, internal::posix::GetEnv(kTestTotalShards)); } if (GTEST_FLAG(shuffle)) { ColoredPrintf(COLOR_YELLOW, "Note: Randomizing tests' orders with a seed of %d .\n", unit_test.random_seed()); } ColoredPrintf(COLOR_GREEN, "[==========] "); printf("Running %s from %s.\n", FormatTestCount(unit_test.test_to_run_count()).c_str(), FormatTestCaseCount(unit_test.test_case_to_run_count()).c_str()); fflush(stdout); } void PrettyUnitTestResultPrinter::OnEnvironmentsSetUpStart( const UnitTest& /*unit_test*/) { ColoredPrintf(COLOR_GREEN, "[----------] "); printf("Global test environment set-up.\n"); fflush(stdout); } void PrettyUnitTestResultPrinter::OnTestCaseStart(const TestCase& test_case) { const std::string counts = FormatCountableNoun(test_case.test_to_run_count(), "test", "tests"); ColoredPrintf(COLOR_GREEN, "[----------] "); printf("%s from %s", counts.c_str(), test_case.name()); if (test_case.type_param() == NULL) { printf("\n"); } else { printf(", where %s = %s\n", kTypeParamLabel, test_case.type_param()); } fflush(stdout); } void PrettyUnitTestResultPrinter::OnTestStart(const TestInfo& test_info) { ColoredPrintf(COLOR_GREEN, "[ RUN ] "); PrintTestName(test_info.test_case_name(), test_info.name()); printf("\n"); fflush(stdout); } // Called after an assertion failure. void PrettyUnitTestResultPrinter::OnTestPartResult( const TestPartResult& result) { // If the test part succeeded, we don't need to do anything. if (result.type() == TestPartResult::kSuccess) return; // Print failure message from the assertion (e.g. expected this and got that). PrintTestPartResult(result); fflush(stdout); } void PrettyUnitTestResultPrinter::OnTestEnd(const TestInfo& test_info) { if (test_info.result()->Passed()) { ColoredPrintf(COLOR_GREEN, "[ OK ] "); } else { ColoredPrintf(COLOR_RED, "[ FAILED ] "); } PrintTestName(test_info.test_case_name(), test_info.name()); if (test_info.result()->Failed()) PrintFullTestCommentIfPresent(test_info); if (GTEST_FLAG(print_time)) { printf(" (%s ms)\n", internal::StreamableToString( test_info.result()->elapsed_time()).c_str()); } else { printf("\n"); } fflush(stdout); } void PrettyUnitTestResultPrinter::OnTestCaseEnd(const TestCase& test_case) { if (!GTEST_FLAG(print_time)) return; const std::string counts = FormatCountableNoun(test_case.test_to_run_count(), "test", "tests"); ColoredPrintf(COLOR_GREEN, "[----------] "); printf("%s from %s (%s ms total)\n\n", counts.c_str(), test_case.name(), internal::StreamableToString(test_case.elapsed_time()).c_str()); fflush(stdout); } void PrettyUnitTestResultPrinter::OnEnvironmentsTearDownStart( const UnitTest& /*unit_test*/) { ColoredPrintf(COLOR_GREEN, "[----------] "); printf("Global test environment tear-down\n"); fflush(stdout); } // Internal helper for printing the list of failed tests. void PrettyUnitTestResultPrinter::PrintFailedTests(const UnitTest& unit_test) { const int failed_test_count = unit_test.failed_test_count(); if (failed_test_count == 0) { return; } for (int i = 0; i < unit_test.total_test_case_count(); ++i) { const TestCase& test_case = *unit_test.GetTestCase(i); if (!test_case.should_run() || (test_case.failed_test_count() == 0)) { continue; } for (int j = 0; j < test_case.total_test_count(); ++j) { const TestInfo& test_info = *test_case.GetTestInfo(j); if (!test_info.should_run() || test_info.result()->Passed()) { continue; } ColoredPrintf(COLOR_RED, "[ FAILED ] "); printf("%s.%s", test_case.name(), test_info.name()); PrintFullTestCommentIfPresent(test_info); printf("\n"); } } } void PrettyUnitTestResultPrinter::OnTestIterationEnd(const UnitTest& unit_test, int /*iteration*/) { ColoredPrintf(COLOR_GREEN, "[==========] "); printf("%s from %s ran.", FormatTestCount(unit_test.test_to_run_count()).c_str(), FormatTestCaseCount(unit_test.test_case_to_run_count()).c_str()); if (GTEST_FLAG(print_time)) { printf(" (%s ms total)", internal::StreamableToString(unit_test.elapsed_time()).c_str()); } printf("\n"); ColoredPrintf(COLOR_GREEN, "[ PASSED ] "); printf("%s.\n", FormatTestCount(unit_test.successful_test_count()).c_str()); int num_failures = unit_test.failed_test_count(); if (!unit_test.Passed()) { const int failed_test_count = unit_test.failed_test_count(); ColoredPrintf(COLOR_RED, "[ FAILED ] "); printf("%s, listed below:\n", FormatTestCount(failed_test_count).c_str()); PrintFailedTests(unit_test); printf("\n%2d FAILED %s\n", num_failures, num_failures == 1 ? "TEST" : "TESTS"); } int num_disabled = unit_test.reportable_disabled_test_count(); if (num_disabled && !GTEST_FLAG(also_run_disabled_tests)) { if (!num_failures) { printf("\n"); // Add a spacer if no FAILURE banner is displayed. } ColoredPrintf(COLOR_YELLOW, " YOU HAVE %d DISABLED %s\n\n", num_disabled, num_disabled == 1 ? "TEST" : "TESTS"); } // Ensure that Google Test output is printed before, e.g., heapchecker output. fflush(stdout); } // End PrettyUnitTestResultPrinter // class TestEventRepeater // // This class forwards events to other event listeners. class TestEventRepeater : public TestEventListener { public: TestEventRepeater() : forwarding_enabled_(true) {} virtual ~TestEventRepeater(); void Append(TestEventListener *listener); TestEventListener* Release(TestEventListener* listener); // Controls whether events will be forwarded to listeners_. Set to false // in death test child processes. bool forwarding_enabled() const { return forwarding_enabled_; } void set_forwarding_enabled(bool enable) { forwarding_enabled_ = enable; } virtual void OnTestProgramStart(const UnitTest& unit_test); virtual void OnTestIterationStart(const UnitTest& unit_test, int iteration); virtual void OnEnvironmentsSetUpStart(const UnitTest& unit_test); virtual void OnEnvironmentsSetUpEnd(const UnitTest& unit_test); virtual void OnTestCaseStart(const TestCase& test_case); virtual void OnTestStart(const TestInfo& test_info); virtual void OnTestPartResult(const TestPartResult& result); virtual void OnTestEnd(const TestInfo& test_info); virtual void OnTestCaseEnd(const TestCase& test_case); virtual void OnEnvironmentsTearDownStart(const UnitTest& unit_test); virtual void OnEnvironmentsTearDownEnd(const UnitTest& unit_test); virtual void OnTestIterationEnd(const UnitTest& unit_test, int iteration); virtual void OnTestProgramEnd(const UnitTest& unit_test); private: // Controls whether events will be forwarded to listeners_. Set to false // in death test child processes. bool forwarding_enabled_; // The list of listeners that receive events. std::vector listeners_; GTEST_DISALLOW_COPY_AND_ASSIGN_(TestEventRepeater); }; TestEventRepeater::~TestEventRepeater() { ForEach(listeners_, Delete); } void TestEventRepeater::Append(TestEventListener *listener) { listeners_.push_back(listener); } // TODO(vladl@google.com): Factor the search functionality into Vector::Find. TestEventListener* TestEventRepeater::Release(TestEventListener *listener) { for (size_t i = 0; i < listeners_.size(); ++i) { if (listeners_[i] == listener) { listeners_.erase(listeners_.begin() + i); return listener; } } return NULL; } // Since most methods are very similar, use macros to reduce boilerplate. // This defines a member that forwards the call to all listeners. #define GTEST_REPEATER_METHOD_(Name, Type) \ void TestEventRepeater::Name(const Type& parameter) { \ if (forwarding_enabled_) { \ for (size_t i = 0; i < listeners_.size(); i++) { \ listeners_[i]->Name(parameter); \ } \ } \ } // This defines a member that forwards the call to all listeners in reverse // order. #define GTEST_REVERSE_REPEATER_METHOD_(Name, Type) \ void TestEventRepeater::Name(const Type& parameter) { \ if (forwarding_enabled_) { \ for (int i = static_cast(listeners_.size()) - 1; i >= 0; i--) { \ listeners_[i]->Name(parameter); \ } \ } \ } GTEST_REPEATER_METHOD_(OnTestProgramStart, UnitTest) GTEST_REPEATER_METHOD_(OnEnvironmentsSetUpStart, UnitTest) GTEST_REPEATER_METHOD_(OnTestCaseStart, TestCase) GTEST_REPEATER_METHOD_(OnTestStart, TestInfo) GTEST_REPEATER_METHOD_(OnTestPartResult, TestPartResult) GTEST_REPEATER_METHOD_(OnEnvironmentsTearDownStart, UnitTest) GTEST_REVERSE_REPEATER_METHOD_(OnEnvironmentsSetUpEnd, UnitTest) GTEST_REVERSE_REPEATER_METHOD_(OnEnvironmentsTearDownEnd, UnitTest) GTEST_REVERSE_REPEATER_METHOD_(OnTestEnd, TestInfo) GTEST_REVERSE_REPEATER_METHOD_(OnTestCaseEnd, TestCase) GTEST_REVERSE_REPEATER_METHOD_(OnTestProgramEnd, UnitTest) #undef GTEST_REPEATER_METHOD_ #undef GTEST_REVERSE_REPEATER_METHOD_ void TestEventRepeater::OnTestIterationStart(const UnitTest& unit_test, int iteration) { if (forwarding_enabled_) { for (size_t i = 0; i < listeners_.size(); i++) { listeners_[i]->OnTestIterationStart(unit_test, iteration); } } } void TestEventRepeater::OnTestIterationEnd(const UnitTest& unit_test, int iteration) { if (forwarding_enabled_) { for (int i = static_cast(listeners_.size()) - 1; i >= 0; i--) { listeners_[i]->OnTestIterationEnd(unit_test, iteration); } } } // End TestEventRepeater // This class generates an XML output file. class XmlUnitTestResultPrinter : public EmptyTestEventListener { public: explicit XmlUnitTestResultPrinter(const char* output_file); virtual void OnTestIterationEnd(const UnitTest& unit_test, int iteration); private: // Is c a whitespace character that is normalized to a space character // when it appears in an XML attribute value? static bool IsNormalizableWhitespace(char c) { return c == 0x9 || c == 0xA || c == 0xD; } // May c appear in a well-formed XML document? static bool IsValidXmlCharacter(char c) { return IsNormalizableWhitespace(c) || c >= 0x20; } // Returns an XML-escaped copy of the input string str. If // is_attribute is true, the text is meant to appear as an attribute // value, and normalizable whitespace is preserved by replacing it // with character references. static std::string EscapeXml(const std::string& str, bool is_attribute); // Returns the given string with all characters invalid in XML removed. static std::string RemoveInvalidXmlCharacters(const std::string& str); // Convenience wrapper around EscapeXml when str is an attribute value. static std::string EscapeXmlAttribute(const std::string& str) { return EscapeXml(str, true); } // Convenience wrapper around EscapeXml when str is not an attribute value. static std::string EscapeXmlText(const char* str) { return EscapeXml(str, false); } // Verifies that the given attribute belongs to the given element and // streams the attribute as XML. static void OutputXmlAttribute(std::ostream* stream, const std::string& element_name, const std::string& name, const std::string& value); // Streams an XML CDATA section, escaping invalid CDATA sequences as needed. static void OutputXmlCDataSection(::std::ostream* stream, const char* data); // Streams an XML representation of a TestInfo object. static void OutputXmlTestInfo(::std::ostream* stream, const char* test_case_name, const TestInfo& test_info); // Prints an XML representation of a TestCase object static void PrintXmlTestCase(::std::ostream* stream, const TestCase& test_case); // Prints an XML summary of unit_test to output stream out. static void PrintXmlUnitTest(::std::ostream* stream, const UnitTest& unit_test); // Produces a string representing the test properties in a result as space // delimited XML attributes based on the property key="value" pairs. // When the std::string is not empty, it includes a space at the beginning, // to delimit this attribute from prior attributes. static std::string TestPropertiesAsXmlAttributes(const TestResult& result); // The output file. const std::string output_file_; GTEST_DISALLOW_COPY_AND_ASSIGN_(XmlUnitTestResultPrinter); }; // Creates a new XmlUnitTestResultPrinter. XmlUnitTestResultPrinter::XmlUnitTestResultPrinter(const char* output_file) : output_file_(output_file) { if (output_file_.c_str() == NULL || output_file_.empty()) { fprintf(stderr, "XML output file may not be null\n"); fflush(stderr); exit(EXIT_FAILURE); } } // Called after the unit test ends. void XmlUnitTestResultPrinter::OnTestIterationEnd(const UnitTest& unit_test, int /*iteration*/) { FILE* xmlout = NULL; FilePath output_file(output_file_); FilePath output_dir(output_file.RemoveFileName()); if (output_dir.CreateDirectoriesRecursively()) { xmlout = posix::FOpen(output_file_.c_str(), "w"); } if (xmlout == NULL) { // TODO(wan): report the reason of the failure. // // We don't do it for now as: // // 1. There is no urgent need for it. // 2. It's a bit involved to make the errno variable thread-safe on // all three operating systems (Linux, Windows, and Mac OS). // 3. To interpret the meaning of errno in a thread-safe way, // we need the strerror_r() function, which is not available on // Windows. fprintf(stderr, "Unable to open file \"%s\"\n", output_file_.c_str()); fflush(stderr); exit(EXIT_FAILURE); } std::stringstream stream; PrintXmlUnitTest(&stream, unit_test); fprintf(xmlout, "%s", StringStreamToString(&stream).c_str()); fclose(xmlout); } // Returns an XML-escaped copy of the input string str. If is_attribute // is true, the text is meant to appear as an attribute value, and // normalizable whitespace is preserved by replacing it with character // references. // // Invalid XML characters in str, if any, are stripped from the output. // It is expected that most, if not all, of the text processed by this // module will consist of ordinary English text. // If this module is ever modified to produce version 1.1 XML output, // most invalid characters can be retained using character references. // TODO(wan): It might be nice to have a minimally invasive, human-readable // escaping scheme for invalid characters, rather than dropping them. std::string XmlUnitTestResultPrinter::EscapeXml( const std::string& str, bool is_attribute) { Message m; for (size_t i = 0; i < str.size(); ++i) { const char ch = str[i]; switch (ch) { case '<': m << "<"; break; case '>': m << ">"; break; case '&': m << "&"; break; case '\'': if (is_attribute) m << "'"; else m << '\''; break; case '"': if (is_attribute) m << """; else m << '"'; break; default: if (IsValidXmlCharacter(ch)) { if (is_attribute && IsNormalizableWhitespace(ch)) m << "&#x" << String::FormatByte(static_cast(ch)) << ";"; else m << ch; } break; } } return m.GetString(); } // Returns the given string with all characters invalid in XML removed. // Currently invalid characters are dropped from the string. An // alternative is to replace them with certain characters such as . or ?. std::string XmlUnitTestResultPrinter::RemoveInvalidXmlCharacters( const std::string& str) { std::string output; output.reserve(str.size()); for (std::string::const_iterator it = str.begin(); it != str.end(); ++it) if (IsValidXmlCharacter(*it)) output.push_back(*it); return output; } // The following routines generate an XML representation of a UnitTest // object. // // This is how Google Test concepts map to the DTD: // // <-- corresponds to a UnitTest object // <-- corresponds to a TestCase object // <-- corresponds to a TestInfo object // ... // ... // ... // <-- individual assertion failures // // // // Formats the given time in milliseconds as seconds. std::string FormatTimeInMillisAsSeconds(TimeInMillis ms) { ::std::stringstream ss; ss << ms/1000.0; return ss.str(); } // 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 // 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); } // Streams an XML CDATA section, escaping invalid CDATA sequences as needed. void XmlUnitTestResultPrinter::OutputXmlCDataSection(::std::ostream* stream, const char* data) { const char* segment = data; *stream << ""); if (next_segment != NULL) { stream->write( segment, static_cast(next_segment - segment)); *stream << "]]>]]>"); } else { *stream << segment; break; } } *stream << "]]>"; } void XmlUnitTestResultPrinter::OutputXmlAttribute( std::ostream* stream, const std::string& element_name, const std::string& name, const std::string& value) { const std::vector& allowed_names = GetReservedAttributesForElement(element_name); GTEST_CHECK_(std::find(allowed_names.begin(), allowed_names.end(), name) != allowed_names.end()) << "Attribute " << name << " is not allowed for element <" << element_name << ">."; *stream << " " << name << "=\"" << EscapeXmlAttribute(value) << "\""; } // Prints an XML representation of a TestInfo object. // TODO(wan): There is also value in printing properties with the plain printer. void XmlUnitTestResultPrinter::OutputXmlTestInfo(::std::ostream* stream, const char* test_case_name, const TestInfo& test_info) { const TestResult& result = *test_info.result(); const std::string kTestcase = "testcase"; *stream << " \n"; } const string location = internal::FormatCompilerIndependentFileLocation( part.file_name(), part.line_number()); const string summary = location + "\n" + part.summary(); *stream << " "; const string detail = location + "\n" + part.message(); OutputXmlCDataSection(stream, RemoveInvalidXmlCharacters(detail).c_str()); *stream << "\n"; } } if (failures == 0) *stream << " />\n"; else *stream << " \n"; } // Prints an XML representation of a TestCase object void XmlUnitTestResultPrinter::PrintXmlTestCase(std::ostream* stream, const TestCase& test_case) { const std::string kTestsuite = "testsuite"; *stream << " <" << kTestsuite; OutputXmlAttribute(stream, kTestsuite, "name", test_case.name()); OutputXmlAttribute(stream, kTestsuite, "tests", StreamableToString(test_case.reportable_test_count())); OutputXmlAttribute(stream, kTestsuite, "failures", StreamableToString(test_case.failed_test_count())); OutputXmlAttribute( stream, kTestsuite, "disabled", StreamableToString(test_case.reportable_disabled_test_count())); OutputXmlAttribute(stream, kTestsuite, "errors", "0"); OutputXmlAttribute(stream, kTestsuite, "time", FormatTimeInMillisAsSeconds(test_case.elapsed_time())); *stream << TestPropertiesAsXmlAttributes(test_case.ad_hoc_test_result()) << ">\n"; for (int i = 0; i < test_case.total_test_count(); ++i) { if (test_case.GetTestInfo(i)->is_reportable()) OutputXmlTestInfo(stream, test_case.name(), *test_case.GetTestInfo(i)); } *stream << " \n"; } // Prints an XML summary of unit_test to output stream out. void XmlUnitTestResultPrinter::PrintXmlUnitTest(std::ostream* stream, const UnitTest& unit_test) { const std::string kTestsuites = "testsuites"; *stream << "\n"; *stream << "<" << kTestsuites; OutputXmlAttribute(stream, kTestsuites, "tests", StreamableToString(unit_test.reportable_test_count())); OutputXmlAttribute(stream, kTestsuites, "failures", StreamableToString(unit_test.failed_test_count())); OutputXmlAttribute( stream, kTestsuites, "disabled", StreamableToString(unit_test.reportable_disabled_test_count())); OutputXmlAttribute(stream, kTestsuites, "errors", "0"); OutputXmlAttribute( stream, kTestsuites, "timestamp", FormatEpochTimeInMillisAsIso8601(unit_test.start_timestamp())); OutputXmlAttribute(stream, kTestsuites, "time", FormatTimeInMillisAsSeconds(unit_test.elapsed_time())); if (GTEST_FLAG(shuffle)) { OutputXmlAttribute(stream, kTestsuites, "random_seed", StreamableToString(unit_test.random_seed())); } *stream << TestPropertiesAsXmlAttributes(unit_test.ad_hoc_test_result()); OutputXmlAttribute(stream, kTestsuites, "name", "AllTests"); *stream << ">\n"; for (int i = 0; i < unit_test.total_test_case_count(); ++i) { if (unit_test.GetTestCase(i)->reportable_test_count() > 0) PrintXmlTestCase(stream, *unit_test.GetTestCase(i)); } *stream << "\n"; } // Produces a string representing the test properties in a result as space // delimited XML attributes based on the property key="value" pairs. std::string XmlUnitTestResultPrinter::TestPropertiesAsXmlAttributes( const TestResult& result) { Message attributes; for (int i = 0; i < result.test_property_count(); ++i) { const TestProperty& property = result.GetTestProperty(i); attributes << " " << property.key() << "=" << "\"" << EscapeXmlAttribute(property.value()) << "\""; } return attributes.GetString(); } // End XmlUnitTestResultPrinter #if GTEST_CAN_STREAM_RESULTS_ // Checks if str contains '=', '&', '%' or '\n' characters. If yes, // replaces them by "%xx" where xx is their hexadecimal value. For // example, replaces "=" with "%3D". This algorithm is O(strlen(str)) // in both time and space -- important as the input str may contain an // arbitrarily long test failure message and stack trace. string StreamingListener::UrlEncode(const char* str) { string result; result.reserve(strlen(str) + 1); for (char ch = *str; ch != '\0'; ch = *++str) { switch (ch) { case '%': case '=': case '&': case '\n': result.append("%" + String::FormatByte(static_cast(ch))); break; default: result.push_back(ch); break; } } return result; } void StreamingListener::SocketWriter::MakeConnection() { GTEST_CHECK_(sockfd_ == -1) << "MakeConnection() can't be called when there is already a connection."; addrinfo hints; memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_UNSPEC; // To allow both IPv4 and IPv6 addresses. hints.ai_socktype = SOCK_STREAM; addrinfo* servinfo = NULL; // Use the getaddrinfo() to get a linked list of IP addresses for // the given host name. const int error_num = getaddrinfo( host_name_.c_str(), port_num_.c_str(), &hints, &servinfo); if (error_num != 0) { GTEST_LOG_(WARNING) << "stream_result_to: getaddrinfo() failed: " << gai_strerror(error_num); } // Loop through all the results and connect to the first we can. for (addrinfo* cur_addr = servinfo; sockfd_ == -1 && cur_addr != NULL; cur_addr = cur_addr->ai_next) { sockfd_ = socket( cur_addr->ai_family, cur_addr->ai_socktype, cur_addr->ai_protocol); if (sockfd_ != -1) { // Connect the client socket to the server socket. if (connect(sockfd_, cur_addr->ai_addr, cur_addr->ai_addrlen) == -1) { close(sockfd_); sockfd_ = -1; } } } freeaddrinfo(servinfo); // all done with this structure if (sockfd_ == -1) { GTEST_LOG_(WARNING) << "stream_result_to: failed to connect to " << host_name_ << ":" << port_num_; } } // End of class Streaming Listener #endif // GTEST_CAN_STREAM_RESULTS__ // Class ScopedTrace // Pushes the given source file location and message onto a per-thread // trace stack maintained by Google Test. ScopedTrace::ScopedTrace(const char* file, int line, const Message& message) GTEST_LOCK_EXCLUDED_(&UnitTest::mutex_) { TraceInfo trace; trace.file = file; trace.line = line; trace.message = message.GetString(); UnitTest::GetInstance()->PushGTestTrace(trace); } // Pops the info pushed by the c'tor. ScopedTrace::~ScopedTrace() GTEST_LOCK_EXCLUDED_(&UnitTest::mutex_) { UnitTest::GetInstance()->PopGTestTrace(); } // 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_) { return ""; } void OsStackTraceGetter::UponLeavingGTest() GTEST_LOCK_EXCLUDED_(mutex_) { } const char* const OsStackTraceGetter::kElidedFramesMarker = "... " GTEST_NAME_ " internal frames ..."; // A helper class that creates the premature-exit file in its // constructor and deletes the file in its destructor. class ScopedPrematureExitFile { public: explicit ScopedPrematureExitFile(const char* premature_exit_filepath) : premature_exit_filepath_(premature_exit_filepath) { // If a path to the premature-exit file is specified... if (premature_exit_filepath != NULL && *premature_exit_filepath != '\0') { // create the file with a single "0" character in it. I/O // errors are ignored as there's nothing better we can do and we // don't want to fail the test because of this. FILE* pfile = posix::FOpen(premature_exit_filepath, "w"); fwrite("0", 1, 1, pfile); fclose(pfile); } } ~ScopedPrematureExitFile() { if (premature_exit_filepath_ != NULL && *premature_exit_filepath_ != '\0') { remove(premature_exit_filepath_); } } private: const char* const premature_exit_filepath_; GTEST_DISALLOW_COPY_AND_ASSIGN_(ScopedPrematureExitFile); }; } // namespace internal // class TestEventListeners TestEventListeners::TestEventListeners() : repeater_(new internal::TestEventRepeater()), default_result_printer_(NULL), default_xml_generator_(NULL) { } TestEventListeners::~TestEventListeners() { delete repeater_; } // Returns the standard listener responsible for the default console // output. Can be removed from the listeners list to shut down default // console output. Note that removing this object from the listener list // with Release transfers its ownership to the user. void TestEventListeners::Append(TestEventListener* listener) { repeater_->Append(listener); } // Removes the given event listener from the list and returns it. It then // becomes the caller's responsibility to delete the listener. Returns // NULL if the listener is not found in the list. TestEventListener* TestEventListeners::Release(TestEventListener* listener) { if (listener == default_result_printer_) default_result_printer_ = NULL; else if (listener == default_xml_generator_) default_xml_generator_ = NULL; return repeater_->Release(listener); } // Returns repeater that broadcasts the TestEventListener events to all // subscribers. TestEventListener* TestEventListeners::repeater() { return repeater_; } // Sets the default_result_printer attribute to the provided listener. // The listener is also added to the listener list and previous // default_result_printer is removed from it and deleted. The listener can // also be NULL in which case it will not be added to the list. Does // nothing if the previous and the current listener objects are the same. void TestEventListeners::SetDefaultResultPrinter(TestEventListener* listener) { if (default_result_printer_ != listener) { // It is an error to pass this method a listener that is already in the // list. delete Release(default_result_printer_); default_result_printer_ = listener; if (listener != NULL) Append(listener); } } // Sets the default_xml_generator attribute to the provided listener. The // listener is also added to the listener list and previous // default_xml_generator is removed from it and deleted. The listener can // also be NULL in which case it will not be added to the list. Does // nothing if the previous and the current listener objects are the same. void TestEventListeners::SetDefaultXmlGenerator(TestEventListener* listener) { if (default_xml_generator_ != listener) { // It is an error to pass this method a listener that is already in the // list. delete Release(default_xml_generator_); default_xml_generator_ = listener; if (listener != NULL) Append(listener); } } // Controls whether events will be forwarded by the repeater to the // listeners in the list. bool TestEventListeners::EventForwardingEnabled() const { return repeater_->forwarding_enabled(); } void TestEventListeners::SuppressEventForwarding() { repeater_->set_forwarding_enabled(false); } // class UnitTest // Gets the singleton UnitTest object. The first time this method is // called, a UnitTest object is constructed and returned. Consecutive // calls will return the same object. // // We don't protect this under mutex_ as a user is not supposed to // call this before main() starts, from which point on the return // value will never change. UnitTest* UnitTest::GetInstance() { // When compiled with MSVC 7.1 in optimized mode, destroying the // UnitTest object upon exiting the program messes up the exit code, // causing successful tests to appear failed. We have to use a // different implementation in this case to bypass the compiler bug. // This implementation makes the compiler happy, at the cost of // leaking the UnitTest object. // CodeGear C++Builder insists on a public destructor for the // default implementation. Use this implementation to keep good OO // design with private destructor. #if (_MSC_VER == 1310 && !defined(_DEBUG)) || defined(__BORLANDC__) static UnitTest* const instance = new UnitTest; return instance; #else static UnitTest instance; return &instance; #endif // (_MSC_VER == 1310 && !defined(_DEBUG)) || defined(__BORLANDC__) } // Gets the number of successful test cases. int UnitTest::successful_test_case_count() const { return impl()->successful_test_case_count(); } // Gets the number of failed test cases. int UnitTest::failed_test_case_count() const { return impl()->failed_test_case_count(); } // Gets the number of all test cases. int UnitTest::total_test_case_count() const { return impl()->total_test_case_count(); } // Gets the number of all test cases that contain at least one test // that should run. int UnitTest::test_case_to_run_count() const { return impl()->test_case_to_run_count(); } // Gets the number of successful tests. int UnitTest::successful_test_count() const { return impl()->successful_test_count(); } // Gets the number of failed tests. int UnitTest::failed_test_count() const { return impl()->failed_test_count(); } // Gets the number of disabled tests that will be reported in the XML report. int UnitTest::reportable_disabled_test_count() const { return impl()->reportable_disabled_test_count(); } // Gets the number of disabled tests. int UnitTest::disabled_test_count() const { return impl()->disabled_test_count(); } // Gets the number of tests to be printed in the XML report. int UnitTest::reportable_test_count() const { return impl()->reportable_test_count(); } // Gets the number of all tests. int UnitTest::total_test_count() const { return impl()->total_test_count(); } // Gets the number of tests that should run. int UnitTest::test_to_run_count() const { return impl()->test_to_run_count(); } // Gets the time of the test program start, in ms from the start of the // UNIX epoch. internal::TimeInMillis UnitTest::start_timestamp() const { return impl()->start_timestamp(); } // Gets the elapsed time, in milliseconds. internal::TimeInMillis UnitTest::elapsed_time() const { return impl()->elapsed_time(); } // Returns true iff the unit test passed (i.e. all test cases passed). bool UnitTest::Passed() const { return impl()->Passed(); } // Returns true iff the unit test failed (i.e. some test case failed // or something outside of all tests failed). bool UnitTest::Failed() const { return impl()->Failed(); } // Gets the i-th test case among all the test cases. i can range from 0 to // total_test_case_count() - 1. If i is not in that range, returns NULL. const TestCase* UnitTest::GetTestCase(int i) const { return impl()->GetTestCase(i); } // Returns the TestResult containing information on test failures and // properties logged outside of individual test cases. const TestResult& UnitTest::ad_hoc_test_result() const { return *impl()->ad_hoc_test_result(); } // Gets the i-th test case among all the test cases. i can range from 0 to // total_test_case_count() - 1. If i is not in that range, returns NULL. TestCase* UnitTest::GetMutableTestCase(int i) { return impl()->GetMutableTestCase(i); } // Returns the list of event listeners that can be used to track events // inside Google Test. TestEventListeners& UnitTest::listeners() { return *impl()->listeners(); } // Registers and returns a global test environment. When a test // program is run, all global test environments will be set-up in the // order they were registered. After all tests in the program have // finished, all global test environments will be torn-down in the // *reverse* order they were registered. // // The UnitTest object takes ownership of the given environment. // // We don't protect this under mutex_, as we only support calling it // from the main thread. Environment* UnitTest::AddEnvironment(Environment* env) { if (env == NULL) { return NULL; } impl_->environments().push_back(env); return env; } // Adds a TestPartResult to the current TestResult object. All Google Test // assertion macros (e.g. ASSERT_TRUE, EXPECT_EQ, etc) eventually call // this to report their results. The user code should use the // assertion macros instead of calling this directly. void UnitTest::AddTestPartResult( TestPartResult::Type result_type, const char* file_name, int line_number, const std::string& message, const std::string& os_stack_trace) GTEST_LOCK_EXCLUDED_(mutex_) { Message msg; msg << message; internal::MutexLock lock(&mutex_); if (impl_->gtest_trace_stack().size() > 0) { msg << "\n" << GTEST_NAME_ << " trace:"; for (int i = static_cast(impl_->gtest_trace_stack().size()); i > 0; --i) { const internal::TraceInfo& trace = impl_->gtest_trace_stack()[i - 1]; msg << "\n" << internal::FormatFileLocation(trace.file, trace.line) << " " << trace.message; } } if (os_stack_trace.c_str() != NULL && !os_stack_trace.empty()) { msg << internal::kStackTraceMarker << os_stack_trace; } const TestPartResult result = TestPartResult(result_type, file_name, line_number, msg.GetString().c_str()); impl_->GetTestPartResultReporterForCurrentThread()-> ReportTestPartResult(result); if (result_type != TestPartResult::kSuccess) { // gtest_break_on_failure takes precedence over // gtest_throw_on_failure. This allows a user to set the latter // in the code (perhaps in order to use Google Test assertions // with another testing framework) and specify the former on the // command line for debugging. if (GTEST_FLAG(break_on_failure)) { #if GTEST_OS_WINDOWS // Using DebugBreak on Windows allows gtest to still break into a debugger // when a failure happens and both the --gtest_break_on_failure and // the --gtest_catch_exceptions flags are specified. DebugBreak(); #else // Dereference NULL through a volatile pointer to prevent the compiler // from removing. We use this rather than abort() or __builtin_trap() for // portability: Symbian doesn't implement abort() well, and some debuggers // don't correctly trap abort(). *static_cast(NULL) = 1; #endif // GTEST_OS_WINDOWS } else if (GTEST_FLAG(throw_on_failure)) { #if GTEST_HAS_EXCEPTIONS throw internal::GoogleTestFailureException(result); #else // We cannot call abort() as it generates a pop-up in debug mode // that cannot be suppressed in VC 7.1 or below. exit(1); #endif } } } // Adds a TestProperty to the current TestResult object when invoked from // inside a test, to current TestCase's ad_hoc_test_result_ when invoked // from SetUpTestCase or TearDownTestCase, or to the global property set // when invoked elsewhere. If the result already contains a property with // the same key, the value will be updated. void UnitTest::RecordProperty(const std::string& key, const std::string& value) { impl_->RecordProperty(TestProperty(key, value)); } // Runs all tests in this UnitTest object and prints the result. // Returns 0 if successful, or 1 otherwise. // // We don't protect this under mutex_, as we only support calling it // from the main thread. int UnitTest::Run() { const bool in_death_test_child_process = internal::GTEST_FLAG(internal_run_death_test).length() > 0; // Google Test implements this protocol for catching that a test // program exits before returning control to Google Test: // // 1. Upon start, Google Test creates a file whose absolute path // is specified by the environment variable // TEST_PREMATURE_EXIT_FILE. // 2. When Google Test has finished its work, it deletes the file. // // This allows a test runner to set TEST_PREMATURE_EXIT_FILE before // running a Google-Test-based test program and check the existence // of the file at the end of the test execution to see if it has // exited prematurely. // If we are in the child process of a death test, don't // create/delete the premature exit file, as doing so is unnecessary // and will confuse the parent process. Otherwise, create/delete // the file upon entering/leaving this function. If the program // somehow exits before this function has a chance to return, the // premature-exit file will be left undeleted, causing a test runner // that understands the premature-exit-file protocol to report the // test as having failed. const internal::ScopedPrematureExitFile premature_exit_file( in_death_test_child_process ? NULL : internal::posix::GetEnv("TEST_PREMATURE_EXIT_FILE")); // Captures the value of GTEST_FLAG(catch_exceptions). This value will be // used for the duration of the program. impl()->set_catch_exceptions(GTEST_FLAG(catch_exceptions)); #if GTEST_HAS_SEH // Either the user wants Google Test to catch exceptions thrown by the // tests or this is executing in the context of death test child // process. In either case the user does not want to see pop-up dialogs // about crashes - they are expected. if (impl()->catch_exceptions() || in_death_test_child_process) { # if !GTEST_OS_WINDOWS_MOBILE // SetErrorMode doesn't exist on CE. SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOALIGNMENTFAULTEXCEPT | SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX); # endif // !GTEST_OS_WINDOWS_MOBILE # if (defined(_MSC_VER) || GTEST_OS_WINDOWS_MINGW) && !GTEST_OS_WINDOWS_MOBILE // Death test children can be terminated with _abort(). On Windows, // _abort() can show a dialog with a warning message. This forces the // abort message to go to stderr instead. _set_error_mode(_OUT_TO_STDERR); # endif # if _MSC_VER >= 1400 && !GTEST_OS_WINDOWS_MOBILE // In the debug version, Visual Studio pops up a separate dialog // offering a choice to debug the aborted program. We need to suppress // this dialog or it will pop up for every EXPECT/ASSERT_DEATH statement // executed. Google Test will notify the user of any unexpected // failure via stderr. // // VC++ doesn't define _set_abort_behavior() prior to the version 8.0. // Users of prior VC versions shall suffer the agony and pain of // clicking through the countless debug dialogs. // TODO(vladl@google.com): find a way to suppress the abort dialog() in the // debug mode when compiled with VC 7.1 or lower. if (!GTEST_FLAG(break_on_failure)) _set_abort_behavior( 0x0, // Clear the following flags: _WRITE_ABORT_MSG | _CALL_REPORTFAULT); // pop-up window, core dump. # endif } #endif // GTEST_HAS_SEH return internal::HandleExceptionsInMethodIfSupported( impl(), &internal::UnitTestImpl::RunAllTests, "auxiliary test code (environments or event listeners)") ? 0 : 1; } // Returns the working directory when the first TEST() or TEST_F() was // executed. const char* UnitTest::original_working_dir() const { return impl_->original_working_dir_.c_str(); } // Returns the TestCase object for the test that's currently running, // or NULL if no test is running. const TestCase* UnitTest::current_test_case() const GTEST_LOCK_EXCLUDED_(mutex_) { internal::MutexLock lock(&mutex_); return impl_->current_test_case(); } // Returns the TestInfo object for the test that's currently running, // or NULL if no test is running. const TestInfo* UnitTest::current_test_info() const GTEST_LOCK_EXCLUDED_(mutex_) { internal::MutexLock lock(&mutex_); return impl_->current_test_info(); } // Returns the random seed used at the start of the current test run. int UnitTest::random_seed() const { return impl_->random_seed(); } #if GTEST_HAS_PARAM_TEST // Returns ParameterizedTestCaseRegistry object used to keep track of // value-parameterized tests and instantiate and register them. internal::ParameterizedTestCaseRegistry& UnitTest::parameterized_test_registry() GTEST_LOCK_EXCLUDED_(mutex_) { return impl_->parameterized_test_registry(); } #endif // GTEST_HAS_PARAM_TEST // Creates an empty UnitTest. UnitTest::UnitTest() { impl_ = new internal::UnitTestImpl(this); } // Destructor of UnitTest. UnitTest::~UnitTest() { delete impl_; } // Pushes a trace defined by SCOPED_TRACE() on to the per-thread // Google Test trace stack. void UnitTest::PushGTestTrace(const internal::TraceInfo& trace) GTEST_LOCK_EXCLUDED_(mutex_) { internal::MutexLock lock(&mutex_); impl_->gtest_trace_stack().push_back(trace); } // Pops a trace from the per-thread Google Test trace stack. void UnitTest::PopGTestTrace() GTEST_LOCK_EXCLUDED_(mutex_) { internal::MutexLock lock(&mutex_); impl_->gtest_trace_stack().pop_back(); } namespace internal { UnitTestImpl::UnitTestImpl(UnitTest* parent) : parent_(parent), #ifdef _MSC_VER # pragma warning(push) // Saves the current warning state. # pragma warning(disable:4355) // Temporarily disables warning 4355 // (using this in initializer). default_global_test_part_result_reporter_(this), default_per_thread_test_part_result_reporter_(this), # pragma warning(pop) // Restores the warning state again. #else default_global_test_part_result_reporter_(this), default_per_thread_test_part_result_reporter_(this), #endif // _MSC_VER global_test_part_result_repoter_( &default_global_test_part_result_reporter_), per_thread_test_part_result_reporter_( &default_per_thread_test_part_result_reporter_), #if GTEST_HAS_PARAM_TEST parameterized_test_registry_(), parameterized_tests_registered_(false), #endif // GTEST_HAS_PARAM_TEST last_death_test_case_(-1), current_test_case_(NULL), current_test_info_(NULL), ad_hoc_test_result_(), os_stack_trace_getter_(NULL), post_flag_parse_init_performed_(false), random_seed_(0), // Will be overridden by the flag before first use. random_(0), // Will be reseeded before first use. start_timestamp_(0), elapsed_time_(0), #if GTEST_HAS_DEATH_TEST death_test_factory_(new DefaultDeathTestFactory), #endif // Will be overridden by the flag before first use. catch_exceptions_(false) { listeners()->SetDefaultResultPrinter(new PrettyUnitTestResultPrinter); } UnitTestImpl::~UnitTestImpl() { // Deletes every TestCase. ForEach(test_cases_, internal::Delete); // Deletes every Environment. ForEach(environments_, internal::Delete); delete os_stack_trace_getter_; } // Adds a TestProperty to the current TestResult object when invoked in a // context of a test, to current test case's ad_hoc_test_result when invoke // from SetUpTestCase/TearDownTestCase, or to the global property set // otherwise. If the result already contains a property with the same key, // the value will be updated. void UnitTestImpl::RecordProperty(const TestProperty& test_property) { std::string xml_element; TestResult* test_result; // TestResult appropriate for property recording. if (current_test_info_ != NULL) { xml_element = "testcase"; test_result = &(current_test_info_->result_); } else if (current_test_case_ != NULL) { xml_element = "testsuite"; test_result = &(current_test_case_->ad_hoc_test_result_); } else { xml_element = "testsuites"; test_result = &ad_hoc_test_result_; } test_result->RecordProperty(xml_element, test_property); } #if GTEST_HAS_DEATH_TEST // Disables event forwarding if the control is currently in a death test // subprocess. Must not be called before InitGoogleTest. void UnitTestImpl::SuppressTestEventsIfInSubprocess() { if (internal_run_death_test_flag_.get() != NULL) listeners()->SuppressEventForwarding(); } #endif // GTEST_HAS_DEATH_TEST // Initializes event listeners performing XML output as specified by // UnitTestOptions. Must not be called before InitGoogleTest. void UnitTestImpl::ConfigureXmlOutput() { const std::string& output_format = UnitTestOptions::GetOutputFormat(); if (output_format == "xml") { listeners()->SetDefaultXmlGenerator(new XmlUnitTestResultPrinter( UnitTestOptions::GetAbsolutePathToOutputFile().c_str())); } else if (output_format != "") { printf("WARNING: unrecognized output format \"%s\" ignored.\n", output_format.c_str()); fflush(stdout); } } #if GTEST_CAN_STREAM_RESULTS_ // Initializes event listeners for streaming test results in string form. // Must not be called before InitGoogleTest. void UnitTestImpl::ConfigureStreamingOutput() { const std::string& target = GTEST_FLAG(stream_result_to); if (!target.empty()) { const size_t pos = target.find(':'); if (pos != std::string::npos) { listeners()->Append(new StreamingListener(target.substr(0, pos), target.substr(pos+1))); } else { printf("WARNING: unrecognized streaming target \"%s\" ignored.\n", target.c_str()); fflush(stdout); } } } #endif // GTEST_CAN_STREAM_RESULTS_ // Performs initialization dependent upon flag values obtained in // ParseGoogleTestFlagsOnly. Is called from InitGoogleTest after the call to // ParseGoogleTestFlagsOnly. In case a user neglects to call InitGoogleTest // this function is also called from RunAllTests. Since this function can be // called more than once, it has to be idempotent. void UnitTestImpl::PostFlagParsingInit() { // Ensures that this function does not execute more than once. if (!post_flag_parse_init_performed_) { post_flag_parse_init_performed_ = true; #if GTEST_HAS_DEATH_TEST InitDeathTestSubprocessControlInfo(); SuppressTestEventsIfInSubprocess(); #endif // GTEST_HAS_DEATH_TEST // Registers parameterized tests. This makes parameterized tests // available to the UnitTest reflection API without running // RUN_ALL_TESTS. RegisterParameterizedTests(); // Configures listeners for XML output. This makes it possible for users // to shut down the default XML output before invoking RUN_ALL_TESTS. ConfigureXmlOutput(); #if GTEST_CAN_STREAM_RESULTS_ // Configures listeners for streaming test results to the specified server. ConfigureStreamingOutput(); #endif // GTEST_CAN_STREAM_RESULTS_ } } // A predicate that checks the name of a TestCase against a known // value. // // This is used for implementation of the UnitTest class only. We put // it in the anonymous namespace to prevent polluting the outer // namespace. // // TestCaseNameIs is copyable. class TestCaseNameIs { public: // Constructor. explicit TestCaseNameIs(const std::string& name) : name_(name) {} // Returns true iff the name of test_case matches name_. bool operator()(const TestCase* test_case) const { return test_case != NULL && strcmp(test_case->name(), name_.c_str()) == 0; } private: std::string name_; }; // Finds and returns a TestCase with the given name. If one doesn't // exist, creates one and returns it. It's the CALLER'S // RESPONSIBILITY to ensure that this function is only called WHEN THE // TESTS ARE NOT SHUFFLED. // // Arguments: // // test_case_name: name of the test case // type_param: the name of the test case's type parameter, or NULL if // this is not a typed or a type-parameterized test case. // set_up_tc: pointer to the function that sets up the test case // tear_down_tc: pointer to the function that tears down the test case TestCase* UnitTestImpl::GetTestCase(const char* test_case_name, const char* type_param, Test::SetUpTestCaseFunc set_up_tc, Test::TearDownTestCaseFunc tear_down_tc) { // Can we find a TestCase with the given name? const std::vector::const_iterator test_case = std::find_if(test_cases_.begin(), test_cases_.end(), TestCaseNameIs(test_case_name)); if (test_case != test_cases_.end()) return *test_case; // No. Let's create one. TestCase* const new_test_case = new TestCase(test_case_name, type_param, set_up_tc, tear_down_tc); // Is this a death test case? if (internal::UnitTestOptions::MatchesFilter(test_case_name, kDeathTestCaseFilter)) { // Yes. Inserts the test case after the last death test case // defined so far. This only works when the test cases haven't // been shuffled. Otherwise we may end up running a death test // after a non-death test. ++last_death_test_case_; test_cases_.insert(test_cases_.begin() + last_death_test_case_, new_test_case); } else { // No. Appends to the end of the list. test_cases_.push_back(new_test_case); } test_case_indices_.push_back(static_cast(test_case_indices_.size())); return new_test_case; } // Helpers for setting up / tearing down the given environment. They // are for use in the ForEach() function. static void SetUpEnvironment(Environment* env) { env->SetUp(); } static void TearDownEnvironment(Environment* env) { env->TearDown(); } // Runs all tests in this UnitTest object, prints the result, and // returns true if all tests are successful. If any exception is // thrown during a test, the test is considered to be failed, but the // rest of the tests will still be run. // // When parameterized tests are enabled, it expands and registers // parameterized tests first in RegisterParameterizedTests(). // All other functions called from RunAllTests() may safely assume that // parameterized tests are ready to be counted and run. bool UnitTestImpl::RunAllTests() { // Makes sure InitGoogleTest() was called. if (!GTestIsInitialized()) { printf("%s", "\nThis test program did NOT call ::testing::InitGoogleTest " "before calling RUN_ALL_TESTS(). Please fix it.\n"); return false; } // Do not run any test if the --help flag was specified. if (g_help_flag) return true; // Repeats the call to the post-flag parsing initialization in case the // user didn't call InitGoogleTest. PostFlagParsingInit(); // Even if sharding is not on, test runners may want to use the // GTEST_SHARD_STATUS_FILE to query whether the test supports the sharding // protocol. internal::WriteToShardStatusFileIfNeeded(); // True iff we are in a subprocess for running a thread-safe-style // death test. bool in_subprocess_for_death_test = false; #if GTEST_HAS_DEATH_TEST in_subprocess_for_death_test = (internal_run_death_test_flag_.get() != NULL); #endif // GTEST_HAS_DEATH_TEST const bool should_shard = ShouldShard(kTestTotalShards, kTestShardIndex, in_subprocess_for_death_test); // Compares the full test names with the filter to decide which // tests to run. const bool has_tests_to_run = FilterTests(should_shard ? HONOR_SHARDING_PROTOCOL : IGNORE_SHARDING_PROTOCOL) > 0; // Lists the tests and exits if the --gtest_list_tests flag was specified. if (GTEST_FLAG(list_tests)) { // This must be called *after* FilterTests() has been called. ListTestsMatchingFilter(); return true; } random_seed_ = GTEST_FLAG(shuffle) ? GetRandomSeedFromFlag(GTEST_FLAG(random_seed)) : 0; // True iff at least one test has failed. bool failed = false; TestEventListener* repeater = listeners()->repeater(); start_timestamp_ = GetTimeInMillis(); repeater->OnTestProgramStart(*parent_); // How many times to repeat the tests? We don't want to repeat them // when we are inside the subprocess of a death test. const int repeat = in_subprocess_for_death_test ? 1 : GTEST_FLAG(repeat); // Repeats forever if the repeat count is negative. const bool forever = repeat < 0; for (int i = 0; forever || i != repeat; i++) { // We want to preserve failures generated by ad-hoc test // assertions executed before RUN_ALL_TESTS(). ClearNonAdHocTestResult(); const TimeInMillis start = GetTimeInMillis(); // Shuffles test cases and tests if requested. if (has_tests_to_run && GTEST_FLAG(shuffle)) { random()->Reseed(random_seed_); // This should be done before calling OnTestIterationStart(), // such that a test event listener can see the actual test order // in the event. ShuffleTests(); } // Tells the unit test event listeners that the tests are about to start. repeater->OnTestIterationStart(*parent_, i); // Runs each test case if there is at least one test to run. if (has_tests_to_run) { // Sets up all environments beforehand. repeater->OnEnvironmentsSetUpStart(*parent_); ForEach(environments_, SetUpEnvironment); repeater->OnEnvironmentsSetUpEnd(*parent_); // Runs the tests only if there was no fatal failure during global // set-up. if (!Test::HasFatalFailure()) { for (int test_index = 0; test_index < total_test_case_count(); test_index++) { GetMutableTestCase(test_index)->Run(); } } // Tears down all environments in reverse order afterwards. repeater->OnEnvironmentsTearDownStart(*parent_); std::for_each(environments_.rbegin(), environments_.rend(), TearDownEnvironment); repeater->OnEnvironmentsTearDownEnd(*parent_); } elapsed_time_ = GetTimeInMillis() - start; // Tells the unit test event listener that the tests have just finished. repeater->OnTestIterationEnd(*parent_, i); // Gets the result and clears it. if (!Passed()) { failed = true; } // Restores the original test order after the iteration. This // allows the user to quickly repro a failure that happens in the // N-th iteration without repeating the first (N - 1) iterations. // This is not enclosed in "if (GTEST_FLAG(shuffle)) { ... }", in // case the user somehow changes the value of the flag somewhere // (it's always safe to unshuffle the tests). UnshuffleTests(); if (GTEST_FLAG(shuffle)) { // Picks a new random seed for each iteration. random_seed_ = GetNextRandomSeed(random_seed_); } } repeater->OnTestProgramEnd(*parent_); return !failed; } // Reads the GTEST_SHARD_STATUS_FILE environment variable, and creates the file // if the variable is present. If a file already exists at this location, this // function will write over it. If the variable is present, but the file cannot // be created, prints an error and exits. void WriteToShardStatusFileIfNeeded() { const char* const test_shard_file = posix::GetEnv(kTestShardStatusFile); if (test_shard_file != NULL) { FILE* const file = posix::FOpen(test_shard_file, "w"); if (file == NULL) { ColoredPrintf(COLOR_RED, "Could not write to the test shard status file \"%s\" " "specified by the %s environment variable.\n", test_shard_file, kTestShardStatusFile); fflush(stdout); exit(EXIT_FAILURE); } fclose(file); } } // Checks whether sharding is enabled by examining the relevant // environment variable values. If the variables are present, // but inconsistent (i.e., shard_index >= total_shards), prints // an error and exits. If in_subprocess_for_death_test, sharding is // disabled because it must only be applied to the original test // process. Otherwise, we could filter out death tests we intended to execute. bool ShouldShard(const char* total_shards_env, const char* shard_index_env, bool in_subprocess_for_death_test) { if (in_subprocess_for_death_test) { return false; } const Int32 total_shards = Int32FromEnvOrDie(total_shards_env, -1); const Int32 shard_index = Int32FromEnvOrDie(shard_index_env, -1); if (total_shards == -1 && shard_index == -1) { return false; } else if (total_shards == -1 && shard_index != -1) { const Message msg = Message() << "Invalid environment variables: you have " << kTestShardIndex << " = " << shard_index << ", but have left " << kTestTotalShards << " unset.\n"; ColoredPrintf(COLOR_RED, msg.GetString().c_str()); fflush(stdout); exit(EXIT_FAILURE); } else if (total_shards != -1 && shard_index == -1) { const Message msg = Message() << "Invalid environment variables: you have " << kTestTotalShards << " = " << total_shards << ", but have left " << kTestShardIndex << " unset.\n"; ColoredPrintf(COLOR_RED, msg.GetString().c_str()); fflush(stdout); exit(EXIT_FAILURE); } else if (shard_index < 0 || shard_index >= total_shards) { const Message msg = Message() << "Invalid environment variables: we require 0 <= " << kTestShardIndex << " < " << kTestTotalShards << ", but you have " << kTestShardIndex << "=" << shard_index << ", " << kTestTotalShards << "=" << total_shards << ".\n"; ColoredPrintf(COLOR_RED, msg.GetString().c_str()); fflush(stdout); exit(EXIT_FAILURE); } return total_shards > 1; } // Parses the environment variable var as an Int32. If it is unset, // returns default_val. If it is not an Int32, prints an error // and aborts. Int32 Int32FromEnvOrDie(const char* var, Int32 default_val) { const char* str_val = posix::GetEnv(var); if (str_val == NULL) { return default_val; } Int32 result; if (!ParseInt32(Message() << "The value of environment variable " << var, str_val, &result)) { exit(EXIT_FAILURE); } return result; } // Given the total number of shards, the shard index, and the test id, // returns true iff the test should be run on this shard. The test id is // some arbitrary but unique non-negative integer assigned to each test // method. Assumes that 0 <= shard_index < total_shards. bool ShouldRunTestOnShard(int total_shards, int shard_index, int test_id) { return (test_id % total_shards) == shard_index; } // Compares the name of each test with the user-specified filter to // decide whether the test should be run, then records the result in // each TestCase and TestInfo object. // If shard_tests == true, further filters tests based on sharding // variables in the environment - see // http://code.google.com/p/googletest/wiki/GoogleTestAdvancedGuide. // Returns the number of tests that should run. int UnitTestImpl::FilterTests(ReactionToSharding shard_tests) { const Int32 total_shards = shard_tests == HONOR_SHARDING_PROTOCOL ? Int32FromEnvOrDie(kTestTotalShards, -1) : -1; const Int32 shard_index = shard_tests == HONOR_SHARDING_PROTOCOL ? Int32FromEnvOrDie(kTestShardIndex, -1) : -1; // num_runnable_tests are the number of tests that will // run across all shards (i.e., match filter and are not disabled). // num_selected_tests are the number of tests to be run on // this shard. int num_runnable_tests = 0; int num_selected_tests = 0; for (size_t i = 0; i < test_cases_.size(); i++) { TestCase* const test_case = test_cases_[i]; const std::string &test_case_name = test_case->name(); test_case->set_should_run(false); for (size_t j = 0; j < test_case->test_info_list().size(); j++) { TestInfo* const test_info = test_case->test_info_list()[j]; const std::string test_name(test_info->name()); // A test is disabled if test case name or test name matches // kDisableTestFilter. const bool is_disabled = internal::UnitTestOptions::MatchesFilter(test_case_name, kDisableTestFilter) || internal::UnitTestOptions::MatchesFilter(test_name, kDisableTestFilter); test_info->is_disabled_ = is_disabled; const bool matches_filter = internal::UnitTestOptions::FilterMatchesTest(test_case_name, test_name); test_info->matches_filter_ = matches_filter; const bool is_runnable = (GTEST_FLAG(also_run_disabled_tests) || !is_disabled) && matches_filter; const bool is_selected = is_runnable && (shard_tests == IGNORE_SHARDING_PROTOCOL || ShouldRunTestOnShard(total_shards, shard_index, num_runnable_tests)); num_runnable_tests += is_runnable; num_selected_tests += is_selected; test_info->should_run_ = is_selected; test_case->set_should_run(test_case->should_run() || is_selected); } } return num_selected_tests; } // Prints the given C-string on a single line by replacing all '\n' // characters with string "\\n". If the output takes more than // max_length characters, only prints the first max_length characters // and "...". static void PrintOnOneLine(const char* str, int max_length) { if (str != NULL) { for (int i = 0; *str != '\0'; ++str) { if (i >= max_length) { printf("..."); break; } if (*str == '\n') { printf("\\n"); i += 2; } else { printf("%c", *str); ++i; } } } } // Prints the names of the tests matching the user-specified filter flag. void UnitTestImpl::ListTestsMatchingFilter() { // Print at most this many characters for each type/value parameter. const int kMaxParamLength = 250; for (size_t i = 0; i < test_cases_.size(); i++) { const TestCase* const test_case = test_cases_[i]; bool printed_test_case_name = false; for (size_t j = 0; j < test_case->test_info_list().size(); j++) { const TestInfo* const test_info = test_case->test_info_list()[j]; if (test_info->matches_filter_) { if (!printed_test_case_name) { printed_test_case_name = true; printf("%s.", test_case->name()); if (test_case->type_param() != NULL) { printf(" # %s = ", kTypeParamLabel); // We print the type parameter on a single line to make // the output easy to parse by a program. PrintOnOneLine(test_case->type_param(), kMaxParamLength); } printf("\n"); } printf(" %s", test_info->name()); if (test_info->value_param() != NULL) { printf(" # %s = ", kValueParamLabel); // We print the value parameter on a single line to make the // output easy to parse by a program. PrintOnOneLine(test_info->value_param(), kMaxParamLength); } printf("\n"); } } } fflush(stdout); } // Sets the OS stack trace getter. // // Does nothing if the input and the current OS stack trace getter are // the same; otherwise, deletes the old getter and makes the input the // current getter. void UnitTestImpl::set_os_stack_trace_getter( OsStackTraceGetterInterface* getter) { if (os_stack_trace_getter_ != getter) { delete os_stack_trace_getter_; os_stack_trace_getter_ = getter; } } // Returns the current OS stack trace getter if it is not NULL; // otherwise, creates an OsStackTraceGetter, makes it the current // getter, and returns it. OsStackTraceGetterInterface* UnitTestImpl::os_stack_trace_getter() { if (os_stack_trace_getter_ == NULL) { os_stack_trace_getter_ = new OsStackTraceGetter; } return os_stack_trace_getter_; } // Returns the TestResult for the test that's currently running, or // the TestResult for the ad hoc test if no test is running. TestResult* UnitTestImpl::current_test_result() { return current_test_info_ ? &(current_test_info_->result_) : &ad_hoc_test_result_; } // Shuffles all test cases, and the tests within each test case, // making sure that death tests are still run first. void UnitTestImpl::ShuffleTests() { // Shuffles the death test cases. ShuffleRange(random(), 0, last_death_test_case_ + 1, &test_case_indices_); // Shuffles the non-death test cases. ShuffleRange(random(), last_death_test_case_ + 1, static_cast(test_cases_.size()), &test_case_indices_); // Shuffles the tests inside each test case. for (size_t i = 0; i < test_cases_.size(); i++) { test_cases_[i]->ShuffleTests(random()); } } // Restores the test cases and tests to their order before the first shuffle. void UnitTestImpl::UnshuffleTests() { for (size_t i = 0; i < test_cases_.size(); i++) { // Unshuffles the tests in each test case. test_cases_[i]->UnshuffleTests(); // Resets the index of each test case. test_case_indices_[i] = static_cast(i); } } // Returns the current OS stack trace as an std::string. // // The maximum number of stack frames to be included is specified by // the gtest_stack_trace_depth flag. The skip_count parameter // specifies the number of top frames to be skipped, which doesn't // count against the number of frames to be included. // // For example, if Foo() calls Bar(), which in turn calls // GetCurrentOsStackTraceExceptTop(..., 1), Foo() will be included in // the trace but Bar() and GetCurrentOsStackTraceExceptTop() won't. std::string GetCurrentOsStackTraceExceptTop(UnitTest* /*unit_test*/, int skip_count) { // We pass skip_count + 1 to skip this wrapper function in addition // to what the user really wants to skip. return GetUnitTestImpl()->CurrentOsStackTraceExceptTop(skip_count + 1); } // Used by the GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_ macro to // suppress unreachable code warnings. namespace { class ClassUniqueToAlwaysTrue {}; } bool IsTrue(bool condition) { return condition; } bool AlwaysTrue() { #if GTEST_HAS_EXCEPTIONS // This condition is always false so AlwaysTrue() never actually throws, // but it makes the compiler think that it may throw. if (IsTrue(false)) throw ClassUniqueToAlwaysTrue(); #endif // GTEST_HAS_EXCEPTIONS return true; } // If *pstr starts with the given prefix, modifies *pstr to be right // past the prefix and returns true; otherwise leaves *pstr unchanged // and returns false. None of pstr, *pstr, and prefix can be NULL. bool SkipPrefix(const char* prefix, const char** pstr) { const size_t prefix_len = strlen(prefix); if (strncmp(*pstr, prefix, prefix_len) == 0) { *pstr += prefix_len; return true; } return false; } // Parses a string as a command line flag. The string should have // the format "--flag=value". When def_optional is true, the "=value" // part can be omitted. // // Returns the value of the flag, or NULL if the parsing failed. const char* ParseFlagValue(const char* str, const char* flag, bool def_optional) { // str and flag must not be NULL. if (str == NULL || flag == NULL) return NULL; // The flag must start with "--" followed by GTEST_FLAG_PREFIX_. const std::string flag_str = std::string("--") + GTEST_FLAG_PREFIX_ + flag; const size_t flag_len = flag_str.length(); if (strncmp(str, flag_str.c_str(), flag_len) != 0) return NULL; // Skips the flag name. const char* flag_end = str + flag_len; // When def_optional is true, it's OK to not have a "=value" part. if (def_optional && (flag_end[0] == '\0')) { return flag_end; } // If def_optional is true and there are more characters after the // flag name, or if def_optional is false, there must be a '=' after // the flag name. if (flag_end[0] != '=') return NULL; // Returns the string after "=". return flag_end + 1; } // Parses a string for a bool flag, in the form of either // "--flag=value" or "--flag". // // In the former case, the value is taken as true as long as it does // not start with '0', 'f', or 'F'. // // In the latter case, the value is taken as true. // // On success, stores the value of the flag in *value, and returns // true. On failure, returns false without changing *value. bool ParseBoolFlag(const char* str, const char* flag, bool* value) { // Gets the value of the flag as a string. const char* const value_str = ParseFlagValue(str, flag, true); // Aborts if the parsing failed. if (value_str == NULL) return false; // Converts the string value to a bool. *value = !(*value_str == '0' || *value_str == 'f' || *value_str == 'F'); return true; } // Parses a string for an Int32 flag, in the form of // "--flag=value". // // On success, stores the value of the flag in *value, and returns // true. On failure, returns false without changing *value. bool ParseInt32Flag(const char* str, const char* flag, Int32* value) { // Gets the value of the flag as a string. const char* const value_str = ParseFlagValue(str, flag, false); // Aborts if the parsing failed. if (value_str == NULL) return false; // Sets *value to the value of the flag. return ParseInt32(Message() << "The value of flag --" << flag, value_str, value); } // Parses a string for a string flag, in the form of // "--flag=value". // // On success, stores the value of the flag in *value, and returns // true. On failure, returns false without changing *value. bool ParseStringFlag(const char* str, const char* flag, std::string* value) { // Gets the value of the flag as a string. const char* const value_str = ParseFlagValue(str, flag, false); // Aborts if the parsing failed. if (value_str == NULL) return false; // Sets *value to the value of the flag. *value = value_str; return true; } // Determines whether a string has a prefix that Google Test uses for its // flags, i.e., starts with GTEST_FLAG_PREFIX_ or GTEST_FLAG_PREFIX_DASH_. // If Google Test detects that a command line flag has its prefix but is not // recognized, it will print its help message. Flags starting with // GTEST_INTERNAL_PREFIX_ followed by "internal_" are considered Google Test // internal flags and do not trigger the help message. static bool HasGoogleTestFlagPrefix(const char* str) { return (SkipPrefix("--", &str) || SkipPrefix("-", &str) || SkipPrefix("/", &str)) && !SkipPrefix(GTEST_FLAG_PREFIX_ "internal_", &str) && (SkipPrefix(GTEST_FLAG_PREFIX_, &str) || SkipPrefix(GTEST_FLAG_PREFIX_DASH_, &str)); } // Prints a string containing code-encoded text. The following escape // sequences can be used in the string to control the text color: // // @@ prints a single '@' character. // @R changes the color to red. // @G changes the color to green. // @Y changes the color to yellow. // @D changes to the default terminal text color. // // TODO(wan@google.com): Write tests for this once we add stdout // capturing to Google Test. static void PrintColorEncoded(const char* str) { GTestColor color = COLOR_DEFAULT; // The current color. // Conceptually, we split the string into segments divided by escape // sequences. Then we print one segment at a time. At the end of // each iteration, the str pointer advances to the beginning of the // next segment. for (;;) { const char* p = strchr(str, '@'); if (p == NULL) { ColoredPrintf(color, "%s", str); return; } ColoredPrintf(color, "%s", std::string(str, p).c_str()); const char ch = p[1]; str = p + 2; if (ch == '@') { ColoredPrintf(color, "@"); } else if (ch == 'D') { color = COLOR_DEFAULT; } else if (ch == 'R') { color = COLOR_RED; } else if (ch == 'G') { color = COLOR_GREEN; } else if (ch == 'Y') { color = COLOR_YELLOW; } else { --str; } } } static const char kColorEncodedHelpMessage[] = "This program contains tests written using " GTEST_NAME_ ". You can use the\n" "following command line flags to control its behavior:\n" "\n" "Test Selection:\n" " @G--" GTEST_FLAG_PREFIX_ "list_tests@D\n" " List the names of all tests instead of running them. The name of\n" " TEST(Foo, Bar) is \"Foo.Bar\".\n" " @G--" GTEST_FLAG_PREFIX_ "filter=@YPOSTIVE_PATTERNS" "[@G-@YNEGATIVE_PATTERNS]@D\n" " Run only the tests whose name matches one of the positive patterns but\n" " none of the negative patterns. '?' matches any single character; '*'\n" " matches any substring; ':' separates two patterns.\n" " @G--" GTEST_FLAG_PREFIX_ "also_run_disabled_tests@D\n" " Run all disabled tests too.\n" "\n" "Test Execution:\n" " @G--" GTEST_FLAG_PREFIX_ "repeat=@Y[COUNT]@D\n" " Run the tests repeatedly; use a negative count to repeat forever.\n" " @G--" GTEST_FLAG_PREFIX_ "shuffle@D\n" " Randomize tests' orders on every iteration.\n" " @G--" GTEST_FLAG_PREFIX_ "random_seed=@Y[NUMBER]@D\n" " Random number seed to use for shuffling test orders (between 1 and\n" " 99999, or 0 to use a seed based on the current time).\n" "\n" "Test Output:\n" " @G--" GTEST_FLAG_PREFIX_ "color=@Y(@Gyes@Y|@Gno@Y|@Gauto@Y)@D\n" " Enable/disable colored output. The default is @Gauto@D.\n" " -@G-" GTEST_FLAG_PREFIX_ "print_time=0@D\n" " Don't print the elapsed time of each test.\n" " @G--" GTEST_FLAG_PREFIX_ "output=xml@Y[@G:@YDIRECTORY_PATH@G" GTEST_PATH_SEP_ "@Y|@G:@YFILE_PATH]@D\n" " Generate an XML report in the given directory or with the given file\n" " name. @YFILE_PATH@D defaults to @Gtest_details.xml@D.\n" #if GTEST_CAN_STREAM_RESULTS_ " @G--" GTEST_FLAG_PREFIX_ "stream_result_to=@YHOST@G:@YPORT@D\n" " Stream test results to the given server.\n" #endif // GTEST_CAN_STREAM_RESULTS_ "\n" "Assertion Behavior:\n" #if GTEST_HAS_DEATH_TEST && !GTEST_OS_WINDOWS " @G--" GTEST_FLAG_PREFIX_ "death_test_style=@Y(@Gfast@Y|@Gthreadsafe@Y)@D\n" " Set the default death test style.\n" #endif // GTEST_HAS_DEATH_TEST && !GTEST_OS_WINDOWS " @G--" GTEST_FLAG_PREFIX_ "break_on_failure@D\n" " Turn assertion failures into debugger break-points.\n" " @G--" GTEST_FLAG_PREFIX_ "throw_on_failure@D\n" " Turn assertion failures into C++ exceptions.\n" " @G--" GTEST_FLAG_PREFIX_ "catch_exceptions=0@D\n" " Do not report exceptions as test failures. Instead, allow them\n" " to crash the program or throw a pop-up (on Windows).\n" "\n" "Except for @G--" GTEST_FLAG_PREFIX_ "list_tests@D, you can alternatively set " "the corresponding\n" "environment variable of a flag (all letters in upper-case). For example, to\n" "disable colored text output, you can either specify @G--" GTEST_FLAG_PREFIX_ "color=no@D or set\n" "the @G" GTEST_FLAG_PREFIX_UPPER_ "COLOR@D environment variable to @Gno@D.\n" "\n" "For more information, please read the " GTEST_NAME_ " documentation at\n" "@G" GTEST_PROJECT_URL_ "@D. If you find a bug in " GTEST_NAME_ "\n" "(not one in your own code or tests), please report it to\n" "@G<" GTEST_DEV_EMAIL_ ">@D.\n"; // Parses the command line for Google Test flags, without initializing // other parts of Google Test. The type parameter CharType can be // instantiated to either char or wchar_t. template void ParseGoogleTestFlagsOnlyImpl(int* argc, CharType** argv) { for (int i = 1; i < *argc; i++) { const std::string arg_string = StreamableToString(argv[i]); const char* const arg = arg_string.c_str(); using internal::ParseBoolFlag; using internal::ParseInt32Flag; using internal::ParseStringFlag; // Do we see a Google Test flag? if (ParseBoolFlag(arg, kAlsoRunDisabledTestsFlag, >EST_FLAG(also_run_disabled_tests)) || ParseBoolFlag(arg, kBreakOnFailureFlag, >EST_FLAG(break_on_failure)) || ParseBoolFlag(arg, kCatchExceptionsFlag, >EST_FLAG(catch_exceptions)) || ParseStringFlag(arg, kColorFlag, >EST_FLAG(color)) || ParseStringFlag(arg, kDeathTestStyleFlag, >EST_FLAG(death_test_style)) || ParseBoolFlag(arg, kDeathTestUseFork, >EST_FLAG(death_test_use_fork)) || ParseStringFlag(arg, kFilterFlag, >EST_FLAG(filter)) || ParseStringFlag(arg, kInternalRunDeathTestFlag, >EST_FLAG(internal_run_death_test)) || ParseBoolFlag(arg, kListTestsFlag, >EST_FLAG(list_tests)) || ParseStringFlag(arg, kOutputFlag, >EST_FLAG(output)) || ParseBoolFlag(arg, kPrintTimeFlag, >EST_FLAG(print_time)) || ParseInt32Flag(arg, kRandomSeedFlag, >EST_FLAG(random_seed)) || ParseInt32Flag(arg, kRepeatFlag, >EST_FLAG(repeat)) || ParseBoolFlag(arg, kShuffleFlag, >EST_FLAG(shuffle)) || ParseInt32Flag(arg, kStackTraceDepthFlag, >EST_FLAG(stack_trace_depth)) || ParseStringFlag(arg, kStreamResultToFlag, >EST_FLAG(stream_result_to)) || ParseBoolFlag(arg, kThrowOnFailureFlag, >EST_FLAG(throw_on_failure)) ) { // Yes. Shift the remainder of the argv list left by one. Note // that argv has (*argc + 1) elements, the last one always being // NULL. The following loop moves the trailing NULL element as // well. for (int j = i; j != *argc; j++) { argv[j] = argv[j + 1]; } // Decrements the argument count. (*argc)--; // We also need to decrement the iterator as we just removed // an element. i--; } else if (arg_string == "--help" || arg_string == "-h" || arg_string == "-?" || arg_string == "/?" || HasGoogleTestFlagPrefix(arg)) { // Both help flag and unrecognized Google Test flags (excluding // internal ones) trigger help display. g_help_flag = true; } } if (g_help_flag) { // We print the help here instead of in RUN_ALL_TESTS(), as the // latter may not be called at all if the user is using Google // Test with another testing framework. PrintColorEncoded(kColorEncodedHelpMessage); } } // Parses the command line for Google Test flags, without initializing // other parts of Google Test. void ParseGoogleTestFlagsOnly(int* argc, char** argv) { ParseGoogleTestFlagsOnlyImpl(argc, argv); } void ParseGoogleTestFlagsOnly(int* argc, wchar_t** argv) { ParseGoogleTestFlagsOnlyImpl(argc, argv); } // The internal implementation of InitGoogleTest(). // // The type parameter CharType can be instantiated to either char or // wchar_t. template void InitGoogleTestImpl(int* argc, CharType** argv) { g_init_gtest_count++; // We don't want to run the initialization code twice. if (g_init_gtest_count != 1) return; if (*argc <= 0) return; internal::g_executable_path = internal::StreamableToString(argv[0]); #if GTEST_HAS_DEATH_TEST g_argvs.clear(); for (int i = 0; i != *argc; i++) { g_argvs.push_back(StreamableToString(argv[i])); } #endif // GTEST_HAS_DEATH_TEST ParseGoogleTestFlagsOnly(argc, argv); GetUnitTestImpl()->PostFlagParsingInit(); } } // namespace internal // Initializes Google Test. This must be called before calling // RUN_ALL_TESTS(). In particular, it parses a command line for the // flags that Google Test recognizes. Whenever a Google Test flag is // seen, it is removed from argv, and *argc is decremented. // // No value is returned. Instead, the Google Test flag variables are // updated. // // Calling the function for the second time has no user-visible effect. void InitGoogleTest(int* argc, char** argv) { internal::InitGoogleTestImpl(argc, argv); } // This overloaded version can be used in Windows programs compiled in // UNICODE mode. void InitGoogleTest(int* argc, wchar_t** argv) { internal::InitGoogleTestImpl(argc, argv); } } // namespace testing dlt-daemon-2.18.4/gtest-1.7.0/src/gtest_main.cc000066400000000000000000000033451353342203500206560ustar00rootroot00000000000000// Copyright 2006, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include "gtest/gtest.h" GTEST_API_ int main(int argc, char **argv) { printf("Running main() from gtest_main.cc\n"); testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } dlt-daemon-2.18.4/gtest-1.7.0/src/gtest_main.lo000066400000000000000000000004641353342203500207020ustar00rootroot00000000000000# src/gtest_main.lo - a libtool object file # Generated by libtool (GNU libtool) 2.4.2 Debian-2.4.2-1ubuntu1 # # Please DO NOT delete this file! # It is necessary for linking the library. # Name of the PIC object. pic_object='.libs/gtest_main.o' # Name of the non-PIC object non_pic_object='gtest_main.o' dlt-daemon-2.18.4/gtest-1.7.0/src/gtest_main.o000066400000000000000000000501541353342203500205270ustar00rootroot00000000000000ELF;4(Running main() from gtest_main.ccL$qUVSQ˃qhXZVS PeY[^]aÍh hhhPW| 0Kn (eint' 7l`z_ 8e4 n     n $ ( , 0  4  e8 _e< @ >D LF nG p H %L " .T ) /X 0 0\ 7 1` > 2%d d4eh 6l@ S!  Vn X0 \Te]O  ^Cp (| e  !''std"  @[  O  f  |        6  R  h  t      &  <  ]  y       4 O o          $ O j      % ; [ { ɛ ʻ    & D c    0/    e  (17eq N ' J77lt ' g77 ne== = ==7 R CC= ICC=  C5Ca ~OI n7 $?' IIeof ( b ,I 0 5O 6| 7r e3nPW v A|9JA  K g[ Yg _  K[>8 [ Z  = ' !;A"#N""e$s %> tZ&dect%Vt&hex t%t%t &octt@% t' t'H "t' &t')t'8,t'/t '3t@%6t%9tJ'<t(*J% N o %Q %V %fY (# in&appl  &ateo % t &inw &outz %p}  (,&beg9  &cur9 &end9 RSTO \e3hMib ) * tr1* +,;- . / 012. 2_Tp  3> 4J' 9 e ~  5Ta0 j6 O | e6Q O  86   e 3 6O 3  6t  e    3 6)Ke  e6Re6   76{eR   76!O h  8n O 6 % !% [ 6 m%  !% 6> ie   [ 6%   % !6O & 3  6O < 3 6\e]  % 76jey   76k O O  6xde   6e   6:qe  % 6e  6 le4 6eO 6r%o3  9    9e  9, e  9   9%  6W% % !:tm,eyehee e6 eee#e $!(6% 9    %9e  %9A $  %6 %II%  6&%j  6jA   6:  6   6 e6E e9^%%  %6e;O 6NEe[  %6 I {  %6N   %6R  3 %6Ye 762e 7;  3 qq &  ;Y Y D 3 11 c  F <F  3 %<    $,- 71:. 1;. 1_ ?" 1@. ) e7B1:1;1_ ?" 1@. ) E71:'1;'1_ ?" 1@. ) 0%71:w1;w1_ ?" 1@. ) S6H  6l e6 s e<71=8>>((>O85|9&:)@ F GIHI JK L$M( N)#P*R+T,fV-]. ^/a0kc1/e2 g3n4^o59|e!?OSeT{ U&eU&eV"eJ:W"eW "X+%'Y3 Y<Y"ZY+FZEP(y[S!&\]^]Ytq_ _ _` a:da2b cccd c ezxf g-4 gYei~h-g g+#ieq!j\e% U: ; I$ > $ >   I : ;  : ; I8 : ;I8  : ; n  : ;  : ; I I!I/  I: ; &I9: ; : ; : ;9: ; .?: ; n<I.?: ; nI<.?: ;nI<.?: ;nI<.?: ;nI< : ; ( < : ;2  : ;I?<!.?: ;2 <d"I4#.?: ;2 <d$: ; I2 % : ;I?2 < & : ;I?2 < ' : ;I?2 <(: ;I2 )/I*/I+ : ; , : ;-9.4: ;I</:: ;0 : ; 1 : ; I?<2/I34: ; nI?<44: ; I<5: ;I6.?: ;I<78.?: ;I<9.?: ; I<: : ; ;.?: ; nI<<9: ; =:: ; > I?.?: ; I<@ : ; nA : ; B I8 CD&E9: ;F : ;G : ;I8 2 H.?: ;n2 <dI.?: ;n2 <dJ : ;I?2 <K.?: ;nI<L4: ;I<M4: ; I<N4: ; I< O.?: ;nI2 <P.?: ;nI2 <dQ.?: ;n<R: ;S.?: ;I T.4 U: ; IV.?: ; I@BW: ; IX1X Y Y1Z.4@B[1X Y \1 ]1^_4: ; I?<`4I?4<a4G b4Gc4Gd4Ge4Gn f4Gng4Gn h4Gni.?nI4<j.?I4<$JP(JPxR src./include/gtest/usr/include/c++/4.9.2/usr/lib/gcc/i686-redhat-linux/4.9.2/include/usr/include/bits/usr/include/usr/include/c++/4.9.2/bits/usr/include/c++/4.9.2/i686-redhat-linux/bits/usr/include/c++/4.9.2/tr1/usr/include/c++/4.9.2/debug/usr/include/c++/4.9.2/ext./include/gtest/internalgtest_main.ccgtest.hiostreamstddef.htypes.hlibio.hstdio.hwchar.hstdarg.hcwcharchar_traits.hc++config.hclocaleios_base.hcwctypetuple iosfwdtime.hdebug.h predefined_ops.hnew_allocator.h numeric_traits.h locale.hpthreadtypes.hatomic_word.hwctype.hgtest-port.h gtest-internal.h gtest-death-test-internal.h gtest-linked_ptr.h gtest-printers.hcxxabi.h!J=n<$<\long int__debugint_p_cs_precedes_ZN7testing8internal21ImplicitlyConvertibleIPKvS3_E5valueEwcsxfrmgoodbit_shortbufvfwprintf_IO_lock_tUnitTeststderrGetInstanceRUN_ALL_TESTStm_ydayLock_ZNSt11char_traitsIcE11to_int_typeERKc_S_atepthread_tchar_type_S_uppercasevfwscanfeofbitp_cs_precedestowctrans_Swallow_assignunsigned int_ZN7testing8internal18g_linked_ptr_mutexE__gnu_cxx_S_fixed_S_floatfieldtuple_size >_flags__int32_t_cur_columnwchar_t_S_refcounttestingvwscanf_old_offset_markerstm_mday_ZNSt11char_traitsIcE2ltERKcS2_MakeFrommon_decimal_point_S_ios_iostate_end_IO_buf_end_ZN9__gnu_cxx24__numeric_traits_integerIiE5__minE__opswcscpy_ZN7testing8UnitTest11GetInstanceEvBiggestInt_ZNSt11char_traitsIcE7not_eofERKiwcscatlconvdecimal_point__numeric_traits_integer__pthread_slist_tAssertHeldn_sep_by_spaceg_linked_ptr_mutexcopy__gnu_debugfwscanftm_wday_poswcsncmpp_sep_by_spacetm_mon_IO_save_end__count__numeric_traits_integerinternal2floatignore__elisiongetwclong long unsigned int_S_endhas_owner__S_dec_S_hexint_n_sign_posn_IO_read_base_S_scientificunitbuflocaleconv__FILE__owneradjustfield_offsetto_int_type_ZNK7testing8internal9MutexBase10AssertHeldEvwcrtomb_ZN7testing8internal9MutexBase6UnlockEviostatevalue_S_ios_seekdir_end_S_failbitfixed__cxa_atexitHelper__gnuc_va_listp_sign_posn__initialize_pputsuppercasetuple<>Initsize_tmovefloatfieldshowposputwccerrputwchar_Ios_Seekdir__priority__lockargcstdin_nextint_frac_digitsfwideint_n_cs_precedes_S_right_S_showpointGNU C++ 4.9.2 20150212 (Red Hat 4.9.2-6) -mtune=generic -march=i686 -g -O2findbasic_ostream >negative_sign__elision_data_ZN7testing14InitGoogleTestEPiPPc__valuefputwc__nextgroupingwscanf_S_showbase_GLOBAL__sub_I_main_S_inchar_modeswscanfptrdiff_t_IO_markerint_type_IO_write_basewctype_S_adjustfield__max__wch_S_boolalpha__builtin_putsmbsrtowcs_S_begwcstoulwctrans_tfwprintfrightpthread_mutex_twcstofwcsspn_ZN9__gnu_cxx24__numeric_traits_integerIsE5__maxE_S_ios_openmode_end_Atomic_word__listlong long intlength_S_eofbit_ZN7testing8internal21ImplicitlyConvertibleIPKvS3_E6HelperEz_IO_save_base_S_oct_S_badbitmon_groupingUnlock_ZNSt11char_traitsIcE6assignERcRKcboolboolalphashowbasefgetwc_ZN7testing8internal21ImplicitlyConvertibleIPKvS3_E6HelperES3_fgetws_S_basefield__quad_tbadbitcomparestdout_IO_backup_base_S_goodbit__dso_handle_ZNSt11char_traitsIcE6assignEPcjc__kindassign__pad1__pad2__pad3__pad4__pad5kInternalRunDeathTestFlag__is_signedungetwcfmtflagssrc/gtest_main.cc_Value_Ios_Iostatewctype_t_vtable_offset_ZSt4cerr_ZN9__gnu_cxx24__numeric_traits_integerIiE5__maxE__mbstate_t_Traitsargvlong doublewcsncatopenmodewcscoll__espins_S_synced_with_stdio_ZNSt11char_traitsIcE4moveEPcPKcjfputws__static_initialization_and_destruction_0/home/user/projects/ascgit/ascgit003.dlt-daemon/build/gtest-1.7.0ios_basebtowcvwprintfFromkMaxStackTraceDepthmbrtowc_IO_read_endiswctypetm_yearmbsinitwmemchr_ZNSt11char_traitsIcE2eqERKcS2_short int_ZN7testing8UnitTest3RunEvmutex__ZNSt11char_traitsIcE3eofEv_CharTwcsrtombsint_curr_symbolkMaxBiggestIntwcstoullfrac_digitsmbrlenwmemcpyscientificn_sign_posn11__mbstate_tchar_traits_S_skipws_Ios_Openmodewcsrchrto_char_typegetwchar__cxxabiv1_IO_write_end_S_internal__wchbint_n_sep_by_space__numeric_traits_integerinternal_run_death_testshowpointbinary_S_binleftmbstate_twcsftimepositive_sign__datawcsstrskipws_ZNSt11char_traitsIcE11eq_int_typeERKiS2_owner__lock_S_left_ZNSt11char_traitsIcE12to_char_typeERKiwmemmove_Ios_Fmtflags__nuserswprintfdeath_test_use_forksizetypelong unsigned int~Init_S_trunc_IO_FILE_ZN7testing8internal21ImplicitlyConvertibleIPKvS3_E8MakeFromEvwint_t_S_appnot_eofwcstodwcspbrktm_minfailbitwcstokwcstoltm_zonewmemset_S_ios_fmtflags_endsetlocale_ZNSt11char_traitsIcE6lengthEPKcunsigned char_sbufMutexBaseinternal_IO_write_ptreq_int_typethousands_sep_ZN9__gnu_cxx24__numeric_traits_integerImE8__digitsE_ZN9__gnu_cxx24__numeric_traits_integerIsE5__minEostreamwcstoldwctob_ZNSt11char_traitsIcE4findEPKcjRS1_death_test_stylecurrency_symbolwcstoll__minswprintf_fileno_ZN9__gnu_cxx24__numeric_traits_integerIcE5__maxE15pthread_mutex_t__size__off_ttm_hourtrunckDeathTestStyleFlagsigned charmon_thousands_sepInitGoogleTestbasefieldshort unsigned int__digitstm_sec_S_unitbufmainwcscspn__builtin_va_list_S_curn_cs_precedestm_isdstseekdir_IO_read_ptrwcsncpy_ZNSt11char_traitsIcE4copyEPcPKcjint_p_sep_by_spacedoublevswscanfwcscmp_ZN7testing8internal9MutexBase4LockEvtm_gmtoff__pthread_internal_slist__align_chainwcschr__numeric_traits_integerkDeathTestUseForkwctransvswprintfkProtobufOneLinerMaxLength_flags2_S_out_ZNSt11char_traitsIcE7compareEPKcS2_jint_p_sign_posn_S_showposImplicitlyConvertiblewcslen__off64_t__ioinit_unused2_IO_buf_base_ZNSt3tr110tuple_sizeINS_5tupleIIEEEE5valueE__pthread_mutex_swmemcmpGCC: (GNU) 4.9.2 20150212 (Red Hat 4.9.2-6)zR| 8JD GuEutu|uxs AAAC $XP(CE HEEE H.symtab.strtab.shstrtab.text.data.bss.rodata.str1.4.text.unlikely.rel.text.startup.rel.init_array.rel.debug_info.debug_abbrev.rel.debug_aranges.rel.debug_ranges.rel.debug_line.debug_str.comment.note.GNU-stack.rel.eh_frame4!4'4,24";VN`xJ BX`\ Cpl C  |g@"( P h" 4P "V TP0%V0,:-Y:\:| \P:@ AP(#   2J7<^gtest_main.cc_GLOBAL__sub_I_main_ZStL8__ioinitmainputs_ZN7testing14InitGoogleTestEPiPPc_ZN7testing8UnitTest11GetInstanceEv_ZN7testing8UnitTest3RunEv_ZNSt8ios_base4InitC1Ev__dso_handle_ZNSt8ios_base4InitD1Ev__cxa_atexit'/8TYafkp !&3:AHOV[ov{ '4AN[hu+9GXco{3Pho6=U\ov %,3:AIQX_fo{+B[g  ' 6 E S a p }                    * 6 = D K P \ g }      7 S i u     ' = ^ z     5Pp-9EQ]iu%Pk&<\|'-ELdk #.9COZep{P\ht(4@LXdp})5AMYex4Nc} ,9@IPcjy&;GNk(1;?Rjoz $.:EO[_r  , \dlt-daemon-2.18.4/gtest-1.7.0/test/000077500000000000000000000000001353342203500164005ustar00rootroot00000000000000dlt-daemon-2.18.4/gtest-1.7.0/test/.deps/000077500000000000000000000000001353342203500174115ustar00rootroot00000000000000dlt-daemon-2.18.4/gtest-1.7.0/test/.deps/gtest_all_test.Po000066400000000000000000000000101353342203500227150ustar00rootroot00000000000000# dummy dlt-daemon-2.18.4/gtest-1.7.0/test/gtest-death-test_ex_test.cc000066400000000000000000000071371353342203500236400ustar00rootroot00000000000000// Copyright 2010, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: vladl@google.com (Vlad Losev) // // Tests that verify interaction of exceptions and death tests. #include "gtest/gtest-death-test.h" #include "gtest/gtest.h" #if GTEST_HAS_DEATH_TEST # if GTEST_HAS_SEH # include // For RaiseException(). # endif # include "gtest/gtest-spi.h" # if GTEST_HAS_EXCEPTIONS # include // For std::exception. // Tests that death tests report thrown exceptions as failures and that the // exceptions do not escape death test macros. TEST(CxxExceptionDeathTest, ExceptionIsFailure) { try { EXPECT_NONFATAL_FAILURE(EXPECT_DEATH(throw 1, ""), "threw an exception"); } catch (...) { // NOLINT FAIL() << "An exception escaped a death test macro invocation " << "with catch_exceptions " << (testing::GTEST_FLAG(catch_exceptions) ? "enabled" : "disabled"); } } class TestException : public std::exception { public: virtual const char* what() const throw() { return "exceptional message"; } }; TEST(CxxExceptionDeathTest, PrintsMessageForStdExceptions) { // Verifies that the exception message is quoted in the failure text. EXPECT_NONFATAL_FAILURE(EXPECT_DEATH(throw TestException(), ""), "exceptional message"); // Verifies that the location is mentioned in the failure text. EXPECT_NONFATAL_FAILURE(EXPECT_DEATH(throw TestException(), ""), "gtest-death-test_ex_test.cc"); } # endif // GTEST_HAS_EXCEPTIONS # if GTEST_HAS_SEH // Tests that enabling interception of SEH exceptions with the // catch_exceptions flag does not interfere with SEH exceptions being // treated as death by death tests. TEST(SehExceptionDeasTest, CatchExceptionsDoesNotInterfere) { EXPECT_DEATH(RaiseException(42, 0x0, 0, NULL), "") << "with catch_exceptions " << (testing::GTEST_FLAG(catch_exceptions) ? "enabled" : "disabled"); } # endif #endif // GTEST_HAS_DEATH_TEST int main(int argc, char** argv) { testing::InitGoogleTest(&argc, argv); testing::GTEST_FLAG(catch_exceptions) = GTEST_ENABLE_CATCH_EXCEPTIONS_ != 0; return RUN_ALL_TESTS(); } dlt-daemon-2.18.4/gtest-1.7.0/test/gtest-death-test_test.cc000066400000000000000000001243441353342203500231440ustar00rootroot00000000000000// Copyright 2005, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: wan@google.com (Zhanyong Wan) // // Tests for death tests. #include "gtest/gtest-death-test.h" #include "gtest/gtest.h" #include "gtest/internal/gtest-filepath.h" using testing::internal::AlwaysFalse; using testing::internal::AlwaysTrue; #if GTEST_HAS_DEATH_TEST # if GTEST_OS_WINDOWS # include // For chdir(). # else # include # include // For waitpid. # endif // GTEST_OS_WINDOWS # include # include # include # if GTEST_OS_LINUX # include # endif // GTEST_OS_LINUX # include "gtest/gtest-spi.h" // Indicates that this translation unit is part of Google Test's // implementation. It must come before gtest-internal-inl.h is // included, or there will be a compiler error. This trick is to // prevent a user from accidentally including gtest-internal-inl.h in // his code. # define GTEST_IMPLEMENTATION_ 1 # include "src/gtest-internal-inl.h" # undef GTEST_IMPLEMENTATION_ namespace posix = ::testing::internal::posix; using testing::Message; using testing::internal::DeathTest; using testing::internal::DeathTestFactory; using testing::internal::FilePath; using testing::internal::GetLastErrnoDescription; using testing::internal::GetUnitTestImpl; using testing::internal::InDeathTestChild; using testing::internal::ParseNaturalNumber; namespace testing { namespace internal { // A helper class whose objects replace the death test factory for a // single UnitTest object during their lifetimes. class ReplaceDeathTestFactory { public: explicit ReplaceDeathTestFactory(DeathTestFactory* new_factory) : unit_test_impl_(GetUnitTestImpl()) { old_factory_ = unit_test_impl_->death_test_factory_.release(); unit_test_impl_->death_test_factory_.reset(new_factory); } ~ReplaceDeathTestFactory() { unit_test_impl_->death_test_factory_.release(); unit_test_impl_->death_test_factory_.reset(old_factory_); } private: // Prevents copying ReplaceDeathTestFactory objects. ReplaceDeathTestFactory(const ReplaceDeathTestFactory&); void operator=(const ReplaceDeathTestFactory&); UnitTestImpl* unit_test_impl_; DeathTestFactory* old_factory_; }; } // namespace internal } // namespace testing void DieWithMessage(const ::std::string& message) { fprintf(stderr, "%s", message.c_str()); fflush(stderr); // Make sure the text is printed before the process exits. // We call _exit() instead of exit(), as the former is a direct // system call and thus safer in the presence of threads. exit() // will invoke user-defined exit-hooks, which may do dangerous // things that conflict with death tests. // // Some compilers can recognize that _exit() never returns and issue the // 'unreachable code' warning for code following this function, unless // fooled by a fake condition. if (AlwaysTrue()) _exit(1); } void DieInside(const ::std::string& function) { DieWithMessage("death inside " + function + "()."); } // Tests that death tests work. class TestForDeathTest : public testing::Test { protected: TestForDeathTest() : original_dir_(FilePath::GetCurrentDir()) {} virtual ~TestForDeathTest() { posix::ChDir(original_dir_.c_str()); } // A static member function that's expected to die. static void StaticMemberFunction() { DieInside("StaticMemberFunction"); } // A method of the test fixture that may die. void MemberFunction() { if (should_die_) DieInside("MemberFunction"); } // True iff MemberFunction() should die. bool should_die_; const FilePath original_dir_; }; // A class with a member function that may die. class MayDie { public: explicit MayDie(bool should_die) : should_die_(should_die) {} // A member function that may die. void MemberFunction() const { if (should_die_) DieInside("MayDie::MemberFunction"); } private: // True iff MemberFunction() should die. bool should_die_; }; // A global function that's expected to die. void GlobalFunction() { DieInside("GlobalFunction"); } // A non-void function that's expected to die. int NonVoidFunction() { DieInside("NonVoidFunction"); return 1; } // A unary function that may die. void DieIf(bool should_die) { if (should_die) DieInside("DieIf"); } // A binary function that may die. bool DieIfLessThan(int x, int y) { if (x < y) { DieInside("DieIfLessThan"); } return true; } // Tests that ASSERT_DEATH can be used outside a TEST, TEST_F, or test fixture. void DeathTestSubroutine() { EXPECT_DEATH(GlobalFunction(), "death.*GlobalFunction"); ASSERT_DEATH(GlobalFunction(), "death.*GlobalFunction"); } // Death in dbg, not opt. int DieInDebugElse12(int* sideeffect) { if (sideeffect) *sideeffect = 12; # ifndef NDEBUG DieInside("DieInDebugElse12"); # endif // NDEBUG return 12; } # if GTEST_OS_WINDOWS // Tests the ExitedWithCode predicate. TEST(ExitStatusPredicateTest, ExitedWithCode) { // On Windows, the process's exit code is the same as its exit status, // so the predicate just compares the its input with its parameter. EXPECT_TRUE(testing::ExitedWithCode(0)(0)); EXPECT_TRUE(testing::ExitedWithCode(1)(1)); EXPECT_TRUE(testing::ExitedWithCode(42)(42)); EXPECT_FALSE(testing::ExitedWithCode(0)(1)); EXPECT_FALSE(testing::ExitedWithCode(1)(0)); } # else // Returns the exit status of a process that calls _exit(2) with a // given exit code. This is a helper function for the // ExitStatusPredicateTest test suite. static int NormalExitStatus(int exit_code) { pid_t child_pid = fork(); if (child_pid == 0) { _exit(exit_code); } int status; waitpid(child_pid, &status, 0); return status; } // Returns the exit status of a process that raises a given signal. // If the signal does not cause the process to die, then it returns // instead the exit status of a process that exits normally with exit // code 1. This is a helper function for the ExitStatusPredicateTest // test suite. static int KilledExitStatus(int signum) { pid_t child_pid = fork(); if (child_pid == 0) { raise(signum); _exit(1); } int status; waitpid(child_pid, &status, 0); return status; } // Tests the ExitedWithCode predicate. TEST(ExitStatusPredicateTest, ExitedWithCode) { const int status0 = NormalExitStatus(0); const int status1 = NormalExitStatus(1); const int status42 = NormalExitStatus(42); const testing::ExitedWithCode pred0(0); const testing::ExitedWithCode pred1(1); const testing::ExitedWithCode pred42(42); EXPECT_PRED1(pred0, status0); EXPECT_PRED1(pred1, status1); EXPECT_PRED1(pred42, status42); EXPECT_FALSE(pred0(status1)); EXPECT_FALSE(pred42(status0)); EXPECT_FALSE(pred1(status42)); } // Tests the KilledBySignal predicate. TEST(ExitStatusPredicateTest, KilledBySignal) { const int status_segv = KilledExitStatus(SIGSEGV); const int status_kill = KilledExitStatus(SIGKILL); const testing::KilledBySignal pred_segv(SIGSEGV); const testing::KilledBySignal pred_kill(SIGKILL); EXPECT_PRED1(pred_segv, status_segv); EXPECT_PRED1(pred_kill, status_kill); EXPECT_FALSE(pred_segv(status_kill)); EXPECT_FALSE(pred_kill(status_segv)); } # endif // GTEST_OS_WINDOWS // Tests that the death test macros expand to code which may or may not // be followed by operator<<, and that in either case the complete text // comprises only a single C++ statement. TEST_F(TestForDeathTest, SingleStatement) { if (AlwaysFalse()) // This would fail if executed; this is a compilation test only ASSERT_DEATH(return, ""); if (AlwaysTrue()) EXPECT_DEATH(_exit(1), ""); else // This empty "else" branch is meant to ensure that EXPECT_DEATH // doesn't expand into an "if" statement without an "else" ; if (AlwaysFalse()) ASSERT_DEATH(return, "") << "did not die"; if (AlwaysFalse()) ; else EXPECT_DEATH(_exit(1), "") << 1 << 2 << 3; } void DieWithEmbeddedNul() { fprintf(stderr, "Hello%cmy null world.\n", '\0'); fflush(stderr); _exit(1); } # if GTEST_USES_PCRE // Tests that EXPECT_DEATH and ASSERT_DEATH work when the error // message has a NUL character in it. TEST_F(TestForDeathTest, EmbeddedNulInMessage) { // TODO(wan@google.com): doesn't support matching strings // with embedded NUL characters - find a way to workaround it. EXPECT_DEATH(DieWithEmbeddedNul(), "my null world"); ASSERT_DEATH(DieWithEmbeddedNul(), "my null world"); } # endif // GTEST_USES_PCRE // Tests that death test macros expand to code which interacts well with switch // statements. TEST_F(TestForDeathTest, SwitchStatement) { // Microsoft compiler usually complains about switch statements without // case labels. We suppress that warning for this test. # ifdef _MSC_VER # pragma warning(push) # pragma warning(disable: 4065) # endif // _MSC_VER switch (0) default: ASSERT_DEATH(_exit(1), "") << "exit in default switch handler"; switch (0) case 0: EXPECT_DEATH(_exit(1), "") << "exit in switch case"; # ifdef _MSC_VER # pragma warning(pop) # endif // _MSC_VER } // Tests that a static member function can be used in a "fast" style // death test. TEST_F(TestForDeathTest, StaticMemberFunctionFastStyle) { testing::GTEST_FLAG(death_test_style) = "fast"; ASSERT_DEATH(StaticMemberFunction(), "death.*StaticMember"); } // Tests that a method of the test fixture can be used in a "fast" // style death test. TEST_F(TestForDeathTest, MemberFunctionFastStyle) { testing::GTEST_FLAG(death_test_style) = "fast"; should_die_ = true; EXPECT_DEATH(MemberFunction(), "inside.*MemberFunction"); } void ChangeToRootDir() { posix::ChDir(GTEST_PATH_SEP_); } // Tests that death tests work even if the current directory has been // changed. TEST_F(TestForDeathTest, FastDeathTestInChangedDir) { testing::GTEST_FLAG(death_test_style) = "fast"; ChangeToRootDir(); EXPECT_EXIT(_exit(1), testing::ExitedWithCode(1), ""); ChangeToRootDir(); ASSERT_DEATH(_exit(1), ""); } # if GTEST_OS_LINUX void SigprofAction(int, siginfo_t*, void*) { /* no op */ } // Sets SIGPROF action and ITIMER_PROF timer (interval: 1ms). void SetSigprofActionAndTimer() { struct itimerval timer; timer.it_interval.tv_sec = 0; timer.it_interval.tv_usec = 1; timer.it_value = timer.it_interval; ASSERT_EQ(0, setitimer(ITIMER_PROF, &timer, NULL)); struct sigaction signal_action; memset(&signal_action, 0, sizeof(signal_action)); sigemptyset(&signal_action.sa_mask); signal_action.sa_sigaction = SigprofAction; signal_action.sa_flags = SA_RESTART | SA_SIGINFO; ASSERT_EQ(0, sigaction(SIGPROF, &signal_action, NULL)); } // Disables ITIMER_PROF timer and ignores SIGPROF signal. void DisableSigprofActionAndTimer(struct sigaction* old_signal_action) { struct itimerval timer; timer.it_interval.tv_sec = 0; timer.it_interval.tv_usec = 0; timer.it_value = timer.it_interval; ASSERT_EQ(0, setitimer(ITIMER_PROF, &timer, NULL)); struct sigaction signal_action; memset(&signal_action, 0, sizeof(signal_action)); sigemptyset(&signal_action.sa_mask); signal_action.sa_handler = SIG_IGN; ASSERT_EQ(0, sigaction(SIGPROF, &signal_action, old_signal_action)); } // Tests that death tests work when SIGPROF handler and timer are set. TEST_F(TestForDeathTest, FastSigprofActionSet) { testing::GTEST_FLAG(death_test_style) = "fast"; SetSigprofActionAndTimer(); EXPECT_DEATH(_exit(1), ""); struct sigaction old_signal_action; DisableSigprofActionAndTimer(&old_signal_action); EXPECT_TRUE(old_signal_action.sa_sigaction == SigprofAction); } TEST_F(TestForDeathTest, ThreadSafeSigprofActionSet) { testing::GTEST_FLAG(death_test_style) = "threadsafe"; SetSigprofActionAndTimer(); EXPECT_DEATH(_exit(1), ""); struct sigaction old_signal_action; DisableSigprofActionAndTimer(&old_signal_action); EXPECT_TRUE(old_signal_action.sa_sigaction == SigprofAction); } # endif // GTEST_OS_LINUX // Repeats a representative sample of death tests in the "threadsafe" style: TEST_F(TestForDeathTest, StaticMemberFunctionThreadsafeStyle) { testing::GTEST_FLAG(death_test_style) = "threadsafe"; ASSERT_DEATH(StaticMemberFunction(), "death.*StaticMember"); } TEST_F(TestForDeathTest, MemberFunctionThreadsafeStyle) { testing::GTEST_FLAG(death_test_style) = "threadsafe"; should_die_ = true; EXPECT_DEATH(MemberFunction(), "inside.*MemberFunction"); } TEST_F(TestForDeathTest, ThreadsafeDeathTestInLoop) { testing::GTEST_FLAG(death_test_style) = "threadsafe"; for (int i = 0; i < 3; ++i) EXPECT_EXIT(_exit(i), testing::ExitedWithCode(i), "") << ": i = " << i; } TEST_F(TestForDeathTest, ThreadsafeDeathTestInChangedDir) { testing::GTEST_FLAG(death_test_style) = "threadsafe"; ChangeToRootDir(); EXPECT_EXIT(_exit(1), testing::ExitedWithCode(1), ""); ChangeToRootDir(); ASSERT_DEATH(_exit(1), ""); } TEST_F(TestForDeathTest, MixedStyles) { testing::GTEST_FLAG(death_test_style) = "threadsafe"; EXPECT_DEATH(_exit(1), ""); testing::GTEST_FLAG(death_test_style) = "fast"; EXPECT_DEATH(_exit(1), ""); } # if GTEST_HAS_CLONE && GTEST_HAS_PTHREAD namespace { bool pthread_flag; void SetPthreadFlag() { pthread_flag = true; } } // namespace TEST_F(TestForDeathTest, DoesNotExecuteAtforkHooks) { if (!testing::GTEST_FLAG(death_test_use_fork)) { testing::GTEST_FLAG(death_test_style) = "threadsafe"; pthread_flag = false; ASSERT_EQ(0, pthread_atfork(&SetPthreadFlag, NULL, NULL)); ASSERT_DEATH(_exit(1), ""); ASSERT_FALSE(pthread_flag); } } # endif // GTEST_HAS_CLONE && GTEST_HAS_PTHREAD // Tests that a method of another class can be used in a death test. TEST_F(TestForDeathTest, MethodOfAnotherClass) { const MayDie x(true); ASSERT_DEATH(x.MemberFunction(), "MayDie\\:\\:MemberFunction"); } // Tests that a global function can be used in a death test. TEST_F(TestForDeathTest, GlobalFunction) { EXPECT_DEATH(GlobalFunction(), "GlobalFunction"); } // Tests that any value convertible to an RE works as a second // argument to EXPECT_DEATH. TEST_F(TestForDeathTest, AcceptsAnythingConvertibleToRE) { static const char regex_c_str[] = "GlobalFunction"; EXPECT_DEATH(GlobalFunction(), regex_c_str); const testing::internal::RE regex(regex_c_str); EXPECT_DEATH(GlobalFunction(), regex); # if GTEST_HAS_GLOBAL_STRING const string regex_str(regex_c_str); EXPECT_DEATH(GlobalFunction(), regex_str); # endif // GTEST_HAS_GLOBAL_STRING const ::std::string regex_std_str(regex_c_str); EXPECT_DEATH(GlobalFunction(), regex_std_str); } // Tests that a non-void function can be used in a death test. TEST_F(TestForDeathTest, NonVoidFunction) { ASSERT_DEATH(NonVoidFunction(), "NonVoidFunction"); } // Tests that functions that take parameter(s) can be used in a death test. TEST_F(TestForDeathTest, FunctionWithParameter) { EXPECT_DEATH(DieIf(true), "DieIf\\(\\)"); EXPECT_DEATH(DieIfLessThan(2, 3), "DieIfLessThan"); } // Tests that ASSERT_DEATH can be used outside a TEST, TEST_F, or test fixture. TEST_F(TestForDeathTest, OutsideFixture) { DeathTestSubroutine(); } // Tests that death tests can be done inside a loop. TEST_F(TestForDeathTest, InsideLoop) { for (int i = 0; i < 5; i++) { EXPECT_DEATH(DieIfLessThan(-1, i), "DieIfLessThan") << "where i == " << i; } } // Tests that a compound statement can be used in a death test. TEST_F(TestForDeathTest, CompoundStatement) { EXPECT_DEATH({ // NOLINT const int x = 2; const int y = x + 1; DieIfLessThan(x, y); }, "DieIfLessThan"); } // Tests that code that doesn't die causes a death test to fail. TEST_F(TestForDeathTest, DoesNotDie) { EXPECT_NONFATAL_FAILURE(EXPECT_DEATH(DieIf(false), "DieIf"), "failed to die"); } // Tests that a death test fails when the error message isn't expected. TEST_F(TestForDeathTest, ErrorMessageMismatch) { EXPECT_NONFATAL_FAILURE({ // NOLINT EXPECT_DEATH(DieIf(true), "DieIfLessThan") << "End of death test message."; }, "died but not with expected error"); } // On exit, *aborted will be true iff the EXPECT_DEATH() statement // aborted the function. void ExpectDeathTestHelper(bool* aborted) { *aborted = true; EXPECT_DEATH(DieIf(false), "DieIf"); // This assertion should fail. *aborted = false; } // Tests that EXPECT_DEATH doesn't abort the test on failure. TEST_F(TestForDeathTest, EXPECT_DEATH) { bool aborted = true; EXPECT_NONFATAL_FAILURE(ExpectDeathTestHelper(&aborted), "failed to die"); EXPECT_FALSE(aborted); } // Tests that ASSERT_DEATH does abort the test on failure. TEST_F(TestForDeathTest, ASSERT_DEATH) { static bool aborted; EXPECT_FATAL_FAILURE({ // NOLINT aborted = true; ASSERT_DEATH(DieIf(false), "DieIf"); // This assertion should fail. aborted = false; }, "failed to die"); EXPECT_TRUE(aborted); } // Tests that EXPECT_DEATH evaluates the arguments exactly once. TEST_F(TestForDeathTest, SingleEvaluation) { int x = 3; EXPECT_DEATH(DieIf((++x) == 4), "DieIf"); const char* regex = "DieIf"; const char* regex_save = regex; EXPECT_DEATH(DieIfLessThan(3, 4), regex++); EXPECT_EQ(regex_save + 1, regex); } // Tests that run-away death tests are reported as failures. TEST_F(TestForDeathTest, RunawayIsFailure) { EXPECT_NONFATAL_FAILURE(EXPECT_DEATH(static_cast(0), "Foo"), "failed to die."); } // Tests that death tests report executing 'return' in the statement as // failure. TEST_F(TestForDeathTest, ReturnIsFailure) { EXPECT_FATAL_FAILURE(ASSERT_DEATH(return, "Bar"), "illegal return in test statement."); } // Tests that EXPECT_DEBUG_DEATH works as expected, that is, you can stream a // message to it, and in debug mode it: // 1. Asserts on death. // 2. Has no side effect. // // And in opt mode, it: // 1. Has side effects but does not assert. TEST_F(TestForDeathTest, TestExpectDebugDeath) { int sideeffect = 0; EXPECT_DEBUG_DEATH(DieInDebugElse12(&sideeffect), "death.*DieInDebugElse12") << "Must accept a streamed message"; # ifdef NDEBUG // Checks that the assignment occurs in opt mode (sideeffect). EXPECT_EQ(12, sideeffect); # else // Checks that the assignment does not occur in dbg mode (no sideeffect). EXPECT_EQ(0, sideeffect); # endif } // Tests that ASSERT_DEBUG_DEATH works as expected, that is, you can stream a // message to it, and in debug mode it: // 1. Asserts on death. // 2. Has no side effect. // // And in opt mode, it: // 1. Has side effects but does not assert. TEST_F(TestForDeathTest, TestAssertDebugDeath) { int sideeffect = 0; ASSERT_DEBUG_DEATH(DieInDebugElse12(&sideeffect), "death.*DieInDebugElse12") << "Must accept a streamed message"; # ifdef NDEBUG // Checks that the assignment occurs in opt mode (sideeffect). EXPECT_EQ(12, sideeffect); # else // Checks that the assignment does not occur in dbg mode (no sideeffect). EXPECT_EQ(0, sideeffect); # endif } # ifndef NDEBUG void ExpectDebugDeathHelper(bool* aborted) { *aborted = true; EXPECT_DEBUG_DEATH(return, "") << "This is expected to fail."; *aborted = false; } # if GTEST_OS_WINDOWS TEST(PopUpDeathTest, DoesNotShowPopUpOnAbort) { printf("This test should be considered failing if it shows " "any pop-up dialogs.\n"); fflush(stdout); EXPECT_DEATH({ testing::GTEST_FLAG(catch_exceptions) = false; abort(); }, ""); } # endif // GTEST_OS_WINDOWS // Tests that EXPECT_DEBUG_DEATH in debug mode does not abort // the function. TEST_F(TestForDeathTest, ExpectDebugDeathDoesNotAbort) { bool aborted = true; EXPECT_NONFATAL_FAILURE(ExpectDebugDeathHelper(&aborted), ""); EXPECT_FALSE(aborted); } void AssertDebugDeathHelper(bool* aborted) { *aborted = true; ASSERT_DEBUG_DEATH(return, "") << "This is expected to fail."; *aborted = false; } // Tests that ASSERT_DEBUG_DEATH in debug mode aborts the function on // failure. TEST_F(TestForDeathTest, AssertDebugDeathAborts) { static bool aborted; aborted = false; EXPECT_FATAL_FAILURE(AssertDebugDeathHelper(&aborted), ""); EXPECT_TRUE(aborted); } # endif // _NDEBUG // Tests the *_EXIT family of macros, using a variety of predicates. static void TestExitMacros() { EXPECT_EXIT(_exit(1), testing::ExitedWithCode(1), ""); ASSERT_EXIT(_exit(42), testing::ExitedWithCode(42), ""); # if GTEST_OS_WINDOWS // Of all signals effects on the process exit code, only those of SIGABRT // are documented on Windows. // See http://msdn.microsoft.com/en-us/library/dwwzkt4c(VS.71).aspx. EXPECT_EXIT(raise(SIGABRT), testing::ExitedWithCode(3), "") << "b_ar"; # else EXPECT_EXIT(raise(SIGKILL), testing::KilledBySignal(SIGKILL), "") << "foo"; ASSERT_EXIT(raise(SIGUSR2), testing::KilledBySignal(SIGUSR2), "") << "bar"; EXPECT_FATAL_FAILURE({ // NOLINT ASSERT_EXIT(_exit(0), testing::KilledBySignal(SIGSEGV), "") << "This failure is expected, too."; }, "This failure is expected, too."); # endif // GTEST_OS_WINDOWS EXPECT_NONFATAL_FAILURE({ // NOLINT EXPECT_EXIT(raise(SIGSEGV), testing::ExitedWithCode(0), "") << "This failure is expected."; }, "This failure is expected."); } TEST_F(TestForDeathTest, ExitMacros) { TestExitMacros(); } TEST_F(TestForDeathTest, ExitMacrosUsingFork) { testing::GTEST_FLAG(death_test_use_fork) = true; TestExitMacros(); } TEST_F(TestForDeathTest, InvalidStyle) { testing::GTEST_FLAG(death_test_style) = "rococo"; EXPECT_NONFATAL_FAILURE({ // NOLINT EXPECT_DEATH(_exit(0), "") << "This failure is expected."; }, "This failure is expected."); } TEST_F(TestForDeathTest, DeathTestFailedOutput) { testing::GTEST_FLAG(death_test_style) = "fast"; EXPECT_NONFATAL_FAILURE( EXPECT_DEATH(DieWithMessage("death\n"), "expected message"), "Actual msg:\n" "[ DEATH ] death\n"); } TEST_F(TestForDeathTest, DeathTestUnexpectedReturnOutput) { testing::GTEST_FLAG(death_test_style) = "fast"; EXPECT_NONFATAL_FAILURE( EXPECT_DEATH({ fprintf(stderr, "returning\n"); fflush(stderr); return; }, ""), " Result: illegal return in test statement.\n" " Error msg:\n" "[ DEATH ] returning\n"); } TEST_F(TestForDeathTest, DeathTestBadExitCodeOutput) { testing::GTEST_FLAG(death_test_style) = "fast"; EXPECT_NONFATAL_FAILURE( EXPECT_EXIT(DieWithMessage("exiting with rc 1\n"), testing::ExitedWithCode(3), "expected message"), " Result: died but not with expected exit code:\n" " Exited with exit status 1\n" "Actual msg:\n" "[ DEATH ] exiting with rc 1\n"); } TEST_F(TestForDeathTest, DeathTestMultiLineMatchFail) { testing::GTEST_FLAG(death_test_style) = "fast"; EXPECT_NONFATAL_FAILURE( EXPECT_DEATH(DieWithMessage("line 1\nline 2\nline 3\n"), "line 1\nxyz\nline 3\n"), "Actual msg:\n" "[ DEATH ] line 1\n" "[ DEATH ] line 2\n" "[ DEATH ] line 3\n"); } TEST_F(TestForDeathTest, DeathTestMultiLineMatchPass) { testing::GTEST_FLAG(death_test_style) = "fast"; EXPECT_DEATH(DieWithMessage("line 1\nline 2\nline 3\n"), "line 1\nline 2\nline 3\n"); } // A DeathTestFactory that returns MockDeathTests. class MockDeathTestFactory : public DeathTestFactory { public: MockDeathTestFactory(); virtual bool Create(const char* statement, const ::testing::internal::RE* regex, const char* file, int line, DeathTest** test); // Sets the parameters for subsequent calls to Create. void SetParameters(bool create, DeathTest::TestRole role, int status, bool passed); // Accessors. int AssumeRoleCalls() const { return assume_role_calls_; } int WaitCalls() const { return wait_calls_; } int PassedCalls() const { return passed_args_.size(); } bool PassedArgument(int n) const { return passed_args_[n]; } int AbortCalls() const { return abort_args_.size(); } DeathTest::AbortReason AbortArgument(int n) const { return abort_args_[n]; } bool TestDeleted() const { return test_deleted_; } private: friend class MockDeathTest; // If true, Create will return a MockDeathTest; otherwise it returns // NULL. bool create_; // The value a MockDeathTest will return from its AssumeRole method. DeathTest::TestRole role_; // The value a MockDeathTest will return from its Wait method. int status_; // The value a MockDeathTest will return from its Passed method. bool passed_; // Number of times AssumeRole was called. int assume_role_calls_; // Number of times Wait was called. int wait_calls_; // The arguments to the calls to Passed since the last call to // SetParameters. std::vector passed_args_; // The arguments to the calls to Abort since the last call to // SetParameters. std::vector abort_args_; // True if the last MockDeathTest returned by Create has been // deleted. bool test_deleted_; }; // A DeathTest implementation useful in testing. It returns values set // at its creation from its various inherited DeathTest methods, and // reports calls to those methods to its parent MockDeathTestFactory // object. class MockDeathTest : public DeathTest { public: MockDeathTest(MockDeathTestFactory *parent, TestRole role, int status, bool passed) : parent_(parent), role_(role), status_(status), passed_(passed) { } virtual ~MockDeathTest() { parent_->test_deleted_ = true; } virtual TestRole AssumeRole() { ++parent_->assume_role_calls_; return role_; } virtual int Wait() { ++parent_->wait_calls_; return status_; } virtual bool Passed(bool exit_status_ok) { parent_->passed_args_.push_back(exit_status_ok); return passed_; } virtual void Abort(AbortReason reason) { parent_->abort_args_.push_back(reason); } private: MockDeathTestFactory* const parent_; const TestRole role_; const int status_; const bool passed_; }; // MockDeathTestFactory constructor. MockDeathTestFactory::MockDeathTestFactory() : create_(true), role_(DeathTest::OVERSEE_TEST), status_(0), passed_(true), assume_role_calls_(0), wait_calls_(0), passed_args_(), abort_args_() { } // Sets the parameters for subsequent calls to Create. void MockDeathTestFactory::SetParameters(bool create, DeathTest::TestRole role, int status, bool passed) { create_ = create; role_ = role; status_ = status; passed_ = passed; assume_role_calls_ = 0; wait_calls_ = 0; passed_args_.clear(); abort_args_.clear(); } // Sets test to NULL (if create_ is false) or to the address of a new // MockDeathTest object with parameters taken from the last call // to SetParameters (if create_ is true). Always returns true. bool MockDeathTestFactory::Create(const char* /*statement*/, const ::testing::internal::RE* /*regex*/, const char* /*file*/, int /*line*/, DeathTest** test) { test_deleted_ = false; if (create_) { *test = new MockDeathTest(this, role_, status_, passed_); } else { *test = NULL; } return true; } // A test fixture for testing the logic of the GTEST_DEATH_TEST_ macro. // It installs a MockDeathTestFactory that is used for the duration // of the test case. class MacroLogicDeathTest : public testing::Test { protected: static testing::internal::ReplaceDeathTestFactory* replacer_; static MockDeathTestFactory* factory_; static void SetUpTestCase() { factory_ = new MockDeathTestFactory; replacer_ = new testing::internal::ReplaceDeathTestFactory(factory_); } static void TearDownTestCase() { delete replacer_; replacer_ = NULL; delete factory_; factory_ = NULL; } // Runs a death test that breaks the rules by returning. Such a death // test cannot be run directly from a test routine that uses a // MockDeathTest, or the remainder of the routine will not be executed. static void RunReturningDeathTest(bool* flag) { ASSERT_DEATH({ // NOLINT *flag = true; return; }, ""); } }; testing::internal::ReplaceDeathTestFactory* MacroLogicDeathTest::replacer_ = NULL; MockDeathTestFactory* MacroLogicDeathTest::factory_ = NULL; // Test that nothing happens when the factory doesn't return a DeathTest: TEST_F(MacroLogicDeathTest, NothingHappens) { bool flag = false; factory_->SetParameters(false, DeathTest::OVERSEE_TEST, 0, true); EXPECT_DEATH(flag = true, ""); EXPECT_FALSE(flag); EXPECT_EQ(0, factory_->AssumeRoleCalls()); EXPECT_EQ(0, factory_->WaitCalls()); EXPECT_EQ(0, factory_->PassedCalls()); EXPECT_EQ(0, factory_->AbortCalls()); EXPECT_FALSE(factory_->TestDeleted()); } // Test that the parent process doesn't run the death test code, // and that the Passed method returns false when the (simulated) // child process exits with status 0: TEST_F(MacroLogicDeathTest, ChildExitsSuccessfully) { bool flag = false; factory_->SetParameters(true, DeathTest::OVERSEE_TEST, 0, true); EXPECT_DEATH(flag = true, ""); EXPECT_FALSE(flag); EXPECT_EQ(1, factory_->AssumeRoleCalls()); EXPECT_EQ(1, factory_->WaitCalls()); ASSERT_EQ(1, factory_->PassedCalls()); EXPECT_FALSE(factory_->PassedArgument(0)); EXPECT_EQ(0, factory_->AbortCalls()); EXPECT_TRUE(factory_->TestDeleted()); } // Tests that the Passed method was given the argument "true" when // the (simulated) child process exits with status 1: TEST_F(MacroLogicDeathTest, ChildExitsUnsuccessfully) { bool flag = false; factory_->SetParameters(true, DeathTest::OVERSEE_TEST, 1, true); EXPECT_DEATH(flag = true, ""); EXPECT_FALSE(flag); EXPECT_EQ(1, factory_->AssumeRoleCalls()); EXPECT_EQ(1, factory_->WaitCalls()); ASSERT_EQ(1, factory_->PassedCalls()); EXPECT_TRUE(factory_->PassedArgument(0)); EXPECT_EQ(0, factory_->AbortCalls()); EXPECT_TRUE(factory_->TestDeleted()); } // Tests that the (simulated) child process executes the death test // code, and is aborted with the correct AbortReason if it // executes a return statement. TEST_F(MacroLogicDeathTest, ChildPerformsReturn) { bool flag = false; factory_->SetParameters(true, DeathTest::EXECUTE_TEST, 0, true); RunReturningDeathTest(&flag); EXPECT_TRUE(flag); EXPECT_EQ(1, factory_->AssumeRoleCalls()); EXPECT_EQ(0, factory_->WaitCalls()); EXPECT_EQ(0, factory_->PassedCalls()); EXPECT_EQ(1, factory_->AbortCalls()); EXPECT_EQ(DeathTest::TEST_ENCOUNTERED_RETURN_STATEMENT, factory_->AbortArgument(0)); EXPECT_TRUE(factory_->TestDeleted()); } // Tests that the (simulated) child process is aborted with the // correct AbortReason if it does not die. TEST_F(MacroLogicDeathTest, ChildDoesNotDie) { bool flag = false; factory_->SetParameters(true, DeathTest::EXECUTE_TEST, 0, true); EXPECT_DEATH(flag = true, ""); EXPECT_TRUE(flag); EXPECT_EQ(1, factory_->AssumeRoleCalls()); EXPECT_EQ(0, factory_->WaitCalls()); EXPECT_EQ(0, factory_->PassedCalls()); // This time there are two calls to Abort: one since the test didn't // die, and another from the ReturnSentinel when it's destroyed. The // sentinel normally isn't destroyed if a test doesn't die, since // _exit(2) is called in that case by ForkingDeathTest, but not by // our MockDeathTest. ASSERT_EQ(2, factory_->AbortCalls()); EXPECT_EQ(DeathTest::TEST_DID_NOT_DIE, factory_->AbortArgument(0)); EXPECT_EQ(DeathTest::TEST_ENCOUNTERED_RETURN_STATEMENT, factory_->AbortArgument(1)); EXPECT_TRUE(factory_->TestDeleted()); } // Tests that a successful death test does not register a successful // test part. TEST(SuccessRegistrationDeathTest, NoSuccessPart) { EXPECT_DEATH(_exit(1), ""); EXPECT_EQ(0, GetUnitTestImpl()->current_test_result()->total_part_count()); } TEST(StreamingAssertionsDeathTest, DeathTest) { EXPECT_DEATH(_exit(1), "") << "unexpected failure"; ASSERT_DEATH(_exit(1), "") << "unexpected failure"; EXPECT_NONFATAL_FAILURE({ // NOLINT EXPECT_DEATH(_exit(0), "") << "expected failure"; }, "expected failure"); EXPECT_FATAL_FAILURE({ // NOLINT ASSERT_DEATH(_exit(0), "") << "expected failure"; }, "expected failure"); } // Tests that GetLastErrnoDescription returns an empty string when the // last error is 0 and non-empty string when it is non-zero. TEST(GetLastErrnoDescription, GetLastErrnoDescriptionWorks) { errno = ENOENT; EXPECT_STRNE("", GetLastErrnoDescription().c_str()); errno = 0; EXPECT_STREQ("", GetLastErrnoDescription().c_str()); } # if GTEST_OS_WINDOWS TEST(AutoHandleTest, AutoHandleWorks) { HANDLE handle = ::CreateEvent(NULL, FALSE, FALSE, NULL); ASSERT_NE(INVALID_HANDLE_VALUE, handle); // Tests that the AutoHandle is correctly initialized with a handle. testing::internal::AutoHandle auto_handle(handle); EXPECT_EQ(handle, auto_handle.Get()); // Tests that Reset assigns INVALID_HANDLE_VALUE. // Note that this cannot verify whether the original handle is closed. auto_handle.Reset(); EXPECT_EQ(INVALID_HANDLE_VALUE, auto_handle.Get()); // Tests that Reset assigns the new handle. // Note that this cannot verify whether the original handle is closed. handle = ::CreateEvent(NULL, FALSE, FALSE, NULL); ASSERT_NE(INVALID_HANDLE_VALUE, handle); auto_handle.Reset(handle); EXPECT_EQ(handle, auto_handle.Get()); // Tests that AutoHandle contains INVALID_HANDLE_VALUE by default. testing::internal::AutoHandle auto_handle2; EXPECT_EQ(INVALID_HANDLE_VALUE, auto_handle2.Get()); } # endif // GTEST_OS_WINDOWS # if GTEST_OS_WINDOWS typedef unsigned __int64 BiggestParsable; typedef signed __int64 BiggestSignedParsable; # else typedef unsigned long long BiggestParsable; typedef signed long long BiggestSignedParsable; # endif // GTEST_OS_WINDOWS // We cannot use std::numeric_limits::max() as it clashes with the // max() macro defined by . const BiggestParsable kBiggestParsableMax = ULLONG_MAX; const BiggestSignedParsable kBiggestSignedParsableMax = LLONG_MAX; TEST(ParseNaturalNumberTest, RejectsInvalidFormat) { BiggestParsable result = 0; // Rejects non-numbers. EXPECT_FALSE(ParseNaturalNumber("non-number string", &result)); // Rejects numbers with whitespace prefix. EXPECT_FALSE(ParseNaturalNumber(" 123", &result)); // Rejects negative numbers. EXPECT_FALSE(ParseNaturalNumber("-123", &result)); // Rejects numbers starting with a plus sign. EXPECT_FALSE(ParseNaturalNumber("+123", &result)); errno = 0; } TEST(ParseNaturalNumberTest, RejectsOverflownNumbers) { BiggestParsable result = 0; EXPECT_FALSE(ParseNaturalNumber("99999999999999999999999", &result)); signed char char_result = 0; EXPECT_FALSE(ParseNaturalNumber("200", &char_result)); errno = 0; } TEST(ParseNaturalNumberTest, AcceptsValidNumbers) { BiggestParsable result = 0; result = 0; ASSERT_TRUE(ParseNaturalNumber("123", &result)); EXPECT_EQ(123U, result); // Check 0 as an edge case. result = 1; ASSERT_TRUE(ParseNaturalNumber("0", &result)); EXPECT_EQ(0U, result); result = 1; ASSERT_TRUE(ParseNaturalNumber("00000", &result)); EXPECT_EQ(0U, result); } TEST(ParseNaturalNumberTest, AcceptsTypeLimits) { Message msg; msg << kBiggestParsableMax; BiggestParsable result = 0; EXPECT_TRUE(ParseNaturalNumber(msg.GetString(), &result)); EXPECT_EQ(kBiggestParsableMax, result); Message msg2; msg2 << kBiggestSignedParsableMax; BiggestSignedParsable signed_result = 0; EXPECT_TRUE(ParseNaturalNumber(msg2.GetString(), &signed_result)); EXPECT_EQ(kBiggestSignedParsableMax, signed_result); Message msg3; msg3 << INT_MAX; int int_result = 0; EXPECT_TRUE(ParseNaturalNumber(msg3.GetString(), &int_result)); EXPECT_EQ(INT_MAX, int_result); Message msg4; msg4 << UINT_MAX; unsigned int uint_result = 0; EXPECT_TRUE(ParseNaturalNumber(msg4.GetString(), &uint_result)); EXPECT_EQ(UINT_MAX, uint_result); } TEST(ParseNaturalNumberTest, WorksForShorterIntegers) { short short_result = 0; ASSERT_TRUE(ParseNaturalNumber("123", &short_result)); EXPECT_EQ(123, short_result); signed char char_result = 0; ASSERT_TRUE(ParseNaturalNumber("123", &char_result)); EXPECT_EQ(123, char_result); } # if GTEST_OS_WINDOWS TEST(EnvironmentTest, HandleFitsIntoSizeT) { // TODO(vladl@google.com): Remove this test after this condition is verified // in a static assertion in gtest-death-test.cc in the function // GetStatusFileDescriptor. ASSERT_TRUE(sizeof(HANDLE) <= sizeof(size_t)); } # endif // GTEST_OS_WINDOWS // Tests that EXPECT_DEATH_IF_SUPPORTED/ASSERT_DEATH_IF_SUPPORTED trigger // failures when death tests are available on the system. TEST(ConditionalDeathMacrosDeathTest, ExpectsDeathWhenDeathTestsAvailable) { EXPECT_DEATH_IF_SUPPORTED(DieInside("CondDeathTestExpectMacro"), "death inside CondDeathTestExpectMacro"); ASSERT_DEATH_IF_SUPPORTED(DieInside("CondDeathTestAssertMacro"), "death inside CondDeathTestAssertMacro"); // Empty statement will not crash, which must trigger a failure. EXPECT_NONFATAL_FAILURE(EXPECT_DEATH_IF_SUPPORTED(;, ""), ""); EXPECT_FATAL_FAILURE(ASSERT_DEATH_IF_SUPPORTED(;, ""), ""); } #else using testing::internal::CaptureStderr; using testing::internal::GetCapturedStderr; // Tests that EXPECT_DEATH_IF_SUPPORTED/ASSERT_DEATH_IF_SUPPORTED are still // defined but do not trigger failures when death tests are not available on // the system. TEST(ConditionalDeathMacrosTest, WarnsWhenDeathTestsNotAvailable) { // Empty statement will not crash, but that should not trigger a failure // when death tests are not supported. CaptureStderr(); EXPECT_DEATH_IF_SUPPORTED(;, ""); std::string output = GetCapturedStderr(); ASSERT_TRUE(NULL != strstr(output.c_str(), "Death tests are not supported on this platform")); ASSERT_TRUE(NULL != strstr(output.c_str(), ";")); // The streamed message should not be printed as there is no test failure. CaptureStderr(); EXPECT_DEATH_IF_SUPPORTED(;, "") << "streamed message"; output = GetCapturedStderr(); ASSERT_TRUE(NULL == strstr(output.c_str(), "streamed message")); CaptureStderr(); ASSERT_DEATH_IF_SUPPORTED(;, ""); // NOLINT output = GetCapturedStderr(); ASSERT_TRUE(NULL != strstr(output.c_str(), "Death tests are not supported on this platform")); ASSERT_TRUE(NULL != strstr(output.c_str(), ";")); CaptureStderr(); ASSERT_DEATH_IF_SUPPORTED(;, "") << "streamed message"; // NOLINT output = GetCapturedStderr(); ASSERT_TRUE(NULL == strstr(output.c_str(), "streamed message")); } void FuncWithAssert(int* n) { ASSERT_DEATH_IF_SUPPORTED(return;, ""); (*n)++; } // Tests that ASSERT_DEATH_IF_SUPPORTED does not return from the current // function (as ASSERT_DEATH does) if death tests are not supported. TEST(ConditionalDeathMacrosTest, AssertDeatDoesNotReturnhIfUnsupported) { int n = 0; FuncWithAssert(&n); EXPECT_EQ(1, n); } TEST(InDeathTestChildDeathTest, ReportsDeathTestCorrectlyInFastStyle) { testing::GTEST_FLAG(death_test_style) = "fast"; EXPECT_FALSE(InDeathTestChild()); EXPECT_DEATH({ fprintf(stderr, InDeathTestChild() ? "Inside" : "Outside"); fflush(stderr); _exit(1); }, "Inside"); } TEST(InDeathTestChildDeathTest, ReportsDeathTestCorrectlyInThreadSafeStyle) { testing::GTEST_FLAG(death_test_style) = "threadsafe"; EXPECT_FALSE(InDeathTestChild()); EXPECT_DEATH({ fprintf(stderr, InDeathTestChild() ? "Inside" : "Outside"); fflush(stderr); _exit(1); }, "Inside"); } #endif // GTEST_HAS_DEATH_TEST // Tests that the death test macros expand to code which may or may not // be followed by operator<<, and that in either case the complete text // comprises only a single C++ statement. // // The syntax should work whether death tests are available or not. TEST(ConditionalDeathMacrosSyntaxDeathTest, SingleStatement) { if (AlwaysFalse()) // This would fail if executed; this is a compilation test only ASSERT_DEATH_IF_SUPPORTED(return, ""); if (AlwaysTrue()) EXPECT_DEATH_IF_SUPPORTED(_exit(1), ""); else // This empty "else" branch is meant to ensure that EXPECT_DEATH // doesn't expand into an "if" statement without an "else" ; // NOLINT if (AlwaysFalse()) ASSERT_DEATH_IF_SUPPORTED(return, "") << "did not die"; if (AlwaysFalse()) ; // NOLINT else EXPECT_DEATH_IF_SUPPORTED(_exit(1), "") << 1 << 2 << 3; } // Tests that conditional death test macros expand to code which interacts // well with switch statements. TEST(ConditionalDeathMacrosSyntaxDeathTest, SwitchStatement) { // Microsoft compiler usually complains about switch statements without // case labels. We suppress that warning for this test. #ifdef _MSC_VER # pragma warning(push) # pragma warning(disable: 4065) #endif // _MSC_VER switch (0) default: ASSERT_DEATH_IF_SUPPORTED(_exit(1), "") << "exit in default switch handler"; switch (0) case 0: EXPECT_DEATH_IF_SUPPORTED(_exit(1), "") << "exit in switch case"; #ifdef _MSC_VER # pragma warning(pop) #endif // _MSC_VER } // Tests that a test case whose name ends with "DeathTest" works fine // on Windows. TEST(NotADeathTest, Test) { SUCCEED(); } dlt-daemon-2.18.4/gtest-1.7.0/test/gtest-filepath_test.cc000066400000000000000000000561451353342203500227010ustar00rootroot00000000000000// Copyright 2008, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Authors: keith.ray@gmail.com (Keith Ray) // // Google Test filepath utilities // // This file tests classes and functions used internally by // Google Test. They are subject to change without notice. // // This file is #included from gtest_unittest.cc, to avoid changing // build or make-files for some existing Google Test clients. Do not // #include this file anywhere else! #include "gtest/internal/gtest-filepath.h" #include "gtest/gtest.h" // Indicates that this translation unit is part of Google Test's // implementation. It must come before gtest-internal-inl.h is // included, or there will be a compiler error. This trick is to // prevent a user from accidentally including gtest-internal-inl.h in // his code. #define GTEST_IMPLEMENTATION_ 1 #include "src/gtest-internal-inl.h" #undef GTEST_IMPLEMENTATION_ #if GTEST_OS_WINDOWS_MOBILE # include // NOLINT #elif GTEST_OS_WINDOWS # include // NOLINT #endif // GTEST_OS_WINDOWS_MOBILE namespace testing { namespace internal { namespace { #if GTEST_OS_WINDOWS_MOBILE // TODO(wan@google.com): Move these to the POSIX adapter section in // gtest-port.h. // Windows CE doesn't have the remove C function. int remove(const char* path) { LPCWSTR wpath = String::AnsiToUtf16(path); int ret = DeleteFile(wpath) ? 0 : -1; delete [] wpath; return ret; } // Windows CE doesn't have the _rmdir C function. int _rmdir(const char* path) { FilePath filepath(path); LPCWSTR wpath = String::AnsiToUtf16( filepath.RemoveTrailingPathSeparator().c_str()); int ret = RemoveDirectory(wpath) ? 0 : -1; delete [] wpath; return ret; } #else TEST(GetCurrentDirTest, ReturnsCurrentDir) { const FilePath original_dir = FilePath::GetCurrentDir(); EXPECT_FALSE(original_dir.IsEmpty()); posix::ChDir(GTEST_PATH_SEP_); const FilePath cwd = FilePath::GetCurrentDir(); posix::ChDir(original_dir.c_str()); # if GTEST_OS_WINDOWS // Skips the ":". const char* const cwd_without_drive = strchr(cwd.c_str(), ':'); ASSERT_TRUE(cwd_without_drive != NULL); EXPECT_STREQ(GTEST_PATH_SEP_, cwd_without_drive + 1); # else EXPECT_EQ(GTEST_PATH_SEP_, cwd.string()); # endif } #endif // GTEST_OS_WINDOWS_MOBILE TEST(IsEmptyTest, ReturnsTrueForEmptyPath) { EXPECT_TRUE(FilePath("").IsEmpty()); } TEST(IsEmptyTest, ReturnsFalseForNonEmptyPath) { EXPECT_FALSE(FilePath("a").IsEmpty()); EXPECT_FALSE(FilePath(".").IsEmpty()); EXPECT_FALSE(FilePath("a/b").IsEmpty()); EXPECT_FALSE(FilePath("a\\b\\").IsEmpty()); } // RemoveDirectoryName "" -> "" TEST(RemoveDirectoryNameTest, WhenEmptyName) { EXPECT_EQ("", FilePath("").RemoveDirectoryName().string()); } // RemoveDirectoryName "afile" -> "afile" TEST(RemoveDirectoryNameTest, ButNoDirectory) { EXPECT_EQ("afile", FilePath("afile").RemoveDirectoryName().string()); } // RemoveDirectoryName "/afile" -> "afile" TEST(RemoveDirectoryNameTest, RootFileShouldGiveFileName) { EXPECT_EQ("afile", FilePath(GTEST_PATH_SEP_ "afile").RemoveDirectoryName().string()); } // RemoveDirectoryName "adir/" -> "" TEST(RemoveDirectoryNameTest, WhereThereIsNoFileName) { EXPECT_EQ("", FilePath("adir" GTEST_PATH_SEP_).RemoveDirectoryName().string()); } // RemoveDirectoryName "adir/afile" -> "afile" TEST(RemoveDirectoryNameTest, ShouldGiveFileName) { EXPECT_EQ("afile", FilePath("adir" GTEST_PATH_SEP_ "afile").RemoveDirectoryName().string()); } // RemoveDirectoryName "adir/subdir/afile" -> "afile" TEST(RemoveDirectoryNameTest, ShouldAlsoGiveFileName) { EXPECT_EQ("afile", FilePath("adir" GTEST_PATH_SEP_ "subdir" GTEST_PATH_SEP_ "afile") .RemoveDirectoryName().string()); } #if GTEST_HAS_ALT_PATH_SEP_ // Tests that RemoveDirectoryName() works with the alternate separator // on Windows. // RemoveDirectoryName("/afile") -> "afile" TEST(RemoveDirectoryNameTest, RootFileShouldGiveFileNameForAlternateSeparator) { EXPECT_EQ("afile", FilePath("/afile").RemoveDirectoryName().string()); } // RemoveDirectoryName("adir/") -> "" TEST(RemoveDirectoryNameTest, WhereThereIsNoFileNameForAlternateSeparator) { EXPECT_EQ("", FilePath("adir/").RemoveDirectoryName().string()); } // RemoveDirectoryName("adir/afile") -> "afile" TEST(RemoveDirectoryNameTest, ShouldGiveFileNameForAlternateSeparator) { EXPECT_EQ("afile", FilePath("adir/afile").RemoveDirectoryName().string()); } // RemoveDirectoryName("adir/subdir/afile") -> "afile" TEST(RemoveDirectoryNameTest, ShouldAlsoGiveFileNameForAlternateSeparator) { EXPECT_EQ("afile", FilePath("adir/subdir/afile").RemoveDirectoryName().string()); } #endif // RemoveFileName "" -> "./" TEST(RemoveFileNameTest, EmptyName) { #if GTEST_OS_WINDOWS_MOBILE // On Windows CE, we use the root as the current directory. EXPECT_EQ(GTEST_PATH_SEP_, FilePath("").RemoveFileName().string()); #else EXPECT_EQ("." GTEST_PATH_SEP_, FilePath("").RemoveFileName().string()); #endif } // RemoveFileName "adir/" -> "adir/" TEST(RemoveFileNameTest, ButNoFile) { EXPECT_EQ("adir" GTEST_PATH_SEP_, FilePath("adir" GTEST_PATH_SEP_).RemoveFileName().string()); } // RemoveFileName "adir/afile" -> "adir/" TEST(RemoveFileNameTest, GivesDirName) { EXPECT_EQ("adir" GTEST_PATH_SEP_, FilePath("adir" GTEST_PATH_SEP_ "afile").RemoveFileName().string()); } // RemoveFileName "adir/subdir/afile" -> "adir/subdir/" TEST(RemoveFileNameTest, GivesDirAndSubDirName) { EXPECT_EQ("adir" GTEST_PATH_SEP_ "subdir" GTEST_PATH_SEP_, FilePath("adir" GTEST_PATH_SEP_ "subdir" GTEST_PATH_SEP_ "afile") .RemoveFileName().string()); } // RemoveFileName "/afile" -> "/" TEST(RemoveFileNameTest, GivesRootDir) { EXPECT_EQ(GTEST_PATH_SEP_, FilePath(GTEST_PATH_SEP_ "afile").RemoveFileName().string()); } #if GTEST_HAS_ALT_PATH_SEP_ // Tests that RemoveFileName() works with the alternate separator on // Windows. // RemoveFileName("adir/") -> "adir/" TEST(RemoveFileNameTest, ButNoFileForAlternateSeparator) { EXPECT_EQ("adir" GTEST_PATH_SEP_, FilePath("adir/").RemoveFileName().string()); } // RemoveFileName("adir/afile") -> "adir/" TEST(RemoveFileNameTest, GivesDirNameForAlternateSeparator) { EXPECT_EQ("adir" GTEST_PATH_SEP_, FilePath("adir/afile").RemoveFileName().string()); } // RemoveFileName("adir/subdir/afile") -> "adir/subdir/" TEST(RemoveFileNameTest, GivesDirAndSubDirNameForAlternateSeparator) { EXPECT_EQ("adir" GTEST_PATH_SEP_ "subdir" GTEST_PATH_SEP_, FilePath("adir/subdir/afile").RemoveFileName().string()); } // RemoveFileName("/afile") -> "\" TEST(RemoveFileNameTest, GivesRootDirForAlternateSeparator) { EXPECT_EQ(GTEST_PATH_SEP_, FilePath("/afile").RemoveFileName().string()); } #endif TEST(MakeFileNameTest, GenerateWhenNumberIsZero) { FilePath actual = FilePath::MakeFileName(FilePath("foo"), FilePath("bar"), 0, "xml"); EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar.xml", actual.string()); } TEST(MakeFileNameTest, GenerateFileNameNumberGtZero) { FilePath actual = FilePath::MakeFileName(FilePath("foo"), FilePath("bar"), 12, "xml"); EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar_12.xml", actual.string()); } TEST(MakeFileNameTest, GenerateFileNameWithSlashNumberIsZero) { FilePath actual = FilePath::MakeFileName(FilePath("foo" GTEST_PATH_SEP_), FilePath("bar"), 0, "xml"); EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar.xml", actual.string()); } TEST(MakeFileNameTest, GenerateFileNameWithSlashNumberGtZero) { FilePath actual = FilePath::MakeFileName(FilePath("foo" GTEST_PATH_SEP_), FilePath("bar"), 12, "xml"); EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar_12.xml", actual.string()); } TEST(MakeFileNameTest, GenerateWhenNumberIsZeroAndDirIsEmpty) { FilePath actual = FilePath::MakeFileName(FilePath(""), FilePath("bar"), 0, "xml"); EXPECT_EQ("bar.xml", actual.string()); } TEST(MakeFileNameTest, GenerateWhenNumberIsNotZeroAndDirIsEmpty) { FilePath actual = FilePath::MakeFileName(FilePath(""), FilePath("bar"), 14, "xml"); EXPECT_EQ("bar_14.xml", actual.string()); } TEST(ConcatPathsTest, WorksWhenDirDoesNotEndWithPathSep) { FilePath actual = FilePath::ConcatPaths(FilePath("foo"), FilePath("bar.xml")); EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar.xml", actual.string()); } TEST(ConcatPathsTest, WorksWhenPath1EndsWithPathSep) { FilePath actual = FilePath::ConcatPaths(FilePath("foo" GTEST_PATH_SEP_), FilePath("bar.xml")); EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar.xml", actual.string()); } TEST(ConcatPathsTest, Path1BeingEmpty) { FilePath actual = FilePath::ConcatPaths(FilePath(""), FilePath("bar.xml")); EXPECT_EQ("bar.xml", actual.string()); } TEST(ConcatPathsTest, Path2BeingEmpty) { FilePath actual = FilePath::ConcatPaths(FilePath("foo"), FilePath("")); EXPECT_EQ("foo" GTEST_PATH_SEP_, actual.string()); } TEST(ConcatPathsTest, BothPathBeingEmpty) { FilePath actual = FilePath::ConcatPaths(FilePath(""), FilePath("")); EXPECT_EQ("", actual.string()); } TEST(ConcatPathsTest, Path1ContainsPathSep) { FilePath actual = FilePath::ConcatPaths(FilePath("foo" GTEST_PATH_SEP_ "bar"), FilePath("foobar.xml")); EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar" GTEST_PATH_SEP_ "foobar.xml", actual.string()); } TEST(ConcatPathsTest, Path2ContainsPathSep) { FilePath actual = FilePath::ConcatPaths( FilePath("foo" GTEST_PATH_SEP_), FilePath("bar" GTEST_PATH_SEP_ "bar.xml")); EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar" GTEST_PATH_SEP_ "bar.xml", actual.string()); } TEST(ConcatPathsTest, Path2EndsWithPathSep) { FilePath actual = FilePath::ConcatPaths(FilePath("foo"), FilePath("bar" GTEST_PATH_SEP_)); EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar" GTEST_PATH_SEP_, actual.string()); } // RemoveTrailingPathSeparator "" -> "" TEST(RemoveTrailingPathSeparatorTest, EmptyString) { EXPECT_EQ("", FilePath("").RemoveTrailingPathSeparator().string()); } // RemoveTrailingPathSeparator "foo" -> "foo" TEST(RemoveTrailingPathSeparatorTest, FileNoSlashString) { EXPECT_EQ("foo", FilePath("foo").RemoveTrailingPathSeparator().string()); } // RemoveTrailingPathSeparator "foo/" -> "foo" TEST(RemoveTrailingPathSeparatorTest, ShouldRemoveTrailingSeparator) { EXPECT_EQ("foo", FilePath("foo" GTEST_PATH_SEP_).RemoveTrailingPathSeparator().string()); #if GTEST_HAS_ALT_PATH_SEP_ EXPECT_EQ("foo", FilePath("foo/").RemoveTrailingPathSeparator().string()); #endif } // RemoveTrailingPathSeparator "foo/bar/" -> "foo/bar/" TEST(RemoveTrailingPathSeparatorTest, ShouldRemoveLastSeparator) { EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar", FilePath("foo" GTEST_PATH_SEP_ "bar" GTEST_PATH_SEP_) .RemoveTrailingPathSeparator().string()); } // RemoveTrailingPathSeparator "foo/bar" -> "foo/bar" TEST(RemoveTrailingPathSeparatorTest, ShouldReturnUnmodified) { EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar", FilePath("foo" GTEST_PATH_SEP_ "bar") .RemoveTrailingPathSeparator().string()); } TEST(DirectoryTest, RootDirectoryExists) { #if GTEST_OS_WINDOWS // We are on Windows. char current_drive[_MAX_PATH]; // NOLINT current_drive[0] = static_cast(_getdrive() + 'A' - 1); current_drive[1] = ':'; current_drive[2] = '\\'; current_drive[3] = '\0'; EXPECT_TRUE(FilePath(current_drive).DirectoryExists()); #else EXPECT_TRUE(FilePath("/").DirectoryExists()); #endif // GTEST_OS_WINDOWS } #if GTEST_OS_WINDOWS TEST(DirectoryTest, RootOfWrongDriveDoesNotExists) { const int saved_drive_ = _getdrive(); // Find a drive that doesn't exist. Start with 'Z' to avoid common ones. for (char drive = 'Z'; drive >= 'A'; drive--) if (_chdrive(drive - 'A' + 1) == -1) { char non_drive[_MAX_PATH]; // NOLINT non_drive[0] = drive; non_drive[1] = ':'; non_drive[2] = '\\'; non_drive[3] = '\0'; EXPECT_FALSE(FilePath(non_drive).DirectoryExists()); break; } _chdrive(saved_drive_); } #endif // GTEST_OS_WINDOWS #if !GTEST_OS_WINDOWS_MOBILE // Windows CE _does_ consider an empty directory to exist. TEST(DirectoryTest, EmptyPathDirectoryDoesNotExist) { EXPECT_FALSE(FilePath("").DirectoryExists()); } #endif // !GTEST_OS_WINDOWS_MOBILE TEST(DirectoryTest, CurrentDirectoryExists) { #if GTEST_OS_WINDOWS // We are on Windows. # ifndef _WIN32_CE // Windows CE doesn't have a current directory. EXPECT_TRUE(FilePath(".").DirectoryExists()); EXPECT_TRUE(FilePath(".\\").DirectoryExists()); # endif // _WIN32_CE #else EXPECT_TRUE(FilePath(".").DirectoryExists()); EXPECT_TRUE(FilePath("./").DirectoryExists()); #endif // GTEST_OS_WINDOWS } // "foo/bar" == foo//bar" == "foo///bar" TEST(NormalizeTest, MultipleConsecutiveSepaparatorsInMidstring) { EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar", FilePath("foo" GTEST_PATH_SEP_ "bar").string()); EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar", FilePath("foo" GTEST_PATH_SEP_ GTEST_PATH_SEP_ "bar").string()); EXPECT_EQ("foo" GTEST_PATH_SEP_ "bar", FilePath("foo" GTEST_PATH_SEP_ GTEST_PATH_SEP_ GTEST_PATH_SEP_ "bar").string()); } // "/bar" == //bar" == "///bar" TEST(NormalizeTest, MultipleConsecutiveSepaparatorsAtStringStart) { EXPECT_EQ(GTEST_PATH_SEP_ "bar", FilePath(GTEST_PATH_SEP_ "bar").string()); EXPECT_EQ(GTEST_PATH_SEP_ "bar", FilePath(GTEST_PATH_SEP_ GTEST_PATH_SEP_ "bar").string()); EXPECT_EQ(GTEST_PATH_SEP_ "bar", FilePath(GTEST_PATH_SEP_ GTEST_PATH_SEP_ GTEST_PATH_SEP_ "bar").string()); } // "foo/" == foo//" == "foo///" TEST(NormalizeTest, MultipleConsecutiveSepaparatorsAtStringEnd) { EXPECT_EQ("foo" GTEST_PATH_SEP_, FilePath("foo" GTEST_PATH_SEP_).string()); EXPECT_EQ("foo" GTEST_PATH_SEP_, FilePath("foo" GTEST_PATH_SEP_ GTEST_PATH_SEP_).string()); EXPECT_EQ("foo" GTEST_PATH_SEP_, FilePath("foo" GTEST_PATH_SEP_ GTEST_PATH_SEP_ GTEST_PATH_SEP_).string()); } #if GTEST_HAS_ALT_PATH_SEP_ // Tests that separators at the end of the string are normalized // regardless of their combination (e.g. "foo\" =="foo/\" == // "foo\\/"). TEST(NormalizeTest, MixAlternateSeparatorAtStringEnd) { EXPECT_EQ("foo" GTEST_PATH_SEP_, FilePath("foo/").string()); EXPECT_EQ("foo" GTEST_PATH_SEP_, FilePath("foo" GTEST_PATH_SEP_ "/").string()); EXPECT_EQ("foo" GTEST_PATH_SEP_, FilePath("foo//" GTEST_PATH_SEP_).string()); } #endif TEST(AssignmentOperatorTest, DefaultAssignedToNonDefault) { FilePath default_path; FilePath non_default_path("path"); non_default_path = default_path; EXPECT_EQ("", non_default_path.string()); EXPECT_EQ("", default_path.string()); // RHS var is unchanged. } TEST(AssignmentOperatorTest, NonDefaultAssignedToDefault) { FilePath non_default_path("path"); FilePath default_path; default_path = non_default_path; EXPECT_EQ("path", default_path.string()); EXPECT_EQ("path", non_default_path.string()); // RHS var is unchanged. } TEST(AssignmentOperatorTest, ConstAssignedToNonConst) { const FilePath const_default_path("const_path"); FilePath non_default_path("path"); non_default_path = const_default_path; EXPECT_EQ("const_path", non_default_path.string()); } class DirectoryCreationTest : public Test { protected: virtual void SetUp() { testdata_path_.Set(FilePath( TempDir() + GetCurrentExecutableName().string() + "_directory_creation" GTEST_PATH_SEP_ "test" GTEST_PATH_SEP_)); testdata_file_.Set(testdata_path_.RemoveTrailingPathSeparator()); unique_file0_.Set(FilePath::MakeFileName(testdata_path_, FilePath("unique"), 0, "txt")); unique_file1_.Set(FilePath::MakeFileName(testdata_path_, FilePath("unique"), 1, "txt")); remove(testdata_file_.c_str()); remove(unique_file0_.c_str()); remove(unique_file1_.c_str()); posix::RmDir(testdata_path_.c_str()); } virtual void TearDown() { remove(testdata_file_.c_str()); remove(unique_file0_.c_str()); remove(unique_file1_.c_str()); posix::RmDir(testdata_path_.c_str()); } std::string TempDir() const { #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 } void CreateTextFile(const char* filename) { FILE* f = posix::FOpen(filename, "w"); fprintf(f, "text\n"); fclose(f); } // Strings representing a directory and a file, with identical paths // except for the trailing separator character that distinquishes // a directory named 'test' from a file named 'test'. Example names: FilePath testdata_path_; // "/tmp/directory_creation/test/" FilePath testdata_file_; // "/tmp/directory_creation/test" FilePath unique_file0_; // "/tmp/directory_creation/test/unique.txt" FilePath unique_file1_; // "/tmp/directory_creation/test/unique_1.txt" }; TEST_F(DirectoryCreationTest, CreateDirectoriesRecursively) { EXPECT_FALSE(testdata_path_.DirectoryExists()) << testdata_path_.string(); EXPECT_TRUE(testdata_path_.CreateDirectoriesRecursively()); EXPECT_TRUE(testdata_path_.DirectoryExists()); } TEST_F(DirectoryCreationTest, CreateDirectoriesForAlreadyExistingPath) { EXPECT_FALSE(testdata_path_.DirectoryExists()) << testdata_path_.string(); EXPECT_TRUE(testdata_path_.CreateDirectoriesRecursively()); // Call 'create' again... should still succeed. EXPECT_TRUE(testdata_path_.CreateDirectoriesRecursively()); } TEST_F(DirectoryCreationTest, CreateDirectoriesAndUniqueFilename) { FilePath file_path(FilePath::GenerateUniqueFileName(testdata_path_, FilePath("unique"), "txt")); EXPECT_EQ(unique_file0_.string(), file_path.string()); EXPECT_FALSE(file_path.FileOrDirectoryExists()); // file not there testdata_path_.CreateDirectoriesRecursively(); EXPECT_FALSE(file_path.FileOrDirectoryExists()); // file still not there CreateTextFile(file_path.c_str()); EXPECT_TRUE(file_path.FileOrDirectoryExists()); FilePath file_path2(FilePath::GenerateUniqueFileName(testdata_path_, FilePath("unique"), "txt")); EXPECT_EQ(unique_file1_.string(), file_path2.string()); EXPECT_FALSE(file_path2.FileOrDirectoryExists()); // file not there CreateTextFile(file_path2.c_str()); EXPECT_TRUE(file_path2.FileOrDirectoryExists()); } TEST_F(DirectoryCreationTest, CreateDirectoriesFail) { // force a failure by putting a file where we will try to create a directory. CreateTextFile(testdata_file_.c_str()); EXPECT_TRUE(testdata_file_.FileOrDirectoryExists()); EXPECT_FALSE(testdata_file_.DirectoryExists()); EXPECT_FALSE(testdata_file_.CreateDirectoriesRecursively()); } TEST(NoDirectoryCreationTest, CreateNoDirectoriesForDefaultXmlFile) { const FilePath test_detail_xml("test_detail.xml"); EXPECT_FALSE(test_detail_xml.CreateDirectoriesRecursively()); } TEST(FilePathTest, DefaultConstructor) { FilePath fp; EXPECT_EQ("", fp.string()); } TEST(FilePathTest, CharAndCopyConstructors) { const FilePath fp("spicy"); EXPECT_EQ("spicy", fp.string()); const FilePath fp_copy(fp); EXPECT_EQ("spicy", fp_copy.string()); } TEST(FilePathTest, StringConstructor) { const FilePath fp(std::string("cider")); EXPECT_EQ("cider", fp.string()); } TEST(FilePathTest, Set) { const FilePath apple("apple"); FilePath mac("mac"); mac.Set(apple); // Implement Set() since overloading operator= is forbidden. EXPECT_EQ("apple", mac.string()); EXPECT_EQ("apple", apple.string()); } TEST(FilePathTest, ToString) { const FilePath file("drink"); EXPECT_EQ("drink", file.string()); } TEST(FilePathTest, RemoveExtension) { EXPECT_EQ("app", FilePath("app.cc").RemoveExtension("cc").string()); EXPECT_EQ("app", FilePath("app.exe").RemoveExtension("exe").string()); EXPECT_EQ("APP", FilePath("APP.EXE").RemoveExtension("exe").string()); } TEST(FilePathTest, RemoveExtensionWhenThereIsNoExtension) { EXPECT_EQ("app", FilePath("app").RemoveExtension("exe").string()); } TEST(FilePathTest, IsDirectory) { EXPECT_FALSE(FilePath("cola").IsDirectory()); EXPECT_TRUE(FilePath("koala" GTEST_PATH_SEP_).IsDirectory()); #if GTEST_HAS_ALT_PATH_SEP_ EXPECT_TRUE(FilePath("koala/").IsDirectory()); #endif } TEST(FilePathTest, IsAbsolutePath) { EXPECT_FALSE(FilePath("is" GTEST_PATH_SEP_ "relative").IsAbsolutePath()); EXPECT_FALSE(FilePath("").IsAbsolutePath()); #if GTEST_OS_WINDOWS EXPECT_TRUE(FilePath("c:\\" GTEST_PATH_SEP_ "is_not" GTEST_PATH_SEP_ "relative").IsAbsolutePath()); EXPECT_FALSE(FilePath("c:foo" GTEST_PATH_SEP_ "bar").IsAbsolutePath()); EXPECT_TRUE(FilePath("c:/" GTEST_PATH_SEP_ "is_not" GTEST_PATH_SEP_ "relative").IsAbsolutePath()); #else EXPECT_TRUE(FilePath(GTEST_PATH_SEP_ "is_not" GTEST_PATH_SEP_ "relative") .IsAbsolutePath()); #endif // GTEST_OS_WINDOWS } TEST(FilePathTest, IsRootDirectory) { #if GTEST_OS_WINDOWS EXPECT_TRUE(FilePath("a:\\").IsRootDirectory()); EXPECT_TRUE(FilePath("Z:/").IsRootDirectory()); EXPECT_TRUE(FilePath("e://").IsRootDirectory()); EXPECT_FALSE(FilePath("").IsRootDirectory()); EXPECT_FALSE(FilePath("b:").IsRootDirectory()); EXPECT_FALSE(FilePath("b:a").IsRootDirectory()); EXPECT_FALSE(FilePath("8:/").IsRootDirectory()); EXPECT_FALSE(FilePath("c|/").IsRootDirectory()); #else EXPECT_TRUE(FilePath("/").IsRootDirectory()); EXPECT_TRUE(FilePath("//").IsRootDirectory()); EXPECT_FALSE(FilePath("").IsRootDirectory()); EXPECT_FALSE(FilePath("\\").IsRootDirectory()); EXPECT_FALSE(FilePath("/x").IsRootDirectory()); #endif } } // namespace } // namespace internal } // namespace testing dlt-daemon-2.18.4/gtest-1.7.0/test/gtest-linked_ptr_test.cc000066400000000000000000000100351353342203500232240ustar00rootroot00000000000000// Copyright 2003, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Authors: Dan Egnor (egnor@google.com) // Ported to Windows: Vadim Berman (vadimb@google.com) #include "gtest/internal/gtest-linked_ptr.h" #include #include "gtest/gtest.h" namespace { using testing::Message; using testing::internal::linked_ptr; int num; Message* history = NULL; // Class which tracks allocation/deallocation class A { public: A(): mynum(num++) { *history << "A" << mynum << " ctor\n"; } virtual ~A() { *history << "A" << mynum << " dtor\n"; } virtual void Use() { *history << "A" << mynum << " use\n"; } protected: int mynum; }; // Subclass class B : public A { public: B() { *history << "B" << mynum << " ctor\n"; } ~B() { *history << "B" << mynum << " dtor\n"; } virtual void Use() { *history << "B" << mynum << " use\n"; } }; class LinkedPtrTest : public testing::Test { public: LinkedPtrTest() { num = 0; history = new Message; } virtual ~LinkedPtrTest() { delete history; history = NULL; } }; TEST_F(LinkedPtrTest, GeneralTest) { { linked_ptr a0, a1, a2; // Use explicit function call notation here to suppress self-assign warning. a0.operator=(a0); a1 = a2; ASSERT_EQ(a0.get(), static_cast(NULL)); ASSERT_EQ(a1.get(), static_cast(NULL)); ASSERT_EQ(a2.get(), static_cast(NULL)); ASSERT_TRUE(a0 == NULL); ASSERT_TRUE(a1 == NULL); ASSERT_TRUE(a2 == NULL); { linked_ptr a3(new A); a0 = a3; ASSERT_TRUE(a0 == a3); ASSERT_TRUE(a0 != NULL); ASSERT_TRUE(a0.get() == a3); ASSERT_TRUE(a0 == a3.get()); linked_ptr a4(a0); a1 = a4; linked_ptr a5(new A); ASSERT_TRUE(a5.get() != a3); ASSERT_TRUE(a5 != a3.get()); a2 = a5; linked_ptr b0(new B); linked_ptr a6(b0); ASSERT_TRUE(b0 == a6); ASSERT_TRUE(a6 == b0); ASSERT_TRUE(b0 != NULL); a5 = b0; a5 = b0; a3->Use(); a4->Use(); a5->Use(); a6->Use(); b0->Use(); (*b0).Use(); b0.get()->Use(); } a0->Use(); a1->Use(); a2->Use(); a1 = a2; a2.reset(new A); a0.reset(); linked_ptr a7; } ASSERT_STREQ( "A0 ctor\n" "A1 ctor\n" "A2 ctor\n" "B2 ctor\n" "A0 use\n" "A0 use\n" "B2 use\n" "B2 use\n" "B2 use\n" "B2 use\n" "B2 use\n" "B2 dtor\n" "A2 dtor\n" "A0 use\n" "A0 use\n" "A1 use\n" "A3 ctor\n" "A0 dtor\n" "A3 dtor\n" "A1 dtor\n", history->GetString().c_str()); } } // Unnamed namespace dlt-daemon-2.18.4/gtest-1.7.0/test/gtest-listener_test.cc000066400000000000000000000230671353342203500227270ustar00rootroot00000000000000// Copyright 2009 Google Inc. All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: vladl@google.com (Vlad Losev) // // The Google C++ Testing Framework (Google Test) // // This file verifies Google Test event listeners receive events at the // right times. #include "gtest/gtest.h" #include using ::testing::AddGlobalTestEnvironment; using ::testing::Environment; using ::testing::InitGoogleTest; using ::testing::Test; using ::testing::TestCase; using ::testing::TestEventListener; using ::testing::TestInfo; using ::testing::TestPartResult; using ::testing::UnitTest; // Used by tests to register their events. std::vector* g_events = NULL; namespace testing { namespace internal { class EventRecordingListener : public TestEventListener { public: explicit EventRecordingListener(const char* name) : name_(name) {} protected: virtual void OnTestProgramStart(const UnitTest& /*unit_test*/) { g_events->push_back(GetFullMethodName("OnTestProgramStart")); } virtual void OnTestIterationStart(const UnitTest& /*unit_test*/, int iteration) { Message message; message << GetFullMethodName("OnTestIterationStart") << "(" << iteration << ")"; g_events->push_back(message.GetString()); } virtual void OnEnvironmentsSetUpStart(const UnitTest& /*unit_test*/) { g_events->push_back(GetFullMethodName("OnEnvironmentsSetUpStart")); } virtual void OnEnvironmentsSetUpEnd(const UnitTest& /*unit_test*/) { g_events->push_back(GetFullMethodName("OnEnvironmentsSetUpEnd")); } virtual void OnTestCaseStart(const TestCase& /*test_case*/) { g_events->push_back(GetFullMethodName("OnTestCaseStart")); } virtual void OnTestStart(const TestInfo& /*test_info*/) { g_events->push_back(GetFullMethodName("OnTestStart")); } virtual void OnTestPartResult(const TestPartResult& /*test_part_result*/) { g_events->push_back(GetFullMethodName("OnTestPartResult")); } virtual void OnTestEnd(const TestInfo& /*test_info*/) { g_events->push_back(GetFullMethodName("OnTestEnd")); } virtual void OnTestCaseEnd(const TestCase& /*test_case*/) { g_events->push_back(GetFullMethodName("OnTestCaseEnd")); } virtual void OnEnvironmentsTearDownStart(const UnitTest& /*unit_test*/) { g_events->push_back(GetFullMethodName("OnEnvironmentsTearDownStart")); } virtual void OnEnvironmentsTearDownEnd(const UnitTest& /*unit_test*/) { g_events->push_back(GetFullMethodName("OnEnvironmentsTearDownEnd")); } virtual void OnTestIterationEnd(const UnitTest& /*unit_test*/, int iteration) { Message message; message << GetFullMethodName("OnTestIterationEnd") << "(" << iteration << ")"; g_events->push_back(message.GetString()); } virtual void OnTestProgramEnd(const UnitTest& /*unit_test*/) { g_events->push_back(GetFullMethodName("OnTestProgramEnd")); } private: std::string GetFullMethodName(const char* name) { return name_ + "." + name; } std::string name_; }; class EnvironmentInvocationCatcher : public Environment { protected: virtual void SetUp() { g_events->push_back("Environment::SetUp"); } virtual void TearDown() { g_events->push_back("Environment::TearDown"); } }; class ListenerTest : public Test { protected: static void SetUpTestCase() { g_events->push_back("ListenerTest::SetUpTestCase"); } static void TearDownTestCase() { g_events->push_back("ListenerTest::TearDownTestCase"); } virtual void SetUp() { g_events->push_back("ListenerTest::SetUp"); } virtual void TearDown() { g_events->push_back("ListenerTest::TearDown"); } }; TEST_F(ListenerTest, DoesFoo) { // Test execution order within a test case is not guaranteed so we are not // recording the test name. g_events->push_back("ListenerTest::* Test Body"); SUCCEED(); // Triggers OnTestPartResult. } TEST_F(ListenerTest, DoesBar) { g_events->push_back("ListenerTest::* Test Body"); SUCCEED(); // Triggers OnTestPartResult. } } // namespace internal } // namespace testing using ::testing::internal::EnvironmentInvocationCatcher; using ::testing::internal::EventRecordingListener; void VerifyResults(const std::vector& data, const char* const* expected_data, int expected_data_size) { const int actual_size = data.size(); // If the following assertion fails, a new entry will be appended to // data. Hence we save data.size() first. EXPECT_EQ(expected_data_size, actual_size); // Compares the common prefix. const int shorter_size = expected_data_size <= actual_size ? expected_data_size : actual_size; int i = 0; for (; i < shorter_size; ++i) { ASSERT_STREQ(expected_data[i], data[i].c_str()) << "at position " << i; } // Prints extra elements in the actual data. for (; i < actual_size; ++i) { printf(" Actual event #%d: %s\n", i, data[i].c_str()); } } int main(int argc, char **argv) { std::vector events; g_events = &events; InitGoogleTest(&argc, argv); UnitTest::GetInstance()->listeners().Append( new EventRecordingListener("1st")); UnitTest::GetInstance()->listeners().Append( new EventRecordingListener("2nd")); AddGlobalTestEnvironment(new EnvironmentInvocationCatcher); GTEST_CHECK_(events.size() == 0) << "AddGlobalTestEnvironment should not generate any events itself."; ::testing::GTEST_FLAG(repeat) = 2; int ret_val = RUN_ALL_TESTS(); const char* const expected_events[] = { "1st.OnTestProgramStart", "2nd.OnTestProgramStart", "1st.OnTestIterationStart(0)", "2nd.OnTestIterationStart(0)", "1st.OnEnvironmentsSetUpStart", "2nd.OnEnvironmentsSetUpStart", "Environment::SetUp", "2nd.OnEnvironmentsSetUpEnd", "1st.OnEnvironmentsSetUpEnd", "1st.OnTestCaseStart", "2nd.OnTestCaseStart", "ListenerTest::SetUpTestCase", "1st.OnTestStart", "2nd.OnTestStart", "ListenerTest::SetUp", "ListenerTest::* Test Body", "1st.OnTestPartResult", "2nd.OnTestPartResult", "ListenerTest::TearDown", "2nd.OnTestEnd", "1st.OnTestEnd", "1st.OnTestStart", "2nd.OnTestStart", "ListenerTest::SetUp", "ListenerTest::* Test Body", "1st.OnTestPartResult", "2nd.OnTestPartResult", "ListenerTest::TearDown", "2nd.OnTestEnd", "1st.OnTestEnd", "ListenerTest::TearDownTestCase", "2nd.OnTestCaseEnd", "1st.OnTestCaseEnd", "1st.OnEnvironmentsTearDownStart", "2nd.OnEnvironmentsTearDownStart", "Environment::TearDown", "2nd.OnEnvironmentsTearDownEnd", "1st.OnEnvironmentsTearDownEnd", "2nd.OnTestIterationEnd(0)", "1st.OnTestIterationEnd(0)", "1st.OnTestIterationStart(1)", "2nd.OnTestIterationStart(1)", "1st.OnEnvironmentsSetUpStart", "2nd.OnEnvironmentsSetUpStart", "Environment::SetUp", "2nd.OnEnvironmentsSetUpEnd", "1st.OnEnvironmentsSetUpEnd", "1st.OnTestCaseStart", "2nd.OnTestCaseStart", "ListenerTest::SetUpTestCase", "1st.OnTestStart", "2nd.OnTestStart", "ListenerTest::SetUp", "ListenerTest::* Test Body", "1st.OnTestPartResult", "2nd.OnTestPartResult", "ListenerTest::TearDown", "2nd.OnTestEnd", "1st.OnTestEnd", "1st.OnTestStart", "2nd.OnTestStart", "ListenerTest::SetUp", "ListenerTest::* Test Body", "1st.OnTestPartResult", "2nd.OnTestPartResult", "ListenerTest::TearDown", "2nd.OnTestEnd", "1st.OnTestEnd", "ListenerTest::TearDownTestCase", "2nd.OnTestCaseEnd", "1st.OnTestCaseEnd", "1st.OnEnvironmentsTearDownStart", "2nd.OnEnvironmentsTearDownStart", "Environment::TearDown", "2nd.OnEnvironmentsTearDownEnd", "1st.OnEnvironmentsTearDownEnd", "2nd.OnTestIterationEnd(1)", "1st.OnTestIterationEnd(1)", "2nd.OnTestProgramEnd", "1st.OnTestProgramEnd" }; VerifyResults(events, expected_events, sizeof(expected_events)/sizeof(expected_events[0])); // We need to check manually for ad hoc test failures that happen after // RUN_ALL_TESTS finishes. if (UnitTest::GetInstance()->Failed()) ret_val = 1; return ret_val; } dlt-daemon-2.18.4/gtest-1.7.0/test/gtest-message_test.cc000066400000000000000000000122661353342203500225250ustar00rootroot00000000000000// Copyright 2005, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: wan@google.com (Zhanyong Wan) // // Tests for the Message class. #include "gtest/gtest-message.h" #include "gtest/gtest.h" namespace { using ::testing::Message; // Tests the testing::Message class // Tests the default constructor. TEST(MessageTest, DefaultConstructor) { const Message msg; EXPECT_EQ("", msg.GetString()); } // Tests the copy constructor. TEST(MessageTest, CopyConstructor) { const Message msg1("Hello"); const Message msg2(msg1); EXPECT_EQ("Hello", msg2.GetString()); } // Tests constructing a Message from a C-string. TEST(MessageTest, ConstructsFromCString) { Message msg("Hello"); EXPECT_EQ("Hello", msg.GetString()); } // Tests streaming a float. TEST(MessageTest, StreamsFloat) { const std::string s = (Message() << 1.23456F << " " << 2.34567F).GetString(); // Both numbers should be printed with enough precision. EXPECT_PRED_FORMAT2(testing::IsSubstring, "1.234560", s.c_str()); EXPECT_PRED_FORMAT2(testing::IsSubstring, " 2.345669", s.c_str()); } // Tests streaming a double. TEST(MessageTest, StreamsDouble) { const std::string s = (Message() << 1260570880.4555497 << " " << 1260572265.1954534).GetString(); // Both numbers should be printed with enough precision. EXPECT_PRED_FORMAT2(testing::IsSubstring, "1260570880.45", s.c_str()); EXPECT_PRED_FORMAT2(testing::IsSubstring, " 1260572265.19", s.c_str()); } // Tests streaming a non-char pointer. TEST(MessageTest, StreamsPointer) { int n = 0; int* p = &n; EXPECT_NE("(null)", (Message() << p).GetString()); } // Tests streaming a NULL non-char pointer. TEST(MessageTest, StreamsNullPointer) { int* p = NULL; EXPECT_EQ("(null)", (Message() << p).GetString()); } // Tests streaming a C string. TEST(MessageTest, StreamsCString) { EXPECT_EQ("Foo", (Message() << "Foo").GetString()); } // Tests streaming a NULL C string. TEST(MessageTest, StreamsNullCString) { char* p = NULL; EXPECT_EQ("(null)", (Message() << p).GetString()); } // Tests streaming std::string. TEST(MessageTest, StreamsString) { const ::std::string str("Hello"); EXPECT_EQ("Hello", (Message() << str).GetString()); } // Tests that we can output strings containing embedded NULs. TEST(MessageTest, StreamsStringWithEmbeddedNUL) { const char char_array_with_nul[] = "Here's a NUL\0 and some more string"; const ::std::string string_with_nul(char_array_with_nul, sizeof(char_array_with_nul) - 1); EXPECT_EQ("Here's a NUL\\0 and some more string", (Message() << string_with_nul).GetString()); } // Tests streaming a NUL char. TEST(MessageTest, StreamsNULChar) { EXPECT_EQ("\\0", (Message() << '\0').GetString()); } // Tests streaming int. TEST(MessageTest, StreamsInt) { EXPECT_EQ("123", (Message() << 123).GetString()); } // Tests that basic IO manipulators (endl, ends, and flush) can be // streamed to Message. TEST(MessageTest, StreamsBasicIoManip) { EXPECT_EQ("Line 1.\nA NUL char \\0 in line 2.", (Message() << "Line 1." << std::endl << "A NUL char " << std::ends << std::flush << " in line 2.").GetString()); } // Tests Message::GetString() TEST(MessageTest, GetString) { Message msg; msg << 1 << " lamb"; EXPECT_EQ("1 lamb", msg.GetString()); } // Tests streaming a Message object to an ostream. TEST(MessageTest, StreamsToOStream) { Message msg("Hello"); ::std::stringstream ss; ss << msg; EXPECT_EQ("Hello", testing::internal::StringStreamToString(&ss)); } // Tests that a Message object doesn't take up too much stack space. TEST(MessageTest, DoesNotTakeUpMuchStackSpace) { EXPECT_LE(sizeof(Message), 16U); } } // namespace dlt-daemon-2.18.4/gtest-1.7.0/test/gtest-options_test.cc000066400000000000000000000174021353342203500225710ustar00rootroot00000000000000// Copyright 2008, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Authors: keith.ray@gmail.com (Keith Ray) // // Google Test UnitTestOptions tests // // This file tests classes and functions used internally by // Google Test. They are subject to change without notice. // // This file is #included from gtest.cc, to avoid changing build or // make-files on Windows and other platforms. Do not #include this file // anywhere else! #include "gtest/gtest.h" #if GTEST_OS_WINDOWS_MOBILE # include #elif GTEST_OS_WINDOWS # include #endif // GTEST_OS_WINDOWS_MOBILE // Indicates that this translation unit is part of Google Test's // implementation. It must come before gtest-internal-inl.h is // included, or there will be a compiler error. This trick is to // prevent a user from accidentally including gtest-internal-inl.h in // his code. #define GTEST_IMPLEMENTATION_ 1 #include "src/gtest-internal-inl.h" #undef GTEST_IMPLEMENTATION_ namespace testing { namespace internal { namespace { // Turns the given relative path into an absolute path. FilePath GetAbsolutePathOf(const FilePath& relative_path) { return FilePath::ConcatPaths(FilePath::GetCurrentDir(), relative_path); } // Testing UnitTestOptions::GetOutputFormat/GetOutputFile. TEST(XmlOutputTest, GetOutputFormatDefault) { GTEST_FLAG(output) = ""; EXPECT_STREQ("", UnitTestOptions::GetOutputFormat().c_str()); } TEST(XmlOutputTest, GetOutputFormat) { GTEST_FLAG(output) = "xml:filename"; EXPECT_STREQ("xml", UnitTestOptions::GetOutputFormat().c_str()); } TEST(XmlOutputTest, GetOutputFileDefault) { GTEST_FLAG(output) = ""; EXPECT_EQ(GetAbsolutePathOf(FilePath("test_detail.xml")).string(), UnitTestOptions::GetAbsolutePathToOutputFile()); } TEST(XmlOutputTest, GetOutputFileSingleFile) { GTEST_FLAG(output) = "xml:filename.abc"; EXPECT_EQ(GetAbsolutePathOf(FilePath("filename.abc")).string(), UnitTestOptions::GetAbsolutePathToOutputFile()); } TEST(XmlOutputTest, GetOutputFileFromDirectoryPath) { GTEST_FLAG(output) = "xml:path" GTEST_PATH_SEP_; const std::string expected_output_file = GetAbsolutePathOf( FilePath(std::string("path") + GTEST_PATH_SEP_ + GetCurrentExecutableName().string() + ".xml")).string(); const std::string& output_file = UnitTestOptions::GetAbsolutePathToOutputFile(); #if GTEST_OS_WINDOWS EXPECT_STRCASEEQ(expected_output_file.c_str(), output_file.c_str()); #else EXPECT_EQ(expected_output_file, output_file.c_str()); #endif } TEST(OutputFileHelpersTest, GetCurrentExecutableName) { const std::string exe_str = GetCurrentExecutableName().string(); #if GTEST_OS_WINDOWS const bool success = _strcmpi("gtest-options_test", exe_str.c_str()) == 0 || _strcmpi("gtest-options-ex_test", exe_str.c_str()) == 0 || _strcmpi("gtest_all_test", exe_str.c_str()) == 0 || _strcmpi("gtest_dll_test", exe_str.c_str()) == 0; #else // TODO(wan@google.com): remove the hard-coded "lt-" prefix when // Chandler Carruth's libtool replacement is ready. const bool success = exe_str == "gtest-options_test" || exe_str == "gtest_all_test" || exe_str == "lt-gtest_all_test" || exe_str == "gtest_dll_test"; #endif // GTEST_OS_WINDOWS if (!success) FAIL() << "GetCurrentExecutableName() returns " << exe_str; } class XmlOutputChangeDirTest : public Test { protected: virtual void SetUp() { original_working_dir_ = FilePath::GetCurrentDir(); posix::ChDir(".."); // This will make the test fail if run from the root directory. EXPECT_NE(original_working_dir_.string(), FilePath::GetCurrentDir().string()); } virtual void TearDown() { posix::ChDir(original_working_dir_.string().c_str()); } FilePath original_working_dir_; }; TEST_F(XmlOutputChangeDirTest, PreserveOriginalWorkingDirWithDefault) { GTEST_FLAG(output) = ""; EXPECT_EQ(FilePath::ConcatPaths(original_working_dir_, FilePath("test_detail.xml")).string(), UnitTestOptions::GetAbsolutePathToOutputFile()); } TEST_F(XmlOutputChangeDirTest, PreserveOriginalWorkingDirWithDefaultXML) { GTEST_FLAG(output) = "xml"; EXPECT_EQ(FilePath::ConcatPaths(original_working_dir_, FilePath("test_detail.xml")).string(), UnitTestOptions::GetAbsolutePathToOutputFile()); } TEST_F(XmlOutputChangeDirTest, PreserveOriginalWorkingDirWithRelativeFile) { GTEST_FLAG(output) = "xml:filename.abc"; EXPECT_EQ(FilePath::ConcatPaths(original_working_dir_, FilePath("filename.abc")).string(), UnitTestOptions::GetAbsolutePathToOutputFile()); } TEST_F(XmlOutputChangeDirTest, PreserveOriginalWorkingDirWithRelativePath) { GTEST_FLAG(output) = "xml:path" GTEST_PATH_SEP_; const std::string expected_output_file = FilePath::ConcatPaths( original_working_dir_, FilePath(std::string("path") + GTEST_PATH_SEP_ + GetCurrentExecutableName().string() + ".xml")).string(); const std::string& output_file = UnitTestOptions::GetAbsolutePathToOutputFile(); #if GTEST_OS_WINDOWS EXPECT_STRCASEEQ(expected_output_file.c_str(), output_file.c_str()); #else EXPECT_EQ(expected_output_file, output_file.c_str()); #endif } TEST_F(XmlOutputChangeDirTest, PreserveOriginalWorkingDirWithAbsoluteFile) { #if GTEST_OS_WINDOWS GTEST_FLAG(output) = "xml:c:\\tmp\\filename.abc"; EXPECT_EQ(FilePath("c:\\tmp\\filename.abc").string(), UnitTestOptions::GetAbsolutePathToOutputFile()); #else GTEST_FLAG(output) ="xml:/tmp/filename.abc"; EXPECT_EQ(FilePath("/tmp/filename.abc").string(), UnitTestOptions::GetAbsolutePathToOutputFile()); #endif } TEST_F(XmlOutputChangeDirTest, PreserveOriginalWorkingDirWithAbsolutePath) { #if GTEST_OS_WINDOWS const std::string path = "c:\\tmp\\"; #else const std::string path = "/tmp/"; #endif GTEST_FLAG(output) = "xml:" + path; const std::string expected_output_file = path + GetCurrentExecutableName().string() + ".xml"; const std::string& output_file = UnitTestOptions::GetAbsolutePathToOutputFile(); #if GTEST_OS_WINDOWS EXPECT_STRCASEEQ(expected_output_file.c_str(), output_file.c_str()); #else EXPECT_EQ(expected_output_file, output_file.c_str()); #endif } } // namespace } // namespace internal } // namespace testing dlt-daemon-2.18.4/gtest-1.7.0/test/gtest-param-test2_test.cc000066400000000000000000000055041353342203500232350ustar00rootroot00000000000000// Copyright 2008, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: vladl@google.com (Vlad Losev) // // Tests for Google Test itself. This verifies that the basic constructs of // Google Test work. #include "gtest/gtest.h" #include "test/gtest-param-test_test.h" #if GTEST_HAS_PARAM_TEST using ::testing::Values; using ::testing::internal::ParamGenerator; // Tests that generators defined in a different translation unit // are functional. The test using extern_gen is defined // in gtest-param-test_test.cc. ParamGenerator extern_gen = Values(33); // Tests that a parameterized test case can be defined in one translation unit // and instantiated in another. The test is defined in gtest-param-test_test.cc // and ExternalInstantiationTest fixture class is defined in // gtest-param-test_test.h. INSTANTIATE_TEST_CASE_P(MultiplesOf33, ExternalInstantiationTest, Values(33, 66)); // Tests that a parameterized test case can be instantiated // in multiple translation units. Another instantiation is defined // in gtest-param-test_test.cc and InstantiationInMultipleTranslaionUnitsTest // fixture is defined in gtest-param-test_test.h INSTANTIATE_TEST_CASE_P(Sequence2, InstantiationInMultipleTranslaionUnitsTest, Values(42*3, 42*4, 42*5)); #endif // GTEST_HAS_PARAM_TEST dlt-daemon-2.18.4/gtest-1.7.0/test/gtest-param-test_test.cc000066400000000000000000001011021353342203500231420ustar00rootroot00000000000000// Copyright 2008, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: vladl@google.com (Vlad Losev) // // Tests for Google Test itself. This file verifies that the parameter // generators objects produce correct parameter sequences and that // Google Test runtime instantiates correct tests from those sequences. #include "gtest/gtest.h" #if GTEST_HAS_PARAM_TEST # include # include # include # include # include # include // To include gtest-internal-inl.h. # define GTEST_IMPLEMENTATION_ 1 # include "src/gtest-internal-inl.h" // for UnitTestOptions # undef GTEST_IMPLEMENTATION_ # include "test/gtest-param-test_test.h" using ::std::vector; using ::std::sort; using ::testing::AddGlobalTestEnvironment; using ::testing::Bool; using ::testing::Message; using ::testing::Range; using ::testing::TestWithParam; using ::testing::Values; using ::testing::ValuesIn; # if GTEST_HAS_COMBINE using ::testing::Combine; using ::std::tr1::get; using ::std::tr1::make_tuple; using ::std::tr1::tuple; # endif // GTEST_HAS_COMBINE using ::testing::internal::ParamGenerator; using ::testing::internal::UnitTestOptions; // Prints a value to a string. // // TODO(wan@google.com): remove PrintValue() when we move matchers and // EXPECT_THAT() from Google Mock to Google Test. At that time, we // can write EXPECT_THAT(x, Eq(y)) to compare two tuples x and y, as // EXPECT_THAT() and the matchers know how to print tuples. template ::std::string PrintValue(const T& value) { ::std::stringstream stream; stream << value; return stream.str(); } # if GTEST_HAS_COMBINE // These overloads allow printing tuples in our tests. We cannot // define an operator<< for tuples, as that definition needs to be in // the std namespace in order to be picked up by Google Test via // Argument-Dependent Lookup, yet defining anything in the std // namespace in non-STL code is undefined behavior. template ::std::string PrintValue(const tuple& value) { ::std::stringstream stream; stream << "(" << get<0>(value) << ", " << get<1>(value) << ")"; return stream.str(); } template ::std::string PrintValue(const tuple& value) { ::std::stringstream stream; stream << "(" << get<0>(value) << ", " << get<1>(value) << ", "<< get<2>(value) << ")"; return stream.str(); } template ::std::string PrintValue( const tuple& value) { ::std::stringstream stream; stream << "(" << get<0>(value) << ", " << get<1>(value) << ", "<< get<2>(value) << ", " << get<3>(value) << ", "<< get<4>(value) << ", " << get<5>(value) << ", "<< get<6>(value) << ", " << get<7>(value) << ", "<< get<8>(value) << ", " << get<9>(value) << ")"; return stream.str(); } # endif // GTEST_HAS_COMBINE // Verifies that a sequence generated by the generator and accessed // via the iterator object matches the expected one using Google Test // assertions. template void VerifyGenerator(const ParamGenerator& generator, const T (&expected_values)[N]) { typename ParamGenerator::iterator it = generator.begin(); for (size_t i = 0; i < N; ++i) { ASSERT_FALSE(it == generator.end()) << "At element " << i << " when accessing via an iterator " << "created with the copy constructor.\n"; // We cannot use EXPECT_EQ() here as the values may be tuples, // which don't support <<. EXPECT_TRUE(expected_values[i] == *it) << "where i is " << i << ", expected_values[i] is " << PrintValue(expected_values[i]) << ", *it is " << PrintValue(*it) << ", and 'it' is an iterator created with the copy constructor.\n"; it++; } EXPECT_TRUE(it == generator.end()) << "At the presumed end of sequence when accessing via an iterator " << "created with the copy constructor.\n"; // Test the iterator assignment. The following lines verify that // the sequence accessed via an iterator initialized via the // assignment operator (as opposed to a copy constructor) matches // just the same. it = generator.begin(); for (size_t i = 0; i < N; ++i) { ASSERT_FALSE(it == generator.end()) << "At element " << i << " when accessing via an iterator " << "created with the assignment operator.\n"; EXPECT_TRUE(expected_values[i] == *it) << "where i is " << i << ", expected_values[i] is " << PrintValue(expected_values[i]) << ", *it is " << PrintValue(*it) << ", and 'it' is an iterator created with the copy constructor.\n"; it++; } EXPECT_TRUE(it == generator.end()) << "At the presumed end of sequence when accessing via an iterator " << "created with the assignment operator.\n"; } template void VerifyGeneratorIsEmpty(const ParamGenerator& generator) { typename ParamGenerator::iterator it = generator.begin(); EXPECT_TRUE(it == generator.end()); it = generator.begin(); EXPECT_TRUE(it == generator.end()); } // Generator tests. They test that each of the provided generator functions // generates an expected sequence of values. The general test pattern // instantiates a generator using one of the generator functions, // checks the sequence produced by the generator using its iterator API, // and then resets the iterator back to the beginning of the sequence // and checks the sequence again. // Tests that iterators produced by generator functions conform to the // ForwardIterator concept. TEST(IteratorTest, ParamIteratorConformsToForwardIteratorConcept) { const ParamGenerator gen = Range(0, 10); ParamGenerator::iterator it = gen.begin(); // Verifies that iterator initialization works as expected. ParamGenerator::iterator it2 = it; EXPECT_TRUE(*it == *it2) << "Initialized iterators must point to the " << "element same as its source points to"; // Verifies that iterator assignment works as expected. it++; EXPECT_FALSE(*it == *it2); it2 = it; EXPECT_TRUE(*it == *it2) << "Assigned iterators must point to the " << "element same as its source points to"; // Verifies that prefix operator++() returns *this. EXPECT_EQ(&it, &(++it)) << "Result of the prefix operator++ must be " << "refer to the original object"; // Verifies that the result of the postfix operator++ points to the value // pointed to by the original iterator. int original_value = *it; // Have to compute it outside of macro call to be // unaffected by the parameter evaluation order. EXPECT_EQ(original_value, *(it++)); // Verifies that prefix and postfix operator++() advance an iterator // all the same. it2 = it; it++; ++it2; EXPECT_TRUE(*it == *it2); } // Tests that Range() generates the expected sequence. TEST(RangeTest, IntRangeWithDefaultStep) { const ParamGenerator gen = Range(0, 3); const int expected_values[] = {0, 1, 2}; VerifyGenerator(gen, expected_values); } // Edge case. Tests that Range() generates the single element sequence // as expected when provided with range limits that are equal. TEST(RangeTest, IntRangeSingleValue) { const ParamGenerator gen = Range(0, 1); const int expected_values[] = {0}; VerifyGenerator(gen, expected_values); } // Edge case. Tests that Range() with generates empty sequence when // supplied with an empty range. TEST(RangeTest, IntRangeEmpty) { const ParamGenerator gen = Range(0, 0); VerifyGeneratorIsEmpty(gen); } // Tests that Range() with custom step (greater then one) generates // the expected sequence. TEST(RangeTest, IntRangeWithCustomStep) { const ParamGenerator gen = Range(0, 9, 3); const int expected_values[] = {0, 3, 6}; VerifyGenerator(gen, expected_values); } // Tests that Range() with custom step (greater then one) generates // the expected sequence when the last element does not fall on the // upper range limit. Sequences generated by Range() must not have // elements beyond the range limits. TEST(RangeTest, IntRangeWithCustomStepOverUpperBound) { const ParamGenerator gen = Range(0, 4, 3); const int expected_values[] = {0, 3}; VerifyGenerator(gen, expected_values); } // Verifies that Range works with user-defined types that define // copy constructor, operator=(), operator+(), and operator<(). class DogAdder { public: explicit DogAdder(const char* a_value) : value_(a_value) {} DogAdder(const DogAdder& other) : value_(other.value_.c_str()) {} DogAdder operator=(const DogAdder& other) { if (this != &other) value_ = other.value_; return *this; } DogAdder operator+(const DogAdder& other) const { Message msg; msg << value_.c_str() << other.value_.c_str(); return DogAdder(msg.GetString().c_str()); } bool operator<(const DogAdder& other) const { return value_ < other.value_; } const std::string& value() const { return value_; } private: std::string value_; }; TEST(RangeTest, WorksWithACustomType) { const ParamGenerator gen = Range(DogAdder("cat"), DogAdder("catdogdog"), DogAdder("dog")); ParamGenerator::iterator it = gen.begin(); ASSERT_FALSE(it == gen.end()); EXPECT_STREQ("cat", it->value().c_str()); ASSERT_FALSE(++it == gen.end()); EXPECT_STREQ("catdog", it->value().c_str()); EXPECT_TRUE(++it == gen.end()); } class IntWrapper { public: explicit IntWrapper(int a_value) : value_(a_value) {} IntWrapper(const IntWrapper& other) : value_(other.value_) {} IntWrapper operator=(const IntWrapper& other) { value_ = other.value_; return *this; } // operator+() adds a different type. IntWrapper operator+(int other) const { return IntWrapper(value_ + other); } bool operator<(const IntWrapper& other) const { return value_ < other.value_; } int value() const { return value_; } private: int value_; }; TEST(RangeTest, WorksWithACustomTypeWithDifferentIncrementType) { const ParamGenerator gen = Range(IntWrapper(0), IntWrapper(2)); ParamGenerator::iterator it = gen.begin(); ASSERT_FALSE(it == gen.end()); EXPECT_EQ(0, it->value()); ASSERT_FALSE(++it == gen.end()); EXPECT_EQ(1, it->value()); EXPECT_TRUE(++it == gen.end()); } // Tests that ValuesIn() with an array parameter generates // the expected sequence. TEST(ValuesInTest, ValuesInArray) { int array[] = {3, 5, 8}; const ParamGenerator gen = ValuesIn(array); VerifyGenerator(gen, array); } // Tests that ValuesIn() with a const array parameter generates // the expected sequence. TEST(ValuesInTest, ValuesInConstArray) { const int array[] = {3, 5, 8}; const ParamGenerator gen = ValuesIn(array); VerifyGenerator(gen, array); } // Edge case. Tests that ValuesIn() with an array parameter containing a // single element generates the single element sequence. TEST(ValuesInTest, ValuesInSingleElementArray) { int array[] = {42}; const ParamGenerator gen = ValuesIn(array); VerifyGenerator(gen, array); } // Tests that ValuesIn() generates the expected sequence for an STL // container (vector). TEST(ValuesInTest, ValuesInVector) { typedef ::std::vector ContainerType; ContainerType values; values.push_back(3); values.push_back(5); values.push_back(8); const ParamGenerator gen = ValuesIn(values); const int expected_values[] = {3, 5, 8}; VerifyGenerator(gen, expected_values); } // Tests that ValuesIn() generates the expected sequence. TEST(ValuesInTest, ValuesInIteratorRange) { typedef ::std::vector ContainerType; ContainerType values; values.push_back(3); values.push_back(5); values.push_back(8); const ParamGenerator gen = ValuesIn(values.begin(), values.end()); const int expected_values[] = {3, 5, 8}; VerifyGenerator(gen, expected_values); } // Edge case. Tests that ValuesIn() provided with an iterator range specifying a // single value generates a single-element sequence. TEST(ValuesInTest, ValuesInSingleElementIteratorRange) { typedef ::std::vector ContainerType; ContainerType values; values.push_back(42); const ParamGenerator gen = ValuesIn(values.begin(), values.end()); const int expected_values[] = {42}; VerifyGenerator(gen, expected_values); } // Edge case. Tests that ValuesIn() provided with an empty iterator range // generates an empty sequence. TEST(ValuesInTest, ValuesInEmptyIteratorRange) { typedef ::std::vector ContainerType; ContainerType values; const ParamGenerator gen = ValuesIn(values.begin(), values.end()); VerifyGeneratorIsEmpty(gen); } // Tests that the Values() generates the expected sequence. TEST(ValuesTest, ValuesWorks) { const ParamGenerator gen = Values(3, 5, 8); const int expected_values[] = {3, 5, 8}; VerifyGenerator(gen, expected_values); } // Tests that Values() generates the expected sequences from elements of // different types convertible to ParamGenerator's parameter type. TEST(ValuesTest, ValuesWorksForValuesOfCompatibleTypes) { const ParamGenerator gen = Values(3, 5.0f, 8.0); const double expected_values[] = {3.0, 5.0, 8.0}; VerifyGenerator(gen, expected_values); } TEST(ValuesTest, ValuesWorksForMaxLengthList) { const ParamGenerator gen = Values( 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160, 170, 180, 190, 200, 210, 220, 230, 240, 250, 260, 270, 280, 290, 300, 310, 320, 330, 340, 350, 360, 370, 380, 390, 400, 410, 420, 430, 440, 450, 460, 470, 480, 490, 500); const int expected_values[] = { 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160, 170, 180, 190, 200, 210, 220, 230, 240, 250, 260, 270, 280, 290, 300, 310, 320, 330, 340, 350, 360, 370, 380, 390, 400, 410, 420, 430, 440, 450, 460, 470, 480, 490, 500}; VerifyGenerator(gen, expected_values); } // Edge case test. Tests that single-parameter Values() generates the sequence // with the single value. TEST(ValuesTest, ValuesWithSingleParameter) { const ParamGenerator gen = Values(42); const int expected_values[] = {42}; VerifyGenerator(gen, expected_values); } // Tests that Bool() generates sequence (false, true). TEST(BoolTest, BoolWorks) { const ParamGenerator gen = Bool(); const bool expected_values[] = {false, true}; VerifyGenerator(gen, expected_values); } # if GTEST_HAS_COMBINE // Tests that Combine() with two parameters generates the expected sequence. TEST(CombineTest, CombineWithTwoParameters) { const char* foo = "foo"; const char* bar = "bar"; const ParamGenerator > gen = Combine(Values(foo, bar), Values(3, 4)); tuple expected_values[] = { make_tuple(foo, 3), make_tuple(foo, 4), make_tuple(bar, 3), make_tuple(bar, 4)}; VerifyGenerator(gen, expected_values); } // Tests that Combine() with three parameters generates the expected sequence. TEST(CombineTest, CombineWithThreeParameters) { const ParamGenerator > gen = Combine(Values(0, 1), Values(3, 4), Values(5, 6)); tuple expected_values[] = { make_tuple(0, 3, 5), make_tuple(0, 3, 6), make_tuple(0, 4, 5), make_tuple(0, 4, 6), make_tuple(1, 3, 5), make_tuple(1, 3, 6), make_tuple(1, 4, 5), make_tuple(1, 4, 6)}; VerifyGenerator(gen, expected_values); } // Tests that the Combine() with the first parameter generating a single value // sequence generates a sequence with the number of elements equal to the // number of elements in the sequence generated by the second parameter. TEST(CombineTest, CombineWithFirstParameterSingleValue) { const ParamGenerator > gen = Combine(Values(42), Values(0, 1)); tuple expected_values[] = {make_tuple(42, 0), make_tuple(42, 1)}; VerifyGenerator(gen, expected_values); } // Tests that the Combine() with the second parameter generating a single value // sequence generates a sequence with the number of elements equal to the // number of elements in the sequence generated by the first parameter. TEST(CombineTest, CombineWithSecondParameterSingleValue) { const ParamGenerator > gen = Combine(Values(0, 1), Values(42)); tuple expected_values[] = {make_tuple(0, 42), make_tuple(1, 42)}; VerifyGenerator(gen, expected_values); } // Tests that when the first parameter produces an empty sequence, // Combine() produces an empty sequence, too. TEST(CombineTest, CombineWithFirstParameterEmptyRange) { const ParamGenerator > gen = Combine(Range(0, 0), Values(0, 1)); VerifyGeneratorIsEmpty(gen); } // Tests that when the second parameter produces an empty sequence, // Combine() produces an empty sequence, too. TEST(CombineTest, CombineWithSecondParameterEmptyRange) { const ParamGenerator > gen = Combine(Values(0, 1), Range(1, 1)); VerifyGeneratorIsEmpty(gen); } // Edge case. Tests that combine works with the maximum number // of parameters supported by Google Test (currently 10). TEST(CombineTest, CombineWithMaxNumberOfParameters) { const char* foo = "foo"; const char* bar = "bar"; const ParamGenerator > gen = Combine(Values(foo, bar), Values(1), Values(2), Values(3), Values(4), Values(5), Values(6), Values(7), Values(8), Values(9)); tuple expected_values[] = {make_tuple(foo, 1, 2, 3, 4, 5, 6, 7, 8, 9), make_tuple(bar, 1, 2, 3, 4, 5, 6, 7, 8, 9)}; VerifyGenerator(gen, expected_values); } # endif // GTEST_HAS_COMBINE // Tests that an generator produces correct sequence after being // assigned from another generator. TEST(ParamGeneratorTest, AssignmentWorks) { ParamGenerator gen = Values(1, 2); const ParamGenerator gen2 = Values(3, 4); gen = gen2; const int expected_values[] = {3, 4}; VerifyGenerator(gen, expected_values); } // This test verifies that the tests are expanded and run as specified: // one test per element from the sequence produced by the generator // specified in INSTANTIATE_TEST_CASE_P. It also verifies that the test's // fixture constructor, SetUp(), and TearDown() have run and have been // supplied with the correct parameters. // The use of environment object allows detection of the case where no test // case functionality is run at all. In this case TestCaseTearDown will not // be able to detect missing tests, naturally. template class TestGenerationEnvironment : public ::testing::Environment { public: static TestGenerationEnvironment* Instance() { static TestGenerationEnvironment* instance = new TestGenerationEnvironment; return instance; } void FixtureConstructorExecuted() { fixture_constructor_count_++; } void SetUpExecuted() { set_up_count_++; } void TearDownExecuted() { tear_down_count_++; } void TestBodyExecuted() { test_body_count_++; } virtual void TearDown() { // If all MultipleTestGenerationTest tests have been de-selected // by the filter flag, the following checks make no sense. bool perform_check = false; for (int i = 0; i < kExpectedCalls; ++i) { Message msg; msg << "TestsExpandedAndRun/" << i; if (UnitTestOptions::FilterMatchesTest( "TestExpansionModule/MultipleTestGenerationTest", msg.GetString().c_str())) { perform_check = true; } } if (perform_check) { EXPECT_EQ(kExpectedCalls, fixture_constructor_count_) << "Fixture constructor of ParamTestGenerationTest test case " << "has not been run as expected."; EXPECT_EQ(kExpectedCalls, set_up_count_) << "Fixture SetUp method of ParamTestGenerationTest test case " << "has not been run as expected."; EXPECT_EQ(kExpectedCalls, tear_down_count_) << "Fixture TearDown method of ParamTestGenerationTest test case " << "has not been run as expected."; EXPECT_EQ(kExpectedCalls, test_body_count_) << "Test in ParamTestGenerationTest test case " << "has not been run as expected."; } } private: TestGenerationEnvironment() : fixture_constructor_count_(0), set_up_count_(0), tear_down_count_(0), test_body_count_(0) {} int fixture_constructor_count_; int set_up_count_; int tear_down_count_; int test_body_count_; GTEST_DISALLOW_COPY_AND_ASSIGN_(TestGenerationEnvironment); }; const int test_generation_params[] = {36, 42, 72}; class TestGenerationTest : public TestWithParam { public: enum { PARAMETER_COUNT = sizeof(test_generation_params)/sizeof(test_generation_params[0]) }; typedef TestGenerationEnvironment Environment; TestGenerationTest() { Environment::Instance()->FixtureConstructorExecuted(); current_parameter_ = GetParam(); } virtual void SetUp() { Environment::Instance()->SetUpExecuted(); EXPECT_EQ(current_parameter_, GetParam()); } virtual void TearDown() { Environment::Instance()->TearDownExecuted(); EXPECT_EQ(current_parameter_, GetParam()); } static void SetUpTestCase() { bool all_tests_in_test_case_selected = true; for (int i = 0; i < PARAMETER_COUNT; ++i) { Message test_name; test_name << "TestsExpandedAndRun/" << i; if ( !UnitTestOptions::FilterMatchesTest( "TestExpansionModule/MultipleTestGenerationTest", test_name.GetString())) { all_tests_in_test_case_selected = false; } } EXPECT_TRUE(all_tests_in_test_case_selected) << "When running the TestGenerationTest test case all of its tests\n" << "must be selected by the filter flag for the test case to pass.\n" << "If not all of them are enabled, we can't reliably conclude\n" << "that the correct number of tests have been generated."; collected_parameters_.clear(); } static void TearDownTestCase() { vector expected_values(test_generation_params, test_generation_params + PARAMETER_COUNT); // Test execution order is not guaranteed by Google Test, // so the order of values in collected_parameters_ can be // different and we have to sort to compare. sort(expected_values.begin(), expected_values.end()); sort(collected_parameters_.begin(), collected_parameters_.end()); EXPECT_TRUE(collected_parameters_ == expected_values); } protected: int current_parameter_; static vector collected_parameters_; private: GTEST_DISALLOW_COPY_AND_ASSIGN_(TestGenerationTest); }; vector TestGenerationTest::collected_parameters_; TEST_P(TestGenerationTest, TestsExpandedAndRun) { Environment::Instance()->TestBodyExecuted(); EXPECT_EQ(current_parameter_, GetParam()); collected_parameters_.push_back(GetParam()); } INSTANTIATE_TEST_CASE_P(TestExpansionModule, TestGenerationTest, ValuesIn(test_generation_params)); // This test verifies that the element sequence (third parameter of // INSTANTIATE_TEST_CASE_P) is evaluated in InitGoogleTest() and neither at // the call site of INSTANTIATE_TEST_CASE_P nor in RUN_ALL_TESTS(). For // that, we declare param_value_ to be a static member of // GeneratorEvaluationTest and initialize it to 0. We set it to 1 in // main(), just before invocation of InitGoogleTest(). After calling // InitGoogleTest(), we set the value to 2. If the sequence is evaluated // before or after InitGoogleTest, INSTANTIATE_TEST_CASE_P will create a // test with parameter other than 1, and the test body will fail the // assertion. class GeneratorEvaluationTest : public TestWithParam { public: static int param_value() { return param_value_; } static void set_param_value(int param_value) { param_value_ = param_value; } private: static int param_value_; }; int GeneratorEvaluationTest::param_value_ = 0; TEST_P(GeneratorEvaluationTest, GeneratorsEvaluatedInMain) { EXPECT_EQ(1, GetParam()); } INSTANTIATE_TEST_CASE_P(GenEvalModule, GeneratorEvaluationTest, Values(GeneratorEvaluationTest::param_value())); // Tests that generators defined in a different translation unit are // functional. Generator extern_gen is defined in gtest-param-test_test2.cc. extern ParamGenerator extern_gen; class ExternalGeneratorTest : public TestWithParam {}; TEST_P(ExternalGeneratorTest, ExternalGenerator) { // Sequence produced by extern_gen contains only a single value // which we verify here. EXPECT_EQ(GetParam(), 33); } INSTANTIATE_TEST_CASE_P(ExternalGeneratorModule, ExternalGeneratorTest, extern_gen); // Tests that a parameterized test case can be defined in one translation // unit and instantiated in another. This test will be instantiated in // gtest-param-test_test2.cc. ExternalInstantiationTest fixture class is // defined in gtest-param-test_test.h. TEST_P(ExternalInstantiationTest, IsMultipleOf33) { EXPECT_EQ(0, GetParam() % 33); } // Tests that a parameterized test case can be instantiated with multiple // generators. class MultipleInstantiationTest : public TestWithParam {}; TEST_P(MultipleInstantiationTest, AllowsMultipleInstances) { } INSTANTIATE_TEST_CASE_P(Sequence1, MultipleInstantiationTest, Values(1, 2)); INSTANTIATE_TEST_CASE_P(Sequence2, MultipleInstantiationTest, Range(3, 5)); // Tests that a parameterized test case can be instantiated // in multiple translation units. This test will be instantiated // here and in gtest-param-test_test2.cc. // InstantiationInMultipleTranslationUnitsTest fixture class // is defined in gtest-param-test_test.h. TEST_P(InstantiationInMultipleTranslaionUnitsTest, IsMultipleOf42) { EXPECT_EQ(0, GetParam() % 42); } INSTANTIATE_TEST_CASE_P(Sequence1, InstantiationInMultipleTranslaionUnitsTest, Values(42, 42*2)); // Tests that each iteration of parameterized test runs in a separate test // object. class SeparateInstanceTest : public TestWithParam { public: SeparateInstanceTest() : count_(0) {} static void TearDownTestCase() { EXPECT_GE(global_count_, 2) << "If some (but not all) SeparateInstanceTest tests have been " << "filtered out this test will fail. Make sure that all " << "GeneratorEvaluationTest are selected or de-selected together " << "by the test filter."; } protected: int count_; static int global_count_; }; int SeparateInstanceTest::global_count_ = 0; TEST_P(SeparateInstanceTest, TestsRunInSeparateInstances) { EXPECT_EQ(0, count_++); global_count_++; } INSTANTIATE_TEST_CASE_P(FourElemSequence, SeparateInstanceTest, Range(1, 4)); // Tests that all instantiations of a test have named appropriately. Test // defined with TEST_P(TestCaseName, TestName) and instantiated with // INSTANTIATE_TEST_CASE_P(SequenceName, TestCaseName, generator) must be named // SequenceName/TestCaseName.TestName/i, where i is the 0-based index of the // sequence element used to instantiate the test. class NamingTest : public TestWithParam {}; TEST_P(NamingTest, TestsReportCorrectNamesAndParameters) { const ::testing::TestInfo* const test_info = ::testing::UnitTest::GetInstance()->current_test_info(); EXPECT_STREQ("ZeroToFiveSequence/NamingTest", test_info->test_case_name()); Message index_stream; index_stream << "TestsReportCorrectNamesAndParameters/" << GetParam(); EXPECT_STREQ(index_stream.GetString().c_str(), test_info->name()); EXPECT_EQ(::testing::PrintToString(GetParam()), test_info->value_param()); } INSTANTIATE_TEST_CASE_P(ZeroToFiveSequence, NamingTest, Range(0, 5)); // Class that cannot be streamed into an ostream. It needs to be copyable // (and, in case of MSVC, also assignable) in order to be a test parameter // type. Its default copy constructor and assignment operator do exactly // what we need. class Unstreamable { public: explicit Unstreamable(int value) : value_(value) {} private: int value_; }; class CommentTest : public TestWithParam {}; TEST_P(CommentTest, TestsCorrectlyReportUnstreamableParams) { const ::testing::TestInfo* const test_info = ::testing::UnitTest::GetInstance()->current_test_info(); EXPECT_EQ(::testing::PrintToString(GetParam()), test_info->value_param()); } INSTANTIATE_TEST_CASE_P(InstantiationWithComments, CommentTest, Values(Unstreamable(1))); // Verify that we can create a hierarchy of test fixtures, where the base // class fixture is not parameterized and the derived class is. In this case // ParameterizedDerivedTest inherits from NonParameterizedBaseTest. We // perform simple tests on both. class NonParameterizedBaseTest : public ::testing::Test { public: NonParameterizedBaseTest() : n_(17) { } protected: int n_; }; class ParameterizedDerivedTest : public NonParameterizedBaseTest, public ::testing::WithParamInterface { protected: ParameterizedDerivedTest() : count_(0) { } int count_; static int global_count_; }; int ParameterizedDerivedTest::global_count_ = 0; TEST_F(NonParameterizedBaseTest, FixtureIsInitialized) { EXPECT_EQ(17, n_); } TEST_P(ParameterizedDerivedTest, SeesSequence) { EXPECT_EQ(17, n_); EXPECT_EQ(0, count_++); EXPECT_EQ(GetParam(), global_count_++); } class ParameterizedDeathTest : public ::testing::TestWithParam { }; TEST_F(ParameterizedDeathTest, GetParamDiesFromTestF) { EXPECT_DEATH_IF_SUPPORTED(GetParam(), ".* value-parameterized test .*"); } INSTANTIATE_TEST_CASE_P(RangeZeroToFive, ParameterizedDerivedTest, Range(0, 5)); #endif // GTEST_HAS_PARAM_TEST TEST(CompileTest, CombineIsDefinedOnlyWhenGtestHasParamTestIsDefined) { #if GTEST_HAS_COMBINE && !GTEST_HAS_PARAM_TEST FAIL() << "GTEST_HAS_COMBINE is defined while GTEST_HAS_PARAM_TEST is not\n" #endif } int main(int argc, char **argv) { #if GTEST_HAS_PARAM_TEST // Used in TestGenerationTest test case. AddGlobalTestEnvironment(TestGenerationTest::Environment::Instance()); // Used in GeneratorEvaluationTest test case. Tests that the updated value // will be picked up for instantiating tests in GeneratorEvaluationTest. GeneratorEvaluationTest::set_param_value(1); #endif // GTEST_HAS_PARAM_TEST ::testing::InitGoogleTest(&argc, argv); #if GTEST_HAS_PARAM_TEST // Used in GeneratorEvaluationTest test case. Tests that value updated // here will NOT be used for instantiating tests in // GeneratorEvaluationTest. GeneratorEvaluationTest::set_param_value(2); #endif // GTEST_HAS_PARAM_TEST return RUN_ALL_TESTS(); } dlt-daemon-2.18.4/gtest-1.7.0/test/gtest-param-test_test.h000066400000000000000000000044471353342203500230220ustar00rootroot00000000000000// Copyright 2008, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Authors: vladl@google.com (Vlad Losev) // // The Google C++ Testing Framework (Google Test) // // This header file provides classes and functions used internally // for testing Google Test itself. #ifndef GTEST_TEST_GTEST_PARAM_TEST_TEST_H_ #define GTEST_TEST_GTEST_PARAM_TEST_TEST_H_ #include "gtest/gtest.h" #if GTEST_HAS_PARAM_TEST // Test fixture for testing definition and instantiation of a test // in separate translation units. class ExternalInstantiationTest : public ::testing::TestWithParam { }; // Test fixture for testing instantiation of a test in multiple // translation units. class InstantiationInMultipleTranslaionUnitsTest : public ::testing::TestWithParam { }; #endif // GTEST_HAS_PARAM_TEST #endif // GTEST_TEST_GTEST_PARAM_TEST_TEST_H_ dlt-daemon-2.18.4/gtest-1.7.0/test/gtest-port_test.cc000066400000000000000000001142661353342203500220700ustar00rootroot00000000000000// Copyright 2008, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Authors: vladl@google.com (Vlad Losev), wan@google.com (Zhanyong Wan) // // This file tests the internal cross-platform support utilities. #include "gtest/internal/gtest-port.h" #include #if GTEST_OS_MAC # include #endif // GTEST_OS_MAC #include #include // For std::pair and std::make_pair. #include #include "gtest/gtest.h" #include "gtest/gtest-spi.h" // Indicates that this translation unit is part of Google Test's // implementation. It must come before gtest-internal-inl.h is // included, or there will be a compiler error. This trick is to // prevent a user from accidentally including gtest-internal-inl.h in // his code. #define GTEST_IMPLEMENTATION_ 1 #include "src/gtest-internal-inl.h" #undef GTEST_IMPLEMENTATION_ using std::make_pair; using std::pair; namespace testing { namespace internal { TEST(IsXDigitTest, WorksForNarrowAscii) { EXPECT_TRUE(IsXDigit('0')); EXPECT_TRUE(IsXDigit('9')); EXPECT_TRUE(IsXDigit('A')); EXPECT_TRUE(IsXDigit('F')); EXPECT_TRUE(IsXDigit('a')); EXPECT_TRUE(IsXDigit('f')); EXPECT_FALSE(IsXDigit('-')); EXPECT_FALSE(IsXDigit('g')); EXPECT_FALSE(IsXDigit('G')); } TEST(IsXDigitTest, ReturnsFalseForNarrowNonAscii) { EXPECT_FALSE(IsXDigit(static_cast(0x80))); EXPECT_FALSE(IsXDigit(static_cast('0' | 0x80))); } TEST(IsXDigitTest, WorksForWideAscii) { EXPECT_TRUE(IsXDigit(L'0')); EXPECT_TRUE(IsXDigit(L'9')); EXPECT_TRUE(IsXDigit(L'A')); EXPECT_TRUE(IsXDigit(L'F')); EXPECT_TRUE(IsXDigit(L'a')); EXPECT_TRUE(IsXDigit(L'f')); EXPECT_FALSE(IsXDigit(L'-')); EXPECT_FALSE(IsXDigit(L'g')); EXPECT_FALSE(IsXDigit(L'G')); } TEST(IsXDigitTest, ReturnsFalseForWideNonAscii) { EXPECT_FALSE(IsXDigit(static_cast(0x80))); EXPECT_FALSE(IsXDigit(static_cast(L'0' | 0x80))); EXPECT_FALSE(IsXDigit(static_cast(L'0' | 0x100))); } class Base { public: // Copy constructor and assignment operator do exactly what we need, so we // use them. Base() : member_(0) {} explicit Base(int n) : member_(n) {} virtual ~Base() {} int member() { return member_; } private: int member_; }; class Derived : public Base { public: explicit Derived(int n) : Base(n) {} }; TEST(ImplicitCastTest, ConvertsPointers) { Derived derived(0); EXPECT_TRUE(&derived == ::testing::internal::ImplicitCast_(&derived)); } TEST(ImplicitCastTest, CanUseInheritance) { Derived derived(1); Base base = ::testing::internal::ImplicitCast_(derived); EXPECT_EQ(derived.member(), base.member()); } class Castable { public: explicit Castable(bool* converted) : converted_(converted) {} operator Base() { *converted_ = true; return Base(); } private: bool* converted_; }; TEST(ImplicitCastTest, CanUseNonConstCastOperator) { bool converted = false; Castable castable(&converted); Base base = ::testing::internal::ImplicitCast_(castable); EXPECT_TRUE(converted); } class ConstCastable { public: explicit ConstCastable(bool* converted) : converted_(converted) {} operator Base() const { *converted_ = true; return Base(); } private: bool* converted_; }; TEST(ImplicitCastTest, CanUseConstCastOperatorOnConstValues) { bool converted = false; const ConstCastable const_castable(&converted); Base base = ::testing::internal::ImplicitCast_(const_castable); EXPECT_TRUE(converted); } class ConstAndNonConstCastable { public: ConstAndNonConstCastable(bool* converted, bool* const_converted) : converted_(converted), const_converted_(const_converted) {} operator Base() { *converted_ = true; return Base(); } operator Base() const { *const_converted_ = true; return Base(); } private: bool* converted_; bool* const_converted_; }; TEST(ImplicitCastTest, CanSelectBetweenConstAndNonConstCasrAppropriately) { bool converted = false; bool const_converted = false; ConstAndNonConstCastable castable(&converted, &const_converted); Base base = ::testing::internal::ImplicitCast_(castable); EXPECT_TRUE(converted); EXPECT_FALSE(const_converted); converted = false; const_converted = false; const ConstAndNonConstCastable const_castable(&converted, &const_converted); base = ::testing::internal::ImplicitCast_(const_castable); EXPECT_FALSE(converted); EXPECT_TRUE(const_converted); } class To { public: To(bool* converted) { *converted = true; } // NOLINT }; TEST(ImplicitCastTest, CanUseImplicitConstructor) { bool converted = false; To to = ::testing::internal::ImplicitCast_(&converted); (void)to; EXPECT_TRUE(converted); } TEST(IteratorTraitsTest, WorksForSTLContainerIterators) { StaticAssertTypeEq::const_iterator>::value_type>(); StaticAssertTypeEq::iterator>::value_type>(); } TEST(IteratorTraitsTest, WorksForPointerToNonConst) { StaticAssertTypeEq::value_type>(); StaticAssertTypeEq::value_type>(); } TEST(IteratorTraitsTest, WorksForPointerToConst) { StaticAssertTypeEq::value_type>(); StaticAssertTypeEq::value_type>(); } // Tests that the element_type typedef is available in scoped_ptr and refers // to the parameter type. TEST(ScopedPtrTest, DefinesElementType) { StaticAssertTypeEq::element_type>(); } // TODO(vladl@google.com): Implement THE REST of scoped_ptr tests. TEST(GtestCheckSyntaxTest, BehavesLikeASingleStatement) { if (AlwaysFalse()) GTEST_CHECK_(false) << "This should never be executed; " "It's a compilation test only."; if (AlwaysTrue()) GTEST_CHECK_(true); else ; // NOLINT if (AlwaysFalse()) ; // NOLINT else GTEST_CHECK_(true) << ""; } TEST(GtestCheckSyntaxTest, WorksWithSwitch) { switch (0) { case 1: break; default: GTEST_CHECK_(true); } switch (0) case 0: GTEST_CHECK_(true) << "Check failed in switch case"; } // Verifies behavior of FormatFileLocation. TEST(FormatFileLocationTest, FormatsFileLocation) { EXPECT_PRED_FORMAT2(IsSubstring, "foo.cc", FormatFileLocation("foo.cc", 42)); EXPECT_PRED_FORMAT2(IsSubstring, "42", FormatFileLocation("foo.cc", 42)); } TEST(FormatFileLocationTest, FormatsUnknownFile) { EXPECT_PRED_FORMAT2( IsSubstring, "unknown file", FormatFileLocation(NULL, 42)); EXPECT_PRED_FORMAT2(IsSubstring, "42", FormatFileLocation(NULL, 42)); } TEST(FormatFileLocationTest, FormatsUknownLine) { EXPECT_EQ("foo.cc:", FormatFileLocation("foo.cc", -1)); } TEST(FormatFileLocationTest, FormatsUknownFileAndLine) { EXPECT_EQ("unknown file:", FormatFileLocation(NULL, -1)); } // Verifies behavior of FormatCompilerIndependentFileLocation. TEST(FormatCompilerIndependentFileLocationTest, FormatsFileLocation) { EXPECT_EQ("foo.cc:42", FormatCompilerIndependentFileLocation("foo.cc", 42)); } TEST(FormatCompilerIndependentFileLocationTest, FormatsUknownFile) { EXPECT_EQ("unknown file:42", FormatCompilerIndependentFileLocation(NULL, 42)); } TEST(FormatCompilerIndependentFileLocationTest, FormatsUknownLine) { EXPECT_EQ("foo.cc", FormatCompilerIndependentFileLocation("foo.cc", -1)); } TEST(FormatCompilerIndependentFileLocationTest, FormatsUknownFileAndLine) { EXPECT_EQ("unknown file", FormatCompilerIndependentFileLocation(NULL, -1)); } #if GTEST_OS_MAC || GTEST_OS_QNX void* ThreadFunc(void* data) { pthread_mutex_t* mutex = static_cast(data); pthread_mutex_lock(mutex); pthread_mutex_unlock(mutex); return NULL; } TEST(GetThreadCountTest, ReturnsCorrectValue) { EXPECT_EQ(1U, GetThreadCount()); pthread_mutex_t mutex; pthread_attr_t attr; pthread_t thread_id; // TODO(vladl@google.com): turn mutex into internal::Mutex for automatic // destruction. pthread_mutex_init(&mutex, NULL); pthread_mutex_lock(&mutex); ASSERT_EQ(0, pthread_attr_init(&attr)); ASSERT_EQ(0, pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE)); const int status = pthread_create(&thread_id, &attr, &ThreadFunc, &mutex); ASSERT_EQ(0, pthread_attr_destroy(&attr)); ASSERT_EQ(0, status); EXPECT_EQ(2U, GetThreadCount()); pthread_mutex_unlock(&mutex); void* dummy; ASSERT_EQ(0, pthread_join(thread_id, &dummy)); # if GTEST_OS_MAC // MacOS X may not immediately report the updated thread count after // joining a thread, causing flakiness in this test. To counter that, we // wait for up to .5 seconds for the OS to report the correct value. for (int i = 0; i < 5; ++i) { if (GetThreadCount() == 1) break; SleepMilliseconds(100); } # endif // GTEST_OS_MAC EXPECT_EQ(1U, GetThreadCount()); pthread_mutex_destroy(&mutex); } #else TEST(GetThreadCountTest, ReturnsZeroWhenUnableToCountThreads) { EXPECT_EQ(0U, GetThreadCount()); } #endif // GTEST_OS_MAC || GTEST_OS_QNX TEST(GtestCheckDeathTest, DiesWithCorrectOutputOnFailure) { const bool a_false_condition = false; const char regex[] = #ifdef _MSC_VER "gtest-port_test\\.cc\\(\\d+\\):" #elif GTEST_USES_POSIX_RE "gtest-port_test\\.cc:[0-9]+" #else "gtest-port_test\\.cc:\\d+" #endif // _MSC_VER ".*a_false_condition.*Extra info.*"; EXPECT_DEATH_IF_SUPPORTED(GTEST_CHECK_(a_false_condition) << "Extra info", regex); } #if GTEST_HAS_DEATH_TEST TEST(GtestCheckDeathTest, LivesSilentlyOnSuccess) { EXPECT_EXIT({ GTEST_CHECK_(true) << "Extra info"; ::std::cerr << "Success\n"; exit(0); }, ::testing::ExitedWithCode(0), "Success"); } #endif // GTEST_HAS_DEATH_TEST // Verifies that Google Test choose regular expression engine appropriate to // the platform. The test will produce compiler errors in case of failure. // For simplicity, we only cover the most important platforms here. TEST(RegexEngineSelectionTest, SelectsCorrectRegexEngine) { #if GTEST_HAS_POSIX_RE EXPECT_TRUE(GTEST_USES_POSIX_RE); #else EXPECT_TRUE(GTEST_USES_SIMPLE_RE); #endif } #if GTEST_USES_POSIX_RE # if GTEST_HAS_TYPED_TEST template class RETest : public ::testing::Test {}; // Defines StringTypes as the list of all string types that class RE // supports. typedef testing::Types< ::std::string, # if GTEST_HAS_GLOBAL_STRING ::string, # endif // GTEST_HAS_GLOBAL_STRING const char*> StringTypes; TYPED_TEST_CASE(RETest, StringTypes); // Tests RE's implicit constructors. TYPED_TEST(RETest, ImplicitConstructorWorks) { const RE empty(TypeParam("")); EXPECT_STREQ("", empty.pattern()); const RE simple(TypeParam("hello")); EXPECT_STREQ("hello", simple.pattern()); const RE normal(TypeParam(".*(\\w+)")); EXPECT_STREQ(".*(\\w+)", normal.pattern()); } // Tests that RE's constructors reject invalid regular expressions. TYPED_TEST(RETest, RejectsInvalidRegex) { EXPECT_NONFATAL_FAILURE({ const RE invalid(TypeParam("?")); }, "\"?\" is not a valid POSIX Extended regular expression."); } // Tests RE::FullMatch(). TYPED_TEST(RETest, FullMatchWorks) { const RE empty(TypeParam("")); EXPECT_TRUE(RE::FullMatch(TypeParam(""), empty)); EXPECT_FALSE(RE::FullMatch(TypeParam("a"), empty)); const RE re(TypeParam("a.*z")); EXPECT_TRUE(RE::FullMatch(TypeParam("az"), re)); EXPECT_TRUE(RE::FullMatch(TypeParam("axyz"), re)); EXPECT_FALSE(RE::FullMatch(TypeParam("baz"), re)); EXPECT_FALSE(RE::FullMatch(TypeParam("azy"), re)); } // Tests RE::PartialMatch(). TYPED_TEST(RETest, PartialMatchWorks) { const RE empty(TypeParam("")); EXPECT_TRUE(RE::PartialMatch(TypeParam(""), empty)); EXPECT_TRUE(RE::PartialMatch(TypeParam("a"), empty)); const RE re(TypeParam("a.*z")); EXPECT_TRUE(RE::PartialMatch(TypeParam("az"), re)); EXPECT_TRUE(RE::PartialMatch(TypeParam("axyz"), re)); EXPECT_TRUE(RE::PartialMatch(TypeParam("baz"), re)); EXPECT_TRUE(RE::PartialMatch(TypeParam("azy"), re)); EXPECT_FALSE(RE::PartialMatch(TypeParam("zza"), re)); } # endif // GTEST_HAS_TYPED_TEST #elif GTEST_USES_SIMPLE_RE TEST(IsInSetTest, NulCharIsNotInAnySet) { EXPECT_FALSE(IsInSet('\0', "")); EXPECT_FALSE(IsInSet('\0', "\0")); EXPECT_FALSE(IsInSet('\0', "a")); } TEST(IsInSetTest, WorksForNonNulChars) { EXPECT_FALSE(IsInSet('a', "Ab")); EXPECT_FALSE(IsInSet('c', "")); EXPECT_TRUE(IsInSet('b', "bcd")); EXPECT_TRUE(IsInSet('b', "ab")); } TEST(IsAsciiDigitTest, IsFalseForNonDigit) { EXPECT_FALSE(IsAsciiDigit('\0')); EXPECT_FALSE(IsAsciiDigit(' ')); EXPECT_FALSE(IsAsciiDigit('+')); EXPECT_FALSE(IsAsciiDigit('-')); EXPECT_FALSE(IsAsciiDigit('.')); EXPECT_FALSE(IsAsciiDigit('a')); } TEST(IsAsciiDigitTest, IsTrueForDigit) { EXPECT_TRUE(IsAsciiDigit('0')); EXPECT_TRUE(IsAsciiDigit('1')); EXPECT_TRUE(IsAsciiDigit('5')); EXPECT_TRUE(IsAsciiDigit('9')); } TEST(IsAsciiPunctTest, IsFalseForNonPunct) { EXPECT_FALSE(IsAsciiPunct('\0')); EXPECT_FALSE(IsAsciiPunct(' ')); EXPECT_FALSE(IsAsciiPunct('\n')); EXPECT_FALSE(IsAsciiPunct('a')); EXPECT_FALSE(IsAsciiPunct('0')); } TEST(IsAsciiPunctTest, IsTrueForPunct) { for (const char* p = "^-!\"#$%&'()*+,./:;<=>?@[\\]_`{|}~"; *p; p++) { EXPECT_PRED1(IsAsciiPunct, *p); } } TEST(IsRepeatTest, IsFalseForNonRepeatChar) { EXPECT_FALSE(IsRepeat('\0')); EXPECT_FALSE(IsRepeat(' ')); EXPECT_FALSE(IsRepeat('a')); EXPECT_FALSE(IsRepeat('1')); EXPECT_FALSE(IsRepeat('-')); } TEST(IsRepeatTest, IsTrueForRepeatChar) { EXPECT_TRUE(IsRepeat('?')); EXPECT_TRUE(IsRepeat('*')); EXPECT_TRUE(IsRepeat('+')); } TEST(IsAsciiWhiteSpaceTest, IsFalseForNonWhiteSpace) { EXPECT_FALSE(IsAsciiWhiteSpace('\0')); EXPECT_FALSE(IsAsciiWhiteSpace('a')); EXPECT_FALSE(IsAsciiWhiteSpace('1')); EXPECT_FALSE(IsAsciiWhiteSpace('+')); EXPECT_FALSE(IsAsciiWhiteSpace('_')); } TEST(IsAsciiWhiteSpaceTest, IsTrueForWhiteSpace) { EXPECT_TRUE(IsAsciiWhiteSpace(' ')); EXPECT_TRUE(IsAsciiWhiteSpace('\n')); EXPECT_TRUE(IsAsciiWhiteSpace('\r')); EXPECT_TRUE(IsAsciiWhiteSpace('\t')); EXPECT_TRUE(IsAsciiWhiteSpace('\v')); EXPECT_TRUE(IsAsciiWhiteSpace('\f')); } TEST(IsAsciiWordCharTest, IsFalseForNonWordChar) { EXPECT_FALSE(IsAsciiWordChar('\0')); EXPECT_FALSE(IsAsciiWordChar('+')); EXPECT_FALSE(IsAsciiWordChar('.')); EXPECT_FALSE(IsAsciiWordChar(' ')); EXPECT_FALSE(IsAsciiWordChar('\n')); } TEST(IsAsciiWordCharTest, IsTrueForLetter) { EXPECT_TRUE(IsAsciiWordChar('a')); EXPECT_TRUE(IsAsciiWordChar('b')); EXPECT_TRUE(IsAsciiWordChar('A')); EXPECT_TRUE(IsAsciiWordChar('Z')); } TEST(IsAsciiWordCharTest, IsTrueForDigit) { EXPECT_TRUE(IsAsciiWordChar('0')); EXPECT_TRUE(IsAsciiWordChar('1')); EXPECT_TRUE(IsAsciiWordChar('7')); EXPECT_TRUE(IsAsciiWordChar('9')); } TEST(IsAsciiWordCharTest, IsTrueForUnderscore) { EXPECT_TRUE(IsAsciiWordChar('_')); } TEST(IsValidEscapeTest, IsFalseForNonPrintable) { EXPECT_FALSE(IsValidEscape('\0')); EXPECT_FALSE(IsValidEscape('\007')); } TEST(IsValidEscapeTest, IsFalseForDigit) { EXPECT_FALSE(IsValidEscape('0')); EXPECT_FALSE(IsValidEscape('9')); } TEST(IsValidEscapeTest, IsFalseForWhiteSpace) { EXPECT_FALSE(IsValidEscape(' ')); EXPECT_FALSE(IsValidEscape('\n')); } TEST(IsValidEscapeTest, IsFalseForSomeLetter) { EXPECT_FALSE(IsValidEscape('a')); EXPECT_FALSE(IsValidEscape('Z')); } TEST(IsValidEscapeTest, IsTrueForPunct) { EXPECT_TRUE(IsValidEscape('.')); EXPECT_TRUE(IsValidEscape('-')); EXPECT_TRUE(IsValidEscape('^')); EXPECT_TRUE(IsValidEscape('$')); EXPECT_TRUE(IsValidEscape('(')); EXPECT_TRUE(IsValidEscape(']')); EXPECT_TRUE(IsValidEscape('{')); EXPECT_TRUE(IsValidEscape('|')); } TEST(IsValidEscapeTest, IsTrueForSomeLetter) { EXPECT_TRUE(IsValidEscape('d')); EXPECT_TRUE(IsValidEscape('D')); EXPECT_TRUE(IsValidEscape('s')); EXPECT_TRUE(IsValidEscape('S')); EXPECT_TRUE(IsValidEscape('w')); EXPECT_TRUE(IsValidEscape('W')); } TEST(AtomMatchesCharTest, EscapedPunct) { EXPECT_FALSE(AtomMatchesChar(true, '\\', '\0')); EXPECT_FALSE(AtomMatchesChar(true, '\\', ' ')); EXPECT_FALSE(AtomMatchesChar(true, '_', '.')); EXPECT_FALSE(AtomMatchesChar(true, '.', 'a')); EXPECT_TRUE(AtomMatchesChar(true, '\\', '\\')); EXPECT_TRUE(AtomMatchesChar(true, '_', '_')); EXPECT_TRUE(AtomMatchesChar(true, '+', '+')); EXPECT_TRUE(AtomMatchesChar(true, '.', '.')); } TEST(AtomMatchesCharTest, Escaped_d) { EXPECT_FALSE(AtomMatchesChar(true, 'd', '\0')); EXPECT_FALSE(AtomMatchesChar(true, 'd', 'a')); EXPECT_FALSE(AtomMatchesChar(true, 'd', '.')); EXPECT_TRUE(AtomMatchesChar(true, 'd', '0')); EXPECT_TRUE(AtomMatchesChar(true, 'd', '9')); } TEST(AtomMatchesCharTest, Escaped_D) { EXPECT_FALSE(AtomMatchesChar(true, 'D', '0')); EXPECT_FALSE(AtomMatchesChar(true, 'D', '9')); EXPECT_TRUE(AtomMatchesChar(true, 'D', '\0')); EXPECT_TRUE(AtomMatchesChar(true, 'D', 'a')); EXPECT_TRUE(AtomMatchesChar(true, 'D', '-')); } TEST(AtomMatchesCharTest, Escaped_s) { EXPECT_FALSE(AtomMatchesChar(true, 's', '\0')); EXPECT_FALSE(AtomMatchesChar(true, 's', 'a')); EXPECT_FALSE(AtomMatchesChar(true, 's', '.')); EXPECT_FALSE(AtomMatchesChar(true, 's', '9')); EXPECT_TRUE(AtomMatchesChar(true, 's', ' ')); EXPECT_TRUE(AtomMatchesChar(true, 's', '\n')); EXPECT_TRUE(AtomMatchesChar(true, 's', '\t')); } TEST(AtomMatchesCharTest, Escaped_S) { EXPECT_FALSE(AtomMatchesChar(true, 'S', ' ')); EXPECT_FALSE(AtomMatchesChar(true, 'S', '\r')); EXPECT_TRUE(AtomMatchesChar(true, 'S', '\0')); EXPECT_TRUE(AtomMatchesChar(true, 'S', 'a')); EXPECT_TRUE(AtomMatchesChar(true, 'S', '9')); } TEST(AtomMatchesCharTest, Escaped_w) { EXPECT_FALSE(AtomMatchesChar(true, 'w', '\0')); EXPECT_FALSE(AtomMatchesChar(true, 'w', '+')); EXPECT_FALSE(AtomMatchesChar(true, 'w', ' ')); EXPECT_FALSE(AtomMatchesChar(true, 'w', '\n')); EXPECT_TRUE(AtomMatchesChar(true, 'w', '0')); EXPECT_TRUE(AtomMatchesChar(true, 'w', 'b')); EXPECT_TRUE(AtomMatchesChar(true, 'w', 'C')); EXPECT_TRUE(AtomMatchesChar(true, 'w', '_')); } TEST(AtomMatchesCharTest, Escaped_W) { EXPECT_FALSE(AtomMatchesChar(true, 'W', 'A')); EXPECT_FALSE(AtomMatchesChar(true, 'W', 'b')); EXPECT_FALSE(AtomMatchesChar(true, 'W', '9')); EXPECT_FALSE(AtomMatchesChar(true, 'W', '_')); EXPECT_TRUE(AtomMatchesChar(true, 'W', '\0')); EXPECT_TRUE(AtomMatchesChar(true, 'W', '*')); EXPECT_TRUE(AtomMatchesChar(true, 'W', '\n')); } TEST(AtomMatchesCharTest, EscapedWhiteSpace) { EXPECT_FALSE(AtomMatchesChar(true, 'f', '\0')); EXPECT_FALSE(AtomMatchesChar(true, 'f', '\n')); EXPECT_FALSE(AtomMatchesChar(true, 'n', '\0')); EXPECT_FALSE(AtomMatchesChar(true, 'n', '\r')); EXPECT_FALSE(AtomMatchesChar(true, 'r', '\0')); EXPECT_FALSE(AtomMatchesChar(true, 'r', 'a')); EXPECT_FALSE(AtomMatchesChar(true, 't', '\0')); EXPECT_FALSE(AtomMatchesChar(true, 't', 't')); EXPECT_FALSE(AtomMatchesChar(true, 'v', '\0')); EXPECT_FALSE(AtomMatchesChar(true, 'v', '\f')); EXPECT_TRUE(AtomMatchesChar(true, 'f', '\f')); EXPECT_TRUE(AtomMatchesChar(true, 'n', '\n')); EXPECT_TRUE(AtomMatchesChar(true, 'r', '\r')); EXPECT_TRUE(AtomMatchesChar(true, 't', '\t')); EXPECT_TRUE(AtomMatchesChar(true, 'v', '\v')); } TEST(AtomMatchesCharTest, UnescapedDot) { EXPECT_FALSE(AtomMatchesChar(false, '.', '\n')); EXPECT_TRUE(AtomMatchesChar(false, '.', '\0')); EXPECT_TRUE(AtomMatchesChar(false, '.', '.')); EXPECT_TRUE(AtomMatchesChar(false, '.', 'a')); EXPECT_TRUE(AtomMatchesChar(false, '.', ' ')); } TEST(AtomMatchesCharTest, UnescapedChar) { EXPECT_FALSE(AtomMatchesChar(false, 'a', '\0')); EXPECT_FALSE(AtomMatchesChar(false, 'a', 'b')); EXPECT_FALSE(AtomMatchesChar(false, '$', 'a')); EXPECT_TRUE(AtomMatchesChar(false, '$', '$')); EXPECT_TRUE(AtomMatchesChar(false, '5', '5')); EXPECT_TRUE(AtomMatchesChar(false, 'Z', 'Z')); } TEST(ValidateRegexTest, GeneratesFailureAndReturnsFalseForInvalid) { EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex(NULL)), "NULL is not a valid simple regular expression"); EXPECT_NONFATAL_FAILURE( ASSERT_FALSE(ValidateRegex("a\\")), "Syntax error at index 1 in simple regular expression \"a\\\": "); EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("a\\")), "'\\' cannot appear at the end"); EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("\\n\\")), "'\\' cannot appear at the end"); EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("\\s\\hb")), "invalid escape sequence \"\\h\""); EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("^^")), "'^' can only appear at the beginning"); EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex(".*^b")), "'^' can only appear at the beginning"); EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("$$")), "'$' can only appear at the end"); EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("^$a")), "'$' can only appear at the end"); EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("a(b")), "'(' is unsupported"); EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("ab)")), "')' is unsupported"); EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("[ab")), "'[' is unsupported"); EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("a{2")), "'{' is unsupported"); EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("?")), "'?' can only follow a repeatable token"); EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("^*")), "'*' can only follow a repeatable token"); EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("5*+")), "'+' can only follow a repeatable token"); } TEST(ValidateRegexTest, ReturnsTrueForValid) { EXPECT_TRUE(ValidateRegex("")); EXPECT_TRUE(ValidateRegex("a")); EXPECT_TRUE(ValidateRegex(".*")); EXPECT_TRUE(ValidateRegex("^a_+")); EXPECT_TRUE(ValidateRegex("^a\\t\\&?")); EXPECT_TRUE(ValidateRegex("09*$")); EXPECT_TRUE(ValidateRegex("^Z$")); EXPECT_TRUE(ValidateRegex("a\\^Z\\$\\(\\)\\|\\[\\]\\{\\}")); } TEST(MatchRepetitionAndRegexAtHeadTest, WorksForZeroOrOne) { EXPECT_FALSE(MatchRepetitionAndRegexAtHead(false, 'a', '?', "a", "ba")); // Repeating more than once. EXPECT_FALSE(MatchRepetitionAndRegexAtHead(false, 'a', '?', "b", "aab")); // Repeating zero times. EXPECT_TRUE(MatchRepetitionAndRegexAtHead(false, 'a', '?', "b", "ba")); // Repeating once. EXPECT_TRUE(MatchRepetitionAndRegexAtHead(false, 'a', '?', "b", "ab")); EXPECT_TRUE(MatchRepetitionAndRegexAtHead(false, '#', '?', ".", "##")); } TEST(MatchRepetitionAndRegexAtHeadTest, WorksForZeroOrMany) { EXPECT_FALSE(MatchRepetitionAndRegexAtHead(false, '.', '*', "a$", "baab")); // Repeating zero times. EXPECT_TRUE(MatchRepetitionAndRegexAtHead(false, '.', '*', "b", "bc")); // Repeating once. EXPECT_TRUE(MatchRepetitionAndRegexAtHead(false, '.', '*', "b", "abc")); // Repeating more than once. EXPECT_TRUE(MatchRepetitionAndRegexAtHead(true, 'w', '*', "-", "ab_1-g")); } TEST(MatchRepetitionAndRegexAtHeadTest, WorksForOneOrMany) { EXPECT_FALSE(MatchRepetitionAndRegexAtHead(false, '.', '+', "a$", "baab")); // Repeating zero times. EXPECT_FALSE(MatchRepetitionAndRegexAtHead(false, '.', '+', "b", "bc")); // Repeating once. EXPECT_TRUE(MatchRepetitionAndRegexAtHead(false, '.', '+', "b", "abc")); // Repeating more than once. EXPECT_TRUE(MatchRepetitionAndRegexAtHead(true, 'w', '+', "-", "ab_1-g")); } TEST(MatchRegexAtHeadTest, ReturnsTrueForEmptyRegex) { EXPECT_TRUE(MatchRegexAtHead("", "")); EXPECT_TRUE(MatchRegexAtHead("", "ab")); } TEST(MatchRegexAtHeadTest, WorksWhenDollarIsInRegex) { EXPECT_FALSE(MatchRegexAtHead("$", "a")); EXPECT_TRUE(MatchRegexAtHead("$", "")); EXPECT_TRUE(MatchRegexAtHead("a$", "a")); } TEST(MatchRegexAtHeadTest, WorksWhenRegexStartsWithEscapeSequence) { EXPECT_FALSE(MatchRegexAtHead("\\w", "+")); EXPECT_FALSE(MatchRegexAtHead("\\W", "ab")); EXPECT_TRUE(MatchRegexAtHead("\\sa", "\nab")); EXPECT_TRUE(MatchRegexAtHead("\\d", "1a")); } TEST(MatchRegexAtHeadTest, WorksWhenRegexStartsWithRepetition) { EXPECT_FALSE(MatchRegexAtHead(".+a", "abc")); EXPECT_FALSE(MatchRegexAtHead("a?b", "aab")); EXPECT_TRUE(MatchRegexAtHead(".*a", "bc12-ab")); EXPECT_TRUE(MatchRegexAtHead("a?b", "b")); EXPECT_TRUE(MatchRegexAtHead("a?b", "ab")); } TEST(MatchRegexAtHeadTest, WorksWhenRegexStartsWithRepetionOfEscapeSequence) { EXPECT_FALSE(MatchRegexAtHead("\\.+a", "abc")); EXPECT_FALSE(MatchRegexAtHead("\\s?b", " b")); EXPECT_TRUE(MatchRegexAtHead("\\(*a", "((((ab")); EXPECT_TRUE(MatchRegexAtHead("\\^?b", "^b")); EXPECT_TRUE(MatchRegexAtHead("\\\\?b", "b")); EXPECT_TRUE(MatchRegexAtHead("\\\\?b", "\\b")); } TEST(MatchRegexAtHeadTest, MatchesSequentially) { EXPECT_FALSE(MatchRegexAtHead("ab.*c", "acabc")); EXPECT_TRUE(MatchRegexAtHead("ab.*c", "ab-fsc")); } TEST(MatchRegexAnywhereTest, ReturnsFalseWhenStringIsNull) { EXPECT_FALSE(MatchRegexAnywhere("", NULL)); } TEST(MatchRegexAnywhereTest, WorksWhenRegexStartsWithCaret) { EXPECT_FALSE(MatchRegexAnywhere("^a", "ba")); EXPECT_FALSE(MatchRegexAnywhere("^$", "a")); EXPECT_TRUE(MatchRegexAnywhere("^a", "ab")); EXPECT_TRUE(MatchRegexAnywhere("^", "ab")); EXPECT_TRUE(MatchRegexAnywhere("^$", "")); } TEST(MatchRegexAnywhereTest, ReturnsFalseWhenNoMatch) { EXPECT_FALSE(MatchRegexAnywhere("a", "bcde123")); EXPECT_FALSE(MatchRegexAnywhere("a.+a", "--aa88888888")); } TEST(MatchRegexAnywhereTest, ReturnsTrueWhenMatchingPrefix) { EXPECT_TRUE(MatchRegexAnywhere("\\w+", "ab1_ - 5")); EXPECT_TRUE(MatchRegexAnywhere(".*=", "=")); EXPECT_TRUE(MatchRegexAnywhere("x.*ab?.*bc", "xaaabc")); } TEST(MatchRegexAnywhereTest, ReturnsTrueWhenMatchingNonPrefix) { EXPECT_TRUE(MatchRegexAnywhere("\\w+", "$$$ ab1_ - 5")); EXPECT_TRUE(MatchRegexAnywhere("\\.+=", "= ...=")); } // Tests RE's implicit constructors. TEST(RETest, ImplicitConstructorWorks) { const RE empty(""); EXPECT_STREQ("", empty.pattern()); const RE simple("hello"); EXPECT_STREQ("hello", simple.pattern()); } // Tests that RE's constructors reject invalid regular expressions. TEST(RETest, RejectsInvalidRegex) { EXPECT_NONFATAL_FAILURE({ const RE normal(NULL); }, "NULL is not a valid simple regular expression"); EXPECT_NONFATAL_FAILURE({ const RE normal(".*(\\w+"); }, "'(' is unsupported"); EXPECT_NONFATAL_FAILURE({ const RE invalid("^?"); }, "'?' can only follow a repeatable token"); } // Tests RE::FullMatch(). TEST(RETest, FullMatchWorks) { const RE empty(""); EXPECT_TRUE(RE::FullMatch("", empty)); EXPECT_FALSE(RE::FullMatch("a", empty)); const RE re1("a"); EXPECT_TRUE(RE::FullMatch("a", re1)); const RE re("a.*z"); EXPECT_TRUE(RE::FullMatch("az", re)); EXPECT_TRUE(RE::FullMatch("axyz", re)); EXPECT_FALSE(RE::FullMatch("baz", re)); EXPECT_FALSE(RE::FullMatch("azy", re)); } // Tests RE::PartialMatch(). TEST(RETest, PartialMatchWorks) { const RE empty(""); EXPECT_TRUE(RE::PartialMatch("", empty)); EXPECT_TRUE(RE::PartialMatch("a", empty)); const RE re("a.*z"); EXPECT_TRUE(RE::PartialMatch("az", re)); EXPECT_TRUE(RE::PartialMatch("axyz", re)); EXPECT_TRUE(RE::PartialMatch("baz", re)); EXPECT_TRUE(RE::PartialMatch("azy", re)); EXPECT_FALSE(RE::PartialMatch("zza", re)); } #endif // GTEST_USES_POSIX_RE #if !GTEST_OS_WINDOWS_MOBILE TEST(CaptureTest, CapturesStdout) { CaptureStdout(); fprintf(stdout, "abc"); EXPECT_STREQ("abc", GetCapturedStdout().c_str()); CaptureStdout(); fprintf(stdout, "def%cghi", '\0'); EXPECT_EQ(::std::string("def\0ghi", 7), ::std::string(GetCapturedStdout())); } TEST(CaptureTest, CapturesStderr) { CaptureStderr(); fprintf(stderr, "jkl"); EXPECT_STREQ("jkl", GetCapturedStderr().c_str()); CaptureStderr(); fprintf(stderr, "jkl%cmno", '\0'); EXPECT_EQ(::std::string("jkl\0mno", 7), ::std::string(GetCapturedStderr())); } // Tests that stdout and stderr capture don't interfere with each other. TEST(CaptureTest, CapturesStdoutAndStderr) { CaptureStdout(); CaptureStderr(); fprintf(stdout, "pqr"); fprintf(stderr, "stu"); EXPECT_STREQ("pqr", GetCapturedStdout().c_str()); EXPECT_STREQ("stu", GetCapturedStderr().c_str()); } TEST(CaptureDeathTest, CannotReenterStdoutCapture) { CaptureStdout(); EXPECT_DEATH_IF_SUPPORTED(CaptureStdout(), "Only one stdout capturer can exist at a time"); GetCapturedStdout(); // We cannot test stderr capturing using death tests as they use it // themselves. } #endif // !GTEST_OS_WINDOWS_MOBILE TEST(ThreadLocalTest, DefaultConstructorInitializesToDefaultValues) { ThreadLocal t1; EXPECT_EQ(0, t1.get()); ThreadLocal t2; EXPECT_TRUE(t2.get() == NULL); } TEST(ThreadLocalTest, SingleParamConstructorInitializesToParam) { ThreadLocal t1(123); EXPECT_EQ(123, t1.get()); int i = 0; ThreadLocal t2(&i); EXPECT_EQ(&i, t2.get()); } class NoDefaultContructor { public: explicit NoDefaultContructor(const char*) {} NoDefaultContructor(const NoDefaultContructor&) {} }; TEST(ThreadLocalTest, ValueDefaultContructorIsNotRequiredForParamVersion) { ThreadLocal bar(NoDefaultContructor("foo")); bar.pointer(); } TEST(ThreadLocalTest, GetAndPointerReturnSameValue) { ThreadLocal thread_local_string; EXPECT_EQ(thread_local_string.pointer(), &(thread_local_string.get())); // Verifies the condition still holds after calling set. thread_local_string.set("foo"); EXPECT_EQ(thread_local_string.pointer(), &(thread_local_string.get())); } TEST(ThreadLocalTest, PointerAndConstPointerReturnSameValue) { ThreadLocal thread_local_string; const ThreadLocal& const_thread_local_string = thread_local_string; EXPECT_EQ(thread_local_string.pointer(), const_thread_local_string.pointer()); thread_local_string.set("foo"); EXPECT_EQ(thread_local_string.pointer(), const_thread_local_string.pointer()); } #if GTEST_IS_THREADSAFE void AddTwo(int* param) { *param += 2; } TEST(ThreadWithParamTest, ConstructorExecutesThreadFunc) { int i = 40; ThreadWithParam thread(&AddTwo, &i, NULL); thread.Join(); EXPECT_EQ(42, i); } TEST(MutexDeathTest, AssertHeldShouldAssertWhenNotLocked) { // AssertHeld() is flaky only in the presence of multiple threads accessing // the lock. In this case, the test is robust. EXPECT_DEATH_IF_SUPPORTED({ Mutex m; { MutexLock lock(&m); } m.AssertHeld(); }, "thread .*hold"); } TEST(MutexTest, AssertHeldShouldNotAssertWhenLocked) { Mutex m; MutexLock lock(&m); m.AssertHeld(); } class AtomicCounterWithMutex { public: explicit AtomicCounterWithMutex(Mutex* mutex) : value_(0), mutex_(mutex), random_(42) {} void Increment() { MutexLock lock(mutex_); int temp = value_; { // Locking a mutex puts up a memory barrier, preventing reads and // writes to value_ rearranged when observed from other threads. // // We cannot use Mutex and MutexLock here or rely on their memory // barrier functionality as we are testing them here. pthread_mutex_t memory_barrier_mutex; GTEST_CHECK_POSIX_SUCCESS_( pthread_mutex_init(&memory_barrier_mutex, NULL)); GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_lock(&memory_barrier_mutex)); SleepMilliseconds(random_.Generate(30)); GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_unlock(&memory_barrier_mutex)); GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_destroy(&memory_barrier_mutex)); } value_ = temp + 1; } int value() const { return value_; } private: volatile int value_; Mutex* const mutex_; // Protects value_. Random random_; }; void CountingThreadFunc(pair param) { for (int i = 0; i < param.second; ++i) param.first->Increment(); } // Tests that the mutex only lets one thread at a time to lock it. TEST(MutexTest, OnlyOneThreadCanLockAtATime) { Mutex mutex; AtomicCounterWithMutex locked_counter(&mutex); typedef ThreadWithParam > ThreadType; const int kCycleCount = 20; const int kThreadCount = 7; scoped_ptr counting_threads[kThreadCount]; Notification threads_can_start; // Creates and runs kThreadCount threads that increment locked_counter // kCycleCount times each. for (int i = 0; i < kThreadCount; ++i) { counting_threads[i].reset(new ThreadType(&CountingThreadFunc, make_pair(&locked_counter, kCycleCount), &threads_can_start)); } threads_can_start.Notify(); for (int i = 0; i < kThreadCount; ++i) counting_threads[i]->Join(); // If the mutex lets more than one thread to increment the counter at a // time, they are likely to encounter a race condition and have some // increments overwritten, resulting in the lower then expected counter // value. EXPECT_EQ(kCycleCount * kThreadCount, locked_counter.value()); } template void RunFromThread(void (func)(T), T param) { ThreadWithParam thread(func, param, NULL); thread.Join(); } void RetrieveThreadLocalValue( pair*, std::string*> param) { *param.second = param.first->get(); } TEST(ThreadLocalTest, ParameterizedConstructorSetsDefault) { ThreadLocal thread_local_string("foo"); EXPECT_STREQ("foo", thread_local_string.get().c_str()); thread_local_string.set("bar"); EXPECT_STREQ("bar", thread_local_string.get().c_str()); std::string result; RunFromThread(&RetrieveThreadLocalValue, make_pair(&thread_local_string, &result)); EXPECT_STREQ("foo", result.c_str()); } // DestructorTracker keeps track of whether its instances have been // destroyed. static std::vector g_destroyed; class DestructorTracker { public: DestructorTracker() : index_(GetNewIndex()) {} DestructorTracker(const DestructorTracker& /* rhs */) : index_(GetNewIndex()) {} ~DestructorTracker() { // We never access g_destroyed concurrently, so we don't need to // protect the write operation under a mutex. g_destroyed[index_] = true; } private: static int GetNewIndex() { g_destroyed.push_back(false); return g_destroyed.size() - 1; } const int index_; }; typedef ThreadLocal* ThreadParam; void CallThreadLocalGet(ThreadParam thread_local_param) { thread_local_param->get(); } // Tests that when a ThreadLocal object dies in a thread, it destroys // the managed object for that thread. TEST(ThreadLocalTest, DestroysManagedObjectForOwnThreadWhenDying) { g_destroyed.clear(); { // The next line default constructs a DestructorTracker object as // the default value of objects managed by thread_local_tracker. ThreadLocal thread_local_tracker; ASSERT_EQ(1U, g_destroyed.size()); ASSERT_FALSE(g_destroyed[0]); // This creates another DestructorTracker object for the main thread. thread_local_tracker.get(); ASSERT_EQ(2U, g_destroyed.size()); ASSERT_FALSE(g_destroyed[0]); ASSERT_FALSE(g_destroyed[1]); } // Now thread_local_tracker has died. It should have destroyed both the // default value shared by all threads and the value for the main // thread. ASSERT_EQ(2U, g_destroyed.size()); EXPECT_TRUE(g_destroyed[0]); EXPECT_TRUE(g_destroyed[1]); g_destroyed.clear(); } // Tests that when a thread exits, the thread-local object for that // thread is destroyed. TEST(ThreadLocalTest, DestroysManagedObjectAtThreadExit) { g_destroyed.clear(); { // The next line default constructs a DestructorTracker object as // the default value of objects managed by thread_local_tracker. ThreadLocal thread_local_tracker; ASSERT_EQ(1U, g_destroyed.size()); ASSERT_FALSE(g_destroyed[0]); // This creates another DestructorTracker object in the new thread. ThreadWithParam thread( &CallThreadLocalGet, &thread_local_tracker, NULL); thread.Join(); // Now the new thread has exited. The per-thread object for it // should have been destroyed. ASSERT_EQ(2U, g_destroyed.size()); ASSERT_FALSE(g_destroyed[0]); ASSERT_TRUE(g_destroyed[1]); } // Now thread_local_tracker has died. The default value should have been // destroyed too. ASSERT_EQ(2U, g_destroyed.size()); EXPECT_TRUE(g_destroyed[0]); EXPECT_TRUE(g_destroyed[1]); g_destroyed.clear(); } TEST(ThreadLocalTest, ThreadLocalMutationsAffectOnlyCurrentThread) { ThreadLocal thread_local_string; thread_local_string.set("Foo"); EXPECT_STREQ("Foo", thread_local_string.get().c_str()); std::string result; RunFromThread(&RetrieveThreadLocalValue, make_pair(&thread_local_string, &result)); EXPECT_TRUE(result.empty()); } #endif // GTEST_IS_THREADSAFE } // namespace internal } // namespace testing dlt-daemon-2.18.4/gtest-1.7.0/test/gtest-printers_test.cc000066400000000000000000001406641353342203500227530ustar00rootroot00000000000000// Copyright 2007, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: wan@google.com (Zhanyong Wan) // Google Test - The Google C++ Testing Framework // // This file tests the universal value printer. #include "gtest/gtest-printers.h" #include #include #include #include #include #include #include #include #include #include #include #include #include "gtest/gtest.h" // hash_map and hash_set are available under Visual C++. #if _MSC_VER # define GTEST_HAS_HASH_MAP_ 1 // Indicates that hash_map is available. # include // NOLINT # define GTEST_HAS_HASH_SET_ 1 // Indicates that hash_set is available. # include // NOLINT #endif // GTEST_OS_WINDOWS // Some user-defined types for testing the universal value printer. // An anonymous enum type. enum AnonymousEnum { kAE1 = -1, kAE2 = 1 }; // An enum without a user-defined printer. enum EnumWithoutPrinter { kEWP1 = -2, kEWP2 = 42 }; // An enum with a << operator. enum EnumWithStreaming { kEWS1 = 10 }; std::ostream& operator<<(std::ostream& os, EnumWithStreaming e) { return os << (e == kEWS1 ? "kEWS1" : "invalid"); } // An enum with a PrintTo() function. enum EnumWithPrintTo { kEWPT1 = 1 }; void PrintTo(EnumWithPrintTo e, std::ostream* os) { *os << (e == kEWPT1 ? "kEWPT1" : "invalid"); } // A class implicitly convertible to BiggestInt. class BiggestIntConvertible { public: operator ::testing::internal::BiggestInt() const { return 42; } }; // A user-defined unprintable class template in the global namespace. template class UnprintableTemplateInGlobal { public: UnprintableTemplateInGlobal() : value_() {} private: T value_; }; // A user-defined streamable type in the global namespace. class StreamableInGlobal { public: virtual ~StreamableInGlobal() {} }; inline void operator<<(::std::ostream& os, const StreamableInGlobal& /* x */) { os << "StreamableInGlobal"; } void operator<<(::std::ostream& os, const StreamableInGlobal* /* x */) { os << "StreamableInGlobal*"; } namespace foo { // A user-defined unprintable type in a user namespace. class UnprintableInFoo { public: UnprintableInFoo() : z_(0) { memcpy(xy_, "\xEF\x12\x0\x0\x34\xAB\x0\x0", 8); } private: char xy_[8]; double z_; }; // A user-defined printable type in a user-chosen namespace. struct PrintableViaPrintTo { PrintableViaPrintTo() : value() {} int value; }; void PrintTo(const PrintableViaPrintTo& x, ::std::ostream* os) { *os << "PrintableViaPrintTo: " << x.value; } // A type with a user-defined << for printing its pointer. struct PointerPrintable { }; ::std::ostream& operator<<(::std::ostream& os, const PointerPrintable* /* x */) { return os << "PointerPrintable*"; } // A user-defined printable class template in a user-chosen namespace. template class PrintableViaPrintToTemplate { public: explicit PrintableViaPrintToTemplate(const T& a_value) : value_(a_value) {} const T& value() const { return value_; } private: T value_; }; template void PrintTo(const PrintableViaPrintToTemplate& x, ::std::ostream* os) { *os << "PrintableViaPrintToTemplate: " << x.value(); } // A user-defined streamable class template in a user namespace. template class StreamableTemplateInFoo { public: StreamableTemplateInFoo() : value_() {} const T& value() const { return value_; } private: T value_; }; template inline ::std::ostream& operator<<(::std::ostream& os, const StreamableTemplateInFoo& x) { return os << "StreamableTemplateInFoo: " << x.value(); } } // namespace foo namespace testing { namespace gtest_printers_test { using ::std::deque; using ::std::list; using ::std::make_pair; using ::std::map; using ::std::multimap; using ::std::multiset; using ::std::pair; using ::std::set; using ::std::vector; using ::testing::PrintToString; using ::testing::internal::FormatForComparisonFailureMessage; using ::testing::internal::ImplicitCast_; using ::testing::internal::NativeArray; using ::testing::internal::RE; using ::testing::internal::Strings; using ::testing::internal::UniversalPrint; using ::testing::internal::UniversalPrinter; using ::testing::internal::UniversalTersePrint; using ::testing::internal::UniversalTersePrintTupleFieldsToStrings; using ::testing::internal::kReference; using ::testing::internal::string; #if GTEST_HAS_TR1_TUPLE using ::std::tr1::make_tuple; using ::std::tr1::tuple; #endif // The hash_* classes are not part of the C++ standard. STLport // defines them in namespace std. MSVC defines them in ::stdext. GCC // defines them in ::. #ifdef _STLP_HASH_MAP // We got from STLport. using ::std::hash_map; using ::std::hash_set; using ::std::hash_multimap; using ::std::hash_multiset; #elif _MSC_VER using ::stdext::hash_map; using ::stdext::hash_set; using ::stdext::hash_multimap; using ::stdext::hash_multiset; #endif // Prints a value to a string using the universal value printer. This // is a helper for testing UniversalPrinter::Print() for various types. template string Print(const T& value) { ::std::stringstream ss; UniversalPrinter::Print(value, &ss); return ss.str(); } // Prints a value passed by reference to a string, using the universal // value printer. This is a helper for testing // UniversalPrinter::Print() for various types. template string PrintByRef(const T& value) { ::std::stringstream ss; UniversalPrinter::Print(value, &ss); return ss.str(); } // Tests printing various enum types. TEST(PrintEnumTest, AnonymousEnum) { EXPECT_EQ("-1", Print(kAE1)); EXPECT_EQ("1", Print(kAE2)); } TEST(PrintEnumTest, EnumWithoutPrinter) { EXPECT_EQ("-2", Print(kEWP1)); EXPECT_EQ("42", Print(kEWP2)); } TEST(PrintEnumTest, EnumWithStreaming) { EXPECT_EQ("kEWS1", Print(kEWS1)); EXPECT_EQ("invalid", Print(static_cast(0))); } TEST(PrintEnumTest, EnumWithPrintTo) { EXPECT_EQ("kEWPT1", Print(kEWPT1)); EXPECT_EQ("invalid", Print(static_cast(0))); } // Tests printing a class implicitly convertible to BiggestInt. TEST(PrintClassTest, BiggestIntConvertible) { EXPECT_EQ("42", Print(BiggestIntConvertible())); } // Tests printing various char types. // char. TEST(PrintCharTest, PlainChar) { EXPECT_EQ("'\\0'", Print('\0')); EXPECT_EQ("'\\'' (39, 0x27)", Print('\'')); EXPECT_EQ("'\"' (34, 0x22)", Print('"')); EXPECT_EQ("'?' (63, 0x3F)", Print('?')); EXPECT_EQ("'\\\\' (92, 0x5C)", Print('\\')); EXPECT_EQ("'\\a' (7)", Print('\a')); EXPECT_EQ("'\\b' (8)", Print('\b')); EXPECT_EQ("'\\f' (12, 0xC)", Print('\f')); EXPECT_EQ("'\\n' (10, 0xA)", Print('\n')); EXPECT_EQ("'\\r' (13, 0xD)", Print('\r')); EXPECT_EQ("'\\t' (9)", Print('\t')); EXPECT_EQ("'\\v' (11, 0xB)", Print('\v')); EXPECT_EQ("'\\x7F' (127)", Print('\x7F')); EXPECT_EQ("'\\xFF' (255)", Print('\xFF')); EXPECT_EQ("' ' (32, 0x20)", Print(' ')); EXPECT_EQ("'a' (97, 0x61)", Print('a')); } // signed char. TEST(PrintCharTest, SignedChar) { EXPECT_EQ("'\\0'", Print(static_cast('\0'))); EXPECT_EQ("'\\xCE' (-50)", Print(static_cast(-50))); } // unsigned char. TEST(PrintCharTest, UnsignedChar) { EXPECT_EQ("'\\0'", Print(static_cast('\0'))); EXPECT_EQ("'b' (98, 0x62)", Print(static_cast('b'))); } // Tests printing other simple, built-in types. // bool. TEST(PrintBuiltInTypeTest, Bool) { EXPECT_EQ("false", Print(false)); EXPECT_EQ("true", Print(true)); } // wchar_t. TEST(PrintBuiltInTypeTest, Wchar_t) { EXPECT_EQ("L'\\0'", Print(L'\0')); EXPECT_EQ("L'\\'' (39, 0x27)", Print(L'\'')); EXPECT_EQ("L'\"' (34, 0x22)", Print(L'"')); EXPECT_EQ("L'?' (63, 0x3F)", Print(L'?')); EXPECT_EQ("L'\\\\' (92, 0x5C)", Print(L'\\')); EXPECT_EQ("L'\\a' (7)", Print(L'\a')); EXPECT_EQ("L'\\b' (8)", Print(L'\b')); EXPECT_EQ("L'\\f' (12, 0xC)", Print(L'\f')); EXPECT_EQ("L'\\n' (10, 0xA)", Print(L'\n')); EXPECT_EQ("L'\\r' (13, 0xD)", Print(L'\r')); EXPECT_EQ("L'\\t' (9)", Print(L'\t')); EXPECT_EQ("L'\\v' (11, 0xB)", Print(L'\v')); EXPECT_EQ("L'\\x7F' (127)", Print(L'\x7F')); EXPECT_EQ("L'\\xFF' (255)", Print(L'\xFF')); EXPECT_EQ("L' ' (32, 0x20)", Print(L' ')); EXPECT_EQ("L'a' (97, 0x61)", Print(L'a')); EXPECT_EQ("L'\\x576' (1398)", Print(static_cast(0x576))); EXPECT_EQ("L'\\xC74D' (51021)", Print(static_cast(0xC74D))); } // Test that Int64 provides more storage than wchar_t. TEST(PrintTypeSizeTest, Wchar_t) { EXPECT_LT(sizeof(wchar_t), sizeof(testing::internal::Int64)); } // Various integer types. TEST(PrintBuiltInTypeTest, Integer) { EXPECT_EQ("'\\xFF' (255)", Print(static_cast(255))); // uint8 EXPECT_EQ("'\\x80' (-128)", Print(static_cast(-128))); // int8 EXPECT_EQ("65535", Print(USHRT_MAX)); // uint16 EXPECT_EQ("-32768", Print(SHRT_MIN)); // int16 EXPECT_EQ("4294967295", Print(UINT_MAX)); // uint32 EXPECT_EQ("-2147483648", Print(INT_MIN)); // int32 EXPECT_EQ("18446744073709551615", Print(static_cast(-1))); // uint64 EXPECT_EQ("-9223372036854775808", Print(static_cast(1) << 63)); // int64 } // Size types. TEST(PrintBuiltInTypeTest, Size_t) { EXPECT_EQ("1", Print(sizeof('a'))); // size_t. #if !GTEST_OS_WINDOWS // Windows has no ssize_t type. EXPECT_EQ("-2", Print(static_cast(-2))); // ssize_t. #endif // !GTEST_OS_WINDOWS } // Floating-points. TEST(PrintBuiltInTypeTest, FloatingPoints) { EXPECT_EQ("1.5", Print(1.5f)); // float EXPECT_EQ("-2.5", Print(-2.5)); // double } // Since ::std::stringstream::operator<<(const void *) formats the pointer // output differently with different compilers, we have to create the expected // output first and use it as our expectation. static string PrintPointer(const void *p) { ::std::stringstream expected_result_stream; expected_result_stream << p; return expected_result_stream.str(); } // Tests printing C strings. // const char*. TEST(PrintCStringTest, Const) { const char* p = "World"; EXPECT_EQ(PrintPointer(p) + " pointing to \"World\"", Print(p)); } // char*. TEST(PrintCStringTest, NonConst) { char p[] = "Hi"; EXPECT_EQ(PrintPointer(p) + " pointing to \"Hi\"", Print(static_cast(p))); } // NULL C string. TEST(PrintCStringTest, Null) { const char* p = NULL; EXPECT_EQ("NULL", Print(p)); } // Tests that C strings are escaped properly. TEST(PrintCStringTest, EscapesProperly) { const char* p = "'\"?\\\a\b\f\n\r\t\v\x7F\xFF a"; EXPECT_EQ(PrintPointer(p) + " pointing to \"'\\\"?\\\\\\a\\b\\f" "\\n\\r\\t\\v\\x7F\\xFF a\"", Print(p)); } // MSVC compiler can be configured to define whar_t as a typedef // of unsigned short. Defining an overload for const wchar_t* in that case // would cause pointers to unsigned shorts be printed as wide strings, // possibly accessing more memory than intended and causing invalid // memory accesses. MSVC defines _NATIVE_WCHAR_T_DEFINED symbol when // wchar_t is implemented as a native type. #if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED) // const wchar_t*. TEST(PrintWideCStringTest, Const) { const wchar_t* p = L"World"; EXPECT_EQ(PrintPointer(p) + " pointing to L\"World\"", Print(p)); } // wchar_t*. TEST(PrintWideCStringTest, NonConst) { wchar_t p[] = L"Hi"; EXPECT_EQ(PrintPointer(p) + " pointing to L\"Hi\"", Print(static_cast(p))); } // NULL wide C string. TEST(PrintWideCStringTest, Null) { const wchar_t* p = NULL; EXPECT_EQ("NULL", Print(p)); } // Tests that wide C strings are escaped properly. TEST(PrintWideCStringTest, EscapesProperly) { const wchar_t s[] = {'\'', '"', '?', '\\', '\a', '\b', '\f', '\n', '\r', '\t', '\v', 0xD3, 0x576, 0x8D3, 0xC74D, ' ', 'a', '\0'}; EXPECT_EQ(PrintPointer(s) + " pointing to L\"'\\\"?\\\\\\a\\b\\f" "\\n\\r\\t\\v\\xD3\\x576\\x8D3\\xC74D a\"", Print(static_cast(s))); } #endif // native wchar_t // Tests printing pointers to other char types. // signed char*. TEST(PrintCharPointerTest, SignedChar) { signed char* p = reinterpret_cast(0x1234); EXPECT_EQ(PrintPointer(p), Print(p)); p = NULL; EXPECT_EQ("NULL", Print(p)); } // const signed char*. TEST(PrintCharPointerTest, ConstSignedChar) { signed char* p = reinterpret_cast(0x1234); EXPECT_EQ(PrintPointer(p), Print(p)); p = NULL; EXPECT_EQ("NULL", Print(p)); } // unsigned char*. TEST(PrintCharPointerTest, UnsignedChar) { unsigned char* p = reinterpret_cast(0x1234); EXPECT_EQ(PrintPointer(p), Print(p)); p = NULL; EXPECT_EQ("NULL", Print(p)); } // const unsigned char*. TEST(PrintCharPointerTest, ConstUnsignedChar) { const unsigned char* p = reinterpret_cast(0x1234); EXPECT_EQ(PrintPointer(p), Print(p)); p = NULL; EXPECT_EQ("NULL", Print(p)); } // Tests printing pointers to simple, built-in types. // bool*. TEST(PrintPointerToBuiltInTypeTest, Bool) { bool* p = reinterpret_cast(0xABCD); EXPECT_EQ(PrintPointer(p), Print(p)); p = NULL; EXPECT_EQ("NULL", Print(p)); } // void*. TEST(PrintPointerToBuiltInTypeTest, Void) { void* p = reinterpret_cast(0xABCD); EXPECT_EQ(PrintPointer(p), Print(p)); p = NULL; EXPECT_EQ("NULL", Print(p)); } // const void*. TEST(PrintPointerToBuiltInTypeTest, ConstVoid) { const void* p = reinterpret_cast(0xABCD); EXPECT_EQ(PrintPointer(p), Print(p)); p = NULL; EXPECT_EQ("NULL", Print(p)); } // Tests printing pointers to pointers. TEST(PrintPointerToPointerTest, IntPointerPointer) { int** p = reinterpret_cast(0xABCD); EXPECT_EQ(PrintPointer(p), Print(p)); p = NULL; EXPECT_EQ("NULL", Print(p)); } // Tests printing (non-member) function pointers. void MyFunction(int /* n */) {} TEST(PrintPointerTest, NonMemberFunctionPointer) { // We cannot directly cast &MyFunction to const void* because the // standard disallows casting between pointers to functions and // pointers to objects, and some compilers (e.g. GCC 3.4) enforce // this limitation. EXPECT_EQ( PrintPointer(reinterpret_cast( reinterpret_cast(&MyFunction))), Print(&MyFunction)); int (*p)(bool) = NULL; // NOLINT EXPECT_EQ("NULL", Print(p)); } // An assertion predicate determining whether a one string is a prefix for // another. template AssertionResult HasPrefix(const StringType& str, const StringType& prefix) { if (str.find(prefix, 0) == 0) return AssertionSuccess(); const bool is_wide_string = sizeof(prefix[0]) > 1; const char* const begin_string_quote = is_wide_string ? "L\"" : "\""; return AssertionFailure() << begin_string_quote << prefix << "\" is not a prefix of " << begin_string_quote << str << "\"\n"; } // Tests printing member variable pointers. Although they are called // pointers, they don't point to a location in the address space. // Their representation is implementation-defined. Thus they will be // printed as raw bytes. struct Foo { public: virtual ~Foo() {} int MyMethod(char x) { return x + 1; } virtual char MyVirtualMethod(int /* n */) { return 'a'; } int value; }; TEST(PrintPointerTest, MemberVariablePointer) { EXPECT_TRUE(HasPrefix(Print(&Foo::value), Print(sizeof(&Foo::value)) + "-byte object ")); int (Foo::*p) = NULL; // NOLINT EXPECT_TRUE(HasPrefix(Print(p), Print(sizeof(p)) + "-byte object ")); } // Tests printing member function pointers. Although they are called // pointers, they don't point to a location in the address space. // Their representation is implementation-defined. Thus they will be // printed as raw bytes. TEST(PrintPointerTest, MemberFunctionPointer) { EXPECT_TRUE(HasPrefix(Print(&Foo::MyMethod), Print(sizeof(&Foo::MyMethod)) + "-byte object ")); EXPECT_TRUE( HasPrefix(Print(&Foo::MyVirtualMethod), Print(sizeof((&Foo::MyVirtualMethod))) + "-byte object ")); int (Foo::*p)(char) = NULL; // NOLINT EXPECT_TRUE(HasPrefix(Print(p), Print(sizeof(p)) + "-byte object ")); } // Tests printing C arrays. // The difference between this and Print() is that it ensures that the // argument is a reference to an array. template string PrintArrayHelper(T (&a)[N]) { return Print(a); } // One-dimensional array. TEST(PrintArrayTest, OneDimensionalArray) { int a[5] = { 1, 2, 3, 4, 5 }; EXPECT_EQ("{ 1, 2, 3, 4, 5 }", PrintArrayHelper(a)); } // Two-dimensional array. TEST(PrintArrayTest, TwoDimensionalArray) { int a[2][5] = { { 1, 2, 3, 4, 5 }, { 6, 7, 8, 9, 0 } }; EXPECT_EQ("{ { 1, 2, 3, 4, 5 }, { 6, 7, 8, 9, 0 } }", PrintArrayHelper(a)); } // Array of const elements. TEST(PrintArrayTest, ConstArray) { const bool a[1] = { false }; EXPECT_EQ("{ false }", PrintArrayHelper(a)); } // char array without terminating NUL. TEST(PrintArrayTest, CharArrayWithNoTerminatingNul) { // Array a contains '\0' in the middle and doesn't end with '\0'. char a[] = { 'H', '\0', 'i' }; EXPECT_EQ("\"H\\0i\" (no terminating NUL)", PrintArrayHelper(a)); } // const char array with terminating NUL. TEST(PrintArrayTest, ConstCharArrayWithTerminatingNul) { const char a[] = "\0Hi"; EXPECT_EQ("\"\\0Hi\"", PrintArrayHelper(a)); } // const wchar_t array without terminating NUL. TEST(PrintArrayTest, WCharArrayWithNoTerminatingNul) { // Array a contains '\0' in the middle and doesn't end with '\0'. const wchar_t a[] = { L'H', L'\0', L'i' }; EXPECT_EQ("L\"H\\0i\" (no terminating NUL)", PrintArrayHelper(a)); } // wchar_t array with terminating NUL. TEST(PrintArrayTest, WConstCharArrayWithTerminatingNul) { const wchar_t a[] = L"\0Hi"; EXPECT_EQ("L\"\\0Hi\"", PrintArrayHelper(a)); } // Array of objects. TEST(PrintArrayTest, ObjectArray) { string a[3] = { "Hi", "Hello", "Ni hao" }; EXPECT_EQ("{ \"Hi\", \"Hello\", \"Ni hao\" }", PrintArrayHelper(a)); } // Array with many elements. TEST(PrintArrayTest, BigArray) { int a[100] = { 1, 2, 3 }; EXPECT_EQ("{ 1, 2, 3, 0, 0, 0, 0, 0, ..., 0, 0, 0, 0, 0, 0, 0, 0 }", PrintArrayHelper(a)); } // Tests printing ::string and ::std::string. #if GTEST_HAS_GLOBAL_STRING // ::string. TEST(PrintStringTest, StringInGlobalNamespace) { const char s[] = "'\"?\\\a\b\f\n\0\r\t\v\x7F\xFF a"; const ::string str(s, sizeof(s)); EXPECT_EQ("\"'\\\"?\\\\\\a\\b\\f\\n\\0\\r\\t\\v\\x7F\\xFF a\\0\"", Print(str)); } #endif // GTEST_HAS_GLOBAL_STRING // ::std::string. TEST(PrintStringTest, StringInStdNamespace) { const char s[] = "'\"?\\\a\b\f\n\0\r\t\v\x7F\xFF a"; const ::std::string str(s, sizeof(s)); EXPECT_EQ("\"'\\\"?\\\\\\a\\b\\f\\n\\0\\r\\t\\v\\x7F\\xFF a\\0\"", Print(str)); } TEST(PrintStringTest, StringAmbiguousHex) { // "\x6BANANA" is ambiguous, it can be interpreted as starting with either of: // '\x6', '\x6B', or '\x6BA'. // a hex escaping sequence following by a decimal digit EXPECT_EQ("\"0\\x12\" \"3\"", Print(::std::string("0\x12" "3"))); // a hex escaping sequence following by a hex digit (lower-case) EXPECT_EQ("\"mm\\x6\" \"bananas\"", Print(::std::string("mm\x6" "bananas"))); // a hex escaping sequence following by a hex digit (upper-case) EXPECT_EQ("\"NOM\\x6\" \"BANANA\"", Print(::std::string("NOM\x6" "BANANA"))); // a hex escaping sequence following by a non-xdigit EXPECT_EQ("\"!\\x5-!\"", Print(::std::string("!\x5-!"))); } // Tests printing ::wstring and ::std::wstring. #if GTEST_HAS_GLOBAL_WSTRING // ::wstring. TEST(PrintWideStringTest, StringInGlobalNamespace) { const wchar_t s[] = L"'\"?\\\a\b\f\n\0\r\t\v\xD3\x576\x8D3\xC74D a"; const ::wstring str(s, sizeof(s)/sizeof(wchar_t)); EXPECT_EQ("L\"'\\\"?\\\\\\a\\b\\f\\n\\0\\r\\t\\v" "\\xD3\\x576\\x8D3\\xC74D a\\0\"", Print(str)); } #endif // GTEST_HAS_GLOBAL_WSTRING #if GTEST_HAS_STD_WSTRING // ::std::wstring. TEST(PrintWideStringTest, StringInStdNamespace) { const wchar_t s[] = L"'\"?\\\a\b\f\n\0\r\t\v\xD3\x576\x8D3\xC74D a"; const ::std::wstring str(s, sizeof(s)/sizeof(wchar_t)); EXPECT_EQ("L\"'\\\"?\\\\\\a\\b\\f\\n\\0\\r\\t\\v" "\\xD3\\x576\\x8D3\\xC74D a\\0\"", Print(str)); } TEST(PrintWideStringTest, StringAmbiguousHex) { // same for wide strings. EXPECT_EQ("L\"0\\x12\" L\"3\"", Print(::std::wstring(L"0\x12" L"3"))); EXPECT_EQ("L\"mm\\x6\" L\"bananas\"", Print(::std::wstring(L"mm\x6" L"bananas"))); EXPECT_EQ("L\"NOM\\x6\" L\"BANANA\"", Print(::std::wstring(L"NOM\x6" L"BANANA"))); EXPECT_EQ("L\"!\\x5-!\"", Print(::std::wstring(L"!\x5-!"))); } #endif // GTEST_HAS_STD_WSTRING // Tests printing types that support generic streaming (i.e. streaming // to std::basic_ostream for any valid Char and // CharTraits types). // Tests printing a non-template type that supports generic streaming. class AllowsGenericStreaming {}; template std::basic_ostream& operator<<( std::basic_ostream& os, const AllowsGenericStreaming& /* a */) { return os << "AllowsGenericStreaming"; } TEST(PrintTypeWithGenericStreamingTest, NonTemplateType) { AllowsGenericStreaming a; EXPECT_EQ("AllowsGenericStreaming", Print(a)); } // Tests printing a template type that supports generic streaming. template class AllowsGenericStreamingTemplate {}; template std::basic_ostream& operator<<( std::basic_ostream& os, const AllowsGenericStreamingTemplate& /* a */) { return os << "AllowsGenericStreamingTemplate"; } TEST(PrintTypeWithGenericStreamingTest, TemplateType) { AllowsGenericStreamingTemplate a; EXPECT_EQ("AllowsGenericStreamingTemplate", Print(a)); } // Tests printing a type that supports generic streaming and can be // implicitly converted to another printable type. template class AllowsGenericStreamingAndImplicitConversionTemplate { public: operator bool() const { return false; } }; template std::basic_ostream& operator<<( std::basic_ostream& os, const AllowsGenericStreamingAndImplicitConversionTemplate& /* a */) { return os << "AllowsGenericStreamingAndImplicitConversionTemplate"; } TEST(PrintTypeWithGenericStreamingTest, TypeImplicitlyConvertible) { AllowsGenericStreamingAndImplicitConversionTemplate a; EXPECT_EQ("AllowsGenericStreamingAndImplicitConversionTemplate", Print(a)); } #if GTEST_HAS_STRING_PIECE_ // Tests printing StringPiece. TEST(PrintStringPieceTest, SimpleStringPiece) { const StringPiece sp = "Hello"; EXPECT_EQ("\"Hello\"", Print(sp)); } TEST(PrintStringPieceTest, UnprintableCharacters) { const char str[] = "NUL (\0) and \r\t"; const StringPiece sp(str, sizeof(str) - 1); EXPECT_EQ("\"NUL (\\0) and \\r\\t\"", Print(sp)); } #endif // GTEST_HAS_STRING_PIECE_ // Tests printing STL containers. TEST(PrintStlContainerTest, EmptyDeque) { deque empty; EXPECT_EQ("{}", Print(empty)); } TEST(PrintStlContainerTest, NonEmptyDeque) { deque non_empty; non_empty.push_back(1); non_empty.push_back(3); EXPECT_EQ("{ 1, 3 }", Print(non_empty)); } #if GTEST_HAS_HASH_MAP_ TEST(PrintStlContainerTest, OneElementHashMap) { hash_map map1; map1[1] = 'a'; EXPECT_EQ("{ (1, 'a' (97, 0x61)) }", Print(map1)); } TEST(PrintStlContainerTest, HashMultiMap) { hash_multimap map1; map1.insert(make_pair(5, true)); map1.insert(make_pair(5, false)); // Elements of hash_multimap can be printed in any order. const string result = Print(map1); EXPECT_TRUE(result == "{ (5, true), (5, false) }" || result == "{ (5, false), (5, true) }") << " where Print(map1) returns \"" << result << "\"."; } #endif // GTEST_HAS_HASH_MAP_ #if GTEST_HAS_HASH_SET_ TEST(PrintStlContainerTest, HashSet) { hash_set set1; set1.insert("hello"); EXPECT_EQ("{ \"hello\" }", Print(set1)); } TEST(PrintStlContainerTest, HashMultiSet) { const int kSize = 5; int a[kSize] = { 1, 1, 2, 5, 1 }; hash_multiset set1(a, a + kSize); // Elements of hash_multiset can be printed in any order. const string result = Print(set1); const string expected_pattern = "{ d, d, d, d, d }"; // d means a digit. // Verifies the result matches the expected pattern; also extracts // the numbers in the result. ASSERT_EQ(expected_pattern.length(), result.length()); std::vector numbers; for (size_t i = 0; i != result.length(); i++) { if (expected_pattern[i] == 'd') { ASSERT_NE(isdigit(static_cast(result[i])), 0); numbers.push_back(result[i] - '0'); } else { EXPECT_EQ(expected_pattern[i], result[i]) << " where result is " << result; } } // Makes sure the result contains the right numbers. std::sort(numbers.begin(), numbers.end()); std::sort(a, a + kSize); EXPECT_TRUE(std::equal(a, a + kSize, numbers.begin())); } #endif // GTEST_HAS_HASH_SET_ TEST(PrintStlContainerTest, List) { const string a[] = { "hello", "world" }; const list strings(a, a + 2); EXPECT_EQ("{ \"hello\", \"world\" }", Print(strings)); } TEST(PrintStlContainerTest, Map) { map map1; map1[1] = true; map1[5] = false; map1[3] = true; EXPECT_EQ("{ (1, true), (3, true), (5, false) }", Print(map1)); } TEST(PrintStlContainerTest, MultiMap) { multimap map1; // The make_pair template function would deduce the type as // pair here, and since the key part in a multimap has to // be constant, without a templated ctor in the pair class (as in // libCstd on Solaris), make_pair call would fail to compile as no // implicit conversion is found. Thus explicit typename is used // here instead. map1.insert(pair(true, 0)); map1.insert(pair(true, 1)); map1.insert(pair(false, 2)); EXPECT_EQ("{ (false, 2), (true, 0), (true, 1) }", Print(map1)); } TEST(PrintStlContainerTest, Set) { const unsigned int a[] = { 3, 0, 5 }; set set1(a, a + 3); EXPECT_EQ("{ 0, 3, 5 }", Print(set1)); } TEST(PrintStlContainerTest, MultiSet) { const int a[] = { 1, 1, 2, 5, 1 }; multiset set1(a, a + 5); EXPECT_EQ("{ 1, 1, 1, 2, 5 }", Print(set1)); } TEST(PrintStlContainerTest, Pair) { pair p(true, 5); EXPECT_EQ("(true, 5)", Print(p)); } TEST(PrintStlContainerTest, Vector) { vector v; v.push_back(1); v.push_back(2); EXPECT_EQ("{ 1, 2 }", Print(v)); } TEST(PrintStlContainerTest, LongSequence) { const int a[100] = { 1, 2, 3 }; const vector v(a, a + 100); EXPECT_EQ("{ 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, " "0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ... }", Print(v)); } TEST(PrintStlContainerTest, NestedContainer) { const int a1[] = { 1, 2 }; const int a2[] = { 3, 4, 5 }; const list l1(a1, a1 + 2); const list l2(a2, a2 + 3); vector > v; v.push_back(l1); v.push_back(l2); EXPECT_EQ("{ { 1, 2 }, { 3, 4, 5 } }", Print(v)); } TEST(PrintStlContainerTest, OneDimensionalNativeArray) { const int a[3] = { 1, 2, 3 }; NativeArray b(a, 3, kReference); EXPECT_EQ("{ 1, 2, 3 }", Print(b)); } TEST(PrintStlContainerTest, TwoDimensionalNativeArray) { const int a[2][3] = { { 1, 2, 3 }, { 4, 5, 6 } }; NativeArray b(a, 2, kReference); EXPECT_EQ("{ { 1, 2, 3 }, { 4, 5, 6 } }", Print(b)); } // Tests that a class named iterator isn't treated as a container. struct iterator { char x; }; TEST(PrintStlContainerTest, Iterator) { iterator it = {}; EXPECT_EQ("1-byte object <00>", Print(it)); } // Tests that a class named const_iterator isn't treated as a container. struct const_iterator { char x; }; TEST(PrintStlContainerTest, ConstIterator) { const_iterator it = {}; EXPECT_EQ("1-byte object <00>", Print(it)); } #if GTEST_HAS_TR1_TUPLE // Tests printing tuples. // Tuples of various arities. TEST(PrintTupleTest, VariousSizes) { tuple<> t0; EXPECT_EQ("()", Print(t0)); tuple t1(5); EXPECT_EQ("(5)", Print(t1)); tuple t2('a', true); EXPECT_EQ("('a' (97, 0x61), true)", Print(t2)); tuple t3(false, 2, 3); EXPECT_EQ("(false, 2, 3)", Print(t3)); tuple t4(false, 2, 3, 4); EXPECT_EQ("(false, 2, 3, 4)", Print(t4)); tuple t5(false, 2, 3, 4, true); EXPECT_EQ("(false, 2, 3, 4, true)", Print(t5)); tuple t6(false, 2, 3, 4, true, 6); EXPECT_EQ("(false, 2, 3, 4, true, 6)", Print(t6)); tuple t7(false, 2, 3, 4, true, 6, 7); EXPECT_EQ("(false, 2, 3, 4, true, 6, 7)", Print(t7)); tuple t8( false, 2, 3, 4, true, 6, 7, true); EXPECT_EQ("(false, 2, 3, 4, true, 6, 7, true)", Print(t8)); tuple t9( false, 2, 3, 4, true, 6, 7, true, 9); EXPECT_EQ("(false, 2, 3, 4, true, 6, 7, true, 9)", Print(t9)); const char* const str = "8"; // VC++ 2010's implementation of tuple of C++0x is deficient, requiring // an explicit type cast of NULL to be used. tuple t10(false, 'a', 3, 4, 5, 1.5F, -2.5, str, ImplicitCast_(NULL), "10"); EXPECT_EQ("(false, 'a' (97, 0x61), 3, 4, 5, 1.5, -2.5, " + PrintPointer(str) + " pointing to \"8\", NULL, \"10\")", Print(t10)); } // Nested tuples. TEST(PrintTupleTest, NestedTuple) { tuple, char> nested(make_tuple(5, true), 'a'); EXPECT_EQ("((5, true), 'a' (97, 0x61))", Print(nested)); } #endif // GTEST_HAS_TR1_TUPLE // Tests printing user-defined unprintable types. // Unprintable types in the global namespace. TEST(PrintUnprintableTypeTest, InGlobalNamespace) { EXPECT_EQ("1-byte object <00>", Print(UnprintableTemplateInGlobal())); } // Unprintable types in a user namespace. TEST(PrintUnprintableTypeTest, InUserNamespace) { EXPECT_EQ("16-byte object ", Print(::foo::UnprintableInFoo())); } // Unprintable types are that too big to be printed completely. struct Big { Big() { memset(array, 0, sizeof(array)); } char array[257]; }; TEST(PrintUnpritableTypeTest, BigObject) { EXPECT_EQ("257-byte object <00-00 00-00 00-00 00-00 00-00 00-00 " "00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 " "00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 " "00-00 00-00 00-00 00-00 00-00 00-00 ... 00-00 00-00 00-00 " "00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 " "00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 " "00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00>", Print(Big())); } // Tests printing user-defined streamable types. // Streamable types in the global namespace. TEST(PrintStreamableTypeTest, InGlobalNamespace) { StreamableInGlobal x; EXPECT_EQ("StreamableInGlobal", Print(x)); EXPECT_EQ("StreamableInGlobal*", Print(&x)); } // Printable template types in a user namespace. TEST(PrintStreamableTypeTest, TemplateTypeInUserNamespace) { EXPECT_EQ("StreamableTemplateInFoo: 0", Print(::foo::StreamableTemplateInFoo())); } // Tests printing user-defined types that have a PrintTo() function. TEST(PrintPrintableTypeTest, InUserNamespace) { EXPECT_EQ("PrintableViaPrintTo: 0", Print(::foo::PrintableViaPrintTo())); } // Tests printing a pointer to a user-defined type that has a << // operator for its pointer. TEST(PrintPrintableTypeTest, PointerInUserNamespace) { ::foo::PointerPrintable x; EXPECT_EQ("PointerPrintable*", Print(&x)); } // Tests printing user-defined class template that have a PrintTo() function. TEST(PrintPrintableTypeTest, TemplateInUserNamespace) { EXPECT_EQ("PrintableViaPrintToTemplate: 5", Print(::foo::PrintableViaPrintToTemplate(5))); } #if GTEST_HAS_PROTOBUF_ // Tests printing a protocol message. TEST(PrintProtocolMessageTest, PrintsShortDebugString) { testing::internal::TestMessage msg; msg.set_member("yes"); EXPECT_EQ("", Print(msg)); } // Tests printing a short proto2 message. TEST(PrintProto2MessageTest, PrintsShortDebugStringWhenItIsShort) { testing::internal::FooMessage msg; msg.set_int_field(2); msg.set_string_field("hello"); EXPECT_PRED2(RE::FullMatch, Print(msg), ""); } // Tests printing a long proto2 message. TEST(PrintProto2MessageTest, PrintsDebugStringWhenItIsLong) { testing::internal::FooMessage msg; msg.set_int_field(2); msg.set_string_field("hello"); msg.add_names("peter"); msg.add_names("paul"); msg.add_names("mary"); EXPECT_PRED2(RE::FullMatch, Print(msg), "<\n" "int_field:\\s*2\n" "string_field:\\s*\"hello\"\n" "names:\\s*\"peter\"\n" "names:\\s*\"paul\"\n" "names:\\s*\"mary\"\n" ">"); } #endif // GTEST_HAS_PROTOBUF_ // Tests that the universal printer prints both the address and the // value of a reference. TEST(PrintReferenceTest, PrintsAddressAndValue) { int n = 5; EXPECT_EQ("@" + PrintPointer(&n) + " 5", PrintByRef(n)); int a[2][3] = { { 0, 1, 2 }, { 3, 4, 5 } }; EXPECT_EQ("@" + PrintPointer(a) + " { { 0, 1, 2 }, { 3, 4, 5 } }", PrintByRef(a)); const ::foo::UnprintableInFoo x; EXPECT_EQ("@" + PrintPointer(&x) + " 16-byte object " "", PrintByRef(x)); } // Tests that the universal printer prints a function pointer passed by // reference. TEST(PrintReferenceTest, HandlesFunctionPointer) { void (*fp)(int n) = &MyFunction; const string fp_pointer_string = PrintPointer(reinterpret_cast(&fp)); // We cannot directly cast &MyFunction to const void* because the // standard disallows casting between pointers to functions and // pointers to objects, and some compilers (e.g. GCC 3.4) enforce // this limitation. const string fp_string = PrintPointer(reinterpret_cast( reinterpret_cast(fp))); EXPECT_EQ("@" + fp_pointer_string + " " + fp_string, PrintByRef(fp)); } // Tests that the universal printer prints a member function pointer // passed by reference. TEST(PrintReferenceTest, HandlesMemberFunctionPointer) { int (Foo::*p)(char ch) = &Foo::MyMethod; EXPECT_TRUE(HasPrefix( PrintByRef(p), "@" + PrintPointer(reinterpret_cast(&p)) + " " + Print(sizeof(p)) + "-byte object ")); char (Foo::*p2)(int n) = &Foo::MyVirtualMethod; EXPECT_TRUE(HasPrefix( PrintByRef(p2), "@" + PrintPointer(reinterpret_cast(&p2)) + " " + Print(sizeof(p2)) + "-byte object ")); } // Tests that the universal printer prints a member variable pointer // passed by reference. TEST(PrintReferenceTest, HandlesMemberVariablePointer) { int (Foo::*p) = &Foo::value; // NOLINT EXPECT_TRUE(HasPrefix( PrintByRef(p), "@" + PrintPointer(&p) + " " + Print(sizeof(p)) + "-byte object ")); } // Tests that FormatForComparisonFailureMessage(), which is used to print // an operand in a comparison assertion (e.g. ASSERT_EQ) when the assertion // fails, formats the operand in the desired way. // scalar TEST(FormatForComparisonFailureMessageTest, WorksForScalar) { EXPECT_STREQ("123", FormatForComparisonFailureMessage(123, 124).c_str()); } // non-char pointer TEST(FormatForComparisonFailureMessageTest, WorksForNonCharPointer) { int n = 0; EXPECT_EQ(PrintPointer(&n), FormatForComparisonFailureMessage(&n, &n).c_str()); } // non-char array TEST(FormatForComparisonFailureMessageTest, FormatsNonCharArrayAsPointer) { // In expression 'array == x', 'array' is compared by pointer. // Therefore we want to print an array operand as a pointer. int n[] = { 1, 2, 3 }; EXPECT_EQ(PrintPointer(n), FormatForComparisonFailureMessage(n, n).c_str()); } // Tests formatting a char pointer when it's compared with another pointer. // In this case we want to print it as a raw pointer, as the comparision is by // pointer. // char pointer vs pointer TEST(FormatForComparisonFailureMessageTest, WorksForCharPointerVsPointer) { // In expression 'p == x', where 'p' and 'x' are (const or not) char // pointers, the operands are compared by pointer. Therefore we // want to print 'p' as a pointer instead of a C string (we don't // even know if it's supposed to point to a valid C string). // const char* const char* s = "hello"; EXPECT_EQ(PrintPointer(s), FormatForComparisonFailureMessage(s, s).c_str()); // char* char ch = 'a'; EXPECT_EQ(PrintPointer(&ch), FormatForComparisonFailureMessage(&ch, &ch).c_str()); } // wchar_t pointer vs pointer TEST(FormatForComparisonFailureMessageTest, WorksForWCharPointerVsPointer) { // In expression 'p == x', where 'p' and 'x' are (const or not) char // pointers, the operands are compared by pointer. Therefore we // want to print 'p' as a pointer instead of a wide C string (we don't // even know if it's supposed to point to a valid wide C string). // const wchar_t* const wchar_t* s = L"hello"; EXPECT_EQ(PrintPointer(s), FormatForComparisonFailureMessage(s, s).c_str()); // wchar_t* wchar_t ch = L'a'; EXPECT_EQ(PrintPointer(&ch), FormatForComparisonFailureMessage(&ch, &ch).c_str()); } // Tests formatting a char pointer when it's compared to a string object. // In this case we want to print the char pointer as a C string. #if GTEST_HAS_GLOBAL_STRING // char pointer vs ::string TEST(FormatForComparisonFailureMessageTest, WorksForCharPointerVsString) { const char* s = "hello \"world"; EXPECT_STREQ("\"hello \\\"world\"", // The string content should be escaped. FormatForComparisonFailureMessage(s, ::string()).c_str()); // char* char str[] = "hi\1"; char* p = str; EXPECT_STREQ("\"hi\\x1\"", // The string content should be escaped. FormatForComparisonFailureMessage(p, ::string()).c_str()); } #endif // char pointer vs std::string TEST(FormatForComparisonFailureMessageTest, WorksForCharPointerVsStdString) { const char* s = "hello \"world"; EXPECT_STREQ("\"hello \\\"world\"", // The string content should be escaped. FormatForComparisonFailureMessage(s, ::std::string()).c_str()); // char* char str[] = "hi\1"; char* p = str; EXPECT_STREQ("\"hi\\x1\"", // The string content should be escaped. FormatForComparisonFailureMessage(p, ::std::string()).c_str()); } #if GTEST_HAS_GLOBAL_WSTRING // wchar_t pointer vs ::wstring TEST(FormatForComparisonFailureMessageTest, WorksForWCharPointerVsWString) { const wchar_t* s = L"hi \"world"; EXPECT_STREQ("L\"hi \\\"world\"", // The string content should be escaped. FormatForComparisonFailureMessage(s, ::wstring()).c_str()); // wchar_t* wchar_t str[] = L"hi\1"; wchar_t* p = str; EXPECT_STREQ("L\"hi\\x1\"", // The string content should be escaped. FormatForComparisonFailureMessage(p, ::wstring()).c_str()); } #endif #if GTEST_HAS_STD_WSTRING // wchar_t pointer vs std::wstring TEST(FormatForComparisonFailureMessageTest, WorksForWCharPointerVsStdWString) { const wchar_t* s = L"hi \"world"; EXPECT_STREQ("L\"hi \\\"world\"", // The string content should be escaped. FormatForComparisonFailureMessage(s, ::std::wstring()).c_str()); // wchar_t* wchar_t str[] = L"hi\1"; wchar_t* p = str; EXPECT_STREQ("L\"hi\\x1\"", // The string content should be escaped. FormatForComparisonFailureMessage(p, ::std::wstring()).c_str()); } #endif // Tests formatting a char array when it's compared with a pointer or array. // In this case we want to print the array as a row pointer, as the comparison // is by pointer. // char array vs pointer TEST(FormatForComparisonFailureMessageTest, WorksForCharArrayVsPointer) { char str[] = "hi \"world\""; char* p = NULL; EXPECT_EQ(PrintPointer(str), FormatForComparisonFailureMessage(str, p).c_str()); } // char array vs char array TEST(FormatForComparisonFailureMessageTest, WorksForCharArrayVsCharArray) { const char str[] = "hi \"world\""; EXPECT_EQ(PrintPointer(str), FormatForComparisonFailureMessage(str, str).c_str()); } // wchar_t array vs pointer TEST(FormatForComparisonFailureMessageTest, WorksForWCharArrayVsPointer) { wchar_t str[] = L"hi \"world\""; wchar_t* p = NULL; EXPECT_EQ(PrintPointer(str), FormatForComparisonFailureMessage(str, p).c_str()); } // wchar_t array vs wchar_t array TEST(FormatForComparisonFailureMessageTest, WorksForWCharArrayVsWCharArray) { const wchar_t str[] = L"hi \"world\""; EXPECT_EQ(PrintPointer(str), FormatForComparisonFailureMessage(str, str).c_str()); } // Tests formatting a char array when it's compared with a string object. // In this case we want to print the array as a C string. #if GTEST_HAS_GLOBAL_STRING // char array vs string TEST(FormatForComparisonFailureMessageTest, WorksForCharArrayVsString) { const char str[] = "hi \"w\0rld\""; EXPECT_STREQ("\"hi \\\"w\"", // The content should be escaped. // Embedded NUL terminates the string. FormatForComparisonFailureMessage(str, ::string()).c_str()); } #endif // char array vs std::string TEST(FormatForComparisonFailureMessageTest, WorksForCharArrayVsStdString) { const char str[] = "hi \"world\""; EXPECT_STREQ("\"hi \\\"world\\\"\"", // The content should be escaped. FormatForComparisonFailureMessage(str, ::std::string()).c_str()); } #if GTEST_HAS_GLOBAL_WSTRING // wchar_t array vs wstring TEST(FormatForComparisonFailureMessageTest, WorksForWCharArrayVsWString) { const wchar_t str[] = L"hi \"world\""; EXPECT_STREQ("L\"hi \\\"world\\\"\"", // The content should be escaped. FormatForComparisonFailureMessage(str, ::wstring()).c_str()); } #endif #if GTEST_HAS_STD_WSTRING // wchar_t array vs std::wstring TEST(FormatForComparisonFailureMessageTest, WorksForWCharArrayVsStdWString) { const wchar_t str[] = L"hi \"w\0rld\""; EXPECT_STREQ( "L\"hi \\\"w\"", // The content should be escaped. // Embedded NUL terminates the string. FormatForComparisonFailureMessage(str, ::std::wstring()).c_str()); } #endif // Useful for testing PrintToString(). We cannot use EXPECT_EQ() // there as its implementation uses PrintToString(). The caller must // ensure that 'value' has no side effect. #define EXPECT_PRINT_TO_STRING_(value, expected_string) \ EXPECT_TRUE(PrintToString(value) == (expected_string)) \ << " where " #value " prints as " << (PrintToString(value)) TEST(PrintToStringTest, WorksForScalar) { EXPECT_PRINT_TO_STRING_(123, "123"); } TEST(PrintToStringTest, WorksForPointerToConstChar) { const char* p = "hello"; EXPECT_PRINT_TO_STRING_(p, "\"hello\""); } TEST(PrintToStringTest, WorksForPointerToNonConstChar) { char s[] = "hello"; char* p = s; EXPECT_PRINT_TO_STRING_(p, "\"hello\""); } TEST(PrintToStringTest, EscapesForPointerToConstChar) { const char* p = "hello\n"; EXPECT_PRINT_TO_STRING_(p, "\"hello\\n\""); } TEST(PrintToStringTest, EscapesForPointerToNonConstChar) { char s[] = "hello\1"; char* p = s; EXPECT_PRINT_TO_STRING_(p, "\"hello\\x1\""); } TEST(PrintToStringTest, WorksForArray) { int n[3] = { 1, 2, 3 }; EXPECT_PRINT_TO_STRING_(n, "{ 1, 2, 3 }"); } TEST(PrintToStringTest, WorksForCharArray) { char s[] = "hello"; EXPECT_PRINT_TO_STRING_(s, "\"hello\""); } TEST(PrintToStringTest, WorksForCharArrayWithEmbeddedNul) { const char str_with_nul[] = "hello\0 world"; EXPECT_PRINT_TO_STRING_(str_with_nul, "\"hello\\0 world\""); char mutable_str_with_nul[] = "hello\0 world"; EXPECT_PRINT_TO_STRING_(mutable_str_with_nul, "\"hello\\0 world\""); } #undef EXPECT_PRINT_TO_STRING_ TEST(UniversalTersePrintTest, WorksForNonReference) { ::std::stringstream ss; UniversalTersePrint(123, &ss); EXPECT_EQ("123", ss.str()); } TEST(UniversalTersePrintTest, WorksForReference) { const int& n = 123; ::std::stringstream ss; UniversalTersePrint(n, &ss); EXPECT_EQ("123", ss.str()); } TEST(UniversalTersePrintTest, WorksForCString) { const char* s1 = "abc"; ::std::stringstream ss1; UniversalTersePrint(s1, &ss1); EXPECT_EQ("\"abc\"", ss1.str()); char* s2 = const_cast(s1); ::std::stringstream ss2; UniversalTersePrint(s2, &ss2); EXPECT_EQ("\"abc\"", ss2.str()); const char* s3 = NULL; ::std::stringstream ss3; UniversalTersePrint(s3, &ss3); EXPECT_EQ("NULL", ss3.str()); } TEST(UniversalPrintTest, WorksForNonReference) { ::std::stringstream ss; UniversalPrint(123, &ss); EXPECT_EQ("123", ss.str()); } TEST(UniversalPrintTest, WorksForReference) { const int& n = 123; ::std::stringstream ss; UniversalPrint(n, &ss); EXPECT_EQ("123", ss.str()); } TEST(UniversalPrintTest, WorksForCString) { const char* s1 = "abc"; ::std::stringstream ss1; UniversalPrint(s1, &ss1); EXPECT_EQ(PrintPointer(s1) + " pointing to \"abc\"", string(ss1.str())); char* s2 = const_cast(s1); ::std::stringstream ss2; UniversalPrint(s2, &ss2); EXPECT_EQ(PrintPointer(s2) + " pointing to \"abc\"", string(ss2.str())); const char* s3 = NULL; ::std::stringstream ss3; UniversalPrint(s3, &ss3); EXPECT_EQ("NULL", ss3.str()); } TEST(UniversalPrintTest, WorksForCharArray) { const char str[] = "\"Line\0 1\"\nLine 2"; ::std::stringstream ss1; UniversalPrint(str, &ss1); EXPECT_EQ("\"\\\"Line\\0 1\\\"\\nLine 2\"", ss1.str()); const char mutable_str[] = "\"Line\0 1\"\nLine 2"; ::std::stringstream ss2; UniversalPrint(mutable_str, &ss2); EXPECT_EQ("\"\\\"Line\\0 1\\\"\\nLine 2\"", ss2.str()); } #if GTEST_HAS_TR1_TUPLE TEST(UniversalTersePrintTupleFieldsToStringsTest, PrintsEmptyTuple) { Strings result = UniversalTersePrintTupleFieldsToStrings(make_tuple()); EXPECT_EQ(0u, result.size()); } TEST(UniversalTersePrintTupleFieldsToStringsTest, PrintsOneTuple) { Strings result = UniversalTersePrintTupleFieldsToStrings(make_tuple(1)); ASSERT_EQ(1u, result.size()); EXPECT_EQ("1", result[0]); } TEST(UniversalTersePrintTupleFieldsToStringsTest, PrintsTwoTuple) { Strings result = UniversalTersePrintTupleFieldsToStrings(make_tuple(1, 'a')); ASSERT_EQ(2u, result.size()); EXPECT_EQ("1", result[0]); EXPECT_EQ("'a' (97, 0x61)", result[1]); } TEST(UniversalTersePrintTupleFieldsToStringsTest, PrintsTersely) { const int n = 1; Strings result = UniversalTersePrintTupleFieldsToStrings( tuple(n, "a")); ASSERT_EQ(2u, result.size()); EXPECT_EQ("1", result[0]); EXPECT_EQ("\"a\"", result[1]); } #endif // GTEST_HAS_TR1_TUPLE } // namespace gtest_printers_test } // namespace testing dlt-daemon-2.18.4/gtest-1.7.0/test/gtest-test-part_test.cc000066400000000000000000000161621353342203500230230ustar00rootroot00000000000000// Copyright 2008 Google Inc. // All Rights Reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: mheule@google.com (Markus Heule) // #include "gtest/gtest-test-part.h" #include "gtest/gtest.h" using testing::Message; using testing::Test; using testing::TestPartResult; using testing::TestPartResultArray; namespace { // Tests the TestPartResult class. // The test fixture for testing TestPartResult. class TestPartResultTest : public Test { protected: TestPartResultTest() : r1_(TestPartResult::kSuccess, "foo/bar.cc", 10, "Success!"), r2_(TestPartResult::kNonFatalFailure, "foo/bar.cc", -1, "Failure!"), r3_(TestPartResult::kFatalFailure, NULL, -1, "Failure!") {} TestPartResult r1_, r2_, r3_; }; TEST_F(TestPartResultTest, ConstructorWorks) { Message message; message << "something is terribly wrong"; message << static_cast(testing::internal::kStackTraceMarker); message << "some unimportant stack trace"; const TestPartResult result(TestPartResult::kNonFatalFailure, "some_file.cc", 42, message.GetString().c_str()); EXPECT_EQ(TestPartResult::kNonFatalFailure, result.type()); EXPECT_STREQ("some_file.cc", result.file_name()); EXPECT_EQ(42, result.line_number()); EXPECT_STREQ(message.GetString().c_str(), result.message()); EXPECT_STREQ("something is terribly wrong", result.summary()); } TEST_F(TestPartResultTest, ResultAccessorsWork) { const TestPartResult success(TestPartResult::kSuccess, "file.cc", 42, "message"); EXPECT_TRUE(success.passed()); EXPECT_FALSE(success.failed()); EXPECT_FALSE(success.nonfatally_failed()); EXPECT_FALSE(success.fatally_failed()); const TestPartResult nonfatal_failure(TestPartResult::kNonFatalFailure, "file.cc", 42, "message"); EXPECT_FALSE(nonfatal_failure.passed()); EXPECT_TRUE(nonfatal_failure.failed()); EXPECT_TRUE(nonfatal_failure.nonfatally_failed()); EXPECT_FALSE(nonfatal_failure.fatally_failed()); const TestPartResult fatal_failure(TestPartResult::kFatalFailure, "file.cc", 42, "message"); EXPECT_FALSE(fatal_failure.passed()); EXPECT_TRUE(fatal_failure.failed()); EXPECT_FALSE(fatal_failure.nonfatally_failed()); EXPECT_TRUE(fatal_failure.fatally_failed()); } // Tests TestPartResult::type(). TEST_F(TestPartResultTest, type) { EXPECT_EQ(TestPartResult::kSuccess, r1_.type()); EXPECT_EQ(TestPartResult::kNonFatalFailure, r2_.type()); EXPECT_EQ(TestPartResult::kFatalFailure, r3_.type()); } // Tests TestPartResult::file_name(). TEST_F(TestPartResultTest, file_name) { EXPECT_STREQ("foo/bar.cc", r1_.file_name()); EXPECT_STREQ(NULL, r3_.file_name()); } // Tests TestPartResult::line_number(). TEST_F(TestPartResultTest, line_number) { EXPECT_EQ(10, r1_.line_number()); EXPECT_EQ(-1, r2_.line_number()); } // Tests TestPartResult::message(). TEST_F(TestPartResultTest, message) { EXPECT_STREQ("Success!", r1_.message()); } // Tests TestPartResult::passed(). TEST_F(TestPartResultTest, Passed) { EXPECT_TRUE(r1_.passed()); EXPECT_FALSE(r2_.passed()); EXPECT_FALSE(r3_.passed()); } // Tests TestPartResult::failed(). TEST_F(TestPartResultTest, Failed) { EXPECT_FALSE(r1_.failed()); EXPECT_TRUE(r2_.failed()); EXPECT_TRUE(r3_.failed()); } // Tests TestPartResult::fatally_failed(). TEST_F(TestPartResultTest, FatallyFailed) { EXPECT_FALSE(r1_.fatally_failed()); EXPECT_FALSE(r2_.fatally_failed()); EXPECT_TRUE(r3_.fatally_failed()); } // Tests TestPartResult::nonfatally_failed(). TEST_F(TestPartResultTest, NonfatallyFailed) { EXPECT_FALSE(r1_.nonfatally_failed()); EXPECT_TRUE(r2_.nonfatally_failed()); EXPECT_FALSE(r3_.nonfatally_failed()); } // Tests the TestPartResultArray class. class TestPartResultArrayTest : public Test { protected: TestPartResultArrayTest() : r1_(TestPartResult::kNonFatalFailure, "foo/bar.cc", -1, "Failure 1"), r2_(TestPartResult::kFatalFailure, "foo/bar.cc", -1, "Failure 2") {} const TestPartResult r1_, r2_; }; // Tests that TestPartResultArray initially has size 0. TEST_F(TestPartResultArrayTest, InitialSizeIsZero) { TestPartResultArray results; EXPECT_EQ(0, results.size()); } // Tests that TestPartResultArray contains the given TestPartResult // after one Append() operation. TEST_F(TestPartResultArrayTest, ContainsGivenResultAfterAppend) { TestPartResultArray results; results.Append(r1_); EXPECT_EQ(1, results.size()); EXPECT_STREQ("Failure 1", results.GetTestPartResult(0).message()); } // Tests that TestPartResultArray contains the given TestPartResults // after two Append() operations. TEST_F(TestPartResultArrayTest, ContainsGivenResultsAfterTwoAppends) { TestPartResultArray results; results.Append(r1_); results.Append(r2_); EXPECT_EQ(2, results.size()); EXPECT_STREQ("Failure 1", results.GetTestPartResult(0).message()); EXPECT_STREQ("Failure 2", results.GetTestPartResult(1).message()); } typedef TestPartResultArrayTest TestPartResultArrayDeathTest; // Tests that the program dies when GetTestPartResult() is called with // an invalid index. TEST_F(TestPartResultArrayDeathTest, DiesWhenIndexIsOutOfBound) { TestPartResultArray results; results.Append(r1_); EXPECT_DEATH_IF_SUPPORTED(results.GetTestPartResult(-1), ""); EXPECT_DEATH_IF_SUPPORTED(results.GetTestPartResult(1), ""); } // TODO(mheule@google.com): Add a test for the class HasNewFatalFailureHelper. } // namespace dlt-daemon-2.18.4/gtest-1.7.0/test/gtest-tuple_test.cc000066400000000000000000000220421353342203500222230ustar00rootroot00000000000000// Copyright 2007, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: wan@google.com (Zhanyong Wan) #include "gtest/internal/gtest-tuple.h" #include #include "gtest/gtest.h" namespace { using ::std::tr1::get; using ::std::tr1::make_tuple; using ::std::tr1::tuple; using ::std::tr1::tuple_element; using ::std::tr1::tuple_size; using ::testing::StaticAssertTypeEq; // Tests that tuple_element >::type returns TK. TEST(tuple_element_Test, ReturnsElementType) { StaticAssertTypeEq >::type>(); StaticAssertTypeEq >::type>(); StaticAssertTypeEq >::type>(); } // Tests that tuple_size::value gives the number of fields in tuple // type T. TEST(tuple_size_Test, ReturnsNumberOfFields) { EXPECT_EQ(0, +tuple_size >::value); EXPECT_EQ(1, +tuple_size >::value); EXPECT_EQ(1, +tuple_size >::value); EXPECT_EQ(1, +(tuple_size > >::value)); EXPECT_EQ(2, +(tuple_size >::value)); EXPECT_EQ(3, +(tuple_size >::value)); } // Tests comparing a tuple with itself. TEST(ComparisonTest, ComparesWithSelf) { const tuple a(5, 'a', false); EXPECT_TRUE(a == a); EXPECT_FALSE(a != a); } // Tests comparing two tuples with the same value. TEST(ComparisonTest, ComparesEqualTuples) { const tuple a(5, true), b(5, true); EXPECT_TRUE(a == b); EXPECT_FALSE(a != b); } // Tests comparing two different tuples that have no reference fields. TEST(ComparisonTest, ComparesUnequalTuplesWithoutReferenceFields) { typedef tuple FooTuple; const FooTuple a(0, 'x'); const FooTuple b(1, 'a'); EXPECT_TRUE(a != b); EXPECT_FALSE(a == b); const FooTuple c(1, 'b'); EXPECT_TRUE(b != c); EXPECT_FALSE(b == c); } // Tests comparing two different tuples that have reference fields. TEST(ComparisonTest, ComparesUnequalTuplesWithReferenceFields) { typedef tuple FooTuple; int i = 5; const char ch = 'a'; const FooTuple a(i, ch); int j = 6; const FooTuple b(j, ch); EXPECT_TRUE(a != b); EXPECT_FALSE(a == b); j = 5; const char ch2 = 'b'; const FooTuple c(j, ch2); EXPECT_TRUE(b != c); EXPECT_FALSE(b == c); } // Tests that a tuple field with a reference type is an alias of the // variable it's supposed to reference. TEST(ReferenceFieldTest, IsAliasOfReferencedVariable) { int n = 0; tuple t(true, n); n = 1; EXPECT_EQ(n, get<1>(t)) << "Changing a underlying variable should update the reference field."; // Makes sure that the implementation doesn't do anything funny with // the & operator for the return type of get<>(). EXPECT_EQ(&n, &(get<1>(t))) << "The address of a reference field should equal the address of " << "the underlying variable."; get<1>(t) = 2; EXPECT_EQ(2, n) << "Changing a reference field should update the underlying variable."; } // Tests that tuple's default constructor default initializes each field. // This test needs to compile without generating warnings. TEST(TupleConstructorTest, DefaultConstructorDefaultInitializesEachField) { // The TR1 report requires that tuple's default constructor default // initializes each field, even if it's a primitive type. If the // implementation forgets to do this, this test will catch it by // generating warnings about using uninitialized variables (assuming // a decent compiler). tuple<> empty; tuple a1, b1; b1 = a1; EXPECT_EQ(0, get<0>(b1)); tuple a2, b2; b2 = a2; EXPECT_EQ(0, get<0>(b2)); EXPECT_EQ(0.0, get<1>(b2)); tuple a3, b3; b3 = a3; EXPECT_EQ(0.0, get<0>(b3)); EXPECT_EQ('\0', get<1>(b3)); EXPECT_TRUE(get<2>(b3) == NULL); tuple a10, b10; b10 = a10; EXPECT_EQ(0, get<0>(b10)); EXPECT_EQ(0, get<1>(b10)); EXPECT_EQ(0, get<2>(b10)); EXPECT_EQ(0, get<3>(b10)); EXPECT_EQ(0, get<4>(b10)); EXPECT_EQ(0, get<5>(b10)); EXPECT_EQ(0, get<6>(b10)); EXPECT_EQ(0, get<7>(b10)); EXPECT_EQ(0, get<8>(b10)); EXPECT_EQ(0, get<9>(b10)); } // Tests constructing a tuple from its fields. TEST(TupleConstructorTest, ConstructsFromFields) { int n = 1; // Reference field. tuple a(n); EXPECT_EQ(&n, &(get<0>(a))); // Non-reference fields. tuple b(5, 'a'); EXPECT_EQ(5, get<0>(b)); EXPECT_EQ('a', get<1>(b)); // Const reference field. const int m = 2; tuple c(true, m); EXPECT_TRUE(get<0>(c)); EXPECT_EQ(&m, &(get<1>(c))); } // Tests tuple's copy constructor. TEST(TupleConstructorTest, CopyConstructor) { tuple a(0.0, true); tuple b(a); EXPECT_DOUBLE_EQ(0.0, get<0>(b)); EXPECT_TRUE(get<1>(b)); } // Tests constructing a tuple from another tuple that has a compatible // but different type. TEST(TupleConstructorTest, ConstructsFromDifferentTupleType) { tuple a(0, 1, 'a'); tuple b(a); EXPECT_DOUBLE_EQ(0.0, get<0>(b)); EXPECT_EQ(1, get<1>(b)); EXPECT_EQ('a', get<2>(b)); } // Tests constructing a 2-tuple from an std::pair. TEST(TupleConstructorTest, ConstructsFromPair) { ::std::pair a(1, 'a'); tuple b(a); tuple c(a); } // Tests assigning a tuple to another tuple with the same type. TEST(TupleAssignmentTest, AssignsToSameTupleType) { const tuple a(5, 7L); tuple b; b = a; EXPECT_EQ(5, get<0>(b)); EXPECT_EQ(7L, get<1>(b)); } // Tests assigning a tuple to another tuple with a different but // compatible type. TEST(TupleAssignmentTest, AssignsToDifferentTupleType) { const tuple a(1, 7L, true); tuple b; b = a; EXPECT_EQ(1L, get<0>(b)); EXPECT_EQ(7, get<1>(b)); EXPECT_TRUE(get<2>(b)); } // Tests assigning an std::pair to a 2-tuple. TEST(TupleAssignmentTest, AssignsFromPair) { const ::std::pair a(5, true); tuple b; b = a; EXPECT_EQ(5, get<0>(b)); EXPECT_TRUE(get<1>(b)); tuple c; c = a; EXPECT_EQ(5L, get<0>(c)); EXPECT_TRUE(get<1>(c)); } // A fixture for testing big tuples. class BigTupleTest : public testing::Test { protected: typedef tuple BigTuple; BigTupleTest() : a_(1, 0, 0, 0, 0, 0, 0, 0, 0, 2), b_(1, 0, 0, 0, 0, 0, 0, 0, 0, 3) {} BigTuple a_, b_; }; // Tests constructing big tuples. TEST_F(BigTupleTest, Construction) { BigTuple a; BigTuple b(b_); } // Tests that get(t) returns the N-th (0-based) field of tuple t. TEST_F(BigTupleTest, get) { EXPECT_EQ(1, get<0>(a_)); EXPECT_EQ(2, get<9>(a_)); // Tests that get() works on a const tuple too. const BigTuple a(a_); EXPECT_EQ(1, get<0>(a)); EXPECT_EQ(2, get<9>(a)); } // Tests comparing big tuples. TEST_F(BigTupleTest, Comparisons) { EXPECT_TRUE(a_ == a_); EXPECT_FALSE(a_ != a_); EXPECT_TRUE(a_ != b_); EXPECT_FALSE(a_ == b_); } TEST(MakeTupleTest, WorksForScalarTypes) { tuple a; a = make_tuple(true, 5); EXPECT_TRUE(get<0>(a)); EXPECT_EQ(5, get<1>(a)); tuple b; b = make_tuple('a', 'b', 5); EXPECT_EQ('a', get<0>(b)); EXPECT_EQ('b', get<1>(b)); EXPECT_EQ(5, get<2>(b)); } TEST(MakeTupleTest, WorksForPointers) { int a[] = { 1, 2, 3, 4 }; const char* const str = "hi"; int* const p = a; tuple t; t = make_tuple(str, p); EXPECT_EQ(str, get<0>(t)); EXPECT_EQ(p, get<1>(t)); } } // namespace dlt-daemon-2.18.4/gtest-1.7.0/test/gtest-typed-test2_test.cc000066400000000000000000000040131353342203500232540ustar00rootroot00000000000000// Copyright 2008 Google Inc. // All Rights Reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: wan@google.com (Zhanyong Wan) #include #include "test/gtest-typed-test_test.h" #include "gtest/gtest.h" #if GTEST_HAS_TYPED_TEST_P // Tests that the same type-parameterized test case can be // instantiated in different translation units linked together. // (ContainerTest is also instantiated in gtest-typed-test_test.cc.) INSTANTIATE_TYPED_TEST_CASE_P(Vector, ContainerTest, testing::Types >); #endif // GTEST_HAS_TYPED_TEST_P dlt-daemon-2.18.4/gtest-1.7.0/test/gtest-typed-test_test.cc000066400000000000000000000261511353342203500232010ustar00rootroot00000000000000// Copyright 2008 Google Inc. // All Rights Reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: wan@google.com (Zhanyong Wan) #include #include #include "test/gtest-typed-test_test.h" #include "gtest/gtest.h" using testing::Test; // Used for testing that SetUpTestCase()/TearDownTestCase(), fixture // ctor/dtor, and SetUp()/TearDown() work correctly in typed tests and // type-parameterized test. template class CommonTest : public Test { // For some technical reason, SetUpTestCase() and TearDownTestCase() // must be public. public: static void SetUpTestCase() { shared_ = new T(5); } static void TearDownTestCase() { delete shared_; shared_ = NULL; } // This 'protected:' is optional. There's no harm in making all // members of this fixture class template public. protected: // We used to use std::list here, but switched to std::vector since // MSVC's doesn't compile cleanly with /W4. typedef std::vector Vector; typedef std::set IntSet; CommonTest() : value_(1) {} virtual ~CommonTest() { EXPECT_EQ(3, value_); } virtual void SetUp() { EXPECT_EQ(1, value_); value_++; } virtual void TearDown() { EXPECT_EQ(2, value_); value_++; } T value_; static T* shared_; }; template T* CommonTest::shared_ = NULL; // This #ifdef block tests typed tests. #if GTEST_HAS_TYPED_TEST using testing::Types; // Tests that SetUpTestCase()/TearDownTestCase(), fixture ctor/dtor, // and SetUp()/TearDown() work correctly in typed tests typedef Types TwoTypes; TYPED_TEST_CASE(CommonTest, TwoTypes); TYPED_TEST(CommonTest, ValuesAreCorrect) { // Static members of the fixture class template can be visited via // the TestFixture:: prefix. EXPECT_EQ(5, *TestFixture::shared_); // Typedefs in the fixture class template can be visited via the // "typename TestFixture::" prefix. typename TestFixture::Vector empty; EXPECT_EQ(0U, empty.size()); typename TestFixture::IntSet empty2; EXPECT_EQ(0U, empty2.size()); // Non-static members of the fixture class must be visited via // 'this', as required by C++ for class templates. EXPECT_EQ(2, this->value_); } // The second test makes sure shared_ is not deleted after the first // test. TYPED_TEST(CommonTest, ValuesAreStillCorrect) { // Static members of the fixture class template can also be visited // via 'this'. ASSERT_TRUE(this->shared_ != NULL); EXPECT_EQ(5, *this->shared_); // TypeParam can be used to refer to the type parameter. EXPECT_EQ(static_cast(2), this->value_); } // Tests that multiple TYPED_TEST_CASE's can be defined in the same // translation unit. template class TypedTest1 : public Test { }; // Verifies that the second argument of TYPED_TEST_CASE can be a // single type. TYPED_TEST_CASE(TypedTest1, int); TYPED_TEST(TypedTest1, A) {} template class TypedTest2 : public Test { }; // Verifies that the second argument of TYPED_TEST_CASE can be a // Types<...> type list. TYPED_TEST_CASE(TypedTest2, Types); // This also verifies that tests from different typed test cases can // share the same name. TYPED_TEST(TypedTest2, A) {} // Tests that a typed test case can be defined in a namespace. namespace library1 { template class NumericTest : public Test { }; typedef Types NumericTypes; TYPED_TEST_CASE(NumericTest, NumericTypes); TYPED_TEST(NumericTest, DefaultIsZero) { EXPECT_EQ(0, TypeParam()); } } // namespace library1 #endif // GTEST_HAS_TYPED_TEST // This #ifdef block tests type-parameterized tests. #if GTEST_HAS_TYPED_TEST_P using testing::Types; using testing::internal::TypedTestCasePState; // Tests TypedTestCasePState. class TypedTestCasePStateTest : public Test { protected: virtual void SetUp() { state_.AddTestName("foo.cc", 0, "FooTest", "A"); state_.AddTestName("foo.cc", 0, "FooTest", "B"); state_.AddTestName("foo.cc", 0, "FooTest", "C"); } TypedTestCasePState state_; }; TEST_F(TypedTestCasePStateTest, SucceedsForMatchingList) { const char* tests = "A, B, C"; EXPECT_EQ(tests, state_.VerifyRegisteredTestNames("foo.cc", 1, tests)); } // Makes sure that the order of the tests and spaces around the names // don't matter. TEST_F(TypedTestCasePStateTest, IgnoresOrderAndSpaces) { const char* tests = "A,C, B"; EXPECT_EQ(tests, state_.VerifyRegisteredTestNames("foo.cc", 1, tests)); } typedef TypedTestCasePStateTest TypedTestCasePStateDeathTest; TEST_F(TypedTestCasePStateDeathTest, DetectsDuplicates) { EXPECT_DEATH_IF_SUPPORTED( state_.VerifyRegisteredTestNames("foo.cc", 1, "A, B, A, C"), "foo\\.cc.1.?: Test A is listed more than once\\."); } TEST_F(TypedTestCasePStateDeathTest, DetectsExtraTest) { EXPECT_DEATH_IF_SUPPORTED( state_.VerifyRegisteredTestNames("foo.cc", 1, "A, B, C, D"), "foo\\.cc.1.?: No test named D can be found in this test case\\."); } TEST_F(TypedTestCasePStateDeathTest, DetectsMissedTest) { EXPECT_DEATH_IF_SUPPORTED( state_.VerifyRegisteredTestNames("foo.cc", 1, "A, C"), "foo\\.cc.1.?: You forgot to list test B\\."); } // Tests that defining a test for a parameterized test case generates // a run-time error if the test case has been registered. TEST_F(TypedTestCasePStateDeathTest, DetectsTestAfterRegistration) { state_.VerifyRegisteredTestNames("foo.cc", 1, "A, B, C"); EXPECT_DEATH_IF_SUPPORTED( state_.AddTestName("foo.cc", 2, "FooTest", "D"), "foo\\.cc.2.?: Test D must be defined before REGISTER_TYPED_TEST_CASE_P" "\\(FooTest, \\.\\.\\.\\)\\."); } // Tests that SetUpTestCase()/TearDownTestCase(), fixture ctor/dtor, // and SetUp()/TearDown() work correctly in type-parameterized tests. template class DerivedTest : public CommonTest { }; TYPED_TEST_CASE_P(DerivedTest); TYPED_TEST_P(DerivedTest, ValuesAreCorrect) { // Static members of the fixture class template can be visited via // the TestFixture:: prefix. EXPECT_EQ(5, *TestFixture::shared_); // Non-static members of the fixture class must be visited via // 'this', as required by C++ for class templates. EXPECT_EQ(2, this->value_); } // The second test makes sure shared_ is not deleted after the first // test. TYPED_TEST_P(DerivedTest, ValuesAreStillCorrect) { // Static members of the fixture class template can also be visited // via 'this'. ASSERT_TRUE(this->shared_ != NULL); EXPECT_EQ(5, *this->shared_); EXPECT_EQ(2, this->value_); } REGISTER_TYPED_TEST_CASE_P(DerivedTest, ValuesAreCorrect, ValuesAreStillCorrect); typedef Types MyTwoTypes; INSTANTIATE_TYPED_TEST_CASE_P(My, DerivedTest, MyTwoTypes); // Tests that multiple TYPED_TEST_CASE_P's can be defined in the same // translation unit. template class TypedTestP1 : public Test { }; TYPED_TEST_CASE_P(TypedTestP1); // For testing that the code between TYPED_TEST_CASE_P() and // TYPED_TEST_P() is not enclosed in a namespace. typedef int IntAfterTypedTestCaseP; TYPED_TEST_P(TypedTestP1, A) {} TYPED_TEST_P(TypedTestP1, B) {} // For testing that the code between TYPED_TEST_P() and // REGISTER_TYPED_TEST_CASE_P() is not enclosed in a namespace. typedef int IntBeforeRegisterTypedTestCaseP; REGISTER_TYPED_TEST_CASE_P(TypedTestP1, A, B); template class TypedTestP2 : public Test { }; TYPED_TEST_CASE_P(TypedTestP2); // This also verifies that tests from different type-parameterized // test cases can share the same name. TYPED_TEST_P(TypedTestP2, A) {} REGISTER_TYPED_TEST_CASE_P(TypedTestP2, A); // Verifies that the code between TYPED_TEST_CASE_P() and // REGISTER_TYPED_TEST_CASE_P() is not enclosed in a namespace. IntAfterTypedTestCaseP after = 0; IntBeforeRegisterTypedTestCaseP before = 0; // Verifies that the last argument of INSTANTIATE_TYPED_TEST_CASE_P() // can be either a single type or a Types<...> type list. INSTANTIATE_TYPED_TEST_CASE_P(Int, TypedTestP1, int); INSTANTIATE_TYPED_TEST_CASE_P(Int, TypedTestP2, Types); // Tests that the same type-parameterized test case can be // instantiated more than once in the same translation unit. INSTANTIATE_TYPED_TEST_CASE_P(Double, TypedTestP2, Types); // Tests that the same type-parameterized test case can be // instantiated in different translation units linked together. // (ContainerTest is also instantiated in gtest-typed-test_test.cc.) typedef Types, std::set > MyContainers; INSTANTIATE_TYPED_TEST_CASE_P(My, ContainerTest, MyContainers); // Tests that a type-parameterized test case can be defined and // instantiated in a namespace. namespace library2 { template class NumericTest : public Test { }; TYPED_TEST_CASE_P(NumericTest); TYPED_TEST_P(NumericTest, DefaultIsZero) { EXPECT_EQ(0, TypeParam()); } TYPED_TEST_P(NumericTest, ZeroIsLessThanOne) { EXPECT_LT(TypeParam(0), TypeParam(1)); } REGISTER_TYPED_TEST_CASE_P(NumericTest, DefaultIsZero, ZeroIsLessThanOne); typedef Types NumericTypes; INSTANTIATE_TYPED_TEST_CASE_P(My, NumericTest, NumericTypes); } // namespace library2 #endif // GTEST_HAS_TYPED_TEST_P #if !defined(GTEST_HAS_TYPED_TEST) && !defined(GTEST_HAS_TYPED_TEST_P) // Google Test may not support type-parameterized tests with some // compilers. If we use conditional compilation to compile out all // code referring to the gtest_main library, MSVC linker will not link // that library at all and consequently complain about missing entry // point defined in that library (fatal error LNK1561: entry point // must be defined). This dummy test keeps gtest_main linked in. TEST(DummyTest, TypedTestsAreNotSupportedOnThisPlatform) {} #endif // #if !defined(GTEST_HAS_TYPED_TEST) && !defined(GTEST_HAS_TYPED_TEST_P) dlt-daemon-2.18.4/gtest-1.7.0/test/gtest-typed-test_test.h000066400000000000000000000046651353342203500230510ustar00rootroot00000000000000// Copyright 2008 Google Inc. // All Rights Reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: wan@google.com (Zhanyong Wan) #ifndef GTEST_TEST_GTEST_TYPED_TEST_TEST_H_ #define GTEST_TEST_GTEST_TYPED_TEST_TEST_H_ #include "gtest/gtest.h" #if GTEST_HAS_TYPED_TEST_P using testing::Test; // For testing that the same type-parameterized test case can be // instantiated in different translation units linked together. // ContainerTest will be instantiated in both gtest-typed-test_test.cc // and gtest-typed-test2_test.cc. template class ContainerTest : public Test { }; TYPED_TEST_CASE_P(ContainerTest); TYPED_TEST_P(ContainerTest, CanBeDefaultConstructed) { TypeParam container; } TYPED_TEST_P(ContainerTest, InitialSizeIsZero) { TypeParam container; EXPECT_EQ(0U, container.size()); } REGISTER_TYPED_TEST_CASE_P(ContainerTest, CanBeDefaultConstructed, InitialSizeIsZero); #endif // GTEST_HAS_TYPED_TEST_P #endif // GTEST_TEST_GTEST_TYPED_TEST_TEST_H_ dlt-daemon-2.18.4/gtest-1.7.0/test/gtest-unittest-api_test.cc000066400000000000000000000316271353342203500235310ustar00rootroot00000000000000// Copyright 2009 Google Inc. All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: vladl@google.com (Vlad Losev) // // The Google C++ Testing Framework (Google Test) // // This file contains tests verifying correctness of data provided via // UnitTest's public methods. #include "gtest/gtest.h" #include // For strcmp. #include using ::testing::InitGoogleTest; namespace testing { namespace internal { template struct LessByName { bool operator()(const T* a, const T* b) { return strcmp(a->name(), b->name()) < 0; } }; class UnitTestHelper { public: // Returns the array of pointers to all test cases sorted by the test case // name. The caller is responsible for deleting the array. static TestCase const** const GetSortedTestCases() { UnitTest& unit_test = *UnitTest::GetInstance(); TestCase const** const test_cases = new const TestCase*[unit_test.total_test_case_count()]; for (int i = 0; i < unit_test.total_test_case_count(); ++i) test_cases[i] = unit_test.GetTestCase(i); std::sort(test_cases, test_cases + unit_test.total_test_case_count(), LessByName()); return test_cases; } // Returns the test case by its name. The caller doesn't own the returned // pointer. static const TestCase* FindTestCase(const char* name) { UnitTest& unit_test = *UnitTest::GetInstance(); for (int i = 0; i < unit_test.total_test_case_count(); ++i) { const TestCase* test_case = unit_test.GetTestCase(i); if (0 == strcmp(test_case->name(), name)) return test_case; } return NULL; } // Returns the array of pointers to all tests in a particular test case // sorted by the test name. The caller is responsible for deleting the // array. static TestInfo const** const GetSortedTests(const TestCase* test_case) { TestInfo const** const tests = new const TestInfo*[test_case->total_test_count()]; for (int i = 0; i < test_case->total_test_count(); ++i) tests[i] = test_case->GetTestInfo(i); std::sort(tests, tests + test_case->total_test_count(), LessByName()); return tests; } }; #if GTEST_HAS_TYPED_TEST template class TestCaseWithCommentTest : public Test {}; TYPED_TEST_CASE(TestCaseWithCommentTest, Types); TYPED_TEST(TestCaseWithCommentTest, Dummy) {} const int kTypedTestCases = 1; const int kTypedTests = 1; #else const int kTypedTestCases = 0; const int kTypedTests = 0; #endif // GTEST_HAS_TYPED_TEST // We can only test the accessors that do not change value while tests run. // Since tests can be run in any order, the values the accessors that track // test execution (such as failed_test_count) can not be predicted. TEST(ApiTest, UnitTestImmutableAccessorsWork) { UnitTest* unit_test = UnitTest::GetInstance(); ASSERT_EQ(2 + kTypedTestCases, unit_test->total_test_case_count()); EXPECT_EQ(1 + kTypedTestCases, unit_test->test_case_to_run_count()); EXPECT_EQ(2, unit_test->disabled_test_count()); EXPECT_EQ(5 + kTypedTests, unit_test->total_test_count()); EXPECT_EQ(3 + kTypedTests, unit_test->test_to_run_count()); const TestCase** const test_cases = UnitTestHelper::GetSortedTestCases(); EXPECT_STREQ("ApiTest", test_cases[0]->name()); EXPECT_STREQ("DISABLED_Test", test_cases[1]->name()); #if GTEST_HAS_TYPED_TEST EXPECT_STREQ("TestCaseWithCommentTest/0", test_cases[2]->name()); #endif // GTEST_HAS_TYPED_TEST delete[] test_cases; // The following lines initiate actions to verify certain methods in // FinalSuccessChecker::TearDown. // Records a test property to verify TestResult::GetTestProperty(). RecordProperty("key", "value"); } AssertionResult IsNull(const char* str) { if (str != NULL) { return testing::AssertionFailure() << "argument is " << str; } return AssertionSuccess(); } TEST(ApiTest, TestCaseImmutableAccessorsWork) { const TestCase* test_case = UnitTestHelper::FindTestCase("ApiTest"); ASSERT_TRUE(test_case != NULL); EXPECT_STREQ("ApiTest", test_case->name()); EXPECT_TRUE(IsNull(test_case->type_param())); EXPECT_TRUE(test_case->should_run()); EXPECT_EQ(1, test_case->disabled_test_count()); EXPECT_EQ(3, test_case->test_to_run_count()); ASSERT_EQ(4, test_case->total_test_count()); const TestInfo** tests = UnitTestHelper::GetSortedTests(test_case); EXPECT_STREQ("DISABLED_Dummy1", tests[0]->name()); EXPECT_STREQ("ApiTest", tests[0]->test_case_name()); EXPECT_TRUE(IsNull(tests[0]->value_param())); EXPECT_TRUE(IsNull(tests[0]->type_param())); EXPECT_FALSE(tests[0]->should_run()); EXPECT_STREQ("TestCaseDisabledAccessorsWork", tests[1]->name()); EXPECT_STREQ("ApiTest", tests[1]->test_case_name()); EXPECT_TRUE(IsNull(tests[1]->value_param())); EXPECT_TRUE(IsNull(tests[1]->type_param())); EXPECT_TRUE(tests[1]->should_run()); EXPECT_STREQ("TestCaseImmutableAccessorsWork", tests[2]->name()); EXPECT_STREQ("ApiTest", tests[2]->test_case_name()); EXPECT_TRUE(IsNull(tests[2]->value_param())); EXPECT_TRUE(IsNull(tests[2]->type_param())); EXPECT_TRUE(tests[2]->should_run()); EXPECT_STREQ("UnitTestImmutableAccessorsWork", tests[3]->name()); EXPECT_STREQ("ApiTest", tests[3]->test_case_name()); EXPECT_TRUE(IsNull(tests[3]->value_param())); EXPECT_TRUE(IsNull(tests[3]->type_param())); EXPECT_TRUE(tests[3]->should_run()); delete[] tests; tests = NULL; #if GTEST_HAS_TYPED_TEST test_case = UnitTestHelper::FindTestCase("TestCaseWithCommentTest/0"); ASSERT_TRUE(test_case != NULL); EXPECT_STREQ("TestCaseWithCommentTest/0", test_case->name()); EXPECT_STREQ(GetTypeName().c_str(), test_case->type_param()); EXPECT_TRUE(test_case->should_run()); EXPECT_EQ(0, test_case->disabled_test_count()); EXPECT_EQ(1, test_case->test_to_run_count()); ASSERT_EQ(1, test_case->total_test_count()); tests = UnitTestHelper::GetSortedTests(test_case); EXPECT_STREQ("Dummy", tests[0]->name()); EXPECT_STREQ("TestCaseWithCommentTest/0", tests[0]->test_case_name()); EXPECT_TRUE(IsNull(tests[0]->value_param())); EXPECT_STREQ(GetTypeName().c_str(), tests[0]->type_param()); EXPECT_TRUE(tests[0]->should_run()); delete[] tests; #endif // GTEST_HAS_TYPED_TEST } TEST(ApiTest, TestCaseDisabledAccessorsWork) { const TestCase* test_case = UnitTestHelper::FindTestCase("DISABLED_Test"); ASSERT_TRUE(test_case != NULL); EXPECT_STREQ("DISABLED_Test", test_case->name()); EXPECT_TRUE(IsNull(test_case->type_param())); EXPECT_FALSE(test_case->should_run()); EXPECT_EQ(1, test_case->disabled_test_count()); EXPECT_EQ(0, test_case->test_to_run_count()); ASSERT_EQ(1, test_case->total_test_count()); const TestInfo* const test_info = test_case->GetTestInfo(0); EXPECT_STREQ("Dummy2", test_info->name()); EXPECT_STREQ("DISABLED_Test", test_info->test_case_name()); EXPECT_TRUE(IsNull(test_info->value_param())); EXPECT_TRUE(IsNull(test_info->type_param())); EXPECT_FALSE(test_info->should_run()); } // These two tests are here to provide support for testing // test_case_to_run_count, disabled_test_count, and test_to_run_count. TEST(ApiTest, DISABLED_Dummy1) {} TEST(DISABLED_Test, Dummy2) {} class FinalSuccessChecker : public Environment { protected: virtual void TearDown() { UnitTest* unit_test = UnitTest::GetInstance(); EXPECT_EQ(1 + kTypedTestCases, unit_test->successful_test_case_count()); EXPECT_EQ(3 + kTypedTests, unit_test->successful_test_count()); EXPECT_EQ(0, unit_test->failed_test_case_count()); EXPECT_EQ(0, unit_test->failed_test_count()); EXPECT_TRUE(unit_test->Passed()); EXPECT_FALSE(unit_test->Failed()); ASSERT_EQ(2 + kTypedTestCases, unit_test->total_test_case_count()); const TestCase** const test_cases = UnitTestHelper::GetSortedTestCases(); EXPECT_STREQ("ApiTest", test_cases[0]->name()); EXPECT_TRUE(IsNull(test_cases[0]->type_param())); EXPECT_TRUE(test_cases[0]->should_run()); EXPECT_EQ(1, test_cases[0]->disabled_test_count()); ASSERT_EQ(4, test_cases[0]->total_test_count()); EXPECT_EQ(3, test_cases[0]->successful_test_count()); EXPECT_EQ(0, test_cases[0]->failed_test_count()); EXPECT_TRUE(test_cases[0]->Passed()); EXPECT_FALSE(test_cases[0]->Failed()); EXPECT_STREQ("DISABLED_Test", test_cases[1]->name()); EXPECT_TRUE(IsNull(test_cases[1]->type_param())); EXPECT_FALSE(test_cases[1]->should_run()); EXPECT_EQ(1, test_cases[1]->disabled_test_count()); ASSERT_EQ(1, test_cases[1]->total_test_count()); EXPECT_EQ(0, test_cases[1]->successful_test_count()); EXPECT_EQ(0, test_cases[1]->failed_test_count()); #if GTEST_HAS_TYPED_TEST EXPECT_STREQ("TestCaseWithCommentTest/0", test_cases[2]->name()); EXPECT_STREQ(GetTypeName().c_str(), test_cases[2]->type_param()); EXPECT_TRUE(test_cases[2]->should_run()); EXPECT_EQ(0, test_cases[2]->disabled_test_count()); ASSERT_EQ(1, test_cases[2]->total_test_count()); EXPECT_EQ(1, test_cases[2]->successful_test_count()); EXPECT_EQ(0, test_cases[2]->failed_test_count()); EXPECT_TRUE(test_cases[2]->Passed()); EXPECT_FALSE(test_cases[2]->Failed()); #endif // GTEST_HAS_TYPED_TEST const TestCase* test_case = UnitTestHelper::FindTestCase("ApiTest"); const TestInfo** tests = UnitTestHelper::GetSortedTests(test_case); EXPECT_STREQ("DISABLED_Dummy1", tests[0]->name()); EXPECT_STREQ("ApiTest", tests[0]->test_case_name()); EXPECT_FALSE(tests[0]->should_run()); EXPECT_STREQ("TestCaseDisabledAccessorsWork", tests[1]->name()); EXPECT_STREQ("ApiTest", tests[1]->test_case_name()); EXPECT_TRUE(IsNull(tests[1]->value_param())); EXPECT_TRUE(IsNull(tests[1]->type_param())); EXPECT_TRUE(tests[1]->should_run()); EXPECT_TRUE(tests[1]->result()->Passed()); EXPECT_EQ(0, tests[1]->result()->test_property_count()); EXPECT_STREQ("TestCaseImmutableAccessorsWork", tests[2]->name()); EXPECT_STREQ("ApiTest", tests[2]->test_case_name()); EXPECT_TRUE(IsNull(tests[2]->value_param())); EXPECT_TRUE(IsNull(tests[2]->type_param())); EXPECT_TRUE(tests[2]->should_run()); EXPECT_TRUE(tests[2]->result()->Passed()); EXPECT_EQ(0, tests[2]->result()->test_property_count()); EXPECT_STREQ("UnitTestImmutableAccessorsWork", tests[3]->name()); EXPECT_STREQ("ApiTest", tests[3]->test_case_name()); EXPECT_TRUE(IsNull(tests[3]->value_param())); EXPECT_TRUE(IsNull(tests[3]->type_param())); EXPECT_TRUE(tests[3]->should_run()); EXPECT_TRUE(tests[3]->result()->Passed()); EXPECT_EQ(1, tests[3]->result()->test_property_count()); const TestProperty& property = tests[3]->result()->GetTestProperty(0); EXPECT_STREQ("key", property.key()); EXPECT_STREQ("value", property.value()); delete[] tests; #if GTEST_HAS_TYPED_TEST test_case = UnitTestHelper::FindTestCase("TestCaseWithCommentTest/0"); tests = UnitTestHelper::GetSortedTests(test_case); EXPECT_STREQ("Dummy", tests[0]->name()); EXPECT_STREQ("TestCaseWithCommentTest/0", tests[0]->test_case_name()); EXPECT_TRUE(IsNull(tests[0]->value_param())); EXPECT_STREQ(GetTypeName().c_str(), tests[0]->type_param()); EXPECT_TRUE(tests[0]->should_run()); EXPECT_TRUE(tests[0]->result()->Passed()); EXPECT_EQ(0, tests[0]->result()->test_property_count()); delete[] tests; #endif // GTEST_HAS_TYPED_TEST delete[] test_cases; } }; } // namespace internal } // namespace testing int main(int argc, char **argv) { InitGoogleTest(&argc, argv); AddGlobalTestEnvironment(new testing::internal::FinalSuccessChecker()); return RUN_ALL_TESTS(); } dlt-daemon-2.18.4/gtest-1.7.0/test/gtest_all_test.cc000066400000000000000000000043131353342203500217250ustar00rootroot00000000000000// Copyright 2009, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: wan@google.com (Zhanyong Wan) // // Tests for Google C++ Testing Framework (Google Test) // // Sometimes it's desirable to build most of Google Test's own tests // by compiling a single file. This file serves this purpose. #include "test/gtest-filepath_test.cc" #include "test/gtest-linked_ptr_test.cc" #include "test/gtest-message_test.cc" #include "test/gtest-options_test.cc" #include "test/gtest-port_test.cc" #include "test/gtest_pred_impl_unittest.cc" #include "test/gtest_prod_test.cc" #include "test/gtest-test-part_test.cc" #include "test/gtest-typed-test_test.cc" #include "test/gtest-typed-test2_test.cc" #include "test/gtest_unittest.cc" #include "test/production.cc" dlt-daemon-2.18.4/gtest-1.7.0/test/gtest_break_on_failure_unittest.py000077500000000000000000000162531353342203500254200ustar00rootroot00000000000000#!/usr/bin/env python # # Copyright 2006, Google Inc. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above # copyright notice, this list of conditions and the following disclaimer # in the documentation and/or other materials provided with the # distribution. # * Neither the name of Google Inc. nor the names of its # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. """Unit test for Google Test's break-on-failure mode. A user can ask Google Test to seg-fault when an assertion fails, using either the GTEST_BREAK_ON_FAILURE environment variable or the --gtest_break_on_failure flag. This script tests such functionality by invoking gtest_break_on_failure_unittest_ (a program written with Google Test) with different environments and command line flags. """ __author__ = 'wan@google.com (Zhanyong Wan)' import gtest_test_utils import os import sys # Constants. IS_WINDOWS = os.name == 'nt' # The environment variable for enabling/disabling the break-on-failure mode. BREAK_ON_FAILURE_ENV_VAR = 'GTEST_BREAK_ON_FAILURE' # The command line flag for enabling/disabling the break-on-failure mode. BREAK_ON_FAILURE_FLAG = 'gtest_break_on_failure' # The environment variable for enabling/disabling the throw-on-failure mode. THROW_ON_FAILURE_ENV_VAR = 'GTEST_THROW_ON_FAILURE' # The environment variable for enabling/disabling the catch-exceptions mode. CATCH_EXCEPTIONS_ENV_VAR = 'GTEST_CATCH_EXCEPTIONS' # Path to the gtest_break_on_failure_unittest_ program. EXE_PATH = gtest_test_utils.GetTestExecutablePath( 'gtest_break_on_failure_unittest_') environ = gtest_test_utils.environ SetEnvVar = gtest_test_utils.SetEnvVar # Tests in this file run a Google-Test-based test program and expect it # to terminate prematurely. Therefore they are incompatible with # the premature-exit-file protocol by design. Unset the # premature-exit filepath to prevent Google Test from creating # the file. SetEnvVar(gtest_test_utils.PREMATURE_EXIT_FILE_ENV_VAR, None) def Run(command): """Runs a command; returns 1 if it was killed by a signal, or 0 otherwise.""" p = gtest_test_utils.Subprocess(command, env=environ) if p.terminated_by_signal: return 1 else: return 0 # The tests. class GTestBreakOnFailureUnitTest(gtest_test_utils.TestCase): """Tests using the GTEST_BREAK_ON_FAILURE environment variable or the --gtest_break_on_failure flag to turn assertion failures into segmentation faults. """ def RunAndVerify(self, env_var_value, flag_value, expect_seg_fault): """Runs gtest_break_on_failure_unittest_ and verifies that it does (or does not) have a seg-fault. Args: env_var_value: value of the GTEST_BREAK_ON_FAILURE environment variable; None if the variable should be unset. flag_value: value of the --gtest_break_on_failure flag; None if the flag should not be present. expect_seg_fault: 1 if the program is expected to generate a seg-fault; 0 otherwise. """ SetEnvVar(BREAK_ON_FAILURE_ENV_VAR, env_var_value) if env_var_value is None: env_var_value_msg = ' is not set' else: env_var_value_msg = '=' + env_var_value if flag_value is None: flag = '' elif flag_value == '0': flag = '--%s=0' % BREAK_ON_FAILURE_FLAG else: flag = '--%s' % BREAK_ON_FAILURE_FLAG command = [EXE_PATH] if flag: command.append(flag) if expect_seg_fault: should_or_not = 'should' else: should_or_not = 'should not' has_seg_fault = Run(command) SetEnvVar(BREAK_ON_FAILURE_ENV_VAR, None) msg = ('when %s%s, an assertion failure in "%s" %s cause a seg-fault.' % (BREAK_ON_FAILURE_ENV_VAR, env_var_value_msg, ' '.join(command), should_or_not)) self.assert_(has_seg_fault == expect_seg_fault, msg) def testDefaultBehavior(self): """Tests the behavior of the default mode.""" self.RunAndVerify(env_var_value=None, flag_value=None, expect_seg_fault=0) def testEnvVar(self): """Tests using the GTEST_BREAK_ON_FAILURE environment variable.""" self.RunAndVerify(env_var_value='0', flag_value=None, expect_seg_fault=0) self.RunAndVerify(env_var_value='1', flag_value=None, expect_seg_fault=1) def testFlag(self): """Tests using the --gtest_break_on_failure flag.""" self.RunAndVerify(env_var_value=None, flag_value='0', expect_seg_fault=0) self.RunAndVerify(env_var_value=None, flag_value='1', expect_seg_fault=1) def testFlagOverridesEnvVar(self): """Tests that the flag overrides the environment variable.""" self.RunAndVerify(env_var_value='0', flag_value='0', expect_seg_fault=0) self.RunAndVerify(env_var_value='0', flag_value='1', expect_seg_fault=1) self.RunAndVerify(env_var_value='1', flag_value='0', expect_seg_fault=0) self.RunAndVerify(env_var_value='1', flag_value='1', expect_seg_fault=1) def testBreakOnFailureOverridesThrowOnFailure(self): """Tests that gtest_break_on_failure overrides gtest_throw_on_failure.""" SetEnvVar(THROW_ON_FAILURE_ENV_VAR, '1') try: self.RunAndVerify(env_var_value=None, flag_value='1', expect_seg_fault=1) finally: SetEnvVar(THROW_ON_FAILURE_ENV_VAR, None) if IS_WINDOWS: def testCatchExceptionsDoesNotInterfere(self): """Tests that gtest_catch_exceptions doesn't interfere.""" SetEnvVar(CATCH_EXCEPTIONS_ENV_VAR, '1') try: self.RunAndVerify(env_var_value='1', flag_value='1', expect_seg_fault=1) finally: SetEnvVar(CATCH_EXCEPTIONS_ENV_VAR, None) if __name__ == '__main__': gtest_test_utils.Main() dlt-daemon-2.18.4/gtest-1.7.0/test/gtest_break_on_failure_unittest_.cc000066400000000000000000000062771353342203500255160ustar00rootroot00000000000000// Copyright 2006, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: wan@google.com (Zhanyong Wan) // Unit test for Google Test's break-on-failure mode. // // A user can ask Google Test to seg-fault when an assertion fails, using // either the GTEST_BREAK_ON_FAILURE environment variable or the // --gtest_break_on_failure flag. This file is used for testing such // functionality. // // This program will be invoked from a Python unit test. It is // expected to fail. Don't run it directly. #include "gtest/gtest.h" #if GTEST_OS_WINDOWS # include # include #endif namespace { // A test that's expected to fail. TEST(Foo, Bar) { EXPECT_EQ(2, 3); } #if GTEST_HAS_SEH && !GTEST_OS_WINDOWS_MOBILE // On Windows Mobile global exception handlers are not supported. LONG WINAPI ExitWithExceptionCode( struct _EXCEPTION_POINTERS* exception_pointers) { exit(exception_pointers->ExceptionRecord->ExceptionCode); } #endif } // namespace int main(int argc, char **argv) { #if GTEST_OS_WINDOWS // Suppresses display of the Windows error dialog upon encountering // a general protection fault (segment violation). SetErrorMode(SEM_NOGPFAULTERRORBOX | SEM_FAILCRITICALERRORS); # if GTEST_HAS_SEH && !GTEST_OS_WINDOWS_MOBILE // The default unhandled exception filter does not always exit // with the exception code as exit code - for example it exits with // 0 for EXCEPTION_ACCESS_VIOLATION and 1 for EXCEPTION_BREAKPOINT // if the application is compiled in debug mode. Thus we use our own // filter which always exits with the exception code for unhandled // exceptions. SetUnhandledExceptionFilter(ExitWithExceptionCode); # endif #endif testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } dlt-daemon-2.18.4/gtest-1.7.0/test/gtest_catch_exceptions_test.py000077500000000000000000000232551353342203500245540ustar00rootroot00000000000000#!/usr/bin/env python # # Copyright 2010 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. """Tests Google Test's exception catching behavior. This script invokes gtest_catch_exceptions_test_ and gtest_catch_exceptions_ex_test_ (programs written with Google Test) and verifies their output. """ __author__ = 'vladl@google.com (Vlad Losev)' import os import gtest_test_utils # Constants. FLAG_PREFIX = '--gtest_' LIST_TESTS_FLAG = FLAG_PREFIX + 'list_tests' NO_CATCH_EXCEPTIONS_FLAG = FLAG_PREFIX + 'catch_exceptions=0' FILTER_FLAG = FLAG_PREFIX + 'filter' # Path to the gtest_catch_exceptions_ex_test_ binary, compiled with # exceptions enabled. EX_EXE_PATH = gtest_test_utils.GetTestExecutablePath( 'gtest_catch_exceptions_ex_test_') # Path to the gtest_catch_exceptions_test_ binary, compiled with # exceptions disabled. EXE_PATH = gtest_test_utils.GetTestExecutablePath( 'gtest_catch_exceptions_no_ex_test_') environ = gtest_test_utils.environ SetEnvVar = gtest_test_utils.SetEnvVar # Tests in this file run a Google-Test-based test program and expect it # to terminate prematurely. Therefore they are incompatible with # the premature-exit-file protocol by design. Unset the # premature-exit filepath to prevent Google Test from creating # the file. SetEnvVar(gtest_test_utils.PREMATURE_EXIT_FILE_ENV_VAR, None) TEST_LIST = gtest_test_utils.Subprocess( [EXE_PATH, LIST_TESTS_FLAG], env=environ).output SUPPORTS_SEH_EXCEPTIONS = 'ThrowsSehException' in TEST_LIST if SUPPORTS_SEH_EXCEPTIONS: BINARY_OUTPUT = gtest_test_utils.Subprocess([EXE_PATH], env=environ).output EX_BINARY_OUTPUT = gtest_test_utils.Subprocess( [EX_EXE_PATH], env=environ).output # The tests. if SUPPORTS_SEH_EXCEPTIONS: # pylint:disable-msg=C6302 class CatchSehExceptionsTest(gtest_test_utils.TestCase): """Tests exception-catching behavior.""" def TestSehExceptions(self, test_output): self.assert_('SEH exception with code 0x2a thrown ' 'in the test fixture\'s constructor' in test_output) self.assert_('SEH exception with code 0x2a thrown ' 'in the test fixture\'s destructor' in test_output) self.assert_('SEH exception with code 0x2a thrown in SetUpTestCase()' in test_output) self.assert_('SEH exception with code 0x2a thrown in TearDownTestCase()' in test_output) self.assert_('SEH exception with code 0x2a thrown in SetUp()' in test_output) self.assert_('SEH exception with code 0x2a thrown in TearDown()' in test_output) self.assert_('SEH exception with code 0x2a thrown in the test body' in test_output) def testCatchesSehExceptionsWithCxxExceptionsEnabled(self): self.TestSehExceptions(EX_BINARY_OUTPUT) def testCatchesSehExceptionsWithCxxExceptionsDisabled(self): self.TestSehExceptions(BINARY_OUTPUT) class CatchCxxExceptionsTest(gtest_test_utils.TestCase): """Tests C++ exception-catching behavior. Tests in this test case verify that: * C++ exceptions are caught and logged as C++ (not SEH) exceptions * Exception thrown affect the remainder of the test work flow in the expected manner. """ def testCatchesCxxExceptionsInFixtureConstructor(self): self.assert_('C++ exception with description ' '"Standard C++ exception" thrown ' 'in the test fixture\'s constructor' in EX_BINARY_OUTPUT) self.assert_('unexpected' not in EX_BINARY_OUTPUT, 'This failure belongs in this test only if ' '"CxxExceptionInConstructorTest" (no quotes) ' 'appears on the same line as words "called unexpectedly"') if ('CxxExceptionInDestructorTest.ThrowsExceptionInDestructor' in EX_BINARY_OUTPUT): def testCatchesCxxExceptionsInFixtureDestructor(self): self.assert_('C++ exception with description ' '"Standard C++ exception" thrown ' 'in the test fixture\'s destructor' in EX_BINARY_OUTPUT) self.assert_('CxxExceptionInDestructorTest::TearDownTestCase() ' 'called as expected.' in EX_BINARY_OUTPUT) def testCatchesCxxExceptionsInSetUpTestCase(self): self.assert_('C++ exception with description "Standard C++ exception"' ' thrown in SetUpTestCase()' in EX_BINARY_OUTPUT) self.assert_('CxxExceptionInConstructorTest::TearDownTestCase() ' 'called as expected.' in EX_BINARY_OUTPUT) self.assert_('CxxExceptionInSetUpTestCaseTest constructor ' 'called as expected.' in EX_BINARY_OUTPUT) self.assert_('CxxExceptionInSetUpTestCaseTest destructor ' 'called as expected.' in EX_BINARY_OUTPUT) self.assert_('CxxExceptionInSetUpTestCaseTest::SetUp() ' 'called as expected.' in EX_BINARY_OUTPUT) self.assert_('CxxExceptionInSetUpTestCaseTest::TearDown() ' 'called as expected.' in EX_BINARY_OUTPUT) self.assert_('CxxExceptionInSetUpTestCaseTest test body ' 'called as expected.' in EX_BINARY_OUTPUT) def testCatchesCxxExceptionsInTearDownTestCase(self): self.assert_('C++ exception with description "Standard C++ exception"' ' thrown in TearDownTestCase()' in EX_BINARY_OUTPUT) def testCatchesCxxExceptionsInSetUp(self): self.assert_('C++ exception with description "Standard C++ exception"' ' thrown in SetUp()' in EX_BINARY_OUTPUT) self.assert_('CxxExceptionInSetUpTest::TearDownTestCase() ' 'called as expected.' in EX_BINARY_OUTPUT) self.assert_('CxxExceptionInSetUpTest destructor ' 'called as expected.' in EX_BINARY_OUTPUT) self.assert_('CxxExceptionInSetUpTest::TearDown() ' 'called as expected.' in EX_BINARY_OUTPUT) self.assert_('unexpected' not in EX_BINARY_OUTPUT, 'This failure belongs in this test only if ' '"CxxExceptionInSetUpTest" (no quotes) ' 'appears on the same line as words "called unexpectedly"') def testCatchesCxxExceptionsInTearDown(self): self.assert_('C++ exception with description "Standard C++ exception"' ' thrown in TearDown()' in EX_BINARY_OUTPUT) self.assert_('CxxExceptionInTearDownTest::TearDownTestCase() ' 'called as expected.' in EX_BINARY_OUTPUT) self.assert_('CxxExceptionInTearDownTest destructor ' 'called as expected.' in EX_BINARY_OUTPUT) def testCatchesCxxExceptionsInTestBody(self): self.assert_('C++ exception with description "Standard C++ exception"' ' thrown in the test body' in EX_BINARY_OUTPUT) self.assert_('CxxExceptionInTestBodyTest::TearDownTestCase() ' 'called as expected.' in EX_BINARY_OUTPUT) self.assert_('CxxExceptionInTestBodyTest destructor ' 'called as expected.' in EX_BINARY_OUTPUT) self.assert_('CxxExceptionInTestBodyTest::TearDown() ' 'called as expected.' in EX_BINARY_OUTPUT) def testCatchesNonStdCxxExceptions(self): self.assert_('Unknown C++ exception thrown in the test body' in EX_BINARY_OUTPUT) def testUnhandledCxxExceptionsAbortTheProgram(self): # Filters out SEH exception tests on Windows. Unhandled SEH exceptions # cause tests to show pop-up windows there. FITLER_OUT_SEH_TESTS_FLAG = FILTER_FLAG + '=-*Seh*' # By default, Google Test doesn't catch the exceptions. uncaught_exceptions_ex_binary_output = gtest_test_utils.Subprocess( [EX_EXE_PATH, NO_CATCH_EXCEPTIONS_FLAG, FITLER_OUT_SEH_TESTS_FLAG], env=environ).output self.assert_('Unhandled C++ exception terminating the program' in uncaught_exceptions_ex_binary_output) self.assert_('unexpected' not in uncaught_exceptions_ex_binary_output) if __name__ == '__main__': gtest_test_utils.Main() dlt-daemon-2.18.4/gtest-1.7.0/test/gtest_catch_exceptions_test_.cc000066400000000000000000000213271353342203500246430ustar00rootroot00000000000000// Copyright 2010, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: vladl@google.com (Vlad Losev) // // Tests for Google Test itself. Tests in this file throw C++ or SEH // exceptions, and the output is verified by gtest_catch_exceptions_test.py. #include "gtest/gtest.h" #include // NOLINT #include // For exit(). #if GTEST_HAS_SEH # include #endif #if GTEST_HAS_EXCEPTIONS # include // For set_terminate(). # include #endif using testing::Test; #if GTEST_HAS_SEH class SehExceptionInConstructorTest : public Test { public: SehExceptionInConstructorTest() { RaiseException(42, 0, 0, NULL); } }; TEST_F(SehExceptionInConstructorTest, ThrowsExceptionInConstructor) {} class SehExceptionInDestructorTest : public Test { public: ~SehExceptionInDestructorTest() { RaiseException(42, 0, 0, NULL); } }; TEST_F(SehExceptionInDestructorTest, ThrowsExceptionInDestructor) {} class SehExceptionInSetUpTestCaseTest : public Test { public: static void SetUpTestCase() { RaiseException(42, 0, 0, NULL); } }; TEST_F(SehExceptionInSetUpTestCaseTest, ThrowsExceptionInSetUpTestCase) {} class SehExceptionInTearDownTestCaseTest : public Test { public: static void TearDownTestCase() { RaiseException(42, 0, 0, NULL); } }; TEST_F(SehExceptionInTearDownTestCaseTest, ThrowsExceptionInTearDownTestCase) {} class SehExceptionInSetUpTest : public Test { protected: virtual void SetUp() { RaiseException(42, 0, 0, NULL); } }; TEST_F(SehExceptionInSetUpTest, ThrowsExceptionInSetUp) {} class SehExceptionInTearDownTest : public Test { protected: virtual void TearDown() { RaiseException(42, 0, 0, NULL); } }; TEST_F(SehExceptionInTearDownTest, ThrowsExceptionInTearDown) {} TEST(SehExceptionTest, ThrowsSehException) { RaiseException(42, 0, 0, NULL); } #endif // GTEST_HAS_SEH #if GTEST_HAS_EXCEPTIONS class CxxExceptionInConstructorTest : public Test { public: CxxExceptionInConstructorTest() { // Without this macro VC++ complains about unreachable code at the end of // the constructor. GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_( throw std::runtime_error("Standard C++ exception")); } static void TearDownTestCase() { printf("%s", "CxxExceptionInConstructorTest::TearDownTestCase() " "called as expected.\n"); } protected: ~CxxExceptionInConstructorTest() { ADD_FAILURE() << "CxxExceptionInConstructorTest destructor " << "called unexpectedly."; } virtual void SetUp() { ADD_FAILURE() << "CxxExceptionInConstructorTest::SetUp() " << "called unexpectedly."; } virtual void TearDown() { ADD_FAILURE() << "CxxExceptionInConstructorTest::TearDown() " << "called unexpectedly."; } }; TEST_F(CxxExceptionInConstructorTest, ThrowsExceptionInConstructor) { ADD_FAILURE() << "CxxExceptionInConstructorTest test body " << "called unexpectedly."; } // Exceptions in destructors are not supported in C++11. #if !defined(__GXX_EXPERIMENTAL_CXX0X__) && __cplusplus < 201103L class CxxExceptionInDestructorTest : public Test { public: static void TearDownTestCase() { printf("%s", "CxxExceptionInDestructorTest::TearDownTestCase() " "called as expected.\n"); } protected: ~CxxExceptionInDestructorTest() { GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_( throw std::runtime_error("Standard C++ exception")); } }; TEST_F(CxxExceptionInDestructorTest, ThrowsExceptionInDestructor) {} #endif // C++11 mode class CxxExceptionInSetUpTestCaseTest : public Test { public: CxxExceptionInSetUpTestCaseTest() { printf("%s", "CxxExceptionInSetUpTestCaseTest constructor " "called as expected.\n"); } static void SetUpTestCase() { throw std::runtime_error("Standard C++ exception"); } static void TearDownTestCase() { printf("%s", "CxxExceptionInSetUpTestCaseTest::TearDownTestCase() " "called as expected.\n"); } protected: ~CxxExceptionInSetUpTestCaseTest() { printf("%s", "CxxExceptionInSetUpTestCaseTest destructor " "called as expected.\n"); } virtual void SetUp() { printf("%s", "CxxExceptionInSetUpTestCaseTest::SetUp() " "called as expected.\n"); } virtual void TearDown() { printf("%s", "CxxExceptionInSetUpTestCaseTest::TearDown() " "called as expected.\n"); } }; TEST_F(CxxExceptionInSetUpTestCaseTest, ThrowsExceptionInSetUpTestCase) { printf("%s", "CxxExceptionInSetUpTestCaseTest test body " "called as expected.\n"); } class CxxExceptionInTearDownTestCaseTest : public Test { public: static void TearDownTestCase() { throw std::runtime_error("Standard C++ exception"); } }; TEST_F(CxxExceptionInTearDownTestCaseTest, ThrowsExceptionInTearDownTestCase) {} class CxxExceptionInSetUpTest : public Test { public: static void TearDownTestCase() { printf("%s", "CxxExceptionInSetUpTest::TearDownTestCase() " "called as expected.\n"); } protected: ~CxxExceptionInSetUpTest() { printf("%s", "CxxExceptionInSetUpTest destructor " "called as expected.\n"); } virtual void SetUp() { throw std::runtime_error("Standard C++ exception"); } virtual void TearDown() { printf("%s", "CxxExceptionInSetUpTest::TearDown() " "called as expected.\n"); } }; TEST_F(CxxExceptionInSetUpTest, ThrowsExceptionInSetUp) { ADD_FAILURE() << "CxxExceptionInSetUpTest test body " << "called unexpectedly."; } class CxxExceptionInTearDownTest : public Test { public: static void TearDownTestCase() { printf("%s", "CxxExceptionInTearDownTest::TearDownTestCase() " "called as expected.\n"); } protected: ~CxxExceptionInTearDownTest() { printf("%s", "CxxExceptionInTearDownTest destructor " "called as expected.\n"); } virtual void TearDown() { throw std::runtime_error("Standard C++ exception"); } }; TEST_F(CxxExceptionInTearDownTest, ThrowsExceptionInTearDown) {} class CxxExceptionInTestBodyTest : public Test { public: static void TearDownTestCase() { printf("%s", "CxxExceptionInTestBodyTest::TearDownTestCase() " "called as expected.\n"); } protected: ~CxxExceptionInTestBodyTest() { printf("%s", "CxxExceptionInTestBodyTest destructor " "called as expected.\n"); } virtual void TearDown() { printf("%s", "CxxExceptionInTestBodyTest::TearDown() " "called as expected.\n"); } }; TEST_F(CxxExceptionInTestBodyTest, ThrowsStdCxxException) { throw std::runtime_error("Standard C++ exception"); } TEST(CxxExceptionTest, ThrowsNonStdCxxException) { throw "C-string"; } // This terminate handler aborts the program using exit() rather than abort(). // This avoids showing pop-ups on Windows systems and core dumps on Unix-like // ones. void TerminateHandler() { fprintf(stderr, "%s\n", "Unhandled C++ exception terminating the program."); fflush(NULL); exit(3); } #endif // GTEST_HAS_EXCEPTIONS int main(int argc, char** argv) { #if GTEST_HAS_EXCEPTIONS std::set_terminate(&TerminateHandler); #endif testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } dlt-daemon-2.18.4/gtest-1.7.0/test/gtest_color_test.py000077500000000000000000000114571353342203500223500ustar00rootroot00000000000000#!/usr/bin/env python # # 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. """Verifies that Google Test correctly determines whether to use colors.""" __author__ = 'wan@google.com (Zhanyong Wan)' import os import gtest_test_utils IS_WINDOWS = os.name = 'nt' COLOR_ENV_VAR = 'GTEST_COLOR' COLOR_FLAG = 'gtest_color' COMMAND = gtest_test_utils.GetTestExecutablePath('gtest_color_test_') def SetEnvVar(env_var, value): """Sets the env variable to 'value'; unsets it when 'value' is None.""" if value is not None: os.environ[env_var] = value elif env_var in os.environ: del os.environ[env_var] def UsesColor(term, color_env_var, color_flag): """Runs gtest_color_test_ and returns its exit code.""" SetEnvVar('TERM', term) SetEnvVar(COLOR_ENV_VAR, color_env_var) if color_flag is None: args = [] else: args = ['--%s=%s' % (COLOR_FLAG, color_flag)] p = gtest_test_utils.Subprocess([COMMAND] + args) return not p.exited or p.exit_code class GTestColorTest(gtest_test_utils.TestCase): def testNoEnvVarNoFlag(self): """Tests the case when there's neither GTEST_COLOR nor --gtest_color.""" if not IS_WINDOWS: self.assert_(not UsesColor('dumb', None, None)) self.assert_(not UsesColor('emacs', None, None)) self.assert_(not UsesColor('xterm-mono', None, None)) self.assert_(not UsesColor('unknown', None, None)) self.assert_(not UsesColor(None, None, None)) self.assert_(UsesColor('linux', None, None)) self.assert_(UsesColor('cygwin', None, None)) self.assert_(UsesColor('xterm', None, None)) self.assert_(UsesColor('xterm-color', None, None)) self.assert_(UsesColor('xterm-256color', None, None)) def testFlagOnly(self): """Tests the case when there's --gtest_color but not GTEST_COLOR.""" self.assert_(not UsesColor('dumb', None, 'no')) self.assert_(not UsesColor('xterm-color', None, 'no')) if not IS_WINDOWS: self.assert_(not UsesColor('emacs', None, 'auto')) self.assert_(UsesColor('xterm', None, 'auto')) self.assert_(UsesColor('dumb', None, 'yes')) self.assert_(UsesColor('xterm', None, 'yes')) def testEnvVarOnly(self): """Tests the case when there's GTEST_COLOR but not --gtest_color.""" self.assert_(not UsesColor('dumb', 'no', None)) self.assert_(not UsesColor('xterm-color', 'no', None)) if not IS_WINDOWS: self.assert_(not UsesColor('dumb', 'auto', None)) self.assert_(UsesColor('xterm-color', 'auto', None)) self.assert_(UsesColor('dumb', 'yes', None)) self.assert_(UsesColor('xterm-color', 'yes', None)) def testEnvVarAndFlag(self): """Tests the case when there are both GTEST_COLOR and --gtest_color.""" self.assert_(not UsesColor('xterm-color', 'no', 'no')) self.assert_(UsesColor('dumb', 'no', 'yes')) self.assert_(UsesColor('xterm-color', 'no', 'auto')) def testAliasesOfYesAndNo(self): """Tests using aliases in specifying --gtest_color.""" self.assert_(UsesColor('dumb', None, 'true')) self.assert_(UsesColor('dumb', None, 'YES')) self.assert_(UsesColor('dumb', None, 'T')) self.assert_(UsesColor('dumb', None, '1')) self.assert_(not UsesColor('xterm', None, 'f')) self.assert_(not UsesColor('xterm', None, 'false')) self.assert_(not UsesColor('xterm', None, '0')) self.assert_(not UsesColor('xterm', None, 'unknown')) if __name__ == '__main__': gtest_test_utils.Main() dlt-daemon-2.18.4/gtest-1.7.0/test/gtest_color_test_.cc000066400000000000000000000055101353342203500224320ustar00rootroot00000000000000// Copyright 2008, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: wan@google.com (Zhanyong Wan) // A helper program for testing how Google Test determines whether to use // colors in the output. It prints "YES" and returns 1 if Google Test // decides to use colors, and prints "NO" and returns 0 otherwise. #include #include "gtest/gtest.h" // Indicates that this translation unit is part of Google Test's // implementation. It must come before gtest-internal-inl.h is // included, or there will be a compiler error. This trick is to // prevent a user from accidentally including gtest-internal-inl.h in // his code. #define GTEST_IMPLEMENTATION_ 1 #include "src/gtest-internal-inl.h" #undef GTEST_IMPLEMENTATION_ using testing::internal::ShouldUseColor; // The purpose of this is to ensure that the UnitTest singleton is // created before main() is entered, and thus that ShouldUseColor() // works the same way as in a real Google-Test-based test. We don't actual // run the TEST itself. TEST(GTestColorTest, Dummy) { } int main(int argc, char** argv) { testing::InitGoogleTest(&argc, argv); if (ShouldUseColor(true)) { // Google Test decides to use colors in the output (assuming it // goes to a TTY). printf("YES\n"); return 1; } else { // Google Test decides not to use colors in the output. printf("NO\n"); return 0; } } dlt-daemon-2.18.4/gtest-1.7.0/test/gtest_env_var_test.py000077500000000000000000000066371353342203500226760ustar00rootroot00000000000000#!/usr/bin/env python # # 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. """Verifies that Google Test correctly parses environment variables.""" __author__ = 'wan@google.com (Zhanyong Wan)' import os import gtest_test_utils IS_WINDOWS = os.name == 'nt' IS_LINUX = os.name == 'posix' and os.uname()[0] == 'Linux' COMMAND = gtest_test_utils.GetTestExecutablePath('gtest_env_var_test_') environ = os.environ.copy() def AssertEq(expected, actual): if expected != actual: print 'Expected: %s' % (expected,) print ' Actual: %s' % (actual,) raise AssertionError def SetEnvVar(env_var, value): """Sets the env variable to 'value'; unsets it when 'value' is None.""" if value is not None: environ[env_var] = value elif env_var in environ: del environ[env_var] def GetFlag(flag): """Runs gtest_env_var_test_ and returns its output.""" args = [COMMAND] if flag is not None: args += [flag] return gtest_test_utils.Subprocess(args, env=environ).output def TestFlag(flag, test_val, default_val): """Verifies that the given flag is affected by the corresponding env var.""" env_var = 'GTEST_' + flag.upper() SetEnvVar(env_var, test_val) AssertEq(test_val, GetFlag(flag)) SetEnvVar(env_var, None) AssertEq(default_val, GetFlag(flag)) class GTestEnvVarTest(gtest_test_utils.TestCase): def testEnvVarAffectsFlag(self): """Tests that environment variable should affect the corresponding flag.""" TestFlag('break_on_failure', '1', '0') TestFlag('color', 'yes', 'auto') TestFlag('filter', 'FooTest.Bar', '*') TestFlag('output', 'xml:tmp/foo.xml', '') TestFlag('print_time', '0', '1') TestFlag('repeat', '999', '1') TestFlag('throw_on_failure', '1', '0') TestFlag('death_test_style', 'threadsafe', 'fast') TestFlag('catch_exceptions', '0', '1') if IS_LINUX: TestFlag('death_test_use_fork', '1', '0') TestFlag('stack_trace_depth', '0', '100') if __name__ == '__main__': gtest_test_utils.Main() dlt-daemon-2.18.4/gtest-1.7.0/test/gtest_env_var_test_.cc000066400000000000000000000067701353342203500227650ustar00rootroot00000000000000// Copyright 2008, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: wan@google.com (Zhanyong Wan) // A helper program for testing that Google Test parses the environment // variables correctly. #include "gtest/gtest.h" #include #define GTEST_IMPLEMENTATION_ 1 #include "src/gtest-internal-inl.h" #undef GTEST_IMPLEMENTATION_ using ::std::cout; namespace testing { // The purpose of this is to make the test more realistic by ensuring // that the UnitTest singleton is created before main() is entered. // We don't actual run the TEST itself. TEST(GTestEnvVarTest, Dummy) { } void PrintFlag(const char* flag) { if (strcmp(flag, "break_on_failure") == 0) { cout << GTEST_FLAG(break_on_failure); return; } if (strcmp(flag, "catch_exceptions") == 0) { cout << GTEST_FLAG(catch_exceptions); return; } if (strcmp(flag, "color") == 0) { cout << GTEST_FLAG(color); return; } if (strcmp(flag, "death_test_style") == 0) { cout << GTEST_FLAG(death_test_style); return; } if (strcmp(flag, "death_test_use_fork") == 0) { cout << GTEST_FLAG(death_test_use_fork); return; } if (strcmp(flag, "filter") == 0) { cout << GTEST_FLAG(filter); return; } if (strcmp(flag, "output") == 0) { cout << GTEST_FLAG(output); return; } if (strcmp(flag, "print_time") == 0) { cout << GTEST_FLAG(print_time); return; } if (strcmp(flag, "repeat") == 0) { cout << GTEST_FLAG(repeat); return; } if (strcmp(flag, "stack_trace_depth") == 0) { cout << GTEST_FLAG(stack_trace_depth); return; } if (strcmp(flag, "throw_on_failure") == 0) { cout << GTEST_FLAG(throw_on_failure); return; } cout << "Invalid flag name " << flag << ". Valid names are break_on_failure, color, filter, etc.\n"; exit(1); } } // namespace testing int main(int argc, char** argv) { testing::InitGoogleTest(&argc, argv); if (argc != 2) { cout << "Usage: gtest_env_var_test_ NAME_OF_FLAG\n"; return 1; } testing::PrintFlag(argv[1]); return 0; } dlt-daemon-2.18.4/gtest-1.7.0/test/gtest_environment_test.cc000066400000000000000000000147161353342203500235310ustar00rootroot00000000000000// Copyright 2007, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: wan@google.com (Zhanyong Wan) // // Tests using global test environments. #include #include #include "gtest/gtest.h" #define GTEST_IMPLEMENTATION_ 1 // Required for the next #include. #include "src/gtest-internal-inl.h" #undef GTEST_IMPLEMENTATION_ namespace testing { GTEST_DECLARE_string_(filter); } namespace { enum FailureType { NO_FAILURE, NON_FATAL_FAILURE, FATAL_FAILURE }; // For testing using global test environments. class MyEnvironment : public testing::Environment { public: MyEnvironment() { Reset(); } // Depending on the value of failure_in_set_up_, SetUp() will // generate a non-fatal failure, generate a fatal failure, or // succeed. virtual void SetUp() { set_up_was_run_ = true; switch (failure_in_set_up_) { case NON_FATAL_FAILURE: ADD_FAILURE() << "Expected non-fatal failure in global set-up."; break; case FATAL_FAILURE: FAIL() << "Expected fatal failure in global set-up."; break; default: break; } } // Generates a non-fatal failure. virtual void TearDown() { tear_down_was_run_ = true; ADD_FAILURE() << "Expected non-fatal failure in global tear-down."; } // Resets the state of the environment s.t. it can be reused. void Reset() { failure_in_set_up_ = NO_FAILURE; set_up_was_run_ = false; tear_down_was_run_ = false; } // We call this function to set the type of failure SetUp() should // generate. void set_failure_in_set_up(FailureType type) { failure_in_set_up_ = type; } // Was SetUp() run? bool set_up_was_run() const { return set_up_was_run_; } // Was TearDown() run? bool tear_down_was_run() const { return tear_down_was_run_; } private: FailureType failure_in_set_up_; bool set_up_was_run_; bool tear_down_was_run_; }; // Was the TEST run? bool test_was_run; // The sole purpose of this TEST is to enable us to check whether it // was run. TEST(FooTest, Bar) { test_was_run = true; } // Prints the message and aborts the program if condition is false. void Check(bool condition, const char* msg) { if (!condition) { printf("FAILED: %s\n", msg); testing::internal::posix::Abort(); } } // Runs the tests. Return true iff successful. // // The 'failure' parameter specifies the type of failure that should // be generated by the global set-up. int RunAllTests(MyEnvironment* env, FailureType failure) { env->Reset(); env->set_failure_in_set_up(failure); test_was_run = false; testing::internal::GetUnitTestImpl()->ClearAdHocTestResult(); return RUN_ALL_TESTS(); } } // namespace int main(int argc, char **argv) { testing::InitGoogleTest(&argc, argv); // Registers a global test environment, and verifies that the // registration function returns its argument. MyEnvironment* const env = new MyEnvironment; Check(testing::AddGlobalTestEnvironment(env) == env, "AddGlobalTestEnvironment() should return its argument."); // Verifies that RUN_ALL_TESTS() runs the tests when the global // set-up is successful. Check(RunAllTests(env, NO_FAILURE) != 0, "RUN_ALL_TESTS() should return non-zero, as the global tear-down " "should generate a failure."); Check(test_was_run, "The tests should run, as the global set-up should generate no " "failure"); Check(env->tear_down_was_run(), "The global tear-down should run, as the global set-up was run."); // Verifies that RUN_ALL_TESTS() runs the tests when the global // set-up generates no fatal failure. Check(RunAllTests(env, NON_FATAL_FAILURE) != 0, "RUN_ALL_TESTS() should return non-zero, as both the global set-up " "and the global tear-down should generate a non-fatal failure."); Check(test_was_run, "The tests should run, as the global set-up should generate no " "fatal failure."); Check(env->tear_down_was_run(), "The global tear-down should run, as the global set-up was run."); // Verifies that RUN_ALL_TESTS() runs no test when the global set-up // generates a fatal failure. Check(RunAllTests(env, FATAL_FAILURE) != 0, "RUN_ALL_TESTS() should return non-zero, as the global set-up " "should generate a fatal failure."); Check(!test_was_run, "The tests should not run, as the global set-up should generate " "a fatal failure."); Check(env->tear_down_was_run(), "The global tear-down should run, as the global set-up was run."); // Verifies that RUN_ALL_TESTS() doesn't do global set-up or // tear-down when there is no test to run. testing::GTEST_FLAG(filter) = "-*"; Check(RunAllTests(env, NO_FAILURE) == 0, "RUN_ALL_TESTS() should return zero, as there is no test to run."); Check(!env->set_up_was_run(), "The global set-up should not run, as there is no test to run."); Check(!env->tear_down_was_run(), "The global tear-down should not run, " "as the global set-up was not run."); printf("PASS\n"); return 0; } dlt-daemon-2.18.4/gtest-1.7.0/test/gtest_filter_unittest.py000077500000000000000000000514151353342203500234150ustar00rootroot00000000000000#!/usr/bin/env python # # Copyright 2005 Google Inc. All Rights Reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above # copyright notice, this list of conditions and the following disclaimer # in the documentation and/or other materials provided with the # distribution. # * Neither the name of Google Inc. nor the names of its # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. """Unit test for Google Test test filters. A user can specify which test(s) in a Google Test program to run via either the GTEST_FILTER environment variable or the --gtest_filter flag. This script tests such functionality by invoking gtest_filter_unittest_ (a program written with Google Test) with different environments and command line flags. Note that test sharding may also influence which tests are filtered. Therefore, we test that here also. """ __author__ = 'wan@google.com (Zhanyong Wan)' import os import re import sets import sys import gtest_test_utils # Constants. # Checks if this platform can pass empty environment variables to child # processes. We set an env variable to an empty string and invoke a python # script in a subprocess to print whether the variable is STILL in # os.environ. We then use 'eval' to parse the child's output so that an # exception is thrown if the input is anything other than 'True' nor 'False'. os.environ['EMPTY_VAR'] = '' child = gtest_test_utils.Subprocess( [sys.executable, '-c', 'import os; print \'EMPTY_VAR\' in os.environ']) CAN_PASS_EMPTY_ENV = eval(child.output) # Check if this platform can unset environment variables in child processes. # We set an env variable to a non-empty string, unset it, and invoke # a python script in a subprocess to print whether the variable # is NO LONGER in os.environ. # We use 'eval' to parse the child's output so that an exception # is thrown if the input is neither 'True' nor 'False'. os.environ['UNSET_VAR'] = 'X' del os.environ['UNSET_VAR'] child = gtest_test_utils.Subprocess( [sys.executable, '-c', 'import os; print \'UNSET_VAR\' not in os.environ']) CAN_UNSET_ENV = eval(child.output) # Checks if we should test with an empty filter. This doesn't # make sense on platforms that cannot pass empty env variables (Win32) # and on platforms that cannot unset variables (since we cannot tell # the difference between "" and NULL -- Borland and Solaris < 5.10) CAN_TEST_EMPTY_FILTER = (CAN_PASS_EMPTY_ENV and CAN_UNSET_ENV) # The environment variable for specifying the test filters. FILTER_ENV_VAR = 'GTEST_FILTER' # The environment variables for test sharding. TOTAL_SHARDS_ENV_VAR = 'GTEST_TOTAL_SHARDS' SHARD_INDEX_ENV_VAR = 'GTEST_SHARD_INDEX' SHARD_STATUS_FILE_ENV_VAR = 'GTEST_SHARD_STATUS_FILE' # The command line flag for specifying the test filters. FILTER_FLAG = 'gtest_filter' # The command line flag for including disabled tests. ALSO_RUN_DISABED_TESTS_FLAG = 'gtest_also_run_disabled_tests' # Command to run the gtest_filter_unittest_ program. COMMAND = gtest_test_utils.GetTestExecutablePath('gtest_filter_unittest_') # Regex for determining whether parameterized tests are enabled in the binary. PARAM_TEST_REGEX = re.compile(r'/ParamTest') # Regex for parsing test case names from Google Test's output. TEST_CASE_REGEX = re.compile(r'^\[\-+\] \d+ tests? from (\w+(/\w+)?)') # Regex for parsing test names from Google Test's output. TEST_REGEX = re.compile(r'^\[\s*RUN\s*\].*\.(\w+(/\w+)?)') # The command line flag to tell Google Test to output the list of tests it # will run. LIST_TESTS_FLAG = '--gtest_list_tests' # Indicates whether Google Test supports death tests. SUPPORTS_DEATH_TESTS = 'HasDeathTest' in gtest_test_utils.Subprocess( [COMMAND, LIST_TESTS_FLAG]).output # Full names of all tests in gtest_filter_unittests_. PARAM_TESTS = [ 'SeqP/ParamTest.TestX/0', 'SeqP/ParamTest.TestX/1', 'SeqP/ParamTest.TestY/0', 'SeqP/ParamTest.TestY/1', 'SeqQ/ParamTest.TestX/0', 'SeqQ/ParamTest.TestX/1', 'SeqQ/ParamTest.TestY/0', 'SeqQ/ParamTest.TestY/1', ] DISABLED_TESTS = [ 'BarTest.DISABLED_TestFour', 'BarTest.DISABLED_TestFive', 'BazTest.DISABLED_TestC', 'DISABLED_FoobarTest.Test1', 'DISABLED_FoobarTest.DISABLED_Test2', 'DISABLED_FoobarbazTest.TestA', ] if SUPPORTS_DEATH_TESTS: DEATH_TESTS = [ 'HasDeathTest.Test1', 'HasDeathTest.Test2', ] else: DEATH_TESTS = [] # All the non-disabled tests. ACTIVE_TESTS = [ 'FooTest.Abc', 'FooTest.Xyz', 'BarTest.TestOne', 'BarTest.TestTwo', 'BarTest.TestThree', 'BazTest.TestOne', 'BazTest.TestA', 'BazTest.TestB', ] + DEATH_TESTS + PARAM_TESTS param_tests_present = None # Utilities. environ = os.environ.copy() def SetEnvVar(env_var, value): """Sets the env variable to 'value'; unsets it when 'value' is None.""" if value is not None: environ[env_var] = value elif env_var in environ: del environ[env_var] def RunAndReturnOutput(args = None): """Runs the test program and returns its output.""" return gtest_test_utils.Subprocess([COMMAND] + (args or []), env=environ).output def RunAndExtractTestList(args = None): """Runs the test program and returns its exit code and a list of tests run.""" p = gtest_test_utils.Subprocess([COMMAND] + (args or []), env=environ) tests_run = [] test_case = '' test = '' for line in p.output.split('\n'): match = TEST_CASE_REGEX.match(line) if match is not None: test_case = match.group(1) else: match = TEST_REGEX.match(line) if match is not None: test = match.group(1) tests_run.append(test_case + '.' + test) return (tests_run, p.exit_code) def InvokeWithModifiedEnv(extra_env, function, *args, **kwargs): """Runs the given function and arguments in a modified environment.""" try: original_env = environ.copy() environ.update(extra_env) return function(*args, **kwargs) finally: environ.clear() environ.update(original_env) def RunWithSharding(total_shards, shard_index, command): """Runs a test program shard and returns exit code and a list of tests run.""" extra_env = {SHARD_INDEX_ENV_VAR: str(shard_index), TOTAL_SHARDS_ENV_VAR: str(total_shards)} return InvokeWithModifiedEnv(extra_env, RunAndExtractTestList, command) # The unit test. class GTestFilterUnitTest(gtest_test_utils.TestCase): """Tests the env variable or the command line flag to filter tests.""" # Utilities. def AssertSetEqual(self, lhs, rhs): """Asserts that two sets are equal.""" for elem in lhs: self.assert_(elem in rhs, '%s in %s' % (elem, rhs)) for elem in rhs: self.assert_(elem in lhs, '%s in %s' % (elem, lhs)) def AssertPartitionIsValid(self, set_var, list_of_sets): """Asserts that list_of_sets is a valid partition of set_var.""" full_partition = [] for slice_var in list_of_sets: full_partition.extend(slice_var) self.assertEqual(len(set_var), len(full_partition)) self.assertEqual(sets.Set(set_var), sets.Set(full_partition)) def AdjustForParameterizedTests(self, tests_to_run): """Adjust tests_to_run in case value parameterized tests are disabled.""" global param_tests_present if not param_tests_present: return list(sets.Set(tests_to_run) - sets.Set(PARAM_TESTS)) else: return tests_to_run def RunAndVerify(self, gtest_filter, tests_to_run): """Checks that the binary runs correct set of tests for a given filter.""" tests_to_run = self.AdjustForParameterizedTests(tests_to_run) # First, tests using the environment variable. # Windows removes empty variables from the environment when passing it # to a new process. This means it is impossible to pass an empty filter # into a process using the environment variable. However, we can still # test the case when the variable is not supplied (i.e., gtest_filter is # None). # pylint: disable-msg=C6403 if CAN_TEST_EMPTY_FILTER or gtest_filter != '': SetEnvVar(FILTER_ENV_VAR, gtest_filter) tests_run = RunAndExtractTestList()[0] SetEnvVar(FILTER_ENV_VAR, None) self.AssertSetEqual(tests_run, tests_to_run) # pylint: enable-msg=C6403 # Next, tests using the command line flag. if gtest_filter is None: args = [] else: args = ['--%s=%s' % (FILTER_FLAG, gtest_filter)] tests_run = RunAndExtractTestList(args)[0] self.AssertSetEqual(tests_run, tests_to_run) def RunAndVerifyWithSharding(self, gtest_filter, total_shards, tests_to_run, args=None, check_exit_0=False): """Checks that binary runs correct tests for the given filter and shard. Runs all shards of gtest_filter_unittest_ with the given filter, and verifies that the right set of tests were run. The union of tests run on each shard should be identical to tests_to_run, without duplicates. Args: gtest_filter: A filter to apply to the tests. total_shards: A total number of shards to split test run into. tests_to_run: A set of tests expected to run. args : Arguments to pass to the to the test binary. check_exit_0: When set to a true value, make sure that all shards return 0. """ tests_to_run = self.AdjustForParameterizedTests(tests_to_run) # Windows removes empty variables from the environment when passing it # to a new process. This means it is impossible to pass an empty filter # into a process using the environment variable. However, we can still # test the case when the variable is not supplied (i.e., gtest_filter is # None). # pylint: disable-msg=C6403 if CAN_TEST_EMPTY_FILTER or gtest_filter != '': SetEnvVar(FILTER_ENV_VAR, gtest_filter) partition = [] for i in range(0, total_shards): (tests_run, exit_code) = RunWithSharding(total_shards, i, args) if check_exit_0: self.assertEqual(0, exit_code) partition.append(tests_run) self.AssertPartitionIsValid(tests_to_run, partition) SetEnvVar(FILTER_ENV_VAR, None) # pylint: enable-msg=C6403 def RunAndVerifyAllowingDisabled(self, gtest_filter, tests_to_run): """Checks that the binary runs correct set of tests for the given filter. Runs gtest_filter_unittest_ with the given filter, and enables disabled tests. Verifies that the right set of tests were run. Args: gtest_filter: A filter to apply to the tests. tests_to_run: A set of tests expected to run. """ tests_to_run = self.AdjustForParameterizedTests(tests_to_run) # Construct the command line. args = ['--%s' % ALSO_RUN_DISABED_TESTS_FLAG] if gtest_filter is not None: args.append('--%s=%s' % (FILTER_FLAG, gtest_filter)) tests_run = RunAndExtractTestList(args)[0] self.AssertSetEqual(tests_run, tests_to_run) def setUp(self): """Sets up test case. Determines whether value-parameterized tests are enabled in the binary and sets the flags accordingly. """ global param_tests_present if param_tests_present is None: param_tests_present = PARAM_TEST_REGEX.search( RunAndReturnOutput()) is not None def testDefaultBehavior(self): """Tests the behavior of not specifying the filter.""" self.RunAndVerify(None, ACTIVE_TESTS) def testDefaultBehaviorWithShards(self): """Tests the behavior without the filter, with sharding enabled.""" self.RunAndVerifyWithSharding(None, 1, ACTIVE_TESTS) self.RunAndVerifyWithSharding(None, 2, ACTIVE_TESTS) self.RunAndVerifyWithSharding(None, len(ACTIVE_TESTS) - 1, ACTIVE_TESTS) self.RunAndVerifyWithSharding(None, len(ACTIVE_TESTS), ACTIVE_TESTS) self.RunAndVerifyWithSharding(None, len(ACTIVE_TESTS) + 1, ACTIVE_TESTS) def testEmptyFilter(self): """Tests an empty filter.""" self.RunAndVerify('', []) self.RunAndVerifyWithSharding('', 1, []) self.RunAndVerifyWithSharding('', 2, []) def testBadFilter(self): """Tests a filter that matches nothing.""" self.RunAndVerify('BadFilter', []) self.RunAndVerifyAllowingDisabled('BadFilter', []) def testFullName(self): """Tests filtering by full name.""" self.RunAndVerify('FooTest.Xyz', ['FooTest.Xyz']) self.RunAndVerifyAllowingDisabled('FooTest.Xyz', ['FooTest.Xyz']) self.RunAndVerifyWithSharding('FooTest.Xyz', 5, ['FooTest.Xyz']) def testUniversalFilters(self): """Tests filters that match everything.""" self.RunAndVerify('*', ACTIVE_TESTS) self.RunAndVerify('*.*', ACTIVE_TESTS) self.RunAndVerifyWithSharding('*.*', len(ACTIVE_TESTS) - 3, ACTIVE_TESTS) self.RunAndVerifyAllowingDisabled('*', ACTIVE_TESTS + DISABLED_TESTS) self.RunAndVerifyAllowingDisabled('*.*', ACTIVE_TESTS + DISABLED_TESTS) def testFilterByTestCase(self): """Tests filtering by test case name.""" self.RunAndVerify('FooTest.*', ['FooTest.Abc', 'FooTest.Xyz']) BAZ_TESTS = ['BazTest.TestOne', 'BazTest.TestA', 'BazTest.TestB'] self.RunAndVerify('BazTest.*', BAZ_TESTS) self.RunAndVerifyAllowingDisabled('BazTest.*', BAZ_TESTS + ['BazTest.DISABLED_TestC']) def testFilterByTest(self): """Tests filtering by test name.""" self.RunAndVerify('*.TestOne', ['BarTest.TestOne', 'BazTest.TestOne']) def testFilterDisabledTests(self): """Select only the disabled tests to run.""" self.RunAndVerify('DISABLED_FoobarTest.Test1', []) self.RunAndVerifyAllowingDisabled('DISABLED_FoobarTest.Test1', ['DISABLED_FoobarTest.Test1']) self.RunAndVerify('*DISABLED_*', []) self.RunAndVerifyAllowingDisabled('*DISABLED_*', DISABLED_TESTS) self.RunAndVerify('*.DISABLED_*', []) self.RunAndVerifyAllowingDisabled('*.DISABLED_*', [ 'BarTest.DISABLED_TestFour', 'BarTest.DISABLED_TestFive', 'BazTest.DISABLED_TestC', 'DISABLED_FoobarTest.DISABLED_Test2', ]) self.RunAndVerify('DISABLED_*', []) self.RunAndVerifyAllowingDisabled('DISABLED_*', [ 'DISABLED_FoobarTest.Test1', 'DISABLED_FoobarTest.DISABLED_Test2', 'DISABLED_FoobarbazTest.TestA', ]) def testWildcardInTestCaseName(self): """Tests using wildcard in the test case name.""" self.RunAndVerify('*a*.*', [ 'BarTest.TestOne', 'BarTest.TestTwo', 'BarTest.TestThree', 'BazTest.TestOne', 'BazTest.TestA', 'BazTest.TestB', ] + DEATH_TESTS + PARAM_TESTS) def testWildcardInTestName(self): """Tests using wildcard in the test name.""" self.RunAndVerify('*.*A*', ['FooTest.Abc', 'BazTest.TestA']) def testFilterWithoutDot(self): """Tests a filter that has no '.' in it.""" self.RunAndVerify('*z*', [ 'FooTest.Xyz', 'BazTest.TestOne', 'BazTest.TestA', 'BazTest.TestB', ]) def testTwoPatterns(self): """Tests filters that consist of two patterns.""" self.RunAndVerify('Foo*.*:*A*', [ 'FooTest.Abc', 'FooTest.Xyz', 'BazTest.TestA', ]) # An empty pattern + a non-empty one self.RunAndVerify(':*A*', ['FooTest.Abc', 'BazTest.TestA']) def testThreePatterns(self): """Tests filters that consist of three patterns.""" self.RunAndVerify('*oo*:*A*:*One', [ 'FooTest.Abc', 'FooTest.Xyz', 'BarTest.TestOne', 'BazTest.TestOne', 'BazTest.TestA', ]) # The 2nd pattern is empty. self.RunAndVerify('*oo*::*One', [ 'FooTest.Abc', 'FooTest.Xyz', 'BarTest.TestOne', 'BazTest.TestOne', ]) # The last 2 patterns are empty. self.RunAndVerify('*oo*::', [ 'FooTest.Abc', 'FooTest.Xyz', ]) def testNegativeFilters(self): self.RunAndVerify('*-BazTest.TestOne', [ 'FooTest.Abc', 'FooTest.Xyz', 'BarTest.TestOne', 'BarTest.TestTwo', 'BarTest.TestThree', 'BazTest.TestA', 'BazTest.TestB', ] + DEATH_TESTS + PARAM_TESTS) self.RunAndVerify('*-FooTest.Abc:BazTest.*', [ 'FooTest.Xyz', 'BarTest.TestOne', 'BarTest.TestTwo', 'BarTest.TestThree', ] + DEATH_TESTS + PARAM_TESTS) self.RunAndVerify('BarTest.*-BarTest.TestOne', [ 'BarTest.TestTwo', 'BarTest.TestThree', ]) # Tests without leading '*'. self.RunAndVerify('-FooTest.Abc:FooTest.Xyz:BazTest.*', [ 'BarTest.TestOne', 'BarTest.TestTwo', 'BarTest.TestThree', ] + DEATH_TESTS + PARAM_TESTS) # Value parameterized tests. self.RunAndVerify('*/*', PARAM_TESTS) # Value parameterized tests filtering by the sequence name. self.RunAndVerify('SeqP/*', [ 'SeqP/ParamTest.TestX/0', 'SeqP/ParamTest.TestX/1', 'SeqP/ParamTest.TestY/0', 'SeqP/ParamTest.TestY/1', ]) # Value parameterized tests filtering by the test name. self.RunAndVerify('*/0', [ 'SeqP/ParamTest.TestX/0', 'SeqP/ParamTest.TestY/0', 'SeqQ/ParamTest.TestX/0', 'SeqQ/ParamTest.TestY/0', ]) def testFlagOverridesEnvVar(self): """Tests that the filter flag overrides the filtering env. variable.""" SetEnvVar(FILTER_ENV_VAR, 'Foo*') args = ['--%s=%s' % (FILTER_FLAG, '*One')] tests_run = RunAndExtractTestList(args)[0] SetEnvVar(FILTER_ENV_VAR, None) self.AssertSetEqual(tests_run, ['BarTest.TestOne', 'BazTest.TestOne']) def testShardStatusFileIsCreated(self): """Tests that the shard file is created if specified in the environment.""" shard_status_file = os.path.join(gtest_test_utils.GetTempDir(), 'shard_status_file') self.assert_(not os.path.exists(shard_status_file)) extra_env = {SHARD_STATUS_FILE_ENV_VAR: shard_status_file} try: InvokeWithModifiedEnv(extra_env, RunAndReturnOutput) finally: self.assert_(os.path.exists(shard_status_file)) os.remove(shard_status_file) def testShardStatusFileIsCreatedWithListTests(self): """Tests that the shard file is created with the "list_tests" flag.""" shard_status_file = os.path.join(gtest_test_utils.GetTempDir(), 'shard_status_file2') self.assert_(not os.path.exists(shard_status_file)) extra_env = {SHARD_STATUS_FILE_ENV_VAR: shard_status_file} try: output = InvokeWithModifiedEnv(extra_env, RunAndReturnOutput, [LIST_TESTS_FLAG]) finally: # This assertion ensures that Google Test enumerated the tests as # opposed to running them. self.assert_('[==========]' not in output, 'Unexpected output during test enumeration.\n' 'Please ensure that LIST_TESTS_FLAG is assigned the\n' 'correct flag value for listing Google Test tests.') self.assert_(os.path.exists(shard_status_file)) os.remove(shard_status_file) if SUPPORTS_DEATH_TESTS: def testShardingWorksWithDeathTests(self): """Tests integration with death tests and sharding.""" gtest_filter = 'HasDeathTest.*:SeqP/*' expected_tests = [ 'HasDeathTest.Test1', 'HasDeathTest.Test2', 'SeqP/ParamTest.TestX/0', 'SeqP/ParamTest.TestX/1', 'SeqP/ParamTest.TestY/0', 'SeqP/ParamTest.TestY/1', ] for flag in ['--gtest_death_test_style=threadsafe', '--gtest_death_test_style=fast']: self.RunAndVerifyWithSharding(gtest_filter, 3, expected_tests, check_exit_0=True, args=[flag]) self.RunAndVerifyWithSharding(gtest_filter, 5, expected_tests, check_exit_0=True, args=[flag]) if __name__ == '__main__': gtest_test_utils.Main() dlt-daemon-2.18.4/gtest-1.7.0/test/gtest_filter_unittest_.cc000066400000000000000000000067541353342203500235140ustar00rootroot00000000000000// Copyright 2005, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: wan@google.com (Zhanyong Wan) // Unit test for Google Test test filters. // // A user can specify which test(s) in a Google Test program to run via // either the GTEST_FILTER environment variable or the --gtest_filter // flag. This is used for testing such functionality. // // The program will be invoked from a Python unit test. Don't run it // directly. #include "gtest/gtest.h" namespace { // Test case FooTest. class FooTest : public testing::Test { }; TEST_F(FooTest, Abc) { } TEST_F(FooTest, Xyz) { FAIL() << "Expected failure."; } // Test case BarTest. TEST(BarTest, TestOne) { } TEST(BarTest, TestTwo) { } TEST(BarTest, TestThree) { } TEST(BarTest, DISABLED_TestFour) { FAIL() << "Expected failure."; } TEST(BarTest, DISABLED_TestFive) { FAIL() << "Expected failure."; } // Test case BazTest. TEST(BazTest, TestOne) { FAIL() << "Expected failure."; } TEST(BazTest, TestA) { } TEST(BazTest, TestB) { } TEST(BazTest, DISABLED_TestC) { FAIL() << "Expected failure."; } // Test case HasDeathTest TEST(HasDeathTest, Test1) { EXPECT_DEATH_IF_SUPPORTED(exit(1), ".*"); } // We need at least two death tests to make sure that the all death tests // aren't on the first shard. TEST(HasDeathTest, Test2) { EXPECT_DEATH_IF_SUPPORTED(exit(1), ".*"); } // Test case FoobarTest TEST(DISABLED_FoobarTest, Test1) { FAIL() << "Expected failure."; } TEST(DISABLED_FoobarTest, DISABLED_Test2) { FAIL() << "Expected failure."; } // Test case FoobarbazTest TEST(DISABLED_FoobarbazTest, TestA) { FAIL() << "Expected failure."; } #if GTEST_HAS_PARAM_TEST class ParamTest : public testing::TestWithParam { }; TEST_P(ParamTest, TestX) { } TEST_P(ParamTest, TestY) { } INSTANTIATE_TEST_CASE_P(SeqP, ParamTest, testing::Values(1, 2)); INSTANTIATE_TEST_CASE_P(SeqQ, ParamTest, testing::Values(5, 6)); #endif // GTEST_HAS_PARAM_TEST } // namespace int main(int argc, char **argv) { ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } dlt-daemon-2.18.4/gtest-1.7.0/test/gtest_help_test.py000077500000000000000000000133401353342203500221530ustar00rootroot00000000000000#!/usr/bin/env python # # Copyright 2009, Google Inc. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above # copyright notice, this list of conditions and the following disclaimer # in the documentation and/or other materials provided with the # distribution. # * Neither the name of Google Inc. nor the names of its # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. """Tests the --help flag of Google C++ Testing Framework. SYNOPSIS gtest_help_test.py --build_dir=BUILD/DIR # where BUILD/DIR contains the built gtest_help_test_ file. gtest_help_test.py """ __author__ = 'wan@google.com (Zhanyong Wan)' import os import re import gtest_test_utils IS_LINUX = os.name == 'posix' and os.uname()[0] == 'Linux' IS_WINDOWS = os.name == 'nt' PROGRAM_PATH = gtest_test_utils.GetTestExecutablePath('gtest_help_test_') FLAG_PREFIX = '--gtest_' DEATH_TEST_STYLE_FLAG = FLAG_PREFIX + 'death_test_style' STREAM_RESULT_TO_FLAG = FLAG_PREFIX + 'stream_result_to' UNKNOWN_FLAG = FLAG_PREFIX + 'unknown_flag_for_testing' LIST_TESTS_FLAG = FLAG_PREFIX + 'list_tests' INCORRECT_FLAG_VARIANTS = [re.sub('^--', '-', LIST_TESTS_FLAG), re.sub('^--', '/', LIST_TESTS_FLAG), re.sub('_', '-', LIST_TESTS_FLAG)] INTERNAL_FLAG_FOR_TESTING = FLAG_PREFIX + 'internal_flag_for_testing' SUPPORTS_DEATH_TESTS = "DeathTest" in gtest_test_utils.Subprocess( [PROGRAM_PATH, LIST_TESTS_FLAG]).output # The help message must match this regex. HELP_REGEX = re.compile( FLAG_PREFIX + r'list_tests.*' + FLAG_PREFIX + r'filter=.*' + FLAG_PREFIX + r'also_run_disabled_tests.*' + FLAG_PREFIX + r'repeat=.*' + FLAG_PREFIX + r'shuffle.*' + FLAG_PREFIX + r'random_seed=.*' + FLAG_PREFIX + r'color=.*' + FLAG_PREFIX + r'print_time.*' + FLAG_PREFIX + r'output=.*' + FLAG_PREFIX + r'break_on_failure.*' + FLAG_PREFIX + r'throw_on_failure.*' + FLAG_PREFIX + r'catch_exceptions=0.*', re.DOTALL) def RunWithFlag(flag): """Runs gtest_help_test_ with the given flag. Returns: the exit code and the text output as a tuple. Args: flag: the command-line flag to pass to gtest_help_test_, or None. """ if flag is None: command = [PROGRAM_PATH] else: command = [PROGRAM_PATH, flag] child = gtest_test_utils.Subprocess(command) return child.exit_code, child.output class GTestHelpTest(gtest_test_utils.TestCase): """Tests the --help flag and its equivalent forms.""" def TestHelpFlag(self, flag): """Verifies correct behavior when help flag is specified. The right message must be printed and the tests must skipped when the given flag is specified. Args: flag: A flag to pass to the binary or None. """ exit_code, output = RunWithFlag(flag) self.assertEquals(0, exit_code) self.assert_(HELP_REGEX.search(output), output) if IS_LINUX: self.assert_(STREAM_RESULT_TO_FLAG in output, output) else: self.assert_(STREAM_RESULT_TO_FLAG not in output, output) if SUPPORTS_DEATH_TESTS and not IS_WINDOWS: self.assert_(DEATH_TEST_STYLE_FLAG in output, output) else: self.assert_(DEATH_TEST_STYLE_FLAG not in output, output) def TestNonHelpFlag(self, flag): """Verifies correct behavior when no help flag is specified. Verifies that when no help flag is specified, the tests are run and the help message is not printed. Args: flag: A flag to pass to the binary or None. """ exit_code, output = RunWithFlag(flag) self.assert_(exit_code != 0) self.assert_(not HELP_REGEX.search(output), output) def testPrintsHelpWithFullFlag(self): self.TestHelpFlag('--help') def testPrintsHelpWithShortFlag(self): self.TestHelpFlag('-h') def testPrintsHelpWithQuestionFlag(self): self.TestHelpFlag('-?') def testPrintsHelpWithWindowsStyleQuestionFlag(self): self.TestHelpFlag('/?') def testPrintsHelpWithUnrecognizedGoogleTestFlag(self): self.TestHelpFlag(UNKNOWN_FLAG) def testPrintsHelpWithIncorrectFlagStyle(self): for incorrect_flag in INCORRECT_FLAG_VARIANTS: self.TestHelpFlag(incorrect_flag) def testRunsTestsWithoutHelpFlag(self): """Verifies that when no help flag is specified, the tests are run and the help message is not printed.""" self.TestNonHelpFlag(None) def testRunsTestsWithGtestInternalFlag(self): """Verifies that the tests are run and no help message is printed when a flag starting with Google Test prefix and 'internal_' is supplied.""" self.TestNonHelpFlag(INTERNAL_FLAG_FOR_TESTING) if __name__ == '__main__': gtest_test_utils.Main() dlt-daemon-2.18.4/gtest-1.7.0/test/gtest_help_test_.cc000066400000000000000000000041231353342203500222430ustar00rootroot00000000000000// Copyright 2009, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: wan@google.com (Zhanyong Wan) // This program is meant to be run by gtest_help_test.py. Do not run // it directly. #include "gtest/gtest.h" // When a help flag is specified, this program should skip the tests // and exit with 0; otherwise the following test will be executed, // causing this program to exit with a non-zero code. TEST(HelpFlagTest, ShouldNotBeRun) { ASSERT_TRUE(false) << "Tests shouldn't be run when --help is specified."; } #if GTEST_HAS_DEATH_TEST TEST(DeathTest, UsedByPythonScriptToDetectSupportForDeathTestsInThisBinary) {} #endif dlt-daemon-2.18.4/gtest-1.7.0/test/gtest_list_tests_unittest.py000077500000000000000000000145631353342203500243300ustar00rootroot00000000000000#!/usr/bin/env python # # Copyright 2006, Google Inc. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above # copyright notice, this list of conditions and the following disclaimer # in the documentation and/or other materials provided with the # distribution. # * Neither the name of Google Inc. nor the names of its # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. """Unit test for Google Test's --gtest_list_tests flag. A user can ask Google Test to list all tests by specifying the --gtest_list_tests flag. This script tests such functionality by invoking gtest_list_tests_unittest_ (a program written with Google Test) the command line flags. """ __author__ = 'phanna@google.com (Patrick Hanna)' import gtest_test_utils import re # Constants. # The command line flag for enabling/disabling listing all tests. LIST_TESTS_FLAG = 'gtest_list_tests' # Path to the gtest_list_tests_unittest_ program. EXE_PATH = gtest_test_utils.GetTestExecutablePath('gtest_list_tests_unittest_') # The expected output when running gtest_list_tests_unittest_ with # --gtest_list_tests EXPECTED_OUTPUT_NO_FILTER_RE = re.compile(r"""FooDeathTest\. Test1 Foo\. Bar1 Bar2 DISABLED_Bar3 Abc\. Xyz Def FooBar\. Baz FooTest\. Test1 DISABLED_Test2 Test3 TypedTest/0\. # TypeParam = (VeryLo{245}|class VeryLo{239})\.\.\. TestA TestB TypedTest/1\. # TypeParam = int\s*\* TestA TestB TypedTest/2\. # TypeParam = .*MyArray TestA TestB My/TypeParamTest/0\. # TypeParam = (VeryLo{245}|class VeryLo{239})\.\.\. TestA TestB My/TypeParamTest/1\. # TypeParam = int\s*\* TestA TestB My/TypeParamTest/2\. # TypeParam = .*MyArray TestA TestB MyInstantiation/ValueParamTest\. TestA/0 # GetParam\(\) = one line TestA/1 # GetParam\(\) = two\\nlines TestA/2 # GetParam\(\) = a very\\nlo{241}\.\.\. TestB/0 # GetParam\(\) = one line TestB/1 # GetParam\(\) = two\\nlines TestB/2 # GetParam\(\) = a very\\nlo{241}\.\.\. """) # The expected output when running gtest_list_tests_unittest_ with # --gtest_list_tests and --gtest_filter=Foo*. EXPECTED_OUTPUT_FILTER_FOO_RE = re.compile(r"""FooDeathTest\. Test1 Foo\. Bar1 Bar2 DISABLED_Bar3 FooBar\. Baz FooTest\. Test1 DISABLED_Test2 Test3 """) # Utilities. def Run(args): """Runs gtest_list_tests_unittest_ and returns the list of tests printed.""" return gtest_test_utils.Subprocess([EXE_PATH] + args, capture_stderr=False).output # The unit test. class GTestListTestsUnitTest(gtest_test_utils.TestCase): """Tests using the --gtest_list_tests flag to list all tests.""" def RunAndVerify(self, flag_value, expected_output_re, other_flag): """Runs gtest_list_tests_unittest_ and verifies that it prints the correct tests. Args: flag_value: value of the --gtest_list_tests flag; None if the flag should not be present. expected_output_re: regular expression that matches the expected output after running command; other_flag: a different flag to be passed to command along with gtest_list_tests; None if the flag should not be present. """ if flag_value is None: flag = '' flag_expression = 'not set' elif flag_value == '0': flag = '--%s=0' % LIST_TESTS_FLAG flag_expression = '0' else: flag = '--%s' % LIST_TESTS_FLAG flag_expression = '1' args = [flag] if other_flag is not None: args += [other_flag] output = Run(args) if expected_output_re: self.assert_( expected_output_re.match(output), ('when %s is %s, the output of "%s" is "%s",\n' 'which does not match regex "%s"' % (LIST_TESTS_FLAG, flag_expression, ' '.join(args), output, expected_output_re.pattern))) else: self.assert_( not EXPECTED_OUTPUT_NO_FILTER_RE.match(output), ('when %s is %s, the output of "%s" is "%s"'% (LIST_TESTS_FLAG, flag_expression, ' '.join(args), output))) def testDefaultBehavior(self): """Tests the behavior of the default mode.""" self.RunAndVerify(flag_value=None, expected_output_re=None, other_flag=None) def testFlag(self): """Tests using the --gtest_list_tests flag.""" self.RunAndVerify(flag_value='0', expected_output_re=None, other_flag=None) self.RunAndVerify(flag_value='1', expected_output_re=EXPECTED_OUTPUT_NO_FILTER_RE, other_flag=None) def testOverrideNonFilterFlags(self): """Tests that --gtest_list_tests overrides the non-filter flags.""" self.RunAndVerify(flag_value='1', expected_output_re=EXPECTED_OUTPUT_NO_FILTER_RE, other_flag='--gtest_break_on_failure') def testWithFilterFlags(self): """Tests that --gtest_list_tests takes into account the --gtest_filter flag.""" self.RunAndVerify(flag_value='1', expected_output_re=EXPECTED_OUTPUT_FILTER_FOO_RE, other_flag='--gtest_filter=Foo*') if __name__ == '__main__': gtest_test_utils.Main() dlt-daemon-2.18.4/gtest-1.7.0/test/gtest_list_tests_unittest_.cc000066400000000000000000000111461353342203500244130ustar00rootroot00000000000000// Copyright 2006, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: phanna@google.com (Patrick Hanna) // Unit test for Google Test's --gtest_list_tests flag. // // A user can ask Google Test to list all tests that will run // so that when using a filter, a user will know what // tests to look for. The tests will not be run after listing. // // This program will be invoked from a Python unit test. // Don't run it directly. #include "gtest/gtest.h" // Several different test cases and tests that will be listed. TEST(Foo, Bar1) { } TEST(Foo, Bar2) { } TEST(Foo, DISABLED_Bar3) { } TEST(Abc, Xyz) { } TEST(Abc, Def) { } TEST(FooBar, Baz) { } class FooTest : public testing::Test { }; TEST_F(FooTest, Test1) { } TEST_F(FooTest, DISABLED_Test2) { } TEST_F(FooTest, Test3) { } TEST(FooDeathTest, Test1) { } // A group of value-parameterized tests. class MyType { public: explicit MyType(const std::string& a_value) : value_(a_value) {} const std::string& value() const { return value_; } private: std::string value_; }; // Teaches Google Test how to print a MyType. void PrintTo(const MyType& x, std::ostream* os) { *os << x.value(); } class ValueParamTest : public testing::TestWithParam { }; TEST_P(ValueParamTest, TestA) { } TEST_P(ValueParamTest, TestB) { } INSTANTIATE_TEST_CASE_P( MyInstantiation, ValueParamTest, testing::Values(MyType("one line"), MyType("two\nlines"), MyType("a very\nloooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong line"))); // NOLINT // A group of typed tests. // A deliberately long type name for testing the line-truncating // behavior when printing a type parameter. class VeryLoooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooogName { // NOLINT }; template class TypedTest : public testing::Test { }; template class MyArray { }; typedef testing::Types > MyTypes; TYPED_TEST_CASE(TypedTest, MyTypes); TYPED_TEST(TypedTest, TestA) { } TYPED_TEST(TypedTest, TestB) { } // A group of type-parameterized tests. template class TypeParamTest : public testing::Test { }; TYPED_TEST_CASE_P(TypeParamTest); TYPED_TEST_P(TypeParamTest, TestA) { } TYPED_TEST_P(TypeParamTest, TestB) { } REGISTER_TYPED_TEST_CASE_P(TypeParamTest, TestA, TestB); INSTANTIATE_TYPED_TEST_CASE_P(My, TypeParamTest, MyTypes); int main(int argc, char **argv) { ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } dlt-daemon-2.18.4/gtest-1.7.0/test/gtest_main_unittest.cc000066400000000000000000000035401353342203500230020ustar00rootroot00000000000000// Copyright 2006, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: wan@google.com (Zhanyong Wan) #include "gtest/gtest.h" // Tests that we don't have to define main() when we link to // gtest_main instead of gtest. namespace { TEST(GTestMainTest, ShouldSucceed) { } } // namespace // We are using the main() function defined in src/gtest_main.cc, so // we don't define it here. dlt-daemon-2.18.4/gtest-1.7.0/test/gtest_no_test_unittest.cc000066400000000000000000000046171353342203500235370ustar00rootroot00000000000000// Copyright 2006, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // Tests that a Google Test program that has no test defined can run // successfully. // // Author: wan@google.com (Zhanyong Wan) #include "gtest/gtest.h" int main(int argc, char **argv) { testing::InitGoogleTest(&argc, argv); // An ad-hoc assertion outside of all tests. // // This serves three purposes: // // 1. It verifies that an ad-hoc assertion can be executed even if // no test is defined. // 2. It verifies that a failed ad-hoc assertion causes the test // program to fail. // 3. We had a bug where the XML output won't be generated if an // assertion is executed before RUN_ALL_TESTS() is called, even // though --gtest_output=xml is specified. This makes sure the // bug is fixed and doesn't regress. EXPECT_EQ(1, 2); // The above EXPECT_EQ() should cause RUN_ALL_TESTS() to return non-zero. return RUN_ALL_TESTS() ? 0 : 1; } dlt-daemon-2.18.4/gtest-1.7.0/test/gtest_output_test.py000077500000000000000000000273451353342203500225750ustar00rootroot00000000000000#!/usr/bin/env python # # 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. """Tests the text output of Google C++ Testing Framework. SYNOPSIS gtest_output_test.py --build_dir=BUILD/DIR --gengolden # where BUILD/DIR contains the built gtest_output_test_ file. gtest_output_test.py --gengolden gtest_output_test.py """ __author__ = 'wan@google.com (Zhanyong Wan)' import os import re import sys import gtest_test_utils # The flag for generating the golden file GENGOLDEN_FLAG = '--gengolden' CATCH_EXCEPTIONS_ENV_VAR_NAME = 'GTEST_CATCH_EXCEPTIONS' IS_WINDOWS = os.name == 'nt' # TODO(vladl@google.com): remove the _lin suffix. GOLDEN_NAME = 'gtest_output_test_golden_lin.txt' PROGRAM_PATH = gtest_test_utils.GetTestExecutablePath('gtest_output_test_') # At least one command we exercise must not have the # --gtest_internal_skip_environment_and_ad_hoc_tests flag. COMMAND_LIST_TESTS = ({}, [PROGRAM_PATH, '--gtest_list_tests']) COMMAND_WITH_COLOR = ({}, [PROGRAM_PATH, '--gtest_color=yes']) COMMAND_WITH_TIME = ({}, [PROGRAM_PATH, '--gtest_print_time', '--gtest_internal_skip_environment_and_ad_hoc_tests', '--gtest_filter=FatalFailureTest.*:LoggingTest.*']) COMMAND_WITH_DISABLED = ( {}, [PROGRAM_PATH, '--gtest_also_run_disabled_tests', '--gtest_internal_skip_environment_and_ad_hoc_tests', '--gtest_filter=*DISABLED_*']) COMMAND_WITH_SHARDING = ( {'GTEST_SHARD_INDEX': '1', 'GTEST_TOTAL_SHARDS': '2'}, [PROGRAM_PATH, '--gtest_internal_skip_environment_and_ad_hoc_tests', '--gtest_filter=PassingTest.*']) GOLDEN_PATH = os.path.join(gtest_test_utils.GetSourceDir(), GOLDEN_NAME) def ToUnixLineEnding(s): """Changes all Windows/Mac line endings in s to UNIX line endings.""" return s.replace('\r\n', '\n').replace('\r', '\n') def RemoveLocations(test_output): """Removes all file location info from a Google Test program's output. Args: test_output: the output of a Google Test program. Returns: output with all file location info (in the form of 'DIRECTORY/FILE_NAME:LINE_NUMBER: 'or 'DIRECTORY\\FILE_NAME(LINE_NUMBER): ') replaced by 'FILE_NAME:#: '. """ return re.sub(r'.*[/\\](.+)(\:\d+|\(\d+\))\: ', r'\1:#: ', test_output) def RemoveStackTraceDetails(output): """Removes all stack traces from a Google Test program's output.""" # *? means "find the shortest string that matches". return re.sub(r'Stack trace:(.|\n)*?\n\n', 'Stack trace: (omitted)\n\n', output) def RemoveStackTraces(output): """Removes all traces of stack traces from a Google Test program's output.""" # *? means "find the shortest string that matches". return re.sub(r'Stack trace:(.|\n)*?\n\n', '', output) def RemoveTime(output): """Removes all time information from a Google Test program's output.""" return re.sub(r'\(\d+ ms', '(? ms', output) def RemoveTypeInfoDetails(test_output): """Removes compiler-specific type info from Google Test program's output. Args: test_output: the output of a Google Test program. Returns: output with type information normalized to canonical form. """ # some compilers output the name of type 'unsigned int' as 'unsigned' return re.sub(r'unsigned int', 'unsigned', test_output) def NormalizeToCurrentPlatform(test_output): """Normalizes platform specific output details for easier comparison.""" if IS_WINDOWS: # Removes the color information that is not present on Windows. test_output = re.sub('\x1b\\[(0;3\d)?m', '', test_output) # Changes failure message headers into the Windows format. test_output = re.sub(r': Failure\n', r': error: ', test_output) # Changes file(line_number) to file:line_number. test_output = re.sub(r'((\w|\.)+)\((\d+)\):', r'\1:\3:', test_output) return test_output def RemoveTestCounts(output): """Removes test counts from a Google Test program's output.""" output = re.sub(r'\d+ tests?, listed below', '? tests, listed below', output) output = re.sub(r'\d+ FAILED TESTS', '? FAILED TESTS', output) output = re.sub(r'\d+ tests? from \d+ test cases?', '? tests from ? test cases', output) output = re.sub(r'\d+ tests? from ([a-zA-Z_])', r'? tests from \1', output) return re.sub(r'\d+ tests?\.', '? tests.', output) def RemoveMatchingTests(test_output, pattern): """Removes output of specified tests from a Google Test program's output. This function strips not only the beginning and the end of a test but also all output in between. Args: test_output: A string containing the test output. pattern: A regex string that matches names of test cases or tests to remove. Returns: Contents of test_output with tests whose names match pattern removed. """ test_output = re.sub( r'.*\[ RUN \] .*%s(.|\n)*?\[( FAILED | OK )\] .*%s.*\n' % ( pattern, pattern), '', test_output) return re.sub(r'.*%s.*\n' % pattern, '', test_output) def NormalizeOutput(output): """Normalizes output (the output of gtest_output_test_.exe).""" output = ToUnixLineEnding(output) output = RemoveLocations(output) output = RemoveStackTraceDetails(output) output = RemoveTime(output) return output def GetShellCommandOutput(env_cmd): """Runs a command in a sub-process, and returns its output in a string. Args: env_cmd: The shell command. A 2-tuple where element 0 is a dict of extra environment variables to set, and element 1 is a string with the command and any flags. Returns: A string with the command's combined standard and diagnostic output. """ # Spawns cmd in a sub-process, and gets its standard I/O file objects. # Set and save the environment properly. environ = os.environ.copy() environ.update(env_cmd[0]) p = gtest_test_utils.Subprocess(env_cmd[1], env=environ) return p.output def GetCommandOutput(env_cmd): """Runs a command and returns its output with all file location info stripped off. Args: env_cmd: The shell command. A 2-tuple where element 0 is a dict of extra environment variables to set, and element 1 is a string with the command and any flags. """ # Disables exception pop-ups on Windows. environ, cmdline = env_cmd environ = dict(environ) # Ensures we are modifying a copy. environ[CATCH_EXCEPTIONS_ENV_VAR_NAME] = '1' return NormalizeOutput(GetShellCommandOutput((environ, cmdline))) def GetOutputOfAllCommands(): """Returns concatenated output from several representative commands.""" return (GetCommandOutput(COMMAND_WITH_COLOR) + GetCommandOutput(COMMAND_WITH_TIME) + GetCommandOutput(COMMAND_WITH_DISABLED) + GetCommandOutput(COMMAND_WITH_SHARDING)) test_list = GetShellCommandOutput(COMMAND_LIST_TESTS) SUPPORTS_DEATH_TESTS = 'DeathTest' in test_list SUPPORTS_TYPED_TESTS = 'TypedTest' in test_list SUPPORTS_THREADS = 'ExpectFailureWithThreadsTest' in test_list SUPPORTS_STACK_TRACES = False CAN_GENERATE_GOLDEN_FILE = (SUPPORTS_DEATH_TESTS and SUPPORTS_TYPED_TESTS and SUPPORTS_THREADS) class GTestOutputTest(gtest_test_utils.TestCase): def RemoveUnsupportedTests(self, test_output): if not SUPPORTS_DEATH_TESTS: test_output = RemoveMatchingTests(test_output, 'DeathTest') if not SUPPORTS_TYPED_TESTS: test_output = RemoveMatchingTests(test_output, 'TypedTest') test_output = RemoveMatchingTests(test_output, 'TypedDeathTest') test_output = RemoveMatchingTests(test_output, 'TypeParamDeathTest') if not SUPPORTS_THREADS: test_output = RemoveMatchingTests(test_output, 'ExpectFailureWithThreadsTest') test_output = RemoveMatchingTests(test_output, 'ScopedFakeTestPartResultReporterTest') test_output = RemoveMatchingTests(test_output, 'WorksConcurrently') if not SUPPORTS_STACK_TRACES: test_output = RemoveStackTraces(test_output) return test_output def testOutput(self): output = GetOutputOfAllCommands() golden_file = open(GOLDEN_PATH, 'rb') # A mis-configured source control system can cause \r appear in EOL # sequences when we read the golden file irrespective of an operating # system used. Therefore, we need to strip those \r's from newlines # unconditionally. golden = ToUnixLineEnding(golden_file.read()) golden_file.close() # We want the test to pass regardless of certain features being # supported or not. # We still have to remove type name specifics in all cases. normalized_actual = RemoveTypeInfoDetails(output) normalized_golden = RemoveTypeInfoDetails(golden) if CAN_GENERATE_GOLDEN_FILE: self.assertEqual(normalized_golden, normalized_actual) else: normalized_actual = NormalizeToCurrentPlatform( RemoveTestCounts(normalized_actual)) normalized_golden = NormalizeToCurrentPlatform( RemoveTestCounts(self.RemoveUnsupportedTests(normalized_golden))) # This code is very handy when debugging golden file differences: if os.getenv('DEBUG_GTEST_OUTPUT_TEST'): open(os.path.join( gtest_test_utils.GetSourceDir(), '_gtest_output_test_normalized_actual.txt'), 'wb').write( normalized_actual) open(os.path.join( gtest_test_utils.GetSourceDir(), '_gtest_output_test_normalized_golden.txt'), 'wb').write( normalized_golden) self.assertEqual(normalized_golden, normalized_actual) if __name__ == '__main__': if sys.argv[1:] == [GENGOLDEN_FLAG]: if CAN_GENERATE_GOLDEN_FILE: output = GetOutputOfAllCommands() golden_file = open(GOLDEN_PATH, 'wb') golden_file.write(output) golden_file.close() else: message = ( """Unable to write a golden file when compiled in an environment that does not support all the required features (death tests, typed tests, and multiple threads). Please generate the golden file using a binary built with those features enabled.""") sys.stderr.write(message) sys.exit(1) else: gtest_test_utils.Main() dlt-daemon-2.18.4/gtest-1.7.0/test/gtest_output_test_.cc000066400000000000000000000772661353342203500226750ustar00rootroot00000000000000// Copyright 2005, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // The purpose of this file is to generate Google Test output under // various conditions. The output will then be verified by // gtest_output_test.py to ensure that Google Test generates the // desired messages. Therefore, most tests in this file are MEANT TO // FAIL. // // Author: wan@google.com (Zhanyong Wan) #include "gtest/gtest-spi.h" #include "gtest/gtest.h" // Indicates that this translation unit is part of Google Test's // implementation. It must come before gtest-internal-inl.h is // included, or there will be a compiler error. This trick is to // prevent a user from accidentally including gtest-internal-inl.h in // his code. #define GTEST_IMPLEMENTATION_ 1 #include "src/gtest-internal-inl.h" #undef GTEST_IMPLEMENTATION_ #include #if GTEST_IS_THREADSAFE using testing::ScopedFakeTestPartResultReporter; using testing::TestPartResultArray; using testing::internal::Notification; using testing::internal::ThreadWithParam; #endif namespace posix = ::testing::internal::posix; using testing::internal::scoped_ptr; // Tests catching fatal failures. // A subroutine used by the following test. void TestEq1(int x) { ASSERT_EQ(1, x); } // This function calls a test subroutine, catches the fatal failure it // generates, and then returns early. void TryTestSubroutine() { // Calls a subrountine that yields a fatal failure. TestEq1(2); // Catches the fatal failure and aborts the test. // // The testing::Test:: prefix is necessary when calling // HasFatalFailure() outside of a TEST, TEST_F, or test fixture. if (testing::Test::HasFatalFailure()) return; // If we get here, something is wrong. FAIL() << "This should never be reached."; } TEST(PassingTest, PassingTest1) { } TEST(PassingTest, PassingTest2) { } // Tests that parameters of failing parameterized tests are printed in the // failing test summary. class FailingParamTest : public testing::TestWithParam {}; TEST_P(FailingParamTest, Fails) { EXPECT_EQ(1, GetParam()); } // This generates a test which will fail. Google Test is expected to print // its parameter when it outputs the list of all failed tests. INSTANTIATE_TEST_CASE_P(PrintingFailingParams, FailingParamTest, testing::Values(2)); static const char kGoldenString[] = "\"Line\0 1\"\nLine 2"; TEST(NonfatalFailureTest, EscapesStringOperands) { std::string actual = "actual \"string\""; EXPECT_EQ(kGoldenString, actual); const char* golden = kGoldenString; EXPECT_EQ(golden, actual); } // Tests catching a fatal failure in a subroutine. TEST(FatalFailureTest, FatalFailureInSubroutine) { printf("(expecting a failure that x should be 1)\n"); TryTestSubroutine(); } // Tests catching a fatal failure in a nested subroutine. TEST(FatalFailureTest, FatalFailureInNestedSubroutine) { printf("(expecting a failure that x should be 1)\n"); // Calls a subrountine that yields a fatal failure. TryTestSubroutine(); // Catches the fatal failure and aborts the test. // // When calling HasFatalFailure() inside a TEST, TEST_F, or test // fixture, the testing::Test:: prefix is not needed. if (HasFatalFailure()) return; // If we get here, something is wrong. FAIL() << "This should never be reached."; } // Tests HasFatalFailure() after a failed EXPECT check. TEST(FatalFailureTest, NonfatalFailureInSubroutine) { printf("(expecting a failure on false)\n"); EXPECT_TRUE(false); // Generates a nonfatal failure ASSERT_FALSE(HasFatalFailure()); // This should succeed. } // Tests interleaving user logging and Google Test assertions. TEST(LoggingTest, InterleavingLoggingAndAssertions) { static const int a[4] = { 3, 9, 2, 6 }; printf("(expecting 2 failures on (3) >= (a[i]))\n"); for (int i = 0; i < static_cast(sizeof(a)/sizeof(*a)); i++) { printf("i == %d\n", i); EXPECT_GE(3, a[i]); } } // Tests the SCOPED_TRACE macro. // A helper function for testing SCOPED_TRACE. void SubWithoutTrace(int n) { EXPECT_EQ(1, n); ASSERT_EQ(2, n); } // Another helper function for testing SCOPED_TRACE. void SubWithTrace(int n) { SCOPED_TRACE(testing::Message() << "n = " << n); SubWithoutTrace(n); } // Tests that SCOPED_TRACE() obeys lexical scopes. TEST(SCOPED_TRACETest, ObeysScopes) { printf("(expected to fail)\n"); // There should be no trace before SCOPED_TRACE() is invoked. ADD_FAILURE() << "This failure is expected, and shouldn't have a trace."; { SCOPED_TRACE("Expected trace"); // After SCOPED_TRACE(), a failure in the current scope should contain // the trace. ADD_FAILURE() << "This failure is expected, and should have a trace."; } // Once the control leaves the scope of the SCOPED_TRACE(), there // should be no trace again. ADD_FAILURE() << "This failure is expected, and shouldn't have a trace."; } // Tests that SCOPED_TRACE works inside a loop. TEST(SCOPED_TRACETest, WorksInLoop) { printf("(expected to fail)\n"); for (int i = 1; i <= 2; i++) { SCOPED_TRACE(testing::Message() << "i = " << i); SubWithoutTrace(i); } } // Tests that SCOPED_TRACE works in a subroutine. TEST(SCOPED_TRACETest, WorksInSubroutine) { printf("(expected to fail)\n"); SubWithTrace(1); SubWithTrace(2); } // Tests that SCOPED_TRACE can be nested. TEST(SCOPED_TRACETest, CanBeNested) { printf("(expected to fail)\n"); SCOPED_TRACE(""); // A trace without a message. SubWithTrace(2); } // Tests that multiple SCOPED_TRACEs can be used in the same scope. TEST(SCOPED_TRACETest, CanBeRepeated) { printf("(expected to fail)\n"); SCOPED_TRACE("A"); ADD_FAILURE() << "This failure is expected, and should contain trace point A."; SCOPED_TRACE("B"); ADD_FAILURE() << "This failure is expected, and should contain trace point A and B."; { SCOPED_TRACE("C"); ADD_FAILURE() << "This failure is expected, and should " << "contain trace point A, B, and C."; } SCOPED_TRACE("D"); ADD_FAILURE() << "This failure is expected, and should " << "contain trace point A, B, and D."; } #if GTEST_IS_THREADSAFE // Tests that SCOPED_TRACE()s can be used concurrently from multiple // threads. Namely, an assertion should be affected by // SCOPED_TRACE()s in its own thread only. // Here's the sequence of actions that happen in the test: // // Thread A (main) | Thread B (spawned) // ===============================|================================ // spawns thread B | // -------------------------------+-------------------------------- // waits for n1 | SCOPED_TRACE("Trace B"); // | generates failure #1 // | notifies n1 // -------------------------------+-------------------------------- // SCOPED_TRACE("Trace A"); | waits for n2 // generates failure #2 | // notifies n2 | // -------------------------------|-------------------------------- // waits for n3 | generates failure #3 // | trace B dies // | generates failure #4 // | notifies n3 // -------------------------------|-------------------------------- // generates failure #5 | finishes // trace A dies | // generates failure #6 | // -------------------------------|-------------------------------- // waits for thread B to finish | struct CheckPoints { Notification n1; Notification n2; Notification n3; }; static void ThreadWithScopedTrace(CheckPoints* check_points) { { SCOPED_TRACE("Trace B"); ADD_FAILURE() << "Expected failure #1 (in thread B, only trace B alive)."; check_points->n1.Notify(); check_points->n2.WaitForNotification(); ADD_FAILURE() << "Expected failure #3 (in thread B, trace A & B both alive)."; } // Trace B dies here. ADD_FAILURE() << "Expected failure #4 (in thread B, only trace A alive)."; check_points->n3.Notify(); } TEST(SCOPED_TRACETest, WorksConcurrently) { printf("(expecting 6 failures)\n"); CheckPoints check_points; ThreadWithParam thread(&ThreadWithScopedTrace, &check_points, NULL); check_points.n1.WaitForNotification(); { SCOPED_TRACE("Trace A"); ADD_FAILURE() << "Expected failure #2 (in thread A, trace A & B both alive)."; check_points.n2.Notify(); check_points.n3.WaitForNotification(); ADD_FAILURE() << "Expected failure #5 (in thread A, only trace A alive)."; } // Trace A dies here. ADD_FAILURE() << "Expected failure #6 (in thread A, no trace alive)."; thread.Join(); } #endif // GTEST_IS_THREADSAFE TEST(DisabledTestsWarningTest, DISABLED_AlsoRunDisabledTestsFlagSuppressesWarning) { // This test body is intentionally empty. Its sole purpose is for // verifying that the --gtest_also_run_disabled_tests flag // suppresses the "YOU HAVE 12 DISABLED TESTS" warning at the end of // the test output. } // Tests using assertions outside of TEST and TEST_F. // // This function creates two failures intentionally. void AdHocTest() { printf("The non-test part of the code is expected to have 2 failures.\n\n"); EXPECT_TRUE(false); EXPECT_EQ(2, 3); } // Runs all TESTs, all TEST_Fs, and the ad hoc test. int RunAllTests() { AdHocTest(); return RUN_ALL_TESTS(); } // Tests non-fatal failures in the fixture constructor. class NonFatalFailureInFixtureConstructorTest : public testing::Test { protected: NonFatalFailureInFixtureConstructorTest() { printf("(expecting 5 failures)\n"); ADD_FAILURE() << "Expected failure #1, in the test fixture c'tor."; } ~NonFatalFailureInFixtureConstructorTest() { ADD_FAILURE() << "Expected failure #5, in the test fixture d'tor."; } virtual void SetUp() { ADD_FAILURE() << "Expected failure #2, in SetUp()."; } virtual void TearDown() { ADD_FAILURE() << "Expected failure #4, in TearDown."; } }; TEST_F(NonFatalFailureInFixtureConstructorTest, FailureInConstructor) { ADD_FAILURE() << "Expected failure #3, in the test body."; } // Tests fatal failures in the fixture constructor. class FatalFailureInFixtureConstructorTest : public testing::Test { protected: FatalFailureInFixtureConstructorTest() { printf("(expecting 2 failures)\n"); Init(); } ~FatalFailureInFixtureConstructorTest() { ADD_FAILURE() << "Expected failure #2, in the test fixture d'tor."; } virtual void SetUp() { ADD_FAILURE() << "UNEXPECTED failure in SetUp(). " << "We should never get here, as the test fixture c'tor " << "had a fatal failure."; } virtual void TearDown() { ADD_FAILURE() << "UNEXPECTED failure in TearDown(). " << "We should never get here, as the test fixture c'tor " << "had a fatal failure."; } private: void Init() { FAIL() << "Expected failure #1, in the test fixture c'tor."; } }; TEST_F(FatalFailureInFixtureConstructorTest, FailureInConstructor) { ADD_FAILURE() << "UNEXPECTED failure in the test body. " << "We should never get here, as the test fixture c'tor " << "had a fatal failure."; } // Tests non-fatal failures in SetUp(). class NonFatalFailureInSetUpTest : public testing::Test { protected: virtual ~NonFatalFailureInSetUpTest() { Deinit(); } virtual void SetUp() { printf("(expecting 4 failures)\n"); ADD_FAILURE() << "Expected failure #1, in SetUp()."; } virtual void TearDown() { FAIL() << "Expected failure #3, in TearDown()."; } private: void Deinit() { FAIL() << "Expected failure #4, in the test fixture d'tor."; } }; TEST_F(NonFatalFailureInSetUpTest, FailureInSetUp) { FAIL() << "Expected failure #2, in the test function."; } // Tests fatal failures in SetUp(). class FatalFailureInSetUpTest : public testing::Test { protected: virtual ~FatalFailureInSetUpTest() { Deinit(); } virtual void SetUp() { printf("(expecting 3 failures)\n"); FAIL() << "Expected failure #1, in SetUp()."; } virtual void TearDown() { FAIL() << "Expected failure #2, in TearDown()."; } private: void Deinit() { FAIL() << "Expected failure #3, in the test fixture d'tor."; } }; TEST_F(FatalFailureInSetUpTest, FailureInSetUp) { FAIL() << "UNEXPECTED failure in the test function. " << "We should never get here, as SetUp() failed."; } TEST(AddFailureAtTest, MessageContainsSpecifiedFileAndLineNumber) { ADD_FAILURE_AT("foo.cc", 42) << "Expected failure in foo.cc"; } #if GTEST_IS_THREADSAFE // A unary function that may die. void DieIf(bool should_die) { GTEST_CHECK_(!should_die) << " - death inside DieIf()."; } // Tests running death tests in a multi-threaded context. // Used for coordination between the main and the spawn thread. struct SpawnThreadNotifications { SpawnThreadNotifications() {} Notification spawn_thread_started; Notification spawn_thread_ok_to_terminate; private: GTEST_DISALLOW_COPY_AND_ASSIGN_(SpawnThreadNotifications); }; // The function to be executed in the thread spawn by the // MultipleThreads test (below). static void ThreadRoutine(SpawnThreadNotifications* notifications) { // Signals the main thread that this thread has started. notifications->spawn_thread_started.Notify(); // Waits for permission to finish from the main thread. notifications->spawn_thread_ok_to_terminate.WaitForNotification(); } // This is a death-test test, but it's not named with a DeathTest // suffix. It starts threads which might interfere with later // death tests, so it must run after all other death tests. class DeathTestAndMultiThreadsTest : public testing::Test { protected: // Starts a thread and waits for it to begin. virtual void SetUp() { thread_.reset(new ThreadWithParam( &ThreadRoutine, ¬ifications_, NULL)); notifications_.spawn_thread_started.WaitForNotification(); } // Tells the thread to finish, and reaps it. // Depending on the version of the thread library in use, // a manager thread might still be left running that will interfere // with later death tests. This is unfortunate, but this class // cleans up after itself as best it can. virtual void TearDown() { notifications_.spawn_thread_ok_to_terminate.Notify(); } private: SpawnThreadNotifications notifications_; scoped_ptr > thread_; }; #endif // GTEST_IS_THREADSAFE // The MixedUpTestCaseTest test case verifies that Google Test will fail a // test if it uses a different fixture class than what other tests in // the same test case use. It deliberately contains two fixture // classes with the same name but defined in different namespaces. // The MixedUpTestCaseWithSameTestNameTest test case verifies that // when the user defines two tests with the same test case name AND // same test name (but in different namespaces), the second test will // fail. namespace foo { class MixedUpTestCaseTest : public testing::Test { }; TEST_F(MixedUpTestCaseTest, FirstTestFromNamespaceFoo) {} TEST_F(MixedUpTestCaseTest, SecondTestFromNamespaceFoo) {} class MixedUpTestCaseWithSameTestNameTest : public testing::Test { }; TEST_F(MixedUpTestCaseWithSameTestNameTest, TheSecondTestWithThisNameShouldFail) {} } // namespace foo namespace bar { class MixedUpTestCaseTest : public testing::Test { }; // The following two tests are expected to fail. We rely on the // golden file to check that Google Test generates the right error message. TEST_F(MixedUpTestCaseTest, ThisShouldFail) {} TEST_F(MixedUpTestCaseTest, ThisShouldFailToo) {} class MixedUpTestCaseWithSameTestNameTest : public testing::Test { }; // Expected to fail. We rely on the golden file to check that Google Test // generates the right error message. TEST_F(MixedUpTestCaseWithSameTestNameTest, TheSecondTestWithThisNameShouldFail) {} } // namespace bar // The following two test cases verify that Google Test catches the user // error of mixing TEST and TEST_F in the same test case. The first // test case checks the scenario where TEST_F appears before TEST, and // the second one checks where TEST appears before TEST_F. class TEST_F_before_TEST_in_same_test_case : public testing::Test { }; TEST_F(TEST_F_before_TEST_in_same_test_case, DefinedUsingTEST_F) {} // Expected to fail. We rely on the golden file to check that Google Test // generates the right error message. TEST(TEST_F_before_TEST_in_same_test_case, DefinedUsingTESTAndShouldFail) {} class TEST_before_TEST_F_in_same_test_case : public testing::Test { }; TEST(TEST_before_TEST_F_in_same_test_case, DefinedUsingTEST) {} // Expected to fail. We rely on the golden file to check that Google Test // generates the right error message. TEST_F(TEST_before_TEST_F_in_same_test_case, DefinedUsingTEST_FAndShouldFail) { } // Used for testing EXPECT_NONFATAL_FAILURE() and EXPECT_FATAL_FAILURE(). int global_integer = 0; // Tests that EXPECT_NONFATAL_FAILURE() can reference global variables. TEST(ExpectNonfatalFailureTest, CanReferenceGlobalVariables) { global_integer = 0; EXPECT_NONFATAL_FAILURE({ EXPECT_EQ(1, global_integer) << "Expected non-fatal failure."; }, "Expected non-fatal failure."); } // Tests that EXPECT_NONFATAL_FAILURE() can reference local variables // (static or not). TEST(ExpectNonfatalFailureTest, CanReferenceLocalVariables) { int m = 0; static int n; n = 1; EXPECT_NONFATAL_FAILURE({ EXPECT_EQ(m, n) << "Expected non-fatal failure."; }, "Expected non-fatal failure."); } // Tests that EXPECT_NONFATAL_FAILURE() succeeds when there is exactly // one non-fatal failure and no fatal failure. TEST(ExpectNonfatalFailureTest, SucceedsWhenThereIsOneNonfatalFailure) { EXPECT_NONFATAL_FAILURE({ ADD_FAILURE() << "Expected non-fatal failure."; }, "Expected non-fatal failure."); } // Tests that EXPECT_NONFATAL_FAILURE() fails when there is no // non-fatal failure. TEST(ExpectNonfatalFailureTest, FailsWhenThereIsNoNonfatalFailure) { printf("(expecting a failure)\n"); EXPECT_NONFATAL_FAILURE({ }, ""); } // Tests that EXPECT_NONFATAL_FAILURE() fails when there are two // non-fatal failures. TEST(ExpectNonfatalFailureTest, FailsWhenThereAreTwoNonfatalFailures) { printf("(expecting a failure)\n"); EXPECT_NONFATAL_FAILURE({ ADD_FAILURE() << "Expected non-fatal failure 1."; ADD_FAILURE() << "Expected non-fatal failure 2."; }, ""); } // Tests that EXPECT_NONFATAL_FAILURE() fails when there is one fatal // failure. TEST(ExpectNonfatalFailureTest, FailsWhenThereIsOneFatalFailure) { printf("(expecting a failure)\n"); EXPECT_NONFATAL_FAILURE({ FAIL() << "Expected fatal failure."; }, ""); } // Tests that EXPECT_NONFATAL_FAILURE() fails when the statement being // tested returns. TEST(ExpectNonfatalFailureTest, FailsWhenStatementReturns) { printf("(expecting a failure)\n"); EXPECT_NONFATAL_FAILURE({ return; }, ""); } #if GTEST_HAS_EXCEPTIONS // Tests that EXPECT_NONFATAL_FAILURE() fails when the statement being // tested throws. TEST(ExpectNonfatalFailureTest, FailsWhenStatementThrows) { printf("(expecting a failure)\n"); try { EXPECT_NONFATAL_FAILURE({ throw 0; }, ""); } catch(int) { // NOLINT } } #endif // GTEST_HAS_EXCEPTIONS // Tests that EXPECT_FATAL_FAILURE() can reference global variables. TEST(ExpectFatalFailureTest, CanReferenceGlobalVariables) { global_integer = 0; EXPECT_FATAL_FAILURE({ ASSERT_EQ(1, global_integer) << "Expected fatal failure."; }, "Expected fatal failure."); } // Tests that EXPECT_FATAL_FAILURE() can reference local static // variables. TEST(ExpectFatalFailureTest, CanReferenceLocalStaticVariables) { static int n; n = 1; EXPECT_FATAL_FAILURE({ ASSERT_EQ(0, n) << "Expected fatal failure."; }, "Expected fatal failure."); } // Tests that EXPECT_FATAL_FAILURE() succeeds when there is exactly // one fatal failure and no non-fatal failure. TEST(ExpectFatalFailureTest, SucceedsWhenThereIsOneFatalFailure) { EXPECT_FATAL_FAILURE({ FAIL() << "Expected fatal failure."; }, "Expected fatal failure."); } // Tests that EXPECT_FATAL_FAILURE() fails when there is no fatal // failure. TEST(ExpectFatalFailureTest, FailsWhenThereIsNoFatalFailure) { printf("(expecting a failure)\n"); EXPECT_FATAL_FAILURE({ }, ""); } // A helper for generating a fatal failure. void FatalFailure() { FAIL() << "Expected fatal failure."; } // Tests that EXPECT_FATAL_FAILURE() fails when there are two // fatal failures. TEST(ExpectFatalFailureTest, FailsWhenThereAreTwoFatalFailures) { printf("(expecting a failure)\n"); EXPECT_FATAL_FAILURE({ FatalFailure(); FatalFailure(); }, ""); } // Tests that EXPECT_FATAL_FAILURE() fails when there is one non-fatal // failure. TEST(ExpectFatalFailureTest, FailsWhenThereIsOneNonfatalFailure) { printf("(expecting a failure)\n"); EXPECT_FATAL_FAILURE({ ADD_FAILURE() << "Expected non-fatal failure."; }, ""); } // Tests that EXPECT_FATAL_FAILURE() fails when the statement being // tested returns. TEST(ExpectFatalFailureTest, FailsWhenStatementReturns) { printf("(expecting a failure)\n"); EXPECT_FATAL_FAILURE({ return; }, ""); } #if GTEST_HAS_EXCEPTIONS // Tests that EXPECT_FATAL_FAILURE() fails when the statement being // tested throws. TEST(ExpectFatalFailureTest, FailsWhenStatementThrows) { printf("(expecting a failure)\n"); try { EXPECT_FATAL_FAILURE({ throw 0; }, ""); } catch(int) { // NOLINT } } #endif // GTEST_HAS_EXCEPTIONS // This #ifdef block tests the output of typed tests. #if GTEST_HAS_TYPED_TEST template class TypedTest : public testing::Test { }; TYPED_TEST_CASE(TypedTest, testing::Types); TYPED_TEST(TypedTest, Success) { EXPECT_EQ(0, TypeParam()); } TYPED_TEST(TypedTest, Failure) { EXPECT_EQ(1, TypeParam()) << "Expected failure"; } #endif // GTEST_HAS_TYPED_TEST // This #ifdef block tests the output of type-parameterized tests. #if GTEST_HAS_TYPED_TEST_P template class TypedTestP : public testing::Test { }; TYPED_TEST_CASE_P(TypedTestP); TYPED_TEST_P(TypedTestP, Success) { EXPECT_EQ(0U, TypeParam()); } TYPED_TEST_P(TypedTestP, Failure) { EXPECT_EQ(1U, TypeParam()) << "Expected failure"; } REGISTER_TYPED_TEST_CASE_P(TypedTestP, Success, Failure); typedef testing::Types UnsignedTypes; INSTANTIATE_TYPED_TEST_CASE_P(Unsigned, TypedTestP, UnsignedTypes); #endif // GTEST_HAS_TYPED_TEST_P #if GTEST_HAS_DEATH_TEST // We rely on the golden file to verify that tests whose test case // name ends with DeathTest are run first. TEST(ADeathTest, ShouldRunFirst) { } # if GTEST_HAS_TYPED_TEST // We rely on the golden file to verify that typed tests whose test // case name ends with DeathTest are run first. template class ATypedDeathTest : public testing::Test { }; typedef testing::Types NumericTypes; TYPED_TEST_CASE(ATypedDeathTest, NumericTypes); TYPED_TEST(ATypedDeathTest, ShouldRunFirst) { } # endif // GTEST_HAS_TYPED_TEST # if GTEST_HAS_TYPED_TEST_P // We rely on the golden file to verify that type-parameterized tests // whose test case name ends with DeathTest are run first. template class ATypeParamDeathTest : public testing::Test { }; TYPED_TEST_CASE_P(ATypeParamDeathTest); TYPED_TEST_P(ATypeParamDeathTest, ShouldRunFirst) { } REGISTER_TYPED_TEST_CASE_P(ATypeParamDeathTest, ShouldRunFirst); INSTANTIATE_TYPED_TEST_CASE_P(My, ATypeParamDeathTest, NumericTypes); # endif // GTEST_HAS_TYPED_TEST_P #endif // GTEST_HAS_DEATH_TEST // Tests various failure conditions of // EXPECT_{,NON}FATAL_FAILURE{,_ON_ALL_THREADS}. class ExpectFailureTest : public testing::Test { public: // Must be public and not protected due to a bug in g++ 3.4.2. enum FailureMode { FATAL_FAILURE, NONFATAL_FAILURE }; static void AddFailure(FailureMode failure) { if (failure == FATAL_FAILURE) { FAIL() << "Expected fatal failure."; } else { ADD_FAILURE() << "Expected non-fatal failure."; } } }; TEST_F(ExpectFailureTest, ExpectFatalFailure) { // Expected fatal failure, but succeeds. printf("(expecting 1 failure)\n"); EXPECT_FATAL_FAILURE(SUCCEED(), "Expected fatal failure."); // Expected fatal failure, but got a non-fatal failure. printf("(expecting 1 failure)\n"); EXPECT_FATAL_FAILURE(AddFailure(NONFATAL_FAILURE), "Expected non-fatal " "failure."); // Wrong message. printf("(expecting 1 failure)\n"); EXPECT_FATAL_FAILURE(AddFailure(FATAL_FAILURE), "Some other fatal failure " "expected."); } TEST_F(ExpectFailureTest, ExpectNonFatalFailure) { // Expected non-fatal failure, but succeeds. printf("(expecting 1 failure)\n"); EXPECT_NONFATAL_FAILURE(SUCCEED(), "Expected non-fatal failure."); // Expected non-fatal failure, but got a fatal failure. printf("(expecting 1 failure)\n"); EXPECT_NONFATAL_FAILURE(AddFailure(FATAL_FAILURE), "Expected fatal failure."); // Wrong message. printf("(expecting 1 failure)\n"); EXPECT_NONFATAL_FAILURE(AddFailure(NONFATAL_FAILURE), "Some other non-fatal " "failure."); } #if GTEST_IS_THREADSAFE class ExpectFailureWithThreadsTest : public ExpectFailureTest { protected: static void AddFailureInOtherThread(FailureMode failure) { ThreadWithParam thread(&AddFailure, failure, NULL); thread.Join(); } }; TEST_F(ExpectFailureWithThreadsTest, ExpectFatalFailure) { // We only intercept the current thread. printf("(expecting 2 failures)\n"); EXPECT_FATAL_FAILURE(AddFailureInOtherThread(FATAL_FAILURE), "Expected fatal failure."); } TEST_F(ExpectFailureWithThreadsTest, ExpectNonFatalFailure) { // We only intercept the current thread. printf("(expecting 2 failures)\n"); EXPECT_NONFATAL_FAILURE(AddFailureInOtherThread(NONFATAL_FAILURE), "Expected non-fatal failure."); } typedef ExpectFailureWithThreadsTest ScopedFakeTestPartResultReporterTest; // Tests that the ScopedFakeTestPartResultReporter only catches failures from // the current thread if it is instantiated with INTERCEPT_ONLY_CURRENT_THREAD. TEST_F(ScopedFakeTestPartResultReporterTest, InterceptOnlyCurrentThread) { printf("(expecting 2 failures)\n"); TestPartResultArray results; { ScopedFakeTestPartResultReporter reporter( ScopedFakeTestPartResultReporter::INTERCEPT_ONLY_CURRENT_THREAD, &results); AddFailureInOtherThread(FATAL_FAILURE); AddFailureInOtherThread(NONFATAL_FAILURE); } // The two failures should not have been intercepted. EXPECT_EQ(0, results.size()) << "This shouldn't fail."; } #endif // GTEST_IS_THREADSAFE TEST_F(ExpectFailureTest, ExpectFatalFailureOnAllThreads) { // Expected fatal failure, but succeeds. printf("(expecting 1 failure)\n"); EXPECT_FATAL_FAILURE_ON_ALL_THREADS(SUCCEED(), "Expected fatal failure."); // Expected fatal failure, but got a non-fatal failure. printf("(expecting 1 failure)\n"); EXPECT_FATAL_FAILURE_ON_ALL_THREADS(AddFailure(NONFATAL_FAILURE), "Expected non-fatal failure."); // Wrong message. printf("(expecting 1 failure)\n"); EXPECT_FATAL_FAILURE_ON_ALL_THREADS(AddFailure(FATAL_FAILURE), "Some other fatal failure expected."); } TEST_F(ExpectFailureTest, ExpectNonFatalFailureOnAllThreads) { // Expected non-fatal failure, but succeeds. printf("(expecting 1 failure)\n"); EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS(SUCCEED(), "Expected non-fatal " "failure."); // Expected non-fatal failure, but got a fatal failure. printf("(expecting 1 failure)\n"); EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS(AddFailure(FATAL_FAILURE), "Expected fatal failure."); // Wrong message. printf("(expecting 1 failure)\n"); EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS(AddFailure(NONFATAL_FAILURE), "Some other non-fatal failure."); } // Two test environments for testing testing::AddGlobalTestEnvironment(). class FooEnvironment : public testing::Environment { public: virtual void SetUp() { printf("%s", "FooEnvironment::SetUp() called.\n"); } virtual void TearDown() { printf("%s", "FooEnvironment::TearDown() called.\n"); FAIL() << "Expected fatal failure."; } }; class BarEnvironment : public testing::Environment { public: virtual void SetUp() { printf("%s", "BarEnvironment::SetUp() called.\n"); } virtual void TearDown() { printf("%s", "BarEnvironment::TearDown() called.\n"); ADD_FAILURE() << "Expected non-fatal failure."; } }; bool GTEST_FLAG(internal_skip_environment_and_ad_hoc_tests) = false; // The main function. // // The idea is to use Google Test to run all the tests we have defined (some // of them are intended to fail), and then compare the test results // with the "golden" file. int main(int argc, char **argv) { testing::GTEST_FLAG(print_time) = false; // We just run the tests, knowing some of them are intended to fail. // We will use a separate Python script to compare the output of // this program with the golden file. // It's hard to test InitGoogleTest() directly, as it has many // global side effects. The following line serves as a sanity test // for it. testing::InitGoogleTest(&argc, argv); if (argc >= 2 && (std::string(argv[1]) == "--gtest_internal_skip_environment_and_ad_hoc_tests")) GTEST_FLAG(internal_skip_environment_and_ad_hoc_tests) = true; #if GTEST_HAS_DEATH_TEST if (testing::internal::GTEST_FLAG(internal_run_death_test) != "") { // Skip the usual output capturing if we're running as the child // process of an threadsafe-style death test. # if GTEST_OS_WINDOWS posix::FReopen("nul:", "w", stdout); # else posix::FReopen("/dev/null", "w", stdout); # endif // GTEST_OS_WINDOWS return RUN_ALL_TESTS(); } #endif // GTEST_HAS_DEATH_TEST if (GTEST_FLAG(internal_skip_environment_and_ad_hoc_tests)) return RUN_ALL_TESTS(); // Registers two global test environments. // The golden file verifies that they are set up in the order they // are registered, and torn down in the reverse order. testing::AddGlobalTestEnvironment(new FooEnvironment); testing::AddGlobalTestEnvironment(new BarEnvironment); return RunAllTests(); } dlt-daemon-2.18.4/gtest-1.7.0/test/gtest_output_test_golden_lin.txt000066400000000000000000000670041353342203500251470ustar00rootroot00000000000000The non-test part of the code is expected to have 2 failures. gtest_output_test_.cc:#: Failure Value of: false Actual: false Expected: true gtest_output_test_.cc:#: Failure Value of: 3 Expected: 2 [==========] Running 63 tests from 28 test cases. [----------] Global test environment set-up. FooEnvironment::SetUp() called. BarEnvironment::SetUp() called. [----------] 1 test from ADeathTest [ RUN ] ADeathTest.ShouldRunFirst [ OK ] ADeathTest.ShouldRunFirst [----------] 1 test from ATypedDeathTest/0, where TypeParam = int [ RUN ] ATypedDeathTest/0.ShouldRunFirst [ OK ] ATypedDeathTest/0.ShouldRunFirst [----------] 1 test from ATypedDeathTest/1, where TypeParam = double [ RUN ] ATypedDeathTest/1.ShouldRunFirst [ OK ] ATypedDeathTest/1.ShouldRunFirst [----------] 1 test from My/ATypeParamDeathTest/0, where TypeParam = int [ RUN ] My/ATypeParamDeathTest/0.ShouldRunFirst [ OK ] My/ATypeParamDeathTest/0.ShouldRunFirst [----------] 1 test from My/ATypeParamDeathTest/1, where TypeParam = double [ RUN ] My/ATypeParamDeathTest/1.ShouldRunFirst [ OK ] My/ATypeParamDeathTest/1.ShouldRunFirst [----------] 2 tests from PassingTest [ RUN ] PassingTest.PassingTest1 [ OK ] PassingTest.PassingTest1 [ RUN ] PassingTest.PassingTest2 [ OK ] PassingTest.PassingTest2 [----------] 1 test from NonfatalFailureTest [ RUN ] NonfatalFailureTest.EscapesStringOperands gtest_output_test_.cc:#: Failure Value of: actual Actual: "actual \"string\"" Expected: kGoldenString Which is: "\"Line" gtest_output_test_.cc:#: Failure Value of: actual Actual: "actual \"string\"" Expected: golden Which is: "\"Line" [ FAILED ] NonfatalFailureTest.EscapesStringOperands [----------] 3 tests from FatalFailureTest [ RUN ] FatalFailureTest.FatalFailureInSubroutine (expecting a failure that x should be 1) gtest_output_test_.cc:#: Failure Value of: x Actual: 2 Expected: 1 [ FAILED ] FatalFailureTest.FatalFailureInSubroutine [ RUN ] FatalFailureTest.FatalFailureInNestedSubroutine (expecting a failure that x should be 1) gtest_output_test_.cc:#: Failure Value of: x Actual: 2 Expected: 1 [ FAILED ] FatalFailureTest.FatalFailureInNestedSubroutine [ RUN ] FatalFailureTest.NonfatalFailureInSubroutine (expecting a failure on false) gtest_output_test_.cc:#: Failure Value of: false Actual: false Expected: true [ FAILED ] FatalFailureTest.NonfatalFailureInSubroutine [----------] 1 test from LoggingTest [ RUN ] LoggingTest.InterleavingLoggingAndAssertions (expecting 2 failures on (3) >= (a[i])) i == 0 i == 1 gtest_output_test_.cc:#: Failure Expected: (3) >= (a[i]), actual: 3 vs 9 i == 2 i == 3 gtest_output_test_.cc:#: Failure Expected: (3) >= (a[i]), actual: 3 vs 6 [ FAILED ] LoggingTest.InterleavingLoggingAndAssertions [----------] 6 tests from SCOPED_TRACETest [ RUN ] SCOPED_TRACETest.ObeysScopes (expected to fail) gtest_output_test_.cc:#: Failure Failed This failure is expected, and shouldn't have a trace. gtest_output_test_.cc:#: Failure Failed This failure is expected, and should have a trace. Google Test trace: gtest_output_test_.cc:#: Expected trace gtest_output_test_.cc:#: Failure Failed This failure is expected, and shouldn't have a trace. [ FAILED ] SCOPED_TRACETest.ObeysScopes [ RUN ] SCOPED_TRACETest.WorksInLoop (expected to fail) gtest_output_test_.cc:#: Failure Value of: n Actual: 1 Expected: 2 Google Test trace: gtest_output_test_.cc:#: i = 1 gtest_output_test_.cc:#: Failure Value of: n Actual: 2 Expected: 1 Google Test trace: gtest_output_test_.cc:#: i = 2 [ FAILED ] SCOPED_TRACETest.WorksInLoop [ RUN ] SCOPED_TRACETest.WorksInSubroutine (expected to fail) gtest_output_test_.cc:#: Failure Value of: n Actual: 1 Expected: 2 Google Test trace: gtest_output_test_.cc:#: n = 1 gtest_output_test_.cc:#: Failure Value of: n Actual: 2 Expected: 1 Google Test trace: gtest_output_test_.cc:#: n = 2 [ FAILED ] SCOPED_TRACETest.WorksInSubroutine [ RUN ] SCOPED_TRACETest.CanBeNested (expected to fail) gtest_output_test_.cc:#: Failure Value of: n Actual: 2 Expected: 1 Google Test trace: gtest_output_test_.cc:#: n = 2 gtest_output_test_.cc:#: [ FAILED ] SCOPED_TRACETest.CanBeNested [ RUN ] SCOPED_TRACETest.CanBeRepeated (expected to fail) gtest_output_test_.cc:#: Failure Failed This failure is expected, and should contain trace point A. Google Test trace: gtest_output_test_.cc:#: A gtest_output_test_.cc:#: Failure Failed This failure is expected, and should contain trace point A and B. Google Test trace: gtest_output_test_.cc:#: B gtest_output_test_.cc:#: A gtest_output_test_.cc:#: Failure Failed This failure is expected, and should contain trace point A, B, and C. Google Test trace: gtest_output_test_.cc:#: C gtest_output_test_.cc:#: B gtest_output_test_.cc:#: A gtest_output_test_.cc:#: Failure Failed This failure is expected, and should contain trace point A, B, and D. Google Test trace: gtest_output_test_.cc:#: D gtest_output_test_.cc:#: B gtest_output_test_.cc:#: A [ FAILED ] SCOPED_TRACETest.CanBeRepeated [ RUN ] SCOPED_TRACETest.WorksConcurrently (expecting 6 failures) gtest_output_test_.cc:#: Failure Failed Expected failure #1 (in thread B, only trace B alive). Google Test trace: gtest_output_test_.cc:#: Trace B gtest_output_test_.cc:#: Failure Failed Expected failure #2 (in thread A, trace A & B both alive). Google Test trace: gtest_output_test_.cc:#: Trace A gtest_output_test_.cc:#: Failure Failed Expected failure #3 (in thread B, trace A & B both alive). Google Test trace: gtest_output_test_.cc:#: Trace B gtest_output_test_.cc:#: Failure Failed Expected failure #4 (in thread B, only trace A alive). gtest_output_test_.cc:#: Failure Failed Expected failure #5 (in thread A, only trace A alive). Google Test trace: gtest_output_test_.cc:#: Trace A gtest_output_test_.cc:#: Failure Failed Expected failure #6 (in thread A, no trace alive). [ FAILED ] SCOPED_TRACETest.WorksConcurrently [----------] 1 test from NonFatalFailureInFixtureConstructorTest [ RUN ] NonFatalFailureInFixtureConstructorTest.FailureInConstructor (expecting 5 failures) gtest_output_test_.cc:#: Failure Failed Expected failure #1, in the test fixture c'tor. gtest_output_test_.cc:#: Failure Failed Expected failure #2, in SetUp(). gtest_output_test_.cc:#: Failure Failed Expected failure #3, in the test body. gtest_output_test_.cc:#: Failure Failed Expected failure #4, in TearDown. gtest_output_test_.cc:#: Failure Failed Expected failure #5, in the test fixture d'tor. [ FAILED ] NonFatalFailureInFixtureConstructorTest.FailureInConstructor [----------] 1 test from FatalFailureInFixtureConstructorTest [ RUN ] FatalFailureInFixtureConstructorTest.FailureInConstructor (expecting 2 failures) gtest_output_test_.cc:#: Failure Failed Expected failure #1, in the test fixture c'tor. gtest_output_test_.cc:#: Failure Failed Expected failure #2, in the test fixture d'tor. [ FAILED ] FatalFailureInFixtureConstructorTest.FailureInConstructor [----------] 1 test from NonFatalFailureInSetUpTest [ RUN ] NonFatalFailureInSetUpTest.FailureInSetUp (expecting 4 failures) gtest_output_test_.cc:#: Failure Failed Expected failure #1, in SetUp(). gtest_output_test_.cc:#: Failure Failed Expected failure #2, in the test function. gtest_output_test_.cc:#: Failure Failed Expected failure #3, in TearDown(). gtest_output_test_.cc:#: Failure Failed Expected failure #4, in the test fixture d'tor. [ FAILED ] NonFatalFailureInSetUpTest.FailureInSetUp [----------] 1 test from FatalFailureInSetUpTest [ RUN ] FatalFailureInSetUpTest.FailureInSetUp (expecting 3 failures) gtest_output_test_.cc:#: Failure Failed Expected failure #1, in SetUp(). gtest_output_test_.cc:#: Failure Failed Expected failure #2, in TearDown(). gtest_output_test_.cc:#: Failure Failed Expected failure #3, in the test fixture d'tor. [ FAILED ] FatalFailureInSetUpTest.FailureInSetUp [----------] 1 test from AddFailureAtTest [ RUN ] AddFailureAtTest.MessageContainsSpecifiedFileAndLineNumber foo.cc:42: Failure Failed Expected failure in foo.cc [ FAILED ] AddFailureAtTest.MessageContainsSpecifiedFileAndLineNumber [----------] 4 tests from MixedUpTestCaseTest [ RUN ] MixedUpTestCaseTest.FirstTestFromNamespaceFoo [ OK ] MixedUpTestCaseTest.FirstTestFromNamespaceFoo [ RUN ] MixedUpTestCaseTest.SecondTestFromNamespaceFoo [ OK ] MixedUpTestCaseTest.SecondTestFromNamespaceFoo [ RUN ] MixedUpTestCaseTest.ThisShouldFail gtest.cc:#: Failure Failed All tests in the same test case must use the same test fixture class. However, in test case MixedUpTestCaseTest, you defined test FirstTestFromNamespaceFoo and test ThisShouldFail using two different test fixture classes. This can happen if the two classes are from different namespaces or translation units and have the same name. You should probably rename one of the classes to put the tests into different test cases. [ FAILED ] MixedUpTestCaseTest.ThisShouldFail [ RUN ] MixedUpTestCaseTest.ThisShouldFailToo gtest.cc:#: Failure Failed All tests in the same test case must use the same test fixture class. However, in test case MixedUpTestCaseTest, you defined test FirstTestFromNamespaceFoo and test ThisShouldFailToo using two different test fixture classes. This can happen if the two classes are from different namespaces or translation units and have the same name. You should probably rename one of the classes to put the tests into different test cases. [ FAILED ] MixedUpTestCaseTest.ThisShouldFailToo [----------] 2 tests from MixedUpTestCaseWithSameTestNameTest [ RUN ] MixedUpTestCaseWithSameTestNameTest.TheSecondTestWithThisNameShouldFail [ OK ] MixedUpTestCaseWithSameTestNameTest.TheSecondTestWithThisNameShouldFail [ RUN ] MixedUpTestCaseWithSameTestNameTest.TheSecondTestWithThisNameShouldFail gtest.cc:#: Failure Failed All tests in the same test case must use the same test fixture class. However, in test case MixedUpTestCaseWithSameTestNameTest, you defined test TheSecondTestWithThisNameShouldFail and test TheSecondTestWithThisNameShouldFail using two different test fixture classes. This can happen if the two classes are from different namespaces or translation units and have the same name. You should probably rename one of the classes to put the tests into different test cases. [ FAILED ] MixedUpTestCaseWithSameTestNameTest.TheSecondTestWithThisNameShouldFail [----------] 2 tests from TEST_F_before_TEST_in_same_test_case [ RUN ] TEST_F_before_TEST_in_same_test_case.DefinedUsingTEST_F [ OK ] TEST_F_before_TEST_in_same_test_case.DefinedUsingTEST_F [ RUN ] TEST_F_before_TEST_in_same_test_case.DefinedUsingTESTAndShouldFail gtest.cc:#: Failure Failed All tests in the same test case must use the same test fixture class, so mixing TEST_F and TEST in the same test case is illegal. In test case TEST_F_before_TEST_in_same_test_case, test DefinedUsingTEST_F is defined using TEST_F but test DefinedUsingTESTAndShouldFail is defined using TEST. You probably want to change the TEST to TEST_F or move it to another test case. [ FAILED ] TEST_F_before_TEST_in_same_test_case.DefinedUsingTESTAndShouldFail [----------] 2 tests from TEST_before_TEST_F_in_same_test_case [ RUN ] TEST_before_TEST_F_in_same_test_case.DefinedUsingTEST [ OK ] TEST_before_TEST_F_in_same_test_case.DefinedUsingTEST [ RUN ] TEST_before_TEST_F_in_same_test_case.DefinedUsingTEST_FAndShouldFail gtest.cc:#: Failure Failed All tests in the same test case must use the same test fixture class, so mixing TEST_F and TEST in the same test case is illegal. In test case TEST_before_TEST_F_in_same_test_case, test DefinedUsingTEST_FAndShouldFail is defined using TEST_F but test DefinedUsingTEST is defined using TEST. You probably want to change the TEST to TEST_F or move it to another test case. [ FAILED ] TEST_before_TEST_F_in_same_test_case.DefinedUsingTEST_FAndShouldFail [----------] 8 tests from ExpectNonfatalFailureTest [ RUN ] ExpectNonfatalFailureTest.CanReferenceGlobalVariables [ OK ] ExpectNonfatalFailureTest.CanReferenceGlobalVariables [ RUN ] ExpectNonfatalFailureTest.CanReferenceLocalVariables [ OK ] ExpectNonfatalFailureTest.CanReferenceLocalVariables [ RUN ] ExpectNonfatalFailureTest.SucceedsWhenThereIsOneNonfatalFailure [ OK ] ExpectNonfatalFailureTest.SucceedsWhenThereIsOneNonfatalFailure [ RUN ] ExpectNonfatalFailureTest.FailsWhenThereIsNoNonfatalFailure (expecting a failure) gtest.cc:#: Failure Expected: 1 non-fatal failure Actual: 0 failures [ FAILED ] ExpectNonfatalFailureTest.FailsWhenThereIsNoNonfatalFailure [ RUN ] ExpectNonfatalFailureTest.FailsWhenThereAreTwoNonfatalFailures (expecting a failure) gtest.cc:#: Failure Expected: 1 non-fatal failure Actual: 2 failures gtest_output_test_.cc:#: Non-fatal failure: Failed Expected non-fatal failure 1. gtest_output_test_.cc:#: Non-fatal failure: Failed Expected non-fatal failure 2. [ FAILED ] ExpectNonfatalFailureTest.FailsWhenThereAreTwoNonfatalFailures [ RUN ] ExpectNonfatalFailureTest.FailsWhenThereIsOneFatalFailure (expecting a failure) gtest.cc:#: Failure Expected: 1 non-fatal failure Actual: gtest_output_test_.cc:#: Fatal failure: Failed Expected fatal failure. [ FAILED ] ExpectNonfatalFailureTest.FailsWhenThereIsOneFatalFailure [ RUN ] ExpectNonfatalFailureTest.FailsWhenStatementReturns (expecting a failure) gtest.cc:#: Failure Expected: 1 non-fatal failure Actual: 0 failures [ FAILED ] ExpectNonfatalFailureTest.FailsWhenStatementReturns [ RUN ] ExpectNonfatalFailureTest.FailsWhenStatementThrows (expecting a failure) gtest.cc:#: Failure Expected: 1 non-fatal failure Actual: 0 failures [ FAILED ] ExpectNonfatalFailureTest.FailsWhenStatementThrows [----------] 8 tests from ExpectFatalFailureTest [ RUN ] ExpectFatalFailureTest.CanReferenceGlobalVariables [ OK ] ExpectFatalFailureTest.CanReferenceGlobalVariables [ RUN ] ExpectFatalFailureTest.CanReferenceLocalStaticVariables [ OK ] ExpectFatalFailureTest.CanReferenceLocalStaticVariables [ RUN ] ExpectFatalFailureTest.SucceedsWhenThereIsOneFatalFailure [ OK ] ExpectFatalFailureTest.SucceedsWhenThereIsOneFatalFailure [ RUN ] ExpectFatalFailureTest.FailsWhenThereIsNoFatalFailure (expecting a failure) gtest.cc:#: Failure Expected: 1 fatal failure Actual: 0 failures [ FAILED ] ExpectFatalFailureTest.FailsWhenThereIsNoFatalFailure [ RUN ] ExpectFatalFailureTest.FailsWhenThereAreTwoFatalFailures (expecting a failure) gtest.cc:#: Failure Expected: 1 fatal failure Actual: 2 failures gtest_output_test_.cc:#: Fatal failure: Failed Expected fatal failure. gtest_output_test_.cc:#: Fatal failure: Failed Expected fatal failure. [ FAILED ] ExpectFatalFailureTest.FailsWhenThereAreTwoFatalFailures [ RUN ] ExpectFatalFailureTest.FailsWhenThereIsOneNonfatalFailure (expecting a failure) gtest.cc:#: Failure Expected: 1 fatal failure Actual: gtest_output_test_.cc:#: Non-fatal failure: Failed Expected non-fatal failure. [ FAILED ] ExpectFatalFailureTest.FailsWhenThereIsOneNonfatalFailure [ RUN ] ExpectFatalFailureTest.FailsWhenStatementReturns (expecting a failure) gtest.cc:#: Failure Expected: 1 fatal failure Actual: 0 failures [ FAILED ] ExpectFatalFailureTest.FailsWhenStatementReturns [ RUN ] ExpectFatalFailureTest.FailsWhenStatementThrows (expecting a failure) gtest.cc:#: Failure Expected: 1 fatal failure Actual: 0 failures [ FAILED ] ExpectFatalFailureTest.FailsWhenStatementThrows [----------] 2 tests from TypedTest/0, where TypeParam = int [ RUN ] TypedTest/0.Success [ OK ] TypedTest/0.Success [ RUN ] TypedTest/0.Failure gtest_output_test_.cc:#: Failure Value of: TypeParam() Actual: 0 Expected: 1 Expected failure [ FAILED ] TypedTest/0.Failure, where TypeParam = int [----------] 2 tests from Unsigned/TypedTestP/0, where TypeParam = unsigned char [ RUN ] Unsigned/TypedTestP/0.Success [ OK ] Unsigned/TypedTestP/0.Success [ RUN ] Unsigned/TypedTestP/0.Failure gtest_output_test_.cc:#: Failure Value of: TypeParam() Actual: '\0' Expected: 1U Which is: 1 Expected failure [ FAILED ] Unsigned/TypedTestP/0.Failure, where TypeParam = unsigned char [----------] 2 tests from Unsigned/TypedTestP/1, where TypeParam = unsigned int [ RUN ] Unsigned/TypedTestP/1.Success [ OK ] Unsigned/TypedTestP/1.Success [ RUN ] Unsigned/TypedTestP/1.Failure gtest_output_test_.cc:#: Failure Value of: TypeParam() Actual: 0 Expected: 1U Which is: 1 Expected failure [ FAILED ] Unsigned/TypedTestP/1.Failure, where TypeParam = unsigned int [----------] 4 tests from ExpectFailureTest [ RUN ] ExpectFailureTest.ExpectFatalFailure (expecting 1 failure) gtest.cc:#: Failure Expected: 1 fatal failure Actual: gtest_output_test_.cc:#: Success: Succeeded (expecting 1 failure) gtest.cc:#: Failure Expected: 1 fatal failure Actual: gtest_output_test_.cc:#: Non-fatal failure: Failed Expected non-fatal failure. (expecting 1 failure) gtest.cc:#: Failure Expected: 1 fatal failure containing "Some other fatal failure expected." Actual: gtest_output_test_.cc:#: Fatal failure: Failed Expected fatal failure. [ FAILED ] ExpectFailureTest.ExpectFatalFailure [ RUN ] ExpectFailureTest.ExpectNonFatalFailure (expecting 1 failure) gtest.cc:#: Failure Expected: 1 non-fatal failure Actual: gtest_output_test_.cc:#: Success: Succeeded (expecting 1 failure) gtest.cc:#: Failure Expected: 1 non-fatal failure Actual: gtest_output_test_.cc:#: Fatal failure: Failed Expected fatal failure. (expecting 1 failure) gtest.cc:#: Failure Expected: 1 non-fatal failure containing "Some other non-fatal failure." Actual: gtest_output_test_.cc:#: Non-fatal failure: Failed Expected non-fatal failure. [ FAILED ] ExpectFailureTest.ExpectNonFatalFailure [ RUN ] ExpectFailureTest.ExpectFatalFailureOnAllThreads (expecting 1 failure) gtest.cc:#: Failure Expected: 1 fatal failure Actual: gtest_output_test_.cc:#: Success: Succeeded (expecting 1 failure) gtest.cc:#: Failure Expected: 1 fatal failure Actual: gtest_output_test_.cc:#: Non-fatal failure: Failed Expected non-fatal failure. (expecting 1 failure) gtest.cc:#: Failure Expected: 1 fatal failure containing "Some other fatal failure expected." Actual: gtest_output_test_.cc:#: Fatal failure: Failed Expected fatal failure. [ FAILED ] ExpectFailureTest.ExpectFatalFailureOnAllThreads [ RUN ] ExpectFailureTest.ExpectNonFatalFailureOnAllThreads (expecting 1 failure) gtest.cc:#: Failure Expected: 1 non-fatal failure Actual: gtest_output_test_.cc:#: Success: Succeeded (expecting 1 failure) gtest.cc:#: Failure Expected: 1 non-fatal failure Actual: gtest_output_test_.cc:#: Fatal failure: Failed Expected fatal failure. (expecting 1 failure) gtest.cc:#: Failure Expected: 1 non-fatal failure containing "Some other non-fatal failure." Actual: gtest_output_test_.cc:#: Non-fatal failure: Failed Expected non-fatal failure. [ FAILED ] ExpectFailureTest.ExpectNonFatalFailureOnAllThreads [----------] 2 tests from ExpectFailureWithThreadsTest [ RUN ] ExpectFailureWithThreadsTest.ExpectFatalFailure (expecting 2 failures) gtest_output_test_.cc:#: Failure Failed Expected fatal failure. gtest.cc:#: Failure Expected: 1 fatal failure Actual: 0 failures [ FAILED ] ExpectFailureWithThreadsTest.ExpectFatalFailure [ RUN ] ExpectFailureWithThreadsTest.ExpectNonFatalFailure (expecting 2 failures) gtest_output_test_.cc:#: Failure Failed Expected non-fatal failure. gtest.cc:#: Failure Expected: 1 non-fatal failure Actual: 0 failures [ FAILED ] ExpectFailureWithThreadsTest.ExpectNonFatalFailure [----------] 1 test from ScopedFakeTestPartResultReporterTest [ RUN ] ScopedFakeTestPartResultReporterTest.InterceptOnlyCurrentThread (expecting 2 failures) gtest_output_test_.cc:#: Failure Failed Expected fatal failure. gtest_output_test_.cc:#: Failure Failed Expected non-fatal failure. [ FAILED ] ScopedFakeTestPartResultReporterTest.InterceptOnlyCurrentThread [----------] 1 test from PrintingFailingParams/FailingParamTest [ RUN ] PrintingFailingParams/FailingParamTest.Fails/0 gtest_output_test_.cc:#: Failure Value of: GetParam() Actual: 2 Expected: 1 [ FAILED ] PrintingFailingParams/FailingParamTest.Fails/0, where GetParam() = 2 [----------] Global test environment tear-down BarEnvironment::TearDown() called. gtest_output_test_.cc:#: Failure Failed Expected non-fatal failure. FooEnvironment::TearDown() called. gtest_output_test_.cc:#: Failure Failed Expected fatal failure. [==========] 63 tests from 28 test cases ran. [ PASSED ] 21 tests. [ FAILED ] 42 tests, listed below: [ FAILED ] NonfatalFailureTest.EscapesStringOperands [ FAILED ] FatalFailureTest.FatalFailureInSubroutine [ FAILED ] FatalFailureTest.FatalFailureInNestedSubroutine [ FAILED ] FatalFailureTest.NonfatalFailureInSubroutine [ FAILED ] LoggingTest.InterleavingLoggingAndAssertions [ FAILED ] SCOPED_TRACETest.ObeysScopes [ FAILED ] SCOPED_TRACETest.WorksInLoop [ FAILED ] SCOPED_TRACETest.WorksInSubroutine [ FAILED ] SCOPED_TRACETest.CanBeNested [ FAILED ] SCOPED_TRACETest.CanBeRepeated [ FAILED ] SCOPED_TRACETest.WorksConcurrently [ FAILED ] NonFatalFailureInFixtureConstructorTest.FailureInConstructor [ FAILED ] FatalFailureInFixtureConstructorTest.FailureInConstructor [ FAILED ] NonFatalFailureInSetUpTest.FailureInSetUp [ FAILED ] FatalFailureInSetUpTest.FailureInSetUp [ FAILED ] AddFailureAtTest.MessageContainsSpecifiedFileAndLineNumber [ FAILED ] MixedUpTestCaseTest.ThisShouldFail [ FAILED ] MixedUpTestCaseTest.ThisShouldFailToo [ FAILED ] MixedUpTestCaseWithSameTestNameTest.TheSecondTestWithThisNameShouldFail [ FAILED ] TEST_F_before_TEST_in_same_test_case.DefinedUsingTESTAndShouldFail [ FAILED ] TEST_before_TEST_F_in_same_test_case.DefinedUsingTEST_FAndShouldFail [ FAILED ] ExpectNonfatalFailureTest.FailsWhenThereIsNoNonfatalFailure [ FAILED ] ExpectNonfatalFailureTest.FailsWhenThereAreTwoNonfatalFailures [ FAILED ] ExpectNonfatalFailureTest.FailsWhenThereIsOneFatalFailure [ FAILED ] ExpectNonfatalFailureTest.FailsWhenStatementReturns [ FAILED ] ExpectNonfatalFailureTest.FailsWhenStatementThrows [ FAILED ] ExpectFatalFailureTest.FailsWhenThereIsNoFatalFailure [ FAILED ] ExpectFatalFailureTest.FailsWhenThereAreTwoFatalFailures [ FAILED ] ExpectFatalFailureTest.FailsWhenThereIsOneNonfatalFailure [ FAILED ] ExpectFatalFailureTest.FailsWhenStatementReturns [ FAILED ] ExpectFatalFailureTest.FailsWhenStatementThrows [ FAILED ] TypedTest/0.Failure, where TypeParam = int [ FAILED ] Unsigned/TypedTestP/0.Failure, where TypeParam = unsigned char [ FAILED ] Unsigned/TypedTestP/1.Failure, where TypeParam = unsigned int [ FAILED ] ExpectFailureTest.ExpectFatalFailure [ FAILED ] ExpectFailureTest.ExpectNonFatalFailure [ FAILED ] ExpectFailureTest.ExpectFatalFailureOnAllThreads [ FAILED ] ExpectFailureTest.ExpectNonFatalFailureOnAllThreads [ FAILED ] ExpectFailureWithThreadsTest.ExpectFatalFailure [ FAILED ] ExpectFailureWithThreadsTest.ExpectNonFatalFailure [ FAILED ] ScopedFakeTestPartResultReporterTest.InterceptOnlyCurrentThread [ FAILED ] PrintingFailingParams/FailingParamTest.Fails/0, where GetParam() = 2 42 FAILED TESTS  YOU HAVE 1 DISABLED TEST Note: Google Test filter = FatalFailureTest.*:LoggingTest.* [==========] Running 4 tests from 2 test cases. [----------] Global test environment set-up. [----------] 3 tests from FatalFailureTest [ RUN ] FatalFailureTest.FatalFailureInSubroutine (expecting a failure that x should be 1) gtest_output_test_.cc:#: Failure Value of: x Actual: 2 Expected: 1 [ FAILED ] FatalFailureTest.FatalFailureInSubroutine (? ms) [ RUN ] FatalFailureTest.FatalFailureInNestedSubroutine (expecting a failure that x should be 1) gtest_output_test_.cc:#: Failure Value of: x Actual: 2 Expected: 1 [ FAILED ] FatalFailureTest.FatalFailureInNestedSubroutine (? ms) [ RUN ] FatalFailureTest.NonfatalFailureInSubroutine (expecting a failure on false) gtest_output_test_.cc:#: Failure Value of: false Actual: false Expected: true [ FAILED ] FatalFailureTest.NonfatalFailureInSubroutine (? ms) [----------] 3 tests from FatalFailureTest (? ms total) [----------] 1 test from LoggingTest [ RUN ] LoggingTest.InterleavingLoggingAndAssertions (expecting 2 failures on (3) >= (a[i])) i == 0 i == 1 gtest_output_test_.cc:#: Failure Expected: (3) >= (a[i]), actual: 3 vs 9 i == 2 i == 3 gtest_output_test_.cc:#: Failure Expected: (3) >= (a[i]), actual: 3 vs 6 [ FAILED ] LoggingTest.InterleavingLoggingAndAssertions (? ms) [----------] 1 test from LoggingTest (? ms total) [----------] Global test environment tear-down [==========] 4 tests from 2 test cases ran. (? ms total) [ PASSED ] 0 tests. [ FAILED ] 4 tests, listed below: [ FAILED ] FatalFailureTest.FatalFailureInSubroutine [ FAILED ] FatalFailureTest.FatalFailureInNestedSubroutine [ FAILED ] FatalFailureTest.NonfatalFailureInSubroutine [ FAILED ] LoggingTest.InterleavingLoggingAndAssertions 4 FAILED TESTS Note: Google Test filter = *DISABLED_* [==========] Running 1 test from 1 test case. [----------] Global test environment set-up. [----------] 1 test from DisabledTestsWarningTest [ RUN ] DisabledTestsWarningTest.DISABLED_AlsoRunDisabledTestsFlagSuppressesWarning [ OK ] DisabledTestsWarningTest.DISABLED_AlsoRunDisabledTestsFlagSuppressesWarning [----------] Global test environment tear-down [==========] 1 test from 1 test case ran. [ PASSED ] 1 test. Note: Google Test filter = PassingTest.* Note: This is test shard 2 of 2. [==========] Running 1 test from 1 test case. [----------] Global test environment set-up. [----------] 1 test from PassingTest [ RUN ] PassingTest.PassingTest2 [ OK ] PassingTest.PassingTest2 [----------] Global test environment tear-down [==========] 1 test from 1 test case ran. [ PASSED ] 1 test. dlt-daemon-2.18.4/gtest-1.7.0/test/gtest_pred_impl_unittest.cc000066400000000000000000002271021353342203500240330ustar00rootroot00000000000000// Copyright 2006, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // This file is AUTOMATICALLY GENERATED on 10/31/2011 by command // 'gen_gtest_pred_impl.py 5'. DO NOT EDIT BY HAND! // Regression test for gtest_pred_impl.h // // This file is generated by a script and quite long. If you intend to // learn how Google Test works by reading its unit tests, read // gtest_unittest.cc instead. // // This is intended as a regression test for the Google Test predicate // assertions. We compile it as part of the gtest_unittest target // only to keep the implementation tidy and compact, as it is quite // involved to set up the stage for testing Google Test using Google // Test itself. // // Currently, gtest_unittest takes ~11 seconds to run in the testing // daemon. In the future, if it grows too large and needs much more // time to finish, we should consider separating this file into a // stand-alone regression test. #include #include "gtest/gtest.h" #include "gtest/gtest-spi.h" // A user-defined data type. struct Bool { explicit Bool(int val) : value(val != 0) {} bool operator>(int n) const { return value > Bool(n).value; } Bool operator+(const Bool& rhs) const { return Bool(value + rhs.value); } bool operator==(const Bool& rhs) const { return value == rhs.value; } bool value; }; // Enables Bool to be used in assertions. std::ostream& operator<<(std::ostream& os, const Bool& x) { return os << (x.value ? "true" : "false"); } // Sample functions/functors for testing unary predicate assertions. // A unary predicate function. template bool PredFunction1(T1 v1) { return v1 > 0; } // The following two functions are needed to circumvent a bug in // gcc 2.95.3, which sometimes has problem with the above template // function. bool PredFunction1Int(int v1) { return v1 > 0; } bool PredFunction1Bool(Bool v1) { return v1 > 0; } // A unary predicate functor. struct PredFunctor1 { template bool operator()(const T1& v1) { return v1 > 0; } }; // A unary predicate-formatter function. template testing::AssertionResult PredFormatFunction1(const char* e1, const T1& v1) { if (PredFunction1(v1)) return testing::AssertionSuccess(); return testing::AssertionFailure() << e1 << " is expected to be positive, but evaluates to " << v1 << "."; } // A unary predicate-formatter functor. struct PredFormatFunctor1 { template testing::AssertionResult operator()(const char* e1, const T1& v1) const { return PredFormatFunction1(e1, v1); } }; // Tests for {EXPECT|ASSERT}_PRED_FORMAT1. class Predicate1Test : public testing::Test { protected: virtual void SetUp() { expected_to_finish_ = true; finished_ = false; n1_ = 0; } virtual void TearDown() { // Verifies that each of the predicate's arguments was evaluated // exactly once. EXPECT_EQ(1, n1_) << "The predicate assertion didn't evaluate argument 2 " "exactly once."; // Verifies that the control flow in the test function is expected. if (expected_to_finish_ && !finished_) { FAIL() << "The predicate assertion unexpactedly aborted the test."; } else if (!expected_to_finish_ && finished_) { FAIL() << "The failed predicate assertion didn't abort the test " "as expected."; } } // true iff the test function is expected to run to finish. static bool expected_to_finish_; // true iff the test function did run to finish. static bool finished_; static int n1_; }; bool Predicate1Test::expected_to_finish_; bool Predicate1Test::finished_; int Predicate1Test::n1_; typedef Predicate1Test EXPECT_PRED_FORMAT1Test; typedef Predicate1Test ASSERT_PRED_FORMAT1Test; typedef Predicate1Test EXPECT_PRED1Test; typedef Predicate1Test ASSERT_PRED1Test; // Tests a successful EXPECT_PRED1 where the // predicate-formatter is a function on a built-in type (int). TEST_F(EXPECT_PRED1Test, FunctionOnBuiltInTypeSuccess) { EXPECT_PRED1(PredFunction1Int, ++n1_); finished_ = true; } // Tests a successful EXPECT_PRED1 where the // predicate-formatter is a function on a user-defined type (Bool). TEST_F(EXPECT_PRED1Test, FunctionOnUserTypeSuccess) { EXPECT_PRED1(PredFunction1Bool, Bool(++n1_)); finished_ = true; } // Tests a successful EXPECT_PRED1 where the // predicate-formatter is a functor on a built-in type (int). TEST_F(EXPECT_PRED1Test, FunctorOnBuiltInTypeSuccess) { EXPECT_PRED1(PredFunctor1(), ++n1_); finished_ = true; } // Tests a successful EXPECT_PRED1 where the // predicate-formatter is a functor on a user-defined type (Bool). TEST_F(EXPECT_PRED1Test, FunctorOnUserTypeSuccess) { EXPECT_PRED1(PredFunctor1(), Bool(++n1_)); finished_ = true; } // Tests a failed EXPECT_PRED1 where the // predicate-formatter is a function on a built-in type (int). TEST_F(EXPECT_PRED1Test, FunctionOnBuiltInTypeFailure) { EXPECT_NONFATAL_FAILURE({ // NOLINT EXPECT_PRED1(PredFunction1Int, n1_++); finished_ = true; }, ""); } // Tests a failed EXPECT_PRED1 where the // predicate-formatter is a function on a user-defined type (Bool). TEST_F(EXPECT_PRED1Test, FunctionOnUserTypeFailure) { EXPECT_NONFATAL_FAILURE({ // NOLINT EXPECT_PRED1(PredFunction1Bool, Bool(n1_++)); finished_ = true; }, ""); } // Tests a failed EXPECT_PRED1 where the // predicate-formatter is a functor on a built-in type (int). TEST_F(EXPECT_PRED1Test, FunctorOnBuiltInTypeFailure) { EXPECT_NONFATAL_FAILURE({ // NOLINT EXPECT_PRED1(PredFunctor1(), n1_++); finished_ = true; }, ""); } // Tests a failed EXPECT_PRED1 where the // predicate-formatter is a functor on a user-defined type (Bool). TEST_F(EXPECT_PRED1Test, FunctorOnUserTypeFailure) { EXPECT_NONFATAL_FAILURE({ // NOLINT EXPECT_PRED1(PredFunctor1(), Bool(n1_++)); finished_ = true; }, ""); } // Tests a successful ASSERT_PRED1 where the // predicate-formatter is a function on a built-in type (int). TEST_F(ASSERT_PRED1Test, FunctionOnBuiltInTypeSuccess) { ASSERT_PRED1(PredFunction1Int, ++n1_); finished_ = true; } // Tests a successful ASSERT_PRED1 where the // predicate-formatter is a function on a user-defined type (Bool). TEST_F(ASSERT_PRED1Test, FunctionOnUserTypeSuccess) { ASSERT_PRED1(PredFunction1Bool, Bool(++n1_)); finished_ = true; } // Tests a successful ASSERT_PRED1 where the // predicate-formatter is a functor on a built-in type (int). TEST_F(ASSERT_PRED1Test, FunctorOnBuiltInTypeSuccess) { ASSERT_PRED1(PredFunctor1(), ++n1_); finished_ = true; } // Tests a successful ASSERT_PRED1 where the // predicate-formatter is a functor on a user-defined type (Bool). TEST_F(ASSERT_PRED1Test, FunctorOnUserTypeSuccess) { ASSERT_PRED1(PredFunctor1(), Bool(++n1_)); finished_ = true; } // Tests a failed ASSERT_PRED1 where the // predicate-formatter is a function on a built-in type (int). TEST_F(ASSERT_PRED1Test, FunctionOnBuiltInTypeFailure) { expected_to_finish_ = false; EXPECT_FATAL_FAILURE({ // NOLINT ASSERT_PRED1(PredFunction1Int, n1_++); finished_ = true; }, ""); } // Tests a failed ASSERT_PRED1 where the // predicate-formatter is a function on a user-defined type (Bool). TEST_F(ASSERT_PRED1Test, FunctionOnUserTypeFailure) { expected_to_finish_ = false; EXPECT_FATAL_FAILURE({ // NOLINT ASSERT_PRED1(PredFunction1Bool, Bool(n1_++)); finished_ = true; }, ""); } // Tests a failed ASSERT_PRED1 where the // predicate-formatter is a functor on a built-in type (int). TEST_F(ASSERT_PRED1Test, FunctorOnBuiltInTypeFailure) { expected_to_finish_ = false; EXPECT_FATAL_FAILURE({ // NOLINT ASSERT_PRED1(PredFunctor1(), n1_++); finished_ = true; }, ""); } // Tests a failed ASSERT_PRED1 where the // predicate-formatter is a functor on a user-defined type (Bool). TEST_F(ASSERT_PRED1Test, FunctorOnUserTypeFailure) { expected_to_finish_ = false; EXPECT_FATAL_FAILURE({ // NOLINT ASSERT_PRED1(PredFunctor1(), Bool(n1_++)); finished_ = true; }, ""); } // Tests a successful EXPECT_PRED_FORMAT1 where the // predicate-formatter is a function on a built-in type (int). TEST_F(EXPECT_PRED_FORMAT1Test, FunctionOnBuiltInTypeSuccess) { EXPECT_PRED_FORMAT1(PredFormatFunction1, ++n1_); finished_ = true; } // Tests a successful EXPECT_PRED_FORMAT1 where the // predicate-formatter is a function on a user-defined type (Bool). TEST_F(EXPECT_PRED_FORMAT1Test, FunctionOnUserTypeSuccess) { EXPECT_PRED_FORMAT1(PredFormatFunction1, Bool(++n1_)); finished_ = true; } // Tests a successful EXPECT_PRED_FORMAT1 where the // predicate-formatter is a functor on a built-in type (int). TEST_F(EXPECT_PRED_FORMAT1Test, FunctorOnBuiltInTypeSuccess) { EXPECT_PRED_FORMAT1(PredFormatFunctor1(), ++n1_); finished_ = true; } // Tests a successful EXPECT_PRED_FORMAT1 where the // predicate-formatter is a functor on a user-defined type (Bool). TEST_F(EXPECT_PRED_FORMAT1Test, FunctorOnUserTypeSuccess) { EXPECT_PRED_FORMAT1(PredFormatFunctor1(), Bool(++n1_)); finished_ = true; } // Tests a failed EXPECT_PRED_FORMAT1 where the // predicate-formatter is a function on a built-in type (int). TEST_F(EXPECT_PRED_FORMAT1Test, FunctionOnBuiltInTypeFailure) { EXPECT_NONFATAL_FAILURE({ // NOLINT EXPECT_PRED_FORMAT1(PredFormatFunction1, n1_++); finished_ = true; }, ""); } // Tests a failed EXPECT_PRED_FORMAT1 where the // predicate-formatter is a function on a user-defined type (Bool). TEST_F(EXPECT_PRED_FORMAT1Test, FunctionOnUserTypeFailure) { EXPECT_NONFATAL_FAILURE({ // NOLINT EXPECT_PRED_FORMAT1(PredFormatFunction1, Bool(n1_++)); finished_ = true; }, ""); } // Tests a failed EXPECT_PRED_FORMAT1 where the // predicate-formatter is a functor on a built-in type (int). TEST_F(EXPECT_PRED_FORMAT1Test, FunctorOnBuiltInTypeFailure) { EXPECT_NONFATAL_FAILURE({ // NOLINT EXPECT_PRED_FORMAT1(PredFormatFunctor1(), n1_++); finished_ = true; }, ""); } // Tests a failed EXPECT_PRED_FORMAT1 where the // predicate-formatter is a functor on a user-defined type (Bool). TEST_F(EXPECT_PRED_FORMAT1Test, FunctorOnUserTypeFailure) { EXPECT_NONFATAL_FAILURE({ // NOLINT EXPECT_PRED_FORMAT1(PredFormatFunctor1(), Bool(n1_++)); finished_ = true; }, ""); } // Tests a successful ASSERT_PRED_FORMAT1 where the // predicate-formatter is a function on a built-in type (int). TEST_F(ASSERT_PRED_FORMAT1Test, FunctionOnBuiltInTypeSuccess) { ASSERT_PRED_FORMAT1(PredFormatFunction1, ++n1_); finished_ = true; } // Tests a successful ASSERT_PRED_FORMAT1 where the // predicate-formatter is a function on a user-defined type (Bool). TEST_F(ASSERT_PRED_FORMAT1Test, FunctionOnUserTypeSuccess) { ASSERT_PRED_FORMAT1(PredFormatFunction1, Bool(++n1_)); finished_ = true; } // Tests a successful ASSERT_PRED_FORMAT1 where the // predicate-formatter is a functor on a built-in type (int). TEST_F(ASSERT_PRED_FORMAT1Test, FunctorOnBuiltInTypeSuccess) { ASSERT_PRED_FORMAT1(PredFormatFunctor1(), ++n1_); finished_ = true; } // Tests a successful ASSERT_PRED_FORMAT1 where the // predicate-formatter is a functor on a user-defined type (Bool). TEST_F(ASSERT_PRED_FORMAT1Test, FunctorOnUserTypeSuccess) { ASSERT_PRED_FORMAT1(PredFormatFunctor1(), Bool(++n1_)); finished_ = true; } // Tests a failed ASSERT_PRED_FORMAT1 where the // predicate-formatter is a function on a built-in type (int). TEST_F(ASSERT_PRED_FORMAT1Test, FunctionOnBuiltInTypeFailure) { expected_to_finish_ = false; EXPECT_FATAL_FAILURE({ // NOLINT ASSERT_PRED_FORMAT1(PredFormatFunction1, n1_++); finished_ = true; }, ""); } // Tests a failed ASSERT_PRED_FORMAT1 where the // predicate-formatter is a function on a user-defined type (Bool). TEST_F(ASSERT_PRED_FORMAT1Test, FunctionOnUserTypeFailure) { expected_to_finish_ = false; EXPECT_FATAL_FAILURE({ // NOLINT ASSERT_PRED_FORMAT1(PredFormatFunction1, Bool(n1_++)); finished_ = true; }, ""); } // Tests a failed ASSERT_PRED_FORMAT1 where the // predicate-formatter is a functor on a built-in type (int). TEST_F(ASSERT_PRED_FORMAT1Test, FunctorOnBuiltInTypeFailure) { expected_to_finish_ = false; EXPECT_FATAL_FAILURE({ // NOLINT ASSERT_PRED_FORMAT1(PredFormatFunctor1(), n1_++); finished_ = true; }, ""); } // Tests a failed ASSERT_PRED_FORMAT1 where the // predicate-formatter is a functor on a user-defined type (Bool). TEST_F(ASSERT_PRED_FORMAT1Test, FunctorOnUserTypeFailure) { expected_to_finish_ = false; EXPECT_FATAL_FAILURE({ // NOLINT ASSERT_PRED_FORMAT1(PredFormatFunctor1(), Bool(n1_++)); finished_ = true; }, ""); } // Sample functions/functors for testing binary predicate assertions. // A binary predicate function. template bool PredFunction2(T1 v1, T2 v2) { return v1 + v2 > 0; } // The following two functions are needed to circumvent a bug in // gcc 2.95.3, which sometimes has problem with the above template // function. bool PredFunction2Int(int v1, int v2) { return v1 + v2 > 0; } bool PredFunction2Bool(Bool v1, Bool v2) { return v1 + v2 > 0; } // A binary predicate functor. struct PredFunctor2 { template bool operator()(const T1& v1, const T2& v2) { return v1 + v2 > 0; } }; // A binary predicate-formatter function. template testing::AssertionResult PredFormatFunction2(const char* e1, const char* e2, const T1& v1, const T2& v2) { if (PredFunction2(v1, v2)) return testing::AssertionSuccess(); return testing::AssertionFailure() << e1 << " + " << e2 << " is expected to be positive, but evaluates to " << v1 + v2 << "."; } // A binary predicate-formatter functor. struct PredFormatFunctor2 { template testing::AssertionResult operator()(const char* e1, const char* e2, const T1& v1, const T2& v2) const { return PredFormatFunction2(e1, e2, v1, v2); } }; // Tests for {EXPECT|ASSERT}_PRED_FORMAT2. class Predicate2Test : public testing::Test { protected: virtual void SetUp() { expected_to_finish_ = true; finished_ = false; n1_ = n2_ = 0; } virtual void TearDown() { // Verifies that each of the predicate's arguments was evaluated // exactly once. EXPECT_EQ(1, n1_) << "The predicate assertion didn't evaluate argument 2 " "exactly once."; EXPECT_EQ(1, n2_) << "The predicate assertion didn't evaluate argument 3 " "exactly once."; // Verifies that the control flow in the test function is expected. if (expected_to_finish_ && !finished_) { FAIL() << "The predicate assertion unexpactedly aborted the test."; } else if (!expected_to_finish_ && finished_) { FAIL() << "The failed predicate assertion didn't abort the test " "as expected."; } } // true iff the test function is expected to run to finish. static bool expected_to_finish_; // true iff the test function did run to finish. static bool finished_; static int n1_; static int n2_; }; bool Predicate2Test::expected_to_finish_; bool Predicate2Test::finished_; int Predicate2Test::n1_; int Predicate2Test::n2_; typedef Predicate2Test EXPECT_PRED_FORMAT2Test; typedef Predicate2Test ASSERT_PRED_FORMAT2Test; typedef Predicate2Test EXPECT_PRED2Test; typedef Predicate2Test ASSERT_PRED2Test; // Tests a successful EXPECT_PRED2 where the // predicate-formatter is a function on a built-in type (int). TEST_F(EXPECT_PRED2Test, FunctionOnBuiltInTypeSuccess) { EXPECT_PRED2(PredFunction2Int, ++n1_, ++n2_); finished_ = true; } // Tests a successful EXPECT_PRED2 where the // predicate-formatter is a function on a user-defined type (Bool). TEST_F(EXPECT_PRED2Test, FunctionOnUserTypeSuccess) { EXPECT_PRED2(PredFunction2Bool, Bool(++n1_), Bool(++n2_)); finished_ = true; } // Tests a successful EXPECT_PRED2 where the // predicate-formatter is a functor on a built-in type (int). TEST_F(EXPECT_PRED2Test, FunctorOnBuiltInTypeSuccess) { EXPECT_PRED2(PredFunctor2(), ++n1_, ++n2_); finished_ = true; } // Tests a successful EXPECT_PRED2 where the // predicate-formatter is a functor on a user-defined type (Bool). TEST_F(EXPECT_PRED2Test, FunctorOnUserTypeSuccess) { EXPECT_PRED2(PredFunctor2(), Bool(++n1_), Bool(++n2_)); finished_ = true; } // Tests a failed EXPECT_PRED2 where the // predicate-formatter is a function on a built-in type (int). TEST_F(EXPECT_PRED2Test, FunctionOnBuiltInTypeFailure) { EXPECT_NONFATAL_FAILURE({ // NOLINT EXPECT_PRED2(PredFunction2Int, n1_++, n2_++); finished_ = true; }, ""); } // Tests a failed EXPECT_PRED2 where the // predicate-formatter is a function on a user-defined type (Bool). TEST_F(EXPECT_PRED2Test, FunctionOnUserTypeFailure) { EXPECT_NONFATAL_FAILURE({ // NOLINT EXPECT_PRED2(PredFunction2Bool, Bool(n1_++), Bool(n2_++)); finished_ = true; }, ""); } // Tests a failed EXPECT_PRED2 where the // predicate-formatter is a functor on a built-in type (int). TEST_F(EXPECT_PRED2Test, FunctorOnBuiltInTypeFailure) { EXPECT_NONFATAL_FAILURE({ // NOLINT EXPECT_PRED2(PredFunctor2(), n1_++, n2_++); finished_ = true; }, ""); } // Tests a failed EXPECT_PRED2 where the // predicate-formatter is a functor on a user-defined type (Bool). TEST_F(EXPECT_PRED2Test, FunctorOnUserTypeFailure) { EXPECT_NONFATAL_FAILURE({ // NOLINT EXPECT_PRED2(PredFunctor2(), Bool(n1_++), Bool(n2_++)); finished_ = true; }, ""); } // Tests a successful ASSERT_PRED2 where the // predicate-formatter is a function on a built-in type (int). TEST_F(ASSERT_PRED2Test, FunctionOnBuiltInTypeSuccess) { ASSERT_PRED2(PredFunction2Int, ++n1_, ++n2_); finished_ = true; } // Tests a successful ASSERT_PRED2 where the // predicate-formatter is a function on a user-defined type (Bool). TEST_F(ASSERT_PRED2Test, FunctionOnUserTypeSuccess) { ASSERT_PRED2(PredFunction2Bool, Bool(++n1_), Bool(++n2_)); finished_ = true; } // Tests a successful ASSERT_PRED2 where the // predicate-formatter is a functor on a built-in type (int). TEST_F(ASSERT_PRED2Test, FunctorOnBuiltInTypeSuccess) { ASSERT_PRED2(PredFunctor2(), ++n1_, ++n2_); finished_ = true; } // Tests a successful ASSERT_PRED2 where the // predicate-formatter is a functor on a user-defined type (Bool). TEST_F(ASSERT_PRED2Test, FunctorOnUserTypeSuccess) { ASSERT_PRED2(PredFunctor2(), Bool(++n1_), Bool(++n2_)); finished_ = true; } // Tests a failed ASSERT_PRED2 where the // predicate-formatter is a function on a built-in type (int). TEST_F(ASSERT_PRED2Test, FunctionOnBuiltInTypeFailure) { expected_to_finish_ = false; EXPECT_FATAL_FAILURE({ // NOLINT ASSERT_PRED2(PredFunction2Int, n1_++, n2_++); finished_ = true; }, ""); } // Tests a failed ASSERT_PRED2 where the // predicate-formatter is a function on a user-defined type (Bool). TEST_F(ASSERT_PRED2Test, FunctionOnUserTypeFailure) { expected_to_finish_ = false; EXPECT_FATAL_FAILURE({ // NOLINT ASSERT_PRED2(PredFunction2Bool, Bool(n1_++), Bool(n2_++)); finished_ = true; }, ""); } // Tests a failed ASSERT_PRED2 where the // predicate-formatter is a functor on a built-in type (int). TEST_F(ASSERT_PRED2Test, FunctorOnBuiltInTypeFailure) { expected_to_finish_ = false; EXPECT_FATAL_FAILURE({ // NOLINT ASSERT_PRED2(PredFunctor2(), n1_++, n2_++); finished_ = true; }, ""); } // Tests a failed ASSERT_PRED2 where the // predicate-formatter is a functor on a user-defined type (Bool). TEST_F(ASSERT_PRED2Test, FunctorOnUserTypeFailure) { expected_to_finish_ = false; EXPECT_FATAL_FAILURE({ // NOLINT ASSERT_PRED2(PredFunctor2(), Bool(n1_++), Bool(n2_++)); finished_ = true; }, ""); } // Tests a successful EXPECT_PRED_FORMAT2 where the // predicate-formatter is a function on a built-in type (int). TEST_F(EXPECT_PRED_FORMAT2Test, FunctionOnBuiltInTypeSuccess) { EXPECT_PRED_FORMAT2(PredFormatFunction2, ++n1_, ++n2_); finished_ = true; } // Tests a successful EXPECT_PRED_FORMAT2 where the // predicate-formatter is a function on a user-defined type (Bool). TEST_F(EXPECT_PRED_FORMAT2Test, FunctionOnUserTypeSuccess) { EXPECT_PRED_FORMAT2(PredFormatFunction2, Bool(++n1_), Bool(++n2_)); finished_ = true; } // Tests a successful EXPECT_PRED_FORMAT2 where the // predicate-formatter is a functor on a built-in type (int). TEST_F(EXPECT_PRED_FORMAT2Test, FunctorOnBuiltInTypeSuccess) { EXPECT_PRED_FORMAT2(PredFormatFunctor2(), ++n1_, ++n2_); finished_ = true; } // Tests a successful EXPECT_PRED_FORMAT2 where the // predicate-formatter is a functor on a user-defined type (Bool). TEST_F(EXPECT_PRED_FORMAT2Test, FunctorOnUserTypeSuccess) { EXPECT_PRED_FORMAT2(PredFormatFunctor2(), Bool(++n1_), Bool(++n2_)); finished_ = true; } // Tests a failed EXPECT_PRED_FORMAT2 where the // predicate-formatter is a function on a built-in type (int). TEST_F(EXPECT_PRED_FORMAT2Test, FunctionOnBuiltInTypeFailure) { EXPECT_NONFATAL_FAILURE({ // NOLINT EXPECT_PRED_FORMAT2(PredFormatFunction2, n1_++, n2_++); finished_ = true; }, ""); } // Tests a failed EXPECT_PRED_FORMAT2 where the // predicate-formatter is a function on a user-defined type (Bool). TEST_F(EXPECT_PRED_FORMAT2Test, FunctionOnUserTypeFailure) { EXPECT_NONFATAL_FAILURE({ // NOLINT EXPECT_PRED_FORMAT2(PredFormatFunction2, Bool(n1_++), Bool(n2_++)); finished_ = true; }, ""); } // Tests a failed EXPECT_PRED_FORMAT2 where the // predicate-formatter is a functor on a built-in type (int). TEST_F(EXPECT_PRED_FORMAT2Test, FunctorOnBuiltInTypeFailure) { EXPECT_NONFATAL_FAILURE({ // NOLINT EXPECT_PRED_FORMAT2(PredFormatFunctor2(), n1_++, n2_++); finished_ = true; }, ""); } // Tests a failed EXPECT_PRED_FORMAT2 where the // predicate-formatter is a functor on a user-defined type (Bool). TEST_F(EXPECT_PRED_FORMAT2Test, FunctorOnUserTypeFailure) { EXPECT_NONFATAL_FAILURE({ // NOLINT EXPECT_PRED_FORMAT2(PredFormatFunctor2(), Bool(n1_++), Bool(n2_++)); finished_ = true; }, ""); } // Tests a successful ASSERT_PRED_FORMAT2 where the // predicate-formatter is a function on a built-in type (int). TEST_F(ASSERT_PRED_FORMAT2Test, FunctionOnBuiltInTypeSuccess) { ASSERT_PRED_FORMAT2(PredFormatFunction2, ++n1_, ++n2_); finished_ = true; } // Tests a successful ASSERT_PRED_FORMAT2 where the // predicate-formatter is a function on a user-defined type (Bool). TEST_F(ASSERT_PRED_FORMAT2Test, FunctionOnUserTypeSuccess) { ASSERT_PRED_FORMAT2(PredFormatFunction2, Bool(++n1_), Bool(++n2_)); finished_ = true; } // Tests a successful ASSERT_PRED_FORMAT2 where the // predicate-formatter is a functor on a built-in type (int). TEST_F(ASSERT_PRED_FORMAT2Test, FunctorOnBuiltInTypeSuccess) { ASSERT_PRED_FORMAT2(PredFormatFunctor2(), ++n1_, ++n2_); finished_ = true; } // Tests a successful ASSERT_PRED_FORMAT2 where the // predicate-formatter is a functor on a user-defined type (Bool). TEST_F(ASSERT_PRED_FORMAT2Test, FunctorOnUserTypeSuccess) { ASSERT_PRED_FORMAT2(PredFormatFunctor2(), Bool(++n1_), Bool(++n2_)); finished_ = true; } // Tests a failed ASSERT_PRED_FORMAT2 where the // predicate-formatter is a function on a built-in type (int). TEST_F(ASSERT_PRED_FORMAT2Test, FunctionOnBuiltInTypeFailure) { expected_to_finish_ = false; EXPECT_FATAL_FAILURE({ // NOLINT ASSERT_PRED_FORMAT2(PredFormatFunction2, n1_++, n2_++); finished_ = true; }, ""); } // Tests a failed ASSERT_PRED_FORMAT2 where the // predicate-formatter is a function on a user-defined type (Bool). TEST_F(ASSERT_PRED_FORMAT2Test, FunctionOnUserTypeFailure) { expected_to_finish_ = false; EXPECT_FATAL_FAILURE({ // NOLINT ASSERT_PRED_FORMAT2(PredFormatFunction2, Bool(n1_++), Bool(n2_++)); finished_ = true; }, ""); } // Tests a failed ASSERT_PRED_FORMAT2 where the // predicate-formatter is a functor on a built-in type (int). TEST_F(ASSERT_PRED_FORMAT2Test, FunctorOnBuiltInTypeFailure) { expected_to_finish_ = false; EXPECT_FATAL_FAILURE({ // NOLINT ASSERT_PRED_FORMAT2(PredFormatFunctor2(), n1_++, n2_++); finished_ = true; }, ""); } // Tests a failed ASSERT_PRED_FORMAT2 where the // predicate-formatter is a functor on a user-defined type (Bool). TEST_F(ASSERT_PRED_FORMAT2Test, FunctorOnUserTypeFailure) { expected_to_finish_ = false; EXPECT_FATAL_FAILURE({ // NOLINT ASSERT_PRED_FORMAT2(PredFormatFunctor2(), Bool(n1_++), Bool(n2_++)); finished_ = true; }, ""); } // Sample functions/functors for testing ternary predicate assertions. // A ternary predicate function. template bool PredFunction3(T1 v1, T2 v2, T3 v3) { return v1 + v2 + v3 > 0; } // The following two functions are needed to circumvent a bug in // gcc 2.95.3, which sometimes has problem with the above template // function. bool PredFunction3Int(int v1, int v2, int v3) { return v1 + v2 + v3 > 0; } bool PredFunction3Bool(Bool v1, Bool v2, Bool v3) { return v1 + v2 + v3 > 0; } // A ternary predicate functor. struct PredFunctor3 { template bool operator()(const T1& v1, const T2& v2, const T3& v3) { return v1 + v2 + v3 > 0; } }; // A ternary predicate-formatter function. template testing::AssertionResult PredFormatFunction3(const char* e1, const char* e2, const char* e3, const T1& v1, const T2& v2, const T3& v3) { if (PredFunction3(v1, v2, v3)) return testing::AssertionSuccess(); return testing::AssertionFailure() << e1 << " + " << e2 << " + " << e3 << " is expected to be positive, but evaluates to " << v1 + v2 + v3 << "."; } // A ternary predicate-formatter functor. struct PredFormatFunctor3 { template testing::AssertionResult operator()(const char* e1, const char* e2, const char* e3, const T1& v1, const T2& v2, const T3& v3) const { return PredFormatFunction3(e1, e2, e3, v1, v2, v3); } }; // Tests for {EXPECT|ASSERT}_PRED_FORMAT3. class Predicate3Test : public testing::Test { protected: virtual void SetUp() { expected_to_finish_ = true; finished_ = false; n1_ = n2_ = n3_ = 0; } virtual void TearDown() { // Verifies that each of the predicate's arguments was evaluated // exactly once. EXPECT_EQ(1, n1_) << "The predicate assertion didn't evaluate argument 2 " "exactly once."; EXPECT_EQ(1, n2_) << "The predicate assertion didn't evaluate argument 3 " "exactly once."; EXPECT_EQ(1, n3_) << "The predicate assertion didn't evaluate argument 4 " "exactly once."; // Verifies that the control flow in the test function is expected. if (expected_to_finish_ && !finished_) { FAIL() << "The predicate assertion unexpactedly aborted the test."; } else if (!expected_to_finish_ && finished_) { FAIL() << "The failed predicate assertion didn't abort the test " "as expected."; } } // true iff the test function is expected to run to finish. static bool expected_to_finish_; // true iff the test function did run to finish. static bool finished_; static int n1_; static int n2_; static int n3_; }; bool Predicate3Test::expected_to_finish_; bool Predicate3Test::finished_; int Predicate3Test::n1_; int Predicate3Test::n2_; int Predicate3Test::n3_; typedef Predicate3Test EXPECT_PRED_FORMAT3Test; typedef Predicate3Test ASSERT_PRED_FORMAT3Test; typedef Predicate3Test EXPECT_PRED3Test; typedef Predicate3Test ASSERT_PRED3Test; // Tests a successful EXPECT_PRED3 where the // predicate-formatter is a function on a built-in type (int). TEST_F(EXPECT_PRED3Test, FunctionOnBuiltInTypeSuccess) { EXPECT_PRED3(PredFunction3Int, ++n1_, ++n2_, ++n3_); finished_ = true; } // Tests a successful EXPECT_PRED3 where the // predicate-formatter is a function on a user-defined type (Bool). TEST_F(EXPECT_PRED3Test, FunctionOnUserTypeSuccess) { EXPECT_PRED3(PredFunction3Bool, Bool(++n1_), Bool(++n2_), Bool(++n3_)); finished_ = true; } // Tests a successful EXPECT_PRED3 where the // predicate-formatter is a functor on a built-in type (int). TEST_F(EXPECT_PRED3Test, FunctorOnBuiltInTypeSuccess) { EXPECT_PRED3(PredFunctor3(), ++n1_, ++n2_, ++n3_); finished_ = true; } // Tests a successful EXPECT_PRED3 where the // predicate-formatter is a functor on a user-defined type (Bool). TEST_F(EXPECT_PRED3Test, FunctorOnUserTypeSuccess) { EXPECT_PRED3(PredFunctor3(), Bool(++n1_), Bool(++n2_), Bool(++n3_)); finished_ = true; } // Tests a failed EXPECT_PRED3 where the // predicate-formatter is a function on a built-in type (int). TEST_F(EXPECT_PRED3Test, FunctionOnBuiltInTypeFailure) { EXPECT_NONFATAL_FAILURE({ // NOLINT EXPECT_PRED3(PredFunction3Int, n1_++, n2_++, n3_++); finished_ = true; }, ""); } // Tests a failed EXPECT_PRED3 where the // predicate-formatter is a function on a user-defined type (Bool). TEST_F(EXPECT_PRED3Test, FunctionOnUserTypeFailure) { EXPECT_NONFATAL_FAILURE({ // NOLINT EXPECT_PRED3(PredFunction3Bool, Bool(n1_++), Bool(n2_++), Bool(n3_++)); finished_ = true; }, ""); } // Tests a failed EXPECT_PRED3 where the // predicate-formatter is a functor on a built-in type (int). TEST_F(EXPECT_PRED3Test, FunctorOnBuiltInTypeFailure) { EXPECT_NONFATAL_FAILURE({ // NOLINT EXPECT_PRED3(PredFunctor3(), n1_++, n2_++, n3_++); finished_ = true; }, ""); } // Tests a failed EXPECT_PRED3 where the // predicate-formatter is a functor on a user-defined type (Bool). TEST_F(EXPECT_PRED3Test, FunctorOnUserTypeFailure) { EXPECT_NONFATAL_FAILURE({ // NOLINT EXPECT_PRED3(PredFunctor3(), Bool(n1_++), Bool(n2_++), Bool(n3_++)); finished_ = true; }, ""); } // Tests a successful ASSERT_PRED3 where the // predicate-formatter is a function on a built-in type (int). TEST_F(ASSERT_PRED3Test, FunctionOnBuiltInTypeSuccess) { ASSERT_PRED3(PredFunction3Int, ++n1_, ++n2_, ++n3_); finished_ = true; } // Tests a successful ASSERT_PRED3 where the // predicate-formatter is a function on a user-defined type (Bool). TEST_F(ASSERT_PRED3Test, FunctionOnUserTypeSuccess) { ASSERT_PRED3(PredFunction3Bool, Bool(++n1_), Bool(++n2_), Bool(++n3_)); finished_ = true; } // Tests a successful ASSERT_PRED3 where the // predicate-formatter is a functor on a built-in type (int). TEST_F(ASSERT_PRED3Test, FunctorOnBuiltInTypeSuccess) { ASSERT_PRED3(PredFunctor3(), ++n1_, ++n2_, ++n3_); finished_ = true; } // Tests a successful ASSERT_PRED3 where the // predicate-formatter is a functor on a user-defined type (Bool). TEST_F(ASSERT_PRED3Test, FunctorOnUserTypeSuccess) { ASSERT_PRED3(PredFunctor3(), Bool(++n1_), Bool(++n2_), Bool(++n3_)); finished_ = true; } // Tests a failed ASSERT_PRED3 where the // predicate-formatter is a function on a built-in type (int). TEST_F(ASSERT_PRED3Test, FunctionOnBuiltInTypeFailure) { expected_to_finish_ = false; EXPECT_FATAL_FAILURE({ // NOLINT ASSERT_PRED3(PredFunction3Int, n1_++, n2_++, n3_++); finished_ = true; }, ""); } // Tests a failed ASSERT_PRED3 where the // predicate-formatter is a function on a user-defined type (Bool). TEST_F(ASSERT_PRED3Test, FunctionOnUserTypeFailure) { expected_to_finish_ = false; EXPECT_FATAL_FAILURE({ // NOLINT ASSERT_PRED3(PredFunction3Bool, Bool(n1_++), Bool(n2_++), Bool(n3_++)); finished_ = true; }, ""); } // Tests a failed ASSERT_PRED3 where the // predicate-formatter is a functor on a built-in type (int). TEST_F(ASSERT_PRED3Test, FunctorOnBuiltInTypeFailure) { expected_to_finish_ = false; EXPECT_FATAL_FAILURE({ // NOLINT ASSERT_PRED3(PredFunctor3(), n1_++, n2_++, n3_++); finished_ = true; }, ""); } // Tests a failed ASSERT_PRED3 where the // predicate-formatter is a functor on a user-defined type (Bool). TEST_F(ASSERT_PRED3Test, FunctorOnUserTypeFailure) { expected_to_finish_ = false; EXPECT_FATAL_FAILURE({ // NOLINT ASSERT_PRED3(PredFunctor3(), Bool(n1_++), Bool(n2_++), Bool(n3_++)); finished_ = true; }, ""); } // Tests a successful EXPECT_PRED_FORMAT3 where the // predicate-formatter is a function on a built-in type (int). TEST_F(EXPECT_PRED_FORMAT3Test, FunctionOnBuiltInTypeSuccess) { EXPECT_PRED_FORMAT3(PredFormatFunction3, ++n1_, ++n2_, ++n3_); finished_ = true; } // Tests a successful EXPECT_PRED_FORMAT3 where the // predicate-formatter is a function on a user-defined type (Bool). TEST_F(EXPECT_PRED_FORMAT3Test, FunctionOnUserTypeSuccess) { EXPECT_PRED_FORMAT3(PredFormatFunction3, Bool(++n1_), Bool(++n2_), Bool(++n3_)); finished_ = true; } // Tests a successful EXPECT_PRED_FORMAT3 where the // predicate-formatter is a functor on a built-in type (int). TEST_F(EXPECT_PRED_FORMAT3Test, FunctorOnBuiltInTypeSuccess) { EXPECT_PRED_FORMAT3(PredFormatFunctor3(), ++n1_, ++n2_, ++n3_); finished_ = true; } // Tests a successful EXPECT_PRED_FORMAT3 where the // predicate-formatter is a functor on a user-defined type (Bool). TEST_F(EXPECT_PRED_FORMAT3Test, FunctorOnUserTypeSuccess) { EXPECT_PRED_FORMAT3(PredFormatFunctor3(), Bool(++n1_), Bool(++n2_), Bool(++n3_)); finished_ = true; } // Tests a failed EXPECT_PRED_FORMAT3 where the // predicate-formatter is a function on a built-in type (int). TEST_F(EXPECT_PRED_FORMAT3Test, FunctionOnBuiltInTypeFailure) { EXPECT_NONFATAL_FAILURE({ // NOLINT EXPECT_PRED_FORMAT3(PredFormatFunction3, n1_++, n2_++, n3_++); finished_ = true; }, ""); } // Tests a failed EXPECT_PRED_FORMAT3 where the // predicate-formatter is a function on a user-defined type (Bool). TEST_F(EXPECT_PRED_FORMAT3Test, FunctionOnUserTypeFailure) { EXPECT_NONFATAL_FAILURE({ // NOLINT EXPECT_PRED_FORMAT3(PredFormatFunction3, Bool(n1_++), Bool(n2_++), Bool(n3_++)); finished_ = true; }, ""); } // Tests a failed EXPECT_PRED_FORMAT3 where the // predicate-formatter is a functor on a built-in type (int). TEST_F(EXPECT_PRED_FORMAT3Test, FunctorOnBuiltInTypeFailure) { EXPECT_NONFATAL_FAILURE({ // NOLINT EXPECT_PRED_FORMAT3(PredFormatFunctor3(), n1_++, n2_++, n3_++); finished_ = true; }, ""); } // Tests a failed EXPECT_PRED_FORMAT3 where the // predicate-formatter is a functor on a user-defined type (Bool). TEST_F(EXPECT_PRED_FORMAT3Test, FunctorOnUserTypeFailure) { EXPECT_NONFATAL_FAILURE({ // NOLINT EXPECT_PRED_FORMAT3(PredFormatFunctor3(), Bool(n1_++), Bool(n2_++), Bool(n3_++)); finished_ = true; }, ""); } // Tests a successful ASSERT_PRED_FORMAT3 where the // predicate-formatter is a function on a built-in type (int). TEST_F(ASSERT_PRED_FORMAT3Test, FunctionOnBuiltInTypeSuccess) { ASSERT_PRED_FORMAT3(PredFormatFunction3, ++n1_, ++n2_, ++n3_); finished_ = true; } // Tests a successful ASSERT_PRED_FORMAT3 where the // predicate-formatter is a function on a user-defined type (Bool). TEST_F(ASSERT_PRED_FORMAT3Test, FunctionOnUserTypeSuccess) { ASSERT_PRED_FORMAT3(PredFormatFunction3, Bool(++n1_), Bool(++n2_), Bool(++n3_)); finished_ = true; } // Tests a successful ASSERT_PRED_FORMAT3 where the // predicate-formatter is a functor on a built-in type (int). TEST_F(ASSERT_PRED_FORMAT3Test, FunctorOnBuiltInTypeSuccess) { ASSERT_PRED_FORMAT3(PredFormatFunctor3(), ++n1_, ++n2_, ++n3_); finished_ = true; } // Tests a successful ASSERT_PRED_FORMAT3 where the // predicate-formatter is a functor on a user-defined type (Bool). TEST_F(ASSERT_PRED_FORMAT3Test, FunctorOnUserTypeSuccess) { ASSERT_PRED_FORMAT3(PredFormatFunctor3(), Bool(++n1_), Bool(++n2_), Bool(++n3_)); finished_ = true; } // Tests a failed ASSERT_PRED_FORMAT3 where the // predicate-formatter is a function on a built-in type (int). TEST_F(ASSERT_PRED_FORMAT3Test, FunctionOnBuiltInTypeFailure) { expected_to_finish_ = false; EXPECT_FATAL_FAILURE({ // NOLINT ASSERT_PRED_FORMAT3(PredFormatFunction3, n1_++, n2_++, n3_++); finished_ = true; }, ""); } // Tests a failed ASSERT_PRED_FORMAT3 where the // predicate-formatter is a function on a user-defined type (Bool). TEST_F(ASSERT_PRED_FORMAT3Test, FunctionOnUserTypeFailure) { expected_to_finish_ = false; EXPECT_FATAL_FAILURE({ // NOLINT ASSERT_PRED_FORMAT3(PredFormatFunction3, Bool(n1_++), Bool(n2_++), Bool(n3_++)); finished_ = true; }, ""); } // Tests a failed ASSERT_PRED_FORMAT3 where the // predicate-formatter is a functor on a built-in type (int). TEST_F(ASSERT_PRED_FORMAT3Test, FunctorOnBuiltInTypeFailure) { expected_to_finish_ = false; EXPECT_FATAL_FAILURE({ // NOLINT ASSERT_PRED_FORMAT3(PredFormatFunctor3(), n1_++, n2_++, n3_++); finished_ = true; }, ""); } // Tests a failed ASSERT_PRED_FORMAT3 where the // predicate-formatter is a functor on a user-defined type (Bool). TEST_F(ASSERT_PRED_FORMAT3Test, FunctorOnUserTypeFailure) { expected_to_finish_ = false; EXPECT_FATAL_FAILURE({ // NOLINT ASSERT_PRED_FORMAT3(PredFormatFunctor3(), Bool(n1_++), Bool(n2_++), Bool(n3_++)); finished_ = true; }, ""); } // Sample functions/functors for testing 4-ary predicate assertions. // A 4-ary predicate function. template bool PredFunction4(T1 v1, T2 v2, T3 v3, T4 v4) { return v1 + v2 + v3 + v4 > 0; } // The following two functions are needed to circumvent a bug in // gcc 2.95.3, which sometimes has problem with the above template // function. bool PredFunction4Int(int v1, int v2, int v3, int v4) { return v1 + v2 + v3 + v4 > 0; } bool PredFunction4Bool(Bool v1, Bool v2, Bool v3, Bool v4) { return v1 + v2 + v3 + v4 > 0; } // A 4-ary predicate functor. struct PredFunctor4 { template bool operator()(const T1& v1, const T2& v2, const T3& v3, const T4& v4) { return v1 + v2 + v3 + v4 > 0; } }; // A 4-ary predicate-formatter function. template testing::AssertionResult PredFormatFunction4(const char* e1, const char* e2, const char* e3, const char* e4, const T1& v1, const T2& v2, const T3& v3, const T4& v4) { if (PredFunction4(v1, v2, v3, v4)) return testing::AssertionSuccess(); return testing::AssertionFailure() << e1 << " + " << e2 << " + " << e3 << " + " << e4 << " is expected to be positive, but evaluates to " << v1 + v2 + v3 + v4 << "."; } // A 4-ary predicate-formatter functor. struct PredFormatFunctor4 { template testing::AssertionResult operator()(const char* e1, const char* e2, const char* e3, const char* e4, const T1& v1, const T2& v2, const T3& v3, const T4& v4) const { return PredFormatFunction4(e1, e2, e3, e4, v1, v2, v3, v4); } }; // Tests for {EXPECT|ASSERT}_PRED_FORMAT4. class Predicate4Test : public testing::Test { protected: virtual void SetUp() { expected_to_finish_ = true; finished_ = false; n1_ = n2_ = n3_ = n4_ = 0; } virtual void TearDown() { // Verifies that each of the predicate's arguments was evaluated // exactly once. EXPECT_EQ(1, n1_) << "The predicate assertion didn't evaluate argument 2 " "exactly once."; EXPECT_EQ(1, n2_) << "The predicate assertion didn't evaluate argument 3 " "exactly once."; EXPECT_EQ(1, n3_) << "The predicate assertion didn't evaluate argument 4 " "exactly once."; EXPECT_EQ(1, n4_) << "The predicate assertion didn't evaluate argument 5 " "exactly once."; // Verifies that the control flow in the test function is expected. if (expected_to_finish_ && !finished_) { FAIL() << "The predicate assertion unexpactedly aborted the test."; } else if (!expected_to_finish_ && finished_) { FAIL() << "The failed predicate assertion didn't abort the test " "as expected."; } } // true iff the test function is expected to run to finish. static bool expected_to_finish_; // true iff the test function did run to finish. static bool finished_; static int n1_; static int n2_; static int n3_; static int n4_; }; bool Predicate4Test::expected_to_finish_; bool Predicate4Test::finished_; int Predicate4Test::n1_; int Predicate4Test::n2_; int Predicate4Test::n3_; int Predicate4Test::n4_; typedef Predicate4Test EXPECT_PRED_FORMAT4Test; typedef Predicate4Test ASSERT_PRED_FORMAT4Test; typedef Predicate4Test EXPECT_PRED4Test; typedef Predicate4Test ASSERT_PRED4Test; // Tests a successful EXPECT_PRED4 where the // predicate-formatter is a function on a built-in type (int). TEST_F(EXPECT_PRED4Test, FunctionOnBuiltInTypeSuccess) { EXPECT_PRED4(PredFunction4Int, ++n1_, ++n2_, ++n3_, ++n4_); finished_ = true; } // Tests a successful EXPECT_PRED4 where the // predicate-formatter is a function on a user-defined type (Bool). TEST_F(EXPECT_PRED4Test, FunctionOnUserTypeSuccess) { EXPECT_PRED4(PredFunction4Bool, Bool(++n1_), Bool(++n2_), Bool(++n3_), Bool(++n4_)); finished_ = true; } // Tests a successful EXPECT_PRED4 where the // predicate-formatter is a functor on a built-in type (int). TEST_F(EXPECT_PRED4Test, FunctorOnBuiltInTypeSuccess) { EXPECT_PRED4(PredFunctor4(), ++n1_, ++n2_, ++n3_, ++n4_); finished_ = true; } // Tests a successful EXPECT_PRED4 where the // predicate-formatter is a functor on a user-defined type (Bool). TEST_F(EXPECT_PRED4Test, FunctorOnUserTypeSuccess) { EXPECT_PRED4(PredFunctor4(), Bool(++n1_), Bool(++n2_), Bool(++n3_), Bool(++n4_)); finished_ = true; } // Tests a failed EXPECT_PRED4 where the // predicate-formatter is a function on a built-in type (int). TEST_F(EXPECT_PRED4Test, FunctionOnBuiltInTypeFailure) { EXPECT_NONFATAL_FAILURE({ // NOLINT EXPECT_PRED4(PredFunction4Int, n1_++, n2_++, n3_++, n4_++); finished_ = true; }, ""); } // Tests a failed EXPECT_PRED4 where the // predicate-formatter is a function on a user-defined type (Bool). TEST_F(EXPECT_PRED4Test, FunctionOnUserTypeFailure) { EXPECT_NONFATAL_FAILURE({ // NOLINT EXPECT_PRED4(PredFunction4Bool, Bool(n1_++), Bool(n2_++), Bool(n3_++), Bool(n4_++)); finished_ = true; }, ""); } // Tests a failed EXPECT_PRED4 where the // predicate-formatter is a functor on a built-in type (int). TEST_F(EXPECT_PRED4Test, FunctorOnBuiltInTypeFailure) { EXPECT_NONFATAL_FAILURE({ // NOLINT EXPECT_PRED4(PredFunctor4(), n1_++, n2_++, n3_++, n4_++); finished_ = true; }, ""); } // Tests a failed EXPECT_PRED4 where the // predicate-formatter is a functor on a user-defined type (Bool). TEST_F(EXPECT_PRED4Test, FunctorOnUserTypeFailure) { EXPECT_NONFATAL_FAILURE({ // NOLINT EXPECT_PRED4(PredFunctor4(), Bool(n1_++), Bool(n2_++), Bool(n3_++), Bool(n4_++)); finished_ = true; }, ""); } // Tests a successful ASSERT_PRED4 where the // predicate-formatter is a function on a built-in type (int). TEST_F(ASSERT_PRED4Test, FunctionOnBuiltInTypeSuccess) { ASSERT_PRED4(PredFunction4Int, ++n1_, ++n2_, ++n3_, ++n4_); finished_ = true; } // Tests a successful ASSERT_PRED4 where the // predicate-formatter is a function on a user-defined type (Bool). TEST_F(ASSERT_PRED4Test, FunctionOnUserTypeSuccess) { ASSERT_PRED4(PredFunction4Bool, Bool(++n1_), Bool(++n2_), Bool(++n3_), Bool(++n4_)); finished_ = true; } // Tests a successful ASSERT_PRED4 where the // predicate-formatter is a functor on a built-in type (int). TEST_F(ASSERT_PRED4Test, FunctorOnBuiltInTypeSuccess) { ASSERT_PRED4(PredFunctor4(), ++n1_, ++n2_, ++n3_, ++n4_); finished_ = true; } // Tests a successful ASSERT_PRED4 where the // predicate-formatter is a functor on a user-defined type (Bool). TEST_F(ASSERT_PRED4Test, FunctorOnUserTypeSuccess) { ASSERT_PRED4(PredFunctor4(), Bool(++n1_), Bool(++n2_), Bool(++n3_), Bool(++n4_)); finished_ = true; } // Tests a failed ASSERT_PRED4 where the // predicate-formatter is a function on a built-in type (int). TEST_F(ASSERT_PRED4Test, FunctionOnBuiltInTypeFailure) { expected_to_finish_ = false; EXPECT_FATAL_FAILURE({ // NOLINT ASSERT_PRED4(PredFunction4Int, n1_++, n2_++, n3_++, n4_++); finished_ = true; }, ""); } // Tests a failed ASSERT_PRED4 where the // predicate-formatter is a function on a user-defined type (Bool). TEST_F(ASSERT_PRED4Test, FunctionOnUserTypeFailure) { expected_to_finish_ = false; EXPECT_FATAL_FAILURE({ // NOLINT ASSERT_PRED4(PredFunction4Bool, Bool(n1_++), Bool(n2_++), Bool(n3_++), Bool(n4_++)); finished_ = true; }, ""); } // Tests a failed ASSERT_PRED4 where the // predicate-formatter is a functor on a built-in type (int). TEST_F(ASSERT_PRED4Test, FunctorOnBuiltInTypeFailure) { expected_to_finish_ = false; EXPECT_FATAL_FAILURE({ // NOLINT ASSERT_PRED4(PredFunctor4(), n1_++, n2_++, n3_++, n4_++); finished_ = true; }, ""); } // Tests a failed ASSERT_PRED4 where the // predicate-formatter is a functor on a user-defined type (Bool). TEST_F(ASSERT_PRED4Test, FunctorOnUserTypeFailure) { expected_to_finish_ = false; EXPECT_FATAL_FAILURE({ // NOLINT ASSERT_PRED4(PredFunctor4(), Bool(n1_++), Bool(n2_++), Bool(n3_++), Bool(n4_++)); finished_ = true; }, ""); } // Tests a successful EXPECT_PRED_FORMAT4 where the // predicate-formatter is a function on a built-in type (int). TEST_F(EXPECT_PRED_FORMAT4Test, FunctionOnBuiltInTypeSuccess) { EXPECT_PRED_FORMAT4(PredFormatFunction4, ++n1_, ++n2_, ++n3_, ++n4_); finished_ = true; } // Tests a successful EXPECT_PRED_FORMAT4 where the // predicate-formatter is a function on a user-defined type (Bool). TEST_F(EXPECT_PRED_FORMAT4Test, FunctionOnUserTypeSuccess) { EXPECT_PRED_FORMAT4(PredFormatFunction4, Bool(++n1_), Bool(++n2_), Bool(++n3_), Bool(++n4_)); finished_ = true; } // Tests a successful EXPECT_PRED_FORMAT4 where the // predicate-formatter is a functor on a built-in type (int). TEST_F(EXPECT_PRED_FORMAT4Test, FunctorOnBuiltInTypeSuccess) { EXPECT_PRED_FORMAT4(PredFormatFunctor4(), ++n1_, ++n2_, ++n3_, ++n4_); finished_ = true; } // Tests a successful EXPECT_PRED_FORMAT4 where the // predicate-formatter is a functor on a user-defined type (Bool). TEST_F(EXPECT_PRED_FORMAT4Test, FunctorOnUserTypeSuccess) { EXPECT_PRED_FORMAT4(PredFormatFunctor4(), Bool(++n1_), Bool(++n2_), Bool(++n3_), Bool(++n4_)); finished_ = true; } // Tests a failed EXPECT_PRED_FORMAT4 where the // predicate-formatter is a function on a built-in type (int). TEST_F(EXPECT_PRED_FORMAT4Test, FunctionOnBuiltInTypeFailure) { EXPECT_NONFATAL_FAILURE({ // NOLINT EXPECT_PRED_FORMAT4(PredFormatFunction4, n1_++, n2_++, n3_++, n4_++); finished_ = true; }, ""); } // Tests a failed EXPECT_PRED_FORMAT4 where the // predicate-formatter is a function on a user-defined type (Bool). TEST_F(EXPECT_PRED_FORMAT4Test, FunctionOnUserTypeFailure) { EXPECT_NONFATAL_FAILURE({ // NOLINT EXPECT_PRED_FORMAT4(PredFormatFunction4, Bool(n1_++), Bool(n2_++), Bool(n3_++), Bool(n4_++)); finished_ = true; }, ""); } // Tests a failed EXPECT_PRED_FORMAT4 where the // predicate-formatter is a functor on a built-in type (int). TEST_F(EXPECT_PRED_FORMAT4Test, FunctorOnBuiltInTypeFailure) { EXPECT_NONFATAL_FAILURE({ // NOLINT EXPECT_PRED_FORMAT4(PredFormatFunctor4(), n1_++, n2_++, n3_++, n4_++); finished_ = true; }, ""); } // Tests a failed EXPECT_PRED_FORMAT4 where the // predicate-formatter is a functor on a user-defined type (Bool). TEST_F(EXPECT_PRED_FORMAT4Test, FunctorOnUserTypeFailure) { EXPECT_NONFATAL_FAILURE({ // NOLINT EXPECT_PRED_FORMAT4(PredFormatFunctor4(), Bool(n1_++), Bool(n2_++), Bool(n3_++), Bool(n4_++)); finished_ = true; }, ""); } // Tests a successful ASSERT_PRED_FORMAT4 where the // predicate-formatter is a function on a built-in type (int). TEST_F(ASSERT_PRED_FORMAT4Test, FunctionOnBuiltInTypeSuccess) { ASSERT_PRED_FORMAT4(PredFormatFunction4, ++n1_, ++n2_, ++n3_, ++n4_); finished_ = true; } // Tests a successful ASSERT_PRED_FORMAT4 where the // predicate-formatter is a function on a user-defined type (Bool). TEST_F(ASSERT_PRED_FORMAT4Test, FunctionOnUserTypeSuccess) { ASSERT_PRED_FORMAT4(PredFormatFunction4, Bool(++n1_), Bool(++n2_), Bool(++n3_), Bool(++n4_)); finished_ = true; } // Tests a successful ASSERT_PRED_FORMAT4 where the // predicate-formatter is a functor on a built-in type (int). TEST_F(ASSERT_PRED_FORMAT4Test, FunctorOnBuiltInTypeSuccess) { ASSERT_PRED_FORMAT4(PredFormatFunctor4(), ++n1_, ++n2_, ++n3_, ++n4_); finished_ = true; } // Tests a successful ASSERT_PRED_FORMAT4 where the // predicate-formatter is a functor on a user-defined type (Bool). TEST_F(ASSERT_PRED_FORMAT4Test, FunctorOnUserTypeSuccess) { ASSERT_PRED_FORMAT4(PredFormatFunctor4(), Bool(++n1_), Bool(++n2_), Bool(++n3_), Bool(++n4_)); finished_ = true; } // Tests a failed ASSERT_PRED_FORMAT4 where the // predicate-formatter is a function on a built-in type (int). TEST_F(ASSERT_PRED_FORMAT4Test, FunctionOnBuiltInTypeFailure) { expected_to_finish_ = false; EXPECT_FATAL_FAILURE({ // NOLINT ASSERT_PRED_FORMAT4(PredFormatFunction4, n1_++, n2_++, n3_++, n4_++); finished_ = true; }, ""); } // Tests a failed ASSERT_PRED_FORMAT4 where the // predicate-formatter is a function on a user-defined type (Bool). TEST_F(ASSERT_PRED_FORMAT4Test, FunctionOnUserTypeFailure) { expected_to_finish_ = false; EXPECT_FATAL_FAILURE({ // NOLINT ASSERT_PRED_FORMAT4(PredFormatFunction4, Bool(n1_++), Bool(n2_++), Bool(n3_++), Bool(n4_++)); finished_ = true; }, ""); } // Tests a failed ASSERT_PRED_FORMAT4 where the // predicate-formatter is a functor on a built-in type (int). TEST_F(ASSERT_PRED_FORMAT4Test, FunctorOnBuiltInTypeFailure) { expected_to_finish_ = false; EXPECT_FATAL_FAILURE({ // NOLINT ASSERT_PRED_FORMAT4(PredFormatFunctor4(), n1_++, n2_++, n3_++, n4_++); finished_ = true; }, ""); } // Tests a failed ASSERT_PRED_FORMAT4 where the // predicate-formatter is a functor on a user-defined type (Bool). TEST_F(ASSERT_PRED_FORMAT4Test, FunctorOnUserTypeFailure) { expected_to_finish_ = false; EXPECT_FATAL_FAILURE({ // NOLINT ASSERT_PRED_FORMAT4(PredFormatFunctor4(), Bool(n1_++), Bool(n2_++), Bool(n3_++), Bool(n4_++)); finished_ = true; }, ""); } // Sample functions/functors for testing 5-ary predicate assertions. // A 5-ary predicate function. template bool PredFunction5(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5) { return v1 + v2 + v3 + v4 + v5 > 0; } // The following two functions are needed to circumvent a bug in // gcc 2.95.3, which sometimes has problem with the above template // function. bool PredFunction5Int(int v1, int v2, int v3, int v4, int v5) { return v1 + v2 + v3 + v4 + v5 > 0; } bool PredFunction5Bool(Bool v1, Bool v2, Bool v3, Bool v4, Bool v5) { return v1 + v2 + v3 + v4 + v5 > 0; } // A 5-ary predicate functor. struct PredFunctor5 { template bool operator()(const T1& v1, const T2& v2, const T3& v3, const T4& v4, const T5& v5) { return v1 + v2 + v3 + v4 + v5 > 0; } }; // A 5-ary predicate-formatter function. template testing::AssertionResult PredFormatFunction5(const char* e1, const char* e2, const char* e3, const char* e4, const char* e5, const T1& v1, const T2& v2, const T3& v3, const T4& v4, const T5& v5) { if (PredFunction5(v1, v2, v3, v4, v5)) return testing::AssertionSuccess(); return testing::AssertionFailure() << e1 << " + " << e2 << " + " << e3 << " + " << e4 << " + " << e5 << " is expected to be positive, but evaluates to " << v1 + v2 + v3 + v4 + v5 << "."; } // A 5-ary predicate-formatter functor. struct PredFormatFunctor5 { template testing::AssertionResult operator()(const char* e1, const char* e2, const char* e3, const char* e4, const char* e5, const T1& v1, const T2& v2, const T3& v3, const T4& v4, const T5& v5) const { return PredFormatFunction5(e1, e2, e3, e4, e5, v1, v2, v3, v4, v5); } }; // Tests for {EXPECT|ASSERT}_PRED_FORMAT5. class Predicate5Test : public testing::Test { protected: virtual void SetUp() { expected_to_finish_ = true; finished_ = false; n1_ = n2_ = n3_ = n4_ = n5_ = 0; } virtual void TearDown() { // Verifies that each of the predicate's arguments was evaluated // exactly once. EXPECT_EQ(1, n1_) << "The predicate assertion didn't evaluate argument 2 " "exactly once."; EXPECT_EQ(1, n2_) << "The predicate assertion didn't evaluate argument 3 " "exactly once."; EXPECT_EQ(1, n3_) << "The predicate assertion didn't evaluate argument 4 " "exactly once."; EXPECT_EQ(1, n4_) << "The predicate assertion didn't evaluate argument 5 " "exactly once."; EXPECT_EQ(1, n5_) << "The predicate assertion didn't evaluate argument 6 " "exactly once."; // Verifies that the control flow in the test function is expected. if (expected_to_finish_ && !finished_) { FAIL() << "The predicate assertion unexpactedly aborted the test."; } else if (!expected_to_finish_ && finished_) { FAIL() << "The failed predicate assertion didn't abort the test " "as expected."; } } // true iff the test function is expected to run to finish. static bool expected_to_finish_; // true iff the test function did run to finish. static bool finished_; static int n1_; static int n2_; static int n3_; static int n4_; static int n5_; }; bool Predicate5Test::expected_to_finish_; bool Predicate5Test::finished_; int Predicate5Test::n1_; int Predicate5Test::n2_; int Predicate5Test::n3_; int Predicate5Test::n4_; int Predicate5Test::n5_; typedef Predicate5Test EXPECT_PRED_FORMAT5Test; typedef Predicate5Test ASSERT_PRED_FORMAT5Test; typedef Predicate5Test EXPECT_PRED5Test; typedef Predicate5Test ASSERT_PRED5Test; // Tests a successful EXPECT_PRED5 where the // predicate-formatter is a function on a built-in type (int). TEST_F(EXPECT_PRED5Test, FunctionOnBuiltInTypeSuccess) { EXPECT_PRED5(PredFunction5Int, ++n1_, ++n2_, ++n3_, ++n4_, ++n5_); finished_ = true; } // Tests a successful EXPECT_PRED5 where the // predicate-formatter is a function on a user-defined type (Bool). TEST_F(EXPECT_PRED5Test, FunctionOnUserTypeSuccess) { EXPECT_PRED5(PredFunction5Bool, Bool(++n1_), Bool(++n2_), Bool(++n3_), Bool(++n4_), Bool(++n5_)); finished_ = true; } // Tests a successful EXPECT_PRED5 where the // predicate-formatter is a functor on a built-in type (int). TEST_F(EXPECT_PRED5Test, FunctorOnBuiltInTypeSuccess) { EXPECT_PRED5(PredFunctor5(), ++n1_, ++n2_, ++n3_, ++n4_, ++n5_); finished_ = true; } // Tests a successful EXPECT_PRED5 where the // predicate-formatter is a functor on a user-defined type (Bool). TEST_F(EXPECT_PRED5Test, FunctorOnUserTypeSuccess) { EXPECT_PRED5(PredFunctor5(), Bool(++n1_), Bool(++n2_), Bool(++n3_), Bool(++n4_), Bool(++n5_)); finished_ = true; } // Tests a failed EXPECT_PRED5 where the // predicate-formatter is a function on a built-in type (int). TEST_F(EXPECT_PRED5Test, FunctionOnBuiltInTypeFailure) { EXPECT_NONFATAL_FAILURE({ // NOLINT EXPECT_PRED5(PredFunction5Int, n1_++, n2_++, n3_++, n4_++, n5_++); finished_ = true; }, ""); } // Tests a failed EXPECT_PRED5 where the // predicate-formatter is a function on a user-defined type (Bool). TEST_F(EXPECT_PRED5Test, FunctionOnUserTypeFailure) { EXPECT_NONFATAL_FAILURE({ // NOLINT EXPECT_PRED5(PredFunction5Bool, Bool(n1_++), Bool(n2_++), Bool(n3_++), Bool(n4_++), Bool(n5_++)); finished_ = true; }, ""); } // Tests a failed EXPECT_PRED5 where the // predicate-formatter is a functor on a built-in type (int). TEST_F(EXPECT_PRED5Test, FunctorOnBuiltInTypeFailure) { EXPECT_NONFATAL_FAILURE({ // NOLINT EXPECT_PRED5(PredFunctor5(), n1_++, n2_++, n3_++, n4_++, n5_++); finished_ = true; }, ""); } // Tests a failed EXPECT_PRED5 where the // predicate-formatter is a functor on a user-defined type (Bool). TEST_F(EXPECT_PRED5Test, FunctorOnUserTypeFailure) { EXPECT_NONFATAL_FAILURE({ // NOLINT EXPECT_PRED5(PredFunctor5(), Bool(n1_++), Bool(n2_++), Bool(n3_++), Bool(n4_++), Bool(n5_++)); finished_ = true; }, ""); } // Tests a successful ASSERT_PRED5 where the // predicate-formatter is a function on a built-in type (int). TEST_F(ASSERT_PRED5Test, FunctionOnBuiltInTypeSuccess) { ASSERT_PRED5(PredFunction5Int, ++n1_, ++n2_, ++n3_, ++n4_, ++n5_); finished_ = true; } // Tests a successful ASSERT_PRED5 where the // predicate-formatter is a function on a user-defined type (Bool). TEST_F(ASSERT_PRED5Test, FunctionOnUserTypeSuccess) { ASSERT_PRED5(PredFunction5Bool, Bool(++n1_), Bool(++n2_), Bool(++n3_), Bool(++n4_), Bool(++n5_)); finished_ = true; } // Tests a successful ASSERT_PRED5 where the // predicate-formatter is a functor on a built-in type (int). TEST_F(ASSERT_PRED5Test, FunctorOnBuiltInTypeSuccess) { ASSERT_PRED5(PredFunctor5(), ++n1_, ++n2_, ++n3_, ++n4_, ++n5_); finished_ = true; } // Tests a successful ASSERT_PRED5 where the // predicate-formatter is a functor on a user-defined type (Bool). TEST_F(ASSERT_PRED5Test, FunctorOnUserTypeSuccess) { ASSERT_PRED5(PredFunctor5(), Bool(++n1_), Bool(++n2_), Bool(++n3_), Bool(++n4_), Bool(++n5_)); finished_ = true; } // Tests a failed ASSERT_PRED5 where the // predicate-formatter is a function on a built-in type (int). TEST_F(ASSERT_PRED5Test, FunctionOnBuiltInTypeFailure) { expected_to_finish_ = false; EXPECT_FATAL_FAILURE({ // NOLINT ASSERT_PRED5(PredFunction5Int, n1_++, n2_++, n3_++, n4_++, n5_++); finished_ = true; }, ""); } // Tests a failed ASSERT_PRED5 where the // predicate-formatter is a function on a user-defined type (Bool). TEST_F(ASSERT_PRED5Test, FunctionOnUserTypeFailure) { expected_to_finish_ = false; EXPECT_FATAL_FAILURE({ // NOLINT ASSERT_PRED5(PredFunction5Bool, Bool(n1_++), Bool(n2_++), Bool(n3_++), Bool(n4_++), Bool(n5_++)); finished_ = true; }, ""); } // Tests a failed ASSERT_PRED5 where the // predicate-formatter is a functor on a built-in type (int). TEST_F(ASSERT_PRED5Test, FunctorOnBuiltInTypeFailure) { expected_to_finish_ = false; EXPECT_FATAL_FAILURE({ // NOLINT ASSERT_PRED5(PredFunctor5(), n1_++, n2_++, n3_++, n4_++, n5_++); finished_ = true; }, ""); } // Tests a failed ASSERT_PRED5 where the // predicate-formatter is a functor on a user-defined type (Bool). TEST_F(ASSERT_PRED5Test, FunctorOnUserTypeFailure) { expected_to_finish_ = false; EXPECT_FATAL_FAILURE({ // NOLINT ASSERT_PRED5(PredFunctor5(), Bool(n1_++), Bool(n2_++), Bool(n3_++), Bool(n4_++), Bool(n5_++)); finished_ = true; }, ""); } // Tests a successful EXPECT_PRED_FORMAT5 where the // predicate-formatter is a function on a built-in type (int). TEST_F(EXPECT_PRED_FORMAT5Test, FunctionOnBuiltInTypeSuccess) { EXPECT_PRED_FORMAT5(PredFormatFunction5, ++n1_, ++n2_, ++n3_, ++n4_, ++n5_); finished_ = true; } // Tests a successful EXPECT_PRED_FORMAT5 where the // predicate-formatter is a function on a user-defined type (Bool). TEST_F(EXPECT_PRED_FORMAT5Test, FunctionOnUserTypeSuccess) { EXPECT_PRED_FORMAT5(PredFormatFunction5, Bool(++n1_), Bool(++n2_), Bool(++n3_), Bool(++n4_), Bool(++n5_)); finished_ = true; } // Tests a successful EXPECT_PRED_FORMAT5 where the // predicate-formatter is a functor on a built-in type (int). TEST_F(EXPECT_PRED_FORMAT5Test, FunctorOnBuiltInTypeSuccess) { EXPECT_PRED_FORMAT5(PredFormatFunctor5(), ++n1_, ++n2_, ++n3_, ++n4_, ++n5_); finished_ = true; } // Tests a successful EXPECT_PRED_FORMAT5 where the // predicate-formatter is a functor on a user-defined type (Bool). TEST_F(EXPECT_PRED_FORMAT5Test, FunctorOnUserTypeSuccess) { EXPECT_PRED_FORMAT5(PredFormatFunctor5(), Bool(++n1_), Bool(++n2_), Bool(++n3_), Bool(++n4_), Bool(++n5_)); finished_ = true; } // Tests a failed EXPECT_PRED_FORMAT5 where the // predicate-formatter is a function on a built-in type (int). TEST_F(EXPECT_PRED_FORMAT5Test, FunctionOnBuiltInTypeFailure) { EXPECT_NONFATAL_FAILURE({ // NOLINT EXPECT_PRED_FORMAT5(PredFormatFunction5, n1_++, n2_++, n3_++, n4_++, n5_++); finished_ = true; }, ""); } // Tests a failed EXPECT_PRED_FORMAT5 where the // predicate-formatter is a function on a user-defined type (Bool). TEST_F(EXPECT_PRED_FORMAT5Test, FunctionOnUserTypeFailure) { EXPECT_NONFATAL_FAILURE({ // NOLINT EXPECT_PRED_FORMAT5(PredFormatFunction5, Bool(n1_++), Bool(n2_++), Bool(n3_++), Bool(n4_++), Bool(n5_++)); finished_ = true; }, ""); } // Tests a failed EXPECT_PRED_FORMAT5 where the // predicate-formatter is a functor on a built-in type (int). TEST_F(EXPECT_PRED_FORMAT5Test, FunctorOnBuiltInTypeFailure) { EXPECT_NONFATAL_FAILURE({ // NOLINT EXPECT_PRED_FORMAT5(PredFormatFunctor5(), n1_++, n2_++, n3_++, n4_++, n5_++); finished_ = true; }, ""); } // Tests a failed EXPECT_PRED_FORMAT5 where the // predicate-formatter is a functor on a user-defined type (Bool). TEST_F(EXPECT_PRED_FORMAT5Test, FunctorOnUserTypeFailure) { EXPECT_NONFATAL_FAILURE({ // NOLINT EXPECT_PRED_FORMAT5(PredFormatFunctor5(), Bool(n1_++), Bool(n2_++), Bool(n3_++), Bool(n4_++), Bool(n5_++)); finished_ = true; }, ""); } // Tests a successful ASSERT_PRED_FORMAT5 where the // predicate-formatter is a function on a built-in type (int). TEST_F(ASSERT_PRED_FORMAT5Test, FunctionOnBuiltInTypeSuccess) { ASSERT_PRED_FORMAT5(PredFormatFunction5, ++n1_, ++n2_, ++n3_, ++n4_, ++n5_); finished_ = true; } // Tests a successful ASSERT_PRED_FORMAT5 where the // predicate-formatter is a function on a user-defined type (Bool). TEST_F(ASSERT_PRED_FORMAT5Test, FunctionOnUserTypeSuccess) { ASSERT_PRED_FORMAT5(PredFormatFunction5, Bool(++n1_), Bool(++n2_), Bool(++n3_), Bool(++n4_), Bool(++n5_)); finished_ = true; } // Tests a successful ASSERT_PRED_FORMAT5 where the // predicate-formatter is a functor on a built-in type (int). TEST_F(ASSERT_PRED_FORMAT5Test, FunctorOnBuiltInTypeSuccess) { ASSERT_PRED_FORMAT5(PredFormatFunctor5(), ++n1_, ++n2_, ++n3_, ++n4_, ++n5_); finished_ = true; } // Tests a successful ASSERT_PRED_FORMAT5 where the // predicate-formatter is a functor on a user-defined type (Bool). TEST_F(ASSERT_PRED_FORMAT5Test, FunctorOnUserTypeSuccess) { ASSERT_PRED_FORMAT5(PredFormatFunctor5(), Bool(++n1_), Bool(++n2_), Bool(++n3_), Bool(++n4_), Bool(++n5_)); finished_ = true; } // Tests a failed ASSERT_PRED_FORMAT5 where the // predicate-formatter is a function on a built-in type (int). TEST_F(ASSERT_PRED_FORMAT5Test, FunctionOnBuiltInTypeFailure) { expected_to_finish_ = false; EXPECT_FATAL_FAILURE({ // NOLINT ASSERT_PRED_FORMAT5(PredFormatFunction5, n1_++, n2_++, n3_++, n4_++, n5_++); finished_ = true; }, ""); } // Tests a failed ASSERT_PRED_FORMAT5 where the // predicate-formatter is a function on a user-defined type (Bool). TEST_F(ASSERT_PRED_FORMAT5Test, FunctionOnUserTypeFailure) { expected_to_finish_ = false; EXPECT_FATAL_FAILURE({ // NOLINT ASSERT_PRED_FORMAT5(PredFormatFunction5, Bool(n1_++), Bool(n2_++), Bool(n3_++), Bool(n4_++), Bool(n5_++)); finished_ = true; }, ""); } // Tests a failed ASSERT_PRED_FORMAT5 where the // predicate-formatter is a functor on a built-in type (int). TEST_F(ASSERT_PRED_FORMAT5Test, FunctorOnBuiltInTypeFailure) { expected_to_finish_ = false; EXPECT_FATAL_FAILURE({ // NOLINT ASSERT_PRED_FORMAT5(PredFormatFunctor5(), n1_++, n2_++, n3_++, n4_++, n5_++); finished_ = true; }, ""); } // Tests a failed ASSERT_PRED_FORMAT5 where the // predicate-formatter is a functor on a user-defined type (Bool). TEST_F(ASSERT_PRED_FORMAT5Test, FunctorOnUserTypeFailure) { expected_to_finish_ = false; EXPECT_FATAL_FAILURE({ // NOLINT ASSERT_PRED_FORMAT5(PredFormatFunctor5(), Bool(n1_++), Bool(n2_++), Bool(n3_++), Bool(n4_++), Bool(n5_++)); finished_ = true; }, ""); } dlt-daemon-2.18.4/gtest-1.7.0/test/gtest_premature_exit_test.cc000066400000000000000000000112441353342203500242130ustar00rootroot00000000000000// Copyright 2013, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: wan@google.com (Zhanyong Wan) // // Tests that Google Test manipulates the premature-exit-detection // file correctly. #include #include "gtest/gtest.h" using ::testing::InitGoogleTest; using ::testing::Test; using ::testing::internal::posix::GetEnv; using ::testing::internal::posix::Stat; using ::testing::internal::posix::StatStruct; namespace { // Is the TEST_PREMATURE_EXIT_FILE environment variable expected to be // set? const bool kTestPrematureExitFileEnvVarShouldBeSet = false; class PrematureExitTest : public Test { public: // Returns true iff the given file exists. static bool FileExists(const char* filepath) { StatStruct stat; return Stat(filepath, &stat) == 0; } protected: PrematureExitTest() { premature_exit_file_path_ = GetEnv("TEST_PREMATURE_EXIT_FILE"); // Normalize NULL to "" for ease of handling. if (premature_exit_file_path_ == NULL) { premature_exit_file_path_ = ""; } } // Returns true iff the premature-exit file exists. bool PrematureExitFileExists() const { return FileExists(premature_exit_file_path_); } const char* premature_exit_file_path_; }; typedef PrematureExitTest PrematureExitDeathTest; // Tests that: // - the premature-exit file exists during the execution of a // death test (EXPECT_DEATH*), and // - a death test doesn't interfere with the main test process's // handling of the premature-exit file. TEST_F(PrematureExitDeathTest, FileExistsDuringExecutionOfDeathTest) { if (*premature_exit_file_path_ == '\0') { return; } EXPECT_DEATH_IF_SUPPORTED({ // If the file exists, crash the process such that the main test // process will catch the (expected) crash and report a success; // otherwise don't crash, which will cause the main test process // to report that the death test has failed. if (PrematureExitFileExists()) { exit(1); } }, ""); } // Tests that TEST_PREMATURE_EXIT_FILE is set where it's expected to // be set. TEST_F(PrematureExitTest, TestPrematureExitFileEnvVarIsSet) { if (kTestPrematureExitFileEnvVarShouldBeSet) { const char* const filepath = GetEnv("TEST_PREMATURE_EXIT_FILE"); ASSERT_TRUE(filepath != NULL); ASSERT_NE(*filepath, '\0'); } } // Tests that the premature-exit file exists during the execution of a // normal (non-death) test. TEST_F(PrematureExitTest, PrematureExitFileExistsDuringTestExecution) { if (*premature_exit_file_path_ == '\0') { return; } EXPECT_TRUE(PrematureExitFileExists()) << " file " << premature_exit_file_path_ << " should exist during test execution, but doesn't."; } } // namespace int main(int argc, char **argv) { InitGoogleTest(&argc, argv); const int exit_code = RUN_ALL_TESTS(); // Test that the premature-exit file is deleted upon return from // RUN_ALL_TESTS(). const char* const filepath = GetEnv("TEST_PREMATURE_EXIT_FILE"); if (filepath != NULL && *filepath != '\0') { if (PrematureExitTest::FileExists(filepath)) { printf( "File %s shouldn't exist after the test program finishes, but does.", filepath); return 1; } } return exit_code; } dlt-daemon-2.18.4/gtest-1.7.0/test/gtest_prod_test.cc000066400000000000000000000042411353342203500221210ustar00rootroot00000000000000// Copyright 2006, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: wan@google.com (Zhanyong Wan) // // Unit test for include/gtest/gtest_prod.h. #include "gtest/gtest.h" #include "test/production.h" // Tests that private members can be accessed from a TEST declared as // a friend of the class. TEST(PrivateCodeTest, CanAccessPrivateMembers) { PrivateCode a; EXPECT_EQ(0, a.x_); a.set_x(1); EXPECT_EQ(1, a.x_); } typedef testing::Test PrivateCodeFixtureTest; // Tests that private members can be accessed from a TEST_F declared // as a friend of the class. TEST_F(PrivateCodeFixtureTest, CanAccessPrivateMembers) { PrivateCode a; EXPECT_EQ(0, a.x_); a.set_x(2); EXPECT_EQ(2, a.x_); } dlt-daemon-2.18.4/gtest-1.7.0/test/gtest_repeat_test.cc000066400000000000000000000200011353342203500224250ustar00rootroot00000000000000// Copyright 2008, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: wan@google.com (Zhanyong Wan) // Tests the --gtest_repeat=number flag. #include #include #include "gtest/gtest.h" // Indicates that this translation unit is part of Google Test's // implementation. It must come before gtest-internal-inl.h is // included, or there will be a compiler error. This trick is to // prevent a user from accidentally including gtest-internal-inl.h in // his code. #define GTEST_IMPLEMENTATION_ 1 #include "src/gtest-internal-inl.h" #undef GTEST_IMPLEMENTATION_ namespace testing { GTEST_DECLARE_string_(death_test_style); GTEST_DECLARE_string_(filter); GTEST_DECLARE_int32_(repeat); } // namespace testing using testing::GTEST_FLAG(death_test_style); using testing::GTEST_FLAG(filter); using testing::GTEST_FLAG(repeat); namespace { // We need this when we are testing Google Test itself and therefore // cannot use Google Test assertions. #define GTEST_CHECK_INT_EQ_(expected, actual) \ do {\ const int expected_val = (expected);\ const int actual_val = (actual);\ if (::testing::internal::IsTrue(expected_val != actual_val)) {\ ::std::cout << "Value of: " #actual "\n"\ << " Actual: " << actual_val << "\n"\ << "Expected: " #expected "\n"\ << "Which is: " << expected_val << "\n";\ ::testing::internal::posix::Abort();\ }\ } while (::testing::internal::AlwaysFalse()) // Used for verifying that global environment set-up and tear-down are // inside the gtest_repeat loop. int g_environment_set_up_count = 0; int g_environment_tear_down_count = 0; class MyEnvironment : public testing::Environment { public: MyEnvironment() {} virtual void SetUp() { g_environment_set_up_count++; } virtual void TearDown() { g_environment_tear_down_count++; } }; // A test that should fail. int g_should_fail_count = 0; TEST(FooTest, ShouldFail) { g_should_fail_count++; EXPECT_EQ(0, 1) << "Expected failure."; } // A test that should pass. int g_should_pass_count = 0; TEST(FooTest, ShouldPass) { g_should_pass_count++; } // A test that contains a thread-safe death test and a fast death // test. It should pass. int g_death_test_count = 0; TEST(BarDeathTest, ThreadSafeAndFast) { g_death_test_count++; GTEST_FLAG(death_test_style) = "threadsafe"; EXPECT_DEATH_IF_SUPPORTED(::testing::internal::posix::Abort(), ""); GTEST_FLAG(death_test_style) = "fast"; EXPECT_DEATH_IF_SUPPORTED(::testing::internal::posix::Abort(), ""); } #if GTEST_HAS_PARAM_TEST int g_param_test_count = 0; const int kNumberOfParamTests = 10; class MyParamTest : public testing::TestWithParam {}; TEST_P(MyParamTest, ShouldPass) { // TODO(vladl@google.com): Make parameter value checking robust // WRT order of tests. GTEST_CHECK_INT_EQ_(g_param_test_count % kNumberOfParamTests, GetParam()); g_param_test_count++; } INSTANTIATE_TEST_CASE_P(MyParamSequence, MyParamTest, testing::Range(0, kNumberOfParamTests)); #endif // GTEST_HAS_PARAM_TEST // Resets the count for each test. void ResetCounts() { g_environment_set_up_count = 0; g_environment_tear_down_count = 0; g_should_fail_count = 0; g_should_pass_count = 0; g_death_test_count = 0; #if GTEST_HAS_PARAM_TEST g_param_test_count = 0; #endif // GTEST_HAS_PARAM_TEST } // Checks that the count for each test is expected. void CheckCounts(int expected) { GTEST_CHECK_INT_EQ_(expected, g_environment_set_up_count); GTEST_CHECK_INT_EQ_(expected, g_environment_tear_down_count); GTEST_CHECK_INT_EQ_(expected, g_should_fail_count); GTEST_CHECK_INT_EQ_(expected, g_should_pass_count); GTEST_CHECK_INT_EQ_(expected, g_death_test_count); #if GTEST_HAS_PARAM_TEST GTEST_CHECK_INT_EQ_(expected * kNumberOfParamTests, g_param_test_count); #endif // GTEST_HAS_PARAM_TEST } // Tests the behavior of Google Test when --gtest_repeat is not specified. void TestRepeatUnspecified() { ResetCounts(); GTEST_CHECK_INT_EQ_(1, RUN_ALL_TESTS()); CheckCounts(1); } // Tests the behavior of Google Test when --gtest_repeat has the given value. void TestRepeat(int repeat) { GTEST_FLAG(repeat) = repeat; ResetCounts(); GTEST_CHECK_INT_EQ_(repeat > 0 ? 1 : 0, RUN_ALL_TESTS()); CheckCounts(repeat); } // Tests using --gtest_repeat when --gtest_filter specifies an empty // set of tests. void TestRepeatWithEmptyFilter(int repeat) { GTEST_FLAG(repeat) = repeat; GTEST_FLAG(filter) = "None"; ResetCounts(); GTEST_CHECK_INT_EQ_(0, RUN_ALL_TESTS()); CheckCounts(0); } // Tests using --gtest_repeat when --gtest_filter specifies a set of // successful tests. void TestRepeatWithFilterForSuccessfulTests(int repeat) { GTEST_FLAG(repeat) = repeat; GTEST_FLAG(filter) = "*-*ShouldFail"; ResetCounts(); GTEST_CHECK_INT_EQ_(0, RUN_ALL_TESTS()); GTEST_CHECK_INT_EQ_(repeat, g_environment_set_up_count); GTEST_CHECK_INT_EQ_(repeat, g_environment_tear_down_count); GTEST_CHECK_INT_EQ_(0, g_should_fail_count); GTEST_CHECK_INT_EQ_(repeat, g_should_pass_count); GTEST_CHECK_INT_EQ_(repeat, g_death_test_count); #if GTEST_HAS_PARAM_TEST GTEST_CHECK_INT_EQ_(repeat * kNumberOfParamTests, g_param_test_count); #endif // GTEST_HAS_PARAM_TEST } // Tests using --gtest_repeat when --gtest_filter specifies a set of // failed tests. void TestRepeatWithFilterForFailedTests(int repeat) { GTEST_FLAG(repeat) = repeat; GTEST_FLAG(filter) = "*ShouldFail"; ResetCounts(); GTEST_CHECK_INT_EQ_(1, RUN_ALL_TESTS()); GTEST_CHECK_INT_EQ_(repeat, g_environment_set_up_count); GTEST_CHECK_INT_EQ_(repeat, g_environment_tear_down_count); GTEST_CHECK_INT_EQ_(repeat, g_should_fail_count); GTEST_CHECK_INT_EQ_(0, g_should_pass_count); GTEST_CHECK_INT_EQ_(0, g_death_test_count); #if GTEST_HAS_PARAM_TEST GTEST_CHECK_INT_EQ_(0, g_param_test_count); #endif // GTEST_HAS_PARAM_TEST } } // namespace int main(int argc, char **argv) { testing::InitGoogleTest(&argc, argv); testing::AddGlobalTestEnvironment(new MyEnvironment); TestRepeatUnspecified(); TestRepeat(0); TestRepeat(1); TestRepeat(5); TestRepeatWithEmptyFilter(2); TestRepeatWithEmptyFilter(3); TestRepeatWithFilterForSuccessfulTests(3); TestRepeatWithFilterForFailedTests(4); // It would be nice to verify that the tests indeed loop forever // when GTEST_FLAG(repeat) is negative, but this test will be quite // complicated to write. Since this flag is for interactive // debugging only and doesn't affect the normal test result, such a // test would be an overkill. printf("PASS\n"); return 0; } dlt-daemon-2.18.4/gtest-1.7.0/test/gtest_shuffle_test.py000077500000000000000000000304051353342203500226600ustar00rootroot00000000000000#!/usr/bin/env python # # Copyright 2009 Google Inc. All Rights Reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above # copyright notice, this list of conditions and the following disclaimer # in the documentation and/or other materials provided with the # distribution. # * Neither the name of Google Inc. nor the names of its # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. """Verifies that test shuffling works.""" __author__ = 'wan@google.com (Zhanyong Wan)' import os import gtest_test_utils # Command to run the gtest_shuffle_test_ program. COMMAND = gtest_test_utils.GetTestExecutablePath('gtest_shuffle_test_') # The environment variables for test sharding. TOTAL_SHARDS_ENV_VAR = 'GTEST_TOTAL_SHARDS' SHARD_INDEX_ENV_VAR = 'GTEST_SHARD_INDEX' TEST_FILTER = 'A*.A:A*.B:C*' ALL_TESTS = [] ACTIVE_TESTS = [] FILTERED_TESTS = [] SHARDED_TESTS = [] SHUFFLED_ALL_TESTS = [] SHUFFLED_ACTIVE_TESTS = [] SHUFFLED_FILTERED_TESTS = [] SHUFFLED_SHARDED_TESTS = [] def AlsoRunDisabledTestsFlag(): return '--gtest_also_run_disabled_tests' def FilterFlag(test_filter): return '--gtest_filter=%s' % (test_filter,) def RepeatFlag(n): return '--gtest_repeat=%s' % (n,) def ShuffleFlag(): return '--gtest_shuffle' def RandomSeedFlag(n): return '--gtest_random_seed=%s' % (n,) def RunAndReturnOutput(extra_env, args): """Runs the test program and returns its output.""" environ_copy = os.environ.copy() environ_copy.update(extra_env) return gtest_test_utils.Subprocess([COMMAND] + args, env=environ_copy).output def GetTestsForAllIterations(extra_env, args): """Runs the test program and returns a list of test lists. Args: extra_env: a map from environment variables to their values args: command line flags to pass to gtest_shuffle_test_ Returns: A list where the i-th element is the list of tests run in the i-th test iteration. """ test_iterations = [] for line in RunAndReturnOutput(extra_env, args).split('\n'): if line.startswith('----'): tests = [] test_iterations.append(tests) elif line.strip(): tests.append(line.strip()) # 'TestCaseName.TestName' return test_iterations def GetTestCases(tests): """Returns a list of test cases in the given full test names. Args: tests: a list of full test names Returns: A list of test cases from 'tests', in their original order. Consecutive duplicates are removed. """ test_cases = [] for test in tests: test_case = test.split('.')[0] if not test_case in test_cases: test_cases.append(test_case) return test_cases def CalculateTestLists(): """Calculates the list of tests run under different flags.""" if not ALL_TESTS: ALL_TESTS.extend( GetTestsForAllIterations({}, [AlsoRunDisabledTestsFlag()])[0]) if not ACTIVE_TESTS: ACTIVE_TESTS.extend(GetTestsForAllIterations({}, [])[0]) if not FILTERED_TESTS: FILTERED_TESTS.extend( GetTestsForAllIterations({}, [FilterFlag(TEST_FILTER)])[0]) if not SHARDED_TESTS: SHARDED_TESTS.extend( GetTestsForAllIterations({TOTAL_SHARDS_ENV_VAR: '3', SHARD_INDEX_ENV_VAR: '1'}, [])[0]) if not SHUFFLED_ALL_TESTS: SHUFFLED_ALL_TESTS.extend(GetTestsForAllIterations( {}, [AlsoRunDisabledTestsFlag(), ShuffleFlag(), RandomSeedFlag(1)])[0]) if not SHUFFLED_ACTIVE_TESTS: SHUFFLED_ACTIVE_TESTS.extend(GetTestsForAllIterations( {}, [ShuffleFlag(), RandomSeedFlag(1)])[0]) if not SHUFFLED_FILTERED_TESTS: SHUFFLED_FILTERED_TESTS.extend(GetTestsForAllIterations( {}, [ShuffleFlag(), RandomSeedFlag(1), FilterFlag(TEST_FILTER)])[0]) if not SHUFFLED_SHARDED_TESTS: SHUFFLED_SHARDED_TESTS.extend( GetTestsForAllIterations({TOTAL_SHARDS_ENV_VAR: '3', SHARD_INDEX_ENV_VAR: '1'}, [ShuffleFlag(), RandomSeedFlag(1)])[0]) class GTestShuffleUnitTest(gtest_test_utils.TestCase): """Tests test shuffling.""" def setUp(self): CalculateTestLists() def testShufflePreservesNumberOfTests(self): self.assertEqual(len(ALL_TESTS), len(SHUFFLED_ALL_TESTS)) self.assertEqual(len(ACTIVE_TESTS), len(SHUFFLED_ACTIVE_TESTS)) self.assertEqual(len(FILTERED_TESTS), len(SHUFFLED_FILTERED_TESTS)) self.assertEqual(len(SHARDED_TESTS), len(SHUFFLED_SHARDED_TESTS)) def testShuffleChangesTestOrder(self): self.assert_(SHUFFLED_ALL_TESTS != ALL_TESTS, SHUFFLED_ALL_TESTS) self.assert_(SHUFFLED_ACTIVE_TESTS != ACTIVE_TESTS, SHUFFLED_ACTIVE_TESTS) self.assert_(SHUFFLED_FILTERED_TESTS != FILTERED_TESTS, SHUFFLED_FILTERED_TESTS) self.assert_(SHUFFLED_SHARDED_TESTS != SHARDED_TESTS, SHUFFLED_SHARDED_TESTS) def testShuffleChangesTestCaseOrder(self): self.assert_(GetTestCases(SHUFFLED_ALL_TESTS) != GetTestCases(ALL_TESTS), GetTestCases(SHUFFLED_ALL_TESTS)) self.assert_( GetTestCases(SHUFFLED_ACTIVE_TESTS) != GetTestCases(ACTIVE_TESTS), GetTestCases(SHUFFLED_ACTIVE_TESTS)) self.assert_( GetTestCases(SHUFFLED_FILTERED_TESTS) != GetTestCases(FILTERED_TESTS), GetTestCases(SHUFFLED_FILTERED_TESTS)) self.assert_( GetTestCases(SHUFFLED_SHARDED_TESTS) != GetTestCases(SHARDED_TESTS), GetTestCases(SHUFFLED_SHARDED_TESTS)) def testShuffleDoesNotRepeatTest(self): for test in SHUFFLED_ALL_TESTS: self.assertEqual(1, SHUFFLED_ALL_TESTS.count(test), '%s appears more than once' % (test,)) for test in SHUFFLED_ACTIVE_TESTS: self.assertEqual(1, SHUFFLED_ACTIVE_TESTS.count(test), '%s appears more than once' % (test,)) for test in SHUFFLED_FILTERED_TESTS: self.assertEqual(1, SHUFFLED_FILTERED_TESTS.count(test), '%s appears more than once' % (test,)) for test in SHUFFLED_SHARDED_TESTS: self.assertEqual(1, SHUFFLED_SHARDED_TESTS.count(test), '%s appears more than once' % (test,)) def testShuffleDoesNotCreateNewTest(self): for test in SHUFFLED_ALL_TESTS: self.assert_(test in ALL_TESTS, '%s is an invalid test' % (test,)) for test in SHUFFLED_ACTIVE_TESTS: self.assert_(test in ACTIVE_TESTS, '%s is an invalid test' % (test,)) for test in SHUFFLED_FILTERED_TESTS: self.assert_(test in FILTERED_TESTS, '%s is an invalid test' % (test,)) for test in SHUFFLED_SHARDED_TESTS: self.assert_(test in SHARDED_TESTS, '%s is an invalid test' % (test,)) def testShuffleIncludesAllTests(self): for test in ALL_TESTS: self.assert_(test in SHUFFLED_ALL_TESTS, '%s is missing' % (test,)) for test in ACTIVE_TESTS: self.assert_(test in SHUFFLED_ACTIVE_TESTS, '%s is missing' % (test,)) for test in FILTERED_TESTS: self.assert_(test in SHUFFLED_FILTERED_TESTS, '%s is missing' % (test,)) for test in SHARDED_TESTS: self.assert_(test in SHUFFLED_SHARDED_TESTS, '%s is missing' % (test,)) def testShuffleLeavesDeathTestsAtFront(self): non_death_test_found = False for test in SHUFFLED_ACTIVE_TESTS: if 'DeathTest.' in test: self.assert_(not non_death_test_found, '%s appears after a non-death test' % (test,)) else: non_death_test_found = True def _VerifyTestCasesDoNotInterleave(self, tests): test_cases = [] for test in tests: [test_case, _] = test.split('.') if test_cases and test_cases[-1] != test_case: test_cases.append(test_case) self.assertEqual(1, test_cases.count(test_case), 'Test case %s is not grouped together in %s' % (test_case, tests)) def testShuffleDoesNotInterleaveTestCases(self): self._VerifyTestCasesDoNotInterleave(SHUFFLED_ALL_TESTS) self._VerifyTestCasesDoNotInterleave(SHUFFLED_ACTIVE_TESTS) self._VerifyTestCasesDoNotInterleave(SHUFFLED_FILTERED_TESTS) self._VerifyTestCasesDoNotInterleave(SHUFFLED_SHARDED_TESTS) def testShuffleRestoresOrderAfterEachIteration(self): # Get the test lists in all 3 iterations, using random seed 1, 2, # and 3 respectively. Google Test picks a different seed in each # iteration, and this test depends on the current implementation # picking successive numbers. This dependency is not ideal, but # makes the test much easier to write. [tests_in_iteration1, tests_in_iteration2, tests_in_iteration3] = ( GetTestsForAllIterations( {}, [ShuffleFlag(), RandomSeedFlag(1), RepeatFlag(3)])) # Make sure running the tests with random seed 1 gets the same # order as in iteration 1 above. [tests_with_seed1] = GetTestsForAllIterations( {}, [ShuffleFlag(), RandomSeedFlag(1)]) self.assertEqual(tests_in_iteration1, tests_with_seed1) # Make sure running the tests with random seed 2 gets the same # order as in iteration 2 above. Success means that Google Test # correctly restores the test order before re-shuffling at the # beginning of iteration 2. [tests_with_seed2] = GetTestsForAllIterations( {}, [ShuffleFlag(), RandomSeedFlag(2)]) self.assertEqual(tests_in_iteration2, tests_with_seed2) # Make sure running the tests with random seed 3 gets the same # order as in iteration 3 above. Success means that Google Test # correctly restores the test order before re-shuffling at the # beginning of iteration 3. [tests_with_seed3] = GetTestsForAllIterations( {}, [ShuffleFlag(), RandomSeedFlag(3)]) self.assertEqual(tests_in_iteration3, tests_with_seed3) def testShuffleGeneratesNewOrderInEachIteration(self): [tests_in_iteration1, tests_in_iteration2, tests_in_iteration3] = ( GetTestsForAllIterations( {}, [ShuffleFlag(), RandomSeedFlag(1), RepeatFlag(3)])) self.assert_(tests_in_iteration1 != tests_in_iteration2, tests_in_iteration1) self.assert_(tests_in_iteration1 != tests_in_iteration3, tests_in_iteration1) self.assert_(tests_in_iteration2 != tests_in_iteration3, tests_in_iteration2) def testShuffleShardedTestsPreservesPartition(self): # If we run M tests on N shards, the same M tests should be run in # total, regardless of the random seeds used by the shards. [tests1] = GetTestsForAllIterations({TOTAL_SHARDS_ENV_VAR: '3', SHARD_INDEX_ENV_VAR: '0'}, [ShuffleFlag(), RandomSeedFlag(1)]) [tests2] = GetTestsForAllIterations({TOTAL_SHARDS_ENV_VAR: '3', SHARD_INDEX_ENV_VAR: '1'}, [ShuffleFlag(), RandomSeedFlag(20)]) [tests3] = GetTestsForAllIterations({TOTAL_SHARDS_ENV_VAR: '3', SHARD_INDEX_ENV_VAR: '2'}, [ShuffleFlag(), RandomSeedFlag(25)]) sorted_sharded_tests = tests1 + tests2 + tests3 sorted_sharded_tests.sort() sorted_active_tests = [] sorted_active_tests.extend(ACTIVE_TESTS) sorted_active_tests.sort() self.assertEqual(sorted_active_tests, sorted_sharded_tests) if __name__ == '__main__': gtest_test_utils.Main() dlt-daemon-2.18.4/gtest-1.7.0/test/gtest_shuffle_test_.cc000066400000000000000000000063521353342203500227550ustar00rootroot00000000000000// Copyright 2009, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: wan@google.com (Zhanyong Wan) // Verifies that test shuffling works. #include "gtest/gtest.h" namespace { using ::testing::EmptyTestEventListener; using ::testing::InitGoogleTest; using ::testing::Message; using ::testing::Test; using ::testing::TestEventListeners; using ::testing::TestInfo; using ::testing::UnitTest; using ::testing::internal::scoped_ptr; // The test methods are empty, as the sole purpose of this program is // to print the test names before/after shuffling. class A : public Test {}; TEST_F(A, A) {} TEST_F(A, B) {} TEST(ADeathTest, A) {} TEST(ADeathTest, B) {} TEST(ADeathTest, C) {} TEST(B, A) {} TEST(B, B) {} TEST(B, C) {} TEST(B, DISABLED_D) {} TEST(B, DISABLED_E) {} TEST(BDeathTest, A) {} TEST(BDeathTest, B) {} TEST(C, A) {} TEST(C, B) {} TEST(C, C) {} TEST(C, DISABLED_D) {} TEST(CDeathTest, A) {} TEST(DISABLED_D, A) {} TEST(DISABLED_D, DISABLED_B) {} // This printer prints the full test names only, starting each test // iteration with a "----" marker. class TestNamePrinter : public EmptyTestEventListener { public: virtual void OnTestIterationStart(const UnitTest& /* unit_test */, int /* iteration */) { printf("----\n"); } virtual void OnTestStart(const TestInfo& test_info) { printf("%s.%s\n", test_info.test_case_name(), test_info.name()); } }; } // namespace int main(int argc, char **argv) { InitGoogleTest(&argc, argv); // Replaces the default printer with TestNamePrinter, which prints // the test name only. TestEventListeners& listeners = UnitTest::GetInstance()->listeners(); delete listeners.Release(listeners.default_result_printer()); listeners.Append(new TestNamePrinter); return RUN_ALL_TESTS(); } dlt-daemon-2.18.4/gtest-1.7.0/test/gtest_sole_header_test.cc000066400000000000000000000042551353342203500234340ustar00rootroot00000000000000// Copyright 2008, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: mheule@google.com (Markus Heule) // // This test verifies that it's possible to use Google Test by including // the gtest.h header file alone. #include "gtest/gtest.h" namespace { void Subroutine() { EXPECT_EQ(42, 42); } TEST(NoFatalFailureTest, ExpectNoFatalFailure) { EXPECT_NO_FATAL_FAILURE(;); EXPECT_NO_FATAL_FAILURE(SUCCEED()); EXPECT_NO_FATAL_FAILURE(Subroutine()); EXPECT_NO_FATAL_FAILURE({ SUCCEED(); }); } TEST(NoFatalFailureTest, AssertNoFatalFailure) { ASSERT_NO_FATAL_FAILURE(;); ASSERT_NO_FATAL_FAILURE(SUCCEED()); ASSERT_NO_FATAL_FAILURE(Subroutine()); ASSERT_NO_FATAL_FAILURE({ SUCCEED(); }); } } // namespace dlt-daemon-2.18.4/gtest-1.7.0/test/gtest_stress_test.cc000066400000000000000000000226511353342203500225050ustar00rootroot00000000000000// Copyright 2007, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: wan@google.com (Zhanyong Wan) // Tests that SCOPED_TRACE() and various Google Test assertions can be // used in a large number of threads concurrently. #include "gtest/gtest.h" #include #include // We must define this macro in order to #include // gtest-internal-inl.h. This is how Google Test prevents a user from // accidentally depending on its internal implementation. #define GTEST_IMPLEMENTATION_ 1 #include "src/gtest-internal-inl.h" #undef GTEST_IMPLEMENTATION_ #if GTEST_IS_THREADSAFE namespace testing { namespace { using internal::Notification; using internal::TestPropertyKeyIs; using internal::ThreadWithParam; using internal::scoped_ptr; // In order to run tests in this file, for platforms where Google Test is // thread safe, implement ThreadWithParam. See the description of its API // in gtest-port.h, where it is defined for already supported platforms. // How many threads to create? const int kThreadCount = 50; std::string IdToKey(int id, const char* suffix) { Message key; key << "key_" << id << "_" << suffix; return key.GetString(); } std::string IdToString(int id) { Message id_message; id_message << id; return id_message.GetString(); } void ExpectKeyAndValueWereRecordedForId( const std::vector& properties, int id, const char* suffix) { TestPropertyKeyIs matches_key(IdToKey(id, suffix).c_str()); const std::vector::const_iterator property = std::find_if(properties.begin(), properties.end(), matches_key); ASSERT_TRUE(property != properties.end()) << "expecting " << suffix << " value for id " << id; EXPECT_STREQ(IdToString(id).c_str(), property->value()); } // Calls a large number of Google Test assertions, where exactly one of them // will fail. void ManyAsserts(int id) { GTEST_LOG_(INFO) << "Thread #" << id << " running..."; SCOPED_TRACE(Message() << "Thread #" << id); for (int i = 0; i < kThreadCount; i++) { SCOPED_TRACE(Message() << "Iteration #" << i); // A bunch of assertions that should succeed. EXPECT_TRUE(true); ASSERT_FALSE(false) << "This shouldn't fail."; EXPECT_STREQ("a", "a"); ASSERT_LE(5, 6); EXPECT_EQ(i, i) << "This shouldn't fail."; // RecordProperty() should interact safely with other threads as well. // The shared_key forces property updates. Test::RecordProperty(IdToKey(id, "string").c_str(), IdToString(id).c_str()); Test::RecordProperty(IdToKey(id, "int").c_str(), id); Test::RecordProperty("shared_key", IdToString(id).c_str()); // This assertion should fail kThreadCount times per thread. It // is for testing whether Google Test can handle failed assertions in a // multi-threaded context. EXPECT_LT(i, 0) << "This should always fail."; } } void CheckTestFailureCount(int expected_failures) { const TestInfo* const info = UnitTest::GetInstance()->current_test_info(); const TestResult* const result = info->result(); GTEST_CHECK_(expected_failures == result->total_part_count()) << "Logged " << result->total_part_count() << " failures " << " vs. " << expected_failures << " expected"; } // Tests using SCOPED_TRACE() and Google Test assertions in many threads // concurrently. TEST(StressTest, CanUseScopedTraceAndAssertionsInManyThreads) { { scoped_ptr > threads[kThreadCount]; Notification threads_can_start; for (int i = 0; i != kThreadCount; i++) threads[i].reset(new ThreadWithParam(&ManyAsserts, i, &threads_can_start)); threads_can_start.Notify(); // Blocks until all the threads are done. for (int i = 0; i != kThreadCount; i++) threads[i]->Join(); } // Ensures that kThreadCount*kThreadCount failures have been reported. const TestInfo* const info = UnitTest::GetInstance()->current_test_info(); const TestResult* const result = info->result(); std::vector properties; // We have no access to the TestResult's list of properties but we can // copy them one by one. for (int i = 0; i < result->test_property_count(); ++i) properties.push_back(result->GetTestProperty(i)); EXPECT_EQ(kThreadCount * 2 + 1, result->test_property_count()) << "String and int values recorded on each thread, " << "as well as one shared_key"; for (int i = 0; i < kThreadCount; ++i) { ExpectKeyAndValueWereRecordedForId(properties, i, "string"); ExpectKeyAndValueWereRecordedForId(properties, i, "int"); } CheckTestFailureCount(kThreadCount*kThreadCount); } void FailingThread(bool is_fatal) { if (is_fatal) FAIL() << "Fatal failure in some other thread. " << "(This failure is expected.)"; else ADD_FAILURE() << "Non-fatal failure in some other thread. " << "(This failure is expected.)"; } void GenerateFatalFailureInAnotherThread(bool is_fatal) { ThreadWithParam thread(&FailingThread, is_fatal, NULL); thread.Join(); } TEST(NoFatalFailureTest, ExpectNoFatalFailureIgnoresFailuresInOtherThreads) { EXPECT_NO_FATAL_FAILURE(GenerateFatalFailureInAnotherThread(true)); // We should only have one failure (the one from // GenerateFatalFailureInAnotherThread()), since the EXPECT_NO_FATAL_FAILURE // should succeed. CheckTestFailureCount(1); } void AssertNoFatalFailureIgnoresFailuresInOtherThreads() { ASSERT_NO_FATAL_FAILURE(GenerateFatalFailureInAnotherThread(true)); } TEST(NoFatalFailureTest, AssertNoFatalFailureIgnoresFailuresInOtherThreads) { // Using a subroutine, to make sure, that the test continues. AssertNoFatalFailureIgnoresFailuresInOtherThreads(); // We should only have one failure (the one from // GenerateFatalFailureInAnotherThread()), since the EXPECT_NO_FATAL_FAILURE // should succeed. CheckTestFailureCount(1); } TEST(FatalFailureTest, ExpectFatalFailureIgnoresFailuresInOtherThreads) { // This statement should fail, since the current thread doesn't generate a // fatal failure, only another one does. EXPECT_FATAL_FAILURE(GenerateFatalFailureInAnotherThread(true), "expected"); CheckTestFailureCount(2); } TEST(FatalFailureOnAllThreadsTest, ExpectFatalFailureOnAllThreads) { // This statement should succeed, because failures in all threads are // considered. EXPECT_FATAL_FAILURE_ON_ALL_THREADS( GenerateFatalFailureInAnotherThread(true), "expected"); CheckTestFailureCount(0); // We need to add a failure, because main() checks that there are failures. // But when only this test is run, we shouldn't have any failures. ADD_FAILURE() << "This is an expected non-fatal failure."; } TEST(NonFatalFailureTest, ExpectNonFatalFailureIgnoresFailuresInOtherThreads) { // This statement should fail, since the current thread doesn't generate a // fatal failure, only another one does. EXPECT_NONFATAL_FAILURE(GenerateFatalFailureInAnotherThread(false), "expected"); CheckTestFailureCount(2); } TEST(NonFatalFailureOnAllThreadsTest, ExpectNonFatalFailureOnAllThreads) { // This statement should succeed, because failures in all threads are // considered. EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS( GenerateFatalFailureInAnotherThread(false), "expected"); CheckTestFailureCount(0); // We need to add a failure, because main() checks that there are failures, // But when only this test is run, we shouldn't have any failures. ADD_FAILURE() << "This is an expected non-fatal failure."; } } // namespace } // namespace testing int main(int argc, char **argv) { testing::InitGoogleTest(&argc, argv); const int result = RUN_ALL_TESTS(); // Expected to fail. GTEST_CHECK_(result == 1) << "RUN_ALL_TESTS() did not fail as expected"; printf("\nPASS\n"); return 0; } #else TEST(StressTest, DISABLED_ThreadSafetyTestsAreSkippedWhenGoogleTestIsNotThreadSafe) { } int main(int argc, char **argv) { testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } #endif // GTEST_IS_THREADSAFE dlt-daemon-2.18.4/gtest-1.7.0/test/gtest_test_utils.py000077500000000000000000000250741353342203500223720ustar00rootroot00000000000000#!/usr/bin/env python # # Copyright 2006, Google Inc. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above # copyright notice, this list of conditions and the following disclaimer # in the documentation and/or other materials provided with the # distribution. # * Neither the name of Google Inc. nor the names of its # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. """Unit test utilities for Google C++ Testing Framework.""" __author__ = 'wan@google.com (Zhanyong Wan)' import atexit import os import shutil import sys import tempfile import unittest _test_module = unittest # Suppresses the 'Import not at the top of the file' lint complaint. # pylint: disable-msg=C6204 try: import subprocess _SUBPROCESS_MODULE_AVAILABLE = True except: import popen2 _SUBPROCESS_MODULE_AVAILABLE = False # pylint: enable-msg=C6204 GTEST_OUTPUT_VAR_NAME = 'GTEST_OUTPUT' IS_WINDOWS = os.name == 'nt' IS_CYGWIN = os.name == 'posix' and 'CYGWIN' in os.uname()[0] # The environment variable for specifying the path to the premature-exit file. PREMATURE_EXIT_FILE_ENV_VAR = 'TEST_PREMATURE_EXIT_FILE' environ = os.environ.copy() def SetEnvVar(env_var, value): """Sets/unsets an environment variable to a given value.""" if value is not None: environ[env_var] = value elif env_var in environ: del environ[env_var] # Here we expose a class from a particular module, depending on the # environment. The comment suppresses the 'Invalid variable name' lint # complaint. TestCase = _test_module.TestCase # pylint: disable-msg=C6409 # Initially maps a flag to its default value. After # _ParseAndStripGTestFlags() is called, maps a flag to its actual value. _flag_map = {'source_dir': os.path.dirname(sys.argv[0]), 'build_dir': os.path.dirname(sys.argv[0])} _gtest_flags_are_parsed = False def _ParseAndStripGTestFlags(argv): """Parses and strips Google Test flags from argv. This is idempotent.""" # Suppresses the lint complaint about a global variable since we need it # here to maintain module-wide state. global _gtest_flags_are_parsed # pylint: disable-msg=W0603 if _gtest_flags_are_parsed: return _gtest_flags_are_parsed = True for flag in _flag_map: # The environment variable overrides the default value. if flag.upper() in os.environ: _flag_map[flag] = os.environ[flag.upper()] # The command line flag overrides the environment variable. i = 1 # Skips the program name. while i < len(argv): prefix = '--' + flag + '=' if argv[i].startswith(prefix): _flag_map[flag] = argv[i][len(prefix):] del argv[i] break else: # We don't increment i in case we just found a --gtest_* flag # and removed it from argv. i += 1 def GetFlag(flag): """Returns the value of the given flag.""" # In case GetFlag() is called before Main(), we always call # _ParseAndStripGTestFlags() here to make sure the --gtest_* flags # are parsed. _ParseAndStripGTestFlags(sys.argv) return _flag_map[flag] def GetSourceDir(): """Returns the absolute path of the directory where the .py files are.""" return os.path.abspath(GetFlag('source_dir')) def GetBuildDir(): """Returns the absolute path of the directory where the test binaries are.""" return os.path.abspath(GetFlag('build_dir')) _temp_dir = None def _RemoveTempDir(): if _temp_dir: shutil.rmtree(_temp_dir, ignore_errors=True) atexit.register(_RemoveTempDir) def GetTempDir(): """Returns a directory for temporary files.""" global _temp_dir if not _temp_dir: _temp_dir = tempfile.mkdtemp() return _temp_dir def GetTestExecutablePath(executable_name, build_dir=None): """Returns the absolute path of the test binary given its name. The function will print a message and abort the program if the resulting file doesn't exist. Args: executable_name: name of the test binary that the test script runs. build_dir: directory where to look for executables, by default the result of GetBuildDir(). Returns: The absolute path of the test binary. """ path = os.path.abspath(os.path.join(build_dir or GetBuildDir(), executable_name)) if (IS_WINDOWS or IS_CYGWIN) and not path.endswith('.exe'): path += '.exe' if not os.path.exists(path): message = ( 'Unable to find the test binary. Please make sure to provide path\n' 'to the binary via the --build_dir flag or the BUILD_DIR\n' 'environment variable.') print >> sys.stderr, message sys.exit(1) return path def GetExitStatus(exit_code): """Returns the argument to exit(), or -1 if exit() wasn't called. Args: exit_code: the result value of os.system(command). """ if os.name == 'nt': # On Windows, os.WEXITSTATUS() doesn't work and os.system() returns # the argument to exit() directly. return exit_code else: # On Unix, os.WEXITSTATUS() must be used to extract the exit status # from the result of os.system(). if os.WIFEXITED(exit_code): return os.WEXITSTATUS(exit_code) else: return -1 class Subprocess: def __init__(self, command, working_dir=None, capture_stderr=True, env=None): """Changes into a specified directory, if provided, and executes a command. Restores the old directory afterwards. Args: command: The command to run, in the form of sys.argv. working_dir: The directory to change into. capture_stderr: Determines whether to capture stderr in the output member or to discard it. env: Dictionary with environment to pass to the subprocess. Returns: An object that represents outcome of the executed process. It has the following attributes: terminated_by_signal True iff the child process has been terminated by a signal. signal Sygnal that terminated the child process. exited True iff the child process exited normally. exit_code The code with which the child process exited. output Child process's stdout and stderr output combined in a string. """ # The subprocess module is the preferrable way of running programs # since it is available and behaves consistently on all platforms, # including Windows. But it is only available starting in python 2.4. # In earlier python versions, we revert to the popen2 module, which is # available in python 2.0 and later but doesn't provide required # functionality (Popen4) under Windows. This allows us to support Mac # OS X 10.4 Tiger, which has python 2.3 installed. if _SUBPROCESS_MODULE_AVAILABLE: if capture_stderr: stderr = subprocess.STDOUT else: stderr = subprocess.PIPE p = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=stderr, cwd=working_dir, universal_newlines=True, env=env) # communicate returns a tuple with the file obect for the child's # output. self.output = p.communicate()[0] self._return_code = p.returncode else: old_dir = os.getcwd() def _ReplaceEnvDict(dest, src): # Changes made by os.environ.clear are not inheritable by child # processes until Python 2.6. To produce inheritable changes we have # to delete environment items with the del statement. for key in dest.keys(): del dest[key] dest.update(src) # When 'env' is not None, backup the environment variables and replace # them with the passed 'env'. When 'env' is None, we simply use the # current 'os.environ' for compatibility with the subprocess.Popen # semantics used above. if env is not None: old_environ = os.environ.copy() _ReplaceEnvDict(os.environ, env) try: if working_dir is not None: os.chdir(working_dir) if capture_stderr: p = popen2.Popen4(command) else: p = popen2.Popen3(command) p.tochild.close() self.output = p.fromchild.read() ret_code = p.wait() finally: os.chdir(old_dir) # Restore the old environment variables # if they were replaced. if env is not None: _ReplaceEnvDict(os.environ, old_environ) # Converts ret_code to match the semantics of # subprocess.Popen.returncode. if os.WIFSIGNALED(ret_code): self._return_code = -os.WTERMSIG(ret_code) else: # os.WIFEXITED(ret_code) should return True here. self._return_code = os.WEXITSTATUS(ret_code) if self._return_code < 0: self.terminated_by_signal = True self.exited = False self.signal = -self._return_code else: self.terminated_by_signal = False self.exited = True self.exit_code = self._return_code def Main(): """Runs the unit test.""" # We must call _ParseAndStripGTestFlags() before calling # unittest.main(). Otherwise the latter will be confused by the # --gtest_* flags. _ParseAndStripGTestFlags(sys.argv) # The tested binaries should not be writing XML output files unless the # script explicitly instructs them to. # TODO(vladl@google.com): Move this into Subprocess when we implement # passing environment into it as a parameter. if GTEST_OUTPUT_VAR_NAME in os.environ: del os.environ[GTEST_OUTPUT_VAR_NAME] _test_module.main() dlt-daemon-2.18.4/gtest-1.7.0/test/gtest_throw_on_failure_ex_test.cc000066400000000000000000000065641353342203500252310ustar00rootroot00000000000000// Copyright 2009, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: wan@google.com (Zhanyong Wan) // Tests Google Test's throw-on-failure mode with exceptions enabled. #include "gtest/gtest.h" #include #include #include #include // Prints the given failure message and exits the program with // non-zero. We use this instead of a Google Test assertion to // indicate a failure, as the latter is been tested and cannot be // relied on. void Fail(const char* msg) { printf("FAILURE: %s\n", msg); fflush(stdout); exit(1); } // Tests that an assertion failure throws a subclass of // std::runtime_error. void TestFailureThrowsRuntimeError() { testing::GTEST_FLAG(throw_on_failure) = true; // A successful assertion shouldn't throw. try { EXPECT_EQ(3, 3); } catch(...) { Fail("A successful assertion wrongfully threw."); } // A failed assertion should throw a subclass of std::runtime_error. try { EXPECT_EQ(2, 3) << "Expected failure"; } catch(const std::runtime_error& e) { if (strstr(e.what(), "Expected failure") != NULL) return; printf("%s", "A failed assertion did throw an exception of the right type, " "but the message is incorrect. Instead of containing \"Expected " "failure\", it is:\n"); Fail(e.what()); } catch(...) { Fail("A failed assertion threw the wrong type of exception."); } Fail("A failed assertion should've thrown but didn't."); } int main(int argc, char** argv) { testing::InitGoogleTest(&argc, argv); // We want to ensure that people can use Google Test assertions in // other testing frameworks, as long as they initialize Google Test // properly and set the thrown-on-failure mode. Therefore, we don't // use Google Test's constructs for defining and running tests // (e.g. TEST and RUN_ALL_TESTS) here. TestFailureThrowsRuntimeError(); return 0; } dlt-daemon-2.18.4/gtest-1.7.0/test/gtest_throw_on_failure_test.py000077500000000000000000000132061353342203500245720ustar00rootroot00000000000000#!/usr/bin/env python # # Copyright 2009, Google Inc. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above # copyright notice, this list of conditions and the following disclaimer # in the documentation and/or other materials provided with the # distribution. # * Neither the name of Google Inc. nor the names of its # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. """Tests Google Test's throw-on-failure mode with exceptions disabled. This script invokes gtest_throw_on_failure_test_ (a program written with Google Test) with different environments and command line flags. """ __author__ = 'wan@google.com (Zhanyong Wan)' import os import gtest_test_utils # Constants. # The command line flag for enabling/disabling the throw-on-failure mode. THROW_ON_FAILURE = 'gtest_throw_on_failure' # Path to the gtest_throw_on_failure_test_ program, compiled with # exceptions disabled. EXE_PATH = gtest_test_utils.GetTestExecutablePath( 'gtest_throw_on_failure_test_') # Utilities. def SetEnvVar(env_var, value): """Sets an environment variable to a given value; unsets it when the given value is None. """ env_var = env_var.upper() if value is not None: os.environ[env_var] = value elif env_var in os.environ: del os.environ[env_var] def Run(command): """Runs a command; returns True/False if its exit code is/isn't 0.""" print 'Running "%s". . .' % ' '.join(command) p = gtest_test_utils.Subprocess(command) return p.exited and p.exit_code == 0 # The tests. TODO(wan@google.com): refactor the class to share common # logic with code in gtest_break_on_failure_unittest.py. class ThrowOnFailureTest(gtest_test_utils.TestCase): """Tests the throw-on-failure mode.""" def RunAndVerify(self, env_var_value, flag_value, should_fail): """Runs gtest_throw_on_failure_test_ and verifies that it does (or does not) exit with a non-zero code. Args: env_var_value: value of the GTEST_BREAK_ON_FAILURE environment variable; None if the variable should be unset. flag_value: value of the --gtest_break_on_failure flag; None if the flag should not be present. should_fail: True iff the program is expected to fail. """ SetEnvVar(THROW_ON_FAILURE, env_var_value) if env_var_value is None: env_var_value_msg = ' is not set' else: env_var_value_msg = '=' + env_var_value if flag_value is None: flag = '' elif flag_value == '0': flag = '--%s=0' % THROW_ON_FAILURE else: flag = '--%s' % THROW_ON_FAILURE command = [EXE_PATH] if flag: command.append(flag) if should_fail: should_or_not = 'should' else: should_or_not = 'should not' failed = not Run(command) SetEnvVar(THROW_ON_FAILURE, None) msg = ('when %s%s, an assertion failure in "%s" %s cause a non-zero ' 'exit code.' % (THROW_ON_FAILURE, env_var_value_msg, ' '.join(command), should_or_not)) self.assert_(failed == should_fail, msg) def testDefaultBehavior(self): """Tests the behavior of the default mode.""" self.RunAndVerify(env_var_value=None, flag_value=None, should_fail=False) def testThrowOnFailureEnvVar(self): """Tests using the GTEST_THROW_ON_FAILURE environment variable.""" self.RunAndVerify(env_var_value='0', flag_value=None, should_fail=False) self.RunAndVerify(env_var_value='1', flag_value=None, should_fail=True) def testThrowOnFailureFlag(self): """Tests using the --gtest_throw_on_failure flag.""" self.RunAndVerify(env_var_value=None, flag_value='0', should_fail=False) self.RunAndVerify(env_var_value=None, flag_value='1', should_fail=True) def testThrowOnFailureFlagOverridesEnvVar(self): """Tests that --gtest_throw_on_failure overrides GTEST_THROW_ON_FAILURE.""" self.RunAndVerify(env_var_value='0', flag_value='0', should_fail=False) self.RunAndVerify(env_var_value='0', flag_value='1', should_fail=True) self.RunAndVerify(env_var_value='1', flag_value='0', should_fail=False) self.RunAndVerify(env_var_value='1', flag_value='1', should_fail=True) if __name__ == '__main__': gtest_test_utils.Main() dlt-daemon-2.18.4/gtest-1.7.0/test/gtest_throw_on_failure_test_.cc000066400000000000000000000060401353342203500246610ustar00rootroot00000000000000// Copyright 2009, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: wan@google.com (Zhanyong Wan) // Tests Google Test's throw-on-failure mode with exceptions disabled. // // This program must be compiled with exceptions disabled. It will be // invoked by gtest_throw_on_failure_test.py, and is expected to exit // with non-zero in the throw-on-failure mode or 0 otherwise. #include "gtest/gtest.h" #include // for fflush, fprintf, NULL, etc. #include // for exit #include // for set_terminate // This terminate handler aborts the program using exit() rather than abort(). // This avoids showing pop-ups on Windows systems and core dumps on Unix-like // ones. void TerminateHandler() { fprintf(stderr, "%s\n", "Unhandled C++ exception terminating the program."); fflush(NULL); exit(1); } int main(int argc, char** argv) { #if GTEST_HAS_EXCEPTIONS std::set_terminate(&TerminateHandler); #endif testing::InitGoogleTest(&argc, argv); // We want to ensure that people can use Google Test assertions in // other testing frameworks, as long as they initialize Google Test // properly and set the throw-on-failure mode. Therefore, we don't // use Google Test's constructs for defining and running tests // (e.g. TEST and RUN_ALL_TESTS) here. // In the throw-on-failure mode with exceptions disabled, this // assertion will cause the program to exit with a non-zero code. EXPECT_EQ(2, 3); // When not in the throw-on-failure mode, the control will reach // here. return 0; } dlt-daemon-2.18.4/gtest-1.7.0/test/gtest_uninitialized_test.py000077500000000000000000000046601353342203500241000ustar00rootroot00000000000000#!/usr/bin/env python # # 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. """Verifies that Google Test warns the user when not initialized properly.""" __author__ = 'wan@google.com (Zhanyong Wan)' import gtest_test_utils COMMAND = gtest_test_utils.GetTestExecutablePath('gtest_uninitialized_test_') def Assert(condition): if not condition: raise AssertionError def AssertEq(expected, actual): if expected != actual: print 'Expected: %s' % (expected,) print ' Actual: %s' % (actual,) raise AssertionError def TestExitCodeAndOutput(command): """Runs the given command and verifies its exit code and output.""" # Verifies that 'command' exits with code 1. p = gtest_test_utils.Subprocess(command) Assert(p.exited) AssertEq(1, p.exit_code) Assert('InitGoogleTest' in p.output) class GTestUninitializedTest(gtest_test_utils.TestCase): def testExitCodeAndOutput(self): TestExitCodeAndOutput(COMMAND) if __name__ == '__main__': gtest_test_utils.Main() dlt-daemon-2.18.4/gtest-1.7.0/test/gtest_uninitialized_test_.cc000066400000000000000000000036011353342203500241630ustar00rootroot00000000000000// Copyright 2008, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: wan@google.com (Zhanyong Wan) #include "gtest/gtest.h" TEST(DummyTest, Dummy) { // This test doesn't verify anything. We just need it to create a // realistic stage for testing the behavior of Google Test when // RUN_ALL_TESTS() is called without testing::InitGoogleTest() being // called first. } int main() { return RUN_ALL_TESTS(); } dlt-daemon-2.18.4/gtest-1.7.0/test/gtest_unittest.cc000066400000000000000000007231111353342203500220010ustar00rootroot00000000000000// Copyright 2005, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: wan@google.com (Zhanyong Wan) // // Tests for Google Test itself. This verifies that the basic constructs of // Google Test work. #include "gtest/gtest.h" // Verifies that the command line flag variables can be accessed // in code once has been #included. // Do not move it after other #includes. TEST(CommandLineFlagsTest, CanBeAccessedInCodeOnceGTestHIsIncluded) { bool dummy = testing::GTEST_FLAG(also_run_disabled_tests) || testing::GTEST_FLAG(break_on_failure) || testing::GTEST_FLAG(catch_exceptions) || testing::GTEST_FLAG(color) != "unknown" || testing::GTEST_FLAG(filter) != "unknown" || testing::GTEST_FLAG(list_tests) || testing::GTEST_FLAG(output) != "unknown" || testing::GTEST_FLAG(print_time) || testing::GTEST_FLAG(random_seed) || testing::GTEST_FLAG(repeat) > 0 || testing::GTEST_FLAG(show_internal_stack_frames) || testing::GTEST_FLAG(shuffle) || testing::GTEST_FLAG(stack_trace_depth) > 0 || testing::GTEST_FLAG(stream_result_to) != "unknown" || testing::GTEST_FLAG(throw_on_failure); EXPECT_TRUE(dummy || !dummy); // Suppresses warning that dummy is unused. } #include // For INT_MAX. #include #include #include #include #include #include #include "gtest/gtest-spi.h" // Indicates that this translation unit is part of Google Test's // implementation. It must come before gtest-internal-inl.h is // included, or there will be a compiler error. This trick is to // prevent a user from accidentally including gtest-internal-inl.h in // his code. #define GTEST_IMPLEMENTATION_ 1 #include "src/gtest-internal-inl.h" #undef GTEST_IMPLEMENTATION_ namespace testing { namespace internal { #if GTEST_CAN_STREAM_RESULTS_ class StreamingListenerTest : public Test { public: class FakeSocketWriter : public StreamingListener::AbstractSocketWriter { public: // Sends a string to the socket. virtual void Send(const string& message) { output_ += message; } string output_; }; StreamingListenerTest() : fake_sock_writer_(new FakeSocketWriter), streamer_(fake_sock_writer_), test_info_obj_("FooTest", "Bar", NULL, NULL, 0, NULL) {} protected: string* output() { return &(fake_sock_writer_->output_); } FakeSocketWriter* const fake_sock_writer_; StreamingListener streamer_; UnitTest unit_test_; TestInfo test_info_obj_; // The name test_info_ was taken by testing::Test. }; TEST_F(StreamingListenerTest, OnTestProgramEnd) { *output() = ""; streamer_.OnTestProgramEnd(unit_test_); EXPECT_EQ("event=TestProgramEnd&passed=1\n", *output()); } TEST_F(StreamingListenerTest, OnTestIterationEnd) { *output() = ""; streamer_.OnTestIterationEnd(unit_test_, 42); EXPECT_EQ("event=TestIterationEnd&passed=1&elapsed_time=0ms\n", *output()); } TEST_F(StreamingListenerTest, OnTestCaseStart) { *output() = ""; streamer_.OnTestCaseStart(TestCase("FooTest", "Bar", NULL, NULL)); EXPECT_EQ("event=TestCaseStart&name=FooTest\n", *output()); } TEST_F(StreamingListenerTest, OnTestCaseEnd) { *output() = ""; streamer_.OnTestCaseEnd(TestCase("FooTest", "Bar", NULL, NULL)); EXPECT_EQ("event=TestCaseEnd&passed=1&elapsed_time=0ms\n", *output()); } TEST_F(StreamingListenerTest, OnTestStart) { *output() = ""; streamer_.OnTestStart(test_info_obj_); EXPECT_EQ("event=TestStart&name=Bar\n", *output()); } TEST_F(StreamingListenerTest, OnTestEnd) { *output() = ""; streamer_.OnTestEnd(test_info_obj_); EXPECT_EQ("event=TestEnd&passed=1&elapsed_time=0ms\n", *output()); } TEST_F(StreamingListenerTest, OnTestPartResult) { *output() = ""; streamer_.OnTestPartResult(TestPartResult( TestPartResult::kFatalFailure, "foo.cc", 42, "failed=\n&%")); // Meta characters in the failure message should be properly escaped. EXPECT_EQ( "event=TestPartResult&file=foo.cc&line=42&message=failed%3D%0A%26%25\n", *output()); } #endif // GTEST_CAN_STREAM_RESULTS_ // Provides access to otherwise private parts of the TestEventListeners class // that are needed to test it. class TestEventListenersAccessor { public: static TestEventListener* GetRepeater(TestEventListeners* listeners) { return listeners->repeater(); } static void SetDefaultResultPrinter(TestEventListeners* listeners, TestEventListener* listener) { listeners->SetDefaultResultPrinter(listener); } static void SetDefaultXmlGenerator(TestEventListeners* listeners, TestEventListener* listener) { listeners->SetDefaultXmlGenerator(listener); } static bool EventForwardingEnabled(const TestEventListeners& listeners) { return listeners.EventForwardingEnabled(); } static void SuppressEventForwarding(TestEventListeners* listeners) { listeners->SuppressEventForwarding(); } }; class UnitTestRecordPropertyTestHelper : public Test { protected: UnitTestRecordPropertyTestHelper() {} // Forwards to UnitTest::RecordProperty() to bypass access controls. void UnitTestRecordProperty(const char* key, const std::string& value) { unit_test_.RecordProperty(key, value); } UnitTest unit_test_; }; } // namespace internal } // namespace testing using testing::AssertionFailure; using testing::AssertionResult; using testing::AssertionSuccess; using testing::DoubleLE; using testing::EmptyTestEventListener; using testing::Environment; using testing::FloatLE; using testing::GTEST_FLAG(also_run_disabled_tests); using testing::GTEST_FLAG(break_on_failure); using testing::GTEST_FLAG(catch_exceptions); using testing::GTEST_FLAG(color); using testing::GTEST_FLAG(death_test_use_fork); using testing::GTEST_FLAG(filter); using testing::GTEST_FLAG(list_tests); using testing::GTEST_FLAG(output); using testing::GTEST_FLAG(print_time); using testing::GTEST_FLAG(random_seed); using testing::GTEST_FLAG(repeat); using testing::GTEST_FLAG(show_internal_stack_frames); using testing::GTEST_FLAG(shuffle); using testing::GTEST_FLAG(stack_trace_depth); using testing::GTEST_FLAG(stream_result_to); using testing::GTEST_FLAG(throw_on_failure); using testing::IsNotSubstring; using testing::IsSubstring; using testing::Message; using testing::ScopedFakeTestPartResultReporter; using testing::StaticAssertTypeEq; using testing::Test; using testing::TestCase; using testing::TestEventListeners; using testing::TestInfo; using testing::TestPartResult; using testing::TestPartResultArray; using testing::TestProperty; using testing::TestResult; using testing::TimeInMillis; using testing::UnitTest; using testing::kMaxStackTraceDepth; using testing::internal::AddReference; using testing::internal::AlwaysFalse; using testing::internal::AlwaysTrue; using testing::internal::AppendUserMessage; using testing::internal::ArrayAwareFind; using testing::internal::ArrayEq; using testing::internal::CodePointToUtf8; using testing::internal::CompileAssertTypesEqual; using testing::internal::CopyArray; using testing::internal::CountIf; using testing::internal::EqFailure; using testing::internal::FloatingPoint; using testing::internal::ForEach; using testing::internal::FormatEpochTimeInMillisAsIso8601; using testing::internal::FormatTimeInMillisAsSeconds; using testing::internal::GTestFlagSaver; using testing::internal::GetCurrentOsStackTraceExceptTop; using testing::internal::GetElementOr; using testing::internal::GetNextRandomSeed; using testing::internal::GetRandomSeedFromFlag; using testing::internal::GetTestTypeId; using testing::internal::GetTimeInMillis; using testing::internal::GetTypeId; using testing::internal::GetUnitTestImpl; using testing::internal::ImplicitlyConvertible; using testing::internal::Int32; using testing::internal::Int32FromEnvOrDie; using testing::internal::IsAProtocolMessage; using testing::internal::IsContainer; using testing::internal::IsContainerTest; using testing::internal::IsNotContainer; using testing::internal::NativeArray; using testing::internal::ParseInt32Flag; using testing::internal::RemoveConst; using testing::internal::RemoveReference; using testing::internal::ShouldRunTestOnShard; using testing::internal::ShouldShard; using testing::internal::ShouldUseColor; using testing::internal::Shuffle; using testing::internal::ShuffleRange; using testing::internal::SkipPrefix; using testing::internal::StreamableToString; using testing::internal::String; using testing::internal::TestEventListenersAccessor; using testing::internal::TestResultAccessor; using testing::internal::UInt32; using testing::internal::WideStringToUtf8; using testing::internal::kCopy; using testing::internal::kMaxRandomSeed; using testing::internal::kReference; using testing::internal::kTestTypeIdInGoogleTest; using testing::internal::scoped_ptr; #if GTEST_HAS_STREAM_REDIRECTION using testing::internal::CaptureStdout; using testing::internal::GetCapturedStdout; #endif #if GTEST_IS_THREADSAFE using testing::internal::ThreadWithParam; #endif class TestingVector : public std::vector { }; ::std::ostream& operator<<(::std::ostream& os, const TestingVector& vector) { os << "{ "; for (size_t i = 0; i < vector.size(); i++) { os << vector[i] << " "; } os << "}"; return os; } // This line tests that we can define tests in an unnamed namespace. namespace { TEST(GetRandomSeedFromFlagTest, HandlesZero) { const int seed = GetRandomSeedFromFlag(0); EXPECT_LE(1, seed); EXPECT_LE(seed, static_cast(kMaxRandomSeed)); } TEST(GetRandomSeedFromFlagTest, PreservesValidSeed) { EXPECT_EQ(1, GetRandomSeedFromFlag(1)); EXPECT_EQ(2, GetRandomSeedFromFlag(2)); EXPECT_EQ(kMaxRandomSeed - 1, GetRandomSeedFromFlag(kMaxRandomSeed - 1)); EXPECT_EQ(static_cast(kMaxRandomSeed), GetRandomSeedFromFlag(kMaxRandomSeed)); } TEST(GetRandomSeedFromFlagTest, NormalizesInvalidSeed) { const int seed1 = GetRandomSeedFromFlag(-1); EXPECT_LE(1, seed1); EXPECT_LE(seed1, static_cast(kMaxRandomSeed)); const int seed2 = GetRandomSeedFromFlag(kMaxRandomSeed + 1); EXPECT_LE(1, seed2); EXPECT_LE(seed2, static_cast(kMaxRandomSeed)); } TEST(GetNextRandomSeedTest, WorksForValidInput) { EXPECT_EQ(2, GetNextRandomSeed(1)); EXPECT_EQ(3, GetNextRandomSeed(2)); EXPECT_EQ(static_cast(kMaxRandomSeed), GetNextRandomSeed(kMaxRandomSeed - 1)); EXPECT_EQ(1, GetNextRandomSeed(kMaxRandomSeed)); // We deliberately don't test GetNextRandomSeed() with invalid // inputs, as that requires death tests, which are expensive. This // is fine as GetNextRandomSeed() is internal and has a // straightforward definition. } static void ClearCurrentTestPartResults() { TestResultAccessor::ClearTestPartResults( GetUnitTestImpl()->current_test_result()); } // Tests GetTypeId. TEST(GetTypeIdTest, ReturnsSameValueForSameType) { EXPECT_EQ(GetTypeId(), GetTypeId()); EXPECT_EQ(GetTypeId(), GetTypeId()); } class SubClassOfTest : public Test {}; class AnotherSubClassOfTest : public Test {}; TEST(GetTypeIdTest, ReturnsDifferentValuesForDifferentTypes) { EXPECT_NE(GetTypeId(), GetTypeId()); EXPECT_NE(GetTypeId(), GetTypeId()); EXPECT_NE(GetTypeId(), GetTestTypeId()); EXPECT_NE(GetTypeId(), GetTestTypeId()); EXPECT_NE(GetTypeId(), GetTestTypeId()); EXPECT_NE(GetTypeId(), GetTypeId()); } // Verifies that GetTestTypeId() returns the same value, no matter it // is called from inside Google Test or outside of it. TEST(GetTestTypeIdTest, ReturnsTheSameValueInsideOrOutsideOfGoogleTest) { EXPECT_EQ(kTestTypeIdInGoogleTest, GetTestTypeId()); } // Tests FormatTimeInMillisAsSeconds(). TEST(FormatTimeInMillisAsSecondsTest, FormatsZero) { EXPECT_EQ("0", FormatTimeInMillisAsSeconds(0)); } TEST(FormatTimeInMillisAsSecondsTest, FormatsPositiveNumber) { EXPECT_EQ("0.003", FormatTimeInMillisAsSeconds(3)); EXPECT_EQ("0.01", FormatTimeInMillisAsSeconds(10)); EXPECT_EQ("0.2", FormatTimeInMillisAsSeconds(200)); EXPECT_EQ("1.2", FormatTimeInMillisAsSeconds(1200)); EXPECT_EQ("3", FormatTimeInMillisAsSeconds(3000)); } TEST(FormatTimeInMillisAsSecondsTest, FormatsNegativeNumber) { EXPECT_EQ("-0.003", FormatTimeInMillisAsSeconds(-3)); EXPECT_EQ("-0.01", FormatTimeInMillisAsSeconds(-10)); EXPECT_EQ("-0.2", FormatTimeInMillisAsSeconds(-200)); EXPECT_EQ("-1.2", FormatTimeInMillisAsSeconds(-1200)); EXPECT_EQ("-3", FormatTimeInMillisAsSeconds(-3000)); } // Tests FormatEpochTimeInMillisAsIso8601(). The correctness of conversion // for particular dates below was verified in Python using // datetime.datetime.fromutctimestamp(/1000). // FormatEpochTimeInMillisAsIso8601 depends on the current timezone, so we // have to set up a particular timezone to obtain predictable results. class FormatEpochTimeInMillisAsIso8601Test : public Test { public: // On Cygwin, GCC doesn't allow unqualified integer literals to exceed // 32 bits, even when 64-bit integer types are available. We have to // force the constants to have a 64-bit type here. static const TimeInMillis kMillisPerSec = 1000; private: virtual void SetUp() { saved_tz_ = NULL; #if _MSC_VER # pragma warning(push) // Saves the current warning state. # pragma warning(disable:4996) // Temporarily disables warning 4996 // (function or variable may be unsafe // for getenv, function is deprecated for // strdup). if (getenv("TZ")) saved_tz_ = strdup(getenv("TZ")); # pragma warning(pop) // Restores the warning state again. #else if (getenv("TZ")) saved_tz_ = strdup(getenv("TZ")); #endif // Set up the time zone for FormatEpochTimeInMillisAsIso8601 to use. We // cannot use the local time zone because the function's output depends // on the time zone. SetTimeZone("UTC+00"); } virtual void TearDown() { SetTimeZone(saved_tz_); free(const_cast(saved_tz_)); saved_tz_ = NULL; } static void SetTimeZone(const char* time_zone) { // tzset() distinguishes between the TZ variable being present and empty // and not being present, so we have to consider the case of time_zone // being NULL. #if _MSC_VER // ...Unless it's MSVC, whose standard library's _putenv doesn't // distinguish between an empty and a missing variable. const std::string env_var = std::string("TZ=") + (time_zone ? time_zone : ""); _putenv(env_var.c_str()); # pragma warning(push) // Saves the current warning state. # pragma warning(disable:4996) // Temporarily disables warning 4996 // (function is deprecated). tzset(); # pragma warning(pop) // Restores the warning state again. #else if (time_zone) { setenv(("TZ"), time_zone, 1); } else { unsetenv("TZ"); } tzset(); #endif } const char* saved_tz_; }; const TimeInMillis FormatEpochTimeInMillisAsIso8601Test::kMillisPerSec; TEST_F(FormatEpochTimeInMillisAsIso8601Test, PrintsTwoDigitSegments) { EXPECT_EQ("2011-10-31T18:52:42", FormatEpochTimeInMillisAsIso8601(1320087162 * kMillisPerSec)); } TEST_F(FormatEpochTimeInMillisAsIso8601Test, MillisecondsDoNotAffectResult) { EXPECT_EQ( "2011-10-31T18:52:42", FormatEpochTimeInMillisAsIso8601(1320087162 * kMillisPerSec + 234)); } TEST_F(FormatEpochTimeInMillisAsIso8601Test, PrintsLeadingZeroes) { EXPECT_EQ("2011-09-03T05:07:02", FormatEpochTimeInMillisAsIso8601(1315026422 * kMillisPerSec)); } TEST_F(FormatEpochTimeInMillisAsIso8601Test, Prints24HourTime) { EXPECT_EQ("2011-09-28T17:08:22", FormatEpochTimeInMillisAsIso8601(1317229702 * kMillisPerSec)); } TEST_F(FormatEpochTimeInMillisAsIso8601Test, PrintsEpochStart) { EXPECT_EQ("1970-01-01T00:00:00", FormatEpochTimeInMillisAsIso8601(0)); } #if GTEST_CAN_COMPARE_NULL # ifdef __BORLANDC__ // Silences warnings: "Condition is always true", "Unreachable code" # pragma option push -w-ccc -w-rch # endif // Tests that GTEST_IS_NULL_LITERAL_(x) is true when x is a null // pointer literal. TEST(NullLiteralTest, IsTrueForNullLiterals) { EXPECT_TRUE(GTEST_IS_NULL_LITERAL_(NULL)); EXPECT_TRUE(GTEST_IS_NULL_LITERAL_(0)); EXPECT_TRUE(GTEST_IS_NULL_LITERAL_(0U)); EXPECT_TRUE(GTEST_IS_NULL_LITERAL_(0L)); } // Tests that GTEST_IS_NULL_LITERAL_(x) is false when x is not a null // pointer literal. TEST(NullLiteralTest, IsFalseForNonNullLiterals) { EXPECT_FALSE(GTEST_IS_NULL_LITERAL_(1)); EXPECT_FALSE(GTEST_IS_NULL_LITERAL_(0.0)); EXPECT_FALSE(GTEST_IS_NULL_LITERAL_('a')); EXPECT_FALSE(GTEST_IS_NULL_LITERAL_(static_cast(NULL))); } # ifdef __BORLANDC__ // Restores warnings after previous "#pragma option push" suppressed them. # pragma option pop # endif #endif // GTEST_CAN_COMPARE_NULL // // Tests CodePointToUtf8(). // Tests that the NUL character L'\0' is encoded correctly. TEST(CodePointToUtf8Test, CanEncodeNul) { EXPECT_EQ("", CodePointToUtf8(L'\0')); } // Tests that ASCII characters are encoded correctly. TEST(CodePointToUtf8Test, CanEncodeAscii) { EXPECT_EQ("a", CodePointToUtf8(L'a')); EXPECT_EQ("Z", CodePointToUtf8(L'Z')); EXPECT_EQ("&", CodePointToUtf8(L'&')); EXPECT_EQ("\x7F", CodePointToUtf8(L'\x7F')); } // Tests that Unicode code-points that have 8 to 11 bits are encoded // as 110xxxxx 10xxxxxx. TEST(CodePointToUtf8Test, CanEncode8To11Bits) { // 000 1101 0011 => 110-00011 10-010011 EXPECT_EQ("\xC3\x93", CodePointToUtf8(L'\xD3')); // 101 0111 0110 => 110-10101 10-110110 // Some compilers (e.g., GCC on MinGW) cannot handle non-ASCII codepoints // in wide strings and wide chars. In order to accomodate them, we have to // introduce such character constants as integers. EXPECT_EQ("\xD5\xB6", CodePointToUtf8(static_cast(0x576))); } // Tests that Unicode code-points that have 12 to 16 bits are encoded // as 1110xxxx 10xxxxxx 10xxxxxx. TEST(CodePointToUtf8Test, CanEncode12To16Bits) { // 0000 1000 1101 0011 => 1110-0000 10-100011 10-010011 EXPECT_EQ("\xE0\xA3\x93", CodePointToUtf8(static_cast(0x8D3))); // 1100 0111 0100 1101 => 1110-1100 10-011101 10-001101 EXPECT_EQ("\xEC\x9D\x8D", CodePointToUtf8(static_cast(0xC74D))); } #if !GTEST_WIDE_STRING_USES_UTF16_ // Tests in this group require a wchar_t to hold > 16 bits, and thus // are skipped on Windows, Cygwin, and Symbian, where a wchar_t is // 16-bit wide. This code may not compile on those systems. // Tests that Unicode code-points that have 17 to 21 bits are encoded // as 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx. TEST(CodePointToUtf8Test, CanEncode17To21Bits) { // 0 0001 0000 1000 1101 0011 => 11110-000 10-010000 10-100011 10-010011 EXPECT_EQ("\xF0\x90\xA3\x93", CodePointToUtf8(L'\x108D3')); // 0 0001 0000 0100 0000 0000 => 11110-000 10-010000 10-010000 10-000000 EXPECT_EQ("\xF0\x90\x90\x80", CodePointToUtf8(L'\x10400')); // 1 0000 1000 0110 0011 0100 => 11110-100 10-001000 10-011000 10-110100 EXPECT_EQ("\xF4\x88\x98\xB4", CodePointToUtf8(L'\x108634')); } // Tests that encoding an invalid code-point generates the expected result. TEST(CodePointToUtf8Test, CanEncodeInvalidCodePoint) { EXPECT_EQ("(Invalid Unicode 0x1234ABCD)", CodePointToUtf8(L'\x1234ABCD')); } #endif // !GTEST_WIDE_STRING_USES_UTF16_ // Tests WideStringToUtf8(). // Tests that the NUL character L'\0' is encoded correctly. TEST(WideStringToUtf8Test, CanEncodeNul) { EXPECT_STREQ("", WideStringToUtf8(L"", 0).c_str()); EXPECT_STREQ("", WideStringToUtf8(L"", -1).c_str()); } // Tests that ASCII strings are encoded correctly. TEST(WideStringToUtf8Test, CanEncodeAscii) { EXPECT_STREQ("a", WideStringToUtf8(L"a", 1).c_str()); EXPECT_STREQ("ab", WideStringToUtf8(L"ab", 2).c_str()); EXPECT_STREQ("a", WideStringToUtf8(L"a", -1).c_str()); EXPECT_STREQ("ab", WideStringToUtf8(L"ab", -1).c_str()); } // Tests that Unicode code-points that have 8 to 11 bits are encoded // as 110xxxxx 10xxxxxx. TEST(WideStringToUtf8Test, CanEncode8To11Bits) { // 000 1101 0011 => 110-00011 10-010011 EXPECT_STREQ("\xC3\x93", WideStringToUtf8(L"\xD3", 1).c_str()); EXPECT_STREQ("\xC3\x93", WideStringToUtf8(L"\xD3", -1).c_str()); // 101 0111 0110 => 110-10101 10-110110 const wchar_t s[] = { 0x576, '\0' }; EXPECT_STREQ("\xD5\xB6", WideStringToUtf8(s, 1).c_str()); EXPECT_STREQ("\xD5\xB6", WideStringToUtf8(s, -1).c_str()); } // Tests that Unicode code-points that have 12 to 16 bits are encoded // as 1110xxxx 10xxxxxx 10xxxxxx. TEST(WideStringToUtf8Test, CanEncode12To16Bits) { // 0000 1000 1101 0011 => 1110-0000 10-100011 10-010011 const wchar_t s1[] = { 0x8D3, '\0' }; EXPECT_STREQ("\xE0\xA3\x93", WideStringToUtf8(s1, 1).c_str()); EXPECT_STREQ("\xE0\xA3\x93", WideStringToUtf8(s1, -1).c_str()); // 1100 0111 0100 1101 => 1110-1100 10-011101 10-001101 const wchar_t s2[] = { 0xC74D, '\0' }; EXPECT_STREQ("\xEC\x9D\x8D", WideStringToUtf8(s2, 1).c_str()); EXPECT_STREQ("\xEC\x9D\x8D", WideStringToUtf8(s2, -1).c_str()); } // Tests that the conversion stops when the function encounters \0 character. TEST(WideStringToUtf8Test, StopsOnNulCharacter) { EXPECT_STREQ("ABC", WideStringToUtf8(L"ABC\0XYZ", 100).c_str()); } // Tests that the conversion stops when the function reaches the limit // specified by the 'length' parameter. TEST(WideStringToUtf8Test, StopsWhenLengthLimitReached) { EXPECT_STREQ("ABC", WideStringToUtf8(L"ABCDEF", 3).c_str()); } #if !GTEST_WIDE_STRING_USES_UTF16_ // Tests that Unicode code-points that have 17 to 21 bits are encoded // as 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx. This code may not compile // on the systems using UTF-16 encoding. TEST(WideStringToUtf8Test, CanEncode17To21Bits) { // 0 0001 0000 1000 1101 0011 => 11110-000 10-010000 10-100011 10-010011 EXPECT_STREQ("\xF0\x90\xA3\x93", WideStringToUtf8(L"\x108D3", 1).c_str()); EXPECT_STREQ("\xF0\x90\xA3\x93", WideStringToUtf8(L"\x108D3", -1).c_str()); // 1 0000 1000 0110 0011 0100 => 11110-100 10-001000 10-011000 10-110100 EXPECT_STREQ("\xF4\x88\x98\xB4", WideStringToUtf8(L"\x108634", 1).c_str()); EXPECT_STREQ("\xF4\x88\x98\xB4", WideStringToUtf8(L"\x108634", -1).c_str()); } // Tests that encoding an invalid code-point generates the expected result. TEST(WideStringToUtf8Test, CanEncodeInvalidCodePoint) { EXPECT_STREQ("(Invalid Unicode 0xABCDFF)", WideStringToUtf8(L"\xABCDFF", -1).c_str()); } #else // !GTEST_WIDE_STRING_USES_UTF16_ // Tests that surrogate pairs are encoded correctly on the systems using // UTF-16 encoding in the wide strings. TEST(WideStringToUtf8Test, CanEncodeValidUtf16SUrrogatePairs) { const wchar_t s[] = { 0xD801, 0xDC00, '\0' }; EXPECT_STREQ("\xF0\x90\x90\x80", WideStringToUtf8(s, -1).c_str()); } // Tests that encoding an invalid UTF-16 surrogate pair // generates the expected result. TEST(WideStringToUtf8Test, CanEncodeInvalidUtf16SurrogatePair) { // Leading surrogate is at the end of the string. const wchar_t s1[] = { 0xD800, '\0' }; EXPECT_STREQ("\xED\xA0\x80", WideStringToUtf8(s1, -1).c_str()); // Leading surrogate is not followed by the trailing surrogate. const wchar_t s2[] = { 0xD800, 'M', '\0' }; EXPECT_STREQ("\xED\xA0\x80M", WideStringToUtf8(s2, -1).c_str()); // Trailing surrogate appearas without a leading surrogate. const wchar_t s3[] = { 0xDC00, 'P', 'Q', 'R', '\0' }; EXPECT_STREQ("\xED\xB0\x80PQR", WideStringToUtf8(s3, -1).c_str()); } #endif // !GTEST_WIDE_STRING_USES_UTF16_ // Tests that codepoint concatenation works correctly. #if !GTEST_WIDE_STRING_USES_UTF16_ TEST(WideStringToUtf8Test, ConcatenatesCodepointsCorrectly) { const wchar_t s[] = { 0x108634, 0xC74D, '\n', 0x576, 0x8D3, 0x108634, '\0'}; EXPECT_STREQ( "\xF4\x88\x98\xB4" "\xEC\x9D\x8D" "\n" "\xD5\xB6" "\xE0\xA3\x93" "\xF4\x88\x98\xB4", WideStringToUtf8(s, -1).c_str()); } #else TEST(WideStringToUtf8Test, ConcatenatesCodepointsCorrectly) { const wchar_t s[] = { 0xC74D, '\n', 0x576, 0x8D3, '\0'}; EXPECT_STREQ( "\xEC\x9D\x8D" "\n" "\xD5\xB6" "\xE0\xA3\x93", WideStringToUtf8(s, -1).c_str()); } #endif // !GTEST_WIDE_STRING_USES_UTF16_ // Tests the Random class. TEST(RandomDeathTest, GeneratesCrashesOnInvalidRange) { testing::internal::Random random(42); EXPECT_DEATH_IF_SUPPORTED( random.Generate(0), "Cannot generate a number in the range \\[0, 0\\)"); EXPECT_DEATH_IF_SUPPORTED( random.Generate(testing::internal::Random::kMaxRange + 1), "Generation of a number in \\[0, 2147483649\\) was requested, " "but this can only generate numbers in \\[0, 2147483648\\)"); } TEST(RandomTest, GeneratesNumbersWithinRange) { const UInt32 kRange = 10000; testing::internal::Random random(12345); for (int i = 0; i < 10; i++) { EXPECT_LT(random.Generate(kRange), kRange) << " for iteration " << i; } testing::internal::Random random2(testing::internal::Random::kMaxRange); for (int i = 0; i < 10; i++) { EXPECT_LT(random2.Generate(kRange), kRange) << " for iteration " << i; } } TEST(RandomTest, RepeatsWhenReseeded) { const int kSeed = 123; const int kArraySize = 10; const UInt32 kRange = 10000; UInt32 values[kArraySize]; testing::internal::Random random(kSeed); for (int i = 0; i < kArraySize; i++) { values[i] = random.Generate(kRange); } random.Reseed(kSeed); for (int i = 0; i < kArraySize; i++) { EXPECT_EQ(values[i], random.Generate(kRange)) << " for iteration " << i; } } // Tests STL container utilities. // Tests CountIf(). static bool IsPositive(int n) { return n > 0; } TEST(ContainerUtilityTest, CountIf) { std::vector v; EXPECT_EQ(0, CountIf(v, IsPositive)); // Works for an empty container. v.push_back(-1); v.push_back(0); EXPECT_EQ(0, CountIf(v, IsPositive)); // Works when no value satisfies. v.push_back(2); v.push_back(-10); v.push_back(10); EXPECT_EQ(2, CountIf(v, IsPositive)); } // Tests ForEach(). static int g_sum = 0; static void Accumulate(int n) { g_sum += n; } TEST(ContainerUtilityTest, ForEach) { std::vector v; g_sum = 0; ForEach(v, Accumulate); EXPECT_EQ(0, g_sum); // Works for an empty container; g_sum = 0; v.push_back(1); ForEach(v, Accumulate); EXPECT_EQ(1, g_sum); // Works for a container with one element. g_sum = 0; v.push_back(20); v.push_back(300); ForEach(v, Accumulate); EXPECT_EQ(321, g_sum); } // Tests GetElementOr(). TEST(ContainerUtilityTest, GetElementOr) { std::vector a; EXPECT_EQ('x', GetElementOr(a, 0, 'x')); a.push_back('a'); a.push_back('b'); EXPECT_EQ('a', GetElementOr(a, 0, 'x')); EXPECT_EQ('b', GetElementOr(a, 1, 'x')); EXPECT_EQ('x', GetElementOr(a, -2, 'x')); EXPECT_EQ('x', GetElementOr(a, 2, 'x')); } TEST(ContainerUtilityDeathTest, ShuffleRange) { std::vector a; a.push_back(0); a.push_back(1); a.push_back(2); testing::internal::Random random(1); EXPECT_DEATH_IF_SUPPORTED( ShuffleRange(&random, -1, 1, &a), "Invalid shuffle range start -1: must be in range \\[0, 3\\]"); EXPECT_DEATH_IF_SUPPORTED( ShuffleRange(&random, 4, 4, &a), "Invalid shuffle range start 4: must be in range \\[0, 3\\]"); EXPECT_DEATH_IF_SUPPORTED( ShuffleRange(&random, 3, 2, &a), "Invalid shuffle range finish 2: must be in range \\[3, 3\\]"); EXPECT_DEATH_IF_SUPPORTED( ShuffleRange(&random, 3, 4, &a), "Invalid shuffle range finish 4: must be in range \\[3, 3\\]"); } class VectorShuffleTest : public Test { protected: static const int kVectorSize = 20; VectorShuffleTest() : random_(1) { for (int i = 0; i < kVectorSize; i++) { vector_.push_back(i); } } static bool VectorIsCorrupt(const TestingVector& vector) { if (kVectorSize != static_cast(vector.size())) { return true; } bool found_in_vector[kVectorSize] = { false }; for (size_t i = 0; i < vector.size(); i++) { const int e = vector[i]; if (e < 0 || e >= kVectorSize || found_in_vector[e]) { return true; } found_in_vector[e] = true; } // Vector size is correct, elements' range is correct, no // duplicate elements. Therefore no corruption has occurred. return false; } static bool VectorIsNotCorrupt(const TestingVector& vector) { return !VectorIsCorrupt(vector); } static bool RangeIsShuffled(const TestingVector& vector, int begin, int end) { for (int i = begin; i < end; i++) { if (i != vector[i]) { return true; } } return false; } static bool RangeIsUnshuffled( const TestingVector& vector, int begin, int end) { return !RangeIsShuffled(vector, begin, end); } static bool VectorIsShuffled(const TestingVector& vector) { return RangeIsShuffled(vector, 0, static_cast(vector.size())); } static bool VectorIsUnshuffled(const TestingVector& vector) { return !VectorIsShuffled(vector); } testing::internal::Random random_; TestingVector vector_; }; // class VectorShuffleTest const int VectorShuffleTest::kVectorSize; TEST_F(VectorShuffleTest, HandlesEmptyRange) { // Tests an empty range at the beginning... ShuffleRange(&random_, 0, 0, &vector_); ASSERT_PRED1(VectorIsNotCorrupt, vector_); ASSERT_PRED1(VectorIsUnshuffled, vector_); // ...in the middle... ShuffleRange(&random_, kVectorSize/2, kVectorSize/2, &vector_); ASSERT_PRED1(VectorIsNotCorrupt, vector_); ASSERT_PRED1(VectorIsUnshuffled, vector_); // ...at the end... ShuffleRange(&random_, kVectorSize - 1, kVectorSize - 1, &vector_); ASSERT_PRED1(VectorIsNotCorrupt, vector_); ASSERT_PRED1(VectorIsUnshuffled, vector_); // ...and past the end. ShuffleRange(&random_, kVectorSize, kVectorSize, &vector_); ASSERT_PRED1(VectorIsNotCorrupt, vector_); ASSERT_PRED1(VectorIsUnshuffled, vector_); } TEST_F(VectorShuffleTest, HandlesRangeOfSizeOne) { // Tests a size one range at the beginning... ShuffleRange(&random_, 0, 1, &vector_); ASSERT_PRED1(VectorIsNotCorrupt, vector_); ASSERT_PRED1(VectorIsUnshuffled, vector_); // ...in the middle... ShuffleRange(&random_, kVectorSize/2, kVectorSize/2 + 1, &vector_); ASSERT_PRED1(VectorIsNotCorrupt, vector_); ASSERT_PRED1(VectorIsUnshuffled, vector_); // ...and at the end. ShuffleRange(&random_, kVectorSize - 1, kVectorSize, &vector_); ASSERT_PRED1(VectorIsNotCorrupt, vector_); ASSERT_PRED1(VectorIsUnshuffled, vector_); } // Because we use our own random number generator and a fixed seed, // we can guarantee that the following "random" tests will succeed. TEST_F(VectorShuffleTest, ShufflesEntireVector) { Shuffle(&random_, &vector_); ASSERT_PRED1(VectorIsNotCorrupt, vector_); EXPECT_FALSE(VectorIsUnshuffled(vector_)) << vector_; // Tests the first and last elements in particular to ensure that // there are no off-by-one problems in our shuffle algorithm. EXPECT_NE(0, vector_[0]); EXPECT_NE(kVectorSize - 1, vector_[kVectorSize - 1]); } TEST_F(VectorShuffleTest, ShufflesStartOfVector) { const int kRangeSize = kVectorSize/2; ShuffleRange(&random_, 0, kRangeSize, &vector_); ASSERT_PRED1(VectorIsNotCorrupt, vector_); EXPECT_PRED3(RangeIsShuffled, vector_, 0, kRangeSize); EXPECT_PRED3(RangeIsUnshuffled, vector_, kRangeSize, kVectorSize); } TEST_F(VectorShuffleTest, ShufflesEndOfVector) { const int kRangeSize = kVectorSize / 2; ShuffleRange(&random_, kRangeSize, kVectorSize, &vector_); ASSERT_PRED1(VectorIsNotCorrupt, vector_); EXPECT_PRED3(RangeIsUnshuffled, vector_, 0, kRangeSize); EXPECT_PRED3(RangeIsShuffled, vector_, kRangeSize, kVectorSize); } TEST_F(VectorShuffleTest, ShufflesMiddleOfVector) { int kRangeSize = kVectorSize/3; ShuffleRange(&random_, kRangeSize, 2*kRangeSize, &vector_); ASSERT_PRED1(VectorIsNotCorrupt, vector_); EXPECT_PRED3(RangeIsUnshuffled, vector_, 0, kRangeSize); EXPECT_PRED3(RangeIsShuffled, vector_, kRangeSize, 2*kRangeSize); EXPECT_PRED3(RangeIsUnshuffled, vector_, 2*kRangeSize, kVectorSize); } TEST_F(VectorShuffleTest, ShufflesRepeatably) { TestingVector vector2; for (int i = 0; i < kVectorSize; i++) { vector2.push_back(i); } random_.Reseed(1234); Shuffle(&random_, &vector_); random_.Reseed(1234); Shuffle(&random_, &vector2); ASSERT_PRED1(VectorIsNotCorrupt, vector_); ASSERT_PRED1(VectorIsNotCorrupt, vector2); for (int i = 0; i < kVectorSize; i++) { EXPECT_EQ(vector_[i], vector2[i]) << " where i is " << i; } } // Tests the size of the AssertHelper class. TEST(AssertHelperTest, AssertHelperIsSmall) { // To avoid breaking clients that use lots of assertions in one // function, we cannot grow the size of AssertHelper. EXPECT_LE(sizeof(testing::internal::AssertHelper), sizeof(void*)); } // Tests String::EndsWithCaseInsensitive(). TEST(StringTest, EndsWithCaseInsensitive) { EXPECT_TRUE(String::EndsWithCaseInsensitive("foobar", "BAR")); EXPECT_TRUE(String::EndsWithCaseInsensitive("foobaR", "bar")); EXPECT_TRUE(String::EndsWithCaseInsensitive("foobar", "")); EXPECT_TRUE(String::EndsWithCaseInsensitive("", "")); EXPECT_FALSE(String::EndsWithCaseInsensitive("Foobar", "foo")); EXPECT_FALSE(String::EndsWithCaseInsensitive("foobar", "Foo")); EXPECT_FALSE(String::EndsWithCaseInsensitive("", "foo")); } // C++Builder's preprocessor is buggy; it fails to expand macros that // appear in macro parameters after wide char literals. Provide an alias // for NULL as a workaround. static const wchar_t* const kNull = NULL; // Tests String::CaseInsensitiveWideCStringEquals TEST(StringTest, CaseInsensitiveWideCStringEquals) { EXPECT_TRUE(String::CaseInsensitiveWideCStringEquals(NULL, NULL)); EXPECT_FALSE(String::CaseInsensitiveWideCStringEquals(kNull, L"")); EXPECT_FALSE(String::CaseInsensitiveWideCStringEquals(L"", kNull)); EXPECT_FALSE(String::CaseInsensitiveWideCStringEquals(kNull, L"foobar")); EXPECT_FALSE(String::CaseInsensitiveWideCStringEquals(L"foobar", kNull)); EXPECT_TRUE(String::CaseInsensitiveWideCStringEquals(L"foobar", L"foobar")); EXPECT_TRUE(String::CaseInsensitiveWideCStringEquals(L"foobar", L"FOOBAR")); EXPECT_TRUE(String::CaseInsensitiveWideCStringEquals(L"FOOBAR", L"foobar")); } #if GTEST_OS_WINDOWS // Tests String::ShowWideCString(). TEST(StringTest, ShowWideCString) { EXPECT_STREQ("(null)", String::ShowWideCString(NULL).c_str()); EXPECT_STREQ("", String::ShowWideCString(L"").c_str()); EXPECT_STREQ("foo", String::ShowWideCString(L"foo").c_str()); } # if GTEST_OS_WINDOWS_MOBILE TEST(StringTest, AnsiAndUtf16Null) { EXPECT_EQ(NULL, String::AnsiToUtf16(NULL)); EXPECT_EQ(NULL, String::Utf16ToAnsi(NULL)); } TEST(StringTest, AnsiAndUtf16ConvertBasic) { const char* ansi = String::Utf16ToAnsi(L"str"); EXPECT_STREQ("str", ansi); delete [] ansi; const WCHAR* utf16 = String::AnsiToUtf16("str"); EXPECT_EQ(0, wcsncmp(L"str", utf16, 3)); delete [] utf16; } TEST(StringTest, AnsiAndUtf16ConvertPathChars) { const char* ansi = String::Utf16ToAnsi(L".:\\ \"*?"); EXPECT_STREQ(".:\\ \"*?", ansi); delete [] ansi; const WCHAR* utf16 = String::AnsiToUtf16(".:\\ \"*?"); EXPECT_EQ(0, wcsncmp(L".:\\ \"*?", utf16, 3)); delete [] utf16; } # endif // GTEST_OS_WINDOWS_MOBILE #endif // GTEST_OS_WINDOWS // Tests TestProperty construction. TEST(TestPropertyTest, StringValue) { TestProperty property("key", "1"); EXPECT_STREQ("key", property.key()); EXPECT_STREQ("1", property.value()); } // Tests TestProperty replacing a value. TEST(TestPropertyTest, ReplaceStringValue) { TestProperty property("key", "1"); EXPECT_STREQ("1", property.value()); property.SetValue("2"); EXPECT_STREQ("2", property.value()); } // AddFatalFailure() and AddNonfatalFailure() must be stand-alone // functions (i.e. their definitions cannot be inlined at the call // sites), or C++Builder won't compile the code. static void AddFatalFailure() { FAIL() << "Expected fatal failure."; } static void AddNonfatalFailure() { ADD_FAILURE() << "Expected non-fatal failure."; } class ScopedFakeTestPartResultReporterTest : public Test { public: // Must be public and not protected due to a bug in g++ 3.4.2. enum FailureMode { FATAL_FAILURE, NONFATAL_FAILURE }; static void AddFailure(FailureMode failure) { if (failure == FATAL_FAILURE) { AddFatalFailure(); } else { AddNonfatalFailure(); } } }; // Tests that ScopedFakeTestPartResultReporter intercepts test // failures. TEST_F(ScopedFakeTestPartResultReporterTest, InterceptsTestFailures) { TestPartResultArray results; { ScopedFakeTestPartResultReporter reporter( ScopedFakeTestPartResultReporter::INTERCEPT_ONLY_CURRENT_THREAD, &results); AddFailure(NONFATAL_FAILURE); AddFailure(FATAL_FAILURE); } EXPECT_EQ(2, results.size()); EXPECT_TRUE(results.GetTestPartResult(0).nonfatally_failed()); EXPECT_TRUE(results.GetTestPartResult(1).fatally_failed()); } TEST_F(ScopedFakeTestPartResultReporterTest, DeprecatedConstructor) { TestPartResultArray results; { // Tests, that the deprecated constructor still works. ScopedFakeTestPartResultReporter reporter(&results); AddFailure(NONFATAL_FAILURE); } EXPECT_EQ(1, results.size()); } #if GTEST_IS_THREADSAFE class ScopedFakeTestPartResultReporterWithThreadsTest : public ScopedFakeTestPartResultReporterTest { protected: static void AddFailureInOtherThread(FailureMode failure) { ThreadWithParam thread(&AddFailure, failure, NULL); thread.Join(); } }; TEST_F(ScopedFakeTestPartResultReporterWithThreadsTest, InterceptsTestFailuresInAllThreads) { TestPartResultArray results; { ScopedFakeTestPartResultReporter reporter( ScopedFakeTestPartResultReporter::INTERCEPT_ALL_THREADS, &results); AddFailure(NONFATAL_FAILURE); AddFailure(FATAL_FAILURE); AddFailureInOtherThread(NONFATAL_FAILURE); AddFailureInOtherThread(FATAL_FAILURE); } EXPECT_EQ(4, results.size()); EXPECT_TRUE(results.GetTestPartResult(0).nonfatally_failed()); EXPECT_TRUE(results.GetTestPartResult(1).fatally_failed()); EXPECT_TRUE(results.GetTestPartResult(2).nonfatally_failed()); EXPECT_TRUE(results.GetTestPartResult(3).fatally_failed()); } #endif // GTEST_IS_THREADSAFE // Tests EXPECT_FATAL_FAILURE{,ON_ALL_THREADS}. Makes sure that they // work even if the failure is generated in a called function rather than // the current context. typedef ScopedFakeTestPartResultReporterTest ExpectFatalFailureTest; TEST_F(ExpectFatalFailureTest, CatchesFatalFaliure) { EXPECT_FATAL_FAILURE(AddFatalFailure(), "Expected fatal failure."); } #if GTEST_HAS_GLOBAL_STRING TEST_F(ExpectFatalFailureTest, AcceptsStringObject) { EXPECT_FATAL_FAILURE(AddFatalFailure(), ::string("Expected fatal failure.")); } #endif TEST_F(ExpectFatalFailureTest, AcceptsStdStringObject) { EXPECT_FATAL_FAILURE(AddFatalFailure(), ::std::string("Expected fatal failure.")); } TEST_F(ExpectFatalFailureTest, CatchesFatalFailureOnAllThreads) { // We have another test below to verify that the macro catches fatal // failures generated on another thread. EXPECT_FATAL_FAILURE_ON_ALL_THREADS(AddFatalFailure(), "Expected fatal failure."); } #ifdef __BORLANDC__ // Silences warnings: "Condition is always true" # pragma option push -w-ccc #endif // Tests that EXPECT_FATAL_FAILURE() can be used in a non-void // function even when the statement in it contains ASSERT_*. int NonVoidFunction() { EXPECT_FATAL_FAILURE(ASSERT_TRUE(false), ""); EXPECT_FATAL_FAILURE_ON_ALL_THREADS(FAIL(), ""); return 0; } TEST_F(ExpectFatalFailureTest, CanBeUsedInNonVoidFunction) { NonVoidFunction(); } // Tests that EXPECT_FATAL_FAILURE(statement, ...) doesn't abort the // current function even though 'statement' generates a fatal failure. void DoesNotAbortHelper(bool* aborted) { EXPECT_FATAL_FAILURE(ASSERT_TRUE(false), ""); EXPECT_FATAL_FAILURE_ON_ALL_THREADS(FAIL(), ""); *aborted = false; } #ifdef __BORLANDC__ // Restores warnings after previous "#pragma option push" suppressed them. # pragma option pop #endif TEST_F(ExpectFatalFailureTest, DoesNotAbort) { bool aborted = true; DoesNotAbortHelper(&aborted); EXPECT_FALSE(aborted); } // Tests that the EXPECT_FATAL_FAILURE{,_ON_ALL_THREADS} accepts a // statement that contains a macro which expands to code containing an // unprotected comma. static int global_var = 0; #define GTEST_USE_UNPROTECTED_COMMA_ global_var++, global_var++ TEST_F(ExpectFatalFailureTest, AcceptsMacroThatExpandsToUnprotectedComma) { #ifndef __BORLANDC__ // ICE's in C++Builder. EXPECT_FATAL_FAILURE({ GTEST_USE_UNPROTECTED_COMMA_; AddFatalFailure(); }, ""); #endif EXPECT_FATAL_FAILURE_ON_ALL_THREADS({ GTEST_USE_UNPROTECTED_COMMA_; AddFatalFailure(); }, ""); } // Tests EXPECT_NONFATAL_FAILURE{,ON_ALL_THREADS}. typedef ScopedFakeTestPartResultReporterTest ExpectNonfatalFailureTest; TEST_F(ExpectNonfatalFailureTest, CatchesNonfatalFailure) { EXPECT_NONFATAL_FAILURE(AddNonfatalFailure(), "Expected non-fatal failure."); } #if GTEST_HAS_GLOBAL_STRING TEST_F(ExpectNonfatalFailureTest, AcceptsStringObject) { EXPECT_NONFATAL_FAILURE(AddNonfatalFailure(), ::string("Expected non-fatal failure.")); } #endif TEST_F(ExpectNonfatalFailureTest, AcceptsStdStringObject) { EXPECT_NONFATAL_FAILURE(AddNonfatalFailure(), ::std::string("Expected non-fatal failure.")); } TEST_F(ExpectNonfatalFailureTest, CatchesNonfatalFailureOnAllThreads) { // We have another test below to verify that the macro catches // non-fatal failures generated on another thread. EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS(AddNonfatalFailure(), "Expected non-fatal failure."); } // Tests that the EXPECT_NONFATAL_FAILURE{,_ON_ALL_THREADS} accepts a // statement that contains a macro which expands to code containing an // unprotected comma. TEST_F(ExpectNonfatalFailureTest, AcceptsMacroThatExpandsToUnprotectedComma) { EXPECT_NONFATAL_FAILURE({ GTEST_USE_UNPROTECTED_COMMA_; AddNonfatalFailure(); }, ""); EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS({ GTEST_USE_UNPROTECTED_COMMA_; AddNonfatalFailure(); }, ""); } #if GTEST_IS_THREADSAFE typedef ScopedFakeTestPartResultReporterWithThreadsTest ExpectFailureWithThreadsTest; TEST_F(ExpectFailureWithThreadsTest, ExpectFatalFailureOnAllThreads) { EXPECT_FATAL_FAILURE_ON_ALL_THREADS(AddFailureInOtherThread(FATAL_FAILURE), "Expected fatal failure."); } TEST_F(ExpectFailureWithThreadsTest, ExpectNonFatalFailureOnAllThreads) { EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS( AddFailureInOtherThread(NONFATAL_FAILURE), "Expected non-fatal failure."); } #endif // GTEST_IS_THREADSAFE // Tests the TestProperty class. TEST(TestPropertyTest, ConstructorWorks) { const TestProperty property("key", "value"); EXPECT_STREQ("key", property.key()); EXPECT_STREQ("value", property.value()); } TEST(TestPropertyTest, SetValue) { TestProperty property("key", "value_1"); EXPECT_STREQ("key", property.key()); property.SetValue("value_2"); EXPECT_STREQ("key", property.key()); EXPECT_STREQ("value_2", property.value()); } // Tests the TestResult class // The test fixture for testing TestResult. class TestResultTest : public Test { protected: typedef std::vector TPRVector; // We make use of 2 TestPartResult objects, TestPartResult * pr1, * pr2; // ... and 3 TestResult objects. TestResult * r0, * r1, * r2; virtual void SetUp() { // pr1 is for success. pr1 = new TestPartResult(TestPartResult::kSuccess, "foo/bar.cc", 10, "Success!"); // pr2 is for fatal failure. pr2 = new TestPartResult(TestPartResult::kFatalFailure, "foo/bar.cc", -1, // This line number means "unknown" "Failure!"); // Creates the TestResult objects. r0 = new TestResult(); r1 = new TestResult(); r2 = new TestResult(); // In order to test TestResult, we need to modify its internal // state, in particular the TestPartResult vector it holds. // test_part_results() returns a const reference to this vector. // We cast it to a non-const object s.t. it can be modified (yes, // this is a hack). TPRVector* results1 = const_cast( &TestResultAccessor::test_part_results(*r1)); TPRVector* results2 = const_cast( &TestResultAccessor::test_part_results(*r2)); // r0 is an empty TestResult. // r1 contains a single SUCCESS TestPartResult. results1->push_back(*pr1); // r2 contains a SUCCESS, and a FAILURE. results2->push_back(*pr1); results2->push_back(*pr2); } virtual void TearDown() { delete pr1; delete pr2; delete r0; delete r1; delete r2; } // Helper that compares two two TestPartResults. static void CompareTestPartResult(const TestPartResult& expected, const TestPartResult& actual) { EXPECT_EQ(expected.type(), actual.type()); EXPECT_STREQ(expected.file_name(), actual.file_name()); EXPECT_EQ(expected.line_number(), actual.line_number()); EXPECT_STREQ(expected.summary(), actual.summary()); EXPECT_STREQ(expected.message(), actual.message()); EXPECT_EQ(expected.passed(), actual.passed()); EXPECT_EQ(expected.failed(), actual.failed()); EXPECT_EQ(expected.nonfatally_failed(), actual.nonfatally_failed()); EXPECT_EQ(expected.fatally_failed(), actual.fatally_failed()); } }; // Tests TestResult::total_part_count(). TEST_F(TestResultTest, total_part_count) { ASSERT_EQ(0, r0->total_part_count()); ASSERT_EQ(1, r1->total_part_count()); ASSERT_EQ(2, r2->total_part_count()); } // Tests TestResult::Passed(). TEST_F(TestResultTest, Passed) { ASSERT_TRUE(r0->Passed()); ASSERT_TRUE(r1->Passed()); ASSERT_FALSE(r2->Passed()); } // Tests TestResult::Failed(). TEST_F(TestResultTest, Failed) { ASSERT_FALSE(r0->Failed()); ASSERT_FALSE(r1->Failed()); ASSERT_TRUE(r2->Failed()); } // Tests TestResult::GetTestPartResult(). typedef TestResultTest TestResultDeathTest; TEST_F(TestResultDeathTest, GetTestPartResult) { CompareTestPartResult(*pr1, r2->GetTestPartResult(0)); CompareTestPartResult(*pr2, r2->GetTestPartResult(1)); EXPECT_DEATH_IF_SUPPORTED(r2->GetTestPartResult(2), ""); EXPECT_DEATH_IF_SUPPORTED(r2->GetTestPartResult(-1), ""); } // Tests TestResult has no properties when none are added. TEST(TestResultPropertyTest, NoPropertiesFoundWhenNoneAreAdded) { TestResult test_result; ASSERT_EQ(0, test_result.test_property_count()); } // Tests TestResult has the expected property when added. TEST(TestResultPropertyTest, OnePropertyFoundWhenAdded) { TestResult test_result; TestProperty property("key_1", "1"); TestResultAccessor::RecordProperty(&test_result, "testcase", property); ASSERT_EQ(1, test_result.test_property_count()); const TestProperty& actual_property = test_result.GetTestProperty(0); EXPECT_STREQ("key_1", actual_property.key()); EXPECT_STREQ("1", actual_property.value()); } // Tests TestResult has multiple properties when added. TEST(TestResultPropertyTest, MultiplePropertiesFoundWhenAdded) { TestResult test_result; TestProperty property_1("key_1", "1"); TestProperty property_2("key_2", "2"); TestResultAccessor::RecordProperty(&test_result, "testcase", property_1); TestResultAccessor::RecordProperty(&test_result, "testcase", property_2); ASSERT_EQ(2, test_result.test_property_count()); const TestProperty& actual_property_1 = test_result.GetTestProperty(0); EXPECT_STREQ("key_1", actual_property_1.key()); EXPECT_STREQ("1", actual_property_1.value()); const TestProperty& actual_property_2 = test_result.GetTestProperty(1); EXPECT_STREQ("key_2", actual_property_2.key()); EXPECT_STREQ("2", actual_property_2.value()); } // Tests TestResult::RecordProperty() overrides values for duplicate keys. TEST(TestResultPropertyTest, OverridesValuesForDuplicateKeys) { TestResult test_result; TestProperty property_1_1("key_1", "1"); TestProperty property_2_1("key_2", "2"); TestProperty property_1_2("key_1", "12"); TestProperty property_2_2("key_2", "22"); TestResultAccessor::RecordProperty(&test_result, "testcase", property_1_1); TestResultAccessor::RecordProperty(&test_result, "testcase", property_2_1); TestResultAccessor::RecordProperty(&test_result, "testcase", property_1_2); TestResultAccessor::RecordProperty(&test_result, "testcase", property_2_2); ASSERT_EQ(2, test_result.test_property_count()); const TestProperty& actual_property_1 = test_result.GetTestProperty(0); EXPECT_STREQ("key_1", actual_property_1.key()); EXPECT_STREQ("12", actual_property_1.value()); const TestProperty& actual_property_2 = test_result.GetTestProperty(1); EXPECT_STREQ("key_2", actual_property_2.key()); EXPECT_STREQ("22", actual_property_2.value()); } // Tests TestResult::GetTestProperty(). TEST(TestResultPropertyTest, GetTestProperty) { TestResult test_result; TestProperty property_1("key_1", "1"); TestProperty property_2("key_2", "2"); TestProperty property_3("key_3", "3"); TestResultAccessor::RecordProperty(&test_result, "testcase", property_1); TestResultAccessor::RecordProperty(&test_result, "testcase", property_2); TestResultAccessor::RecordProperty(&test_result, "testcase", property_3); const TestProperty& fetched_property_1 = test_result.GetTestProperty(0); const TestProperty& fetched_property_2 = test_result.GetTestProperty(1); const TestProperty& fetched_property_3 = test_result.GetTestProperty(2); EXPECT_STREQ("key_1", fetched_property_1.key()); EXPECT_STREQ("1", fetched_property_1.value()); EXPECT_STREQ("key_2", fetched_property_2.key()); EXPECT_STREQ("2", fetched_property_2.value()); EXPECT_STREQ("key_3", fetched_property_3.key()); EXPECT_STREQ("3", fetched_property_3.value()); EXPECT_DEATH_IF_SUPPORTED(test_result.GetTestProperty(3), ""); EXPECT_DEATH_IF_SUPPORTED(test_result.GetTestProperty(-1), ""); } // Tests that GTestFlagSaver works on Windows and Mac. class GTestFlagSaverTest : public Test { protected: // Saves the Google Test flags such that we can restore them later, and // then sets them to their default values. This will be called // before the first test in this test case is run. static void SetUpTestCase() { saver_ = new GTestFlagSaver; GTEST_FLAG(also_run_disabled_tests) = false; GTEST_FLAG(break_on_failure) = false; GTEST_FLAG(catch_exceptions) = false; GTEST_FLAG(death_test_use_fork) = false; GTEST_FLAG(color) = "auto"; GTEST_FLAG(filter) = ""; GTEST_FLAG(list_tests) = false; GTEST_FLAG(output) = ""; GTEST_FLAG(print_time) = true; GTEST_FLAG(random_seed) = 0; GTEST_FLAG(repeat) = 1; GTEST_FLAG(shuffle) = false; GTEST_FLAG(stack_trace_depth) = kMaxStackTraceDepth; GTEST_FLAG(stream_result_to) = ""; GTEST_FLAG(throw_on_failure) = false; } // Restores the Google Test flags that the tests have modified. This will // be called after the last test in this test case is run. static void TearDownTestCase() { delete saver_; saver_ = NULL; } // Verifies that the Google Test flags have their default values, and then // modifies each of them. void VerifyAndModifyFlags() { EXPECT_FALSE(GTEST_FLAG(also_run_disabled_tests)); EXPECT_FALSE(GTEST_FLAG(break_on_failure)); EXPECT_FALSE(GTEST_FLAG(catch_exceptions)); EXPECT_STREQ("auto", GTEST_FLAG(color).c_str()); EXPECT_FALSE(GTEST_FLAG(death_test_use_fork)); EXPECT_STREQ("", GTEST_FLAG(filter).c_str()); EXPECT_FALSE(GTEST_FLAG(list_tests)); EXPECT_STREQ("", GTEST_FLAG(output).c_str()); EXPECT_TRUE(GTEST_FLAG(print_time)); EXPECT_EQ(0, GTEST_FLAG(random_seed)); EXPECT_EQ(1, GTEST_FLAG(repeat)); EXPECT_FALSE(GTEST_FLAG(shuffle)); EXPECT_EQ(kMaxStackTraceDepth, GTEST_FLAG(stack_trace_depth)); EXPECT_STREQ("", GTEST_FLAG(stream_result_to).c_str()); EXPECT_FALSE(GTEST_FLAG(throw_on_failure)); GTEST_FLAG(also_run_disabled_tests) = true; GTEST_FLAG(break_on_failure) = true; GTEST_FLAG(catch_exceptions) = true; GTEST_FLAG(color) = "no"; GTEST_FLAG(death_test_use_fork) = true; GTEST_FLAG(filter) = "abc"; GTEST_FLAG(list_tests) = true; GTEST_FLAG(output) = "xml:foo.xml"; GTEST_FLAG(print_time) = false; GTEST_FLAG(random_seed) = 1; GTEST_FLAG(repeat) = 100; GTEST_FLAG(shuffle) = true; GTEST_FLAG(stack_trace_depth) = 1; GTEST_FLAG(stream_result_to) = "localhost:1234"; GTEST_FLAG(throw_on_failure) = true; } private: // For saving Google Test flags during this test case. static GTestFlagSaver* saver_; }; GTestFlagSaver* GTestFlagSaverTest::saver_ = NULL; // Google Test doesn't guarantee the order of tests. The following two // tests are designed to work regardless of their order. // Modifies the Google Test flags in the test body. TEST_F(GTestFlagSaverTest, ModifyGTestFlags) { VerifyAndModifyFlags(); } // Verifies that the Google Test flags in the body of the previous test were // restored to their original values. TEST_F(GTestFlagSaverTest, VerifyGTestFlags) { VerifyAndModifyFlags(); } // Sets an environment variable with the given name to the given // value. If the value argument is "", unsets the environment // variable. The caller must ensure that both arguments are not NULL. static void SetEnv(const char* name, const char* value) { #if GTEST_OS_WINDOWS_MOBILE // Environment variables are not supported on Windows CE. return; #elif defined(__BORLANDC__) || defined(__SunOS_5_8) || defined(__SunOS_5_9) // C++Builder's putenv only stores a pointer to its parameter; we have to // ensure that the string remains valid as long as it might be needed. // We use an std::map to do so. static std::map added_env; // Because putenv stores a pointer to the string buffer, we can't delete the // previous string (if present) until after it's replaced. std::string *prev_env = NULL; if (added_env.find(name) != added_env.end()) { prev_env = added_env[name]; } added_env[name] = new std::string( (Message() << name << "=" << value).GetString()); // The standard signature of putenv accepts a 'char*' argument. Other // implementations, like C++Builder's, accept a 'const char*'. // We cast away the 'const' since that would work for both variants. putenv(const_cast(added_env[name]->c_str())); delete prev_env; #elif GTEST_OS_WINDOWS // If we are on Windows proper. _putenv((Message() << name << "=" << value).GetString().c_str()); #else if (*value == '\0') { unsetenv(name); } else { setenv(name, value, 1); } #endif // GTEST_OS_WINDOWS_MOBILE } #if !GTEST_OS_WINDOWS_MOBILE // Environment variables are not supported on Windows CE. using testing::internal::Int32FromGTestEnv; // Tests Int32FromGTestEnv(). // Tests that Int32FromGTestEnv() returns the default value when the // environment variable is not set. TEST(Int32FromGTestEnvTest, ReturnsDefaultWhenVariableIsNotSet) { SetEnv(GTEST_FLAG_PREFIX_UPPER_ "TEMP", ""); EXPECT_EQ(10, Int32FromGTestEnv("temp", 10)); } // Tests that Int32FromGTestEnv() returns the default value when the // environment variable overflows as an Int32. TEST(Int32FromGTestEnvTest, ReturnsDefaultWhenValueOverflows) { printf("(expecting 2 warnings)\n"); SetEnv(GTEST_FLAG_PREFIX_UPPER_ "TEMP", "12345678987654321"); EXPECT_EQ(20, Int32FromGTestEnv("temp", 20)); SetEnv(GTEST_FLAG_PREFIX_UPPER_ "TEMP", "-12345678987654321"); EXPECT_EQ(30, Int32FromGTestEnv("temp", 30)); } // Tests that Int32FromGTestEnv() returns the default value when the // environment variable does not represent a valid decimal integer. TEST(Int32FromGTestEnvTest, ReturnsDefaultWhenValueIsInvalid) { printf("(expecting 2 warnings)\n"); SetEnv(GTEST_FLAG_PREFIX_UPPER_ "TEMP", "A1"); EXPECT_EQ(40, Int32FromGTestEnv("temp", 40)); SetEnv(GTEST_FLAG_PREFIX_UPPER_ "TEMP", "12X"); EXPECT_EQ(50, Int32FromGTestEnv("temp", 50)); } // Tests that Int32FromGTestEnv() parses and returns the value of the // environment variable when it represents a valid decimal integer in // the range of an Int32. TEST(Int32FromGTestEnvTest, ParsesAndReturnsValidValue) { SetEnv(GTEST_FLAG_PREFIX_UPPER_ "TEMP", "123"); EXPECT_EQ(123, Int32FromGTestEnv("temp", 0)); SetEnv(GTEST_FLAG_PREFIX_UPPER_ "TEMP", "-321"); EXPECT_EQ(-321, Int32FromGTestEnv("temp", 0)); } #endif // !GTEST_OS_WINDOWS_MOBILE // Tests ParseInt32Flag(). // Tests that ParseInt32Flag() returns false and doesn't change the // output value when the flag has wrong format TEST(ParseInt32FlagTest, ReturnsFalseForInvalidFlag) { Int32 value = 123; EXPECT_FALSE(ParseInt32Flag("--a=100", "b", &value)); EXPECT_EQ(123, value); EXPECT_FALSE(ParseInt32Flag("a=100", "a", &value)); EXPECT_EQ(123, value); } // Tests that ParseInt32Flag() returns false and doesn't change the // output value when the flag overflows as an Int32. TEST(ParseInt32FlagTest, ReturnsDefaultWhenValueOverflows) { printf("(expecting 2 warnings)\n"); Int32 value = 123; EXPECT_FALSE(ParseInt32Flag("--abc=12345678987654321", "abc", &value)); EXPECT_EQ(123, value); EXPECT_FALSE(ParseInt32Flag("--abc=-12345678987654321", "abc", &value)); EXPECT_EQ(123, value); } // Tests that ParseInt32Flag() returns false and doesn't change the // output value when the flag does not represent a valid decimal // integer. TEST(ParseInt32FlagTest, ReturnsDefaultWhenValueIsInvalid) { printf("(expecting 2 warnings)\n"); Int32 value = 123; EXPECT_FALSE(ParseInt32Flag("--abc=A1", "abc", &value)); EXPECT_EQ(123, value); EXPECT_FALSE(ParseInt32Flag("--abc=12X", "abc", &value)); EXPECT_EQ(123, value); } // Tests that ParseInt32Flag() parses the value of the flag and // returns true when the flag represents a valid decimal integer in // the range of an Int32. TEST(ParseInt32FlagTest, ParsesAndReturnsValidValue) { Int32 value = 123; EXPECT_TRUE(ParseInt32Flag("--" GTEST_FLAG_PREFIX_ "abc=456", "abc", &value)); EXPECT_EQ(456, value); EXPECT_TRUE(ParseInt32Flag("--" GTEST_FLAG_PREFIX_ "abc=-789", "abc", &value)); EXPECT_EQ(-789, value); } // Tests that Int32FromEnvOrDie() parses the value of the var or // returns the correct default. // Environment variables are not supported on Windows CE. #if !GTEST_OS_WINDOWS_MOBILE TEST(Int32FromEnvOrDieTest, ParsesAndReturnsValidValue) { EXPECT_EQ(333, Int32FromEnvOrDie(GTEST_FLAG_PREFIX_UPPER_ "UnsetVar", 333)); SetEnv(GTEST_FLAG_PREFIX_UPPER_ "UnsetVar", "123"); EXPECT_EQ(123, Int32FromEnvOrDie(GTEST_FLAG_PREFIX_UPPER_ "UnsetVar", 333)); SetEnv(GTEST_FLAG_PREFIX_UPPER_ "UnsetVar", "-123"); EXPECT_EQ(-123, Int32FromEnvOrDie(GTEST_FLAG_PREFIX_UPPER_ "UnsetVar", 333)); } #endif // !GTEST_OS_WINDOWS_MOBILE // Tests that Int32FromEnvOrDie() aborts with an error message // if the variable is not an Int32. TEST(Int32FromEnvOrDieDeathTest, AbortsOnFailure) { SetEnv(GTEST_FLAG_PREFIX_UPPER_ "VAR", "xxx"); EXPECT_DEATH_IF_SUPPORTED( Int32FromEnvOrDie(GTEST_FLAG_PREFIX_UPPER_ "VAR", 123), ".*"); } // Tests that Int32FromEnvOrDie() aborts with an error message // if the variable cannot be represnted by an Int32. TEST(Int32FromEnvOrDieDeathTest, AbortsOnInt32Overflow) { SetEnv(GTEST_FLAG_PREFIX_UPPER_ "VAR", "1234567891234567891234"); EXPECT_DEATH_IF_SUPPORTED( Int32FromEnvOrDie(GTEST_FLAG_PREFIX_UPPER_ "VAR", 123), ".*"); } // Tests that ShouldRunTestOnShard() selects all tests // where there is 1 shard. TEST(ShouldRunTestOnShardTest, IsPartitionWhenThereIsOneShard) { EXPECT_TRUE(ShouldRunTestOnShard(1, 0, 0)); EXPECT_TRUE(ShouldRunTestOnShard(1, 0, 1)); EXPECT_TRUE(ShouldRunTestOnShard(1, 0, 2)); EXPECT_TRUE(ShouldRunTestOnShard(1, 0, 3)); EXPECT_TRUE(ShouldRunTestOnShard(1, 0, 4)); } class ShouldShardTest : public testing::Test { protected: virtual void SetUp() { index_var_ = GTEST_FLAG_PREFIX_UPPER_ "INDEX"; total_var_ = GTEST_FLAG_PREFIX_UPPER_ "TOTAL"; } virtual void TearDown() { SetEnv(index_var_, ""); SetEnv(total_var_, ""); } const char* index_var_; const char* total_var_; }; // Tests that sharding is disabled if neither of the environment variables // are set. TEST_F(ShouldShardTest, ReturnsFalseWhenNeitherEnvVarIsSet) { SetEnv(index_var_, ""); SetEnv(total_var_, ""); EXPECT_FALSE(ShouldShard(total_var_, index_var_, false)); EXPECT_FALSE(ShouldShard(total_var_, index_var_, true)); } // Tests that sharding is not enabled if total_shards == 1. TEST_F(ShouldShardTest, ReturnsFalseWhenTotalShardIsOne) { SetEnv(index_var_, "0"); SetEnv(total_var_, "1"); EXPECT_FALSE(ShouldShard(total_var_, index_var_, false)); EXPECT_FALSE(ShouldShard(total_var_, index_var_, true)); } // Tests that sharding is enabled if total_shards > 1 and // we are not in a death test subprocess. // Environment variables are not supported on Windows CE. #if !GTEST_OS_WINDOWS_MOBILE TEST_F(ShouldShardTest, WorksWhenShardEnvVarsAreValid) { SetEnv(index_var_, "4"); SetEnv(total_var_, "22"); EXPECT_TRUE(ShouldShard(total_var_, index_var_, false)); EXPECT_FALSE(ShouldShard(total_var_, index_var_, true)); SetEnv(index_var_, "8"); SetEnv(total_var_, "9"); EXPECT_TRUE(ShouldShard(total_var_, index_var_, false)); EXPECT_FALSE(ShouldShard(total_var_, index_var_, true)); SetEnv(index_var_, "0"); SetEnv(total_var_, "9"); EXPECT_TRUE(ShouldShard(total_var_, index_var_, false)); EXPECT_FALSE(ShouldShard(total_var_, index_var_, true)); } #endif // !GTEST_OS_WINDOWS_MOBILE // Tests that we exit in error if the sharding values are not valid. typedef ShouldShardTest ShouldShardDeathTest; TEST_F(ShouldShardDeathTest, AbortsWhenShardingEnvVarsAreInvalid) { SetEnv(index_var_, "4"); SetEnv(total_var_, "4"); EXPECT_DEATH_IF_SUPPORTED(ShouldShard(total_var_, index_var_, false), ".*"); SetEnv(index_var_, "4"); SetEnv(total_var_, "-2"); EXPECT_DEATH_IF_SUPPORTED(ShouldShard(total_var_, index_var_, false), ".*"); SetEnv(index_var_, "5"); SetEnv(total_var_, ""); EXPECT_DEATH_IF_SUPPORTED(ShouldShard(total_var_, index_var_, false), ".*"); SetEnv(index_var_, ""); SetEnv(total_var_, "5"); EXPECT_DEATH_IF_SUPPORTED(ShouldShard(total_var_, index_var_, false), ".*"); } // Tests that ShouldRunTestOnShard is a partition when 5 // shards are used. TEST(ShouldRunTestOnShardTest, IsPartitionWhenThereAreFiveShards) { // Choose an arbitrary number of tests and shards. const int num_tests = 17; const int num_shards = 5; // Check partitioning: each test should be on exactly 1 shard. for (int test_id = 0; test_id < num_tests; test_id++) { int prev_selected_shard_index = -1; for (int shard_index = 0; shard_index < num_shards; shard_index++) { if (ShouldRunTestOnShard(num_shards, shard_index, test_id)) { if (prev_selected_shard_index < 0) { prev_selected_shard_index = shard_index; } else { ADD_FAILURE() << "Shard " << prev_selected_shard_index << " and " << shard_index << " are both selected to run test " << test_id; } } } } // Check balance: This is not required by the sharding protocol, but is a // desirable property for performance. for (int shard_index = 0; shard_index < num_shards; shard_index++) { int num_tests_on_shard = 0; for (int test_id = 0; test_id < num_tests; test_id++) { num_tests_on_shard += ShouldRunTestOnShard(num_shards, shard_index, test_id); } EXPECT_GE(num_tests_on_shard, num_tests / num_shards); } } // For the same reason we are not explicitly testing everything in the // Test class, there are no separate tests for the following classes // (except for some trivial cases): // // TestCase, UnitTest, UnitTestResultPrinter. // // Similarly, there are no separate tests for the following macros: // // TEST, TEST_F, RUN_ALL_TESTS TEST(UnitTestTest, CanGetOriginalWorkingDir) { ASSERT_TRUE(UnitTest::GetInstance()->original_working_dir() != NULL); EXPECT_STRNE(UnitTest::GetInstance()->original_working_dir(), ""); } TEST(UnitTestTest, ReturnsPlausibleTimestamp) { EXPECT_LT(0, UnitTest::GetInstance()->start_timestamp()); EXPECT_LE(UnitTest::GetInstance()->start_timestamp(), GetTimeInMillis()); } // When a property using a reserved key is supplied to this function, it // tests that a non-fatal failure is added, a fatal failure is not added, // and that the property is not recorded. void ExpectNonFatalFailureRecordingPropertyWithReservedKey( const TestResult& test_result, const char* key) { EXPECT_NONFATAL_FAILURE(Test::RecordProperty(key, "1"), "Reserved key"); ASSERT_EQ(0, test_result.test_property_count()) << "Property for key '" << key << "' recorded unexpectedly."; } void ExpectNonFatalFailureRecordingPropertyWithReservedKeyForCurrentTest( const char* key) { const TestInfo* test_info = UnitTest::GetInstance()->current_test_info(); ASSERT_TRUE(test_info != NULL); ExpectNonFatalFailureRecordingPropertyWithReservedKey(*test_info->result(), key); } void ExpectNonFatalFailureRecordingPropertyWithReservedKeyForCurrentTestCase( const char* key) { const TestCase* test_case = UnitTest::GetInstance()->current_test_case(); ASSERT_TRUE(test_case != NULL); ExpectNonFatalFailureRecordingPropertyWithReservedKey( test_case->ad_hoc_test_result(), key); } void ExpectNonFatalFailureRecordingPropertyWithReservedKeyOutsideOfTestCase( const char* key) { ExpectNonFatalFailureRecordingPropertyWithReservedKey( UnitTest::GetInstance()->ad_hoc_test_result(), key); } // Tests that property recording functions in UnitTest outside of tests // functions correcly. Creating a separate instance of UnitTest ensures it // is in a state similar to the UnitTest's singleton's between tests. class UnitTestRecordPropertyTest : public testing::internal::UnitTestRecordPropertyTestHelper { public: static void SetUpTestCase() { ExpectNonFatalFailureRecordingPropertyWithReservedKeyForCurrentTestCase( "disabled"); ExpectNonFatalFailureRecordingPropertyWithReservedKeyForCurrentTestCase( "errors"); ExpectNonFatalFailureRecordingPropertyWithReservedKeyForCurrentTestCase( "failures"); ExpectNonFatalFailureRecordingPropertyWithReservedKeyForCurrentTestCase( "name"); ExpectNonFatalFailureRecordingPropertyWithReservedKeyForCurrentTestCase( "tests"); ExpectNonFatalFailureRecordingPropertyWithReservedKeyForCurrentTestCase( "time"); Test::RecordProperty("test_case_key_1", "1"); const TestCase* test_case = UnitTest::GetInstance()->current_test_case(); ASSERT_TRUE(test_case != NULL); ASSERT_EQ(1, test_case->ad_hoc_test_result().test_property_count()); EXPECT_STREQ("test_case_key_1", test_case->ad_hoc_test_result().GetTestProperty(0).key()); EXPECT_STREQ("1", test_case->ad_hoc_test_result().GetTestProperty(0).value()); } }; // Tests TestResult has the expected property when added. TEST_F(UnitTestRecordPropertyTest, OnePropertyFoundWhenAdded) { UnitTestRecordProperty("key_1", "1"); ASSERT_EQ(1, unit_test_.ad_hoc_test_result().test_property_count()); EXPECT_STREQ("key_1", unit_test_.ad_hoc_test_result().GetTestProperty(0).key()); EXPECT_STREQ("1", unit_test_.ad_hoc_test_result().GetTestProperty(0).value()); } // Tests TestResult has multiple properties when added. TEST_F(UnitTestRecordPropertyTest, MultiplePropertiesFoundWhenAdded) { UnitTestRecordProperty("key_1", "1"); UnitTestRecordProperty("key_2", "2"); ASSERT_EQ(2, unit_test_.ad_hoc_test_result().test_property_count()); EXPECT_STREQ("key_1", unit_test_.ad_hoc_test_result().GetTestProperty(0).key()); EXPECT_STREQ("1", unit_test_.ad_hoc_test_result().GetTestProperty(0).value()); EXPECT_STREQ("key_2", unit_test_.ad_hoc_test_result().GetTestProperty(1).key()); EXPECT_STREQ("2", unit_test_.ad_hoc_test_result().GetTestProperty(1).value()); } // Tests TestResult::RecordProperty() overrides values for duplicate keys. TEST_F(UnitTestRecordPropertyTest, OverridesValuesForDuplicateKeys) { UnitTestRecordProperty("key_1", "1"); UnitTestRecordProperty("key_2", "2"); UnitTestRecordProperty("key_1", "12"); UnitTestRecordProperty("key_2", "22"); ASSERT_EQ(2, unit_test_.ad_hoc_test_result().test_property_count()); EXPECT_STREQ("key_1", unit_test_.ad_hoc_test_result().GetTestProperty(0).key()); EXPECT_STREQ("12", unit_test_.ad_hoc_test_result().GetTestProperty(0).value()); EXPECT_STREQ("key_2", unit_test_.ad_hoc_test_result().GetTestProperty(1).key()); EXPECT_STREQ("22", unit_test_.ad_hoc_test_result().GetTestProperty(1).value()); } TEST_F(UnitTestRecordPropertyTest, AddFailureInsideTestsWhenUsingTestCaseReservedKeys) { ExpectNonFatalFailureRecordingPropertyWithReservedKeyForCurrentTest( "name"); ExpectNonFatalFailureRecordingPropertyWithReservedKeyForCurrentTest( "value_param"); ExpectNonFatalFailureRecordingPropertyWithReservedKeyForCurrentTest( "type_param"); ExpectNonFatalFailureRecordingPropertyWithReservedKeyForCurrentTest( "status"); ExpectNonFatalFailureRecordingPropertyWithReservedKeyForCurrentTest( "time"); ExpectNonFatalFailureRecordingPropertyWithReservedKeyForCurrentTest( "classname"); } TEST_F(UnitTestRecordPropertyTest, AddRecordWithReservedKeysGeneratesCorrectPropertyList) { EXPECT_NONFATAL_FAILURE( Test::RecordProperty("name", "1"), "'classname', 'name', 'status', 'time', 'type_param', and 'value_param'" " are reserved"); } class UnitTestRecordPropertyTestEnvironment : public Environment { public: virtual void TearDown() { ExpectNonFatalFailureRecordingPropertyWithReservedKeyOutsideOfTestCase( "tests"); ExpectNonFatalFailureRecordingPropertyWithReservedKeyOutsideOfTestCase( "failures"); ExpectNonFatalFailureRecordingPropertyWithReservedKeyOutsideOfTestCase( "disabled"); ExpectNonFatalFailureRecordingPropertyWithReservedKeyOutsideOfTestCase( "errors"); ExpectNonFatalFailureRecordingPropertyWithReservedKeyOutsideOfTestCase( "name"); ExpectNonFatalFailureRecordingPropertyWithReservedKeyOutsideOfTestCase( "timestamp"); ExpectNonFatalFailureRecordingPropertyWithReservedKeyOutsideOfTestCase( "time"); ExpectNonFatalFailureRecordingPropertyWithReservedKeyOutsideOfTestCase( "random_seed"); } }; // This will test property recording outside of any test or test case. static Environment* record_property_env = AddGlobalTestEnvironment(new UnitTestRecordPropertyTestEnvironment); // This group of tests is for predicate assertions (ASSERT_PRED*, etc) // of various arities. They do not attempt to be exhaustive. Rather, // view them as smoke tests that can be easily reviewed and verified. // A more complete set of tests for predicate assertions can be found // in gtest_pred_impl_unittest.cc. // First, some predicates and predicate-formatters needed by the tests. // Returns true iff the argument is an even number. bool IsEven(int n) { return (n % 2) == 0; } // A functor that returns true iff the argument is an even number. struct IsEvenFunctor { bool operator()(int n) { return IsEven(n); } }; // A predicate-formatter function that asserts the argument is an even // number. AssertionResult AssertIsEven(const char* expr, int n) { if (IsEven(n)) { return AssertionSuccess(); } Message msg; msg << expr << " evaluates to " << n << ", which is not even."; return AssertionFailure(msg); } // A predicate function that returns AssertionResult for use in // EXPECT/ASSERT_TRUE/FALSE. AssertionResult ResultIsEven(int n) { if (IsEven(n)) return AssertionSuccess() << n << " is even"; else return AssertionFailure() << n << " is odd"; } // A predicate function that returns AssertionResult but gives no // explanation why it succeeds. Needed for testing that // EXPECT/ASSERT_FALSE handles such functions correctly. AssertionResult ResultIsEvenNoExplanation(int n) { if (IsEven(n)) return AssertionSuccess(); else return AssertionFailure() << n << " is odd"; } // A predicate-formatter functor that asserts the argument is an even // number. struct AssertIsEvenFunctor { AssertionResult operator()(const char* expr, int n) { return AssertIsEven(expr, n); } }; // Returns true iff the sum of the arguments is an even number. bool SumIsEven2(int n1, int n2) { return IsEven(n1 + n2); } // A functor that returns true iff the sum of the arguments is an even // number. struct SumIsEven3Functor { bool operator()(int n1, int n2, int n3) { return IsEven(n1 + n2 + n3); } }; // A predicate-formatter function that asserts the sum of the // arguments is an even number. AssertionResult AssertSumIsEven4( const char* e1, const char* e2, const char* e3, const char* e4, int n1, int n2, int n3, int n4) { const int sum = n1 + n2 + n3 + n4; if (IsEven(sum)) { return AssertionSuccess(); } Message msg; msg << e1 << " + " << e2 << " + " << e3 << " + " << e4 << " (" << n1 << " + " << n2 << " + " << n3 << " + " << n4 << ") evaluates to " << sum << ", which is not even."; return AssertionFailure(msg); } // A predicate-formatter functor that asserts the sum of the arguments // is an even number. struct AssertSumIsEven5Functor { AssertionResult operator()( const char* e1, const char* e2, const char* e3, const char* e4, const char* e5, int n1, int n2, int n3, int n4, int n5) { const int sum = n1 + n2 + n3 + n4 + n5; if (IsEven(sum)) { return AssertionSuccess(); } Message msg; msg << e1 << " + " << e2 << " + " << e3 << " + " << e4 << " + " << e5 << " (" << n1 << " + " << n2 << " + " << n3 << " + " << n4 << " + " << n5 << ") evaluates to " << sum << ", which is not even."; return AssertionFailure(msg); } }; // Tests unary predicate assertions. // Tests unary predicate assertions that don't use a custom formatter. TEST(Pred1Test, WithoutFormat) { // Success cases. EXPECT_PRED1(IsEvenFunctor(), 2) << "This failure is UNEXPECTED!"; ASSERT_PRED1(IsEven, 4); // Failure cases. EXPECT_NONFATAL_FAILURE({ // NOLINT EXPECT_PRED1(IsEven, 5) << "This failure is expected."; }, "This failure is expected."); EXPECT_FATAL_FAILURE(ASSERT_PRED1(IsEvenFunctor(), 5), "evaluates to false"); } // Tests unary predicate assertions that use a custom formatter. TEST(Pred1Test, WithFormat) { // Success cases. EXPECT_PRED_FORMAT1(AssertIsEven, 2); ASSERT_PRED_FORMAT1(AssertIsEvenFunctor(), 4) << "This failure is UNEXPECTED!"; // Failure cases. const int n = 5; EXPECT_NONFATAL_FAILURE(EXPECT_PRED_FORMAT1(AssertIsEvenFunctor(), n), "n evaluates to 5, which is not even."); EXPECT_FATAL_FAILURE({ // NOLINT ASSERT_PRED_FORMAT1(AssertIsEven, 5) << "This failure is expected."; }, "This failure is expected."); } // Tests that unary predicate assertions evaluates their arguments // exactly once. TEST(Pred1Test, SingleEvaluationOnFailure) { // A success case. static int n = 0; EXPECT_PRED1(IsEven, n++); EXPECT_EQ(1, n) << "The argument is not evaluated exactly once."; // A failure case. EXPECT_FATAL_FAILURE({ // NOLINT ASSERT_PRED_FORMAT1(AssertIsEvenFunctor(), n++) << "This failure is expected."; }, "This failure is expected."); EXPECT_EQ(2, n) << "The argument is not evaluated exactly once."; } // Tests predicate assertions whose arity is >= 2. // Tests predicate assertions that don't use a custom formatter. TEST(PredTest, WithoutFormat) { // Success cases. ASSERT_PRED2(SumIsEven2, 2, 4) << "This failure is UNEXPECTED!"; EXPECT_PRED3(SumIsEven3Functor(), 4, 6, 8); // Failure cases. const int n1 = 1; const int n2 = 2; EXPECT_NONFATAL_FAILURE({ // NOLINT EXPECT_PRED2(SumIsEven2, n1, n2) << "This failure is expected."; }, "This failure is expected."); EXPECT_FATAL_FAILURE({ // NOLINT ASSERT_PRED3(SumIsEven3Functor(), 1, 2, 4); }, "evaluates to false"); } // Tests predicate assertions that use a custom formatter. TEST(PredTest, WithFormat) { // Success cases. ASSERT_PRED_FORMAT4(AssertSumIsEven4, 4, 6, 8, 10) << "This failure is UNEXPECTED!"; EXPECT_PRED_FORMAT5(AssertSumIsEven5Functor(), 2, 4, 6, 8, 10); // Failure cases. const int n1 = 1; const int n2 = 2; const int n3 = 4; const int n4 = 6; EXPECT_NONFATAL_FAILURE({ // NOLINT EXPECT_PRED_FORMAT4(AssertSumIsEven4, n1, n2, n3, n4); }, "evaluates to 13, which is not even."); EXPECT_FATAL_FAILURE({ // NOLINT ASSERT_PRED_FORMAT5(AssertSumIsEven5Functor(), 1, 2, 4, 6, 8) << "This failure is expected."; }, "This failure is expected."); } // Tests that predicate assertions evaluates their arguments // exactly once. TEST(PredTest, SingleEvaluationOnFailure) { // A success case. int n1 = 0; int n2 = 0; EXPECT_PRED2(SumIsEven2, n1++, n2++); EXPECT_EQ(1, n1) << "Argument 1 is not evaluated exactly once."; EXPECT_EQ(1, n2) << "Argument 2 is not evaluated exactly once."; // Another success case. n1 = n2 = 0; int n3 = 0; int n4 = 0; int n5 = 0; ASSERT_PRED_FORMAT5(AssertSumIsEven5Functor(), n1++, n2++, n3++, n4++, n5++) << "This failure is UNEXPECTED!"; EXPECT_EQ(1, n1) << "Argument 1 is not evaluated exactly once."; EXPECT_EQ(1, n2) << "Argument 2 is not evaluated exactly once."; EXPECT_EQ(1, n3) << "Argument 3 is not evaluated exactly once."; EXPECT_EQ(1, n4) << "Argument 4 is not evaluated exactly once."; EXPECT_EQ(1, n5) << "Argument 5 is not evaluated exactly once."; // A failure case. n1 = n2 = n3 = 0; EXPECT_NONFATAL_FAILURE({ // NOLINT EXPECT_PRED3(SumIsEven3Functor(), ++n1, n2++, n3++) << "This failure is expected."; }, "This failure is expected."); EXPECT_EQ(1, n1) << "Argument 1 is not evaluated exactly once."; EXPECT_EQ(1, n2) << "Argument 2 is not evaluated exactly once."; EXPECT_EQ(1, n3) << "Argument 3 is not evaluated exactly once."; // Another failure case. n1 = n2 = n3 = n4 = 0; EXPECT_NONFATAL_FAILURE({ // NOLINT EXPECT_PRED_FORMAT4(AssertSumIsEven4, ++n1, n2++, n3++, n4++); }, "evaluates to 1, which is not even."); EXPECT_EQ(1, n1) << "Argument 1 is not evaluated exactly once."; EXPECT_EQ(1, n2) << "Argument 2 is not evaluated exactly once."; EXPECT_EQ(1, n3) << "Argument 3 is not evaluated exactly once."; EXPECT_EQ(1, n4) << "Argument 4 is not evaluated exactly once."; } // Some helper functions for testing using overloaded/template // functions with ASSERT_PREDn and EXPECT_PREDn. bool IsPositive(double x) { return x > 0; } template bool IsNegative(T x) { return x < 0; } template bool GreaterThan(T1 x1, T2 x2) { return x1 > x2; } // Tests that overloaded functions can be used in *_PRED* as long as // their types are explicitly specified. TEST(PredicateAssertionTest, AcceptsOverloadedFunction) { // C++Builder requires C-style casts rather than static_cast. EXPECT_PRED1((bool (*)(int))(IsPositive), 5); // NOLINT ASSERT_PRED1((bool (*)(double))(IsPositive), 6.0); // NOLINT } // Tests that template functions can be used in *_PRED* as long as // their types are explicitly specified. TEST(PredicateAssertionTest, AcceptsTemplateFunction) { EXPECT_PRED1(IsNegative, -5); // Makes sure that we can handle templates with more than one // parameter. ASSERT_PRED2((GreaterThan), 5, 0); } // Some helper functions for testing using overloaded/template // functions with ASSERT_PRED_FORMATn and EXPECT_PRED_FORMATn. AssertionResult IsPositiveFormat(const char* /* expr */, int n) { return n > 0 ? AssertionSuccess() : AssertionFailure(Message() << "Failure"); } AssertionResult IsPositiveFormat(const char* /* expr */, double x) { return x > 0 ? AssertionSuccess() : AssertionFailure(Message() << "Failure"); } template AssertionResult IsNegativeFormat(const char* /* expr */, T x) { return x < 0 ? AssertionSuccess() : AssertionFailure(Message() << "Failure"); } template AssertionResult EqualsFormat(const char* /* expr1 */, const char* /* expr2 */, const T1& x1, const T2& x2) { return x1 == x2 ? AssertionSuccess() : AssertionFailure(Message() << "Failure"); } // Tests that overloaded functions can be used in *_PRED_FORMAT* // without explicitly specifying their types. TEST(PredicateFormatAssertionTest, AcceptsOverloadedFunction) { EXPECT_PRED_FORMAT1(IsPositiveFormat, 5); ASSERT_PRED_FORMAT1(IsPositiveFormat, 6.0); } // Tests that template functions can be used in *_PRED_FORMAT* without // explicitly specifying their types. TEST(PredicateFormatAssertionTest, AcceptsTemplateFunction) { EXPECT_PRED_FORMAT1(IsNegativeFormat, -5); ASSERT_PRED_FORMAT2(EqualsFormat, 3, 3); } // Tests string assertions. // Tests ASSERT_STREQ with non-NULL arguments. TEST(StringAssertionTest, ASSERT_STREQ) { const char * const p1 = "good"; ASSERT_STREQ(p1, p1); // Let p2 have the same content as p1, but be at a different address. const char p2[] = "good"; ASSERT_STREQ(p1, p2); EXPECT_FATAL_FAILURE(ASSERT_STREQ("bad", "good"), "Expected: \"bad\""); } // Tests ASSERT_STREQ with NULL arguments. TEST(StringAssertionTest, ASSERT_STREQ_Null) { ASSERT_STREQ(static_cast(NULL), NULL); EXPECT_FATAL_FAILURE(ASSERT_STREQ(NULL, "non-null"), "non-null"); } // Tests ASSERT_STREQ with NULL arguments. TEST(StringAssertionTest, ASSERT_STREQ_Null2) { EXPECT_FATAL_FAILURE(ASSERT_STREQ("non-null", NULL), "non-null"); } // Tests ASSERT_STRNE. TEST(StringAssertionTest, ASSERT_STRNE) { ASSERT_STRNE("hi", "Hi"); ASSERT_STRNE("Hi", NULL); ASSERT_STRNE(NULL, "Hi"); ASSERT_STRNE("", NULL); ASSERT_STRNE(NULL, ""); ASSERT_STRNE("", "Hi"); ASSERT_STRNE("Hi", ""); EXPECT_FATAL_FAILURE(ASSERT_STRNE("Hi", "Hi"), "\"Hi\" vs \"Hi\""); } // Tests ASSERT_STRCASEEQ. TEST(StringAssertionTest, ASSERT_STRCASEEQ) { ASSERT_STRCASEEQ("hi", "Hi"); ASSERT_STRCASEEQ(static_cast(NULL), NULL); ASSERT_STRCASEEQ("", ""); EXPECT_FATAL_FAILURE(ASSERT_STRCASEEQ("Hi", "hi2"), "(ignoring case)"); } // Tests ASSERT_STRCASENE. TEST(StringAssertionTest, ASSERT_STRCASENE) { ASSERT_STRCASENE("hi1", "Hi2"); ASSERT_STRCASENE("Hi", NULL); ASSERT_STRCASENE(NULL, "Hi"); ASSERT_STRCASENE("", NULL); ASSERT_STRCASENE(NULL, ""); ASSERT_STRCASENE("", "Hi"); ASSERT_STRCASENE("Hi", ""); EXPECT_FATAL_FAILURE(ASSERT_STRCASENE("Hi", "hi"), "(ignoring case)"); } // Tests *_STREQ on wide strings. TEST(StringAssertionTest, STREQ_Wide) { // NULL strings. ASSERT_STREQ(static_cast(NULL), NULL); // Empty strings. ASSERT_STREQ(L"", L""); // Non-null vs NULL. EXPECT_NONFATAL_FAILURE(EXPECT_STREQ(L"non-null", NULL), "non-null"); // Equal strings. EXPECT_STREQ(L"Hi", L"Hi"); // Unequal strings. EXPECT_NONFATAL_FAILURE(EXPECT_STREQ(L"abc", L"Abc"), "Abc"); // Strings containing wide characters. EXPECT_NONFATAL_FAILURE(EXPECT_STREQ(L"abc\x8119", L"abc\x8120"), "abc"); // The streaming variation. EXPECT_NONFATAL_FAILURE({ // NOLINT EXPECT_STREQ(L"abc\x8119", L"abc\x8121") << "Expected failure"; }, "Expected failure"); } // Tests *_STRNE on wide strings. TEST(StringAssertionTest, STRNE_Wide) { // NULL strings. EXPECT_NONFATAL_FAILURE({ // NOLINT EXPECT_STRNE(static_cast(NULL), NULL); }, ""); // Empty strings. EXPECT_NONFATAL_FAILURE(EXPECT_STRNE(L"", L""), "L\"\""); // Non-null vs NULL. ASSERT_STRNE(L"non-null", NULL); // Equal strings. EXPECT_NONFATAL_FAILURE(EXPECT_STRNE(L"Hi", L"Hi"), "L\"Hi\""); // Unequal strings. EXPECT_STRNE(L"abc", L"Abc"); // Strings containing wide characters. EXPECT_NONFATAL_FAILURE(EXPECT_STRNE(L"abc\x8119", L"abc\x8119"), "abc"); // The streaming variation. ASSERT_STRNE(L"abc\x8119", L"abc\x8120") << "This shouldn't happen"; } // Tests for ::testing::IsSubstring(). // Tests that IsSubstring() returns the correct result when the input // argument type is const char*. TEST(IsSubstringTest, ReturnsCorrectResultForCString) { EXPECT_FALSE(IsSubstring("", "", NULL, "a")); EXPECT_FALSE(IsSubstring("", "", "b", NULL)); EXPECT_FALSE(IsSubstring("", "", "needle", "haystack")); EXPECT_TRUE(IsSubstring("", "", static_cast(NULL), NULL)); EXPECT_TRUE(IsSubstring("", "", "needle", "two needles")); } // Tests that IsSubstring() returns the correct result when the input // argument type is const wchar_t*. TEST(IsSubstringTest, ReturnsCorrectResultForWideCString) { EXPECT_FALSE(IsSubstring("", "", kNull, L"a")); EXPECT_FALSE(IsSubstring("", "", L"b", kNull)); EXPECT_FALSE(IsSubstring("", "", L"needle", L"haystack")); EXPECT_TRUE(IsSubstring("", "", static_cast(NULL), NULL)); EXPECT_TRUE(IsSubstring("", "", L"needle", L"two needles")); } // Tests that IsSubstring() generates the correct message when the input // argument type is const char*. TEST(IsSubstringTest, GeneratesCorrectMessageForCString) { EXPECT_STREQ("Value of: needle_expr\n" " Actual: \"needle\"\n" "Expected: a substring of haystack_expr\n" "Which is: \"haystack\"", IsSubstring("needle_expr", "haystack_expr", "needle", "haystack").failure_message()); } // Tests that IsSubstring returns the correct result when the input // argument type is ::std::string. TEST(IsSubstringTest, ReturnsCorrectResultsForStdString) { EXPECT_TRUE(IsSubstring("", "", std::string("hello"), "ahellob")); EXPECT_FALSE(IsSubstring("", "", "hello", std::string("world"))); } #if GTEST_HAS_STD_WSTRING // Tests that IsSubstring returns the correct result when the input // argument type is ::std::wstring. TEST(IsSubstringTest, ReturnsCorrectResultForStdWstring) { EXPECT_TRUE(IsSubstring("", "", ::std::wstring(L"needle"), L"two needles")); EXPECT_FALSE(IsSubstring("", "", L"needle", ::std::wstring(L"haystack"))); } // Tests that IsSubstring() generates the correct message when the input // argument type is ::std::wstring. TEST(IsSubstringTest, GeneratesCorrectMessageForWstring) { EXPECT_STREQ("Value of: needle_expr\n" " Actual: L\"needle\"\n" "Expected: a substring of haystack_expr\n" "Which is: L\"haystack\"", IsSubstring( "needle_expr", "haystack_expr", ::std::wstring(L"needle"), L"haystack").failure_message()); } #endif // GTEST_HAS_STD_WSTRING // Tests for ::testing::IsNotSubstring(). // Tests that IsNotSubstring() returns the correct result when the input // argument type is const char*. TEST(IsNotSubstringTest, ReturnsCorrectResultForCString) { EXPECT_TRUE(IsNotSubstring("", "", "needle", "haystack")); EXPECT_FALSE(IsNotSubstring("", "", "needle", "two needles")); } // Tests that IsNotSubstring() returns the correct result when the input // argument type is const wchar_t*. TEST(IsNotSubstringTest, ReturnsCorrectResultForWideCString) { EXPECT_TRUE(IsNotSubstring("", "", L"needle", L"haystack")); EXPECT_FALSE(IsNotSubstring("", "", L"needle", L"two needles")); } // Tests that IsNotSubstring() generates the correct message when the input // argument type is const wchar_t*. TEST(IsNotSubstringTest, GeneratesCorrectMessageForWideCString) { EXPECT_STREQ("Value of: needle_expr\n" " Actual: L\"needle\"\n" "Expected: not a substring of haystack_expr\n" "Which is: L\"two needles\"", IsNotSubstring( "needle_expr", "haystack_expr", L"needle", L"two needles").failure_message()); } // Tests that IsNotSubstring returns the correct result when the input // argument type is ::std::string. TEST(IsNotSubstringTest, ReturnsCorrectResultsForStdString) { EXPECT_FALSE(IsNotSubstring("", "", std::string("hello"), "ahellob")); EXPECT_TRUE(IsNotSubstring("", "", "hello", std::string("world"))); } // Tests that IsNotSubstring() generates the correct message when the input // argument type is ::std::string. TEST(IsNotSubstringTest, GeneratesCorrectMessageForStdString) { EXPECT_STREQ("Value of: needle_expr\n" " Actual: \"needle\"\n" "Expected: not a substring of haystack_expr\n" "Which is: \"two needles\"", IsNotSubstring( "needle_expr", "haystack_expr", ::std::string("needle"), "two needles").failure_message()); } #if GTEST_HAS_STD_WSTRING // Tests that IsNotSubstring returns the correct result when the input // argument type is ::std::wstring. TEST(IsNotSubstringTest, ReturnsCorrectResultForStdWstring) { EXPECT_FALSE( IsNotSubstring("", "", ::std::wstring(L"needle"), L"two needles")); EXPECT_TRUE(IsNotSubstring("", "", L"needle", ::std::wstring(L"haystack"))); } #endif // GTEST_HAS_STD_WSTRING // Tests floating-point assertions. template class FloatingPointTest : public Test { protected: // Pre-calculated numbers to be used by the tests. struct TestValues { RawType close_to_positive_zero; RawType close_to_negative_zero; RawType further_from_negative_zero; RawType close_to_one; RawType further_from_one; RawType infinity; RawType close_to_infinity; RawType further_from_infinity; RawType nan1; RawType nan2; }; typedef typename testing::internal::FloatingPoint Floating; typedef typename Floating::Bits Bits; virtual void SetUp() { const size_t max_ulps = Floating::kMaxUlps; // The bits that represent 0.0. const Bits zero_bits = Floating(0).bits(); // Makes some numbers close to 0.0. values_.close_to_positive_zero = Floating::ReinterpretBits( zero_bits + max_ulps/2); values_.close_to_negative_zero = -Floating::ReinterpretBits( zero_bits + max_ulps - max_ulps/2); values_.further_from_negative_zero = -Floating::ReinterpretBits( zero_bits + max_ulps + 1 - max_ulps/2); // The bits that represent 1.0. const Bits one_bits = Floating(1).bits(); // Makes some numbers close to 1.0. values_.close_to_one = Floating::ReinterpretBits(one_bits + max_ulps); values_.further_from_one = Floating::ReinterpretBits( one_bits + max_ulps + 1); // +infinity. values_.infinity = Floating::Infinity(); // The bits that represent +infinity. const Bits infinity_bits = Floating(values_.infinity).bits(); // Makes some numbers close to infinity. values_.close_to_infinity = Floating::ReinterpretBits( infinity_bits - max_ulps); values_.further_from_infinity = Floating::ReinterpretBits( infinity_bits - max_ulps - 1); // Makes some NAN's. Sets the most significant bit of the fraction so that // our NaN's are quiet; trying to process a signaling NaN would raise an // exception if our environment enables floating point exceptions. values_.nan1 = Floating::ReinterpretBits(Floating::kExponentBitMask | (static_cast(1) << (Floating::kFractionBitCount - 1)) | 1); values_.nan2 = Floating::ReinterpretBits(Floating::kExponentBitMask | (static_cast(1) << (Floating::kFractionBitCount - 1)) | 200); } void TestSize() { EXPECT_EQ(sizeof(RawType), sizeof(Bits)); } static TestValues values_; }; template typename FloatingPointTest::TestValues FloatingPointTest::values_; // Instantiates FloatingPointTest for testing *_FLOAT_EQ. typedef FloatingPointTest FloatTest; // Tests that the size of Float::Bits matches the size of float. TEST_F(FloatTest, Size) { TestSize(); } // Tests comparing with +0 and -0. TEST_F(FloatTest, Zeros) { EXPECT_FLOAT_EQ(0.0, -0.0); EXPECT_NONFATAL_FAILURE(EXPECT_FLOAT_EQ(-0.0, 1.0), "1.0"); EXPECT_FATAL_FAILURE(ASSERT_FLOAT_EQ(0.0, 1.5), "1.5"); } // Tests comparing numbers close to 0. // // This ensures that *_FLOAT_EQ handles the sign correctly and no // overflow occurs when comparing numbers whose absolute value is very // small. TEST_F(FloatTest, AlmostZeros) { // In C++Builder, names within local classes (such as used by // EXPECT_FATAL_FAILURE) cannot be resolved against static members of the // scoping class. Use a static local alias as a workaround. // We use the assignment syntax since some compilers, like Sun Studio, // don't allow initializing references using construction syntax // (parentheses). static const FloatTest::TestValues& v = this->values_; EXPECT_FLOAT_EQ(0.0, v.close_to_positive_zero); EXPECT_FLOAT_EQ(-0.0, v.close_to_negative_zero); EXPECT_FLOAT_EQ(v.close_to_positive_zero, v.close_to_negative_zero); EXPECT_FATAL_FAILURE({ // NOLINT ASSERT_FLOAT_EQ(v.close_to_positive_zero, v.further_from_negative_zero); }, "v.further_from_negative_zero"); } // Tests comparing numbers close to each other. TEST_F(FloatTest, SmallDiff) { EXPECT_FLOAT_EQ(1.0, values_.close_to_one); EXPECT_NONFATAL_FAILURE(EXPECT_FLOAT_EQ(1.0, values_.further_from_one), "values_.further_from_one"); } // Tests comparing numbers far apart. TEST_F(FloatTest, LargeDiff) { EXPECT_NONFATAL_FAILURE(EXPECT_FLOAT_EQ(2.5, 3.0), "3.0"); } // Tests comparing with infinity. // // This ensures that no overflow occurs when comparing numbers whose // absolute value is very large. TEST_F(FloatTest, Infinity) { EXPECT_FLOAT_EQ(values_.infinity, values_.close_to_infinity); EXPECT_FLOAT_EQ(-values_.infinity, -values_.close_to_infinity); #if !GTEST_OS_SYMBIAN // Nokia's STLport crashes if we try to output infinity or NaN. EXPECT_NONFATAL_FAILURE(EXPECT_FLOAT_EQ(values_.infinity, -values_.infinity), "-values_.infinity"); // This is interesting as the representations of infinity and nan1 // are only 1 DLP apart. EXPECT_NONFATAL_FAILURE(EXPECT_FLOAT_EQ(values_.infinity, values_.nan1), "values_.nan1"); #endif // !GTEST_OS_SYMBIAN } // Tests that comparing with NAN always returns false. TEST_F(FloatTest, NaN) { #if !GTEST_OS_SYMBIAN // Nokia's STLport crashes if we try to output infinity or NaN. // In C++Builder, names within local classes (such as used by // EXPECT_FATAL_FAILURE) cannot be resolved against static members of the // scoping class. Use a static local alias as a workaround. // We use the assignment syntax since some compilers, like Sun Studio, // don't allow initializing references using construction syntax // (parentheses). static const FloatTest::TestValues& v = this->values_; EXPECT_NONFATAL_FAILURE(EXPECT_FLOAT_EQ(v.nan1, v.nan1), "v.nan1"); EXPECT_NONFATAL_FAILURE(EXPECT_FLOAT_EQ(v.nan1, v.nan2), "v.nan2"); EXPECT_NONFATAL_FAILURE(EXPECT_FLOAT_EQ(1.0, v.nan1), "v.nan1"); EXPECT_FATAL_FAILURE(ASSERT_FLOAT_EQ(v.nan1, v.infinity), "v.infinity"); #endif // !GTEST_OS_SYMBIAN } // Tests that *_FLOAT_EQ are reflexive. TEST_F(FloatTest, Reflexive) { EXPECT_FLOAT_EQ(0.0, 0.0); EXPECT_FLOAT_EQ(1.0, 1.0); ASSERT_FLOAT_EQ(values_.infinity, values_.infinity); } // Tests that *_FLOAT_EQ are commutative. TEST_F(FloatTest, Commutative) { // We already tested EXPECT_FLOAT_EQ(1.0, values_.close_to_one). EXPECT_FLOAT_EQ(values_.close_to_one, 1.0); // We already tested EXPECT_FLOAT_EQ(1.0, values_.further_from_one). EXPECT_NONFATAL_FAILURE(EXPECT_FLOAT_EQ(values_.further_from_one, 1.0), "1.0"); } // Tests EXPECT_NEAR. TEST_F(FloatTest, EXPECT_NEAR) { EXPECT_NEAR(-1.0f, -1.1f, 0.2f); EXPECT_NEAR(2.0f, 3.0f, 1.0f); EXPECT_NONFATAL_FAILURE(EXPECT_NEAR(1.0f,1.5f, 0.25f), // NOLINT "The difference between 1.0f and 1.5f is 0.5, " "which exceeds 0.25f"); // To work around a bug in gcc 2.95.0, there is intentionally no // space after the first comma in the previous line. } // Tests ASSERT_NEAR. TEST_F(FloatTest, ASSERT_NEAR) { ASSERT_NEAR(-1.0f, -1.1f, 0.2f); ASSERT_NEAR(2.0f, 3.0f, 1.0f); EXPECT_FATAL_FAILURE(ASSERT_NEAR(1.0f,1.5f, 0.25f), // NOLINT "The difference between 1.0f and 1.5f is 0.5, " "which exceeds 0.25f"); // To work around a bug in gcc 2.95.0, there is intentionally no // space after the first comma in the previous line. } // Tests the cases where FloatLE() should succeed. TEST_F(FloatTest, FloatLESucceeds) { EXPECT_PRED_FORMAT2(FloatLE, 1.0f, 2.0f); // When val1 < val2, ASSERT_PRED_FORMAT2(FloatLE, 1.0f, 1.0f); // val1 == val2, // or when val1 is greater than, but almost equals to, val2. EXPECT_PRED_FORMAT2(FloatLE, values_.close_to_positive_zero, 0.0f); } // Tests the cases where FloatLE() should fail. TEST_F(FloatTest, FloatLEFails) { // When val1 is greater than val2 by a large margin, EXPECT_NONFATAL_FAILURE(EXPECT_PRED_FORMAT2(FloatLE, 2.0f, 1.0f), "(2.0f) <= (1.0f)"); // or by a small yet non-negligible margin, EXPECT_NONFATAL_FAILURE({ // NOLINT EXPECT_PRED_FORMAT2(FloatLE, values_.further_from_one, 1.0f); }, "(values_.further_from_one) <= (1.0f)"); #if !GTEST_OS_SYMBIAN && !defined(__BORLANDC__) // Nokia's STLport crashes if we try to output infinity or NaN. // C++Builder gives bad results for ordered comparisons involving NaNs // due to compiler bugs. EXPECT_NONFATAL_FAILURE({ // NOLINT EXPECT_PRED_FORMAT2(FloatLE, values_.nan1, values_.infinity); }, "(values_.nan1) <= (values_.infinity)"); EXPECT_NONFATAL_FAILURE({ // NOLINT EXPECT_PRED_FORMAT2(FloatLE, -values_.infinity, values_.nan1); }, "(-values_.infinity) <= (values_.nan1)"); EXPECT_FATAL_FAILURE({ // NOLINT ASSERT_PRED_FORMAT2(FloatLE, values_.nan1, values_.nan1); }, "(values_.nan1) <= (values_.nan1)"); #endif // !GTEST_OS_SYMBIAN && !defined(__BORLANDC__) } // Instantiates FloatingPointTest for testing *_DOUBLE_EQ. typedef FloatingPointTest DoubleTest; // Tests that the size of Double::Bits matches the size of double. TEST_F(DoubleTest, Size) { TestSize(); } // Tests comparing with +0 and -0. TEST_F(DoubleTest, Zeros) { EXPECT_DOUBLE_EQ(0.0, -0.0); EXPECT_NONFATAL_FAILURE(EXPECT_DOUBLE_EQ(-0.0, 1.0), "1.0"); EXPECT_FATAL_FAILURE(ASSERT_DOUBLE_EQ(0.0, 1.0), "1.0"); } // Tests comparing numbers close to 0. // // This ensures that *_DOUBLE_EQ handles the sign correctly and no // overflow occurs when comparing numbers whose absolute value is very // small. TEST_F(DoubleTest, AlmostZeros) { // In C++Builder, names within local classes (such as used by // EXPECT_FATAL_FAILURE) cannot be resolved against static members of the // scoping class. Use a static local alias as a workaround. // We use the assignment syntax since some compilers, like Sun Studio, // don't allow initializing references using construction syntax // (parentheses). static const DoubleTest::TestValues& v = this->values_; EXPECT_DOUBLE_EQ(0.0, v.close_to_positive_zero); EXPECT_DOUBLE_EQ(-0.0, v.close_to_negative_zero); EXPECT_DOUBLE_EQ(v.close_to_positive_zero, v.close_to_negative_zero); EXPECT_FATAL_FAILURE({ // NOLINT ASSERT_DOUBLE_EQ(v.close_to_positive_zero, v.further_from_negative_zero); }, "v.further_from_negative_zero"); } // Tests comparing numbers close to each other. TEST_F(DoubleTest, SmallDiff) { EXPECT_DOUBLE_EQ(1.0, values_.close_to_one); EXPECT_NONFATAL_FAILURE(EXPECT_DOUBLE_EQ(1.0, values_.further_from_one), "values_.further_from_one"); } // Tests comparing numbers far apart. TEST_F(DoubleTest, LargeDiff) { EXPECT_NONFATAL_FAILURE(EXPECT_DOUBLE_EQ(2.0, 3.0), "3.0"); } // Tests comparing with infinity. // // This ensures that no overflow occurs when comparing numbers whose // absolute value is very large. TEST_F(DoubleTest, Infinity) { EXPECT_DOUBLE_EQ(values_.infinity, values_.close_to_infinity); EXPECT_DOUBLE_EQ(-values_.infinity, -values_.close_to_infinity); #if !GTEST_OS_SYMBIAN // Nokia's STLport crashes if we try to output infinity or NaN. EXPECT_NONFATAL_FAILURE(EXPECT_DOUBLE_EQ(values_.infinity, -values_.infinity), "-values_.infinity"); // This is interesting as the representations of infinity_ and nan1_ // are only 1 DLP apart. EXPECT_NONFATAL_FAILURE(EXPECT_DOUBLE_EQ(values_.infinity, values_.nan1), "values_.nan1"); #endif // !GTEST_OS_SYMBIAN } // Tests that comparing with NAN always returns false. TEST_F(DoubleTest, NaN) { #if !GTEST_OS_SYMBIAN // In C++Builder, names within local classes (such as used by // EXPECT_FATAL_FAILURE) cannot be resolved against static members of the // scoping class. Use a static local alias as a workaround. // We use the assignment syntax since some compilers, like Sun Studio, // don't allow initializing references using construction syntax // (parentheses). static const DoubleTest::TestValues& v = this->values_; // Nokia's STLport crashes if we try to output infinity or NaN. EXPECT_NONFATAL_FAILURE(EXPECT_DOUBLE_EQ(v.nan1, v.nan1), "v.nan1"); EXPECT_NONFATAL_FAILURE(EXPECT_DOUBLE_EQ(v.nan1, v.nan2), "v.nan2"); EXPECT_NONFATAL_FAILURE(EXPECT_DOUBLE_EQ(1.0, v.nan1), "v.nan1"); EXPECT_FATAL_FAILURE(ASSERT_DOUBLE_EQ(v.nan1, v.infinity), "v.infinity"); #endif // !GTEST_OS_SYMBIAN } // Tests that *_DOUBLE_EQ are reflexive. TEST_F(DoubleTest, Reflexive) { EXPECT_DOUBLE_EQ(0.0, 0.0); EXPECT_DOUBLE_EQ(1.0, 1.0); #if !GTEST_OS_SYMBIAN // Nokia's STLport crashes if we try to output infinity or NaN. ASSERT_DOUBLE_EQ(values_.infinity, values_.infinity); #endif // !GTEST_OS_SYMBIAN } // Tests that *_DOUBLE_EQ are commutative. TEST_F(DoubleTest, Commutative) { // We already tested EXPECT_DOUBLE_EQ(1.0, values_.close_to_one). EXPECT_DOUBLE_EQ(values_.close_to_one, 1.0); // We already tested EXPECT_DOUBLE_EQ(1.0, values_.further_from_one). EXPECT_NONFATAL_FAILURE(EXPECT_DOUBLE_EQ(values_.further_from_one, 1.0), "1.0"); } // Tests EXPECT_NEAR. TEST_F(DoubleTest, EXPECT_NEAR) { EXPECT_NEAR(-1.0, -1.1, 0.2); EXPECT_NEAR(2.0, 3.0, 1.0); EXPECT_NONFATAL_FAILURE(EXPECT_NEAR(1.0, 1.5, 0.25), // NOLINT "The difference between 1.0 and 1.5 is 0.5, " "which exceeds 0.25"); // To work around a bug in gcc 2.95.0, there is intentionally no // space after the first comma in the previous statement. } // Tests ASSERT_NEAR. TEST_F(DoubleTest, ASSERT_NEAR) { ASSERT_NEAR(-1.0, -1.1, 0.2); ASSERT_NEAR(2.0, 3.0, 1.0); EXPECT_FATAL_FAILURE(ASSERT_NEAR(1.0, 1.5, 0.25), // NOLINT "The difference between 1.0 and 1.5 is 0.5, " "which exceeds 0.25"); // To work around a bug in gcc 2.95.0, there is intentionally no // space after the first comma in the previous statement. } // Tests the cases where DoubleLE() should succeed. TEST_F(DoubleTest, DoubleLESucceeds) { EXPECT_PRED_FORMAT2(DoubleLE, 1.0, 2.0); // When val1 < val2, ASSERT_PRED_FORMAT2(DoubleLE, 1.0, 1.0); // val1 == val2, // or when val1 is greater than, but almost equals to, val2. EXPECT_PRED_FORMAT2(DoubleLE, values_.close_to_positive_zero, 0.0); } // Tests the cases where DoubleLE() should fail. TEST_F(DoubleTest, DoubleLEFails) { // When val1 is greater than val2 by a large margin, EXPECT_NONFATAL_FAILURE(EXPECT_PRED_FORMAT2(DoubleLE, 2.0, 1.0), "(2.0) <= (1.0)"); // or by a small yet non-negligible margin, EXPECT_NONFATAL_FAILURE({ // NOLINT EXPECT_PRED_FORMAT2(DoubleLE, values_.further_from_one, 1.0); }, "(values_.further_from_one) <= (1.0)"); #if !GTEST_OS_SYMBIAN && !defined(__BORLANDC__) // Nokia's STLport crashes if we try to output infinity or NaN. // C++Builder gives bad results for ordered comparisons involving NaNs // due to compiler bugs. EXPECT_NONFATAL_FAILURE({ // NOLINT EXPECT_PRED_FORMAT2(DoubleLE, values_.nan1, values_.infinity); }, "(values_.nan1) <= (values_.infinity)"); EXPECT_NONFATAL_FAILURE({ // NOLINT EXPECT_PRED_FORMAT2(DoubleLE, -values_.infinity, values_.nan1); }, " (-values_.infinity) <= (values_.nan1)"); EXPECT_FATAL_FAILURE({ // NOLINT ASSERT_PRED_FORMAT2(DoubleLE, values_.nan1, values_.nan1); }, "(values_.nan1) <= (values_.nan1)"); #endif // !GTEST_OS_SYMBIAN && !defined(__BORLANDC__) } // Verifies that a test or test case whose name starts with DISABLED_ is // not run. // A test whose name starts with DISABLED_. // Should not run. TEST(DisabledTest, DISABLED_TestShouldNotRun) { FAIL() << "Unexpected failure: Disabled test should not be run."; } // A test whose name does not start with DISABLED_. // Should run. TEST(DisabledTest, NotDISABLED_TestShouldRun) { EXPECT_EQ(1, 1); } // A test case whose name starts with DISABLED_. // Should not run. TEST(DISABLED_TestCase, TestShouldNotRun) { FAIL() << "Unexpected failure: Test in disabled test case should not be run."; } // A test case and test whose names start with DISABLED_. // Should not run. TEST(DISABLED_TestCase, DISABLED_TestShouldNotRun) { FAIL() << "Unexpected failure: Test in disabled test case should not be run."; } // Check that when all tests in a test case are disabled, SetupTestCase() and // TearDownTestCase() are not called. class DisabledTestsTest : public Test { protected: static void SetUpTestCase() { FAIL() << "Unexpected failure: All tests disabled in test case. " "SetupTestCase() should not be called."; } static void TearDownTestCase() { FAIL() << "Unexpected failure: All tests disabled in test case. " "TearDownTestCase() should not be called."; } }; TEST_F(DisabledTestsTest, DISABLED_TestShouldNotRun_1) { FAIL() << "Unexpected failure: Disabled test should not be run."; } TEST_F(DisabledTestsTest, DISABLED_TestShouldNotRun_2) { FAIL() << "Unexpected failure: Disabled test should not be run."; } // Tests that disabled typed tests aren't run. #if GTEST_HAS_TYPED_TEST template class TypedTest : public Test { }; typedef testing::Types NumericTypes; TYPED_TEST_CASE(TypedTest, NumericTypes); TYPED_TEST(TypedTest, DISABLED_ShouldNotRun) { FAIL() << "Unexpected failure: Disabled typed test should not run."; } template class DISABLED_TypedTest : public Test { }; TYPED_TEST_CASE(DISABLED_TypedTest, NumericTypes); TYPED_TEST(DISABLED_TypedTest, ShouldNotRun) { FAIL() << "Unexpected failure: Disabled typed test should not run."; } #endif // GTEST_HAS_TYPED_TEST // Tests that disabled type-parameterized tests aren't run. #if GTEST_HAS_TYPED_TEST_P template class TypedTestP : public Test { }; TYPED_TEST_CASE_P(TypedTestP); TYPED_TEST_P(TypedTestP, DISABLED_ShouldNotRun) { FAIL() << "Unexpected failure: " << "Disabled type-parameterized test should not run."; } REGISTER_TYPED_TEST_CASE_P(TypedTestP, DISABLED_ShouldNotRun); INSTANTIATE_TYPED_TEST_CASE_P(My, TypedTestP, NumericTypes); template class DISABLED_TypedTestP : public Test { }; TYPED_TEST_CASE_P(DISABLED_TypedTestP); TYPED_TEST_P(DISABLED_TypedTestP, ShouldNotRun) { FAIL() << "Unexpected failure: " << "Disabled type-parameterized test should not run."; } REGISTER_TYPED_TEST_CASE_P(DISABLED_TypedTestP, ShouldNotRun); INSTANTIATE_TYPED_TEST_CASE_P(My, DISABLED_TypedTestP, NumericTypes); #endif // GTEST_HAS_TYPED_TEST_P // Tests that assertion macros evaluate their arguments exactly once. class SingleEvaluationTest : public Test { public: // Must be public and not protected due to a bug in g++ 3.4.2. // This helper function is needed by the FailedASSERT_STREQ test // below. It's public to work around C++Builder's bug with scoping local // classes. static void CompareAndIncrementCharPtrs() { ASSERT_STREQ(p1_++, p2_++); } // This helper function is needed by the FailedASSERT_NE test below. It's // public to work around C++Builder's bug with scoping local classes. static void CompareAndIncrementInts() { ASSERT_NE(a_++, b_++); } protected: SingleEvaluationTest() { p1_ = s1_; p2_ = s2_; a_ = 0; b_ = 0; } static const char* const s1_; static const char* const s2_; static const char* p1_; static const char* p2_; static int a_; static int b_; }; const char* const SingleEvaluationTest::s1_ = "01234"; const char* const SingleEvaluationTest::s2_ = "abcde"; const char* SingleEvaluationTest::p1_; const char* SingleEvaluationTest::p2_; int SingleEvaluationTest::a_; int SingleEvaluationTest::b_; // Tests that when ASSERT_STREQ fails, it evaluates its arguments // exactly once. TEST_F(SingleEvaluationTest, FailedASSERT_STREQ) { EXPECT_FATAL_FAILURE(SingleEvaluationTest::CompareAndIncrementCharPtrs(), "p2_++"); EXPECT_EQ(s1_ + 1, p1_); EXPECT_EQ(s2_ + 1, p2_); } // Tests that string assertion arguments are evaluated exactly once. TEST_F(SingleEvaluationTest, ASSERT_STR) { // successful EXPECT_STRNE EXPECT_STRNE(p1_++, p2_++); EXPECT_EQ(s1_ + 1, p1_); EXPECT_EQ(s2_ + 1, p2_); // failed EXPECT_STRCASEEQ EXPECT_NONFATAL_FAILURE(EXPECT_STRCASEEQ(p1_++, p2_++), "ignoring case"); EXPECT_EQ(s1_ + 2, p1_); EXPECT_EQ(s2_ + 2, p2_); } // Tests that when ASSERT_NE fails, it evaluates its arguments exactly // once. TEST_F(SingleEvaluationTest, FailedASSERT_NE) { EXPECT_FATAL_FAILURE(SingleEvaluationTest::CompareAndIncrementInts(), "(a_++) != (b_++)"); EXPECT_EQ(1, a_); EXPECT_EQ(1, b_); } // Tests that assertion arguments are evaluated exactly once. TEST_F(SingleEvaluationTest, OtherCases) { // successful EXPECT_TRUE EXPECT_TRUE(0 == a_++); // NOLINT EXPECT_EQ(1, a_); // failed EXPECT_TRUE EXPECT_NONFATAL_FAILURE(EXPECT_TRUE(-1 == a_++), "-1 == a_++"); EXPECT_EQ(2, a_); // successful EXPECT_GT EXPECT_GT(a_++, b_++); EXPECT_EQ(3, a_); EXPECT_EQ(1, b_); // failed EXPECT_LT EXPECT_NONFATAL_FAILURE(EXPECT_LT(a_++, b_++), "(a_++) < (b_++)"); EXPECT_EQ(4, a_); EXPECT_EQ(2, b_); // successful ASSERT_TRUE ASSERT_TRUE(0 < a_++); // NOLINT EXPECT_EQ(5, a_); // successful ASSERT_GT ASSERT_GT(a_++, b_++); EXPECT_EQ(6, a_); EXPECT_EQ(3, b_); } #if GTEST_HAS_EXCEPTIONS void ThrowAnInteger() { throw 1; } // Tests that assertion arguments are evaluated exactly once. TEST_F(SingleEvaluationTest, ExceptionTests) { // successful EXPECT_THROW EXPECT_THROW({ // NOLINT a_++; ThrowAnInteger(); }, int); EXPECT_EQ(1, a_); // failed EXPECT_THROW, throws different EXPECT_NONFATAL_FAILURE(EXPECT_THROW({ // NOLINT a_++; ThrowAnInteger(); }, bool), "throws a different type"); EXPECT_EQ(2, a_); // failed EXPECT_THROW, throws nothing EXPECT_NONFATAL_FAILURE(EXPECT_THROW(a_++, bool), "throws nothing"); EXPECT_EQ(3, a_); // successful EXPECT_NO_THROW EXPECT_NO_THROW(a_++); EXPECT_EQ(4, a_); // failed EXPECT_NO_THROW EXPECT_NONFATAL_FAILURE(EXPECT_NO_THROW({ // NOLINT a_++; ThrowAnInteger(); }), "it throws"); EXPECT_EQ(5, a_); // successful EXPECT_ANY_THROW EXPECT_ANY_THROW({ // NOLINT a_++; ThrowAnInteger(); }); EXPECT_EQ(6, a_); // failed EXPECT_ANY_THROW EXPECT_NONFATAL_FAILURE(EXPECT_ANY_THROW(a_++), "it doesn't"); EXPECT_EQ(7, a_); } #endif // GTEST_HAS_EXCEPTIONS // Tests {ASSERT|EXPECT}_NO_FATAL_FAILURE. class NoFatalFailureTest : public Test { protected: void Succeeds() {} void FailsNonFatal() { ADD_FAILURE() << "some non-fatal failure"; } void Fails() { FAIL() << "some fatal failure"; } void DoAssertNoFatalFailureOnFails() { ASSERT_NO_FATAL_FAILURE(Fails()); ADD_FAILURE() << "shold not reach here."; } void DoExpectNoFatalFailureOnFails() { EXPECT_NO_FATAL_FAILURE(Fails()); ADD_FAILURE() << "other failure"; } }; TEST_F(NoFatalFailureTest, NoFailure) { EXPECT_NO_FATAL_FAILURE(Succeeds()); ASSERT_NO_FATAL_FAILURE(Succeeds()); } TEST_F(NoFatalFailureTest, NonFatalIsNoFailure) { EXPECT_NONFATAL_FAILURE( EXPECT_NO_FATAL_FAILURE(FailsNonFatal()), "some non-fatal failure"); EXPECT_NONFATAL_FAILURE( ASSERT_NO_FATAL_FAILURE(FailsNonFatal()), "some non-fatal failure"); } TEST_F(NoFatalFailureTest, AssertNoFatalFailureOnFatalFailure) { TestPartResultArray gtest_failures; { ScopedFakeTestPartResultReporter gtest_reporter(>est_failures); DoAssertNoFatalFailureOnFails(); } ASSERT_EQ(2, gtest_failures.size()); EXPECT_EQ(TestPartResult::kFatalFailure, gtest_failures.GetTestPartResult(0).type()); EXPECT_EQ(TestPartResult::kFatalFailure, gtest_failures.GetTestPartResult(1).type()); EXPECT_PRED_FORMAT2(testing::IsSubstring, "some fatal failure", gtest_failures.GetTestPartResult(0).message()); EXPECT_PRED_FORMAT2(testing::IsSubstring, "it does", gtest_failures.GetTestPartResult(1).message()); } TEST_F(NoFatalFailureTest, ExpectNoFatalFailureOnFatalFailure) { TestPartResultArray gtest_failures; { ScopedFakeTestPartResultReporter gtest_reporter(>est_failures); DoExpectNoFatalFailureOnFails(); } ASSERT_EQ(3, gtest_failures.size()); EXPECT_EQ(TestPartResult::kFatalFailure, gtest_failures.GetTestPartResult(0).type()); EXPECT_EQ(TestPartResult::kNonFatalFailure, gtest_failures.GetTestPartResult(1).type()); EXPECT_EQ(TestPartResult::kNonFatalFailure, gtest_failures.GetTestPartResult(2).type()); EXPECT_PRED_FORMAT2(testing::IsSubstring, "some fatal failure", gtest_failures.GetTestPartResult(0).message()); EXPECT_PRED_FORMAT2(testing::IsSubstring, "it does", gtest_failures.GetTestPartResult(1).message()); EXPECT_PRED_FORMAT2(testing::IsSubstring, "other failure", gtest_failures.GetTestPartResult(2).message()); } TEST_F(NoFatalFailureTest, MessageIsStreamable) { TestPartResultArray gtest_failures; { ScopedFakeTestPartResultReporter gtest_reporter(>est_failures); EXPECT_NO_FATAL_FAILURE(FAIL() << "foo") << "my message"; } ASSERT_EQ(2, gtest_failures.size()); EXPECT_EQ(TestPartResult::kNonFatalFailure, gtest_failures.GetTestPartResult(0).type()); EXPECT_EQ(TestPartResult::kNonFatalFailure, gtest_failures.GetTestPartResult(1).type()); EXPECT_PRED_FORMAT2(testing::IsSubstring, "foo", gtest_failures.GetTestPartResult(0).message()); EXPECT_PRED_FORMAT2(testing::IsSubstring, "my message", gtest_failures.GetTestPartResult(1).message()); } // Tests non-string assertions. // Tests EqFailure(), used for implementing *EQ* assertions. TEST(AssertionTest, EqFailure) { const std::string foo_val("5"), bar_val("6"); const std::string msg1( EqFailure("foo", "bar", foo_val, bar_val, false) .failure_message()); EXPECT_STREQ( "Value of: bar\n" " Actual: 6\n" "Expected: foo\n" "Which is: 5", msg1.c_str()); const std::string msg2( EqFailure("foo", "6", foo_val, bar_val, false) .failure_message()); EXPECT_STREQ( "Value of: 6\n" "Expected: foo\n" "Which is: 5", msg2.c_str()); const std::string msg3( EqFailure("5", "bar", foo_val, bar_val, false) .failure_message()); EXPECT_STREQ( "Value of: bar\n" " Actual: 6\n" "Expected: 5", msg3.c_str()); const std::string msg4( EqFailure("5", "6", foo_val, bar_val, false).failure_message()); EXPECT_STREQ( "Value of: 6\n" "Expected: 5", msg4.c_str()); const std::string msg5( EqFailure("foo", "bar", std::string("\"x\""), std::string("\"y\""), true).failure_message()); EXPECT_STREQ( "Value of: bar\n" " Actual: \"y\"\n" "Expected: foo (ignoring case)\n" "Which is: \"x\"", msg5.c_str()); } // Tests AppendUserMessage(), used for implementing the *EQ* macros. TEST(AssertionTest, AppendUserMessage) { const std::string foo("foo"); Message msg; EXPECT_STREQ("foo", AppendUserMessage(foo, msg).c_str()); msg << "bar"; EXPECT_STREQ("foo\nbar", AppendUserMessage(foo, msg).c_str()); } #ifdef __BORLANDC__ // Silences warnings: "Condition is always true", "Unreachable code" # pragma option push -w-ccc -w-rch #endif // Tests ASSERT_TRUE. TEST(AssertionTest, ASSERT_TRUE) { ASSERT_TRUE(2 > 1); // NOLINT EXPECT_FATAL_FAILURE(ASSERT_TRUE(2 < 1), "2 < 1"); } // Tests ASSERT_TRUE(predicate) for predicates returning AssertionResult. TEST(AssertionTest, AssertTrueWithAssertionResult) { ASSERT_TRUE(ResultIsEven(2)); #ifndef __BORLANDC__ // ICE's in C++Builder. EXPECT_FATAL_FAILURE(ASSERT_TRUE(ResultIsEven(3)), "Value of: ResultIsEven(3)\n" " Actual: false (3 is odd)\n" "Expected: true"); #endif ASSERT_TRUE(ResultIsEvenNoExplanation(2)); EXPECT_FATAL_FAILURE(ASSERT_TRUE(ResultIsEvenNoExplanation(3)), "Value of: ResultIsEvenNoExplanation(3)\n" " Actual: false (3 is odd)\n" "Expected: true"); } // Tests ASSERT_FALSE. TEST(AssertionTest, ASSERT_FALSE) { ASSERT_FALSE(2 < 1); // NOLINT EXPECT_FATAL_FAILURE(ASSERT_FALSE(2 > 1), "Value of: 2 > 1\n" " Actual: true\n" "Expected: false"); } // Tests ASSERT_FALSE(predicate) for predicates returning AssertionResult. TEST(AssertionTest, AssertFalseWithAssertionResult) { ASSERT_FALSE(ResultIsEven(3)); #ifndef __BORLANDC__ // ICE's in C++Builder. EXPECT_FATAL_FAILURE(ASSERT_FALSE(ResultIsEven(2)), "Value of: ResultIsEven(2)\n" " Actual: true (2 is even)\n" "Expected: false"); #endif ASSERT_FALSE(ResultIsEvenNoExplanation(3)); EXPECT_FATAL_FAILURE(ASSERT_FALSE(ResultIsEvenNoExplanation(2)), "Value of: ResultIsEvenNoExplanation(2)\n" " Actual: true\n" "Expected: false"); } #ifdef __BORLANDC__ // Restores warnings after previous "#pragma option push" supressed them # pragma option pop #endif // Tests using ASSERT_EQ on double values. The purpose is to make // sure that the specialization we did for integer and anonymous enums // isn't used for double arguments. TEST(ExpectTest, ASSERT_EQ_Double) { // A success. ASSERT_EQ(5.6, 5.6); // A failure. EXPECT_FATAL_FAILURE(ASSERT_EQ(5.1, 5.2), "5.1"); } // Tests ASSERT_EQ. TEST(AssertionTest, ASSERT_EQ) { ASSERT_EQ(5, 2 + 3); EXPECT_FATAL_FAILURE(ASSERT_EQ(5, 2*3), "Value of: 2*3\n" " Actual: 6\n" "Expected: 5"); } // Tests ASSERT_EQ(NULL, pointer). #if GTEST_CAN_COMPARE_NULL TEST(AssertionTest, ASSERT_EQ_NULL) { // A success. const char* p = NULL; // Some older GCC versions may issue a spurious waring in this or the next // assertion statement. This warning should not be suppressed with // static_cast since the test verifies the ability to use bare NULL as the // expected parameter to the macro. ASSERT_EQ(NULL, p); // A failure. static int n = 0; EXPECT_FATAL_FAILURE(ASSERT_EQ(NULL, &n), "Value of: &n\n"); } #endif // GTEST_CAN_COMPARE_NULL // Tests ASSERT_EQ(0, non_pointer). Since the literal 0 can be // treated as a null pointer by the compiler, we need to make sure // that ASSERT_EQ(0, non_pointer) isn't interpreted by Google Test as // ASSERT_EQ(static_cast(NULL), non_pointer). TEST(ExpectTest, ASSERT_EQ_0) { int n = 0; // A success. ASSERT_EQ(0, n); // A failure. EXPECT_FATAL_FAILURE(ASSERT_EQ(0, 5.6), "Expected: 0"); } // Tests ASSERT_NE. TEST(AssertionTest, ASSERT_NE) { ASSERT_NE(6, 7); EXPECT_FATAL_FAILURE(ASSERT_NE('a', 'a'), "Expected: ('a') != ('a'), " "actual: 'a' (97, 0x61) vs 'a' (97, 0x61)"); } // Tests ASSERT_LE. TEST(AssertionTest, ASSERT_LE) { ASSERT_LE(2, 3); ASSERT_LE(2, 2); EXPECT_FATAL_FAILURE(ASSERT_LE(2, 0), "Expected: (2) <= (0), actual: 2 vs 0"); } // Tests ASSERT_LT. TEST(AssertionTest, ASSERT_LT) { ASSERT_LT(2, 3); EXPECT_FATAL_FAILURE(ASSERT_LT(2, 2), "Expected: (2) < (2), actual: 2 vs 2"); } // Tests ASSERT_GE. TEST(AssertionTest, ASSERT_GE) { ASSERT_GE(2, 1); ASSERT_GE(2, 2); EXPECT_FATAL_FAILURE(ASSERT_GE(2, 3), "Expected: (2) >= (3), actual: 2 vs 3"); } // Tests ASSERT_GT. TEST(AssertionTest, ASSERT_GT) { ASSERT_GT(2, 1); EXPECT_FATAL_FAILURE(ASSERT_GT(2, 2), "Expected: (2) > (2), actual: 2 vs 2"); } #if GTEST_HAS_EXCEPTIONS void ThrowNothing() {} // Tests ASSERT_THROW. TEST(AssertionTest, ASSERT_THROW) { ASSERT_THROW(ThrowAnInteger(), int); # ifndef __BORLANDC__ // ICE's in C++Builder 2007 and 2009. EXPECT_FATAL_FAILURE( ASSERT_THROW(ThrowAnInteger(), bool), "Expected: ThrowAnInteger() throws an exception of type bool.\n" " Actual: it throws a different type."); # endif EXPECT_FATAL_FAILURE( ASSERT_THROW(ThrowNothing(), bool), "Expected: ThrowNothing() throws an exception of type bool.\n" " Actual: it throws nothing."); } // Tests ASSERT_NO_THROW. TEST(AssertionTest, ASSERT_NO_THROW) { ASSERT_NO_THROW(ThrowNothing()); EXPECT_FATAL_FAILURE(ASSERT_NO_THROW(ThrowAnInteger()), "Expected: ThrowAnInteger() doesn't throw an exception." "\n Actual: it throws."); } // Tests ASSERT_ANY_THROW. TEST(AssertionTest, ASSERT_ANY_THROW) { ASSERT_ANY_THROW(ThrowAnInteger()); EXPECT_FATAL_FAILURE( ASSERT_ANY_THROW(ThrowNothing()), "Expected: ThrowNothing() throws an exception.\n" " Actual: it doesn't."); } #endif // GTEST_HAS_EXCEPTIONS // Makes sure we deal with the precedence of <<. This test should // compile. TEST(AssertionTest, AssertPrecedence) { ASSERT_EQ(1 < 2, true); bool false_value = false; ASSERT_EQ(true && false_value, false); } // A subroutine used by the following test. void TestEq1(int x) { ASSERT_EQ(1, x); } // Tests calling a test subroutine that's not part of a fixture. TEST(AssertionTest, NonFixtureSubroutine) { EXPECT_FATAL_FAILURE(TestEq1(2), "Value of: x"); } // An uncopyable class. class Uncopyable { public: explicit Uncopyable(int a_value) : value_(a_value) {} int value() const { return value_; } bool operator==(const Uncopyable& rhs) const { return value() == rhs.value(); } private: // This constructor deliberately has no implementation, as we don't // want this class to be copyable. Uncopyable(const Uncopyable&); // NOLINT int value_; }; ::std::ostream& operator<<(::std::ostream& os, const Uncopyable& value) { return os << value.value(); } bool IsPositiveUncopyable(const Uncopyable& x) { return x.value() > 0; } // A subroutine used by the following test. void TestAssertNonPositive() { Uncopyable y(-1); ASSERT_PRED1(IsPositiveUncopyable, y); } // A subroutine used by the following test. void TestAssertEqualsUncopyable() { Uncopyable x(5); Uncopyable y(-1); ASSERT_EQ(x, y); } // Tests that uncopyable objects can be used in assertions. TEST(AssertionTest, AssertWorksWithUncopyableObject) { Uncopyable x(5); ASSERT_PRED1(IsPositiveUncopyable, x); ASSERT_EQ(x, x); EXPECT_FATAL_FAILURE(TestAssertNonPositive(), "IsPositiveUncopyable(y) evaluates to false, where\ny evaluates to -1"); EXPECT_FATAL_FAILURE(TestAssertEqualsUncopyable(), "Value of: y\n Actual: -1\nExpected: x\nWhich is: 5"); } // Tests that uncopyable objects can be used in expects. TEST(AssertionTest, ExpectWorksWithUncopyableObject) { Uncopyable x(5); EXPECT_PRED1(IsPositiveUncopyable, x); Uncopyable y(-1); EXPECT_NONFATAL_FAILURE(EXPECT_PRED1(IsPositiveUncopyable, y), "IsPositiveUncopyable(y) evaluates to false, where\ny evaluates to -1"); EXPECT_EQ(x, x); EXPECT_NONFATAL_FAILURE(EXPECT_EQ(x, y), "Value of: y\n Actual: -1\nExpected: x\nWhich is: 5"); } enum NamedEnum { kE1 = 0, kE2 = 1 }; TEST(AssertionTest, NamedEnum) { EXPECT_EQ(kE1, kE1); EXPECT_LT(kE1, kE2); EXPECT_NONFATAL_FAILURE(EXPECT_EQ(kE1, kE2), "Which is: 0"); EXPECT_NONFATAL_FAILURE(EXPECT_EQ(kE1, kE2), "Actual: 1"); } // The version of gcc used in XCode 2.2 has a bug and doesn't allow // anonymous enums in assertions. Therefore the following test is not // done on Mac. // Sun Studio and HP aCC also reject this code. #if !GTEST_OS_MAC && !defined(__SUNPRO_CC) && !defined(__HP_aCC) // Tests using assertions with anonymous enums. enum { kCaseA = -1, # if GTEST_OS_LINUX // We want to test the case where the size of the anonymous enum is // larger than sizeof(int), to make sure our implementation of the // assertions doesn't truncate the enums. However, MSVC // (incorrectly) doesn't allow an enum value to exceed the range of // an int, so this has to be conditionally compiled. // // On Linux, kCaseB and kCaseA have the same value when truncated to // int size. We want to test whether this will confuse the // assertions. kCaseB = testing::internal::kMaxBiggestInt, # else kCaseB = INT_MAX, # endif // GTEST_OS_LINUX kCaseC = 42 }; TEST(AssertionTest, AnonymousEnum) { # if GTEST_OS_LINUX EXPECT_EQ(static_cast(kCaseA), static_cast(kCaseB)); # endif // GTEST_OS_LINUX EXPECT_EQ(kCaseA, kCaseA); EXPECT_NE(kCaseA, kCaseB); EXPECT_LT(kCaseA, kCaseB); EXPECT_LE(kCaseA, kCaseB); EXPECT_GT(kCaseB, kCaseA); EXPECT_GE(kCaseA, kCaseA); EXPECT_NONFATAL_FAILURE(EXPECT_GE(kCaseA, kCaseB), "(kCaseA) >= (kCaseB)"); EXPECT_NONFATAL_FAILURE(EXPECT_GE(kCaseA, kCaseC), "-1 vs 42"); ASSERT_EQ(kCaseA, kCaseA); ASSERT_NE(kCaseA, kCaseB); ASSERT_LT(kCaseA, kCaseB); ASSERT_LE(kCaseA, kCaseB); ASSERT_GT(kCaseB, kCaseA); ASSERT_GE(kCaseA, kCaseA); # ifndef __BORLANDC__ // ICE's in C++Builder. EXPECT_FATAL_FAILURE(ASSERT_EQ(kCaseA, kCaseB), "Value of: kCaseB"); EXPECT_FATAL_FAILURE(ASSERT_EQ(kCaseA, kCaseC), "Actual: 42"); # endif EXPECT_FATAL_FAILURE(ASSERT_EQ(kCaseA, kCaseC), "Which is: -1"); } #endif // !GTEST_OS_MAC && !defined(__SUNPRO_CC) #if GTEST_OS_WINDOWS static HRESULT UnexpectedHRESULTFailure() { return E_UNEXPECTED; } static HRESULT OkHRESULTSuccess() { return S_OK; } static HRESULT FalseHRESULTSuccess() { return S_FALSE; } // HRESULT assertion tests test both zero and non-zero // success codes as well as failure message for each. // // Windows CE doesn't support message texts. TEST(HRESULTAssertionTest, EXPECT_HRESULT_SUCCEEDED) { EXPECT_HRESULT_SUCCEEDED(S_OK); EXPECT_HRESULT_SUCCEEDED(S_FALSE); EXPECT_NONFATAL_FAILURE(EXPECT_HRESULT_SUCCEEDED(UnexpectedHRESULTFailure()), "Expected: (UnexpectedHRESULTFailure()) succeeds.\n" " Actual: 0x8000FFFF"); } TEST(HRESULTAssertionTest, ASSERT_HRESULT_SUCCEEDED) { ASSERT_HRESULT_SUCCEEDED(S_OK); ASSERT_HRESULT_SUCCEEDED(S_FALSE); EXPECT_FATAL_FAILURE(ASSERT_HRESULT_SUCCEEDED(UnexpectedHRESULTFailure()), "Expected: (UnexpectedHRESULTFailure()) succeeds.\n" " Actual: 0x8000FFFF"); } TEST(HRESULTAssertionTest, EXPECT_HRESULT_FAILED) { EXPECT_HRESULT_FAILED(E_UNEXPECTED); EXPECT_NONFATAL_FAILURE(EXPECT_HRESULT_FAILED(OkHRESULTSuccess()), "Expected: (OkHRESULTSuccess()) fails.\n" " Actual: 0x0"); EXPECT_NONFATAL_FAILURE(EXPECT_HRESULT_FAILED(FalseHRESULTSuccess()), "Expected: (FalseHRESULTSuccess()) fails.\n" " Actual: 0x1"); } TEST(HRESULTAssertionTest, ASSERT_HRESULT_FAILED) { ASSERT_HRESULT_FAILED(E_UNEXPECTED); # ifndef __BORLANDC__ // ICE's in C++Builder 2007 and 2009. EXPECT_FATAL_FAILURE(ASSERT_HRESULT_FAILED(OkHRESULTSuccess()), "Expected: (OkHRESULTSuccess()) fails.\n" " Actual: 0x0"); # endif EXPECT_FATAL_FAILURE(ASSERT_HRESULT_FAILED(FalseHRESULTSuccess()), "Expected: (FalseHRESULTSuccess()) fails.\n" " Actual: 0x1"); } // Tests that streaming to the HRESULT macros works. TEST(HRESULTAssertionTest, Streaming) { EXPECT_HRESULT_SUCCEEDED(S_OK) << "unexpected failure"; ASSERT_HRESULT_SUCCEEDED(S_OK) << "unexpected failure"; EXPECT_HRESULT_FAILED(E_UNEXPECTED) << "unexpected failure"; ASSERT_HRESULT_FAILED(E_UNEXPECTED) << "unexpected failure"; EXPECT_NONFATAL_FAILURE( EXPECT_HRESULT_SUCCEEDED(E_UNEXPECTED) << "expected failure", "expected failure"); # ifndef __BORLANDC__ // ICE's in C++Builder 2007 and 2009. EXPECT_FATAL_FAILURE( ASSERT_HRESULT_SUCCEEDED(E_UNEXPECTED) << "expected failure", "expected failure"); # endif EXPECT_NONFATAL_FAILURE( EXPECT_HRESULT_FAILED(S_OK) << "expected failure", "expected failure"); EXPECT_FATAL_FAILURE( ASSERT_HRESULT_FAILED(S_OK) << "expected failure", "expected failure"); } #endif // GTEST_OS_WINDOWS #ifdef __BORLANDC__ // Silences warnings: "Condition is always true", "Unreachable code" # pragma option push -w-ccc -w-rch #endif // Tests that the assertion macros behave like single statements. TEST(AssertionSyntaxTest, BasicAssertionsBehavesLikeSingleStatement) { if (AlwaysFalse()) ASSERT_TRUE(false) << "This should never be executed; " "It's a compilation test only."; if (AlwaysTrue()) EXPECT_FALSE(false); else ; // NOLINT if (AlwaysFalse()) ASSERT_LT(1, 3); if (AlwaysFalse()) ; // NOLINT else EXPECT_GT(3, 2) << ""; } #if GTEST_HAS_EXCEPTIONS // Tests that the compiler will not complain about unreachable code in the // EXPECT_THROW/EXPECT_ANY_THROW/EXPECT_NO_THROW macros. TEST(ExpectThrowTest, DoesNotGenerateUnreachableCodeWarning) { int n = 0; EXPECT_THROW(throw 1, int); EXPECT_NONFATAL_FAILURE(EXPECT_THROW(n++, int), ""); EXPECT_NONFATAL_FAILURE(EXPECT_THROW(throw 1, const char*), ""); EXPECT_NO_THROW(n++); EXPECT_NONFATAL_FAILURE(EXPECT_NO_THROW(throw 1), ""); EXPECT_ANY_THROW(throw 1); EXPECT_NONFATAL_FAILURE(EXPECT_ANY_THROW(n++), ""); } TEST(AssertionSyntaxTest, ExceptionAssertionsBehavesLikeSingleStatement) { if (AlwaysFalse()) EXPECT_THROW(ThrowNothing(), bool); if (AlwaysTrue()) EXPECT_THROW(ThrowAnInteger(), int); else ; // NOLINT if (AlwaysFalse()) EXPECT_NO_THROW(ThrowAnInteger()); if (AlwaysTrue()) EXPECT_NO_THROW(ThrowNothing()); else ; // NOLINT if (AlwaysFalse()) EXPECT_ANY_THROW(ThrowNothing()); if (AlwaysTrue()) EXPECT_ANY_THROW(ThrowAnInteger()); else ; // NOLINT } #endif // GTEST_HAS_EXCEPTIONS TEST(AssertionSyntaxTest, NoFatalFailureAssertionsBehavesLikeSingleStatement) { if (AlwaysFalse()) EXPECT_NO_FATAL_FAILURE(FAIL()) << "This should never be executed. " << "It's a compilation test only."; else ; // NOLINT if (AlwaysFalse()) ASSERT_NO_FATAL_FAILURE(FAIL()) << ""; else ; // NOLINT if (AlwaysTrue()) EXPECT_NO_FATAL_FAILURE(SUCCEED()); else ; // NOLINT if (AlwaysFalse()) ; // NOLINT else ASSERT_NO_FATAL_FAILURE(SUCCEED()); } // Tests that the assertion macros work well with switch statements. TEST(AssertionSyntaxTest, WorksWithSwitch) { switch (0) { case 1: break; default: ASSERT_TRUE(true); } switch (0) case 0: EXPECT_FALSE(false) << "EXPECT_FALSE failed in switch case"; // Binary assertions are implemented using a different code path // than the Boolean assertions. Hence we test them separately. switch (0) { case 1: default: ASSERT_EQ(1, 1) << "ASSERT_EQ failed in default switch handler"; } switch (0) case 0: EXPECT_NE(1, 2); } #if GTEST_HAS_EXCEPTIONS void ThrowAString() { throw "std::string"; } // Test that the exception assertion macros compile and work with const // type qualifier. TEST(AssertionSyntaxTest, WorksWithConst) { ASSERT_THROW(ThrowAString(), const char*); EXPECT_THROW(ThrowAString(), const char*); } #endif // GTEST_HAS_EXCEPTIONS } // namespace namespace testing { // Tests that Google Test tracks SUCCEED*. TEST(SuccessfulAssertionTest, SUCCEED) { SUCCEED(); SUCCEED() << "OK"; EXPECT_EQ(2, GetUnitTestImpl()->current_test_result()->total_part_count()); } // Tests that Google Test doesn't track successful EXPECT_*. TEST(SuccessfulAssertionTest, EXPECT) { EXPECT_TRUE(true); EXPECT_EQ(0, GetUnitTestImpl()->current_test_result()->total_part_count()); } // Tests that Google Test doesn't track successful EXPECT_STR*. TEST(SuccessfulAssertionTest, EXPECT_STR) { EXPECT_STREQ("", ""); EXPECT_EQ(0, GetUnitTestImpl()->current_test_result()->total_part_count()); } // Tests that Google Test doesn't track successful ASSERT_*. TEST(SuccessfulAssertionTest, ASSERT) { ASSERT_TRUE(true); EXPECT_EQ(0, GetUnitTestImpl()->current_test_result()->total_part_count()); } // Tests that Google Test doesn't track successful ASSERT_STR*. TEST(SuccessfulAssertionTest, ASSERT_STR) { ASSERT_STREQ("", ""); EXPECT_EQ(0, GetUnitTestImpl()->current_test_result()->total_part_count()); } } // namespace testing namespace { // Tests the message streaming variation of assertions. TEST(AssertionWithMessageTest, EXPECT) { EXPECT_EQ(1, 1) << "This should succeed."; EXPECT_NONFATAL_FAILURE(EXPECT_NE(1, 1) << "Expected failure #1.", "Expected failure #1"); EXPECT_LE(1, 2) << "This should succeed."; EXPECT_NONFATAL_FAILURE(EXPECT_LT(1, 0) << "Expected failure #2.", "Expected failure #2."); EXPECT_GE(1, 0) << "This should succeed."; EXPECT_NONFATAL_FAILURE(EXPECT_GT(1, 2) << "Expected failure #3.", "Expected failure #3."); EXPECT_STREQ("1", "1") << "This should succeed."; EXPECT_NONFATAL_FAILURE(EXPECT_STRNE("1", "1") << "Expected failure #4.", "Expected failure #4."); EXPECT_STRCASEEQ("a", "A") << "This should succeed."; EXPECT_NONFATAL_FAILURE(EXPECT_STRCASENE("a", "A") << "Expected failure #5.", "Expected failure #5."); EXPECT_FLOAT_EQ(1, 1) << "This should succeed."; EXPECT_NONFATAL_FAILURE(EXPECT_DOUBLE_EQ(1, 1.2) << "Expected failure #6.", "Expected failure #6."); EXPECT_NEAR(1, 1.1, 0.2) << "This should succeed."; } TEST(AssertionWithMessageTest, ASSERT) { ASSERT_EQ(1, 1) << "This should succeed."; ASSERT_NE(1, 2) << "This should succeed."; ASSERT_LE(1, 2) << "This should succeed."; ASSERT_LT(1, 2) << "This should succeed."; ASSERT_GE(1, 0) << "This should succeed."; EXPECT_FATAL_FAILURE(ASSERT_GT(1, 2) << "Expected failure.", "Expected failure."); } TEST(AssertionWithMessageTest, ASSERT_STR) { ASSERT_STREQ("1", "1") << "This should succeed."; ASSERT_STRNE("1", "2") << "This should succeed."; ASSERT_STRCASEEQ("a", "A") << "This should succeed."; EXPECT_FATAL_FAILURE(ASSERT_STRCASENE("a", "A") << "Expected failure.", "Expected failure."); } TEST(AssertionWithMessageTest, ASSERT_FLOATING) { ASSERT_FLOAT_EQ(1, 1) << "This should succeed."; ASSERT_DOUBLE_EQ(1, 1) << "This should succeed."; EXPECT_FATAL_FAILURE(ASSERT_NEAR(1,1.2, 0.1) << "Expect failure.", // NOLINT "Expect failure."); // To work around a bug in gcc 2.95.0, there is intentionally no // space after the first comma in the previous statement. } // Tests using ASSERT_FALSE with a streamed message. TEST(AssertionWithMessageTest, ASSERT_FALSE) { ASSERT_FALSE(false) << "This shouldn't fail."; EXPECT_FATAL_FAILURE({ // NOLINT ASSERT_FALSE(true) << "Expected failure: " << 2 << " > " << 1 << " evaluates to " << true; }, "Expected failure"); } // Tests using FAIL with a streamed message. TEST(AssertionWithMessageTest, FAIL) { EXPECT_FATAL_FAILURE(FAIL() << 0, "0"); } // Tests using SUCCEED with a streamed message. TEST(AssertionWithMessageTest, SUCCEED) { SUCCEED() << "Success == " << 1; } // Tests using ASSERT_TRUE with a streamed message. TEST(AssertionWithMessageTest, ASSERT_TRUE) { ASSERT_TRUE(true) << "This should succeed."; ASSERT_TRUE(true) << true; EXPECT_FATAL_FAILURE({ // NOLINT ASSERT_TRUE(false) << static_cast(NULL) << static_cast(NULL); }, "(null)(null)"); } #if GTEST_OS_WINDOWS // Tests using wide strings in assertion messages. TEST(AssertionWithMessageTest, WideStringMessage) { EXPECT_NONFATAL_FAILURE({ // NOLINT EXPECT_TRUE(false) << L"This failure is expected.\x8119"; }, "This failure is expected."); EXPECT_FATAL_FAILURE({ // NOLINT ASSERT_EQ(1, 2) << "This failure is " << L"expected too.\x8120"; }, "This failure is expected too."); } #endif // GTEST_OS_WINDOWS // Tests EXPECT_TRUE. TEST(ExpectTest, EXPECT_TRUE) { EXPECT_TRUE(true) << "Intentional success"; EXPECT_NONFATAL_FAILURE(EXPECT_TRUE(false) << "Intentional failure #1.", "Intentional failure #1."); EXPECT_NONFATAL_FAILURE(EXPECT_TRUE(false) << "Intentional failure #2.", "Intentional failure #2."); EXPECT_TRUE(2 > 1); // NOLINT EXPECT_NONFATAL_FAILURE(EXPECT_TRUE(2 < 1), "Value of: 2 < 1\n" " Actual: false\n" "Expected: true"); EXPECT_NONFATAL_FAILURE(EXPECT_TRUE(2 > 3), "2 > 3"); } // Tests EXPECT_TRUE(predicate) for predicates returning AssertionResult. TEST(ExpectTest, ExpectTrueWithAssertionResult) { EXPECT_TRUE(ResultIsEven(2)); EXPECT_NONFATAL_FAILURE(EXPECT_TRUE(ResultIsEven(3)), "Value of: ResultIsEven(3)\n" " Actual: false (3 is odd)\n" "Expected: true"); EXPECT_TRUE(ResultIsEvenNoExplanation(2)); EXPECT_NONFATAL_FAILURE(EXPECT_TRUE(ResultIsEvenNoExplanation(3)), "Value of: ResultIsEvenNoExplanation(3)\n" " Actual: false (3 is odd)\n" "Expected: true"); } // Tests EXPECT_FALSE with a streamed message. TEST(ExpectTest, EXPECT_FALSE) { EXPECT_FALSE(2 < 1); // NOLINT EXPECT_FALSE(false) << "Intentional success"; EXPECT_NONFATAL_FAILURE(EXPECT_FALSE(true) << "Intentional failure #1.", "Intentional failure #1."); EXPECT_NONFATAL_FAILURE(EXPECT_FALSE(true) << "Intentional failure #2.", "Intentional failure #2."); EXPECT_NONFATAL_FAILURE(EXPECT_FALSE(2 > 1), "Value of: 2 > 1\n" " Actual: true\n" "Expected: false"); EXPECT_NONFATAL_FAILURE(EXPECT_FALSE(2 < 3), "2 < 3"); } // Tests EXPECT_FALSE(predicate) for predicates returning AssertionResult. TEST(ExpectTest, ExpectFalseWithAssertionResult) { EXPECT_FALSE(ResultIsEven(3)); EXPECT_NONFATAL_FAILURE(EXPECT_FALSE(ResultIsEven(2)), "Value of: ResultIsEven(2)\n" " Actual: true (2 is even)\n" "Expected: false"); EXPECT_FALSE(ResultIsEvenNoExplanation(3)); EXPECT_NONFATAL_FAILURE(EXPECT_FALSE(ResultIsEvenNoExplanation(2)), "Value of: ResultIsEvenNoExplanation(2)\n" " Actual: true\n" "Expected: false"); } #ifdef __BORLANDC__ // Restores warnings after previous "#pragma option push" supressed them # pragma option pop #endif // Tests EXPECT_EQ. TEST(ExpectTest, EXPECT_EQ) { EXPECT_EQ(5, 2 + 3); EXPECT_NONFATAL_FAILURE(EXPECT_EQ(5, 2*3), "Value of: 2*3\n" " Actual: 6\n" "Expected: 5"); EXPECT_NONFATAL_FAILURE(EXPECT_EQ(5, 2 - 3), "2 - 3"); } // Tests using EXPECT_EQ on double values. The purpose is to make // sure that the specialization we did for integer and anonymous enums // isn't used for double arguments. TEST(ExpectTest, EXPECT_EQ_Double) { // A success. EXPECT_EQ(5.6, 5.6); // A failure. EXPECT_NONFATAL_FAILURE(EXPECT_EQ(5.1, 5.2), "5.1"); } #if GTEST_CAN_COMPARE_NULL // Tests EXPECT_EQ(NULL, pointer). TEST(ExpectTest, EXPECT_EQ_NULL) { // A success. const char* p = NULL; // Some older GCC versions may issue a spurious warning in this or the next // assertion statement. This warning should not be suppressed with // static_cast since the test verifies the ability to use bare NULL as the // expected parameter to the macro. EXPECT_EQ(NULL, p); // A failure. int n = 0; EXPECT_NONFATAL_FAILURE(EXPECT_EQ(NULL, &n), "Value of: &n\n"); } #endif // GTEST_CAN_COMPARE_NULL // Tests EXPECT_EQ(0, non_pointer). Since the literal 0 can be // treated as a null pointer by the compiler, we need to make sure // that EXPECT_EQ(0, non_pointer) isn't interpreted by Google Test as // EXPECT_EQ(static_cast(NULL), non_pointer). TEST(ExpectTest, EXPECT_EQ_0) { int n = 0; // A success. EXPECT_EQ(0, n); // A failure. EXPECT_NONFATAL_FAILURE(EXPECT_EQ(0, 5.6), "Expected: 0"); } // Tests EXPECT_NE. TEST(ExpectTest, EXPECT_NE) { EXPECT_NE(6, 7); EXPECT_NONFATAL_FAILURE(EXPECT_NE('a', 'a'), "Expected: ('a') != ('a'), " "actual: 'a' (97, 0x61) vs 'a' (97, 0x61)"); EXPECT_NONFATAL_FAILURE(EXPECT_NE(2, 2), "2"); char* const p0 = NULL; EXPECT_NONFATAL_FAILURE(EXPECT_NE(p0, p0), "p0"); // Only way to get the Nokia compiler to compile the cast // is to have a separate void* variable first. Putting // the two casts on the same line doesn't work, neither does // a direct C-style to char*. void* pv1 = (void*)0x1234; // NOLINT char* const p1 = reinterpret_cast(pv1); EXPECT_NONFATAL_FAILURE(EXPECT_NE(p1, p1), "p1"); } // Tests EXPECT_LE. TEST(ExpectTest, EXPECT_LE) { EXPECT_LE(2, 3); EXPECT_LE(2, 2); EXPECT_NONFATAL_FAILURE(EXPECT_LE(2, 0), "Expected: (2) <= (0), actual: 2 vs 0"); EXPECT_NONFATAL_FAILURE(EXPECT_LE(1.1, 0.9), "(1.1) <= (0.9)"); } // Tests EXPECT_LT. TEST(ExpectTest, EXPECT_LT) { EXPECT_LT(2, 3); EXPECT_NONFATAL_FAILURE(EXPECT_LT(2, 2), "Expected: (2) < (2), actual: 2 vs 2"); EXPECT_NONFATAL_FAILURE(EXPECT_LT(2, 1), "(2) < (1)"); } // Tests EXPECT_GE. TEST(ExpectTest, EXPECT_GE) { EXPECT_GE(2, 1); EXPECT_GE(2, 2); EXPECT_NONFATAL_FAILURE(EXPECT_GE(2, 3), "Expected: (2) >= (3), actual: 2 vs 3"); EXPECT_NONFATAL_FAILURE(EXPECT_GE(0.9, 1.1), "(0.9) >= (1.1)"); } // Tests EXPECT_GT. TEST(ExpectTest, EXPECT_GT) { EXPECT_GT(2, 1); EXPECT_NONFATAL_FAILURE(EXPECT_GT(2, 2), "Expected: (2) > (2), actual: 2 vs 2"); EXPECT_NONFATAL_FAILURE(EXPECT_GT(2, 3), "(2) > (3)"); } #if GTEST_HAS_EXCEPTIONS // Tests EXPECT_THROW. TEST(ExpectTest, EXPECT_THROW) { EXPECT_THROW(ThrowAnInteger(), int); EXPECT_NONFATAL_FAILURE(EXPECT_THROW(ThrowAnInteger(), bool), "Expected: ThrowAnInteger() throws an exception of " "type bool.\n Actual: it throws a different type."); EXPECT_NONFATAL_FAILURE( EXPECT_THROW(ThrowNothing(), bool), "Expected: ThrowNothing() throws an exception of type bool.\n" " Actual: it throws nothing."); } // Tests EXPECT_NO_THROW. TEST(ExpectTest, EXPECT_NO_THROW) { EXPECT_NO_THROW(ThrowNothing()); EXPECT_NONFATAL_FAILURE(EXPECT_NO_THROW(ThrowAnInteger()), "Expected: ThrowAnInteger() doesn't throw an " "exception.\n Actual: it throws."); } // Tests EXPECT_ANY_THROW. TEST(ExpectTest, EXPECT_ANY_THROW) { EXPECT_ANY_THROW(ThrowAnInteger()); EXPECT_NONFATAL_FAILURE( EXPECT_ANY_THROW(ThrowNothing()), "Expected: ThrowNothing() throws an exception.\n" " Actual: it doesn't."); } #endif // GTEST_HAS_EXCEPTIONS // Make sure we deal with the precedence of <<. TEST(ExpectTest, ExpectPrecedence) { EXPECT_EQ(1 < 2, true); EXPECT_NONFATAL_FAILURE(EXPECT_EQ(true, true && false), "Value of: true && false"); } // Tests the StreamableToString() function. // Tests using StreamableToString() on a scalar. TEST(StreamableToStringTest, Scalar) { EXPECT_STREQ("5", StreamableToString(5).c_str()); } // Tests using StreamableToString() on a non-char pointer. TEST(StreamableToStringTest, Pointer) { int n = 0; int* p = &n; EXPECT_STRNE("(null)", StreamableToString(p).c_str()); } // Tests using StreamableToString() on a NULL non-char pointer. TEST(StreamableToStringTest, NullPointer) { int* p = NULL; EXPECT_STREQ("(null)", StreamableToString(p).c_str()); } // Tests using StreamableToString() on a C string. TEST(StreamableToStringTest, CString) { EXPECT_STREQ("Foo", StreamableToString("Foo").c_str()); } // Tests using StreamableToString() on a NULL C string. TEST(StreamableToStringTest, NullCString) { char* p = NULL; EXPECT_STREQ("(null)", StreamableToString(p).c_str()); } // Tests using streamable values as assertion messages. // Tests using std::string as an assertion message. TEST(StreamableTest, string) { static const std::string str( "This failure message is a std::string, and is expected."); EXPECT_FATAL_FAILURE(FAIL() << str, str.c_str()); } // Tests that we can output strings containing embedded NULs. // Limited to Linux because we can only do this with std::string's. TEST(StreamableTest, stringWithEmbeddedNUL) { static const char char_array_with_nul[] = "Here's a NUL\0 and some more string"; static const std::string string_with_nul(char_array_with_nul, sizeof(char_array_with_nul) - 1); // drops the trailing NUL EXPECT_FATAL_FAILURE(FAIL() << string_with_nul, "Here's a NUL\\0 and some more string"); } // Tests that we can output a NUL char. TEST(StreamableTest, NULChar) { EXPECT_FATAL_FAILURE({ // NOLINT FAIL() << "A NUL" << '\0' << " and some more string"; }, "A NUL\\0 and some more string"); } // Tests using int as an assertion message. TEST(StreamableTest, int) { EXPECT_FATAL_FAILURE(FAIL() << 900913, "900913"); } // Tests using NULL char pointer as an assertion message. // // In MSVC, streaming a NULL char * causes access violation. Google Test // implemented a workaround (substituting "(null)" for NULL). This // tests whether the workaround works. TEST(StreamableTest, NullCharPtr) { EXPECT_FATAL_FAILURE(FAIL() << static_cast(NULL), "(null)"); } // Tests that basic IO manipulators (endl, ends, and flush) can be // streamed to testing::Message. TEST(StreamableTest, BasicIoManip) { EXPECT_FATAL_FAILURE({ // NOLINT FAIL() << "Line 1." << std::endl << "A NUL char " << std::ends << std::flush << " in line 2."; }, "Line 1.\nA NUL char \\0 in line 2."); } // Tests the macros that haven't been covered so far. void AddFailureHelper(bool* aborted) { *aborted = true; ADD_FAILURE() << "Intentional failure."; *aborted = false; } // Tests ADD_FAILURE. TEST(MacroTest, ADD_FAILURE) { bool aborted = true; EXPECT_NONFATAL_FAILURE(AddFailureHelper(&aborted), "Intentional failure."); EXPECT_FALSE(aborted); } // Tests ADD_FAILURE_AT. TEST(MacroTest, ADD_FAILURE_AT) { // Verifies that ADD_FAILURE_AT does generate a nonfatal failure and // the failure message contains the user-streamed part. EXPECT_NONFATAL_FAILURE(ADD_FAILURE_AT("foo.cc", 42) << "Wrong!", "Wrong!"); // Verifies that the user-streamed part is optional. EXPECT_NONFATAL_FAILURE(ADD_FAILURE_AT("foo.cc", 42), "Failed"); // Unfortunately, we cannot verify that the failure message contains // the right file path and line number the same way, as // EXPECT_NONFATAL_FAILURE() doesn't get to see the file path and // line number. Instead, we do that in gtest_output_test_.cc. } // Tests FAIL. TEST(MacroTest, FAIL) { EXPECT_FATAL_FAILURE(FAIL(), "Failed"); EXPECT_FATAL_FAILURE(FAIL() << "Intentional failure.", "Intentional failure."); } // Tests SUCCEED TEST(MacroTest, SUCCEED) { SUCCEED(); SUCCEED() << "Explicit success."; } // Tests for EXPECT_EQ() and ASSERT_EQ(). // // These tests fail *intentionally*, s.t. the failure messages can be // generated and tested. // // We have different tests for different argument types. // Tests using bool values in {EXPECT|ASSERT}_EQ. TEST(EqAssertionTest, Bool) { EXPECT_EQ(true, true); EXPECT_FATAL_FAILURE({ bool false_value = false; ASSERT_EQ(false_value, true); }, "Value of: true"); } // Tests using int values in {EXPECT|ASSERT}_EQ. TEST(EqAssertionTest, Int) { ASSERT_EQ(32, 32); EXPECT_NONFATAL_FAILURE(EXPECT_EQ(32, 33), "33"); } // Tests using time_t values in {EXPECT|ASSERT}_EQ. TEST(EqAssertionTest, Time_T) { EXPECT_EQ(static_cast(0), static_cast(0)); EXPECT_FATAL_FAILURE(ASSERT_EQ(static_cast(0), static_cast(1234)), "1234"); } // Tests using char values in {EXPECT|ASSERT}_EQ. TEST(EqAssertionTest, Char) { ASSERT_EQ('z', 'z'); const char ch = 'b'; EXPECT_NONFATAL_FAILURE(EXPECT_EQ('\0', ch), "ch"); EXPECT_NONFATAL_FAILURE(EXPECT_EQ('a', ch), "ch"); } // Tests using wchar_t values in {EXPECT|ASSERT}_EQ. TEST(EqAssertionTest, WideChar) { EXPECT_EQ(L'b', L'b'); EXPECT_NONFATAL_FAILURE(EXPECT_EQ(L'\0', L'x'), "Value of: L'x'\n" " Actual: L'x' (120, 0x78)\n" "Expected: L'\0'\n" "Which is: L'\0' (0, 0x0)"); static wchar_t wchar; wchar = L'b'; EXPECT_NONFATAL_FAILURE(EXPECT_EQ(L'a', wchar), "wchar"); wchar = 0x8119; EXPECT_FATAL_FAILURE(ASSERT_EQ(static_cast(0x8120), wchar), "Value of: wchar"); } // Tests using ::std::string values in {EXPECT|ASSERT}_EQ. TEST(EqAssertionTest, StdString) { // Compares a const char* to an std::string that has identical // content. ASSERT_EQ("Test", ::std::string("Test")); // Compares two identical std::strings. static const ::std::string str1("A * in the middle"); static const ::std::string str2(str1); EXPECT_EQ(str1, str2); // Compares a const char* to an std::string that has different // content EXPECT_NONFATAL_FAILURE(EXPECT_EQ("Test", ::std::string("test")), "\"test\""); // Compares an std::string to a char* that has different content. char* const p1 = const_cast("foo"); EXPECT_NONFATAL_FAILURE(EXPECT_EQ(::std::string("bar"), p1), "p1"); // Compares two std::strings that have different contents, one of // which having a NUL character in the middle. This should fail. static ::std::string str3(str1); str3.at(2) = '\0'; EXPECT_FATAL_FAILURE(ASSERT_EQ(str1, str3), "Value of: str3\n" " Actual: \"A \\0 in the middle\""); } #if GTEST_HAS_STD_WSTRING // Tests using ::std::wstring values in {EXPECT|ASSERT}_EQ. TEST(EqAssertionTest, StdWideString) { // Compares two identical std::wstrings. const ::std::wstring wstr1(L"A * in the middle"); const ::std::wstring wstr2(wstr1); ASSERT_EQ(wstr1, wstr2); // Compares an std::wstring to a const wchar_t* that has identical // content. const wchar_t kTestX8119[] = { 'T', 'e', 's', 't', 0x8119, '\0' }; EXPECT_EQ(::std::wstring(kTestX8119), kTestX8119); // Compares an std::wstring to a const wchar_t* that has different // content. const wchar_t kTestX8120[] = { 'T', 'e', 's', 't', 0x8120, '\0' }; EXPECT_NONFATAL_FAILURE({ // NOLINT EXPECT_EQ(::std::wstring(kTestX8119), kTestX8120); }, "kTestX8120"); // Compares two std::wstrings that have different contents, one of // which having a NUL character in the middle. ::std::wstring wstr3(wstr1); wstr3.at(2) = L'\0'; EXPECT_NONFATAL_FAILURE(EXPECT_EQ(wstr1, wstr3), "wstr3"); // Compares a wchar_t* to an std::wstring that has different // content. EXPECT_FATAL_FAILURE({ // NOLINT ASSERT_EQ(const_cast(L"foo"), ::std::wstring(L"bar")); }, ""); } #endif // GTEST_HAS_STD_WSTRING #if GTEST_HAS_GLOBAL_STRING // Tests using ::string values in {EXPECT|ASSERT}_EQ. TEST(EqAssertionTest, GlobalString) { // Compares a const char* to a ::string that has identical content. EXPECT_EQ("Test", ::string("Test")); // Compares two identical ::strings. const ::string str1("A * in the middle"); const ::string str2(str1); ASSERT_EQ(str1, str2); // Compares a ::string to a const char* that has different content. EXPECT_NONFATAL_FAILURE(EXPECT_EQ(::string("Test"), "test"), "test"); // Compares two ::strings that have different contents, one of which // having a NUL character in the middle. ::string str3(str1); str3.at(2) = '\0'; EXPECT_NONFATAL_FAILURE(EXPECT_EQ(str1, str3), "str3"); // Compares a ::string to a char* that has different content. EXPECT_FATAL_FAILURE({ // NOLINT ASSERT_EQ(::string("bar"), const_cast("foo")); }, ""); } #endif // GTEST_HAS_GLOBAL_STRING #if GTEST_HAS_GLOBAL_WSTRING // Tests using ::wstring values in {EXPECT|ASSERT}_EQ. TEST(EqAssertionTest, GlobalWideString) { // Compares two identical ::wstrings. static const ::wstring wstr1(L"A * in the middle"); static const ::wstring wstr2(wstr1); EXPECT_EQ(wstr1, wstr2); // Compares a const wchar_t* to a ::wstring that has identical content. const wchar_t kTestX8119[] = { 'T', 'e', 's', 't', 0x8119, '\0' }; ASSERT_EQ(kTestX8119, ::wstring(kTestX8119)); // Compares a const wchar_t* to a ::wstring that has different // content. const wchar_t kTestX8120[] = { 'T', 'e', 's', 't', 0x8120, '\0' }; EXPECT_NONFATAL_FAILURE({ // NOLINT EXPECT_EQ(kTestX8120, ::wstring(kTestX8119)); }, "Test\\x8119"); // Compares a wchar_t* to a ::wstring that has different content. wchar_t* const p1 = const_cast(L"foo"); EXPECT_NONFATAL_FAILURE(EXPECT_EQ(p1, ::wstring(L"bar")), "bar"); // Compares two ::wstrings that have different contents, one of which // having a NUL character in the middle. static ::wstring wstr3; wstr3 = wstr1; wstr3.at(2) = L'\0'; EXPECT_FATAL_FAILURE(ASSERT_EQ(wstr1, wstr3), "wstr3"); } #endif // GTEST_HAS_GLOBAL_WSTRING // Tests using char pointers in {EXPECT|ASSERT}_EQ. TEST(EqAssertionTest, CharPointer) { char* const p0 = NULL; // Only way to get the Nokia compiler to compile the cast // is to have a separate void* variable first. Putting // the two casts on the same line doesn't work, neither does // a direct C-style to char*. void* pv1 = (void*)0x1234; // NOLINT void* pv2 = (void*)0xABC0; // NOLINT char* const p1 = reinterpret_cast(pv1); char* const p2 = reinterpret_cast(pv2); ASSERT_EQ(p1, p1); EXPECT_NONFATAL_FAILURE(EXPECT_EQ(p0, p2), "Value of: p2"); EXPECT_NONFATAL_FAILURE(EXPECT_EQ(p1, p2), "p2"); EXPECT_FATAL_FAILURE(ASSERT_EQ(reinterpret_cast(0x1234), reinterpret_cast(0xABC0)), "ABC0"); } // Tests using wchar_t pointers in {EXPECT|ASSERT}_EQ. TEST(EqAssertionTest, WideCharPointer) { wchar_t* const p0 = NULL; // Only way to get the Nokia compiler to compile the cast // is to have a separate void* variable first. Putting // the two casts on the same line doesn't work, neither does // a direct C-style to char*. void* pv1 = (void*)0x1234; // NOLINT void* pv2 = (void*)0xABC0; // NOLINT wchar_t* const p1 = reinterpret_cast(pv1); wchar_t* const p2 = reinterpret_cast(pv2); EXPECT_EQ(p0, p0); EXPECT_NONFATAL_FAILURE(EXPECT_EQ(p0, p2), "Value of: p2"); EXPECT_NONFATAL_FAILURE(EXPECT_EQ(p1, p2), "p2"); void* pv3 = (void*)0x1234; // NOLINT void* pv4 = (void*)0xABC0; // NOLINT const wchar_t* p3 = reinterpret_cast(pv3); const wchar_t* p4 = reinterpret_cast(pv4); EXPECT_NONFATAL_FAILURE(EXPECT_EQ(p3, p4), "p4"); } // Tests using other types of pointers in {EXPECT|ASSERT}_EQ. TEST(EqAssertionTest, OtherPointer) { ASSERT_EQ(static_cast(NULL), static_cast(NULL)); EXPECT_FATAL_FAILURE(ASSERT_EQ(static_cast(NULL), reinterpret_cast(0x1234)), "0x1234"); } // A class that supports binary comparison operators but not streaming. class UnprintableChar { public: explicit UnprintableChar(char ch) : char_(ch) {} bool operator==(const UnprintableChar& rhs) const { return char_ == rhs.char_; } bool operator!=(const UnprintableChar& rhs) const { return char_ != rhs.char_; } bool operator<(const UnprintableChar& rhs) const { return char_ < rhs.char_; } bool operator<=(const UnprintableChar& rhs) const { return char_ <= rhs.char_; } bool operator>(const UnprintableChar& rhs) const { return char_ > rhs.char_; } bool operator>=(const UnprintableChar& rhs) const { return char_ >= rhs.char_; } private: char char_; }; // Tests that ASSERT_EQ() and friends don't require the arguments to // be printable. TEST(ComparisonAssertionTest, AcceptsUnprintableArgs) { const UnprintableChar x('x'), y('y'); ASSERT_EQ(x, x); EXPECT_NE(x, y); ASSERT_LT(x, y); EXPECT_LE(x, y); ASSERT_GT(y, x); EXPECT_GE(x, x); EXPECT_NONFATAL_FAILURE(EXPECT_EQ(x, y), "1-byte object <78>"); EXPECT_NONFATAL_FAILURE(EXPECT_EQ(x, y), "1-byte object <79>"); EXPECT_NONFATAL_FAILURE(EXPECT_LT(y, y), "1-byte object <79>"); EXPECT_NONFATAL_FAILURE(EXPECT_GT(x, y), "1-byte object <78>"); EXPECT_NONFATAL_FAILURE(EXPECT_GT(x, y), "1-byte object <79>"); // Code tested by EXPECT_FATAL_FAILURE cannot reference local // variables, so we have to write UnprintableChar('x') instead of x. #ifndef __BORLANDC__ // ICE's in C++Builder. EXPECT_FATAL_FAILURE(ASSERT_NE(UnprintableChar('x'), UnprintableChar('x')), "1-byte object <78>"); EXPECT_FATAL_FAILURE(ASSERT_LE(UnprintableChar('y'), UnprintableChar('x')), "1-byte object <78>"); #endif EXPECT_FATAL_FAILURE(ASSERT_LE(UnprintableChar('y'), UnprintableChar('x')), "1-byte object <79>"); EXPECT_FATAL_FAILURE(ASSERT_GE(UnprintableChar('x'), UnprintableChar('y')), "1-byte object <78>"); EXPECT_FATAL_FAILURE(ASSERT_GE(UnprintableChar('x'), UnprintableChar('y')), "1-byte object <79>"); } // Tests the FRIEND_TEST macro. // This class has a private member we want to test. We will test it // both in a TEST and in a TEST_F. class Foo { public: Foo() {} private: int Bar() const { return 1; } // Declares the friend tests that can access the private member // Bar(). FRIEND_TEST(FRIEND_TEST_Test, TEST); FRIEND_TEST(FRIEND_TEST_Test2, TEST_F); }; // Tests that the FRIEND_TEST declaration allows a TEST to access a // class's private members. This should compile. TEST(FRIEND_TEST_Test, TEST) { ASSERT_EQ(1, Foo().Bar()); } // The fixture needed to test using FRIEND_TEST with TEST_F. class FRIEND_TEST_Test2 : public Test { protected: Foo foo; }; // Tests that the FRIEND_TEST declaration allows a TEST_F to access a // class's private members. This should compile. TEST_F(FRIEND_TEST_Test2, TEST_F) { ASSERT_EQ(1, foo.Bar()); } // Tests the life cycle of Test objects. // The test fixture for testing the life cycle of Test objects. // // This class counts the number of live test objects that uses this // fixture. class TestLifeCycleTest : public Test { protected: // Constructor. Increments the number of test objects that uses // this fixture. TestLifeCycleTest() { count_++; } // Destructor. Decrements the number of test objects that uses this // fixture. ~TestLifeCycleTest() { count_--; } // Returns the number of live test objects that uses this fixture. int count() const { return count_; } private: static int count_; }; int TestLifeCycleTest::count_ = 0; // Tests the life cycle of test objects. TEST_F(TestLifeCycleTest, Test1) { // There should be only one test object in this test case that's // currently alive. ASSERT_EQ(1, count()); } // Tests the life cycle of test objects. TEST_F(TestLifeCycleTest, Test2) { // After Test1 is done and Test2 is started, there should still be // only one live test object, as the object for Test1 should've been // deleted. ASSERT_EQ(1, count()); } } // namespace // Tests that the copy constructor works when it is NOT optimized away by // the compiler. TEST(AssertionResultTest, CopyConstructorWorksWhenNotOptimied) { // Checks that the copy constructor doesn't try to dereference NULL pointers // in the source object. AssertionResult r1 = AssertionSuccess(); AssertionResult r2 = r1; // The following line is added to prevent the compiler from optimizing // away the constructor call. r1 << "abc"; AssertionResult r3 = r1; EXPECT_EQ(static_cast(r3), static_cast(r1)); EXPECT_STREQ("abc", r1.message()); } // Tests that AssertionSuccess and AssertionFailure construct // AssertionResult objects as expected. TEST(AssertionResultTest, ConstructionWorks) { AssertionResult r1 = AssertionSuccess(); EXPECT_TRUE(r1); EXPECT_STREQ("", r1.message()); AssertionResult r2 = AssertionSuccess() << "abc"; EXPECT_TRUE(r2); EXPECT_STREQ("abc", r2.message()); AssertionResult r3 = AssertionFailure(); EXPECT_FALSE(r3); EXPECT_STREQ("", r3.message()); AssertionResult r4 = AssertionFailure() << "def"; EXPECT_FALSE(r4); EXPECT_STREQ("def", r4.message()); AssertionResult r5 = AssertionFailure(Message() << "ghi"); EXPECT_FALSE(r5); EXPECT_STREQ("ghi", r5.message()); } // Tests that the negation flips the predicate result but keeps the message. TEST(AssertionResultTest, NegationWorks) { AssertionResult r1 = AssertionSuccess() << "abc"; EXPECT_FALSE(!r1); EXPECT_STREQ("abc", (!r1).message()); AssertionResult r2 = AssertionFailure() << "def"; EXPECT_TRUE(!r2); EXPECT_STREQ("def", (!r2).message()); } TEST(AssertionResultTest, StreamingWorks) { AssertionResult r = AssertionSuccess(); r << "abc" << 'd' << 0 << true; EXPECT_STREQ("abcd0true", r.message()); } TEST(AssertionResultTest, CanStreamOstreamManipulators) { AssertionResult r = AssertionSuccess(); r << "Data" << std::endl << std::flush << std::ends << "Will be visible"; EXPECT_STREQ("Data\n\\0Will be visible", r.message()); } // Tests streaming a user type whose definition and operator << are // both in the global namespace. class Base { public: explicit Base(int an_x) : x_(an_x) {} int x() const { return x_; } private: int x_; }; std::ostream& operator<<(std::ostream& os, const Base& val) { return os << val.x(); } std::ostream& operator<<(std::ostream& os, const Base* pointer) { return os << "(" << pointer->x() << ")"; } TEST(MessageTest, CanStreamUserTypeInGlobalNameSpace) { Message msg; Base a(1); msg << a << &a; // Uses ::operator<<. EXPECT_STREQ("1(1)", msg.GetString().c_str()); } // Tests streaming a user type whose definition and operator<< are // both in an unnamed namespace. namespace { class MyTypeInUnnamedNameSpace : public Base { public: explicit MyTypeInUnnamedNameSpace(int an_x): Base(an_x) {} }; std::ostream& operator<<(std::ostream& os, const MyTypeInUnnamedNameSpace& val) { return os << val.x(); } std::ostream& operator<<(std::ostream& os, const MyTypeInUnnamedNameSpace* pointer) { return os << "(" << pointer->x() << ")"; } } // namespace TEST(MessageTest, CanStreamUserTypeInUnnamedNameSpace) { Message msg; MyTypeInUnnamedNameSpace a(1); msg << a << &a; // Uses ::operator<<. EXPECT_STREQ("1(1)", msg.GetString().c_str()); } // Tests streaming a user type whose definition and operator<< are // both in a user namespace. namespace namespace1 { class MyTypeInNameSpace1 : public Base { public: explicit MyTypeInNameSpace1(int an_x): Base(an_x) {} }; std::ostream& operator<<(std::ostream& os, const MyTypeInNameSpace1& val) { return os << val.x(); } std::ostream& operator<<(std::ostream& os, const MyTypeInNameSpace1* pointer) { return os << "(" << pointer->x() << ")"; } } // namespace namespace1 TEST(MessageTest, CanStreamUserTypeInUserNameSpace) { Message msg; namespace1::MyTypeInNameSpace1 a(1); msg << a << &a; // Uses namespace1::operator<<. EXPECT_STREQ("1(1)", msg.GetString().c_str()); } // Tests streaming a user type whose definition is in a user namespace // but whose operator<< is in the global namespace. namespace namespace2 { class MyTypeInNameSpace2 : public ::Base { public: explicit MyTypeInNameSpace2(int an_x): Base(an_x) {} }; } // namespace namespace2 std::ostream& operator<<(std::ostream& os, const namespace2::MyTypeInNameSpace2& val) { return os << val.x(); } std::ostream& operator<<(std::ostream& os, const namespace2::MyTypeInNameSpace2* pointer) { return os << "(" << pointer->x() << ")"; } TEST(MessageTest, CanStreamUserTypeInUserNameSpaceWithStreamOperatorInGlobal) { Message msg; namespace2::MyTypeInNameSpace2 a(1); msg << a << &a; // Uses ::operator<<. EXPECT_STREQ("1(1)", msg.GetString().c_str()); } // Tests streaming NULL pointers to testing::Message. TEST(MessageTest, NullPointers) { Message msg; char* const p1 = NULL; unsigned char* const p2 = NULL; int* p3 = NULL; double* p4 = NULL; bool* p5 = NULL; Message* p6 = NULL; msg << p1 << p2 << p3 << p4 << p5 << p6; ASSERT_STREQ("(null)(null)(null)(null)(null)(null)", msg.GetString().c_str()); } // Tests streaming wide strings to testing::Message. TEST(MessageTest, WideStrings) { // Streams a NULL of type const wchar_t*. const wchar_t* const_wstr = NULL; EXPECT_STREQ("(null)", (Message() << const_wstr).GetString().c_str()); // Streams a NULL of type wchar_t*. wchar_t* wstr = NULL; EXPECT_STREQ("(null)", (Message() << wstr).GetString().c_str()); // Streams a non-NULL of type const wchar_t*. const_wstr = L"abc\x8119"; EXPECT_STREQ("abc\xe8\x84\x99", (Message() << const_wstr).GetString().c_str()); // Streams a non-NULL of type wchar_t*. wstr = const_cast(const_wstr); EXPECT_STREQ("abc\xe8\x84\x99", (Message() << wstr).GetString().c_str()); } // This line tests that we can define tests in the testing namespace. namespace testing { // Tests the TestInfo class. class TestInfoTest : public Test { protected: static const TestInfo* GetTestInfo(const char* test_name) { const TestCase* const test_case = GetUnitTestImpl()-> GetTestCase("TestInfoTest", "", NULL, NULL); for (int i = 0; i < test_case->total_test_count(); ++i) { const TestInfo* const test_info = test_case->GetTestInfo(i); if (strcmp(test_name, test_info->name()) == 0) return test_info; } return NULL; } static const TestResult* GetTestResult( const TestInfo* test_info) { return test_info->result(); } }; // Tests TestInfo::test_case_name() and TestInfo::name(). TEST_F(TestInfoTest, Names) { const TestInfo* const test_info = GetTestInfo("Names"); ASSERT_STREQ("TestInfoTest", test_info->test_case_name()); ASSERT_STREQ("Names", test_info->name()); } // Tests TestInfo::result(). TEST_F(TestInfoTest, result) { const TestInfo* const test_info = GetTestInfo("result"); // Initially, there is no TestPartResult for this test. ASSERT_EQ(0, GetTestResult(test_info)->total_part_count()); // After the previous assertion, there is still none. ASSERT_EQ(0, GetTestResult(test_info)->total_part_count()); } // Tests setting up and tearing down a test case. class SetUpTestCaseTest : public Test { protected: // This will be called once before the first test in this test case // is run. static void SetUpTestCase() { printf("Setting up the test case . . .\n"); // Initializes some shared resource. In this simple example, we // just create a C string. More complex stuff can be done if // desired. shared_resource_ = "123"; // Increments the number of test cases that have been set up. counter_++; // SetUpTestCase() should be called only once. EXPECT_EQ(1, counter_); } // This will be called once after the last test in this test case is // run. static void TearDownTestCase() { printf("Tearing down the test case . . .\n"); // Decrements the number of test cases that have been set up. counter_--; // TearDownTestCase() should be called only once. EXPECT_EQ(0, counter_); // Cleans up the shared resource. shared_resource_ = NULL; } // This will be called before each test in this test case. virtual void SetUp() { // SetUpTestCase() should be called only once, so counter_ should // always be 1. EXPECT_EQ(1, counter_); } // Number of test cases that have been set up. static int counter_; // Some resource to be shared by all tests in this test case. static const char* shared_resource_; }; int SetUpTestCaseTest::counter_ = 0; const char* SetUpTestCaseTest::shared_resource_ = NULL; // A test that uses the shared resource. TEST_F(SetUpTestCaseTest, Test1) { EXPECT_STRNE(NULL, shared_resource_); } // Another test that uses the shared resource. TEST_F(SetUpTestCaseTest, Test2) { EXPECT_STREQ("123", shared_resource_); } // The InitGoogleTestTest test case tests testing::InitGoogleTest(). // The Flags struct stores a copy of all Google Test flags. struct Flags { // Constructs a Flags struct where each flag has its default value. Flags() : also_run_disabled_tests(false), break_on_failure(false), catch_exceptions(false), death_test_use_fork(false), filter(""), list_tests(false), output(""), print_time(true), random_seed(0), repeat(1), shuffle(false), stack_trace_depth(kMaxStackTraceDepth), stream_result_to(""), throw_on_failure(false) {} // Factory methods. // Creates a Flags struct where the gtest_also_run_disabled_tests flag has // the given value. static Flags AlsoRunDisabledTests(bool also_run_disabled_tests) { Flags flags; flags.also_run_disabled_tests = also_run_disabled_tests; return flags; } // Creates a Flags struct where the gtest_break_on_failure flag has // the given value. static Flags BreakOnFailure(bool break_on_failure) { Flags flags; flags.break_on_failure = break_on_failure; return flags; } // Creates a Flags struct where the gtest_catch_exceptions flag has // the given value. static Flags CatchExceptions(bool catch_exceptions) { Flags flags; flags.catch_exceptions = catch_exceptions; return flags; } // Creates a Flags struct where the gtest_death_test_use_fork flag has // the given value. static Flags DeathTestUseFork(bool death_test_use_fork) { Flags flags; flags.death_test_use_fork = death_test_use_fork; return flags; } // Creates a Flags struct where the gtest_filter flag has the given // value. static Flags Filter(const char* filter) { Flags flags; flags.filter = filter; return flags; } // Creates a Flags struct where the gtest_list_tests flag has the // given value. static Flags ListTests(bool list_tests) { Flags flags; flags.list_tests = list_tests; return flags; } // Creates a Flags struct where the gtest_output flag has the given // value. static Flags Output(const char* output) { Flags flags; flags.output = output; return flags; } // Creates a Flags struct where the gtest_print_time flag has the given // value. static Flags PrintTime(bool print_time) { Flags flags; flags.print_time = print_time; return flags; } // Creates a Flags struct where the gtest_random_seed flag has // the given value. static Flags RandomSeed(Int32 random_seed) { Flags flags; flags.random_seed = random_seed; return flags; } // Creates a Flags struct where the gtest_repeat flag has the given // value. static Flags Repeat(Int32 repeat) { Flags flags; flags.repeat = repeat; return flags; } // Creates a Flags struct where the gtest_shuffle flag has // the given value. static Flags Shuffle(bool shuffle) { Flags flags; flags.shuffle = shuffle; return flags; } // Creates a Flags struct where the GTEST_FLAG(stack_trace_depth) flag has // the given value. static Flags StackTraceDepth(Int32 stack_trace_depth) { Flags flags; flags.stack_trace_depth = stack_trace_depth; return flags; } // Creates a Flags struct where the GTEST_FLAG(stream_result_to) flag has // the given value. static Flags StreamResultTo(const char* stream_result_to) { Flags flags; flags.stream_result_to = stream_result_to; return flags; } // Creates a Flags struct where the gtest_throw_on_failure flag has // the given value. static Flags ThrowOnFailure(bool throw_on_failure) { Flags flags; flags.throw_on_failure = throw_on_failure; return flags; } // These fields store the flag values. bool also_run_disabled_tests; bool break_on_failure; bool catch_exceptions; bool death_test_use_fork; const char* filter; bool list_tests; const char* output; bool print_time; Int32 random_seed; Int32 repeat; bool shuffle; Int32 stack_trace_depth; const char* stream_result_to; bool throw_on_failure; }; // Fixture for testing InitGoogleTest(). class InitGoogleTestTest : public Test { protected: // Clears the flags before each test. virtual void SetUp() { GTEST_FLAG(also_run_disabled_tests) = false; GTEST_FLAG(break_on_failure) = false; GTEST_FLAG(catch_exceptions) = false; GTEST_FLAG(death_test_use_fork) = false; GTEST_FLAG(filter) = ""; GTEST_FLAG(list_tests) = false; GTEST_FLAG(output) = ""; GTEST_FLAG(print_time) = true; GTEST_FLAG(random_seed) = 0; GTEST_FLAG(repeat) = 1; GTEST_FLAG(shuffle) = false; GTEST_FLAG(stack_trace_depth) = kMaxStackTraceDepth; GTEST_FLAG(stream_result_to) = ""; GTEST_FLAG(throw_on_failure) = false; } // Asserts that two narrow or wide string arrays are equal. template static void AssertStringArrayEq(size_t size1, CharType** array1, size_t size2, CharType** array2) { ASSERT_EQ(size1, size2) << " Array sizes different."; for (size_t i = 0; i != size1; i++) { ASSERT_STREQ(array1[i], array2[i]) << " where i == " << i; } } // Verifies that the flag values match the expected values. static void CheckFlags(const Flags& expected) { EXPECT_EQ(expected.also_run_disabled_tests, GTEST_FLAG(also_run_disabled_tests)); EXPECT_EQ(expected.break_on_failure, GTEST_FLAG(break_on_failure)); EXPECT_EQ(expected.catch_exceptions, GTEST_FLAG(catch_exceptions)); EXPECT_EQ(expected.death_test_use_fork, GTEST_FLAG(death_test_use_fork)); EXPECT_STREQ(expected.filter, GTEST_FLAG(filter).c_str()); EXPECT_EQ(expected.list_tests, GTEST_FLAG(list_tests)); EXPECT_STREQ(expected.output, GTEST_FLAG(output).c_str()); EXPECT_EQ(expected.print_time, GTEST_FLAG(print_time)); EXPECT_EQ(expected.random_seed, GTEST_FLAG(random_seed)); EXPECT_EQ(expected.repeat, GTEST_FLAG(repeat)); EXPECT_EQ(expected.shuffle, GTEST_FLAG(shuffle)); EXPECT_EQ(expected.stack_trace_depth, GTEST_FLAG(stack_trace_depth)); EXPECT_STREQ(expected.stream_result_to, GTEST_FLAG(stream_result_to).c_str()); EXPECT_EQ(expected.throw_on_failure, GTEST_FLAG(throw_on_failure)); } // Parses a command line (specified by argc1 and argv1), then // verifies that the flag values are expected and that the // recognized flags are removed from the command line. template static void TestParsingFlags(int argc1, const CharType** argv1, int argc2, const CharType** argv2, const Flags& expected, bool should_print_help) { const bool saved_help_flag = ::testing::internal::g_help_flag; ::testing::internal::g_help_flag = false; #if GTEST_HAS_STREAM_REDIRECTION CaptureStdout(); #endif // Parses the command line. internal::ParseGoogleTestFlagsOnly(&argc1, const_cast(argv1)); #if GTEST_HAS_STREAM_REDIRECTION const std::string captured_stdout = GetCapturedStdout(); #endif // Verifies the flag values. CheckFlags(expected); // Verifies that the recognized flags are removed from the command // line. AssertStringArrayEq(argc1 + 1, argv1, argc2 + 1, argv2); // ParseGoogleTestFlagsOnly should neither set g_help_flag nor print the // help message for the flags it recognizes. EXPECT_EQ(should_print_help, ::testing::internal::g_help_flag); #if GTEST_HAS_STREAM_REDIRECTION const char* const expected_help_fragment = "This program contains tests written using"; if (should_print_help) { EXPECT_PRED_FORMAT2(IsSubstring, expected_help_fragment, captured_stdout); } else { EXPECT_PRED_FORMAT2(IsNotSubstring, expected_help_fragment, captured_stdout); } #endif // GTEST_HAS_STREAM_REDIRECTION ::testing::internal::g_help_flag = saved_help_flag; } // This macro wraps TestParsingFlags s.t. the user doesn't need // to specify the array sizes. #define GTEST_TEST_PARSING_FLAGS_(argv1, argv2, expected, should_print_help) \ TestParsingFlags(sizeof(argv1)/sizeof(*argv1) - 1, argv1, \ sizeof(argv2)/sizeof(*argv2) - 1, argv2, \ expected, should_print_help) }; // Tests parsing an empty command line. TEST_F(InitGoogleTestTest, Empty) { const char* argv[] = { NULL }; const char* argv2[] = { NULL }; GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags(), false); } // Tests parsing a command line that has no flag. TEST_F(InitGoogleTestTest, NoFlag) { const char* argv[] = { "foo.exe", NULL }; const char* argv2[] = { "foo.exe", NULL }; GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags(), false); } // Tests parsing a bad --gtest_filter flag. TEST_F(InitGoogleTestTest, FilterBad) { const char* argv[] = { "foo.exe", "--gtest_filter", NULL }; const char* argv2[] = { "foo.exe", "--gtest_filter", NULL }; GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Filter(""), true); } // Tests parsing an empty --gtest_filter flag. TEST_F(InitGoogleTestTest, FilterEmpty) { const char* argv[] = { "foo.exe", "--gtest_filter=", NULL }; const char* argv2[] = { "foo.exe", NULL }; GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Filter(""), false); } // Tests parsing a non-empty --gtest_filter flag. TEST_F(InitGoogleTestTest, FilterNonEmpty) { const char* argv[] = { "foo.exe", "--gtest_filter=abc", NULL }; const char* argv2[] = { "foo.exe", NULL }; GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Filter("abc"), false); } // Tests parsing --gtest_break_on_failure. TEST_F(InitGoogleTestTest, BreakOnFailureWithoutValue) { const char* argv[] = { "foo.exe", "--gtest_break_on_failure", NULL }; const char* argv2[] = { "foo.exe", NULL }; GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::BreakOnFailure(true), false); } // Tests parsing --gtest_break_on_failure=0. TEST_F(InitGoogleTestTest, BreakOnFailureFalse_0) { const char* argv[] = { "foo.exe", "--gtest_break_on_failure=0", NULL }; const char* argv2[] = { "foo.exe", NULL }; GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::BreakOnFailure(false), false); } // Tests parsing --gtest_break_on_failure=f. TEST_F(InitGoogleTestTest, BreakOnFailureFalse_f) { const char* argv[] = { "foo.exe", "--gtest_break_on_failure=f", NULL }; const char* argv2[] = { "foo.exe", NULL }; GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::BreakOnFailure(false), false); } // Tests parsing --gtest_break_on_failure=F. TEST_F(InitGoogleTestTest, BreakOnFailureFalse_F) { const char* argv[] = { "foo.exe", "--gtest_break_on_failure=F", NULL }; const char* argv2[] = { "foo.exe", NULL }; GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::BreakOnFailure(false), false); } // Tests parsing a --gtest_break_on_failure flag that has a "true" // definition. TEST_F(InitGoogleTestTest, BreakOnFailureTrue) { const char* argv[] = { "foo.exe", "--gtest_break_on_failure=1", NULL }; const char* argv2[] = { "foo.exe", NULL }; GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::BreakOnFailure(true), false); } // Tests parsing --gtest_catch_exceptions. TEST_F(InitGoogleTestTest, CatchExceptions) { const char* argv[] = { "foo.exe", "--gtest_catch_exceptions", NULL }; const char* argv2[] = { "foo.exe", NULL }; GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::CatchExceptions(true), false); } // Tests parsing --gtest_death_test_use_fork. TEST_F(InitGoogleTestTest, DeathTestUseFork) { const char* argv[] = { "foo.exe", "--gtest_death_test_use_fork", NULL }; const char* argv2[] = { "foo.exe", NULL }; GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::DeathTestUseFork(true), false); } // Tests having the same flag twice with different values. The // expected behavior is that the one coming last takes precedence. TEST_F(InitGoogleTestTest, DuplicatedFlags) { const char* argv[] = { "foo.exe", "--gtest_filter=a", "--gtest_filter=b", NULL }; const char* argv2[] = { "foo.exe", NULL }; GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Filter("b"), false); } // Tests having an unrecognized flag on the command line. TEST_F(InitGoogleTestTest, UnrecognizedFlag) { const char* argv[] = { "foo.exe", "--gtest_break_on_failure", "bar", // Unrecognized by Google Test. "--gtest_filter=b", NULL }; const char* argv2[] = { "foo.exe", "bar", NULL }; Flags flags; flags.break_on_failure = true; flags.filter = "b"; GTEST_TEST_PARSING_FLAGS_(argv, argv2, flags, false); } // Tests having a --gtest_list_tests flag TEST_F(InitGoogleTestTest, ListTestsFlag) { const char* argv[] = { "foo.exe", "--gtest_list_tests", NULL }; const char* argv2[] = { "foo.exe", NULL }; GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::ListTests(true), false); } // Tests having a --gtest_list_tests flag with a "true" value TEST_F(InitGoogleTestTest, ListTestsTrue) { const char* argv[] = { "foo.exe", "--gtest_list_tests=1", NULL }; const char* argv2[] = { "foo.exe", NULL }; GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::ListTests(true), false); } // Tests having a --gtest_list_tests flag with a "false" value TEST_F(InitGoogleTestTest, ListTestsFalse) { const char* argv[] = { "foo.exe", "--gtest_list_tests=0", NULL }; const char* argv2[] = { "foo.exe", NULL }; GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::ListTests(false), false); } // Tests parsing --gtest_list_tests=f. TEST_F(InitGoogleTestTest, ListTestsFalse_f) { const char* argv[] = { "foo.exe", "--gtest_list_tests=f", NULL }; const char* argv2[] = { "foo.exe", NULL }; GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::ListTests(false), false); } // Tests parsing --gtest_list_tests=F. TEST_F(InitGoogleTestTest, ListTestsFalse_F) { const char* argv[] = { "foo.exe", "--gtest_list_tests=F", NULL }; const char* argv2[] = { "foo.exe", NULL }; GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::ListTests(false), false); } // Tests parsing --gtest_output (invalid). TEST_F(InitGoogleTestTest, OutputEmpty) { const char* argv[] = { "foo.exe", "--gtest_output", NULL }; const char* argv2[] = { "foo.exe", "--gtest_output", NULL }; GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags(), true); } // Tests parsing --gtest_output=xml TEST_F(InitGoogleTestTest, OutputXml) { const char* argv[] = { "foo.exe", "--gtest_output=xml", NULL }; const char* argv2[] = { "foo.exe", NULL }; GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Output("xml"), false); } // Tests parsing --gtest_output=xml:file TEST_F(InitGoogleTestTest, OutputXmlFile) { const char* argv[] = { "foo.exe", "--gtest_output=xml:file", NULL }; const char* argv2[] = { "foo.exe", NULL }; GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Output("xml:file"), false); } // Tests parsing --gtest_output=xml:directory/path/ TEST_F(InitGoogleTestTest, OutputXmlDirectory) { const char* argv[] = { "foo.exe", "--gtest_output=xml:directory/path/", NULL }; const char* argv2[] = { "foo.exe", NULL }; GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Output("xml:directory/path/"), false); } // Tests having a --gtest_print_time flag TEST_F(InitGoogleTestTest, PrintTimeFlag) { const char* argv[] = { "foo.exe", "--gtest_print_time", NULL }; const char* argv2[] = { "foo.exe", NULL }; GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::PrintTime(true), false); } // Tests having a --gtest_print_time flag with a "true" value TEST_F(InitGoogleTestTest, PrintTimeTrue) { const char* argv[] = { "foo.exe", "--gtest_print_time=1", NULL }; const char* argv2[] = { "foo.exe", NULL }; GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::PrintTime(true), false); } // Tests having a --gtest_print_time flag with a "false" value TEST_F(InitGoogleTestTest, PrintTimeFalse) { const char* argv[] = { "foo.exe", "--gtest_print_time=0", NULL }; const char* argv2[] = { "foo.exe", NULL }; GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::PrintTime(false), false); } // Tests parsing --gtest_print_time=f. TEST_F(InitGoogleTestTest, PrintTimeFalse_f) { const char* argv[] = { "foo.exe", "--gtest_print_time=f", NULL }; const char* argv2[] = { "foo.exe", NULL }; GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::PrintTime(false), false); } // Tests parsing --gtest_print_time=F. TEST_F(InitGoogleTestTest, PrintTimeFalse_F) { const char* argv[] = { "foo.exe", "--gtest_print_time=F", NULL }; const char* argv2[] = { "foo.exe", NULL }; GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::PrintTime(false), false); } // Tests parsing --gtest_random_seed=number TEST_F(InitGoogleTestTest, RandomSeed) { const char* argv[] = { "foo.exe", "--gtest_random_seed=1000", NULL }; const char* argv2[] = { "foo.exe", NULL }; GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::RandomSeed(1000), false); } // Tests parsing --gtest_repeat=number TEST_F(InitGoogleTestTest, Repeat) { const char* argv[] = { "foo.exe", "--gtest_repeat=1000", NULL }; const char* argv2[] = { "foo.exe", NULL }; GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Repeat(1000), false); } // Tests having a --gtest_also_run_disabled_tests flag TEST_F(InitGoogleTestTest, AlsoRunDisabledTestsFlag) { const char* argv[] = { "foo.exe", "--gtest_also_run_disabled_tests", NULL }; const char* argv2[] = { "foo.exe", NULL }; GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::AlsoRunDisabledTests(true), false); } // Tests having a --gtest_also_run_disabled_tests flag with a "true" value TEST_F(InitGoogleTestTest, AlsoRunDisabledTestsTrue) { const char* argv[] = { "foo.exe", "--gtest_also_run_disabled_tests=1", NULL }; const char* argv2[] = { "foo.exe", NULL }; GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::AlsoRunDisabledTests(true), false); } // Tests having a --gtest_also_run_disabled_tests flag with a "false" value TEST_F(InitGoogleTestTest, AlsoRunDisabledTestsFalse) { const char* argv[] = { "foo.exe", "--gtest_also_run_disabled_tests=0", NULL }; const char* argv2[] = { "foo.exe", NULL }; GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::AlsoRunDisabledTests(false), false); } // Tests parsing --gtest_shuffle. TEST_F(InitGoogleTestTest, ShuffleWithoutValue) { const char* argv[] = { "foo.exe", "--gtest_shuffle", NULL }; const char* argv2[] = { "foo.exe", NULL }; GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Shuffle(true), false); } // Tests parsing --gtest_shuffle=0. TEST_F(InitGoogleTestTest, ShuffleFalse_0) { const char* argv[] = { "foo.exe", "--gtest_shuffle=0", NULL }; const char* argv2[] = { "foo.exe", NULL }; GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Shuffle(false), false); } // Tests parsing a --gtest_shuffle flag that has a "true" // definition. TEST_F(InitGoogleTestTest, ShuffleTrue) { const char* argv[] = { "foo.exe", "--gtest_shuffle=1", NULL }; const char* argv2[] = { "foo.exe", NULL }; GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Shuffle(true), false); } // Tests parsing --gtest_stack_trace_depth=number. TEST_F(InitGoogleTestTest, StackTraceDepth) { const char* argv[] = { "foo.exe", "--gtest_stack_trace_depth=5", NULL }; const char* argv2[] = { "foo.exe", NULL }; GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::StackTraceDepth(5), false); } TEST_F(InitGoogleTestTest, StreamResultTo) { const char* argv[] = { "foo.exe", "--gtest_stream_result_to=localhost:1234", NULL }; const char* argv2[] = { "foo.exe", NULL }; GTEST_TEST_PARSING_FLAGS_( argv, argv2, Flags::StreamResultTo("localhost:1234"), false); } // Tests parsing --gtest_throw_on_failure. TEST_F(InitGoogleTestTest, ThrowOnFailureWithoutValue) { const char* argv[] = { "foo.exe", "--gtest_throw_on_failure", NULL }; const char* argv2[] = { "foo.exe", NULL }; GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::ThrowOnFailure(true), false); } // Tests parsing --gtest_throw_on_failure=0. TEST_F(InitGoogleTestTest, ThrowOnFailureFalse_0) { const char* argv[] = { "foo.exe", "--gtest_throw_on_failure=0", NULL }; const char* argv2[] = { "foo.exe", NULL }; GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::ThrowOnFailure(false), false); } // Tests parsing a --gtest_throw_on_failure flag that has a "true" // definition. TEST_F(InitGoogleTestTest, ThrowOnFailureTrue) { const char* argv[] = { "foo.exe", "--gtest_throw_on_failure=1", NULL }; const char* argv2[] = { "foo.exe", NULL }; GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::ThrowOnFailure(true), false); } #if GTEST_OS_WINDOWS // Tests parsing wide strings. TEST_F(InitGoogleTestTest, WideStrings) { const wchar_t* argv[] = { L"foo.exe", L"--gtest_filter=Foo*", L"--gtest_list_tests=1", L"--gtest_break_on_failure", L"--non_gtest_flag", NULL }; const wchar_t* argv2[] = { L"foo.exe", L"--non_gtest_flag", NULL }; Flags expected_flags; expected_flags.break_on_failure = true; expected_flags.filter = "Foo*"; expected_flags.list_tests = true; GTEST_TEST_PARSING_FLAGS_(argv, argv2, expected_flags, false); } #endif // GTEST_OS_WINDOWS // Tests current_test_info() in UnitTest. class CurrentTestInfoTest : public Test { protected: // Tests that current_test_info() returns NULL before the first test in // the test case is run. static void SetUpTestCase() { // There should be no tests running at this point. const TestInfo* test_info = UnitTest::GetInstance()->current_test_info(); EXPECT_TRUE(test_info == NULL) << "There should be no tests running at this point."; } // Tests that current_test_info() returns NULL after the last test in // the test case has run. static void TearDownTestCase() { const TestInfo* test_info = UnitTest::GetInstance()->current_test_info(); EXPECT_TRUE(test_info == NULL) << "There should be no tests running at this point."; } }; // Tests that current_test_info() returns TestInfo for currently running // test by checking the expected test name against the actual one. TEST_F(CurrentTestInfoTest, WorksForFirstTestInATestCase) { const TestInfo* test_info = UnitTest::GetInstance()->current_test_info(); ASSERT_TRUE(NULL != test_info) << "There is a test running so we should have a valid TestInfo."; EXPECT_STREQ("CurrentTestInfoTest", test_info->test_case_name()) << "Expected the name of the currently running test case."; EXPECT_STREQ("WorksForFirstTestInATestCase", test_info->name()) << "Expected the name of the currently running test."; } // Tests that current_test_info() returns TestInfo for currently running // test by checking the expected test name against the actual one. We // use this test to see that the TestInfo object actually changed from // the previous invocation. TEST_F(CurrentTestInfoTest, WorksForSecondTestInATestCase) { const TestInfo* test_info = UnitTest::GetInstance()->current_test_info(); ASSERT_TRUE(NULL != test_info) << "There is a test running so we should have a valid TestInfo."; EXPECT_STREQ("CurrentTestInfoTest", test_info->test_case_name()) << "Expected the name of the currently running test case."; EXPECT_STREQ("WorksForSecondTestInATestCase", test_info->name()) << "Expected the name of the currently running test."; } } // namespace testing // These two lines test that we can define tests in a namespace that // has the name "testing" and is nested in another namespace. namespace my_namespace { namespace testing { // Makes sure that TEST knows to use ::testing::Test instead of // ::my_namespace::testing::Test. class Test {}; // Makes sure that an assertion knows to use ::testing::Message instead of // ::my_namespace::testing::Message. class Message {}; // Makes sure that an assertion knows to use // ::testing::AssertionResult instead of // ::my_namespace::testing::AssertionResult. class AssertionResult {}; // Tests that an assertion that should succeed works as expected. TEST(NestedTestingNamespaceTest, Success) { EXPECT_EQ(1, 1) << "This shouldn't fail."; } // Tests that an assertion that should fail works as expected. TEST(NestedTestingNamespaceTest, Failure) { EXPECT_FATAL_FAILURE(FAIL() << "This failure is expected.", "This failure is expected."); } } // namespace testing } // namespace my_namespace // Tests that one can call superclass SetUp and TearDown methods-- // that is, that they are not private. // No tests are based on this fixture; the test "passes" if it compiles // successfully. class ProtectedFixtureMethodsTest : public Test { protected: virtual void SetUp() { Test::SetUp(); } virtual void TearDown() { Test::TearDown(); } }; // StreamingAssertionsTest tests the streaming versions of a representative // sample of assertions. TEST(StreamingAssertionsTest, Unconditional) { SUCCEED() << "expected success"; EXPECT_NONFATAL_FAILURE(ADD_FAILURE() << "expected failure", "expected failure"); EXPECT_FATAL_FAILURE(FAIL() << "expected failure", "expected failure"); } #ifdef __BORLANDC__ // Silences warnings: "Condition is always true", "Unreachable code" # pragma option push -w-ccc -w-rch #endif TEST(StreamingAssertionsTest, Truth) { EXPECT_TRUE(true) << "unexpected failure"; ASSERT_TRUE(true) << "unexpected failure"; EXPECT_NONFATAL_FAILURE(EXPECT_TRUE(false) << "expected failure", "expected failure"); EXPECT_FATAL_FAILURE(ASSERT_TRUE(false) << "expected failure", "expected failure"); } TEST(StreamingAssertionsTest, Truth2) { EXPECT_FALSE(false) << "unexpected failure"; ASSERT_FALSE(false) << "unexpected failure"; EXPECT_NONFATAL_FAILURE(EXPECT_FALSE(true) << "expected failure", "expected failure"); EXPECT_FATAL_FAILURE(ASSERT_FALSE(true) << "expected failure", "expected failure"); } #ifdef __BORLANDC__ // Restores warnings after previous "#pragma option push" supressed them # pragma option pop #endif TEST(StreamingAssertionsTest, IntegerEquals) { EXPECT_EQ(1, 1) << "unexpected failure"; ASSERT_EQ(1, 1) << "unexpected failure"; EXPECT_NONFATAL_FAILURE(EXPECT_EQ(1, 2) << "expected failure", "expected failure"); EXPECT_FATAL_FAILURE(ASSERT_EQ(1, 2) << "expected failure", "expected failure"); } TEST(StreamingAssertionsTest, IntegerLessThan) { EXPECT_LT(1, 2) << "unexpected failure"; ASSERT_LT(1, 2) << "unexpected failure"; EXPECT_NONFATAL_FAILURE(EXPECT_LT(2, 1) << "expected failure", "expected failure"); EXPECT_FATAL_FAILURE(ASSERT_LT(2, 1) << "expected failure", "expected failure"); } TEST(StreamingAssertionsTest, StringsEqual) { EXPECT_STREQ("foo", "foo") << "unexpected failure"; ASSERT_STREQ("foo", "foo") << "unexpected failure"; EXPECT_NONFATAL_FAILURE(EXPECT_STREQ("foo", "bar") << "expected failure", "expected failure"); EXPECT_FATAL_FAILURE(ASSERT_STREQ("foo", "bar") << "expected failure", "expected failure"); } TEST(StreamingAssertionsTest, StringsNotEqual) { EXPECT_STRNE("foo", "bar") << "unexpected failure"; ASSERT_STRNE("foo", "bar") << "unexpected failure"; EXPECT_NONFATAL_FAILURE(EXPECT_STRNE("foo", "foo") << "expected failure", "expected failure"); EXPECT_FATAL_FAILURE(ASSERT_STRNE("foo", "foo") << "expected failure", "expected failure"); } TEST(StreamingAssertionsTest, StringsEqualIgnoringCase) { EXPECT_STRCASEEQ("foo", "FOO") << "unexpected failure"; ASSERT_STRCASEEQ("foo", "FOO") << "unexpected failure"; EXPECT_NONFATAL_FAILURE(EXPECT_STRCASEEQ("foo", "bar") << "expected failure", "expected failure"); EXPECT_FATAL_FAILURE(ASSERT_STRCASEEQ("foo", "bar") << "expected failure", "expected failure"); } TEST(StreamingAssertionsTest, StringNotEqualIgnoringCase) { EXPECT_STRCASENE("foo", "bar") << "unexpected failure"; ASSERT_STRCASENE("foo", "bar") << "unexpected failure"; EXPECT_NONFATAL_FAILURE(EXPECT_STRCASENE("foo", "FOO") << "expected failure", "expected failure"); EXPECT_FATAL_FAILURE(ASSERT_STRCASENE("bar", "BAR") << "expected failure", "expected failure"); } TEST(StreamingAssertionsTest, FloatingPointEquals) { EXPECT_FLOAT_EQ(1.0, 1.0) << "unexpected failure"; ASSERT_FLOAT_EQ(1.0, 1.0) << "unexpected failure"; EXPECT_NONFATAL_FAILURE(EXPECT_FLOAT_EQ(0.0, 1.0) << "expected failure", "expected failure"); EXPECT_FATAL_FAILURE(ASSERT_FLOAT_EQ(0.0, 1.0) << "expected failure", "expected failure"); } #if GTEST_HAS_EXCEPTIONS TEST(StreamingAssertionsTest, Throw) { EXPECT_THROW(ThrowAnInteger(), int) << "unexpected failure"; ASSERT_THROW(ThrowAnInteger(), int) << "unexpected failure"; EXPECT_NONFATAL_FAILURE(EXPECT_THROW(ThrowAnInteger(), bool) << "expected failure", "expected failure"); EXPECT_FATAL_FAILURE(ASSERT_THROW(ThrowAnInteger(), bool) << "expected failure", "expected failure"); } TEST(StreamingAssertionsTest, NoThrow) { EXPECT_NO_THROW(ThrowNothing()) << "unexpected failure"; ASSERT_NO_THROW(ThrowNothing()) << "unexpected failure"; EXPECT_NONFATAL_FAILURE(EXPECT_NO_THROW(ThrowAnInteger()) << "expected failure", "expected failure"); EXPECT_FATAL_FAILURE(ASSERT_NO_THROW(ThrowAnInteger()) << "expected failure", "expected failure"); } TEST(StreamingAssertionsTest, AnyThrow) { EXPECT_ANY_THROW(ThrowAnInteger()) << "unexpected failure"; ASSERT_ANY_THROW(ThrowAnInteger()) << "unexpected failure"; EXPECT_NONFATAL_FAILURE(EXPECT_ANY_THROW(ThrowNothing()) << "expected failure", "expected failure"); EXPECT_FATAL_FAILURE(ASSERT_ANY_THROW(ThrowNothing()) << "expected failure", "expected failure"); } #endif // GTEST_HAS_EXCEPTIONS // Tests that Google Test correctly decides whether to use colors in the output. TEST(ColoredOutputTest, UsesColorsWhenGTestColorFlagIsYes) { GTEST_FLAG(color) = "yes"; SetEnv("TERM", "xterm"); // TERM supports colors. EXPECT_TRUE(ShouldUseColor(true)); // Stdout is a TTY. EXPECT_TRUE(ShouldUseColor(false)); // Stdout is not a TTY. SetEnv("TERM", "dumb"); // TERM doesn't support colors. EXPECT_TRUE(ShouldUseColor(true)); // Stdout is a TTY. EXPECT_TRUE(ShouldUseColor(false)); // Stdout is not a TTY. } TEST(ColoredOutputTest, UsesColorsWhenGTestColorFlagIsAliasOfYes) { SetEnv("TERM", "dumb"); // TERM doesn't support colors. GTEST_FLAG(color) = "True"; EXPECT_TRUE(ShouldUseColor(false)); // Stdout is not a TTY. GTEST_FLAG(color) = "t"; EXPECT_TRUE(ShouldUseColor(false)); // Stdout is not a TTY. GTEST_FLAG(color) = "1"; EXPECT_TRUE(ShouldUseColor(false)); // Stdout is not a TTY. } TEST(ColoredOutputTest, UsesNoColorWhenGTestColorFlagIsNo) { GTEST_FLAG(color) = "no"; SetEnv("TERM", "xterm"); // TERM supports colors. EXPECT_FALSE(ShouldUseColor(true)); // Stdout is a TTY. EXPECT_FALSE(ShouldUseColor(false)); // Stdout is not a TTY. SetEnv("TERM", "dumb"); // TERM doesn't support colors. EXPECT_FALSE(ShouldUseColor(true)); // Stdout is a TTY. EXPECT_FALSE(ShouldUseColor(false)); // Stdout is not a TTY. } TEST(ColoredOutputTest, UsesNoColorWhenGTestColorFlagIsInvalid) { SetEnv("TERM", "xterm"); // TERM supports colors. GTEST_FLAG(color) = "F"; EXPECT_FALSE(ShouldUseColor(true)); // Stdout is a TTY. GTEST_FLAG(color) = "0"; EXPECT_FALSE(ShouldUseColor(true)); // Stdout is a TTY. GTEST_FLAG(color) = "unknown"; EXPECT_FALSE(ShouldUseColor(true)); // Stdout is a TTY. } TEST(ColoredOutputTest, UsesColorsWhenStdoutIsTty) { GTEST_FLAG(color) = "auto"; SetEnv("TERM", "xterm"); // TERM supports colors. EXPECT_FALSE(ShouldUseColor(false)); // Stdout is not a TTY. EXPECT_TRUE(ShouldUseColor(true)); // Stdout is a TTY. } TEST(ColoredOutputTest, UsesColorsWhenTermSupportsColors) { GTEST_FLAG(color) = "auto"; #if GTEST_OS_WINDOWS // On Windows, we ignore the TERM variable as it's usually not set. SetEnv("TERM", "dumb"); EXPECT_TRUE(ShouldUseColor(true)); // Stdout is a TTY. SetEnv("TERM", ""); EXPECT_TRUE(ShouldUseColor(true)); // Stdout is a TTY. SetEnv("TERM", "xterm"); EXPECT_TRUE(ShouldUseColor(true)); // Stdout is a TTY. #else // On non-Windows platforms, we rely on TERM to determine if the // terminal supports colors. SetEnv("TERM", "dumb"); // TERM doesn't support colors. EXPECT_FALSE(ShouldUseColor(true)); // Stdout is a TTY. SetEnv("TERM", "emacs"); // TERM doesn't support colors. EXPECT_FALSE(ShouldUseColor(true)); // Stdout is a TTY. SetEnv("TERM", "vt100"); // TERM doesn't support colors. EXPECT_FALSE(ShouldUseColor(true)); // Stdout is a TTY. SetEnv("TERM", "xterm-mono"); // TERM doesn't support colors. EXPECT_FALSE(ShouldUseColor(true)); // Stdout is a TTY. SetEnv("TERM", "xterm"); // TERM supports colors. EXPECT_TRUE(ShouldUseColor(true)); // Stdout is a TTY. SetEnv("TERM", "xterm-color"); // TERM supports colors. EXPECT_TRUE(ShouldUseColor(true)); // Stdout is a TTY. SetEnv("TERM", "xterm-256color"); // TERM supports colors. EXPECT_TRUE(ShouldUseColor(true)); // Stdout is a TTY. SetEnv("TERM", "screen"); // TERM supports colors. EXPECT_TRUE(ShouldUseColor(true)); // Stdout is a TTY. SetEnv("TERM", "screen-256color"); // TERM supports colors. EXPECT_TRUE(ShouldUseColor(true)); // Stdout is a TTY. SetEnv("TERM", "linux"); // TERM supports colors. EXPECT_TRUE(ShouldUseColor(true)); // Stdout is a TTY. SetEnv("TERM", "cygwin"); // TERM supports colors. EXPECT_TRUE(ShouldUseColor(true)); // Stdout is a TTY. #endif // GTEST_OS_WINDOWS } // Verifies that StaticAssertTypeEq works in a namespace scope. static bool dummy1 GTEST_ATTRIBUTE_UNUSED_ = StaticAssertTypeEq(); static bool dummy2 GTEST_ATTRIBUTE_UNUSED_ = StaticAssertTypeEq(); // Verifies that StaticAssertTypeEq works in a class. template class StaticAssertTypeEqTestHelper { public: StaticAssertTypeEqTestHelper() { StaticAssertTypeEq(); } }; TEST(StaticAssertTypeEqTest, WorksInClass) { StaticAssertTypeEqTestHelper(); } // Verifies that StaticAssertTypeEq works inside a function. typedef int IntAlias; TEST(StaticAssertTypeEqTest, CompilesForEqualTypes) { StaticAssertTypeEq(); StaticAssertTypeEq(); } TEST(GetCurrentOsStackTraceExceptTopTest, ReturnsTheStackTrace) { testing::UnitTest* const unit_test = testing::UnitTest::GetInstance(); // We don't have a stack walker in Google Test yet. EXPECT_STREQ("", GetCurrentOsStackTraceExceptTop(unit_test, 0).c_str()); EXPECT_STREQ("", GetCurrentOsStackTraceExceptTop(unit_test, 1).c_str()); } TEST(HasNonfatalFailureTest, ReturnsFalseWhenThereIsNoFailure) { EXPECT_FALSE(HasNonfatalFailure()); } static void FailFatally() { FAIL(); } TEST(HasNonfatalFailureTest, ReturnsFalseWhenThereIsOnlyFatalFailure) { FailFatally(); const bool has_nonfatal_failure = HasNonfatalFailure(); ClearCurrentTestPartResults(); EXPECT_FALSE(has_nonfatal_failure); } TEST(HasNonfatalFailureTest, ReturnsTrueWhenThereIsNonfatalFailure) { ADD_FAILURE(); const bool has_nonfatal_failure = HasNonfatalFailure(); ClearCurrentTestPartResults(); EXPECT_TRUE(has_nonfatal_failure); } TEST(HasNonfatalFailureTest, ReturnsTrueWhenThereAreFatalAndNonfatalFailures) { FailFatally(); ADD_FAILURE(); const bool has_nonfatal_failure = HasNonfatalFailure(); ClearCurrentTestPartResults(); EXPECT_TRUE(has_nonfatal_failure); } // A wrapper for calling HasNonfatalFailure outside of a test body. static bool HasNonfatalFailureHelper() { return testing::Test::HasNonfatalFailure(); } TEST(HasNonfatalFailureTest, WorksOutsideOfTestBody) { EXPECT_FALSE(HasNonfatalFailureHelper()); } TEST(HasNonfatalFailureTest, WorksOutsideOfTestBody2) { ADD_FAILURE(); const bool has_nonfatal_failure = HasNonfatalFailureHelper(); ClearCurrentTestPartResults(); EXPECT_TRUE(has_nonfatal_failure); } TEST(HasFailureTest, ReturnsFalseWhenThereIsNoFailure) { EXPECT_FALSE(HasFailure()); } TEST(HasFailureTest, ReturnsTrueWhenThereIsFatalFailure) { FailFatally(); const bool has_failure = HasFailure(); ClearCurrentTestPartResults(); EXPECT_TRUE(has_failure); } TEST(HasFailureTest, ReturnsTrueWhenThereIsNonfatalFailure) { ADD_FAILURE(); const bool has_failure = HasFailure(); ClearCurrentTestPartResults(); EXPECT_TRUE(has_failure); } TEST(HasFailureTest, ReturnsTrueWhenThereAreFatalAndNonfatalFailures) { FailFatally(); ADD_FAILURE(); const bool has_failure = HasFailure(); ClearCurrentTestPartResults(); EXPECT_TRUE(has_failure); } // A wrapper for calling HasFailure outside of a test body. static bool HasFailureHelper() { return testing::Test::HasFailure(); } TEST(HasFailureTest, WorksOutsideOfTestBody) { EXPECT_FALSE(HasFailureHelper()); } TEST(HasFailureTest, WorksOutsideOfTestBody2) { ADD_FAILURE(); const bool has_failure = HasFailureHelper(); ClearCurrentTestPartResults(); EXPECT_TRUE(has_failure); } class TestListener : public EmptyTestEventListener { public: TestListener() : on_start_counter_(NULL), is_destroyed_(NULL) {} TestListener(int* on_start_counter, bool* is_destroyed) : on_start_counter_(on_start_counter), is_destroyed_(is_destroyed) {} virtual ~TestListener() { if (is_destroyed_) *is_destroyed_ = true; } protected: virtual void OnTestProgramStart(const UnitTest& /*unit_test*/) { if (on_start_counter_ != NULL) (*on_start_counter_)++; } private: int* on_start_counter_; bool* is_destroyed_; }; // Tests the constructor. TEST(TestEventListenersTest, ConstructionWorks) { TestEventListeners listeners; EXPECT_TRUE(TestEventListenersAccessor::GetRepeater(&listeners) != NULL); EXPECT_TRUE(listeners.default_result_printer() == NULL); EXPECT_TRUE(listeners.default_xml_generator() == NULL); } // Tests that the TestEventListeners destructor deletes all the listeners it // owns. TEST(TestEventListenersTest, DestructionWorks) { bool default_result_printer_is_destroyed = false; bool default_xml_printer_is_destroyed = false; bool extra_listener_is_destroyed = false; TestListener* default_result_printer = new TestListener( NULL, &default_result_printer_is_destroyed); TestListener* default_xml_printer = new TestListener( NULL, &default_xml_printer_is_destroyed); TestListener* extra_listener = new TestListener( NULL, &extra_listener_is_destroyed); { TestEventListeners listeners; TestEventListenersAccessor::SetDefaultResultPrinter(&listeners, default_result_printer); TestEventListenersAccessor::SetDefaultXmlGenerator(&listeners, default_xml_printer); listeners.Append(extra_listener); } EXPECT_TRUE(default_result_printer_is_destroyed); EXPECT_TRUE(default_xml_printer_is_destroyed); EXPECT_TRUE(extra_listener_is_destroyed); } // Tests that a listener Append'ed to a TestEventListeners list starts // receiving events. TEST(TestEventListenersTest, Append) { int on_start_counter = 0; bool is_destroyed = false; TestListener* listener = new TestListener(&on_start_counter, &is_destroyed); { TestEventListeners listeners; listeners.Append(listener); TestEventListenersAccessor::GetRepeater(&listeners)->OnTestProgramStart( *UnitTest::GetInstance()); EXPECT_EQ(1, on_start_counter); } EXPECT_TRUE(is_destroyed); } // Tests that listeners receive events in the order they were appended to // the list, except for *End requests, which must be received in the reverse // order. class SequenceTestingListener : public EmptyTestEventListener { public: SequenceTestingListener(std::vector* vector, const char* id) : vector_(vector), id_(id) {} protected: virtual void OnTestProgramStart(const UnitTest& /*unit_test*/) { vector_->push_back(GetEventDescription("OnTestProgramStart")); } virtual void OnTestProgramEnd(const UnitTest& /*unit_test*/) { vector_->push_back(GetEventDescription("OnTestProgramEnd")); } virtual void OnTestIterationStart(const UnitTest& /*unit_test*/, int /*iteration*/) { vector_->push_back(GetEventDescription("OnTestIterationStart")); } virtual void OnTestIterationEnd(const UnitTest& /*unit_test*/, int /*iteration*/) { vector_->push_back(GetEventDescription("OnTestIterationEnd")); } private: std::string GetEventDescription(const char* method) { Message message; message << id_ << "." << method; return message.GetString(); } std::vector* vector_; const char* const id_; GTEST_DISALLOW_COPY_AND_ASSIGN_(SequenceTestingListener); }; TEST(EventListenerTest, AppendKeepsOrder) { std::vector vec; TestEventListeners listeners; listeners.Append(new SequenceTestingListener(&vec, "1st")); listeners.Append(new SequenceTestingListener(&vec, "2nd")); listeners.Append(new SequenceTestingListener(&vec, "3rd")); TestEventListenersAccessor::GetRepeater(&listeners)->OnTestProgramStart( *UnitTest::GetInstance()); ASSERT_EQ(3U, vec.size()); EXPECT_STREQ("1st.OnTestProgramStart", vec[0].c_str()); EXPECT_STREQ("2nd.OnTestProgramStart", vec[1].c_str()); EXPECT_STREQ("3rd.OnTestProgramStart", vec[2].c_str()); vec.clear(); TestEventListenersAccessor::GetRepeater(&listeners)->OnTestProgramEnd( *UnitTest::GetInstance()); ASSERT_EQ(3U, vec.size()); EXPECT_STREQ("3rd.OnTestProgramEnd", vec[0].c_str()); EXPECT_STREQ("2nd.OnTestProgramEnd", vec[1].c_str()); EXPECT_STREQ("1st.OnTestProgramEnd", vec[2].c_str()); vec.clear(); TestEventListenersAccessor::GetRepeater(&listeners)->OnTestIterationStart( *UnitTest::GetInstance(), 0); ASSERT_EQ(3U, vec.size()); EXPECT_STREQ("1st.OnTestIterationStart", vec[0].c_str()); EXPECT_STREQ("2nd.OnTestIterationStart", vec[1].c_str()); EXPECT_STREQ("3rd.OnTestIterationStart", vec[2].c_str()); vec.clear(); TestEventListenersAccessor::GetRepeater(&listeners)->OnTestIterationEnd( *UnitTest::GetInstance(), 0); ASSERT_EQ(3U, vec.size()); EXPECT_STREQ("3rd.OnTestIterationEnd", vec[0].c_str()); EXPECT_STREQ("2nd.OnTestIterationEnd", vec[1].c_str()); EXPECT_STREQ("1st.OnTestIterationEnd", vec[2].c_str()); } // Tests that a listener removed from a TestEventListeners list stops receiving // events and is not deleted when the list is destroyed. TEST(TestEventListenersTest, Release) { int on_start_counter = 0; bool is_destroyed = false; // Although Append passes the ownership of this object to the list, // the following calls release it, and we need to delete it before the // test ends. TestListener* listener = new TestListener(&on_start_counter, &is_destroyed); { TestEventListeners listeners; listeners.Append(listener); EXPECT_EQ(listener, listeners.Release(listener)); TestEventListenersAccessor::GetRepeater(&listeners)->OnTestProgramStart( *UnitTest::GetInstance()); EXPECT_TRUE(listeners.Release(listener) == NULL); } EXPECT_EQ(0, on_start_counter); EXPECT_FALSE(is_destroyed); delete listener; } // Tests that no events are forwarded when event forwarding is disabled. TEST(EventListenerTest, SuppressEventForwarding) { int on_start_counter = 0; TestListener* listener = new TestListener(&on_start_counter, NULL); TestEventListeners listeners; listeners.Append(listener); ASSERT_TRUE(TestEventListenersAccessor::EventForwardingEnabled(listeners)); TestEventListenersAccessor::SuppressEventForwarding(&listeners); ASSERT_FALSE(TestEventListenersAccessor::EventForwardingEnabled(listeners)); TestEventListenersAccessor::GetRepeater(&listeners)->OnTestProgramStart( *UnitTest::GetInstance()); EXPECT_EQ(0, on_start_counter); } // Tests that events generated by Google Test are not forwarded in // death test subprocesses. TEST(EventListenerDeathTest, EventsNotForwardedInDeathTestSubprecesses) { EXPECT_DEATH_IF_SUPPORTED({ GTEST_CHECK_(TestEventListenersAccessor::EventForwardingEnabled( *GetUnitTestImpl()->listeners())) << "expected failure";}, "expected failure"); } // Tests that a listener installed via SetDefaultResultPrinter() starts // receiving events and is returned via default_result_printer() and that // the previous default_result_printer is removed from the list and deleted. TEST(EventListenerTest, default_result_printer) { int on_start_counter = 0; bool is_destroyed = false; TestListener* listener = new TestListener(&on_start_counter, &is_destroyed); TestEventListeners listeners; TestEventListenersAccessor::SetDefaultResultPrinter(&listeners, listener); EXPECT_EQ(listener, listeners.default_result_printer()); TestEventListenersAccessor::GetRepeater(&listeners)->OnTestProgramStart( *UnitTest::GetInstance()); EXPECT_EQ(1, on_start_counter); // Replacing default_result_printer with something else should remove it // from the list and destroy it. TestEventListenersAccessor::SetDefaultResultPrinter(&listeners, NULL); EXPECT_TRUE(listeners.default_result_printer() == NULL); EXPECT_TRUE(is_destroyed); // After broadcasting an event the counter is still the same, indicating // the listener is not in the list anymore. TestEventListenersAccessor::GetRepeater(&listeners)->OnTestProgramStart( *UnitTest::GetInstance()); EXPECT_EQ(1, on_start_counter); } // Tests that the default_result_printer listener stops receiving events // when removed via Release and that is not owned by the list anymore. TEST(EventListenerTest, RemovingDefaultResultPrinterWorks) { int on_start_counter = 0; bool is_destroyed = false; // Although Append passes the ownership of this object to the list, // the following calls release it, and we need to delete it before the // test ends. TestListener* listener = new TestListener(&on_start_counter, &is_destroyed); { TestEventListeners listeners; TestEventListenersAccessor::SetDefaultResultPrinter(&listeners, listener); EXPECT_EQ(listener, listeners.Release(listener)); EXPECT_TRUE(listeners.default_result_printer() == NULL); EXPECT_FALSE(is_destroyed); // Broadcasting events now should not affect default_result_printer. TestEventListenersAccessor::GetRepeater(&listeners)->OnTestProgramStart( *UnitTest::GetInstance()); EXPECT_EQ(0, on_start_counter); } // Destroying the list should not affect the listener now, too. EXPECT_FALSE(is_destroyed); delete listener; } // Tests that a listener installed via SetDefaultXmlGenerator() starts // receiving events and is returned via default_xml_generator() and that // the previous default_xml_generator is removed from the list and deleted. TEST(EventListenerTest, default_xml_generator) { int on_start_counter = 0; bool is_destroyed = false; TestListener* listener = new TestListener(&on_start_counter, &is_destroyed); TestEventListeners listeners; TestEventListenersAccessor::SetDefaultXmlGenerator(&listeners, listener); EXPECT_EQ(listener, listeners.default_xml_generator()); TestEventListenersAccessor::GetRepeater(&listeners)->OnTestProgramStart( *UnitTest::GetInstance()); EXPECT_EQ(1, on_start_counter); // Replacing default_xml_generator with something else should remove it // from the list and destroy it. TestEventListenersAccessor::SetDefaultXmlGenerator(&listeners, NULL); EXPECT_TRUE(listeners.default_xml_generator() == NULL); EXPECT_TRUE(is_destroyed); // After broadcasting an event the counter is still the same, indicating // the listener is not in the list anymore. TestEventListenersAccessor::GetRepeater(&listeners)->OnTestProgramStart( *UnitTest::GetInstance()); EXPECT_EQ(1, on_start_counter); } // Tests that the default_xml_generator listener stops receiving events // when removed via Release and that is not owned by the list anymore. TEST(EventListenerTest, RemovingDefaultXmlGeneratorWorks) { int on_start_counter = 0; bool is_destroyed = false; // Although Append passes the ownership of this object to the list, // the following calls release it, and we need to delete it before the // test ends. TestListener* listener = new TestListener(&on_start_counter, &is_destroyed); { TestEventListeners listeners; TestEventListenersAccessor::SetDefaultXmlGenerator(&listeners, listener); EXPECT_EQ(listener, listeners.Release(listener)); EXPECT_TRUE(listeners.default_xml_generator() == NULL); EXPECT_FALSE(is_destroyed); // Broadcasting events now should not affect default_xml_generator. TestEventListenersAccessor::GetRepeater(&listeners)->OnTestProgramStart( *UnitTest::GetInstance()); EXPECT_EQ(0, on_start_counter); } // Destroying the list should not affect the listener now, too. EXPECT_FALSE(is_destroyed); delete listener; } // Sanity tests to ensure that the alternative, verbose spellings of // some of the macros work. We don't test them thoroughly as that // would be quite involved. Since their implementations are // straightforward, and they are rarely used, we'll just rely on the // users to tell us when they are broken. GTEST_TEST(AlternativeNameTest, Works) { // GTEST_TEST is the same as TEST. GTEST_SUCCEED() << "OK"; // GTEST_SUCCEED is the same as SUCCEED. // GTEST_FAIL is the same as FAIL. EXPECT_FATAL_FAILURE(GTEST_FAIL() << "An expected failure", "An expected failure"); // GTEST_ASSERT_XY is the same as ASSERT_XY. GTEST_ASSERT_EQ(0, 0); EXPECT_FATAL_FAILURE(GTEST_ASSERT_EQ(0, 1) << "An expected failure", "An expected failure"); EXPECT_FATAL_FAILURE(GTEST_ASSERT_EQ(1, 0) << "An expected failure", "An expected failure"); GTEST_ASSERT_NE(0, 1); GTEST_ASSERT_NE(1, 0); EXPECT_FATAL_FAILURE(GTEST_ASSERT_NE(0, 0) << "An expected failure", "An expected failure"); GTEST_ASSERT_LE(0, 0); GTEST_ASSERT_LE(0, 1); EXPECT_FATAL_FAILURE(GTEST_ASSERT_LE(1, 0) << "An expected failure", "An expected failure"); GTEST_ASSERT_LT(0, 1); EXPECT_FATAL_FAILURE(GTEST_ASSERT_LT(0, 0) << "An expected failure", "An expected failure"); EXPECT_FATAL_FAILURE(GTEST_ASSERT_LT(1, 0) << "An expected failure", "An expected failure"); GTEST_ASSERT_GE(0, 0); GTEST_ASSERT_GE(1, 0); EXPECT_FATAL_FAILURE(GTEST_ASSERT_GE(0, 1) << "An expected failure", "An expected failure"); GTEST_ASSERT_GT(1, 0); EXPECT_FATAL_FAILURE(GTEST_ASSERT_GT(0, 1) << "An expected failure", "An expected failure"); EXPECT_FATAL_FAILURE(GTEST_ASSERT_GT(1, 1) << "An expected failure", "An expected failure"); } // Tests for internal utilities necessary for implementation of the universal // printing. // TODO(vladl@google.com): Find a better home for them. class ConversionHelperBase {}; class ConversionHelperDerived : public ConversionHelperBase {}; // Tests that IsAProtocolMessage::value is a compile-time constant. TEST(IsAProtocolMessageTest, ValueIsCompileTimeConstant) { GTEST_COMPILE_ASSERT_(IsAProtocolMessage::value, const_true); GTEST_COMPILE_ASSERT_(!IsAProtocolMessage::value, const_false); } // Tests that IsAProtocolMessage::value is true when T is // proto2::Message or a sub-class of it. TEST(IsAProtocolMessageTest, ValueIsTrueWhenTypeIsAProtocolMessage) { EXPECT_TRUE(IsAProtocolMessage< ::proto2::Message>::value); EXPECT_TRUE(IsAProtocolMessage::value); } // Tests that IsAProtocolMessage::value is false when T is neither // ProtocolMessage nor a sub-class of it. TEST(IsAProtocolMessageTest, ValueIsFalseWhenTypeIsNotAProtocolMessage) { EXPECT_FALSE(IsAProtocolMessage::value); EXPECT_FALSE(IsAProtocolMessage::value); } // Tests that CompileAssertTypesEqual compiles when the type arguments are // equal. TEST(CompileAssertTypesEqual, CompilesWhenTypesAreEqual) { CompileAssertTypesEqual(); CompileAssertTypesEqual(); } // Tests that RemoveReference does not affect non-reference types. TEST(RemoveReferenceTest, DoesNotAffectNonReferenceType) { CompileAssertTypesEqual::type>(); CompileAssertTypesEqual::type>(); } // Tests that RemoveReference removes reference from reference types. TEST(RemoveReferenceTest, RemovesReference) { CompileAssertTypesEqual::type>(); CompileAssertTypesEqual::type>(); } // Tests GTEST_REMOVE_REFERENCE_. template void TestGTestRemoveReference() { CompileAssertTypesEqual(); } TEST(RemoveReferenceTest, MacroVersion) { TestGTestRemoveReference(); TestGTestRemoveReference(); } // Tests that RemoveConst does not affect non-const types. TEST(RemoveConstTest, DoesNotAffectNonConstType) { CompileAssertTypesEqual::type>(); CompileAssertTypesEqual::type>(); } // Tests that RemoveConst removes const from const types. TEST(RemoveConstTest, RemovesConst) { CompileAssertTypesEqual::type>(); CompileAssertTypesEqual::type>(); CompileAssertTypesEqual::type>(); } // Tests GTEST_REMOVE_CONST_. template void TestGTestRemoveConst() { CompileAssertTypesEqual(); } TEST(RemoveConstTest, MacroVersion) { TestGTestRemoveConst(); TestGTestRemoveConst(); TestGTestRemoveConst(); } // Tests GTEST_REMOVE_REFERENCE_AND_CONST_. template void TestGTestRemoveReferenceAndConst() { CompileAssertTypesEqual(); } TEST(RemoveReferenceToConstTest, Works) { TestGTestRemoveReferenceAndConst(); TestGTestRemoveReferenceAndConst(); TestGTestRemoveReferenceAndConst(); TestGTestRemoveReferenceAndConst(); TestGTestRemoveReferenceAndConst(); } // Tests that AddReference does not affect reference types. TEST(AddReferenceTest, DoesNotAffectReferenceType) { CompileAssertTypesEqual::type>(); CompileAssertTypesEqual::type>(); } // Tests that AddReference adds reference to non-reference types. TEST(AddReferenceTest, AddsReference) { CompileAssertTypesEqual::type>(); CompileAssertTypesEqual::type>(); } // Tests GTEST_ADD_REFERENCE_. template void TestGTestAddReference() { CompileAssertTypesEqual(); } TEST(AddReferenceTest, MacroVersion) { TestGTestAddReference(); TestGTestAddReference(); } // Tests GTEST_REFERENCE_TO_CONST_. template void TestGTestReferenceToConst() { CompileAssertTypesEqual(); } TEST(GTestReferenceToConstTest, Works) { TestGTestReferenceToConst(); TestGTestReferenceToConst(); TestGTestReferenceToConst(); TestGTestReferenceToConst(); } // Tests that ImplicitlyConvertible::value is a compile-time constant. TEST(ImplicitlyConvertibleTest, ValueIsCompileTimeConstant) { GTEST_COMPILE_ASSERT_((ImplicitlyConvertible::value), const_true); GTEST_COMPILE_ASSERT_((!ImplicitlyConvertible::value), const_false); } // Tests that ImplicitlyConvertible::value is true when T1 can // be implicitly converted to T2. TEST(ImplicitlyConvertibleTest, ValueIsTrueWhenConvertible) { EXPECT_TRUE((ImplicitlyConvertible::value)); EXPECT_TRUE((ImplicitlyConvertible::value)); EXPECT_TRUE((ImplicitlyConvertible::value)); EXPECT_TRUE((ImplicitlyConvertible::value)); EXPECT_TRUE((ImplicitlyConvertible::value)); EXPECT_TRUE((ImplicitlyConvertible::value)); } // Tests that ImplicitlyConvertible::value is false when T1 // cannot be implicitly converted to T2. TEST(ImplicitlyConvertibleTest, ValueIsFalseWhenNotConvertible) { EXPECT_FALSE((ImplicitlyConvertible::value)); EXPECT_FALSE((ImplicitlyConvertible::value)); EXPECT_FALSE((ImplicitlyConvertible::value)); EXPECT_FALSE((ImplicitlyConvertible::value)); } // Tests IsContainerTest. class NonContainer {}; TEST(IsContainerTestTest, WorksForNonContainer) { EXPECT_EQ(sizeof(IsNotContainer), sizeof(IsContainerTest(0))); EXPECT_EQ(sizeof(IsNotContainer), sizeof(IsContainerTest(0))); EXPECT_EQ(sizeof(IsNotContainer), sizeof(IsContainerTest(0))); } TEST(IsContainerTestTest, WorksForContainer) { EXPECT_EQ(sizeof(IsContainer), sizeof(IsContainerTest >(0))); EXPECT_EQ(sizeof(IsContainer), sizeof(IsContainerTest >(0))); } // Tests ArrayEq(). TEST(ArrayEqTest, WorksForDegeneratedArrays) { EXPECT_TRUE(ArrayEq(5, 5L)); EXPECT_FALSE(ArrayEq('a', 0)); } TEST(ArrayEqTest, WorksForOneDimensionalArrays) { // Note that a and b are distinct but compatible types. const int a[] = { 0, 1 }; long b[] = { 0, 1 }; EXPECT_TRUE(ArrayEq(a, b)); EXPECT_TRUE(ArrayEq(a, 2, b)); b[0] = 2; EXPECT_FALSE(ArrayEq(a, b)); EXPECT_FALSE(ArrayEq(a, 1, b)); } TEST(ArrayEqTest, WorksForTwoDimensionalArrays) { const char a[][3] = { "hi", "lo" }; const char b[][3] = { "hi", "lo" }; const char c[][3] = { "hi", "li" }; EXPECT_TRUE(ArrayEq(a, b)); EXPECT_TRUE(ArrayEq(a, 2, b)); EXPECT_FALSE(ArrayEq(a, c)); EXPECT_FALSE(ArrayEq(a, 2, c)); } // Tests ArrayAwareFind(). TEST(ArrayAwareFindTest, WorksForOneDimensionalArray) { const char a[] = "hello"; EXPECT_EQ(a + 4, ArrayAwareFind(a, a + 5, 'o')); EXPECT_EQ(a + 5, ArrayAwareFind(a, a + 5, 'x')); } TEST(ArrayAwareFindTest, WorksForTwoDimensionalArray) { int a[][2] = { { 0, 1 }, { 2, 3 }, { 4, 5 } }; const int b[2] = { 2, 3 }; EXPECT_EQ(a + 1, ArrayAwareFind(a, a + 3, b)); const int c[2] = { 6, 7 }; EXPECT_EQ(a + 3, ArrayAwareFind(a, a + 3, c)); } // Tests CopyArray(). TEST(CopyArrayTest, WorksForDegeneratedArrays) { int n = 0; CopyArray('a', &n); EXPECT_EQ('a', n); } TEST(CopyArrayTest, WorksForOneDimensionalArrays) { const char a[3] = "hi"; int b[3]; #ifndef __BORLANDC__ // C++Builder cannot compile some array size deductions. CopyArray(a, &b); EXPECT_TRUE(ArrayEq(a, b)); #endif int c[3]; CopyArray(a, 3, c); EXPECT_TRUE(ArrayEq(a, c)); } TEST(CopyArrayTest, WorksForTwoDimensionalArrays) { const int a[2][3] = { { 0, 1, 2 }, { 3, 4, 5 } }; int b[2][3]; #ifndef __BORLANDC__ // C++Builder cannot compile some array size deductions. CopyArray(a, &b); EXPECT_TRUE(ArrayEq(a, b)); #endif int c[2][3]; CopyArray(a, 2, c); EXPECT_TRUE(ArrayEq(a, c)); } // Tests NativeArray. TEST(NativeArrayTest, ConstructorFromArrayWorks) { const int a[3] = { 0, 1, 2 }; NativeArray na(a, 3, kReference); EXPECT_EQ(3U, na.size()); EXPECT_EQ(a, na.begin()); } TEST(NativeArrayTest, CreatesAndDeletesCopyOfArrayWhenAskedTo) { typedef int Array[2]; Array* a = new Array[1]; (*a)[0] = 0; (*a)[1] = 1; NativeArray na(*a, 2, kCopy); EXPECT_NE(*a, na.begin()); delete[] a; EXPECT_EQ(0, na.begin()[0]); EXPECT_EQ(1, na.begin()[1]); // We rely on the heap checker to verify that na deletes the copy of // array. } TEST(NativeArrayTest, TypeMembersAreCorrect) { StaticAssertTypeEq::value_type>(); StaticAssertTypeEq::value_type>(); StaticAssertTypeEq::const_iterator>(); StaticAssertTypeEq::const_iterator>(); } TEST(NativeArrayTest, MethodsWork) { const int a[3] = { 0, 1, 2 }; NativeArray na(a, 3, kCopy); ASSERT_EQ(3U, na.size()); EXPECT_EQ(3, na.end() - na.begin()); NativeArray::const_iterator it = na.begin(); EXPECT_EQ(0, *it); ++it; EXPECT_EQ(1, *it); it++; EXPECT_EQ(2, *it); ++it; EXPECT_EQ(na.end(), it); EXPECT_TRUE(na == na); NativeArray na2(a, 3, kReference); EXPECT_TRUE(na == na2); const int b1[3] = { 0, 1, 1 }; const int b2[4] = { 0, 1, 2, 3 }; EXPECT_FALSE(na == NativeArray(b1, 3, kReference)); EXPECT_FALSE(na == NativeArray(b2, 4, kCopy)); } TEST(NativeArrayTest, WorksForTwoDimensionalArray) { const char a[2][3] = { "hi", "lo" }; NativeArray na(a, 2, kReference); ASSERT_EQ(2U, na.size()); EXPECT_EQ(a, na.begin()); } // Tests SkipPrefix(). TEST(SkipPrefixTest, SkipsWhenPrefixMatches) { const char* const str = "hello"; const char* p = str; EXPECT_TRUE(SkipPrefix("", &p)); EXPECT_EQ(str, p); p = str; EXPECT_TRUE(SkipPrefix("hell", &p)); EXPECT_EQ(str + 4, p); } TEST(SkipPrefixTest, DoesNotSkipWhenPrefixDoesNotMatch) { const char* const str = "world"; const char* p = str; EXPECT_FALSE(SkipPrefix("W", &p)); EXPECT_EQ(str, p); p = str; EXPECT_FALSE(SkipPrefix("world!", &p)); EXPECT_EQ(str, p); } dlt-daemon-2.18.4/gtest-1.7.0/test/gtest_xml_outfile1_test_.cc000066400000000000000000000037331353342203500237310ustar00rootroot00000000000000// Copyright 2008, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: keith.ray@gmail.com (Keith Ray) // // gtest_xml_outfile1_test_ writes some xml via TestProperty used by // gtest_xml_outfiles_test.py #include "gtest/gtest.h" class PropertyOne : public testing::Test { protected: virtual void SetUp() { RecordProperty("SetUpProp", 1); } virtual void TearDown() { RecordProperty("TearDownProp", 1); } }; TEST_F(PropertyOne, TestSomeProperties) { RecordProperty("TestSomeProperty", 1); } dlt-daemon-2.18.4/gtest-1.7.0/test/gtest_xml_outfile2_test_.cc000066400000000000000000000037331353342203500237320ustar00rootroot00000000000000// Copyright 2008, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: keith.ray@gmail.com (Keith Ray) // // gtest_xml_outfile2_test_ writes some xml via TestProperty used by // gtest_xml_outfiles_test.py #include "gtest/gtest.h" class PropertyTwo : public testing::Test { protected: virtual void SetUp() { RecordProperty("SetUpProp", 2); } virtual void TearDown() { RecordProperty("TearDownProp", 2); } }; TEST_F(PropertyTwo, TestSomeProperties) { RecordProperty("TestSomeProperty", 2); } dlt-daemon-2.18.4/gtest-1.7.0/test/gtest_xml_outfiles_test.py000077500000000000000000000123341353342203500237370ustar00rootroot00000000000000#!/usr/bin/env python # # 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. """Unit test for the gtest_xml_output module.""" __author__ = "keith.ray@gmail.com (Keith Ray)" import os from xml.dom import minidom, Node import gtest_test_utils import gtest_xml_test_utils GTEST_OUTPUT_SUBDIR = "xml_outfiles" GTEST_OUTPUT_1_TEST = "gtest_xml_outfile1_test_" GTEST_OUTPUT_2_TEST = "gtest_xml_outfile2_test_" EXPECTED_XML_1 = """ """ EXPECTED_XML_2 = """ """ class GTestXMLOutFilesTest(gtest_xml_test_utils.GTestXMLTestCase): """Unit test for Google Test's XML output functionality.""" def setUp(self): # We want the trailing '/' that the last "" provides in os.path.join, for # telling Google Test to create an output directory instead of a single file # for xml output. self.output_dir_ = os.path.join(gtest_test_utils.GetTempDir(), GTEST_OUTPUT_SUBDIR, "") self.DeleteFilesAndDir() def tearDown(self): self.DeleteFilesAndDir() def DeleteFilesAndDir(self): try: os.remove(os.path.join(self.output_dir_, GTEST_OUTPUT_1_TEST + ".xml")) except os.error: pass try: os.remove(os.path.join(self.output_dir_, GTEST_OUTPUT_2_TEST + ".xml")) except os.error: pass try: os.rmdir(self.output_dir_) except os.error: pass def testOutfile1(self): self._TestOutFile(GTEST_OUTPUT_1_TEST, EXPECTED_XML_1) def testOutfile2(self): self._TestOutFile(GTEST_OUTPUT_2_TEST, EXPECTED_XML_2) def _TestOutFile(self, test_name, expected_xml): gtest_prog_path = gtest_test_utils.GetTestExecutablePath(test_name) command = [gtest_prog_path, "--gtest_output=xml:%s" % self.output_dir_] p = gtest_test_utils.Subprocess(command, working_dir=gtest_test_utils.GetTempDir()) self.assert_(p.exited) self.assertEquals(0, p.exit_code) # TODO(wan@google.com): libtool causes the built test binary to be # named lt-gtest_xml_outfiles_test_ instead of # gtest_xml_outfiles_test_. To account for this possibillity, we # allow both names in the following code. We should remove this # hack when Chandler Carruth's libtool replacement tool is ready. output_file_name1 = test_name + ".xml" output_file1 = os.path.join(self.output_dir_, output_file_name1) output_file_name2 = 'lt-' + output_file_name1 output_file2 = os.path.join(self.output_dir_, output_file_name2) self.assert_(os.path.isfile(output_file1) or os.path.isfile(output_file2), output_file1) expected = minidom.parseString(expected_xml) if os.path.isfile(output_file1): actual = minidom.parse(output_file1) else: actual = minidom.parse(output_file2) self.NormalizeXml(actual.documentElement) self.AssertEquivalentNodes(expected.documentElement, actual.documentElement) expected.unlink() actual.unlink() if __name__ == "__main__": os.environ["GTEST_STACK_TRACE_DEPTH"] = "0" gtest_test_utils.Main() dlt-daemon-2.18.4/gtest-1.7.0/test/gtest_xml_output_unittest.py000077500000000000000000000343641353342203500243540ustar00rootroot00000000000000#!/usr/bin/env python # # Copyright 2006, Google Inc. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above # copyright notice, this list of conditions and the following disclaimer # in the documentation and/or other materials provided with the # distribution. # * Neither the name of Google Inc. nor the names of its # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. """Unit test for the gtest_xml_output module""" __author__ = 'eefacm@gmail.com (Sean Mcafee)' import datetime import errno import os import re import sys from xml.dom import minidom, Node import gtest_test_utils import gtest_xml_test_utils GTEST_FILTER_FLAG = '--gtest_filter' GTEST_LIST_TESTS_FLAG = '--gtest_list_tests' GTEST_OUTPUT_FLAG = "--gtest_output" GTEST_DEFAULT_OUTPUT_FILE = "test_detail.xml" GTEST_PROGRAM_NAME = "gtest_xml_output_unittest_" SUPPORTS_STACK_TRACES = False if SUPPORTS_STACK_TRACES: STACK_TRACE_TEMPLATE = '\nStack trace:\n*' else: STACK_TRACE_TEMPLATE = '' EXPECTED_NON_EMPTY_XML = """ ]]>%(stack)s]]> """ % {'stack': STACK_TRACE_TEMPLATE} EXPECTED_FILTERED_TEST_XML = """ """ EXPECTED_EMPTY_XML = """ """ GTEST_PROGRAM_PATH = gtest_test_utils.GetTestExecutablePath(GTEST_PROGRAM_NAME) SUPPORTS_TYPED_TESTS = 'TypedTest' in gtest_test_utils.Subprocess( [GTEST_PROGRAM_PATH, GTEST_LIST_TESTS_FLAG], capture_stderr=False).output class GTestXMLOutputUnitTest(gtest_xml_test_utils.GTestXMLTestCase): """ Unit test for Google Test's XML output functionality. """ # This test currently breaks on platforms that do not support typed and # type-parameterized tests, so we don't run it under them. if SUPPORTS_TYPED_TESTS: def testNonEmptyXmlOutput(self): """ Runs a test program that generates a non-empty XML output, and tests that the XML output is expected. """ self._TestXmlOutput(GTEST_PROGRAM_NAME, EXPECTED_NON_EMPTY_XML, 1) def testEmptyXmlOutput(self): """Verifies XML output for a Google Test binary without actual tests. Runs a test program that generates an empty XML output, and tests that the XML output is expected. """ self._TestXmlOutput('gtest_no_test_unittest', EXPECTED_EMPTY_XML, 0) def testTimestampValue(self): """Checks whether the timestamp attribute in the XML output is valid. Runs a test program that generates an empty XML output, and checks if the timestamp attribute in the testsuites tag is valid. """ actual = self._GetXmlOutput('gtest_no_test_unittest', [], 0) date_time_str = actual.documentElement.getAttributeNode('timestamp').value # datetime.strptime() is only available in Python 2.5+ so we have to # parse the expected datetime manually. match = re.match(r'(\d+)-(\d\d)-(\d\d)T(\d\d):(\d\d):(\d\d)', date_time_str) self.assertTrue( re.match, 'XML datettime string %s has incorrect format' % date_time_str) date_time_from_xml = datetime.datetime( year=int(match.group(1)), month=int(match.group(2)), day=int(match.group(3)), hour=int(match.group(4)), minute=int(match.group(5)), second=int(match.group(6))) time_delta = abs(datetime.datetime.now() - date_time_from_xml) # timestamp value should be near the current local time self.assertTrue(time_delta < datetime.timedelta(seconds=600), 'time_delta is %s' % time_delta) actual.unlink() def testDefaultOutputFile(self): """ Confirms that Google Test produces an XML output file with the expected default name if no name is explicitly specified. """ output_file = os.path.join(gtest_test_utils.GetTempDir(), GTEST_DEFAULT_OUTPUT_FILE) gtest_prog_path = gtest_test_utils.GetTestExecutablePath( 'gtest_no_test_unittest') try: os.remove(output_file) except OSError, e: if e.errno != errno.ENOENT: raise p = gtest_test_utils.Subprocess( [gtest_prog_path, '%s=xml' % GTEST_OUTPUT_FLAG], working_dir=gtest_test_utils.GetTempDir()) self.assert_(p.exited) self.assertEquals(0, p.exit_code) self.assert_(os.path.isfile(output_file)) def testSuppressedXmlOutput(self): """ Tests that no XML file is generated if the default XML listener is shut down before RUN_ALL_TESTS is invoked. """ xml_path = os.path.join(gtest_test_utils.GetTempDir(), GTEST_PROGRAM_NAME + 'out.xml') if os.path.isfile(xml_path): os.remove(xml_path) command = [GTEST_PROGRAM_PATH, '%s=xml:%s' % (GTEST_OUTPUT_FLAG, xml_path), '--shut_down_xml'] p = gtest_test_utils.Subprocess(command) if p.terminated_by_signal: # p.signal is avalable only if p.terminated_by_signal is True. self.assertFalse( p.terminated_by_signal, '%s was killed by signal %d' % (GTEST_PROGRAM_NAME, p.signal)) else: self.assert_(p.exited) self.assertEquals(1, p.exit_code, "'%s' exited with code %s, which doesn't match " 'the expected exit code %s.' % (command, p.exit_code, 1)) self.assert_(not os.path.isfile(xml_path)) def testFilteredTestXmlOutput(self): """Verifies XML output when a filter is applied. Runs a test program that executes only some tests and verifies that non-selected tests do not show up in the XML output. """ self._TestXmlOutput(GTEST_PROGRAM_NAME, EXPECTED_FILTERED_TEST_XML, 0, extra_args=['%s=SuccessfulTest.*' % GTEST_FILTER_FLAG]) def _GetXmlOutput(self, gtest_prog_name, extra_args, expected_exit_code): """ Returns the xml output generated by running the program gtest_prog_name. Furthermore, the program's exit code must be expected_exit_code. """ xml_path = os.path.join(gtest_test_utils.GetTempDir(), gtest_prog_name + 'out.xml') gtest_prog_path = gtest_test_utils.GetTestExecutablePath(gtest_prog_name) command = ([gtest_prog_path, '%s=xml:%s' % (GTEST_OUTPUT_FLAG, xml_path)] + extra_args) p = gtest_test_utils.Subprocess(command) if p.terminated_by_signal: self.assert_(False, '%s was killed by signal %d' % (gtest_prog_name, p.signal)) else: self.assert_(p.exited) self.assertEquals(expected_exit_code, p.exit_code, "'%s' exited with code %s, which doesn't match " 'the expected exit code %s.' % (command, p.exit_code, expected_exit_code)) actual = minidom.parse(xml_path) return actual def _TestXmlOutput(self, gtest_prog_name, expected_xml, expected_exit_code, extra_args=None): """ Asserts that the XML document generated by running the program gtest_prog_name matches expected_xml, a string containing another XML document. Furthermore, the program's exit code must be expected_exit_code. """ actual = self._GetXmlOutput(gtest_prog_name, extra_args or [], expected_exit_code) expected = minidom.parseString(expected_xml) self.NormalizeXml(actual.documentElement) self.AssertEquivalentNodes(expected.documentElement, actual.documentElement) expected.unlink() actual.unlink() if __name__ == '__main__': os.environ['GTEST_STACK_TRACE_DEPTH'] = '1' gtest_test_utils.Main() dlt-daemon-2.18.4/gtest-1.7.0/test/gtest_xml_output_unittest_.cc000066400000000000000000000137771353342203500244520ustar00rootroot00000000000000// Copyright 2006, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // Author: eefacm@gmail.com (Sean Mcafee) // Unit test for Google Test XML output. // // A user can specify XML output in a Google Test program to run via // either the GTEST_OUTPUT environment variable or the --gtest_output // flag. This is used for testing such functionality. // // This program will be invoked from a Python unit test. Don't run it // directly. #include "gtest/gtest.h" using ::testing::InitGoogleTest; using ::testing::TestEventListeners; using ::testing::TestWithParam; using ::testing::UnitTest; using ::testing::Test; using ::testing::Values; class SuccessfulTest : public Test { }; TEST_F(SuccessfulTest, Succeeds) { SUCCEED() << "This is a success."; ASSERT_EQ(1, 1); } class FailedTest : public Test { }; TEST_F(FailedTest, Fails) { ASSERT_EQ(1, 2); } class DisabledTest : public Test { }; TEST_F(DisabledTest, DISABLED_test_not_run) { FAIL() << "Unexpected failure: Disabled test should not be run"; } TEST(MixedResultTest, Succeeds) { EXPECT_EQ(1, 1); ASSERT_EQ(1, 1); } TEST(MixedResultTest, Fails) { EXPECT_EQ(1, 2); ASSERT_EQ(2, 3); } TEST(MixedResultTest, DISABLED_test) { FAIL() << "Unexpected failure: Disabled test should not be run"; } TEST(XmlQuotingTest, OutputsCData) { FAIL() << "XML output: " ""; } // Helps to test that invalid characters produced by test code do not make // it into the XML file. TEST(InvalidCharactersTest, InvalidCharactersInMessage) { FAIL() << "Invalid characters in brackets [\x1\x2]"; } class PropertyRecordingTest : public Test { public: static void SetUpTestCase() { RecordProperty("SetUpTestCase", "yes"); } static void TearDownTestCase() { RecordProperty("TearDownTestCase", "aye"); } }; TEST_F(PropertyRecordingTest, OneProperty) { RecordProperty("key_1", "1"); } TEST_F(PropertyRecordingTest, IntValuedProperty) { RecordProperty("key_int", 1); } TEST_F(PropertyRecordingTest, ThreeProperties) { RecordProperty("key_1", "1"); RecordProperty("key_2", "2"); RecordProperty("key_3", "3"); } TEST_F(PropertyRecordingTest, TwoValuesForOneKeyUsesLastValue) { RecordProperty("key_1", "1"); RecordProperty("key_1", "2"); } TEST(NoFixtureTest, RecordProperty) { RecordProperty("key", "1"); } void ExternalUtilityThatCallsRecordProperty(const std::string& key, int value) { testing::Test::RecordProperty(key, value); } void ExternalUtilityThatCallsRecordProperty(const std::string& key, const std::string& value) { testing::Test::RecordProperty(key, value); } TEST(NoFixtureTest, ExternalUtilityThatCallsRecordIntValuedProperty) { ExternalUtilityThatCallsRecordProperty("key_for_utility_int", 1); } TEST(NoFixtureTest, ExternalUtilityThatCallsRecordStringValuedProperty) { ExternalUtilityThatCallsRecordProperty("key_for_utility_string", "1"); } // Verifies that the test parameter value is output in the 'value_param' // XML attribute for value-parameterized tests. class ValueParamTest : public TestWithParam {}; TEST_P(ValueParamTest, HasValueParamAttribute) {} TEST_P(ValueParamTest, AnotherTestThatHasValueParamAttribute) {} INSTANTIATE_TEST_CASE_P(Single, ValueParamTest, Values(33, 42)); #if GTEST_HAS_TYPED_TEST // Verifies that the type parameter name is output in the 'type_param' // XML attribute for typed tests. template class TypedTest : public Test {}; typedef testing::Types TypedTestTypes; TYPED_TEST_CASE(TypedTest, TypedTestTypes); TYPED_TEST(TypedTest, HasTypeParamAttribute) {} #endif #if GTEST_HAS_TYPED_TEST_P // Verifies that the type parameter name is output in the 'type_param' // XML attribute for type-parameterized tests. template class TypeParameterizedTestCase : public Test {}; TYPED_TEST_CASE_P(TypeParameterizedTestCase); TYPED_TEST_P(TypeParameterizedTestCase, HasTypeParamAttribute) {} REGISTER_TYPED_TEST_CASE_P(TypeParameterizedTestCase, HasTypeParamAttribute); typedef testing::Types TypeParameterizedTestCaseTypes; INSTANTIATE_TYPED_TEST_CASE_P(Single, TypeParameterizedTestCase, TypeParameterizedTestCaseTypes); #endif int main(int argc, char** argv) { InitGoogleTest(&argc, argv); if (argc > 1 && strcmp(argv[1], "--shut_down_xml") == 0) { TestEventListeners& listeners = UnitTest::GetInstance()->listeners(); delete listeners.Release(listeners.default_xml_generator()); } testing::Test::RecordProperty("ad_hoc_property", "42"); return RUN_ALL_TESTS(); } dlt-daemon-2.18.4/gtest-1.7.0/test/gtest_xml_test_utils.py000077500000000000000000000212541353342203500232460ustar00rootroot00000000000000#!/usr/bin/env python # # Copyright 2006, Google Inc. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above # copyright notice, this list of conditions and the following disclaimer # in the documentation and/or other materials provided with the # distribution. # * Neither the name of Google Inc. nor the names of its # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. """Unit test utilities for gtest_xml_output""" __author__ = 'eefacm@gmail.com (Sean Mcafee)' import re from xml.dom import minidom, Node import gtest_test_utils GTEST_OUTPUT_FLAG = '--gtest_output' GTEST_DEFAULT_OUTPUT_FILE = 'test_detail.xml' class GTestXMLTestCase(gtest_test_utils.TestCase): """ Base class for tests of Google Test's XML output functionality. """ def AssertEquivalentNodes(self, expected_node, actual_node): """ Asserts that actual_node (a DOM node object) is equivalent to expected_node (another DOM node object), in that either both of them are CDATA nodes and have the same value, or both are DOM elements and actual_node meets all of the following conditions: * It has the same tag name as expected_node. * It has the same set of attributes as expected_node, each with the same value as the corresponding attribute of expected_node. Exceptions are any attribute named "time", which needs only be convertible to a floating-point number and any attribute named "type_param" which only has to be non-empty. * It has an equivalent set of child nodes (including elements and CDATA sections) as expected_node. Note that we ignore the order of the children as they are not guaranteed to be in any particular order. """ if expected_node.nodeType == Node.CDATA_SECTION_NODE: self.assertEquals(Node.CDATA_SECTION_NODE, actual_node.nodeType) self.assertEquals(expected_node.nodeValue, actual_node.nodeValue) return self.assertEquals(Node.ELEMENT_NODE, actual_node.nodeType) self.assertEquals(Node.ELEMENT_NODE, expected_node.nodeType) self.assertEquals(expected_node.tagName, actual_node.tagName) expected_attributes = expected_node.attributes actual_attributes = actual_node .attributes self.assertEquals( expected_attributes.length, actual_attributes.length, 'attribute numbers differ in element %s:\nExpected: %r\nActual: %r' % ( actual_node.tagName, expected_attributes.keys(), actual_attributes.keys())) for i in range(expected_attributes.length): expected_attr = expected_attributes.item(i) actual_attr = actual_attributes.get(expected_attr.name) self.assert_( actual_attr is not None, 'expected attribute %s not found in element %s' % (expected_attr.name, actual_node.tagName)) self.assertEquals( expected_attr.value, actual_attr.value, ' values of attribute %s in element %s differ: %s vs %s' % (expected_attr.name, actual_node.tagName, expected_attr.value, actual_attr.value)) expected_children = self._GetChildren(expected_node) actual_children = self._GetChildren(actual_node) self.assertEquals( len(expected_children), len(actual_children), 'number of child elements differ in element ' + actual_node.tagName) for child_id, child in expected_children.iteritems(): self.assert_(child_id in actual_children, '<%s> is not in <%s> (in element %s)' % (child_id, actual_children, actual_node.tagName)) self.AssertEquivalentNodes(child, actual_children[child_id]) identifying_attribute = { 'testsuites': 'name', 'testsuite': 'name', 'testcase': 'name', 'failure': 'message', } def _GetChildren(self, element): """ Fetches all of the child nodes of element, a DOM Element object. Returns them as the values of a dictionary keyed by the IDs of the children. For , and elements, the ID is the value of their "name" attribute; for elements, it is the value of the "message" attribute; CDATA sections and non-whitespace text nodes are concatenated into a single CDATA section with ID "detail". An exception is raised if any element other than the above four is encountered, if two child elements with the same identifying attributes are encountered, or if any other type of node is encountered. """ children = {} for child in element.childNodes: if child.nodeType == Node.ELEMENT_NODE: self.assert_(child.tagName in self.identifying_attribute, 'Encountered unknown element <%s>' % child.tagName) childID = child.getAttribute(self.identifying_attribute[child.tagName]) self.assert_(childID not in children) children[childID] = child elif child.nodeType in [Node.TEXT_NODE, Node.CDATA_SECTION_NODE]: if 'detail' not in children: if (child.nodeType == Node.CDATA_SECTION_NODE or not child.nodeValue.isspace()): children['detail'] = child.ownerDocument.createCDATASection( child.nodeValue) else: children['detail'].nodeValue += child.nodeValue else: self.fail('Encountered unexpected node type %d' % child.nodeType) return children def NormalizeXml(self, element): """ Normalizes Google Test's XML output to eliminate references to transient information that may change from run to run. * The "time" attribute of , and elements is replaced with a single asterisk, if it contains only digit characters. * The "timestamp" attribute of elements is replaced with a single asterisk, if it contains a valid ISO8601 datetime value. * The "type_param" attribute of elements is replaced with a single asterisk (if it sn non-empty) as it is the type name returned by the compiler and is platform dependent. * The line info reported in the first line of the "message" attribute and CDATA section of elements is replaced with the file's basename and a single asterisk for the line number. * The directory names in file paths are removed. * The stack traces are removed. """ if element.tagName == 'testsuites': timestamp = element.getAttributeNode('timestamp') timestamp.value = re.sub(r'^\d{4}-\d\d-\d\dT\d\d:\d\d:\d\d$', '*', timestamp.value) if element.tagName in ('testsuites', 'testsuite', 'testcase'): time = element.getAttributeNode('time') time.value = re.sub(r'^\d+(\.\d+)?$', '*', time.value) type_param = element.getAttributeNode('type_param') if type_param and type_param.value: type_param.value = '*' elif element.tagName == 'failure': source_line_pat = r'^.*[/\\](.*:)\d+\n' # Replaces the source line information with a normalized form. message = element.getAttributeNode('message') message.value = re.sub(source_line_pat, '\\1*\n', message.value) for child in element.childNodes: if child.nodeType == Node.CDATA_SECTION_NODE: # Replaces the source line information with a normalized form. cdata = re.sub(source_line_pat, '\\1*\n', child.nodeValue) # Removes the actual stack trace. child.nodeValue = re.sub(r'\nStack trace:\n(.|\n)*', '', cdata) for child in element.childNodes: if child.nodeType == Node.ELEMENT_NODE: self.NormalizeXml(child) dlt-daemon-2.18.4/gtest-1.7.0/test/production.cc000066400000000000000000000033041353342203500210750ustar00rootroot00000000000000// Copyright 2006, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: wan@google.com (Zhanyong Wan) // // This is part of the unit test for include/gtest/gtest_prod.h. #include "production.h" PrivateCode::PrivateCode() : x_(0) {} dlt-daemon-2.18.4/gtest-1.7.0/test/production.h000066400000000000000000000041741353342203500207450ustar00rootroot00000000000000// Copyright 2006, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: wan@google.com (Zhanyong Wan) // // This is part of the unit test for include/gtest/gtest_prod.h. #ifndef GTEST_TEST_PRODUCTION_H_ #define GTEST_TEST_PRODUCTION_H_ #include "gtest/gtest_prod.h" class PrivateCode { public: // Declares a friend test that does not use a fixture. FRIEND_TEST(PrivateCodeTest, CanAccessPrivateMembers); // Declares a friend test that uses a fixture. FRIEND_TEST(PrivateCodeFixtureTest, CanAccessPrivateMembers); PrivateCode(); int x() const { return x_; } private: void set_x(int an_x) { x_ = an_x; } int x_; }; #endif // GTEST_TEST_PRODUCTION_H_ dlt-daemon-2.18.4/gtest-1.7.0/xcode/000077500000000000000000000000001353342203500165235ustar00rootroot00000000000000dlt-daemon-2.18.4/gtest-1.7.0/xcode/Config/000077500000000000000000000000001353342203500177305ustar00rootroot00000000000000dlt-daemon-2.18.4/gtest-1.7.0/xcode/Config/DebugProject.xcconfig000066400000000000000000000017271353342203500240360ustar00rootroot00000000000000// // DebugProject.xcconfig // // These are Debug Configuration project settings for the gtest framework and // examples. It is set in the "Based On:" dropdown in the "Project" info // dialog. // This file is based on the Xcode Configuration files in: // http://code.google.com/p/google-toolbox-for-mac/ // #include "General.xcconfig" // No optimization GCC_OPTIMIZATION_LEVEL = 0 // Deployment postprocessing is what triggers Xcode to strip, turn it off DEPLOYMENT_POSTPROCESSING = NO // Dead code stripping off DEAD_CODE_STRIPPING = NO // Debug symbols should be on obviously GCC_GENERATE_DEBUGGING_SYMBOLS = YES // Define the DEBUG macro in all debug builds OTHER_CFLAGS = $(OTHER_CFLAGS) -DDEBUG=1 // These are turned off to avoid STL incompatibilities with client code // // Turns on special C++ STL checks to "encourage" good STL use // GCC_PREPROCESSOR_DEFINITIONS = $(GCC_PREPROCESSOR_DEFINITIONS) _GLIBCXX_DEBUG_PEDANTIC _GLIBCXX_DEBUG _GLIBCPP_CONCEPT_CHECKS dlt-daemon-2.18.4/gtest-1.7.0/xcode/Config/FrameworkTarget.xcconfig000066400000000000000000000010471353342203500245600ustar00rootroot00000000000000// // FrameworkTarget.xcconfig // // These are Framework target settings for the gtest framework and examples. It // is set in the "Based On:" dropdown in the "Target" info dialog. // This file is based on the Xcode Configuration files in: // http://code.google.com/p/google-toolbox-for-mac/ // // Dynamic libs need to be position independent GCC_DYNAMIC_NO_PIC = NO // Dynamic libs should not have their external symbols stripped. STRIP_STYLE = non-global // Let the user install by specifying the $DSTROOT with xcodebuild SKIP_INSTALL = NO dlt-daemon-2.18.4/gtest-1.7.0/xcode/Config/General.xcconfig000066400000000000000000000022571353342203500230350ustar00rootroot00000000000000// // General.xcconfig // // These are General configuration settings for the gtest framework and // examples. // This file is based on the Xcode Configuration files in: // http://code.google.com/p/google-toolbox-for-mac/ // // Build for PPC and Intel, 32- and 64-bit ARCHS = i386 x86_64 ppc ppc64 // Zerolink prevents link warnings so turn it off ZERO_LINK = NO // Prebinding considered unhelpful in 10.3 and later PREBINDING = NO // Strictest warning policy WARNING_CFLAGS = -Wall -Werror -Wendif-labels -Wnewline-eof -Wno-sign-compare -Wshadow // Work around Xcode bugs by using external strip. See: // http://lists.apple.com/archives/Xcode-users/2006/Feb/msg00050.html SEPARATE_STRIP = YES // Force C99 dialect GCC_C_LANGUAGE_STANDARD = c99 // not sure why apple defaults this on, but it's pretty risky ALWAYS_SEARCH_USER_PATHS = NO // Turn on position dependent code for most cases (overridden where appropriate) GCC_DYNAMIC_NO_PIC = YES // Default SDK and minimum OS version is 10.4 SDKROOT = $(DEVELOPER_SDK_DIR)/MacOSX10.4u.sdk MACOSX_DEPLOYMENT_TARGET = 10.4 GCC_VERSION = 4.0 // VERSIONING BUILD SETTINGS (used in Info.plist) GTEST_VERSIONINFO_ABOUT = © 2008 Google Inc. dlt-daemon-2.18.4/gtest-1.7.0/xcode/Config/ReleaseProject.xcconfig000066400000000000000000000017411353342203500243640ustar00rootroot00000000000000// // ReleaseProject.xcconfig // // These are Release Configuration project settings for the gtest framework // and examples. It is set in the "Based On:" dropdown in the "Project" info // dialog. // This file is based on the Xcode Configuration files in: // http://code.google.com/p/google-toolbox-for-mac/ // #include "General.xcconfig" // subconfig/Release.xcconfig // Optimize for space and size (Apple recommendation) GCC_OPTIMIZATION_LEVEL = s // Deploment postprocessing is what triggers Xcode to strip DEPLOYMENT_POSTPROCESSING = YES // No symbols GCC_GENERATE_DEBUGGING_SYMBOLS = NO // Dead code strip does not affect ObjC code but can help for C DEAD_CODE_STRIPPING = YES // NDEBUG is used by things like assert.h, so define it for general compat. // ASSERT going away in release tends to create unused vars. OTHER_CFLAGS = $(OTHER_CFLAGS) -DNDEBUG=1 -Wno-unused-variable // When we strip we want to strip all symbols in release, but save externals. STRIP_STYLE = all dlt-daemon-2.18.4/gtest-1.7.0/xcode/Config/StaticLibraryTarget.xcconfig000066400000000000000000000011131353342203500253710ustar00rootroot00000000000000// // StaticLibraryTarget.xcconfig // // These are static library target settings for libgtest.a. It // is set in the "Based On:" dropdown in the "Target" info dialog. // This file is based on the Xcode Configuration files in: // http://code.google.com/p/google-toolbox-for-mac/ // // Static libs can be included in bundles so make them position independent GCC_DYNAMIC_NO_PIC = NO // Static libs should not have their internal globals or external symbols // stripped. STRIP_STYLE = debugging // Let the user install by specifying the $DSTROOT with xcodebuild SKIP_INSTALL = NO dlt-daemon-2.18.4/gtest-1.7.0/xcode/Config/TestTarget.xcconfig000066400000000000000000000003561353342203500235440ustar00rootroot00000000000000// // TestTarget.xcconfig // // These are Test target settings for the gtest framework and examples. It // is set in the "Based On:" dropdown in the "Target" info dialog. PRODUCT_NAME = $(TARGET_NAME) HEADER_SEARCH_PATHS = ../include dlt-daemon-2.18.4/gtest-1.7.0/xcode/Resources/000077500000000000000000000000001353342203500204755ustar00rootroot00000000000000dlt-daemon-2.18.4/gtest-1.7.0/xcode/Resources/Info.plist000066400000000000000000000017621353342203500224530ustar00rootroot00000000000000 CFBundleDevelopmentRegion English CFBundleExecutable ${EXECUTABLE_NAME} CFBundleIconFile CFBundleIdentifier com.google.${PRODUCT_NAME} CFBundleInfoDictionaryVersion 6.0 CFBundlePackageType FMWK CFBundleSignature ???? CFBundleVersion GTEST_VERSIONINFO_LONG CFBundleShortVersionString GTEST_VERSIONINFO_SHORT CFBundleGetInfoString ${PRODUCT_NAME} GTEST_VERSIONINFO_LONG, ${GTEST_VERSIONINFO_ABOUT} NSHumanReadableCopyright ${GTEST_VERSIONINFO_ABOUT} CSResourcesFileMapped dlt-daemon-2.18.4/gtest-1.7.0/xcode/Samples/000077500000000000000000000000001353342203500201275ustar00rootroot00000000000000dlt-daemon-2.18.4/gtest-1.7.0/xcode/Samples/FrameworkSample/000077500000000000000000000000001353342203500232265ustar00rootroot00000000000000dlt-daemon-2.18.4/gtest-1.7.0/xcode/Samples/FrameworkSample/Info.plist000066400000000000000000000015161353342203500252010ustar00rootroot00000000000000 CFBundleDevelopmentRegion English CFBundleExecutable ${EXECUTABLE_NAME} CFBundleIconFile CFBundleIdentifier com.google.gtest.${PRODUCT_NAME:identifier} CFBundleInfoDictionaryVersion 6.0 CFBundleName ${PRODUCT_NAME} CFBundlePackageType FMWK CFBundleShortVersionString 1.0 CFBundleSignature ???? CFBundleVersion 1.0 CSResourcesFileMapped dlt-daemon-2.18.4/gtest-1.7.0/xcode/Samples/FrameworkSample/WidgetFramework.xcodeproj/000077500000000000000000000000001353342203500303235ustar00rootroot00000000000000project.pbxproj000066400000000000000000000372741353342203500333350ustar00rootroot00000000000000dlt-daemon-2.18.4/gtest-1.7.0/xcode/Samples/FrameworkSample/WidgetFramework.xcodeproj// !$*UTF8*$! { archiveVersion = 1; classes = { }; objectVersion = 42; objects = { /* Begin PBXAggregateTarget section */ 4024D162113D7D2400C7059E /* Test */ = { isa = PBXAggregateTarget; buildConfigurationList = 4024D169113D7D4600C7059E /* Build configuration list for PBXAggregateTarget "Test" */; buildPhases = ( 4024D161113D7D2400C7059E /* ShellScript */, ); dependencies = ( 4024D166113D7D3100C7059E /* PBXTargetDependency */, ); name = Test; productName = TestAndBuild; }; 4024D1E9113D83FF00C7059E /* TestAndBuild */ = { isa = PBXAggregateTarget; buildConfigurationList = 4024D1F0113D842B00C7059E /* Build configuration list for PBXAggregateTarget "TestAndBuild" */; buildPhases = ( ); dependencies = ( 4024D1ED113D840900C7059E /* PBXTargetDependency */, 4024D1EF113D840D00C7059E /* PBXTargetDependency */, ); name = TestAndBuild; productName = TestAndBuild; }; /* End PBXAggregateTarget section */ /* Begin PBXBuildFile section */ 3B7EB1250E5AEE3500C7F239 /* widget.cc in Sources */ = {isa = PBXBuildFile; fileRef = 3B7EB1230E5AEE3500C7F239 /* widget.cc */; }; 3B7EB1260E5AEE3500C7F239 /* widget.h in Headers */ = {isa = PBXBuildFile; fileRef = 3B7EB1240E5AEE3500C7F239 /* widget.h */; settings = {ATTRIBUTES = (Public, ); }; }; 3B7EB1280E5AEE4600C7F239 /* widget_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 3B7EB1270E5AEE4600C7F239 /* widget_test.cc */; }; 3B7EB1480E5AF3B400C7F239 /* Widget.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8D07F2C80486CC7A007CD1D0 /* Widget.framework */; }; 4024D188113D7D7800C7059E /* libgtest.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4024D185113D7D5500C7059E /* libgtest.a */; }; 4024D189113D7D7A00C7059E /* libgtest_main.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4024D183113D7D5500C7059E /* libgtest_main.a */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ 3B07BDF00E3F3FAE00647869 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; proxyType = 1; remoteGlobalIDString = 8D07F2BC0486CC7A007CD1D0; remoteInfo = gTestExample; }; 4024D165113D7D3100C7059E /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; proxyType = 1; remoteGlobalIDString = 3B07BDE90E3F3F9E00647869; remoteInfo = WidgetFrameworkTest; }; 4024D1EC113D840900C7059E /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; proxyType = 1; remoteGlobalIDString = 8D07F2BC0486CC7A007CD1D0; remoteInfo = WidgetFramework; }; 4024D1EE113D840D00C7059E /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; proxyType = 1; remoteGlobalIDString = 4024D162113D7D2400C7059E; remoteInfo = Test; }; /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ 3B07BDEA0E3F3F9E00647869 /* WidgetFrameworkTest */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = WidgetFrameworkTest; sourceTree = BUILT_PRODUCTS_DIR; }; 3B7EB1230E5AEE3500C7F239 /* widget.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = widget.cc; sourceTree = ""; }; 3B7EB1240E5AEE3500C7F239 /* widget.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = widget.h; sourceTree = ""; }; 3B7EB1270E5AEE4600C7F239 /* widget_test.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = widget_test.cc; sourceTree = ""; }; 4024D183113D7D5500C7059E /* libgtest_main.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libgtest_main.a; path = /usr/local/lib/libgtest_main.a; sourceTree = ""; }; 4024D185113D7D5500C7059E /* libgtest.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libgtest.a; path = /usr/local/lib/libgtest.a; sourceTree = ""; }; 4024D1E2113D838200C7059E /* runtests.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = runtests.sh; sourceTree = ""; }; 8D07F2C70486CC7A007CD1D0 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist; path = Info.plist; sourceTree = ""; }; 8D07F2C80486CC7A007CD1D0 /* Widget.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Widget.framework; sourceTree = BUILT_PRODUCTS_DIR; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ 3B07BDE80E3F3F9E00647869 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( 4024D189113D7D7A00C7059E /* libgtest_main.a in Frameworks */, 4024D188113D7D7800C7059E /* libgtest.a in Frameworks */, 3B7EB1480E5AF3B400C7F239 /* Widget.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; 8D07F2C30486CC7A007CD1D0 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ 034768DDFF38A45A11DB9C8B /* Products */ = { isa = PBXGroup; children = ( 8D07F2C80486CC7A007CD1D0 /* Widget.framework */, 3B07BDEA0E3F3F9E00647869 /* WidgetFrameworkTest */, ); name = Products; sourceTree = ""; }; 0867D691FE84028FC02AAC07 /* gTestExample */ = { isa = PBXGroup; children = ( 4024D1E1113D836C00C7059E /* Scripts */, 08FB77ACFE841707C02AAC07 /* Source */, 089C1665FE841158C02AAC07 /* Resources */, 3B07BE350E4094E400647869 /* Test */, 0867D69AFE84028FC02AAC07 /* External Frameworks and Libraries */, 034768DDFF38A45A11DB9C8B /* Products */, ); name = gTestExample; sourceTree = ""; }; 0867D69AFE84028FC02AAC07 /* External Frameworks and Libraries */ = { isa = PBXGroup; children = ( 4024D183113D7D5500C7059E /* libgtest_main.a */, 4024D185113D7D5500C7059E /* libgtest.a */, ); name = "External Frameworks and Libraries"; sourceTree = ""; }; 089C1665FE841158C02AAC07 /* Resources */ = { isa = PBXGroup; children = ( 8D07F2C70486CC7A007CD1D0 /* Info.plist */, ); name = Resources; sourceTree = ""; }; 08FB77ACFE841707C02AAC07 /* Source */ = { isa = PBXGroup; children = ( 3B7EB1230E5AEE3500C7F239 /* widget.cc */, 3B7EB1240E5AEE3500C7F239 /* widget.h */, ); name = Source; sourceTree = ""; }; 3B07BE350E4094E400647869 /* Test */ = { isa = PBXGroup; children = ( 3B7EB1270E5AEE4600C7F239 /* widget_test.cc */, ); name = Test; sourceTree = ""; }; 4024D1E1113D836C00C7059E /* Scripts */ = { isa = PBXGroup; children = ( 4024D1E2113D838200C7059E /* runtests.sh */, ); name = Scripts; sourceTree = ""; }; /* End PBXGroup section */ /* Begin PBXHeadersBuildPhase section */ 8D07F2BD0486CC7A007CD1D0 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( 3B7EB1260E5AEE3500C7F239 /* widget.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXHeadersBuildPhase section */ /* Begin PBXNativeTarget section */ 3B07BDE90E3F3F9E00647869 /* WidgetFrameworkTest */ = { isa = PBXNativeTarget; buildConfigurationList = 3B07BDF40E3F3FB600647869 /* Build configuration list for PBXNativeTarget "WidgetFrameworkTest" */; buildPhases = ( 3B07BDE70E3F3F9E00647869 /* Sources */, 3B07BDE80E3F3F9E00647869 /* Frameworks */, ); buildRules = ( ); dependencies = ( 3B07BDF10E3F3FAE00647869 /* PBXTargetDependency */, ); name = WidgetFrameworkTest; productName = gTestExampleTest; productReference = 3B07BDEA0E3F3F9E00647869 /* WidgetFrameworkTest */; productType = "com.apple.product-type.tool"; }; 8D07F2BC0486CC7A007CD1D0 /* WidgetFramework */ = { isa = PBXNativeTarget; buildConfigurationList = 4FADC24208B4156D00ABE55E /* Build configuration list for PBXNativeTarget "WidgetFramework" */; buildPhases = ( 8D07F2C10486CC7A007CD1D0 /* Sources */, 8D07F2C30486CC7A007CD1D0 /* Frameworks */, 8D07F2BD0486CC7A007CD1D0 /* Headers */, 8D07F2BF0486CC7A007CD1D0 /* Resources */, 8D07F2C50486CC7A007CD1D0 /* Rez */, ); buildRules = ( ); dependencies = ( ); name = WidgetFramework; productInstallPath = "$(HOME)/Library/Frameworks"; productName = gTestExample; productReference = 8D07F2C80486CC7A007CD1D0 /* Widget.framework */; productType = "com.apple.product-type.framework"; }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ 0867D690FE84028FC02AAC07 /* Project object */ = { isa = PBXProject; buildConfigurationList = 4FADC24608B4156D00ABE55E /* Build configuration list for PBXProject "WidgetFramework" */; compatibilityVersion = "Xcode 2.4"; hasScannedForEncodings = 1; mainGroup = 0867D691FE84028FC02AAC07 /* gTestExample */; productRefGroup = 034768DDFF38A45A11DB9C8B /* Products */; projectDirPath = ""; projectRoot = ""; targets = ( 8D07F2BC0486CC7A007CD1D0 /* WidgetFramework */, 3B07BDE90E3F3F9E00647869 /* WidgetFrameworkTest */, 4024D162113D7D2400C7059E /* Test */, 4024D1E9113D83FF00C7059E /* TestAndBuild */, ); }; /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ 8D07F2BF0486CC7A007CD1D0 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXResourcesBuildPhase section */ /* Begin PBXRezBuildPhase section */ 8D07F2C50486CC7A007CD1D0 /* Rez */ = { isa = PBXRezBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXRezBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ 4024D161113D7D2400C7059E /* ShellScript */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( ); outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "/bin/bash $SRCROOT/runtests.sh $BUILT_PRODUCTS_DIR/WidgetFrameworkTest\n"; }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ 3B07BDE70E3F3F9E00647869 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 3B7EB1280E5AEE4600C7F239 /* widget_test.cc in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 8D07F2C10486CC7A007CD1D0 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 3B7EB1250E5AEE3500C7F239 /* widget.cc in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ 3B07BDF10E3F3FAE00647869 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 8D07F2BC0486CC7A007CD1D0 /* WidgetFramework */; targetProxy = 3B07BDF00E3F3FAE00647869 /* PBXContainerItemProxy */; }; 4024D166113D7D3100C7059E /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 3B07BDE90E3F3F9E00647869 /* WidgetFrameworkTest */; targetProxy = 4024D165113D7D3100C7059E /* PBXContainerItemProxy */; }; 4024D1ED113D840900C7059E /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 8D07F2BC0486CC7A007CD1D0 /* WidgetFramework */; targetProxy = 4024D1EC113D840900C7059E /* PBXContainerItemProxy */; }; 4024D1EF113D840D00C7059E /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 4024D162113D7D2400C7059E /* Test */; targetProxy = 4024D1EE113D840D00C7059E /* PBXContainerItemProxy */; }; /* End PBXTargetDependency section */ /* Begin XCBuildConfiguration section */ 3B07BDEC0E3F3F9F00647869 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { PRODUCT_NAME = WidgetFrameworkTest; }; name = Debug; }; 3B07BDED0E3F3F9F00647869 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { PRODUCT_NAME = WidgetFrameworkTest; }; name = Release; }; 4024D163113D7D2400C7059E /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { PRODUCT_NAME = TestAndBuild; }; name = Debug; }; 4024D164113D7D2400C7059E /* Release */ = { isa = XCBuildConfiguration; buildSettings = { PRODUCT_NAME = TestAndBuild; }; name = Release; }; 4024D1EA113D83FF00C7059E /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { PRODUCT_NAME = TestAndBuild; }; name = Debug; }; 4024D1EB113D83FF00C7059E /* Release */ = { isa = XCBuildConfiguration; buildSettings = { PRODUCT_NAME = TestAndBuild; }; name = Release; }; 4FADC24308B4156D00ABE55E /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; FRAMEWORK_VERSION = A; INFOPLIST_FILE = Info.plist; INSTALL_PATH = "@loader_path/../Frameworks"; PRODUCT_NAME = Widget; }; name = Debug; }; 4FADC24408B4156D00ABE55E /* Release */ = { isa = XCBuildConfiguration; buildSettings = { DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; FRAMEWORK_VERSION = A; INFOPLIST_FILE = Info.plist; INSTALL_PATH = "@loader_path/../Frameworks"; PRODUCT_NAME = Widget; }; name = Release; }; 4FADC24708B4156D00ABE55E /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { GCC_VERSION = 4.0; SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk; }; name = Debug; }; 4FADC24808B4156D00ABE55E /* Release */ = { isa = XCBuildConfiguration; buildSettings = { GCC_VERSION = 4.0; SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk; }; name = Release; }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ 3B07BDF40E3F3FB600647869 /* Build configuration list for PBXNativeTarget "WidgetFrameworkTest" */ = { isa = XCConfigurationList; buildConfigurations = ( 3B07BDEC0E3F3F9F00647869 /* Debug */, 3B07BDED0E3F3F9F00647869 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; 4024D169113D7D4600C7059E /* Build configuration list for PBXAggregateTarget "Test" */ = { isa = XCConfigurationList; buildConfigurations = ( 4024D163113D7D2400C7059E /* Debug */, 4024D164113D7D2400C7059E /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; 4024D1F0113D842B00C7059E /* Build configuration list for PBXAggregateTarget "TestAndBuild" */ = { isa = XCConfigurationList; buildConfigurations = ( 4024D1EA113D83FF00C7059E /* Debug */, 4024D1EB113D83FF00C7059E /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; 4FADC24208B4156D00ABE55E /* Build configuration list for PBXNativeTarget "WidgetFramework" */ = { isa = XCConfigurationList; buildConfigurations = ( 4FADC24308B4156D00ABE55E /* Debug */, 4FADC24408B4156D00ABE55E /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; 4FADC24608B4156D00ABE55E /* Build configuration list for PBXProject "WidgetFramework" */ = { isa = XCConfigurationList; buildConfigurations = ( 4FADC24708B4156D00ABE55E /* Debug */, 4FADC24808B4156D00ABE55E /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; /* End XCConfigurationList section */ }; rootObject = 0867D690FE84028FC02AAC07 /* Project object */; } dlt-daemon-2.18.4/gtest-1.7.0/xcode/Samples/FrameworkSample/runtests.sh000066400000000000000000000044621353342203500254570ustar00rootroot00000000000000#!/bin/bash # # 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. # Executes the samples and tests for the Google Test Framework. # Help the dynamic linker find the path to the libraries. export DYLD_FRAMEWORK_PATH=$BUILT_PRODUCTS_DIR export DYLD_LIBRARY_PATH=$BUILT_PRODUCTS_DIR # Create some executables. test_executables=$@ # Now execute each one in turn keeping track of how many succeeded and failed. succeeded=0 failed=0 failed_list=() for test in ${test_executables[*]}; do "$test" result=$? if [ $result -eq 0 ]; then succeeded=$(( $succeeded + 1 )) else failed=$(( failed + 1 )) failed_list="$failed_list $test" fi done # Report the successes and failures to the console. echo "Tests complete with $succeeded successes and $failed failures." if [ $failed -ne 0 ]; then echo "The following tests failed:" echo $failed_list fi exit $failed dlt-daemon-2.18.4/gtest-1.7.0/xcode/Samples/FrameworkSample/widget.cc000066400000000000000000000044031353342203500250210ustar00rootroot00000000000000// Copyright 2008, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: preston.a.jackson@gmail.com (Preston Jackson) // // Google Test - FrameworkSample // widget.cc // // Widget is a very simple class used for demonstrating the use of gtest #include "widget.h" Widget::Widget(int number, const std::string& name) : number_(number), name_(name) {} Widget::~Widget() {} float Widget::GetFloatValue() const { return number_; } int Widget::GetIntValue() const { return static_cast(number_); } std::string Widget::GetStringValue() const { return name_; } void Widget::GetCharPtrValue(char* buffer, size_t max_size) const { // Copy the char* representation of name_ into buffer, up to max_size. strncpy(buffer, name_.c_str(), max_size-1); buffer[max_size-1] = '\0'; return; } dlt-daemon-2.18.4/gtest-1.7.0/xcode/Samples/FrameworkSample/widget.h000066400000000000000000000043361353342203500246700ustar00rootroot00000000000000// Copyright 2008, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: preston.a.jackson@gmail.com (Preston Jackson) // // Google Test - FrameworkSample // widget.h // // Widget is a very simple class used for demonstrating the use of gtest. It // simply stores two values a string and an integer, which are returned via // public accessors in multiple forms. #import class Widget { public: Widget(int number, const std::string& name); ~Widget(); // Public accessors to number data float GetFloatValue() const; int GetIntValue() const; // Public accessors to the string data std::string GetStringValue() const; void GetCharPtrValue(char* buffer, size_t max_size) const; private: // Data members float number_; std::string name_; }; dlt-daemon-2.18.4/gtest-1.7.0/xcode/Samples/FrameworkSample/widget_test.cc000066400000000000000000000051551353342203500260650ustar00rootroot00000000000000// Copyright 2008, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: preston.a.jackson@gmail.com (Preston Jackson) // // Google Test - FrameworkSample // widget_test.cc // // This is a simple test file for the Widget class in the Widget.framework #include #include "gtest/gtest.h" #include // This test verifies that the constructor sets the internal state of the // Widget class correctly. TEST(WidgetInitializerTest, TestConstructor) { Widget widget(1.0f, "name"); EXPECT_FLOAT_EQ(1.0f, widget.GetFloatValue()); EXPECT_EQ(std::string("name"), widget.GetStringValue()); } // This test verifies the conversion of the float and string values to int and // char*, respectively. TEST(WidgetInitializerTest, TestConversion) { Widget widget(1.0f, "name"); EXPECT_EQ(1, widget.GetIntValue()); size_t max_size = 128; char buffer[max_size]; widget.GetCharPtrValue(buffer, max_size); EXPECT_STREQ("name", buffer); } // Use the Google Test main that is linked into the framework. It does something // like this: // int main(int argc, char** argv) { // testing::InitGoogleTest(&argc, argv); // return RUN_ALL_TESTS(); // } dlt-daemon-2.18.4/gtest-1.7.0/xcode/Scripts/000077500000000000000000000000001353342203500201525ustar00rootroot00000000000000dlt-daemon-2.18.4/gtest-1.7.0/xcode/Scripts/runtests.sh000066400000000000000000000050331353342203500223760ustar00rootroot00000000000000#!/bin/bash # # 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. # Executes the samples and tests for the Google Test Framework. # Help the dynamic linker find the path to the libraries. export DYLD_FRAMEWORK_PATH=$BUILT_PRODUCTS_DIR export DYLD_LIBRARY_PATH=$BUILT_PRODUCTS_DIR # Create some executables. test_executables=("$BUILT_PRODUCTS_DIR/gtest_unittest-framework" "$BUILT_PRODUCTS_DIR/gtest_unittest" "$BUILT_PRODUCTS_DIR/sample1_unittest-framework" "$BUILT_PRODUCTS_DIR/sample1_unittest-static") # Now execute each one in turn keeping track of how many succeeded and failed. succeeded=0 failed=0 failed_list=() for test in ${test_executables[*]}; do "$test" result=$? if [ $result -eq 0 ]; then succeeded=$(( $succeeded + 1 )) else failed=$(( failed + 1 )) failed_list="$failed_list $test" fi done # Report the successes and failures to the console. echo "Tests complete with $succeeded successes and $failed failures." if [ $failed -ne 0 ]; then echo "The following tests failed:" echo $failed_list fi exit $failed dlt-daemon-2.18.4/gtest-1.7.0/xcode/Scripts/versiongenerate.py000077500000000000000000000106701353342203500237330ustar00rootroot00000000000000#!/usr/bin/env python # # 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. """A script to prepare version informtion for use the gtest Info.plist file. This script extracts the version information from the configure.ac file and uses it to generate a header file containing the same information. The #defines in this header file will be included in during the generation of the Info.plist of the framework, giving the correct value to the version shown in the Finder. This script makes the following assumptions (these are faults of the script, not problems with the Autoconf): 1. The AC_INIT macro will be contained within the first 1024 characters of configure.ac 2. The version string will be 3 integers separated by periods and will be surrounded by squre brackets, "[" and "]" (e.g. [1.0.1]). The first segment represents the major version, the second represents the minor version and the third represents the fix version. 3. No ")" character exists between the opening "(" and closing ")" of AC_INIT, including in comments and character strings. """ import sys import re # Read the command line argument (the output directory for Version.h) if (len(sys.argv) < 3): print "Usage: versiongenerate.py input_dir output_dir" sys.exit(1) else: input_dir = sys.argv[1] output_dir = sys.argv[2] # Read the first 1024 characters of the configure.ac file config_file = open("%s/configure.ac" % input_dir, 'r') buffer_size = 1024 opening_string = config_file.read(buffer_size) config_file.close() # Extract the version string from the AC_INIT macro # The following init_expression means: # Extract three integers separated by periods and surrounded by squre # brackets(e.g. "[1.0.1]") between "AC_INIT(" and ")". Do not be greedy # (*? is the non-greedy flag) since that would pull in everything between # the first "(" and the last ")" in the file. version_expression = re.compile(r"AC_INIT\(.*?\[(\d+)\.(\d+)\.(\d+)\].*?\)", re.DOTALL) version_values = version_expression.search(opening_string) major_version = version_values.group(1) minor_version = version_values.group(2) fix_version = version_values.group(3) # Write the version information to a header file to be included in the # Info.plist file. file_data = """// // DO NOT MODIFY THIS FILE (but you can delete it) // // This file is autogenerated by the versiongenerate.py script. This script // is executed in a "Run Script" build phase when creating gtest.framework. This // header file is not used during compilation of C-source. Rather, it simply // defines some version strings for substitution in the Info.plist. Because of // this, we are not not restricted to C-syntax nor are we using include guards. // #define GTEST_VERSIONINFO_SHORT %s.%s #define GTEST_VERSIONINFO_LONG %s.%s.%s """ % (major_version, minor_version, major_version, minor_version, fix_version) version_file = open("%s/Version.h" % output_dir, 'w') version_file.write(file_data) version_file.close() dlt-daemon-2.18.4/gtest-1.7.0/xcode/gtest.xcodeproj/000077500000000000000000000000001353342203500216455ustar00rootroot00000000000000dlt-daemon-2.18.4/gtest-1.7.0/xcode/gtest.xcodeproj/project.pbxproj000066400000000000000000001434341353342203500247320ustar00rootroot00000000000000// !$*UTF8*$! { archiveVersion = 1; classes = { }; objectVersion = 46; objects = { /* Begin PBXAggregateTarget section */ 3B238F5F0E828B5400846E11 /* Check */ = { isa = PBXAggregateTarget; buildConfigurationList = 3B238FA30E828BB600846E11 /* Build configuration list for PBXAggregateTarget "Check" */; buildPhases = ( 3B238F5E0E828B5400846E11 /* ShellScript */, ); dependencies = ( 40899F9D0FFA740F000B29AE /* PBXTargetDependency */, 40C849F7101A43440083642A /* PBXTargetDependency */, 4089A0980FFAD34A000B29AE /* PBXTargetDependency */, 40C849F9101A43490083642A /* PBXTargetDependency */, ); name = Check; productName = Check; }; 40C44ADC0E3798F4008FCC51 /* Version Info */ = { isa = PBXAggregateTarget; buildConfigurationList = 40C44AE40E379905008FCC51 /* Build configuration list for PBXAggregateTarget "Version Info" */; buildPhases = ( 40C44ADB0E3798F4008FCC51 /* Generate Version.h */, ); comments = "The generation of Version.h must be performed in its own target. Since the Info.plist is preprocessed before any of the other build phases in gtest, the Version.h file would not be ready if included as a build phase of that target."; dependencies = ( ); name = "Version Info"; productName = Version.h; }; /* End PBXAggregateTarget section */ /* Begin PBXBuildFile section */ 224A12A30E9EADCC00BD17FD /* gtest-test-part.h in Headers */ = {isa = PBXBuildFile; fileRef = 224A12A20E9EADCC00BD17FD /* gtest-test-part.h */; settings = {ATTRIBUTES = (Public, ); }; }; 3BF6F2A00E79B5AD000F2EEE /* gtest-type-util.h in Copy Headers Internal */ = {isa = PBXBuildFile; fileRef = 3BF6F29F0E79B5AD000F2EEE /* gtest-type-util.h */; }; 3BF6F2A50E79B616000F2EEE /* gtest-typed-test.h in Headers */ = {isa = PBXBuildFile; fileRef = 3BF6F2A40E79B616000F2EEE /* gtest-typed-test.h */; settings = {ATTRIBUTES = (Public, ); }; }; 404884380E2F799B00CF7658 /* gtest-death-test.h in Headers */ = {isa = PBXBuildFile; fileRef = 404883DB0E2F799B00CF7658 /* gtest-death-test.h */; settings = {ATTRIBUTES = (Public, ); }; }; 404884390E2F799B00CF7658 /* gtest-message.h in Headers */ = {isa = PBXBuildFile; fileRef = 404883DC0E2F799B00CF7658 /* gtest-message.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4048843A0E2F799B00CF7658 /* gtest-spi.h in Headers */ = {isa = PBXBuildFile; fileRef = 404883DD0E2F799B00CF7658 /* gtest-spi.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4048843B0E2F799B00CF7658 /* gtest.h in Headers */ = {isa = PBXBuildFile; fileRef = 404883DE0E2F799B00CF7658 /* gtest.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4048843C0E2F799B00CF7658 /* gtest_pred_impl.h in Headers */ = {isa = PBXBuildFile; fileRef = 404883DF0E2F799B00CF7658 /* gtest_pred_impl.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4048843D0E2F799B00CF7658 /* gtest_prod.h in Headers */ = {isa = PBXBuildFile; fileRef = 404883E00E2F799B00CF7658 /* gtest_prod.h */; settings = {ATTRIBUTES = (Public, ); }; }; 404884500E2F799B00CF7658 /* README in Resources */ = {isa = PBXBuildFile; fileRef = 404883F60E2F799B00CF7658 /* README */; }; 404884A00E2F7BE600CF7658 /* gtest-death-test-internal.h in Copy Headers Internal */ = {isa = PBXBuildFile; fileRef = 404883E20E2F799B00CF7658 /* gtest-death-test-internal.h */; }; 404884A10E2F7BE600CF7658 /* gtest-filepath.h in Copy Headers Internal */ = {isa = PBXBuildFile; fileRef = 404883E30E2F799B00CF7658 /* gtest-filepath.h */; }; 404884A20E2F7BE600CF7658 /* gtest-internal.h in Copy Headers Internal */ = {isa = PBXBuildFile; fileRef = 404883E40E2F799B00CF7658 /* gtest-internal.h */; }; 404884A30E2F7BE600CF7658 /* gtest-port.h in Copy Headers Internal */ = {isa = PBXBuildFile; fileRef = 404883E50E2F799B00CF7658 /* gtest-port.h */; }; 404884A40E2F7BE600CF7658 /* gtest-string.h in Copy Headers Internal */ = {isa = PBXBuildFile; fileRef = 404883E60E2F799B00CF7658 /* gtest-string.h */; }; 404884AC0E2F7CD900CF7658 /* CHANGES in Resources */ = {isa = PBXBuildFile; fileRef = 404884A90E2F7CD900CF7658 /* CHANGES */; }; 404884AD0E2F7CD900CF7658 /* CONTRIBUTORS in Resources */ = {isa = PBXBuildFile; fileRef = 404884AA0E2F7CD900CF7658 /* CONTRIBUTORS */; }; 404884AE0E2F7CD900CF7658 /* LICENSE in Resources */ = {isa = PBXBuildFile; fileRef = 404884AB0E2F7CD900CF7658 /* LICENSE */; }; 40899F3A0FFA70D4000B29AE /* gtest-all.cc in Sources */ = {isa = PBXBuildFile; fileRef = 224A12A10E9EADA700BD17FD /* gtest-all.cc */; }; 40899F500FFA7281000B29AE /* gtest-tuple.h in Copy Headers Internal */ = {isa = PBXBuildFile; fileRef = 40899F4D0FFA7271000B29AE /* gtest-tuple.h */; }; 40899F530FFA72A0000B29AE /* gtest_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = 3B238C120E7FE13C00846E11 /* gtest_unittest.cc */; }; 4089A0440FFAD1BE000B29AE /* sample1.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4089A02C0FFACF7F000B29AE /* sample1.cc */; }; 4089A0460FFAD1BE000B29AE /* sample1_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4089A02E0FFACF7F000B29AE /* sample1_unittest.cc */; }; 40C848FF101A21150083642A /* gtest-all.cc in Sources */ = {isa = PBXBuildFile; fileRef = 224A12A10E9EADA700BD17FD /* gtest-all.cc */; }; 40C84915101A21DF0083642A /* gtest_main.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4048840D0E2F799B00CF7658 /* gtest_main.cc */; }; 40C84916101A235B0083642A /* libgtest_main.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 40C8490B101A217E0083642A /* libgtest_main.a */; }; 40C84921101A23AD0083642A /* libgtest_main.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 40C8490B101A217E0083642A /* libgtest_main.a */; }; 40C84978101A36540083642A /* libgtest_main.a in Resources */ = {isa = PBXBuildFile; fileRef = 40C8490B101A217E0083642A /* libgtest_main.a */; }; 40C84980101A36850083642A /* gtest_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = 3B238C120E7FE13C00846E11 /* gtest_unittest.cc */; }; 40C84982101A36850083642A /* libgtest.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 40C848FA101A209C0083642A /* libgtest.a */; }; 40C84983101A36850083642A /* libgtest_main.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 40C8490B101A217E0083642A /* libgtest_main.a */; }; 40C8498F101A36A60083642A /* sample1.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4089A02C0FFACF7F000B29AE /* sample1.cc */; }; 40C84990101A36A60083642A /* sample1_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4089A02E0FFACF7F000B29AE /* sample1_unittest.cc */; }; 40C84992101A36A60083642A /* libgtest.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 40C848FA101A209C0083642A /* libgtest.a */; }; 40C84993101A36A60083642A /* libgtest_main.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 40C8490B101A217E0083642A /* libgtest_main.a */; }; 40C849A2101A37050083642A /* gtest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4539C8FF0EC27F6400A70F4C /* gtest.framework */; }; 40C849A4101A37150083642A /* gtest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4539C8FF0EC27F6400A70F4C /* gtest.framework */; }; 4539C9340EC280AE00A70F4C /* gtest-param-test.h in Headers */ = {isa = PBXBuildFile; fileRef = 4539C9330EC280AE00A70F4C /* gtest-param-test.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4539C9380EC280E200A70F4C /* gtest-linked_ptr.h in Copy Headers Internal */ = {isa = PBXBuildFile; fileRef = 4539C9350EC280E200A70F4C /* gtest-linked_ptr.h */; }; 4539C9390EC280E200A70F4C /* gtest-param-util-generated.h in Copy Headers Internal */ = {isa = PBXBuildFile; fileRef = 4539C9360EC280E200A70F4C /* gtest-param-util-generated.h */; }; 4539C93A0EC280E200A70F4C /* gtest-param-util.h in Copy Headers Internal */ = {isa = PBXBuildFile; fileRef = 4539C9370EC280E200A70F4C /* gtest-param-util.h */; }; 4567C8181264FF71007740BE /* gtest-printers.h in Headers */ = {isa = PBXBuildFile; fileRef = 4567C8171264FF71007740BE /* gtest-printers.h */; settings = {ATTRIBUTES = (Public, ); }; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ 40899F9C0FFA740F000B29AE /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; proxyType = 1; remoteGlobalIDString = 40899F420FFA7184000B29AE; remoteInfo = gtest_unittest; }; 4089A0970FFAD34A000B29AE /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; proxyType = 1; remoteGlobalIDString = 4089A0120FFACEFC000B29AE; remoteInfo = sample1_unittest; }; 408BEC0F1046CFE900DEF522 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; proxyType = 1; remoteGlobalIDString = 40C848F9101A209C0083642A; remoteInfo = "gtest-static"; }; 40C44AE50E379922008FCC51 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; proxyType = 1; remoteGlobalIDString = 40C44ADC0E3798F4008FCC51; remoteInfo = Version.h; }; 40C8497C101A36850083642A /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; proxyType = 1; remoteGlobalIDString = 40C848F9101A209C0083642A; remoteInfo = "gtest-static"; }; 40C8497E101A36850083642A /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; proxyType = 1; remoteGlobalIDString = 40C8490A101A217E0083642A; remoteInfo = "gtest_main-static"; }; 40C8498B101A36A60083642A /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; proxyType = 1; remoteGlobalIDString = 40C848F9101A209C0083642A; remoteInfo = "gtest-static"; }; 40C8498D101A36A60083642A /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; proxyType = 1; remoteGlobalIDString = 40C8490A101A217E0083642A; remoteInfo = "gtest_main-static"; }; 40C8499B101A36DC0083642A /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; proxyType = 1; remoteGlobalIDString = 40C8490A101A217E0083642A; remoteInfo = "gtest_main-static"; }; 40C8499D101A36E50083642A /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; proxyType = 1; remoteGlobalIDString = 8D07F2BC0486CC7A007CD1D0; remoteInfo = "gtest-framework"; }; 40C8499F101A36F10083642A /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; proxyType = 1; remoteGlobalIDString = 8D07F2BC0486CC7A007CD1D0; remoteInfo = "gtest-framework"; }; 40C849F6101A43440083642A /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; proxyType = 1; remoteGlobalIDString = 40C8497A101A36850083642A; remoteInfo = "gtest_unittest-static"; }; 40C849F8101A43490083642A /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; proxyType = 1; remoteGlobalIDString = 40C84989101A36A60083642A; remoteInfo = "sample1_unittest-static"; }; /* End PBXContainerItemProxy section */ /* Begin PBXCopyFilesBuildPhase section */ 404884A50E2F7C0400CF7658 /* Copy Headers Internal */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 2147483647; dstPath = Headers/internal; dstSubfolderSpec = 6; files = ( 404884A00E2F7BE600CF7658 /* gtest-death-test-internal.h in Copy Headers Internal */, 404884A10E2F7BE600CF7658 /* gtest-filepath.h in Copy Headers Internal */, 404884A20E2F7BE600CF7658 /* gtest-internal.h in Copy Headers Internal */, 4539C9380EC280E200A70F4C /* gtest-linked_ptr.h in Copy Headers Internal */, 4539C9390EC280E200A70F4C /* gtest-param-util-generated.h in Copy Headers Internal */, 4539C93A0EC280E200A70F4C /* gtest-param-util.h in Copy Headers Internal */, 404884A30E2F7BE600CF7658 /* gtest-port.h in Copy Headers Internal */, 404884A40E2F7BE600CF7658 /* gtest-string.h in Copy Headers Internal */, 40899F500FFA7281000B29AE /* gtest-tuple.h in Copy Headers Internal */, 3BF6F2A00E79B5AD000F2EEE /* gtest-type-util.h in Copy Headers Internal */, ); name = "Copy Headers Internal"; runOnlyForDeploymentPostprocessing = 0; }; /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ 224A12A10E9EADA700BD17FD /* gtest-all.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = "gtest-all.cc"; sourceTree = ""; }; 224A12A20E9EADCC00BD17FD /* gtest-test-part.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = "gtest-test-part.h"; sourceTree = ""; }; 3B238C120E7FE13C00846E11 /* gtest_unittest.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = gtest_unittest.cc; sourceTree = ""; }; 3B87D2100E96B92E000D1852 /* runtests.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = runtests.sh; sourceTree = ""; }; 3BF6F29F0E79B5AD000F2EEE /* gtest-type-util.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "gtest-type-util.h"; sourceTree = ""; }; 3BF6F2A40E79B616000F2EEE /* gtest-typed-test.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "gtest-typed-test.h"; sourceTree = ""; }; 403EE37C0E377822004BD1E2 /* versiongenerate.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = versiongenerate.py; sourceTree = ""; }; 404883DB0E2F799B00CF7658 /* gtest-death-test.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "gtest-death-test.h"; sourceTree = ""; }; 404883DC0E2F799B00CF7658 /* gtest-message.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "gtest-message.h"; sourceTree = ""; }; 404883DD0E2F799B00CF7658 /* gtest-spi.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "gtest-spi.h"; sourceTree = ""; }; 404883DE0E2F799B00CF7658 /* gtest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gtest.h; sourceTree = ""; }; 404883DF0E2F799B00CF7658 /* gtest_pred_impl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gtest_pred_impl.h; sourceTree = ""; }; 404883E00E2F799B00CF7658 /* gtest_prod.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gtest_prod.h; sourceTree = ""; }; 404883E20E2F799B00CF7658 /* gtest-death-test-internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "gtest-death-test-internal.h"; sourceTree = ""; }; 404883E30E2F799B00CF7658 /* gtest-filepath.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "gtest-filepath.h"; sourceTree = ""; }; 404883E40E2F799B00CF7658 /* gtest-internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "gtest-internal.h"; sourceTree = ""; }; 404883E50E2F799B00CF7658 /* gtest-port.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "gtest-port.h"; sourceTree = ""; }; 404883E60E2F799B00CF7658 /* gtest-string.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "gtest-string.h"; sourceTree = ""; }; 404883F60E2F799B00CF7658 /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = README; path = ../README; sourceTree = SOURCE_ROOT; }; 4048840D0E2F799B00CF7658 /* gtest_main.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = gtest_main.cc; sourceTree = ""; }; 404884A90E2F7CD900CF7658 /* CHANGES */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = CHANGES; path = ../CHANGES; sourceTree = SOURCE_ROOT; }; 404884AA0E2F7CD900CF7658 /* CONTRIBUTORS */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = CONTRIBUTORS; path = ../CONTRIBUTORS; sourceTree = SOURCE_ROOT; }; 404884AB0E2F7CD900CF7658 /* LICENSE */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = LICENSE; path = ../LICENSE; sourceTree = SOURCE_ROOT; }; 40899F430FFA7184000B29AE /* gtest_unittest-framework */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "gtest_unittest-framework"; sourceTree = BUILT_PRODUCTS_DIR; }; 40899F4D0FFA7271000B29AE /* gtest-tuple.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "gtest-tuple.h"; sourceTree = ""; }; 40899FB30FFA7567000B29AE /* StaticLibraryTarget.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = StaticLibraryTarget.xcconfig; sourceTree = ""; }; 4089A0130FFACEFC000B29AE /* sample1_unittest-framework */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "sample1_unittest-framework"; sourceTree = BUILT_PRODUCTS_DIR; }; 4089A02C0FFACF7F000B29AE /* sample1.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sample1.cc; sourceTree = ""; }; 4089A02D0FFACF7F000B29AE /* sample1.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sample1.h; sourceTree = ""; }; 4089A02E0FFACF7F000B29AE /* sample1_unittest.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sample1_unittest.cc; sourceTree = ""; }; 40C848FA101A209C0083642A /* libgtest.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libgtest.a; sourceTree = BUILT_PRODUCTS_DIR; }; 40C8490B101A217E0083642A /* libgtest_main.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libgtest_main.a; sourceTree = BUILT_PRODUCTS_DIR; }; 40C84987101A36850083642A /* gtest_unittest */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = gtest_unittest; sourceTree = BUILT_PRODUCTS_DIR; }; 40C84997101A36A60083642A /* sample1_unittest-static */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "sample1_unittest-static"; sourceTree = BUILT_PRODUCTS_DIR; }; 40D4CDF10E30E07400294801 /* DebugProject.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = DebugProject.xcconfig; sourceTree = ""; }; 40D4CDF20E30E07400294801 /* FrameworkTarget.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = FrameworkTarget.xcconfig; sourceTree = ""; }; 40D4CDF30E30E07400294801 /* General.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = General.xcconfig; sourceTree = ""; }; 40D4CDF40E30E07400294801 /* ReleaseProject.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = ReleaseProject.xcconfig; sourceTree = ""; }; 40D4CF510E30F5E200294801 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 4539C8FF0EC27F6400A70F4C /* gtest.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = gtest.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 4539C9330EC280AE00A70F4C /* gtest-param-test.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "gtest-param-test.h"; sourceTree = ""; }; 4539C9350EC280E200A70F4C /* gtest-linked_ptr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "gtest-linked_ptr.h"; sourceTree = ""; }; 4539C9360EC280E200A70F4C /* gtest-param-util-generated.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "gtest-param-util-generated.h"; sourceTree = ""; }; 4539C9370EC280E200A70F4C /* gtest-param-util.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "gtest-param-util.h"; sourceTree = ""; }; 4567C8171264FF71007740BE /* gtest-printers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "gtest-printers.h"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ 40899F410FFA7184000B29AE /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( 40C849A4101A37150083642A /* gtest.framework in Frameworks */, 40C84916101A235B0083642A /* libgtest_main.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; 4089A0110FFACEFC000B29AE /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( 40C849A2101A37050083642A /* gtest.framework in Frameworks */, 40C84921101A23AD0083642A /* libgtest_main.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; 40C84981101A36850083642A /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( 40C84982101A36850083642A /* libgtest.a in Frameworks */, 40C84983101A36850083642A /* libgtest_main.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; 40C84991101A36A60083642A /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( 40C84992101A36A60083642A /* libgtest.a in Frameworks */, 40C84993101A36A60083642A /* libgtest_main.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ 034768DDFF38A45A11DB9C8B /* Products */ = { isa = PBXGroup; children = ( 4539C8FF0EC27F6400A70F4C /* gtest.framework */, 40C848FA101A209C0083642A /* libgtest.a */, 40C8490B101A217E0083642A /* libgtest_main.a */, 40899F430FFA7184000B29AE /* gtest_unittest-framework */, 40C84987101A36850083642A /* gtest_unittest */, 4089A0130FFACEFC000B29AE /* sample1_unittest-framework */, 40C84997101A36A60083642A /* sample1_unittest-static */, ); name = Products; sourceTree = ""; }; 0867D691FE84028FC02AAC07 /* gtest */ = { isa = PBXGroup; children = ( 40D4CDF00E30E07400294801 /* Config */, 08FB77ACFE841707C02AAC07 /* Source */, 40D4CF4E0E30F5E200294801 /* Resources */, 403EE37B0E377822004BD1E2 /* Scripts */, 034768DDFF38A45A11DB9C8B /* Products */, ); name = gtest; sourceTree = ""; }; 08FB77ACFE841707C02AAC07 /* Source */ = { isa = PBXGroup; children = ( 404884A90E2F7CD900CF7658 /* CHANGES */, 404884AA0E2F7CD900CF7658 /* CONTRIBUTORS */, 404884AB0E2F7CD900CF7658 /* LICENSE */, 404883F60E2F799B00CF7658 /* README */, 404883D90E2F799B00CF7658 /* include */, 4089A02F0FFACF84000B29AE /* samples */, 404884070E2F799B00CF7658 /* src */, 3B238BF00E7FE13B00846E11 /* test */, ); name = Source; sourceTree = ""; }; 3B238BF00E7FE13B00846E11 /* test */ = { isa = PBXGroup; children = ( 3B238C120E7FE13C00846E11 /* gtest_unittest.cc */, ); name = test; path = ../test; sourceTree = SOURCE_ROOT; }; 403EE37B0E377822004BD1E2 /* Scripts */ = { isa = PBXGroup; children = ( 403EE37C0E377822004BD1E2 /* versiongenerate.py */, 3B87D2100E96B92E000D1852 /* runtests.sh */, ); path = Scripts; sourceTree = ""; }; 404883D90E2F799B00CF7658 /* include */ = { isa = PBXGroup; children = ( 404883DA0E2F799B00CF7658 /* gtest */, ); name = include; path = ../include; sourceTree = SOURCE_ROOT; }; 404883DA0E2F799B00CF7658 /* gtest */ = { isa = PBXGroup; children = ( 404883E10E2F799B00CF7658 /* internal */, 224A12A20E9EADCC00BD17FD /* gtest-test-part.h */, 404883DB0E2F799B00CF7658 /* gtest-death-test.h */, 404883DC0E2F799B00CF7658 /* gtest-message.h */, 4539C9330EC280AE00A70F4C /* gtest-param-test.h */, 4567C8171264FF71007740BE /* gtest-printers.h */, 404883DD0E2F799B00CF7658 /* gtest-spi.h */, 404883DE0E2F799B00CF7658 /* gtest.h */, 404883DF0E2F799B00CF7658 /* gtest_pred_impl.h */, 404883E00E2F799B00CF7658 /* gtest_prod.h */, 3BF6F2A40E79B616000F2EEE /* gtest-typed-test.h */, ); path = gtest; sourceTree = ""; }; 404883E10E2F799B00CF7658 /* internal */ = { isa = PBXGroup; children = ( 404883E20E2F799B00CF7658 /* gtest-death-test-internal.h */, 404883E30E2F799B00CF7658 /* gtest-filepath.h */, 404883E40E2F799B00CF7658 /* gtest-internal.h */, 4539C9350EC280E200A70F4C /* gtest-linked_ptr.h */, 4539C9360EC280E200A70F4C /* gtest-param-util-generated.h */, 4539C9370EC280E200A70F4C /* gtest-param-util.h */, 404883E50E2F799B00CF7658 /* gtest-port.h */, 404883E60E2F799B00CF7658 /* gtest-string.h */, 40899F4D0FFA7271000B29AE /* gtest-tuple.h */, 3BF6F29F0E79B5AD000F2EEE /* gtest-type-util.h */, ); path = internal; sourceTree = ""; }; 404884070E2F799B00CF7658 /* src */ = { isa = PBXGroup; children = ( 224A12A10E9EADA700BD17FD /* gtest-all.cc */, 4048840D0E2F799B00CF7658 /* gtest_main.cc */, ); name = src; path = ../src; sourceTree = SOURCE_ROOT; }; 4089A02F0FFACF84000B29AE /* samples */ = { isa = PBXGroup; children = ( 4089A02C0FFACF7F000B29AE /* sample1.cc */, 4089A02D0FFACF7F000B29AE /* sample1.h */, 4089A02E0FFACF7F000B29AE /* sample1_unittest.cc */, ); name = samples; path = ../samples; sourceTree = SOURCE_ROOT; }; 40D4CDF00E30E07400294801 /* Config */ = { isa = PBXGroup; children = ( 40D4CDF10E30E07400294801 /* DebugProject.xcconfig */, 40D4CDF20E30E07400294801 /* FrameworkTarget.xcconfig */, 40D4CDF30E30E07400294801 /* General.xcconfig */, 40D4CDF40E30E07400294801 /* ReleaseProject.xcconfig */, 40899FB30FFA7567000B29AE /* StaticLibraryTarget.xcconfig */, ); path = Config; sourceTree = ""; }; 40D4CF4E0E30F5E200294801 /* Resources */ = { isa = PBXGroup; children = ( 40D4CF510E30F5E200294801 /* Info.plist */, ); path = Resources; sourceTree = ""; }; /* End PBXGroup section */ /* Begin PBXHeadersBuildPhase section */ 8D07F2BD0486CC7A007CD1D0 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( 404884380E2F799B00CF7658 /* gtest-death-test.h in Headers */, 404884390E2F799B00CF7658 /* gtest-message.h in Headers */, 4539C9340EC280AE00A70F4C /* gtest-param-test.h in Headers */, 4567C8181264FF71007740BE /* gtest-printers.h in Headers */, 3BF6F2A50E79B616000F2EEE /* gtest-typed-test.h in Headers */, 4048843A0E2F799B00CF7658 /* gtest-spi.h in Headers */, 4048843B0E2F799B00CF7658 /* gtest.h in Headers */, 4048843C0E2F799B00CF7658 /* gtest_pred_impl.h in Headers */, 4048843D0E2F799B00CF7658 /* gtest_prod.h in Headers */, 224A12A30E9EADCC00BD17FD /* gtest-test-part.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXHeadersBuildPhase section */ /* Begin PBXNativeTarget section */ 40899F420FFA7184000B29AE /* gtest_unittest-framework */ = { isa = PBXNativeTarget; buildConfigurationList = 40899F4A0FFA71BC000B29AE /* Build configuration list for PBXNativeTarget "gtest_unittest-framework" */; buildPhases = ( 40899F400FFA7184000B29AE /* Sources */, 40899F410FFA7184000B29AE /* Frameworks */, ); buildRules = ( ); dependencies = ( 40C849A0101A36F10083642A /* PBXTargetDependency */, ); name = "gtest_unittest-framework"; productName = gtest_unittest; productReference = 40899F430FFA7184000B29AE /* gtest_unittest-framework */; productType = "com.apple.product-type.tool"; }; 4089A0120FFACEFC000B29AE /* sample1_unittest-framework */ = { isa = PBXNativeTarget; buildConfigurationList = 4089A0240FFACF01000B29AE /* Build configuration list for PBXNativeTarget "sample1_unittest-framework" */; buildPhases = ( 4089A0100FFACEFC000B29AE /* Sources */, 4089A0110FFACEFC000B29AE /* Frameworks */, ); buildRules = ( ); dependencies = ( 40C8499E101A36E50083642A /* PBXTargetDependency */, ); name = "sample1_unittest-framework"; productName = sample1_unittest; productReference = 4089A0130FFACEFC000B29AE /* sample1_unittest-framework */; productType = "com.apple.product-type.tool"; }; 40C848F9101A209C0083642A /* gtest-static */ = { isa = PBXNativeTarget; buildConfigurationList = 40C84902101A212E0083642A /* Build configuration list for PBXNativeTarget "gtest-static" */; buildPhases = ( 40C848F7101A209C0083642A /* Sources */, ); buildRules = ( ); dependencies = ( ); name = "gtest-static"; productName = "gtest-static"; productReference = 40C848FA101A209C0083642A /* libgtest.a */; productType = "com.apple.product-type.library.static"; }; 40C8490A101A217E0083642A /* gtest_main-static */ = { isa = PBXNativeTarget; buildConfigurationList = 40C84912101A21D20083642A /* Build configuration list for PBXNativeTarget "gtest_main-static" */; buildPhases = ( 40C84908101A217E0083642A /* Sources */, ); buildRules = ( ); dependencies = ( ); name = "gtest_main-static"; productName = "gtest_main-static"; productReference = 40C8490B101A217E0083642A /* libgtest_main.a */; productType = "com.apple.product-type.library.static"; }; 40C8497A101A36850083642A /* gtest_unittest-static */ = { isa = PBXNativeTarget; buildConfigurationList = 40C84984101A36850083642A /* Build configuration list for PBXNativeTarget "gtest_unittest-static" */; buildPhases = ( 40C8497F101A36850083642A /* Sources */, 40C84981101A36850083642A /* Frameworks */, ); buildRules = ( ); dependencies = ( 40C8497B101A36850083642A /* PBXTargetDependency */, 40C8497D101A36850083642A /* PBXTargetDependency */, ); name = "gtest_unittest-static"; productName = gtest_unittest; productReference = 40C84987101A36850083642A /* gtest_unittest */; productType = "com.apple.product-type.tool"; }; 40C84989101A36A60083642A /* sample1_unittest-static */ = { isa = PBXNativeTarget; buildConfigurationList = 40C84994101A36A60083642A /* Build configuration list for PBXNativeTarget "sample1_unittest-static" */; buildPhases = ( 40C8498E101A36A60083642A /* Sources */, 40C84991101A36A60083642A /* Frameworks */, ); buildRules = ( ); dependencies = ( 40C8498A101A36A60083642A /* PBXTargetDependency */, 40C8498C101A36A60083642A /* PBXTargetDependency */, ); name = "sample1_unittest-static"; productName = sample1_unittest; productReference = 40C84997101A36A60083642A /* sample1_unittest-static */; productType = "com.apple.product-type.tool"; }; 8D07F2BC0486CC7A007CD1D0 /* gtest-framework */ = { isa = PBXNativeTarget; buildConfigurationList = 4FADC24208B4156D00ABE55E /* Build configuration list for PBXNativeTarget "gtest-framework" */; buildPhases = ( 8D07F2C10486CC7A007CD1D0 /* Sources */, 8D07F2BD0486CC7A007CD1D0 /* Headers */, 404884A50E2F7C0400CF7658 /* Copy Headers Internal */, 8D07F2BF0486CC7A007CD1D0 /* Resources */, ); buildRules = ( ); dependencies = ( 40C44AE60E379922008FCC51 /* PBXTargetDependency */, 408BEC101046CFE900DEF522 /* PBXTargetDependency */, 40C8499C101A36DC0083642A /* PBXTargetDependency */, ); name = "gtest-framework"; productInstallPath = "$(HOME)/Library/Frameworks"; productName = gtest; productReference = 4539C8FF0EC27F6400A70F4C /* gtest.framework */; productType = "com.apple.product-type.framework"; }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ 0867D690FE84028FC02AAC07 /* Project object */ = { isa = PBXProject; attributes = { LastUpgradeCheck = 0460; }; buildConfigurationList = 4FADC24608B4156D00ABE55E /* Build configuration list for PBXProject "gtest" */; compatibilityVersion = "Xcode 3.2"; developmentRegion = English; hasScannedForEncodings = 1; knownRegions = ( English, Japanese, French, German, en, ); mainGroup = 0867D691FE84028FC02AAC07 /* gtest */; productRefGroup = 034768DDFF38A45A11DB9C8B /* Products */; projectDirPath = ""; projectRoot = ""; targets = ( 8D07F2BC0486CC7A007CD1D0 /* gtest-framework */, 40C848F9101A209C0083642A /* gtest-static */, 40C8490A101A217E0083642A /* gtest_main-static */, 40899F420FFA7184000B29AE /* gtest_unittest-framework */, 40C8497A101A36850083642A /* gtest_unittest-static */, 4089A0120FFACEFC000B29AE /* sample1_unittest-framework */, 40C84989101A36A60083642A /* sample1_unittest-static */, 3B238F5F0E828B5400846E11 /* Check */, 40C44ADC0E3798F4008FCC51 /* Version Info */, ); }; /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ 8D07F2BF0486CC7A007CD1D0 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( 404884500E2F799B00CF7658 /* README in Resources */, 404884AC0E2F7CD900CF7658 /* CHANGES in Resources */, 404884AD0E2F7CD900CF7658 /* CONTRIBUTORS in Resources */, 404884AE0E2F7CD900CF7658 /* LICENSE in Resources */, 40C84978101A36540083642A /* libgtest_main.a in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ 3B238F5E0E828B5400846E11 /* ShellScript */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( ); outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "# Remember, this \"Run Script\" build phase will be executed from $SRCROOT\n/bin/bash Scripts/runtests.sh"; }; 40C44ADB0E3798F4008FCC51 /* Generate Version.h */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( "$(SRCROOT)/Scripts/versiongenerate.py", "$(SRCROOT)/../configure.ac", ); name = "Generate Version.h"; outputPaths = ( "$(PROJECT_TEMP_DIR)/Version.h", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "# Remember, this \"Run Script\" build phase will be executed from $SRCROOT\n/usr/bin/python Scripts/versiongenerate.py ../ $PROJECT_TEMP_DIR"; }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ 40899F400FFA7184000B29AE /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 40899F530FFA72A0000B29AE /* gtest_unittest.cc in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 4089A0100FFACEFC000B29AE /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 4089A0440FFAD1BE000B29AE /* sample1.cc in Sources */, 4089A0460FFAD1BE000B29AE /* sample1_unittest.cc in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 40C848F7101A209C0083642A /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 40C848FF101A21150083642A /* gtest-all.cc in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 40C84908101A217E0083642A /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 40C84915101A21DF0083642A /* gtest_main.cc in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 40C8497F101A36850083642A /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 40C84980101A36850083642A /* gtest_unittest.cc in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 40C8498E101A36A60083642A /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 40C8498F101A36A60083642A /* sample1.cc in Sources */, 40C84990101A36A60083642A /* sample1_unittest.cc in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 8D07F2C10486CC7A007CD1D0 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 40899F3A0FFA70D4000B29AE /* gtest-all.cc in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ 40899F9D0FFA740F000B29AE /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 40899F420FFA7184000B29AE /* gtest_unittest-framework */; targetProxy = 40899F9C0FFA740F000B29AE /* PBXContainerItemProxy */; }; 4089A0980FFAD34A000B29AE /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 4089A0120FFACEFC000B29AE /* sample1_unittest-framework */; targetProxy = 4089A0970FFAD34A000B29AE /* PBXContainerItemProxy */; }; 408BEC101046CFE900DEF522 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 40C848F9101A209C0083642A /* gtest-static */; targetProxy = 408BEC0F1046CFE900DEF522 /* PBXContainerItemProxy */; }; 40C44AE60E379922008FCC51 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 40C44ADC0E3798F4008FCC51 /* Version Info */; targetProxy = 40C44AE50E379922008FCC51 /* PBXContainerItemProxy */; }; 40C8497B101A36850083642A /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 40C848F9101A209C0083642A /* gtest-static */; targetProxy = 40C8497C101A36850083642A /* PBXContainerItemProxy */; }; 40C8497D101A36850083642A /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 40C8490A101A217E0083642A /* gtest_main-static */; targetProxy = 40C8497E101A36850083642A /* PBXContainerItemProxy */; }; 40C8498A101A36A60083642A /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 40C848F9101A209C0083642A /* gtest-static */; targetProxy = 40C8498B101A36A60083642A /* PBXContainerItemProxy */; }; 40C8498C101A36A60083642A /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 40C8490A101A217E0083642A /* gtest_main-static */; targetProxy = 40C8498D101A36A60083642A /* PBXContainerItemProxy */; }; 40C8499C101A36DC0083642A /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 40C8490A101A217E0083642A /* gtest_main-static */; targetProxy = 40C8499B101A36DC0083642A /* PBXContainerItemProxy */; }; 40C8499E101A36E50083642A /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 8D07F2BC0486CC7A007CD1D0 /* gtest-framework */; targetProxy = 40C8499D101A36E50083642A /* PBXContainerItemProxy */; }; 40C849A0101A36F10083642A /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 8D07F2BC0486CC7A007CD1D0 /* gtest-framework */; targetProxy = 40C8499F101A36F10083642A /* PBXContainerItemProxy */; }; 40C849F7101A43440083642A /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 40C8497A101A36850083642A /* gtest_unittest-static */; targetProxy = 40C849F6101A43440083642A /* PBXContainerItemProxy */; }; 40C849F9101A43490083642A /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 40C84989101A36A60083642A /* sample1_unittest-static */; targetProxy = 40C849F8101A43490083642A /* PBXContainerItemProxy */; }; /* End PBXTargetDependency section */ /* Begin XCBuildConfiguration section */ 3B238F600E828B5400846E11 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { COMBINE_HIDPI_IMAGES = YES; COPY_PHASE_STRIP = NO; GCC_DYNAMIC_NO_PIC = NO; GCC_OPTIMIZATION_LEVEL = 0; GCC_VERSION = com.apple.compilers.llvm.clang.1_0; PRODUCT_NAME = Check; SDKROOT = macosx; }; name = Debug; }; 3B238F610E828B5400846E11 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { COMBINE_HIDPI_IMAGES = YES; COPY_PHASE_STRIP = YES; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; GCC_VERSION = com.apple.compilers.llvm.clang.1_0; PRODUCT_NAME = Check; SDKROOT = macosx; ZERO_LINK = NO; }; name = Release; }; 40899F450FFA7185000B29AE /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { GCC_VERSION = com.apple.compilers.llvm.clang.1_0; HEADER_SEARCH_PATHS = ../; PRODUCT_NAME = "gtest_unittest-framework"; SDKROOT = macosx; }; name = Debug; }; 40899F460FFA7185000B29AE /* Release */ = { isa = XCBuildConfiguration; buildSettings = { GCC_VERSION = com.apple.compilers.llvm.clang.1_0; HEADER_SEARCH_PATHS = ../; PRODUCT_NAME = "gtest_unittest-framework"; SDKROOT = macosx; }; name = Release; }; 4089A0150FFACEFD000B29AE /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { GCC_VERSION = com.apple.compilers.llvm.clang.1_0; PRODUCT_NAME = "sample1_unittest-framework"; SDKROOT = macosx; }; name = Debug; }; 4089A0160FFACEFD000B29AE /* Release */ = { isa = XCBuildConfiguration; buildSettings = { GCC_VERSION = com.apple.compilers.llvm.clang.1_0; PRODUCT_NAME = "sample1_unittest-framework"; SDKROOT = macosx; }; name = Release; }; 40C44ADF0E3798F4008FCC51 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { COMBINE_HIDPI_IMAGES = YES; GCC_VERSION = com.apple.compilers.llvm.clang.1_0; MACOSX_DEPLOYMENT_TARGET = 10.7; PRODUCT_NAME = gtest; SDKROOT = macosx; TARGET_NAME = gtest; }; name = Debug; }; 40C44AE00E3798F4008FCC51 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { COMBINE_HIDPI_IMAGES = YES; GCC_VERSION = com.apple.compilers.llvm.clang.1_0; MACOSX_DEPLOYMENT_TARGET = 10.7; PRODUCT_NAME = gtest; SDKROOT = macosx; TARGET_NAME = gtest; }; name = Release; }; 40C848FB101A209D0083642A /* Debug */ = { isa = XCBuildConfiguration; baseConfigurationReference = 40899FB30FFA7567000B29AE /* StaticLibraryTarget.xcconfig */; buildSettings = { COMBINE_HIDPI_IMAGES = YES; GCC_INLINES_ARE_PRIVATE_EXTERN = YES; GCC_SYMBOLS_PRIVATE_EXTERN = YES; GCC_VERSION = com.apple.compilers.llvm.clang.1_0; HEADER_SEARCH_PATHS = ( ../, ../include/, ); PRODUCT_NAME = gtest; SDKROOT = macosx; }; name = Debug; }; 40C848FC101A209D0083642A /* Release */ = { isa = XCBuildConfiguration; baseConfigurationReference = 40899FB30FFA7567000B29AE /* StaticLibraryTarget.xcconfig */; buildSettings = { COMBINE_HIDPI_IMAGES = YES; GCC_INLINES_ARE_PRIVATE_EXTERN = YES; GCC_SYMBOLS_PRIVATE_EXTERN = YES; GCC_VERSION = com.apple.compilers.llvm.clang.1_0; HEADER_SEARCH_PATHS = ( ../, ../include/, ); PRODUCT_NAME = gtest; SDKROOT = macosx; }; name = Release; }; 40C8490E101A217F0083642A /* Debug */ = { isa = XCBuildConfiguration; baseConfigurationReference = 40899FB30FFA7567000B29AE /* StaticLibraryTarget.xcconfig */; buildSettings = { COMBINE_HIDPI_IMAGES = YES; GCC_VERSION = com.apple.compilers.llvm.clang.1_0; HEADER_SEARCH_PATHS = ( ../, ../include/, ); PRODUCT_NAME = gtest_main; SDKROOT = macosx; }; name = Debug; }; 40C8490F101A217F0083642A /* Release */ = { isa = XCBuildConfiguration; baseConfigurationReference = 40899FB30FFA7567000B29AE /* StaticLibraryTarget.xcconfig */; buildSettings = { COMBINE_HIDPI_IMAGES = YES; GCC_VERSION = com.apple.compilers.llvm.clang.1_0; HEADER_SEARCH_PATHS = ( ../, ../include/, ); PRODUCT_NAME = gtest_main; SDKROOT = macosx; }; name = Release; }; 40C84985101A36850083642A /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { GCC_VERSION = com.apple.compilers.llvm.clang.1_0; HEADER_SEARCH_PATHS = ../; PRODUCT_NAME = gtest_unittest; SDKROOT = macosx; }; name = Debug; }; 40C84986101A36850083642A /* Release */ = { isa = XCBuildConfiguration; buildSettings = { GCC_VERSION = com.apple.compilers.llvm.clang.1_0; HEADER_SEARCH_PATHS = ../; PRODUCT_NAME = gtest_unittest; SDKROOT = macosx; }; name = Release; }; 40C84995101A36A60083642A /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { GCC_VERSION = com.apple.compilers.llvm.clang.1_0; PRODUCT_NAME = "sample1_unittest-static"; SDKROOT = macosx; }; name = Debug; }; 40C84996101A36A60083642A /* Release */ = { isa = XCBuildConfiguration; buildSettings = { GCC_VERSION = com.apple.compilers.llvm.clang.1_0; PRODUCT_NAME = "sample1_unittest-static"; SDKROOT = macosx; }; name = Release; }; 4FADC24308B4156D00ABE55E /* Debug */ = { isa = XCBuildConfiguration; baseConfigurationReference = 40D4CDF20E30E07400294801 /* FrameworkTarget.xcconfig */; buildSettings = { COMBINE_HIDPI_IMAGES = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; GCC_VERSION = com.apple.compilers.llvm.clang.1_0; HEADER_SEARCH_PATHS = ( ../, ../include/, ); INFOPLIST_FILE = Resources/Info.plist; INFOPLIST_PREFIX_HEADER = "$(PROJECT_TEMP_DIR)/Version.h"; INFOPLIST_PREPROCESS = YES; PRODUCT_NAME = gtest; SDKROOT = macosx; VERSIONING_SYSTEM = "apple-generic"; }; name = Debug; }; 4FADC24408B4156D00ABE55E /* Release */ = { isa = XCBuildConfiguration; baseConfigurationReference = 40D4CDF20E30E07400294801 /* FrameworkTarget.xcconfig */; buildSettings = { COMBINE_HIDPI_IMAGES = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; GCC_VERSION = com.apple.compilers.llvm.clang.1_0; HEADER_SEARCH_PATHS = ( ../, ../include/, ); INFOPLIST_FILE = Resources/Info.plist; INFOPLIST_PREFIX_HEADER = "$(PROJECT_TEMP_DIR)/Version.h"; INFOPLIST_PREPROCESS = YES; PRODUCT_NAME = gtest; SDKROOT = macosx; VERSIONING_SYSTEM = "apple-generic"; }; name = Release; }; 4FADC24708B4156D00ABE55E /* Debug */ = { isa = XCBuildConfiguration; baseConfigurationReference = 40D4CDF10E30E07400294801 /* DebugProject.xcconfig */; buildSettings = { }; name = Debug; }; 4FADC24808B4156D00ABE55E /* Release */ = { isa = XCBuildConfiguration; baseConfigurationReference = 40D4CDF40E30E07400294801 /* ReleaseProject.xcconfig */; buildSettings = { }; name = Release; }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ 3B238FA30E828BB600846E11 /* Build configuration list for PBXAggregateTarget "Check" */ = { isa = XCConfigurationList; buildConfigurations = ( 3B238F600E828B5400846E11 /* Debug */, 3B238F610E828B5400846E11 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; 40899F4A0FFA71BC000B29AE /* Build configuration list for PBXNativeTarget "gtest_unittest-framework" */ = { isa = XCConfigurationList; buildConfigurations = ( 40899F450FFA7185000B29AE /* Debug */, 40899F460FFA7185000B29AE /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; 4089A0240FFACF01000B29AE /* Build configuration list for PBXNativeTarget "sample1_unittest-framework" */ = { isa = XCConfigurationList; buildConfigurations = ( 4089A0150FFACEFD000B29AE /* Debug */, 4089A0160FFACEFD000B29AE /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; 40C44AE40E379905008FCC51 /* Build configuration list for PBXAggregateTarget "Version Info" */ = { isa = XCConfigurationList; buildConfigurations = ( 40C44ADF0E3798F4008FCC51 /* Debug */, 40C44AE00E3798F4008FCC51 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; 40C84902101A212E0083642A /* Build configuration list for PBXNativeTarget "gtest-static" */ = { isa = XCConfigurationList; buildConfigurations = ( 40C848FB101A209D0083642A /* Debug */, 40C848FC101A209D0083642A /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; 40C84912101A21D20083642A /* Build configuration list for PBXNativeTarget "gtest_main-static" */ = { isa = XCConfigurationList; buildConfigurations = ( 40C8490E101A217F0083642A /* Debug */, 40C8490F101A217F0083642A /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; 40C84984101A36850083642A /* Build configuration list for PBXNativeTarget "gtest_unittest-static" */ = { isa = XCConfigurationList; buildConfigurations = ( 40C84985101A36850083642A /* Debug */, 40C84986101A36850083642A /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; 40C84994101A36A60083642A /* Build configuration list for PBXNativeTarget "sample1_unittest-static" */ = { isa = XCConfigurationList; buildConfigurations = ( 40C84995101A36A60083642A /* Debug */, 40C84996101A36A60083642A /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; 4FADC24208B4156D00ABE55E /* Build configuration list for PBXNativeTarget "gtest-framework" */ = { isa = XCConfigurationList; buildConfigurations = ( 4FADC24308B4156D00ABE55E /* Debug */, 4FADC24408B4156D00ABE55E /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; 4FADC24608B4156D00ABE55E /* Build configuration list for PBXProject "gtest" */ = { isa = XCConfigurationList; buildConfigurations = ( 4FADC24708B4156D00ABE55E /* Debug */, 4FADC24808B4156D00ABE55E /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; /* End XCConfigurationList section */ }; rootObject = 0867D690FE84028FC02AAC07 /* Project object */; } dlt-daemon-2.18.4/include/000077500000000000000000000000001353342203500152555ustar00rootroot00000000000000dlt-daemon-2.18.4/include/CMakeLists.txt000066400000000000000000000007021353342203500200140ustar00rootroot00000000000000####### # SPDX license identifier: MPL-2.0 # # Copyright (C) 2011-2015, BMW AG # # This file is part of GENIVI Project DLT - Diagnostic Log and Trace. # # This Source Code Form is subject to the terms of the # Mozilla Public License (MPL), v. 2.0. # If a copy of the MPL was not distributed with this file, # You can obtain one at http://mozilla.org/MPL/2.0/. # # For further information see http://www.genivi.org/. ####### ADD_SUBDIRECTORY( dlt ) dlt-daemon-2.18.4/include/dlt/000077500000000000000000000000001353342203500160405ustar00rootroot00000000000000dlt-daemon-2.18.4/include/dlt/CMakeLists.txt000066400000000000000000000015561353342203500206070ustar00rootroot00000000000000####### # SPDX license identifier: MPL-2.0 # # Copyright (C) 2011-2015, BMW AG # # This file is part of GENIVI Project DLT - Diagnostic Log and Trace. # # This Source Code Form is subject to the terms of the # Mozilla Public License (MPL), v. 2.0. # If a copy of the MPL was not distributed with this file, # You can obtain one at http://mozilla.org/MPL/2.0/. # # For further information see http://www.genivi.org/. ####### install(FILES dlt.h dlt_user.h dlt_user_macros.h dlt_client.h dlt_protocol.h dlt_common.h dlt_types.h dlt_shm.h dlt_offline_trace.h dlt_filetransfer.h dlt_common_api.h ${PROJECT_BINARY_DIR}/include/dlt/dlt_version.h DESTINATION include/dlt COMPONENT devel) if(WITH_DLT_CXX11_EXT) install(FILES dlt_cpp_extension.hpp DESTINATION include/dlt COMPONENT devel) endif() dlt-daemon-2.18.4/include/dlt/dlt.h000066400000000000000000000067211353342203500170020ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2011-2015, BMW AG * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author Alexander Wenzel * * \copyright Copyright © 2011-2015 BMW AG. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file dlt.h */ /******************************************************************************* ** ** ** SRC-MODULE: dlt.h ** ** ** ** TARGET : linux ** ** ** ** PROJECT : DLT ** ** ** ** AUTHOR : Alexander Wenzel Alexander.AW.Wenzel@bmw.de ** ** Markus Klein ** ** ** ** PURPOSE : ** ** ** ** REMARKS : ** ** ** ** PLATFORM DEPENDANT [yes/no]: yes ** ** ** ** TO BE CHANGED BY USER [yes/no]: no ** ** ** *******************************************************************************/ /******************************************************************************* ** Author Identity ** ******************************************************************************** ** ** ** Initials Name Company ** ** -------- ------------------------- ---------------------------------- ** ** aw Alexander Wenzel BMW ** ** mk Markus Klein Fraunhofer ESK ** *******************************************************************************/ /******************************************************************************* ** Revision Control History ** *******************************************************************************/ /* * $LastChangedRevision: 1670 $ * $LastChangedDate: 2011-04-08 15:12:06 +0200 (Fr, 08. Apr 2011) $ * $LastChangedBy$ * Initials Date Comment * aw 13.01.2010 initial */ #ifndef DLT_H #define DLT_H #include "dlt_common.h" #include "dlt_user.h" #endif /* DLT_H */ dlt-daemon-2.18.4/include/dlt/dlt_client.h000066400000000000000000000276421353342203500203450ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2011-2015, BMW AG * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author Alexander Wenzel * * \copyright Copyright © 2011-2015 BMW AG. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file dlt_client.h */ /******************************************************************************* ** ** ** SRC-MODULE: dlt_client.h ** ** ** ** TARGET : linux ** ** ** ** PROJECT : DLT ** ** ** ** AUTHOR : Alexander Wenzel Alexander.AW.Wenzel@bmw.de ** ** Markus Klein ** ** ** ** PURPOSE : ** ** ** ** REMARKS : ** ** ** ** PLATFORM DEPENDANT [yes/no]: yes ** ** ** ** TO BE CHANGED BY USER [yes/no]: no ** ** ** *******************************************************************************/ /******************************************************************************* ** Author Identity ** ******************************************************************************** ** ** ** Initials Name Company ** ** -------- ------------------------- ---------------------------------- ** ** aw Alexander Wenzel BMW ** ** mk Markus Klein Fraunhofer ESK ** *******************************************************************************/ /******************************************************************************* ** Revision Control History ** *******************************************************************************/ /* * $LastChangedRevision$ * $LastChangedDate$ * $LastChangedBy$ */ #ifndef DLT_CLIENT_H # define DLT_CLIENT_H /** * \defgroup clientapi DLT Client API * \addtogroup clientapi \{ */ # include "dlt_types.h" # include "dlt_common.h" typedef enum { DLT_CLIENT_MODE_UNDEFINED = -1, DLT_CLIENT_MODE_TCP, DLT_CLIENT_MODE_SERIAL, DLT_CLIENT_MODE_UNIX } DltClientMode; typedef struct { DltReceiver receiver; /**< receiver pointer to dlt receiver structure */ int sock; /**< sock Connection handle/socket */ char *servIP; /**< servIP IP adress/Hostname of TCP/IP interface */ int port; /**< Port for TCP connections (optional) */ char *serialDevice; /**< serialDevice Devicename of serial device */ char *socketPath; /**< socketPath Unix socket path */ char ecuid[4]; /**< ECUiD */ speed_t baudrate; /**< baudrate Baudrate of serial interface, as speed_t */ DltClientMode mode; /**< mode DltClientMode */ } DltClient; # ifdef __cplusplus extern "C" { # endif void dlt_client_register_message_callback(int (*registerd_callback)(DltMessage *message, void *data)); /** * Initialising dlt client structure with a specific port * @param client pointer to dlt client structure * @param port The port for the tcp connection * @param verbose if set to true verbose information is printed out. * @return negative value if there was an error */ int dlt_client_init_port(DltClient *client, int port, int verbose); /** * Initialising dlt client structure * @param client pointer to dlt client structure * @param verbose if set to true verbose information is printed out. * @return Value from DltReturnValue enum */ DltReturnValue dlt_client_init(DltClient *client, int verbose); /** * Connect to dlt daemon using the information from the dlt client structure * @param client pointer to dlt client structure * @param verbose if set to true verbose information is printed out. * @return Value from DltReturnValue enum */ DltReturnValue dlt_client_connect(DltClient *client, int verbose); /** * Cleanup dlt client structure * @param client pointer to dlt client structure * @param verbose if set to true verbose information is printed out. * @return Value from DltReturnValue enum */ DltReturnValue dlt_client_cleanup(DltClient *client, int verbose); /** * Main Loop of dlt client application * @param client pointer to dlt client structure * @param data pointer to data to be provided to the main loop * @param verbose if set to true verbose information is printed out. * @return Value from DltReturnValue enum */ DltReturnValue dlt_client_main_loop(DltClient *client, void *data, int verbose); /** * Send ancontrol message to the dlt daemon * @param client pointer to dlt client structure * @param apid application id * @param ctid context id * @param payload Buffer filled with control message data * @param size Size of control message data * @return Value from DltReturnValue enum */ DltReturnValue dlt_client_send_ctrl_msg(DltClient *client, char *apid, char *ctid, uint8_t *payload, uint32_t size); /** * Send an injection message to the dlt daemon * @param client pointer to dlt client structure * @param apid application id * @param ctid context id * @param serviceID service id * @param buffer Buffer filled with injection message data * @param size Size of injection data within buffer * @return Value from DltReturnValue enum */ DltReturnValue dlt_client_send_inject_msg(DltClient *client, char *apid, char *ctid, uint32_t serviceID, uint8_t *buffer, uint32_t size); /** * Send an set log level message to the dlt daemon * @param client pointer to dlt client structure * @param apid application id * @param ctid context id * @param logLevel Log Level * @return Value from DltReturnValue enum */ DltReturnValue dlt_client_send_log_level(DltClient *client, char *apid, char *ctid, uint8_t logLevel); /** * Send an request to get log info message to the dlt daemon * @param client pointer to dlt client structure * @return negative value if there was an error */ int dlt_client_get_log_info(DltClient *client); /** * Send an request to get default log level to the dlt daemon * @param client pointer to dlt client structure * @return negative value if there was an error */ DltReturnValue dlt_client_get_default_log_level(DltClient *client); /** * Send an request to get software version to the dlt daemon * @param client pointer to dlt client structure * @return negative value if there was an error */ int dlt_client_get_software_version(DltClient *client); /** * Initialise get log info structure * @return void */ void dlt_getloginfo_init(void); /** * To free the memory allocated for app description in get log info * @return void */ void dlt_getloginfo_free(void); /** * Send a set trace status message to the dlt daemon * @param client pointer to dlt client structure * @param apid application id * @param ctid context id * @param traceStatus Default Trace Status * @return Value from DltReturnValue enum */ DltReturnValue dlt_client_send_trace_status(DltClient *client, char *apid, char *ctid, uint8_t traceStatus); /** * Send the default log level to the dlt daemon * @param client pointer to dlt client structure * @param defaultLogLevel Default Log Level * @return Value from DltReturnValue enum */ DltReturnValue dlt_client_send_default_log_level(DltClient *client, uint8_t defaultLogLevel); /** * Send the log level to all contexts registered with dlt daemon * @param client pointer to dlt client structure * @param LogLevel Log Level to be set * @return Value from DltReturnValue enum */ DltReturnValue dlt_client_send_all_log_level(DltClient *client, uint8_t LogLevel); /** * Send the default trace status to the dlt daemon * @param client pointer to dlt client structure * @param defaultTraceStatus Default Trace Status * @return Value from DltReturnValue enum */ DltReturnValue dlt_client_send_default_trace_status(DltClient *client, uint8_t defaultTraceStatus); /** * Send the trace status to all contexts registered with dlt daemon * @param client pointer to dlt client structure * @param traceStatus trace status to be set * @return Value from DltReturnValue enum */ DltReturnValue dlt_client_send_all_trace_status(DltClient *client, uint8_t traceStatus); /** * Send the timing pakets status to the dlt daemon * @param client pointer to dlt client structure * @param timingPakets Timing pakets enabled * @return Value from DltReturnValue enum */ DltReturnValue dlt_client_send_timing_pakets(DltClient *client, uint8_t timingPakets); /** * Send the store config command to the dlt daemon * @param client pointer to dlt client structure * @return Value from DltReturnValue enum */ DltReturnValue dlt_client_send_store_config(DltClient *client); /** * Send the reset to factory default command to the dlt daemon * @param client pointer to dlt client structure * @return Value from DltReturnValue enum */ DltReturnValue dlt_client_send_reset_to_factory_default(DltClient *client); /** * Set baudrate within dlt client structure * @param client pointer to dlt client structure * @param baudrate Baudrate * @return Value from DltReturnValue enum */ DltReturnValue dlt_client_setbaudrate(DltClient *client, int baudrate); /** * Set server ip * @param client pointer to dlt client structure * @param ipaddr pointer to command line argument * @return negative value if there was an error */ int dlt_client_set_server_ip(DltClient *client, char *ipaddr); /** * Set serial device * @param client pointer to dlt client structure * @param serial_device pointer to command line argument * @return negative value if there was an error */ int dlt_client_set_serial_device(DltClient *client, char *serial_device); /** * Set socket path * @param client pointer to dlt client structure * @param socket_path pointer to socket path string * @return negative value if there was an error */ int dlt_client_set_socket_path(DltClient *client, char *socket_path); /** * Parse GET_LOG_INFO response text * @param resp GET_LOG_INFO response * @param resp_text response text represented by ASCII * @return Value from DltReturnValue enum */ DltReturnValue dlt_client_parse_get_log_info_resp_text(DltServiceGetLogInfoResponse *resp, char *resp_text); /** * Free memory allocated for get log info message * @param resp response * @return 0 on success, -1 otherwise */ int dlt_client_cleanup_get_log_info(DltServiceGetLogInfoResponse *resp); # ifdef __cplusplus } # endif /** \} */ #endif /* DLT_CLIENT_H */ dlt-daemon-2.18.4/include/dlt/dlt_common.h000066400000000000000000001630761353342203500203610ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2011-2015, BMW AG * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author Alexander Wenzel * * \copyright Copyright © 2011-2015 BMW AG. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file dlt_common.h */ /******************************************************************************* ** ** ** SRC-MODULE: dlt_common.h ** ** ** ** TARGET : linux ** ** ** ** PROJECT : DLT ** ** ** ** AUTHOR : Alexander Wenzel Alexander.AW.Wenzel@bmw.de ** ** Markus Klein ** ** ** ** PURPOSE : ** ** ** ** REMARKS : ** ** ** ** PLATFORM DEPENDANT [yes/no]: yes ** ** ** ** TO BE CHANGED BY USER [yes/no]: no ** ** ** *******************************************************************************/ /******************************************************************************* ** Author Identity ** ******************************************************************************** ** ** ** Initials Name Company ** ** -------- ------------------------- ---------------------------------- ** ** aw Alexander Wenzel BMW ** ** mk Markus Klein Fraunhofer ESK ** *******************************************************************************/ /******************************************************************************* ** Revision Control History ** *******************************************************************************/ /* * $LastChangedRevision: 1670 $ * $LastChangedDate: 2011-04-08 15:12:06 +0200 (Fr, 08. Apr 2011) $ * $LastChangedBy$ * Initials Date Comment * aw 13.01.2010 initial */ #ifndef DLT_COMMON_H # define DLT_COMMON_H /** * \defgroup commonapi DLT Common API * \addtogroup commonapi \{ */ # include # include # ifdef __linux__ # include # else # include # endif # if !defined(_MSC_VER) # include # include # endif # if !defined (__WIN32__) && !defined(_MSC_VER) # include # endif # include "dlt_types.h" # include "dlt_protocol.h" # if !defined (PACKED) # define PACKED __attribute__((aligned(1), packed)) # endif # if defined (__MSDOS__) || defined (_MSC_VER) /* set instead /Zp8 flag in Visual C++ configuration */ # undef PACKED # define PACKED # endif /* * Macros to swap the byte order. */ # define DLT_SWAP_64(value) ((((uint64_t)DLT_SWAP_32((value) & 0xffffffffull)) << 32) | (DLT_SWAP_32((value) >> 32))) # define DLT_SWAP_16(value) ((((value) >> 8) & 0xff) | (((value) << 8) & 0xff00)) # define DLT_SWAP_32(value) ((((value) >> 24) & 0xff) | (((value) << 8) & 0xff0000) | (((value) >> 8) & 0xff00) | \ (((value) << 24) & 0xff000000)) /* Set Big Endian and Little Endian to a initial value, if not defined */ # if !defined __USE_BSD # ifndef LITTLE_ENDIAN # define LITTLE_ENDIAN 1234 # endif # ifndef BIG_ENDIAN # define BIG_ENDIAN 4321 # endif # endif /* __USE_BSD */ /* If byte order is not defined, default to little endian */ # if !defined __USE_BSD # ifndef BYTE_ORDER # define BYTE_ORDER LITTLE_ENDIAN # endif # endif /* __USE_BSD */ /* Check for byte-order */ # if (BYTE_ORDER == BIG_ENDIAN) /* #warning "Big Endian Architecture!" */ # define DLT_HTOBE_16(x) ((x)) # define DLT_HTOLE_16(x) DLT_SWAP_16((x)) # define DLT_BETOH_16(x) ((x)) # define DLT_LETOH_16(x) DLT_SWAP_16((x)) # define DLT_HTOBE_32(x) ((x)) # define DLT_HTOLE_32(x) DLT_SWAP_32((x)) # define DLT_BETOH_32(x) ((x)) # define DLT_LETOH_32(x) DLT_SWAP_32((x)) # define DLT_HTOBE_64(x) ((x)) # define DLT_HTOLE_64(x) DLT_SWAP_64((x)) # define DLT_BETOH_64(x) ((x)) # define DLT_LETOH_64(x) DLT_SWAP_64((x)) # else /* #warning "Litte Endian Architecture!" */ # define DLT_HTOBE_16(x) DLT_SWAP_16((x)) # define DLT_HTOLE_16(x) ((x)) # define DLT_BETOH_16(x) DLT_SWAP_16((x)) # define DLT_LETOH_16(x) ((x)) # define DLT_HTOBE_32(x) DLT_SWAP_32((x)) # define DLT_HTOLE_32(x) ((x)) # define DLT_BETOH_32(x) DLT_SWAP_32((x)) # define DLT_LETOH_32(x) ((x)) # define DLT_HTOBE_64(x) DLT_SWAP_64((x)) # define DLT_HTOLE_64(x) ((x)) # define DLT_BETOH_64(x) DLT_SWAP_64((x)) # define DLT_LETOH_64(x) ((x)) # endif # define DLT_ENDIAN_GET_16(htyp, x) ((((htyp) & DLT_HTYP_MSBF) > 0) ? DLT_BETOH_16(x) : DLT_LETOH_16(x)) # define DLT_ENDIAN_GET_32(htyp, x) ((((htyp) & DLT_HTYP_MSBF) > 0) ? DLT_BETOH_32(x) : DLT_LETOH_32(x)) # define DLT_ENDIAN_GET_64(htyp, x) ((((htyp) & DLT_HTYP_MSBF) > 0) ? DLT_BETOH_64(x) : DLT_LETOH_64(x)) # if defined (__WIN32__) || defined (_MSC_VER) # define LOG_EMERG 0 # define LOG_ALERT 1 # define LOG_CRIT 2 # define LOG_ERR 3 # define LOG_WARNING 4 # define LOG_NOTICE 5 # define LOG_INFO 6 # define LOG_DEBUG 7 # define LOG_PID 0x01 # define LOG_DAEMON (3 << 3) # endif enum { DLT_LOG_TO_CONSOLE = 0, DLT_LOG_TO_SYSLOG = 1, DLT_LOG_TO_FILE = 2, DLT_LOG_DROPPED = 3 }; /** * The standard TCP Port used for DLT daemon, can be overwritten via -p \ when starting dlt-daemon */ # define DLT_DAEMON_TCP_PORT 3490 /* Initial value for file descriptor */ # define DLT_FD_INIT -1 /* Minimum value for a file descriptor except the POSIX Standards: stdin=0, stdout=1, stderr=2 */ # define DLT_FD_MINIMUM 3 /** * The size of a DLT ID */ # define DLT_ID_SIZE 4 # define DLT_SIZE_WEID DLT_ID_SIZE # define DLT_SIZE_WSID (sizeof(uint32_t)) # define DLT_SIZE_WTMS (sizeof(uint32_t)) /** * Definitions for GET_LOG_INFO */ # define DLT_GET_LOG_INFO_HEADER 18 /*Get log info header size in response text */ # define GET_LOG_INFO_LENGTH 13 # define SERVICE_OPT_LENGTH 3 /* checks if received size is big enough for expected data */ # define DLT_CHECK_RCV_DATA_SIZE(received, required) \ ({ \ int _ret = DLT_RETURN_OK; \ if (((int)received - (int)required) < 0) { \ dlt_vlog(LOG_WARNING, "%s: Received data not complete\n", __func__); \ _ret = DLT_RETURN_ERROR; \ } \ _ret; \ }) /** * Get the size of extra header parameters, depends on htyp. */ # define DLT_STANDARD_HEADER_EXTRA_SIZE(htyp) ((DLT_IS_HTYP_WEID(htyp) ? DLT_SIZE_WEID : 0) + \ (DLT_IS_HTYP_WSID(htyp) ? DLT_SIZE_WSID : 0) + \ (DLT_IS_HTYP_WTMS(htyp) ? DLT_SIZE_WTMS : 0)) # if defined (__MSDOS__) || defined (_MSC_VER) # define __func__ __FUNCTION__ # endif # define PRINT_FUNCTION_VERBOSE(_verbose) \ { \ if (_verbose) \ { \ dlt_vlog(LOG_INFO, "%s()\n", __func__); \ } \ } # ifndef NULL # define NULL (char *)0 # endif # define DLT_MSG_IS_CONTROL(MSG) ((DLT_IS_HTYP_UEH((MSG)->standardheader->htyp)) && \ (DLT_GET_MSIN_MSTP((MSG)->extendedheader->msin) == DLT_TYPE_CONTROL)) # define DLT_MSG_IS_CONTROL_REQUEST(MSG) ((DLT_IS_HTYP_UEH((MSG)->standardheader->htyp)) && \ (DLT_GET_MSIN_MSTP((MSG)->extendedheader->msin) == DLT_TYPE_CONTROL) && \ (DLT_GET_MSIN_MTIN((MSG)->extendedheader->msin) == DLT_CONTROL_REQUEST)) # define DLT_MSG_IS_CONTROL_RESPONSE(MSG) ((DLT_IS_HTYP_UEH((MSG)->standardheader->htyp)) && \ (DLT_GET_MSIN_MSTP((MSG)->extendedheader->msin) == DLT_TYPE_CONTROL) && \ (DLT_GET_MSIN_MTIN((MSG)->extendedheader->msin) == DLT_CONTROL_RESPONSE)) # define DLT_MSG_IS_CONTROL_TIME(MSG) ((DLT_IS_HTYP_UEH((MSG)->standardheader->htyp)) && \ (DLT_GET_MSIN_MSTP((MSG)->extendedheader->msin) == DLT_TYPE_CONTROL) && \ (DLT_GET_MSIN_MTIN((MSG)->extendedheader->msin) == DLT_CONTROL_TIME)) # define DLT_MSG_IS_NW_TRACE(MSG) ((DLT_IS_HTYP_UEH((MSG)->standardheader->htyp)) && \ (DLT_GET_MSIN_MSTP((MSG)->extendedheader->msin) == DLT_TYPE_NW_TRACE)) # define DLT_MSG_IS_TRACE_MOST(MSG) ((DLT_IS_HTYP_UEH((MSG)->standardheader->htyp)) && \ (DLT_GET_MSIN_MSTP((MSG)->extendedheader->msin) == DLT_TYPE_NW_TRACE) && \ (DLT_GET_MSIN_MTIN((MSG)->extendedheader->msin) == DLT_NW_TRACE_MOST)) # define DLT_MSG_IS_NONVERBOSE(MSG) (!(DLT_IS_HTYP_UEH((MSG)->standardheader->htyp)) || \ ((DLT_IS_HTYP_UEH((MSG)->standardheader->htyp)) && \ (!(DLT_IS_MSIN_VERB((MSG)->extendedheader->msin))))) /* * * Definitions of DLT message buffer overflow */ # define DLT_MESSAGE_BUFFER_NO_OVERFLOW 0x00/**< Buffer overflow has not occured */ # define DLT_MESSAGE_BUFFER_OVERFLOW 0x01/**< Buffer overflow has occured */ /* * Definition of DLT output variants */ # define DLT_OUTPUT_HEX 1 # define DLT_OUTPUT_ASCII 2 # define DLT_OUTPUT_MIXED_FOR_PLAIN 3 # define DLT_OUTPUT_MIXED_FOR_HTML 4 # define DLT_OUTPUT_ASCII_LIMITED 5 # define DLT_FILTER_MAX 30 /**< Maximum number of filters */ # define DLT_MSG_READ_VALUE(dst, src, length, type) \ { \ if ((length < 0) || ((length) < ((int32_t)sizeof(type)))) \ { length = -1; } \ else \ { dst = *((type *)src); src += sizeof(type); length -= sizeof(type); } \ } # define DLT_MSG_READ_ID(dst, src, length) \ { \ if ((length < 0) || ((length) < DLT_ID_SIZE)) \ { length = -1; } \ else \ { memcpy(dst, src, DLT_ID_SIZE); src += DLT_ID_SIZE; length -= DLT_ID_SIZE; } \ } # define DLT_MSG_READ_STRING(dst, src, maxlength, length) \ { \ if (((maxlength) < 0) || ((length) < 0) || ((maxlength) < (length))) \ { maxlength = -1; } \ else \ { memcpy(dst, src, length); dlt_clean_string(dst, length); dst[length] = 0; \ src += length; maxlength -= length; } \ } # define DLT_MSG_READ_NULL(src, maxlength, length) \ { \ if (((maxlength) < 0) || ((length) < 0) || ((maxlength) < (length))) \ { length = -1; } \ else \ { src += length; maxlength -= length; } \ } # define DLT_HEADER_SHOW_NONE 0x0000 # define DLT_HEADER_SHOW_TIME 0x0001 # define DLT_HEADER_SHOW_TMSTP 0x0002 # define DLT_HEADER_SHOW_MSGCNT 0x0004 # define DLT_HEADER_SHOW_ECUID 0x0008 # define DLT_HEADER_SHOW_APID 0x0010 # define DLT_HEADER_SHOW_CTID 0x0020 # define DLT_HEADER_SHOW_MSGTYPE 0x0040 # define DLT_HEADER_SHOW_MSGSUBTYPE 0x0080 # define DLT_HEADER_SHOW_VNVSTATUS 0x0100 # define DLT_HEADER_SHOW_NOARG 0x0200 # define DLT_HEADER_SHOW_ALL 0xFFFF /* dlt_receiver_check_and_get flags */ # define DLT_RCV_NONE 0 # define DLT_RCV_SKIP_HEADER (1 << 0) # define DLT_RCV_REMOVE (1 << 1) /** * Maximal length of path in DLT * DLT limits the path length and does not do anything else to determine * the actual value, because the least that is supported on any system * that DLT runs on is 1024 bytes. */ # define DLT_PATH_MAX 1024 /** * Maximal length of mounted path */ # define DLT_MOUNT_PATH_MAX 1024 /** * Maximal length of an entry */ # define DLT_ENTRY_MAX 100 /** * Maximal IPC path len */ # define DLT_IPC_PATH_MAX 100 /** * Maximal receiver buffer size for application messages */ # define DLT_RECEIVE_BUFSIZE 65535 /** * Maximal line length */ # define DLT_LINE_LEN 1024 /** * Macros for network trace */ #define DLT_TRACE_NW_TRUNCATED "NWTR" #define DLT_TRACE_NW_START "NWST" #define DLT_TRACE_NW_SEGMENT "NWCH" #define DLT_TRACE_NW_END "NWEN" /** * Provision to test static function */ # ifndef DLT_UNIT_TESTS # define DLT_STATIC static # else # define DLT_STATIC # endif /** * Type to specify whether received data is from socket or file/fifo */ typedef enum { DLT_RECEIVE_SOCKET, DLT_RECEIVE_FD } DltReceiverType; /** * The definition of the serial header containing the characters "DLS" + 0x01. */ extern const char dltSerialHeader[DLT_ID_SIZE]; /** * The definition of the serial header containing the characters "DLS" + 0x01 as char. */ extern char dltSerialHeaderChar[DLT_ID_SIZE]; /** * The common base-path of the dlt-daemon-fifo and application-generated fifos */ extern char dltFifoBaseDir[DLT_PATH_MAX]; #ifdef DLT_SHM_ENABLE /** * The common name of the dlt-daemon and application share memory */ extern char dltShmName[NAME_MAX + 1]; #endif /** * The type of a DLT ID (context id, application id, etc.) */ typedef char ID4[DLT_ID_SIZE]; /** * The structure of the DLT file storage header. This header is used before each stored DLT message. */ typedef struct { char pattern[DLT_ID_SIZE]; /**< This pattern should be DLT0x01 */ uint32_t seconds; /**< seconds since 1.1.1970 */ int32_t microseconds; /**< Microseconds */ char ecu[DLT_ID_SIZE]; /**< The ECU id is added, if it is not already in the DLT message itself */ } PACKED DltStorageHeader; /** * The structure of the DLT standard header. This header is used in each DLT message. */ typedef struct { uint8_t htyp; /**< This parameter contains several informations, see definitions below */ uint8_t mcnt; /**< The message counter is increased with each sent DLT message */ uint16_t len; /**< Length of the complete message, without storage header */ } PACKED DltStandardHeader; /** * The structure of the DLT extra header parameters. Each parameter is sent only if enabled in htyp. */ typedef struct { char ecu[DLT_ID_SIZE]; /**< ECU id */ uint32_t seid; /**< Session number */ uint32_t tmsp; /**< Timestamp since system start in 0.1 milliseconds */ } PACKED DltStandardHeaderExtra; /** * The structure of the DLT extended header. This header is only sent if enabled in htyp parameter. */ typedef struct { uint8_t msin; /**< messsage info */ uint8_t noar; /**< number of arguments */ char apid[DLT_ID_SIZE]; /**< application id */ char ctid[DLT_ID_SIZE]; /**< context id */ } PACKED DltExtendedHeader; /** * The structure to organise the DLT messages. * This structure is used by the corresponding functions. */ typedef struct sDltMessage { /* flags */ int8_t found_serialheader; /* offsets */ int32_t resync_offset; /* size parameters */ int32_t headersize; /**< size of complete header including storage header */ int32_t datasize; /**< size of complete payload */ /* buffer for current loaded message */ uint8_t headerbuffer[sizeof(DltStorageHeader) + sizeof(DltStandardHeader) + sizeof(DltStandardHeaderExtra) + sizeof(DltExtendedHeader)]; /**< buffer for loading complete header */ uint8_t *databuffer; /**< buffer for loading payload */ int32_t databuffersize; /* header values of current loaded message */ DltStorageHeader *storageheader; /**< pointer to storage header of current loaded header */ DltStandardHeader *standardheader; /**< pointer to standard header of current loaded header */ DltStandardHeaderExtra headerextra; /**< extra parameters of current loaded header */ DltExtendedHeader *extendedheader; /**< pointer to extended of current loaded header */ } DltMessage; /** * The structure of the DLT Service Get Log Info. */ typedef struct { uint32_t service_id; /**< service ID */ uint8_t options; /**< type of request */ char apid[DLT_ID_SIZE]; /**< application id */ char ctid[DLT_ID_SIZE]; /**< context id */ char com[DLT_ID_SIZE]; /**< communication interface */ } PACKED DltServiceGetLogInfoRequest; typedef struct { uint32_t service_id; /**< service ID */ } PACKED DltServiceGetDefaultLogLevelRequest; /** * The structure of the DLT Service Get Log Info response. */ typedef struct { char context_id[DLT_ID_SIZE]; int16_t log_level; int16_t trace_status; uint16_t len_context_description; char *context_description; } ContextIDsInfoType; typedef struct { char app_id[DLT_ID_SIZE]; uint16_t count_context_ids; ContextIDsInfoType *context_id_info; /**< holds info about a specific con id */ uint16_t len_app_description; char *app_description; } AppIDsType; typedef struct { uint16_t count_app_ids; AppIDsType *app_ids; /**< holds info about a specific app id */ } LogInfoType; typedef struct { uint32_t service_id; /**< service ID */ uint8_t status; /**< type of request */ LogInfoType log_info_type; /**< log info type */ char com[DLT_ID_SIZE]; /**< communication interface */ } DltServiceGetLogInfoResponse; /** * The structure of the DLT Service Set Log Level. */ typedef struct { uint32_t service_id; /**< service ID */ char apid[DLT_ID_SIZE]; /**< application id */ char ctid[DLT_ID_SIZE]; /**< context id */ uint8_t log_level; /**< log level to be set */ char com[DLT_ID_SIZE]; /**< communication interface */ } PACKED DltServiceSetLogLevel; /** * The structure of the DLT Service Set Default Log Level. */ typedef struct { uint32_t service_id; /**< service ID */ uint8_t log_level; /**< default log level to be set */ char com[DLT_ID_SIZE]; /**< communication interface */ } PACKED DltServiceSetDefaultLogLevel; /** * The structure of the DLT Service Set Verbose Mode */ typedef struct { uint32_t service_id; /**< service ID */ uint8_t new_status; /**< new status to be set */ } PACKED DltServiceSetVerboseMode; /** * The structure of the DLT Service Set Communication Interface Status */ typedef struct { uint32_t service_id; /**< service ID */ char com[DLT_ID_SIZE]; /**< communication interface */ uint8_t new_status; /**< new status to be set */ } PACKED DltServiceSetCommunicationInterfaceStatus; /** * The structure of the DLT Service Set Communication Maximum Bandwidth */ typedef struct { uint32_t service_id; /**< service ID */ char com[DLT_ID_SIZE]; /**< communication interface */ uint32_t max_bandwidth; /**< maximum bandwith */ } PACKED DltServiceSetCommunicationMaximumBandwidth; typedef struct { uint32_t service_id; /**< service ID */ uint8_t status; /**< reponse status */ } PACKED DltServiceResponse; typedef struct { uint32_t service_id; /**< service ID */ uint8_t status; /**< reponse status */ uint8_t log_level; /**< log level */ } PACKED DltServiceGetDefaultLogLevelResponse; typedef struct { uint32_t service_id; /**< service ID */ uint8_t status; /**< reponse status */ uint8_t overflow; /**< overflow status */ uint32_t overflow_counter; /**< overflow counter */ } PACKED DltServiceMessageBufferOverflowResponse; typedef struct { uint32_t service_id; /**< service ID */ } PACKED DltServiceGetSoftwareVersion; typedef struct { uint32_t service_id; /**< service ID */ uint8_t status; /**< reponse status */ uint32_t length; /**< length of following payload */ /*char [] payload;*/ } PACKED DltServiceGetSoftwareVersionResponse; /** * The structure of the DLT Service Unregister Context. */ typedef struct { uint32_t service_id; /**< service ID */ uint8_t status; /**< reponse status */ char apid[DLT_ID_SIZE]; /**< application id */ char ctid[DLT_ID_SIZE]; /**< context id */ char comid[DLT_ID_SIZE]; /**< communication interface */ } PACKED DltServiceUnregisterContext; /** * The structure of the DLT Service Connection Info */ typedef struct { uint32_t service_id; /**< service ID */ uint8_t status; /**< reponse status */ uint8_t state; /**< new state */ char comid[DLT_ID_SIZE]; /**< communication interface */ } PACKED DltServiceConnectionInfo; /** * The structure of the DLT Service Timezone */ typedef struct { uint32_t service_id; /**< service ID */ uint8_t status; /**< reponse status */ int32_t timezone; /**< Timezone in seconds */ uint8_t isdst; /**< Is daylight saving time */ } PACKED DltServiceTimezone; /** * The structure of the DLT Service Marker */ typedef struct { uint32_t service_id; /**< service ID */ uint8_t status; /**< reponse status */ } PACKED DltServiceMarker; /*** * The structure of the DLT Service Offline Logstorage */ typedef struct { uint32_t service_id; /**< service ID */ char mount_point[DLT_MOUNT_PATH_MAX]; /**< storage device mount point */ uint8_t connection_type; /**< connection status of the connected device connected/disconnected */ char comid[DLT_ID_SIZE]; /**< communication interface */ } PACKED DltServiceOfflineLogstorage; /** * The structure of DLT Service Get Filter Config */ typedef struct { uint32_t service_id; /**< service ID */ uint8_t status; /**< response status */ char name[DLT_ENTRY_MAX]; /**< config name */ uint32_t level; /**< filter level */ uint32_t client_mask; /**< client mask */ uint32_t ctrl_mask; /**< control message mask */ char injections[DLT_ENTRY_MAX]; /**< list of injections */ } PACKED DltServiceGetCurrentFilterInfo; /** * The structure of DLT Service Passive Node Connect */ typedef struct { uint32_t service_id; /**< service ID */ uint32_t connection_status; /**< connect/disconnect */ char node_id[DLT_ID_SIZE]; /**< passive node ID */ } PACKED DltServicePassiveNodeConnect; /** * The structure of DLT Service Passive Node Connection Status */ typedef struct { uint32_t service_id; /**< service ID */ uint8_t status; /**< response status */ uint32_t num_connections; /**< number of connections */ uint8_t connection_status[DLT_ENTRY_MAX]; /**< list of connection status */ char node_id[DLT_ENTRY_MAX]; /**< list of passive node IDs */ } PACKED DltServicePassiveNodeConnectionInfo; /** * Structure to store filter parameters. * ID are maximal four characters. Unused values are filled with zeros. * If every value as filter is valid, the id should be empty by having only zero values. */ typedef struct { char apid[DLT_FILTER_MAX][DLT_ID_SIZE]; /**< application id */ char ctid[DLT_FILTER_MAX][DLT_ID_SIZE]; /**< context id */ int counter; /**< number of filters */ } DltFilter; /** * The structure to organise the access to DLT files. * This structure is used by the corresponding functions. */ typedef struct sDltFile { /* file handle and index for fast access */ FILE *handle; /**< file handle of opened DLT file */ long *index; /**< file positions of all DLT messages for fast access to file, only filtered messages */ /* size parameters */ int32_t counter; /**< number of messages in DLT file with filter */ int32_t counter_total; /**< number of messages in DLT file without filter */ int32_t position; /**< current index to message parsed in DLT file starting at 0 */ long file_length; /**< length of the file */ long file_position; /**< current position in the file */ /* error counters */ int32_t error_messages; /**< number of incomplete DLT messages found during file parsing */ /* filter parameters */ DltFilter *filter; /**< pointer to filter list. Zero if no filter is set. */ int32_t filter_counter; /**< number of filter set */ /* current loaded message */ DltMessage msg; /**< pointer to message */ } DltFile; /** * The structure is used to organise the receiving of data * including buffer handling. * This structure is used by the corresponding functions. */ typedef struct { int32_t lastBytesRcvd; /**< bytes received in last receive call */ int32_t bytesRcvd; /**< received bytes */ int32_t totalBytesRcvd; /**< total number of received bytes */ char *buffer; /**< pointer to receiver buffer */ char *buf; /**< pointer to position within receiver buffer */ char *backup_buf; /** pointer to the buffer with partial messages if any **/ int fd; /**< connection handle */ int32_t buffersize; /**< size of receiver buffer */ } DltReceiver; typedef struct { unsigned char *shm; /* pointer to beginning of shared memory */ int size; /* size of data area in shared memory */ unsigned char *mem; /* pointer to data area in shared memory */ uint32_t min_size; /**< Minimum size of buffer */ uint32_t max_size; /**< Maximum size of buffer */ uint32_t step_size; /**< Step size of buffer */ } DltBuffer; typedef struct { int write; int read; int count; } DltBufferHead; # define DLT_BUFFER_HEAD "SHM" typedef struct { char head[4]; unsigned char status; int size; } DltBufferBlockHead; # ifdef DLT_USE_IPv6 # define DLT_IP_SIZE (INET6_ADDRSTRLEN) # else # define DLT_IP_SIZE (INET_ADDRSTRLEN) # endif typedef struct DltBindAddress { char ip[DLT_IP_SIZE]; struct DltBindAddress *next; } DltBindAddress_t; # define DLT_MESSAGE_ERROR_OK 0 # define DLT_MESSAGE_ERROR_UNKNOWN -1 # define DLT_MESSAGE_ERROR_SIZE -2 # define DLT_MESSAGE_ERROR_CONTENT -3 # ifdef __cplusplus extern "C" { # endif /** * Helper function to print a byte array in hex. * @param ptr pointer to the byte array. * @param size number of bytes to be printed. */ void dlt_print_hex(uint8_t *ptr, int size); /** * Helper function to print a byte array in hex into a string. * @param text pointer to a ASCII string, in which the text is written * @param textlength maximal size of text buffer * @param ptr pointer to the byte array. * @param size number of bytes to be printed. * @return negative value if there was an error */ DltReturnValue dlt_print_hex_string(char *text, int textlength, uint8_t *ptr, int size); /** * Helper function to print a byte array in hex and ascii into a string. * @param text pointer to a ASCII string, in which the text is written * @param textlength maximal size of text buffer * @param ptr pointer to the byte array. * @param size number of bytes to be printed. * @param html output is html? 0 - false, 1 - true * @return negative value if there was an error */ DltReturnValue dlt_print_mixed_string(char *text, int textlength, uint8_t *ptr, int size, int html); /** * Helper function to print a byte array in ascii into a string. * @param text pointer to a ASCII string, in which the text is written * @param textlength maximal size of text buffer * @param ptr pointer to the byte array. * @param size number of bytes to be printed. * @return negative value if there was an error */ DltReturnValue dlt_print_char_string(char **text, int textlength, uint8_t *ptr, int size); /** * Helper function to print an id. * @param text pointer to ASCII string where to write the id * @param id four byte char array as used in DLT mesages as IDs. */ void dlt_print_id(char *text, const char *id); /** * Helper function to set an ID parameter. * @param id four byte char array as used in DLT mesages as IDs. * @param text string to be copied into char array. */ void dlt_set_id(char *id, const char *text); /** * Helper function to remove not nice to print characters, e.g. NULL or carage return. * @param text pointer to string to be cleaned. * @param length length of string excluding terminating zero. */ void dlt_clean_string(char *text, int length); /** * Initialise the filter list. * This function must be called before using further dlt filter. * @param filter pointer to structure of organising DLT filter * @param verbose if set to true verbose information is printed out. * @return negative value if there was an error */ DltReturnValue dlt_filter_init(DltFilter *filter, int verbose); /** * Free the used memory by the organising structure of filter. * @param filter pointer to structure of organising DLT filter * @param verbose if set to true verbose information is printed out. * @return negative value if there was an error */ DltReturnValue dlt_filter_free(DltFilter *filter, int verbose); /** * Load filter list from file. * @param filter pointer to structure of organising DLT filter * @param filename filename to load filters from * @param verbose if set to true verbose information is printed out. * @return negative value if there was an error */ DltReturnValue dlt_filter_load(DltFilter *filter, const char *filename, int verbose); /** * Save filter list to file. * @param filter pointer to structure of organising DLT filter * @param filename filename to load filters from * @param verbose if set to true verbose information is printed out. * @return negative value if there was an error */ DltReturnValue dlt_filter_save(DltFilter *filter, const char *filename, int verbose); /** * Find index of filter in filter list * @param filter pointer to structure of organising DLT filter * @param apid application id to be found in filter list * @param ctid context id to be found in filter list * @param verbose if set to true verbose information is printed out. * @return negative value if there was an error (or not found), else return index of filter */ int dlt_filter_find(DltFilter *filter, const char *apid, const char *ctid, int verbose); /** * Add new filter to filter list. * @param filter pointer to structure of organising DLT filter * @param apid application id to be added to filter list (must always be set). * @param ctid context id to be added to filter list. empty equals don't care. * @param verbose if set to true verbose information is printed out. * @return negative value if there was an error */ DltReturnValue dlt_filter_add(DltFilter *filter, const char *apid, const char *ctid, int verbose); /** * Delete filter from filter list * @param filter pointer to structure of organising DLT filter * @param apid application id to be deleted from filter list * @param ctid context id to be deleted from filter list * @param verbose if set to true verbose information is printed out. * @return negative value if there was an error */ DltReturnValue dlt_filter_delete(DltFilter *filter, const char *apid, const char *ctid, int verbose); /** * Initialise the structure used to access a DLT message. * This function must be called before using further dlt_message functions. * @param msg pointer to structure of organising access to DLT messages * @param verbose if set to true verbose information is printed out. * @return negative value if there was an error */ DltReturnValue dlt_message_init(DltMessage *msg, int verbose); /** * Free the used memory by the organising structure of file. * @param msg pointer to structure of organising access to DLT messages * @param verbose if set to true verbose information is printed out. * @return negative value if there was an error */ DltReturnValue dlt_message_free(DltMessage *msg, int verbose); /** * Print Header into an ASCII string. * This function calls dlt_message_header_flags() with flags=DLT_HEADER_SHOW_ALL * @param msg pointer to structure of organising access to DLT messages * @param text pointer to a ASCII string, in which the header is written * @param textlength maximal size of text buffer * @param verbose if set to true verbose information is printed out. * @return negative value if there was an error */ DltReturnValue dlt_message_header(DltMessage *msg, char *text, int textlength, int verbose); /** * Print Header into an ASCII string, selective. * @param msg pointer to structure of organising access to DLT messages * @param text pointer to a ASCII string, in which the header is written * @param textlength maximal size of text buffer * @param flags select, bit-field to select, what should be printed (DLT_HEADER_SHOW_...) * @param verbose if set to true verbose information is printed out. * @return negative value if there was an error */ DltReturnValue dlt_message_header_flags(DltMessage *msg, char *text, int textlength, int flags, int verbose); /** * Print Payload into an ASCII string. * @param msg pointer to structure of organising access to DLT messages * @param text pointer to a ASCII string, in which the header is written * @param textlength maximal size of text buffer * @param type 1 = payload as hex, 2 = payload as ASCII. * @param verbose if set to true verbose information is printed out. * @return negative value if there was an error */ DltReturnValue dlt_message_payload(DltMessage *msg, char *text, int textlength, int type, int verbose); /** * Check if message is filtered or not. All filters are applied (logical OR). * @param msg pointer to structure of organising access to DLT messages * @param filter pointer to filter * @param verbose if set to true verbose information is printed out. * @return 1 = filter matches, 0 = filter does not match, negative value if there was an error */ DltReturnValue dlt_message_filter_check(DltMessage *msg, DltFilter *filter, int verbose); /** * Read message from memory buffer. * Message in buffer has no storage header. * @param msg pointer to structure of organising access to DLT messages * @param buffer pointer to memory buffer * @param length length of message in buffer * @param resync if set to true resync to serial header is enforced * @param verbose if set to true verbose information is printed out. * @return negative value if there was an error */ int dlt_message_read(DltMessage *msg, uint8_t *buffer, unsigned int length, int resync, int verbose); /** * Get standard header extra parameters * @param msg pointer to structure of organising access to DLT messages * @param verbose if set to true verbose information is printed out. * @return negative value if there was an error */ DltReturnValue dlt_message_get_extraparameters(DltMessage *msg, int verbose); /** * Set standard header extra parameters * @param msg pointer to structure of organising access to DLT messages * @param verbose if set to true verbose information is printed out. * @return negative value if there was an error */ DltReturnValue dlt_message_set_extraparameters(DltMessage *msg, int verbose); /** * Initialise the structure used to access a DLT file. * This function must be called before using further dlt_file functions. * @param file pointer to structure of organising access to DLT file * @param verbose if set to true verbose information is printed out. * @return negative value if there was an error */ DltReturnValue dlt_file_init(DltFile *file, int verbose); /** * Set a list to filters. * This function should be called before loading a DLT file, if filters should be used. * A filter list is an array of filters. Several filters are combined logically by or operation. * The filter list is not copied, so take care to keep list in memory. * @param file pointer to structure of organising access to DLT file * @param filter pointer to filter list array * @param verbose if set to true verbose information is printed out. * @return negative value if there was an error */ DltReturnValue dlt_file_set_filter(DltFile *file, DltFilter *filter, int verbose); /** * Initialising loading a DLT file. * @param file pointer to structure of organising access to DLT file * @param filename filename of DLT file * @param verbose if set to true verbose information is printed out. * @return negative value if there was an error */ DltReturnValue dlt_file_open(DltFile *file, const char *filename, int verbose); /** * Find next message in the DLT file and parse them. * This function finds the next message in the DLT file. * If a filter is set, the filter list is used. * @param file pointer to structure of organising access to DLT file * @param verbose if set to true verbose information is printed out. * @return 0 = message does not match filter, 1 = message was read, negative value if there was an error */ DltReturnValue dlt_file_read(DltFile *file, int verbose); /** * Find next message in the DLT file in RAW format (without storage header) and parse them. * This function finds the next message in the DLT file. * If a filter is set, the filter list is used. * @param file pointer to structure of organising access to DLT file * @param resync Resync to serial header when set to true * @param verbose if set to true verbose information is printed out. * @return 0 = message does not match filter, 1 = message was read, negative value if there was an error */ DltReturnValue dlt_file_read_raw(DltFile *file, int resync, int verbose); /** * Closing loading a DLT file. * @param file pointer to structure of organising access to DLT file * @param verbose if set to true verbose information is printed out. * @return negative value if there was an error */ DltReturnValue dlt_file_close(DltFile *file, int verbose); /** * Load standard header of a message from file * @param file pointer to structure of organising access to DLT file * @param verbose if set to true verbose information is printed out. * @return negative value if there was an error */ DltReturnValue dlt_file_read_header(DltFile *file, int verbose); /** * Load standard header of a message from file in RAW format (without storage header) * @param file pointer to structure of organising access to DLT file * @param resync Resync to serial header when set to true * @param verbose if set to true verbose information is printed out. * @return negative value if there was an error */ DltReturnValue dlt_file_read_header_raw(DltFile *file, int resync, int verbose); /** * Load, if available in message, extra standard header fields and * extended header of a message from file * (dlt_file_read_header() must have been called before this call!) * @param file pointer to structure of organising access to DLT file * @param verbose if set to true verbose information is printed out. * @return negative value if there was an error */ DltReturnValue dlt_file_read_header_extended(DltFile *file, int verbose); /** * Load payload of a message from file * (dlt_file_read_header() must have been called before this call!) * @param file pointer to structure of organising access to DLT file * @param verbose if set to true verbose information is printed out. * @return negative value if there was an error */ DltReturnValue dlt_file_read_data(DltFile *file, int verbose); /** * Load headers and payload of a message selected by the index. * If filters are set, index is based on the filtered list. * @param file pointer to structure of organising access to DLT file * @param index position of message in the files beginning from zero * @param verbose if set to true verbose information is printed out. * @return number of messages loaded, negative value if there was an error */ DltReturnValue dlt_file_message(DltFile *file, int index, int verbose); /** * Free the used memory by the organising structure of file. * @param file pointer to structure of organising access to DLT file * @param verbose if set to true verbose information is printed out. * @return negative value if there was an error */ DltReturnValue dlt_file_free(DltFile *file, int verbose); /** * Set internal logging filename if mode 2 * @param filename the filename */ void dlt_log_set_filename(const char *filename); /** * Set internal logging level * @param level the level */ void dlt_log_set_level(int level); /** * Initialize (external) logging facility * @param mode positive, 0 = log to stdout, 1 = log to syslog, 2 = log to file */ void dlt_log_init(int mode); /** * Log ASCII string with null-termination to (external) logging facility * @param prio priority (see syslog() call) * @param s Pointer to ASCII string with null-termination * @return negative value if there was an error */ DltReturnValue dlt_log(int prio, char *s); /** * Log with variable arguments to (external) logging facility (like printf) * @param prio priority (see syslog() call) * @param format format string for log message * @return negative value if there was an error */ DltReturnValue dlt_vlog(int prio, const char *format, ...); /** * Log size bytes with variable arguments to (external) logging facility (similar to snprintf) * @param prio priority (see syslog() call) * @param size number of bytes to log * @param format format string for log message * @return negative value if there was an error */ DltReturnValue dlt_vnlog(int prio, size_t size, const char *format, ...); /** * De-Initialize (external) logging facility */ void dlt_log_free(void); /** * Initialising a dlt receiver structure * @param receiver pointer to dlt receiver structure * @param _fd handle to file/socket/fifo, fram which the data should be received * @param _buffersize size of data buffer for storing the received data * @return negative value if there was an error */ DltReturnValue dlt_receiver_init(DltReceiver *receiver, int _fd, int _buffersize); /** * De-Initialize a dlt receiver structure * @param receiver pointer to dlt receiver structure * @return negative value if there was an error */ DltReturnValue dlt_receiver_free(DltReceiver *receiver); /** * Initialising a dlt receiver structure * @param receiver pointer to dlt receiver structure * @param fd handle to file/socket/fifo, fram which the data should be received * @param buffer data buffer for storing the received data * @return negative value if there was an error and zero if success */ DltReturnValue dlt_receiver_init_unix_socket(DltReceiver *receiver, int fd, char **buffer); /** * De-Initialize a dlt receiver structure * @param receiver pointer to dlt receiver structure * @return negative value if there was an error and zero if success */ DltReturnValue dlt_receiver_free_unix_socket(DltReceiver *receiver); /** * Receive data from socket or file/fifo using the dlt receiver structure * @param receiver pointer to dlt receiver structure * @param from_src specify whether received data is from socket or file/fifo * @return number of received bytes or negative value if there was an error */ int dlt_receiver_receive(DltReceiver *receiver, DltReceiverType from_src); /** * Remove a specific size of bytes from the received data * @param receiver pointer to dlt receiver structure * @param size amount of bytes to be removed * @return negative value if there was an error */ DltReturnValue dlt_receiver_remove(DltReceiver *receiver, int size); /** * Move data from last receive call to front of receive buffer * @param receiver pointer to dlt receiver structure * @return negative value if there was an error */ DltReturnValue dlt_receiver_move_to_begin(DltReceiver *receiver); /** * Check whether to_get amount of data is available in receiver and * copy it to dest. Skip the DltUserHeader if skip_header is set to 1. * @param receiver pointer to dlt receiver structure * @param dest pointer to the destination buffer * @param to_get size of the data to copy in dest * @param skip_header whether if the DltUserHeader must be skipped. */ int dlt_receiver_check_and_get(DltReceiver *receiver, void *dest, unsigned int to_get, unsigned int skip_header); /** * Fill out storage header of a dlt message * @param storageheader pointer to storage header of a dlt message * @param ecu name of ecu to be set in storage header * @return negative value if there was an error */ DltReturnValue dlt_set_storageheader(DltStorageHeader *storageheader, const char *ecu); /** * Check if a storage header contains its marker * @param storageheader pointer to storage header of a dlt message * @return 0 no, 1 yes, negative value if there was an error */ DltReturnValue dlt_check_storageheader(DltStorageHeader *storageheader); /** * Initialise static ringbuffer with a size of size. * Initialise as server. Init counters. * Memory is already allocated. * @param buf Pointer to ringbuffer structure * @param ptr Ptr to ringbuffer memory * @param size Maximum size of buffer in bytes * @return negative value if there was an error */ DltReturnValue dlt_buffer_init_static_server(DltBuffer *buf, const unsigned char *ptr, uint32_t size); /** * Initialize static ringbuffer with a size of size. * Initialise as a client. Do not change counters. * Memory is already allocated. * @param buf Pointer to ringbuffer structure * @param ptr Ptr to ringbuffer memory * @param size Maximum size of buffer in bytes * @return negative value if there was an error */ DltReturnValue dlt_buffer_init_static_client(DltBuffer *buf, const unsigned char *ptr, uint32_t size); /** * Initialize dynamic ringbuffer with a size of size. * Initialise as a client. Do not change counters. * Memory will be allocated starting with min_size. * If more memory is needed size is increased wit step_size. * The maximum size is max_size. * @param buf Pointer to ringbuffer structure * @param min_size Minimum size of buffer in bytes * @param max_size Maximum size of buffer in bytes * @param step_size size of which ringbuffer is increased * @return negative value if there was an error */ DltReturnValue dlt_buffer_init_dynamic(DltBuffer *buf, uint32_t min_size, uint32_t max_size, uint32_t step_size); /** * Deinitilaise usage of static ringbuffer * @param buf Pointer to ringbuffer structure * @return negative value if there was an error */ DltReturnValue dlt_buffer_free_static(DltBuffer *buf); /** * Release and free memory used by dynamic ringbuffer * @param buf Pointer to ringbuffer structure * @return negative value if there was an error */ DltReturnValue dlt_buffer_free_dynamic(DltBuffer *buf); /** * Check if message fits into buffer. * @param buf Pointer to buffer structure * @param needed Needed size * @return DLT_RETURN_OK if enough space, DLT_RETURN_ERROR otherwise */ DltReturnValue dlt_buffer_check_size(DltBuffer *buf, int needed); /** * Write one entry to ringbuffer * @param buf Pointer to ringbuffer structure * @param data Pointer to data to be written to ringbuffer * @param size Size of data in bytes to be written to ringbuffer * @return negative value if there was an error */ DltReturnValue dlt_buffer_push(DltBuffer *buf, const unsigned char *data, unsigned int size); /** * Write up to three entries to ringbuffer. * Entries are joined to one block. * @param buf Pointer to ringbuffer structure * @param data1 Pointer to data to be written to ringbuffer * @param size1 Size of data in bytes to be written to ringbuffer * @param data2 Pointer to data to be written to ringbuffer * @param size2 Size of data in bytes to be written to ringbuffer * @param data3 Pointer to data to be written to ringbuffer * @param size3 Size of data in bytes to be written to ringbuffer * @return negative value if there was an error */ DltReturnValue dlt_buffer_push3(DltBuffer *buf, const unsigned char *data1, unsigned int size1, const unsigned char *data2, unsigned int size2, const unsigned char *data3, unsigned int size3); /** * Read one entry from ringbuffer. * Remove it from ringbuffer. * @param buf Pointer to ringbuffer structure * @param data Pointer to data read from ringbuffer * @param max_size Max size of read data in bytes from ringbuffer * @return size of read data, zero if no data available, negative value if there was an error */ int dlt_buffer_pull(DltBuffer *buf, unsigned char *data, int max_size); /** * Read one entry from ringbuffer. * Do not remove it from ringbuffer. * @param buf Pointer to ringbuffer structure * @param data Pointer to data read from ringbuffer * @param max_size Max size of read data in bytes from ringbuffer * @return size of read data, zero if no data available, negative value if there was an error */ int dlt_buffer_copy(DltBuffer *buf, unsigned char *data, int max_size); /** * Remove entry from ringbuffer. * @param buf Pointer to ringbuffer structure * @return size of read data, zero if no data available, negative value if there was an error */ int dlt_buffer_remove(DltBuffer *buf); /** * Print information about buffer and log to internal DLT log. * @param buf Pointer to ringbuffer structure */ void dlt_buffer_info(DltBuffer *buf); /** * Print status of buffer and log to internal DLT log. * @param buf Pointer to ringbuffer structure */ void dlt_buffer_status(DltBuffer *buf); /** * Get total size in bytes of ringbuffer. * If buffer is dynamic, max size is returned. * @param buf Pointer to ringbuffer structure * @return total size of buffer */ uint32_t dlt_buffer_get_total_size(DltBuffer *buf); /** * Get used size in bytes of ringbuffer. * @param buf Pointer to ringbuffer structure * @return used size of buffer */ int dlt_buffer_get_used_size(DltBuffer *buf); /** * Get number of entries in ringbuffer. * @param buf Pointer to ringbuffer structure * @return number of entries */ int dlt_buffer_get_message_count(DltBuffer *buf); # if !defined (__WIN32__) /** * Helper function: Setup serial connection * @param fd File descriptor of serial tty device * @param speed Serial line speed, as defined in termios.h * @return negative value if there was an error */ DltReturnValue dlt_setup_serial(int fd, speed_t speed); /** * Helper function: Convert serial line baudrate (as number) to line speed (as defined in termios.h) * @param baudrate Serial line baudrate (as number) * @return Serial line speed, as defined in termios.h */ speed_t dlt_convert_serial_speed(int baudrate); /** * Print dlt version and dlt svn version to buffer * @param buf Pointer to buffer * @param size size of buffer */ void dlt_get_version(char *buf, size_t size); /** * Print dlt major version to buffer * @param buf Pointer to buffer * @param size size of buffer */ void dlt_get_major_version(char *buf, size_t size); /** * Print dlt minor version to buffer * @param buf Pointer to buffer * @param size size of buffer */ void dlt_get_minor_version(char *buf, size_t size); # endif /* Function prototypes which should be used only internally */ /* */ /** * Common part of initialisation * @return negative value if there was an error */ DltReturnValue dlt_init_common(void); /** * Return the uptime of the system in 0.1 ms resolution * @return 0 if there was an error */ uint32_t dlt_uptime(void); /** * Print header of a DLT message * @param message pointer to structure of organising access to DLT messages * @param text pointer to a ASCII string, in which the header is written * @param size maximal size of text buffer * @param verbose if set to true verbose information is printed out. * @return negative value if there was an error */ DltReturnValue dlt_message_print_header(DltMessage *message, char *text, uint32_t size, int verbose); /** * Print payload of a DLT message as Hex-Output * @param message pointer to structure of organising access to DLT messages * @param text pointer to a ASCII string, in which the output is written * @param size maximal size of text buffer * @param verbose if set to true verbose information is printed out. * @return negative value if there was an error */ DltReturnValue dlt_message_print_hex(DltMessage *message, char *text, uint32_t size, int verbose); /** * Print payload of a DLT message as ASCII-Output * @param message pointer to structure of organising access to DLT messages * @param text pointer to a ASCII string, in which the output is written * @param size maximal size of text buffer * @param verbose if set to true verbose information is printed out. * @return negative value if there was an error */ DltReturnValue dlt_message_print_ascii(DltMessage *message, char *text, uint32_t size, int verbose); /** * Print payload of a DLT message as Mixed-Ouput (Hex and ASCII), for plain text output * @param message pointer to structure of organising access to DLT messages * @param text pointer to a ASCII string, in which the output is written * @param size maximal size of text buffer * @param verbose if set to true verbose information is printed out. * @return negative value if there was an error */ DltReturnValue dlt_message_print_mixed_plain(DltMessage *message, char *text, uint32_t size, int verbose); /** * Print payload of a DLT message as Mixed-Ouput (Hex and ASCII), for HTML text output * @param message pointer to structure of organising access to DLT messages * @param text pointer to a ASCII string, in which the output is written * @param size maximal size of text buffer * @param verbose if set to true verbose information is printed out. * @return negative value if there was an error */ DltReturnValue dlt_message_print_mixed_html(DltMessage *message, char *text, uint32_t size, int verbose); /** * Decode and print a argument of a DLT message * @param msg pointer to structure of organising access to DLT messages * @param type_info Type of argument * @param ptr pointer to pointer to data (pointer to data is changed within this function) * @param datalength pointer to datalength (datalength is changed within this function) * @param text pointer to a ASCII string, in which the output is written * @param textlength maximal size of text buffer * @param byteLength If argument is a string, and this value is 0 or greater, this value will be taken as string length * @param verbose if set to true verbose information is printed out. * @return negative value if there was an error */ DltReturnValue dlt_message_argument_print(DltMessage *msg, uint32_t type_info, uint8_t **ptr, int32_t *datalength, char *text, int textlength, int byteLength, int verbose); /** * Check environment variables. */ void dlt_check_envvar(); /** * Parse the response text and identifying service id and its options. * * @param resp_text char * * @param service_id int * * @param service_opt int * * @return pointer to resp_text */ int dlt_set_loginfo_parse_service_id(char *resp_text, uint32_t *service_id, uint8_t *service_opt); /** * Convert get log info from ASCII to uint16 * * @param rp char * @param rp_count int * @return length */ int16_t dlt_getloginfo_conv_ascii_to_uint16_t(char *rp, int *rp_count); /** * Convert get log info from ASCII to int16 * * @param rp char * @param rp_count int * @return length */ int16_t dlt_getloginfo_conv_ascii_to_int16_t(char *rp, int *rp_count); /** * Convert get log info from ASCII to ID * * @param rp char * @param rp_count int * @param wp char * @param len int */ void dlt_getloginfo_conv_ascii_to_id(char *rp, int *rp_count, char *wp, int len); /** * Convert from hex ASCII to binary * @param ptr const char * @param binary uint8_t * @param size int */ void dlt_hex_ascii_to_binary(const char *ptr, uint8_t *binary, int *size); # ifndef DLT_USE_UNIX_SOCKET_IPC /** * Create the specified path, recursive if necessary * behaves like calling mkdir -p \ on the console */ int dlt_mkdir_recursive(const char *dir); # endif # ifdef __cplusplus } # endif /** \} */ #endif /* DLT_COMMON_H */ dlt-daemon-2.18.4/include/dlt/dlt_common_api.h000066400000000000000000000461741353342203500212110ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2011-2015, BMW AG * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author Alexander Wenzel * * \copyright Copyright © 2011-2015 BMW AG. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file dlt_common_api.h */ /******************************************************************************* ** ** ** SRC-MODULE: dlt_commpn_api.h ** ** ** ** TARGET : linux ** ** ** ** PROJECT : DLT ** ** ** ** AUTHOR : Alexander Wenzel Alexander.AW.Wenzel@bmw.de ** ** ** ** PURPOSE : ** ** ** ** REMARKS : ** ** ** ** PLATFORM DEPENDANT [yes/no]: yes ** ** ** ** TO BE CHANGED BY USER [yes/no]: no ** ** ** *******************************************************************************/ /******************************************************************************* ** Author Identity ** ******************************************************************************** ** ** ** Initials Name Company ** ** -------- ------------------------- ---------------------------------- ** ** aw Alexander Wenzel BMW ** *******************************************************************************/ #ifndef DLT_COMMON_API_H #define DLT_COMMON_API_H #include "dlt.h" /** * Create an object for a new context. * Common API with DLT Embedded * This macro has to be called first for every. * @param CONTEXT object containing information about one special logging context */ /* #define DLT_DECLARE_CONTEXT(CONTEXT) */ /* UNCHANGED */ /** * Use an object of a new context created in another module. * Common API with DLT Embedded * This macro has to be called first for every. * @param CONTEXT object containing information about one special logging context */ /* #define DLT_IMPORT_CONTEXT(CONTEXT) */ /* UNCHANGED */ /** * Register application. * Common API with DLT Embedded * @param APPID application id with maximal four characters * @param DESCRIPTION ASCII string containing description */ /* #define DLT_REGISTER_APP(APPID,DESCRIPTION) */ /* UNCHANGED */ /** * Register context including application (with default log level and default trace status) * Common API with DLT Embedded * @param CONTEXT object containing information about one special logging context * @param CONTEXTID context id with maximal four characters * @param APPID context id with maximal four characters * @param DESCRIPTION ASCII string containing description */ #define DLT_REGISTER_CONTEXT_APP(CONTEXT, CONTEXTID, APPID, DESCRIPTION) \ DLT_REGISTER_CONTEXT(CONTEXT, CONTEXTID, DESCRIPTION) /** * Send log message with variable list of messages (intended for verbose mode) * Common API with DLT Embedded * @param CONTEXT object containing information about one special logging context * @param LOGLEVEL the log level of the log message * @param ARGS variable list of arguments */ /*****************************************/ #define DLT_LOG0(CONTEXT, LOGLEVEL) \ DLT_LOG(CONTEXT, LOGLEVEL) /*****************************************/ #define DLT_LOG1(CONTEXT, LOGLEVEL, ARGS1) \ DLT_LOG(CONTEXT, LOGLEVEL, ARGS1) /*****************************************/ #define DLT_LOG2(CONTEXT, LOGLEVEL, ARGS1, ARGS2) \ DLT_LOG(CONTEXT, LOGLEVEL, ARGS1, ARGS2) /*****************************************/ #define DLT_LOG3(CONTEXT, LOGLEVEL, ARGS1, ARGS2, ARGS3) \ DLT_LOG(CONTEXT, LOGLEVEL, ARGS1, ARGS2, ARGS3) /*****************************************/ #define DLT_LOG4(CONTEXT, LOGLEVEL, ARGS1, ARGS2, ARGS3, ARGS4) \ DLT_LOG(CONTEXT, LOGLEVEL, ARGS1, ARGS2, ARGS3, ARGS4) /*****************************************/ #define DLT_LOG5(CONTEXT, LOGLEVEL, ARGS1, ARGS2, ARGS3, ARGS4, ARGS5) \ DLT_LOG(CONTEXT, LOGLEVEL, ARGS1, ARGS2, ARGS3, ARGS4, ARGS5) /*****************************************/ #define DLT_LOG6(CONTEXT, LOGLEVEL, ARGS1, ARGS2, ARGS3, ARGS4, ARGS5, ARGS6) \ DLT_LOG(CONTEXT, LOGLEVEL, ARGS1, ARGS2, ARGS3, ARGS4, ARGS5, ARGS6) /*****************************************/ #define DLT_LOG7(CONTEXT, LOGLEVEL, ARGS1, ARGS2, ARGS3, ARGS4, ARGS5, ARGS6, ARGS7) \ DLT_LOG(CONTEXT, LOGLEVEL, ARGS1, ARGS2, ARGS3, ARGS4, ARGS5, ARGS6, ARGS7) /*****************************************/ #define DLT_LOG8(CONTEXT, LOGLEVEL, ARGS1, ARGS2, ARGS3, ARGS4, ARGS5, ARGS6, ARGS7, ARGS8) \ DLT_LOG(CONTEXT, LOGLEVEL, ARGS1, ARGS2, ARGS3, ARGS4, ARGS5, ARGS6, ARGS7, ARGS8) /*****************************************/ #define DLT_LOG9(CONTEXT, LOGLEVEL, ARGS1, ARGS2, ARGS3, ARGS4, ARGS5, ARGS6, ARGS7, ARGS8, ARGS9) \ DLT_LOG(CONTEXT, LOGLEVEL, ARGS1, ARGS2, ARGS3, ARGS4, ARGS5, ARGS6, ARGS7, ARGS8, ARGS9) /*****************************************/ #define DLT_LOG10(CONTEXT, LOGLEVEL, ARGS1, ARGS2, ARGS3, ARGS4, ARGS5, ARGS6, ARGS7, ARGS8, ARGS9, ARGS10) \ DLT_LOG(CONTEXT, LOGLEVEL, ARGS1, ARGS2, ARGS3, ARGS4, ARGS5, ARGS6, ARGS7, ARGS8, ARGS9, ARGS10) /*****************************************/ #define DLT_LOG11(CONTEXT, LOGLEVEL, ARGS1, ARGS2, ARGS3, ARGS4, ARGS5, ARGS6, ARGS7, ARGS8, ARGS9, ARGS10, ARGS11) \ DLT_LOG(CONTEXT, LOGLEVEL, ARGS1, ARGS2, ARGS3, ARGS4, ARGS5, ARGS6, ARGS7, ARGS8, ARGS9, ARGS10, ARGS11) /*****************************************/ #define DLT_LOG12(CONTEXT, \ LOGLEVEL, \ ARGS1, \ ARGS2, \ ARGS3, \ ARGS4, \ ARGS5, \ ARGS6, \ ARGS7, \ ARGS8, \ ARGS9, \ ARGS10, \ ARGS11, \ ARGS12) \ DLT_LOG(CONTEXT, LOGLEVEL, ARGS1, ARGS2, ARGS3, ARGS4, ARGS5, ARGS6, ARGS7, ARGS8, ARGS9, ARGS10, ARGS11, ARGS12) /*****************************************/ #define DLT_LOG13(CONTEXT, \ LOGLEVEL, \ ARGS1, \ ARGS2, \ ARGS3, \ ARGS4, \ ARGS5, \ ARGS6, \ ARGS7, \ ARGS8, \ ARGS9, \ ARGS10, \ ARGS11, \ ARGS12, \ ARGS13) \ DLT_LOG(CONTEXT, \ LOGLEVEL, \ ARGS1, \ ARGS2, \ ARGS3, \ ARGS4, \ ARGS5, \ ARGS6, \ ARGS7, \ ARGS8, \ ARGS9, \ ARGS10, \ ARGS11, \ ARGS12, \ ARGS13) /*****************************************/ #define DLT_LOG14(CONTEXT, \ LOGLEVEL, \ ARGS1, \ ARGS2, \ ARGS3, \ ARGS4, \ ARGS5, \ ARGS6, \ ARGS7, \ ARGS8, \ ARGS9, \ ARGS10, \ ARGS11, \ ARGS12, \ ARGS13, \ ARGS14) \ DLT_LOG(CONTEXT, \ LOGLEVEL, \ ARGS1, \ ARGS2, \ ARGS3, \ ARGS4, \ ARGS5, \ ARGS6, \ ARGS7, \ ARGS8, \ ARGS9, \ ARGS10, \ ARGS11, \ ARGS12, \ ARGS13, \ ARGS14) /*****************************************/ #define DLT_LOG15(CONTEXT, \ LOGLEVEL, \ ARGS1, \ ARGS2, \ ARGS3, \ ARGS4, \ ARGS5, \ ARGS6, \ ARGS7, \ ARGS8, \ ARGS9, \ ARGS10, \ ARGS11, \ ARGS12, \ ARGS13, \ ARGS14, \ ARGS15) \ DLT_LOG(CONTEXT, \ LOGLEVEL, \ ARGS1, \ ARGS2, \ ARGS3, \ ARGS4, \ ARGS5, \ ARGS6, \ ARGS7, \ ARGS8, \ ARGS9, \ ARGS10, \ ARGS11, \ ARGS12, \ ARGS13, \ ARGS14, \ ARGS15) /*****************************************/ #define DLT_LOG16(CONTEXT, \ LOGLEVEL, \ ARGS1, \ ARGS2, \ ARGS3, \ ARGS4, \ ARGS5, \ ARGS6, \ ARGS7, \ ARGS8, \ ARGS9, \ ARGS10, \ ARGS11, \ ARGS12, \ ARGS13, \ ARGS14, \ ARGS15, \ ARGS16) \ DLT_LOG(CONTEXT, \ LOGLEVEL, \ ARGS1, \ ARGS2, \ ARGS3, \ ARGS4, \ ARGS5, \ ARGS6, \ ARGS7, \ ARGS8, \ ARGS9, \ ARGS10, \ ARGS11, \ ARGS12, \ ARGS13, \ ARGS14, \ ARGS15, \ ARGS16) /** * Send log message with variable list of messages (intended for non-verbose mode) * Common API with DLT Embedded * @param CONTEXT object containing information about one special logging context * @param LOGLEVEL the log level of the log message * @param MSGID the message id of log message * @param ARGS variable list of arguments: * calls to DLT_STRING(), DLT_BOOL(), DLT_FLOAT32(), DLT_FLOAT64(), * DLT_INT(), DLT_UINT(), DLT_RAW() */ /*****************************************/ #define DLT_LOG_ID0(CONTEXT, LOGLEVEL, MSGID) \ DLT_LOG_ID(CONTEXT, LOGLEVEL, MSGID) /*****************************************/ #define DLT_LOG_ID1(CONTEXT, LOGLEVEL, MSGID, ARGS1) \ DLT_LOG_ID(CONTEXT, LOGLEVEL, MSGID, ARGS1) /*****************************************/ #define DLT_LOG_ID2(CONTEXT, LOGLEVEL, MSGID, ARGS1, ARGS2) \ DLT_LOG_ID(CONTEXT, LOGLEVEL, MSGID, ARGS1, ARGS2) /*****************************************/ #define DLT_LOG_ID3(CONTEXT, LOGLEVEL, MSGID, ARGS1, ARGS2, ARGS3) \ DLT_LOG_ID(CONTEXT, LOGLEVEL, MSGID, ARGS1, ARGS2, ARGS3) /*****************************************/ #define DLT_LOG_ID4(CONTEXT, LOGLEVEL, MSGID, ARGS1, ARGS2, ARGS3, ARGS4) \ DLT_LOG_ID(CONTEXT, LOGLEVEL, MSGID, ARGS1, ARGS2, ARGS3, ARGS4) /*****************************************/ #define DLT_LOG_ID5(CONTEXT, LOGLEVEL, MSGID, ARGS1, ARGS2, ARGS3, ARGS4, ARGS5) \ DLT_LOG_ID(CONTEXT, LOGLEVEL, MSGID, ARGS1, ARGS2, ARGS3, ARGS4, ARGS5) /*****************************************/ #define DLT_LOG_ID6(CONTEXT, LOGLEVEL, MSGID, ARGS1, ARGS2, ARGS3, ARGS4, ARGS5, ARGS6) \ DLT_LOG_ID(CONTEXT, LOGLEVEL, MSGID, ARGS1, ARGS2, ARGS3, ARGS4, ARGS5, ARGS6) /*****************************************/ #define DLT_LOG_ID7(CONTEXT, LOGLEVEL, MSGID, ARGS1, ARGS2, ARGS3, ARGS4, ARGS5, ARGS6, ARGS7) \ DLT_LOG_ID(CONTEXT, LOGLEVEL, MSGID, ARGS1, ARGS2, ARGS3, ARGS4, ARGS5, ARGS6, ARGS7) /*****************************************/ #define DLT_LOG_ID8(CONTEXT, LOGLEVEL, MSGID, ARGS1, ARGS2, ARGS3, ARGS4, ARGS5, ARGS6, ARGS7, ARGS8) \ DLT_LOG_ID(CONTEXT, LOGLEVEL, MSGID, ARGS1, ARGS2, ARGS3, ARGS4, ARGS5, ARGS6, ARGS7, ARGS8) /*****************************************/ #define DLT_LOG_ID9(CONTEXT, LOGLEVEL, MSGID, ARGS1, ARGS2, ARGS3, ARGS4, ARGS5, ARGS6, ARGS7, ARGS8, ARGS9) \ DLT_LOG_ID(CONTEXT, LOGLEVEL, MSGID, ARGS1, ARGS2, ARGS3, ARGS4, ARGS5, ARGS6, ARGS7, ARGS8, ARGS9) /*****************************************/ #define DLT_LOG_ID10(CONTEXT, LOGLEVEL, MSGID, ARGS1, ARGS2, ARGS3, ARGS4, ARGS5, ARGS6, ARGS7, ARGS8, ARGS9, ARGS10) \ DLT_LOG_ID(CONTEXT, LOGLEVEL, MSGID, ARGS1, ARGS2, ARGS3, ARGS4, ARGS5, ARGS6, ARGS7, ARGS8, ARGS9, ARGS10) /*****************************************/ #define DLT_LOG_ID11(CONTEXT, \ LOGLEVEL, \ MSGID, \ ARGS1, \ ARGS2, \ ARGS3, \ ARGS4, \ ARGS5, \ ARGS6, \ ARGS7, \ ARGS8, \ ARGS9, \ ARGS10, \ ARGS11) \ DLT_LOG_ID(CONTEXT, LOGLEVEL, MSGID, ARGS1, ARGS2, ARGS3, ARGS4, ARGS5, ARGS6, ARGS7, ARGS8, ARGS9, ARGS10, ARGS11) /*****************************************/ #define DLT_LOG_ID12(CONTEXT, \ LOGLEVEL, \ MSGID, \ ARGS1, \ ARGS2, \ ARGS3, \ ARGS4, \ ARGS5, \ ARGS6, \ ARGS7, \ ARGS8, \ ARGS9, \ ARGS10, \ ARGS11, \ ARGS12) \ DLT_LOG_ID(CONTEXT, \ LOGLEVEL, \ MSGID, \ ARGS1, \ ARGS2, \ ARGS3, \ ARGS4, \ ARGS5, \ ARGS6, \ ARGS7, \ ARGS8, \ ARGS9, \ ARGS10, \ ARGS11, \ ARGS12) /*****************************************/ #define DLT_LOG_ID13(CONTEXT, \ LOGLEVEL, \ MSGID, \ ARGS1, \ ARGS2, \ ARGS3, \ ARGS4, \ ARGS5, \ ARGS6, \ ARGS7, \ ARGS8, \ ARGS9, \ ARGS10, \ ARGS11, \ ARGS12, \ ARGS13) \ DLT_LOG_ID(CONTEXT, \ LOGLEVEL, \ MSGID, \ ARGS1, \ ARGS2, \ ARGS3, \ ARGS4, \ ARGS5, \ ARGS6, \ ARGS7, \ ARGS8, \ ARGS9, \ ARGS10, \ ARGS11, \ ARGS12, \ ARGS13) /*****************************************/ #define DLT_LOG_ID14(CONTEXT, \ LOGLEVEL, \ MSGID, \ ARGS1, \ ARGS2, \ ARGS3, \ ARGS4, \ ARGS5, \ ARGS6, \ ARGS7, \ ARGS8, \ ARGS9, \ ARGS10, \ ARGS11, \ ARGS12, \ ARGS13, \ ARGS14) \ DLT_LOG_ID(CONTEXT, \ LOGLEVEL, \ MSGID, \ ARGS1, \ ARGS2, \ ARGS3, \ ARGS4, \ ARGS5, \ ARGS6, \ ARGS7, \ ARGS8, \ ARGS9, \ ARGS10, \ ARGS11, \ ARGS12, \ ARGS13, \ ARGS14) /*****************************************/ #define DLT_LOG_ID15(CONTEXT, \ LOGLEVEL, \ MSGID, \ ARGS1, \ ARGS2, \ ARGS3, \ ARGS4, \ ARGS5, \ ARGS6, \ ARGS7, \ ARGS8, \ ARGS9, \ ARGS10, \ ARGS11, \ ARGS12, \ ARGS13, \ ARGS14, \ ARGS15) \ DLT_LOG_ID(CONTEXT, \ LOGLEVEL, \ MSGID, \ ARGS1, \ ARGS2, \ ARGS3, \ ARGS4, \ ARGS5, \ ARGS6, \ ARGS7, \ ARGS8, \ ARGS9, \ ARGS10, \ ARGS11, \ ARGS12, \ ARGS13, \ ARGS14, \ ARGS15) /*****************************************/ #define DLT_LOG_ID16(CONTEXT, \ LOGLEVEL, \ MSGID, \ ARGS1, \ ARGS2, \ ARGS3, \ ARGS4, \ ARGS5, \ ARGS6, \ ARGS7, \ ARGS8, \ ARGS9, \ ARGS10, \ ARGS11, \ ARGS12, \ ARGS13, \ ARGS14, \ ARGS15, \ ARGS16) \ DLT_LOG_ID(CONTEXT, \ LOGLEVEL, \ MSGID, \ ARGS1, \ ARGS2, \ ARGS3, \ ARGS4, \ ARGS5, \ ARGS6, \ ARGS7, \ ARGS8, \ ARGS9, \ ARGS10, \ ARGS11, \ ARGS12, \ ARGS13, \ ARGS14, \ ARGS15, \ ARGS16) /** * Unregister context. * Common API with DLT Embedded * @param CONTEXT object containing information about one special logging context */ /* #define DLT_UNREGISTER_CONTEXT(CONTEXT) */ /* UNCHANGED */ /** * Unregister application. * Common API with DLT Embedded */ /* #define DLT_UNREGISTER_APP() */ /* UNCHANGED */ /** * Add string parameter to the log messsage. * Common API with DLT Embedded * In the future in none verbose mode the string will not be sent via DLT message. * @param TEXT ASCII string */ /* #define DLT_CSTRING(TEXT) */ /* UNCHANGED */ #endif /* DLT_COMMON_API_H */ dlt-daemon-2.18.4/include/dlt/dlt_cpp_extension.hpp000066400000000000000000000134521353342203500222770ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2015 Intel Corporation * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author Stefan Vacek Intel Corporation * * \copyright Copyright © 2015 Intel Corporation. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file dlt_cpp_extension.hpp */ #ifndef DLT_CPP_EXTENSION_HPP #define DLT_CPP_EXTENSION_HPP #include #include #include #include #include "dlt.h" template int32_t logToDlt(DltContextData &log, T const &value) = delete; template<> inline int32_t logToDlt(DltContextData &log, int8_t const &value) { return dlt_user_log_write_int8(&log, value); } template<> inline int32_t logToDlt(DltContextData &log, int16_t const &value) { return dlt_user_log_write_int16(&log, value); } template<> inline int32_t logToDlt(DltContextData &log, int32_t const &value) { return dlt_user_log_write_int32(&log, value); } template<> inline int32_t logToDlt(DltContextData &log, int64_t const &value) { return dlt_user_log_write_int64(&log, value); } template<> inline int32_t logToDlt(DltContextData &log, uint8_t const &value) { return dlt_user_log_write_uint8(&log, value); } template<> inline int32_t logToDlt(DltContextData &log, uint16_t const &value) { return dlt_user_log_write_uint16(&log, value); } template<> inline int32_t logToDlt(DltContextData &log, uint32_t const &value) { return dlt_user_log_write_uint32(&log, value); } template<> inline int32_t logToDlt(DltContextData &log, uint64_t const &value) { return dlt_user_log_write_uint64(&log, value); } template<> inline int32_t logToDlt(DltContextData &log, float32_t const &value) { return dlt_user_log_write_float32(&log, value); } template<> inline int32_t logToDlt(DltContextData &log, double const &value) { return dlt_user_log_write_float64(&log, value); } template<> inline int32_t logToDlt(DltContextData &log, bool const &value) { return dlt_user_log_write_bool(&log, value); } static inline int32_t logToDlt(DltContextData &log, char const * const value) { return dlt_user_log_write_utf8_string(&log, value); } static inline int32_t logToDlt(DltContextData &log, char * const value) { return dlt_user_log_write_utf8_string(&log, value); } template<> inline int32_t logToDlt(DltContextData &log, std::string const &value) { return dlt_user_log_write_utf8_string(&log, value.c_str()); } /* stl types */ template<> int32_t logToDlt(DltContextData &log, std::string const &value); template> static inline int32_t logToDlt(DltContextData &log, std::vector<_Tp, _Alloc> const & value) { int result = 0; for (auto elem : value) result += logToDlt(log, elem); if (result != 0) result = -1; return result; } template> static inline int32_t logToDlt(DltContextData &log, std::list<_Tp, _Alloc> const & value) { int result = 0; for (auto elem : value) result += logToDlt(log, elem); if (result != 0) result = -1; return result; } template, typename _Alloc = std::allocator>> static inline int32_t logToDlt(DltContextData &log, std::map<_Key, _Tp, _Compare, _Alloc> const & value) { int result = 0; for (auto elem : value) { result += logToDlt(log, elem.first); result += logToDlt(log, elem.second); } if (result != 0) result = -1; return result; } //variadic functions using C11 standard template static inline int32_t logToDltVariadic(DltContextData &log, First const &valueA) { return logToDlt(log, valueA); } template static inline int32_t logToDltVariadic(DltContextData &log, First const &valueA, const Rest&... valueB) { int result = logToDlt(log, valueA) + logToDltVariadic(log, valueB...); if (result != 0) result = -1; return result; } /** * @brief macro to write a log message with variable number of arguments and without the need to specify the type of log data * * The macro can be used with any type that provides a logToDlt function. * * Example: * DLT_LOG_CXX(dltContext, DLT_LV_X, "text", valueA, valueB, ...) */ #define DLT_LOG_CXX(CONTEXT, LOGLEVEL, ...)\ do\ {\ DltContextData log;\ if (dlt_user_log_write_start(&CONTEXT,&log,LOGLEVEL)>0)\ {\ logToDltVariadic(log, ##__VA_ARGS__);\ dlt_user_log_write_finish(&log);\ }\ }\ while(0) /** * @brief macro to write a log message with variable number of arguments and without the need to specify the type of log data. * * The macro can be used with any type that provides a logToDlt function. * This includes all the types that are code generated. * * This macro is similar to \c DLT_LOG_CXX. However, it adds the current function name as the first log argument. * * Example: * DLT_LOG_FCN_CXX(dltContext, DLT_LV_X, "text", valueA, valueB, ...) */ #define DLT_LOG_FCN_CXX(CONTEXT, LOGLEVEL, ...) \ do\ {\ DltContextData log;\ if (dlt_user_log_write_start(&CONTEXT, &log, LOGLEVEL) > 0)\ {\ dlt_user_log_write_string(&log, __PRETTY_FUNCTION__);\ logToDltVariadic(log, ##__VA_ARGS__);\ dlt_user_log_write_finish(&log);\ }\ }\ while(0) #endif /* DLT_CPP_EXTENSION_HPP */ dlt-daemon-2.18.4/include/dlt/dlt_filetransfer.h000066400000000000000000000156511353342203500215500ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2011-2015, BMW AG * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author Alexander Wenzel * * \copyright Copyright © 2011-2015 BMW AG. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file dlt_filetransfer.h */ #ifndef DLT_FILETRANSFER_H #define DLT_FILETRANSFER_H #include /* Needed for LONG_MAX */ #include /* Needed for struct stat st*/ #include "dlt.h" /* Needed for DLT Logs */ #include /* Signal handling */ #include "errno.h" /* ! Error code for dlt_user_log_file_complete */ #define DLT_FILETRANSFER_ERROR_FILE_COMPLETE -300 /* ! Error code for dlt_user_log_file_complete */ #define DLT_FILETRANSFER_ERROR_FILE_COMPLETE1 -301 /* ! Error code for dlt_user_log_file_complete */ #define DLT_FILETRANSFER_ERROR_FILE_COMPLETE2 -302 /* ! Error code for dlt_user_log_file_complete */ #define DLT_FILETRANSFER_ERROR_FILE_COMPLETE3 -303 /* ! Error code for dlt_user_log_file_head */ #define DLT_FILETRANSFER_ERROR_FILE_HEAD -400 /* ! Error code for dlt_user_log_file_data */ #define DLT_FILETRANSFER_ERROR_FILE_DATA -500 /* ! Error code for dlt_user_log_file_data */ #define DLT_FILETRANSFER_ERROR_FILE_DATA_USER_BUFFER_FAILED -501 /* ! Error code for dlt_user_log_file_end */ #define DLT_FILETRANSFER_ERROR_FILE_END -600 /* ! Error code for dlt_user_log_file_infoAbout */ #define DLT_FILETRANSFER_ERROR_INFO_ABOUT -700 /* ! Error code for dlt_user_log_file_packagesCount */ #define DLT_FILETRANSFER_ERROR_PACKAGE_COUNT -800 /* !Transfer the complete file as several dlt logs. */ /**This method transfer the complete file as several dlt logs. At first it will be checked that the file exist. * In the next step some generic informations about the file will be logged to dlt. * Now the header will be logged to dlt. See the method dlt_user_log_file_header for more informations. * Then the method dlt_user_log_data will be called with the parameter to log all packages in a loop with some timeout. * At last dlt_user_log_end is called to signal that the complete file transfer was okey. This is important for the plugin of the dlt viewer. * @param fileContext Specific context to log the file to dlt * @param filename Absolute file path * @param deleteFlag Flag if the file will be deleted after transfer. 1->delete, 0->notDelete * @param timeout Timeout in ms to wait between some logs. Important that the FIFO of dlt will not be flooded with to many messages in a short period of time. * @return Returns 0 if everything was okey. If there was a failure value < 0 will be returned. */ extern int dlt_user_log_file_complete(DltContext *fileContext, const char *filename, int deleteFlag, int timeout); /* !This method gives information about the number of packages the file have */ /**Every file will be divided into several packages. Every package will be logged as a single dlt log. * The number of packages depends on the BUFFER_SIZE. * At first it will be checked if the file exist. Then the file will be divided into * several packages depending on the buffer size. * @param fileContext Specific context to log the file to dlt * @param filename Absolute file path * @return Returns 0 if everything was okey. If there was a failure value < 0 will be returned. */ extern int dlt_user_log_file_packagesCount(DltContext *fileContext, const char *filename); /* !Logs specific file inforamtions to dlt */ /**The filename, file size, file serial number and the number of packages will be logged to dlt. * @param fileContext Specific context * @param filename Absolute file path * @return Returns 0 if everything was okey.If there was a failure value < 0 will be returned. */ extern int dlt_user_log_file_infoAbout(DltContext *fileContext, const char *filename); /* !Transfer the head of the file as a dlt logs. */ /**The head of the file must be logged to dlt because the head contains inforamtion about the file serial number, * the file name, the file size, package number the file have and the buffer size. * All these informations are needed from the plugin of the dlt viewer. * See the Mainpages.c for more informations. * @param fileContext Specific context to log the file to dlt * @param filename Absolute file path * @param alias Alias for the file. An alternative name to show in the receiving end * @return Returns 0 if everything was okey. If there was a failure value < 0 will be returned. */ extern int dlt_user_log_file_header_alias(DltContext *fileContext, const char *filename, const char *alias); /* !Transfer the head of the file as a dlt logs. */ /**The head of the file must be logged to dlt because the head contains inforamtion about the file serial number, * the file name, the file size, package number the file have and the buffer size. * All these informations are needed from the plugin of the dlt viewer. * See the Mainpages.c for more informations. * @param fileContext Specific context to log the file to dlt * @param filename Absolute file path * @return Returns 0 if everything was okey. If there was a failure value < 0 will be returned. */ extern int dlt_user_log_file_header(DltContext *fileContext, const char *filename); /* !Transfer the content data of a file. */ /**See the Mainpages.c for more informations. * @param fileContext Specific context to log the file to dlt * @param filename Absolute file path * @param packageToTransfer Package number to transfer. If this param is LONG_MAX, the whole file will be transferred with a specific timeout * @param timeout Timeout to wait between dlt logs. Important because the dlt FIFO should not be flooded. Default is defined by MIN_TIMEOUT. The given timeout in ms can not be smaller than MIN_TIMEOUT. * @return Returns 0 if everything was okey. If there was a failure value < 0 will be returned. */ extern int dlt_user_log_file_data(DltContext *fileContext, const char *filename, int packageToTransfer, int timeout); /* !Transfer the end of the file as a dlt logs. */ /**The end of the file must be logged to dlt because the end contains inforamtion about the file serial number. * This informations is needed from the plugin of the dlt viewer. * See the Mainpages.c for more informations. * @param fileContext Specific context to log the file to dlt * @param filename Absolute file path * @param deleteFlag Flag to delete the file after the whole file is transferred (logged to dlt).1->delete,0->NotDelete * @return Returns 0 if everything was okey. If there was a failure value < 0 will be returned. */ extern int dlt_user_log_file_end(DltContext *fileContext, const char *filename, int deleteFlag); #endif /* DLT_FILETRANSFER_H */ dlt-daemon-2.18.4/include/dlt/dlt_offline_trace.h000066400000000000000000000173531353342203500216650ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2011-2015, BMW AG * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author Alexander Wenzel * * \copyright Copyright © 2011-2015 BMW AG. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file dlt_offline_trace.h */ /******************************************************************************* ** ** ** SRC-MODULE: dlt_offline_trace.h ** ** ** ** TARGET : linux ** ** ** ** PROJECT : DLT ** ** ** ** AUTHOR : Alexander Wenzel Alexander.AW.Wenzel@bmw.de ** ** ** ** PURPOSE : ** ** ** ** REMARKS : ** ** ** ** PLATFORM DEPENDANT [yes/no]: yes ** ** ** ** TO BE CHANGED BY USER [yes/no]: no ** ** ** *******************************************************************************/ /******************************************************************************* ** Author Identity ** ******************************************************************************** ** ** ** Initials Name Company ** ** -------- ------------------------- ---------------------------------- ** ** aw Alexander Wenzel BMW ** *******************************************************************************/ #ifndef DLT_OFFLINE_TRACE_H #define DLT_OFFLINE_TRACE_H #include #include "dlt_types.h" #define DLT_OFFLINETRACE_FILENAME_BASE "dlt_offlinetrace" #define DLT_OFFLINETRACE_FILENAME_DELI "." #define DLT_OFFLINETRACE_FILENAME_EXT ".dlt" #define DLT_OFFLINETRACE_INDEX_MAX_SIZE 10 #define DLT_OFFLINETRACE_FILENAME_TO_COMPARE "dlt_offlinetrace_" /* "dlt_offlinetrace.4294967295.dlt" -> MAX 32byte include NULL terminate */ #define DLT_OFFLINETRACE_FILENAME_MAX_SIZE (sizeof(DLT_OFFLINETRACE_FILENAME_BASE) + \ sizeof(DLT_OFFLINETRACE_FILENAME_DELI) + \ DLT_OFFLINETRACE_INDEX_MAX_SIZE + \ sizeof(DLT_OFFLINETRACE_FILENAME_EXT) + 1) typedef struct { char directory[NAME_MAX + 1];/**< (String) Store DLT messages to local directory */ char filename[NAME_MAX + 1]; /**< (String) Filename of currently used log file */ int fileSize; /**< (int) Maximum size in bytes of one trace file (Default: 1000000) */ int maxSize; /**< (int) Maximum size of all trace files (Default: 4000000) */ int filenameTimestampBased; /**< (int) timestamp based or index based (Default: 1 Timestamp based) */ int ohandle; } DltOfflineTrace; /** * Initialise the offline trace * This function call opens the currently used log file. * A check of the complete size of the offline trace is done during startup. * Old files are deleted, if there is not enough space left to create new file. * This function must be called before using further offline trace functions. * @param trace pointer to offline trace structure * @param directory directory where to store offline trace files * @param fileSize maximum size of one offline trace file. * @param maxSize maximum size of complete offline trace in bytes. *.@param filenameTimestampBased filename to be created on timestamp based or index based * @return negative value if there was an error */ extern DltReturnValue dlt_offline_trace_init(DltOfflineTrace *trace, const char *directory, int fileSize, int maxSize, int filenameTimestampBased); /** * Uninitialise the offline trace * This function call closes currently used log file. * This function must be called after usage of offline trace * @param buf pointer to offline trace structure * @return negative value if there was an error */ extern DltReturnValue dlt_offline_trace_free(DltOfflineTrace *buf); /** * Write data into offline trace * If the current used log file exceeds the max file size, new log file is created. * A check of the complete size of the offline trace is done before new file is created. * Old files are deleted, if there is not enough space left to create new file. * @param trace pointer to offline trace structure * @param data1 pointer to first data block to be written, null if not used * @param size1 size in bytes of first data block to be written, 0 if not used * @param data2 pointer to second data block to be written, null if not used * @param size2 size in bytes of second data block to be written, 0 if not used * @param data3 pointer to third data block to be written, null if not used * @param size3 size in bytes of third data block to be written, 0 if not used * @return negative value if there was an error */ extern DltReturnValue dlt_offline_trace_write(DltOfflineTrace *trace, unsigned char *data1, int size1, unsigned char *data2, int size2, unsigned char *data3, int size3); /** * Get size of currently used offline trace buffer * @return size in bytes */ extern unsigned long dlt_offline_trace_get_total_size(DltOfflineTrace *trace); /** * Provides info about the offline logs storage directory * @param path path of the storage directory * @param file_name filename to search for * @param newest pointer to store newest filename * @param oldest pointer to store oldest filename * @return num of files in the directory */ unsigned int dlt_offline_trace_storage_dir_info(char *path, char *file_name, char *newest, char *oldest); /** * creates filename with index * @param log_file_name file name created with index * @param name filename base * @param idx index to be used for file name creation */ void dlt_offline_trace_file_name(char *log_file_name, char *name, unsigned int idx); /** * generates index for log file name * @param file filename supplied to create index * @return the index to be used for log file name */ unsigned int dlt_offline_trace_get_idx_of_log_file(char *file); #endif /* DLT_OFFLINE_TRACE_H */ dlt-daemon-2.18.4/include/dlt/dlt_protocol.h000066400000000000000000000250451353342203500207230ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2011-2015, BMW AG * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author Alexander Wenzel * * \copyright Copyright © 2011-2015 BMW AG. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file dlt_protocol.h */ /******************************************************************************* ** ** ** SRC-MODULE: dlt_protocol.h ** ** ** ** TARGET : linux ** ** ** ** PROJECT : DLT ** ** ** ** AUTHOR : Alexander Wenzel Alexander.AW.Wenzel@bmw.de ** ** Markus Klein ** ** ** ** PURPOSE : ** ** ** ** REMARKS : ** ** ** ** PLATFORM DEPENDANT [yes/no]: yes ** ** ** ** TO BE CHANGED BY USER [yes/no]: no ** ** ** *******************************************************************************/ /******************************************************************************* ** Author Identity ** ******************************************************************************** ** ** ** Initials Name Company ** ** -------- ------------------------- ---------------------------------- ** ** aw Alexander Wenzel BMW ** ** mk Markus Klein Fraunhofer ESK ** *******************************************************************************/ /******************************************************************************* ** Revision Control History ** *******************************************************************************/ /* * $LastChangedRevision$ * $LastChangedDate$ * $LastChangedBy$ * Initials Date Comment * aw 13.01.2010 initial */ #ifndef DLT_PROTOCOL_H #define DLT_PROTOCOL_H /** * \defgroup protocolapi DLT Protocol API * \addtogroup protocolapi \{ */ /* * Definitions of the htyp parameter in standard header. */ #define DLT_HTYP_UEH 0x01 /**< use extended header */ #define DLT_HTYP_MSBF 0x02 /**< MSB first */ #define DLT_HTYP_WEID 0x04 /**< with ECU ID */ #define DLT_HTYP_WSID 0x08 /**< with session ID */ #define DLT_HTYP_WTMS 0x10 /**< with timestamp */ #define DLT_HTYP_VERS 0xe0 /**< version number, 0x1 */ #define DLT_IS_HTYP_UEH(htyp) ((htyp) & DLT_HTYP_UEH) #define DLT_IS_HTYP_MSBF(htyp) ((htyp) & DLT_HTYP_MSBF) #define DLT_IS_HTYP_WEID(htyp) ((htyp) & DLT_HTYP_WEID) #define DLT_IS_HTYP_WSID(htyp) ((htyp) & DLT_HTYP_WSID) #define DLT_IS_HTYP_WTMS(htyp) ((htyp) & DLT_HTYP_WTMS) #define DLT_HTYP_PROTOCOL_VERSION1 (1 << 5) /* * Definitions of msin parameter in extended header. */ #define DLT_MSIN_VERB 0x01 /**< verbose */ #define DLT_MSIN_MSTP 0x0e /**< message type */ #define DLT_MSIN_MTIN 0xf0 /**< message type info */ #define DLT_MSIN_MSTP_SHIFT 1 /**< shift right offset to get mstp value */ #define DLT_MSIN_MTIN_SHIFT 4 /**< shift right offset to get mtin value */ #define DLT_IS_MSIN_VERB(msin) ((msin) & DLT_MSIN_VERB) #define DLT_GET_MSIN_MSTP(msin) (((msin) & DLT_MSIN_MSTP) >> DLT_MSIN_MSTP_SHIFT) #define DLT_GET_MSIN_MTIN(msin) (((msin) & DLT_MSIN_MTIN) >> DLT_MSIN_MTIN_SHIFT) /* * Definitions of mstp parameter in extended header. */ #define DLT_TYPE_LOG 0x00 /**< Log message type */ #define DLT_TYPE_APP_TRACE 0x01 /**< Application trace message type */ #define DLT_TYPE_NW_TRACE 0x02 /**< Network trace message type */ #define DLT_TYPE_CONTROL 0x03 /**< Control message type */ /* * Definitions of msti parameter in extended header. */ #define DLT_TRACE_VARIABLE 0x01 /**< tracing of a variable */ #define DLT_TRACE_FUNCTION_IN 0x02 /**< tracing of function calls */ #define DLT_TRACE_FUNCTION_OUT 0x03 /**< tracing of function return values */ #define DLT_TRACE_STATE 0x04 /**< tracing of states of a state machine */ #define DLT_TRACE_VFB 0x05 /**< tracing of virtual function bus */ /* * Definitions of msbi parameter in extended header. */ /* see file dlt_user.h */ /* * Definitions of msci parameter in extended header. */ #define DLT_CONTROL_REQUEST 0x01 /**< Request message */ #define DLT_CONTROL_RESPONSE 0x02 /**< Response to request message */ #define DLT_CONTROL_TIME 0x03 /**< keep-alive message */ #define DLT_MSIN_CONTROL_REQUEST ((DLT_TYPE_CONTROL << DLT_MSIN_MSTP_SHIFT) | \ (DLT_CONTROL_REQUEST << DLT_MSIN_MTIN_SHIFT)) #define DLT_MSIN_CONTROL_RESPONSE ((DLT_TYPE_CONTROL << DLT_MSIN_MSTP_SHIFT) | \ (DLT_CONTROL_RESPONSE << DLT_MSIN_MTIN_SHIFT)) #define DLT_MSIN_CONTROL_TIME ((DLT_TYPE_CONTROL << DLT_MSIN_MSTP_SHIFT) | \ (DLT_CONTROL_TIME << DLT_MSIN_MTIN_SHIFT)) /* * Definitions of types of arguments in payload. */ #define DLT_TYPE_INFO_TYLE 0x0000000f /**< Length of standard data: 1 = 8bit, 2 = 16bit, 3 = 32 bit, 4 = 64 bit, 5 = 128 bit */ #define DLT_TYPE_INFO_BOOL 0x00000010 /**< Boolean data */ #define DLT_TYPE_INFO_SINT 0x00000020 /**< Signed integer data */ #define DLT_TYPE_INFO_UINT 0x00000040 /**< Unsigned integer data */ #define DLT_TYPE_INFO_FLOA 0x00000080 /**< Float data */ #define DLT_TYPE_INFO_ARAY 0x00000100 /**< Array of standard types */ #define DLT_TYPE_INFO_STRG 0x00000200 /**< String */ #define DLT_TYPE_INFO_RAWD 0x00000400 /**< Raw data */ #define DLT_TYPE_INFO_VARI 0x00000800 /**< Set, if additional information to a variable is available */ #define DLT_TYPE_INFO_FIXP 0x00001000 /**< Set, if quantization and offset are added */ #define DLT_TYPE_INFO_TRAI 0x00002000 /**< Set, if additional trace information is added */ #define DLT_TYPE_INFO_STRU 0x00004000 /**< Struct */ #define DLT_TYPE_INFO_SCOD 0x00038000 /**< coding of the type string: 0 = ASCII, 1 = UTF-8 */ #define DLT_TYLE_8BIT 0x00000001 #define DLT_TYLE_16BIT 0x00000002 #define DLT_TYLE_32BIT 0x00000003 #define DLT_TYLE_64BIT 0x00000004 #define DLT_TYLE_128BIT 0x00000005 #define DLT_SCOD_ASCII 0x00000000 #define DLT_SCOD_UTF8 0x00008000 #define DLT_SCOD_HEX 0x00010000 #define DLT_SCOD_BIN 0x00018000 /* * Definitions of DLT services. */ #define DLT_SERVICE_ID_CALLSW_CINJECTION 0xFFF enum dlt_services { DLT_SERVICE_ID = 0x00, DLT_SERVICE_ID_SET_LOG_LEVEL = 0x01, DLT_SERVICE_ID_SET_TRACE_STATUS = 0x02, DLT_SERVICE_ID_GET_LOG_INFO = 0x03, DLT_SERVICE_ID_GET_DEFAULT_LOG_LEVEL = 0x04, DLT_SERVICE_ID_STORE_CONFIG = 0x05, DLT_SERVICE_ID_RESET_TO_FACTORY_DEFAULT = 0x06, DLT_SERVICE_ID_SET_COM_INTERFACE_STATUS = 0x07, DLT_SERVICE_ID_SET_COM_INTERFACE_MAX_BANDWIDTH = 0x08, DLT_SERVICE_ID_SET_VERBOSE_MODE = 0x09, DLT_SERVICE_ID_SET_MESSAGE_FILTERING = 0x0A, DLT_SERVICE_ID_SET_TIMING_PACKETS = 0x0B, DLT_SERVICE_ID_GET_LOCAL_TIME = 0x0C, DLT_SERVICE_ID_USE_ECU_ID = 0x0D, DLT_SERVICE_ID_USE_SESSION_ID = 0x0E, DLT_SERVICE_ID_USE_TIMESTAMP = 0x0F, DLT_SERVICE_ID_USE_EXTENDED_HEADER = 0x10, DLT_SERVICE_ID_SET_DEFAULT_LOG_LEVEL = 0x11, DLT_SERVICE_ID_SET_DEFAULT_TRACE_STATUS = 0x12, DLT_SERVICE_ID_GET_SOFTWARE_VERSION = 0x13, DLT_SERVICE_ID_MESSAGE_BUFFER_OVERFLOW = 0x14, DLT_SERVICE_ID_LAST_ENTRY }; enum dlt_user_services { DLT_USER_SERVICE_ID = 0xF00, DLT_SERVICE_ID_UNREGISTER_CONTEXT = 0xF01, DLT_SERVICE_ID_CONNECTION_INFO = 0xF02, DLT_SERVICE_ID_TIMEZONE = 0xF03, DLT_SERVICE_ID_MARKER = 0xF04, DLT_SERVICE_ID_OFFLINE_LOGSTORAGE = 0xF05, DLT_SERVICE_ID_PASSIVE_NODE_CONNECT = 0xF06, DLT_SERVICE_ID_PASSIVE_NODE_CONNECTION_STATUS = 0xF07, DLT_SERVICE_ID_SET_ALL_LOG_LEVEL = 0xF08, DLT_SERVICE_ID_SET_ALL_TRACE_STATUS = 0xF09, DLT_SERVICE_ID_RESERVED_B = 0xF0B, DLT_SERVICE_ID_RESERVED_C = 0xF0C, DLT_SERVICE_ID_RESERVED_D = 0xF0D, DLT_SERVICE_ID_RESERVED_E = 0xF0E, DLT_USER_SERVICE_ID_LAST_ENTRY }; /* Need to be adapted if another service is added */ extern const char *const dlt_service_names[]; extern const char *const dlt_user_service_names[]; extern const char *dlt_get_service_name(unsigned int id); /* * Definitions of DLT service response status */ #define DLT_SERVICE_RESPONSE_OK 0x00 /**< Control message response: OK */ #define DLT_SERVICE_RESPONSE_NOT_SUPPORTED 0x01 /**< Control message response: Not supported */ #define DLT_SERVICE_RESPONSE_ERROR 0x02 /**< Control message response: Error */ #define DLT_SERVICE_RESPONSE_PERM_DENIED 0x03 /**< Control message response: Permission denied */ #define DLT_SERVICE_RESPONSE_WARNING 0x04 /**< Control message response: warning */ #define DLT_SERVICE_RESPONSE_LAST 0x05 /**< Used as max value */ /* * Definitions of DLT service connection state */ #define DLT_CONNECTION_STATUS_DISCONNECTED 0x01 /**< Client is disconnected */ #define DLT_CONNECTION_STATUS_CONNECTED 0x02 /**< Client is connected */ /* * Definitions of DLT GET_LOG_INFO status */ #define GET_LOG_INFO_STATUS_MIN 3 #define GET_LOG_INFO_STATUS_MAX 7 #define GET_LOG_INFO_STATUS_NO_MATCHING_CTX 8 #define GET_LOG_INFO_STATUS_RESP_DATA_OVERFLOW 9 /** \} */ #endif /* DLT_PROTOCOL_H */ dlt-daemon-2.18.4/include/dlt/dlt_shm.h000066400000000000000000000172441353342203500176530ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2011-2015, BMW AG * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author Alexander Wenzel * * \copyright Copyright © 2011-2015 BMW AG. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file dlt_shm.h */ /******************************************************************************* ** ** ** SRC-MODULE: dlt_shm.h ** ** ** ** TARGET : linux ** ** ** ** PROJECT : DLT ** ** ** ** AUTHOR : Alexander Wenzel Alexander.AW.Wenzel@bmw.de ** ** ** ** PURPOSE : ** ** ** ** REMARKS : ** ** ** ** PLATFORM DEPENDANT [yes/no]: yes ** ** ** ** TO BE CHANGED BY USER [yes/no]: no ** ** ** *******************************************************************************/ /******************************************************************************* ** Author Identity ** ******************************************************************************** ** ** ** Initials Name Company ** ** -------- ------------------------- ---------------------------------- ** ** aw Alexander Wenzel BMW ** *******************************************************************************/ #ifndef DLT_SHM_H #define DLT_SHM_H #include #include "dlt_common.h" /** * Default size of shared memory. * size is extended during creation to fit segment size. * client retrieves real size from file descriptor of shared memory. */ #define DLT_SHM_SIZE 100000 typedef struct { int shmfd; /* file descriptor of shared memory */ sem_t *sem; /* pointer to semaphore */ DltBuffer buffer; } DltShm; typedef struct { char head[4]; unsigned char status; int size; } DltShmBlockHead; #define DLT_SHM_SEM_GET(id) sem_wait(id) #define DLT_SHM_SEM_FREE(id) sem_post(id) /** * Initialise the shared memory on the client side. * This function must be called before using further shm functions. * @param buf pointer to shm structure * @param name the name of the shm, must be the same for server and client * @return negative value if there was an error */ extern DltReturnValue dlt_shm_init_client(DltShm *buf, const char *name); /** * Initialise the shared memory on the server side. * This function must be called before using further shm functions. * @param buf pointer to shm structure * @param name the name of the shm, must be the same for server and client * @param size the requested size of the shm * @return negative value if there was an error */ extern DltReturnValue dlt_shm_init_server(DltShm *buf, const char *name, int size); /** * Push data from client onto the shm. * @param buf pointer to shm structure * @param data1 pointer to first data block to be written, null if not used * @param size1 size in bytes of first data block to be written, 0 if not used * @param data2 pointer to second data block to be written, null if not used * @param size2 size in bytes of second data block to be written, 0 if not used * @param data3 pointer to third data block to be written, null if not used * @param size3 size in bytes of third data block to be written, 0 if not used * @return negative value if there was an error */ extern int dlt_shm_push(DltShm *buf, const unsigned char *data1, unsigned int size1, const unsigned char *data2, unsigned int size2, const unsigned char *data3, unsigned int size3); /** * Pull data from shm. * This function should be called from client. * Data is deleted from shm after this call. * @param buf pointer to shm structure * @param data pointer to buffer where data is to be written * @param size maximum size to be written into buffer * @return negative value if there was an error */ extern int dlt_shm_pull(DltShm *buf, unsigned char *data, int size); /** * Copy message from shm. * This function should be called from server. * Data is not deleted from shm after this call. * @param buf pointer to shm structure * @param data pointer to buffer where data is to be written * @param size maximum size to be written into buffer * @return negative value if there was an error */ extern int dlt_shm_copy(DltShm *buf, unsigned char *data, int size); /** * Delete message from shm. * This function should be called from server. * This function should be called after each succesful copy. * @param buf pointer to shm structure * @return negative value if there was an error */ extern int dlt_shm_remove(DltShm *buf); /** * Print information about shm. * @param buf pointer to shm structure */ extern void dlt_shm_info(DltShm *buf); /** * Print status about shm. * @param buf pointer to shm structure */ extern void dlt_shm_status(DltShm *buf); /** * Deinitialise the shared memory on the client side. * @param buf pointer to shm structure * @return negative value if there was an error */ extern DltReturnValue dlt_shm_free_client(DltShm *buf); /** * Returns the total size of the shm. * @param buf pointer to shm structure * @return size of the shared memory. */ extern int dlt_shm_get_total_size(DltShm *buf); /** * Returns the used size in the shm. * @param buf pointer to shm structure * @return size of the shared memory. */ extern int dlt_shm_get_used_size(DltShm *buf); /** * Returns the number of messages in the shm. * @param buf pointer to shm structure * @return size of the shared memory. */ extern int dlt_shm_get_message_count(DltShm *buf); /** * Reset pointers and counters when shm corrupted. * @param buf pointer to shm structure * @return size of the shared memory. */ extern int dlt_shm_reset(DltShm *buf); /** * Recover to find next valid message. * @param buf pointer to shm structure * @return size of the shared memory. */ extern int dlt_shm_recover(DltShm *buf); /** * Deinitialise the shared memory on the server side. * @param buf pointer to shm structure * @param name name of the shared memory * @return negative value if there was an error */ extern DltReturnValue dlt_shm_free_server(DltShm *buf, const char *name); #endif /* DLT_SHM_H */ dlt-daemon-2.18.4/include/dlt/dlt_types.h000066400000000000000000000156031353342203500202250ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2011-2015, BMW AG * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author Alexander Wenzel * * \copyright Copyright © 2011-2015 BMW AG. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file dlt_types.h */ /******************************************************************************* ** ** ** SRC-MODULE: dlt_types.h ** ** ** ** TARGET : linux ** ** ** ** PROJECT : DLT ** ** ** ** AUTHOR : Alexander Wenzel Alexander.AW.Wenzel@bmw.de ** ** Markus Klein ** ** ** ** PURPOSE : ** ** ** ** REMARKS : ** ** ** ** PLATFORM DEPENDANT [yes/no]: yes ** ** ** ** TO BE CHANGED BY USER [yes/no]: no ** ** ** *******************************************************************************/ /******************************************************************************* ** Author Identity ** ******************************************************************************** ** ** ** Initials Name Company ** ** -------- ------------------------- ---------------------------------- ** ** aw Alexander Wenzel BMW ** ** mk Markus Klein Fraunhofer ESK ** *******************************************************************************/ #ifndef DLT_TYPES_H #define DLT_TYPES_H #ifdef _MSC_VER typedef __int64 int64_t; typedef __int32 int32_t; typedef __int16 int16_t; typedef __int8 int8_t; typedef unsigned __int64 uint64_t; typedef unsigned __int32 uint32_t; typedef unsigned __int16 uint16_t; typedef unsigned __int8 uint8_t; typedef int pid_t; typedef unsigned int speed_t; # define UINT16_MAX 0xFFFF # include #else # include #endif /** * Definitions of DLT return values */ typedef enum { DLT_RETURN_LOGGING_DISABLED = -7, DLT_RETURN_USER_BUFFER_FULL = -6, DLT_RETURN_WRONG_PARAMETER = -5, DLT_RETURN_BUFFER_FULL = -4, DLT_RETURN_PIPE_FULL = -3, DLT_RETURN_PIPE_ERROR = -2, DLT_RETURN_ERROR = -1, DLT_RETURN_OK = 0, DLT_RETURN_TRUE = 1 } DltReturnValue; /** * Definitions of DLT log level */ typedef enum { DLT_LOG_DEFAULT = -1, /**< Default log level */ DLT_LOG_OFF = 0x00, /**< Log level off */ DLT_LOG_FATAL = 0x01, /**< fatal system error */ DLT_LOG_ERROR = 0x02, /**< error with impact to correct functionality */ DLT_LOG_WARN = 0x03, /**< warning, correct behaviour could not be ensured */ DLT_LOG_INFO = 0x04, /**< informational */ DLT_LOG_DEBUG = 0x05, /**< debug */ DLT_LOG_VERBOSE = 0x06, /**< highest grade of information */ DLT_LOG_MAX /**< maximum value, used for range check */ } DltLogLevelType; /** * Definitions of DLT Format */ typedef enum { DLT_FORMAT_DEFAULT = 0x00, /**< no sepecial format */ DLT_FORMAT_HEX8 = 0x01, /**< Hex 8 */ DLT_FORMAT_HEX16 = 0x02, /**< Hex 16 */ DLT_FORMAT_HEX32 = 0x03, /**< Hex 32 */ DLT_FORMAT_HEX64 = 0x04, /**< Hex 64 */ DLT_FORMAT_BIN8 = 0x05, /**< Binary 8 */ DLT_FORMAT_BIN16 = 0x06, /**< Binary 16 */ DLT_FORMAT_MAX /**< maximum value, used for range check */ } DltFormatType; /** * Definitions of DLT trace status */ typedef enum { DLT_TRACE_STATUS_DEFAULT = -1, /**< Default trace status */ DLT_TRACE_STATUS_OFF = 0x00, /**< Trace status: Off */ DLT_TRACE_STATUS_ON = 0x01, /**< Trace status: On */ DLT_TRACE_STATUS_MAX /**< maximum value, used for range check */ } DltTraceStatusType; /** * Definitions for dlt_user_trace_network/DLT_TRACE_NETWORK() * as defined in the DLT protocol */ typedef enum { DLT_NW_TRACE_IPC = 0x01, /**< Interprocess communication */ DLT_NW_TRACE_CAN = 0x02, /**< Controller Area Network Bus */ DLT_NW_TRACE_FLEXRAY = 0x03, /**< Flexray Bus */ DLT_NW_TRACE_MOST = 0x04, /**< Media Oriented System Transport Bus */ DLT_NW_TRACE_RESERVED0 = 0x05, DLT_NW_TRACE_RESERVED1 = 0x06, DLT_NW_TRACE_RESERVED2 = 0x07, DLT_NW_TRACE_USER_DEFINED0 = 0x08, DLT_NW_TRACE_USER_DEFINED1 = 0x09, DLT_NW_TRACE_USER_DEFINED2 = 0x0A, DLT_NW_TRACE_USER_DEFINED3 = 0x0B, DLT_NW_TRACE_USER_DEFINED4 = 0x0C, DLT_NW_TRACE_USER_DEFINED5 = 0x0D, DLT_NW_TRACE_USER_DEFINED6 = 0x0E, DLT_NW_TRACE_RESEND = 0x0F, /**< Mark a resend */ DLT_NW_TRACE_MAX /**< maximum value, used for range check */ } DltNetworkTraceType; /** * This are the log modes. */ typedef enum { DLT_USER_MODE_UNDEFINED = -1, DLT_USER_MODE_OFF = 0, DLT_USER_MODE_EXTERNAL, DLT_USER_MODE_INTERNAL, DLT_USER_MODE_BOTH, DLT_USER_MODE_MAX /**< maximum value, used for range check */ } DltUserLogMode; typedef float float32_t; typedef double float64_t; #ifdef DLT_USE_UNIX_SOCKET_IPC /** * Definition Library connection state */ typedef enum { DLT_USER_NOT_CONNECTED = 0, DLT_USER_CONNECTED, DLT_USER_RETRY_CONNECT } DltUserConnectionState; #endif #endif /* DLT_TYPES_H */ dlt-daemon-2.18.4/include/dlt/dlt_user.h000066400000000000000000001200271353342203500200340ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2011-2015, BMW AG * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author Alexander Wenzel * * \copyright Copyright © 2011-2015 BMW AG. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file dlt_user.h */ /******************************************************************************* ** ** ** SRC-MODULE: dlt_user.h ** ** ** ** TARGET : linux ** ** ** ** PROJECT : DLT ** ** ** ** AUTHOR : Alexander Wenzel Alexander.AW.Wenzel@bmw.de ** ** Markus Klein ** ** ** ** PURPOSE : ** ** ** ** REMARKS : ** ** ** ** PLATFORM DEPENDANT [yes/no]: yes ** ** ** ** TO BE CHANGED BY USER [yes/no]: no ** ** ** *******************************************************************************/ /******************************************************************************* ** Author Identity ** ******************************************************************************** ** ** ** Initials Name Company ** ** -------- ------------------------- ---------------------------------- ** ** aw Alexander Wenzel BMW ** ** mk Markus Klein Fraunhofer ESK ** *******************************************************************************/ /******************************************************************************* ** Revision Control History ** *******************************************************************************/ /* * $LastChangedRevision: 1670 $ * $LastChangedDate: 2011-04-08 15:12:06 +0200 (Fr, 08. Apr 2011) $ * $LastChangedBy$ * Initials Date Comment * aw 13.01.2010 initial */ #ifndef DLT_USER_H # define DLT_USER_H /** * \defgroup userapi DLT User API * \addtogroup userapi \{ */ # include # if !defined (__WIN32__) # include # endif # include "dlt_types.h" # include "dlt_user_macros.h" # include "dlt_shm.h" # ifdef __cplusplus extern "C" { # endif # define DLT_USER_BUF_MAX_SIZE 1390 /**< maximum size of each user buffer, also used for injection buffer */ # define DLT_USER_RESENDBUF_MAX_SIZE (DLT_USER_BUF_MAX_SIZE + 100) /**< Size of resend buffer; Max DLT message size is 1390 bytes plus some extra header space */ /* Use a semaphore or mutex from your OS to prevent concurrent access to the DLT buffer. */ #define DLT_SEM_LOCK() do{\ while ((sem_wait(&dlt_mutex) == -1) && (errno == EINTR)) \ continue; /* Restart if interrupted */ \ } while(0) #define DLT_SEM_FREE() { sem_post(&dlt_mutex); } /** * This structure is used for every context used in an application. */ typedef struct { char contextID[DLT_ID_SIZE]; /**< context id */ int32_t log_level_pos; /**< offset in user-application context field */ int8_t *log_level_ptr; /**< pointer to the log level */ int8_t *trace_status_ptr; /**< pointer to the trace status */ uint8_t mcnt; /**< message counter */ } DltContext; /** * This structure is used for context data used in an application. */ typedef struct { DltContext *handle; /**< pointer to DltContext */ unsigned char *buffer; /**< buffer for building log message*/ int32_t size; /**< payload size */ int32_t log_level; /**< log level */ int32_t trace_status; /**< trace status */ int32_t args_num; /**< number of arguments for extended header*/ char *context_description; /**< description of context */ } DltContextData; typedef struct { uint32_t service_id; int (*injection_callback)(uint32_t service_id, void *data, uint32_t length); int (*injection_callback_with_id)(uint32_t service_id, void *data, uint32_t length, void *priv_data); void *data; } DltUserInjectionCallback; typedef struct { char contextID[DLT_ID_SIZE]; /**< Context ID */ int8_t log_level; /**< Log level */ int8_t trace_status; /**< Trace status */ void (*log_level_changed_callback)(char context_id[DLT_ID_SIZE], uint8_t log_level, uint8_t trace_status); } DltUserLogLevelChangedCallback; /** * This structure is used in a table managing all contexts and the corresponding log levels in an application. */ typedef struct { char contextID[DLT_ID_SIZE]; /**< Context ID */ int8_t log_level; /**< Log level */ int8_t *log_level_ptr; /**< Ptr to the log level */ int8_t trace_status; /**< Trace status */ int8_t *trace_status_ptr; /**< Ptr to the trace status */ char *context_description; /**< description of context */ DltUserInjectionCallback *injection_table; /**< Table with pointer to injection functions and service ids */ uint32_t nrcallbacks; /* Log Level changed callback */ void (*log_level_changed_callback)(char context_id[DLT_ID_SIZE], uint8_t log_level, uint8_t trace_status); } dlt_ll_ts_type; /** * @brief holds initial log-level for given appId:ctxId pair */ typedef struct { char appId[DLT_ID_SIZE]; char ctxId[DLT_ID_SIZE]; int8_t ll; } dlt_env_ll_item; /** * @brief holds all initial log-levels given via environment variable DLT_INITIAL_LOG_LEVEL */ typedef struct { dlt_env_ll_item *item; size_t array_size; size_t num_elem; } dlt_env_ll_set; /** * This structure is used once for one application. */ typedef struct { char ecuID[DLT_ID_SIZE]; /**< ECU ID */ char appID[DLT_ID_SIZE]; /**< Application ID */ int dlt_log_handle; /**< Handle to fifo of dlt daemon */ int dlt_user_handle; /**< Handle to own fifo */ mqd_t dlt_segmented_queue_read_handle; /**< Handle message queue */ mqd_t dlt_segmented_queue_write_handle; /**< Handle message queue */ pthread_t dlt_segmented_nwt_handle; /**< thread handle of segmented sending */ int8_t dlt_is_file; /**< Target of logging: 1 to file, 0 to daemon */ dlt_ll_ts_type *dlt_ll_ts; /** [MAX_DLT_LL_TS_ENTRIES]; < Internal management struct for all * contexts */ uint32_t dlt_ll_ts_max_num_entries; /**< Maximum number of contexts */ uint32_t dlt_ll_ts_num_entries; /**< Number of used contexts */ int8_t overflow; /**< Overflow marker, set to 1 on overflow, 0 otherwise */ uint32_t overflow_counter; /**< Counts the number of lost messages */ char *application_description; /**< description of application */ DltReceiver receiver; /**< Receiver for internal user-defined messages from daemon */ int8_t verbose_mode; /**< Verbose mode enabled: 1 enabled, 0 disabled */ int8_t use_extende_header_for_non_verbose; /**< Use extended header for non verbose: 1 enabled, 0 disabled */ int8_t with_session_id; /**< Send always session id: 1 enabled, 0 disabled */ int8_t with_timestamp; /**< Send always timestamp: 1 enabled, 0 disabled */ int8_t with_ecu_id; /**< Send always ecu id: 1 enabled, 0 disabled */ int8_t enable_local_print; /**< Local printing of log messages: 1 enabled, 0 disabled */ int8_t local_print_mode; /**< Local print mode, controlled by environment variable */ int8_t log_state; /**< Log state of external connection: * 1 client connected, * 0 not connected, * -1 unknown */ DltBuffer startup_buffer; /**< Ring-buffer for buffering messages during startup and missing connection */ /* Buffer used for resending, locked by DLT semaphore */ uint8_t *resend_buffer; uint32_t timeout_at_exit_handler; /**< timeout used in dlt_user_atexit_blow_out_user_buffer, in 0.1 milliseconds */ dlt_env_ll_set initial_ll_set; # ifdef DLT_SHM_ENABLE DltShm dlt_shm; # endif # ifdef DLT_TEST_ENABLE int corrupt_user_header; int corrupt_message_size; int16_t corrupt_message_size_size; # endif # ifdef DLT_USE_UNIX_SOCKET_IPC DltUserConnectionState connection_state; # endif uint16_t log_buf_len; /**< length of message buffer, by default: DLT_USER_BUF_MAX_SIZE */ } DltUser; typedef int (*dlt_injection_callback_id)(uint32_t, void *, uint32_t, void *); typedef int (*dlt_injection_callback)(uint32_t, void *, uint32_t); /************************************************************************************************** * The following API functions define a low level function interface for DLT **************************************************************************************************/ /** * Initialize the generation of a DLT log message (intended for usage in verbose mode) * This function has to be called first, when an application wants to send a new log messages. * Following functions like dlt_user_log_write_string and dlt_user_log_write_finish must only be called, * when return value is bigger than zero. * @param handle pointer to an object containing information about one special logging context * @param log pointer to an object containing information about logging context data * @param loglevel this is the current log level of the log message to be sent * @return Value from DltReturnValue enum, DLT_RETURN_TRUE if log level is matching */ DltReturnValue dlt_user_log_write_start(DltContext *handle, DltContextData *log, DltLogLevelType loglevel); /** * Initialize the generation of a DLT log message (intended for usage in non-verbose mode) * This function has to be called first, when an application wants to send a new log messages. * Following functions like dlt_user_log_write_string and dlt_user_log_write_finish must only be called, * when return value is bigger than zero. * @param handle pointer to an object containing information about one special logging context * @param log pointer to an object containing information about logging context data * @param loglevel this is the current log level of the log message to be sent * @param messageid message id of message * @return Value from DltReturnValue enum, DLT_RETURN_TRUE if log level is matching */ DltReturnValue dlt_user_log_write_start_id(DltContext *handle, DltContextData *log, DltLogLevelType loglevel, uint32_t messageid); /** * Finishing the generation of a DLT log message and sending it to the DLT daemon. * This function has to be called after writing all the log attributes of a log message. * @param log pointer to an object containing information about logging context data * @return Value from DltReturnValue enum */ DltReturnValue dlt_user_log_write_finish(DltContextData *log); /** * Write a boolean parameter into a DLT log message. * dlt_user_log_write_start has to be called before adding any attributes to the log message. * Finish sending log message by calling dlt_user_log_write_finish. * @param log pointer to an object containing information about logging context data * @param data boolean parameter written into log message (mapped to uint8) * @return Value from DltReturnValue enum */ DltReturnValue dlt_user_log_write_bool(DltContextData *log, uint8_t data); /** * Write a float parameter into a DLT log message. * dlt_user_log_write_start has to be called before adding any attributes to the log message. * Finish sending log message by calling dlt_user_log_write_finish. * @param log pointer to an object containing information about logging context data * @param data float32_t parameter written into log message. * @return Value from DltReturnValue enum */ DltReturnValue dlt_user_log_write_float32(DltContextData *log, float32_t data); /** * Write a double parameter into a DLT log message. * dlt_user_log_write_start has to be called before adding any attributes to the log message. * Finish sending log message by calling dlt_user_log_write_finish. * @param log pointer to an object containing information about logging context data * @param data float64_t parameter written into log message. * @return Value from DltReturnValue enum */ DltReturnValue dlt_user_log_write_float64(DltContextData *log, double data); /** * Write a uint parameter into a DLT log message. * dlt_user_log_write_start has to be called before adding any attributes to the log message. * Finish sending log message by calling dlt_user_log_write_finish. * @param log pointer to an object containing information about logging context data * @param data unsigned int parameter written into log message. * @return Value from DltReturnValue enum */ DltReturnValue dlt_user_log_write_uint(DltContextData *log, unsigned int data); DltReturnValue dlt_user_log_write_uint8(DltContextData *log, uint8_t data); DltReturnValue dlt_user_log_write_uint16(DltContextData *log, uint16_t data); DltReturnValue dlt_user_log_write_uint32(DltContextData *log, uint32_t data); DltReturnValue dlt_user_log_write_uint64(DltContextData *log, uint64_t data); /** * Write a uint parameter into a DLT log message. The output will be formatted as given by the parameter type. * dlt_user_log_write_start has to be called before adding any attributes to the log message. * Finish sending log message by calling dlt_user_log_write_finish. * @param log pointer to an object containing information about logging context data * @param data unsigned int parameter written into log message. * @param type The formatting type of the string output. * @return Value from DltReturnValue enum */ DltReturnValue dlt_user_log_write_uint8_formatted(DltContextData *log, uint8_t data, DltFormatType type); DltReturnValue dlt_user_log_write_uint16_formatted(DltContextData *log, uint16_t data, DltFormatType type); DltReturnValue dlt_user_log_write_uint32_formatted(DltContextData *log, uint32_t data, DltFormatType type); DltReturnValue dlt_user_log_write_uint64_formatted(DltContextData *log, uint64_t data, DltFormatType type); /** * Write a pointer value architecture independent. * dlt_user_log_write_start has to be called before adding any attributes to the log message. * Finish sending log message by calling dlt_user_log_write_finish. * @param log pointer to an object containing information about logging context data * @param data void* parameter written into log message. * @return Value from DltReturnValue enum */ DltReturnValue dlt_user_log_write_ptr(DltContextData *log, void *data); /** * Write a int parameter into a DLT log message. * dlt_user_log_write_start has to be called before adding any attributes to the log message. * Finish sending log message by calling dlt_user_log_write_finish. * @param log pointer to an object containing information about logging context data * @param data int parameter written into log message. * @return Value from DltReturnValue enum */ DltReturnValue dlt_user_log_write_int(DltContextData *log, int data); DltReturnValue dlt_user_log_write_int8(DltContextData *log, int8_t data); DltReturnValue dlt_user_log_write_int16(DltContextData *log, int16_t data); DltReturnValue dlt_user_log_write_int32(DltContextData *log, int32_t data); DltReturnValue dlt_user_log_write_int64(DltContextData *log, int64_t data); /** * Write a null terminated ASCII string into a DLT log message. * dlt_user_log_write_start has to be called before adding any attributes to the log message. * Finish sending log message by calling dlt_user_log_write_finish. * @param log pointer to an object containing information about logging context data * @param text pointer to the parameter written into log message containing null termination. * @return Value from DltReturnValue enum */ DltReturnValue dlt_user_log_write_string(DltContextData *log, const char *text); /** * Write a constant null terminated ASCII string into a DLT log message. * In non verbose mode DLT parameter will not be send at all. * dlt_user_log_write_start has to be called before adding any attributes to the log message. * Finish sending log message by calling dlt_user_log_write_finish. * @param log pointer to an object containing information about logging context data * @param text pointer to the parameter written into log message containing null termination. * @return Value from DltReturnValue enum */ DltReturnValue dlt_user_log_write_constant_string(DltContextData *log, const char *text); /** * Write a null terminated UTF8 string into a DLT log message. * dlt_user_log_write_start has to be called before adding any attributes to the log message. * Finish sending log message by calling dlt_user_log_write_finish. * @param log pointer to an object containing information about logging context data * @param text pointer to the parameter written into log message containing null termination. * @return Value from DltReturnValue enum */ DltReturnValue dlt_user_log_write_utf8_string(DltContextData *log, const char *text); /** * Write a binary memory block into a DLT log message. * dlt_user_log_write_start has to be called before adding any attributes to the log message. * Finish sending log message by calling dlt_user_log_write_finish. * @param log pointer to an object containing information about logging context data * @param data pointer to the parameter written into log message. * @param length length in bytes of the parameter written into log message. * @return Value from DltReturnValue enum */ DltReturnValue dlt_user_log_write_raw(DltContextData *log, void *data, uint16_t length); /** * Write a binary memory block into a DLT log message. * dlt_user_log_write_start has to be called before adding any attributes to the log message. * Finish sending log message by calling dlt_user_log_write_finish. * @param log pointer to an object containing information about logging context data * @param data pointer to the parameter written into log message. * @param length length in bytes of the parameter written into log message. * @param type the format information. * @return Value from DltReturnValue enum */ DltReturnValue dlt_user_log_write_raw_formatted(DltContextData *log, void *data, uint16_t length, DltFormatType type); /** * Trace network message * @param handle pointer to an object containing information about one special logging context * @param nw_trace_type type of network trace (DLT_NW_TRACE_IPC, DLT_NW_TRACE_CAN, DLT_NW_TRACE_FLEXRAY, or DLT_NW_TRACE_MOST) * @param header_len length of network message header * @param header pointer to network message header * @param payload_len length of network message payload * @param payload pointer to network message payload * @return Value from DltReturnValue enum */ DltReturnValue dlt_user_trace_network(DltContext *handle, DltNetworkTraceType nw_trace_type, uint16_t header_len, void *header, uint16_t payload_len, void *payload); /** * Trace network message, truncated if necessary. * @param handle pointer to an object containing information about logging context * @param nw_trace_type type of network trace (DLT_NW_TRACE_IPC, DLT_NW_TRACE_CAN, DLT_NW_TRACE_FLEXRAY, or DLT_NW_TRACE_MOST) * @param header_len length of network message header * @param header pointer to network message header * @param payload_len length of network message payload * @param payload pointer to network message payload * @param allow_truncate Set to > 0 to allow truncating of the message if it is too large. * @return Value from DltReturnValue enum */ DltReturnValue dlt_user_trace_network_truncated(DltContext *handle, DltNetworkTraceType nw_trace_type, uint16_t header_len, void *header, uint16_t payload_len, void *payload, int allow_truncate); /** * Trace network message in segmented asynchronous mode. * The sending of the data is done in a separate thread. * Please note that handle must exist for the lifetime of the application, because * data chunks are sent asynchronously in undetermined future time. * @param handle pointer to an object containing information about logging context * @param nw_trace_type type of network trace (DLT_NW_TRACE_IPC, DLT_NW_TRACE_CAN, DLT_NW_TRACE_FLEXRAY, or DLT_NW_TRACE_MOST) * @param header_len length of network message header * @param header pointer to network message header * @param payload_len length of network message payload * @param payload pointer to network message payload * @return Value from DltReturnValue enum */ DltReturnValue dlt_user_trace_network_segmented(DltContext *handle, DltNetworkTraceType nw_trace_type, uint16_t header_len, void *header, uint16_t payload_len, void *payload); /************************************************************************************************** * The following API functions define a high level function interface for DLT **************************************************************************************************/ /** * Initialize the user lib communication with daemon. * This function has to be called first, before using any DLT user lib functions. * @return Value from DltReturnValue enum */ DltReturnValue dlt_init(); /** * Initialize the user lib writing only to file. * This function has to be called first, before using any DLT user lib functions. * @param name name of an optional log file * @return Value from DltReturnValue enum */ DltReturnValue dlt_init_file(const char *name); /** * Terminate the user lib. * This function has to be called when finishing using the DLT user lib. * @return Value from DltReturnValue enum */ DltReturnValue dlt_free(); /** * Check the library version of DLT library. * @param user_major_version the major version to be compared * @param user_minor_version the minor version to be compared * @return Value from DltReturnValue enum, DLT_RETURN_ERROR if there is a mismatch */ DltReturnValue dlt_check_library_version(const char *user_major_version, const char *user_minor_version); /** * Register an application in the daemon. * @param apid four byte long character array with the application id * @param description long name of the application * @return Value from DltReturnValue enum */ DltReturnValue dlt_register_app(const char *apid, const char *description); /** * Unregister an application in the daemon. * This function has to be called when finishing using an application. * @return Value from DltReturnValue enum */ DltReturnValue dlt_unregister_app(void); /** * Unregister an application in the daemon and also flushes the buffered logs. * This function has to be called when finishing using an application. * @return Value from DltReturnValue enum */ DltReturnValue dlt_unregister_app_flush_buffered_logs(void); /** * Register a context in the daemon. * This function has to be called before first usage of the context. * @param handle pointer to an object containing information about one special logging context * @param contextid four byte long character array with the context id * @param description long name of the context * @return Value from DltReturnValue enum */ DltReturnValue dlt_register_context(DltContext *handle, const char *contextid, const char *description); /** * Register a context in the daemon with pre-defined log level and pre-defined trace status. * This function has to be called before first usage of the context. * @param handle pointer to an object containing information about one special logging context * @param contextid four byte long character array with the context id * @param description long name of the context * @param loglevel This is the log level to be pre-set for this context * (DLT_LOG_DEFAULT is not allowed here) * @param tracestatus This is the trace status to be pre-set for this context * (DLT_TRACE_STATUS_DEFAULT is not allowed here) * @return Value from DltReturnValue enum */ DltReturnValue dlt_register_context_ll_ts(DltContext *handle, const char *contextid, const char *description, int loglevel, int tracestatus); /** * Register a context in the daemon with log level changed callback fn. * This function is introduced to avoid missing of LL change callback during registration * @param handle pointer to an object containing information about one special logging context * @param contextid four byte long character array with the context id * @param description long name of the context * @param *dlt_log_level_changed_callback This is the fn which will be called when log level is changed * @return Value from DltReturnValue enum */ DltReturnValue dlt_register_context_llccb(DltContext *handle, const char *contextid, const char *description, void (*dlt_log_level_changed_callback)(char context_id[DLT_ID_SIZE], uint8_t log_level, uint8_t trace_status)); /** * Unregister a context in the DLT daemon. * This function has to be called when finishing using a context. * @param handle pointer to an object containing information about one special logging context * @return Value from DltReturnValue enum */ DltReturnValue dlt_unregister_context(DltContext *handle); /** * Set maximum timeout for re-sending at exit * @param timeout_in_milliseconds maximum time to wait until giving up re-sending, default 10000 (equals to 10 seconds) */ int dlt_set_resend_timeout_atexit(uint32_t timeout_in_milliseconds); /** * Set the logging mode used by the daemon. * The logging mode is stored persistantly by the daemon. * @see DltUserLogMode * @param mode the new logging mode used by the daemon: off, extern, internal, both. * @return Value from DltReturnValue enum */ DltReturnValue dlt_set_log_mode(DltUserLogMode mode); /** * Get the state of the connected client to the daemon. * The user application gets a message, when client is connected or disconnected. * This value contains the last state. * It needs some time until the application gets state from the daemon. * Until then the state is "unknown state". * @return -1 = unknown state, 0 = client not connected, 1 = client connected */ int dlt_get_log_state(); /** * Register callback function called when injection message was received * @param handle pointer to an object containing information about one special logging context * @param service_id the service id to be waited for * @param (*dlt_injection_callback) function pointer to callback function * @return Value from DltReturnValue enum */ DltReturnValue dlt_register_injection_callback(DltContext *handle, uint32_t service_id, int (*dlt_injection_callback)(uint32_t service_id, void *data, uint32_t length)); /** * Register callback function with private data called when injection message was received * @param handle pointer to an object containing information about one special logging context * @param service_id the service id to be waited for * @param (*dlt_injection_callback) function pointer to callback function * @param priv private data * @return Value from DltReturnValue enum */ DltReturnValue dlt_register_injection_callback_with_id(DltContext *handle, uint32_t service_id, int (*dlt_injection_callback)(uint32_t service_id, void *data, uint32_t length, void *priv_data), void *priv); /** * Register callback function called when log level of context was changed * @param handle pointer to an object containing information about one special logging context * @param (*dlt_log_level_changed_callback) function pointer to callback function * @return Value from DltReturnValue enum */ DltReturnValue dlt_register_log_level_changed_callback(DltContext *handle, void (*dlt_log_level_changed_callback)( char context_id[DLT_ID_SIZE], uint8_t log_level, uint8_t trace_status)); /** * Switch to verbose mode * @return Value from DltReturnValue enum */ DltReturnValue dlt_verbose_mode(void); /** * Check the version of dlt library with library version used of the application. * @param user_major_version version number of application - see dlt_version.h * @param user_minor_version version number of application - see dlt_version.h * @return Value from DltReturnValue enum, DLT_RETURN_ERROR if there is a mismatch */ DltReturnValue dlt_user_check_library_version(const char *user_major_version, const char *user_minor_version); /** * Switch to non-verbose mode * */ DltReturnValue dlt_nonverbose_mode(void); /** * Use extended header in non verbose mode. * Enabled by default. * @param use_extende_header_for_non_verbose Use extended header for non verbose mode if true * @return Value from DltReturnValue enum */ DltReturnValue dlt_use_extended_header_for_non_verbose(int8_t use_extende_header_for_non_verbose); /** * Send session id configuration. * Enabled by default. * @param with_session_id Send session id in each message if enabled * @return Value from DltReturnValue enum */ DltReturnValue dlt_with_session_id(int8_t with_session_id); /** * Send timestamp configuration. * Enabled by default. * @param with_timestamp Send timestamp id in each message if enabled * @return Value from DltReturnValue enum */ DltReturnValue dlt_with_timestamp(int8_t with_timestamp); /** * Send ecu id configuration. * Enabled by default. * @param with_ecu_id Send ecu id in each message if enabled * @return Value from DltReturnValue enum */ DltReturnValue dlt_with_ecu_id(int8_t with_ecu_id); /** * Set maximum logged log level and trace status of application * * @param loglevel This is the log level to be set for the whole application * @param tracestatus This is the trace status to be set for the whole application * @return Value from DltReturnValue enum */ DltReturnValue dlt_set_application_ll_ts_limit(DltLogLevelType loglevel, DltTraceStatusType tracestatus); /** * @brief adjust log-level based on values given through environment * * Iterate over the set of items, and find the best match. * For any item that matches, the one with the highest priority is selected and that * log-level is returned. * * Priorities are determined as follows: * - no apid, no ctid only ll given in item: use ll with prio 1 * - no apid, ctid matches: use ll with prio 2 * - no ctid, apid matches: use ll with prio 3 * - apid, ctid matches: use ll with prio 4 * * @param ll_set * @param apid * @param ctid * @param ll * If no item matches or in case of error, the original log-level (\param ll) is returned */ int dlt_env_adjust_ll_from_env(dlt_env_ll_set const *const ll_set, char const *const apid, char const *const ctid, int const ll); /** * @brief extract log-level settings from given string * * Scan \param env for setttings like apid:ctid:log-level and store them * in given \param ll_set * * @param env reference to a string to be parsed, after parsing env will point after the last parse character * @param ll_set set of log-level extracted from given string * * @return 0 on success * @return -1 on failure */ int dlt_env_extract_ll_set(char **const env, dlt_env_ll_set *const ll_set); void dlt_env_free_ll_set(dlt_env_ll_set *const ll_set); /** * Enable local printing of messages * @return Value from DltReturnValue enum */ DltReturnValue dlt_enable_local_print(void); /** * Disable local printing of messages * @return Value from DltReturnValue enum */ DltReturnValue dlt_disable_local_print(void); /** * Write a null terminated ASCII string into a DLT log message. * @param handle pointer to an object containing information about one special logging context * @param loglevel this is the current log level of the log message to be sent * @param text pointer to the ASCII string written into log message containing null termination. * @return Value from DltReturnValue enum */ DltReturnValue dlt_log_string(DltContext *handle, DltLogLevelType loglevel, const char *text); /** * Write a null terminated ASCII string and an integer value into a DLT log message. * @param handle pointer to an object containing information about one special logging context * @param loglevel this is the current log level of the log message to be sent * @param text pointer to the ASCII string written into log message containing null termination. * @param data integer value written into the log message * @return Value from DltReturnValue enum */ DltReturnValue dlt_log_string_int(DltContext *handle, DltLogLevelType loglevel, const char *text, int data); /** * Write a null terminated ASCII string and an unsigned integer value into a DLT log message. * @param handle pointer to an object containing information about one special logging context * @param loglevel this is the current log level of the log message to be sent * @param text pointer to the ASCII string written into log message containing null termination. * @param data unsigned integer value written into the log message * @return Value from DltReturnValue enum */ DltReturnValue dlt_log_string_uint(DltContext *handle, DltLogLevelType loglevel, const char *text, unsigned int data); /** * Write an integer value into a DLT log message. * @param handle pointer to an object containing information about one special logging context * @param loglevel this is the current log level of the log message to be sent * @param data integer value written into the log message * @return Value from DltReturnValue enum */ DltReturnValue dlt_log_int(DltContext *handle, DltLogLevelType loglevel, int data); /** * Write an unsigned integer value into a DLT log message. * @param handle pointer to an object containing information about one special logging context * @param loglevel this is the current log level of the log message to be sent * @param data unsigned integer value written into the log message * @return Value from DltReturnValue enum */ DltReturnValue dlt_log_uint(DltContext *handle, DltLogLevelType loglevel, unsigned int data); /** * Write an unsigned integer value into a DLT log message. * @param handle pointer to an object containing information about one special logging context * @param loglevel this is the current log level of the log message to be sent * @param data pointer to the parameter written into log message. * @param length length in bytes of the parameter written into log message. * @return Value from DltReturnValue enum */ DltReturnValue dlt_log_raw(DltContext *handle, DltLogLevelType loglevel, void *data, uint16_t length); /** * Write marker message to DLT. * @return Value from DltReturnValue enum */ DltReturnValue dlt_log_marker(); /** * Get the total size and available size of the shared memory buffer between daemon and applications. * This information is useful to control the flow control between applications and daemon. * For example only 50% of the buffer should be used for file transfer. * @param total_size total size of buffer in bytes * @param used_size used size of buffer in bytes * @return Value from DltReturnValue enum */ DltReturnValue dlt_user_check_buffer(int *total_size, int *used_size); /** * Try to resend log message in the user buffer. Stops if the dlt_uptime is bigger than * dlt_uptime() + DLT_USER_ATEXIT_RESEND_BUFFER_EXIT_TIMEOUT. A pause between the resending * attempts can be defined with DLT_USER_ATEXIT_RESEND_BUFFER_SLEEP * @return number of messages in the user buffer */ int dlt_user_atexit_blow_out_user_buffer(void); /** * Try to resend log message in the user buffer. * @return Value from DltReturnValue enum */ DltReturnValue dlt_user_log_resend_buffer(void); /** * Checks the log level passed by the log function if enabled for that context or not. * This function can be called by applications before generating their logs. * Also called before writing new log messages. * @param handle pointer to an object containing information about one special logging context * @param loglevel this is the current log level of the log message to be sent * @return Value from DltReturnValue enum, DLT_RETURN_TRUE if log level is enabled */ static inline DltReturnValue dlt_user_is_logLevel_enabled(DltContext *handle, DltLogLevelType loglevel) { if ((loglevel < DLT_LOG_DEFAULT) || (loglevel >= DLT_LOG_MAX)) return DLT_RETURN_WRONG_PARAMETER; if ((handle == NULL) || (handle->log_level_ptr == NULL)) return DLT_RETURN_WRONG_PARAMETER; if ((loglevel <= (DltLogLevelType)(*(handle->log_level_ptr))) && (loglevel != DLT_LOG_OFF)) return DLT_RETURN_TRUE; return DLT_RETURN_LOGGING_DISABLED; } # ifdef DLT_TEST_ENABLE void dlt_user_test_corrupt_user_header(int enable); void dlt_user_test_corrupt_message_size(int enable, int16_t size); # endif /* DLT_TEST_ENABLE */ # ifdef __cplusplus } # endif /** \} */ #endif /* DLT_USER_H */ dlt-daemon-2.18.4/include/dlt/dlt_user_macros.h000066400000000000000000000505421353342203500214040ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2011-2015, BMW AG * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author Alexander Wenzel * * \copyright Copyright © 2011-2015 BMW AG. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file dlt_user_macros.h */ /******************************************************************************* ** ** ** SRC-MODULE: dlt_user_macros.h ** ** ** ** TARGET : linux ** ** ** ** PROJECT : DLT ** ** ** ** AUTHOR : Alexander Wenzel Alexander.AW.Wenzel@bmw.de ** ** Markus Klein ** ** ** ** PURPOSE : ** ** ** ** REMARKS : ** ** ** ** PLATFORM DEPENDANT [yes/no]: yes ** ** ** ** TO BE CHANGED BY USER [yes/no]: no ** ** ** *******************************************************************************/ /******************************************************************************* ** Author Identity ** ******************************************************************************** ** ** ** Initials Name Company ** ** -------- ------------------------- ---------------------------------- ** ** aw Alexander Wenzel BMW ** ** mk Markus Klein Fraunhofer ESK ** *******************************************************************************/ /******************************************************************************* ** Revision Control History ** *******************************************************************************/ /* * $LastChangedRevision: 1515 $ * $LastChangedDate: 2010-12-13 09:18:54 +0100 (Mon, 13 Dec 2010) $ * $LastChangedBy$ * Initials Date Comment * aw 13.01.2010 initial */ #ifndef DLT_USER_MACROS_H #define DLT_USER_MACROS_H #include "dlt_version.h" /** * \defgroup userapi DLT User API * \addtogroup userapi \{ */ /************************************************************************************************** * The folowing macros define a macro interface for DLT **************************************************************************************************/ /** * Create an object for a new context. * This macro has to be called first for every. * @param CONTEXT object containing information about one special logging context * @note To avoid the MISRA warning "Null statement is located close to other code or comments" * remove the semicolon when using the macro. * Example: DLT_DECLARE_CONTEXT(hContext) */ #define DLT_DECLARE_CONTEXT(CONTEXT) \ DltContext CONTEXT; /** * Use an object of a new context created in another module. * This macro has to be called first for every. * @param CONTEXT object containing information about one special logging context * @note To avoid the MISRA warning "Null statement is located close to other code or comments" * remove the semicolon when using the macro. * Example: DLT_IMPORT_CONTEXT(hContext) */ #define DLT_IMPORT_CONTEXT(CONTEXT) \ extern DltContext CONTEXT; /** * Register application. * @param APPID application id with maximal four characters * @param DESCRIPTION ASCII string containing description */ #define DLT_REGISTER_APP(APPID, DESCRIPTION) do { \ (void)dlt_check_library_version(_DLT_PACKAGE_MAJOR_VERSION, _DLT_PACKAGE_MINOR_VERSION); \ (void)dlt_register_app(APPID, DESCRIPTION); } while (0) /** * Unregister application. */ #define DLT_UNREGISTER_APP() do { \ (void)dlt_unregister_app(); } while (0) /** * Unregister application and flush the logs buffered in startup buffer if any. */ #define DLT_UNREGISTER_APP_FLUSH_BUFFERED_LOGS() do { \ (void)dlt_unregister_app_flush_buffered_logs(); } while (0) /** * Register context (with default log level and default trace status) * @param CONTEXT object containing information about one special logging context * @param CONTEXTID context id with maximal four characters * @param DESCRIPTION ASCII string containing description */ #define DLT_REGISTER_CONTEXT(CONTEXT, CONTEXTID, DESCRIPTION) do { \ (void)dlt_register_context(&(CONTEXT), CONTEXTID, DESCRIPTION); } while (0) /** * Register context with pre-defined log level and pre-defined trace status. * @param CONTEXT object containing information about one special logging context * @param CONTEXTID context id with maximal four characters * @param DESCRIPTION ASCII string containing description * @param LOGLEVEL log level to be pre-set for this context * (DLT_LOG_DEFAULT is not allowed here) * @param TRACESTATUS trace status to be pre-set for this context * (DLT_TRACE_STATUS_DEFAULT is not allowed here) */ #define DLT_REGISTER_CONTEXT_LL_TS(CONTEXT, CONTEXTID, DESCRIPTION, LOGLEVEL, TRACESTATUS) do { \ (void)dlt_register_context_ll_ts(&(CONTEXT), CONTEXTID, DESCRIPTION, LOGLEVEL, TRACESTATUS); } while (0) /** * Register context (with default log level and default trace status and log level change callback) * @param CONTEXT object containing information about one special logging context * @param CONTEXTID context id with maximal four characters * @param DESCRIPTION ASCII string containing description * @param CBK log level change callback to be registered */ #define DLT_REGISTER_CONTEXT_LLCCB(CONTEXT, CONTEXTID, DESCRIPTION, CBK) do { \ (void)dlt_register_context_llccb(&(CONTEXT), CONTEXTID, DESCRIPTION, CBK); } while (0) /** * Unregister context. * @param CONTEXT object containing information about one special logging context */ #define DLT_UNREGISTER_CONTEXT(CONTEXT) do { \ (void)dlt_unregister_context(&(CONTEXT)); } while (0) /** * Register callback function called when injection message was received * @param CONTEXT object containing information about one special logging context * @param SERVICEID service id of the injection message * @param CALLBACK function pointer to callback function */ #define DLT_REGISTER_INJECTION_CALLBACK(CONTEXT, SERVICEID, CALLBACK) do { \ (void)dlt_register_injection_callback(&(CONTEXT), SERVICEID, CALLBACK); } while (0) /** * Register callback function called when injection message was received * @param CONTEXT object containing information about one special logging context * @param SERVICEID service id of the injection message * @param CALLBACK function pointer to callback function * @param PRIV_DATA data specific to context */ #define DLT_REGISTER_INJECTION_CALLBACK_WITH_ID(CONTEXT, SERVICEID, CALLBACK, PRIV_DATA) do { \ (void)dlt_register_injection_callback_with_id(&(CONTEXT), SERVICEID, CALLBACK, PRIV_DATA); } while (0) /** * Register callback function called when log level of context was changed * @param CONTEXT object containing information about one special logging context * @param CALLBACK function pointer to callback function */ #define DLT_REGISTER_LOG_LEVEL_CHANGED_CALLBACK(CONTEXT, CALLBACK) do { \ (void)dlt_register_log_level_changed_callback(&(CONTEXT), CALLBACK); } while (0) /** * Send log message with variable list of messages (intended for verbose mode) * @param CONTEXT object containing information about one special logging context * @param LOGLEVEL the log level of the log message * @param ARGS variable list of arguments * @note To avoid the MISRA warning "The comma operator has been used outside a for statement" * use a semicolon instead of a comma to separate the ARGS. * Example: DLT_LOG(hContext, DLT_LOG_INFO, DLT_STRING("Hello world"); DLT_INT(123)); */ #ifdef _MSC_VER /* DLT_LOG is not supported by MS Visual C++ */ /* use function interface instead */ #else # define DLT_LOG(CONTEXT, LOGLEVEL, ARGS ...) \ do { \ DltContextData log_local; \ int dlt_local; \ dlt_local = dlt_user_log_write_start(&CONTEXT, &log_local, LOGLEVEL); \ if (dlt_local == DLT_RETURN_TRUE) \ { \ ARGS; \ (void)dlt_user_log_write_finish(&log_local); \ } \ } while (0) #endif /** * Send log message with variable list of messages (intended for non-verbose mode) * @param CONTEXT object containing information about one special logging context * @param LOGLEVEL the log level of the log message * @param MSGID the message id of log message * @param ARGS variable list of arguments: * calls to DLT_STRING(), DLT_BOOL(), DLT_FLOAT32(), DLT_FLOAT64(), * DLT_INT(), DLT_UINT(), DLT_RAW() * @note To avoid the MISRA warning "The comma operator has been used outside a for statement" * use a semicolon instead of a comma to separate the ARGS. * Example: DLT_LOG_ID(hContext, DLT_LOG_INFO, 0x1234, DLT_STRING("Hello world"); DLT_INT(123)); */ #ifdef _MSC_VER /* DLT_LOG_ID is not supported by MS Visual C++ */ /* use function interface instead */ #else # define DLT_LOG_ID(CONTEXT, LOGLEVEL, MSGID, ARGS ...) \ do { \ DltContextData log_local; \ int dlt_local; \ dlt_local = dlt_user_log_write_start_id(&CONTEXT, &log_local, LOGLEVEL, MSGID); \ if (dlt_local == DLT_RETURN_TRUE) \ { \ ARGS; \ (void)dlt_user_log_write_finish(&log_local); \ } \ } while (0) #endif /** * Add string parameter to the log messsage. * @param TEXT ASCII string */ #define DLT_STRING(TEXT) \ (void)dlt_user_log_write_string(&log_local, TEXT) /** * Add constant string parameter to the log messsage. * @param TEXT Constant ASCII string */ #define DLT_CSTRING(TEXT) \ (void)dlt_user_log_write_constant_string(&log_local, TEXT) /** * Add utf8-encoded string parameter to the log messsage. * @param TEXT UTF8-encoded string */ #define DLT_UTF8(TEXT) \ (void)dlt_user_log_write_utf8_string(&log_local, TEXT) /** * Add boolean parameter to the log messsage. * @param BOOL_VAR Boolean value (mapped to uint8) */ #define DLT_BOOL(BOOL_VAR) \ (void)dlt_user_log_write_bool(&log_local, BOOL_VAR) /** * Add float32 parameter to the log messsage. * @param FLOAT32_VAR Float32 value (mapped to float) */ #define DLT_FLOAT32(FLOAT32_VAR) \ (void)dlt_user_log_write_float32(&log_local, FLOAT32_VAR) /** * Add float64 parameter to the log messsage. * @param FLOAT64_VAR Float64 value (mapped to double) */ #define DLT_FLOAT64(FLOAT64_VAR) \ (void)dlt_user_log_write_float64(&log_local, FLOAT64_VAR) /** * Add integer parameter to the log messsage. * @param INT_VAR integer value */ #define DLT_INT(INT_VAR) \ (void)dlt_user_log_write_int(&log_local, INT_VAR) #define DLT_INT8(INT_VAR) \ (void)dlt_user_log_write_int8(&log_local, INT_VAR) #define DLT_INT16(INT_VAR) \ (void)dlt_user_log_write_int16(&log_local, INT_VAR) #define DLT_INT32(INT_VAR) \ (void)dlt_user_log_write_int32(&log_local, INT_VAR) #define DLT_INT64(INT_VAR) \ (void)dlt_user_log_write_int64(&log_local, INT_VAR) /** * Add unsigned integer parameter to the log messsage. * @param UINT_VAR unsigned integer value */ #define DLT_UINT(UINT_VAR) \ (void)dlt_user_log_write_uint(&log_local, UINT_VAR) #define DLT_UINT8(UINT_VAR) \ (void)dlt_user_log_write_uint8(&log_local, UINT_VAR) #define DLT_UINT16(UINT_VAR) \ (void)dlt_user_log_write_uint16(&log_local, UINT_VAR) #define DLT_UINT32(UINT_VAR) \ (void)dlt_user_log_write_uint32(&log_local, UINT_VAR) #define DLT_UINT64(UINT_VAR) \ (void)dlt_user_log_write_uint64(&log_local, UINT_VAR) /** * Add binary memory block to the log messages. * @param BUF pointer to memory block * @param LEN length of memory block */ #define DLT_RAW(BUF, LEN) \ (void)dlt_user_log_write_raw(&log_local, BUF, LEN) #define DLT_HEX8(UINT_VAR) \ (void)dlt_user_log_write_uint8_formatted(&log_local, UINT_VAR, DLT_FORMAT_HEX8) #define DLT_HEX16(UINT_VAR) \ (void)dlt_user_log_write_uint16_formatted(&log_local, UINT_VAR, DLT_FORMAT_HEX16) #define DLT_HEX32(UINT_VAR) \ (void)dlt_user_log_write_uint32_formatted(&log_local, UINT_VAR, DLT_FORMAT_HEX32) #define DLT_HEX64(UINT_VAR) \ (void)dlt_user_log_write_uint64_formatted(&log_local, UINT_VAR, DLT_FORMAT_HEX64) #define DLT_BIN8(UINT_VAR) \ (void)dlt_user_log_write_uint8_formatted(&log_local, UINT_VAR, DLT_FORMAT_BIN8) #define DLT_BIN16(UINT_VAR) \ (void)dlt_user_log_write_uint16_formatted(&log_local, UINT_VAR, DLT_FORMAT_BIN16) /** * Architecture independent macro to print pointers */ #define DLT_PTR(PTR_VAR) \ (void)dlt_user_log_write_ptr(&log_local, PTR_VAR) /** * Trace network message * @param CONTEXT object containing information about one special logging context * @param TYPE type of network trace message * @param HEADERLEN length of network message header * @param HEADER pointer to network message header * @param PAYLOADLEN length of network message payload * @param PAYLOAD pointer to network message payload */ #define DLT_TRACE_NETWORK(CONTEXT, TYPE, HEADERLEN, HEADER, PAYLOADLEN, PAYLOAD) \ do { \ if ((CONTEXT).trace_status_ptr && *((CONTEXT).trace_status_ptr) == DLT_TRACE_STATUS_ON) \ { \ (void)dlt_user_trace_network(&(CONTEXT), TYPE, HEADERLEN, HEADER, PAYLOADLEN, PAYLOAD); \ } \ } while (0) /** * Trace network message, allow truncation * @param CONTEXT object containing information about one special logging context * @param TYPE type of network trace message * @param HEADERLEN length of network message header * @param HEADER pointer to network message header * @param PAYLOADLEN length of network message payload * @param PAYLOAD pointer to network message payload */ #define DLT_TRACE_NETWORK_TRUNCATED(CONTEXT, TYPE, HEADERLEN, HEADER, PAYLOADLEN, PAYLOAD) \ do { \ if ((CONTEXT).trace_status_ptr && *((CONTEXT).trace_status_ptr) == DLT_TRACE_STATUS_ON) \ { \ (void)dlt_user_trace_network_truncated(&(CONTEXT), TYPE, HEADERLEN, HEADER, PAYLOADLEN, PAYLOAD, 1); \ } \ } while (0) /** * Trace network message, segment large messages * @param CONTEXT object containing information about one special logging context * @param TYPE type of network trace message * @param HEADERLEN length of network message header * @param HEADER pointer to network message header * @param PAYLOADLEN length of network message payload * @param PAYLOAD pointer to network message payload */ #define DLT_TRACE_NETWORK_SEGMENTED(CONTEXT, TYPE, HEADERLEN, HEADER, PAYLOADLEN, PAYLOAD) \ do { \ if ((CONTEXT).trace_status_ptr && *((CONTEXT).trace_status_ptr) == DLT_TRACE_STATUS_ON) \ { \ (void)dlt_user_trace_network_segmented(&(CONTEXT), TYPE, HEADERLEN, HEADER, PAYLOADLEN, PAYLOAD); \ } \ } while (0) /** * Send log message with string parameter. * @param CONTEXT object containing information about one special logging context * @param LOGLEVEL the log level of the log message * @param TEXT ASCII string */ #define DLT_LOG_STRING(CONTEXT, LOGLEVEL, TEXT) \ do { \ if (dlt_user_is_logLevel_enabled(&CONTEXT, LOGLEVEL) == DLT_RETURN_TRUE) \ { \ (void)dlt_log_string(&(CONTEXT), LOGLEVEL, TEXT); \ } \ } while (0) /** * Send log message with string parameter and integer parameter. * @param CONTEXT object containing information about one special logging context * @param LOGLEVEL the log level of the log messages * @param TEXT ASCII string * @param INT_VAR integer value */ #define DLT_LOG_STRING_INT(CONTEXT, LOGLEVEL, TEXT, INT_VAR) \ do { \ if (dlt_user_is_logLevel_enabled(&CONTEXT, LOGLEVEL) == DLT_RETURN_TRUE) \ { \ (void)dlt_log_string_int(&(CONTEXT), LOGLEVEL, TEXT, INT_VAR); \ } \ } while (0) /** * Send log message with string parameter and unsigned integer parameter. * @param CONTEXT object containing information about one special logging context * @param LOGLEVEL the log level of the log message * @param TEXT ASCII string * @param UINT_VAR unsigned integer value */ #define DLT_LOG_STRING_UINT(CONTEXT, LOGLEVEL, TEXT, UINT_VAR) \ do { \ if (dlt_user_is_logLevel_enabled(&CONTEXT, LOGLEVEL) == DLT_RETURN_TRUE) \ { \ (void)dlt_log_string_uint(&(CONTEXT), LOGLEVEL, TEXT, UINT_VAR); \ } \ } while (0) /** * Send log message with unsigned integer parameter. * @param CONTEXT object containing information about one special logging context * @param LOGLEVEL the log level of the log message * @param UINT_VAR unsigned integer value */ #define DLT_LOG_UINT(CONTEXT, LOGLEVEL, UINT_VAR) \ do { \ if (dlt_user_is_logLevel_enabled(&CONTEXT, LOGLEVEL) == DLT_RETURN_TRUE) \ { \ (void)dlt_log_uint(&(CONTEXT), LOGLEVEL, UINT_VAR); \ } \ } while (0) /** * Send log message with integer parameter. * @param CONTEXT object containing information about one special logging context * @param LOGLEVEL the log level of the log message * @param INT_VAR integer value */ #define DLT_LOG_INT(CONTEXT, LOGLEVEL, INT_VAR) \ do { \ if (dlt_user_is_logLevel_enabled(&CONTEXT, LOGLEVEL) == DLT_RETURN_TRUE) \ { \ (void)dlt_log_int(&(CONTEXT), LOGLEVEL, INT_VAR); \ } \ } while (0) /** * Send log message with binary memory block. * @param CONTEXT object containing information about one special logging context * @param LOGLEVEL the log level of the log message * @param BUF pointer to memory block * @param LEN length of memory block */ #define DLT_LOG_RAW(CONTEXT, LOGLEVEL, BUF, LEN) \ do { \ if (dlt_user_is_logLevel_enabled(&CONTEXT, LOGLEVEL) == DLT_RETURN_TRUE) \ { \ (void)dlt_log_raw(&(CONTEXT), LOGLEVEL, BUF, LEN); \ } \ } while (0) /** * Send log message with marker. */ #define DLT_LOG_MARKER() \ do { \ (void)dlt_log_marker(); \ } while (0) /** * Switch to verbose mode * */ #define DLT_VERBOSE_MODE() do { \ (void)dlt_verbose_mode(); } while (0) /** * Switch to non-verbose mode * */ #define DLT_NONVERBOSE_MODE() do { \ (void)dlt_nonverbose_mode(); } while (0) /** * Set maximum logged log level and trace status of application * * @param LOGLEVEL This is the log level to be set for the whole application * @param TRACESTATUS This is the trace status to be set for the whole application */ #define DLT_SET_APPLICATION_LL_TS_LIMIT(LOGLEVEL, TRACESTATUS) do { \ (void)dlt_set_application_ll_ts_limit(LOGLEVEL, TRACESTATUS); } while (0) /** * Enable local printing of messages * */ #define DLT_ENABLE_LOCAL_PRINT() do { \ (void)dlt_enable_local_print(); } while (0) /** * Disable local printing of messages * */ #define DLT_DISABLE_LOCAL_PRINT() do { \ (void)dlt_disable_local_print(); } while (0) /** * Check if log level is enabled * * @param CONTEXT object containing information about one special logging context * @param LOGLEVEL the log level of the log message */ #define DLT_IS_LOG_LEVEL_ENABLED(CONTEXT, LOGLEVEL) \ (dlt_user_is_logLevel_enabled(&CONTEXT, LOGLEVEL) == DLT_RETURN_TRUE) /** \} */ #endif /* DLT_USER_MACROS_H */ dlt-daemon-2.18.4/src/000077500000000000000000000000001353342203500144215ustar00rootroot00000000000000dlt-daemon-2.18.4/src/CMakeLists.txt000066400000000000000000000022071353342203500171620ustar00rootroot00000000000000####### # SPDX license identifier: MPL-2.0 # # Copyright (C) 2011-2015, BMW AG # # This file is part of GENIVI Project DLT - Diagnostic Log and Trace. # # This Source Code Form is subject to the terms of the # Mozilla Public License (MPL), v. 2.0. # If a copy of the MPL was not distributed with this file, # You can obtain one at http://mozilla.org/MPL/2.0/. # # For further information see http://www.genivi.org/. ####### add_subdirectory( lib ) add_subdirectory( daemon ) add_subdirectory( gateway ) if( WITH_DLT_CONSOLE ) add_subdirectory( console ) endif( WITH_DLT_CONSOLE ) if( WITH_DLT_EXAMPLES ) add_subdirectory( examples ) endif( WITH_DLT_EXAMPLES ) if( WITH_DLT_ADAPTOR ) add_subdirectory( adaptor ) endif( WITH_DLT_ADAPTOR ) if( WITH_DLT_TESTS ) add_subdirectory( tests ) endif( WITH_DLT_TESTS ) if( WITH_DLT_SYSTEM ) add_subdirectory( system ) endif( WITH_DLT_SYSTEM ) if( WITH_DLT_DBUS ) add_subdirectory( dbus ) endif( WITH_DLT_DBUS ) if( WITH_DLT_COREDUMPHANDLER ) add_subdirectory( core_dump_handler ) endif( WITH_DLT_COREDUMPHANDLER ) if( WITH_DLT_KPI ) add_subdirectory( kpi ) endif( WITH_DLT_KPI ) dlt-daemon-2.18.4/src/adaptor/000077500000000000000000000000001353342203500160535ustar00rootroot00000000000000dlt-daemon-2.18.4/src/adaptor/CMakeLists.txt000066400000000000000000000016731353342203500206220ustar00rootroot00000000000000####### # SPDX license identifier: MPL-2.0 # # Copyright (C) 2011-2015, BMW AG # # This file is part of GENIVI Project DLT - Diagnostic Log and Trace. # # This Source Code Form is subject to the terms of the # Mozilla Public License (MPL), v. 2.0. # If a copy of the MPL was not distributed with this file, # You can obtain one at http://mozilla.org/MPL/2.0/. # # For further information see http://www.genivi.org/. ####### set(dlt_adaptor_stdin_SRCS dlt-adaptor-stdin.c) add_executable(dlt-adaptor-stdin ${dlt_adaptor_stdin_SRCS}) target_link_libraries(dlt-adaptor-stdin dlt) set_target_properties(dlt-adaptor-stdin PROPERTIES LINKER_LANGUAGE C) set(dlt_adaptor_udp_SRCS dlt-adaptor-udp.c) add_executable(dlt-adaptor-udp ${dlt_adaptor_udp_SRCS}) target_link_libraries(dlt-adaptor-udp dlt) set_target_properties(dlt-adaptor-udp PROPERTIES LINKER_LANGUAGE C) install(TARGETS dlt-adaptor-stdin dlt-adaptor-udp RUNTIME DESTINATION bin COMPONENT base) dlt-daemon-2.18.4/src/adaptor/dlt-adaptor-stdin.c000066400000000000000000000157221353342203500215600ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2011-2015, BMW AG * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author Alexander Wenzel * * \copyright Copyright © 2011-2015 BMW AG. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file dlt-adaptor-stdin.c */ /******************************************************************************* ** ** ** SRC-MODULE: dlt-adaptor-stdin.c ** ** ** ** TARGET : linux ** ** ** ** PROJECT : DLT ** ** ** ** AUTHOR : Alexander Wenzel Alexander.AW.Wenzel@bmw.de ** ** Markus Klein ** ** ** ** PURPOSE : ** ** ** ** REMARKS : ** ** ** ** PLATFORM DEPENDANT [yes/no]: yes ** ** ** ** TO BE CHANGED BY USER [yes/no]: no ** ** ** *******************************************************************************/ /******************************************************************************* ** Author Identity ** ******************************************************************************** ** ** ** Initials Name Company ** ** -------- ------------------------- ---------------------------------- ** ** aw Alexander Wenzel BMW ** ** mk Markus Klein Fraunhofer ESK ** *******************************************************************************/ /******************************************************************************* ** Revision Control History ** *******************************************************************************/ /* * $LastChangedRevision: 1670 $ * $LastChangedDate: 2011-04-08 15:12:06 +0200 (Fr, 08. Apr 2011) $ * $LastChangedBy$ */ #include #include #include #include "dlt_common.h" #include "dlt_user.h" #define MAXSTRLEN 1024 #define PS_DLT_APP_DESC "stdin adaptor application" #define PS_DLT_CONTEXT_DESC "stdin adaptor context" #define PS_DLT_APP "SINA" #define PS_DLT_CONTEXT "SINC" DLT_DECLARE_CONTEXT(mycontext) int main(int argc, char *argv[]) { char str[MAXSTRLEN]; int opt; char apid[DLT_ID_SIZE]; char ctid[DLT_ID_SIZE]; char version[255]; int timeout = -1; int verbosity = DLT_LOG_INFO; int bflag = 0; dlt_set_id(apid, PS_DLT_APP); dlt_set_id(ctid, PS_DLT_CONTEXT); while ((opt = getopt(argc, argv, "a:c:bht:v:")) != -1) switch (opt) { case 'a': { dlt_set_id(apid, optarg); break; } case 'c': { dlt_set_id(ctid, optarg); break; } case 'b': { bflag = 1; break; } case 't': { timeout = atoi(optarg); break; } case 'h': { dlt_get_version(version, 255); printf("Usage: dlt-adaptor-stdin [options]\n"); printf("Adaptor for forwarding input from stdin to DLT daemon.\n"); printf("%s \n", version); printf("Options:\n"); printf(" -a apid - Set application id to apid (default: SINA)\n"); printf(" -c ctid - Set context id to ctid (default: SINC)\n"); printf(" -b - Flush buffered logs before unregistering app\n"); printf(" -t timeout - Set timeout when sending messages at exit, in ms (Default: 10000 = 10sec)\n"); printf( " -v verbosity level - Set verbosity level (Default: INFO, values: FATAL ERROR WARN INFO DEBUG VERBOSE)\n"); printf(" -h - This help\n"); return 0; break; } case 'v': { if (!strcmp(optarg, "FATAL")) { verbosity = DLT_LOG_FATAL; break; } else if (!strcmp(optarg, "ERROR")) { verbosity = DLT_LOG_ERROR; break; } else if (!strcmp(optarg, "WARN")) { verbosity = DLT_LOG_WARN; break; } else if (!strcmp(optarg, "INFO")) { verbosity = DLT_LOG_INFO; break; } else if (!strcmp(optarg, "DEBUG")) { verbosity = DLT_LOG_DEBUG; break; } else if (!strcmp(optarg, "VERBOSE")) { verbosity = DLT_LOG_VERBOSE; break; } else { printf( "Wrong verbosity level, setting to INFO. Accepted values are: FATAL ERROR WARN INFO DEBUG VERBOSE\n"); verbosity = DLT_LOG_INFO; break; } break; } default: /* '?' */ { fprintf(stderr, "Unknown option '%c'\n", optopt); return -1; } } DLT_REGISTER_APP(apid, PS_DLT_APP_DESC); DLT_REGISTER_CONTEXT(mycontext, ctid, PS_DLT_CONTEXT_DESC); if (timeout > -1) dlt_set_resend_timeout_atexit(timeout); while (fgets(str, MAXSTRLEN, stdin)) if (strcmp(str, "") != 0) DLT_LOG(mycontext, verbosity, DLT_STRING(str)); DLT_UNREGISTER_CONTEXT(mycontext); if (bflag == 1) DLT_UNREGISTER_APP_FLUSH_BUFFERED_LOGS(); else DLT_UNREGISTER_APP(); return 0; } dlt-daemon-2.18.4/src/adaptor/dlt-adaptor-udp.c000066400000000000000000000200461353342203500212220ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2011-2015, BMW AG * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author Alexander Wenzel * * \copyright Copyright © 2011-2015 BMW AG. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file dlt-adaptor-udp.c */ /******************************************************************************* ** ** ** SRC-MODULE: dlt-adaptor-udp.c ** ** ** ** TARGET : linux ** ** ** ** PROJECT : DLT ** ** ** ** AUTHOR : Alexander Wenzel Alexander.AW.Wenzel@bmw.de ** ** Markus Klein ** ** ** ** PURPOSE : ** ** ** ** REMARKS : ** ** ** ** PLATFORM DEPENDANT [yes/no]: yes ** ** ** ** TO BE CHANGED BY USER [yes/no]: no ** ** ** *******************************************************************************/ /******************************************************************************* ** Author Identity ** ******************************************************************************** ** ** ** Initials Name Company ** ** -------- ------------------------- ---------------------------------- ** ** aw Alexander Wenzel BMW ** ** mk Markus Klein Fraunhofer ESK ** *******************************************************************************/ /******************************************************************************* ** Revision Control History ** *******************************************************************************/ /* * $LastChangedRevision: 1670 $ * $LastChangedDate: 2011-04-08 15:12:06 +0200 (Fr, 08. Apr 2011) $ * $LastChangedBy$ */ #include #include #include #include #include #include #include #include #include #include "dlt_common.h" #include "dlt_user.h" /* Port number, to which the syslogd-ng sends its log messages */ #define RCVPORT 47111 #define MAXSTRLEN 1024 #define PU_DLT_APP_DESC "udp adaptor application" #define PU_DLT_CONTEXT_DESC "udp adaptor context" #define PU_DLT_APP "UDPA" #define PU_DLT_CONTEXT "UDPC" DLT_DECLARE_CONTEXT(mycontext) int main(int argc, char *argv[]) { int sock; int bytes_read; socklen_t addr_len; int opt, port; char recv_data[MAXSTRLEN]; struct sockaddr_in client_addr, server_addr; char apid[DLT_ID_SIZE]; char ctid[DLT_ID_SIZE]; char version[255]; int verbosity = DLT_LOG_INFO; dlt_set_id(apid, PU_DLT_APP); dlt_set_id(ctid, PU_DLT_CONTEXT); port = RCVPORT; while ((opt = getopt(argc, argv, "a:c:hp:v:")) != -1) switch (opt) { case 'a': { dlt_set_id(apid, optarg); break; } case 'c': { dlt_set_id(ctid, optarg); break; } case 'h': { dlt_get_version(version, 255); printf("Usage: dlt-adaptor-udp [options]\n"); printf("Adaptor for forwarding received UDP messages to DLT daemon.\n"); printf("%s \n", version); printf("Options:\n"); printf("-a apid - Set application id to apid (default: UDPA)\n"); printf("-c ctid - Set context id to ctid (default: UDPC)\n"); printf("-p - Set receive port number for UDP messages (default: %d) \n", port); printf( "-v verbosity level - Set verbosity level (Default: INFO, values: FATAL ERROR WARN INFO DEBUG VERBOSE)\n"); printf("-h - This help\n"); return 0; break; } case 'p': { port = atoi(optarg); break; } case 'v': { if (!strcmp(optarg, "FATAL")) { verbosity = DLT_LOG_FATAL; break; } else if (!strcmp(optarg, "ERROR")) { verbosity = DLT_LOG_ERROR; break; } else if (!strcmp(optarg, "WARN")) { verbosity = DLT_LOG_WARN; break; } else if (!strcmp(optarg, "INFO")) { verbosity = DLT_LOG_INFO; break; } else if (!strcmp(optarg, "DEBUG")) { verbosity = DLT_LOG_DEBUG; break; } else if (!strcmp(optarg, "VERBOSE")) { verbosity = DLT_LOG_VERBOSE; break; } else { printf( "Wrong verbosity level, setting to INFO. Accepted values are: FATAL ERROR WARN INFO DEBUG VERBOSE\n"); verbosity = DLT_LOG_INFO; break; } break; } default: /* '?' */ { fprintf(stderr, "Unknown option '%c'\n", optopt); exit(3); return 3;/*for parasoft */ } } #ifdef DLT_USE_IPv6 if ((sock = socket(AF_INET6, SOCK_DGRAM, 0)) == -1) #else if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) == -1) #endif { perror("Socket"); exit(1); } #ifdef DLT_USE_IPv6 server_addr.sin_family = AF_INET6; #else server_addr.sin_family = AF_INET; #endif server_addr.sin_port = htons(port); server_addr.sin_addr.s_addr = INADDR_ANY; memset(&(server_addr.sin_zero), 0, 8); if (bind(sock, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) == -1) { perror("Bind"); return -1; } addr_len = sizeof(struct sockaddr); DLT_REGISTER_APP(apid, PU_DLT_APP_DESC); DLT_REGISTER_CONTEXT(mycontext, ctid, PU_DLT_CONTEXT_DESC); while (1) { bytes_read = 0; bytes_read = recvfrom(sock, recv_data, MAXSTRLEN, 0, (struct sockaddr *)&client_addr, &addr_len); if (bytes_read == -1) { if (errno == EINTR) { continue; } else { DLT_UNREGISTER_CONTEXT(mycontext); DLT_UNREGISTER_APP(); exit(1); } } recv_data[bytes_read] = '\0'; if (bytes_read != 0) DLT_LOG(mycontext, verbosity, DLT_STRING(recv_data)); } DLT_UNREGISTER_CONTEXT(mycontext); DLT_UNREGISTER_APP(); return 0; } dlt-daemon-2.18.4/src/console/000077500000000000000000000000001353342203500160635ustar00rootroot00000000000000dlt-daemon-2.18.4/src/console/CMakeLists.txt000066400000000000000000000022721353342203500206260ustar00rootroot00000000000000####### # SPDX license identifier: MPL-2.0 # # Copyright (C) 2011-2015, BMW AG # # This file is part of GENIVI Project DLT - Diagnostic Log and Trace. # # This Source Code Form is subject to the terms of the # Mozilla Public License (MPL), v. 2.0. # If a copy of the MPL was not distributed with this file, # You can obtain one at http://mozilla.org/MPL/2.0/. # # For further information see http://www.genivi.org/. ####### set(dlt_control_common_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/dlt-control-common.c) add_subdirectory(logstorage) set(dlt-sortbytimestamp_SRCS dlt-sortbytimestamp.c) set(dlt-convert_SRCS dlt-convert.c) set(dlt-receive_SRCS dlt-receive.c) set(dlt-control_SRCS dlt-control.c ${dlt_control_common_SRCS}) set(dlt-passive-node-ctrl_SRCS dlt-passive-node-ctrl.c ${dlt_control_common_SRCS}) foreach(target dlt-sortbytimestamp dlt-convert dlt-receive dlt-control dlt-passive-node-ctrl ) add_executable(${target} ${${target}_SRCS}) target_link_libraries(${target} dlt) set_target_properties(${target} PROPERTIES LINKER_LANGUAGE C) install(TARGETS ${target} RUNTIME DESTINATION bin COMPONENT base) endforeach() dlt-daemon-2.18.4/src/console/dlt-control-common.c000066400000000000000000000465701353342203500217720ustar00rootroot00000000000000/** * Copyright (C) 2015 Advanced Driver Information Technology. * This code is developed by Advanced Driver Information Technology. * Copyright of Advanced Driver Information Technology, Bosch and DENSO. * * This file is part of GENIVI Project Dlt - Diagnostic Log and Trace console apps. * * * \copyright * This Source Code Form is subject to the terms of the * Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with * this file, You can obtain one at http://mozilla.org/MPL/2.0/. * * * \author Christoph Lipka ADIT 2015 * \author Frederic Berat ADIT 2015 * * \file dlt-control-common.c * For further information see http://www.genivi.org/. */ /******************************************************************************* ** ** ** SRC-MODULE: dlt-control-common.c ** ** ** ** TARGET : linux ** ** ** ** PROJECT : DLT ** ** ** ** AUTHOR : Christoph Lipka clipka@jp.adit-jv.com ** ** PURPOSE : ** ** ** ** REMARKS : ** ** ** ** PLATFORM DEPENDANT [yes/no]: yes ** ** ** ** TO BE CHANGED BY USER [yes/no]: no ** ** ** *******************************************************************************/ /******************************************************************************* ** Author Identity ** ******************************************************************************** ** ** ** Initials Name Company ** ** -------- ------------------------- ---------------------------------- ** ** cl Christoph Lipka ADIT ** ** fb Frederic Berat ADIT ** *******************************************************************************/ #define pr_fmt(fmt) "Common control: "fmt #include #include #include #include #include #include #include #include #include "dlt_common.h" #include "dlt_protocol.h" #include "dlt_client.h" #include "dlt-control-common.h" #define DLT_CTRL_APID "DLTC" #define DLT_CTRL_CTID "DLTC" #define DLT_DAEMON_DEFAULT_CTRL_SOCK_PATH "/tmp/dlt-ctrl.sock" /** @brief Analyze the daemon answer * * This function as to be provided by the user of the connection. * * @param answer The textual answer of the daemon * @param payload The daemons answer payload * @param length The daemons answer payload length * * @return User defined. */ static int (*response_analyzer_cb)(char *, void *, int); static pthread_t daemon_connect_thread; static DltClient g_client; static int callback_return = -1; static pthread_mutex_t answer_lock = PTHREAD_MUTEX_INITIALIZER; static pthread_cond_t answer_cond = PTHREAD_COND_INITIALIZER; static int local_verbose; static char local_ecuid[DLT_CTRL_ECUID_LEN]; /* Name of ECU */ static long local_timeout; int get_verbosity(void) { return local_verbose; } void set_verbosity(int v) { local_verbose = !!v; } char *get_ecuid(void) { return local_ecuid; } void set_ecuid(char *ecuid) { char *ecuid_conf = NULL; if (local_ecuid != ecuid) { /* If user pass NULL, read ECUId from dlt.conf */ if (ecuid == NULL) { if (dlt_parse_config_param("ECUId", &ecuid_conf) == 0) { memset(local_ecuid, 0, DLT_CTRL_ECUID_LEN); strncpy(local_ecuid, ecuid_conf, DLT_CTRL_ECUID_LEN); local_ecuid[DLT_CTRL_ECUID_LEN - 1] = '\0'; } else { pr_error("Cannot read ECUid from dlt.conf\n"); } } else { /* Set user passed ECUID */ memset(local_ecuid, 0, DLT_CTRL_ECUID_LEN); strncpy(local_ecuid, ecuid, DLT_CTRL_ECUID_LEN); local_ecuid[DLT_CTRL_ECUID_LEN - 1] = '\0'; } } } long get_timeout(void) { return local_timeout; } void set_timeout(long t) { local_timeout = DLT_CTRL_TIMEOUT; if (t > 1) local_timeout = t; else pr_error("Timeout to small. Set to default: %d", DLT_CTRL_TIMEOUT); } int dlt_parse_config_param(char *config_id, char **config_data) { FILE *pFile = NULL; int value_length = DLT_LINE_LEN; char line[DLT_LINE_LEN - 1] = { 0 }; char token[DLT_LINE_LEN] = { 0 }; char value[DLT_LINE_LEN] = { 0 }; char *pch = NULL; const char *filename = NULL; if (*config_data != NULL) *config_data = NULL; /* open configuration file */ filename = CONFIGURATION_FILES_DIR "/dlt.conf"; pFile = fopen(filename, "r"); if (pFile != NULL) { while (1) { /* fetch line from configuration file */ if (fgets(line, value_length - 1, pFile) != NULL) { if (strncmp(line, config_id, strlen(config_id)) == 0) { pch = strtok(line, " =\r\n"); token[0] = 0; value[0] = 0; while (pch != NULL) { if (token[0] == 0) { strncpy(token, pch, sizeof(token) - 1); token[sizeof(token) - 1] = 0; } else { strncpy(value, pch, sizeof(value) - 1); value[sizeof(value) - 1] = 0; break; } pch = strtok(NULL, " =\r\n"); } if (token[0] && value[0]) { if (strcmp(token, config_id) == 0) { *(config_data) = (char *) calloc(DLT_DAEMON_FLAG_MAX, sizeof(char)); memcpy(*config_data, value, DLT_DAEMON_FLAG_MAX - 1); } } } } else { break; } } fclose (pFile); } else { fprintf(stderr, "Cannot open configuration file: %s\n", filename); } if (*config_data == NULL) return -1; return 0; } /** @brief Send a message to the daemon through the socket. * * The socket as to be opened and active before sending. * * @param sock The socket to send the message through * @param msg The message to be send in DLT format. * * @return 0 on success, -1 otherwise. */ static int dlt_control_send_message_to_socket(int sock, DltMessage *msg) { if (send(sock, (const char *)(msg->headerbuffer + sizeof(DltStorageHeader)), msg->headersize - sizeof(DltStorageHeader), 0) == -1) { pr_error("Sending message header failed: %s\n", strerror(errno)); return -1; } if (send(sock, (const char *)msg->databuffer, msg->datasize, 0) == -1) { pr_error("Sending message failed: %s\n", strerror(errno)); return -1; } return 0; } /** @brief Prepare the extra headers of a DLT message * * Modifies the extra headers of the message so that it can be sent. * * @param msg The message to be prepared * @param header The base header to be used. * * @return 0 on success, -1 otherwise. */ static int prepare_extra_headers(DltMessage *msg, uint8_t *header) { int shift = 0; pr_verbose("Preparing extra headers.\n"); if (!msg || !header) return -1; shift = sizeof(DltStorageHeader) + sizeof(DltStandardHeader) + DLT_STANDARD_HEADER_EXTRA_SIZE(msg->standardheader->htyp); /* Set header extra parameters */ dlt_set_id(msg->headerextra.ecu, get_ecuid()); msg->headerextra.tmsp = dlt_uptime(); /* Copy header extra parameters to header buffer */ if (dlt_message_set_extraparameters(msg, get_verbosity()) == -1) { pr_error("Cannot copy header extra parameter\n"); return -1; } /* prepare extended header */ msg->extendedheader = (DltExtendedHeader *)(header + shift); msg->extendedheader->msin = DLT_MSIN_CONTROL_REQUEST; msg->extendedheader->noar = 1; /* one payload packet */ /* Dummy values have to be set */ dlt_set_id(msg->extendedheader->apid, DLT_CTRL_APID); dlt_set_id(msg->extendedheader->ctid, DLT_CTRL_CTID); return 0; } /** @brief Prepare the headers of a DLT message * * Modifies the headers of the message so that it can be sent. * * @param msg The message to be prepared * @param header The base header to be used. * * @return 0 on success, -1 otherwise. */ static int prepare_headers(DltMessage *msg, uint8_t *header) { uint32_t len = 0; pr_verbose("Preparing headers.\n"); if (!msg || !header) return -1; msg->storageheader = (DltStorageHeader *)header; if (dlt_set_storageheader(msg->storageheader, "") == -1) { pr_error("Storage header initialization failed.\n"); return -1; } /* prepare standard header */ msg->standardheader = (DltStandardHeader *)(header + sizeof(DltStorageHeader)); msg->standardheader->htyp = DLT_HTYP_WEID | DLT_HTYP_WTMS | DLT_HTYP_UEH | DLT_HTYP_PROTOCOL_VERSION1; #if (BYTE_ORDER == BIG_ENDIAN) msg->standardheader->htyp = (msg->standardheader->htyp | DLT_HTYP_MSBF); #endif msg->standardheader->mcnt = 0; /* prepare length information */ msg->headersize = sizeof(DltStorageHeader) + sizeof(DltStandardHeader) + sizeof(DltExtendedHeader) + DLT_STANDARD_HEADER_EXTRA_SIZE(msg->standardheader->htyp); len = msg->headersize - sizeof(DltStorageHeader) + msg->datasize; if (len > UINT16_MAX) { pr_error("Message header is too long.\n"); return -1; } msg->standardheader->len = DLT_HTOBE_16(len); return 0; } /** @brief Prepare a DLT message. * * The DLT message is built using the data given by the user. * The data is basically composed of a buffer and a size. * * @param data The message body to be used to build the DLT message. * * @return 0 on success, -1 otherwise. */ static DltMessage *dlt_control_prepare_message(DltControlMsgBody *data) { DltMessage *msg = NULL; pr_verbose("Preparing message.\n"); if (data == NULL) { pr_error("Data for message body is NULL\n"); return NULL; } msg = calloc(1, sizeof(DltMessage)); if (msg == NULL) { pr_error("Cannot allocate memory for Dlt Message\n"); return NULL; } if (dlt_message_init(msg, get_verbosity()) == -1) { pr_error("Cannot initialize Dlt Message\n"); free(msg); return NULL; } /* prepare payload of data */ msg->databuffersize = msg->datasize = data->size; /* Allocate memory for Dlt Message's buffer */ msg->databuffer = (uint8_t *)calloc(1, data->size); if (msg->databuffer == NULL) { pr_error("Cannot allocate memory for data buffer\n"); free(msg); return NULL; } /* copy data into message */ memcpy(msg->databuffer, data->data, data->size); /* prepare storage header */ if (prepare_headers(msg, msg->headerbuffer)) { dlt_message_free(msg, get_verbosity()); free(msg); return NULL; } /* prepare extra headers */ if (prepare_extra_headers(msg, msg->headerbuffer)) { dlt_message_free(msg, get_verbosity()); free(msg); return NULL; } return msg; } /** @brief Initialize the connection with the daemon * * The connection is initialized using an internal callback. The user's * response analyzer will be finally executed by this callback. * The client pointer is used to established the connection. * * @param client A pointer to a valid client structure * @param cb The internal callback to be executed while receiving a new message * * @return 0 on success, -1 otherwise. */ static int dlt_control_init_connection(DltClient *client, void *cb) { int (*callback)(DltMessage *message, void *data) = cb; if (!cb || !client) { pr_error("%s: Invalid parameters\n", __func__); return -1; } pr_verbose("Initializing the connection.\n"); if (dlt_client_init(client, get_verbosity()) != 0) { pr_error("Failed to register callback (NULL)\n"); return -1; } dlt_client_register_message_callback(callback); client->socketPath = NULL; if (dlt_parse_config_param("ControlSocketPath", &client->socketPath) != 0) { /* Failed to read from conf, copy default */ if (dlt_client_set_socket_path(client, DLT_DAEMON_DEFAULT_CTRL_SOCK_PATH) == -1) { pr_error("set socket path didn't succeed\n"); return -1; } } client->mode = DLT_CLIENT_MODE_UNIX; return dlt_client_connect(client, get_verbosity()); } /** @brief Daemon listener function * * This function will continuously read on the DLT socket, until an error occurs * or the thread executing this function is canceled. * * @param data Thread parameter * * @return The thread parameter given as argument. */ static void *dlt_control_listen_to_daemon(void *data) { pr_verbose("Ready to receive DLT answers.\n"); dlt_client_main_loop(&g_client, NULL, get_verbosity()); return data; } /** @brief Internal callback for DLT response * * This function is called by the dlt_client_main_loop once a response is read * from the DLT socket. * After some basic checks, the user's response analyzer is called. The return * value of the analyzer is then provided back to the dlt_control_send_message * function to be given back as a return value. * As this function is called in a dedicated thread, the return value is * provided using a global variable. * Access to this variable is controlled through a dedicated mutex. * New values are signaled using a dedicated condition variable. * * @param message The DLT answer * @param data Unused * * @return The analyzer return value or -1 on early errors. */ static int dlt_control_callback(DltMessage *message, void *data) { char text[DLT_RECEIVE_BUFSIZE] = { 0 }; (void)data; if (message == NULL) { pr_error("Received message is null\n"); return -1; } /* prepare storage header */ if (DLT_IS_HTYP_WEID(message->standardheader->htyp)) dlt_set_storageheader(message->storageheader, message->headerextra.ecu); else dlt_set_storageheader(message->storageheader, "LCTL"); dlt_message_header(message, text, DLT_RECEIVE_BUFSIZE, get_verbosity()); /* Extracting payload */ dlt_message_payload(message, text, DLT_RECEIVE_BUFSIZE, DLT_OUTPUT_ASCII, get_verbosity()); /* * Checking payload with the provided callback and return the result */ pthread_mutex_lock(&answer_lock); callback_return = response_analyzer_cb(text, message->databuffer, message->datasize); pthread_cond_signal(&answer_cond); pthread_mutex_unlock(&answer_lock); return callback_return; } /** @brief Send a message to the daemon and wait for the asynchronous answer. * * The answer is received and analyzed by a dedicated thread. Thus we need * to wait for the signal from this thread and then read the return value * to be provided to the user. * In case of timeout, this function fails. * The message provided by the user is formated in DLT format before sending. * * @param body The message provided by the user * @param timeout The time to wait before considering that no answer will come * * @return The user response analyzer return value, -1 in case of early error. */ int dlt_control_send_message(DltControlMsgBody *body, int timeout) { struct timespec t; DltMessage *msg = NULL; if (!body) { pr_error("%s: Invalid input.\n", __func__); return -1; } if (clock_gettime(CLOCK_REALTIME, &t) == -1) { pr_error("Cannot read system time.\n"); return -1; } t.tv_sec += timeout; /* send command to daemon here */ msg = dlt_control_prepare_message(body); if (msg == NULL) { pr_error("Control message preparation failed\n"); return -1; } pthread_mutex_lock(&answer_lock); /* Re-init the return value */ callback_return = -1; if (dlt_control_send_message_to_socket(g_client.sock, msg) != 0) { pr_error("Sending message to daemon failed\n"); free(msg); return -1; } /* If we timeout the lock is not taken back */ if (!pthread_cond_timedwait(&answer_cond, &answer_lock, &t)) pthread_mutex_unlock(&answer_lock); /* Destroying the message */ dlt_message_free(msg, get_verbosity()); free(msg); /* At this point either the value is already correct, either it's still -1. * Then, we don't care to lock the access. */ return callback_return; } /** @brief Control communication initialization * * This will prepare the DLT connection and the thread dedicated to the * response listening. * * @param response_analyzer User defined function used to analyze the response * @param ecuid The ECUID to provide to the daemon * @param verbosity The verbosity level * * @return 0 on success, -1 otherwise. */ int dlt_control_init(int (*response_analyzer)(char *, void *, int), char *ecuid, int verbosity) { if (!response_analyzer || !ecuid) { pr_error("%s: Invalid input.\n", __func__); return -1; } response_analyzer_cb = response_analyzer; set_ecuid(ecuid); set_verbosity(verbosity); if (dlt_control_init_connection(&g_client, dlt_control_callback) != 0) { pr_error("Connection initialization failed\n"); dlt_client_cleanup(&g_client, get_verbosity()); return -1; } /* Contact DLT daemon */ if (pthread_create(&daemon_connect_thread, NULL, dlt_control_listen_to_daemon, NULL) != 0) { pr_error("Cannot create thread to communicate with DLT daemon.\n"); return -1; } return 0; } /** @brief Control communication clean-up * * Cancels the listener thread and clean=up the dlt client structure. * * @return 0 on success, -1 otherwise. */ int dlt_control_deinit(void) { /* Stopping the listener thread */ pthread_cancel(daemon_connect_thread); /* Closing the socket */ return dlt_client_cleanup(&g_client, get_verbosity()); } dlt-daemon-2.18.4/src/console/dlt-control-common.h000066400000000000000000000046771353342203500220010ustar00rootroot00000000000000/** * Copyright (C) 2015 Advanced Driver Information Technology. * This code is developed by Advanced Driver Information Technology. * Copyright of Advanced Driver Information Technology, Bosch and DENSO. * * This file is part of GENIVI Project Dlt - Diagnostic Log and Trace console apps. * * * \copyright * This Source Code Form is subject to the terms of the * Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with * this file, You can obtain one at http://mozilla.org/MPL/2.0/. * * * \author Christoph Lipka ADIT 2015 * \author Frederic Berat ADIT 2015 * * \file dlt-control-common.h * For further information see http://www.genivi.org/. */ #ifndef _DLT_CONTROL_COMMON_H_ #define _DLT_CONTROL_COMMON_H_ #include #include "dlt_common.h" #define DLT_CTRL_TIMEOUT 10 #define DLT_CTRL_ECUID_LEN 10 #define DLT_DAEMON_FLAG_MAX 256 #ifndef pr_fmt # define pr_fmt(fmt) fmt #endif #ifndef USE_STDOUT # define PRINT_OUT stderr #else # define PRINT_OUT stdout #endif #define pr_error(fmt, ...) \ ({ fprintf(PRINT_OUT, pr_fmt(fmt), ## __VA_ARGS__); fflush(PRINT_OUT); }) #define pr_verbose(fmt, ...) \ ({ if (get_verbosity()) { fprintf(PRINT_OUT, pr_fmt(fmt), ## __VA_ARGS__); fflush(PRINT_OUT); } }) #define DLT_CTRL_DEFAULT_ECUID "ECU1" #define NANOSEC_PER_MILLISEC 1000000 #define NANOSEC_PER_SEC 1000000000 /* To be used as Dlt Message body when sending to DLT daemon */ typedef struct { void *data; /**< data to be send to DLT Daemon */ int size; /**< size of that data */ } DltControlMsgBody; /* As verbosity, ecuid and timeout are needed during the communication, * defining getter and setters here. * Then there is no need to define them in the control's user application. */ int get_verbosity(void); void set_verbosity(int); char *get_ecuid(void); void set_ecuid(char *); long get_timeout(void); void set_timeout(long); /* Parse dlt.conf file and return the value of requested configuration */ int dlt_parse_config_param(char *config_id, char **config_data); /* Initialize the connection to the daemon */ int dlt_control_init(int (*response_analyser)(char *, void *, int), char *ecuid, int verbosity); /* Send a message to the daemon. The call is not thread safe. */ int dlt_control_send_message(DltControlMsgBody *, int); /* Destroys the connection to the daemon */ int dlt_control_deinit(void); #endif dlt-daemon-2.18.4/src/console/dlt-control.c000066400000000000000000000577221353342203500205050ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2011-2015, BMW AG * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author Alexander Wenzel * * \copyright Copyright © 2011-2015 BMW AG. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file dlt-control.c */ /******************************************************************************* ** ** ** SRC-MODULE: dlt-control.c ** ** ** ** TARGET : linux ** ** ** ** PROJECT : DLT ** ** ** ** AUTHOR : Alexander Wenzel Alexander.AW.Wenzel@bmw.de ** ** ** ** PURPOSE : ** ** ** ** REMARKS : ** ** ** ** PLATFORM DEPENDANT [yes/no]: yes ** ** ** ** TO BE CHANGED BY USER [yes/no]: no ** ** ** *******************************************************************************/ /******************************************************************************* ** Author Identity ** ******************************************************************************** ** ** ** Initials Name Company ** ** -------- ------------------------- ---------------------------------- ** ** aw Alexander Wenzel BMW ** *******************************************************************************/ #include /* for isprint() */ #include /* for atoi() */ #include /* for S_IRUSR, S_IWUSR, S_IRGRP, S_IROTH */ #include /* for open() */ #include /* for writev() */ #include /* for open() */ #include "dlt_client.h" #include "dlt_user.h" #include "dlt-control-common.h" #define DLT_GLOGINFO_APID_NUM_MAX 150 #define DLT_GLOGINFO_DATA_MAX 800 #define DLT_GET_LOG_INFO_HEADER 18 /*Get log info header size in response text */ #define DLT_INVALID_LOG_LEVEL 0xF #define DLT_INVALID_TRACE_STATUS 0xF /* Option of GET_LOG_INFO */ #define DLT_SERVICE_GET_LOG_INFO_OPT7 7 /* get Apid, ApDescription, Ctid, CtDescription, loglevel, tracestatus */ typedef struct { uint32_t service_id; /**< service ID */ } PACKED DltServiceGetDefaultLogLevel; DltClient g_dltclient; DltServiceGetLogInfoResponse *g_resp = NULL; /* Function prototypes */ int dlt_receive_message_callback(DltMessage *message, void *data); typedef struct { int vflag; int yflag; char *evalue; char *avalue; char *cvalue; int svalue; char *mvalue; char *xvalue; int tvalue; int lvalue; int rvalue; int dvalue; int fvalue; int ivalue; int oflag; int gflag; int jvalue; int bvalue; char ecuid[4]; DltFile file; DltFilter filter; } DltReceiveData; /** * Print usage information of tool. */ void usage() { char version[255]; dlt_get_version(version, 255); printf("Usage: dlt-control [options] hostname/serial_device_name\n"); printf("Send control message to DLT daemon.\n"); printf("%s \n", version); printf("Options:\n"); printf(" -v Verbose mode\n"); printf(" -h Usage\n"); printf(" -y Serial device mode\n"); printf(" -b baudrate Serial device baudrate (Default: 115200)\n"); printf(" -e ecuid Set ECU ID (Default: RECV)\n"); printf("\n"); printf(" -a id Control message application id\n"); printf(" -c id Control message context id\n"); printf(" -s id Control message injection service id\n"); printf(" -m message Control message injection in ASCII\n"); printf(" -x message Control message injection in Hex e.g. 'ad 01 24 ef'\n"); printf(" -t milliseconds Timeout to terminate application (Default:1000)'\n"); printf(" -l loglevel Set the log level (0=off - 6=verbose default= -1)\n"); printf(" supported options:\n"); printf(" -l level -a apid -c ctid\n"); printf(" -l level -a abc* (set level for all ctxts of apps name starts with abc)\n"); printf(" -l level -a apid (set level for all ctxts of this app)\n"); printf(" -l level -c xyz* (set level for all ctxts whose name starts with xyz)\n"); printf(" -l level -c ctid (set level for the particular ctxt)\n"); printf(" -l level (set level for all the registered contexts)\n"); printf(" -r tracestatus Set the trace status (0=off - 1=on,255=default)\n"); printf(" supported options:\n"); printf(" -r tracestatus -a apid -c ctid\n"); printf(" -r tracestatus -a abc* (set status for all ctxts of apps name starts with abc)\n"); printf(" -r tracestatus -a apid (set status for all ctxts of this app)\n"); printf(" -r tracestatus -c xyz* (set status for all ctxts whose name starts with xyz)\n"); printf(" -r tracestatus -c ctid (set status for the particular ctxt)\n"); printf(" -r tracestatus (set status for all the registered contexts)\n"); printf(" -d loglevel Set the default log level (0=off - 5=verbose)\n"); printf(" -f tracestatus Set the default trace status (0=off - 1=on)\n"); printf(" -i enable Enable timing packets (0=off - 1=on)\n"); printf(" -o Store configuration\n"); printf(" -g Reset to factory default\n"); printf(" -j Get log info\n"); printf(" -u unix port\n"); } /** * Function for sending get log info ctrl msg and printing the response. */ void dlt_process_get_log_info(void) { char apid[DLT_ID_SIZE + 1] = { 0 }; char ctid[DLT_ID_SIZE + 1] = { 0 }; AppIDsType app; ContextIDsInfoType con; int i = 0; int j = 0; g_resp = (DltServiceGetLogInfoResponse *)calloc(1, sizeof(DltServiceGetLogInfoResponse)); if (g_resp == NULL) { fprintf(stderr, "%s: Calloc failed for resp..\n", __func__); return; } /* send control message*/ if (0 != dlt_client_get_log_info(&g_dltclient)) { fprintf(stderr, "ERROR: Could not get log info\n"); dlt_client_cleanup_get_log_info(g_resp); return; } if (dlt_client_main_loop(&g_dltclient, NULL, 0) == DLT_RETURN_TRUE) fprintf(stdout, "DLT-daemon's response is invalid.\n"); for (i = 0; i < g_resp->log_info_type.count_app_ids; i++) { app = g_resp->log_info_type.app_ids[i]; dlt_print_id(apid, app.app_id); if (app.app_description != 0) printf("APID:%4s %s\n", apid, app.app_description); else printf("APID:%4s \n", apid); for (j = 0; j < app.count_context_ids; j++) { con = app.context_id_info[j]; dlt_print_id(ctid, con.context_id); if (con.context_description != 0) printf("CTID:%4s %2d %2d %s\n", ctid, con.log_level, con.trace_status, con.context_description); else printf("CTID:%4s %2d %2d\n", ctid, con.log_level, con.trace_status); } } dlt_client_cleanup_get_log_info(g_resp); } /** * Main function of tool. */ int main(int argc, char *argv[]) { DltReceiveData dltdata; int c; int index; char *endptr = NULL; struct timespec ts; /* Initialize dltdata */ dltdata.vflag = 0; dltdata.yflag = 0; dltdata.evalue = 0; dltdata.bvalue = 0; dltdata.avalue = 0; dltdata.cvalue = 0; dltdata.svalue = 0; dltdata.mvalue = 0; dltdata.xvalue = 0; dltdata.tvalue = 1000; dltdata.lvalue = DLT_INVALID_LOG_LEVEL; dltdata.rvalue = DLT_INVALID_TRACE_STATUS; dltdata.dvalue = -1; dltdata.fvalue = -1; dltdata.ivalue = -1; dltdata.oflag = -1; dltdata.gflag = -1; dltdata.jvalue = 0; /* Fetch command line arguments */ opterr = 0; while ((c = getopt (argc, argv, "vhye:b:a:c:s:m:x:t:l:r:d:f:i:ogju")) != -1) switch (c) { case 'v': { dltdata.vflag = 1; break; } case 'h': { usage(); return -1; } case 'y': { dltdata.yflag = DLT_CLIENT_MODE_SERIAL; break; } case 'e': { dltdata.evalue = optarg; break; } case 'b': { dltdata.bvalue = atoi(optarg); break; } case 'a': { dltdata.avalue = optarg; if (strlen(dltdata.avalue) > DLT_ID_SIZE) { fprintf (stderr, "Invalid application id\n"); return -1; } break; } case 'c': { dltdata.cvalue = optarg; if (strlen(dltdata.cvalue) > DLT_ID_SIZE) { fprintf (stderr, "Invalid context id\n"); return -1; } break; } case 's': { dltdata.svalue = atoi(optarg); break; } case 'm': { dltdata.mvalue = optarg; break; } case 'x': { dltdata.xvalue = optarg; break; } case 't': { dltdata.tvalue = atoi(optarg); break; } case 'l': { dltdata.lvalue = strtol(optarg, &endptr, 10); if ((dltdata.lvalue < DLT_LOG_DEFAULT) || (dltdata.lvalue > DLT_LOG_VERBOSE)) { fprintf (stderr, "invalid log level, supported log level 0-6\n"); return -1; } break; } case 'r': { dltdata.rvalue = strtol(optarg, &endptr, 10); if ((dltdata.rvalue < DLT_TRACE_STATUS_DEFAULT) || (dltdata.rvalue > DLT_TRACE_STATUS_ON)) { fprintf (stderr, "invalid trace status, supported trace status -1, 0, 1\n"); return -1; } break; } case 'd': { dltdata.dvalue = atoi(optarg); break; } case 'f': { dltdata.fvalue = atoi(optarg); break; } case 'i': { dltdata.ivalue = atoi(optarg); break; } case 'o': { dltdata.oflag = 1; break; } case 'g': { dltdata.gflag = 1; break; } case 'j': { dltdata.jvalue = 1; break; } case 'u': { dltdata.yflag = DLT_CLIENT_MODE_UNIX; break; } case '?': { if ((optopt == 'o') || (optopt == 'f')) fprintf (stderr, "Option -%c requires an argument.\n", optopt); else if (isprint (optopt)) fprintf (stderr, "Unknown option `-%c'.\n", optopt); else fprintf (stderr, "Unknown option character `\\x%x'.\n", optopt); /* unknown or wrong option used, show usage information and terminate */ usage(); return -1; } default: { abort (); return -1; /*for parasoft */ } } /* Initialize DLT Client */ dlt_client_init(&g_dltclient, dltdata.vflag); /* Register callback to be called when message was received */ dlt_client_register_message_callback(dlt_receive_message_callback); /* Setup DLT Client structure */ if (dltdata.yflag == DLT_CLIENT_MODE_SERIAL) { g_dltclient.mode = DLT_CLIENT_MODE_SERIAL; } else if (dltdata.yflag == DLT_CLIENT_MODE_UNIX) { g_dltclient.mode = DLT_CLIENT_MODE_UNIX; g_dltclient.socketPath = NULL; dlt_parse_config_param("ControlSocketPath", &g_dltclient.socketPath); } else { g_dltclient.mode = DLT_CLIENT_MODE_TCP; } if (g_dltclient.mode == DLT_CLIENT_MODE_TCP) { for (index = optind; index < argc; index++) if (dlt_client_set_server_ip(&g_dltclient, argv[index]) == -1) { pr_error("set server ip didn't succeed\n"); return -1; } if (g_dltclient.servIP == 0) { /* no hostname selected, show usage and terminate */ fprintf(stderr, "ERROR: No hostname selected\n"); usage(); dlt_client_cleanup(&g_dltclient, dltdata.vflag); return -1; } } else if (g_dltclient.mode == DLT_CLIENT_MODE_SERIAL) { for (index = optind; index < argc; index++) if (dlt_client_set_serial_device(&g_dltclient, argv[index]) == -1) { pr_error("set serial device didn't succeed\n"); return -1; } if (g_dltclient.serialDevice == 0) { /* no serial device name selected, show usage and terminate */ fprintf(stderr, "ERROR: No serial device name specified\n"); usage(); return -1; } dlt_client_setbaudrate(&g_dltclient, dltdata.bvalue); } /* initialise structure to use DLT file */ dlt_file_init(&(dltdata.file), dltdata.vflag); /* first parse filter file if filter parameter is used */ dlt_filter_init(&(dltdata.filter), dltdata.vflag); if (dltdata.evalue) { dlt_set_id(dltdata.ecuid, dltdata.evalue); dlt_set_id(g_dltclient.ecuid, dltdata.evalue); } else { dltdata.evalue = NULL; if (dlt_parse_config_param("ECUId", &dltdata.evalue) == 0) { dlt_set_id(dltdata.ecuid, dltdata.evalue); dlt_set_id(g_dltclient.ecuid, dltdata.evalue); free (dltdata.evalue); } else { fprintf(stderr, "ERROR: Failed to read ECUId from dlt.conf \n"); } } /* Connect to TCP socket or open serial device */ if (dlt_client_connect(&g_dltclient, dltdata.vflag) != DLT_RETURN_ERROR) { /* send injection message */ if (dltdata.mvalue && dltdata.avalue && dltdata.cvalue) { /* ASCII */ printf("Send injection message:\n"); printf("AppId: %s\n", dltdata.avalue); printf("ConId: %s\n", dltdata.cvalue); printf("ServiceId: %d\n", dltdata.svalue); printf("Message: %s\n", dltdata.mvalue); /* send control message in ascii */ if (dlt_client_send_inject_msg(&g_dltclient, dltdata.avalue, dltdata.cvalue, dltdata.svalue, (uint8_t *)dltdata.mvalue, strlen(dltdata.mvalue)) != DLT_RETURN_OK) fprintf(stderr, "ERROR: Could not send inject message\n"); } else if (dltdata.xvalue && dltdata.avalue && dltdata.cvalue) { /* Hex */ uint8_t buffer[1024]; int size = 1024; printf("Send injection message:\n"); printf("AppId: %s\n", dltdata.avalue); printf("ConId: %s\n", dltdata.cvalue); printf("ServiceId: %d\n", dltdata.svalue); printf("Message: %s\n", dltdata.xvalue); dlt_hex_ascii_to_binary(dltdata.xvalue, buffer, &size); printf("Size: %d\n", size); /* send control message in hex */ if (dlt_client_send_inject_msg(&g_dltclient, dltdata.avalue, dltdata.cvalue, dltdata.svalue, buffer, size) != DLT_RETURN_OK) fprintf(stderr, "ERROR: Could not send inject message\n"); } else if (dltdata.lvalue != DLT_INVALID_LOG_LEVEL) /*&& dltdata.avalue && dltdata.cvalue)*/ { if ((dltdata.avalue == 0) && (dltdata.cvalue == 0)) { if (dltdata.vflag) { printf("Set all log level:\n"); printf("Loglevel: %d\n", dltdata.lvalue); } if (0 != dlt_client_send_all_log_level(&g_dltclient, dltdata.lvalue)) fprintf(stderr, "ERROR: Could not send log level\n"); } else { /* log level */ if (dltdata.vflag) { printf("Set log level:\n"); printf("AppId: %s\n", dltdata.avalue); printf("ConId: %s\n", dltdata.cvalue); printf("Loglevel: %d\n", dltdata.lvalue); } /* send control message*/ if (0 != dlt_client_send_log_level(&g_dltclient, dltdata.avalue, dltdata.cvalue, dltdata.lvalue)) fprintf(stderr, "ERROR: Could not send log level\n"); } } else if (dltdata.rvalue != DLT_INVALID_TRACE_STATUS) { if ((dltdata.avalue == 0) && (dltdata.cvalue == 0)) { if (dltdata.vflag) { printf("Set all trace status:\n"); printf("Tracestatus: %d\n", dltdata.rvalue); } if (0 != dlt_client_send_all_trace_status(&g_dltclient, dltdata.rvalue)) fprintf(stderr, "ERROR: Could not send trace status\n"); } else { /* trace status */ if (dltdata.vflag) { printf("Set trace status:\n"); printf("AppId: %s\n", dltdata.avalue); printf("ConId: %s\n", dltdata.cvalue); printf("Tracestatus: %d\n", dltdata.rvalue); } /* send control message*/ if (0 != dlt_client_send_trace_status(&g_dltclient, dltdata.avalue, dltdata.cvalue, dltdata.rvalue)) fprintf(stderr, "ERROR: Could not send trace status\n"); } } else if (dltdata.dvalue != -1) { /* default log level */ printf("Set default log level:\n"); printf("Loglevel: %d\n", dltdata.dvalue); /* send control message in*/ if (dlt_client_send_default_log_level(&g_dltclient, dltdata.dvalue) != DLT_RETURN_OK) fprintf (stderr, "ERROR: Could not send default log level\n"); } else if (dltdata.fvalue != -1) { /* default trace status */ printf("Set default trace status:\n"); printf("TraceStatus: %d\n", dltdata.fvalue); /* send control message in*/ if (dlt_client_send_default_trace_status(&g_dltclient, dltdata.fvalue) != DLT_RETURN_OK) fprintf (stderr, "ERROR: Could not send default trace status\n"); } else if (dltdata.ivalue != -1) { /* timing pakets */ printf("Set timing pakets:\n"); printf("Timing packets: %d\n", dltdata.ivalue); /* send control message in*/ if (dlt_client_send_timing_pakets(&g_dltclient, dltdata.ivalue) != DLT_RETURN_OK) fprintf (stderr, "ERROR: Could not send timing packets\n"); } else if (dltdata.oflag != -1) { /* default trace status */ printf("Store config\n"); /* send control message in*/ if (dlt_client_send_store_config(&g_dltclient) != DLT_RETURN_OK) fprintf (stderr, "ERROR: Could not send store config\n"); } else if (dltdata.gflag != -1) { /* reset to factory default */ printf("Reset to factory default\n"); /* send control message in*/ if (dlt_client_send_reset_to_factory_default(&g_dltclient) != DLT_RETURN_OK) fprintf (stderr, "ERROR: Could send reset to factory default\n"); } else if (dltdata.jvalue == 1) { /* get log info */ printf("Get log info:\n"); dlt_process_get_log_info(); } /* Dlt Client Main Loop */ /*dlt_client_main_loop(&dltclient, &dltdata, dltdata.vflag); */ /* Wait timeout */ ts.tv_sec = (dltdata.tvalue * NANOSEC_PER_MILLISEC) / NANOSEC_PER_SEC; ts.tv_nsec = (dltdata.tvalue * NANOSEC_PER_MILLISEC) % NANOSEC_PER_SEC; nanosleep(&ts, NULL); } /* Dlt Client Cleanup */ dlt_client_cleanup(&g_dltclient, dltdata.vflag); if (g_dltclient.socketPath != NULL) free(g_dltclient.socketPath); dlt_file_free(&(dltdata.file), dltdata.vflag); dlt_filter_free(&(dltdata.filter), dltdata.vflag); return 0; } int dlt_receive_message_callback(DltMessage *message, void *data) { static char resp_text[DLT_RECEIVE_BUFSIZE]; int ret = DLT_RETURN_ERROR; /* parameter check */ if (message == NULL) return -1; /* to avoid warning */ (void)data; /* prepare storage header */ if (DLT_IS_HTYP_WEID(message->standardheader->htyp)) dlt_set_storageheader(message->storageheader, message->headerextra.ecu); else dlt_set_storageheader(message->storageheader, "LCTL"); /* get response data */ ret = dlt_message_header(message, resp_text, DLT_RECEIVE_BUFSIZE, 0); if (ret < 0) { fprintf(stderr, "GET_LOG_INFO message_header result failed..\n"); dlt_client_cleanup(&g_dltclient, 0); return -1; } ret = dlt_message_payload(message, resp_text, DLT_RECEIVE_BUFSIZE, DLT_OUTPUT_ASCII, 0); if (ret < 0) { fprintf(stderr, "GET_LOG_INFO message_payload result failed..\n"); dlt_client_cleanup(&g_dltclient, 0); return -1; } /* check service id */ if (g_resp == NULL) { fprintf(stderr, "%s: g_resp isn't allocated.\n", __func__); dlt_client_cleanup(&g_dltclient, 0); return -1; } ret = dlt_set_loginfo_parse_service_id(resp_text, &g_resp->service_id, &g_resp->status); if ((ret == 0) && (g_resp->service_id == DLT_SERVICE_ID_GET_LOG_INFO)) { ret = dlt_client_parse_get_log_info_resp_text(g_resp, resp_text); if (ret != 0) fprintf(stderr, "GET_LOG_INFO result failed..\n"); dlt_client_cleanup(&g_dltclient, 0); } return ret; } dlt-daemon-2.18.4/src/console/dlt-convert.c000066400000000000000000000306141353342203500204740ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2011-2015, BMW AG * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author Alexander Wenzel * * \copyright Copyright © 2011-2015 BMW AG. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file dlt-convert.c */ /******************************************************************************* ** ** ** SRC-MODULE: dlt-convert.c ** ** ** ** TARGET : linux ** ** ** ** PROJECT : DLT ** ** ** ** AUTHOR : Alexander Wenzel Alexander.AW.Wenzel@bmw.de ** ** Markus Klein ** ** ** ** PURPOSE : ** ** ** ** REMARKS : ** ** ** ** PLATFORM DEPENDANT [yes/no]: yes ** ** ** ** TO BE CHANGED BY USER [yes/no]: no ** ** ** *******************************************************************************/ /******************************************************************************* ** Author Identity ** ******************************************************************************** ** ** ** Initials Name Company ** ** -------- ------------------------- ---------------------------------- ** ** aw Alexander Wenzel BMW ** ** mk Markus Klein Fraunhofer ESK ** *******************************************************************************/ /******************************************************************************* ** Author Identity ** ******************************************************************************** ** ** ** Initials Name Company ** ** -------- ------------------------- ---------------------------------- ** ** aw Alexander Wenzel BMW ** *******************************************************************************/ /******************************************************************************* ** Revision Control History ** *******************************************************************************/ /* * $LastChangedRevision: 1670 $ * $LastChangedDate: 2011-04-08 15:12:06 +0200 (Fr, 08. Apr 2011) $ * $LastChangedBy$ * Initials Date Comment * aw 13.01.2010 initial */ #include #include #include #include #include #include #include #include /* writev() */ #include "dlt_common.h" #define DLT_CONVERT_TEXTBUFSIZE 10024 /* Size of buffer for text output */ /** * Print usage information of tool. */ void usage() { char version[DLT_CONVERT_TEXTBUFSIZE]; dlt_get_version(version, 255); printf("Usage: dlt-convert [options] [commands] file1 [file2]\n"); printf("Read DLT files, print DLT messages as ASCII and store the messages again.\n"); printf("Use filters to filter DLT messages.\n"); printf("Use Ranges and Output file to cut DLT files.\n"); printf("Use two files and Output file to join DLT files.\n"); printf("%s \n", version); printf("Commands:\n"); printf(" -h Usage\n"); printf(" -a Print DLT file; payload as ASCII\n"); printf(" -x Print DLT file; payload as hex\n"); printf(" -m Print DLT file; payload as hex and ASCII\n"); printf(" -s Print DLT file; only headers\n"); printf(" -o filename Output messages in new DLT file\n"); printf("Options:\n"); printf(" -v Verbose mode\n"); printf(" -c Count number of messages\n"); printf(" -f filename Enable filtering of messages\n"); printf(" -b number First messages to be handled\n"); printf(" -e number Last message to be handled\n"); printf(" -w Follow dlt file while file is increasing\n"); } /** * Main function of tool. */ int main(int argc, char *argv[]) { int vflag = 0; int cflag = 0; int aflag = 0; int sflag = 0; int xflag = 0; int mflag = 0; int wflag = 0; char *fvalue = 0; char *bvalue = 0; char *evalue = 0; char *ovalue = 0; int index; int c; DltFile file; DltFilter filter; int ohandle = -1; int num, begin, end; char text[DLT_CONVERT_TEXTBUFSIZE]; struct iovec iov[2]; int bytes_written; opterr = 0; while ((c = getopt (argc, argv, "vcashxmwf:b:e:o:")) != -1) switch (c) { case 'v': { vflag = 1; break; } case 'c': { cflag = 1; break; } case 'a': { aflag = 1; break; } case 's': { sflag = 1; break; } case 'x': { xflag = 1; break; } case 'm': { mflag = 1; break; } case 'w': { wflag = 1; break; } case 'h': { usage(); return -1; } case 'f': { fvalue = optarg; break; } case 'b': { bvalue = optarg; break; } case 'e': { evalue = optarg; break; } case 'o': { ovalue = optarg; break; } case '?': { if ((optopt == 'f') || (optopt == 'b') || (optopt == 'e') || (optopt == 'o')) fprintf (stderr, "Option -%c requires an argument.\n", optopt); else if (isprint (optopt)) fprintf (stderr, "Unknown option `-%c'.\n", optopt); else fprintf (stderr, "Unknown option character `\\x%x'.\n", optopt); /* unknown or wrong option used, show usage information and terminate */ usage(); return -1; } default: { abort(); return -1; /*for parasoft */ } } /* initialise structure to use DLT file */ dlt_file_init(&file, vflag); /* first parse filter file if filter parameter is used */ if (fvalue) { if (dlt_filter_load(&filter, fvalue, vflag) < DLT_RETURN_OK) { dlt_file_free(&file, vflag); return -1; } dlt_file_set_filter(&file, &filter, vflag); } if (ovalue) { ohandle = open(ovalue, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); /* mode: wb */ if (ohandle == -1) { dlt_file_free(&file, vflag); fprintf(stderr, "ERROR: Output file %s cannot be opened!\n", ovalue); return -1; } } for (index = optind; index < argc; index++) { /* load, analyse data file and create index list */ if (dlt_file_open(&file, argv[index], vflag) >= DLT_RETURN_OK) { while (dlt_file_read(&file, vflag) >= DLT_RETURN_OK) {} } if (aflag || sflag || xflag || mflag || ovalue) { if (bvalue) begin = atoi(bvalue); else begin = 0; if (evalue && (wflag == 0)) end = atoi(evalue); else end = file.counter - 1; if ((begin < 0) || (begin >= file.counter)) { fprintf(stderr, "ERROR: Selected first message %d is out of range!\n", begin); return -1; } if ((end < 0) || (end >= file.counter) || (end < begin)) { fprintf(stderr, "ERROR: Selected end message %d is out of range!\n", end); return -1; } for (num = begin; num <= end; num++) { dlt_file_message(&file, num, vflag); if (xflag) { printf("%d ", num); dlt_message_print_hex(&(file.msg), text, DLT_CONVERT_TEXTBUFSIZE, vflag); } else if (aflag) { printf("%d ", num); dlt_message_header(&(file.msg), text, DLT_CONVERT_TEXTBUFSIZE, vflag); printf("%s ", text); dlt_message_payload(&file.msg, text, DLT_CONVERT_TEXTBUFSIZE, DLT_OUTPUT_ASCII, vflag); printf("[%s]\n", text); } else if (mflag) { printf("%d ", num); dlt_message_print_mixed_plain(&(file.msg), text, DLT_CONVERT_TEXTBUFSIZE, vflag); } else if (sflag) { printf("%d ", num); dlt_message_header(&(file.msg), text, DLT_CONVERT_TEXTBUFSIZE, vflag); printf("%s \n", text); } /* if file output enabled write message */ if (ovalue) { iov[0].iov_base = file.msg.headerbuffer; iov[0].iov_len = file.msg.headersize; iov[1].iov_base = file.msg.databuffer; iov[1].iov_len = file.msg.datasize; bytes_written = writev(ohandle, iov, 2); if (0 > bytes_written) { printf("in main: writev(ohandle, iov, 2); returned an error!"); dlt_file_free(&file, vflag); return -1; } } /* check for new messages if follow flag set */ if (wflag && (num == end)) { while (1) { while (dlt_file_read(&file, 0) >= 0) {} if (end == (file.counter - 1)) { /* Sleep if no new message was received */ struct timespec req; req.tv_sec = 0; req.tv_nsec = 100000000; nanosleep(&req, NULL); } else { /* set new end of log file and continue reading */ end = file.counter - 1; break; } } } } } if (cflag) { printf("Total number of messages: %d\n", file.counter_total); if (file.filter) printf("Filtered number of messages: %d\n", file.counter); } } if (ovalue) close(ohandle); if (index == optind) { /* no file selected, show usage and terminate */ fprintf(stderr, "ERROR: No file selected\n"); usage(); return -1; } dlt_file_free(&file, vflag); return 0; } dlt-daemon-2.18.4/src/console/dlt-passive-node-ctrl.c000066400000000000000000000312371353342203500223550ustar00rootroot00000000000000/** * Copyright (C) 2015 Advanced Driver Information Technology. * This code is developed by Advanced Driver Information Technology. * Copyright of Advanced Driver Information Technology, Bosch and DENSO. * * This file is part of GENIVI Project Dlt - Diagnostic Log and Trace console apps. * * * \copyright * This Source Code Form is subject to the terms of the * Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with * this file, You can obtain one at http://mozilla.org/MPL/2.0/. * * * \author Christoph Lipka ADIT 2015 * * \file dlt-passive-node-ctrl.c * For further information see http://www.genivi.org/. */ /******************************************************************************* ** ** ** SRC-MODULE: dlt-passive-node-ctrl.c ** ** ** ** TARGET : linux ** ** ** ** PROJECT : DLT ** ** ** ** AUTHOR : Christoph Lipka ** ** PURPOSE : ** ** ** ** REMARKS : ** ** ** ** PLATFORM DEPENDANT [yes/no]: yes ** ** ** ** TO BE CHANGED BY USER [yes/no]: no ** ** ** *******************************************************************************/ /******************************************************************************* ** Author Identity ** ******************************************************************************** ** ** ** Initials Name Company ** ** -------- ------------------------- ---------------------------------- ** ** CL Christoph Lipka ADIT ** *******************************************************************************/ #include #include #include #include #include #include "dlt_protocol.h" #include "dlt_client.h" #include "dlt-control-common.h" #include "dlt_daemon_connection_types.h" #define MAX_RESPONSE_LENGTH 32 #define DLT_NODE_CONNECT 1 #define DLT_NODE_DISCONNECT 0 #define DLT_NODE_CONNECT_UNDEF 999 #define DLT_GATEWAY_CONNECTED 2 #define DLT_NODE_CONNECTED_STR "Connected" #define DLT_NODE_DISCONNECTED_STR "Disconnected" #define UNDEFINED 999 static struct PassiveNodeOptions { unsigned int command; /**< passive node control command */ unsigned int connection_state; /**< connection state */ char node_id[DLT_ID_SIZE]; /**< node identifier */ long timeout; /**< Default timeout */ } g_options = { .command = UNDEFINED, .connection_state = UNDEFINED, .node_id = { '\0' }, }; unsigned int get_command(void) { return g_options.command; } void set_command(unsigned int c) { g_options.command = c; } unsigned int get_connection_state(void) { return g_options.connection_state; } void set_connection_state(unsigned int s) { if ((s == DLT_NODE_CONNECT) || (s == DLT_NODE_DISCONNECT)) { g_options.connection_state = s; set_command(DLT_SERVICE_ID_PASSIVE_NODE_CONNECT); } else { pr_error("Connection status %u invalid\n", s); exit(-1); } } void set_node_id(char *id) { if (id == 0) { pr_error("node identifier is NULL\n"); exit(-1); } else { strncpy(g_options.node_id, id, DLT_ID_SIZE); } } char *get_node_id() { return g_options.node_id; } /** * @brief Print passive node status information * * @param info DltServicePassiveNodeConnectionInfo */ static void dlt_print_passive_node_status( DltServicePassiveNodeConnectionInfo *info) { unsigned int i = 0; char *status; if (info == NULL) return; printf("\nPassive Node connection status:\n" "---------------------------------\n"); for (i = 0; i < info->num_connections; i++) { if (info->connection_status[i] == DLT_GATEWAY_CONNECTED) status = DLT_NODE_CONNECTED_STR; else status = DLT_NODE_DISCONNECTED_STR; printf("%.4s: %s\n", &info->node_id[i * DLT_ID_SIZE], status); } printf("\n"); } /** * @brief Analyze received DLT Daemon response * * This function checks the received message. In particular, it checks the * answer string 'service(\, {ok, error, perm_denied})'. In any case the * g_callback_return variable will be set as well which is evaluated in the * main function after the communication thread returned. * * @param answer Recieved response * @param payload Received DLT Message * @param len Length of received DLT message * @return 0 if daemon returns 'ok' message, -1 otherwise */ static int dlt_passive_node_analyze_response(char *answer, void *payload, int len) { int ret = -1; char resp_ok[MAX_RESPONSE_LENGTH] = { 0 }; if ((answer == NULL) || (payload == NULL)) return -1; snprintf(resp_ok, MAX_RESPONSE_LENGTH, "service(%u), ok", get_command()); pr_verbose("Response received: '%s'\n", answer); pr_verbose("Response expected: '%s'\n", resp_ok); if (strncmp(answer, resp_ok, strlen(resp_ok)) == 0) { ret = 0; if (get_command() == DLT_SERVICE_ID_PASSIVE_NODE_CONNECTION_STATUS) { if ((int)sizeof(DltServicePassiveNodeConnectionInfo) > len) { pr_error("Received payload is smaller than expected\n"); pr_verbose("Expected: %zu,\nreceived: %d", sizeof(DltServicePassiveNodeConnectionInfo), len); ret = -1; } else { DltServicePassiveNodeConnectionInfo *info = (DltServicePassiveNodeConnectionInfo *)(payload); if (info == NULL) { fprintf(stderr, "Received response is NULL\n"); return -1; } dlt_print_passive_node_status(info); } } } return ret; } /** * @brief Prepare message body to be send to DLT Daemon * * @return Pointer ot DltControlMsgBody, NULL otherwise */ DltControlMsgBody *dlt_passive_node_prepare_message_body() { DltControlMsgBody *mb = calloc(1, sizeof(DltControlMsgBody)); char *ecuid = get_node_id(); if (mb == NULL) return NULL; if (get_command() == DLT_SERVICE_ID_PASSIVE_NODE_CONNECT) { mb->data = calloc(1, sizeof(DltServicePassiveNodeConnect)); if (mb->data == NULL) { free(mb); return NULL; } mb->size = sizeof(DltServicePassiveNodeConnect); DltServicePassiveNodeConnect *serv = (DltServicePassiveNodeConnect *) mb->data; serv->service_id = DLT_SERVICE_ID_PASSIVE_NODE_CONNECT; serv->connection_status = get_connection_state(); memcpy(serv->node_id, ecuid, DLT_ID_SIZE); } else { /* DLT_SERVICE_ID_PASSIVE_NODE_CONNECTION_STATUS */ mb->data = calloc(1, sizeof(DltServicePassiveNodeConnectionInfo)); if (mb->data == NULL) { free(mb); return NULL; } mb->size = sizeof(DltServicePassiveNodeConnectionInfo); DltServicePassiveNodeConnectionInfo *serv = (DltServicePassiveNodeConnectionInfo *)mb->data; serv->service_id = DLT_SERVICE_ID_PASSIVE_NODE_CONNECTION_STATUS; } return mb; } /** * @brief Destroy message body */ void dlt_passive_node_destroy_message_body(DltControlMsgBody *msg_body) { if (msg_body == NULL) return; if (msg_body->data != NULL) free(msg_body->data); free(msg_body); } /** * @brief Send a single command to DLT daemon and wait for response * * @return 0 on success, -1 on error */ static int dlt_passive_node_ctrl_single_request() { int ret = -1; /* Initializing the communication with the daemon */ if (dlt_control_init(dlt_passive_node_analyze_response, get_ecuid(), get_verbosity()) != 0) { pr_error("Failed to initialize connection with the daemon.\n"); return ret; } /* prepare message body */ DltControlMsgBody *msg_body = NULL; msg_body = dlt_passive_node_prepare_message_body(); if (msg_body == NULL) { pr_error("Data for Dlt Message body is NULL\n"); return ret; } ret = dlt_control_send_message(msg_body, get_timeout()); dlt_passive_node_destroy_message_body(msg_body); dlt_control_deinit(); return ret; } static void usage() { printf("Usage: dlt-passive-node-ctrl [options]\n"); printf("Send a trigger to DLT daemon to (dis)connect a passive node " "or get current passive node status \n"); printf("\n"); printf("Options:\n"); printf(" -c Connection status (1 - connect, 0 - disconnect)\n"); printf(" -h Usage\n"); printf(" -n passive Node identifier (e.g. ECU2)\n"); printf(" -s Show passive node(s) connection status\n"); printf(" -t Specify connection timeout (Default: %ds)\n", DLT_CTRL_TIMEOUT); printf(" -v Set verbose flag (Default:%d)\n", get_verbosity()); } /** * @brief Parse application arguments * * The arguments are parsed and saved in static structure for future use. * * @param argc amount of arguments * @param argv argument table * @return 0 on success, -1 otherwise */ static int parse_args(int argc, char *argv[]) { int c = 0; int state = -1; /* Get command line arguments */ opterr = 0; while ((c = getopt(argc, argv, "c:hn:stv")) != -1) switch (c) { case 'c': state = (int)strtol(optarg, NULL, 10); if ((state == DLT_NODE_CONNECT) || (state == DLT_NODE_DISCONNECT)) { set_connection_state(state); set_command(DLT_SERVICE_ID_PASSIVE_NODE_CONNECT); } else { pr_error("unknown connection state: %d\n", state); return -1; } break; case 'h': usage(); return -1; case 'n': set_node_id(optarg); break; case 's': set_command(DLT_SERVICE_ID_PASSIVE_NODE_CONNECTION_STATUS); break; case 't': set_timeout(strtol(optarg, NULL, 10)); break; case 'v': set_verbosity(1); pr_verbose("Now in verbose mode.\n"); break; case '?': if (isprint(optopt)) pr_error("Unknown option -%c.\n", optopt); else pr_error("Unknown option character \\x%x.\n", optopt); usage(); return -1; default: pr_error("Try %s -h for more information.\n", argv[0]); return -1; } return 0; } /** * @brief Entry point * * Execute the argument parser and call the main feature accordingly * * @param argc amount of arguments * @param argv argument table * @return 0 on success, -1 otherwise */ int main(int argc, char *argv[]) { int ret = 0; set_ecuid(NULL); set_timeout(DLT_CTRL_TIMEOUT); /* Get command line arguments */ if (parse_args(argc, argv) != 0) return -1; if ((get_command() == UNDEFINED) || ((get_command() == DLT_SERVICE_ID_PASSIVE_NODE_CONNECT) && (g_options.node_id[0] == '\0') && (g_options.connection_state == DLT_NODE_CONNECT_UNDEF))) { pr_error("No valid parameter configuration given!\n"); usage(); return -1; } pr_verbose("Sending command to DLT daemon.\n"); /* one shot request */ ret = dlt_passive_node_ctrl_single_request(); pr_verbose("Exiting.\n"); return ret; } dlt-daemon-2.18.4/src/console/dlt-receive.c000066400000000000000000000453121353342203500204370ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2011-2015, BMW AG * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author Alexander Wenzel * * \copyright Copyright © 2011-2015 BMW AG. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file dlt-receive.c */ /******************************************************************************* ** ** ** SRC-MODULE: dlt-receive.c ** ** ** ** TARGET : linux ** ** ** ** PROJECT : DLT ** ** ** ** AUTHOR : Alexander Wenzel Alexander.AW.Wenzel@bmw.de ** ** Markus Klein ** ** ** ** PURPOSE : ** ** ** ** REMARKS : ** ** ** ** PLATFORM DEPENDANT [yes/no]: yes ** ** ** ** TO BE CHANGED BY USER [yes/no]: no ** ** ** *******************************************************************************/ /******************************************************************************* ** Author Identity ** ******************************************************************************** ** ** ** Initials Name Company ** ** -------- ------------------------- ---------------------------------- ** ** aw Alexander Wenzel BMW ** ** mk Markus Klein Fraunhofer ESK ** *******************************************************************************/ /******************************************************************************* ** Revision Control History ** *******************************************************************************/ /* * $LastChangedRevision: 1670 $ * $LastChangedDate: 2011-04-08 15:12:06 +0200 (Fr, 08. Apr 2011) $ * $LastChangedBy$ * Initials Date Comment * aw 13.01.2010 initial */ #include /* for isprint() */ #include /* for atoi() */ #include /* for S_IRUSR, S_IWUSR, S_IRGRP, S_IROTH */ #include /* for open() */ #include /* for writev() */ #include #include #include #include #ifdef __linux__ # include #else # include #endif #include #include "dlt_client.h" #define DLT_RECEIVE_ECU_ID "RECV" /* Function prototypes */ int dlt_receive_message_callback(DltMessage *message, void *data); typedef struct { int aflag; int sflag; int xflag; int mflag; int vflag; int yflag; char *ovalue; char *ovaluebase; /* ovalue without ".dlt" */ char *fvalue; char *evalue; int bvalue; int64_t climit; char ecuid[4]; int ohandle; int64_t totalbytes; /* bytes written so far into the output file, used to check the file size limit */ int part_num; /* number of current output file if limit was exceeded */ DltFile file; DltFilter filter; } DltReceiveData; /** * Print usage information of tool. */ void usage() { char version[255]; dlt_get_version(version, 255); printf("Usage: dlt-receive [options] hostname/serial_device_name\n"); printf("Receive DLT messages from DLT daemon and print or store the messages.\n"); printf("Use filters to filter received messages.\n"); printf("%s \n", version); printf("Options:\n"); printf(" -a Print DLT messages; payload as ASCII\n"); printf(" -x Print DLT messages; payload as hex\n"); printf(" -m Print DLT messages; payload as hex and ASCII\n"); printf(" -s Print DLT messages; only headers\n"); printf(" -v Verbose mode\n"); printf(" -h Usage\n"); printf(" -y Serial device mode\n"); printf(" -b baudrate Serial device baudrate (Default: 115200)\n"); printf(" -e ecuid Set ECU ID (Default: RECV)\n"); printf(" -o filename Output messages in new DLT file\n"); printf(" -c limit Restrict file size to bytes when output to file\n"); printf(" When limit is reached, a new file is opened. Use K,M,G as\n"); printf(" suffix to specify kilo-, mega-, giga-bytes respectively\n"); printf(" -f filename Enable filtering of messages\n"); } int64_t convert_arg_to_byte_size(char *arg) { size_t i; int64_t factor; int64_t result; /* check if valid input */ for (i = 0; i < strlen(arg) - 1; ++i) if (!isdigit(arg[i])) return -2; /* last character */ factor = 1; if ((arg[strlen(arg) - 1] == 'K') || (arg[strlen(arg) - 1] == 'k')) { factor = 1024; } else if ((arg[strlen(arg) - 1] == 'M') || (arg[strlen(arg) - 1] == 'm')) { factor = 1024 * 1024; } else if ((arg[strlen(arg) - 1] == 'G') || (arg[strlen(arg) - 1] == 'g')) { factor = 1024 * 1024 * 1024; } else if (!isdigit(arg[strlen(arg) - 1])) return -2; /* range checking */ int64_t const mult = atoll(arg); if (((INT64_MAX) / factor) < mult) /* Would overflow! */ return -2; result = factor * mult; /* The result be at least the size of one message * One message consists of its header + user data: */ DltMessage msg; int64_t min_size = sizeof(msg.headerbuffer); min_size += 2048 /* DLT_USER_BUF_MAX_SIZE */; if (min_size > result) { dlt_vlog(LOG_ERR, "ERROR: Specified limit: %" PRId64 "is smaller than a the size of a single message: %" PRId64 "!\n", result, min_size); result = -2; } return result; } /* * open output file */ int dlt_receive_open_output_file(DltReceiveData *dltdata) { /* if (file_already_exists) */ glob_t outer; if (glob(dltdata->ovalue, GLOB_TILDE | GLOB_NOSORT, NULL, &outer) == 0) { if (dltdata->vflag) { dlt_vlog(LOG_INFO, "File %s already exists, need to rename first\n", dltdata->ovalue); } if (dltdata->part_num < 0) { char pattern[PATH_MAX + 1]; pattern[PATH_MAX] = 0; snprintf(pattern, PATH_MAX, "%s.*.dlt", dltdata->ovaluebase); glob_t inner; /* sort does not help here because we have to traverse the * full result in any case. Remember, a sorted list would look like: * foo.1.dlt * foo.10.dlt * foo.1000.dlt * foo.11.dlt */ if (glob(pattern, GLOB_TILDE | GLOB_NOSORT, NULL, &inner) == 0) { /* search for the highest number used */ size_t i; for (i = 0; i < inner.gl_pathc; ++i) { /* convert string that follows the period after the initial portion, * e.g. gt.gl_pathv[i] = foo.1.dlt -> atoi("1.dlt"); */ int cur = atoi(&inner.gl_pathv[i][strlen(dltdata->ovaluebase) + 1]); if (cur > dltdata->part_num) dltdata->part_num = cur; } } globfree(&inner); ++dltdata->part_num; } char filename[PATH_MAX + 1]; filename[PATH_MAX] = 0; snprintf(filename, PATH_MAX, "%s.%i.dlt", dltdata->ovaluebase, dltdata->part_num++); if (rename(dltdata->ovalue, filename) != 0) { dlt_vlog(LOG_ERR, "ERROR: rename %s to %s failed with error %s\n", dltdata->ovalue, filename, strerror(errno)); } else if (dltdata->vflag) { dlt_vlog(LOG_INFO, "Renaming existing file from %s to %s\n", dltdata->ovalue, filename); } } /* if (file_already_exists) */ globfree(&outer); dltdata->ohandle = open(dltdata->ovalue, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); return dltdata->ohandle; } void dlt_receive_close_output_file(DltReceiveData *dltdata) { if (dltdata->ohandle) { close(dltdata->ohandle); dltdata->ohandle = -1; } } /** * Main function of tool. */ int main(int argc, char *argv[]) { DltClient dltclient; DltReceiveData dltdata; int c; int index; /* Initialize dltdata */ dltdata.aflag = 0; dltdata.sflag = 0; dltdata.xflag = 0; dltdata.mflag = 0; dltdata.vflag = 0; dltdata.yflag = 0; dltdata.ovalue = 0; dltdata.ovaluebase = 0; dltdata.fvalue = 0; dltdata.evalue = 0; dltdata.bvalue = 0; dltdata.climit = -1; /* default: -1 = unlimited */ dltdata.ohandle = -1; dltdata.totalbytes = 0; dltdata.part_num = -1; /* Fetch command line arguments */ opterr = 0; while ((c = getopt (argc, argv, "vashyxmf:o:e:b:c:")) != -1) switch (c) { case 'v': { dltdata.vflag = 1; break; } case 'a': { dltdata.aflag = 1; break; } case 's': { dltdata.sflag = 1; break; } case 'x': { dltdata.xflag = 1; break; } case 'm': { dltdata.mflag = 1; break; } case 'h': { usage(); return -1; } case 'y': { dltdata.yflag = 1; break; } case 'f': { dltdata.fvalue = optarg; break; } case 'o': { dltdata.ovalue = optarg; size_t to_copy = strlen(dltdata.ovalue); if (strcmp(&dltdata.ovalue[to_copy - 4], ".dlt") == 0) to_copy = to_copy - 4; dltdata.ovaluebase = (char *)calloc(1, to_copy + 1); if (dltdata.ovaluebase == NULL) { fprintf (stderr, "Memory allocation failed.\n"); return -1; } dltdata.ovaluebase[to_copy] = '\0'; memcpy(dltdata.ovaluebase, dltdata.ovalue, to_copy); break; } case 'e': { dltdata.evalue = optarg; break; } case 'b': { dltdata.bvalue = atoi(optarg); break; } case 'c': { dltdata.climit = convert_arg_to_byte_size(optarg); if (dltdata.climit < -1) { fprintf (stderr, "Invalid argument for option -c.\n"); /* unknown or wrong option used, show usage information and terminate */ usage(); return -1; } break; } case '?': { if ((optopt == 'o') || (optopt == 'f') || (optopt == 'c')) fprintf (stderr, "Option -%c requires an argument.\n", optopt); else if (isprint (optopt)) fprintf (stderr, "Unknown option `-%c'.\n", optopt); else fprintf (stderr, "Unknown option character `\\x%x'.\n", optopt); /* unknown or wrong option used, show usage information and terminate */ usage(); return -1; } default: { abort (); return -1; /*for parasoft */ } } /* Initialize DLT Client */ dlt_client_init(&dltclient, dltdata.vflag); /* Register callback to be called when message was received */ dlt_client_register_message_callback(dlt_receive_message_callback); /* Setup DLT Client structure */ dltclient.mode = dltdata.yflag; if (dltclient.mode == DLT_CLIENT_MODE_TCP) { for (index = optind; index < argc; index++) if (dlt_client_set_server_ip(&dltclient, argv[index]) == -1) { fprintf(stderr, "set server ip didn't succeed\n"); return -1; } if (dltclient.servIP == 0) { /* no hostname selected, show usage and terminate */ fprintf(stderr, "ERROR: No hostname selected\n"); usage(); dlt_client_cleanup(&dltclient, dltdata.vflag); return -1; } } else { for (index = optind; index < argc; index++) if (dlt_client_set_serial_device(&dltclient, argv[index]) == -1) { fprintf(stderr, "set serial device didn't succeed\n"); return -1; } if (dltclient.serialDevice == 0) { /* no serial device name selected, show usage and terminate */ fprintf(stderr, "ERROR: No serial device name specified\n"); usage(); return -1; } dlt_client_setbaudrate(&dltclient, dltdata.bvalue); } /* initialise structure to use DLT file */ dlt_file_init(&(dltdata.file), dltdata.vflag); /* first parse filter file if filter parameter is used */ dlt_filter_init(&(dltdata.filter), dltdata.vflag); if (dltdata.fvalue) { if (dlt_filter_load(&(dltdata.filter), dltdata.fvalue, dltdata.vflag) < DLT_RETURN_OK) { dlt_file_free(&(dltdata.file), dltdata.vflag); return -1; } dlt_file_set_filter(&(dltdata.file), &(dltdata.filter), dltdata.vflag); } /* open DLT output file */ if (dltdata.ovalue) { if (dltdata.climit > -1) { dlt_vlog(LOG_INFO, "Using file size limit of %" PRId64 "bytes\n", dltdata.climit); dltdata.ohandle = dlt_receive_open_output_file(&dltdata); } else { /* in case no limit for the output file is given, we simply overwrite any existing file */ dltdata.ohandle = open(dltdata.ovalue, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); } if (dltdata.ohandle == -1) { dlt_file_free(&(dltdata.file), dltdata.vflag); fprintf(stderr, "ERROR: Output file %s cannot be opened!\n", dltdata.ovalue); return -1; } } if (dltdata.evalue) dlt_set_id(dltdata.ecuid, dltdata.evalue); else dlt_set_id(dltdata.ecuid, DLT_RECEIVE_ECU_ID); /* Connect to TCP socket or open serial device */ if (dlt_client_connect(&dltclient, dltdata.vflag) != DLT_RETURN_ERROR) { /* Dlt Client Main Loop */ dlt_client_main_loop(&dltclient, &dltdata, dltdata.vflag); /* Dlt Client Cleanup */ dlt_client_cleanup(&dltclient, dltdata.vflag); } /* dlt-receive cleanup */ if (dltdata.ovalue) close(dltdata.ohandle); free(dltdata.ovaluebase); dlt_file_free(&(dltdata.file), dltdata.vflag); dlt_filter_free(&(dltdata.filter), dltdata.vflag); return 0; } int dlt_receive_message_callback(DltMessage *message, void *data) { DltReceiveData *dltdata; static char text[DLT_RECEIVE_BUFSIZE]; struct iovec iov[2]; int bytes_written; if ((message == 0) || (data == 0)) return -1; dltdata = (DltReceiveData *)data; /* prepare storage header */ if (DLT_IS_HTYP_WEID(message->standardheader->htyp)) dlt_set_storageheader(message->storageheader, message->headerextra.ecu); else dlt_set_storageheader(message->storageheader, dltdata->ecuid); if ((dltdata->fvalue == 0) || (dltdata->fvalue && (dlt_message_filter_check(message, &(dltdata->filter), dltdata->vflag) == DLT_RETURN_TRUE))) { /* if no filter set or filter is matching display message */ if (dltdata->xflag) { dlt_message_print_hex(message, text, DLT_RECEIVE_BUFSIZE, dltdata->vflag); } else if (dltdata->aflag) { dlt_message_header(message, text, DLT_RECEIVE_BUFSIZE, dltdata->vflag); printf("%s ", text); dlt_message_payload(message, text, DLT_RECEIVE_BUFSIZE, DLT_OUTPUT_ASCII, dltdata->vflag); printf("[%s]\n", text); } else if (dltdata->mflag) { dlt_message_print_mixed_plain(message, text, DLT_RECEIVE_BUFSIZE, dltdata->vflag); } else if (dltdata->sflag) { dlt_message_header(message, text, DLT_RECEIVE_BUFSIZE, dltdata->vflag); printf("%s \n", text); } /* if file output enabled write message */ if (dltdata->ovalue) { iov[0].iov_base = message->headerbuffer; iov[0].iov_len = message->headersize; iov[1].iov_base = message->databuffer; iov[1].iov_len = message->datasize; if (dltdata->climit > -1) { int bytes_to_write = message->headersize + message->datasize; if ((bytes_to_write + dltdata->totalbytes > dltdata->climit)) { dlt_receive_close_output_file(dltdata); if (dlt_receive_open_output_file(dltdata) < 0) { printf( "ERROR: dlt_receive_message_callback: Unable to open log when maximum filesize was reached!\n"); return -1; } dltdata->totalbytes = 0; } } bytes_written = writev(dltdata->ohandle, iov, 2); dltdata->totalbytes += bytes_written; if (0 > bytes_written) { printf("dlt_receive_message_callback: writev(dltdata->ohandle, iov, 2); returned an error!"); return -1; } } } return 0; } dlt-daemon-2.18.4/src/console/dlt-sortbytimestamp.c000066400000000000000000000264031353342203500222630ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2018, Codethink Ltd. * Copyright (C) 2011-2015, BMW AG * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author Jonathan Sambrook * * \copyright Copyright © 2018 Codethink Ltd. \n * Copyright © 2011-2015 BMW AG. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file dlt-sortbytimestamp.c */ /******************************************************************************* ** ** ** SRC-MODULE: dlt-sortbytimestamp.c ** ** ** ** TARGET : linux ** ** ** ** PROJECT : DLT ** ** ** ** AUTHOR : Jonathan Sambrook jonathasambrook@codethink.co.uk ** ** Alexander Wenzel Alexander.AW.Wenzel@bmw.de ** ** Markus Klein ** ** ** ** PURPOSE : ** ** ** ** REMARKS : ** ** ** ** PLATFORM DEPENDANT [yes/no]: yes ** ** ** ** TO BE CHANGED BY USER [yes/no]: no ** ** ** *******************************************************************************/ /******************************************************************************* ** Author Identity ** ******************************************************************************** ** ** ** Initials Name Company ** ** -------- ------------------------- ---------------------------------- ** ** aw Alexander Wenzel BMW ** ** js Jonathan Sambrook Codethink ** ** mk Markus Klein Fraunhofer ESK ** *******************************************************************************/ #include #include #include #include #include #include #include #include #include #include /* writev() */ #include "dlt_common.h" #define DLT_VERBUFSIZE 255 typedef struct sTimestampIndex { int num; uint32_t tmsp; } TimestampIndex; int verbosity = 0; /** * Print information, conditional upon requested verbosity level */ void verbose(int level, char *msg, ...) { if (level <= verbosity) { if (verbosity > 1) { /* timestamp */ time_t tnow = time((time_t *)0); if (tnow != -1) { char snow[50]; ctime_r(&tnow, snow); /* suppress newline char */ snow[strlen(snow) - 1] = 0; printf("%s: ", snow); } } int len = strlen(msg); va_list args; va_start (args, msg); vprintf(msg, args); /* lines without a terminal newline aren't guaranteed to be displayed */ if (msg[len - 1] != '\n') fflush(stdout); } } /** * Comparison function for use with qsort */ int compare_index_timestamps(const void *a, const void *b) { if (((TimestampIndex *)a)->tmsp > ((TimestampIndex *)b)->tmsp) return 1; else if (((TimestampIndex *)a)->tmsp == ((TimestampIndex *)b)->tmsp) return 0; return -1; } /** * Write the messages in the order specified by the given index */ void write_messages(int ohandle, DltFile *file, TimestampIndex *timestamps, int message_count) { struct iovec iov[2]; int bytes_written; verbose(1, "Writing %d messages\n", message_count); for (int i = 0; i < message_count; ++i) { if ((0 == i % 1001) || (i == message_count - 1)) verbose(2, "Writing message %d\r", i); dlt_file_message(file, timestamps[i].num, 0); iov[0].iov_base = file->msg.headerbuffer; iov[0].iov_len = file->msg.headersize; iov[1].iov_base = file->msg.databuffer; iov[1].iov_len = file->msg.datasize; bytes_written = writev(ohandle, iov, 2); if (0 > bytes_written) { printf("in main: writev(ohandle, iov, 2); returned an error!"); dlt_file_free(file, 0); exit (-1); } } verbose (2, "\n"); } /** * Print usage information of tool. */ void usage() { char version[DLT_VERBUFSIZE]; dlt_get_version(version, DLT_VERBUFSIZE); printf("Usage: dlt-sortbytimestamp [options] [commands] file_in file_out\n"); printf("Read DLT file, sort by timestamp and store the messages again.\n"); printf("Use filters to filter DLT messages.\n"); printf("Use range to cut DLT file. Indices are zero based.\n"); printf("%s \n", version); printf("Commands:\n"); printf(" -h Usage\n"); printf("Options:\n"); printf(" -v Verbosity. Multiple uses will effect an increase in loquacity\n"); printf(" -c Count number of messages\n"); printf(" -f filename Enable filtering of messages\n"); printf(" -b number First message in range to be handled (default: first message)\n"); printf(" -e number Last message in range to be handled (default: last message)\n"); } /** * Main function of tool. */ int main(int argc, char *argv[]) { int vflag = 0; int cflag = 0; char *fvalue = 0; char *bvalue = 0; char *evalue = 0; char *ivalue = 0; char *ovalue = 0; TimestampIndex *timestamp_index = 0; int32_t message_count = 0; int c; DltFile file; DltFilter filter; int ohandle = -1; int num, begin, end; opterr = 0; verbose(1, "Configuring\n"); while ((c = getopt (argc, argv, "vchf:b:e:")) != -1) switch (c) { case 'v': { verbosity += 1; break; } case 'c': { cflag = 1; break; } case 'h': { usage(); return -1; } case 'f': { fvalue = optarg; break; } case 'b': { bvalue = optarg; break; } case 'e': { evalue = optarg; break; } case '?': { if ((optopt == 'f') || (optopt == 'b') || (optopt == 'e')) fprintf (stderr, "Option -%c requires an argument.\n", optopt); else if (isprint (optopt)) fprintf (stderr, "Unknown option `-%c'.\n", optopt); else fprintf (stderr, "Unknown option character `\\x%x'.\n", optopt); /* unknown or wrong option used, show usage information and terminate */ usage(); return -1; } default: { abort(); return -1; /*for parasoft */ } } /* Don't use vflag on quietest levels */ if (verbosity > 2) vflag = 1; verbose (1, "Initializing\n"); /* initialise structure to use DLT file */ dlt_file_init(&file, vflag); /* first parse filter file if filter parameter is used */ if (fvalue) { if (bvalue || evalue) { fprintf(stderr, "ERROR: can't specify a range *and* filtering!\n"); dlt_file_free(&file, vflag); return -1; } if (dlt_filter_load(&filter, fvalue, vflag) < DLT_RETURN_OK) { dlt_file_free(&file, vflag); return -1; } dlt_file_set_filter(&file, &filter, vflag); } ivalue = argv[optind]; if (!ivalue) { dlt_file_free(&file, vflag); fprintf(stderr, "ERROR: Need an input file!\n"); return -1; } ovalue = argv[optind + 1]; if (ovalue) { ohandle = open(ovalue, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); /* mode: wb */ if (ohandle == -1) { dlt_file_free(&file, vflag); fprintf(stderr, "ERROR: Output file %s cannot be opened!\n", ovalue); return -1; } } else { dlt_file_free(&file, vflag); fprintf(stderr, "ERROR: Need an output file!\n"); return -1; } verbose(1, "Loading\n"); /* load, analyse data file and create index list */ if (dlt_file_open(&file, ivalue, vflag) >= DLT_RETURN_OK) { while (dlt_file_read(&file, vflag) >= DLT_RETURN_OK) {} } if (cflag) { if (fvalue) printf("Loaded %d messages, %d after filtering.\n", file.counter_total, file.counter); else printf("Loaded %d messages.\n", file.counter_total); } if (bvalue) begin = atoi(bvalue); else begin = 0; if (evalue) end = atoi(evalue); else end = file.counter - 1; if ((begin < 0) || (begin >= file.counter) || (begin > end)) { fprintf(stderr, "ERROR: Selected first message %d is out of range!\n", begin); return -1; } if (end >= file.counter) { fprintf(stderr, "ERROR: Selected end message %d is out of range!\n", end); return -1; } verbose(2, "Begin: %d End: %d Range: %d\n", begin, end, 1 + end - begin); verbose(1, "Allocating memory\n"); message_count = 1 + end - begin; timestamp_index = (TimestampIndex *)malloc(sizeof(TimestampIndex) * message_count); if (timestamp_index == 0) { fprintf(stderr, "ERROR: Failed to allocate memory for message index!\n"); dlt_file_free(&file, vflag); return -1; } verbose(1, "Filling %d entries\n", message_count); for (num = begin; num <= end; num++) { dlt_file_message(&file, num, vflag); timestamp_index[num - begin].num = num; timestamp_index[num - begin].tmsp = file.msg.headerextra.tmsp; } verbose(1, "Sorting\n"); qsort((void *)timestamp_index, message_count, sizeof(TimestampIndex), compare_index_timestamps); write_messages(ohandle, &file, timestamp_index, message_count); close(ohandle); verbose(1, "Tidying up.\n"); free(timestamp_index); dlt_file_free(&file, vflag); return 0; } dlt-daemon-2.18.4/src/console/filter.txt000066400000000000000000000000241353342203500201050ustar00rootroot00000000000000ABCD IJKL TEST LOG dlt-daemon-2.18.4/src/console/logstorage/000077500000000000000000000000001353342203500202315ustar00rootroot00000000000000dlt-daemon-2.18.4/src/console/logstorage/CMakeLists.txt000066400000000000000000000025521353342203500227750ustar00rootroot00000000000000####### # SPDX license identifier: MPL-2.0 # # Copyright (C) 2015, ADIT GmbH # # This file is part of GENIVI Project DLT - Diagnostic Log and Trace. # # This Source Code Form is subject to the terms of the # Mozilla Public License (MPL), v. 2.0. # If a copy of the MPL was not distributed with this file, # You can obtain one at http://mozilla.org/MPL/2.0/. # # For further information see http://www.genivi.org/. ####### add_definitions( -Werror ) set(dlt_logstorage_ctrl_SRCS dlt-logstorage-ctrl.c dlt-logstorage-common.c dlt-logstorage-list.c) if(WITH_DLT_LOGSTORAGE_CTRL_UDEV) set(dlt_logstorage_ctrl_SRCS ${dlt_logstorage_ctrl_SRCS} dlt-logstorage-udev.c) endif(WITH_DLT_LOGSTORAGE_CTRL_UDEV) if(WITH_SYSTEMD) set(dlt_logstorage_ctrl_SRCS ${dlt_logstorage_ctrl_SRCS} ${PROJECT_SOURCE_DIR}/systemd/3rdparty/sd-daemon.c) endif(WITH_SYSTEMD) add_executable(dlt-logstorage-ctrl ${dlt_logstorage_ctrl_SRCS} ${dlt_control_common_SRCS} ${dlt_most_SRCS}) set(DLT_LOGSTORAGE_LIBRARIES dlt-logstorage-ctrl dlt ${EXPAT_LIBRARIES}) if(WITH_DLT_LOGSTORAGE_CTRL_UDEV) set(DLT_LOGSTORAGE_LIBRARIES ${DLT_LOGSTORAGE_LIBRARIES} udev) endif(WITH_DLT_LOGSTORAGE_CTRL_UDEV) target_link_libraries(${DLT_LOGSTORAGE_LIBRARIES}) set_target_properties(dlt-logstorage-ctrl PROPERTIES LINKER_LANGUAGE C) install(TARGETS dlt-logstorage-ctrl RUNTIME DESTINATION bin COMPONENT base) dlt-daemon-2.18.4/src/console/logstorage/dlt-logstorage-common.c000066400000000000000000000222041353342203500246120ustar00rootroot00000000000000/** * Copyright (C) 2013 - 2015 Advanced Driver Information Technology. * This code is developed by Advanced Driver Information Technology. * Copyright of Advanced Driver Information Technology, Bosch and DENSO. * * This file is part of GENIVI Project Dlt - Diagnostic Log and Trace console apps. * * * \copyright * This Source Code Form is subject to the terms of the * Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with * this file, You can obtain one at http://mozilla.org/MPL/2.0/. * * * \author Syed Hameed ADIT 2013 - 2015 * \author Christoph Lipka ADIT 2015 * \author Frederic Berat ADIT 2015 * * \file dlt-logstorage-common.c * For further information see http://www.genivi.org/. */ /******************************************************************************* ** ** ** SRC-MODULE: dlt-logstorage-common.c ** ** ** ** TARGET : linux ** ** ** ** PROJECT : DLT ** ** ** ** AUTHOR : Christoph Lipka clipka@jp.adit-jv.com ** ** Frederic Berat fberat@de.adit-jv.com ** ** PURPOSE : ** ** ** ** REMARKS : Code extracted from dlt-control-common.c and reworked. ** ** ** ** PLATFORM DEPENDANT [yes/no]: yes ** ** ** ** TO BE CHANGED BY USER [yes/no]: no ** ** ** *******************************************************************************/ /******************************************************************************* ** Author Identity ** ******************************************************************************** ** ** ** Initials Name Company ** ** -------- ------------------------- ---------------------------------- ** ** cl Christoph Lipka ADIT ** ** fb Frederic Berat ADIT ** *******************************************************************************/ #define pr_fmt(fmt) "Logstorage common: "fmt #include #include #include #include #include #include #include #include #include #include "dlt_common.h" #include "dlt_protocol.h" #include "dlt_client.h" #include "dlt-control-common.h" #include "dlt-logstorage-common.h" #ifdef DLT_LOGSTORAGE_CTRL_UDEV_ENABLE # include "dlt-logstorage-udev.h" #endif #include "dlt-logstorage-prop.h" static struct LogstorageOptions { int event_type; /**< EVENT_UNMOUNTING/EVENT_MOUNTED */ char device_path[DLT_MOUNT_PATH_MAX]; /**< Default Mount path */ DltLogstorageHandler handler_type; /**< be controlled by udev or prop */ long timeout; /**< Default timeout */ } g_options = { .event_type = EVENT_MOUNTED, .handler_type = CTRL_NOHANDLER, }; DltLogstorageHandler get_handler_type(void) { return g_options.handler_type; } void set_handler_type(char *type) { g_options.handler_type = CTRL_UDEV; if (type && check_proprietary_handling(type)) g_options.handler_type = CTRL_PROPRIETARY; } int get_default_event_type(void) { return g_options.event_type; } void set_default_event_type(long type) { g_options.event_type = type; } char *get_default_path(void) { return g_options.device_path; } void set_default_path(char *path) { memset(g_options.device_path, 0, DLT_MOUNT_PATH_MAX); if (path != NULL) strncpy(g_options.device_path, path, DLT_MOUNT_PATH_MAX - 1); } /* Used by the handlers */ static DltLogstorageCtrl lctrl; DltLogstorageCtrl *get_logstorage_control(void) { return &lctrl; } void *dlt_logstorage_get_handler_cb(void) { return lctrl.callback; } int dlt_logstorage_get_handler_fd(void) { return lctrl.fd; } /** @brief Initialized the handler based on configuration * * @return 0 on success, -1 otherwise. */ int dlt_logstorage_init_handler(void) { switch (get_handler_type()) { case CTRL_PROPRIETARY: return dlt_logstorage_prop_init(); case CTRL_UDEV: default: #ifdef DLT_LOGSTORAGE_CTRL_UDEV_ENABLE return dlt_logstorage_udev_init(); #else return -1; #endif } } /** @brief Clean-up the handler based on configuration * * @return 0 on success, -1 otherwise. */ int dlt_logstorage_deinit_handler(void) { switch (get_handler_type()) { case CTRL_PROPRIETARY: return dlt_logstorage_prop_deinit(); case CTRL_UDEV: default: #ifdef DLT_LOGSTORAGE_CTRL_UDEV_ENABLE return dlt_logstorage_udev_deinit(); #else return -1; #endif } } /** @brief Search for config file in given mount point * * The file is searched at the top directory. The function exits once it * founds it. * * @param mnt_point The mount point to check * * @return 1 if the file is found, 0 otherwise. */ int dlt_logstorage_check_config_file(char *mnt_point) { struct dirent **files; int n; int i = 0; int ret = 0; if ((mnt_point == NULL) || (mnt_point[0] == '\0')) { pr_error("Mount point missing.\n"); return ret; } pr_verbose("Now scanning %s\n", mnt_point); n = scandir(mnt_point, &files, NULL, alphasort); if (n <= 0) { pr_error("Cannot read mounted directory\n"); return ret; } do { pr_verbose("Checking %s.\n", files[i]->d_name); if (strncmp(files[i]->d_name, CONF_NAME, strlen(CONF_NAME)) == 0) { /* We found it ! */ pr_verbose("File found.\n"); ret = 1; break; } } while (++i < n); for (i = 0; i < n; i++) free(files[i]); free(files); return ret; } /** @brief Check if given mount point is writable * * @param mnt_point The mount point to check * * @return 1 if the file is writable, 0 otherwise. */ int dlt_logstorage_check_directory_permission(char *mnt_point) { if (mnt_point == NULL) { pr_error("Given mount point is NULL\n"); return 0; } if (access(mnt_point, W_OK) == 0) return 1; return 0; } /** @brief Prepares the body of the message to be send to DLT * * @param body A pointer to the MsgBody structure pointer * @param conn_type The type of the event (Mounted/Unmounting) * @param path The mount point path. * * @return The body once built or NULL. */ static DltControlMsgBody *prepare_message_body(DltControlMsgBody **body, int conn_type, char *path) { DltServiceOfflineLogstorage *serv = NULL; if (path == NULL) { pr_error("Mount path is uninitialized.\n"); return NULL; } pr_verbose("Sending event %d for %s.\n", conn_type, path); *body = calloc(1, sizeof(DltControlMsgBody)); if (!*body) { pr_error("Not able to allocate memory for body.\n"); return *body; } (*body)->data = calloc(1, sizeof(DltServiceOfflineLogstorage)); if (!(*body)->data) { free(*body); *body = NULL; pr_error("Not able to allocate memory for body data.\n"); return NULL; } (*body)->size = sizeof(DltServiceOfflineLogstorage); serv = (DltServiceOfflineLogstorage *)(*body)->data; serv->service_id = DLT_SERVICE_ID_OFFLINE_LOGSTORAGE; serv->connection_type = conn_type; /* mount_point is DLT_MOUNT_PATH_MAX + 1 long, * and the memory is already zeroed. */ strncpy(serv->mount_point, path, DLT_MOUNT_PATH_MAX - 1); pr_verbose("Body is now ready.\n"); return *body; } /** @brief Send a logstorage event to DLT * * @param type The type of the event (Mounted/Unmounting) * @param mount_point The mount point for this event * * @return 0 On success, -1 otherwise. */ int dlt_logstorage_send_event(int type, char *mount_point) { int ret = 0; DltControlMsgBody *msg_body = NULL; /* mount_point is checked against NULL in the preparation */ if (!prepare_message_body(&msg_body, type, mount_point)) { pr_error("Data for Dlt Message body is NULL\n"); return -1; } ret = dlt_control_send_message(msg_body, get_timeout()); free(msg_body->data); free(msg_body); return ret; } dlt-daemon-2.18.4/src/console/logstorage/dlt-logstorage-common.h000066400000000000000000000051061353342203500246210ustar00rootroot00000000000000/** * Copyright (C) 2013 - 2015 Advanced Driver Information Technology. * This code is developed by Advanced Driver Information Technology. * Copyright of Advanced Driver Information Technology, Bosch and DENSO. * * This file is part of GENIVI Project Dlt - Diagnostic Log and Trace console apps. * * * \copyright * This Source Code Form is subject to the terms of the * Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with * this file, You can obtain one at http://mozilla.org/MPL/2.0/. * * * \author Syed Hameed ADIT 2013 - 2015 * \author Christoph Lipka ADIT 2015 * \author Frederic Berat ADIT 2015 * * \file dlt-logstorage-common.h * For further information see http://www.genivi.org/. */ #ifndef _DLT_LOGSTORAGE_COMMON_H_ #define _DLT_LOGSTORAGE_COMMON_H_ #define CONF_NAME "dlt_logstorage.conf" #define EVENT_UNMOUNTING 0 #define EVENT_MOUNTED 1 #define EVENT_SYNC_CACHE 2 typedef enum { CTRL_NOHANDLER = 0, /**< one shot application */ CTRL_UDEV, /**< Handles udev events */ CTRL_PROPRIETARY /**< Handles proprietary event */ } DltLogstorageHandler; DltLogstorageHandler get_handler_type(void); void set_handler_type(char *); char *get_default_path(void); void set_default_path(char *); int get_default_event_type(void); void set_default_event_type(long type); typedef struct { int fd; int (*callback)(void); /* callback for event handling */ void *prvt; /* Private data */ } DltLogstorageCtrl; /* Get a reference to the logstorage control instance */ DltLogstorageCtrl *get_logstorage_control(void); void *dlt_logstorage_get_handler_cb(void); int dlt_logstorage_get_handler_fd(void); int dlt_logstorage_init_handler(void); int dlt_logstorage_deinit_handler(void); /** * Send an event to the dlt daemon * * @param type Event type (EVENT_UNMOUNTING/EVENT_MOUNTED) * @param mount_point The mount point path concerned by this event * * @return 0 on success, -1 on error */ int dlt_logstorage_send_event(int, char *); /** @brief Search for config file in given mount point * * The file is searched at the top directory. The function exits once it * founds it. * * @param mnt_point The mount point to check * * @return 1 if the file is found, 0 otherwise. */ int dlt_logstorage_check_config_file(char *); /** @brief Check if given mount point is writable * * @param mnt_point The mount point to check * * @return 1 if the file is writable, 0 otherwise. */ int dlt_logstorage_check_directory_permission(char *mnt_point); #endif dlt-daemon-2.18.4/src/console/logstorage/dlt-logstorage-ctrl.c000066400000000000000000000431251353342203500242730ustar00rootroot00000000000000/** * Copyright (C) 2013 - 2015 Advanced Driver Information Technology. * This code is developed by Advanced Driver Information Technology. * Copyright of Advanced Driver Information Technology, Bosch and DENSO. * * This file is part of GENIVI Project Dlt - Diagnostic Log and Trace console apps. * * * \copyright * This Source Code Form is subject to the terms of the * Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with * this file, You can obtain one at http://mozilla.org/MPL/2.0/. * * * \author Syed Hameed ADIT 2013 - 2015 * \author Christoph Lipka ADIT 2015 * \author Frederic Berat ADIT 2015 * * \file dlt-logstorage-ctrl.c * For further information see http://www.genivi.org/. */ /******************************************************************************* ** ** ** SRC-MODULE: dlt-logstorage-ctrl.c ** ** ** ** TARGET : linux ** ** ** ** PROJECT : DLT ** ** ** ** AUTHOR : Syed Hameed shameed@jp.adit-jv.com ** ** Christoph Lipka clipka@jp.adit-jv.com ** ** AnithaAmmaji.baggam@in.bosch.com ** ** Frederic Berat fberat@de.adit-jv.com ** ** PURPOSE : ** ** ** ** REMARKS : ** ** ** ** PLATFORM DEPENDANT [yes/no]: yes ** ** ** ** TO BE CHANGED BY USER [yes/no]: no ** ** ** *******************************************************************************/ /******************************************************************************* ** Author Identity ** ******************************************************************************** ** Initials Name Company ** ** -------- ------------------------- ---------------------------------- ** ** sh Syed Hameed ADIT ** ** cl Christoph Lipka ADIT ** ** BA Anitha BA ADIT ** ** fb Frederic Berat ADIT ** *******************************************************************************/ #define pr_fmt(fmt) "Logstorage control: "fmt #include #include #include #include #include #include #include #include #if defined(__linux__) # include "sd-daemon.h" #endif #include "dlt_protocol.h" #include "dlt_client.h" #include "dlt-control-common.h" #include "dlt-logstorage-common.h" #include "dlt-logstorage-ctrl.h" #define POLL_TIME_OUT 500 #define EV_MASK_REJECTED (POLLERR | POLLHUP | POLLNVAL) #define DLT_LOGSTORAGE_CTRL_EXIT 1 static int must_exit; struct dlt_event { struct pollfd pfd; void *func; }; /** @brief Triggers the application exit * * The application will exit on next poll timeout. */ void dlt_logstorage_exit(void) { must_exit = DLT_LOGSTORAGE_CTRL_EXIT; } /** @brief Check if the application must exit * * The application will exit on next poll timeout. */ int dlt_logstorage_must_exit(void) { return must_exit; } /** @brief Signal handler. * * Triggers the exit of the application in case of specific signals * * @param signo The value of the signal received. */ static void catch_signal(int signo) { if (signo) { pr_error("Signal %d received, exiting.", signo); dlt_logstorage_exit(); } } /** @brief Install a handler for some signals * * Handler are installed on exit related signals. That allows to exit from * the main loop gracefully. */ static void install_signal_handler(void) { int signals[] = { SIGINT, SIGQUIT, SIGTERM, 0 }; unsigned int i; struct sigaction sa; pr_verbose("Installing signal handler.\n"); /* install a signal handler for the above listed signals */ for (i = 0; signals[i]; i++) { memset(&sa, 0, sizeof(sa)); sa.sa_handler = catch_signal; if (sigaction(signals[i], &sa, NULL) < 0) pr_error("Failed to install signal %u handler. Error: %s\n", signals[i], strerror(errno)); } } #define MAX_RESPONSE_LENGTH 32 /** @brief Analyze the daemon answer to a request * * This function checks whether if the daemon answered positively to * the request or not. * * @param data The textual answer * @param payload The answer payload * @param len The answer payload length * @return 0 on success, -1 otherwise. */ static int analyze_response(char *data, void *payload, int len) { int ret = -1; char resp_ok[MAX_RESPONSE_LENGTH] = { 0 }; char resp_warning[MAX_RESPONSE_LENGTH] = { 0 }; char resp_perm_denied[MAX_RESPONSE_LENGTH] = { 0 }; if ((data == NULL) || (payload == NULL)) return -1; /* satisfy compiler */ (void)payload; (void)len; snprintf(resp_ok, MAX_RESPONSE_LENGTH, "service(%u), ok", DLT_SERVICE_ID_OFFLINE_LOGSTORAGE); snprintf(resp_warning, MAX_RESPONSE_LENGTH, "service(%u), warning", DLT_SERVICE_ID_OFFLINE_LOGSTORAGE); snprintf(resp_perm_denied, MAX_RESPONSE_LENGTH, "service(%u), perm_denied", DLT_SERVICE_ID_OFFLINE_LOGSTORAGE); if (strncmp(data, resp_ok, strlen(resp_ok)) == 0) ret = 0; if (strncmp(data, resp_warning, strlen(resp_warning)) == 0) { pr_error("Warning:Some filter configurations are ignored due to configuration issues \n"); ret = 0; } if (strncmp(data, resp_perm_denied, strlen(resp_perm_denied)) == 0) { pr_error("Warning: Permission denied.\n"); ret = 0; } pr_verbose("Response received: '%s'\n", data); pr_verbose("Response expected: '%s'\n", resp_ok); return ret; } /** @brief Add a new event to watch * * This function could be exported to be used by udev/prop so that they can * register several events. * * @param ev_hdl The structure containing the file descriptors * @param fd The file descriptor to watch * @param cb The callback to be called on event. * * @return 0 on success, -1 if the parameters are invalid. */ static int dlt_logstorage_ctrl_add_event(struct dlt_event *ev_hdl, int fd, void *cb) { if ((fd < 0) || !cb || !ev_hdl) { pr_error("Wrong parameter to add event (%d %p)\n", fd, cb); return -1; } pr_verbose("Setting up the event handler with (%d, %p).\n", fd, cb); ev_hdl->func = cb; ev_hdl->pfd.fd = fd; return 0; } /** @brief Main execution loop * * Waits on events, and executes the callbacks retrieved * back from the event structure. * * @return 0 on success, -1 otherwise. */ static int dlt_logstorage_ctrl_execute_event_loop(struct dlt_event *ev) { int ret = 0; int (*callback)() = ev->func; ret = poll(&ev->pfd, 1, POLL_TIME_OUT); if (ret <= 0) { if (errno == EINTR) ret = 0; if (ret < 0) pr_error("poll error: %s\n", strerror(errno)); return ret; } if (ev->pfd.revents == 0) return 0; if (ev->pfd.events & EV_MASK_REJECTED) { pr_error("Error while polling. Event received: 0x%x\n", ev->pfd.events); /* We only support one event producer. * Error means that this producer died. */ pr_error("Now closing fd and exiting.\n"); close(ev->pfd.fd); ev->pfd.fd = -1; dlt_logstorage_exit(); return -1; } if (!callback) { pr_error("Callback not found, exiting.\n"); dlt_logstorage_exit(); return -1; } pr_verbose("Got new event, calling %p.\n", callback); if (callback() < 0) { pr_error("Error while calling the callback, exiting.\n"); dlt_logstorage_exit(); return -1; } return 0; } /** @brief Start event loop and receive messages from DLT. * * The function will first install the signal handler, * then create the poll instance, initialize the communication controller, * initialize the event handler and finally start the polling. * * @return 0 on success, -1 on error */ static int dlt_logstorage_ctrl_setup_event_loop(void) { int ret = 0; struct dlt_event ev_hdl = { .pfd = { .fd = -1, .events = POLLIN } }; install_signal_handler(); pr_verbose("Creating poll instance.\n"); /* Initializing the communication with the daemon */ while (dlt_control_init(analyze_response, get_ecuid(), get_verbosity()) && !dlt_logstorage_must_exit()) { pr_error("Failed to initialize connection with the daemon.\n"); pr_error("Retrying to connect in %lds.\n", get_timeout()); sleep(get_timeout()); } if (dlt_logstorage_must_exit()) { pr_verbose("Exiting.\n"); return 0; } pr_verbose("Initializing event generator.\n"); if (dlt_logstorage_init_handler() < 0) { pr_error("Failed to initialize handler.\n"); dlt_control_deinit(); return -1; } if (dlt_logstorage_ctrl_add_event(&ev_hdl, dlt_logstorage_get_handler_fd(), dlt_logstorage_get_handler_cb()) < 0) { pr_error("add_event error: %s\n", strerror(errno)); dlt_logstorage_exit(); } while (!dlt_logstorage_must_exit() && (ret == 0)) ret = dlt_logstorage_ctrl_execute_event_loop(&ev_hdl); /* Clean up */ dlt_logstorage_deinit_handler(); dlt_control_deinit(); return ret; } /** @brief Send a single command to DLT daemon and wait for response * * @return 0 on success, -1 otherwise. */ static int dlt_logstorage_ctrl_single_request() { int ret = 0; /* in case sync all caches, an empty path is given */ if (get_default_event_type() != EVENT_SYNC_CACHE) { /* Check if a 'CONF_NAME' file is present at the given path */ if (!dlt_logstorage_check_config_file(get_default_path())) { pr_error("No '%s' file available at: %s\n", CONF_NAME, get_default_path()); return -1; } if (!dlt_logstorage_check_directory_permission(get_default_path())) { pr_error("'%s' is not writable\n", get_default_path()); return -1; } } /* Initializing the communication with the daemon */ while (dlt_control_init(analyze_response, get_ecuid(), get_verbosity()) && !dlt_logstorage_must_exit()) { pr_error("Failed to initialize connection with the daemon.\n"); pr_error("Retrying to connect in %lds.\n", get_timeout()); sleep(get_timeout()); } pr_verbose("event type is [%d]\t device path is [%s]\n", get_default_event_type(), get_default_path()); ret = dlt_logstorage_send_event(get_default_event_type(), get_default_path()); dlt_control_deinit(); return ret; } /** @brief Print out the application help */ static void usage(void) { printf("Usage: dlt-logstorage-ctrl [options]\n"); printf("Send a trigger to DLT daemon to connect/disconnect" "a certain logstorage device\n"); printf("\n"); printf("Options:\n"); printf(" -c --command Connection type: connect = 1, disconnect = 0\n"); printf(" -d[prop] --daemonize=prop Run as daemon: prop = use proprietary handler\n"); printf(" 'prop' may be replaced by any meaningful word\n"); printf(" If prop is not specified, udev will be used\n"); printf(" -e --ecuid Set ECU ID (Default: %s)\n", DLT_CTRL_DEFAULT_ECUID); printf(" -h --help Usage\n"); printf(" -p --path Mount point path\n"); printf(" -s[path] --snapshot=path Sync Logstorage cache\n"); printf(" Don't use -s together with -d and -c\n"); printf(" -t Specify connection timeout (Default: %ds)\n", DLT_CTRL_TIMEOUT); printf(" -v --verbose Set verbose flag (Default:%d)\n", get_verbosity()); } static struct option long_options[] = { { "command", required_argument, 0, 'c' }, { "daemonize", optional_argument, 0, 'd' }, { "ecuid", required_argument, 0, 'e' }, { "help", no_argument, 0, 'h' }, { "path", required_argument, 0, 'p' }, { "snapshot", optional_argument, 0, 's' }, { "timeout", required_argument, 0, 't' }, { "verbose", no_argument, 0, 'v' }, { 0, 0, 0, 0 } }; /** @brief Parses the application arguments * * The arguments are parsed and saved in static structure for future use. * * @param argc The amount of arguments * @param argv The table of arguments * * @return 0 on success, -1 otherwise */ static int parse_args(int argc, char *argv[]) { int c = -1; int long_index = 0; while ((c = getopt_long(argc, argv, ":s::t:he:p:d::c:v", long_options, &long_index)) != -1) switch (c) { case 's': set_default_event_type(EVENT_SYNC_CACHE); if ((optarg != NULL) && (strlen(optarg) >= DLT_MOUNT_PATH_MAX)) { pr_error("Mount path '%s' too long\n", optarg); return -1; } set_default_path(optarg); break; case 't': set_timeout(strtol(optarg, NULL, 10)); break; case 'h': usage(); return -1; case 'e': set_ecuid(optarg); break; case 'd': pr_verbose("Choosing handler.\n"); set_handler_type(optarg); pr_verbose("Handler chosen: %d.\n", get_handler_type()); break; case 'p': if (strlen(optarg) >= DLT_MOUNT_PATH_MAX) { pr_error("Mount path '%s' too long\n", optarg); return -1; } set_default_path(optarg); break; case 'c': set_default_event_type(strtol(optarg, NULL, 10)); break; case 'v': set_verbosity(1); pr_verbose("Now in verbose mode.\n"); break; case ':': pr_error("Option -%c requires an argument.\n", optopt); usage(); return -1; case '?': if (isprint(optopt)) pr_error("Unknown option -%c.\n", optopt); else pr_error("Unknown option character \\x%x.\n", optopt); usage(); return -1; default: pr_error("Try %s -h for more information.\n", argv[0]); return -1; } if ((get_default_event_type() == EVENT_SYNC_CACHE) && (get_handler_type() != CTRL_NOHANDLER)) { pr_error("Sync caches not available in daemon mode\n"); return -1; } return 0; } #if !defined(DLT_SYSTEMD_ENABLE) int sd_notify(int unset_environment, const char *state) { /* Satisfy Compiler for warnings */ (void)unset_environment; (void)state; return 0; } #endif /** @brief Entry point * * Execute the argument parser and call the main feature accordingly. * * @param argc The amount of arguments * @param argv The table of arguments * * @return 0 on success, -1 otherwise */ int main(int argc, char *argv[]) { int ret = 0; set_ecuid(NULL); set_timeout(DLT_CTRL_TIMEOUT); /* Get command line arguments */ if (parse_args(argc, argv) != 0) return -1; /* all parameter valid, start communication with daemon or setup * communication with control daemon */ if (get_handler_type() == CTRL_NOHANDLER) { pr_verbose("One shot.\n"); ret = dlt_logstorage_ctrl_single_request(); if (ret < 0) pr_error("Message failed to be send. Please check DLT config.\n"); } else { pr_verbose("Entering in daemon mode.\n"); /* Let's daemonize */ if (sd_notify(0, "READY=1") <= 0) { pr_verbose("SD notify failed, manually daemonizing.\n"); /* No message can be sent or Systemd is not available. * Daemonizing manually. */ if (daemon(1, 1)) { pr_error("Failed to daemonize: %s\n", strerror(errno)); return EXIT_FAILURE; } } pr_verbose("Executing the event loop\n"); ret = dlt_logstorage_ctrl_setup_event_loop(); } pr_verbose("Exiting.\n"); return ret; } dlt-daemon-2.18.4/src/console/logstorage/dlt-logstorage-ctrl.h000066400000000000000000000016161353342203500242770ustar00rootroot00000000000000/** * Copyright (C) 2013 - 2015 Advanced Driver Information Technology. * This code is developed by Advanced Driver Information Technology. * Copyright of Advanced Driver Information Technology, Bosch and DENSO. * * This file is part of GENIVI Project Dlt - Diagnostic Log and Trace console apps. * * * \copyright * This Source Code Form is subject to the terms of the * Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with * this file, You can obtain one at http://mozilla.org/MPL/2.0/. * * * \author Syed Hameed ADIT 2013 - 2015 * \author Christoph Lipka ADIT 2015 * * \file dlt-logstorage-ctrl.h * For further information see http://www.genivi.org/. */ #ifndef _DLT_LOGSTORAGE_CONTROL_H_ #define _DLT_LOGSTORAGE_CONTROL_H_ /* Triggers the exit at the end of the event */ void dlt_logstorage_exit(void); #endif dlt-daemon-2.18.4/src/console/logstorage/dlt-logstorage-list.c000066400000000000000000000164111353342203500243000ustar00rootroot00000000000000/** * Copyright (C) 2013 - 2015 Advanced Driver Information Technology. * This code is developed by Advanced Driver Information Technology. * Copyright of Advanced Driver Information Technology, Bosch and DENSO. * * This file is part of GENIVI Project Dlt - Diagnostic Log and Trace console apps. * * * \copyright * This Source Code Form is subject to the terms of the * Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with * this file, You can obtain one at http://mozilla.org/MPL/2.0/. * * * \author Anitha.BA ADIT 2015 * \author Christoph Lipka ADIT 2015 * \author Frederic Berat ADIT 2015 * * \file dlt-logstorage-list.c * For further information see http://www.genivi.org/. */ /******************************************************************************* ** ** ** SRC-MODULE: dlt-logstorage-list.c ** ** ** ** TARGET : linux ** ** ** ** PROJECT : DLT ** ** ** ** AUTHOR : Christoph Lipka clipka@jp.adit-jv.com ** ** Anitha.B.A anithaammaji.baggam@in.bosch.com ** ** Frederic Berat fberat@de.adit-jv.com ** ** ** ** PURPOSE : linked list implementation for storing the device info ** ** ** ** REMARKS : ** ** ** ** PLATFORM DEPENDANT [yes/no]: yes ** ** ** ** TO BE CHANGED BY USER [yes/no]: no ** ** ** *******************************************************************************/ /******************************************************************************* ** Author Identity ** ******************************************************************************** ** ** ** Initials Name Company ** ** -------- ------------------------- ---------------------------------- ** ** BA Anitha ADIT ** ** cl Christoph Lipka ADIT ** ** fb Frederic Berat ADIT ** *******************************************************************************/ #define pr_fmt(fmt) "Log storage list: "fmt #include #include #include #include #include "dlt_common.h" #include "dlt-control-common.h" #include "dlt-logstorage-common.h" static struct LogstorageDeviceInfo { char *dev_node; /**< The device node */ char *mnt_point; /**< Mount point for this device */ struct LogstorageDeviceInfo *prev; /**< Previous element of the list */ struct LogstorageDeviceInfo *next; /**< Next element of the list */ } *g_info; /** @brief Prints the device list in verbose mode * * This can be used to debug the behavior. * Therefore, it's only available in verbose mode. */ void print_list() { struct LogstorageDeviceInfo *ptr = g_info; pr_verbose(" -------Device list-------\n"); while (ptr != NULL) { pr_verbose("%p:\t[%s][%s] \n", ptr, ptr->dev_node, ptr->mnt_point); ptr = ptr->next; } pr_verbose(" -------Device list end-------\n\n"); return; } /** @brief Find element in the list based on device node * * Allows to check whether a device is already in the list or * to find out the one to be removed. * * @param node The device node to look for * * @return The element of the list found, NULL either. */ static struct LogstorageDeviceInfo *logstorage_find_dev_info(const char *node) { struct LogstorageDeviceInfo *ptr = g_info; if (!node) return NULL; pr_verbose("Looking for %s.\n", node); while (ptr != NULL) { if (strncmp(ptr->dev_node, node, DLT_MOUNT_PATH_MAX) == 0) { pr_verbose("%s found in %p.\n", node, ptr); break; } else { ptr = ptr->next; } } return ptr; } /** @brief Add new device in the list * * The device is only added if a configuration file has been found and * if it's not already in the list. * * @param node The device node to add * @param path The corresponding mount point path * * @return 0 on success, -1 in case of error. */ int logstorage_store_dev_info(const char *node, const char *path) { struct LogstorageDeviceInfo *ptr = NULL; size_t path_len = 0; if ((node == NULL) || (path == NULL)) { pr_error("Invalid input\n"); return -1; } if (logstorage_find_dev_info(node)) { pr_verbose("%s already in list.\n", node); print_list(); return 0; } ptr = calloc(1, sizeof(struct LogstorageDeviceInfo)); if (ptr == NULL) { pr_error("Node creation failed\n"); return -1; } ptr->dev_node = strdup(node); path_len = strlen(path); if (path_len > DLT_MOUNT_PATH_MAX) path_len = (size_t)DLT_MOUNT_PATH_MAX; ptr->mnt_point = (char *)calloc(1, path_len + 1); if (ptr->mnt_point == NULL) { pr_error("memory allocation failed for mnt_point\n"); return -1; } ptr->mnt_point[path_len] = '\0'; memcpy(ptr->mnt_point, path, path_len); /* Put it on head */ ptr->next = g_info; if (g_info) g_info->prev = ptr; g_info = ptr; pr_verbose("%s added to list.\n", node); print_list(); return 0; } /** @brief Remove a device from the list * * If the device is removed from the list, the mount point * pointer is given back to the caller. That means that * he has to free it. * * @param node The device node to be removed * * @return the mount point if the node is found, NULL either. */ char *logstorage_delete_dev_info(const char *node) { struct LogstorageDeviceInfo *del = NULL; char *ret = NULL; del = logstorage_find_dev_info(node); if (del == NULL) { pr_verbose("%s not found in list.\n", node); print_list(); return ret; } /* Has to be freed by the caller */ ret = del->mnt_point; if (del->prev) del->prev->next = del->next; if (del->next) del->next->prev = del->prev; if (del == g_info) g_info = g_info->next; free(del->dev_node); free(del); pr_verbose("%s removed from list.\n", node); print_list(); return ret; } dlt-daemon-2.18.4/src/console/logstorage/dlt-logstorage-list.h000066400000000000000000000021571353342203500243070ustar00rootroot00000000000000/** * Copyright (C) 2013 - 2015 Advanced Driver Information Technology. * This code is developed by Advanced Driver Information Technology. * Copyright of Advanced Driver Information Technology, Bosch and DENSO. * * This file is part of GENIVI Project Dlt - Diagnostic Log and Trace console apps. * * * \copyright * This Source Code Form is subject to the terms of the * Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with * this file, You can obtain one at http://mozilla.org/MPL/2.0/. * * * \author Christoph Lipka clipka@jp.adit-jv.com * \author Anitha BA ADIT 2015 * \author Frederic Berat ADIT 2015 * * \file dlt-logstorage-list.h * For further information see http://www.genivi.org/. */ #ifndef _DLT_LOGSTORAGE_LIST_H_ #define _DLT_LOGSTORAGE_LIST_H_ /* Return 0 it the node as been added (or is already present) */ int logstorage_store_dev_info(const char *node, const char *path); /* Returns the mount point if node has been found and deleted. NULL either */ char *logstorage_delete_dev_info(const char *node); #endif dlt-daemon-2.18.4/src/console/logstorage/dlt-logstorage-prop.h000066400000000000000000000033231353342203500243100ustar00rootroot00000000000000/** * Copyright (C) 2013 - 2015 Advanced Driver Information Technology. * This code is developed by Advanced Driver Information Technology. * Copyright of Advanced Driver Information Technology, Bosch and DENSO. * * This file is part of GENIVI Project Dlt - Diagnostic Log and Trace console apps. * * \copyright * This Source Code Form is subject to the terms of the * Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with * this file, You can obtain one at http://mozilla.org/MPL/2.0/. * * \author Christoph Lipka ADIT 2015 * \author Frederic Berat ADIT 2015 * * \file dlt-logstorage-udev.h * For further information see http://www.genivi.org/. */ #ifndef _DLT_LOGSTORAGE_PROP_H_ #define _DLT_LOGSTORAGE_PROP_H_ #ifndef HAS_PROPRIETARY_LOGSTORAGE /** @brief Initialize proprietary connection * * @return 0 */ static inline int dlt_logstorage_prop_init(void) { return 0; } /** @brief Clean-up proprietary connection * * @return 0 */ static inline int dlt_logstorage_prop_deinit(void) { return 0; } /** @brief Check whether user wants to use proprietary handler * * @return 0 */ static inline int check_proprietary_handling(char *type) { (void)type; return 0; } #else /** * Initialize proprietary connection * * @return 0 on success, -1 on error */ int dlt_logstorage_prop_init(void); /** * Clean-up proprietary connection * * @return 0 on success, -1 on error */ int dlt_logstorage_prop_deinit(void); /** * Check whether user wants to use proprietary event handler * * @return 1 if yes, 0 either. */ int check_proprietary_handling(char *); #endif /* HAS_PROPRIETARY_LOGSTORAGE */ #endif /* _DLT_LOGSTORAGE_PROP_H_ */ dlt-daemon-2.18.4/src/console/logstorage/dlt-logstorage-udev.c000066400000000000000000000320401353342203500242640ustar00rootroot00000000000000/** * Copyright (C) 2013 - 2015 Advanced Driver Information Technology. * This code is developed by Advanced Driver Information Technology. * Copyright of Advanced Driver Information Technology, Bosch and DENSO. * * This file is part of GENIVI Project Dlt - Diagnostic Log and Trace console apps. * * * \copyright * This Source Code Form is subject to the terms of the * Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with * this file, You can obtain one at http://mozilla.org/MPL/2.0/. * * * \author Christoph Lipka ADIT 2015 * \author Frederic Berat ADIT 2015 * * \file dlt-logstorage-udev.c * For further information see http://www.genivi.org/. */ /******************************************************************************* ** ** ** SRC-MODULE: dlt-logstorage-udev.c ** ** ** ** TARGET : linux ** ** ** ** PROJECT : DLT ** ** ** ** AUTHOR : Christoph Lipka clipka@jp.adit-jv.com ** ** Frederic Berat fberat@de.adit-jv.com ** ** ** ** PURPOSE : For udev-based handling of any device ** ** ** ** REMARKS : ** ** ** ** PLATFORM DEPENDANT [yes/no]: yes ** ** ** ** TO BE CHANGED BY USER [yes/no]: no ** ** ** *******************************************************************************/ /******************************************************************************* ** Author Identity ** ******************************************************************************** ** ** ** Initials Name Company ** ** -------- ------------------------- ---------------------------------- ** ** cl Christoph Lipka ADIT ** ** fb Frederic Berat ADIT ** *******************************************************************************/ #define pr_fmt(fmt) "Udev control: "fmt #include #include #include #include #include #include #include #include #include "dlt-control-common.h" #include "dlt-logstorage-common.h" #include "dlt-logstorage-list.h" #include "dlt-logstorage-udev.h" typedef struct { struct udev *udev; /**< Udev instance */ struct udev_monitor *mon; /**< Udev monitor instance */ } LogstorageCtrlUdev; /** @brief Get mount point of a device node * * This function search for the mount point in /proc/mounts * based on the device node. * * @param dev_node Device node as string * * @return mount path or NULL on error */ static char *dlt_logstorage_udev_get_mount_point(char *dev_node) { struct mntent *ent; FILE *f; char *mnt_point = NULL; if (dev_node == NULL) return NULL; f = setmntent("/proc/mounts", "r"); if (f == NULL) { pr_error("Cannot read /proc/mounts\n"); return NULL; } while (NULL != (ent = getmntent(f))) if (strncmp(ent->mnt_fsname, dev_node, strlen(ent->mnt_fsname)) == 0) { mnt_point = strdup(ent->mnt_dir); if (mnt_point == NULL) { pr_error("Cannot duplicate string.\n"); return NULL; } /* Remounting rw */ if (strlen(mnt_point)) /* capabilities needed. Thus we don't really car on failure. * Therefor we can ignore the return value. */ (void)mount(NULL, mnt_point, NULL, MS_REMOUNT, ent->mnt_opts); break; } endmntent(f); return mnt_point; } /** @brief Check if the daemon needs to be notified by the event * * On mount event: * If the device mount point contains the DLT configuration file, * the function will then send a message to the daemon. * On Unmounting event: * Check if the device was on the list, remove it and send the message * to the daemon. * * @param event The kind of event happening * @param part The device partition to be checked * * @return 0 on success, -1 if an error occured. */ static int check_mountpoint_from_partition(int event, struct udev_device *part) { int logstorage_dev = 0; char *mnt_point = NULL; char *dev_node = NULL; int ret = 0; if (!part) { pr_verbose("No partition structure given.\n"); return -1; } pr_verbose("Checking mount point.\n"); if (!udev_device_get_devnode(part)) { pr_verbose("Skipping as no devnode.\n"); return 0; } dev_node = strdup(udev_device_get_devnode(part)); if (dev_node == NULL) { pr_error("Cannot allocate memory for to store string\n"); return -1; } if (event == EVENT_MOUNTED) { mnt_point = dlt_logstorage_udev_get_mount_point(dev_node); logstorage_dev = dlt_logstorage_check_config_file(mnt_point); if (logstorage_dev) { /* Configuration file available, add node to internal list */ logstorage_store_dev_info(dev_node, mnt_point); } else { free(mnt_point); mnt_point = NULL; } } else { /* remove device information */ mnt_point = logstorage_delete_dev_info(dev_node); } if (mnt_point) { ret = dlt_logstorage_send_event(event, mnt_point); if (ret) pr_error("Can't send event for %s to DLT.\n", mnt_point); } free(dev_node); free(mnt_point); return 0; } /** @brief Handles the udev events * * On event, it finds the corresponding action, and calls * check_mountpoint_from_partition with the corresponding event. * * @return 0 on success, -1 on error. */ static int logstorage_udev_udevd_callback(void) { const char *action; int ret = 0; DltLogstorageCtrl *lctrl = get_logstorage_control(); LogstorageCtrlUdev *prvt = NULL; struct udev_device *partition = NULL; struct timespec ts; if (!lctrl) { pr_error("Not able to get logstorage control instance.\n"); return -1; } prvt = (LogstorageCtrlUdev *)lctrl->prvt; if ((!prvt) || (!prvt->mon)) { pr_error("Not able to get private data.\n"); return -1; } partition = udev_monitor_receive_device(prvt->mon); if (!partition) { pr_error("Not able to get partition.\n"); return -1; } action = udev_device_get_action(partition); if (!action) { pr_error("Not able to get action.\n"); udev_device_unref(partition); return -1; } pr_verbose("%s action received from udev for %s.\n", action, udev_device_get_devnode(partition)); if (strncmp(action, "add", sizeof("add")) == 0) { /*TODO: This can be replaced by polling on /proc/mount. * we could get event on modification, and keep track on a list * of mounted devices. New devices could be check that way. * That also would solve the unmount event issue. * Then, udev is only interesting to simplify the check on new devices, * and/or for hot unplug (without unmount). */ ts.tv_sec = 0; ts.tv_nsec = 500 * NANOSEC_PER_MILLISEC; nanosleep(&ts, NULL); ret = check_mountpoint_from_partition(EVENT_MOUNTED, partition); } else if (strncmp(action, "remove", sizeof("remove")) == 0) { ret = check_mountpoint_from_partition(EVENT_UNMOUNTING, partition); } udev_device_unref(partition); return ret; } /** @brief Check all partitions on the system to find configuration file * * The function looks for block devices that are of "partition" type. * Then, it gets the node, and call check_mountpoint_from_partition with it. * * @param udev The udev device used to find all the nodes * * @return 0 on success, -1 otherwise. */ static int dlt_logstorage_udev_check_mounted(struct udev *udev) { if (udev == NULL) { pr_error("%s: udev structure is NULL\n", __func__); return -1; } /* Create a list of the devices in the 'partition' subsystem. */ struct udev_enumerate *enumerate = udev_enumerate_new(udev); struct udev_list_entry *devices = NULL; struct udev_list_entry *dev_list_entry = NULL; if (!enumerate) { pr_error("Can't enumerate devices.\n"); return -1; } udev_enumerate_add_match_subsystem(enumerate, "block"); udev_enumerate_add_match_property(enumerate, "DEVTYPE", "partition"); udev_enumerate_scan_devices(enumerate); devices = udev_enumerate_get_list_entry(enumerate); /* For each list entry, get the corresponding device */ udev_list_entry_foreach(dev_list_entry, devices) { const char *path; struct udev_device *partition = NULL; /* Get the filename of the /sys entry for the device * and create a udev_device object representing it */ path = udev_list_entry_get_name(dev_list_entry); partition = udev_device_new_from_syspath(udev, path); if (!partition) continue; pr_verbose("Found device %s %s %s.\n", path, udev_device_get_devnode(partition), udev_device_get_devtype(partition)); /* Check the device and clean-up */ check_mountpoint_from_partition(EVENT_MOUNTED, partition); udev_device_unref(partition); } /* Free the enumerator object */ udev_enumerate_unref(enumerate); return 0; } /** @brief Clean-up the udev data * * That will destroy all the private data. * * @return 0 on success, -1 otherwise. */ int dlt_logstorage_udev_deinit(void) { DltLogstorageCtrl *lctrl = get_logstorage_control(); LogstorageCtrlUdev *prvt = NULL; if (!lctrl) return -1; prvt = (LogstorageCtrlUdev *)lctrl->prvt; if (prvt == NULL) return -1; if (prvt->mon) udev_monitor_unref(prvt->mon); if (prvt->udev) udev_unref(prvt->udev); free(prvt); lctrl->prvt = NULL; return 0; } /** @brief Initialize the private data * * That function will create the udev device and monitor. * * @return 0 on success, -1 otherwise. */ int dlt_logstorage_udev_init(void) { int ret = 0; DltLogstorageCtrl *lctrl = get_logstorage_control(); LogstorageCtrlUdev *prvt = NULL; pr_verbose("Initializing.\n"); if (!lctrl) { pr_error("Not able to get logstorage control instance.\n"); return -1; } lctrl->prvt = calloc(1, sizeof(LogstorageCtrlUdev)); if (!lctrl->prvt) { pr_error("No memory to allocate private data.\n"); return -1; } prvt = (LogstorageCtrlUdev *)lctrl->prvt; /* Initialize udev object */ prvt->udev = udev_new(); if (!prvt->udev) { pr_error("Cannot initialize udev object\n"); dlt_logstorage_udev_deinit(); return -1; } /* setup udev monitor which will report events when * devices attached to the system change. Events include * "add", "remove", "change", etc */ prvt->mon = udev_monitor_new_from_netlink(prvt->udev, "udev"); if (!prvt->mon) { pr_error("Cannot initialize udev monitor\n"); dlt_logstorage_udev_deinit(); return -1; } ret = udev_monitor_filter_add_match_subsystem_devtype(prvt->mon, "block", NULL); if (ret) { pr_error("Cannot attach filter to monitor: %s.\n", strerror(-ret)); dlt_logstorage_udev_deinit(); return -1; } ret = udev_monitor_enable_receiving(prvt->mon); if (ret < 0) { pr_error("Cannot start receiving: %s.\n", strerror(-ret)); dlt_logstorage_udev_deinit(); return -1; } /* get file descriptor */ lctrl->fd = udev_monitor_get_fd(prvt->mon); /* set callback function */ lctrl->callback = &logstorage_udev_udevd_callback; /* check if there is something already mounted */ return dlt_logstorage_udev_check_mounted(prvt->udev); } dlt-daemon-2.18.4/src/console/logstorage/dlt-logstorage-udev.h000066400000000000000000000020221353342203500242660ustar00rootroot00000000000000/** * Copyright (C) 2013 - 2015 Advanced Driver Information Technology. * This code is developed by Advanced Driver Information Technology. * Copyright of Advanced Driver Information Technology, Bosch and DENSO. * * This file is part of GENIVI Project Dlt - Diagnostic Log and Trace console apps. * * \copyright * This Source Code Form is subject to the terms of the * Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with * this file, You can obtain one at http://mozilla.org/MPL/2.0/. * * \author Christoph Lipka ADIT 2015 * \author Frederic Berat ADIT 2015 * * \file dlt-logstorage-udev.h * For further information see http://www.genivi.org/. */ #ifndef _DLT_LOGSTORAGE_UDEV_H_ #define _DLT_LOGSTORAGE_UDEV_H_ /** * Initialize udev connection * * @return 0 on success, -1 on error */ int dlt_logstorage_udev_init(void); /** * Clean-up udev connection * * @return 0 on success, -1 on error */ int dlt_logstorage_udev_deinit(void); #endif dlt-daemon-2.18.4/src/core_dump_handler/000077500000000000000000000000001353342203500200735ustar00rootroot00000000000000dlt-daemon-2.18.4/src/core_dump_handler/50-coredump.conf.cmake000066400000000000000000000007551353342203500240700ustar00rootroot00000000000000####### # SPDX license identifier: MPL-2.0 # # Copyright (C) 2011-2015, BMW AG # # This file is part of GENIVI Project DLT - Diagnostic Log and Trace. # # This Source Code Form is subject to the terms of the # Mozilla Public License (MPL), v. 2.0. # If a copy of the MPL was not distributed with this file, # You can obtain one at http://mozilla.org/MPL/2.0/. # # For further information see http://www.genivi.org/. ####### kernel.core_pattern=|@CMAKE_INSTALL_PREFIX@/bin/dlt-cdh %t %p %s %e dlt-daemon-2.18.4/src/core_dump_handler/CMakeLists.txt000066400000000000000000000030101353342203500226250ustar00rootroot00000000000000####### # SPDX license identifier: MPL-2.0 # # Copyright (C) 2011-2015, BMW AG # # This file is part of GENIVI Project DLT - Diagnostic Log and Trace. # # This Source Code Form is subject to the terms of the # Mozilla Public License (MPL), v. 2.0. # If a copy of the MPL was not distributed with this file, # You can obtain one at http://mozilla.org/MPL/2.0/. # # For further information see http://www.genivi.org/. ####### if(WITH_DLT_COREDUMPHANDLER) set(PLATFORM_DIR ${PROJECT_SOURCE_DIR}/src/core_dump_handler/${TARGET_CPU_NAME}) set(dlt_cdh_SRCS dlt_cdh.c dlt_cdh_context.c dlt_cdh_coredump.c ${PLATFORM_DIR}/dlt_cdh_cpuinfo.c dlt_cdh_crashid.c dlt_cdh_streamer.c) set(COREDUMP_CONF_DIR "/usr/lib/sysctl.d/") #add_definitions( -fno-strict-aliasing ) if(WITH_CITYHASH) set(CITYHASH_DIR ${PROJECT_SOURCE_DIR}/src/core_dump_handler/cityhash_c) add_definitions(-DHAS_CITYHASH_C) set(dlt_cdh_SRCS ${CITYHASH_DIR}/city_c.c ${dlt_cdh_SRCS}) endif(WITH_CITYHASH) add_executable(dlt-cdh ${dlt_cdh_SRCS}) target_link_libraries(dlt-cdh z) set_target_properties(dlt-cdh PROPERTIES LINKER_LANGUAGE C) configure_file(${PROJECT_SOURCE_DIR}/src/core_dump_handler/50-coredump.conf.cmake ${PROJECT_BINARY_DIR}/core_dump_handler/50-coredump.conf) install(TARGETS dlt-cdh RUNTIME DESTINATION bin COMPONENT base) install(FILES ${PROJECT_BINARY_DIR}/core_dump_handler/50-coredump.conf DESTINATION ${COREDUMP_CONF_DIR}) endif(WITH_DLT_COREDUMPHANDLER) dlt-daemon-2.18.4/src/core_dump_handler/README000066400000000000000000000016101353342203500207510ustar00rootroot00000000000000To build use cmake with -DWITH_DLT_COREDUMPHANDLER=ON -DTARGET_CPU_NAME={i686|x86_64} Temporary replacement of default crash handler: If you don't want to make the change persistent just become root (not sudo) and execute the following ("man core" for details): echo "|/usr/local/bin/dlt-cdh %t %p %s %e" > /proc/sys/kernel/core_pattern (replace /usr/local/bin with the path dlt-cdh has been installed to) Persistent replacement of default crash handler: We have to generate "50-coredump.conf" in "/usr/lib/sysctl.d/" which is done automatically by "make install". Unfortunately at least on Fedora systems we also have to remove abrt with "yum remove abrtd*" because this ruthlessly overwrites our change at every boot. This must be done when installing this stuff as Debian package. To enable the core dump handler without rebooting we have to execute "sysctl -p /usr/lib/sysctl.d/50-coredump.conf" dlt-daemon-2.18.4/src/core_dump_handler/cityhash_c/000077500000000000000000000000001353342203500222115ustar00rootroot00000000000000dlt-daemon-2.18.4/src/core_dump_handler/cityhash_c/COPYING000066400000000000000000000021251353342203500232440ustar00rootroot00000000000000// Copyright (c) 2011 Google, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE.dlt-daemon-2.18.4/src/core_dump_handler/cityhash_c/README000066400000000000000000000165401353342203500230770ustar00rootroot00000000000000CityHash, a family of hash functions for strings. Introduction ============ CityHash provides hash functions for strings. The functions mix the input bits thoroughly but are not suitable for cryptography. See "Hash Quality," below, for details on how CityHash was tested and so on. We provide reference implementations in C++, with a friendly MIT license. CityHash32() returns a 32-bit hash. CityHash64() and similar return a 64-bit hash. CityHash128() and similar return a 128-bit hash and are tuned for strings of at least a few hundred bytes. Depending on your compiler and hardware, it's likely faster than CityHash64() on sufficiently long strings. It's slower than necessary on shorter strings, but we expect that case to be relatively unimportant. CityHashCrc128() and similar are variants of CityHash128() that depend on _mm_crc32_u64(), an intrinsic that compiles to a CRC32 instruction on some CPUs. However, none of the functions we provide are CRCs. CityHashCrc256() is a variant of CityHashCrc128() that also depends on _mm_crc32_u64(). It returns a 256-bit hash. All members of the CityHash family were designed with heavy reliance on previous work by Austin Appleby, Bob Jenkins, and others. For example, CityHash32 has many similarities with Murmur3a. Performance on long strings: 64-bit CPUs ======================================== We are most excited by the performance of CityHash64() and its variants on short strings, but long strings are interesting as well. CityHash is intended to be fast, under the constraint that it hash very well. For CPUs with the CRC32 instruction, CRC is speedy, but CRC wasn't designed as a hash function and shouldn't be used as one. CityHashCrc128() is not a CRC, but it uses the CRC32 machinery. On a single core of a 2.67GHz Intel Xeon X5550, CityHashCrc256 peaks at about 5 to 5.5 bytes/cycle. The other CityHashCrc functions are wrappers around CityHashCrc256 and should have similar performance on long strings. (CityHashCrc256 in v1.0.3 was even faster, but we decided it wasn't as thorough as it should be.) CityHash128 peaks at about 4.3 bytes/cycle. The fastest Murmur variant on that hardware, Murmur3F, peaks at about 2.4 bytes/cycle. We expect the peak speed of CityHash128 to dominate CityHash64, which is aimed more toward short strings or use in hash tables. For long strings, a new function by Bob Jenkins, SpookyHash, is just slightly slower than CityHash128 on Intel x86-64 CPUs, but noticeably faster on AMD x86-64 CPUs. For hashing long strings on AMD CPUs and/or CPUs without the CRC instruction, SpookyHash may be just as good or better than any of the CityHash variants. Performance on short strings: 64-bit CPUs ========================================= For short strings, e.g., most hash table keys, CityHash64 is faster than CityHash128, and probably faster than all the aforementioned functions, depending on the mix of string lengths. Here are a few results from that same hardware, where we (unrealistically) tested a single string length over and over again: Hash Results ------------------------------------------------------------------------------ CityHash64 v1.0.3 7ns for 1 byte, or 6ns for 8 bytes, or 9ns for 64 bytes Murmur2 (64-bit) 6ns for 1 byte, or 6ns for 8 bytes, or 15ns for 64 bytes Murmur3F 14ns for 1 byte, or 15ns for 8 bytes, or 23ns for 64 bytes We don't have CityHash64 benchmarks results for v1.1, but we expect the numbers to be similar. Performance: 32-bit CPUs ======================== CityHash32 is the newest variant of CityHash. It is intended for 32-bit hardware in general but has been mostly tested on x86. Our benchmarks suggest that Murmur3 is the nearest competitor to CityHash32 on x86. We don't know of anything faster that has comparable quality. The speed rankings in our testing: CityHash32 > Murmur3f > Murmur3a (for long strings), and CityHash32 > Murmur3a > Murmur3f (for short strings). Installation ============ We provide reference implementations of several CityHash functions, written in C++. The build system is based on autoconf. It defaults the C++ compiler flags to "-g -O2", which is probably slower than -O3 if you are using gcc. YMMV. On systems with gcc, we generally recommend: ./configure make all check CXXFLAGS="-g -O3" sudo make install Or, if your system has the CRC32 instruction, and you want to build everything: ./configure --enable-sse4.2 make all check CXXFLAGS="-g -O3 -msse4.2" sudo make install Note that our build system doesn't try to determine the appropriate compiler flag for enabling SSE4.2. For gcc it is "-msse4.2". The --enable-sse4.2 flag to the configure script controls whether citycrc.h is installed when you "make install." In general, picking the right compiler flags can be tricky, and may depend on your compiler, your hardware, and even how you plan to use the library. For generic information about how to configure this software, please try: ./configure --help Failing that, please work from city.cc and city*.h, as they contain all the necessary code. Usage ===== The above installation instructions will produce a single library. It will contain CityHash32(), CityHash64(), and CityHash128(), and their variants, and possibly CityHashCrc128(), CityHashCrc128WithSeed(), and CityHashCrc256(). The functions with Crc in the name are declared in citycrc.h; the rest are declared in city.h. Limitations =========== 1) CityHash32 is intended for little-endian 32-bit code, and everything else in the current version of CityHash is intended for little-endian 64-bit CPUs. All functions that don't use the CRC32 instruction should work in little-endian 32-bit or 64-bit code. CityHash should work on big-endian CPUs as well, but we haven't tested that very thoroughly yet. 2) CityHash is fairly complex. As a result of its complexity, it may not perform as expected on some compilers. For example, preliminary reports suggest that some Microsoft compilers compile CityHash to assembly that's 10-20% slower than it could be. Hash Quality ============ We like to test hash functions with SMHasher, among other things. SMHasher isn't perfect, but it seems to find almost any significant flaw. SMHasher is available at http://code.google.com/p/smhasher/ SMHasher is designed to pass a 32-bit seed to the hash functions it tests. No CityHash function is designed to work that way, so we adapt as follows: For our functions that accept a seed, we use the given seed directly (padded with zeroes); for our functions that don't accept a seed, we hash the concatenation of the given seed and the input string. The CityHash functions have the following flaws according to SMHasher: (1) CityHash64: none (2) CityHash64WithSeed: none (3) CityHash64WithSeeds: did not test (4) CityHash128: none (5) CityHash128WithSeed: none (6) CityHashCrc128: none (7) CityHashCrc128WithSeed: none (8) CityHashCrc256: none (9) CityHash32: none Some minor flaws in 32-bit and 64-bit functions are harmless, as we expect the primary use of these functions will be in hash tables. We may have gone slightly overboard in trying to please SMHasher and other similar tests, but we don't want anyone to choose a different hash function because of some minor issue reported by a quality test. For more information ==================== http://code.google.com/p/cityhash/ cityhash-discuss@googlegroups.com Please feel free to send us comments, questions, bug reports, or patches.dlt-daemon-2.18.4/src/core_dump_handler/cityhash_c/city-test.cc000066400000000000000000003053041353342203500244520ustar00rootroot00000000000000// Copyright (c) 2011 Google, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #include #include #include #include "city_c.h" #ifdef __SSE4_2__ #include "citycrc_c.h" #endif using std::cout; using std::cerr; using std::hex; static const uint64 k0 = 0xc3a5c85c97cb3127ULL; static const uint64 kSeed0 = 1234567; static const uint64 kSeed1 = k0; static const uint128 kSeed128 = {kSeed0, kSeed1}; static const int kDataSize = 1 << 20; static const int kTestSize = 300; static char data[kDataSize]; static int errors = 0; // global error count // Initialize data to pseudorandom values. void setup() { uint64 a = 9; uint64 b = 777; for (int i = 0; i < kDataSize; i++) { a = (a ^ (a >> 41)) * k0 + b; b = (b ^ (b >> 41)) * k0 + i; uint8 u = (uint8)(b >> 37); memcpy(data + i, &u, 1); // uint8 -> char } } #if 1 #define C(y) 0x ## y ## ULL static const uint64 testdata[kTestSize][15] = { {C(9ae16a3b2f90404f), C(75106db890237a4a), C(3feac5f636039766), C(3df09dfc64c09a2b), C(3cb540c392e51e29), C(6b56343feac0663), C(5b7bc50fd8e8ad92), C(3df09dfc64c09a2b), C(3cb540c392e51e29), C(6b56343feac0663), C(5b7bc50fd8e8ad92), C(889f555a0f5b2dc0), C(7767800902c8a8ce), C(bcd2a808f4cb4a44), C(e9024dba8f94f2f3)}, {C(75e9dee28ded761d), C(931992c1b14334c5), C(245eeb25ba2c172e), C(1290f0e8a5caa74d), C(ca4c6bf7583f5cda), C(e1d60d51632c536d), C(cbc54a1db641910a), C(1290f0e8a5caa74d), C(ca4c6bf7583f5cda), C(e1d60d51632c536d), C(cbc54a1db641910a), C(9866d68d17c2c08e), C(8d84ba63eb4d020a), C(df0ad99c78cbce44), C(7c98593ef62573ed)}, {C(75de892fdc5ba914), C(f89832e71f764c86), C(39a82df1f278a297), C(b4af8ae673acb930), C(992b7acb203d8885), C(57b533f3f8b94d50), C(bbb69298a5dcf1a1), C(b4af8ae673acb930), C(992b7acb203d8885), C(57b533f3f8b94d50), C(bbb69298a5dcf1a1), C(433495196af9ac4f), C(53445c0896ae1fe6), C(f7b939315f6fb56f), C(ac1b05e5a2e0335e)}, {C(69cfe9fca1cc683a), C(e65f2a81e19b8067), C(20575ea6370a9d14), C(8f52532fc6f005b7), C(4ebe60df371ec129), C(c6ef8a7f8deb8116), C(83df17e3c9bb9a67), C(8f52532fc6f005b7), C(4ebe60df371ec129), C(c6ef8a7f8deb8116), C(83df17e3c9bb9a67), C(6a0aaf51016e19cd), C(fb0d1e89f39dbf6a), C(c73095102872943a), C(405ea97456c28a75)}, {C(675b04c582a34966), C(53624b5ef8cd4f45), C(c412e0931ac8c9b1), C(798637e677c65a3), C(83e3b06adc4cd3ff), C(f3e76e8a7135852f), C(111e66cfbb05366d), C(798637e677c65a3), C(83e3b06adc4cd3ff), C(f3e76e8a7135852f), C(111e66cfbb05366d), C(29c4f84aa48e8682), C(b77a8685750c94d0), C(7cab65571969123f), C(fb1dbd79f68a8519)}, {C(46fa817397ea8b68), C(cc960c1c15ce2d20), C(e5f9f947bafb9e79), C(b342cdf0d7ac4b2a), C(66914d44b373b232), C(261194e76cb43966), C(45a0010190365048), C(b342cdf0d7ac4b2a), C(66914d44b373b232), C(261194e76cb43966), C(45a0010190365048), C(e2586947ca8eac83), C(6650daf2d9677cdc), C(2f9533d8f4951a9), C(a5bdc0f3edc4bd7b)}, {C(406e959cdffadec7), C(e80dc125dca28ed1), C(e5beb146d4b79a21), C(e66d5c1bb441541a), C(d14961bc1fd265a2), C(e4cc669d4fc0577f), C(abf4a51e36da2702), C(e66d5c1bb441541a), C(d14961bc1fd265a2), C(e4cc669d4fc0577f), C(abf4a51e36da2702), C(21236d12df338f75), C(54b8c4a5ad2ae4a4), C(202d50ef9c2d4465), C(5ecc6a128e51a797)}, {C(46663908b4169b95), C(4e7e90b5c426bf1d), C(dc660b58daaf8b2c), C(b298265ebd1bd55f), C(4a5f6838b55c0b08), C(fc003c97aa05d397), C(2fb5adad3380c3bc), C(b298265ebd1bd55f), C(4a5f6838b55c0b08), C(fc003c97aa05d397), C(2fb5adad3380c3bc), C(c46fd01d253b4a0b), C(4c799235c2a33188), C(7e21bc57487a11bf), C(e1392bb1994bd4f2)}, {C(f214b86cffeab596), C(5fccb0b132da564f), C(86e7aa8b4154b883), C(763529c8d4189ea8), C(860d77e7fef74ca3), C(3b1ba41191219b6b), C(722b25dfa6d0a04b), C(763529c8d4189ea8), C(860d77e7fef74ca3), C(3b1ba41191219b6b), C(722b25dfa6d0a04b), C(5f7b463094e22a91), C(75d6f57376b31bd7), C(d253c7f89efec8e6), C(efe56ac880a2b8a3)}, {C(eba670441d1a4f7d), C(eb6b272502d975fa), C(69f8d424d50c083e), C(313d49cb51b8cd2c), C(6e982d8b4658654a), C(dd59629a17e5492d), C(81cb23bdab95e30e), C(313d49cb51b8cd2c), C(6e982d8b4658654a), C(dd59629a17e5492d), C(81cb23bdab95e30e), C(1e6c3e6c454c774f), C(177655172666d5ea), C(9cc67e0d38d80886), C(36a2d64d7bc58d22)}, {C(172c17ff21dbf88d), C(1f5104e320f0c815), C(1e34e9f1fa63bcef), C(3506ae8fae368d2a), C(59fa2b2de5306203), C(67d1119dcfa6007e), C(1f7190c648ad9aef), C(3506ae8fae368d2a), C(59fa2b2de5306203), C(67d1119dcfa6007e), C(1f7190c648ad9aef), C(7e8b1e689137b637), C(cbe373368a31db3c), C(dbc79d82cd49c671), C(641399520c452c99)}, {C(5a0838df8a019b8c), C(73fc859b4952923), C(45e39daf153491bd), C(a9b91459a5fada46), C(de0fbf8800a2da3), C(21800e4b5af9dedb), C(517c3726ae0dbae7), C(a9b91459a5fada46), C(de0fbf8800a2da3), C(21800e4b5af9dedb), C(517c3726ae0dbae7), C(1ccffbd74acf9d66), C(cbb08cf95e7eda99), C(61444f09e2a29587), C(35c0d15745f96455)}, {C(8f42b1fbb2fc0302), C(5ae31626076ab6ca), C(b87f0cb67cb75d28), C(2498586ac2e1fab2), C(e683f9cbea22809a), C(a9728d0b2bbe377c), C(46baf5cae53dc39a), C(2498586ac2e1fab2), C(e683f9cbea22809a), C(a9728d0b2bbe377c), C(46baf5cae53dc39a), C(806f4352c99229e), C(d4643728fc71754a), C(998c1647976bc893), C(d8094fdc2d6bb032)}, {C(72085e82d70dcea9), C(32f502c43349ba16), C(5ebc98c3645a018f), C(c7fa762238fd90ac), C(8d03b5652d615677), C(a3f5226e51d42217), C(46d5010a7cae8c1e), C(c7fa762238fd90ac), C(8d03b5652d615677), C(a3f5226e51d42217), C(46d5010a7cae8c1e), C(4293122580db7f5f), C(3df6042f39c6d487), C(439124809cf5c90e), C(90b704e4f71d0ccf)}, {C(32b75fc2223b5032), C(246fff80eb230868), C(a6fdbc82c9aeecc0), C(c089498074167021), C(ab094a9f9ab81c23), C(4facf3d9466bcb03), C(57aa9c67938cf3eb), C(c089498074167021), C(ab094a9f9ab81c23), C(4facf3d9466bcb03), C(57aa9c67938cf3eb), C(79a769ca1c762117), C(9c8dee60337f87a8), C(dabf1b96535a3abb), C(f87e9fbb590ba446)}, {C(e1dd010487d2d647), C(12352858295d2167), C(acc5e9b6f6b02dbb), C(1c66ceea473413df), C(dc3f70a124b25a40), C(66a6dfe54c441cd8), C(b436dabdaaa37121), C(1c66ceea473413df), C(dc3f70a124b25a40), C(66a6dfe54c441cd8), C(b436dabdaaa37121), C(6d95aa6890f51674), C(42c6c0fc7ab3c107), C(83b9dfe082e76140), C(939cdbd3614d6416)}, {C(2994f9245194a7e2), C(b7cd7249d6db6c0c), C(2170a7d119c5c6c3), C(8505c996b70ee9fc), C(b92bba6b5d778eb7), C(4db4c57f3a7a4aee), C(3cfd441cb222d06f), C(8505c996b70ee9fc), C(b92bba6b5d778eb7), C(4db4c57f3a7a4aee), C(3cfd441cb222d06f), C(4d940313c96ac6bd), C(43762837c9ffac4b), C(480fcf58920722e3), C(4bbd1e1a1d06752f)}, {C(32e2ed6fa03e5b22), C(58baf09d7c71c62b), C(a9c599f3f8f50b5b), C(1660a2c4972d0fa1), C(1a1538d6b50a57c), C(8a5362485bbc9363), C(e8eec3c84fd9f2f8), C(1660a2c4972d0fa1), C(1a1538d6b50a57c), C(8a5362485bbc9363), C(e8eec3c84fd9f2f8), C(2562514461d373da), C(33857675fed52b4), C(e58d2a17057f1943), C(fe7d3f30820e4925)}, {C(37a72b6e89410c9f), C(139fec53b78cee23), C(4fccd8f0da7575c3), C(3a5f04166518ac75), C(f49afe05a44fc090), C(cb01b4713cfda4bd), C(9027bd37ffc0a5de), C(3a5f04166518ac75), C(f49afe05a44fc090), C(cb01b4713cfda4bd), C(9027bd37ffc0a5de), C(e15144d3ad46ec1b), C(736fd99679a5ae78), C(b3d7ed9ed0ddfe57), C(cef60639457867d7)}, {C(10836563cb8ff3a1), C(d36f67e2dfc085f7), C(edc1bb6a3dcba8df), C(bd4f3a0566df3bed), C(81fc8230c163dcbe), C(4168bc8417a8281b), C(7100c9459827c6a6), C(bd4f3a0566df3bed), C(81fc8230c163dcbe), C(4168bc8417a8281b), C(7100c9459827c6a6), C(21cad59eaf79e72f), C(61c8af6fb71469f3), C(b0dfc42ce4f578b), C(33ea34ccea305d4e)}, {C(4dabcb5c1d382e5c), C(9a868c608088b7a4), C(7b2b6c389b943be5), C(c914b925ab69fda0), C(6bafe864647c94d7), C(7a48682dd4afa22), C(40fe01210176ba10), C(c914b925ab69fda0), C(6bafe864647c94d7), C(7a48682dd4afa22), C(40fe01210176ba10), C(88dd28f33ec31388), C(c6db60abf1d45381), C(7b94c447298824d5), C(6b2a5e05ad0b9fc0)}, {C(296afb509046d945), C(c38fe9eb796bd4be), C(d7b17535df110279), C(dd2482b87d1ade07), C(662785d2e3e78ddf), C(eae39994375181bb), C(9994500c077ee1db), C(dd2482b87d1ade07), C(662785d2e3e78ddf), C(eae39994375181bb), C(9994500c077ee1db), C(a275489f8c6bb289), C(30695ea31df1a369), C(1aeeb31802d701b5), C(7799d5a6d5632838)}, {C(f7c0257efde772ea), C(af6af9977ecf7bff), C(1cdff4bd07e8d973), C(fab1f4acd2cd4ab4), C(b4e19ba52b566bd), C(7f1db45725fe2881), C(70276ff8763f8396), C(fab1f4acd2cd4ab4), C(b4e19ba52b566bd), C(7f1db45725fe2881), C(70276ff8763f8396), C(1b0f2b546dddd16b), C(aa066984b5fd5144), C(7c3f9386c596a5a8), C(e5befdb24b665d5f)}, {C(61e021c8da344ba1), C(cf9c720676244755), C(354ffa8e9d3601f6), C(44e40a03093fbd92), C(bda9481cc5b93cae), C(986b589cbc0cf617), C(210f59f074044831), C(44e40a03093fbd92), C(bda9481cc5b93cae), C(986b589cbc0cf617), C(210f59f074044831), C(ac32cbbb6f50245a), C(afa6f712efb22075), C(47289f7af581719f), C(31b6e75d3aa0e54b)}, {C(c0a86ed83908560b), C(440c8b6f97bd1749), C(a99bf2891726ea93), C(ac0c0b84df66df9d), C(3ee2337b437eb264), C(8a341daed9a25f98), C(cc665499aa38c78c), C(ac0c0b84df66df9d), C(3ee2337b437eb264), C(8a341daed9a25f98), C(cc665499aa38c78c), C(af7275299d79a727), C(874fa8434b45d0e), C(ca7b67388950dd33), C(2db5cd3675ec58f7)}, {C(35c9cf87e4accbf3), C(2267eb4d2191b2a3), C(80217695666b2c9), C(cd43a24abbaae6d), C(a88abf0ea1b2a8ff), C(e297ff01427e2a9d), C(935d545695b2b41d), C(cd43a24abbaae6d), C(a88abf0ea1b2a8ff), C(e297ff01427e2a9d), C(935d545695b2b41d), C(6accd4dbcb52e849), C(261295acb662fd49), C(f9d91f1ac269a8a2), C(5e45f39df355e395)}, {C(e74c366b3091e275), C(522e657c5da94b06), C(ca9afa806f1a54ac), C(b545042f67929471), C(90d10e75ed0e75d8), C(3ea60f8f158df77e), C(8863eff3c2d670b7), C(b545042f67929471), C(90d10e75ed0e75d8), C(3ea60f8f158df77e), C(8863eff3c2d670b7), C(5799296e97f144a7), C(1d6e517c12a88271), C(da579e9e1add90ef), C(942fb4cdbc3a4da)}, {C(a3f2ca45089ad1a6), C(13f6270fe56fbce4), C(1f93a534bf03e705), C(aaea14288ae2d90c), C(1be3cd51ef0f15e8), C(e8b47c84d5a4aac1), C(297d27d55b766782), C(aaea14288ae2d90c), C(1be3cd51ef0f15e8), C(e8b47c84d5a4aac1), C(297d27d55b766782), C(e922d1d8bb2afd0), C(b4481c4fa2e7d8d5), C(691e21538af794d5), C(9bd4fb0a53962a72)}, {C(e5181466d8e60e26), C(cf31f3a2d582c4f3), C(d9cee87cb71f75b2), C(4750ca6050a2d726), C(d6e6dd8940256849), C(f3b3749fdab75b0), C(c55d8a0f85ba0ccf), C(4750ca6050a2d726), C(d6e6dd8940256849), C(f3b3749fdab75b0), C(c55d8a0f85ba0ccf), C(47f134f9544c6da6), C(e1cdd9cb74ad764), C(3ce2d096d844941e), C(321fe62f608d2d4e)}, {C(fb528a8dd1e48ad7), C(98c4fd149c8a63dd), C(4abd8fc3377ae1f), C(d7a9304abbb47cc5), C(7f2b9a27aa57f99), C(353ab332d4ef9f18), C(47d56b8d6c8cf578), C(d7a9304abbb47cc5), C(7f2b9a27aa57f99), C(353ab332d4ef9f18), C(47d56b8d6c8cf578), C(df55f58ae09f311f), C(dba9511784fa86e3), C(c43ce0288858a47e), C(62971e94270b78e1)}, {C(da6d2b7ea9d5f9b6), C(57b11153ee3b4cc8), C(7d3bd1256037142f), C(90b16ff331b719b5), C(fc294e7ad39e01e6), C(d2145386bab41623), C(7045a63d44d76011), C(90b16ff331b719b5), C(fc294e7ad39e01e6), C(d2145386bab41623), C(7045a63d44d76011), C(a232222ed0fe2fa4), C(e6c17dff6c323a8a), C(bbcb079be123ac6c), C(4121fe2c5de7d850)}, {C(61d95225bc2293e), C(f6c52cb6be9889a8), C(91a0667a7ed6a113), C(441133d221486a3d), C(fb9c5a40e19515b), C(6c967b6c69367c2d), C(145bd9ef258c4099), C(441133d221486a3d), C(fb9c5a40e19515b), C(6c967b6c69367c2d), C(145bd9ef258c4099), C(a0197657160c686e), C(91ada0871c23f379), C(2fd74fceccb5c80c), C(bf04f24e2dc17913)}, {C(81247c01ab6a9cc1), C(fbccea953e810636), C(ae18965000c31be0), C(15bb46383daec2a5), C(716294063b4ba089), C(f3bd691ce02c3014), C(14ccaad685a20764), C(15bb46383daec2a5), C(716294063b4ba089), C(f3bd691ce02c3014), C(14ccaad685a20764), C(5db25914279d6f24), C(25c451fce3b2ed06), C(e6bacb43ba1ddb9a), C(6d77493a2e6fd76)}, {C(c17f3ebd3257cb8b), C(e9e68c939c118c8d), C(72a5572be35bfc1b), C(f6916c341cb31f2a), C(591da1353ee5f31c), C(f1313c98a836b407), C(e0b8473eada48cd1), C(f6916c341cb31f2a), C(591da1353ee5f31c), C(f1313c98a836b407), C(e0b8473eada48cd1), C(ac5c2fb40b09ba46), C(3a3e8a9344eb6548), C(3bf9349a9d8483a6), C(c30dd0d9b15e92d0)}, {C(9802438969c3043b), C(6cd07575c948dd82), C(83e26b6830ea8640), C(d52f1fa190576961), C(11d182e4f0d419cc), C(5d9ccf1b56617424), C(c8a16debb585e452), C(d52f1fa190576961), C(11d182e4f0d419cc), C(5d9ccf1b56617424), C(c8a16debb585e452), C(2158a752d2686d40), C(b93c1fdf54789e8c), C(3a9a435627b2a30b), C(de6e5e551e7e5ad5)}, {C(3dd8ed248a03d754), C(d8c1fcf001cb62e0), C(87a822141ed64927), C(4bfaf6fd26271f47), C(aefeae8222ad3c77), C(cfb7b24351a60585), C(8678904e9e890b8f), C(4bfaf6fd26271f47), C(aefeae8222ad3c77), C(cfb7b24351a60585), C(8678904e9e890b8f), C(968dd1aa4d7dcf31), C(7ac643b015007a39), C(d1e1bac3d94406ec), C(babfa52474a404fa)}, {C(c5bf48d7d3e9a5a3), C(8f0249b5c5996341), C(c6d2c8a606f45125), C(fd1779db740e2c48), C(1950ef50fefab3f8), C(e4536426a6196809), C(699556c502a01a6a), C(fd1779db740e2c48), C(1950ef50fefab3f8), C(e4536426a6196809), C(699556c502a01a6a), C(2f49d268bb57b946), C(b205baa6c66ebfa5), C(ab91ebe4f48b0da1), C(c7e0718ccc360328)}, {C(bc4a21d00cf52288), C(28df3eb5a533fa87), C(6081bbc2a18dd0d), C(8eed355d219e58b9), C(2d7b9f1a3d645165), C(5758d1aa8d85f7b2), C(9c90c65920041dff), C(8eed355d219e58b9), C(2d7b9f1a3d645165), C(5758d1aa8d85f7b2), C(9c90c65920041dff), C(3c5c4ea46645c7f1), C(346879ecc0e2eb90), C(8434fec461bb5a0f), C(783ccede50ef5ce9)}, {C(172c8674913ff413), C(1815a22400e832bf), C(7e011f9467a06650), C(161be43353a31dd0), C(79a8afddb0642ac3), C(df43af54e3e16709), C(6e12553a75b43f07), C(161be43353a31dd0), C(79a8afddb0642ac3), C(df43af54e3e16709), C(6e12553a75b43f07), C(3ac1b1121e87d023), C(2d47d33df7b9b027), C(e2d3f71f4e817ff5), C(70b3a11ca85f8a39)}, {C(17a361dbdaaa7294), C(c67d368223a3b83c), C(f49cf8d51ab583d2), C(666eb21e2eaa596), C(778f3e1b6650d56), C(3f6be451a668fe2d), C(5452892b0b101388), C(666eb21e2eaa596), C(778f3e1b6650d56), C(3f6be451a668fe2d), C(5452892b0b101388), C(cc867fceaeabdb95), C(f238913c18aaa101), C(f5236b44f324cea1), C(c507cc892ff83dd1)}, {C(5cc268bac4bd55f), C(232717a35d5b2f1), C(38da1393365c961d), C(2d187f89c16f7b62), C(4eb504204fa1be8), C(222bd53d2efe5fa), C(a4dcd6d721ddb187), C(2d187f89c16f7b62), C(4eb504204fa1be8), C(222bd53d2efe5fa), C(a4dcd6d721ddb187), C(d86bbe67666eca70), C(c8bbae99d8e6429f), C(41dac4ceb2cb6b10), C(2f90c331755f6c48)}, {C(db04969cc06547f1), C(fcacc8a75332f120), C(967ccec4ed0c977e), C(ac5d1087e454b6cd), C(c1f8b2e284d28f6c), C(cc3994f4a9312cfa), C(8d61606dbc4e060d), C(ac5d1087e454b6cd), C(c1f8b2e284d28f6c), C(cc3994f4a9312cfa), C(8d61606dbc4e060d), C(17315af3202a1307), C(850775145e01163a), C(96f10e7357f930d2), C(abf27049cf07129)}, {C(25bd8d3ca1b375b2), C(4ad34c2c865816f9), C(9be30ad32f8f28aa), C(7755ea02dbccad6a), C(cb8aaf8886247a4a), C(8f6966ce7ea1b6e6), C(3f2863090fa45a70), C(7755ea02dbccad6a), C(cb8aaf8886247a4a), C(8f6966ce7ea1b6e6), C(3f2863090fa45a70), C(1e46d73019c9fb06), C(af37f39351616f2c), C(657efdfff20ea2ed), C(93bdf4c58ada3ecb)}, {C(166c11fbcbc89fd8), C(cce1af56c48a48aa), C(78908959b8ede084), C(19032925ba2c951a), C(a53ed6e81b67943a), C(edc871a9e8ef4bdf), C(ae66cf46a8371aba), C(19032925ba2c951a), C(a53ed6e81b67943a), C(edc871a9e8ef4bdf), C(ae66cf46a8371aba), C(a37b97790fe75861), C(eda28c8622708b98), C(3f0a23509d3d5c9d), C(5787b0e7976c97cf)}, {C(3565bcc4ca4ce807), C(ec35bfbe575819d5), C(6a1f690d886e0270), C(1ab8c584625f6a04), C(ccfcdafb81b572c4), C(53b04ba39fef5af9), C(64ce81828eefeed4), C(1ab8c584625f6a04), C(ccfcdafb81b572c4), C(53b04ba39fef5af9), C(64ce81828eefeed4), C(131af99997fc662c), C(8d9081192fae833c), C(2828064791cb2eb), C(80554d2e8294065c)}, {C(b7897fd2f274307d), C(6d43a9e5dd95616d), C(31a2218e64d8fce0), C(664e581fc1cf769b), C(415110942fc97022), C(7a5d38fee0bfa763), C(dc87ddb4d7495b6c), C(664e581fc1cf769b), C(415110942fc97022), C(7a5d38fee0bfa763), C(dc87ddb4d7495b6c), C(7c3b66372e82e64b), C(1c89c0ceeeb2dd1), C(dad76d2266214dbd), C(744783486e43cc61)}, {C(aba98113ab0e4a16), C(287f883aede0274d), C(3ecd2a607193ba3b), C(e131f6cc9e885c28), C(b399f98d827e4958), C(6eb90c8ed6c9090c), C(ec89b378612a2b86), C(e131f6cc9e885c28), C(b399f98d827e4958), C(6eb90c8ed6c9090c), C(ec89b378612a2b86), C(cfc0e126e2f860c0), C(a9a8ab5dec95b1c), C(d06747f372f7c733), C(fbd643f943a026d3)}, {C(17f7796e0d4b636c), C(ddba5551d716137b), C(65f9735375df1ada), C(a39e946d02e14ec2), C(1c88cc1d3822a193), C(663f8074a5172bb4), C(8ad2934942e4cb9c), C(a39e946d02e14ec2), C(1c88cc1d3822a193), C(663f8074a5172bb4), C(8ad2934942e4cb9c), C(3da03b033a95f16c), C(54a52f1932a1749d), C(779eeb734199bc25), C(359ce8c8faccc57b)}, {C(33c0128e62122440), C(b23a588c8c37ec2b), C(f2608199ca14c26a), C(acab0139dc4f36df), C(9502b1605ca1345a), C(32174ef1e06a5e9c), C(d824b7869258192b), C(acab0139dc4f36df), C(9502b1605ca1345a), C(32174ef1e06a5e9c), C(d824b7869258192b), C(681d021b52064762), C(30b6c735f80ac371), C(6a12d8d7f78896b3), C(157111657a972144)}, {C(988bc5d290b97aef), C(6754bb647eb47666), C(44b5cf8b5b8106a8), C(a1c5ba961937f723), C(32d6bc7214dfcb9b), C(6863397e0f4c6758), C(e644bcb87e3eef70), C(a1c5ba961937f723), C(32d6bc7214dfcb9b), C(6863397e0f4c6758), C(e644bcb87e3eef70), C(bf25ae22e7aa7c97), C(f5f3177da5756312), C(56a469cb0dbb58cd), C(5233184bb6130470)}, {C(23c8c25c2ab72381), C(d6bc672da4175fba), C(6aef5e6eb4a4eb10), C(3df880c945e68aed), C(5e08a75e956d456f), C(f984f088d1a322d7), C(7d44a1b597b7a05e), C(3df880c945e68aed), C(5e08a75e956d456f), C(f984f088d1a322d7), C(7d44a1b597b7a05e), C(cbd7d157b7fcb020), C(2e2945e90749c2aa), C(a86a13c934d8b1bb), C(fbe3284bb4eab95f)}, {C(450fe4acc4ad3749), C(3111b29565e4f852), C(db570fc2abaf13a9), C(35107d593ba38b22), C(fd8212a125073d88), C(72805d6e015bfacf), C(6b22ae1a29c4b853), C(35107d593ba38b22), C(fd8212a125073d88), C(72805d6e015bfacf), C(6b22ae1a29c4b853), C(df2401f5c3c1b633), C(c72307e054c81c8f), C(3efbfe65bd2922c0), C(b4f632e240b3190c)}, {C(48e1eff032d90c50), C(dee0fe333d962b62), C(c845776990c96775), C(8ea71758346b71c9), C(d84258cab79431fd), C(af566b4975cce10a), C(5c5c7e70a91221d2), C(8ea71758346b71c9), C(d84258cab79431fd), C(af566b4975cce10a), C(5c5c7e70a91221d2), C(c33202c7be49ea6f), C(e8ade53b6cbf4caf), C(102ea04fc82ce320), C(c1f7226614715e5e)}, {C(c048604ba8b6c753), C(21ea6d24b417fdb6), C(4e40a127ad2d6834), C(5234231bf173c51), C(62319525583eaf29), C(87632efa9144cc04), C(1749de70c8189067), C(5234231bf173c51), C(62319525583eaf29), C(87632efa9144cc04), C(1749de70c8189067), C(29672240923e8207), C(11dd247a815f6d0d), C(8d64e16922487ed0), C(9fa6f45d50d83627)}, {C(67ff1cbe469ebf84), C(3a828ac9e5040eb0), C(85bf1ad6b363a14b), C(2fc6c0783390d035), C(ef78307f5be5524e), C(a46925b7a1a77905), C(fea37470f9a51514), C(2fc6c0783390d035), C(ef78307f5be5524e), C(a46925b7a1a77905), C(fea37470f9a51514), C(9d6504cf6d3947ce), C(174cc006b8e96e7), C(d653a06d8a009836), C(7d22b5399326a76c)}, {C(b45c7536bd7a5416), C(e2d17c16c4300d3c), C(b70b641138765ff5), C(a5a859ab7d0ddcfc), C(8730164a0b671151), C(af93810c10348dd0), C(7256010c74f5d573), C(a5a859ab7d0ddcfc), C(8730164a0b671151), C(af93810c10348dd0), C(7256010c74f5d573), C(e22a335be6cd49f3), C(3bc9c8b40c9c397a), C(18da5c08e28d3fb5), C(f58ea5a00404a5c9)}, {C(215c2eaacdb48f6f), C(33b09acf1bfa2880), C(78c4e94ba9f28bf), C(981b7219224443d1), C(1f476fc4344d7bba), C(abad36e07283d3a5), C(831bf61190eaaead), C(981b7219224443d1), C(1f476fc4344d7bba), C(abad36e07283d3a5), C(831bf61190eaaead), C(4c90729f62432254), C(2ffadc94c89f47b3), C(677e790b43d20e9a), C(bb0a1686e7c3ae5f)}, {C(241baf16d80e0fe8), C(b6b3c5b53a3ce1d), C(6ae6b36209eecd70), C(a560b6a4aa3743a4), C(b3e04f202b7a99b), C(3b3b1573f4c97d9f), C(ccad8715a65af186), C(a560b6a4aa3743a4), C(b3e04f202b7a99b), C(3b3b1573f4c97d9f), C(ccad8715a65af186), C(d0c93a838b0c37e7), C(7150aa1be7eb1aad), C(755b1e60b84d8d), C(51916e77b1b05ba9)}, {C(d10a9743b5b1c4d1), C(f16e0e147ff9ccd6), C(fbd20a91b6085ed3), C(43d309eb00b771d5), C(a6d1f26105c0f61b), C(d37ad62406e5c37e), C(75d9b28c717c8cf7), C(43d309eb00b771d5), C(a6d1f26105c0f61b), C(d37ad62406e5c37e), C(75d9b28c717c8cf7), C(8f5f118b425b57cd), C(5d806318613275f3), C(8150848bcf89d009), C(d5531710d53e1462)}, {C(919ef9e209f2edd1), C(684c33fb726a720a), C(540353f94e8033), C(26da1a143e7d4ec4), C(55095eae445aacf4), C(31efad866d075938), C(f9b580cff4445f94), C(26da1a143e7d4ec4), C(55095eae445aacf4), C(31efad866d075938), C(f9b580cff4445f94), C(b1bea6b8716d9c48), C(9ed2a3df4a15dc53), C(11f1be58843eb8e9), C(d9899ecaaef3c77c)}, {C(b5f9519b6c9280b), C(7823a2fe2e103803), C(d379a205a3bd4660), C(466ec55ee4b4302a), C(714f1b9985deeaf0), C(728595f26e633cf7), C(25ecd0738e1bee2b), C(466ec55ee4b4302a), C(714f1b9985deeaf0), C(728595f26e633cf7), C(25ecd0738e1bee2b), C(db51771ad4778278), C(763e5742ac55639e), C(df040e92d38aa785), C(5df997d298499bf1)}, {C(77a75e89679e6757), C(25d31fee616b5dd0), C(d81f2dfd08890060), C(7598df8911dd40a4), C(3b6dda517509b41b), C(7dae29d248dfffae), C(6697c427733135f), C(7598df8911dd40a4), C(3b6dda517509b41b), C(7dae29d248dfffae), C(6697c427733135f), C(834d6c0444c90899), C(c790675b3cd53818), C(28bb4c996ecadf18), C(92c648513e6e6064)}, {C(9d709e1b086aabe2), C(4d6d6a6c543e3fec), C(df73b01acd416e84), C(d54f613658e35418), C(fcc88fd0567afe77), C(d18f2380980db355), C(ec3896137dfbfa8b), C(d54f613658e35418), C(fcc88fd0567afe77), C(d18f2380980db355), C(ec3896137dfbfa8b), C(eb48dbd9a1881600), C(ca7bd7415ab43ca9), C(e6c5a362919e2351), C(2f4e4bd2d5267c21)}, {C(91c89971b3c20a8a), C(87b82b1d55780b5), C(bc47bb80dfdaefcd), C(87e11c0f44454863), C(2df1aedb5871cc4b), C(ba72fd91536382c8), C(52cebef9e6ea865d), C(87e11c0f44454863), C(2df1aedb5871cc4b), C(ba72fd91536382c8), C(52cebef9e6ea865d), C(5befc3fc66bc7fc5), C(b128bbd735a89061), C(f8f500816fa012b3), C(f828626c9612f04)}, {C(16468c55a1b3f2b4), C(40b1e8d6c63c9ff4), C(143adc6fee592576), C(4caf4deeda66a6ee), C(264720f6f35f7840), C(71c3aef9e59e4452), C(97886ca1cb073c55), C(4caf4deeda66a6ee), C(264720f6f35f7840), C(71c3aef9e59e4452), C(97886ca1cb073c55), C(16155fef16fc08e8), C(9d0c1d1d5254139a), C(246513bf2ac95ee2), C(22c8440f59925034)}, {C(1a2bd6641870b0e4), C(e4126e928f4a7314), C(1e9227d52aab00b2), C(d82489179f16d4e8), C(a3c59f65e2913cc5), C(36cbaecdc3532b3b), C(f1b454616cfeca41), C(d82489179f16d4e8), C(a3c59f65e2913cc5), C(36cbaecdc3532b3b), C(f1b454616cfeca41), C(99393e31e3eefc16), C(3ca886eac5754cdf), C(c11776fc3e4756dd), C(ca118f7059198ba)}, {C(1d2f92f23d3e811a), C(e0812edbcd475412), C(92d2d6ad29c05767), C(fd7feb3d2956875e), C(d7192a886b8b01b6), C(16e71dba55f5b85a), C(93dabd3ff22ff144), C(fd7feb3d2956875e), C(d7192a886b8b01b6), C(16e71dba55f5b85a), C(93dabd3ff22ff144), C(14ff0a5444c272c9), C(fb024d3bb8d915c2), C(1bc3229a94cab5fe), C(6f6f1fb3c0dccf09)}, {C(a47c08255da30ca8), C(cf6962b7353f4e68), C(2808051ea18946b1), C(b5b472960ece11ec), C(13935c99b9abbf53), C(3e80d95687f0432c), C(3516ab536053be5), C(b5b472960ece11ec), C(13935c99b9abbf53), C(3e80d95687f0432c), C(3516ab536053be5), C(748ce6a935755e20), C(2961b51d61b0448c), C(864624113aae88d2), C(a143805366f91338)}, {C(efb3b0262c9cd0c), C(1273901e9e7699b3), C(58633f4ad0dcd5bb), C(62e33ba258712d51), C(fa085c15d779c0e), C(2c15d9142308c5ad), C(feb517011f27be9e), C(62e33ba258712d51), C(fa085c15d779c0e), C(2c15d9142308c5ad), C(feb517011f27be9e), C(1b2b049793b9eedb), C(d26be505fabc5a8f), C(adc483e42a5c36c5), C(c81ff37d56d3b00b)}, {C(5029700a7773c3a4), C(d01231e97e300d0f), C(397cdc80f1f0ec58), C(e4041579de57c879), C(bbf513cb7bab5553), C(66ad0373099d5fa0), C(44bb6b21b87f3407), C(e4041579de57c879), C(bbf513cb7bab5553), C(66ad0373099d5fa0), C(44bb6b21b87f3407), C(a8108c43b4daba33), C(c0b5308c311e865e), C(cdd265ada48f6fcf), C(efbc1dae0a95ac0a)}, {C(71c8287225d96c9a), C(eb836740524735c4), C(4777522d0e09846b), C(16fde90d02a1343b), C(ad14e0ed6e165185), C(8df6e0b2f24085dd), C(caa8a47292d50263), C(16fde90d02a1343b), C(ad14e0ed6e165185), C(8df6e0b2f24085dd), C(caa8a47292d50263), C(a020413ba660359d), C(9de401413f7c8a0c), C(20bfb965927a7c85), C(b52573e5f817ae27)}, {C(4e8b9ad9347d7277), C(c0f195eeee7641cf), C(dbd810bee1ad5e50), C(8459801016414808), C(6fbf75735353c2d1), C(6e69aaf2d93ed647), C(85bb5b90167cce5e), C(8459801016414808), C(6fbf75735353c2d1), C(6e69aaf2d93ed647), C(85bb5b90167cce5e), C(39d79ee490d890cc), C(ac9f31f7ec97deb0), C(3bdc1cae4ed46504), C(eb5c63cfaee05622)}, {C(1d5218d6ee2e52ab), C(cb25025c4daeff3b), C(aaf107566f31bf8c), C(aad20d70e231582b), C(eab92d70d9a22e54), C(cc5ab266375580c0), C(85091463e3630dce), C(aad20d70e231582b), C(eab92d70d9a22e54), C(cc5ab266375580c0), C(85091463e3630dce), C(b830b617a4690089), C(9dacf13cd76f13cf), C(d47cc5224265c68f), C(f04690880202b002)}, {C(162360be6c293c8b), C(ff672b4a831953c8), C(dda57487ab6f78b5), C(38a42e0db55a4275), C(585971da56bb56d6), C(cd957009adc1482e), C(d6a96021e427567d), C(38a42e0db55a4275), C(585971da56bb56d6), C(cd957009adc1482e), C(d6a96021e427567d), C(8e2b1a5a63cd96fe), C(426ef8ce033d722d), C(c4d1c3d8acdda5f), C(4e694c9be38769b2)}, {C(31459914f13c8867), C(ef96f4342d3bef53), C(a4e944ee7a1762fc), C(3526d9b950a1d910), C(a58ba01135bca7c0), C(cbad32e86d60a87c), C(adde1962aad3d730), C(3526d9b950a1d910), C(a58ba01135bca7c0), C(cbad32e86d60a87c), C(adde1962aad3d730), C(55faade148929704), C(bfc06376c72a2968), C(97762698b87f84be), C(117483d4828cbaf7)}, {C(6b4e8fca9b3aecff), C(3ea0a33def0a296c), C(901fcb5fe05516f5), C(7c909e8cd5261727), C(c5acb3d5fbdc832e), C(54eff5c782ad3cdd), C(9d54397f3caf5bfa), C(7c909e8cd5261727), C(c5acb3d5fbdc832e), C(54eff5c782ad3cdd), C(9d54397f3caf5bfa), C(6b53ce24c4fc3092), C(2789abfdd4c9a14d), C(94d6a2261637276c), C(648aa4a2a1781f25)}, {C(dd3271a46c7aec5d), C(fb1dcb0683d711c3), C(240332e9ebe5da44), C(479f936b6d496dca), C(dc2dc93d63739d4a), C(27e4151c3870498c), C(3a3a22ba512d13ba), C(479f936b6d496dca), C(dc2dc93d63739d4a), C(27e4151c3870498c), C(3a3a22ba512d13ba), C(5da92832f96d3cde), C(439b9ad48c4e7644), C(d2939279030accd9), C(6829f920e2950dbe)}, {C(109b226238347d6e), C(e27214c32c43b7e7), C(eb71b0afaf0163ef), C(464f1adf4c68577), C(acf3961e1c9d897f), C(985b01ab89b41fe1), C(6972d6237390aac0), C(464f1adf4c68577), C(acf3961e1c9d897f), C(985b01ab89b41fe1), C(6972d6237390aac0), C(122d89898e256a0e), C(ac830561bd8be599), C(5744312574fbf0ad), C(7bff7f480a924ce9)}, {C(cc920608aa94cce4), C(d67efe9e097bce4f), C(5687727c2c9036a9), C(8af42343888843c), C(191433ffcbab7800), C(7eb45fc94f88a71), C(31bc5418ffb88fa8), C(8af42343888843c), C(191433ffcbab7800), C(7eb45fc94f88a71), C(31bc5418ffb88fa8), C(4b53a37d8f446cb7), C(a6a7dfc757a60d28), C(a074be7bacbc013a), C(cc6db5f270de7adc)}, {C(901ff46f22283dbe), C(9dd59794d049a066), C(3c7d9c3b0e77d2c6), C(dc46069eec17bfdf), C(cacb63fe65d9e3e), C(362fb57287d530c6), C(5854a4fbe1762d9), C(dc46069eec17bfdf), C(cacb63fe65d9e3e), C(362fb57287d530c6), C(5854a4fbe1762d9), C(3197427495021efc), C(5fabf34386aa4205), C(ca662891de36212), C(21f603e4d39bca84)}, {C(11b3bdda68b0725d), C(2366bf0aa97a00bd), C(55dc4a4f6bf47e2b), C(69437142dae5a255), C(f2980cc4816965ac), C(dbbe76ba1d9adfcf), C(49c18025c0a8b0b5), C(69437142dae5a255), C(f2980cc4816965ac), C(dbbe76ba1d9adfcf), C(49c18025c0a8b0b5), C(fe25c147c9001731), C(38b99cad0ca30c81), C(c7ff06ac47eb950), C(a10f92885a6b3c02)}, {C(9f5f03e84a40d232), C(1151a9ff99da844), C(d6f2e7c559ac4657), C(5e351e20f30377bf), C(91b3805daf12972c), C(94417fa6452a265e), C(bfa301a26765a7c), C(5e351e20f30377bf), C(91b3805daf12972c), C(94417fa6452a265e), C(bfa301a26765a7c), C(6924e2a053297d13), C(ed4a7904ed30d77e), C(d734abaad66d6eab), C(ce373e6c09e6e8a1)}, {C(39eeff4f60f439be), C(1f7559c118517c70), C(6139d2492237a36b), C(fd39b7642cecf78f), C(104f1af4e9201df5), C(ab1a3cc7eaeab609), C(cee3363f210a3d8b), C(fd39b7642cecf78f), C(104f1af4e9201df5), C(ab1a3cc7eaeab609), C(cee3363f210a3d8b), C(51490f65fe56c884), C(6a8c8322cda993c), C(1f90609a017de1f0), C(9f3acea480a41edf)}, {C(9b9e0126fe4b8b04), C(6a6190d520886c41), C(69640b27c16b3ed8), C(18865ff87619fd8f), C(dec5293e665663d8), C(ea07c345872d3201), C(6fce64da038a17ab), C(18865ff87619fd8f), C(dec5293e665663d8), C(ea07c345872d3201), C(6fce64da038a17ab), C(ad48f3c826c6a83e), C(70a1ff080a4da737), C(ecdac686c7d7719), C(700338424b657470)}, {C(3ec4b8462b36df47), C(ff8de4a1cbdb7e37), C(4ede0449884716ac), C(b5f630ac75a8ce03), C(7cf71ae74fa8566a), C(e068f2b4618df5d), C(369df952ad3fd0b8), C(b5f630ac75a8ce03), C(7cf71ae74fa8566a), C(e068f2b4618df5d), C(369df952ad3fd0b8), C(5e1ba38fea018eb6), C(5ea5edce48e3da30), C(9b3490c941069dcb), C(e17854a44cc2fff)}, {C(5e3fd9298fe7009f), C(d2058a44222d5a1d), C(cc25df39bfeb005c), C(1b0118c5c60a99c7), C(6ae919ef932301b8), C(cde25defa089c2fc), C(c2a3776e3a7716c4), C(1b0118c5c60a99c7), C(6ae919ef932301b8), C(cde25defa089c2fc), C(c2a3776e3a7716c4), C(2557bf65fb26269e), C(b2edabba58f2ae4f), C(264144e9f0e632cb), C(ad6481273c979566)}, {C(7504ecb4727b274e), C(f698cfed6bc11829), C(71b62c425ecd348e), C(2a5e555fd35627db), C(55d5da439c42f3b8), C(a758e451732a1c6f), C(18caa6b46664b484), C(2a5e555fd35627db), C(55d5da439c42f3b8), C(a758e451732a1c6f), C(18caa6b46664b484), C(6ec1c7d1524bbad7), C(1cc3531dc422529d), C(61a6eeb29c0e5110), C(9cc8652016784a6a)}, {C(4bdedc104d5eaed5), C(531c4bb4fd721e5d), C(1d860834e94a219f), C(1944ec723253392b), C(7ea6aa6a2f278ea5), C(5ff786af8113b3d5), C(194832eb9b0b8d0f), C(1944ec723253392b), C(7ea6aa6a2f278ea5), C(5ff786af8113b3d5), C(194832eb9b0b8d0f), C(56ab0396ed73fd38), C(2c88725b3dfbf89d), C(7ff57adf6275c816), C(b32f7630bcdb218)}, {C(da0b4a6fb26a4748), C(8a3165320ae1af74), C(4803664ee3d61d09), C(81d90ddff0d00fdb), C(2c8c7ce1173b5c77), C(18c6b6c8d3f91dfb), C(415d5cbbf7d9f717), C(81d90ddff0d00fdb), C(2c8c7ce1173b5c77), C(18c6b6c8d3f91dfb), C(415d5cbbf7d9f717), C(b683e956f1eb3235), C(43166dde2b64d11f), C(f9689c90f5aad771), C(ca0ebc253c2eec38)}, {C(bad6dd64d1b18672), C(6d4c4b91c68bd23f), C(d8f1507176822db7), C(381068e0f65f708b), C(b4f3762e451b12a6), C(6d61ed2f6d4e741), C(8b3b9df537b91a2c), C(381068e0f65f708b), C(b4f3762e451b12a6), C(6d61ed2f6d4e741), C(8b3b9df537b91a2c), C(b0759e599a91575c), C(9e7adbcc77212239), C(cf0eba98436555fe), C(b1fcc9c42c4cd1e6)}, {C(98da3fe388d5860e), C(14a9fda8b3adb103), C(d85f5f798637994b), C(6e8e8ff107799274), C(24a2ef180891b531), C(c0eaf33a074bcb9d), C(1fa399a82974e17e), C(6e8e8ff107799274), C(24a2ef180891b531), C(c0eaf33a074bcb9d), C(1fa399a82974e17e), C(e7c116bef933725d), C(859908c7d17b93de), C(f6cfa27113af4a72), C(edf41c5d83c721a8)}, {C(ef243a576431d7ac), C(92a32619ecfae0a5), C(fb34d2c062dc803a), C(f5f8b21ec30bd3a0), C(80a442fd5c6482a8), C(4fde11e5ccde5169), C(55671451f661a885), C(f5f8b21ec30bd3a0), C(80a442fd5c6482a8), C(4fde11e5ccde5169), C(55671451f661a885), C(94f27bc2d5d8d63e), C(2156968b87f084dc), C(b591bcae146f6fea), C(f57f4c01e41ac7fe)}, {C(97854de6f22c97b6), C(1292ac07b0f426bb), C(9a099a28b22d3a38), C(caac64f5865d87f3), C(771b9fdbd3aa4bd2), C(88446393c3606c2d), C(bc3d3dcd5b7d6d7f), C(caac64f5865d87f3), C(771b9fdbd3aa4bd2), C(88446393c3606c2d), C(bc3d3dcd5b7d6d7f), C(56e22512b832d3ee), C(bbc677fe5ce0b665), C(f1914b0f070e5c32), C(c10d40362472dcd1)}, {C(d26ce17bfc1851d), C(db30fb632c7da294), C(26cb7b1a465400a5), C(401a0581221957e2), C(fc04e99ae3a283ce), C(fe895303ab2d1e3e), C(35ab7c498403975b), C(401a0581221957e2), C(fc04e99ae3a283ce), C(fe895303ab2d1e3e), C(35ab7c498403975b), C(c6e4c8dc6f52fb11), C(63f0b484c2c7502f), C(93693da3439bdbe9), C(1264dbaaaaf6b7f1)}, {C(97477bac0ba4c7f1), C(788ef8729dca29ac), C(63d88e226d36132c), C(330b7e93663affbd), C(3c59913fcf0d603f), C(e207e6572672fd0a), C(8a5dc17019c8a667), C(330b7e93663affbd), C(3c59913fcf0d603f), C(e207e6572672fd0a), C(8a5dc17019c8a667), C(5c8f47ade659d40), C(6e0838e5a808e9a2), C(8a2d9a0afcd48b19), C(d1c9d5af7b48418d)}, {C(f6bbcba92b11f5c8), C(72cf221cad20f191), C(a04726593764122d), C(77fbb70409d316e2), C(c864432c5208e583), C(d3f593922668c184), C(23307562648bdb54), C(77fbb70409d316e2), C(c864432c5208e583), C(d3f593922668c184), C(23307562648bdb54), C(b03e0b274f848a74), C(c6121e3af71f4281), C(2e48dd2a16ca63ec), C(f4cd44c69ae024df)}, {C(1ac8b67c1c82132), C(7536db9591be9471), C(42f18fbe7141e565), C(20085827a39ff749), C(42e6c504df174606), C(839da16331fea7ac), C(7fd768552b10ffc6), C(20085827a39ff749), C(42e6c504df174606), C(839da16331fea7ac), C(7fd768552b10ffc6), C(d1c53c90fde72640), C(c61ae7cf4e266556), C(127561e440e4c156), C(f329cae8c26af3e1)}, {C(9cd716ca0eee52fa), C(67c1076e1ef11f93), C(927342024f36f5d7), C(d0884af223fd056b), C(bb33aafc7b80b3e4), C(36b722fea81a4c88), C(6e72e3022c0ed97), C(d0884af223fd056b), C(bb33aafc7b80b3e4), C(36b722fea81a4c88), C(6e72e3022c0ed97), C(5db446a3ba66e0ba), C(2e138fb81b28ad9), C(16e8e82995237c85), C(9730dbfb072fbf03)}, {C(1909f39123d9ad44), C(c0bdd71c5641fdb7), C(112e5d19abda9b14), C(984cf3f611546e28), C(d7d9c9c4e7efb5d7), C(b3152c389532b329), C(1c168b512ec5f659), C(984cf3f611546e28), C(d7d9c9c4e7efb5d7), C(b3152c389532b329), C(1c168b512ec5f659), C(eca67cc49e26069a), C(73cb0b224d36d541), C(df8379190ae6c5fe), C(e0f6bde7c4726211)}, {C(1d206f99f535efeb), C(882e15548afc3422), C(c94f203775c8c634), C(24940a3adac420b8), C(5adf73051c52bce0), C(1aa5030247ed3d32), C(e1ae74ab6804c08b), C(24940a3adac420b8), C(5adf73051c52bce0), C(1aa5030247ed3d32), C(e1ae74ab6804c08b), C(95217bf71b0da84c), C(ca9bb91c0126a36e), C(741b9a99ea470974), C(2adc4e34b8670f41)}, {C(b38c3a83042eb802), C(ea134be7c6e0c326), C(81d396c683df4f35), C(2a55645640911e27), C(4fac2eefbd36e26f), C(79ad798fb4c5835c), C(359aa2faec050131), C(2a55645640911e27), C(4fac2eefbd36e26f), C(79ad798fb4c5835c), C(359aa2faec050131), C(5b802dcec21a7157), C(6ecde915b75ede0a), C(f2e653587e89058b), C(a661be80528d3385)}, {C(488d6b45d927161b), C(f5cac66d869a8aaf), C(c326d56c643a214e), C(10a7228693eb083e), C(1054fb19cbacf01c), C(a8f389d24587ebd8), C(afcb783a39926dba), C(10a7228693eb083e), C(1054fb19cbacf01c), C(a8f389d24587ebd8), C(afcb783a39926dba), C(fe83e658532edf8f), C(6fdcf97f147dc4db), C(dc5e487845abef4b), C(137693f4eab77e27)}, {C(3d6aaa43af5d4f86), C(44c7d370910418d8), C(d099515f7c5c4eca), C(39756960441fbe2f), C(fb68e5fedbe3d874), C(3ff380fbdd27b8e), C(f48832fdda648998), C(39756960441fbe2f), C(fb68e5fedbe3d874), C(3ff380fbdd27b8e), C(f48832fdda648998), C(270ddbf2327058c9), C(9eead83a8319d0c4), C(b4c3356e162b086d), C(88f013588f411b7)}, {C(e5c40a6381e43845), C(312a18e66bbceaa3), C(31365186c2059563), C(cba4c10e65410ba0), C(3c250c8b2d72c1b6), C(177e82f415595117), C(8c8dcfb9e73d3f6), C(cba4c10e65410ba0), C(3c250c8b2d72c1b6), C(177e82f415595117), C(8c8dcfb9e73d3f6), C(c017a797e49c0f7), C(ea2b233b2e7d5aea), C(878d204c55a56cb1), C(7b1b62cc0dfdc523)}, {C(86fb323e5a4b710b), C(710c1092c23a79e0), C(bd2c6d3fc949402e), C(951f2078aa4b8099), C(e68b7fefa1cfd190), C(41525a4990ba6d4a), C(c373552ef4b51712), C(951f2078aa4b8099), C(e68b7fefa1cfd190), C(41525a4990ba6d4a), C(c373552ef4b51712), C(73eb44c6122bdf5a), C(58047289a314b013), C(e31d30432521705b), C(6cf856774873faa4)}, {C(7930c09adaf6e62e), C(f230d3311593662c), C(a795b9bf6c37d211), C(b57ec44bc7101b96), C(6cb710e77767a25a), C(2f446152d5e3a6d0), C(cd69172f94543ce3), C(b57ec44bc7101b96), C(6cb710e77767a25a), C(2f446152d5e3a6d0), C(cd69172f94543ce3), C(e6c2483cf425f072), C(2060d5d4379d6d5a), C(86a3c04c2110d893), C(561d3b8a509313c6)}, {C(e505e86f0eff4ecd), C(cf31e1ccb273b9e6), C(d8efb8e9d0fe575), C(ed094f47671e359d), C(d9ebdb047d57611a), C(1c620e4d301037a3), C(df6f401c172f68e8), C(ed094f47671e359d), C(d9ebdb047d57611a), C(1c620e4d301037a3), C(df6f401c172f68e8), C(af0a2c7f72388ec7), C(6d4c4a087fa4564a), C(411b30def69700a), C(67e5c84557a47e01)}, {C(dedccb12011e857), C(d831f899174feda8), C(ee4bcdb5804c582a), C(5d765af4e88f3277), C(d2abe1c63ad4d103), C(342a8ce0bc7af6e4), C(31bfda956f3e5058), C(5d765af4e88f3277), C(d2abe1c63ad4d103), C(342a8ce0bc7af6e4), C(31bfda956f3e5058), C(4c7a1fec9af54bbb), C(84a88f0655899bf4), C(66fb60d0582ac601), C(be0dd1ffe967bd4a)}, {C(4d679bda26f5555f), C(7deb387eb7823c1c), C(a65ef3b4fecd6888), C(a6814d3dc578b9df), C(3372111a3292b691), C(e97589c81d92b513), C(74edd943d1b9b5bf), C(a6814d3dc578b9df), C(3372111a3292b691), C(e97589c81d92b513), C(74edd943d1b9b5bf), C(889e38b0af80bb7a), C(a416349af3c5818b), C(f5f5bb25576221c1), C(3be023fa6912c32e)}, {C(e47cd22995a75a51), C(3686350c2569a162), C(861afcb185b8efd9), C(63672de7951e1853), C(3ca0c763273b99db), C(29e04fa994cccb98), C(b02587d792be5ee8), C(63672de7951e1853), C(3ca0c763273b99db), C(29e04fa994cccb98), C(b02587d792be5ee8), C(c85ada4858f7e4fc), C(3f280ab7d5864460), C(4109822f92f68326), C(2d73f61314a2f630)}, {C(92ba8e12e0204f05), C(4e29321580273802), C(aa83b675ed74a851), C(a16cd2e8b445a3fd), C(f0d4f9fb613c38ef), C(eee7755d444d8f2f), C(b530591eb67ae30d), C(a16cd2e8b445a3fd), C(f0d4f9fb613c38ef), C(eee7755d444d8f2f), C(b530591eb67ae30d), C(6fb3031a6edf8fec), C(65118d08aecf56d8), C(9a2117bbef1faa8), C(97055c5fd310aa93)}, {C(bb3a8427c64f8939), C(b5902af2ec095a04), C(89f1b440667b2a28), C(5386ef0b438d0330), C(d39e03c686f8a2da), C(9555249bb9073d78), C(8c0b3623fdf0b156), C(5386ef0b438d0330), C(d39e03c686f8a2da), C(9555249bb9073d78), C(8c0b3623fdf0b156), C(354fc5d3a5504e5e), C(b2fd7391719aa614), C(13cd4ce3dfe27b3d), C(a2d63a85dc3cae4b)}, {C(998988f7d6dacc43), C(5f2b853d841152db), C(d76321badc5cb978), C(e381f24ee1d9a97d), C(7c5d95b2a3af2e08), C(ca714acc461cdc93), C(1a8ee94bc847aa3e), C(e381f24ee1d9a97d), C(7c5d95b2a3af2e08), C(ca714acc461cdc93), C(1a8ee94bc847aa3e), C(ee59ee4c21a36f47), C(d476e8bba5bf5143), C(22a03cb5900f6ec8), C(19d954e14f35d7a8)}, {C(3f1049221dd72b98), C(8d9200d7a0664c37), C(3925704c83a5f406), C(4cbef49086e62678), C(d77dfecc2819ef19), C(c327e4deaf4c7e72), C(b4d58c73a262a32d), C(4cbef49086e62678), C(d77dfecc2819ef19), C(c327e4deaf4c7e72), C(b4d58c73a262a32d), C(78cd002324861653), C(7c3f3977576efb88), C(d1c9975fd4a4cc26), C(3e3cbc90a9baa442)}, {C(419e4ff78c3e06f3), C(aa8ff514c8a141d7), C(5bb176e21f89f10d), C(becb065dc12d8b4e), C(ebee135492a2018), C(d3f07e65bcd9e13a), C(85c933e85382e9f9), C(becb065dc12d8b4e), C(ebee135492a2018), C(d3f07e65bcd9e13a), C(85c933e85382e9f9), C(2c19ab7c419ebaca), C(982375b2999bdb46), C(652ca1c6325d9296), C(e9c790fa8561940a)}, {C(9ba090af14171317), C(b0445c5232d7be53), C(72cc929d1577ddb8), C(bc944c1b5ba2184d), C(ab3d57e5e60e9714), C(5d8d27e7dd0a365a), C(4dd809e11740af1a), C(bc944c1b5ba2184d), C(ab3d57e5e60e9714), C(5d8d27e7dd0a365a), C(4dd809e11740af1a), C(6f42d856faad44df), C(5118dc58d7eaf56e), C(829bbc076a43004), C(1747fbbfaca6da98)}, {C(6ad739e4ada9a340), C(2c6c4fb3a2e9b614), C(ab58620e94ca8a77), C(aaa144fbe3e6fda2), C(52a9291d1e212bc5), C(2b4c68291f26b570), C(45351ab332855267), C(aaa144fbe3e6fda2), C(52a9291d1e212bc5), C(2b4c68291f26b570), C(45351ab332855267), C(1149f55400bc9799), C(8c6ec1a0c617771f), C(e9966cc03f3bec05), C(3e6889140ccd2646)}, {C(8ecff07fd67e4abd), C(f1b8029b17006ece), C(21d96d5859229a61), C(b8c18d66154ac51), C(5807350371ad7388), C(81f783f4f5ab2b8), C(fa4e659f90744de7), C(b8c18d66154ac51), C(5807350371ad7388), C(81f783f4f5ab2b8), C(fa4e659f90744de7), C(809da4baa51cad2c), C(88d5c11ff5598342), C(7c7125b0681d67d0), C(1b5ba6124bfed8e8)}, {C(497ca8dbfee8b3a7), C(58c708155d70e20e), C(90428a7e349d6949), C(b744f5056e74ca86), C(88aa27b96f3d84a5), C(b4b1ee0470ac3826), C(aeb46264f4e15d4f), C(b744f5056e74ca86), C(88aa27b96f3d84a5), C(b4b1ee0470ac3826), C(aeb46264f4e15d4f), C(14921b1ee856bc55), C(a341d74aaba00a02), C(4f50aa8e3d08a919), C(75a148668ff3869e)}, {C(a929cd66daa65b0a), C(7c0150a2d9ca564d), C(46ddec37e2ec0a6d), C(4323852cc57e4af3), C(1f5f638bbf9d2e5b), C(578fb6ac89a31d9), C(7792536d9ac4bf12), C(4323852cc57e4af3), C(1f5f638bbf9d2e5b), C(578fb6ac89a31d9), C(7792536d9ac4bf12), C(60be62e795ef5798), C(c276cc5b44febefe), C(519ba0b9f6d1be95), C(1fdce3561ed35bb8)}, {C(4107c4156bc8d4bc), C(1cda0c6f3f0f48af), C(cf11a23299cf7181), C(766b71bff7d6f461), C(b004f2c910a6659e), C(4c0eb3848e1a7c8), C(3f90439d05c3563b), C(766b71bff7d6f461), C(b004f2c910a6659e), C(4c0eb3848e1a7c8), C(3f90439d05c3563b), C(4a2a013f4bc2c1d7), C(888779ab0c272548), C(ae0f8462d89a4241), C(c5c85b7c44679abd)}, {C(15b38dc0e40459d1), C(344fedcfc00fff43), C(b9215c5a0fcf17df), C(d178444a236c1f2d), C(5576deee27f3f103), C(943611bb5b1b0736), C(a0fde17cb5c2316d), C(d178444a236c1f2d), C(5576deee27f3f103), C(943611bb5b1b0736), C(a0fde17cb5c2316d), C(feaa1a047f4375f3), C(5435f313e84767e), C(522e4333cd0330c1), C(7e6b609b0ea9e91f)}, {C(e5e5370ed3186f6c), C(4592e75db47ea35d), C(355d452b82250e83), C(7a265e37da616168), C(6a1f06c34bafa27), C(fbae175e7ed22a9c), C(b144e84f6f33c098), C(7a265e37da616168), C(6a1f06c34bafa27), C(fbae175e7ed22a9c), C(b144e84f6f33c098), C(bd444561b0db41fc), C(2072c85731e7b0b0), C(ce1b1fac436b51f3), C(4f5d44f31a3dcdb9)}, {C(ea2785c8f873e28f), C(3e257272f4464f5f), C(9267e7e0cc9c7fb5), C(9fd4d9362494cbbc), C(e562bc615befb1b9), C(8096808d8646cfde), C(c4084a587b9776ec), C(9fd4d9362494cbbc), C(e562bc615befb1b9), C(8096808d8646cfde), C(c4084a587b9776ec), C(a9135db8a850d8e4), C(fffc4f8b1a11f5af), C(c50e9173c2c6fe64), C(a32630581df4ceda)}, {C(e7bf98235fc8a4a8), C(4042ef2aae400e64), C(6538ba9ffe72dd70), C(c84bb7b3881ab070), C(36fe6c51023fbda0), C(d62838514bb87ea4), C(9eeb5e7934373d86), C(c84bb7b3881ab070), C(36fe6c51023fbda0), C(d62838514bb87ea4), C(9eeb5e7934373d86), C(5f8480d0a2750a96), C(40afa38506456ad9), C(e4012b7ef2e0ddea), C(659da200a011836b)}, {C(b94e261a90888396), C(1f468d07e853294c), C(cb2c9b863a5317b9), C(4473c8e2a3458ee0), C(258053945ab4a39a), C(f8d745ca41962817), C(7afb6d40df9b8f71), C(4473c8e2a3458ee0), C(258053945ab4a39a), C(f8d745ca41962817), C(7afb6d40df9b8f71), C(9030c2349604f677), C(f544dcd593087faf), C(77a3b0efe6345d12), C(fff4e398c05817cc)}, {C(4b0226e5f5cdc9c), C(a836ae7303dc4301), C(8505e1b628bac101), C(b5f52041a698da7), C(29864874b5f1936d), C(49b3a0c6d78f98da), C(93a1a8c7d90de296), C(b5f52041a698da7), C(29864874b5f1936d), C(49b3a0c6d78f98da), C(93a1a8c7d90de296), C(ed62288423c17b7f), C(685afa2cfba09660), C(6d9b6f59585452c6), C(e505535c4010efb9)}, {C(e07edbe7325c718c), C(9db1eda964f06827), C(2f245ad774e4cb1b), C(664ec3fad8521859), C(406f082beb9ca29a), C(b6b0fb3a7981c7c8), C(3ebd280b598a9721), C(664ec3fad8521859), C(406f082beb9ca29a), C(b6b0fb3a7981c7c8), C(3ebd280b598a9721), C(d9a6ceb072eab22a), C(d5bc5df5eb2ff6f1), C(488db3cab48daa0b), C(9916f14fa5672f37)}, {C(f4b56421eae4c4e7), C(5da0070cf40937a0), C(aca4a5e01295984a), C(5414e385f5677a6d), C(41ef105f8a682a28), C(4cd2e95ea7f5e7b0), C(775bb1e0d57053b2), C(5414e385f5677a6d), C(41ef105f8a682a28), C(4cd2e95ea7f5e7b0), C(775bb1e0d57053b2), C(8919017805e84b3f), C(15402f44e0e2b259), C(483b1309e1403c87), C(85c7b4232d45b0d9)}, {C(c07fcb8ae7b4e480), C(4ebcad82e0b53976), C(8643c63d6c78a6ce), C(d4bd358fed3e6aa5), C(8a1ba396356197d9), C(7afc2a54733922cc), C(b813bdac4c7c02ef), C(d4bd358fed3e6aa5), C(8a1ba396356197d9), C(7afc2a54733922cc), C(b813bdac4c7c02ef), C(f6c610cf7e7c955), C(dab6a53e1c0780f8), C(837c9ffec33e5d48), C(8cb8c20032af152d)}, {C(3edad9568a9aaab), C(23891bbaeb3a17bc), C(4eb7238738b0c51a), C(db0c32f76f5b7fc1), C(5e41b711f0abd1a0), C(bcb758f01ded0a11), C(7d15f7d87955e28b), C(db0c32f76f5b7fc1), C(5e41b711f0abd1a0), C(bcb758f01ded0a11), C(7d15f7d87955e28b), C(cd2dc1f0b05939b), C(9fd6d680462e4c47), C(95d5846e993bc8ff), C(f0b3cafc2697b8a8)}, {C(fcabde8700de91e8), C(63784d19c60bf366), C(8f3af9a056b1a1c8), C(32d3a29cf49e2dc9), C(3079c0b0c2269bd0), C(ed76ba44f04e7b82), C(6eee76a90b83035f), C(32d3a29cf49e2dc9), C(3079c0b0c2269bd0), C(ed76ba44f04e7b82), C(6eee76a90b83035f), C(4a9286f545bbc09), C(bd36525be4dd1b51), C(5f7a9117228fdee5), C(543c96a08f03151c)}, {C(362fc5ba93e8eb31), C(7549ae99fa609d61), C(47e4cf524e37178f), C(a54eaa5d7f3a7227), C(9d26922965d54727), C(27d22acb31a194d4), C(e9b8e68771db0da6), C(a54eaa5d7f3a7227), C(9d26922965d54727), C(27d22acb31a194d4), C(e9b8e68771db0da6), C(16fd0e006209abe8), C(81d3f72987a6a81a), C(74e96e4044817bc7), C(924ca5f08572fef9)}, {C(e323b1c5b55a4dfb), C(719993d7d1ad77fb), C(555ca6c6166e989c), C(ea37f61c0c2f6d53), C(9b0c2174f14a01f5), C(7bbe6921e26293f3), C(2ab6c72235b6c98a), C(ea37f61c0c2f6d53), C(9b0c2174f14a01f5), C(7bbe6921e26293f3), C(2ab6c72235b6c98a), C(2c6e7668f37f6d23), C(3e8edb057a57c2dd), C(2595fc79768c8b34), C(ffc541f5efed9c43)}, {C(9461913a153530ef), C(83fc6d9ed7d1285a), C(73df90bdc50807cf), C(a32c192f6e3c3f66), C(8f10077b8a902d00), C(61a227f2faac29b4), C(1a71466fc005a61d), C(a32c192f6e3c3f66), C(8f10077b8a902d00), C(61a227f2faac29b4), C(1a71466fc005a61d), C(12545812f3d01a92), C(aece72f823ade07d), C(52634cdd5f9e5260), C(cb48f56805c08e98)}, {C(ec2332acc6df0c41), C(59f5ee17e20a8263), C(1087d756afcd8e7b), C(a82a7bb790678fc9), C(d197682c421e4373), C(dd78d25c7f0f935a), C(9850cb6fbfee520f), C(a82a7bb790678fc9), C(d197682c421e4373), C(dd78d25c7f0f935a), C(9850cb6fbfee520f), C(2590847398688a46), C(ad266f08713ca5fe), C(25b978be91e830b5), C(2996c8f2b4c8f231)}, {C(aae00b3a289bc82), C(4f6d69f5a5a5b659), C(3ff5abc145614e3), C(33322363b5f45216), C(7e83f1fe4189e843), C(df384b2adfc35b03), C(396ce7790a5ada53), C(33322363b5f45216), C(7e83f1fe4189e843), C(df384b2adfc35b03), C(396ce7790a5ada53), C(c3286e44108b8d36), C(6db8716c498d703f), C(d1db09466f37f4e7), C(56c98e7f68a41388)}, {C(4c842e732fcd25f), C(e7dd7b953cf9c2b2), C(911ee248a76ae3), C(33c6690937582317), C(fe6d61a77985d7bb), C(97b153d04a115535), C(d3fde02e42cfe6df), C(33c6690937582317), C(fe6d61a77985d7bb), C(97b153d04a115535), C(d3fde02e42cfe6df), C(d1c7d1efa52a016), C(1d6ed137f4634c), C(1a260ec505097081), C(8d1e70861a1c7db6)}, {C(40e23ca5817a91f3), C(353e2935809b7ad1), C(f7820021b86391bb), C(f3d41b3d4717eb83), C(2670d457dde68842), C(19707a6732c49278), C(5d0f05a83569ba26), C(f3d41b3d4717eb83), C(2670d457dde68842), C(19707a6732c49278), C(5d0f05a83569ba26), C(6fe5bc84e528816a), C(94df3dca91a29ace), C(420196ed097e8b6f), C(7c52da0e1f043ad6)}, {C(2564527fad710b8d), C(2bdcca8d57f890f), C(81f7bfcd9ea5a532), C(dd70e407984cfa80), C(66996d6066db6e1a), C(36a812bc418b97c9), C(18ea2c63da57f36e), C(dd70e407984cfa80), C(66996d6066db6e1a), C(36a812bc418b97c9), C(18ea2c63da57f36e), C(937fd7ad09be1a8f), C(163b12cab35d5d15), C(3606c3e441335cce), C(949f6ea5bb241ae8)}, {C(6bf70df9d15a2bf6), C(81cad17764b8e0dd), C(58b349a9ba22a7ef), C(9432536dd9f65229), C(192dc54522da3e3d), C(274c6019e0227ca9), C(160abc932a4e4f35), C(9432536dd9f65229), C(192dc54522da3e3d), C(274c6019e0227ca9), C(160abc932a4e4f35), C(1204f2fb5aa79dc6), C(2536edaf890f0760), C(6f2b561f44ff46b4), C(8c7b3e95baa8d984)}, {C(45e6f446eb6bbcf5), C(98ab0ef06f1a7d84), C(85ae96bacca50de6), C(b9aa5bead3352801), C(8a6d9e02a19a4229), C(c352f5b6d5ee1d9d), C(ce562bdb0cfa84fb), C(b9aa5bead3352801), C(8a6d9e02a19a4229), C(c352f5b6d5ee1d9d), C(ce562bdb0cfa84fb), C(d47b768a85283981), C(1fe72557be57a11b), C(95d8afe4af087d51), C(2f59c4e383f30045)}, {C(620d3fe4b8849c9e), C(975a15812a429ec2), C(437c453593dcaf13), C(8d8e7c63385df78e), C(16d55add72a5e25e), C(aa6321421dd87eb5), C(6f27f62e785f0203), C(8d8e7c63385df78e), C(16d55add72a5e25e), C(aa6321421dd87eb5), C(6f27f62e785f0203), C(829030a61078206e), C(ae1f30fcfa445cc8), C(f61f21c9df4ef68d), C(1e5b1945f858dc4c)}, {C(535aa7340b3c168f), C(bed5d3c3cd87d48a), C(266d40ae10f0cbc1), C(ce218d5b44f7825a), C(2ae0c64765800d3a), C(f22dc1ae0728fc01), C(48a171bc666d227f), C(ce218d5b44f7825a), C(2ae0c64765800d3a), C(f22dc1ae0728fc01), C(48a171bc666d227f), C(e7367aff24203c97), C(da39d2be1db3a58d), C(85ce86523003933a), C(dfd4ef2ae83f138a)}, {C(dd3e761d4eada300), C(893d7e4c3bea5bb6), C(cc6d6783bf43eea), C(eb8eed7c391f0044), C(b58961c3abf80753), C(3d75ea687191521), C(389be7bbd8e478f3), C(eb8eed7c391f0044), C(b58961c3abf80753), C(3d75ea687191521), C(389be7bbd8e478f3), C(917070a07441ee47), C(d78efa8cd65b313), C(a8a16f4c1c08c8a1), C(b69cb8ee549eb113)}, {C(4ac1902ccde06545), C(2c44aeb0983a7a07), C(b566035215b309f9), C(64c136fe9404a7b3), C(99f3d8c98a399d5e), C(6319c7cb14180185), C(fbacdbd277d33f4c), C(64c136fe9404a7b3), C(99f3d8c98a399d5e), C(6319c7cb14180185), C(fbacdbd277d33f4c), C(a96a5626c2adda86), C(39ea72fd2ad133ed), C(b5583f2f736df73e), C(ef2c63619782b7ba)}, {C(aee339a23bb00a5e), C(cbb402255318f919), C(9922948e99aa0781), C(df367034233fedc4), C(dcbe14db816586e5), C(f4b1cb814adf21d3), C(f4690695102fa00a), C(df367034233fedc4), C(dcbe14db816586e5), C(f4b1cb814adf21d3), C(f4690695102fa00a), C(6b4f01dd6b76dafc), C(b79388676b50da5d), C(cb64f8bde5ed3393), C(9b422781f13219d3)}, {C(627599e91148df4f), C(3e2d01e8baab062b), C(2daab20edb245251), C(9a958bc3a895a223), C(331058dd6c5d2064), C(46c4d962072094fa), C(e6207c19160e58eb), C(9a958bc3a895a223), C(331058dd6c5d2064), C(46c4d962072094fa), C(e6207c19160e58eb), C(5655e4dbf7272728), C(67b217b1f56c747d), C(3ac0be79691b9a0d), C(9d0954dd0b57073)}, {C(cfb04cf00cfed6b3), C(5fe75fc559af22fa), C(c440a935d72cdc40), C(3ab0d0691b251b8b), C(47181a443504a819), C(9bcaf1253f99f499), C(8ee002b89c1b6b3f), C(3ab0d0691b251b8b), C(47181a443504a819), C(9bcaf1253f99f499), C(8ee002b89c1b6b3f), C(55dfe8eedcd1ec5e), C(1bf50f0bbad796a5), C(9044369a042d7fd6), C(d423df3e3738ba8f)}, {C(942631c47a26889), C(427962c82d8a6e00), C(224071a6592537ff), C(d3e96f4fb479401), C(68b3f2ec11de9368), C(cb51b01083acad4f), C(500cec4564d62aeb), C(d3e96f4fb479401), C(68b3f2ec11de9368), C(cb51b01083acad4f), C(500cec4564d62aeb), C(4ce547491e732887), C(9423883a9a11df4c), C(1a0fc7a14214360), C(9e837914505da6ed)}, {C(4c9eb4e09726b47e), C(fd927483a2b38cf3), C(6d7e56407d1ba870), C(9f5dc7db69fa1e29), C(f42fff56934533d5), C(92d768c230a53918), C(f3360ff11642136c), C(9f5dc7db69fa1e29), C(f42fff56934533d5), C(92d768c230a53918), C(f3360ff11642136c), C(9e989932eb86d1b5), C(449a77f69a8a9d65), C(efabaf8a7789ed9a), C(2798eb4c50c826fd)}, {C(cf7f208ef20e887a), C(f4ce4edeadcaf1a1), C(7ee15226eaf4a74d), C(17ab41ab2ae0705d), C(9dd56694aa2dcd4e), C(dd4fa2add9baced2), C(7ad99099c9e199a3), C(17ab41ab2ae0705d), C(9dd56694aa2dcd4e), C(dd4fa2add9baced2), C(7ad99099c9e199a3), C(a59112144accef0e), C(5838df47e38d251d), C(8750fe45760331e5), C(4b2ce14732e0312a)}, {C(a8dc4687bcf27f4), C(c4aadd7802553f15), C(5401eb9912be5269), C(5c2a2b5b0657a928), C(1e1968ebb38fcb99), C(a082d0e067c4a59c), C(18b616495ad9bf5d), C(5c2a2b5b0657a928), C(1e1968ebb38fcb99), C(a082d0e067c4a59c), C(18b616495ad9bf5d), C(18c5dc6c78a7f9ed), C(b3cc94fe34b68aa1), C(3b77e91292be38cc), C(61d1786ec5097971)}, {C(daed638536ed19df), C(1a762ea5d7ac6f7e), C(48a1cc07a798b84f), C(7f15bdaf50d550f9), C(4c1d48aa621a037e), C(2b1d7a389d497ee0), C(81c6775d46f4b517), C(7f15bdaf50d550f9), C(4c1d48aa621a037e), C(2b1d7a389d497ee0), C(81c6775d46f4b517), C(35296005cbba3ebe), C(db1642f825b53532), C(3e07588a9fd829a4), C(60f13b5446bc7638)}, {C(90a04b11ee1e4af3), C(ab09a35f8f2dff95), C(d7cbe82231ae1e83), C(3262e9017bb788c4), C(1612017731c997bc), C(e789d66134aff5e1), C(275642fd17048af1), C(3262e9017bb788c4), C(1612017731c997bc), C(e789d66134aff5e1), C(275642fd17048af1), C(99255b68d0b46b51), C(74a6f1ad4b2bb296), C(4164222761af840e), C(54d59bf6211a8fe6)}, {C(511f29e1b732617d), C(551cb47a9a83d769), C(df6f56fbda20e7a), C(f27583a930221d44), C(d7d2c46de69b2ed8), C(add24ddd2be4a850), C(5cf2f688dbb93585), C(f27583a930221d44), C(d7d2c46de69b2ed8), C(add24ddd2be4a850), C(5cf2f688dbb93585), C(a7f8e42d5dd4aa00), C(72dc11fd76b4dea9), C(8886f194e6f8e3ff), C(7e8ead04a0e0b1ef)}, {C(95567f03939e651f), C(62a426f09d81d884), C(15cb96e36a8e712c), C(1a2f43bdeaea9c28), C(bca2fd840831291f), C(83446d4a1f7dcc1a), C(449a211df83b6187), C(1a2f43bdeaea9c28), C(bca2fd840831291f), C(83446d4a1f7dcc1a), C(449a211df83b6187), C(553ce97832b2f695), C(3110a2ba303db75), C(b91d6d399a02f453), C(3cb148561e0ef2bb)}, {C(248a32ad10e76bc3), C(dac39c8b036985e9), C(79d38c4af2958b56), C(cc954b4e56275f54), C(700cd864e04e8aaa), C(d6ba03cbff7cc34b), C(da297d7891c9c046), C(cc954b4e56275f54), C(700cd864e04e8aaa), C(d6ba03cbff7cc34b), C(da297d7891c9c046), C(c05d2be8f8ee8114), C(7f4541cbe2ec0025), C(8f0a7a70af6ea926), C(3837ddce693781b5)}, {C(f9f05a2a892242eb), C(de00b6b2e0998460), C(f1f4bd817041497a), C(3deac49eb42a1e26), C(642f77f7c57e84b7), C(2f2c231222651e8b), C(380202ec06bdc29e), C(3deac49eb42a1e26), C(642f77f7c57e84b7), C(2f2c231222651e8b), C(380202ec06bdc29e), C(59abc4ff54765e66), C(8561ea1dddd1f742), C(9ca1f94b0d3f3875), C(b7fa93c3a9fa4ec4)}, {C(3a015cea8c3f5bdf), C(5583521b852fc3ac), C(53d5cd66029a1014), C(ac2eeca7bb04412a), C(daba45cb16ccff2b), C(ddd90b51209e414), C(d90e74ee28cb6271), C(ac2eeca7bb04412a), C(daba45cb16ccff2b), C(ddd90b51209e414), C(d90e74ee28cb6271), C(117027648ca9db68), C(29c1dba39bbcf072), C(787f6bb010a34cd9), C(e099f487e09b847)}, {C(670e43506aa1f71b), C(1cd7929573e54c05), C(cbb00a0aaba5f20a), C(f779909e3d5688d1), C(88211b9117678271), C(59f44f73759a8bc6), C(ef14f73c405123b4), C(f779909e3d5688d1), C(88211b9117678271), C(59f44f73759a8bc6), C(ef14f73c405123b4), C(78775601f11186f), C(fc4641d676fbeed9), C(669ca96b5a2ae5b), C(67b5f0d072025f8d)}, {C(977bb79b58bbd984), C(26d45cfcfb0e9756), C(df8885db518d5f6a), C(6a1d2876488bed06), C(ae35d83c3afb5769), C(33667427d99f9f4e), C(d84c31c17495e3ba), C(6a1d2876488bed06), C(ae35d83c3afb5769), C(33667427d99f9f4e), C(d84c31c17495e3ba), C(31357cded7495ffc), C(295e2eefcd383a2e), C(25063ef4a24c29ae), C(88c694170fcbf0b7)}, {C(e6264fbccd93a530), C(c92f420494e99a7d), C(c14001a298cf976), C(5c8685fee2e4ce55), C(228c49268d6a4345), C(3b04ee2861baec6d), C(7334878a00e96e72), C(5c8685fee2e4ce55), C(228c49268d6a4345), C(3b04ee2861baec6d), C(7334878a00e96e72), C(7317164b2ce711bb), C(e645447e363e8ca1), C(d326d129ad7b4e7f), C(58b9b76d5c2eb272)}, {C(54e4d0cab7ec5c27), C(31ca61d2262a9acc), C(30bd3a50d8082ff6), C(46b3b963bf7e2847), C(b319d04e16ad10b0), C(76c8dd82e6f5a0eb), C(2070363cefb488bc), C(46b3b963bf7e2847), C(b319d04e16ad10b0), C(76c8dd82e6f5a0eb), C(2070363cefb488bc), C(6f9dbacb2bdc556d), C(88a5fb0b293c1e22), C(cb131d9b9abd84b7), C(21db6f0e147a0040)}, {C(882a598e98cf5416), C(36c8dca4a80d9788), C(c386480f07591cfe), C(5b517bcf2005fd9c), C(b9b8f8e5f90e7025), C(2a833e6199e21708), C(bcb7549de5fda812), C(5b517bcf2005fd9c), C(b9b8f8e5f90e7025), C(2a833e6199e21708), C(bcb7549de5fda812), C(44fc96a3cafa1c34), C(fb7724d4899ec7c7), C(4662e3b87df93e13), C(bcf22545acbcfd4e)}, {C(7c37a5376c056d55), C(e0cce8936a06b6f6), C(d32f933fdbec4c7d), C(7ac50423e2be4703), C(546d4b42340d6dc7), C(624f56ee027f12bf), C(5f7f65d1e90c30f9), C(7ac50423e2be4703), C(546d4b42340d6dc7), C(624f56ee027f12bf), C(5f7f65d1e90c30f9), C(d6f15c19625d2621), C(c7afd12394f24b50), C(2c6adde5d249bcd0), C(6c857e6aa07b9fd2)}, {C(21c5e9616f24be97), C(ba3536c86e4b6fe9), C(6d3a65cfe3a9ae06), C(2113903ebd760a31), C(e561f76a5eac8beb), C(86b5b3e76392e166), C(68c8004ccc53e049), C(2113903ebd760a31), C(e561f76a5eac8beb), C(86b5b3e76392e166), C(68c8004ccc53e049), C(b51a28fe4251dd79), C(fd9c2d4d2a84c3c7), C(5bf2ec8a470d2553), C(135a52cdc76241c9)}, {C(a6eaefe74fa7d62b), C(cb34669c751b10eb), C(80da952ad8abd5f3), C(3368262b0e172d82), C(1d51f6c982476285), C(4497675ac57228a9), C(2a71766a71d0b83f), C(3368262b0e172d82), C(1d51f6c982476285), C(4497675ac57228a9), C(2a71766a71d0b83f), C(79ad94d1e9c1dedd), C(cbf1a1c9f23bfa40), C(3ebf24e068cd638b), C(be8e63472edfb462)}, {C(764af88ed4b0b828), C(36946775f20457ce), C(d4bc88ac8281c22e), C(3b2104d68dd9ac02), C(2eca14fcdc0892d0), C(7913b0c09329cd47), C(9373f458938688c8), C(3b2104d68dd9ac02), C(2eca14fcdc0892d0), C(7913b0c09329cd47), C(9373f458938688c8), C(b4448f52a5bf9425), C(9f8c8b90b61ed532), C(78f6774f48e72961), C(e47c00bf9c1206f4)}, {C(5f55a694fb173ea3), C(7db02b80ef5a918b), C(d87ff079f476ca3a), C(1d11117374e0da3), C(744bfbde42106439), C(93a99fab10bb1789), C(246ba292a85d8d7c), C(1d11117374e0da3), C(744bfbde42106439), C(93a99fab10bb1789), C(246ba292a85d8d7c), C(e5bd7838e9edd53a), C(d9c0b104c79d9019), C(ee3dcc7a8e565de5), C(619c9e0a9cf3596d)}, {C(86d086738b0a7701), C(d2402313a4280dda), C(b327aa1a25278366), C(49efdde5d1f98163), C(cbcffcee90f22824), C(951aec1daeb79bab), C(7055e2c70d2eeb4c), C(49efdde5d1f98163), C(cbcffcee90f22824), C(951aec1daeb79bab), C(7055e2c70d2eeb4c), C(1fc0de9399bacb96), C(dab7bbe67901959e), C(375805eccf683ef0), C(bbb6f465c4bae04e)}, {C(acfc8be97115847b), C(c8f0d887bf8d9d1), C(e698fbc6d39bf837), C(61fd1d6b13c1ea77), C(527ed97ff4ae24f0), C(af51a9ebb322c0), C(14f7c25058864825), C(61fd1d6b13c1ea77), C(527ed97ff4ae24f0), C(af51a9ebb322c0), C(14f7c25058864825), C(f40b2bbeaf9f021d), C(80d827160dfdc2d2), C(77baea2e3650486e), C(5de2d256740a1a97)}, {C(dc5ad3c016024d4), C(a0235e954da1a152), C(6daa8a4ed194cc43), C(185e650afc8d39f8), C(adba03a4d40de998), C(9975c776b499b26f), C(9770c59368a43a2), C(185e650afc8d39f8), C(adba03a4d40de998), C(9975c776b499b26f), C(9770c59368a43a2), C(d2776f0cf0e4f66c), C(38eaaabfb743f7f6), C(c066f03d959b3f07), C(9d91c2d52240d546)}, {C(a0e91182f03277f7), C(15c6ebef7376556), C(516f887657ab5a), C(f95050524c7f4b84), C(460dcebbaaa09ae3), C(a9f7a9f0b1b2a961), C(5f8dc5e198e34539), C(f95050524c7f4b84), C(460dcebbaaa09ae3), C(a9f7a9f0b1b2a961), C(5f8dc5e198e34539), C(9c49227ffcff07cb), C(a29388e9fcb794c8), C(475867910d110cba), C(8c9a5cee480b5bac)}, {C(767f1dbd1dba673b), C(1e466a3848a5b01e), C(483eadef1347cd6e), C(a67645c72f54fe24), C(c7a5562c69bd796b), C(e14201a35b55e4a6), C(b3a6d89f19d8f774), C(a67645c72f54fe24), C(c7a5562c69bd796b), C(e14201a35b55e4a6), C(b3a6d89f19d8f774), C(bb4d607ac22bebe5), C(792030edeaa924e0), C(138730dcb60f7e32), C(699d9dcc326c72dc)}, {C(a5e30221500dcd53), C(3a1058d71c9fad93), C(510520710c6444e8), C(a6a5e60c2c1d0108), C(45c8ea4e14bf8c6b), C(213a7235416b86df), C(c186072f80d56ad3), C(a6a5e60c2c1d0108), C(45c8ea4e14bf8c6b), C(213a7235416b86df), C(c186072f80d56ad3), C(2e7be098db59d832), C(d5fa382f3717a0ee), C(b168b26921d243d), C(61601a60c2addfbb)}, {C(ebaed82e48e18ce4), C(cfe6836b65ebe7c7), C(504d9d388684d449), C(bd9c744ee9e3308e), C(faefbb8d296b65d4), C(eba051fe2404c25f), C(250c8510b8931f87), C(bd9c744ee9e3308e), C(faefbb8d296b65d4), C(eba051fe2404c25f), C(250c8510b8931f87), C(3c4a49150dc5676f), C(6c28793c565345c4), C(9df6dd8829a6d8fb), C(760d3a023fab72e7)}, {C(ffa50913362b118d), C(626d52251a8ec3e0), C(76ce4b9dde2e8c5e), C(fc57418d92e52355), C(6b46c559e67a063), C(3f5c269e10690c5c), C(6870de8d49e65349), C(fc57418d92e52355), C(6b46c559e67a063), C(3f5c269e10690c5c), C(6870de8d49e65349), C(88737e5c672de296), C(ca71fca5f4c4f1ce), C(42fca3fa7f60e031), C(4a70246d0d4c2bd8)}, {C(256186bcda057f54), C(fb059b012049fd8e), C(304e07418b5f739b), C(3e166f9fac2eec0b), C(82bc11707ec4a7a4), C(e29acd3851ce36b6), C(9765ca9323d30046), C(3e166f9fac2eec0b), C(82bc11707ec4a7a4), C(e29acd3851ce36b6), C(9765ca9323d30046), C(dab63e7790017f7c), C(b9559988bff0f170), C(48d9ef8aea13eee8), C(e31e47857c511ec2)}, {C(382b15315e84f28b), C(f9a2578b79590b72), C(708936af6d4450e8), C(76a9d4843df75c1c), C(2c33447da3f2c70a), C(5e4dcf2eaeace0d6), C(2ae1727aa7220634), C(76a9d4843df75c1c), C(2c33447da3f2c70a), C(5e4dcf2eaeace0d6), C(2ae1727aa7220634), C(a122f6b52e1130ba), C(a17ae9a21f345e91), C(ff67313f1d0906a9), C(bb16dc0acd6ebecc)}, {C(9983a9cc5576d967), C(29e37689a173109f), C(c526073a91f2808c), C(fe9a9d4a799cf817), C(7ca841999012c0d1), C(8b3abfa4bd2aa28e), C(4ed49274526602eb), C(fe9a9d4a799cf817), C(7ca841999012c0d1), C(8b3abfa4bd2aa28e), C(4ed49274526602eb), C(40995df99063fe23), C(7f51b7ceded05144), C(743c89732b265bf2), C(10c8e1fd835713fd)}, {C(c2c58a843f733bdb), C(516c47c97b4ba886), C(abc3cae0339517db), C(be29af0dad5c9d27), C(70f802599d97fe08), C(23af3f67d941e52b), C(a031edd8b3a008fb), C(be29af0dad5c9d27), C(70f802599d97fe08), C(23af3f67d941e52b), C(a031edd8b3a008fb), C(43431336b198f8fd), C(7c4b60284e1c2245), C(51ee580ddabae1b3), C(ca99bd13845d8f7f)}, {C(648ff27fabf93521), C(d7fba33cbc153035), C(3dbcdcf87ad06c9e), C(52ddbdc9dfd26990), C(d46784cd2aeabb28), C(bd3a15e5e4eb7177), C(b5d7632e19a2cd), C(52ddbdc9dfd26990), C(d46784cd2aeabb28), C(bd3a15e5e4eb7177), C(b5d7632e19a2cd), C(8007450fa355dc04), C(41ca59f64588bb5c), C(66f2ca6b7487499d), C(8098716530db9bea)}, {C(99be55475dcb3461), C(d94ffa462f6ba8dc), C(dbab2b456bdf13bb), C(f28f496e15914b2d), C(1171ce20f49cc87d), C(1b5f514bc1b377a9), C(8a02cb12ec4d6397), C(f28f496e15914b2d), C(1171ce20f49cc87d), C(1b5f514bc1b377a9), C(8a02cb12ec4d6397), C(1c6540740c128d79), C(d085b67114969f41), C(af8c1988085306f3), C(4681f415d9ce8038)}, {C(e16fbb9303dd6d92), C(4d92b99dd164db74), C(3f98f2c9da4f5ce3), C(c65b38c5a47eeed0), C(5c5301c8ee3923a6), C(51bf9f9eddec630e), C(b1cbf1a68be455c2), C(c65b38c5a47eeed0), C(5c5301c8ee3923a6), C(51bf9f9eddec630e), C(b1cbf1a68be455c2), C(c356f5f98499bdb8), C(d897df1ad63fc1d4), C(9bf2a3a69982e93a), C(a2380d43e271bcc8)}, {C(4a57a4899834e4c0), C(836c4df2aac32257), C(cdb66b29e3e12147), C(c734232cbda1eb4c), C(30a3cffff6b9dda0), C(d199313e17cca1ed), C(594d99e4c1360d82), C(c734232cbda1eb4c), C(30a3cffff6b9dda0), C(d199313e17cca1ed), C(594d99e4c1360d82), C(ccc37662829a65b7), C(cae30ff4d2343ce9), C(54da907f7aade4fa), C(5d6e4a0272958922)}, {C(f658958cdf49f149), C(de8e4a622b7a16b), C(a227ebf448c80415), C(3de9e38b3a369785), C(84d160d688c573a9), C(8f562593add0ad54), C(4446b762cc34e6bf), C(3de9e38b3a369785), C(84d160d688c573a9), C(8f562593add0ad54), C(4446b762cc34e6bf), C(2f795f1594c7d598), C(29e05bd1e0dceaff), C(a9a88f2962b49589), C(4b9c86c141ac120b)}, {C(ae1befc65d3ea04d), C(cfd9bc0388c8fd00), C(522f2e1f6cdb31af), C(585447ebe078801a), C(14a31676ec4a2cbd), C(b274e7e6af86a5e1), C(2d487019570bedce), C(585447ebe078801a), C(14a31676ec4a2cbd), C(b274e7e6af86a5e1), C(2d487019570bedce), C(ea1dc9ef3c7b2fcc), C(bde99d4af2f4ee8c), C(64e4c43cd7c43442), C(9b5262ee2eed2f99)}, {C(2fc8f9fc5946296d), C(6a2b94c6765ebfa2), C(f4108b8c79662fd8), C(3a48de4a1e994623), C(6318e6e1ff7bc092), C(84aee2ea26a048fb), C(cf3c393fdad7b184), C(3a48de4a1e994623), C(6318e6e1ff7bc092), C(84aee2ea26a048fb), C(cf3c393fdad7b184), C(28b265bd8985a71e), C(bd3d97dbd76d89a5), C(b04ba1623c0937d), C(b6de821229693515)}, {C(efdb4dc26e84dce4), C(9ce45b6172dffee8), C(c15ad8c8bcaced19), C(f10cc2bcf0475411), C(1126f457c160d8f5), C(34c67f6ea249d5cc), C(3ab7633f4557083), C(f10cc2bcf0475411), C(1126f457c160d8f5), C(34c67f6ea249d5cc), C(3ab7633f4557083), C(3b2e4d8611a03bd7), C(3103d6e63d71c3c9), C(43a56a0b93bb9d53), C(50aa3ae25803c403)}, {C(e84a123b3e1b0c91), C(735cc1d493c5e524), C(287030af8f4ac951), C(fb46abaf4713dda0), C(e8835b9a08cf8cb2), C(3b85a40e6bee4cce), C(eea02a3930757200), C(fb46abaf4713dda0), C(e8835b9a08cf8cb2), C(3b85a40e6bee4cce), C(eea02a3930757200), C(fe7057d5fb18ee87), C(723d258b36eada2a), C(67641393692a716c), C(c8539a48dae2e539)}, {C(686c22d2863c48a6), C(1ee6804e3ddde627), C(8d66184dd34ddac8), C(35ac1bc76c11976), C(fed58f898503280d), C(ab6fcb01c630071e), C(edabf3ec7663c3c9), C(35ac1bc76c11976), C(fed58f898503280d), C(ab6fcb01c630071e), C(edabf3ec7663c3c9), C(591ec5025592b76e), C(918a77179b072163), C(25421d9db4c81e1a), C(96f1b3be51f0b548)}, {C(2c5c1c9fa0ecfde0), C(266a71b430afaec3), C(53ab2d731bd8184a), C(5722f16b15e7f206), C(35bb5922c0946610), C(b8d72c08f927f2aa), C(65f2c378cb9e8c51), C(5722f16b15e7f206), C(35bb5922c0946610), C(b8d72c08f927f2aa), C(65f2c378cb9e8c51), C(cd42fec772c2d221), C(10ccd5d7bacffdd9), C(a75ecb52192f60e2), C(a648f5fe45e5c164)}, {C(7a0ac8dd441c9a9d), C(4a4315964b7377f0), C(24092991c8f27459), C(9c6868d561691eb6), C(78b7016996f98828), C(651e072f06c9e7b7), C(fed953d1251ae90), C(9c6868d561691eb6), C(78b7016996f98828), C(651e072f06c9e7b7), C(fed953d1251ae90), C(7a4d19fdd89e368c), C(d8224d83b6b9a753), C(3a93520a455ee9c9), C(159942bea42b999c)}, {C(c6f9a31dfc91537c), C(b3a250ae029272f8), C(d065fc76d79ec222), C(d2baa99749c71d52), C(5f90a2cfc2a3f637), C(79e4aca7c8bb0998), C(981633149c85c0ba), C(d2baa99749c71d52), C(5f90a2cfc2a3f637), C(79e4aca7c8bb0998), C(981633149c85c0ba), C(5ded415df904b2ee), C(d37d1fc032ebca94), C(ed5b024594967bf7), C(ed7ae636d467e961)}, {C(2d12010eaf7d8d3d), C(eaec74ccd9b76590), C(541338571d45608b), C(e97454e4191065f3), C(afb357655f2a5d1c), C(521ac1614653c130), C(c8a8cac96aa7f32c), C(e97454e4191065f3), C(afb357655f2a5d1c), C(521ac1614653c130), C(c8a8cac96aa7f32c), C(196d7f3f386dfd29), C(1dcd2da5227325cc), C(10e3b9fa712d3405), C(fdf7864ede0856c0)}, {C(f46de22b2d79a5bd), C(e3e198ba766c0a29), C(828d8c137216b797), C(bafdb732c8a29420), C(2ed0b9f4548a9ac3), C(f1ed2d5417d8d1f7), C(451462f90354d097), C(bafdb732c8a29420), C(2ed0b9f4548a9ac3), C(f1ed2d5417d8d1f7), C(451462f90354d097), C(bdd091094408851a), C(c4c1731c1ea46c2c), C(615a2348d60409a8), C(fbc2f058d5539bcc)}, {C(2ce2f3e89fa141fe), C(ac588fe6ab2b719), C(59b848c80739487d), C(423722957b566d10), C(ae4be02664998dc6), C(64017aacfa69ef80), C(28076dddbf65a40a), C(423722957b566d10), C(ae4be02664998dc6), C(64017aacfa69ef80), C(28076dddbf65a40a), C(873bc41acb810f94), C(ac0edafb574b7c0d), C(937d5d5fd95330bf), C(4ea91171e208bd7e)}, {C(8aa75419d95555dd), C(bdb046419d0bf1b0), C(aadf49f217b153da), C(c3cbbe7eb0f5e126), C(fd1809c329311bf6), C(9c26cc255714d79d), C(67093aeb89f5d8c8), C(c3cbbe7eb0f5e126), C(fd1809c329311bf6), C(9c26cc255714d79d), C(67093aeb89f5d8c8), C(265954c61009eaf7), C(a5703e8073eaf83f), C(855382b1aed9c128), C(a6652d5a53d4a008)}, {C(1fbf19dd9207e6aa), C(722834f3c5e43cb7), C(e3c13578c5a69744), C(db9120bc83472135), C(f3d9f715e669cfd5), C(63facc852f487dda), C(9f08fd85a3a78111), C(db9120bc83472135), C(f3d9f715e669cfd5), C(63facc852f487dda), C(9f08fd85a3a78111), C(6c1e5c694b51b7ca), C(bbceb2e47d44f6a1), C(2eb472efe06f8330), C(1844408e2bb87ee)}, {C(6f11f9c1131f1182), C(6f90740debc7bad2), C(8d6e4e2d46ee614b), C(403e3793f0805ac3), C(6278da3d8667a055), C(98eceadb4f237978), C(4daa96284c847b0), C(403e3793f0805ac3), C(6278da3d8667a055), C(98eceadb4f237978), C(4daa96284c847b0), C(ab119ac9f803d770), C(ab893fe847208376), C(f9d9968ae4472ac3), C(b149ff3b35874201)}, {C(92e896d8bfdebdb5), C(2d5c691a0acaeba7), C(377d7f86b7cb2f8b), C(b8a0738135dde772), C(57fb6c9033fc5f35), C(20e628f266e63e1), C(1ad6647eaaa153a3), C(b8a0738135dde772), C(57fb6c9033fc5f35), C(20e628f266e63e1), C(1ad6647eaaa153a3), C(10005c85a89e601a), C(cc9088ed03a78e4a), C(c8d3049b8c0d26a1), C(26e8c0e936cf8cce)}, {C(369ba54df3c534d1), C(972c7d2be5f62834), C(112c8d0cfcc8b1e), C(bcddd22a14192678), C(446cf170a4f05e72), C(c9e992c7a79ce219), C(fa4762e60a93cf84), C(bcddd22a14192678), C(446cf170a4f05e72), C(c9e992c7a79ce219), C(fa4762e60a93cf84), C(b2e11a375a352f), C(a70467d0fd624cf1), C(776b638246febf88), C(e7d1033f7faa39b5)}, {C(bcc4229e083e940e), C(7a42ebe9e8f526b5), C(bb8d1f389b0769ee), C(ae6790e9fe24c57a), C(659a16feab53eb5), C(6fd4cfade750bf16), C(31b1acd328815c81), C(ae6790e9fe24c57a), C(659a16feab53eb5), C(6fd4cfade750bf16), C(31b1acd328815c81), C(8a711090a6ccfd44), C(363240c31681b80e), C(ad791f19de0b07e9), C(d512217d21c7c370)}, {C(17c648f416fb15ca), C(fe4d070d14d71a1d), C(ff22eac66f7eb0d3), C(fa4c10f92facc6c7), C(94cad9e4daecfd58), C(6ffcf829a275d7ef), C(2a35d2436894d549), C(fa4c10f92facc6c7), C(94cad9e4daecfd58), C(6ffcf829a275d7ef), C(2a35d2436894d549), C(c9ea25549513f5a), C(93f7cf06df2d0206), C(ef0da319d38fe57c), C(f715dc84df4f4a75)}, {C(8b752dfa2f9fa592), C(ca95e87b662fe94d), C(34da3aadfa49936d), C(bf1696df6e61f235), C(9724fac2c03e3859), C(d9fd1463b07a8b61), C(f8e397251053d8ca), C(bf1696df6e61f235), C(9724fac2c03e3859), C(d9fd1463b07a8b61), C(f8e397251053d8ca), C(c6d26d868c9e858e), C(2f4a1cb842ed6105), C(6cc48927bd59d1c9), C(469e836d0b7901e1)}, {C(3edda5262a7869bf), C(a15eab8c522050c9), C(ba0853c48707207b), C(4d751c1a836dcda3), C(9747a6e96f1dd82c), C(3c986fc5c9dc9755), C(a9d04f3a92844ecd), C(4d751c1a836dcda3), C(9747a6e96f1dd82c), C(3c986fc5c9dc9755), C(a9d04f3a92844ecd), C(2da9c6cede185e36), C(fae575ef03f987d6), C(b4a6a620b2bee11a), C(8acba91c5813c424)}, {C(b5776f9ceaf0dba2), C(546eee4cee927b0a), C(ce70d774c7b1cf77), C(7f707785c2d807d7), C(1ea8247d40cdfae9), C(4945806eac060028), C(1a14948790321c37), C(7f707785c2d807d7), C(1ea8247d40cdfae9), C(4945806eac060028), C(1a14948790321c37), C(ba3327bf0a6ab79e), C(54e2939592862de8), C(b7d4651234fa11c7), C(d122970552454def)}, {C(313161f3ce61ec83), C(c6c5acb78303987d), C(f00761c6c6e44cee), C(ea660b39d2528951), C(e84537f81a44826a), C(b850bbb69593c26d), C(22499793145e1209), C(ea660b39d2528951), C(e84537f81a44826a), C(b850bbb69593c26d), C(22499793145e1209), C(4c61b993560bbd58), C(636d296abe771743), C(f1861b17b8bc3146), C(cd5fca4649d30f8a)}, {C(6e23080c57f4bcb), C(5f4dad6078644535), C(f1591bc445804407), C(46ca76959d0d4824), C(200b16bb4031e6a5), C(3d0e4718ed5363d2), C(4c8cfcc96382106f), C(46ca76959d0d4824), C(200b16bb4031e6a5), C(3d0e4718ed5363d2), C(4c8cfcc96382106f), C(8d6258d795b8097b), C(23ae7cd1cab4b141), C(cbe74e8fd420afa), C(d553da4575629c63)}, {C(a194c120f440fd48), C(ac0d985eef446947), C(5df9fa7d97244438), C(fce2269035535eba), C(2d9b4b2010a90960), C(2b0952b893dd72f0), C(9a51e8462c1111de), C(fce2269035535eba), C(2d9b4b2010a90960), C(2b0952b893dd72f0), C(9a51e8462c1111de), C(8682b5e0624432a4), C(de8500edda7c67a9), C(4821b171f562c5a2), C(ecb17dea1002e2df)}, {C(3c78f67ee87b62fe), C(274c83c73f20f662), C(25a94c36d3763332), C(7e053f1b873bed61), C(d1c343547cd9c816), C(4deee69b90a52394), C(14038f0f3128ca46), C(7e053f1b873bed61), C(d1c343547cd9c816), C(4deee69b90a52394), C(14038f0f3128ca46), C(ebbf836e38c70747), C(c3c1077b9a7598d0), C(e73c720a27b07ba7), C(ec57f8a9a75af4d9)}, {C(b7d2aee81871e3ac), C(872ac6546cc94ff2), C(a1b0d2f507ad2d8f), C(bdd983653b339252), C(c02783d47ab815f8), C(36c5dc27d64d776c), C(5193988eea7df808), C(bdd983653b339252), C(c02783d47ab815f8), C(36c5dc27d64d776c), C(5193988eea7df808), C(8d8cca9c605cdb4a), C(334904fd32a1f934), C(dbfc15742057a47f), C(f3f92db42ec0cba1)}, {C(41ec0382933e8f72), C(bd5e52d651bf3a41), C(cbf51a6873d4b29e), C(1c8c650bfed2c546), C(9c9085c070350c27), C(e82305be3bded854), C(cf56326bab3d685d), C(1c8c650bfed2c546), C(9c9085c070350c27), C(e82305be3bded854), C(cf56326bab3d685d), C(f94db129adc6cecc), C(1f80871ec4b35deb), C(c0dc1a4c74d63d0), C(d3cac509f998c174)}, {C(7fe4e777602797f0), C(626e62f39f7c575d), C(d15d6185215fee2f), C(f82ef80641514b70), C(e2702de53389d34e), C(9950592b7f2da8d8), C(d6b960bf3503f893), C(f82ef80641514b70), C(e2702de53389d34e), C(9950592b7f2da8d8), C(d6b960bf3503f893), C(95de69e4f131a9b), C(ee6f56eeff9cdefa), C(28f4f86c2b856b72), C(b73d2decaac56b5b)}, {C(aa71127fd91bd68a), C(960f6304500f8069), C(5cfa9758933beba8), C(dcbbdeb1f56b0ac5), C(45164c603d084ce4), C(85693f4ef7e34314), C(e3a3e3a5ec1f6252), C(dcbbdeb1f56b0ac5), C(45164c603d084ce4), C(85693f4ef7e34314), C(e3a3e3a5ec1f6252), C(91f4711c59532bab), C(5e5a61d26f97200b), C(ffa65a1a41da5883), C(5f0e712235371eef)}, {C(677b53782a8af152), C(90d76ef694361f72), C(fa2cb9714617a9e0), C(72c8667cc1e45aa9), C(3a0aa035bbcd1ef6), C(588e89b034fde91b), C(f62e4e1d81c1687), C(72c8667cc1e45aa9), C(3a0aa035bbcd1ef6), C(588e89b034fde91b), C(f62e4e1d81c1687), C(1ea81508efa11e09), C(1cf493a4dcd49aad), C(8217d0fbe8226130), C(607b979c0eb297dd)}, {C(8f97bb03473c860f), C(e23e420f9a32e4a2), C(3432c97895fea7cf), C(69cc85dac0991c6c), C(4a6c529f94e9c36a), C(e5865f8da8c887df), C(27e8c77da38582e0), C(69cc85dac0991c6c), C(4a6c529f94e9c36a), C(e5865f8da8c887df), C(27e8c77da38582e0), C(8e60596b4e327dbc), C(955cf21baa1ddb18), C(c24a8eb9360370aa), C(70d75fd116c2cab1)}, {C(fe50ea9f58e4de6f), C(f0a085b814230ce7), C(89407f0548f90e9d), C(6c595ea139648eba), C(efe867c726ab2974), C(26f48ecc1c3821cf), C(55c63c1b3d0f1549), C(6c595ea139648eba), C(efe867c726ab2974), C(26f48ecc1c3821cf), C(55c63c1b3d0f1549), C(552e5f78e1d87a69), C(c9bfe2747a4eedf0), C(d5230acb6ef95a1), C(1e812f3c0d9962bd)}, {C(56eb0fcb9852bd27), C(c817b9a578c7b12), C(45427842795bfa84), C(8dccc5f52a65030c), C(f89ffa1f4fab979), C(7d94da4a61305982), C(1ba6839d59f1a07a), C(8dccc5f52a65030c), C(f89ffa1f4fab979), C(7d94da4a61305982), C(1ba6839d59f1a07a), C(e0162ec1f40d583e), C(6abf0b85552c7c33), C(f14bb021a875867d), C(c12a569c8bfe3ba7)}, {C(6be2903d8f07af90), C(26aaf7b795987ae8), C(44a19337cb53fdeb), C(f0e14afc59e29a3a), C(a4d0084172a98c0d), C(275998a345d04f0f), C(db73704d81680e8d), C(f0e14afc59e29a3a), C(a4d0084172a98c0d), C(275998a345d04f0f), C(db73704d81680e8d), C(351388cf7529b1b1), C(a3155d0237571da5), C(355231b516da2890), C(263c5a3d498c1cc)}, {C(58668066da6bfc4), C(a4ea2eb7212df3dd), C(481f64f7ca220524), C(11b3b649b1cea339), C(57f4ad5b54d71118), C(feeb30bec803ab49), C(6ed9bcc1973d9bf9), C(11b3b649b1cea339), C(57f4ad5b54d71118), C(feeb30bec803ab49), C(6ed9bcc1973d9bf9), C(bf2859d9964a70c8), C(d31ab162ca25f24e), C(70349336ff55d5d5), C(9a2fa97115ef4409)}, {C(2d04d1fbab341106), C(efe0c5b2878b444c), C(882a2a889b5e8e71), C(18cc96be09e5455), C(1ad58fd26919e409), C(76593521c4a0006b), C(f1361f348fa7cbfb), C(18cc96be09e5455), C(1ad58fd26919e409), C(76593521c4a0006b), C(f1361f348fa7cbfb), C(205bc68e660b0560), C(74360e11f9fc367e), C(a88b7b0fa86caf), C(a982d749b30d4e4c)}, {C(d366b37bcd83805b), C(a6d16fea50466886), C(cb76dfa8eaf74d70), C(389c44e423749aa), C(a30d802bec4e5430), C(9ac1279f92bea800), C(686ef471c2624025), C(389c44e423749aa), C(a30d802bec4e5430), C(9ac1279f92bea800), C(686ef471c2624025), C(2c21a72f8e3a3423), C(df5ab83f0918646a), C(cd876e0cb4df80fa), C(5abbb92679b3ea36)}, {C(bbb9bc819ab65946), C(25e0c756c95803e2), C(82a73a1e1cc9bf6a), C(671b931b702519a3), C(61609e7dc0dd9488), C(9cb329b8cab5420), C(3c64f8ea340096ca), C(671b931b702519a3), C(61609e7dc0dd9488), C(9cb329b8cab5420), C(3c64f8ea340096ca), C(1690afe3befd3afb), C(4d3c18a846602740), C(a6783133a31dd64d), C(ecf4665e6bc76729)}, {C(8e994eac99bbc61), C(84de870b6f3c114e), C(150efc95ce7b0cd2), C(4c5d48abf41185e3), C(86049a83c7cdcc70), C(ad828ff609277b93), C(f60fe028d582ccc7), C(4c5d48abf41185e3), C(86049a83c7cdcc70), C(ad828ff609277b93), C(f60fe028d582ccc7), C(464e0b174da0cbd4), C(eadf1df69041b06e), C(48cb9c96a9df1cdc), C(b7e5ee62809223a1)}, {C(364cabf6585e2f7d), C(3be1cc452509807e), C(1236ce85788680d4), C(4cea77c54fc3583a), C(9a2a64766fd77614), C(63e6c9254b5dc4db), C(26af12ba3bf5988e), C(4cea77c54fc3583a), C(9a2a64766fd77614), C(63e6c9254b5dc4db), C(26af12ba3bf5988e), C(4a821aca3ffa26a1), C(99aa9aacbb3d08e3), C(619ac77b52e8a823), C(68c745a1ce4b7adb)}, {C(e878e2200893d775), C(76b1e0a25867a803), C(9c14d6d91f5ae2c5), C(ac0ffd8d64e242ed), C(e1673ee2dd997587), C(8cdf3e9369d61003), C(c37c9a5258b98eba), C(ac0ffd8d64e242ed), C(e1673ee2dd997587), C(8cdf3e9369d61003), C(c37c9a5258b98eba), C(f252b2e7b67dd012), C(47fc1eb088858f28), C(59c42e4af1353223), C(e05b6c61c19eb26e)}, {C(6f6a014b9a861926), C(269e13a120277867), C(37fc8a181e78711b), C(33dd054c41f3aef2), C(4fc8ab1a2ef3da7b), C(597178c3756a06dc), C(748f8aadc540116f), C(33dd054c41f3aef2), C(4fc8ab1a2ef3da7b), C(597178c3756a06dc), C(748f8aadc540116f), C(78e3be34de99461e), C(28b7b60d90dddab4), C(e47475fa9327a619), C(88b17629e6265924)}, {C(da52b64212e8149b), C(121e713c1692086f), C(f3d63cfa03850a02), C(f0d82bafec3c564c), C(37dece35b549a1ce), C(5fb28f6078c4a2bd), C(b69990b7d9405710), C(f0d82bafec3c564c), C(37dece35b549a1ce), C(5fb28f6078c4a2bd), C(b69990b7d9405710), C(3af5223132071100), C(56d5bb35f3bb5d2a), C(fcad4a4d5d3a1bc7), C(f17bf3d8853724d0)}, {C(1100f797ce53a629), C(f528c6614a1a30c2), C(30e49fb56bec67fa), C(f991664844003cf5), C(d54f5f6c8c7cf835), C(ca9cc4437c591ef3), C(d5871c77cf8fb424), C(f991664844003cf5), C(d54f5f6c8c7cf835), C(ca9cc4437c591ef3), C(d5871c77cf8fb424), C(5cf90f1e617b750c), C(1648f825ab986232), C(936cf225126a60), C(90fa5311d6f2445c)}, {C(4f00655b76e9cfda), C(9dc5c707772ed283), C(b0f885f1e01927ec), C(6e4d6843289dfb47), C(357b41c6e5fd561f), C(491e386bacb6df3c), C(86be1b64ecd9945c), C(6e4d6843289dfb47), C(357b41c6e5fd561f), C(491e386bacb6df3c), C(86be1b64ecd9945c), C(be9547e3cfd85fae), C(f9e26ac346b430a8), C(38508b84b0e68cff), C(a28d49dbd5562703)}, {C(d970198b6ca854db), C(92e3d1786ae556a0), C(99a165d7f0d85cf1), C(6548910c5f668397), C(a5c8d20873e7de65), C(5b7c4ecfb8e38e81), C(6aa50a5531dad63e), C(6548910c5f668397), C(a5c8d20873e7de65), C(5b7c4ecfb8e38e81), C(6aa50a5531dad63e), C(ab903d724449e003), C(ea3cc836c28fef88), C(4b250d6c7200949d), C(13a110654fa916c0)}, {C(76c850754f28803), C(a4bffed2982cb821), C(6710e352247caf63), C(d9cbf5b9c31d964e), C(25c8f890178b97ae), C(e7c46064676cde9f), C(d8bb5eeb49c06336), C(d9cbf5b9c31d964e), C(25c8f890178b97ae), C(e7c46064676cde9f), C(d8bb5eeb49c06336), C(962b35ae89d5f4c1), C(c49083801ac2c21), C(2db46ddec36ff33b), C(da48992ab8da284)}, {C(9c98da9763f0d691), C(f5437139a3d40401), C(6f493c26c42f91e2), C(e857e4ab2d124d5), C(6417bb2f363f36da), C(adc36c9c92193bb1), C(d35bd456172df3df), C(e857e4ab2d124d5), C(6417bb2f363f36da), C(adc36c9c92193bb1), C(d35bd456172df3df), C(577da94064d3a3d6), C(23f13d7532ea496a), C(6e09392d80b8e85b), C(2e05ff6f23663892)}, {C(22f8f6869a5f325), C(a0e7a96180772c26), C(cb71ea6825fa3b77), C(39d3dec4e718e903), C(900c9fbdf1ae2428), C(305301da2584818), C(c6831f674e1fdb1f), C(39d3dec4e718e903), C(900c9fbdf1ae2428), C(305301da2584818), C(c6831f674e1fdb1f), C(8ad0e38ffe71babf), C(554ac85a8a837e64), C(9900c582cf401356), C(169f646b01ed7762)}, {C(9ae7575fc14256bb), C(ab9c5a397fabc1b3), C(1d3f582aaa724b2e), C(94412f598ef156), C(15bf1a588f25b327), C(5756646bd68ce022), C(f062a7d29be259a5), C(94412f598ef156), C(15bf1a588f25b327), C(5756646bd68ce022), C(f062a7d29be259a5), C(aa99c683cfb60b26), C(9e3b7d4b17f91273), C(301d3f5422dd34cf), C(53d3769127253551)}, {C(540040e79752b619), C(670327e237c88cb3), C(50962f261bcc31d9), C(9a8ea2b68b2847ec), C(bc24ab7d4cbbda31), C(df5aff1cd42a9b57), C(db47d368295f4628), C(9a8ea2b68b2847ec), C(bc24ab7d4cbbda31), C(df5aff1cd42a9b57), C(db47d368295f4628), C(9a66c221d1bf3f3), C(7ae74ee1281de8ee), C(a4e173e2c787621f), C(5b51062d10ae472)}, {C(34cbf85722d897b1), C(6208cb2a0fff4eba), C(e926cbc7e86f544e), C(883706c4321efee0), C(8fd5d3d84c7827e4), C(a5c80e455a7ccaaa), C(3515f41164654591), C(883706c4321efee0), C(8fd5d3d84c7827e4), C(a5c80e455a7ccaaa), C(3515f41164654591), C(2c08bfc75dbfd261), C(6e9eadf14f8c965e), C(18783f5770cd19a3), C(a6c7f2f1aa7b59ea)}, {C(46afa66366bf5989), C(aa0d424ac649008b), C(97a9108b3cd9c5c9), C(6ca08e09227a9630), C(8b11f73a8e5b80eb), C(2391bb535dc7ce02), C(e43e2529cf36f4b9), C(6ca08e09227a9630), C(8b11f73a8e5b80eb), C(2391bb535dc7ce02), C(e43e2529cf36f4b9), C(c9bd6d82b7a73d9d), C(b2ed9bae888447ac), C(bd22bb13af0cd06d), C(62781441785b355b)}, {C(e15074b077c6e560), C(7c8f2173fcc34afa), C(8aad55bc3bd38370), C(d407ecdbfb7cb138), C(642442eff44578af), C(d3e9fdaf71a5b79e), C(c87c53eda46aa860), C(d407ecdbfb7cb138), C(642442eff44578af), C(d3e9fdaf71a5b79e), C(c87c53eda46aa860), C(8462310a2c76ff51), C(1bc17a2e0976665e), C(6ec446b13b4d79cf), C(388c7a904b4264c1)}, {C(9740b2b2d6d06c6), C(e738265f9de8dafc), C(fdc947c1fca8be9e), C(d6936b41687c1e3d), C(a1a2deb673345994), C(91501e58b17168bd), C(b8edee2b0b708dfc), C(d6936b41687c1e3d), C(a1a2deb673345994), C(91501e58b17168bd), C(b8edee2b0b708dfc), C(ddf4b43dafd17445), C(44015d050a04ce5c), C(1019fd9ab82c4655), C(c803aea0957bcdd1)}, {C(f1431889f2db1bff), C(85257aa1dc6bd0d0), C(1abbdea0edda5be4), C(775aa89d278f26c3), C(a542d20265e3ef09), C(933bdcac58a33090), C(c43614862666ca42), C(775aa89d278f26c3), C(a542d20265e3ef09), C(933bdcac58a33090), C(c43614862666ca42), C(4c5e54d481a9748d), C(65ce3cd0db838b26), C(9ccbb4005c7f09d2), C(e6dda9555dde899a)}, {C(e2dd273a8d28c52d), C(8cd95915fdcfd96b), C(67c0f5b1025f0699), C(cbc94668d48df4d9), C(7e3d656e49d632d1), C(8329e30cac7a61d4), C(38e6cd1e2034e668), C(cbc94668d48df4d9), C(7e3d656e49d632d1), C(8329e30cac7a61d4), C(38e6cd1e2034e668), C(41e0bce03ed9394b), C(7be48d0158b9834a), C(9ea8d5d1a976b18b), C(606c424c33617e7a)}, {C(e0f79029834cc6ac), C(f2b1dcb87cc5e94c), C(4210bc221fe5e70a), C(fd4a4301d4e2ac67), C(8f84358d25b2999b), C(6c4b7d8a5a22ccbb), C(25df606bb23c9d40), C(fd4a4301d4e2ac67), C(8f84358d25b2999b), C(6c4b7d8a5a22ccbb), C(25df606bb23c9d40), C(915298b0eaadf85b), C(5ec23cc4c6a74e62), C(d640a4ff99763439), C(1603753fb34ad427)}, {C(9dc0a29830bcbec1), C(ec4a01dbd52d96a0), C(cd49c657eff87b05), C(ea487fe948c399e1), C(f5de9b2e59192609), C(4604d9b3248b3a5), C(1929878a22c86a1d), C(ea487fe948c399e1), C(f5de9b2e59192609), C(4604d9b3248b3a5), C(1929878a22c86a1d), C(3cf6cd7c19dfa1ef), C(46e404ee4af2d726), C(613ab0588a5527b5), C(73e39385ced7e684)}, {C(d10b70dde60270a6), C(be0f3b256e23422a), C(6c601297a3739826), C(e327ffc477cd2467), C(ebebba63911f32b2), C(2c2c5c24cf4970a2), C(a3cd2c192c1b8bf), C(e327ffc477cd2467), C(ebebba63911f32b2), C(2c2c5c24cf4970a2), C(a3cd2c192c1b8bf), C(94cb02c94aaf250b), C(30ca38d5e3dac579), C(d68598a91dc597b5), C(162b050e8de2d92)}, {C(58d2459f094d075c), C(b4df247528d23251), C(355283f2128a9e71), C(d046198e4df506c2), C(c61bb9705786ae53), C(b360200380d10da8), C(59942bf009ee7bc), C(d046198e4df506c2), C(c61bb9705786ae53), C(b360200380d10da8), C(59942bf009ee7bc), C(95806d027f8d245e), C(32df87487ed9d0f4), C(e2c5bc224ce97a98), C(9a47c1e33cfb1cc5)}, {C(68c600cdd42d9f65), C(bdf0c331f039ff25), C(1354ac1d98944023), C(b5cdfc0b06fd1bd9), C(71f0ce33b183efab), C(d8ae4f9d4b949755), C(877da19d6424f6b3), C(b5cdfc0b06fd1bd9), C(71f0ce33b183efab), C(d8ae4f9d4b949755), C(877da19d6424f6b3), C(f7cc5cbf76bc6006), C(c93078f44b98efdb), C(3d482142c727e8bc), C(8e23f92e0616d711)}, {C(9fc0bd876cb975da), C(80f41015045d1ade), C(5cbf601fc55c809a), C(7d9c567075001705), C(a2fafeed0df46d5d), C(a70b82990031da8f), C(8611c76abf697e56), C(7d9c567075001705), C(a2fafeed0df46d5d), C(a70b82990031da8f), C(8611c76abf697e56), C(806911617e1ee53), C(1ce82ae909fba503), C(52df85fea9e404bd), C(dbd184e5d9a11a3e)}, {C(7b3e8c267146c361), C(c6ad095af345b726), C(af702ddc731948bd), C(7ca4c883bded44b5), C(c90beb31ee9b699a), C(2cdb4aba3d59b8a3), C(df0d4fa685e938f0), C(7ca4c883bded44b5), C(c90beb31ee9b699a), C(2cdb4aba3d59b8a3), C(df0d4fa685e938f0), C(cc0e568e91aaa382), C(70ca583a464dbea), C(b7a5859b44710e1a), C(ad141467fdf9a83a)}, {C(6c49c6b3c9dd340f), C(897c41d89af37bd1), C(52df69e0e2c68a8d), C(eec4be1f65531a50), C(bf23d928f20f1b50), C(c642009b9c593940), C(c5e59e6ca9e96f85), C(eec4be1f65531a50), C(bf23d928f20f1b50), C(c642009b9c593940), C(c5e59e6ca9e96f85), C(7fbd53343e7da499), C(dd87e7b88afbd251), C(92696e7683b9f322), C(60ff51ef02c24652)}, {C(47324327a4cf1732), C(6044753d211e1dd5), C(1ecae46d75192d3b), C(b6d6315a902807e3), C(ccc8312c1b488e5d), C(b933a7b48a338ec), C(9d6753cd83422074), C(b6d6315a902807e3), C(ccc8312c1b488e5d), C(b933a7b48a338ec), C(9d6753cd83422074), C(5714bd5c0efdc7a8), C(221585e2c88068ca), C(303342b25678904), C(8c174a03e69a76e)}, {C(1e984ef53c5f6aae), C(99ea10dac804298b), C(a3f8c241100fb14d), C(259eb3c63a9c9be6), C(f8991532947c7037), C(a16d20b3fc29cfee), C(493c2e91a775af8c), C(259eb3c63a9c9be6), C(f8991532947c7037), C(a16d20b3fc29cfee), C(493c2e91a775af8c), C(275fccf4acb08abc), C(d13fb6ea3eeaf070), C(505283e5b702b9ea), C(64c092f9f8df1901)}, {C(b88f5c9b8b854cc6), C(54fc5d39825b446), C(a12fc1546eac665d), C(ab90eb7fa58b280c), C(dda26598356aa599), C(64191d63f2586e52), C(cada0075c34e8b02), C(ab90eb7fa58b280c), C(dda26598356aa599), C(64191d63f2586e52), C(cada0075c34e8b02), C(e7de6532b691d87c), C(a28fec86e368624), C(796c280eebd0241a), C(acfcecb641fdbeee)}, {C(9fcb3fdb09e7a63a), C(7a115c9ded150112), C(e9ba629108852f37), C(9b03c7c218c192a), C(93c1dd563f46308e), C(f9553625917ea800), C(e0a52f8a5024c59), C(9b03c7c218c192a), C(93c1dd563f46308e), C(f9553625917ea800), C(e0a52f8a5024c59), C(2bb3a9e8b053e490), C(8b97936723cd8ff6), C(bf3f835246d02722), C(c8e033da88ecd724)}, {C(d58438d62089243), C(d8c19375b228e9d3), C(13042546ed96e790), C(4a42ef343514138c), C(549e62449e225cf1), C(dd8260e2808f68e8), C(69580fc81fcf281b), C(4a42ef343514138c), C(549e62449e225cf1), C(dd8260e2808f68e8), C(69580fc81fcf281b), C(fc0e30d682e87289), C(f44b784248d6107b), C(df25119527fdf209), C(cc265612588171a8)}, {C(7ea73b6b74c8cd0b), C(e07188dd9b5bf3ca), C(6ef62ff2dd008ed4), C(acd94b3038342152), C(1b0ed99c9b7ba297), C(b794a93f4c895939), C(97a60cd93021206d), C(acd94b3038342152), C(1b0ed99c9b7ba297), C(b794a93f4c895939), C(97a60cd93021206d), C(9e0c0e6da5001b07), C(5f5b817de5d2a391), C(35b8a8702acdd533), C(3bbcfef344f455)}, {C(e42ffdf6278bb21), C(59df3e5ca582ff9d), C(f3108785599dbde9), C(f78e8a2d4aba6a1d), C(700473fb0d8380fc), C(d0a0d68061ac74b2), C(11650612fa426e5a), C(f78e8a2d4aba6a1d), C(700473fb0d8380fc), C(d0a0d68061ac74b2), C(11650612fa426e5a), C(e39ceb5b2955710c), C(f559ff201f8cebaa), C(1fbc182809e829a0), C(295c7fc82fa6fb5b)}, {C(9ad37fcd49fe4aa0), C(76d40da71930f708), C(bea08b630f731623), C(797292108901a81f), C(3b94127b18fae49c), C(688247179f144f1b), C(48a507a1625d13d7), C(797292108901a81f), C(3b94127b18fae49c), C(688247179f144f1b), C(48a507a1625d13d7), C(452322aaad817005), C(51d730d973e13d44), C(c883eb30176652ea), C(8d338fd678b2404d)}, {C(27b7ff391136696e), C(60db94a18593438c), C(b5e46d79c4dafbad), C(ad56fd25a6f15289), C(68a0ec7c0179df80), C(a0aacfc36620957), C(87a0762a09e2e1c1), C(ad56fd25a6f15289), C(68a0ec7c0179df80), C(a0aacfc36620957), C(87a0762a09e2e1c1), C(d50ace99460f0be3), C(7f1fe5653ae0d999), C(3870899d9d6c22c), C(df5f952dd90d5a09)}, {C(76bd077e42692ddf), C(c14b60958c2c7a85), C(fd9f3b0b3b1e2738), C(273d2c51a8e65e71), C(ac531423f670bf34), C(7f40c6bfb8c5758a), C(5fde65b433a10b02), C(273d2c51a8e65e71), C(ac531423f670bf34), C(7f40c6bfb8c5758a), C(5fde65b433a10b02), C(dbda6c4252b0a75c), C(5d4cfd8f937b23d9), C(3895f478e1c29c9d), C(e3e7c1fd1199aec6)}, {C(81c672225442e053), C(927c3f6c8964050e), C(cb59f8f2bb36fac5), C(298f3583326fd942), C(b85602a9a2e2f97c), C(65c849bfa3191459), C(bf21329dfb496c0d), C(298f3583326fd942), C(b85602a9a2e2f97c), C(65c849bfa3191459), C(bf21329dfb496c0d), C(ea7b7b44c596aa18), C(c18bfb6e9a36d59c), C(1b55f03e8a38cc0a), C(b6a94cd47bbf847f)}, {C(37b9e308747448ca), C(513f39f5545b1bd), C(145b32114ca00f9c), C(cce24b9910eb0489), C(af4ac64668ac57d9), C(ea0e44c13a9a5d5e), C(b224fb0c680455f4), C(cce24b9910eb0489), C(af4ac64668ac57d9), C(ea0e44c13a9a5d5e), C(b224fb0c680455f4), C(a7714bbba8699be7), C(fecad6e0e0092204), C(c1ce8bd5ac247eb4), C(3993aef5c07cdca2)}, {C(dab71695950a51d4), C(9e98e4dfa07566fe), C(fab3587513b84ec0), C(2409f60f0854f305), C(b17f6e6c8ff1894c), C(62fa048551dc7ad6), C(d99f4fe2799bad72), C(2409f60f0854f305), C(b17f6e6c8ff1894c), C(62fa048551dc7ad6), C(d99f4fe2799bad72), C(4a38e7f2f4a669d3), C(53173510ca91f0e3), C(cc9096c0df860b0), C(52ed637026a4a0d5)}, {C(28630288285c747b), C(a165a5bf51aaec95), C(927d211f27370016), C(727c782893d30c22), C(742706852989c247), C(c546494c3bb5e7e2), C(1fb2a5d1570f5dc0), C(727c782893d30c22), C(742706852989c247), C(c546494c3bb5e7e2), C(1fb2a5d1570f5dc0), C(71e498804df91b76), C(4a6a5aa6f7e5621), C(871a63730d13a544), C(63f77c8f371cc2f8)}, {C(4b591ad5160b6c1b), C(e8f85ddd5a1143f7), C(377e18171476d64), C(829481773cce2cb1), C(c9d9fb4e25e4d243), C(c1fff894f0cf713b), C(69edd73ec20984b0), C(829481773cce2cb1), C(c9d9fb4e25e4d243), C(c1fff894f0cf713b), C(69edd73ec20984b0), C(7fb1132262925f4a), C(a292e214fe56794f), C(915bfee68e16f46f), C(98bcc857bb6d31e7)}, {C(7e02f7a5a97dd3df), C(9724a88ac8c30809), C(d8dee12589eeaf36), C(c61f8fa31ad1885b), C(3e3744e04485ff9a), C(939335b37f34c7a2), C(faa5de308dbbbc39), C(c61f8fa31ad1885b), C(3e3744e04485ff9a), C(939335b37f34c7a2), C(faa5de308dbbbc39), C(f5996b1be7837a75), C(4fcb12d267f5af4f), C(39be67b8cd132169), C(5c39e3819198b8a1)}, {C(ff66660873521fb2), C(d82841f7e714ce03), C(c830d273f005e378), C(66990c8c54782228), C(4f28bea83dda97c), C(6a24c64698688de0), C(69721141111da99b), C(66990c8c54782228), C(4f28bea83dda97c), C(6a24c64698688de0), C(69721141111da99b), C(d5c771fade83931b), C(8094ed75e6feb396), C(7a79d4de8efd1a2c), C(5f9e50167693e363)}, {C(ef3c4dd60fa37412), C(e8d2898c86d11327), C(8c883d860aafacfe), C(a4ace72ba19d6de5), C(4cae26627dfc5511), C(38e496de9f677b05), C(558770996e1906d6), C(a4ace72ba19d6de5), C(4cae26627dfc5511), C(38e496de9f677b05), C(558770996e1906d6), C(40df30e332ceca69), C(8f106cbd94166c42), C(332b6ab4f4c1014e), C(7c0bc3092ad850e5)}, {C(a7b07bcb1a1333ba), C(9d007956720914c3), C(4751f60ef2b15545), C(77ac4dcee10c9023), C(e90235108fa20e56), C(1d3ea38535215800), C(5ed1ccfff26bc64), C(77ac4dcee10c9023), C(e90235108fa20e56), C(1d3ea38535215800), C(5ed1ccfff26bc64), C(789a1c352bf5c61e), C(860a119056da8252), C(a6c268a238699086), C(4d70f5cccf4ef2eb)}, {C(89858fc94ee25469), C(f72193b78aeaa896), C(7dba382760727c27), C(846b72f372f1685a), C(f708db2fead5433c), C(c04e121770ee5dc), C(4619793b67d0daa4), C(846b72f372f1685a), C(f708db2fead5433c), C(c04e121770ee5dc), C(4619793b67d0daa4), C(79f80506f152285f), C(5300074926fccd56), C(7fbbff6cc418fce6), C(b908f77c676b32e4)}, {C(e6344d83aafdca2e), C(6e147816e6ebf87), C(8508c38680732caf), C(f4ce36d3a375c981), C(9d67e5572f8d7bf4), C(900d63d9ec79e477), C(5251c85ab52839a3), C(f4ce36d3a375c981), C(9d67e5572f8d7bf4), C(900d63d9ec79e477), C(5251c85ab52839a3), C(92ec4b3952e38027), C(40b2dc421a518cbf), C(661ea97b2331a070), C(8d428a4a9485179b)}, {C(3ddbb400198d3d4d), C(fe73de3ada21af5c), C(cd7df833dacd8da3), C(162be779eea87bf8), C(7d62d36edf759e6d), C(dc20f528362e37b2), C(1a902edfe4a5824e), C(162be779eea87bf8), C(7d62d36edf759e6d), C(dc20f528362e37b2), C(1a902edfe4a5824e), C(e6a258d30fa817ba), C(c5d73adf6fb196fd), C(475b7a6286a207fb), C(d35f96363e8eba95)}, {C(79d4c20cf83a7732), C(651ea0a6ab059bcd), C(94631144f363cdef), C(894a0ee0c1f87a22), C(4e682573f8b38f25), C(89803fc082816289), C(71613963a02d90e1), C(894a0ee0c1f87a22), C(4e682573f8b38f25), C(89803fc082816289), C(71613963a02d90e1), C(4c6cc0e5a737c910), C(a3765b5da16bccd9), C(8bf483c4d735ec96), C(7fd7c8ba1934afec)}, {C(5aaf0d7b669173b5), C(19661ca108694547), C(5d03d681639d71fe), C(7c422f4a12fd1a66), C(aa561203e7413665), C(e99d8d202a04d573), C(6090357ec6f1f1), C(7c422f4a12fd1a66), C(aa561203e7413665), C(e99d8d202a04d573), C(6090357ec6f1f1), C(dbfe89f01f0162e), C(49aa89da4f1e389b), C(7119a6f4514efb22), C(56593f6b4e7318d9)}, {C(35d6cc883840170c), C(444694c4f8928732), C(98500f14b8741c6), C(5021ac9480077dd), C(44c2ebc11cfb9837), C(e5d310c4b5c1d9fd), C(a577102c33ac773c), C(5021ac9480077dd), C(44c2ebc11cfb9837), C(e5d310c4b5c1d9fd), C(a577102c33ac773c), C(a00d2efd2effa3cf), C(c2c33ffcda749df6), C(d172099d3b6f2986), C(f308fe33fcd23338)}, {C(b07eead7a57ff2fe), C(c1ffe295ca7dbf47), C(ef137b125cfa8851), C(8f8eec5cde7a490a), C(79916d20a405760b), C(3c30188c6d38c43c), C(b17e3c3ff7685e8d), C(8f8eec5cde7a490a), C(79916d20a405760b), C(3c30188c6d38c43c), C(b17e3c3ff7685e8d), C(ac8aa3cd0790c4c9), C(78ca60d8bf10f670), C(26f522be4fbc1184), C(55bc7688083326d4)}, {C(20fba36c76380b18), C(95c39353c2a3477d), C(4f362902cf9117ad), C(89816ec851e3f405), C(65258396f932858d), C(b7dcaf3cc57a0017), C(b368f482afc90506), C(89816ec851e3f405), C(65258396f932858d), C(b7dcaf3cc57a0017), C(b368f482afc90506), C(88f08c74465015f1), C(94ebaf209d59099d), C(c1b7ff7304b0a87), C(56bf8235257d4435)}, {C(c7e9e0c45afeab41), C(999d95f41d9ee841), C(55ef15ac11ea010), C(cc951b8eab5885d), C(956c702c88ac056b), C(de355f324a37e3c0), C(ed09057eb60bd463), C(cc951b8eab5885d), C(956c702c88ac056b), C(de355f324a37e3c0), C(ed09057eb60bd463), C(1f44b6d04a43d088), C(53631822a26ba96d), C(90305fc2d21f8d28), C(60693a9a6093351a)}, {C(69a8e59c1577145d), C(cb04a6e309ebc626), C(9b3326a5b250e9b1), C(d805f665265fd867), C(82b2b019652c19c6), C(f0df7738353c82a6), C(6a9acf124383ca5f), C(d805f665265fd867), C(82b2b019652c19c6), C(f0df7738353c82a6), C(6a9acf124383ca5f), C(6838374508a7a99f), C(7b6719db8d3e40af), C(1a22666cf0dcb7cf), C(989a9cf7f46b434d)}, {C(6638191337226509), C(42b55e08e4894870), C(a7696f5fbd51878e), C(433bbdd27481d85d), C(ee32136b5a47bbec), C(769a77f346d82f4e), C(38b91b1cb7e34be), C(433bbdd27481d85d), C(ee32136b5a47bbec), C(769a77f346d82f4e), C(38b91b1cb7e34be), C(cb10fd95c0e43875), C(ce9744efd6f11427), C(946b32bddada6a13), C(35d544690b99e3b6)}, {C(c44e8c33ff6c5e13), C(1f128a22aab3007f), C(6a8b41bf04cd593), C(1b9b0deaf126522a), C(cc51d382baedc2eb), C(8df8831bb2e75daa), C(de4e7a4b5de99588), C(1b9b0deaf126522a), C(cc51d382baedc2eb), C(8df8831bb2e75daa), C(de4e7a4b5de99588), C(55a2707103a9f968), C(e0063f4e1649702d), C(7e82f5b440e74043), C(649b44a27f00219d)}, {C(68125009158bded7), C(563a9a62753fc088), C(b97a9873a352cf6a), C(237d1de15ae56127), C(b96445f758ba57d), C(b842628a9f9938eb), C(70313d232dc2cd0d), C(237d1de15ae56127), C(b96445f758ba57d), C(b842628a9f9938eb), C(70313d232dc2cd0d), C(8bfe1f78cb40ad5b), C(a5bde811d49f56e1), C(1acd0cf913ded507), C(820b3049fa5e6786)}, {C(e0dd644db35a62d6), C(292889772752ab42), C(b80433749dbb8793), C(7032fe67035f95db), C(d8076d1fda17eb8d), C(115ca1775560f946), C(92da1e16f396bf61), C(7032fe67035f95db), C(d8076d1fda17eb8d), C(115ca1775560f946), C(92da1e16f396bf61), C(17c8bc7f6d23a639), C(fb28a2afa4d562a9), C(6c59c95fa2450d5f), C(fe0d41d5ebfbce2a)}, {C(21ce9eab220aaf87), C(27d20caec922d708), C(610c51f976cb1d30), C(6052f97a1e02d2ba), C(836eea7ce63dea17), C(e1f8efb81b443b45), C(ddbdbbe717570246), C(6052f97a1e02d2ba), C(836eea7ce63dea17), C(e1f8efb81b443b45), C(ddbdbbe717570246), C(69551045b0e56f60), C(625a435960ba7466), C(9cdb004e8b11405c), C(d6284db99a3b16af)}, {C(83b54046fdca7c1e), C(e3709e9153c01626), C(f306b5edc2682490), C(88f14b0b554fba02), C(a0ec13fac0a24d0), C(f468ebbc03b05f47), C(a9cc417c8dad17f0), C(88f14b0b554fba02), C(a0ec13fac0a24d0), C(f468ebbc03b05f47), C(a9cc417c8dad17f0), C(4c1ababa96d42275), C(c112895a2b751f17), C(5dd7d9fa55927aa9), C(ca09db548d91cd46)}, {C(dd3b2ce7dabb22fb), C(64888c62a5cb46ee), C(f004e8b4b2a97362), C(31831cf3efc20c84), C(901ba53808e677ae), C(4b36895c097d0683), C(7d93ad993f9179aa), C(31831cf3efc20c84), C(901ba53808e677ae), C(4b36895c097d0683), C(7d93ad993f9179aa), C(a4c5ea29ae78ba6b), C(9cf637af6d607193), C(5731bd261d5b3adc), C(d59a9e4f796984f3)}, {C(9ee08fc7a86b0ea6), C(5c8d17dff5768e66), C(18859672bafd1661), C(d3815c5f595e513e), C(44b3bdbdc0fe061f), C(f5f43b2a73ad2df5), C(7c0e6434c8d7553c), C(d3815c5f595e513e), C(44b3bdbdc0fe061f), C(f5f43b2a73ad2df5), C(7c0e6434c8d7553c), C(8c05859060821002), C(73629a0d275008ce), C(860c012879e6f00f), C(d48735a120d2c37c)}, {C(4e2a10f1c409dfa5), C(6e684591f5da86bd), C(ff8c9305d447cadb), C(c43ae49df25b1c86), C(d4f42115cee1ac8), C(a0e6a714471b975c), C(a40089dec5fe07b0), C(c43ae49df25b1c86), C(d4f42115cee1ac8), C(a0e6a714471b975c), C(a40089dec5fe07b0), C(18c3d8f967915e10), C(739c747dbe05adfb), C(4b0397b596e16230), C(3c57d7e1de9e58d1)}, {C(bdf3383d7216ee3c), C(eed3a37e4784d324), C(247cff656d081ba0), C(76059e4cb25d4700), C(e0af815fe1fa70ed), C(5a6ccb4f36c5b3df), C(391a274cd5f5182d), C(76059e4cb25d4700), C(e0af815fe1fa70ed), C(5a6ccb4f36c5b3df), C(391a274cd5f5182d), C(ff1579baa6a2b511), C(c385fc5062e8a728), C(e940749739a37c78), C(a093523a5b5edee5)}, {C(a22e8f6681f0267d), C(61e79bc120729914), C(86ec13c84c1600d3), C(1614811d59dcab44), C(d1ddcca9a2675c33), C(f3c551d5fa617763), C(5c78d4181402e98c), C(1614811d59dcab44), C(d1ddcca9a2675c33), C(f3c551d5fa617763), C(5c78d4181402e98c), C(b43b4a9caa6f5d4c), C(f112829bca2df8f3), C(87e5c85db80d06c3), C(8eb4bac85453409)}, {C(6997121cae0ce362), C(ba3594cbcc299a07), C(7e4b71c7de25a5e4), C(16ad89e66db557ba), C(a43c401140ffc77d), C(3780a8b3fd91e68), C(48190678248a06b5), C(16ad89e66db557ba), C(a43c401140ffc77d), C(3780a8b3fd91e68), C(48190678248a06b5), C(d10deb97b651ad42), C(3a69f3f29046a24f), C(f7179735f2c6dab4), C(ac82965ad3b67a02)}, {C(9bfc2c3e050a3c27), C(dc434110e1059ff3), C(5426055da178decd), C(cb44d00207e16f99), C(9d9e99afedc8107f), C(56907c4fb7b3bc01), C(bcff1472bb01f85a), C(cb44d00207e16f99), C(9d9e99afedc8107f), C(56907c4fb7b3bc01), C(bcff1472bb01f85a), C(516f800f74ad0985), C(f93193ade9614da4), C(9f4a7845355b75b7), C(423c17045824dea5)}, {C(a3f37e415aedf14), C(8d21c92bfa0dc545), C(a2715ebb07deaf80), C(98ce1ff2b3f99f0f), C(162acfd3b47c20bf), C(62b9a25fd39dc6c0), C(c165c3c95c878dfe), C(98ce1ff2b3f99f0f), C(162acfd3b47c20bf), C(62b9a25fd39dc6c0), C(c165c3c95c878dfe), C(2b9a7e1f055bd27c), C(e91c8099cafaa75d), C(37e38d64ef0263b), C(a46e89f47a1a70d5)}, {C(cef3c748045e7618), C(41dd44faef4ca301), C(6add718a88f383c6), C(1197eca317e70a93), C(61f9497e6cc4a33), C(22e7178d1e57af73), C(5df95da0ff1c6435), C(1197eca317e70a93), C(61f9497e6cc4a33), C(22e7178d1e57af73), C(5df95da0ff1c6435), C(934327643705e56c), C(11eb0eec553137c9), C(1e6b9b57ac5283ec), C(6934785db184b2e4)}, {C(fe2b841766a4d212), C(42cf817e58fe998c), C(29f7f493ba9cbe6c), C(2a9231d98b441827), C(fca55e769df78f6c), C(da87ea680eb14df4), C(e0b77394b0fd2bcc), C(2a9231d98b441827), C(fca55e769df78f6c), C(da87ea680eb14df4), C(e0b77394b0fd2bcc), C(f36a2a3c73ab371a), C(d52659d36d93b71), C(3d3b7d2d2fafbb14), C(b4b7b317d9266711)}, {C(d6131e688593a181), C(5b658b282688ccd3), C(b9f7c066beed1204), C(e9dd79bad89f6b19), C(b420092bae6aaf41), C(515f9bbd06069d77), C(80664957a02cbc29), C(e9dd79bad89f6b19), C(b420092bae6aaf41), C(515f9bbd06069d77), C(80664957a02cbc29), C(f9dc7a744a56d9b3), C(7eb2bdcd6667f383), C(c5914296fbdaf9d1), C(af0d5a8fec374fc4)}, {C(91288884ebfcf145), C(3dffd892d36403af), C(7c4789db82755080), C(634acbe037edec27), C(878a97fab822d804), C(fcb042af908f0577), C(4cbafc318bb90a2e), C(634acbe037edec27), C(878a97fab822d804), C(fcb042af908f0577), C(4cbafc318bb90a2e), C(68a96d589d5e5654), C(a752cb250bca1bc0), C(8f228f406024aa7e), C(fc5408cf22a080b5)}, {C(754c7e98ae3495ea), C(2030124a22512c19), C(ec241579c626c39d), C(e682b5c87fa8e41b), C(6cfa4baff26337ac), C(4d66358112f09b2a), C(58889d3f50ffa99c), C(33fc6ffd1ffb8676), C(36db7617b765f6e2), C(8df41c03c514a9dc), C(6707cc39a809bb74), C(3f27d7bb79e31984), C(a39dc6ac6cb0b0a8), C(33fc6ffd1ffb8676), C(36db7617b765f6e2)}, }; void Check(uint64 expected, uint64 actual) { if (expected != actual) { cerr << "ERROR: expected 0x" << hex << expected << ", but got 0x" << actual << "\n"; ++errors; } } void Test(const uint64* expected, int offset, int len) { const uint128 u = CityHash128(data + offset, len); const uint128 v = CityHash128WithSeed(data + offset, len, kSeed128); Check(expected[0], CityHash64(data + offset, len)); Check(expected[1], CityHash64WithSeed(data + offset, len, kSeed0)); Check(expected[2], CityHash64WithSeeds(data + offset, len, kSeed0, kSeed1)); Check(expected[3], Uint128Low64(u)); Check(expected[4], Uint128High64(u)); Check(expected[5], Uint128Low64(v)); Check(expected[6], Uint128High64(v)); #ifdef __SSE4_2__ const uint128 y = CityHashCrc128(data + offset, len); const uint128 z = CityHashCrc128WithSeed(data + offset, len, kSeed128); uint64 crc256_results[4]; CityHashCrc256(data + offset, len, crc256_results); Check(expected[7], Uint128Low64(y)); Check(expected[8], Uint128High64(y)); Check(expected[9], Uint128Low64(z)); Check(expected[10], Uint128High64(z)); for (int i = 0; i < 4; i++) { Check(expected[11 + i], crc256_results[i]); } #endif } #else #define Test(a, b, c) Dump((b), (c)) void Dump(int offset, int len) { const uint128 u = CityHash128(data + offset, len); const uint128 v = CityHash128WithSeed(data + offset, len, kSeed128); const uint128 y = CityHashCrc128(data + offset, len); const uint128 z = CityHashCrc128WithSeed(data + offset, len, kSeed128); uint64 crc256_results[4]; CityHashCrc256(data + offset, len, crc256_results); cout << hex << "{C(" << CityHash64(data + offset, len) << "), " << "C(" << CityHash64WithSeed(data + offset, len, kSeed0) << "), " << "C(" << CityHash64WithSeeds(data + offset, len, kSeed0, kSeed1) << "), " << "C(" << Uint128Low64(u) << "), " << "C(" << Uint128High64(u) << "), " << "C(" << Uint128Low64(v) << "), " << "C(" << Uint128High64(v) << "),\n" << "C(" << Uint128Low64(y) << "), " << "C(" << Uint128High64(y) << "), " << "C(" << Uint128Low64(z) << "), " << "C(" << Uint128High64(z) << "),\n"; for (int i = 0; i < 4; i++) { cout << hex << "C(" << crc256_results[i] << (i == 3 ? ")},\n" : "), "); } } #endif int main(int argc, char** argv) { setup(); int i = 0; for ( ; i < kTestSize - 1; i++) { Test(testdata[i], i * i, i); } Test(testdata[i], 0, kDataSize); return errors > 0; } dlt-daemon-2.18.4/src/core_dump_handler/cityhash_c/city_c.c000066400000000000000000000425131353342203500236340ustar00rootroot00000000000000/* Copyright (c) 2011 Google, Inc. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining a copy */ /* of this software and associated documentation files (the "Software"), to deal */ /* in the Software without restriction, including without limitation the rights */ /* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell */ /* copies of the Software, and to permit persons to whom the Software is */ /* furnished to do so, subject to the following conditions: */ /* */ /* The above copyright notice and this permission notice shall be included in */ /* all copies or substantial portions of the Software. */ /* */ /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR */ /* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, */ /* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE */ /* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER */ /* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, */ /* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN */ /* THE SOFTWARE. */ /* */ /* CityHash, by Geoff Pike and Jyrki Alakuijala */ /* */ /* This file provides CityHash64() and related functions. */ /* */ /* It's probably possible to create even faster hash functions by */ /* writing a program that systematically explores some of the space of */ /* possible hash functions, by using SIMD instructions, or by */ /* compromising on hash quality. */ #include "city_c.h" #include #if defined(__sparc) || defined(__sparc__) \ || defined(_POWER) || defined(__powerpc__) \ || defined(__ppc__) || defined(__hpux) || defined(__hppa) \ || defined(_MIPSEB) || defined(_POWER) \ || defined(__s390__) # define WORDS_BIGENDIAN #elif defined(__i386__) || defined(__alpha__) \ || defined(__ia64) || defined(__ia64__) \ || defined(_M_IX86) || defined(_M_IA64) \ || defined(_M_ALPHA) || defined(__amd64) \ || defined(__amd64__) || defined(_M_AMD64) \ || defined(__x86_64) || defined(__x86_64__) \ || defined(_M_X64) || defined(__bfin__) # define WORDS_LITTLEENDIAN #endif #if !defined(WORDS_BIGENDIAN) # define uint32_in_expected_order(x) (x) # define uint64_in_expected_order(x) (x) #else # if defined _MSC_VER # include # define bswap_32(x) _byteswap_ulong(x) # define bswap_64(x) _byteswap_uint64(x) # elif defined(__APPLE__) /* Mac OS X / Darwin features */ # include # define bswap_32(x) OSSwapInt32(x) # define bswap_64(x) OSSwapInt64(x) # else # include # endif # define uint32_in_expected_order(x) (bswap_32(x)) # define uint64_in_expected_order(x) (bswap_64(x)) #endif /* WORDS_BIGENDIAN */ #if !defined inline # ifdef _MSC_VER # define inline __inline # endif #endif #if !defined LIKELY # if defined __GNUC__ && (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96))/*GCC 2.96 above */ # define LIKELY(x) (__builtin_expect(!!(x), 1)) # else # define LIKELY(x) (x) # endif #endif #define UNSAFE_SWAP(type, a, b) do { type tmp; tmp = (a); (a) = (b); (b) = tmp; } while (0) static inline uint128 UInt128(uint64 low, uint64 high) { uint128 val; val.first = low; val.second = high; return val; } static inline uint64 UNALIGNED_LOAD64(const char *p) { uint64 result; memcpy(&result, p, sizeof(result)); return result; } static inline uint32 UNALIGNED_LOAD32(const char *p) { uint32 result; memcpy(&result, p, sizeof(result)); return result; } static uint64 Hash64Pairto64(uint64 u, uint64 v) { /* Murmur-inspired hashing. */ static const uint64 kMul = 0x9ddfea08eb382d69ULL; uint64 a, b; a = (u ^ v) * kMul; a ^= (a >> 47); b = (v ^ a) * kMul; b ^= (b >> 47); b *= kMul; return b; } static inline uint64 Fetch64(const char *p) { return uint64_in_expected_order(UNALIGNED_LOAD64(p)); } static inline uint32 Fetch32(const char *p) { return uint32_in_expected_order(UNALIGNED_LOAD32(p)); } /* Some primes between 2^63 and 2^64 for various uses. */ static const uint64 k0 = 0xc3a5c85c97cb3127ULL; static const uint64 k1 = 0xb492b66fbe98f273ULL; static const uint64 k2 = 0x9ae16a3b2f90404fULL; static const uint64 k3 = 0xc949d7c7509e6557ULL; /* Bitwise right rotate. Normally this will compile to a single */ /* instruction, especially if the shift is a manifest constant. */ static inline uint64 Rotate(uint64 val, int shift) { /* Avoid shifting by 64: doing so yields an undefined result. */ return shift == 0 ? val : ((val >> shift) | (val << (64 - shift))); } /* Equivalent to Rotate(), but requires the second arg to be non-zero. */ /* On x86-64, and probably others, it's possible for this to compile */ /* to a single instruction if both args are already in registers. */ static inline uint64 RotateByAtLeast1(uint64 val, int shift) { return (val >> shift) | (val << (64 - shift)); } static inline uint64 ShiftMix(uint64 val) { return val ^ (val >> 47); } static inline uint64 HashLen16(uint64 u, uint64 v) { /*return Hash128to64(uint128(u, v)); */ return Hash64Pairto64(u, v); } static uint64 HashLen0to16(const char *s, size_t len) { if (len > 8) { uint64 a = Fetch64(s); uint64 b = Fetch64(s + len - 8); return HashLen16(a, RotateByAtLeast1(b + len, len)) ^ b; } if (len >= 4) { uint64 a = Fetch32(s); return HashLen16(len + (a << 3), Fetch32(s + len - 4)); } if (len > 0) { uint8 a = s[0]; uint8 b = s[len >> 1]; uint8 c = s[len - 1]; uint32 y = (uint32)a + ((uint32)b << 8); uint32 z = len + ((uint32)c << 2); return ShiftMix(y * k2 ^ z * k3) * k2; } return k2; } /* This probably works well for 16-byte strings as well, but it may be overkill */ /* in that case. */ static uint64 HashLen17to32(const char *s, size_t len) { uint64 a = Fetch64(s) * k1; uint64 b = Fetch64(s + 8); uint64 c = Fetch64(s + len - 8) * k2; uint64 d = Fetch64(s + len - 16) * k0; return HashLen16(Rotate(a - b, 43) + Rotate(c, 30) + d, a + Rotate(b ^ k3, 20) - c + len); } /* Return a 16-byte hash for 48 bytes. Quick and dirty. */ /* Callers do best to use "random-looking" values for a and b. */ static uint128 WeakHashLen32WithSeeds6(uint64 w, uint64 x, uint64 y, uint64 z, uint64 a, uint64 b) { uint64 c; a += w; b = Rotate(b + a + z, 21); c = a; a += x; a += y; b += Rotate(a, 44); return UInt128(a + z, b + c); } /* Return a 16-byte hash for s[0] ... s[31], a, and b. Quick and dirty. */ static uint128 WeakHashLen32WithSeeds3(const char *s, uint64 a, uint64 b) { return WeakHashLen32WithSeeds6(Fetch64(s), Fetch64(s + 8), Fetch64(s + 16), Fetch64(s + 24), a, b); } /* Return an 8-byte hash for 33 to 64 bytes. */ static uint64 HashLen33to64(const char *s, size_t len) { uint64 z = Fetch64(s + 24); uint64 a = Fetch64(s) + (len + Fetch64(s + len - 16)) * k0; uint64 b = Rotate(a + z, 52); uint64 c = Rotate(a, 37); uint64 vf, vs, wf, ws, r; a += Fetch64(s + 8); c += Rotate(a, 7); a += Fetch64(s + 16); vf = a + z; vs = b + Rotate(a, 31) + c; a = Fetch64(s + 16) + Fetch64(s + len - 32); z = Fetch64(s + len - 8); b = Rotate(a + z, 52); c = Rotate(a, 37); a += Fetch64(s + len - 24); c += Rotate(a, 7); a += Fetch64(s + len - 16); wf = a + z; ws = b + Rotate(a, 31) + c; r = ShiftMix((vf + ws) * k2 + (wf + vs) * k0); return ShiftMix(r * k0 + vs) * k2; } uint64 CityHash64(const char *s, size_t len) { if (len <= 32) { if (len <= 16) return HashLen0to16(s, len); else return HashLen17to32(s, len); } else if (len <= 64) { return HashLen33to64(s, len); } do { /* For strings over 64 bytes we hash the end first, and then as we */ /* loop we keep 56 bytes of state: v, w, x, y, and z. */ uint64 x = Fetch64(s + len - 40); uint64 y = Fetch64(s + len - 16) + Fetch64(s + len - 56); uint64 z = HashLen16(Fetch64(s + len - 48) + len, Fetch64(s + len - 24)); uint128 v = WeakHashLen32WithSeeds3(s + len - 64, len, z); uint128 w = WeakHashLen32WithSeeds3(s + len - 32, y + k1, x); x = x * k1 + Fetch64(s); /* Decrease len to the nearest multiple of 64, and operate on 64-byte chunks. */ len = (len - 1) & ~(size_t)63; do { x = Rotate(x + y + v.first + Fetch64(s + 8), 37) * k1; y = Rotate(y + v.second + Fetch64(s + 48), 42) * k1; x ^= w.second; y += v.first + Fetch64(s + 40); z = Rotate(z + w.first, 33) * k1; v = WeakHashLen32WithSeeds3(s, v.second * k1, x + w.first); w = WeakHashLen32WithSeeds3(s + 32, z + w.second, y + Fetch64(s + 16)); UNSAFE_SWAP(uint64, z, x); s += 64; len -= 64; } while (len != 0); return HashLen16(HashLen16(v.first, w.first) + ShiftMix(y) * k1 + z, HashLen16(v.second, w.second) + x); } while (0); } uint64 CityHash64WithSeed(const char *s, size_t len, uint64 seed) { return CityHash64WithSeeds(s, len, k2, seed); } uint64 CityHash64WithSeeds(const char *s, size_t len, uint64 seed0, uint64 seed1) { return HashLen16(CityHash64(s, len) - seed0, seed1); } /* A subroutine for CityHash128(). Returns a decent 128-bit hash for strings */ /* of any length representable in signed long. Based on City and Murmur. */ static uint128 CityMurmur(const char *s, size_t len, uint128 seed) { uint64 a = Uint128Low64(seed); uint64 b = Uint128High64(seed); uint64 c = 0; uint64 d = 0; signed long l = len - 16; if (l <= 0) { /* len <= 16 */ a = ShiftMix(a * k1) * k1; c = b * k1 + HashLen0to16(s, len); d = ShiftMix(a + (len >= 8 ? Fetch64(s) : c)); } else { /* len > 16 */ c = HashLen16(Fetch64(s + len - 8) + k1, a); d = HashLen16(b + len, c + Fetch64(s + len - 16)); a += d; do { a ^= ShiftMix(Fetch64(s) * k1) * k1; a *= k1; b ^= a; c ^= ShiftMix(Fetch64(s + 8) * k1) * k1; c *= k1; d ^= c; s += 16; l -= 16; } while (l > 0); } a = HashLen16(a, c); b = HashLen16(d, b); return UInt128(a ^ b, HashLen16(b, a)); } uint128 CityHash128WithSeed(const char *s, size_t len, uint128 seed) { if (len < 128) return CityMurmur(s, len, seed); do { /* We expect len >= 128 to be the common case. Keep 56 bytes of state: */ /* v, w, x, y, and z. */ uint128 v, w; uint64 x = Uint128Low64(seed); uint64 y = Uint128High64(seed); uint64 z = len * k1; size_t tail_done; v.first = Rotate(y ^ k1, 49) * k1 + Fetch64(s); v.second = Rotate(v.first, 42) * k1 + Fetch64(s + 8); w.first = Rotate(y + z, 35) * k1 + x; w.second = Rotate(x + Fetch64(s + 88), 53) * k1; /* This is the same inner loop as CityHash64(), manually unrolled. */ do { x = Rotate(x + y + v.first + Fetch64(s + 8), 37) * k1; y = Rotate(y + v.second + Fetch64(s + 48), 42) * k1; x ^= w.second; y += v.first + Fetch64(s + 40); z = Rotate(z + w.first, 33) * k1; v = WeakHashLen32WithSeeds3(s, v.second * k1, x + w.first); w = WeakHashLen32WithSeeds3(s + 32, z + w.second, y + Fetch64(s + 16)); UNSAFE_SWAP(uint64, z, x); s += 64; x = Rotate(x + y + v.first + Fetch64(s + 8), 37) * k1; y = Rotate(y + v.second + Fetch64(s + 48), 42) * k1; x ^= w.second; y += v.first + Fetch64(s + 40); z = Rotate(z + w.first, 33) * k1; v = WeakHashLen32WithSeeds3(s, v.second * k1, x + w.first); w = WeakHashLen32WithSeeds3(s + 32, z + w.second, y + Fetch64(s + 16)); UNSAFE_SWAP(uint64, z, x); s += 64; len -= 128; } while (LIKELY(len >= 128)); x += Rotate(v.first + z, 49) * k0; z += Rotate(w.first, 37) * k0; /* If 0 < len < 128, hash up to 4 chunks of 32 bytes each from the end of s. */ for (tail_done = 0; tail_done < len;) { tail_done += 32; y = Rotate(x + y, 42) * k0 + v.second; w.first += Fetch64(s + len - tail_done + 16); x = x * k0 + w.first; z += w.second + Fetch64(s + len - tail_done); w.second += v.first; v = WeakHashLen32WithSeeds3(s + len - tail_done, v.first + z, v.second); } /* At this point our 56 bytes of state should contain more than */ /* enough information for a strong 128-bit hash. We use two */ /* different 56-byte-to-8-byte hashes to get a 16-byte final result. */ x = HashLen16(x, v.first); y = HashLen16(y + z, w.first); return UInt128(HashLen16(x + v.second, w.second) + y, HashLen16(x + w.second, y + v.second)); } while (0); } uint128 CityHash128(const char *s, size_t len) { if (len >= 16) return CityHash128WithSeed(s + 16, len - 16, UInt128(Fetch64(s) ^ k3, Fetch64(s + 8))); else if (len >= 8) return CityHash128WithSeed(NULL, 0, UInt128(Fetch64(s) ^ (len * k0), Fetch64(s + len - 8) ^ k1)); else return CityHash128WithSeed(s, len, UInt128(k0, k1)); } #ifdef __SSE4_2__ # include "citycrc_c.h" # include /* Requires len >= 240. */ static void CityHashCrc256Long(const char *s, size_t len, uint32 seed, uint64 *result) { uint64 a = Fetch64(s + 56) + k0; uint64 b = Fetch64(s + 96) + k0; uint64 c = result[0] = HashLen16(b, len); uint64 d = result[1] = Fetch64(s + 120) * k0 + len; uint64 e = Fetch64(s + 184) + seed; uint64 f = seed; uint64 g = 0; uint64 h = 0; uint64 i = 0; uint64 j = 0; uint64 t = c + d; /* 240 bytes of input per iter. */ size_t iters = len / 240; len -= iters * 240; do { # define CHUNK(multiplier, z) \ { \ uint64 old_a = a; \ a = Rotate(b, 41 ^ z) * multiplier + Fetch64(s); \ b = Rotate(c, 27 ^ z) * multiplier + Fetch64(s + 8); \ c = Rotate(d, 41 ^ z) * multiplier + Fetch64(s + 16); \ d = Rotate(e, 33 ^ z) * multiplier + Fetch64(s + 24); \ e = Rotate(t, 25 ^ z) * multiplier + Fetch64(s + 32); \ t = old_a; \ } \ f = _mm_crc32_u64(f, a); \ g = _mm_crc32_u64(g, b); \ h = _mm_crc32_u64(h, c); \ i = _mm_crc32_u64(i, d); \ j = _mm_crc32_u64(j, e); \ s += 40 CHUNK(1, 1); CHUNK(k0, 0); CHUNK(1, 1); CHUNK(k0, 0); CHUNK(1, 1); CHUNK(k0, 0); } while (--iters > 0); while (len >= 40) { CHUNK(k0, 0); len -= 40; } if (len > 0) { s = s + len - 40; CHUNK(k0, 0); } j += i << 32; a = HashLen16(a, j); h += g << 32; b += h; c = HashLen16(c, f) + i; d = HashLen16(d, e + result[0]); j += e; i += HashLen16(h, t); e = HashLen16(a, d) + j; f = HashLen16(b, c) + a; g = HashLen16(j, i) + c; result[0] = e + f + g + h; a = ShiftMix((a + g) * k0) * k0 + b; result[1] += a + result[0]; a = ShiftMix(a * k0) * k0 + c; result[2] = a + result[1]; a = ShiftMix((a + e) * k0) * k0; result[3] = a + result[2]; } /* Requires len < 240. */ static inline void CityHashCrc256Short(const char *s, size_t len, uint64 *result) { char buf[240]; memcpy(buf, s, len); memset(buf + len, 0, 240 - len); CityHashCrc256Long(buf, 240, ~(uint32)len, result); } void CityHashCrc256(const char *s, size_t len, uint64 *result) { if (LIKELY(len >= 240)) CityHashCrc256Long(s, len, 0, result); else CityHashCrc256Short(s, len, result); } uint128 CityHashCrc128WithSeed(const char *s, size_t len, uint128 seed) { if (len <= 900) { return CityHash128WithSeed(s, len, seed); } else { uint64 result[4], u, v; CityHashCrc256(s, len, result); u = Uint128High64(seed) + result[0]; v = Uint128Low64(seed) + result[1]; return UInt128(HashLen16(u, v + result[2]), HashLen16(Rotate(v, 32), u * k0 + result[3])); } } uint128 CityHashCrc128(const char *s, size_t len) { if (len <= 900) { return CityHash128(s, len); } else { uint64 result[4]; CityHashCrc256(s, len, result); return UInt128(result[2], result[3]); } } #endif dlt-daemon-2.18.4/src/core_dump_handler/cityhash_c/city_c.h000066400000000000000000000070301353342203500236340ustar00rootroot00000000000000/* Copyright (c) 2011 Google, Inc. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining a copy */ /* of this software and associated documentation files (the "Software"), to deal */ /* in the Software without restriction, including without limitation the rights */ /* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell */ /* copies of the Software, and to permit persons to whom the Software is */ /* furnished to do so, subject to the following conditions: */ /* */ /* The above copyright notice and this permission notice shall be included in */ /* all copies or substantial portions of the Software. */ /* */ /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR */ /* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, */ /* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE */ /* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER */ /* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, */ /* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN */ /* THE SOFTWARE. */ /* */ /* CityHash, by Geoff Pike and Jyrki Alakuijala */ /* */ /* This file provides a few functions for hashing strings. On x86-64 */ /* hardware in 2011, CityHash64() is faster than other high-quality */ /* hash functions, such as Murmur. This is largely due to higher */ /* instruction-level parallelism. CityHash64() and CityHash128() also perform */ /* well on hash-quality tests. */ /* */ /* CityHash128() is optimized for relatively long strings and returns */ /* a 128-bit hash. For strings more than about 2000 bytes it can be */ /* faster than CityHash64(). */ /* */ /* Functions in the CityHash family are not suitable for cryptography. */ /* */ /* WARNING: This code has not been tested on big-endian platforms! */ /* It is known to work well on little-endian platforms that have a small penalty */ /* for unaligned reads, such as current Intel and AMD moderate-to-high-end CPUs. */ /* */ /* By the way, for some hash functions, given strings a and b, the hash */ /* of a+b is easily derived from the hashes of a and b. This property */ /* doesn't hold for any hash functions in this file. */ #ifndef CITY_HASH_H_ # define CITY_HASH_H_ # include # ifdef _MSC_VER typedef unsigned char uint8; typedef unsigned int uint32; typedef unsigned long long uint64; # else # include typedef uint8_t uint8; typedef uint32_t uint32; typedef uint64_t uint64; # endif # ifdef __cplusplus extern "C" { # endif # pragma pack(1) typedef struct { uint64 first, second; } uint128; # pragma pack() # define Uint128Low64(x) ((x).first) # define Uint128High64(x) ((x).second) /* Hash function for a byte array. */ uint64 CityHash64(const char *buf, size_t len); /* Hash function for a byte array. For convenience, a 64-bit seed is also */ /* hashed into the result. */ uint64 CityHash64WithSeed(const char *buf, size_t len, uint64 seed); /* Hash function for a byte array. For convenience, two seeds are also */ /* hashed into the result. */ uint64 CityHash64WithSeeds(const char *buf, size_t len, uint64 seed0, uint64 seed1); /* Hash function for a byte array. */ uint128 CityHash128(const char *s, size_t len); /* Hash function for a byte array. For convenience, a 128-bit seed is also */ /* hashed into the result. */ uint128 CityHash128WithSeed(const char *s, size_t len, uint128 seed); # ifdef __cplusplus } # endif #endif /* CITY_HASH_H_ */ dlt-daemon-2.18.4/src/core_dump_handler/cityhash_c/citycrc_c.h000066400000000000000000000037741353342203500243370ustar00rootroot00000000000000/* Copyright (c) 2011 Google, Inc. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining a copy */ /* of this software and associated documentation files (the "Software"), to deal */ /* in the Software without restriction, including without limitation the rights */ /* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell */ /* copies of the Software, and to permit persons to whom the Software is */ /* furnished to do so, subject to the following conditions: */ /* */ /* The above copyright notice and this permission notice shall be included in */ /* all copies or substantial portions of the Software. */ /* */ /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR */ /* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, */ /* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE */ /* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER */ /* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, */ /* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN */ /* THE SOFTWARE. */ /* */ /* CityHash, by Geoff Pike and Jyrki Alakuijala */ /* */ /* This file declares the subset of the CityHash functions that require */ /* _mm_crc32_u64(). See the CityHash README for details. */ /* */ /* Functions in the CityHash family are not suitable for cryptography. */ #ifndef CITY_HASH_CRC_H_ # define CITY_HASH_CRC_H_ # include "city_c.h" # ifdef __cplusplus extern "C" { # endif /* Hash function for a byte array. */ uint128 CityHashCrc128(const char *s, size_t len); /* Hash function for a byte array. For convenience, a 128-bit seed is also */ /* hashed into the result. */ uint128 CityHashCrc128WithSeed(const char *s, size_t len, uint128 seed); /* Hash function for a byte array. Sets result[0] ... result[3]. */ void CityHashCrc256(const char *s, size_t len, uint64 *result); # ifdef __cplusplus } # endif #endif /* CITY_HASH_CRC_H_ */ dlt-daemon-2.18.4/src/core_dump_handler/dlt_cdh.c000066400000000000000000000315071353342203500216460ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2011-2015, BMW AG * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author Magneti Marelli http://www.magnetimarelli.com * \author Lutz Helwing * * \copyright Copyright © 2011-2015 BMW AG. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file dlt_cdh.c */ #include #include #include #include #include #include #include #include #include #include #include #include #include "dlt_cdh.h" #include /* Unusual characters in a windows filename are replaced */ #define UNUSUAL_CHARS ":/\\!*" #define REPLACEMENT_CHAR '_' #define COREDUMP_FILESYSTEM "/var" #define COREDUMP_FILESYSTEM_MIN_SIZE_MB 40 #define COREDUMP_HANDLER_PRIORITY -19 void core_locks(const proc_info_t *p_proc, int action); /* =================================================================== ** Method : init_proc_info(...) ** ** Description : initialises all members of process info structure to defined values ** ** Parameters : INPUT p_proc ** OUTPUT pointer to initialised crashed process info structure ** ** Returns : nothing ** ===================================================================*/ void init_proc_info(proc_info_t *p_proc) { memset(p_proc->name, 0, sizeof(p_proc->name)); memset(p_proc->threadname, 0, sizeof(p_proc->threadname)); p_proc->pid = 0; p_proc->timestamp = 0; p_proc->signal = 0; p_proc->can_create_coredump = 1; memset(&p_proc->streamer, 0, sizeof(p_proc->streamer)); memset(&p_proc->m_Ehdr, 0, sizeof(p_proc->m_Ehdr)); p_proc->m_pPhdr = NULL; p_proc->m_Nhdr = NULL; p_proc->m_note_page_size = 0; memset(&p_proc->m_registers, 0, sizeof(p_proc->m_registers)); p_proc->m_crashed_pid = 0; p_proc->m_crashid_phase1 = 0; memset(p_proc->m_crashid, 0, sizeof(p_proc->m_crashid)); } /* =================================================================== ** Method : read_args(...) ** ** Description : reads command line arguments ** ** Parameters : INPUT argc ** INPUT argv ** OUTPUT pointer to crashed process info structure ** ** Returns : 0 if success, else -1 ** ===================================================================*/ cdh_status_t read_args(int argc, char **argv, proc_info_t *proc) { if (argc < 5) { syslog(LOG_ERR, "Usage: cdh timestamp pid signal procname"); return CDH_NOK; } init_proc_info(proc); if (sscanf(argv[1], "%u", &proc->timestamp) != 1) { syslog(LOG_ERR, "Unable to read timestamp argument <%s>. Closing", argv[1]); return CDH_NOK; } if (sscanf(argv[2], "%d", &proc->pid) != 1) { syslog(LOG_ERR, "Unable to read pid argument <%s>. Closing", argv[2]); return CDH_NOK; } if (sscanf(argv[3], "%d", &proc->signal) != 1) { syslog(LOG_ERR, "Unable to read signal argument <%s>. Closing", argv[3]); return CDH_NOK; } /* save the thread name given by the kernel */ strncpy(proc->threadname, argv[4], sizeof(proc->threadname) - 1); /* initialize the binary name with threadname... in case we cannot read it from /proc */ strncpy(proc->name, argv[4], sizeof(proc->name) - 1); return CDH_OK; } /* =================================================================== ** Method : remove_unusual_chars(...) ** ** Description : modify the input string to change UNUSUALS_CHARS to ** REPLACEMENT_CHAR ** Parameters : INPUT/OUTPUT string to be modified ** ** Returns : nothing ** ===================================================================*/ void remove_unusual_chars(char *p_string) { unsigned int l_char_index = 0; for (l_char_index = 0; l_char_index < sizeof(UNUSUAL_CHARS) - 1; l_char_index++) { char *l_str_pointer = p_string; do { l_str_pointer = strchr(l_str_pointer, UNUSUAL_CHARS[l_char_index]); if (l_str_pointer != NULL) { *l_str_pointer = REPLACEMENT_CHAR; l_str_pointer++; } } while (l_str_pointer != NULL); } } /* =================================================================== ** Method : check_disk_space(...) ** ** Description : check if there is sufficient disk space to write a coredump ** Parameters : INPUT/OUTPUT string to be modified ** ** Returns : 0 if success, else -1 ** ===================================================================*/ cdh_status_t check_disk_space() { struct statvfs stat; unsigned long free_size = 0; if (statvfs(COREDUMP_FILESYSTEM, &stat) < 0) { syslog(LOG_ERR, "ERR cannot stat disk space on %s: %s", COREDUMP_FILESYSTEM, strerror(errno)); return CDH_NOK; } /* free space: size of block * number of free blocks (>>20 => MB) */ free_size = (stat.f_bsize * stat.f_bavail) >> 20; if (free_size < COREDUMP_FILESYSTEM_MIN_SIZE_MB) { syslog(LOG_WARNING, "ERR insufficient disk space for coredump: %ld MB.", free_size); return CDH_NOK; } syslog(LOG_INFO, "INFO disk space for coredump: %ld MB.", free_size); return CDH_OK; } void clean_core_tmp_dir() { DIR *d = NULL; struct dirent *dir = NULL; if ((d = opendir(CORE_TMP_DIRECTORY)) != NULL) { char lockfilepath[CORE_MAX_FILENAME_LENGTH]; while ((dir = readdir(d)) != NULL) { struct stat unused_stat; /* check if lock file exists */ snprintf(lockfilepath, sizeof(lockfilepath), "%s/%s", CORE_LOCK_DIRECTORY, dir->d_name); if (stat(lockfilepath, &unused_stat) != 0) { /* No lock file found for this coredump => from previous LC => delete */ char filepath[CORE_MAX_FILENAME_LENGTH] = { 0 }; snprintf(filepath, sizeof(filepath), "%s/%s", CORE_TMP_DIRECTORY, dir->d_name); syslog(LOG_INFO, "Cleaning %s: delete file %s", CORE_TMP_DIRECTORY, filepath); unlink(filepath); } } closedir(d); } } /* =================================================================== ** Method : check_core_directory(...) ** ** Description : checks the availability of core dumps directory. ** if not available, there is an installation issue. ** ** Parameters : ** ** Returns : 0 if success, else -1 ** ===================================================================*/ cdh_status_t check_and_create_directory(const char *p_dirname, int create_silently) { int l_need_create = 0; int l_need_delete = 0; struct stat l_stat; if (lstat(p_dirname, &l_stat) < 0) { l_need_create = 1; } else if (!S_ISDIR(l_stat.st_mode)) { l_need_delete = 1; l_need_create = 1; } if (l_need_delete > 0) { syslog(LOG_WARNING, "WARN core directory '%s' is not a directory => removing it", p_dirname); if (unlink(p_dirname) == -1) { syslog(LOG_ERR, "ERR core directory '%s' cannot be unlinked: %s", p_dirname, strerror(errno)); return CDH_NOK; } } if (l_need_create > 0) { if (create_silently == 0) syslog(LOG_WARNING, "WARN core directory '%s' does not exist => creation", p_dirname); if (mkdir(p_dirname, 0666) == -1) { syslog(LOG_ERR, "ERR core directory '%s' cannot be created: %s", p_dirname, strerror(errno)); return CDH_NOK; } } return CDH_OK; } /* =================================================================== ** Method : check_core_directory(...) ** ** Description : checks the availability of core dumps directory. ** if not available, there is an installation issue. ** ** Parameters : ** ** Returns : 0 if success, else -1 ** ===================================================================*/ cdh_status_t check_core_directory() { if (check_and_create_directory(CORE_DIRECTORY, 0) < 0) return CDH_NOK; if (check_and_create_directory(CORE_TMP_DIRECTORY, 0) < 0) return CDH_NOK; if (check_and_create_directory(CORE_LOCK_DIRECTORY, 1) < 0) return CDH_NOK; clean_core_tmp_dir(); return CDH_OK; } /* =================================================================== ** Method : move_to_core_directory(...) ** ** Description : move the coredump and context files ** from temporary dir to final core directory ** ** Parameters : ** ** Returns : 0 if success, else -1 ** ===================================================================*/ cdh_status_t move_to_core_directory(proc_info_t *p_proc) { char l_src_filename[CORE_MAX_FILENAME_LENGTH] = { 0 }; char l_dst_filename[CORE_MAX_FILENAME_LENGTH] = { 0 }; char *patterns[] = { CORE_FILE_PATTERN, CONTEXT_FILE_PATTERN }; unsigned int pattern_num = 0; if (p_proc == NULL) return CDH_NOK; for (pattern_num = 0; pattern_num < sizeof(patterns) / sizeof(char *); pattern_num++) { /* Don't move coredump if it cannot be created */ if ((p_proc->can_create_coredump == 0) && (pattern_num == 0)) continue; snprintf(l_src_filename, sizeof(l_src_filename), patterns[pattern_num], CORE_TMP_DIRECTORY, p_proc->timestamp, p_proc->name, p_proc->pid); snprintf(l_dst_filename, sizeof(l_dst_filename), patterns[pattern_num], CORE_DIRECTORY, p_proc->timestamp, p_proc->name, p_proc->pid); syslog(LOG_INFO, "Moving coredump from %s to %s", l_src_filename, l_dst_filename); if (rename(l_src_filename, l_dst_filename) < 0) syslog(LOG_ERR, "Moving failed: %s", strerror(errno)); } return CDH_OK; } /* =================================================================== ** Method : main(...) ** ** Description : ** ** Parameters : argc, argv ** ** Returns : ** ===================================================================*/ int main(int argc, char *argv[]) { proc_info_t l_proc_info; /* char l_exec_name[CORE_MAX_FILENAME_LENGTH] = {0}; */ openlog("CoredumpHandler", 0, LOG_DAEMON); if (read_args(argc, argv, &l_proc_info) < 0) exit(-1); if (get_exec_name(l_proc_info.pid, l_proc_info.name, sizeof(l_proc_info.name)) != 0) syslog(LOG_ERR, "Failed to get executable name"); syslog(LOG_NOTICE, "Handling coredump procname:%s pid:%d timest:%d signal:%d", l_proc_info.name, l_proc_info.pid, l_proc_info.timestamp, l_proc_info.signal); /* Increase priority of the coredump handler */ if (nice(COREDUMP_HANDLER_PRIORITY) != COREDUMP_HANDLER_PRIORITY) syslog(LOG_WARNING, "Failed to change CDH priority"); if (check_disk_space() < 0) /*return CDH_NOK; */ l_proc_info.can_create_coredump = 0; if (check_core_directory() < 0) /*return CDH_NOK; */ l_proc_info.can_create_coredump = 0; remove_unusual_chars(l_proc_info.name); core_locks(&l_proc_info, 1); write_proc_context(&l_proc_info); treat_coredump(&l_proc_info); move_to_core_directory(&l_proc_info); core_locks(&l_proc_info, 0); treat_crash_data(&l_proc_info); closelog(); return CDH_OK; } void core_locks(const proc_info_t *p_proc, int action) { char l_lockfilepath[CORE_MAX_FILENAME_LENGTH] = { 0 }; char *patterns[] = { CORE_FILE_PATTERN, CONTEXT_FILE_PATTERN }; unsigned int pattern_num = 0; int fd_lockfile = -1; if (p_proc == NULL) return; for (pattern_num = 0; pattern_num < sizeof(patterns) / sizeof(char *); pattern_num++) { snprintf(l_lockfilepath, sizeof(l_lockfilepath), patterns[pattern_num], CORE_LOCK_DIRECTORY, p_proc->timestamp, p_proc->name, p_proc->pid); switch (action) { case 0: { unlink(l_lockfilepath); break; } case 1: { if ((fd_lockfile = open(l_lockfilepath, O_CREAT | O_WRONLY | O_TRUNC, S_IRUSR | S_IWUSR)) >= 0) { if (write(fd_lockfile, "1", 1) < 0) syslog(LOG_WARNING, "Failed to write lockfile %d: %s", fd_lockfile, strerror(errno)); close(fd_lockfile); } else { syslog(LOG_WARNING, "Failed to open lockfile %s: %s", l_lockfilepath, strerror(errno)); } break; } default: break; } } } dlt-daemon-2.18.4/src/core_dump_handler/dlt_cdh.h000066400000000000000000000047331353342203500216540ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2011-2015, BMW AG * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author Magneti Marelli http://www.magnetimarelli.com * \author Lutz Helwing * * \copyright Copyright © 2011-2015 BMW AG. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file dlt_cdh.h */ #ifndef DLT_CDH_H #define DLT_CDH_H #include #include #include #include #include #include "dlt_cdh_streamer.h" #define CORE_DIRECTORY "/var/core" #define CORE_TMP_DIRECTORY "/var/core_tmp" #define CORE_LOCK_DIRECTORY "/tmp/.core_locks" #define CORE_MAX_FILENAME_LENGTH 255 #define MAX_PROC_NAME_LENGTH 32 #define CRASH_ID_LEN 8 #define CRASHID_FILE "/tmp/.crashid" /* the file where the white screen app will read the crashid */ #define CORE_FILE_PATTERN "%s/core.%d.%s.%d.gz" #define CONTEXT_FILE_PATTERN "%s/context.%d.%s.%d.txt" #define ELF_Ehdr Elf32_Ehdr #define ELF_Phdr Elf32_Phdr #define ELF_Shdr Elf32_Shdr #define ELF_Nhdr Elf32_Nhdr typedef struct { uint64_t pc; uint64_t ip; uint64_t lr; } cdh_registers_t; typedef struct { char name[MAX_PROC_NAME_LENGTH]; char threadname[MAX_PROC_NAME_LENGTH]; pid_t pid; uint32_t timestamp; int signal; int can_create_coredump; file_streamer_t streamer; /* coredump content, for crash id generation */ ELF_Ehdr m_Ehdr; ELF_Phdr *m_pPhdr; char *m_Nhdr; /* buffer with all NOTE pages */ unsigned int m_note_page_size; cdh_registers_t m_registers; pid_t m_crashed_pid; uint64_t m_crashid_phase1; unsigned char m_crashid[CRASH_ID_LEN]; } proc_info_t; cdh_status_t get_exec_name(unsigned int p_pid_str, char *p_exec_name, int p_exec_name_maxsize); cdh_status_t write_proc_context(const proc_info_t *); cdh_status_t treat_coredump(proc_info_t *p_proc); cdh_status_t treat_crash_data(proc_info_t *p_proc); cdh_status_t move_to_core_directory(proc_info_t *p_proc); cdh_status_t check_core_directory(); #endif /* #ifndef DLT_CDH_H */ dlt-daemon-2.18.4/src/core_dump_handler/dlt_cdh_context.c000066400000000000000000000257411353342203500234150ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2011-2015, BMW AG * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author Magneti Marelli http://www.magnetimarelli.com * \author Lutz Helwing * * \copyright Copyright © 2011-2015 BMW AG. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file dlt_cdh_context.c */ #include #include #include #include #include #include #include #include "dlt_cdh.h" /* Global buffer for file reading */ char g_buffer[4096]; /* =================================================================== ** Method : get_exec_name(...) ** ** Description : read executable filename ** ** Parameters : INPUT p_pid_str pid of the process ** OUTPUT p_exec_name executable name ** INPUT p_exec_name_maxsize size of p_exec_name buffer ** ** Returns : 0 if success, else -1 ** ===================================================================*/ cdh_status_t get_exec_name(unsigned int p_pid, char *p_exec_name, int p_exec_name_maxsize) { char l_exe_link[CORE_MAX_FILENAME_LENGTH] = { 0 }; char *l_name_ptr = NULL; memset(l_exe_link, 0, sizeof(l_exe_link)); snprintf(l_exe_link, sizeof(l_exe_link) - 1, "/proc/%d/exe", p_pid); if (readlink(l_exe_link, g_buffer, p_exec_name_maxsize) < 0) return CDH_NOK; if ((l_name_ptr = strrchr(g_buffer, '/')) == NULL) return CDH_NOK; memset(p_exec_name, 0, p_exec_name_maxsize); strncpy(p_exec_name, l_name_ptr + 1, p_exec_name_maxsize - 1); return CDH_OK; } /* =================================================================== ** Method : dump_file_to(...) ** ** Description : dump the content of file p_src_filename to the file descriptor p_fout ** ** Parameters : INPUT p_src_filename ** INPUT p_fout ** ** Returns : 0 if success, else -1 ** ===================================================================*/ cdh_status_t dump_file_to(const char *p_src_filename, FILE *p_fout) { FILE *l_fin = NULL; int bytes_read = 0; if (p_fout == NULL) return CDH_NOK; fprintf(p_fout, "\n==== Dumping file <%s> ====\n", p_src_filename); if ((l_fin = fopen(p_src_filename, "rt")) == NULL) { syslog(LOG_ERR, "ERR opening info file '%s' for dumping [%s]", p_src_filename, strerror(errno)); fprintf(p_fout, "**error**\n"); return CDH_NOK; } while ((bytes_read = fread(g_buffer, 1, sizeof(g_buffer), l_fin)) != 0) { int i = 0; /* changes all "\0" in the file to a "\n" */ /* (needed for example for /proc//cmdline, to keep all arguments) */ for (i = 0; i < bytes_read; i++) if (g_buffer[i] == '\000') g_buffer[i] = '\n'; fwrite(g_buffer, 1, bytes_read, p_fout); if (ferror(p_fout)) { syslog(LOG_ERR, "Writing in context file failed [%s]", strerror(errno)); fclose(p_fout); fclose(l_fin); return CDH_NOK; } } if (ferror(l_fin)) { syslog(LOG_ERR, "reading '%s' failed [%s]", p_src_filename, strerror(errno)); fclose(l_fin); return CDH_NOK; } fclose(l_fin); fprintf(p_fout, "\n"); return CDH_OK; } /************************************************************************************************** / */ /* "ls -l" implementation for /proc//fd (at least) */ /* Taken from coreutils sources, lib/filemode.c */ /* */ /* Return a character indicating the type of file described by * file mode BITS: * '-' regular file * 'b' block special file * 'c' character special file * 'C' high performance ("contiguous data") file * 'd' directory * 'D' door * 'l' symbolic link * 'm' multiplexed file (7th edition Unix; obsolete) * 'n' network special file (HP-UX) * 'p' fifo (named pipe) * 'P' port * 's' socket * 'w' whiteout (4.4BSD) * '?' some other file type */ static char ftypelet(mode_t bits) { /* These are the most common, so test for them first. */ if (S_ISREG(bits)) return '-'; if (S_ISDIR(bits)) return 'd'; /* Other letters standardized by POSIX 1003.1-2004. */ if (S_ISBLK(bits)) return 'b'; if (S_ISCHR(bits)) return 'c'; if (S_ISLNK(bits)) return 'l'; if (S_ISFIFO(bits)) return 'p'; /* Other file types (though not letters) standardized by POSIX. */ if (S_ISSOCK(bits)) return 's'; /* Nonstandard file types. * if (S_ISCTG (bits)) * return 'C'; * if (S_ISDOOR (bits)) * return 'D'; * if (S_ISMPB (bits) || S_ISMPC (bits)) * return 'm'; * if (S_ISNWK (bits)) * return 'n'; * if (S_ISPORT (bits)) * return 'P'; * if (S_ISWHT (bits)) * return 'w'; */ return '?'; } void strmode(mode_t mode, char *str) { if (str == NULL) return; str[0] = ftypelet(mode); str[1] = mode & S_IRUSR ? 'r' : '-'; str[2] = mode & S_IWUSR ? 'w' : '-'; str[3] = (mode & S_ISUID ? (mode & S_IXUSR ? 's' : 'S') : (mode & S_IXUSR ? 'x' : '-')); str[4] = mode & S_IRGRP ? 'r' : '-'; str[5] = mode & S_IWGRP ? 'w' : '-'; str[6] = (mode & S_ISGID ? (mode & S_IXGRP ? 's' : 'S') : (mode & S_IXGRP ? 'x' : '-')); str[7] = mode & S_IROTH ? 'r' : '-'; str[8] = mode & S_IWOTH ? 'w' : '-'; str[9] = (mode & S_ISVTX ? (mode & S_IXOTH ? 't' : 'T') : (mode & S_IXOTH ? 'x' : '-')); str[10] = ' '; str[11] = '\0'; } /* =================================================================== ** Method : list_dircontent_to(...) ** ** Description : list the filenames in p_dirname directory to the file descriptor p_fout ** ** Parameters : INPUT p_dirname ** INPUT p_fout ** ** Returns : 0 if success, else -1 ** ===================================================================*/ cdh_status_t list_dircontent_to(const char *p_dirname, FILE *p_fout) { DIR *l_dd = NULL; /* directory descriptor */ struct dirent *l_entity = NULL; if ((l_dd = opendir(p_dirname)) == NULL) { syslog(LOG_ERR, "ERR reading info dir '%s' failed [%s]", p_dirname, strerror(errno)); return CDH_NOK; } fprintf(p_fout, "==== Listing directory <%s> ====\n", p_dirname); while ((l_entity = readdir(l_dd)) != NULL) { char l_fullpath[CORE_MAX_FILENAME_LENGTH] = { 0 }; char l_linkpath[CORE_MAX_FILENAME_LENGTH] = { 0 }; char l_modebuf[12] = { 0 }; struct stat l_stat; ssize_t l_size = 0; if (!strcmp(l_entity->d_name, ".") || !strcmp(l_entity->d_name, "..")) continue; snprintf(l_fullpath, sizeof(l_fullpath), "%s/%s", p_dirname, l_entity->d_name); if (lstat(l_fullpath, &l_stat) < 0) { syslog(LOG_ERR, "ERR lstat on '%s' failed. [%s]", l_fullpath, strerror(errno)); continue; } strmode(l_stat.st_mode, l_modebuf); fprintf(p_fout, "%s %ld %d %d %ld %4s", l_modebuf, l_stat.st_nlink, l_stat.st_uid, l_stat.st_gid, l_stat.st_size, l_entity->d_name); switch (l_stat.st_mode & S_IFMT) { case S_IFBLK: fprintf(p_fout, " [block device]\n"); break; case S_IFCHR: fprintf(p_fout, " [character device]\n"); break; case S_IFDIR: fprintf(p_fout, " [directory]\n"); break; case S_IFIFO: fprintf(p_fout, " [FIFO/pipe]\n"); break; case S_IFLNK: l_size = readlink(l_fullpath, l_linkpath, sizeof(l_linkpath)); l_linkpath[l_size] = 0; fprintf(p_fout, " -> %s\n", l_linkpath); break; case S_IFREG: fprintf(p_fout, " [regular file]\n"); break; case S_IFSOCK: fprintf(p_fout, " [socket]\n"); break; default: fprintf(p_fout, " [unknown?]\n"); break; } } /* while ( (l_entity = readdir(l_dd)) != NULL ) */ fprintf(p_fout, "===========================\n"); closedir(l_dd); return CDH_OK; } /************************************************************************************************** / */ /* END of "ls -l" implementation for /proc//fd (at least) */ /************************************************************************************************** / */ /* =================================================================== ** Method : write_proc_context(...) ** ** Description : write the context data of the crashed process ** (context data coming mainly from /proc) ** ** Parameters : INPUT p_proc crashed process info ** ** Returns : 0 if success, else -1 ** ===================================================================*/ cdh_status_t write_proc_context(const proc_info_t *p_proc) { FILE *l_fout = NULL; char l_procfile[256] = { 0 }; char l_outfilename[CORE_MAX_FILENAME_LENGTH] = { 0 }; if (p_proc == NULL) return CDH_NOK; snprintf(l_outfilename, sizeof(l_outfilename), CONTEXT_FILE_PATTERN, CORE_TMP_DIRECTORY, p_proc->timestamp, p_proc->name, p_proc->pid); if ((l_fout = fopen(l_outfilename, "w+t")) == NULL) { syslog(LOG_ERR, "ERR Cannot open context file '%s' [%s]", l_outfilename, strerror(errno)); return CDH_NOK; } #define PROC_FILENAME(x) do { \ snprintf(l_procfile, sizeof(l_procfile), "/proc/%d/"x, \ p_proc->pid); \ } while (0) fprintf(l_fout, "ProcName:%s\n", p_proc->name); fprintf(l_fout, "ThreadName:%s\n", p_proc->threadname); fprintf(l_fout, "PID:%d\n", p_proc->pid); fprintf(l_fout, "signal:%d\n", p_proc->signal); PROC_FILENAME("cmdline"); dump_file_to(l_procfile, l_fout); PROC_FILENAME("cgroup"); dump_file_to(l_procfile, l_fout); PROC_FILENAME("stack"); dump_file_to(l_procfile, l_fout); dump_file_to("/proc/loadavg", l_fout); dump_file_to("/etc/sysrel", l_fout); dump_file_to("/proc/version", l_fout); PROC_FILENAME("environ"); dump_file_to(l_procfile, l_fout); PROC_FILENAME("status"); dump_file_to(l_procfile, l_fout); PROC_FILENAME("sched"); dump_file_to(l_procfile, l_fout); PROC_FILENAME("maps"); dump_file_to(l_procfile, l_fout); PROC_FILENAME("fd"); list_dircontent_to(l_procfile, l_fout); #undef PROC_FILENAME fflush(l_fout); return CDH_OK; } dlt-daemon-2.18.4/src/core_dump_handler/dlt_cdh_coredump.c000066400000000000000000000120001353342203500235270ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2011-2015, BMW AG * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author Magneti Marelli http://www.magnetimarelli.com * \author Lutz Helwing * * \copyright Copyright © 2011-2015 BMW AG. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file dlt_cdh_coredump.c */ #include #include #include #include #include #include #include #include #include #include "dlt_cdh.h" cdh_status_t read_elf_headers(proc_info_t *p_proc) { int phnum = 0; /* Read ELF header */ stream_read(&p_proc->streamer, &p_proc->m_Ehdr, sizeof(p_proc->m_Ehdr)); /* Read until PROG position */ stream_move_to_offest(&p_proc->streamer, p_proc->m_Ehdr.e_phoff); /* Read and store all program headers */ p_proc->m_pPhdr = (ELF_Phdr *)malloc(sizeof(ELF_Phdr) * p_proc->m_Ehdr.e_phnum); if (p_proc->m_pPhdr == NULL) { syslog(LOG_ERR, "Cannot allocate Phdr memory (%d headers)", p_proc->m_Ehdr.e_phnum); return CDH_NOK; } for (phnum = 0; phnum < p_proc->m_Ehdr.e_phnum; phnum++) /* Read Programm header */ stream_read(&p_proc->streamer, &p_proc->m_pPhdr[phnum], sizeof(ELF_Phdr)); return CDH_OK; } int getNotePageIndex(proc_info_t *p_proc) { int i = 0; /* Search PT_NOTE section */ for (i = 0; i < p_proc->m_Ehdr.e_phnum; i++) { syslog(LOG_INFO, "==Note section prog_note:%d type:0x%X offset:0x%X size:0x%X (%dbytes)", i, p_proc->m_pPhdr[i].p_type, p_proc->m_pPhdr[i].p_offset, p_proc->m_pPhdr[i].p_filesz, p_proc->m_pPhdr[i].p_filesz); if (p_proc->m_pPhdr[i].p_type == PT_NOTE) break; } return i == p_proc->m_Ehdr.e_phnum ? CDH_NOK : i; } cdh_status_t read_notes(proc_info_t *p_proc) { int prog_note = getNotePageIndex(p_proc); /* p_proc->m_note_page_size = 0; */ p_proc->m_Nhdr = NULL; /* note page not found, abort */ if (prog_note < 0) { syslog(LOG_ERR, "Cannot find note header page index"); return CDH_NOK; } /* Move to NOTE header position */ if (stream_move_to_offest(&p_proc->streamer, p_proc->m_pPhdr[prog_note].p_offset) != CDH_OK) { syslog(LOG_ERR, "Cannot move to note header"); return CDH_NOK; } if ((p_proc->m_Nhdr = (char *)malloc(p_proc->m_pPhdr[prog_note].p_filesz)) == NULL) { syslog(LOG_ERR, "Cannot allocate Nhdr memory (note size %d bytes)", p_proc->m_pPhdr[prog_note].p_filesz); return CDH_NOK; } if (stream_read(&p_proc->streamer, p_proc->m_Nhdr, p_proc->m_pPhdr[prog_note].p_filesz) != CDH_OK) { syslog(LOG_ERR, "Cannot read note header"); return CDH_NOK; } p_proc->m_note_page_size = p_proc->m_pPhdr[prog_note].p_filesz; return CDH_OK; } cdh_status_t init_coredump(proc_info_t *p_proc) { if (p_proc == NULL) return CDH_NOK; if (p_proc->can_create_coredump) { char l_dst_filename[CORE_MAX_FILENAME_LENGTH]; snprintf(l_dst_filename, sizeof(l_dst_filename), CORE_FILE_PATTERN, CORE_TMP_DIRECTORY, p_proc->timestamp, p_proc->name, p_proc->pid); stream_init(&p_proc->streamer, 0, l_dst_filename); } else { stream_init(&p_proc->streamer, 0, NULL); } return CDH_OK; } cdh_status_t close_coredump(proc_info_t *p_proc) { stream_close(&p_proc->streamer); return CDH_OK; } cdh_status_t treat_coredump(proc_info_t *p_proc) { cdh_status_t ret = CDH_OK; /* open src and dest files, allocate read buffer */ if (init_coredump(p_proc) != CDH_OK) { syslog(LOG_ERR, "cannot init coredump system"); ret = CDH_NOK; goto finished; } if (read_elf_headers(p_proc) == CDH_OK) { /* TODO: No NOTES here leads to crash elsewhere!!! dlt_cdh_crashid.c: around line 76 */ if (read_notes(p_proc) != CDH_OK) { syslog(LOG_ERR, "cannot read NOTES"); ret = CDH_NOK; goto finished; } } else if (read_elf_headers(p_proc) != CDH_OK) { syslog(LOG_ERR, "cannot read ELF header"); ret = CDH_NOK; goto finished; } finished: /* In all cases, we try to finish to read/compress the coredump until the end */ if (stream_finish(&p_proc->streamer) != CDH_OK) syslog(LOG_ERR, "cannot finish coredump compression"); /* In all cases, let's close the files */ if (close_coredump(p_proc) != CDH_OK) syslog(LOG_ERR, "cannot close coredump system"); return ret; } dlt-daemon-2.18.4/src/core_dump_handler/dlt_cdh_cpuinfo.h000066400000000000000000000015661353342203500234000ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2011-2015, BMW AG * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author Magneti Marelli http://www.magnetimarelli.com * \author Lutz Helwing * * \copyright Copyright © 2011-2015 BMW AG. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file dlt_cdh_cpuinfo.h */ #ifndef DLT_CDH_CPUINFO_H #define DLT_CDH_CPUINFO_H #include "dlt_cdh.h" void get_registers(prstatus_t *prstatus, cdh_registers_t *registers); #endif /* DLT_CDH_CPUINFO_H */ dlt-daemon-2.18.4/src/core_dump_handler/dlt_cdh_crashid.c000066400000000000000000000134561353342203500233460ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2011-2015, BMW AG * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author Magneti Marelli http://www.magnetimarelli.com * \author Lutz Helwing * * \copyright Copyright © 2011-2015 BMW AG. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file dlt_cdh_crashid.c */ #include #include #include #include #include #include #include #include #include #include "dlt_cdh.h" #include "dlt_cdh_cpuinfo.h" #ifdef HAS_CITYHASH_C # include "city_c.h" #endif /*ARM32 specific */ /*#define REG_FRAME_POINTER 11 */ /*#define REG_INSTR_POINTER 12 */ /*#define REG_STACK_POINTER 13 */ /*#define REG_LINK_REGISTER 14 */ /*#define REG_PROC_COUNTER 15 */ #ifdef HAS_CITYHASH_C static cdh_status_t crashid_cityhash(proc_info_t *p_proc); #endif cdh_status_t get_phdr_num(proc_info_t *p_proc, unsigned int p_address, int *phdr_num) { int i = 0; if (phdr_num == NULL) return CDH_NOK; for (i = 0; i < p_proc->m_Ehdr.e_phnum; i++) if ((p_proc->m_pPhdr[i].p_vaddr < p_address) && (p_proc->m_pPhdr[i].p_vaddr + p_proc->m_pPhdr[i].p_memsz > p_address)) { *phdr_num = i; return CDH_OK; } *phdr_num = -1; return CDH_NOK; } /* Thanks to libunwind for the following definitions, which helps to */ #define ALIGN(x, a) (((x) + (a) - 1UL) & ~((a) - 1UL)) #define NOTE_SIZE(_hdr) (sizeof (_hdr) + ALIGN((_hdr).n_namesz, 4) + (_hdr).n_descsz) cdh_status_t get_crashed_registers(proc_info_t *p_proc) { int found = CDH_NOK; /* CDH_OK, when we find the page note associated to PID of crashed process */ unsigned int offset = 0; /* TODO: if no notes were found m_note_page_size was not set to 0 which leads to a crash in this loop because it is then used */ /* uninitialised here => this is an x86_64 issue */ while (found != CDH_OK && offset < p_proc->m_note_page_size) { /* Crash mentioned in TODO dlt_cdh_coredump.c line 163 */ ELF_Nhdr *ptr_note = (ELF_Nhdr *)(p_proc->m_Nhdr + offset); if (ptr_note->n_type == NT_PRSTATUS) { /* The first PRSTATUS note is the one of the crashed thread */ prstatus_t *prstatus = (prstatus_t *)((char *)ptr_note + sizeof(ELF_Nhdr) + ALIGN(ptr_note->n_namesz, 4)); p_proc->m_crashed_pid = prstatus->pr_pid; get_registers(prstatus, &p_proc->m_registers); found = CDH_OK; } offset += NOTE_SIZE(*ptr_note); } return found; } #ifdef HAS_CITYHASH_C cdh_status_t crashid_cityhash(proc_info_t *p_proc) { # define CRASHID_BUF_SIZE MAX_PROC_NAME_LENGTH + sizeof(uint64_t) char cityhash_in[CRASHID_BUF_SIZE]; uint64_t cityhash_result = 0; memcpy(cityhash_in, p_proc->name, MAX_PROC_NAME_LENGTH); memcpy(cityhash_in + MAX_PROC_NAME_LENGTH, &p_proc->m_crashid_phase1, sizeof(uint64_t)); cityhash_result = CityHash64(cityhash_in, CRASHID_BUF_SIZE); memcpy(p_proc->m_crashid, &cityhash_result, sizeof(uint64_t)); return CDH_OK; # undef CRASHID_BUF_SIZE } #endif /* HAS_CITYHASH_C */ cdh_status_t create_crashid(proc_info_t *p_proc) { uint32_t final_lr = 0; uint32_t final_pc = 0; int pc_phnum = 0; int lr_phnum = 0; /* translate address from virtual address (process point of view) to offset in the stack memory page */ #define ADDRESS_REBASE(__x, __phdr_num) (__x - p_proc->m_pPhdr[__phdr_num].p_vaddr) /* read value in the stack at position offset: +/- sizeof(), depends on stack growing upward or downward */ #define READ_STACK_VALUE(__offset, __type) (*(__type *)(stack_page + __offset - sizeof(__type))) get_phdr_num(p_proc, p_proc->m_registers.pc, &pc_phnum); final_pc = ADDRESS_REBASE(p_proc->m_registers.pc, pc_phnum); get_phdr_num(p_proc, p_proc->m_registers.lr, &lr_phnum); if (lr_phnum >= 0) final_lr = ADDRESS_REBASE(p_proc->m_registers.lr, lr_phnum); p_proc->m_crashid_phase1 = p_proc->signal << 24; p_proc->m_crashid_phase1 |= (uint64_t)final_lr; p_proc->m_crashid_phase1 <<= 32; p_proc->m_crashid_phase1 |= (uint64_t)final_pc; #ifdef HAS_CITYHASH_C crashid_cityhash(p_proc); #else memcpy(p_proc->m_crashid, &p_proc->m_crashid_phase1, sizeof(uint64_t)); #endif syslog(LOG_INFO, "Crash in \"%s\", thread=\"%s\", pid=%d, crashID=%" PRIx64 ", based on signal=%d, PC=0x%x, caller=0x%x", p_proc->name, p_proc->threadname, p_proc->pid, *((uint64_t *)p_proc->m_crashid), p_proc->signal, final_pc, final_lr ); return CDH_OK; } int write_crashid_to_filesystem(proc_info_t *p_proc) { FILE *crashid_file = NULL; if ((crashid_file = fopen(CRASHID_FILE, "wt")) == NULL) { syslog(LOG_ERR, "(pid=%d) cannot write crashid to %s: %s", p_proc->pid, CRASHID_FILE, strerror(errno)); return CDH_NOK; } fprintf(crashid_file, "%" PRIx64, *(uint64_t *)p_proc->m_crashid); fclose(crashid_file); return CDH_OK; } cdh_status_t treat_crash_data(proc_info_t *p_proc) { if (get_crashed_registers(p_proc) != CDH_OK) { syslog(LOG_ERR, "registers not found in notes"); return CDH_NOK; } if (create_crashid(p_proc) != CDH_OK) { syslog(LOG_ERR, "crashid not generated"); return CDH_NOK; } write_crashid_to_filesystem(p_proc); return CDH_OK; } dlt-daemon-2.18.4/src/core_dump_handler/dlt_cdh_definitions.h000066400000000000000000000015531353342203500242440ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2011-2015, BMW AG * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author Magneti Marelli http://www.magnetimarelli.com * \author Lutz Helwing * * \copyright Copyright © 2011-2015 BMW AG. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file dlt_cdh_definitions.h */ #ifndef DLT_CDH_DEFINITIONS_H #define DLT_CDH_DEFINITIONS_H typedef enum { CDH_OK = 0, CDH_NOK = -1 } cdh_status_t; #endif /* DLT_CDH_DEFINITIONS_H */ dlt-daemon-2.18.4/src/core_dump_handler/dlt_cdh_streamer.c000066400000000000000000000127041353342203500235460ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2011-2015, BMW AG * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author Magneti Marelli http://www.magnetimarelli.com * \author Lutz Helwing * * \copyright Copyright © 2011-2015 BMW AG. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file dlt_cdh_streamer.c */ #include #include #include #include #include #include "dlt_cdh_streamer.h" #define Z_CHUNK_SZ 1024 * 128 #define Z_MODE_STR "wb1" cdh_status_t stream_init(file_streamer_t *p_fs, const char *p_src_fname, const char *p_dst_fname) { if (p_fs == NULL) { syslog(LOG_ERR, "Internal pointer error in 'stream_init'"); return CDH_NOK; } memset(p_fs, 0, sizeof(file_streamer_t)); /* Allow to not save the coredump */ if (p_dst_fname == NULL) { p_fs->gz_dst_file = 0; } else { /* Create output file */ p_fs->gz_dst_file = gzopen(p_dst_fname, Z_MODE_STR); if (p_fs->gz_dst_file == Z_NULL) { /*return CDH_NOK; */ syslog(LOG_ERR, "Cannot open output filename <%s>. %s", p_dst_fname, strerror(errno)); p_fs->gz_dst_file = 0; } } if (p_fs->gz_dst_file == Z_NULL) syslog(LOG_WARNING, "The coredump will be processed, but not written"); /* Open input file */ if (p_src_fname == NULL) { p_fs->stream = stdin; } else if ((p_fs->stream = fopen(p_src_fname, "rb")) == NULL) { syslog(LOG_ERR, "Cannot open filename <%s>. %s", p_src_fname, strerror(errno)); return CDH_NOK; } /* Allocate read buffer */ if ((p_fs->read_buf = (unsigned char *)malloc(Z_CHUNK_SZ)) == NULL) { syslog(LOG_ERR, "Cannot allocate %d bytes for read buffer. %s", Z_CHUNK_SZ, strerror(errno)); return CDH_NOK; } return CDH_OK; } cdh_status_t stream_close(file_streamer_t *p_fs) { if (p_fs == NULL) { syslog(LOG_ERR, "Internal pointer error in 'stream_close'"); return CDH_NOK; } if (p_fs->gz_dst_file != NULL) { gzflush(p_fs->gz_dst_file, Z_FINISH); gzclose(p_fs->gz_dst_file); p_fs->gz_dst_file = NULL; } if (p_fs->stream != NULL) { fclose(p_fs->stream); p_fs->stream = NULL; } if (p_fs->read_buf != NULL) { free(p_fs->read_buf); p_fs->read_buf = NULL; } return CDH_OK; } cdh_status_t stream_read(file_streamer_t *p_fs, void *p_buf, unsigned int p_size) { unsigned int byte_read = 0; if (p_fs == NULL) { syslog(LOG_ERR, "Internal pointer error in 'stream_read'"); return CDH_NOK; } if (p_buf == NULL) { syslog(LOG_ERR, "Internal buffer pointer error in 'stream_read'"); return CDH_NOK; } if ((byte_read = fread(p_buf, 1, p_size, p_fs->stream)) != p_size) { syslog(LOG_WARNING, "Cannot read %d bytes from src. %s", p_size, strerror(errno)); return CDH_NOK; } p_fs->offset += byte_read; if (p_fs->gz_dst_file != NULL) gzwrite(p_fs->gz_dst_file, p_buf, byte_read); return CDH_OK; } int stream_finish(file_streamer_t *p_fs) { if ((p_fs == NULL) || (p_fs->stream == NULL)) { syslog(LOG_ERR, "Internal pointer error in 'stream_move_ahead'"); return CDH_NOK; } while (!feof(p_fs->stream)) { size_t read_bytes = fread(p_fs->read_buf, 1, Z_CHUNK_SZ, p_fs->stream); if (p_fs->gz_dst_file != NULL) gzwrite(p_fs->gz_dst_file, p_fs->read_buf, read_bytes); p_fs->offset += read_bytes; if (ferror(p_fs->stream)) { syslog(LOG_WARNING, "Error reading from the src stream: %s", strerror(errno)); return CDH_NOK; } } return CDH_OK; } int stream_move_to_offest(file_streamer_t *p_fs, unsigned int p_offset) { int bytes_to_read = 0; if (p_fs == NULL) { syslog(LOG_ERR, "Internal pointer error in 'stream_move_to_offest'"); return CDH_NOK; } bytes_to_read = p_offset - p_fs->offset; return stream_move_ahead(p_fs, bytes_to_read); } int stream_move_ahead(file_streamer_t *p_fs, unsigned int p_nbbytes) { int bytes_to_read = p_nbbytes; if (p_fs == NULL) { syslog(LOG_ERR, "Internal pointer error in 'stream_move_ahead'"); return CDH_NOK; } while (bytes_to_read > 0) { size_t chunk_size = bytes_to_read > Z_CHUNK_SZ ? Z_CHUNK_SZ : bytes_to_read; size_t read_bytes = fread(p_fs->read_buf, 1, chunk_size, p_fs->stream); if (read_bytes != chunk_size) { syslog(LOG_WARNING, "Cannot move ahead by %d bytes from src. Read %lu bytes", p_nbbytes, read_bytes); return CDH_NOK; } if (p_fs->gz_dst_file != 0) gzwrite(p_fs->gz_dst_file, p_fs->read_buf, chunk_size); bytes_to_read -= chunk_size; } p_fs->offset += p_nbbytes; return CDH_OK; } unsigned int stream_get_offset(file_streamer_t *p_fs) { if (p_fs == NULL) { syslog(LOG_ERR, "Internal pointer error in 'stream_get_offset'"); return CDH_NOK; } return p_fs->offset; } dlt-daemon-2.18.4/src/core_dump_handler/dlt_cdh_streamer.h000066400000000000000000000027471353342203500235610ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2011-2015, BMW AG * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author Magneti Marelli http://www.magnetimarelli.com * \author Lutz Helwing * * \copyright Copyright © 2011-2015 BMW AG. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file dlt_cdh_streamer.h */ #ifndef DLT_CDH_STREAMER_H #define DLT_CDH_STREAMER_H #include #include #include "dlt_cdh_definitions.h" typedef struct { FILE *stream; unsigned int offset; gzFile gz_dst_file; unsigned char *read_buf; } file_streamer_t; cdh_status_t stream_init(file_streamer_t *p_fs, const char *p_src_fname, const char *p_dst_fname); cdh_status_t stream_close(file_streamer_t *p_fs); cdh_status_t stream_read(file_streamer_t *p_fs, void *p_buf, unsigned int p_size); cdh_status_t stream_finish(file_streamer_t *p_fs); cdh_status_t stream_move_to_offest(file_streamer_t *p_fs, unsigned int p_offset); cdh_status_t stream_move_ahead(file_streamer_t *p_fs, unsigned int p_nbbytes); unsigned int stream_get_offset(file_streamer_t *p_fs); #endif /* #ifndef DLT_CDH_STREAMER_H */ dlt-daemon-2.18.4/src/core_dump_handler/i686/000077500000000000000000000000001353342203500205675ustar00rootroot00000000000000dlt-daemon-2.18.4/src/core_dump_handler/i686/dlt_cdh_cpuinfo.c000066400000000000000000000020771353342203500240650ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2011-2015, BMW AG * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author Magneti Marelli http://www.magnetimarelli.com * \author Lutz Helwing * * \copyright Copyright © 2011-2015 BMW AG. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file i686/dlt_cdh_cpuinfo.c */ #include "../dlt_cdh_cpuinfo.h" void get_registers(prstatus_t *prstatus, cdh_registers_t *registers) { struct user_regs_struct *ptr_reg = (struct user_regs_struct *)prstatus->pr_reg; registers->pc = ptr_reg->ecx; /* [REG_PROC_COUNTER]; */ registers->ip = ptr_reg->eip; /* [REG_INSTR_POINTER]; */ registers->lr = ptr_reg->ebp; /* [REG_LINK_REGISTER]; */ } dlt-daemon-2.18.4/src/core_dump_handler/x86_64/000077500000000000000000000000001353342203500210315ustar00rootroot00000000000000dlt-daemon-2.18.4/src/core_dump_handler/x86_64/dlt_cdh_cpuinfo.c000066400000000000000000000021011353342203500243130ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2011-2015, BMW AG * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author Magneti Marelli http://www.magnetimarelli.com * \author Lutz Helwing * * \copyright Copyright © 2011-2015 BMW AG. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file x86_64/dlt_cdh_cpuinfo.c */ #include "../dlt_cdh_cpuinfo.h" void get_registers(prstatus_t *prstatus, cdh_registers_t *registers) { struct user_regs_struct *ptr_reg = (struct user_regs_struct *)prstatus->pr_reg; registers->pc = ptr_reg->rcx; /* [REG_PROC_COUNTER]; */ registers->ip = ptr_reg->rip; /* [REG_INSTR_POINTER]; */ registers->lr = ptr_reg->rsp; /* [REG_LINK_REGISTER]; */ } dlt-daemon-2.18.4/src/daemon/000077500000000000000000000000001353342203500156645ustar00rootroot00000000000000dlt-daemon-2.18.4/src/daemon/CMakeLists.txt000066400000000000000000000056461353342203500204370ustar00rootroot00000000000000####### # SPDX license identifier: MPL-2.0 # # Copyright (C) 2011-2015, BMW AG # # This file is part of GENIVI Project DLT - Diagnostic Log and Trace. # # This Source Code Form is subject to the terms of the # Mozilla Public License (MPL), v. 2.0. # If a copy of the MPL was not distributed with this file, # You can obtain one at http://mozilla.org/MPL/2.0/. # # For further information see http://www.genivi.org/. ####### if(WITH_SYSTEMD_WATCHDOG OR WITH_SYSTEMD) message(STATUS "Added ${systemd_SRCS} to dlt-daemon") endif() set(dlt_daemon_SRCS dlt-daemon.c dlt_daemon_client.c dlt_daemon_common.c dlt_daemon_connection.c dlt_daemon_event_handler.c dlt_daemon_offline_logstorage.c dlt_daemon_serial.c dlt_daemon_socket.c dlt_daemon_unix_socket.c ${PROJECT_SOURCE_DIR}/src/gateway/dlt_gateway.c ${PROJECT_SOURCE_DIR}/src/lib/dlt_client.c ${PROJECT_SOURCE_DIR}/src/shared/dlt_common.c ${PROJECT_SOURCE_DIR}/src/shared/dlt_config_file_parser.c ${PROJECT_SOURCE_DIR}/src/shared/dlt_offline_trace.c ${PROJECT_SOURCE_DIR}/src/shared/dlt_protocol.c ${PROJECT_SOURCE_DIR}/src/shared/dlt_user_shared.c ${PROJECT_SOURCE_DIR}/src/offlinelogstorage/dlt_offline_logstorage.c ${PROJECT_SOURCE_DIR}/src/offlinelogstorage/dlt_offline_logstorage_behavior.c ) if(WITH_DLT_SHM_ENABLE) set(dlt_daemon_SRCS ${dlt_daemon_SRCS} ${PROJECT_SOURCE_DIR}/src/shared/dlt_shm.c) endif() if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux") set(RT_LIBRARY rt) set(SOCKET_LIBRARY "") else() set(RT_LIBRARY "") set(SOCKET_LIBRARY socket) endif() if(WITH_UDP_CONNECTION) include_directories(${PROJECT_SOURCE_DIR}/src/daemon/udp_connection) add_definitions(-DUDP_CONNECTION_SUPPORT) set(dlt_daemon_SRCS ${dlt_daemon_SRCS} ${PROJECT_SOURCE_DIR}/src/daemon/udp_connection/dlt_daemon_udp_socket.c) endif(WITH_UDP_CONNECTION) add_executable(dlt-daemon ${dlt_daemon_SRCS} ${systemd_SRCS}) target_link_libraries(dlt-daemon ${RT_LIBRARY} ${SOCKET_LIBRARY} ${CMAKE_THREAD_LIBS_INIT}) install(TARGETS dlt-daemon RUNTIME DESTINATION bin PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ GROUP_EXECUTE GROUP_READ WORLD_EXECUTE WORLD_READ COMPONENT base) if (WITH_DLT_UNIT_TESTS) set(library_SRCS ${dlt_daemon_SRCS}) if (WITH_SYSTEMD_WATCHDOG OR WITH_SYSTEMD) set(library_SRCS ${library_SRCS} ${systemd_SRCS}) endif(WITH_SYSTEMD_WATCHDOG OR WITH_SYSTEMD) add_library(dlt_daemon ${library_SRCS}) target_link_libraries(dlt_daemon ${RT_LIBRARY} ${SOCKET_LIBRARY} ${CMAKE_THREAD_LIBS_INIT}) install(TARGETS dlt_daemon RUNTIME DESTINATION bin LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}/static COMPONENT base) endif(WITH_DLT_UNIT_TESTS) INSTALL(FILES dlt.conf DESTINATION ${CONFIGURATION_FILES_DIR} COMPONENT base) dlt-daemon-2.18.4/src/daemon/dlt-daemon.c000066400000000000000000003614131353342203500200640ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2011-2015, BMW AG * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author * Alexander Wenzel * Markus Klein * Mikko Rapeli * * \copyright Copyright © 2011-2015 BMW AG. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file dlt-daemon.c */ #include #include #include /* for printf() and fprintf() */ #include /* for socket(), connect(), (), and recv() */ #include #include /* for sockaddr_in and inet_addr() */ #include /* for atoi() and exit() */ #include /* for memset() */ #include /* for close() */ #include #include #include #include #include #include #ifdef linux # include #endif #include #include #if defined(linux) && defined(__NR_statx) # include #endif #include "dlt_types.h" #include "dlt-daemon.h" #include "dlt-daemon_cfg.h" #include "dlt_daemon_common_cfg.h" #include "dlt_daemon_socket.h" #include "dlt_daemon_unix_socket.h" #include "dlt_daemon_serial.h" #include "dlt_daemon_client.h" #include "dlt_daemon_connection.h" #include "dlt_daemon_event_handler.h" #include "dlt_daemon_offline_logstorage.h" #include "dlt_gateway.h" #ifdef UDP_CONNECTION_SUPPORT # include "dlt_daemon_udp_socket.h" #endif #if defined(DLT_SYSTEMD_WATCHDOG_ENABLE) || defined(DLT_SYSTEMD_ENABLE) # include "sd-daemon.h" #endif /** * \defgroup daemon DLT Daemon * \addtogroup daemon \{ */ static int dlt_daemon_log_internal(DltDaemon *daemon, DltDaemonLocal *daemon_local, char *str, int verbose); #ifdef DLT_SYSTEMD_WATCHDOG_ENABLE static uint32_t watchdog_trigger_interval; /* watchdog trigger interval in [s] */ #endif /* used in main event loop and signal handler */ int g_exit = 0; int g_signo = 0; /** * Print usage information of tool. */ void usage() { char version[DLT_DAEMON_TEXTBUFSIZE]; dlt_get_version(version, DLT_DAEMON_TEXTBUFSIZE); /*printf("DLT logging daemon %s %s\n", _DLT_PACKAGE_VERSION, _DLT_PACKAGE_VERSION_STATE); */ /*printf("Compile options: %s %s %s %s",_DLT_SYSTEMD_ENABLE, _DLT_SYSTEMD_WATCHDOG_ENABLE, _DLT_TEST_ENABLE, _DLT_SHM_ENABLE); */ printf("%s", version); printf("Usage: dlt-daemon [options]\n"); printf("Options:\n"); printf(" -d Daemonize\n"); printf(" -h Usage\n"); printf(" -c filename DLT daemon configuration file (Default: " CONFIGURATION_FILES_DIR "/dlt.conf)\n"); printf(" -t directory Directory for local fifo and user-pipes (Default: /tmp)\n"); printf(" (Applications wanting to connect to a daemon using a\n"); printf(" custom directory need to be started with the environment \n"); printf(" variable DLT_PIPE_DIR set appropriately)\n"); #ifdef DLT_SHM_ENABLE printf(" -s filename The file name to create the share memory (Default: /dlt-shm)\n"); printf(" (Applications wanting to connect to a daemon using a\n"); printf(" custom shm name need to be started with the environment \n"); printf(" variable DLT_SHM_NAME set appropriately)\n"); #endif printf(" -p port port to monitor for incoming requests (Default: 3490)\n"); printf(" (Applications wanting to connect to a daemon using a custom\n"); printf(" port need to be started with the environment variable\n"); printf(" DLT_DAEMON_TCP_PORT set appropriately)\n"); } /* usage() */ /** * Option handling */ int option_handling(DltDaemonLocal *daemon_local, int argc, char *argv[]) { int c; if (daemon_local == 0) { fprintf (stderr, "Invalid parameter passed to option_handling()\n"); return -1; } /* Initialize flags */ memset(daemon_local, 0, sizeof(DltDaemonLocal)); /* default values */ daemon_local->flags.port = DLT_DAEMON_TCP_PORT; strncpy(dltFifoBaseDir, DLT_USER_IPC_PATH, DLT_PATH_MAX); dltFifoBaseDir[DLT_PATH_MAX - 1] = 0; #ifdef DLT_SHM_ENABLE strncpy(dltShmName, "/dlt-shm", NAME_MAX); #endif opterr = 0; #ifdef DLT_SHM_ENABLE while ((c = getopt (argc, argv, "hdc:t:s:p:")) != -1) #else while ((c = getopt (argc, argv, "hdc:t:p:")) != -1) #endif switch (c) { case 'd': { daemon_local->flags.dflag = 1; break; } case 'c': { strncpy(daemon_local->flags.cvalue, optarg, NAME_MAX); break; } case 't': { strncpy(dltFifoBaseDir, optarg, DLT_PATH_MAX); dltFifoBaseDir[DLT_PATH_MAX - 1] = 0; break; } #ifdef DLT_SHM_ENABLE case 's': { strncpy(dltShmName, optarg, NAME_MAX); break; } #endif case 'p': { daemon_local->flags.port = atoi(optarg); if (daemon_local->flags.port == 0) { fprintf (stderr, "Invalid port `%s' specified.\n", optarg); return -1; } break; } case 'h': { usage(); return -2; /* return no error */ } case '?': { if ((optopt == 'c') || (optopt == 't') || (optopt == 'p')) fprintf (stderr, "Option -%c requires an argument.\n", optopt); else if (isprint (optopt)) fprintf (stderr, "Unknown option `-%c'.\n", optopt); else fprintf (stderr, "Unknown option character `\\x%x'.\n", optopt); /* unknown or wrong option used, show usage information and terminate */ usage(); return -1; } default: { fprintf (stderr, "Invalid option, this should never occur!\n"); return -1; } } /* switch() */ #ifndef DLT_USE_UNIX_SOCKET_IPC snprintf(daemon_local->flags.userPipesDir, DLT_PATH_MAX, "%s/dltpipes", dltFifoBaseDir); snprintf(daemon_local->flags.daemonFifoName, DLT_PATH_MAX, "%s/dlt", dltFifoBaseDir); #endif #ifdef DLT_SHM_ENABLE strncpy(daemon_local->flags.dltShmName, dltShmName, NAME_MAX); #endif return 0; } /* option_handling() */ /** * Option file parser */ int option_file_parser(DltDaemonLocal *daemon_local) { FILE *pFile; int value_length = 1024; char line[value_length - 1]; char token[value_length]; char value[value_length]; char *pch; const char *filename; /* set default values for configuration */ daemon_local->flags.sharedMemorySize = DLT_SHM_SIZE; daemon_local->flags.sendMessageTime = 0; daemon_local->flags.offlineTraceDirectory[0] = 0; daemon_local->flags.offlineTraceFileSize = 1000000; daemon_local->flags.offlineTraceMaxSize = 0; daemon_local->flags.offlineTraceFilenameTimestampBased = 1; daemon_local->flags.loggingMode = DLT_LOG_TO_CONSOLE; daemon_local->flags.loggingLevel = LOG_INFO; snprintf(daemon_local->flags.loggingFilename, sizeof(daemon_local->flags.loggingFilename), "%s/dlt.log", dltFifoBaseDir); daemon_local->timeoutOnSend = 4; daemon_local->RingbufferMinSize = DLT_DAEMON_RINGBUFFER_MIN_SIZE; daemon_local->RingbufferMaxSize = DLT_DAEMON_RINGBUFFER_MAX_SIZE; daemon_local->RingbufferStepSize = DLT_DAEMON_RINGBUFFER_STEP_SIZE; daemon_local->daemonFifoSize = 0; daemon_local->flags.sendECUSoftwareVersion = 0; memset(daemon_local->flags.pathToECUSoftwareVersion, 0, sizeof(daemon_local->flags.pathToECUSoftwareVersion)); daemon_local->flags.sendTimezone = 0; daemon_local->flags.offlineLogstorageMaxDevices = 0; daemon_local->flags.offlineLogstorageDirPath[0] = 0; daemon_local->flags.offlineLogstorageMaxDevices = 0; daemon_local->flags.offlineLogstorageTimestamp = 1; daemon_local->flags.offlineLogstorageDelimiter = '_'; daemon_local->flags.offlineLogstorageMaxCounter = UINT_MAX; daemon_local->flags.offlineLogstorageMaxCounterIdx = 0; daemon_local->flags.offlineLogstorageCacheSize = 30000; /* 30MB */ dlt_daemon_logstorage_set_logstorage_cache_size( daemon_local->flags.offlineLogstorageCacheSize); strncpy(daemon_local->flags.ctrlSockPath, DLT_DAEMON_DEFAULT_CTRL_SOCK_PATH, sizeof(daemon_local->flags.ctrlSockPath) - 1); #ifdef DLT_USE_UNIX_SOCKET_IPC snprintf(daemon_local->flags.appSockPath, DLT_IPC_PATH_MAX, "%s/dlt", DLT_USER_IPC_PATH); if (strlen(DLT_USER_IPC_PATH) > DLT_IPC_PATH_MAX) fprintf(stderr, "Provided path too long...trimming it to path[%s]\n", daemon_local->flags.appSockPath); #else memset(daemon_local->flags.daemonFifoGroup, 0, sizeof(daemon_local->flags.daemonFifoGroup)); #endif daemon_local->flags.gatewayMode = 0; strncpy(daemon_local->flags.gatewayConfigFile, DLT_GATEWAY_CONFIG_PATH, DLT_DAEMON_FLAG_MAX - 1); daemon_local->flags.autoResponseGetLogInfoOption = 7; daemon_local->flags.contextLogLevel = DLT_LOG_INFO; daemon_local->flags.contextTraceStatus = DLT_TRACE_STATUS_OFF; daemon_local->flags.enforceContextLLAndTS = 0; /* default is off */ #ifdef UDP_CONNECTION_SUPPORT daemon_local->UDPConnectionSetup = MULTICAST_CONNECTION_ENABLED; strncpy(daemon_local->UDPMulticastIPAddress, MULTICASTIPADDRESS, MULTICASTIP_MAX_SIZE - 1); daemon_local->UDPMulticastIPPort = MULTICASTIPPORT; #endif daemon_local->flags.ipNodes = NULL; /* open configuration file */ if (daemon_local->flags.cvalue[0]) filename = daemon_local->flags.cvalue; else filename = CONFIGURATION_FILES_DIR "/dlt.conf"; /*printf("Load configuration from file: %s\n",filename); */ pFile = fopen (filename, "r"); if (pFile != NULL) { while (1) { /* fetch line from configuration file */ if (fgets (line, value_length - 1, pFile) != NULL) { pch = strtok (line, " =\r\n"); token[0] = 0; value[0] = 0; while (pch != NULL) { if (strcmp(pch, "#") == 0) break; if (token[0] == 0) { strncpy(token, pch, sizeof(token) - 1); token[sizeof(token) - 1] = 0; } else { strncpy(value, pch, sizeof(value) - 1); value[sizeof(value) - 1] = 0; break; } pch = strtok (NULL, " =\r\n"); } if (token[0] && value[0]) { /* parse arguments here */ if (strcmp(token, "Verbose") == 0) { daemon_local->flags.vflag = atoi(value); /*printf("Option: %s=%s\n",token,value); */ } else if (strcmp(token, "PrintASCII") == 0) { daemon_local->flags.aflag = atoi(value); /*printf("Option: %s=%s\n",token,value); */ } else if (strcmp(token, "PrintHex") == 0) { daemon_local->flags.xflag = atoi(value); /*printf("Option: %s=%s\n",token,value); */ } else if (strcmp(token, "PrintHeadersOnly") == 0) { daemon_local->flags.sflag = atoi(value); /*printf("Option: %s=%s\n",token,value); */ } else if (strcmp(token, "SendSerialHeader") == 0) { daemon_local->flags.lflag = atoi(value); /*printf("Option: %s=%s\n",token,value); */ } else if (strcmp(token, "SendContextRegistration") == 0) { daemon_local->flags.rflag = atoi(value); /*printf("Option: %s=%s\n",token,value); */ } else if (strcmp(token, "SendContextRegistrationOption") == 0) { daemon_local->flags.autoResponseGetLogInfoOption = atoi(value); /*printf("Option: %s=%s\n",token,value); */ } else if (strcmp(token, "SendMessageTime") == 0) { daemon_local->flags.sendMessageTime = atoi(value); /*printf("Option: %s=%s\n",token,value); */ } else if (strcmp(token, "RS232SyncSerialHeader") == 0) { daemon_local->flags.mflag = atoi(value); /*printf("Option: %s=%s\n",token,value); */ } else if (strcmp(token, "TCPSyncSerialHeader") == 0) { daemon_local->flags.nflag = atoi(value); /*printf("Option: %s=%s\n",token,value); */ } else if (strcmp(token, "RS232DeviceName") == 0) { strncpy(daemon_local->flags.yvalue, value, NAME_MAX); daemon_local->flags.yvalue[NAME_MAX] = 0; /*printf("Option: %s=%s\n",token,value); */ } else if (strcmp(token, "RS232Baudrate") == 0) { strncpy(daemon_local->flags.bvalue, value, NAME_MAX); daemon_local->flags.bvalue[NAME_MAX] = 0; /*printf("Option: %s=%s\n",token,value); */ } else if (strcmp(token, "ECUId") == 0) { strncpy(daemon_local->flags.evalue, value, NAME_MAX); daemon_local->flags.evalue[NAME_MAX] = 0; /*printf("Option: %s=%s\n",token,value); */ } else if (strcmp(token, "PersistanceStoragePath") == 0) { strncpy(daemon_local->flags.ivalue, value, NAME_MAX); daemon_local->flags.ivalue[NAME_MAX] = 0; /*printf("Option: %s=%s\n",token,value); */ } else if (strcmp(token, "LoggingMode") == 0) { daemon_local->flags.loggingMode = atoi(value); /*printf("Option: %s=%s\n",token,value); */ } else if (strcmp(token, "LoggingLevel") == 0) { daemon_local->flags.loggingLevel = atoi(value); /*printf("Option: %s=%s\n",token,value); */ } else if (strcmp(token, "LoggingFilename") == 0) { strncpy(daemon_local->flags.loggingFilename, value, sizeof(daemon_local->flags.loggingFilename) - 1); daemon_local->flags.loggingFilename[sizeof(daemon_local->flags.loggingFilename) - 1] = 0; /*printf("Option: %s=%s\n",token,value); */ } else if (strcmp(token, "TimeOutOnSend") == 0) { daemon_local->timeoutOnSend = atoi(value); /*printf("Option: %s=%s\n",token,value); */ } else if (strcmp(token, "RingbufferMinSize") == 0) { sscanf(value, "%lu", &(daemon_local->RingbufferMinSize)); } else if (strcmp(token, "RingbufferMaxSize") == 0) { sscanf(value, "%lu", &(daemon_local->RingbufferMaxSize)); } else if (strcmp(token, "RingbufferStepSize") == 0) { sscanf(value, "%lu", &(daemon_local->RingbufferStepSize)); } else if (strcmp(token, "DaemonFIFOSize") == 0) { sscanf(value, "%lu", &(daemon_local->daemonFifoSize)); } else if (strcmp(token, "SharedMemorySize") == 0) { daemon_local->flags.sharedMemorySize = atoi(value); /*printf("Option: %s=%s\n",token,value); */ } else if (strcmp(token, "OfflineTraceDirectory") == 0) { strncpy(daemon_local->flags.offlineTraceDirectory, value, sizeof(daemon_local->flags.offlineTraceDirectory) - 1); daemon_local->flags.offlineTraceDirectory[sizeof(daemon_local->flags.offlineTraceDirectory) - 1] = 0; /*printf("Option: %s=%s\n",token,value); */ } else if (strcmp(token, "OfflineTraceFileSize") == 0) { daemon_local->flags.offlineTraceFileSize = atoi(value); /*printf("Option: %s=%s\n",token,value); */ } else if (strcmp(token, "OfflineTraceMaxSize") == 0) { daemon_local->flags.offlineTraceMaxSize = atoi(value); /*printf("Option: %s=%s\n",token,value); */ } else if (strcmp(token, "OfflineTraceFileNameTimestampBased") == 0) { daemon_local->flags.offlineTraceFilenameTimestampBased = atoi(value); /*printf("Option: %s=%s\n",token,value); */ } else if (strcmp(token, "SendECUSoftwareVersion") == 0) { daemon_local->flags.sendECUSoftwareVersion = atoi(value); /*printf("Option: %s=%s\n",token,value); */ } else if (strcmp(token, "PathToECUSoftwareVersion") == 0) { strncpy(daemon_local->flags.pathToECUSoftwareVersion, value, sizeof(daemon_local->flags.pathToECUSoftwareVersion) - 1); daemon_local->flags.pathToECUSoftwareVersion[sizeof(daemon_local->flags.pathToECUSoftwareVersion) - 1] = 0; /*printf("Option: %s=%s\n",token,value); */ } else if (strcmp(token, "SendTimezone") == 0) { daemon_local->flags.sendTimezone = atoi(value); /*printf("Option: %s=%s\n",token,value); */ } else if (strcmp(token, "OfflineLogstorageMaxDevices") == 0) { daemon_local->flags.offlineLogstorageMaxDevices = atoi(value); } else if (strcmp(token, "OfflineLogstorageDirPath") == 0) { strncpy(daemon_local->flags.offlineLogstorageDirPath, value, sizeof(daemon_local->flags.offlineLogstorageDirPath) - 1); } else if (strcmp(token, "OfflineLogstorageTimestamp") == 0) { /* Check if set to 0, default otherwise */ if (atoi(value) == 0) daemon_local->flags.offlineLogstorageTimestamp = 0; } else if (strcmp(token, "OfflineLogstorageDelimiter") == 0) { /* Check if valid punctuation, default otherwise*/ if (ispunct((char)value[0])) daemon_local->flags.offlineLogstorageDelimiter = (char)value[0]; } else if (strcmp(token, "OfflineLogstorageMaxCounter") == 0) { daemon_local->flags.offlineLogstorageMaxCounter = atoi(value); daemon_local->flags.offlineLogstorageMaxCounterIdx = strlen(value); } else if (strcmp(token, "OfflineLogstorageCacheSize") == 0) { daemon_local->flags.offlineLogstorageCacheSize = (unsigned int)atoi(value); dlt_daemon_logstorage_set_logstorage_cache_size( daemon_local->flags.offlineLogstorageCacheSize); } else if (strcmp(token, "ControlSocketPath") == 0) { memset( daemon_local->flags.ctrlSockPath, 0, DLT_DAEMON_FLAG_MAX); strncpy( daemon_local->flags.ctrlSockPath, value, DLT_DAEMON_FLAG_MAX - 1); } else if (strcmp(token, "GatewayMode") == 0) { daemon_local->flags.gatewayMode = atoi(value); /*printf("Option: %s=%s\n",token,value); */ } else if (strcmp(token, "GatewayConfigFile") == 0) { memset( daemon_local->flags.gatewayConfigFile, 0, DLT_DAEMON_FLAG_MAX); strncpy( daemon_local->flags.gatewayConfigFile, value, DLT_DAEMON_FLAG_MAX - 1); } else if (strcmp(token, "ContextLogLevel") == 0) { int const intval = atoi(value); if ((intval >= DLT_LOG_OFF) && (intval <= DLT_LOG_VERBOSE)) { daemon_local->flags.contextLogLevel = intval; printf("Option: %s=%s\n", token, value); } else { fprintf(stderr, "Invalid value for ContextLogLevel: %i. Must be in range [%i..%i]\n", intval, DLT_LOG_OFF, DLT_LOG_VERBOSE); } } else if (strcmp(token, "ContextTraceStatus") == 0) { int const intval = atoi(value); if ((intval >= DLT_TRACE_STATUS_OFF) && (intval <= DLT_TRACE_STATUS_ON)) { daemon_local->flags.contextTraceStatus = intval; printf("Option: %s=%s\n", token, value); } else { fprintf(stderr, "Invalid value for ContextTraceStatus: %i. Must be in range [%i..%i]\n", intval, DLT_TRACE_STATUS_OFF, DLT_TRACE_STATUS_ON); } } else if (strcmp(token, "ForceContextLogLevelAndTraceStatus") == 0) { int const intval = atoi(value); if ((intval >= 0) && (intval <= 1)) { daemon_local->flags.enforceContextLLAndTS = intval; printf("Option: %s=%s\n", token, value); } else { fprintf(stderr, "Invalid value for ForceContextLogLevelAndTraceStatus: %i. Must be 0, 1\n", intval); } } #ifndef DLT_USE_UNIX_SOCKET_IPC else if(strcmp(token, "DaemonFifoGroup") == 0) { strncpy(daemon_local->flags.daemonFifoGroup, value, NAME_MAX); daemon_local->flags.daemonFifoGroup[NAME_MAX] = 0; } #endif #ifdef UDP_CONNECTION_SUPPORT else if (strcmp(token, "UDPConnectionSetup") == 0) { const long longval = strtol(value, NULL, 10); if ((longval == MULTICAST_CONNECTION_DISABLED) || (longval == MULTICAST_CONNECTION_ENABLED)) { daemon_local->UDPConnectionSetup = longval; printf("Option: %s=%s\n", token, value); } else { daemon_local->UDPConnectionSetup = MULTICAST_CONNECTION_DISABLED; fprintf(stderr, "Invalid value for UDPConnectionSetup set to default %ld\n", longval); } } else if (strcmp(token, "UDPMulticastIPAddress") == 0) { strncpy(daemon_local->UDPMulticastIPAddress, value, MULTICASTIP_MAX_SIZE - 1); } else if (strcmp(token, "UDPMulticastIPPort") == 0) { daemon_local->UDPMulticastIPPort = strtol(value, NULL, 10); } #endif else if (strcmp(token, "BindAddress") == 0) { DltBindAddress_t *newNode = NULL; DltBindAddress_t *temp = NULL; char *tok = strtok(value, ",;"); if (tok != NULL) { daemon_local->flags.ipNodes = calloc(1, sizeof(DltBindAddress_t)); if (daemon_local->flags.ipNodes == NULL) { dlt_vlog(LOG_ERR, "Could not allocate for IP list\n"); return -1; } else { strncpy(daemon_local->flags.ipNodes->ip, tok, sizeof(daemon_local->flags.ipNodes->ip) - 1); daemon_local->flags.ipNodes->next = NULL; temp = daemon_local->flags.ipNodes; tok = strtok(NULL, ",;"); while (tok != NULL) { newNode = calloc(1, sizeof(DltBindAddress_t)); if (newNode == NULL) { dlt_vlog(LOG_ERR, "Could not allocate for IP list\n"); return -1; } else { strncpy(newNode->ip, tok, sizeof(newNode->ip) - 1); } temp->next = newNode; temp = temp->next; tok = strtok(NULL, ",;"); } } } else { dlt_vlog(LOG_WARNING, "BindAddress option is empty\n"); } } else { fprintf(stderr, "Unknown option: %s=%s\n", token, value); } } } else { break; } } fclose (pFile); } else { fprintf(stderr, "Cannot open configuration file: %s\n", filename); } return 0; } #ifndef DLT_USE_UNIX_SOCKET_IPC static DltReturnValue dlt_daemon_create_pipes_dir(char *dir) { int ret = DLT_RETURN_OK; if (dir == NULL) { dlt_vlog(LOG_ERR, "%s: Invalid parameter\n", __func__); return DLT_RETURN_WRONG_PARAMETER; } /* create dlt pipes directory */ ret = mkdir(dir, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH | S_ISVTX); if ((ret == -1) && (errno != EEXIST)) { dlt_vlog(LOG_ERR, "FIFO user dir %s cannot be created (%s)!\n", dir, strerror(errno)); return DLT_RETURN_ERROR; } /* S_ISGID cannot be set by mkdir, let's reassign right bits */ ret = chmod(dir, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IXGRP | S_IROTH | S_IWOTH | S_IXOTH | S_ISGID | S_ISVTX); if (ret == -1) { dlt_vlog(LOG_ERR, "FIFO user dir %s cannot be chmoded (%s)!\n", dir, strerror(errno)); return DLT_RETURN_ERROR; } return ret; } #endif /** * Main function of tool. */ int main(int argc, char *argv[]) { char version[DLT_DAEMON_TEXTBUFSIZE]; char local_str[DLT_DAEMON_TEXTBUFSIZE]; DltDaemonLocal daemon_local; DltDaemon daemon; int back = 0; memset(&daemon_local, 0, sizeof(DltDaemonLocal)); memset(&daemon, 0, sizeof(DltDaemon)); /* Command line option handling */ if ((back = option_handling(&daemon_local, argc, argv)) < 0) { if (back != -2) fprintf (stderr, "option_handling() failed!\n"); return -1; } /* Configuration file option handling */ if ((back = option_file_parser(&daemon_local)) < 0) { if (back != -2) fprintf (stderr, "option_file_parser() failed!\n"); return -1; } /* Initialize internal logging facility */ dlt_log_set_filename(daemon_local.flags.loggingFilename); dlt_log_set_level(daemon_local.flags.loggingLevel); dlt_log_init(daemon_local.flags.loggingMode); /* Print version information */ dlt_get_version(version, DLT_DAEMON_TEXTBUFSIZE); dlt_vlog(LOG_NOTICE, "Starting DLT Daemon; %s\n", version); PRINT_FUNCTION_VERBOSE(daemon_local.flags.vflag); #ifndef DLT_USE_UNIX_SOCKET_IPC /* Make sure the parent user directory is created */ if (dlt_mkdir_recursive(dltFifoBaseDir) != 0) { dlt_vlog(LOG_ERR, "Base dir %s cannot be created!\n", dltFifoBaseDir); return -1; } #endif /* --- Daemon init phase 1 begin --- */ if (dlt_daemon_local_init_p1(&daemon, &daemon_local, daemon_local.flags.vflag) == -1) { dlt_log(LOG_CRIT, "Initialization of phase 1 failed!\n"); return -1; } /* --- Daemon init phase 1 end --- */ if (dlt_daemon_prepare_event_handling(&daemon_local.pEvent)) { /* TODO: Perform clean-up */ dlt_log(LOG_CRIT, "Initialization of event handling failed!\n"); return -1; } /* --- Daemon connection init begin */ if (dlt_daemon_local_connection_init(&daemon, &daemon_local, daemon_local.flags.vflag) == -1) { dlt_log(LOG_CRIT, "Initialization of local connections failed!\n"); return -1; } /* --- Daemon connection init end */ /* --- Daemon init phase 2 begin --- */ if (dlt_daemon_local_init_p2(&daemon, &daemon_local, daemon_local.flags.vflag) == -1) { dlt_log(LOG_CRIT, "Initialization of phase 2 failed!\n"); return -1; } /* --- Daemon init phase 2 end --- */ if (daemon_local.flags.offlineLogstorageDirPath[0]) if (dlt_daemon_logstorage_setup_internal_storage( &daemon, &daemon_local, daemon_local.flags.offlineLogstorageDirPath, daemon_local.flags.vflag) == -1) dlt_log(LOG_INFO, "Setting up internal offline log storage failed!\n"); /* create fd for watchdog */ #ifdef DLT_SYSTEMD_WATCHDOG_ENABLE { char *watchdogUSec = getenv("WATCHDOG_USEC"); int watchdogTimeoutSeconds = 0; dlt_log(LOG_DEBUG, "Systemd watchdog initialization\n"); if (watchdogUSec) watchdogTimeoutSeconds = atoi(watchdogUSec) / 2000000; watchdog_trigger_interval = watchdogTimeoutSeconds; create_timer_fd(&daemon_local, watchdogTimeoutSeconds, watchdogTimeoutSeconds, DLT_TIMER_SYSTEMD); } #endif /* create fd for timer timing packets */ create_timer_fd(&daemon_local, 1, 1, DLT_TIMER_PACKET); /* create fd for timer ecu version */ if ((daemon_local.flags.sendECUSoftwareVersion > 0) || (daemon_local.flags.sendTimezone > 0)) create_timer_fd(&daemon_local, 60, 60, DLT_TIMER_ECU); /* initiate gateway */ if (daemon_local.flags.gatewayMode == 1) { if (dlt_gateway_init(&daemon_local, daemon_local.flags.vflag) == -1) { dlt_log(LOG_CRIT, "Fail to create gateway\n"); return -1; } /* create gateway timer */ create_timer_fd(&daemon_local, DLT_GATEWAY_TIMER_INTERVAL, DLT_GATEWAY_TIMER_INTERVAL, DLT_TIMER_GATEWAY); } /* For offline tracing we still can use the same states */ /* as for socket sending. Using this trick we see the traces */ /* In the offline trace AND in the socket stream. */ if (daemon_local.flags.yvalue[0]) dlt_daemon_change_state(&daemon, DLT_DAEMON_STATE_SEND_DIRECT); else dlt_daemon_change_state(&daemon, DLT_DAEMON_STATE_BUFFER); dlt_daemon_init_user_information(&daemon, &daemon_local.pGateway, daemon_local.flags.gatewayMode, daemon_local.flags.vflag); if (dlt_daemon_load_runtime_configuration(&daemon, daemon_local.flags.ivalue, daemon_local.flags.vflag) == -1) { dlt_log(LOG_ERR, "Could not load runtime config\n"); return -1; } dlt_daemon_log_internal(&daemon, &daemon_local, "Daemon launched. Starting to output traces...", daemon_local.flags.vflag); /* Even handling loop. */ while ((back >= 0) && (g_exit >= 0)) back = dlt_daemon_handle_event(&daemon_local.pEvent, &daemon, &daemon_local); snprintf(local_str, DLT_DAEMON_TEXTBUFSIZE, "Exiting DLT daemon... [%d]", g_signo); dlt_daemon_log_internal(&daemon, &daemon_local, local_str, daemon_local.flags.vflag); dlt_log(LOG_NOTICE, local_str); dlt_daemon_local_cleanup(&daemon, &daemon_local, daemon_local.flags.vflag); dlt_gateway_deinit(&daemon_local.pGateway, daemon_local.flags.vflag); dlt_daemon_free(&daemon, daemon_local.flags.vflag); dlt_log(LOG_NOTICE, "Leaving DLT daemon\n"); return 0; } /* main() */ int dlt_daemon_local_init_p1(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose) { PRINT_FUNCTION_VERBOSE(verbose); int ret = DLT_RETURN_OK; if ((daemon == 0) || (daemon_local == 0)) { dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_local_init_p1()\n"); return -1; } #if defined(DLT_SYSTEMD_WATCHDOG_ENABLE) || defined(DLT_SYSTEMD_ENABLE) ret = sd_booted(); if (ret == 0) { dlt_log(LOG_CRIT, "System not booted with systemd!\n"); } else if (ret < 0) { dlt_log(LOG_CRIT, "sd_booted failed!\n"); return -1; } else { dlt_log(LOG_INFO, "System booted with systemd\n"); } #endif #ifndef DLT_USE_UNIX_SOCKET_IPC if (dlt_daemon_create_pipes_dir(daemon_local->flags.userPipesDir) == DLT_RETURN_ERROR) return DLT_RETURN_ERROR; #endif /* Check for daemon mode */ if (daemon_local->flags.dflag) dlt_daemon_daemonize(daemon_local->flags.vflag); /* Re-Initialize internal logging facility after fork */ dlt_log_set_filename(daemon_local->flags.loggingFilename); dlt_log_set_level(daemon_local->flags.loggingLevel); dlt_log_init(daemon_local->flags.loggingMode); /* initialise structure to use DLT file */ ret = dlt_file_init(&(daemon_local->file), daemon_local->flags.vflag); if (ret == DLT_RETURN_ERROR) { dlt_log(LOG_ERR, "Could not initialize file structure\n"); /* Return value ignored, dlt daemon will exit */ dlt_file_free(&(daemon_local->file), daemon_local->flags.vflag); return ret; } signal(SIGPIPE, SIG_IGN); signal(SIGTERM, dlt_daemon_signal_handler); /* software termination signal from kill */ signal(SIGHUP, dlt_daemon_signal_handler); /* hangup signal */ signal(SIGQUIT, dlt_daemon_signal_handler); signal(SIGINT, dlt_daemon_signal_handler); return DLT_RETURN_OK; } int dlt_daemon_local_init_p2(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose) { PRINT_FUNCTION_VERBOSE(verbose); if ((daemon == 0) || (daemon_local == 0)) { dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_local_init_p2()\n"); return -1; } /* Daemon data */ if (dlt_daemon_init(daemon, daemon_local->RingbufferMinSize, daemon_local->RingbufferMaxSize, daemon_local->RingbufferStepSize, daemon_local->flags.ivalue, daemon_local->flags.contextLogLevel, daemon_local->flags.contextTraceStatus, daemon_local->flags.enforceContextLLAndTS, daemon_local->flags.vflag) == -1) { dlt_log(LOG_ERR, "Could not initialize daemon data\n"); return -1; } /* init offline trace */ if (((daemon->mode == DLT_USER_MODE_INTERNAL) || (daemon->mode == DLT_USER_MODE_BOTH)) && daemon_local->flags.offlineTraceDirectory[0]) { if (dlt_offline_trace_init(&(daemon_local->offlineTrace), daemon_local->flags.offlineTraceDirectory, daemon_local->flags.offlineTraceFileSize, daemon_local->flags.offlineTraceMaxSize, daemon_local->flags.offlineTraceFilenameTimestampBased) == -1) { dlt_log(LOG_ERR, "Could not initialize offline trace\n"); return -1; } } /* Init offline logstorage for MAX devices */ if (daemon_local->flags.offlineLogstorageMaxDevices > 0) { daemon->storage_handle = malloc(sizeof(DltLogStorage) * daemon_local->flags.offlineLogstorageMaxDevices); if (daemon->storage_handle == NULL) { dlt_log(LOG_ERR, "Could not initialize offline logstorage\n"); return -1; } memset(daemon->storage_handle, 0, (sizeof(DltLogStorage) * daemon_local->flags.offlineLogstorageMaxDevices)); } /* Set ECU id of daemon */ if (daemon_local->flags.evalue[0]) dlt_set_id(daemon->ecuid, daemon_local->flags.evalue); else dlt_set_id(daemon->ecuid, DLT_DAEMON_ECU_ID); /* Set flag for optional sending of serial header */ daemon->sendserialheader = daemon_local->flags.lflag; #ifdef DLT_SHM_ENABLE /* init shared memory */ if (dlt_shm_init_server(&(daemon_local->dlt_shm), daemon_local->flags.dltShmName, daemon_local->flags.sharedMemorySize) == DLT_RETURN_ERROR) { dlt_log(LOG_ERR, "Could not initialize shared memory\n"); return -1; } #endif /* prepare main loop */ if (dlt_message_init(&(daemon_local->msg), daemon_local->flags.vflag) == DLT_RETURN_ERROR) { dlt_log(LOG_ERR, "Could not initialize message\n"); return -1; } /* configure sending timing packets */ if (daemon_local->flags.sendMessageTime) daemon->timingpackets = 1; /* Binary semaphore for thread */ if (sem_init(&dlt_daemon_mutex, 0, 1) == -1) { dlt_log(LOG_ERR, "Could not initialize binary semaphore\n"); return -1; } /* Get ECU version info from a file. If it fails, use dlt_version as fallback. */ if (dlt_daemon_local_ecu_version_init(daemon, daemon_local, daemon_local->flags.vflag) < 0) { daemon->ECUVersionString = malloc(DLT_DAEMON_TEXTBUFSIZE); if (daemon->ECUVersionString == 0) { dlt_log(LOG_WARNING, "Could not allocate memory for version string\n"); return -1; } dlt_get_version(daemon->ECUVersionString, DLT_DAEMON_TEXTBUFSIZE); } return 0; } static int dlt_daemon_init_serial(DltDaemonLocal *daemon_local) { /* create and open serial connection from/to client */ /* open serial connection */ int fd = -1; if (daemon_local->flags.yvalue[0] == '\0') return 0; fd = open(daemon_local->flags.yvalue, O_RDWR); if (fd < 0) { dlt_vlog(LOG_ERR, "Failed to open serial device %s\n", daemon_local->flags.yvalue); daemon_local->flags.yvalue[0] = 0; return -1; } if (isatty(fd)) { int speed = DLT_DAEMON_SERIAL_DEFAULT_BAUDRATE; if (daemon_local->flags.bvalue[0]) speed = atoi(daemon_local->flags.bvalue); daemon_local->baudrate = dlt_convert_serial_speed(speed); if (dlt_setup_serial(fd, daemon_local->baudrate) < 0) { close(fd); daemon_local->flags.yvalue[0] = 0; dlt_vlog(LOG_ERR, "Failed to configure serial device %s (%s) \n", daemon_local->flags.yvalue, strerror(errno)); return -1; } if (daemon_local->flags.vflag) dlt_log(LOG_DEBUG, "Serial init done\n"); } else { close(fd); fprintf(stderr, "Device is not a serial device, device = %s (%s) \n", daemon_local->flags.yvalue, strerror(errno)); daemon_local->flags.yvalue[0] = 0; return -1; } return dlt_connection_create(daemon_local, &daemon_local->pEvent, fd, POLLIN, DLT_CONNECTION_CLIENT_MSG_SERIAL); } #ifndef DLT_USE_UNIX_SOCKET_IPC static int dlt_daemon_init_fifo(DltDaemonLocal *daemon_local) { int ret; int fd = -1; int fifo_size; /* open named pipe(FIFO) to receive DLT messages from users */ umask(0); /* Try to delete existing pipe, ignore result of unlink */ const char *tmpFifo = daemon_local->flags.daemonFifoName; unlink(tmpFifo); ret = mkfifo(tmpFifo, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); if (ret == -1) { dlt_vlog(LOG_WARNING, "FIFO user %s cannot be created (%s)!\n", tmpFifo, strerror(errno)); return -1; } /* if */ /* Set group of daemon FIFO */ if (daemon_local->flags.daemonFifoGroup[0] != 0) { errno = 0; struct group * group_dlt = getgrnam(daemon_local->flags.daemonFifoGroup); if (group_dlt) { ret = chown(tmpFifo, -1, group_dlt->gr_gid); if (ret == -1) { dlt_vlog(LOG_ERR, "FIFO user %s cannot be chowned to group %s (%s)\n", tmpFifo, daemon_local->flags.daemonFifoGroup, strerror(errno)); } } else if ((errno == 0) || (errno == ENOENT) || (errno == EBADF) || (errno == EPERM)) { dlt_vlog(LOG_ERR, "Group name %s is not found (%s)\n", daemon_local->flags.daemonFifoGroup, strerror(errno)); } else { dlt_vlog(LOG_ERR, "Failed to get group id of %s (%s)\n", daemon_local->flags.daemonFifoGroup, strerror(errno)); } } fd = open(tmpFifo, O_RDWR); if (fd == -1) { dlt_vlog(LOG_WARNING, "FIFO user %s cannot be opened (%s)!\n", tmpFifo, strerror(errno)); return -1; } /* if */ if (daemon_local->daemonFifoSize != 0) { /* Set Daemon FIFO size */ if (fcntl(fd, F_SETPIPE_SZ, daemon_local->daemonFifoSize) == -1) { dlt_vlog(LOG_ERR, "set FIFO size error: %s\n", strerror(errno)); } } /* Get Daemon FIFO size */ if ((fifo_size = fcntl(fd, F_GETPIPE_SZ, 0)) == -1) { dlt_vlog(LOG_ERR, "get FIFO size error: %s\n", strerror(errno)); } else { dlt_vlog(LOG_INFO, "FIFO size: %d\n", fifo_size); } /* Early init, to be able to catch client (app) connections * as soon as possible. This registration is automatically ignored * during next execution. */ return dlt_connection_create(daemon_local, &daemon_local->pEvent, fd, POLLIN, DLT_CONNECTION_APP_MSG); } #endif int dlt_daemon_local_connection_init(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose) { int fd = -1; int mask = 0; DltBindAddress_t *head = daemon_local->flags.ipNodes; PRINT_FUNCTION_VERBOSE(verbose); if ((daemon == NULL) || (daemon_local == NULL)) { dlt_vlog(LOG_ERR, "%s: Invalid function parameters\n", __func__); return -1; } #ifdef DLT_USE_UNIX_SOCKET_IPC /* create and open socket to receive incoming connections from user application * socket access permission set to srw-rw-rw- (666) */ mask = S_IXUSR | S_IXGRP | S_IXOTH; if (dlt_daemon_unix_socket_open(&fd, daemon_local->flags.appSockPath, SOCK_STREAM, mask) == DLT_RETURN_OK) { if (dlt_connection_create(daemon_local, &daemon_local->pEvent, fd, POLLIN, DLT_CONNECTION_APP_CONNECT)) { dlt_log(LOG_CRIT, "Could not initialize app socket.\n"); return DLT_RETURN_ERROR; } } else { dlt_log(LOG_CRIT, "Could not initialize app socket.\n"); return DLT_RETURN_ERROR; } #else if (dlt_daemon_init_fifo(daemon_local)) { dlt_log(LOG_ERR, "Unable to initialize fifo.\n"); return DLT_RETURN_ERROR; } #endif /* create and open socket to receive incoming connections from client */ daemon_local->client_connections = 0; if (head == NULL) { /* no IP set in BindAddress option, will use "0.0.0.0" as default */ if (dlt_daemon_socket_open(&fd, daemon_local->flags.port, "0.0.0.0") == DLT_RETURN_OK) { if (dlt_connection_create(daemon_local, &daemon_local->pEvent, fd, POLLIN, DLT_CONNECTION_CLIENT_CONNECT)) { dlt_log(LOG_ERR, "Could not initialize main socket.\n"); return DLT_RETURN_ERROR; } } else { dlt_log(LOG_ERR, "Could not initialize main socket.\n"); return DLT_RETURN_ERROR; } } else { while (head != NULL) { /* open socket for each IP in the bindAddress list */ if (dlt_daemon_socket_open(&fd, daemon_local->flags.port, head->ip) == DLT_RETURN_OK) { if (dlt_connection_create(daemon_local, &daemon_local->pEvent, fd, POLLIN, DLT_CONNECTION_CLIENT_CONNECT)) { dlt_log(LOG_ERR, "Could not initialize main socket.\n"); return DLT_RETURN_ERROR; } } else { dlt_log(LOG_ERR, "Could not initialize main socket.\n"); return DLT_RETURN_ERROR; } head = head->next; } } #ifdef UDP_CONNECTION_SUPPORT if (daemon_local->UDPConnectionSetup == MULTICAST_CONNECTION_ENABLED) { if (dlt_daemon_udp_connection_setup(daemon_local) < 0) { dlt_log(LOG_ERR, "UDP fd creation and register in epoll failed\n"); return DLT_RETURN_ERROR; } else { dlt_log(LOG_INFO, "UDP fd creation and register in epoll success\n"); } } #endif /* create and open unix socket to receive incoming connections from * control application * socket access permission set to srw-rw---- (660) */ mask = S_IXUSR | S_IXGRP | S_IROTH | S_IWOTH | S_IXOTH; if (dlt_daemon_unix_socket_open(&fd, daemon_local->flags.ctrlSockPath, SOCK_STREAM, mask) == DLT_RETURN_OK) { if (dlt_connection_create(daemon_local, &daemon_local->pEvent, fd, POLLIN, DLT_CONNECTION_CONTROL_CONNECT)) { dlt_log(LOG_ERR, "Could not initialize control socket.\n"); return DLT_RETURN_ERROR; } } else { dlt_log(LOG_ERR, "Could not initialize control socket.\n"); return DLT_RETURN_ERROR; } /* Init serial */ if (dlt_daemon_init_serial(daemon_local) < 0) { dlt_log(LOG_ERR, "Could not initialize daemon data\n"); return DLT_RETURN_ERROR; } return 0; } int dlt_daemon_local_ecu_version_init(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose) { char *version = NULL; FILE *f = NULL; PRINT_FUNCTION_VERBOSE(verbose); /* By default, version string is null. */ daemon->ECUVersionString = NULL; /* Open the file. Bail out if error occurs */ f = fopen(daemon_local->flags.pathToECUSoftwareVersion, "r"); if (f == NULL) { /* Error level notice, because this might be deliberate choice */ dlt_log(LOG_NOTICE, "Failed to open ECU Software version file.\n"); return -1; } /* Get the file size. Bail out if stat fails. */ int fd = fileno(f); struct stat s_buf; if (fstat(fd, &s_buf) < 0) { dlt_log(LOG_WARNING, "Failed to stat ECU Software version file.\n"); fclose(f); return -1; } /* Bail out if file is too large. Use DLT_DAEMON_TEXTBUFSIZE max. * Reserve one byte for trailing '\0' */ off_t size = s_buf.st_size; if (size >= DLT_DAEMON_TEXTBUFSIZE) { dlt_log(LOG_WARNING, "Too large file for ECU version.\n"); fclose(f); return -1; } /* Allocate permanent buffer for version info */ version = malloc(size + 1); if (version == 0) { dlt_log(LOG_WARNING, "Cannot allocate memory for ECU version.\n"); fclose(f); return -1; } off_t offset = 0; while (!feof(f)) { offset += fread(version + offset, 1, size, f); if (ferror(f)) { dlt_log(LOG_WARNING, "Failed to read ECU Software version file.\n"); free(version); fclose(f); return -1; } if (offset > size) { dlt_log(LOG_WARNING, "Too long file for ECU Software version info.\n"); free(version); fclose(f); return -1; } } version[offset] = '\0';/*append null termination at end of version string */ daemon->ECUVersionString = version; fclose(f); return 0; } void dlt_daemon_local_cleanup(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose) { PRINT_FUNCTION_VERBOSE(verbose); if ((daemon == 0) || (daemon_local == 0)) { dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_local_cleanup()\n"); return; } /* Don't receive event anymore */ dlt_event_handler_cleanup_connections(&daemon_local->pEvent); dlt_message_free(&(daemon_local->msg), daemon_local->flags.vflag); /* free shared memory */ if (daemon_local->flags.offlineTraceDirectory[0]) dlt_offline_trace_free(&(daemon_local->offlineTrace)); /* Ignore result */ dlt_file_free(&(daemon_local->file), daemon_local->flags.vflag); #ifndef DLT_USE_UNIX_SOCKET_IPC /* Try to delete existing pipe, ignore result of unlink() */ unlink(daemon_local->flags.daemonFifoName); #else /* Try to delete existing pipe, ignore result of unlink() */ unlink(daemon_local->flags.appSockPath); #endif #ifdef DLT_SHM_ENABLE /* free shared memory */ dlt_shm_free_server(&(daemon_local->dlt_shm), daemon_local->flags.dltShmName); #endif if (daemon_local->flags.offlineLogstorageMaxDevices > 0) { /* disconnect all logstorage devices */ dlt_daemon_logstorage_cleanup(daemon, daemon_local, daemon_local->flags.vflag); free(daemon->storage_handle); } if (daemon->ECUVersionString != NULL) free(daemon->ECUVersionString); unlink(daemon_local->flags.ctrlSockPath); /* free IP list */ free(daemon_local->flags.ipNodes); } void dlt_daemon_exit_trigger() { char tmp[DLT_PATH_MAX] = { 0 }; snprintf(tmp, DLT_PATH_MAX, "%s/dlt", dltFifoBaseDir); (void)unlink(tmp); /* stop event loop */ g_exit = -1; } void dlt_daemon_signal_handler(int sig) { g_signo = sig; switch (sig) { case SIGHUP: case SIGTERM: case SIGINT: case SIGQUIT: { /* finalize the server */ dlt_vlog(LOG_NOTICE, "Exiting DLT daemon due to signal: %s\n", strsignal(sig)); dlt_daemon_exit_trigger(); break; } default: { /* This case should never happen! */ break; } } /* switch */ } /* dlt_daemon_signal_handler() */ void dlt_daemon_daemonize(int verbose) { int i; int fd; PRINT_FUNCTION_VERBOSE(verbose); dlt_log(LOG_NOTICE, "Daemon mode\n"); /* Daemonize */ i = fork(); if (i < 0) { dlt_log(LOG_CRIT, "Unable to fork(), exiting DLT daemon\n"); exit(-1); /* fork error */ } if (i > 0) exit(0); /* parent exits */ /* child (daemon) continues */ /* Process independency */ /* obtain a new process group */ if (setsid() == -1) { dlt_log(LOG_CRIT, "setsid() failed, exiting DLT daemon\n"); exit(-1); /* fork error */ } /* Open standard descriptors stdin, stdout, stderr */ fd = open("/dev/null", O_RDWR); if (fd != -1) { /* Redirect STDOUT to /dev/null */ if (dup2(fd, STDOUT_FILENO) < 0) dlt_vlog(LOG_WARNING, "Failed to direct stdout to /dev/null. Error: %s\n", strerror(errno)); /* Redirect STDERR to /dev/null */ if (dup2(fd, STDERR_FILENO) < 0) dlt_vlog(LOG_WARNING, "Failed to direct stderr to /dev/null. Error: %s\n", strerror(errno)); close(fd); } else { dlt_log(LOG_CRIT, "Error opening /dev/null, exiting DLT daemon\n"); exit(-1); /* fork error */ } /* Set umask */ umask(DLT_DAEMON_UMASK); /* Change to root directory */ if (chdir("/") < 0) dlt_log(LOG_WARNING, "Failed to chdir to root\n"); /* Catch signals */ signal(SIGCHLD, SIG_IGN); /* ignore child */ signal(SIGTSTP, SIG_IGN); /* ignore tty signals */ signal(SIGTTOU, SIG_IGN); signal(SIGTTIN, SIG_IGN); } /* dlt_daemon_daemonize() */ /* This function logs str to the configured output sink (socket, serial, offline trace). * To avoid recursion this function must be called only from DLT highlevel functions. * E. g. calling it to output a failure when the open of the offline trace file fails * would cause an endless loop because dlt_daemon_log_internal() would itself again try * to open the offline trace file. * This is a dlt-daemon only function. The libdlt has no equivalent function available. */ int dlt_daemon_log_internal(DltDaemon *daemon, DltDaemonLocal *daemon_local, char *str, int verbose) { DltMessage msg = { 0 }; static uint8_t uiMsgCount = 0; DltStandardHeaderExtra *pStandardExtra = NULL; uint32_t uiType; uint16_t uiSize; uint32_t uiExtraSize; int ret; PRINT_FUNCTION_VERBOSE(verbose); /* Set storageheader */ msg.storageheader = (DltStorageHeader *)(msg.headerbuffer); dlt_set_storageheader(msg.storageheader, daemon->ecuid); /* Set standardheader */ msg.standardheader = (DltStandardHeader *)(msg.headerbuffer + sizeof(DltStorageHeader)); msg.standardheader->htyp = DLT_HTYP_UEH | DLT_HTYP_WEID | DLT_HTYP_WSID | DLT_HTYP_WTMS | DLT_HTYP_PROTOCOL_VERSION1; msg.standardheader->mcnt = uiMsgCount++; uiExtraSize = DLT_STANDARD_HEADER_EXTRA_SIZE(msg.standardheader->htyp) + (DLT_IS_HTYP_UEH(msg.standardheader->htyp) ? sizeof(DltExtendedHeader) : 0); msg.headersize = sizeof(DltStorageHeader) + sizeof(DltStandardHeader) + uiExtraSize; /* Set extraheader */ pStandardExtra = (DltStandardHeaderExtra *)(msg.headerbuffer + sizeof(DltStorageHeader) + sizeof(DltStandardHeader)); dlt_set_id(pStandardExtra->ecu, daemon->ecuid); pStandardExtra->tmsp = DLT_HTOBE_32(dlt_uptime()); pStandardExtra->seid = DLT_HTOBE_32(getpid()); /* Set extendedheader */ msg.extendedheader = (DltExtendedHeader *)(msg.headerbuffer + sizeof(DltStorageHeader) + sizeof(DltStandardHeader) + DLT_STANDARD_HEADER_EXTRA_SIZE(msg.standardheader->htyp)); msg.extendedheader->msin = DLT_MSIN_VERB | (DLT_TYPE_LOG << DLT_MSIN_MSTP_SHIFT) | ((DLT_LOG_INFO << DLT_MSIN_MTIN_SHIFT) & DLT_MSIN_MTIN); msg.extendedheader->noar = 1; dlt_set_id(msg.extendedheader->apid, "DLTD"); dlt_set_id(msg.extendedheader->ctid, "INTM"); /* Set payload data... */ uiType = DLT_TYPE_INFO_STRG; uiSize = strlen(str) + 1; msg.datasize = sizeof(uint32_t) + sizeof(uint16_t) + uiSize; msg.databuffer = (uint8_t *)malloc(msg.datasize); msg.databuffersize = msg.datasize; if (msg.databuffer == 0) { dlt_log(LOG_WARNING, "Can't allocate buffer for get log info message\n"); return -1; } msg.datasize = 0; memcpy((uint8_t *)(msg.databuffer + msg.datasize), (uint8_t *)(&uiType), sizeof(uint32_t)); msg.datasize += sizeof(uint32_t); memcpy((uint8_t *)(msg.databuffer + msg.datasize), (uint8_t *)(&uiSize), sizeof(uint16_t)); msg.datasize += sizeof(uint16_t); memcpy((uint8_t *)(msg.databuffer + msg.datasize), str, uiSize); msg.datasize += uiSize; /* Calc lengths */ msg.standardheader->len = DLT_HTOBE_16(msg.headersize - sizeof(DltStorageHeader) + msg.datasize); /* Sending data... */ { /* check if overflow occurred */ if (daemon->overflow_counter) { if (dlt_daemon_send_message_overflow(daemon, daemon_local, verbose) == 0) { dlt_vlog(LOG_WARNING, "%u messages discarded!\n", daemon->overflow_counter); daemon->overflow_counter = 0; } } /* look if TCP connection to client is available */ if ((daemon->mode == DLT_USER_MODE_EXTERNAL) || (daemon->mode == DLT_USER_MODE_BOTH)) if ((ret = dlt_daemon_client_send(DLT_DAEMON_SEND_TO_ALL, daemon, daemon_local, msg.headerbuffer, sizeof(DltStorageHeader), msg.headerbuffer + sizeof(DltStorageHeader), msg.headersize - sizeof(DltStorageHeader), msg.databuffer, msg.datasize, verbose))) if (ret == DLT_DAEMON_ERROR_BUFFER_FULL) daemon->overflow_counter++; } free(msg.databuffer); return 0; } int dlt_daemon_process_client_connect(DltDaemon *daemon, DltDaemonLocal *daemon_local, DltReceiver *receiver, int verbose) { socklen_t cli_size; struct sockaddr_un cli; int in_sock = -1; char local_str[DLT_DAEMON_TEXTBUFSIZE] = { '\0' }; PRINT_FUNCTION_VERBOSE(verbose); if ((daemon == NULL) || (daemon_local == NULL) || (receiver == NULL)) { dlt_log(LOG_ERR, "Invalid function parameters used for function " "dlt_daemon_process_client_connect()\n"); return -1; } /* event from TCP server socket, new connection */ cli_size = sizeof(cli); if ((in_sock = accept(receiver->fd, (struct sockaddr *)&cli, &cli_size)) < 0) { dlt_vlog(LOG_ERR, "accept() for socket %d failed: %s\n", receiver->fd, strerror(errno)); return -1; } /* check if file file descriptor was already used, and make it invalid if it * is reused. */ /* This prevents sending messages to wrong file descriptor */ dlt_daemon_applications_invalidate_fd(daemon, daemon->ecuid, in_sock, verbose); dlt_daemon_contexts_invalidate_fd(daemon, daemon->ecuid, in_sock, verbose); /* Set socket timeout in reception */ struct timeval timeout_send; timeout_send.tv_sec = daemon_local->timeoutOnSend; timeout_send.tv_usec = 0; if (setsockopt (in_sock, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout_send, sizeof(timeout_send)) < 0) dlt_log(LOG_WARNING, "setsockopt failed\n"); if (dlt_connection_create(daemon_local, &daemon_local->pEvent, in_sock, POLLIN, DLT_CONNECTION_CLIENT_MSG_TCP)) { dlt_log(LOG_ERR, "Failed to register new client. \n"); /* TODO: Perform clean-up */ return -1; } /* send connection info about connected */ dlt_daemon_control_message_connection_info(in_sock, daemon, daemon_local, DLT_CONNECTION_STATUS_CONNECTED, "", verbose); /* send ecu version string */ if (daemon_local->flags.sendECUSoftwareVersion > 0) { if (daemon_local->flags.sendECUSoftwareVersion > 0) dlt_daemon_control_get_software_version(DLT_DAEMON_SEND_TO_ALL, daemon, daemon_local, daemon_local->flags.vflag); if (daemon_local->flags.sendTimezone > 0) dlt_daemon_control_message_timezone(DLT_DAEMON_SEND_TO_ALL, daemon, daemon_local, daemon_local->flags.vflag); } dlt_vlog(LOG_DEBUG, "New client connection #%d established, Total Clients : %d\n", in_sock, daemon_local->client_connections); dlt_daemon_log_internal(daemon, daemon_local, local_str, daemon_local->flags.vflag); if (daemon_local->client_connections == 1) { if (daemon_local->flags.vflag) dlt_log(LOG_DEBUG, "Send ring-buffer to client\n"); dlt_daemon_change_state(daemon, DLT_DAEMON_STATE_SEND_BUFFER); if (dlt_daemon_send_ringbuffer_to_client(daemon, daemon_local, verbose) == -1) { dlt_log(LOG_WARNING, "Can't send contents of ringbuffer to clients\n"); return -1; } /* send new log state to all applications */ daemon->connectionState = 1; dlt_daemon_user_send_all_log_state(daemon, verbose); } return 0; } int dlt_daemon_process_client_messages(DltDaemon *daemon, DltDaemonLocal *daemon_local, DltReceiver *receiver, int verbose) { int bytes_to_be_removed = 0; int must_close_socket = -1; PRINT_FUNCTION_VERBOSE(verbose); if ((daemon == NULL) || (daemon_local == NULL) || (receiver == NULL)) { dlt_log(LOG_ERR, "Invalid function parameters used for function " "dlt_daemon_process_client_messages()\n"); return -1; } must_close_socket = dlt_receiver_receive(receiver, DLT_RECEIVE_SOCKET); if (must_close_socket < 0) { dlt_daemon_close_socket(receiver->fd, daemon, daemon_local, verbose); return -1; } /* Process all received messages */ while (dlt_message_read(&(daemon_local->msg), (uint8_t *)receiver->buf, receiver->bytesRcvd, daemon_local->flags.nflag, daemon_local->flags.vflag) == DLT_MESSAGE_ERROR_OK) { /* Check for control message */ if ((0 < receiver->fd) && DLT_MSG_IS_CONTROL_REQUEST(&(daemon_local->msg))) dlt_daemon_client_process_control(receiver->fd, daemon, daemon_local, &(daemon_local->msg), daemon_local->flags.vflag); bytes_to_be_removed = daemon_local->msg.headersize + daemon_local->msg.datasize - sizeof(DltStorageHeader); if (daemon_local->msg.found_serialheader) bytes_to_be_removed += sizeof(dltSerialHeader); if (daemon_local->msg.resync_offset) bytes_to_be_removed += daemon_local->msg.resync_offset; if (dlt_receiver_remove(receiver, bytes_to_be_removed) == -1) { dlt_log(LOG_WARNING, "Can't remove bytes from receiver for sockets\n"); return -1; } } /* while */ if (dlt_receiver_move_to_begin(receiver) == -1) { dlt_log(LOG_WARNING, "Can't move bytes to beginning of receiver buffer for sockets\n"); return -1; } if (must_close_socket == 0) /* FIXME: Why the hell do we need to close the socket * on control message reception ?? */ dlt_daemon_close_socket(receiver->fd, daemon, daemon_local, verbose); return 0; } int dlt_daemon_process_client_messages_serial(DltDaemon *daemon, DltDaemonLocal *daemon_local, DltReceiver *receiver, int verbose) { int bytes_to_be_removed = 0; PRINT_FUNCTION_VERBOSE(verbose); if ((daemon == NULL) || (daemon_local == NULL) || (receiver == NULL)) { dlt_log(LOG_ERR, "Invalid function parameters used for function " "dlt_daemon_process_client_messages_serial()\n"); return -1; } if (dlt_receiver_receive(receiver, DLT_RECEIVE_FD) <= 0) { dlt_log(LOG_WARNING, "dlt_receiver_receive_fd() for messages from serial interface " "failed!\n"); return -1; } /* Process all received messages */ while (dlt_message_read(&(daemon_local->msg), (uint8_t *)receiver->buf, receiver->bytesRcvd, daemon_local->flags.mflag, daemon_local->flags.vflag) == DLT_MESSAGE_ERROR_OK) { /* Check for control message */ if (DLT_MSG_IS_CONTROL_REQUEST(&(daemon_local->msg))) { if (dlt_daemon_client_process_control(receiver->fd, daemon, daemon_local, &(daemon_local->msg), daemon_local->flags.vflag) == -1) { dlt_log(LOG_WARNING, "Can't process control messages\n"); return -1; } } bytes_to_be_removed = daemon_local->msg.headersize + daemon_local->msg.datasize - sizeof(DltStorageHeader); if (daemon_local->msg.found_serialheader) bytes_to_be_removed += sizeof(dltSerialHeader); if (daemon_local->msg.resync_offset) bytes_to_be_removed += daemon_local->msg.resync_offset; if (dlt_receiver_remove(receiver, bytes_to_be_removed) == -1) { dlt_log(LOG_WARNING, "Can't remove bytes from receiver for serial connection\n"); return -1; } } /* while */ if (dlt_receiver_move_to_begin(receiver) == -1) { dlt_log(LOG_WARNING, "Can't move bytes to beginning of receiver buffer for serial " "connection\n"); return -1; } return 0; } int dlt_daemon_process_control_connect( DltDaemon *daemon, DltDaemonLocal *daemon_local, DltReceiver *receiver, int verbose) { socklen_t ctrl_size; struct sockaddr_un ctrl; int in_sock = -1; PRINT_FUNCTION_VERBOSE(verbose); if ((daemon == NULL) || (daemon_local == NULL) || (receiver == NULL)) { dlt_log(LOG_ERR, "Invalid function parameters used for function " "dlt_daemon_process_control_connect()\n"); return -1; } /* event from UNIX server socket, new connection */ ctrl_size = sizeof(ctrl); if ((in_sock = accept(receiver->fd, (struct sockaddr *)&ctrl, &ctrl_size)) < 0) { dlt_vlog(LOG_ERR, "accept() on UNIX control socket %d failed: %s\n", receiver->fd, strerror(errno)); return -1; } /* check if file file descriptor was already used, and make it invalid if it * is reused */ /* This prevents sending messages to wrong file descriptor */ dlt_daemon_applications_invalidate_fd(daemon, daemon->ecuid, in_sock, verbose); dlt_daemon_contexts_invalidate_fd(daemon, daemon->ecuid, in_sock, verbose); if (dlt_connection_create(daemon_local, &daemon_local->pEvent, in_sock, POLLIN, DLT_CONNECTION_CONTROL_MSG)) { dlt_log(LOG_ERR, "Failed to register new client. \n"); /* TODO: Perform clean-up */ return -1; } if (verbose) { dlt_vlog(LOG_INFO, "New connection to control client established\n"); } return 0; } #ifdef DLT_USE_UNIX_SOCKET_IPC int dlt_daemon_process_app_connect( DltDaemon *daemon, DltDaemonLocal *daemon_local, DltReceiver *receiver, int verbose) { socklen_t app_size; struct sockaddr_un app; int in_sock = -1; PRINT_FUNCTION_VERBOSE(verbose); if ((daemon == NULL) || (daemon_local == NULL) || (receiver == NULL)) { dlt_vlog(LOG_ERR, "%s: Invalid parameters\n", __func__); return DLT_RETURN_WRONG_PARAMETER; } /* event from UNIX server socket, new connection */ app_size = sizeof(app); if ((in_sock = accept(receiver->fd, (struct sockaddr *)&app, &app_size)) < 0) { dlt_vlog(LOG_ERR, "accept() on UNIX socket %d failed: %s\n", receiver->fd, strerror(errno)); return -1; } /* check if file file descriptor was already used, and make it invalid if it * is reused. This prevents sending messages to wrong file descriptor */ dlt_daemon_applications_invalidate_fd(daemon, daemon->ecuid, in_sock, verbose); dlt_daemon_contexts_invalidate_fd(daemon, daemon->ecuid, in_sock, verbose); if (dlt_connection_create(daemon_local, &daemon_local->pEvent, in_sock, POLLIN, DLT_CONNECTION_APP_MSG)) { dlt_log(LOG_ERR, "Failed to register new application. \n"); close(in_sock); return -1; } if (verbose) { dlt_vlog(LOG_INFO, "New connection to application established\n"); } return 0; } #endif int dlt_daemon_process_control_messages( DltDaemon *daemon, DltDaemonLocal *daemon_local, DltReceiver *receiver, int verbose) { int bytes_to_be_removed = 0; PRINT_FUNCTION_VERBOSE(verbose); if ((daemon == NULL) || (daemon_local == NULL) || (receiver == NULL)) { dlt_log(LOG_ERR, "Invalid function parameters used for function " "dlt_daemon_process_control_messages()\n"); return -1; } if (dlt_receiver_receive(receiver, DLT_RECEIVE_SOCKET) <= 0) { dlt_daemon_close_socket(receiver->fd, daemon, daemon_local, verbose); /* FIXME: Why the hell do we need to close the socket * on control message reception ?? */ return 0; } /* Process all received messages */ while (dlt_message_read( &(daemon_local->msg), (uint8_t *)receiver->buf, receiver->bytesRcvd, daemon_local->flags.nflag, daemon_local->flags.vflag) == DLT_MESSAGE_ERROR_OK) { /* Check for control message */ if ((receiver->fd > 0) && DLT_MSG_IS_CONTROL_REQUEST(&(daemon_local->msg))) dlt_daemon_client_process_control(receiver->fd, daemon, daemon_local, &(daemon_local->msg), daemon_local->flags.vflag); bytes_to_be_removed = daemon_local->msg.headersize + daemon_local->msg.datasize - sizeof(DltStorageHeader); if (daemon_local->msg.found_serialheader) bytes_to_be_removed += sizeof(dltSerialHeader); if (daemon_local->msg.resync_offset) bytes_to_be_removed += daemon_local->msg.resync_offset; if (dlt_receiver_remove(receiver, bytes_to_be_removed) == -1) { dlt_log(LOG_WARNING, "Can't remove bytes from receiver for sockets\n"); return -1; } } /* while */ if (dlt_receiver_move_to_begin(receiver) == -1) { dlt_log(LOG_WARNING, "Can't move bytes to beginning of receiver buffer for sockets\n"); return -1; } return 0; } static int dlt_daemon_process_user_message_not_sup(DltDaemon *daemon, DltDaemonLocal *daemon_local, DltReceiver *receiver, int verbose) { DltUserHeader *userheader = (DltUserHeader *)(receiver->buf); (void)daemon; (void)daemon_local; PRINT_FUNCTION_VERBOSE(verbose); dlt_vlog(LOG_ERR, "Invalid user message type received: %d!\n", userheader->message); /* remove user header */ if (dlt_receiver_remove(receiver, sizeof(DltUserHeader)) == -1) dlt_log(LOG_WARNING, "Can't remove bytes from receiver for user messages\n"); return -1; } static dlt_daemon_process_user_message_func process_user_func[DLT_USER_MESSAGE_NOT_SUPPORTED] = { dlt_daemon_process_user_message_not_sup, dlt_daemon_process_user_message_log, dlt_daemon_process_user_message_register_application, dlt_daemon_process_user_message_unregister_application, dlt_daemon_process_user_message_register_context, dlt_daemon_process_user_message_unregister_context, dlt_daemon_process_user_message_not_sup, dlt_daemon_process_user_message_not_sup, dlt_daemon_process_user_message_overflow, dlt_daemon_process_user_message_set_app_ll_ts, #ifdef DLT_SHM_ENABLE dlt_daemon_process_user_message_log_shm, #else dlt_daemon_process_user_message_not_sup, #endif dlt_daemon_process_user_message_not_sup, dlt_daemon_process_user_message_not_sup, dlt_daemon_process_user_message_marker, dlt_daemon_process_user_message_not_sup, dlt_daemon_process_user_message_not_sup }; int dlt_daemon_process_user_messages(DltDaemon *daemon, DltDaemonLocal *daemon_local, DltReceiver *receiver, int verbose) { int offset = 0; int run_loop = 1; int32_t min_size = (int32_t)sizeof(DltUserHeader); DltUserHeader *userheader; int recv; PRINT_FUNCTION_VERBOSE(verbose); if ((daemon == NULL) || (daemon_local == NULL) || (receiver == NULL)) { dlt_log(LOG_ERR, "Invalid function parameters used for function " "dlt_daemon_process_user_messages()\n"); return -1; } #ifdef DLT_USE_UNIX_SOCKET_IPC recv = dlt_receiver_receive(receiver, DLT_RECEIVE_SOCKET); if (recv <= 0) { dlt_daemon_close_socket(receiver->fd, daemon, daemon_local, verbose); return 0; } #else recv = dlt_receiver_receive(receiver, DLT_RECEIVE_FD); if (recv < 0) { dlt_log(LOG_WARNING, "dlt_receiver_receive_fd() for user messages failed!\n"); return -1; } #endif /* look through buffer as long as data is in there */ while ((receiver->bytesRcvd >= min_size) && run_loop) { dlt_daemon_process_user_message_func func = NULL; offset = 0; userheader = (DltUserHeader *)(receiver->buf + offset); while (!dlt_user_check_userheader(userheader) && (offset + min_size <= receiver->bytesRcvd)) { /* resync if necessary */ offset++; userheader = (DltUserHeader *)(receiver->buf + offset); } /* Check for user header pattern */ if (!dlt_user_check_userheader(userheader)) break; /* Set new start offset */ if (offset > 0) dlt_receiver_remove(receiver, offset); if (userheader->message >= DLT_USER_MESSAGE_NOT_SUPPORTED) func = dlt_daemon_process_user_message_not_sup; else func = process_user_func[userheader->message]; if (func(daemon, daemon_local, receiver, daemon_local->flags.vflag) == -1) run_loop = 0; } /* keep not read data in buffer */ if (dlt_receiver_move_to_begin(receiver) == -1) { dlt_log(LOG_WARNING, "Can't move bytes to beginning of receiver buffer for user " "messages\n"); return -1; } return 0; } int dlt_daemon_process_user_message_overflow(DltDaemon *daemon, DltDaemonLocal *daemon_local, DltReceiver *rec, int verbose) { uint32_t len = sizeof(DltUserControlMsgBufferOverflow); DltUserControlMsgBufferOverflow userpayload; PRINT_FUNCTION_VERBOSE(verbose); if ((daemon == NULL) || (daemon_local == NULL) || (rec == NULL)) { dlt_vlog(LOG_ERR, "Invalid function parameters used for %s\n", __func__); return -1; } if (dlt_receiver_check_and_get(rec, &userpayload, len, DLT_RCV_SKIP_HEADER | DLT_RCV_REMOVE) < 0) /* Not enough bytes received */ return -1; /* Store in daemon, that a message buffer overflow has occured */ /* look if TCP connection to client is available or it least message can be put into buffer */ if (dlt_daemon_control_message_buffer_overflow(DLT_DAEMON_SEND_TO_ALL, daemon, daemon_local, userpayload.overflow_counter, userpayload.apid, verbose)) /* there was an error when storing message */ /* add the counter of lost messages to the daemon counter */ daemon->overflow_counter += userpayload.overflow_counter; return 0; } int dlt_daemon_send_message_overflow(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose) { int ret; PRINT_FUNCTION_VERBOSE(verbose); if ((daemon == 0) || (daemon_local == 0)) { dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_user_message_overflow()\n"); return DLT_DAEMON_ERROR_UNKNOWN; } /* Store in daemon, that a message buffer overflow has occured */ if ((ret = dlt_daemon_control_message_buffer_overflow(DLT_DAEMON_SEND_TO_ALL, daemon, daemon_local, daemon->overflow_counter, "", verbose))) return ret; return DLT_DAEMON_ERROR_OK; } int dlt_daemon_process_user_message_register_application(DltDaemon *daemon, DltDaemonLocal *daemon_local, DltReceiver *rec, int verbose) { uint32_t len = sizeof(DltUserControlMsgRegisterApplication); int to_remove = 0; DltDaemonApplication *application = NULL; DltDaemonApplication *old_application = NULL; pid_t old_pid = 0; char description[DLT_DAEMON_DESCSIZE + 1] = { '\0' }; DltUserControlMsgRegisterApplication userapp; char *origin; PRINT_FUNCTION_VERBOSE(verbose); if ((daemon == NULL) || (daemon_local == NULL) || (rec == NULL)) { dlt_vlog(LOG_ERR, "Invalid function parameters used for %s\n", __func__); return -1; } memset(&userapp, 0, sizeof(DltUserControlMsgRegisterApplication)); origin = rec->buf; /* We shall not remove data before checking that everything is there. */ to_remove = dlt_receiver_check_and_get(rec, &userapp, len, DLT_RCV_SKIP_HEADER); if (to_remove < 0) /* Not enough bytes received */ return -1; len = userapp.description_length; if (len > DLT_DAEMON_DESCSIZE) { len = DLT_DAEMON_DESCSIZE; dlt_log(LOG_WARNING, "Application description exceeds limit\n"); } /* adjust buffer pointer */ rec->buf += to_remove + sizeof(DltUserHeader); if (dlt_receiver_check_and_get(rec, description, len, DLT_RCV_NONE) < 0) { dlt_log(LOG_ERR, "Unable to get application description\n"); /* in case description was not readable, set dummy description */ strncpy(description, "Unknown", sizeof("Unknown")); /* unknown len of original description, set to 0 to not remove in next * step. Because message buffer is re-adjusted the corrupted description * is ignored. */ len = 0; } /* adjust to_remove */ to_remove += sizeof(DltUserHeader) + len; /* point to begin of message */ rec->buf = origin; /* We can now remove data. */ if (dlt_receiver_remove(rec, to_remove) != DLT_RETURN_OK) { dlt_log(LOG_WARNING, "Can't remove bytes from receiver\n"); return -1; } old_application = dlt_daemon_application_find(daemon, userapp.apid, daemon->ecuid, verbose); if (old_application != NULL) old_pid = old_application->pid; application = dlt_daemon_application_add(daemon, userapp.apid, userapp.pid, description, rec->fd, daemon->ecuid, verbose); /* send log state to new application */ dlt_daemon_user_send_log_state(daemon, application, verbose); if (application == NULL) { dlt_vlog(LOG_WARNING, "Can't add ApplicationID '%.4s' for PID %d\n", userapp.apid, userapp.pid); return -1; } else if (old_pid != application->pid) { char local_str[DLT_DAEMON_TEXTBUFSIZE] = { '\0' }; snprintf(local_str, DLT_DAEMON_TEXTBUFSIZE, "ApplicationID '%.4s' registered for PID %d, Description=%s\n", application->apid, application->pid, application->application_description); dlt_daemon_log_internal(daemon, daemon_local, local_str, daemon_local->flags.vflag); dlt_log(LOG_DEBUG, local_str); } return 0; } int dlt_daemon_process_user_message_register_context(DltDaemon *daemon, DltDaemonLocal *daemon_local, DltReceiver *rec, int verbose) { int to_remove = 0; uint32_t len = sizeof(DltUserControlMsgRegisterContext); DltUserControlMsgRegisterContext userctxt; char description[DLT_DAEMON_DESCSIZE + 1] = { '\0' }; DltDaemonApplication *application = NULL; DltDaemonContext *context = NULL; DltServiceGetLogInfoRequest *req = NULL; char *origin; DltMessage msg; PRINT_FUNCTION_VERBOSE(verbose); if ((daemon == NULL) || (daemon_local == NULL) || (rec == NULL)) { dlt_vlog(LOG_ERR, "Invalid function parameters used for %s\n", __func__); return -1; } memset(&userctxt, 0, sizeof(DltUserControlMsgRegisterContext)); origin = rec->buf; to_remove = dlt_receiver_check_and_get(rec, &userctxt, len, DLT_RCV_SKIP_HEADER); if (to_remove < 0) /* Not enough bytes received */ return -1; len = userctxt.description_length; if (len > DLT_DAEMON_DESCSIZE) { dlt_vlog(LOG_WARNING, "Context description exceeds limit: %d\n", len); len = DLT_DAEMON_DESCSIZE; } /* adjust buffer pointer */ rec->buf += to_remove + sizeof(DltUserHeader); if (dlt_receiver_check_and_get(rec, description, len, DLT_RCV_NONE) < 0) { dlt_log(LOG_ERR, "Unable to get context description\n"); /* in case description was not readable, set dummy description */ strncpy(description, "Unknown", sizeof("Unknown")); /* unknown len of original description, set to 0 to not remove in next * step. Because message buffer is re-adjusted the corrupted description * is ignored. */ len = 0; } /* adjust to_remove */ to_remove += sizeof(DltUserHeader) + len; /* point to begin of message */ rec->buf = origin; /* We can now remove data. */ if (dlt_receiver_remove(rec, to_remove) != DLT_RETURN_OK) { dlt_log(LOG_WARNING, "Can't remove bytes from receiver\n"); return -1; } application = dlt_daemon_application_find(daemon, userctxt.apid, daemon->ecuid, verbose); if (application == 0) { dlt_vlog(LOG_WARNING, "ApID '%.4s' not found for new ContextID '%.4s' in %s\n", userctxt.apid, userctxt.ctid, __func__); return 0; } /* Set log level */ if (userctxt.log_level == DLT_USER_LOG_LEVEL_NOT_SET) userctxt.log_level = DLT_LOG_DEFAULT; else /* Plausibility check */ if ((userctxt.log_level < DLT_LOG_DEFAULT) || (userctxt.log_level > DLT_LOG_VERBOSE)) return -1; /* Set trace status */ if (userctxt.trace_status == DLT_USER_TRACE_STATUS_NOT_SET) userctxt.trace_status = DLT_TRACE_STATUS_DEFAULT; else /* Plausibility check */ if ((userctxt.trace_status < DLT_TRACE_STATUS_DEFAULT) || (userctxt.trace_status > DLT_TRACE_STATUS_ON)) return -1; context = dlt_daemon_context_add(daemon, userctxt.apid, userctxt.ctid, userctxt.log_level, userctxt.trace_status, userctxt.log_level_pos, application->user_handle, description, daemon->ecuid, verbose); if (context == 0) { dlt_vlog(LOG_WARNING, "Can't add ContextID '%.4s' for ApID '%.4s'\n in %s", userctxt.ctid, userctxt.apid, __func__); return -1; } else { char local_str[DLT_DAEMON_TEXTBUFSIZE] = { '\0' }; snprintf(local_str, DLT_DAEMON_TEXTBUFSIZE, "ContextID '%.4s' registered for ApID '%.4s', Description=%s\n", context->ctid, context->apid, context->context_description); if (verbose) dlt_daemon_log_internal(daemon, daemon_local, local_str, verbose); dlt_log(LOG_DEBUG, local_str); } if (daemon_local->flags.offlineLogstorageMaxDevices) /* Store log level set for offline logstorage into context structure*/ context->storage_log_level = dlt_daemon_logstorage_get_loglevel(daemon, daemon_local->flags.offlineLogstorageMaxDevices, userctxt.apid, userctxt.ctid); else context->storage_log_level = DLT_LOG_DEFAULT; /* Create automatic get log info response for registered context */ if (daemon_local->flags.rflag) { /* Prepare request for get log info with one application and one context */ if (dlt_message_init(&msg, verbose) == -1) { dlt_log(LOG_WARNING, "Can't initialize message"); return -1; } msg.datasize = sizeof(DltServiceGetLogInfoRequest); if (msg.databuffer && (msg.databuffersize < msg.datasize)) { free(msg.databuffer); msg.databuffer = 0; } if (msg.databuffer == 0) { msg.databuffer = (uint8_t *)malloc(msg.datasize); msg.databuffersize = msg.datasize; } if (msg.databuffer == 0) { dlt_log(LOG_WARNING, "Can't allocate buffer for get log info message\n"); return -1; } req = (DltServiceGetLogInfoRequest *)msg.databuffer; req->service_id = DLT_SERVICE_ID_GET_LOG_INFO; req->options = daemon_local->flags.autoResponseGetLogInfoOption; dlt_set_id(req->apid, userctxt.apid); dlt_set_id(req->ctid, userctxt.ctid); dlt_set_id(req->com, "remo"); dlt_daemon_control_get_log_info(DLT_DAEMON_SEND_TO_ALL, daemon, daemon_local, &msg, verbose); dlt_message_free(&msg, verbose); } if (context->user_handle >= DLT_FD_MINIMUM) { if ((userctxt.log_level == DLT_LOG_DEFAULT) || (userctxt.trace_status == DLT_TRACE_STATUS_DEFAULT)) { /* This call also replaces the default values with the values defined for default */ if (dlt_daemon_user_send_log_level(daemon, context, verbose) == -1) { dlt_vlog(LOG_WARNING, "Can't send current log level as response to %s for (%.4s;%.4s)\n", __func__, context->apid, context->ctid); return -1; } } } return 0; } int dlt_daemon_process_user_message_unregister_application(DltDaemon *daemon, DltDaemonLocal *daemon_local, DltReceiver *rec, int verbose) { uint32_t len = sizeof(DltUserControlMsgUnregisterApplication); DltUserControlMsgUnregisterApplication userapp; DltDaemonApplication *application = NULL; DltDaemonContext *context; int i, offset_base; DltDaemonRegisteredUsers *user_list = NULL; PRINT_FUNCTION_VERBOSE(verbose); if ((daemon == NULL) || (daemon_local == NULL) || (rec == NULL)) { dlt_vlog(LOG_ERR, "Invalid function parameters used for %s\n", __func__); return -1; } if (dlt_receiver_check_and_get(rec, &userapp, len, DLT_RCV_SKIP_HEADER | DLT_RCV_REMOVE) < 0) /* Not enough bytes received */ return -1; user_list = dlt_daemon_find_users_list(daemon, daemon->ecuid, verbose); if (user_list == NULL) return -1; if (user_list->num_applications > 0) { /* Delete this application and all corresponding contexts * for this application from internal table. */ application = dlt_daemon_application_find(daemon, userapp.apid, daemon->ecuid, verbose); if (application) { /* Calculate start offset within contexts[] */ offset_base = 0; for (i = 0; i < (application - (user_list->applications)); i++) offset_base += user_list->applications[i].num_contexts; for (i = (application->num_contexts) - 1; i >= 0; i--) { context = &(user_list->contexts[offset_base + i]); if (context) { /* Delete context */ if (dlt_daemon_context_del(daemon, context, daemon->ecuid, verbose) == -1) { dlt_vlog(LOG_WARNING, "Can't delete CtID '%.4s' for ApID '%.4s' in %s\n", context->ctid, context->apid, __func__); return -1; } } } /* Delete this application entry from internal table*/ if (dlt_daemon_application_del(daemon, application, daemon->ecuid, verbose) == -1) { dlt_vlog(LOG_WARNING, "Can't delete ApID '%.4s' in %s\n", application->apid, __func__); return -1; } else { char local_str[DLT_DAEMON_TEXTBUFSIZE] = { '\0' }; snprintf(local_str, DLT_DAEMON_TEXTBUFSIZE, "Unregistered ApID '%.4s'\n", userapp.apid); dlt_daemon_log_internal(daemon, daemon_local, local_str, verbose); dlt_log(LOG_DEBUG, local_str); } } } return 0; } int dlt_daemon_process_user_message_unregister_context(DltDaemon *daemon, DltDaemonLocal *daemon_local, DltReceiver *rec, int verbose) { uint32_t len = sizeof(DltUserControlMsgUnregisterContext); DltUserControlMsgUnregisterContext userctxt; DltDaemonContext *context; PRINT_FUNCTION_VERBOSE(verbose); if ((daemon == NULL) || (daemon_local == NULL) || (rec == NULL)) { dlt_vlog(LOG_ERR, "Invalid function parameters used for %s\n", __func__); return -1; } if (dlt_receiver_check_and_get(rec, &userctxt, len, DLT_RCV_SKIP_HEADER | DLT_RCV_REMOVE) < 0) /* Not enough bytes received */ return -1; context = dlt_daemon_context_find(daemon, userctxt.apid, userctxt.ctid, daemon->ecuid, verbose); /* In case the daemon is loaded with predefined contexts and its context * unregisters, the context information will not be deleted from daemon's * table until its parent application is unregistered. */ if (context && context->predefined == false) { /* Delete this connection entry from internal table*/ if (dlt_daemon_context_del(daemon, context, daemon->ecuid, verbose) == -1) { dlt_vlog(LOG_WARNING, "Can't delete CtID '%.4s' for ApID '%.4s' in %s\n", userctxt.ctid, userctxt.apid, __func__); return -1; } else { char local_str[DLT_DAEMON_TEXTBUFSIZE] = { '\0' }; snprintf(local_str, DLT_DAEMON_TEXTBUFSIZE, "Unregistered CtID '%.4s' for ApID '%.4s'\n", userctxt.ctid, userctxt.apid); if (verbose) dlt_daemon_log_internal(daemon, daemon_local, local_str, verbose); dlt_log(LOG_DEBUG, local_str); } } /* Create automatic unregister context response for unregistered context */ if (daemon_local->flags.rflag) dlt_daemon_control_message_unregister_context(DLT_DAEMON_SEND_TO_ALL, daemon, daemon_local, userctxt.apid, userctxt.ctid, "remo", verbose); return 0; } int dlt_daemon_process_user_message_log(DltDaemon *daemon, DltDaemonLocal *daemon_local, DltReceiver *rec, int verbose) { int ret; int bytes_to_be_removed; static char text[DLT_DAEMON_TEXTSIZE]; PRINT_FUNCTION_VERBOSE(verbose); if ((daemon == NULL) || (daemon_local == NULL) || (rec == NULL)) { dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_user_message_log()\n"); return DLT_DAEMON_ERROR_UNKNOWN; } ret = dlt_message_read(&(daemon_local->msg), (unsigned char *)rec->buf + sizeof(DltUserHeader), rec->bytesRcvd - sizeof(DltUserHeader), 0, verbose); if (ret != DLT_MESSAGE_ERROR_OK) { if (ret != DLT_MESSAGE_ERROR_SIZE) /* This is a normal usecase: The daemon reads the data in 10kb chunks. * Thus the last trace in this chunk is probably not complete and will be completed * with the next chunk read. This happens always when the FIFO is filled with more than 10kb before * the daemon is able to read from the FIFO. * Thus the loglevel of this message is set to DEBUG. * A cleaner solution would be to check more in detail whether the message is not complete (normal usecase) * or the headers are corrupted (error case). */ dlt_log(LOG_DEBUG, "Can't read messages from receiver\n"); return DLT_DAEMON_ERROR_UNKNOWN; } /* set overwrite ecu id */ if ((daemon_local->flags.evalue[0]) && (strncmp(daemon_local->msg.headerextra.ecu, DLT_DAEMON_ECU_ID, 4) == 0)) { /* Set header extra parameters */ dlt_set_id(daemon_local->msg.headerextra.ecu, daemon->ecuid); /*msg.headerextra.seid = 0; */ if (dlt_message_set_extraparameters(&(daemon_local->msg), 0) == DLT_RETURN_ERROR) { dlt_log(LOG_WARNING, "Can't set message extra parameters in process user message log\n"); return DLT_DAEMON_ERROR_UNKNOWN; } /* Correct value of timestamp, this was changed by dlt_message_set_extraparameters() */ daemon_local->msg.headerextra.tmsp = DLT_BETOH_32(daemon_local->msg.headerextra.tmsp); } /* prepare storage header */ if (DLT_IS_HTYP_WEID(daemon_local->msg.standardheader->htyp)) { if (dlt_set_storageheader(daemon_local->msg.storageheader, daemon_local->msg.headerextra.ecu) == DLT_RETURN_ERROR) { dlt_log(LOG_WARNING, "Can't set storage header in process user message log\n"); return DLT_DAEMON_ERROR_UNKNOWN; } } else if (dlt_set_storageheader(daemon_local->msg.storageheader, daemon->ecuid) == DLT_RETURN_ERROR) { dlt_log(LOG_WARNING, "Can't set storage header in process user message log\n"); return DLT_DAEMON_ERROR_UNKNOWN; } { /* if no filter set or filter is matching display message */ if (daemon_local->flags.xflag) { if (dlt_message_print_hex(&(daemon_local->msg), text, DLT_DAEMON_TEXTSIZE, verbose) == DLT_RETURN_ERROR) dlt_log(LOG_WARNING, "dlt_message_print_hex() failed!\n"); } /* if */ else if (daemon_local->flags.aflag) { if (dlt_message_print_ascii(&(daemon_local->msg), text, DLT_DAEMON_TEXTSIZE, verbose) == DLT_RETURN_ERROR) dlt_log(LOG_WARNING, "dlt_message_print_ascii() failed!\n"); } /* if */ else if (daemon_local->flags.sflag) { if (dlt_message_print_header(&(daemon_local->msg), text, DLT_DAEMON_TEXTSIZE, verbose) == DLT_RETURN_ERROR) dlt_log(LOG_WARNING, "dlt_message_print_header() failed!\n"); /* print message header only */ } /* if */ /* check if overflow occurred */ if (daemon->overflow_counter) { if (dlt_daemon_send_message_overflow(daemon, daemon_local, verbose) == 0) { dlt_vlog(LOG_WARNING, "%u messages discarded!\n", daemon->overflow_counter); daemon->overflow_counter = 0; } } /* send message to client or write to log file */ if ((ret = dlt_daemon_client_send(DLT_DAEMON_SEND_TO_ALL, daemon, daemon_local, daemon_local->msg.headerbuffer, sizeof(DltStorageHeader), daemon_local->msg.headerbuffer + sizeof(DltStorageHeader), daemon_local->msg.headersize - sizeof(DltStorageHeader), daemon_local->msg.databuffer, daemon_local->msg.datasize, verbose))) if (ret == DLT_DAEMON_ERROR_BUFFER_FULL) daemon->overflow_counter++; } /* keep not read data in buffer */ bytes_to_be_removed = daemon_local->msg.headersize + daemon_local->msg.datasize - sizeof(DltStorageHeader) + sizeof(DltUserHeader); if (daemon_local->msg.found_serialheader) bytes_to_be_removed += sizeof(dltSerialHeader); if (dlt_receiver_remove(rec, bytes_to_be_removed) == -1) { dlt_log(LOG_WARNING, "Can't remove bytes from receiver\n"); return DLT_DAEMON_ERROR_UNKNOWN; } return DLT_DAEMON_ERROR_OK; } #ifdef DLT_SHM_ENABLE # define DLT_SHM_RCV_BUFFER_SIZE 10000 int dlt_daemon_process_user_message_log_shm(DltDaemon *daemon, DltDaemonLocal *daemon_local, DltReceiver *rec, int verbose) { int sent; uint8_t *rcv_buffer = NULL; int size; uint32_t len = sizeof(DltUserHeader); DltUserHeader userheader; static char text[DLT_DAEMON_TEXTSIZE]; PRINT_FUNCTION_VERBOSE(verbose); if ((daemon == NULL) || (daemon_local == NULL) || (rec == NULL)) { dlt_vlog(LOG_ERR, "Invalid function parameters used for %s\n", __func__); return -1; } rcv_buffer = calloc(1, DLT_SHM_RCV_BUFFER_SIZE); if (!rcv_buffer) { dlt_vlog(LOG_ERR, "No memory to allocate receiver buffer in %s.\n", __func__); return -1; } memset(&userheader, 0, len); if (dlt_receiver_check_and_get(rec, &userheader, len, DLT_RCV_REMOVE) < 0) /* Not enough bytes received */ return -1; /*dlt_shm_status(&(daemon_local->dlt_shm)); */ while (1) { /* log message in SHM */ size = dlt_shm_copy(&(daemon_local->dlt_shm), rcv_buffer, DLT_SHM_RCV_BUFFER_SIZE); if (size <= 0) break; if (dlt_message_read(&(daemon_local->msg), rcv_buffer, size, 0, verbose) != 0) { break; dlt_log(LOG_WARNING, "Can't read messages from shm\n"); return -1; } /* set overwrite ecu id */ if ((daemon_local->flags.evalue[0]) && (strncmp(daemon_local->msg.headerextra.ecu, DLT_DAEMON_ECU_ID, 4) == 0)) { /* Set header extra parameters */ dlt_set_id(daemon_local->msg.headerextra.ecu, daemon->ecuid); /*msg.headerextra.seid = 0; */ if (dlt_message_set_extraparameters(&(daemon_local->msg), 0) == -1) { dlt_log(LOG_WARNING, "Can't set message extra parameters in process user message log\n"); dlt_shm_remove(&(daemon_local->dlt_shm)); return -1; } /* Correct value of timestamp, this was changed by dlt_message_set_extraparameters() */ daemon_local->msg.headerextra.tmsp = DLT_BETOH_32(daemon_local->msg.headerextra.tmsp); } /* prepare storage header */ if (DLT_IS_HTYP_WEID(daemon_local->msg.standardheader->htyp)) { if (dlt_set_storageheader(daemon_local->msg.storageheader, daemon_local->msg.headerextra.ecu) == -1) { dlt_log(LOG_WARNING, "Can't set storage header in process user message log\n"); dlt_shm_remove(&(daemon_local->dlt_shm)); return -1; } } else if (dlt_set_storageheader(daemon_local->msg.storageheader, daemon->ecuid) == -1) { dlt_log(LOG_WARNING, "Can't set storage header in process user message log\n"); dlt_shm_remove(&(daemon_local->dlt_shm)); return -1; } /* display message */ if (daemon_local->flags.xflag) { if (dlt_message_print_hex(&(daemon_local->msg), text, DLT_DAEMON_TEXTSIZE, verbose) == -1) dlt_log(LOG_WARNING, "dlt_message_print_hex() failed!\n"); } /* if */ else if (daemon_local->flags.aflag) { if (dlt_message_print_ascii(&(daemon_local->msg), text, DLT_DAEMON_TEXTSIZE, verbose) == -1) dlt_log(LOG_WARNING, "dlt_message_print_ascii() failed!\n"); } /* if */ else if (daemon_local->flags.sflag) { if (dlt_message_print_header(&(daemon_local->msg), text, DLT_DAEMON_TEXTSIZE, verbose) == -1) dlt_log(LOG_WARNING, "dlt_message_print_header() failed!\n"); /* print message header only */ } /* if */ sent = 0; /* write message to offline trace */ if (daemon_local->flags.offlineTraceDirectory[0]) { dlt_offline_trace_write(&(daemon_local->offlineTrace), daemon_local->msg.headerbuffer, daemon_local->msg.headersize, daemon_local->msg.databuffer, daemon_local->msg.datasize, 0, 0); sent = 1; } sent = dlt_daemon_client_send_all(daemon, daemon_local, verbose); /* Message was not sent to client, so store it in client ringbuffer */ if (sent == 1) { if (userheader.message == DLT_USER_MESSAGE_LOG_SHM) /* dlt message was sent, remove from buffer if log message from shm */ dlt_shm_remove(&(daemon_local->dlt_shm)); } else { /* dlt message was not sent, keep in buffer */ break; } } return 0; } # undef DLT_SHM_RCV_BUFFER_SIZE #endif int dlt_daemon_process_user_message_set_app_ll_ts(DltDaemon *daemon, DltDaemonLocal *daemon_local, DltReceiver *rec, int verbose) { uint32_t len = sizeof(DltUserControlMsgAppLogLevelTraceStatus); DltUserControlMsgAppLogLevelTraceStatus userctxt; DltDaemonApplication *application; DltDaemonContext *context; int i, offset_base; int8_t old_log_level, old_trace_status; DltDaemonRegisteredUsers *user_list = NULL; PRINT_FUNCTION_VERBOSE(verbose); if ((daemon == NULL) || (daemon_local == NULL) || (rec == NULL)) { dlt_vlog(LOG_ERR, "Invalid function parameters used for %s\n", __func__); return DLT_RETURN_ERROR; } user_list = dlt_daemon_find_users_list(daemon, daemon->ecuid, verbose); if (user_list == NULL) return DLT_RETURN_ERROR; memset(&userctxt, 0, len); if (dlt_receiver_check_and_get(rec, &userctxt, len, DLT_RCV_SKIP_HEADER | DLT_RCV_REMOVE) < 0) /* Not enough bytes received */ return DLT_RETURN_ERROR; if (user_list->num_applications > 0) { /* Get all contexts with application id matching the received application id */ application = dlt_daemon_application_find(daemon, userctxt.apid, daemon->ecuid, verbose); if (application) { /* Calculate start offset within contexts[] */ offset_base = 0; for (i = 0; i < (application - (user_list->applications)); i++) offset_base += user_list->applications[i].num_contexts; for (i = 0; i < application->num_contexts; i++) { context = &(user_list->contexts[offset_base + i]); if (context) { old_log_level = context->log_level; context->log_level = userctxt.log_level; /* No endianess conversion necessary*/ old_trace_status = context->trace_status; context->trace_status = userctxt.trace_status; /* No endianess conversion necessary */ /* The following function sends also the trace status */ if ((context->user_handle >= DLT_FD_MINIMUM) && (dlt_daemon_user_send_log_level(daemon, context, verbose) != 0)) { context->log_level = old_log_level; context->trace_status = old_trace_status; } } } } } return DLT_RETURN_OK; } int dlt_daemon_process_user_message_log_mode(DltDaemon *daemon, DltDaemonLocal *daemon_local, DltReceiver *rec, int verbose) { DltUserControlMsgLogMode userctxt; uint32_t len = sizeof(DltUserControlMsgLogMode); PRINT_FUNCTION_VERBOSE(verbose); if ((daemon == 0) || (daemon_local == 0)) { dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_log_mode()\n"); return -1; } memset(&userctxt, 0, len); if (dlt_receiver_check_and_get(rec, &userctxt, len, DLT_RCV_SKIP_HEADER | DLT_RCV_REMOVE) < 0) /* Not enough bytes received */ return -1; /* set the new log mode */ daemon->mode = userctxt.log_mode; /* write configuration persistantly */ dlt_daemon_configuration_save(daemon, daemon->runtime_configuration, verbose); return 0; } int dlt_daemon_process_user_message_marker(DltDaemon *daemon, DltDaemonLocal *daemon_local, DltReceiver *rec, int verbose) { uint32_t len = sizeof(DltUserControlMsgLogMode); DltUserControlMsgLogMode userctxt; PRINT_FUNCTION_VERBOSE(verbose); if ((daemon == NULL) || (daemon_local == NULL) || (rec == NULL)) { dlt_vlog(LOG_ERR, "Invalid function parameters used for %s\n", __func__); return -1; } memset(&userctxt, 0, len); if (dlt_receiver_check_and_get(rec, &userctxt, len, DLT_RCV_SKIP_HEADER | DLT_RCV_REMOVE) < 0) /* Not enough bytes received */ return -1; /* Create automatic unregister context response for unregistered context */ dlt_daemon_control_message_marker(DLT_DAEMON_SEND_TO_ALL, daemon, daemon_local, verbose); return 0; } int dlt_daemon_send_ringbuffer_to_client(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose) { int ret; static uint8_t data[DLT_DAEMON_RCVBUFSIZE]; int length; #ifdef DLT_SYSTEMD_WATCHDOG_ENABLE uint32_t curr_time; #endif PRINT_FUNCTION_VERBOSE(verbose); if ((daemon == 0) || (daemon_local == 0)) { dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_send_ringbuffer_to_client()\n"); return DLT_DAEMON_ERROR_UNKNOWN; } if (dlt_buffer_get_message_count(&(daemon->client_ringbuffer)) <= 0) { dlt_daemon_change_state(daemon, DLT_DAEMON_STATE_SEND_DIRECT); return DLT_DAEMON_ERROR_OK; } #ifdef DLT_SYSTEMD_WATCHDOG_ENABLE if (sd_notify(0, "WATCHDOG=1") < 0) dlt_log(LOG_WARNING, "Could not reset systemd watchdog\n"); curr_time = dlt_uptime(); #endif while ((length = dlt_buffer_copy(&(daemon->client_ringbuffer), data, sizeof(data))) > 0) { #ifdef DLT_SYSTEMD_WATCHDOG_ENABLE if ((dlt_uptime() - curr_time) / 10000 >= watchdog_trigger_interval) { if (sd_notify(0, "WATCHDOG=1") < 0) dlt_log(LOG_WARNING, "Could not reset systemd watchdog\n"); curr_time = dlt_uptime(); } #endif if ((ret = dlt_daemon_client_send(DLT_DAEMON_SEND_FORCE, daemon, daemon_local, 0, 0, data, length, 0, 0, verbose))) return ret; dlt_buffer_remove(&(daemon->client_ringbuffer)); if (daemon->state != DLT_DAEMON_STATE_SEND_BUFFER) dlt_daemon_change_state(daemon, DLT_DAEMON_STATE_SEND_BUFFER); if (dlt_buffer_get_message_count(&(daemon->client_ringbuffer)) <= 0) { dlt_daemon_change_state(daemon, DLT_DAEMON_STATE_SEND_DIRECT); return DLT_DAEMON_ERROR_OK; } } return DLT_DAEMON_ERROR_OK; } static char dlt_timer_conn_types[DLT_TIMER_UNKNOWN + 1] = { [DLT_TIMER_PACKET] = DLT_CONNECTION_ONE_S_TIMER, [DLT_TIMER_ECU] = DLT_CONNECTION_SIXTY_S_TIMER, #ifdef DLT_SYSTEMD_WATCHDOG_ENABLE [DLT_TIMER_SYSTEMD] = DLT_CONNECTION_SYSTEMD_TIMER, #endif [DLT_TIMER_GATEWAY] = DLT_CONNECTION_GATEWAY_TIMER, [DLT_TIMER_UNKNOWN] = DLT_CONNECTION_TYPE_MAX }; static char dlt_timer_names[DLT_TIMER_UNKNOWN + 1][32] = { [DLT_TIMER_PACKET] = "Timing packet", [DLT_TIMER_ECU] = "ECU version", #ifdef DLT_SYSTEMD_WATCHDOG_ENABLE [DLT_TIMER_SYSTEMD] = "Systemd watchdog", #endif [DLT_TIMER_GATEWAY] = "Gateway", [DLT_TIMER_UNKNOWN] = "Unknown timer" }; int create_timer_fd(DltDaemonLocal *daemon_local, int period_sec, int starts_in, DltTimers timer_id) { int local_fd = -1; char *timer_name = NULL; if (timer_id >= DLT_TIMER_UNKNOWN) { dlt_log(DLT_LOG_ERROR, "Unknown timer."); return -1; } timer_name = dlt_timer_names[timer_id]; if (daemon_local == NULL) { dlt_log(DLT_LOG_ERROR, "Daemaon local structure is NULL"); return -1; } if ((period_sec <= 0) || (starts_in <= 0)) { /* timer not activated via the service file */ dlt_vlog(LOG_INFO, "<%s> not set: period=0\n", timer_name); local_fd = -1; } #ifdef linux else { struct itimerspec l_timer_spec; local_fd = timerfd_create(CLOCK_MONOTONIC, 0); if (local_fd < 0) { dlt_vlog(LOG_WARNING, "<%s> timerfd_create failed: %s\n", timer_name, strerror(errno)); } l_timer_spec.it_interval.tv_sec = period_sec; l_timer_spec.it_interval.tv_nsec = 0; l_timer_spec.it_value.tv_sec = starts_in; l_timer_spec.it_value.tv_nsec = 0; if (timerfd_settime(local_fd, 0, &l_timer_spec, NULL) < 0) { dlt_vlog(LOG_WARNING, "<%s> timerfd_settime failed: %s\n", timer_name, strerror(errno)); local_fd = -1; } } #endif /* If fully initialized we are done. * Event handling registration is done later on with other connections. */ if (local_fd > 0) { dlt_vlog(LOG_INFO, "<%s> initialized with %d timer\n", timer_name, period_sec); } return dlt_connection_create(daemon_local, &daemon_local->pEvent, local_fd, POLLIN, dlt_timer_conn_types[timer_id]); } /* Close connection function */ int dlt_daemon_close_socket(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose) { char local_str[DLT_DAEMON_TEXTBUFSIZE] = { '\0' }; PRINT_FUNCTION_VERBOSE(verbose); if ((daemon_local == NULL) || (daemon == NULL)) { dlt_log(LOG_ERR, "dlt_daemon_close_socket: Invalid input parmeters\n"); return -1; } /* Closure is done while unregistering has for any connection */ dlt_event_handler_unregister_connection(&daemon_local->pEvent, daemon_local, sock); if (daemon_local->client_connections == 0) { /* send new log state to all applications */ daemon->connectionState = 0; dlt_daemon_user_send_all_log_state(daemon, verbose); /* For offline tracing we still can use the same states */ /* as for socket sending. Using this trick we see the traces */ /* In the offline trace AND in the socket stream. */ if (daemon_local->flags.yvalue[0] == 0) dlt_daemon_change_state(daemon, DLT_DAEMON_STATE_BUFFER); } dlt_daemon_control_message_connection_info(DLT_DAEMON_SEND_TO_ALL, daemon, daemon_local, DLT_CONNECTION_STATUS_DISCONNECTED, "", verbose); snprintf(local_str, DLT_DAEMON_TEXTBUFSIZE, "Client connection #%d closed. Total Clients : %d\n", sock, daemon_local->client_connections); dlt_log(LOG_DEBUG, local_str); dlt_daemon_log_internal(daemon, daemon_local, local_str, daemon_local->flags.vflag); return 0; } /** \} */ dlt-daemon-2.18.4/src/daemon/dlt-daemon.h000066400000000000000000000366441353342203500200760ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2011-2015, BMW AG * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author Alexander Wenzel * * \copyright Copyright © 2011-2015 BMW AG. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file dlt-daemon.h */ /******************************************************************************* ** ** ** SRC-MODULE: dlt-daemon.h ** ** ** ** TARGET : linux ** ** ** ** PROJECT : DLT ** ** ** ** AUTHOR : Alexander Wenzel Alexander.AW.Wenzel@bmw.de ** ** Markus Klein ** ** ** ** PURPOSE : ** ** ** ** REMARKS : ** ** ** ** PLATFORM DEPENDANT [yes/no]: yes ** ** ** ** TO BE CHANGED BY USER [yes/no]: no ** ** ** *******************************************************************************/ /******************************************************************************* ** Author Identity ** ******************************************************************************** ** ** ** Initials Name Company ** ** -------- ------------------------- ---------------------------------- ** ** aw Alexander Wenzel BMW ** ** mk Markus Klein Fraunhofer ESK ** *******************************************************************************/ /******************************************************************************* ** Author Identity ** ******************************************************************************** ** ** ** Initials Name Company ** ** -------- ------------------------- ---------------------------------- ** ** aw Alexander Wenzel BMW ** ** mk Markus Klein Fraunhofer ESK ** *******************************************************************************/ #ifndef DLT_DAEMON_H #define DLT_DAEMON_H #include /* for NAME_MAX */ #include #include "dlt_daemon_common.h" #include "dlt_user_shared.h" #include "dlt_user_shared_cfg.h" #include "dlt_daemon_event_handler_types.h" #include "dlt_gateway_types.h" #include "dlt_offline_trace.h" #define DLT_DAEMON_FLAG_MAX 256 /** * The flags of a dlt daemon. */ typedef struct { int aflag; /**< (Boolean) Print DLT messages; payload as ASCII */ int sflag; /**< (Boolean) Print DLT messages; payload as hex */ int xflag; /**< (Boolean) Print DLT messages; only headers */ int vflag; /**< (Boolean) Verbose mode */ int dflag; /**< (Boolean) Daemonize */ int lflag; /**< (Boolean) Send DLT messages with serial header */ int rflag; /**< (Boolean) Send automatic get log info response during context registration */ int mflag; /**< (Boolean) Sync to serial header on serial connection */ int nflag; /**< (Boolean) Sync to serial header on all TCP connections */ char evalue[NAME_MAX + 1]; /**< (String: ECU ID) Set ECU ID (Default: ECU1) */ char bvalue[NAME_MAX + 1]; /**< (String: Baudrate) Serial device baudrate (Default: 115200) */ char yvalue[NAME_MAX + 1]; /**< (String: Devicename) Additional support for serial device */ char ivalue[NAME_MAX + 1]; /**< (String: Directory) Directory where to store the persistant configuration (Default: /tmp) */ char cvalue[NAME_MAX + 1]; /**< (String: Directory) Filename of DLT configuration file (Default: /etc/dlt.conf) */ int sharedMemorySize; /**< (int) Size of shared memory (Default: 100000) */ int sendMessageTime; /**< (Boolean) Send periodic Message Time if client is connected (Default: 0) */ char offlineTraceDirectory[DLT_DAEMON_FLAG_MAX]; /**< (String: Directory) Store DLT messages to local directory (Default: /etc/dlt.conf) */ int offlineTraceFileSize; /**< (int) Maximum size in bytes of one trace file (Default: 1000000) */ int offlineTraceMaxSize; /**< (int) Maximum size of all trace files (Default: 4000000) */ int offlineTraceFilenameTimestampBased; /**< (int) timestamp based or index based (Default: 1 Timestamp based) */ int loggingMode; /**< (int) The logging console for internal logging of dlt-daemon (Default: 0) */ int loggingLevel; /**< (int) The logging level for internal logging of dlt-daemon (Default: 6) */ char loggingFilename[DLT_DAEMON_FLAG_MAX]; /**< (String: Filename) The logging filename if internal logging mode is log to file (Default: /tmp/log) */ int sendECUSoftwareVersion; /**< (Boolean) Send ECU software version perdiodically */ char pathToECUSoftwareVersion[DLT_DAEMON_FLAG_MAX]; /**< (String: Filename) The file from which to read the ECU version from. */ int sendTimezone; /**< (Boolean) Send Timezone perdiodically */ int offlineLogstorageMaxDevices; /**< (int) Maximum devices to be used as offline logstorage devices */ char offlineLogstorageDirPath[DLT_MOUNT_PATH_MAX]; /**< (String: Directory) DIR path to store offline logs */ int offlineLogstorageTimestamp; /**< (int) Append timestamp in offline logstorage filename */ char offlineLogstorageDelimiter; /**< (char) Append delimeter character in offline logstorage filename */ unsigned int offlineLogstorageMaxCounter; /**< (int) Maximum offline logstorage file counter index until wraparound */ unsigned int offlineLogstorageMaxCounterIdx; /**< (int) String len of offlineLogstorageMaxCounter*/ unsigned int offlineLogstorageCacheSize; /**< Max cache size offline logstorage cache */ #ifdef DLT_USE_UNIX_SOCKET_IPC char appSockPath[DLT_DAEMON_FLAG_MAX]; /**< Path to User socket */ #else char userPipesDir[DLT_PATH_MAX]; /**< (String: Directory) directory where dltpipes reside (Default: /tmp/dltpipes) */ char daemonFifoName[DLT_PATH_MAX]; /**< (String: Filename) name of local fifo (Default: /tmp/dlt) */ char daemonFifoGroup[DLT_PATH_MAX]; /**< (String: Group name) Owner group of local fifo (Default: Primary Group) */ #endif #ifdef DLT_SHM_ENABLE char dltShmName[NAME_MAX + 1]; /**< Shared memory name */ #endif unsigned int port; /**< port number */ char ctrlSockPath[DLT_DAEMON_FLAG_MAX]; /**< Path to Control socket */ int gatewayMode; /**< (Boolean) Gateway Mode */ char gatewayConfigFile[DLT_DAEMON_FLAG_MAX]; /**< Gateway config file path */ int autoResponseGetLogInfoOption; /**< (int) The Option of automatic get log info response during context registration. (Default: 7)*/ int contextLogLevel; /**< (int) log level sent to context if registered with default log-level or if enforced*/ int contextTraceStatus; /**< (int) trace status sent to context if registered with default trace status or if enforced*/ int enforceContextLLAndTS; /**< (Boolean) Enforce log-level, trace-status not to exceed contextLogLevel, contextTraceStatus */ DltBindAddress_t *ipNodes; /**< (String: BindAddress) The daemon accepts connections only on this list of IP addresses */ } DltDaemonFlags; /** * The global parameters of a dlt daemon. */ typedef struct { DltDaemonFlags flags; /**< flags of the daemon */ DltFile file; /**< struct for file access */ DltEventHandler pEvent; /**< struct for message producer event handling */ DltGateway pGateway; /**< struct for passive node connection handling */ DltMessage msg; /**< one dlt message */ int client_connections; /**< counter for nr. of client connections */ size_t baudrate; /**< Baudrate of serial connection */ #ifdef DLT_SHM_ENABLE DltShm dlt_shm; /**< Shared memory handling */ #endif DltOfflineTrace offlineTrace; /**< Offline trace handling */ int timeoutOnSend; unsigned long RingbufferMinSize; unsigned long RingbufferMaxSize; unsigned long RingbufferStepSize; unsigned long daemonFifoSize; #ifdef UDP_CONNECTION_SUPPORT int UDPConnectionSetup; /* enable/disable the UDP connection */ char UDPMulticastIPAddress[MULTICASTIP_MAX_SIZE]; /* multicast ip addres */ int UDPMulticastIPPort; /* multicast port */ #endif } DltDaemonLocal; typedef struct { int timer_fd; unsigned long long wakeups_missed; } DltDaemonPeriodicData; typedef struct { DltDaemon *daemon; DltDaemonLocal *daemon_local; } DltDaemonTimingPacketThreadData; typedef DltDaemonTimingPacketThreadData DltDaemonECUVersionThreadData; #define DLT_DAEMON_ERROR_OK 0 #define DLT_DAEMON_ERROR_UNKNOWN -1 #define DLT_DAEMON_ERROR_BUFFER_FULL -2 #define DLT_DAEMON_ERROR_SEND_FAILED -3 #define DLT_DAEMON_ERROR_WRITE_FAILED -4 /* Function prototypes */ void dlt_daemon_local_cleanup(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose); int dlt_daemon_local_init_p1(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose); int dlt_daemon_local_init_p2(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose); int dlt_daemon_local_connection_init(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose); int dlt_daemon_local_ecu_version_init(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose); void dlt_daemon_daemonize(int verbose); void dlt_daemon_exit_trigger(); void dlt_daemon_signal_handler(int sig); int dlt_daemon_process_client_connect(DltDaemon *daemon, DltDaemonLocal *daemon_local, DltReceiver *recv, int verbose); int dlt_daemon_process_client_messages(DltDaemon *daemon, DltDaemonLocal *daemon_local, DltReceiver *revc, int verbose); int dlt_daemon_process_client_messages_serial(DltDaemon *daemon, DltDaemonLocal *daemon_local, DltReceiver *recv, int verbose); int dlt_daemon_process_user_messages(DltDaemon *daemon, DltDaemonLocal *daemon_local, DltReceiver *recv, int verbose); int dlt_daemon_process_one_s_timer(DltDaemon *daemon, DltDaemonLocal *daemon_local, DltReceiver *recv, int verbose); int dlt_daemon_process_sixty_s_timer(DltDaemon *daemon, DltDaemonLocal *daemon_local, DltReceiver *recv, int verbose); int dlt_daemon_process_systemd_timer(DltDaemon *daemon, DltDaemonLocal *daemon_local, DltReceiver *recv, int verbose); int dlt_daemon_process_control_connect(DltDaemon *daemon, DltDaemonLocal *daemon_local, DltReceiver *recv, int verbose); #ifdef DLT_USE_UNIX_SOCKET_IPC int dlt_daemon_process_app_connect(DltDaemon *daemon, DltDaemonLocal *daemon_local, DltReceiver *recv, int verbose); #endif int dlt_daemon_process_control_messages(DltDaemon *daemon, DltDaemonLocal *daemon_local, DltReceiver *recv, int verbose); typedef int (*dlt_daemon_process_user_message_func)(DltDaemon *daemon, DltDaemonLocal *daemon_local, DltReceiver *rec, int verbose); int dlt_daemon_process_user_message_overflow(DltDaemon *daemon, DltDaemonLocal *daemon_local, DltReceiver *rec, int verbose); int dlt_daemon_send_message_overflow(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose); int dlt_daemon_process_user_message_register_application(DltDaemon *daemon, DltDaemonLocal *daemon_local, DltReceiver *rec, int verbose); int dlt_daemon_process_user_message_unregister_application(DltDaemon *daemon, DltDaemonLocal *daemon_local, DltReceiver *rec, int verbose); int dlt_daemon_process_user_message_register_context(DltDaemon *daemon, DltDaemonLocal *daemon_local, DltReceiver *rec, int verbose); int dlt_daemon_process_user_message_unregister_context(DltDaemon *daemon, DltDaemonLocal *daemon_local, DltReceiver *rec, int verbose); int dlt_daemon_process_user_message_log(DltDaemon *daemon, DltDaemonLocal *daemon_local, DltReceiver *rec, int verbose); #ifdef DLT_SHM_ENABLE int dlt_daemon_process_user_message_log_shm(DltDaemon *daemon, DltDaemonLocal *daemon_local, DltReceiver *rec, int verbose); #endif int dlt_daemon_process_user_message_set_app_ll_ts(DltDaemon *daemon, DltDaemonLocal *daemon_local, DltReceiver *rec, int verbose); int dlt_daemon_process_user_message_marker(DltDaemon *daemon, DltDaemonLocal *daemon_local, DltReceiver *rec, int verbose); int dlt_daemon_send_ringbuffer_to_client(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose); void dlt_daemon_timingpacket_thread(void *ptr); void dlt_daemon_ecu_version_thread(void *ptr); #if defined(DLT_SYSTEMD_WATCHDOG_ENABLE) void dlt_daemon_systemd_watchdog_thread(void *ptr); #endif int create_timer_fd(DltDaemonLocal *daemon_local, int period_sec, int starts_in, DltTimers timer); int dlt_daemon_close_socket(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose); #endif /* DLT_DAEMON_H */ dlt-daemon-2.18.4/src/daemon/dlt-daemon_cfg.h000066400000000000000000000116201353342203500207000ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2011-2015, BMW AG * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author Alexander Wenzel * * \copyright Copyright © 2011-2015 BMW AG. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file dlt-daemon_cfg.h */ /******************************************************************************* ** ** ** SRC-MODULE: dlt-daemon-cfg.h ** ** ** ** TARGET : linux ** ** ** ** PROJECT : DLT ** ** ** ** AUTHOR : Alexander Wenzel Alexander.AW.Wenzel@bmw.de ** ** Markus Klein ** ** ** ** PURPOSE : ** ** ** ** REMARKS : ** ** ** ** PLATFORM DEPENDANT [yes/no]: yes ** ** ** ** TO BE CHANGED BY USER [yes/no]: no ** ** ** *******************************************************************************/ /******************************************************************************* ** Author Identity ** ******************************************************************************** ** ** ** Initials Name Company ** ** -------- ------------------------- ---------------------------------- ** ** aw Alexander Wenzel BMW ** ** mk Markus Klein Fraunhofer ESK ** *******************************************************************************/ /******************************************************************************* ** Author Identity ** ******************************************************************************** ** ** ** Initials Name Company ** ** -------- ------------------------- ---------------------------------- ** ** aw Alexander Wenzel BMW ** ** mk Markus Klein Fraunhofer ESK ** *******************************************************************************/ #ifndef DLT_DAEMON_CFG_H #define DLT_DAEMON_CFG_H /*************/ /* Changable */ /*************/ /* Stack size of timing packet thread */ #define DLT_DAEMON_TIMINGPACKET_THREAD_STACKSIZE 100000 /* Stack size of ecu version thread */ #define DLT_DAEMON_ECU_VERSION_THREAD_STACKSIZE 100000 /* Size of receive buffer for fifo connection (from user application) */ #define DLT_DAEMON_RCVBUFSIZE 10024 /* Size of receive buffer for socket connection (from dlt client) */ #define DLT_DAEMON_RCVBUFSIZESOCK 10024 /* Size of receive buffer for serial connection (from dlt client) */ #define DLT_DAEMON_RCVBUFSIZESERIAL 10024 /* Size of buffer for text output */ #define DLT_DAEMON_TEXTSIZE 10024 /* Size of buffer */ #define DLT_DAEMON_TEXTBUFSIZE 512 /* Maximum length of a description */ #define DLT_DAEMON_DESCSIZE 256 /* Umask of daemon, creates files with permission 750 */ #define DLT_DAEMON_UMASK 027 /* Default ECU ID, used in storage header and transmitted to client*/ #define DLT_DAEMON_ECU_ID "ECU1" /* Default baudrate for serial interface */ #define DLT_DAEMON_SERIAL_DEFAULT_BAUDRATE 115200 /************************/ /* Don't change please! */ /************************/ #endif /* DLT_DAEMON_CFG_H */ dlt-daemon-2.18.4/src/daemon/dlt.conf000066400000000000000000000206771353342203500173320ustar00rootroot00000000000000# Configuration file of DLT daemon # # Configurations made here will overwrite settings by command line ######################################################################## # General configuration # ######################################################################## # Start daemon in debug mode, so that all internal debug information is printed out on the console # Verbose = 1 # Daemonize DLT daemon, if it is started as daemon # Daemonize = 1 # Send DLT messages with serial header # SendSerialHeader = 1 # Send automatic get log info response during context registration SendContextRegistration = 1 # Option of get log info response during context registration (Default: 7) # Apid and Ctid Only = 3, with LogLevel = 4, with TraceStatus = 5, with LL and TS = 6, with LL, TS, and Description = 7 # SendContextRegistrationOption = 7 # Send automatic time packets every second if client is connected (Default: 0) # SendMessageTime = 0 # Set ECU ID (Default: ECU1) ECUId = ECU1 # Size of shared memory (Default: 100000) SharedMemorySize = 100000 # Directory where to store the persistant configuration (Default: /tmp) # PersistanceStoragePath = /tmp # The logging console for internal logging of dlt-daemon (Default: 0) # 0 = log to stdout, 1 = log to syslog, 2 = log to file (see LoggingFilename) LoggingMode = 0 # The internal log level, up to which logs are written (Default: 6) # LOG_EMERG = 0, LOG_ALERT = 1, LOG_CRIT = 2, LOG_ERR = 3, LOG_WARNING = 4, LOG_NOTICE = 5, LOG_INFO = 6, LOG_DEBUG = 7 LoggingLevel = 6 # The logging filename if internal logging mode is log to file (Default: /tmp/dlt.log) LoggingFilename = /tmp/dlt.log # Timeout on send to client (sec) TimeOutOnSend = 4 # The minimum size of the Ringbuffer, used for storing temporary DLT messages, until client is connected (Default: 500000) RingbufferMinSize = 500000 # The max size of the Ringbuffer, used for storing temporary DLT messages, until client is connected (Default: 10000000) RingbufferMaxSize = 10000000 # The step size the Ringbuffer is increased, used for storing temporary DLT messages, until client is connected (Default: 500000) RingbufferStepSize = 500000 # The size of Daemon FIFO (/tmp/dlt) (Default: 65536, MinSize: depend on pagesize of system, MaxSize: please check /proc/sys/fs/pipe-max-size) # DaemonFIFOSize = 65536 # Initial log-level that is sent when an application registers (Default: 4) # DLT_LOG_OFF = 0, DLT_LOG_FATAL = 1, DLT_LOG_ERROR = 2, DLT_LOG_WARN = 3, DLT_LOG_INFO = 4, DLT_LOG_DEBUG = 5, DLT_LOG_VERBOSE = 6 # ContextLogLevel = 4 # Initial trace-status that is sent when an application registers (Default: 0) # DLT_TRACE_STATUS_OFF = 0, DLT_TRACE_STATUS_ON = 1 # ContextTraceStatus = 0 # Force log level and trace status of context to not exceed "ContextLogLevel" and "ContextTraceStatus" (Default: 0 = OFF) # If set to 1 (ON) whenever a context registers or changes the log-level it has to be lower or equal to ContextLogLevel # ForceContextLogLevelAndTraceStatus = 1 ######################################################################## # Gateway Configuration # ######################################################################## # Enable Gateway mode (Default: 0) # GatewayMode = 1 # Read gateway configuration from another location # GatewayConfigFile = /etc/dlt_gateway.conf ######################################################################## # Permission configuration # # ==================================================================== # # Owner group of daemon FIFO directory(Default: /tmp/dlt) # (If not set, primary group of dlt-daemon process is used) # DaemonFifoGroup = dlt_user_apps_group ######################################################################## # Control Application # ######################################################################## ControlSocketPath = /tmp/dlt-ctrl.sock ######################################################################## # Offline Trace memory # ######################################################################## # Store DLT messages to local directory, if not set offline Trace is off (Default: off) # OfflineTraceDirectory = /tmp # Maximum size in bytes of one trace file (Default: 1000000) # OfflineTraceFileSize = 1000000 # Maximum size of all trace files (Default: 4000000) # OfflineTraceMaxSize = 4000000 # Filename timestamp based or index based (Default:1) (timestamp based=1, index based =0) # OfflineTraceFileNameTimestampBased = 1 ######################################################################## # Local console output configuration # ######################################################################## # Print DLT messages; payload as ASCII # PrintASCII = 1 # Print DLT messages; payload as hex # PrintHex = 1 # Print DLT messages; only headers # PrintHeadersOnly = 1 ######################################################################## # Client Serial port configuration # ######################################################################## # Additional support for serial device # If a device name is set serial port is enabled. # RS232DeviceName = /dev/ttyS0 # Serial device baudrate (Default: 115200) # RS232Baudrate = 115200 # Sync to serial header on serial connection # RS232SyncSerialHeader = 1 ######################################################################## # TCP Serial port configuration # ######################################################################## # Sync to serial header on all TCP connections # TCPSyncSerialHeader = 1 ######################################################################## # ECU Software version info # ######################################################################## # Send periodic get ecu version info (Default: 0) # SendECUSoftwareVersion = 0 # Absolute path to file storing version info - otherwise DLT version is used # PathToECUSoftwareVersion = ######################################################################## # Timezone info # ######################################################################## # Send periodic timezone info (Default: 0) # SendTimezone = 0 ############################################################################## # Offline logstorage # ############################################################################## # Store DLT log messages, if not set offline logstorage is off (Default: off) # Maximum devices to be used as offline logstorage devices # OfflineLogstorageMaxDevices = 1 # Path to store DLT offline log storage messages (Default: off) # OfflineLogstorageDirPath = /opt # File options # Appends timestamp in log file name, Disable by setting to 0 (Default: 1) # OfflineLogstorageTimestamp = 0 # Appends delimiter in log file name, allowed punctutations only (Default: _) # OfflineLogstorageDelimiter = _ # Wrap around value for log file count in file name (Default: UINT_MAX) # OfflineLogstorageMaxCounter = 999 # Maximal used memory for Logstorage Cache in KB (Default: 30000 KB) # OfflineLogstorageCacheSize = 30000 ############################################################################## # UDP Multicast Configuration # ############################################################################## # Enable UDP connection support for daemon(Control Message/Multicast is enabled) UDPConnectionSetup = 1 # UDP multicast address(default:225.0.0.37) UDPMulticastIPAddress = 225.0.0.37 # UDP multicast port(default:3491) UDPMulticastIPPort = 3491 ############################################################################## # BindAddress Limitation # ############################################################################## # Accept connections only on this list of IP addresses (Default: "0.0.0.0" INADDR_ANY) # The IP addresses must be separated with ',' or ';' but not with space character ' ' # If DLT_USE_IPv6 flag is ON, then only IPv6 addresses are accepted # If DLT_USE_IPv6 flag is OFF, then only IPv4 addresses are accepted # BindAddress = 160.48.199.97;160.48.199.98 dlt-daemon-2.18.4/src/daemon/dlt_daemon_client.c000066400000000000000000003065341353342203500215070ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2011-2015, BMW AG * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author * Alexander Wenzel * Markus Klein * Mikko Rapeli * * \copyright Copyright © 2011-2015 BMW AG. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file dlt_daemon_client.c */ #include #include #include /* for printf() and fprintf() */ #include /* for socket(), connect(), (), and recv() */ #include /* for sockaddr_in and inet_addr() */ #include /* for atoi() and exit() */ #include /* for memset() */ #include /* for close() */ #include #include #include #include #include #ifdef linux # include #endif #include #include #if defined(linux) && defined(__NR_statx) # include #endif #ifdef DLT_SYSTEMD_WATCHDOG_ENABLE # include #endif #include "dlt_types.h" #include "dlt-daemon.h" #include "dlt-daemon_cfg.h" #include "dlt_daemon_common_cfg.h" #include "dlt_daemon_socket.h" #include "dlt_daemon_serial.h" #include "dlt_daemon_client.h" #include "dlt_daemon_connection.h" #include "dlt_daemon_event_handler.h" #include "dlt_daemon_offline_logstorage.h" #include "dlt_gateway.h" /** Inline function to calculate/set the requested log level or traces status * with default log level or trace status when "ForceContextLogLevelAndTraceStatus" * is enabled and set to 1 in dlt.conf file. * * @param request_log The requested log level (or) trace status * @param context_log The default log level (or) trace status * * @return The log level if requested log level is lower or equal to ContextLogLevel */ static inline int8_t getStatus(uint8_t request_log, int context_log) { return (request_log <= context_log) ? request_log : context_log; } #ifdef UDP_CONNECTION_SUPPORT # include "dlt_daemon_udp_socket.h" #endif /** @brief Sends up to 2 messages to all the clients. * * Runs through the client list and sends the messages to them. If the message * transfer fails and the connection is a socket connection, the socket is closed. * Takes and release dlt_daemon_mutex. * * @param daemon Daemon structure needed for socket closure. * @param daemon_local Daemon local structure * @param data1 The first message to be sent. * @param size1 The size of the first message. * @param data2 The second message to be send. * @param size2 The second message size. * @param verbose Needed for socket closure. * * @return The amount of data transfered. */ static int dlt_daemon_client_send_all_multiple(DltDaemon *daemon, DltDaemonLocal *daemon_local, void *data1, int size1, void *data2, int size2, int verbose) { int sent = 0; unsigned int i = 0; int ret = 0; DltConnection *temp = NULL; int type_mask = (DLT_CON_MASK_CLIENT_MSG_TCP | DLT_CON_MASK_CLIENT_MSG_SERIAL); PRINT_FUNCTION_VERBOSE(verbose); if ((daemon == NULL) || (daemon_local == NULL)) { dlt_vlog(LOG_ERR, "%s: Invalid parameters\n", __func__); return 0; } for (i = 0; i < daemon_local->pEvent.nfds; i++) { temp = dlt_event_handler_find_connection(&(daemon_local->pEvent), daemon_local->pEvent.pfd[i].fd); if ((temp == NULL) || (temp->receiver == NULL) || !((1 << temp->type) & type_mask)) { dlt_vlog(LOG_DEBUG, "The connection not found or the connection type not TCP/Serial.\n"); continue; } DLT_DAEMON_SEM_LOCK(); ret = dlt_connection_send_multiple(temp, data1, size1, data2, size2, daemon->sendserialheader); DLT_DAEMON_SEM_FREE(); if ((ret != DLT_DAEMON_ERROR_OK) && (DLT_CONNECTION_CLIENT_MSG_TCP == temp->type)) { dlt_daemon_close_socket(temp->receiver->fd, daemon, daemon_local, verbose); } if (ret != DLT_DAEMON_ERROR_OK) dlt_vlog(LOG_WARNING, "%s: send dlt message failed\n", __func__); else /* If sent to at least one client, * then do not store in ring buffer */ sent = 1; } /* for */ return sent; } /** @brief Send out message to all the clients. * * @param daemon pointer to dlt daemon structure * @param daemon_local pointer to dlt daemon local structure * @param verbose if set to true verbose information is printed out. * * @return 1 if transfer succeed, 0 otherwise. */ int dlt_daemon_client_send_all(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose) { void *msg1, *msg2; int msg1_sz, msg2_sz; int ret = 0; if ((daemon == NULL) || (daemon_local == NULL)) { dlt_vlog(LOG_ERR, "%s: Invalid parameters\n", __func__); return 0; } /* FIXME: the lock shall include the for loop but * dlt_daemon_close_socket may call us too ... */ DLT_DAEMON_SEM_LOCK(); msg1 = daemon_local->msg.headerbuffer + sizeof(DltStorageHeader); msg1_sz = daemon_local->msg.headersize - sizeof(DltStorageHeader); msg2 = daemon_local->msg.databuffer; msg2_sz = daemon_local->msg.datasize; DLT_DAEMON_SEM_FREE(); ret = dlt_daemon_client_send_all_multiple(daemon, daemon_local, msg1, msg1_sz, msg2, msg2_sz, verbose); return ret; } int dlt_daemon_client_send(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, void *storage_header, int storage_header_size, void *data1, int size1, void *data2, int size2, int verbose) { int sent, ret; if ((daemon == NULL) || (daemon_local == NULL)) { dlt_vlog(LOG_ERR, "%s: Invalid arguments\n", __func__); return DLT_DAEMON_ERROR_UNKNOWN; } if ((sock != DLT_DAEMON_SEND_TO_ALL) && (sock != DLT_DAEMON_SEND_FORCE)) { /* Send message to specific socket */ if (isatty(sock)) { DLT_DAEMON_SEM_LOCK(); if ((ret = dlt_daemon_serial_send(sock, data1, size1, data2, size2, daemon->sendserialheader))) { DLT_DAEMON_SEM_FREE(); dlt_log(LOG_WARNING, "dlt_daemon_client_send: serial send dlt message failed\n"); return ret; } DLT_DAEMON_SEM_FREE(); } else { DLT_DAEMON_SEM_LOCK(); if ((ret = dlt_daemon_socket_send(sock, data1, size1, data2, size2, daemon->sendserialheader))) { DLT_DAEMON_SEM_FREE(); dlt_log(LOG_WARNING, "dlt_daemon_client_send: socket send dlt message failed\n"); return ret; } DLT_DAEMON_SEM_FREE(); } return DLT_DAEMON_ERROR_OK; } /* write message to offline trace */ /* In the SEND_BUFFER state we must skip offline tracing because the offline traces */ /* are going without buffering directly to the offline trace. Thus we have to filter out */ /* the traces that are coming from the buffer. */ if ((sock != DLT_DAEMON_SEND_FORCE) && (daemon->state != DLT_DAEMON_STATE_SEND_BUFFER)) { if (((daemon->mode == DLT_USER_MODE_INTERNAL) || (daemon->mode == DLT_USER_MODE_BOTH)) && daemon_local->flags.offlineTraceDirectory[0]) { if (dlt_offline_trace_write(&(daemon_local->offlineTrace), storage_header, storage_header_size, data1, size1, data2, size2)) { static int error_dlt_offline_trace_write_failed = 0; if (!error_dlt_offline_trace_write_failed) { dlt_log(LOG_ERR, "dlt_daemon_client_send: dlt_offline_trace_write failed!\n"); error_dlt_offline_trace_write_failed = 1; } /*return DLT_DAEMON_ERROR_WRITE_FAILED; */ } } /* write messages to offline logstorage only if there is an extended header set * this need to be checked because the function is dlt_daemon_client_send is called by * newly introduced dlt_daemon_log_internal */ if (daemon_local->flags.offlineLogstorageMaxDevices > 0) dlt_daemon_logstorage_write(daemon, &daemon_local->flags, storage_header, storage_header_size, data1, size1, data2, size2); } /* send messages to daemon socket */ if ((daemon->mode == DLT_USER_MODE_EXTERNAL) || (daemon->mode == DLT_USER_MODE_BOTH)) { #ifdef UDP_CONNECTION_SUPPORT if (daemon_local->UDPConnectionSetup == MULTICAST_CONNECTION_ENABLED) dlt_daemon_udp_dltmsg_multicast(data1, size1, data2, size2, verbose); #endif if ((sock == DLT_DAEMON_SEND_FORCE) || (daemon->state == DLT_DAEMON_STATE_SEND_DIRECT)) { sent = dlt_daemon_client_send_all_multiple(daemon, daemon_local, data1, size1, data2, size2, verbose); if ((sock == DLT_DAEMON_SEND_FORCE) && !sent) return DLT_DAEMON_ERROR_SEND_FAILED; } } /* Message was not sent to client, so store it in client ringbuffer */ if ((sock != DLT_DAEMON_SEND_FORCE) && ((daemon->state == DLT_DAEMON_STATE_BUFFER) || (daemon->state == DLT_DAEMON_STATE_SEND_BUFFER) || (daemon->state == DLT_DAEMON_STATE_BUFFER_FULL))) { if (daemon->state == DLT_DAEMON_STATE_BUFFER_FULL) return DLT_DAEMON_ERROR_BUFFER_FULL; DLT_DAEMON_SEM_LOCK(); /* Store message in history buffer */ if (dlt_buffer_push3(&(daemon->client_ringbuffer), data1, size1, data2, size2, 0, 0) < DLT_RETURN_OK) { DLT_DAEMON_SEM_FREE(); dlt_log(LOG_DEBUG, "dlt_daemon_client_send: Buffer is full! Message discarded.\n"); dlt_daemon_change_state(daemon, DLT_DAEMON_STATE_BUFFER_FULL); return DLT_DAEMON_ERROR_BUFFER_FULL; } DLT_DAEMON_SEM_FREE(); } return DLT_DAEMON_ERROR_OK; } int dlt_daemon_client_send_control_message(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, DltMessage *msg, char *apid, char *ctid, int verbose) { int ret; int32_t len; PRINT_FUNCTION_VERBOSE(verbose); if ((daemon == 0) || (msg == 0) || (apid == 0) || (ctid == 0)) return DLT_DAEMON_ERROR_UNKNOWN; /* prepare storage header */ msg->storageheader = (DltStorageHeader *)msg->headerbuffer; if (dlt_set_storageheader(msg->storageheader, daemon->ecuid) == DLT_RETURN_ERROR) return DLT_DAEMON_ERROR_UNKNOWN; /* prepare standard header */ msg->standardheader = (DltStandardHeader *)(msg->headerbuffer + sizeof(DltStorageHeader)); msg->standardheader->htyp = DLT_HTYP_WEID | DLT_HTYP_WTMS | DLT_HTYP_UEH | DLT_HTYP_PROTOCOL_VERSION1; #if (BYTE_ORDER == BIG_ENDIAN) msg->standardheader->htyp = (msg->standardheader->htyp | DLT_HTYP_MSBF); #endif msg->standardheader->mcnt = 0; /* Set header extra parameters */ dlt_set_id(msg->headerextra.ecu, daemon->ecuid); /*msg->headerextra.seid = 0; */ msg->headerextra.tmsp = dlt_uptime(); dlt_message_set_extraparameters(msg, verbose); /* prepare extended header */ msg->extendedheader = (DltExtendedHeader *)(msg->headerbuffer + sizeof(DltStorageHeader) + sizeof(DltStandardHeader) + DLT_STANDARD_HEADER_EXTRA_SIZE(msg->standardheader->htyp)); msg->extendedheader->msin = DLT_MSIN_CONTROL_RESPONSE; msg->extendedheader->noar = 1; /* number of arguments */ if (strcmp(apid, "") == 0) dlt_set_id(msg->extendedheader->apid, DLT_DAEMON_CTRL_APID); /* application id */ else dlt_set_id(msg->extendedheader->apid, apid); if (strcmp(ctid, "") == 0) dlt_set_id(msg->extendedheader->ctid, DLT_DAEMON_CTRL_CTID); /* context id */ else dlt_set_id(msg->extendedheader->ctid, ctid); /* prepare length information */ msg->headersize = sizeof(DltStorageHeader) + sizeof(DltStandardHeader) + sizeof(DltExtendedHeader) + DLT_STANDARD_HEADER_EXTRA_SIZE(msg->standardheader->htyp); len = msg->headersize - sizeof(DltStorageHeader) + msg->datasize; if (len > UINT16_MAX) { dlt_log(LOG_WARNING, "Huge control message discarded!\n"); return DLT_DAEMON_ERROR_UNKNOWN; } msg->standardheader->len = DLT_HTOBE_16(((uint16_t)len)); if ((ret = dlt_daemon_client_send(sock, daemon, daemon_local, msg->headerbuffer, sizeof(DltStorageHeader), msg->headerbuffer + sizeof(DltStorageHeader), msg->headersize - sizeof(DltStorageHeader), msg->databuffer, msg->datasize, verbose))) { dlt_log(LOG_DEBUG, "dlt_daemon_control_send_control_message: DLT message send to all failed!.\n"); return ret; } return DLT_DAEMON_ERROR_OK; } int dlt_daemon_client_process_control(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, DltMessage *msg, int verbose) { uint32_t id, id_tmp = 0; DltStandardHeaderExtra extra; PRINT_FUNCTION_VERBOSE(verbose); if ((daemon == NULL) || (daemon_local == NULL) || (msg == NULL)) return -1; if (msg->datasize < (int32_t)sizeof(uint32_t)) return -1; extra = msg->headerextra; /* check if the message needs to be forwarded */ if (daemon_local->flags.gatewayMode == 1) { if (strcmp(daemon_local->flags.evalue, extra.ecu) != 0) return dlt_gateway_forward_control_message(&daemon_local->pGateway, daemon_local, msg, extra.ecu, verbose); } id_tmp = *((uint32_t *)(msg->databuffer)); id = DLT_ENDIAN_GET_32(msg->standardheader->htyp, id_tmp); if ((id > DLT_SERVICE_ID) && (id < DLT_SERVICE_ID_CALLSW_CINJECTION)) { /* Control message handling */ switch (id) { case DLT_SERVICE_ID_SET_LOG_LEVEL: { dlt_daemon_control_set_log_level(sock, daemon, daemon_local, msg, verbose); break; } case DLT_SERVICE_ID_SET_TRACE_STATUS: { dlt_daemon_control_set_trace_status(sock, daemon, daemon_local, msg, verbose); break; } case DLT_SERVICE_ID_GET_LOG_INFO: { dlt_daemon_control_get_log_info(sock, daemon, daemon_local, msg, verbose); break; } case DLT_SERVICE_ID_GET_DEFAULT_LOG_LEVEL: { dlt_daemon_control_get_default_log_level(sock, daemon, daemon_local, verbose); break; } case DLT_SERVICE_ID_STORE_CONFIG: { if (dlt_daemon_applications_save(daemon, daemon->runtime_application_cfg, verbose) == 0) { if (dlt_daemon_contexts_save(daemon, daemon->runtime_context_cfg, verbose) == 0) { dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_OK, verbose); } else { /* Delete saved files */ dlt_daemon_control_reset_to_factory_default(daemon, daemon->runtime_application_cfg, daemon->runtime_context_cfg, daemon_local->flags.contextLogLevel, daemon_local->flags.contextTraceStatus, daemon_local->flags.enforceContextLLAndTS, verbose); dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_ERROR, verbose); } } else { dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_ERROR, verbose); } break; } case DLT_SERVICE_ID_RESET_TO_FACTORY_DEFAULT: { dlt_daemon_control_reset_to_factory_default(daemon, daemon->runtime_application_cfg, daemon->runtime_context_cfg, daemon_local->flags.contextLogLevel, daemon_local->flags.contextTraceStatus, daemon_local->flags.enforceContextLLAndTS, verbose); dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_OK, verbose); break; } case DLT_SERVICE_ID_SET_COM_INTERFACE_STATUS: { dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_NOT_SUPPORTED, verbose); break; } case DLT_SERVICE_ID_SET_COM_INTERFACE_MAX_BANDWIDTH: { dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_NOT_SUPPORTED, verbose); break; } case DLT_SERVICE_ID_SET_VERBOSE_MODE: { dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_NOT_SUPPORTED, verbose); break; } case DLT_SERVICE_ID_SET_MESSAGE_FILTERING: { dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_NOT_SUPPORTED, verbose); break; } case DLT_SERVICE_ID_SET_TIMING_PACKETS: { dlt_daemon_control_set_timing_packets(sock, daemon, daemon_local, msg, verbose); break; } case DLT_SERVICE_ID_GET_LOCAL_TIME: { /* Send response with valid timestamp (TMSP) field */ dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_OK, verbose); break; } case DLT_SERVICE_ID_USE_ECU_ID: { dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_NOT_SUPPORTED, verbose); break; } case DLT_SERVICE_ID_USE_SESSION_ID: { dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_NOT_SUPPORTED, verbose); break; } case DLT_SERVICE_ID_USE_TIMESTAMP: { dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_NOT_SUPPORTED, verbose); break; } case DLT_SERVICE_ID_USE_EXTENDED_HEADER: { dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_NOT_SUPPORTED, verbose); break; } case DLT_SERVICE_ID_SET_DEFAULT_LOG_LEVEL: { dlt_daemon_control_set_default_log_level(sock, daemon, daemon_local, msg, verbose); break; } case DLT_SERVICE_ID_SET_DEFAULT_TRACE_STATUS: { dlt_daemon_control_set_default_trace_status(sock, daemon, daemon_local, msg, verbose); break; } case DLT_SERVICE_ID_GET_SOFTWARE_VERSION: { dlt_daemon_control_get_software_version(sock, daemon, daemon_local, verbose); break; } case DLT_SERVICE_ID_MESSAGE_BUFFER_OVERFLOW: { dlt_daemon_control_message_buffer_overflow(sock, daemon, daemon_local, daemon->overflow_counter, "", verbose); break; } case DLT_SERVICE_ID_OFFLINE_LOGSTORAGE: { dlt_daemon_control_service_logstorage(sock, daemon, daemon_local, msg, verbose); break; } case DLT_SERVICE_ID_PASSIVE_NODE_CONNECT: { dlt_daemon_control_passive_node_connect(sock, daemon, daemon_local, msg, verbose); break; } case DLT_SERVICE_ID_PASSIVE_NODE_CONNECTION_STATUS: { dlt_daemon_control_passive_node_connect_status(sock, daemon, daemon_local, verbose); break; } case DLT_SERVICE_ID_SET_ALL_LOG_LEVEL: { dlt_daemon_control_set_all_log_level(sock, daemon, daemon_local, msg, verbose); break; } case DLT_SERVICE_ID_SET_ALL_TRACE_STATUS: { dlt_daemon_control_set_all_trace_status(sock, daemon, daemon_local, msg, verbose); break; } default: { dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_NOT_SUPPORTED, verbose); break; } } } else { /* Injection handling */ dlt_daemon_control_callsw_cinjection(sock, daemon, daemon_local, msg, verbose); } return 0; } void dlt_daemon_control_get_software_version(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose) { DltMessage msg; uint32_t len; DltServiceGetSoftwareVersionResponse *resp; PRINT_FUNCTION_VERBOSE(verbose); if (daemon == 0) return; /* initialise new message */ if (dlt_message_init(&msg, 0) == DLT_RETURN_ERROR) { dlt_daemon_control_service_response(sock, daemon, daemon_local, DLT_SERVICE_ID_GET_SOFTWARE_VERSION, DLT_SERVICE_RESPONSE_ERROR, verbose); return; } /* prepare payload of data */ len = strlen(daemon->ECUVersionString); msg.datasize = sizeof(DltServiceGetSoftwareVersionResponse) + len; if (msg.databuffer && (msg.databuffersize < msg.datasize)) { free(msg.databuffer); msg.databuffer = 0; } if (msg.databuffer == 0) { msg.databuffer = (uint8_t *)malloc(msg.datasize); msg.databuffersize = msg.datasize; } if (msg.databuffer == 0) { dlt_daemon_control_service_response(sock, daemon, daemon_local, DLT_SERVICE_ID_GET_SOFTWARE_VERSION, DLT_SERVICE_RESPONSE_ERROR, verbose); return; } resp = (DltServiceGetSoftwareVersionResponse *)msg.databuffer; resp->service_id = DLT_SERVICE_ID_GET_SOFTWARE_VERSION; resp->status = DLT_SERVICE_RESPONSE_OK; resp->length = len; memcpy(msg.databuffer + sizeof(DltServiceGetSoftwareVersionResponse), daemon->ECUVersionString, len); /* send message */ dlt_daemon_client_send_control_message(sock, daemon, daemon_local, &msg, "", "", verbose); /* free message */ dlt_message_free(&msg, 0); } void dlt_daemon_control_get_default_log_level(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose) { DltMessage msg; DltServiceGetDefaultLogLevelResponse *resp; PRINT_FUNCTION_VERBOSE(verbose); if (daemon == 0) return; /* initialise new message */ if (dlt_message_init(&msg, 0) == DLT_RETURN_ERROR) { dlt_daemon_control_service_response(sock, daemon, daemon_local, DLT_SERVICE_ID_GET_DEFAULT_LOG_LEVEL, DLT_SERVICE_RESPONSE_ERROR, verbose); return; } msg.datasize = sizeof(DltServiceGetDefaultLogLevelResponse); if (msg.databuffer && (msg.databuffersize < msg.datasize)) { free(msg.databuffer); msg.databuffer = 0; } if (msg.databuffer == 0) { msg.databuffer = (uint8_t *)malloc(msg.datasize); msg.databuffersize = msg.datasize; } if (msg.databuffer == 0) { dlt_daemon_control_service_response(sock, daemon, daemon_local, DLT_SERVICE_ID_GET_DEFAULT_LOG_LEVEL, DLT_SERVICE_RESPONSE_ERROR, verbose); return; } resp = (DltServiceGetDefaultLogLevelResponse *)msg.databuffer; resp->service_id = DLT_SERVICE_ID_GET_DEFAULT_LOG_LEVEL; resp->status = DLT_SERVICE_RESPONSE_OK; resp->log_level = daemon->default_log_level; /* send message */ dlt_daemon_client_send_control_message(sock, daemon, daemon_local, &msg, "", "", verbose); /* free message */ dlt_message_free(&msg, 0); } void dlt_daemon_control_get_log_info(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, DltMessage *msg, int verbose) { DltServiceGetLogInfoRequest *req; DltMessage resp; DltDaemonContext *context = 0; DltDaemonApplication *application = 0; int num_applications = 0, num_contexts = 0; uint16_t count_app_ids = 0, count_con_ids = 0; #if (DLT_DEBUG_GETLOGINFO == 1) char buf[255]; #endif int32_t i, j, offset = 0; char *apid = 0; int8_t ll, ts; uint16_t len; int8_t value; int32_t sizecont = 0; int offset_base; uint32_t sid; DltDaemonRegisteredUsers *user_list = NULL; PRINT_FUNCTION_VERBOSE(verbose); if ((daemon == NULL) || (msg == NULL) || (msg->databuffer == NULL)) return; if (DLT_CHECK_RCV_DATA_SIZE(msg->datasize, sizeof(DltServiceGetLogInfoRequest)) < 0) return; user_list = dlt_daemon_find_users_list(daemon, daemon->ecuid, verbose); if (user_list == NULL) return; /* prepare pointer to message request */ req = (DltServiceGetLogInfoRequest *)(msg->databuffer); /* initialise new message */ if (dlt_message_init(&resp, 0) == DLT_RETURN_ERROR) { dlt_daemon_control_service_response(sock, daemon, daemon_local, DLT_SERVICE_ID_GET_LOG_INFO, DLT_SERVICE_RESPONSE_ERROR, verbose); return; } /* check request */ if ((req->options < 3) || (req->options > 7)) { dlt_daemon_control_service_response(sock, daemon, daemon_local, DLT_SERVICE_ID_GET_LOG_INFO, DLT_SERVICE_RESPONSE_ERROR, verbose); return; } if (req->apid[0] != '\0') { application = dlt_daemon_application_find(daemon, req->apid, daemon->ecuid, verbose); if (application) { num_applications = 1; if (req->ctid[0] != '\0') { context = dlt_daemon_context_find(daemon, req->apid, req->ctid, daemon->ecuid, verbose); num_contexts = ((context) ? 1 : 0); } else { num_contexts = application->num_contexts; } } else { num_applications = 0; num_contexts = 0; } } else { /* Request all applications and contexts */ num_applications = user_list->num_applications; num_contexts = user_list->num_contexts; } /* prepare payload of data */ /* Calculate maximum size for a response */ resp.datasize = sizeof(uint32_t) /* SID */ + sizeof(int8_t) /* status*/ + sizeof(ID4) /* DLT_DAEMON_REMO_STRING */; sizecont = sizeof(uint32_t) /* context_id */; /* Add additional size for response of Mode 4, 6, 7 */ if ((req->options == 4) || (req->options == 6) || (req->options == 7)) sizecont += sizeof(int8_t); /* log level */ /* Add additional size for response of Mode 5, 6, 7 */ if ((req->options == 5) || (req->options == 6) || (req->options == 7)) sizecont += sizeof(int8_t); /* trace status */ resp.datasize += (num_applications * (sizeof(uint32_t) /* app_id */ + sizeof(uint16_t) /* count_con_ids */)) + (num_contexts * sizecont); resp.datasize += sizeof(uint16_t) /* count_app_ids */; /* Add additional size for response of Mode 7 */ if (req->options == 7) { if (req->apid[0] != '\0') { if (req->ctid[0] != '\0') { /* One application, one context */ /* context = dlt_daemon_context_find(daemon, req->apid, req->ctid, verbose); */ if (context) { resp.datasize += sizeof(uint16_t) /* len_context_description */; if (context->context_description != 0) resp.datasize += strlen(context->context_description); /* context_description */ } } else /* One application, all contexts */ if ((user_list->applications) && (application)) { /* Calculate start offset within contexts[] */ offset_base = 0; for (i = 0; i < (application - (user_list->applications)); i++) offset_base += user_list->applications[i].num_contexts; /* Iterate over all contexts belonging to this application */ for (j = 0; j < application->num_contexts; j++) { context = &(user_list->contexts[offset_base + j]); if (context) { resp.datasize += sizeof(uint16_t) /* len_context_description */; if (context->context_description != 0) resp.datasize += strlen(context->context_description); /* context_description */ } } } /* Space for application description */ if (application) { resp.datasize += sizeof(uint16_t) /* len_app_description */; if (application->application_description != 0) resp.datasize += strlen(application->application_description); /* app_description */ } } else { /* All applications, all contexts */ for (i = 0; i < user_list->num_contexts; i++) { resp.datasize += sizeof(uint16_t) /* len_context_description */; if (user_list->contexts[i].context_description != 0) resp.datasize += strlen(user_list->contexts[i].context_description); } for (i = 0; i < user_list->num_applications; i++) { resp.datasize += sizeof(uint16_t) /* len_app_description */; if (user_list->applications[i].application_description != 0) resp.datasize += strlen(user_list->applications[i].application_description); /* app_description */ } } } if (verbose) dlt_vlog(LOG_DEBUG, "Allocate %d bytes for response msg databuffer\n", resp.datasize); /* Allocate buffer for response message */ resp.databuffer = (uint8_t *)malloc(resp.datasize); resp.databuffersize = resp.datasize; if (resp.databuffer == 0) { dlt_daemon_control_service_response(sock, daemon, daemon_local, DLT_SERVICE_ID_GET_LOG_INFO, DLT_SERVICE_RESPONSE_ERROR, verbose); return; } memset(resp.databuffer, 0, resp.datasize); /* Preparation finished */ /* Prepare response */ sid = DLT_SERVICE_ID_GET_LOG_INFO; memcpy(resp.databuffer, &sid, sizeof(uint32_t)); offset += sizeof(uint32_t); value = (((num_applications != 0) && (num_contexts != 0)) ? req->options : 8); /* 8 = no matching context found */ memcpy(resp.databuffer + offset, &value, sizeof(int8_t)); offset += sizeof(int8_t); count_app_ids = num_applications; if (count_app_ids != 0) { memcpy(resp.databuffer + offset, &count_app_ids, sizeof(uint16_t)); offset += sizeof(uint16_t); #if (DLT_DEBUG_GETLOGINFO == 1) dlt_vlog(LOG_DEBUG, "#apid: %d \n", count_app_ids); #endif for (i = 0; i < count_app_ids; i++) { if (req->apid[0] != '\0') { apid = req->apid; } else { if (user_list->applications) apid = user_list->applications[i].apid; else /* This should never occur! */ apid = 0; } application = dlt_daemon_application_find(daemon, apid, daemon->ecuid, verbose); if (application) { /* Calculate start offset within contexts[] */ offset_base = 0; for (j = 0; j < (application - (user_list->applications)); j++) offset_base += user_list->applications[j].num_contexts; dlt_set_id((char *)(resp.databuffer + offset), apid); offset += sizeof(ID4); #if (DLT_DEBUG_GETLOGINFO == 1) dlt_print_id(buf, apid); dlt_vlog(LOG_DEBUG, "apid: %s\n", buf); #endif if (req->apid[0] != '\0') count_con_ids = num_contexts; else count_con_ids = application->num_contexts; memcpy(resp.databuffer + offset, &count_con_ids, sizeof(uint16_t)); offset += sizeof(uint16_t); #if (DLT_DEBUG_GETLOGINFO == 1) dlt_vlog(LOG_DEBUG, "#ctid: %d \n", count_con_ids); #endif for (j = 0; j < count_con_ids; j++) { #if (DLT_DEBUG_GETLOGINFO == 1) dlt_vlog(LOG_DEBUG, "j: %d \n", j); #endif if (!((count_con_ids == 1) && (req->apid[0] != '\0') && (req->ctid[0] != '\0'))) context = &(user_list->contexts[offset_base + j]); /* else: context was already searched and found * (one application (found) with one context (found))*/ if ((context) && ((req->ctid[0] == '\0') || ((req->ctid[0] != '\0') && (memcmp(context->ctid, req->ctid, DLT_ID_SIZE) == 0))) ) { dlt_set_id((char *)(resp.databuffer + offset), context->ctid); offset += sizeof(ID4); #if (DLT_DEBUG_GETLOGINFO == 1) dlt_print_id(buf, context->ctid); dlt_vlog(LOG_DEBUG, "ctid: %s \n", buf); #endif /* Mode 4, 6, 7 */ if ((req->options == 4) || (req->options == 6) || (req->options == 7)) { ll = context->log_level; memcpy(resp.databuffer + offset, &ll, sizeof(int8_t)); offset += sizeof(int8_t); } /* Mode 5, 6, 7 */ if ((req->options == 5) || (req->options == 6) || (req->options == 7)) { ts = context->trace_status; memcpy(resp.databuffer + offset, &ts, sizeof(int8_t)); offset += sizeof(int8_t); } /* Mode 7 */ if (req->options == 7) { if (context->context_description) { len = strlen(context->context_description); memcpy(resp.databuffer + offset, &len, sizeof(uint16_t)); offset += sizeof(uint16_t); memcpy(resp.databuffer + offset, context->context_description, strlen(context->context_description)); offset += strlen(context->context_description); } else { len = 0; memcpy(resp.databuffer + offset, &len, sizeof(uint16_t)); offset += sizeof(uint16_t); } } #if (DLT_DEBUG_GETLOGINFO == 1) dlt_vlog(LOG_DEBUG, "ll=%d ts=%d \n", (int32_t)ll, (int32_t)ts); #endif } #if (DLT_DEBUG_GETLOGINFO == 1) dlt_log(LOG_DEBUG, "\n"); #endif } /* Mode 7 */ if (req->options == 7) { if (application->application_description) { len = strlen(application->application_description); memcpy(resp.databuffer + offset, &len, sizeof(uint16_t)); offset += sizeof(uint16_t); memcpy(resp.databuffer + offset, application->application_description, strlen(application->application_description)); offset += strlen(application->application_description); } else { len = 0; memcpy(resp.databuffer + offset, &len, sizeof(uint16_t)); offset += sizeof(uint16_t); } } } /* if (application) */ } /* for (i=0;iservice_id = DLT_SERVICE_ID_MESSAGE_BUFFER_OVERFLOW; resp->status = DLT_SERVICE_RESPONSE_OK; resp->overflow = DLT_MESSAGE_BUFFER_OVERFLOW; resp->overflow_counter = overflow_counter; /* send message */ if ((ret = dlt_daemon_client_send_control_message(sock, daemon, daemon_local, &msg, apid, "", verbose))) { dlt_message_free(&msg, 0); return ret; } /* free message */ dlt_message_free(&msg, 0); return DLT_DAEMON_ERROR_OK; } void dlt_daemon_control_service_response(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, uint32_t service_id, int8_t status, int verbose) { DltMessage msg; DltServiceResponse *resp; PRINT_FUNCTION_VERBOSE(verbose); if (daemon == 0) return; /* initialise new message */ if (dlt_message_init(&msg, 0) == DLT_RETURN_ERROR) return; /* prepare payload of data */ msg.datasize = sizeof(DltServiceResponse); if (msg.databuffer && (msg.databuffersize < msg.datasize)) { free(msg.databuffer); msg.databuffer = 0; } if (msg.databuffer == 0) { msg.databuffer = (uint8_t *)malloc(msg.datasize); msg.databuffersize = msg.datasize; } if (msg.databuffer == 0) return; resp = (DltServiceResponse *)msg.databuffer; resp->service_id = service_id; resp->status = status; /* send message */ dlt_daemon_client_send_control_message(sock, daemon, daemon_local, &msg, "", "", verbose); /* free message */ dlt_message_free(&msg, 0); } int dlt_daemon_control_message_unregister_context(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, char *apid, char *ctid, char *comid, int verbose) { DltMessage msg; DltServiceUnregisterContext *resp; PRINT_FUNCTION_VERBOSE(verbose); if (daemon == 0) return -1; /* initialise new message */ if (dlt_message_init(&msg, 0) == DLT_RETURN_ERROR) return -1; /* prepare payload of data */ msg.datasize = sizeof(DltServiceUnregisterContext); if (msg.databuffer && (msg.databuffersize < msg.datasize)) { free(msg.databuffer); msg.databuffer = 0; } if (msg.databuffer == 0) { msg.databuffer = (uint8_t *)malloc(msg.datasize); msg.databuffersize = msg.datasize; } if (msg.databuffer == 0) return -1; resp = (DltServiceUnregisterContext *)msg.databuffer; resp->service_id = DLT_SERVICE_ID_UNREGISTER_CONTEXT; resp->status = DLT_SERVICE_RESPONSE_OK; dlt_set_id(resp->apid, apid); dlt_set_id(resp->ctid, ctid); dlt_set_id(resp->comid, comid); /* send message */ if (dlt_daemon_client_send_control_message(sock, daemon, daemon_local, &msg, "", "", verbose)) { dlt_message_free(&msg, 0); return -1; } /* free message */ dlt_message_free(&msg, 0); return 0; } int dlt_daemon_control_message_connection_info(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, uint8_t state, char *comid, int verbose) { DltMessage msg; DltServiceConnectionInfo *resp; PRINT_FUNCTION_VERBOSE(verbose); if (daemon == 0) return -1; /* initialise new message */ if (dlt_message_init(&msg, 0) == DLT_RETURN_ERROR) return -1; /* prepare payload of data */ msg.datasize = sizeof(DltServiceConnectionInfo); if (msg.databuffer && (msg.databuffersize < msg.datasize)) { free(msg.databuffer); msg.databuffer = 0; } if (msg.databuffer == 0) { msg.databuffer = (uint8_t *)malloc(msg.datasize); msg.databuffersize = msg.datasize; } if (msg.databuffer == 0) return -1; resp = (DltServiceConnectionInfo *)msg.databuffer; resp->service_id = DLT_SERVICE_ID_CONNECTION_INFO; resp->status = DLT_SERVICE_RESPONSE_OK; resp->state = state; dlt_set_id(resp->comid, comid); /* send message */ if (dlt_daemon_client_send_control_message(sock, daemon, daemon_local, &msg, "", "", verbose)) { dlt_message_free(&msg, 0); return -1; } /* free message */ dlt_message_free(&msg, 0); return 0; } int dlt_daemon_control_message_timezone(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose) { DltMessage msg; DltServiceTimezone *resp; PRINT_FUNCTION_VERBOSE(verbose); if (daemon == 0) return -1; /* initialise new message */ if (dlt_message_init(&msg, 0) == DLT_RETURN_ERROR) return -1; /* prepare payload of data */ msg.datasize = sizeof(DltServiceTimezone); if (msg.databuffer && (msg.databuffersize < msg.datasize)) { free(msg.databuffer); msg.databuffer = 0; } if (msg.databuffer == 0) { msg.databuffer = (uint8_t *)malloc(msg.datasize); msg.databuffersize = msg.datasize; } if (msg.databuffer == 0) return -1; resp = (DltServiceTimezone *)msg.databuffer; resp->service_id = DLT_SERVICE_ID_TIMEZONE; resp->status = DLT_SERVICE_RESPONSE_OK; time_t t = time(NULL); struct tm lt; localtime_r(&t, <); #if !defined(__CYGWIN__) resp->timezone = (int32_t)lt.tm_gmtoff; #endif resp->isdst = (uint8_t)lt.tm_isdst; /* send message */ if (dlt_daemon_client_send_control_message(sock, daemon, daemon_local, &msg, "", "", verbose)) { dlt_message_free(&msg, 0); return -1; } /* free message */ dlt_message_free(&msg, 0); return 0; } int dlt_daemon_control_message_marker(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose) { DltMessage msg; DltServiceMarker *resp; PRINT_FUNCTION_VERBOSE(verbose); if (daemon == 0) return -1; /* initialise new message */ if (dlt_message_init(&msg, 0) == DLT_RETURN_ERROR) return -1; /* prepare payload of data */ msg.datasize = sizeof(DltServiceMarker); if (msg.databuffer && (msg.databuffersize < msg.datasize)) { free(msg.databuffer); msg.databuffer = 0; } if (msg.databuffer == 0) { msg.databuffer = (uint8_t *)malloc(msg.datasize); msg.databuffersize = msg.datasize; } if (msg.databuffer == 0) return -1; resp = (DltServiceMarker *)msg.databuffer; resp->service_id = DLT_SERVICE_ID_MARKER; resp->status = DLT_SERVICE_RESPONSE_OK; /* send message */ if (dlt_daemon_client_send_control_message(sock, daemon, daemon_local, &msg, "", "", verbose)) { dlt_message_free(&msg, 0); return -1; } /* free message */ dlt_message_free(&msg, 0); return 0; } void dlt_daemon_control_callsw_cinjection(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, DltMessage *msg, int verbose) { char apid[DLT_ID_SIZE], ctid[DLT_ID_SIZE]; uint32_t id = 0, id_tmp = 0; uint8_t *ptr; DltDaemonContext *context; int32_t data_length_inject = 0; uint32_t data_length_inject_tmp = 0; int32_t datalength; DltUserHeader userheader; DltUserControlMsgInjection usercontext; uint8_t *userbuffer; PRINT_FUNCTION_VERBOSE(verbose); if ((daemon == NULL) || (msg == NULL) || (msg->databuffer == NULL)) return; datalength = msg->datasize; ptr = msg->databuffer; DLT_MSG_READ_VALUE(id_tmp, ptr, datalength, uint32_t); /* Get service id */ id = DLT_ENDIAN_GET_32(msg->standardheader->htyp, id_tmp); /* id is always less than DLT_DAEMON_INJECTION_MAX since its type is uinit32_t */ if (id >= DLT_DAEMON_INJECTION_MIN) { /* This a a real SW-C injection call */ data_length_inject = 0; data_length_inject_tmp = 0; DLT_MSG_READ_VALUE(data_length_inject_tmp, ptr, datalength, uint32_t); /* Get data length */ data_length_inject = DLT_ENDIAN_GET_32(msg->standardheader->htyp, data_length_inject_tmp); /* Get context handle for apid, ctid (and seid) */ /* Warning: seid is ignored in this implementation! */ if (DLT_IS_HTYP_UEH(msg->standardheader->htyp)) { dlt_set_id(apid, msg->extendedheader->apid); dlt_set_id(ctid, msg->extendedheader->ctid); } else { /* No extended header, and therefore no apid and ctid available */ dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_ERROR, verbose); return; } /* At this point, apid and ctid is available */ context = dlt_daemon_context_find(daemon, apid, ctid, daemon->ecuid, verbose); if (context == 0) { /* dlt_log(LOG_INFO,"No context found!\n"); */ dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_ERROR, verbose); return; } /* Send user message to handle, specified in context */ if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_INJECTION) < DLT_RETURN_OK) { dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_ERROR, verbose); return; } usercontext.log_level_pos = context->log_level_pos; if (data_length_inject > msg->databuffersize) { dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_ERROR, verbose); return; } userbuffer = malloc(data_length_inject); if (userbuffer == 0) { dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_ERROR, verbose); return; } usercontext.data_length_inject = data_length_inject; usercontext.service_id = id; memcpy(userbuffer, ptr, data_length_inject); /* Copy received injection to send buffer */ /* write to FIFO */ DltReturnValue ret = dlt_user_log_out3(context->user_handle, &(userheader), sizeof(DltUserHeader), &(usercontext), sizeof(DltUserControlMsgInjection), userbuffer, data_length_inject); if (ret < DLT_RETURN_OK) { if (ret == DLT_RETURN_PIPE_ERROR) { /* Close connection */ close(context->user_handle); context->user_handle = DLT_FD_INIT; } dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_ERROR, verbose); } else { dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_OK, verbose); } free(userbuffer); userbuffer = 0; } else { /* Invalid ID */ dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_NOT_SUPPORTED, verbose); } } void dlt_daemon_send_log_level(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, DltDaemonContext *context, int8_t loglevel, int verbose) { PRINT_FUNCTION_VERBOSE(verbose); int32_t id = DLT_SERVICE_ID_SET_LOG_LEVEL; int8_t old_log_level = 0; old_log_level = context->log_level; context->log_level = loglevel; /* No endianess conversion necessary*/ if ((context->user_handle >= DLT_FD_MINIMUM) && (dlt_daemon_user_send_log_level(daemon, context, verbose) == 0)) { dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_OK, verbose); } else { dlt_log(LOG_ERR, "Log level could not be sent!\n"); context->log_level = old_log_level; dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_ERROR, verbose); } } void dlt_daemon_find_multiple_context_and_send_log_level(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, int8_t app_flag, char *str, int8_t len, int8_t loglevel, int verbose) { PRINT_FUNCTION_VERBOSE(verbose); int count = 0; DltDaemonContext *context = NULL; char src_str[DLT_ID_SIZE + 1] = { 0 }; int8_t ret = 0; DltDaemonRegisteredUsers *user_list = NULL; if (daemon == 0) { dlt_vlog(LOG_ERR, "%s: Invalid parameters\n", __func__); return; } user_list = dlt_daemon_find_users_list(daemon, daemon->ecuid, verbose); if (user_list == NULL) return; for (count = 0; count < user_list->num_contexts; count++) { context = &(user_list->contexts[count]); if (context) { if (app_flag == 1) strncpy(src_str, context->apid, DLT_ID_SIZE); else strncpy(src_str, context->ctid, DLT_ID_SIZE); ret = strncmp(src_str, str, len); if (ret == 0) dlt_daemon_send_log_level(sock, daemon, daemon_local, context, loglevel, verbose); else if ((ret > 0) && (app_flag == 1)) break; else continue; } } } void dlt_daemon_control_set_log_level(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, DltMessage *msg, int verbose) { PRINT_FUNCTION_VERBOSE(verbose); char apid[DLT_ID_SIZE + 1] = { 0 }; char ctid[DLT_ID_SIZE + 1] = { 0 }; DltServiceSetLogLevel *req = NULL; DltDaemonContext *context = NULL; int8_t apid_length = 0; int8_t ctid_length = 0; if ((daemon == NULL) || (msg == NULL) || (msg->databuffer == NULL)) return; if (DLT_CHECK_RCV_DATA_SIZE(msg->datasize, sizeof(DltServiceSetLogLevel)) < 0) return; req = (DltServiceSetLogLevel *)(msg->databuffer); if (daemon_local->flags.enforceContextLLAndTS) req->log_level = getStatus(req->log_level, daemon_local->flags.contextLogLevel); dlt_set_id(apid, req->apid); dlt_set_id(ctid, req->ctid); apid_length = strlen(apid); ctid_length = strlen(ctid); if ((apid_length != 0) && (apid[apid_length - 1] == '*') && (ctid[0] == 0)) { /*apid provided having '*' in it and ctid is null*/ dlt_daemon_find_multiple_context_and_send_log_level(sock, daemon, daemon_local, 1, apid, apid_length - 1, req->log_level, verbose); } else if ((ctid_length != 0) && (ctid[ctid_length - 1] == '*') && (apid[0] == 0)) /*ctid provided is having '*' in it and apid is null*/ { dlt_daemon_find_multiple_context_and_send_log_level(sock, daemon, daemon_local, 0, ctid, ctid_length - 1, req->log_level, verbose); } else if ((apid_length != 0) && (apid[apid_length - 1] != '*') && (ctid[0] == 0)) /*only app id case*/ { dlt_daemon_find_multiple_context_and_send_log_level(sock, daemon, daemon_local, 1, apid, DLT_ID_SIZE, req->log_level, verbose); } else if ((ctid_length != 0) && (ctid[ctid_length - 1] != '*') && (apid[0] == 0)) /*only context id case*/ { dlt_daemon_find_multiple_context_and_send_log_level(sock, daemon, daemon_local, 0, ctid, DLT_ID_SIZE, req->log_level, verbose); } else { context = dlt_daemon_context_find(daemon, apid, ctid, daemon->ecuid, verbose); /* Set log level */ if (context != 0) { dlt_daemon_send_log_level(sock, daemon, daemon_local, context, req->log_level, verbose); } else { dlt_vlog(LOG_ERR, "Could not set log level: %d. Context [%.4s:%.4s] not found:", req->log_level, apid, ctid); dlt_daemon_control_service_response(sock, daemon, daemon_local, DLT_SERVICE_ID_SET_LOG_LEVEL, DLT_SERVICE_RESPONSE_ERROR, verbose); } } } void dlt_daemon_send_trace_status(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, DltDaemonContext *context, int8_t tracestatus, int verbose) { PRINT_FUNCTION_VERBOSE(verbose); int32_t id = DLT_SERVICE_ID_SET_TRACE_STATUS; int8_t old_trace_status = 0; old_trace_status = context->trace_status; context->trace_status = tracestatus; /* No endianess conversion necessary*/ if ((context->user_handle >= DLT_FD_MINIMUM) && (dlt_daemon_user_send_log_level(daemon, context, verbose) == 0)) { dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_OK, verbose); } else { dlt_log(LOG_ERR, "Trace status could not be sent!\n"); context->trace_status = old_trace_status; dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_ERROR, verbose); } } void dlt_daemon_find_multiple_context_and_send_trace_status(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, int8_t app_flag, char *str, int8_t len, int8_t tracestatus, int verbose) { PRINT_FUNCTION_VERBOSE(verbose); int count = 0; DltDaemonContext *context = NULL; char src_str[DLT_ID_SIZE + 1] = { 0 }; int8_t ret = 0; DltDaemonRegisteredUsers *user_list = NULL; if (daemon == 0) { dlt_vlog(LOG_ERR, "%s: Invalid parameters\n", __func__); return; } user_list = dlt_daemon_find_users_list(daemon, daemon->ecuid, verbose); if (user_list == NULL) return; for (count = 0; count < user_list->num_contexts; count++) { context = &(user_list->contexts[count]); if (context) { if (app_flag == 1) strncpy(src_str, context->apid, DLT_ID_SIZE); else strncpy(src_str, context->ctid, DLT_ID_SIZE); ret = strncmp(src_str, str, len); if (ret == 0) dlt_daemon_send_trace_status(sock, daemon, daemon_local, context, tracestatus, verbose); else if ((ret > 0) && (app_flag == 1)) break; else continue; } } } void dlt_daemon_control_set_trace_status(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, DltMessage *msg, int verbose) { PRINT_FUNCTION_VERBOSE(verbose); char apid[DLT_ID_SIZE + 1] = { 0 }; char ctid[DLT_ID_SIZE + 1] = { 0 }; DltServiceSetLogLevel *req = NULL; DltDaemonContext *context = NULL; int8_t apid_length = 0; int8_t ctid_length = 0; if ((daemon == NULL) || (msg == NULL) || (msg->databuffer == NULL)) return; if (DLT_CHECK_RCV_DATA_SIZE(msg->datasize, sizeof(DltServiceSetLogLevel)) < 0) return; req = (DltServiceSetLogLevel *)(msg->databuffer); if (daemon_local->flags.enforceContextLLAndTS) req->log_level = getStatus(req->log_level, daemon_local->flags.contextTraceStatus); dlt_set_id(apid, req->apid); dlt_set_id(ctid, req->ctid); apid_length = strlen(apid); ctid_length = strlen(ctid); if ((apid_length != 0) && (apid[apid_length - 1] == '*') && (ctid[0] == 0)) { /*apid provided having '*' in it and ctid is null*/ dlt_daemon_find_multiple_context_and_send_trace_status(sock, daemon, daemon_local, 1, apid, apid_length - 1, req->log_level, verbose); } else if ((ctid_length != 0) && (ctid[ctid_length - 1] == '*') && (apid[0] == 0)) /*ctid provided is having '*' in it and apid is null*/ { dlt_daemon_find_multiple_context_and_send_trace_status(sock, daemon, daemon_local, 0, ctid, ctid_length - 1, req->log_level, verbose); } else if ((apid_length != 0) && (apid[apid_length - 1] != '*') && (ctid[0] == 0)) /*only app id case*/ { dlt_daemon_find_multiple_context_and_send_trace_status(sock, daemon, daemon_local, 1, apid, DLT_ID_SIZE, req->log_level, verbose); } else if ((ctid_length != 0) && (ctid[ctid_length - 1] != '*') && (apid[0] == 0)) /*only context id case*/ { dlt_daemon_find_multiple_context_and_send_trace_status(sock, daemon, daemon_local, 0, ctid, DLT_ID_SIZE, req->log_level, verbose); } else { context = dlt_daemon_context_find(daemon, apid, ctid, daemon->ecuid, verbose); /* Set trace status */ if (context != 0) { dlt_daemon_send_trace_status(sock, daemon, daemon_local, context, req->log_level, verbose); } else { dlt_vlog(LOG_ERR, "Could not set trace status: %d. Context [%.4s:%.4s] not found:", req->log_level, apid, ctid); dlt_daemon_control_service_response(sock, daemon, daemon_local, DLT_SERVICE_ID_SET_LOG_LEVEL, DLT_SERVICE_RESPONSE_ERROR, verbose); } } } void dlt_daemon_control_set_default_log_level(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, DltMessage *msg, int verbose) { PRINT_FUNCTION_VERBOSE(verbose); DltServiceSetDefaultLogLevel *req; int32_t id = DLT_SERVICE_ID_SET_DEFAULT_LOG_LEVEL; if ((daemon == NULL) || (msg == NULL) || (msg->databuffer == NULL)) return; if (DLT_CHECK_RCV_DATA_SIZE(msg->datasize, sizeof(DltServiceSetDefaultLogLevel)) < 0) return; req = (DltServiceSetDefaultLogLevel *)(msg->databuffer); /* No endianess conversion necessary */ if (/*(req->log_level>=0) &&*/ (req->log_level <= DLT_LOG_VERBOSE)) { if (daemon_local->flags.enforceContextLLAndTS) daemon->default_log_level = getStatus(req->log_level, daemon_local->flags.contextLogLevel); else daemon->default_log_level = req->log_level; /* No endianess conversion necessary */ /* Send Update to all contexts using the default log level */ dlt_daemon_user_send_default_update(daemon, verbose); dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_OK, verbose); } else { dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_ERROR, verbose); } } void dlt_daemon_control_set_all_log_level(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, DltMessage *msg, int verbose) { PRINT_FUNCTION_VERBOSE(verbose); DltServiceSetDefaultLogLevel *req = NULL; int32_t id = DLT_SERVICE_ID_SET_ALL_LOG_LEVEL; int8_t loglevel = 0; if ((daemon == NULL) || (msg == NULL) || (msg->databuffer == NULL)) { dlt_vlog(LOG_ERR, "%s: Invalid parameters\n", __func__); return; } if (DLT_CHECK_RCV_DATA_SIZE(msg->datasize, sizeof(DltServiceSetDefaultLogLevel)) < 0) return; req = (DltServiceSetDefaultLogLevel *)(msg->databuffer); /* No endianess conversion necessary */ if ((req != NULL) && ((req->log_level <= DLT_LOG_VERBOSE) || (req->log_level == (uint8_t)DLT_LOG_DEFAULT))) { if (daemon_local->flags.enforceContextLLAndTS) loglevel = getStatus(req->log_level, daemon_local->flags.contextLogLevel); else loglevel = req->log_level; /* No endianess conversion necessary */ /* Send Update to all contexts using the new log level */ dlt_daemon_user_send_all_log_level_update(daemon, loglevel, verbose); dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_OK, verbose); } else { dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_ERROR, verbose); } } void dlt_daemon_control_set_default_trace_status(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, DltMessage *msg, int verbose) { PRINT_FUNCTION_VERBOSE(verbose); /* Payload of request message */ DltServiceSetDefaultLogLevel *req; int32_t id = DLT_SERVICE_ID_SET_DEFAULT_TRACE_STATUS; if ((daemon == NULL) || (msg == NULL) || (msg->databuffer == NULL)) return; if (DLT_CHECK_RCV_DATA_SIZE(msg->datasize, sizeof(DltServiceSetDefaultLogLevel)) < 0) return; req = (DltServiceSetDefaultLogLevel *)(msg->databuffer); /* No endianess conversion necessary */ if ((req->log_level == DLT_TRACE_STATUS_OFF) || (req->log_level == DLT_TRACE_STATUS_ON)) { if (daemon_local->flags.enforceContextLLAndTS) daemon->default_trace_status = getStatus(req->log_level, daemon_local->flags.contextTraceStatus); else daemon->default_trace_status = req->log_level; /* No endianess conversion necessary*/ /* Send Update to all contexts using the default trace status */ dlt_daemon_user_send_default_update(daemon, verbose); dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_OK, verbose); } else { dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_ERROR, verbose); } } void dlt_daemon_control_set_all_trace_status(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, DltMessage *msg, int verbose) { PRINT_FUNCTION_VERBOSE(verbose); DltServiceSetDefaultLogLevel *req = NULL; int32_t id = DLT_SERVICE_ID_SET_ALL_TRACE_STATUS; int8_t tracestatus = 0; if ((daemon == NULL) || (msg == NULL) || (msg->databuffer == NULL)) { dlt_vlog(LOG_ERR, "%s: Invalid parameters\n", __func__); return; } if (DLT_CHECK_RCV_DATA_SIZE(msg->datasize, sizeof(DltServiceSetDefaultLogLevel)) < 0) return; req = (DltServiceSetDefaultLogLevel *)(msg->databuffer); /* No endianess conversion necessary */ if ((req != NULL) && ((req->log_level <= DLT_TRACE_STATUS_ON) || (req->log_level == (uint8_t)DLT_TRACE_STATUS_DEFAULT))) { if (daemon_local->flags.enforceContextLLAndTS) tracestatus = getStatus(req->log_level, daemon_local->flags.contextTraceStatus); else tracestatus = req->log_level; /* No endianess conversion necessary */ /* Send Update to all contexts using the new log level */ dlt_daemon_user_send_all_trace_status_update(daemon, tracestatus, verbose); dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_OK, verbose); } else { dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_ERROR, verbose); } } void dlt_daemon_control_set_timing_packets(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, DltMessage *msg, int verbose) { PRINT_FUNCTION_VERBOSE(verbose); DltServiceSetVerboseMode *req; /* request uses same struct as set verbose mode */ int32_t id = DLT_SERVICE_ID_SET_TIMING_PACKETS; if ((daemon == NULL) || (msg == NULL) || (msg->databuffer == NULL)) return; if (DLT_CHECK_RCV_DATA_SIZE(msg->datasize, sizeof(DltServiceSetVerboseMode)) < 0) return; req = (DltServiceSetVerboseMode *)(msg->databuffer); if ((req->new_status == 0) || (req->new_status == 1)) { daemon->timingpackets = req->new_status; dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_OK, verbose); } else { dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_ERROR, verbose); } } void dlt_daemon_control_message_time(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose) { DltMessage msg; int32_t len; PRINT_FUNCTION_VERBOSE(verbose); if (daemon == 0) return; /* initialise new message */ if (dlt_message_init(&msg, 0) == DLT_RETURN_ERROR) return; /* send message */ /* prepare storage header */ msg.storageheader = (DltStorageHeader *)msg.headerbuffer; dlt_set_storageheader(msg.storageheader, daemon->ecuid); /* prepare standard header */ msg.standardheader = (DltStandardHeader *)(msg.headerbuffer + sizeof(DltStorageHeader)); msg.standardheader->htyp = DLT_HTYP_WEID | DLT_HTYP_WTMS | DLT_HTYP_UEH | DLT_HTYP_PROTOCOL_VERSION1; #if (BYTE_ORDER == BIG_ENDIAN) msg.standardheader->htyp = (msg.standardheader->htyp | DLT_HTYP_MSBF); #endif msg.standardheader->mcnt = 0; /* Set header extra parameters */ dlt_set_id(msg.headerextra.ecu, daemon->ecuid); msg.headerextra.tmsp = dlt_uptime(); dlt_message_set_extraparameters(&msg, verbose); /* prepare extended header */ msg.extendedheader = (DltExtendedHeader *)(msg.headerbuffer + sizeof(DltStorageHeader) + sizeof(DltStandardHeader) + DLT_STANDARD_HEADER_EXTRA_SIZE(msg.standardheader->htyp)); msg.extendedheader->msin = DLT_MSIN_CONTROL_TIME; msg.extendedheader->noar = 0; /* number of arguments */ dlt_set_id(msg.extendedheader->apid, ""); /* application id */ dlt_set_id(msg.extendedheader->ctid, ""); /* context id */ /* prepare length information */ msg.headersize = sizeof(DltStorageHeader) + sizeof(DltStandardHeader) + sizeof(DltExtendedHeader) + DLT_STANDARD_HEADER_EXTRA_SIZE(msg.standardheader->htyp); len = msg.headersize - sizeof(DltStorageHeader) + msg.datasize; if (len > UINT16_MAX) { dlt_log(LOG_WARNING, "Huge control message discarded!\n"); /* free message */ dlt_message_free(&msg, 0); return; } msg.standardheader->len = DLT_HTOBE_16(((uint16_t)len)); /* Send message, ignore return value */ dlt_daemon_client_send(sock, daemon, daemon_local, msg.headerbuffer, sizeof(DltStorageHeader), msg.headerbuffer + sizeof(DltStorageHeader), msg.headersize - sizeof(DltStorageHeader), msg.databuffer, msg.datasize, verbose); /* free message */ dlt_message_free(&msg, 0); } int dlt_daemon_process_one_s_timer(DltDaemon *daemon, DltDaemonLocal *daemon_local, DltReceiver *receiver, int verbose) { uint64_t expir = 0; ssize_t res = 0; PRINT_FUNCTION_VERBOSE(verbose); if ((daemon_local == NULL) || (daemon == NULL) || (receiver == NULL)) { dlt_vlog(LOG_ERR, "%s: invalid parameters", __func__); return -1; } res = read(receiver->fd, &expir, sizeof(expir)); if (res < 0) { dlt_vlog(LOG_WARNING, "%s: Fail to read timer (%s)\n", __func__, strerror(errno)); /* Activity received on timer_wd, but unable to read the fd: * let's go on sending notification */ } if ((daemon->state == DLT_DAEMON_STATE_SEND_BUFFER) || (daemon->state == DLT_DAEMON_STATE_BUFFER_FULL)) { if (dlt_daemon_send_ringbuffer_to_client(daemon, daemon_local, daemon_local->flags.vflag)) dlt_log(LOG_DEBUG, "Can't send contents of ring buffer to clients\n"); } if ((daemon->timingpackets) && (daemon->state == DLT_DAEMON_STATE_SEND_DIRECT)) dlt_daemon_control_message_time(DLT_DAEMON_SEND_TO_ALL, daemon, daemon_local, daemon_local->flags.vflag); dlt_log(LOG_DEBUG, "Timer timingpacket\n"); return 0; } int dlt_daemon_process_sixty_s_timer(DltDaemon *daemon, DltDaemonLocal *daemon_local, DltReceiver *receiver, int verbose) { uint64_t expir = 0; ssize_t res = 0; PRINT_FUNCTION_VERBOSE(verbose); if ((daemon_local == NULL) || (daemon == NULL) || (receiver == NULL)) { dlt_vlog(LOG_ERR, "%s: invalid parameters", __func__); return -1; } res = read(receiver->fd, &expir, sizeof(expir)); if (res < 0) { dlt_vlog(LOG_WARNING, "%s: Fail to read timer (%s)\n", __func__, strerror(errno)); /* Activity received on timer_wd, but unable to read the fd: * let's go on sending notification */ } if (daemon_local->flags.sendECUSoftwareVersion > 0) dlt_daemon_control_get_software_version(DLT_DAEMON_SEND_TO_ALL, daemon, daemon_local, daemon_local->flags.vflag); if (daemon_local->flags.sendTimezone > 0) { /* send timezone information */ time_t t = time(NULL); struct tm lt; /*Added memset to avoid compiler warning for near initialization */ memset((void *)<, 0, sizeof(lt)); localtime_r(&t, <); dlt_daemon_control_message_timezone(DLT_DAEMON_SEND_TO_ALL, daemon, daemon_local, daemon_local->flags.vflag); } dlt_log(LOG_DEBUG, "Timer ecuversion\n"); return 0; } #ifdef DLT_SYSTEMD_WATCHDOG_ENABLE int dlt_daemon_process_systemd_timer(DltDaemon *daemon, DltDaemonLocal *daemon_local, DltReceiver *receiver, int verbose) { uint64_t expir = 0; ssize_t res = -1; PRINT_FUNCTION_VERBOSE(verbose); if ((daemon_local == NULL) || (daemon == NULL) || (receiver == NULL)) { dlt_vlog(LOG_ERR, "%s: invalid parameters", __func__); return res; } res = read(receiver->fd, &expir, sizeof(expir)); if (res < 0) { dlt_vlog(LOG_WARNING, "Failed to read timer_wd; %s\n", strerror(errno)); /* Activity received on timer_wd, but unable to read the fd: * let's go on sending notification */ } if (sd_notify(0, "WATCHDOG=1") < 0) dlt_log(LOG_CRIT, "Could not reset systemd watchdog\n"); dlt_log(LOG_DEBUG, "Timer watchdog\n"); return 0; } #else int dlt_daemon_process_systemd_timer(DltDaemon *daemon, DltDaemonLocal *daemon_local, DltReceiver *receiver, int verbose) { (void)daemon; (void)daemon_local; (void)receiver; (void)verbose; dlt_log(LOG_DEBUG, "Timer watchdog not enabled\n"); return -1; } #endif void dlt_daemon_control_service_logstorage(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, DltMessage *msg, int verbose) { DltServiceOfflineLogstorage *req; int ret; unsigned int connection_type = 0; DltLogStorage *device = NULL; int device_index = -1; int i = 0; PRINT_FUNCTION_VERBOSE(verbose); if ((daemon == NULL) || (msg == NULL) || (daemon_local == NULL)) { dlt_vlog(LOG_ERR, "%s: Invalid function parameters\n", __func__); return; } if ((daemon_local->flags.offlineLogstorageMaxDevices <= 0) || (msg->databuffer == NULL)) { dlt_daemon_control_service_response(sock, daemon, daemon_local, DLT_SERVICE_ID_OFFLINE_LOGSTORAGE, DLT_SERVICE_RESPONSE_ERROR, verbose); dlt_log(LOG_INFO, "Logstorage functionality not enabled or MAX device set is 0\n"); return; } if (DLT_CHECK_RCV_DATA_SIZE(msg->datasize, sizeof(DltServiceOfflineLogstorage)) < 0) return; req = (DltServiceOfflineLogstorage *)(msg->databuffer); for (i = 0; i < daemon_local->flags.offlineLogstorageMaxDevices; i++) { connection_type = daemon->storage_handle[i].connection_type; /* Check if the requested device path is already used as log storage device */ if (strncmp(daemon->storage_handle[i].device_mount_point, req->mount_point, strlen(req->mount_point)) == 0) { device_index = i; break; } /* Get first available device index here */ if ((connection_type != DLT_OFFLINE_LOGSTORAGE_DEVICE_CONNECTED) && (device_index == -1)) device_index = i; } /* It might be possible to sync all caches of all devices */ if ((req->connection_type == DLT_OFFLINE_LOGSTORAGE_SYNC_CACHES) && (strlen(req->mount_point) == 0)) { /* It is expected to receive an empty mount point to sync all Logstorage * devices in this case. */ } else if (device_index == -1) { dlt_daemon_control_service_response(sock, daemon, daemon_local, DLT_SERVICE_ID_OFFLINE_LOGSTORAGE, DLT_SERVICE_RESPONSE_ERROR, verbose); dlt_log(LOG_WARNING, "MAX devices already in use \n"); return; } /* Check for device connection request from log storage ctrl app */ device = &daemon->storage_handle[device_index]; if (req->connection_type == DLT_OFFLINE_LOGSTORAGE_DEVICE_CONNECTED) { ret = dlt_logstorage_device_connected(device, req->mount_point); if (ret == 1) { dlt_daemon_control_service_response(sock, daemon, daemon_local, DLT_SERVICE_ID_OFFLINE_LOGSTORAGE, DLT_SERVICE_RESPONSE_WARNING, verbose); return; } else if (ret != 0) { dlt_daemon_control_service_response(sock, daemon, daemon_local, DLT_SERVICE_ID_OFFLINE_LOGSTORAGE, DLT_SERVICE_RESPONSE_ERROR, verbose); return; } dlt_daemon_control_service_response(sock, daemon, daemon_local, DLT_SERVICE_ID_OFFLINE_LOGSTORAGE, DLT_SERVICE_RESPONSE_OK, verbose); /* Check if log level of running application needs an update */ dlt_daemon_logstorage_update_application_loglevel(daemon, daemon_local, device_index, verbose); } /* Check for device disconnection request from log storage ctrl app */ else if (req->connection_type == DLT_OFFLINE_LOGSTORAGE_DEVICE_DISCONNECTED) { /* Check if log level of running application needs to be reset */ dlt_daemon_logstorage_reset_application_loglevel( daemon, daemon_local, device_index, daemon_local->flags.offlineLogstorageMaxDevices, verbose); dlt_logstorage_device_disconnected(&(daemon->storage_handle[device_index]), DLT_LOGSTORAGE_SYNC_ON_DEVICE_DISCONNECT); dlt_daemon_control_service_response(sock, daemon, daemon_local, DLT_SERVICE_ID_OFFLINE_LOGSTORAGE, DLT_SERVICE_RESPONSE_OK, verbose); } /* Check for cache synchronization request from log storage ctrl app */ else if (req->connection_type == DLT_OFFLINE_LOGSTORAGE_SYNC_CACHES) { int ret = 0; if (device_index == -1) { /* sync all Logstorage devices */ for (i = 0; i < daemon_local->flags.offlineLogstorageMaxDevices; i++) if (daemon->storage_handle[i].connection_type == DLT_OFFLINE_LOGSTORAGE_DEVICE_CONNECTED) ret = dlt_daemon_logstorage_sync_cache( daemon, daemon_local, daemon->storage_handle[i].device_mount_point, verbose); } else { /* trigger logstorage to sync caches */ ret = dlt_daemon_logstorage_sync_cache(daemon, daemon_local, req->mount_point, verbose); } if (ret == 0) dlt_daemon_control_service_response(sock, daemon, daemon_local, DLT_SERVICE_ID_OFFLINE_LOGSTORAGE, DLT_SERVICE_RESPONSE_OK, verbose); else dlt_daemon_control_service_response(sock, daemon, daemon_local, DLT_SERVICE_ID_OFFLINE_LOGSTORAGE, DLT_SERVICE_RESPONSE_ERROR, verbose); } else { dlt_daemon_control_service_response(sock, daemon, daemon_local, DLT_SERVICE_ID_OFFLINE_LOGSTORAGE, DLT_SERVICE_RESPONSE_ERROR, verbose); } } void dlt_daemon_control_passive_node_connect(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, DltMessage *msg, int verbose) { PRINT_FUNCTION_VERBOSE(verbose); DltServicePassiveNodeConnect *req; uint32_t id = DLT_SERVICE_ID_PASSIVE_NODE_CONNECT; if ((daemon == NULL) || (daemon_local == NULL) || (msg == NULL) || (msg->databuffer == NULL)) return; /* return error, if gateway mode not enabled*/ if (daemon_local->flags.gatewayMode == 0) { dlt_log(LOG_WARNING, "Received passive node connection status request, " "but GatewayMode is disabled\n"); dlt_daemon_control_service_response( sock, daemon, daemon_local, DLT_SERVICE_ID_PASSIVE_NODE_CONNECTION_STATUS, DLT_SERVICE_RESPONSE_ERROR, verbose); return; } if (DLT_CHECK_RCV_DATA_SIZE(msg->datasize, sizeof(DltServicePassiveNodeConnect)) < 0) return; req = (DltServicePassiveNodeConnect *)msg->databuffer; if (dlt_gateway_process_on_demand_request(&daemon_local->pGateway, daemon_local, req->node_id, req->connection_status, verbose) < 0) dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_ERROR, verbose); else dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_OK, verbose); } void dlt_daemon_control_passive_node_connect_status(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose) { DltMessage msg; DltServicePassiveNodeConnectionInfo *resp; DltGatewayConnection *con = NULL; unsigned int i = 0; PRINT_FUNCTION_VERBOSE(verbose); if ((daemon == NULL) || (daemon_local == NULL)) return; if (dlt_message_init(&msg, verbose) == -1) return; /* return error, if gateway mode not enabled*/ if (daemon_local->flags.gatewayMode == 0) { dlt_log(LOG_WARNING, "Received passive node connection status request, " "but GatewayMode is disabled\n"); dlt_daemon_control_service_response( sock, daemon, daemon_local, DLT_SERVICE_ID_PASSIVE_NODE_CONNECTION_STATUS, DLT_SERVICE_RESPONSE_ERROR, verbose); return; } /* prepare payload of data */ msg.datasize = sizeof(DltServicePassiveNodeConnectionInfo); if (msg.databuffer && (msg.databuffersize < msg.datasize)) msg.databuffer = NULL; if (msg.databuffer == NULL) { msg.databuffer = (uint8_t *)malloc(msg.datasize); if (msg.databuffer == NULL) { dlt_log(LOG_CRIT, "Cannot allocate memory for message response\n"); return; } msg.databuffersize = msg.datasize; } resp = (DltServicePassiveNodeConnectionInfo *)msg.databuffer; memset(resp, 0, msg.datasize); resp->service_id = DLT_SERVICE_ID_PASSIVE_NODE_CONNECTION_STATUS; resp->status = DLT_SERVICE_RESPONSE_OK; resp->num_connections = daemon_local->pGateway.num_connections; for (i = 0; i < resp->num_connections; i++) { if ((i * DLT_ID_SIZE) > DLT_ENTRY_MAX) { dlt_log(LOG_ERR, "Maximal message size reached. Skip further information\n"); break; } con = &daemon_local->pGateway.connections[i]; if (con == NULL) { dlt_log(LOG_CRIT, "Passive node connection structure is NULL\n"); dlt_daemon_control_service_response( sock, daemon, daemon_local, DLT_SERVICE_ID_PASSIVE_NODE_CONNECTION_STATUS, DLT_SERVICE_RESPONSE_ERROR, verbose); /* free message */ dlt_message_free(&msg, verbose); return; } resp->connection_status[i] = con->status; memcpy(&resp->node_id[i * DLT_ID_SIZE], con->ecuid, DLT_ID_SIZE); } dlt_daemon_client_send_control_message(sock, daemon, daemon_local, &msg, "", "", verbose); /* free message */ dlt_message_free(&msg, verbose); } dlt-daemon-2.18.4/src/daemon/dlt_daemon_client.h000066400000000000000000000462571353342203500215170ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2011-2015, BMW AG * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author Alexander Wenzel * * \copyright Copyright © 2011-2015 BMW AG. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file dlt_daemon_client.h */ /******************************************************************************* ** ** ** SRC-MODULE: dlt_daemon_client.h ** ** ** ** TARGET : linux ** ** ** ** PROJECT : DLT ** ** ** ** AUTHOR : Alexander Wenzel Alexander.AW.Wenzel@bmw.de ** ** ** ** PURPOSE : ** ** ** ** REMARKS : ** ** ** ** PLATFORM DEPENDANT [yes/no]: yes ** ** ** ** TO BE CHANGED BY USER [yes/no]: no ** ** ** *******************************************************************************/ /******************************************************************************* ** Author Identity ** ******************************************************************************** ** ** ** Initials Name Company ** ** -------- ------------------------- ---------------------------------- ** ** aw Alexander Wenzel BMW ** *******************************************************************************/ #ifndef DLT_DAEMON_CLIENT_H #define DLT_DAEMON_CLIENT_H #include /* for NAME_MAX */ #include "dlt_daemon_common.h" #include "dlt_user_shared.h" #include "dlt_user_shared_cfg.h" #include #include /** * Send out message to all the clients. * @param daemon pointer to dlt daemon structure * @param daemon_local pointer to dlt daemon local structure * @param verbose if set to true verbose information is printed out. * @return 1 if transfer succeed, 0 otherwise. */ int dlt_daemon_client_send_all(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose); /** * Send out message to client or store message in offline trace. * @param sock connection handle used for sending response * @param daemon pointer to dlt daemon structure * @param daemon_local pointer to dlt daemon local structure * @param storage_header pointer to data * @param storage_header_size size of data * @param data1 pointer to data * @param size1 size of data * @param data2 pointer to data * @param size2 size of data * @param verbose if set to true verbose information is printed out. * @return unequal 0 if there is an error or buffer is full */ int dlt_daemon_client_send(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, void *storage_header, int storage_header_size, void *data1, int size1, void *data2, int size2, int verbose); /** * Send out response message to dlt client * @param sock connection handle used for sending response * @param daemon pointer to dlt daemon structure * @param daemon_local pointer to dlt daemon local structure * @param msg pointer to response message * @param apid pointer to application id to be used in response message * @param ctid pointer to context id to be used in response message * @param verbose if set to true verbose information is printed out. * @return -1 if there is an error or buffer is full */ int dlt_daemon_client_send_control_message(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, DltMessage *msg, char *apid, char *ctid, int verbose); /** * Process and generate response to received get log info control message * @param sock connection handle used for sending response * @param daemon pointer to dlt daemon structure * @param daemon_local pointer to dlt daemon local structure * @param msg pointer to received control message * @param verbose if set to true verbose information is printed out. */ void dlt_daemon_control_get_log_info(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, DltMessage *msg, int verbose); /** * Process and generate response to received get software version control message * @param sock connection handle used for sending response * @param daemon pointer to dlt daemon structure * @param daemon_local pointer to dlt daemon local structure * @param verbose if set to true verbose information is printed out. */ void dlt_daemon_control_get_software_version(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose); /** * Process and generate response to received get default log level control message * @param sock connection handle used for sending response * @param daemon pointer to dlt daemon structure * @param daemon_local pointer to dlt daemon local structure * @param verbose if set to true verbose information is printed out. */ void dlt_daemon_control_get_default_log_level(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose); /** * Process and generate response to message buffer overflow control message * @param sock connection handle used for sending response * @param daemon pointer to dlt daemon structure * @param daemon_local pointer to dlt daemon local structure * @param overflow_counter Overflow counter * @param apid Application ID * @param verbose if set to true verbose information is printed out. * @return -1 if there is an error or buffer overflow, else 0 */ int dlt_daemon_control_message_buffer_overflow(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, unsigned int overflow_counter, char *apid, int verbose); /** * Generate response to control message from dlt client * @param sock connection handle used for sending response * @param daemon pointer to dlt daemon structure * @param daemon_local pointer to dlt daemon local structure * @param service_id service id of control message * @param status status of response (e.g. ok, not supported, error) * @param verbose if set to true verbose information is printed out. */ void dlt_daemon_control_service_response(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, uint32_t service_id, int8_t status, int verbose); /** * Send control message unregister context (add on to AUTOSAR standard) * @param sock connection handle used for sending response * @param daemon pointer to dlt daemon structure * @param daemon_local pointer to dlt daemon local structure * @param apid application id to be unregisteres * @param ctid context id to be unregistered * @param comid Communication id where apid is unregistered * @param verbose if set to true verbose information is printed out. */ int dlt_daemon_control_message_unregister_context(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, char *apid, char *ctid, char *comid, int verbose); /** * Send control message connection info (add on to AUTOSAR standard) * @param sock connection handle used for sending response * @param daemon pointer to dlt daemon structure * @param daemon_local pointer to dlt daemon local structure * @param state state of connection * @param comid Communication id where connection state changed * @param verbose if set to true verbose information is printed out. */ int dlt_daemon_control_message_connection_info(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, uint8_t state, char *comid, int verbose); /** * Send control message timezone (add on to AUTOSAR standard) * @param sock connection handle used for sending response * @param daemon pointer to dlt daemon structure * @param daemon_local pointer to dlt daemon local structure * @param verbose if set to true verbose information is printed out. */ int dlt_daemon_control_message_timezone(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose); /** * Send control message marker (add on to AUTOSAR standard) * @param sock connection handle used for sending response * @param daemon pointer to dlt daemon structure * @param daemon_local pointer to dlt daemon local structure * @param verbose if set to true verbose information is printed out. */ int dlt_daemon_control_message_marker(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose); /** * Process received control message from dlt client * @param sock connection handle used for sending response * @param daemon pointer to dlt daemon structure * @param daemon_local pointer to dlt daemon local structure * @param msg pointer to received control message * @param verbose if set to true verbose information is printed out. */ int dlt_daemon_client_process_control(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, DltMessage *msg, int verbose); /** * Process and generate response to received sw injection control message * @param sock connection handle used for sending response * @param daemon pointer to dlt daemon structure * @param daemon_local pointer to dlt daemon local structure * @param msg pointer to received sw injection control message * @param verbose if set to true verbose information is printed out. */ void dlt_daemon_control_callsw_cinjection(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, DltMessage *msg, int verbose); /** * Process and generate response to received set log level control message * @param sock connection handle used for sending response * @param daemon pointer to dlt daemon structure * @param daemon_local pointer to dlt daemon local structure * @param msg pointer to received control message * @param verbose if set to true verbose information is printed out. */ void dlt_daemon_control_set_log_level(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, DltMessage *msg, int verbose); /** * Process and generate response to received set trace status control message * @param sock connection handle used for sending response * @param daemon pointer to dlt daemon structure * @param daemon_local pointer to dlt daemon local structure * @param msg pointer to received control message * @param verbose if set to true verbose information is printed out. */ void dlt_daemon_control_set_trace_status(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, DltMessage *msg, int verbose); /** * Process and generate response to received set default log level control message * @param sock connection handle used for sending response * @param daemon pointer to dlt daemon structure * @param daemon_local pointer to dlt daemon local structure * @param msg pointer to received control message * @param verbose if set to true verbose information is printed out. */ void dlt_daemon_control_set_default_log_level(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, DltMessage *msg, int verbose); /** * Process and generate response to received set all log level control message * @param sock connection handle used for sending response * @param daemon pointer to dlt daemon structure * @param daemon_local pointer to dlt daemon local structure * @param msg pointer to received control message * @param verbose if set to true verbose information is printed out. */ void dlt_daemon_control_set_all_log_level(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, DltMessage *msg, int verbose); /** * Process and generate response to received set default trace status control message * @param sock connection handle used for sending response * @param daemon pointer to dlt daemon structure * @param daemon_local pointer to dlt daemon local structure * @param msg pointer to received control message * @param verbose if set to true verbose information is printed out. */ void dlt_daemon_control_set_default_trace_status(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, DltMessage *msg, int verbose); /** * Process and generate response to received set all trace status control message * @param sock connection handle used for sending response * @param daemon pointer to dlt daemon structure * @param daemon_local pointer to dlt daemon local structure * @param msg pointer to received control message * @param verbose if set to true verbose information is printed out. */ void dlt_daemon_control_set_all_trace_status(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, DltMessage *msg, int verbose); /** * Process and generate response to set timing packets control message * @param sock connection handle used for sending response * @param daemon pointer to dlt daemon structure * @param daemon_local pointer to dlt daemon local structure * @param msg pointer to received control message * @param verbose if set to true verbose information is printed out. */ void dlt_daemon_control_set_timing_packets(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, DltMessage *msg, int verbose); /** * Send time control message * @param sock connection handle used for sending response * @param daemon pointer to dlt daemon structure * @param daemon_local pointer to dlt daemon local structure * @param verbose if set to true verbose information is printed out. */ void dlt_daemon_control_message_time(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose); /** * Service offline logstorage command request * @param sock connection handle used for sending response * @param daemon pointer to dlt daemon structure * @param daemon_local pointer to dlt daemon local structure * @param msg pointer to received control message * @param verbose if set to true verbose information is printed out. */ void dlt_daemon_control_service_logstorage(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, DltMessage *msg, int verbose); /** * Process and generate response to received passive node connect control * message * @param sock connection handle used for sending response * @param daemon pointer to dlt daemon structure * @param daemon_local pointer to dlt daemon local structure * @param msg pointer to received control message * @param verbose if set to true verbose information is printed out. */ void dlt_daemon_control_passive_node_connect(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, DltMessage *msg, int verbose); /** * Process and generate response to received passive node connection status * control message * @param sock connection handle used for sending response * @param daemon pointer to dlt daemon structure * @param daemon_local pointer to dlt daemon local structure * @param verbose if set to true verbose information is printed out. */ void dlt_daemon_control_passive_node_connect_status(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose); #endif /* DLT_DAEMON_CLIENT_H */ dlt-daemon-2.18.4/src/daemon/dlt_daemon_common.c000066400000000000000000001521111353342203500215070ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2011-2015, BMW AG * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author Alexander Wenzel * * \copyright Copyright © 2011-2015 BMW AG. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file dlt_daemon_common.c */ /******************************************************************************* ** ** ** SRC-MODULE: dlt_daemon_common.c ** ** ** ** TARGET : linux ** ** ** ** PROJECT : DLT ** ** ** ** AUTHOR : Alexander Wenzel Alexander.AW.Wenzel@bmw.de ** ** Markus Klein ** ** ** ** PURPOSE : ** ** ** ** REMARKS : ** ** ** ** PLATFORM DEPENDANT [yes/no]: yes ** ** ** ** TO BE CHANGED BY USER [yes/no]: no ** ** ** *******************************************************************************/ /******************************************************************************* ** Author Identity ** ******************************************************************************** ** ** ** Initials Name Company ** ** -------- ------------------------- ---------------------------------- ** ** aw Alexander Wenzel BMW ** ** mk Markus Klein Fraunhofer ESK ** *******************************************************************************/ /******************************************************************************* ** Revision Control History ** *******************************************************************************/ /* * $LastChangedRevision: 1670 $ * $LastChangedDate: 2011-04-08 15:12:06 +0200 (Fr, 08. Apr 2011) $ * $LastChangedBy$ * Initials Date Comment * aw 13.01.2010 initial */ #include #include #include #include #include #include #include #include /* send() */ #include /* send() */ #include "dlt_types.h" #include "dlt_daemon_common.h" #include "dlt_daemon_common_cfg.h" #include "dlt_user_shared.h" #include "dlt_user_shared_cfg.h" #include "dlt-daemon.h" #include "dlt_daemon_socket.h" #include "dlt_daemon_serial.h" char *app_recv_buffer = NULL; /* pointer to receiver buffer for application msges */ sem_t dlt_daemon_mutex; static int dlt_daemon_cmp_apid(const void *m1, const void *m2) { if ((m1 == NULL) || (m2 == NULL)) return -1; DltDaemonApplication *mi1 = (DltDaemonApplication *)m1; DltDaemonApplication *mi2 = (DltDaemonApplication *)m2; return memcmp(mi1->apid, mi2->apid, DLT_ID_SIZE); } static int dlt_daemon_cmp_apid_ctid(const void *m1, const void *m2) { if ((m1 == NULL) || (m2 == NULL)) return -1; int ret, cmp; DltDaemonContext *mi1 = (DltDaemonContext *)m1; DltDaemonContext *mi2 = (DltDaemonContext *)m2; cmp = memcmp(mi1->apid, mi2->apid, DLT_ID_SIZE); if (cmp < 0) ret = -1; else if (cmp == 0) ret = memcmp(mi1->ctid, mi2->ctid, DLT_ID_SIZE); else ret = 1; return ret; } DltDaemonRegisteredUsers *dlt_daemon_find_users_list(DltDaemon *daemon, char *ecu, int verbose) { PRINT_FUNCTION_VERBOSE(verbose); int i = 0; if ((daemon == NULL) || (ecu == NULL)) { dlt_vlog(LOG_ERR, "%s: Wrong parameters", __func__); return (DltDaemonRegisteredUsers *)NULL; } for (i = 0; i < daemon->num_user_lists; i++) if (strncmp(ecu, daemon->user_list[i].ecu, DLT_ID_SIZE) == 0) return &daemon->user_list[i]; dlt_vlog(LOG_ERR, "Cannot find user list for ECU: %4s\n", ecu); return (DltDaemonRegisteredUsers *)NULL; } int dlt_daemon_load_runtime_configuration(DltDaemon *daemon, const char *runtime_directory, int verbose) { int append_length = 0; if ((daemon == NULL) || (runtime_directory == NULL)) return DLT_RETURN_ERROR; /* prepare filenames for configuration */ append_length = PATH_MAX - sizeof(DLT_RUNTIME_APPLICATION_CFG); if (runtime_directory[0]) { strncpy(daemon->runtime_application_cfg, runtime_directory, append_length); daemon->runtime_application_cfg[append_length] = 0; } else { strncpy(daemon->runtime_application_cfg, DLT_RUNTIME_DEFAULT_DIRECTORY, append_length); daemon->runtime_application_cfg[append_length] = 0; } strcat(daemon->runtime_application_cfg, DLT_RUNTIME_APPLICATION_CFG); /* strcat uncritical here, because max length already checked */ append_length = PATH_MAX - sizeof(DLT_RUNTIME_CONTEXT_CFG); if (runtime_directory[0]) { strncpy(daemon->runtime_context_cfg, runtime_directory, append_length); daemon->runtime_context_cfg[append_length] = 0; } else { strncpy(daemon->runtime_context_cfg, DLT_RUNTIME_DEFAULT_DIRECTORY, append_length); daemon->runtime_context_cfg[append_length] = 0; } strcat(daemon->runtime_context_cfg, DLT_RUNTIME_CONTEXT_CFG); /* strcat uncritical here, because max length already checked */ append_length = PATH_MAX - sizeof(DLT_RUNTIME_CONFIGURATION); if (runtime_directory[0]) { strncpy(daemon->runtime_configuration, runtime_directory, append_length); daemon->runtime_configuration[append_length] = 0; } else { strncpy(daemon->runtime_configuration, DLT_RUNTIME_DEFAULT_DIRECTORY, append_length); daemon->runtime_configuration[append_length] = 0; } strcat(daemon->runtime_configuration, DLT_RUNTIME_CONFIGURATION); /* strcat uncritical here, because max length already checked */ /* Check for runtime cfg, if it is loadable, load it! */ if ((dlt_daemon_applications_load(daemon, daemon->runtime_application_cfg, verbose) == 0) && (dlt_daemon_contexts_load(daemon, daemon->runtime_context_cfg, verbose) == 0)) daemon->runtime_context_cfg_loaded = 1; /* load configuration if available */ dlt_daemon_configuration_load(daemon, daemon->runtime_configuration, verbose); return DLT_RETURN_OK; } int dlt_daemon_init(DltDaemon *daemon, unsigned long RingbufferMinSize, unsigned long RingbufferMaxSize, unsigned long RingbufferStepSize, const char *runtime_directory, int InitialContextLogLevel, int InitialContextTraceStatus, int ForceLLTS, int verbose) { PRINT_FUNCTION_VERBOSE(verbose); if ((daemon == NULL) || (runtime_directory == NULL)) return -1; daemon->user_list = NULL; daemon->num_user_lists = 0; daemon->default_log_level = InitialContextLogLevel; daemon->default_trace_status = InitialContextTraceStatus; daemon->force_ll_ts = ForceLLTS; daemon->overflow_counter = 0; daemon->runtime_context_cfg_loaded = 0; daemon->mode = DLT_USER_MODE_EXTERNAL; daemon->connectionState = 0; /* no logger connected */ daemon->state = DLT_DAEMON_STATE_INIT; /* initial logging state */ daemon->sendserialheader = 0; daemon->timingpackets = 0; dlt_set_id(daemon->ecuid, ""); /* initialize ring buffer for client connection */ dlt_vlog(LOG_INFO, "Ringbuffer configuration: %lu/%lu/%lu\n", RingbufferMinSize, RingbufferMaxSize, RingbufferStepSize); if (dlt_buffer_init_dynamic(&(daemon->client_ringbuffer), RingbufferMinSize, RingbufferMaxSize, RingbufferStepSize) == DLT_RETURN_ERROR) return -1; daemon->storage_handle = NULL; return 0; } int dlt_daemon_free(DltDaemon *daemon, int verbose) { int i = 0; DltDaemonRegisteredUsers *user_list = NULL; PRINT_FUNCTION_VERBOSE(verbose); if ((daemon == NULL) || (daemon->user_list == NULL)) return -1; /* free all registered user information */ for (i = 0; i < daemon->num_user_lists; i++) { user_list = &daemon->user_list[i]; if (user_list != NULL) { /* ignore return values */ dlt_daemon_contexts_clear(daemon, user_list->ecu, verbose); dlt_daemon_applications_clear(daemon, user_list->ecu, verbose); } } free(daemon->user_list); if (app_recv_buffer) free(app_recv_buffer); /* free ringbuffer */ dlt_buffer_free_dynamic(&(daemon->client_ringbuffer)); return 0; } int dlt_daemon_init_user_information(DltDaemon *daemon, DltGateway *gateway, int gateway_mode, int verbose) { int nodes = 1; int i = 1; PRINT_FUNCTION_VERBOSE(verbose); if ((daemon == NULL) || ((gateway_mode == 1) && (gateway == NULL))) return DLT_RETURN_ERROR; if (gateway_mode == 0) { /* initialize application list */ daemon->user_list = calloc(nodes, sizeof(DltDaemonRegisteredUsers)); if (daemon->user_list == NULL) { dlt_log(LOG_ERR, "Allocating memory for user information"); return DLT_RETURN_ERROR; } dlt_set_id(daemon->user_list[0].ecu, daemon->ecuid); daemon->num_user_lists = 1; } else { /* gateway is active */ nodes += gateway->num_connections; /* initialize application list */ daemon->user_list = calloc(nodes, sizeof(DltDaemonRegisteredUsers)); if (daemon->user_list == NULL) { dlt_log(LOG_ERR, "Allocating memory for user information"); return DLT_RETURN_ERROR; } dlt_set_id(daemon->user_list[0].ecu, daemon->ecuid); daemon->num_user_lists = nodes; for (i = 1; i < nodes; i++) dlt_set_id(daemon->user_list[i].ecu, gateway->connections[i - 1].ecuid); } return DLT_RETURN_OK; } int dlt_daemon_applications_invalidate_fd(DltDaemon *daemon, char *ecu, int fd, int verbose) { int i; DltDaemonRegisteredUsers *user_list = NULL; PRINT_FUNCTION_VERBOSE(verbose); if ((daemon == NULL) || (ecu == NULL)) return DLT_RETURN_ERROR; user_list = dlt_daemon_find_users_list(daemon, ecu, verbose); if (user_list != NULL) { for (i = 0; i < user_list->num_applications; i++) if (user_list->applications[i].user_handle == fd) user_list->applications[i].user_handle = DLT_FD_INIT; return DLT_RETURN_OK; } return DLT_RETURN_ERROR; } int dlt_daemon_applications_clear(DltDaemon *daemon, char *ecu, int verbose) { int i; DltDaemonRegisteredUsers *user_list = NULL; PRINT_FUNCTION_VERBOSE(verbose); if ((daemon == NULL) || (daemon->user_list == NULL) || (ecu == NULL)) return DLT_RETURN_WRONG_PARAMETER; user_list = dlt_daemon_find_users_list(daemon, ecu, verbose); if (user_list == NULL) return DLT_RETURN_ERROR; for (i = 0; i < user_list->num_applications; i++) if (user_list->applications[i].application_description != NULL) { free(user_list->applications[i].application_description); user_list->applications[i].application_description = NULL; } if (user_list->applications != NULL) free(user_list->applications); user_list->applications = NULL; user_list->num_applications = 0; return 0; } DltDaemonApplication *dlt_daemon_application_add(DltDaemon *daemon, char *apid, pid_t pid, char *description, int fd, char *ecu, int verbose) { DltDaemonApplication *application; DltDaemonApplication *old; int new_application; int dlt_user_handle; DltDaemonRegisteredUsers *user_list = NULL; #ifndef DLT_USE_UNIX_SOCKET_IPC (void)fd; /* To avoid compiler warning : unused variable */ char filename[DLT_DAEMON_COMMON_TEXTBUFSIZE]; #endif if ((daemon == NULL) || (apid == NULL) || (apid[0] == '\0') || (ecu == NULL)) return (DltDaemonApplication *)NULL; user_list = dlt_daemon_find_users_list(daemon, ecu, verbose); if (user_list == NULL) return (DltDaemonApplication *)NULL; if (user_list->applications == NULL) { user_list->applications = (DltDaemonApplication *) malloc(sizeof(DltDaemonApplication) * DLT_DAEMON_APPL_ALLOC_SIZE); if (user_list->applications == NULL) return (DltDaemonApplication *)NULL; } new_application = 0; /* Check if application [apid] is already available */ application = dlt_daemon_application_find(daemon, apid, ecu, verbose); if (application == NULL) { user_list->num_applications += 1; if (user_list->num_applications != 0) { if ((user_list->num_applications % DLT_DAEMON_APPL_ALLOC_SIZE) == 0) { /* allocate memory in steps of DLT_DAEMON_APPL_ALLOC_SIZE, e.g. 100 */ old = user_list->applications; user_list->applications = (DltDaemonApplication *) malloc(sizeof(DltDaemonApplication) * ((user_list->num_applications / DLT_DAEMON_APPL_ALLOC_SIZE) + 1) * DLT_DAEMON_APPL_ALLOC_SIZE); if (user_list->applications == NULL) { user_list->applications = old; user_list->num_applications -= 1; return (DltDaemonApplication *)NULL; } memcpy(user_list->applications, old, sizeof(DltDaemonApplication) * user_list->num_applications); free(old); } } application = &(user_list->applications[user_list->num_applications - 1]); dlt_set_id(application->apid, apid); application->pid = 0; application->application_description = NULL; application->num_contexts = 0; application->user_handle = DLT_FD_INIT; new_application = 1; } else if ((pid != application->pid) && (application->pid != 0)) { dlt_vlog(LOG_WARNING, "Duplicate registration of ApplicationID: '%.4s'; registering from PID %d, existing from PID %d\n", apid, pid, application->pid); } /* Store application description and pid of application */ if (application->application_description) { free(application->application_description); application->application_description = NULL; } if (description != NULL) { application->application_description = malloc(strlen(description) + 1); if (application->application_description) { strncpy(application->application_description, description, strlen(description)); application->application_description[strlen(description)] = '\0'; } else { dlt_log(LOG_ERR, "Cannot allocate memory to store application description\n"); free(application); return (DltDaemonApplication *)NULL; } } if (application->user_handle != DLT_FD_INIT) { if (application->pid != pid) { #ifndef DLT_USE_UNIX_SOCKET_IPC if (close(application->user_handle) < 0) dlt_vlog(LOG_WARNING, "close() failed to %s/dltpipes/dlt%d, errno=%d (%s)!\n", dltFifoBaseDir, pid, errno, strerror(errno)); /* errno 2: ENOENT - No such file or directory */ #endif application->user_handle = DLT_FD_INIT; application->pid = 0; } } /* open user pipe only if it is not yet opened */ if ((application->user_handle == DLT_FD_INIT) && (pid != 0)) { #ifdef DLT_USE_UNIX_SOCKET_IPC dlt_user_handle = fd; #else snprintf(filename, DLT_DAEMON_COMMON_TEXTBUFSIZE, "%s/dltpipes/dlt%d", dltFifoBaseDir, pid); dlt_user_handle = open(filename, O_WRONLY | O_NONBLOCK); if (dlt_user_handle < 0) { int prio = (errno == ENOENT) ? LOG_INFO : LOG_WARNING; dlt_vlog(prio, "open() failed to %s, errno=%d (%s)!\n", filename, errno, strerror(errno)); } /* if */ #endif /* check if file descriptor was already used, and make it invalid if it * is reused. This prevents sending messages to wrong file descriptor */ dlt_daemon_applications_invalidate_fd(daemon, ecu, dlt_user_handle, verbose); dlt_daemon_contexts_invalidate_fd(daemon, ecu, dlt_user_handle, verbose); application->user_handle = dlt_user_handle; application->pid = pid; } /* Sort */ if (new_application) { qsort(user_list->applications, user_list->num_applications, sizeof(DltDaemonApplication), dlt_daemon_cmp_apid); /* Find new position of application with apid*/ application = dlt_daemon_application_find(daemon, apid, ecu, verbose); } return application; } int dlt_daemon_application_del(DltDaemon *daemon, DltDaemonApplication *application, char *ecu, int verbose) { int pos; DltDaemonRegisteredUsers *user_list = NULL; PRINT_FUNCTION_VERBOSE(verbose); if ((daemon == NULL) || (application == NULL) || (ecu == NULL)) return -1; user_list = dlt_daemon_find_users_list(daemon, ecu, verbose); if (user_list == NULL) return -1; if (user_list->num_applications > 0) { /* Check if user handle is open; if yes, close it */ if (application->user_handle >= DLT_FD_MINIMUM) { #ifndef DLT_USE_UNIX_SOCKET_IPC close(application->user_handle); #endif application->user_handle = DLT_FD_INIT; } /* Free description of application to be deleted */ if (application->application_description) { free(application->application_description); application->application_description = NULL; } pos = application - (user_list->applications); /* move all applications above pos to pos */ memmove(&(user_list->applications[pos]), &(user_list->applications[pos + 1]), sizeof(DltDaemonApplication) * ((user_list->num_applications - 1) - pos)); /* Clear last application */ memset(&(user_list->applications[user_list->num_applications - 1]), 0, sizeof(DltDaemonApplication)); user_list->num_applications--; } return 0; } DltDaemonApplication *dlt_daemon_application_find(DltDaemon *daemon, char *apid, char *ecu, int verbose) { DltDaemonApplication application; DltDaemonRegisteredUsers *user_list = NULL; PRINT_FUNCTION_VERBOSE(verbose); if ((daemon == NULL) || (daemon->user_list == NULL) || (apid == NULL) || (apid[0] == '\0') || (ecu == NULL)) return (DltDaemonApplication *)NULL; user_list = dlt_daemon_find_users_list(daemon, ecu, verbose); if ((user_list == NULL) || (user_list->num_applications == 0)) return (DltDaemonApplication *)NULL; /* Check, if apid is smaller than smallest apid or greater than greatest apid */ if ((memcmp(apid, user_list->applications[0].apid, DLT_ID_SIZE) < 0) || (memcmp(apid, user_list->applications[user_list->num_applications - 1].apid, DLT_ID_SIZE) > 0)) return (DltDaemonApplication *)NULL; dlt_set_id(application.apid, apid); return (DltDaemonApplication *)bsearch(&application, user_list->applications, user_list->num_applications, sizeof(DltDaemonApplication), dlt_daemon_cmp_apid); } int dlt_daemon_applications_load(DltDaemon *daemon, const char *filename, int verbose) { FILE *fd; ID4 apid; char buf[DLT_DAEMON_COMMON_TEXTBUFSIZE]; char *ret; char *pb; PRINT_FUNCTION_VERBOSE(verbose); if ((daemon == NULL) || (filename == NULL) || (filename[0] == '\0')) return -1; fd = fopen(filename, "r"); if (fd == NULL) { dlt_vlog(LOG_WARNING, "%s: cannot open file %s: %s\n", __func__, filename, strerror(errno)); return -1; } while (!feof(fd)) { /* Clear buf */ memset(buf, 0, sizeof(buf)); /* Get line */ ret = fgets(buf, sizeof(buf), fd); if (NULL == ret) { /* fgets always null pointer if the last byte of the file is a new line * We need to check here if there was an error or was it feof.*/ if (ferror(fd)) { dlt_vlog(LOG_WARNING, "%s: fgets(buf,sizeof(buf),fd) returned NULL. %s\n", __func__, strerror(errno)); fclose(fd); return -1; } else if (feof(fd)) { fclose(fd); return 0; } else { dlt_vlog(LOG_WARNING, "%s: fgets(buf,sizeof(buf),fd) returned NULL. Unknown error.\n", __func__); fclose(fd); return -1; } } if (strcmp(buf, "") != 0) { /* Split line */ pb = strtok(buf, ":"); if (pb != NULL) { dlt_set_id(apid, pb); pb = strtok(NULL, ":"); if (pb != NULL) { /* pb contains now the description */ /* pid is unknown at loading time */ if (dlt_daemon_application_add(daemon, apid, 0, pb, -1, daemon->ecuid, verbose) == 0) { dlt_vlog(LOG_WARNING, "%s: dlt_daemon_application_add failed for %4s\n", __func__, apid); fclose(fd); return -1; } } } } } fclose(fd); return 0; } int dlt_daemon_applications_save(DltDaemon *daemon, const char *filename, int verbose) { FILE *fd; int i; char apid[DLT_ID_SIZE + 1]; /* DLT_ID_SIZE+1, because the 0-termination is required here */ DltDaemonRegisteredUsers *user_list = NULL; PRINT_FUNCTION_VERBOSE(verbose); if ((daemon == NULL) || (filename == NULL) || (filename[0] == '\0')) return -1; memset(apid, 0, sizeof(apid)); user_list = dlt_daemon_find_users_list(daemon, daemon->ecuid, verbose); if (user_list == NULL) return -1; if ((user_list->applications != NULL) && (user_list->num_applications > 0)) { fd = fopen(filename, "w"); if (fd != NULL) { for (i = 0; i < user_list->num_applications; i++) { dlt_set_id(apid, user_list->applications[i].apid); if ((user_list->applications[i].application_description) && (user_list->applications[i].application_description[0] != '\0')) fprintf(fd, "%s:%s:\n", apid, user_list->applications[i].application_description); else fprintf(fd, "%s::\n", apid); } fclose(fd); } else { dlt_vlog(LOG_ERR, "%s: open %s failed! No application information stored.\n", __func__, filename); } } return 0; } DltDaemonContext *dlt_daemon_context_add(DltDaemon *daemon, char *apid, char *ctid, int8_t log_level, int8_t trace_status, int log_level_pos, int user_handle, char *description, char *ecu, int verbose) { DltDaemonApplication *application; DltDaemonContext *context; DltDaemonContext *old; int new_context = 0; DltDaemonRegisteredUsers *user_list = NULL; PRINT_FUNCTION_VERBOSE(verbose); if ((daemon == NULL) || (apid == NULL) || (apid[0] == '\0') || (ctid == NULL) || (ctid[0] == '\0') || (ecu == NULL)) return (DltDaemonContext *)NULL; if ((log_level < DLT_LOG_DEFAULT) || (log_level > DLT_LOG_VERBOSE)) return (DltDaemonContext *)NULL; if ((trace_status < DLT_TRACE_STATUS_DEFAULT) || (trace_status > DLT_TRACE_STATUS_ON)) return (DltDaemonContext *)NULL; user_list = dlt_daemon_find_users_list(daemon, ecu, verbose); if (user_list == NULL) return (DltDaemonContext *)NULL; if (user_list->contexts == NULL) { user_list->contexts = (DltDaemonContext *)malloc(sizeof(DltDaemonContext) * DLT_DAEMON_CONTEXT_ALLOC_SIZE); if (user_list->contexts == NULL) return (DltDaemonContext *)NULL; } /* Check if application [apid] is available */ application = dlt_daemon_application_find(daemon, apid, ecu, verbose); if (application == NULL) return (DltDaemonContext *)NULL; /* Check if context [apid, ctid] is already available */ context = dlt_daemon_context_find(daemon, apid, ctid, ecu, verbose); if (context == NULL) { user_list->num_contexts += 1; if (user_list->num_contexts != 0) { if ((user_list->num_contexts % DLT_DAEMON_CONTEXT_ALLOC_SIZE) == 0) { /* allocate memory for context in steps of DLT_DAEMON_CONTEXT_ALLOC_SIZE, e.g 100 */ old = user_list->contexts; user_list->contexts = (DltDaemonContext *)malloc(sizeof(DltDaemonContext) * ((user_list->num_contexts / DLT_DAEMON_CONTEXT_ALLOC_SIZE) + 1) * DLT_DAEMON_CONTEXT_ALLOC_SIZE); if (user_list->contexts == NULL) { user_list->contexts = old; user_list->num_contexts -= 1; return (DltDaemonContext *)NULL; } memcpy(user_list->contexts, old, sizeof(DltDaemonContext) * user_list->num_contexts); free(old); } } context = &(user_list->contexts[user_list->num_contexts - 1]); dlt_set_id(context->apid, apid); dlt_set_id(context->ctid, ctid); context->context_description = NULL; application->num_contexts++; new_context = 1; } /* Set context description */ if (context->context_description) { free(context->context_description); context->context_description = NULL; } if (description != NULL) { context->context_description = malloc(strlen(description) + 1); if (context->context_description) { strncpy(context->context_description, description, strlen(description)); context->context_description[strlen(description)] = '\0'; } } if ((strncmp(daemon->ecuid, ecu, DLT_ID_SIZE) == 0) && (daemon->force_ll_ts)) { if (log_level > daemon->default_log_level) log_level = daemon->default_log_level; if (trace_status > daemon->default_trace_status) trace_status = daemon->default_trace_status; dlt_vlog(LOG_NOTICE, "Adapting ll_ts for context: %.4s:%.4s with %i %i\n", apid, ctid, log_level, trace_status); } /* Store log level and trace status, * if this is a new context, or * if this is an old context and the runtime cfg was not loaded */ if ((new_context == 1) || ((new_context == 0) && (daemon->runtime_context_cfg_loaded == 0))) { context->log_level = log_level; context->trace_status = trace_status; } context->log_level_pos = log_level_pos; context->user_handle = user_handle; /* In case a context is loaded from runtime config file, * the user_handle is 0 and we mark that context as predefined. */ if (context->user_handle == 0) context->predefined = true; else context->predefined = false; /* Sort */ if (new_context) { qsort(user_list->contexts, user_list->num_contexts, sizeof(DltDaemonContext), dlt_daemon_cmp_apid_ctid); /* Find new position of context with apid, ctid */ context = dlt_daemon_context_find(daemon, apid, ctid, ecu, verbose); } return context; } int dlt_daemon_context_del(DltDaemon *daemon, DltDaemonContext *context, char *ecu, int verbose) { int pos; DltDaemonApplication *application; DltDaemonRegisteredUsers *user_list = NULL; PRINT_FUNCTION_VERBOSE(verbose); if ((daemon == NULL) || (context == NULL) || (ecu == NULL)) return -1; user_list = dlt_daemon_find_users_list(daemon, ecu, verbose); if (user_list == NULL) return -1; if (user_list->num_contexts > 0) { application = dlt_daemon_application_find(daemon, context->apid, ecu, verbose); /* Free description of context to be deleted */ if (context->context_description) { free(context->context_description); context->context_description = NULL; } pos = context - (user_list->contexts); /* move all contexts above pos to pos */ memmove(&(user_list->contexts[pos]), &(user_list->contexts[pos + 1]), sizeof(DltDaemonContext) * ((user_list->num_contexts - 1) - pos)); /* Clear last context */ memset(&(user_list->contexts[user_list->num_contexts - 1]), 0, sizeof(DltDaemonContext)); user_list->num_contexts--; /* Check if application [apid] is available */ if (application != NULL) application->num_contexts--; } return 0; } DltDaemonContext *dlt_daemon_context_find(DltDaemon *daemon, char *apid, char *ctid, char *ecu, int verbose) { DltDaemonContext context; DltDaemonRegisteredUsers *user_list = NULL; PRINT_FUNCTION_VERBOSE(verbose); if ((daemon == NULL) || (apid == NULL) || (apid[0] == '\0') || (ctid == NULL) || (ctid[0] == '\0') || (ecu == NULL)) return (DltDaemonContext *)NULL; user_list = dlt_daemon_find_users_list(daemon, ecu, verbose); if ((user_list == NULL) || (user_list->num_contexts == 0)) return (DltDaemonContext *)NULL; /* Check, if apid is smaller than smallest apid or greater than greatest apid */ if ((memcmp(apid, user_list->contexts[0].apid, DLT_ID_SIZE) < 0) || (memcmp(apid, user_list->contexts[user_list->num_contexts - 1].apid, DLT_ID_SIZE) > 0)) return (DltDaemonContext *)NULL; dlt_set_id(context.apid, apid); dlt_set_id(context.ctid, ctid); return (DltDaemonContext *)bsearch(&context, user_list->contexts, user_list->num_contexts, sizeof(DltDaemonContext), dlt_daemon_cmp_apid_ctid); } int dlt_daemon_contexts_invalidate_fd(DltDaemon *daemon, char *ecu, int fd, int verbose) { int i; DltDaemonRegisteredUsers *user_list = NULL; PRINT_FUNCTION_VERBOSE(verbose); if ((daemon == NULL) || (ecu == NULL)) return -1; user_list = dlt_daemon_find_users_list(daemon, ecu, verbose); if (user_list != NULL) { for (i = 0; i < user_list->num_contexts; i++) if (user_list->contexts[i].user_handle == fd) user_list->contexts[i].user_handle = DLT_FD_INIT; return 0; } return -1; } int dlt_daemon_contexts_clear(DltDaemon *daemon, char *ecu, int verbose) { int i; DltDaemonRegisteredUsers *users = NULL; PRINT_FUNCTION_VERBOSE(verbose); if ((daemon == NULL) || (ecu == NULL)) return DLT_RETURN_WRONG_PARAMETER; users = dlt_daemon_find_users_list(daemon, ecu, verbose); if (users == NULL) return DLT_RETURN_ERROR; for (i = 0; i < users->num_contexts; i++) if (users->contexts[i].context_description != NULL) { free(users->contexts[i].context_description); users->contexts[i].context_description = NULL; } if (users->contexts) { free(users->contexts); users->contexts = NULL; } for (i = 0; i < users->num_applications; i++) users->applications[i].num_contexts = 0; users->num_contexts = 0; return 0; } int dlt_daemon_contexts_load(DltDaemon *daemon, const char *filename, int verbose) { FILE *fd; ID4 apid, ctid; char buf[DLT_DAEMON_COMMON_TEXTBUFSIZE]; char *ret; char *pb; int ll, ts; PRINT_FUNCTION_VERBOSE(verbose); if ((daemon == NULL) || (filename == NULL) || (filename[0] == '\0')) return -1; fd = fopen(filename, "r"); if (fd == NULL) { dlt_vlog(LOG_WARNING, "DLT runtime-context load, cannot open file %s: %s\n", filename, strerror(errno)); return -1; } while (!feof(fd)) { /* Clear buf */ memset(buf, 0, sizeof(buf)); /* Get line */ ret = fgets(buf, sizeof(buf), fd); if (NULL == ret) { /* fgets always returns null pointer if the last byte of the file is a new line. * We need to check here if there was an error or was it feof.*/ if (ferror(fd)) { dlt_vlog(LOG_WARNING, "%s fgets(buf,sizeof(buf),fd) returned NULL. %s\n", __func__, strerror(errno)); fclose(fd); return -1; } else if (feof(fd)) { fclose(fd); return 0; } else { dlt_vlog(LOG_WARNING, "%s fgets(buf,sizeof(buf),fd) returned NULL. Unknown error.\n", __func__); fclose(fd); return -1; } } if (strcmp(buf, "") != 0) { /* Split line */ pb = strtok(buf, ":"); if (pb != NULL) { dlt_set_id(apid, pb); pb = strtok(NULL, ":"); if (pb != NULL) { dlt_set_id(ctid, pb); pb = strtok(NULL, ":"); if (pb != NULL) { sscanf(pb, "%d", &ll); pb = strtok(NULL, ":"); if (pb != NULL) { sscanf(pb, "%d", &ts); pb = strtok(NULL, ":"); if (pb != NULL) { /* pb contains now the description */ /* log_level_pos, and user_handle are unknown at loading time */ if (dlt_daemon_context_add(daemon, apid, ctid, (int8_t)ll, (int8_t)ts, 0, 0, pb, daemon->ecuid, verbose) == NULL) { dlt_vlog(LOG_WARNING, "%s dlt_daemon_context_add failed\n", __func__); fclose(fd); return -1; } } } } } } } } fclose(fd); return 0; } int dlt_daemon_contexts_save(DltDaemon *daemon, const char *filename, int verbose) { FILE *fd; int i; char apid[DLT_ID_SIZE + 1], ctid[DLT_ID_SIZE + 1]; /* DLT_ID_SIZE+1, because the 0-termination is required here */ DltDaemonRegisteredUsers *user_list = NULL; PRINT_FUNCTION_VERBOSE(verbose); if ((daemon == NULL) || (filename == NULL) || (filename[0] == '\0')) return -1; user_list = dlt_daemon_find_users_list(daemon, daemon->ecuid, verbose); if (user_list == NULL) return -1; memset(apid, 0, sizeof(apid)); memset(ctid, 0, sizeof(ctid)); if ((user_list->contexts) && (user_list->num_contexts > 0)) { fd = fopen(filename, "w"); if (fd != NULL) { for (i = 0; i < user_list->num_contexts; i++) { dlt_set_id(apid, user_list->contexts[i].apid); dlt_set_id(ctid, user_list->contexts[i].ctid); if ((user_list->contexts[i].context_description) && (user_list->contexts[i].context_description[0] != '\0')) fprintf(fd, "%s:%s:%d:%d:%s:\n", apid, ctid, (int)(user_list->contexts[i].log_level), (int)(user_list->contexts[i].trace_status), user_list->contexts[i].context_description); else fprintf(fd, "%s:%s:%d:%d::\n", apid, ctid, (int)(user_list->contexts[i].log_level), (int)(user_list->contexts[i].trace_status)); } fclose(fd); } else { dlt_vlog(LOG_ERR, "%s: Cannot open %s. No context information stored\n", __func__, filename); } } return 0; } int dlt_daemon_configuration_save(DltDaemon *daemon, const char *filename, int verbose) { FILE *fd; PRINT_FUNCTION_VERBOSE(verbose); if ((daemon == NULL) || (filename == NULL) || (filename[0] == '\0')) return -1; fd = fopen(filename, "w"); if (fd != NULL) { fprintf(fd, "# 0 = off, 1 = external, 2 = internal, 3 = both\n"); fprintf(fd, "LoggingMode = %d\n", daemon->mode); fclose(fd); } return 0; } int dlt_daemon_configuration_load(DltDaemon *daemon, const char *filename, int verbose) { if ((daemon == NULL) || (filename == NULL)) return -1; FILE *pFile; char line[1024]; char token[1024]; char value[1024]; char *pch; PRINT_FUNCTION_VERBOSE(verbose); pFile = fopen (filename, "r"); if (pFile != NULL) { while (1) { /* fetch line from configuration file */ if (fgets (line, 1024, pFile) != NULL) { pch = strtok (line, " =\r\n"); token[0] = 0; value[0] = 0; while (pch != NULL) { if (strcmp(pch, "#") == 0) break; if (token[0] == 0) { strncpy(token, pch, sizeof(token) - 1); token[sizeof(token) - 1] = 0; } else { strncpy(value, pch, sizeof(value) - 1); value[sizeof(value) - 1] = 0; break; } pch = strtok (NULL, " =\r\n"); } if (token[0] && value[0]) { /* parse arguments here */ if (strcmp(token, "LoggingMode") == 0) { daemon->mode = atoi(value); dlt_vlog(LOG_INFO, "Runtime Option: %s=%d\n", token, daemon->mode); } else { dlt_vlog(LOG_WARNING, "Unknown option: %s=%s\n", token, value); } } } else { break; } } fclose (pFile); } else { dlt_vlog(LOG_INFO, "Cannot open configuration file: %s\n", filename); } return 0; } int dlt_daemon_user_send_log_level(DltDaemon *daemon, DltDaemonContext *context, int verbose) { DltUserHeader userheader; DltUserControlMsgLogLevel usercontext; DltReturnValue ret; PRINT_FUNCTION_VERBOSE(verbose); if ((daemon == NULL) || (context == NULL)) { dlt_vlog(LOG_ERR, "NULL parameter in %s", __func__); return -1; } if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_LOG_LEVEL) < DLT_RETURN_OK) { dlt_vlog(LOG_ERR, "Failed to set userheader in %s", __func__); return -1; } if (context->storage_log_level != DLT_LOG_DEFAULT) usercontext.log_level = context->log_level > context->storage_log_level ? context->log_level : context->storage_log_level; else /* Storage log level is not updated (is DEFAULT) then no device is yet connected so ignore */ usercontext.log_level = ((context->log_level == DLT_LOG_DEFAULT) ? daemon->default_log_level : context->log_level); usercontext.trace_status = ((context->trace_status == DLT_TRACE_STATUS_DEFAULT) ? daemon->default_trace_status : context->trace_status); usercontext.log_level_pos = context->log_level_pos; dlt_vlog(LOG_NOTICE, "Send log-level to context: %.4s:%.4s [%i -> %i] [%i -> %i]\n", context->apid, context->ctid, context->log_level, usercontext.log_level, context->trace_status, usercontext.trace_status); /* log to FIFO */ errno = 0; ret = dlt_user_log_out2(context->user_handle, &(userheader), sizeof(DltUserHeader), &(usercontext), sizeof(DltUserControlMsgLogLevel)); if (ret < DLT_RETURN_OK) { dlt_vlog(LOG_ERR, "Failed to send data to application in %s: %s", __func__, errno != 0 ? strerror(errno) : "Unknown error"); if (errno == EPIPE) { #ifndef DLT_USE_UNIX_SOCKET_IPC /* Close connection */ close(context->user_handle); #endif context->user_handle = DLT_FD_INIT; } } return (ret == DLT_RETURN_OK) ? DLT_RETURN_OK : DLT_RETURN_ERROR; } int dlt_daemon_user_send_log_state(DltDaemon *daemon, DltDaemonApplication *app, int verbose) { DltUserHeader userheader; DltUserControlMsgLogState logstate; DltReturnValue ret; PRINT_FUNCTION_VERBOSE(verbose); if ((daemon == NULL) || (app == NULL)) return -1; if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_LOG_STATE) < DLT_RETURN_OK) return -1; logstate.log_state = daemon->connectionState; /* log to FIFO */ ret = dlt_user_log_out2(app->user_handle, &(userheader), sizeof(DltUserHeader), &(logstate), sizeof(DltUserControlMsgLogState)); if (ret < DLT_RETURN_OK) { if (errno == EPIPE) { #ifndef DLT_USE_UNIX_SOCKET_IPC /* Close connection */ close(app->user_handle); #endif app->user_handle = DLT_FD_INIT; } } return (ret == DLT_RETURN_OK) ? DLT_RETURN_OK : DLT_RETURN_ERROR; } void dlt_daemon_control_reset_to_factory_default(DltDaemon *daemon, const char *filename, const char *filename1, int InitialContextLogLevel, int InitialContextTraceStatus, int InitialEnforceLlTsStatus, int verbose) { FILE *fd; PRINT_FUNCTION_VERBOSE(verbose); if ((daemon == NULL) || (filename == NULL) || (filename1 == NULL)) { dlt_log(LOG_WARNING, "Wrong parameter: Null pointer\n"); return; } if ((filename[0] == '\0') || (filename1[0] == '\0')) { dlt_log(LOG_WARNING, "Wrong parameter: Empty string\n"); return; } /* Check for runtime cfg file and delete it, if available */ fd = fopen(filename, "r"); if (fd != NULL) { /* Close and delete file */ fclose(fd); unlink(filename); } fd = fopen(filename1, "r"); if (fd != NULL) { /* Close and delete file */ fclose(fd); unlink(filename1); } daemon->default_log_level = InitialContextLogLevel; daemon->default_trace_status = InitialContextTraceStatus; daemon->force_ll_ts = InitialEnforceLlTsStatus; /* Reset all other things (log level, trace status, etc. * to default values */ /* Inform user libraries about changed default log level/trace status */ dlt_daemon_user_send_default_update(daemon, verbose); } void dlt_daemon_user_send_default_update(DltDaemon *daemon, int verbose) { int32_t count; DltDaemonContext *context; DltDaemonRegisteredUsers *user_list = NULL; PRINT_FUNCTION_VERBOSE(verbose); if (daemon == NULL) { dlt_log(LOG_WARNING, "Wrong parameter: Null pointer\n"); return; } user_list = dlt_daemon_find_users_list(daemon, daemon->ecuid, verbose); if (user_list == NULL) return; for (count = 0; count < user_list->num_contexts; count++) { context = &(user_list->contexts[count]); if (context != NULL) { if ((context->log_level == DLT_LOG_DEFAULT) || (context->trace_status == DLT_TRACE_STATUS_DEFAULT)) { if (context->user_handle >= DLT_FD_MINIMUM) { if (dlt_daemon_user_send_log_level(daemon, context, verbose) == -1) dlt_vlog(LOG_WARNING, "Cannot update default of %.4s:%.4s\n", context->apid, context->ctid); } } } } } void dlt_daemon_user_send_all_log_level_update(DltDaemon *daemon, int8_t log_level, int verbose) { int32_t count = 0; DltDaemonContext *context = NULL; DltDaemonRegisteredUsers *user_list = NULL; PRINT_FUNCTION_VERBOSE(verbose); if (daemon == NULL) return; user_list = dlt_daemon_find_users_list(daemon, daemon->ecuid, verbose); if (user_list == NULL) return; for (count = 0; count < user_list->num_contexts; count++) { context = &(user_list->contexts[count]); if (context) { if (context->user_handle >= DLT_FD_MINIMUM) { context->log_level = log_level; if (dlt_daemon_user_send_log_level(daemon, context, verbose) == -1) dlt_vlog(LOG_WARNING, "Cannot send log level %.4s:%.4s -> %i\n", context->apid, context->ctid, context->log_level); } } } } void dlt_daemon_user_send_all_trace_status_update(DltDaemon *daemon, int8_t trace_status, int verbose) { int32_t count = 0; DltDaemonContext *context = NULL; DltDaemonRegisteredUsers *user_list = NULL; PRINT_FUNCTION_VERBOSE(verbose); if (daemon == NULL) return; user_list = dlt_daemon_find_users_list(daemon, daemon->ecuid, verbose); if (user_list == NULL) return; dlt_vlog(LOG_NOTICE, "All trace status is updated -> %i\n", trace_status); for (count = 0; count < user_list->num_contexts; count++) { context = &(user_list->contexts[count]); if (context) { if (context->user_handle >= DLT_FD_MINIMUM) { context->trace_status = trace_status; if (dlt_daemon_user_send_log_level(daemon, context, verbose) == -1) dlt_vlog(LOG_WARNING, "Cannot send trace status %.4s:%.4s -> %i\n", context->apid, context->ctid, context->trace_status); } } } } void dlt_daemon_user_send_all_log_state(DltDaemon *daemon, int verbose) { int32_t count; DltDaemonApplication *app; DltDaemonRegisteredUsers *user_list = NULL; PRINT_FUNCTION_VERBOSE(verbose); if (daemon == NULL) { dlt_log(LOG_WARNING, "Wrong parameter: Null pointer\n"); return; } user_list = dlt_daemon_find_users_list(daemon, daemon->ecuid, verbose); if (user_list == NULL) return; for (count = 0; count < user_list->num_applications; count++) { app = &(user_list->applications[count]); if (app != NULL) { if (app->user_handle >= DLT_FD_MINIMUM) { if (dlt_daemon_user_send_log_state(daemon, app, verbose) == -1) dlt_vlog(LOG_WARNING, "Cannot send log state to Apid: %.4s, PID: %d\n", app->apid, app->pid); } } } } void dlt_daemon_change_state(DltDaemon *daemon, DltDaemonState newState) { switch (newState) { case DLT_DAEMON_STATE_INIT: dlt_log(LOG_INFO, "Switched to init state.\n"); daemon->state = DLT_DAEMON_STATE_INIT; break; case DLT_DAEMON_STATE_BUFFER: dlt_log(LOG_INFO, "Switched to buffer state for socket connections.\n"); daemon->state = DLT_DAEMON_STATE_BUFFER; break; case DLT_DAEMON_STATE_BUFFER_FULL: dlt_log(LOG_INFO, "Switched to buffer full state.\n"); daemon->state = DLT_DAEMON_STATE_BUFFER_FULL; break; case DLT_DAEMON_STATE_SEND_BUFFER: dlt_log(LOG_INFO, "Switched to send buffer state for socket connections.\n"); daemon->state = DLT_DAEMON_STATE_SEND_BUFFER; break; case DLT_DAEMON_STATE_SEND_DIRECT: dlt_log(LOG_INFO, "Switched to send direct state.\n"); daemon->state = DLT_DAEMON_STATE_SEND_DIRECT; break; } } dlt-daemon-2.18.4/src/daemon/dlt_daemon_common.h000066400000000000000000000576771353342203500215410ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2011-2015, BMW AG * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author Alexander Wenzel * * \copyright Copyright © 2011-2015 BMW AG. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file dlt_daemon_common.h */ /******************************************************************************* ** ** ** SRC-MODULE: dlt_daemon_common.h ** ** ** ** TARGET : linux ** ** ** ** PROJECT : DLT ** ** ** ** AUTHOR : Alexander Wenzel Alexander.AW.Wenzel@bmw.de ** ** Markus Klein ** ** ** ** PURPOSE : ** ** ** ** REMARKS : ** ** ** ** PLATFORM DEPENDANT [yes/no]: yes ** ** ** ** TO BE CHANGED BY USER [yes/no]: no ** ** ** *******************************************************************************/ /******************************************************************************* ** Author Identity ** ******************************************************************************** ** ** ** Initials Name Company ** ** -------- ------------------------- ---------------------------------- ** ** aw Alexander Wenzel BMW ** ** mk Markus Klein Fraunhofer ESK ** *******************************************************************************/ /******************************************************************************* ** Revision Control History ** *******************************************************************************/ /* * $LastChangedRevision: 1670 $ * $LastChangedDate: 2011-04-08 15:12:06 +0200 (Fr, 08. Apr 2011) $ * $LastChangedBy$ * Initials Date Comment * aw 15.02.2010 initial */ #ifndef DLT_DAEMON_COMMON_H # define DLT_DAEMON_COMMON_H /** * \defgroup daemonapi DLT Daemon API * \addtogroup daemonapi \{ */ # include # include # include # include "dlt_common.h" # include "dlt_user.h" # include "dlt_offline_logstorage.h" # include "dlt_gateway_types.h" # ifdef __cplusplus extern "C" { # endif # define DLT_DAEMON_RINGBUFFER_MIN_SIZE 500000/**< Ring buffer size for storing log messages while no client is connected */ # define DLT_DAEMON_RINGBUFFER_MAX_SIZE 10000000/**< Ring buffer size for storing log messages while no client is connected */ # define DLT_DAEMON_RINGBUFFER_STEP_SIZE 500000/**< Ring buffer size for storing log messages while no client is connected */ # define DLT_DAEMON_SEND_TO_ALL -3/**< Constant value to identify the command "send to all" */ # define DLT_DAEMON_SEND_FORCE -4/**< Constant value to identify the command "send force to all" */ /* Use a semaphore or mutex from your OS to prevent concurrent access to the DLT buffer. */ #define DLT_DAEMON_SEM_LOCK() do{\ while ((sem_wait(&dlt_daemon_mutex) == -1) && (errno == EINTR)) \ continue; /* Restart if interrupted */ \ } while(0) #define DLT_DAEMON_SEM_FREE() { sem_post(&dlt_daemon_mutex); } extern sem_t dlt_daemon_mutex; /* UDPMulticart Default IP and Port */ # ifdef UDP_CONNECTION_SUPPORT # define MULTICASTIPADDRESS "225.0.0.37" # define MULTICASTIPPORT 3491 # define MULTICASTIP_MAX_SIZE 256 # define MULTICAST_CONNECTION_DISABLED 0 # define MULTICAST_CONNECTION_ENABLED 1 # endif /** * Definitions of DLT daemon logging states */ typedef enum { DLT_DAEMON_STATE_INIT = 0, /**< Initial state */ DLT_DAEMON_STATE_BUFFER = 1, /**< logging is buffered until external logger is connected or internal logging is activated */ DLT_DAEMON_STATE_BUFFER_FULL = 2, /**< then internal buffer is full, wait for connect from client */ DLT_DAEMON_STATE_SEND_BUFFER = 3, /**< external logger is connected, but buffer is still not empty or external logger queue is full */ DLT_DAEMON_STATE_SEND_DIRECT = 4 /**< External logger is connected or internal logging is active, and buffer is empty */ } DltDaemonState; /** * The parameters of a daemon application. */ typedef struct { char apid[DLT_ID_SIZE]; /**< application id */ pid_t pid; /**< process id of user application */ int user_handle; /**< connection handle for connection to user application */ char *application_description; /**< context description */ int num_contexts; /**< number of contexts for this application */ } DltDaemonApplication; /** * The parameters of a daemon context. */ typedef struct { char apid[DLT_ID_SIZE]; /**< application id */ char ctid[DLT_ID_SIZE]; /**< context id */ int8_t log_level; /**< the current log level of the context */ int8_t trace_status; /**< the current trace status of the context */ int log_level_pos; /**< offset of context in context field on user application */ int user_handle; /**< connection handle for connection to user application */ char *context_description; /**< context description */ int8_t storage_log_level; /**< log level set for offline logstorage */ bool predefined; /**< set to true if this context is predefined by runtime configuration file */ } DltDaemonContext; /* * The parameter of registered users list */ typedef struct { DltDaemonApplication *applications; /**< Pointer to applications */ int num_applications; /**< Number of available application */ DltDaemonContext *contexts; /**< Pointer to contexts */ int num_contexts; /**< Total number of all contexts in all applications in this list */ char ecu[DLT_ID_SIZE]; /**< ECU ID of where contexts are registered */ } DltDaemonRegisteredUsers; /** * The parameters of a daemon. */ typedef struct { DltDaemonRegisteredUsers *user_list; /**< registered users per ECU */ int num_user_lists; /** < number of context lists */ int8_t default_log_level; /**< Default log level (of daemon) */ int8_t default_trace_status; /**< Default trace status (of daemon) */ int8_t force_ll_ts; /**< Enforce ll and ts to not exceed default_log_level, default_trace_status */ unsigned int overflow_counter; /**< counts the number of lost messages. */ int runtime_context_cfg_loaded; /**< Set to one, if runtime context configuration has been loaded, zero otherwise */ char ecuid[DLT_ID_SIZE]; /**< ECU ID of daemon */ int sendserialheader; /**< 1: send serial header; 0 don't send serial header */ int timingpackets; /**< 1: send continous timing packets; 0 don't send continous timing packets */ DltBuffer client_ringbuffer; /**< Ring-buffer for storing received logs while no client connection is available */ char runtime_application_cfg[PATH_MAX + 1]; /**< Path and filename of persistent application configuration. Set to path max, as it specifies a full path*/ char runtime_context_cfg[PATH_MAX + 1]; /**< Path and filename of persistent context configuration */ char runtime_configuration[PATH_MAX + 1]; /**< Path and filename of persistent configuration */ DltUserLogMode mode; /**< Mode used for tracing: off, external, internal, both */ char connectionState; /**< state for tracing: 0 = no client connected, 1 = client connected */ char *ECUVersionString; /**< Version string to send to client. Loaded from a file at startup. May be null. */ DltDaemonState state; /**< the current logging state of dlt daemon. */ DltLogStorage *storage_handle; } DltDaemon; /** * Initialise the dlt daemon structure * This function must be called before using further dlt daemon structure * @param daemon pointer to dlt daemon structure * @param RingbufferMinSize ringbuffer size * @param RingbufferMaxSize ringbuffer size * @param RingbufferStepSize ringbuffer size * @param runtime_directory Directory of persistent configuration * @param InitialContextLogLevel loglevel to be sent to context when those register with loglevel default, read from dlt.conf * @param InitialContextTraceStatus tracestatus to be sent to context when those register with tracestatus default, read from dlt.conf * @param ForceLLTS force default log-level * @param verbose if set to true verbose information is printed out. * @return negative value if there was an error */ int dlt_daemon_init(DltDaemon *daemon, unsigned long RingbufferMinSize, unsigned long RingbufferMaxSize, unsigned long RingbufferStepSize, const char *runtime_directory, int InitialContextLogLevel, int InitialContextTraceStatus, int ForceLLTS, int verbose); /** * De-Initialise the dlt daemon structure * @param daemon pointer to dlt daemon structure * @param verbose if set to true verbose information is printed out. * @return negative value if there was an error */ int dlt_daemon_free(DltDaemon *daemon, int verbose); /** * Initialize data structures to store information about applications running on same * or passive node. * @param daemon pointer to dlt daemon structure * @param gateway pointer to dlt gateway structure * @param gateway_mode mode of dlt daemon, specified in dlt.conf * @param verbose if set to true verbose information is printed out * @return DLT_RETURN_OK on success, DLT_RETURN_ERROR otherwise */ int dlt_daemon_init_user_information(DltDaemon *daemon, DltGateway *gateway, int gateway_mode, int verbose); /** * Find information about application/contexts for a specific ECU * @param daemon pointer to dlt daemon structure * @param ecu pointer to node name * @param verbose if set to true verbose information is printed out * @return pointer to user list, NULL otherwise */ DltDaemonRegisteredUsers *dlt_daemon_find_users_list(DltDaemon *daemon, char *ecu, int verbose); /** * Loads the user saved configurations to daemon * @param daemon pointer to dlt daemon structure * @param runtime_directory directory path * @param verbose if set to true verbose information is printed out * @return DLT_RETURN_OK on success, DLT_RETURN_ERROR otherwise */ int dlt_daemon_load_runtime_configuration(DltDaemon *daemon, const char *runtime_directory, int verbose); /** * Add (new) application to internal application management * @param daemon pointer to dlt daemon structure * @param apid pointer to application id * @param pid process id of user application * @param description description of application * @param fd file descriptor of application * @param ecu pointer to ecu id of node to add applications * @param verbose if set to true verbose information is printed out. * @return Pointer to added context, null pointer on error */ DltDaemonApplication *dlt_daemon_application_add(DltDaemon *daemon, char *apid, pid_t pid, char *description, int fd, char *ecu, int verbose); /** * Delete application from internal application management * @param daemon pointer to dlt daemon structure * @param application pointer to application to be deleted * @param ecu pointer to ecu id of node to delete applications * @param verbose if set to true verbose information is printed out. * @return negative value if there was an error */ int dlt_daemon_application_del(DltDaemon *daemon, DltDaemonApplication *application, char *ecu, int verbose); /** * Find application with specific application id * @param daemon pointer to dlt daemon structure * @param apid pointer to application id * @param ecu pointer to ecu id of node to clear applications * @param verbose if set to true verbose information is printed out. * @return Pointer to application, null pointer on error or not found */ DltDaemonApplication *dlt_daemon_application_find(DltDaemon *daemon, char *apid, char *ecu, int verbose); /** * Load applications from file to internal context management * @param daemon pointer to dlt daemon structure * @param filename name of file to be used for loading * @param verbose if set to true verbose information is printed out. * @return negative value if there was an error */ int dlt_daemon_applications_load(DltDaemon *daemon, const char *filename, int verbose); /** * Save applications from internal context management to file * @param daemon pointer to dlt daemon structure * @param filename name of file to be used for saving * @param verbose if set to true verbose information is printed out. * @return negative value if there was an error */ int dlt_daemon_applications_save(DltDaemon *daemon, const char *filename, int verbose); /** * Invalidate all applications fd, if fd is reused * @param daemon pointer to dlt daemon structure * @param ecu node these applications running on. * @param fd file descriptor * @param verbose if set to true verbose information is printed out. * @return negative value if there was an error */ int dlt_daemon_applications_invalidate_fd(DltDaemon *daemon, char *ecu, int fd, int verbose); /** * Clear all applications in internal application management of specific ecu * @param daemon pointer to dlt daemon structure * @param ecu pointer to ecu id of node to clear applications * @param verbose if set to true verbose information is printed out. * @return negative value if there was an error */ int dlt_daemon_applications_clear(DltDaemon *daemon, char *ecu, int verbose); /** * Add (new) context to internal context management * @param daemon pointer to dlt daemon structure * @param apid pointer to application id * @param ctid pointer to context id * @param log_level log level of context * @param trace_status trace status of context * @param log_level_pos offset of context in context field on user application * @param user_handle connection handle for connection to user application * @param description description of context * @param ecu pointer to ecu id of node to add application * @param verbose if set to true verbose information is printed out. * @return Pointer to added context, null pointer on error */ DltDaemonContext *dlt_daemon_context_add(DltDaemon *daemon, char *apid, char *ctid, int8_t log_level, int8_t trace_status, int log_level_pos, int user_handle, char *description, char *ecu, int verbose); /** * Delete context from internal context management * @param daemon pointer to dlt daemon structure * @param context pointer to context to be deleted * @param ecu pointer to ecu id of node to delete application * @param verbose if set to true verbose information is printed out. * @return negative value if there was an error */ int dlt_daemon_context_del(DltDaemon *daemon, DltDaemonContext *context, char *ecu, int verbose); /** * Find context with specific application id and context id * @param daemon pointer to dlt daemon structure * @param apid pointer to application id * @param ctid pointer to context id * @param ecu pointer to ecu id of node to clear applications * @param verbose if set to true verbose information is printed out. * @return Pointer to context, null pointer on error or not found */ DltDaemonContext *dlt_daemon_context_find(DltDaemon *daemon, char *apid, char *ctid, char *ecu, int verbose); /** * Invalidate all contexts fd, if fd is reused * @param daemon pointer to dlt daemon structure * @param ecu node these contexts running on. * @param fd file descriptor * @param verbose if set to true verbose information is printed out. * @return negative value if there was an error */ int dlt_daemon_contexts_invalidate_fd(DltDaemon *daemon, char *ecu, int fd, int verbose); /** * Clear all contexts in internal context management of specific ecu * @param daemon pointer to dlt daemon structure * @param ecu pointer to ecu id of node to clear contexts * @param verbose if set to true verbose information is printed out. * @return negative value if there was an error */ int dlt_daemon_contexts_clear(DltDaemon *daemon, char *ecu, int verbose); /** * Load contexts from file to internal context management * @param daemon pointer to dlt daemon structure * @param filename name of file to be used for loading * @param verbose if set to true verbose information is printed out. * @return negative value if there was an error */ int dlt_daemon_contexts_load(DltDaemon *daemon, const char *filename, int verbose); /** * Save contexts from internal context management to file * @param daemon pointer to dlt daemon structure * @param filename name of file to be used for saving * @param verbose if set to true verbose information is printed out. * @return negative value if there was an error */ int dlt_daemon_contexts_save(DltDaemon *daemon, const char *filename, int verbose); /** * Load persistant configuration * @param daemon pointer to dlt daemon structure * @param filename name of file to be used for loading * @param verbose if set to true verbose information is printed out. * @return negative value if there was an error */ int dlt_daemon_configuration_load(DltDaemon *daemon, const char *filename, int verbose); /** * Save configuration persistantly * @param daemon pointer to dlt daemon structure * @param filename name of file to be used for saving * @param verbose if set to true verbose information is printed out. * @return negative value if there was an error */ int dlt_daemon_configuration_save(DltDaemon *daemon, const char *filename, int verbose); /** * Send user message DLT_USER_MESSAGE_LOG_LEVEL to user application * @param daemon pointer to dlt daemon structure * @param context pointer to context for response * @param verbose if set to true verbose information is printed out. * @return negative value if there was an error */ int dlt_daemon_user_send_log_level(DltDaemon *daemon, DltDaemonContext *context, int verbose); /** * Send user message DLT_USER_MESSAGE_LOG_STATE to user application * @param daemon pointer to dlt daemon structure * @param app pointer to application for response * @param verbose if set to true verbose information is printed out. * @return negative value if there was an error */ int dlt_daemon_user_send_log_state(DltDaemon *daemon, DltDaemonApplication *app, int verbose); /** * Send user messages to all user applications using default context, or trace status * to update those values * @param daemon pointer to dlt daemon structure * @param verbose if set to true verbose information is printed out. */ void dlt_daemon_user_send_default_update(DltDaemon *daemon, int verbose); /** * Send user messages to all user applications context to update with the new log level * @param daemon pointer to dlt daemon structure * @param log_level new log level to be set * @param verbose if set to true verbose information is printed out. */ void dlt_daemon_user_send_all_log_level_update(DltDaemon *daemon, int8_t log_level, int verbose); /** * Send user messages to all user applications context to update with the new trace status * @param daemon pointer to dlt daemon structure * @param trace_status new trace status to be set * @param verbose if set to true verbose information is printed out. */ void dlt_daemon_user_send_all_trace_status_update(DltDaemon *daemon, int8_t trace_status, int verbose); /** * Send user messages to all user applications the log status * everytime the client is connected or disconnected. * @param daemon pointer to dlt daemon structure * @param verbose if set to true verbose information is printed out. */ void dlt_daemon_user_send_all_log_state(DltDaemon *daemon, int verbose); /** * Process reset to factory default control message * @param daemon pointer to dlt daemon structure * @param filename name of file containing the runtime defaults for applications * @param filename1 name of file containing the runtime defaults for contexts * @param InitialContextLogLevel loglevel to be sent to context when those register with loglevel default, read from dlt.conf * @param InitialContextTraceStatus tracestatus to be sent to context when those register with tracestatus default, read from dlt.conf * @param InitialEnforceLlTsStatus force default log-level * @param verbose if set to true verbose information is printed out. */ void dlt_daemon_control_reset_to_factory_default(DltDaemon *daemon, const char *filename, const char *filename1, int InitialContextLogLevel, int InitialContextTraceStatus, int InitialEnforceLlTsStatus, int verbose); /** * Change the logging state of dlt daemon * @param daemon pointer to dlt daemon structure * @param newState the requested new state */ void dlt_daemon_change_state(DltDaemon *daemon, DltDaemonState newState); # ifdef __cplusplus } # endif /** \} */ #endif /* DLT_DAEMON_COMMON_H */ dlt-daemon-2.18.4/src/daemon/dlt_daemon_common_cfg.h000066400000000000000000000130441353342203500223340ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2011-2015, BMW AG * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author Alexander Wenzel * * \copyright Copyright © 2011-2015 BMW AG. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file dlt_daemon_common_cfg.h */ /******************************************************************************* ** ** ** SRC-MODULE: dlt_daemon_common_cfg.h ** ** ** ** TARGET : linux ** ** ** ** PROJECT : DLT ** ** ** ** AUTHOR : Alexander Wenzel Alexander.AW.Wenzel@bmw.de ** ** Markus Klein ** ** ** ** PURPOSE : ** ** ** ** REMARKS : ** ** ** ** PLATFORM DEPENDANT [yes/no]: yes ** ** ** ** TO BE CHANGED BY USER [yes/no]: no ** ** ** *******************************************************************************/ /******************************************************************************* ** Author Identity ** ******************************************************************************** ** ** ** Initials Name Company ** ** -------- ------------------------- ---------------------------------- ** ** aw Alexander Wenzel BMW ** ** mk Markus Klein Fraunhofer ESK ** *******************************************************************************/ /******************************************************************************* ** Author Identity ** ******************************************************************************** ** ** ** Initials Name Company ** ** -------- ------------------------- ---------------------------------- ** ** aw Alexander Wenzel BMW ** ** mk Markus Klein Fraunhofer ESK ** *******************************************************************************/ #ifndef DLT_DAEMON_COMMON_CFG_H #define DLT_DAEMON_COMMON_CFG_H /*************/ /* Changable */ /*************/ /* Default Path for runtime configuration */ #define DLT_RUNTIME_DEFAULT_DIRECTORY "/tmp" /* Path and filename for runtime configuration (applications) */ #define DLT_RUNTIME_APPLICATION_CFG "/dlt-runtime-application.cfg" /* Path and filename for runtime configuration (contexts) */ #define DLT_RUNTIME_CONTEXT_CFG "/dlt-runtime-context.cfg" /* Path and filename for runtime configuration */ #define DLT_RUNTIME_CONFIGURATION "/dlt-runtime.cfg" /* Default Path for control socket */ #define DLT_DAEMON_DEFAULT_CTRL_SOCK_PATH DLT_RUNTIME_DEFAULT_DIRECTORY \ "/dlt-ctrl.sock" #ifdef DLT_USE_UNIX_SOCKET_IPC # define DLT_DAEMON_DEFAULT_APP_SOCK_PATH DLT_RUNTIME_DEFAULT_DIRECTORY \ "/dlt-app.sock" #endif /* Size of text buffer */ #define DLT_DAEMON_COMMON_TEXTBUFSIZE 255 /* Application ID used when the dlt daemon creates a control message */ #define DLT_DAEMON_CTRL_APID "DA1" /* Context ID used when the dlt daemon creates a control message */ #define DLT_DAEMON_CTRL_CTID "DC1" /* Number of entries to be allocated at one in application table, * when no more entries are available */ #define DLT_DAEMON_APPL_ALLOC_SIZE 500 /* Number of entries to be allocated at one in context table, * when no more entries are available */ #define DLT_DAEMON_CONTEXT_ALLOC_SIZE 1000 /* Debug get log info function, * set to 1 to enable, 0 to disable debugging */ #define DLT_DEBUG_GETLOGINFO 0 /************************/ /* Don't change please! */ /************************/ /* Minimum ID for an injection message */ #define DLT_DAEMON_INJECTION_MIN 0xFFF /* Maximum ID for an injection message */ #define DLT_DAEMON_INJECTION_MAX 0xFFFFFFFF /* Remote interface identifier */ #define DLT_DAEMON_REMO_STRING "remo" #endif /* DLT_DAEMON_COMMON_CFG_H */ dlt-daemon-2.18.4/src/daemon/dlt_daemon_connection.c000066400000000000000000000307061353342203500223630ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2015 Advanced Driver Information Technology. * This code is developed by Advanced Driver Information Technology. * Copyright of Advanced Driver Information Technology, Bosch and DENSO. * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author * Frederic Berat * * \copyright Copyright © 2015 Advanced Driver Information Technology. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file dlt_daemon_connection.c */ #include #include #include #include #include #include #include #include #include "dlt_daemon_connection_types.h" #include "dlt_daemon_connection.h" #include "dlt_daemon_event_handler_types.h" #include "dlt_daemon_event_handler.h" #include "dlt-daemon.h" #include "dlt-daemon_cfg.h" #include "dlt_daemon_common.h" #include "dlt_common.h" #include "dlt_gateway.h" #include "dlt_daemon_socket.h" static DltConnectionId connectionId; extern char *app_recv_buffer; /** @brief Generic sending function. * * We manage different type of connection which have similar send/write * functions. We can then abstract the data transfer using this function, * moreover as we often transfer data to different kind of connection * within the same loop. * * @param conn The connection structure. * @param msg The message buffer to be sent * @param msg_size The length of the message to be sent * * @return DLT_DAEMON_ERROR_OK on success, DLT_DAEMON_ERROR_SEND_FAILED * on send failure, DLT_DAEMON_ERROR_UNKNOWN otherwise. * errno is appropriately set. */ DLT_STATIC int dlt_connection_send(DltConnection *conn, void *msg, size_t msg_size) { DltConnectionType type = DLT_CONNECTION_TYPE_MAX; int ret = 0; if ((conn != NULL) && (conn->receiver != NULL)) type = conn->type; switch (type) { case DLT_CONNECTION_CLIENT_MSG_SERIAL: if (write(conn->receiver->fd, msg, msg_size) > 0) return DLT_DAEMON_ERROR_OK; return DLT_DAEMON_ERROR_UNKNOWN; case DLT_CONNECTION_CLIENT_MSG_TCP: ret = dlt_daemon_socket_sendreliable(conn->receiver->fd, msg, msg_size); return ret; default: return DLT_DAEMON_ERROR_UNKNOWN; } } /** @brief Send up to two messages through a connection. * * We often need to send 2 messages through a specific connection, plus * the serial header. This function groups these different calls. * * @param con The connection to send the messages through. * @param data1 The first message to be sent. * @param size1 The size of the first message. * @param data2 The second message to be send. * @param size2 The second message size. * @param sendserialheader Whether we need or not to send the serial header. * * @return DLT_DAEMON_ERROR_OK on success, -1 otherwise. errno is properly set. */ int dlt_connection_send_multiple(DltConnection *con, void *data1, int size1, void *data2, int size2, int sendserialheader) { int ret = 0; if (con == NULL) return DLT_DAEMON_ERROR_UNKNOWN; if (sendserialheader) ret = dlt_connection_send(con, (void *)dltSerialHeader, sizeof(dltSerialHeader)); if ((data1 != NULL) && (ret == DLT_RETURN_OK)) ret = dlt_connection_send(con, data1, size1); if ((data2 != NULL) && (ret == DLT_RETURN_OK)) ret = dlt_connection_send(con, data2, size2); return ret; } /** @brief Get the next connection filtered with a type mask. * * In some cases we need the next connection available of a specific type or * specific different types. This function returns the next available connection * that is of one of the types included in the mask. The current connection can * be returned. * * @param current The current connection pointer. * @param type_mask A bit mask representing the connection types to be filtered. * * @return The next available connection of the considered types or NULL. */ DltConnection *dlt_connection_get_next(DltConnection *current, int type_mask) { while (current && !((1 << current->type) & type_mask)) current = current->next; return current; } DLT_STATIC void dlt_connection_destroy_receiver(DltConnection *con) { if (!con) return; switch (con->type) { case DLT_CONNECTION_GATEWAY: /* We rely on the gateway for clean-up */ break; case DLT_CONNECTION_APP_MSG: dlt_receiver_free_unix_socket(con->receiver); free(con->receiver); con->receiver = NULL; break; default: (void)dlt_receiver_free(con->receiver); free(con->receiver); con->receiver = NULL; break; } } /** @brief Get the receiver structure associated to a connection. * * The receiver structure is sometimes needed while handling the event. * This behavior is mainly due to the fact that it's not intended to modify * the whole design of the daemon while implementing the new event handling. * Based on the connection type provided, this function returns the pointer * to the DltReceiver structure corresponding. * * @param daemon_local Structure where to take the DltReceiver pointer from. * @param type Type of the connection. * @param fd File descriptor * * @return DltReceiver structure or NULL if none corresponds to the type. */ DLT_STATIC DltReceiver *dlt_connection_get_receiver(DltDaemonLocal *daemon_local, DltConnectionType type, int fd) { DltReceiver *ret = NULL; switch (type) { case DLT_CONNECTION_CONTROL_CONNECT: /* FALL THROUGH */ case DLT_CONNECTION_CONTROL_MSG: /* FALL THROUGH */ case DLT_CONNECTION_CLIENT_CONNECT: /* FALL THROUGH */ case DLT_CONNECTION_CLIENT_MSG_TCP: ret = calloc(1, sizeof(DltReceiver)); if (ret) dlt_receiver_init(ret, fd, DLT_DAEMON_RCVBUFSIZESOCK); break; case DLT_CONNECTION_CLIENT_MSG_SERIAL: ret = calloc(1, sizeof(DltReceiver)); if (ret) dlt_receiver_init(ret, fd, DLT_DAEMON_RCVBUFSIZESERIAL); break; case DLT_CONNECTION_APP_MSG: ret = calloc(1, sizeof(DltReceiver)); if (ret) { #ifdef DLT_USE_UNIX_SOCKET_IPC dlt_receiver_init_unix_socket(ret, fd, &app_recv_buffer); #else dlt_receiver_init(ret, fd, DLT_RECEIVE_BUFSIZE); #endif } break; #ifdef DLT_USE_UNIX_SOCKET_IPC case DLT_CONNECTION_APP_CONNECT: /* FALL THROUGH */ #endif case DLT_CONNECTION_ONE_S_TIMER: /* FALL THROUGH */ case DLT_CONNECTION_SIXTY_S_TIMER: #ifdef DLT_SYSTEMD_WATCHDOG_ENABLE /* FALL THROUGH */ case DLT_CONNECTION_SYSTEMD_TIMER: #endif /* FALL THROUGH */ case DLT_CONNECTION_GATEWAY_TIMER: ret = calloc(1, sizeof(DltReceiver)); if (ret) dlt_receiver_init(ret, fd, DLT_DAEMON_RCVBUFSIZE); break; case DLT_CONNECTION_GATEWAY: /* We rely on the gateway for init */ ret = dlt_gateway_get_connection_receiver(&daemon_local->pGateway, fd); break; default: ret = NULL; } return ret; } /** @brief Get the callback from a specific connection. * * The callback retrieved that way is used to handle event for this connection. * It as been chosen to proceed that way instead of having the callback directly * in the structure in order to have some way to check that the structure is * still valid, or at least gracefully handle errors instead of crashing. * * @param con The connection to retrieve the callback from. * * @return Function pointer or NULL. */ void *dlt_connection_get_callback(DltConnection *con) { void *ret = NULL; DltConnectionType type = DLT_CONNECTION_TYPE_MAX; if (con) type = con->type; switch (type) { case DLT_CONNECTION_CLIENT_CONNECT: ret = dlt_daemon_process_client_connect; break; case DLT_CONNECTION_CLIENT_MSG_TCP: ret = dlt_daemon_process_client_messages; break; case DLT_CONNECTION_CLIENT_MSG_SERIAL: ret = dlt_daemon_process_client_messages_serial; break; #ifdef DLT_USE_UNIX_SOCKET_IPC case DLT_CONNECTION_APP_CONNECT: ret = dlt_daemon_process_app_connect; break; #endif case DLT_CONNECTION_APP_MSG: ret = dlt_daemon_process_user_messages; break; case DLT_CONNECTION_ONE_S_TIMER: ret = dlt_daemon_process_one_s_timer; break; case DLT_CONNECTION_SIXTY_S_TIMER: ret = dlt_daemon_process_sixty_s_timer; break; #ifdef DLT_SYSTEMD_WATCHDOG_ENABLE case DLT_CONNECTION_SYSTEMD_TIMER: ret = dlt_daemon_process_systemd_timer; break; #endif case DLT_CONNECTION_CONTROL_CONNECT: ret = dlt_daemon_process_control_connect; break; case DLT_CONNECTION_CONTROL_MSG: ret = dlt_daemon_process_control_messages; break; case DLT_CONNECTION_GATEWAY: ret = dlt_gateway_process_passive_node_messages; break; case DLT_CONNECTION_GATEWAY_TIMER: ret = dlt_gateway_process_gateway_timer; break; default: ret = NULL; } return ret; } /** @brief Destroys a connection. * * This function closes and frees the corresponding connection. This is expected * to be called by the connection owner: the DltEventHandler. * Ownership of the connection is given during the registration to * the DltEventHandler. * * @param to_destroy Connection to be destroyed. */ void dlt_connection_destroy(DltConnection *to_destroy) { to_destroy->id = 0; close(to_destroy->receiver->fd); dlt_connection_destroy_receiver(to_destroy); free(to_destroy); } /** @brief Creates a connection and registers it to the DltEventHandler. * * The function will allocate memory for the connection, and give the pointer * to the DltEventHandler in order to register it for incoming events. * The connection is then destroyed later on, once it's not needed anymore or * it the event handler is destroyed. * * @param daemon_local Structure were some needed information is. * @param evh DltEventHandler to register the connection to. * @param fd File descriptor of the connection. * @param mask Event list bit mask. * @param type Connection type. * * @return 0 On success, -1 otherwise. */ int dlt_connection_create(DltDaemonLocal *daemon_local, DltEventHandler *evh, int fd, int mask, DltConnectionType type) { DltConnection *temp = NULL; if (fd < 0) /* Nothing to do */ return 0; if (dlt_event_handler_find_connection(evh, fd) != NULL) /* No need for the same client to be registered twice * for the same event. * TODO: If another mask can be expected, * we need it to update the poll event here. */ return 0; temp = (DltConnection *)malloc(sizeof(DltConnection)); if (temp == NULL) { dlt_log(LOG_CRIT, "Allocation of client handle failed\n"); return -1; } memset(temp, 0, sizeof(DltConnection)); temp->receiver = dlt_connection_get_receiver(daemon_local, type, fd); if (!temp->receiver) { dlt_vlog(LOG_CRIT, "Unable to get receiver from %d connection.\n", type); free(temp); return -1; } /* We are single threaded no need for protection. */ temp->id = connectionId++; if (!temp->id) /* Skipping 0 */ temp->id = connectionId++; temp->type = type; temp->status = ACTIVE; /* Now give the ownership of the newly created connection * to the event handler, by registering for events. */ return dlt_event_handler_register_connection(evh, daemon_local, temp, mask); } dlt-daemon-2.18.4/src/daemon/dlt_daemon_connection.h000066400000000000000000000036551353342203500223730ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2015 Advanced Driver Information Technology. * This code is developed by Advanced Driver Information Technology. * Copyright of Advanced Driver Information Technology, Bosch and DENSO. * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author * Frederic Berat * * \copyright Copyright © 2015 Advanced Driver Information Technology. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file dlt_daemon_connection.h */ #ifndef DLT_DAEMON_CONNECTION_H #define DLT_DAEMON_CONNECTION_H #include "dlt_daemon_connection_types.h" #include "dlt_daemon_event_handler_types.h" #include "dlt-daemon.h" int dlt_connection_send_multiple(DltConnection *, void *, int, void *, int, int); DltConnection *dlt_connection_get_next(DltConnection *, int); int dlt_connection_create_remaining(DltDaemonLocal *); int dlt_connection_create(DltDaemonLocal *, DltEventHandler *, int, int, DltConnectionType); void dlt_connection_destroy(DltConnection *); void *dlt_connection_get_callback(DltConnection *); #ifdef DLT_UNIT_TESTS int dlt_connection_send(DltConnection *conn, void *msg, size_t msg_size); void dlt_connection_destroy_receiver(DltConnection *con); DltReceiver *dlt_connection_get_receiver(DltDaemonLocal *daemon_local, DltConnectionType type, int fd); #endif #endif /* DLT_DAEMON_CONNECTION_H */ dlt-daemon-2.18.4/src/daemon/dlt_daemon_connection_types.h000066400000000000000000000065221353342203500236130ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2015 Advanced Driver Information Technology. * This code is developed by Advanced Driver Information Technology. * Copyright of Advanced Driver Information Technology, Bosch and DENSO. * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author * Frederic Berat * * \copyright Copyright © 2015 Advanced Driver Information Technology. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file dlt_daemon_connection_types.h */ #ifndef DLT_DAEMON_CONNECTION_TYPES_H #define DLT_DAEMON_CONNECTION_TYPES_H #include "dlt_common.h" typedef enum { UNDEFINED, /* Undefined status */ INACTIVE, /* Connection is inactive, excluded from poll handling */ ACTIVE, /* Connection is actively handled by poll */ DEACTIVATE,/* Request for deactivation of the connection */ ACTIVATE /* Request for activation of the connection */ } DltConnectionStatus; typedef enum { DLT_CONNECTION_NONE = 0, DLT_CONNECTION_CLIENT_CONNECT, DLT_CONNECTION_CLIENT_MSG_TCP, DLT_CONNECTION_CLIENT_MSG_SERIAL, DLT_CONNECTION_APP_CONNECT, DLT_CONNECTION_APP_MSG, DLT_CONNECTION_ONE_S_TIMER, DLT_CONNECTION_SIXTY_S_TIMER, DLT_CONNECTION_SYSTEMD_TIMER, DLT_CONNECTION_CONTROL_CONNECT, DLT_CONNECTION_CONTROL_MSG, DLT_CONNECTION_GATEWAY, DLT_CONNECTION_GATEWAY_TIMER, DLT_CONNECTION_TYPE_MAX } DltConnectionType; #define DLT_CON_MASK_CLIENT_CONNECT (1 << DLT_CONNECTION_CLIENT_CONNECT) #define DLT_CON_MASK_CLIENT_MSG_TCP (1 << DLT_CONNECTION_CLIENT_MSG_TCP) #define DLT_CON_MASK_CLIENT_MSG_SERIAL (1 << DLT_CONNECTION_CLIENT_MSG_SERIAL) #define DLT_CON_MASK_APP_MSG (1 << DLT_CONNECTION_APP_MSG) #define DLT_CON_MASK_APP_CONNECT (1 << DLT_CONNECTION_APP_CONNECT) #define DLT_CON_MASK_ONE_S_TIMER (1 << DLT_CONNECTION_ONE_S_TIMER) #define DLT_CON_MASK_SIXTY_S_TIMER (1 << DLT_CONNECTION_SIXTY_S_TIMER) #define DLT_CON_MASK_SYSTEMD_TIMER (1 << DLT_CONNECTION_SYSTEMD_TIMER) #define DLT_CON_MASK_CONTROL_CONNECT (1 << DLT_CONNECTION_CONTROL_CONNECT) #define DLT_CON_MASK_CONTROL_MSG (1 << DLT_CONNECTION_CONTROL_MSG) #define DLT_CON_MASK_GATEWAY (1 << DLT_CONNECTION_GATEWAY) #define DLT_CON_MASK_GATEWAY_TIMER (1 << DLT_CONNECTION_GATEWAY_TIMER) #define DLT_CON_MASK_ALL (0xffff) typedef uintptr_t DltConnectionId; /* TODO: squash the DltReceiver structure in there * and remove any other duplicates of FDs */ typedef struct DltConnection { DltConnectionId id; DltReceiver *receiver; /**< Receiver structure for this connection */ DltConnectionType type; /**< Represents what type of handle is this (like FIFO, serial, client, server) */ DltConnectionStatus status; /**< Status of connection */ struct DltConnection *next; /**< For multiple client connection using linked list */ int ev_mask; /**< Mask to set when registering the connection for events */ } DltConnection; #endif /* DLT_DAEMON_CONNECTION_TYPES_H */ dlt-daemon-2.18.4/src/daemon/dlt_daemon_event_handler.c000066400000000000000000000372061353342203500230440ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2015 Advanced Driver Information Technology. * This code is developed by Advanced Driver Information Technology. * Copyright of Advanced Driver Information Technology, Bosch and DENSO. * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author * Frederic Berat * * \copyright Copyright © 2015 Advanced Driver Information Technology. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file dlt_daemon_event_handler.c */ #include #include #include #include #include #include #include "dlt_common.h" #include "dlt-daemon.h" #include "dlt-daemon_cfg.h" #include "dlt_daemon_common.h" #include "dlt_daemon_connection.h" #include "dlt_daemon_connection_types.h" #include "dlt_daemon_event_handler.h" #include "dlt_daemon_event_handler_types.h" /** * \def DLT_EV_TIMEOUT_MSEC * The maximum amount of time to wait for a poll event. * Set to 1 second to avoid unnecessary wake ups. */ #define DLT_EV_TIMEOUT_MSEC 1000 #define DLT_EV_BASE_FD 16 #define DLT_EV_MASK_REJECTED (POLLERR | POLLNVAL) /** @brief Initialize a pollfd structure * * That ensures that no event will be mis-watched. * * @param pfd The element to initialize */ static void init_poll_fd(struct pollfd *pfd) { pfd->fd = -1; pfd->events = 0; pfd->revents = 0; } /** @brief Prepare the event handler * * This will create the base poll file descriptor list. * * @param ev The event handler to prepare. * * @return 0 on success, -1 otherwise. */ int dlt_daemon_prepare_event_handling(DltEventHandler *ev) { int i = 0; if (ev == NULL) return DLT_RETURN_ERROR; ev->pfd = calloc(DLT_EV_BASE_FD, sizeof(struct pollfd)); if (ev->pfd == NULL) { dlt_log(LOG_CRIT, "Creation of poll instance failed!\n"); return -1; } for (i = 0; i < DLT_EV_BASE_FD; i++) init_poll_fd(&ev->pfd[i]); ev->nfds = 0; ev->max_nfds = DLT_EV_BASE_FD; return 0; } /** @brief Enable a file descriptor to be watched * * Adds a file descriptor to the descriptor list. If the list is to small, * increase its size. * * @param ev The event handler structure, containing the list * @param fd The file descriptor to add * @param mask The mask of event to be watched */ static void dlt_event_handler_enable_fd(DltEventHandler *ev, int fd, int mask) { if (ev->max_nfds <= ev->nfds) { int i = ev->nfds; int max = 2 * ev->max_nfds; struct pollfd *tmp = realloc(ev->pfd, max * sizeof(*ev->pfd)); if (!tmp) { dlt_log(LOG_CRIT, "Unable to register new fd for the event handler.\n"); return; } ev->pfd = tmp; ev->max_nfds = max; for (; i < max; i++) init_poll_fd(&ev->pfd[i]); } ev->pfd[ev->nfds].fd = fd; ev->pfd[ev->nfds].events = mask; ev->nfds++; } /** @brief Disable a file descriptor for watching * * The file descriptor is removed from the descriptor list, the list is * compressed during the process. * * @param ev The event handler structure containing the list * @param fd The file descriptor to be removed */ static void dlt_event_handler_disable_fd(DltEventHandler *ev, int fd) { unsigned int i = 0; unsigned int j = 0; unsigned int nfds = ev->nfds; for (; i < nfds; i++, j++) { if (ev->pfd[i].fd == fd) { init_poll_fd(&ev->pfd[i]); j++; ev->nfds--; } if (i == j) continue; /* Compressing the table */ if (i < ev->nfds) { ev->pfd[i].fd = ev->pfd[j].fd; ev->pfd[i].events = ev->pfd[j].events; ev->pfd[i].revents = ev->pfd[j].revents; } else { init_poll_fd(&ev->pfd[i]); } } } /** @brief Catch and process incoming events. * * This function waits for events on all connections. Once an event raise, * the callback for the specific connection is called, or the connection is * destroyed if a hangup occurs. * * @param daemon Structure to be passed to the callback. * @param daemon_local Structure containing needed information. * @param pEvent Event handler structure. * * @return 0 on success, -1 otherwise. May be interrupted. */ int dlt_daemon_handle_event(DltEventHandler *pEvent, DltDaemon *daemon, DltDaemonLocal *daemon_local) { int ret = 0; unsigned int i = 0; int (*callback)(DltDaemon *, DltDaemonLocal *, DltReceiver *, int) = NULL; if ((pEvent == NULL) || (daemon == NULL) || (daemon_local == NULL)) return DLT_RETURN_ERROR; ret = poll(pEvent->pfd, pEvent->nfds, DLT_EV_TIMEOUT_MSEC); if (ret <= 0) { /* We are not interested in EINTR has it comes * either from timeout or signal. */ if (errno == EINTR) ret = 0; if (ret < 0) dlt_vlog(LOG_CRIT, "poll() failed: %s\n", strerror(errno)); return ret; } for (i = 0; i < pEvent->nfds; i++) { int fd = 0; DltConnection *con = NULL; DltConnectionType type = DLT_CONNECTION_TYPE_MAX; if (pEvent->pfd[i].revents == 0) continue; con = dlt_event_handler_find_connection(pEvent, pEvent->pfd[i].fd); if (con && con->receiver) { type = con->type; fd = con->receiver->fd; } else { /* connection might have been destroyed in the meanwhile */ dlt_event_handler_disable_fd(pEvent, pEvent->pfd[i].fd); continue; } /* First of all handle error events */ if (pEvent->pfd[i].revents & DLT_EV_MASK_REJECTED) { /* An error occurred, we need to clean-up the concerned event */ if (type == DLT_CONNECTION_CLIENT_MSG_TCP) /* To transition to BUFFER state if this is final TCP client connection, * call dedicated function. this function also calls * dlt_event_handler_unregister_connection() inside the function. */ dlt_daemon_close_socket(fd, daemon, daemon_local, 0); else dlt_event_handler_unregister_connection(pEvent, daemon_local, fd); continue; } /* Get the function to be used to handle the event */ callback = dlt_connection_get_callback(con); if (!callback) { dlt_vlog(LOG_CRIT, "Unable to find function for %d handle type.\n", type); return -1; } /* From now on, callback is correct */ if (callback(daemon, daemon_local, con->receiver, daemon_local->flags.vflag) == -1) { dlt_vlog(LOG_CRIT, "Processing from %d handle type failed!\n", type); return -1; } } return 0; } /** @brief Find connection with a specific \a fd in the connection list. * * There can be only one event per \a fd. We can then find a specific connection * based on this \a fd. That allows to check if a specific \a fd has already been * registered. * * @param ev The event handler structure where the list of connection is. * @param fd The file descriptor of the connection to be found. * * @return The found connection pointer, NULL otherwise. */ DltConnection *dlt_event_handler_find_connection(DltEventHandler *ev, int fd) { DltConnection *temp = ev->connections; while (temp != NULL) { if ((temp->receiver != NULL) && (temp->receiver->fd == fd)) return temp; temp = temp->next; } return temp; } /** @brief Remove a connection from the list and destroy it. * * This function will first look for the connection in the event handler list, * remove it from the list and then destroy it. * * @param ev The event handler structure where the list of connection is. * @param to_remove The connection to remove from the list. * * @return 0 on success, -1 if the connection is not found. */ DLT_STATIC int dlt_daemon_remove_connection(DltEventHandler *ev, DltConnection *to_remove) { if ((ev == NULL) || (to_remove == NULL)) return DLT_RETURN_ERROR; DltConnection *curr = ev->connections; DltConnection *prev = curr; /* Find the address where to_remove value is registered */ while (curr && (curr != to_remove)) { prev = curr; curr = curr->next; } if (!curr) { /* Must not be possible as we check for existence before */ dlt_log(LOG_CRIT, "Connection not found for removal.\n"); return -1; } else if (curr == ev->connections) { ev->connections = curr->next; } else { prev->next = curr->next; } /* Now we can destroy our pointer */ dlt_connection_destroy(to_remove); return 0; } /** @brief Destroy the connection list. * * This function runs through the connection list and destroy them one by one. * * @param ev Pointer to the event handler structure. */ void dlt_event_handler_cleanup_connections(DltEventHandler *ev) { unsigned int i = 0; if (ev == NULL) /* Nothing to do. */ return; while (ev->connections != NULL) /* We don really care on failure */ (void)dlt_daemon_remove_connection(ev, ev->connections); for (i = 0; i < ev->nfds; i++) init_poll_fd(&ev->pfd[i]); free(ev->pfd); } /** @brief Add a new connection to the list. * * The connection is added at the tail of the list. * * @param ev The event handler structure where the connection list is. * @param connection The connection to be added. */ DLT_STATIC void dlt_daemon_add_connection(DltEventHandler *ev, DltConnection *connection) { DltConnection **temp = &ev->connections; while (*temp != NULL) temp = &(*temp)->next; *temp = connection; } /** @brief Check for connection activation * * If the connection is active and it's not allowed anymore or it the user * ask for deactivation, the connection will be deactivated. * If the connection is inactive, the user asks for activation and it's * allowed for it to be activated, the connection will be activated. * * @param evhdl The event handler structure. * @param con The connection to act on * @param activation_type The type of activation requested ((DE)ACTIVATE) * * @return 0 on success, -1 otherwise */ int dlt_connection_check_activate(DltEventHandler *evhdl, DltConnection *con, int activation_type) { if (!evhdl || !con || !con->receiver) { dlt_vlog(LOG_ERR, "%s: wrong parameters.\n", __func__); return -1; } switch (con->status) { case ACTIVE: if (activation_type == DEACTIVATE) { dlt_vlog(LOG_INFO, "Deactivate connection type: %d\n", con->type); dlt_event_handler_disable_fd(evhdl, con->receiver->fd); if (con->type == DLT_CONNECTION_CLIENT_CONNECT) con->receiver->fd = -1; con->status = INACTIVE; } break; case INACTIVE: if (activation_type == ACTIVATE) { dlt_vlog(LOG_INFO, "Activate connection type: %d\n", con->type); dlt_event_handler_enable_fd(evhdl, con->receiver->fd, con->ev_mask); con->status = ACTIVE; } break; default: dlt_vlog(LOG_ERR, "Unknown connection status: %d\n", con->status); return -1; } return 0; } /** @brief Registers a connection for event handling and takes its ownership. * * As we add the connection to the list of connection, we take its ownership. * That's the only place where the connection pointer is stored. * The connection is then used to create a new event trigger. * If the connection is of type DLT_CONNECTION_CLIENT_MSG_TCP, we increase * the daemon_local->client_connections counter. TODO: Move this counter inside * the event handler structure. * * @param evhdl The event handler structure where the connection list is. * @param daemon_local Structure containing needed information. * @param connection The connection to be registered. * @param mask The bit mask of event to be registered. * * @return 0 on success, -1 otherwise. */ int dlt_event_handler_register_connection(DltEventHandler *evhdl, DltDaemonLocal *daemon_local, DltConnection *connection, int mask) { if (!evhdl || !connection || !connection->receiver) { dlt_log(LOG_ERR, "Wrong parameters when registering connection.\n"); return -1; } dlt_daemon_add_connection(evhdl, connection); if ((connection->type == DLT_CONNECTION_CLIENT_MSG_TCP) || (connection->type == DLT_CONNECTION_CLIENT_MSG_SERIAL)) daemon_local->client_connections++; /* On creation the connection is not active by default */ connection->status = INACTIVE; connection->next = NULL; connection->ev_mask = mask; return dlt_connection_check_activate(evhdl, connection, ACTIVATE); } /** @brief Unregisters a connection from the event handler and destroys it. * * We first look for the connection to be unregistered, delete the event * corresponding and then destroy the connection. * If the connection is of type DLT_CONNECTION_CLIENT_MSG_TCP, we decrease * the daemon_local->client_connections counter. TODO: Move this counter inside * the event handler structure. * * @param evhdl The event handler structure where the connection list is. * @param daemon_local Structure containing needed information. * @param fd The file descriptor of the connection to be unregistered. * * @return 0 on success, -1 otherwise. */ int dlt_event_handler_unregister_connection(DltEventHandler *evhdl, DltDaemonLocal *daemon_local, int fd) { if ((evhdl == NULL) || (daemon_local == NULL)) return DLT_RETURN_ERROR; /* Look for the pointer in the client list. * There shall be only one event handler with the same fd. */ DltConnection *temp = dlt_event_handler_find_connection(evhdl, fd); if (!temp) { dlt_log(LOG_ERR, "Connection not found for unregistration.\n"); return -1; } if ((temp->type == DLT_CONNECTION_CLIENT_MSG_TCP) || (temp->type == DLT_CONNECTION_CLIENT_MSG_SERIAL)) { daemon_local->client_connections--; if (daemon_local->client_connections < 0) { daemon_local->client_connections = 0; dlt_log(LOG_CRIT, "Unregistering more client than registered!\n"); } } if (dlt_connection_check_activate(evhdl, temp, DEACTIVATE) < 0) dlt_log(LOG_ERR, "Unable to unregister event.\n"); /* Cannot fail as far as dlt_daemon_find_connection succeed */ return dlt_daemon_remove_connection(evhdl, temp); } dlt-daemon-2.18.4/src/daemon/dlt_daemon_event_handler.h000066400000000000000000000045261353342203500230500ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2015 Advanced Driver Information Technology. * This code is developed by Advanced Driver Information Technology. * Copyright of Advanced Driver Information Technology, Bosch and DENSO. * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author * Frederic Berat * * \copyright Copyright © 2015 Advanced Driver Information Technology. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file dlt_daemon_event_handler.h */ #include #include "dlt_daemon_connection_types.h" #include "dlt_daemon_event_handler_types.h" #include "dlt-daemon.h" #ifndef DLT_DAEMON_EVENT_HANDLER_H # define DLT_DAEMON_EVENT_HANDLER_H int dlt_daemon_prepare_event_handling(DltEventHandler *); int dlt_daemon_handle_event(DltEventHandler *, DltDaemon *, DltDaemonLocal *); DltConnection *dlt_event_handler_find_connection_by_id(DltEventHandler *, DltConnectionId); DltConnection *dlt_event_handler_find_connection(DltEventHandler *, int); void dlt_event_handler_cleanup_connections(DltEventHandler *); int dlt_event_handler_register_connection(DltEventHandler *, DltDaemonLocal *, DltConnection *, int); int dlt_event_handler_unregister_connection(DltEventHandler *, DltDaemonLocal *, int); int dlt_connection_check_activate(DltEventHandler *, DltConnection *, int); # ifdef DLT_UNIT_TESTS int dlt_daemon_remove_connection(DltEventHandler *ev, DltConnection *to_remove); void dlt_daemon_add_connection(DltEventHandler *ev, DltConnection *connection); # endif #endif /* DLT_DAEMON_EVENT_HANDLER_H */ dlt-daemon-2.18.4/src/daemon/dlt_daemon_event_handler_types.h000066400000000000000000000031341353342203500242660ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2015 Advanced Driver Information Technology. * This code is developed by Advanced Driver Information Technology. * Copyright of Advanced Driver Information Technology, Bosch and DENSO. * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author * Frederic Berat * * \copyright Copyright © 2015 Advanced Driver Information Technology. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file dlt_daemon_event_handler_types.h */ #include #include "dlt_daemon_connection_types.h" #ifndef DLT_DAEMON_EVENT_HANDLER_TYPES_H # define DLT_DAEMON_EVENT_HANDLER_TYPES_H /* FIXME: Remove the need for DltDaemonLocal everywhere in the code * These typedefs are needed by DltDaemonLocal which is * itself needed for functions used by the event handler * (as this structure is used everywhere in the code ...) */ typedef enum { DLT_TIMER_PACKET = 0, DLT_TIMER_ECU, # ifdef DLT_SYSTEMD_WATCHDOG_ENABLE DLT_TIMER_SYSTEMD, # endif DLT_TIMER_GATEWAY, DLT_TIMER_UNKNOWN } DltTimers; typedef struct { struct pollfd *pfd; nfds_t nfds; nfds_t max_nfds; DltConnection *connections; } DltEventHandler; #endif /* DLT_DAEMON_EVENT_HANDLER_TYPES_H */ dlt-daemon-2.18.4/src/daemon/dlt_daemon_offline_logstorage.c000066400000000000000000001316161353342203500240760ustar00rootroot00000000000000/** * Copyright (C) 2013 - 2018 Advanced Driver Information Technology. * This code is developed by Advanced Driver Information Technology. * Copyright of Advanced Driver Information Technology, Bosch and DENSO. * * DLT offline log storage functionality source file. * * \copyright * This Source Code Form is subject to the terms of the * Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with * this file, You can obtain one at http://mozilla.org/MPL/2.0/. * * * \author Syed Hameed ADIT 2013 - 2015 * \author Christoph Lipka ADIT 2015 * * \file: dlt_daemon_offline_logstorage.c * For further information see http://www.genivi.org/. */ #include #include #include #include #include "dlt_daemon_offline_logstorage.h" #include "dlt_daemon_offline_logstorage_internal.h" #include "dlt_gateway_types.h" #include "dlt_gateway.h" /** * dlt_logstorage_split_ecuid * * Split keys with ECU ID alone * * @param key Key * @param len Key length * @param ecuid ECU ID from key stored here * @param apid Application ID as .* stored here * @param ctid Context id as .* stored here * @return 0 on success -1 on error */ DLT_STATIC DltReturnValue dlt_logstorage_split_ecuid(char *key, int len, char *ecuid, char *apid, char *ctid) { if ((len > (DLT_ID_SIZE + 2)) || (len < 2)) return DLT_RETURN_ERROR; strncpy(ecuid, key, (len - 2)); strncpy(apid, ".*", 2); strncpy(ctid, ".*", 2); return DLT_RETURN_OK; } /** * dlt_logstorage_split_ctid * * Split keys with Context ID alone * * @param key Key * @param len Key length * @param apid Application ID as .* stored here * @param ctid Context id from key stored here * @return 0 on success -1 on error */ DLT_STATIC DltReturnValue dlt_logstorage_split_ctid(char *key, int len, char *apid, char *ctid) { if ((len > (DLT_ID_SIZE + 2)) || (len < 1)) return DLT_RETURN_ERROR; strncpy(ctid, (key + 2), (len - 1)); strncpy(apid, ".*", 2); return DLT_RETURN_OK; } /** * dlt_logstorage_split_apid * * Split keys with Application ID alone * * @param key Key * @param len Key length * @param apid Application ID from key is stored here * @param ctid Context id as .* stored here * @return 0 on success -1 on error */ DLT_STATIC DltReturnValue dlt_logstorage_split_apid(char *key, int len, char *apid, char *ctid) { if ((len > (DLT_ID_SIZE + 2)) || (len < 2)) return DLT_RETURN_ERROR; strncpy(apid, key + 1, (len - 2)); strncpy(ctid, ".*", 2); return DLT_RETURN_OK; } /** * dlt_logstorage_split_apid_ctid * * Split keys with Application ID and Context ID * * @param key Key * @param len Key length * @param apid Application ID from key is stored here * @param ctid CContext id from key is stored here * @return 0 on success -1 on error */ DLT_STATIC DltReturnValue dlt_logstorage_split_apid_ctid(char *key, int len, char *apid, char *ctid) { char *tok = NULL; if (len > DLT_OFFLINE_LOGSTORAGE_MAX_KEY_LEN) return DLT_RETURN_ERROR; /* copy apid and ctid */ tok = strtok(key, ":"); if (tok != NULL) strncpy(apid, tok, DLT_ID_SIZE); else return DLT_RETURN_ERROR; tok = strtok(NULL, ":"); if (tok != NULL) strncpy(ctid, tok, DLT_ID_SIZE); else return DLT_RETURN_ERROR; return DLT_RETURN_OK; } /** * dlt_logstorage_split_ecuid_apid * * Split keys with ECU ID and Application ID * * @param key Key * @param len Key length * @param ecuid ECU ID from key stored here * @param apid Application ID from key is stored here * @param ctid Context id as .* stored here * @return 0 on success -1 on error */ DLT_STATIC DltReturnValue dlt_logstorage_split_ecuid_apid(char *key, int len, char *ecuid, char *apid, char *ctid) { char *tok = NULL; if (len > DLT_OFFLINE_LOGSTORAGE_MAX_KEY_LEN) return DLT_RETURN_ERROR; /* copy apid and ctid */ tok = strtok(key, ":"); if (tok != NULL) strncpy(ecuid, tok, DLT_ID_SIZE); else return DLT_RETURN_ERROR; tok = strtok(NULL, ":"); if (tok != NULL) strncpy(apid, tok, DLT_ID_SIZE); else return DLT_RETURN_ERROR; strncpy(ctid, ".*", 2); return DLT_RETURN_OK; } /** * dlt_logstorage_split_multi * * Prepares keys with application ID alone, will use ecuid if provided * (ecuid\:apid\:\:) or (\:apid\:\:) * * @param key Prepared key stored here * @param len Key length * @param ecuid ECU ID * @param apid Application ID * @param ctid Context ID * @return None */ DLT_STATIC DltReturnValue dlt_logstorage_split_multi(char *key, int len, char *ecuid, char *apid, char *ctid) { char *tok = NULL; if (len > DLT_OFFLINE_LOGSTORAGE_MAX_KEY_LEN) return DLT_RETURN_ERROR; tok = strtok(key, ":"); if (tok == NULL) return DLT_RETURN_ERROR; len = strlen(tok); if (key[len + 1] == ':') { strncpy(ecuid, tok, DLT_ID_SIZE); tok = strtok(NULL, ":"); if (tok != NULL) strncpy(ctid, tok, DLT_ID_SIZE); strncpy(apid, ".*", 2); } else { strncpy(ecuid, tok, DLT_ID_SIZE); tok = strtok(NULL, ":"); strncpy(apid, tok, DLT_ID_SIZE); tok = strtok(NULL, ":"); strncpy(ctid, tok, DLT_ID_SIZE); } return DLT_RETURN_OK; } /** * dlt_logstorage_split_key * * Split a given key into apid and ctid. * If APID\: - apid = APID and ctid = .* * If \:CTID - ctid = CTID and apid = .* * Else apid = APID and ctid = CTID * * @param key Given key of filter hash map * @param apid Application id * @param ctid Context id * @param ecuid ECU id * @return 0 on success, -1 on error */ DLT_STATIC DltReturnValue dlt_logstorage_split_key(char *key, char *apid, char *ctid, char *ecuid) { int len = 0; char *sep = NULL; if ((key == NULL) || (apid == NULL) || (ctid == NULL) || (ecuid == NULL)) return DLT_RETURN_WRONG_PARAMETER; len = strlen(key); sep = strchr (key, ':'); if (sep == NULL) return DLT_RETURN_WRONG_PARAMETER; /* key is ecuid only ecuid::*/ if ((key[len - 1] == ':') && (key[len - 2] == ':')) return dlt_logstorage_split_ecuid(key, len, ecuid, apid, ctid); /* key is context id only ::apid*/ else if ((key[0] == ':') && (key[1] == ':')) return dlt_logstorage_split_ctid(key, len, apid, ctid); /* key is application id only :apid: */ else if ((key[0] == ':') && (key[len - 1] == ':')) return dlt_logstorage_split_apid(key, len, apid, ctid); /* key is :apid:ctid */ else if ((key[0] == ':') && (key[len - 1] != ':')) return dlt_logstorage_split_apid_ctid(key, len, apid, ctid); /* key is ecuid:apid: */ else if ((key[0] != ':') && (key[len - 1] == ':')) return dlt_logstorage_split_ecuid_apid(key, len, ecuid, apid, ctid); /* key is either ecuid::ctid or ecuid:apid:ctid */ else return dlt_logstorage_split_multi(key, len, ecuid, apid, ctid); } /** * Forward SET_LOG_LEVEL request to passive node * * @param daemon_local pointer to DltDaemonLocal structure * @param apid Application ID * @param ctid Context ID * @param ecuid ECU ID * @param loglevel requested log level * @param verbose verbosity flag */ DLT_STATIC DltReturnValue dlt_daemon_logstorage_update_passive_node_context( DltDaemonLocal *daemon_local, char *apid, char *ctid, char *ecuid, int loglevel, int verbose) { DltServiceSetLogLevel req = { 0 }; DltPassiveControlMessage ctrl = { 0 }; DltGatewayConnection *con = NULL; PRINT_FUNCTION_VERBOSE(verbose); if ((daemon_local == NULL) || (apid == NULL) || (ctid == NULL) || (ecuid == NULL) || (loglevel > DLT_LOG_VERBOSE) || (loglevel < DLT_LOG_DEFAULT)) { dlt_vlog(LOG_ERR, "%s: Wrong parameter\n", __func__); return DLT_RETURN_WRONG_PARAMETER; } con = dlt_gateway_get_connection(&daemon_local->pGateway, ecuid, verbose); if (con == NULL) { dlt_vlog(LOG_ERR, "Failed to fond connection to passive node %s\n", ecuid); return DLT_RETURN_ERROR; } ctrl.id = DLT_SERVICE_ID_SET_LOG_LEVEL; ctrl.type = CONTROL_MESSAGE_ON_DEMAND; dlt_set_id(req.apid, apid); dlt_set_id(req.ctid, ctid); req.log_level = loglevel; if (dlt_gateway_send_control_message(con, &ctrl, (void *)&req, verbose) != 0) { dlt_vlog(LOG_ERR, "Failed to forward SET_LOG_LEVEL message to passive node %s\n", ecuid); return DLT_RETURN_ERROR; } return DLT_RETURN_OK; } /** * dlt_daemon_logstorage_send_log_level * * Send new log level for the provided context, if ecuid is not daemon ecuid * update log level of passive node * * @param daemon DltDaemon structure * @param daemon_local DltDaemonLocal structure * @param context DltDaemonContext structure * @param ecuid ECU id * @param loglevel log level to be set to context * @param verbose If set to true verbose information is printed out * @return 0 on success, -1 on error */ DLT_STATIC DltReturnValue dlt_daemon_logstorage_send_log_level(DltDaemon *daemon, DltDaemonLocal *daemon_local, DltDaemonContext *context, char *ecuid, int loglevel, int verbose) { int old_log_level = -1; int ll = DLT_LOG_DEFAULT; if ((daemon == NULL) || (daemon_local == NULL) || (ecuid == NULL) || (context == NULL) || (loglevel > DLT_LOG_VERBOSE) || (loglevel < DLT_LOG_DEFAULT)) { dlt_vlog(LOG_ERR, "%s: Wrong parameter\n", __func__); return DLT_RETURN_WRONG_PARAMETER; } if (strncmp(ecuid, daemon->ecuid, DLT_ID_SIZE) == 0) { old_log_level = context->storage_log_level; context->storage_log_level = DLT_OFFLINE_LOGSTORAGE_MAX(loglevel, context->storage_log_level); if (context->storage_log_level > old_log_level) { if (dlt_daemon_user_send_log_level(daemon, context, verbose) == -1) { dlt_log(LOG_ERR, "Unable to update log level\n"); return DLT_RETURN_ERROR; } } } else { old_log_level = context->log_level; ll = DLT_OFFLINE_LOGSTORAGE_MAX(loglevel, context->log_level); if (ll > old_log_level) return dlt_daemon_logstorage_update_passive_node_context(daemon_local, context->apid, context->ctid, ecuid, ll, verbose); } return DLT_RETURN_OK; } /** * dlt_daemon_logstorage_reset_log_level * * The log levels are reset if log level provided is -1 (not sent to * application in this case). Reset and sent to application if current log level * provided is 0. * * @param daemon DltDaemon structure * @param daemon_local DltDaemonLocal structure * @param context DltDaemonContext structure * @param ecuid ECU ID * @param loglevel log level to be set to context * @param verbose If set to true verbose information is printed out * @return 0 on success, -1 on error */ DLT_STATIC DltReturnValue dlt_daemon_logstorage_reset_log_level(DltDaemon *daemon, DltDaemonLocal *daemon_local, DltDaemonContext *context, char *ecuid, int loglevel, int verbose) { if ((daemon == NULL) || (daemon_local == NULL) || (ecuid == NULL) || (context == NULL) || (loglevel > DLT_LOG_VERBOSE) || (loglevel < DLT_LOG_DEFAULT)) { dlt_vlog(LOG_ERR, "%s: Wrong parameter\n", __func__); return DLT_RETURN_WRONG_PARAMETER; } /* Set storage level to -1, to clear log levels */ context->storage_log_level = DLT_LOG_DEFAULT; if (loglevel == DLT_DAEMON_LOGSTORAGE_RESET_SEND_LOGLEVEL) { if (strncmp(ecuid, daemon->ecuid, DLT_ID_SIZE) == 0) { if (dlt_daemon_user_send_log_level(daemon, context, verbose) == DLT_RETURN_ERROR) { dlt_log(LOG_ERR, "Unable to update log level\n"); return DLT_RETURN_ERROR; } } else { /* forward set log level to passive node */ return dlt_daemon_logstorage_update_passive_node_context(daemon_local, context->apid, context->ctid, ecuid, DLT_LOG_DEFAULT, verbose); } } return DLT_RETURN_OK; } /** * dlt_daemon_logstorage_force_reset_level * * Force resetting of log level since have no data provided by passive node. * * @param daemon DltDaemon structure * @param daemon_local DltDaemonLocal structure * @param apid Application ID * @param ctid Context ID * @param ecuid ECU ID * @param loglevel log level to be set to context * @param verbose If set to true verbose information is printed out * @return 0 on success, -1 on error */ DLT_STATIC DltReturnValue dlt_daemon_logstorage_force_reset_level(DltDaemon *daemon, DltDaemonLocal *daemon_local, char *apid, char *ctid, char *ecuid, int loglevel, int verbose) { int ll = DLT_LOG_DEFAULT; int num = 0; int i = 0; DltLogStorageFilterConfig *config[DLT_CONFIG_FILE_SECTIONS_MAX] = { 0 }; if ((daemon == NULL) || (daemon_local == NULL) || (ecuid == NULL) || (apid == NULL) || (ctid == NULL) || (loglevel > DLT_LOG_VERBOSE) || (loglevel < DLT_LOG_DEFAULT)) { dlt_vlog(LOG_ERR, "%s: Wrong parameter\n", __func__); return DLT_RETURN_WRONG_PARAMETER; } for (i = 0; i < daemon_local->flags.offlineLogstorageMaxDevices; i++) { num = dlt_logstorage_get_config(&(daemon->storage_handle[i]), config, apid, ctid, ecuid); if (num > 0) break; /* found config */ } if ((num == 0) || (config[0] == NULL)) { dlt_vlog(LOG_ERR, "%s: No information about APID: %s, CTID: %s, ECU: %s in Logstorage configuration\n", __func__, apid, ctid, ecuid); return DLT_RETURN_ERROR; } if (loglevel == DLT_DAEMON_LOGSTORAGE_RESET_SEND_LOGLEVEL) ll = config[0]->reset_log_level; else ll = config[0]->log_level; return dlt_daemon_logstorage_update_passive_node_context(daemon_local, apid, ctid, ecuid, ll, verbose); } /** * dlt_logstorage_update_all_contexts * * Update log level of all contexts of the application by updating the daemon * internal table. The compare flags (cmp_flag) indicates if Id has to be * compared with application id or Context id of the daemon internal table. * The log levels are reset if current log level provided is -1 (not sent to * application in this case). Reset and sent to application if current log level * provided is 0. * * @param daemon DltDaemon structure * @param daemon_local DltDaemonLocal structure * @param id application id or context id * @param curr_log_level log level to be set to context * @param cmp_flag compare flag (1 id is apid, 2 id is ctid) * @param ecuid ecu id where application runs * @param verbose If set to true verbose information is printed out * @return 0 on success, -1 on error */ DltReturnValue dlt_logstorage_update_all_contexts(DltDaemon *daemon, DltDaemonLocal *daemon_local, char *id, int curr_log_level, int cmp_flag, char *ecuid, int verbose) { DltDaemonRegisteredUsers *user_list = NULL; int i = 0; char tmp_id[DLT_ID_SIZE + 1] = { '\0' }; if ((daemon == NULL) || (daemon_local == NULL) || (id == NULL) || (ecuid == NULL) || (cmp_flag < DLT_DAEMON_LOGSTORAGE_CMP_APID) || (cmp_flag > DLT_DAEMON_LOGSTORAGE_CMP_CTID)) { dlt_vlog(LOG_ERR, "Wrong parameter in function %s\n", __func__); return DLT_RETURN_WRONG_PARAMETER; } user_list = dlt_daemon_find_users_list(daemon, ecuid, verbose); if (user_list == NULL) return DLT_RETURN_ERROR; for (i = 0; i < user_list->num_contexts; i++) { if (cmp_flag == 1) dlt_set_id(tmp_id, user_list->contexts[i].apid); else dlt_set_id(tmp_id, user_list->contexts[i].ctid); if (strncmp(id, tmp_id, DLT_ID_SIZE) == 0) { if (curr_log_level > 0) dlt_daemon_logstorage_send_log_level(daemon, daemon_local, &user_list->contexts[i], ecuid, curr_log_level, verbose); else /* The request is to reset log levels */ dlt_daemon_logstorage_reset_log_level(daemon, daemon_local, &user_list->contexts[i], ecuid, curr_log_level, verbose); } } return DLT_RETURN_OK; } /** * dlt_logstorage_update_context * * Update log level of a context by updating the daemon internal table * The log levels are reset if current log level provided is -1 (not sent to * application in this case) * Reset and sent to application if current log level provided is 0 * * @param daemon DltDaemon structure * @param daemon_local DltDaemonLocal structure * @param apid application id * @param ctid context id * @param ecuid ecu id * @param curr_log_level log level to be set to context * @param verbose If set to true verbose information is printed out * @return 0 on success, -1 on error */ DltReturnValue dlt_logstorage_update_context(DltDaemon *daemon, DltDaemonLocal *daemon_local, char *apid, char *ctid, char *ecuid, int curr_log_level, int verbose) { DltDaemonContext *context = NULL; if ((daemon == NULL) || (daemon_local == NULL) || (apid == NULL) || (ctid == NULL) || (ecuid == NULL)) { dlt_vlog(LOG_ERR, "Wrong parameter in function %s\n", __func__); return DLT_RETURN_WRONG_PARAMETER; } context = dlt_daemon_context_find(daemon, apid, ctid, ecuid, verbose); if (context != NULL) { if (curr_log_level > 0) return dlt_daemon_logstorage_send_log_level(daemon, daemon_local, context, ecuid, curr_log_level, verbose); else /* The request is to reset log levels */ return dlt_daemon_logstorage_reset_log_level(daemon, daemon_local, context, ecuid, curr_log_level, verbose); } else { if (strncmp(ecuid, daemon->ecuid, DLT_ID_SIZE) != 0) { /* we intentionally have no data provided by passive node. */ /* We blindly send the log level or reset log level */ return dlt_daemon_logstorage_force_reset_level(daemon, daemon_local, apid, ctid, ecuid, curr_log_level, verbose); } else { dlt_vlog(LOG_WARNING, "%s: No information about APID: %s, CTID: %s, ECU: %s\n", __func__, apid, ctid, ecuid); return DLT_RETURN_ERROR; } } return DLT_RETURN_OK; } /** * dlt_logstorage_update_context_loglevel * * Update all contexts or particular context depending provided key * * @param daemon Pointer to DLT Daemon structure * @param daemon_local Pointer to DLT Daemon Local structure * @param key Filter key stored in Hash Map * @param curr_log_level log level to be set to context * @param verbose If set to true verbose information is printed out * @return 0 on success, -1 on error */ DltReturnValue dlt_logstorage_update_context_loglevel(DltDaemon *daemon, DltDaemonLocal *daemon_local, char *key, int curr_log_level, int verbose) { int cmp_flag = 0; char apid[DLT_ID_SIZE + 1] = { '\0' }; char ctid[DLT_ID_SIZE + 1] = { '\0' }; char ecuid[DLT_ID_SIZE + 1] = { '\0' }; PRINT_FUNCTION_VERBOSE(verbose); if ((daemon == NULL) || (daemon_local == NULL) || (key == NULL)) return DLT_RETURN_WRONG_PARAMETER; if (dlt_logstorage_split_key(key, apid, ctid, ecuid) != 0) { dlt_log(LOG_ERR, "Error while updating application log levels (split key)\n"); return DLT_RETURN_ERROR; } if (ecuid[0] == '\0') /* ECU id was not specified in filter configuration */ dlt_set_id(ecuid, daemon->ecuid); /* wildcard for context id, find all contexts of given application id */ if (strcmp(ctid, ".*") == 0) { cmp_flag = DLT_DAEMON_LOGSTORAGE_CMP_APID; if (dlt_logstorage_update_all_contexts(daemon, daemon_local, apid, curr_log_level, cmp_flag, ecuid, verbose) != 0) return DLT_RETURN_ERROR; } /* wildcard for application id, find all contexts with context id */ else if (strcmp(apid, ".*") == 0) { cmp_flag = DLT_DAEMON_LOGSTORAGE_CMP_CTID; if (dlt_logstorage_update_all_contexts(daemon, daemon_local, ctid, curr_log_level, cmp_flag, ecuid, verbose) != 0) return DLT_RETURN_ERROR; } /* In case of given application id, context id pair, call available context * find function */ else if (dlt_logstorage_update_context(daemon, daemon_local, apid, ctid, ecuid, curr_log_level, verbose) != 0) { return DLT_RETURN_ERROR; } return DLT_RETURN_OK; } /** * dlt_daemon_logstorage_reset_application_loglevel * * Reset storage log level of all running applications * 2 steps for resetting * 1. Setup storage_loglevel of all contexts configured for the requested device * to -1 * 2. Re-run update log level for all other configured devices * * @param daemon Pointer to DLT Daemon structure * @param daemon_local Pointer to DLT Daemon local structure * @param dev_num Number of attached DLT Logstorage device * @param max_device Maximum storage devices setup by the daemon * @param verbose If set to true verbose information is printed out */ void dlt_daemon_logstorage_reset_application_loglevel(DltDaemon *daemon, DltDaemonLocal *daemon_local, int dev_num, int max_device, int verbose) { DltLogStorage *handle = NULL; DltLogStorageFilterList **tmp = NULL; int i = 0; char key[DLT_OFFLINE_LOGSTORAGE_MAX_KEY_LEN + 1] = { '\0' }; int num_device_configured = 0; unsigned int status; int log_level = 0; PRINT_FUNCTION_VERBOSE(verbose); if ((daemon == NULL) || (daemon_local == NULL) || (daemon->storage_handle == NULL) || (dev_num < 0)) { dlt_vlog(LOG_ERR, "Invalid function parameters used for %s\n", __func__); return; } handle = &(daemon->storage_handle[dev_num]); if ((handle->connection_type != DLT_OFFLINE_LOGSTORAGE_DEVICE_CONNECTED) || (handle->config_status != DLT_OFFLINE_LOGSTORAGE_CONFIG_DONE)) return; /* First, check number of devices configured */ for (i = 0; i < max_device; i++) { status = daemon->storage_handle[i].config_status; if (status == DLT_OFFLINE_LOGSTORAGE_CONFIG_DONE) num_device_configured++; } /* for all filters (keys) check if application context are already running * and log level need to be reset*/ tmp = &(handle->config_list); while (*(tmp) != NULL) { for (i = 0; i < (*tmp)->num_keys; i++) { memset(key, 0, sizeof(key)); strncpy(key, ((*tmp)->key_list + (i * DLT_OFFLINE_LOGSTORAGE_MAX_KEY_LEN)), DLT_OFFLINE_LOGSTORAGE_MAX_KEY_LEN); if (num_device_configured == 1) { /* Reset context log level and send to application */ log_level = DLT_DAEMON_LOGSTORAGE_RESET_SEND_LOGLEVEL; } else { /** * Reset context log level do not send to application as other * devices can have same configuration * */ log_level = DLT_DAEMON_LOGSTORAGE_RESET_LOGLEVEL; } dlt_logstorage_update_context_loglevel( daemon, daemon_local, key, log_level, verbose); } tmp = &(*tmp)->next; } /* Re-run update log level for all other configured devices */ for (i = 0; i < max_device; i++) { status = daemon->storage_handle[i].config_status; if (i == dev_num) continue; if (status == DLT_OFFLINE_LOGSTORAGE_CONFIG_DONE) dlt_daemon_logstorage_update_application_loglevel(daemon, daemon_local, i, verbose); } return; } /** * dlt_daemon_logstorage_update_application_loglevel * * Update log level of all running applications with new filter configuration * available due to newly attached DltLogstorage device. The log level is only * updated when the current application log level is less than the log level * obtained from the storage configuration file * * @param daemon Pointer to DLT Daemon structure * @param daemon_local Pointer to DLT Daemon local structure * @param dev_num Number of attached DLT Logstorage device * @param verbose If set to true verbose information is printed out */ void dlt_daemon_logstorage_update_application_loglevel(DltDaemon *daemon, DltDaemonLocal *daemon_local, int dev_num, int verbose) { DltLogStorage *handle = NULL; DltLogStorageFilterList **tmp = NULL; char key[DLT_OFFLINE_LOGSTORAGE_MAX_KEY_LEN + 1] = { '\0' }; int i = 0; int log_level = 0; PRINT_FUNCTION_VERBOSE(verbose); if ((daemon == NULL) || (daemon_local == NULL) || (dev_num < 0)) { dlt_vlog(LOG_ERR, "Invalid function parameters used for %s\n", __func__); return; } handle = &(daemon->storage_handle[dev_num]); if ((handle->connection_type != DLT_OFFLINE_LOGSTORAGE_DEVICE_CONNECTED) || (handle->config_status != DLT_OFFLINE_LOGSTORAGE_CONFIG_DONE)) return; /* for all filters (keys) check if application or context already running * and log level need to be updated*/ tmp = &(handle->config_list); while (*(tmp) != NULL) { for (i = 0; i < (*tmp)->num_keys; i++) { memset(key, 0, sizeof(key)); strncpy(key, ((*tmp)->key_list + (i * DLT_OFFLINE_LOGSTORAGE_MAX_KEY_LEN)), DLT_OFFLINE_LOGSTORAGE_MAX_KEY_LEN); /* Obtain storage configuration data */ log_level = dlt_logstorage_get_loglevel_by_key(handle, key); if (log_level < 0) { dlt_log(LOG_ERR, "Failed to get log level by key \n"); return; } /* Update context log level with storage configuration log level */ dlt_logstorage_update_context_loglevel(daemon, daemon_local, key, log_level, verbose); } tmp = &(*tmp)->next; } return; } /** * dlt_daemon_logstorage_get_loglevel * * Obtain log level as a union of all configured storage devices and filters for * the provided application id and context id * * @param daemon Pointer to DLT Daemon structure * @param max_device Maximum storage devices setup by the daemon * @param apid Application ID * @param ctid Context ID * @return Log level on success, -1 on error */ int dlt_daemon_logstorage_get_loglevel(DltDaemon *daemon, int max_device, char *apid, char *ctid) { DltLogStorageFilterConfig *config[DLT_CONFIG_FILE_SECTIONS_MAX] = { 0 }; int i = 0; int j = 0; int8_t storage_loglevel = -1; int8_t configured_loglevel = -1; int num_config = 0; if ((daemon == NULL) || (max_device == 0) || (apid == NULL) || (ctid == NULL)) return DLT_RETURN_WRONG_PARAMETER; for (i = 0; i < max_device; i++) if (daemon->storage_handle[i].config_status == DLT_OFFLINE_LOGSTORAGE_CONFIG_DONE) { num_config = dlt_logstorage_get_config(&(daemon->storage_handle[i]), config, apid, ctid, daemon->ecuid); if (num_config == 0) { dlt_log(LOG_DEBUG, "No valid filter configuration found\n"); continue; } for (j = 0; j < num_config; j++) { if (config[j] == NULL) continue; /* If logstorage configuration do not contain file name, * then it is non verbose control filter, so return level as in this filter */ if (config[j]->file_name == NULL) { storage_loglevel = config[j]->log_level; break; } configured_loglevel = config[j]->log_level; storage_loglevel = DLT_OFFLINE_LOGSTORAGE_MAX( configured_loglevel, storage_loglevel); } } return storage_loglevel; } /** * dlt_daemon_logstorage_write * * Write log message to all attached storage device. If the called * dlt_logstorage_write function is not able to write to the device, DltDaemon * will disconnect this device. * * @param daemon Pointer to Dlt Daemon structure * @param user_config DltDaemon configuration * @param data1 message header buffer * @param size1 message header buffer size * @param data2 message extended header buffer * @param size2 message extended header size * @param data3 message data buffer * @param size3 message data size */ void dlt_daemon_logstorage_write(DltDaemon *daemon, DltDaemonFlags *user_config, unsigned char *data1, int size1, unsigned char *data2, int size2, unsigned char *data3, int size3) { int i = 0; DltLogStorageUserConfig file_config; if ((daemon == NULL) || (user_config == NULL) || (user_config->offlineLogstorageMaxDevices <= 0) || (data1 == NULL) || (data2 == NULL) || (data3 == NULL)) { dlt_vlog(LOG_DEBUG, "%s: message type is not LOG. Skip storing.\n", __func__); return; /* Log Level changed callback */ } /* Copy user configuration */ file_config.logfile_timestamp = user_config->offlineLogstorageTimestamp; file_config.logfile_delimiter = user_config->offlineLogstorageDelimiter; file_config.logfile_maxcounter = user_config->offlineLogstorageMaxCounter; file_config.logfile_counteridxlen = user_config->offlineLogstorageMaxCounterIdx; for (i = 0; i < user_config->offlineLogstorageMaxDevices; i++) if (daemon->storage_handle[i].config_status == DLT_OFFLINE_LOGSTORAGE_CONFIG_DONE) { if (dlt_logstorage_write(&(daemon->storage_handle[i]), &file_config, data1, size1, data2, size2, data3, size3) != 0) { dlt_log(LOG_ERR, "dlt_daemon_logstorage_write: failed. " "Disable storage device\n"); /* DLT_OFFLINE_LOGSTORAGE_MAX_WRITE_ERRORS happened, * therefore remove logstorage device */ dlt_logstorage_device_disconnected( &(daemon->storage_handle[i]), DLT_LOGSTORAGE_SYNC_ON_DEVICE_DISCONNECT); } } } /** * dlt_daemon_logstorage_setup_internal_storage * * Setup user defined path as offline log storage device * * @param daemon Pointer to Dlt Daemon structure * @param daemon_local Pointer to Dlt Daemon local structure * @param path User configured internal storage path * @param verbose If set to true verbose information is printed out * @return 0 on sucess, -1 otherwise */ int dlt_daemon_logstorage_setup_internal_storage(DltDaemon *daemon, DltDaemonLocal *daemon_local, char *path, int verbose) { int ret = 0; PRINT_FUNCTION_VERBOSE(verbose); if ((path == NULL) || (daemon == NULL)) return DLT_RETURN_WRONG_PARAMETER; /* connect internal storage device */ /* Device index always used as 0 as it is setup on DLT daemon startup */ ret = dlt_logstorage_device_connected(&(daemon->storage_handle[0]), path); if (ret != 0) { dlt_vlog(LOG_ERR, "%s: Device connect failed\n", __func__); return DLT_RETURN_ERROR; } /* check if log level of running application need an update */ dlt_daemon_logstorage_update_application_loglevel(daemon, daemon_local, 0, verbose); return ret; } void dlt_daemon_logstorage_set_logstorage_cache_size(unsigned int size) { /* store given [KB] size in [Bytes] */ g_logstorage_cache_max = size * 1024; } int dlt_daemon_logstorage_cleanup(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose) { int i = 0; PRINT_FUNCTION_VERBOSE(verbose); if ((daemon == NULL) || (daemon_local == NULL) || (daemon->storage_handle == NULL)) return DLT_RETURN_WRONG_PARAMETER; for (i = 0; i < daemon_local->flags.offlineLogstorageMaxDevices; i++) /* call disconnect on all currently connected devices */ if (daemon->storage_handle[i].connection_type == DLT_OFFLINE_LOGSTORAGE_DEVICE_CONNECTED) { (&daemon->storage_handle[i])->uconfig.logfile_counteridxlen = daemon_local->flags.offlineLogstorageMaxCounterIdx; (&daemon->storage_handle[i])->uconfig.logfile_delimiter = daemon_local->flags.offlineLogstorageDelimiter; (&daemon->storage_handle[i])->uconfig.logfile_maxcounter = daemon_local->flags.offlineLogstorageMaxCounter; (&daemon->storage_handle[i])->uconfig.logfile_timestamp = daemon_local->flags.offlineLogstorageTimestamp; dlt_logstorage_device_disconnected( &daemon->storage_handle[i], DLT_LOGSTORAGE_SYNC_ON_DAEMON_EXIT); } return 0; } int dlt_daemon_logstorage_sync_cache(DltDaemon *daemon, DltDaemonLocal *daemon_local, char *mnt_point, int verbose) { int i = 0; DltLogStorage *handle = NULL; PRINT_FUNCTION_VERBOSE(verbose); if ((daemon == NULL) || (daemon_local == NULL) || (mnt_point == NULL)) return DLT_RETURN_WRONG_PARAMETER; if (strlen(mnt_point) > 0) { /* mount point is given */ handle = dlt_daemon_logstorage_get_device(daemon, daemon_local, mnt_point, verbose); if (handle == NULL) { return DLT_RETURN_ERROR; } else { handle->uconfig.logfile_counteridxlen = daemon_local->flags.offlineLogstorageMaxCounterIdx; handle->uconfig.logfile_delimiter = daemon_local->flags.offlineLogstorageDelimiter; handle->uconfig.logfile_maxcounter = daemon_local->flags.offlineLogstorageMaxCounter; handle->uconfig.logfile_timestamp = daemon_local->flags.offlineLogstorageTimestamp; if (dlt_logstorage_sync_caches(handle) != 0) return DLT_RETURN_ERROR; } } else { /* sync caches for all connected logstorage devices */ for (i = 0; i < daemon_local->flags.offlineLogstorageMaxDevices; i++) if (daemon->storage_handle[i].connection_type == DLT_OFFLINE_LOGSTORAGE_DEVICE_CONNECTED) { daemon->storage_handle[i].uconfig.logfile_counteridxlen = daemon_local->flags.offlineLogstorageMaxCounterIdx; daemon->storage_handle[i].uconfig.logfile_delimiter = daemon_local->flags.offlineLogstorageDelimiter; daemon->storage_handle[i].uconfig.logfile_maxcounter = daemon_local->flags.offlineLogstorageMaxCounter; daemon->storage_handle[i].uconfig.logfile_timestamp = daemon_local->flags.offlineLogstorageTimestamp; if (dlt_logstorage_sync_caches(&daemon->storage_handle[i]) != 0) return DLT_RETURN_ERROR; } } return 0; } DltLogStorage *dlt_daemon_logstorage_get_device(DltDaemon *daemon, DltDaemonLocal *daemon_local, char *mnt_point, int verbose) { int i = 0; int len = 0; int len1 = 0; int len2 = 0; PRINT_FUNCTION_VERBOSE(verbose); if ((daemon == NULL) || (daemon_local == NULL) || (mnt_point == NULL)) return NULL; len1 = strlen(mnt_point); for (i = 0; i < daemon_local->flags.offlineLogstorageMaxDevices; i++) { len2 = strlen(daemon->storage_handle[i].device_mount_point); /* Check if the requested device path is already used as log storage * device. Check for strlen first, to avoid comparison errors when * final '/' is given or not */ len = len1 > len2 ? len2 : len1; if (strncmp(daemon->storage_handle[i].device_mount_point, mnt_point, len) == 0) return &daemon->storage_handle[i]; } return NULL; } dlt-daemon-2.18.4/src/daemon/dlt_daemon_offline_logstorage.h000066400000000000000000000220001353342203500240650ustar00rootroot00000000000000/** * Copyright (C) 2013 - 2015 Advanced Driver Information Technology. * This code is developed by Advanced Driver Information Technology. * Copyright of Advanced Driver Information Technology, Bosch and DENSO. * * DLT offline log storage functionality header file. * * \copyright * This Source Code Form is subject to the terms of the * Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with * this file, You can obtain one at http://mozilla.org/MPL/2.0/. * * * \author Syed Hameed ADIT 2013 - 2015 * \author Christoph Lipka ADIT 2015 * * \file: dlt_daemon_offline_logstorage.h * For further information see http://www.genivi.org/. */ /******************************************************************************* * ** * SRC-MODULE: dlt_daemon_offline_logstorage.h ** * ** * TARGET : linux ** * ** * PROJECT : DLT ** * ** * AUTHOR : Syed Hameed shameed@jp.adit-jv.com ** * Christoph Lipka clipka@jp.adit-jv.com ** * PURPOSE : ** * ** * REMARKS : ** * ** * PLATFORM DEPENDANT [yes/no]: yes ** * ** * TO BE CHANGED BY USER [yes/no]: no ** * ** ******************************************************************************/ /******************************************************************************* * Author Identity ** ******************************************************************************* * ** * Initials Name Company ** * -------- ------------------------- ---------------------------------- ** * sh Syed Hameed ADIT ** * cl Christoph Lipka ADIT ** *******************************************************************************/ #ifndef DLT_DAEMON_OFFLINE_LOGSTORAGE_H #define DLT_DAEMON_OFFLINE_LOGSTORAGE_H #include "dlt-daemon.h" #include "dlt_daemon_common.h" #include "dlt_offline_logstorage.h" #define DLT_DAEMON_LOGSTORAGE_RESET_LOGLEVEL -1 #define DLT_DAEMON_LOGSTORAGE_RESET_SEND_LOGLEVEL 0 #define DLT_DAEMON_LOGSTORAGE_CMP_APID 1 #define DLT_DAEMON_LOGSTORAGE_CMP_CTID 2 /** * dlt_daemon_logstorage_get_loglevel * * Obtain log level as a union of all configured storage devices and filters for * the provided application id and context id * * @param daemon Pointer to DLT Daemon structure * @param max_device Maximum storage devices setup by the daemon * @param apid Application ID * @param ctid Context ID * @return Log level on success, -1 on error */ int dlt_daemon_logstorage_get_loglevel(DltDaemon *daemon, int max_device, char *apid, char *ctid); /** * dlt_daemon_logstorage_reset_application_loglevel * * Reset storage log level of all running applications with -1 * * @param daemon Pointer to DLT Daemon structure * @param daemon_local Pointer to DLT Daemon local structure * @param dev_num Number of attached DLT Logstorage device * @param verbose If set to true verbose information is printed out */ void dlt_daemon_logstorage_reset_application_loglevel(DltDaemon *daemon, DltDaemonLocal *daemon_local, int dev_num, int max_device, int verbose); /** * dlt_daemon_logstorage_update_application_loglevel * * Update log level of all running applications with new filter configuration * available due to newly attached DltLogstorage device. The log level is only * updated when the current application log level is less than the log level * obtained from the storage configuration file. * * @param daemon Pointer to DLT Daemon structure * @param daemon_local Pointer to DLT Daemon local structure * @param dev_num Number of attached DLT Logstorage device * @param verbose if set to true verbose information is printed out */ void dlt_daemon_logstorage_update_application_loglevel(DltDaemon *daemon, DltDaemonLocal *daemon_local, int dev_num, int verbose); /** * dlt_daemon_logstorage_write * * Write log message to all attached storage device. If the called * dlt_logstorage_write function is not able to write to the device, * DltDaemon will disconnect this device. * * @param daemon Pointer to Dlt Daemon structure * @param user_config DltDaemon configuration * @param data1 message header buffer * @param size1 message header buffer size * @param data2 message extended data buffer * @param size2 message extended data size * @param data3 message data buffer * @param size3 message data size */ void dlt_daemon_logstorage_write(DltDaemon *daemon, DltDaemonFlags *user_config, unsigned char *data1, int size1, unsigned char *data2, int size2, unsigned char *data3, int size3); /** * dlt_daemon_logstorage_setup_internal_storage * * Setup user defined path as offline log storage device * * @param daemon Pointer to Dlt Daemon structure * @param daemon_local Pointer to Dlt Daemon Local structure * @param path User configured internal storage path * @param verbose If set to true verbose information is printed out */ int dlt_daemon_logstorage_setup_internal_storage(DltDaemon *daemon, DltDaemonLocal *daemon_local, char *path, int verbose); /** * Set max size of logstorage cache. Stored internally in bytes * * @param size Size of logstorage cache [in KB] */ void dlt_daemon_logstorage_set_logstorage_cache_size(unsigned int size); /** * Cleanup dlt logstorage * * @param daemon Pointer to Dlt Daemon structure * @param daemon_local Pointer to Dlt Daemon Local structure * @param verbose If set to true verbose information is printed out */ int dlt_daemon_logstorage_cleanup(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose); /** * Sync logstorage caches * * @param daemon Pointer to Dlt Daemon structure * @param daemon_local Pointer to Dlt Daemon Local structure * @param mnt_point Logstorage device mount point * @param verbose If set to true verbose information is printed out * @return 0 on success, -1 otherwise */ int dlt_daemon_logstorage_sync_cache(DltDaemon *daemon, DltDaemonLocal *daemon_local, char *mnt_point, int verbose); /** * dlt_logstorage_get_device * * Get a Logstorage device handle for given the mount point. * * @param daemon Pointer to Dlt Daemon structure * @param daemon_local Pointer to Dlt Daemon Local structure * @param mnt_point Logstorage device mount point * @param verbose If set to true verbose information is printed out * @return handle to Logstorage device on success, NULL otherwise */ DltLogStorage *dlt_daemon_logstorage_get_device(DltDaemon *daemon, DltDaemonLocal *daemon_local, char *mnt_point, int verbose); #endif /* DLT_DAEMON_OFFLINE_LOGSTORAGE_H */ dlt-daemon-2.18.4/src/daemon/dlt_daemon_offline_logstorage_internal.h000066400000000000000000000105021353342203500257650ustar00rootroot00000000000000/** * Copyright (C) 2018 Advanced Driver Information Technology. * This code is developed by Advanced Driver Information Technology. * Copyright of Advanced Driver Information Technology, Bosch and DENSO. * * DLT offline log storage functionality internal header file. * * \copyright * This Source Code Form is subject to the terms of the * Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with * this file, You can obtain one at http://mozilla.org/MPL/2.0/. * * * \author Aditya Paluri ADIT 2018 * * \file: dlt_daemon_offline_logstorage_internal.h * For further information see http://www.genivi.org/. */ /******************************************************************************* * ** * SRC-MODULE: dlt_daemon_offline_logstorage_internal.h ** * ** * TARGET : linux ** * ** * PROJECT : DLT ** * ** * AUTHOR : Aditya Paluri venkataaditya.paluri@in.bosch.com ** * PURPOSE : ** * ** * REMARKS : ** * ** * PLATFORM DEPENDANT [yes/no]: yes ** * ** * TO BE CHANGED BY USER [yes/no]: no ** * ** ******************************************************************************/ /******************************************************************************* * Author Identity ** ******************************************************************************* * ** * Initials Name Company ** * -------- ------------------------- ---------------------------------- ** * ap Aditya Paluri ADIT ** *******************************************************************************/ #ifndef DLT_DAEMON_OFFLINE_LOGSTORAGE_INTERNAL_H #define DLT_DAEMON_OFFLINE_LOGSTORAGE_INTERNAL_H DLT_STATIC DltReturnValue dlt_logstorage_split_key(char *key, char *apid, char *ctid, char *ecuid); DltReturnValue dlt_logstorage_update_all_contexts(DltDaemon *daemon, DltDaemonLocal *daemon_local, char *id, int curr_log_level, int cmp_flag, char *ecuid, int verbose); DltReturnValue dlt_logstorage_update_context(DltDaemon *daemon, DltDaemonLocal *daemon_local, char *apid, char *ctid, char *ecuid, int curr_log_level, int verbose); DltReturnValue dlt_logstorage_update_context_loglevel(DltDaemon *daemon, DltDaemonLocal *daemon_local, char *key, int curr_log_level, int verbose); #endif dlt-daemon-2.18.4/src/daemon/dlt_daemon_serial.c000066400000000000000000000072451353342203500215050ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2011-2015, BMW AG * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author Alexander Wenzel * * \copyright Copyright © 2011-2015 BMW AG. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file dlt_daemon_serial.c */ /******************************************************************************* ** ** ** SRC-MODULE: dlt_daemon_serial.c ** ** ** ** TARGET : linux ** ** ** ** PROJECT : DLT ** ** ** ** AUTHOR : Alexander Wenzel Alexander.AW.Wenzel@bmw.de ** ** ** ** PURPOSE : ** ** ** ** REMARKS : ** ** ** ** PLATFORM DEPENDANT [yes/no]: yes ** ** ** ** TO BE CHANGED BY USER [yes/no]: no ** ** ** *******************************************************************************/ /******************************************************************************* ** Author Identity ** ******************************************************************************** ** ** ** Initials Name Company ** ** -------- ------------------------- ---------------------------------- ** ** aw Alexander Wenzel BMW ** *******************************************************************************/ #include #include #include #include #include #include #include #include /* send() */ #include /* send() */ #include "dlt-daemon.h" #include "dlt_types.h" #include "dlt_daemon_serial.h" int dlt_daemon_serial_send(int sock, void *data1, int size1, void *data2, int size2, char serialheader) { /* Optional: Send serial header, if requested */ if (serialheader) if (0 > write(sock, dltSerialHeader, sizeof(dltSerialHeader))) return DLT_DAEMON_ERROR_SEND_FAILED; /* Send data */ if (data1 && (size1 > 0)) if (0 > write(sock, data1, size1)) return DLT_DAEMON_ERROR_SEND_FAILED; if (data2 && (size2 > 0)) if (0 > write(sock, data2, size2)) return DLT_DAEMON_ERROR_SEND_FAILED; return DLT_DAEMON_ERROR_OK; } dlt-daemon-2.18.4/src/daemon/dlt_daemon_serial.h000066400000000000000000000061011353342203500215000ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2011-2015, BMW AG * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author Alexander Wenzel * * \copyright Copyright © 2011-2015 BMW AG. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file dlt_daemon_serial.h */ /******************************************************************************* ** ** ** SRC-MODULE: dlt_daemon_serial.h ** ** ** ** TARGET : linux ** ** ** ** PROJECT : DLT ** ** ** ** AUTHOR : Alexander Wenzel Alexander.AW.Wenzel@bmw.de ** ** ** ** PURPOSE : ** ** ** ** REMARKS : ** ** ** ** PLATFORM DEPENDANT [yes/no]: yes ** ** ** ** TO BE CHANGED BY USER [yes/no]: no ** ** ** *******************************************************************************/ /******************************************************************************* ** Author Identity ** ******************************************************************************** ** ** ** Initials Name Company ** ** -------- ------------------------- ---------------------------------- ** ** aw Alexander Wenzel BMW ** *******************************************************************************/ #ifndef DLT_DAEMON_SERIAL_H #define DLT_DAEMON_SERIAL_H #include #include #include "dlt_common.h" #include "dlt_user.h" int dlt_daemon_serial_send(int sock, void *data1, int size1, void *data2, int size2, char serialheader); #endif /* DLT_DAEMON_SERIAL_H */ dlt-daemon-2.18.4/src/daemon/dlt_daemon_socket.c000066400000000000000000000135371353342203500215170ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2011-2015, BMW AG * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author * Alexander Wenzel * Markus Klein * Mikko Rapeli * * \copyright Copyright © 2011-2015 BMW AG. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file dlt_daemon_socket.c */ #include #include #include /* for printf() and fprintf() */ #include /* for socket(), connect(), (), and recv() */ #include /* for sockaddr_in and inet_addr() */ #include /* for atoi() and exit() */ #include /* for memset() */ #include /* for close() */ #include #include #include #include #include #include #ifdef linux # include #endif #include #include #if defined(linux) && defined(__NR_statx) # include #endif #include "dlt_types.h" #include "dlt-daemon.h" #include "dlt-daemon_cfg.h" #include "dlt_daemon_common_cfg.h" #include "dlt_daemon_socket.h" int dlt_daemon_socket_open(int *sock, unsigned int servPort, char *ip) { int yes = 1; int ret_inet_pton = 1; int lastErrno = 0; #ifdef DLT_USE_IPv6 /* create socket */ if ((*sock = socket(AF_INET6, SOCK_STREAM, 0)) == -1) { lastErrno = errno; dlt_vlog(LOG_WARNING, "dlt_daemon_socket_open: socket() error %d: %s\n", lastErrno, strerror(lastErrno)); } #else if ((*sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) { lastErrno = errno; dlt_vlog(LOG_WARNING, "dlt_daemon_socket_open: socket() error %d: %s\n", lastErrno, strerror(lastErrno)); } #endif dlt_vlog(LOG_INFO, "%s: Socket created\n", __FUNCTION__); /* setsockpt SO_REUSEADDR */ if (setsockopt(*sock, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) { lastErrno = errno; dlt_vlog(LOG_WARNING, "dlt_daemon_socket_open: Setsockopt error %d in dlt_daemon_local_connection_init: %s\n", lastErrno, strerror(lastErrno)); } /* bind */ #ifdef DLT_USE_IPv6 struct sockaddr_in6 forced_addr; memset(&forced_addr, 0, sizeof(forced_addr)); forced_addr.sin6_family = AF_INET6; forced_addr.sin6_port = htons(servPort); if (0 == strcmp(ip, "0.0.0.0")) forced_addr.sin6_addr = in6addr_any; else ret_inet_pton = inet_pton(AF_INET6, ip, &forced_addr.sin6_addr); #else struct sockaddr_in forced_addr; memset(&forced_addr, 0, sizeof(forced_addr)); forced_addr.sin_family = AF_INET; forced_addr.sin_port = htons(servPort); ret_inet_pton = inet_pton(AF_INET, ip, &forced_addr.sin_addr); #endif /* inet_pton returns 1 on success */ if (ret_inet_pton != 1) { lastErrno = errno; dlt_vlog(LOG_WARNING, "dlt_daemon_socket_open: inet_pton() error %d: %s. Cannot convert IP address: %s\n", lastErrno, strerror(lastErrno), ip); return -1; } if (bind(*sock, (struct sockaddr *)&forced_addr, sizeof(forced_addr)) == -1) { lastErrno = errno; /*close() may set errno too */ close(*sock); dlt_vlog(LOG_WARNING, "dlt_daemon_socket_open: bind() error %d: %s\n", lastErrno, strerror(lastErrno)); } /*listen */ dlt_vlog(LOG_INFO, "%s: Listening on ip %s and port: %u\n", __FUNCTION__, ip, servPort); /* get socket buffer size */ dlt_vlog(LOG_INFO, "dlt_daemon_socket_open: Socket send queue size: %d\n", dlt_daemon_socket_get_send_qeue_max_size(*sock)); if (listen(*sock, 3) < 0) { lastErrno = errno; dlt_vlog(LOG_WARNING, "dlt_daemon_socket_open: listen() failed with error %d: %s\n", lastErrno, strerror(lastErrno)); return -1; } return 0; /* OK */ } int dlt_daemon_socket_close(int sock) { close(sock); return 0; } int dlt_daemon_socket_send(int sock, void *data1, int size1, void *data2, int size2, char serialheader) { int ret = DLT_RETURN_OK; /* Optional: Send serial header, if requested */ if (serialheader) { ret = dlt_daemon_socket_sendreliable(sock, (void *)dltSerialHeader, sizeof(dltSerialHeader)); if (ret != DLT_RETURN_OK) return ret; } /* Send data */ if ((data1 != NULL) && (size1 > 0)) { ret = dlt_daemon_socket_sendreliable(sock, data1, size1); if (ret != DLT_RETURN_OK) return ret; } if ((data2 != NULL) && (size2 > 0)) ret = dlt_daemon_socket_sendreliable(sock, data2, size2); return ret; } int dlt_daemon_socket_get_send_qeue_max_size(int sock) { int n = 0; socklen_t m = sizeof(n); getsockopt(sock, SOL_SOCKET, SO_SNDBUF, (void *)&n, &m); return n; } int dlt_daemon_socket_sendreliable(int sock, void *data_buffer, int message_size) { int data_sent = 0; while (data_sent < message_size) { ssize_t ret = send(sock, data_buffer + data_sent, message_size - data_sent, 0); if (ret < 0) { dlt_vlog(LOG_WARNING, "dlt_daemon_socket_sendreliable: socket send failed [errno: %d]!\n", errno); return DLT_DAEMON_ERROR_SEND_FAILED; } else { data_sent += ret; } } return DLT_DAEMON_ERROR_OK; } dlt-daemon-2.18.4/src/daemon/dlt_daemon_socket.h000066400000000000000000000071371353342203500215230ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2011-2015, BMW AG * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author Alexander Wenzel * * \copyright Copyright © 2011-2015 BMW AG. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file dlt_daemon_socket.h */ /******************************************************************************* ** ** ** SRC-MODULE: dlt_daemon_socket.h ** ** ** ** TARGET : linux ** ** ** ** PROJECT : DLT ** ** ** ** AUTHOR : Alexander Wenzel Alexander.AW.Wenzel@bmw.de ** ** ** ** PURPOSE : ** ** ** ** REMARKS : ** ** ** ** PLATFORM DEPENDANT [yes/no]: yes ** ** ** ** TO BE CHANGED BY USER [yes/no]: no ** ** ** *******************************************************************************/ /******************************************************************************* ** Author Identity ** ******************************************************************************** ** ** ** Initials Name Company ** ** -------- ------------------------- ---------------------------------- ** ** aw Alexander Wenzel BMW ** *******************************************************************************/ #ifndef DLT_DAEMON_SOCKET_H #define DLT_DAEMON_SOCKET_H #include #include #include "dlt_common.h" #include "dlt_user.h" int dlt_daemon_socket_open(int *sock, unsigned int servPort, char *ip); int dlt_daemon_socket_close(int sock); int dlt_daemon_socket_get_send_qeue_max_size(int sock); int dlt_daemon_socket_send(int sock, void *data1, int size1, void *data2, int size2, char serialheader); /** * @brief dlt_daemon_socket_sendreliable - sends data to socket with additional checks and resending functionality - trying to be reliable * @param sock * @param data_buffer * @param message_size * @return on sucess: DLT_DAEMON_ERROR_OK, on error: DLT_DAEMON_ERROR_SEND_FAILED */ int dlt_daemon_socket_sendreliable(int sock, void *data_buffer, int message_size); #endif /* DLT_DAEMON_SOCKET_H */ dlt-daemon-2.18.4/src/daemon/dlt_daemon_unix_socket.c000066400000000000000000000043411353342203500225530ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2015, Advanced Driver Information Technology * Copyright of Advanced Driver Information Technology, Bosch and Denso * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author * Christoph Lipka * * \copyright Copyright © 2015 ADIT. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file dlt_daemon_unix_socket.c */ #include #include #include #include #include #include #include #include #include #include "dlt-daemon.h" #include "dlt_common.h" #include "dlt-daemon_cfg.h" #include "dlt_daemon_socket.h" #include "dlt_daemon_unix_socket.h" int dlt_daemon_unix_socket_open(int *sock, char *sock_path, int type, int mask) { struct sockaddr_un addr; int old_mask; if ((sock == NULL) || (sock_path == NULL)) { dlt_log(LOG_ERR, "dlt_daemon_unix_socket_open: arguments invalid"); return -1; } if ((*sock = socket(AF_UNIX, type, 0)) == -1) { dlt_log(LOG_WARNING, "unix socket: socket() error"); return -1; } memset(&addr, 0, sizeof(addr)); addr.sun_family = AF_UNIX; memcpy(addr.sun_path, sock_path, sizeof(addr.sun_path)); unlink(sock_path); /* set appropriate access permissions */ old_mask = umask(mask); if (bind(*sock, (struct sockaddr *)&addr, sizeof(addr)) == -1) { dlt_log(LOG_WARNING, "unix socket: bind() error"); return -1; } if (listen(*sock, 1) == -1) { dlt_log(LOG_WARNING, "unix socket: listen error"); return -1; } /* restore permissions */ umask(old_mask); return 0; } int dlt_daemon_unix_socket_close(int sock) { int ret = close(sock); if (ret != 0) { dlt_vlog(LOG_WARNING, "unix socket close failed: %s", strerror(errno)); } return ret; } dlt-daemon-2.18.4/src/daemon/dlt_daemon_unix_socket.h000066400000000000000000000061501353342203500225600ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2015, Advanced Driver Information Technology * Copyright of Advanced Driver Information Technology, Bosch and Denso. * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author Christoph Lipka * * \copyright Copyright © 2015 ADIT. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file dlt_daemon_unix_socket.h */ /******************************************************************************* ** ** ** SRC-MODULE: dlt_daemon_unix_socket.h ** ** ** ** TARGET : linux ** ** ** ** PROJECT : DLT ** ** ** ** AUTHOR : Christoph Lipka clipka@jp.adit-jv.com ** ** ** ** PURPOSE : ** ** ** ** REMARKS : ** ** ** ** PLATFORM DEPENDANT [yes/no]: yes ** ** ** ** TO BE CHANGED BY USER [yes/no]: no ** ** ** *******************************************************************************/ /******************************************************************************* ** Author Identity ** ******************************************************************************** ** ** ** Initials Name Company ** ** -------- ------------------------- ---------------------------------- ** ** cl Christoph Lipka ADIT ** *******************************************************************************/ #ifndef DLT_DAEMON_UNIX_SOCKET_H #define DLT_DAEMON_UNIX_SOCKET_H int dlt_daemon_unix_socket_open(int *sock, char *socket_path, int type, int mask); int dlt_daemon_unix_socket_close(int sock); #endif /* DLT_DAEMON_UNIX_SOCKET_H */ dlt-daemon-2.18.4/src/daemon/udp_connection/000077500000000000000000000000001353342203500206735ustar00rootroot00000000000000dlt-daemon-2.18.4/src/daemon/udp_connection/dlt_daemon_udp_common_socket.h000066400000000000000000000041461353342203500267470ustar00rootroot00000000000000/* * Copyright (c) 2019 LG Electronics Inc. * SPDX-License-Identifier: MPL-2.0 * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author * Guruprasad KN * Sachin Sudhakar Shetty * Sunil Kovila Sampath * * \Copyright (c) 2019 LG Electronics Inc. * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file dlt_daemon_udp_common_socket.h */ #ifndef DLT_DAEMON_UDP_COMMON_SOCKET_H #define DLT_DAEMON_UDP_COMMON_SOCKET_H #include /* for sockaddr_in and inet_addr() */ #include #include #include #include #include /* for atoi() and exit() */ #include /* for memset() */ #include #include /* for socket(), connect(), (), and recv() */ #include #include #include /* for close() */ #include "dlt_common.h" #include "dlt-daemon.h" #include "dlt_daemon_common_cfg.h" #include "dlt_daemon_client.h" #include "dlt_daemon_connection.h" #include "dlt_daemon_udp_socket.h" #include "dlt_types.h" /* #define variables */ #define ADDRESS_VALID 1 #define ADDRESS_INVALID 0 #define SOCKPORT_MAX_LEN 6 /* port range 0-65535 */ #define SYSTEM_CALL_ERROR -1 #define ZERO_BYTE_RECIEVED 0 #define ONE_BYTE_RECIEVED 0 typedef struct sockaddr_storage CLIENT_ADDR_STRUCT; typedef socklen_t CLIENT_ADDR_STRUCT_SIZE; /* udp strutures */ typedef struct { CLIENT_ADDR_STRUCT clientaddr; CLIENT_ADDR_STRUCT_SIZE clientaddr_size; int isvalidflag; } DltDaemonClientSockInfo; /* Function prototype declaration */ void dlt_daemon_udp_init_clientstruct(DltDaemonClientSockInfo *clientinfo_struct); DltReturnValue dlt_daemon_udp_socket_open(int *sock, unsigned int servPort); void dlt_daemon_udp_setmulticast_addr(DltDaemonLocal *daemon_local); #endif /* DLT_DAEMON_UDP_COMMON_SOCKET_H */ dlt-daemon-2.18.4/src/daemon/udp_connection/dlt_daemon_udp_socket.c000066400000000000000000000232541353342203500253730ustar00rootroot00000000000000/* * Copyright (c) 2019 LG Electronics Inc. * SPDX-License-Identifier: MPL-2.0 * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author * Guruprasad KN * Sachin Sudhakar Shetty * Sunil Kovila Sampath * * \Copyright (c) 2019 LG Electronics Inc. * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file dlt_daemon_udp_socket.c */ #include "dlt_daemon_udp_common_socket.h" static void dlt_daemon_udp_clientmsg_send(DltDaemonClientSockInfo *clientinfo, void *data1, int size1, void *data2, int size2, int verbose); static int g_udp_sock_fd = -1; static DltDaemonClientSockInfo g_udpmulticast_addr; /* ************************************************************************** */ /* Function : dlt_daemon_udp_init_clientstruct */ /* In Param : UDP client_info struct to be initilzed */ /* Out Param : NIL */ /* Description: client struct to be initilized to copy control/connect/disconnect */ /* client addr */ /* ************************************************************************** */ void dlt_daemon_udp_init_clientstruct(DltDaemonClientSockInfo *clientinfo_struct) { if (clientinfo_struct == NULL) { dlt_vlog(LOG_ERR, "%s: NULL arg\n", __func__); return; } memset(&clientinfo_struct->clientaddr, 0x00, sizeof(clientinfo_struct->clientaddr)); clientinfo_struct->clientaddr_size = sizeof(clientinfo_struct->clientaddr); clientinfo_struct->isvalidflag = ADDRESS_INVALID; /* info is invalid */ dlt_vlog(LOG_DEBUG, "%s: client addr struct init success \n", __func__); dlt_log(LOG_INFO, "dlt_daemon_udp_init_clientstruct: client addr struct init success \n"); } /* ************************************************************************** */ /* Function : dlt_daemon_udp_setmulticast_addr */ /* In Param : NIL */ /* Out Param : NIL */ /* Description: set the multicast addr to global variables */ /* ************************************************************************** */ void dlt_daemon_udp_setmulticast_addr(DltDaemonLocal *daemon_local) { if (daemon_local == NULL) { dlt_vlog(LOG_ERR, "%s: NULL arg\n", __func__); return; } dlt_daemon_udp_init_clientstruct(&g_udpmulticast_addr); struct sockaddr_in clientaddr; clientaddr.sin_family = AF_INET; inet_pton(AF_INET, daemon_local->UDPMulticastIPAddress, &clientaddr.sin_addr); clientaddr.sin_port = htons(daemon_local->UDPMulticastIPPort); memcpy(&g_udpmulticast_addr.clientaddr, &clientaddr, sizeof(struct sockaddr_in)); g_udpmulticast_addr.clientaddr_size = sizeof(g_udpmulticast_addr.clientaddr); g_udpmulticast_addr.isvalidflag = ADDRESS_VALID; } /* ************************************************************************** */ /* Function : dlt_daemon_udp_connection_setup */ /* In Param : contains daemon param values used globally */ /* Out Param : status of udp connection setup and fd registration */ /* Description: DataGram socket fd connection is setup */ /* fd is registered with the epoll */ /* ************************************************************************** */ DltReturnValue dlt_daemon_udp_connection_setup(DltDaemonLocal *daemon_local) { int fd = DLT_FD_INIT; DltReturnValue ret_val = DLT_RETURN_WRONG_PARAMETER; if (daemon_local == NULL) return ret_val; if ((ret_val = dlt_daemon_udp_socket_open(&fd, daemon_local->flags.port)) != DLT_RETURN_OK) { dlt_log(LOG_ERR, "Could not initialize udp socket.\n"); } else { /* assign to global udp fd */ g_udp_sock_fd = fd; /* set global multicast addr */ dlt_daemon_udp_setmulticast_addr(daemon_local); dlt_log(LOG_DEBUG, "initialize udp socket success\n"); } return ret_val; } /* ************************************************************************** */ /* Function : dlt_daemon_udp_socket_open */ /* In Param : contains udp port number */ /* Out Param : status of udp connection setup */ /* Description: This funtion is used to setup DGRAM connection */ /* does socket()->bind() on udp port */ /* ************************************************************************** */ DltReturnValue dlt_daemon_udp_socket_open(int *sock, unsigned int servPort) { int enable_reuse_addr = 1; int sockbuffer = DLT_DAEMON_RCVBUFSIZESOCK; char portnumbuffer[SOCKPORT_MAX_LEN] = { 0 }; struct addrinfo hints; struct addrinfo *servinfo = NULL; struct addrinfo *addrinfo_iterator = NULL; int getaddrinfo_errorcode = -1; if (sock == NULL) return DLT_RETURN_WRONG_PARAMETER; memset(&hints, 0, sizeof hints); #ifdef DLT_USE_IPv6 hints.ai_family = AF_INET6; /* force IPv6 - will still work with IPv4 */ #else hints.ai_family = AF_INET; #endif hints.ai_socktype = SOCK_DGRAM;/* UDP Connection */ hints.ai_flags = AI_PASSIVE; /* use my IP address */ snprintf(portnumbuffer, SOCKPORT_MAX_LEN, "%d", servPort); if ((getaddrinfo_errorcode = getaddrinfo(NULL, portnumbuffer, &hints, &servinfo)) != 0) { dlt_vlog(LOG_WARNING, "[%s:%d] getaddrinfo: %s\n", __func__, __LINE__, gai_strerror(getaddrinfo_errorcode)); return DLT_RETURN_ERROR; } for (addrinfo_iterator = servinfo; addrinfo_iterator != NULL; addrinfo_iterator = addrinfo_iterator->ai_next) { if ((*sock = socket(addrinfo_iterator->ai_family, addrinfo_iterator->ai_socktype, addrinfo_iterator->ai_protocol)) == SYSTEM_CALL_ERROR) { dlt_log(LOG_WARNING, "socket() error\n"); continue; } dlt_vlog(LOG_INFO, "[%s:%d] Socket created - socket_family:%i socket_type:%i, protocol:%i\n", __func__, __LINE__, addrinfo_iterator->ai_family, addrinfo_iterator->ai_socktype, addrinfo_iterator->ai_protocol); if (setsockopt(*sock, SOL_SOCKET, SO_REUSEADDR, &enable_reuse_addr, sizeof(enable_reuse_addr)) == SYSTEM_CALL_ERROR) { dlt_vlog(LOG_WARNING, "[%s:%d] Setsockopt error %s\n", __func__, __LINE__, strerror(errno)); close(*sock); continue; } if (setsockopt(*sock, SOL_SOCKET, SO_RCVBUF, &sockbuffer, sizeof(sockbuffer)) == SYSTEM_CALL_ERROR) { dlt_vlog(LOG_WARNING, "[%s:%d] Setsockopt error %s\n", __func__, __LINE__, strerror(errno)); close(*sock); continue; } if (bind(*sock, addrinfo_iterator->ai_addr, addrinfo_iterator->ai_addrlen) == SYSTEM_CALL_ERROR) { close(*sock); dlt_log(LOG_WARNING, "bind() error\n"); continue; } break; } if (addrinfo_iterator == NULL) { dlt_log(LOG_WARNING, "failed to bind socket\n"); return DLT_RETURN_ERROR; } freeaddrinfo(servinfo); return DLT_RETURN_OK; /* OK */ } /* ************************************************************************** */ /* Function : dlt_daemon_udp_dltmsg_multicast */ /* In Param : data bytes in dlt format */ /* Out Param : NIL */ /* Description: multicast UDP dlt-message packets to dlt-client */ /* ************************************************************************** */ void dlt_daemon_udp_dltmsg_multicast(void *data1, int size1, void *data2, int size2, int verbose) { PRINT_FUNCTION_VERBOSE(verbose); /* * When UDP Buffer is implemented then data2 would be expected to be NULL * as the data comes from buffer directly. In that case data2 should * not be checked for NULL */ if ((data1 == NULL) || (data2 == NULL)) { dlt_vlog(LOG_ERR, "%s: NULL arg\n", __func__); return; } dlt_daemon_udp_clientmsg_send(&g_udpmulticast_addr, data1, size1, data2, size2, verbose); } /* ************************************************************************** */ /* Function : dlt_daemon_udp_clientmsg_send */ /* In Param : data bytes & respective size in dlt format */ /* Out Param : NIL */ /* Description: common interface to send data via UDP protocol */ /* ************************************************************************** */ void dlt_daemon_udp_clientmsg_send(DltDaemonClientSockInfo *clientinfo, void *data1, int size1, void *data2, int size2, int verbose) { PRINT_FUNCTION_VERBOSE(verbose); if ((clientinfo->isvalidflag == ADDRESS_VALID) && (size1 > 0) && (size2 > 0)) { void *data = (void *)calloc(size1 + size2, sizeof(char)); if (data == NULL) { dlt_vlog(LOG_ERR, "%s: calloc failure\n", __func__); return; } memcpy(data, data1, size1); memcpy(data + size1, data2, size2); if (sendto(g_udp_sock_fd, data, size1 + size2, 0, (struct sockaddr *)&clientinfo->clientaddr, clientinfo->clientaddr_size) < 0) dlt_vlog(LOG_ERR, "%s: Send UDP Packet Data failed\n", __func__); free(data); data = NULL; } else { if (clientinfo->isvalidflag != ADDRESS_VALID) dlt_vlog(LOG_ERR, "%s: clientinfo->isvalidflag != ADDRESS_VALID %d\n", __func__, clientinfo->isvalidflag); if (size1 <= 0) dlt_vlog(LOG_ERR, "%s: size1 <= 0\n", __func__); if (size2 <= 0) dlt_vlog(LOG_ERR, "%s: size2 <= 0\n", __func__); } } dlt-daemon-2.18.4/src/daemon/udp_connection/dlt_daemon_udp_socket.h000066400000000000000000000017401353342203500253740ustar00rootroot00000000000000/* * Copyright (c) 2019 LG Electronics Inc. * SPDX-License-Identifier: MPL-2.0 * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author * Guruprasad KN * Sachin Sudhakar Shetty * Sunil Kovila Sampath * * \Copyright (c) 2019 LG Electronics Inc. * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file dlt_daemon_udp_socket.h */ #ifndef DLT_DAEMON_UDP_SOCKET_H #define DLT_DAEMON_UDP_SOCKET_H #include "dlt-daemon.h" DltReturnValue dlt_daemon_udp_connection_setup(DltDaemonLocal *daemon_local); void dlt_daemon_udp_dltmsg_multicast(void *data1, int size1, void *data2, int size2, int verbose); #endif /* DLT_DAEMON_UDP_SOCKET_H */ dlt-daemon-2.18.4/src/dbus/000077500000000000000000000000001353342203500153565ustar00rootroot00000000000000dlt-daemon-2.18.4/src/dbus/CMakeLists.txt000066400000000000000000000016041353342203500201170ustar00rootroot00000000000000####### # SPDX license identifier: MPL-2.0 # # Copyright (C) 2011-2015, BMW AG # # This file is part of GENIVI Project DLT - Diagnostic Log and Trace. # # This Source Code Form is subject to the terms of the # Mozilla Public License (MPL), v. 2.0. # If a copy of the MPL was not distributed with this file, # You can obtain one at http://mozilla.org/MPL/2.0/. # # For further information see http://www.genivi.org/. ####### include_directories( ${PROJECT_SOURCE_DIR}/ ${PROJECT_SOURCE_DIR}/include/dlt ${DBUS_INCLUDE_DIRS} ) set(dlt_dbus_SRCS dlt-dbus.c dlt-dbus-options.c) add_executable(dlt-dbus ${dlt_dbus_SRCS}) target_link_libraries(dlt-dbus dlt ${DBUS_LIBRARIES}) set_target_properties(dlt-dbus PROPERTIES LINKER_LANGUAGE C) install(TARGETS dlt-dbus RUNTIME DESTINATION bin COMPONENT base) INSTALL(FILES dlt-dbus.conf DESTINATION ${CONFIGURATION_FILES_DIR} COMPONENT base) dlt-daemon-2.18.4/src/dbus/dlt-dbus-options.c000066400000000000000000000156101353342203500207340ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2011-2015, BMW AG * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author Alexander Wenzel * * \copyright Copyright © 2011-2015 BMW AG. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file dlt-dbus-options.c */ #include "dlt-dbus.h" #include #include /** * Print information how to use this program. */ void usage(char *prog_name) { char version[255]; dlt_get_version(version, 255); printf("Usage: %s [options]\n", prog_name); printf("Application to forward dbus messages to DLT.\n"); printf("%s\n", version); printf("Options:\n"); printf(" -d Daemonize. Detach from terminal and run in background.\n"); printf(" -c filename Use configuration file. \n"); printf(" -a apid Used application id. \n"); printf(" Default: %s\n", DEFAULT_CONF_FILE); printf(" -b type Used bus type. \n"); printf(" Session = 0, System = 1.\n"); printf(" -h This help message.\n"); } /** * Initialize command line options with default values. */ void init_cli_options(DltDBusCliOptions *options) { options->ConfigurationFileName = DEFAULT_CONF_FILE; options->ApplicationId = 0; options->BusType = 0; options->Daemonize = 0; } /** * Read command line options and set the values in provided structure */ int read_command_line(DltDBusCliOptions *options, int argc, char *argv[]) { init_cli_options(options); int opt; while ((opt = getopt(argc, argv, "c:b:a:hd")) != -1) switch (opt) { case 'd': { options->Daemonize = 1; break; } case 'b': { options->BusType = malloc(strlen(optarg) + 1); MALLOC_ASSERT(options->BusType); strcpy(options->BusType, optarg); /* strcpy uncritical here, because size matches exactly the size to be copied */ break; } case 'a': { options->ApplicationId = malloc(strlen(optarg) + 1); MALLOC_ASSERT(options->ApplicationId); strcpy(options->ApplicationId, optarg); /* strcpy uncritical here, because size matches exactly the size to be copied */ break; } case 'c': { options->ConfigurationFileName = malloc(strlen(optarg) + 1); MALLOC_ASSERT(options->ConfigurationFileName); strcpy(options->ConfigurationFileName, optarg); /* strcpy uncritical here, because size matches exactly the size to be copied */ break; } case 'h': { usage(argv[0]); exit(0); return -1; /*for parasoft */ } default: { fprintf(stderr, "Unknown option '%c'\n", optopt); usage(argv[0]); return -1; } } return 0; } /** * Initialize configuration to default values. */ void init_configuration(DltDBusConfiguration *config) { /* Common */ config->ApplicationId = "IPC0"; /* DBus */ config->DBus.ContextId = "ALL"; config->DBus.BusType = 0; config->DBus.FilterCount = 0; } /** * Read options from the configuration file */ int read_configuration_file(DltDBusConfiguration *config, char *file_name) { FILE *file; char *line, *token, *value, *filter, *pch; int ret = 0; char *filterBegin, *filterEnd; init_configuration(config); file = fopen(file_name, "r"); if (file == NULL) { fprintf(stderr, "dlt-dbus-options, could not open configuration file.\n"); return -1; } line = malloc(MAX_LINE); token = malloc(MAX_LINE); value = malloc(MAX_LINE); filter = malloc(MAX_LINE); MALLOC_ASSERT(line); MALLOC_ASSERT(token); MALLOC_ASSERT(value); MALLOC_ASSERT(filter); while (fgets(line, MAX_LINE, file) != NULL) { token[0] = 0; value[0] = 0; filter[0] = 0; filterBegin = strchr(line, '='); filterEnd = strpbrk (line, "\r\n"); if (filterBegin) { if (filterEnd && (filterEnd > filterBegin)) { strncpy(filter, filterBegin + 1, filterEnd - filterBegin - 1); filter[filterEnd - filterBegin - 1] = 0; } else { strcpy(filter, filterBegin + 1); } } pch = strtok (line, " =\r\n"); while (pch != NULL) { if (pch[0] == '#') break; if (token[0] == 0) { strncpy(token, pch, MAX_LINE - 1); token[MAX_LINE - 1] = 0; } else { strncpy(value, pch, MAX_LINE); value[MAX_LINE - 1] = 0; break; } pch = strtok (NULL, " =\r\n"); } if (token[0] && value[0]) { /* Common */ if (strcmp(token, "ApplicationId") == 0) { config->ApplicationId = malloc(strlen(value) + 1); MALLOC_ASSERT(config->ApplicationId); strcpy(config->ApplicationId, value); /* strcpy unritical here, because size matches exactly the size to be copied */ } /* ContextId */ else if (strcmp(token, "ContextId") == 0) { config->DBus.ContextId = malloc(strlen(value) + 1); MALLOC_ASSERT(config->DBus.ContextId); strcpy(config->DBus.ContextId, value); /* strcpy unritical here, because size matches exactly the size to be copied */ } /* BusType */ else if (strcmp(token, "BusType") == 0) { config->DBus.BusType = malloc(strlen(value) + 1); MALLOC_ASSERT(config->DBus.BusType); strcpy(config->DBus.BusType, value); /* strcpy unritical here, because size matches exactly the size to be copied */ } /* BusType */ else if (strcmp(token, "FilterMatch") == 0) { if (config->DBus.FilterCount < DLT_DBUS_FILTER_MAX) { config->DBus.FilterMatch[config->DBus.FilterCount] = malloc(strlen(filter) + 1); MALLOC_ASSERT(config->DBus.FilterMatch[config->DBus.FilterCount]); strcpy(config->DBus.FilterMatch[config->DBus.FilterCount], filter); config->DBus.FilterCount++; } } } } fclose(file); free(value); free(token); free(filter); free(line); return ret; } dlt-daemon-2.18.4/src/dbus/dlt-dbus.c000066400000000000000000000114541353342203500172450ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2011-2015, BMW AG * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author Alexander Wenzel * * \copyright Copyright © 2011-2015 BMW AG. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file dlt-dbus.c */ #include "dlt-dbus.h" #include #include #include #include #include #include #include DLT_DECLARE_CONTEXT(dbusLog) DLT_DECLARE_CONTEXT(dbusContext) static char dbus_message_buffer[DBUS_MAXIMUM_MESSAGE_LENGTH]; static DBusHandlerResult filter_func (DBusConnection *con, DBusMessage *message, void *data) { char **buf; int len_p; UNUSED(con); UNUSED(data); buf = (char **)&dbus_message_buffer; if (!dbus_message_marshal(message, buf, &len_p)) { fprintf (stderr, "Failed to serialize DBus message!\n"); return DBUS_HANDLER_RESULT_HANDLED; } DLT_TRACE_NETWORK_SEGMENTED(dbusContext, DLT_NW_TRACE_IPC, 0, 0, len_p, (void *)*buf); free(*buf); *buf = NULL; if (dbus_message_is_signal (message, DBUS_INTERFACE_LOCAL, "Disconnected")) { DLT_UNREGISTER_CONTEXT (dbusContext); DLT_UNREGISTER_APP (); exit (0); } /* Conceptually we want this to be * DBUS_HANDLER_RESULT_NOT_YET_HANDLED, but this raises * some problems. See bug 1719. */ return DBUS_HANDLER_RESULT_HANDLED; } int main (int argc, char *argv[]) { DltDBusCliOptions options; DltDBusConfiguration config; DBusConnection *connection; DBusError error; DBusBusType type; int num; if (read_command_line(&options, argc, argv) < 0) { fprintf(stderr, "Failed to read command line!\n"); return -1; } if (read_configuration_file(&config, options.ConfigurationFileName) < 0) { fprintf(stderr, "Failed to read configuration file!\n"); return -1; } /* register application */ if (options.ApplicationId) DLT_REGISTER_APP (options.ApplicationId, "DBus Logging"); else DLT_REGISTER_APP (config.ApplicationId, "DBus Logging"); /* register context */ DLT_REGISTER_CONTEXT_LL_TS(dbusContext, config.DBus.ContextId, "DBus Context for Logging", DLT_LOG_INFO, DLT_TRACE_STATUS_ON); DLT_REGISTER_CONTEXT(dbusLog, "Log", "DBus Context for Logging Generic information"); /* initialise error handler */ dbus_error_init (&error); /* set DBus bus type */ if (options.BusType) type = (DBusBusType)atoi(options.BusType); else type = (DBusBusType)atoi(config.DBus.BusType); /* get connection */ connection = dbus_bus_get (type, &error); if (type == 0) DLT_LOG(dbusLog, DLT_LOG_INFO, DLT_STRING("BusType"), DLT_STRING("Session Bus")); else if (type == 1) DLT_LOG(dbusLog, DLT_LOG_INFO, DLT_STRING("BusType"), DLT_STRING("System Bus")); else DLT_LOG(dbusLog, DLT_LOG_INFO, DLT_STRING("BusType"), DLT_INT(type)); if (NULL == connection) { fprintf (stderr, "Failed to open connection to %d: %s\n", DBUS_BUS_SYSTEM, error.message); dbus_error_free (&error); exit (1); } for (num = 0; num < config.DBus.FilterCount; num++) { dbus_bus_add_match (connection, config.DBus.FilterMatch[num], &error); printf("Added FilterMatch: %s\n", config.DBus.FilterMatch[num]); DLT_LOG(dbusLog, DLT_LOG_INFO, DLT_STRING("FilterMatch"), DLT_UINT(num + 1), DLT_STRING(config.DBus.FilterMatch[num])); if (dbus_error_is_set (&error)) goto fail; } if (!dbus_connection_add_filter (connection, filter_func, NULL, NULL)) { fprintf (stderr, "Couldn't add filter!\n"); exit (1); } while (dbus_connection_read_write_dispatch(connection, -1)) ; DLT_UNREGISTER_CONTEXT (dbusContext); DLT_UNREGISTER_CONTEXT (dbusLog); DLT_UNREGISTER_APP (); exit(1); fail: /* fail */ fprintf (stderr, "Error: %s\n", error.message); DLT_UNREGISTER_CONTEXT (dbusContext); DLT_UNREGISTER_CONTEXT (dbusLog); DLT_UNREGISTER_APP (); exit(1); } dlt-daemon-2.18.4/src/dbus/dlt-dbus.conf000066400000000000000000000013031353342203500177400ustar00rootroot00000000000000# Configuration file of DLT dbus forwarder # ######################################################################## # General configuration ######################################################################## # The application Id used for DBus Trace (Default: DBUS) # If command line parameter used, the command line application id is used instead ApplicationId = DBUS # The context Id used for the DBus Trace(Default: ALL) ContextId = ALL # The DBus bus to be logged (Default: 1) # DBUS_BUS_SESSION = 0 # DBUS_BUS_SYSTEM = 1 # DBUS_BUS_STARTER = 2 BusType = 1 # Add one or several filters # Filter String is beginning directly after first occurence of character '=' FilterMatch=eavesdrop=true dlt-daemon-2.18.4/src/dbus/dlt-dbus.h000066400000000000000000000032551353342203500172520ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2011-2015, BMW AG * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author Alexander Wenzel * * \copyright Copyright © 2011-2015 BMW AG. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file dlt-dbus.h */ #ifndef DLT_DBUS_H_ #define DLT_DBUS_H_ /* DLT related includes. */ #include "dlt.h" #include "dlt_common.h" #define DEFAULT_CONF_FILE CONFIGURATION_FILES_DIR "/dlt-dbus.conf" #define DLT_DBUS_FILTER_MAX 32 /* Macros */ #define UNUSED(x) (void)(x) #define MALLOC_ASSERT(x) if (x == NULL) { \ fprintf(stderr, "Out of memory\n"); \ abort(); } #define MAX_LINE 1024 /* Command line options */ typedef struct { char *ConfigurationFileName; char *ApplicationId; char *BusType; int Daemonize; } DltDBusCliOptions; /* Configuration dbus options */ typedef struct { char *ContextId; char *BusType; int FilterCount; char *FilterMatch[DLT_DBUS_FILTER_MAX]; } DBusOptions; typedef struct { char *ApplicationId; DBusOptions DBus; } DltDBusConfiguration; extern void init_cli_options(DltDBusCliOptions *options); extern int read_command_line(DltDBusCliOptions *options, int argc, char *argv[]); extern int read_configuration_file(DltDBusConfiguration *config, char *file_name); #endif /* DLT_DBUS_H_ */ dlt-daemon-2.18.4/src/examples/000077500000000000000000000000001353342203500162375ustar00rootroot00000000000000dlt-daemon-2.18.4/src/examples/CMakeLists.txt000066400000000000000000000041111353342203500207740ustar00rootroot00000000000000####### # SPDX license identifier: MPL-2.0 # # Copyright (C) 2011-2015, BMW AG # # This file is part of GENIVI Project DLT - Diagnostic Log and Trace. # # This Source Code Form is subject to the terms of the # Mozilla Public License (MPL), v. 2.0. # If a copy of the MPL was not distributed with this file, # You can obtain one at http://mozilla.org/MPL/2.0/. # # For further information see http://www.genivi.org/. ####### set(dlt_example_user_SRCS dlt-example-user.c) add_executable(dlt-example-user ${dlt_example_user_SRCS}) target_link_libraries(dlt-example-user dlt) set_target_properties(dlt-example-user PROPERTIES LINKER_LANGUAGE C) set(dlt_example_user_common_api_SRCS dlt-example-user-common-api.c) add_executable(dlt-example-user-common-api ${dlt_example_user_common_api_SRCS}) target_link_libraries(dlt-example-user-common-api dlt) set_target_properties(dlt-example-user-common-api PROPERTIES LINKER_LANGUAGE C) set(dlt_example_user_func_SRCS dlt-example-user-func.c) add_executable(dlt-example-user-func ${dlt_example_user_func_SRCS}) target_link_libraries(dlt-example-user-func dlt) set_target_properties(dlt-example-user-func PROPERTIES LINKER_LANGUAGE C) set(dlt_example_filetransfer_SRCS dlt-example-filetransfer.c) add_executable( dlt-example-filetransfer ${dlt_example_filetransfer_SRCS}) target_link_libraries(dlt-example-filetransfer dlt ) set_target_properties(dlt-example-filetransfer PROPERTIES LINKER_LANGUAGE C) if(WITH_UDP_CONNECTION) set(dlt-example-multicast-clientmsg-view_SRCS dlt-example-multicast-clientmsg-view.c) add_executable(dlt-example-multicast-clientmsg-view ${dlt-example-multicast-clientmsg-view_SRCS} ${dlt_most_SRCS}) target_link_libraries(dlt-example-multicast-clientmsg-view dlt ) set_target_properties(dlt-example-multicast-clientmsg-view PROPERTIES LINKER_LANGUAGE C) install(TARGETS dlt-example-multicast-clientmsg-view RUNTIME DESTINATION bin COMPONENT base) endif(WITH_UDP_CONNECTION) install(TARGETS dlt-example-user dlt-example-user-func dlt-example-user-common-api dlt-example-filetransfer RUNTIME DESTINATION bin COMPONENT base) dlt-daemon-2.18.4/src/examples/dlt-example-filetransfer.c000066400000000000000000000153001353342203500233000ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2011-2015, BMW AG * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author Alexander Wenzel * * \copyright Copyright © 2011-2015 BMW AG. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file dlt-example-filetransfer.c */ /******************************************************************************* ** ** ** SRC-MODULE: dlt-test-client.c ** ** ** ** TARGET : linux ** ** ** ** PROJECT : DLT ** ** ** ** AUTHOR : Alexander Wenzel Alexander.AW.Wenzel@bmw.de ** ** ** ** PURPOSE : ** ** ** ** REMARKS : ** ** ** ** PLATFORM DEPENDANT [yes/no]: yes ** ** ** ** TO BE CHANGED BY USER [yes/no]: no ** ** ** *******************************************************************************/ /******************************************************************************* ** Author Identity ** ******************************************************************************** ** ** ** Initials Name Company ** ** -------- ------------------------- ---------------------------------- ** ** aw Alexander Wenzel BMW ** *******************************************************************************/ #include #include #include #include /*Needed for transferring files with the dlt protocol*/ #include /*Needed for dlt logging*/ #define MAXSTRLEN 1024 #define FLTR_APP_DESC "Filetransfer application" #define FLTR_CONTEXT_DESC "Filetransfer context" #define FLTR_APP "FLTR" #define FLTR_CONTEXT "FLTR" #define TIMEOUT 1 /*!Declare some context for the file transfer. It's not a must have to do this, but later you can set a filter on this context in the dlt viewer. */ DLT_DECLARE_CONTEXT(fileContext) /** * Print usage information of tool. */ void usage() { char version[255]; dlt_get_version(version, 255); printf("Usage: dlt-example-filetransfer [options] absolute-path-to-file\n"); printf("Simple filetransfer example"); printf("%s \n", version); printf("Options:\n"); printf("-a apid - Set application id to apid (default: FLTR)\n"); printf("-c ctid - Set context id to ctid (default: FLTR)\n"); printf("-t ms - Timeout between file packages in ms (minimum 1 ms)\n"); printf("-d - Flag to delete the file after the transfer (default: false)\n"); printf("-i - Flag to log file infos to DLT before transfer file (default: false)\n"); printf("-h - This help\n"); } /*!Main program dlt-test-filestransfer starts here */ int main(int argc, char *argv[]) { /*char str[MAXSTRLEN]; */ int opt, timeout; char apid[DLT_ID_SIZE]; char ctid[DLT_ID_SIZE]; /*char version[255]; */ int index; int dflag = 0; int iflag = 0; char *file = 0; char *tvalue = 0; dlt_set_id(apid, FLTR_APP); dlt_set_id(ctid, FLTR_CONTEXT); while ((opt = getopt(argc, argv, "idf:t:a:c:h")) != -1) switch (opt) { case 'd': { dflag = 1; break; } case 'i': { iflag = 1; break; } case 't': { tvalue = optarg; break; } case 'a': { dlt_set_id(apid, optarg); break; } case 'c': { dlt_set_id(ctid, optarg); break; } case 'h': { usage(); break; } case '?': { if ((optopt == 'a') || (optopt == 'c') || (optopt == 't')) fprintf (stderr, "Option -%c requires an argument.\n", optopt); else if (isprint (optopt)) fprintf (stderr, "Unknown option `-%c'.\n", optopt); else fprintf (stderr, "Unknown option character `\\x%x'.\n", optopt); /* unknown or wrong option used, show usage information and terminate */ usage(); return -1; } } for (index = optind; index < argc; index++) file = argv[index]; if (file == 0) { /* no message, show usage and terminate */ fprintf(stderr, "ERROR: No absolute path to file specified\n"); usage(); return -1; } if (tvalue) timeout = atoi(tvalue); else timeout = TIMEOUT; /*Register the application at the dlt-daemon */ DLT_REGISTER_APP(apid, FLTR_APP_DESC); /*Register the context of the main program at the dlt-daemon */ DLT_REGISTER_CONTEXT(fileContext, ctid, FLTR_CONTEXT_DESC); /*More details in corresponding methods */ if (iflag) dlt_user_log_file_infoAbout(&fileContext, file); if (dlt_user_log_file_complete(&fileContext, file, dflag, timeout) < 0) printf("File couldn't be transferred. Please check the dlt log messages.\n"); /*Unregister the context in which the file transfer happened from the dlt-daemon */ DLT_UNREGISTER_CONTEXT(fileContext); /*Unregister the context of the main program from the dlt-daemon */ DLT_UNREGISTER_APP(); return 0; } dlt-daemon-2.18.4/src/examples/dlt-example-multicast-clientmsg-view.c000066400000000000000000000135261353342203500255640ustar00rootroot00000000000000/* * Copyright (c) 2019 LG Electronics Inc. * SPDX-License-Identifier: MPL-2.0 * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author * Guruprasad KN * Sachin Sudhakar Shetty * Sunil Kovila Sampath * * \Copyright (c) 2019 LG Electronics Inc. * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file dlt-example-multicast-clientmsg-view.c */ #include #include #include #include #include #include #include #include /* for isprint() */ #include /* for atoi() */ #include /* for S_IRUSR, S_IWUSR, S_IRGRP, S_IROTH */ #include /* for open() */ #include /* for writev() */ #include #include #include #include #include /* for PATH_MAX */ #include #include "dlt_client.h" #include "dlt_client_cfg.h" #define DLT_RECEIVE_TEXTBUFSIZE 10024 #define HELLO_PORT 3491 #define HELLO_GROUP "225.0.0.37" struct clientinfostruct { int fd; struct sockaddr_in addr; socklen_t addlen; DltReceiver receiver; }; int dlt_receiver_receive_socket_udp(struct clientinfostruct *clientinfo, DltReceiver *receiver) { if ((receiver == NULL) || (clientinfo == NULL)) { printf("NULL receiver or clientinfo in dlt_receiver_receive_socket_udp\n"); return -1; } if (receiver->buffer == NULL) { printf("NULL receiver->buffer in dlt_receiver_receive_socket_udp\n"); return -1; } receiver->buf = (char *)receiver->buffer; receiver->lastBytesRcvd = receiver->bytesRcvd; /* wait for data from socket */ unsigned int addrlen = sizeof(clientinfo->addr); if ((receiver->bytesRcvd = recvfrom(clientinfo->fd, receiver->buf + receiver->lastBytesRcvd, receiver->buffersize - receiver->lastBytesRcvd, 0, (struct sockaddr *)&(clientinfo->addr), &addrlen)) <= 0) { printf("Error\n"); perror("recvfrom"); receiver->bytesRcvd = 0; return receiver->bytesRcvd; } /* if */ receiver->totalBytesRcvd += receiver->bytesRcvd; receiver->bytesRcvd += receiver->lastBytesRcvd; return receiver->bytesRcvd; } int dlt_receive_message_callback_udp(DltMessage *message) { static char text[DLT_RECEIVE_TEXTBUFSIZE]; if ((message == NULL)) { printf("NULL message in dlt_receive_message_callback_udp\n"); return -1; } /* prepare storage header */ if (DLT_IS_HTYP_WEID(message->standardheader->htyp)) dlt_set_storageheader(message->storageheader, message->headerextra.ecu); else dlt_set_storageheader(message->storageheader, "ECU1"); dlt_message_header(message, text, DLT_RECEIVE_TEXTBUFSIZE, 0); printf("%s ", text); dlt_message_payload(message, text, DLT_RECEIVE_TEXTBUFSIZE, DLT_OUTPUT_ASCII, 0); printf("[%s]\n", text); return 0; } int main() { struct clientinfostruct clientinfo; struct ip_mreq mreq; u_int yes = 1; /* create what looks like an ordinary UDP socket */ if ((clientinfo.fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { perror("socket"); exit(1); } /* allow multiple sockets to use the same PORT number */ if (setsockopt(clientinfo.fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) < 0) { perror("Reusing ADDR failed"); exit(1); } /* set up destination address */ memset(&clientinfo.addr, 0, sizeof(clientinfo.addr)); clientinfo.addr.sin_family = AF_INET; clientinfo.addr.sin_addr.s_addr = htonl(INADDR_ANY); /* N.B.: differs from sender */ clientinfo.addr.sin_port = htons(HELLO_PORT); /* bind to receive address */ if (bind(clientinfo.fd, (struct sockaddr *)&clientinfo.addr, sizeof(clientinfo.addr)) < 0) { perror("bind"); exit(1); } /* use setsockopt() to request that the kernel join a multicast group */ mreq.imr_multiaddr.s_addr = inet_addr(HELLO_GROUP); mreq.imr_interface.s_addr = htonl(INADDR_ANY); if (setsockopt(clientinfo.fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0) { perror("setsockopt"); exit(1); } DltMessage msg; if (dlt_message_init(&msg, 0) == DLT_RETURN_ERROR) return DLT_RETURN_ERROR; if (dlt_receiver_init(&(clientinfo.receiver), clientinfo.fd, DLT_RECEIVE_BUFSIZE) != DLT_RETURN_OK) return DLT_RETURN_ERROR; printf("Waiting for message on ip %s port : %d\n", HELLO_GROUP, HELLO_PORT); while (1) { /* wait for data from socket */ dlt_receiver_receive_socket_udp(&clientinfo, &(clientinfo.receiver)); while (dlt_message_read(&msg, (unsigned char *)(clientinfo.receiver.buf), clientinfo.receiver.bytesRcvd, 0, 0) == DLT_MESSAGE_ERROR_OK) { dlt_receive_message_callback_udp(&msg); if (dlt_receiver_remove(&(clientinfo.receiver), msg.headersize + msg.datasize - sizeof(DltStorageHeader)) == DLT_RETURN_ERROR) { /* Return value ignored */ dlt_message_free(&msg, 0); return DLT_RETURN_ERROR; } } if (dlt_receiver_move_to_begin(&(clientinfo.receiver)) == DLT_RETURN_ERROR) { /* Return value ignored */ dlt_message_free(&msg, 0); return DLT_RETURN_ERROR; } } } dlt-daemon-2.18.4/src/examples/dlt-example-non-verbose-1.xml000077500000000000000000000600151353342203500235730ustar00rootroot00000000000000 projectTCB TCB 001.004.062 LOG Application 1 TEST Context 1 PDU_10_0 DLT non verbose test message. 0 OTHER PDU_11_0 Buffer near limit. Free size: 0 OTHER PDU_11_1 2 OTHER 0 PDU_12_0 Buffer size exceeded. 0 OTHER PDU_12_1 4 OTHER 0 PDU_12_2 4 OTHER 0 PDU_12_3 Process terminated. 0 OTHER PDU_13_0 Temperature measurement 0 OTHER PDU_13_1 1 OTHER 0 measurement_point PDU_13_2 4 OTHER 0 reading Kelvin PDU_14_0 Build ID: 0 OTHER PDU_14_1 0 OTHER 0 ID_10 0 OTHER 0 DLT_TYPE_LOG DLT_LOG_INFO LOG TEST dlt_test.c 411 ID_1001 2 OTHER 0 1 DLT_TYPE_LOG DLT_LOG_WARN LOG TEST application_file.c 955 ID_1002 2 OTHER 0 1 2 3 DLT_TYPE_LOG DLT_LOG_ERROR LOG TEST application_file.c 1058 ID_1003 5 OTHER 0 1 2 DLT_TYPE_LOG DLT_LOG_INFO LOG TEST temp_meas.c 42 ID_14 0 OTHER 0 1 DLT_TYPE_LOG DLT_LOG_INFO LOG TEST latsTask.c 421 S_BOOL S_SINT8 S_UINT8 S_SINT16 S_UINT16 S_SINT32 S_UINT32 S_SINT64 S_UINT64 S_FLOA16 S_FLOA32 S_FLOA64 S_STRG_ASCII S_STRG_UTF8 BOOL Coding for boolean values. 8 SINT8 Coding for signel 8bit values. 8 UINT8 Coding for unsignel 8bit values. 8 SINT16 Coding for signel 16bit values. 16 UINT16 Coding for unsignel 16bit values. 16 SINT32 Coding for signel 32bit values. 32 UINT32 Coding for unsignel 32bit values. 32 SINT64 Coding for signel 64bit values. 64 UINT64 Coding for unsignel 64bit values. 64 FLOA16 Coding for float 16bit values. 16 FLOA32 Coding for float 32bit values. 32 FLOA64 Coding for float 64bit values. 64 STRG_ASCII Coding for ASCII string. 0 255 STRG_UTF8 Coding for UTF8 string. 0 255 dlt-daemon-2.18.4/src/examples/dlt-example-non-verbose-1.xml.old000066400000000000000000000621201353342203500243440ustar00rootroot00000000000000 projectTCB TCB 001.004.062 APP1 Application 1 CON1 Context 1 TEST Test Application CON1 Context 1 LAT Log And Trace NV NV test PDU_10_0 DLT non verbose test message. 0 OTHER PDU_11_0 Buffer near limit. Free size: 0 OTHER PDU_11_1 2 OTHER 0 PDU_12_0 Buffer size exceeded. 0 OTHER PDU_12_1 4 OTHER 0 PDU_12_2 4 OTHER 0 PDU_12_3 Process terminated. 0 OTHER PDU_13_0 Temperature measurement 0 OTHER PDU_13_1 1 OTHER 0 measurement_point PDU_13_2 4 OTHER 0 reading Kelvin PDU_14_0 Build ID: 0 OTHER PDU_14_1 0 OTHER 0 ID_10 0 OTHER 0 DLT_TYPE_LOG DLT_LOG_INFO TEST CON1 dlt_test.c 411 ID_1001 2 OTHER 0 1 DLT_TYPE_LOG DLT_LOG_WARN APP1 CON1 application_file.c 955 ID_1002 2 OTHER 0 1 2 3 DLT_TYPE_LOG DLT_LOG_ERROR APP1 CON1 application_file.c 1058 ID_1003 5 OTHER 0 1 2 DLT_TYPE_LOG DLT_LOG_INFO APP1 CON1 temp_meas.c 42 ID_14 0 OTHER 0 1 DLT_TYPE_LOG DLT_LOG_INFO LAT NV latsTask.c 421 S_BOOL S_SINT8 S_UINT8 S_SINT16 S_UINT16 S_SINT32 S_UINT32 S_SINT64 S_UINT64 S_FLOA16 S_FLOA32 S_FLOA64 S_STRG_ASCII S_STRG_UTF8 BOOL Coding for boolean values. 8 SINT8 Coding for signel 8bit values. 8 UINT8 Coding for unsignel 8bit values. 8 SINT16 Coding for signel 16bit values. 16 UINT16 Coding for unsignel 16bit values. 16 SINT32 Coding for signel 32bit values. 32 UINT32 Coding for unsignel 32bit values. 32 SINT64 Coding for signel 64bit values. 64 UINT64 Coding for unsignel 64bit values. 64 FLOA16 Coding for float 16bit values. 16 FLOA32 Coding for float 32bit values. 32 FLOA64 Coding for float 64bit values. 64 STRG_ASCII Coding for ASCII string. 0 255 STRG_UTF8 Coding for UTF8 string. 0 255 dlt-daemon-2.18.4/src/examples/dlt-example-non-verbose.xml000066400000000000000000000443021353342203500234330ustar00rootroot00000000000000 projectTCB TCB 001.004.062 PDU_10_0 DLT non verbose test message. 0 OTHER PDU_11_0 Buffer near limit. Free size: 0 OTHER PDU_11_1 2 OTHER 0 PDU_12_0 Buffer size exceeded. 0 OTHER PDU_12_1 Requested size: 4 OTHER 0 PDU_12_2 Free size: 4 OTHER 0 PDU_12_3 Process terminated. 0 OTHER PDU_13_0 Temperature measurement 0 OTHER PDU_13_1 1 OTHER 0 measurement_point PDU_13_2 4 OTHER 0 reading Kelvin ID_10 0 OTHER 0 DLT_TYPE_LOG DLT_LOG_INFO TEST CON1 dlt_test.c 411 ID_11 2 OTHER 0 1 DLT_TYPE_LOG DLT_LOG_WARN APP1 CON1 application_file.c 955 ID_12 8 OTHER 0 1 2 3 DLT_TYPE_LOG DLT_LOG_ERROR APP1 CON1 application_file.c 1058 ID_13 5 OTHER 0 1 2 DLT_TYPE_LOG DLT_LOG_INFO APP1 CON1 temp_meas.c 42 S_BOOL S_SINT8 S_UINT8 S_SINT16 S_UINT16 S_SINT32 S_UINT32 S_SINT64 S_UINT64 S_FLOA16 S_FLOA32 S_FLOA64 S_STRG_ASCII S_STRG_UTF8 BOOL Coding for boolean values. 8 SINT8 Coding for signel 8bit values. 8 UINT8 Coding for unsignel 8bit values. 8 SINT16 Coding for signel 16bit values. 16 UINT16 Coding for unsignel 16bit values. 16 SINT32 Coding for signel 32bit values. 32 UINT32 Coding for unsignel 32bit values. 32 SINT64 Coding for signel 64bit values. 64 UINT64 Coding for unsignel 64bit values. 64 FLOA16 Coding for float 16bit values. 16 FLOA32 Coding for float 32bit values. 32 FLOA64 Coding for float 64bit values. 64 STRG_ASCII Coding for ASCII string. 0 255 STRG_UTF8 Coding for UTF8 string. 0 255 dlt-daemon-2.18.4/src/examples/dlt-example-user-common-api.c000066400000000000000000000207001353342203500236270ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2011-2015, BMW AG * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author Alexander Wenzel * * \copyright Copyright © 2011-2015 BMW AG. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file dlt-example-user-common-api.c */ /******************************************************************************* ** ** ** SRC-MODULE: dlt-example-common-api.c ** ** ** ** TARGET : linux ** ** ** ** PROJECT : DLT ** ** ** ** AUTHOR : Alexander Wenzel Alexander.AW.Wenzel@bmw.de ** ** ** ** PURPOSE : ** ** ** ** REMARKS : ** ** ** ** PLATFORM DEPENDANT [yes/no]: yes ** ** ** ** TO BE CHANGED BY USER [yes/no]: no ** ** ** *******************************************************************************/ /******************************************************************************* ** Author Identity ** ******************************************************************************** ** ** ** Initials Name Company ** ** -------- ------------------------- ---------------------------------- ** ** aw Alexander Wenzel BMW ** *******************************************************************************/ #include #include #include /* for printf() and fprintf() */ #include /* for atoi() and exit() */ #include /* for memset() */ #include /* for close() */ #include "dlt_common_api.h" DLT_DECLARE_CONTEXT(mycontext) /** * Print usage information of tool. */ void usage() { char version[255]; dlt_get_version(version, 255); printf("Usage: dlt-example-common-api [options] message\n"); printf("Generate DLT messages and store them to file or send them to daemon.\n"); printf("%s \n", version); printf("Options:\n"); printf(" -d delay Milliseconds to wait between sending messages (Default: 500)\n"); printf(" -f filename Use local log file instead of sending to daemon\n"); printf(" -n count Number of messages to be generated (Default: 10)\n"); printf(" -g Switch to non-verbose mode (Default: verbose mode)\n"); printf(" -a Enable local printing of DLT messages (Default: disabled)\n"); printf(" -m mode Set log mode 0=off,1=external,2=internal,3=both\n"); #ifdef DLT_TEST_ENABLE printf(" -c Corrupt user header\n"); printf(" -s size Corrupt message size\n"); printf(" -z size Size of message\n"); #endif /* DLT_TEST_ENABLE */ } /** * Main function of tool. */ int main(int argc, char *argv[]) { #ifdef DLT_TEST_ENABLE int cflag = 0; char *svalue = 0; char *zvalue = 0; #endif /* DLT_TEST_ENABLE */ int gflag = 0; char *dvalue = 0; char *nvalue = 0; char *message = 0; int index; int c; char *text; int num, maxnum; int delay; struct timespec ts; int state = -1, newstate; opterr = 0; #ifdef DLT_TEST_ENABLE while ((c = getopt (argc, argv, "vgcd:n:z:s:")) != -1) #else while ((c = getopt (argc, argv, "vgd:n:")) != -1) #endif /* DLT_TEST_ENABLE */ { switch (c) { #ifdef DLT_TEST_ENABLE case 'c': { cflag = 1; break; } case 's': { svalue = optarg; break; } case 'z': { zvalue = optarg; break; } #endif /* DLT_TEST_ENABLE */ case 'g': { gflag = 1; break; } case 'd': { dvalue = optarg; break; } case 'n': { nvalue = optarg; break; } case '?': { if ((optopt == 'd') || (optopt == 'f') || (optopt == 'n')) fprintf (stderr, "Option -%c requires an argument.\n", optopt); else if (isprint (optopt)) fprintf (stderr, "Unknown option `-%c'.\n", optopt); else fprintf (stderr, "Unknown option character `\\x%x'.\n", optopt); /* unknown or wrong option used, show usage information and terminate */ usage(); return -1; } default: { abort (); break;/*for parasoft */ } } } for (index = optind; index < argc; index++) message = argv[index]; if (message == 0) { /* no message, show usage and terminate */ fprintf(stderr, "ERROR: No message selected\n"); usage(); return -1; } DLT_REGISTER_APP("LOG", "Test Application for Logging"); DLT_REGISTER_CONTEXT_APP(mycontext, "TEST", "LOG", "Test Context for Logging"); text = message; if (nvalue) maxnum = atoi(nvalue); else maxnum = 10; if (dvalue) delay = atoi(dvalue) * 1000000; else delay = 500 * 1000000; if (gflag) { /* DLT messages to test Fibex non-verbose description: dlt-example-non-verbose.xml */ DLT_LOG_ID0(mycontext, DLT_LOG_INFO, 10); DLT_LOG_ID1(mycontext, DLT_LOG_INFO, 11, DLT_UINT16(1011)); DLT_LOG_ID2(mycontext, DLT_LOG_INFO, 12, DLT_UINT32(1012), DLT_UINT32(1013)); DLT_LOG_ID2(mycontext, DLT_LOG_INFO, 13, DLT_UINT8(123), DLT_FLOAT32(1.12)); DLT_LOG_ID1(mycontext, DLT_LOG_INFO, 14, DLT_STRING("DEAD BEEF")); } #ifdef DLT_TEST_ENABLE if (cflag) dlt_user_test_corrupt_user_header(1); if (svalue) dlt_user_test_corrupt_message_size(1, atoi(svalue)); if (zvalue) { char *buffer = malloc(atoi(zvalue)); if (buffer == 0) { /* no message, show usage and terminate */ fprintf(stderr, "Cannot allocate buffer memory!\n"); return -1; } DLT_LOG2(mycontext, DLT_LOG_WARN, DLT_STRING(text), DLT_RAW(buffer, atoi(zvalue))); free(buffer); } #endif /* DLT_TEST_ENABLE */ for (num = 0; num < maxnum; num++) { printf("Send %d %s\n", num, text); newstate = dlt_get_log_state(); if (state != newstate) { state = newstate; if (state == -1) printf("Client unknown state!\n"); else if (state == 0) printf("Client disconnected!\n"); else if (state == 1) printf("Client connected!\n"); } if (gflag) /* Non-verbose mode */ DLT_LOG_ID2(mycontext, DLT_LOG_WARN, num, DLT_INT(num), DLT_STRING(text)); else /* Verbose mode */ DLT_LOG2(mycontext, DLT_LOG_WARN, DLT_INT(num), DLT_STRING(text)); if (delay > 0) { ts.tv_sec = delay / 1000000000; ts.tv_nsec = delay % 1000000000; nanosleep(&ts, NULL); } } sleep(1); DLT_UNREGISTER_CONTEXT(mycontext); DLT_UNREGISTER_APP(); return 0; } dlt-daemon-2.18.4/src/examples/dlt-example-user-func.c000066400000000000000000000226731353342203500225360ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2011-2015, BMW AG * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author Alexander Wenzel * * \copyright Copyright © 2011-2015 BMW AG. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file dlt-example-user-func.c */ /******************************************************************************* ** ** ** SRC-MODULE: dlt-example-user-func.cpp ** ** ** ** TARGET : linux ** ** ** ** PROJECT : DLT ** ** ** ** AUTHOR : Alexander Wenzel Alexander.AW.Wenzel@bmw.de ** ** Markus Klein ** ** ** ** PURPOSE : ** ** ** ** REMARKS : ** ** ** ** PLATFORM DEPENDANT [yes/no]: yes ** ** ** ** TO BE CHANGED BY USER [yes/no]: no ** ** ** *******************************************************************************/ /******************************************************************************* ** Author Identity ** ******************************************************************************** ** ** ** Initials Name Company ** ** -------- ------------------------- ---------------------------------- ** ** aw Alexander Wenzel BMW ** ** mk Markus Klein Fraunhofer ESK ** *******************************************************************************/ /******************************************************************************* ** Revision Control History ** *******************************************************************************/ /* * $LastChangedRevision: 1670 $ * $LastChangedDate: 2011-04-08 15:12:06 +0200 (Fr, 08. Apr 2011) $ * $LastChangedBy$ * Initials Date Comment * aw 13.01.2010 initial */ #include #include #include /* for printf() and fprintf() */ #include /* for atoi() and exit() */ #include /* for memset() */ #include /* for close() */ #include "dlt.h" #include "dlt_common.h" /* for dlt_get_version() */ int dlt_user_injection_callback(uint32_t service_id, void *data, uint32_t length); DltContext mycontext; DltContextData mycontextdata; /** * Print usage information of tool. */ void usage() { char version[255]; dlt_get_version(version, 255); printf("Usage: dlt-example-user-func [options] message\n"); printf("Generate DLT messages and store them to file or send them to daemon.\n"); printf("%s \n", version); printf("Options:\n"); printf(" -d delay Milliseconds to wait between sending messages (Default: 500)\n"); printf(" -f filename Use local log file instead of sending to daemon\n"); printf(" -n count Number of messages to be generated (Default: 10)\n"); printf(" -g Switch to non-verbose mode (Default: verbose mode)\n"); printf(" -a Enable local printing of DLT messages (Default: disabled)\n"); } /** * Main function of tool. */ int main(int argc, char *argv[]) { int gflag = 0; int aflag = 0; char *dvalue = 0; char *fvalue = 0; char *nvalue = 0; char *message = 0; int index; int c; char *text; int num, maxnum; int delay; struct timespec ts; opterr = 0; while ((c = getopt (argc, argv, "vgad:f:n:")) != -1) switch (c) { case 'g': { gflag = 1; break; } case 'a': { aflag = 1; break; } case 'd': { dvalue = optarg; break; } case 'f': { fvalue = optarg; break; } case 'n': { nvalue = optarg; break; } case '?': { if ((optopt == 'd') || (optopt == 'f') || (optopt == 'n')) fprintf (stderr, "Option -%c requires an argument.\n", optopt); else if (isprint (optopt)) fprintf (stderr, "Unknown option `-%c'.\n", optopt); else fprintf (stderr, "Unknown option character `\\x%x'.\n", optopt); /* unknown or wrong option used, show usage information and terminate */ usage(); return -1; } default: { abort (); return -1;/*for parasoft */ } } for (index = optind; index < argc; index++) message = argv[index]; if (message == 0) { /* no message, show usage and terminate */ fprintf(stderr, "ERROR: No message selected\n"); usage(); return -1; } if (fvalue) { /* DLT is intialised automatically, except another output target will be used */ if (dlt_init_file(fvalue) < 0) /* log to file */ return -1; } dlt_register_app("LOG", "Test Application for Logging"); dlt_register_context(&mycontext, "TEST", "Test Context for Logging"); dlt_register_injection_callback(&mycontext, 0xFFF, dlt_user_injection_callback); text = message; if (gflag) dlt_nonverbose_mode(); if (aflag) dlt_enable_local_print(); if (nvalue) maxnum = atoi(nvalue); else maxnum = 10; if (dvalue) delay = atoi(dvalue) * 1000000; else delay = 500 * 1000000; if (gflag) { /* DLT messages to test Fibex non-verbose description: dlt-example-non-verbose.xml */ if (dlt_user_log_write_start_id(&mycontext, &mycontextdata, DLT_LOG_INFO, 10) > 0) dlt_user_log_write_finish(&mycontextdata); if (dlt_user_log_write_start_id(&mycontext, &mycontextdata, DLT_LOG_INFO, 11) > 0) { dlt_user_log_write_uint16(&mycontextdata, 1011); dlt_user_log_write_finish(&mycontextdata); } if (dlt_user_log_write_start_id(&mycontext, &mycontextdata, DLT_LOG_INFO, 12) > 0) { dlt_user_log_write_uint32(&mycontextdata, 1012); dlt_user_log_write_uint32(&mycontextdata, 1013); dlt_user_log_write_finish(&mycontextdata); } if (dlt_user_log_write_start_id(&mycontext, &mycontextdata, DLT_LOG_INFO, 13) > 0) { dlt_user_log_write_uint8(&mycontextdata, 123); dlt_user_log_write_float32(&mycontextdata, 1.12); dlt_user_log_write_finish(&mycontextdata); } if (dlt_user_log_write_start_id(&mycontext, &mycontextdata, DLT_LOG_INFO, 14) > 0) { dlt_user_log_write_string(&mycontextdata, "DEAD BEEF"); dlt_user_log_write_finish(&mycontextdata); } } for (num = 0; num < maxnum; num++) { printf("Send %d %s\n", num, text); if (gflag) { /* Non-verbose mode */ if (dlt_user_log_write_start_id(&mycontext, &mycontextdata, DLT_LOG_WARN, num) > 0) { dlt_user_log_write_int(&mycontextdata, num); dlt_user_log_write_string(&mycontextdata, text); dlt_user_log_write_finish(&mycontextdata); } } else /* Verbose mode */ if (dlt_user_log_write_start(&mycontext, &mycontextdata, DLT_LOG_WARN) > 0) { dlt_user_log_write_int(&mycontextdata, num); dlt_user_log_write_string(&mycontextdata, text); dlt_user_log_write_finish(&mycontextdata); } if (delay > 0) { ts.tv_sec = delay / 1000000000; ts.tv_nsec = delay % 1000000000; nanosleep(&ts, NULL); } } dlt_unregister_context(&mycontext); dlt_unregister_app(); return 0; } int dlt_user_injection_callback(uint32_t service_id, void *data, uint32_t length) { char text[1024]; printf("Injection %d, Length=%d \n", service_id, length); if (length > 0) { dlt_print_mixed_string(text, 1024, data, length, 0); printf("%s \n", text); } return 0; } dlt-daemon-2.18.4/src/examples/dlt-example-user.c000066400000000000000000000335151353342203500216020ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2011-2015, BMW AG * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author Alexander Wenzel * * \copyright Copyright © 2011-2015 BMW AG. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file dlt-example-user.c */ /******************************************************************************* ** ** ** SRC-MODULE: dlt-example-user.c ** ** ** ** TARGET : linux ** ** ** ** PROJECT : DLT ** ** ** ** AUTHOR : Alexander Wenzel Alexander.AW.Wenzel@bmw.de ** ** Markus Klein ** ** ** ** PURPOSE : ** ** ** ** REMARKS : ** ** ** ** PLATFORM DEPENDANT [yes/no]: yes ** ** ** ** TO BE CHANGED BY USER [yes/no]: no ** ** ** *******************************************************************************/ /******************************************************************************* ** Author Identity ** ******************************************************************************** ** ** ** Initials Name Company ** ** -------- ------------------------- ---------------------------------- ** ** aw Alexander Wenzel BMW ** ** mk Markus Klein Fraunhofer ESK ** *******************************************************************************/ /******************************************************************************* ** Revision Control History ** *******************************************************************************/ /* * $LastChangedRevision: 1670 $ * $LastChangedDate: 2011-04-08 15:12:06 +0200 (Fr, 08. Apr 2011) $ * $LastChangedBy$ * Initials Date Comment * aw 13.01.2010 initial */ #include #include #include /* for printf() and fprintf() */ #include /* for atoi() and exit() */ #include /* for memset() */ #include /* for close() */ #include "dlt.h" #include "dlt_common.h" /* for dlt_get_version() */ int dlt_user_injection_callback(uint32_t service_id, void *data, uint32_t length); int dlt_user_injection_callback_with_specific_data(uint32_t service_id, void *data, uint32_t length, void *priv_data); void dlt_user_log_level_changed_callback(char context_id[DLT_ID_SIZE], uint8_t log_level, uint8_t trace_status); DLT_DECLARE_CONTEXT(mycontext1) DLT_DECLARE_CONTEXT(mycontext2) DLT_DECLARE_CONTEXT(mycontext3) /** * Print usage information of tool. */ void usage() { char version[255]; dlt_get_version(version, 255); printf("Usage: dlt-example-user [options] message\n"); printf("Generate DLT messages and store them to file or send them to daemon.\n"); printf("%s \n", version); printf("Options:\n"); printf(" -d delay Milliseconds to wait between sending messages (Default: 500)\n"); printf(" -f filename Use local log file instead of sending to daemon\n"); printf(" -n count Number of messages to be generated (Default: 10)\n"); printf(" -g Switch to non-verbose mode (Default: verbose mode)\n"); printf(" -a Enable local printing of DLT messages (Default: disabled)\n"); printf(" -k Send marker message\n"); printf(" -m mode Set log mode 0=off,1=external,2=internal,3=both\n"); printf(" -l level Set log level to , level=-1..6\n"); printf(" -t timeout Set timeout when sending messages at exit, in ms (Default: 10000 = 10sec)\n"); printf(" -r size Send raw data with specified size instead of string\n"); #ifdef DLT_TEST_ENABLE printf(" -c Corrupt user header\n"); printf(" -s size Corrupt message size\n"); printf(" -z size Size of message\n"); #endif /* DLT_TEST_ENABLE */ } /** * Main function of tool. */ int main(int argc, char *argv[]) { int gflag = 0; int aflag = 0; int kflag = 0; #ifdef DLT_TEST_ENABLE int cflag = 0; char *svalue = 0; char *zvalue = 0; #endif /* DLT_TEST_ENABLE */ char *dvalue = 0; char *fvalue = 0; char *nvalue = 0; char *mvalue = 0; char *message = 0; int lvalue = DLT_LOG_WARN; char *tvalue = 0; int rvalue = -1; int index; int c; char *text; int num, maxnum; int delay; struct timespec ts; int state = -1, newstate; opterr = 0; #ifdef DLT_TEST_ENABLE while ((c = getopt (argc, argv, "vgakcd:f:n:m:z:r:s:l:t:")) != -1) #else while ((c = getopt (argc, argv, "vgakd:f:n:m:l:r:t:")) != -1) #endif /* DLT_TEST_ENABLE */ { switch (c) { case 'g': { gflag = 1; break; } case 'a': { aflag = 1; break; } case 'k': { kflag = 1; break; } #ifdef DLT_TEST_ENABLE case 'c': { cflag = 1; break; } case 's': { svalue = optarg; break; } case 'z': { zvalue = optarg; break; } #endif /* DLT_TEST_ENABLE */ case 'd': { dvalue = optarg; break; } case 'f': { fvalue = optarg; break; } case 'n': { nvalue = optarg; break; } case 'm': { mvalue = optarg; break; } case 'l': { lvalue = atoi(optarg); break; } case 't': { tvalue = optarg; break; } case 'r': { rvalue = atoi(optarg); break; } case '?': { if ((optopt == 'd') || (optopt == 'f') || (optopt == 'n') || (optopt == 'l') || (optopt == 't')) fprintf (stderr, "Option -%c requires an argument.\n", optopt); else if (isprint (optopt)) fprintf (stderr, "Unknown option `-%c'.\n", optopt); else fprintf (stderr, "Unknown option character `\\x%x'.\n", optopt); /* unknown or wrong option used, show usage information and terminate */ usage(); return -1; } default: { abort (); break;/*for parasoft */ } } } if (rvalue == -1) { for (index = optind; index < argc; index++) message = argv[index]; } else { /* allocate raw buffer */ message = calloc(sizeof(char), rvalue); memset(message, 'X', rvalue - 1); } if (message == 0) { /* no message, show usage and terminate */ fprintf(stderr, "ERROR: No message selected\n"); usage(); return -1; } if (fvalue) { /* DLT is initialized automatically, except another output target will be used */ if (dlt_init_file(fvalue) < 0) /* log to file */ return -1; } dlt_with_session_id(1); dlt_with_timestamp(1); dlt_with_ecu_id(1); dlt_verbose_mode(); DLT_REGISTER_APP("LOG", "Test Application for Logging"); DLT_REGISTER_CONTEXT(mycontext1, "TEST", "Test Context for Logging"); DLT_REGISTER_CONTEXT_LLCCB(mycontext2, "TS1", "Test Context1 for injection", dlt_user_log_level_changed_callback); DLT_REGISTER_CONTEXT_LLCCB(mycontext3, "TS2", "Test Context2 for injection", dlt_user_log_level_changed_callback); DLT_REGISTER_INJECTION_CALLBACK(mycontext1, 0x1000, dlt_user_injection_callback); DLT_REGISTER_INJECTION_CALLBACK_WITH_ID(mycontext2, 0x1000, dlt_user_injection_callback_with_specific_data, (void *)"TS1 context"); DLT_REGISTER_INJECTION_CALLBACK(mycontext2, 0x1001, dlt_user_injection_callback); DLT_REGISTER_INJECTION_CALLBACK_WITH_ID(mycontext3, 0x1000, dlt_user_injection_callback_with_specific_data, (void *)"TS2 context"); DLT_REGISTER_INJECTION_CALLBACK(mycontext3, 0x1001, dlt_user_injection_callback); DLT_REGISTER_LOG_LEVEL_CHANGED_CALLBACK(mycontext1, dlt_user_log_level_changed_callback); text = message; if (mvalue) { printf("Set log mode to %d\n", atoi(mvalue)); dlt_set_log_mode(atoi(mvalue)); } if (gflag) DLT_NONVERBOSE_MODE(); if (aflag) DLT_ENABLE_LOCAL_PRINT(); if (kflag) DLT_LOG_MARKER(); if (nvalue) maxnum = atoi(nvalue); else maxnum = 10; if (dvalue) delay = atoi(dvalue) * 1000000; else delay = 500 * 1000000; if (tvalue) dlt_set_resend_timeout_atexit(atoi(tvalue)); if (gflag) { /* DLT messages to test Fibex non-verbose description: dlt-example-non-verbose.xml */ DLT_LOG_ID(mycontext1, DLT_LOG_INFO, 10); DLT_LOG_ID(mycontext1, DLT_LOG_INFO, 11, DLT_UINT16(1011)); DLT_LOG_ID(mycontext1, DLT_LOG_INFO, 12, DLT_UINT32(1012), DLT_UINT32(1013)); DLT_LOG_ID(mycontext1, DLT_LOG_INFO, 13, DLT_UINT8(123), DLT_FLOAT32(1.12)); DLT_LOG_ID(mycontext1, DLT_LOG_INFO, 14, DLT_STRING("DEAD BEEF")); } #ifdef DLT_TEST_ENABLE if (cflag) dlt_user_test_corrupt_user_header(1); if (svalue) dlt_user_test_corrupt_message_size(1, atoi(svalue)); if (zvalue) { char *buffer = malloc(atoi(zvalue)); if (buffer == 0) { /* no message, show usage and terminate */ fprintf(stderr, "Cannot allocate buffer memory!\n"); return -1; } DLT_LOG(mycontext1, DLT_LOG_WARN, DLT_STRING(text), DLT_RAW(buffer, atoi(zvalue))); free(buffer); } #endif /* DLT_TEST_ENABLE */ for (num = 0; num < maxnum; num++) { printf("Send %d %s\n", num, text); newstate = dlt_get_log_state(); if (state != newstate) { state = newstate; if (state == -1) printf("Client unknown state!\n"); else if (state == 0) printf("Client disconnected!\n"); else if (state == 1) printf("Client connected!\n"); } if (gflag) { /* Non-verbose mode */ DLT_LOG_ID(mycontext1, lvalue, num, DLT_INT(num), DLT_STRING(text)); } else { if (rvalue == -1) /* Verbose mode */ DLT_LOG(mycontext1, lvalue, DLT_INT(num), DLT_STRING(text)); else DLT_LOG(mycontext1, lvalue, DLT_RAW(text, rvalue)); } if (delay > 0) { ts.tv_sec = delay / 1000000000; ts.tv_nsec = delay % 1000000000; nanosleep(&ts, NULL); } } sleep(1); DLT_UNREGISTER_CONTEXT(mycontext1); DLT_UNREGISTER_APP(); return 0; } int dlt_user_injection_callback(uint32_t service_id, void *data, uint32_t length) { char text[1024]; DLT_LOG(mycontext1, DLT_LOG_INFO, DLT_STRING("Injection: "), DLT_UINT32(service_id)); printf("Injection %d, Length=%d \n", service_id, length); if (length > 0) { dlt_print_mixed_string(text, 1024, data, length, 0); DLT_LOG(mycontext1, DLT_LOG_INFO, DLT_STRING("Data: "), DLT_STRING(text)); printf("%s \n", text); } return 0; } int dlt_user_injection_callback_with_specific_data(uint32_t service_id, void *data, uint32_t length, void *priv_data) { char text[1024]; DLT_LOG(mycontext1, DLT_LOG_INFO, DLT_STRING("Injection: "), DLT_UINT32(service_id)); printf("Injection %d, Length=%d \n", service_id, length); if (length > 0) { dlt_print_mixed_string(text, 1024, data, length, 0); DLT_LOG(mycontext1, DLT_LOG_INFO, DLT_STRING("Data: "), DLT_STRING(text), DLT_STRING(priv_data)); printf("%s \n", text); } return 0; } void dlt_user_log_level_changed_callback(char context_id[DLT_ID_SIZE], uint8_t log_level, uint8_t trace_status) { char text[5]; text[4] = 0; memcpy(text, context_id, DLT_ID_SIZE); printf("Log level changed of context %s, LogLevel=%u, TraceState=%u \n", text, log_level, trace_status); } dlt-daemon-2.18.4/src/gateway/000077500000000000000000000000001353342203500160625ustar00rootroot00000000000000dlt-daemon-2.18.4/src/gateway/CMakeLists.txt000066400000000000000000000012501353342203500206200ustar00rootroot00000000000000####### # SPDX license identifier: MPL-2.0 # # Copyright (C) 2015, Advanced Driver Information Technology # This code is developed by Advanced Driver Information Technology. # Copyright of Advanced Driver Information Technology, Bosch and DENSO. # # This file is part of GENIVI Project DLT - Diagnostic Log and Trace. # # This Source Code Form is subject to the terms of the # Mozilla Public License (MPL), v. 2.0. # If a copy of the MPL was not distributed with this file, # You can obtain one at http://mozilla.org/MPL/2.0/. # # For further information see http://www.genivi.org/. ####### INSTALL(FILES dlt_gateway.conf DESTINATION ${CONFIGURATION_FILES_DIR} COMPONENT base) dlt-daemon-2.18.4/src/gateway/dlt_gateway.c000066400000000000000000001531211353342203500205350ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2015 Advanced Driver Information Technology. * This code is developed by Advanced Driver Information Technology. * Copyright of Advanced Driver Information Technology, Bosch and DENSO. * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author * Christoph Lipka * Saya Sugiura * * \copyright Copyright © 2015-2018 Advanced Driver Information Technology. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file dlt_gateway.c */ #include #include #include #include #include #include #include #include #include #include #include "dlt_gateway.h" #include "dlt_gateway_internal.h" #include "dlt_config_file_parser.h" #include "dlt_common.h" #include "dlt-daemon_cfg.h" #include "dlt_daemon_common_cfg.h" #include "dlt_daemon_event_handler.h" #include "dlt_daemon_connection.h" #include "dlt_daemon_client.h" #include "dlt_daemon_offline_logstorage.h" /** * Check if given string is a valid IP address * * @param con DltGatewayConnection to be updated * @param value string to be tested * @return Value from DltReturnValue enum */ DLT_STATIC DltReturnValue dlt_gateway_check_ip(DltGatewayConnection *con, char *value) { struct sockaddr_in sa; int ret = DLT_RETURN_ERROR; if ((con == NULL) || (value == NULL)) { dlt_vlog(LOG_ERR, "%s: wrong parameter\n", __func__); return DLT_RETURN_WRONG_PARAMETER; } ret = inet_pton(AF_INET, value, &(sa.sin_addr)); /* valid IP address */ if (ret != 0) { con->ip_address = strdup(value); if (con->ip_address == NULL) { dlt_log(LOG_ERR, "Cannot copy passive node IP address string\n"); return DLT_RETURN_ERROR; } return DLT_RETURN_OK; } else { dlt_log(LOG_ERR, "IP address is not valid\n"); } return DLT_RETURN_ERROR; } /** * Check port number * * @param con DltGatewayConnection to be updated * @param value string to be tested * @return Value from DltReturnValue enum */ DLT_STATIC DltReturnValue dlt_gateway_check_port(DltGatewayConnection *con, char *value) { long int tmp = -1; if ((con == NULL) || (value == NULL)) { dlt_vlog(LOG_ERR, "%s: wrong parameter\n", __func__); return DLT_RETURN_WRONG_PARAMETER; } errno = 0; tmp = strtol(value, NULL, 10); if ((errno == ERANGE && (tmp == LONG_MAX || tmp == LONG_MIN)) || (errno != 0 && tmp == 0)) { dlt_vlog(LOG_ERR, "%s: cannot convert port number\n", __func__); return DLT_RETURN_ERROR; } /* port ranges for unprivileged applications */ if ((tmp > IPPORT_RESERVED) && ((unsigned)tmp <= USHRT_MAX)) { con->port = (int)tmp; return DLT_RETURN_OK; } else { dlt_log(LOG_ERR, "Port number is invalid\n"); } return DLT_RETURN_ERROR; } /** * Check ECU name * * @param con DltGatewayConnection to be updated * @param value string to be used as ECU identifier * @return Value from DltReturnValue enum */ DLT_STATIC DltReturnValue dlt_gateway_check_ecu(DltGatewayConnection *con, char *value) { if ((con == NULL) || (value == NULL)) { dlt_vlog(LOG_ERR, "%s: wrong parameter\n", __func__); return DLT_RETURN_WRONG_PARAMETER; } con->ecuid = strdup(value); if (con->ecuid == NULL) return DLT_RETURN_ERROR; return DLT_RETURN_OK; } /** * Check connection trigger * * @param con DltGatewayConnection to be updated * @param value string to be tested * @return Value from DltReturnValue enum */ DLT_STATIC DltReturnValue dlt_gateway_check_connect_trigger(DltGatewayConnection *con, char *value) { if ((con == NULL) || (value == NULL)) { dlt_vlog(LOG_ERR, "%s: wrong parameter\n", __func__); return DLT_RETURN_WRONG_PARAMETER; } if (strncasecmp(value, "OnStartup", strlen("OnStartup")) == 0) { con->trigger = DLT_GATEWAY_ON_STARTUP; } else if (strncasecmp(value, "OnDemand", strlen("OnDemand")) == 0) { con->trigger = DLT_GATEWAY_ON_DEMAND; } else { dlt_log(LOG_ERR, "Wrong connection trigger state given.\n"); con->trigger = DLT_GATEWAY_UNDEFINED; return DLT_RETURN_ERROR; } return DLT_RETURN_OK; } /** * Check connection timeout value * * @param con DltGatewayConnection to be updated * @param value string to be tested * @return Value from DltReturnValue enum */ DLT_STATIC DltReturnValue dlt_gateway_check_timeout(DltGatewayConnection *con, char *value) { if ((con == NULL) || (value == NULL)) { dlt_vlog(LOG_ERR, "%s: wrong parameter\n", __func__); return DLT_RETURN_WRONG_PARAMETER; } con->timeout = (int)strtol(value, NULL, 10); if (con->timeout > 0) return DLT_RETURN_OK; return DLT_RETURN_ERROR; } /** * Check the value for SendSerialHeader * * @param con DltGatewayConnection to be updated * @param value string to be tested * @return Value from DltReturnValue enum */ DLT_STATIC DltReturnValue dlt_gateway_check_send_serial(DltGatewayConnection *con, char *value) { if ((con == NULL) || (value == NULL)) { dlt_vlog(LOG_ERR, "%s: wrong parameter\n", __func__); return DLT_RETURN_WRONG_PARAMETER; } con->send_serial = !!((int)strtol(value, NULL, 10)); return DLT_RETURN_OK; } /** * Allocate passive control messages * * @param con DltGatewayConnection to be updated * @return Value from DltReturnValue enum */ DLT_STATIC DltReturnValue dlt_gateway_allocate_control_messages(DltGatewayConnection *con) { if (con == NULL) { dlt_vlog(LOG_ERR, "%s: wrong parameter\n", __func__); return DLT_RETURN_WRONG_PARAMETER; } if (con->p_control_msgs == NULL) { con->p_control_msgs = calloc(1, sizeof(DltPassiveControlMessage)); if (!con->p_control_msgs) { dlt_log(LOG_ERR, "Passive Control Message could not be allocated\n"); return DLT_RETURN_ERROR; } } else { con->p_control_msgs->next = calloc(1, sizeof(DltPassiveControlMessage)); if (!con->p_control_msgs->next) { dlt_log(LOG_ERR, "Passive Control Message could not be allocated\n"); return DLT_RETURN_ERROR; } con->p_control_msgs = con->p_control_msgs->next; } return DLT_RETURN_OK; } /** * Check the specified control messages identifier * * @param con DltGatewayConnection to be updated * @param value string to be tested * @return Value from DltReturnValue enum */ DLT_STATIC DltReturnValue dlt_gateway_check_control_messages(DltGatewayConnection *con, char *value) { /* list of allowed clients given */ char *token = NULL; char *rest = NULL; DltPassiveControlMessage *head = NULL; if ((con == NULL) || (value == NULL)) { dlt_vlog(LOG_ERR, "%s: wrong parameter\n", __func__); return DLT_RETURN_WRONG_PARAMETER; } if (strlen(value) == 0) return DLT_RETURN_OK; /* set on startup control msg id and interval*/ token = strtok_r(value, ",", &rest); while (token != NULL) { if (dlt_gateway_allocate_control_messages(con) != DLT_RETURN_OK) { dlt_log(LOG_ERR, "Passive Control Message could not be allocated\n"); return DLT_RETURN_ERROR; } con->p_control_msgs->id = strtol(token, NULL, 16); con->p_control_msgs->user_id = DLT_SERVICE_ID_PASSIVE_NODE_CONNECT; con->p_control_msgs->type = CONTROL_MESSAGE_ON_STARTUP; con->p_control_msgs->req = CONTROL_MESSAGE_NOT_REQUESTED; con->p_control_msgs->interval = -1; if (head == NULL) head = con->p_control_msgs; if ((errno == EINVAL) || (errno == ERANGE)) { dlt_vlog(LOG_ERR, "Control message ID is not an integer: %s\n", token); return DLT_RETURN_ERROR; } else if ((con->p_control_msgs->id < DLT_SERVICE_ID_SET_LOG_LEVEL) || (con->p_control_msgs->id >= DLT_SERVICE_ID_LAST_ENTRY)) { dlt_vlog(LOG_ERR, "Control message ID is not valid: %s\n", token); return DLT_RETURN_ERROR; } token = strtok_r(NULL, ",", &rest); } /* get back to head */ con->p_control_msgs = head; con->head = head; return DLT_RETURN_OK; } /** * Check the specified periodic control messages identifier * * @param con DltGatewayConnection to be updated * @param value string to be tested * @return Value from DltReturnValue enum */ DLT_STATIC DltReturnValue dlt_gateway_check_periodic_control_messages( DltGatewayConnection *con, char *value) { char *token = NULL; char *rest = NULL; DltPassiveControlMessage *head = NULL; if ((con == NULL) || (value == NULL)) { dlt_vlog(LOG_ERR, "%s: wrong parameter\n", __func__); return DLT_RETURN_WRONG_PARAMETER; } if (strlen(value) == 0) return DLT_RETURN_OK; /* store head address */ head = con->p_control_msgs; /* set periodic control msg id and interval*/ token = strtok_r(value, ",", &rest); while (token != NULL) { char *p_token = NULL; char *p_rest = NULL; uint32_t id = 0; p_token = strtok_r(token, ":", &p_rest); if ((p_token != NULL) && (strlen(p_token) != 0)) { id = strtol(p_token, NULL, 16); /* get back to head */ con->p_control_msgs = head; /* check if there is already id set in p_control_msgs */ while (con->p_control_msgs != NULL) { if (con->p_control_msgs->id == id) { con->p_control_msgs->type = CONTROL_MESSAGE_BOTH; con->p_control_msgs->interval = strtol(p_rest, NULL, 10); if (con->p_control_msgs->interval <= 0) dlt_vlog(LOG_WARNING, "%s interval is %d. It won't be send periodically.\n", dlt_get_service_name(con->p_control_msgs->id), con->p_control_msgs->interval); break; } con->p_control_msgs = con->p_control_msgs->next; } /* if the id is not added yet, p_control_msgs supposed to be NULL */ if (con->p_control_msgs == NULL) { /* get back to head */ con->p_control_msgs = head; /* go to last pointer */ while (con->p_control_msgs != NULL) { if (con->p_control_msgs->next == NULL) break; con->p_control_msgs = con->p_control_msgs->next; } if (dlt_gateway_allocate_control_messages(con) != DLT_RETURN_OK) { dlt_log(LOG_ERR, "Passive Control Message could not be allocated\n"); return DLT_RETURN_ERROR; } con->p_control_msgs->id = id; con->p_control_msgs->user_id = DLT_SERVICE_ID_PASSIVE_NODE_CONNECT; con->p_control_msgs->type = CONTROL_MESSAGE_PERIODIC; con->p_control_msgs->req = CONTROL_MESSAGE_NOT_REQUESTED; con->p_control_msgs->interval = strtol(p_rest, NULL, 10); if (con->p_control_msgs->interval <= 0) dlt_vlog(LOG_WARNING, "%s interval is %d. It won't be send periodically.\n", dlt_get_service_name(con->p_control_msgs->id), con->p_control_msgs->interval); if (head == NULL) head = con->p_control_msgs; } } if ((errno == EINVAL) || (errno == ERANGE)) { dlt_vlog(LOG_ERR, "Control message ID is not an integer: %s\n", p_token); return DLT_RETURN_ERROR; } else if ((con->p_control_msgs->id < DLT_SERVICE_ID_SET_LOG_LEVEL) || (con->p_control_msgs->id >= DLT_SERVICE_ID_LAST_ENTRY)) { dlt_vlog(LOG_ERR, "Control message ID is not valid: %s\n", p_token); return DLT_RETURN_ERROR; } token = strtok_r(NULL, ",", &rest); } /* get back to head */ con->p_control_msgs = head; con->head = head; return DLT_RETURN_OK; } /** * Expected entries for a passive node configuration * Caution: after changing entries here, * dlt_gateway_check_param needs to be updated as well * */ DLT_STATIC DltGatewayConf configuration_entries[GW_CONF_COUNT] = { [GW_CONF_IP_ADDRESS] = { .key = "IPaddress", .func = dlt_gateway_check_ip, .is_opt = 0 }, [GW_CONF_PORT] = { .key = "Port", .func = dlt_gateway_check_port, .is_opt = 1 }, [GW_CONF_ECUID] = { .key = "EcuID", .func = dlt_gateway_check_ecu, .is_opt = 0 }, [GW_CONF_CONNECT] = { .key = "Connect", .func = dlt_gateway_check_connect_trigger, .is_opt = 1 }, [GW_CONF_TIMEOUT] = { .key = "Timeout", .func = dlt_gateway_check_timeout, .is_opt = 0 }, [GW_CONF_SEND_CONTROL] = { .key = "SendControl", .func = dlt_gateway_check_control_messages, .is_opt = 1 }, [GW_CONF_SEND_PERIODIC_CONTROL] = { .key = "SendPeriodicControl", .func = dlt_gateway_check_periodic_control_messages, .is_opt = 1 }, [GW_CONF_SEND_SERIAL_HEADER] = { .key = "SendSerialHeader", .func = dlt_gateway_check_send_serial, .is_opt = 1 } }; #define DLT_GATEWAY_NUM_PROPERTIES_MAX GW_CONF_COUNT /** * Check if gateway connection configuration parameter is valid. * * @param gateway DltGateway * @param con DltGatewayConnection * @param ctype DltGatwayConnection property * @param value specified property value from configuration file * @return Value from DltReturnValue enum */ DLT_STATIC DltReturnValue dlt_gateway_check_param(DltGateway *gateway, DltGatewayConnection *con, DltGatewayConfType ctype, char *value) { if ((gateway == NULL) || (con == NULL) || (value == NULL)) { dlt_vlog(LOG_ERR, "%s: wrong parameter\n", __func__); return DLT_RETURN_WRONG_PARAMETER; } if (ctype < GW_CONF_COUNT) return configuration_entries[ctype].func(con, value); return DLT_RETURN_ERROR; } /** * Store gateway connection in internal data structure * * @param gateway DltGatway * @param tmp DltGatewayConnection * @param verbose verbose flag * @return 0 on success, -1 otherwise */ int dlt_gateway_store_connection(DltGateway *gateway, DltGatewayConnection *tmp, int verbose) { int i = 0; PRINT_FUNCTION_VERBOSE(verbose); if ((gateway == NULL) || (tmp == NULL)) { dlt_vlog(LOG_ERR, "%s: wrong parameter\n", __func__); return DLT_RETURN_WRONG_PARAMETER; } /* find next free entry in connection array */ while (i < gateway->num_connections) { if (gateway->connections[i].status == DLT_GATEWAY_UNINITIALIZED) break; i++; } if (&(gateway->connections[i]) == NULL) return DLT_RETURN_ERROR; /* store values */ gateway->connections[i].ip_address = strdup(tmp->ip_address); gateway->connections[i].ecuid = strdup(tmp->ecuid); gateway->connections[i].sock_domain = tmp->sock_domain; gateway->connections[i].sock_type = tmp->sock_type; gateway->connections[i].sock_protocol = tmp->sock_protocol; gateway->connections[i].port = tmp->port; gateway->connections[i].trigger = tmp->trigger; gateway->connections[i].timeout = tmp->timeout; gateway->connections[i].handle = 0; gateway->connections[i].status = DLT_GATEWAY_INITIALIZED; gateway->connections[i].p_control_msgs = tmp->p_control_msgs; gateway->connections[i].head = tmp->head; gateway->connections[i].send_serial = tmp->send_serial; if (dlt_client_init_port(&gateway->connections[i].client, gateway->connections[i].port, verbose) != 0) { free(gateway->connections[i].ip_address); gateway->connections[i].ip_address = NULL; free(gateway->connections[i].ecuid); gateway->connections[i].ecuid = NULL; free(gateway->connections[i].p_control_msgs); gateway->connections[i].p_control_msgs = NULL; dlt_log(LOG_CRIT, "dlt_client_init_port() failed for gateway connection\n"); return DLT_RETURN_ERROR; } /* setup DltClient Structure */ if (dlt_client_set_server_ip(&gateway->connections[i].client, gateway->connections[i].ip_address) == -1) { dlt_log(LOG_ERR, "dlt_client_set_server_ip() failed for gateway connection \n"); return DLT_RETURN_ERROR; } return DLT_RETURN_OK; } /** * Read configuration file and initialize connection data structures * * @param gateway DltGateway * @param config_file Gateway configuration * @param verbose verbose flag * @return 0 on success, -1 otherwise */ int dlt_gateway_configure(DltGateway *gateway, char *config_file, int verbose) { int ret = 0; int i = 0; DltConfigFile *file = NULL; PRINT_FUNCTION_VERBOSE(verbose); if ((gateway == NULL) || (config_file == 0) || (config_file[0] == '\0')) { dlt_vlog(LOG_ERR, "%s: wrong parameter\n", __func__); return DLT_RETURN_WRONG_PARAMETER; } /* read configuration file */ file = dlt_config_file_init(config_file); /* get number of entries and allocate memory to store information */ ret = dlt_config_file_get_num_sections(file, &gateway->num_connections); if (ret != 0) { dlt_config_file_release(file); dlt_log(LOG_ERR, "Invalid number of sections in configuration file\n"); return DLT_RETURN_ERROR; } gateway->connections = calloc(sizeof(DltGatewayConnection), gateway->num_connections); if (gateway->connections == NULL) { dlt_config_file_release(file); dlt_log(LOG_CRIT, "Memory allocation for gateway connections failed\n"); return DLT_RETURN_ERROR; } for (i = 0; i < gateway->num_connections; i++) { DltGatewayConnection tmp; int invalid = 0; DltGatewayConfType j = 0; char section[DLT_CONFIG_FILE_ENTRY_MAX_LEN] = { '\0' }; char value[DLT_CONFIG_FILE_ENTRY_MAX_LEN] = { '\0' }; memset(&tmp, 0, sizeof(tmp)); /* Set default */ tmp.send_serial = gateway->send_serial; tmp.port = DLT_DAEMON_TCP_PORT; ret = dlt_config_file_get_section_name(file, i, section); for (j = 0; j < GW_CONF_COUNT; j++) { ret = dlt_config_file_get_value(file, section, configuration_entries[j].key, value); if ((ret != 0) && configuration_entries[j].is_opt) { /* Use default values for this key */ dlt_vlog(LOG_WARNING, "Using default for %s.\n", configuration_entries[j].key); continue; } else if (ret != 0) { dlt_vlog(LOG_WARNING, "Missing configuration for %s.\n", configuration_entries[j].key); invalid = 1; break; } /* check value and store temporary */ ret = dlt_gateway_check_param(gateway, &tmp, j, value); if (ret != 0) dlt_vlog(LOG_ERR, "Configuration %s = %s is invalid.\n" "Using default.\n", configuration_entries[j].key, value); } if (invalid) { dlt_vlog(LOG_ERR, "%s configuration is invalid.\n" "Ignoring.\n", section); } else { ret = dlt_gateway_store_connection(gateway, &tmp, verbose); if (ret != 0) dlt_log(LOG_ERR, "Storing gateway connection data failed\n"); } /* strdup used inside some get_value function */ free(tmp.ecuid); tmp.ecuid = NULL; free(tmp.ip_address); tmp.ip_address = NULL; } dlt_config_file_release(file); return ret; } int dlt_gateway_init(DltDaemonLocal *daemon_local, int verbose) { PRINT_FUNCTION_VERBOSE(verbose); if (daemon_local == NULL) { dlt_vlog(LOG_ERR, "%s: wrong parameter\n", __func__); return DLT_RETURN_WRONG_PARAMETER; } DltGateway *gateway = &daemon_local->pGateway; if (gateway != NULL) { /* Get default value from daemon_local */ gateway->send_serial = daemon_local->flags.lflag; if (dlt_gateway_configure(gateway, daemon_local->flags.gatewayConfigFile, verbose) != 0) { dlt_log(LOG_ERR, "Gateway initialization failed\n"); return DLT_RETURN_ERROR; } } else { dlt_log(LOG_CRIT, "Pointer to Gateway structure is NULL\n"); return DLT_RETURN_ERROR; } /* ignore return value */ dlt_gateway_establish_connections(gateway, daemon_local, verbose); return DLT_RETURN_OK; } void dlt_gateway_deinit(DltGateway *gateway, int verbose) { DltPassiveControlMessage *msg; int i = 0; if (gateway == NULL) { dlt_vlog(LOG_ERR, "%s: wrong parameter\n", __func__); return; } PRINT_FUNCTION_VERBOSE(verbose); for (i = 0; i < gateway->num_connections; i++) { DltGatewayConnection *c = &gateway->connections[i]; dlt_client_cleanup(&c->client, verbose); free(c->ip_address); c->ip_address = NULL; free(c->ecuid); c->ecuid = NULL; while (c->p_control_msgs != NULL) { msg = c->p_control_msgs->next; free(c->p_control_msgs); c->p_control_msgs = msg; } } free(gateway->connections); gateway->connections = NULL; } /** * If connection to passive node established, add to event loop * * @param daemon_local DltDaemonLocal * @param con DltGatewayConnection * @param verbose verbose flag * @return 0 on success, -1 otherwise */ DLT_STATIC int dlt_gateway_add_to_event_loop(DltDaemonLocal *daemon_local, DltGatewayConnection *con, int verbose) { DltPassiveControlMessage *control_msg = NULL; int sendtime = 1; if ((daemon_local == NULL) || (con == NULL)) { dlt_vlog(LOG_ERR, "%s: wrong parameter\n", __func__); return DLT_RETURN_WRONG_PARAMETER; } /* connection to passive node established, add to event loop */ con->status = DLT_GATEWAY_CONNECTED; con->reconnect_cnt = 0; con->timeout_cnt = 0; con->sendtime_cnt = 0; /* setup dlt connection and add to poll event loop here */ if (dlt_connection_create(daemon_local, &daemon_local->pEvent, con->client.sock, POLLIN, DLT_CONNECTION_GATEWAY) != 0) { dlt_log(LOG_ERR, "Gateway connection creation failed\n"); return DLT_RETURN_ERROR; } /* immediately send configured control messages */ control_msg = con->p_control_msgs; while (control_msg != NULL) { if ((control_msg->type == CONTROL_MESSAGE_ON_STARTUP) || (control_msg->type == CONTROL_MESSAGE_BOTH)) { if (dlt_gateway_send_control_message(con, control_msg, NULL, verbose) == DLT_RETURN_OK) control_msg->req = CONTROL_MESSAGE_REQUESTED; } /* multiply periodic sending time */ if (((control_msg->type == CONTROL_MESSAGE_PERIODIC) || (control_msg->type == CONTROL_MESSAGE_BOTH)) && (control_msg->interval > 0)) sendtime *= control_msg->interval; control_msg = control_msg->next; } /* set periodic sending time */ con->sendtime = sendtime; con->sendtime_cnt = con->sendtime; return DLT_RETURN_OK; } int dlt_gateway_establish_connections(DltGateway *gateway, DltDaemonLocal *daemon_local, int verbose) { int i = 0; int ret = 0; PRINT_FUNCTION_VERBOSE(verbose); if ((gateway == NULL) || (daemon_local == NULL)) { dlt_vlog(LOG_ERR, "%s: wrong parameter\n", __func__); return DLT_RETURN_WRONG_PARAMETER; } for (i = 0; i < gateway->num_connections; i++) { DltGatewayConnection *con = &(gateway->connections[i]); DltPassiveControlMessage *control_msg = NULL; if (con == NULL) { dlt_log(LOG_CRIT, "Cannot retrieve gateway connection details\n"); return DLT_RETURN_ERROR; } if ((con->status != DLT_GATEWAY_CONNECTED) && (con->trigger != DLT_GATEWAY_ON_DEMAND) && (con->trigger != DLT_GATEWAY_DISABLED)) { ret = dlt_client_connect(&con->client, verbose); if (ret == 0) { /* setup dlt connection and add to poll event loop here */ if (dlt_gateway_add_to_event_loop(daemon_local, con, verbose) != DLT_RETURN_OK) { dlt_log(LOG_ERR, "Gateway connection creation failed\n"); return DLT_RETURN_ERROR; } } else { dlt_log(LOG_DEBUG, "Passive Node is not up. Connection failed.\n"); con->timeout_cnt++; if (con->timeout_cnt > con->timeout) { con->trigger = DLT_GATEWAY_DISABLED; dlt_log(LOG_WARNING, "Passive Node connection retry timed out. " "Give up.\n"); } } } else if ((con->status == DLT_GATEWAY_CONNECTED) && (con->trigger != DLT_GATEWAY_DISABLED)) { /* setup dlt connection and add to poll event loop here */ if (dlt_connection_create(daemon_local, &daemon_local->pEvent, con->client.sock, POLLIN, DLT_CONNECTION_GATEWAY) != 0) { dlt_log(LOG_ERR, "Gateway connection creation failed\n"); return DLT_RETURN_ERROR; } /* immediately send periodic configured control messages */ control_msg = con->p_control_msgs; while (control_msg != NULL) { if ((control_msg->type == CONTROL_MESSAGE_PERIODIC) || (control_msg->type == CONTROL_MESSAGE_BOTH)) { if (dlt_gateway_send_control_message(con, control_msg, NULL, verbose) == DLT_RETURN_OK) control_msg->req = CONTROL_MESSAGE_REQUESTED; } control_msg = control_msg->next; } /* check sendtime counter */ if (con->sendtime_cnt > 0) con->sendtime_cnt--; if (con->sendtime_cnt == 0) con->sendtime_cnt = con->sendtime; } } return DLT_RETURN_OK; } DltReceiver *dlt_gateway_get_connection_receiver(DltGateway *gateway, int fd) { int i = 0; if (gateway == NULL) { dlt_vlog(LOG_ERR, "%s: wrong parameter\n", __func__); return NULL; } for (i = 0; i < gateway->num_connections; i++) { DltGatewayConnection *c = &gateway->connections[i]; if ((c->status == DLT_GATEWAY_CONNECTED) && (c->client.sock == fd)) return &c->client.receiver; } return NULL; } /** * Parse GET_LOG_INFO * * @param daemon DltDaemon * @param ecu Ecu ID * @param msg DltMessage * @param req 1 if requested from gateway, 0 otherwise * @param verbose verbose flag * @return Value from DltReturnValue enum */ DLT_STATIC DltReturnValue dlt_gateway_parse_get_log_info(DltDaemon *daemon, char *ecu, DltMessage *msg, int req, int verbose) { char resp_text[DLT_RECEIVE_BUFSIZE] = { '\0' }; DltServiceGetLogInfoResponse *resp = NULL; AppIDsType app; ContextIDsInfoType con; int i = 0; int j = 0; PRINT_FUNCTION_VERBOSE(verbose); if ((msg == NULL) || (msg->databuffer == NULL)) { dlt_vlog(LOG_ERR, "%s: wrong parameter\n", __func__); return DLT_RETURN_WRONG_PARAMETER; } if (DLT_CHECK_RCV_DATA_SIZE(msg->datasize, sizeof(DltServiceGetLogInfoResponse)) < 0) return DLT_RETURN_ERROR; /* if the request was send from gateway, clear all application and context list */ if (req == CONTROL_MESSAGE_REQUESTED) { /* clear application list */ if (dlt_daemon_applications_clear(daemon, ecu, verbose) == DLT_RETURN_ERROR) { dlt_log(LOG_ERR, "Cannot clear applications list\n"); return DLT_RETURN_ERROR; } /* clear context list */ if (dlt_daemon_contexts_clear(daemon, ecu, verbose) == DLT_RETURN_ERROR) { dlt_log(LOG_ERR, "Cannot clear contexts list\n"); return DLT_RETURN_ERROR; } } /* check response */ if (dlt_message_payload(msg, resp_text, DLT_RECEIVE_BUFSIZE, DLT_OUTPUT_ASCII, 0) != DLT_RETURN_OK) { dlt_log(LOG_ERR, "GET_LOG_INFO payload failed\n"); return DLT_RETURN_ERROR; } /* prepare pointer to message request */ resp = (DltServiceGetLogInfoResponse *)calloc(1, sizeof(DltServiceGetLogInfoResponse)); if (resp == NULL) { dlt_log(LOG_ERR, "Get Log Info Response could not be allocated\n"); return DLT_RETURN_ERROR; } if (dlt_set_loginfo_parse_service_id(resp_text, &resp->service_id, &resp->status) != DLT_RETURN_OK) { dlt_log(LOG_ERR, "Parsing GET_LOG_INFO failed\n"); dlt_client_cleanup_get_log_info(resp); return DLT_RETURN_ERROR; } if (dlt_client_parse_get_log_info_resp_text(resp, resp_text) != DLT_RETURN_OK) { dlt_log(LOG_ERR, "Parsing GET_LOG_INFO failed\n"); dlt_client_cleanup_get_log_info(resp); return DLT_RETURN_ERROR; } for (i = 0; i < resp->log_info_type.count_app_ids; i++) { app = resp->log_info_type.app_ids[i]; /* add application */ if (dlt_daemon_application_add(daemon, app.app_id, 0, app.app_description, -1, ecu, verbose) == 0) { dlt_vlog(LOG_WARNING, "%s: dlt_daemon_application_add failed\n", __func__); dlt_client_cleanup_get_log_info(resp); return DLT_RETURN_ERROR; } for (j = 0; j < app.count_context_ids; j++) { con = app.context_id_info[j]; /* add context */ if (dlt_daemon_context_add(daemon, app.app_id, con.context_id, con.log_level, con.trace_status, 0, -1, con.context_description, ecu, verbose) == 0) { dlt_vlog(LOG_WARNING, "%s: dlt_daemon_context_add failed for %4s\n", __func__, app.app_id); dlt_client_cleanup_get_log_info(resp); return DLT_RETURN_ERROR; } } } /* free response */ dlt_client_cleanup_get_log_info(resp); return DLT_RETURN_OK; } /** * Parse GET_DEFAULT_LOG_LEVEL * * @param daemon DltDaemon * @param daemon_local DltDaemonLocal * @param ecu Ecu ID * @param msg DltMessage * @param verbose verbose flag * @return 0 on success, -1 otherwise */ DLT_STATIC int dlt_gateway_parse_get_default_log_level(DltDaemon *daemon, DltDaemonLocal *daemon_local, char *ecu, DltMessage *msg, int verbose) { DltServiceGetDefaultLogLevelResponse *resp = NULL; DltGatewayConnection *con = NULL; PRINT_FUNCTION_VERBOSE(verbose); if ((daemon == NULL) || (daemon_local == NULL)) { dlt_vlog(LOG_ERR, "%s: wrong parameter\n", __func__); return DLT_RETURN_WRONG_PARAMETER; } if (DLT_CHECK_RCV_DATA_SIZE(msg->datasize, sizeof(DltServiceGetDefaultLogLevelResponse)) < 0) { dlt_log(LOG_ERR, "Received data incomplete.\n"); return DLT_RETURN_ERROR; } /* prepare pointer to message request */ resp = (DltServiceGetDefaultLogLevelResponse *)(msg->databuffer); con = dlt_gateway_get_connection(&daemon_local->pGateway, ecu, verbose); if (con == NULL) { dlt_vlog(LOG_ERR, "No information about passive ECU: %s\n", ecu); return DLT_RETURN_ERROR; } con->default_log_level = resp->log_level; return DLT_RETURN_OK; } /** * Service offline logstorage * * @param daemon DltDaemon * @param daemon_local DltDaemonLocal * @param verbose int * @return 0 on success, -1 otherwise */ DLT_STATIC int dlt_gateway_control_service_logstorage(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose) { unsigned int connection_type = 0; int i = 0; if (daemon_local->flags.offlineLogstorageMaxDevices <= 0) { dlt_log(LOG_INFO, "Logstorage functionality not enabled or MAX device set is 0\n"); return DLT_RETURN_ERROR; } for (i = 0; i < daemon_local->flags.offlineLogstorageMaxDevices; i++) { connection_type = daemon->storage_handle[i].connection_type; if (connection_type == DLT_OFFLINE_LOGSTORAGE_DEVICE_CONNECTED) /* Check if log level of running application needs an update */ dlt_daemon_logstorage_update_application_loglevel(daemon, daemon_local, i, verbose); } return DLT_RETURN_OK; } DltReturnValue dlt_gateway_process_passive_node_messages(DltDaemon *daemon, DltDaemonLocal *daemon_local, DltReceiver *receiver, int verbose) { int i = 0; DltGateway *gateway = NULL; DltGatewayConnection *con = NULL; DltMessage msg = { 0 }; if ((daemon == NULL) || (daemon_local == NULL) || (receiver == NULL)) { dlt_vlog(LOG_ERR, "%s: wrong parameter\n", __func__); return DLT_RETURN_WRONG_PARAMETER; } PRINT_FUNCTION_VERBOSE(verbose); gateway = &daemon_local->pGateway; if (gateway == NULL) { dlt_log(LOG_ERR, "Gateway structure is NULL\n"); return DLT_RETURN_ERROR; } for (i = 0; i < gateway->num_connections; i++) if (gateway->connections[i].client.sock == receiver->fd) { con = &gateway->connections[i]; break; } if (con == NULL) { dlt_log(LOG_ERR, "Cannot associate fd to passive Node connection\n"); return DLT_RETURN_ERROR; } /* now the corresponding passive node connection is available */ if (dlt_message_init(&msg, verbose) == -1) { dlt_log(LOG_ERR, "Cannot initialize DLT message for passive node forwarding\n"); return DLT_RETURN_ERROR; } /* nearly copy and paste of dlt_client_main_loop function */ if (dlt_receiver_receive(receiver, DLT_RECEIVE_SOCKET) <= 0) { /* No more data to be received */ if (dlt_message_free(&msg, verbose) < 0) { dlt_log(LOG_ERR, "Cannot free DLT message\n"); return DLT_RETURN_ERROR; } dlt_log(LOG_WARNING, "Connection to passive node lost\n"); if (con->reconnect_cnt < DLT_GATEWAY_RECONNECT_MAX) { dlt_log(LOG_WARNING, "Try to reconnect.\n"); con->reconnect_cnt += 1; con->timeout_cnt = 0; } else { con->status = DLT_GATEWAY_DISCONNECTED; if (dlt_event_handler_unregister_connection(&daemon_local->pEvent, daemon_local, receiver->fd) != 0) dlt_log(LOG_ERR, "Remove passive node Connection failed\n"); } return DLT_RETURN_OK; } while (dlt_message_read(&msg, (unsigned char *)receiver->buf, receiver->bytesRcvd, 0, verbose) == DLT_MESSAGE_ERROR_OK) { DltStandardHeaderExtra *header = (DltStandardHeaderExtra *) (msg.headerbuffer + sizeof(DltStorageHeader) + sizeof(DltStandardHeader)); /* only forward messages if the received ECUid is the expected one */ if (strncmp(header->ecu, con->ecuid, strlen(con->ecuid)) == 0) { uint32_t id; uint32_t id_tmp; DltPassiveControlMessage *control_msg = con->p_control_msgs; dlt_vlog(LOG_DEBUG, "Received ECUid (%s) similar to configured ECUid(%s). " "Forwarding message (%s).\n", header->ecu, con->ecuid, msg.databuffer); id_tmp = *((uint32_t *)(msg.databuffer)); id = DLT_ENDIAN_GET_32(msg.standardheader->htyp, id_tmp); /* if ID is GET_LOG_INFO, parse msg */ if (id == DLT_SERVICE_ID_GET_LOG_INFO) { while (control_msg) { if (control_msg->id == id) { if (dlt_gateway_parse_get_log_info(daemon, header->ecu, &msg, control_msg->req, verbose) == DLT_RETURN_ERROR) dlt_log(LOG_WARNING, "Parsing GET_LOG_INFO message failed!\n"); /* Check for logstorage */ dlt_gateway_control_service_logstorage(daemon, daemon_local, verbose); /* initialize the flag */ control_msg->req = CONTROL_MESSAGE_NOT_REQUESTED; break; } control_msg = control_msg->next; } } else if (id == DLT_SERVICE_ID_GET_DEFAULT_LOG_LEVEL) { if (dlt_gateway_parse_get_default_log_level( daemon, daemon_local, header->ecu, &msg, verbose) == DLT_RETURN_ERROR) dlt_log(LOG_WARNING, "Parsing GET_DEFAULT_LOG_LEVEL message failed!\n"); } /* prepare storage header */ if (dlt_set_storageheader(msg.storageheader, msg.headerextra.ecu) == DLT_RETURN_ERROR) { dlt_vlog(LOG_ERR, "%s: Can't set storage header\n", __func__); return DLT_RETURN_ERROR; } if (dlt_daemon_client_send(DLT_DAEMON_SEND_TO_ALL, daemon, daemon_local, msg.headerbuffer, sizeof(DltStorageHeader), msg.headerbuffer + sizeof(DltStorageHeader), msg.headersize - sizeof(DltStorageHeader), msg.databuffer, msg.datasize, verbose) != DLT_DAEMON_ERROR_OK) dlt_log(LOG_WARNING, "Forward message to clients failed!\n"); } else { /* otherwise remove this connection and do not connect again */ dlt_vlog(LOG_WARNING, "Received ECUid (%s) differs to configured ECUid(%s). " "Discard this message.\n", header->ecu, con->ecuid); /* disconnect from passive node */ con->status = DLT_GATEWAY_DISCONNECTED; con->trigger = DLT_GATEWAY_DISABLED; if (dlt_event_handler_unregister_connection(&daemon_local->pEvent, daemon_local, receiver->fd) != 0) dlt_log(LOG_ERR, "Remove passive node Connection failed\n"); dlt_log(LOG_WARNING, "Disconnect from passive node due to invalid ECUid\n"); } if (msg.found_serialheader) { if (dlt_receiver_remove(receiver, msg.headersize + msg.datasize - sizeof(DltStorageHeader) + sizeof(dltSerialHeader)) == -1) { /* Return value ignored */ dlt_message_free(&msg, verbose); return DLT_RETURN_ERROR; } } else if (dlt_receiver_remove(receiver, msg.headersize + msg.datasize - sizeof(DltStorageHeader)) == -1) { /* Return value ignored */ dlt_message_free(&msg, verbose); return DLT_RETURN_ERROR; } } if (dlt_receiver_move_to_begin(receiver) == -1) { /* Return value ignored */ dlt_message_free(&msg, verbose); return DLT_RETURN_ERROR; } if (dlt_message_free(&msg, verbose) == -1) return DLT_RETURN_ERROR; return DLT_RETURN_OK; } int dlt_gateway_process_gateway_timer(DltDaemon *daemon, DltDaemonLocal *daemon_local, DltReceiver *receiver, int verbose) { uint64_t expir = 0; ssize_t res = 0; PRINT_FUNCTION_VERBOSE(verbose); if ((daemon_local == NULL) || (daemon == NULL) || (receiver == NULL)) { dlt_vlog(LOG_ERR, "%s: invalid parameters\n", __func__); return DLT_RETURN_WRONG_PARAMETER; } res = read(receiver->fd, &expir, sizeof(expir)); if (res < 0) dlt_vlog(LOG_WARNING, "%s: Fail to read timer (%s)\n", __func__, strerror(errno)); /* Activity received on timer_wd, but unable to read the fd: * let's go on sending notification */ /* try to connect to passive nodes */ dlt_gateway_establish_connections(&daemon_local->pGateway, daemon_local, verbose); dlt_log(LOG_DEBUG, "Gateway Timer\n"); return DLT_RETURN_OK; } int dlt_gateway_forward_control_message(DltGateway *gateway, DltDaemonLocal *daemon_local, DltMessage *msg, char *ecu, int verbose) { int i = 0; int ret = 0; DltGatewayConnection *con = NULL; uint32_t id_tmp; uint32_t id; PRINT_FUNCTION_VERBOSE(verbose); if ((gateway == NULL) || (daemon_local == NULL) || (msg == NULL) || (ecu == NULL)) { dlt_vlog(LOG_ERR, "%s: wrong parameter\n", __func__); return DLT_RETURN_WRONG_PARAMETER; } for (i = 0; i < gateway->num_connections; i++) if (strncmp(gateway->connections[i].ecuid, ecu, strlen(gateway->connections[i].ecuid)) == 0) { con = &gateway->connections[i]; break; } if (con == NULL) { dlt_log(LOG_WARNING, "Unknown passive node identifier\n"); return DLT_RETURN_ERROR; } if (con->status != DLT_GATEWAY_CONNECTED) { dlt_log(LOG_INFO, "Passive node is not connected\n"); return DLT_RETURN_ERROR; } if (con->send_serial) { /* send serial header */ ret = send(con->client.sock, (void *)dltSerialHeader, sizeof(dltSerialHeader), 0); if (ret == -1) { dlt_log(LOG_ERR, "Sending message to passive DLT Daemon failed\n"); return DLT_RETURN_ERROR; } } ret = send(con->client.sock, msg->headerbuffer + sizeof(DltStorageHeader), msg->headersize - sizeof(DltStorageHeader), 0); if (ret == -1) { dlt_log(LOG_ERR, "Sending message to passive DLT Daemon failed\n"); return DLT_RETURN_ERROR; } else { ret = send(con->client.sock, msg->databuffer, msg->datasize, 0); if (ret == -1) { dlt_log(LOG_ERR, "Sending message to passive DLT Daemon failed\n"); return DLT_RETURN_ERROR; } } id_tmp = *((uint32_t *)(msg->databuffer)); id = DLT_ENDIAN_GET_32(msg->standardheader->htyp, id_tmp); dlt_vlog(LOG_INFO, "Control message forwarded : %s\n", dlt_get_service_name(id)); return DLT_RETURN_OK; } int dlt_gateway_process_on_demand_request(DltGateway *gateway, DltDaemonLocal *daemon_local, char *node_id, int connection_status, int verbose) { int i = 0; DltGatewayConnection *con = NULL; PRINT_FUNCTION_VERBOSE(verbose); if ((gateway == NULL) || (daemon_local == NULL) || (node_id == NULL)) { dlt_vlog(LOG_ERR, "%s: wrong parameter\n", __func__); return DLT_RETURN_WRONG_PARAMETER; } /* find connection by ECU id */ for (i = 0; i < gateway->num_connections; i++) if (strncmp(node_id, gateway->connections->ecuid, DLT_ID_SIZE) == 0) { con = &gateway->connections[i]; break; } if (con == NULL) { dlt_log(LOG_WARNING, "Specified ECUid not found\n"); return DLT_RETURN_ERROR; } if (connection_status == 1) { /* try to connect */ if (con->status != DLT_GATEWAY_CONNECTED) { if (dlt_client_connect(&con->client, verbose) == 0) { /* setup dlt connection and add to poll event loop here */ if (dlt_gateway_add_to_event_loop(daemon_local, con, verbose) != DLT_RETURN_OK) { dlt_log(LOG_ERR, "Gateway connection creation failed\n"); return DLT_RETURN_ERROR; } } else { dlt_log(LOG_ERR, "Could not connect to passive node\n"); return DLT_RETURN_ERROR; } } else { dlt_log(LOG_INFO, "Passive node already connected\n"); } } else if (connection_status == 0) /* disconnect*/ { con->status = DLT_GATEWAY_DISCONNECTED; con->trigger = DLT_GATEWAY_ON_DEMAND; if (dlt_event_handler_unregister_connection(&daemon_local->pEvent, daemon_local, con->client.sock) != 0) dlt_log(LOG_ERR, "Remove passive node event handler connection failed\n"); } else { dlt_log(LOG_ERR, "Unknown command (connection_status)\n"); return DLT_RETURN_ERROR; } return DLT_RETURN_OK; } int dlt_gateway_send_control_message(DltGatewayConnection *con, DltPassiveControlMessage *control_msg, void *data, int verbose) { int ret = DLT_RETURN_OK; PRINT_FUNCTION_VERBOSE(verbose); if (con == NULL) { dlt_vlog(LOG_WARNING, "%s: Invalid parameter given\n", __func__); return DLT_RETURN_WRONG_PARAMETER; } /* no (more) control message to be send */ if (control_msg->id == 0) return DLT_RETURN_ERROR; /* check sendtime counter and message interval */ /* sendtime counter is 0 on startup, otherwise positive value */ if ((control_msg->type != CONTROL_MESSAGE_ON_DEMAND) && (con->sendtime_cnt > 0)) { if (control_msg->interval <= 0) return DLT_RETURN_ERROR; if ((control_msg->type == CONTROL_MESSAGE_PERIODIC) || (control_msg->type == CONTROL_MESSAGE_BOTH)) { if ((con->sendtime_cnt - 1) % control_msg->interval != 0) return DLT_RETURN_ERROR; } } if (con->send_serial) { /* send serial header */ ret = send(con->client.sock, (void *)dltSerialHeader, sizeof(dltSerialHeader), 0); if (ret == -1) { dlt_log(LOG_ERR, "Sending message to passive DLT Daemon failed\n"); return DLT_RETURN_ERROR; } } switch (control_msg->id) { case DLT_SERVICE_ID_GET_LOG_INFO: return dlt_client_get_log_info(&con->client); break; case DLT_SERVICE_ID_GET_DEFAULT_LOG_LEVEL: return dlt_client_get_default_log_level(&con->client); break; case DLT_SERVICE_ID_GET_SOFTWARE_VERSION: return dlt_client_get_software_version(&con->client); break; case DLT_SERVICE_ID_SET_LOG_LEVEL: if (data == NULL) { dlt_vlog(LOG_WARNING, "Insufficient data for %s received. Send control request failed.\n", dlt_get_service_name(control_msg->id)); return DLT_RETURN_ERROR; } DltServiceSetLogLevel *req = (DltServiceSetLogLevel *)data; return dlt_client_send_log_level(&con->client, req->apid, req->ctid, req->log_level); break; default: dlt_vlog(LOG_WARNING, "Cannot forward request: %s.\n", dlt_get_service_name(control_msg->id)); } return DLT_RETURN_OK; } DltGatewayConnection *dlt_gateway_get_connection(DltGateway *gateway, char *ecu, int verbose) { DltGatewayConnection *con = NULL; int i = 0; PRINT_FUNCTION_VERBOSE(verbose); if ((gateway == NULL) || (ecu == NULL)) { dlt_vlog(LOG_ERR, "%s: wrong parameter\n", __func__); return con; } for (i = 0; i < gateway->num_connections; i++) { con = &gateway->connections[i]; if (strncmp(con->ecuid, ecu, DLT_ID_SIZE) == 0) return con; } dlt_vlog(LOG_ERR, "%s: No connection found\n", ecu); return con; } dlt-daemon-2.18.4/src/gateway/dlt_gateway.conf000066400000000000000000000015561353342203500212440ustar00rootroot00000000000000[PassiveNode1] IPaddress=192.168.2.11 ; TCP port. Default 3490 is used if no port is specified. ; Port=3490 ; passive nodes ECU identifier. Mandatory. EcuID=ECU2 ; Try connect to passive Node on DLT Daemon startup. Default OnStartup if not specified. ; Connect=OnStartup ; Stop connecting to passive node, if not successful after 10 seconds Timeout=10 ; Send following control messages after connection is established ; SendControl=0x03,0x04,0x13 ; Send Serial Header with control messages. Value in dlt.conf is used as default if not specified. ; SendSerialHeader=0 ; Send following control messages periodically () ; SendPeriodicControl=0x03:5,0x13:10 ; Supported Control messages: ; DLT_SERVICE_ID_GET_LOG_INFO 0x03 ; DLT_SERVICE_ID_GET_DEFAULT_LOG_LEVEL 0x04 ; DLT_SERVICE_ID_GET_SOFTWARE_VERSION 0x13 dlt-daemon-2.18.4/src/gateway/dlt_gateway.h000066400000000000000000000166451353342203500205530ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2015 Advanced Driver Information Technology. * This code is developed by Advanced Driver Information Technology. * Copyright of Advanced Driver Information Technology, Bosch and DENSO. * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author * Christoph Lipka * * \copyright Copyright © 2015 Advanced Driver Information Technology. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file dlt_gateway.h */ /******************************************************************************* ** ** ** SRC-MODULE: dlt_gateway.h ** ** ** ** TARGET : linux ** ** ** ** PROJECT : DLT ** ** ** ** AUTHOR : Christoph Lipka clipka@jp.adit-jv.com ** ** PURPOSE : ** ** ** ** REMARKS : ** ** ** ** PLATFORM DEPENDANT [yes/no]: yes ** ** ** ** TO BE CHANGED BY USER [yes/no]: no ** ** ** *******************************************************************************/ /******************************************************************************* ** Author Identity ** ******************************************************************************** ** ** ** Initials Name Company ** ** -------- ------------------------- ---------------------------------- ** ** cl Christoph Lipka ADIT ** *******************************************************************************/ #ifndef DLT_GATEWAY_H_ #define DLT_GATEWAY_H_ #include "dlt-daemon.h" #include "dlt_gateway_types.h" /** * Initialize the gateway to passive nodes * * TODO: Make path to configuration file configurable * * @param daemon_local pointer to DltDaemonLocal * @param verbose verbose flag * @return 0 on success, -1 on error */ int dlt_gateway_init(DltDaemonLocal *daemon_local, int verbose); /** * De-initialize the gateway. All internal data will be freed. * * @param g DltGateway pointer * @param verbose verbose flag */ void dlt_gateway_deinit(DltGateway *g, int verbose); /** * Establish all connections to passive nodes that are configured to be started * on daemon startup and add this connections to the main event loop. * * TODO: This function is called during gateway initialization and in main loop * whenever the poll returns. This may need to be improved. * * @param g DltGateway * @param daemon_local DltDaemonLocal * @param verbose verbose flag * @return 0 on success, -1 on error */ int dlt_gateway_establish_connections(DltGateway *g, DltDaemonLocal *daemon_local, int verbose); /** * Return the receiver for a given file descriptor * * @param g DltGateway * @param fd file descriptor * @return Pointer to DltReceiver on success, NULL otherwise */ DltReceiver *dlt_gateway_get_connection_receiver(DltGateway *g, int fd); /** * Process incoming messages from passive nodes * * @param daemon DltDaemon * @param daemon_local DltDaemonLocal * @param recv DltReceiver structure * @param verbose verbose flag * @return 0 on success, -1 otherwise */ int dlt_gateway_process_passive_node_messages(DltDaemon *daemon, DltDaemonLocal *daemon_local, DltReceiver *recv, int verbose); /** * Process gateway timer * * @param daemon DltDaemon * @param daemon_local DltDaemonLocal * @param rec DltReceiver * @param verbose verbose flag * @return 0 on success, -1 otherwise */ int dlt_gateway_process_gateway_timer(DltDaemon *daemon, DltDaemonLocal *daemon_local, DltReceiver *rec, int verbose); /** * Forward control messages to the specified passive node DLT Daemon. * * @param g DltGateway * @param daemon_local DltDaemonLocal * @param msg DltMessage * @param ecu Identifier of the passive node * @param verbose verbose flag * @return 0 on success, -1 otherwise */ int dlt_gateway_forward_control_message(DltGateway *g, DltDaemonLocal *daemon_local, DltMessage *msg, char *ecu, int verbose); /** * Process on demand connect/disconnect of passive nodes * * @param g DltGateway * @param daemon_local DltDaemonLocal * @param node_id Passive Node identifier * @param connection_status Connection status * @param verbose verbose flag * @return 0 on success, -1 otherwise */ int dlt_gateway_process_on_demand_request(DltGateway *g, DltDaemonLocal *daemon_local, char *node_id, int connection_status, int verbose); /** * Send control message to passive node * * @param con DltGatewayConnection * @param control_msg DltPassiveControlMessage * @param data DltMessage * @param verbose verbose flag * @return 0 on success, -1 otherwise */ int dlt_gateway_send_control_message(DltGatewayConnection *con, DltPassiveControlMessage *control_msg, void *data, int verbose); /** * Gets the connection handle of passive node with specified ECU * * @param g DltGateway * @param ecu Identifier string * @param verbose verbose flag * @returns Gateway connection handle on success, NULL otherwise */ DltGatewayConnection *dlt_gateway_get_connection(DltGateway *g, char *ecu, int verbose); #endif dlt-daemon-2.18.4/src/gateway/dlt_gateway_internal.h000066400000000000000000000122021353342203500224300ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2018 Advanced Driver Information Technology. * This code is developed by Advanced Driver Information Technology. * Copyright of Advanced Driver Information Technology, Bosch and DENSO. * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author * Aditya Paluri * * \copyright Copyright © 2018 Advanced Driver Information Technology. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file dlt_gateway_internal.h */ /******************************************************************************* ** ** ** SRC-MODULE: dlt_gateway_internal.h ** ** ** ** TARGET : linux ** ** ** ** PROJECT : DLT ** ** ** ** AUTHOR : Aditya Paluri venkataaditya.paluri@in.bosch.com ** ** PURPOSE : ** ** ** ** REMARKS : ** ** ** ** PLATFORM DEPENDANT [yes/no]: yes ** ** ** ** TO BE CHANGED BY USER [yes/no]: no ** ** ** *******************************************************************************/ /******************************************************************************* ** Author Identity ** ******************************************************************************** ** ** ** Initials Name Company ** ** -------- ------------------------- ---------------------------------- ** ** ap Aditya Paluri ADIT ** *******************************************************************************/ #ifndef DLT_GATEWAY_INTERNAL_H_ #define DLT_GATEWAY_INTERNAL_H_ DLT_STATIC DltReturnValue dlt_gateway_check_ip(DltGatewayConnection *con, char *value); DLT_STATIC DltReturnValue dlt_gateway_check_port(DltGatewayConnection *con, char *value); DLT_STATIC DltReturnValue dlt_gateway_check_ecu(DltGatewayConnection *con, char *value); DLT_STATIC DltReturnValue dlt_gateway_check_connect_trigger(DltGatewayConnection *con, char *value); DLT_STATIC DltReturnValue dlt_gateway_check_timeout(DltGatewayConnection *con, char *value); DLT_STATIC DltReturnValue dlt_gateway_check_send_serial(DltGatewayConnection *con, char *value); DLT_STATIC DltReturnValue dlt_gateway_allocate_control_messages(DltGatewayConnection *con); DLT_STATIC DltReturnValue dlt_gateway_check_control_messages(DltGatewayConnection *con, char *value); DLT_STATIC DltReturnValue dlt_gateway_check_periodic_control_messages(DltGatewayConnection *con, char *value); DLT_STATIC DltReturnValue dlt_gateway_check_param(DltGateway *gateway, DltGatewayConnection *con, DltGatewayConfType ctype, char *value); int dlt_gateway_configure(DltGateway *gateway, char *config_file, int verbose); int dlt_gateway_store_connection(DltGateway *gateway, DltGatewayConnection *tmp, int verbose); DLT_STATIC DltReturnValue dlt_gateway_parse_get_log_info(DltDaemon *daemon, char *ecu, DltMessage *msg, int req, int verbose); #endif dlt-daemon-2.18.4/src/gateway/dlt_gateway_types.h000066400000000000000000000153471353342203500217750ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2015 Advanced Driver Information Technology. * This code is developed by Advanced Driver Information Technology. * Copyright of Advanced Driver Information Technology, Bosch and DENSO. * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author * Christoph Lipka * * \copyright Copyright © 2015 Advanced Driver Information Technology. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file dlt_gateway_types.h */ /******************************************************************************* ** ** ** SRC-MODULE: dlt_gateway_types.h ** ** ** ** TARGET : linux ** ** ** ** PROJECT : DLT ** ** ** ** AUTHOR : Christoph Lipka clipka@jp.adit-jv.com ** ** PURPOSE : ** ** ** ** REMARKS : ** ** ** ** PLATFORM DEPENDANT [yes/no]: yes ** ** ** ** TO BE CHANGED BY USER [yes/no]: no ** ** ** *******************************************************************************/ /******************************************************************************* ** Author Identity ** ******************************************************************************** ** ** ** Initials Name Company ** ** -------- ------------------------- ---------------------------------- ** ** cl Christoph Lipka ADIT ** *******************************************************************************/ #ifndef DLT_GATEWAY_TYPES_H_ #define DLT_GATEWAY_TYPES_H_ #include "dlt_protocol.h" #include "dlt_client.h" #define DLT_GATEWAY_CONFIG_PATH CONFIGURATION_FILES_DIR "/dlt_gateway.conf" #define DLT_GATEWAY_TIMER_INTERVAL 1 #define DLT_GATEWAY_RECONNECT_MAX 1 /* reconnect once after connection loss */ /* maximum number of control messages that can be send after connection is * established */ #define DLT_GATEWAY_MAX_STARTUP_CTRL_MSG 10 typedef enum { DLT_GATEWAY_UNINITIALIZED, DLT_GATEWAY_INITIALIZED, DLT_GATEWAY_CONNECTED, DLT_GATEWAY_DISCONNECTED } connection_status; typedef enum { DLT_GATEWAY_UNDEFINED = -1, DLT_GATEWAY_ON_STARTUP, /* connect directly on startup */ DLT_GATEWAY_ON_DEMAND, /* connect on demand only */ DLT_GATEWAY_DISABLED /* disable this connection due to problems */ } connection_trigger; typedef enum { CONTROL_MESSAGE_UNDEFINED = -1, CONTROL_MESSAGE_ON_STARTUP, /* send on startup */ CONTROL_MESSAGE_PERIODIC, /* send periodically */ CONTROL_MESSAGE_BOTH, /* send on startup and periodically */ CONTROL_MESSAGE_ON_DEMAND /* send on demand only */ } control_msg_trigger; typedef enum { CONTROL_MESSAGE_REQUEST_UNDEFINED = -1, CONTROL_MESSAGE_NOT_REQUESTED, /* control msg not requested (default) */ CONTROL_MESSAGE_REQUESTED /* control msg requested */ } control_msg_request; /* Passive control message */ typedef struct DltPassiveControlMessage { uint32_t id; /* msg ID */ uint32_t user_id; control_msg_trigger type; /* on startup or periodic or both */ control_msg_request req; /* whether it is requested from gateway or not */ int interval; /* interval for periodic sending. if on startup, -1 */ struct DltPassiveControlMessage *next; /* for multiple passive control message */ } DltPassiveControlMessage; /* DLT Gateway connection structure */ typedef struct { int handle; /* connection handle */ connection_status status; /* connected/disconnected */ char *ecuid; /* name of passive node */ char *ip_address; /* IP address */ int sock_domain; /* socket domain */ int sock_type; /* socket type */ int sock_protocol; /* socket protocol */ int port; /* port */ connection_trigger trigger; /* connection trigger */ int timeout; /* connection timeout */ int timeout_cnt; /* connection timeout counter */ int reconnect_cnt; /* reconnection counter */ int sendtime; /* periodic sending max time */ int sendtime_cnt; /* periodic sending counter */ DltPassiveControlMessage *p_control_msgs; /* passive control msgs */ DltPassiveControlMessage *head; /* to go back to the head pointer of p_control_msgs */ int send_serial; /* Send serial header with control messages */ DltClient client; /* DltClient structure */ int default_log_level; /* Default Log Level on passive node */ } DltGatewayConnection; /* DltGateway structure */ typedef struct { int send_serial; /* Default: Send serial header with control messages */ DltGatewayConnection *connections; /* pointer to connections */ int num_connections; /* number of connections */ } DltGateway; typedef struct { char *key; /* The configuration key*/ int (*func)(DltGatewayConnection *con, char *value); /* Conf handler */ int is_opt; /* If the configuration is optional or not */ } DltGatewayConf; typedef enum { GW_CONF_IP_ADDRESS = 0, GW_CONF_PORT, GW_CONF_ECUID, GW_CONF_CONNECT, GW_CONF_TIMEOUT, GW_CONF_SEND_CONTROL, GW_CONF_SEND_PERIODIC_CONTROL, GW_CONF_SEND_SERIAL_HEADER, GW_CONF_COUNT } DltGatewayConfType; #endif /* DLT_GATEWAY_TYPES_H_ */ dlt-daemon-2.18.4/src/kpi/000077500000000000000000000000001353342203500152045ustar00rootroot00000000000000dlt-daemon-2.18.4/src/kpi/CMakeLists.txt000066400000000000000000000015071353342203500177470ustar00rootroot00000000000000####### # SPDX license identifier: MPL-2.0 # # Copyright (C) 2011-2015, BMW AG # # This file is part of GENIVI Project DLT - Diagnostic Log and Trace. # # This Source Code Form is subject to the terms of the # Mozilla Public License (MPL), v. 2.0. # If a copy of the MPL was not distributed with this file, # You can obtain one at http://mozilla.org/MPL/2.0/. # # For further information see http://www.genivi.org/. ####### set (dlt_kpi_SRCS dlt-kpi.c dlt-kpi-options.c dlt-kpi-process.c dlt-kpi-process-list.c dlt-kpi-common.c dlt-kpi-interrupt.c) add_executable (dlt-kpi ${dlt_kpi_SRCS}) target_link_libraries (dlt-kpi dlt) set_target_properties(dlt-kpi PROPERTIES LINKER_LANGUAGE C) install(TARGETS dlt-kpi RUNTIME DESTINATION bin COMPONENT base) INSTALL(FILES dlt-kpi.conf DESTINATION ${CONFIGURATION_FILES_DIR} COMPONENT base) dlt-daemon-2.18.4/src/kpi/dlt-kpi-common.c000066400000000000000000000053641353342203500202120ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2011-2015, BMW AG * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author Sven Hassler * * \copyright Copyright © 2011-2015 BMW AG. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file dlt-kpi-common.c */ #include "dlt-kpi-common.h" static int dlt_kpi_cpu_count = -1; DltReturnValue dlt_kpi_read_file_compact(char *filename, char **target) { if ((filename == NULL) || (target == NULL)) { fprintf(stderr, "%s: Nullpointer parameter!\n", __func__); return DLT_RETURN_WRONG_PARAMETER; } char buffer[BUFFER_SIZE]; int ret = dlt_kpi_read_file(filename, buffer, BUFFER_SIZE); if (ret < DLT_RETURN_OK) return ret; if ((*target = malloc(strlen(buffer) + 1)) == NULL) { fprintf(stderr, "Out of memory!\n"); return DLT_RETURN_ERROR; } memcpy(*target, buffer, strlen(buffer) + 1); return DLT_RETURN_OK; } DltReturnValue dlt_kpi_read_file(char *filename, char *buffer, uint maxLength) { if ((filename == NULL) || (buffer == NULL)) { fprintf(stderr, "%s: Nullpointer parameter!\n", __func__); return DLT_RETURN_WRONG_PARAMETER; } FILE *file = fopen(filename, "r"); if (file == NULL) /* fprintf(stderr, "Could not read file %s\n", filename); */ return DLT_RETURN_ERROR; int buflen = fread(buffer, 1, maxLength - 1, file); buffer[buflen] = '\0'; fclose(file); return DLT_RETURN_OK; } int dlt_kpi_read_cpu_count() { char buffer[BUFFER_SIZE]; int ret = dlt_kpi_read_file("/proc/cpuinfo", buffer, sizeof(buffer)); if (ret != 0) { fprintf(stderr, "dlt_kpi_get_cpu_count(): Could not read /proc/cpuinfo\n"); return -1; } char *delim = "[] \t\n"; char *tok = strtok(buffer, delim); if (tok == NULL) { fprintf(stderr, "dlt_kpi_get_cpu_count(): Could not extract token\n"); return -1; } int num = 0; do { if (strcmp(tok, "processor") == 0) num++; tok = strtok(NULL, delim); } while (tok != NULL); return num; } int dlt_kpi_get_cpu_count() { if (dlt_kpi_cpu_count <= 0) { dlt_kpi_cpu_count = dlt_kpi_read_cpu_count(); if (dlt_kpi_cpu_count <= 0) { fprintf(stderr, "Could not get CPU count\n"); dlt_kpi_cpu_count = -1; } } return dlt_kpi_cpu_count; } dlt-daemon-2.18.4/src/kpi/dlt-kpi-common.h000066400000000000000000000020331353342203500202050ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2011-2015, BMW AG * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author Sven Hassler * * \copyright Copyright © 2011-2015 BMW AG. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file dlt-kpi-common.h */ #ifndef SRC_KPI_DLT_KPI_COMMON_H_ #define SRC_KPI_DLT_KPI_COMMON_H_ #include #include #include #include #define BUFFER_SIZE 4096 DltReturnValue dlt_kpi_read_file(char *filename, char *buffer, uint maxLength); DltReturnValue dlt_kpi_read_file_compact(char *filename, char **target); int dlt_kpi_get_cpu_count(); #endif /* SRC_KPI_DLT_KPI_COMMON_H_ */ dlt-daemon-2.18.4/src/kpi/dlt-kpi-interrupt.c000066400000000000000000000117341353342203500207540ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2011-2015, BMW AG * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author Sven Hassler * * \copyright Copyright © 2011-2015 BMW AG. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file dlt-kpi-interrupt.c */ #include "dlt-kpi-interrupt.h" DltReturnValue dlt_kpi_log_interrupts(DltContext *ctx, DltLogLevelType log_level) { if (ctx == NULL) { fprintf(stderr, "%s: Nullpointer parameter (NULL) !\n", __func__); return DLT_RETURN_WRONG_PARAMETER; } char buffer[BUFFER_SIZE]; *buffer = '\0'; char file_buffer[BUFFER_SIZE]; char *token, *delim = " \t", *delim2 = " \t\n", *check; int head_line = 1, first_row = 1, cpu_count = 0, column = 0, buffer_offset = 0; DltReturnValue ret; if ((ret = dlt_kpi_read_file("/proc/interrupts", file_buffer, BUFFER_SIZE)) < DLT_RETURN_OK) return ret; token = strtok(file_buffer, delim); while (token != NULL) { if (head_line) { if ((strlen(token) > 3) && (token[0] == 'C') && (token[1] == 'P') && (token[2] == 'U')) { cpu_count++; } else if (cpu_count <= 0) { fprintf(stderr, "%s: Could not parse CPU count !\n", __func__); return DLT_RETURN_ERROR; } else if (strcmp(token, "\n") == 0) { head_line = 0; } token = strtok(NULL, delim); } else { int tokenlen = strlen(token); if (token[tokenlen - 1] == ':') { column = 0; if (first_row) first_row = 0; else buffer_offset += snprintf(buffer + buffer_offset, BUFFER_SIZE - buffer_offset, "\n"); } if (column == 0) { /* IRQ number */ buffer_offset += snprintf(buffer + buffer_offset, BUFFER_SIZE - buffer_offset, "%.*s;", tokenlen - 1, token); } else if (column <= cpu_count) { long int interrupt_count = strtol(token, &check, 10); if (*check != '\0') { fprintf(stderr, "%s: Could not parse interrupt count for CPU !\n", __func__); return DLT_RETURN_ERROR; } buffer_offset += snprintf(buffer + buffer_offset, BUFFER_SIZE - buffer_offset, "cpu%d:%ld;", column - 1, interrupt_count); } column++; token = strtok(NULL, delim2); } } /* synchronization message */ DLT_LOG(*ctx, log_level, DLT_STRING("IRQ"), DLT_STRING("BEG")); DltContextData ctx_data; if ((ret = dlt_user_log_write_start(ctx, &ctx_data, log_level)) < DLT_RETURN_OK) { fprintf(stderr, "%s: dlt_user_log_write_start() returned error\n", __func__); return ret; } if ((ret = dlt_user_log_write_string(&ctx_data, "IRQ")) < DLT_RETURN_OK) { fprintf(stderr, "%s: dlt_user_log_write_string() returned error\n", __func__); return ret; } token = strtok(buffer, "\n"); while (token != NULL) { if (dlt_user_log_write_string(&ctx_data, token) < DLT_RETURN_OK) { /* message buffer full, start new one */ if ((ret = dlt_user_log_write_finish(&ctx_data)) < DLT_RETURN_OK) { fprintf(stderr, "%s: dlt_user_log_write_finish() returned error\n", __func__); return ret; } if ((ret = dlt_user_log_write_start(ctx, &ctx_data, log_level)) < DLT_RETURN_OK) { fprintf(stderr, "%s: dlt_user_log_write_start() returned error\n", __func__); return ret; } if ((ret = dlt_user_log_write_string(&ctx_data, "IRQ")) < DLT_RETURN_OK) { fprintf(stderr, "%s: dlt_user_log_write_string() returned error\n", __func__); return ret; } } else { token = strtok(NULL, "\n"); } } if ((ret = dlt_user_log_write_finish(&ctx_data)) < DLT_RETURN_OK) { fprintf(stderr, "%s: dlt_user_log_write_finish() returned error\n", __func__); return ret; } /* synchronization message */ DLT_LOG(*ctx, log_level, DLT_STRING("IRQ"), DLT_STRING("END")); return DLT_RETURN_OK; } dlt-daemon-2.18.4/src/kpi/dlt-kpi-interrupt.h000066400000000000000000000016051353342203500207550ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2011-2015, BMW AG * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author Sven Hassler * * \copyright Copyright © 2011-2015 BMW AG. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file dlt-kpi-interrupt.h */ #ifndef SRC_KPI_DLT_KPI_INTERRUPT_H_ #define SRC_KPI_DLT_KPI_INTERRUPT_H_ #include "dlt.h" #include "dlt-kpi-common.h" DltReturnValue dlt_kpi_log_interrupts(DltContext *ctx, DltLogLevelType log_level); #endif /* SRC_KPI_DLT_KPI_INTERRUPT_H_ */ dlt-daemon-2.18.4/src/kpi/dlt-kpi-options.c000066400000000000000000000155721353342203500204170ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2011-2015, BMW AG * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author Sven Hassler * * \copyright Copyright © 2011-2015 BMW AG. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file dlt-kpi-options.c */ #include "dlt-kpi.h" /** * Print information how to use this program. */ void usage(char *prog_name) { char version[255]; dlt_get_version(version, 255); printf("Usage: %s [options]\n", prog_name); printf("Application to forward information from the /proc/ file system to DLT.\n"); printf("%s\n", version); printf("Options:\n"); /*printf(" -d Daemonize. Detach from terminal and run in background.\n"); */ printf(" -c filename Use configuration file. \n"); printf(" Default: %s\n", DEFAULT_CONF_FILE); printf(" -h This help message.\n"); } /** * Initialize command line options with default values. */ void dlt_kpi_init_cli_options(DltKpiOptions *options) { options->configurationFileName = DEFAULT_CONF_FILE; options->customConfigFile = 0; } void dlt_kpi_free_cli_options(DltKpiOptions *options) { if (options->customConfigFile) free(options->configurationFileName); } DltReturnValue dlt_kpi_read_command_line(DltKpiOptions *options, int argc, char **argv) { if (options == NULL) { fprintf(stderr, "%s: Nullpointer parameter\n", __func__); return DLT_RETURN_WRONG_PARAMETER; } dlt_kpi_init_cli_options(options); int opt; while ((opt = getopt(argc, argv, "c:h")) != -1) switch (opt) { case 'c': { if ((options->configurationFileName = malloc(strlen(optarg) + 1)) == 0) { fprintf(stderr, "Out of memory!\n"); return DLT_RETURN_ERROR; } strcpy(options->configurationFileName, optarg); /* strcpy unritical here, because size matches exactly the size to be copied */ options->customConfigFile = 1; break; } case 'h': { usage(argv[0]); exit(0); return -1; /*for parasoft */ } default: { fprintf(stderr, "Unknown option: %c\n", optopt); usage(argv[0]); return DLT_RETURN_ERROR; } } return DLT_RETURN_OK; } /** * Initialize configuration to default values. */ void dlt_kpi_init_configuration(DltKpiConfig *config) { config->process_log_interval = 1000; config->irq_log_interval = 1000; config->log_level = DLT_LOG_DEFAULT; } /** * Read options from the configuration file */ DltReturnValue dlt_kpi_read_configuration_file(DltKpiConfig *config, char *file_name) { FILE *file; char *line = NULL; char *token = NULL; char *value = NULL; char *pch, *strchk; int tmp; if ((config == NULL) || (file_name == NULL)) { fprintf(stderr, "%s: Nullpointer parameter!\n", __func__); return DLT_RETURN_WRONG_PARAMETER; } dlt_kpi_init_configuration(config); file = fopen(file_name, "r"); if (file == NULL) { fprintf(stderr, "%s: Could not open configuration file!\n", __func__); return DLT_RETURN_ERROR; } if (((line = malloc(COMMAND_LINE_SIZE)) == 0) || ((token = malloc(COMMAND_LINE_SIZE)) == 0) || ((value = malloc(COMMAND_LINE_SIZE)) == 0)) { fclose(file); free(line); free(token); free(value); fprintf(stderr, "%s: Out of memory!\n", __func__); return DLT_RETURN_ERROR; } while (fgets(line, COMMAND_LINE_SIZE, file) != NULL) { token[0] = '\0'; value[0] = '\0'; pch = strtok (line, " =\r\n"); while (pch != NULL) { if (pch[0] == '#') break; if (token[0] == '\0') { strncpy(token, pch, COMMAND_LINE_SIZE - 1); token[COMMAND_LINE_SIZE - 1] = '\0'; } else { strncpy(value, pch, COMMAND_LINE_SIZE - 1); value[COMMAND_LINE_SIZE - 1] = '\0'; break; } pch = strtok(NULL, " =\r\n"); } if ((token[0] != '\0') && (value[0] != '\0')) { if (strcmp(token, "process_interval") == '\0') { tmp = strtol(value, &strchk, 10); if ((strchk[0] == '\0') && (tmp > 0)) config->process_log_interval = tmp; else fprintf(stderr, "Error reading configuration file: %s is not a valid value for %s\n", value, token); } else if (strcmp(token, "irq_interval") == '\0') { tmp = strtol(value, &strchk, 10); if ((strchk[0] == '\0') && (tmp > 0)) config->irq_log_interval = tmp; else fprintf(stderr, "Error reading configuration file: %s is not a valid value for %s\n", value, token); } else if (strcmp(token, "check_interval") == '\0') { tmp = strtol(value, &strchk, 10); if ((strchk[0] == '\0') && (tmp > 0)) config->check_log_interval = tmp; else fprintf(stderr, "Error reading configuration file: %s is not a valid value for %s\n", value, token); } else if (strcmp(token, "log_level") == '\0') { tmp = strtol(value, &strchk, 10); if ((strchk[0] == '\0') && (tmp >= -1) && (tmp <= 6)) config->log_level = tmp; else fprintf(stderr, "Error reading configuration file: %s is not a valid value for %s\n", value, token); } } } fclose(file); free(value); free(token); free(line); return DLT_RETURN_OK; } DltReturnValue dlt_kpi_init(int argc, char **argv, DltKpiConfig *config) { DltKpiOptions options; DltReturnValue ret; if (config == NULL) { fprintf(stderr, "%s: Invalid Parameter!", __func__); return DLT_RETURN_WRONG_PARAMETER; } if ((ret = dlt_kpi_read_command_line(&options, argc, argv)) < DLT_RETURN_OK) { fprintf(stderr, "Failed to read command line!"); return ret; } if ((ret = dlt_kpi_read_configuration_file(config, options.configurationFileName)) < DLT_RETURN_OK) { fprintf(stderr, "Failed to read configuration file!"); return ret; } dlt_kpi_free_cli_options(&options); return DLT_RETURN_OK; } dlt-daemon-2.18.4/src/kpi/dlt-kpi-process-list.c000066400000000000000000000152111353342203500213410ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2011-2015, BMW AG * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author Sven Hassler * * \copyright Copyright © 2011-2015 BMW AG. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file dlt-kpi-process-list.c */ #include "dlt-kpi-process-list.h" DltKpiProcessList *dlt_kpi_create_process_list() { DltKpiProcessList *new_list = malloc(sizeof(DltKpiProcessList)); if (new_list == NULL) { fprintf(stderr, "%s: Cannot create process list, out of memory\n", __func__); return NULL; } memset(new_list, 0, sizeof(DltKpiProcessList)); new_list->start = new_list->cursor = NULL; return new_list; } DltReturnValue dlt_kpi_free_process_list_soft(DltKpiProcessList *list) { if (list == NULL) { fprintf(stderr, "%s: Invalid Parameter (NULL)\n", __func__); return DLT_RETURN_WRONG_PARAMETER; } free(list); return DLT_RETURN_OK; } DltReturnValue dlt_kpi_free_process_list(DltKpiProcessList *list) { if (list == NULL) { fprintf(stderr, "%s: Invalid Parameter (NULL)\n", __func__); return DLT_RETURN_WRONG_PARAMETER; } DltKpiProcess *tmp; list->cursor = list->start; while (list->cursor != NULL) { tmp = list->cursor->next; dlt_kpi_free_process(list->cursor); list->cursor = tmp; } return dlt_kpi_free_process_list_soft(list); } DltKpiProcess *dlt_kpi_get_process_at_cursor(DltKpiProcessList *list) { if (list == NULL) { fprintf(stderr, "%s: Invalid Parameter (NULL)\n", __func__); return NULL; } return list->cursor; } DltReturnValue dlt_kpi_reset_cursor(DltKpiProcessList *list) { if (list == NULL) { fprintf(stderr, "%s: Invalid Parameter (NULL)\n", __func__); return DLT_RETURN_WRONG_PARAMETER; } list->cursor = list->start; return DLT_RETURN_OK; } DltReturnValue dlt_kpi_set_cursor_at_end(DltKpiProcessList *list) { if (list == NULL) { fprintf(stderr, "%s: Invalid Parameter (NULL)\n", __func__); return DLT_RETURN_WRONG_PARAMETER; } list->cursor = list->start; if (list->cursor == NULL) return DLT_RETURN_OK; while (list->cursor->next != NULL) dlt_kpi_increment_cursor(list); return DLT_RETURN_OK; } DltReturnValue dlt_kpi_increment_cursor(DltKpiProcessList *list) { if (list == NULL) { fprintf(stderr, "%s: Invalid Parameter (NULL)\n", __func__); return DLT_RETURN_WRONG_PARAMETER; } if (list->cursor == NULL) return DLT_RETURN_ERROR; list->cursor = list->cursor->next; return DLT_RETURN_OK; } DltReturnValue dlt_kpi_decrement_cursor(DltKpiProcessList *list) { if (list == NULL) { fprintf(stderr, "%s: Invalid Parameter (NULL)\n", __func__); return DLT_RETURN_WRONG_PARAMETER; } if (list->cursor == NULL) return DLT_RETURN_ERROR; list->cursor = list->cursor->prev; return DLT_RETURN_OK; } DltReturnValue dlt_kpi_add_process_at_start(DltKpiProcessList *list, DltKpiProcess *process) { if ((list == NULL) || (process == NULL)) { fprintf(stderr, "%s: Invalid Parameter (NULL)\n", __func__); return DLT_RETURN_WRONG_PARAMETER; } if (list->start != NULL) list->start->prev = process; process->next = list->start; list->start = process; return DLT_RETURN_OK; } DltReturnValue dlt_kpi_add_process_before_cursor(DltKpiProcessList *list, DltKpiProcess *process) { if ((list == NULL) || (process == NULL)) { fprintf(stderr, "%s: Invalid Parameter (NULL)\n", __func__); return DLT_RETURN_WRONG_PARAMETER; } if (list->start == NULL) { /* Empty list? */ DltReturnValue ret = dlt_kpi_add_process_at_start(list, process); list->cursor = NULL; return ret; } else if (list->cursor == NULL) { dlt_kpi_set_cursor_at_end(list); DltReturnValue ret = dlt_kpi_add_process_after_cursor(list, process); list->cursor = NULL; return ret; } if (list->cursor->prev != NULL) list->cursor->prev->next = process; else list->start = process; process->next = list->cursor; process->prev = list->cursor->prev; list->cursor->prev = process; return DLT_RETURN_OK; } DltReturnValue dlt_kpi_add_process_after_cursor(DltKpiProcessList *list, DltKpiProcess *process) { if ((list == NULL) || (process == NULL)) { fprintf(stderr, "%s: Invalid Parameter (NULL)\n", __func__); return DLT_RETURN_ERROR; } if (list->cursor == NULL) return dlt_kpi_add_process_at_start(list, process); if (list->cursor->next != NULL) list->cursor->next->prev = process; process->next = list->cursor->next; process->prev = list->cursor; list->cursor->next = process; return DLT_RETURN_OK; } DltReturnValue dlt_kpi_remove_process_at_cursor_soft(DltKpiProcessList *list) { if (list == NULL) { fprintf(stderr, "%s: Invalid Parameter (NULL)\n", __func__); return DLT_RETURN_WRONG_PARAMETER; } if (list->cursor == NULL) { fprintf(stderr, "%s: Cursor is Invalid (NULL)\n", __func__); return DLT_RETURN_ERROR; } DltKpiProcess *tmp = list->cursor; if (tmp->prev != NULL) { if (tmp->next != NULL) { tmp->prev->next = tmp->next; tmp->next->prev = tmp->prev; } else { tmp->prev->next = NULL; } } else { if (tmp->next != NULL) { tmp->next->prev = NULL; list->start = tmp->next; } else { list->start = NULL; } } list->cursor = tmp->next; /* becomes NULL if list is at end */ return DLT_RETURN_OK; } DltReturnValue dlt_kpi_remove_process_at_cursor(DltKpiProcessList *list) { if (list == NULL) { fprintf(stderr, "%s: Invalid Parameter (NULL)\n", __func__); return DLT_RETURN_WRONG_PARAMETER; } if (list->cursor == NULL) { fprintf(stderr, "%s: Invalid Parameter (NULL)\n", __func__); return DLT_RETURN_ERROR; } DltKpiProcess *tmp = list->cursor; DltReturnValue ret = dlt_kpi_remove_process_at_cursor_soft(list); if (ret < DLT_RETURN_OK) return ret; dlt_kpi_free_process(tmp); return DLT_RETURN_OK; } dlt-daemon-2.18.4/src/kpi/dlt-kpi-process-list.h000066400000000000000000000036751353342203500213610ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2011-2015, BMW AG * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author Sven Hassler * * \copyright Copyright © 2011-2015 BMW AG. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file dlt-kpi-process-list.h */ #ifndef SRC_KPI_DLT_KPI_PROCESS_LIST_H_ #define SRC_KPI_DLT_KPI_PROCESS_LIST_H_ #include "dlt-kpi-process.h" #include "dlt-kpi-common.h" typedef struct { struct DltKpiProcess *start, *cursor; } DltKpiProcessList; DltKpiProcessList *dlt_kpi_create_process_list(); DltReturnValue dlt_kpi_free_process_list_soft(DltKpiProcessList *list); DltReturnValue dlt_kpi_free_process_list(DltKpiProcessList *list); DltKpiProcess *dlt_kpi_get_process_at_cursor(DltKpiProcessList *list); DltReturnValue dlt_kpi_increment_cursor(DltKpiProcessList *list); DltReturnValue dlt_kpi_decrement_cursor(DltKpiProcessList *list); DltReturnValue dlt_kpi_reset_cursor(DltKpiProcessList *list); DltReturnValue dlt_kpi_add_process_at_start(DltKpiProcessList *list, DltKpiProcess *process); DltReturnValue dlt_kpi_add_process_before_cursor(DltKpiProcessList *list, DltKpiProcess *process); DltReturnValue dlt_kpi_add_process_after_cursor(DltKpiProcessList *list, DltKpiProcess *process); DltReturnValue dlt_kpi_remove_process_at_cursor_soft(DltKpiProcessList *list); DltReturnValue dlt_kpi_remove_process_at_cursor(DltKpiProcessList *list); /* DltReturnValue dlt_kpi_remove_process_after_cursor(DltKpiProcessList *list); */ /* DltReturnValue dlt_kpi_remove_first_process(DltKpiProcessList *list); */ #endif /* SRC_KPI_DLT_KPI_PROCESS_LIST_H_ */ dlt-daemon-2.18.4/src/kpi/dlt-kpi-process.c000066400000000000000000000323211353342203500203710ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2011-2015, BMW AG * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author Sven Hassler * * \copyright Copyright © 2011-2015 BMW AG. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file dlt-kpi-process.c */ #include "dlt-kpi-process.h" #include #include DltReturnValue dlt_kpi_read_process_file_to_str(pid_t pid, char **target_str, char *subdir); unsigned long int dlt_kpi_read_process_stat_to_ulong(pid_t pid, unsigned int index); DltReturnValue dlt_kpi_read_process_stat_cmdline(pid_t pid, char **buffer); DltReturnValue dlt_kpi_process_update_io_wait(DltKpiProcess *process, unsigned long int time_dif_ms) { if (process == NULL) { fprintf(stderr, "%s: Invalid Parameter (NULL)\n", __func__); return DLT_RETURN_WRONG_PARAMETER; } unsigned long int total_io_wait = dlt_kpi_read_process_stat_to_ulong(process->pid, 42); int cpu_count = dlt_kpi_get_cpu_count(); process->io_wait = (total_io_wait - process->last_io_wait) * 1000 / sysconf(_SC_CLK_TCK); /* busy milliseconds since last update */ if ((time_dif_ms > 0) && (cpu_count > 0)) process->io_wait = process->io_wait * 1000 / time_dif_ms / cpu_count; /* busy milliseconds per second per CPU */ process->last_io_wait = total_io_wait; return DLT_RETURN_OK; } DltReturnValue dlt_kpi_process_update_cpu_time(DltKpiProcess *process, unsigned long int time_dif_ms) { if (process == NULL) { fprintf(stderr, "%s: Invalid Parameter (NULL)\n", __func__); return DLT_RETURN_WRONG_PARAMETER; } unsigned long int utime = dlt_kpi_read_process_stat_to_ulong(process->pid, 14); unsigned long int stime = dlt_kpi_read_process_stat_to_ulong(process->pid, 15); unsigned long total_cpu_time = utime + stime; if ((process->last_cpu_time > 0) && (process->last_cpu_time <= total_cpu_time)) { int cpu_count = dlt_kpi_get_cpu_count(); process->cpu_time = (total_cpu_time - process->last_cpu_time) * 1000 / sysconf(_SC_CLK_TCK); /* busy milliseconds since last update */ if ((time_dif_ms > 0) && (cpu_count > 0)) process->cpu_time = process->cpu_time * 1000 / time_dif_ms / cpu_count; /* busy milliseconds per second per CPU */ } else { process->cpu_time = 0; } process->last_cpu_time = total_cpu_time; return DLT_RETURN_OK; } DltReturnValue dlt_kpi_process_update_rss(DltKpiProcess *process) { if (process == NULL) { fprintf(stderr, "%s: Invalid Parameter (NULL)\n", __func__); return DLT_RETURN_WRONG_PARAMETER; } process->rss = dlt_kpi_read_process_stat_to_ulong(process->pid, 24); return DLT_RETURN_OK; } DltReturnValue dlt_kpi_process_update_ctx_switches(DltKpiProcess *process) { if (process == NULL) { fprintf(stderr, "%s: Invalid Parameter (NULL)\n", __func__); return DLT_RETURN_WRONG_PARAMETER; } char *buffer, *tok, *last_tok; char *delim = " :\t\n"; last_tok = NULL; DltReturnValue ret; if ((ret = dlt_kpi_read_process_file_to_str(process->pid, &buffer, "status")) < DLT_RETURN_OK) return ret; process->ctx_switches = 0; tok = strtok(buffer, delim); while (tok != NULL) { if (last_tok != NULL) { if ((strcmp(last_tok, "voluntary_ctxt_switches") == 0) || (strcmp(last_tok, "nonvoluntary_ctxt_switches") == 0)) { char *chk; process->ctx_switches += strtol(tok, &chk, 10); if (*chk != '\0') { fprintf(stderr, "Could not parse ctx_switches info from /proc/%d/status", process->pid); free(buffer); return DLT_RETURN_ERROR; } } } last_tok = tok; tok = strtok(NULL, delim); } free(buffer); return DLT_RETURN_OK; } DltReturnValue dlt_kpi_process_update_io_bytes(DltKpiProcess *process) { if (process == NULL) { fprintf(stderr, "%s: Invalid Parameter (NULL)\n", __func__); return DLT_RETURN_WRONG_PARAMETER; } char *buffer, *tok, *last_tok; char *delim = " :\t\n"; last_tok = NULL; DltReturnValue ret; if ((ret = dlt_kpi_read_process_file_to_str(process->pid, &buffer, "io")) < DLT_RETURN_OK) return ret; process->io_bytes = 0; tok = strtok(buffer, delim); while (tok != NULL) { if (last_tok != NULL) { if ((strcmp(last_tok, "rchar") == 0) || (strcmp(last_tok, "wchar") == 0)) { char *chk; process->io_bytes += strtoul(tok, &chk, 10); if (*chk != '\0') { fprintf(stderr, "Could not parse io_bytes info from /proc/%d/io", process->pid); free(buffer); return DLT_RETURN_ERROR; } } } last_tok = tok; tok = strtok(NULL, delim); } free(buffer); return DLT_RETURN_OK; } DltReturnValue dlt_kpi_update_process(DltKpiProcess *process, unsigned long int time_dif_ms) { if (process == NULL) { fprintf(stderr, "%s: Invalid Parameter (NULL)\n", __func__); return DLT_RETURN_WRONG_PARAMETER; } dlt_kpi_process_update_io_wait(process, time_dif_ms); dlt_kpi_process_update_cpu_time(process, time_dif_ms); dlt_kpi_process_update_rss(process); dlt_kpi_process_update_ctx_switches(process); dlt_kpi_process_update_io_bytes(process); return DLT_RETURN_OK; } DltKpiProcess *dlt_kpi_create_process(int pid) { DltKpiProcess *new_process = malloc(sizeof(DltKpiProcess)); if (new_process == NULL) { fprintf(stderr, "%s: Out of Memory \n", __func__); return NULL; } memset(new_process, 0, sizeof(DltKpiProcess)); new_process->pid = pid; new_process->ppid = (pid_t)dlt_kpi_read_process_stat_to_ulong(pid, 4); dlt_kpi_read_process_file_to_str(pid, &(new_process->command_line), "cmdline"); if (new_process->command_line != NULL) if (strlen(new_process->command_line) == 0) { free(new_process->command_line); dlt_kpi_read_process_stat_cmdline(pid, &(new_process->command_line)); } dlt_kpi_update_process(new_process, 0); return new_process; } DltKpiProcess *dlt_kpi_clone_process(DltKpiProcess *original) { if (original == NULL) { fprintf(stderr, "%s: Invalid Parameter (NULL)\n", __func__); return NULL; } /* DltKpiProcess *new_process = dlt_kpi_create_process(original->pid); */ DltKpiProcess *new_process = malloc(sizeof(DltKpiProcess)); if (new_process == NULL) { fprintf(stderr, "%s: Out of Memory\n", __func__); return NULL; } memcpy(new_process, original, sizeof(DltKpiProcess)); if (original->command_line != NULL) { new_process->command_line = malloc(strlen(original->command_line) + 1); if (new_process->command_line == NULL) { fprintf(stderr, "%s: Out of Memory\n", __func__); free(new_process); return NULL; } strncpy(new_process->command_line, original->command_line, strlen(original->command_line) + 1); } else { new_process->command_line = NULL; } new_process->next = new_process->prev = NULL; return new_process; } DltReturnValue dlt_kpi_free_process(DltKpiProcess *process) { if (process == NULL) { fprintf(stderr, "%s: Invalid Parameter (NULL)\n", __func__); return DLT_RETURN_WRONG_PARAMETER; } if (process->command_line != NULL) free(process->command_line); free(process); return DLT_RETURN_OK; } DltReturnValue dlt_kpi_print_process(DltKpiProcess *process) { if (process == NULL) { fprintf(stderr, "%s: Invalid Parameter (NULL)\n", __func__); return DLT_RETURN_WRONG_PARAMETER; } printf("[PID %d]\n", process->pid); printf(" > PPID : %d\n", process->ppid); printf(" > CMDLINE : %s\n", process->command_line); printf(" > CPUTIME : %lu (busy ms/s)\n", process->cpu_time); printf(" > RSS : %ld\n", process->rss); printf(" > CTXSWTC : %ld\n", process->ctx_switches); printf(" > IOBYTES : %lu\n", process->io_bytes); printf(" > IOWAIT : %ld (%ld)\n", process->io_wait, process->last_io_wait); return DLT_RETURN_OK; } DltReturnValue dlt_kpi_read_process_file_to_str(pid_t pid, char **target_str, char *subdir) { if (target_str == NULL) { fprintf(stderr, "%s: Invalid Parameter (NULL)\n", __func__); return DLT_RETURN_ERROR; } *target_str = NULL; if (pid <= 0) { fprintf(stderr, "%s: Invalid Parameter (PID)\n", __func__); return DLT_RETURN_ERROR; } if (subdir == NULL) { fprintf(stderr, "%s: Invalid Parameter (NULL)\n", __func__); return DLT_RETURN_ERROR; } char filename[BUFFER_SIZE]; snprintf(filename, BUFFER_SIZE, "/proc/%d/%s", pid, subdir); return dlt_kpi_read_file_compact(filename, target_str); } unsigned long int dlt_kpi_read_process_stat_to_ulong(pid_t pid, unsigned int index) { if (pid <= 0) { fprintf(stderr, "%s: Invalid Parameter (NULL)\n", __func__); return 0; } char *buffer = NULL; if (dlt_kpi_read_process_file_to_str(pid, &buffer, "stat") < DLT_RETURN_OK) { /* fprintf(stderr, "dlt_kpi_read_process_stat_to_ulong(): Error while reading process stat file. Pid: %d. Requested index: %u\n", pid, index); // can happen if process closed shortly before */ if (buffer != NULL) free(buffer); return 0; } char *tok = strtok(buffer, " \t\n"); unsigned int i = 1, found = 0; while (tok != NULL) { if (i == index) { found = 1; break; } i++; tok = strtok(NULL, " \t\n"); } unsigned long int ret = 0; if (found) { char *check = NULL; ret = strtoul(tok, &check, 10); if (*check != '\0') { fprintf(stderr, "dlt_kpi_read_process_stat_to_ulong(): Could not extract token\n"); ret = 0; } } else { fprintf(stderr, "dlt_kpi_read_process_stat_to_ulong(): Index not found\n"); } free(buffer); return ret; } DltReturnValue dlt_kpi_read_process_stat_cmdline(pid_t pid, char **buffer) { if (pid <= 0) { fprintf(stderr, "%s: Invalid Parameter (PID)\n", __func__); return DLT_RETURN_WRONG_PARAMETER; } if (buffer == NULL) { fprintf(stderr, "%s: Invalid Parameter (NULL)\n", __func__); return DLT_RETURN_WRONG_PARAMETER; } char *tmp_buffer = NULL; DltReturnValue tmp = dlt_kpi_read_process_file_to_str(pid, &tmp_buffer, "stat"); if (tmp < DLT_RETURN_OK) { if (tmp_buffer != NULL) free(tmp_buffer); return tmp; } char *tok = strtok(tmp_buffer, " \t\n"); unsigned int i = 1; while (tok != NULL) { if (i == 2) break; i++; tok = strtok(NULL, " \t\n"); } if (i == 2) { (*buffer) = malloc(strlen(tok) + 1); strncpy(*buffer, tok, strlen(tok) + 1); } else { fprintf(stderr, "dlt_kpi_read_process_stat_cmdline(): cmdline entry not found\n"); return DLT_RETURN_ERROR; } free(tmp_buffer); return DLT_RETURN_OK; } DltReturnValue dlt_kpi_get_msg_process_update(DltKpiProcess *process, char *buffer, int maxlen) { if ((process == NULL) || (buffer == NULL)) { fprintf(stderr, "%s: Invalid Parameter (NULL)\n", __func__); return DLT_RETURN_WRONG_PARAMETER; } snprintf(buffer, maxlen, "%d;%lu;%ld;%ld;%lu;%lu", process->pid, process->cpu_time, process->rss, process->ctx_switches, process->io_bytes, process->io_wait); return DLT_RETURN_OK; } DltReturnValue dlt_kpi_get_msg_process_new(DltKpiProcess *process, char *buffer, int maxlen) { if ((process == NULL) || (buffer == NULL)) { fprintf(stderr, "%s: Invalid Parameter (NULL)\n", __func__); return DLT_RETURN_WRONG_PARAMETER; } snprintf(buffer, maxlen, "%d;%d;%s", process->pid, process->ppid, process->command_line); return DLT_RETURN_OK; } DltReturnValue dlt_kpi_get_msg_process_stop(DltKpiProcess *process, char *buffer, int maxlen) { if ((process == NULL) || (buffer == NULL)) { fprintf(stderr, "%s: Invalid Parameter (NULL)\n", __func__); return DLT_RETURN_WRONG_PARAMETER; } snprintf(buffer, maxlen, "%d", process->pid); return DLT_RETURN_OK; } DltReturnValue dlt_kpi_get_msg_process_commandline(DltKpiProcess *process, char *buffer, int maxlen) { if ((process == NULL) || (buffer == NULL)) { fprintf(stderr, "%s: Invalid Parameter (NULL)\n", __func__); return DLT_RETURN_WRONG_PARAMETER; } snprintf(buffer, maxlen, "%d;%s", process->pid, process->command_line); return DLT_RETURN_OK; } dlt-daemon-2.18.4/src/kpi/dlt-kpi-process.h000066400000000000000000000035061353342203500204010ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2011-2015, BMW AG * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author Sven Hassler * * \copyright Copyright © 2011-2015 BMW AG. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file dlt-kpi-process.h */ #ifndef SRC_KPI_DLT_KPI_PROCESS_H_ #define SRC_KPI_DLT_KPI_PROCESS_H_ #include "dlt.h" #include #include "dlt-kpi-common.h" typedef struct DltKpiEventWatch DltKpiEventWatch; /* forward declaration */ typedef struct DltKpiProcess { pid_t pid, ppid; char *command_line; unsigned long int cpu_time, last_cpu_time, io_wait, last_io_wait, io_bytes; long int rss, ctx_switches; struct DltKpiProcess *next, *prev; } DltKpiProcess; DltKpiProcess *dlt_kpi_create_process(); DltKpiProcess *dlt_kpi_clone_process(DltKpiProcess *original); DltReturnValue dlt_kpi_free_process(DltKpiProcess *process); DltReturnValue dlt_kpi_print_process(DltKpiProcess *process); DltReturnValue dlt_kpi_update_process(DltKpiProcess *process, unsigned long int time_dif_ms); DltReturnValue dlt_kpi_get_msg_process_new(DltKpiProcess *process, char *buffer, int maxlen); DltReturnValue dlt_kpi_get_msg_process_stop(DltKpiProcess *process, char *buffer, int maxlen); DltReturnValue dlt_kpi_get_msg_process_update(DltKpiProcess *process, char *buffer, int maxlen); DltReturnValue dlt_kpi_get_msg_process_commandline(DltKpiProcess *process, char *buffer, int maxlen); #endif /* SRC_KPI_DLT_KPI_PROCESS_H_ */ dlt-daemon-2.18.4/src/kpi/dlt-kpi.c000066400000000000000000000365771353342203500167360ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2011-2015, BMW AG * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author Sven Hassler * * \copyright Copyright © 2011-2015 BMW AG. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file dlt-kpi.c */ #include "dlt-kpi.h" #include #include #include #include #include DLT_DECLARE_CONTEXT(kpi_ctx); DltKpiConfig config; static volatile sig_atomic_t stop_loop = 0; static DltKpiProcessList *list, *new_process_list, *stopped_process_list, *update_process_list; static struct timespec _tmp_time; static pthread_mutex_t process_list_mutex; void dlt_kpi_stop_loops(int sig); void dlt_kpi_init_sigterm_handler(); DltReturnValue dlt_kpi_init_process_lists(); DltReturnValue dlt_kpi_free_process_lists(); void *dlt_kpi_start_process_thread(); DltReturnValue dlt_kpi_process_loop(); DltReturnValue dlt_kpi_update_process_list(DltKpiProcessList *list, unsigned long int time_dif_ms); void *dlt_kpi_start_irq_thread(); DltReturnValue dlt_kpi_irq_loop(); void *dlt_kpi_start_check_thread(); DltReturnValue dlt_kpi_check_loop(); DltReturnValue dlt_kpi_log_check_commandlines(); unsigned long int timespec_to_millis(struct timespec *time) { return (time->tv_sec) * 1000 + (time->tv_nsec / 1000000); } unsigned long int get_millis() { clock_gettime(CLOCK_REALTIME, &_tmp_time); return timespec_to_millis(&_tmp_time); } int main(int argc, char **argv) { printf("Launching dlt-kpi...\n"); if (dlt_kpi_init(argc, argv, &config) < DLT_RETURN_OK) { fprintf(stderr, "Initialization error!\n"); return -1; } dlt_kpi_init_sigterm_handler(); if (dlt_kpi_init_process_lists() < DLT_RETURN_OK) { fprintf(stderr, "Error occurred initializing process lists\n"); return -1; } if (pthread_mutex_init(&process_list_mutex, NULL) < 0) { fprintf(stderr, "Error occurred initializing mutex\n"); return -1; } DLT_REGISTER_APP("PROC", "/proc/-filesystem logger application"); DLT_REGISTER_CONTEXT_LL_TS(kpi_ctx, "PROC", "/proc/-filesystem logger context", config.log_level, 1); pthread_t process_thread; pthread_t irq_thread; pthread_t check_thread; if (pthread_create(&process_thread, NULL, &dlt_kpi_start_process_thread, NULL) != 0) { fprintf(stderr, "Could not create thread\n"); return -1; } if (pthread_create(&irq_thread, NULL, &dlt_kpi_start_irq_thread, NULL) != 0) { fprintf(stderr, "Could not create thread\n"); return -1; } if (pthread_create(&check_thread, NULL, &dlt_kpi_start_check_thread, NULL) != 0) { fprintf(stderr, "Could not create thread\n"); return -1; } pthread_join(process_thread, NULL); pthread_join(irq_thread, NULL); pthread_join(check_thread, NULL); DLT_UNREGISTER_CONTEXT(kpi_ctx); DLT_UNREGISTER_APP(); pthread_mutex_destroy(&process_list_mutex); dlt_kpi_free_process_lists(); printf("Done.\n"); return 0; } void dlt_kpi_init_sigterm_handler() { struct sigaction action; memset(&action, 0, sizeof(struct sigaction)); action.sa_handler = dlt_kpi_stop_loops; sigaction(SIGTERM, &action, NULL); } void dlt_kpi_stop_loops(int sig) { if (sig > -1) fprintf(stderr, "dlt-kpi is now terminating due to signal %d...\n", sig); else fprintf(stderr, "dlt-kpi is now terminating due to an error...\n"); stop_loop = 1; } DltReturnValue dlt_kpi_init_process_lists() { if ((list = dlt_kpi_create_process_list()) == NULL) return DLT_RETURN_ERROR; if ((new_process_list = dlt_kpi_create_process_list()) == NULL) return DLT_RETURN_ERROR; if ((stopped_process_list = dlt_kpi_create_process_list()) == NULL) return DLT_RETURN_ERROR; if ((update_process_list = dlt_kpi_create_process_list()) == NULL) return DLT_RETURN_ERROR; return DLT_RETURN_OK; } DltReturnValue dlt_kpi_free_process_lists() { DltReturnValue ret = DLT_RETURN_OK; if (dlt_kpi_free_process_list(list) < DLT_RETURN_OK) ret = DLT_RETURN_ERROR; if (dlt_kpi_free_process_list(new_process_list) < DLT_RETURN_OK) ret = DLT_RETURN_ERROR; if (dlt_kpi_free_process_list(stopped_process_list) < DLT_RETURN_OK) ret = DLT_RETURN_ERROR; if (dlt_kpi_free_process_list(update_process_list) < DLT_RETURN_OK) ret = DLT_RETURN_ERROR; return ret; } void *dlt_kpi_start_process_thread() { if (dlt_kpi_process_loop() < DLT_RETURN_OK) dlt_kpi_stop_loops(-1); return NULL; } DltReturnValue dlt_kpi_process_loop() { static unsigned long int old_millis, sleep_millis, dif_millis; struct timespec ts; old_millis = get_millis(); while (!stop_loop) { /*DltReturnValue ret = */ dlt_kpi_update_process_list(list, config.process_log_interval); /*if(ret < DLT_RETURN_OK) */ /* return ret; */ dif_millis = get_millis() - old_millis; if (dif_millis >= (unsigned long)(config.process_log_interval)) sleep_millis = 0; else sleep_millis = config.process_log_interval - dif_millis; ts.tv_sec = (sleep_millis * NANOSEC_PER_MILLISEC) / NANOSEC_PER_SEC; ts.tv_nsec = (sleep_millis * NANOSEC_PER_MILLISEC) % NANOSEC_PER_SEC; nanosleep(&ts, NULL); old_millis = get_millis(); } return DLT_RETURN_OK; } DltReturnValue dlt_kpi_log_list(DltKpiProcessList *list, DltReturnValue (*process_callback)(DltKpiProcess *, char *, int), char *title, int delete_elements) { if ((list == NULL) || (process_callback == NULL) || (title == NULL)) { fprintf(stderr, "%s: Invalid Parameter (NULL)\n", __func__); return DLT_RETURN_WRONG_PARAMETER; } dlt_kpi_reset_cursor(list); if (list->cursor == NULL) return DLT_RETURN_OK; /* list empty; nothing to do */ /* Synchronization message */ DLT_LOG(kpi_ctx, config.log_level, DLT_STRING(title), DLT_STRING("BEG")); DltReturnValue ret; DltContextData data; char buffer[BUFFER_SIZE]; buffer[0] = '\0'; if ((ret = dlt_user_log_write_start(&kpi_ctx, &data, config.log_level)) < DLT_RETURN_OK) { fprintf(stderr, "%s: dlt_user_log_write_start() returned error.\n", __func__); return ret; } if ((ret = dlt_user_log_write_string(&data, title)) < DLT_RETURN_OK) { fprintf(stderr, "%s: dlt_user_log_write_string() returned error.\n", __func__); return ret; } do { if ((ret = (*process_callback)(list->cursor, buffer, sizeof(buffer) - 1)) < DLT_RETURN_OK) return ret; if ((ret = dlt_user_log_write_string(&data, buffer)) < DLT_RETURN_OK) { /* Log buffer full => Write log and start new one*/ if ((ret = dlt_user_log_write_finish(&data)) < DLT_RETURN_OK) { fprintf(stderr, "%s: dlt_user_log_write_finish() returned error.\n", __func__); return ret; } if ((ret = dlt_user_log_write_start(&kpi_ctx, &data, config.log_level)) < DLT_RETURN_OK) { fprintf(stderr, "%s: dlt_user_log_write_start() returned error.\n", __func__); return ret; } if ((ret = dlt_user_log_write_string(&data, title)) < DLT_RETURN_OK) { fprintf(stderr, "%s: dlt_user_log_write_string() returned error.\n", __func__); return ret; } } else if (delete_elements) { if ((ret = dlt_kpi_remove_process_at_cursor(list)) < DLT_RETURN_OK) return ret; } else { list->cursor = list->cursor->next; } } while (list->cursor != NULL); if ((ret = dlt_user_log_write_finish(&data)) < DLT_RETURN_OK) { fprintf(stderr, "%s: dlt_user_log_write_finish() returned error.\n", __func__); return ret; } /* Synchronization message */ DLT_LOG(kpi_ctx, config.log_level, DLT_STRING(title), DLT_STRING("END")); return DLT_RETURN_OK; } DltReturnValue dlt_kpi_update_process_list(DltKpiProcessList *list, unsigned long int time_dif_ms) { static char *strchk; static DltReturnValue tmp_ret; static struct dirent *current_dir; static pid_t current_dir_pid; if (list == NULL) { fprintf(stderr, "dlt_kpi_update_process_list(): Nullpointer parameter"); return DLT_RETURN_WRONG_PARAMETER; } DIR *proc_dir = opendir("/proc"); if (proc_dir == NULL) { dlt_log(LOG_ERR, "Could not open /proc/ !\n"); return DLT_RETURN_ERROR; } current_dir = readdir(proc_dir); dlt_kpi_reset_cursor(list); int debug_process_count = 0; if (pthread_mutex_lock(&process_list_mutex) < 0) { fprintf(stderr, "Can't lock mutex\n"); return DLT_RETURN_ERROR; } while (1) { if (current_dir == NULL) { /* no more active processes.. delete all remaining processes in the list */ if (list->cursor != NULL) while (list->cursor != NULL) { if ((tmp_ret = dlt_kpi_add_process_after_cursor(stopped_process_list, dlt_kpi_clone_process(list->cursor))) < DLT_RETURN_OK) return tmp_ret; dlt_kpi_remove_process_at_cursor(list); } break; } current_dir_pid = strtol(current_dir->d_name, &strchk, 10); if ((*strchk != '\0') || (current_dir_pid <= 0)) { /* no valid PID */ current_dir = readdir(proc_dir); /* next process in proc-fs */ continue; } /* compare the /proc/-filesystem with our process-list */ if ((list->cursor == NULL) || (current_dir_pid < list->cursor->pid)) { /* New Process */ DltKpiProcess *new_process = dlt_kpi_create_process(current_dir_pid); if (new_process == NULL) { fprintf(stderr, "Error: Could not create process (out of memory?)\n"); return DLT_RETURN_ERROR; } if ((tmp_ret = dlt_kpi_add_process_before_cursor(list, new_process)) < DLT_RETURN_OK) return tmp_ret; if ((tmp_ret = dlt_kpi_add_process_before_cursor(new_process_list, dlt_kpi_clone_process(new_process))) < DLT_RETURN_OK) return tmp_ret; current_dir = readdir(proc_dir); /* next process in proc-fs */ debug_process_count++; } else if (current_dir_pid > list->cursor->pid) /* Process ended */ { if ((tmp_ret = dlt_kpi_add_process_after_cursor(stopped_process_list, dlt_kpi_clone_process(list->cursor))) < DLT_RETURN_OK) return tmp_ret; if ((tmp_ret = dlt_kpi_remove_process_at_cursor(list)) < DLT_RETURN_OK) return tmp_ret; } else if (current_dir_pid == list->cursor->pid) /* Staying process */ { /* update data */ if ((tmp_ret = dlt_kpi_update_process(list->cursor, time_dif_ms)) < DLT_RETURN_OK) return tmp_ret; if (list->cursor->cpu_time > 0) /* only log active processes */ if ((tmp_ret = dlt_kpi_add_process_after_cursor(update_process_list, dlt_kpi_clone_process(list->cursor))) < DLT_RETURN_OK) { fprintf(stderr, "dlt_kpi_update_process_list: Can't add process to list updateProcessList\n"); return tmp_ret; } if ((tmp_ret = dlt_kpi_increment_cursor(list)) < DLT_RETURN_OK) /* next process in list */ return tmp_ret; current_dir = readdir(proc_dir); /* next process in proc-fs */ debug_process_count++; } } if (pthread_mutex_unlock(&process_list_mutex) < 0) { fprintf(stderr, "Can't unlock mutex\n"); return DLT_RETURN_ERROR; } /* Log new processes */ if ((tmp_ret = dlt_kpi_log_list(new_process_list, &dlt_kpi_get_msg_process_new, "NEW", 1)) < DLT_RETURN_OK) return tmp_ret; /* Log stopped processes */ if ((tmp_ret = dlt_kpi_log_list(stopped_process_list, &dlt_kpi_get_msg_process_stop, "STP", 1)) < DLT_RETURN_OK) return tmp_ret; /* Log active processes */ if ((tmp_ret = dlt_kpi_log_list(update_process_list, &dlt_kpi_get_msg_process_update, "ACT", 1)) < DLT_RETURN_OK) return tmp_ret; if (closedir(proc_dir) < 0) fprintf(stderr, "Could not close /proc/ directory\n"); return DLT_RETURN_OK; } void *dlt_kpi_start_irq_thread() { if (dlt_kpi_irq_loop() < DLT_RETURN_OK) dlt_kpi_stop_loops(-1); return NULL; } DltReturnValue dlt_kpi_irq_loop() { static unsigned long int old_millis, sleep_millis, dif_millis; struct timespec ts; old_millis = get_millis(); while (!stop_loop) { /*DltReturnValue ret = */ dlt_kpi_log_interrupts(&kpi_ctx, config.log_level); /*if(ret < DLT_RETURN_OK) */ /* return ret; */ dif_millis = get_millis() - old_millis; if (dif_millis >= (unsigned long)(config.irq_log_interval)) sleep_millis = 0; else sleep_millis = config.irq_log_interval - dif_millis; ts.tv_sec = (sleep_millis * NANOSEC_PER_MILLISEC) / NANOSEC_PER_SEC; ts.tv_nsec = (sleep_millis * NANOSEC_PER_MILLISEC) % NANOSEC_PER_SEC; nanosleep(&ts, NULL); old_millis = get_millis(); } return DLT_RETURN_OK; } void *dlt_kpi_start_check_thread() { if (dlt_kpi_check_loop() < DLT_RETURN_OK) dlt_kpi_stop_loops(-1); return NULL; } DltReturnValue dlt_kpi_check_loop() { static unsigned long int old_millis, sleep_millis, dif_millis; struct timespec ts; old_millis = get_millis(); while (!stop_loop) { /*DltReturnValue ret = */ dlt_kpi_log_check_commandlines(); /*if(ret < DLT_RETURN_OK) */ /* return ret; */ dif_millis = get_millis() - old_millis; if (dif_millis >= (unsigned long)(config.check_log_interval)) sleep_millis = 0; else sleep_millis = config.check_log_interval - dif_millis; ts.tv_sec = (sleep_millis * NANOSEC_PER_MILLISEC) / NANOSEC_PER_SEC; ts.tv_nsec = (sleep_millis * NANOSEC_PER_MILLISEC) % NANOSEC_PER_SEC; nanosleep(&ts, NULL); old_millis = get_millis(); } return DLT_RETURN_OK; } DltReturnValue dlt_kpi_log_check_commandlines() { if (pthread_mutex_lock(&process_list_mutex) < 0) { fprintf(stderr, "Can't lock mutex\n"); return DLT_RETURN_ERROR; } DltReturnValue ret = dlt_kpi_log_list(list, dlt_kpi_get_msg_process_commandline, "CHK", 0); if (pthread_mutex_unlock(&process_list_mutex) < 0) { fprintf(stderr, "Can't unlock mutex\n"); return DLT_RETURN_ERROR; } return ret; } dlt-daemon-2.18.4/src/kpi/dlt-kpi.conf000066400000000000000000000012431353342203500174170ustar00rootroot00000000000000# Configuration file for DLT KPI logger # ######################################################################## # General configuration ######################################################################## # The interval in milliseconds of how often process updates should be logged. (Default: 1000) process_interval = 1000 # The interval in milliseconds of how often interrupt stats should be logged. (Default: 3000) irq_interval = 3000 # The interval in milliseconds of how often the commandlines of all processes should be logged. (Default: 10000) check_interval = 10000 # The used log level. -1 = DEFAULT, 0 = OFF, [...], 6 = VERBOSE (Default: 4) log_level = 4dlt-daemon-2.18.4/src/kpi/dlt-kpi.h000066400000000000000000000032101353342203500167150ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2011-2015, BMW AG * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author Sven Hassler * * \copyright Copyright © 2011-2015 BMW AG. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file dlt-kpi.h */ #ifndef SRC_KPI_DLT_KPI_H_ #define SRC_KPI_DLT_KPI_H_ #include "dlt.h" #include #include "dlt-kpi-common.h" #include "dlt-kpi-interrupt.h" #include "dlt-kpi-process.h" #include "dlt-kpi-process-list.h" /* CONSTANT DEFINITIONS */ #define DEFAULT_CONF_FILE (CONFIGURATION_FILES_DIR "/dlt-kpi.conf") #define COMMAND_LINE_SIZE 1024 #define NANOSEC_PER_MILLISEC 1000000 #define NANOSEC_PER_SEC 1000000000 /* STRUCTURES */ typedef struct { char *configurationFileName; int customConfigFile; } DltKpiOptions; typedef struct { int process_log_interval, irq_log_interval, check_log_interval; DltLogLevelType log_level; } DltKpiConfig; /* FUNCTION DECLARATIONS: */ DltReturnValue dlt_kpi_read_command_line(DltKpiOptions *options, int argc, char **argv); DltReturnValue dlt_kpi_read_configuration_file(DltKpiConfig *config, char *file_name); void dlt_kpi_free_cli_options(DltKpiOptions *options); DltReturnValue dlt_kpi_init(int argc, char **argv, DltKpiConfig *config); #endif /* SRC_KPI_DLT_KPI_H_ */ dlt-daemon-2.18.4/src/lib/000077500000000000000000000000001353342203500151675ustar00rootroot00000000000000dlt-daemon-2.18.4/src/lib/CMakeLists.txt000066400000000000000000000030761353342203500177350ustar00rootroot00000000000000####### # SPDX license identifier: MPL-2.0 # # Copyright (C) 2011-2015, BMW AG # # This file is part of GENIVI Project DLT - Diagnostic Log and Trace. # # This Source Code Form is subject to the terms of the # Mozilla Public License (MPL), v. 2.0. # If a copy of the MPL was not distributed with this file, # You can obtain one at http://mozilla.org/MPL/2.0/. # # For further information see http://www.genivi.org/. ####### set(dlt_LIB_SRCS dlt_user.c dlt_client.c dlt_filetransfer.c dlt_env_ll.c ${PROJECT_SOURCE_DIR}/src/shared/dlt_common.c ${PROJECT_SOURCE_DIR}/src/shared/dlt_protocol.c ${PROJECT_SOURCE_DIR}/src/shared/dlt_user_shared.c ) if(WITH_DLT_SHM_ENABLE) set(dlt_LIB_SRCS ${dlt_LIB_SRCS} ${PROJECT_SOURCE_DIR}/src/shared/dlt_shm.c) endif() add_library(dlt ${dlt_LIB_SRCS}) if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux") set(RT_LIBRARY rt) set(SOCKET_LIBRARY "") else() set(RT_LIBRARY "") set(SOCKET_LIBRARY socket) endif() if(HAVE_FUNC_PTHREAD_SETNAME_NP) add_definitions(-DDLT_USE_PTHREAD_SETNAME_NP) message(STATUS "Using pthread_setname_np API to set thread name") else() message(STATUS "pthread_setname_np API not available on this platform") endif() target_link_libraries(dlt ${RT_LIBRARY} ${SOCKET_LIBRARY} ${CMAKE_THREAD_LIBS_INIT}) set_target_properties(dlt PROPERTIES VERSION ${DLT_VERSION} SOVERSION ${DLT_MAJOR_VERSION}) install(TARGETS dlt RUNTIME DESTINATION bin LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}/static COMPONENT base) dlt-daemon-2.18.4/src/lib/dlt_client.c000066400000000000000000001060741353342203500174640ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2011-2015, BMW AG * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author Alexander Wenzel * * \copyright Copyright © 2011-2015 BMW AG. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file dlt_client.c */ /******************************************************************************* ** ** ** SRC-MODULE: dlt_client.c ** ** ** ** TARGET : linux ** ** ** ** PROJECT : DLT ** ** ** ** AUTHOR : Alexander Wenzel Alexander.AW.Wenzel@bmw.de ** ** Markus Klein ** ** ** ** PURPOSE : ** ** ** ** REMARKS : ** ** ** ** PLATFORM DEPENDANT [yes/no]: yes ** ** ** ** TO BE CHANGED BY USER [yes/no]: no ** ** ** *******************************************************************************/ /******************************************************************************* ** Author Identity ** ******************************************************************************** ** ** ** Initials Name Company ** ** -------- ------------------------- ---------------------------------- ** ** aw Alexander Wenzel BMW ** ** mk Markus Klein Fraunhofer ESK ** *******************************************************************************/ /******************************************************************************* ** Revision Control History ** *******************************************************************************/ /* * $LastChangedRevision$ * $LastChangedDate$ * $LastChangedBy$ * Initials Date Comment * aw 12.07.2010 initial */ #include #if defined (__WIN32__) || defined (_MSC_VER) # pragma warning(disable : 4996) /* Switch off C4996 warnings */ # include /* for socket(), connect(), send(), and recv() */ #else # include /* for socket(), connect(), send(), and recv() */ # include /* for sockaddr_in and inet_addr() */ # include # include # include #endif #if defined(_MSC_VER) # include #else # include # include #endif #include #include /* for malloc(), free() */ #include /* for strlen(), memcmp(), memmove() */ #include #include #include "dlt_types.h" #include "dlt_client.h" #include "dlt_client_cfg.h" static int (*message_callback_function)(DltMessage *message, void *data) = NULL; void dlt_client_register_message_callback(int (*registerd_callback)(DltMessage *message, void *data)) { message_callback_function = registerd_callback; } DltReturnValue dlt_client_init_port(DltClient *client, int port, int verbose) { if (verbose && (port != DLT_DAEMON_TCP_PORT)) dlt_vlog(LOG_INFO, "Init dlt client struct with port %d\n", port); if (client == NULL) return DLT_RETURN_ERROR; client->sock = -1; client->servIP = NULL; client->serialDevice = NULL; client->baudrate = DLT_CLIENT_INITIAL_BAUDRATE; client->port = port; client->socketPath = NULL; client->mode = DLT_CLIENT_MODE_TCP; client->receiver.buffer = NULL; client->receiver.buf = NULL; client->receiver.backup_buf = NULL; return DLT_RETURN_OK; } DltReturnValue dlt_client_init(DltClient *client, int verbose) { char *env_daemon_port; int tmp_port; /* the port may be specified by an environment variable, defaults to DLT_DAEMON_TCP_PORT */ unsigned short servPort = DLT_DAEMON_TCP_PORT; /* the port may be specified by an environment variable */ env_daemon_port = getenv(DLT_CLIENT_ENV_DAEMON_TCP_PORT); if (env_daemon_port != NULL) { tmp_port = atoi(env_daemon_port); if ((tmp_port < IPPORT_RESERVED) || ((unsigned)tmp_port > USHRT_MAX)) { dlt_vlog(LOG_ERR, "Specified port is out of possible range: %d.\n", tmp_port); return DLT_RETURN_ERROR; } else { servPort = (unsigned short)tmp_port; } } if (verbose) dlt_vlog(LOG_INFO, "Init dlt client struct with default port: %hu.\n", servPort); return dlt_client_init_port(client, servPort, verbose); } DltReturnValue dlt_client_connect(DltClient *client, int verbose) { char portnumbuffer[33]; struct addrinfo hints, *servinfo, *p; struct sockaddr_un addr; int rv; memset(&hints, 0, sizeof(hints)); hints.ai_socktype = SOCK_STREAM; if (client == 0) return DLT_RETURN_ERROR; switch (client->mode) { case DLT_CLIENT_MODE_TCP: snprintf(portnumbuffer, 32, "%d", client->port); if ((rv = getaddrinfo(client->servIP, portnumbuffer, &hints, &servinfo)) != 0) { fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv)); return DLT_RETURN_ERROR; } for (p = servinfo; p != NULL; p = p->ai_next) { if ((client->sock = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) < 0) { dlt_vlog(LOG_WARNING, "socket() failed! %s\n", strerror(errno)); continue; } if (connect(client->sock, p->ai_addr, p->ai_addrlen) < 0) { close(client->sock); dlt_vlog(LOG_WARNING, "connect() failed! %s\n", strerror(errno)); continue; } break; } freeaddrinfo(servinfo); if (p == NULL) { dlt_log(LOG_ERR, "ERROR: failed to connect.\n"); return DLT_RETURN_ERROR; } if (verbose) printf("Connected to DLT daemon (%s)\n", client->servIP); break; case DLT_CLIENT_MODE_SERIAL: /* open serial connection */ client->sock = open(client->serialDevice, O_RDWR); if (client->sock < 0) { fprintf(stderr, "ERROR: Failed to open device %s\n", client->serialDevice); return DLT_RETURN_ERROR; } if (isatty(client->sock)) { #if !defined (__WIN32__) if (dlt_setup_serial(client->sock, client->baudrate) < DLT_RETURN_OK) { fprintf(stderr, "ERROR: Failed to configure serial device %s (%s) \n", client->serialDevice, strerror(errno)); return DLT_RETURN_ERROR; } #else return DLT_RETURN_ERROR; #endif } else { if (verbose) fprintf(stderr, "ERROR: Device is not a serial device, device = %s (%s) \n", client->serialDevice, strerror(errno)); return DLT_RETURN_ERROR; } if (verbose) printf("Connected to %s\n", client->serialDevice); break; case DLT_CLIENT_MODE_UNIX: if ((client->sock = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) { fprintf(stderr, "ERROR: (unix) socket error: %s\n", strerror(errno)); return DLT_RETURN_ERROR; } memset(&addr, 0, sizeof(addr)); addr.sun_family = AF_UNIX; memcpy(addr.sun_path, client->socketPath, sizeof(addr.sun_path) - 1); if (connect(client->sock, (struct sockaddr *) &addr, sizeof(addr)) == -1) { fprintf(stderr, "ERROR: (unix) connect error: %s\n", strerror(errno)); return DLT_RETURN_ERROR; } if (client->sock < 0) { fprintf(stderr, "ERROR: Failed to open device %s\n", client->socketPath); return DLT_RETURN_ERROR; } break; default: if (verbose) fprintf(stderr, "ERROR: Mode not supported: %d\n", client->mode); return DLT_RETURN_ERROR; } if (dlt_receiver_init(&(client->receiver), client->sock, DLT_RECEIVE_BUFSIZE) != DLT_RETURN_OK) { fprintf(stderr, "ERROR initializing receiver\n"); return DLT_RETURN_ERROR; } return DLT_RETURN_OK; } DltReturnValue dlt_client_cleanup(DltClient *client, int verbose) { int ret = DLT_RETURN_OK; if (verbose) printf("Cleanup dlt client\n"); if (client == NULL) return DLT_RETURN_WRONG_PARAMETER; if (client->sock != -1) close(client->sock); if (dlt_receiver_free(&(client->receiver)) != DLT_RETURN_OK) { dlt_vlog(LOG_WARNING, "Failed to free receiver\n"); ret = DLT_RETURN_ERROR; } if (client->serialDevice) { free(client->serialDevice); client->serialDevice = NULL; } if (client->servIP) { free(client->servIP); client->servIP = NULL; } if (client->socketPath) { free(client->socketPath); client->socketPath = NULL; } return ret; } DltReturnValue dlt_client_main_loop(DltClient *client, void *data, int verbose) { DltMessage msg; int ret; if (client == 0) return DLT_RETURN_ERROR; if (dlt_message_init(&msg, verbose) == DLT_RETURN_ERROR) return DLT_RETURN_ERROR; while (1) { /* wait for data from socket or serial connection */ ret = dlt_receiver_receive(&(client->receiver), client->mode); if (ret <= 0) { /* No more data to be received */ if (dlt_message_free(&msg, verbose) == DLT_RETURN_ERROR) return DLT_RETURN_ERROR; return DLT_RETURN_TRUE; } while (dlt_message_read(&msg, (unsigned char *)(client->receiver.buf), client->receiver.bytesRcvd, 0, verbose) == DLT_MESSAGE_ERROR_OK) { /* Call callback function */ if (message_callback_function) (*message_callback_function)(&msg, data); if (msg.found_serialheader) { if (dlt_receiver_remove(&(client->receiver), msg.headersize + msg.datasize - sizeof(DltStorageHeader) + sizeof(dltSerialHeader)) == DLT_RETURN_ERROR) { /* Return value ignored */ dlt_message_free(&msg, verbose); return DLT_RETURN_ERROR; } } else if (dlt_receiver_remove(&(client->receiver), msg.headersize + msg.datasize - sizeof(DltStorageHeader)) == DLT_RETURN_ERROR) { /* Return value ignored */ dlt_message_free(&msg, verbose); return DLT_RETURN_ERROR; } } if (dlt_receiver_move_to_begin(&(client->receiver)) == DLT_RETURN_ERROR) { /* Return value ignored */ dlt_message_free(&msg, verbose); return DLT_RETURN_ERROR; } } if (dlt_message_free(&msg, verbose) == DLT_RETURN_ERROR) return DLT_RETURN_ERROR; return DLT_RETURN_OK; } DltReturnValue dlt_client_send_ctrl_msg(DltClient *client, char *apid, char *ctid, uint8_t *payload, uint32_t size) { DltMessage msg; int ret; int32_t len; uint32_t id_tmp; uint32_t id; if ((client == 0) || (client->sock < 0) || (apid == 0) || (ctid == 0)) return DLT_RETURN_ERROR; /* initialise new message */ if (dlt_message_init(&msg, 0) == DLT_RETURN_ERROR) return DLT_RETURN_ERROR; /* prepare payload of data */ msg.datasize = size; if (msg.databuffer && (msg.databuffersize < msg.datasize)) { free(msg.databuffer); msg.databuffer = 0; } if (msg.databuffer == 0) { msg.databuffer = (uint8_t *)malloc(msg.datasize); msg.databuffersize = msg.datasize; } if (msg.databuffer == 0) { dlt_message_free(&msg, 0); return DLT_RETURN_ERROR; } /* copy data */ memcpy(msg.databuffer, payload, size); /* prepare storage header */ msg.storageheader = (DltStorageHeader *)msg.headerbuffer; if (dlt_set_storageheader(msg.storageheader, "") == DLT_RETURN_ERROR) { dlt_message_free(&msg, 0); return DLT_RETURN_ERROR; } /* prepare standard header */ msg.standardheader = (DltStandardHeader *)(msg.headerbuffer + sizeof(DltStorageHeader)); msg.standardheader->htyp = DLT_HTYP_WEID | DLT_HTYP_WTMS | DLT_HTYP_UEH | DLT_HTYP_PROTOCOL_VERSION1; #if (BYTE_ORDER == BIG_ENDIAN) msg.standardheader->htyp = (msg.standardheader->htyp | DLT_HTYP_MSBF); #endif msg.standardheader->mcnt = 0; /* Set header extra parameters */ dlt_set_id(msg.headerextra.ecu, client->ecuid); /*msg.headerextra.seid = 0; */ msg.headerextra.tmsp = dlt_uptime(); /* Copy header extra parameters to headerbuffer */ if (dlt_message_set_extraparameters(&msg, 0) == DLT_RETURN_ERROR) { dlt_message_free(&msg, 0); return DLT_RETURN_ERROR; } /* prepare extended header */ msg.extendedheader = (DltExtendedHeader *)(msg.headerbuffer + sizeof(DltStorageHeader) + sizeof(DltStandardHeader) + DLT_STANDARD_HEADER_EXTRA_SIZE(msg.standardheader->htyp)); msg.extendedheader->msin = DLT_MSIN_CONTROL_REQUEST; msg.extendedheader->noar = 1; /* number of arguments */ dlt_set_id(msg.extendedheader->apid, (apid[0] == '\0') ? DLT_CLIENT_DUMMY_APP_ID : apid); dlt_set_id(msg.extendedheader->ctid, (ctid[0] == '\0') ? DLT_CLIENT_DUMMY_CON_ID : ctid); /* prepare length information */ msg.headersize = sizeof(DltStorageHeader) + sizeof(DltStandardHeader) + sizeof(DltExtendedHeader) + DLT_STANDARD_HEADER_EXTRA_SIZE(msg.standardheader->htyp); len = msg.headersize - sizeof(DltStorageHeader) + msg.datasize; if (len > UINT16_MAX) { fprintf(stderr, "Critical: Huge injection message discarded!\n"); dlt_message_free(&msg, 0); return DLT_RETURN_ERROR; } msg.standardheader->len = DLT_HTOBE_16(len); /* Send data (without storage header) */ if ((client->mode == DLT_CLIENT_MODE_TCP) || (client->mode == DLT_CLIENT_MODE_SERIAL)) { /* via FileDescriptor */ ret = write(client->sock, msg.headerbuffer + sizeof(DltStorageHeader), msg.headersize - sizeof(DltStorageHeader)); if (0 > ret) { dlt_log(LOG_ERR, "Sending message failed\n"); dlt_message_free(&msg, 0); return DLT_RETURN_ERROR; } ret = write(client->sock, msg.databuffer, msg.datasize); if (0 > ret) { dlt_log(LOG_ERR, "Sending message failed\n"); dlt_message_free(&msg, 0); return DLT_RETURN_ERROR; } id_tmp = *((uint32_t *)(msg.databuffer)); id = DLT_ENDIAN_GET_32(msg.standardheader->htyp, id_tmp); dlt_vlog(LOG_INFO, "Control message forwarded : %s\n", dlt_get_service_name(id)); } else { /* via Socket */ send(client->sock, (const char *)(msg.headerbuffer + sizeof(DltStorageHeader)), msg.headersize - sizeof(DltStorageHeader), 0); send(client->sock, (const char *)msg.databuffer, msg.datasize, 0); } /* free message */ if (dlt_message_free(&msg, 0) == DLT_RETURN_ERROR) return DLT_RETURN_ERROR; return DLT_RETURN_OK; } DltReturnValue dlt_client_send_inject_msg(DltClient *client, char *apid, char *ctid, uint32_t serviceID, uint8_t *buffer, uint32_t size) { uint8_t *payload; int offset; payload = (uint8_t *)malloc(sizeof(uint32_t) + sizeof(uint32_t) + size); if (payload == 0) return DLT_RETURN_ERROR; offset = 0; memcpy(payload, &serviceID, sizeof(serviceID)); offset += sizeof(uint32_t); memcpy(payload + offset, &size, sizeof(size)); offset += sizeof(uint32_t); memcpy(payload + offset, buffer, size); /* free message */ if (dlt_client_send_ctrl_msg(client, apid, ctid, payload, sizeof(uint32_t) + sizeof(uint32_t) + size) == DLT_RETURN_ERROR) { free(payload); return DLT_RETURN_ERROR; } free(payload); return DLT_RETURN_OK; } DltReturnValue dlt_client_send_log_level(DltClient *client, char *apid, char *ctid, uint8_t logLevel) { DltServiceSetLogLevel *req; int ret = DLT_RETURN_ERROR; if (client == NULL) return ret; req = (DltServiceSetLogLevel *)malloc(sizeof(DltServiceSetLogLevel)); if (req == NULL) return ret; memset(req, 0, sizeof(DltServiceSetLogLevel)); req->service_id = DLT_SERVICE_ID_SET_LOG_LEVEL; dlt_set_id(req->apid, apid); dlt_set_id(req->ctid, ctid); req->log_level = logLevel; dlt_set_id(req->com, "remo"); /* free message */ ret = dlt_client_send_ctrl_msg(client, "APP", "CON", (uint8_t *)req, sizeof(DltServiceSetLogLevel)); free(req); return ret; } DltReturnValue dlt_client_get_log_info(DltClient *client) { DltServiceGetLogInfoRequest *req; int ret = DLT_RETURN_ERROR; if (client == NULL) return ret; req = (DltServiceGetLogInfoRequest *)malloc(sizeof(DltServiceGetLogInfoRequest)); if (req == NULL) return ret; req->service_id = DLT_SERVICE_ID_GET_LOG_INFO; req->options = 7; dlt_set_id(req->apid, ""); dlt_set_id(req->ctid, ""); dlt_set_id(req->com, "remo"); /* send control message to daemon*/ ret = dlt_client_send_ctrl_msg(client, "", "", (uint8_t *)req, sizeof(DltServiceGetLogInfoRequest)); free(req); return ret; } DltReturnValue dlt_client_get_default_log_level(DltClient *client) { DltServiceGetDefaultLogLevelRequest *req; int ret = DLT_RETURN_ERROR; if (client == NULL) return ret; req = (DltServiceGetDefaultLogLevelRequest *) malloc(sizeof(DltServiceGetDefaultLogLevelRequest)); if (req == NULL) return ret; req->service_id = DLT_SERVICE_ID_GET_DEFAULT_LOG_LEVEL; /* send control message to daemon*/ ret = dlt_client_send_ctrl_msg(client, "", "", (uint8_t *)req, sizeof(DltServiceGetDefaultLogLevelRequest)); free(req); return ret; } DltReturnValue dlt_client_get_software_version(DltClient *client) { DltServiceGetSoftwareVersion *req; int ret = DLT_RETURN_ERROR; if (client == NULL) return ret; req = (DltServiceGetSoftwareVersion *)malloc(sizeof(DltServiceGetSoftwareVersion)); req->service_id = DLT_SERVICE_ID_GET_SOFTWARE_VERSION; /* send control message to daemon*/ ret = dlt_client_send_ctrl_msg(client, "", "", (uint8_t *)req, sizeof(DltServiceGetSoftwareVersion)); free(req); return ret; } DltReturnValue dlt_client_send_trace_status(DltClient *client, char *apid, char *ctid, uint8_t traceStatus) { DltServiceSetLogLevel *req; uint8_t *payload; payload = (uint8_t *)malloc(sizeof(DltServiceSetLogLevel)); if (payload == 0) return DLT_RETURN_ERROR; req = (DltServiceSetLogLevel *)payload; memset(req, 0, sizeof(DltServiceSetLogLevel)); req->service_id = DLT_SERVICE_ID_SET_TRACE_STATUS; dlt_set_id(req->apid, apid); dlt_set_id(req->ctid, ctid); req->log_level = traceStatus; dlt_set_id(req->com, "remo"); /* free message */ if (dlt_client_send_ctrl_msg(client, "APP", "CON", payload, sizeof(DltServiceSetLogLevel)) == DLT_RETURN_ERROR) { free(payload); return DLT_RETURN_ERROR; } free(payload); return DLT_RETURN_OK; } DltReturnValue dlt_client_send_default_log_level(DltClient *client, uint8_t defaultLogLevel) { DltServiceSetDefaultLogLevel *req; uint8_t *payload; payload = (uint8_t *)malloc(sizeof(DltServiceSetDefaultLogLevel)); if (payload == 0) return DLT_RETURN_ERROR; req = (DltServiceSetDefaultLogLevel *)payload; req->service_id = DLT_SERVICE_ID_SET_DEFAULT_LOG_LEVEL; req->log_level = defaultLogLevel; dlt_set_id(req->com, "remo"); /* free message */ if (dlt_client_send_ctrl_msg(client, "APP", "CON", payload, sizeof(DltServiceSetDefaultLogLevel)) == DLT_RETURN_ERROR) { free(payload); return DLT_RETURN_ERROR; } free(payload); return DLT_RETURN_OK; } DltReturnValue dlt_client_send_all_log_level(DltClient *client, uint8_t LogLevel) { DltServiceSetDefaultLogLevel *req; uint8_t *payload; payload = (uint8_t *)malloc(sizeof(DltServiceSetDefaultLogLevel)); if (payload == 0) return DLT_RETURN_ERROR; req = (DltServiceSetDefaultLogLevel *)payload; req->service_id = DLT_SERVICE_ID_SET_ALL_LOG_LEVEL; req->log_level = LogLevel; dlt_set_id(req->com, "remo"); /* free message */ if (dlt_client_send_ctrl_msg(client, "APP", "CON", payload, sizeof(DltServiceSetDefaultLogLevel)) == -1) { free(payload); return DLT_RETURN_ERROR; } free(payload); return DLT_RETURN_OK; } DltReturnValue dlt_client_send_default_trace_status(DltClient *client, uint8_t defaultTraceStatus) { DltServiceSetDefaultLogLevel *req; uint8_t *payload; payload = (uint8_t *)malloc(sizeof(DltServiceSetDefaultLogLevel)); if (payload == 0) return DLT_RETURN_ERROR; req = (DltServiceSetDefaultLogLevel *)payload; req->service_id = DLT_SERVICE_ID_SET_DEFAULT_TRACE_STATUS; req->log_level = defaultTraceStatus; dlt_set_id(req->com, "remo"); /* free message */ if (dlt_client_send_ctrl_msg(client, "APP", "CON", payload, sizeof(DltServiceSetDefaultLogLevel)) == DLT_RETURN_ERROR) { free(payload); return DLT_RETURN_ERROR; } free(payload); return DLT_RETURN_OK; } DltReturnValue dlt_client_send_all_trace_status(DltClient *client, uint8_t traceStatus) { DltServiceSetDefaultLogLevel *req; uint8_t *payload; if (client == NULL) { dlt_vlog(LOG_ERR, "%s: Invalid parameters\n", __func__); return DLT_RETURN_ERROR; } payload = (uint8_t *)malloc(sizeof(DltServiceSetDefaultLogLevel)); if (payload == 0) { dlt_vlog(LOG_ERR, "%s: Could not allocate memory %zu\n", __func__, sizeof(DltServiceSetDefaultLogLevel)); return DLT_RETURN_ERROR; } req = (DltServiceSetDefaultLogLevel *)payload; req->service_id = DLT_SERVICE_ID_SET_ALL_TRACE_STATUS; req->log_level = traceStatus; dlt_set_id(req->com, "remo"); /* free message */ if (dlt_client_send_ctrl_msg(client, "APP", "CON", payload, sizeof(DltServiceSetDefaultLogLevel)) == -1) { free(payload); return DLT_RETURN_ERROR; } free(payload); return DLT_RETURN_OK; } DltReturnValue dlt_client_send_timing_pakets(DltClient *client, uint8_t timingPakets) { DltServiceSetVerboseMode *req; uint8_t *payload; payload = (uint8_t *)malloc(sizeof(DltServiceSetVerboseMode)); if (payload == 0) return DLT_RETURN_ERROR; req = (DltServiceSetVerboseMode *)payload; req->service_id = DLT_SERVICE_ID_SET_TIMING_PACKETS; req->new_status = timingPakets; /* free message */ if (dlt_client_send_ctrl_msg(client, "APP", "CON", payload, sizeof(DltServiceSetVerboseMode)) == DLT_RETURN_ERROR) { free(payload); return DLT_RETURN_ERROR; } free(payload); return DLT_RETURN_OK; } DltReturnValue dlt_client_send_store_config(DltClient *client) { uint32_t service_id; service_id = DLT_SERVICE_ID_STORE_CONFIG; /* free message */ if (dlt_client_send_ctrl_msg(client, "APP", "CON", (uint8_t *)&service_id, sizeof(uint32_t)) == DLT_RETURN_ERROR) return DLT_RETURN_ERROR; return DLT_RETURN_OK; } DltReturnValue dlt_client_send_reset_to_factory_default(DltClient *client) { uint32_t service_id; service_id = DLT_SERVICE_ID_RESET_TO_FACTORY_DEFAULT; /* free message */ if (dlt_client_send_ctrl_msg(client, "APP", "CON", (uint8_t *)&service_id, sizeof(uint32_t)) == DLT_RETURN_ERROR) return DLT_RETURN_ERROR; return DLT_RETURN_OK; } DltReturnValue dlt_client_setbaudrate(DltClient *client, int baudrate) { if (client == 0) return DLT_RETURN_ERROR; client->baudrate = dlt_convert_serial_speed(baudrate); return DLT_RETURN_OK; } int dlt_client_set_server_ip(DltClient *client, char *ipaddr) { client->servIP = strdup(ipaddr); if (client->servIP == NULL) { dlt_log(LOG_ERR, "ERROR: failed to duplicate server IP\n"); return DLT_RETURN_ERROR; } return DLT_RETURN_OK; } int dlt_client_set_serial_device(DltClient *client, char *serial_device) { client->serialDevice = strdup(serial_device); if (client->serialDevice == NULL) { dlt_log(LOG_ERR, "ERROR: failed to duplicate serial device\n"); return DLT_RETURN_ERROR; } return DLT_RETURN_OK; } int dlt_client_set_socket_path(DltClient *client, char *socket_path) { client->socketPath = strdup(socket_path); if (client->socketPath == NULL) { dlt_log(LOG_ERR, "ERROR: failed to duplicate socket path\n"); return DLT_RETURN_ERROR; } return DLT_RETURN_OK; } /** * free allocation when calloc failed * * @param resp DltServiceGetLogInfoResponse * @param count_app_ids number of app_ids which needs to be freed */ DLT_STATIC void dlt_client_free_calloc_failed_get_log_info(DltServiceGetLogInfoResponse *resp, int count_app_ids) { AppIDsType *app = NULL; ContextIDsInfoType *con = NULL; int i = 0; int j = 0; for (i = 0; i < count_app_ids; i++) { app = &(resp->log_info_type.app_ids[i]); for (j = 0; j < app->count_context_ids; j++) { con = &(app->context_id_info[j]); free(con->context_description); con->context_description = NULL; } free(app->app_description); app->app_description = NULL; free(app->context_id_info); app->context_id_info = NULL; } free(resp->log_info_type.app_ids); resp->log_info_type.app_ids = NULL; return; } DltReturnValue dlt_client_parse_get_log_info_resp_text(DltServiceGetLogInfoResponse *resp, char *resp_text) { AppIDsType *app = NULL; ContextIDsInfoType *con = NULL; int i = 0; int j = 0; char *rp = NULL; int rp_count = 0; if ((resp == NULL) || (resp_text == NULL)) return DLT_RETURN_WRONG_PARAMETER; /* ------------------------------------------------------ * get_log_info data structure(all data is ascii) * * get_log_info, aa, bb bb cc cc cc cc dd dd ee ee ee ee ff gg hh hh ii ii ii .. .. * ~~ ~~~~~ ~~~~~~~~~~~ ~~~~~ ~~~~~~~~~~~~~~ * cc cc cc cc dd dd ee ee ee ee ff gg hh hh ii ii ii .. .. * jj jj kk kk kk .. .. * ~~~~~~~~~~~ ~~~~~ ~~~~~~~~~~~~~~ * aa : get mode (fix value at 0x07) * bb bb : list num of apid (little endian) * cc cc cc cc: apid * dd dd : list num of ctid (little endian) * ee ee ee ee: ctid * ff : log level * gg : trace status * hh hh : description length of ctid * ii ii .. : description text of ctid * jj jj : description length of apid * kk kk .. : description text of apid * ------------------------------------------------------ */ rp = resp_text + DLT_GET_LOG_INFO_HEADER; rp_count = 0; /* check if status is acceptable */ if ((resp->status < GET_LOG_INFO_STATUS_MIN) || (resp->status > GET_LOG_INFO_STATUS_MAX)) { if (resp->status == GET_LOG_INFO_STATUS_NO_MATCHING_CTX) dlt_vlog(LOG_WARNING, "The status(%d) is invalid: NO matching Context IDs\n", resp->status); else if (resp->status == GET_LOG_INFO_STATUS_RESP_DATA_OVERFLOW) dlt_vlog(LOG_WARNING, "The status(%d) is invalid: Response data over flow\n", resp->status); else dlt_vlog(LOG_WARNING, "The status(%d) is invalid\n", resp->status); return DLT_RETURN_ERROR; } /* count_app_ids */ resp->log_info_type.count_app_ids = dlt_getloginfo_conv_ascii_to_uint16_t(rp, &rp_count); resp->log_info_type.app_ids = (AppIDsType *)calloc (resp->log_info_type.count_app_ids, sizeof(AppIDsType)); if (resp->log_info_type.app_ids == NULL) { dlt_vlog(LOG_ERR, "calloc failed for app_ids\n"); dlt_client_free_calloc_failed_get_log_info(resp, 0); return DLT_RETURN_ERROR; } for (i = 0; i < resp->log_info_type.count_app_ids; i++) { app = &(resp->log_info_type.app_ids[i]); /* get app id */ dlt_getloginfo_conv_ascii_to_id(rp, &rp_count, app->app_id, DLT_ID_SIZE); /* count_con_ids */ app->count_context_ids = dlt_getloginfo_conv_ascii_to_uint16_t(rp, &rp_count); app->context_id_info = (ContextIDsInfoType *)calloc (app->count_context_ids, sizeof(ContextIDsInfoType)); if (app->context_id_info == NULL) { dlt_vlog(LOG_ERR, "calloc failed for context_id_info\n"); dlt_client_free_calloc_failed_get_log_info(resp, i); return DLT_RETURN_ERROR; } for (j = 0; j < app->count_context_ids; j++) { con = &(app->context_id_info[j]); /* get con id */ dlt_getloginfo_conv_ascii_to_id(rp, &rp_count, con->context_id, DLT_ID_SIZE); /* log_level */ if ((resp->status == 4) || (resp->status == 6) || (resp->status == 7)) con->log_level = dlt_getloginfo_conv_ascii_to_int16_t(rp, &rp_count); /* trace status */ if ((resp->status == 5) || (resp->status == 6) || (resp->status == 7)) con->trace_status = dlt_getloginfo_conv_ascii_to_int16_t(rp, &rp_count); /* context desc */ if (resp->status == 7) { con->len_context_description = dlt_getloginfo_conv_ascii_to_uint16_t(rp, &rp_count); con->context_description = (char *)calloc (con->len_context_description + 1, sizeof(char)); if (con->context_description == 0) { dlt_log(LOG_ERR, "calloc failed for context description\n"); dlt_client_free_calloc_failed_get_log_info(resp, i); return DLT_RETURN_ERROR; } dlt_getloginfo_conv_ascii_to_id(rp, &rp_count, con->context_description, con->len_context_description); } } /* application desc */ if (resp->status == 7) { app->len_app_description = dlt_getloginfo_conv_ascii_to_uint16_t(rp, &rp_count); app->app_description = (char *)calloc (app->len_app_description + 1, sizeof(char)); if (app->app_description == 0) { dlt_log(LOG_ERR, "calloc failed for application description\n"); dlt_client_free_calloc_failed_get_log_info(resp, i); return DLT_RETURN_ERROR; } dlt_getloginfo_conv_ascii_to_id(rp, &rp_count, app->app_description, app->len_app_description); } } return DLT_RETURN_OK; } int dlt_client_cleanup_get_log_info(DltServiceGetLogInfoResponse *resp) { AppIDsType app; int i = 0; int j = 0; if (resp == NULL) return DLT_RETURN_OK; for (i = 0; i < resp->log_info_type.count_app_ids; i++) { app = resp->log_info_type.app_ids[i]; for (j = 0; j < app.count_context_ids; j++) { free(app.context_id_info[j].context_description); app.context_id_info[j].context_description = NULL; } free(app.context_id_info); app.context_id_info = NULL; free(app.app_description); app.app_description = NULL; } free(resp->log_info_type.app_ids); resp->log_info_type.app_ids = NULL; free(resp); resp = NULL; return DLT_RETURN_OK; } dlt-daemon-2.18.4/src/lib/dlt_client_cfg.h000066400000000000000000000105721353342203500203050ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2011-2015, BMW AG * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author Alexander Wenzel * * \copyright Copyright © 2011-2015 BMW AG. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file dlt_client_cfg.h */ /******************************************************************************* ** ** ** SRC-MODULE: dlt_client_cfg.h ** ** ** ** TARGET : linux ** ** ** ** PROJECT : DLT ** ** ** ** AUTHOR : Alexander Wenzel Alexander.AW.Wenzel@bmw.de ** ** Markus Klein ** ** ** ** PURPOSE : ** ** ** ** REMARKS : ** ** ** ** PLATFORM DEPENDANT [yes/no]: yes ** ** ** ** TO BE CHANGED BY USER [yes/no]: no ** ** ** *******************************************************************************/ /******************************************************************************* ** Author Identity ** ******************************************************************************** ** ** ** Initials Name Company ** ** -------- ------------------------- ---------------------------------- ** ** aw Alexander Wenzel BMW ** ** mk Markus Klein Fraunhofer ESK ** *******************************************************************************/ /******************************************************************************* ** Author Identity ** ******************************************************************************** ** ** ** Initials Name Company ** ** -------- ------------------------- ---------------------------------- ** ** aw Alexander Wenzel BMW ** ** mk Markus Klein Fraunhofer ESK ** *******************************************************************************/ #ifndef DLT_CLIENT_CFG_H #define DLT_CLIENT_CFG_H /*************/ /* Changable */ /*************/ /* Dummy application id of DLT client */ #define DLT_CLIENT_DUMMY_APP_ID "CA1" /* Dummy context id of DLT client */ #define DLT_CLIENT_DUMMY_CON_ID "CC1" /* Size of buffer */ #define DLT_CLIENT_TEXTBUFSIZE 512 /* Initial baudrate */ #if !defined (__WIN32__) && !defined(_MSC_VER) # define DLT_CLIENT_INITIAL_BAUDRATE B115200 #else # define DLT_CLIENT_INITIAL_BAUDRATE 0 #endif /* Name of environment variable for specifying the daemon port */ #define DLT_CLIENT_ENV_DAEMON_TCP_PORT "DLT_DAEMON_TCP_PORT" /************************/ /* Don't change please! */ /************************/ #endif /* DLT_CLIENT_CFG_H */ dlt-daemon-2.18.4/src/lib/dlt_env_ll.c000066400000000000000000000241361353342203500174630ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2015 Intel Corporation * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author Stefan Vacek Intel Corporation * * \copyright Copyright © 2015 Intel Corporation. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file dlt_env_ll.c */ #include "dlt_user.h" #include #include #define DLT_ENV_LL_SET_INCREASE 10 /* a generic entry looks like: * ll_item ::= apid:ctid:ll * ll_set ::= ll_item | * ll_set;ll_item */ /** * @brief extract id out of given string * * Extract 4-byte string out of given environment string, the pointer of the * environment string is moved to the next un-used character and the extracted * id is copied into \param id * * Example: * env[] = "abcd:1234:3" * char res[4u]; * char * tmp = &env[0]; * int ret = extract_id(&tmp, res); * assert(ret == 0); * assert(*tmp == ':'); * assert(res[3] == 'd'); * * @param env Environment variable * @param id Extracted ID * @return 0 if successful, -1 else */ int dlt_env_extract_id(char **const env, char *id) { int i; if (!env || !id) return -1; if (!(*env)) return -1; memset(id, 0, 4); for (i = 0; (i < 4) && (**env != ':') && (**env != 0); ++i) *id++ = *((*env)++); /* the next/last character must be ':' */ if ((0 != **env) && (':' == **env)) return 0; return -1; } /** * @brief convert a given string to lower-case * * Stops end of string or if ';' is detected */ int dlt_env_helper_to_lower(char **const env, char *result, int const res_len) { int count = 0; char ch; if (!env || !result) return -1; if (!(*env)) return -1; ch = *(*env); while (ch && (count < res_len - 1) && (ch != ';')) { if ((ch >= 'A') && (ch <= 'Z')) result[count] = ch + 'a' - 'A'; else result[count] = ch; ch = *(++(*env)); ++count; } result[count] = 0; if (!ch || (ch == ';')) /* full input was parsed */ return 0; else return -1; } int dlt_env_extract_symbolic_ll(char **const env, int8_t *ll) { char result[strlen("verbose") + 1]; if (!env || !ll) return -1; if (!(*env)) return -1; if (dlt_env_helper_to_lower(env, &result[0], sizeof(result)) == 0) { if (strncmp("default", result, sizeof(result)) == 0) *ll = -1; else if (strncmp("off", result, sizeof(result)) == 0) *ll = 0; else if (strncmp("fatal", result, sizeof(result)) == 0) *ll = 1; else if (strncmp("error", result, sizeof(result)) == 0) *ll = 2; else if (strncmp("warning", result, sizeof(result)) == 0) *ll = 3; else if (strncmp("info", result, sizeof(result)) == 0) *ll = 4; else if (strncmp("debug", result, sizeof(result)) == 0) *ll = 5; else if (strncmp("verbose", result, sizeof(result)) == 0) *ll = 6; else return -1; if (**env != 0) (*env)++; return 0; } else { return -1; } } /** * @brief extract log-level out of given string * * A valid log-level is a numeric value in the range of -1 .. 6, with: * -1: default * 0: off * 1: fatal * 2: error * 3: warning * 4: info * 5: debug * 6: verbose * During parsing, the environment string is moved to the next un-used character and the extracted * log-level is written into \param ll * * Example: * env[] = "abcd:1234:6" * int ll; * char ** tmp = &env[10]; // tmp points to '6'! * int ret = extract_ll(&tmp, &ll); * assert(ret == 0); * assert(*tmp == NULL); * assert(ll == 6); * * @param env Environment variable * @param ll Extracted log level * @return 0 if successful, -1 else */ int dlt_env_extract_ll(char **const env, int8_t *ll) { if (!env || !ll) return -1; if (!(*env)) return -1; /* extract number */ if (**env == '-') { (*env)++; if (**env == '1') { *ll = -1; (*env)++; } } else { if ((**env >= '0') && (**env < '7')) { *ll = **env - '0'; (*env)++; } else if (dlt_env_extract_symbolic_ll(env, ll) != 0) return -1; } /* check end, either next char is NULL or ';' */ if ((**env == ';') || (**env == 0)) return 0; return -1; } /** * @brief extract one item out of string * * @return 0 if successful, -1 else */ int dlt_env_extract_ll_item(char **const env, dlt_env_ll_item *const item) { int ret = -1; if (!env || !item) return -1; if (!(*env)) return -1; memset(item, 0, sizeof(dlt_env_ll_item)); ret = dlt_env_extract_id(env, item->appId); if (ret == -1) return -1; (*env)++; ret = dlt_env_extract_id(env, item->ctxId); if (ret == -1) return -1; (*env)++; ret = dlt_env_extract_ll(env, &item->ll); if (ret == -1) return -1; return 0; } /** * @brief initialize ll_set * * Must call release_ll_set before exit to release all memory * * @return -1 if memory could not be allocated * @return 0 on success */ int dlt_env_init_ll_set(dlt_env_ll_set *const ll_set) { if (!ll_set) return -1; ll_set->array_size = DLT_ENV_LL_SET_INCREASE; ll_set->item = (dlt_env_ll_item *)malloc(sizeof(dlt_env_ll_item) * ll_set->array_size); if (!ll_set->item) { /* should trigger a warning: no memory left */ ll_set->array_size = 0; return -1; } ll_set->num_elem = 0u; return 0; } /** * @brief release ll_set */ void dlt_env_free_ll_set(dlt_env_ll_set *const ll_set) { if (!ll_set) return; if (ll_set->item != NULL) { free(ll_set->item); ll_set->item = NULL; } ll_set->array_size = 0u; ll_set->num_elem = 0u; } /** * @brief increase size of ll_set by LL_SET_INCREASE elements * * @return -1 if memory could not be allocated * @return 0 on success */ int dlt_env_increase_ll_set(dlt_env_ll_set *const ll_set) { dlt_env_ll_item *old_set; size_t old_size; if (!ll_set) return -1; old_set = ll_set->item; old_size = ll_set->array_size; ll_set->array_size += DLT_ENV_LL_SET_INCREASE; ll_set->item = (dlt_env_ll_item *)malloc(sizeof(dlt_env_ll_item) * ll_set->array_size); if (!ll_set->item) { /* should trigger a warning: no memory left */ ll_set->array_size -= DLT_ENV_LL_SET_INCREASE; return -1; } else { memcpy(ll_set->item, old_set, sizeof(dlt_env_ll_item) * old_size); free(old_set); return 0; } } /** * @brief extract all items out of string * * The given set is initialized within this function (memory is allocated). * Make sure, that the caller frees this memory when it is no longer needed! * * @return 0 if successful, -1 else */ int dlt_env_extract_ll_set(char **const env, dlt_env_ll_set *const ll_set) { if (!env || !ll_set) return -1; if (!(*env)) return -1; if (dlt_env_init_ll_set(ll_set) == -1) return -1; do { if (ll_set->num_elem == ll_set->array_size) { if (dlt_env_increase_ll_set(ll_set) == -1) return -1; } if (dlt_env_extract_ll_item(env, &ll_set->item[ll_set->num_elem++]) == -1) return -1; if (**env == ';') (*env)++; } while (**env != 0); return 0; } /** * @brief check if two ids match * * @return 1 if matching, 0 if not */ int dlt_env_ids_match(char const *const a, char const *const b) { if (a[0] != b[0]) return 0; if (a[1] != b[1]) return 0; if (a[2] != b[2]) return 0; if (a[3] != b[3]) return 0; return 1; } /** * @brief check if (and how) apid and ctid match with given item * * Resulting priorities: * - no apid, no ctid only ll given in item: use ll with prio 1 * - no apid, ctid matches: use ll with prio 2 * - no ctid, apid matches: use ll with prio 3 * - apid, ctid matches: use ll with prio 4 * * In case of error, -1 is returned. */ int dlt_env_ll_item_get_matching_prio(dlt_env_ll_item const *const item, char const *const apid, char const *const ctid) { if ((!item) || (!apid) || (!ctid)) return -1; if (item->appId[0] == 0) { if (item->ctxId[0] == 0) { return 1; } else if (dlt_env_ids_match(item->ctxId, ctid)) return 2; } else if (dlt_env_ids_match(item->appId, apid)) { if (item->ctxId[0] == 0) return 3; else if (dlt_env_ids_match(item->ctxId, ctid)) return 4; } return 0; } /** * @brief adjust log-level based on values given through environment * * Iterate over the set of items, and find the best match (\see ll_item_get_matching_prio) * For any item that matches, the one with the highest priority is selected and that * log-level is returned. * * If no item matches or in case of error, the original log-level (\param ll) is returned */ int dlt_env_adjust_ll_from_env(dlt_env_ll_set const *const ll_set, char const *const apid, char const *const ctid, int const ll) { if ((!ll_set) || (!apid) || (!ctid)) return ll; int res = ll; int prio = 0; /* no match so far */ size_t i; for (i = 0; i < ll_set->num_elem; ++i) { int p = dlt_env_ll_item_get_matching_prio(&ll_set->item[i], apid, ctid); if (p > prio) { prio = p; res = ll_set->item[i].ll; if (p == 4) /* maximum reached, immediate return */ return res; } } return res; } dlt-daemon-2.18.4/src/lib/dlt_filetransfer.c000066400000000000000000000613451353342203500206730ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2011-2015, BMW AG * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author Alexander Wenzel * * \copyright Copyright © 2011-2015 BMW AG. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file dlt_filetransfer.c */ /******************************************************************************* ** ** ** SRC-MODULE: dlt-test-client.c ** ** ** ** TARGET : linux ** ** ** ** PROJECT : DLT ** ** ** ** AUTHOR : Alexander Wenzel Alexander.AW.Wenzel@bmw.de ** ** ** ** PURPOSE : ** ** ** ** REMARKS : ** ** ** ** PLATFORM DEPENDANT [yes/no]: yes ** ** ** ** TO BE CHANGED BY USER [yes/no]: no ** ** ** *******************************************************************************/ /******************************************************************************* ** Author Identity ** ******************************************************************************** ** ** ** Initials Name Company ** ** -------- ------------------------- ---------------------------------- ** ** aw Alexander Wenzel BMW ** *******************************************************************************/ #include #include #include #include "dlt_filetransfer.h" #include "dlt_common.h" /*!Defines the buffer size of a single file package which will be logged to dlt */ #define BUFFER_SIZE 1024 /*!Defines the minimum timeout between two dlt logs. This is important because dlt should not be flooded with too many logs in a short period of time. */ #define MIN_TIMEOUT 20 #define DLT_FILETRANSFER_TRANSFER_ALL_PACKAGES INT_MAX #define NANOSEC_PER_MILLISEC 1000000 #define NANOSEC_PER_SEC 1000000000 /*!Buffer for dlt file transfer. The size is defined by BUFFER_SIZE */ unsigned char buffer[BUFFER_SIZE]; /*!Get some information about the file size of a file */ /**See stat(2) for more informations. * @param file Absolute file path * @param ok Result of stat * @return Returns the size of the file (if it is a regular file or a symbolic link) in bytes. */ uint32_t getFilesize(const char *file, int *ok) { struct stat st; if (-1 == stat(file, &st)) { /*we can only return 0, as the value is unsigned */ *ok = 0; return 0; } *ok = 1; return (uint32_t)st.st_size; } /** A simple Hash function for C-strings * @param str input string. E.g. a file path. * @param hash start and result value for hash computation * */ void stringHash(const char *str, uint32_t *hash) { if (!str || !hash) return; unsigned int len = strlen(str); unsigned int i = 0; if (len <= 0) return; for (i = 0; i < len; i++) *hash = 53 * *hash + str[i]; } /*!Get some information about the file serial number of a file */ /** See stat(2) for more informations. * @param file Absolute file path * @param ok *ok == 0 -> error; *ok == 1 -> ok * @return Returns a unique number associated with each filename */ uint32_t getFileSerialNumber(const char *file, int *ok) { struct stat st; uint32_t ret; if (-1 == stat(file, &st)) { *ok = 0; ret = 0; } else { *ok = 1; ret = st.st_ino; ret = ret << (sizeof(ret) * 8) / 2; ret |= st.st_size; ret ^= st.st_ctime; stringHash(file, &ret); } return ret; } /*!Returns the creation date of a file */ /** See stat(2) for more informations. * @param file Absolute file path * @param ok Result of stat * @return Returns the creation date of a file */ time_t getFileCreationDate(const char *file, int *ok) { struct stat st; if (-1 == stat(file, &st)) { *ok = 0; return 0; } *ok = 1; return st.st_ctime; } /*!Returns the creation date of a file */ /** Format of the creation date is Day Mon dd hh:mm:ss yyyy * @param file Absolute file path * @param ok Result of stat * @param date Local time * @return Returns the creation date of a file */ void getFileCreationDate2(const char *file, int *ok, char *date) { struct stat st; struct tm ts; if (-1 == stat(file, &st)) { *ok = 0; date = 0; } *ok = 1; localtime_r(&st.st_ctime, &ts); asctime_r(&ts, date); } /*!Checks if the file exists */ /**@param file Absolute file path * @return Returns 1 if the file exists, 0 if the file does not exist */ int isFile (const char *file) { struct stat st; return stat (file, &st) == 0; } /*!Waits a period of time */ /**Waits a period of time. The minimal time to wait is MIN_TIMEOUT. This makes sure that the FIFO of dlt is not flooded. * @param timeout Timeout to in ms but can not be smaller as MIN_TIMEOUT */ void doTimeout(int timeout) { struct timespec ts; ts.tv_sec = (timeout * NANOSEC_PER_MILLISEC) / NANOSEC_PER_SEC; ts.tv_nsec = (timeout * NANOSEC_PER_MILLISEC) % NANOSEC_PER_SEC; nanosleep(&ts, NULL); } /*!Checks free space of the user buffer */ /** * @return -1 if more than 50% space in the user buffer is free. Otherwise 1 will be returned. */ int checkUserBufferForFreeSpace() { int total_size, used_size; dlt_user_check_buffer(&total_size, &used_size); if ((total_size - used_size) < (total_size / 2)) return -1; return 1; } /*!Deletes the given file */ /** * @param filename Absolute file path * @return If the file is successfully deleted, a zero value is returned.If the file can not be deleted a nonzero value is returned. */ int doRemoveFile(const char *filename) { return remove(filename); } void dlt_user_log_file_errorMessage(DltContext *fileContext, const char *filename, int errorCode) { if (errno != ENOENT) { int ok = 0; uint32_t fserial = getFileSerialNumber(filename, &ok); if (!ok) DLT_LOG(*fileContext, DLT_LOG_ERROR, DLT_STRING("dlt_user_log_file_errorMessage, error in getFileSerialNumber for: "), DLT_STRING(filename)); uint32_t fsize = getFilesize(filename, &ok); if (!ok) DLT_LOG(*fileContext, DLT_LOG_ERROR, DLT_STRING("dlt_user_log_file_errorMessage, error in getFilesize for: "), DLT_STRING(filename)); char fcreationdate[50]; getFileCreationDate2(filename, &ok, fcreationdate); if (!ok) DLT_LOG(*fileContext, DLT_LOG_ERROR, DLT_STRING("dlt_user_log_file_errorMessage, error in getFilesize for: "), DLT_STRING(filename)); int package_count = dlt_user_log_file_packagesCount(fileContext, filename); DLT_LOG(*fileContext, DLT_LOG_ERROR, DLT_STRING("FLER"), DLT_INT(errorCode), DLT_INT(-errno), DLT_UINT(fserial), DLT_STRING(filename), DLT_UINT(fsize), DLT_STRING(fcreationdate), DLT_INT(package_count), DLT_UINT(BUFFER_SIZE), DLT_STRING("FLER") ); } else { DLT_LOG(*fileContext, DLT_LOG_ERROR, DLT_STRING("FLER"), DLT_INT(errorCode), DLT_INT(-errno), DLT_STRING(filename), DLT_STRING("FLER") ); } } /*!Logs specific file inforamtions to dlt */ /**The filename, file size, file serial number and the number of packages will be logged to dlt. * @param fileContext Specific context * @param filename Absolute file path * @return Returns 0 if everything was okey.If there was a failure a value < 0 will be returned. */ int dlt_user_log_file_infoAbout(DltContext *fileContext, const char *filename) { if (isFile(filename)) { int ok; uint32_t fsize = getFilesize(filename, &ok); if (!ok) DLT_LOG(*fileContext, DLT_LOG_ERROR, DLT_STRING("dlt_user_log_file_infoAbout, Error getting size of file:"), DLT_STRING(filename)); uint32_t fserialnumber = getFileSerialNumber(filename, &ok); if (!ok) DLT_LOG(*fileContext, DLT_LOG_ERROR, DLT_STRING("dlt_user_log_file_infoAbout, Error getting serial number of file:"), DLT_STRING(filename)); char creationdate[50]; getFileCreationDate2(filename, &ok, creationdate); if (!ok) DLT_LOG(*fileContext, DLT_LOG_ERROR, DLT_STRING("dlt_user_log_file_infoAbout, Error getting creation date of file:"), DLT_STRING(filename)); DLT_LOG(*fileContext, DLT_LOG_INFO, DLT_STRING("FLIF"), DLT_STRING("file serialnumber"), DLT_UINT(fserialnumber), DLT_STRING("filename"), DLT_STRING(filename), DLT_STRING("file size in bytes"), DLT_UINT(fsize), DLT_STRING("file creation date"), DLT_STRING(creationdate), DLT_STRING("number of packages"), DLT_UINT(dlt_user_log_file_packagesCount(fileContext, filename)), DLT_STRING("FLIF") ); return 0; } else { dlt_user_log_file_errorMessage(fileContext, filename, DLT_FILETRANSFER_ERROR_INFO_ABOUT); return DLT_FILETRANSFER_ERROR_INFO_ABOUT; } } /*!Transfer the complete file as several dlt logs. */ /**This method transfer the complete file as several dlt logs. At first it will be checked that the file exist. * In the next step some generic informations about the file will be logged to dlt. * Now the header will be logged to dlt. See the method dlt_user_log_file_header for more informations. * Then the method dlt_user_log_data will be called with the parameter to log all packages in a loop with some timeout. * At last dlt_user_log_end is called to signal that the complete file transfer was okey. This is important for the plugin of the dlt viewer. * @param fileContext Specific context to log the file to dlt * @param filename Absolute file path * @param deleteFlag Flag if the file will be deleted after transfer. 1->delete, 0->notDelete * @param timeout Timeout in ms to wait between some logs. Important that the FIFO of dlt will not be flooded with to many messages in a short period of time. * @return Returns 0 if everything was okey. If there was a failure a value < 0 will be returned. */ int dlt_user_log_file_complete(DltContext *fileContext, const char *filename, int deleteFlag, int timeout) { if (!isFile(filename)) { dlt_user_log_file_errorMessage(fileContext, filename, DLT_FILETRANSFER_ERROR_FILE_COMPLETE); return DLT_FILETRANSFER_ERROR_FILE_COMPLETE; } if (dlt_user_log_file_header(fileContext, filename) != 0) return DLT_FILETRANSFER_ERROR_FILE_COMPLETE1; if (dlt_user_log_file_data(fileContext, filename, DLT_FILETRANSFER_TRANSFER_ALL_PACKAGES, timeout) != 0) return DLT_FILETRANSFER_ERROR_FILE_COMPLETE2; if (dlt_user_log_file_end(fileContext, filename, deleteFlag) != 0) return DLT_FILETRANSFER_ERROR_FILE_COMPLETE3; return 0; } /*!This method gives information about the number of packages the file have */ /**Every file will be divided into several packages. Every package will be logged as a single dlt log. * The number of packages depends on the BUFFER_SIZE. * At first it will be checked if the file exist. Then the file will be divided into * several packages depending on the buffer size. * @param fileContext Specific context to log the file to dlt * @param filename Absolute file path * @return Returns the number of packages if everything was okey. If there was a failure a value < 0 will be returned. */ int dlt_user_log_file_packagesCount(DltContext *fileContext, const char *filename) { int packages; uint32_t filesize; if (isFile(filename)) { packages = 1; int ok; filesize = getFilesize(filename, &ok); if (!ok) { DLT_LOG(*fileContext, DLT_LOG_ERROR, DLT_STRING("Error in: dlt_user_log_file_packagesCount, isFile"), DLT_STRING(filename), DLT_INT(DLT_FILETRANSFER_ERROR_PACKAGE_COUNT)); return -1; } if (filesize < BUFFER_SIZE) { return packages; } else { packages = filesize / BUFFER_SIZE; if (filesize % BUFFER_SIZE == 0) return packages; else return packages + 1; } } else { DLT_LOG(*fileContext, DLT_LOG_ERROR, DLT_STRING("Error in: dlt_user_log_file_packagesCount, !isFile"), DLT_STRING(filename), DLT_INT(DLT_FILETRANSFER_ERROR_PACKAGE_COUNT)); return -1; } } /*!Transfer the head of the file as a dlt logs. */ /**The head of the file must be logged to dlt because the head contains inforamtion about the file serial number, * the file name, the file size, package number the file have and the buffer size. * All these informations are needed from the plugin of the dlt viewer. * See the Mainpages.c for more informations. * @param fileContext Specific context to log the file to dlt * @param filename Absolute file path * @param alias Alias for the file. An alternative name to show in the receiving end * @return Returns 0 if everything was okey. If there was a failure a value < 0 will be returned. */ int dlt_user_log_file_header_alias(DltContext *fileContext, const char *filename, const char *alias) { if (isFile(filename)) { int ok; uint32_t fserialnumber = getFileSerialNumber(filename, &ok); if (!ok) DLT_LOG(*fileContext, DLT_LOG_ERROR, DLT_STRING("dlt_user_log_file_header_alias, Error getting serial number of file:"), DLT_STRING(filename)); uint32_t fsize = getFilesize(filename, &ok); if (!ok) DLT_LOG(*fileContext, DLT_LOG_ERROR, DLT_STRING("dlt_user_log_file_header_alias, Error getting size of file:"), DLT_STRING(filename)); char fcreationdate[50]; getFileCreationDate2(filename, &ok, fcreationdate); if (!ok) DLT_LOG(*fileContext, DLT_LOG_ERROR, DLT_STRING("dlt_user_log_file_header_alias, Error getting creation date of file:"), DLT_STRING(filename)); DLT_LOG(*fileContext, DLT_LOG_INFO, DLT_STRING("FLST"), DLT_UINT(fserialnumber), DLT_STRING(alias), DLT_UINT(fsize), DLT_STRING(fcreationdate); DLT_UINT(dlt_user_log_file_packagesCount(fileContext, filename)), DLT_UINT(BUFFER_SIZE), DLT_STRING("FLST") ); return 0; } else { dlt_user_log_file_errorMessage(fileContext, filename, DLT_FILETRANSFER_ERROR_FILE_HEAD); return DLT_FILETRANSFER_ERROR_FILE_HEAD; } } /*!Transfer the head of the file as a dlt logs. */ /**The head of the file must be logged to dlt because the head contains inforamtion about the file serial number, * the file name, the file size, package number the file have and the buffer size. * All these informations are needed from the plugin of the dlt viewer. * See the Mainpages.c for more informations. * @param fileContext Specific context to log the file to dlt * @param filename Absolute file path * @return Returns 0 if everything was okey. If there was a failure a value < 0 will be returned. */ int dlt_user_log_file_header(DltContext *fileContext, const char *filename) { if (isFile(filename)) { int ok; uint32_t fserialnumber = getFileSerialNumber(filename, &ok); if (!ok) DLT_LOG(*fileContext, DLT_LOG_ERROR, DLT_STRING("dlt_user_log_file_header, Error getting serial number of file:"), DLT_STRING(filename)); uint32_t fsize = getFilesize(filename, &ok); if (!ok) DLT_LOG(*fileContext, DLT_LOG_ERROR, DLT_STRING("dlt_user_log_file_header, Error getting size of file:"), DLT_STRING(filename)); char fcreationdate[50]; getFileCreationDate2(filename, &ok, fcreationdate); if (!ok) DLT_LOG(*fileContext, DLT_LOG_ERROR, DLT_STRING("dlt_user_log_file_header, Error getting creation date of file:"), DLT_STRING(filename)); DLT_LOG(*fileContext, DLT_LOG_INFO, DLT_STRING("FLST"), DLT_UINT(fserialnumber), DLT_STRING(filename), DLT_UINT(fsize), DLT_STRING(fcreationdate); DLT_UINT(dlt_user_log_file_packagesCount(fileContext, filename)), DLT_UINT(BUFFER_SIZE), DLT_STRING("FLST") ); return 0; } else { dlt_user_log_file_errorMessage(fileContext, filename, DLT_FILETRANSFER_ERROR_FILE_HEAD); return DLT_FILETRANSFER_ERROR_FILE_HEAD; } } /*!Transfer the content data of a file. */ /**See the Mainpages.c for more informations. * @param fileContext Specific context to log the file to dlt * @param filename Absolute file path * @param packageToTransfer Package number to transfer. If this param is LONG_MAX, the whole file will be transferred with a specific timeout * @param timeout Timeout to wait between dlt logs. Important because the dlt FIFO should not be flooded. Default is defined by MIN_TIMEOUT. The given timeout in ms can not be smaller than MIN_TIMEOUT. * @return Returns 0 if everything was okey. If there was a failure a value < 0 will be returned. */ int dlt_user_log_file_data(DltContext *fileContext, const char *filename, int packageToTransfer, int timeout) { FILE *file; int pkgNumber; uint32_t readBytes; if (isFile(filename)) { file = fopen (filename, "rb"); if (file == NULL) { dlt_user_log_file_errorMessage(fileContext, filename, DLT_FILETRANSFER_ERROR_FILE_DATA); return DLT_FILETRANSFER_ERROR_FILE_DATA; } if (((packageToTransfer != DLT_FILETRANSFER_TRANSFER_ALL_PACKAGES) && (packageToTransfer > dlt_user_log_file_packagesCount(fileContext, filename))) || (packageToTransfer <= 0)) { DLT_LOG(*fileContext, DLT_LOG_ERROR, DLT_STRING("Error at dlt_user_log_file_data: packageToTransfer out of scope"), DLT_STRING("packageToTransfer:"), DLT_UINT(packageToTransfer), DLT_STRING("numberOfMaximalPackages:"), DLT_UINT(dlt_user_log_file_packagesCount(fileContext, filename)), DLT_STRING("for File:"), DLT_STRING(filename) ); fclose(file); return DLT_FILETRANSFER_ERROR_FILE_DATA; } readBytes = 0; if (packageToTransfer != DLT_FILETRANSFER_TRANSFER_ALL_PACKAGES) { /* If a single package should be transferred. The user has to check that the free space in the user buffer > 50% */ /* if(checkUserBufferForFreeSpace()<0) */ /* return DLT_FILETRANSFER_ERROR_FILE_DATA_USER_BUFFER_FAILED; */ if (0 != fseek (file, (packageToTransfer - 1) * BUFFER_SIZE, SEEK_SET)) { DLT_LOG(*fileContext, DLT_LOG_ERROR, DLT_STRING("failed to fseek in file: "), DLT_STRING(filename), DLT_STRING("ferror:"), DLT_INT(ferror(file)) ); fclose (file); return -1; } readBytes = fread(buffer, sizeof(char), BUFFER_SIZE, file); int ok; uint32_t fserial = getFileSerialNumber(filename, &ok); if (1 != ok) DLT_LOG(*fileContext, DLT_LOG_ERROR, DLT_STRING("failed to get FileSerialNumber for: "), DLT_STRING(filename)); DLT_LOG(*fileContext, DLT_LOG_INFO, DLT_STRING("FLDA"), DLT_UINT(fserial), DLT_UINT(packageToTransfer), DLT_RAW(buffer, readBytes), DLT_STRING("FLDA") ); doTimeout(timeout); } else { pkgNumber = 0; while (!feof(file)) { /* If the complete file should be transferred, the user buffer will be checked. */ /* If free space < 50% the package won't be transferred. */ if (checkUserBufferForFreeSpace() > 0) { pkgNumber++; readBytes = fread(buffer, sizeof(char), BUFFER_SIZE, file); int ok; uint32_t fserial = getFileSerialNumber(filename, &ok); if (1 != ok) DLT_LOG(*fileContext, DLT_LOG_ERROR, DLT_STRING("failed to get FileSerialNumber for: "), DLT_STRING(filename)); DLT_LOG(*fileContext, DLT_LOG_INFO, DLT_STRING("FLDA"), DLT_UINT(fserial), DLT_UINT(pkgNumber), DLT_RAW(buffer, readBytes), DLT_STRING("FLDA") ); } doTimeout(timeout); } } fclose(file); return 0; } else { dlt_user_log_file_errorMessage(fileContext, filename, DLT_FILETRANSFER_ERROR_FILE_DATA); return DLT_FILETRANSFER_ERROR_FILE_DATA; } } /*!Transfer the end of the file as a dlt logs. */ /**The end of the file must be logged to dlt because the end contains inforamtion about the file serial number. * This informations is needed from the plugin of the dlt viewer. * See the Mainpages.c for more informations. * @param fileContext Specific context to log the file to dlt * @param filename Absolute file path * @param deleteFlag Flag to delete the file after the whole file is transferred (logged to dlt).1->delete,0->NotDelete * @return Returns 0 if everything was okey. If there was a failure a value < 0 will be returned. */ int dlt_user_log_file_end(DltContext *fileContext, const char *filename, int deleteFlag) { if (isFile(filename)) { int ok; uint32_t fserial = getFileSerialNumber(filename, &ok); if (1 != ok) DLT_LOG(*fileContext, DLT_LOG_ERROR, DLT_STRING("failed to get FileSerialNumber for: "), DLT_STRING(filename)); DLT_LOG(*fileContext, DLT_LOG_INFO, DLT_STRING("FLFI"), DLT_UINT(fserial), DLT_STRING("FLFI") ); if (deleteFlag) { if (doRemoveFile(filename) != 0) { dlt_user_log_file_errorMessage(fileContext, filename, DLT_FILETRANSFER_ERROR_FILE_END); return -1; } } return 0; } else { dlt_user_log_file_errorMessage(fileContext, filename, DLT_FILETRANSFER_ERROR_FILE_END); return DLT_FILETRANSFER_ERROR_FILE_END; } } dlt-daemon-2.18.4/src/lib/dlt_user.c000066400000000000000000004643321353342203500171700ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2011-2015, BMW AG * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author * Alexander Wenzel * Markus Klein * Mikko Rapeli * * \copyright Copyright © 2011-2015 BMW AG. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file dlt_user.c */ #include /* for getenv(), free(), atexit() */ #include /* for strcmp(), strncmp(), strlen(), memset(), memcpy() */ #include /* for signal(), SIGPIPE, SIG_IGN */ #if !defined (__WIN32__) # include /* for LOG_... */ # include # include /* POSIX Threads */ #endif #include #include #include #include #include #include /* writev() */ #include #ifdef linux # include #endif #include /* needed for getpid() */ #include #include #ifdef DLT_USE_UNIX_SOCKET_IPC # include # include #endif #include "dlt_user.h" #include "dlt_common.h" #include "dlt_user_shared.h" #include "dlt_user_shared_cfg.h" #include "dlt_user_cfg.h" #ifdef DLT_FATAL_LOG_RESET_ENABLE # define DLT_LOG_FATAL_RESET_TRAP(LOGLEVEL) \ do { \ if (LOGLEVEL == DLT_LOG_FATAL) { \ int *p = NULL; \ *p = 0; \ } \ } while (0) #else /* DLT_FATAL_LOG_RESET_ENABLE */ # define DLT_LOG_FATAL_RESET_TRAP(LOGLEVEL) #endif /* DLT_FATAL_LOG_RESET_ENABLE */ static DltUser dlt_user; static bool dlt_user_initialised = false; static int dlt_user_freeing = 0; #ifndef DLT_USE_UNIX_SOCKET_IPC static char dlt_user_dir[DLT_PATH_MAX]; static char dlt_daemon_fifo[DLT_PATH_MAX]; #endif static sem_t dlt_mutex; static pthread_t dlt_receiverthread_handle; /* calling dlt_user_atexit_handler() second time fails with error message */ static int atexit_registered = 0; /* used to disallow DLT usage in fork() child */ static int g_dlt_is_child = 0; /* String truncate message */ static const char *STR_TRUNCATED_MESSAGE = "... <>"; /* Enum for type of string */ enum StringType { ASCII_STRING = 0, UTF8_STRING = 1 }; /*Max DLT message size is 1390 bytes plus some extra header space to accomidate the resend buffer*/ #define DLT_USER_EXTRA_BUFF_SIZE 100 /* Segmented Network Trace */ #define DLT_MAX_TRACE_SEGMENT_SIZE 1024 #define DLT_MESSAGE_QUEUE_NAME "/dlt_message_queue" #define DLT_DELAYED_RESEND_INDICATOR_PATTERN 0xFFFF #define DLT_UNUSED(x) (void)(x) /* Mutex to wait on while message queue is not initialized */ pthread_mutex_t mq_mutex = PTHREAD_MUTEX_INITIALIZER; pthread_cond_t mq_init_condition; void dlt_lock_mutex(pthread_mutex_t *mutex) { int32_t lock_mutex_result = pthread_mutex_lock(mutex); if (lock_mutex_result != 0) dlt_vlog(LOG_ERR, "Mutex lock failed unexpected pid=%i with result %i!\n", getpid(), lock_mutex_result); } void dlt_unlock_mutex(pthread_mutex_t *mutex) { pthread_mutex_unlock(mutex); } /* Structure to pass data to segmented thread */ typedef struct { DltContext *handle; uint32_t id; DltNetworkTraceType nw_trace_type; uint32_t header_len; void *header; uint32_t payload_len; void *payload; } s_segmented_data; /* Function prototypes for internally used functions */ static void dlt_user_receiverthread_function(void *ptr); static void dlt_user_atexit_handler(void); static DltReturnValue dlt_user_log_init(DltContext *handle, DltContextData *log); static DltReturnValue dlt_user_log_send_log(DltContextData *log, int mtype); static DltReturnValue dlt_user_log_send_register_application(void); static DltReturnValue dlt_user_log_send_unregister_application(void); static DltReturnValue dlt_user_log_send_register_context(DltContextData *log); static DltReturnValue dlt_user_log_send_unregister_context(DltContextData *log); static DltReturnValue dlt_send_app_ll_ts_limit(const char *apid, DltLogLevelType loglevel, DltTraceStatusType tracestatus); static DltReturnValue dlt_user_log_send_log_mode(DltUserLogMode mode); static DltReturnValue dlt_user_log_send_marker(); static DltReturnValue dlt_user_print_msg(DltMessage *msg, DltContextData *log); static DltReturnValue dlt_user_log_check_user_message(void); static void dlt_user_log_reattach_to_daemon(void); static DltReturnValue dlt_user_log_send_overflow(void); static void dlt_user_trace_network_segmented_thread(void *unused); static void dlt_user_trace_network_segmented_thread_segmenter(s_segmented_data *data); static DltReturnValue dlt_user_queue_resend(void); static DltReturnValue dlt_user_log_out_error_handling(void *ptr1, size_t len1, void *ptr2, size_t len2, void *ptr3, size_t len3); static void dlt_user_cleanup_handler(void *arg); static int dlt_start_threads(); static void dlt_stop_threads(); static void dlt_fork_child_fork_handler(); static DltReturnValue dlt_user_log_write_string_utils(DltContextData *log, const char *text, const enum StringType type); DltReturnValue dlt_user_check_library_version(const char *user_major_version, const char *user_minor_version) { char lib_major_version[DLT_USER_MAX_LIB_VERSION_LENGTH]; char lib_minor_version[DLT_USER_MAX_LIB_VERSION_LENGTH]; dlt_get_major_version(lib_major_version, DLT_USER_MAX_LIB_VERSION_LENGTH); dlt_get_minor_version(lib_minor_version, DLT_USER_MAX_LIB_VERSION_LENGTH); if ((strcmp(lib_major_version, user_major_version) != 0) || (strcmp(lib_minor_version, user_minor_version) != 0)) { dlt_vnlog(LOG_WARNING, DLT_USER_BUFFER_LENGTH, "DLT Library version check failed! Installed DLT library version is %s.%s - Application using DLT library version %s.%s\n", lib_major_version, lib_minor_version, user_major_version, user_minor_version); return DLT_RETURN_ERROR; } return DLT_RETURN_OK; } #ifdef DLT_USE_UNIX_SOCKET_IPC static DltReturnValue dlt_initialize_socket_connection(void) { struct sockaddr_un remote; int status = 0; char dltSockBaseDir[DLT_IPC_PATH_MAX]; struct linger l_opt; DLT_SEM_LOCK(); int sockfd = socket(AF_UNIX, SOCK_STREAM, 0); if (sockfd == DLT_FD_INIT) { dlt_log(LOG_CRIT, "Failed to create socket\n"); DLT_SEM_FREE(); return DLT_RETURN_ERROR; } status = fcntl(sockfd, F_SETFL, fcntl(sockfd, F_GETFL, 0) | O_NONBLOCK); if (status == -1) { dlt_vlog(LOG_INFO, "Socket %s/dlt cannot be changed to NON BLOCK\n", DLT_USER_IPC_PATH); return DLT_RETURN_ERROR; } /* Set SO_LINGER opt for the new client socket. */ l_opt.l_onoff = 1; l_opt.l_linger = 10; if (setsockopt(sockfd, SOL_SOCKET, SO_LINGER, &l_opt, sizeof l_opt) < 0) dlt_log(LOG_WARNING, "Failed to set linger option\n"); remote.sun_family = AF_UNIX; snprintf(dltSockBaseDir, DLT_IPC_PATH_MAX, "%s/dlt", DLT_USER_IPC_PATH); strncpy(remote.sun_path, dltSockBaseDir, sizeof(remote.sun_path)); if (strlen(DLT_USER_IPC_PATH) > DLT_IPC_PATH_MAX) dlt_vlog(LOG_INFO, "Provided path too long...trimming it to path[%s]\n", dltSockBaseDir); if (connect(sockfd, (struct sockaddr *)&remote, sizeof(remote)) == -1) { if (dlt_user.connection_state != DLT_USER_RETRY_CONNECT) { dlt_vlog(LOG_INFO, "Socket %s cannot be opened. Retrying later...\n", dltSockBaseDir); dlt_user.connection_state = DLT_USER_RETRY_CONNECT; } close(sockfd); } else { dlt_user.dlt_log_handle = sockfd; dlt_user.connection_state = DLT_USER_CONNECTED; if (dlt_receiver_init(&(dlt_user.receiver), sockfd, DLT_USER_RCVBUF_MAX_SIZE) == DLT_RETURN_ERROR) { dlt_user_initialised = false; DLT_SEM_FREE(); return DLT_RETURN_ERROR; } } DLT_SEM_FREE(); return DLT_RETURN_OK; } #else /* setup fifo*/ static DltReturnValue dlt_initialize_fifo_connection(void) { char filename[DLT_PATH_MAX]; int ret; snprintf(dlt_user_dir, DLT_PATH_MAX, "%s/dltpipes", dltFifoBaseDir); snprintf(dlt_daemon_fifo, DLT_PATH_MAX, "%s/dlt", dltFifoBaseDir); ret = mkdir(dlt_user_dir, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH | S_ISVTX); if ((ret == -1) && (errno != EEXIST)) { dlt_vnlog(LOG_ERR, DLT_USER_BUFFER_LENGTH, "FIFO user dir %s cannot be created!\n", dlt_user_dir); return DLT_RETURN_ERROR; } /* if dlt pipes directory is created by the application also chmod the directory */ if (ret == 0) { /* S_ISGID cannot be set by mkdir, let's reassign right bits */ ret = chmod(dlt_user_dir, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IXGRP | S_IROTH | S_IWOTH | S_IXOTH | S_ISGID | S_ISVTX); if (ret == -1) { dlt_vnlog(LOG_ERR, DLT_USER_BUFFER_LENGTH, "FIFO user dir %s cannot be chmoded!\n", dlt_user_dir); return DLT_RETURN_ERROR; } } /* create and open DLT user FIFO */ snprintf(filename, DLT_PATH_MAX, "%s/dlt%d", dlt_user_dir, getpid()); /* Try to delete existing pipe, ignore result of unlink */ unlink(filename); ret = mkfifo(filename, S_IRUSR | S_IWUSR | S_IWGRP | S_IRGRP); if (ret == -1) dlt_vnlog(LOG_WARNING, DLT_USER_BUFFER_LENGTH, "Loging disabled, FIFO user %s cannot be created!\n", filename); /* S_IWGRP cannot be set by mkfifo (???), let's reassign right bits */ ret = chmod(filename, S_IRUSR | S_IWUSR | S_IWGRP | S_IRGRP); if (ret == -1) { dlt_vnlog(LOG_WARNING, DLT_USER_BUFFER_LENGTH, "FIFO user %s cannot be chmoded!\n", dlt_user_dir); return DLT_RETURN_ERROR; } dlt_user.dlt_user_handle = open(filename, O_RDWR | O_CLOEXEC); if (dlt_user.dlt_user_handle == DLT_FD_INIT) { dlt_vnlog(LOG_WARNING, DLT_USER_BUFFER_LENGTH, "Logging disabled, FIFO user %s cannot be opened!\n", filename); unlink(filename); return DLT_RETURN_OK; } /* open DLT output FIFO */ dlt_user.dlt_log_handle = open(dlt_daemon_fifo, O_WRONLY | O_NONBLOCK | O_CLOEXEC); if (dlt_user.dlt_log_handle == -1) /* This is a normal usecase. It is OK that the daemon (and thus the FIFO /tmp/dlt) * starts later and some DLT users have already been started before. * Thus it is OK if the FIFO can't be opened. */ dlt_vnlog(LOG_INFO, DLT_USER_BUFFER_LENGTH, "FIFO %s cannot be opened. Retrying later...\n", dlt_daemon_fifo); return DLT_RETURN_OK; } #endif DltReturnValue dlt_init(void) { /* process is exiting. Do not allocate new resources. */ if (dlt_user_freeing != 0) { dlt_vlog(LOG_INFO, "%s logging disabled, process is exiting", __func__); /* return negative value, to stop the current log */ return DLT_RETURN_LOGGING_DISABLED; } /* WARNING: multithread unsafe ! */ /* Another thread will check that dlt_user_initialised != 0, but the lib is not initialised ! */ dlt_user_initialised = true; /* Initialize common part of dlt_init()/dlt_init_file() */ if (dlt_init_common() == DLT_RETURN_ERROR) { dlt_user_initialised = false; return DLT_RETURN_ERROR; } strncpy(dltFifoBaseDir, DLT_USER_IPC_PATH, DLT_PATH_MAX); dltFifoBaseDir[DLT_PATH_MAX - 1] = 0; /* check environment variables */ dlt_check_envvar(); dlt_user.dlt_is_file = 0; dlt_user.overflow = 0; dlt_user.overflow_counter = 0; #ifdef DLT_SHM_ENABLE memset(&(dlt_user.dlt_shm), 0, sizeof(DltShm)); /* init shared memory */ if (dlt_shm_init_client(&(dlt_user.dlt_shm), dltShmName) < DLT_RETURN_OK) dlt_vnlog(LOG_WARNING, DLT_USER_BUFFER_LENGTH, "Logging disabled," " Shared memory %s cannot be created!\n", dltShmName); #endif #ifdef DLT_USE_UNIX_SOCKET_IPC if (dlt_initialize_socket_connection() != DLT_RETURN_OK) /* We could connect to the pipe, but not to the socket, which is normally */ /* open before by the DLT daemon => bad failure => return error code */ /* in case application is started before daemon, it is expected behaviour */ return DLT_RETURN_ERROR; #else /* FIFO connection */ if (dlt_initialize_fifo_connection() != DLT_RETURN_OK) return DLT_RETURN_ERROR; if (dlt_receiver_init(&(dlt_user.receiver), dlt_user.dlt_user_handle, DLT_USER_RCVBUF_MAX_SIZE) == DLT_RETURN_ERROR) { dlt_user_initialised = false; return DLT_RETURN_ERROR; } #endif /* These will be lazy initialized only when needed */ dlt_user.dlt_segmented_queue_read_handle = -1; dlt_user.dlt_segmented_queue_write_handle = -1; pthread_cond_init(&mq_init_condition, NULL); if (dlt_start_threads() < 0) { dlt_user_initialised = false; return DLT_RETURN_ERROR; } /* prepare for fork() call */ pthread_atfork(NULL, NULL, &dlt_fork_child_fork_handler); return DLT_RETURN_OK; } DltReturnValue dlt_init_file(const char *name) { /* check null pointer */ if (!name) return DLT_RETURN_WRONG_PARAMETER; dlt_user_initialised = true; /* Initialize common part of dlt_init()/dlt_init_file() */ if (dlt_init_common() == DLT_RETURN_ERROR) { dlt_user_initialised = false; return DLT_RETURN_ERROR; } dlt_user.dlt_is_file = 1; /* open DLT output file */ dlt_user.dlt_log_handle = open(name, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); /* mode: wb */ if (dlt_user.dlt_log_handle == -1) { dlt_vnlog(LOG_ERR, DLT_USER_BUFFER_LENGTH, "Log file %s cannot be opened!\n", name); return DLT_RETURN_ERROR; } return DLT_RETURN_OK; } DltReturnValue dlt_init_message_queue(void) { dlt_lock_mutex(&mq_mutex); if ((dlt_user.dlt_segmented_queue_read_handle >= 0) && (dlt_user.dlt_segmented_queue_write_handle >= 0)) { /* Already intialized */ dlt_unlock_mutex(&mq_mutex); return DLT_RETURN_OK; } /* Generate per process name for queue */ char queue_name[NAME_MAX]; snprintf(queue_name, NAME_MAX, "%s.%d", DLT_MESSAGE_QUEUE_NAME, getpid()); /* Maximum queue size is 10, limit to size of pointers */ struct mq_attr mqatr; mqatr.mq_flags = 0; mqatr.mq_maxmsg = 10; mqatr.mq_msgsize = sizeof(s_segmented_data *); mqatr.mq_curmsgs = 0; /** * Create the message queue. It must be newly created * if old one was left by a crashing process. * */ dlt_user.dlt_segmented_queue_read_handle = mq_open(queue_name, O_CREAT | O_RDONLY | O_EXCL, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH, &mqatr); if (dlt_user.dlt_segmented_queue_read_handle < 0) { if (errno == EEXIST) { dlt_log(LOG_WARNING, "Old message queue exists, trying to delete.\n"); if (mq_unlink(queue_name) < 0) dlt_vnlog(LOG_CRIT, 256, "Could not delete existing message queue!: %s \n", strerror(errno)); else /* Retry */ dlt_user.dlt_segmented_queue_read_handle = mq_open(queue_name, O_CREAT | O_RDONLY | O_EXCL, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH, &mqatr); } if (dlt_user.dlt_segmented_queue_read_handle < 0) { dlt_vnlog(LOG_CRIT, 256, "Can't create message queue read handle!: %s \n", strerror(errno)); dlt_unlock_mutex(&mq_mutex); return DLT_RETURN_ERROR; } } dlt_user.dlt_segmented_queue_write_handle = mq_open(queue_name, O_WRONLY | O_NONBLOCK); if (dlt_user.dlt_segmented_queue_write_handle < 0) { dlt_vnlog(LOG_CRIT, 256, "Can't open message queue write handle!: %s \n", strerror(errno)); dlt_unlock_mutex(&mq_mutex); return DLT_RETURN_ERROR; } pthread_cond_signal(&mq_init_condition); dlt_unlock_mutex(&mq_mutex); return DLT_RETURN_OK; } DltReturnValue dlt_init_common(void) { char *env_local_print; char *env_initial_log_level; char *env_buffer_min; uint32_t buffer_min = DLT_USER_RINGBUFFER_MIN_SIZE; char *env_buffer_max; uint32_t buffer_max = DLT_USER_RINGBUFFER_MAX_SIZE; char *env_buffer_step; uint32_t buffer_step = DLT_USER_RINGBUFFER_STEP_SIZE; char *env_log_buffer_len; uint32_t buffer_max_configured = 0; /* Binary semaphore for threads */ if (sem_init(&dlt_mutex, 0, 1) == -1) { dlt_user_initialised = false; return DLT_RETURN_ERROR; } /* set to unknown state of connected client */ dlt_user.log_state = -1; dlt_user.dlt_log_handle = -1; dlt_user.dlt_user_handle = DLT_FD_INIT; dlt_set_id(dlt_user.ecuID, DLT_USER_DEFAULT_ECU_ID); dlt_set_id(dlt_user.appID, ""); dlt_user.application_description = NULL; /* Verbose mode is enabled by default */ dlt_user.verbose_mode = 1; /* Use extended header for non verbose is enabled by default */ dlt_user.use_extende_header_for_non_verbose = DLT_USER_USE_EXTENDED_HEADER_FOR_NONVERBOSE; /* WIth session id is enabled by default */ dlt_user.with_session_id = DLT_USER_WITH_SESSION_ID; /* With timestamp is enabled by default */ dlt_user.with_timestamp = DLT_USER_WITH_TIMESTAMP; /* With timestamp is enabled by default */ dlt_user.with_ecu_id = DLT_USER_WITH_ECU_ID; /* Local print is disabled by default */ dlt_user.enable_local_print = 0; dlt_user.local_print_mode = DLT_PM_UNSET; dlt_user.timeout_at_exit_handler = DLT_USER_ATEXIT_RESEND_BUFFER_EXIT_TIMEOUT; env_local_print = getenv(DLT_USER_ENV_LOCAL_PRINT_MODE); if (env_local_print) { if (strcmp(env_local_print, "AUTOMATIC") == 0) dlt_user.local_print_mode = DLT_PM_AUTOMATIC; else if (strcmp(env_local_print, "FORCE_ON") == 0) dlt_user.local_print_mode = DLT_PM_FORCE_ON; else if (strcmp(env_local_print, "FORCE_OFF") == 0) dlt_user.local_print_mode = DLT_PM_FORCE_OFF; } env_initial_log_level = getenv("DLT_INITIAL_LOG_LEVEL"); if (env_initial_log_level != NULL) { if (dlt_env_extract_ll_set(&env_initial_log_level, &dlt_user.initial_ll_set) != 0) dlt_vlog(LOG_WARNING, "Unable to parse initial set of log-levels from environment! Env:\n%s\n", getenv("DLT_INITIAL_LOG_LEVEL")); } /* Initialize LogLevel/TraceStatus field */ DLT_SEM_LOCK(); dlt_user.dlt_ll_ts = NULL; dlt_user.dlt_ll_ts_max_num_entries = 0; dlt_user.dlt_ll_ts_num_entries = 0; env_buffer_min = getenv(DLT_USER_ENV_BUFFER_MIN_SIZE); env_buffer_max = getenv(DLT_USER_ENV_BUFFER_MAX_SIZE); env_buffer_step = getenv(DLT_USER_ENV_BUFFER_STEP_SIZE); if (env_buffer_min != NULL) { buffer_min = (uint32_t)strtol(env_buffer_min, NULL, 10); if ((errno == EINVAL) || (errno == ERANGE)) { dlt_vlog(LOG_ERR, "Wrong value specified for %s. Using default\n", DLT_USER_ENV_BUFFER_MIN_SIZE); buffer_min = DLT_USER_RINGBUFFER_MIN_SIZE; } } if (env_buffer_max != NULL) { buffer_max = (uint32_t)strtol(env_buffer_max, NULL, 10); if ((errno == EINVAL) || (errno == ERANGE)) { dlt_vlog(LOG_ERR, "Wrong value specified for %s. Using default\n", DLT_USER_ENV_BUFFER_MAX_SIZE); buffer_max = DLT_USER_RINGBUFFER_MAX_SIZE; } } if (env_buffer_step != NULL) { buffer_step = (uint32_t)strtol(env_buffer_step, NULL, 10); if ((errno == EINVAL) || (errno == ERANGE)) { dlt_vlog(LOG_ERR, "Wrong value specified for %s. Using default\n", DLT_USER_ENV_BUFFER_STEP_SIZE); buffer_step = DLT_USER_RINGBUFFER_STEP_SIZE; } } /* init log buffer size */ dlt_user.log_buf_len = DLT_USER_BUF_MAX_SIZE; env_log_buffer_len = getenv(DLT_USER_ENV_LOG_MSG_BUF_LEN); if (env_log_buffer_len != NULL) { buffer_max_configured = (uint32_t)strtol(env_log_buffer_len, NULL, 10); if (buffer_max_configured > DLT_LOG_MSG_BUF_MAX_SIZE) { dlt_user.log_buf_len = DLT_LOG_MSG_BUF_MAX_SIZE; dlt_vlog(LOG_WARNING, "Configured size exceeds maximum allowed size,restricting to max [65535 bytes]\n"); } else { dlt_user.log_buf_len = buffer_max_configured; dlt_vlog(LOG_INFO, "Configured buffer size to [%d bytes]\n", buffer_max_configured); } } if (dlt_user.resend_buffer == NULL) { dlt_user.resend_buffer = calloc(sizeof(unsigned char), (dlt_user.log_buf_len + DLT_USER_EXTRA_BUFF_SIZE)); if (dlt_user.resend_buffer == NULL) { dlt_user_initialised = false; DLT_SEM_FREE(); dlt_vlog(LOG_ERR, "cannot allocate memory for resend buffer\n"); return DLT_RETURN_ERROR; } } if (dlt_buffer_init_dynamic(&(dlt_user.startup_buffer), buffer_min, buffer_max, buffer_step) == DLT_RETURN_ERROR) { dlt_user_initialised = false; DLT_SEM_FREE(); return DLT_RETURN_ERROR; } DLT_SEM_FREE(); signal(SIGPIPE, SIG_IGN); /* ignore pipe signals */ if (atexit_registered == 0) { atexit_registered = 1; atexit(dlt_user_atexit_handler); } #ifdef DLT_TEST_ENABLE dlt_user.corrupt_user_header = 0; dlt_user.corrupt_message_size = 0; dlt_user.corrupt_message_size_size = 0; #endif return DLT_RETURN_OK; } void dlt_user_atexit_handler(void) { /* parent will do clean-up */ if (g_dlt_is_child) return; if (!dlt_user_initialised) { dlt_vlog(LOG_WARNING, "%s dlt_user_initialised false\n", __FUNCTION__); /* close file */ dlt_log_free(); return; } /* Try to resend potential log messages in the user buffer */ int count = dlt_user_atexit_blow_out_user_buffer(); if (count != 0) dlt_vnlog(LOG_WARNING, 128, "Lost log messages in user buffer when exiting: %i\n", count); /* Unregister app (this also unregisters all contexts in daemon) */ /* Ignore return value */ dlt_unregister_app(); /* Cleanup */ /* Ignore return value */ dlt_free(); } int dlt_user_atexit_blow_out_user_buffer(void) { int count, ret; struct timespec ts; uint32_t exitTime = dlt_uptime() + dlt_user.timeout_at_exit_handler; /* Send content of ringbuffer */ DLT_SEM_LOCK(); count = dlt_buffer_get_message_count(&(dlt_user.startup_buffer)); DLT_SEM_FREE(); if (count > 0) { while (dlt_uptime() < exitTime) { if (dlt_user.dlt_log_handle == -1) { /* Reattach to daemon if neccesary */ dlt_user_log_reattach_to_daemon(); if ((dlt_user.dlt_log_handle != -1) && (dlt_user.overflow_counter)) { if (dlt_user_log_send_overflow() == 0) { dlt_vnlog(LOG_WARNING, DLT_USER_BUFFER_LENGTH, "%u messages discarded!\n", dlt_user.overflow_counter); dlt_user.overflow_counter = 0; } } } if (dlt_user.dlt_log_handle != -1) { ret = dlt_user_log_resend_buffer(); if (ret == 0) { DLT_SEM_LOCK(); count = dlt_buffer_get_message_count(&(dlt_user.startup_buffer)); DLT_SEM_FREE(); return count; } } ts.tv_sec = 0; ts.tv_nsec = DLT_USER_ATEXIT_RESEND_BUFFER_SLEEP; nanosleep(&ts, NULL); } DLT_SEM_LOCK(); count = dlt_buffer_get_message_count(&(dlt_user.startup_buffer)); DLT_SEM_FREE(); } return count; } static void dlt_user_free_buffer(unsigned char **buffer) { if (*buffer) { free(*buffer); *buffer = NULL; } } DltReturnValue dlt_free(void) { uint32_t i; int ret = 0; #ifndef DLT_USE_UNIX_SOCKET_IPC char filename[DLT_PATH_MAX]; #endif if (dlt_user_freeing != 0) /* resources are already being freed. Do nothing and return. */ return DLT_RETURN_ERROR; /* library is freeing its resources. Avoid to allocate it in dlt_init() */ dlt_user_freeing = 1; if (!dlt_user_initialised) { dlt_user_freeing = 0; return DLT_RETURN_ERROR; } dlt_user_initialised = false; dlt_stop_threads(); #ifndef DLT_USE_UNIX_SOCKET_IPC if (dlt_user.dlt_user_handle != DLT_FD_INIT) { close(dlt_user.dlt_user_handle); dlt_user.dlt_user_handle = DLT_FD_INIT; snprintf(filename, DLT_PATH_MAX, "%s/dlt%d", dlt_user_dir, getpid()); unlink(filename); } #endif #ifdef DLT_SHM_ENABLE /* free shared memory */ dlt_shm_free_client(&dlt_user.dlt_shm); #endif if (dlt_user.dlt_log_handle != -1) { /* close log file/output fifo to daemon */ #ifdef DLT_USE_UNIX_SOCKET_IPC ret = shutdown(dlt_user.dlt_log_handle, SHUT_WR); if (ret < 0) { dlt_vlog(LOG_WARNING, "%s: shutdown failed: %s\n", __func__, strerror(errno)); } else { while (1) { ssize_t bytes_read; bytes_read = read(dlt_user.dlt_log_handle, dlt_user.resend_buffer, dlt_user.log_buf_len); if (bytes_read < 0) { dlt_vlog(LOG_DEBUG, "%s - %d: Reading...\n", __func__, __LINE__); break; } else { dlt_vlog(LOG_DEBUG, "%s - %d: %d bytes read from resend buffer\n", __func__, __LINE__); if (!bytes_read) break; } } } #endif ret = close(dlt_user.dlt_log_handle); if (ret < 0) dlt_vlog(LOG_WARNING, "%s: close failed: %s\n", __func__, strerror(errno)); dlt_user.dlt_log_handle = -1; } /* Ignore return value */ DLT_SEM_LOCK(); dlt_receiver_free(&(dlt_user.receiver)); DLT_SEM_FREE(); /* Ignore return value */ DLT_SEM_LOCK(); dlt_user_free_buffer(&(dlt_user.resend_buffer)); dlt_buffer_free_dynamic(&(dlt_user.startup_buffer)); DLT_SEM_FREE(); DLT_SEM_LOCK(); if (dlt_user.dlt_ll_ts) { for (i = 0; i < dlt_user.dlt_ll_ts_max_num_entries; i++) { if (dlt_user.dlt_ll_ts[i].context_description != NULL) { free (dlt_user.dlt_ll_ts[i].context_description); dlt_user.dlt_ll_ts[i].context_description = NULL; } if (dlt_user.dlt_ll_ts[i].log_level_ptr != NULL) { free(dlt_user.dlt_ll_ts[i].log_level_ptr); dlt_user.dlt_ll_ts[i].log_level_ptr = NULL; } if (dlt_user.dlt_ll_ts[i].trace_status_ptr != NULL) { free(dlt_user.dlt_ll_ts[i].trace_status_ptr); dlt_user.dlt_ll_ts[i].trace_status_ptr = NULL; } if (dlt_user.dlt_ll_ts[i].injection_table != NULL) { free(dlt_user.dlt_ll_ts[i].injection_table); dlt_user.dlt_ll_ts[i].injection_table = NULL; } dlt_user.dlt_ll_ts[i].nrcallbacks = 0; dlt_user.dlt_ll_ts[i].log_level_changed_callback = 0; } free(dlt_user.dlt_ll_ts); dlt_user.dlt_ll_ts = NULL; dlt_user.dlt_ll_ts_max_num_entries = 0; dlt_user.dlt_ll_ts_num_entries = 0; } dlt_env_free_ll_set(&dlt_user.initial_ll_set); DLT_SEM_FREE(); char queue_name[NAME_MAX]; snprintf(queue_name, NAME_MAX, "%s.%d", DLT_MESSAGE_QUEUE_NAME, getpid()); /** * Ignore errors from these, to not to spam user if dlt_free * is accidentally called multiple times. */ if (dlt_user.dlt_segmented_queue_write_handle > 0) mq_close(dlt_user.dlt_segmented_queue_write_handle); if (dlt_user.dlt_segmented_queue_read_handle > 0) mq_close(dlt_user.dlt_segmented_queue_read_handle); if ((dlt_user.dlt_segmented_queue_write_handle > 0) || (dlt_user.dlt_segmented_queue_read_handle > 0)) mq_unlink(queue_name); dlt_user.dlt_segmented_queue_write_handle = DLT_FD_INIT; dlt_user.dlt_segmented_queue_read_handle = DLT_FD_INIT; pthread_cond_destroy(&mq_init_condition); sem_destroy(&dlt_mutex); /* allow the user app to do dlt_init() again. */ /* The flag is unset only to keep almost the same behaviour as before, on EntryNav */ /* This should be removed for other projects (see documentation of dlt_free() */ dlt_user_freeing = 0; return DLT_RETURN_OK; } DltReturnValue dlt_check_library_version(const char *user_major_version, const char *user_minor_version) { return dlt_user_check_library_version(user_major_version, user_minor_version); } DltReturnValue dlt_register_app(const char *apid, const char *description) { DltReturnValue ret = DLT_RETURN_OK; /* forbid dlt usage in child after fork */ if (g_dlt_is_child) return DLT_RETURN_ERROR; if (!dlt_user_initialised) { if (dlt_init() < 0) { dlt_vlog(LOG_ERR, "%s Failed to initialise dlt", __FUNCTION__); return DLT_RETURN_ERROR; } } if ((apid == NULL) || (apid[0] == '\0')) return DLT_RETURN_WRONG_PARAMETER; /* check if application already registered */ /* if yes do not register again */ if (apid[1] == 0) { if (apid[0] == dlt_user.appID[0]) return DLT_RETURN_OK; } else if (apid[2] == 0) { if ((apid[0] == dlt_user.appID[0]) && (apid[1] == dlt_user.appID[1])) return DLT_RETURN_OK; } else if (apid[3] == 0) { if ((apid[0] == dlt_user.appID[0]) && (apid[1] == dlt_user.appID[1]) && (apid[2] == dlt_user.appID[2])) return DLT_RETURN_OK; } else if ((apid[0] == dlt_user.appID[0]) && (apid[1] == dlt_user.appID[1]) && (apid[2] == dlt_user.appID[2]) && (apid[3] == dlt_user.appID[3])) { return DLT_RETURN_OK; } DLT_SEM_LOCK(); /* Store locally application id and application description */ dlt_set_id(dlt_user.appID, apid); if (dlt_user.application_description != NULL) free(dlt_user.application_description); dlt_user.application_description = NULL; if (description != NULL) { size_t desc_len = strlen(description); dlt_user.application_description = malloc(desc_len + 1); if (dlt_user.application_description) { strncpy(dlt_user.application_description, description, desc_len); dlt_user.application_description[desc_len] = '\0'; } else { DLT_SEM_FREE(); return DLT_RETURN_ERROR; } } DLT_SEM_FREE(); ret = dlt_user_log_send_register_application(); if ((ret == DLT_RETURN_OK) && (dlt_user.dlt_log_handle != -1)) ret = dlt_user_log_resend_buffer(); return ret; } DltReturnValue dlt_register_context(DltContext *handle, const char *contextid, const char *description) { /* check nullpointer */ if (handle == NULL) return DLT_RETURN_WRONG_PARAMETER; /* forbid dlt usage in child after fork */ if (g_dlt_is_child) return DLT_RETURN_ERROR; if (!dlt_user_initialised) { if (dlt_init() < 0) { dlt_vlog(LOG_ERR, "%s Failed to initialise dlt", __FUNCTION__); return DLT_RETURN_ERROR; } } if ((contextid == NULL) || (contextid[0] == '\0')) return DLT_RETURN_WRONG_PARAMETER; return dlt_register_context_ll_ts(handle, contextid, description, DLT_USER_LOG_LEVEL_NOT_SET, DLT_USER_TRACE_STATUS_NOT_SET); } DltReturnValue dlt_register_context_ll_ts_llccb(DltContext *handle, const char *contextid, const char *description, int loglevel, int tracestatus, void (*dlt_log_level_changed_callback)(char context_id[DLT_ID_SIZE], uint8_t log_level, uint8_t trace_status)) { DltContextData log; uint32_t i; int envLogLevel = DLT_USER_LOG_LEVEL_NOT_SET; /*check nullpointer */ if ((handle == NULL) || (contextid == NULL) || (contextid[0] == '\0')) return DLT_RETURN_WRONG_PARAMETER; /* forbid dlt usage in child after fork */ if (g_dlt_is_child) return DLT_RETURN_ERROR; if ((loglevel < DLT_USER_LOG_LEVEL_NOT_SET) || (loglevel >= DLT_LOG_MAX)) { dlt_vlog(LOG_ERR, "Loglevel %d is outside valid range", loglevel); return DLT_RETURN_WRONG_PARAMETER; } if ((tracestatus < DLT_USER_TRACE_STATUS_NOT_SET) || (tracestatus >= DLT_TRACE_STATUS_MAX)) { dlt_vlog(LOG_ERR, "Tracestatus %d is outside valid range", tracestatus); return DLT_RETURN_WRONG_PARAMETER; } if (dlt_user_log_init(handle, &log) < DLT_RETURN_OK) return DLT_RETURN_ERROR; /* Reset message counter */ handle->mcnt = 0; /* Store context id in log level/trace status field */ /* Check if already registered, else register context */ DLT_SEM_LOCK(); /* Check of double context registration removed */ /* Double registration is already checked by daemon */ /* Allocate or expand context array */ if (dlt_user.dlt_ll_ts == NULL) { dlt_user.dlt_ll_ts = (dlt_ll_ts_type *)malloc(sizeof(dlt_ll_ts_type) * DLT_USER_CONTEXT_ALLOC_SIZE); if (dlt_user.dlt_ll_ts == NULL) { DLT_SEM_FREE(); return DLT_RETURN_ERROR; } dlt_user.dlt_ll_ts_max_num_entries = DLT_USER_CONTEXT_ALLOC_SIZE; /* Initialize new entries */ for (i = 0; i < dlt_user.dlt_ll_ts_max_num_entries; i++) { dlt_set_id(dlt_user.dlt_ll_ts[i].contextID, ""); /* At startup, logging and tracing is locally enabled */ /* the correct log level/status is set after received from daemon */ dlt_user.dlt_ll_ts[i].log_level = DLT_USER_INITIAL_LOG_LEVEL; dlt_user.dlt_ll_ts[i].trace_status = DLT_USER_INITIAL_TRACE_STATUS; dlt_user.dlt_ll_ts[i].log_level_ptr = 0; dlt_user.dlt_ll_ts[i].trace_status_ptr = 0; dlt_user.dlt_ll_ts[i].context_description = 0; dlt_user.dlt_ll_ts[i].injection_table = 0; dlt_user.dlt_ll_ts[i].nrcallbacks = 0; dlt_user.dlt_ll_ts[i].log_level_changed_callback = 0; } } else if ((dlt_user.dlt_ll_ts_num_entries % DLT_USER_CONTEXT_ALLOC_SIZE) == 0) { /* allocate memory in steps of DLT_USER_CONTEXT_ALLOC_SIZE, e.g. 500 */ dlt_ll_ts_type *old_ll_ts; uint32_t old_max_entries; old_ll_ts = dlt_user.dlt_ll_ts; old_max_entries = dlt_user.dlt_ll_ts_max_num_entries; dlt_user.dlt_ll_ts_max_num_entries = ((dlt_user.dlt_ll_ts_num_entries / DLT_USER_CONTEXT_ALLOC_SIZE) + 1) * DLT_USER_CONTEXT_ALLOC_SIZE; dlt_user.dlt_ll_ts = (dlt_ll_ts_type *)malloc(sizeof(dlt_ll_ts_type) * dlt_user.dlt_ll_ts_max_num_entries); if (dlt_user.dlt_ll_ts == NULL) { dlt_user.dlt_ll_ts = old_ll_ts; dlt_user.dlt_ll_ts_max_num_entries = old_max_entries; DLT_SEM_FREE(); return DLT_RETURN_ERROR; } memcpy(dlt_user.dlt_ll_ts, old_ll_ts, sizeof(dlt_ll_ts_type) * dlt_user.dlt_ll_ts_num_entries); free(old_ll_ts); /* Initialize new entries */ for (i = dlt_user.dlt_ll_ts_num_entries; i < dlt_user.dlt_ll_ts_max_num_entries; i++) { dlt_set_id(dlt_user.dlt_ll_ts[i].contextID, ""); /* At startup, logging and tracing is locally enabled */ /* the correct log level/status is set after received from daemon */ dlt_user.dlt_ll_ts[i].log_level = DLT_USER_INITIAL_LOG_LEVEL; dlt_user.dlt_ll_ts[i].trace_status = DLT_USER_INITIAL_TRACE_STATUS; dlt_user.dlt_ll_ts[i].log_level_ptr = 0; dlt_user.dlt_ll_ts[i].trace_status_ptr = 0; dlt_user.dlt_ll_ts[i].context_description = 0; dlt_user.dlt_ll_ts[i].injection_table = 0; dlt_user.dlt_ll_ts[i].nrcallbacks = 0; dlt_user.dlt_ll_ts[i].log_level_changed_callback = 0; } } /* Store locally context id and context description */ dlt_set_id(dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].contextID, contextid); if (dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description != 0) free(dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description); dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description = 0; if (description != 0) { size_t desc_len = strlen(description); dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description = malloc(desc_len + 1); if (dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description == 0) { DLT_SEM_FREE(); return DLT_RETURN_ERROR; } strncpy(dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description, description, desc_len); dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description[desc_len] = '\0'; } if (dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].log_level_ptr == 0) { dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].log_level_ptr = malloc(sizeof(int8_t)); if (dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].log_level_ptr == 0) { DLT_SEM_FREE(); return DLT_RETURN_ERROR; } } if (dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].trace_status_ptr == 0) { dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].trace_status_ptr = malloc(sizeof(int8_t)); if (dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].trace_status_ptr == 0) { DLT_SEM_FREE(); return DLT_RETURN_ERROR; } } /* check if the log level is set in the environement */ envLogLevel = dlt_env_adjust_ll_from_env(&dlt_user.initial_ll_set, dlt_user.appID, contextid, DLT_USER_LOG_LEVEL_NOT_SET); if (envLogLevel != DLT_USER_LOG_LEVEL_NOT_SET) { dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].log_level = envLogLevel; loglevel = envLogLevel; } else if (loglevel != DLT_USER_LOG_LEVEL_NOT_SET) { dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].log_level = loglevel; } if (tracestatus != DLT_USER_TRACE_STATUS_NOT_SET) dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].trace_status = tracestatus; /* Prepare transfer struct */ dlt_set_id(handle->contextID, contextid); handle->log_level_pos = dlt_user.dlt_ll_ts_num_entries; handle->log_level_ptr = dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].log_level_ptr; handle->trace_status_ptr = dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].trace_status_ptr; log.context_description = dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description; *(dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].log_level_ptr) = dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].log_level; *(dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].trace_status_ptr) = dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].trace_status = tracestatus; dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].log_level_changed_callback = dlt_log_level_changed_callback; log.log_level = loglevel; log.trace_status = tracestatus; dlt_user.dlt_ll_ts_num_entries++; DLT_SEM_FREE(); return dlt_user_log_send_register_context(&log); } DltReturnValue dlt_register_context_ll_ts(DltContext *handle, const char *contextid, const char *description, int loglevel, int tracestatus) { return dlt_register_context_ll_ts_llccb(handle, contextid, description, loglevel, tracestatus, NULL); } DltReturnValue dlt_register_context_llccb(DltContext *handle, const char *contextid, const char *description, void (*dlt_log_level_changed_callback)(char context_id[DLT_ID_SIZE], uint8_t log_level, uint8_t trace_status)) { if ((handle == NULL) || (contextid == NULL) || (contextid[0] == '\0')) return DLT_RETURN_WRONG_PARAMETER; /* forbid dlt usage in child after fork */ if (g_dlt_is_child) return DLT_RETURN_ERROR; if (!dlt_user_initialised) { if (dlt_init() < 0) { dlt_vlog(LOG_ERR, "%s Failed to initialise dlt", __FUNCTION__); return DLT_RETURN_ERROR; } } return dlt_register_context_ll_ts_llccb(handle, contextid, description, DLT_USER_LOG_LEVEL_NOT_SET, DLT_USER_TRACE_STATUS_NOT_SET, dlt_log_level_changed_callback); } DltReturnValue dlt_unregister_app(void) { DltReturnValue ret = DLT_RETURN_OK; /* forbid dlt usage in child after fork */ if (g_dlt_is_child) return DLT_RETURN_ERROR; if (!dlt_user_initialised) { dlt_vlog(LOG_WARNING, "%s dlt_user_initialised false\n", __FUNCTION__); return DLT_RETURN_ERROR; } /* Inform daemon to unregister application and all of its contexts */ ret = dlt_user_log_send_unregister_application(); DLT_SEM_LOCK(); /* Clear and free local stored application information */ dlt_set_id(dlt_user.appID, ""); if (dlt_user.application_description != NULL) free(dlt_user.application_description); dlt_user.application_description = NULL; DLT_SEM_FREE(); return ret; } DltReturnValue dlt_unregister_app_flush_buffered_logs(void) { DltReturnValue ret = DLT_RETURN_OK; /* forbid dlt usage in child after fork */ if (g_dlt_is_child) return DLT_RETURN_ERROR; if (!dlt_user_initialised) { dlt_vlog(LOG_ERR, "%s dlt_user_initialised false\n", __func__); return DLT_RETURN_ERROR; } if (dlt_user.dlt_log_handle != -1) { do ret = dlt_user_log_resend_buffer(); while ((ret != DLT_RETURN_OK) && (dlt_user.dlt_log_handle != -1)); } return dlt_unregister_app(); } DltReturnValue dlt_unregister_context(DltContext *handle) { DltContextData log; DltReturnValue ret = DLT_RETURN_OK; /* forbid dlt usage in child after fork */ if (g_dlt_is_child) return DLT_RETURN_ERROR; log.handle = NULL; log.context_description = NULL; if (dlt_user_log_init(handle, &log) <= DLT_RETURN_ERROR) return DLT_RETURN_ERROR; DLT_SEM_LOCK(); handle->log_level_ptr = NULL; handle->trace_status_ptr = NULL; if (dlt_user.dlt_ll_ts != NULL) { /* Clear and free local stored context information */ dlt_set_id(dlt_user.dlt_ll_ts[handle->log_level_pos].contextID, ""); dlt_user.dlt_ll_ts[handle->log_level_pos].log_level = DLT_USER_INITIAL_LOG_LEVEL; dlt_user.dlt_ll_ts[handle->log_level_pos].trace_status = DLT_USER_INITIAL_TRACE_STATUS; if (dlt_user.dlt_ll_ts[handle->log_level_pos].context_description != NULL) free(dlt_user.dlt_ll_ts[handle->log_level_pos].context_description); if (dlt_user.dlt_ll_ts[handle->log_level_pos].log_level_ptr != NULL) { free(dlt_user.dlt_ll_ts[handle->log_level_pos].log_level_ptr); dlt_user.dlt_ll_ts[handle->log_level_pos].log_level_ptr = NULL; } if (dlt_user.dlt_ll_ts[handle->log_level_pos].trace_status_ptr != NULL) { free(dlt_user.dlt_ll_ts[handle->log_level_pos].trace_status_ptr); dlt_user.dlt_ll_ts[handle->log_level_pos].trace_status_ptr = NULL; } dlt_user.dlt_ll_ts[handle->log_level_pos].context_description = NULL; if (dlt_user.dlt_ll_ts[handle->log_level_pos].injection_table != NULL) { free(dlt_user.dlt_ll_ts[handle->log_level_pos].injection_table); dlt_user.dlt_ll_ts[handle->log_level_pos].injection_table = NULL; } dlt_user.dlt_ll_ts[handle->log_level_pos].nrcallbacks = 0; dlt_user.dlt_ll_ts[handle->log_level_pos].log_level_changed_callback = 0; } DLT_SEM_FREE(); /* Inform daemon to unregister context */ ret = dlt_user_log_send_unregister_context(&log); return ret; } DltReturnValue dlt_set_application_ll_ts_limit(DltLogLevelType loglevel, DltTraceStatusType tracestatus) { uint32_t i; /* forbid dlt usage in child after fork */ if (g_dlt_is_child) return DLT_RETURN_ERROR; if ((loglevel < DLT_USER_LOG_LEVEL_NOT_SET) || (loglevel >= DLT_LOG_MAX)) { dlt_vlog(LOG_ERR, "Loglevel %d is outside valid range", loglevel); return DLT_RETURN_WRONG_PARAMETER; } if ((tracestatus < DLT_USER_TRACE_STATUS_NOT_SET) || (tracestatus >= DLT_TRACE_STATUS_MAX)) { dlt_vlog(LOG_ERR, "Tracestatus %d is outside valid range", tracestatus); return DLT_RETURN_WRONG_PARAMETER; } if (!dlt_user_initialised) { if (dlt_init() < 0) { dlt_vlog(LOG_ERR, "%s Failed to initialise dlt", __FUNCTION__); return DLT_RETURN_ERROR; } } DLT_SEM_LOCK(); if (dlt_user.dlt_ll_ts == NULL) { DLT_SEM_FREE(); return DLT_RETURN_ERROR; } /* Update local structures */ for (i = 0; i < dlt_user.dlt_ll_ts_num_entries; i++) { dlt_user.dlt_ll_ts[i].log_level = loglevel; dlt_user.dlt_ll_ts[i].trace_status = tracestatus; if (dlt_user.dlt_ll_ts[i].log_level_ptr) *(dlt_user.dlt_ll_ts[i].log_level_ptr) = loglevel; if (dlt_user.dlt_ll_ts[i].trace_status_ptr) *(dlt_user.dlt_ll_ts[i].trace_status_ptr) = tracestatus; } DLT_SEM_FREE(); /* Inform DLT server about update */ return dlt_send_app_ll_ts_limit(dlt_user.appID, loglevel, tracestatus); } int dlt_get_log_state() { return dlt_user.log_state; } DltReturnValue dlt_set_log_mode(DltUserLogMode mode) { /* forbid dlt usage in child after fork */ if (g_dlt_is_child) return DLT_RETURN_ERROR; if ((mode < DLT_USER_MODE_UNDEFINED) || (mode >= DLT_USER_MODE_MAX)) { dlt_vlog(LOG_ERR, "User log mode %d is outside valid range", mode); return DLT_RETURN_WRONG_PARAMETER; } if (!dlt_user_initialised) { if (dlt_init() < 0) { dlt_vlog(LOG_ERR, "%s Failed to initialise dlt", __FUNCTION__); return DLT_RETURN_ERROR; } } return dlt_user_log_send_log_mode(mode); } int dlt_set_resend_timeout_atexit(uint32_t timeout_in_milliseconds) { /* forbid dlt usage in child after fork */ if (g_dlt_is_child) return DLT_RETURN_ERROR; if (dlt_user_initialised == 0) if (dlt_init() < 0) return -1; dlt_user.timeout_at_exit_handler = timeout_in_milliseconds * 10; return 0; } /* ********************************************************************************************* */ inline DltReturnValue dlt_user_log_write_start(DltContext *handle, DltContextData *log, DltLogLevelType loglevel) { return dlt_user_log_write_start_id(handle, log, loglevel, DLT_USER_DEFAULT_MSGID); } DltReturnValue dlt_user_log_write_start_id(DltContext *handle, DltContextData *log, DltLogLevelType loglevel, uint32_t messageid) { DLT_LOG_FATAL_RESET_TRAP(loglevel); DltReturnValue ret = DLT_RETURN_OK; /* check nullpointer */ if ((handle == NULL) || (log == NULL)) return DLT_RETURN_WRONG_PARAMETER; /* forbid dlt usage in child after fork */ if (g_dlt_is_child) return DLT_RETURN_ERROR; /* check log levels */ ret = dlt_user_is_logLevel_enabled(handle, loglevel); if (ret == DLT_RETURN_WRONG_PARAMETER) return DLT_RETURN_WRONG_PARAMETER; else if (ret == DLT_RETURN_LOGGING_DISABLED) return DLT_RETURN_OK; else /* Do nothing */ /* initialize values */ if ((dlt_user_log_init(handle, log) < DLT_RETURN_OK) || (dlt_user.dlt_ll_ts == NULL)) return DLT_RETURN_ERROR; /* initialize values */ if (log->buffer == NULL) { log->buffer = calloc(sizeof(unsigned char), dlt_user.log_buf_len); if (log->buffer == NULL) { dlt_vlog(LOG_ERR, "Cannot allocate buffer for DLT Log message\n"); return DLT_RETURN_ERROR; } } log->args_num = 0; log->log_level = loglevel; log->size = 0; /* In non-verbose mode, insert message id */ if (dlt_user.verbose_mode == 0) { if ((sizeof(uint32_t)) > dlt_user.log_buf_len) return DLT_RETURN_USER_BUFFER_FULL; /* Write message id */ memcpy(log->buffer, &(messageid), sizeof(uint32_t)); log->size = sizeof(uint32_t); /* as the message id is part of each message in non-verbose mode, * it doesn't increment the argument counter in extended header (if used) */ } return DLT_RETURN_TRUE; } DltReturnValue dlt_user_log_write_finish(DltContextData *log) { int ret = DLT_RETURN_ERROR; if (log == NULL) return DLT_RETURN_WRONG_PARAMETER; ret = dlt_user_log_send_log(log, DLT_TYPE_LOG); dlt_user_free_buffer(&(log->buffer)); return ret; } DltReturnValue dlt_user_log_write_raw(DltContextData *log, void *data, uint16_t length) { return dlt_user_log_write_raw_formatted(log, data, length, DLT_FORMAT_DEFAULT); } DltReturnValue dlt_user_log_write_raw_formatted(DltContextData *log, void *data, uint16_t length, DltFormatType type) { size_t new_log_size = 0; uint32_t type_info = 0; /* check nullpointer */ if ((log == NULL) || ((data == NULL) && (length != 0))) return DLT_RETURN_WRONG_PARAMETER; /* Have to cast type to signed type because some compilers assume that DltFormatType is unsigned and issue a warning */ if (((int16_t)type < DLT_FORMAT_DEFAULT) || (type >= DLT_FORMAT_MAX)) { dlt_vlog(LOG_ERR, "Format type %d is outside valid range", type); return DLT_RETURN_WRONG_PARAMETER; } if (!dlt_user_initialised) { dlt_vlog(LOG_WARNING, "%s dlt_user_initialised false\n", __FUNCTION__); return DLT_RETURN_ERROR; } new_log_size = log->size + length + sizeof(uint16_t); if (new_log_size > dlt_user.log_buf_len) return DLT_RETURN_USER_BUFFER_FULL; if (dlt_user.verbose_mode) { new_log_size = log->size + length + sizeof(uint32_t) + sizeof(uint16_t); if (new_log_size > dlt_user.log_buf_len) return DLT_RETURN_USER_BUFFER_FULL; /* Transmit type information */ type_info = DLT_TYPE_INFO_RAWD; if ((type >= DLT_FORMAT_HEX8) && (type <= DLT_FORMAT_HEX64)) { type_info |= DLT_SCOD_HEX; type_info += type; } else if ((type >= DLT_FORMAT_BIN8) && (type <= DLT_FORMAT_BIN16)) { type_info |= DLT_SCOD_BIN; type_info += type - DLT_FORMAT_BIN8 + 1; } memcpy((log->buffer) + log->size, &(type_info), sizeof(uint32_t)); log->size += sizeof(uint32_t); } /* First transmit length of raw data, then the raw data itself */ memcpy((log->buffer) + log->size, &(length), sizeof(uint16_t)); log->size += sizeof(uint16_t); memcpy((log->buffer) + log->size, data, length); log->size += length; log->args_num++; return DLT_RETURN_OK; } DltReturnValue dlt_user_log_write_float32(DltContextData *log, float32_t data) { uint32_t type_info; if (log == NULL) return DLT_RETURN_WRONG_PARAMETER; if (!dlt_user_initialised) { dlt_vlog(LOG_WARNING, "%s dlt_user_initialised false\n", __FUNCTION__); return DLT_RETURN_ERROR; } if (sizeof(float32_t) != 4) return DLT_RETURN_ERROR; if ((log->size + sizeof(float32_t)) > dlt_user.log_buf_len) return DLT_RETURN_USER_BUFFER_FULL; if (dlt_user.verbose_mode) { if ((log->size + sizeof(uint32_t) + sizeof(float32_t)) > dlt_user.log_buf_len) return DLT_RETURN_USER_BUFFER_FULL; type_info = DLT_TYPE_INFO_FLOA | DLT_TYLE_32BIT; memcpy((log->buffer) + log->size, &(type_info), sizeof(uint32_t)); log->size += sizeof(uint32_t); } memcpy((log->buffer) + log->size, &data, sizeof(float32_t)); log->size += sizeof(float32_t); log->args_num++; return DLT_RETURN_OK; } DltReturnValue dlt_user_log_write_float64(DltContextData *log, float64_t data) { uint32_t type_info; if (log == NULL) return DLT_RETURN_WRONG_PARAMETER; if (!dlt_user_initialised) { dlt_vlog(LOG_WARNING, "%s dlt_user_initialised false\n", __FUNCTION__); return DLT_RETURN_ERROR; } if (sizeof(float64_t) != 8) return DLT_RETURN_ERROR; if ((log->size + sizeof(float64_t)) > dlt_user.log_buf_len) return DLT_RETURN_USER_BUFFER_FULL; if (dlt_user.verbose_mode) { if ((log->size + sizeof(uint32_t) + sizeof(float64_t)) > dlt_user.log_buf_len) return DLT_RETURN_USER_BUFFER_FULL; type_info = DLT_TYPE_INFO_FLOA | DLT_TYLE_64BIT; memcpy((log->buffer) + log->size, &(type_info), sizeof(uint32_t)); log->size += sizeof(uint32_t); } memcpy((log->buffer) + log->size, &data, sizeof(float64_t)); log->size += sizeof(float64_t); log->args_num++; return DLT_RETURN_OK; } DltReturnValue dlt_user_log_write_uint(DltContextData *log, unsigned int data) { if (log == NULL) return DLT_RETURN_WRONG_PARAMETER; if (!dlt_user_initialised) { dlt_vlog(LOG_WARNING, "%s dlt_user_initialised false\n", __FUNCTION__); return DLT_RETURN_ERROR; } switch (sizeof(unsigned int)) { case 1: { return dlt_user_log_write_uint8(log, (uint8_t)data); break; } case 2: { return dlt_user_log_write_uint16(log, (uint16_t)data); break; } case 4: { return dlt_user_log_write_uint32(log, (uint32_t)data); break; } case 8: { return dlt_user_log_write_uint64(log, (uint64_t)data); break; } default: { return DLT_RETURN_ERROR; break; } } return DLT_RETURN_OK; } DltReturnValue dlt_user_log_write_uint8(DltContextData *log, uint8_t data) { uint32_t type_info; if (log == NULL) return DLT_RETURN_WRONG_PARAMETER; if (!dlt_user_initialised) { dlt_vlog(LOG_WARNING, "%s dlt_user_initialised false\n", __FUNCTION__); return DLT_RETURN_ERROR; } if ((log->size + sizeof(uint8_t)) > dlt_user.log_buf_len) return DLT_RETURN_USER_BUFFER_FULL; if (dlt_user.verbose_mode) { if ((log->size + sizeof(uint32_t) + sizeof(uint8_t)) > dlt_user.log_buf_len) return DLT_RETURN_USER_BUFFER_FULL; type_info = DLT_TYPE_INFO_UINT | DLT_TYLE_8BIT; memcpy((log->buffer) + log->size, &(type_info), sizeof(uint32_t)); log->size += sizeof(uint32_t); } memcpy((log->buffer) + log->size, &data, sizeof(uint8_t)); log->size += sizeof(uint8_t); log->args_num++; return DLT_RETURN_OK; } DltReturnValue dlt_user_log_write_uint16(DltContextData *log, uint16_t data) { uint32_t type_info; if (log == NULL) return DLT_RETURN_WRONG_PARAMETER; if (!dlt_user_initialised) { dlt_vlog(LOG_WARNING, "%s dlt_user_initialised false\n", __FUNCTION__); return DLT_RETURN_ERROR; } if ((log->size + sizeof(uint16_t)) > dlt_user.log_buf_len) return DLT_RETURN_USER_BUFFER_FULL; if (dlt_user.verbose_mode) { if ((log->size + sizeof(uint32_t) + sizeof(uint16_t)) > dlt_user.log_buf_len) return DLT_RETURN_USER_BUFFER_FULL; type_info = DLT_TYPE_INFO_UINT | DLT_TYLE_16BIT; memcpy((log->buffer) + log->size, &(type_info), sizeof(uint32_t)); log->size += sizeof(uint32_t); } memcpy((log->buffer) + log->size, &data, sizeof(uint16_t)); log->size += sizeof(uint16_t); log->args_num++; return DLT_RETURN_OK; } DltReturnValue dlt_user_log_write_uint32(DltContextData *log, uint32_t data) { uint32_t type_info; if (log == NULL) return DLT_RETURN_WRONG_PARAMETER; if (!dlt_user_initialised) { dlt_vlog(LOG_WARNING, "%s dlt_user_initialised false\n", __FUNCTION__); return DLT_RETURN_ERROR; } if ((log->size + sizeof(uint32_t)) > dlt_user.log_buf_len) return DLT_RETURN_USER_BUFFER_FULL; if (dlt_user.verbose_mode) { if ((log->size + sizeof(uint32_t) + sizeof(uint32_t)) > dlt_user.log_buf_len) return DLT_RETURN_USER_BUFFER_FULL; type_info = DLT_TYPE_INFO_UINT | DLT_TYLE_32BIT; memcpy((log->buffer) + log->size, &(type_info), sizeof(uint32_t)); log->size += sizeof(uint32_t); } memcpy((log->buffer) + log->size, &data, sizeof(uint32_t)); log->size += sizeof(uint32_t); log->args_num++; return DLT_RETURN_OK; } DltReturnValue dlt_user_log_write_uint64(DltContextData *log, uint64_t data) { uint32_t type_info; if (log == NULL) return DLT_RETURN_WRONG_PARAMETER; if (!dlt_user_initialised) { dlt_vlog(LOG_WARNING, "%s dlt_user_initialised false\n", __FUNCTION__); return DLT_RETURN_ERROR; } if ((log->size + sizeof(uint64_t)) > dlt_user.log_buf_len) return DLT_RETURN_USER_BUFFER_FULL; if (dlt_user.verbose_mode) { if ((log->size + sizeof(uint32_t) + sizeof(uint64_t)) > dlt_user.log_buf_len) return DLT_RETURN_USER_BUFFER_FULL; type_info = DLT_TYPE_INFO_UINT | DLT_TYLE_64BIT; memcpy((log->buffer) + log->size, &(type_info), sizeof(uint32_t)); log->size += sizeof(uint32_t); } memcpy((log->buffer) + log->size, &data, sizeof(uint64_t)); log->size += sizeof(uint64_t); log->args_num++; return DLT_RETURN_OK; } DltReturnValue dlt_user_log_write_uint8_formatted(DltContextData *log, uint8_t data, DltFormatType type) { uint32_t type_info; if (log == NULL) return DLT_RETURN_WRONG_PARAMETER; /* Have to cast type to signed type because some compilers assume that DltFormatType is unsigned and issue a warning */ if (((int16_t)type < DLT_FORMAT_DEFAULT) || (type >= DLT_FORMAT_MAX)) { dlt_vlog(LOG_ERR, "Format type %d is outside valid range", type); return DLT_RETURN_WRONG_PARAMETER; } if (!dlt_user_initialised) { dlt_vlog(LOG_WARNING, "%s dlt_user_initialised false\n", __FUNCTION__); return DLT_RETURN_ERROR; } if ((log->size + sizeof(uint16_t)) > dlt_user.log_buf_len) return DLT_RETURN_USER_BUFFER_FULL; if (dlt_user.verbose_mode) { if ((log->size + sizeof(uint32_t) + sizeof(uint16_t)) > dlt_user.log_buf_len) return DLT_RETURN_USER_BUFFER_FULL; type_info = DLT_TYPE_INFO_UINT | DLT_TYLE_8BIT; if ((type >= DLT_FORMAT_HEX8) && (type <= DLT_FORMAT_HEX64)) type_info |= DLT_SCOD_HEX; else if ((type >= DLT_FORMAT_BIN8) && (type <= DLT_FORMAT_BIN16)) type_info |= DLT_SCOD_BIN; memcpy((log->buffer) + log->size, &(type_info), sizeof(uint32_t)); log->size += sizeof(uint32_t); } memcpy((log->buffer) + log->size, &data, sizeof(uint8_t)); log->size += sizeof(uint8_t); log->args_num++; return DLT_RETURN_OK; } DltReturnValue dlt_user_log_write_uint16_formatted(DltContextData *log, uint16_t data, DltFormatType type) { uint32_t type_info; if (log == NULL) return DLT_RETURN_WRONG_PARAMETER; /* Have to cast type to signed type because some compilers assume that DltFormatType is unsigned and issue a warning */ if (((int16_t)type < DLT_FORMAT_DEFAULT) || (type >= DLT_FORMAT_MAX)) { dlt_vlog(LOG_ERR, "Format type %d is outside valid range", type); return DLT_RETURN_WRONG_PARAMETER; } if (!dlt_user_initialised) { dlt_vlog(LOG_WARNING, "%s dlt_user_initialised false\n", __FUNCTION__); return DLT_RETURN_ERROR; } if ((log->size + sizeof(uint16_t)) > dlt_user.log_buf_len) return DLT_RETURN_USER_BUFFER_FULL; if (dlt_user.verbose_mode) { if ((log->size + sizeof(uint32_t) + sizeof(uint16_t)) > dlt_user.log_buf_len) return DLT_RETURN_USER_BUFFER_FULL; type_info = DLT_TYPE_INFO_UINT | DLT_TYLE_16BIT; if ((type >= DLT_FORMAT_HEX8) && (type <= DLT_FORMAT_HEX64)) type_info |= DLT_SCOD_HEX; else if ((type >= DLT_FORMAT_BIN8) && (type <= DLT_FORMAT_BIN16)) type_info |= DLT_SCOD_BIN; memcpy((log->buffer) + log->size, &(type_info), sizeof(uint32_t)); log->size += sizeof(uint32_t); } memcpy((log->buffer) + log->size, &data, sizeof(uint16_t)); log->size += sizeof(uint16_t); log->args_num++; return DLT_RETURN_OK; } DltReturnValue dlt_user_log_write_uint32_formatted(DltContextData *log, uint32_t data, DltFormatType type) { uint32_t type_info; if (log == NULL) return DLT_RETURN_WRONG_PARAMETER; /* Have to cast type to signed type because some compilers assume that DltFormatType is unsigned and issue a warning */ if (((int16_t)type < DLT_FORMAT_DEFAULT) || (type >= DLT_FORMAT_MAX)) { dlt_vlog(LOG_ERR, "Format type %d is outside valid range", type); return DLT_RETURN_WRONG_PARAMETER; } if (!dlt_user_initialised) { dlt_vlog(LOG_WARNING, "%s dlt_user_initialised false\n", __FUNCTION__); return DLT_RETURN_ERROR; } if ((log->size + sizeof(uint16_t)) > dlt_user.log_buf_len) return DLT_RETURN_USER_BUFFER_FULL; if (dlt_user.verbose_mode) { if ((log->size + sizeof(uint32_t) + sizeof(uint16_t)) > dlt_user.log_buf_len) return DLT_RETURN_USER_BUFFER_FULL; type_info = DLT_TYPE_INFO_UINT | DLT_TYLE_32BIT; if ((type >= DLT_FORMAT_HEX8) && (type <= DLT_FORMAT_HEX64)) type_info |= DLT_SCOD_HEX; else if ((type >= DLT_FORMAT_BIN8) && (type <= DLT_FORMAT_BIN16)) type_info |= DLT_SCOD_BIN; memcpy((log->buffer) + log->size, &(type_info), sizeof(uint32_t)); log->size += sizeof(uint32_t); } memcpy((log->buffer) + log->size, &data, sizeof(uint32_t)); log->size += sizeof(uint32_t); log->args_num++; return DLT_RETURN_OK; } DltReturnValue dlt_user_log_write_uint64_formatted(DltContextData *log, uint64_t data, DltFormatType type) { uint32_t type_info; if (log == NULL) return DLT_RETURN_WRONG_PARAMETER; /* Have to cast type to signed type because some compilers assume that DltFormatType is unsigned and issue a warning */ if (((int16_t)type < DLT_FORMAT_DEFAULT) || (type >= DLT_FORMAT_MAX)) { dlt_vlog(LOG_ERR, "Format type %d is outside valid range", type); return DLT_RETURN_WRONG_PARAMETER; } if (!dlt_user_initialised) { dlt_vlog(LOG_WARNING, "%s dlt_user_initialised false\n", __FUNCTION__); return DLT_RETURN_ERROR; } if ((log->size + sizeof(uint16_t)) > dlt_user.log_buf_len) return DLT_RETURN_USER_BUFFER_FULL; if (dlt_user.verbose_mode) { if ((log->size + sizeof(uint32_t) + sizeof(uint16_t)) > dlt_user.log_buf_len) return DLT_RETURN_USER_BUFFER_FULL; type_info = DLT_TYPE_INFO_UINT | DLT_TYLE_64BIT; if ((type >= DLT_FORMAT_HEX8) && (type <= DLT_FORMAT_HEX64)) type_info |= DLT_SCOD_HEX; else if ((type >= DLT_FORMAT_BIN8) && (type <= DLT_FORMAT_BIN16)) type_info |= DLT_SCOD_BIN; memcpy((log->buffer) + log->size, &(type_info), sizeof(uint32_t)); log->size += sizeof(uint32_t); } memcpy((log->buffer) + log->size, &data, sizeof(uint64_t)); log->size += sizeof(uint64_t); log->args_num++; return DLT_RETURN_OK; } DltReturnValue dlt_user_log_write_ptr(DltContextData *log, void *data) { if (log == NULL) return DLT_RETURN_WRONG_PARAMETER; if (!dlt_user_initialised) { dlt_vlog(LOG_WARNING, "%s user_initialised false\n", __FUNCTION__); return DLT_RETURN_ERROR; } switch (sizeof(void *)) { case 4: return dlt_user_log_write_uint32_formatted(log, (uintptr_t)data, DLT_FORMAT_HEX32); break; case 8: return dlt_user_log_write_uint64_formatted(log, (uintptr_t)data, DLT_FORMAT_HEX64); break; default: ; /* skip */ } return DLT_RETURN_OK; } DltReturnValue dlt_user_log_write_int(DltContextData *log, int data) { if (log == NULL) return DLT_RETURN_WRONG_PARAMETER; if (!dlt_user_initialised) { dlt_vlog(LOG_WARNING, "%s dlt_user_initialised false\n", __FUNCTION__); return DLT_RETURN_ERROR; } switch (sizeof(int)) { case 1: { return dlt_user_log_write_int8(log, (int8_t)data); break; } case 2: { return dlt_user_log_write_int16(log, (int16_t)data); break; } case 4: { return dlt_user_log_write_int32(log, (int32_t)data); break; } case 8: { return dlt_user_log_write_int64(log, (int64_t)data); break; } default: { return DLT_RETURN_ERROR; break; } } return DLT_RETURN_OK; } DltReturnValue dlt_user_log_write_int8(DltContextData *log, int8_t data) { uint32_t type_info; if (log == NULL) return DLT_RETURN_WRONG_PARAMETER; if (!dlt_user_initialised) { dlt_vlog(LOG_WARNING, "%s dlt_user_initialised false\n", __FUNCTION__); return DLT_RETURN_ERROR; } if ((log->size + sizeof(int8_t)) > dlt_user.log_buf_len) return DLT_RETURN_USER_BUFFER_FULL; if (dlt_user.verbose_mode) { if ((log->size + sizeof(uint32_t) + sizeof(int8_t)) > dlt_user.log_buf_len) return DLT_RETURN_USER_BUFFER_FULL; type_info = DLT_TYPE_INFO_SINT | DLT_TYLE_8BIT; memcpy((log->buffer) + log->size, &(type_info), sizeof(uint32_t)); log->size += sizeof(uint32_t); } memcpy((log->buffer) + log->size, &data, sizeof(int8_t)); log->size += sizeof(int8_t); log->args_num++; return DLT_RETURN_OK; } DltReturnValue dlt_user_log_write_int16(DltContextData *log, int16_t data) { uint32_t type_info; if (log == NULL) return DLT_RETURN_WRONG_PARAMETER; if (!dlt_user_initialised) { dlt_vlog(LOG_WARNING, "%s dlt_user_initialised false\n", __FUNCTION__); return DLT_RETURN_ERROR; } if ((log->size + sizeof(int16_t)) > dlt_user.log_buf_len) return DLT_RETURN_USER_BUFFER_FULL; if (dlt_user.verbose_mode) { if ((log->size + sizeof(uint32_t) + sizeof(int16_t)) > dlt_user.log_buf_len) return DLT_RETURN_USER_BUFFER_FULL; type_info = DLT_TYPE_INFO_SINT | DLT_TYLE_16BIT; memcpy((log->buffer) + log->size, &(type_info), sizeof(uint32_t)); log->size += sizeof(uint32_t); } memcpy((log->buffer) + log->size, &data, sizeof(int16_t)); log->size += sizeof(int16_t); log->args_num++; return DLT_RETURN_OK; } DltReturnValue dlt_user_log_write_int32(DltContextData *log, int32_t data) { uint32_t type_info; if (log == NULL) return DLT_RETURN_WRONG_PARAMETER; if (!dlt_user_initialised) { dlt_vlog(LOG_WARNING, "%s dlt_user_initialised false\n", __FUNCTION__); return DLT_RETURN_ERROR; } if ((log->size + sizeof(int32_t)) > dlt_user.log_buf_len) return DLT_RETURN_USER_BUFFER_FULL; if (dlt_user.verbose_mode) { if ((log->size + sizeof(uint32_t) + sizeof(int32_t)) > dlt_user.log_buf_len) return DLT_RETURN_USER_BUFFER_FULL; type_info = DLT_TYPE_INFO_SINT | DLT_TYLE_32BIT; memcpy((log->buffer) + log->size, &(type_info), sizeof(uint32_t)); log->size += sizeof(uint32_t); } memcpy((log->buffer) + log->size, &data, sizeof(int32_t)); log->size += sizeof(int32_t); log->args_num++; return DLT_RETURN_OK; } DltReturnValue dlt_user_log_write_int64(DltContextData *log, int64_t data) { uint32_t type_info; if (log == NULL) return DLT_RETURN_WRONG_PARAMETER; if (!dlt_user_initialised) { dlt_vlog(LOG_WARNING, "%s dlt_user_initialised false\n", __FUNCTION__); return DLT_RETURN_ERROR; } if ((log->size + sizeof(int64_t)) > dlt_user.log_buf_len) return DLT_RETURN_USER_BUFFER_FULL; if (dlt_user.verbose_mode) { if ((log->size + sizeof(uint32_t) + sizeof(int64_t)) > dlt_user.log_buf_len) return DLT_RETURN_USER_BUFFER_FULL; type_info = DLT_TYPE_INFO_SINT | DLT_TYLE_64BIT; memcpy((log->buffer) + log->size, &(type_info), sizeof(uint32_t)); log->size += sizeof(uint32_t); } memcpy((log->buffer) + log->size, &data, sizeof(int64_t)); log->size += sizeof(int64_t); log->args_num++; return DLT_RETURN_OK; } DltReturnValue dlt_user_log_write_bool(DltContextData *log, uint8_t data) { uint32_t type_info; if (log == NULL) return DLT_RETURN_WRONG_PARAMETER; if (!dlt_user_initialised) { dlt_vlog(LOG_WARNING, "%s dlt_user_initialised false\n", __FUNCTION__); return DLT_RETURN_ERROR; } if ((log->size + sizeof(uint8_t)) > dlt_user.log_buf_len) return DLT_RETURN_USER_BUFFER_FULL; if (dlt_user.verbose_mode) { if ((log->size + sizeof(uint32_t) + sizeof(uint8_t)) > dlt_user.log_buf_len) return DLT_RETURN_USER_BUFFER_FULL; type_info = DLT_TYPE_INFO_BOOL; memcpy((log->buffer) + log->size, &(type_info), sizeof(uint32_t)); log->size += sizeof(uint32_t); } memcpy((log->buffer) + log->size, &data, sizeof(uint8_t)); log->size += sizeof(uint8_t); log->args_num++; return DLT_RETURN_OK; } DltReturnValue dlt_user_log_write_string(DltContextData *log, const char *text) { return dlt_user_log_write_string_utils(log, text, ASCII_STRING); } DltReturnValue dlt_user_log_write_constant_string(DltContextData *log, const char *text) { /* Send parameter only in verbose mode */ return dlt_user.verbose_mode ? dlt_user_log_write_string(log, text) : DLT_RETURN_OK; } DltReturnValue dlt_user_log_write_utf8_string(DltContextData *log, const char *text) { return dlt_user_log_write_string_utils(log, text, UTF8_STRING); } DltReturnValue dlt_user_log_write_string_utils(DltContextData *log, const char *text, const enum StringType type) { uint16_t arg_size = 0; uint32_t type_info = 0; size_t new_log_size = 0; DltReturnValue ret = DLT_RETURN_OK; size_t str_truncate_message_length = strlen(STR_TRUNCATED_MESSAGE) + 1; size_t max_payload_str_msg; if ((log == NULL) || (text == NULL)) return DLT_RETURN_WRONG_PARAMETER; if (!dlt_user_initialised) { dlt_vlog(LOG_WARNING, "%s dlt_user_initialised false\n", __FUNCTION__); return DLT_RETURN_ERROR; } arg_size = strlen(text) + 1; new_log_size = log->size + arg_size + sizeof(uint16_t); if (dlt_user.verbose_mode) new_log_size += sizeof(uint32_t); /* Check log size condition */ if (new_log_size > dlt_user.log_buf_len) { ret = DLT_RETURN_USER_BUFFER_FULL; /* Re-calculate arg_size */ arg_size = dlt_user.log_buf_len - log->size - sizeof(uint16_t); size_t min_payload_str_truncate_msg = log->size + str_truncate_message_length + sizeof(uint16_t); if (dlt_user.verbose_mode) { min_payload_str_truncate_msg += sizeof(uint32_t); arg_size -= sizeof(uint32_t); } /* Return when dlt_user.log_buf_len does not have enough space for min_payload_str_truncate_msg */ if (min_payload_str_truncate_msg > dlt_user.log_buf_len) { dlt_vlog(LOG_WARNING, "%s not enough minimum space to store data\n", __FUNCTION__); return ret; } /* Calculate the maximum size of string will be copied after truncate */ max_payload_str_msg = dlt_user.log_buf_len - min_payload_str_truncate_msg; if (type == UTF8_STRING) { /** * Adjust the lengh to truncate one utf8 character corectly * refer: https://en.wikipedia.org/wiki/UTF-8 * one utf8 character will have maximum 4 bytes then maximum bytes will be truncate additional is 3 */ const char *tmp = (text + max_payload_str_msg - 3); uint16_t reduce_size = 0; if (tmp[2] & 0x80) { /* Is the last byte of truncated text is the first byte in multi-byte sequence (utf8 2 bytes) */ if (tmp[2] & 0x40) reduce_size = 1; /* Is the next to last byte of truncated text is the first byte in multi-byte sequence (utf8 3 bytes) */ else if ((tmp[1] & 0xe0) == 0xe0) reduce_size = 2; /* utf8 4 bytes */ else if ((tmp[0] & 0xf0) == 0xf0) reduce_size = 3; } max_payload_str_msg -= reduce_size; arg_size -= reduce_size; } } if (dlt_user.verbose_mode) { switch (type) { case ASCII_STRING: { type_info = DLT_TYPE_INFO_STRG | DLT_SCOD_ASCII; break; } case UTF8_STRING: { type_info = DLT_TYPE_INFO_STRG | DLT_SCOD_UTF8; break; } default: { /* Do nothing */ break; } } memcpy((log->buffer) + log->size, &(type_info), sizeof(uint32_t)); log->size += sizeof(uint32_t); } memcpy((log->buffer) + log->size, &(arg_size), sizeof(uint16_t)); log->size += sizeof(uint16_t); switch (ret) { case DLT_RETURN_OK: { /* Whole string will be copied */ memcpy((log->buffer) + log->size, text, arg_size); log->size += arg_size; break; } case DLT_RETURN_USER_BUFFER_FULL: { /* Only copy partial string */ memcpy((log->buffer) + log->size, text, max_payload_str_msg); log->size += max_payload_str_msg; /* Append string truncate the input string */ memcpy((log->buffer) + log->size, STR_TRUNCATED_MESSAGE, str_truncate_message_length); log->size += str_truncate_message_length; break; } default: { /* Do nothing */ break; } } log->args_num++; return ret; } DltReturnValue dlt_register_injection_callback_with_id(DltContext *handle, uint32_t service_id, dlt_injection_callback_id dlt_injection_cbk, void *priv) { DltContextData log; uint32_t i, j, k; int found = 0; DltUserInjectionCallback *old; if (dlt_user_log_init(handle, &log) < DLT_RETURN_OK) return DLT_RETURN_ERROR; if (service_id < DLT_USER_INJECTION_MIN) return DLT_RETURN_WRONG_PARAMETER; /* This function doesn't make sense storing to local file is choosen; * so terminate this function */ if (dlt_user.dlt_is_file) return DLT_RETURN_OK; DLT_SEM_LOCK(); if (dlt_user.dlt_ll_ts == NULL) { DLT_SEM_FREE(); return DLT_RETURN_OK; } /* Insert callback in corresponding table */ i = handle->log_level_pos; /* Insert each service_id only once */ for (k = 0; k < dlt_user.dlt_ll_ts[i].nrcallbacks; k++) if ((dlt_user.dlt_ll_ts[i].injection_table) && (dlt_user.dlt_ll_ts[i].injection_table[k].service_id == service_id)) { found = 1; break; } if (found) { j = k; } else { j = dlt_user.dlt_ll_ts[i].nrcallbacks; /* Allocate or expand injection table */ if (dlt_user.dlt_ll_ts[i].injection_table == NULL) { dlt_user.dlt_ll_ts[i].injection_table = (DltUserInjectionCallback *)malloc(sizeof(DltUserInjectionCallback)); if (dlt_user.dlt_ll_ts[i].injection_table == NULL) { DLT_SEM_FREE(); return DLT_RETURN_ERROR; } } else { old = dlt_user.dlt_ll_ts[i].injection_table; dlt_user.dlt_ll_ts[i].injection_table = (DltUserInjectionCallback *)malloc( sizeof(DltUserInjectionCallback) * (j + 1)); if (dlt_user.dlt_ll_ts[i].injection_table == NULL) { dlt_user.dlt_ll_ts[i].injection_table = old; DLT_SEM_FREE(); return DLT_RETURN_ERROR; } memcpy(dlt_user.dlt_ll_ts[i].injection_table, old, sizeof(DltUserInjectionCallback) * j); free(old); } dlt_user.dlt_ll_ts[i].nrcallbacks++; } /* Store service_id and corresponding function pointer for callback function */ dlt_user.dlt_ll_ts[i].injection_table[j].service_id = service_id; if (priv == NULL) { dlt_user.dlt_ll_ts[i].injection_table[j].injection_callback = (dlt_injection_callback)dlt_injection_cbk; dlt_user.dlt_ll_ts[i].injection_table[j].injection_callback_with_id = NULL; dlt_user.dlt_ll_ts[i].injection_table[j].data = NULL; } else { dlt_user.dlt_ll_ts[i].injection_table[j].injection_callback = NULL; dlt_user.dlt_ll_ts[i].injection_table[j].injection_callback_with_id = dlt_injection_cbk; dlt_user.dlt_ll_ts[i].injection_table[j].data = priv; } DLT_SEM_FREE(); return DLT_RETURN_OK; } DltReturnValue dlt_register_injection_callback(DltContext *handle, uint32_t service_id, int (*dlt_injection_callback)(uint32_t service_id, void *data, uint32_t length)) { return dlt_register_injection_callback_with_id(handle, service_id, (dlt_injection_callback_id)dlt_injection_callback, NULL); } DltReturnValue dlt_register_log_level_changed_callback(DltContext *handle, void (*dlt_log_level_changed_callback)( char context_id[DLT_ID_SIZE], uint8_t log_level, uint8_t trace_status)) { DltContextData log; uint32_t i; if (dlt_user_log_init(handle, &log) < DLT_RETURN_OK) return DLT_RETURN_ERROR; /* This function doesn't make sense storing to local file is choosen; * so terminate this function */ if (dlt_user.dlt_is_file) return DLT_RETURN_OK; DLT_SEM_LOCK(); if (dlt_user.dlt_ll_ts == NULL) { DLT_SEM_FREE(); return DLT_RETURN_OK; } /* Insert callback in corresponding table */ i = handle->log_level_pos; /* Store new callback function */ dlt_user.dlt_ll_ts[i].log_level_changed_callback = dlt_log_level_changed_callback; DLT_SEM_FREE(); return DLT_RETURN_OK; } /** * NW Trace related */ int check_buffer(void) { int total_size, used_size; dlt_user_check_buffer(&total_size, &used_size); return (total_size - used_size < total_size / 2) ? -1 : 1; } /** * Send the start of a segment chain. * Returns DLT_RETURN_ERROR on failure */ DltReturnValue dlt_user_trace_network_segmented_start(uint32_t *id, DltContext *handle, DltNetworkTraceType nw_trace_type, uint16_t header_len, void *header, uint16_t payload_len) { DltContextData log; struct timeval tv; int ret = DLT_RETURN_ERROR; /* check null pointer */ if (id == NULL) return DLT_RETURN_WRONG_PARAMETER; if ((nw_trace_type < DLT_NW_TRACE_IPC) || (nw_trace_type >= DLT_NW_TRACE_MAX)) { dlt_vlog(LOG_ERR, "Network trace type %d is outside valid range", nw_trace_type); return DLT_RETURN_WRONG_PARAMETER; } if (dlt_user.dlt_ll_ts == NULL) return DLT_RETURN_ERROR; if (handle->trace_status_ptr && (*(handle->trace_status_ptr) == DLT_TRACE_STATUS_ON)) { /* initialize values */ if (dlt_user_log_init(handle, &log) < DLT_RETURN_OK) return DLT_RETURN_ERROR; if (log.buffer == NULL) { log.buffer = calloc(sizeof(unsigned char), dlt_user.log_buf_len); if (log.buffer == NULL) { dlt_vlog(LOG_ERR, "Cannot allocate buffer for DLT Log message\n"); return DLT_RETURN_ERROR; } } log.args_num = 0; log.trace_status = nw_trace_type; log.size = 0; gettimeofday(&tv, NULL); *id = tv.tv_usec; /* Write identifier */ if (dlt_user_log_write_string(&log, DLT_TRACE_NW_START) < 0) { dlt_user_free_buffer(&(log.buffer)); return DLT_RETURN_ERROR; } /* Write stream handle */ if (dlt_user_log_write_uint32(&log, *id) < 0) { dlt_user_free_buffer(&(log.buffer)); return DLT_RETURN_ERROR; } /* Write header */ if (dlt_user_log_write_raw(&log, header, header_len) < 0) { dlt_user_free_buffer(&(log.buffer)); return DLT_RETURN_ERROR; } /* Write size of payload */ if (dlt_user_log_write_uint32(&log, payload_len) < 0) { dlt_user_free_buffer(&(log.buffer)); return DLT_RETURN_ERROR; } /* Write expected segment count */ uint16_t segment_count = payload_len / DLT_MAX_TRACE_SEGMENT_SIZE + 1; /* If segments align perfectly with segment size, avoid sending empty segment */ if ((payload_len % DLT_MAX_TRACE_SEGMENT_SIZE) == 0) segment_count--; if (dlt_user_log_write_uint16(&log, segment_count) < 0) { dlt_user_free_buffer(&(log.buffer)); return DLT_RETURN_ERROR; } /* Write length of one segment */ if (dlt_user_log_write_uint16(&log, DLT_MAX_TRACE_SEGMENT_SIZE) < 0) { dlt_user_free_buffer(&(log.buffer)); return DLT_RETURN_ERROR; } /* Send log */ ret = dlt_user_log_send_log(&log, DLT_TYPE_NW_TRACE); dlt_user_free_buffer(&(log.buffer)); return ret; } return DLT_RETURN_OK; } DltReturnValue dlt_user_trace_network_segmented_segment(uint32_t id, DltContext *handle, DltNetworkTraceType nw_trace_type, int sequence, uint16_t payload_len, void *payload) { int ret = DLT_RETURN_ERROR; struct timespec ts; if ((nw_trace_type < DLT_NW_TRACE_IPC) || (nw_trace_type >= DLT_NW_TRACE_MAX)) { dlt_vlog(LOG_ERR, "Network trace type %d is outside valid range", nw_trace_type); return DLT_RETURN_WRONG_PARAMETER; } while (check_buffer() < 0) { /* Wait 50ms */ ts.tv_sec = 0; ts.tv_nsec = 1000000 * 50; nanosleep(&ts, NULL); dlt_user_log_resend_buffer(); } if (dlt_user.dlt_ll_ts == NULL) return DLT_RETURN_ERROR; if (handle->trace_status_ptr && (*(handle->trace_status_ptr) == DLT_TRACE_STATUS_ON)) { DltContextData log; if (dlt_user_log_init(handle, &log) < DLT_RETURN_OK) return DLT_RETURN_ERROR; /* initialize values */ if (log.buffer == NULL) { log.buffer = calloc(sizeof(unsigned char), dlt_user.log_buf_len); if (log.buffer == NULL) { dlt_vlog(LOG_ERR, "Cannot allocate buffer for DLT Log message\n"); return DLT_RETURN_ERROR; } } log.args_num = 0; log.trace_status = nw_trace_type; log.size = 0; /* Write identifier */ if (dlt_user_log_write_string(&log, DLT_TRACE_NW_SEGMENT) < DLT_RETURN_OK) { dlt_user_free_buffer(&(log.buffer)); return DLT_RETURN_ERROR; } /* Write stream handle */ if (dlt_user_log_write_uint32(&log, id) < DLT_RETURN_OK) { dlt_user_free_buffer(&(log.buffer)); return DLT_RETURN_ERROR; } /* Write segment sequence number */ if (dlt_user_log_write_uint16(&log, sequence) < DLT_RETURN_OK) { dlt_user_free_buffer(&(log.buffer)); return DLT_RETURN_ERROR; } /* Write data */ if (dlt_user_log_write_raw(&log, payload, payload_len) < DLT_RETURN_OK) { dlt_user_free_buffer(&(log.buffer)); return DLT_RETURN_ERROR; } ret = dlt_user_log_send_log(&log, DLT_TYPE_NW_TRACE); /* Send log */ dlt_user_free_buffer(&(log.buffer)); return ret; } /* Allow other threads to log between chunks */ sched_yield(); return DLT_RETURN_OK; } DltReturnValue dlt_user_trace_network_segmented_end(uint32_t id, DltContext *handle, DltNetworkTraceType nw_trace_type) { DltContextData log; int ret = DLT_RETURN_ERROR; if ((nw_trace_type < DLT_NW_TRACE_IPC) || (nw_trace_type >= DLT_NW_TRACE_MAX)) { dlt_vlog(LOG_ERR, "Network trace type %d is outside valid range", nw_trace_type); return DLT_RETURN_WRONG_PARAMETER; } if (dlt_user.dlt_ll_ts == NULL) return DLT_RETURN_ERROR; if (handle->trace_status_ptr && (*(handle->trace_status_ptr) == DLT_TRACE_STATUS_ON)) { /* initialize values */ if (dlt_user_log_init(handle, &log) < DLT_RETURN_OK) return DLT_RETURN_ERROR; /* initialize values */ if (log.buffer == NULL) { log.buffer = calloc(sizeof(unsigned char), dlt_user.log_buf_len); if (log.buffer == NULL) { dlt_vlog(LOG_ERR, "Cannot allocate buffer for DLT Log message\n"); return DLT_RETURN_ERROR; } } log.args_num = 0; log.trace_status = nw_trace_type; log.size = 0; /* Write identifier */ if (dlt_user_log_write_string(&log, DLT_TRACE_NW_END) < DLT_RETURN_OK) { dlt_user_free_buffer(&(log.buffer)); return DLT_RETURN_ERROR; } /* Write stream handle */ if (dlt_user_log_write_uint32(&log, id) < DLT_RETURN_OK) { dlt_user_free_buffer(&(log.buffer)); return DLT_RETURN_ERROR; } ret = dlt_user_log_send_log(&log, DLT_TYPE_NW_TRACE); /* Send log */ dlt_user_free_buffer(&(log.buffer)); return ret; } return DLT_RETURN_OK; } void dlt_user_trace_network_segmented_thread(void *unused) { /* Unused on purpose. */ (void)unused; #ifdef linux prctl(PR_SET_NAME, "dlt_segmented", 0, 0, 0); #endif pthread_cleanup_push(dlt_user_cleanup_handler, NULL); s_segmented_data *data; while (1) { /* Wait until message queue is initialized */ dlt_lock_mutex(&mq_mutex); if (dlt_user.dlt_segmented_queue_read_handle < 0) pthread_cond_wait(&mq_init_condition, &mq_mutex); dlt_unlock_mutex(&mq_mutex); ssize_t read = mq_receive(dlt_user.dlt_segmented_queue_read_handle, (char *)&data, sizeof(s_segmented_data *), NULL); if (read < 0) { if (errno != EINTR) { struct timespec req; long sec = (DLT_USER_MQ_ERROR_RETRY_INTERVAL / 1000000); dlt_vlog(LOG_WARNING, "NWTSegmented: Error while reading queue: %s\n", strerror(errno)); req.tv_sec = sec; req.tv_nsec = (DLT_USER_MQ_ERROR_RETRY_INTERVAL - sec * 1000000) * 1000; nanosleep(&req, NULL); } continue; } if (read != sizeof(s_segmented_data *)) { /* This case will not happen. */ /* When this thread is interrupted by signal, mq_receive() will not return */ /* partial read length and will return -1. And also no data is removed from mq. */ dlt_vlog(LOG_WARNING, "NWTSegmented: Could not read data fully from queue: %zd\n", read); continue; } /* Indicator just to try to flush the buffer */ /* DLT_NW_TRACE_RESEND custom type is used to mark a resend */ if (data->nw_trace_type == DLT_NW_TRACE_RESEND) { struct timespec req; /* Sleep 100ms, to allow other process to read FIFO */ req.tv_sec = 0; req.tv_nsec = 100 * 1000 * 1000; nanosleep(&req, NULL); if (dlt_user_log_resend_buffer() < 0) { /* Requeue if still not empty */ if (dlt_user_queue_resend() < 0) { /*dlt_log(LOG_WARNING, "Failed to queue resending in dlt_user_trace_network_segmented_thread.\n"); */ } } free(data); continue; } dlt_user_trace_network_segmented_thread_segmenter(data); /* Send the end message */ DltReturnValue err = dlt_user_trace_network_segmented_end(data->id, data->handle, data->nw_trace_type); if ((err == DLT_RETURN_BUFFER_FULL) || (err == DLT_RETURN_ERROR)) dlt_log(LOG_WARNING, "NWTSegmented: Could not send end segment.\n"); /* Free resources */ free(data->header); free(data->payload); free(data); } pthread_cleanup_pop(1); } void dlt_user_trace_network_segmented_thread_segmenter(s_segmented_data *data) { /* Segment the data and send the chunks */ void *ptr = NULL; uint32_t offset = 0; uint16_t sequence = 0; do { uint16_t len = 0; if (offset + DLT_MAX_TRACE_SEGMENT_SIZE > data->payload_len) len = data->payload_len - offset; else len = DLT_MAX_TRACE_SEGMENT_SIZE; /* If payload size aligns perfectly with segment size, avoid sending empty segment */ if (len == 0) break; ptr = data->payload + offset; DltReturnValue err = dlt_user_trace_network_segmented_segment(data->id, data->handle, data->nw_trace_type, sequence++, len, ptr); if ((err == DLT_RETURN_BUFFER_FULL) || (err == DLT_RETURN_ERROR)) { dlt_log(LOG_ERR, "NWTSegmented: Could not send segment. Aborting.\n"); break; /* loop */ } offset += len; } while (ptr < data->payload + data->payload_len); } DltReturnValue dlt_user_trace_network_segmented(DltContext *handle, DltNetworkTraceType nw_trace_type, uint16_t header_len, void *header, uint16_t payload_len, void *payload) { /* Send as normal trace if possible */ if (header_len + payload_len + sizeof(uint16_t) < dlt_user.log_buf_len) return dlt_user_trace_network(handle, nw_trace_type, header_len, header, payload_len, payload); /* Allocate Memory */ s_segmented_data *thread_data = malloc(sizeof(s_segmented_data)); if (thread_data == NULL) return DLT_RETURN_ERROR; thread_data->header = malloc(header_len); if (thread_data->header == NULL) { free(thread_data); return DLT_RETURN_ERROR; } thread_data->payload = malloc(payload_len); if (thread_data->payload == NULL) { free(thread_data->header); free(thread_data); return DLT_RETURN_ERROR; } /* Copy data */ thread_data->handle = handle; thread_data->nw_trace_type = nw_trace_type; thread_data->header_len = header_len; memcpy(thread_data->header, header, header_len); thread_data->payload_len = payload_len; memcpy(thread_data->payload, payload, payload_len); /* Send start message */ DltReturnValue err = dlt_user_trace_network_segmented_start(&(thread_data->id), thread_data->handle, thread_data->nw_trace_type, thread_data->header_len, thread_data->header, thread_data->payload_len); if ((err == DLT_RETURN_BUFFER_FULL) || (err == DLT_RETURN_ERROR)) { dlt_log(LOG_ERR, "NWTSegmented: Could not send start segment. Aborting.\n"); free(thread_data->header); free(thread_data->payload); free(thread_data); return DLT_RETURN_ERROR; } /* Open queue if it is not open */ if (dlt_init_message_queue() < 0) { dlt_log(LOG_ERR, "NWTSegmented: Could not open queue.\n"); free(thread_data->header); free(thread_data->payload); free(thread_data); return DLT_RETURN_ERROR; } /* Add to queue */ if (mq_send(dlt_user.dlt_segmented_queue_write_handle, (char *)&thread_data, sizeof(s_segmented_data *), 1) < 0) { if (errno == EAGAIN) dlt_log(LOG_WARNING, "NWTSegmented: Queue full. Message discarded.\n"); free(thread_data->header); free(thread_data->payload); free(thread_data); dlt_vnlog(LOG_WARNING, 256, "NWTSegmented: Could not write into queue: %s \n", strerror(errno)); return DLT_RETURN_ERROR; } /*thread_data will be freed by the receiver function */ /*coverity[leaked_storage] */ return DLT_RETURN_OK; } DltReturnValue dlt_user_trace_network(DltContext *handle, DltNetworkTraceType nw_trace_type, uint16_t header_len, void *header, uint16_t payload_len, void *payload) { return dlt_user_trace_network_truncated(handle, nw_trace_type, header_len, header, payload_len, payload, 1); } DltReturnValue dlt_user_trace_network_truncated(DltContext *handle, DltNetworkTraceType nw_trace_type, uint16_t header_len, void *header, uint16_t payload_len, void *payload, int allow_truncate) { int ret = DLT_RETURN_ERROR; if ((payload == NULL) && (payload_len > 0)) return DLT_RETURN_WRONG_PARAMETER; DltContextData log; if ((nw_trace_type < DLT_NW_TRACE_IPC) || (nw_trace_type >= DLT_NW_TRACE_MAX)) { dlt_vlog(LOG_ERR, "Network trace type %d is outside valid range", nw_trace_type); return DLT_RETURN_WRONG_PARAMETER; } if (dlt_user.dlt_ll_ts == NULL) return DLT_RETURN_ERROR; if (handle->trace_status_ptr && (*(handle->trace_status_ptr) == DLT_TRACE_STATUS_ON)) { if ((dlt_user_log_init(handle, &log) < DLT_RETURN_OK) || (dlt_user.dlt_ll_ts == NULL)) return DLT_RETURN_ERROR; /* initialize values */ if (log.buffer == NULL) { log.buffer = calloc(sizeof(unsigned char), dlt_user.log_buf_len); if (log.buffer == NULL) { dlt_vlog(LOG_ERR, "Cannot allocate buffer for DLT Log message\n"); return DLT_RETURN_ERROR; } } log.args_num = 0; log.trace_status = nw_trace_type; log.size = 0; if (header == NULL) header_len = 0; /* If truncation is allowed, check if we must do it */ if ((allow_truncate > 0) && ((header_len + payload_len + sizeof(uint16_t)) > dlt_user.log_buf_len)) { /* Identify as truncated */ if (dlt_user_log_write_string(&log, DLT_TRACE_NW_END) < DLT_RETURN_OK) { dlt_user_free_buffer(&(log.buffer)); return DLT_RETURN_ERROR; } /* Write header and its length */ if (dlt_user_log_write_raw(&log, header, header_len) < DLT_RETURN_OK) { dlt_user_free_buffer(&(log.buffer)); return DLT_RETURN_ERROR; } /* Write original size of payload */ if (dlt_user_log_write_uint32(&log, payload_len) < DLT_RETURN_OK) { dlt_user_free_buffer(&(log.buffer)); return DLT_RETURN_ERROR; } /** * Calculate maximum available space in sending buffer after headers. */ int truncated_payload_len = dlt_user.log_buf_len - log.size - sizeof(uint16_t) - sizeof(uint32_t); /* Write truncated payload */ if (dlt_user_log_write_raw(&log, payload, truncated_payload_len) < DLT_RETURN_OK) { dlt_user_free_buffer(&(log.buffer)); return DLT_RETURN_ERROR; } } else { /* Truncation not allowed or data short enough */ /* Write header and its length */ if (dlt_user_log_write_raw(&log, header, header_len) < DLT_RETURN_OK) { dlt_user_free_buffer(&(log.buffer)); return DLT_RETURN_ERROR; } if (payload == NULL) payload_len = 0; /* Write payload and its length */ if (dlt_user_log_write_raw(&log, payload, payload_len) < DLT_RETURN_OK) { dlt_user_free_buffer(&(log.buffer)); return DLT_RETURN_ERROR; } } ret = dlt_user_log_send_log(&log, DLT_TYPE_NW_TRACE); dlt_user_free_buffer(&(log.buffer)); /* Send log */ return ret; } return DLT_RETURN_OK; } DltReturnValue dlt_log_string(DltContext *handle, DltLogLevelType loglevel, const char *text) { DltReturnValue ret = DLT_RETURN_OK; DltContextData log; if (dlt_user.verbose_mode == 0) return DLT_RETURN_ERROR; if ((handle == NULL) || (text == NULL)) return DLT_RETURN_WRONG_PARAMETER; if (dlt_user_log_write_start(handle, &log, loglevel) == DLT_RETURN_TRUE) { ret = dlt_user_log_write_string(&log, text); if (dlt_user_log_write_finish(&log) < DLT_RETURN_OK) ret = DLT_RETURN_ERROR; } return ret; } DltReturnValue dlt_log_string_int(DltContext *handle, DltLogLevelType loglevel, const char *text, int data) { DltReturnValue ret = DLT_RETURN_OK; DltContextData log; if (dlt_user.verbose_mode == 0) return DLT_RETURN_ERROR; if ((handle == NULL) || (text == NULL)) return DLT_RETURN_WRONG_PARAMETER; if (dlt_user_log_write_start(handle, &log, loglevel) == DLT_RETURN_TRUE) { ret = dlt_user_log_write_string(&log, text); dlt_user_log_write_int(&log, data); if (dlt_user_log_write_finish(&log) < DLT_RETURN_OK) ret = DLT_RETURN_ERROR; } return ret; } DltReturnValue dlt_log_string_uint(DltContext *handle, DltLogLevelType loglevel, const char *text, unsigned int data) { DltReturnValue ret = DLT_RETURN_OK; DltContextData log; if (dlt_user.verbose_mode == 0) return DLT_RETURN_ERROR; if ((handle == NULL) || (text == NULL)) return DLT_RETURN_WRONG_PARAMETER; if (dlt_user_log_write_start(handle, &log, loglevel) == DLT_RETURN_TRUE) { ret = dlt_user_log_write_string(&log, text); dlt_user_log_write_uint(&log, data); if (dlt_user_log_write_finish(&log) < DLT_RETURN_OK) ret = DLT_RETURN_ERROR; } return ret; } DltReturnValue dlt_log_int(DltContext *handle, DltLogLevelType loglevel, int data) { DltContextData log; if (dlt_user.verbose_mode == 0) return DLT_RETURN_ERROR; if (handle == NULL) return DLT_RETURN_ERROR; if (dlt_user_log_write_start(handle, &log, loglevel) == DLT_RETURN_TRUE) { dlt_user_log_write_int(&log, data); if (dlt_user_log_write_finish(&log) < DLT_RETURN_OK) return DLT_RETURN_ERROR; } return DLT_RETURN_OK; } DltReturnValue dlt_log_uint(DltContext *handle, DltLogLevelType loglevel, unsigned int data) { DltContextData log; if (dlt_user.verbose_mode == 0) return DLT_RETURN_ERROR; if (handle == NULL) return DLT_RETURN_WRONG_PARAMETER; if (dlt_user_log_write_start(handle, &log, loglevel) == DLT_RETURN_TRUE) { dlt_user_log_write_uint(&log, data); if (dlt_user_log_write_finish(&log) < DLT_RETURN_OK) return DLT_RETURN_ERROR; } return DLT_RETURN_OK; } DltReturnValue dlt_log_raw(DltContext *handle, DltLogLevelType loglevel, void *data, uint16_t length) { DltContextData log; DltReturnValue ret = DLT_RETURN_OK; if (dlt_user.verbose_mode == 0) return DLT_RETURN_ERROR; if (handle == NULL) return DLT_RETURN_WRONG_PARAMETER; if (dlt_user_log_write_start(handle, &log, loglevel) > 0) { if ((ret = dlt_user_log_write_raw(&log, data, length)) < DLT_RETURN_OK) { dlt_user_free_buffer(&(log.buffer)); return ret; } if (dlt_user_log_write_finish(&log) < DLT_RETURN_OK) return DLT_RETURN_ERROR; } return DLT_RETURN_OK; } DltReturnValue dlt_log_marker() { if (!dlt_user_initialised) { if (dlt_init() < DLT_RETURN_OK) { dlt_vlog(LOG_ERR, "%s Failed to initialise dlt", __FUNCTION__); return DLT_RETURN_ERROR; } } return dlt_user_log_send_marker(); } DltReturnValue dlt_verbose_mode(void) { if (!dlt_user_initialised) { if (dlt_init() < DLT_RETURN_OK) { dlt_vlog(LOG_ERR, "%s Failed to initialise dlt", __FUNCTION__); return DLT_RETURN_ERROR; } } /* Switch to verbose mode */ dlt_user.verbose_mode = 1; return DLT_RETURN_OK; } DltReturnValue dlt_nonverbose_mode(void) { if (!dlt_user_initialised) { if (dlt_init() < DLT_RETURN_OK) { dlt_vlog(LOG_ERR, "%s Failed to initialise dlt", __FUNCTION__); return DLT_RETURN_ERROR; } } /* Switch to non-verbose mode */ dlt_user.verbose_mode = 0; return DLT_RETURN_OK; } DltReturnValue dlt_use_extended_header_for_non_verbose(int8_t use_extende_header_for_non_verbose) { if (!dlt_user_initialised) { if (dlt_init() < DLT_RETURN_OK) { dlt_vlog(LOG_ERR, "%s Failed to initialise dlt", __FUNCTION__); return DLT_RETURN_ERROR; } } /* Set use_extende_header_for_non_verbose */ dlt_user.use_extende_header_for_non_verbose = use_extende_header_for_non_verbose; return DLT_RETURN_OK; } DltReturnValue dlt_with_session_id(int8_t with_session_id) { if (!dlt_user_initialised) { if (dlt_init() < DLT_RETURN_OK) { dlt_vlog(LOG_ERR, "%s Failed to initialise dlt", __FUNCTION__); return DLT_RETURN_ERROR; } } /* Set use_extende_header_for_non_verbose */ dlt_user.with_session_id = with_session_id; return DLT_RETURN_OK; } DltReturnValue dlt_with_timestamp(int8_t with_timestamp) { if (!dlt_user_initialised) { if (dlt_init() < DLT_RETURN_OK) { dlt_vlog(LOG_ERR, "%s Failed to initialise dlt", __FUNCTION__); return DLT_RETURN_ERROR; } } /* Set with_timestamp */ dlt_user.with_timestamp = with_timestamp; return DLT_RETURN_OK; } DltReturnValue dlt_with_ecu_id(int8_t with_ecu_id) { if (!dlt_user_initialised) { if (dlt_init() < DLT_RETURN_OK) { dlt_vlog(LOG_ERR, "%s Failed to initialise dlt", __FUNCTION__); return DLT_RETURN_ERROR; } } /* Set with_timestamp */ dlt_user.with_ecu_id = with_ecu_id; return DLT_RETURN_OK; } DltReturnValue dlt_enable_local_print(void) { if (!dlt_user_initialised) { if (dlt_init() < DLT_RETURN_OK) { dlt_vlog(LOG_ERR, "%s Failed to initialise dlt", __FUNCTION__); return DLT_RETURN_ERROR; } } dlt_user.enable_local_print = 1; return DLT_RETURN_OK; } DltReturnValue dlt_disable_local_print(void) { if (!dlt_user_initialised) { if (dlt_init() < DLT_RETURN_OK) { dlt_vlog(LOG_ERR, "%s Failed to initialise dlt", __FUNCTION__); return DLT_RETURN_ERROR; } } dlt_user.enable_local_print = 0; return DLT_RETURN_OK; } /* Cleanup on thread cancellation, thread may hold lock release it here */ static void dlt_user_cleanup_handler(void *arg) { DLT_UNUSED(arg); /* Satisfy compiler */ /* unlock the message queue */ dlt_unlock_mutex(&mq_mutex); /* unlock DLT (dlt_mutex) */ DLT_SEM_FREE(); } void dlt_user_receiverthread_function(__attribute__((unused)) void *ptr) { struct timespec ts; #ifdef linux prctl(PR_SET_NAME, "dlt_receiver", 0, 0, 0); #endif pthread_cleanup_push(dlt_user_cleanup_handler, NULL); while (1) { /* Check for new messages from DLT daemon */ if (dlt_user_log_check_user_message() < DLT_RETURN_OK) /* Critical error */ dlt_log(LOG_CRIT, "Receiver thread encountered error condition\n"); /* delay */ ts.tv_sec = 0; ts.tv_nsec = DLT_USER_RECEIVE_NDELAY; nanosleep(&ts, NULL); } pthread_cleanup_pop(1); } /* Private functions of user library */ DltReturnValue dlt_user_log_init(DltContext *handle, DltContextData *log) { int ret = DLT_RETURN_OK; if ((handle == NULL) || (log == NULL)) return DLT_RETURN_WRONG_PARAMETER; if (!dlt_user_initialised) { ret = dlt_init(); if (ret < DLT_RETURN_OK) { if (ret != DLT_RETURN_LOGGING_DISABLED) dlt_vlog(LOG_ERR, "%s Failed to initialise dlt", __FUNCTION__); return ret; } } log->handle = handle; log->buffer = NULL; return ret; } DltReturnValue dlt_user_queue_resend(void) { static unsigned char dlt_user_queue_resend_error_counter = 0; if (dlt_user.dlt_log_handle < 0) /* Fail silenty. FIFO is not open yet */ return DLT_RETURN_ERROR; /** * Ask segmented thread to try emptying the buffer soon. * This will be freed in dlt_user_trace_network_segmented_thread * */ s_segmented_data *resend_data = malloc(sizeof(s_segmented_data)); if (resend_data == NULL) return DLT_RETURN_ERROR; /* DLT_NW_TRACE_RESEND custom type is used to mark a resend */ resend_data->nw_trace_type = DLT_NW_TRACE_RESEND; /* Open queue if it is not open */ if (dlt_init_message_queue() < DLT_RETURN_OK) { if (!dlt_user_queue_resend_error_counter) /* log error only when problem occurred first time */ dlt_log(LOG_WARNING, "NWTSegmented: Could not open queue.\n"); dlt_user_queue_resend_error_counter = 1; free(resend_data); return DLT_RETURN_ERROR; } if (mq_send(dlt_user.dlt_segmented_queue_write_handle, (char *)&resend_data, sizeof(s_segmented_data *), 1) < 0) { if (!dlt_user_queue_resend_error_counter) /* log error only when problem occurred first time */ dlt_vnlog(LOG_DEBUG, 256, "Could not request resending.: %s \n", strerror(errno)); dlt_user_queue_resend_error_counter = 1; free(resend_data); return DLT_RETURN_ERROR; } dlt_user_queue_resend_error_counter = 0; /*thread_data will be freed by the receiver function */ /*coverity[leaked_storage] */ return DLT_RETURN_OK; } DltReturnValue dlt_user_log_send_log(DltContextData *log, int mtype) { DltMessage msg; DltUserHeader userheader; int32_t len; DltReturnValue ret = DLT_RETURN_OK; if (!dlt_user_initialised) { dlt_vlog(LOG_ERR, "%s dlt_user_initialised false\n", __FUNCTION__); return DLT_RETURN_ERROR; } if ((log == NULL) || (log->handle == NULL) || (log->handle->contextID[0] == '\0') || (mtype < DLT_TYPE_LOG) || (mtype > DLT_TYPE_CONTROL) ) return DLT_RETURN_WRONG_PARAMETER; /* also for Trace messages */ #ifdef DLT_SHM_ENABLE if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_LOG_SHM) < DLT_RETURN_OK) #else if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_LOG) < DLT_RETURN_OK) #endif return DLT_RETURN_ERROR; if (dlt_message_init(&msg, 0) == DLT_RETURN_ERROR) return DLT_RETURN_ERROR; msg.storageheader = (DltStorageHeader *)msg.headerbuffer; if (dlt_set_storageheader(msg.storageheader, dlt_user.ecuID) == DLT_RETURN_ERROR) return DLT_RETURN_ERROR; msg.standardheader = (DltStandardHeader *)(msg.headerbuffer + sizeof(DltStorageHeader)); msg.standardheader->htyp = DLT_HTYP_PROTOCOL_VERSION1; /* send ecu id */ if (dlt_user.with_ecu_id) msg.standardheader->htyp |= DLT_HTYP_WEID; /* send timestamp */ if (dlt_user.with_timestamp) msg.standardheader->htyp |= DLT_HTYP_WTMS; /* send session id */ if (dlt_user.with_session_id) { msg.standardheader->htyp |= DLT_HTYP_WSID; msg.headerextra.seid = getpid(); } if (dlt_user.verbose_mode) /* In verbose mode, send extended header */ msg.standardheader->htyp = (msg.standardheader->htyp | DLT_HTYP_UEH); else /* In non-verbose, send extended header if desired */ if (dlt_user.use_extende_header_for_non_verbose) msg.standardheader->htyp = (msg.standardheader->htyp | DLT_HTYP_UEH); #if (BYTE_ORDER == BIG_ENDIAN) msg.standardheader->htyp = (msg.standardheader->htyp | DLT_HTYP_MSBF); #endif msg.standardheader->mcnt = log->handle->mcnt++; /* Set header extra parameters */ dlt_set_id(msg.headerextra.ecu, dlt_user.ecuID); /*msg.headerextra.seid = 0; */ msg.headerextra.tmsp = dlt_uptime(); if (dlt_message_set_extraparameters(&msg, 0) == DLT_RETURN_ERROR) return DLT_RETURN_ERROR; /* Fill out extended header, if extended header should be provided */ if (DLT_IS_HTYP_UEH(msg.standardheader->htyp)) { /* with extended header */ msg.extendedheader = (DltExtendedHeader *)(msg.headerbuffer + sizeof(DltStorageHeader) + sizeof(DltStandardHeader) + DLT_STANDARD_HEADER_EXTRA_SIZE(msg.standardheader->htyp)); switch (mtype) { case DLT_TYPE_LOG: { msg.extendedheader->msin = (DLT_TYPE_LOG << DLT_MSIN_MSTP_SHIFT) | ((log->log_level << DLT_MSIN_MTIN_SHIFT) & DLT_MSIN_MTIN); break; } case DLT_TYPE_NW_TRACE: { msg.extendedheader->msin = (DLT_TYPE_NW_TRACE << DLT_MSIN_MSTP_SHIFT) | ((log->trace_status << DLT_MSIN_MTIN_SHIFT) & DLT_MSIN_MTIN); break; } default: { /* This case should not occur */ return DLT_RETURN_ERROR; break; } } /* If in verbose mode, set flag in header for verbose mode */ if (dlt_user.verbose_mode) msg.extendedheader->msin |= DLT_MSIN_VERB; msg.extendedheader->noar = log->args_num; /* number of arguments */ dlt_set_id(msg.extendedheader->apid, dlt_user.appID); /* application id */ dlt_set_id(msg.extendedheader->ctid, log->handle->contextID); /* context id */ msg.headersize = sizeof(DltStorageHeader) + sizeof(DltStandardHeader) + sizeof(DltExtendedHeader) + DLT_STANDARD_HEADER_EXTRA_SIZE(msg.standardheader->htyp); } else { /* without extended header */ msg.headersize = sizeof(DltStorageHeader) + sizeof(DltStandardHeader) + DLT_STANDARD_HEADER_EXTRA_SIZE( msg.standardheader->htyp); } len = msg.headersize - sizeof(DltStorageHeader) + log->size; if (len > UINT16_MAX) { dlt_log(LOG_WARNING, "Huge message discarded!\n"); return DLT_RETURN_ERROR; } msg.standardheader->len = DLT_HTOBE_16(len); /* print to std out, if enabled */ if ((dlt_user.local_print_mode != DLT_PM_FORCE_OFF) && (dlt_user.local_print_mode != DLT_PM_AUTOMATIC)) { if ((dlt_user.enable_local_print) || (dlt_user.local_print_mode == DLT_PM_FORCE_ON)) if (dlt_user_print_msg(&msg, log) == DLT_RETURN_ERROR) return DLT_RETURN_ERROR; } if (dlt_user.dlt_is_file) { /* log to file */ ret = dlt_user_log_out2(dlt_user.dlt_log_handle, msg.headerbuffer, msg.headersize, log->buffer, log->size); return ret; } else { /* Reattach to daemon if neccesary */ dlt_user_log_reattach_to_daemon(); if (dlt_user.overflow_counter) { if (dlt_user_log_send_overflow() == DLT_RETURN_OK) { dlt_vnlog(LOG_WARNING, DLT_USER_BUFFER_LENGTH, "%u messages discarded!\n", dlt_user.overflow_counter); dlt_user.overflow_counter = 0; } } /* try to resent old data first */ ret = DLT_RETURN_OK; if ((dlt_user.dlt_log_handle != -1) && (dlt_user.appID[0] != '\0')) ret = dlt_user_log_resend_buffer(); if ((ret == DLT_RETURN_OK) && (dlt_user.appID[0] != '\0')) { /* resend ok or nothing to resent */ #ifdef DLT_SHM_ENABLE if (dlt_user.dlt_log_handle != -1) dlt_shm_push(&dlt_user.dlt_shm, msg.headerbuffer + sizeof(DltStorageHeader), msg.headersize - sizeof(DltStorageHeader), log->buffer, log->size, 0, 0); ret = dlt_user_log_out3(dlt_user.dlt_log_handle, &(userheader), sizeof(DltUserHeader), 0, 0, 0, 0); #else # ifdef DLT_TEST_ENABLE if (dlt_user.corrupt_user_header) { userheader.pattern[0] = 0xff; userheader.pattern[1] = 0xff; userheader.pattern[2] = 0xff; userheader.pattern[3] = 0xff; } if (dlt_user.corrupt_message_size) msg.standardheader->len = DLT_HTOBE_16(dlt_user.corrupt_message_size_size); # endif ret = dlt_user_log_out3(dlt_user.dlt_log_handle, &(userheader), sizeof(DltUserHeader), msg.headerbuffer + sizeof(DltStorageHeader), msg.headersize - sizeof(DltStorageHeader), log->buffer, log->size); #endif } /* store message in ringbuffer, if an error has occured */ if ((ret != DLT_RETURN_OK) || (dlt_user.appID[0] == '\0')) ret = dlt_user_log_out_error_handling(&(userheader), sizeof(DltUserHeader), msg.headerbuffer + sizeof(DltStorageHeader), msg.headersize - sizeof(DltStorageHeader), log->buffer, log->size); switch (ret) { case DLT_RETURN_BUFFER_FULL: { /* Buffer full */ dlt_user.overflow_counter += 1; return DLT_RETURN_BUFFER_FULL; } case DLT_RETURN_PIPE_FULL: { /* data could not be written */ return DLT_RETURN_PIPE_FULL; } case DLT_RETURN_PIPE_ERROR: { /* handle not open or pipe error */ close(dlt_user.dlt_log_handle); dlt_user.dlt_log_handle = -1; #ifdef DLT_USE_UNIX_SOCKET_IPC dlt_user.connection_state = DLT_USER_RETRY_CONNECT; #endif #ifdef DLT_SHM_ENABLE /* free shared memory */ dlt_shm_free_client(&dlt_user.dlt_shm); #endif if (dlt_user.local_print_mode == DLT_PM_AUTOMATIC) dlt_user_print_msg(&msg, log); return DLT_RETURN_PIPE_ERROR; } case DLT_RETURN_ERROR: { /* other error condition */ return DLT_RETURN_ERROR; } case DLT_RETURN_OK: { return DLT_RETURN_OK; } default: { /* This case should never occur. */ return DLT_RETURN_ERROR; } } } return DLT_RETURN_OK; } DltReturnValue dlt_user_log_send_register_application(void) { DltUserHeader userheader; DltUserControlMsgRegisterApplication usercontext; DltReturnValue ret; if (dlt_user.appID[0] == '\0') return DLT_RETURN_ERROR; /* set userheader */ if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_REGISTER_APPLICATION) < DLT_RETURN_OK) return DLT_RETURN_ERROR; /* set usercontext */ dlt_set_id(usercontext.apid, dlt_user.appID); /* application id */ usercontext.pid = getpid(); if (dlt_user.application_description != NULL) usercontext.description_length = strlen(dlt_user.application_description); else usercontext.description_length = 0; if (dlt_user.dlt_is_file) return DLT_RETURN_OK; ret = dlt_user_log_out3(dlt_user.dlt_log_handle, &(userheader), sizeof(DltUserHeader), &(usercontext), sizeof(DltUserControlMsgRegisterApplication), dlt_user.application_description, usercontext.description_length); /* store message in ringbuffer, if an error has occured */ if (ret < DLT_RETURN_OK) return dlt_user_log_out_error_handling(&(userheader), sizeof(DltUserHeader), &(usercontext), sizeof(DltUserControlMsgRegisterApplication), dlt_user.application_description, usercontext.description_length); return DLT_RETURN_OK; } DltReturnValue dlt_user_log_send_unregister_application(void) { DltUserHeader userheader; DltUserControlMsgUnregisterApplication usercontext; DltReturnValue ret = DLT_RETURN_OK; if (dlt_user.appID[0] == '\0') return DLT_RETURN_ERROR; /* set userheader */ if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_UNREGISTER_APPLICATION) < DLT_RETURN_OK) return DLT_RETURN_ERROR; /* set usercontext */ dlt_set_id(usercontext.apid, dlt_user.appID); /* application id */ usercontext.pid = getpid(); if (dlt_user.dlt_is_file) return DLT_RETURN_OK; ret = dlt_user_log_out2(dlt_user.dlt_log_handle, &(userheader), sizeof(DltUserHeader), &(usercontext), sizeof(DltUserControlMsgUnregisterApplication)); /* store message in ringbuffer, if an error has occured */ if (ret < DLT_RETURN_OK) return dlt_user_log_out_error_handling(&(userheader), sizeof(DltUserHeader), &(usercontext), sizeof(DltUserControlMsgUnregisterApplication), NULL, 0); return DLT_RETURN_OK; } DltReturnValue dlt_user_log_send_register_context(DltContextData *log) { DltUserHeader userheader; DltUserControlMsgRegisterContext usercontext; DltReturnValue ret = DLT_RETURN_ERROR; if (log == NULL) return DLT_RETURN_WRONG_PARAMETER; if (log->handle == NULL) return DLT_RETURN_ERROR; if (log->handle->contextID[0] == '\0') return DLT_RETURN_ERROR; /* set userheader */ if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_REGISTER_CONTEXT) < DLT_RETURN_OK) return DLT_RETURN_ERROR; /* set usercontext */ dlt_set_id(usercontext.apid, dlt_user.appID); /* application id */ dlt_set_id(usercontext.ctid, log->handle->contextID); /* context id */ usercontext.log_level_pos = log->handle->log_level_pos; usercontext.pid = getpid(); usercontext.log_level = (int8_t)log->log_level; usercontext.trace_status = (int8_t)log->trace_status; if (log->context_description != NULL) usercontext.description_length = strlen(log->context_description); else usercontext.description_length = 0; if (dlt_user.dlt_is_file) return DLT_RETURN_OK; if (dlt_user.appID[0] != '\0') ret = dlt_user_log_out3(dlt_user.dlt_log_handle, &(userheader), sizeof(DltUserHeader), &(usercontext), sizeof(DltUserControlMsgRegisterContext), log->context_description, usercontext.description_length); /* store message in ringbuffer, if an error has occured */ if ((ret != DLT_RETURN_OK) || (dlt_user.appID[0] == '\0')) return dlt_user_log_out_error_handling(&(userheader), sizeof(DltUserHeader), &(usercontext), sizeof(DltUserControlMsgRegisterContext), log->context_description, usercontext.description_length); return DLT_RETURN_OK; } DltReturnValue dlt_user_log_send_unregister_context(DltContextData *log) { DltUserHeader userheader; DltUserControlMsgUnregisterContext usercontext; DltReturnValue ret; if (log == NULL) return DLT_RETURN_WRONG_PARAMETER; if (log->handle == NULL) return DLT_RETURN_WRONG_PARAMETER; if (log->handle->contextID[0] == '\0') return DLT_RETURN_ERROR; /* set userheader */ if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_UNREGISTER_CONTEXT) < DLT_RETURN_OK) return DLT_RETURN_ERROR; /* set usercontext */ dlt_set_id(usercontext.apid, dlt_user.appID); /* application id */ dlt_set_id(usercontext.ctid, log->handle->contextID); /* context id */ usercontext.pid = getpid(); if (dlt_user.dlt_is_file) return DLT_RETURN_OK; ret = dlt_user_log_out2(dlt_user.dlt_log_handle, &(userheader), sizeof(DltUserHeader), &(usercontext), sizeof(DltUserControlMsgUnregisterContext)); /* store message in ringbuffer, if an error has occured */ if (ret < DLT_RETURN_OK) return dlt_user_log_out_error_handling(&(userheader), sizeof(DltUserHeader), &(usercontext), sizeof(DltUserControlMsgUnregisterContext), NULL, 0); return DLT_RETURN_OK; } DltReturnValue dlt_send_app_ll_ts_limit(const char *apid, DltLogLevelType loglevel, DltTraceStatusType tracestatus) { DltUserHeader userheader; DltUserControlMsgAppLogLevelTraceStatus usercontext; DltReturnValue ret; if ((loglevel < DLT_USER_LOG_LEVEL_NOT_SET) || (loglevel >= DLT_LOG_MAX)) { dlt_vlog(LOG_ERR, "Loglevel %d is outside valid range", loglevel); return DLT_RETURN_ERROR; } if ((tracestatus < DLT_USER_TRACE_STATUS_NOT_SET) || (tracestatus >= DLT_TRACE_STATUS_MAX)) { dlt_vlog(LOG_ERR, "Tracestatus %d is outside valid range", tracestatus); return DLT_RETURN_ERROR; } if ((apid == NULL) || (apid[0] == '\0')) return DLT_RETURN_ERROR; /* set userheader */ if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_APP_LL_TS) < DLT_RETURN_OK) return DLT_RETURN_ERROR; /* set usercontext */ dlt_set_id(usercontext.apid, apid); /* application id */ usercontext.log_level = loglevel; usercontext.trace_status = tracestatus; if (dlt_user.dlt_is_file) return DLT_RETURN_OK; ret = dlt_user_log_out2(dlt_user.dlt_log_handle, &(userheader), sizeof(DltUserHeader), &(usercontext), sizeof(DltUserControlMsgAppLogLevelTraceStatus)); /* store message in ringbuffer, if an error has occured */ if (ret < DLT_RETURN_OK) return dlt_user_log_out_error_handling(&(userheader), sizeof(DltUserHeader), &(usercontext), sizeof(DltUserControlMsgAppLogLevelTraceStatus), NULL, 0); return DLT_RETURN_OK; } DltReturnValue dlt_user_log_send_log_mode(DltUserLogMode mode) { DltUserHeader userheader; DltUserControlMsgLogMode logmode; DltReturnValue ret; if ((mode < DLT_USER_MODE_UNDEFINED) || (mode >= DLT_USER_MODE_MAX)) { dlt_vlog(LOG_ERR, "User log mode %d is outside valid range", mode); return DLT_RETURN_WRONG_PARAMETER; } /* set userheader */ if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_LOG_MODE) < DLT_RETURN_OK) return DLT_RETURN_ERROR; /* set data */ logmode.log_mode = (unsigned char)mode; if (dlt_user.dlt_is_file) return DLT_RETURN_OK; ret = dlt_user_log_out2(dlt_user.dlt_log_handle, &(userheader), sizeof(DltUserHeader), &(logmode), sizeof(DltUserControlMsgLogMode)); /* store message in ringbuffer, if an error has occured */ if (ret < DLT_RETURN_OK) return dlt_user_log_out_error_handling(&(userheader), sizeof(DltUserHeader), &(logmode), sizeof(DltUserControlMsgLogMode), NULL, 0); return DLT_RETURN_OK; } DltReturnValue dlt_user_log_send_marker() { DltUserHeader userheader; DltReturnValue ret; /* set userheader */ if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_MARKER) < DLT_RETURN_OK) return DLT_RETURN_ERROR; if (dlt_user.dlt_is_file) return DLT_RETURN_OK; /* log to FIFO */ ret = dlt_user_log_out2(dlt_user.dlt_log_handle, &(userheader), sizeof(DltUserHeader), 0, 0); /* store message in ringbuffer, if an error has occured */ if (ret < DLT_RETURN_OK) return dlt_user_log_out_error_handling(&(userheader), sizeof(DltUserHeader), NULL, 0, NULL, 0); return DLT_RETURN_OK; } DltReturnValue dlt_user_print_msg(DltMessage *msg, DltContextData *log) { uint8_t *databuffer_tmp; int32_t datasize_tmp; int32_t databuffersize_tmp; static char text[DLT_USER_TEXT_LENGTH]; if ((msg == NULL) || (log == NULL)) return DLT_RETURN_WRONG_PARAMETER; /* Save variables before print */ databuffer_tmp = msg->databuffer; datasize_tmp = msg->datasize; databuffersize_tmp = msg->databuffersize; /* Act like a receiver, convert header back to host format */ msg->standardheader->len = DLT_BETOH_16(msg->standardheader->len); dlt_message_get_extraparameters(msg, 0); msg->databuffer = log->buffer; msg->datasize = log->size; msg->databuffersize = log->size; /* Print message as ASCII */ if (dlt_message_print_ascii(msg, text, DLT_USER_TEXT_LENGTH, 0) == DLT_RETURN_ERROR) return DLT_RETURN_ERROR; /* Restore variables and set len to BE*/ msg->databuffer = databuffer_tmp; msg->databuffersize = databuffersize_tmp; msg->datasize = datasize_tmp; msg->standardheader->len = DLT_HTOBE_16(msg->standardheader->len); return DLT_RETURN_OK; } DltReturnValue dlt_user_log_check_user_message(void) { int offset = 0; int leave_while = 0; uint32_t i; int fd; DltUserHeader *userheader; DltReceiver *receiver = &(dlt_user.receiver); DltUserControlMsgLogLevel *usercontextll; DltUserControlMsgInjection *usercontextinj; DltUserControlMsgLogState *userlogstate; unsigned char *userbuffer; /* For delayed calling of injection callback, to avoid deadlock */ DltUserInjectionCallback delayed_injection_callback; DltUserLogLevelChangedCallback delayed_log_level_changed_callback; unsigned char *delayed_inject_buffer = 0; uint32_t delayed_inject_data_length = 0; /* Ensure that callback is null before searching for it */ delayed_injection_callback.injection_callback = 0; delayed_injection_callback.injection_callback_with_id = 0; delayed_injection_callback.service_id = 0; delayed_log_level_changed_callback.log_level_changed_callback = 0; delayed_injection_callback.data = 0; #ifdef DLT_USE_UNIX_SOCKET_IPC fd = dlt_user.dlt_log_handle; #else fd = dlt_user.dlt_user_handle; #endif if (fd != DLT_FD_INIT) { while (1) { if (dlt_receiver_receive(receiver, DLT_RECEIVE_FD) <= 0) /* No new message available */ return DLT_RETURN_OK; /* look through buffer as long as data is in there */ while (1) { if (receiver->bytesRcvd < (int32_t)sizeof(DltUserHeader)) break; /* resync if necessary */ offset = 0; do { userheader = (DltUserHeader *)(receiver->buf + offset); /* Check for user header pattern */ if (dlt_user_check_userheader(userheader)) break; offset++; } while ((int32_t)(sizeof(DltUserHeader) + offset) <= receiver->bytesRcvd); /* Check for user header pattern */ if ((dlt_user_check_userheader(userheader) < 0) || (dlt_user_check_userheader(userheader) == 0)) break; /* Set new start offset */ if (offset > 0) { receiver->buf += offset; receiver->bytesRcvd -= offset; } switch (userheader->message) { case DLT_USER_MESSAGE_LOG_LEVEL: { if (receiver->bytesRcvd < (int32_t)(sizeof(DltUserHeader) + sizeof(DltUserControlMsgLogLevel))) { leave_while = 1; break; } usercontextll = (DltUserControlMsgLogLevel *)(receiver->buf + sizeof(DltUserHeader)); /* Update log level and trace status */ if (usercontextll != NULL) { DLT_SEM_LOCK(); if ((usercontextll->log_level_pos >= 0) && (usercontextll->log_level_pos < (int32_t)dlt_user.dlt_ll_ts_num_entries)) { /* printf("Store ll, ts\n"); */ if (dlt_user.dlt_ll_ts) { dlt_user.dlt_ll_ts[usercontextll->log_level_pos].log_level = usercontextll->log_level; dlt_user.dlt_ll_ts[usercontextll->log_level_pos].trace_status = usercontextll->trace_status; if (dlt_user.dlt_ll_ts[usercontextll->log_level_pos].log_level_ptr) *(dlt_user.dlt_ll_ts[usercontextll->log_level_pos].log_level_ptr) = usercontextll->log_level; if (dlt_user.dlt_ll_ts[usercontextll->log_level_pos].trace_status_ptr) *(dlt_user.dlt_ll_ts[usercontextll->log_level_pos].trace_status_ptr) = usercontextll->trace_status; delayed_log_level_changed_callback.log_level_changed_callback = dlt_user.dlt_ll_ts[usercontextll->log_level_pos].log_level_changed_callback; memcpy(delayed_log_level_changed_callback.contextID, dlt_user.dlt_ll_ts[usercontextll->log_level_pos].contextID, DLT_ID_SIZE); delayed_log_level_changed_callback.log_level = usercontextll->log_level; delayed_log_level_changed_callback.trace_status = usercontextll->trace_status; } } DLT_SEM_FREE(); } /* call callback outside of semaphore */ if (delayed_log_level_changed_callback.log_level_changed_callback != 0) delayed_log_level_changed_callback.log_level_changed_callback( delayed_log_level_changed_callback.contextID, delayed_log_level_changed_callback.log_level, delayed_log_level_changed_callback.trace_status); /* keep not read data in buffer */ if (dlt_receiver_remove(receiver, sizeof(DltUserHeader) + sizeof(DltUserControlMsgLogLevel)) == DLT_RETURN_ERROR) return DLT_RETURN_ERROR; } break; case DLT_USER_MESSAGE_INJECTION: { /* At least, user header, user context, and service id and data_length of injected message is available */ if (receiver->bytesRcvd < (int32_t)(sizeof(DltUserHeader) + sizeof(DltUserControlMsgInjection))) { leave_while = 1; break; } usercontextinj = (DltUserControlMsgInjection *)(receiver->buf + sizeof(DltUserHeader)); userbuffer = (unsigned char *)(receiver->buf + sizeof(DltUserHeader) + sizeof(DltUserControlMsgInjection)); if (userbuffer != NULL) { if (receiver->bytesRcvd < (int32_t)(sizeof(DltUserHeader) + sizeof(DltUserControlMsgInjection) + usercontextinj->data_length_inject)) { leave_while = 1; break; } DLT_SEM_LOCK(); if ((usercontextinj->data_length_inject > 0) && (dlt_user.dlt_ll_ts)) /* Check if injection callback is registered for this context */ for (i = 0; i < dlt_user.dlt_ll_ts[usercontextinj->log_level_pos].nrcallbacks; i++) if ((dlt_user.dlt_ll_ts[usercontextinj->log_level_pos].injection_table) && (dlt_user.dlt_ll_ts[usercontextinj->log_level_pos].injection_table[i].service_id == usercontextinj->service_id)) { /* Prepare delayed injection callback call */ if (dlt_user.dlt_ll_ts[usercontextinj->log_level_pos].injection_table[i]. injection_callback != NULL) { delayed_injection_callback.injection_callback = dlt_user.dlt_ll_ts[usercontextinj->log_level_pos].injection_table[i]. injection_callback; } else if (dlt_user.dlt_ll_ts[usercontextinj->log_level_pos].injection_table[i]. injection_callback_with_id != NULL) { delayed_injection_callback.injection_callback_with_id = dlt_user.dlt_ll_ts[usercontextinj->log_level_pos].injection_table[i]. injection_callback_with_id; delayed_injection_callback.data = dlt_user.dlt_ll_ts[usercontextinj->log_level_pos].injection_table[i].data; } delayed_injection_callback.service_id = usercontextinj->service_id; delayed_inject_data_length = usercontextinj->data_length_inject; delayed_inject_buffer = malloc(delayed_inject_data_length); if (delayed_inject_buffer != NULL) { memcpy(delayed_inject_buffer, userbuffer, delayed_inject_data_length); } else { DLT_SEM_FREE(); dlt_log(LOG_WARNING, "malloc failed!\n"); return DLT_RETURN_ERROR; } break; } DLT_SEM_FREE(); /* Delayed injection callback call */ if ((delayed_inject_buffer != NULL) && (delayed_injection_callback.injection_callback != NULL)) { delayed_injection_callback.injection_callback(delayed_injection_callback.service_id, delayed_inject_buffer, delayed_inject_data_length); delayed_injection_callback.injection_callback = NULL; } else if ((delayed_inject_buffer != NULL) && (delayed_injection_callback.injection_callback_with_id != NULL)) { delayed_injection_callback.injection_callback_with_id(delayed_injection_callback.service_id, delayed_inject_buffer, delayed_inject_data_length, delayed_injection_callback.data); delayed_injection_callback.injection_callback_with_id = NULL; } free(delayed_inject_buffer); delayed_inject_buffer = NULL; /* keep not read data in buffer */ if (dlt_receiver_remove(receiver, (sizeof(DltUserHeader) + sizeof(DltUserControlMsgInjection) + usercontextinj->data_length_inject)) != DLT_RETURN_OK) return DLT_RETURN_ERROR; } } break; case DLT_USER_MESSAGE_LOG_STATE: { /* At least, user header, user context, and service id and data_length of injected message is available */ if (receiver->bytesRcvd < (int32_t)(sizeof(DltUserHeader) + sizeof(DltUserControlMsgLogState))) { leave_while = 1; break; } userlogstate = (DltUserControlMsgLogState *)(receiver->buf + sizeof(DltUserHeader)); dlt_user.log_state = userlogstate->log_state; /* keep not read data in buffer */ if (dlt_receiver_remove(receiver, (sizeof(DltUserHeader) + sizeof(DltUserControlMsgLogState))) == DLT_RETURN_ERROR) return DLT_RETURN_ERROR; } break; default: { dlt_log(LOG_WARNING, "Invalid user message type received!\n"); /* Ignore result */ dlt_receiver_remove(receiver, sizeof(DltUserHeader)); /* In next invocation of while loop, a resync will be triggered if additional data was received */ } break; } /* switch() */ if (leave_while == 1) { leave_while = 0; break; } } /* while buffer*/ if (dlt_receiver_move_to_begin(receiver) == DLT_RETURN_ERROR) return DLT_RETURN_ERROR; } /* while receive */ } /* if */ return DLT_RETURN_OK; } DltReturnValue dlt_user_log_resend_buffer(void) { int num, count; int size; DltReturnValue ret; DLT_SEM_LOCK(); if (dlt_user.appID[0] == '\0') { DLT_SEM_FREE(); return 0; } /* Send content of ringbuffer */ count = dlt_buffer_get_message_count(&(dlt_user.startup_buffer)); DLT_SEM_FREE(); for (num = 0; num < count; num++) { DLT_SEM_LOCK(); size = dlt_buffer_copy(&(dlt_user.startup_buffer), dlt_user.resend_buffer, dlt_user.log_buf_len); if (size > 0) { DltUserHeader *userheader = (DltUserHeader *)(dlt_user.resend_buffer); /* Add application id to the messages of needed*/ if (dlt_user_check_userheader(userheader)) { switch (userheader->message) { case DLT_USER_MESSAGE_REGISTER_CONTEXT: { DltUserControlMsgRegisterContext *usercontext = (DltUserControlMsgRegisterContext *)(dlt_user.resend_buffer + sizeof(DltUserHeader)); if ((usercontext != 0) && (usercontext->apid[0] == '\0')) dlt_set_id(usercontext->apid, dlt_user.appID); break; } case DLT_USER_MESSAGE_LOG: { DltExtendedHeader *extendedHeader = (DltExtendedHeader *)(dlt_user.resend_buffer + sizeof(DltUserHeader) + sizeof(DltStandardHeader) + sizeof(DltStandardHeaderExtra)); if (((extendedHeader) != 0) && (extendedHeader->apid[0] == '\0')) /* if application id is empty, add it */ dlt_set_id(extendedHeader->apid, dlt_user.appID); break; } default: { break; } } } #ifdef DLT_SHM_ENABLE dlt_shm_push(&dlt_user.dlt_shm, dlt_user.resend_buffer + sizeof(DltUserHeader), size - sizeof(DltUserHeader), 0, 0, 0, 0); ret = dlt_user_log_out3(dlt_user.dlt_log_handle, dlt_user.resend_buffer, sizeof(DltUserHeader), 0, 0, 0, 0); #else ret = dlt_user_log_out3(dlt_user.dlt_log_handle, dlt_user.resend_buffer, size, 0, 0, 0, 0); #endif /* in case of error, keep message in ringbuffer */ if (ret == DLT_RETURN_OK) { dlt_buffer_remove(&(dlt_user.startup_buffer)); } else { if (ret == DLT_RETURN_PIPE_ERROR) { /* handle not open or pipe error */ close(dlt_user.dlt_log_handle); dlt_user.dlt_log_handle = -1; } /* keep message in ringbuffer */ DLT_SEM_FREE(); return ret; } } DLT_SEM_FREE(); } return DLT_RETURN_OK; } void dlt_user_log_reattach_to_daemon(void) { uint32_t num, reregistered = 0; DltContext handle; DltContextData log_new; if (dlt_user.dlt_log_handle < 0) { dlt_user.dlt_log_handle = -1; #ifdef DLT_USE_UNIX_SOCKET_IPC /* try to open connection to dlt daemon */ dlt_initialize_socket_connection(); if (dlt_user.connection_state != DLT_USER_CONNECTED) /* return if not connected */ return; #else /* try to open pipe to dlt daemon */ int fd = open(dlt_daemon_fifo, O_WRONLY | O_NONBLOCK); if (fd < 0) return; dlt_user.dlt_log_handle = fd; #endif if (dlt_user_log_init(&handle, &log_new) < DLT_RETURN_OK) return; #ifdef DLT_SHM_ENABLE /* init shared memory */ if (dlt_shm_init_client(&dlt_user.dlt_shm, dltShmName) < DLT_RETURN_OK) dlt_vnlog(LOG_WARNING, DLT_USER_BUFFER_LENGTH, "Logging disabled," " Shared memory %s cannot be created!\n", dltShmName); #endif dlt_log(LOG_NOTICE, "Logging (re-)enabled!\n"); /* Re-register application */ if (dlt_user_log_send_register_application() < DLT_RETURN_ERROR) return; DLT_SEM_LOCK(); /* Re-register all stored contexts */ for (num = 0; num < dlt_user.dlt_ll_ts_num_entries; num++) /* Re-register stored context */ if ((dlt_user.appID[0] != '\0') && (dlt_user.dlt_ll_ts) && (dlt_user.dlt_ll_ts[num].contextID[0] != '\0')) { /*dlt_set_id(log_new.appID, dlt_user.appID); */ dlt_set_id(handle.contextID, dlt_user.dlt_ll_ts[num].contextID); handle.log_level_pos = num; log_new.context_description = dlt_user.dlt_ll_ts[num].context_description; /* Release the mutex for sending context registration: */ /* function dlt_user_log_send_register_context() can take the mutex to write to the DLT buffer. => dead lock */ DLT_SEM_FREE(); log_new.log_level = DLT_USER_LOG_LEVEL_NOT_SET; log_new.trace_status = DLT_USER_TRACE_STATUS_NOT_SET; if (dlt_user_log_send_register_context(&log_new) < DLT_RETURN_ERROR) return; reregistered = 1; /* Lock again the mutex */ /* it is necessary in the for(;;) test, in order to have coherent dlt_user data all over the critical section. */ DLT_SEM_LOCK(); } DLT_SEM_FREE(); if (reregistered == 1) dlt_user_log_resend_buffer(); } } DltReturnValue dlt_user_log_send_overflow(void) { DltUserHeader userheader; DltUserControlMsgBufferOverflow userpayload; /* set userheader */ if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_OVERFLOW) < DLT_RETURN_OK) return DLT_RETURN_ERROR; if (dlt_user.dlt_is_file) return DLT_RETURN_OK; /* set user message parameters */ userpayload.overflow_counter = dlt_user.overflow_counter; dlt_set_id(userpayload.apid, dlt_user.appID); return dlt_user_log_out2(dlt_user.dlt_log_handle, &(userheader), sizeof(DltUserHeader), &(userpayload), sizeof(DltUserControlMsgBufferOverflow)); } DltReturnValue dlt_user_check_buffer(int *total_size, int *used_size) { if ((total_size == NULL) || (used_size == NULL)) return DLT_RETURN_WRONG_PARAMETER; DLT_SEM_LOCK(); #ifdef DLT_SHM_ENABLE *total_size = dlt_shm_get_total_size(&(dlt_user.dlt_shm)); *used_size = dlt_shm_get_used_size(&(dlt_user.dlt_shm)); #else *total_size = dlt_buffer_get_total_size(&(dlt_user.startup_buffer)); *used_size = dlt_buffer_get_used_size(&(dlt_user.startup_buffer)); #endif DLT_SEM_FREE(); return DLT_RETURN_OK; /* ok */ } #ifdef DLT_TEST_ENABLE void dlt_user_test_corrupt_user_header(int enable) { dlt_user.corrupt_user_header = enable; } void dlt_user_test_corrupt_message_size(int enable, int16_t size) { dlt_user.corrupt_message_size = enable; dlt_user.corrupt_message_size_size = size; } #endif int dlt_start_threads() { /* Start receiver thread */ if (pthread_create(&(dlt_receiverthread_handle), 0, (void *)&dlt_user_receiverthread_function, 0) != 0) { dlt_log(LOG_CRIT, "Can't create receiver thread!\n"); return -1; } /* Start the segmented thread */ if (pthread_create(&(dlt_user.dlt_segmented_nwt_handle), NULL, (void *)dlt_user_trace_network_segmented_thread, NULL)) { dlt_log(LOG_CRIT, "Can't start segmented thread!\n"); return -1; } return 0; } void dlt_stop_threads() { int dlt_receiverthread_result = 0; int dlt_segmented_nwt_result = 0; if (dlt_receiverthread_handle) { /* do not ignore return value */ dlt_receiverthread_result = pthread_cancel(dlt_receiverthread_handle); if (dlt_receiverthread_result != 0) dlt_vlog(LOG_ERR, "ERROR pthread_cancel(dlt_receiverthread_handle): %s\n", strerror(errno)); } if (dlt_user.dlt_segmented_nwt_handle) { dlt_lock_mutex(&mq_mutex); pthread_cond_signal(&mq_init_condition); dlt_unlock_mutex(&mq_mutex); dlt_segmented_nwt_result = pthread_cancel(dlt_user.dlt_segmented_nwt_handle); if (dlt_segmented_nwt_result != 0) dlt_vlog(LOG_ERR, "ERROR pthread_cancel(dlt_user.dlt_segmented_nwt_handle): %s\n", strerror(errno)); } /* make sure that the threads really finished working */ if ((dlt_receiverthread_result == 0) && dlt_receiverthread_handle) { int joined = pthread_join(dlt_receiverthread_handle, NULL); if (joined < 0) dlt_vlog(LOG_ERR, "ERROR pthread_join(dlt_receiverthread_handle, NULL): %s\n", strerror(errno)); dlt_receiverthread_handle = 0; /* set to invalid */ } if ((dlt_segmented_nwt_result == 0) && dlt_user.dlt_segmented_nwt_handle) { int joined = pthread_join(dlt_user.dlt_segmented_nwt_handle, NULL); if (joined < 0) dlt_vlog(LOG_ERR, "ERROR pthread_join(dlt_user.dlt_segmented_nwt_handle, NULL): %s\n", strerror(errno)); dlt_user.dlt_segmented_nwt_handle = 0; /* set to invalid */ } } static void dlt_fork_child_fork_handler() { g_dlt_is_child = 1; dlt_user_initialised = false; dlt_user.dlt_log_handle = -1; } DltReturnValue dlt_user_log_out_error_handling(void *ptr1, size_t len1, void *ptr2, size_t len2, void *ptr3, size_t len3) { int ret = DLT_RETURN_ERROR; int msg_size = len1 + len2 + len3; DLT_SEM_LOCK(); ret = dlt_buffer_check_size(&(dlt_user.startup_buffer), msg_size); DLT_SEM_FREE(); DLT_SEM_LOCK(); if (dlt_buffer_push3(&(dlt_user.startup_buffer), ptr1, len1, ptr2, len2, ptr3, len3) == DLT_RETURN_ERROR) { if (dlt_user.overflow_counter == 0) dlt_log(LOG_WARNING, "Buffer full! Messages will be discarded.\n"); ret = DLT_RETURN_BUFFER_FULL; } DLT_SEM_FREE(); return ret; } dlt-daemon-2.18.4/src/lib/dlt_user_cfg.h000066400000000000000000000153101353342203500200000ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2011-2015, BMW AG * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author Alexander Wenzel * * \copyright Copyright © 2011-2015 BMW AG. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file dlt_user_cfg.h */ /******************************************************************************* ** ** ** SRC-MODULE: dlt_user_cfg.h ** ** ** ** TARGET : linux ** ** ** ** PROJECT : DLT ** ** ** ** AUTHOR : Alexander Wenzel Alexander.AW.Wenzel@bmw.de ** ** Markus Klein ** ** ** ** PURPOSE : ** ** ** ** REMARKS : ** ** ** ** PLATFORM DEPENDANT [yes/no]: yes ** ** ** ** TO BE CHANGED BY USER [yes/no]: no ** ** ** *******************************************************************************/ /******************************************************************************* ** Author Identity ** ******************************************************************************** ** ** ** Initials Name Company ** ** -------- ------------------------- ---------------------------------- ** ** aw Alexander Wenzel BMW ** ** mk Markus Klein Fraunhofer ESK ** *******************************************************************************/ /******************************************************************************* ** Author Identity ** ******************************************************************************** ** ** ** Initials Name Company ** ** -------- ------------------------- ---------------------------------- ** ** aw Alexander Wenzel BMW ** ** mk Markus Klein Fraunhofer ESK ** *******************************************************************************/ #ifndef DLT_USER_CFG_H #define DLT_USER_CFG_H /*************/ /* Changable */ /*************/ /* Size of receive buffer */ #define DLT_USER_RCVBUF_MAX_SIZE 10024 /* Size of ring buffer */ #define DLT_USER_RINGBUFFER_MIN_SIZE 50000 #define DLT_USER_RINGBUFFER_MAX_SIZE 500000 #define DLT_USER_RINGBUFFER_STEP_SIZE 50000 /* Name of environment variable for ringbuffer configuration */ #define DLT_USER_ENV_BUFFER_MIN_SIZE "DLT_USER_BUFFER_MIN" #define DLT_USER_ENV_BUFFER_MAX_SIZE "DLT_USER_BUFFER_MAX" #define DLT_USER_ENV_BUFFER_STEP_SIZE "DLT_USER_BUFFER_STEP" /* Temporary buffer length */ #define DLT_USER_BUFFER_LENGTH 255 /* Number of context entries, which will be allocated, * if no more context entries are available */ #define DLT_USER_CONTEXT_ALLOC_SIZE 500 /* Maximu length of a filename string */ #define DLT_USER_MAX_FILENAME_LENGTH 255 /* Maximum length of a single version number */ #define DLT_USER_MAX_LIB_VERSION_LENGTH 3 /* Length of buffer for constructing text output */ #define DLT_USER_TEXT_LENGTH 10024 /* Stack size of receiver thread */ #define DLT_USER_RECEIVERTHREAD_STACKSIZE 100000 /* default value for storage to file, not used in daemon connection */ #define DLT_USER_DEFAULT_ECU_ID "ECU1" /* Initial log level */ #define DLT_USER_INITIAL_LOG_LEVEL DLT_LOG_INFO /* Initial trace status */ #define DLT_USER_INITIAL_TRACE_STATUS DLT_TRACE_STATUS_OFF /* use extended header for non-verbose mode: 0 - don't use, 1 - use */ #define DLT_USER_USE_EXTENDED_HEADER_FOR_NONVERBOSE 1 /* send always session id: 0 - don't use, 1 - use */ #define DLT_USER_WITH_SESSION_ID 1 /* send always timestamp: 0 - don't use, 1 - use */ #define DLT_USER_WITH_TIMESTAMP 1 /* send always ecu id: 0 - don't use, 1 - use */ #define DLT_USER_WITH_ECU_ID 1 /* default message id for non-verbose mode, if no message id was provided */ #define DLT_USER_DEFAULT_MSGID 0xffff /* delay for receiver thread (nsec) */ #define DLT_USER_RECEIVE_NDELAY (100000000) /* Name of environment variable for local print mode */ #define DLT_USER_ENV_LOCAL_PRINT_MODE "DLT_LOCAL_PRINT_MODE" /* Timeout offset for resending user buffer at exit in 10th milliseconds (10000 = 1s)*/ #define DLT_USER_ATEXIT_RESEND_BUFFER_EXIT_TIMEOUT 100000 /* Sleeps between resending user buffer at exit in nsec (1000000 nsec = 1ms)*/ #define DLT_USER_ATEXIT_RESEND_BUFFER_SLEEP 100000000 /* Retry interval for mq error in usec */ #define DLT_USER_MQ_ERROR_RETRY_INTERVAL 100000 /* Name of environment variable to change the dlt log message buffer size */ #define DLT_USER_ENV_LOG_MSG_BUF_LEN "DLT_LOG_MSG_BUF_LEN" /* Maximum msg size as per autosar standard */ #define DLT_LOG_MSG_BUF_MAX_SIZE 65535 /************************/ /* Don't change please! */ /************************/ /* Minimum valid ID of an injection message */ #define DLT_USER_INJECTION_MIN 0xFFF /* Defines of the different local print modes */ #define DLT_PM_UNSET 0 #define DLT_PM_AUTOMATIC 1 #define DLT_PM_FORCE_ON 2 #define DLT_PM_FORCE_OFF 3 #endif /* DLT_USER_CFG_H */ dlt-daemon-2.18.4/src/offlinelogstorage/000077500000000000000000000000001353342203500201325ustar00rootroot00000000000000dlt-daemon-2.18.4/src/offlinelogstorage/dlt_offline_logstorage.c000066400000000000000000001735051353342203500250240ustar00rootroot00000000000000/** * Copyright (C) 2013 - 2015 Advanced Driver Information Technology. * This code is developed by Advanced Driver Information Technology. * Copyright of Advanced Driver Information Technology, Bosch and DENSO. * * DLT offline log storage functionality source file. * * \copyright * This Source Code Form is subject to the terms of the * Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with * this file, You can obtain one at http://mozilla.org/MPL/2.0/. * * * \author Syed Hameed ADIT 2013 - 2015 * \author Christoph Lipka ADIT 2015 * * \file: dlt_offline_logstorage.c * For further information see http://www.genivi.org/. */ #include #include #include #include #include #include #include #include #include #include #include #include "dlt_offline_logstorage.h" #include "dlt_offline_logstorage_internal.h" #include "dlt_offline_logstorage_behavior.h" #include "dlt_config_file_parser.h" #define DLT_OFFLINE_LOGSTORAGE_FILTER_ERROR 1 #define DLT_OFFLINE_LOGSTORAGE_STORE_FILTER_ERROR 2 #define DLT_OFFLINE_LOGSTORAGE_FILTER_CONTINUE 3 #define GENERAL_BASE_NAME "General" DLT_STATIC void dlt_logstorage_filter_config_free(DltLogStorageFilterConfig *data) { DltLogStorageFileList *n = NULL; DltLogStorageFileList *n1 = NULL; free(data->apids); data->apids = NULL; free(data->ctids); data->ctids = NULL; free(data->file_name); data->file_name = NULL; if (data->ecuid != NULL) { free(data->ecuid); data->ecuid = NULL; } if (data->log != NULL) fclose(data->log); if (data->cache != NULL) { free(data->cache); data->cache = NULL; } n = data->records; while (n) { n1 = n; n = n->next; free(n1->name); n1->name = NULL; free(n1); n1 = NULL; } } /** * dlt_logstorage_list_destroy * * Destroy Filter configurations list. * * @param list List of the filter configurations will be destroyed. * @param uconfig User configurations for log file * @param dev_path Path to the device * @param reason Reason for the destroying of Filter configurations list * @return 0 on success, -1 on error */ DLT_STATIC int dlt_logstorage_list_destroy(DltLogStorageFilterList **list, DltLogStorageUserConfig *uconfig, char *dev_path, int reason) { DltLogStorageFilterList *tmp = NULL; while (*(list) != NULL) { tmp = *list; *list = (*list)->next; if (tmp->key_list != NULL) { free(tmp->key_list); tmp->key_list = NULL; } if (tmp->data != NULL) { /* sync data if necessary */ /* ignore return value */ tmp->data->dlt_logstorage_sync(tmp->data, uconfig, dev_path, reason); dlt_logstorage_filter_config_free(tmp->data); free(tmp->data); tmp->data = NULL; } free(tmp); tmp = NULL; } return 0; } DLT_STATIC int dlt_logstorage_list_add_config(DltLogStorageFilterConfig *data, DltLogStorageFilterConfig **listdata) { if (*(listdata) == NULL) return -1; (*listdata)->apids = NULL; (*listdata)->ctids = NULL; (*listdata)->file_name = NULL; (*listdata)->ecuid = NULL; (*listdata)->records = NULL; (*listdata)->log = NULL; (*listdata)->cache = NULL; /* copy the data to list */ memcpy(*listdata, data, sizeof(DltLogStorageFilterConfig)); if (data->apids != NULL) (*listdata)->apids = strdup(data->apids); if (data->ctids != NULL) (*listdata)->ctids = strdup(data->ctids); if (data->file_name != NULL) (*listdata)->file_name = strdup(data->file_name); if (data->ecuid != NULL) (*listdata)->ecuid = strdup(data->ecuid); return 0; } /** * dlt_logstorage_list_add * * Add Filter configurations to the list. * * @param keys Keys will be added to the list. * @param num_keys Number of keys * @param data Filter configurations data will be added to the list. * @param list List of the filter configurations * @return 0 on success, -1 on error */ DLT_STATIC int dlt_logstorage_list_add(char *keys, int num_keys, DltLogStorageFilterConfig *data, DltLogStorageFilterList **list) { DltLogStorageFilterList *tmp = NULL; while (*(list) != NULL) { list = &(*list)->next; } tmp = calloc(1, sizeof(DltLogStorageFilterList)); if (tmp == NULL) return -1; tmp->key_list = (char *)calloc( (num_keys * DLT_OFFLINE_LOGSTORAGE_MAX_KEY_LEN), sizeof(char)); if (tmp->key_list == NULL) { free(tmp); tmp = NULL; return -1; } memcpy(tmp->key_list, keys, num_keys * DLT_OFFLINE_LOGSTORAGE_MAX_KEY_LEN); tmp->num_keys = num_keys; tmp->next = NULL; tmp->data = calloc(1, sizeof(DltLogStorageFilterConfig)); if (tmp->data == NULL) { free(tmp->key_list); tmp->key_list = NULL; free(tmp); tmp = NULL; return -1; } if (dlt_logstorage_list_add_config(data, &(tmp->data)) != 0) { free(tmp->key_list); tmp->key_list = NULL; free(tmp->data); tmp->data = NULL; free(tmp); tmp = NULL; return -1; } *list = tmp; return 0; } /** * dlt_logstorage_list_find * * Find all Filter configurations corresponding with key provided. * * @param key Key to find the filter configurations * @param list List of the filter configurations * @param config Filter configurations corresponding with the key. * @return Number of the filter configuration found. */ DLT_STATIC int dlt_logstorage_list_find(char *key, DltLogStorageFilterList **list, DltLogStorageFilterConfig **config) { int i = 0; int num = 0; while (*(list) != NULL) { for (i = 0; i < (*list)->num_keys; i++) { if (strncmp(((*list)->key_list + (i * DLT_OFFLINE_LOGSTORAGE_MAX_KEY_LEN)), key, DLT_OFFLINE_LOGSTORAGE_MAX_KEY_LEN) == 0) { config[num] = (*list)->data; num++; break; } } list = &(*list)->next; } return num; } /* Configuration file parsing helper functions */ DLT_STATIC int dlt_logstorage_count_ids(const char *str) { if (str == NULL) return -1; /* delimiter is: "," */ const char *p = str; int i = 0; int num = 1; while (p[i] != 0) { if (p[i] == ',') num++; i++; } return num; } /** * dlt_logstorage_free * * Free all allocated memory used in log storage handle * * @param handle DLT Logstorage handle * @param reason Reason for freeing the device * */ void dlt_logstorage_free(DltLogStorage *handle, int reason) { if (handle == NULL) { dlt_vlog(LOG_ERR, "%s failed: handle is NULL\n", __func__); return; } dlt_logstorage_list_destroy(&(handle->config_list), &handle->uconfig, handle->device_mount_point, reason); } /** * dlt_logstorage_read_list_of_names * * Evaluate app and ctx names given in config file and create a list of names * acceptable by DLT Daemon. When using SET_APPLICATION_NAME and SET_CONTEXT_NAME * there is no constraint that these names have max 4 characters. Internally, * these names are cutted down to max 4 chars. To have create valid keys, the * internal representation of these names has to be considered. * Therefore, a given configuration of "AppLogName = App1,Application2,A3" will * be stored as "App1,Appl,A3". * * @param names to store the list of names * @param value string given in config file * @return 0 on success, -1 on error */ DLT_STATIC int dlt_logstorage_read_list_of_names(char **names, char *value) { int i = 0; int y = 0; int len = 0; char *tok; int num = 1; if ((names == NULL) || (value == NULL)) return -1; /* free, alloce'd memory to store new apid/ctid */ if (*names != NULL) { free(*names); *names = NULL; } len = strlen(value); if (len == 0) return -1; /* count number of delimiters to get actual number off names */ num = dlt_logstorage_count_ids(value); /* need to alloc space for 5 chars, 4 for the name and "," and "\0" */ *names = (char *)calloc(num * 5, sizeof(char)); if (*names == NULL) return -1; tok = strtok(value, ","); i = 1; while (tok != NULL) { len = strlen(tok); len = DLT_OFFLINE_LOGSTORAGE_MIN(len, 4); strncpy((*names + y), tok, len); if ((num > 1) && (i < num)) strncpy((*names + y + len), ",", 2); y += len + 1; i++; tok = strtok(NULL, ","); } return 0; } /** * dlt_logstorage_read_number * * Evaluate file size and number of files given in config file and set file size * The file number is checked by converting a string to an unsigned integer * width 0 > result < UINT_MAX (excludes 0!) * Non-digit characters including spaces and out of boundary will lead to an * error -1. * * @param number Number to be read * @param value string given in config file * @return 0 on success, -1 on error */ DLT_STATIC int dlt_logstorage_read_number(unsigned int *number, char *value) { int i = 0; int len = 0; unsigned long size = 0; if (value == NULL) return -1; *number = 0; len = strlen(value); /* check if string consists of digits only */ for (i = 0; i < len; i++) if (!isdigit(value[i])) { dlt_log(LOG_ERR, "Invalid, is not a number \n"); return -1; } size = strtoul(value, NULL, 10); if ((size == 0) || (size > UINT_MAX)) { dlt_log(LOG_ERR, "Invalid, is not a number \n"); return -1; } *number = (unsigned int)size; return 0; } /** * dlt_logstorage_get_keys_list * * Obtain key list and number of keys for id list passed * after splitting it between seperator (,) * * @param ids ID's * @param sep Seperator * @param list Prepared key list is stored here * @param numids Number of keys in the list is stored here * @return: 0 on success, error on failure* */ DLT_STATIC int dlt_logstorage_get_keys_list(char *ids, char *sep, char **list, int *numids) { char *token = NULL; char *tmp_token = NULL; char *ids_local = NULL; *numids = 0; /* Duplicate the ids passed for using in strtok_r() */ ids_local = strdup(ids); if (ids_local == NULL) return -1; token = strtok_r(ids_local, sep, &tmp_token); if (token == NULL) { free(ids_local); return -1; } *list = (char *)calloc(DLT_OFFLINE_LOGSTORAGE_MAXIDS * (DLT_ID_SIZE + 1), sizeof(char)); if (*(list) == NULL) { free(ids_local); return -1; } while (token != NULL) { /* If it reached the max then other ids are ignored */ if (*numids >= DLT_OFFLINE_LOGSTORAGE_MAXIDS) { free(ids_local); return 0; } strncpy(((*list) + ((*numids) * (DLT_ID_SIZE + 1))), token, DLT_ID_SIZE); *numids = *numids + 1; token = strtok_r(NULL, sep, &tmp_token); } free(ids_local); return 0; } /** * dlt_logstorage_create_keys_only_ctid * * Prepares keys with context ID alone, will use ecuid if provided * (ecuid\:\:ctid) or (\:\:ctid) * * @param ecuid ECU ID * @param ctid Context ID * @param key Prepared key stored here * @return None */ DLT_STATIC void dlt_logstorage_create_keys_only_ctid(char *ecuid, char *ctid, char *key) { char curr_str[DLT_OFFLINE_LOGSTORAGE_MAX_KEY_LEN + 1] = { 0 }; int curr_len = 0; if (ecuid != NULL) { strncpy(curr_str, ecuid, strlen(ecuid)); strncat(curr_str, "::", 2); } else { strncpy(curr_str, "::", 2); } curr_len = strlen(ctid); strncat(curr_str, ctid, curr_len); curr_len = strlen(curr_str); strncpy(key, curr_str, curr_len); } /** * dlt_logstorage_create_keys_only_apid * * Prepares keys with application ID alone, will use ecuid if provided * (ecuid:apid::) or (:apid::) * * @param ecuid ECU ID * @param apid Application ID * @param key Prepared key stored here * @return None */ DLT_STATIC void dlt_logstorage_create_keys_only_apid(char *ecuid, char *apid, char *key) { char curr_str[DLT_OFFLINE_LOGSTORAGE_MAX_KEY_LEN + 1] = { 0 }; int curr_len = 0; if (ecuid != NULL) { strncpy(curr_str, ecuid, strlen(ecuid)); strncat(curr_str, ":", 1); } else { strncpy(curr_str, ":", 1); } curr_len = strlen(apid); strncat(curr_str, apid, curr_len); strncat(curr_str, ":", 1); curr_len = strlen(curr_str); strncpy(key, curr_str, curr_len); } /** * dlt_logstorage_create_keys_multi * * Prepares keys with apid, ctid (ecuid:apid:ctid), will use ecuid if is provided * (ecuid:apid:ctid) or (:apid:ctid) * * @param ecuid ECU ID * @param apid Application ID * @param ctid Context ID * @param key Prepared key stored here * @return None */ DLT_STATIC void dlt_logstorage_create_keys_multi(char *ecuid, char *apid, char *ctid, char *key) { char curr_str[DLT_OFFLINE_LOGSTORAGE_MAX_KEY_LEN + 1] = { 0 }; int curr_len = 0; if (ecuid != NULL) { strncpy(curr_str, ecuid, strlen(ecuid)); strncat(curr_str, ":", 1); } else { strncpy(curr_str, ":", 1); } curr_len = strlen(apid); strncat(curr_str, apid, curr_len); strncat(curr_str, ":", 1); curr_len = strlen(ctid); strncat(curr_str, ctid, curr_len); curr_len = strlen(curr_str); strncpy(key, curr_str, curr_len); } /** * dlt_logstorage_create_keys_only_ecu * * Prepares keys with only ecuid (ecuid::) * * @param ecuid ECU ID * @param key Prepared key stored here * @return None */ DLT_STATIC void dlt_logstorage_create_keys_only_ecu(char *ecuid, char *key) { char curr_str[DLT_OFFLINE_LOGSTORAGE_MAX_KEY_LEN + 1] = { 0 }; strncpy(curr_str, ecuid, strlen(ecuid)); strncat(curr_str, "::", 2); strncpy(key, curr_str, strlen(curr_str)); } /** * dlt_logstorage_create_keys * * Create keys for hash table * * From each section [filter] in offline logstorage configuration file, we * receive application and context id strings. * Application and context id can consist of * - a 4char long name * - a comma separated list of ids * - a wildcard: .* * * Not allowed is the combination of application id and context id set to * wildcard. This will be rejected. * * If lists given for application and/or context id, all possible combinations * are returned as keys in a form "[apid][ctid], e.g. "APP1\:CTX1". * If wildcards are used, the non-wildcard value becomes the key, e.g. "APP1\:" * or "\:CTX2". * * @param[in] apids string given from filter configuration * @param[in] ctids string given from filter configuration * @param[in] ecuid string given from filter configuration * @param[out] keys keys to fill into hash table * @param[out] num_keys number of keys * @return: 0 on success, error on failure* */ DLT_STATIC int dlt_logstorage_create_keys(char *apids, char *ctids, char *ecuid, char **keys, int *num_keys) { int i, j; int num_apids = 0; int num_ctids = 0; char *apid_list = NULL; char *ctid_list = NULL; char *curr_apid = NULL; char *curr_ctid = NULL; char curr_key[DLT_OFFLINE_LOGSTORAGE_MAX_KEY_LEN + 1] = { 0 }; int num_currkey = 0; /* Handle ecuid alone case here */ if ((apids == NULL) && (ctids == NULL) && (ecuid != NULL)) { dlt_logstorage_create_keys_only_ecu(ecuid, curr_key); *(num_keys) = 1; *(keys) = (char *)calloc(*num_keys * DLT_OFFLINE_LOGSTORAGE_MAX_KEY_LEN, sizeof(char)); if (*(keys) == NULL) return -1; strncpy(*keys, curr_key, strlen(curr_key)); return 0; } if ((apids == NULL) || (ctids == NULL)) { dlt_log(LOG_ERR, "Required inputs (apid and ctid) are NULL\n"); return -1; } /* obtain key list and number of keys for application ids */ if (dlt_logstorage_get_keys_list(apids, ",", &apid_list, &num_apids) != 0) { dlt_log(LOG_ERR, "Failed to obtain apid, check configuration file \n"); return -1; } /* obtain key list and number of keys for context ids */ if (dlt_logstorage_get_keys_list(ctids, ",", &ctid_list, &num_ctids) != 0) { dlt_log(LOG_ERR, "Failed to obtain ctid, check configuration file \n"); free(apid_list); return -1; } *(num_keys) = num_apids * num_ctids; /* allocate memory for needed number of keys */ *(keys) = (char *)calloc(*num_keys * DLT_OFFLINE_LOGSTORAGE_MAX_KEY_LEN, sizeof(char)); if (*(keys) == NULL) { free(apid_list); free(ctid_list); return -1; } /* store all combinations of apid ctid in keys */ for (i = 0; i < num_apids; i++) { curr_apid = apid_list + (i * (DLT_ID_SIZE + 1)); for (j = 0; j < num_ctids; j++) { curr_ctid = ctid_list + (j * (DLT_ID_SIZE + 1)); if (strncmp(curr_apid, ".*", 2) == 0) /* only context id matters */ dlt_logstorage_create_keys_only_ctid(ecuid, curr_ctid, curr_key); else if (strncmp(curr_ctid, ".*", 2) == 0) /* only app id matters*/ dlt_logstorage_create_keys_only_apid(ecuid, curr_apid, curr_key); else /* key is combination of all */ dlt_logstorage_create_keys_multi(ecuid, curr_apid, curr_ctid, curr_key); strncpy((*keys + (num_currkey * DLT_OFFLINE_LOGSTORAGE_MAX_KEY_LEN)), curr_key, strlen(curr_key)); num_currkey += 1; memset(&curr_key[0], 0, sizeof(curr_key)); } } free(apid_list); free(ctid_list); return 0; } /** * dlt_logstorage_prepare_table * * Prepares hash table with keys and data * * @param handle DLT Logstorage handle * @param data Holds all other configuration values * @return 0 on success, -1 on error */ DLT_STATIC int dlt_logstorage_prepare_table(DltLogStorage *handle, DltLogStorageFilterConfig *data) { int ret = 0; int num_keys = 0; char *keys = NULL; if ((handle == NULL) || (data == NULL)) { dlt_vlog(LOG_ERR, "Invalid parameters in %s\n", __func__); return -1; } ret = dlt_logstorage_create_keys(data->apids, data->ctids, data->ecuid, &keys, &num_keys); if (ret != 0) { dlt_log(LOG_ERR, "Not able to create keys for hash table\n"); return -1; } /* hash_add */ if (dlt_logstorage_list_add(keys, num_keys, data, &(handle->config_list)) != 0) { dlt_log(LOG_ERR, "Adding to hash table failed, returning failure\n"); dlt_logstorage_free(handle, DLT_LOGSTORAGE_SYNC_ON_ERROR); free(keys); keys = NULL; return -1; } free(keys); keys = NULL; return 0; } /** * dlt_logstorage_validate_filter_name * * Validates if the provided filter name is as required [FILTER] * * @param name Filter name * @return 0 on success, -1 on error * */ DLT_STATIC int dlt_logstorage_validate_filter_name(char *name) { int len = 0; int idx = 0; int config_sec_len = strlen(DLT_OFFLINE_LOGSTORAGE_CONFIG_SECTION); int storage_sec_len = strlen(DLT_OFFLINE_LOGSTORAGE_NONVERBOSE_STORAGE_SECTION); int control_sec_len = strlen(DLT_OFFLINE_LOGSTORAGE_NONVERBOSE_CONTROL_SECTION); if (name == NULL) return -1; len = strlen(name); /* Check if section header is of format "FILTER" followed by a number */ if (strncmp(name, DLT_OFFLINE_LOGSTORAGE_CONFIG_SECTION, config_sec_len) == 0) { for (idx = config_sec_len; idx < len - 1; idx++) if (!isdigit(name[idx])) return -1; return 0; } /* Check if section header is of format "FILTER" followed by a number */ else if (strncmp(name, DLT_OFFLINE_LOGSTORAGE_NONVERBOSE_STORAGE_SECTION, storage_sec_len) == 0) { for (idx = storage_sec_len; idx < len - 1; idx++) if (!isdigit(name[idx])) return -1; return 0; } /* Check if section header is of format "FILTER" followed by a number */ else if (strncmp(name, DLT_OFFLINE_LOGSTORAGE_NONVERBOSE_CONTROL_SECTION, control_sec_len) == 0) { for (idx = control_sec_len; idx < len - 1; idx++) if (!isdigit(name[idx])) return -1; return 0; } else { return -1; } } DLT_STATIC void dlt_logstorage_filter_set_strategy(DltLogStorageFilterConfig *config, int strategy) { if (config == NULL) return; /* file based */ if ((strategy == DLT_LOGSTORAGE_SYNC_ON_MSG) || (strategy == DLT_LOGSTORAGE_SYNC_UNSET)) { config->dlt_logstorage_prepare = &dlt_logstorage_prepare_on_msg; config->dlt_logstorage_write = &dlt_logstorage_write_on_msg; config->dlt_logstorage_sync = &dlt_logstorage_sync_on_msg; } else { /* cache based */ config->dlt_logstorage_prepare = &dlt_logstorage_prepare_msg_cache; config->dlt_logstorage_write = &dlt_logstorage_write_msg_cache; config->dlt_logstorage_sync = &dlt_logstorage_sync_msg_cache; } } DLT_STATIC int dlt_logstorage_check_apids(DltLogStorageFilterConfig *config, char *value) { if ((config == NULL) || (value == NULL)) { dlt_log(LOG_ERR, "Not able to create keys for hash table\n"); return -1; } return dlt_logstorage_read_list_of_names(&config->apids, value); } DLT_STATIC int dlt_logstorage_check_ctids(DltLogStorageFilterConfig *config, char *value) { if ((config == NULL) || (value == NULL)) return -1; return dlt_logstorage_read_list_of_names(&config->ctids, value); } DLT_STATIC int dlt_logstorage_check_loglevel(DltLogStorageFilterConfig *config, char *value) { if ((config == NULL) || (value == NULL)) return -1; if (value == NULL) { config->log_level = 0; return -1; } if (strcmp(value, "DLT_LOG_FATAL") == 0) { config->log_level = 1; } else if (strcmp(value, "DLT_LOG_ERROR") == 0) { config->log_level = 2; } else if (strcmp(value, "DLT_LOG_WARN") == 0) { config->log_level = 3; } else if (strcmp(value, "DLT_LOG_INFO") == 0) { config->log_level = 4; } else if (strcmp(value, "DLT_LOG_DEBUG") == 0) { config->log_level = 5; } else if (strcmp(value, "DLT_LOG_VERBOSE") == 0) { config->log_level = 6; } else { config->log_level = -1; dlt_log(LOG_ERR, "Invalid log level \n"); return -1; } return 0; } DLT_STATIC int dlt_logstorage_check_reset_loglevel(DltLogStorageFilterConfig *config, char *value) { if (config == NULL) return -1; if (value == NULL) { config->reset_log_level = 0; return -1; } if (strcmp(value, "DLT_LOG_OFF") == 0) { config->reset_log_level = DLT_LOG_OFF; } else if (strcmp(value, "DLT_LOG_FATAL") == 0) { config->reset_log_level = DLT_LOG_FATAL; } else if (strcmp(value, "DLT_LOG_ERROR") == 0) { config->reset_log_level = DLT_LOG_ERROR; } else if (strcmp(value, "DLT_LOG_WARN") == 0) { config->reset_log_level = DLT_LOG_WARN; } else if (strcmp(value, "DLT_LOG_INFO") == 0) { config->reset_log_level = DLT_LOG_INFO; } else if (strcmp(value, "DLT_LOG_DEBUG") == 0) { config->reset_log_level = DLT_LOG_DEBUG; } else if (strcmp(value, "DLT_LOG_VERBOSE") == 0) { config->reset_log_level = DLT_LOG_VERBOSE; } else { config->reset_log_level = -1; dlt_log(LOG_ERR, "Invalid log level \n"); return -1; } return 0; } DLT_STATIC int dlt_logstorage_check_filename(DltLogStorageFilterConfig *config, char *value) { int len; if ((value == NULL) || (strcmp(value, "") == 0)) return -1; if (config->file_name != NULL) { free(config->file_name); config->file_name = NULL; } len = strlen(value); /* do not allow the user to change directory by adding a relative path */ if (strstr(value, "..") == NULL) { config->file_name = calloc((len + 1), sizeof(char)); if (config->file_name == NULL) { dlt_log(LOG_ERR, "Cannot allocate memory for filename\n"); return -1; } strncpy(config->file_name, value, len); } else { dlt_log(LOG_ERR, "Invalid filename, paths not accepted due to security issues\n"); return -1; } return 0; } DLT_STATIC int dlt_logstorage_check_filesize(DltLogStorageFilterConfig *config, char *value) { if ((config == NULL) || (value == NULL)) return -1; return dlt_logstorage_read_number(&config->file_size, value); } DLT_STATIC int dlt_logstorage_check_nofiles(DltLogStorageFilterConfig *config, char *value) { if ((config == NULL) || (value == NULL)) return -1; return dlt_logstorage_read_number(&config->num_files, value); } DLT_STATIC int dlt_logstorage_check_specificsize(DltLogStorageFilterConfig *config, char *value) { if ((config == NULL) || (value == NULL)) return -1; return dlt_logstorage_read_number(&config->specific_size, value); } /** * dlt_logstorage_check_sync_strategy * * Evaluate sync strategy. The sync strategy is an optional filter * configuration parameter. * If the given value cannot be associated with a sync strategy, the default * sync strategy will be assigned. * * @param config DltLogStorageFilterConfig * @param value string given in config file * @return 0 on success, -1 on error */ DLT_STATIC int dlt_logstorage_check_sync_strategy(DltLogStorageFilterConfig *config, char *value) { if ((config == NULL) || (value == NULL)) return -1; if (strcasestr(value, "ON_MSG") != NULL) { config->sync = DLT_LOGSTORAGE_SYNC_ON_MSG; dlt_log(LOG_DEBUG, "ON_MSG found, ignore other if added\n"); } else { /* ON_MSG not set, combination of cache based strategies possible */ if (strcasestr(value, "ON_DAEMON_EXIT") != NULL) config->sync |= DLT_LOGSTORAGE_SYNC_ON_DAEMON_EXIT; if (strcasestr(value, "ON_DEMAND") != NULL) config->sync |= DLT_LOGSTORAGE_SYNC_ON_DEMAND; if (strcasestr(value, "ON_DEVICE_DISCONNECT") != NULL) config->sync |= DLT_LOGSTORAGE_SYNC_ON_DEVICE_DISCONNECT; if (strcasestr(value, "ON_SPECIFIC_SIZE") != NULL) config->sync |= DLT_LOGSTORAGE_SYNC_ON_SPECIFIC_SIZE; if (strcasestr(value, "ON_FILE_SIZE") != NULL) config->sync |= DLT_LOGSTORAGE_SYNC_ON_FILE_SIZE; if (config->sync == 0) { dlt_log(LOG_WARNING, "Unknown sync strategies. Set default ON_MSG\n"); config->sync = DLT_LOGSTORAGE_SYNC_ON_MSG; return 1; } } return 0; } /** * dlt_logstorage_check_ecuid * * Evaluate if ECU idenfifier given in config file * * @param config DltLogStorageFilterConfig * @param value string given in config file * @return 0 on success, -1 on error */ DLT_STATIC int dlt_logstorage_check_ecuid(DltLogStorageFilterConfig *config, char *value) { int len; if ((config == NULL) || (value == NULL) || (value[0] == '\0')) return -1; if (config->ecuid != NULL) { free(config->ecuid); config->ecuid = NULL; } len = strlen(value); config->ecuid = calloc((len + 1), sizeof(char)); if (config->ecuid == NULL) return -1; strncpy(config->ecuid, value, len); return 0; } DLT_STATIC DltLogstorageFilterConf filter_cfg_entries[DLT_LOGSTORAGE_FILTER_CONF_COUNT] = { [DLT_LOGSTORAGE_FILTER_CONF_LOGAPPNAME] = { .key = "LogAppName", .func = dlt_logstorage_check_apids, .is_opt = 1 }, [DLT_LOGSTORAGE_FILTER_CONF_CONTEXTNAME] = { .key = "ContextName", .func = dlt_logstorage_check_ctids, .is_opt = 1 }, [DLT_LOGSTORAGE_FILTER_CONF_LOGLEVEL] = { .key = "LogLevel", .func = dlt_logstorage_check_loglevel, .is_opt = 0 }, [DLT_LOGSTORAGE_FILTER_CONF_RESET_LOGLEVEL] = { .key = NULL, .func = dlt_logstorage_check_reset_loglevel, .is_opt = 0 }, [DLT_LOGSTORAGE_FILTER_CONF_FILE] = { .key = "File", .func = dlt_logstorage_check_filename, .is_opt = 0 }, [DLT_LOGSTORAGE_FILTER_CONF_FILESIZE] = { .key = "FileSize", .func = dlt_logstorage_check_filesize, .is_opt = 0 }, [DLT_LOGSTORAGE_FILTER_CONF_NOFILES] = { .key = "NOFiles", .func = dlt_logstorage_check_nofiles, .is_opt = 0 }, [DLT_LOGSTORAGE_FILTER_CONF_SYNCBEHAVIOR] = { .key = "SyncBehavior", .func = dlt_logstorage_check_sync_strategy, .is_opt = 1 }, [DLT_LOGSTORAGE_FILTER_CONF_ECUID] = { .key = "EcuID", .func = dlt_logstorage_check_ecuid, .is_opt = 1 }, [DLT_LOGSTORAGE_FILTER_CONF_SPECIFIC_SIZE] = { .key = "SpecificSize", .func = dlt_logstorage_check_specificsize, .is_opt = 1 } }; /* */ DLT_STATIC DltLogstorageFilterConf filter_nonverbose_storage_entries[DLT_LOGSTORAGE_FILTER_CONF_COUNT] = { [DLT_LOGSTORAGE_FILTER_CONF_LOGAPPNAME] = { .key = NULL, .func = dlt_logstorage_check_apids, .is_opt = 0 }, [DLT_LOGSTORAGE_FILTER_CONF_CONTEXTNAME] = { .key = NULL, .func = dlt_logstorage_check_ctids, .is_opt = 0 }, [DLT_LOGSTORAGE_FILTER_CONF_LOGLEVEL] = { .key = NULL, .func = dlt_logstorage_check_loglevel, .is_opt = 0 }, [DLT_LOGSTORAGE_FILTER_CONF_RESET_LOGLEVEL] = { .key = NULL, .func = NULL, .is_opt = 0 }, [DLT_LOGSTORAGE_FILTER_CONF_FILE] = { .key = "File", .func = dlt_logstorage_check_filename, .is_opt = 0 }, [DLT_LOGSTORAGE_FILTER_CONF_FILESIZE] = { .key = "FileSize", .func = dlt_logstorage_check_filesize, .is_opt = 0 }, [DLT_LOGSTORAGE_FILTER_CONF_NOFILES] = { .key = "NOFiles", .func = dlt_logstorage_check_nofiles, .is_opt = 0 }, [DLT_LOGSTORAGE_FILTER_CONF_SYNCBEHAVIOR] = { .key = NULL, .func = dlt_logstorage_check_sync_strategy, .is_opt = 1 }, [DLT_LOGSTORAGE_FILTER_CONF_ECUID] = { .key = "EcuID", .func = dlt_logstorage_check_ecuid, .is_opt = 0 }, [DLT_LOGSTORAGE_FILTER_CONF_SPECIFIC_SIZE] = { .key = NULL, .func = dlt_logstorage_check_specificsize, .is_opt = 1 } }; DLT_STATIC DltLogstorageFilterConf filter_nonverbose_control_entries[DLT_LOGSTORAGE_FILTER_CONF_COUNT] = { [DLT_LOGSTORAGE_FILTER_CONF_LOGAPPNAME] = { .key = "LogAppName", .func = dlt_logstorage_check_apids, .is_opt = 0 }, [DLT_LOGSTORAGE_FILTER_CONF_CONTEXTNAME] = { .key = "ContextName", .func = dlt_logstorage_check_ctids, .is_opt = 0 }, [DLT_LOGSTORAGE_FILTER_CONF_LOGLEVEL] = { .key = "LogLevel", .func = dlt_logstorage_check_loglevel, .is_opt = 0 }, [DLT_LOGSTORAGE_FILTER_CONF_RESET_LOGLEVEL] = { .key = "ResetLogLevel", .func = dlt_logstorage_check_reset_loglevel, .is_opt = 1 }, [DLT_LOGSTORAGE_FILTER_CONF_FILE] = { .key = NULL, .func = dlt_logstorage_check_filename, .is_opt = 0 }, [DLT_LOGSTORAGE_FILTER_CONF_FILESIZE] = { .key = NULL, .func = dlt_logstorage_check_filesize, .is_opt = 0 }, [DLT_LOGSTORAGE_FILTER_CONF_NOFILES] = { .key = NULL, .func = dlt_logstorage_check_nofiles, .is_opt = 0 }, [DLT_LOGSTORAGE_FILTER_CONF_SYNCBEHAVIOR] = { .key = NULL, .func = dlt_logstorage_check_sync_strategy, .is_opt = 1 }, [DLT_LOGSTORAGE_FILTER_CONF_ECUID] = { .key = "EcuID", .func = dlt_logstorage_check_ecuid, .is_opt = 0 }, [DLT_LOGSTORAGE_FILTER_CONF_SPECIFIC_SIZE] = { .key = NULL, .func = dlt_logstorage_check_specificsize, .is_opt = 1 } }; /** * Check filter configuration parameter is valid. * * @param config DltLogStorageFilterConfig * @param ctype DltLogstorageFilterConfType * @param value specified property value from configuration file * @return 0 on success, -1 otherwise */ DLT_STATIC int dlt_logstorage_check_param(DltLogStorageFilterConfig *config, DltLogstorageFilterConfType ctype, char *value) { if ((config == NULL) || (value == NULL)) return -1; if (ctype < DLT_LOGSTORAGE_FILTER_CONF_COUNT) return filter_cfg_entries[ctype].func(config, value); return -1; } DLT_STATIC int dlt_logstorage_get_filter_value(DltConfigFile *config_file, char *sec_name, int index, char *value) { int ret = 0; int config_sec_len = strlen(DLT_OFFLINE_LOGSTORAGE_CONFIG_SECTION); int storage_sec_len = strlen(DLT_OFFLINE_LOGSTORAGE_NONVERBOSE_STORAGE_SECTION); int control_sec_len = strlen(DLT_OFFLINE_LOGSTORAGE_NONVERBOSE_CONTROL_SECTION); if ((config_file == NULL) || (sec_name == NULL)) return DLT_OFFLINE_LOGSTORAGE_FILTER_ERROR; /* Branch based on section name, no complete string compare needed */ if (strncmp(sec_name, DLT_OFFLINE_LOGSTORAGE_CONFIG_SECTION, config_sec_len) == 0) { if (filter_cfg_entries[index].key != NULL) { ret = dlt_config_file_get_value(config_file, sec_name, filter_cfg_entries[index].key, value); if ((ret != 0) && (filter_cfg_entries[index].is_opt == 0)) { dlt_vlog(LOG_WARNING, "Invalid configuration in section: %s -> %s : %s\n", sec_name, filter_cfg_entries[index].key, value); return DLT_OFFLINE_LOGSTORAGE_FILTER_ERROR; } if ((ret != 0) && (filter_cfg_entries[index].is_opt == 1)) { dlt_vlog(LOG_DEBUG, "Optional parameter %s not specified\n", filter_cfg_entries[index].key); return DLT_OFFLINE_LOGSTORAGE_FILTER_CONTINUE; } } else { return DLT_OFFLINE_LOGSTORAGE_FILTER_CONTINUE; } } else if (strncmp(sec_name, DLT_OFFLINE_LOGSTORAGE_NONVERBOSE_STORAGE_SECTION, storage_sec_len) == 0) { if (filter_nonverbose_storage_entries[index].key != NULL) { if (dlt_config_file_get_value(config_file, sec_name, filter_nonverbose_storage_entries[index].key, value) != 0) { dlt_vlog(LOG_WARNING, "Invalid configuration in section: %s -> %s : %s\n", sec_name, filter_nonverbose_storage_entries[index].key, value); return DLT_OFFLINE_LOGSTORAGE_FILTER_ERROR; } } else { return DLT_OFFLINE_LOGSTORAGE_FILTER_CONTINUE; } } else if ((strncmp(sec_name, DLT_OFFLINE_LOGSTORAGE_NONVERBOSE_CONTROL_SECTION, control_sec_len) == 0)) { if (filter_nonverbose_control_entries[index].key != NULL) { if (dlt_config_file_get_value(config_file, sec_name, filter_nonverbose_control_entries[index].key, value) != 0) { dlt_vlog(LOG_WARNING, "Invalid configuration in section: %s -> %s : %s\n", sec_name, filter_nonverbose_control_entries[index].key, value); return DLT_OFFLINE_LOGSTORAGE_FILTER_ERROR; } } else { return DLT_OFFLINE_LOGSTORAGE_FILTER_CONTINUE; } } else { dlt_log(LOG_ERR, "Error: Section name not valid \n"); return DLT_OFFLINE_LOGSTORAGE_FILTER_ERROR; } return 0; } DLT_STATIC int dlt_logstorage_setup_table(DltLogStorage *handle, DltLogStorageFilterConfig *tmp_data) { int ret = 0; /* depending on the specified strategy set function pointers for * prepare, write and sync */ dlt_logstorage_filter_set_strategy(tmp_data, tmp_data->sync); ret = dlt_logstorage_prepare_table(handle, tmp_data); if (ret != 0) { dlt_vlog(LOG_ERR, "%s Error: Storing filter values failed\n", __func__); ret = DLT_OFFLINE_LOGSTORAGE_STORE_FILTER_ERROR; } return ret; } /*Return : * DLT_OFFLINE_LOGSTORAGE_FILTER_ERROR - On filter properties or value is not valid * DLT_OFFLINE_LOGSTORAGE_STORE_FILTER_ERROR - On error while storing in hash table */ DLT_STATIC int dlt_daemon_offline_setup_filter_properties(DltLogStorage *handle, DltConfigFile *config_file, char *sec_name) { DltLogStorageFilterConfig tmp_data; char value[DLT_CONFIG_FILE_ENTRY_MAX_LEN + 1] = { '\0' }; int i = 0; int ret = 0; if ((handle == NULL) || (config_file == NULL) || (sec_name == NULL)) return DLT_OFFLINE_LOGSTORAGE_STORE_FILTER_ERROR; memset(&tmp_data, 0, sizeof(DltLogStorageFilterConfig)); tmp_data.apids = NULL; tmp_data.ctids = NULL; tmp_data.file_name = NULL; tmp_data.ecuid = NULL; tmp_data.log_level = DLT_LOG_VERBOSE; tmp_data.reset_log_level = DLT_LOG_OFF; tmp_data.records = NULL; tmp_data.log = NULL; tmp_data.cache = NULL; for (i = 0; i < DLT_LOGSTORAGE_FILTER_CONF_COUNT; i++) { ret = dlt_logstorage_get_filter_value(config_file, sec_name, i, value); if (ret == DLT_OFFLINE_LOGSTORAGE_FILTER_ERROR) return ret; if (ret == DLT_OFFLINE_LOGSTORAGE_FILTER_CONTINUE) continue; /* check value and store temporary */ ret = dlt_logstorage_check_param(&tmp_data, i, value); if (ret != 0) { if (tmp_data.apids != NULL) { free(tmp_data.apids); tmp_data.apids = NULL; } if (tmp_data.ctids != NULL) { free(tmp_data.ctids); tmp_data.ctids = NULL; } if (tmp_data.file_name != NULL) { free(tmp_data.file_name); tmp_data.file_name = NULL; } if (tmp_data.ecuid != NULL) { free(tmp_data.ecuid); tmp_data.ecuid = NULL; } return DLT_OFFLINE_LOGSTORAGE_FILTER_ERROR; } } /* filter configuration is valid */ ret = dlt_logstorage_setup_table(handle, &tmp_data); if (ret != 0) { dlt_vlog(LOG_ERR, "%s Error: Storing filter values failed\n", __func__); ret = DLT_OFFLINE_LOGSTORAGE_STORE_FILTER_ERROR; } else { /* move to next free filter configuration, if no error occurred */ handle->num_configs += 1; } /* free tmp_data */ dlt_logstorage_filter_config_free(&tmp_data); return ret; } /** * dlt_logstorage_store_filters * * This function reads the filter keys and values * and stores them into the hash map * * @param handle DLT Logstorage handle * @param config_file_name Configuration file name * @return 0 on success, -1 on error, 1 on warning * */ DLT_STATIC int dlt_logstorage_store_filters(DltLogStorage *handle, char *config_file_name) { DltConfigFile *config = NULL; int sec = 0; int num_sec = 0; int ret = 0; /* we have to make sure that this function returns success if atleast one * filter configuration is valid and stored */ int valid = -1; if (config_file_name == NULL) { dlt_vlog(LOG_ERR, "%s unexpected parameter received\n", __func__); return -1; } config = dlt_config_file_init(config_file_name); if (config == NULL) { dlt_log(LOG_CRIT, "Failed to open filter configuration file\n"); return -1; } dlt_config_file_get_num_sections(config, &num_sec); for (sec = 0; sec < num_sec; sec++) { char sec_name[DLT_CONFIG_FILE_ENTRY_MAX_LEN + 1]; if (dlt_config_file_get_section_name(config, sec, sec_name) == -1) { dlt_log(LOG_CRIT, "Failed to read section name\n"); dlt_config_file_release(config); return -1; } if (strstr(sec_name, GENERAL_BASE_NAME) != NULL) { dlt_log(LOG_CRIT, "General configuration not supported \n"); continue; } else if (dlt_logstorage_validate_filter_name(sec_name) == 0) { ret = dlt_daemon_offline_setup_filter_properties(handle, config, sec_name); if (ret == DLT_OFFLINE_LOGSTORAGE_STORE_FILTER_ERROR) { break; } else if (ret == DLT_OFFLINE_LOGSTORAGE_FILTER_ERROR) { valid = 1; dlt_vlog(LOG_WARNING, "%s filter configuration is invalid \n", sec_name); /* Continue reading next filter section */ continue; } else /* Filter properties read and stored successfuly */ if (valid != 1) valid = 0; } else { /* unknown section */ dlt_vlog(LOG_WARNING, "Unknown section: %s", sec_name); } } dlt_config_file_release(config); return valid; } /** * dlt_logstorage_load_config * * Read dlt_logstorage.conf file and setup filters in hash table * Hash table key consists of "APID:CTID", e.g "APP1:CTX1". If * wildcards used for application id or context id, the hash table * key consists of none wildcard value, e.g. apid=.*, cxid=CTX1 * results in "CTX1". * * Combination of two wildcards is not allowed. * * @param handle DLT Logstorage handle * @return 0 on success, -1 on error, 1 on warning */ DLT_STATIC int dlt_logstorage_load_config(DltLogStorage *handle) { char config_file_name[PATH_MAX] = {0}; int ret = 0; /* Check if handle is NULL or already initialized or already configured */ if ((handle == NULL) || (handle->connection_type != DLT_OFFLINE_LOGSTORAGE_DEVICE_CONNECTED)) return -1; /* Check if this device config was already setup */ if (handle->config_status == DLT_OFFLINE_LOGSTORAGE_CONFIG_DONE) { dlt_vlog(LOG_ERR, "%s: Device already configured. Send disconnect first.\n", __func__); return -1; } if (snprintf(config_file_name, PATH_MAX, "%s/%s", handle->device_mount_point, DLT_OFFLINE_LOGSTORAGE_CONFIG_FILE_NAME) < 0) { dlt_log(LOG_ERR, "Creating configuration file path string failed\n"); return -1; } config_file_name[PATH_MAX - 1] = 0; ret = dlt_logstorage_store_filters(handle, config_file_name); if (ret == 1) { handle->config_status = DLT_OFFLINE_LOGSTORAGE_CONFIG_DONE; return 1; } else if (ret != 0) { dlt_log(LOG_ERR, "dlt_logstorage_load_config Error : Storing filters failed\n"); return -1; } handle->config_status = DLT_OFFLINE_LOGSTORAGE_CONFIG_DONE; return 0; } /** * dlt_logstorage_device_connected * * Initializes DLT Offline Logstorage with respect to device status * * @param handle DLT Logstorage handle * @param mount_point Device mount path * @return 0 on success, -1 on error, 1 on warning */ int dlt_logstorage_device_connected(DltLogStorage *handle, char *mount_point) { if ((handle == NULL) || (mount_point == NULL)) { dlt_log(LOG_ERR, "Handle error \n"); return -1; } if (handle->connection_type == DLT_OFFLINE_LOGSTORAGE_DEVICE_CONNECTED) { dlt_log(LOG_WARNING, "Device already connected. Send disconnect, connect request\n"); dlt_logstorage_device_disconnected( handle, DLT_LOGSTORAGE_SYNC_ON_DEVICE_DISCONNECT); } strncpy(handle->device_mount_point, mount_point, DLT_MOUNT_PATH_MAX); handle->device_mount_point[DLT_MOUNT_PATH_MAX] = 0; handle->connection_type = DLT_OFFLINE_LOGSTORAGE_DEVICE_CONNECTED; handle->config_status = 0; handle->write_errors = 0; handle->num_configs = 0; /* Setup logstorage with config file settings */ return dlt_logstorage_load_config(handle); } /** * dlt_logstorage_device_disconnected * * De-Initializes DLT Offline Logstorage with respect to device status * * @param handle DLT Logstorage handle * @param reason Reason for disconnect * @return 0 on success, -1 on error * */ int dlt_logstorage_device_disconnected(DltLogStorage *handle, int reason) { if (handle == NULL) return -1; /* If configuration loading was done, free it */ if (handle->config_status == DLT_OFFLINE_LOGSTORAGE_CONFIG_DONE) dlt_logstorage_free(handle, reason); /* Reset all device status */ memset(handle->device_mount_point, 0, sizeof(char) * (DLT_MOUNT_PATH_MAX + 1)); handle->connection_type = DLT_OFFLINE_LOGSTORAGE_DEVICE_DISCONNECTED; handle->config_status = 0; handle->write_errors = 0; handle->num_configs = 0; return 0; } /** * dlt_logstorage_get_loglevel_by_key * * Obtain the log level for the provided key * This function can be used to obtain log level when the actual * key stored in the Hash map is availble with the caller * * @param handle DltLogstorage handle * @param key key to search for in Hash MAP * @return log level on success:, -1 on error */ int dlt_logstorage_get_loglevel_by_key(DltLogStorage *handle, char *key) { DltLogStorageFilterConfig *config[DLT_CONFIG_FILE_SECTIONS_MAX] = { 0 }; int num_configs = 0; int i = 0; int log_level = 0; /* Check if handle is NULL,already initialized or already configured */ if ((handle == NULL) || (key == NULL) || (handle->connection_type != DLT_OFFLINE_LOGSTORAGE_DEVICE_CONNECTED) || (handle->config_status != DLT_OFFLINE_LOGSTORAGE_CONFIG_DONE)) return -1; num_configs = dlt_logstorage_list_find(key, &(handle->config_list), config); if (num_configs == 0) { dlt_vlog(LOG_WARNING, "Configuration for key [%s] not found!\n", key); return -1; } else if (num_configs == 1) { if (config[0] != NULL) { log_level = config[0]->log_level; } } else { /** * Multiple configurations found, raise a warning to the user and go * for the more verbose one. */ dlt_vlog(LOG_WARNING, "Multiple configuration for key [%s] found," " return the highest log level!\n", key); for (i = 0; i < num_configs; i++) { if ((config[i] != NULL) && (config[i]->log_level > log_level)) { log_level = config[i]->log_level; } } } return log_level; } /** * dlt_logstorage_get_config * * Obtain the configuration data of all filters for provided apid and ctid * * @param handle DltLogStorage handle * @param config [out] Pointer to array of filter configurations * @param apid application id * @param ctid context id * @param ecuid ecu id * @return number of configurations found */ int dlt_logstorage_get_config(DltLogStorage *handle, DltLogStorageFilterConfig **config, char *apid, char *ctid, char *ecuid) { DltLogStorageFilterConfig **cur_config_ptr = NULL; char key[DLT_CONFIG_FILE_SECTIONS_MAX][DLT_OFFLINE_LOGSTORAGE_MAX_KEY_LEN] = { { '\0' }, { '\0' }, { '\0' } }; int i = 0; int apid_len = 0; int ctid_len = 0; int ecuid_len = 0; int num_configs = 0; int num = 0; /* Check if handle is NULL,already initialized or already configured */ if ((handle == NULL) || (config == NULL) || (handle->connection_type != DLT_OFFLINE_LOGSTORAGE_DEVICE_CONNECTED) || (handle->config_status != DLT_OFFLINE_LOGSTORAGE_CONFIG_DONE) || (ecuid == NULL)) return 0; /* Prepare possible keys with * Possible combinations are * ecu:: * ecu:apid:ctid * :apid:ctid * ecu::ctid * ecu:apid: * ::ctid * :apid: */ ecuid_len = strlen(ecuid); if (ecuid_len > DLT_ID_SIZE) ecuid_len = DLT_ID_SIZE; if ((apid == NULL) && (ctid == NULL)) { /* ecu:: */ strncpy(key[0], ecuid, ecuid_len); strncat(key[0], ":", 1); strncat(key[0], ":", 1); num_configs = dlt_logstorage_list_find(key[0], &(handle->config_list), config); return num_configs; } apid_len = strlen(apid); if (apid_len > DLT_ID_SIZE) apid_len = DLT_ID_SIZE; ctid_len = strlen(ctid); if (ctid_len > DLT_ID_SIZE) ctid_len = DLT_ID_SIZE; /* :apid: */ strncpy(key[0], ":", 1); strncat(key[0], apid, apid_len); strncat(key[0], ":", 1); /* ::ctid */ strncpy(key[1], ":", 1); strncat(key[1], ":", 1); strncat(key[1], ctid, ctid_len); /* :apid:ctid */ strncpy(key[2], ":", 1); strncat(key[2], apid, apid_len); strncat(key[2], ":", 1); strncat(key[2], ctid, ctid_len); /* ecu:apid:ctid */ strncpy(key[3], ecuid, ecuid_len); strncat(key[3], ":", 1); strncat(key[3], apid, apid_len); strncat(key[3], ":", 1); strncat(key[3], ctid, ctid_len); /* ecu:apid: */ strncpy(key[4], ecuid, ecuid_len); strncat(key[4], ":", 1); strncat(key[4], apid, apid_len); strncat(key[4], ":", 1); /* ecu::ctid */ strncpy(key[5], ecuid, ecuid_len); strncat(key[5], ":", 1); strncat(key[5], ":", 1); strncat(key[5], ctid, ctid_len); /* ecu:: */ strncpy(key[6], ecuid, ecuid_len); strncat(key[6], ":", 1); strncat(key[6], ":", 1); /* Search the list three times with keys as -apid: , :ctid and apid:ctid */ for (i = 0; i < DLT_OFFLINE_LOGSTORAGE_MAX_POSSIBLE_KEYS; i++) { cur_config_ptr = &config[num_configs]; num = dlt_logstorage_list_find(key[i], &(handle->config_list), cur_config_ptr); num_configs += num; /* If all filter configurations matched, stop and return */ if (num_configs == handle->num_configs) { break; } } return num_configs; } /** * dlt_logstorage_filter * * Check if log message need to be stored in a certain device based on filter * config * - get all DltLogStorageFilterConfig from hash table possible by given * apid/ctid (apid:, :ctid, apid:ctid * - for each found structure, compare message log level with configured one * * @param handle DltLogStorage handle * @param config Pointer to array of filter configurations * @param apid application id * @param ctid context id * @param log_level Log level of message * @param ecuid EcuID given in the message * @return number of found configurations */ DLT_STATIC int dlt_logstorage_filter(DltLogStorage *handle, DltLogStorageFilterConfig **config, char *apid, char *ctid, char *ecuid, int log_level) { int i = 0; int num = 0; if ((handle == NULL) || (config == NULL) || (ecuid == NULL)) return -1; /* filter on names: find DltLogStorageFilterConfig structures */ num = dlt_logstorage_get_config(handle, config, apid, ctid, ecuid); if (num == 0) { dlt_log(LOG_DEBUG, "No valid filter configuration found\n"); return 0; } for (i = 0 ; i < num ; i++) { if (config[i] == NULL) continue; /* filter on log level */ if (log_level > config[i]->log_level) { config[i] = NULL; continue; } /* filter on ECU id only if EcuID is set */ if (config[i]->ecuid != NULL) { if (strncmp(ecuid, config[i]->ecuid, DLT_ID_SIZE) != 0) config[i] = NULL; } } return num; } /** * dlt_logstorage_write * * Write a message to one or more configured log files, based on filter * configuration. * * @param handle DltLogStorage handle * @param uconfig User configurations for log file * @param data1 Data buffer of message header * @param size1 Size of message header buffer * @param data2 Data buffer of extended message body * @param size2 Size of extended message body * @param data3 Data buffer of message body * @param size3 Size of message body * @return 0 on success or write errors < max write errors, -1 on error */ int dlt_logstorage_write(DltLogStorage *handle, DltLogStorageUserConfig *uconfig, unsigned char *data1, int size1, unsigned char *data2, int size2, unsigned char *data3, int size3) { DltLogStorageFilterConfig *config[DLT_CONFIG_FILE_SECTIONS_MAX] = { 0 }; int i = 0; int ret = 0; int num = 0; int err = 0; /* data2 contains DltStandardHeader, DltStandardHeaderExtra and * DltExtendedHeader. We are interested in ecuid, apid, ctid and loglevel */ DltExtendedHeader *extendedHeader = NULL; DltStandardHeaderExtra *extraHeader = NULL; DltStandardHeader *standardHeader = NULL; unsigned int standardHeaderExtraLen = sizeof(DltStandardHeaderExtra); unsigned int header_len = 0; int log_level = -1; if ((handle == NULL) || (uconfig == NULL) || (data1 == NULL) || (data2 == NULL) || (data3 == NULL) || (handle->connection_type != DLT_OFFLINE_LOGSTORAGE_DEVICE_CONNECTED) || (handle->config_status != DLT_OFFLINE_LOGSTORAGE_CONFIG_DONE)) return 0; /* Calculate real length of DltStandardHeaderExtra */ standardHeader = (DltStandardHeader *)data2; if (!DLT_IS_HTYP_WEID(standardHeader->htyp)) standardHeaderExtraLen -= DLT_ID_SIZE; if (!DLT_IS_HTYP_WSID(standardHeader->htyp)) standardHeaderExtraLen -= DLT_SIZE_WSID; if (!DLT_IS_HTYP_WTMS(standardHeader->htyp)) standardHeaderExtraLen -= DLT_SIZE_WTMS; extraHeader = (DltStandardHeaderExtra *)(data2 + sizeof(DltStandardHeader)); if (DLT_IS_HTYP_UEH(standardHeader->htyp)) { header_len = sizeof(DltStandardHeader) + sizeof(DltExtendedHeader) + standardHeaderExtraLen; /* check if size2 is big enough to contain expected DLT message header */ if ((unsigned int)size2 < header_len) { dlt_log(LOG_ERR, "DLT message header is too small\n"); return 0; } extendedHeader = (DltExtendedHeader *)(data2 + sizeof(DltStandardHeader) + standardHeaderExtraLen); log_level = DLT_GET_MSIN_MTIN(extendedHeader->msin); /* check if log message need to be stored in a certain device based on * filter configuration */ num = dlt_logstorage_filter(handle, config, extendedHeader->apid, extendedHeader->ctid, extraHeader->ecu, log_level); if ((num == 0) || (num == -1)) { dlt_log(LOG_DEBUG, "No valid filter configuration found!\n"); return 0; } } else { header_len = sizeof(DltStandardHeader) + standardHeaderExtraLen; /* check if size2 is big enough to contain expected DLT message header */ if ((unsigned int)size2 < header_len) { dlt_log(LOG_ERR, "DLT message header is too small (without extended header)\n"); return 0; } log_level = DLT_LOG_VERBOSE; /* check if log message need to be stored in a certain device based on * filter configuration */ num = dlt_logstorage_filter(handle, config, NULL, NULL, extraHeader->ecu, log_level); if ((num == 0) || (num == -1)) { dlt_log(LOG_DEBUG, "No valid filter configuration found!\n"); return 0; } } /* store log message in every found filter */ for (i = 0; i < num; i++) { if (config[i] == NULL) continue; /* If file name is not present, the filter is non verbose control filter * hence skip storing */ if (config[i]->file_name == NULL) continue; /* prepare log file (create and/or open)*/ ret = config[i]->dlt_logstorage_prepare(config[i], uconfig, handle->device_mount_point, size1 + size2 + size3); if (ret == 0) { /* log data (write) */ ret = config[i]->dlt_logstorage_write(config[i], uconfig, handle->device_mount_point, data1, size1, data2, size2, data3, size3); if (ret == 0) { /* flush to be sure log is stored on device */ ret = config[i]->dlt_logstorage_sync(config[i], uconfig, handle->device_mount_point, DLT_LOGSTORAGE_SYNC_ON_MSG); if (ret != 0) dlt_log(LOG_ERR, "dlt_logstorage_write: Unable to sync.\n"); } else { handle->write_errors += 1; if (handle->write_errors >= DLT_OFFLINE_LOGSTORAGE_MAX_WRITE_ERRORS) err = -1; dlt_log(LOG_ERR, "dlt_logstorage_write: Unable to write.\n"); } } else { dlt_log(LOG_ERR, "dlt_logstorage_write: Unable to prepare.\n"); } } return err; } /** * dlt_logstorage_sync_caches * * Write Cache data to file * * @param handle DltLogStorage handle * @return 0 on success, -1 on error */ int dlt_logstorage_sync_caches(DltLogStorage *handle) { DltLogStorageFilterList **tmp = NULL; if (handle == NULL) return -1; tmp = &(handle->config_list); while (*(tmp) != NULL) { if ((*tmp)->data != NULL) { if ((*tmp)->data->dlt_logstorage_sync((*tmp)->data, &handle->uconfig, handle->device_mount_point, DLT_LOGSTORAGE_SYNC_ON_DEMAND) != 0) dlt_vlog(LOG_ERR, "%s: Sync failed. Continue with next cache.\n", __func__); } tmp = &(*tmp)->next; } return 0; } dlt-daemon-2.18.4/src/offlinelogstorage/dlt_offline_logstorage.h000066400000000000000000000353631353342203500250300ustar00rootroot00000000000000/** * Copyright (C) 2013 - 2015 Advanced Driver Information Technology. * This code is developed by Advanced Driver Information Technology. * Copyright of Advanced Driver Information Technology, Bosch and DENSO. * * DLT offline log storage functionality header file. * * \copyright * This Source Code Form is subject to the terms of the * Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with * this file, You can obtain one at http://mozilla.org/MPL/2.0/. * * * \author Syed Hameed ADIT 2013 - 2015 * \author Christoph Lipka ADIT 2015 * * \file: dlt_offline_logstorage.h * For further information see http://www.genivi.org/. */ /******************************************************************************* ** ** ** SRC-MODULE: dlt_offline_logstorage.h ** ** ** ** TARGET : linux ** ** ** ** PROJECT : DLT ** ** ** ** AUTHOR : Syed Hameed shameed@jp.adit-jv.com ** ** Christoph Lipka clipka@jp.adit-jv.com ** ** PURPOSE : ** ** ** ** REMARKS : ** ** ** ** PLATFORM DEPENDANT [yes/no]: yes ** ** ** ** TO BE CHANGED BY USER [yes/no]: no ** ** ** *******************************************************************************/ /******************************************************************************* ** Author Identity ** ******************************************************************************** ** ** ** Initials Name Company ** ** -------- ------------------------- ---------------------------------- ** ** sh Syed Hameed ADIT ** ** cl Christoph Lipka ADIT ** *******************************************************************************/ #ifndef DLT_OFFLINE_LOGSTORAGE_H #define DLT_OFFLINE_LOGSTORAGE_H #include #include "dlt_common.h" #include "dlt-daemon_cfg.h" #include "dlt_config_file_parser.h" #define DLT_OFFLINE_LOGSTORAGE_MAXIDS 100 /* Maximum entries for each apids and ctids */ #define DLT_OFFLINE_LOGSTORAGE_MAX_POSSIBLE_KEYS 7 /* Max number of possible keys when searching for */ #define DLT_OFFLINE_LOGSTORAGE_INIT_DONE 1 /* For device configuration status */ #define DLT_OFFLINE_LOGSTORAGE_DEVICE_CONNECTED 1 #define DLT_OFFLINE_LOGSTORAGE_FREE 0 #define DLT_OFFLINE_LOGSTORAGE_DEVICE_DISCONNECTED 0 #define DLT_OFFLINE_LOGSTORAGE_CONFIG_DONE 1 #define DLT_OFFLINE_LOGSTORAGE_SYNC_CACHES 2 /* sync logstorage caches */ #define DLT_OFFLINE_LOGSTORAGE_MAX_KEY_LEN 15 /* Maximum size for key */ #define DLT_OFFLINE_LOGSTORAGE_MAX_FILE_NAME_LEN 50 /* Maximum file name length of the log file */ #define DLT_OFFLINE_LOGSTORAGE_FILE_EXTENSION_LEN 4 #define DLT_OFFLINE_LOGSTORAGE_INDEX_LEN 3 #define DLT_OFFLINE_LOGSTORAGE_MAX_INDEX 999 #define DLT_OFFLINE_LOGSTORAGE_TIMESTAMP_LEN 16 #define DLT_OFFLINE_LOGSTORAGE_INDEX_OFFSET (DLT_OFFLINE_LOGSTORAGE_TIMESTAMP_LEN + \ DLT_OFFLINE_LOGSTORAGE_FILE_EXTENSION_LEN + \ DLT_OFFLINE_LOGSTORAGE_INDEX_LEN) #define DLT_OFFLINE_LOGSTORAGE_MAX_LOG_FILE_LEN (DLT_OFFLINE_LOGSTORAGE_MAX_FILE_NAME_LEN + \ DLT_OFFLINE_LOGSTORAGE_TIMESTAMP_LEN + \ DLT_OFFLINE_LOGSTORAGE_INDEX_LEN + \ DLT_OFFLINE_LOGSTORAGE_FILE_EXTENSION_LEN + 1) #define DLT_OFFLINE_LOGSTORAGE_CONFIG_DIR_PATH_LEN 50 #define DLT_OFFLINE_LOGSTORAGE_CONFIG_FILE_NAME "dlt_logstorage.conf" /* +3 because of device number and \0 */ #define DLT_OFFLINE_LOGSTORAGE_MAX_PATH_LEN (DLT_OFFLINE_LOGSTORAGE_MAX_LOG_FILE_LEN + \ DLT_OFFLINE_LOGSTORAGE_CONFIG_DIR_PATH_LEN + 3) #define DLT_OFFLINE_LOGSTORAGE_MAX(A, B) ((A) > (B) ? (A) : (B)) #define DLT_OFFLINE_LOGSTORAGE_MIN(A, B) ((A) < (B) ? (A) : (B)) #define DLT_OFFLINE_LOGSTORAGE_MAX_WRITE_ERRORS 5 #define DLT_OFFLINE_LOGSTORAGE_MAX_KEY_NUM 8 #define DLT_OFFLINE_LOGSTORAGE_CONFIG_SECTION "FILTER" #define DLT_OFFLINE_LOGSTORAGE_GENERAL_CONFIG_SECTION "GENERAL" #define DLT_OFFLINE_LOGSTORAGE_NONVERBOSE_STORAGE_SECTION "NON-VERBOSE-STORAGE-FILTER" #define DLT_OFFLINE_LOGSTORAGE_NONVERBOSE_CONTROL_SECTION "NON-VERBOSE-LOGLEVEL-CTRL" /* Offline Logstorage sync strategies */ #define DLT_LOGSTORAGE_SYNC_ON_ERROR -1 /* error case */ #define DLT_LOGSTORAGE_SYNC_UNSET 0 /* strategy not set */ #define DLT_LOGSTORAGE_SYNC_ON_MSG 1 /* default, on message sync */ #define DLT_LOGSTORAGE_SYNC_ON_DAEMON_EXIT (1 << 1) /* sync on daemon exit */ #define DLT_LOGSTORAGE_SYNC_ON_DEMAND (1 << 2) /* sync on demand */ #define DLT_LOGSTORAGE_SYNC_ON_DEVICE_DISCONNECT (1 << 3) /* sync on device disconnect*/ #define DLT_LOGSTORAGE_SYNC_ON_SPECIFIC_SIZE (1 << 4) /* sync on after specific size */ #define DLT_LOGSTORAGE_SYNC_ON_FILE_SIZE (1 << 5) /* sync on file size reached */ #define DLT_OFFLINE_LOGSTORAGE_IS_STRATEGY_SET(S, s) ((S)&(s)) /* logstorage max cache */ unsigned int g_logstorage_cache_max; /* current logstorage cache size */ unsigned int g_logstorage_cache_size; typedef struct { unsigned int offset; /* current write offset */ unsigned int wrap_around_cnt; /* wrap around counter */ unsigned int last_sync_offset; /* last sync position */ unsigned int end_sync_offset; /* end position of previous round */ } DltLogStorageCacheFooter; typedef struct { /* File name user configurations */ int logfile_timestamp; /* Timestamp set/reset */ char logfile_delimiter; /* Choice of delimiter */ unsigned int logfile_maxcounter; /* Maximum file index counter */ unsigned int logfile_counteridxlen; /* File index counter length */ } DltLogStorageUserConfig; typedef struct DltLogStorageFileList { /* List for filenames */ char *name; /* Filename */ unsigned int idx; /* File index */ struct DltLogStorageFileList *next; } DltLogStorageFileList; typedef struct DltLogStorageFilterConfig DltLogStorageFilterConfig; struct DltLogStorageFilterConfig { /* filter section */ char *apids; /* Application IDs configured for filter */ char *ctids; /* Context IDs configured for filter */ int log_level; /* Log level number configured for filter */ int reset_log_level; /* reset Log level to be sent on disconnect */ char *file_name; /* File name for log storage configured for filter */ unsigned int file_size; /* MAX File size of storage file configured for filter */ unsigned int num_files; /* MAX number of storage files configured for filters */ int sync; /* Sync strategy */ char *ecuid; /* ECU identifier */ /* callback function for filter configurations */ int (*dlt_logstorage_prepare)(DltLogStorageFilterConfig *config, DltLogStorageUserConfig *file_config, char *dev_path, int log_msg_size); int (*dlt_logstorage_write)(DltLogStorageFilterConfig *config, DltLogStorageUserConfig *file_config, char *dev_path, unsigned char *data1, int size1, unsigned char *data2, int size2, unsigned char *data3, int size3); /* status is strategy, e.g. DLT_LOGSTORAGE_SYNC_ON_MSG is used when callback * is called on message received */ int (*dlt_logstorage_sync)(DltLogStorageFilterConfig *config, DltLogStorageUserConfig *uconfig, char *dev_path, int status); FILE *log; /* current open log file */ void *cache; /* log data cache */ unsigned int specific_size; /* cache size used for specific_size sync strategy */ unsigned int current_write_file_offset; /* file offset for specific_size sync strategy */ DltLogStorageFileList *records; /* File name list */ }; typedef struct DltLogStorageFilterList DltLogStorageFilterList; struct DltLogStorageFilterList { char *key_list; /* List of key */ int num_keys; /* Number of keys */ DltLogStorageFilterConfig *data; /* Filter data */ DltLogStorageFilterList *next; /* Pointer to next */ }; typedef struct { DltLogStorageFilterList *config_list; /* List of all filters */ DltLogStorageUserConfig uconfig; /* User configurations for file name*/ int num_configs; /* Number of configs */ char device_mount_point[DLT_MOUNT_PATH_MAX + 1]; /* Device mount path */ unsigned int connection_type; /* Type of connection */ unsigned int config_status; /* Status of configuration */ int write_errors; /* number of write errors */ } DltLogStorage; typedef struct { char *key; /* The configuration key */ int (*func)(DltLogStorage *handle, char *value); /* conf handler */ int is_opt; /* If configuration is optional or not */ } DltLogstorageGeneralConf; typedef enum { DLT_LOGSTORAGE_GENERAL_CONF_BLOCKMODE = 0, DLT_LOGSTORAGE_GENERAL_CONF_COUNT } DltLogstorageGeneralConfType; typedef struct { char *key; /* Configuration key */ int (*func)(DltLogStorageFilterConfig *config, char *value); /* conf handler */ int is_opt; /* If configuration is optional or not */ } DltLogstorageFilterConf; typedef enum { DLT_LOGSTORAGE_FILTER_CONF_LOGAPPNAME = 0, DLT_LOGSTORAGE_FILTER_CONF_CONTEXTNAME, DLT_LOGSTORAGE_FILTER_CONF_LOGLEVEL, DLT_LOGSTORAGE_FILTER_CONF_RESET_LOGLEVEL, DLT_LOGSTORAGE_FILTER_CONF_FILE, DLT_LOGSTORAGE_FILTER_CONF_FILESIZE, DLT_LOGSTORAGE_FILTER_CONF_NOFILES, DLT_LOGSTORAGE_FILTER_CONF_SYNCBEHAVIOR, DLT_LOGSTORAGE_FILTER_CONF_ECUID, DLT_LOGSTORAGE_FILTER_CONF_SPECIFIC_SIZE, DLT_LOGSTORAGE_FILTER_CONF_COUNT } DltLogstorageFilterConfType; /** * dlt_logstorage_device_connected * * Initializes DLT Offline Logstorage with respect to device status * * * @param handle DLT Logstorage handle * @param mount_point Device mount path * @return 0 on success, -1 on error */ int dlt_logstorage_device_connected(DltLogStorage *handle, char *mount_point); /** * dlt_logstorage_device_disconnected * De-Initializes DLT Offline Logstorage with respect to device status * * @param handle DLT Logstorage handle * @param reason Reason for device disconnection * @return 0 on success, -1 on error */ int dlt_logstorage_device_disconnected(DltLogStorage *handle, int reason); /** * dlt_logstorage_get_config * * Obtain the configuration data of all filters for provided apid and ctid * For a given apid and ctid, there can be 3 possiblities of configuration * data available in the Hash map, this function will return the address * of configuration data for all these 3 combinations * * @param handle DltLogStorage handle * @param config Pointer to array of filter configurations * @param apid application id * @param ctid context id * @param ecuid ecu id * @return number of found configurations */ int dlt_logstorage_get_config(DltLogStorage *handle, DltLogStorageFilterConfig **config, char *apid, char *ctid, char *ecuid); /** * dlt_logstorage_get_loglevel_by_key * * Obtain the log level for the provided key * This function can be used to obtain log level when the actual * key stored in the Hash map is available with the caller * * @param handle DltLogstorage handle * @param key key to search for in Hash MAP * @return log level on success:, -1 on error */ int dlt_logstorage_get_loglevel_by_key(DltLogStorage *handle, char *key); /** * dlt_logstorage_write * * Write a message to one or more configured log files, based on filter * configuration. * * @param handle DltLogStorage handle * @param uconfig User configurations for log file * @param data1 Data buffer of message header * @param size1 Size of message header buffer * @param data2 Data buffer of extended message body * @param size2 Size of extended message body * @param data3 Data buffer of message body * @param size3 Size of message body * @return 0 on success or write errors < max write errors, -1 on error */ int dlt_logstorage_write(DltLogStorage *handle, DltLogStorageUserConfig *uconfig, unsigned char *data1, int size1, unsigned char *data2, int size2, unsigned char *data3, int size3); /** * dlt_logstorage_sync_caches * * Sync all caches inside the specified logstorage device. * * @param handle DltLogStorage handle * @return 0 on success, -1 otherwise */ int dlt_logstorage_sync_caches(DltLogStorage *handle); #endif /* DLT_OFFLINE_LOGSTORAGE_H */ dlt-daemon-2.18.4/src/offlinelogstorage/dlt_offline_logstorage_behavior.c000066400000000000000000001132411353342203500266720ustar00rootroot00000000000000/** * Copyright (C) 2015 Advanced Driver Information Technology. * This code is developed by Advanced Driver Information Technology. * Copyright of Advanced Driver Information Technology, Bosch and DENSO. * * DLT offline log storage functionality source file. * * \copyright * This Source Code Form is subject to the terms of the * Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with * this file, You can obtain one at http://mozilla.org/MPL/2.0/. * * * \author Christoph Lipka ADIT 2015 * \author Syed Hameed ADIT 2015 * * \file: dlt_offline_logstorage_behavior.c * For further information see http://www.genivi.org/. */ #include #include #include #include #include #include #include #include #include #include "dlt_offline_logstorage.h" #include "dlt_offline_logstorage_behavior.h" #include "dlt_offline_logstorage_behavior_internal.h" /** * dlt_logstorage_log_file_name * * Create log file name in the form configured by the user * \\\\\.dlt * * filename: given in configuration file * delimiter: Punctuation characters (configured in dlt.conf) * timestamp: yyyy-mm-dd-hh-mm-ss (enabled/disabled in dlt.conf) * index: Index len depends on wrap around value in dlt.conf * ex: wrap around = 99, index will 01..99 * * @param log_file_name contains complete logfile name * @param file_config User configurations for log file * @param name file name given in configuration file * @param idx continous index of log files * @ return None */ void dlt_logstorage_log_file_name(char *log_file_name, DltLogStorageUserConfig *file_config, char *name, int idx) { if ((log_file_name == NULL) || (file_config == NULL)) return; char file_index[10] = { '\0' }; /* create log file name */ memset(log_file_name, 0, DLT_MOUNT_PATH_MAX * sizeof(char)); strcat(log_file_name, name); strncat(log_file_name, &file_config->logfile_delimiter, 1); snprintf(file_index, 10, "%d", idx); if (file_config->logfile_maxcounter != UINT_MAX) { /* Setup 0's to be appended in file index until max index len*/ unsigned int digit_idx = 0; unsigned int i = 0; snprintf(file_index, 10, "%d", idx); digit_idx = strlen(file_index); if (file_config->logfile_counteridxlen > digit_idx) { for (i = 0 ; i < (file_config->logfile_counteridxlen - digit_idx) ; i++) strcat(log_file_name, "0"); } } strcat(log_file_name, file_index); /* Add time stamp if user has configured */ if (file_config->logfile_timestamp) { char stamp[DLT_OFFLINE_LOGSTORAGE_TIMESTAMP_LEN + 1] = { 0 }; time_t t = time(NULL); struct tm tm_info; localtime_r(&t, &tm_info); sprintf(stamp, "%c%04d%02d%02d-%02d%02d%02d", file_config->logfile_delimiter, 1900 + tm_info.tm_year, 1 + tm_info.tm_mon, tm_info.tm_mday, tm_info.tm_hour, tm_info.tm_min, tm_info.tm_sec); strcat(log_file_name, stamp); } strcat(log_file_name, ".dlt"); } /** * dlt_logstorage_sort_file_name * * Sort the filenames with index based ascending order (bubble sort) * * @param head Log filename list * @ return None */ void dlt_logstorage_sort_file_name(DltLogStorageFileList **head) { int done = 0; if ((head == NULL) || (*head == NULL) || ((*head)->next == NULL)) return; while (!done) { /* "source" of the pointer to the current node in the list struct */ DltLogStorageFileList **pv = head; DltLogStorageFileList *nd = *head; /* local iterator pointer */ DltLogStorageFileList *nx = (*head)->next; /* local next pointer */ done = 1; while (nx) { if (nd->idx > nx->idx) { nd->next = nx->next; nx->next = nd; *pv = nx; done = 0; } pv = &nd->next; nd = nx; nx = nx->next; } } } /** * dlt_logstorage_rearrange_file_name * * Rearrange the filenames in the order of latest and oldest * * @param head Log filename list * @ return None */ void dlt_logstorage_rearrange_file_name(DltLogStorageFileList **head) { DltLogStorageFileList *n_prev = NULL; DltLogStorageFileList *tail = NULL; DltLogStorageFileList *wrap_pre = NULL; DltLogStorageFileList *wrap_post = NULL; DltLogStorageFileList *n = NULL; if ((head == NULL) || (*head == NULL) || ((*head)->next == NULL)) return; for (n = *head; n != NULL; n = n->next) { if (n && n_prev) { if ((n->idx - n_prev->idx) != 1) { wrap_post = n; wrap_pre = n_prev; } } n_prev = n; } tail = n_prev; if (wrap_post && wrap_pre) { wrap_pre->next = NULL; tail->next = *head; *head = wrap_post; } } /** * dlt_logstorage_get_idx_of_log_file * * Extract index of log file name passed as input argument * * @param file file name to extract the index from * @param file_config User configurations for log file * @return index on success, -1 if no index is found */ unsigned int dlt_logstorage_get_idx_of_log_file(DltLogStorageUserConfig *file_config, char *file) { unsigned int idx = -1; char *endptr; char *filename; unsigned int filename_len = 0; unsigned int fileindex_len = 0; if ((file_config == NULL) || (file == NULL)) return -1; /* Calculate actual file name length */ filename = strchr(file, file_config->logfile_delimiter); if (filename == NULL) { dlt_vlog(LOG_ERR, "Cannot extract filename from %s\n", file); return -1; } filename_len = strlen(file) - strlen(filename); /* index is retrived from file name */ if (file_config->logfile_timestamp) { fileindex_len = strlen(file) - (DLT_OFFLINE_LOGSTORAGE_FILE_EXTENSION_LEN + DLT_OFFLINE_LOGSTORAGE_TIMESTAMP_LEN + filename_len + 1); idx = (int)strtol(&file[strlen(file) - (DLT_OFFLINE_LOGSTORAGE_FILE_EXTENSION_LEN + fileindex_len + DLT_OFFLINE_LOGSTORAGE_TIMESTAMP_LEN)], &endptr, 10); } else { fileindex_len = strlen(file) - (DLT_OFFLINE_LOGSTORAGE_FILE_EXTENSION_LEN + filename_len + 1); idx = (int)strtol(&file[strlen(file) - (DLT_OFFLINE_LOGSTORAGE_FILE_EXTENSION_LEN + fileindex_len)], &endptr, 10); } if ((endptr == file) || (idx == 0)) dlt_log(LOG_ERR, "Unable to calculate index from log file name. Reset to 001.\n"); return idx; } /** * dlt_logstorage_storage_dir_info * * Read file names of storage directory. * Update the file list, arrange it in order of latest and oldest * * @param file_config User configurations for log file * @param path Path to storage directory * @param config DltLogStorageFilterConfig * @return 0 on success, -1 on error */ int dlt_logstorage_storage_dir_info(DltLogStorageUserConfig *file_config, char *path, DltLogStorageFilterConfig *config) { int i = 0; int cnt = 0; int ret = 0; struct dirent **files = { 0 }; unsigned int current_idx = 0; if ((config == NULL) || (file_config == NULL) || (path == NULL) || (config->file_name == NULL)) return -1; cnt = scandir(path, &files, 0, alphasort); if (cnt < 0) { dlt_log(LOG_ERR, "dlt_logstorage_storage_dir_info: Failed to scan directory\n"); return -1; } for (i = 0; i < cnt; i++) { int len = 0; len = strlen(config->file_name); if ((strncmp(files[i]->d_name, config->file_name, len) == 0) && (files[i]->d_name[len] == file_config->logfile_delimiter)) { DltLogStorageFileList **tmp = NULL; current_idx = dlt_logstorage_get_idx_of_log_file(file_config, files[i]->d_name); if (config->records == NULL) { config->records = malloc(sizeof(DltLogStorageFileList)); if (config->records == NULL) { ret = -1; dlt_log(LOG_ERR, "Memory allocation failed\n"); break; } tmp = &config->records; } else { tmp = &config->records; while (*(tmp) != NULL) tmp = &(*tmp)->next; *tmp = malloc(sizeof(DltLogStorageFileList)); if (*tmp == NULL) { ret = -1; dlt_log(LOG_ERR, "Memory allocation failed\n"); break; } } (*tmp)->name = strdup(files[i]->d_name); (*tmp)->idx = current_idx; (*tmp)->next = NULL; } } if (ret == 0) { dlt_logstorage_sort_file_name(&config->records); dlt_logstorage_rearrange_file_name(&config->records); } /* free scandir result */ for (i = 0; i < cnt; i++) free(files[i]); free(files); return ret; } /** * dlt_logstorage_open_log_file * * Open a log file. Check storage directory for already created files and open * the oldest if there is enough space to store at least msg_size. * Otherwise create a new file, but take configured max number of files into * account and remove the oldest file if needed. * * @param config DltLogStorageFilterConfig * @param file_config User configurations for log file * @param dev_path Storage device path * @param msg_size Size of incoming message * @return 0 on succes, -1 on error */ int dlt_logstorage_open_log_file(DltLogStorageFilterConfig *config, DltLogStorageUserConfig *file_config, char *dev_path, int msg_size) { int ret = 0; char absolute_file_path[DLT_MOUNT_PATH_MAX + DLT_OFFLINE_LOGSTORAGE_CONFIG_DIR_PATH_LEN + 1] = { '\0' }; char storage_path[DLT_OFFLINE_LOGSTORAGE_CONFIG_DIR_PATH_LEN + 1] = { '\0' }; unsigned int num_log_files = 0; struct stat s; DltLogStorageFileList **tmp = NULL; DltLogStorageFileList **newest = NULL; char file_name[DLT_MOUNT_PATH_MAX + 1] = { '\0' }; if (config == NULL) return -1; if (strlen(dev_path) > DLT_OFFLINE_LOGSTORAGE_CONFIG_DIR_PATH_LEN) { dlt_vlog(LOG_ERR, "device path '%s' is too long to store\n", dev_path); return -1; } snprintf(storage_path, DLT_OFFLINE_LOGSTORAGE_CONFIG_DIR_PATH_LEN, "%s/", dev_path); /* check if there are already files stored */ if (config->records == NULL) { if (dlt_logstorage_storage_dir_info(file_config, storage_path, config) != 0) return -1; } /* obtain locations of newest, current file names, file count */ tmp = &config->records; while (*(tmp) != NULL) { num_log_files += 1; if ((*tmp)->next == NULL) newest = tmp; tmp = &(*tmp)->next; } /* need new file*/ if (num_log_files == 0) { dlt_logstorage_log_file_name(file_name, file_config, config->file_name, 1); /* concatenate path and file and open absolute path */ strcat(absolute_file_path, storage_path); strcat(absolute_file_path, file_name); config->log = fopen(absolute_file_path, "a+"); /* Add file to file list */ *tmp = malloc(sizeof(DltLogStorageFileList)); if (*tmp == NULL) { dlt_log(LOG_ERR, "Memory allocation for file name failed\n"); return -1; } (*tmp)->name = strdup(file_name); (*tmp)->idx = 1; (*tmp)->next = NULL; } else { /* newest file available*/ strcat(absolute_file_path, storage_path); strcat(absolute_file_path, (*newest)->name); ret = stat(absolute_file_path, &s); /* if size is enough, open it */ if ((ret == 0) && (s.st_size + msg_size < (int)config->file_size)) { config->log = fopen(absolute_file_path, "a+"); } else { /* no space in file or file stats cannot be read */ unsigned int idx = 0; /* get index of newest log file */ idx = dlt_logstorage_get_idx_of_log_file(file_config, (*newest)->name); idx += 1; /* wrap around if max index is reached or an error occurred * while calculating index from file name */ if ((idx > file_config->logfile_maxcounter) || (idx == 0)) idx = 1; dlt_logstorage_log_file_name(file_name, file_config, config->file_name, idx); /* concatenate path and file and open absolute path */ memset(absolute_file_path, 0, sizeof(absolute_file_path) / sizeof(char)); strcat(absolute_file_path, storage_path); strcat(absolute_file_path, file_name); config->log = fopen(absolute_file_path, "a+"); /* Add file to file list */ *tmp = malloc(sizeof(DltLogStorageFileList)); if (*tmp == NULL) { dlt_log(LOG_ERR, "Memory allocation for file name failed\n"); return -1; } (*tmp)->name = strdup(file_name); (*tmp)->idx = idx; (*tmp)->next = NULL; num_log_files += 1; /* check if number of log files exceeds configured max value */ if (num_log_files > config->num_files) { /* delete oldest */ DltLogStorageFileList **head = &config->records; DltLogStorageFileList *n = *head; memset(absolute_file_path, 0, sizeof(absolute_file_path) / sizeof(char)); strcat(absolute_file_path, storage_path); strcat(absolute_file_path, (*head)->name); remove(absolute_file_path); free((*head)->name); *head = n->next; n->next = NULL; free(n); } } } if (config->log == NULL) { dlt_log(LOG_ERR, "dlt_logstorage_create_log_file: Unable to open log file.\n"); return -1; } return ret; } /** * dlt_logstorage_find_dlt_header * * search for dlt header in cache * * @param ptr cache starting position * @param offset offset * @param cnt count * @return index on success, -1 on error */ DLT_STATIC int dlt_logstorage_find_dlt_header(void *ptr, unsigned int offset, unsigned int cnt) { int index = 0; char substring[] = { 'D', 'L', 'T', 0x01 }; while (cnt > 0) { if (*((char *)(ptr + offset + index)) == 'D') { if (strncmp(ptr + offset + index, substring, 4) == 0) return index; } cnt--; index++; } return -1; } /** * dlt_logstorage_find_last_dlt_header * * search for last dlt header in cache * * @param ptr cache starting position * @param offset offset * @param cnt count * @return index on success, -1 on error */ DLT_STATIC int dlt_logstorage_find_last_dlt_header(void *ptr, unsigned int offset, unsigned int cnt) { char substring[] = {'D', 'L', 'T', 0x01}; while(cnt > 0) { if (*((char *)(ptr + offset + cnt)) == 'D') { if (strncmp(ptr + offset + cnt, substring, 4) == 0) { return cnt; } } cnt--; } return -1; } /** * dlt_logstorage_check_write_ret * * check the return value of fwrite * * @param config DltLogStorageFilterConfig * @param ret return value of fwrite call */ DLT_STATIC void dlt_logstorage_check_write_ret(DltLogStorageFilterConfig *config, int ret) { if (config == NULL) dlt_vlog(LOG_ERR, "%s: cannot retrieve config information\n", __func__); if (ret <= 0) { if (ferror(config->log) != 0) dlt_vlog(LOG_ERR, "%s: failed to write cache into log file\n", __func__); } else { /* force sync */ if (fflush(config->log) != 0) dlt_vlog(LOG_ERR, "%s: failed to flush log file\n", __func__); if (fsync(fileno(config->log)) != 0) /* some filesystem doesn't support fsync() */ if (errno != ENOSYS) { dlt_vlog(LOG_ERR, "%s: failed to sync log file\n", __func__); } } } /** * dlt_logstorage_sync_to_file * * Write the log message to log file * * @param config DltLogStorageFilterConfig * @param file_config DltLogStorageUserConfig * @param dev_path Storage device mount point path * @param footer DltLogStorageCacheFooter * @param start_offset Start offset of the cache * @param end_offset End offset of the cache * @return 0 on success, -1 on error */ DLT_STATIC int dlt_logstorage_sync_to_file(DltLogStorageFilterConfig *config, DltLogStorageUserConfig *file_config, char *dev_path, DltLogStorageCacheFooter *footer, unsigned int start_offset, unsigned int end_offset) { int ret = 0; int start_index = 0; int end_index = 0; int count; int remain_file_size; if ((config == NULL) || (file_config == NULL) || (dev_path == NULL) || (footer == NULL)) { dlt_vlog(LOG_ERR, "%s: cannot retrieve config information\n", __func__); return -1; } count = end_offset - start_offset; remain_file_size = config->file_size - config->current_write_file_offset; if (count > remain_file_size) { /* Check if more than one message can fit into the remaining file */ start_index = dlt_logstorage_find_dlt_header(config->cache, start_offset, remain_file_size); end_index = dlt_logstorage_find_last_dlt_header(config->cache, start_offset + start_index, remain_file_size - start_index); count = end_index - start_index; if ((start_index >= 0) && (end_index > start_index) && (count > 0) && (count <= remain_file_size)) { /* Prepare log file */ if (config->log == NULL) { if (dlt_logstorage_prepare_on_msg(config, file_config, dev_path, config->file_size) != 0) { dlt_vlog(LOG_ERR, "%s: failed to prepare log file\n", __func__); return -1; } } ret = fwrite(config->cache + start_offset + start_index, count, 1, config->log); dlt_logstorage_check_write_ret(config, ret); /* Close log file */ fclose(config->log); config->log = NULL; config->current_write_file_offset = 0; footer->last_sync_offset = start_offset + count; start_offset = footer->last_sync_offset; } else { /* Close log file */ fclose(config->log); config->log = NULL; config->current_write_file_offset = 0; } } start_index = dlt_logstorage_find_dlt_header(config->cache, start_offset, count); count = end_offset - start_offset - start_index; if ((start_index >= 0) && (count > 0)) { /* Prepare log file */ if (config->log == NULL) { if (dlt_logstorage_prepare_on_msg(config, file_config, dev_path, config->file_size) != 0) { dlt_vlog(LOG_ERR, "%s: failed to prepare log file\n", __func__); return -1; } } ret = fwrite(config->cache + start_offset + start_index, count, 1, config->log); dlt_logstorage_check_write_ret(config, ret); config->current_write_file_offset += count; footer->last_sync_offset = end_offset; } footer->wrap_around_cnt = 0; return 0; } /** * dlt_logstorage_prepare_on_msg * * Prepare the log file for a certain filer. If log file not open or log * files max size reached, open a new file. * * @param config DltLogStorageFilterConfig * @param file_config User configurations for log file * @param dev_path Storage device path * @param log_msg_size Size of log message * @return 0 on success, -1 on error */ int dlt_logstorage_prepare_on_msg(DltLogStorageFilterConfig *config, DltLogStorageUserConfig *file_config, char *dev_path, int log_msg_size) { int ret = 0; struct stat s; if ((config == NULL) || (file_config == NULL) || (dev_path == NULL)) return -1; if (config->log == NULL) { /* open a new log file */ ret = dlt_logstorage_open_log_file(config, file_config, dev_path, log_msg_size); } else { /* already open, check size and create a new file if needed */ ret = fstat(fileno(config->log), &s); if (ret == 0) { /* check if adding new data do not exceed max file size */ if (s.st_size + log_msg_size > (int)config->file_size) { fclose(config->log); config->log = NULL; ret = dlt_logstorage_open_log_file(config, file_config, dev_path, log_msg_size); } else { /*everything is prepared */ ret = 0; } } else { dlt_log(LOG_ERR, "dlt_logstorage_prepare_log_file: stat() failed.\n"); ret = -1; } } return ret; } /** * dlt_logstorage_write_on_msg * * Write the log message. * * @param config DltLogStorageFilterConfig * @param file_config DltLogStorageUserConfig * @param dev_path Path to device * @param data1 header * @param size1 header size * @param data2 storage header * @param size2 storage header size * @param data3 payload * @param size3 payload size * @return 0 on success, -1 on error */ int dlt_logstorage_write_on_msg(DltLogStorageFilterConfig *config, DltLogStorageUserConfig *file_config, char *dev_path, unsigned char *data1, int size1, unsigned char *data2, int size2, unsigned char *data3, int size3) { int ret; if ((config == NULL) || (data1 == NULL) || (data2 == NULL) || (data3 == NULL) || (file_config == NULL) || (dev_path == NULL)) { return -1; } ret = fwrite(data1, 1, size1, config->log); if (ret != size1) dlt_log(LOG_WARNING, "Wrote less data than specified\n"); ret = fwrite(data2, 1, size2, config->log); if (ret != size2) dlt_log(LOG_WARNING, "Wrote less data than specified\n"); ret = fwrite(data3, 1, size3, config->log); if (ret != size3) dlt_log(LOG_WARNING, "Wrote less data than specified\n"); return ferror(config->log); } /** * dlt_logstorage_sync_on_msg * * sync data to disk. * * @param config DltLogStorageFilterConfig * @param file_config User configurations for log file * @param dev_path Storage device path * @param status Strategy flag * @return 0 on success, -1 on error */ int dlt_logstorage_sync_on_msg(DltLogStorageFilterConfig *config, DltLogStorageUserConfig *file_config, char *dev_path, int status) { int ret; (void)file_config; /* satisfy compiler */ (void)dev_path; if (config == NULL) return -1; if (status == DLT_LOGSTORAGE_SYNC_ON_MSG) { /* sync on every message */ ret = fflush(config->log); if (ret != 0) dlt_log(LOG_ERR, "fflush failed\n"); } return 0; } /** * dlt_logstorage_prepare_msg_cache * * Prepare the log file for a certain filer. If log file not open or log * files max size reached, open a new file. * Create a memory area to cache data. * * @param config DltLogStorageFilterConfig * @param file_config User configurations for log file * @param dev_path Storage device path * @param log_msg_size Size of log message * @return 0 on success, -1 on error */ int dlt_logstorage_prepare_msg_cache(DltLogStorageFilterConfig *config, DltLogStorageUserConfig *file_config, char *dev_path, int log_msg_size) { if ((config == NULL) || (file_config == NULL) || (dev_path == NULL)) return -1; /* Combinations allowed: on Daemon_Exit with on Demand,File_Size with Daemon_Exit * File_Size with on Demand, Specific_Size with Daemon_Exit,Specific_Size with on Demand * Combination not allowed : File_Size with Specific_Size */ /* check for combinations of specific_size and file_size strategy */ if ((DLT_OFFLINE_LOGSTORAGE_IS_STRATEGY_SET(config->sync, DLT_LOGSTORAGE_SYNC_ON_SPECIFIC_SIZE) > 0) && ((DLT_OFFLINE_LOGSTORAGE_IS_STRATEGY_SET(config->sync, DLT_LOGSTORAGE_SYNC_ON_FILE_SIZE)) > 0)) { dlt_log(LOG_WARNING, "wrong combination of sync strategies \n"); return -1; } (void)log_msg_size; /* satisfy compiler */ /* check specific size is smaller than file size */ if ((DLT_OFFLINE_LOGSTORAGE_IS_STRATEGY_SET(config->sync, DLT_LOGSTORAGE_SYNC_ON_SPECIFIC_SIZE) > 0) && (config->specific_size > config->file_size)) { dlt_log(LOG_ERR, "Cache size is larger than file size. " "Cannot prepare log file for ON_SPECIFIC_SIZE sync\n"); return -1; } if (config->cache == NULL) { unsigned int cache_size = 0; /* check for sync_specific_size strategy */ if (DLT_OFFLINE_LOGSTORAGE_IS_STRATEGY_SET(config->sync, DLT_LOGSTORAGE_SYNC_ON_SPECIFIC_SIZE) > 0) { cache_size = config->specific_size; } else /* other cache strategies */ { cache_size = config->file_size; } /* check total logstorage cache size */ if ((g_logstorage_cache_size + cache_size + sizeof(DltLogStorageCacheFooter)) > g_logstorage_cache_max) { dlt_log(LOG_ERR, "Max size of Logstorage Cache already used."); return -1; } /* create cache */ config->cache = calloc(1, cache_size + sizeof(DltLogStorageCacheFooter)); if (config->cache == NULL) { dlt_log(LOG_CRIT, "Cannot allocate memory for filter ring buffer\n"); } else { /* update current used cache size */ g_logstorage_cache_size = cache_size + sizeof(DltLogStorageCacheFooter); } } return 0; } /** * dlt_logstorage_write_msg_cache * * Write the log message. * * @param config DltLogStorageFilterConfig * @param file_config User configurations for log file * @param dev_path Storage device path * @param data1 header * @param size1 header size * @param data2 storage header * @param size2 storage header size * @param data3 payload * @param size3 payload size * @return 0 on success, -1 on error */ int dlt_logstorage_write_msg_cache(DltLogStorageFilterConfig *config, DltLogStorageUserConfig *file_config, char *dev_path, unsigned char *data1, int size1, unsigned char *data2, int size2, unsigned char *data3, int size3) { DltLogStorageCacheFooter *footer = NULL; int msg_size; int remain_cache_size; void *curr_write_addr = NULL; int ret = 0; unsigned int cache_size; if ((config == NULL) || (data1 == NULL) || (size1 < 0) || (data2 == NULL) || (size2 < 0) || (data3 == NULL) || (size3 < 0) || (config->cache == NULL) || (file_config == NULL) || (dev_path == NULL)) { return -1; } if (DLT_OFFLINE_LOGSTORAGE_IS_STRATEGY_SET(config->sync, DLT_LOGSTORAGE_SYNC_ON_SPECIFIC_SIZE) > 0) { cache_size = config->specific_size; } else { cache_size = config->file_size; } footer = (DltLogStorageCacheFooter *)(config->cache + cache_size); if (footer == NULL) { dlt_log(LOG_ERR, "Cannot retrieve cache footer. Address is NULL\n"); return -1; } msg_size = size1 + size2 + size3; remain_cache_size = cache_size - footer->offset; if (msg_size <= remain_cache_size) /* add at current position */ { curr_write_addr = (void *)(config->cache + footer->offset); footer->offset += msg_size; if (footer->wrap_around_cnt < 1) { footer->end_sync_offset = footer->offset; } /* write data to cache */ memcpy(curr_write_addr, data1, size1); curr_write_addr += size1; memcpy(curr_write_addr, data2, size2); curr_write_addr += size2; memcpy(curr_write_addr, data3, size3); } /* * In case the msg_size is equal to remaining cache size, * the message is still written in cache. * Then whole cache data is synchronized to file. */ if (msg_size >= remain_cache_size) { /*check for message size exceeds cache size for specific_size strategy */ if ((unsigned int) msg_size > cache_size) { dlt_log(LOG_WARNING, "Message is larger than cache. Discard.\n"); return -1; } /*sync to file for specific_size or file_size */ if (DLT_OFFLINE_LOGSTORAGE_IS_STRATEGY_SET(config->sync, DLT_LOGSTORAGE_SYNC_ON_FILE_SIZE) > 0) { ret = config->dlt_logstorage_sync(config, file_config, dev_path, DLT_LOGSTORAGE_SYNC_ON_FILE_SIZE); if (ret != 0) { dlt_log(LOG_ERR,"dlt_logstorage_sync: Unable to sync.\n"); return -1; } } else if (DLT_OFFLINE_LOGSTORAGE_IS_STRATEGY_SET(config->sync, DLT_LOGSTORAGE_SYNC_ON_SPECIFIC_SIZE) > 0) { ret = config->dlt_logstorage_sync(config, file_config, dev_path, DLT_LOGSTORAGE_SYNC_ON_SPECIFIC_SIZE); if (ret != 0) { dlt_log(LOG_ERR,"dlt_logstorage_sync: Unable to sync.\n"); return -1; } } else if ((DLT_OFFLINE_LOGSTORAGE_IS_STRATEGY_SET(config->sync, DLT_LOGSTORAGE_SYNC_ON_DEMAND) > 0) || (DLT_OFFLINE_LOGSTORAGE_IS_STRATEGY_SET(config->sync, DLT_LOGSTORAGE_SYNC_ON_DAEMON_EXIT) > 0)) { footer->wrap_around_cnt += 1; } if (msg_size > remain_cache_size) { /* start writing from beginning */ footer->end_sync_offset = footer->offset; curr_write_addr = config->cache; footer->offset = msg_size; /* write data to cache */ memcpy(curr_write_addr, data1, size1); curr_write_addr += size1; memcpy(curr_write_addr, data2, size2); curr_write_addr += size2; memcpy(curr_write_addr, data3, size3); } } return 0; } /** * dlt_logstorage_sync_msg_cache * * sync data to disk. * * @param config DltLogStorageFilterConfig * @param file_config User configurations for log file * @param dev_path Storage device path * @param status Strategy flag * @return 0 on success, -1 on error */ int dlt_logstorage_sync_msg_cache(DltLogStorageFilterConfig *config, DltLogStorageUserConfig *file_config, char *dev_path, int status) { unsigned int cache_size; DltLogStorageCacheFooter *footer = NULL; if ((config == NULL) || (file_config == NULL) || (dev_path == NULL)) { return -1; } /* sync only, if given strategy is set */ if (DLT_OFFLINE_LOGSTORAGE_IS_STRATEGY_SET(config->sync, status) > 0) { if (config->cache == NULL) { dlt_log(LOG_ERR, "Cannot copy cache to file. Cache is NULL\n"); return -1; } if (DLT_OFFLINE_LOGSTORAGE_IS_STRATEGY_SET(config->sync, DLT_LOGSTORAGE_SYNC_ON_SPECIFIC_SIZE) > 0) { cache_size = config->specific_size; } else { cache_size = config->file_size; } footer = (DltLogStorageCacheFooter *)(config->cache + cache_size); if (footer == NULL) { dlt_log(LOG_ERR, "Cannot retrieve cache information\n"); return -1; } /* sync cache data to file */ if (footer->wrap_around_cnt < 1) { /* Sync whole cache */ dlt_logstorage_sync_to_file(config, file_config, dev_path, footer, footer->last_sync_offset, footer->offset); } else if ((footer->wrap_around_cnt == 1) && (footer->offset < footer->last_sync_offset)) { /* sync (1) footer->last_sync_offset to footer->end_sync_offset, * and (2) footer->last_sync_offset (= 0) to footer->offset */ dlt_logstorage_sync_to_file(config, file_config, dev_path, footer, footer->last_sync_offset, footer->end_sync_offset); footer->last_sync_offset = 0; dlt_logstorage_sync_to_file(config, file_config, dev_path, footer, footer->last_sync_offset, footer->offset); } else { /* sync (1) footer->offset + index to footer->end_sync_offset, * and (2) footer->last_sync_offset (= 0) to footer->offset */ dlt_logstorage_sync_to_file(config, file_config, dev_path, footer, footer->offset, footer->end_sync_offset); footer->last_sync_offset = 0; dlt_logstorage_sync_to_file(config, file_config, dev_path, footer, footer->last_sync_offset, footer->offset); } /* Initialize cache if needed */ if ((status == DLT_LOGSTORAGE_SYNC_ON_SPECIFIC_SIZE) || (status == DLT_LOGSTORAGE_SYNC_ON_FILE_SIZE)) { /* clean ring buffer and reset footer information */ memset(config->cache, 0, cache_size + sizeof(DltLogStorageCacheFooter)); } if (status == DLT_LOGSTORAGE_SYNC_ON_FILE_SIZE) { /* Close log file */ fclose(config->log); config->log = NULL; config->current_write_file_offset = 0; } } return 0; } dlt-daemon-2.18.4/src/offlinelogstorage/dlt_offline_logstorage_behavior.h000066400000000000000000000120641353342203500267000ustar00rootroot00000000000000/** * Copyright (C) 2015 Advanced Driver Information Technology. * This code is developed by Advanced Driver Information Technology. * Copyright of Advanced Driver Information Technology, Bosch and DENSO. * * DLT offline log storage functionality header file. * * \copyright * This Source Code Form is subject to the terms of the * Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with * this file, You can obtain one at http://mozilla.org/MPL/2.0/. * * * \author Christoph Lipka ADIT 2015 * * \file: dlt_offline_logstorage_behavior.h * For further information see http://www.genivi.org/. */ /******************************************************************************* ** ** ** SRC-MODULE: dlt_offline_logstorage_behavior.h ** ** ** ** TARGET : linux ** ** ** ** PROJECT : DLT ** ** ** ** AUTHOR : Christoph Lipka clipka@jp.adit-jv.com ** ** ** ** PURPOSE : ** ** ** ** REMARKS : ** ** ** ** PLATFORM DEPENDANT [yes/no]: yes ** ** ** ** TO BE CHANGED BY USER [yes/no]: no ** ** ** *******************************************************************************/ /******************************************************************************* ** Author Identity ** ******************************************************************************** ** ** ** Initials Name Company ** ** -------- ------------------------- ---------------------------------- ** ** cl Christoph Lipka ADIT ** *******************************************************************************/ #ifndef DLT_OFFLINELOGSTORAGE_DLT_OFFLINE_LOGSTORAGE_BEHAVIOR_H_ #define DLT_OFFLINELOGSTORAGE_DLT_OFFLINE_LOGSTORAGE_BEHAVIOR_H_ /* ON_MSG behavior */ int dlt_logstorage_prepare_on_msg(DltLogStorageFilterConfig *config, DltLogStorageUserConfig *file_config, char *dev_path, int log_msg_size); int dlt_logstorage_write_on_msg(DltLogStorageFilterConfig *config, DltLogStorageUserConfig *file_config, char *dev_path, unsigned char *data1, int size1, unsigned char *data2, int size2, unsigned char *data3, int size3); /* status is strategy, e.g. DLT_LOGSTORAGE_SYNC_ON_MSG is used when callback * is called on message received */ int dlt_logstorage_sync_on_msg(DltLogStorageFilterConfig *config, DltLogStorageUserConfig *file_config, char *dev_path, int status); /* Logstorage cache functionality */ int dlt_logstorage_prepare_msg_cache(DltLogStorageFilterConfig *config, DltLogStorageUserConfig *file_config, char *dev_path, int log_msg_size); int dlt_logstorage_write_msg_cache(DltLogStorageFilterConfig *config, DltLogStorageUserConfig *file_config, char *dev_path, unsigned char *data1, int size1, unsigned char *data2, int size2, unsigned char *data3, int size3); int dlt_logstorage_sync_msg_cache(DltLogStorageFilterConfig *config, DltLogStorageUserConfig *file_config, char *dev_path, int status); #endif /* DLT_OFFLINELOGSTORAGE_DLT_OFFLINE_LOGSTORAGE_BEHAVIOR_H_ */ dlt-daemon-2.18.4/src/offlinelogstorage/dlt_offline_logstorage_behavior_internal.h000066400000000000000000000113021353342203500305660ustar00rootroot00000000000000/** * Copyright (C) 2018 Advanced Driver Information Technology. * This code is developed by Advanced Driver Information Technology. * Copyright of Advanced Driver Information Technology, Bosch and DENSO. * * DLT offline log storage functionality internal header file. * * \copyright * This Source Code Form is subject to the terms of the * Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with * this file, You can obtain one at http://mozilla.org/MPL/2.0/. * * * \author Aditya Paluri ADIT 2018 * * \file: dlt_offline_logstorage_behavior_internal.h * For further information see http://www.genivi.org/. */ /******************************************************************************* ** ** ** SRC-MODULE: dlt_offline_logstorage_behavior_internal.h ** ** ** ** TARGET : linux ** ** ** ** PROJECT : DLT ** ** ** ** AUTHOR : Aditya Paluri venkataaditya.paluri@in.bosch.com ** ** ** ** PURPOSE : ** ** ** ** REMARKS : ** ** ** ** PLATFORM DEPENDANT [yes/no]: yes ** ** ** ** TO BE CHANGED BY USER [yes/no]: no ** ** ** *******************************************************************************/ /******************************************************************************* ** Author Identity ** ******************************************************************************** ** ** ** Initials Name Company ** ** -------- ------------------------- ---------------------------------- ** ** ap Aditya Paluri ADIT ** *******************************************************************************/ #ifndef DLT_OFFLINELOGSTORAGE_BEHAVIOR_INTERNAL_H_ #define DLT_OFFLINELOGSTORAGE_BEHAVIOR_INTERNAL_H_ void dlt_logstorage_log_file_name(char *log_file_name, DltLogStorageUserConfig *file_config, char *name, int idx); void dlt_logstorage_sort_file_name(DltLogStorageFileList **head); void dlt_logstorage_rearrange_file_name(DltLogStorageFileList **head); unsigned int dlt_logstorage_get_idx_of_log_file(DltLogStorageUserConfig *file_config, char *file); int dlt_logstorage_storage_dir_info(DltLogStorageUserConfig *file_config, char *path, DltLogStorageFilterConfig *config); int dlt_logstorage_open_log_file(DltLogStorageFilterConfig *config, DltLogStorageUserConfig *file_config, char *dev_path, int msg_size); DLT_STATIC int dlt_logstorage_sync_to_file(DltLogStorageFilterConfig *config, DltLogStorageUserConfig *file_config, char *dev_path, DltLogStorageCacheFooter *footer, unsigned int start_offset, unsigned int end_offset); DLT_STATIC int dlt_logstorage_find_dlt_header(void *ptr, unsigned int offset, unsigned int cnt); DLT_STATIC int dlt_logstorage_find_last_dlt_header(void *ptr, unsigned int offset, unsigned int cnt); #endif /* DLT_OFFLINELOGSTORAGE_BEHAVIOR_INTERNAL_H_ */ dlt-daemon-2.18.4/src/offlinelogstorage/dlt_offline_logstorage_internal.h000066400000000000000000000141201353342203500267100ustar00rootroot00000000000000/** * Copyright (C) 2017 Advanced Driver Information Technology. * This code is developed by Advanced Driver Information Technology. * Copyright of Advanced Driver Information Technology, Bosch and DENSO. * * DLT offline log storage functionality internal header file. * * \copyright * This Source Code Form is subject to the terms of the * Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with * this file, You can obtain one at http://mozilla.org/MPL/2.0/. * * * \author Aditya Paluri ADIT 2017 * * \file: dlt_offline_logstorage_internal.h * For further information see http://www.genivi.org/. */ /******************************************************************************* ** ** ** SRC-MODULE: dlt_offline_logstorage_internal.h ** ** ** ** TARGET : linux ** ** ** ** PROJECT : DLT ** ** ** ** AUTHOR : Aditya Paluri venkataaditya.paluri@in.bosch.com ** ** PURPOSE : ** ** ** ** REMARKS : ** ** ** ** PLATFORM DEPENDANT [yes/no]: yes ** ** ** ** TO BE CHANGED BY USER [yes/no]: no ** ** ** *******************************************************************************/ /******************************************************************************* ** Author Identity ** ******************************************************************************** ** ** ** Initials Name Company ** ** -------- ------------------------- ---------------------------------- ** ** ap Aditya Paluri ADIT ** *******************************************************************************/ #ifndef DLT_OFFLINE_LOGSTORAGE_INTERNAL_H #define DLT_OFFLINE_LOGSTORAGE_INTERNAL_H DLT_STATIC int dlt_logstorage_list_destroy(DltLogStorageFilterList **list, DltLogStorageUserConfig *uconfig, char *dev_path, int reason); DLT_STATIC int dlt_logstorage_list_add_config(DltLogStorageFilterConfig *data, DltLogStorageFilterConfig **listdata); DLT_STATIC int dlt_logstorage_list_add(char *key, int num_keys, DltLogStorageFilterConfig *data, DltLogStorageFilterList **list); DLT_STATIC int dlt_logstorage_list_find(char *key, DltLogStorageFilterList **list, DltLogStorageFilterConfig **config); DLT_STATIC int dlt_logstorage_count_ids(const char *str); DLT_STATIC int dlt_logstorage_read_number(unsigned int *number, char *value); DLT_STATIC int dlt_logstorage_read_list_of_names(char **names, char *value); DLT_STATIC int dlt_logstorage_check_apids(DltLogStorageFilterConfig *config, char *value); DLT_STATIC int dlt_logstorage_check_ctids(DltLogStorageFilterConfig *config, char *value); DLT_STATIC int dlt_logstorage_check_loglevel(DltLogStorageFilterConfig *config, char *value); DLT_STATIC int dlt_logstorage_check_filename(DltLogStorageFilterConfig *config, char *value); DLT_STATIC int dlt_logstorage_check_filesize(DltLogStorageFilterConfig *config, char *value); DLT_STATIC int dlt_logstorage_check_nofiles(DltLogStorageFilterConfig *config, char *value); DLT_STATIC int dlt_logstorage_check_sync_strategy(DltLogStorageFilterConfig *config, char *value); DLT_STATIC int dlt_logstorage_check_ecuid(DltLogStorageFilterConfig *config, char *value); DLT_STATIC int dlt_logstorage_check_param(DltLogStorageFilterConfig *config, DltLogstorageFilterConfType ctype, char *value); DLT_STATIC int dlt_logstorage_store_filters(DltLogStorage *handle, char *config_file_name); void dlt_logstorage_free(DltLogStorage *handle, int reason); DLT_STATIC int dlt_logstorage_create_keys(char *apids, char *ctids, char *ecuid, char **keys, int *num_keys); DLT_STATIC int dlt_logstorage_prepare_table(DltLogStorage *handle, DltLogStorageFilterConfig *data); DLT_STATIC int dlt_logstorage_validate_filter_name(char *name); DLT_STATIC void dlt_logstorage_filter_set_strategy(DltLogStorageFilterConfig *config, int strategy); DLT_STATIC int dlt_logstorage_load_config(DltLogStorage *handle); DLT_STATIC int dlt_logstorage_filter(DltLogStorage *handle, DltLogStorageFilterConfig **config, char *apid, char *ctid, char *ecuid, int log_level); #endif /* DLT_OFFLINE_LOGSTORAGE_INTERNAL_H */ dlt-daemon-2.18.4/src/shared/000077500000000000000000000000001353342203500156675ustar00rootroot00000000000000dlt-daemon-2.18.4/src/shared/dlt_common.c000066400000000000000000003455531353342203500202050ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2011-2015, BMW AG * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author * Alexander Wenzel * Markus Klein * Mikko Rapeli * * \copyright Copyright © 2011-2015 BMW AG. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file dlt_common.c */ #include #include /* for malloc(), free() */ #include /* for strlen(), memcmp(), memmove() */ #include /* for localtime_r(), strftime() */ #include /* for NAME_MAX */ #include /* for PRI formatting macro */ #include #include #include /* for mkdir() */ #include "dlt_user_shared.h" #include "dlt_common.h" #include "dlt_common_cfg.h" #include "dlt_version.h" #if defined (__WIN32__) || defined (_MSC_VER) # include /* for socket(), connect(), send(), and recv() */ #else # include /* for socket(), connect(), send(), and recv() */ # include # include /* for clock_gettime() */ #endif #if defined (_MSC_VER) # include #else # include /* for read(), close() */ # include /* for gettimeofday() */ #endif #if defined (__MSDOS__) || defined (_MSC_VER) # pragma warning(disable : 4996) /* Switch off C4996 warnings */ # include # include #endif const char dltSerialHeader[DLT_ID_SIZE] = { 'D', 'L', 'S', 1 }; char dltSerialHeaderChar[DLT_ID_SIZE] = { 'D', 'L', 'S', 1 }; char dltFifoBaseDir[DLT_PATH_MAX] = "/tmp"; #ifdef DLT_SHM_ENABLE char dltShmName[NAME_MAX + 1] = "/dlt-shm"; #endif /* internal logging parameters */ static int logging_mode = DLT_LOG_TO_CONSOLE; static int logging_level = LOG_INFO; static char logging_filename[NAME_MAX + 1] = ""; static FILE *logging_handle = NULL; char *message_type[] = { "log", "app_trace", "nw_trace", "control", "", "", "", "" }; char *log_info[] = { "", "fatal", "error", "warn", "info", "debug", "verbose", "", "", "", "", "", "", "", "", "" }; char *trace_type[] = { "", "variable", "func_in", "func_out", "state", "vfb", "", "", "", "", "", "", "", "", "", "" }; char *nw_trace_type[] = { "", "ipc", "can", "flexray", "most", "vfb", "", "", "", "", "", "", "", "", "", "" }; char *control_type[] = { "", "request", "response", "time", "", "", "", "", "", "", "", "", "", "", "", "" }; static char *service_id_name[] = { "", "set_log_level", "set_trace_status", "get_log_info", "get_default_log_level", "store_config", "reset_to_factory_default", "set_com_interface_status", "set_com_interface_max_bandwidth", "set_verbose_mode", "set_message_filtering", "set_timing_packets", "get_local_time", "use_ecu_id", "use_session_id", "use_timestamp", "use_extended_header", "set_default_log_level", "set_default_trace_status", "get_software_version", "message_buffer_overflow" }; static char *return_type[] = { "ok", "not_supported", "error", "perm_denied", "warning", "", "", "", "no_matching_context_id" }; /* internal function definitions */ int dlt_buffer_get(DltBuffer *buf, unsigned char *data, int max_size, int delete); int dlt_buffer_reset(DltBuffer *buf); int dlt_buffer_increase_size(DltBuffer *buf); int dlt_buffer_minimize_size(DltBuffer *buf); void dlt_buffer_write_block(DltBuffer *buf, int *write, const unsigned char *data, unsigned int size); void dlt_buffer_read_block(DltBuffer *buf, int *read, unsigned char *data, unsigned int size); void dlt_print_hex(uint8_t *ptr, int size) { int num; if (ptr == NULL) return; for (num = 0; num < size; num++) { if (num > 0) printf(" "); printf("%.2x", ((uint8_t *)ptr)[num]); } } DltReturnValue dlt_print_hex_string(char *text, int textlength, uint8_t *ptr, int size) { int num; if ((ptr == NULL) || (text == NULL) || (textlength <= 0) || (size < 0)) return DLT_RETURN_WRONG_PARAMETER; /* Length 3: AB_ , A is first digit of hex number, B is second digit of hex number, _ is space */ if (textlength < (size * 3)) { dlt_vlog(LOG_WARNING, "String does not fit hex data (available=%d, required=%d) !\n", textlength, size * 3); return DLT_RETURN_ERROR; } for (num = 0; num < size; num++) { if (num > 0) { snprintf(text, 2, " "); text++; } snprintf(text, 3, "%.2x", ((uint8_t *)ptr)[num]); text += 2; /* 2 chars */ } return DLT_RETURN_OK; } DltReturnValue dlt_print_mixed_string(char *text, int textlength, uint8_t *ptr, int size, int html) { int required_size = 0; int lines, rest, i; if ((ptr == NULL) || (text == NULL) || (textlength <= 0) || (size < 0)) return DLT_RETURN_WRONG_PARAMETER; /* Check maximum required size and do a length check */ if (html == 0) required_size = (DLT_COMMON_HEX_LINELEN + (2 * DLT_COMMON_HEX_CHARS + (DLT_COMMON_HEX_CHARS - 1)) + DLT_COMMON_CHARLEN + DLT_COMMON_HEX_CHARS + DLT_COMMON_CHARLEN) * ((size / DLT_COMMON_HEX_CHARS) + 1); /* Example: (8 chars line number + (2*16 chars + 15 spaces) + space + 16 ascii chars + CR) * * ((size/16) lines + extra line for the rest) */ else required_size = (DLT_COMMON_HEX_LINELEN + (2 * DLT_COMMON_HEX_CHARS + (DLT_COMMON_HEX_CHARS - 1)) + DLT_COMMON_CHARLEN + DLT_COMMON_HEX_CHARS + 4 * DLT_COMMON_CHARLEN) * ((size / DLT_COMMON_HEX_CHARS) + 1); /* Example: (8 chars line number + (2*16 chars + 15 spaces) + space + 16 ascii chars + 4 [HTML CR:
]) * * ((size/16) lines + extra line for the rest) */ if (textlength < required_size) { dlt_vlog(LOG_WARNING, "String does not fit mixed data (available=%d, required=%d) !\n", textlength, required_size); return DLT_RETURN_ERROR; } /* print full lines */ for (lines = 0; lines < (size / DLT_COMMON_HEX_CHARS); lines++) { int ret = 0; /* Line number */ ret = snprintf(text, DLT_COMMON_HEX_LINELEN + 1, "%.6x: ", lines * DLT_COMMON_HEX_CHARS); if ((ret < 0) || (ret >= (DLT_COMMON_HEX_LINELEN + 1))) dlt_log(LOG_WARNING, "line was truncated\n"); text += DLT_COMMON_HEX_LINELEN; /* 'XXXXXX: ' */ /* Hex-Output */ /* It is not required to decrement textlength, as it was already checked, that * there is enough space for the complete output */ dlt_print_hex_string(text, textlength, (uint8_t *)(ptr + (lines * DLT_COMMON_HEX_CHARS)), DLT_COMMON_HEX_CHARS); text += ((2 * DLT_COMMON_HEX_CHARS) + (DLT_COMMON_HEX_CHARS - 1)); /* 32 characters + 15 spaces */ snprintf(text, 2, " "); text += DLT_COMMON_CHARLEN; /* Char-Output */ /* It is not required to decrement textlength, as it was already checked, that * there is enough space for the complete output */ dlt_print_char_string(&text, textlength, (uint8_t *)(ptr + (lines * DLT_COMMON_HEX_CHARS)), DLT_COMMON_HEX_CHARS); if (html == 0) { snprintf(text, 2, "\n"); text += DLT_COMMON_CHARLEN; } else { snprintf(text, 5, "
"); text += (4 * DLT_COMMON_CHARLEN); } } /* print partial line */ rest = size % DLT_COMMON_HEX_CHARS; if (rest > 0) { /* Line number */ int ret = 0; ret = snprintf(text, 9, "%.6x: ", (size / DLT_COMMON_HEX_CHARS) * DLT_COMMON_HEX_CHARS); if ((ret < 0) || (ret >= 9)) dlt_log(LOG_WARNING, "line number was truncated"); text += DLT_COMMON_HEX_LINELEN; /* 'XXXXXX: ' */ /* Hex-Output */ /* It is not required to decrement textlength, as it was already checked, that * there is enough space for the complete output */ dlt_print_hex_string(text, textlength, (uint8_t *)(ptr + ((size / DLT_COMMON_HEX_CHARS) * DLT_COMMON_HEX_CHARS)), rest); text += 2 * rest + (rest - 1); for (i = 0; i < (DLT_COMMON_HEX_CHARS - rest); i++) { snprintf(text, 4, " xx"); text += (3 * DLT_COMMON_CHARLEN); } snprintf(text, 2, " "); text += DLT_COMMON_CHARLEN; /* Char-Output */ /* It is not required to decrement textlength, as it was already checked, that * there is enough space for the complete output */ dlt_print_char_string(&text, textlength, (uint8_t *)(ptr + ((size / DLT_COMMON_HEX_CHARS) * DLT_COMMON_HEX_CHARS)), rest); } return DLT_RETURN_OK; } DltReturnValue dlt_print_char_string(char **text, int textlength, uint8_t *ptr, int size) { int num; if ((text == NULL) || (ptr == NULL) || (*text == NULL) || (textlength <= 0) || (size < 0)) return DLT_RETURN_WRONG_PARAMETER; if (textlength < size) { dlt_vlog(LOG_WARNING, "String does not fit character data (available=%d, required=%d) !\n", textlength, size); return DLT_RETURN_WRONG_PARAMETER; } for (num = 0; num < size; num++) { if ((((char *)ptr)[num] < DLT_COMMON_ASCII_CHAR_SPACE) || (((char *)ptr)[num] > DLT_COMMON_ASCII_CHAR_TILDE)) { snprintf(*text, 2, "."); } else { /* replace < with . */ if (((char *)ptr)[num] != DLT_COMMON_ASCII_CHAR_LT) snprintf(*text, 2, "%c", ((char *)ptr)[num]); else snprintf(*text, 2, "."); } (*text)++; } return DLT_RETURN_OK; } void dlt_print_id(char *text, const char *id) { /* check nullpointer */ if ((text == NULL) || (id == NULL)) return; int i, len; /* Initialize text */ for (i = 0; i < DLT_ID_SIZE; i++) text[i] = '-'; text[DLT_ID_SIZE] = 0; len = ((strlen(id) <= DLT_ID_SIZE) ? strlen(id) : DLT_ID_SIZE); /* Check id*/ for (i = 0; i < len; i++) text[i] = id[i]; } void dlt_set_id(char *id, const char *text) { /* check nullpointer */ if ((id == NULL) || (text == NULL)) return; id[0] = 0; id[1] = 0; id[2] = 0; id[3] = 0; if (text[0] != 0) id[0] = text[0]; else return; if (text[1] != 0) id[1] = text[1]; else return; if (text[2] != 0) id[2] = text[2]; else return; if (text[3] != 0) id[3] = text[3]; else return; } void dlt_clean_string(char *text, int length) { int num; if (text == NULL) return; for (num = 0; num < length; num++) if ((text[num] == '\r') || (text[num] == '\n')) text[num] = ' '; } DltReturnValue dlt_filter_init(DltFilter *filter, int verbose) { PRINT_FUNCTION_VERBOSE(verbose); if (filter == NULL) return DLT_RETURN_WRONG_PARAMETER; filter->counter = 0; return DLT_RETURN_OK; } DltReturnValue dlt_filter_free(DltFilter *filter, int verbose) { PRINT_FUNCTION_VERBOSE(verbose); if (filter == NULL) return DLT_RETURN_WRONG_PARAMETER; return DLT_RETURN_OK; } DltReturnValue dlt_filter_load(DltFilter *filter, const char *filename, int verbose) { if ((filter == NULL) || (filename == NULL)) return DLT_RETURN_WRONG_PARAMETER; FILE *handle; char str1[DLT_COMMON_BUFFER_LENGTH]; char apid[DLT_ID_SIZE], ctid[DLT_ID_SIZE]; PRINT_FUNCTION_VERBOSE(verbose); handle = fopen(filename, "r"); if (handle == NULL) { dlt_vlog(LOG_WARNING, "Filter file %s cannot be opened!\n", filename); return DLT_RETURN_ERROR; } /* Reset filters */ filter->counter = 0; while (!feof(handle)) { str1[0] = 0; if (fscanf(handle, "%s", str1) != 1) break; if (str1[0] == 0) break; printf(" %s", str1); if (strcmp(str1, "----") == 0) dlt_set_id(apid, ""); else dlt_set_id(apid, str1); str1[0] = 0; if (fscanf(handle, "%s", str1) != 1) break; if (str1[0] == 0) break; printf(" %s\r\n", str1); if (strcmp(str1, "----") == 0) dlt_set_id(ctid, ""); else dlt_set_id(ctid, str1); if (filter->counter < DLT_FILTER_MAX) { dlt_filter_add(filter, apid, ctid, verbose); } else { dlt_vlog(LOG_WARNING, "Maximum number (%d) of allowed filters reached, ignoring rest of filters!\n", DLT_FILTER_MAX); } } fclose(handle); return DLT_RETURN_OK; } DltReturnValue dlt_filter_save(DltFilter *filter, const char *filename, int verbose) { if ((filter == NULL) || (filename == NULL)) return DLT_RETURN_WRONG_PARAMETER; FILE *handle; int num; char buf[DLT_COMMON_BUFFER_LENGTH]; PRINT_FUNCTION_VERBOSE(verbose); handle = fopen(filename, "w"); if (handle == NULL) { dlt_vlog(LOG_WARNING, "Filter file %s cannot be opened!\n", filename); return DLT_RETURN_ERROR; } for (num = 0; num < filter->counter; num++) { if (filter->apid[num][0] == 0) { fprintf(handle, "---- "); } else { dlt_print_id(buf, filter->apid[num]); fprintf(handle, "%s ", buf); } if (filter->ctid[num][0] == 0) { fprintf(handle, "---- "); } else { dlt_print_id(buf, filter->ctid[num]); fprintf(handle, "%s ", buf); } } fclose(handle); return DLT_RETURN_OK; } int dlt_filter_find(DltFilter *filter, const char *apid, const char *ctid, int verbose) { int num; PRINT_FUNCTION_VERBOSE(verbose); if ((filter == NULL) || (apid == NULL)) return -1; for (num = 0; num < filter->counter; num++) if (memcmp(filter->apid[num], apid, DLT_ID_SIZE) == 0) { /* apid matches, now check for ctid */ if (ctid == NULL) { /* check if empty ctid matches */ /*if (memcmp(filter->ctid[num],"",DLT_ID_SIZE)==0)//coverity complains here about Out-of-bounds access. */ char empty_ctid[DLT_ID_SIZE] = ""; if (memcmp(filter->ctid[num], empty_ctid, DLT_ID_SIZE) == 0) return num; } else if (memcmp(filter->ctid[num], ctid, DLT_ID_SIZE) == 0) return num; } return -1; /* Not found */ } DltReturnValue dlt_filter_add(DltFilter *filter, const char *apid, const char *ctid, int verbose) { PRINT_FUNCTION_VERBOSE(verbose); if ((filter == NULL) || (apid == NULL)) return DLT_RETURN_WRONG_PARAMETER; if (filter->counter >= DLT_FILTER_MAX) { dlt_vlog(LOG_WARNING, "Maximum number (%d) of allowed filters reached, ignoring filter!\n", DLT_FILTER_MAX); return DLT_RETURN_ERROR; } /* add each filter (apid, ctid) only once to filter array */ if (dlt_filter_find(filter, apid, ctid, verbose) < 0) { /* filter not found, so add it to filter array */ if (filter->counter < DLT_FILTER_MAX) { dlt_set_id(filter->apid[filter->counter], apid); dlt_set_id(filter->ctid[filter->counter], (ctid ? ctid : "")); filter->counter++; return DLT_RETURN_OK; } } return DLT_RETURN_ERROR; } DltReturnValue dlt_filter_delete(DltFilter *filter, const char *apid, const char *ctid, int verbose) { int j, k; int found = 0; PRINT_FUNCTION_VERBOSE(verbose); if ((filter == NULL) || (apid == NULL) || (ctid == NULL)) return DLT_RETURN_WRONG_PARAMETER; if (filter->counter > 0) { /* Get first occurence of apid and ctid in filter array */ for (j = 0; j < filter->counter; j++) if ((memcmp(filter->apid[j], apid, DLT_ID_SIZE) == 0) && (memcmp(filter->ctid[j], ctid, DLT_ID_SIZE) == 0) ) { found = 1; break; } if (found) { /* j is index */ /* Copy from j+1 til end to j til end-1 */ dlt_set_id(filter->apid[j], ""); dlt_set_id(filter->ctid[j], ""); for (k = j; k < (filter->counter - 1); k++) { dlt_set_id(filter->apid[k], filter->apid[k + 1]); dlt_set_id(filter->ctid[k], filter->ctid[k + 1]); } filter->counter--; return DLT_RETURN_OK; } } return DLT_RETURN_ERROR; } DltReturnValue dlt_message_init(DltMessage *msg, int verbose) { PRINT_FUNCTION_VERBOSE(verbose); if (msg == NULL) return DLT_RETURN_WRONG_PARAMETER; /* initalise structure parameters */ msg->headersize = 0; msg->datasize = 0; msg->databuffer = NULL; msg->databuffersize = 0; msg->storageheader = NULL; msg->standardheader = NULL; msg->extendedheader = NULL; msg->found_serialheader = 0; return DLT_RETURN_OK; } DltReturnValue dlt_message_free(DltMessage *msg, int verbose) { PRINT_FUNCTION_VERBOSE(verbose); if (msg == NULL) return DLT_RETURN_WRONG_PARAMETER; /* delete databuffer if exists */ if (msg->databuffer) { free(msg->databuffer); msg->databuffer = NULL; msg->databuffersize = 0; } return DLT_RETURN_OK; } DltReturnValue dlt_message_header(DltMessage *msg, char *text, int textlength, int verbose) { return dlt_message_header_flags(msg, text, textlength, DLT_HEADER_SHOW_ALL, verbose); } DltReturnValue dlt_message_header_flags(DltMessage *msg, char *text, int textlength, int flags, int verbose) { struct tm timeinfo; char buffer [DLT_COMMON_BUFFER_LENGTH]; PRINT_FUNCTION_VERBOSE(verbose); if ((msg == NULL) || (text == NULL) || (textlength <= 0)) return DLT_RETURN_WRONG_PARAMETER; if ((flags < DLT_HEADER_SHOW_NONE) || (flags > DLT_HEADER_SHOW_ALL)) return DLT_RETURN_WRONG_PARAMETER; text[0] = 0; if ((flags & DLT_HEADER_SHOW_TIME) == DLT_HEADER_SHOW_TIME) { /* print received time */ time_t tt = msg->storageheader->seconds; localtime_r(&tt, &timeinfo); strftime (buffer, sizeof(buffer), "%Y/%m/%d %H:%M:%S", &timeinfo); snprintf(text, textlength, "%s.%.6d ", buffer, msg->storageheader->microseconds); } if ((flags & DLT_HEADER_SHOW_TMSTP) == DLT_HEADER_SHOW_TMSTP) { /* print timestamp if available */ if (DLT_IS_HTYP_WTMS(msg->standardheader->htyp)) snprintf(text + strlen(text), textlength - strlen(text), "%10u ", msg->headerextra.tmsp); else snprintf(text + strlen(text), textlength - strlen(text), "---------- "); } if ((flags & DLT_HEADER_SHOW_MSGCNT) == DLT_HEADER_SHOW_MSGCNT) /* print message counter */ snprintf(text + strlen(text), textlength - strlen(text), "%.3d ", msg->standardheader->mcnt); if ((flags & DLT_HEADER_SHOW_ECUID) == DLT_HEADER_SHOW_ECUID) { /* print ecu id, use header extra if available, else storage header value */ if (DLT_IS_HTYP_WEID(msg->standardheader->htyp)) dlt_print_id(text + strlen(text), msg->headerextra.ecu); else dlt_print_id(text + strlen(text), msg->storageheader->ecu); } /* print app id and context id if extended header available, else '----' */ # if ((flags & DLT_HEADER_SHOW_APID) == DLT_HEADER_SHOW_APID) { snprintf(text + strlen(text), textlength - strlen(text), " "); if ((DLT_IS_HTYP_UEH(msg->standardheader->htyp)) && (msg->extendedheader->apid[0] != 0)) dlt_print_id(text + strlen(text), msg->extendedheader->apid); else snprintf(text + strlen(text), textlength - strlen(text), "----"); snprintf(text + strlen(text), textlength - strlen(text), " "); } if ((flags & DLT_HEADER_SHOW_CTID) == DLT_HEADER_SHOW_CTID) { if ((DLT_IS_HTYP_UEH(msg->standardheader->htyp)) && (msg->extendedheader->ctid[0] != 0)) dlt_print_id(text + strlen(text), msg->extendedheader->ctid); else snprintf(text + strlen(text), textlength - strlen(text), "----"); snprintf(text + strlen(text), textlength - strlen(text), " "); } /* print info about message type and length */ if (DLT_IS_HTYP_UEH(msg->standardheader->htyp)) { if ((flags & DLT_HEADER_SHOW_MSGTYPE) == DLT_HEADER_SHOW_MSGTYPE) { snprintf(text + strlen(text), textlength - strlen(text), "%s", message_type[DLT_GET_MSIN_MSTP(msg->extendedheader->msin)]); snprintf(text + strlen(text), textlength - strlen(text), " "); } if ((flags & DLT_HEADER_SHOW_MSGSUBTYPE) == DLT_HEADER_SHOW_MSGSUBTYPE) { if ((DLT_GET_MSIN_MSTP(msg->extendedheader->msin)) == DLT_TYPE_LOG) snprintf(text + strlen(text), textlength - strlen(text), "%s", log_info[DLT_GET_MSIN_MTIN(msg->extendedheader->msin)]); if ((DLT_GET_MSIN_MSTP(msg->extendedheader->msin)) == DLT_TYPE_APP_TRACE) snprintf(text + strlen(text), textlength - strlen(text), "%s", trace_type[DLT_GET_MSIN_MTIN(msg->extendedheader->msin)]); if ((DLT_GET_MSIN_MSTP(msg->extendedheader->msin)) == DLT_TYPE_NW_TRACE) snprintf(text + strlen(text), textlength - strlen(text), "%s", nw_trace_type[DLT_GET_MSIN_MTIN(msg->extendedheader->msin)]); if ((DLT_GET_MSIN_MSTP(msg->extendedheader->msin)) == DLT_TYPE_CONTROL) snprintf(text + strlen(text), textlength - strlen(text), "%s", control_type[DLT_GET_MSIN_MTIN(msg->extendedheader->msin)]); snprintf(text + strlen(text), textlength - strlen(text), " "); } if ((flags & DLT_HEADER_SHOW_VNVSTATUS) == DLT_HEADER_SHOW_VNVSTATUS) { /* print verbose status pf message */ if (DLT_IS_MSIN_VERB(msg->extendedheader->msin)) snprintf(text + strlen(text), textlength - strlen(text), "V"); else snprintf(text + strlen(text), textlength - strlen(text), "N"); snprintf(text + strlen(text), textlength - strlen(text), " "); } if ((flags & DLT_HEADER_SHOW_NOARG) == DLT_HEADER_SHOW_NOARG) /* print number of arguments */ snprintf(text + strlen(text), textlength - strlen(text), "%d", msg->extendedheader->noar); } else { if ((flags & DLT_HEADER_SHOW_MSGTYPE) == DLT_HEADER_SHOW_MSGTYPE) snprintf(text + strlen(text), textlength - strlen(text), "--- "); if ((flags & DLT_HEADER_SHOW_MSGSUBTYPE) == DLT_HEADER_SHOW_MSGSUBTYPE) snprintf(text + strlen(text), textlength - strlen(text), "--- "); if ((flags & DLT_HEADER_SHOW_VNVSTATUS) == DLT_HEADER_SHOW_VNVSTATUS) snprintf(text + strlen(text), textlength - strlen(text), "N "); if ((flags & DLT_HEADER_SHOW_NOARG) == DLT_HEADER_SHOW_NOARG) snprintf(text + strlen(text), textlength - strlen(text), "-"); } return DLT_RETURN_OK; } DltReturnValue dlt_message_payload(DltMessage *msg, char *text, int textlength, int type, int verbose) { uint32_t id = 0, id_tmp = 0; uint8_t retval = 0; uint8_t *ptr; int32_t datalength; /* Pointer to ptr and datalength */ uint8_t **pptr; int32_t *pdatalength; int ret = 0; int num; uint32_t type_info = 0, type_info_tmp = 0; PRINT_FUNCTION_VERBOSE(verbose); if ((msg == NULL) || (text == NULL)) return DLT_RETURN_WRONG_PARAMETER; if (textlength <= 0) { dlt_log(LOG_WARNING, "String does not fit binary data!\n"); return DLT_RETURN_WRONG_PARAMETER; } /* start with empty string */ text[0] = 0; /* print payload only as hex */ if (type == DLT_OUTPUT_HEX) return dlt_print_hex_string(text, textlength, msg->databuffer, msg->datasize); /* print payload as mixed */ if (type == DLT_OUTPUT_MIXED_FOR_PLAIN) return dlt_print_mixed_string(text, textlength, msg->databuffer, msg->datasize, 0); if (type == DLT_OUTPUT_MIXED_FOR_HTML) return dlt_print_mixed_string(text, textlength, msg->databuffer, msg->datasize, 1); ptr = msg->databuffer; datalength = msg->datasize; /* Pointer to ptr and datalength */ pptr = &ptr; pdatalength = &datalength; /* non-verbose mode */ /* print payload as hex */ if (DLT_MSG_IS_NONVERBOSE(msg)) { DLT_MSG_READ_VALUE(id_tmp, ptr, datalength, uint32_t); id = DLT_ENDIAN_GET_32(msg->standardheader->htyp, id_tmp); if (textlength < ((datalength * 3) + 20)) { dlt_vlog(LOG_WARNING, "String does not fit binary data (available=%d, required=%d) !\n", textlength, (datalength * 3) + 20); return DLT_RETURN_ERROR; } /* process message id / service id */ if (DLT_MSG_IS_CONTROL(msg)) { if ((id > 0) && (id < DLT_SERVICE_ID_LAST_ENTRY)) { snprintf(text + strlen(text), textlength - strlen(text), "%s", service_id_name[id]); /* service id */ } else if (!(DLT_MSG_IS_CONTROL_TIME(msg))) snprintf(text + strlen(text), textlength - strlen(text), "service(%u)", id); /* service id */ if (datalength > 0) snprintf(text + strlen(text), textlength - strlen(text), ", "); } else { snprintf(text + strlen(text), textlength - strlen(text), "%u, ", id); /* message id */ } /* process return value */ if (DLT_MSG_IS_CONTROL_RESPONSE(msg)) { if (datalength > 0) { DLT_MSG_READ_VALUE(retval, ptr, datalength, uint8_t); /* No endian conversion necessary */ if ((retval < 3) || (retval == 8)) snprintf(text + strlen(text), textlength - strlen(text), "%s", return_type[retval]); else snprintf(text + strlen(text), textlength - strlen(text), "%.2x", retval); if (datalength >= 1) snprintf(text + strlen(text), textlength - strlen(text), ", "); } } if (type == DLT_OUTPUT_ASCII_LIMITED) { ret = dlt_print_hex_string(text + strlen(text), textlength - strlen( text), ptr, (datalength > DLT_COMMON_ASCII_LIMIT_MAX_CHARS ? DLT_COMMON_ASCII_LIMIT_MAX_CHARS : datalength)); if ((datalength > DLT_COMMON_ASCII_LIMIT_MAX_CHARS) && ((textlength - strlen(text)) > 4)) snprintf(text + strlen(text), textlength - strlen(text), " ..."); } else { ret = dlt_print_hex_string(text + strlen(text), textlength - strlen(text), ptr, datalength); } return ret; } /* At this point, it is ensured that a extended header is available */ /* verbose mode */ type_info = 0; type_info_tmp = 0; for (num = 0; num < (int)(msg->extendedheader->noar); num++) { if (num != 0) snprintf(text + strlen(text), textlength - strlen(text), " "); /* first read the type info of the argument */ DLT_MSG_READ_VALUE(type_info_tmp, ptr, datalength, uint32_t); type_info = DLT_ENDIAN_GET_32(msg->standardheader->htyp, type_info_tmp); /* print out argument */ if (dlt_message_argument_print(msg, type_info, pptr, pdatalength, text, textlength, -1, 0) == DLT_RETURN_ERROR) return DLT_RETURN_ERROR; } return DLT_RETURN_OK; } DltReturnValue dlt_message_filter_check(DltMessage *msg, DltFilter *filter, int verbose) { /* check the filters if message is used */ int num; DltReturnValue found = DLT_RETURN_OK; PRINT_FUNCTION_VERBOSE(verbose); if ((msg == NULL) || (filter == NULL)) return DLT_RETURN_WRONG_PARAMETER; if ((filter->counter == 0) || (!(DLT_IS_HTYP_UEH(msg->standardheader->htyp)))) /* no filter is set, or no extended header is available, so do as filter is matching */ return DLT_RETURN_TRUE; for (num = 0; num < filter->counter; num++) /* check each filter if it matches */ if ((DLT_IS_HTYP_UEH(msg->standardheader->htyp)) && ((filter->apid[num][0] == 0) || (memcmp(filter->apid[num], msg->extendedheader->apid, DLT_ID_SIZE) == 0)) && ((filter->ctid[num][0] == 0) || (memcmp(filter->ctid[num], msg->extendedheader->ctid, DLT_ID_SIZE) == 0))) { found = DLT_RETURN_TRUE; break; } return found; } int dlt_message_read(DltMessage *msg, uint8_t *buffer, unsigned int length, int resync, int verbose) { int extra_size = 0; PRINT_FUNCTION_VERBOSE(verbose); if ((msg == NULL) || (buffer == NULL) || (length <= 0)) return DLT_MESSAGE_ERROR_UNKNOWN; /* initialize resync_offset */ msg->resync_offset = 0; /* check if message contains serial header, smaller than standard header */ if (length < sizeof(dltSerialHeader)) /* dlt_log(LOG_ERR, "Length smaller than serial header!\n"); */ return DLT_MESSAGE_ERROR_SIZE; if (memcmp(buffer, dltSerialHeader, sizeof(dltSerialHeader)) == 0) { /* serial header found */ msg->found_serialheader = 1; buffer += sizeof(dltSerialHeader); length -= sizeof(dltSerialHeader); } else { /* serial header not found */ msg->found_serialheader = 0; if (resync) { /* resync if necessary */ msg->resync_offset = 0; do { if (memcmp(buffer + msg->resync_offset, dltSerialHeader, sizeof(dltSerialHeader)) == 0) { /* serial header found */ msg->found_serialheader = 1; buffer += sizeof(dltSerialHeader); length -= sizeof(dltSerialHeader); break; } msg->resync_offset++; } while ((sizeof(dltSerialHeader) + msg->resync_offset) <= length); /* Set new start offset */ if (msg->resync_offset > 0) { /* Resyncing connection */ buffer += msg->resync_offset; length -= msg->resync_offset; } } } /* check that standard header fits buffer */ if (length < sizeof(DltStandardHeader)) /* dlt_log(LOG_ERR, "Length smaller than standard header!\n"); */ return DLT_MESSAGE_ERROR_SIZE; memcpy(msg->headerbuffer + sizeof(DltStorageHeader), buffer, sizeof(DltStandardHeader)); /* set ptrs to structures */ msg->storageheader = (DltStorageHeader *)msg->headerbuffer; msg->standardheader = (DltStandardHeader *)(msg->headerbuffer + sizeof(DltStorageHeader)); /* calculate complete size of headers */ extra_size = DLT_STANDARD_HEADER_EXTRA_SIZE(msg->standardheader->htyp) + (DLT_IS_HTYP_UEH(msg->standardheader->htyp) ? sizeof(DltExtendedHeader) : 0); msg->headersize = sizeof(DltStorageHeader) + sizeof(DltStandardHeader) + extra_size; msg->datasize = DLT_BETOH_16(msg->standardheader->len) - (msg->headersize - sizeof(DltStorageHeader)); if (verbose) { dlt_vlog(LOG_DEBUG, "BufferLength=%d, HeaderSize=%d, DataSize=%d\n", length, msg->headersize, msg->datasize); } /* check data size */ if (msg->datasize < 0) { dlt_vlog(LOG_WARNING, "Plausibility check failed. Complete message size too short (%d)!\n", msg->datasize); return DLT_MESSAGE_ERROR_CONTENT; } /* load standard header extra parameters and Extended header if used */ if (extra_size > 0) { if (length < (msg->headersize - sizeof(DltStorageHeader))) return DLT_MESSAGE_ERROR_SIZE; memcpy(msg->headerbuffer + sizeof(DltStorageHeader) + sizeof(DltStandardHeader), buffer + sizeof(DltStandardHeader), extra_size); /* set extended header ptr and get standard header extra parameters */ if (DLT_IS_HTYP_UEH(msg->standardheader->htyp)) msg->extendedheader = (DltExtendedHeader *)(msg->headerbuffer + sizeof(DltStorageHeader) + sizeof(DltStandardHeader) + DLT_STANDARD_HEADER_EXTRA_SIZE(msg->standardheader->htyp)); else msg->extendedheader = NULL; dlt_message_get_extraparameters(msg, verbose); } /* check if payload fits length */ if (length < (msg->headersize - sizeof(DltStorageHeader) + msg->datasize)) /* dlt_log(LOG_ERR,"length does not fit!\n"); */ return DLT_MESSAGE_ERROR_SIZE; /* free last used memory for buffer */ if (msg->databuffer) { if (msg->datasize > msg->databuffersize) { free(msg->databuffer); msg->databuffer = (uint8_t *)malloc(msg->datasize); msg->databuffersize = msg->datasize; } } else { /* get new memory for buffer */ msg->databuffer = (uint8_t *)malloc(msg->datasize); msg->databuffersize = msg->datasize; } if (msg->databuffer == NULL) { dlt_vlog(LOG_WARNING, "Cannot allocate memory for payload buffer of size %d!\n", msg->datasize); return DLT_MESSAGE_ERROR_UNKNOWN; } /* load payload data from buffer */ memcpy(msg->databuffer, buffer + (msg->headersize - sizeof(DltStorageHeader)), msg->datasize); return DLT_MESSAGE_ERROR_OK; } DltReturnValue dlt_message_get_extraparameters(DltMessage *msg, int verbose) { PRINT_FUNCTION_VERBOSE(verbose); if (msg == NULL) return DLT_RETURN_WRONG_PARAMETER; if (DLT_IS_HTYP_WEID(msg->standardheader->htyp)) memcpy(msg->headerextra.ecu, msg->headerbuffer + sizeof(DltStorageHeader) + sizeof(DltStandardHeader), DLT_ID_SIZE); if (DLT_IS_HTYP_WSID(msg->standardheader->htyp)) { memcpy(&(msg->headerextra.seid), msg->headerbuffer + sizeof(DltStorageHeader) + sizeof(DltStandardHeader) + (DLT_IS_HTYP_WEID(msg->standardheader->htyp) ? DLT_SIZE_WEID : 0), DLT_SIZE_WSID); msg->headerextra.seid = DLT_BETOH_32(msg->headerextra.seid); } if (DLT_IS_HTYP_WTMS(msg->standardheader->htyp)) { memcpy(&(msg->headerextra.tmsp), msg->headerbuffer + sizeof(DltStorageHeader) + sizeof(DltStandardHeader) + (DLT_IS_HTYP_WEID(msg->standardheader->htyp) ? DLT_SIZE_WEID : 0) + (DLT_IS_HTYP_WSID(msg->standardheader->htyp) ? DLT_SIZE_WSID : 0), DLT_SIZE_WTMS); msg->headerextra.tmsp = DLT_BETOH_32(msg->headerextra.tmsp); } return DLT_RETURN_OK; } DltReturnValue dlt_message_set_extraparameters(DltMessage *msg, int verbose) { PRINT_FUNCTION_VERBOSE(verbose); if (msg == NULL) return DLT_RETURN_WRONG_PARAMETER; if (DLT_IS_HTYP_WEID(msg->standardheader->htyp)) memcpy(msg->headerbuffer + sizeof(DltStorageHeader) + sizeof(DltStandardHeader), msg->headerextra.ecu, DLT_ID_SIZE); if (DLT_IS_HTYP_WSID(msg->standardheader->htyp)) { msg->headerextra.seid = DLT_HTOBE_32(msg->headerextra.seid); memcpy(msg->headerbuffer + sizeof(DltStorageHeader) + sizeof(DltStandardHeader) + (DLT_IS_HTYP_WEID(msg->standardheader->htyp) ? DLT_SIZE_WEID : 0), &(msg->headerextra.seid), DLT_SIZE_WSID); } if (DLT_IS_HTYP_WTMS(msg->standardheader->htyp)) { msg->headerextra.tmsp = DLT_HTOBE_32(msg->headerextra.tmsp); memcpy(msg->headerbuffer + sizeof(DltStorageHeader) + sizeof(DltStandardHeader) + (DLT_IS_HTYP_WEID(msg->standardheader->htyp) ? DLT_SIZE_WEID : 0) + (DLT_IS_HTYP_WSID(msg->standardheader->htyp) ? DLT_SIZE_WSID : 0), &(msg->headerextra.tmsp), DLT_SIZE_WTMS); } return DLT_RETURN_OK; } DltReturnValue dlt_file_init(DltFile *file, int verbose) { PRINT_FUNCTION_VERBOSE(verbose); if (file == NULL) return DLT_RETURN_WRONG_PARAMETER; /* initalise structure parameters */ file->handle = NULL; file->counter = 0; file->counter_total = 0; file->index = NULL; file->filter = NULL; file->filter_counter = 0; file->file_position = 0; file->position = 0; file->error_messages = 0; return dlt_message_init(&(file->msg), verbose); } DltReturnValue dlt_file_set_filter(DltFile *file, DltFilter *filter, int verbose) { PRINT_FUNCTION_VERBOSE(verbose); if (file == NULL) return DLT_RETURN_WRONG_PARAMETER; /* set filter */ file->filter = filter; return DLT_RETURN_OK; } DltReturnValue dlt_file_read_header(DltFile *file, int verbose) { PRINT_FUNCTION_VERBOSE(verbose); if (file == NULL) return DLT_RETURN_WRONG_PARAMETER; /* load header from file */ if (fread(file->msg.headerbuffer, sizeof(DltStorageHeader) + sizeof(DltStandardHeader), 1, file->handle) != 1) { if (!feof(file->handle)) dlt_log(LOG_WARNING, "Cannot read header from file!\n"); return DLT_RETURN_ERROR; } /* set ptrs to structures */ file->msg.storageheader = (DltStorageHeader *)file->msg.headerbuffer; file->msg.standardheader = (DltStandardHeader *)(file->msg.headerbuffer + sizeof(DltStorageHeader)); /* check id of storage header */ if (dlt_check_storageheader(file->msg.storageheader) != DLT_RETURN_TRUE) { dlt_log(LOG_WARNING, "DLT storage header pattern not found!\n"); return DLT_RETURN_ERROR; } /* calculate complete size of headers */ file->msg.headersize = sizeof(DltStorageHeader) + sizeof(DltStandardHeader) + DLT_STANDARD_HEADER_EXTRA_SIZE(file->msg.standardheader->htyp) + (DLT_IS_HTYP_UEH(file->msg.standardheader->htyp) ? sizeof(DltExtendedHeader) : 0); file->msg.datasize = DLT_BETOH_16(file->msg.standardheader->len) + sizeof(DltStorageHeader) - file->msg.headersize; if (verbose) { dlt_vlog(LOG_DEBUG, "HeaderSize=%d, DataSize=%d\n", file->msg.headersize, file->msg.datasize); } /* check data size */ if (file->msg.datasize < 0) { dlt_vlog(LOG_WARNING, "Plausibility check failed. Complete message size too short! (%d)\n", file->msg.datasize); return DLT_RETURN_ERROR; } return DLT_RETURN_OK; } DltReturnValue dlt_file_read_header_raw(DltFile *file, int resync, int verbose) { char dltSerialHeaderBuffer[DLT_ID_SIZE]; PRINT_FUNCTION_VERBOSE(verbose); if (file == NULL) return DLT_RETURN_WRONG_PARAMETER; /* check if serial header exists, ignore if found */ if (fread(dltSerialHeaderBuffer, sizeof(dltSerialHeaderBuffer), 1, file->handle) != 1) { /* cannot read serial header, not enough data available in file */ if (!feof(file->handle)) dlt_log(LOG_WARNING, "Cannot read header from file!\n"); return DLT_RETURN_ERROR; } if (memcmp(dltSerialHeaderBuffer, dltSerialHeader, sizeof(dltSerialHeader)) == 0) { /* serial header found */ /* nothing to do continue reading */ } else { /* serial header not found */ if (resync) { /* increase error counter */ file->error_messages++; /* resync to serial header */ do { memmove(dltSerialHeaderBuffer, dltSerialHeaderBuffer + 1, sizeof(dltSerialHeader) - 1); if (fread(dltSerialHeaderBuffer + 3, 1, 1, file->handle) != 1) /* cannot read any data, perhaps end of file reached */ return DLT_RETURN_ERROR; if (memcmp(dltSerialHeaderBuffer, dltSerialHeader, sizeof(dltSerialHeader)) == 0) /* serial header synchronised */ break; } while (1); } else /* go back to last file position */ if (0 != fseek(file->handle, file->file_position, SEEK_SET)) return DLT_RETURN_ERROR; } /* load header from file */ if (fread(file->msg.headerbuffer + sizeof(DltStorageHeader), sizeof(DltStandardHeader), 1, file->handle) != 1) { if (!feof(file->handle)) dlt_log(LOG_WARNING, "Cannot read header from file!\n"); return DLT_RETURN_ERROR; } /* set ptrs to structures */ file->msg.storageheader = (DltStorageHeader *)file->msg.headerbuffer; /* this points now to a empty storage header (filled with '0') */ file->msg.standardheader = (DltStandardHeader *)(file->msg.headerbuffer + sizeof(DltStorageHeader)); /* Skip storage header field, fill this field with '0' */ memset(file->msg.storageheader, 0, sizeof(DltStorageHeader)); /* Set storage header */ dlt_set_storageheader(file->msg.storageheader, DLT_COMMON_DUMMY_ECUID); /* no check for storage header id*/ /* calculate complete size of headers */ file->msg.headersize = sizeof(DltStorageHeader) + sizeof(DltStandardHeader) + DLT_STANDARD_HEADER_EXTRA_SIZE(file->msg.standardheader->htyp) + (DLT_IS_HTYP_UEH(file->msg.standardheader->htyp) ? sizeof(DltExtendedHeader) : 0); file->msg.datasize = DLT_BETOH_16(file->msg.standardheader->len) + sizeof(DltStorageHeader) - file->msg.headersize; if (verbose) { dlt_vlog(LOG_DEBUG, "HeaderSize=%d, DataSize=%d\n", file->msg.headersize, file->msg.datasize); } /* check data size */ if (file->msg.datasize < 0) { dlt_vlog(LOG_WARNING, "Plausibility check failed. Complete message size too short! (%d)\n", file->msg.datasize); return DLT_RETURN_ERROR; } return DLT_RETURN_OK; } DltReturnValue dlt_file_read_header_extended(DltFile *file, int verbose) { PRINT_FUNCTION_VERBOSE(verbose); if (file == NULL) return DLT_RETURN_WRONG_PARAMETER; /* load standard header extra parameters if used */ if (DLT_STANDARD_HEADER_EXTRA_SIZE(file->msg.standardheader->htyp)) { if (fread(file->msg.headerbuffer + sizeof(DltStorageHeader) + sizeof(DltStandardHeader), DLT_STANDARD_HEADER_EXTRA_SIZE(file->msg.standardheader->htyp), 1, file->handle) != 1) { dlt_log(LOG_WARNING, "Cannot read standard header extra parameters from file!\n"); return DLT_RETURN_ERROR; } dlt_message_get_extraparameters(&(file->msg), verbose); } /* load Extended header if used */ if (DLT_IS_HTYP_UEH(file->msg.standardheader->htyp) == 0) /* there is nothing to be loaded */ return DLT_RETURN_OK; if (fread(file->msg.headerbuffer + sizeof(DltStorageHeader) + sizeof(DltStandardHeader) + DLT_STANDARD_HEADER_EXTRA_SIZE(file->msg.standardheader->htyp), (DLT_IS_HTYP_UEH(file->msg.standardheader->htyp) ? sizeof(DltExtendedHeader) : 0), 1, file->handle) != 1) { dlt_log(LOG_WARNING, "Cannot read extended header from file!\n"); return DLT_RETURN_ERROR; } /* set extended header ptr */ if (DLT_IS_HTYP_UEH(file->msg.standardheader->htyp)) file->msg.extendedheader = (DltExtendedHeader *)(file->msg.headerbuffer + sizeof(DltStorageHeader) + sizeof(DltStandardHeader) + DLT_STANDARD_HEADER_EXTRA_SIZE(file->msg.standardheader->htyp)); else file->msg.extendedheader = NULL; return DLT_RETURN_OK; } DltReturnValue dlt_file_read_data(DltFile *file, int verbose) { PRINT_FUNCTION_VERBOSE(verbose); if (file == NULL) return DLT_RETURN_WRONG_PARAMETER; /* free last used memory for buffer */ if (file->msg.databuffer && (file->msg.databuffersize < file->msg.datasize)) { free(file->msg.databuffer); file->msg.databuffer = NULL; } if (file->msg.databuffer == NULL) { /* get new memory for buffer */ file->msg.databuffer = (uint8_t *)malloc(file->msg.datasize); file->msg.databuffersize = file->msg.datasize; } if (file->msg.databuffer == NULL) { dlt_vlog(LOG_WARNING, "Cannot allocate memory for payload buffer of size %d!\n", file->msg.datasize); return DLT_RETURN_ERROR; } /* load payload data from file */ if (fread(file->msg.databuffer, file->msg.datasize, 1, file->handle) != 1) { if (file->msg.datasize != 0) { dlt_vlog(LOG_WARNING, "Cannot read payload data from file of size %d!\n", file->msg.datasize); return DLT_RETURN_ERROR; } } return DLT_RETURN_OK; } DltReturnValue dlt_file_open(DltFile *file, const char *filename, int verbose) { PRINT_FUNCTION_VERBOSE(verbose); if ((file == NULL) || (filename == NULL)) return DLT_RETURN_WRONG_PARAMETER; /* reset counters */ file->counter = 0; file->counter_total = 0; file->position = 0; file->file_position = 0; file->file_length = 0; file->error_messages = 0; if (file->handle) fclose(file->handle); /* open dlt file */ file->handle = fopen(filename, "rb"); if (file->handle == NULL) { dlt_vlog(LOG_WARNING, "File %s cannot be opened!\n", filename); return DLT_RETURN_ERROR; } if (0 != fseek(file->handle, 0, SEEK_END)) { dlt_vlog(LOG_WARNING, "dlt_file_open: Seek failed to 0,SEEK_END"); return DLT_RETURN_ERROR; } file->file_length = ftell(file->handle); if (0 != fseek(file->handle, 0, SEEK_SET)) { dlt_vlog(LOG_WARNING, "dlt_file_open: Seek failed to 0,SEEK_SET"); return DLT_RETURN_ERROR; } if (verbose) { /* print file length */ dlt_vlog(LOG_DEBUG, "File is %lu bytes long\n", file->file_length); } return DLT_RETURN_OK; } DltReturnValue dlt_file_read(DltFile *file, int verbose) { long *ptr; int found = DLT_RETURN_OK; if (verbose) { dlt_vlog(LOG_DEBUG, "%s: Message %d:\n", __func__, file->counter_total); } if (file == NULL) return DLT_RETURN_WRONG_PARAMETER; /* allocate new memory for index if number of messages exceeds a multiple of DLT_COMMON_INDEX_ALLOC (e.g.: 1000) */ if (file->counter % DLT_COMMON_INDEX_ALLOC == 0) { ptr = (long *)malloc(((file->counter / DLT_COMMON_INDEX_ALLOC) + 1) * DLT_COMMON_INDEX_ALLOC * sizeof(long)); if (ptr == NULL) return DLT_RETURN_ERROR; if (file->index) { memcpy(ptr, file->index, file->counter * sizeof(long)); free(file->index); } file->index = ptr; } /* set to end of last succesful read message, because of conflicting calls to dlt_file_read and dlt_file_message */ if (0 != fseek(file->handle, file->file_position, SEEK_SET)) { dlt_vlog(LOG_WARNING, "Seek failed to file_position %ld \n", file->file_position); return DLT_RETURN_ERROR; } /* get file position at start of DLT message */ if (verbose) { dlt_vlog(LOG_INFO, "Position in file: %ld\n", file->file_position); } /* read header */ if (dlt_file_read_header(file, verbose) < DLT_RETURN_OK) { /* go back to last position in file */ fseek(file->handle, file->file_position, SEEK_SET); return DLT_RETURN_ERROR; } if (file->filter) { /* read the extended header if filter is enabled and extended header exists */ if (dlt_file_read_header_extended(file, verbose) < DLT_RETURN_OK) { /* go back to last position in file */ if (0 != fseek(file->handle, file->file_position, SEEK_SET)) { dlt_vlog(LOG_WARNING, "Seek to last file pos failed!\n"); } return DLT_RETURN_ERROR; } /* check the filters if message is used */ if (dlt_message_filter_check(&(file->msg), file->filter, verbose) == DLT_RETURN_TRUE) { /* filter matched, consequently store current message */ /* store index pointer to message position in DLT file */ file->index[file->counter] = file->file_position; file->counter++; file->position = file->counter - 1; found = DLT_RETURN_TRUE; } /* skip payload data */ if (fseek(file->handle, file->msg.datasize, SEEK_CUR) != 0) { /* go back to last position in file */ dlt_vlog(LOG_WARNING, "Seek failed to skip payload data of size %d!\n", file->msg.datasize); if (0 != fseek(file->handle, file->file_position, SEEK_SET)) { dlt_log(LOG_WARNING, "Seek back also failed!\n"); } return DLT_RETURN_ERROR; } } else { /* filter is disabled */ /* skip additional header parameters and payload data */ if (fseek(file->handle, file->msg.headersize - sizeof(DltStorageHeader) - sizeof(DltStandardHeader) + file->msg.datasize, SEEK_CUR)) { dlt_vlog(LOG_WARNING, "Seek failed to skip extra header and payload data from file of size %d!\n", file->msg.headersize - (int32_t)sizeof(DltStorageHeader) - (int32_t)sizeof(DltStandardHeader) + file->msg.datasize); /* go back to last position in file */ if (fseek(file->handle, file->file_position, SEEK_SET)) { dlt_log(LOG_WARNING, "Seek back also failed!\n"); } return DLT_RETURN_ERROR; } /* store index pointer to message position in DLT file */ file->index[file->counter] = file->file_position; file->counter++; file->position = file->counter - 1; found = DLT_RETURN_TRUE; } /* increase total message counter */ file->counter_total++; /* store position to next message */ file->file_position = ftell(file->handle); return found; } DltReturnValue dlt_file_read_raw(DltFile *file, int resync, int verbose) { int found = DLT_RETURN_OK; long *ptr; if (verbose) { dlt_vlog(LOG_DEBUG, "%s: Message %d:\n", __func__, file->counter_total); } if (file == NULL) return DLT_RETURN_WRONG_PARAMETER; /* allocate new memory for index if number of messages exceeds a multiple of DLT_COMMON_INDEX_ALLOC (e.g.: 1000) */ if (file->counter % DLT_COMMON_INDEX_ALLOC == 0) { ptr = (long *)malloc(((file->counter / DLT_COMMON_INDEX_ALLOC) + 1) * DLT_COMMON_INDEX_ALLOC * sizeof(long)); if (ptr == NULL) return DLT_RETURN_ERROR; if (file->index) { memcpy(ptr, file->index, file->counter * sizeof(long)); free(file->index); } file->index = ptr; } /* set to end of last successful read message, because of conflicting calls to dlt_file_read and dlt_file_message */ if (0 != fseek(file->handle, file->file_position, SEEK_SET)) return DLT_RETURN_ERROR; /* get file position at start of DLT message */ if (verbose) { dlt_vlog(LOG_DEBUG, "Position in file: %ld\n", file->file_position); } /* read header */ if (dlt_file_read_header_raw(file, resync, verbose) < DLT_RETURN_OK) { /* go back to last position in file */ if (0 != fseek(file->handle, file->file_position, SEEK_SET)) { dlt_log(LOG_WARNING, "dlt_file_read_raw, fseek failed 1\n"); } return DLT_RETURN_ERROR; } /* read the extended header if filter is enabled and extended header exists */ if (dlt_file_read_header_extended(file, verbose) < DLT_RETURN_OK) { /* go back to last position in file */ if (0 != fseek(file->handle, file->file_position, SEEK_SET)) { dlt_log(LOG_WARNING, "dlt_file_read_raw, fseek failed 2\n"); } return DLT_RETURN_ERROR; } if (dlt_file_read_data(file, verbose) < DLT_RETURN_OK) { /* go back to last position in file */ if (0 != fseek(file->handle, file->file_position, SEEK_SET)) { dlt_log(LOG_WARNING, "dlt_file_read_raw, fseek failed 3\n"); } return DLT_RETURN_ERROR; } /* store index pointer to message position in DLT file */ file->index[file->counter] = file->file_position; file->counter++; file->position = file->counter - 1; found = DLT_RETURN_TRUE; /* increase total message counter */ file->counter_total++; /* store position to next message */ file->file_position = ftell(file->handle); return found; } DltReturnValue dlt_file_close(DltFile *file, int verbose) { PRINT_FUNCTION_VERBOSE(verbose); if (file == NULL) return DLT_RETURN_WRONG_PARAMETER; if (file->handle) fclose(file->handle); file->handle = NULL; return DLT_RETURN_OK; } DltReturnValue dlt_file_message(DltFile *file, int index, int verbose) { PRINT_FUNCTION_VERBOSE(verbose); if (file == NULL) return DLT_RETURN_WRONG_PARAMETER; /* check if message is in range */ if (index >= file->counter) { dlt_vlog(LOG_WARNING, "Message %d out of range!\r\n", index); return DLT_RETURN_WRONG_PARAMETER; } /* seek to position in file */ if (fseek(file->handle, file->index[index], SEEK_SET) != 0) { dlt_vlog(LOG_WARNING, "Seek to message %d to position %ld failed!\r\n", index, file->index[index]); return DLT_RETURN_ERROR; } /* read all header and payload */ if (dlt_file_read_header(file, verbose) < DLT_RETURN_OK) return DLT_RETURN_ERROR; if (dlt_file_read_header_extended(file, verbose) < DLT_RETURN_OK) return DLT_RETURN_ERROR; if (dlt_file_read_data(file, verbose) < DLT_RETURN_OK) return DLT_RETURN_ERROR; /* set current position in file */ file->position = index; return DLT_RETURN_OK; } DltReturnValue dlt_file_free(DltFile *file, int verbose) { PRINT_FUNCTION_VERBOSE(verbose); if (file == NULL) return DLT_RETURN_WRONG_PARAMETER; /* delete index lost if exists */ if (file->index) free(file->index); file->index = NULL; /* close file */ if (file->handle) fclose(file->handle); file->handle = NULL; return dlt_message_free(&(file->msg), verbose); } void dlt_log_set_level(int level) { if ((level < 0) || (level > LOG_DEBUG)) { if (logging_level < LOG_WARNING) logging_level = LOG_WARNING; dlt_vlog(LOG_WARNING, "Wrong parameter for level: %d\n", level); } else { logging_level = level; } } void dlt_log_set_filename(const char *filename) { /* check nullpointer */ if (filename == NULL) { dlt_log(LOG_WARNING, "Wrong parameter: filename is NULL\n"); return; } strncpy(logging_filename, filename, NAME_MAX); logging_filename[NAME_MAX] = 0; } void dlt_log_set_fifo_basedir(const char *env_pipe_dir) { strncpy(dltFifoBaseDir, env_pipe_dir, DLT_PATH_MAX); dltFifoBaseDir[DLT_PATH_MAX - 1] = 0; } #ifdef DLT_SHM_ENABLE void dlt_log_set_shm_name(const char * env_shm_name) { strncpy(dltShmName, env_shm_name, NAME_MAX); dltShmName[NAME_MAX] = 0; } #endif void dlt_log_init(int mode) { if ((mode < DLT_LOG_TO_CONSOLE) || (mode > DLT_LOG_DROPPED)) { dlt_vlog(LOG_WARNING, "Wrong parameter for mode: %d\n", mode); return; } logging_mode = mode; if (logging_mode == DLT_LOG_TO_FILE) { /* internal logging to file */ logging_handle = fopen(logging_filename, "a"); if (logging_handle == NULL) { printf("Internal log file %s cannot be opened!\n", logging_filename); return; } } } void dlt_log_free(void) { if (logging_mode == DLT_LOG_TO_FILE) fclose(logging_handle); } DltReturnValue dlt_log(int prio, char *s) { static const char asSeverity[LOG_DEBUG + 2][11] = { "EMERGENCY", "ALERT ", "CRITICAL ", "ERROR ", "WARNING ", "NOTICE ", "INFO ", "DEBUG ", " " }; static const char sFormatString[] = "[%5d.%06d]~DLT~%5d~%s~%s"; struct timespec sTimeSpec; if (s == NULL) return DLT_RETURN_WRONG_PARAMETER; if (logging_level < prio) return DLT_RETURN_OK; if ((prio < 0) || (prio > LOG_DEBUG)) prio = LOG_DEBUG + 1; clock_gettime(CLOCK_MONOTONIC, &sTimeSpec); switch (logging_mode) { case DLT_LOG_TO_CONSOLE: /* log to stdout */ printf(sFormatString, (unsigned int)sTimeSpec.tv_sec, (unsigned int)(sTimeSpec.tv_nsec / 1000), getpid(), asSeverity[prio], s); fflush(stdout); break; case DLT_LOG_TO_SYSLOG: /* log to syslog */ #if !defined (__WIN32__) && !defined(_MSC_VER) openlog("DLT", LOG_PID, LOG_DAEMON); syslog(prio, sFormatString, (unsigned int)sTimeSpec.tv_sec, (unsigned int)(sTimeSpec.tv_nsec / 1000), getpid(), asSeverity[prio], s); closelog(); #endif break; case DLT_LOG_TO_FILE: /* log to file */ if (logging_handle) { fprintf(logging_handle, sFormatString, (unsigned int)sTimeSpec.tv_sec, (unsigned int)(sTimeSpec.tv_nsec / 1000), getpid(), asSeverity[prio], s); fflush(logging_handle); } break; case DLT_LOG_DROPPED: default: break; } return DLT_RETURN_OK; } DltReturnValue dlt_vlog(int prio, const char *format, ...) { char outputString[2048] = { 0 }; /* TODO: what is a reasonable string length here? */ va_list args; if (format == NULL) return DLT_RETURN_WRONG_PARAMETER; if (logging_level < prio) return DLT_RETURN_OK; va_start(args, format); vsnprintf(outputString, 2047, format, args); va_end(args); dlt_log(prio, outputString); return DLT_RETURN_OK; } DltReturnValue dlt_vnlog(int prio, size_t size, const char *format, ...) { char *outputString = NULL; va_list args; if (format == NULL) return DLT_RETURN_WRONG_PARAMETER; if ((logging_level < prio) || (size == 0)) return DLT_RETURN_OK; if ((outputString = (char *)calloc(size + 1, sizeof(char))) == NULL) return DLT_RETURN_ERROR; va_start(args, format); vsnprintf(outputString, size, format, args); va_end(args); dlt_log(prio, outputString); free(outputString); outputString = NULL; return DLT_RETURN_OK; } DltReturnValue dlt_receiver_init(DltReceiver *receiver, int fd, int buffersize) { if (receiver == NULL) return DLT_RETURN_WRONG_PARAMETER; receiver->lastBytesRcvd = 0; receiver->bytesRcvd = 0; receiver->totalBytesRcvd = 0; receiver->buffersize = buffersize; receiver->fd = fd; receiver->buffer = (char *)malloc(receiver->buffersize); receiver->backup_buf = NULL; if (receiver->buffer == NULL) { receiver->buf = NULL; return DLT_RETURN_ERROR; } else { receiver->buf = receiver->buffer; } return DLT_RETURN_OK; } DltReturnValue dlt_receiver_init_unix_socket(DltReceiver *receiver, int fd, char **buffer) { if (receiver == NULL) return DLT_RETURN_WRONG_PARAMETER; if (*buffer == NULL) { /* allocating the buffer once and using it for all application receivers * by keeping allocated buffer in app_recv_buffer global handle */ *buffer = (char *)malloc(DLT_RECEIVE_BUFSIZE); if (*buffer == NULL) return DLT_RETURN_ERROR; } receiver->lastBytesRcvd = 0; receiver->bytesRcvd = 0; receiver->totalBytesRcvd = 0; receiver->buffersize = DLT_RECEIVE_BUFSIZE; receiver->fd = fd; receiver->buffer = *buffer; receiver->backup_buf = NULL; receiver->buf = receiver->buffer; return DLT_RETURN_OK; } DltReturnValue dlt_receiver_free(DltReceiver *receiver) { if (receiver == NULL) return DLT_RETURN_WRONG_PARAMETER; if (receiver->buffer) free(receiver->buffer); if (receiver->backup_buf) free(receiver->backup_buf); receiver->buffer = NULL; receiver->buf = NULL; receiver->backup_buf = NULL; return DLT_RETURN_OK; } DltReturnValue dlt_receiver_free_unix_socket(DltReceiver *receiver) { if (receiver == NULL) return DLT_RETURN_WRONG_PARAMETER; if (receiver->backup_buf) free(receiver->backup_buf); receiver->buffer = NULL; receiver->buf = NULL; receiver->backup_buf = NULL; return DLT_RETURN_OK; } int dlt_receiver_receive(DltReceiver *receiver, DltReceiverType from_src) { if (receiver == NULL) return -1; if (receiver->buffer == NULL) return -1; receiver->buf = (char *)receiver->buffer; receiver->lastBytesRcvd = receiver->bytesRcvd; if ((receiver->lastBytesRcvd) && (receiver->backup_buf != NULL)) { memcpy(receiver->buf, receiver->backup_buf, receiver->lastBytesRcvd); free(receiver->backup_buf); receiver->backup_buf = NULL; } if (from_src == DLT_RECEIVE_SOCKET) /* wait for data from socket */ receiver->bytesRcvd = recv(receiver->fd, receiver->buf + receiver->lastBytesRcvd, receiver->buffersize - receiver->lastBytesRcvd, 0); else /* wait for data from fd */ receiver->bytesRcvd = read(receiver->fd, receiver->buf + receiver->lastBytesRcvd, receiver->buffersize - receiver->lastBytesRcvd); if (receiver->bytesRcvd <= 0) { receiver->bytesRcvd = 0; return receiver->bytesRcvd; } /* if */ receiver->totalBytesRcvd += receiver->bytesRcvd; receiver->bytesRcvd += receiver->lastBytesRcvd; return receiver->bytesRcvd; } DltReturnValue dlt_receiver_remove(DltReceiver *receiver, int size) { if (receiver == NULL) return DLT_RETURN_WRONG_PARAMETER; if (receiver->buf == NULL) return DLT_RETURN_ERROR; if ((size > receiver->bytesRcvd) || (size <= 0)) { receiver->buf = receiver->buf + receiver->bytesRcvd; receiver->bytesRcvd = 0; return DLT_RETURN_WRONG_PARAMETER; } receiver->bytesRcvd = receiver->bytesRcvd - size; receiver->buf = receiver->buf + size; return DLT_RETURN_OK; } DltReturnValue dlt_receiver_move_to_begin(DltReceiver *receiver) { if (receiver == NULL) return DLT_RETURN_WRONG_PARAMETER; if ((receiver->buffer == NULL) || (receiver->buf == NULL)) return DLT_RETURN_ERROR; if ((receiver->buffer != receiver->buf) && (receiver->bytesRcvd != 0)) { receiver->backup_buf = calloc(receiver->bytesRcvd + 1, sizeof(char)); if (receiver->backup_buf == NULL) dlt_vlog(LOG_WARNING, "Can't allocate memory for backup buf, there will be atleast" "one corrupted message for fd[%d] \n", receiver->fd); else memcpy(receiver->backup_buf, receiver->buf, receiver->bytesRcvd); } return DLT_RETURN_OK; } int dlt_receiver_check_and_get(DltReceiver *receiver, void *dest, unsigned int to_get, unsigned int flags) { unsigned int min_size = to_get; void *src = NULL; if (flags & DLT_RCV_SKIP_HEADER) min_size += sizeof(DltUserHeader); if (!receiver || (receiver->bytesRcvd < (int32_t)min_size) || !receiver->buf || !dest) return DLT_RETURN_WRONG_PARAMETER; src = (void *)receiver->buf; if (flags & DLT_RCV_SKIP_HEADER) src += sizeof(DltUserHeader); memcpy(dest, src, to_get); if (flags & DLT_RCV_REMOVE) { if (dlt_receiver_remove(receiver, min_size) != DLT_RETURN_OK) { dlt_log(LOG_WARNING, "Can't remove bytes from receiver\n"); return DLT_RETURN_ERROR; } } return to_get; } DltReturnValue dlt_set_storageheader(DltStorageHeader *storageheader, const char *ecu) { #if !defined(_MSC_VER) struct timeval tv; #endif if ((storageheader == NULL) || (ecu == NULL)) return DLT_RETURN_WRONG_PARAMETER; /* get time of day */ #if defined(_MSC_VER) time(&(storageheader->seconds)); #else gettimeofday(&tv, NULL); #endif /* prepare storage header */ storageheader->pattern[0] = 'D'; storageheader->pattern[1] = 'L'; storageheader->pattern[2] = 'T'; storageheader->pattern[3] = 0x01; dlt_set_id(storageheader->ecu, ecu); /* Set current time */ #if defined(_MSC_VER) storageheader->microseconds = 0; #else storageheader->seconds = (time_t)tv.tv_sec; /* value is long */ storageheader->microseconds = (int32_t)tv.tv_usec; /* value is long */ #endif return DLT_RETURN_OK; } DltReturnValue dlt_check_storageheader(DltStorageHeader *storageheader) { if (storageheader == NULL) return DLT_RETURN_WRONG_PARAMETER; return ((storageheader->pattern[0] == 'D') && (storageheader->pattern[1] == 'L') && (storageheader->pattern[2] == 'T') && (storageheader->pattern[3] == 1)) ? DLT_RETURN_TRUE : DLT_RETURN_OK; } DltReturnValue dlt_buffer_init_static_server(DltBuffer *buf, const unsigned char *ptr, uint32_t size) { if ((buf == NULL) || (ptr == NULL)) return DLT_RETURN_WRONG_PARAMETER; DltBufferHead *head; /* Init parameters */ buf->shm = (unsigned char *)ptr; buf->min_size = size; buf->max_size = size; buf->step_size = 0; /* Init pointers */ head = (DltBufferHead *)buf->shm; head->read = 0; head->write = 0; head->count = 0; buf->mem = (unsigned char *)(buf->shm + sizeof(DltBufferHead)); buf->size = buf->min_size - sizeof(DltBufferHead); /* clear memory */ memset(buf->mem, 0, buf->size); dlt_vlog(LOG_DEBUG, "%s: Buffer: Size %d, Start address %lX\n", __func__, buf->size, (unsigned long)buf->mem); return DLT_RETURN_OK; /* OK */ } DltReturnValue dlt_buffer_init_static_client(DltBuffer *buf, const unsigned char *ptr, uint32_t size) { if ((buf == NULL) || (ptr == NULL)) return DLT_RETURN_WRONG_PARAMETER; /* Init parameters */ buf->shm = (unsigned char *)ptr; buf->min_size = size; buf->max_size = size; buf->step_size = 0; /* Init pointers */ buf->mem = (unsigned char *)(buf->shm + sizeof(DltBufferHead)); buf->size = buf->min_size - sizeof(DltBufferHead); dlt_vlog(LOG_DEBUG, "%s: Buffer: Size %d, Start address %lX\n", __func__, buf->size, (unsigned long)buf->mem); return DLT_RETURN_OK; /* OK */ } DltReturnValue dlt_buffer_init_dynamic(DltBuffer *buf, uint32_t min_size, uint32_t max_size, uint32_t step_size) { /*Do not DLT_SEM_LOCK inside here! */ DltBufferHead *head; /* catch null pointer */ if (buf == NULL) return DLT_RETURN_WRONG_PARAMETER; /* catch 0 logical errors */ if ((min_size == 0) || (max_size == 0) || (step_size == 0)) return DLT_RETURN_WRONG_PARAMETER; if (min_size > max_size) return DLT_RETURN_WRONG_PARAMETER; if (step_size > max_size) return DLT_RETURN_WRONG_PARAMETER; /* Init parameters */ buf->min_size = min_size; buf->max_size = max_size; buf->step_size = step_size; /* allocat memory */ buf->shm = malloc(buf->min_size); if (buf->shm == NULL) { dlt_vlog(LOG_EMERG, "%s: Buffer: Cannot allocate %d bytes\n", __func__, buf->min_size); return DLT_RETURN_ERROR; } /* Init pointers */ head = (DltBufferHead *)buf->shm; head->read = 0; head->write = 0; head->count = 0; buf->mem = (unsigned char *)(buf->shm + sizeof(DltBufferHead)); buf->size = buf->min_size - sizeof(DltBufferHead); dlt_vlog(LOG_DEBUG, "%s: Buffer: Size %d, Start address %lX\n", __func__, buf->size, (unsigned long)buf->mem); /* clear memory */ memset(buf->mem, 0, buf->size); return DLT_RETURN_OK; /* OK */ } DltReturnValue dlt_buffer_free_static(DltBuffer *buf) { /* catch null pointer */ if (buf == NULL) return DLT_RETURN_WRONG_PARAMETER; if (buf->mem == NULL) { /* buffer not initialized */ dlt_vlog(LOG_WARNING, "%s: Buffer: Buffer not initialized\n", __func__); return DLT_RETURN_ERROR; /* ERROR */ } return DLT_RETURN_OK; } DltReturnValue dlt_buffer_free_dynamic(DltBuffer *buf) { /* catch null pointer */ if (buf == NULL) return DLT_RETURN_WRONG_PARAMETER; if (buf->shm == NULL) { /* buffer not initialized */ dlt_vlog(LOG_WARNING, "%s: Buffer: Buffer not initialized\n", __func__); return DLT_RETURN_ERROR; /* ERROR */ } free(buf->shm); buf->shm = NULL; buf->mem = NULL; return DLT_RETURN_OK; } void dlt_buffer_write_block(DltBuffer *buf, int *write, const unsigned char *data, unsigned int size) { /* catch null pointer */ if ((buf != NULL) && (write != NULL) && (data != NULL)) { if ((int)(*write + size) <= buf->size) { /* write one block */ memcpy(buf->mem + *write, data, size); *write += size; } else { /* write two blocks */ memcpy(buf->mem + *write, data, buf->size - *write); memcpy(buf->mem, data + buf->size - *write, size - buf->size + *write); *write += size - buf->size; } } else { dlt_vlog(LOG_WARNING, "%s: Wrong parameter: Null pointer\n", __func__); } } void dlt_buffer_read_block(DltBuffer *buf, int *read, unsigned char *data, unsigned int size) { /* catch nullpointer */ if ((buf != NULL) && (read != NULL) && (data != NULL)) { if ((int)(*read + size) <= buf->size) { /* read one block */ memcpy(data, buf->mem + *read, size); *read += size; } else { /* read two blocks */ memcpy(data, buf->mem + *read, buf->size - *read); memcpy(data + buf->size - *read, buf->mem, size - buf->size + *read); *read += size - buf->size; } } else { dlt_vlog(LOG_WARNING, "%s: Wrong parameter: Null pointer\n", __func__); } } int dlt_buffer_check_size(DltBuffer *buf, int needed) { if (buf == NULL) return DLT_RETURN_WRONG_PARAMETER; if ((buf->size + sizeof(DltBufferHead) + needed) > buf->max_size) return DLT_RETURN_ERROR; return DLT_RETURN_OK; } int dlt_buffer_increase_size(DltBuffer *buf) { DltBufferHead *head, *new_head; unsigned char *new_ptr; /* catch null pointer */ if (buf == NULL) { dlt_vlog(LOG_WARNING, "%s: Wrong parameter: Null pointer\n", __func__); return DLT_RETURN_WRONG_PARAMETER; } /* check size */ if (buf->step_size == 0) /* cannot increase size */ return DLT_RETURN_ERROR; /* check size */ if ((buf->size + sizeof(DltBufferHead) + buf->step_size) > buf->max_size) /* max size reached, do not increase */ return DLT_RETURN_ERROR; /* allocate new buffer */ new_ptr = malloc(buf->size + sizeof(DltBufferHead) + buf->step_size); if (new_ptr == NULL) { dlt_vlog(LOG_WARNING, "%s: Buffer: Cannot increase size because allocate %d bytes failed\n", __func__, buf->min_size); return DLT_RETURN_ERROR; } /* copy data */ head = (DltBufferHead *)buf->shm; new_head = (DltBufferHead *)new_ptr; if (head->read < head->write) { memcpy(new_ptr + sizeof(DltBufferHead), buf->mem + head->read, head->write - head->read); new_head->read = 0; new_head->write = head->write - head->read; new_head->count = head->count; } else { memcpy(new_ptr + sizeof(DltBufferHead), buf->mem + head->read, buf->size - head->read); memcpy(new_ptr + sizeof(DltBufferHead) + buf->size - head->read, buf->mem, head->write); new_head->read = 0; new_head->write = buf->size - head->read + head->write; new_head->count = head->count; } /* free old data */ free(buf->shm); /* update data */ buf->shm = new_ptr; buf->mem = new_ptr + sizeof(DltBufferHead); buf->size += buf->step_size; dlt_vlog(LOG_DEBUG, "%s: Buffer: Size increased to %d bytes with start address %lX\n", __func__, buf->size + (int32_t)sizeof(DltBufferHead), (unsigned long)buf->mem); return DLT_RETURN_OK; /* OK */ } int dlt_buffer_minimize_size(DltBuffer *buf) { unsigned char *new_ptr; /* catch null pointer */ if (buf == NULL) { dlt_vlog(LOG_WARNING, "%s: Wrong parameter: Null pointer\n", __func__); return DLT_RETURN_WRONG_PARAMETER; } if ((buf->size + sizeof(DltBufferHead)) == buf->min_size) /* already minimized */ return DLT_RETURN_OK; /* allocate new buffer */ new_ptr = malloc(buf->min_size); if (new_ptr == NULL) { dlt_vlog(LOG_WARNING, "%s: Buffer: Cannot set to min size of %d bytes\n", __func__, buf->min_size); return DLT_RETURN_ERROR; } /* free old data */ free(buf->shm); /* update data */ buf->shm = new_ptr; buf->mem = new_ptr + sizeof(DltBufferHead); buf->size = buf->min_size - sizeof(DltBufferHead); /* reset pointers and counters */ ((int *)(buf->shm))[0] = 0; /* pointer to write memory */ ((int *)(buf->shm))[1] = 0; /* pointer to read memory */ ((int *)(buf->shm))[2] = 0; /* number of packets */ dlt_vlog(LOG_DEBUG, "%s: Buffer: Buffer minimized to Size %d bytes with start address %lX\n", __func__, buf->size, (unsigned long)buf->mem); /* clear memory */ memset(buf->mem, 0, buf->size); return DLT_RETURN_OK; /* OK */ } int dlt_buffer_reset(DltBuffer *buf) { /* catch null pointer */ if (buf == NULL) { dlt_vlog(LOG_WARNING, "%s: Wrong parameter: Null pointer\n", __func__); return DLT_RETURN_WRONG_PARAMETER; } dlt_vlog(LOG_WARNING, "%s: Buffer: Buffer reset triggered. Size: %d, Start address: %lX\n", __func__, buf->size, (unsigned long)buf->mem); /* reset pointers and counters */ ((int *)(buf->shm))[0] = 0; /* pointer to write memory */ ((int *)(buf->shm))[1] = 0; /* pointer to read memory */ ((int *)(buf->shm))[2] = 0; /* number of packets */ /* clear memory */ memset(buf->mem, 0, buf->size); return DLT_RETURN_OK; /* OK */ } DltReturnValue dlt_buffer_push(DltBuffer *buf, const unsigned char *data, unsigned int size) { return dlt_buffer_push3(buf, data, size, 0, 0, 0, 0); } int dlt_buffer_push3(DltBuffer *buf, const unsigned char *data1, unsigned int size1, const unsigned char *data2, unsigned int size2, const unsigned char *data3, unsigned int size3) { int free_size; int write, read, count; DltBufferBlockHead head; /* catch null pointer */ if (buf == NULL) return DLT_RETURN_WRONG_PARAMETER; if (buf->shm == NULL) { /* buffer not initialised */ dlt_vlog(LOG_ERR, "%s: Buffer: Buffer not initialized\n", __func__); return DLT_RETURN_ERROR; /* ERROR */ } /* get current write pointer */ write = ((int *)(buf->shm))[0]; read = ((int *)(buf->shm))[1]; count = ((int *)(buf->shm))[2]; /* check pointers */ if ((read > buf->size) || (write > buf->size)) { dlt_vlog(LOG_ERR, "%s: Buffer: Pointer out of range. Read: %d, Write: %d, Size: %d\n", __func__, read, write, buf->size); dlt_buffer_reset(buf); return DLT_RETURN_ERROR; /* ERROR */ } /* calculate free size */ if (read > write) free_size = read - write; else if (count && (write == read)) free_size = 0; else free_size = buf->size - write + read; /* check size */ if (free_size < (int)(sizeof(DltBufferBlockHead) + size1 + size2 + size3)) { /* try to increase size if possible */ if (dlt_buffer_increase_size(buf)) /* increase size is not possible */ /*dlt_log(LOG_ERR, "Buffer: Buffer is full\n"); */ return DLT_RETURN_ERROR; /* ERROR */ /* update pointers */ write = ((int *)(buf->shm))[0]; read = ((int *)(buf->shm))[1]; } /* set header */ strncpy(head.head, DLT_BUFFER_HEAD, 4); head.head[3] = 0; head.status = 2; head.size = size1 + size2 + size3; /* write data */ dlt_buffer_write_block(buf, &write, (unsigned char *)&head, sizeof(DltBufferBlockHead)); if (size1) dlt_buffer_write_block(buf, &write, data1, size1); if (size2) dlt_buffer_write_block(buf, &write, data2, size2); if (size3) dlt_buffer_write_block(buf, &write, data3, size3); /* update global shm pointers */ ((int *)(buf->shm))[0] = write; /* set new write pointer */ ((int *)(buf->shm))[2] += 1; /* increase counter */ return DLT_RETURN_OK; /* OK */ } int dlt_buffer_get(DltBuffer *buf, unsigned char *data, int max_size, int delete) { int used_size; int write, read, count; char head_compare[] = DLT_BUFFER_HEAD; DltBufferBlockHead head; /* catch null pointer */ if (buf == NULL) return DLT_RETURN_WRONG_PARAMETER; if (buf->shm == NULL) { /* shm not initialised */ dlt_vlog(LOG_ERR, "%s: Buffer: SHM not initialized\n", __func__); return DLT_RETURN_ERROR; /* ERROR */ } /* get current write pointer */ write = ((int *)(buf->shm))[0]; read = ((int *)(buf->shm))[1]; count = ((int *)(buf->shm))[2]; /* check pointers */ if ((read > buf->size) || (write > buf->size) || (count < 0)) { dlt_vlog(LOG_ERR, "%s: Buffer: Pointer out of range. Read: %d, Write: %d, Count: %d, Size: %d\n", __func__, read, write, count, buf->size); dlt_buffer_reset(buf); return DLT_RETURN_ERROR; /* ERROR */ } /* check if data is in there */ if (count == 0) { if (write != read) { dlt_vlog(LOG_ERR, "%s: Buffer: SHM should be empty, but is not. Read: %d, Write: %d\n", __func__, read, write); dlt_buffer_reset(buf); } return DLT_RETURN_ERROR; /* ERROR */ } /* calculate used size */ if (write > read) used_size = write - read; else used_size = buf->size - read + write; /* first check size */ if (used_size < (int)(sizeof(DltBufferBlockHead))) { dlt_vlog(LOG_ERR, "%s: Buffer: Used size is smaller than buffer block header size. Used size: %d\n", __func__, used_size); dlt_buffer_reset(buf); return DLT_RETURN_ERROR; /* ERROR */ } /* read header */ dlt_buffer_read_block(buf, &read, (unsigned char *)&head, sizeof(DltBufferBlockHead)); /* check header */ if (memcmp((unsigned char *)(head.head), head_compare, sizeof(head_compare)) != 0) { dlt_vlog(LOG_ERR, "%s: Buffer: Header head check failed\n", __func__); dlt_buffer_reset(buf); return DLT_RETURN_ERROR; /* ERROR */ } if (head.status != 2) { dlt_vlog(LOG_ERR, "%s: Buffer: Header status check failed\n", __func__); dlt_buffer_reset(buf); return DLT_RETURN_ERROR; /* ERROR */ } /* second check size */ if (used_size < (int)(sizeof(DltBufferBlockHead) + head.size)) { dlt_vlog(LOG_ERR, "%s: Buffer: Used size is smaller than buffer block header size And read header size. Used size: %d\n", __func__, used_size); dlt_buffer_reset(buf); return DLT_RETURN_ERROR; /* ERROR */ } /* third check size */ if (max_size && (head.size > max_size)) dlt_vlog(LOG_WARNING, "%s: Buffer: Max size is smaller than read header size. Max size: %d\n", __func__, max_size); /* nothing to do but data does not fit provided buffer */ if ((data != NULL) && max_size) { /* read data */ dlt_buffer_read_block(buf, &read, data, head.size); if (delete) /* update buffer pointers */ ((int *)(buf->shm))[1] = read; /* set new read pointer */ } else if (delete) { if ((read + head.size) <= buf->size) ((int *)(buf->shm))[1] = read + head.size; /* set new read pointer */ else ((int *)(buf->shm))[1] = read + head.size - buf->size; /* set new read pointer */ } if (delete) { ((int *)(buf->shm))[2] -= 1; /* decrease counter */ if (((int *)(buf->shm))[2] == 0) /* try to minimize size */ dlt_buffer_minimize_size(buf); } return head.size; /* OK */ } int dlt_buffer_pull(DltBuffer *buf, unsigned char *data, int max_size) { return dlt_buffer_get(buf, data, max_size, 1); } int dlt_buffer_copy(DltBuffer *buf, unsigned char *data, int max_size) { return dlt_buffer_get(buf, data, max_size, 0); } int dlt_buffer_remove(DltBuffer *buf) { return dlt_buffer_get(buf, 0, 0, 1); } void dlt_buffer_info(DltBuffer *buf) { /* check nullpointer */ if (buf == NULL) { dlt_vlog(LOG_WARNING, "%s: Wrong parameter: Null pointer\n", __func__); return; } dlt_vlog(LOG_DEBUG, "Buffer: Available size: %d, Buffer: Buffer full start address: %lX, Buffer: Buffer start address: %lX\n", buf->size, (unsigned long)buf->shm, (unsigned long)buf->mem); } void dlt_buffer_status(DltBuffer *buf) { int write, read, count; /* check nullpointer */ if (buf == NULL) { dlt_vlog(LOG_WARNING, "%s: Wrong parameter: Null pointer\n", __func__); return; } /* check if buffer available */ if (buf->shm == NULL) return; write = ((int *)(buf->shm))[0]; read = ((int *)(buf->shm))[1]; count = ((int *)(buf->shm))[2]; dlt_vlog(LOG_DEBUG, "Buffer: Write: %d, Read: %d, Count: %d\n", write, read, count); } uint32_t dlt_buffer_get_total_size(DltBuffer *buf) { /* catch null pointer */ if (buf == NULL) return DLT_RETURN_WRONG_PARAMETER; return buf->max_size; } int dlt_buffer_get_used_size(DltBuffer *buf) { int write, read, count; /* catch null pointer */ if (buf == NULL) return DLT_RETURN_WRONG_PARAMETER; /* check if buffer available */ if (buf->shm == NULL) return DLT_RETURN_OK; write = ((int *)(buf->shm))[0]; read = ((int *)(buf->shm))[1]; count = ((int *)(buf->shm))[2]; if (count == 0) return DLT_RETURN_OK; if (write > read) return write - read; return buf->size - read + write; } int dlt_buffer_get_message_count(DltBuffer *buf) { /* catch null pointer */ if (buf == NULL) return DLT_RETURN_WRONG_PARAMETER; /* check if buffer available */ if (buf->shm == NULL) return DLT_RETURN_OK; return ((int *)(buf->shm))[2]; } #if !defined (__WIN32__) DltReturnValue dlt_setup_serial(int fd, speed_t speed) { # if !defined (__WIN32__) && !defined(_MSC_VER) struct termios config; if (isatty(fd) == 0) return DLT_RETURN_ERROR; if (tcgetattr(fd, &config) < 0) return DLT_RETURN_ERROR; /* Input flags - Turn off input processing * convert break to null byte, no CR to NL translation, * no NL to CR translation, don't mark parity errors or breaks * no input parity check, don't strip high bit off, * no XON/XOFF software flow control */ config.c_iflag &= ~(IGNBRK | BRKINT | ICRNL | INLCR | PARMRK | INPCK | ISTRIP | IXON); /* Output flags - Turn off output processing * no CR to NL translation, no NL to CR-NL translation, * no NL to CR translation, no column 0 CR suppression, * no Ctrl-D suppression, no fill characters, no case mapping, * no local output processing * * config.c_oflag &= ~(OCRNL | ONLCR | ONLRET | * ONOCR | ONOEOT| OFILL | OLCUC | OPOST); */ config.c_oflag = 0; /* No line processing: * echo off, echo newline off, canonical mode off, * extended input processing off, signal chars off */ config.c_lflag &= ~(ECHO | ECHONL | ICANON | IEXTEN | ISIG); /* Turn off character processing * clear current char size mask, no parity checking, * no output processing, force 8 bit input */ config.c_cflag &= ~(CSIZE | PARENB); config.c_cflag |= CS8; /* One input byte is enough to return from read() * Inter-character timer off */ config.c_cc[VMIN] = 1; config.c_cc[VTIME] = 0; /* Communication speed (simple version, using the predefined * constants) */ if ((cfsetispeed(&config, speed) < 0) || (cfsetospeed(&config, speed) < 0)) return DLT_RETURN_ERROR; /* Finally, apply the configuration */ if (tcsetattr(fd, TCSAFLUSH, &config) < 0) return DLT_RETURN_ERROR; return DLT_RETURN_OK; # else return DLT_RETURN_ERROR; # endif } speed_t dlt_convert_serial_speed(int baudrate) { # if !defined (__WIN32__) && !defined(_MSC_VER) && !defined(__CYGWIN__) speed_t ret; switch (baudrate) { case 50: { ret = B50; break; } case 75: { ret = B75; break; } case 110: { ret = B110; break; } case 134: { ret = B134; break; } case 150: { ret = B150; break; } case 200: { ret = B200; break; } case 300: { ret = B300; break; } case 600: { ret = B600; break; } case 1200: { ret = B1200; break; } case 1800: { ret = B1800; break; } case 2400: { ret = B2400; break; } case 4800: { ret = B4800; break; } case 9600: { ret = B9600; break; } case 19200: { ret = B19200; break; } case 38400: { ret = B38400; break; } case 57600: { ret = B57600; break; } case 115200: { ret = B115200; break; } # ifdef __linux__ case 230400: { ret = B230400; break; } case 460800: { ret = B460800; break; } case 500000: { ret = B500000; break; } case 576000: { ret = B576000; break; } case 921600: { ret = B921600; break; } case 1000000: { ret = B1000000; break; } case 1152000: { ret = B1152000; break; } case 1500000: { ret = B1500000; break; } case 2000000: { ret = B2000000; break; } case 2500000: { ret = B2500000; break; } case 3000000: { ret = B3000000; break; } case 3500000: { ret = B3500000; break; } case 4000000: { ret = B4000000; break; } # endif /* __linux__ */ default: { ret = B115200; break; } } return ret; # else return 0; # endif } #endif void dlt_get_version(char *buf, size_t size) { if ((buf == NULL) && (size > 0)) { dlt_log(LOG_WARNING, "Wrong parameter: Null pointer\n"); return; } snprintf(buf, size, "DLT Package Version: %s %s, Package Revision: %s, build on %s %s\n%s %s %s %s\n", _DLT_PACKAGE_VERSION, _DLT_PACKAGE_VERSION_STATE, _DLT_PACKAGE_REVISION, __DATE__, __TIME__, _DLT_SYSTEMD_ENABLE, _DLT_SYSTEMD_WATCHDOG_ENABLE, _DLT_TEST_ENABLE, _DLT_SHM_ENABLE); } void dlt_get_major_version(char *buf, size_t size) { if ((buf == NULL) && (size > 0)) { dlt_log(LOG_WARNING, "Wrong parameter: Null pointer\n"); return; } snprintf(buf, size, "%s", _DLT_PACKAGE_MAJOR_VERSION); } void dlt_get_minor_version(char *buf, size_t size) { if ((buf == NULL) && (size > 0)) { dlt_log(LOG_WARNING, "Wrong parameter: Null pointer\n"); return; } snprintf(buf, size, "%s", _DLT_PACKAGE_MINOR_VERSION); } uint32_t dlt_uptime(void) { #if defined (__WIN32__) || defined(_MSC_VER) return (uint32_t)(GetTickCount() * 10); /* GetTickCount() return DWORD */ #else struct timespec ts; if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0) return (uint32_t)ts.tv_sec * 10000 + (uint32_t)ts.tv_nsec / 100000;/* in 0.1 ms = 100 us */ else return 0; #endif } DltReturnValue dlt_message_print_header(DltMessage *message, char *text, uint32_t size, int verbose) { if ((message == NULL) || (text == NULL)) return DLT_RETURN_WRONG_PARAMETER; dlt_message_header(message, text, size, verbose); printf("%s\n", text); return DLT_RETURN_OK; } DltReturnValue dlt_message_print_hex(DltMessage *message, char *text, uint32_t size, int verbose) { if ((message == NULL) || (text == NULL)) return DLT_RETURN_WRONG_PARAMETER; dlt_message_header(message, text, size, verbose); printf("%s ", text); dlt_message_payload(message, text, size, DLT_OUTPUT_HEX, verbose); printf("[%s]\n", text); return DLT_RETURN_OK; } DltReturnValue dlt_message_print_ascii(DltMessage *message, char *text, uint32_t size, int verbose) { if ((message == NULL) || (text == NULL)) return DLT_RETURN_WRONG_PARAMETER; dlt_message_header(message, text, size, verbose); printf("%s ", text); dlt_message_payload(message, text, size, DLT_OUTPUT_ASCII, verbose); printf("[%s]\n", text); return DLT_RETURN_OK; } DltReturnValue dlt_message_print_mixed_plain(DltMessage *message, char *text, uint32_t size, int verbose) { if ((message == NULL) || (text == NULL)) return DLT_RETURN_WRONG_PARAMETER; dlt_message_header(message, text, size, verbose); printf("%s \n", text); dlt_message_payload(message, text, size, DLT_OUTPUT_MIXED_FOR_PLAIN, verbose); printf("[%s]\n", text); return DLT_RETURN_OK; } DltReturnValue dlt_message_print_mixed_html(DltMessage *message, char *text, uint32_t size, int verbose) { if ((message == NULL) || (text == NULL)) return DLT_RETURN_WRONG_PARAMETER; dlt_message_header(message, text, size, verbose); printf("%s \n", text); dlt_message_payload(message, text, size, DLT_OUTPUT_MIXED_FOR_HTML, verbose); printf("[%s]\n", text); return DLT_RETURN_OK; } DltReturnValue dlt_message_argument_print(DltMessage *msg, uint32_t type_info, uint8_t **ptr, int32_t *datalength, char *text, int textlength, int byteLength, int __attribute__((unused)) verbose) { /* check null pointers */ if ((msg == NULL) || (ptr == NULL) || (datalength == NULL) || (text == NULL)) return DLT_RETURN_WRONG_PARAMETER; int16_t length = 0, length_tmp = 0; /* the macro can set this variable to -1 */ uint16_t length2 = 0, length2_tmp = 0, length3 = 0, length3_tmp = 0; uint8_t value8u = 0; uint16_t value16u = 0, value16u_tmp = 0; uint32_t value32u = 0, value32u_tmp = 0; uint64_t value64u = 0, value64u_tmp = 0; int8_t value8i = 0; int16_t value16i = 0, value16i_tmp = 0; int32_t value32i = 0, value32i_tmp = 0; int64_t value64i = 0, value64i_tmp = 0; float32_t value32f = 0, value32f_tmp = 0; int32_t value32f_tmp_int32i = 0, value32f_tmp_int32i_swaped = 0; float64_t value64f = 0, value64f_tmp = 0; int64_t value64f_tmp_int64i = 0, value64f_tmp_int64i_swaped = 0; uint32_t quantisation_tmp = 0; /* apparently this makes no sense but needs to be done to prevent compiler warning. * This variable is only written by DLT_MSG_READ_VALUE macro in if (type_info & DLT_TYPE_INFO_FIXP) * case but never read anywhere */ quantisation_tmp += quantisation_tmp; if ((type_info & DLT_TYPE_INFO_STRG) && (((type_info & DLT_TYPE_INFO_SCOD) == DLT_SCOD_ASCII) || ((type_info & DLT_TYPE_INFO_SCOD) == DLT_SCOD_UTF8))) { /* string type or utf8-encoded string type */ if (byteLength < 0) { DLT_MSG_READ_VALUE(length_tmp, *ptr, *datalength, uint16_t); if ((*datalength) < 0) return DLT_RETURN_ERROR; length = DLT_ENDIAN_GET_16(msg->standardheader->htyp, length_tmp); } else { length = (int16_t)byteLength; } if (type_info & DLT_TYPE_INFO_VARI) { DLT_MSG_READ_VALUE(length2_tmp, *ptr, *datalength, uint16_t); if ((*datalength) < 0) return DLT_RETURN_ERROR; length2 = DLT_ENDIAN_GET_16(msg->standardheader->htyp, length2_tmp); if ((*datalength) < length2) return DLT_RETURN_ERROR; *ptr += length2; *datalength -= length2; } DLT_MSG_READ_STRING((text + strlen(text)), *ptr, *datalength, length); if ((*datalength) < 0) return DLT_RETURN_ERROR; } else if (type_info & DLT_TYPE_INFO_BOOL) { /* Boolean type */ if (type_info & DLT_TYPE_INFO_VARI) { DLT_MSG_READ_VALUE(length2_tmp, *ptr, *datalength, uint16_t); if ((*datalength) < 0) return DLT_RETURN_ERROR; length2 = DLT_ENDIAN_GET_16(msg->standardheader->htyp, length2_tmp); if ((*datalength) < length2) return DLT_RETURN_ERROR; *ptr += length2; *datalength -= length2; } value8u = 0; DLT_MSG_READ_VALUE(value8u, *ptr, *datalength, uint8_t); /* No endian conversion necessary */ if ((*datalength) < 0) return DLT_RETURN_ERROR; snprintf(text + strlen(text), textlength - strlen(text), "%d", value8u); } else if ((type_info & DLT_TYPE_INFO_UINT) && (DLT_SCOD_BIN == (type_info & DLT_TYPE_INFO_SCOD))) { if (DLT_TYLE_8BIT == (type_info & DLT_TYPE_INFO_TYLE)) { DLT_MSG_READ_VALUE(value8u, *ptr, *datalength, uint8_t); /* No endian conversion necessary */ if ((*datalength) < 0) return DLT_RETURN_ERROR; char binary[10] = { '\0' }; /* e.g.: "0b1100 0010" */ int i; for (i = (1 << 7); i > 0; i >>= 1) { if ((1 << 3) == i) strcat(binary, " "); strcat(binary, (i == (value8u & i)) ? "1" : "0"); } snprintf(text + strlen(text), textlength - strlen(text), "0b%s", binary); } if (DLT_TYLE_16BIT == (type_info & DLT_TYPE_INFO_TYLE)) { DLT_MSG_READ_VALUE(value16u, *ptr, *datalength, uint16_t); if ((*datalength) < 0) return DLT_RETURN_ERROR; char binary[20] = { '\0' }; /* e.g.: "0b1100 0010 0011 0110" */ int i; for (i = (1 << 15); i > 0; i >>= 1) { if (((1 << 3) == i) || ((1 << 7) == i) || ((1 << 11) == i)) strcat(binary, " "); strcat(binary, (i == (value16u & i)) ? "1" : "0"); } snprintf(text + strlen(text), textlength - strlen(text), "0b%s", binary); } } else if ((type_info & DLT_TYPE_INFO_UINT) && (DLT_SCOD_HEX == (type_info & DLT_TYPE_INFO_SCOD))) { if (DLT_TYLE_8BIT == (type_info & DLT_TYPE_INFO_TYLE)) { DLT_MSG_READ_VALUE(value8u, *ptr, *datalength, uint8_t); /* No endian conversion necessary */ if ((*datalength) < 0) return DLT_RETURN_ERROR; snprintf(text + strlen(text), textlength - strlen(text), "0x%02x", value8u); } if (DLT_TYLE_16BIT == (type_info & DLT_TYPE_INFO_TYLE)) { DLT_MSG_READ_VALUE(value16u, *ptr, *datalength, uint16_t); if ((*datalength) < 0) return DLT_RETURN_ERROR; snprintf(text + strlen(text), textlength - strlen(text), "0x%04x", value16u); } if (DLT_TYLE_32BIT == (type_info & DLT_TYPE_INFO_TYLE)) { DLT_MSG_READ_VALUE(value32u, *ptr, *datalength, uint32_t); if ((*datalength) < 0) return DLT_RETURN_ERROR; snprintf(text + strlen(text), textlength - strlen(text), "0x%08x", value32u); } if (DLT_TYLE_64BIT == (type_info & DLT_TYPE_INFO_TYLE)) { *ptr += 4; DLT_MSG_READ_VALUE(value32u, *ptr, *datalength, uint32_t); if ((*datalength) < 0) return DLT_RETURN_ERROR; snprintf(text + strlen(text), textlength - strlen(text), "0x%08x", value32u); *ptr -= 8; DLT_MSG_READ_VALUE(value32u, *ptr, *datalength, uint32_t); if ((*datalength) < 0) return DLT_RETURN_ERROR; snprintf(text + strlen(text), textlength - strlen(text), "%08x", value32u); *ptr += 4; } } else if ((type_info & DLT_TYPE_INFO_SINT) || (type_info & DLT_TYPE_INFO_UINT)) { /* signed or unsigned argument received */ if (type_info & DLT_TYPE_INFO_VARI) { DLT_MSG_READ_VALUE(length2_tmp, *ptr, *datalength, uint16_t); if ((*datalength) < 0) return DLT_RETURN_ERROR; length2 = DLT_ENDIAN_GET_16(msg->standardheader->htyp, length2_tmp); DLT_MSG_READ_VALUE(length3_tmp, *ptr, *datalength, uint16_t); if ((*datalength) < 0) return DLT_RETURN_ERROR; length3 = DLT_ENDIAN_GET_16(msg->standardheader->htyp, length3_tmp); if ((*datalength) < length2) return DLT_RETURN_ERROR; *ptr += length2; *datalength -= length2; if ((*datalength) < length3) return DLT_RETURN_ERROR; *ptr += length3; *datalength -= length3; } if (type_info & DLT_TYPE_INFO_FIXP) { DLT_MSG_READ_VALUE(quantisation_tmp, *ptr, *datalength, uint32_t); if ((*datalength) < 0) return DLT_RETURN_ERROR; switch (type_info & DLT_TYPE_INFO_TYLE) { case DLT_TYLE_8BIT: case DLT_TYLE_16BIT: case DLT_TYLE_32BIT: { if ((*datalength) < 4) return DLT_RETURN_ERROR; *ptr += 4; *datalength -= 4; break; } case DLT_TYLE_64BIT: { if ((*datalength) < 8) return DLT_RETURN_ERROR; *ptr += 8; *datalength -= 8; break; } case DLT_TYLE_128BIT: { if ((*datalength) < 16) return DLT_RETURN_ERROR; *ptr += 16; *datalength -= 16; break; } default: { return DLT_RETURN_ERROR; } } } switch (type_info & DLT_TYPE_INFO_TYLE) { case DLT_TYLE_8BIT: { if (type_info & DLT_TYPE_INFO_SINT) { value8i = 0; DLT_MSG_READ_VALUE(value8i, *ptr, *datalength, int8_t); /* No endian conversion necessary */ if ((*datalength) < 0) return DLT_RETURN_ERROR; snprintf(text + strlen(text), textlength - strlen(text), "%d", value8i); } else { value8u = 0; DLT_MSG_READ_VALUE(value8u, *ptr, *datalength, uint8_t); /* No endian conversion necessary */ if ((*datalength) < 0) return DLT_RETURN_ERROR; snprintf(text + strlen(text), textlength - strlen(text), "%d", value8u); } break; } case DLT_TYLE_16BIT: { if (type_info & DLT_TYPE_INFO_SINT) { value16i = 0; value16i_tmp = 0; DLT_MSG_READ_VALUE(value16i_tmp, *ptr, *datalength, int16_t); if ((*datalength) < 0) return DLT_RETURN_ERROR; value16i = DLT_ENDIAN_GET_16(msg->standardheader->htyp, value16i_tmp); snprintf(text + strlen(text), textlength - strlen(text), "%hd", value16i); } else { value16u = 0; value16u_tmp = 0; DLT_MSG_READ_VALUE(value16u_tmp, *ptr, *datalength, uint16_t); if ((*datalength) < 0) return DLT_RETURN_ERROR; value16u = DLT_ENDIAN_GET_16(msg->standardheader->htyp, value16u_tmp); snprintf(text + strlen(text), textlength - strlen(text), "%hu", value16u); } break; } case DLT_TYLE_32BIT: { if (type_info & DLT_TYPE_INFO_SINT) { value32i = 0; value32i_tmp = 0; DLT_MSG_READ_VALUE(value32i_tmp, *ptr, *datalength, int32_t); if ((*datalength) < 0) return DLT_RETURN_ERROR; value32i = DLT_ENDIAN_GET_32(msg->standardheader->htyp, (uint32_t)value32i_tmp); snprintf(text + strlen(text), textlength - strlen(text), "%d", value32i); } else { value32u = 0; value32u_tmp = 0; DLT_MSG_READ_VALUE(value32u_tmp, *ptr, *datalength, uint32_t); if ((*datalength) < 0) return DLT_RETURN_ERROR; value32u = DLT_ENDIAN_GET_32(msg->standardheader->htyp, value32u_tmp); snprintf(text + strlen(text), textlength - strlen(text), "%u", value32u); } break; } case DLT_TYLE_64BIT: { if (type_info & DLT_TYPE_INFO_SINT) { value64i = 0; value64i_tmp = 0; DLT_MSG_READ_VALUE(value64i_tmp, *ptr, *datalength, int64_t); if ((*datalength) < 0) return DLT_RETURN_ERROR; value64i = DLT_ENDIAN_GET_64(msg->standardheader->htyp, (uint64_t)value64i_tmp); #if defined (__WIN32__) && !defined(_MSC_VER) snprintf(text + strlen(text), textlength - strlen(text), "%I64d", value64i); #else snprintf(text + strlen(text), textlength - strlen(text), "%" PRId64, value64i); #endif } else { value64u = 0; value64u_tmp = 0; DLT_MSG_READ_VALUE(value64u_tmp, *ptr, *datalength, uint64_t); if ((*datalength) < 0) return DLT_RETURN_ERROR; value64u = DLT_ENDIAN_GET_64(msg->standardheader->htyp, value64u_tmp); #if defined (__WIN32__) && !defined(_MSC_VER) snprintf(text + strlen(text), textlength - strlen(text), "%I64u", value64u); #else snprintf(text + strlen(text), textlength - strlen(text), "%" PRId64, value64u); #endif } break; } case DLT_TYLE_128BIT: { if (*datalength >= 16) dlt_print_hex_string(text + strlen(text), textlength, *ptr, 16); if ((*datalength) < 16) return DLT_RETURN_ERROR; *ptr += 16; *datalength -= 16; break; } default: { return DLT_RETURN_ERROR; } } } else if (type_info & DLT_TYPE_INFO_FLOA) { /* float data argument */ if (type_info & DLT_TYPE_INFO_VARI) { DLT_MSG_READ_VALUE(length2_tmp, *ptr, *datalength, uint16_t); if ((*datalength) < 0) return DLT_RETURN_ERROR; length2 = DLT_ENDIAN_GET_16(msg->standardheader->htyp, length2_tmp); DLT_MSG_READ_VALUE(length3_tmp, *ptr, *datalength, uint16_t); if ((*datalength) < 0) return DLT_RETURN_ERROR; length3 = DLT_ENDIAN_GET_16(msg->standardheader->htyp, length3_tmp); if ((*datalength) < length2) return DLT_RETURN_ERROR; *ptr += length2; *datalength -= length2; if ((*datalength) < length3) return DLT_RETURN_ERROR; *ptr += length3; *datalength -= length3; } switch (type_info & DLT_TYPE_INFO_TYLE) { case DLT_TYLE_8BIT: { if (*datalength >= 1) dlt_print_hex_string(text + strlen(text), textlength, *ptr, 1); if ((*datalength) < 1) return DLT_RETURN_ERROR; *ptr += 1; *datalength -= 1; break; } case DLT_TYLE_16BIT: { if (*datalength >= 2) dlt_print_hex_string(text + strlen(text), textlength, *ptr, 2); if ((*datalength) < 2) return DLT_RETURN_ERROR; *ptr += 2; *datalength -= 2; break; } case DLT_TYLE_32BIT: { if (sizeof(float32_t) == 4) { value32f = 0; value32f_tmp = 0; value32f_tmp_int32i = 0; value32f_tmp_int32i_swaped = 0; DLT_MSG_READ_VALUE(value32f_tmp, *ptr, *datalength, float32_t); if ((*datalength) < 0) return DLT_RETURN_ERROR; memcpy(&value32f_tmp_int32i, &value32f_tmp, sizeof(float32_t)); value32f_tmp_int32i_swaped = DLT_ENDIAN_GET_32(msg->standardheader->htyp, (uint32_t)value32f_tmp_int32i); memcpy(&value32f, &value32f_tmp_int32i_swaped, sizeof(float32_t)); snprintf(text + strlen(text), textlength - strlen(text), "%g", value32f); } else { dlt_log(LOG_ERR, "Invalid size of float32_t\n"); return DLT_RETURN_ERROR; } break; } case DLT_TYLE_64BIT: { if (sizeof(float64_t) == 8) { value64f = 0; value64f_tmp = 0; value64f_tmp_int64i = 0; value64f_tmp_int64i_swaped = 0; DLT_MSG_READ_VALUE(value64f_tmp, *ptr, *datalength, float64_t); if ((*datalength) < 0) return DLT_RETURN_ERROR; memcpy(&value64f_tmp_int64i, &value64f_tmp, sizeof(float64_t)); value64f_tmp_int64i_swaped = DLT_ENDIAN_GET_64(msg->standardheader->htyp, (uint64_t)value64f_tmp_int64i); memcpy(&value64f, &value64f_tmp_int64i_swaped, sizeof(float64_t)); #ifdef __arm__ snprintf(text + strlen(text), textlength - strlen(text), "ILLEGAL"); #else snprintf(text + strlen(text), textlength - strlen(text), "%g", value64f); #endif } else { dlt_log(LOG_ERR, "Invalid size of float64_t\n"); return DLT_RETURN_ERROR; } break; } case DLT_TYLE_128BIT: { if (*datalength >= 16) dlt_print_hex_string(text + strlen(text), textlength, *ptr, 16); if ((*datalength) < 16) return DLT_RETURN_ERROR; *ptr += 16; *datalength -= 16; break; } default: { return DLT_RETURN_ERROR; } } } else if (type_info & DLT_TYPE_INFO_RAWD) { /* raw data argument */ DLT_MSG_READ_VALUE(length_tmp, *ptr, *datalength, uint16_t); if ((*datalength) < 0) return DLT_RETURN_ERROR; length = DLT_ENDIAN_GET_16(msg->standardheader->htyp, length_tmp); if (type_info & DLT_TYPE_INFO_VARI) { DLT_MSG_READ_VALUE(length2_tmp, *ptr, *datalength, uint16_t); if ((*datalength) < 0) return DLT_RETURN_ERROR; length2 = DLT_ENDIAN_GET_16(msg->standardheader->htyp, length2_tmp); if ((*datalength) < length2) return DLT_RETURN_ERROR; *ptr += length2; *datalength -= length2; } if ((*datalength) < length) return DLT_RETURN_ERROR; dlt_print_hex_string(text + strlen(text), textlength, *ptr, length); *ptr += length; *datalength -= length; } else if (type_info & DLT_TYPE_INFO_TRAI) { /* trace info argument */ DLT_MSG_READ_VALUE(length_tmp, *ptr, *datalength, uint16_t); if ((*datalength) < 0) return DLT_RETURN_ERROR; length = DLT_ENDIAN_GET_16(msg->standardheader->htyp, length_tmp); DLT_MSG_READ_STRING((text + strlen(text)), *ptr, *datalength, length); if ((*datalength) < 0) return DLT_RETURN_ERROR; } else { return DLT_RETURN_ERROR; } if (*datalength < 0) { dlt_log(LOG_ERR, "Payload of DLT message corrupted\n"); return DLT_RETURN_ERROR; } return DLT_RETURN_OK; } void dlt_check_envvar() { char *env_log_filename = getenv("DLT_LOG_FILENAME"); if (env_log_filename != NULL) dlt_log_set_filename(env_log_filename); char *env_log_level_str = getenv("DLT_LOG_LEVEL"); if (env_log_level_str != NULL) { int level = 0; if (sscanf(env_log_level_str, "%d", &level)) dlt_log_set_level(level); } char *env_log_mode = getenv("DLT_LOG_MODE"); if (env_log_mode != NULL) { int mode = 0; if (sscanf(env_log_mode, "%d", &mode)) dlt_log_init(mode); } char *env_pipe_dir = getenv("DLT_PIPE_DIR"); if (env_pipe_dir != NULL) dlt_log_set_fifo_basedir(env_pipe_dir); #ifdef DLT_SHM_ENABLE char* env_shm_name = getenv("DLT_SHM_NAME"); if (env_shm_name != NULL) { dlt_log_set_shm_name(env_shm_name); } #endif } int dlt_set_loginfo_parse_service_id(char *resp_text, uint32_t *service_id, uint8_t *service_opt) { int ret = -1; char get_log_info_tag[GET_LOG_INFO_LENGTH]; char service_opt_str[SERVICE_OPT_LENGTH]; if ((resp_text == NULL) || (service_id == NULL) || (service_opt == NULL)) return DLT_RETURN_ERROR; /* ascii type, syntax is 'get_log_info, ..' */ /* check target id */ strncpy(get_log_info_tag, "get_log_info", strlen("get_log_info")); ret = memcmp((void *)resp_text, (void *)get_log_info_tag, sizeof(get_log_info_tag) - 1); if (ret == 0) { *service_id = DLT_SERVICE_ID_GET_LOG_INFO; /* reading the response mode from the resp_text. eg. option 7*/ service_opt_str[0] = *(resp_text + GET_LOG_INFO_LENGTH + 1); service_opt_str[1] = *(resp_text + GET_LOG_INFO_LENGTH + 2); service_opt_str[2] = 0; *service_opt = atoi(service_opt_str); } return ret; } int16_t dlt_getloginfo_conv_ascii_to_uint16_t(char *rp, int *rp_count) { char num_work[5] = { 0 }; char *endptr; if ((rp == NULL) || (rp_count == NULL)) return -1; /* ------------------------------------------------------ * from: [89 13 ] -> to: ['+0x'1389\0] -> to num * ------------------------------------------------------ */ num_work[0] = *(rp + *rp_count + 3); num_work[1] = *(rp + *rp_count + 4); num_work[2] = *(rp + *rp_count + 0); num_work[3] = *(rp + *rp_count + 1); num_work[4] = 0; *rp_count += 6; return (unsigned char)strtol(num_work, &endptr, 16); } int16_t dlt_getloginfo_conv_ascii_to_int16_t(char *rp, int *rp_count) { char num_work[3] = { 0 }; char *endptr; if ((rp == NULL) || (rp_count == NULL)) return -1; /* ------------------------------------------------------ * from: [89 ] -> to: ['0x'89\0] -> to num * ------------------------------------------------------ */ num_work[0] = *(rp + *rp_count + 0); num_work[1] = *(rp + *rp_count + 1); num_work[2] = 0; *rp_count += 3; return (signed char)strtol(num_work, &endptr, 16); } void dlt_getloginfo_conv_ascii_to_id(char *rp, int *rp_count, char *wp, int len) { char number16[3] = {0}; char *endptr; int count; if ((rp == NULL) || (rp_count == NULL) || (wp == NULL)) return; /* ------------------------------------------------------ * from: [72 65 6d 6f ] -> to: [0x72,0x65,0x6d,0x6f,0x00] * ------------------------------------------------------ */ for (count = 0; count < len; count++) { number16[0] = *(rp + *rp_count + 0); number16[1] = *(rp + *rp_count + 1); *(wp + count) = strtol(number16, &endptr, 16); *rp_count += 3; } *(wp + count) = 0; return; } void dlt_hex_ascii_to_binary(const char *ptr, uint8_t *binary, int *size) { char ch = *ptr; int pos = 0; binary[pos] = 0; int first = 1; int found; for (;;) { if (ch == 0) { *size = pos; return; } found = 0; if ((ch >= '0') && (ch <= '9')) { binary[pos] = (binary[pos] << 4) + (ch - '0'); found = 1; } else if ((ch >= 'A') && (ch <= 'F')) { binary[pos] = (binary[pos] << 4) + (ch - 'A' + 10); found = 1; } else if ((ch >= 'a') && (ch <= 'f')) { binary[pos] = (binary[pos] << 4) + (ch - 'a' + 10); found = 1; } if (found) { if (first) { first = 0; } else { first = 1; pos++; if (pos >= *size) return; binary[pos] = 0; } } ch = *(++ptr); } } #ifndef DLT_USE_UNIX_SOCKET_IPC int dlt_mkdir_recursive(const char *dir) { int ret = 0; char tmp[PATH_MAX + 1]; char *p = NULL; char *end = NULL; size_t len; strncpy(tmp, dir, PATH_MAX); len = strlen(tmp); if (tmp[len - 1] == '/') tmp[len - 1] = 0; end = tmp + len; for (p = tmp + 1; ((*p) && (ret == 0)) || ((ret == -1 && errno == EEXIST) && (p != end)); p++) if (*p == '/') { *p = 0; ret = mkdir(tmp, S_IRWXU); *p = '/'; } if ((ret == 0) || ((ret == -1) && (errno == EEXIST))) ret = mkdir(tmp, S_IRWXU); if ((ret == -1) && (errno == EEXIST)) ret = 0; return ret; } #endif dlt-daemon-2.18.4/src/shared/dlt_common_cfg.h000066400000000000000000000115541353342203500210200ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2011-2015, BMW AG * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author Alexander Wenzel * * \copyright Copyright © 2011-2015 BMW AG. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file dlt_common_cfg.h */ /******************************************************************************* ** ** ** SRC-MODULE: dlt_common_cfg.h ** ** ** ** TARGET : linux ** ** ** ** PROJECT : DLT ** ** ** ** AUTHOR : Alexander Wenzel Alexander.AW.Wenzel@bmw.de ** ** Markus Klein ** ** ** ** PURPOSE : ** ** ** ** REMARKS : ** ** ** ** PLATFORM DEPENDANT [yes/no]: yes ** ** ** ** TO BE CHANGED BY USER [yes/no]: no ** ** ** *******************************************************************************/ /******************************************************************************* ** Author Identity ** ******************************************************************************** ** ** ** Initials Name Company ** ** -------- ------------------------- ---------------------------------- ** ** aw Alexander Wenzel BMW ** ** mk Markus Klein Fraunhofer ESK ** *******************************************************************************/ /******************************************************************************* ** Author Identity ** ******************************************************************************** ** ** ** Initials Name Company ** ** -------- ------------------------- ---------------------------------- ** ** aw Alexander Wenzel BMW ** ** mk Markus Klein Fraunhofer ESK ** *******************************************************************************/ #ifndef DLT_COMMON_CFG_H #define DLT_COMMON_CFG_H /*************/ /* Changable */ /*************/ /* Buffer length for temporary buffer */ #define DLT_COMMON_BUFFER_LENGTH 255 /* Number of ASCII chars to be printed in one line as HEX and as ASCII */ /* e.g. XX XX XX XX ABCD is DLT_COMMON_HEX_CHARS = 4 */ #define DLT_COMMON_HEX_CHARS 16 /* Length of line number */ #define DLT_COMMON_HEX_LINELEN 8 /* Length of one char */ #define DLT_COMMON_CHARLEN 1 /* Number of indices to be allocated at one, if no more indeces are left */ #define DLT_COMMON_INDEX_ALLOC 1000 /* If limited output is called, * this is the maximum number of characters to be printed out */ #define DLT_COMMON_ASCII_LIMIT_MAX_CHARS 20 /* This defines the dummy ECU ID set in storage header during import * of a message from a DLT file in RAW format (without storage header) */ #define DLT_COMMON_DUMMY_ECUID "ECU" /************************/ /* Don't change please! */ /************************/ /* ASCII value for space */ #define DLT_COMMON_ASCII_CHAR_SPACE 32 /* ASCII value for tilde */ #define DLT_COMMON_ASCII_CHAR_TILDE 126 /* ASCII value for lesser than */ #define DLT_COMMON_ASCII_CHAR_LT 60 #endif /* DLT_COMMON_CFG_H */ dlt-daemon-2.18.4/src/shared/dlt_config_file_parser.c000066400000000000000000000336671353342203500225350ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2015, Advanced Driver Information Technology * This code is developed by Advanced Driver Information Technology. * Copyright of Advanced Driver Information Technology, Bosch and DENSO. * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author * Christoph Lipka * * \copyright Copyright © 2015 Advanced Driver Information Technology. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file dlt_config_file_parser.c */ #include "dlt_config_file_parser.h" #include #include #include #include #include #include "dlt_common.h" #include "dlt-daemon_cfg.h" /* internal defines */ #define DLT_CONFIG_FILE_NEW_SECTION 0x0a #define DLT_CONFIG_FILE_NEW_DATA 0x0b /* internal helper functions */ /** * dlt_config_file_trim_line * * Trim all whitespace from a string * * @param line String to remove whitespace from */ static void dlt_config_file_trim_line(char *line) { if (line == NULL) return; char *i = line; char *j = line; while (*j != '\0') { *i = *j++; if (!isspace(*i)) i++; } *i = '\0'; } /** * dlt_config_file_ignore_line * * Check if a line has to be ignored, because it contains a comment or is empty * * @param line Line of configuration file * @return 0 if ignore, -1 do not ignore */ static int dlt_config_file_ignore_line(char *line) { if ((line[0] == '#') || (line[0] == ';') || (line[0] == '\n') || (line[0] == '\0')) return 0; /* ignore */ else return -1; /* do not ignore */ } /** * dlt_config_file_is_section_name * * Check if section name already used * * @param file DltConfigFile * @param name Name of section * @return 0, section name not used, -1 section name already used */ static int dlt_config_file_is_section_name(DltConfigFile *file, char *name) { int i = 0; if ((file == NULL) || (name == NULL)) return -1; for (i = 0; i < file->num_sections; i++) { DltConfigFileSection *s = &file->sections[i]; if (strncmp(s->name, name, DLT_CONFIG_FILE_ENTRY_MAX_LEN) == 0) return -1; } return 0; /* section name not used */ } /** * dlt_config_file_set_section * * Store section in internal data structure * * @param file DltConfigFile * @param name Name of section * @return 0 on success, else -1 */ static int dlt_config_file_set_section(DltConfigFile *file, char *name) { int section = file->num_sections; /* check if adding another section would exceed max number of sections */ if (section + 1 >= DLT_CONFIG_FILE_SECTIONS_MAX) { dlt_log(LOG_WARNING, "Cannot store more sections\n"); return -1; /* reached max number of sections */ } /* do not store section with same name again */ if (dlt_config_file_is_section_name(file, name) != 0) { dlt_log(LOG_WARNING, "Cannot store section name again\n"); return -1; } DltConfigFileSection *s = &file->sections[section]; /* alloc data for entries */ s->name = calloc(sizeof(char), DLT_CONFIG_FILE_ENTRY_MAX_LEN + 1); if (s->name == NULL) { dlt_log(LOG_ERR, "Cannot allocate memory for internal data structure\n"); return -1; } s->keys = calloc(sizeof(char), DLT_CONFIG_FILE_ENTRY_MAX_LEN * DLT_CONFIG_FILE_KEYS_MAX + 1); if (s->keys == NULL) { free(s->name); dlt_log(LOG_ERR, "Cannot allocate memory for internal data structure\n"); return -1; } strncpy(file->sections[section].name, name, DLT_CONFIG_FILE_ENTRY_MAX_LEN); file->num_sections += 1; return 0; } /** * dlt_config_file_set_section_data * * Store data pair of a section * * @param file DltConfigFile * @param str1 string used for key * @param str2 string used for value * @return 0 on success, else -1 */ static int dlt_config_file_set_section_data(DltConfigFile *file, char *str1, char *str2) { DltConfigKeyData **tmp = NULL; if ((file == NULL) || (str1 == NULL) || (str2 == NULL)) return -1; DltConfigFileSection *s = &file->sections[file->num_sections - 1]; int key_number = s->num_entries; if (key_number + 1 >= DLT_CONFIG_FILE_KEYS_MAX) { dlt_log(LOG_WARNING, "Cannot store more keys in section\n"); return -1; /* reached max number of keys per section */ } /* copy data into structure */ strncpy(&s->keys[key_number * DLT_CONFIG_FILE_ENTRY_MAX_LEN], str1, DLT_CONFIG_FILE_ENTRY_MAX_LEN); if (s->list == NULL) { /* creating a list if it doesnt exists */ s->list = malloc(sizeof(DltConfigKeyData)); if (s->list == NULL) { dlt_log(LOG_WARNING, "Could not allocate initial memory to list \n"); return -1; } tmp = &s->list; } else { tmp = &s->list; while (*(tmp) != NULL) tmp = &(*tmp)->next; /* Adding new entry to the list */ *tmp = malloc(sizeof(DltConfigKeyData)); if (*tmp == NULL) { dlt_log(LOG_WARNING, "Could not allocate memory to list \n"); return -1; } } (*tmp)->key = strdup(str1); (*tmp)->data = strdup(str2); (*tmp)->next = NULL; s->num_entries += 1; return 0; } /** * dlt_config_file_has_section * * Check if a certain line in config file is a section header * * @param line Line in configuration file * @return 0 if section header, else -1 */ static int dlt_config_file_line_has_section(char *line) { (void)line; /* avoid compiler warnings */ if (line[0] == '[') /* section found */ return 0; else return -1; } /** * dlt_config_file_get_section_name_from_string * * Extract section name from line * * @param line Line in configuration file containing a section header * @param name Section name * @return 0 on success, else -1 */ static int dlt_config_file_get_section_name_from_string(char *line, char *name) { int i = 0; int j = 0; if ((line == NULL) || (name == NULL)) return -1; for (i = 0; i < DLT_CONFIG_FILE_ENTRY_MAX_LEN; i++) { if ((line[i] == '[') || isspace(line[i])) continue; else if ((line[i] == ']') || (line[i] == '\n') || (line[i] == '\0')) break; else name[j++] = line[i]; } return 0; } /** * dlt_config_file_get_key_value * * Get key and value from a line of configuration file * * @param line Line on configuration file * @param[out] str1 String to be used as key * @param[out] str2 String to be used as value * @return 0 on success, else -1 */ static int dlt_config_file_get_key_value(char *line, char *str1, char *str2) { char *delimiter = "="; char *ptr; char *save_ptr; if ((line == NULL) || (str1 == NULL) || (str2 == NULL)) return -1; ptr = strtok_r(line, delimiter, &save_ptr); if (ptr != NULL) /* get key */ strncpy(str1, ptr, DLT_CONFIG_FILE_ENTRY_MAX_LEN); else return -1; ptr = strtok_r(NULL, delimiter, &save_ptr); if (ptr != NULL) strncpy(str2, ptr, DLT_CONFIG_FILE_ENTRY_MAX_LEN); else return -1; return 0; } /** * dlt_config_file_read_line * * Read line from configuration file * * @param line Line from configuration file * @param[out] str1 String contains section header or key * @param[out] str2 String contains value or is empty * @return 0 on success, else -1 */ static int dlt_config_file_read_line(char *line, char *str1, char *str2) { if ((line == NULL) || (str1 == NULL) || (str2 == NULL)) return -1; /* reset values to zero */ memset(str1, 0, DLT_CONFIG_FILE_ENTRY_MAX_LEN); memset(str2, 0, DLT_CONFIG_FILE_ENTRY_MAX_LEN); /* check if line contains a section */ if ((dlt_config_file_line_has_section(line)) == 0) { /* retrieve section name */ if (dlt_config_file_get_section_name_from_string(line, str1) != 0) return -1; return DLT_CONFIG_FILE_NEW_SECTION; } /* copy strings as key value pair into str1, str2 */ if (dlt_config_file_get_key_value(line, str1, str2) != 0) return -1; return DLT_CONFIG_FILE_NEW_DATA; } /** * dlt_config_file_read_file * * Read configuration file line by line and fill internal structures * * @param file DltConfigFile * @param hdl FILE handle of opened configuration file */ static void dlt_config_file_read_file(DltConfigFile *file, FILE *hdl) { int ret = 0; char line[DLT_CONFIG_FILE_LINE_MAX_LEN] = { '\0' }; char str1[DLT_CONFIG_FILE_ENTRY_MAX_LEN] = { '\0' }; char str2[DLT_CONFIG_FILE_ENTRY_MAX_LEN] = { '\0' }; int line_number = 0; int is_section_valid = -1; /* to check if section name is given twice or invalid */ /* read configuration file line by line */ while (fgets(line, DLT_CONFIG_FILE_LINE_MAX_LEN, hdl) != NULL) { line_number++; /* ignore empty and comment lines */ if (dlt_config_file_ignore_line(line) == 0) continue; /* trim line end */ dlt_config_file_trim_line(line); /* parse content of line */ ret = dlt_config_file_read_line(line, str1, str2); switch (ret) { case DLT_CONFIG_FILE_NEW_SECTION: /* store str1 as new section */ is_section_valid = -1; if ((ret = dlt_config_file_set_section(file, str1)) == 0) is_section_valid = 0; break; case DLT_CONFIG_FILE_NEW_DATA: /* store str1 and str2 as new data for section */ if (is_section_valid == 0) ret = dlt_config_file_set_section_data(file, str1, str2); break; default: /* something is wrong with the line */ dlt_vlog(LOG_WARNING, "Line (%d) \"%s\" is invalid\n", line_number, line); } } } /** * dlt_config_file_find_section * * Find a section * * @param file DltConfigFile * @param section Name of section * @return number of section on success, else -1 */ static int dlt_config_file_find_section(const DltConfigFile *file, const char *section) { int i = 0; if ((file == NULL) || (section == NULL) || (file->num_sections <= 0)) { dlt_log(LOG_WARNING, "Section cannot be found due to invalid parameters\n"); return -1; } for (i = 0; i < file->num_sections; i++) { DltConfigFileSection *s = &file->sections[i]; if (strncmp(s->name, section, DLT_CONFIG_FILE_ENTRY_MAX_LEN) == 0) return i; } return -1; } /************************** interface implementation ***************************/ DltConfigFile *dlt_config_file_init(char *file_name) { DltConfigFile *file; FILE *hdl = NULL; if ((file_name == NULL) || (strlen(file_name) >= DLT_CONFIG_FILE_PATH_MAX_LEN)) { dlt_log(LOG_ERR, "Given configuration file invalid\n"); return NULL; } file = calloc(sizeof(DltConfigFile), 1); if (file == NULL) { dlt_log(LOG_ERR, "Setup internal data structure to parse config file failed\n"); return NULL; } file->sections = calloc(sizeof(DltConfigFileSection), DLT_CONFIG_FILE_SECTIONS_MAX); /* open file */ if ((hdl = fopen(file_name, "r")) == NULL) { dlt_log(LOG_ERR, "Cannot open configuration file\n"); free(file); return NULL; } dlt_config_file_read_file(file, hdl); /* all information stored internally */ fclose(hdl); return file; } void dlt_config_file_release(DltConfigFile *file) { int i = 0; if (file != NULL) { int max = file->num_sections; for (i = 0; i < max; i++) { DltConfigFileSection *s = &file->sections[i]; DltConfigKeyData *node = file->sections[i].list; free(s->name); if (s->keys != NULL) free(s->keys); while (node) { DltConfigKeyData *tmp = node; node = node->next; free(tmp->key); free(tmp->data); free(tmp); } } free(file->sections); free(file); } } int dlt_config_file_get_section_name(const DltConfigFile *file, int num, char *name) { if ((file == NULL) || (name == NULL) || (num < 0) || (num >= file->num_sections)) return -1; strncpy(name, (file->sections + num)->name, DLT_CONFIG_FILE_ENTRY_MAX_LEN); return 0; } int dlt_config_file_get_num_sections(const DltConfigFile *file, int *num) { if ((file == NULL) || (file->num_sections < 0)) return -1; *num = file->num_sections; return 0; } int dlt_config_file_get_value(const DltConfigFile *file, const char *section, const char *key, char *value) { DltConfigFileSection *s = NULL; DltConfigKeyData **tmp = NULL; int num_section = 0; if ((file == NULL) || (section == NULL) || (key == NULL) || (value == NULL)) return -1; /* clean value */ memset(value, 0, DLT_CONFIG_FILE_ENTRY_MAX_LEN); num_section = dlt_config_file_find_section(file, section); if (num_section == -1) return -1; s = (file->sections + num_section); tmp = &s->list; while (*(tmp) != NULL) { if (strncmp((*tmp)->key, key, DLT_CONFIG_FILE_ENTRY_MAX_LEN) == 0) { strncpy(value, (*tmp)->data, DLT_CONFIG_FILE_ENTRY_MAX_LEN); return 0; } else { /* not found yet see list for more */ tmp = &(*tmp)->next; } } dlt_log(LOG_WARNING, "Entry does not exist in section \n"); return -1; } dlt-daemon-2.18.4/src/shared/dlt_config_file_parser.h000066400000000000000000000131201353342203500225200ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2015, Advanced Driver Information Technology * This code is developed by Advanced Driver Information Technology. * Copyright of Advanced Driver Information Technology, Bosch and DENSO. * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author Christoph Lipka * * \copyright Copyright © 2015 Advanced Driver Information Technology. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file dlt_config_file_parser.h */ /******************************************************************************* ** ** ** SRC-MODULE: dlt_config_file_parser.h ** ** ** ** TARGET : linux ** ** ** ** PROJECT : DLT ** ** ** ** AUTHOR : Christoph Lipka clipka@jp.adit-jv.com ** ** ** ** PURPOSE : ** ** ** ** REMARKS : ** ** ** ** PLATFORM DEPENDANT [yes/no]: yes ** ** ** ** TO BE CHANGED BY USER [yes/no]: no ** ** ** *******************************************************************************/ /******************************************************************************* ** Author Identity ** ******************************************************************************** ** ** ** Initials Name Company ** ** -------- ------------------------- ---------------------------------- ** ** cl Christoph Lipka ADIT ** *******************************************************************************/ #ifndef _DLT_CONFIG_FILE_PARSER_H_ #define _DLT_CONFIG_FILE_PARSER_H_ /* definitions */ #define DLT_CONFIG_FILE_PATH_MAX_LEN 100 /* absolute path including filename */ #define DLT_CONFIG_FILE_ENTRY_MAX_LEN 100 /* Entry for section, key and value */ #define DLT_CONFIG_FILE_LINE_MAX_LEN 210 #define DLT_CONFIG_FILE_SECTIONS_MAX 100 #define DLT_CONFIG_FILE_KEYS_MAX 25 /* Maximal keys per section */ typedef struct DltConfigKeyData { char *key; char *data; struct DltConfigKeyData *next; } DltConfigKeyData; /* Config file section structure */ typedef struct { int num_entries; /* number of entries */ char *name; /* name of section */ char *keys; /* keys */ DltConfigKeyData *list; } DltConfigFileSection; typedef struct { int num_sections; /* number of sections */ DltConfigFileSection *sections; /* sections */ } DltConfigFile; /** * dlt_config_file_init * * Load the configuration file and stores all data in * internal data structures. * * @param file_name File to be opened * @return Pointer to DltConfigFile object or NULL on error */ DltConfigFile *dlt_config_file_init(char *file_name); /** * dlt_config_file_release * * Release config file and frees all internal data. Has to be called after * after all data is read. * * @param file DltConfigFile */ void dlt_config_file_release(DltConfigFile *file); /** * dlt_config_file_get_section_name * * Get name of section number. * * @param[in] file DltConfigFile * @param[in] num Number of section * @param[out] name Section name * @return 0 on success, else -1 */ int dlt_config_file_get_section_name(const DltConfigFile *file, int num, char *name); /** * dlt_config_file_get_num_sections * * Get the number of sections inside configuration file * * @param[in] file DltConfigFile * @param[out] num Number of sections inside configuration file * @return 0 on success, else -1 */ int dlt_config_file_get_num_sections(const DltConfigFile *file, int *num); /** * dlt_config_file_get_value * * Get value of key in specified section. * * @param[in] file DltConfigFile * @param[in] section Name of section * @param[in] key Key * @param[out] value Value * @return 0 on success, else -1 */ int dlt_config_file_get_value(const DltConfigFile *file, const char *section, const char *key, char *value); #endif dlt-daemon-2.18.4/src/shared/dlt_offline_trace.c000066400000000000000000000353021353342203500215010ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2011-2015, BMW AG * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author Alexander Wenzel * * \copyright Copyright © 2011-2015 BMW AG. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file dlt_offline_trace.c */ /******************************************************************************* ** ** ** SRC-MODULE: dlt_offline_trace.c ** ** ** ** TARGET : linux ** ** ** ** PROJECT : DLT ** ** ** ** AUTHOR : Alexander Wenzel Alexander.AW.Wenzel@bmw.de ** ** ** ** PURPOSE : ** ** ** ** REMARKS : ** ** ** ** PLATFORM DEPENDANT [yes/no]: yes ** ** ** ** TO BE CHANGED BY USER [yes/no]: no ** ** ** *******************************************************************************/ /******************************************************************************* ** Author Identity ** ******************************************************************************** ** ** ** Initials Name Company ** ** -------- ------------------------- ---------------------------------- ** ** aw Alexander Wenzel BMW ** *******************************************************************************/ #include #include #include #include #include #include #include #include #include #include #include #include "dlt_common.h" unsigned int dlt_offline_trace_storage_dir_info(char *path, char *file_name, char *newest, char *oldest) { int i = 0; unsigned int num = 0; int cnt = 0; struct dirent **files = { 0 }; char *tmp_old = NULL; char *tmp_new = NULL; if ((path == NULL) || (file_name == NULL) || (newest == NULL) || (oldest == NULL)) { printf("dlt_offline_trace_storage_dir_info: Invalid parameter(s)"); return 0; } cnt = scandir(path, &files, NULL, alphasort); if (cnt < 0) return 0; for (i = 0; i < cnt; i++) { int len = 0; len = strlen(file_name); if ((strncmp(files[i]->d_name, file_name, len) == 0) && (files[i]->d_name[len] == '.')) { num++; if ((tmp_old == NULL) || (strlen(tmp_old) >= strlen(files[i]->d_name))) { if (tmp_old == NULL) tmp_old = files[i]->d_name; /* when file name is smaller, it is older */ else if (strlen(tmp_old) > strlen(files[i]->d_name)) tmp_old = files[i]->d_name; else /* filename is equal, do a string compare */ if (strcmp(tmp_old, files[i]->d_name) > 0) tmp_old = files[i]->d_name; } if ((tmp_new == NULL) || (strlen(tmp_new) <= strlen(files[i]->d_name))) { if (tmp_new == NULL) { tmp_new = files[i]->d_name; } /* when file name is longer, it is younger */ else if (strlen(tmp_new) < strlen(files[i]->d_name)) { tmp_new = files[i]->d_name; } else if (strcmp(tmp_new, files[i]->d_name) < 0) tmp_new = files[i]->d_name; } } } if (num > 0) { if (tmp_old != NULL) { if (strlen(tmp_old) < DLT_OFFLINETRACE_FILENAME_MAX_SIZE) strncpy(oldest, tmp_old, DLT_OFFLINETRACE_FILENAME_MAX_SIZE); } if (tmp_new != NULL) { if (strlen(tmp_old) < DLT_OFFLINETRACE_FILENAME_MAX_SIZE) strncpy(newest, tmp_new, DLT_OFFLINETRACE_FILENAME_MAX_SIZE); } } /* free scandir result */ for (i = 0; i < cnt; i++) free(files[i]); free(files); return num; } void dlt_offline_trace_file_name(char *log_file_name, char *name, unsigned int idx) { char file_index[11]; /* UINT_MAX = 4294967295 -> 10 digits */ snprintf(file_index, sizeof(file_index), "%010u", idx); /* create log file name */ memset(log_file_name, 0, DLT_OFFLINETRACE_FILENAME_MAX_SIZE * sizeof(char)); strncat(log_file_name, name, sizeof(log_file_name) - strlen(log_file_name) - 1); strncat(log_file_name, DLT_OFFLINETRACE_FILENAME_DELI, sizeof(log_file_name) - strlen(log_file_name) - 1); strncat(log_file_name, file_index, sizeof(log_file_name) - strlen(log_file_name) - 1); strncat(log_file_name, DLT_OFFLINETRACE_FILENAME_EXT, sizeof(log_file_name) - strlen(log_file_name) - 1); } unsigned int dlt_offline_trace_get_idx_of_log_file(char *file) { const char d[2] = "."; char *token; unsigned int idx = 0; if (file[0] == '\0') return 0; token = strtok(file, d); /* we are interested in 2. token because of log file name */ token = strtok(NULL, d); if (token != NULL) idx = strtol(token, NULL, 10); else idx = 0; return idx; } DltReturnValue dlt_offline_trace_create_new_file(DltOfflineTrace *trace) { time_t t; struct tm tmp; char outstr[200]; char newest[DLT_OFFLINETRACE_FILENAME_MAX_SIZE] = { 0 }; char oldest[DLT_OFFLINETRACE_FILENAME_MAX_SIZE] = { 0 }; unsigned int idx = 0; /* set filename */ if (trace->filenameTimestampBased) { int ret = 0; t = time(NULL); localtime_r(&t, &tmp); strftime(outstr, sizeof(outstr), "%Y%m%d_%H%M%S", &tmp); ret = snprintf(trace->filename, NAME_MAX, "%s/dlt_offlinetrace_%s.dlt", trace->directory, outstr); if ((ret < 0) || (ret >= NAME_MAX)) { printf("dlt_offlinetrace filename cannot be concatenated\n"); return DLT_RETURN_ERROR; } } else { int ret = 0; /* targeting newest file, ignoring number of files in dir returned */ dlt_offline_trace_storage_dir_info(trace->directory, DLT_OFFLINETRACE_FILENAME_BASE, newest, oldest); idx = dlt_offline_trace_get_idx_of_log_file(newest) + 1; dlt_offline_trace_file_name(outstr, DLT_OFFLINETRACE_FILENAME_BASE, idx); ret = snprintf(trace->filename, NAME_MAX, "%s/%s", trace->directory, outstr); if ((ret < 0) || (ret >= NAME_MAX)) { printf("filename cannot be concatenated\n"); return DLT_RETURN_ERROR; } } /* open DLT output file */ trace->ohandle = open(trace->filename, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); /* mode: wb */ if (trace->ohandle == -1) { /* trace file cannot be opened */ printf("Offline trace file %s cannot be created\n", trace->filename); return DLT_RETURN_ERROR; } /* if */ return DLT_RETURN_OK; /* OK */ } unsigned long dlt_offline_trace_get_total_size(DltOfflineTrace *trace) { struct dirent *dp; char filename[256]; unsigned long size = 0; struct stat status; /* go through all dlt files in directory */ DIR *dir = opendir(trace->directory); while ((dp = readdir(dir)) != NULL) if (strstr(dp->d_name, DLT_OFFLINETRACE_FILENAME_BASE)) { int res = snprintf(filename, sizeof(filename), "%s/%s", trace->directory, dp->d_name); /* if the total length of the string is greater than the buffer, silently forget it. */ /* snprintf: a return value of size or more means that the output was truncated */ /* if an output error is encountered, a negative value is returned. */ if (((unsigned int)res < sizeof(filename)) && (res > 0)) { if (0 == stat(filename, &status)) size += status.st_size; else printf("Offline trace file %s cannot be stat-ed", filename); } /*else */ /*{ */ /* dlt_log(3, "dlt_offline_trace_get_total_size: long filename ignored"); */ /*} */ } closedir(dir); /* return size */ return size; } int dlt_offline_trace_delete_oldest_file(DltOfflineTrace *trace) { struct dirent *dp; char filename[PATH_MAX + 1]; char filename_oldest[PATH_MAX + 1]; unsigned long size_oldest = 0; struct stat status; time_t time_oldest = 0; filename[0] = 0; filename_oldest[0] = 0; /* go through all dlt files in directory */ DIR *dir = opendir(trace->directory); while ((dp = readdir(dir)) != NULL) if (strstr(dp->d_name, DLT_OFFLINETRACE_FILENAME_TO_COMPARE)) { int res = snprintf(filename, sizeof(filename), "%s/%s", trace->directory, dp->d_name); /* if the total length of the string is greater than the buffer, silently forget it. */ /* snprintf: a return value of size or more means that the output was truncated */ /* if an output error is encountered, a negative value is returned. */ if (((unsigned int)res < sizeof(filename)) && (res > 0)) { if (0 == stat(filename, &status)) { if ((time_oldest == 0) || (status.st_mtime < time_oldest)) { time_oldest = status.st_mtime; size_oldest = status.st_size; strncpy(filename_oldest, filename, PATH_MAX); filename_oldest[PATH_MAX] = 0; } } else { printf("Old offline trace file %s cannot be stat-ed", filename); } } } closedir(dir); /* delete file */ if (filename_oldest[0]) { if (remove(filename_oldest)) { printf("Remove file %s failed!\n", filename_oldest); return -1; /* ERROR */ } } else { printf("No file to be removed!\n"); return -1; /* ERROR */ } /* return size of deleted file*/ return size_oldest; } DltReturnValue dlt_offline_trace_check_size(DltOfflineTrace *trace) { struct stat status; /* check for existence of offline trace directory */ if (stat(trace->directory, &status) == -1) { dlt_vlog(LOG_ERR, "Offline trace directory: %s doesn't exist \n", trace->directory); return DLT_RETURN_ERROR; } /* check for accesibilty of offline trace directory */ else if (access(trace->directory, W_OK) != 0) { dlt_vlog(LOG_ERR, "Offline trace directory: %s doesn't have the write access \n", trace->directory); return DLT_RETURN_ERROR; } /* check size of complete offline trace */ while ((int)dlt_offline_trace_get_total_size(trace) > (trace->maxSize - trace->fileSize)) /* remove oldest files as long as new file will not fit in completely into complete offline trace */ if (dlt_offline_trace_delete_oldest_file(trace) < 0) return DLT_RETURN_ERROR; return DLT_RETURN_OK; /* OK */ } DltReturnValue dlt_offline_trace_init(DltOfflineTrace *trace, const char *directory, int fileSize, int maxSize, int filenameTimestampBased) { /* init parameters */ strncpy(trace->directory, directory, NAME_MAX); trace->directory[NAME_MAX] = 0; trace->fileSize = fileSize; trace->maxSize = maxSize; trace->filenameTimestampBased = filenameTimestampBased; /* check complete offlien trace size, remove old logs if needed */ dlt_offline_trace_check_size(trace); return dlt_offline_trace_create_new_file(trace); } DltReturnValue dlt_offline_trace_write(DltOfflineTrace *trace, unsigned char *data1, int size1, unsigned char *data2, int size2, unsigned char *data3, int size3) { if (trace->ohandle <= 0) return DLT_RETURN_ERROR; /* check file size here */ if ((lseek(trace->ohandle, 0, SEEK_CUR) + size1 + size2 + size3) >= trace->fileSize) { /* close old file */ close(trace->ohandle); trace->ohandle = -1; /* check complete offline trace size, remove old logs if needed */ dlt_offline_trace_check_size(trace); /* create new file */ dlt_offline_trace_create_new_file(trace); } /* write data into log file */ if (data1 && (trace->ohandle >= 0)) { if (write(trace->ohandle, data1, size1) != size1) { printf("Offline trace write failed!\n"); return DLT_RETURN_ERROR; } } if (data2 && (trace->ohandle >= 0)) { if (write(trace->ohandle, data2, size2) != size2) { printf("Offline trace write failed!\n"); return DLT_RETURN_ERROR; } } if (data3 && (trace->ohandle >= 0)) { if (write(trace->ohandle, data3, size3) != size3) { printf("Offline trace write failed!\n"); return DLT_RETURN_ERROR; } } return DLT_RETURN_OK; /* OK */ } DltReturnValue dlt_offline_trace_free(DltOfflineTrace *trace) { if (trace->ohandle <= 0) return DLT_RETURN_ERROR; /* close last used log file */ close(trace->ohandle); return DLT_RETURN_OK; /* OK */ } dlt-daemon-2.18.4/src/shared/dlt_protocol.c000066400000000000000000000055471353342203500205520ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2016 Advanced Driver Information Technology. * This code is developed by Advanced Driver Information Technology. * Copyright of Advanced Driver Information Technology, Bosch and DENSO. * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author * Christoph Lipka * * \copyright Copyright © 2016 Advanced Driver Information Technology. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file dlt_protocol.c */ #include "dlt_protocol.h" const char *const dlt_service_names[] = { "DLT_SERVICE_ID", "DLT_SERVICE_ID_SET_LOG_LEVEL", "DLT_SERVICE_ID_SET_TRACE_STATUS", "DLT_SERVICE_ID_GET_LOG_INFO", "DLT_SERVICE_ID_GET_DEFAULT_LOG_LEVEL", "DLT_SERVICE_ID_STORE_CONFIG", "DLT_SERVICE_ID_RESET_TO_FACTORY_DEFAULT", "DLT_SERVICE_ID_SET_COM_INTERFACE_STATUS", "DLT_SERVICE_ID_SET_COM_INTERFACE_MAX_BANDWIDTH", "DLT_SERVICE_ID_SET_VERBOSE_MODE", "DLT_SERVICE_ID_SET_MESSAGE_FILTERING", "DLT_SERVICE_ID_SET_TIMING_PACKETS", "DLT_SERVICE_ID_GET_LOCAL_TIME", "DLT_SERVICE_ID_USE_ECU_ID", "DLT_SERVICE_ID_USE_SESSION_ID", "DLT_SERVICE_ID_USE_TIMESTAMP", "DLT_SERVICE_ID_USE_EXTENDED_HEADER", "DLT_SERVICE_ID_SET_DEFAULT_LOG_LEVEL", "DLT_SERVICE_ID_SET_DEFAULT_TRACE_STATUS", "DLT_SERVICE_ID_GET_SOFTWARE_VERSION", "DLT_SERVICE_ID_MESSAGE_BUFFER_OVERFLOW" }; const char *const dlt_user_service_names[] = { "DLT_USER_SERVICE_ID", "DLT_SERVICE_ID_UNREGISTER_CONTEXT", "DLT_SERVICE_ID_CONNECTION_INFO", "DLT_SERVICE_ID_TIMEZONE", "DLT_SERVICE_ID_MARKER", "DLT_SERVICE_ID_OFFLINE_LOGSTORAGE", "DLT_SERVICE_ID_PASSIVE_NODE_CONNECT", "DLT_SERVICE_ID_PASSIVE_NODE_CONNECTION_STATUS", "DLT_SERVICE_ID_SET_ALL_LOG_LEVEL", "DLT_SERVICE_ID_SET_ALL_TRACE_STATUS", "DLT_SERVICE_ID_UNDEFINED", /* 0xF0A is not defined */ "DLT_SERVICE_ID_RESERVED", "DLT_SERVICE_ID_RESERVED", "DLT_SERVICE_ID_RESERVED", "DLT_SERVICE_ID_RESERVED" }; const char *dlt_get_service_name(unsigned int id) { if (id == DLT_SERVICE_ID_CALLSW_CINJECTION) return "DLT_SERVICE_ID_CALLSW_CINJECTION"; else if ((id == DLT_SERVICE_ID) || (id >= DLT_USER_SERVICE_ID_LAST_ENTRY) || ((id >= DLT_SERVICE_ID_LAST_ENTRY) && (id <= DLT_USER_SERVICE_ID))) return "UNDEFINED"; else if ((id > DLT_SERVICE_ID) && (id < DLT_SERVICE_ID_LAST_ENTRY)) return dlt_service_names[id]; else /* user services */ return dlt_user_service_names[id & 0xFF]; } dlt-daemon-2.18.4/src/shared/dlt_shm.c000066400000000000000000000325021353342203500174670ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2011-2015, BMW AG * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author Alexander Wenzel * * \copyright Copyright © 2011-2015 BMW AG. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file dlt_shm.c */ /******************************************************************************* ** ** ** SRC-MODULE: dlt_shm.c ** ** ** ** TARGET : linux ** ** ** ** PROJECT : DLT ** ** ** ** AUTHOR : Alexander Wenzel Alexander.AW.Wenzel@bmw.de ** ** ** ** PURPOSE : ** ** ** ** REMARKS : ** ** ** ** PLATFORM DEPENDANT [yes/no]: yes ** ** ** ** TO BE CHANGED BY USER [yes/no]: no ** ** ** *******************************************************************************/ /******************************************************************************* ** Author Identity ** ******************************************************************************** ** ** ** Initials Name Company ** ** -------- ------------------------- ---------------------------------- ** ** aw Alexander Wenzel BMW ** *******************************************************************************/ #include #include #include #include #include #include #include #if !defined(_MSC_VER) #include #include #endif #include #include void dlt_shm_print_hex(char *ptr, int size) { int num; for (num = 0; num < size; num++) { if ((num % 16) == 15) printf("%.2x\n", ((unsigned char *)ptr)[num]); else printf("%.2x ", ((unsigned char *)ptr)[num]); } printf("\n"); } DltReturnValue dlt_shm_init_server(DltShm *buf, const char *name, int size) { unsigned char *ptr; /* Check if buffer and name available */ if (buf == NULL || name == NULL) { dlt_vlog(LOG_ERR, "%s: Wrong parameter: Null pointer\n", __func__); return DLT_RETURN_WRONG_PARAMETER; } /* Init parameters */ buf->shmfd = 0; buf->sem = NULL; /** * Create the shared memory segment. * @name Name of the new shared memory object. * (shm_open will create a file under /dev/shm/) * @oflag O_CREAT | O_EXCL | O_RDWR * O_CREAT | O_EXCL: The shm_open() fails if the shared memory exists. * O_RDWR: Open the object for read-write access. * @mode 0666 * The shared memory object's permission. */ buf->shmfd = shm_open(name, O_CREAT | O_EXCL | O_RDWR, 0666); if (buf->shmfd == -1) { dlt_vlog(LOG_ERR, "%s: shm_open() failed: %s\n", __func__, strerror(errno)); return DLT_RETURN_ERROR; /* ERROR */ } /* Set the size of shm */ if (ftruncate(buf->shmfd, size) == -1) { dlt_vlog(LOG_ERR, "%s: ftruncate() failed: %s\n", __func__, strerror(errno)); return DLT_RETURN_ERROR; /* ERROR */ } /* Now we attach the segment to our data space. */ ptr = (unsigned char *)mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, buf->shmfd, 0); if (ptr == MAP_FAILED) { dlt_vlog(LOG_ERR, "%s: mmap() failed: %s\n", __func__, strerror(errno)); return DLT_RETURN_ERROR; /* ERROR */ } /** * Create the semaphore with input name * @name name * Name of the new semaphore * (sem_open will create a file under /dev/shm/sem.) * @oflag O_CREAT | O_EXCEL * The sem_open() fails if the semaphore name exists. * @mode 0777 * The permissions to be placed on the new semaphore. * @value 1 * Initial value for the new semaphore. */ buf->sem = sem_open(name, O_CREAT | O_EXCL, 0666, 1); if (buf->sem == SEM_FAILED) { dlt_vlog(LOG_ERR, "%s: sem_open() failed: %s\n", __func__, strerror(errno)); return DLT_RETURN_ERROR; /* ERROR */ } /* Init buffer */ dlt_buffer_init_static_server(&(buf->buffer), ptr, size); /* The 'buf->shmfd' is no longer needed */ if (close(buf->shmfd) == -1) { dlt_vlog(LOG_ERR, "%s: Failed to close shared memory" " file descriptor: %s\n", __func__, strerror(errno)); return DLT_RETURN_ERROR; /* ERROR */ } return DLT_RETURN_OK; /* OK */ } DltReturnValue dlt_shm_init_client(DltShm *buf, const char *name) { struct stat shm_buf; unsigned char *ptr; /* Check if buffer and name available */ if (buf == NULL || name == NULL) { dlt_vlog(LOG_ERR, "%s: Wrong parameter: Null pointer\n", __func__); return DLT_RETURN_WRONG_PARAMETER; } /* Init parameters */ buf->shmfd = 0; buf->sem = NULL; /** * Open the existing shared memory segment created by the server. * @name Name of the existing shared memory object. * (shm_open will open the file under /dev/shm/) * @oflag O_RDWR * Open the object for read-write access. * @mode 0 * We are not creating a new object, this argument should be specified as 0. */ buf->shmfd = shm_open(name, O_RDWR, 0); if (buf->shmfd == -1) { dlt_vlog(LOG_ERR, "%s: shm_open() failed: %s\n", __func__, strerror(errno)); return DLT_RETURN_ERROR; /* ERROR */ } /* Get the size of shm */ if (fstat(buf->shmfd, &shm_buf) == -1) { dlt_vlog(LOG_ERR, "%s: fstat() failed: %s\n", __func__, strerror(errno)); return DLT_RETURN_ERROR; /* ERROR */ } /* Now we attach the segment to our data space. */ ptr = (unsigned char *)mmap(NULL, shm_buf.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, buf->shmfd, 0); if (ptr == MAP_FAILED) { dlt_vlog(LOG_ERR, "%s: mmap() failed: %s\n", __func__, strerror(errno)); return DLT_RETURN_ERROR; /* ERROR */ } /** * Open the existing semaphore with name created by the server * The call requires only two arguments. * @name name * Name of the existing semaphore * (sem_open will open a file under /dev/shm/sem.) * @oflag 0 * We are accessing an existing semaphore, oflag should be specified as 0. */ buf->sem = sem_open(name, 0); if (buf->sem == SEM_FAILED) { dlt_vlog(LOG_ERR, "%s: sem_open() failed: %s\n", __func__, strerror(errno)); return DLT_RETURN_ERROR; /* ERROR */ } /* Init buffer */ dlt_buffer_init_static_client(&(buf->buffer), ptr, shm_buf.st_size); /* The 'buf->shmfd' is no longer needed */ if (close(buf->shmfd) == -1) { dlt_vlog(LOG_ERR, "%s: Failed to close shared memory" " file descriptor: %s\n", __func__, strerror(errno)); return DLT_RETURN_ERROR; /* ERROR */ } return DLT_RETURN_OK; /* OK */ } void dlt_shm_info(DltShm *buf) { /* Check if buffer available */ if (buf == NULL) { dlt_vlog(LOG_ERR, "%s: Wrong parameter: Null pointer\n", __func__); return; } dlt_buffer_info(&(buf->buffer)); } void dlt_shm_status(DltShm *buf) { /* Check if buffer available */ if (buf == NULL) { dlt_vlog(LOG_ERR, "%s: Wrong parameter: Null pointer\n", __func__); return; } dlt_buffer_status(&(buf->buffer)); } int dlt_shm_get_total_size(DltShm *buf) { /* Check if buffer available */ if (buf == NULL) { dlt_vlog(LOG_ERR, "%s: Wrong parameter: Null pointer\n", __func__); return -1; } return dlt_buffer_get_total_size(&(buf->buffer)); } int dlt_shm_get_used_size(DltShm *buf) { int ret; /* Check if buffer available */ if ((buf == NULL) || (buf->buffer.mem == NULL)) { dlt_vlog(LOG_ERR, "%s: Wrong parameter: Null pointer\n", __func__); return -1; } DLT_SHM_SEM_GET(buf->sem); ret = dlt_buffer_get_used_size(&(buf->buffer)); DLT_SHM_SEM_FREE(buf->sem); return ret; } int dlt_shm_get_message_count(DltShm *buf) { /* Check if buffer available */ if (buf == NULL) { dlt_vlog(LOG_ERR, "%s: Wrong parameter: Null pointer\n", __func__); return -1; } return dlt_buffer_get_message_count(&(buf->buffer)); } int dlt_shm_push(DltShm *buf, const unsigned char *data1, unsigned int size1, const unsigned char *data2, unsigned int size2, const unsigned char *data3, unsigned int size3) { int ret; /* Check if buffer available */ if ((buf == NULL) || (buf->buffer.mem == NULL)) { dlt_vlog(LOG_ERR, "%s: Wrong parameter: Null pointer\n", __func__); return -1; } DLT_SHM_SEM_GET(buf->sem); ret = dlt_buffer_push3(&(buf->buffer), data1, size1, data2, size2, data3, size3); DLT_SHM_SEM_FREE(buf->sem); return ret; } int dlt_shm_pull(DltShm *buf, unsigned char *data, int max_size) { int ret; /* Check if buffer available */ if ((buf == NULL) || (buf->buffer.mem == NULL)) { dlt_vlog(LOG_ERR, "%s: Wrong parameter: Null pointer\n", __func__); return -1; } DLT_SHM_SEM_GET(buf->sem); ret = dlt_buffer_pull(&(buf->buffer), data, max_size); DLT_SHM_SEM_FREE(buf->sem); return ret; } int dlt_shm_copy(DltShm *buf, unsigned char *data, int max_size) { int ret; /* Check if buffer available */ if ((buf == NULL) || (buf->buffer.mem == NULL)) { dlt_vlog(LOG_ERR, "%s: Wrong parameter: Null pointer\n", __func__); return -1; } DLT_SHM_SEM_GET(buf->sem); ret = dlt_buffer_copy(&(buf->buffer), data, max_size); DLT_SHM_SEM_FREE(buf->sem); return ret; } int dlt_shm_remove(DltShm *buf) { int ret; /* Check if buffer available */ if ((buf == NULL) || (buf->buffer.mem == NULL)) { dlt_vlog(LOG_ERR, "%s: Wrong parameter: Null pointer\n", __func__); return -1; } DLT_SHM_SEM_GET(buf->sem); ret = dlt_buffer_remove(&(buf->buffer)); DLT_SHM_SEM_FREE(buf->sem); return ret; } DltReturnValue dlt_shm_free_server(DltShm *buf, const char *name) { if ((buf == NULL) || (buf->buffer.shm == NULL) || name == NULL) { dlt_vlog(LOG_ERR, "%s: Wrong parameter: Null pointer\n", __func__); return DLT_RETURN_WRONG_PARAMETER; } if (munmap(buf->buffer.shm, buf->buffer.min_size) == -1) { dlt_vlog(LOG_ERR, "%s: munmap() failed: %s\n", __func__, strerror(errno)); } if (shm_unlink(name) == -1) { dlt_vlog(LOG_ERR, "%s: shm_unlink() failed: %s\n", __func__, strerror(errno)); } if (sem_close(buf->sem) == -1) { dlt_vlog(LOG_ERR, "%s: sem_close() failed: %s\n", __func__, strerror(errno)); } if (sem_unlink(name) == -1) { dlt_vlog(LOG_ERR, "%s: sem_unlink() failed: %s\n", __func__, strerror(errno)); } /* Reset parameters */ buf->shmfd = 0; buf->sem = NULL; return dlt_buffer_free_static(&(buf->buffer)); } DltReturnValue dlt_shm_free_client(DltShm *buf) { if ((buf == NULL) || (buf->buffer.shm == NULL)) { dlt_vlog(LOG_ERR, "%s: Wrong parameter: Null pointer\n", __func__); return DLT_RETURN_WRONG_PARAMETER; } if (munmap(buf->buffer.shm, buf->buffer.min_size) == -1) { dlt_vlog(LOG_ERR, "%s: munmap() failed: %s\n", __func__, strerror(errno)); } if (sem_close(buf->sem) == -1) { dlt_vlog(LOG_ERR, "%s: sem_close() failed: %s\n", __func__, strerror(errno)); } /* Reset parameters */ buf->shmfd = 0; buf->sem = NULL; return dlt_buffer_free_static(&(buf->buffer)); } dlt-daemon-2.18.4/src/shared/dlt_user_shared.c000066400000000000000000000133711353342203500212070ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2011-2015, BMW AG * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author Alexander Wenzel * * \copyright Copyright © 2011-2015 BMW AG. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file dlt_user_shared.c */ /******************************************************************************* ** ** ** SRC-MODULE: dlt_user_shared.c ** ** ** ** TARGET : linux ** ** ** ** PROJECT : DLT ** ** ** ** AUTHOR : Alexander Wenzel Alexander.AW.Wenzel@bmw.de ** ** Markus Klein ** ** ** ** PURPOSE : ** ** ** ** REMARKS : ** ** ** ** PLATFORM DEPENDANT [yes/no]: yes ** ** ** ** TO BE CHANGED BY USER [yes/no]: no ** ** ** *******************************************************************************/ /******************************************************************************* ** Author Identity ** ******************************************************************************** ** ** ** Initials Name Company ** ** -------- ------------------------- ---------------------------------- ** ** aw Alexander Wenzel BMW ** ** mk Markus Klein Fraunhofer ESK ** *******************************************************************************/ /******************************************************************************* ** Revision Control History ** *******************************************************************************/ /* * $LastChangedRevision: 1670 $ * $LastChangedDate: 2011-04-08 15:12:06 +0200 (Fr, 08. Apr 2011) $ * $LastChangedBy$ * Initials Date Comment * aw 13.01.2010 initial */ #include #include #include #include /* writev() */ #include "dlt_user_shared.h" #include "dlt_user_shared_cfg.h" DltReturnValue dlt_user_set_userheader(DltUserHeader *userheader, uint32_t mtype) { if (userheader == 0) return DLT_RETURN_ERROR; if (mtype <= 0) return DLT_RETURN_ERROR; userheader->pattern[0] = 'D'; userheader->pattern[1] = 'U'; userheader->pattern[2] = 'H'; userheader->pattern[3] = 1; userheader->message = mtype; return DLT_RETURN_OK; } int dlt_user_check_userheader(DltUserHeader *userheader) { if (userheader == 0) return -1; return (userheader->pattern[0] == 'D') && (userheader->pattern[1] == 'U') && (userheader->pattern[2] == 'H') && (userheader->pattern[3] == 1); } DltReturnValue dlt_user_log_out2(int handle, void *ptr1, size_t len1, void *ptr2, size_t len2) { struct iovec iov[2]; uint32_t bytes_written; if (handle <= 0) /* Invalid handle */ return DLT_RETURN_ERROR; iov[0].iov_base = ptr1; iov[0].iov_len = len1; iov[1].iov_base = ptr2; iov[1].iov_len = len2; bytes_written = writev(handle, iov, 2); if (bytes_written != (len1 + len2)) return DLT_RETURN_ERROR; return DLT_RETURN_OK; } DltReturnValue dlt_user_log_out3(int handle, void *ptr1, size_t len1, void *ptr2, size_t len2, void *ptr3, size_t len3) { struct iovec iov[3]; uint32_t bytes_written; if (handle <= 0) /* Invalid handle */ return DLT_RETURN_ERROR; iov[0].iov_base = ptr1; iov[0].iov_len = len1; iov[1].iov_base = ptr2; iov[1].iov_len = len2; iov[2].iov_base = ptr3; iov[2].iov_len = len3; bytes_written = writev(handle, iov, 3); if (bytes_written != (len1 + len2 + len3)) { switch (errno) { case EBADF: { return DLT_RETURN_PIPE_ERROR; /* EBADF - handle not open */ break; } case EPIPE: { return DLT_RETURN_PIPE_ERROR; /* EPIPE - pipe error */ break; } case EAGAIN: { return DLT_RETURN_PIPE_FULL; /* EAGAIN - data could not be written */ break; } default: { break; } } return DLT_RETURN_ERROR; } return DLT_RETURN_OK; } dlt-daemon-2.18.4/src/shared/dlt_user_shared.h000066400000000000000000000234131353342203500212120ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2011-2015, BMW AG * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author Alexander Wenzel * * \copyright Copyright © 2011-2015 BMW AG. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file dlt_user_shared.h */ /******************************************************************************* ** ** ** SRC-MODULE: dlt_user_shared.h ** ** ** ** TARGET : linux ** ** ** ** PROJECT : DLT ** ** ** ** AUTHOR : Alexander Wenzel Alexander.AW.Wenzel@bmw.de ** ** Markus Klein ** ** ** ** PURPOSE : ** ** ** ** REMARKS : ** ** ** ** PLATFORM DEPENDANT [yes/no]: yes ** ** ** ** TO BE CHANGED BY USER [yes/no]: no ** ** ** *******************************************************************************/ /******************************************************************************* ** Author Identity ** ******************************************************************************** ** ** ** Initials Name Company ** ** -------- ------------------------- ---------------------------------- ** ** aw Alexander Wenzel BMW ** ** mk Markus Klein Fraunhofer ESK ** *******************************************************************************/ /******************************************************************************* ** Author Identity ** ******************************************************************************** ** ** ** Initials Name Company ** ** -------- ------------------------- ---------------------------------- ** ** aw Alexander Wenzel BMW ** ** mk Markus Klein Fraunhofer ESK ** *******************************************************************************/ #ifndef DLT_USER_SHARED_H #define DLT_USER_SHARED_H #include "dlt_types.h" #include "dlt_user.h" #include /** * This is the header of each message to be exchanged between application and daemon. */ typedef struct { char pattern[DLT_ID_SIZE]; /**< This pattern should be DUH0x01 */ uint32_t message; /**< messsage info */ } PACKED DltUserHeader; /** * This is the internal message content to exchange control msg register app information between application and daemon. */ typedef struct { char apid[DLT_ID_SIZE]; /**< application id */ pid_t pid; /**< process id of user application */ uint32_t description_length; /**< length of description */ } PACKED DltUserControlMsgRegisterApplication; /** * This is the internal message content to exchange control msg unregister app information between application and daemon. */ typedef struct { char apid[DLT_ID_SIZE]; /**< application id */ pid_t pid; /**< process id of user application */ } PACKED DltUserControlMsgUnregisterApplication; /** * This is the internal message content to exchange control msg register information between application and daemon. */ typedef struct { char apid[DLT_ID_SIZE]; /**< application id */ char ctid[DLT_ID_SIZE]; /**< context id */ int32_t log_level_pos; /**< offset in management structure on user-application side */ int8_t log_level; /**< log level */ int8_t trace_status; /**< trace status */ pid_t pid; /**< process id of user application */ uint32_t description_length; /**< length of description */ } PACKED DltUserControlMsgRegisterContext; /** * This is the internal message content to exchange control msg unregister information between application and daemon. */ typedef struct { char apid[DLT_ID_SIZE]; /**< application id */ char ctid[DLT_ID_SIZE]; /**< context id */ pid_t pid; /**< process id of user application */ } PACKED DltUserControlMsgUnregisterContext; /** * This is the internal message content to exchange control msg log level information between application and daemon. */ typedef struct { uint8_t log_level; /**< log level */ uint8_t trace_status; /**< trace status */ int32_t log_level_pos; /**< offset in management structure on user-application side */ } PACKED DltUserControlMsgLogLevel; /** * This is the internal message content to exchange control msg injection information between application and daemon. */ typedef struct { int32_t log_level_pos; /**< offset in management structure on user-application side */ uint32_t service_id; /**< service id of injection */ uint32_t data_length_inject; /**< length of injection message data field */ } PACKED DltUserControlMsgInjection; /** * This is the internal message content to exchange information about application log level and trace stats between * application and daemon. */ typedef struct { char apid[DLT_ID_SIZE]; /**< application id */ uint8_t log_level; /**< log level */ uint8_t trace_status; /**< trace status */ } PACKED DltUserControlMsgAppLogLevelTraceStatus; /** * This is the internal message content to set the logging mode: off, external, internal, both. */ typedef struct { int8_t log_mode; /**< the mode to be used for logging: off, external, internal, both */ } PACKED DltUserControlMsgLogMode; /** * This is the internal message content to get the logging state: 0 = off, 1 = external client connected. */ typedef struct { int8_t log_state; /**< the state to be used for logging state: 0 = off, 1 = external client connected */ } PACKED DltUserControlMsgLogState; /** * This is the internal message content to get the number of lost messages reported to the daemon. */ typedef struct { uint32_t overflow_counter; /**< counts the number of lost messages */ char apid[4]; /**< application which lost messages */ } PACKED DltUserControlMsgBufferOverflow; /************************************************************************************************** * The folowing functions are used shared between the user lib and the daemon implementation **************************************************************************************************/ /** * Set user header marker and store message type in user header * @param userheader pointer to the userheader * @param mtype user message type of internal message * @return Value from DltReturnValue enum */ DltReturnValue dlt_user_set_userheader(DltUserHeader *userheader, uint32_t mtype); /** * Check if user header contains its marker * @param userheader pointer to the userheader * @return 0 no, 1 yes, negative value if there was an error */ int dlt_user_check_userheader(DltUserHeader *userheader); /** * Atomic write to file descriptor, using vector of 2 elements * @param handle file descriptor * @param ptr1 generic pointer to first segment of data to be written * @param len1 length of first segment of data to be written * @param ptr2 generic pointer to second segment of data to be written * @param len2 length of second segment of data to be written * @return Value from DltReturnValue enum */ DltReturnValue dlt_user_log_out2(int handle, void *ptr1, size_t len1, void *ptr2, size_t len2); /** * Atomic write to file descriptor, using vector of 3 elements * @param handle file descriptor * @param ptr1 generic pointer to first segment of data to be written * @param len1 length of first segment of data to be written * @param ptr2 generic pointer to second segment of data to be written * @param len2 length of second segment of data to be written * @param ptr3 generic pointer to third segment of data to be written * @param len3 length of third segment of data to be written * @return Value from DltReturnValue enum */ DltReturnValue dlt_user_log_out3(int handle, void *ptr1, size_t len1, void *ptr2, size_t len2, void *ptr3, size_t len3); #endif /* DLT_USER_SHARED_H */ dlt-daemon-2.18.4/src/shared/dlt_user_shared_cfg.h000066400000000000000000000113241353342203500220270ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2011-2015, BMW AG * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author Alexander Wenzel * * \copyright Copyright © 2011-2015 BMW AG. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file dlt_user_shared_cfg.h */ /******************************************************************************* ** ** ** SRC-MODULE: dlt_user_shared_cfg.h ** ** ** ** TARGET : linux ** ** ** ** PROJECT : DLT ** ** ** ** AUTHOR : Alexander Wenzel Alexander.AW.Wenzel@bmw.de ** ** Markus Klein ** ** ** ** PURPOSE : ** ** ** ** REMARKS : ** ** ** ** PLATFORM DEPENDANT [yes/no]: yes ** ** ** ** TO BE CHANGED BY USER [yes/no]: no ** ** ** *******************************************************************************/ /******************************************************************************* ** Author Identity ** ******************************************************************************** ** ** ** Initials Name Company ** ** -------- ------------------------- ---------------------------------- ** ** aw Alexander Wenzel BMW ** ** mk Markus Klein Fraunhofer ESK ** *******************************************************************************/ /******************************************************************************* ** Author Identity ** ******************************************************************************** ** ** ** Initials Name Company ** ** -------- ------------------------- ---------------------------------- ** ** aw Alexander Wenzel BMW ** ** mk Markus Klein Fraunhofer ESK ** *******************************************************************************/ #ifndef DLT_USER_SHARED_CFG_H #define DLT_USER_SHARED_CFG_H /*************/ /* Changable */ /*************/ /************************/ /* Don't change please! */ /************************/ /* The different types of internal messages between user application and daemon. */ #define DLT_USER_MESSAGE_LOG 1 #define DLT_USER_MESSAGE_REGISTER_APPLICATION 2 #define DLT_USER_MESSAGE_UNREGISTER_APPLICATION 3 #define DLT_USER_MESSAGE_REGISTER_CONTEXT 4 #define DLT_USER_MESSAGE_UNREGISTER_CONTEXT 5 #define DLT_USER_MESSAGE_LOG_LEVEL 6 #define DLT_USER_MESSAGE_INJECTION 7 #define DLT_USER_MESSAGE_OVERFLOW 8 #define DLT_USER_MESSAGE_APP_LL_TS 9 #define DLT_USER_MESSAGE_LOG_SHM 10 #define DLT_USER_MESSAGE_LOG_MODE 11 #define DLT_USER_MESSAGE_LOG_STATE 12 #define DLT_USER_MESSAGE_MARKER 13 #define DLT_USER_MESSAGE_NOT_SUPPORTED 16 /* Internal defined values */ /* must be different from DltLogLevelType */ #define DLT_USER_LOG_LEVEL_NOT_SET -2 /* must be different from DltTraceStatusType */ #define DLT_USER_TRACE_STATUS_NOT_SET -2 #endif /* DLT_USER_SHARED_CFG_H */ dlt-daemon-2.18.4/src/system/000077500000000000000000000000001353342203500157455ustar00rootroot00000000000000dlt-daemon-2.18.4/src/system/CMakeLists.txt000066400000000000000000000030021353342203500205000ustar00rootroot00000000000000####### # SPDX license identifier: MPL-2.0 # # Copyright (C) 2011-2015, BMW AG # # This file is part of GENIVI Project DLT - Diagnostic Log and Trace. # # This Source Code Form is subject to the terms of the # Mozilla Public License (MPL), v. 2.0. # If a copy of the MPL was not distributed with this file, # You can obtain one at http://mozilla.org/MPL/2.0/. # # For further information see http://www.genivi.org/. ####### if(WITH_SYSTEMD_WATCHDOG OR WITH_SYSTEMD OR WITH_SYSTEMD_JOURNAL) message( STATUS "Added ${systemd_SRCS} to dlt-system") endif(WITH_SYSTEMD_WATCHDOG OR WITH_SYSTEMD OR WITH_SYSTEMD_JOURNAL) set(dlt_system_SRCS dlt-system.c dlt-system-options.c dlt-system-process-handling.c dlt-system-filetransfer.c dlt-system-logfile.c dlt-system-processes.c dlt-system-shell.c dlt-system-syslog.c dlt-system-watchdog.c dlt-system-journal.c) add_executable(dlt-system ${dlt_system_SRCS} ${systemd_SRCS}) if(WITH_SYSTEMD_JOURNAL) if(SYSTEMD_VERSION LESS 209) target_link_libraries(dlt-system dlt ${ZLIB_LIBRARIES} systemd-journal systemd-id128) else(SYSTEMD_VERSION LESS 209) target_link_libraries(dlt-system dlt ${ZLIB_LIBRARIES} systemd) endif(SYSTEMD_VERSION LESS 209) else(WITH_SYSTEMD_JOURNAL) target_link_libraries(dlt-system dlt ${ZLIB_LIBRARIES}) endif(WITH_SYSTEMD_JOURNAL) set_target_properties(dlt-system PROPERTIES LINKER_LANGUAGE C) install(TARGETS dlt-system RUNTIME DESTINATION bin COMPONENT base) INSTALL(FILES dlt-system.conf DESTINATION ${CONFIGURATION_FILES_DIR} COMPONENT base) dlt-daemon-2.18.4/src/system/dlt-system-filetransfer.c000066400000000000000000000624311353342203500227060ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2011-2015, BMW AG * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author * Lassi Marttala * Alexander Wenzel * Markus Klein * Mikko Rapeli * * \copyright Copyright © 2011-2015 BMW AG. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file dlt-system-filetransfer.c */ /******************************************************************************* ** ** ** SRC-MODULE: dlt-system-filetransfer.c ** ** ** ** TARGET : linux ** ** ** ** PROJECT : DLT ** ** ** ** AUTHOR : Lassi Marttala ** ** Alexander Wenzel Alexander.AW.Wenzel@bmw.de ** ** ** ** PURPOSE : ** ** ** ** REMARKS : ** ** ** ** PLATFORM DEPENDANT [yes/no]: yes ** ** ** ** TO BE CHANGED BY USER [yes/no]: no ** ** ** *******************************************************************************/ #include #include #ifdef linux # include #endif #include #include #include #include #include #include #include #include "dlt-system.h" #include "dlt.h" #include "dlt_filetransfer.h" #ifdef linux # define INOTIFY_SZ (sizeof(struct inotify_event)) # define INOTIFY_LEN (INOTIFY_SZ + NAME_MAX + 1) #endif #define Z_CHUNK_SZ 1024 * 128 #define COMPRESS_EXTENSION ".gz" #define SUBDIR_COMPRESS ".tocompress" #define SUBDIR_TOSEND ".tosend" extern DltSystemThreads threads; /* From dlt_filetransfer */ extern uint32_t getFileSerialNumber(const char *file, int *ok); DLT_IMPORT_CONTEXT(dltsystem) DLT_DECLARE_CONTEXT(filetransferContext) #ifdef linux typedef struct { int handle; int fd[DLT_SYSTEM_LOG_DIRS_MAX]; } s_ft_inotify; s_ft_inotify ino; #endif char *origin_name(char *src) { if (strlen((char *)basename(src)) > 10) { return (char *)(basename(src) + 10); } else { DLT_LOG(dltsystem, DLT_LOG_ERROR, DLT_STRING("dlt-system-filetransfer, error in recreating origin name!")); return NULL; } } char *unique_name(char *src) { DLT_LOG(dltsystem, DLT_LOG_DEBUG, DLT_STRING("dlt-system-filetransfer, creating unique temporary file name.")); time_t t = time(NULL); int ok; uint32_t l = getFileSerialNumber(src, &ok) ^ t; if (!ok) return (char *)NULL; char *basename_f = basename(src); /* Length of ULONG_MAX + 1 */ int len = 11 + strlen(basename_f); if (len > NAME_MAX) { DLT_LOG(dltsystem, DLT_LOG_WARN, DLT_STRING("dlt-system-filetransfer, unique name creation needs to shorten the filename:"), DLT_STRING(basename_f)); len = NAME_MAX; } char *ret = malloc(len); MALLOC_ASSERT(ret); snprintf(ret, len, "%010" PRIu32 "%s", l, basename_f); return ret; } /** * Function which only calls the relevant part to transfer the payload */ void send_dumped_file(FiletransferOptions const *opts, char *dst_tosend) { /* check if a client is connected to the deamon. If not, try again in a second */ while (dlt_get_log_state() != 1) sleep(1); char *fn = origin_name(dst_tosend); DLT_LOG(dltsystem, DLT_LOG_DEBUG, DLT_STRING("dlt-system-filetransfer, sending dumped file:"), DLT_STRING(fn)); if (dlt_user_log_file_header_alias(&filetransferContext, dst_tosend, fn) == 0) { int pkgcount = dlt_user_log_file_packagesCount(&filetransferContext, dst_tosend); int lastpkg = 0; int success = 1; while (lastpkg < pkgcount) { int total = 2; int used = 2; dlt_user_check_buffer(&total, &used); while ((total - used) < (total / 2)) { struct timespec t; t.tv_sec = 0; t.tv_nsec = 1000000ul * opts->TimeoutBetweenLogs; nanosleep(&t, NULL); dlt_user_log_resend_buffer(); dlt_user_check_buffer(&total, &used); } lastpkg++; if (dlt_user_log_file_data(&filetransferContext, dst_tosend, lastpkg, opts->TimeoutBetweenLogs) < 0) { success = 0; break; } } if (success) dlt_user_log_file_end(&filetransferContext, dst_tosend, 1); } DLT_LOG(dltsystem, DLT_LOG_DEBUG, DLT_STRING("dlt-system-filetransfer, sent dumped file")); } /** * compress file, delete the source file * modification: compress into subdirectory * File whis is compress will be deleted afterwards * @param src File to be sent * @param dst destination where to compress the file * @param level of compression **/ int compress_file_to(char *src, char *dst, int level) { DLT_LOG(dltsystem, DLT_LOG_DEBUG, DLT_STRING("dlt-system-filetransfer, compressing file from:"), DLT_STRING(src), DLT_STRING("to:"), DLT_STRING(dst)); char *buf; char dst_mode[8]; snprintf(dst_mode, 8, "wb%d", level); gzFile dst_file; FILE *src_file; dst_file = gzopen(dst, dst_mode); if (dst_file == Z_NULL) return -1; src_file = fopen(src, "r"); if (src_file == NULL) { gzclose(dst_file); return -1; } buf = malloc(Z_CHUNK_SZ); MALLOC_ASSERT(buf); while (!feof(src_file)) { int read = fread(buf, 1, Z_CHUNK_SZ, src_file); if (ferror(src_file)) { free(buf); gzclose(dst_file); fclose(src_file); return -1; } gzwrite(dst_file, buf, read); } if (remove(src) < 0) DLT_LOG(dltsystem, DLT_LOG_WARN, DLT_STRING("Could not remove file"), DLT_STRING(src)); free(buf); fclose(src_file); gzclose(dst_file); return 0; } /*!Sends one file over DLT. */ /** * If configured in opts, compresses it, then sends it. * uses subdirecties for compressing and before sending, to avoid that those files get changed in the meanwhile * */ int send_one(char *src, FiletransferOptions const *opts, int which) { DLT_LOG(dltsystem, DLT_LOG_DEBUG, DLT_STRING("dlt-system-filetransfer, sending a file.")); sleep(opts->TimeDelay); /* Prepare all needed file names */ char *fn = basename(src); if (fn == NULL) { DLT_LOG(dltsystem, DLT_LOG_ERROR, DLT_STRING("basename not valid")); return -1; } char *fdir = strndup(src, PATH_MAX); MALLOC_ASSERT(fdir); fdir = dirname(fdir);/*dirname overwrites its argument anyway */ char *dst_tosend;/*file which is going to be sent */ char *rn = unique_name(src);/*new unique filename based on inode */ if (rn == NULL) { DLT_LOG(dltsystem, DLT_LOG_ERROR, DLT_STRING("file information not available, may be file got overwritten")); return -1; } /* Compress if needed */ if (opts->Compression[which] > 0) { DLT_LOG(dltsystem, DLT_LOG_DEBUG, DLT_STRING("dlt-system-filetransfer, Moving file to tmp directory for compressing it.")); char *dst_tocompress;/*file which is going to be compressed, the compressed one is named dst_tosend */ int len = strlen(fdir) + strlen(SUBDIR_COMPRESS) + strlen(rn) + 3;/*the filename in .tocompress +2 for 2*"/", +1 for \0 */ dst_tocompress = malloc(len); MALLOC_ASSERT(dst_tocompress); snprintf(dst_tocompress, len, "%s/%s/%s", fdir, SUBDIR_COMPRESS, rn); /*moving in subdir, from where it can be compressed */ if (rename(src, dst_tocompress) < 0) { DLT_LOG(dltsystem, DLT_LOG_ERROR, DLT_STRING("Could not move file"), DLT_STRING(src), DLT_STRING(dst_tocompress)); free(rn); free(dst_tocompress); free(fdir); return -1; } len = strlen(fdir) + strlen(SUBDIR_TOSEND) + strlen(rn) + strlen(COMPRESS_EXTENSION) + 3;/*the resulting filename in .tosend +2 for 2*"/", +1 for \0 */ dst_tosend = malloc(len); MALLOC_ASSERT(dst_tosend); snprintf(dst_tosend, len, "%s/%s/%s%s", fdir, SUBDIR_TOSEND, rn, COMPRESS_EXTENSION); if (compress_file_to(dst_tocompress, dst_tosend, opts->CompressionLevel[which]) != 0) { free(rn); free(dst_tosend); free(dst_tocompress); free(fdir); return -1; } free(dst_tocompress); } else { /*move it directly into "tosend" */ DLT_LOG(dltsystem, DLT_LOG_DEBUG, DLT_STRING("dlt-system-filetransfer, Moving file to tmp directory.")); int len = strlen(fdir) + strlen(SUBDIR_TOSEND) + strlen(rn) + 3; dst_tosend = malloc(len);/*the resulting filename in .tosend +2 for 2*"/", +1 for \0 */ snprintf(dst_tosend, len, "%s/%s/%s", fdir, SUBDIR_TOSEND, rn); DLT_LOG(dltsystem, DLT_LOG_DEBUG, DLT_STRING("dlt-system-filetransfer, Rename:"), DLT_STRING(src), DLT_STRING("to: "), DLT_STRING(dst_tosend)); /*moving in subdir, from where it can be compressed */ if (rename(src, dst_tosend) < 0) { DLT_LOG(dltsystem, DLT_LOG_ERROR, DLT_STRING("Could not move file"), DLT_STRING(src), DLT_STRING(dst_tosend)); free(rn); free(dst_tosend); free(fdir); return -1; } } DLT_LOG(dltsystem, DLT_LOG_DEBUG, DLT_STRING("dlt-system-filetransfer, File ready to send")); send_dumped_file(opts, dst_tosend); free(rn); free(dst_tosend); free(fdir); return 0; } int flush_dir_send(FiletransferOptions const *opts, const char *compress_dir, const char *send_dir) { struct dirent *dp; DIR *dir; dir = opendir(send_dir); if (dir != NULL) { while ((dp = readdir(dir)) != NULL) { if (dp->d_type != DT_REG) continue; char *fn; DLT_LOG(dltsystem, DLT_LOG_DEBUG, DLT_STRING("dlt-system-filetransfer, old compressed file found in send directory:"), DLT_STRING(dp->d_name)); int len = strlen(send_dir) + strlen(dp->d_name) + 2; fn = malloc(len); MALLOC_ASSERT(fn); snprintf(fn, len, "%s/%s", send_dir, dp->d_name); /*if we have a file here and in the to_compress dir, we delete the to_send file: we can not be sure, that it has been properly compressed! */ if (!strncmp(dp->d_name + strlen(dp->d_name) - strlen(COMPRESS_EXTENSION), COMPRESS_EXTENSION, strlen(COMPRESS_EXTENSION))) { /*ends with ".gz" */ /*old file name (not: path) would have been: */ char tmp[strlen(dp->d_name) - strlen(COMPRESS_EXTENSION) + 1]; strncpy(tmp, dp->d_name, strlen(dp->d_name) - strlen(COMPRESS_EXTENSION)); tmp[strlen(dp->d_name) - strlen(COMPRESS_EXTENSION)] = '\0'; int len = strlen(tmp) + strlen(compress_dir) + 1 + 1;/*2 sizes + 1*"/" + \0 */ char *path_uncompressed = malloc(len); MALLOC_ASSERT(path_uncompressed); snprintf(path_uncompressed, len, "%s/%s", compress_dir, tmp); struct stat sb; if (stat(path_uncompressed, &sb) == -1) { /*uncompressed equivalent does not exist. We can send it out. */ DLT_LOG(dltsystem, DLT_LOG_DEBUG, DLT_STRING("dlt-system-filetransfer, sending file.")); send_dumped_file(opts, fn); } else { /*There is an uncompressed file. Compression seems to have been interrupted -> delete the compressed file instead of sending it! */ DLT_LOG(dltsystem, DLT_LOG_DEBUG, DLT_STRING( "dlt-system-filetransfer, uncompressed version exists. Deleting partially compressed version.")); if (sb.st_mode & S_IFREG) { if (remove(fn) != 0) /*"Error deleting file". Continue? If we would cancel, maybe the dump is never sent! Deletion would again be tried in next LC. */ DLT_LOG(dltsystem, DLT_LOG_ERROR, DLT_STRING("Error deleting file:"), DLT_STRING(fn)); } else { /*"Oldfile is a not reg file. Is this possible? Can we compress a directory?: %s\n",path_uncompressed); */ DLT_LOG(dltsystem, DLT_LOG_DEBUG, DLT_STRING( "dlt-system-filetransfer, Oldfile is a not regular file! Do we have a problem?"), DLT_STRING(fn)); } } free(path_uncompressed);/*it is no more used. It would be transferred in next step. */ }/*it is a .gz file */ else { /*uncompressed file. We can just resend it, the action to put it here was a move action. */ DLT_LOG(dltsystem, DLT_LOG_DEBUG, DLT_STRING("dlt-system-filetransfer, Sending uncompressed file from previous LC."), DLT_STRING(fn)); send_dumped_file(opts, fn); } free(fn); } } else { DLT_LOG(dltsystem, DLT_LOG_ERROR, DLT_STRING("Could not open directory"), DLT_STRING(send_dir)); return -1; } closedir(dir);/*end: send_dir */ return 0; } int flush_dir_compress(FiletransferOptions const *opts, int which, const char *compress_dir, const char *send_dir) { /*check for files in compress_dir. Assumption: a file which lies here, should have been compressed, but that action was interrupted. */ /*As it can arrive here only by a rename, it is most likely to be a complete file */ struct dirent *dp; DIR *dir; dir = opendir(compress_dir); if (dir != NULL) { while ((dp = readdir(dir)) != NULL) { if (dp->d_type != DT_REG) continue; DLT_LOG(dltsystem, DLT_LOG_DEBUG, DLT_STRING("dlt-system-filetransfer, old file found in compress-directory.")); /*compress file into to_send dir */ int len = strlen(compress_dir) + strlen(dp->d_name) + 2; char *cd_filename = malloc(len); MALLOC_ASSERT(cd_filename); snprintf(cd_filename, len, "%s/%s", compress_dir, dp->d_name); len = strlen(send_dir) + strlen(dp->d_name) + strlen(COMPRESS_EXTENSION) + 2; char *dst_tosend = malloc(len);/*the resulting filename in .tosend +2 for 1*"/", +1 for \0 + .gz */ MALLOC_ASSERT(dst_tosend); snprintf(dst_tosend, len, "%s/%s%s", send_dir, dp->d_name, COMPRESS_EXTENSION); if (compress_file_to(cd_filename, dst_tosend, opts->CompressionLevel[which]) != 0) { free(dst_tosend); free(cd_filename); closedir(dir); return -1; } /*send file */ send_dumped_file(opts, dst_tosend); free(dst_tosend); free(cd_filename); } } else { DLT_LOG(dltsystem, DLT_LOG_ERROR, DLT_STRING("Could not open directory"), DLT_STRING(compress_dir)); return -1; } closedir(dir);/*end: compress_dir */ return 0; } int flush_dir_original(FiletransferOptions const *opts, int which) { struct dirent *dp; DIR *dir; const char *sdir = opts->Directory[which]; dir = opendir(sdir); if (dir != NULL) { while ((dp = readdir(dir)) != NULL) { if (dp->d_type != DT_REG) /*we don't send directories */ continue; DLT_LOG(dltsystem, DLT_LOG_DEBUG, DLT_STRING("dlt-system-filetransfer, old file found in directory.")); int len = strlen(sdir) + strlen(dp->d_name) + 2; char *fn = malloc(len); MALLOC_ASSERT(fn); snprintf(fn, len, "%s/%s", sdir, dp->d_name); if (send_one(fn, opts, which) < 0) { closedir(dir); free(fn); return -1; } free(fn); } } else { DLT_LOG(dltsystem, DLT_LOG_ERROR, DLT_STRING("Could not open directory"), DLT_STRING(sdir)); return -1; } closedir(dir); return 0; } /*!Cleans the surveyed directories and subdirectories. Sends residing files into trace */ /** * @param opts FiletransferOptions * @param which which directory is affected -> position in list of opts->Directory * @return Returns 0 if everything was okay. If there was a failure a value < 0 will be returned. */ int flush_dir(FiletransferOptions const *opts, int which) { DLT_LOG(dltsystem, DLT_LOG_DEBUG, DLT_STRING("dlt-system-filetransfer, flush directory of old files.")); char *compress_dir; char *send_dir; int len = strlen(opts->Directory[which]) + strlen(SUBDIR_COMPRESS) + 2; compress_dir = malloc (len); MALLOC_ASSERT(compress_dir); snprintf(compress_dir, len, "%s/%s", opts->Directory[which], SUBDIR_COMPRESS); len = strlen(opts->Directory[which]) + strlen(SUBDIR_TOSEND) + 2; send_dir = malloc (len); MALLOC_ASSERT(send_dir); snprintf(send_dir, len, "%s/%s", opts->Directory[which], SUBDIR_TOSEND); /*1st: scan the tosend directory. */ if (0 != flush_dir_send(opts, compress_dir, send_dir)) { free(send_dir); free(compress_dir); return -1; } /*1nd: scan the tocompress directory. */ if (0 != flush_dir_compress(opts, which, compress_dir, send_dir)) { free(send_dir); free(compress_dir); return -1; } free(send_dir);/*no more used */ free(compress_dir); /*last step: scan the original directory - we can reuse the send_one function */ if (0 != flush_dir_original(opts, which)) return -1; return 0; } /*!Initializes the surveyed directories */ /**On startup, the inotifiy handlers are created, and existing files shall be sent into DLT stream * @param opts FiletransferOptions * @return Returns 0 if everything was okay. If there was a failure a value < 0 will be returned. */ int init_filetransfer_dirs(FiletransferOptions const *opts) { DLT_LOG(dltsystem, DLT_LOG_DEBUG, DLT_STRING("dlt-system-filetransfer, initializing inotify on directories.")); int i; #ifdef linux ino.handle = inotify_init(); if (ino.handle < 0) { DLT_LOG(filetransferContext, DLT_LOG_FATAL, DLT_STRING("Failed to initialize inotify in dlt-system file transfer.")); return -1; } #endif for (i = 0; i < opts->Count; i++) { /*create subdirectories for processing the files */ char *subdirpath; int len = strlen(opts->Directory[i]) + strlen(SUBDIR_COMPRESS) + 2; subdirpath = malloc (len); MALLOC_ASSERT(subdirpath); snprintf(subdirpath, len, "%s/%s", opts->Directory[i], SUBDIR_COMPRESS); int ret = mkdir(subdirpath, 0777); if ((0 != ret) && (EEXIST != errno)) { DLT_LOG(dltsystem, DLT_LOG_ERROR, DLT_STRING("dlt-system-filetransfer, error creating subdirectory: "), DLT_STRING(subdirpath), DLT_STRING(" Errorcode: "), DLT_INT(errno)); free (subdirpath); return -1; } free(subdirpath); len = strlen(opts->Directory[i]) + strlen(SUBDIR_TOSEND) + 2; subdirpath = malloc (len); MALLOC_ASSERT(subdirpath); snprintf(subdirpath, len, "%s/%s", opts->Directory[i], SUBDIR_TOSEND); ret = mkdir(subdirpath, 0777); if ((0 != ret) && (EEXIST != errno)) { DLT_LOG(dltsystem, DLT_LOG_ERROR, DLT_STRING("dlt-system-filetransfer, error creating subdirectory: "), DLT_STRING(subdirpath), DLT_STRING(" Errorcode: "), DLT_INT(errno)); free (subdirpath); return -1; } free(subdirpath); #ifdef linux ino.fd[i] = inotify_add_watch(ino.handle, opts->Directory[i], IN_CLOSE_WRITE | IN_MOVED_TO); if (ino.fd[i] < 0) { char buf[1024]; snprintf(buf, 1024, "Failed to add inotify watch to directory %s in dlt-system file transfer.", opts->Directory[i]); DLT_LOG(filetransferContext, DLT_LOG_FATAL, DLT_STRING(buf)); return -1; } #endif flush_dir(opts, i); } return 0; } int wait_for_files(FiletransferOptions const *opts) { #ifdef linux DLT_LOG(dltsystem, DLT_LOG_DEBUG, DLT_STRING("dlt-system-filetransfer, waiting for files.")); static char buf[INOTIFY_LEN]; ssize_t len = read(ino.handle, buf, INOTIFY_LEN); if (len < 0) { DLT_LOG(filetransferContext, DLT_LOG_ERROR, DLT_STRING("Error while waiting for files in dlt-system file transfer.")); return -1; } unsigned int i = 0; while (i < (len - INOTIFY_SZ)) { struct inotify_event *ie = (struct inotify_event *)&buf[i]; if (ie->len > 0) { if ((ie->mask & IN_CLOSE_WRITE) || (ie->mask & IN_MOVED_TO)) { int j; for (j = 0; j < opts->Count; j++) if (ie->wd == ino.fd[j]) { DLT_LOG(dltsystem, DLT_LOG_DEBUG, DLT_STRING("dlt-system-filetransfer, found new file."), DLT_STRING(ie->name)); int length = strlen(opts->Directory[j]) + ie->len + 1; if (length > PATH_MAX) { DLT_LOG(filetransferContext, DLT_LOG_ERROR, DLT_STRING( "dlt-system-filetransfer: Very long path for file transfer. Cancelling transfer! Length is: "), DLT_INT(length)); return -1; } char *tosend = malloc(length); snprintf(tosend, length, "%s/%s", opts->Directory[j], ie->name); send_one(tosend, opts, j); free(tosend); } } } i += INOTIFY_SZ + ie->len; } #endif return 0; } void filetransfer_thread(void *v_conf) { DLT_LOG(dltsystem, DLT_LOG_DEBUG, DLT_STRING("dlt-system-filetransfer, in thread.")); DltSystemConfiguration *conf = (DltSystemConfiguration *)v_conf; DLT_REGISTER_CONTEXT(filetransferContext, conf->Filetransfer.ContextId, "File transfer manager."); sleep(conf->Filetransfer.TimeStartup); if (init_filetransfer_dirs(&(conf->Filetransfer)) < 0) return; while (!threads.shutdown) { if (wait_for_files(&(conf->Filetransfer)) < 0) { DLT_LOG(dltsystem, DLT_LOG_ERROR, DLT_STRING("Error while waiting files. File transfer shutdown.")); return; } sleep(conf->Filetransfer.TimeDelay); } } void start_filetransfer(DltSystemConfiguration *conf) { DLT_LOG(dltsystem, DLT_LOG_DEBUG, DLT_STRING("dlt-system-filetransfer, start.")); static pthread_attr_t t_attr; static pthread_t pt; pthread_create(&pt, &t_attr, (void *)filetransfer_thread, conf); threads.threads[threads.count++] = pt; } dlt-daemon-2.18.4/src/system/dlt-system-journal.c000066400000000000000000000325541353342203500216770ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2011-2015, BMW AG * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author Alexander Wenzel * * \copyright Copyright © 2011-2015 BMW AG. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file dlt-system-journal.c */ /******************************************************************************* ** ** ** SRC-MODULE: dlt-system-journal.c ** ** ** ** TARGET : linux ** ** ** ** PROJECT : DLT ** ** ** ** AUTHOR : Alexander Wenzel Alexander.AW.Wenzel@bmw.de ** ** ** ** PURPOSE : ** ** ** ** REMARKS : ** ** ** ** PLATFORM DEPENDANT [yes/no]: yes ** ** ** ** TO BE CHANGED BY USER [yes/no]: no ** ** ** *******************************************************************************/ #if defined(DLT_SYSTEMD_JOURNAL_ENABLE) #include #include #include #include #include #include #include "dlt-system.h" #include #include #include /* for PRI formatting macro */ extern DltSystemThreads threads; #define DLT_SYSTEM_JOURNAL_BUFFER_SIZE 256 #define DLT_SYSTEM_JOURNAL_BUFFER_SIZE_BIG 2048 #define DLT_SYSTEM_JOURNAL_ASCII_FIRST_VISIBLE_CHARACTER 31 #define DLT_SYSTEM_JOURNAL_BOOT_ID_MAX_LENGTH 9 + 32 + 1 typedef struct { char real[DLT_SYSTEM_JOURNAL_BUFFER_SIZE]; char monotonic[DLT_SYSTEM_JOURNAL_BUFFER_SIZE]; } MessageTimestamp; DLT_IMPORT_CONTEXT(dltsystem) DLT_DECLARE_CONTEXT(journalContext) int journal_checkUserBufferForFreeSpace() { int total_size, used_size; dlt_user_check_buffer(&total_size, &used_size); if ((total_size - used_size) < (total_size / 2)) return -1; return 1; } int dlt_system_journal_get(sd_journal *j, char *target, const char *field, size_t max_size) { char *data; size_t length; int error_code; size_t field_size; /* pre check parameters */ if ((max_size < 1) || (target == 0) || (field == 0) || (j == 0)) return -1; /* intialise empty target */ target[0] = 0; /* get data from journal */ error_code = sd_journal_get_data(j, field, (const void **)&data, &length); /* check if an error */ if (error_code) return error_code; /* calculate field size */ field_size = strlen(field) + 1; /*check length */ if (length < field_size) return -1; /* copy string */ if (max_size <= (length - field_size)) { /* truncate */ strncpy(target, data + field_size, max_size - 1); target[max_size - 1] = 0; } else { /* full copy */ strncpy(target, data + field_size, length - field_size); target[length - field_size] = 0; } /* debug messages */ /*printf("%s = %s\n",field,target); */ /* Success */ return 0; } void dlt_system_journal_get_timestamp(sd_journal *journal, MessageTimestamp *timestamp) { int ret = 0; uint64_t time_secs = 0; uint64_t time_usecs = 0; struct tm *timeinfo = NULL; char buffer_realtime[DLT_SYSTEM_JOURNAL_BUFFER_SIZE] = { 0 }; char buffer_realtime_formatted[DLT_SYSTEM_JOURNAL_BUFFER_SIZE] = { 0 }; char buffer_monotime[DLT_SYSTEM_JOURNAL_BUFFER_SIZE] = { 0 }; /* Try to get realtime from message source and if not successful try to get realtime from journal entry */ ret = dlt_system_journal_get(journal, buffer_realtime, "_SOURCE_REALTIME_TIMESTAMP", sizeof(buffer_realtime)); if ((ret == 0) && (strlen(buffer_realtime) > 0)) { errno = 0; time_usecs = strtoull(buffer_realtime, NULL, 10); if (errno != 0) time_usecs = 0; } else if ((ret = sd_journal_get_realtime_usec(journal, &time_usecs)) < 0) { DLT_LOG(dltsystem, DLT_LOG_WARN, DLT_STRING("dlt-system-journal failed to get realtime: "), DLT_STRING(strerror(-ret))); /* just to be sure to have a defined value */ time_usecs = 0; } time_secs = time_usecs / 1000000; localtime_r((const time_t *)(&time_secs), timeinfo); strftime(buffer_realtime_formatted, sizeof(buffer_realtime_formatted), "%Y/%m/%d %H:%M:%S", timeinfo); snprintf(timestamp->real, sizeof(timestamp->real), "%s.%06" PRIu64, buffer_realtime_formatted, time_usecs % 1000000); /* Try to get monotonic time from message source and if not successful try to get monotonic time from journal entry */ ret = dlt_system_journal_get(journal, buffer_monotime, "_SOURCE_MONOTONIC_TIMESTAMP", sizeof(buffer_monotime)); if ((ret == 0) && (strlen(buffer_monotime) > 0)) { errno = 0; time_usecs = strtoull(buffer_monotime, NULL, 10); if (errno != 0) time_usecs = 0; } else if ((ret = sd_journal_get_monotonic_usec(journal, &time_usecs, NULL)) < 0) { DLT_LOG(dltsystem, DLT_LOG_WARN, DLT_STRING("dlt-system-journal failed to get monotonic time: "), DLT_STRING(strerror(-ret))); /* just to be sure to have a defined value */ time_usecs = 0; } snprintf(timestamp->monotonic, sizeof(timestamp->monotonic), "%" PRId64 ".%06" PRIu64, time_usecs / 1000000, time_usecs % 1000000); } void journal_thread(void *v_conf) { int r; sd_journal *j; char match[DLT_SYSTEM_JOURNAL_BOOT_ID_MAX_LENGTH] = "_BOOT_ID="; sd_id128_t boot_id; char buffer_process[DLT_SYSTEM_JOURNAL_BUFFER_SIZE] = { 0 }, buffer_priority[DLT_SYSTEM_JOURNAL_BUFFER_SIZE] = { 0 }, buffer_pid[DLT_SYSTEM_JOURNAL_BUFFER_SIZE] = { 0 }, buffer_comm[DLT_SYSTEM_JOURNAL_BUFFER_SIZE] = { 0 }, buffer_message[DLT_SYSTEM_JOURNAL_BUFFER_SIZE_BIG] = { 0 }, buffer_transport[DLT_SYSTEM_JOURNAL_BUFFER_SIZE] = { 0 }; MessageTimestamp timestamp; int loglevel, systemd_loglevel; char *systemd_log_levels[] = { "Emergency", "Alert", "Critical", "Error", "Warning", "Notice", "Informational", "Debug" }; DLT_LOG(dltsystem, DLT_LOG_DEBUG, DLT_STRING("dlt-system-journal, in thread.")); DltSystemConfiguration *conf = (DltSystemConfiguration *)v_conf; DLT_REGISTER_CONTEXT(journalContext, conf->Journal.ContextId, "Journal Adapter"); r = sd_journal_open(&j, SD_JOURNAL_LOCAL_ONLY /*SD_JOURNAL_LOCAL_ONLY|SD_JOURNAL_RUNTIME_ONLY*/); printf("journal open return %d\n", r); if (r < 0) { DLT_LOG(dltsystem, DLT_LOG_ERROR, DLT_STRING("dlt-system-journal, cannot open journal:"), DLT_STRING(strerror(-r))); printf("journal open failed: %s\n", strerror(-r)); return; } if (conf->Journal.CurrentBoot) { /* show only current boot entries */ r = sd_id128_get_boot(&boot_id); if (r < 0) { DLT_LOG(dltsystem, DLT_LOG_ERROR, DLT_STRING("dlt-system-journal failed to get boot id:"), DLT_STRING(strerror(-r))); sd_journal_close(j); return; } sd_id128_to_string(boot_id, match + 9); r = sd_journal_add_match(j, match, strlen(match)); if (r < 0) { DLT_LOG(dltsystem, DLT_LOG_ERROR, DLT_STRING("dlt-system-journal failed to get match:"), DLT_STRING(strerror(-r))); sd_journal_close(j); return; } } if (conf->Journal.Follow) { /* show only last 10 entries and follow */ r = sd_journal_seek_tail(j); if (r < 0) { DLT_LOG(dltsystem, DLT_LOG_ERROR, DLT_STRING("dlt-system-journal failed to seek to tail:"), DLT_STRING(strerror(-r))); sd_journal_close(j); return; } r = sd_journal_previous_skip(j, 10); if (r < 0) { DLT_LOG(dltsystem, DLT_LOG_ERROR, DLT_STRING("dlt-system-journal failed to seek back 10 entries:"), DLT_STRING(strerror(-r))); sd_journal_close(j); return; } } while (!threads.shutdown) { r = sd_journal_next(j); if (r < 0) { DLT_LOG(dltsystem, DLT_LOG_ERROR, DLT_STRING("dlt-system-journal failed to get next entry:"), DLT_STRING(strerror(-r))); sd_journal_close(j); return; } else if (r > 0) { /* get all data from current journal entry */ dlt_system_journal_get_timestamp(j, ×tamp); /* get data from journal entry, empty string if invalid fields */ dlt_system_journal_get(j, buffer_comm, "_COMM", sizeof(buffer_comm)); dlt_system_journal_get(j, buffer_pid, "_PID", sizeof(buffer_pid)); dlt_system_journal_get(j, buffer_priority, "PRIORITY", sizeof(buffer_priority)); dlt_system_journal_get(j, buffer_message, "MESSAGE", sizeof(buffer_message)); dlt_system_journal_get(j, buffer_transport, "_TRANSPORT", sizeof(buffer_transport)); /* prepare process string */ if (strcmp(buffer_transport, "kernel") == 0) snprintf(buffer_process, DLT_SYSTEM_JOURNAL_BUFFER_SIZE, "kernel:"); else snprintf(buffer_process, DLT_SYSTEM_JOURNAL_BUFFER_SIZE, "%s[%s]:", buffer_comm, buffer_pid); /* map log level on demand */ loglevel = DLT_LOG_INFO; systemd_loglevel = atoi(buffer_priority); if (conf->Journal.MapLogLevels) { /* Map log levels from journal to DLT */ switch (systemd_loglevel) { case 0: /* Emergency */ case 1: /* Alert */ case 2: /* Critical */ loglevel = DLT_LOG_FATAL; break; case 3: /* Error */ loglevel = DLT_LOG_ERROR; break; case 4: /* Warning */ loglevel = DLT_LOG_WARN; break; case 5: /* Notice */ case 6: /* Informational */ loglevel = DLT_LOG_INFO; break; case 7: /* Debug */ loglevel = DLT_LOG_DEBUG; break; default: loglevel = DLT_LOG_INFO; break; } } if ((systemd_loglevel >= 0) && (systemd_loglevel <= 7)) snprintf(buffer_priority, DLT_SYSTEM_JOURNAL_BUFFER_SIZE, "%s:", systemd_log_levels[systemd_loglevel]); else snprintf(buffer_priority, DLT_SYSTEM_JOURNAL_BUFFER_SIZE, "prio_unknown:"); /* write log entry */ DLT_LOG(journalContext, loglevel, DLT_STRING(timestamp.real), DLT_STRING(timestamp.monotonic), DLT_STRING(buffer_process), DLT_STRING(buffer_priority), DLT_STRING(buffer_message) ); } else { r = sd_journal_wait(j, 1000000); if (r < 0) { DLT_LOG(dltsystem, DLT_LOG_ERROR, DLT_STRING("dlt-system-journal failed to call sd_journal_get_realtime_usec(): "), DLT_STRING(strerror(-r))); sd_journal_close(j); return; } } if (journal_checkUserBufferForFreeSpace() == -1) { /* buffer is nearly full */ /* wait 500ms for writing next entry */ struct timespec t; t.tv_sec = 0; t.tv_nsec = 1000000ul * 500; nanosleep(&t, NULL); } } sd_journal_close(j); DLT_UNREGISTER_CONTEXT(journalContext); } void start_systemd_journal(DltSystemConfiguration *conf) { DLT_LOG(dltsystem, DLT_LOG_DEBUG, DLT_STRING("dlt-system-journal, start journal")); static pthread_attr_t t_attr; static pthread_t pt; pthread_create(&pt, &t_attr, (void *)journal_thread, conf); threads.threads[threads.count++] = pt; } #endif /* DLT_SYSTEMD_JOURNAL_ENABLE */ dlt-daemon-2.18.4/src/system/dlt-system-logfile.c000066400000000000000000000123601353342203500216370ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2011-2015, BMW AG * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author Lassi Marttala * * \copyright Copyright © 2011-2015 BMW AG. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file dlt-system-logfile.c */ /******************************************************************************* ** ** ** SRC-MODULE: dlt-system-logfile.c ** ** ** ** TARGET : linux ** ** ** ** PROJECT : DLT ** ** ** ** AUTHOR : Lassi Marttala ** ** Alexander Wenzel Alexander.AW.Wenzel@bmw.de ** ** ** ** PURPOSE : ** ** ** ** REMARKS : ** ** ** ** PLATFORM DEPENDANT [yes/no]: yes ** ** ** ** TO BE CHANGED BY USER [yes/no]: no ** ** ** *******************************************************************************/ #include #include #include "dlt-system.h" /* Modes of sending */ #define SEND_MODE_OFF 0 #define SEND_MODE_ONCE 1 #define SEND_MODE_ON 2 DLT_IMPORT_CONTEXT(dltsystem) extern DltSystemThreads threads; DltContext logfileContext[DLT_SYSTEM_LOG_FILE_MAX]; void send_file(LogFileOptions const *fileopt, int n) { DLT_LOG(dltsystem, DLT_LOG_DEBUG, DLT_STRING("dlt-system-logfile, sending file.")); FILE *pFile; DltContext context = logfileContext[n]; char buffer[1024]; int bytes; int seq = 1; pFile = fopen((*fileopt).Filename[n], "r"); if (pFile != NULL) { while (!feof(pFile)) { bytes = fread(buffer, 1, sizeof(buffer) - 1, pFile); if (bytes >= 0) buffer[bytes] = 0; else buffer[0] = 0; if (feof(pFile)) { DLT_LOG(context, DLT_LOG_INFO, DLT_INT(seq * -1), DLT_STRING(buffer)); break; } else { DLT_LOG(context, DLT_LOG_INFO, DLT_INT(seq++), DLT_STRING(buffer)); } } fclose(pFile); } else { DLT_LOG(dltsystem, DLT_LOG_ERROR, DLT_STRING("dlt-system-logfile, failed to open file."), DLT_STRING((*fileopt).Filename[n])); } } void register_contexts(LogFileOptions const *fileopts) { DLT_LOG(dltsystem, DLT_LOG_DEBUG, DLT_STRING("dlt-system-logfile, registering file contexts.")); int i; for (i = 0; i < (*fileopts).Count; i++) DLT_REGISTER_CONTEXT(logfileContext[i], (*fileopts).ContextId[i], (*fileopts).Filename[i]); } void logfile_thread(void *v_conf) { DLT_LOG(dltsystem, DLT_LOG_DEBUG, DLT_STRING("dlt-system-logfile, in thread.")); DltSystemConfiguration *conf = (DltSystemConfiguration *)v_conf; register_contexts(&(conf->LogFile)); int logfile_delays[DLT_SYSTEM_LOG_FILE_MAX]; int i; for (i = 0; i < conf->LogFile.Count; i++) logfile_delays[i] = conf->LogFile.TimeDelay[i]; while (!threads.shutdown) { sleep(1); for (i = 0; i < conf->LogFile.Count; i++) { if (conf->LogFile.Mode[i] == SEND_MODE_OFF) continue; if (logfile_delays[i] <= 0) { send_file(&(conf->LogFile), i); logfile_delays[i] = conf->LogFile.TimeDelay[i]; if (conf->LogFile.Mode[i] == SEND_MODE_ONCE) conf->LogFile.Mode[i] = SEND_MODE_OFF; } else { logfile_delays[i]--; } } } } void start_logfile(DltSystemConfiguration *conf) { DLT_LOG(dltsystem, DLT_LOG_DEBUG, DLT_STRING("dlt-system-logfile, starting.")); DLT_LOG(dltsystem, DLT_LOG_DEBUG, DLT_STRING("Starting thread for logfile")); static pthread_attr_t t_attr; static pthread_t pt; pthread_create(&pt, &t_attr, (void *)logfile_thread, conf); threads.threads[threads.count++] = pt; } dlt-daemon-2.18.4/src/system/dlt-system-options.c000066400000000000000000000405641353342203500217200ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2011-2015, BMW AG * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author Lassi Marttala * * \copyright Copyright © 2011-2015 BMW AG. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file dlt-system-options.c */ /******************************************************************************* ** ** ** SRC-MODULE: dlt-system-options.c ** ** ** ** TARGET : linux ** ** ** ** PROJECT : DLT ** ** ** ** AUTHOR : Lassi Marttala ** ** Alexander Wenzel Alexander.AW.Wenzel@bmw.de ** ** ** ** PURPOSE : ** ** ** ** REMARKS : ** ** ** ** PLATFORM DEPENDANT [yes/no]: yes ** ** ** ** TO BE CHANGED BY USER [yes/no]: no ** ** ** *******************************************************************************/ /******************************************************************************* ** Author Identity ** ******************************************************************************** ** ** ** Initials Name Company ** ** -------- ------------------------- ---------------------------------- ** ** lm Lassi Marttala BMW ** ** aw Alexander Wenzel BMW ** *******************************************************************************/ #include "dlt-system.h" #include #include /** * Print information how to use this program. */ void usage(char *prog_name) { char version[255]; dlt_get_version(version, 255); printf("Usage: %s [options]\n", prog_name); printf("Application to forward syslog messages to DLT, transfer system information, logs and files.\n"); printf("%s\n", version); printf("Options:\n"); printf(" -d Daemonize. Detach from terminal and run in background.\n"); printf(" -c filename Use configuration file. \n"); printf(" Default: %s\n", DEFAULT_CONF_FILE); printf(" -h This help message.\n"); } /** * Initialize command line options with default values. */ void init_cli_options(DltSystemCliOptions *options) { options->ConfigurationFileName = DEFAULT_CONF_FILE; options->Daemonize = 0; } /** * Read command line options and set the values in provided structure */ int read_command_line(DltSystemCliOptions *options, int argc, char *argv[]) { init_cli_options(options); int opt; while ((opt = getopt(argc, argv, "c:hd")) != -1) switch (opt) { case 'd': { options->Daemonize = 1; break; } case 'c': { options->ConfigurationFileName = malloc(strlen(optarg) + 1); MALLOC_ASSERT(options->ConfigurationFileName); strcpy(options->ConfigurationFileName, optarg); /* strcpy unritical here, because size matches exactly the size to be copied */ break; } case 'h': { usage(argv[0]); exit(0); return -1; /*for parasoft */ } default: { fprintf(stderr, "Unknown option '%c'\n", optopt); usage(argv[0]); return -1; } } return 0; } /** * Initialize configuration to default values. */ void init_configuration(DltSystemConfiguration *config) { int i = 0; /* Common */ config->ApplicationId = "SYS"; /* Shell */ config->Shell.Enable = 0; /* Syslog */ config->Syslog.Enable = 0; config->Syslog.ContextId = "SYSL"; config->Syslog.Port = 47111; /* Journal */ config->Journal.Enable = 0; config->Journal.ContextId = "JOUR"; config->Journal.CurrentBoot = 1; config->Journal.Follow = 0; config->Journal.MapLogLevels = 1; /* File transfer */ config->Filetransfer.Enable = 0; config->Filetransfer.ContextId = "FILE"; config->Filetransfer.TimeDelay = 10; config->Filetransfer.TimeStartup = 30; config->Filetransfer.TimeoutBetweenLogs = 10; config->Filetransfer.Count = 0; for (i = 0; i < DLT_SYSTEM_LOG_DIRS_MAX; i++) { config->Filetransfer.Directory[i] = NULL; config->Filetransfer.Compression[i] = 0; config->Filetransfer.CompressionLevel[i] = 5; } /* Log file */ config->LogFile.Enable = 0; config->LogFile.Count = 0; for (i = 0; i < DLT_SYSTEM_LOG_FILE_MAX; i++) { config->LogFile.ContextId[i] = NULL; config->LogFile.Filename[i] = NULL; config->LogFile.Mode[i] = 0; config->LogFile.TimeDelay[i] = 0; } /* Log process */ config->LogProcesses.Enable = 0; config->LogProcesses.ContextId = "PROC"; config->LogProcesses.Count = 0; for (i = 0; i < DLT_SYSTEM_LOG_PROCESSES_MAX; i++) { config->LogProcesses.Name[i] = NULL; config->LogProcesses.Filename[i] = NULL; config->LogProcesses.Mode[i] = 0; config->LogProcesses.TimeDelay[i] = 0; } } /** * Read options from the configuration file */ int read_configuration_file(DltSystemConfiguration *config, char *file_name) { FILE *file; char *line, *token, *value, *pch; int ret = 0; init_configuration(config); file = fopen(file_name, "r"); if (file == NULL) { fprintf(stderr, "dlt-system-options, could not open configuration file.\n"); return -1; } line = malloc(MAX_LINE); token = malloc(MAX_LINE); value = malloc(MAX_LINE); MALLOC_ASSERT(line); MALLOC_ASSERT(token); MALLOC_ASSERT(value); while (fgets(line, MAX_LINE, file) != NULL) { token[0] = 0; value[0] = 0; pch = strtok (line, " =\r\n"); while (pch != NULL) { if (pch[0] == '#') break; if (token[0] == 0) { strncpy(token, pch, MAX_LINE - 1); token[MAX_LINE - 1] = 0; } else { strncpy(value, pch, MAX_LINE); value[MAX_LINE - 1] = 0; break; } pch = strtok (NULL, " =\r\n"); } if (token[0] && value[0]) { /* Common */ if (strcmp(token, "ApplicationId") == 0) { config->ApplicationId = malloc(strlen(value) + 1); MALLOC_ASSERT(config->ApplicationId); strcpy(config->ApplicationId, value); /* strcpy unritical here, because size matches exactly the size to be copied */ } /* Shell */ else if (strcmp(token, "ShellEnable") == 0) { config->Shell.Enable = atoi(value); } /* Syslog */ else if (strcmp(token, "SyslogEnable") == 0) { config->Syslog.Enable = atoi(value); } else if (strcmp(token, "SyslogContextId") == 0) { config->Syslog.ContextId = malloc(strlen(value) + 1); MALLOC_ASSERT(config->Syslog.ContextId); strcpy(config->Syslog.ContextId, value); /* strcpy unritical here, because size matches exactly the size to be copied */ } else if (strcmp(token, "SyslogPort") == 0) { config->Syslog.Port = atoi(value); } /* Journal */ else if (strcmp(token, "JournalEnable") == 0) { config->Journal.Enable = atoi(value); } else if (strcmp(token, "JournalContextId") == 0) { config->Journal.ContextId = malloc(strlen(value) + 1); MALLOC_ASSERT(config->Journal.ContextId); strcpy(config->Journal.ContextId, value); /* strcpy unritical here, because size matches exactly the size to be copied */ } else if (strcmp(token, "JournalCurrentBoot") == 0) { config->Journal.CurrentBoot = atoi(value); } else if (strcmp(token, "JournalFollow") == 0) { config->Journal.Follow = atoi(value); } else if (strcmp(token, "JournalMapLogLevels") == 0) { config->Journal.MapLogLevels = atoi(value); } /* File transfer */ else if (strcmp(token, "FiletransferEnable") == 0) { config->Filetransfer.Enable = atoi(value); } else if (strcmp(token, "FiletransferContextId") == 0) { config->Filetransfer.ContextId = malloc(strlen(value) + 1); MALLOC_ASSERT(config->Filetransfer.ContextId); strcpy(config->Filetransfer.ContextId, value); /* strcpy unritical here, because size matches exactly the size to be copied */ } else if (strcmp(token, "FiletransferTimeStartup") == 0) { config->Filetransfer.TimeStartup = atoi(value); } else if (strcmp(token, "FiletransferTimeDelay") == 0) { config->Filetransfer.TimeDelay = atoi(value); } else if (strcmp(token, "FiletransferTimeoutBetweenLogs") == 0) { config->Filetransfer.TimeoutBetweenLogs = atoi(value); } else if (strcmp(token, "FiletransferTempDir") == 0) { config->Filetransfer.TempDir = malloc(strlen(value) + 1); MALLOC_ASSERT(config->Filetransfer.TempDir); strcpy(config->Filetransfer.TempDir, value); /* strcpy unritical here, because size matches exactly the size to be copied */ } else if (strcmp(token, "FiletransferDirectory") == 0) { config->Filetransfer.Directory[config->Filetransfer.Count] = malloc(strlen(value) + 1); MALLOC_ASSERT(config->Filetransfer.Directory[config->Filetransfer.Count]); strcpy(config->Filetransfer.Directory[config->Filetransfer.Count], value); /* strcpy unritical here, because size matches exactly the size to be copied */ } else if (strcmp(token, "FiletransferCompression") == 0) { config->Filetransfer.Compression[config->Filetransfer.Count] = atoi(value); } else if (strcmp(token, "FiletransferCompressionLevel") == 0) { config->Filetransfer.CompressionLevel[config->Filetransfer.Count] = atoi(value); if (config->Filetransfer.Count < (DLT_SYSTEM_LOG_DIRS_MAX - 1)) { config->Filetransfer.Count++; } else { fprintf(stderr, "Too many file transfer directories configured. Maximum: %d\n", DLT_SYSTEM_LOG_DIRS_MAX); ret = -1; break; } } /* Log files */ else if (strcmp(token, "LogFileEnable") == 0) { config->LogFile.Enable = atoi(value); } else if (strcmp(token, "LogFileFilename") == 0) { config->LogFile.Filename[config->LogFile.Count] = malloc(strlen(value) + 1); MALLOC_ASSERT(config->LogFile.Filename[config->LogFile.Count]); strcpy(config->LogFile.Filename[config->LogFile.Count], value); /* strcpy unritical here, because size matches exactly the size to be copied */ } else if (strcmp(token, "LogFileMode") == 0) { config->LogFile.Mode[config->LogFile.Count] = atoi(value); } else if (strcmp(token, "LogFileTimeDelay") == 0) { config->LogFile.TimeDelay[config->LogFile.Count] = atoi(value); } else if (strcmp(token, "LogFileContextId") == 0) { config->LogFile.ContextId[config->LogFile.Count] = malloc(strlen(value) + 1); MALLOC_ASSERT(config->LogFile.ContextId[config->LogFile.Count]); strcpy(config->LogFile.ContextId[config->LogFile.Count], value); /* strcpy unritical here, because size matches exactly the size to be copied */ if (config->LogFile.Count < (DLT_SYSTEM_LOG_FILE_MAX - 1)) { config->LogFile.Count++; } else { fprintf(stderr, "Too many log files configured. Maximum: %d\n", DLT_SYSTEM_LOG_FILE_MAX); ret = -1; break; } } /* Log Processes */ else if (strcmp(token, "LogProcessesEnable") == 0) { config->LogProcesses.Enable = atoi(value); } else if (strcmp(token, "LogProcessesContextId") == 0) { config->LogProcesses.ContextId = malloc(strlen(value) + 1); MALLOC_ASSERT(config->LogProcesses.ContextId); strcpy(config->LogProcesses.ContextId, value); /* strcpy unritical here, because size matches exactly the size to be copied */ } else if (strcmp(token, "LogProcessName") == 0) { config->LogProcesses.Name[config->LogProcesses.Count] = malloc(strlen(value) + 1); MALLOC_ASSERT(config->LogProcesses.Name[config->LogProcesses.Count]); strcpy(config->LogProcesses.Name[config->LogProcesses.Count], value); /* strcpy unritical here, because size matches exactly the size to be copied */ } else if (strcmp(token, "LogProcessFilename") == 0) { config->LogProcesses.Filename[config->LogProcesses.Count] = malloc(strlen(value) + 1); MALLOC_ASSERT(config->LogProcesses.Filename[config->LogProcesses.Count]); strcpy(config->LogProcesses.Filename[config->LogProcesses.Count], value); /* strcpy unritical here, because size matches exactly the size to be copied */ } else if (strcmp(token, "LogProcessMode") == 0) { config->LogProcesses.Mode[config->LogProcesses.Count] = atoi(value); } else if (strcmp(token, "LogProcessTimeDelay") == 0) { config->LogProcesses.TimeDelay[config->LogProcesses.Count] = atoi(value); if (config->LogProcesses.Count < (DLT_SYSTEM_LOG_PROCESSES_MAX - 1)) { config->LogProcesses.Count++; } else { fprintf(stderr, "Too many processes to log configured. Maximum: %d\n", DLT_SYSTEM_LOG_PROCESSES_MAX); ret = -1; break; } } } } fclose(file); free(value); free(token); free(line); return ret; } dlt-daemon-2.18.4/src/system/dlt-system-process-handling.c000066400000000000000000000133041353342203500234550ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2011-2015, BMW AG * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author Lassi Marttala * * \copyright Copyright © 2011-2015 BMW AG. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file dlt-system-process-handling.c */ /******************************************************************************* ** ** ** SRC-MODULE: dlt-systemprocess-handling.c ** ** ** ** TARGET : linux ** ** ** ** PROJECT : DLT ** ** ** ** AUTHOR : Lassi Marttala ** ** ** ** PURPOSE : ** ** ** ** REMARKS : ** ** ** ** PLATFORM DEPENDANT [yes/no]: yes ** ** ** ** TO BE CHANGED BY USER [yes/no]: no ** ** ** *******************************************************************************/ #include "dlt.h" #include "dlt-system.h" #include #include #include #include #include #include #include volatile DltSystemThreads threads; DLT_IMPORT_CONTEXT(dltsystem) int daemonize() { DLT_LOG(dltsystem, DLT_LOG_DEBUG, DLT_STRING("dlt-system-process-handling, daemonize")); /* Fork new process */ int f = fork(); if (f < 0) return f; if (f > 0) exit(0); /* Create a new process group */ if (setsid() < 0) return -1; /** * Close all file descriptors and point * stdin, stdout and stderr to /dev/null */ int i; for (i = getdtablesize(); i >= 0; i--) close(i); int fd = open("/dev/null", O_RDWR); if (fd < 0) return -1; if ((dup(fd) < 0) || (dup(fd) < 0)) { close(fd); return -1; } /** * Ignore signals related to child processes and * terminal handling. */ signal(SIGCHLD, SIG_IGN); signal(SIGTSTP, SIG_IGN); signal(SIGTTOU, SIG_IGN); signal(SIGTTIN, SIG_IGN); /*no close(fd); - we just intentionally pointed stdx to null! tbd: set ignore for coverity */ return 0; } void start_threads(DltSystemConfiguration *config) { DLT_LOG(dltsystem, DLT_LOG_DEBUG, DLT_STRING("dlt-system-process-handling, start threads")); int i; threads.count = 0; threads.shutdown = 0; for (i = 0; i < MAX_THREADS; i++) threads.threads[i] = 0; #if defined(DLT_SYSTEMD_WATCHDOG_ENABLE) start_systemd_watchdog(config); #endif if (config->Shell.Enable) init_shell(); if (config->LogFile.Enable) start_logfile(config); if (config->Filetransfer.Enable) start_filetransfer(config); if (config->LogProcesses.Enable) start_logprocess(config); if (config->Syslog.Enable) start_syslog(config); #if defined(DLT_SYSTEMD_JOURNAL_ENABLE) if (config->Journal.Enable) start_systemd_journal(config); #endif } /** * Wait for threads to exit. * There's not actually a condition currently * to bail out of file transfer without a signal. */ void join_threads() { int i; DLT_LOG(dltsystem, DLT_LOG_DEBUG, DLT_STRING("dlt-system-process-handling, waiting for threads to exit.")); if (threads.count < 1) { DLT_LOG(dltsystem, DLT_LOG_DEBUG, DLT_STRING("dlt-system-process-handling, no threads, waiting for signal.")); sleep(UINT_MAX); } else { DLT_LOG(dltsystem, DLT_LOG_DEBUG, DLT_STRING("dlt-system-process-handling, thread count: "), DLT_INT(threads.count)); for (i = 0; i < threads.count; i++) { pthread_join(threads.threads[i], NULL); DLT_LOG(dltsystem, DLT_LOG_DEBUG, DLT_STRING("dlt-system-process-handling, thread exit: "), DLT_INT(threads.threads[i])); } } } void dlt_system_signal_handler(int sig) { DLT_LOG(dltsystem, DLT_LOG_DEBUG, DLT_STRING("dlt-system-process-handling, signal handler")); switch (sig) { case SIGHUP: case SIGTERM: case SIGINT: case SIGQUIT: DLT_LOG(dltsystem, DLT_LOG_DEBUG, DLT_STRING("dlt-system-process-handling, exit, signal: "), DLT_INT(sig)); exit(0); break; default: DLT_LOG(dltsystem, DLT_LOG_WARN, DLT_STRING("dlt-system-process-handling, unknown signal!")); break; } } dlt-daemon-2.18.4/src/system/dlt-system-processes.c000066400000000000000000000137601353342203500222310ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2011-2015, BMW AG * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author Lassi Marttala * * \copyright Copyright © 2011-2015 BMW AG. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file dlt-system-processes.c */ /******************************************************************************* ** ** ** SRC-MODULE: dlt-system-processes.c ** ** ** ** TARGET : linux ** ** ** ** PROJECT : DLT ** ** ** ** AUTHOR : Lassi Marttala ** ** Alexander Wenzel Alexander.AW.Wenzel@bmw.de ** ** ** ** PURPOSE : ** ** ** ** REMARKS : ** ** ** ** PLATFORM DEPENDANT [yes/no]: yes ** ** ** ** TO BE CHANGED BY USER [yes/no]: no ** ** ** *******************************************************************************/ #include #include #include #include #include #include #include #include #include "dlt-system.h" /* Modes of sending */ #define SEND_MODE_OFF 0 #define SEND_MODE_ONCE 1 #define SEND_MODE_ON 2 extern DltSystemThreads threads; DLT_IMPORT_CONTEXT(dltsystem) DLT_DECLARE_CONTEXT(procContext) void send_process(LogProcessOptions const *popts, int n) { DLT_LOG(dltsystem, DLT_LOG_DEBUG, DLT_STRING("dlt-system-processes, send process info.")); FILE *pFile; struct dirent *dp; char filename[PATH_MAX]; char buffer[1024]; int bytes; int found = 0; /* go through all process files in directory */ DIR *dir = opendir("/proc"); if (dir != NULL) { while ((dp = readdir(dir)) != NULL) if (isdigit(dp->d_name[0])) { buffer[0] = 0; snprintf(filename, PATH_MAX, "/proc/%s/cmdline", dp->d_name); pFile = fopen(filename, "r"); if (pFile != NULL) { bytes = fread(buffer, 1, sizeof(buffer) - 1, pFile); fclose(pFile); } if ((strcmp((*popts).Name[n], "*") == 0) || (strcmp(buffer, (*popts).Name[n]) == 0)) { found = 1; snprintf(filename, PATH_MAX, "/proc/%s/%s", dp->d_name, (*popts).Filename[n]); pFile = fopen(filename, "r"); if (pFile != NULL) { bytes = fread(buffer, 1, sizeof(buffer) - 1, pFile); fclose(pFile); if (bytes > 0) { buffer[bytes] = 0; DLT_LOG(procContext, DLT_LOG_INFO, DLT_INT(atoi(dp->d_name)), DLT_STRING((*popts).Filename[n]), DLT_STRING(buffer)); } } if (strcmp((*popts).Name[n], "*") != 0) break; } } closedir(dir); } else { DLT_LOG(dltsystem, DLT_LOG_ERROR, DLT_STRING("dlt-system-processes, failed to open /proc.")); } if (!found) DLT_LOG(procContext, DLT_LOG_INFO, DLT_STRING("Process"), DLT_STRING((*popts).Name[n]), DLT_STRING("not running!")); } void logprocess_thread(void *v_conf) { DLT_LOG(dltsystem, DLT_LOG_DEBUG, DLT_STRING("dlt-system-processes, in thread.")); DltSystemConfiguration *conf = (DltSystemConfiguration *)v_conf; DLT_REGISTER_CONTEXT(procContext, conf->LogProcesses.ContextId, "Log Processes"); int process_delays[DLT_SYSTEM_LOG_PROCESSES_MAX]; int i; for (i = 0; i < conf->LogProcesses.Count; i++) process_delays[i] = conf->LogProcesses.TimeDelay[i]; while (!threads.shutdown) { sleep(1); for (i = 0; i < conf->LogProcesses.Count; i++) { if (conf->LogProcesses.Mode[i] == SEND_MODE_OFF) continue; if (process_delays[i] <= 0) { send_process(&(conf->LogProcesses), i); process_delays[i] = conf->LogProcesses.TimeDelay[i]; if (conf->LogProcesses.Mode[i] == SEND_MODE_ONCE) conf->LogProcesses.Mode[i] = SEND_MODE_OFF; } else { process_delays[i]--; } } } } void start_logprocess(DltSystemConfiguration *conf) { DLT_LOG(dltsystem, DLT_LOG_DEBUG, DLT_STRING("dlt-system-processes, starting process log.")); static pthread_attr_t t_attr; static pthread_t pt; pthread_create(&pt, &t_attr, (void *)logprocess_thread, conf); threads.threads[threads.count++] = pt; } dlt-daemon-2.18.4/src/system/dlt-system-shell.c000066400000000000000000000115111353342203500213220ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2011-2015, BMW AG * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author Lassi Marttala * * \copyright Copyright © 2011-2015 BMW AG. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file dlt-system-shell.c */ /******************************************************************************* ** ** ** SRC-MODULE: dlt-system-shell.c ** ** ** ** TARGET : linux ** ** ** ** PROJECT : DLT ** ** ** ** AUTHOR : Lassi Marttala ** ** Alexander Wenzel Alexander.AW.Wenzel@bmw.de ** ** ** ** PURPOSE : ** ** ** ** REMARKS : ** ** ** ** PLATFORM DEPENDANT [yes/no]: yes ** ** ** ** TO BE CHANGED BY USER [yes/no]: no ** ** ** *******************************************************************************/ /******************************************************************************* ** Author Identity ** ******************************************************************************** ** ** ** Initials Name Company ** ** -------- ------------------------- ---------------------------------- ** ** lm Lassi Marttala BMW ** *******************************************************************************/ #include "dlt.h" #include "dlt-system.h" #include #include #define DLT_SHELL_COMMAND_MAX_LENGTH 1024 DLT_IMPORT_CONTEXT(dltsystem) DLT_DECLARE_CONTEXT(shellContext) int dlt_shell_injection_callback(uint32_t service_id, void *data, uint32_t length) { (void)length; DLT_LOG(shellContext, DLT_LOG_DEBUG, DLT_STRING("dlt-system-shell, injection callback")); char text[DLT_SHELL_COMMAND_MAX_LENGTH]; int syserr = 0; if (length <= DLT_SHELL_COMMAND_MAX_LENGTH - 1) { strncpy(text, data, length); text[length] = 0; } else { strncpy(text, data, DLT_SHELL_COMMAND_MAX_LENGTH - 1); text[DLT_SHELL_COMMAND_MAX_LENGTH - 1] = 0; } DLT_LOG(shellContext, DLT_LOG_DEBUG, DLT_STRING("dlt-system-shell, injection injection id:"), DLT_UINT32(service_id)); DLT_LOG(shellContext, DLT_LOG_DEBUG, DLT_STRING("dlt-system-shell, injection data:"), DLT_STRING(text)); switch (service_id) { case 0x1001: if ((syserr = system(text)) != 0) DLT_LOG(shellContext, DLT_LOG_ERROR, DLT_STRING("dlt-system-shell, abnormal exit status."), DLT_STRING(text), DLT_INT(syserr)); else DLT_LOG(shellContext, DLT_LOG_INFO, DLT_STRING("Shell command executed:"), DLT_STRING(text)); break; default: DLT_LOG(shellContext, DLT_LOG_ERROR, DLT_STRING("dlt-system-shell, unknown command received."), DLT_UINT32(service_id), DLT_STRING(text)); break; } return 0; } void init_shell() { DLT_LOG(dltsystem, DLT_LOG_DEBUG, DLT_STRING("dlt-system-shell, register callback")); DLT_REGISTER_CONTEXT(shellContext, "CMD", "Execute Shell commands"); DLT_REGISTER_INJECTION_CALLBACK(shellContext, 0x1001, dlt_shell_injection_callback); } dlt-daemon-2.18.4/src/system/dlt-system-syslog.c000066400000000000000000000121701353342203500215350ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2011-2015, BMW AG * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author Lassi Marttala * * \copyright Copyright © 2011-2015 BMW AG. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file dlt-system-syslog.c */ /******************************************************************************* ** ** ** SRC-MODULE: dlt-system-syslog.c ** ** ** ** TARGET : linux ** ** ** ** PROJECT : DLT ** ** ** ** AUTHOR : Lassi Marttala ** ** Alexander Wenzel Alexander.AW.Wenzel@bmw.de ** ** ** ** PURPOSE : ** ** ** ** REMARKS : ** ** ** ** PLATFORM DEPENDANT [yes/no]: yes ** ** ** ** TO BE CHANGED BY USER [yes/no]: no ** ** ** *******************************************************************************/ #include #include #include #include #include #include #include "dlt-system.h" extern DltSystemThreads threads; DLT_IMPORT_CONTEXT(dltsystem) DLT_DECLARE_CONTEXT(syslogContext) #define RECV_BUF_SZ 1024 int init_socket(SyslogOptions opts) { DLT_LOG(dltsystem, DLT_LOG_DEBUG, DLT_STRING("dlt-system-syslog, init socket, port: "), DLT_INT(opts.Port)); int sock = -1; struct sockaddr_in syslog_addr; #ifdef DLT_USE_IPv6 sock = socket(AF_INET6, SOCK_DGRAM, 0); #else sock = socket(AF_INET, SOCK_DGRAM, 0); #endif if (sock < 0) { DLT_LOG(syslogContext, DLT_LOG_FATAL, DLT_STRING("Unable to create socket for SYSLOG.")); return -1; } #ifdef DLT_USE_IPv6 syslog_addr.sin_family = AF_INET6; #else syslog_addr.sin_family = AF_INET; #endif syslog_addr.sin_port = htons(opts.Port); syslog_addr.sin_addr.s_addr = INADDR_ANY; memset(&(syslog_addr.sin_zero), 0, 8); if (bind(sock, (struct sockaddr *)&syslog_addr, sizeof(struct sockaddr)) == -1) { DLT_LOG(syslogContext, DLT_LOG_FATAL, DLT_STRING("Unable to bind socket for SYSLOG.")); close(sock); return -1; } return sock; } int read_socket(int sock) { DLT_LOG(dltsystem, DLT_LOG_DEBUG, DLT_STRING("dlt-system-syslog, read socket")); char recv_data[RECV_BUF_SZ]; struct sockaddr_in client_addr; socklen_t addr_len = sizeof(struct sockaddr_in); int bytes_read = recvfrom(sock, recv_data, RECV_BUF_SZ, 0, (struct sockaddr *)&client_addr, &addr_len); if (bytes_read == -1) { if (errno == EINTR) { return 0; } else { DLT_LOG(syslogContext, DLT_LOG_FATAL, DLT_STRING("Read from socket failed in SYSLOG.")); return -1; } } recv_data[bytes_read] = '\0'; if (bytes_read != 0) DLT_LOG(syslogContext, DLT_LOG_INFO, DLT_STRING(recv_data)); return bytes_read; } void syslog_thread(void *v_conf) { DLT_LOG(dltsystem, DLT_LOG_DEBUG, DLT_STRING("dlt-system-syslog, in thread.")); DltSystemConfiguration *conf = (DltSystemConfiguration *)v_conf; DLT_REGISTER_CONTEXT(syslogContext, conf->Syslog.ContextId, "SYSLOG Adapter"); int sock = init_socket(conf->Syslog); if (sock < 0) return; while (!threads.shutdown) if (read_socket(sock) < 0) { close(sock); return; } close (sock); } void start_syslog(DltSystemConfiguration *conf) { DLT_LOG(dltsystem, DLT_LOG_DEBUG, DLT_STRING("dlt-system-syslog, start syslog")); static pthread_attr_t t_attr; static pthread_t pt; pthread_create(&pt, &t_attr, (void *)syslog_thread, conf); threads.threads[threads.count++] = pt; } dlt-daemon-2.18.4/src/system/dlt-system-watchdog.c000066400000000000000000000120251353342203500220140ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2011-2015, BMW AG * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author * Lassi Marttala * Alexander Wenzel * Markus Klein * Mikko Rapeli * * \copyright Copyright © 2011-2015 BMW AG. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file dlt-system-watchdog.c */ #if defined(DLT_SYSTEMD_WATCHDOG_ENABLE) #include #include #include #include #include "dlt.h" #include "dlt-system.h" #include "sd-daemon.h" DLT_DECLARE_CONTEXT(watchdogContext) DLT_IMPORT_CONTEXT(dltsystem) extern DltSystemThreads threads; typedef struct { int timer_fd; unsigned long long wakeups_missed; } PeriodicData; void wait_period (PeriodicData *info) { unsigned long long missed; if (read (info->timer_fd, &missed, sizeof (missed)) < 0) DLT_LOG(watchdogContext, DLT_LOG_ERROR, DLT_STRING("Could not read from timer file descriptor in watchdog.\n")); if (missed > 0) info->wakeups_missed += (missed - 1); } int make_periodic(unsigned int period, PeriodicData *info) { unsigned int ns; unsigned int sec; int fd; struct itimerspec itval; if (info == 0) { DLT_LOG(watchdogContext, DLT_LOG_ERROR, DLT_STRING("Invalid function parameters used for function make_periodic.\n")); return -1; } /* Create the timer */ fd = timerfd_create (CLOCK_MONOTONIC, 0); info->wakeups_missed = 0; info->timer_fd = fd; if (fd == -1) { DLT_LOG(watchdogContext, DLT_LOG_ERROR, DLT_STRING("Can't create timer filedescriptor.\n")); return -1; } /* Make the timer periodic */ sec = period / 1000000; ns = (period - (sec * 1000000)) * 1000; itval.it_interval.tv_sec = sec; itval.it_interval.tv_nsec = ns; itval.it_value.tv_sec = sec; itval.it_value.tv_nsec = ns; return timerfd_settime (fd, 0, &itval, NULL); } void watchdog_thread(void *v_conf) { char str[512]; char *watchdogUSec; unsigned int watchdogTimeoutSeconds; unsigned int notifiyPeriodNSec; PeriodicData info; DLT_REGISTER_CONTEXT(watchdogContext, "DOG", "dlt system watchdog context."); sleep(1); DLT_LOG(watchdogContext, DLT_LOG_INFO, DLT_STRING("Watchdog thread started.\n")); if (v_conf == 0) { DLT_LOG(watchdogContext, DLT_LOG_ERROR, DLT_STRING("Invalid function parameters used for function watchdog_thread.\n")); return; } watchdogUSec = getenv("WATCHDOG_USEC"); if (watchdogUSec) { DLT_LOG(watchdogContext, DLT_LOG_DEBUG, DLT_STRING("watchdogusec: "), DLT_STRING(watchdogUSec)); watchdogTimeoutSeconds = atoi(watchdogUSec); if (watchdogTimeoutSeconds > 0) { /* Calculate half of WATCHDOG_USEC in ns for timer tick */ notifiyPeriodNSec = watchdogTimeoutSeconds / 2; snprintf(str, 512, "systemd watchdog timeout: %u nsec - timer will be initialized: %u nsec\n", watchdogTimeoutSeconds, notifiyPeriodNSec); DLT_LOG(watchdogContext, DLT_LOG_DEBUG, DLT_STRING(str)); if (make_periodic (notifiyPeriodNSec, &info) < 0) { DLT_LOG(watchdogContext, DLT_LOG_ERROR, DLT_STRING("Could not initialize systemd watchdog timer\n")); return; } while (1) { if (sd_notify(0, "WATCHDOG=1") < 0) DLT_LOG(watchdogContext, DLT_LOG_ERROR, DLT_STRING("Could not reset systemd watchdog\n")); DLT_LOG(watchdogContext, DLT_LOG_DEBUG, DLT_STRING("systemd watchdog waited periodic\n")); /* Wait for next period */ wait_period(&info); } } else { snprintf(str, 512, "systemd watchdog timeout incorrect: %u\n", watchdogTimeoutSeconds); DLT_LOG(watchdogContext, DLT_LOG_DEBUG, DLT_STRING(str)); } } else { DLT_LOG(watchdogContext, DLT_LOG_ERROR, DLT_STRING("systemd watchdog timeout (WATCHDOG_USEC) is null\n")); } } void start_systemd_watchdog(DltSystemConfiguration *conf) { DLT_LOG(dltsystem, DLT_LOG_DEBUG, DLT_STRING("Creating thread for systemd watchdog\n")); static pthread_attr_t t_attr; static pthread_t pt; if (pthread_create(&pt, &t_attr, (void *)watchdog_thread, conf) == 0) threads.threads[threads.count++] = pt; else DLT_LOG(dltsystem, DLT_LOG_ERROR, DLT_STRING("Could not create thread for systemd watchdog\n")); } #endif dlt-daemon-2.18.4/src/system/dlt-system.c000066400000000000000000000104701353342203500202200ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2011-2015, BMW AG * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author Lassi Marttala * * \copyright Copyright © 2011-2015 BMW AG. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file dlt-system.c */ /******************************************************************************* ** ** ** SRC-MODULE: dlt-system.c ** ** ** ** TARGET : linux ** ** ** ** PROJECT : DLT ** ** ** ** AUTHOR : Lassi Marttala ** ** Alexander Wenzel Alexander.AW.Wenzel@bmw.de ** ** ** ** PURPOSE : ** ** ** ** REMARKS : ** ** ** ** PLATFORM DEPENDANT [yes/no]: yes ** ** ** ** TO BE CHANGED BY USER [yes/no]: no ** ** ** *******************************************************************************/ #include "dlt-system.h" #include #include #include #include #if defined(DLT_SYSTEMD_WATCHDOG_ENABLE) || defined(DLT_SYSTEMD_ENABLE) # include "sd-daemon.h" #endif DLT_DECLARE_CONTEXT(dltsystem) int main(int argc, char *argv[]) { DltSystemCliOptions options; DltSystemConfiguration config; #if defined(DLT_SYSTEMD_WATCHDOG_ENABLE) || defined(DLT_SYSTEMD_ENABLE) int ret; #endif if (read_command_line(&options, argc, argv) < 0) { fprintf(stderr, "Failed to read command line!\n"); return -1; } if (read_configuration_file(&config, options.ConfigurationFileName) < 0) { fprintf(stderr, "Failed to read configuration file!\n"); return -1; } DLT_REGISTER_APP(config.ApplicationId, "DLT System Manager"); DLT_REGISTER_CONTEXT(dltsystem, "MGR", "Context of main dlt system manager"); #if defined(DLT_SYSTEMD_WATCHDOG_ENABLE) || defined(DLT_SYSTEMD_ENABLE) ret = sd_booted(); if (ret == 0) { DLT_LOG(dltsystem, DLT_LOG_INFO, DLT_STRING("system not booted with systemd!\n")); } else if (ret < 0) { DLT_LOG(dltsystem, DLT_LOG_ERROR, DLT_STRING("sd_booted failed!\n")); return -1; } else { DLT_LOG(dltsystem, DLT_LOG_INFO, DLT_STRING("system booted with systemd\n")); } #endif DLT_LOG(dltsystem, DLT_LOG_DEBUG, DLT_STRING("Configuration loaded.")); if (options.Daemonize > 0) { if (daemonize() < 0) { DLT_LOG(dltsystem, DLT_LOG_FATAL, DLT_STRING("Daemonization failed!")); return -1; } DLT_LOG(dltsystem, DLT_LOG_DEBUG, DLT_STRING("dlt-system daemonized.")); } DLT_LOG(dltsystem, DLT_LOG_DEBUG, DLT_STRING("Setting signal handlers for abnormal exit")); signal(SIGTERM, dlt_system_signal_handler); signal(SIGHUP, dlt_system_signal_handler); signal(SIGQUIT, dlt_system_signal_handler); signal(SIGINT, dlt_system_signal_handler); DLT_LOG(dltsystem, DLT_LOG_DEBUG, DLT_STRING("Launching threads.")); start_threads(&config); join_threads(); return 0; } dlt-daemon-2.18.4/src/system/dlt-system.conf000066400000000000000000000144241353342203500207260ustar00rootroot00000000000000# Configuration file of DLT system manager # ######################################################################## # General configuration ######################################################################## # The application Id used for the System manager (Default: SYS) ApplicationId = SYS ######################################################################## # Shell configuration ######################################################################## # Be careful when you enable this feature. The user can send any kind of # shell commands. The commands are executed with the rights of the # dlt-system process. Dlt-system is started by default as user genivi. # Enable the Shell for command line injections (Default: 0) ShellEnable = 0 ######################################################################## # Syslog Adapter configuration ######################################################################## # Enable the Syslog Adapter (Default: 0) # Enable only when systemd is already running in your system otherwise # logs will not come to Client (e.g. dlt_viewer). SyslogEnable = 0 # The Context Id of the syslog adapter (Default: SYSL) SyslogContextId = SYSL # The UDP port opened by DLT system mamager to receive system logs (Default: 47111) SyslogPort = 47111 ######################################################################## # Systemd Journal Adapter configuration ######################################################################## # This feature is only available, when dlt is compiled with # the option "WITH_SYSTEMD_JOURNAL" # Dlt-system is started by default as user genivi, see dlt-system.service file. # The user genivi must be added to one of the groups 'adm', 'wheel' or # 'systemd-journal' to have access to all journal entries. # Enable Systemd Journal Adapter only when your system doesn't have systemd. # Don't enable both (SyslogEnable = 1 and JournalEnable = 1) together because # it causes bind error (can see on connected client). # Enable the Systemd Journal Adapter (Default: 0) JournalEnable = 0 # The Context Id of the journal adapter (Default: JOUR) JournalContextId = JOUR # Show only log entries of current boot and follow (Default: 1) # if not JournalCurrentBoot and not JournalFollow is set all # persistent journal entries will be logged JournalCurrentBoot = 1 # Show only the last 10 entries and follow (Default: 0) JournalFollow = 0 # Map the log levels (Default: 1) # Mapping journal log levels to DLT log levels # 0 Emergency DLT_LOG_FATAL # 1 Alert DLT_LOG_FATAL # 2 Critical DLT_LOG_FATAL # 3 Error DLT_LOG_ERROR # 4 Warning DLT_LOG_WARN # 5 Notice DLT_LOG_INFO # 6 Informational DLT_LOG_INFO # 7 Debug DLT_LOG_DEBUG JournalMapLogLevels = 1 ######################################################################## # Filetransfer Manager ######################################################################## # Enable the Filetransfer (Default: 0) FiletransferEnable = 0 # The Context Id of the filetransfer (Default: FILE) FiletransferContextId = FILE # Time in seconds after startup of dlt-system when first file is transfered (Default: 0) FiletransferTimeStartup = 0 # Time to wait when transfered file is deleted and next file transfer starts (Default: 10) # Time in seconds FiletransferTimeDelay = 10 # Time in ms seconds to wait between two file transfer logs of a single file to DLT. (Default: 10) FiletransferTimeoutBetweenLogs = 5 # You can define multiple file transfer directories # Define the directory to watch, whether to compress # the file with zlib and the zlib compression level # For parsing purposes, FiletransferCompressionLevel # must be the last one of three values. # For compressing and sending following subdirectories are used: .tocompress and .tosend FiletransferDirectory = /var/dlt/ft1 FiletransferCompression = 1 FiletransferCompressionLevel = 5 # Second directory to watch FiletransferDirectory = /var/dlt/ft2 FiletransferCompression = 0 FiletransferCompressionLevel = 5 # And so on... FiletransferDirectory = /var/dlt/ft3 FiletransferCompression = 0 FiletransferCompressionLevel = 5 ######################################################################## # Log short files, especially from proc filesystem ######################################################################## # Enable the logging of files (Default: 0) LogFileEnable = 0 # Log different files # Mode: 0 = off, 1 = startup only, 2 = regular # TimeDelay: If mode regular is set, time delay is the number of seconds for next sent # Log the file /etc/sysrel LogFileFilename = /etc/sysrel LogFileMode = 1 LogFileTimeDelay = 3 LogFileContextId = VER # Log the file /proc/version LogFileFilename = /proc/version LogFileMode = 1 LogFileTimeDelay = 3 LogFileContextId = VERK # Log the file /proc/meminfo # LogFileFilename = /proc/meminfo # LogFileMode = 2 # LogFileTimeDelay = 5 # LogFileContextId = MEM # Log the file /proc/cpuinfo # LogFileFilename = /proc/cpuinfo # LogFileMode = 2 # LogFileTimeDelay = 5 # LogFileContextId = CPU # Log the file /proc/stat LogFileFilename = /proc/stat LogFileMode = 2 LogFileTimeDelay = 1 LogFileContextId = STAT # Log the file /proc/modules # LogFileFilename = /proc/modules # LogFileMode = 2 # LogFileTimeDelay = 5 # LogFileContextId = MOD # Log the file /proc/ioports # LogFileFilename = /proc/ioports # LogFileMode = 1 # LogFileTimeDelay = 5 # LogFileContextId = IOP # Log the file /proc/iomem # LogFileFilename = /proc/iomem # LogFileMode = 1 # LogFileTimeDelay = 5 # LogFileContextId = IOM ######################################################################## # Log Processes ######################################################################## # Enable the logging of processes (Default: 0) LogProcessesEnable = 0 # The Context Id of the kernel version (Default: PROC) LogProcessesContextId = PROC # Log different processes # Name: * = all process, X=alternative name (must correspind to /proc/X/cmdline # Filename: the filename in the subdirectory /proc/processid/ # Mode: 0 = off, 1 = startup only, 2 = regular # TimeDelay: If mode regular is set, time delay is the number of seconds for next sent LogProcessName = * LogProcessFilename = stat LogProcessMode = 2 LogProcessTimeDelay = 5 # LogProcessName = dlt_viewer # LogProcessFilename = stat # LogProcessMode = 2 # LogProcessTimeDelay = 1 dlt-daemon-2.18.4/src/system/dlt-system.h000066400000000000000000000142241353342203500202260ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2011-2015, BMW AG * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author Lassi Marttala * * \copyright Copyright © 2011-2015 BMW AG. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file dlt-system.h */ /******************************************************************************* ** ** ** SRC-MODULE: dlt-system.h ** ** ** ** TARGET : linux ** ** ** ** PROJECT : DLT ** ** ** ** AUTHOR : Lassi Marttala ** ** ** ** PURPOSE : ** ** ** ** REMARKS : ** ** ** ** PLATFORM DEPENDANT [yes/no]: yes ** ** ** ** TO BE CHANGED BY USER [yes/no]: no ** ** ** *******************************************************************************/ /******************************************************************************* ** Author Identity ** ******************************************************************************** ** ** ** Initials Name Company ** ** -------- ------------------------- ---------------------------------- ** ** lm Lassi Marttala BMW ** *******************************************************************************/ #ifndef DLT_SYSTEM_H_ #define DLT_SYSTEM_H_ /* DLT related includes. */ #include "dlt.h" #include "dlt_common.h" /* Constants */ #define DEFAULT_CONF_FILE (CONFIGURATION_FILES_DIR "/dlt-system.conf") #define DLT_SYSTEM_LOG_FILE_MAX 32 #define DLT_SYSTEM_LOG_DIRS_MAX 32 #define DLT_SYSTEM_LOG_PROCESSES_MAX 32 #define DLT_SYSTEM_MODE_OFF 0 #define DLT_SYSTEM_MODE_STARTUP 1 #define DLT_SYSTEM_MODE_REGULAR 2 #define MAX_LINE 1024 #define MAX_THREADS 8 /* Macros */ #define MALLOC_ASSERT(x) if (x == NULL) { \ fprintf(stderr, "Out of memory\n"); \ abort(); } /** * Configuration structures. * Please see dlt-system.conf for explanation of all the options. */ /* Command line options */ typedef struct { char *ConfigurationFileName; int Daemonize; } DltSystemCliOptions; /* Configuration shell options */ typedef struct { int Enable; } ShellOptions; /* Configuration syslog options */ typedef struct { int Enable; char *ContextId; int Port; } SyslogOptions; /* Configuration journal options */ typedef struct { int Enable; char *ContextId; int CurrentBoot; int Follow; int MapLogLevels; } JournalOptions; typedef struct { int Enable; char *ContextId; int TimeStartup; int TimeDelay; int TimeoutBetweenLogs; char *TempDir; /* Variable number of file transfer dirs */ int Count; int Compression[DLT_SYSTEM_LOG_DIRS_MAX]; int CompressionLevel[DLT_SYSTEM_LOG_DIRS_MAX]; char *Directory[DLT_SYSTEM_LOG_DIRS_MAX]; } FiletransferOptions; typedef struct { int Enable; /* Variable number of files to transfer */ int Count; char *ContextId[DLT_SYSTEM_LOG_FILE_MAX]; char *Filename[DLT_SYSTEM_LOG_FILE_MAX]; int Mode[DLT_SYSTEM_LOG_FILE_MAX]; int TimeDelay[DLT_SYSTEM_LOG_FILE_MAX]; } LogFileOptions; typedef struct { int Enable; char *ContextId; /* Variable number of processes */ int Count; char *Name[DLT_SYSTEM_LOG_PROCESSES_MAX]; char *Filename[DLT_SYSTEM_LOG_PROCESSES_MAX]; int Mode[DLT_SYSTEM_LOG_PROCESSES_MAX]; int TimeDelay[DLT_SYSTEM_LOG_PROCESSES_MAX]; } LogProcessOptions; typedef struct { char *ApplicationId; ShellOptions Shell; SyslogOptions Syslog; JournalOptions Journal; FiletransferOptions Filetransfer; LogFileOptions LogFile; LogProcessOptions LogProcesses; } DltSystemConfiguration; typedef struct { pthread_t threads[MAX_THREADS]; int count; int shutdown; } DltSystemThreads; /** * Forward declarations for the whole application */ /* In dlt-system-options.c */ int read_command_line(DltSystemCliOptions *options, int argc, char *argv[]); int read_configuration_file(DltSystemConfiguration *config, char *file_name); /* In dlt-process-handling.c */ int daemonize(); void start_threads(DltSystemConfiguration *config); void join_threads(); void dlt_system_signal_handler(int sig); void register_with_dlt(DltSystemConfiguration *config); /* Thread initiators: */ void init_shell(); void start_syslog(); void start_filetransfer(DltSystemConfiguration *conf); void start_logfile(DltSystemConfiguration *conf); void start_logprocess(DltSystemConfiguration *conf); #if defined(DLT_SYSTEMD_WATCHDOG_ENABLE) void start_systemd_watchdog(DltSystemConfiguration *conf); #endif #if defined(DLT_SYSTEMD_JOURNAL_ENABLE) void start_systemd_journal(DltSystemConfiguration *conf); #endif #endif /* DLT_SYSTEM_H_ */ dlt-daemon-2.18.4/src/tests/000077500000000000000000000000001353342203500155635ustar00rootroot00000000000000dlt-daemon-2.18.4/src/tests/CMakeLists.txt000066400000000000000000000031611353342203500203240ustar00rootroot00000000000000####### # SPDX license identifier: MPL-2.0 # # Copyright (C) 2011-2015, BMW AG # # This file is part of GENIVI Project DLT - Diagnostic Log and Trace. # # This Source Code Form is subject to the terms of the # Mozilla Public License (MPL), v. 2.0. # If a copy of the MPL was not distributed with this file, # You can obtain one at http://mozilla.org/MPL/2.0/. # # For further information see http://www.genivi.org/. ####### set(dlt-test-multi-process_SRCS dlt-test-multi-process.c) set(dlt-test-multi-process-client_SRCS dlt-test-multi-process-client.c) set(dlt-test-user_SRCS dlt-test-user.c) set(dlt-test-client_SRCS dlt-test-client.c) set(dlt-test-stress-user_SRCS dlt-test-stress-user.c) set(dlt-test-stress-client_SRCS dlt-test-stress-client.c) set(dlt-test-stress_SRCS dlt-test-stress.c) set(dlt-test-filetransfer_SRCS dlt-test-filetransfer.c) set(dlt-test-fork-handler_SRCS dlt-test-fork-handler.c) set(dlt-test-init-free_SRCS dlt-test-init-free.c) foreach(target dlt-test-multi-process dlt-test-multi-process-client dlt-test-user dlt-test-client dlt-test-stress-user dlt-test-stress-client dlt-test-stress dlt-test-filetransfer dlt-test-fork-handler dlt-test-init-free ) add_executable(${target} ${${target}_SRCS}) target_link_libraries(${target} dlt) set_target_properties(${target} PROPERTIES LINKER_LANGUAGE C) install(TARGETS ${target} RUNTIME DESTINATION bin COMPONENT base) endforeach() install(FILES dlt-test-filetransfer-file dlt-test-filetransfer-image.png DESTINATION share/dlt-filetransfer) dlt-daemon-2.18.4/src/tests/dlt-test-change-ll-through-env.sh000077500000000000000000000031161353342203500237570ustar00rootroot00000000000000#!/bin/bash # check if dlt-daemon is running daemon_running=`/usr/bin/ps -C dlt-daemon | wc -l` daemon_pid=0 if [ "$daemon_running" -lt "2" ]; then echo "No daemon running, starting one myself" /usr/bin/dlt-daemon > /tmp/dlt_daemon_dlt_receiver_test.txt & daemon_pid=$! echo "daemon pid: " ${daemon_pid} else echo "dlt-daemon already running" fi # create a directory in /tmp where all logs will be stored output_dir=`mktemp -d /tmp/DLT_TESTING_XXXXXX` echo "Using directory " ${output_dir} # start dlt-receive (in background) and store PID echo "Starting dlt-receive" /usr/bin/dlt-receive -o ${output_dir}/dlt_test.dlt localhost & dlt_receive_pid=$! disown # start dlt-example-user to create some logs # sleep time: 100ms # number of messages: 10 /usr/bin/dlt-example-user -d 100 -n 10 TEST_MESSAGE_ONE # stop dlt-receive kill ${dlt_receive_pid} # show content of /tmp echo "log-file after first run" ls -l ${output_dir} # start dlt-receive (in background) and store PID echo "Starting dlt-receive" /usr/bin/dlt-receive -o ${output_dir}/dlt_test_no_log.dlt localhost & dlt_receive_pid=$! disown # start dlt-example-user to create some logs, disable logging through environment variable DLT_INITIAL_LOG_LEVEL=::-1 /usr/bin/dlt-example-user -d 100 -n 10 TEST_MESSAGE_TWO # show content of /tmp, log should not contain log messages from dlt-example-user (TEST_MESSAGE_TWO) kill ${dlt_receive_pid} echo "log-file after second run" ls -l ${output_dir} # directory will not be cleaned up echo "Used directory " ${output_dir} if [ "${daemon_pid}" -ne "0" ]; then sleep 1 kill ${daemon_pid} fi dlt-daemon-2.18.4/src/tests/dlt-test-client.c000066400000000000000000003170331353342203500207520ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2011-2015, BMW AG * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author Alexander Wenzel * * \copyright Copyright © 2011-2015 BMW AG. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file dlt-test-client.c */ /******************************************************************************* ** ** ** SRC-MODULE: dlt-test-client.c ** ** ** ** TARGET : linux ** ** ** ** PROJECT : DLT ** ** ** ** AUTHOR : Alexander Wenzel Alexander.AW.Wenzel@bmw.de ** ** Markus Klein ** ** ** ** PURPOSE : ** ** ** ** REMARKS : ** ** ** ** PLATFORM DEPENDANT [yes/no]: yes ** ** ** ** TO BE CHANGED BY USER [yes/no]: no ** ** ** *******************************************************************************/ /******************************************************************************* ** Author Identity ** ******************************************************************************** ** ** ** Initials Name Company ** ** -------- ------------------------- ---------------------------------- ** ** aw Alexander Wenzel BMW ** ** mk Markus Klein Fraunhofer ESK ** *******************************************************************************/ /******************************************************************************* ** Revision Control History ** *******************************************************************************/ /* * $LastChangedRevision: 1670 $ * $LastChangedDate: 2011-04-08 15:12:06 +0200 (Fr, 08. Apr 2011) $ * $LastChangedBy$ * Initials Date Comment * aw 13.01.2010 initial */ #include /* for isprint() */ #include /* for atoi() */ #include /* for S_IRUSR, S_IWUSR, S_IRGRP, S_IROTH */ #include /* for open() */ #include /* for strcmp() */ #include /* for writev() */ #include "dlt_client.h" #include "dlt_protocol.h" #include "dlt_user.h" #define DLT_TESTCLIENT_TEXTBUFSIZE 10024 /* Size of buffer for text output */ #define DLT_TESTCLIENT_ECU_ID "ECU1" #define DLT_TESTCLIENT_NUM_TESTS 9 static int g_testsFailed = 0; DltClient g_dltclient; /* Function prototypes */ int dlt_testclient_message_callback(DltMessage *message, void *data); typedef struct { int aflag; int sflag; int xflag; int mflag; int vflag; int yflag; char *ovalue; char *fvalue; char *tvalue; char *evalue; int bvalue; char ecuid[4]; int ohandle; DltFile file; DltFilter filter; int running_test; int test_counter_macro[DLT_TESTCLIENT_NUM_TESTS]; int test_counter_function[DLT_TESTCLIENT_NUM_TESTS]; int tests_passed; int tests_failed; int sock; } DltTestclientData; /** * Print usage information of tool. */ void usage() { char version[255]; dlt_get_version(version, 255); printf("Usage: dlt-test-client [options] hostname/serial_device_name\n"); printf("Test against received data from dlt-test-user.\n"); printf("%s \n", version); printf("Options:\n"); printf(" -a Print DLT messages; payload as ASCII\n"); printf(" -x Print DLT messages; payload as hex\n"); printf(" -m Print DLT messages; payload as hex and ASCII\n"); printf(" -s Print DLT messages; only headers\n"); printf(" -v Verbose mode\n"); printf(" -h Usage\n"); printf(" -y Serial device mode\n"); printf(" -b baudrate Serial device baudrate (Default: 115200)\n"); printf(" -e ecuid Set ECU ID (Default: ECU1)\n"); printf(" -o filename Output messages in new DLT file\n"); printf(" -f filename Enable filtering of messages\n"); } /** * Main function of tool. */ int main(int argc, char *argv[]) { DltTestclientData dltdata; int c, i; int index; /* Initialize dltdata */ dltdata.aflag = 0; dltdata.sflag = 0; dltdata.xflag = 0; dltdata.mflag = 0; dltdata.vflag = 0; dltdata.yflag = 0; dltdata.ovalue = 0; dltdata.fvalue = 0; dltdata.evalue = 0; dltdata.bvalue = 0; dltdata.ohandle = -1; dltdata.running_test = 0; for (i = 0; i < DLT_TESTCLIENT_NUM_TESTS; i++) { dltdata.test_counter_macro[i] = 0; dltdata.test_counter_function[i] = 0; } dltdata.tests_passed = 0; dltdata.tests_failed = 0; dltdata.sock = -1; /* Fetch command line arguments */ opterr = 0; while ((c = getopt (argc, argv, "vashyxmf:o:e:b:")) != -1) switch (c) { case 'v': { dltdata.vflag = 1; break; } case 'a': { dltdata.aflag = 1; break; } case 's': { dltdata.sflag = 1; break; } case 'x': { dltdata.xflag = 1; break; } case 'm': { dltdata.mflag = 1; break; } case 'h': { usage(); return -1; } case 'y': { dltdata.yflag = 1; break; } case 'f': { dltdata.fvalue = optarg; break; } case 'o': { dltdata.ovalue = optarg; break; } case 'e': { dltdata.evalue = optarg; break; } case 'b': { dltdata.bvalue = atoi(optarg); break; } case '?': { if ((optopt == 'o') || (optopt == 'f') || (optopt == 't')) fprintf (stderr, "Option -%c requires an argument.\n", optopt); else if (isprint (optopt)) fprintf (stderr, "Unknown option `-%c'.\n", optopt); else fprintf (stderr, "Unknown option character `\\x%x'.\n", optopt); /* unknown or wrong option used, show usage information and terminate */ usage(); return -1; } default: { abort (); return -1;/*for parasoft */ } } /* Initialize DLT Client */ dlt_client_init(&g_dltclient, dltdata.vflag); /* Register callback to be called when message was received */ dlt_client_register_message_callback(dlt_testclient_message_callback); /* Setup DLT Client structure */ g_dltclient.mode = dltdata.yflag; if (g_dltclient.mode == 0) { for (index = optind; index < argc; index++) if (dlt_client_set_server_ip(&g_dltclient, argv[index]) == -1) { fprintf(stderr, "set server ip didn't succeed\n"); return -1; } if (g_dltclient.servIP == 0) { /* no hostname selected, show usage and terminate */ fprintf(stderr, "ERROR: No hostname selected\n"); usage(); dlt_client_cleanup(&g_dltclient, dltdata.vflag); return -1; } } else { for (index = optind; index < argc; index++) if (dlt_client_set_serial_device(&g_dltclient, argv[index]) == -1) { fprintf(stderr, "set serial device didn't succeed\n"); return -1; } if (g_dltclient.serialDevice == 0) { /* no serial device name selected, show usage and terminate */ fprintf(stderr, "ERROR: No serial device name specified\n"); usage(); return -1; } dlt_client_setbaudrate(&g_dltclient, dltdata.bvalue); } /* initialise structure to use DLT file */ dlt_file_init(&(dltdata.file), dltdata.vflag); /* first parse filter file if filter parameter is used */ dlt_filter_init(&(dltdata.filter), dltdata.vflag); if (dltdata.fvalue) { if (dlt_filter_load(&(dltdata.filter), dltdata.fvalue, dltdata.vflag) < DLT_RETURN_OK) { dlt_file_free(&(dltdata.file), dltdata.vflag); return -1; } dlt_file_set_filter(&(dltdata.file), &(dltdata.filter), dltdata.vflag); } /* open DLT output file */ if (dltdata.ovalue) { dltdata.ohandle = open(dltdata.ovalue, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); /* mode: wb */ if (dltdata.ohandle == -1) { dlt_file_free(&(dltdata.file), dltdata.vflag); fprintf(stderr, "ERROR: Output file %s cannot be opened!\n", dltdata.ovalue); return -1; } } if (dltdata.evalue) dlt_set_id(dltdata.ecuid, dltdata.evalue); else dlt_set_id(dltdata.ecuid, DLT_TESTCLIENT_ECU_ID); /* Connect to TCP socket or open serial device */ if (dlt_client_connect(&g_dltclient, dltdata.vflag) != DLT_RETURN_ERROR) { dltdata.sock = g_dltclient.sock; /* Dlt Client Main Loop */ dlt_client_main_loop(&g_dltclient, &dltdata, dltdata.vflag); /* Dlt Client Cleanup */ dlt_client_cleanup(&g_dltclient, dltdata.vflag); } /* dlt-receive cleanup */ if (dltdata.ovalue) close(dltdata.ohandle); dlt_file_free(&(dltdata.file), dltdata.vflag); dlt_filter_free(&(dltdata.filter), dltdata.vflag); return g_testsFailed == 0 ? 0 : 1; } int dlt_testclient_message_callback(DltMessage *message, void *data) { static char text[DLT_TESTCLIENT_TEXTBUFSIZE]; int mtin; DltTestclientData *dltdata; uint32_t type_info, type_info_tmp; int16_t length, length_tmp; /* the macro can set this variable to -1 */ uint32_t length_tmp32 = 0; uint8_t *ptr; int32_t datalength; uint32_t id, id_tmp; int slen; int tc_old; struct iovec iov[2]; int bytes_written; if ((message == 0) || (data == 0)) return -1; dltdata = (DltTestclientData *)data; /* prepare storage header */ if (DLT_IS_HTYP_WEID(message->standardheader->htyp)) dlt_set_storageheader(message->storageheader, message->headerextra.ecu); else dlt_set_storageheader(message->storageheader, dltdata->ecuid); if ((dltdata->fvalue == 0) || (dltdata->fvalue && (dlt_message_filter_check(message, &(dltdata->filter), dltdata->vflag) == DLT_RETURN_TRUE))) { dlt_message_header(message, text, sizeof(text), dltdata->vflag); if (dltdata->aflag) printf("%s ", text); dlt_message_payload(message, text, sizeof(text), DLT_OUTPUT_ASCII, dltdata->vflag); if (dltdata->aflag) printf("[%s]\n", text); if (strcmp(text, "Tests starting") == 0) printf("Tests starting\n"); /* check test 1m */ if (strcmp(text, "Test1: (Macro IF) Test all log levels") == 0) { printf("Test1m: (Macro IF) Test all log levels\n"); dltdata->running_test = 1; dltdata->test_counter_macro[0] = 0; } else if (strcmp(text, "Test1: (Macro IF) finished") == 0) { /* >=4, as "info" is default log level */ if (dltdata->test_counter_macro[0] >= 4) { printf("Test1m PASSED\n"); dltdata->tests_passed++; } else { printf("Test1m FAILED\n"); dltdata->tests_failed++; } dltdata->running_test = 0; } else if (dltdata->running_test == 1) { if (DLT_IS_HTYP_UEH(message->standardheader->htyp)) { if ((DLT_GET_MSIN_MSTP(message->extendedheader->msin)) == DLT_TYPE_LOG) { mtin = DLT_GET_MSIN_MTIN(message->extendedheader->msin); if (mtin == DLT_LOG_FATAL) dltdata->test_counter_macro[0]++; if (mtin == DLT_LOG_ERROR) dltdata->test_counter_macro[0]++; if (mtin == DLT_LOG_WARN) dltdata->test_counter_macro[0]++; if (mtin == DLT_LOG_INFO) dltdata->test_counter_macro[0]++; if (mtin == DLT_LOG_DEBUG) dltdata->test_counter_macro[0]++; if (mtin == DLT_LOG_VERBOSE) dltdata->test_counter_macro[0]++; } } } /* check test 2m */ if (strcmp(text, "Test2: (Macro IF) Test all variable types (verbose)") == 0) { printf("Test2m: (Macro IF) Test all variable types (verbose)\n"); dltdata->running_test = 2; dltdata->test_counter_macro[1] = 0; } else if (strcmp(text, "Test2: (Macro IF) finished") == 0) { if (dltdata->test_counter_macro[1] == 16) { printf("Test2m PASSED\n"); dltdata->tests_passed++; } else { printf("Test2m FAILED\n"); dltdata->tests_failed++; } dltdata->running_test = 0; } else if (dltdata->running_test == 2) { /* Verbose */ if (!(DLT_MSG_IS_NONVERBOSE(message))) { type_info = 0; type_info_tmp = 0; length = 0; /* the macro can set this variable to -1 */ length_tmp = 0; ptr = message->databuffer; datalength = message->datasize; /* Log message */ if ((DLT_GET_MSIN_MSTP(message->extendedheader->msin)) == DLT_TYPE_LOG) { if (message->extendedheader->noar >= 2) { /* get type of first argument: must be string */ DLT_MSG_READ_VALUE(type_info_tmp, ptr, datalength, uint32_t); type_info = DLT_ENDIAN_GET_32(message->standardheader->htyp, type_info_tmp); if (type_info & DLT_TYPE_INFO_STRG) { /* skip string */ DLT_MSG_READ_VALUE(length_tmp, ptr, datalength, uint16_t); length = DLT_ENDIAN_GET_16(message->standardheader->htyp, length_tmp); if (length >= 0) { ptr += length; datalength -= length; /* read type of second argument: must be raw */ DLT_MSG_READ_VALUE(type_info_tmp, ptr, datalength, uint32_t); type_info = DLT_ENDIAN_GET_32(message->standardheader->htyp, type_info_tmp); if ((type_info & DLT_TYPE_INFO_STRG) && ((type_info & DLT_TYPE_INFO_SCOD) == DLT_SCOD_ASCII)) { if (datalength == (sizeof(uint16_t) + strlen("Hello world") + 1)) dltdata->test_counter_macro[1]++; } else if ((type_info & DLT_TYPE_INFO_STRG) && ((type_info & DLT_TYPE_INFO_SCOD) == DLT_SCOD_UTF8)) { if (datalength == (sizeof(uint16_t) + strlen("Hello world") + 1)) dltdata->test_counter_macro[1]++; } else if (type_info & DLT_TYPE_INFO_BOOL) { if (datalength == sizeof(uint8_t)) dltdata->test_counter_macro[1]++; } else if (type_info & DLT_TYPE_INFO_SINT) { switch (type_info & DLT_TYPE_INFO_TYLE) { case DLT_TYLE_8BIT: { if (datalength == sizeof(int8_t)) dltdata->test_counter_macro[1]++; break; } case DLT_TYLE_16BIT: { if (datalength == sizeof(int16_t)) dltdata->test_counter_macro[1]++; break; } case DLT_TYLE_32BIT: { if (datalength == sizeof(int32_t)) dltdata->test_counter_macro[1]++; break; } case DLT_TYLE_64BIT: { if (datalength == sizeof(int64_t)) dltdata->test_counter_macro[1]++; break; } case DLT_TYLE_128BIT: { /* Not tested here */ break; } } } else if (type_info & DLT_TYPE_INFO_UINT) { switch (type_info & DLT_TYPE_INFO_TYLE) { case DLT_TYLE_8BIT: { if (datalength == sizeof(uint8_t)) dltdata->test_counter_macro[1]++; break; } case DLT_TYLE_16BIT: { if (datalength == sizeof(uint16_t)) dltdata->test_counter_macro[1]++; break; } case DLT_TYLE_32BIT: { if (datalength == sizeof(uint32_t)) dltdata->test_counter_macro[1]++; break; } case DLT_TYLE_64BIT: { if (datalength == sizeof(uint64_t)) dltdata->test_counter_macro[1]++; break; } case DLT_TYLE_128BIT: { /* Not tested here */ break; } } } else if (type_info & DLT_TYPE_INFO_FLOA) { switch (type_info & DLT_TYPE_INFO_TYLE) { case DLT_TYLE_8BIT: { /* Not tested here */ break; } case DLT_TYLE_16BIT: { /* Not tested here */ break; } case DLT_TYLE_32BIT: { if (datalength == (2 * sizeof(float) + sizeof(uint32_t))) dltdata->test_counter_macro[1]++; break; } case DLT_TYLE_64BIT: { if (datalength == (2 * sizeof(double) + sizeof(uint32_t))) dltdata->test_counter_macro[1]++; break; } case DLT_TYLE_128BIT: /* Not tested here */ break; } } else if (type_info & DLT_TYPE_INFO_RAWD) { /* Get length */ DLT_MSG_READ_VALUE(length_tmp, ptr, datalength, uint16_t); length = DLT_ENDIAN_GET_16(message->standardheader->htyp, length_tmp); if ((length == datalength) && (10 == length)) dltdata->test_counter_macro[1]++; } } } } } } } /* check test 3m */ if (strcmp(text, "Test3: (Macro IF) Test all variable types (non-verbose)") == 0) { printf("Test3m: (Macro IF) Test all variable types (non-verbose)\n"); dltdata->running_test = 3; dltdata->test_counter_macro[2] = 0; } else if (strcmp(text, "Test3: (Macro IF) finished") == 0) { if (dltdata->test_counter_macro[2] == 16) { printf("Test3m PASSED\n"); dltdata->tests_passed++; } else { printf("Test3m FAILED\n"); dltdata->tests_failed++; } dltdata->running_test = 0; } else if (dltdata->running_test == 3) { /* Nonverbose */ if (DLT_MSG_IS_NONVERBOSE(message)) { id = 0; id_tmp = 0; ptr = message->databuffer; datalength = message->datasize; slen = -1; tc_old = dltdata->test_counter_macro[2]; /* Get message id */ DLT_MSG_READ_VALUE(id_tmp, ptr, datalength, uint32_t); id = DLT_ENDIAN_GET_32(message->standardheader->htyp, id_tmp); /* Length of string */ datalength -= sizeof(uint16_t); ptr += sizeof(uint16_t); switch (id) { case 1: { slen = strlen("string") + 1; datalength -= slen; ptr += slen; if (datalength == sizeof(uint16_t) + strlen("Hello world") + 1) dltdata->test_counter_macro[2]++; break; } case 2: { slen = strlen("utf8") + 1; datalength -= slen; ptr += slen; if (datalength == sizeof(uint16_t) + strlen("Hello world") + 1) dltdata->test_counter_macro[2]++; break; } case 3: { slen = strlen("bool") + 1; datalength -= slen; ptr += slen; if (datalength == sizeof(uint8_t)) dltdata->test_counter_macro[2]++; break; } case 4: { slen = strlen("int") + 1; datalength -= slen; ptr += slen; if (datalength == sizeof(int)) dltdata->test_counter_macro[2]++; break; } case 5: { slen = strlen("int8") + 1; datalength -= slen; ptr += slen; if (datalength == sizeof(int8_t)) dltdata->test_counter_macro[2]++; break; } case 6: { slen = strlen("int16") + 1; datalength -= slen; ptr += slen; if (datalength == sizeof(int16_t)) dltdata->test_counter_macro[2]++; break; } case 7: { slen = strlen("int32") + 1; datalength -= slen; ptr += slen; if (datalength == sizeof(int32_t)) dltdata->test_counter_macro[2]++; break; } case 8: { slen = strlen("int64") + 1; datalength -= slen; ptr += slen; if (datalength == sizeof(int64_t)) dltdata->test_counter_macro[2]++; break; } case 9: { slen = strlen("uint") + 1; datalength -= slen; ptr += slen; if (datalength == sizeof(unsigned int)) dltdata->test_counter_macro[2]++; break; } case 10: { slen = strlen("uint8") + 1; datalength -= slen; ptr += slen; if (datalength == sizeof(uint8_t)) dltdata->test_counter_macro[2]++; break; } case 11: { slen = strlen("uint16") + 1; datalength -= slen; ptr += slen; if (datalength == sizeof(uint16_t)) dltdata->test_counter_macro[2]++; break; } case 12: { slen = strlen("uint32") + 1; datalength -= slen; ptr += slen; if (datalength == sizeof(uint32_t)) dltdata->test_counter_macro[2]++; break; } case 13: { slen = strlen("uint64") + 1; datalength -= slen; ptr += slen; if (datalength == sizeof(uint64_t)) dltdata->test_counter_macro[2]++; break; } case 14: { slen = strlen("float32") + 1; datalength -= slen; ptr += slen; /* 2*, as the min and the max is transfered */ if (datalength == 2 * sizeof(float)) dltdata->test_counter_macro[2]++; break; } case 15: { slen = strlen("float64") + 1; datalength -= slen; ptr += slen; /* 2*, as the min and the max is transfered */ if (datalength == 2 * sizeof(double)) dltdata->test_counter_macro[2]++; break; } case 16: { slen = strlen("raw") + 1; datalength -= slen; ptr += slen; datalength -= sizeof(uint16_t); ptr += sizeof(uint16_t); if (datalength == 10) dltdata->test_counter_macro[2]++; break; } } if ((slen >= 0) && (tc_old == dltdata->test_counter_macro[2])) printf("ID=%d, Datalength=%d => Failed!", id, datalength); } } /* check test 4m */ if (strcmp(text, "Test4: (Macro IF) Test different message sizes") == 0) { printf("Test4m: (Macro IF) Test different message sizes\n"); dltdata->running_test = 4; dltdata->test_counter_macro[3] = 0; } else if (strcmp(text, "Test4: (Macro IF) finished") == 0) { if (dltdata->test_counter_macro[3] == 4) { printf("Test4m PASSED\n"); dltdata->tests_passed++; } else { printf("Test4m FAILED\n"); dltdata->tests_failed++; } dltdata->running_test = 0; } else if (dltdata->running_test == 4) { /* Extended header */ if (DLT_IS_HTYP_UEH(message->standardheader->htyp)) { /* Log message */ if ((DLT_GET_MSIN_MSTP(message->extendedheader->msin)) == DLT_TYPE_LOG) { /* Verbose */ if (DLT_IS_MSIN_VERB(message->extendedheader->msin)) { /* 2 arguments */ if (message->extendedheader->noar == 2) { /* verbose mode */ type_info = 0; type_info_tmp = 0; length = 0; length_tmp = 0; /* the macro can set this variable to -1 */ ptr = message->databuffer; datalength = message->datasize; /* first read the type info of the first argument: must be string */ DLT_MSG_READ_VALUE(type_info_tmp, ptr, datalength, uint32_t); type_info = DLT_ENDIAN_GET_32(message->standardheader->htyp, type_info_tmp); if (type_info & DLT_TYPE_INFO_STRG) { /* skip string */ DLT_MSG_READ_VALUE(length_tmp, ptr, datalength, uint16_t); length = DLT_ENDIAN_GET_16(message->standardheader->htyp, length_tmp); if (length >= 0) { ptr += length; datalength -= length; /* read type of second argument: must be raw */ DLT_MSG_READ_VALUE(type_info_tmp, ptr, datalength, uint32_t); type_info = DLT_ENDIAN_GET_32(message->standardheader->htyp, type_info_tmp); if (type_info & DLT_TYPE_INFO_RAWD) { /* get length of raw data block */ DLT_MSG_READ_VALUE(length_tmp, ptr, datalength, uint16_t); length = DLT_ENDIAN_GET_16(message->standardheader->htyp, length_tmp); if ((length >= 0) && (length == datalength)) /*printf("Raw data found in payload, length="); */ /*printf("%d, datalength=%d \n", length, datalength); */ dltdata->test_counter_macro[3]++; } } } } } } } } /* check test 5m */ if (strcmp(text, "Test5: (Macro IF) Test high-level API") == 0) { printf("Test5m: (Macro IF) Test high-level API\n"); dltdata->running_test = 5; dltdata->test_counter_macro[4] = 0; } else if (strcmp(text, "Test5: (Macro IF) finished") == 0) { if (dltdata->test_counter_macro[4] == 12) { printf("Test5m PASSED\n"); dltdata->tests_passed++; } else { printf("Test5m FAILED\n"); dltdata->tests_failed++; } dltdata->running_test = 0; } else if (dltdata->running_test == 5) { if (strcmp(text, "Next line: DLT_LOG_INT") == 0) dltdata->test_counter_macro[4]++; if (strcmp(text, "-42") == 0) dltdata->test_counter_macro[4]++; if (strcmp(text, "Next line: DLT_LOG_UINT") == 0) dltdata->test_counter_macro[4]++; if (strcmp(text, "42") == 0) dltdata->test_counter_macro[4]++; if (strcmp(text, "Next line: DLT_LOG_STRING") == 0) dltdata->test_counter_macro[4]++; if (strcmp(text, "String output") == 0) dltdata->test_counter_macro[4]++; if (strcmp(text, "Next line: DLT_LOG_RAW") == 0) dltdata->test_counter_macro[4]++; if (strcmp(text, "00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f") == 0) dltdata->test_counter_macro[4]++; if (strcmp(text, "Next line: DLT_LOG_STRING_INT") == 0) dltdata->test_counter_macro[4]++; if (strcmp(text, "String output: -42") == 0) dltdata->test_counter_macro[4]++; if (strcmp(text, "Next line: DLT_LOG_STRING_UINT") == 0) dltdata->test_counter_macro[4]++; if (strcmp(text, "String output: 42") == 0) dltdata->test_counter_macro[4]++; } /* check test 6m */ if (strcmp(text, "Test 6: (Macro IF) Test local printing") == 0) { printf("Test6m: (Macro IF) Test local printing\n"); dltdata->running_test = 6; dltdata->test_counter_macro[5] = 0; } else if (strcmp(text, "Test6: (Macro IF) finished") == 0) { if (dltdata->test_counter_macro[5] == 2) { printf("Test6m PASSED\n"); dltdata->tests_passed++; } else { printf("Test6m FAILED\n"); dltdata->tests_failed++; } dltdata->running_test = 0; } else if (dltdata->running_test == 6) { if (strcmp(text, "Message (visible: locally printed)") == 0) { printf("Message (visible: locally printed)\n"); dltdata->test_counter_macro[5]++; } if (strcmp(text, "Message (invisible: not locally printed)") == 0) { printf("Message (invisible: not locally printed)\n"); dltdata->test_counter_macro[5]++; } } /* check test 7m */ if (strcmp(text, "Test 7: (Macro IF) Test network trace") == 0) { printf("Test7m: (Macro IF) Test network trace\n"); dltdata->running_test = 7; dltdata->test_counter_macro[6] = 0; } else if (strcmp(text, "Test7: (Macro IF) finished") == 0) { if (dltdata->test_counter_macro[6] == 8) { printf("Test7m PASSED\n"); dltdata->tests_passed++; } else { printf("Test7m FAILED\n"); dltdata->tests_failed++; } dltdata->running_test = 0; } else if (dltdata->running_test == 7) { if (DLT_IS_HTYP_UEH(message->standardheader->htyp)) { if ((DLT_GET_MSIN_MSTP(message->extendedheader->msin)) == DLT_TYPE_NW_TRACE) { /* Check message type information*/ /* Each correct message type increases the counter by 1 */ mtin = DLT_GET_MSIN_MTIN(message->extendedheader->msin); if (mtin == DLT_NW_TRACE_IPC) dltdata->test_counter_macro[6]++; if (mtin == DLT_NW_TRACE_CAN) dltdata->test_counter_macro[6]++; if (mtin == DLT_NW_TRACE_FLEXRAY) dltdata->test_counter_macro[6]++; if (mtin == DLT_NW_TRACE_MOST) dltdata->test_counter_macro[6]++; /* Check payload, must be two arguments (2 raw data blocks) */ /* If the payload is correct, the counter is increased by 1 */ if (message->extendedheader->noar == 2) { /* verbose mode */ type_info = 0; type_info_tmp = 0; length = 0, length_tmp = 0; /* the macro can set this variable to -1 */ ptr = message->databuffer; datalength = message->datasize; /* first read the type info of the first argument: must be string */ DLT_MSG_READ_VALUE(type_info_tmp, ptr, datalength, uint32_t); type_info = DLT_ENDIAN_GET_32(message->standardheader->htyp, type_info_tmp); if (type_info & DLT_TYPE_INFO_RAWD) { /* skip string */ DLT_MSG_READ_VALUE(length_tmp, ptr, datalength, uint16_t); length = DLT_ENDIAN_GET_16(message->standardheader->htyp, length_tmp); if (length >= 0) { ptr += length; datalength -= length; /* read type of second argument: must be raw */ DLT_MSG_READ_VALUE(type_info_tmp, ptr, datalength, uint32_t); type_info = DLT_ENDIAN_GET_32(message->standardheader->htyp, type_info_tmp); if (type_info & DLT_TYPE_INFO_RAWD) { /* get length of raw data block */ DLT_MSG_READ_VALUE(length_tmp, ptr, datalength, uint16_t); length = DLT_ENDIAN_GET_16(message->standardheader->htyp, length_tmp); if ((length >= 0) && (length == datalength)) /*printf("Raw data found in payload, length="); */ /*printf("%d, datalength=%d \n", length, datalength); */ dltdata->test_counter_macro[6]++; } } } } } } } /* check test 8m */ if (strcmp(text, "Test 8: (Macro IF) Test truncated network trace") == 0) { printf("Test8m: (Macro IF) Test truncated network trace\n"); dltdata->running_test = 8; dltdata->test_counter_macro[7] = 0; } else if (strcmp(text, "Test8: (Macro IF) finished") == 0) { if (dltdata->test_counter_macro[7] == 20) { printf("Test8m PASSED\n"); dltdata->tests_passed++; } else { printf("Test8m FAILED\n"); dltdata->tests_failed++; } dltdata->running_test = 0; } else if (dltdata->running_test == 8) { if (DLT_IS_HTYP_UEH(message->standardheader->htyp)) { if ((DLT_GET_MSIN_MSTP(message->extendedheader->msin)) == DLT_TYPE_NW_TRACE) { /* Check message type information*/ /* Each correct message type increases the counter by 1 */ mtin = DLT_GET_MSIN_MTIN(message->extendedheader->msin); if (mtin == DLT_NW_TRACE_IPC) dltdata->test_counter_macro[7]++; if (mtin == DLT_NW_TRACE_CAN) dltdata->test_counter_macro[7]++; if (mtin == DLT_NW_TRACE_FLEXRAY) dltdata->test_counter_macro[7]++; if (mtin == DLT_NW_TRACE_MOST) dltdata->test_counter_macro[7]++; /* Check payload, must be two arguments (2 raw data blocks) */ /* If the payload is correct, the counter is increased by 1 */ if (message->extendedheader->noar == 4) { type_info = 0; type_info_tmp = 0; length = 0, length_tmp = 0; /* the macro can set this variable to -1 */ ptr = message->databuffer; datalength = message->datasize; DLT_MSG_READ_VALUE(type_info_tmp, ptr, datalength, uint32_t); type_info = DLT_ENDIAN_GET_32(message->standardheader->htyp, type_info_tmp); if (type_info & DLT_TYPE_INFO_STRG) { /* Read NWTR */ char chdr[10]; DLT_MSG_READ_VALUE(length_tmp, ptr, datalength, uint16_t); length = DLT_ENDIAN_GET_16(message->standardheader->htyp, length_tmp); DLT_MSG_READ_STRING(chdr, ptr, datalength, length); if (strcmp((char *)chdr, DLT_TRACE_NW_TRUNCATED) == 0) dltdata->test_counter_macro[7]++; DLT_MSG_READ_VALUE(type_info_tmp, ptr, datalength, uint32_t); type_info = DLT_ENDIAN_GET_32(message->standardheader->htyp, type_info_tmp); if (type_info & DLT_TYPE_INFO_RAWD) { char hdr[2048]; DLT_MSG_READ_VALUE(length_tmp, ptr, datalength, uint16_t); length = DLT_ENDIAN_GET_16(message->standardheader->htyp, length_tmp); DLT_MSG_READ_STRING(hdr, ptr, datalength, length); if ((length == 16) && (hdr[15] == 15)) dltdata->test_counter_macro[7]++; DLT_MSG_READ_VALUE(type_info_tmp, ptr, datalength, uint32_t); type_info = DLT_ENDIAN_GET_32(message->standardheader->htyp, type_info_tmp); if (type_info & DLT_TYPE_INFO_UINT) { uint32_t orig_size; DLT_MSG_READ_VALUE(length_tmp32, ptr, datalength, uint32_t); orig_size = DLT_ENDIAN_GET_32(message->standardheader->htyp, length_tmp32); if (orig_size == 1024 * 5) dltdata->test_counter_macro[7]++; DLT_MSG_READ_VALUE(type_info_tmp, ptr, datalength, uint32_t); type_info = DLT_ENDIAN_GET_32(message->standardheader->htyp, type_info_tmp); if (type_info & DLT_TYPE_INFO_RAWD) { DLT_MSG_READ_VALUE(length_tmp, ptr, datalength, uint16_t); length = DLT_ENDIAN_GET_16(message->standardheader->htyp, length_tmp); /* Size of the truncated message after headers */ if (length == DLT_USER_BUF_MAX_SIZE - 41 - sizeof(uint16_t) - sizeof(uint32_t)) dltdata->test_counter_macro[7]++; } } } } } } } } /* check test 9m */ if (strcmp(text, "Test 9: (Macro IF) Test segmented network trace") == 0) { printf("Test9m: (Macro IF) Test segmented network trace\n"); dltdata->running_test = 9; dltdata->test_counter_macro[8] = 0; } else if (strcmp(text, "Test9: (Macro IF) finished") == 0) { /* (Interface types) * (results per packet)*/ if (dltdata->test_counter_macro[8] == 4 * 35) { printf("Test9m PASSED\n"); dltdata->tests_passed++; } else { printf("Test9m FAILED\n"); dltdata->tests_failed++; } dltdata->running_test = 0; } else if (dltdata->running_test == 9) { if (DLT_IS_HTYP_UEH(message->standardheader->htyp)) { if ((DLT_GET_MSIN_MSTP(message->extendedheader->msin)) == DLT_TYPE_NW_TRACE) { /* Check message type information*/ /* Each correct message type increases the counter by 1 */ mtin = DLT_GET_MSIN_MTIN(message->extendedheader->msin); if (mtin == DLT_NW_TRACE_IPC) dltdata->test_counter_macro[8]++; if (mtin == DLT_NW_TRACE_CAN) dltdata->test_counter_macro[8]++; if (mtin == DLT_NW_TRACE_FLEXRAY) dltdata->test_counter_macro[8]++; if (mtin == DLT_NW_TRACE_MOST) dltdata->test_counter_macro[8]++; /* Payload for first segmented message */ if (message->extendedheader->noar == 6) { /* verbose mode */ type_info = 0; type_info_tmp = 0; length = 0, length_tmp = 0; /* the macro can set this variable to -1 */ ptr = message->databuffer; datalength = message->datasize; /* NWST */ DLT_MSG_READ_VALUE(type_info_tmp, ptr, datalength, uint32_t); type_info = DLT_ENDIAN_GET_32(message->standardheader->htyp, type_info_tmp); if (type_info & DLT_TYPE_INFO_STRG) { char chdr[10]; DLT_MSG_READ_VALUE(length_tmp, ptr, datalength, uint16_t); length = DLT_ENDIAN_GET_16(message->standardheader->htyp, length_tmp); DLT_MSG_READ_STRING(chdr, ptr, datalength, length); if (strcmp((char *)chdr, DLT_TRACE_NW_START) == 0) dltdata->test_counter_macro[8]++; /* Streahandle */ DLT_MSG_READ_VALUE(type_info_tmp, ptr, datalength, uint32_t); type_info = DLT_ENDIAN_GET_32(message->standardheader->htyp, type_info_tmp); if (type_info & DLT_TYPE_INFO_UINT) { uint32_t handle; DLT_MSG_READ_VALUE(length_tmp32, ptr, datalength, uint32_t); handle = DLT_ENDIAN_GET_32(message->standardheader->htyp, length_tmp32); if (handle > 0) dltdata->test_counter_macro[8]++; /* Header */ DLT_MSG_READ_VALUE(type_info_tmp, ptr, datalength, uint32_t); type_info = DLT_ENDIAN_GET_32(message->standardheader->htyp, type_info_tmp); if (type_info & DLT_TYPE_INFO_RAWD) { DLT_MSG_READ_VALUE(length_tmp, ptr, datalength, uint16_t); length = DLT_ENDIAN_GET_16(message->standardheader->htyp, length_tmp); /* Test packet header size 16 */ if (length == 16) dltdata->test_counter_macro[8]++; /* Skip data */ ptr += length; datalength -= length; /* Payload size */ DLT_MSG_READ_VALUE(type_info_tmp, ptr, datalength, uint32_t); type_info = DLT_ENDIAN_GET_32(message->standardheader->htyp, type_info_tmp); if (type_info & DLT_TYPE_INFO_UINT) { uint32_t pl_sz; DLT_MSG_READ_VALUE(length_tmp32, ptr, datalength, uint32_t); pl_sz = DLT_ENDIAN_GET_32(message->standardheader->htyp, length_tmp32); /* Test packet payload size. */ if (pl_sz == 5120) dltdata->test_counter_macro[8]++; /* Segmentcount */ DLT_MSG_READ_VALUE(type_info_tmp, ptr, datalength, uint32_t); type_info = DLT_ENDIAN_GET_32(message->standardheader->htyp, type_info_tmp); if (type_info & DLT_TYPE_INFO_UINT) { uint16_t scount; DLT_MSG_READ_VALUE(length_tmp, ptr, datalength, uint16_t); scount = DLT_ENDIAN_GET_16(message->standardheader->htyp, length_tmp); /* Test packet segment count 5 */ if (scount == 5) dltdata->test_counter_macro[8]++; /* Segment length */ DLT_MSG_READ_VALUE(type_info_tmp, ptr, datalength, uint32_t); type_info = DLT_ENDIAN_GET_32(message->standardheader->htyp, type_info_tmp); if (type_info & DLT_TYPE_INFO_UINT) { uint16_t slen; DLT_MSG_READ_VALUE(length_tmp, ptr, datalength, uint16_t); slen = DLT_ENDIAN_GET_16(message->standardheader->htyp, length_tmp); /* Default segment size 1024 */ if (slen == 1024) dltdata->test_counter_macro[8]++; } } } } } } } /* Data segment */ else if (message->extendedheader->noar == 4) { /* verbose mode */ type_info = 0; type_info_tmp = 0; length = 0, length_tmp = 0; /* the macro can set this variable to -1 */ ptr = message->databuffer; datalength = message->datasize; /* NWCH */ DLT_MSG_READ_VALUE(type_info_tmp, ptr, datalength, uint32_t); type_info = DLT_ENDIAN_GET_32(message->standardheader->htyp, type_info_tmp); if (type_info & DLT_TYPE_INFO_STRG) { char chdr[10]; DLT_MSG_READ_VALUE(length_tmp, ptr, datalength, uint16_t); length = DLT_ENDIAN_GET_16(message->standardheader->htyp, length_tmp); DLT_MSG_READ_STRING(chdr, ptr, datalength, length); if (strcmp((char *)chdr, DLT_TRACE_NW_SEGMENT) == 0) dltdata->test_counter_macro[8]++; /* handle */ DLT_MSG_READ_VALUE(type_info_tmp, ptr, datalength, uint32_t); type_info = DLT_ENDIAN_GET_32(message->standardheader->htyp, type_info_tmp); if (type_info & DLT_TYPE_INFO_UINT) { uint32_t handle; DLT_MSG_READ_VALUE(length_tmp32, ptr, datalength, uint32_t); handle = DLT_ENDIAN_GET_32(message->standardheader->htyp, length_tmp32); if (handle > 0) dltdata->test_counter_macro[8]++; /* Sequence */ DLT_MSG_READ_VALUE(type_info_tmp, ptr, datalength, uint32_t); type_info = DLT_ENDIAN_GET_32(message->standardheader->htyp, type_info_tmp); if (type_info & DLT_TYPE_INFO_UINT) { /*uint16_t seq; */ DLT_MSG_READ_VALUE(length_tmp, ptr, datalength, uint16_t); /*seq=DLT_ENDIAN_GET_16(message->standardheader->htyp, length_tmp); */ dltdata->test_counter_macro[8]++; /* Data */ DLT_MSG_READ_VALUE(type_info_tmp, ptr, datalength, uint32_t); type_info = DLT_ENDIAN_GET_32(message->standardheader->htyp, type_info_tmp); if (type_info & DLT_TYPE_INFO_RAWD) { DLT_MSG_READ_VALUE(length_tmp, ptr, datalength, uint16_t); length = DLT_ENDIAN_GET_16(message->standardheader->htyp, length_tmp); /* Segment size by default, 1024 */ if (length == 1024) dltdata->test_counter_macro[8]++; } } } } } /* End segment */ else if (message->extendedheader->noar == 2) { /* verbose mode */ type_info = 0; type_info_tmp = 0; length = 0, length_tmp = 0; /* the macro can set this variable to -1 */ ptr = message->databuffer; datalength = message->datasize; /* NWEN */ DLT_MSG_READ_VALUE(type_info_tmp, ptr, datalength, uint32_t); type_info = DLT_ENDIAN_GET_32(message->standardheader->htyp, type_info_tmp); if (type_info & DLT_TYPE_INFO_STRG) { char chdr[10]; DLT_MSG_READ_VALUE(length_tmp, ptr, datalength, uint16_t); length = DLT_ENDIAN_GET_16(message->standardheader->htyp, length_tmp); DLT_MSG_READ_STRING(chdr, ptr, datalength, length); if (strcmp((char *)chdr, DLT_TRACE_NW_END) == 0) dltdata->test_counter_macro[8]++; /* handle */ DLT_MSG_READ_VALUE(type_info_tmp, ptr, datalength, uint32_t); type_info = DLT_ENDIAN_GET_32(message->standardheader->htyp, type_info_tmp); if (type_info & DLT_TYPE_INFO_UINT) { uint32_t handle; DLT_MSG_READ_VALUE(length_tmp32, ptr, datalength, uint32_t); handle = DLT_ENDIAN_GET_32(message->standardheader->htyp, length_tmp32); if (handle > 0) dltdata->test_counter_macro[8]++; } } } } } } /* check test 1f */ if (strcmp(text, "Test1: (Function IF) Test all log levels") == 0) { printf("Test1f: (Function IF) Test all log levels\n"); dltdata->running_test = 10; dltdata->test_counter_function[0] = 0; } else if (strcmp(text, "Test1: (Function IF) finished") == 0) { /* >=4, as "info" is default log level */ if (dltdata->test_counter_function[0] >= 4) { printf("Test1f PASSED\n"); dltdata->tests_passed++; } else { printf("Test1f FAILED\n"); dltdata->tests_failed++; } dltdata->running_test = 0; } else if (dltdata->running_test == 10) { if (DLT_IS_HTYP_UEH(message->standardheader->htyp)) { if ((DLT_GET_MSIN_MSTP(message->extendedheader->msin)) == DLT_TYPE_LOG) { mtin = DLT_GET_MSIN_MTIN(message->extendedheader->msin); if (mtin == DLT_LOG_FATAL) dltdata->test_counter_function[0]++; if (mtin == DLT_LOG_ERROR) dltdata->test_counter_function[0]++; if (mtin == DLT_LOG_WARN) dltdata->test_counter_function[0]++; if (mtin == DLT_LOG_INFO) dltdata->test_counter_function[0]++; if (mtin == DLT_LOG_DEBUG) dltdata->test_counter_function[0]++; if (mtin == DLT_LOG_VERBOSE) dltdata->test_counter_function[0]++; } } } /* check test 2f */ if (strcmp(text, "Test2: (Function IF) Test all variable types (verbose)") == 0) { printf("Test2f: (Function IF) Test all variable types (verbose)\n"); dltdata->running_test = 11; dltdata->test_counter_function[1] = 0; } else if (strcmp(text, "Test2: (Function IF) finished") == 0) { if (dltdata->test_counter_function[1] == 14) { printf("Test2f PASSED\n"); dltdata->tests_passed++; } else { printf("Test2f FAILED\n"); dltdata->tests_failed++; } dltdata->running_test = 0; } else if (dltdata->running_test == 11) { /* Verbose */ if (!(DLT_MSG_IS_NONVERBOSE(message))) { type_info = 0; type_info_tmp = 0; length = 0; length_tmp = 0; /* the macro can set this variable to -1 */ ptr = message->databuffer; datalength = message->datasize; /* Log message */ if ((DLT_GET_MSIN_MSTP(message->extendedheader->msin)) == DLT_TYPE_LOG) { if (message->extendedheader->noar >= 2) { /* get type of first argument: must be string */ DLT_MSG_READ_VALUE(type_info_tmp, ptr, datalength, uint32_t); type_info = DLT_ENDIAN_GET_32(message->standardheader->htyp, type_info_tmp); if (type_info & DLT_TYPE_INFO_STRG) { /* skip string */ DLT_MSG_READ_VALUE(length_tmp, ptr, datalength, uint16_t); length = DLT_ENDIAN_GET_16(message->standardheader->htyp, length_tmp); if (length >= 0) { ptr += length; datalength -= length; /* read type of second argument: must be raw */ DLT_MSG_READ_VALUE(type_info_tmp, ptr, datalength, uint32_t); type_info = DLT_ENDIAN_GET_32(message->standardheader->htyp, type_info_tmp); if (type_info & DLT_TYPE_INFO_BOOL) { if (datalength == sizeof(uint8_t)) dltdata->test_counter_function[1]++; } else if (type_info & DLT_TYPE_INFO_SINT) { switch (type_info & DLT_TYPE_INFO_TYLE) { case DLT_TYLE_8BIT: { if (datalength == sizeof(int8_t)) dltdata->test_counter_function[1]++; break; } case DLT_TYLE_16BIT: { if (datalength == sizeof(int16_t)) dltdata->test_counter_function[1]++; break; } case DLT_TYLE_32BIT: { if (datalength == sizeof(int32_t)) dltdata->test_counter_function[1]++; break; } case DLT_TYLE_64BIT: { if (datalength == sizeof(int64_t)) dltdata->test_counter_function[1]++; break; } case DLT_TYLE_128BIT: { /* Not tested here */ break; } } } else if (type_info & DLT_TYPE_INFO_UINT) { switch (type_info & DLT_TYPE_INFO_TYLE) { case DLT_TYLE_8BIT: { if (datalength == sizeof(uint8_t)) dltdata->test_counter_function[1]++; break; } case DLT_TYLE_16BIT: { if (datalength == sizeof(uint16_t)) dltdata->test_counter_function[1]++; break; } case DLT_TYLE_32BIT: { if (datalength == sizeof(uint32_t)) dltdata->test_counter_function[1]++; break; } case DLT_TYLE_64BIT: { if (datalength == sizeof(uint64_t)) dltdata->test_counter_function[1]++; break; } case DLT_TYLE_128BIT: { /* Not tested here */ break; } } } else if (type_info & DLT_TYPE_INFO_FLOA) { switch (type_info & DLT_TYPE_INFO_TYLE) { case DLT_TYLE_8BIT: { /* Not tested here */ break; } case DLT_TYLE_16BIT: { /* Not tested here */ break; } case DLT_TYLE_32BIT: { if (datalength == (2 * sizeof(float) + sizeof(uint32_t))) dltdata->test_counter_function[1]++; break; } case DLT_TYLE_64BIT: { if (datalength == (2 * sizeof(double) + sizeof(uint32_t))) dltdata->test_counter_function[1]++; break; } case DLT_TYLE_128BIT: { /* Not tested here */ break; } } } else if (type_info & DLT_TYPE_INFO_RAWD) { /* Get length */ DLT_MSG_READ_VALUE(length_tmp, ptr, datalength, uint16_t); length = DLT_ENDIAN_GET_16(message->standardheader->htyp, length_tmp); if ((length == datalength) && (length == 10)) dltdata->test_counter_function[1]++; } } } } } } } /* check test 3f */ if (strcmp(text, "Test3: (Function IF) Test all variable types (non-verbose)") == 0) { printf("Test3f: (Function IF) Test all variable types (non-verbose)\n"); dltdata->running_test = 12; dltdata->test_counter_function[2] = 0; } else if (strcmp(text, "Test3: (Function IF) finished") == 0) { if (dltdata->test_counter_function[2] == 14) { printf("Test3f PASSED\n"); dltdata->tests_passed++; } else { printf("Test3f FAILED\n"); dltdata->tests_failed++; } dltdata->running_test = 0; } else if (dltdata->running_test == 12) { /* Nonverbose */ if (DLT_MSG_IS_NONVERBOSE(message)) { id = 0; id_tmp = 0; ptr = message->databuffer; datalength = message->datasize; slen = -1; tc_old = dltdata->test_counter_function[2]; /* Get message id */ DLT_MSG_READ_VALUE(id_tmp, ptr, datalength, uint32_t); id = DLT_ENDIAN_GET_32(message->standardheader->htyp, id_tmp); /* Length of string */ datalength -= sizeof(uint16_t); ptr += sizeof(uint16_t); switch (id) { case 1: { slen = strlen("bool") + 1; datalength -= slen; ptr += slen; if (datalength == sizeof(uint8_t)) dltdata->test_counter_function[2]++; break; } case 2: { slen = strlen("int") + 1; datalength -= slen; ptr += slen; if (datalength == sizeof(int)) dltdata->test_counter_function[2]++; break; } case 3: { slen = strlen("int8") + 1; datalength -= slen; ptr += slen; if (datalength == sizeof(int8_t)) dltdata->test_counter_function[2]++; break; } case 4: { slen = strlen("int16") + 1; datalength -= slen; ptr += slen; if (datalength == sizeof(int16_t)) dltdata->test_counter_function[2]++; break; } case 5: { slen = strlen("int32") + 1; datalength -= slen; ptr += slen; if (datalength == sizeof(int32_t)) dltdata->test_counter_function[2]++; break; } case 6: { slen = strlen("int64") + 1; datalength -= slen; ptr += slen; if (datalength == sizeof(int64_t)) dltdata->test_counter_function[2]++; break; } case 7: { slen = strlen("uint") + 1; datalength -= slen; ptr += slen; if (datalength == sizeof(unsigned int)) dltdata->test_counter_function[2]++; break; } case 8: { slen = strlen("uint8") + 1; datalength -= slen; ptr += slen; if (datalength == sizeof(uint8_t)) dltdata->test_counter_function[2]++; break; } case 9: { slen = strlen("uint16") + 1; datalength -= slen; ptr += slen; if (datalength == sizeof(uint16_t)) dltdata->test_counter_function[2]++; break; } case 10: { slen = strlen("uint32") + 1; datalength -= slen; ptr += slen; if (datalength == sizeof(uint32_t)) dltdata->test_counter_function[2]++; break; } case 11: { slen = strlen("uint64") + 1; datalength -= slen; ptr += slen; if (datalength == sizeof(uint64_t)) dltdata->test_counter_function[2]++; break; } case 12: { slen = strlen("float32") + 1; datalength -= slen; ptr += slen; /* 2*, as the min and the max is transfered */ if (datalength == 2 * sizeof(float)) dltdata->test_counter_function[2]++; break; } case 13: { slen = strlen("float64") + 1; datalength -= slen; ptr += slen; /* 2*, as the min and the max is transfered */ if (datalength == 2 * sizeof(double)) dltdata->test_counter_function[2]++; break; } case 14: { slen = strlen("raw") + 1; datalength -= slen; ptr += slen; datalength -= sizeof(uint16_t); ptr += sizeof(uint16_t); if (datalength == 10) dltdata->test_counter_function[2]++; break; } } if ((slen >= 0) && (tc_old == dltdata->test_counter_function[2])) printf("ID=%d, Datalength=%d => Failed!", id, datalength); } } /* check test 4f */ if (strcmp(text, "Test4: (Function IF) Test different message sizes") == 0) { printf("Test4f: (Function IF) Test different message sizes\n"); dltdata->running_test = 13; dltdata->test_counter_function[3] = 0; } else if (strcmp(text, "Test4: (Function IF) finished") == 0) { if (dltdata->test_counter_function[3] == 4) { printf("Test4f PASSED\n"); dltdata->tests_passed++; } else { printf("Test4f FAILED\n"); dltdata->tests_failed++; } dltdata->running_test = 0; } else if (dltdata->running_test == 13) { /* Extended header */ if (DLT_IS_HTYP_UEH(message->standardheader->htyp)) { /* Log message */ if ((DLT_GET_MSIN_MSTP(message->extendedheader->msin)) == DLT_TYPE_LOG) { /* Verbose */ if (DLT_IS_MSIN_VERB(message->extendedheader->msin)) { /* 2 arguments */ if (message->extendedheader->noar == 2) { /* verbose mode */ type_info = 0; type_info_tmp = 0; length = 0; length_tmp = 0; /* the macro can set this variable to -1 */ ptr = message->databuffer; datalength = message->datasize; /* first read the type info of the first argument: should be string */ DLT_MSG_READ_VALUE(type_info_tmp, ptr, datalength, uint32_t); type_info = DLT_ENDIAN_GET_32(message->standardheader->htyp, type_info_tmp); if (type_info & DLT_TYPE_INFO_STRG) { /* skip string */ DLT_MSG_READ_VALUE(length_tmp, ptr, datalength, uint16_t); length = DLT_ENDIAN_GET_16(message->standardheader->htyp, length_tmp); if (length >= 0) { ptr += length; datalength -= length; /* read type of second argument: should be raw */ DLT_MSG_READ_VALUE(type_info_tmp, ptr, datalength, uint32_t); type_info = DLT_ENDIAN_GET_32(message->standardheader->htyp, type_info_tmp); if (type_info & DLT_TYPE_INFO_RAWD) { /* get length of raw data block */ DLT_MSG_READ_VALUE(length_tmp, ptr, datalength, uint16_t); length = DLT_ENDIAN_GET_16(message->standardheader->htyp, length_tmp); if ((length >= 0) && (length == datalength)) /*printf("Raw data found in payload, length="); */ /*printf("%d, datalength=%d \n", length, datalength); */ dltdata->test_counter_function[3]++; } } } } } } } } /* check test 5f */ if (strcmp(text, "Test5: (Function IF) Test high-level API") == 0) { printf("Test5f: (Function IF) Test high-level API\n"); dltdata->running_test = 14; dltdata->test_counter_function[4] = 0; } else if (strcmp(text, "Test5: (Function IF) finished") == 0) { if (dltdata->test_counter_function[4] == 12) { printf("Test5f PASSED\n"); dltdata->tests_passed++; } else { printf("Test5f FAILED\n"); dltdata->tests_failed++; } dltdata->running_test = 0; } else if (dltdata->running_test == 14) { if (strcmp(text, "Next line: dlt_log_int()") == 0) dltdata->test_counter_function[4]++; if (strcmp(text, "-42") == 0) dltdata->test_counter_function[4]++; if (strcmp(text, "Next line: dlt_log_uint()") == 0) dltdata->test_counter_function[4]++; if (strcmp(text, "42") == 0) dltdata->test_counter_function[4]++; if (strcmp(text, "Next line: dlt_log_string()") == 0) dltdata->test_counter_function[4]++; if (strcmp(text, "String output") == 0) dltdata->test_counter_function[4]++; if (strcmp(text, "Next line: dlt_log_raw()") == 0) dltdata->test_counter_function[4]++; if (strcmp(text, "00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f") == 0) dltdata->test_counter_function[4]++; if (strcmp(text, "Next line: dlt_log_string_int()") == 0) dltdata->test_counter_function[4]++; if (strcmp(text, "String output: -42") == 0) dltdata->test_counter_function[4]++; if (strcmp(text, "Next line: dlt_log_string_uint()") == 0) dltdata->test_counter_function[4]++; if (strcmp(text, "String output: 42") == 0) dltdata->test_counter_function[4]++; } /* check test 6f */ if (strcmp(text, "Test 6: (Function IF) Test local printing") == 0) { printf("Test6f: (Function IF) Test local printing\n"); dltdata->running_test = 15; dltdata->test_counter_function[5] = 0; } else if (strcmp(text, "Test6: (Function IF) finished") == 0) { if (dltdata->test_counter_function[5] == 2) { printf("Test6f PASSED\n"); dltdata->tests_passed++; } else { printf("Test6f FAILED\n"); dltdata->tests_failed++; } dltdata->running_test = 0; } else if (dltdata->running_test == 15) { if (strcmp(text, "Message (visible: locally printed)") == 0) { printf("Message (visible: locally printed)\n"); dltdata->test_counter_function[5]++; } if (strcmp(text, "Message (invisible: not locally printed)") == 0) { printf("Message (invisible: not locally printed)\n"); dltdata->test_counter_function[5]++; } } /* check test 7f */ if (strcmp(text, "Test 7: (Function IF) Test network trace") == 0) { printf("Test7f: (Function IF) Test network trace\n"); dltdata->running_test = 16; dltdata->test_counter_function[6] = 0; } else if (strcmp(text, "Test7: (Function IF) finished") == 0) { if (dltdata->test_counter_function[6] == 8) { printf("Test7f PASSED\n"); dltdata->tests_passed++; } else { printf("Test7f FAILED\n"); dltdata->tests_failed++; } dltdata->running_test = 0; } else if (dltdata->running_test == 16) { if (DLT_IS_HTYP_UEH(message->standardheader->htyp)) { if ((DLT_GET_MSIN_MSTP(message->extendedheader->msin)) == DLT_TYPE_NW_TRACE) { /* Check message type information*/ /* Each correct message type increases the counter by 1 */ mtin = DLT_GET_MSIN_MTIN(message->extendedheader->msin); if (mtin == DLT_NW_TRACE_IPC) dltdata->test_counter_function[6]++; if (mtin == DLT_NW_TRACE_CAN) dltdata->test_counter_function[6]++; if (mtin == DLT_NW_TRACE_FLEXRAY) dltdata->test_counter_function[6]++; if (mtin == DLT_NW_TRACE_MOST) dltdata->test_counter_function[6]++; /* Check payload, must be two arguments (2 raw data blocks) */ /* If the payload is correct, the counter is increased by 1 */ if (message->extendedheader->noar == 2) { /* verbose mode */ type_info = 0; type_info_tmp = 0; length = 0; length_tmp = 0; /* the macro can set this variable to -1 */ ptr = message->databuffer; datalength = message->datasize; /* first read the type info of the first argument: should be string */ DLT_MSG_READ_VALUE(type_info_tmp, ptr, datalength, uint32_t); type_info = DLT_ENDIAN_GET_32(message->standardheader->htyp, type_info_tmp); if (type_info & DLT_TYPE_INFO_RAWD) { /* skip string */ DLT_MSG_READ_VALUE(length_tmp, ptr, datalength, uint16_t); length = DLT_ENDIAN_GET_16(message->standardheader->htyp, length_tmp); if (length >= 0) { ptr += length; datalength -= length; /* read type of second argument: should be raw */ DLT_MSG_READ_VALUE(type_info_tmp, ptr, datalength, uint32_t); type_info = DLT_ENDIAN_GET_32(message->standardheader->htyp, type_info_tmp); if (type_info & DLT_TYPE_INFO_RAWD) { /* get length of raw data block */ DLT_MSG_READ_VALUE(length_tmp, ptr, datalength, uint16_t); length = DLT_ENDIAN_GET_16(message->standardheader->htyp, length_tmp); if ((length >= 0) && (length == datalength)) /*printf("Raw data found in payload, length="); */ /*printf("%d, datalength=%d \n", length, datalength); */ dltdata->test_counter_function[6]++; } } } } } } } /* check test 8f */ if (strcmp(text, "Test 8: (Function IF) Test truncated network trace") == 0) { printf("Test8f: (Function IF) Test truncated network trace\n"); dltdata->running_test = 17; dltdata->test_counter_function[7] = 0; } else if (strcmp(text, "Test8: (Function IF) finished") == 0) { if (dltdata->test_counter_function[7] == 20) { printf("Test8f PASSED\n"); dltdata->tests_passed++; } else { printf("Test8f FAILED\n"); dltdata->tests_failed++; } dltdata->running_test = 0; } else if (dltdata->running_test == 17) { if (DLT_IS_HTYP_UEH(message->standardheader->htyp)) { if ((DLT_GET_MSIN_MSTP(message->extendedheader->msin)) == DLT_TYPE_NW_TRACE) { /* Check message type information*/ /* Each correct message type increases the counter by 1 */ mtin = DLT_GET_MSIN_MTIN(message->extendedheader->msin); if (mtin == DLT_NW_TRACE_IPC) dltdata->test_counter_function[7]++; if (mtin == DLT_NW_TRACE_CAN) dltdata->test_counter_function[7]++; if (mtin == DLT_NW_TRACE_FLEXRAY) dltdata->test_counter_function[7]++; if (mtin == DLT_NW_TRACE_MOST) dltdata->test_counter_function[7]++; /* Check payload, must be two arguments (2 raw data blocks) */ /* If the payload is correct, the counter is increased by 1 */ if (message->extendedheader->noar == 4) { type_info = 0; type_info_tmp = 0; length = 0, length_tmp = 0; /* the macro can set this variable to -1 */ ptr = message->databuffer; datalength = message->datasize; DLT_MSG_READ_VALUE(type_info_tmp, ptr, datalength, uint32_t); type_info = DLT_ENDIAN_GET_32(message->standardheader->htyp, type_info_tmp); if (type_info & DLT_TYPE_INFO_STRG) { /* Read NWTR */ char chdr[10]; DLT_MSG_READ_VALUE(length_tmp, ptr, datalength, uint16_t); length = DLT_ENDIAN_GET_16(message->standardheader->htyp, length_tmp); DLT_MSG_READ_STRING(chdr, ptr, datalength, length); if (strcmp((char *)chdr, DLT_TRACE_NW_TRUNCATED) == 0) dltdata->test_counter_function[7]++; DLT_MSG_READ_VALUE(type_info_tmp, ptr, datalength, uint32_t); type_info = DLT_ENDIAN_GET_32(message->standardheader->htyp, type_info_tmp); if (type_info & DLT_TYPE_INFO_RAWD) { char hdr[2048]; DLT_MSG_READ_VALUE(length_tmp, ptr, datalength, uint16_t); length = DLT_ENDIAN_GET_16(message->standardheader->htyp, length_tmp); DLT_MSG_READ_STRING(hdr, ptr, datalength, length); if ((length == 16) && (hdr[15] == 15)) dltdata->test_counter_function[7]++; DLT_MSG_READ_VALUE(type_info_tmp, ptr, datalength, uint32_t); type_info = DLT_ENDIAN_GET_32(message->standardheader->htyp, type_info_tmp); if (type_info & DLT_TYPE_INFO_UINT) { uint32_t orig_size; DLT_MSG_READ_VALUE(length_tmp32, ptr, datalength, uint32_t); orig_size = DLT_ENDIAN_GET_32(message->standardheader->htyp, length_tmp32); if (orig_size == 1024 * 5) dltdata->test_counter_function[7]++; DLT_MSG_READ_VALUE(type_info_tmp, ptr, datalength, uint32_t); type_info = DLT_ENDIAN_GET_32(message->standardheader->htyp, type_info_tmp); if (type_info & DLT_TYPE_INFO_RAWD) { DLT_MSG_READ_VALUE(length_tmp, ptr, datalength, uint16_t); length = DLT_ENDIAN_GET_16(message->standardheader->htyp, length_tmp); /* Size of the truncated message after headers */ if (length == DLT_USER_BUF_MAX_SIZE - 41 - sizeof(uint16_t) - sizeof(uint32_t)) dltdata->test_counter_function[7]++; } } } } } } } } /* check test 9f */ if (strcmp(text, "Test 9: (Function IF) Test segmented network trace") == 0) { printf("Test9f: (Function IF) Test segmented network trace\n"); dltdata->running_test = 18; dltdata->test_counter_function[8] = 0; } else if (strcmp(text, "Test9: (Function IF) finished") == 0) { /* (Interface types) * (number of messages per complete message) */ if (dltdata->test_counter_function[8] == 4 * 35) { printf("Test9f PASSED\n"); dltdata->tests_passed++; } else { printf("Test9f FAILED\n"); dltdata->tests_failed++; } dltdata->running_test = 0; } else if (dltdata->running_test == 18) { if (DLT_IS_HTYP_UEH(message->standardheader->htyp)) { if ((DLT_GET_MSIN_MSTP(message->extendedheader->msin)) == DLT_TYPE_NW_TRACE) { /* Check message type information*/ /* Each correct message type increases the counter by 1 */ mtin = DLT_GET_MSIN_MTIN(message->extendedheader->msin); if (mtin == DLT_NW_TRACE_IPC) dltdata->test_counter_function[8]++; if (mtin == DLT_NW_TRACE_CAN) dltdata->test_counter_function[8]++; if (mtin == DLT_NW_TRACE_FLEXRAY) dltdata->test_counter_function[8]++; if (mtin == DLT_NW_TRACE_MOST) dltdata->test_counter_function[8]++; /* Payload for first segmented message */ if (message->extendedheader->noar == 6) { /* verbose mode */ type_info = 0; type_info_tmp = 0; length = 0, length_tmp = 0; /* the macro can set this variable to -1 */ ptr = message->databuffer; datalength = message->datasize; /* NWST */ DLT_MSG_READ_VALUE(type_info_tmp, ptr, datalength, uint32_t); type_info = DLT_ENDIAN_GET_32(message->standardheader->htyp, type_info_tmp); if (type_info & DLT_TYPE_INFO_STRG) { char chdr[10]; DLT_MSG_READ_VALUE(length_tmp, ptr, datalength, uint16_t); length = DLT_ENDIAN_GET_16(message->standardheader->htyp, length_tmp); DLT_MSG_READ_STRING(chdr, ptr, datalength, length); if (strcmp((char *)chdr, DLT_TRACE_NW_START) == 0) dltdata->test_counter_function[8]++; /* Streahandle */ DLT_MSG_READ_VALUE(type_info_tmp, ptr, datalength, uint32_t); type_info = DLT_ENDIAN_GET_32(message->standardheader->htyp, type_info_tmp); if (type_info & DLT_TYPE_INFO_UINT) { uint32_t handle; DLT_MSG_READ_VALUE(length_tmp32, ptr, datalength, uint32_t); handle = DLT_ENDIAN_GET_32(message->standardheader->htyp, length_tmp32); if (handle > 0) dltdata->test_counter_function[8]++; /* Header */ DLT_MSG_READ_VALUE(type_info_tmp, ptr, datalength, uint32_t); type_info = DLT_ENDIAN_GET_32(message->standardheader->htyp, type_info_tmp); if (type_info & DLT_TYPE_INFO_RAWD) { DLT_MSG_READ_VALUE(length_tmp, ptr, datalength, uint16_t); length = DLT_ENDIAN_GET_16(message->standardheader->htyp, length_tmp); /* Test packet header size 16 */ if (length == 16) dltdata->test_counter_function[8]++; /* Skip data */ ptr += length; datalength -= length; /* Payload size */ DLT_MSG_READ_VALUE(type_info_tmp, ptr, datalength, uint32_t); type_info = DLT_ENDIAN_GET_32(message->standardheader->htyp, type_info_tmp); if (type_info & DLT_TYPE_INFO_UINT) { uint32_t pl_sz; DLT_MSG_READ_VALUE(length_tmp32, ptr, datalength, uint32_t); pl_sz = DLT_ENDIAN_GET_32(message->standardheader->htyp, length_tmp32); /* Test packet payload size. */ if (pl_sz == 5120) dltdata->test_counter_function[8]++; /* Segmentcount */ DLT_MSG_READ_VALUE(type_info_tmp, ptr, datalength, uint32_t); type_info = DLT_ENDIAN_GET_32(message->standardheader->htyp, type_info_tmp); if (type_info & DLT_TYPE_INFO_UINT) { uint16_t scount; DLT_MSG_READ_VALUE(length_tmp, ptr, datalength, uint16_t); scount = DLT_ENDIAN_GET_16(message->standardheader->htyp, length_tmp); /* Test packet segment count 5 */ if (scount == 5) dltdata->test_counter_function[8]++; /* Segment length */ DLT_MSG_READ_VALUE(type_info_tmp, ptr, datalength, uint32_t); type_info = DLT_ENDIAN_GET_32(message->standardheader->htyp, type_info_tmp); if (type_info & DLT_TYPE_INFO_UINT) { uint16_t slen; DLT_MSG_READ_VALUE(length_tmp, ptr, datalength, uint16_t); slen = DLT_ENDIAN_GET_16(message->standardheader->htyp, length_tmp); /* Default segment size 1024 */ if (slen == 1024) dltdata->test_counter_function[8]++; } } } } } } } /* Data segment */ else if (message->extendedheader->noar == 4) { /* verbose mode */ type_info = 0; type_info_tmp = 0; length = 0, length_tmp = 0; /* the macro can set this variable to -1 */ ptr = message->databuffer; datalength = message->datasize; /* NWCH */ DLT_MSG_READ_VALUE(type_info_tmp, ptr, datalength, uint32_t); type_info = DLT_ENDIAN_GET_32(message->standardheader->htyp, type_info_tmp); if (type_info & DLT_TYPE_INFO_STRG) { char chdr[10]; DLT_MSG_READ_VALUE(length_tmp, ptr, datalength, uint16_t); length = DLT_ENDIAN_GET_16(message->standardheader->htyp, length_tmp); DLT_MSG_READ_STRING(chdr, ptr, datalength, length); if (strcmp((char *)chdr, DLT_TRACE_NW_SEGMENT) == 0) dltdata->test_counter_function[8]++; /* handle */ DLT_MSG_READ_VALUE(type_info_tmp, ptr, datalength, uint32_t); type_info = DLT_ENDIAN_GET_32(message->standardheader->htyp, type_info_tmp); if (type_info & DLT_TYPE_INFO_UINT) { uint32_t handle; DLT_MSG_READ_VALUE(length_tmp32, ptr, datalength, uint32_t); handle = DLT_ENDIAN_GET_32(message->standardheader->htyp, length_tmp32); if (handle > 0) dltdata->test_counter_function[8]++; /* Sequence */ DLT_MSG_READ_VALUE(type_info_tmp, ptr, datalength, uint32_t); type_info = DLT_ENDIAN_GET_32(message->standardheader->htyp, type_info_tmp); if (type_info & DLT_TYPE_INFO_UINT) { /*uint16_t seq; */ DLT_MSG_READ_VALUE(length_tmp, ptr, datalength, uint16_t); /*seq=DLT_ENDIAN_GET_16(message->standardheader->htyp, length_tmp); */ dltdata->test_counter_function[8]++; /* Data */ DLT_MSG_READ_VALUE(type_info_tmp, ptr, datalength, uint32_t); type_info = DLT_ENDIAN_GET_32(message->standardheader->htyp, type_info_tmp); if (type_info & DLT_TYPE_INFO_RAWD) { DLT_MSG_READ_VALUE(length_tmp, ptr, datalength, uint16_t); length = DLT_ENDIAN_GET_16(message->standardheader->htyp, length_tmp); /* Segment size by default, 1024 */ if (length == 1024) dltdata->test_counter_function[8]++; } } } } } /* End segment */ else if (message->extendedheader->noar == 2) { /* verbose mode */ type_info = 0; type_info_tmp = 0; length = 0, length_tmp = 0; /* the macro can set this variable to -1 */ ptr = message->databuffer; datalength = message->datasize; /* NWEN */ DLT_MSG_READ_VALUE(type_info_tmp, ptr, datalength, uint32_t); type_info = DLT_ENDIAN_GET_32(message->standardheader->htyp, type_info_tmp); if (type_info & DLT_TYPE_INFO_STRG) { char chdr[10]; DLT_MSG_READ_VALUE(length_tmp, ptr, datalength, uint16_t); length = DLT_ENDIAN_GET_16(message->standardheader->htyp, length_tmp); DLT_MSG_READ_STRING(chdr, ptr, datalength, length); if (strcmp((char *)chdr, DLT_TRACE_NW_END) == 0) dltdata->test_counter_function[8]++; /* handle */ DLT_MSG_READ_VALUE(type_info_tmp, ptr, datalength, uint32_t); type_info = DLT_ENDIAN_GET_32(message->standardheader->htyp, type_info_tmp); if (type_info & DLT_TYPE_INFO_UINT) { uint32_t handle; DLT_MSG_READ_VALUE(length_tmp32, ptr, datalength, uint32_t); handle = DLT_ENDIAN_GET_32(message->standardheader->htyp, length_tmp32); if (handle > 0) dltdata->test_counter_function[8]++; } } } } } } if (strcmp(text, "Tests finished") == 0) { printf("Tests finished\n"); dltdata->running_test = 1; printf("%d tests passed\n", dltdata->tests_passed); printf("%d tests failed\n", dltdata->tests_failed); if (dltdata->sock != -1) close(dltdata->sock); g_testsFailed = dltdata->tests_failed; return 0; } /* if no filter set or filter is matching display message */ if (dltdata->xflag) dlt_message_print_hex(message, text, DLT_TESTCLIENT_TEXTBUFSIZE, dltdata->vflag); else if (dltdata->mflag) dlt_message_print_mixed_plain(message, text, DLT_TESTCLIENT_TEXTBUFSIZE, dltdata->vflag); else if (dltdata->sflag) dlt_message_print_header(message, text, sizeof(text), dltdata->vflag); /* if file output enabled write message */ if (dltdata->ovalue) { iov[0].iov_base = message->headerbuffer; iov[0].iov_len = message->headersize; iov[1].iov_base = message->databuffer; iov[1].iov_len = message->datasize; bytes_written = writev(dltdata->ohandle, iov, 2); if (0 > bytes_written) { printf("dlt_testclient_message_callback, error in: writev(dltdata->ohandle, iov, 2)\n"); return -1; } } } return 0; } dlt-daemon-2.18.4/src/tests/dlt-test-filetransfer-file000066400000000000000000000000211353342203500226360ustar00rootroot00000000000000!!!HelloWorld!!! dlt-daemon-2.18.4/src/tests/dlt-test-filetransfer-image.png000066400000000000000000000447211353342203500236030ustar00rootroot00000000000000PNG  IHDR`sRGBgAMA a pHYsodIjIDATx^ŝ}f/s'g$;f7h&&qHԈ**"((*l(. [6mmݧ9uݵ?zWuu PPPPP c.ȸl PPPP PPPPVÚux( PPPPVÚux( PPPPVÚux( PPPPVÚux( PPPPVÚux( PPPPVÚux( PPPPVÚux( PPPPVÚux( PPPPVÚux( PPPPV`l 'Sϟ7h0000lDϟZ5g<f͓/W7W<oFw@1)/|/>ԙÌyІjROY㈹jnך޽\9isffS'>9>k^9a8```o oTNJ',|U> W32n9d^]G}b`ͼN8Z5 `+`W͡7Λm@̗'7߿e9ک¼1e}/UTWAVsY غ}[7n./>6°ʬʨ}l5+vY ```&[. hN u}u 6#}Y7B`I/p3:-i3׉u$ kiTϝ;g[ɛ̽7GY@qb@ v__9Ys~]`ב35WLܶEsT: X3(>[L֑2Y=Ƿ0:`̑R00i })kyțFO'a}Wl3;_`Mkֆ4yg7U5/iÁ0000+3Ҧ5kêOVɬ\~(Y ܻ{GִfkXm۞y\|Nc s dYϘG7iO^eiXfվWgK81Lt```ϛE] kiV8qtՎ`V10000OWیGWY;fogp2ff 000P2yisѭ[ӣSYVd5w.=`a8```:f`530Z$裏Κa-_zշ}1L |f NJrϚa-swi+cV10000Gv̙3g°[}1su2c``` \d_p߶H%S~,?C7/Vr@a``6=w|MYݰ/Z=^C41{m//`:TZ~sw1޵,&pN&L```g?^e=uTC5s_1_af 000C`b X<* kuuŻ !5 GͤY:Tê~8q'O`X100000?p|mc7C3pY_&74!1pѭ;'_4.~n~5Z=溇!D 耙2oW/_ Ͱ~vfxǛV + Θ!mC1o}z֛ef```@ |g6s0*V˷3NeX8```vkW7ڿ'O>i$ pNG1pCfW}S-?C1@Mvs#k420q6_=a-?~~u7͋N42پx߯7ǎ+>o%ߖßV_GS6Oba``` p|e:s}# ԰ WBHfSÝM? Çְ;w@B`Xit000y1 z~@`+a=t֚3/%p43 /bXO:e8`$`Lb@ ```JJêOjq,2ra}0000?{cmX%D``` ?0+r2ry;@ȃ +s``` k0֬ef̖8a2auvŁ0000Va=fÁ0000V k 2A`000cÊaŰ2{Ț ðr eX_@Ȃ +5  0I1aul ```` 0V9bXm3[@``eX_Pr daXpr Ê9g0005V kր2cfK 0bX1̪a``f0Xh9Goi.\ɡu8 ?NĀ@{?wL擾7O->*C }tPa=h2GXCՠnR<>r m`}SjKwڬ5޲\0onIS?eztkwHݧ`X17ێhBxݸSlS 0S54owa 3n7Y~ϞL'ue1Q|)7 k;4Ӣ9aŰvְCV\c ACiaX'^|"1amslHP: ^+ Gs B*kXcNqBiQ_b7( ̵{bry, ``0 ~`}x~sgcGˣ{}׹~_ k?&V kgJUFԗƕvc}vEc8; t M_JӰjWkR~aŰvְ{5"@i'4aJ/O-4vUO|#0. 6Gc u4q~1}9Ot^z5 {fsMjs' ӛ1aŰv66]a՛=S:w}r]ym)\?efUYQ2*GYJ?lumY~mʧ2fJiƃv_X5F^|2Q,K\8.o41uFODfozWeu^V6<˒S4vڹI^UaX{kkq﫫U^Xվ-u_+ū~kcV+Y#lbXC[BT55^qF/P4zSnqjj1tנbe1:QHCU>z8S&,ʫCc+M2V%mbƧ4,~ӫ>a߽ ߡ1)v=aXƆo5iUM&ڻi{ekhS NǕ^F4?scK/Tޔ2&T+-vuoK#v~])M؍4Uc=*ik*gj]2omӥmkU7WEjK*ߡccCvW#v1# +Gc u5MWؿ7G8}"+F0!v_+̒#[ WS=R44 ZYZwޓChk1Yf'8 |H6 7e&'қY-(LAWQ_3xr0kKRak?vIׄRѠ *Մ:=kp 1 FѰv5.p5I⊽RjLX[SLtLJnj̠+]γԸʰbX{6UuO<&-aXu8ky]V:c+6ΧmB?lWb~1묑[QzX#-C:(PYC+&BZtjz^1^hxN+K'W\}Ծ^^2PENiy뱪P=|W,%e_1U\Ҷ+|AmWS^;fX]sxTT틕o\G4ðbX;k|mu/h_ycLzYcPbIQ3ǡ,U K=4}ɠR/ohp}>K[I-tֵO^ekId(P{t|Cb*4钋^b黷˾6~ưCW/e11#͏/ڙ%êA6Tmh0u ġU&WGB)d\FͰY%35UѦ+I=4 QYJyS/e|WT|C}Hl)@ /KU?@W_1:Q2,B(jZjNͣQ21VB؀[Om'Vm7fCήMSu]*ʑL(MeM-GJ>M|Cu }yOa[\eM4Ne{^5ð aְ4]f{ 믭aC<>^;}zM}v Z_P?WZjz-K" 0؉ZTBZj\׵oW}nSWMޱ'UrQڮƸw_aŰ&B7jU @]:?.+M@׵ 0;PCZ&z*n4HIHyS_6Z1|B܅xJ=dׯؤm}aX?6L~ ŸXumOsmԧ!aXpr4 .y!Mu>گxX15|}eB*c/ӻ6;rTc1) ա˸tUJ{8$SqY]0E]Ey_wkbhIm[jPd˾ ^6P}P4q]3aŰvf{1]vM;Pmez/>ipamA uԀ ?Mb.ֺ0ey/61I@~_{voW}aX6*=ukpm3C ÊaҁӰG`] ]>Va kZǸnÈ1վMAƷnB g9 =eu?f8_u°bXް궀b>b bX:تKgY=Bڇtu}SUYMيe| '4i۬_L 1#q 1Mau'\؊CH @;?>|otwD} =zcƚF䬥i]Ǚ]O(]%UH2Ho_]J-UԖe?]Җ.I}@0hXCn:QKEdqXa14&t2>aXu]!hAȰ.+X!MuwA[G l%PzԝR |~K#4*vuwҍ RkbZ.)ihWepW[>c5>!kW)W颼J/+6M~ Qe:30 -҅.4BV?$.xiwy*[/bq>;0ѨVǘA չUvu7QŌcȴLL+XPcki%.cEh2Pu1cur) Ym-0׶5ݫmb'fL-m=DU?_2SqŇ~ӊauփV0 &t=]!]aP)ub>ŰbX'aUG3xyu)&&05] uMr]ZdڻҪnbB:}0 ~J,u4>}&w MS؉]n^4et5mLc4.5q*'=& /aXqk08k|Յ:'v0T~rܮðbX/_#(5eŤa,5S{Q]U u<0Զ+1R[̯[ưƟ}ujY!MѾyYTs6HI匙Ui8弿? +Gc ~KKvYiDSq轱WYcIzkZ|_`VolR?+*SݯXh`OXU//h(*GϹ;ˮtt.UvGyM ה{SqHkU$(MbZs_] 迻-mnҧH}o(+z0;-T5Xa;ECF^. =c.P!{쀠Ci(st<`'fP7͚X^ĵ:(RgX#+/oݧz׵W{|JږMm5ܫCXVzժ{P׾b}Z41_o_}x廗U JCjm؏`X14"l Kڡ (3MS(+cX14a ͒ebsi``@E-~V։aZ 1V XͰfꌺ@'I: ΀aՖ>*ð: k`8Svl-}xA܉; vkоl ˰hK )ӠpAۀ27n,~ +FUhD``S ƍ9Iǜ`X14?7¿D=66000Z ,mdوcqİ: vk`8OVW5csȃ +# vV2߰:<:-@```bX1b dÚ5̢oM̉9 @ ˰`A@Ȃ ðnpr Ê9g0005V kր2cfK 0bX1̪a``f0[-h000y0aump8````ÊaD&L```| `X1Vf000Y3au-Z4<bX1LP```f2l ```` 0úɁ0000V + @ `X1Y6-q 00d2,h000Y0auMN4<bX?1wj~7|5wf#3 .O]]ut&xdBsPsÊa-Ӫ? nR}-|S7Suq6m=if>7O0V k- }kƵjCzM+gg͉~645ns|bQmVah ̸7VXun߫}^5}yk҆&.-vNO,2`qӽ-:7nzpO kEiLlƯ=NkP8}n^(u 'C50wj/4izm U+? Q>wOba kM8]ik3֌yau vuuG+~Wطԛ!@5QK;3z+>U-B[tΧ8ĦK'*^u|>w9İacWR}JC iN4B̮tfW[}i8.YŁqQm_"1yaŰFo6Jb}Cnሙq 5_*c9_Eʹ~mbp<}(aŰbXۯ_xYtua:O c /5juVa]o (n hR_ й&iMk 7պ>.Yn/f"ƃDyQeX{&AnιRc鎓lRz^_l]jݤ޺MlRe9j[. nuy1&ϽTQ 8M[W.5Q:bL52:(/~fjU#F., V3ow_Py4Pug5^ֽSVY-a&ֵ,g/JCRiC߫cQgX1 Mϔ)_D.үL?VO6^/1v!W>9%mYW#F!]i4\?,cXQ'&S}sh̨#xƴq]^\i[jVMA:v7*cX1; xyWXa9l86:>`})uDS׵wێvmcRt-9 K_ZV3u1SnD7쪣~~96,(χ5ߔr-eZOnӏ'W;8c_jw)qk0chXը%vUiǣNiPnOzٴ >񤔱nRvm;]6MX1VĮĶ< V.Wm" I̫{?PYAGSRcP^E(6۱2}W+ &*XC)m|(zP/[ieKkTbXQu*(p?۶Ƴ}] ]:LêVb]͌Uԉˠ O΃2'|m KMMB()nXTyCLwR'Ŵv6}nlQǷbuk(]aCYf)WL:`SCxtrڅawPm:^f77]6`jb~v{;v(CuQզ2064h{GJA1c3׿jF,6cSӾ:ƥO~|01&#fb׾wn{X]i~{uaTP:o}ȿJZ}$o(*xOX|ei{Qײ\V2?EE\=_ӗ71nm8*ljc>}O|K2.cZڗ b6cJb͗،]J;TPw׽@mGeQe(ԟ-kLG5&}s(ىjwmX{0#fXP:%&v̮jtj>\/wLF BvuNmz_.BWDyk&j7ՉF/: q`ޮAWHiCUDW'RRk\ӉDB'*O}2g?Mnh7qjWzlDk]`X1ŀ1PǪ.| @l.مj (:,Hk .~Ҹ#~tMmhݴMzfIWqKy k|7~M9뜈P:mM6N lIS~)fKV k1ez F+PS u|Se:*ðvD|X0R7fSS[MbS?aK_ w%v.sHdka -ФU{.m5VakWXGʿK k:LӬ:u6*+]ߣ廧NH)3&=V.nqFER.- UL׶OXئ57vШ|٧%-4l9Դ ?Wg}&Xt>\Q2辴j7Sm7֩-/ݥeðbX52ѥ> ]״5^#*g،6] æFiI`lh2&]VR J64,GF`z[YJe5Ys)VODZobIY NuB``uiyr0kl#64 VKI+J#uO1kR_Zո}k{i+Ů71u>fN|uQ6P WR%⹋xh&TGzVefg /JUcD>t}ZyJ/6vckcX1EEo3Pe2h 6U]i +m 1waTKMs5imctvKy]w>dei\(N|˔b&Lky{BEuiQ]Ӳ|=:a :m v.uݰVښ k*ޱZk#Զ/ qSLg6ՕS5~֐aaUeBIvזð vK3W_jRts)iWXmY]if]?(6-n5 ZQкm]toV|V=t^-.({v調U,ljsxXxrMb-/*X+ghLQ.ks])%*5]^ːV kѨRh ܔg:Ȑ! 6]s67>mb]gM;Lm/wȜǕ^/mhXiR[t.%@/1Hwׄʩzm]KrcY X&i4×V[Mްx"M ]~=dZ\}' Pt>4N!T___]ǩIz)ڶ~[ci=>5Va}8ft%8u>JR{XCep]hJkl9٨)釴VShqFARXVBp,ޡ?KXWӦ*v|leOk]#JGuf]1U5)e G]%f]m.Yƶ 0+`5*G^XM㻁@J#rQ?|F'gJk/'%Oe]תn9rV|$IlhB*KO^b]j٦}[ذ\b4͚_[ .74/]251Z[5fUuڤ'Bus~$"uJðaj.#צl3PihkӑNII,\[<:MaxT kJ]. y..&FMtT;H-tSd0qj&yz't45¥^1k1}0+3JGYˏ|~{Xu.EauYOlӰSLQZ֔tjL9Z-r1//ZiX}1o`?ERsH\ZGJlEu5%6_PVO۝'OM7%: & V^&lJ'kt`VU듫r\cSk1aM5AjW2.⹋@.SAPޡL_)d8^l[H tꄠ : )oG;M_KP h<Ԑ>/0MSNj>WrԵ^Xv_uE۶C[O0H^m~E<3)&QIQZho6L)Ϯkzf|0 : rFk۬ٻ>ƯeJtաO~,k4_n۱uPcWt륬mWMls[+cn˙ˮ2ht|:i]ĺMexYϲ͕Mܴ+mȥu?y"m{=i)e+~Tێ)uzMSL]/p: k,#v00eXw0000Va]f@ȃ +s``` k0֬ef̖8a2au֥vŁ0000Va} ```` 0,@d$ ```aX @ `X1s&(000Y3aŰf (3v<ݚV420{y߬1[0GꅫV퇨c1j~2eٳgOvWfXef-7ô-`Ҭ`h000e5Sf-/{Fz(C5 ;w4Ǿ6}VL; Yv;ZcoV|5 (P0=[?~Քkw=`g0092ϛv\:tZeIk+O4>3p?v\a-+}J;gdB```@ }͵V_m6Msڿ:=[{/D@ڼyM cZ10000GT[O7l`ۗݏTakh{XUm >`UCm8```ÀjЊOVWs|j[ꫬ'N(>qubv@(+ 7S4߰6m*>eofSաo Ňj~itkי{֞5Z8```:aW&7s*!/w5W!'OC;vs޲Lβr oLxzʭwr2@6{X˂{YϞ=k^bƍ͔Knag͵w/3ׯ7sSOu֙޹}@J{ 2u\2eYzuॗ^2NgXf5=Bր#G'x¬Zоucf5mh000i ?1K0;w,`j+_gSn xo9p@u[7ٴn@Hb'̷&3 -3۶m3 oꥫqg}7 Ӧ+~@Rp0{qgG̷'2.-~I ?~ط/ZVzZagUnٲ,Y֥梩{Λ̊ ```` \2Ys+̂>'DsU{X+rU>si]l{A%w?)}iVWUK\mОVզO1aŋgW[WO}(`4lĝ w\z~ū֘o.\X|^זF٬aUA˯{wÎ=ZBXa7/X`s^0N|>@ϛ_>ךo}̛7K>OWFvKWN~A/c[bElذx!KSUjԉ*cyϦ=g֚_ܲ|x^bc=Vl>گa"ߨ|g5Y~*ThjE@W-+p/V\0y+W}+,h0009o8oj+WM^i~s|yŶȵk/멳VUuR[ʗFq}%g\KӪ%n ڣ@)`d,Wm3g~\K?n}I0W6%/Z@{^ebuٳgǬY8``` s^dܹ?zREҤe*}꥗^*FuU+WL3 covҼj',{hU/kiЏ2 ```f@>C~CCC>D~D?]vnz\&UR|NiT'^ձ0e%תydDUoiO^ؒ2h000/7;?CGKOW^)kM&UO2UuD7[B/gͫ^xmҀުZdj9```_ ohTC>D~DD lz\~\IGZwڰֿZ5Z}U𵜮ي000]3Pz ҃ȏȗȟW)ԱlY ~y4U_2f5r @~ `X %B@@@(a@@@@f ((((a@@@@f ((((a@@@@f ((((a@@@@f ((((a@@@@f ((((a@@@@f ((((a@@@@f ((((a@@@@f ((((a@@@@f ((((a@@@@f ((((a@@@@f ((((a@@@@f ((((G xyIENDB`dlt-daemon-2.18.4/src/tests/dlt-test-filetransfer.c000066400000000000000000000444021353342203500221550ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2011-2015, BMW AG * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author Alexander Wenzel * * \copyright Copyright © 2011-2015 BMW AG. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file dlt-test-filetransfer.c */ /******************************************************************************* ** ** ** SRC-MODULE: dlt-test-filetransfer.c ** ** ** ** TARGET : linux ** ** ** ** PROJECT : DLT ** ** ** ** AUTHOR : Alexander Wenzel Alexander.AW.Wenzel@bmw.de ** ** ** ** PURPOSE : ** ** ** ** REMARKS : ** ** ** ** PLATFORM DEPENDANT [yes/no]: yes ** ** ** ** TO BE CHANGED BY USER [yes/no]: no ** ** ** *******************************************************************************/ /******************************************************************************* ** Author Identity ** ******************************************************************************** ** ** ** Initials Name Company ** ** -------- ------------------------- ---------------------------------- ** ** aw Alexander Wenzel BMW ** *******************************************************************************/ #include /*Needed for transferring files with the dlt protocol*/ #include /*Needed for dlt logging*/ /*!Declare some context for the main program. It's a must have to do this, when you want to log with dlt. */ DLT_DECLARE_CONTEXT(mainContext) /*!Declare some context for the file transfer. It's not a must have to do this, but later you can set a filter on this context in the dlt viewer. */ DLT_DECLARE_CONTEXT(fileContext) /*!Textfile which will be transferred. */ char *file1; /*!Image which will be transferred. */ char *file2; /*!Not existing file which will be transferred. */ char *file3_1; /*!Not existing file which will be transferred. */ char *file3_2; /*!Not existing file which will be transferred. */ char *file3_3; /*!Just some variables */ int i, countPackages, transferResult; static int g_numFailed = 0; /*!Prints the test result */ void printTestResultPositiveExpected(const char *function, int result) { if (result >= 0) { printf("%s successful\n", function); } else { printf("%s failed\n", function); g_numFailed++; } } /*!Prints the test result */ void printTestResultNegativeExpected(const char *function, int result) { if (result < 0) { printf("%s successful\n", function); } else { printf("%s failed\n", function); g_numFailed++; } } /*!Test the file transfer with the condition that the transferred file is smaller as the file transfer buffer using dlt_user_log_file_complete. */ int testFile1Run1() { /*Just some log to the main context */ DLT_LOG(mainContext, DLT_LOG_INFO, DLT_STRING("Started testF1P1 - dlt_user_log_file_complete"), DLT_STRING(file1)); /*Here's the line where the dlt file transfer is called. The method call needs a context, the absolute file path, will the file be deleted after transfer and the timeout between the packages */ transferResult = dlt_user_log_file_complete(&fileContext, file1, 0, 20); if (transferResult < 0) { printf("Error: dlt_user_log_file_complete\n"); return transferResult; } /*Just some log to the main context */ DLT_LOG(mainContext, DLT_LOG_INFO, DLT_STRING("Finished testF1P1"), DLT_STRING(file1)); printTestResultPositiveExpected(__FUNCTION__, transferResult); return transferResult; } /*!Test the file transfer with the condition that the transferred file is smaller as the file transfer buffer using single package transfer */ int testFile1Run2() { int total_size, used_size; /*Get the information how many packages have the file */ countPackages = dlt_user_log_file_packagesCount(&fileContext, file1); if (countPackages < 0) { printf("Error: dlt_user_log_file_packagesCount\n"); printTestResultPositiveExpected(__FUNCTION__, countPackages); return -1; } /*Just some log to the main context */ DLT_LOG(mainContext, DLT_LOG_INFO, DLT_STRING("Started testF1P2 - transfer single package"), DLT_STRING(file1)); /*Logs the header of the file transfer. For more details see Mainpage.c. */ /*The header gives information about the file serial number, filename (with absolute path), filesize, packages of file, buffer size */ transferResult = dlt_user_log_file_header(&fileContext, file1); if (transferResult >= 0) { /*Loop to log all packages */ for (i = 1; i <= countPackages; i++) { dlt_user_check_buffer(&total_size, &used_size); if ((total_size - used_size) < (total_size / 2)) { printf("Error: dlt_user_log_file_data\n"); printTestResultPositiveExpected(__FUNCTION__, transferResult); break; } /*Logs one single package to the file context */ transferResult = dlt_user_log_file_data(&fileContext, file1, i, 20); if (transferResult < 0) { printf("Error: dlt_user_log_file_data\n"); printTestResultPositiveExpected(__FUNCTION__, transferResult); return transferResult; } } /*Logs the end of the file transfer. For more details see Mainpage.c */ /*The end gives just information about the file serial number but is needed to signal that the file transfer has correctly finished and needed for the file transfer plugin of the dlt viewer. */ transferResult = dlt_user_log_file_end(&fileContext, file1, 0); if (transferResult < 0) { printf("Error: dlt_user_log_file_end\n"); printTestResultPositiveExpected(__FUNCTION__, transferResult); return transferResult; } } else { printf("Error: dlt_user_log_file_header\n"); printTestResultPositiveExpected(__FUNCTION__, transferResult); return transferResult; } /*Just some log to main context */ DLT_LOG(mainContext, DLT_LOG_INFO, DLT_STRING("Finished testF1P2 - transfer single package"), DLT_STRING(file1)); printTestResultPositiveExpected(__FUNCTION__, transferResult); return 0; } /*!Test the file transfer with the condition that the transferred file is bigger as the file transfer buffer using dlt_user_log_file_complete. */ int testFile2Run1() { /*Just some log to main context */ DLT_LOG(mainContext, DLT_LOG_INFO, DLT_STRING("Started testF2P1 - dlt_user_log_file_complete"), DLT_STRING(file2)); /*Here's the line where the dlt file transfer is called. The method call needs a context, the absolute file path, will the file be deleted after transfer and the timeout between the packages */ transferResult = dlt_user_log_file_complete(&fileContext, file2, 0, 20); if (transferResult < 0) { printf("Error: dlt_user_log_file_complete\n"); printTestResultPositiveExpected(__FUNCTION__, transferResult); return transferResult; } /*Just some log to main context */ DLT_LOG(mainContext, DLT_LOG_INFO, DLT_STRING("Finished testF2P1"), DLT_STRING(file2)); printTestResultPositiveExpected(__FUNCTION__, transferResult); return transferResult; } /*!Test the file transfer with the condition that the transferred file is bigger as the file transfer buffer using single package transfer */ int testFile2Run2() { int total_size, used_size; /*Get the information how many packages have the file */ countPackages = dlt_user_log_file_packagesCount(&fileContext, file2); if (countPackages < 0) { printf("Error: dlt_user_log_file_packagesCount\n"); printTestResultPositiveExpected(__FUNCTION__, countPackages); return -1; } /*Just some log to the main context */ DLT_LOG(mainContext, DLT_LOG_INFO, DLT_STRING("Started testF2P2 - transfer single package"), DLT_STRING(file2)); /*Logs the header of the file transfer. For more details see Mainpage.c. */ /*The header gives information about the file serial number, filename (with absolute path), filesize, packages of file, buffer size */ transferResult = dlt_user_log_file_header(&fileContext, file2); if (transferResult >= 0) { /*Loop to log all packages */ for (i = 1; i <= countPackages; i++) { dlt_user_check_buffer(&total_size, &used_size); if ((total_size - used_size) < (total_size / 2)) { printf("Error: dlt_user_log_file_data\n"); printTestResultPositiveExpected(__FUNCTION__, transferResult); break; } /*Logs one single package to the file context */ transferResult = dlt_user_log_file_data(&fileContext, file2, i, 20); if (transferResult < 0) { printf("Error: dlt_user_log_file_data\n"); printTestResultPositiveExpected(__FUNCTION__, transferResult); return transferResult; } } /*Logs the end of the file transfer. For more details see Mainpage.c */ /*The end gives just information about the file serial number but is needed to signal that the file transfer has correctly finished and needed for the file transfer plugin of the dlt viewer. */ transferResult = dlt_user_log_file_end(&fileContext, file2, 0); if (transferResult < 0) { printf("Error: dlt_user_log_file_end\n"); printTestResultPositiveExpected(__FUNCTION__, transferResult); return transferResult; } } else { printf("Error: dlt_user_log_file_header\n"); printTestResultPositiveExpected(__FUNCTION__, transferResult); return transferResult; } /*Just some log to the main context */ DLT_LOG(mainContext, DLT_LOG_INFO, DLT_STRING("Finished testF2P2"), DLT_STRING(file2)); printTestResultPositiveExpected(__FUNCTION__, transferResult); return 0; } /*!Test the file transfer with the condition that the transferred file does not exist using dlt_user_log_file_complete. */ int testFile3Run1() { /*Just some log to the main context */ DLT_LOG(mainContext, DLT_LOG_INFO, DLT_STRING("Started testF3P1"), DLT_STRING(file3_1)); /*Here's the line where the dlt file transfer is called. The method call needs a context, the absolute file path, will the file be deleted after transfer and the timeout between the packages */ transferResult = dlt_user_log_file_complete(&fileContext, file3_1, 0, 20); if (transferResult < 0) { /*Error expected because file doesn't exist */ /*printf("Error: dlt_user_log_file_complete\n"); */ /*Just some log to the main context */ DLT_LOG(mainContext, DLT_LOG_INFO, DLT_STRING("Finished testF3P1"), DLT_STRING(file3_1)); printTestResultNegativeExpected(__FUNCTION__, transferResult); return transferResult; } printTestResultNegativeExpected(__FUNCTION__, transferResult); return transferResult; } /*!Test the file transfer with the condition that the transferred file does not exist using single package transfer */ int testFile3Run2() { /*Get the information how many packages have the file */ countPackages = dlt_user_log_file_packagesCount(&fileContext, file3_2); if (countPackages < 0) { /*Error expected because file doesn't exist */ /*printf("Error: dlt_user_log_file_packagesCount\n"); */ /*Just some log to the main context */ DLT_LOG(mainContext, DLT_LOG_INFO, DLT_STRING("Finished testF3P1"), DLT_STRING(file3_2)); printTestResultNegativeExpected(__FUNCTION__, countPackages); return -1; } /*Just some log to the main context */ DLT_LOG(mainContext, DLT_LOG_INFO, DLT_STRING("Started testF3P1"), DLT_STRING(file3_2)); /*Logs the header of the file transfer. For more details see Mainpage.c. */ /*The header gives information about the file serial number, filename (with absolute path), filesize, packages of file, buffer size */ transferResult = dlt_user_log_file_header(&fileContext, file3_2); if (transferResult >= 0) { /*Loop to log all packages */ for (i = 1; i <= countPackages; i++) { /*Logs one single package to the file context */ transferResult = dlt_user_log_file_data(&fileContext, file3_2, i, 20); if (transferResult < 0) { printf("Error: dlt_user_log_file_data\n"); printTestResultNegativeExpected(__FUNCTION__, transferResult); return transferResult; } } /*Logs the end of the file transfer. For more details see Mainpage.c */ /*The end gives just information about the file serial number but is needed to signal that the file transfer has correctly finished and needed for the file transfer plugin of the dlt viewer. */ transferResult = dlt_user_log_file_end(&fileContext, file3_2, 0); if (transferResult < 0) { printf("Error: dlt_user_log_file_end\n"); printTestResultNegativeExpected(__FUNCTION__, transferResult); return transferResult; } } printTestResultNegativeExpected(__FUNCTION__, transferResult); return 0; } /*!Logs some information about the file. */ int testFile3Run3() { /*Just some log to the main context */ DLT_LOG(mainContext, DLT_LOG_INFO, DLT_STRING("Started testF3P2"), DLT_STRING(file3_3)); /*Here's the line where the dlt file file info is called. The method call logs some information to dlt about the file, filesize, file serial number and number of packages */ transferResult = dlt_user_log_file_infoAbout(&fileContext, file3_3); if (transferResult < 0) { /*Error expected because file doesn't exist */ /*printf("Error: dlt_user_log_file_infoAbout\n"); */ /*Just some log to the main context */ DLT_LOG(mainContext, DLT_LOG_INFO, DLT_STRING("Finished testF3P2"), DLT_STRING(file3_3)); printTestResultNegativeExpected(__FUNCTION__, transferResult); return transferResult; } printTestResultNegativeExpected(__FUNCTION__, transferResult); return 0; } void usage() { char version[255]; dlt_get_version(version, 255); printf("Usage: dlt-test-filestransfer [options]\n"); printf("Test filestransfer application by transfering files.\n"); printf("%s \n", version); printf("Options:\n"); printf(" -h display help information\n"); printf(" -t absolute path to a text file\n"); printf(" -i absolute path to an image file\n"); } /*!Main program dlt-test-filestransfer starts here */ int main(int argc, char* argv[]) { int c; /*First file contains some text */ file1 = "/usr/local/share/dlt-filetransfer/dlt-test-filetransfer-file"; /*Second file is a picture */ file2 = "/usr/local/share/dlt-filetransfer/dlt-test-filetransfer-image.png"; /*Third file doesn't exist. Just to test the reaction when the file isn't available. */ file3_1 = "dlt-test-filetransfer-doesntExist_1"; /*Third file doesn't exist. Just to test the reaction when the file isn't available. */ file3_2 = "dlt-test-filetransfer-doesntExist_2"; /*Third file doesn't exist. Just to test the reaction when the file isn't available. */ file3_3 = "dlt-test-filetransfer-doesntExist_3"; while((c = getopt(argc, argv, "ht:i:")) != -1) { switch (c) { case 't': { file1 = optarg; break; } case 'i': { file2 = optarg; break; } case 'h': { usage(); return 0; } default: { usage(); return -1; } } } /*Register the application at the dlt-daemon */ DLT_REGISTER_APP("FLTR", "Test Application filetransfer"); /*Register the context of the main program at the dlt-daemon */ DLT_REGISTER_CONTEXT(mainContext, "MAIN", "Main context for filetransfer test"); /*Register the context in which the file transfer will be logged at the dlt-daemon */ DLT_REGISTER_CONTEXT(fileContext, "FLTR", "Test Context for filetransfer"); /*More details in corresponding methods */ testFile1Run1(); testFile1Run2(); testFile2Run1(); testFile2Run2(); testFile3Run1(); testFile3Run2(); testFile3Run3(); /*Unregister the context in which the file transfer happened from the dlt-daemon */ DLT_UNREGISTER_CONTEXT(fileContext); /*Unregister the context of the main program from the dlt-daemon */ DLT_UNREGISTER_CONTEXT(mainContext); /*Unregister the app from the dlt-daemon */ DLT_UNREGISTER_APP(); return g_numFailed == 0 ? 0 : 1; } dlt-daemon-2.18.4/src/tests/dlt-test-fork-handler.c000066400000000000000000000044171353342203500220470ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2015 Intel Corporation * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author Stefan Vacek Intel Corporation * * \copyright Copyright © 2015 Intel Corporation. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file dlt-test-fork-handler.c */ #include /* for fork() */ #include #include #include "dlt.h" /** * @brief sample code for using at_fork-handler */ int main() { DltContext mainContext; struct timespec timeout, r; timeout.tv_sec = 0; timeout.tv_nsec = 200000000L; DLT_REGISTER_APP("PRNT", "Parent application"); DLT_REGISTER_CONTEXT(mainContext, "CTXP", "Parent context"); DLT_LOG(mainContext, DLT_LOG_WARN, DLT_STRING("First message before fork")); nanosleep(&timeout, &r); pid_t pid = fork(); if (pid == 0) { /* child process */ /* this message should not be visible */ DLT_LOG(mainContext, DLT_LOG_WARN, DLT_STRING("Child's first message after fork, pid: "), DLT_INT32(getpid())); /* this will not register CHLD application */ DLT_REGISTER_APP("CHLD", "Child application"); /* this will not register CTXC context */ DLT_REGISTER_CONTEXT(mainContext, "CTXC", "Child context"); /* this will not log a message */ DLT_LOG(mainContext, DLT_LOG_WARN, DLT_STRING("Child's second message after fork, pid: "), DLT_INT32(getpid())); nanosleep(&timeout, &r); if (execlp("dlt-example-user", "dlt-example-user", "-n 1", "you should see this message", NULL)) return errno; } else if (pid == -1) /* error in fork */ { return -1; } else { /* parent */ DLT_LOG(mainContext, DLT_LOG_WARN, DLT_STRING("Parent's first message after fork, pid: "), DLT_INT32(getpid())); nanosleep(&timeout, &r); } DLT_UNREGISTER_APP() ; return 0; } dlt-daemon-2.18.4/src/tests/dlt-test-init-free.c000066400000000000000000000057641353342203500213630ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2011-2015, BMW AG * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author Sven Hassler * * \copyright Copyright © 2011-2015 BMW AG. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file dlt-test-init-free.c */ #include #include #include #include #include "dlt_common.h" #include "dlt_user.h" void exec(const char *cmd, char *buffer, size_t length); void printMemoryUsage(); char *occupyMemory(uint size); void do_example_test(); void do_dlt_test(); int num_repetitions; int main(int argc, char **argv) { if (argc > 1) num_repetitions = strtol(argv[1], 0, 10); else num_repetitions = 1000; printf("Will do %d repetitions.\n", num_repetitions); /*do_example_test(); */ do_dlt_test(); printf("Done.\n"); return 0; } /* Should increase and then decrease memory amount. */ void do_example_test() { const int immediatelyFree = 0; int numBufs = 1024; int sizePerBuf = 1024 * 1024; /* 1MB */ char **bufs = (char **)malloc(numBufs * sizeof(char *)); for (int i = 0; i < numBufs; i++) { bufs[i] = occupyMemory(sizePerBuf); printf("after alloc: "); printMemoryUsage(); if (immediatelyFree) { free(bufs[i]); printf("after free: "); printMemoryUsage(); } } printf("deleting memory:\n"); if (!immediatelyFree) for (int i = 0; i < numBufs; i++) { /*for (int i = numBufs - 1; i >= 0; i--) // other way round works, too */ free(bufs[i]); printf("after free: "); printMemoryUsage(); } free(bufs); } /* Should give stable amount of memory across all iterations. */ void do_dlt_test() { for (int i = 0; i < num_repetitions; i++) { dlt_init(); dlt_free(); printf("Iteration %d) - currently used memory amount: ", i); printMemoryUsage(); } } void exec(const char *cmd, char *buffer, size_t length) { FILE *pipe = NULL; strncpy(buffer, "ERROR", length); if ((pipe = popen(cmd, "r")) == NULL) return; while (fgets(buffer, length, pipe) != NULL); if (pipe != NULL) pclose(pipe); } void printMemoryUsage() { char result[128] = { 0 }; char command[128] = { 0 }; snprintf(command, sizeof(command), "pmap %d | grep total", getpid()); exec(command, result, sizeof(result)); printf("%s", result); } char *occupyMemory(uint size) { char *buf = (char *)malloc(size * sizeof(char)); for (int i = 0; i < 1; i++) buf[i] = 1; return buf; } dlt-daemon-2.18.4/src/tests/dlt-test-multi-process-client.c000066400000000000000000000230231353342203500235470ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2011-2015, BMW AG * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author Lassi Marttala * * \copyright Copyright © 2011-2015 BMW AG. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file dlt-test-multi-process-client.c */ /******************************************************************************* ** ** ** SRC-MODULE: dlt-test-multi-process-client.c ** ** ** ** TARGET : linux ** ** ** ** PROJECT : DLT ** ** ** ** AUTHOR : Lassi Marttala ** ** ** ** PURPOSE : Receive, validate and measure data from multi process tester ** ** ** ** REMARKS : ** ** ** ** PLATFORM DEPENDANT [yes/no]: yes ** ** ** ** TO BE CHANGED BY USER [yes/no]: no ** ** ** *******************************************************************************/ /* System includes */ #include #include #include #include #include #include #include #include #include /* DLT Library includes */ #include "dlt_client.h" #include "dlt_protocol.h" #include "dlt_user.h" /* PRivate includes */ #include "dlt-test-multi-process.h" /* Local data structures */ typedef struct { int max_messages; int verbose; int serial; int baudrate; char *output; int output_handle; int messages_left; DltClient *client_ref; } s_parameters; typedef struct { int messages_received; int broken_messages_received; int bytes_received; int first_message_time; int output_bytes; } s_statistics; /* Forward declarations */ int receive(DltMessage *msg, void *data); /** * Print usage information */ void usage(char *name) { char version[255]; dlt_get_version(version, 255); printf("Usage: %s [options] \n", name); printf("Receive messages from dlt-test-multi-process.\n"); printf("%s", version); printf("Options:\n"); printf(" -m Total messages to receive. (Default: 10000)\n"); printf(" -y Serial device mode.\n"); printf(" -b baudrate Serial device baudrate. (Default: 115200)\n"); printf(" -v Verbose. Increases the verbosity level of dlt client library.\n"); printf(" -o filename Output messages in new DLT file.\n"); } /** * Initialize reasonable default parameters. */ void init_params(s_parameters *params) { params->max_messages = 10000; params->verbose = 0; params->serial = 0; params->output = NULL; params->output_handle = -1; params->baudrate = 115200; } /** * Read the command line parameters */ int read_params(s_parameters *params, int argc, char *argv[]) { init_params(params); int c; opterr = 0; while ((c = getopt(argc, argv, "m:yb:vo:")) != -1) switch (c) { case 'm': params->max_messages = atoi(optarg); break; case 'y': params->serial = 1; break; case 'b': params->baudrate = atoi(optarg); break; case 'v': params->verbose = 1; break; case 'o': params->output = optarg; break; case '?': if ((optopt == 'm') || (optopt == 'b') || (optopt == 'o')) fprintf(stderr, "Option -%c requires an argument.\n", optopt); if (isprint(optopt)) fprintf(stderr, "Unknown option '-%c'.\n", optopt); else fprintf(stderr, "Unknown option character '\\x%x'.\n", optopt); return -1; break; default: return -1; } return 0; } /** * Set the connection parameters for dlt client */ int init_dlt_connect(DltClient *client, const s_parameters *params, int argc, char *argv[]) { char id[4]; if (argc < 2) return -1; if (params->serial > 0) { client->mode = 1; if (dlt_client_set_serial_device(client, argv[argc - 1]) == -1) { fprintf(stderr, "set serial device didn't succeed\n"); return -1; } dlt_client_setbaudrate(client, params->baudrate); } else if (dlt_client_set_server_ip(client, argv[argc - 1]) == -1) { fprintf(stderr, "set serial ip didn't succeed\n"); return -1; } dlt_set_id(id, ECUID); return 0; } /** * Entry point */ int main(int argc, char *argv[]) { s_parameters params; DltClient client; params.client_ref = &client; int err = read_params(¶ms, argc, argv); if (err != 0) { usage(argv[0]); return err; } dlt_client_init(&client, params.verbose); dlt_client_register_message_callback(receive); err = init_dlt_connect(&client, ¶ms, argc, argv); if (err != 0) { usage(argv[0]); return err; } err = dlt_client_connect(&client, params.verbose); if (err != DLT_RETURN_OK) { printf("Failed to connect %s.\n", client.mode > 0 ? client.serialDevice : client.servIP); return err; } if (params.output) { params.output_handle = open(params.output, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); if (params.output_handle == -1) { fprintf(stderr, "Failed to open %s for writing.\n", params.output); return -1; } } params.messages_left = params.max_messages; dlt_client_main_loop(&client, ¶ms, params.verbose); if (params.output_handle > 0) close(params.output_handle); return 0; } /** * Print current test statistics */ void print_stats(s_statistics stats, s_parameters params) { static int last_print_time; if ((last_print_time >= time(NULL)) && /* Only print once a second */ ((stats.messages_received + stats.broken_messages_received) % 1000 != 0) && (params.messages_left != 0)) /* Print also every 1000th message */ return; printf("\033[2J\033[1;1H"); /* Clear screen. */ printf("Statistics:\n"); printf(" Messages received : %d\n", stats.messages_received); printf(" Broken messages received : %d\n", stats.broken_messages_received); printf(" Bytes received : %d\n", stats.bytes_received); printf(" Time running (seconds) : %ld\n", time(NULL) - stats.first_message_time); printf(" Throughput (msgs/sec)/(B/sec) : %ld/%ld\n", stats.messages_received / ((time(NULL) - stats.first_message_time) + 1), (stats.bytes_received) / ((time(NULL) - stats.first_message_time) + 1)); if (params.messages_left == 0) { if (stats.broken_messages_received == 0) printf("All messages received succesfully!\n"); else printf("Test failure! There were %d broken messages.", stats.broken_messages_received); } fflush(stdout); last_print_time = time(NULL); } /** * Callback for dlt client */ int receive(DltMessage *msg, void *data) { static s_statistics stats; char apid[5]; struct iovec iov[2]; s_parameters *params = (s_parameters *)data; memset(apid, 0, 5); memcpy(apid, msg->extendedheader->apid, 4); if ((apid[0] != 'M') || (apid[1] != 'T')) /* TODO: Check through the app description */ return 0; params->messages_left--; if (stats.first_message_time == 0) stats.first_message_time = time(NULL); int buflen = msg->datasize + 1; char *buf = malloc(buflen); if (buf == 0) { printf("Out of memory\n"); return -1; } memset(buf, 0, buflen); dlt_message_payload(msg, buf, buflen - 1, DLT_OUTPUT_ASCII, 0); if (strcmp(buf, PAYLOAD_DATA) == 0) stats.messages_received++; else stats.broken_messages_received++; stats.bytes_received += msg->datasize + msg->headersize - sizeof(DltStorageHeader); free(buf); print_stats(stats, *params); if (params->output_handle > 0) { iov[0].iov_base = msg->headerbuffer; iov[0].iov_len = msg->headersize; iov[1].iov_base = msg->databuffer; iov[1].iov_len = msg->datasize; stats.output_bytes += writev(params->output_handle, iov, 2); } if (params->messages_left < 1) dlt_client_cleanup(params->client_ref, params->verbose); return 0; } dlt-daemon-2.18.4/src/tests/dlt-test-multi-process.c000066400000000000000000000257741353342203500223120ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2011-2015, BMW AG * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author Lassi Marttala * * \copyright Copyright © 2011-2015 BMW AG. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file dlt-test-multi-process.c */ /******************************************************************************* ** ** ** SRC-MODULE: dlt-test-multi-process.c ** ** ** ** TARGET : linux ** ** ** ** PROJECT : DLT ** ** ** ** AUTHOR : Lassi Marttala Lassi.LM.Marttala@partner.bmw.de ** ** ** ** PURPOSE : Stress test timing using multiple processes ** ** ** ** REMARKS : Requires POSIX fork() ** ** ** ** PLATFORM DEPENDANT [yes/no]: yes ** ** ** ** TO BE CHANGED BY USER [yes/no]: no ** ** ** *******************************************************************************/ #include #include #include #include #include #include #include #include #include #include #include #include "dlt.h" #include "dlt_common.h" #include "dlt-test-multi-process.h" /* Constants */ #define MAX_PROCS 100 #define MAX_THREADS 100 #ifndef WAIT_ANY # define WAIT_ANY -1 #endif /* Structs */ typedef struct { int nmsgs; /* Number of messages to send */ int nprocs; /* Number of processes to start */ int nthreads; /* Number of threads to start */ int delay; /* Delay between logs messages for each process */ int delay_fudge; /* Fudge the delay by 0-n to cause desynchronization */ bool generate_ctid; /* true: To generate context Id from App Id + Thread Number */ } s_parameters; typedef struct { s_parameters params; DltContext ctx; unsigned int pidcount; unsigned int tidcount; } s_thread_data; /* Forward declarations */ void init_params(s_parameters *params); void quit_handler(int signum); void cleanup(); void do_forks(s_parameters params); void run_threads(s_parameters params); void do_logging(s_thread_data *data); int wait_for_death(); /* State information */ volatile sig_atomic_t in_handler = 0; /* Globals for cleanup from main and signal handler */ pid_t pids[MAX_PROCS]; unsigned int pidcount = 0; /** * Print instructions. */ void usage(char *prog_name) { char version[255]; dlt_get_version(version, 255); s_parameters defaults; init_params(&defaults); printf("Usage: %s [options]\n", prog_name); printf("Test application for stress testing the daemon with multiple processes and threads.\n"); printf("%s\n", version); printf("Options (Default):\n"); printf(" -m number Number of messages per thread to send. (%d)\n", defaults.nmsgs); printf(" -p number Number of processes to start. (%d), Max %d.\n", defaults.nprocs, MAX_PROCS); printf(" -t number Number of threads per process. (%d), Max %d.\n", defaults.nthreads, MAX_THREADS); printf(" -d delay Delay in milliseconds to wait between log messages. (%d)\n", defaults.delay); printf(" -f delay Random fudge in milliseconds to add to delay. (%d)\n", defaults.delay_fudge); printf(" -g Generate Context IDs from Application ID and thread number \n"); } /** * Set nice default values for parameters */ void init_params(s_parameters *params) { params->nmsgs = 100; params->nprocs = 10; params->nthreads = 2; params->delay = 1000; params->delay_fudge = 100; params->generate_ctid = false; } /** * Read the command line and modify parameters */ int read_cli(s_parameters *params, int argc, char **argv) { int c; opterr = 0; while ((c = getopt (argc, argv, "m:p:t:d:f:g")) != -1) switch (c) { case 'm': params->nmsgs = atoi(optarg); break; case 'p': params->nprocs = atoi(optarg); if (params->nprocs > MAX_PROCS) { fprintf(stderr, "Too many processes selected.\n"); return -1; } break; case 't': params->nthreads = atoi(optarg); if (params->nprocs > MAX_PROCS) { fprintf(stderr, "Too many threads selected.\n"); return -1; } break; case 'd': params->delay = atoi(optarg); break; case 'f': params->delay_fudge = atoi(optarg); break; case 'g': params->generate_ctid = true; break; case '?': if ((optopt == 'n') || (optopt == 'd') || (optopt == 'f')) fprintf(stderr, "Option -%c requires an argument.\n", optopt); else if (isprint(optopt)) fprintf(stderr, "Unknown option '-%c'.\n", optopt); else fprintf(stderr, "Unknown option character '\\x%x'.\n", optopt); return -1; break; default: abort(); return -1; /*for parasoft */ } return 0; } /** * Entry point */ int main(int argc, char **argv) { /* Prepare parameters */ s_parameters params; init_params(¶ms); if (read_cli(¶ms, argc, argv) != 0) { usage(argv[0]); exit(-1); } /* Launch the child processes */ do_forks(params); /* Register signal handlers */ if (signal(SIGINT, quit_handler) == SIG_IGN) signal(SIGINT, SIG_IGN); /* C-c */ if (signal(SIGHUP, quit_handler) == SIG_IGN) signal(SIGHUP, SIG_IGN); /* Terminal closed */ if (signal(SIGTERM, quit_handler) == SIG_IGN) signal(SIGTERM, SIG_IGN); /* kill (nice) */ printf("Setup done. Listening. My pid: %d\n", getpid()); fflush(stdout); int err = wait_for_death(); cleanup(); return err; } /** * Start the child processes */ void do_forks(s_parameters params) { int i; /* Launch child processes */ for (i = 0; i < params.nprocs; i++) { pid_t pid = fork(); switch (pid) { case -1: /* An error occured */ if (errno == EAGAIN) { fprintf(stderr, "Could not allocate resources for child process.\n"); cleanup(); abort(); } if (errno == ENOMEM) { fprintf(stderr, "Could not allocate memory for child process' kernel structure.\n"); cleanup(); abort(); } break; case 0: /* Child process, start threads */ run_threads(params); break; default: /* Parent process, store the childs pid */ pids[pidcount++] = pid; break; } } } /** * Clean up the child processes. * Reraise signal to default handler. */ void quit_handler(int signum) { if (in_handler) raise(signum); in_handler = 1; cleanup(); signal(signum, SIG_DFL); raise(signum); } /** * Ask the child processes to die */ void cleanup() { unsigned int i; for (i = 0; i < pidcount; i++) kill(pids[i], SIGINT); } /** * Generate the next sleep time */ time_t mksleep_time(int delay, int fudge) { if (!fudge) return delay*1000000; else return (delay+rand()%fudge)*1000000; } /** * Open logging channel and proceed to spam messages */ void do_logging(s_thread_data *data) { DltContext mycontext; char ctid[5]; char ctid_name[256]; struct timespec ts; time_t sleep_time; if(data->params.generate_ctid) snprintf(ctid, 5, "%02u%02u", data->pidcount, data->tidcount); else snprintf(ctid, 5, "CT%02u", data->tidcount); snprintf(ctid_name, 256, "Child %s in dlt-test-multi-process", ctid); DLT_REGISTER_CONTEXT(mycontext, ctid, ctid_name); int msgs_left = data->params.nmsgs; while (msgs_left-- > 0) { DLT_LOG(mycontext, DLT_LOG_INFO, DLT_STRING(PAYLOAD_DATA)); sleep_time = mksleep_time(data->params.delay, data->params.delay_fudge); ts.tv_sec = sleep_time / 1000000000; ts.tv_nsec = sleep_time % 1000000000; nanosleep(&ts, NULL); } DLT_UNREGISTER_CONTEXT(mycontext); } /** * Start the threads and wait for them to return. */ void run_threads(s_parameters params) { pthread_t thread[params.nthreads]; s_thread_data *thread_data = NULL; char apid[5]; char apid_name[256]; int i; srand(getpid()); snprintf(apid, 5, "MT%02u", pidcount); snprintf(apid_name, 256, "Apps %s.", apid); DLT_REGISTER_APP(apid, apid_name); thread_data = calloc(params.nthreads, sizeof(s_thread_data)); if (thread_data == NULL) { printf("Error allocate memory for thread data.\n"); abort(); } for (i = 0; i < params.nthreads; i++) { thread_data[i].tidcount = i; thread_data[i].params = params; thread_data[i].pidcount = pidcount; if (pthread_create(&(thread[i]), NULL, (void *)&do_logging, &thread_data[i]) != 0) { printf("Error creating thread.\n"); abort(); } } for (i = 0; i < params.nthreads; i++) pthread_join(thread[i], NULL); if(thread_data) free(thread_data); DLT_UNREGISTER_APP(); /* We can exit now */ exit(0); } /** * Wait for child processes to complete their work. */ int wait_for_death() { int pids_left = pidcount; while (pids_left > 0) { int status; pid_t w = waitpid(WAIT_ANY, &status, 0); if (status < 0) { return -1; } else { unsigned int i; for (i = 0; i < pidcount; i++) if (pids[i] == w) { pids_left--; break; } } } return 0; } dlt-daemon-2.18.4/src/tests/dlt-test-multi-process.h000066400000000000000000000016171353342203500223050ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2011-2015, BMW AG * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author Lassi Marttala * * \copyright Copyright © 2011-2015 BMW AG. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file dlt-test-multi-process.h */ #ifndef DLT_TEST_MULTI_PROCESS_H_ #define DLT_TEST_MULTI_PROCESS_H_ #define DMPT_NAME "DMPT" #define PAYLOAD_DATA "qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBM1234567890" #define ECUID "ECU1" #endif /* DLT_TEST_MULTI_PROCESS_H_ */ dlt-daemon-2.18.4/src/tests/dlt-test-receiver-multiple-files.sh000077500000000000000000000037731353342203500244270ustar00rootroot00000000000000#!/bin/bash # check if dlt-daemon is running daemon_running=`/usr/bin/ps -C dlt-daemon | wc -l` daemon_pid=0 if [ "$daemon_running" -lt "2" ]; then echo "No daemon running, starting one myself" /usr/bin/dlt-daemon > /tmp/dlt_daemon_dlt_receiver_test.txt & daemon_pid=$! echo "daemon pid: " ${daemon_pid} else echo "dlt-daemon already running" fi # create a directory in /tmp where all logs will be stored output_dir=`mktemp -d /tmp/DLT_TESTING_XXXXXX` echo "Using directory " ${output_dir} # start dlt-receive (in background) and store PID echo "Starting dlt-receive" /usr/bin/dlt-receive -o ${output_dir}/dlt_test.dlt localhost & dlt_receive_pid=$! disown # start dlt-example-user to create some logs # sleep time: 100ms # number of messages: 10 /usr/bin/dlt-example-user -g -d 100 -n 10 TEST_MESSAGE_ONE # stop dlt-receive kill ${dlt_receive_pid} # show content of /tmp echo "log-file after first run" ls -l ${output_dir} # start dlt-receive (in background) and store PID echo "Starting dlt-receive" /usr/bin/dlt-receive -o ${output_dir}/dlt_test.dlt localhost & dlt_receive_pid=$! disown # start dlt-example-user to create some logs (use different number of messages) /usr/bin/dlt-example-user -d 100 -n 20 TEST_MESSAGE_TWO # show content of /tmp --> original file was overwritten kill ${dlt_receive_pid} echo "log-file after second run" ls -l ${output_dir} # start dlt-receive with small maximum file size (in background) and store PID echo "Starting dlt-receive" /usr/bin/dlt-receive -o ${output_dir}/dlt_test.dlt -c 3K localhost & dlt_receive_pid=$! disown # start dlt-example-user to create some logs (use even more messages then before) /usr/bin/dlt-example-user -d 20 -n 500 TEST_MESSAGE_THREE # show content of /tmp --> multiple files were created, the original file was preserved echo "log-file after third run (should show multiple files)" ls -l ${output_dir} # directory will not be cleaned up echo "Used directory " ${output_dir} if [ "${daemon_pid}" -ne "0" ]; then sleep 1 kill ${daemon_pid} fi dlt-daemon-2.18.4/src/tests/dlt-test-stress-client.c000066400000000000000000000441711353342203500222730ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2011-2015, BMW AG * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author Alexander Wenzel * * \copyright Copyright © 2011-2015 BMW AG. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file dlt-test-stress-client.c */ /******************************************************************************* ** ** ** SRC-MODULE: dlt-test-stress-client.c ** ** ** ** TARGET : linux ** ** ** ** PROJECT : DLT ** ** ** ** AUTHOR : Alexander Wenzel Alexander.AW.Wenzel@bmw.de ** ** Markus Klein ** ** ** ** PURPOSE : ** ** ** ** REMARKS : ** ** ** ** PLATFORM DEPENDANT [yes/no]: yes ** ** ** ** TO BE CHANGED BY USER [yes/no]: no ** ** ** *******************************************************************************/ /******************************************************************************* ** Author Identity ** ******************************************************************************** ** ** ** Initials Name Company ** ** -------- ------------------------- ---------------------------------- ** ** aw Alexander Wenzel BMW ** ** mk Markus Klein Fraunhofer ESK ** *******************************************************************************/ /******************************************************************************* ** Revision Control History ** *******************************************************************************/ /* * $LastChangedRevision: 1670 $ * $LastChangedDate: 2011-04-08 15:12:06 +0200 (Fr, 08. Apr 2011) $ * $LastChangedBy$ * Initials Date Comment * aw 13.01.2010 initial */ #include /* for isprint() */ #include /* for atoi() */ #include /* for S_IRUSR, S_IWUSR, S_IRGRP, S_IROTH */ #include /* for open() */ #include /* for strcmp() */ #include /* for writev() */ #include "dlt_client.h" #include "dlt_protocol.h" #include "dlt_user.h" #define DLT_TESTCLIENT_TEXTBUFSIZE 10024 /* Size of buffer for text output */ #define DLT_TESTCLIENT_ECU_ID "ECU1" #define DLT_TESTCLIENT_NUM_TESTS 7 /* Function prototypes */ int dlt_testclient_message_callback(DltMessage *message, void *data); typedef struct { int aflag; int sflag; int xflag; int mflag; int vflag; int yflag; char *ovalue; char *fvalue; char *tvalue; char *evalue; int nvalue; int bvalue; char ecuid[4]; int ohandle; DltFile file; DltFilter filter; int running_test; int test_counter_macro[DLT_TESTCLIENT_NUM_TESTS]; int test_counter_function[DLT_TESTCLIENT_NUM_TESTS]; int tests_passed; int tests_failed; int sock; /* test values */ unsigned long bytes_received; unsigned long time_elapsed; int last_value; int count_received_messages; int count_not_received_messages; } DltTestclientData; /** * Print usage information of tool. */ void usage() { char version[255]; dlt_get_version(version, 255); printf("Usage: dlt-test-stress-client [options] hostname/serial_device_name\n"); printf("Test against received data from dlt-test-stress-user.\n"); printf("%s \n", version); printf("Options:\n"); printf(" -a Print DLT messages; payload as ASCII\n"); printf(" -x Print DLT messages; payload as hex\n"); printf(" -m Print DLT messages; payload as hex and ASCII\n"); printf(" -s Print DLT messages; only headers\n"); printf(" -v Verbose mode\n"); printf(" -h Usage\n"); printf(" -y Serial device mode\n"); printf(" -b baudrate Serial device baudrate (Default: 115200)\n"); printf(" -e ecuid Set ECU ID (Default: ECU1)\n"); printf(" -o filename Output messages in new DLT file\n"); printf(" -f filename Enable filtering of messages\n"); printf(" -n messages Number of messages to be received per test(Default: 10000)\n"); } /** * Main function of tool. */ int main(int argc, char *argv[]) { DltClient dltclient; DltTestclientData dltdata; int c, i; int index; /* Initialize dltclient */ memset(&dltclient, 0x0, sizeof(DltClient)); /* Initialize dltdata */ dltdata.aflag = 0; dltdata.sflag = 0; dltdata.xflag = 0; dltdata.mflag = 0; dltdata.vflag = 0; dltdata.yflag = 0; dltdata.ovalue = 0; dltdata.fvalue = 0; dltdata.evalue = 0; dltdata.bvalue = 0; dltdata.nvalue = 10000; dltdata.ohandle = -1; dltdata.running_test = 0; for (i = 0; i < DLT_TESTCLIENT_NUM_TESTS; i++) { dltdata.test_counter_macro[i] = 0; dltdata.test_counter_function[i] = 0; } dltdata.tests_passed = 0; dltdata.tests_failed = 0; dltdata.bytes_received = 0; dltdata.time_elapsed = dlt_uptime(); dltdata.last_value = 0; dltdata.count_received_messages = 0; dltdata.count_not_received_messages = 0; dltdata.sock = -1; /* Fetch command line arguments */ opterr = 0; while ((c = getopt (argc, argv, "vashyxmf:o:e:b:n:")) != -1) switch (c) { case 'v': { dltdata.vflag = 1; break; } case 'a': { dltdata.aflag = 1; break; } case 's': { dltdata.sflag = 1; break; } case 'x': { dltdata.xflag = 1; break; } case 'm': { dltdata.mflag = 1; break; } case 'h': { usage(); return -1; } case 'y': { dltdata.yflag = 1; break; } case 'f': { dltdata.fvalue = optarg; break; } case 'o': { dltdata.ovalue = optarg; break; } case 'e': { dltdata.evalue = optarg; break; } case 'b': { dltdata.bvalue = atoi(optarg); break; } case 'n': { dltdata.nvalue = atoi(optarg); break; } case '?': { if ((optopt == 'o') || (optopt == 'f') || (optopt == 't')) fprintf (stderr, "Option -%c requires an argument.\n", optopt); else if (isprint (optopt)) fprintf (stderr, "Unknown option `-%c'.\n", optopt); else fprintf (stderr, "Unknown option character `\\x%x'.\n", optopt); /* unknown or wrong option used, show usage information and terminate */ usage(); return -1; } default: { abort (); return -1;/*for parasoft */ } } /* Initialize DLT Client */ dlt_client_init(&dltclient, dltdata.vflag); /* Register callback to be called when message was received */ dlt_client_register_message_callback(dlt_testclient_message_callback); /* Setup DLT Client structure */ dltclient.mode = dltdata.yflag; if (dltclient.mode == 0) { for (index = optind; index < argc; index++) if (dlt_client_set_server_ip(&dltclient, argv[index]) == -1) { fprintf(stderr, "set server ip didn't succeed\n"); return -1; } if (dltclient.servIP == 0) { /* no hostname selected, show usage and terminate */ fprintf(stderr, "ERROR: No hostname selected\n"); usage(); dlt_client_cleanup(&dltclient, dltdata.vflag); return -1; } } else { for (index = optind; index < argc; index++) if (dlt_client_set_serial_device(&dltclient, argv[index]) == -1) { fprintf(stderr, "set serial device didn't succeed\n"); return -1; } if (dltclient.serialDevice == 0) { /* no serial device name selected, show usage and terminate */ fprintf(stderr, "ERROR: No serial device name specified\n"); usage(); return -1; } dlt_client_setbaudrate(&dltclient, dltdata.bvalue); } /* initialise structure to use DLT file */ dlt_file_init(&(dltdata.file), dltdata.vflag); /* first parse filter file if filter parameter is used */ dlt_filter_init(&(dltdata.filter), dltdata.vflag); if (dltdata.fvalue) { if (dlt_filter_load(&(dltdata.filter), dltdata.fvalue, dltdata.vflag) < DLT_RETURN_OK) { dlt_file_free(&(dltdata.file), dltdata.vflag); return -1; } dlt_file_set_filter(&(dltdata.file), &(dltdata.filter), dltdata.vflag); } /* open DLT output file */ if (dltdata.ovalue) { dltdata.ohandle = open(dltdata.ovalue, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); /* mode: wb */ if (dltdata.ohandle == -1) { dlt_file_free(&(dltdata.file), dltdata.vflag); fprintf(stderr, "ERROR: Output file %s cannot be opened!\n", dltdata.ovalue); return -1; } } if (dltdata.evalue) dlt_set_id(dltdata.ecuid, dltdata.evalue); else dlt_set_id(dltdata.ecuid, DLT_TESTCLIENT_ECU_ID); /* Connect to TCP socket or open serial device */ if (dlt_client_connect(&dltclient, dltdata.vflag) != DLT_RETURN_ERROR) { dltdata.sock = dltclient.sock; /* Dlt Client Main Loop */ dlt_client_main_loop(&dltclient, &dltdata, dltdata.vflag); /* Dlt Client Cleanup */ dlt_client_cleanup(&dltclient, dltdata.vflag); } /* dlt-receive cleanup */ if (dltdata.ovalue) close(dltdata.ohandle); dlt_file_free(&(dltdata.file), dltdata.vflag); dlt_filter_free(&(dltdata.filter), dltdata.vflag); return 0; } int dlt_testclient_message_callback(DltMessage *message, void *data) { static char text[DLT_TESTCLIENT_TEXTBUFSIZE]; DltTestclientData *dltdata; uint32_t type_info, type_info_tmp; int16_t length, length_tmp; /* the macro can set this variable to -1 */ uint8_t *ptr; int32_t datalength; int32_t value; uint32_t value_tmp = 0; struct iovec iov[2]; int bytes_written; if ((message == 0) || (data == 0)) return -1; dltdata = (DltTestclientData *)data; /* prepare storage header */ if (DLT_IS_HTYP_WEID(message->standardheader->htyp)) dlt_set_storageheader(message->storageheader, message->headerextra.ecu); else dlt_set_storageheader(message->storageheader, dltdata->ecuid); if ((dltdata->fvalue == 0) || (dltdata->fvalue && (dlt_message_filter_check(message, &(dltdata->filter), dltdata->vflag) == DLT_RETURN_TRUE))) { /*dlt_message_header(message,text,sizeof(text),dltdata->vflag); */ if (dltdata->aflag) { /*printf("%s ",text); */ } /*dlt_message_payload(message,text,sizeof(text),DLT_OUTPUT_ASCII,dltdata->vflag); */ if (dltdata->aflag) { /*printf("[%s]\n",text); */ } /* do something here */ /* Count number of received bytes */ dltdata->bytes_received += message->datasize + message->headersize - sizeof(DltStorageHeader); /* print number of received bytes */ if ((dlt_uptime() - dltdata->time_elapsed) > 10000) { printf("Received %lu Bytes/s\n", dltdata->bytes_received /**10000/(dlt_uptime()-dltdata->time_elapsed)*/); /*printf("Received %lu Bytes received\n",dltdata->bytes_received); */ dltdata->time_elapsed = dlt_uptime(); dltdata->bytes_received = 0; } /* Extended header */ if (DLT_IS_HTYP_UEH(message->standardheader->htyp)) { /* Log message */ if ((DLT_GET_MSIN_MSTP(message->extendedheader->msin)) == DLT_TYPE_LOG) { /* Verbose */ if (DLT_IS_MSIN_VERB(message->extendedheader->msin)) { /* 2 arguments */ if (message->extendedheader->noar == 2) { /* verbose mode */ type_info = 0; type_info_tmp = 0; length = 0; length_tmp = 0; /* the macro can set this variable to -1 */ ptr = message->databuffer; datalength = message->datasize; /* first read the type info of the first argument: must be string */ DLT_MSG_READ_VALUE(type_info_tmp, ptr, datalength, uint32_t); type_info = DLT_ENDIAN_GET_32(message->standardheader->htyp, type_info_tmp); if (type_info & DLT_TYPE_INFO_SINT) { /* read value */ DLT_MSG_READ_VALUE(value_tmp, ptr, datalength, int32_t); value = DLT_ENDIAN_GET_32(message->standardheader->htyp, value_tmp); /*printf("%d\n",value); */ if (value < dltdata->last_value) { if (dltdata->nvalue == dltdata->count_received_messages) printf("PASSED: %d Msg received, %d not received\n", dltdata->count_received_messages, dltdata->count_not_received_messages); else printf("FAILED: %d Msg received, %d not received\n", dltdata->count_received_messages, dltdata->count_not_received_messages); dltdata->last_value = 0; dltdata->count_received_messages = 0; dltdata->count_not_received_messages = value - 1; } else { dltdata->count_not_received_messages += value - dltdata->last_value - 1; } dltdata->last_value = value; dltdata->count_received_messages++; if (length >= 0) { ptr += length; datalength -= length; /* read type of second argument: must be raw */ DLT_MSG_READ_VALUE(type_info_tmp, ptr, datalength, uint32_t); type_info = DLT_ENDIAN_GET_32(message->standardheader->htyp, type_info_tmp); if (type_info & DLT_TYPE_INFO_RAWD) { /* get length of raw data block */ DLT_MSG_READ_VALUE(length_tmp, ptr, datalength, uint16_t); length = DLT_ENDIAN_GET_16(message->standardheader->htyp, length_tmp); if ((length >= 0) && (length == datalength)) /*printf("Raw data found in payload, length="); */ /*printf("%d, datalength=%d \n", length, datalength); */ dltdata->test_counter_macro[3]++; } } } } } } } /* if no filter set or filter is matching display message */ if (dltdata->xflag) dlt_message_print_hex(message, text, DLT_TESTCLIENT_TEXTBUFSIZE, dltdata->vflag); else if (dltdata->mflag) dlt_message_print_mixed_plain(message, text, DLT_TESTCLIENT_TEXTBUFSIZE, dltdata->vflag); else if (dltdata->sflag) dlt_message_print_header(message, text, sizeof(text), dltdata->vflag); /* if file output enabled write message */ if (dltdata->ovalue) { iov[0].iov_base = message->headerbuffer; iov[0].iov_len = message->headersize; iov[1].iov_base = message->databuffer; iov[1].iov_len = message->datasize; bytes_written = writev(dltdata->ohandle, iov, 2); if (0 > bytes_written) { printf("dlt_testclient_message_callback, error when: writev(dltdata->ohandle, iov, 2) \n"); return -1; } } } return 0; } dlt-daemon-2.18.4/src/tests/dlt-test-stress-user.c000066400000000000000000000201561353342203500217700ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2011-2015, BMW AG * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author Alexander Wenzel * * \copyright Copyright © 2011-2015 BMW AG. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file dlt-test-stress-user.c */ /******************************************************************************* ** ** ** SRC-MODULE: dlt-test-stress-user.c ** ** ** ** TARGET : linux ** ** ** ** PROJECT : DLT ** ** ** ** AUTHOR : Alexander Wenzel Alexander.AW.Wenzel@bmw.de ** ** Markus Klein ** ** ** ** PURPOSE : ** ** ** ** REMARKS : ** ** ** ** PLATFORM DEPENDANT [yes/no]: yes ** ** ** ** TO BE CHANGED BY USER [yes/no]: no ** ** ** *******************************************************************************/ /******************************************************************************* ** Author Identity ** ******************************************************************************** ** ** ** Initials Name Company ** ** -------- ------------------------- ---------------------------------- ** ** aw Alexander Wenzel BMW ** ** mk Markus Klein Fraunhofer ESK ** *******************************************************************************/ /******************************************************************************* ** Revision Control History ** *******************************************************************************/ /* * $LastChangedRevision: 1670 $ * $LastChangedDate: 2011-04-08 15:12:06 +0200 (Fr, 08. Apr 2011) $ * $LastChangedBy$ * Initials Date Comment * aw 13.01.2010 initial */ #include /* for printf() and fprintf() */ #include #include /* for atoi(), abort() */ #include /* for memset() */ #include /* for isprint() */ #include "dlt.h" #define DLT_TEST_NUM_CONTEXT 7 /* Test functions... */ int testall(int count, int repeat, int delay, int size); /* Context declaration.. */ DLT_DECLARE_CONTEXT(context_info) /* for macro interface */ DLT_DECLARE_CONTEXT(context_macro_callback) DLT_DECLARE_CONTEXT(context_macro_test[DLT_TEST_NUM_CONTEXT]) /* for function interface */ DltContext context_function_callback; DltContext context_function_test[DLT_TEST_NUM_CONTEXT]; DltContextData context_data; /** * Print usage information of tool. */ void usage() { char version[255]; dlt_get_version(version, 255); printf("Usage: dlt-test-stress-user [options]\n"); printf("Test user application providing Test messages.\n"); printf("%s \n", version); printf("Options:\n"); printf(" -v Verbose mode\n"); printf(" -f filename Use local log file instead of sending to daemon\n"); printf(" -n count Number of messages to be sent per test (Default: 10000)\n"); printf(" -r repeat How often test is repeated (Default: 100)\n"); printf(" -d delay Delay between sent messages in uSec (Default: 1000)\n"); printf(" -s size Size of extra message data in bytes (Default: 100)\n"); } /** * Main function of tool. */ int main(int argc, char *argv[]) { /*int vflag = 0; */ char *fvalue = 0; int nvalue = 10000; int rvalue = 100; int dvalue = 1000; int svalue = 100; int c; opterr = 0; while ((c = getopt (argc, argv, "vf:n:r:d:s:")) != -1) switch (c) { case 'v': { /*vflag = 1; */ break; } case 'f': { fvalue = optarg; break; } case 'n': { nvalue = atoi(optarg); break; } case 'r': { rvalue = atoi(optarg); break; } case 'd': { dvalue = atoi(optarg); break; } case 's': { svalue = atoi(optarg); break; } case '?': { if ((optopt == 'f') || (optopt == 'n') || (optopt == 'r') || (optopt == 'd') || (optopt == 's')) fprintf (stderr, "Option -%c requires an argument.\n", optopt); else if (isprint (optopt)) fprintf (stderr, "Unknown option `-%c'.\n", optopt); else fprintf (stderr, "Unknown option character `\\x%x'.\n", optopt); /* unknown or wrong option used, show usage information and terminate */ usage(); return -1; } default: { abort (); return -1;/*for parasoft */ } } if (fvalue) { /* DLT is intialised automatically, except another output target will be used */ if (dlt_init_file(fvalue) < 0) /* log to file */ return -1; } /* Register APP */ DLT_REGISTER_APP("DIFT", "DLT Interface Test"); /* Register CONTEXTS... */ DLT_REGISTER_CONTEXT(context_info, "INFO", "Information context"); /* Tests starting */ printf("Tests starting\n"); /*DLT_LOG(context_info,DLT_LOG_INFO,DLT_STRING("Tests starting")); */ /* wait 3 seconds before starting */ /*sleep(3); */ testall(nvalue, rvalue, dvalue, svalue); /* Tests finished */ printf("Tests finished\n"); /*DLT_LOG(context_info,DLT_LOG_INFO,DLT_STRING("Tests finished")); */ /* wait 3 seconds before terminating application */ /*sleep(3); */ /* Unregister CONTEXTS... */ DLT_UNREGISTER_CONTEXT(context_info); /* Unregister APP */ DLT_UNREGISTER_APP(); return 0; } /******************/ /* The test cases */ /******************/ int testall(int count, int repeat, int delay, int size) { char buffer[size]; int num, rnum; struct timespec ts; for (num = 0; num < size; num++) buffer[num] = num; /* Test All: Test all start */ /*printf("Test1: Test all\n"); */ /*DLT_LOG(context_info,DLT_LOG_INFO,DLT_STRING("Test1: Test all")); */ for (rnum = 0; rnum < repeat; rnum++) for (num = 1; num <= count; num++) { DLT_LOG(context_info, DLT_LOG_INFO, DLT_INT(num), DLT_RAW(buffer, size)); ts.tv_sec = (delay * 1000) / 1000000000; ts.tv_nsec = (delay * 1000) % 1000000000; nanosleep(&ts, NULL); } /* wait 5 seconds after test */ /*sleep(5); */ /*DLT_LOG(context_info,DLT_LOG_INFO,DLT_STRING("Test1: finished")); */ return 0; } dlt-daemon-2.18.4/src/tests/dlt-test-stress.c000066400000000000000000000244031353342203500210130ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2011-2015, BMW AG * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author Alexander Wenzel * * \copyright Copyright © 2011-2015 BMW AG. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file dlt-test-stress.c */ /******************************************************************************* ** ** ** SRC-MODULE: dlt-test-stress.c ** ** ** ** TARGET : linux ** ** ** ** PROJECT : DLT ** ** ** ** AUTHOR : Alexander Wenzel Alexander.AW.Wenzel@bmw.de ** ** Markus Klein ** ** ** ** PURPOSE : ** ** ** ** REMARKS : ** ** ** ** PLATFORM DEPENDANT [yes/no]: yes ** ** ** ** TO BE CHANGED BY USER [yes/no]: no ** ** ** *******************************************************************************/ /******************************************************************************* ** Author Identity ** ******************************************************************************** ** ** ** Initials Name Company ** ** -------- ------------------------- ---------------------------------- ** ** aw Alexander Wenzel BMW ** ** mk Markus Klein Fraunhofer ESK ** *******************************************************************************/ /******************************************************************************* ** Revision Control History ** *******************************************************************************/ /* * $LastChangedRevision: 1670 $ * $LastChangedDate: 2011-04-08 15:12:06 +0200 (Fr, 08. Apr 2011) $ * $LastChangedBy$ * Initials Date Comment * aw 13.01.2010 initial */ #include #include /* for isprint() */ #include #include /* for printf() and fprintf() */ #include /* for atoi() and exit() */ #include /* for memset() */ #include /* for close() */ #include /* POSIX Threads */ #include "dlt.h" #include "dlt_common.h" /* for dlt_get_version() */ DltContext mycontext[9999]; typedef struct { int num; } thread_data_t; #define STRESS1_NUM_CONTEXTS 3000 #define STRESS2_MAX_NUM_THREADS 64 #define STRESS3_MAX_NUM_MESSAGES 512 #define MAX_TESTS 3 void stress1(void); void stress2(void); void thread_function(void); void stress3(void); /* * This environment variable is used when developer wants to interrupt program manually */ char *env_manual_interruption = 0; /** * Print usage information of tool. */ void usage() { char version[255]; dlt_get_version(version, 255); printf("Usage: dlt-test-stress [options]\n"); printf("Test application executing several stress tests.\n"); printf("%s \n", version); printf("Options:\n"); printf(" -v Verbose mode\n"); printf(" -f filename Use local log file instead of sending to daemon\n"); printf(" -1 Execute test 1 (register/unregister many contexts)\n"); printf(" In order to interrupt test manually (e.g: wait for ENTER key),\n"); printf(" set environment variable DLT_TEST_MANUAL_INTERRUPTION=1\n"); printf(" -2 Execute test 2 (multiple threads logging data)\n"); printf(" -3 Execute test 3 (logging much data)\n"); } /** * Main function of tool. */ int main(int argc, char *argv[]) { /*int vflag = 0; */ char *fvalue = 0; int test[MAX_TESTS]; int i, c, help; for (i = 0; i < MAX_TESTS; i++) test[i] = 0; opterr = 0; while ((c = getopt (argc, argv, "vf:123")) != -1) switch (c) { case 'v': { /*vflag = 1; */ break; } case 'f': { fvalue = optarg; break; } case '1': { test[0] = 1; env_manual_interruption = getenv("DLT_TEST_MANUAL_INTERRUPTION"); break; } case '2': { test[1] = 1; break; } case '3': { test[2] = 1; break; } case '?': { if (optopt == 'f') fprintf (stderr, "Option -%c requires an argument.\n", optopt); else if (isprint (optopt)) fprintf (stderr, "Unknown option `-%c'.\n", optopt); else fprintf (stderr, "Unknown option character `\\x%x'.\n", optopt); /* unknown or wrong option used, show usage information and terminate */ usage(); return -1; } default: { abort (); return -1;/*for parasoft */ } } if (fvalue) { /* DLT is intialised automatically, except another output target will be used */ if (dlt_init_file(fvalue) < 0) /* log to file */ return -1; } help = 0; for (i = 0; i < MAX_TESTS; i++) if (test[i] == 1) { help = 1; break; } if (help == 0) { usage(); return -1; } DLT_REGISTER_APP("DSTS", "DLT daemon stress tests"); if (test[0]) stress1(); if (test[1]) stress2(); if (test[2]) stress3(); DLT_UNREGISTER_APP(); sleep(1); return 0; } void stress1(void) { int i, c; char ctid[5]; struct timespec ts; printf("Starting stress test1...\n"); printf("* Register %d contexts...\n", STRESS1_NUM_CONTEXTS); for (i = 0; i < STRESS1_NUM_CONTEXTS; i++) { /* Generate id */ memset(ctid, 0, 5); snprintf(ctid, 5, "%d", i); /*printf("%i: '%s' \n",i,ctid); */ dlt_register_context(&(mycontext[i]), ctid, ctid); ts.tv_sec = 0; ts.tv_nsec = 500 * 1000; nanosleep(&ts, NULL); } if (env_manual_interruption && (strcmp(env_manual_interruption, "1") == 0)) { printf("press \"Enter\" to terminate test"); while (1) { c=getchar(); /* if "Return" is pressed, exit loop; */ if (c==10) { break; } } } printf("* Unregister %d contexts...\n", STRESS1_NUM_CONTEXTS); for (i = 0; i < STRESS1_NUM_CONTEXTS; i++) { DLT_UNREGISTER_CONTEXT(mycontext[i]); ts.tv_sec = 0; ts.tv_nsec = 500 * 1000; nanosleep(&ts, NULL); } printf("Finished stress test1 \n\n"); } void stress2(void) { int ret, index; struct timespec ts; pthread_t thread[STRESS2_MAX_NUM_THREADS]; thread_data_t thread_data[STRESS2_MAX_NUM_THREADS]; printf("Starting stress test2... \n"); srand(time(NULL)); printf("* Creating %d Threads, each of them registers one context,\n", STRESS2_MAX_NUM_THREADS); printf(" sending one log message, then unregisters the context\n"); for (index = 0; index < STRESS2_MAX_NUM_THREADS; index++) { thread_data[index].num = index; ret = pthread_create(&(thread[index]), NULL, (void *)&thread_function, (void *)&(thread_data[index])); if (ret != 0) printf("Error creating thread %d: %s \n", index, strerror(errno)); ts.tv_sec = 0; ts.tv_nsec = 1000 * 1000; nanosleep(&ts, NULL); } for (index = 0; index < STRESS2_MAX_NUM_THREADS; index++) pthread_join(thread[index], NULL); printf("Finished stress test2 \n\n"); } void thread_function(void) { /*thread_data_t *data; */ DLT_DECLARE_CONTEXT(context_thread1); char ctid[5]; struct timespec ts; /*data = (thread_data_t *) ptr; */ memset(ctid, 0, 5); /* Create random context id */ snprintf(ctid, 5, "%.2x", rand() & 0x0000ffff); ts.tv_sec = 0; ts.tv_nsec = rand(); nanosleep(&ts, NULL); DLT_REGISTER_CONTEXT(context_thread1, ctid, ctid); DLT_LOG(context_thread1, DLT_LOG_INFO, DLT_STRING(ctid)); DLT_UNREGISTER_CONTEXT(context_thread1); } void stress3(void) { DLT_DECLARE_CONTEXT(context_stress3); char buffer[STRESS3_MAX_NUM_MESSAGES]; int num; struct timespec ts; /* Performance test */ DLT_REGISTER_CONTEXT(context_stress3, "TST3", "Stress Test 3 - Performance"); printf("Starting stress test3... \n"); printf("* Logging raw data, up to a size of %d\n", STRESS3_MAX_NUM_MESSAGES); for (num = 0; num < STRESS3_MAX_NUM_MESSAGES; num++) { buffer[num] = num; DLT_LOG(context_stress3, DLT_LOG_INFO, DLT_INT(num), DLT_RAW(buffer, num)); ts.tv_sec = 0; ts.tv_nsec = 10000 * 1000; nanosleep(&ts, NULL); } printf("Finished stress test3 \n\n"); } dlt-daemon-2.18.4/src/tests/dlt-test-user.c000066400000000000000000001351241353342203500204510ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2011-2015, BMW AG * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author Alexander Wenzel * * \copyright Copyright © 2011-2015 BMW AG. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file dlt-test-user.c */ /******************************************************************************* ** ** ** SRC-MODULE: dlt-test-user.c ** ** ** ** TARGET : linux ** ** ** ** PROJECT : DLT ** ** ** ** AUTHOR : Alexander Wenzel Alexander.AW.Wenzel@bmw.de ** ** Markus Klein ** ** ** ** PURPOSE : ** ** ** ** REMARKS : ** ** ** ** PLATFORM DEPENDANT [yes/no]: yes ** ** ** ** TO BE CHANGED BY USER [yes/no]: no ** ** ** *******************************************************************************/ /******************************************************************************* ** Author Identity ** ******************************************************************************** ** ** ** Initials Name Company ** ** -------- ------------------------- ---------------------------------- ** ** aw Alexander Wenzel BMW ** ** mk Markus Klein Fraunhofer ESK ** *******************************************************************************/ /******************************************************************************* ** Revision Control History ** *******************************************************************************/ /* * $LastChangedRevision: 1670 $ * $LastChangedDate: 2011-04-08 15:12:06 +0200 (Fr, 08. Apr 2011) $ * $LastChangedBy$ * Initials Date Comment * aw 13.01.2010 initial */ #include /* for printf() and fprintf() */ #include #include /* for atoi(), abort() */ #include /* for memset() */ #include /* for isprint() */ #include "dlt.h" #define DLT_TEST_NUM_CONTEXT 9 /* LogLevel string representation */ static const char *loglevelstr[DLT_LOG_MAX] = { "DLT_LOG_OFF", "DLT_LOG_FATAL", "DLT_LOG_ERROR", "DLT_LOG_WARN", "DLT_LOG_INFO", "DLT_LOG_DEBUG", "DLT_LOG_VERBOSE" }; /* Test functions... */ /* for macro interface */ int test1m(void); int test2m(void); int test3m(void); int test4m(void); int test5m(void); int test6m(void); int test7m(void); int test8m(void); int test9m(void); /* for function interface */ int test1f(void); int test2f(void); int test3f(void); int test4f(void); int test5f(void); int test6f(void); int test7f(void); int test8f(void); int test9f(void); /* Declaration of callback functions */ int test_injection_macro_callback(uint32_t service_id, void *data, uint32_t length); int test_injection_function_callback(uint32_t service_id, void *data, uint32_t length); /* Context declaration.. */ DLT_DECLARE_CONTEXT(context_info) /* for macro interface */ DLT_DECLARE_CONTEXT(context_macro_callback) DLT_DECLARE_CONTEXT(context_macro_test[DLT_TEST_NUM_CONTEXT]) /* for function interface */ DltContext context_function_callback; DltContext context_function_test[DLT_TEST_NUM_CONTEXT]; DltContextData context_data; /** * Print usage information of tool. */ void usage() { char version[255]; dlt_get_version(version, 255); printf("Usage: dlt-test-user [options]\n"); printf("Test user application providing several Tests.\n"); printf("%s \n", version); printf("Options:\n"); printf(" -v Verbose mode\n"); printf(" -f filename Use local log file instead of sending to daemon\n"); printf(" -n count Repeats of tests (Default: 1)\n"); printf("Tests:\n"); printf(" 1m: (Macro IF) Test all log levels\n"); printf(" 2m: (Macro IF) Test all variable types (verbose) \n"); printf(" 3m: (Macro IF) Test all variable types (non-verbose) \n"); printf(" 4m: (Macro IF) Test different message sizes\n"); printf(" 5m: (Macro IF) Test high-level API\n"); printf(" 6m: (Macro IF) Test local printing\n"); printf(" 7m: (Macro IF) Test network trace\n"); printf(" 8m: (Macro IF) Test truncated network trace\n"); printf(" 9m: (Macro IF) Test segmented network trace\n"); printf(" 1f: (Function IF) Test all log levels\n"); printf(" 2f: (Function IF) Test all variable types (verbose) \n"); printf(" 3f: (Function IF) Test all variable types (non-verbose) \n"); printf(" 4f: (Function IF) Test different message sizes\n"); printf(" 5f: (Function IF) Test high-level API\n"); printf(" 6f: (Function IF) Test local printing\n"); printf(" 7f: (Function IF) Test network trace\n"); printf(" 8f: (Function IF) Test truncated network trace\n"); printf(" 9f: (Function IF) Test segmented network trace\n"); } /** * Main function of tool. */ int main(int argc, char *argv[]) { /*int vflag = 0; */ char *fvalue = 0; char *nvalue = 0; int c; int i; char ctid[4], ctdesc[255]; int num, maxnum; opterr = 0; while ((c = getopt (argc, argv, "vf:n:")) != -1) switch (c) { case 'v': { /*vflag = 1; */ break; } case 'f': { fvalue = optarg; break; } case 'n': { nvalue = optarg; break; } case '?': { if ((optopt == 'd') || (optopt == 'f') || (optopt == 'n')) fprintf (stderr, "Option -%c requires an argument.\n", optopt); else if (isprint (optopt)) fprintf (stderr, "Unknown option `-%c'.\n", optopt); else fprintf (stderr, "Unknown option character `\\x%x'.\n", optopt); /* unknown or wrong option used, show usage information and terminate */ usage(); return -1; } default: { abort (); return -1;/*for parasoft */ } } if (fvalue) { /* DLT is intialised automatically, except another output target will be used */ if (dlt_init_file(fvalue) < 0) /* log to file */ return -1; } if (nvalue) maxnum = atoi(nvalue); else maxnum = 1; /* Register APP */ DLT_REGISTER_APP("DIFT", "DLT Interface Test"); /* Register CONTEXTS... */ DLT_REGISTER_CONTEXT(context_info, "INFO", "Information context"); /* used for macro interface tests */ DLT_REGISTER_CONTEXT(context_macro_callback, "CBM", "Callback Test context for macro interface"); for (i = 0; i < DLT_TEST_NUM_CONTEXT; i++) { snprintf(ctid, 4, "TM%d", i + 1); snprintf(ctdesc, 255, "Test %d context for macro interface", i + 1); DLT_REGISTER_CONTEXT(context_macro_test[i], ctid, ctdesc); } /* used for function interface tests */ dlt_register_context(&context_function_callback, "CBF", "Callback Test context for function interface"); for (i = 0; i < DLT_TEST_NUM_CONTEXT; i++) { snprintf(ctid, 4, "TF%d", i + 1); snprintf(ctdesc, 255, "Test %d context for function interface", i + 1); dlt_register_context(&(context_function_test[i]), ctid, ctdesc); } /* Register callbacks... */ /* with macro interface */ DLT_LOG(context_macro_callback, DLT_LOG_INFO, DLT_STRING("Register callback (Macro Interface) for Injection ID: 0xFFF")); DLT_REGISTER_INJECTION_CALLBACK(context_macro_callback, 0xFFF, test_injection_macro_callback); /* with function interface */ if (dlt_user_log_write_start(&context_function_callback, &context_data, DLT_LOG_INFO) > 0) { dlt_user_log_write_string(&context_data, "Register callback (Function Interface) for Injection ID: 0xFFF"); dlt_user_log_write_finish(&context_data); } dlt_register_injection_callback(&context_function_callback, 0xFFF, test_injection_function_callback); /* Tests starting */ printf("Tests starting\n"); DLT_LOG(context_info, DLT_LOG_INFO, DLT_STRING("Tests starting")); /* wait 3 seconds before starting */ sleep(3); for (num = 0; num < maxnum; num++) { /* Execute tests... */ /* with macro interface */ test1m(); test2m(); test3m(); test4m(); test5m(); test6m(); test7m(); test8m(); test9m(); /* with function interface */ test1f(); test2f(); test3f(); test4f(); test5f(); test6f(); test7f(); test8f(); test9f(); /* wait 1 second before next repeat of tests */ sleep(1); } /* Tests finished */ printf("Tests finished\n"); DLT_LOG(context_info, DLT_LOG_INFO, DLT_STRING("Tests finished")); /* wait 3 seconds before terminating application */ sleep(3); /* Unregister CONTEXTS... */ DLT_UNREGISTER_CONTEXT(context_info); /* used for macro interface tests */ for (i = 0; i < DLT_TEST_NUM_CONTEXT; i++) DLT_UNREGISTER_CONTEXT(context_macro_test[i]); DLT_UNREGISTER_CONTEXT(context_macro_callback); /* used for function interface tests */ for (i = 0; i < DLT_TEST_NUM_CONTEXT; i++) dlt_unregister_context(&(context_function_test[i])); dlt_unregister_context(&context_function_callback); /* Unregister APP */ DLT_UNREGISTER_APP(); return 0; } /******************/ /* The test cases */ /******************/ int test1m(void) { /* Test 1: (Macro IF) Test all log levels */ printf("Test1m: (Macro IF) Test all log levels\n"); DLT_LOG(context_info, DLT_LOG_INFO, DLT_STRING("Test1: (Macro IF) Test all log levels")); DLT_LOG(context_macro_test[0], DLT_LOG_FATAL, DLT_STRING("fatal")); DLT_LOG(context_macro_test[0], DLT_LOG_ERROR, DLT_STRING("error")); DLT_LOG(context_macro_test[0], DLT_LOG_WARN, DLT_STRING("warn")); DLT_LOG(context_macro_test[0], DLT_LOG_INFO, DLT_STRING("info")); DLT_LOG(context_macro_test[0], DLT_LOG_DEBUG, DLT_STRING("debug")); DLT_LOG(context_macro_test[0], DLT_LOG_VERBOSE, DLT_STRING("verbose")); /* wait 2 second before next test */ sleep(2); DLT_LOG(context_info, DLT_LOG_INFO, DLT_STRING("Test1: (Macro IF) finished")); return 0; } int test2m(void) { char buffer[10]; int num2; /* Test 2: (Macro IF) Test all variable types (verbose) */ printf("Test2m: (Macro IF) Test all variable types (verbose)\n"); DLT_LOG(context_info, DLT_LOG_INFO, DLT_STRING("Test2: (Macro IF) Test all variable types (verbose)")); DLT_LOG(context_macro_test[1], DLT_LOG_INFO, DLT_STRING("string"), DLT_STRING("Hello world")); DLT_LOG(context_macro_test[1], DLT_LOG_INFO, DLT_STRING("utf8"), DLT_UTF8("Hello world")); DLT_LOG(context_macro_test[1], DLT_LOG_INFO, DLT_STRING("bool"), DLT_BOOL(1)); DLT_LOG(context_macro_test[1], DLT_LOG_INFO, DLT_STRING("int"), DLT_INT(INT32_MIN)); /* (-2147483647-1) */ DLT_LOG(context_macro_test[1], DLT_LOG_INFO, DLT_STRING("int8"), DLT_INT8(INT8_MIN)); /* (-128) */ DLT_LOG(context_macro_test[1], DLT_LOG_INFO, DLT_STRING("int16"), DLT_INT16(INT16_MIN)); /* (-32767-1) */ DLT_LOG(context_macro_test[1], DLT_LOG_INFO, DLT_STRING("int32"), DLT_INT32(INT32_MIN)); /* (-2147483647-1) */ DLT_LOG(context_macro_test[1], DLT_LOG_INFO, DLT_STRING("int64"), DLT_INT64(INT64_MIN)); /* (-__INT64_C(9223372036854775807)-1) */ DLT_LOG(context_macro_test[1], DLT_LOG_INFO, DLT_STRING("uint"), DLT_UINT(UINT32_MAX)); /* (4294967295U) */ DLT_LOG(context_macro_test[1], DLT_LOG_INFO, DLT_STRING("uint8"), DLT_UINT8(UINT8_MAX)); /* (255) */ DLT_LOG(context_macro_test[1], DLT_LOG_INFO, DLT_STRING("uint16"), DLT_UINT16(UINT16_MAX)); /* (65535) */ DLT_LOG(context_macro_test[1], DLT_LOG_INFO, DLT_STRING("uint32"), DLT_UINT32(UINT32_MAX)); /* (4294967295U) */ DLT_LOG(context_macro_test[1], DLT_LOG_INFO, DLT_STRING("uint64"), DLT_UINT64(UINT64_MAX)); /* (__UINT64_C(18446744073709551615)) */ DLT_LOG(context_macro_test[1], DLT_LOG_INFO, DLT_STRING("float32"), DLT_FLOAT32(FLT_MIN), DLT_FLOAT32(FLT_MAX)); DLT_LOG(context_macro_test[1], DLT_LOG_INFO, DLT_STRING("float64"), DLT_FLOAT64(DBL_MIN), DLT_FLOAT64(DBL_MAX)); for (num2 = 0; num2 < 10; num2++) buffer[num2] = num2; DLT_LOG(context_macro_test[1], DLT_LOG_INFO, DLT_STRING("raw"), DLT_RAW(buffer, 10)); /* wait 2 second before next test */ sleep(2); DLT_LOG(context_info, DLT_LOG_INFO, DLT_STRING("Test2: (Macro IF) finished")); return 0; } int test3m(void) { char buffer[10]; int num2; /* Test 3: (Macro IF) Test all variable types (non-verbose) */ printf("Test3m: (Macro IF) Test all variable types (non-verbose)\n"); DLT_LOG(context_info, DLT_LOG_INFO, DLT_STRING("Test3: (Macro IF) Test all variable types (non-verbose)")); DLT_NONVERBOSE_MODE(); DLT_LOG_ID(context_macro_test[2], DLT_LOG_INFO, 1, DLT_STRING("string"), DLT_STRING("Hello world")); DLT_LOG_ID(context_macro_test[2], DLT_LOG_INFO, 2, DLT_STRING("utf8"), DLT_UTF8("Hello world")); DLT_LOG_ID(context_macro_test[2], DLT_LOG_INFO, 3, DLT_STRING("bool"), DLT_BOOL(1)); DLT_LOG_ID(context_macro_test[2], DLT_LOG_INFO, 4, DLT_STRING("int"), DLT_INT(INT32_MIN)); /* (-2147483647-1) */ DLT_LOG_ID(context_macro_test[2], DLT_LOG_INFO, 5, DLT_STRING("int8"), DLT_INT8(INT8_MIN)); /* (-128) */ DLT_LOG_ID(context_macro_test[2], DLT_LOG_INFO, 6, DLT_STRING("int16"), DLT_INT16(INT16_MIN)); /* (-32767-1) */ DLT_LOG_ID(context_macro_test[2], DLT_LOG_INFO, 7, DLT_STRING("int32"), DLT_INT32(INT32_MIN)); /* (-2147483647-1) */ DLT_LOG_ID(context_macro_test[2], DLT_LOG_INFO, 8, DLT_STRING("int64"), DLT_INT64(INT64_MIN)); /* (-__INT64_C(9223372036854775807)-1) */ DLT_LOG_ID(context_macro_test[2], DLT_LOG_INFO, 9, DLT_STRING("uint"), DLT_UINT(UINT32_MAX)); /* (4294967295U) */ DLT_LOG_ID(context_macro_test[2], DLT_LOG_INFO, 10, DLT_STRING("uint8"), DLT_UINT8(UINT8_MAX)); /* (255) */ DLT_LOG_ID(context_macro_test[2], DLT_LOG_INFO, 11, DLT_STRING("uint16"), DLT_UINT16(UINT16_MAX)); /* (65535) */ DLT_LOG_ID(context_macro_test[2], DLT_LOG_INFO, 12, DLT_STRING("uint32"), DLT_UINT32(UINT32_MAX)); /* (4294967295U) */ DLT_LOG_ID(context_macro_test[2], DLT_LOG_INFO, 13, DLT_STRING("uint64"), DLT_UINT64(UINT64_MAX)); /* (__UINT64_C(18446744073709551615)) */ DLT_LOG_ID(context_macro_test[2], DLT_LOG_INFO, 14, DLT_STRING("float32"), DLT_FLOAT32(FLT_MIN), DLT_FLOAT32(FLT_MAX)); DLT_LOG_ID(context_macro_test[2], DLT_LOG_INFO, 15, DLT_STRING("float64"), DLT_FLOAT64(DBL_MIN), DLT_FLOAT64(DBL_MAX)); for (num2 = 0; num2 < 10; num2++) buffer[num2] = num2; DLT_LOG_ID(context_macro_test[2], DLT_LOG_INFO, 14, DLT_STRING("raw"), DLT_RAW(buffer, 10)); DLT_VERBOSE_MODE(); /* wait 2 second before next test */ sleep(2); DLT_LOG(context_info, DLT_LOG_INFO, DLT_STRING("Test3: (Macro IF) finished")); return 0; } int test4m(void) { char buffer[1024]; int num; for (num = 0; num < 1024; num++) buffer[num] = num; /* Test 4: (Macro IF) Message size test */ printf("Test4m: (Macro IF) Test different message sizes\n"); DLT_LOG(context_info, DLT_LOG_INFO, DLT_STRING("Test4: (Macro IF) Test different message sizes")); DLT_LOG(context_macro_test[3], DLT_LOG_INFO, DLT_STRING("1"), DLT_RAW(buffer, 1)); DLT_LOG(context_macro_test[3], DLT_LOG_INFO, DLT_STRING("16"), DLT_RAW(buffer, 16)); DLT_LOG(context_macro_test[3], DLT_LOG_INFO, DLT_STRING("256"), DLT_RAW(buffer, 256)); DLT_LOG(context_macro_test[3], DLT_LOG_INFO, DLT_STRING("1024"), DLT_RAW(buffer, 1024)); /* wait 2 second before next test */ sleep(2); DLT_LOG(context_info, DLT_LOG_INFO, DLT_STRING("Test4: (Macro IF) finished")); return 0; } int test5m(void) { char buffer[32]; int num; int i; void *ptr = malloc(sizeof(int)); for (num = 0; num < 32; num++) buffer[num] = num; /* Test 5: (Macro IF) Test high-level API */ printf("Test5m: (Macro IF) Test high-level API\n"); DLT_LOG(context_info, DLT_LOG_INFO, DLT_STRING("Test5: (Macro IF) Test high-level API")); DLT_LOG(context_macro_test[4], DLT_LOG_INFO, DLT_STRING("Next line: DLT_LOG_INT")); DLT_LOG_INT(context_macro_test[4], DLT_LOG_INFO, -42); DLT_LOG(context_macro_test[4], DLT_LOG_INFO, DLT_STRING("Next line: DLT_LOG_UINT")); DLT_LOG_UINT(context_macro_test[4], DLT_LOG_INFO, 42); DLT_LOG(context_macro_test[4], DLT_LOG_INFO, DLT_STRING("Next line: DLT_LOG_STRING")); DLT_LOG_STRING(context_macro_test[4], DLT_LOG_INFO, "String output"); DLT_LOG(context_macro_test[4], DLT_LOG_INFO, DLT_STRING("Next line: DLT_LOG_RAW")); DLT_LOG_RAW(context_macro_test[4], DLT_LOG_INFO, buffer, 16); DLT_LOG(context_macro_test[4], DLT_LOG_INFO, DLT_STRING("Next line: DLT_LOG_STRING_INT")); DLT_LOG_STRING_INT(context_macro_test[4], DLT_LOG_INFO, "String output: ", -42); DLT_LOG(context_macro_test[4], DLT_LOG_INFO, DLT_STRING("Next line: DLT_LOG_STRING_UINT")); DLT_LOG_STRING_UINT(context_macro_test[4], DLT_LOG_INFO, "String output: ", 42); DLT_LOG(context_macro_test[4], DLT_LOG_INFO, DLT_STRING("Next line: DLT_LOG_PTR")); DLT_LOG(context_macro_test[4], DLT_LOG_INFO, DLT_PTR(ptr)); DLT_LOG(context_macro_test[4], DLT_LOG_INFO, DLT_STRING("Next lines: DLT_IS_LOG_LEVEL_ENABLED")); for (i = DLT_LOG_FATAL; i < DLT_LOG_MAX; i++) { if (DLT_IS_LOG_LEVEL_ENABLED(context_macro_test[4], i)) DLT_LOG(context_info, DLT_LOG_INFO, DLT_STRING("Loglevel is enabled: "), DLT_STRING(loglevelstr[i])); else DLT_LOG(context_info, DLT_LOG_INFO, DLT_STRING("Loglevel is disabled: "), DLT_STRING(loglevelstr[i])); } /* wait 2 second before next test */ sleep(2); DLT_LOG(context_info, DLT_LOG_INFO, DLT_STRING("Test5: (Macro IF) finished")); free(ptr); return 0; } int test6m(void) { /* Test 6: (Macro IF) Test local printing */ printf("Test6m: (Macro IF) Test local printing\n"); DLT_LOG_STRING(context_info, DLT_LOG_INFO, "Test 6: (Macro IF) Test local printing"); DLT_ENABLE_LOCAL_PRINT(); DLT_LOG_STRING(context_macro_test[5], DLT_LOG_INFO, "Message (visible: locally printed)"); DLT_DISABLE_LOCAL_PRINT(); DLT_LOG_STRING(context_macro_test[5], DLT_LOG_INFO, "Message (invisible: not locally printed)"); /* wait 2 second before next test */ sleep(2); DLT_LOG(context_info, DLT_LOG_INFO, DLT_STRING("Test6: (Macro IF) finished")); return 0; } int test7m(void) { char buffer[32]; int num; for (num = 0; num < 32; num++) buffer[num] = num; /* Show all log messages and traces */ DLT_SET_APPLICATION_LL_TS_LIMIT(DLT_LOG_VERBOSE, DLT_TRACE_STATUS_ON); /* Test 7: (Macro IF) Test network trace */ printf("Test7m: (Macro IF) Test network trace\n"); DLT_LOG_STRING(context_info, DLT_LOG_INFO, "Test 7: (Macro IF) Test network trace"); /* Dummy messages: 16 byte header, 32 byte payload */ DLT_TRACE_NETWORK(context_macro_test[6], DLT_NW_TRACE_IPC, 16, buffer, 32, buffer); DLT_TRACE_NETWORK(context_macro_test[6], DLT_NW_TRACE_CAN, 16, buffer, 32, buffer); DLT_TRACE_NETWORK(context_macro_test[6], DLT_NW_TRACE_FLEXRAY, 16, buffer, 32, buffer); DLT_TRACE_NETWORK(context_macro_test[6], DLT_NW_TRACE_MOST, 16, buffer, 32, buffer); /* wait 2 second before next test */ sleep(2); DLT_LOG(context_info, DLT_LOG_INFO, DLT_STRING("Test7: (Macro IF) finished")); DLT_SET_APPLICATION_LL_TS_LIMIT(DLT_LOG_DEFAULT, DLT_TRACE_STATUS_DEFAULT); sleep(2); return 0; } int test8m(void) { char buffer[1024 * 5]; int num; for (num = 0; num < 1024 * 5; num++) buffer[num] = num; /* Show all log messages and traces */ DLT_SET_APPLICATION_LL_TS_LIMIT(DLT_LOG_VERBOSE, DLT_TRACE_STATUS_ON); /* Test 8: (Macro IF) Test truncated network trace*/ printf("Test8m: (Macro IF) Test truncated network trace\n"); DLT_LOG_STRING(context_info, DLT_LOG_INFO, "Test 8: (Macro IF) Test truncated network trace"); /* Dummy messages: 16 byte header, 5k payload */ DLT_TRACE_NETWORK_TRUNCATED(context_macro_test[7], DLT_NW_TRACE_IPC, 16, buffer, 1024 * 5, buffer); DLT_TRACE_NETWORK_TRUNCATED(context_macro_test[7], DLT_NW_TRACE_CAN, 16, buffer, 1024 * 5, buffer); DLT_TRACE_NETWORK_TRUNCATED(context_macro_test[7], DLT_NW_TRACE_FLEXRAY, 16, buffer, 1024 * 5, buffer); DLT_TRACE_NETWORK_TRUNCATED(context_macro_test[7], DLT_NW_TRACE_MOST, 16, buffer, 1024 * 5, buffer); /* wait 2 second before next test */ sleep(2); DLT_LOG(context_info, DLT_LOG_INFO, DLT_STRING("Test8: (Macro IF) finished")); DLT_SET_APPLICATION_LL_TS_LIMIT(DLT_LOG_DEFAULT, DLT_TRACE_STATUS_DEFAULT); sleep(2); return 0; } int test9m(void) { char buffer[1024 * 5]; int num; for (num = 0; num < 1024 * 5; num++) buffer[num] = num; /* Show all log messages and traces */ DLT_SET_APPLICATION_LL_TS_LIMIT(DLT_LOG_VERBOSE, DLT_TRACE_STATUS_ON); /* Test 9: (Macro IF) Test segmented network trace*/ printf("Test9m: (Macro IF) Test segmented network trace\n"); DLT_LOG_STRING(context_info, DLT_LOG_INFO, "Test 9: (Macro IF) Test segmented network trace"); /* Dummy messages: 16 byte header, 5k payload */ DLT_TRACE_NETWORK_SEGMENTED(context_macro_test[8], DLT_NW_TRACE_IPC, 16, buffer, 1024 * 5, buffer); DLT_TRACE_NETWORK_SEGMENTED(context_macro_test[8], DLT_NW_TRACE_CAN, 16, buffer, 1024 * 5, buffer); DLT_TRACE_NETWORK_SEGMENTED(context_macro_test[8], DLT_NW_TRACE_FLEXRAY, 16, buffer, 1024 * 5, buffer); DLT_TRACE_NETWORK_SEGMENTED(context_macro_test[8], DLT_NW_TRACE_MOST, 16, buffer, 1024 * 5, buffer); /* wait 2 second before next test */ sleep(2); DLT_LOG(context_info, DLT_LOG_INFO, DLT_STRING("Test9: (Macro IF) finished")); DLT_SET_APPLICATION_LL_TS_LIMIT(DLT_LOG_DEFAULT, DLT_TRACE_STATUS_DEFAULT); sleep(2); return 0; } int test1f(void) { /* Test 1: (Function IF) Test all log levels */ printf("Test1f: (Function IF) Test all log levels\n"); if (dlt_user_log_write_start(&context_info, &context_data, DLT_LOG_INFO) > 0) { dlt_user_log_write_string(&context_data, "Test1: (Function IF) Test all log levels"); dlt_user_log_write_finish(&context_data); } if (dlt_user_log_write_start(&(context_function_test[0]), &context_data, DLT_LOG_FATAL) > 0) { dlt_user_log_write_string(&context_data, "fatal"); dlt_user_log_write_finish(&context_data); } if (dlt_user_log_write_start(&(context_function_test[0]), &context_data, DLT_LOG_ERROR) > 0) { dlt_user_log_write_string(&context_data, "error"); dlt_user_log_write_finish(&context_data); } if (dlt_user_log_write_start(&(context_function_test[0]), &context_data, DLT_LOG_WARN) > 0) { dlt_user_log_write_string(&context_data, "warn"); dlt_user_log_write_finish(&context_data); } if (dlt_user_log_write_start(&(context_function_test[0]), &context_data, DLT_LOG_INFO) > 0) { dlt_user_log_write_string(&context_data, "info"); dlt_user_log_write_finish(&context_data); } if (dlt_user_log_write_start(&(context_function_test[0]), &context_data, DLT_LOG_DEBUG) > 0) { dlt_user_log_write_string(&context_data, "debug"); dlt_user_log_write_finish(&context_data); } if (dlt_user_log_write_start(&(context_function_test[0]), &context_data, DLT_LOG_VERBOSE) > 0) { dlt_user_log_write_string(&context_data, "verbose"); dlt_user_log_write_finish(&context_data); } /* wait 2 second before next test */ sleep(2); if (dlt_user_log_write_start(&context_info, &context_data, DLT_LOG_INFO) > 0) { dlt_user_log_write_string(&context_data, "Test1: (Function IF) finished"); dlt_user_log_write_finish(&context_data); } return 0; } int test2f(void) { char buffer[10]; int num2; /* Test 2: (Function IF) Test all variable types (verbose) */ printf("Test2f: (Function IF) Test all variable types (verbose)\n"); if (dlt_user_log_write_start(&context_info, &context_data, DLT_LOG_INFO) > 0) { dlt_user_log_write_string(&context_data, "Test2: (Function IF) Test all variable types (verbose)"); dlt_user_log_write_finish(&context_data); } if (dlt_user_log_write_start(&(context_function_test[1]), &context_data, DLT_LOG_INFO) > 0) { dlt_user_log_write_string(&context_data, "bool"); dlt_user_log_write_bool(&context_data, 1); dlt_user_log_write_finish(&context_data); } if (dlt_user_log_write_start(&(context_function_test[1]), &context_data, DLT_LOG_INFO) > 0) { dlt_user_log_write_string(&context_data, "int"); dlt_user_log_write_int(&context_data, INT32_MIN); /* (-2147483647-1) */ dlt_user_log_write_finish(&context_data); } if (dlt_user_log_write_start(&(context_function_test[1]), &context_data, DLT_LOG_INFO) > 0) { dlt_user_log_write_string(&context_data, "int8"); dlt_user_log_write_int8(&context_data, INT8_MIN); /* (-128) */ dlt_user_log_write_finish(&context_data); } if (dlt_user_log_write_start(&(context_function_test[1]), &context_data, DLT_LOG_INFO) > 0) { dlt_user_log_write_string(&context_data, "int16"); dlt_user_log_write_int16(&context_data, INT16_MIN); /* (-32767-1) */ dlt_user_log_write_finish(&context_data); } if (dlt_user_log_write_start(&(context_function_test[1]), &context_data, DLT_LOG_INFO) > 0) { dlt_user_log_write_string(&context_data, "int32"); dlt_user_log_write_int32(&context_data, INT32_MIN); /* (-2147483647-1) */ dlt_user_log_write_finish(&context_data); } if (dlt_user_log_write_start(&(context_function_test[1]), &context_data, DLT_LOG_INFO) > 0) { dlt_user_log_write_string(&context_data, "int64"); dlt_user_log_write_int64(&context_data, INT64_MIN); /* (-__INT64_C(9223372036854775807)-1) */ dlt_user_log_write_finish(&context_data); } if (dlt_user_log_write_start(&(context_function_test[1]), &context_data, DLT_LOG_INFO) > 0) { dlt_user_log_write_string(&context_data, "uint"); dlt_user_log_write_uint(&context_data, UINT32_MAX); /* (4294967295U) */ dlt_user_log_write_finish(&context_data); } if (dlt_user_log_write_start(&(context_function_test[1]), &context_data, DLT_LOG_INFO) > 0) { dlt_user_log_write_string(&context_data, "uint8"); dlt_user_log_write_uint8(&context_data, UINT8_MAX); /* (255) */ dlt_user_log_write_finish(&context_data); } if (dlt_user_log_write_start(&(context_function_test[1]), &context_data, DLT_LOG_INFO) > 0) { dlt_user_log_write_string(&context_data, "uint16"); dlt_user_log_write_uint16(&context_data, UINT16_MAX); /* (65535) */ dlt_user_log_write_finish(&context_data); } if (dlt_user_log_write_start(&(context_function_test[1]), &context_data, DLT_LOG_INFO) > 0) { dlt_user_log_write_string(&context_data, "uint32"); dlt_user_log_write_uint32(&context_data, UINT32_MAX); /* (4294967295U) */ dlt_user_log_write_finish(&context_data); } if (dlt_user_log_write_start(&(context_function_test[1]), &context_data, DLT_LOG_INFO) > 0) { dlt_user_log_write_string(&context_data, "uint64"); dlt_user_log_write_uint64(&context_data, UINT64_MAX); /* (__UINT64_C(18446744073709551615)) */ dlt_user_log_write_finish(&context_data); } if (dlt_user_log_write_start(&(context_function_test[1]), &context_data, DLT_LOG_INFO) > 0) { dlt_user_log_write_string(&context_data, "float32"); dlt_user_log_write_float32(&context_data, FLT_MIN); dlt_user_log_write_float32(&context_data, FLT_MAX); dlt_user_log_write_finish(&context_data); } if (dlt_user_log_write_start(&(context_function_test[1]), &context_data, DLT_LOG_INFO) > 0) { dlt_user_log_write_string(&context_data, "float64"); dlt_user_log_write_float64(&context_data, DBL_MIN); dlt_user_log_write_float64(&context_data, DBL_MAX); dlt_user_log_write_finish(&context_data); } for (num2 = 0; num2 < 10; num2++) buffer[num2] = num2; if (dlt_user_log_write_start(&(context_function_test[1]), &context_data, DLT_LOG_INFO) > 0) { dlt_user_log_write_string(&context_data, "raw"); dlt_user_log_write_raw(&context_data, buffer, 10); dlt_user_log_write_finish(&context_data); } /* wait 2 second before next test */ sleep(2); if (dlt_user_log_write_start(&context_info, &context_data, DLT_LOG_INFO) > 0) { dlt_user_log_write_string(&context_data, "Test2: (Function IF) finished"); dlt_user_log_write_finish(&context_data); } return 0; } int test3f(void) { char buffer[10]; int num2; /* Test 3: (Function IF) Test all variable types (non-verbose) */ printf("Test3f: (Function IF) Test all variable types (non-verbose)\n"); if (dlt_user_log_write_start(&context_info, &context_data, DLT_LOG_INFO) > 0) { dlt_user_log_write_string(&context_data, "Test3: (Function IF) Test all variable types (non-verbose)"); dlt_user_log_write_finish(&context_data); } dlt_nonverbose_mode(); if (dlt_user_log_write_start_id(&(context_function_test[2]), &context_data, DLT_LOG_INFO, 1) > 0) { /* bug mb: we have to compare against >0. in case of error -1 is returned! */ dlt_user_log_write_string(&context_data, "bool"); dlt_user_log_write_bool(&context_data, 1); dlt_user_log_write_finish(&context_data); } if (dlt_user_log_write_start_id(&(context_function_test[2]), &context_data, DLT_LOG_INFO, 2) > 0) { dlt_user_log_write_string(&context_data, "int"); dlt_user_log_write_int(&context_data, INT32_MIN); /* (-2147483647-1) */ dlt_user_log_write_finish(&context_data); } if (dlt_user_log_write_start_id(&(context_function_test[2]), &context_data, DLT_LOG_INFO, 3) > 0) { dlt_user_log_write_string(&context_data, "int8"); dlt_user_log_write_int8(&context_data, INT8_MIN); /* (-128) */ dlt_user_log_write_finish(&context_data); } if (dlt_user_log_write_start_id(&(context_function_test[2]), &context_data, DLT_LOG_INFO, 4) > 0) { dlt_user_log_write_string(&context_data, "int16"); dlt_user_log_write_int16(&context_data, INT16_MIN); /* (-32767-1) */ dlt_user_log_write_finish(&context_data); } if (dlt_user_log_write_start_id(&(context_function_test[2]), &context_data, DLT_LOG_INFO, 5) > 0) { dlt_user_log_write_string(&context_data, "int32"); dlt_user_log_write_int32(&context_data, INT32_MIN); /* (-2147483647-1) */ dlt_user_log_write_finish(&context_data); } if (dlt_user_log_write_start_id(&(context_function_test[2]), &context_data, DLT_LOG_INFO, 6) > 0) { dlt_user_log_write_string(&context_data, "int64"); dlt_user_log_write_int64(&context_data, INT64_MIN); /* (-__INT64_C(9223372036854775807)-1) */ dlt_user_log_write_finish(&context_data); } if (dlt_user_log_write_start_id(&(context_function_test[2]), &context_data, DLT_LOG_INFO, 7) > 0) { dlt_user_log_write_string(&context_data, "uint"); dlt_user_log_write_uint(&context_data, UINT32_MAX); /* (4294967295U) */ dlt_user_log_write_finish(&context_data); } if (dlt_user_log_write_start_id(&(context_function_test[2]), &context_data, DLT_LOG_INFO, 8) > 0) { dlt_user_log_write_string(&context_data, "uint8"); dlt_user_log_write_uint8(&context_data, UINT8_MAX); /* (255) */ dlt_user_log_write_finish(&context_data); } if (dlt_user_log_write_start_id(&(context_function_test[2]), &context_data, DLT_LOG_INFO, 9) > 0) { dlt_user_log_write_string(&context_data, "uint16"); dlt_user_log_write_uint16(&context_data, UINT16_MAX); /* (65535) */ dlt_user_log_write_finish(&context_data); } if (dlt_user_log_write_start_id(&(context_function_test[2]), &context_data, DLT_LOG_INFO, 10) > 0) { dlt_user_log_write_string(&context_data, "uint32"); dlt_user_log_write_uint32(&context_data, UINT32_MAX); /* (4294967295U) */ dlt_user_log_write_finish(&context_data); } if (dlt_user_log_write_start_id(&(context_function_test[2]), &context_data, DLT_LOG_INFO, 11) > 0) { dlt_user_log_write_string(&context_data, "uint64"); dlt_user_log_write_uint64(&context_data, UINT64_MAX); /* (__UINT64_C(18446744073709551615)) */ dlt_user_log_write_finish(&context_data); } if (dlt_user_log_write_start_id(&(context_function_test[2]), &context_data, DLT_LOG_INFO, 12) > 0) { dlt_user_log_write_string(&context_data, "float32"); dlt_user_log_write_float32(&context_data, FLT_MIN); dlt_user_log_write_float32(&context_data, FLT_MAX); dlt_user_log_write_finish(&context_data); } if (dlt_user_log_write_start_id(&(context_function_test[2]), &context_data, DLT_LOG_INFO, 13) > 0) { dlt_user_log_write_string(&context_data, "float64"); dlt_user_log_write_float64(&context_data, DBL_MIN); dlt_user_log_write_float64(&context_data, DBL_MAX); dlt_user_log_write_finish(&context_data); } for (num2 = 0; num2 < 10; num2++) buffer[num2] = num2; if (dlt_user_log_write_start_id(&(context_function_test[2]), &context_data, DLT_LOG_INFO, 14) > 0) { dlt_user_log_write_string(&context_data, "raw"); dlt_user_log_write_raw(&context_data, buffer, 10); dlt_user_log_write_finish(&context_data); } dlt_verbose_mode(); /* wait 2 second before next test */ sleep(2); if (dlt_user_log_write_start(&context_info, &context_data, DLT_LOG_INFO) > 0) { dlt_user_log_write_string(&context_data, "Test3: (Function IF) finished"); dlt_user_log_write_finish(&context_data); } return 0; } int test4f(void) { char buffer[1024]; int num; for (num = 0; num < 1024; num++) buffer[num] = num; /* Test 4: (Function IF) Message size test */ printf("Test4f: (Function IF) Test different message sizes\n"); if (dlt_user_log_write_start(&context_info, &context_data, DLT_LOG_INFO) > 0) { dlt_user_log_write_string(&context_data, "Test4: (Function IF) Test different message sizes"); dlt_user_log_write_finish(&context_data); } if (dlt_user_log_write_start(&(context_function_test[3]), &context_data, DLT_LOG_INFO) > 0) { dlt_user_log_write_string(&context_data, "1"); dlt_user_log_write_raw(&context_data, buffer, 1); dlt_user_log_write_finish(&context_data); } if (dlt_user_log_write_start(&(context_function_test[3]), &context_data, DLT_LOG_INFO) > 0) { dlt_user_log_write_string(&context_data, "16"); dlt_user_log_write_raw(&context_data, buffer, 16); dlt_user_log_write_finish(&context_data); } if (dlt_user_log_write_start(&(context_function_test[3]), &context_data, DLT_LOG_INFO) > 0) { dlt_user_log_write_string(&context_data, "256"); dlt_user_log_write_raw(&context_data, buffer, 256); dlt_user_log_write_finish(&context_data); } if (dlt_user_log_write_start(&(context_function_test[3]), &context_data, DLT_LOG_INFO) > 0) { dlt_user_log_write_string(&context_data, "1024"); dlt_user_log_write_raw(&context_data, buffer, 1024); dlt_user_log_write_finish(&context_data); } /* wait 2 second before next test */ sleep(2); if (dlt_user_log_write_start(&context_info, &context_data, DLT_LOG_INFO) > 0) { dlt_user_log_write_string(&context_data, "Test4: (Function IF) finished"); dlt_user_log_write_finish(&context_data); } return 0; } int test5f(void) { char buffer[32]; int num; int i; char log[DLT_USER_BUF_MAX_SIZE]; for (num = 0; num < 32; num++) buffer[num] = num; /* Test 5: (Function IF) Test high-level API */ printf("Test5f: (Function IF) Test high-level API\n"); dlt_log_string(&context_info, DLT_LOG_INFO, "Test5: (Function IF) Test high-level API"); dlt_log_string(&(context_function_test[4]), DLT_LOG_INFO, "Next line: dlt_log_int()"); dlt_log_int(&(context_function_test[4]), DLT_LOG_INFO, -42); dlt_log_string(&(context_function_test[4]), DLT_LOG_INFO, "Next line: dlt_log_uint()"); dlt_log_uint(&(context_function_test[4]), DLT_LOG_INFO, 42); dlt_log_string(&(context_function_test[4]), DLT_LOG_INFO, "Next line: dlt_log_string()"); dlt_log_string(&(context_function_test[4]), DLT_LOG_INFO, "String output"); dlt_log_string(&(context_function_test[4]), DLT_LOG_INFO, "Next line: dlt_log_raw()"); dlt_log_raw(&(context_function_test[4]), DLT_LOG_INFO, buffer, 16); dlt_log_string(&(context_function_test[4]), DLT_LOG_INFO, "Next line: dlt_log_string_int()"); dlt_log_string_int(&(context_function_test[4]), DLT_LOG_INFO, "String output: ", -42); dlt_log_string(&(context_function_test[4]), DLT_LOG_INFO, "Next line: dlt_log_string_uint()"); dlt_log_string_uint(&(context_function_test[4]), DLT_LOG_INFO, "String output: ", 42); dlt_log_string(&(context_function_test[4]), DLT_LOG_INFO, "Next lines: dlt_user_is_logLevel_enabled"); for (i = DLT_LOG_FATAL; i < DLT_LOG_MAX; i++) { if (dlt_user_is_logLevel_enabled(&(context_function_test[4]), i) == DLT_RETURN_TRUE) { snprintf(log, DLT_USER_BUF_MAX_SIZE, "Loglevel is enabled: %s", loglevelstr[i]); dlt_log_string(&(context_function_test[4]), DLT_LOG_INFO, log); } else { snprintf(log, DLT_USER_BUF_MAX_SIZE, "Loglevel is disabled: %s", loglevelstr[i]); dlt_log_string(&(context_function_test[4]), DLT_LOG_INFO, log); } } /* wait 2 second before next test */ sleep(2); dlt_log_string(&context_info, DLT_LOG_INFO, "Test5: (Function IF) finished"); return 0; } int test6f(void) { /* Test 6: (Function IF) Test local printing */ printf("Test6f: (Function IF) Test local printing\n"); if (dlt_user_log_write_start(&context_info, &context_data, DLT_LOG_INFO) > 0) { dlt_user_log_write_string(&context_data, "Test 6: (Function IF) Test local printing"); dlt_user_log_write_finish(&context_data); } dlt_enable_local_print(); if (dlt_user_log_write_start(&(context_function_test[5]), &context_data, DLT_LOG_INFO) > 0) { dlt_user_log_write_string(&context_data, "Message (visible: locally printed)"); dlt_user_log_write_finish(&context_data); } dlt_disable_local_print(); if (dlt_user_log_write_start(&(context_function_test[5]), &context_data, DLT_LOG_INFO) > 0) { dlt_user_log_write_string(&context_data, "Message (invisible: not locally printed)"); dlt_user_log_write_finish(&context_data); } /* wait 2 second before next test */ sleep(2); if (dlt_user_log_write_start(&context_info, &context_data, DLT_LOG_INFO) > 0) { dlt_user_log_write_string(&context_data, "Test6: (Function IF) finished"); dlt_user_log_write_finish(&context_data); } return 0; } int test7f(void) { char buffer[32]; int num; for (num = 0; num < 32; num++) buffer[num] = num; /* Show all log messages and traces */ dlt_set_application_ll_ts_limit(DLT_LOG_VERBOSE, DLT_TRACE_STATUS_ON); /* Test 7: (Function IF) Test network trace */ printf("Test7f: (Function IF) Test network trace\n"); if (dlt_user_log_write_start(&context_info, &context_data, DLT_LOG_INFO) > 0) { dlt_user_log_write_string(&context_data, "Test 7: (Function IF) Test network trace"); dlt_user_log_write_finish(&context_data); } /* Dummy message: 16 byte header, 32 byte payload */ dlt_user_trace_network(&(context_function_test[6]), DLT_NW_TRACE_IPC, 16, buffer, 32, buffer); dlt_user_trace_network(&(context_function_test[6]), DLT_NW_TRACE_CAN, 16, buffer, 32, buffer); dlt_user_trace_network(&(context_function_test[6]), DLT_NW_TRACE_FLEXRAY, 16, buffer, 32, buffer); dlt_user_trace_network(&(context_function_test[6]), DLT_NW_TRACE_MOST, 16, buffer, 32, buffer); /* wait 2 second before next test */ sleep(2); if (dlt_user_log_write_start(&context_info, &context_data, DLT_LOG_INFO) > 0) { dlt_user_log_write_string(&context_data, "Test7: (Function IF) finished"); dlt_user_log_write_finish(&context_data); } dlt_set_application_ll_ts_limit(DLT_LOG_DEFAULT, DLT_TRACE_STATUS_DEFAULT); sleep(2); return 0; } int test8f(void) { char buffer[1024 * 5]; int num; for (num = 0; num < 1024 * 5; num++) buffer[num] = num; /* Show all log messages and traces */ dlt_set_application_ll_ts_limit(DLT_LOG_VERBOSE, DLT_TRACE_STATUS_ON); /* Test 8: (Function IF) Test truncated network trace */ printf("Test8f: (Function IF) Test truncated network trace\n"); if (dlt_user_log_write_start(&context_info, &context_data, DLT_LOG_INFO) > 0) { dlt_user_log_write_string(&context_data, "Test 8: (Function IF) Test truncated network trace"); dlt_user_log_write_finish(&context_data); } /* Dummy message: 16 byte header, 32 byte payload */ dlt_user_trace_network_truncated(&(context_function_test[7]), DLT_NW_TRACE_IPC, 16, buffer, 1024 * 5, buffer, 1); dlt_user_trace_network_truncated(&(context_function_test[7]), DLT_NW_TRACE_CAN, 16, buffer, 1024 * 5, buffer, 1); dlt_user_trace_network_truncated(&(context_function_test[7]), DLT_NW_TRACE_FLEXRAY, 16, buffer, 1024 * 5, buffer, 1); dlt_user_trace_network_truncated(&(context_function_test[7]), DLT_NW_TRACE_MOST, 16, buffer, 1024 * 5, buffer, 1); /* wait 2 second before next test */ sleep(2); if (dlt_user_log_write_start(&context_info, &context_data, DLT_LOG_INFO) > 0) { dlt_user_log_write_string(&context_data, "Test8: (Function IF) finished"); dlt_user_log_write_finish(&context_data); } dlt_set_application_ll_ts_limit(DLT_LOG_DEFAULT, DLT_TRACE_STATUS_DEFAULT); sleep(2); return 0; } int test9f(void) { char buffer[1024 * 5]; int num; for (num = 0; num < 1024 * 5; num++) buffer[num] = num; /* Show all log messages and traces */ dlt_set_application_ll_ts_limit(DLT_LOG_VERBOSE, DLT_TRACE_STATUS_ON); /* Test 9: (Function IF) Test segmented network trace */ printf("Test9f: (Function IF) Test segmented network trace\n"); if (dlt_user_log_write_start(&context_info, &context_data, DLT_LOG_INFO) > 0) { dlt_user_log_write_string(&context_data, "Test 9: (Function IF) Test segmented network trace"); dlt_user_log_write_finish(&context_data); } /* Dummy message: 16 byte header, 5k payload */ dlt_user_trace_network_segmented(&(context_function_test[8]), DLT_NW_TRACE_IPC, 16, buffer, 1024 * 5, buffer); dlt_user_trace_network_segmented(&(context_function_test[8]), DLT_NW_TRACE_CAN, 16, buffer, 1024 * 5, buffer); dlt_user_trace_network_segmented(&(context_function_test[8]), DLT_NW_TRACE_FLEXRAY, 16, buffer, 1024 * 5, buffer); dlt_user_trace_network_segmented(&(context_function_test[8]), DLT_NW_TRACE_MOST, 16, buffer, 1024 * 5, buffer); /* wait 2 second before next test */ sleep(2); if (dlt_user_log_write_start(&context_info, &context_data, DLT_LOG_INFO) > 0) { dlt_user_log_write_string(&context_data, "Test9: (Function IF) finished"); dlt_user_log_write_finish(&context_data); } dlt_set_application_ll_ts_limit(DLT_LOG_DEFAULT, DLT_TRACE_STATUS_DEFAULT); sleep(2); return 0; } int test_injection_macro_callback(uint32_t service_id, void *data, uint32_t length) { char text[1024]; memset(text, 0, 1024); snprintf(text, 1024, "Injection received (macro IF). ID: 0x%.4x, Length: %d", service_id, length); printf("%s \n", text); DLT_LOG(context_macro_callback, DLT_LOG_INFO, DLT_STRING("Injection received (macro IF). ID: "), DLT_UINT32(service_id), DLT_STRING("Data:"), DLT_STRING(text)); memset(text, 0, 1024); if (length > 0) { dlt_print_mixed_string(text, 1024, data, length, 0); printf("%s \n", text); } return 0; } int test_injection_function_callback(uint32_t service_id, void *data, uint32_t length) { char text[1024]; memset(text, 0, 1024); snprintf(text, 1024, "Injection received (function IF). ID: 0x%.4x, Length: %d", service_id, length); printf("%s \n", text); DLT_LOG(context_function_callback, DLT_LOG_INFO, DLT_STRING("Injection received (function IF). ID: "), DLT_UINT32(service_id), DLT_STRING("Data:"), DLT_STRING(text)); memset(text, 0, 1024); if (length > 0) { dlt_print_mixed_string(text, 1024, data, length, 0); printf("%s \n", text); } return 0; } dlt-daemon-2.18.4/systemd/000077500000000000000000000000001353342203500153225ustar00rootroot00000000000000dlt-daemon-2.18.4/systemd/3rdparty/000077500000000000000000000000001353342203500170725ustar00rootroot00000000000000dlt-daemon-2.18.4/systemd/3rdparty/sd-daemon.c000066400000000000000000000330621353342203500211110ustar00rootroot00000000000000/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ /*** Copyright 2010 Lennart Poettering Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ***/ #ifndef _GNU_SOURCE #define _GNU_SOURCE #endif #include #include #include #include #ifdef __BIONIC__ #include #else #include #endif #include #include #include #include #include #include #include #include #include #if defined(__linux__) #include #endif #include "sd-daemon.h" #if (__GNUC__ >= 4) #ifdef SD_EXPORT_SYMBOLS /* Export symbols */ #define _sd_export_ __attribute__ ((visibility("default"))) #else /* Don't export the symbols */ #define _sd_export_ __attribute__ ((visibility("hidden"))) #endif #else #define _sd_export_ #endif _sd_export_ int sd_listen_fds(int unset_environment) { #if defined(DISABLE_SYSTEMD) || !defined(__linux__) return 0; #else int r, fd; const char *e; char *p = NULL; unsigned long l; if (!(e = getenv("LISTEN_PID"))) { r = 0; goto finish; } errno = 0; l = strtoul(e, &p, 10); if (errno != 0) { r = -errno; goto finish; } if (!p || *p || l <= 0) { r = -EINVAL; goto finish; } /* Is this for us? */ if (getpid() != (pid_t) l) { r = 0; goto finish; } if (!(e = getenv("LISTEN_FDS"))) { r = 0; goto finish; } errno = 0; l = strtoul(e, &p, 10); if (errno != 0) { r = -errno; goto finish; } if (!p || *p) { r = -EINVAL; goto finish; } for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + (int) l; fd ++) { int flags; if ((flags = fcntl(fd, F_GETFD)) < 0) { r = -errno; goto finish; } if (flags & FD_CLOEXEC) continue; if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) < 0) { r = -errno; goto finish; } } r = (int) l; finish: if (unset_environment) { unsetenv("LISTEN_PID"); unsetenv("LISTEN_FDS"); } return r; #endif } _sd_export_ int sd_is_fifo(int fd, const char *path) { struct stat st_fd; if (fd < 0) return -EINVAL; memset(&st_fd, 0, sizeof(st_fd)); if (fstat(fd, &st_fd) < 0) return -errno; if (!S_ISFIFO(st_fd.st_mode)) return 0; if (path) { struct stat st_path; memset(&st_path, 0, sizeof(st_path)); if (stat(path, &st_path) < 0) { if (errno == ENOENT || errno == ENOTDIR) return 0; return -errno; } return st_path.st_dev == st_fd.st_dev && st_path.st_ino == st_fd.st_ino; } return 1; } _sd_export_ int sd_is_special(int fd, const char *path) { struct stat st_fd; if (fd < 0) return -EINVAL; if (fstat(fd, &st_fd) < 0) return -errno; if (!S_ISREG(st_fd.st_mode) && !S_ISCHR(st_fd.st_mode)) return 0; if (path) { struct stat st_path; if (stat(path, &st_path) < 0) { if (errno == ENOENT || errno == ENOTDIR) return 0; return -errno; } if (S_ISREG(st_fd.st_mode) && S_ISREG(st_path.st_mode)) return st_path.st_dev == st_fd.st_dev && st_path.st_ino == st_fd.st_ino; else if (S_ISCHR(st_fd.st_mode) && S_ISCHR(st_path.st_mode)) return st_path.st_rdev == st_fd.st_rdev; else return 0; } return 1; } static int sd_is_socket_internal(int fd, int type, int listening) { struct stat st_fd; if (fd < 0 || type < 0) return -EINVAL; if (fstat(fd, &st_fd) < 0) return -errno; if (!S_ISSOCK(st_fd.st_mode)) return 0; if (type != 0) { int other_type = 0; socklen_t l = sizeof(other_type); if (getsockopt(fd, SOL_SOCKET, SO_TYPE, &other_type, &l) < 0) return -errno; if (l != sizeof(other_type)) return -EINVAL; if (other_type != type) return 0; } if (listening >= 0) { int accepting = 0; socklen_t l = sizeof(accepting); if (getsockopt(fd, SOL_SOCKET, SO_ACCEPTCONN, &accepting, &l) < 0) return -errno; if (l != sizeof(accepting)) return -EINVAL; if (!accepting != !listening) return 0; } return 1; } union sockaddr_union { struct sockaddr sa; struct sockaddr_in in4; struct sockaddr_in6 in6; struct sockaddr_un un; struct sockaddr_storage storage; }; _sd_export_ int sd_is_socket(int fd, int family, int type, int listening) { int r; if (family < 0) return -EINVAL; if ((r = sd_is_socket_internal(fd, type, listening)) <= 0) return r; if (family > 0) { union sockaddr_union sockaddr; socklen_t l; memset(&sockaddr, 0, sizeof(sockaddr)); l = sizeof(sockaddr); if (getsockname(fd, &sockaddr.sa, &l) < 0) return -errno; if (l < sizeof(sa_family_t)) return -EINVAL; return sockaddr.sa.sa_family == family; } return 1; } _sd_export_ int sd_is_socket_inet(int fd, int family, int type, int listening, uint16_t port) { union sockaddr_union sockaddr; socklen_t l; int r; if (family != 0 && family != AF_INET && family != AF_INET6) return -EINVAL; if ((r = sd_is_socket_internal(fd, type, listening)) <= 0) return r; memset(&sockaddr, 0, sizeof(sockaddr)); l = sizeof(sockaddr); if (getsockname(fd, &sockaddr.sa, &l) < 0) return -errno; if (l < sizeof(sa_family_t)) return -EINVAL; if (sockaddr.sa.sa_family != AF_INET && sockaddr.sa.sa_family != AF_INET6) return 0; if (family > 0) if (sockaddr.sa.sa_family != family) return 0; if (port > 0) { if (sockaddr.sa.sa_family == AF_INET) { if (l < sizeof(struct sockaddr_in)) return -EINVAL; return htons(port) == sockaddr.in4.sin_port; } else { if (l < sizeof(struct sockaddr_in6)) return -EINVAL; return htons(port) == sockaddr.in6.sin6_port; } } return 1; } _sd_export_ int sd_is_socket_unix(int fd, int type, int listening, const char *path, size_t length) { union sockaddr_union sockaddr; socklen_t l; int r; if ((r = sd_is_socket_internal(fd, type, listening)) <= 0) return r; memset(&sockaddr, 0, sizeof(sockaddr)); l = sizeof(sockaddr); if (getsockname(fd, &sockaddr.sa, &l) < 0) return -errno; if (l < sizeof(sa_family_t)) return -EINVAL; if (sockaddr.sa.sa_family != AF_UNIX) return 0; if (path) { if (length <= 0) length = strlen(path); if (length <= 0) /* Unnamed socket */ return l == offsetof(struct sockaddr_un, sun_path); if (path[0]) /* Normal path socket */ return (l >= offsetof(struct sockaddr_un, sun_path) + length + 1) && memcmp(path, sockaddr.un.sun_path, length+1) == 0; else /* Abstract namespace socket */ return (l == offsetof(struct sockaddr_un, sun_path) + length) && memcmp(path, sockaddr.un.sun_path, length) == 0; } return 1; } _sd_export_ int sd_is_mq(int fd, const char *path) { #if !defined(__linux__) return 0; #else struct mq_attr attr; if (fd < 0) return -EINVAL; if (mq_getattr(fd, &attr) < 0) return -errno; if (path) { char fpath[PATH_MAX]; struct stat a, b; if (path[0] != '/') return -EINVAL; if (fstat(fd, &a) < 0) return -errno; strncpy(stpcpy(fpath, "/dev/mqueue"), path, sizeof(fpath) - 12); fpath[sizeof(fpath)-1] = 0; if (stat(fpath, &b) < 0) return -errno; if (a.st_dev != b.st_dev || a.st_ino != b.st_ino) return 0; } return 1; #endif } _sd_export_ int sd_notify(int unset_environment, const char *state) { #if defined(DISABLE_SYSTEMD) || !defined(__linux__) || !defined(SOCK_CLOEXEC) return 0; #else int fd = -1, r; struct msghdr msghdr; struct iovec iovec; union sockaddr_union sockaddr; const char *e; if (!state) { r = -EINVAL; goto finish; } if (!(e = getenv("NOTIFY_SOCKET"))) return 0; /* Must be an abstract socket, or an absolute path */ if ((e[0] != '@' && e[0] != '/') || e[1] == 0) { r = -EINVAL; goto finish; } if ((fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0)) < 0) { r = -errno; goto finish; } memset(&sockaddr, 0, sizeof(sockaddr)); sockaddr.sa.sa_family = AF_UNIX; strncpy(sockaddr.un.sun_path, e, sizeof(sockaddr.un.sun_path)-1); if (sockaddr.un.sun_path[0] == '@') sockaddr.un.sun_path[0] = 0; memset(&iovec, 0, sizeof(iovec)); iovec.iov_base = (char*) state; iovec.iov_len = strlen(state); memset(&msghdr, 0, sizeof(msghdr)); msghdr.msg_name = &sockaddr; msghdr.msg_namelen = offsetof(struct sockaddr_un, sun_path) + strlen(e); if (msghdr.msg_namelen > sizeof(struct sockaddr_un)) msghdr.msg_namelen = sizeof(struct sockaddr_un); msghdr.msg_iov = &iovec; msghdr.msg_iovlen = 1; if (sendmsg(fd, &msghdr, MSG_NOSIGNAL) < 0) { r = -errno; goto finish; } r = 1; finish: if (unset_environment) unsetenv("NOTIFY_SOCKET"); if (fd >= 0) close(fd); return r; #endif } _sd_export_ int sd_notifyf(int unset_environment, const char *format, ...) { #if defined(DISABLE_SYSTEMD) || !defined(__linux__) return 0; #else va_list ap; char *p = NULL; int r; va_start(ap, format); r = vasprintf(&p, format, ap); va_end(ap); if (r < 0 || !p) return -ENOMEM; r = sd_notify(unset_environment, p); free(p); return r; #endif } _sd_export_ int sd_booted(void) { #if defined(DISABLE_SYSTEMD) || !defined(__linux__) return 0; #else struct stat a, b; /* We simply test whether the systemd cgroup hierarchy is * mounted */ if (lstat("/sys/fs/cgroup", &a) < 0) return 0; if (lstat("/sys/fs/cgroup/systemd", &b) < 0) return 0; return a.st_dev != b.st_dev; #endif } dlt-daemon-2.18.4/systemd/3rdparty/sd-daemon.h000066400000000000000000000255641353342203500211260ustar00rootroot00000000000000/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ #ifndef foosddaemonhfoo #define foosddaemonhfoo /*** Copyright 2010 Lennart Poettering Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ***/ #include #include #ifdef __cplusplus extern "C" { #endif /* Reference implementation of a few systemd related interfaces for writing daemons. These interfaces are trivial to implement. To simplify porting we provide this reference implementation. Applications are welcome to reimplement the algorithms described here if they do not want to include these two source files. The following functionality is provided: - Support for logging with log levels on stderr - File descriptor passing for socket-based activation - Daemon startup and status notification - Detection of systemd boots You may compile this with -DDISABLE_SYSTEMD to disable systemd support. This makes all those calls NOPs that are directly related to systemd (i.e. only sd_is_xxx() will stay useful). Since this is drop-in code we don't want any of our symbols to be exported in any case. Hence we declare hidden visibility for all of them. You may find an up-to-date version of these source files online: http://cgit.freedesktop.org/systemd/systemd/plain/src/systemd/sd-daemon.h http://cgit.freedesktop.org/systemd/systemd/plain/src/sd-daemon.c This should compile on non-Linux systems, too, but with the exception of the sd_is_xxx() calls all functions will become NOPs. See sd-daemon(7) for more information. */ #ifndef _sd_printf_attr_ #if __GNUC__ >= 4 #define _sd_printf_attr_(a,b) __attribute__ ((format (printf, a, b))) #else #define _sd_printf_attr_(a,b) #endif #endif /* Log levels for usage on stderr: fprintf(stderr, SD_NOTICE "Hello World!\n"); This is similar to printk() usage in the kernel. */ #define SD_EMERG "<0>" /* system is unusable */ #define SD_ALERT "<1>" /* action must be taken immediately */ #define SD_CRIT "<2>" /* critical conditions */ #define SD_ERR "<3>" /* error conditions */ #define SD_WARNING "<4>" /* warning conditions */ #define SD_NOTICE "<5>" /* normal but significant condition */ #define SD_INFO "<6>" /* informational */ #define SD_DEBUG "<7>" /* debug-level messages */ /* The first passed file descriptor is fd 3 */ #define SD_LISTEN_FDS_START 3 /* Returns how many file descriptors have been passed, or a negative errno code on failure. Optionally, removes the $LISTEN_FDS and $LISTEN_PID file descriptors from the environment (recommended, but problematic in threaded environments). If r is the return value of this function you'll find the file descriptors passed as fds SD_LISTEN_FDS_START to SD_LISTEN_FDS_START+r-1. Returns a negative errno style error code on failure. This function call ensures that the FD_CLOEXEC flag is set for the passed file descriptors, to make sure they are not passed on to child processes. If FD_CLOEXEC shall not be set, the caller needs to unset it after this call for all file descriptors that are used. See sd_listen_fds(3) for more information. */ int sd_listen_fds(int unset_environment); /* Helper call for identifying a passed file descriptor. Returns 1 if the file descriptor is a FIFO in the file system stored under the specified path, 0 otherwise. If path is NULL a path name check will not be done and the call only verifies if the file descriptor refers to a FIFO. Returns a negative errno style error code on failure. See sd_is_fifo(3) for more information. */ int sd_is_fifo(int fd, const char *path); /* Helper call for identifying a passed file descriptor. Returns 1 if the file descriptor is a special character device on the file system stored under the specified path, 0 otherwise. If path is NULL a path name check will not be done and the call only verifies if the file descriptor refers to a special character. Returns a negative errno style error code on failure. See sd_is_special(3) for more information. */ int sd_is_special(int fd, const char *path); /* Helper call for identifying a passed file descriptor. Returns 1 if the file descriptor is a socket of the specified family (AF_INET, ...) and type (SOCK_DGRAM, SOCK_STREAM, ...), 0 otherwise. If family is 0 a socket family check will not be done. If type is 0 a socket type check will not be done and the call only verifies if the file descriptor refers to a socket. If listening is > 0 it is verified that the socket is in listening mode. (i.e. listen() has been called) If listening is == 0 it is verified that the socket is not in listening mode. If listening is < 0 no listening mode check is done. Returns a negative errno style error code on failure. See sd_is_socket(3) for more information. */ int sd_is_socket(int fd, int family, int type, int listening); /* Helper call for identifying a passed file descriptor. Returns 1 if the file descriptor is an Internet socket, of the specified family (either AF_INET or AF_INET6) and the specified type (SOCK_DGRAM, SOCK_STREAM, ...), 0 otherwise. If version is 0 a protocol version check is not done. If type is 0 a socket type check will not be done. If port is 0 a socket port check will not be done. The listening flag is used the same way as in sd_is_socket(). Returns a negative errno style error code on failure. See sd_is_socket_inet(3) for more information. */ int sd_is_socket_inet(int fd, int family, int type, int listening, uint16_t port); /* Helper call for identifying a passed file descriptor. Returns 1 if the file descriptor is an AF_UNIX socket of the specified type (SOCK_DGRAM, SOCK_STREAM, ...) and path, 0 otherwise. If type is 0 a socket type check will not be done. If path is NULL a socket path check will not be done. For normal AF_UNIX sockets set length to 0. For abstract namespace sockets set length to the length of the socket name (including the initial 0 byte), and pass the full socket path in path (including the initial 0 byte). The listening flag is used the same way as in sd_is_socket(). Returns a negative errno style error code on failure. See sd_is_socket_unix(3) for more information. */ int sd_is_socket_unix(int fd, int type, int listening, const char *path, size_t length); /* Helper call for identifying a passed file descriptor. Returns 1 if the file descriptor is a POSIX Message Queue of the specified name, 0 otherwise. If path is NULL a message queue name check is not done. Returns a negative errno style error code on failure. */ int sd_is_mq(int fd, const char *path); /* Informs systemd about changed daemon state. This takes a number of newline separated environment-style variable assignments in a string. The following variables are known: READY=1 Tells systemd that daemon startup is finished (only relevant for services of Type=notify). The passed argument is a boolean "1" or "0". Since there is little value in signaling non-readiness the only value daemons should send is "READY=1". STATUS=... Passes a single-line status string back to systemd that describes the daemon state. This is free-from and can be used for various purposes: general state feedback, fsck-like programs could pass completion percentages and failing programs could pass a human readable error message. Example: "STATUS=Completed 66% of file system check..." ERRNO=... If a daemon fails, the errno-style error code, formatted as string. Example: "ERRNO=2" for ENOENT. BUSERROR=... If a daemon fails, the D-Bus error-style error code. Example: "BUSERROR=org.freedesktop.DBus.Error.TimedOut" MAINPID=... The main pid of a daemon, in case systemd did not fork off the process itself. Example: "MAINPID=4711" WATCHDOG=1 Tells systemd to update the watchdog timestamp. Services using this feature should do this in regular intervals. A watchdog framework can use the timestamps to detect failed services. Daemons can choose to send additional variables. However, it is recommended to prefix variable names not listed above with X_. Returns a negative errno-style error code on failure. Returns > 0 if systemd could be notified, 0 if it couldn't possibly because systemd is not running. Example: When a daemon finished starting up, it could issue this call to notify systemd about it: sd_notify(0, "READY=1"); See sd_notifyf() for more complete examples. See sd_notify(3) for more information. */ int sd_notify(int unset_environment, const char *state); /* Similar to sd_notify() but takes a format string. Example 1: A daemon could send the following after initialization: sd_notifyf(0, "READY=1\n" "STATUS=Processing requests...\n" "MAINPID=%lu", (unsigned long) getpid()); Example 2: A daemon could send the following shortly before exiting, on failure: sd_notifyf(0, "STATUS=Failed to start up: %s\n" "ERRNO=%i", strerror(errno), errno); See sd_notifyf(3) for more information. */ int sd_notifyf(int unset_environment, const char *format, ...) _sd_printf_attr_(2,3); /* Returns > 0 if the system was booted with systemd. Returns < 0 on error. Returns 0 if the system was not booted with systemd. Note that all of the functions above handle non-systemd boots just fine. You should NOT protect them with a call to this function. Also note that this function checks whether the system, not the user session is controlled by systemd. However the functions above work for both user and system services. See sd_booted(3) for more information. */ int sd_booted(void); #ifdef __cplusplus } #endif #endif dlt-daemon-2.18.4/systemd/CMakeLists.txt000066400000000000000000000066531353342203500200740ustar00rootroot00000000000000####### # SPDX license identifier: MPL-2.0 # # Copyright (C) 2011-2015, BMW AG # # This file is part of GENIVI Project DLT - Diagnostic Log and Trace. # # This Source Code Form is subject to the terms of the # Mozilla Public License (MPL), v. 2.0. # If a copy of the MPL was not distributed with this file, # You can obtain one at http://mozilla.org/MPL/2.0/. # # For further information see http://www.genivi.org/. ####### if(WITH_SYSTEMD) set(SYSTEMD_CONFIGURATIONS_FILES_DIR ${SYSTEMD_UNITDIR} ) if(WITH_SYSTEMD_WATCHDOG) set( DLT_WatchdogSec 2 ) message( STATUS "The systemd watchdog is enabled - timeout is set to ${DLT_WatchdogSec} seconds") else(WITH_SYSTEMD_WATCHDOG) set( DLT_WatchdogSec 0 ) message( STATUS "The systemd watchdog is disabled") endif(WITH_SYSTEMD_WATCHDOG) configure_file(${PROJECT_SOURCE_DIR}/systemd/dlt.service.cmake ${PROJECT_BINARY_DIR}/systemd/dlt.service) message( STATUS "Configured systemd unit file:dlt.service" ) install(FILES ${PROJECT_BINARY_DIR}/systemd/dlt.service DESTINATION ${SYSTEMD_CONFIGURATIONS_FILES_DIR} ) if(WITH_DLT_SYSTEM) configure_file(${PROJECT_SOURCE_DIR}/systemd/dlt-system.service.cmake ${PROJECT_BINARY_DIR}/systemd/dlt-system.service) message( STATUS "Configured systemd unit file:dlt-system.service" ) install(FILES ${PROJECT_BINARY_DIR}/systemd/dlt-system.service DESTINATION ${SYSTEMD_CONFIGURATIONS_FILES_DIR} ) endif(WITH_DLT_SYSTEM) if(WITH_DLT_DBUS) configure_file(${PROJECT_SOURCE_DIR}/systemd/dlt-dbus.service.cmake ${PROJECT_BINARY_DIR}/systemd/dlt-dbus.service) message( STATUS "Configured systemd unit file:dlt-dbus.service" ) install(FILES ${PROJECT_BINARY_DIR}/systemd/dlt-dbus.service DESTINATION ${SYSTEMD_CONFIGURATIONS_FILES_DIR} ) endif(WITH_DLT_DBUS) if(WITH_DLT_CONSOLE AND WITH_DLT_EXAMPLES) configure_file(${PROJECT_SOURCE_DIR}/systemd/dlt-receive.service.cmake ${PROJECT_BINARY_DIR}/systemd/dlt-receive.service) message( STATUS "Configured systemd unit file:dlt-receive.service" ) install(FILES ${PROJECT_BINARY_DIR}/systemd/dlt-receive.service DESTINATION ${SYSTEMD_CONFIGURATIONS_FILES_DIR} ) endif(WITH_DLT_CONSOLE AND WITH_DLT_EXAMPLES) if(WITH_DLT_EXAMPLES) configure_file(${PROJECT_SOURCE_DIR}/systemd/dlt-example-user.service.cmake ${PROJECT_BINARY_DIR}/systemd/dlt-example-user.service) message( STATUS "Configured systemd unit file:dlt-example-user.service" ) install(FILES ${PROJECT_BINARY_DIR}/systemd/dlt-example-user.service DESTINATION ${SYSTEMD_CONFIGURATIONS_FILES_DIR} ) endif(WITH_DLT_EXAMPLES) if(WITH_DLT_ADAPTOR) set( DLT_ADAPTOR_UDP_APPID "DUDP" ) set( DLT_ADAPTOR_UDP_CTID "DCTI" ) set( DLT_ADAPTOR_UDP_PORT 4712 ) configure_file(${PROJECT_SOURCE_DIR}/systemd/dlt-adaptor-udp.service.cmake ${PROJECT_BINARY_DIR}/systemd/dlt-adaptor-udp.service) message( STATUS "Configured systemd unit file:dlt-adaptor-udp.service" ) message(STATUS "DLT adaptor udp configuration: APPID=${DLT_ADAPTOR_UDP_APPID} CTID=${DLT_ADAPTOR_UDP_CTID} PORT=${DLT_ADAPTOR_UDP_PORT}" ) install(FILES ${PROJECT_BINARY_DIR}/systemd/dlt-adaptor-udp.service DESTINATION ${SYSTEMD_CONFIGURATIONS_FILES_DIR} ) endif(WITH_DLT_ADAPTOR) message(STATUS "Unit files will be installed to ${SYSTEMD_CONFIGURATIONS_FILES_DIR} after make install" ) endif(WITH_SYSTEMD) dlt-daemon-2.18.4/systemd/dlt-adaptor-udp.service.cmake000066400000000000000000000014071353342203500227660ustar00rootroot00000000000000####### # SPDX license identifier: MPL-2.0 # # Copyright (C) 2011-2015, BMW AG # # This file is part of GENIVI Project DLT - Diagnostic Log and Trace. # # This Source Code Form is subject to the terms of the # Mozilla Public License (MPL), v. 2.0. # If a copy of the MPL was not distributed with this file, # You can obtain one at http://mozilla.org/MPL/2.0/. # # For further information see http://www.genivi.org/. ####### [Unit] Description=GENIVI DLT adaptor stdin. Adaptor for forwarding received UDP messages to DLT daemon. Wants=dlt.service [Service] Type=simple User=@DLT_USER@ ExecStart=@CMAKE_INSTALL_PREFIX@/bin/dlt-adaptor-udp -a @DLT_ADAPTOR_UDP_APPID@ -c @DLT_ADAPTOR_UDP_CTID@ -p @DLT_ADAPTOR_UDP_PORT@ LimitCORE=infinity [Install] WantedBy=multi-user.targetdlt-daemon-2.18.4/systemd/dlt-dbus.service.cmake000066400000000000000000000013711353342203500215030ustar00rootroot00000000000000####### # SPDX license identifier: MPL-2.0 # # Copyright (C) 2011-2015, BMW AG # # This file is part of GENIVI Project DLT - Diagnostic Log and Trace. # # This Source Code Form is subject to the terms of the # Mozilla Public License (MPL), v. 2.0. # If a copy of the MPL was not distributed with this file, # You can obtain one at http://mozilla.org/MPL/2.0/. # # For further information see http://www.genivi.org/. ####### [Unit] Description=GENIVI DLT DBus. Application to forward DBus messages to DLT. Documentation=man:dlt-dbus(1) man:dlt-dbus.conf(5) Wants=dlt.service [Service] Type=simple User=@DLT_USER@ ExecStart=@CMAKE_INSTALL_PREFIX@/bin/dlt-dbus WatchdogSec=@DLT_WatchdogSec@ NotifyAccess=main LimitCORE=infinity [Install] WantedBy=basic.target dlt-daemon-2.18.4/systemd/dlt-example-user.service.cmake000066400000000000000000000013141353342203500231520ustar00rootroot00000000000000####### # SPDX license identifier: MPL-2.0 # # Copyright (C) 2011-2015, BMW AG # # This file is part of GENIVI Project DLT - Diagnostic Log and Trace. # # This Source Code Form is subject to the terms of the # Mozilla Public License (MPL), v. 2.0. # If a copy of the MPL was not distributed with this file, # You can obtain one at http://mozilla.org/MPL/2.0/. # # For further information see http://www.genivi.org/. ####### [Unit] Description=GENIVI DLT example user. Generate DLT messages and store them to file or send them to daemon. Wants=dlt.service [Service] Type=simple User=@DLT_USER@ ExecStart=@CMAKE_INSTALL_PREFIX@/bin/dlt-example-user "Hallo from GENIVI DLT example user application" LimitCORE=infinitydlt-daemon-2.18.4/systemd/dlt-receive.service.cmake000066400000000000000000000013311353342203500221640ustar00rootroot00000000000000####### # SPDX license identifier: MPL-2.0 # # Copyright (C) 2011-2015, BMW AG # # This file is part of GENIVI Project DLT - Diagnostic Log and Trace. # # This Source Code Form is subject to the terms of the # Mozilla Public License (MPL), v. 2.0. # If a copy of the MPL was not distributed with this file, # You can obtain one at http://mozilla.org/MPL/2.0/. # # For further information see http://www.genivi.org/. ####### [Unit] Description=GENIVI DLT receive. Receive DLT messages from DLT daemon and print or store the messages. Documentation=man:dlt-receive(1) Wants=dlt.service [Service] Type=simple User=@DLT_USER@ ExecStart=@CMAKE_INSTALL_PREFIX@/bin/dlt-receive -o /tmp/dlt_receive_log.dlt localhost LimitCORE=infinitydlt-daemon-2.18.4/systemd/dlt-system.service.cmake000077500000000000000000000014601353342203500220740ustar00rootroot00000000000000####### # SPDX license identifier: MPL-2.0 # # Copyright (C) 2011-2015, BMW AG # # This file is part of GENIVI Project DLT - Diagnostic Log and Trace. # # This Source Code Form is subject to the terms of the # Mozilla Public License (MPL), v. 2.0. # If a copy of the MPL was not distributed with this file, # You can obtain one at http://mozilla.org/MPL/2.0/. # # For further information see http://www.genivi.org/. ####### [Unit] Description=GENIVI DLT system. Application to forward syslog messages to DLT, transfer system information, logs and files. Documentation=man:dlt-system(1) man:dlt-system.conf(5) Wants=dlt.service [Service] Type=simple User=@DLT_USER@ ExecStart=@CMAKE_INSTALL_PREFIX@/bin/dlt-system WatchdogSec=@DLT_WatchdogSec@ NotifyAccess=main LimitCORE=infinity [Install] WantedBy=basic.target dlt-daemon-2.18.4/systemd/dlt.service.cmake000077500000000000000000000013011353342203500205440ustar00rootroot00000000000000####### # SPDX license identifier: MPL-2.0 # # Copyright (C) 2011-2015, BMW AG # # This file is part of GENIVI Project DLT - Diagnostic Log and Trace. # # This Source Code Form is subject to the terms of the # Mozilla Public License (MPL), v. 2.0. # If a copy of the MPL was not distributed with this file, # You can obtain one at http://mozilla.org/MPL/2.0/. # # For further information see http://www.genivi.org/. ####### [Unit] Description=GENIVI DLT logging daemon Documentation=man:dlt-daemon(1) man:dlt.conf(5) [Service] Type=simple User=@DLT_USER@ ExecStart=@CMAKE_INSTALL_PREFIX@/bin/dlt-daemon WatchdogSec=@DLT_WatchdogSec@ NotifyAccess=main LimitCORE=infinity [Install] WantedBy=basic.target dlt-daemon-2.18.4/tests/000077500000000000000000000000001353342203500147745ustar00rootroot00000000000000dlt-daemon-2.18.4/tests/CMakeLists.txt000066400000000000000000000042311353342203500175340ustar00rootroot00000000000000# Setup testing enable_testing() #add_compile_options(-g -fsanitize=address) add_compile_options(-isystem ${gtest_SOURCE_DIR}/include) configure_file(${PROJECT_SOURCE_DIR}/tests/testfile.dlt ${PROJECT_BINARY_DIR}/tests COPYONLY) if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux") set(LIBRARIES gtest gtest_main) else() set(LIBRARIES gtest socket) endif() set(DLT_LIBRARIES ${LIBRARIES} dlt) set(DLT_DAEMON_LIBRARIES ${LIBRARIES} dlt_daemon) if(WITH_SYSTEMD OR WITH_SYSTEMD_WATCHDOG OR WITH_SYSTEMD_JOURNAL) add_definitions( -DSD_EXPORT_SYMBOLS ) endif() add_executable(gtest_dlt_common gtest_dlt_common.cpp) add_executable(gtest_dlt_user gtest_dlt_user.cpp) add_executable(gtest_dlt_daemon_common gtest_dlt_daemon_common.cpp ../src/daemon/dlt_daemon_common.c) add_executable(dlt_test_receiver dlt_test_receiver.c) add_executable(dlt_env_ll_unit_test dlt_env_ll_unit_test.cpp) add_executable(dlt-test-preregister-context dlt-test-preregister-context.c) add_executable(gtest_dlt_daemon_gateway gtest_dlt_daemon_gateway.cpp ${systemd_SRCS}) add_executable(gtest_dlt_daemon_event_handler gtest_dlt_daemon_event_handler.cpp ${systemd_SRCS}) add_executable(gtest_dlt_daemon_offline_log gtest_dlt_daemon_offline_log.cpp ${systemd_SRCS}) if(WITH_DLT_SHM_ENABLE) add_executable(gtest_dlt_shm gtest_dlt_shm.cpp) endif(WITH_DLT_SHM_ENABLE) target_link_libraries(gtest_dlt_common ${DLT_LIBRARIES}) target_link_libraries(gtest_dlt_user ${DLT_LIBRARIES}) target_link_libraries(gtest_dlt_daemon_common ${DLT_LIBRARIES}) target_link_libraries(dlt_test_receiver dlt) target_link_libraries(dlt_env_ll_unit_test ${DLT_LIBRARIES}) target_link_libraries(dlt-test-preregister-context ${DLT_LIBRARIES}) target_link_libraries(gtest_dlt_daemon_gateway ${DLT_DAEMON_LIBRARIES}) target_link_libraries(gtest_dlt_daemon_event_handler ${DLT_DAEMON_LIBRARIES}) target_link_libraries(gtest_dlt_daemon_offline_log ${DLT_DAEMON_LIBRARIES}) if(WITH_DLT_SHM_ENABLE) target_link_libraries(gtest_dlt_shm ${DLT_DAEMON_LIBRARIES}) endif(WITH_DLT_SHM_ENABLE) if(WITH_DLT_CXX11_EXT) add_executable(dlt-test-cpp-extension dlt-test-cpp-extension.cpp) target_link_libraries(dlt-test-cpp-extension ${DLT_LIBRARIES}) endif() dlt-daemon-2.18.4/tests/dlt-test-cpp-extension.cpp000066400000000000000000000062131353342203500220340ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2015 Intel Corporation * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author Stefan Vacek Intel Corporation * * \copyright Copyright © 2015 Intel Corporation. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file dlt-test-cpp-extension.cpp */ #include "dlt_cpp_extension.hpp" #include #include struct MyStruct { int64_t uuid; int32_t interfaceId; int32_t registrationState; }; template<> inline int logToDlt(DltContextData &log, MyStruct const &value) { int result = 0; result += dlt_user_log_write_string(&log, "("); result += logToDlt(log, value.uuid); result += dlt_user_log_write_string(&log, ","); result += logToDlt(log, value.interfaceId); result += dlt_user_log_write_string(&log, ","); result += logToDlt(log, value.registrationState); result += dlt_user_log_write_string(&log, ")"); if (result != 0) result = -1; return result; } /** * Sample code to show usage of the cpp-extension * mainly the variadic templates */ int main() { if (dlt_register_app("TCPP", "Test cpp extension") < 0) { printf("Failed to register application\n"); return -1; } DltContext ctx; if (dlt_register_context_ll_ts(&ctx, "TCPP", "Test cpp extension", DLT_LOG_INFO, DLT_TRACE_STATUS_OFF) < 0) { printf("Failed to register context\n"); return -1; } dlt_enable_local_print(); dlt_verbose_mode(); DLT_LOG(ctx, DLT_LOG_WARN, DLT_STRING("a message")); /* the classic way to go */ int an_int = 42; float a_float = 22.7; DLT_LOG_FCN_CXX(ctx, DLT_LOG_WARN, "Testing DLT_LOG_CXX_FCN", an_int, a_float); DLT_LOG_CXX(ctx, DLT_LOG_WARN, 1.0, 65); /* Example for logging user-defined types */ MyStruct myData = { 1u, 2u, 3u }; DLT_LOG_CXX(ctx, DLT_LOG_WARN, "MyStruct myData", myData); char *non_const_string = (char *)malloc(17); memcpy(non_const_string, "non_const_string", 16); non_const_string[16] = 0; DLT_LOG_CXX(ctx, DLT_LOG_WARN, "char *", non_const_string); std::string aString = "std::string"; DLT_LOG_CXX(ctx, DLT_LOG_WARN, "std::string", aString); std::vector intVector; intVector.push_back(0); intVector.push_back(1); intVector.push_back(2); DLT_LOG_CXX(ctx, DLT_LOG_WARN, "vector", intVector); std::vector doubleList; doubleList.push_back(10.); doubleList.push_back(11.); doubleList.push_back(12.); DLT_LOG_CXX(ctx, DLT_LOG_WARN, "list", doubleList); std::map testMap; testMap["apple"] = 100; testMap["plum"] = 200; testMap["orange"] = 300; DLT_LOG_CXX(ctx, DLT_LOG_WARN, "map", testMap); dlt_unregister_context(&ctx); dlt_unregister_app(); return 0; } dlt-daemon-2.18.4/tests/dlt-test-preregister-context.c000066400000000000000000000026671353342203500227260ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2015 Intel Corporation * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author Stefan Vacek Intel Corporation * * \copyright Copyright © 2015 Intel Corporation. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file dlt-test-preregister-context.c */ #include /* for fork() */ #include "dlt.h" /** * @brief sample code for using pre-registered contexts */ int main() { DltContext mainContext; struct timespec ts; ts.tv_sec = 0; ts.tv_nsec = 200000 * 1000; DLT_REGISTER_CONTEXT(mainContext, "CTXP", "main context"); DLT_LOG(mainContext, DLT_LOG_WARN, DLT_STRING("First message before app registered")); nanosleep(&ts, NULL); DLT_LOG(mainContext, DLT_LOG_WARN, DLT_STRING("Second message before app registered")); nanosleep(&ts, NULL); DLT_REGISTER_APP("PRNT", "Sample pre-register application"); DLT_LOG(mainContext, DLT_LOG_WARN, DLT_STRING("First message after app registered")); nanosleep(&ts, NULL); DLT_UNREGISTER_APP() ; return 0; } dlt-daemon-2.18.4/tests/dlt_env_ll_unit_test.cpp000066400000000000000000000413371353342203500217300ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2015 Intel Corporation * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author Stefan Vacek Intel Corporation * * \copyright Copyright © 2015 Intel Corporation. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file dlt_env_ll_unit_test.cpp */ #include "gtest/gtest.h" #include "dlt_user.h" #include "dlt_common.h" /* needed for dlt_set_id */ /* simply include the whole file to allow testing it */ #include "src/lib/dlt_env_ll.c" int main(int argc, char *argv[]) { ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } TEST(DltExtensionTests, extract_id) { /* testing valid input */ char id[4u]; char env0[] = "abcd:1234:3"; char *tmp = &env0[0]; ASSERT_EQ(dlt_env_extract_id(&tmp, id), 0); ASSERT_EQ(tmp - &env0[0], 4); /* moved 4 bytes */ ASSERT_EQ(id[0], 'a'); ASSERT_EQ(id[1], 'b'); ASSERT_EQ(id[2], 'c'); ASSERT_EQ(id[3], 'd'); char env1[] = "abc:1234:3"; tmp = &env1[0]; ASSERT_EQ(dlt_env_extract_id(&tmp, id), 0); ASSERT_EQ(tmp - &env1[0], 3); /* moved 3 bytes */ ASSERT_EQ(id[0], 'a'); ASSERT_EQ(id[1], 'b'); ASSERT_EQ(id[2], 'c'); ASSERT_EQ(id[3], 0); char env2[] = "ab:1234:3"; tmp = &env2[0]; ASSERT_EQ(dlt_env_extract_id(&tmp, id), 0); ASSERT_EQ(tmp - &env2[0], 2); /* moved 2 bytes */ ASSERT_EQ(id[0], 'a'); ASSERT_EQ(id[1], 'b'); ASSERT_EQ(id[2], 0); ASSERT_EQ(id[3], 0); char env3[] = "a:1234:3"; tmp = &env3[0]; ASSERT_EQ(dlt_env_extract_id(&tmp, id), 0); ASSERT_EQ(tmp - &env3[0], 1); /* moved 1 byte */ ASSERT_EQ(id[0], 'a'); ASSERT_EQ(id[1], 0); ASSERT_EQ(id[2], 0); ASSERT_EQ(id[3], 0); char env4[] = ":1234:3"; tmp = &env4[0]; ASSERT_EQ(dlt_env_extract_id(&tmp, id), 0); ASSERT_EQ(tmp - &env4[0], 0); /* moved 1 byte */ ASSERT_EQ(id[0], 0); ASSERT_EQ(id[1], 0); ASSERT_EQ(id[2], 0); ASSERT_EQ(id[3], 0); char env5[] = "abcd:1234:3;"; tmp = &env5[0]; ASSERT_EQ(dlt_env_extract_id(&tmp, id), 0); ASSERT_EQ(tmp - &env5[0], 4); /* moved 4 bytes */ ASSERT_EQ(id[0], 'a'); ASSERT_EQ(id[1], 'b'); ASSERT_EQ(id[2], 'c'); ASSERT_EQ(id[3], 'd'); /* testing invalid input */ /* - string too long: abcde: * - string too short/missing end: abc * - NULL string: */ tmp = NULL; ASSERT_EQ(dlt_env_extract_id(&tmp, id), -1); char env6[] = "abcd:1234:3"; tmp = &env6[0]; ASSERT_EQ(dlt_env_extract_id(&tmp, NULL), -1); char invalid0[] = ""; tmp = &invalid0[0]; ASSERT_EQ(dlt_env_extract_id(&tmp, id), -1); char invalid1[] = "abcd"; /* missing delimiter */ tmp = &invalid1[0]; ASSERT_EQ(dlt_env_extract_id(&tmp, id), -1); char invalid2[] = "abcde"; /* id too long */ tmp = &invalid2[0]; ASSERT_EQ(dlt_env_extract_id(&tmp, id), -1); } TEST(DltExtensionTests, extract_ll) { /* testing valid input */ int8_t ll; char env_1[] = "-1"; char *tmp = &env_1[0]; ASSERT_EQ(dlt_env_extract_ll(&tmp, &ll), 0); ASSERT_EQ(tmp - &env_1[0], 2); /* moved 2 bytes */ ASSERT_EQ(ll, -1); char env0[] = "0;"; tmp = &env0[0]; ASSERT_EQ(dlt_env_extract_ll(&tmp, &ll), 0); ASSERT_EQ(tmp - &env0[0], 1); /* moved 1 byte */ ASSERT_EQ(ll, 0); char env1[] = "1;"; tmp = &env1[0]; ASSERT_EQ(dlt_env_extract_ll(&tmp, &ll), 0); ASSERT_EQ(tmp - &env1[0], 1); /* moved 1 byte */ ASSERT_EQ(ll, 1); char env2[] = "2;"; tmp = &env2[0]; ASSERT_EQ(dlt_env_extract_ll(&tmp, &ll), 0); ASSERT_EQ(tmp - &env2[0], 1); /* moved 1 byte */ ASSERT_EQ(ll, 2); char env3[] = "3;"; tmp = &env3[0]; ASSERT_EQ(dlt_env_extract_ll(&tmp, &ll), 0); ASSERT_EQ(tmp - &env3[0], 1); /* moved 1 byte */ ASSERT_EQ(ll, 3); char env4[] = "4;"; tmp = &env4[0]; ASSERT_EQ(dlt_env_extract_ll(&tmp, &ll), 0); ASSERT_EQ(tmp - &env4[0], 1); /* moved 1 byte */ ASSERT_EQ(ll, 4); char env5[] = "5;"; tmp = &env5[0]; ASSERT_EQ(dlt_env_extract_ll(&tmp, &ll), 0); ASSERT_EQ(tmp - &env5[0], 1); /* moved 1 byte */ ASSERT_EQ(ll, 5); char env6[] = "6;"; tmp = &env6[0]; ASSERT_EQ(dlt_env_extract_ll(&tmp, &ll), 0); ASSERT_EQ(tmp - &env6[0], 1); /* moved 1 byte */ ASSERT_EQ(ll, 6); /* testing invalid input */ /* - number outside range, e.g. -2, 103 * - missing delimiter * - NULL string: */ tmp = NULL; ASSERT_EQ(dlt_env_extract_ll(&tmp, &ll), -1); char env7[] = "abcd:1234:3"; tmp = &env7[0]; ASSERT_EQ(dlt_env_extract_id(&tmp, NULL), -1); char invalid0[] = ""; tmp = &invalid0[0]; ASSERT_EQ(dlt_env_extract_ll(&tmp, &ll), -1); char invalid1[] = "-2"; /* outside range */ tmp = &invalid1[0]; ASSERT_EQ(dlt_env_extract_ll(&tmp, &ll), -1); char invalid2[] = "8"; /* outside range */ tmp = &invalid2[0]; ASSERT_EQ(dlt_env_extract_ll(&tmp, &ll), -1); char invalid3[] = "1e"; /* missing delimiter */ tmp = &invalid3[0]; ASSERT_EQ(dlt_env_extract_ll(&tmp, &ll), -1); } TEST(DltExtensionTests, extract_ll_item) { /* testing valid input */ dlt_env_ll_item item; char env0[] = "abcd:1234:3"; char *tmp = &env0[0]; ASSERT_EQ(dlt_env_extract_ll_item(&tmp, &item), 0); ASSERT_EQ(tmp - &env0[0], 11); /* moved 11 bytes */ ASSERT_EQ(item.appId[0], 'a'); ASSERT_EQ(item.appId[1], 'b'); ASSERT_EQ(item.appId[2], 'c'); ASSERT_EQ(item.appId[3], 'd'); ASSERT_EQ(item.ctxId[0], '1'); ASSERT_EQ(item.ctxId[1], '2'); ASSERT_EQ(item.ctxId[2], '3'); ASSERT_EQ(item.ctxId[3], '4'); ASSERT_EQ(item.ll, 3); char env1[] = "::-1;"; tmp = &env1[0]; ASSERT_EQ(dlt_env_extract_ll_item(&tmp, &item), 0); ASSERT_EQ(tmp - &env1[0], 4); /* moved 4 bytes */ ASSERT_EQ(item.appId[0], 0); ASSERT_EQ(item.appId[1], 0); ASSERT_EQ(item.appId[2], 0); ASSERT_EQ(item.appId[3], 0); ASSERT_EQ(item.ctxId[0], 0); ASSERT_EQ(item.ctxId[1], 0); ASSERT_EQ(item.ctxId[2], 0); ASSERT_EQ(item.ctxId[3], 0); ASSERT_EQ(item.ll, -1); /* testing invalid input */ /* - string too long: abcde: * - string too short/missing end: abc * - NULL string: */ tmp = NULL; ASSERT_EQ(dlt_env_extract_ll_item(&tmp, &item), -1); char env2[] = "abcd:1234:3"; tmp = &env2[0]; ASSERT_EQ(dlt_env_extract_ll_item(&tmp, NULL), -1); char invalid0[] = ""; tmp = &invalid0[0]; ASSERT_EQ(dlt_env_extract_ll_item(&tmp, &item), -1); char invalid1[] = "abcd:1234:"; /* missing ll */ tmp = &invalid1[0]; ASSERT_EQ(dlt_env_extract_ll_item(&tmp, &item), -1); char invalid2[] = "abcd:1234"; /* missing ll, missing delimiter in ctxId */ tmp = &invalid2[0]; ASSERT_EQ(dlt_env_extract_ll_item(&tmp, &item), -1); char invalid3[] = "abcd:"; /* missing ll, missing delimiter in appId */ tmp = &invalid3[0]; ASSERT_EQ(dlt_env_extract_ll_item(&tmp, &item), -1); char invalid4[] = "abcd"; /* missing ll, missing delimiter in appId */ tmp = &invalid4[0]; ASSERT_EQ(dlt_env_extract_ll_item(&tmp, &item), -1); } TEST(DltExtensionTests, basic_ll_set_handling) { dlt_env_init_ll_set(NULL); /* must not crash */ dlt_env_free_ll_set(NULL); /* must not crash */ dlt_env_increase_ll_set(NULL); /* must not crash */ dlt_env_ll_set ll_set; dlt_env_init_ll_set(&ll_set); EXPECT_TRUE(NULL != ll_set.item); EXPECT_EQ(DLT_ENV_LL_SET_INCREASE, ll_set.array_size); EXPECT_EQ(0, ll_set.num_elem); dlt_env_free_ll_set(&ll_set); EXPECT_TRUE(NULL == ll_set.item); EXPECT_EQ(0, ll_set.array_size); EXPECT_EQ(0, ll_set.num_elem); dlt_env_init_ll_set(&ll_set); for (int i = 0; i < DLT_ENV_LL_SET_INCREASE; ++i) ll_set.item[i].ll = i; dlt_env_increase_ll_set(&ll_set); EXPECT_EQ(2 * DLT_ENV_LL_SET_INCREASE, ll_set.array_size); for (int i = 0; i < DLT_ENV_LL_SET_INCREASE; ++i) EXPECT_EQ(ll_set.item[i].ll, i); dlt_env_free_ll_set(&ll_set); EXPECT_TRUE(NULL == ll_set.item); EXPECT_EQ(0, ll_set.array_size); EXPECT_EQ(0, ll_set.num_elem); } TEST(DltExtensionTests, extract_ll_set) { /* testing valid input */ dlt_env_ll_set ll_set; char env0[] = "abcd:1234:3"; char *tmp = &env0[0]; ASSERT_EQ(dlt_env_extract_ll_set(&tmp, &ll_set), 0); EXPECT_EQ(ll_set.array_size, DLT_ENV_LL_SET_INCREASE); EXPECT_EQ(ll_set.num_elem, 1); EXPECT_EQ(ll_set.item[0].ll, 3); dlt_env_free_ll_set(&ll_set); /* force increasing the list */ char env1[] = "abcd:0000:3;abcd:0001:3;abcd:0002:3;abcd:0003:3;abcd:0004:3;abcd:0005:3;abcd:0006:3;abcd:0007:3;abcd:0008:3;abcd:0009:3;abcd:0010:3"; tmp = &env1[0]; ASSERT_EQ(dlt_env_extract_ll_set(&tmp, &ll_set), 0); EXPECT_EQ(ll_set.array_size, 2 * DLT_ENV_LL_SET_INCREASE); EXPECT_EQ(ll_set.num_elem, 11); for (size_t i = 0; i < ll_set.num_elem; ++i) EXPECT_EQ(ll_set.item[i].ctxId[3], i % 10 + '0'); dlt_env_free_ll_set(&ll_set); char env2[] = "SINA:SINC:FATAL"; tmp = &env2[0]; ASSERT_EQ(dlt_env_extract_ll_set(&tmp, &ll_set), 0); EXPECT_EQ(ll_set.array_size, DLT_ENV_LL_SET_INCREASE); EXPECT_EQ(ll_set.num_elem, 1); EXPECT_EQ(ll_set.item[0].ll, 1); dlt_env_free_ll_set(&ll_set); } TEST(DltExtensionTests, ids_match) { ASSERT_EQ(1, dlt_env_ids_match("abcd", "abcd")); ASSERT_EQ(0, dlt_env_ids_match("abcd", "abce")); ASSERT_EQ(0, dlt_env_ids_match("abcd", "abee")); ASSERT_EQ(0, dlt_env_ids_match("abcd", "aeee")); ASSERT_EQ(0, dlt_env_ids_match("abcd", "eeee")); ASSERT_TRUE(dlt_env_ids_match("abcd", "abcd")); ASSERT_FALSE(dlt_env_ids_match("abcd", "abce")); } TEST(DltExtensionTests, get_matching_prio) { char apid[5] = "ABCD"; char ctid[5] = "1234"; dlt_env_ll_item test0; dlt_set_id(test0.appId, ""); dlt_set_id(test0.ctxId, ""); ASSERT_EQ(1, dlt_env_ll_item_get_matching_prio(&test0, apid, ctid)); dlt_set_id(test0.appId, ""); dlt_set_id(test0.ctxId, ctid); ASSERT_EQ(2, dlt_env_ll_item_get_matching_prio(&test0, apid, ctid)); dlt_set_id(test0.appId, apid); dlt_set_id(test0.ctxId, ""); ASSERT_EQ(3, dlt_env_ll_item_get_matching_prio(&test0, apid, ctid)); dlt_set_id(test0.appId, apid); dlt_set_id(test0.ctxId, ctid); ASSERT_EQ(4, dlt_env_ll_item_get_matching_prio(&test0, apid, ctid)); dlt_set_id(test0.appId, "EFGH"); /* appId should not match */ dlt_set_id(test0.ctxId, ctid); ASSERT_EQ(0, dlt_env_ll_item_get_matching_prio(&test0, apid, ctid)); ASSERT_EQ(-1, dlt_env_ll_item_get_matching_prio(NULL, apid, ctid)); ASSERT_EQ(-1, dlt_env_ll_item_get_matching_prio(&test0, NULL, ctid)); ASSERT_EQ(-1, dlt_env_ll_item_get_matching_prio(&test0, apid, NULL)); } TEST(DltExtensionTests, adjust_ll_from_env) { char apid[5] = "ABCD"; char ctid[5] = "1234"; int ll = 42; /* unrealistic value to see that the ll was not touched */ dlt_env_ll_set ll_set; dlt_env_init_ll_set(&ll_set); EXPECT_EQ(ll, dlt_env_adjust_ll_from_env(NULL, apid, ctid, ll)); /* orig value in case of error */ EXPECT_EQ(ll, dlt_env_adjust_ll_from_env(&ll_set, NULL, ctid, ll)); /* orig value in case of error */ EXPECT_EQ(ll, dlt_env_adjust_ll_from_env(&ll_set, apid, NULL, ll)); /* orig value in case of error */ EXPECT_EQ(ll, dlt_env_adjust_ll_from_env(&ll_set, apid, ctid, ll)); /* an empty set should not match anything */ dlt_set_id(ll_set.item[0].appId, "DEAD"); /* not matching */ dlt_set_id(ll_set.item[0].ctxId, "BEEF"); ll_set.item[0].ll = 0; ll_set.num_elem = 1; EXPECT_EQ(ll, dlt_env_adjust_ll_from_env(&ll_set, apid, ctid, ll)); /* not matching anything */ dlt_set_id(ll_set.item[1].appId, ""); /* empty rule, weakest */ dlt_set_id(ll_set.item[1].ctxId, ""); ll_set.item[1].ll = 1; ll_set.num_elem = 2; EXPECT_EQ(1, dlt_env_adjust_ll_from_env(&ll_set, apid, ctid, ll)); dlt_set_id(ll_set.item[2].appId, ""); /* prio 2 */ dlt_set_id(ll_set.item[2].ctxId, ctid); ll_set.item[2].ll = 2; ll_set.num_elem = 3; EXPECT_EQ(2, dlt_env_adjust_ll_from_env(&ll_set, apid, ctid, ll)); dlt_set_id(ll_set.item[3].appId, apid); /* prio 3 */ dlt_set_id(ll_set.item[3].ctxId, ""); ll_set.item[3].ll = 3; ll_set.num_elem = 4; EXPECT_EQ(3, dlt_env_adjust_ll_from_env(&ll_set, apid, ctid, ll)); dlt_set_id(ll_set.item[4].appId, apid); /* prio 4 */ dlt_set_id(ll_set.item[4].ctxId, ctid); ll_set.item[4].ll = 4; ll_set.num_elem = 5; EXPECT_EQ(4, dlt_env_adjust_ll_from_env(&ll_set, apid, ctid, ll)); dlt_set_id(ll_set.item[5].appId, apid); /* does not matter item[4] will always match */ dlt_set_id(ll_set.item[5].ctxId, ""); ll_set.item[5].ll = 5; ll_set.num_elem = 6; EXPECT_EQ(4, dlt_env_adjust_ll_from_env(&ll_set, apid, ctid, ll)); /* remember, item[4] matches */ dlt_env_free_ll_set(&ll_set); } /* int dlt_env_helper_to_lower(char **env, char *result, int res_len) */ TEST(DltExtensionTests, dlt_env_helper_to_lower) { /* default behavior */ char env0[] = "1238<><<>>>>#$//abcdABCDEDFGHIJKLMNOPQRSTUVWXYZpo;ABcd"; char res0[] = "1238<><<>>>>#$//abcdabcdedfghijklmnopqrstuvwxyzpo"; char *tmp0 = &env0[0]; char result0[sizeof(res0)]; ASSERT_EQ(0, dlt_env_helper_to_lower(&tmp0, result0, sizeof(result0))); ASSERT_EQ(';', *tmp0); /* next char is ';' */ ASSERT_STREQ(res0, result0); /* stops at ';' and is correctly converted */ /* default behavior with end of string */ char env1[] = "1238<><<>>>>#$//abcdABCDEDFGHIJKLMNOPQRSTUVWXYZpo"; char res1[] = "1238<><<>>>>#$//abcdabcdedfghijklmnopqrstuvwxyzpo"; char *tmp1 = &env1[0]; char result1[sizeof(res1)]; ASSERT_EQ(0, dlt_env_helper_to_lower(&tmp1, result1, sizeof(result1))); ASSERT_EQ(0, *tmp1); /* next char is void */ ASSERT_STREQ(res1, result1); /* stops at end-of-string and is correctly converted */ /* result string too short */ char env2[] = "2238<><<>>>>#$//abcdABCDEDFGHIJKLMNOPQRSTUVWXYZpo"; char res2[] = "2238<><<>>>>#$//abcdabcdedfg"; char *tmp2 = &env2[0]; char result2[sizeof(res2)]; ASSERT_EQ(-1, dlt_env_helper_to_lower(&tmp2, result2, sizeof(result2))); ASSERT_EQ('H', *tmp2); /* next char is void */ ASSERT_STREQ(res2, result2); /* stops at end-of-string and is partially converted */ /* input string shorter than result */ char env3[] = "3338<><<>>>>#$//abcdABCDEDFGHIJKLMNOPQRSTUVWXYZpo"; char res3[] = "3338<><<>>>>#$//abcdabcdedfghijklmnopqrstuvwxyzpo"; char *tmp3 = &env3[0]; char result3[sizeof(res3) + 5]; ASSERT_EQ(0, dlt_env_helper_to_lower(&tmp3, result3, sizeof(result3))); ASSERT_EQ(0, *tmp3); /* next char is void */ ASSERT_STREQ(res3, result3); /* stops at end-of-string and is correctly converted */ } /* int dlt_env_extract_symbolic_ll(char **env, int8_t * ll) */ TEST(DltExtensionTests, dlt_env_extract_symbolic_ll) { int8_t result; /* correct behavior */ char env0[] = "DEFAULT;off;fatal;error;warning;info;DeBuG;verbose"; char *tmp0 = &env0[0]; ASSERT_EQ(0, dlt_env_extract_symbolic_ll(&tmp0, &result)); ASSERT_EQ('o', *tmp0); ASSERT_EQ(-1, result); ASSERT_EQ(0, dlt_env_extract_symbolic_ll(&tmp0, &result)); ASSERT_EQ('f', *tmp0); ASSERT_EQ(0, result); ASSERT_EQ(0, dlt_env_extract_symbolic_ll(&tmp0, &result)); ASSERT_EQ('e', *tmp0); ASSERT_EQ(1, result); ASSERT_EQ(0, dlt_env_extract_symbolic_ll(&tmp0, &result)); ASSERT_EQ('w', *tmp0); ASSERT_EQ(2, result); ASSERT_EQ(0, dlt_env_extract_symbolic_ll(&tmp0, &result)); ASSERT_EQ('i', *tmp0); ASSERT_EQ(3, result); ASSERT_EQ(0, dlt_env_extract_symbolic_ll(&tmp0, &result)); ASSERT_EQ('D', *tmp0); ASSERT_EQ(4, result); ASSERT_EQ(0, dlt_env_extract_symbolic_ll(&tmp0, &result)); ASSERT_EQ('v', *tmp0); ASSERT_EQ(5, result); ASSERT_EQ(0, dlt_env_extract_symbolic_ll(&tmp0, &result)); ASSERT_EQ(0, *tmp0); ASSERT_EQ(6, result); /* incorrect behavior */ char env1[] = "DEF"; char *tmp1 = &env1[0]; result = 18; ASSERT_EQ(-1, dlt_env_extract_symbolic_ll(&tmp1, &result)); ASSERT_EQ(0, *tmp1); ASSERT_EQ(18, result); /* 'result' is not touched */ /* incorrect behavior */ char env2[] = "DEFaultingfBa"; char *tmp2 = &env2[0]; result = 28; ASSERT_EQ(-1, dlt_env_extract_symbolic_ll(&tmp2, &result)); ASSERT_EQ('i', *tmp2); ASSERT_EQ(28, result); /* 'result' is not touched */ } dlt-daemon-2.18.4/tests/dlt_test_receiver.c000066400000000000000000000330621353342203500206520ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2011-2015, BMW AG * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author * Alexander Wenzel * Markus Klein * Stefan Held * * \copyright Copyright © 2011-2015 BMW AG. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file dlt_test_receiver.c */ /******************************************************************************* ** ** ** SRC-MODULE: dlt-receive.cpp ** ** ** ** TARGET : linux ** ** ** ** PROJECT : DLT ** ** ** ** AUTHOR : Alexander Wenzel Alexander.AW.Wenzel@bmw.de ** ** Markus Klein ** ** ** ** PURPOSE : ** ** ** ** REMARKS : ** ** ** ** PLATFORM DEPENDANT [yes/no]: yes ** ** ** ** TO BE CHANGED BY USER [yes/no]: no ** ** ** *******************************************************************************/ /******************************************************************************* ** Author Identity ** ******************************************************************************** ** ** ** Initials Name Company ** ** -------- ------------------------- ---------------------------------- ** ** aw Alexander Wenzel BMW ** ** mk Markus Klein Fraunhofer ESK ** *******************************************************************************/ /******************************************************************************* ** Revision Control History ** *******************************************************************************/ /* * $LastChangedRevision: 1670 $ * $LastChangedDate: 2011-04-08 15:12:06 +0200 (Fr, 08. Apr 2011) $ * $LastChangedBy$ * Initials Date Comment * aw 13.01.2010 initial */ #include /* for isprint() */ #include /* for atoi() */ #include /* for S_IRUSR, S_IWUSR, S_IRGRP, S_IROTH */ #include /* for open() */ #include /* for writev() */ #include #include #include "dlt_client.h" #include #define DLT_RECEIVE_ECU_ID "RECV" /* Function prototypes */ int dlt_receive_filetransfer_callback(DltMessage *message, void *data); typedef struct { int vflag; int yflag; char *ovalue; char *evalue; int bvalue; int filetransfervalue; int systemjournalvalue; int systemloggervalue; char ecuid[4]; int ohandle; DltFile file; DltFilter filter; } DltReceiveData; FILE *fp; int result = 0; /** * Print usage information of tool. */ void usage() { char version[255]; dlt_get_version(version, 255); printf("Usage: dlt-receive [options] hostname/serial_device_name\n"); printf("Receive DLT messages from DLT daemon and print or store the messages.\n"); printf("Use filters to filter received messages.\n"); printf("%s \n", version); printf("Options:\n"); printf(" -v Verbose mode\n"); printf(" -h Usage\n"); printf(" -y Serial device mode\n"); printf(" -f Activate filetransfer test case\n"); printf(" -s Activate systemd journal test case\n"); printf(" -l Activate system logger test case"); printf(" -b baudrate Serial device baudrate (Default: 115200)\n"); printf(" -e ecuid Set ECU ID (Default: RECV)\n"); printf(" -o filename Output messages in new DLT file\n"); } /** * Main function of tool. */ int main(int argc, char *argv[]) { DltClient dltclient; DltReceiveData dltdata; int c; int index; /* Initialize dltdata */ dltdata.vflag = 0; dltdata.yflag = 0; dltdata.ovalue = 0; dltdata.evalue = 0; dltdata.bvalue = 0; dltdata.ohandle = -1; dltdata.filetransfervalue = 0; dltdata.systemjournalvalue = 0; /* Fetch command line arguments */ opterr = 0; while ((c = getopt (argc, argv, "vshyfla:o:e:b:")) != -1) switch (c) { case 'v': { dltdata.vflag = 1; break; } case 'h': { usage(); return -1; } case 'y': { dltdata.yflag = 1; break; } case 'f': { dltdata.filetransfervalue = 1; break; } case 's': { dltdata.systemjournalvalue = 1; break; } case 'l': { dltdata.systemloggervalue = 1; break; } case 'o': { dltdata.ovalue = optarg; break; } case 'e': { dltdata.evalue = optarg; break; } case 'b': { dltdata.bvalue = atoi(optarg); break; } case '?': { if (optopt == 'o') fprintf (stderr, "Option -%c requires an argument.\n", optopt); else if (isprint (optopt)) fprintf (stderr, "Unknown option `-%c'.\n", optopt); else fprintf (stderr, "Unknown option character `\\x%x'.\n", optopt); /* unknown or wrong option used, show usage information and terminate */ usage(); return -1; } default: { abort (); return -1; /*for parasoft */ } } /* Initialize DLT Client */ dlt_client_init(&dltclient, dltdata.vflag); /* Register callback to be called when message was received */ dlt_client_register_message_callback(dlt_receive_filetransfer_callback); /* Setup DLT Client structure */ dltclient.mode = dltdata.yflag; if (dltclient.mode == 0) { for (index = optind; index < argc; index++) if (dlt_client_set_server_ip(&dltclient, argv[index]) == -1) { fprintf(stderr, "set server ip didn't succeed\n"); return -1; } if (dltclient.servIP == 0) { /* no hostname selected, show usage and terminate */ fprintf(stderr, "ERROR: No hostname selected\n"); usage(); dlt_client_cleanup(&dltclient, dltdata.vflag); return -1; } } else { for (index = optind; index < argc; index++) if (dlt_client_set_serial_device(&dltclient, argv[index]) == -1) { fprintf(stderr, "set serial device didn't succeed\n"); return -1; } if (dltclient.serialDevice == 0) { /* no serial device name selected, show usage and terminate */ fprintf(stderr, "ERROR: No serial device name specified\n"); usage(); return -1; } dlt_client_setbaudrate(&dltclient, dltdata.bvalue); } /* initialise structure to use DLT file */ dlt_file_init(&(dltdata.file), dltdata.vflag); /* first parse filter file if filter parameter is used */ dlt_filter_init(&(dltdata.filter), dltdata.vflag); /* open DLT output file */ if (dltdata.ovalue) { dltdata.ohandle = open(dltdata.ovalue, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); /* mode: wb */ if (dltdata.ohandle == -1) { dlt_file_free(&(dltdata.file), dltdata.vflag); fprintf(stderr, "ERROR: Output file %s cannot be opened!\n", dltdata.ovalue); return -1; } } if (dltdata.evalue) dlt_set_id(dltdata.ecuid, dltdata.evalue); else dlt_set_id(dltdata.ecuid, DLT_RECEIVE_ECU_ID); /* Connect to TCP socket or open serial device */ if (dlt_client_connect(&dltclient, dltdata.vflag) != DLT_RETURN_ERROR) { /* Dlt Client Main Loop */ dlt_client_main_loop(&dltclient, &dltdata, dltdata.vflag); /* Dlt Client Cleanup */ dlt_client_cleanup(&dltclient, dltdata.vflag); } /* dlt-receive cleanup */ if (dltdata.ovalue) close(dltdata.ohandle); dlt_file_free(&(dltdata.file), dltdata.vflag); dlt_filter_free(&(dltdata.filter), dltdata.vflag); return 0; } int dlt_receive_filetransfer_callback(DltMessage *message, void *data) { DltReceiveData *dltdata; static char text[DLT_RECEIVE_BUFSIZE]; char filename[255]; struct iovec iov[2]; int bytes_written; if ((message == 0) || (data == 0)) return -1; dltdata = (DltReceiveData *)data; if (dltdata->filetransfervalue) { dlt_message_print_ascii(message, text, DLT_RECEIVE_BUFSIZE, dltdata->vflag); /* 1st find starting point of tranfering data packages */ if (strncmp(text, "FLST", 4) == 0) { char *tmpFilename; tmpFilename = strrchr(text, '/') + 1; unsigned int i; for (i = 0; i < strlen(tmpFilename); i++) if (isspace(tmpFilename[i])) { tmpFilename[i] = '\0'; break; } /* create file for each received file, as named as crc value */ snprintf(filename, 255, "/tmp/%s", tmpFilename); fp = fopen(filename, "w+"); } /* 3rd close fp */ if (strncmp(text, "FLFI", 4) == 0) { printf("TEST FILETRANSFER PASSED\n"); fclose(fp); } /* 2nd check if incomming data are filetransfer data */ if (strncmp(text, "FLDA", 4) == 0) { /* truncate beginning of data stream ( FLDA, File identifier and package number) */ char *position = strchr(text, 32); /* search for space */ strncpy(text, position + 1, DLT_RECEIVE_BUFSIZE); position = strchr(text, 32); strncpy(text, position + 1, DLT_RECEIVE_BUFSIZE); position = strchr(text, 32); strncpy(text, position + 1, DLT_RECEIVE_BUFSIZE); /* truncate ending of data stream ( FLDA ) */ int len = strlen(text); text[len - 4] = '\0'; /* hex to ascii and store at /tmp */ char tmp[3]; int i; for (i = 0; i < (int)strlen(text); i = i + 3) { tmp[0] = text[i]; tmp[1] = text[i + 1]; tmp[2] = '\0'; unsigned long h = strtoul(tmp, NULL, 16); fprintf(fp, "%c", (int)h); } } } if (dltdata->systemjournalvalue) { dlt_message_print_ascii(message, text, DLT_RECEIVE_BUFSIZE, dltdata->vflag); /* 1st find the relevant packages */ char *tmp = message->extendedheader->ctid; tmp[4] = '\0'; if (strcmp(tmp, (const char *)"JOUR") == 0) { if (strstr(text, "DLT SYSTEM JOURNAL TEST")) { result++; if (result == 1000) exit(159); } } } if (dltdata->systemloggervalue) { dlt_message_print_ascii(message, text, DLT_RECEIVE_BUFSIZE, dltdata->vflag); /* 1st find the relevant packages */ char *tmp = message->extendedheader->ctid; tmp[4] = '\0'; const char *substring = text; const char *founding = "Test Systemlogger"; int length = strlen(founding); if (strcmp(tmp, (const char *)"PROC") == 0) { substring = strstr(text, founding); while (substring != NULL) { result++; substring += length; if (result == 1000) exit(159); } } } /* if file output enabled write message */ if (dltdata->ovalue) { iov[0].iov_base = message->headerbuffer; iov[0].iov_len = message->headersize; iov[1].iov_base = message->databuffer; iov[1].iov_len = message->datasize; bytes_written = writev(dltdata->ohandle, iov, 2); if (0 > bytes_written) { printf("dlt_receive_message_callback: writev(dltdata->ohandle, iov, 2); returned an error!"); return -1; } } return 0; } dlt-daemon-2.18.4/tests/gtest_dlt_common.cpp000066400000000000000000006052241353342203500210520ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2011-2015, BMW AG * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author * Stefan Held * * \copyright Copyright © 2011-2015 BMW AG. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file gtest_dlt_common.cpp */ #include #include #include #include extern "C" { #include "dlt-daemon.h" #include "dlt-daemon_cfg.h" #include "dlt_user_cfg.h" #include "dlt_version.h" int dlt_buffer_increase_size(DltBuffer *); int dlt_buffer_minimize_size(DltBuffer *); int dlt_buffer_reset(DltBuffer *); DltReturnValue dlt_buffer_push(DltBuffer *, const unsigned char *, unsigned int); DltReturnValue dlt_buffer_push3(DltBuffer *, const unsigned char *, unsigned int, const unsigned char *, unsigned int, const unsigned char *, unsigned int); int dlt_buffer_get(DltBuffer *, unsigned char *, int, int); int dlt_buffer_pull(DltBuffer *, unsigned char *, int); int dlt_buffer_remove(DltBuffer *); void dlt_buffer_status(DltBuffer *); void dlt_buffer_write_block(DltBuffer *, int *, const unsigned char *, unsigned int); void dlt_buffer_read_block(DltBuffer *, int *, unsigned char *, unsigned int); void dlt_buffer_info(DltBuffer *); } /* Begin Method: dlt_common::dlt_buffer_init_dynamic */ TEST(t_dlt_buffer_init_dynamic, normal) { DltBuffer init_dynamic; /* Normal Use-Case for initializing a buffer */ EXPECT_LE(DLT_RETURN_OK, dlt_buffer_init_dynamic(&init_dynamic, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&init_dynamic)); /* Min Values for a success init */ EXPECT_LE(DLT_RETURN_OK, dlt_buffer_init_dynamic(&init_dynamic, 12, 12, 12)); EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&init_dynamic)); } TEST(t_dlt_buffer_init_dynamic, abnormal) { /* DltBuffer buf; */ /* Initialze buffer twice, expected -1 for second init */ /* EXPECT_LE(DLT_RETURN_OK, dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); */ /* EXPECT_GE(-1, dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); */ /* EXPECT_LE(DLT_RETURN_OK,dlt_buffer_free_dynamic(&buf)); */ /* Initialize buffer with max-value of uint32, expected 0 */ /* TODO: what should the maximum parameter values be? UINT_MAX is too large and leads to segfault */ /* EXPECT_LE(DLT_RETURN_OK, dlt_buffer_init_dynamic(&buf, UINT_MAX,UINT_MAX,UINT_MAX)); */ /* EXPECT_LE(DLT_RETURN_OK,dlt_buffer_free_dynamic(&buf)); */ /* Initialize buffer with min-value of uint32, expected 0 */ /* EXPECT_LE(DLT_RETURN_OK, dlt_buffer_init_dynamic(&buf, 0,0,0)); */ /* EXPECT_LE(DLT_RETURN_OK,dlt_buffer_free_dynamic(&buf)); */ /* Initialize buffer min-value > max-value, expected -1 */ /* EXPECT_GE(-1, dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); */ /* EXPECT_LE(DLT_RETURN_OK,dlt_buffer_free_dynamic(&buf)); */ /* Initialsize buffer step-value > max-value, expected -1 */ /* EXPECT_GE(-1,dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE * 2)); */ /* EXPECT_LE(DLT_RETURN_OK,dlt_buffer_free_dynamic(&buf)); */ } TEST(t_dlt_buffer_init_dynamic, nullpointer) { DltBuffer buf; /* NULL-Pointer, expect -1 */ EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_init_dynamic(NULL, 0, 0, 0)); EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_init_dynamic(NULL, 0, 0, DLT_USER_RINGBUFFER_STEP_SIZE)); EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_init_dynamic(NULL, 0, DLT_USER_RINGBUFFER_MAX_SIZE, 0)); EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_init_dynamic(NULL, 0, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_init_dynamic(NULL, DLT_USER_RINGBUFFER_MIN_SIZE, 0, 0)); EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_init_dynamic(NULL, DLT_USER_RINGBUFFER_MIN_SIZE, 0, DLT_USER_RINGBUFFER_STEP_SIZE)); EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_init_dynamic(NULL, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, 0)); EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_init_dynamic(NULL, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_init_dynamic(&buf, 0, 0, 0)); EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_init_dynamic(&buf, 0, 0, DLT_USER_RINGBUFFER_STEP_SIZE)); EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_init_dynamic(&buf, 0, DLT_USER_RINGBUFFER_MAX_SIZE, 0)); EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_init_dynamic(&buf, 0, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, 0, 0)); EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, 0, DLT_USER_RINGBUFFER_STEP_SIZE)); EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, 0)); } /* End Method: dlt_common::dlt_buffer_init_dynamic */ /* Begin Method: dlt_common::dlt_buffer_free_dynamic */ TEST(t_dlt_buffer_free_dynamic, normal) { DltBuffer buf; /* Normal Use-Case szenario */ EXPECT_LE(DLT_RETURN_OK, dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); /* Normal Use-Case szenario */ EXPECT_LE(DLT_RETURN_OK, dlt_buffer_init_dynamic(&buf, 12, 12, 12)); EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); } TEST(t_dlt_buffer_free_dynamic, abnormal) { /* DltBuffer buf; */ /* Free uninizialised buffer, expected -1 */ /* EXPECT_GE(-1, dlt_buffer_free_dynamic(&buf)); */ /* Free buffer twice, expected -1 */ /* EXPECT_LE(DLT_RETURN_OK, dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); */ /* EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); */ /* EXPECT_GE(-1, dlt_buffer_free_dynamic(&buf)); */ } TEST(t_dlt_buffer_free_dynamic, nullpointer) { /* NULL-POinter */ EXPECT_GE(-1, dlt_buffer_free_dynamic(NULL)); } /* End Method: dlt_common::dlt_buffer_free_dynamic */ /* Begin Method: dlt_common::dlt_buffer_increase_size */ TEST(t_dlt_buffer_increase_size, normal) { DltBuffer buf; /* Normal Use-Case, expected 0 */ EXPECT_LE(DLT_RETURN_OK, dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); EXPECT_LE(0, dlt_buffer_increase_size(&buf)); EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); /* Fill buffer to max-value, expected 0 */ EXPECT_LE(DLT_RETURN_OK, dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); for (int i = 0; i <= (DLT_USER_RINGBUFFER_MAX_SIZE / DLT_USER_RINGBUFFER_MIN_SIZE); i += DLT_USER_RINGBUFFER_STEP_SIZE) EXPECT_LE(0, dlt_buffer_increase_size(&buf)); EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); } TEST(t_dlt_buffer_increase_size, abnormal) { /* DltBuffer buf; */ /* Increase uninizialised buffer */ /* EXPECT_GE(-1, dlt_buffer_increase_size(&buf)); */ /* Fill buffer over max-value, expected -1 */ /* EXPECT_LE(DLT_RETURN_OK, dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); */ /* EXPECT_GE(-1, dlt_buffer_increase_size(&buf)); */ /* EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); */ /* min-value > max-value, trying to increase buffer, expected -1 */ /* EXPECT_LE(DLT_RETURN_OK, dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); */ /* EXPECT_GE(-1, dlt_buffer_increase_size(&buf)); */ /* EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); */ /* trying to increase buffer with 0 , expected -1 */ /* EXPECT_LE(DLT_RETURN_OK, dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, 0)); */ /* EXPECT_GE(-1, dlt_buffer_increase_size(&buf)); */ /* EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); */ } TEST(t_dlt_buffer_increase_size, nullpointer) { /* NULL-Pointer, expected -1 */ EXPECT_GE(-1, dlt_buffer_increase_size(NULL)); } /* End Method: dlt_common::dlt_buffer_increase_size */ /* Begin Method: dlt_common::dlt_buffer_minimize_size */ TEST(t_dlt_buffer_minimize_size, normal) { DltBuffer buf; /* Normal Use-Case, expected 0 */ EXPECT_LE(DLT_RETURN_OK, dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); EXPECT_LE(0, dlt_buffer_minimize_size(&buf)); EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); /* minimize buffer to min-value, expected 0 */ EXPECT_LE(DLT_RETURN_OK, dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); for (int i = (DLT_USER_RINGBUFFER_MAX_SIZE / DLT_USER_RINGBUFFER_MIN_SIZE); i >= 0; i -= DLT_USER_RINGBUFFER_STEP_SIZE) EXPECT_LE(0, dlt_buffer_minimize_size(&buf)); EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); } TEST(t_dlt_buffer_minimize_size, abnormal) { /* DltBuffer buf; */ /* Minimize uninizialised buffer */ /* EXPECT_GE(-1, dlt_buffer_minimize_size(&buf)); */ /* minimize buffer under min-value, expected -1 */ /* EXPECT_LE(DLT_RETURN_OK, dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); */ /* EXPECT_GE(-1, dlt_buffer_minimize_size(&buf)); */ /* EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); */ /* min-value > max-value, trying to minimize buffer, expected -1 */ /* EXPECT_LE(DLT_RETURN_OK, dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); */ /* EXPECT_GE(-1, dlt_buffer_minimize_size(&buf)); */ /* EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); */ /* trying to minimize buffer with 0 , expected -1 */ /* EXPECT_LE(DLT_RETURN_OK, dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, 0)); */ /* EXPECT_GE(-1, dlt_buffer_minimize_size(&buf)); */ /* EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); */ } TEST(t_dlt_buffer_minimize_size, nullpointer) { /* NULL-Pointer, expected -1 */ EXPECT_GE(-1, dlt_buffer_minimize_size(NULL)); } /* End Method: dlt_common::dlt_buffer_minimize_size */ /* Begin Method: dlt_common::dlt_buffer_reset */ TEST(t_dlt_buffer_reset, normal) { DltBuffer buf; /* Normal Use-Case. expect 0 */ EXPECT_LE(DLT_RETURN_OK, dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); EXPECT_LE(0, dlt_buffer_reset(&buf)); } TEST(t_dlt_buffer_reset, abnormal) { /* DltBuffer buf; */ /*Use uninizialsied buffer, expected -1 */ /* EXPECT_GE(-1, dlt_buffer_reset(&buf)); */ } TEST(t_dlt_buffer_reset, nullpointer) { /*Use NULL-Pointer, expected -1 */ EXPECT_GE(-1, dlt_buffer_reset(NULL)); } /* End Method: dlt_common::dlt_buffer_reset */ /* Begin Method: dlt_common::dlt_buffer_push*/ TEST(t_dlt_buffer_push, normal) { DltBuffer buf; char *test; unsigned int size = sizeof(test); /* Normal Use-Case, expected 0 */ EXPECT_LE(DLT_RETURN_OK, dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); EXPECT_LE(DLT_RETURN_OK, dlt_buffer_push(&buf, (unsigned char *)&test, size)); EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); /* Push till buffer is full, expected 0 */ EXPECT_LE(DLT_RETURN_OK, dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); for (unsigned int i = 0; i <= (DLT_USER_RINGBUFFER_MIN_SIZE / size); i++) EXPECT_LE(DLT_RETURN_OK, dlt_buffer_push(&buf, (unsigned char *)&test, size)); EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); } TEST(t_dlt_buffer_push, abnormal) { /* DltBuffer buf; */ /* char * test; */ /* int size = sizeof(test); */ /* Use uninizialsied, expected -1 */ /* EXPECT_GE(-1, dlt_buffer_push(&buf,(unsigned char *)&test,size)); */ /* set size == 0, expected -1 */ /* EXPECT_LE(DLT_RETURN_OK, dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push(&buf,(unsigned char *)&test,0)); */ /* EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); */ /* set size == 0 and char == 0 expected -1 */ /* EXPECT_LE(DLT_RETURN_OK, dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push(&buf,0,0)); */ /* EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); */ /* Push till buffer is overfilled , expected -1 */ /* EXPECT_LE(DLT_RETURN_OK, dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); */ /* for(int i=0; i<= (DLT_USER_RINGBUFFER_MIN_SIZE/size) + size; i++) */ /* { */ /* if(i <= DLT_USER_RINGBUFFER_MIN_SIZE) */ /* EXPECT_LE(DLT_RETURN_OK, dlt_buffer_push(&buf,(unsigned char *)&test,size)); */ /* else */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push(&buf,(unsigned char *)&test,size)); */ /* } */ /* EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); */ /* All use-case, wich works with null pointer, has to discuss */ /* EXPECT_LE(DLT_RETURN_OK, dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push(&buf,NULL,0)); */ /* EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); */ /* EXPECT_LE(DLT_RETURN_OK, dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push(&buf,NULL,size)); */ /* EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); */ } TEST(t_dlt_buffer_push, nullpointer) { char *test; int size = sizeof(test); /* NULL-Pointer, expected -1 */ EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push(NULL, NULL, 0)); EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push(NULL, NULL, size)); EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push(NULL, (unsigned char *)&test, 0)); EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push(NULL, (unsigned char *)&test, size)); } /* End Method: dlt_common::dlt_buffer_push*/ /* Begin Method: dlt_common::dlt_buffer_push3 */ TEST(t_dlt_buffer_push3, normal) { DltBuffer buf; char *test; int size = sizeof(test); /* Normal Use-Case, expected 0 */ EXPECT_LE(DLT_RETURN_OK, dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); EXPECT_LE(DLT_RETURN_OK, dlt_buffer_push3(&buf, (unsigned char *)&test, size, 0, 0, 0, 0)); EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); EXPECT_LE(DLT_RETURN_OK, dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); EXPECT_LE(DLT_RETURN_OK, dlt_buffer_push3(&buf, (unsigned char *)&test, size, (unsigned char *)&test, size, (unsigned char *)&test, size)); EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); /* Push till buffer is full, expected 0 */ EXPECT_LE(DLT_RETURN_OK, dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); for (int i = 0; i <= (DLT_USER_RINGBUFFER_MIN_SIZE / size); i++) EXPECT_LE(DLT_RETURN_OK, dlt_buffer_push3(&buf, (unsigned char *)&test, size, (unsigned char *)&test, size, (unsigned char *)&test, size)); EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); } TEST(t_dlt_buffer_push3, abnormal) { /* DltBuffer buf; */ /* char * test; */ /* int size = sizeof(test); */ /* Use uninizialsied, expected -1 */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(&buf,(unsigned char *)&test,size,(unsigned char *)&test,size,(unsigned char *)&test,size)); */ /* set size == 0, expected -1 */ /* EXPECT_LE(DLT_RETURN_OK, dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(&buf,(unsigned char *)&test,0, (unsigned char *)&test,0, (unsigned char *)&test,0)); */ /* EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); */ /* set size == 0 and char == 0 expected -1 */ /* EXPECT_LE(DLT_RETURN_OK, dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(&buf,0,0,0,0,0,0)); */ /* EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); */ /* works with null pointer, expected -1 */ /* EXPECT_LE(DLT_RETURN_OK, dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(&buf,NULL,0,NULL,0,NULL,0)); */ /* EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); */ /* Push till buffer is overfilled , expected -1 */ /* EXPECT_LE(DLT_RETURN_OK, dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); */ /* for(int i=0; i<= (DLT_USER_RINGBUFFER_MIN_SIZE/size) + size; i++) */ /* { */ /* if(i <= DLT_USER_RINGBUFFER_MIN_SIZE) */ /* EXPECT_LE(DLT_RETURN_OK, dlt_buffer_push3(&buf,(unsigned char *)&test,size,(unsigned char *)&test,size,(unsigned char *)&test,size)); */ /* else */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(&buf,(unsigned char *)&test,size,(unsigned char *)&test,size,(unsigned char *)&test,size)); */ /* } */ /* EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); */ /* All use-case, wich works with null pointer, has to discuss */ /* EXPECT_LE(DLT_RETURN_OK, dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(&buf,NULL,0,NULL,0,NULL,size)); */ /* EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); */ /* EXPECT_LE(DLT_RETURN_OK, dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(&buf,NULL,0,NULL,0,(unsigned char *)&test,0)); */ /* EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); */ /* EXPECT_LE(DLT_RETURN_OK, dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(&buf,NULL,0,NULL,0,(unsigned char *)&test,size)); */ /* EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); */ /* EXPECT_LE(DLT_RETURN_OK, dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(&buf,NULL,0,NULL,size,NULL,0)); */ /* EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); */ /* EXPECT_LE(DLT_RETURN_OK, dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(&buf,NULL,0,NULL,size,NULL,size)); */ /* EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); */ /* EXPECT_LE(DLT_RETURN_OK, dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(&buf,NULL,0,NULL,size,(unsigned char *)&test,0)); */ /* EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); */ /* EXPECT_LE(DLT_RETURN_OK, dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(&buf,NULL,0,NULL,size,(unsigned char *)&test,size)); */ /* EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); */ /* EXPECT_LE(DLT_RETURN_OK, dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(&buf,NULL,0,(unsigned char *)&test,0,NULL,0)); */ /* EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); */ /* EXPECT_LE(DLT_RETURN_OK,dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(&buf,NULL,0,(unsigned char *)&test,0,NULL,size)); */ /* EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); */ /* EXPECT_LE(DLT_RETURN_OK,dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(&buf,NULL,0,(unsigned char *)&test,0,(unsigned char *)&test,0)); */ /* EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); */ /* EXPECT_LE(DLT_RETURN_OK,dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(&buf,NULL,0,(unsigned char *)&test,0,(unsigned char *)&test,size)); */ /* EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); */ /* EXPECT_LE(DLT_RETURN_OK,dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(&buf,NULL,0,(unsigned char *)&test,size,NULL,0)); */ /* EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); */ /* EXPECT_LE(DLT_RETURN_OK,dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(&buf,NULL,0,(unsigned char *)&test,size,NULL,size)); */ /* EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); */ /* EXPECT_LE(DLT_RETURN_OK,dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(&buf,NULL,0,(unsigned char *)&test,size,(unsigned char *)&test,0)); */ /* EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); */ /* EXPECT_LE(DLT_RETURN_OK,dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(&buf,NULL,0,(unsigned char *)&test,size,(unsigned char *)&test,size)); */ /* EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); */ /* EXPECT_LE(DLT_RETURN_OK,dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(&buf,NULL,size,NULL,0,NULL,0)); */ /* EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); */ /* EXPECT_LE(DLT_RETURN_OK,dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(&buf,NULL,size,NULL,0,NULL,size)); */ /* EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); */ /* EXPECT_LE(DLT_RETURN_OK,dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(&buf,NULL,size,NULL,0,(unsigned char *)&test,0)); */ /* EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); */ /* EXPECT_LE(DLT_RETURN_OK,dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(&buf,NULL,size,NULL,0,(unsigned char *)&test,size)); */ /* EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); */ /* EXPECT_LE(DLT_RETURN_OK,dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(&buf,NULL,size,NULL,size,NULL,0)); */ /* EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); */ /* EXPECT_LE(DLT_RETURN_OK,dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(&buf,NULL,size,NULL,size,NULL,size)); */ /* EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); */ /* EXPECT_LE(DLT_RETURN_OK,dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(&buf,NULL,size,NULL,size,(unsigned char *)&test,0)); */ /* EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); */ /* EXPECT_LE(DLT_RETURN_OK,dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(&buf,NULL,size,NULL,size,(unsigned char *)&test,size)); */ /* EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); */ /* EXPECT_LE(DLT_RETURN_OK,dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(&buf,NULL,size,(unsigned char *)&test,0,NULL,0)); */ /* EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); */ /* EXPECT_LE(DLT_RETURN_OK,dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(&buf,NULL,size,(unsigned char *)&test,0,NULL,size)); */ /* EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); */ /* EXPECT_LE(DLT_RETURN_OK,dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(&buf,NULL,size,(unsigned char *)&test,0,(unsigned char *)&test,0)); */ /* EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); */ /* EXPECT_LE(DLT_RETURN_OK,dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(&buf,NULL,size,(unsigned char *)&test,0,(unsigned char *)&test,size)); */ /* EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); */ /* EXPECT_LE(DLT_RETURN_OK,dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(&buf,NULL,size,(unsigned char *)&test,size,NULL,0)); */ /* EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); */ /* EXPECT_LE(DLT_RETURN_OK,dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(&buf,NULL,size,(unsigned char *)&test,size,NULL,size)); */ /* EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); */ /* EXPECT_LE(DLT_RETURN_OK,dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(&buf,NULL,size,(unsigned char *)&test,size,(unsigned char *)&test,0)); */ /* EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); */ /* EXPECT_LE(DLT_RETURN_OK,dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(&buf,NULL,size,(unsigned char *)&test,size,(unsigned char *)&test,size)); */ /* EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); */ /* EXPECT_LE(DLT_RETURN_OK,dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(&buf,(unsigned char *)&test,0,NULL,0,NULL,0)); */ /* EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); */ /* EXPECT_LE(DLT_RETURN_OK,dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(&buf,(unsigned char *)&test,0,NULL,0,NULL,size)); */ /* EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); */ /* EXPECT_LE(DLT_RETURN_OK,dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(&buf,(unsigned char *)&test,0,NULL,0,(unsigned char *)&test,0)); */ /* EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); */ /* EXPECT_LE(DLT_RETURN_OK,dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(&buf,(unsigned char *)&test,0,NULL,0,(unsigned char *)&test,size)); */ /* EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); */ /* EXPECT_LE(DLT_RETURN_OK,dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(&buf,(unsigned char *)&test,0,NULL,size,NULL,0)); */ /* EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); */ /* EXPECT_LE(DLT_RETURN_OK,dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(&buf,(unsigned char *)&test,0,NULL,size,NULL,size)); */ /* EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); */ /* EXPECT_LE(DLT_RETURN_OK,dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(&buf,(unsigned char *)&test,0,NULL,size,(unsigned char *)&test,0)); */ /* EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); */ /* EXPECT_LE(DLT_RETURN_OK,dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(&buf,(unsigned char *)&test,0,NULL,size,(unsigned char *)&test,size)); */ /* EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); */ /* EXPECT_LE(DLT_RETURN_OK,dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(&buf,(unsigned char *)&test,0,(unsigned char *)&test,0,NULL,0)); */ /* EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); */ /* EXPECT_LE(DLT_RETURN_OK,dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(&buf,(unsigned char *)&test,0,(unsigned char *)&test,0,NULL,size)); */ /* EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); */ /* EXPECT_LE(DLT_RETURN_OK,dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(&buf,(unsigned char *)&test,0,(unsigned char *)&test,size,NULL,0)); */ /* EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); */ /* EXPECT_LE(DLT_RETURN_OK,dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(&buf,(unsigned char *)&test,0,(unsigned char *)&test,size,NULL,size)); */ /* EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); */ /* EXPECT_LE(DLT_RETURN_OK,dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(&buf,(unsigned char *)&test,size,NULL,0,NULL,0)); */ /* EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); */ /* EXPECT_LE(DLT_RETURN_OK,dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(&buf,(unsigned char *)&test,size,NULL,0,NULL,size)); */ /* EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); */ /* EXPECT_LE(DLT_RETURN_OK,dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(&buf,(unsigned char *)&test,size,NULL,0,(unsigned char *)&test,0)); */ /* EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); */ /* EXPECT_LE(DLT_RETURN_OK,dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(&buf,(unsigned char *)&test,size,NULL,0,(unsigned char *)&test,size)); */ /* EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); */ /* EXPECT_LE(DLT_RETURN_OK,dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(&buf,(unsigned char *)&test,size,NULL,size,NULL,0)); */ /* EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); */ /* EXPECT_LE(DLT_RETURN_OK,dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(&buf,(unsigned char *)&test,size,NULL,size,NULL,size)); */ /* EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); */ /* EXPECT_LE(DLT_RETURN_OK,dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(&buf,(unsigned char *)&test,size,NULL,size,(unsigned char *)&test,0)); */ /* EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); */ /* EXPECT_LE(DLT_RETURN_OK,dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(&buf,(unsigned char *)&test,size,NULL,size,(unsigned char *)&test,size)); */ /* EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); */ /* EXPECT_LE(DLT_RETURN_OK,dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(&buf,(unsigned char *)&test,size,(unsigned char *)&test,0,NULL,0)); */ /* EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); */ /* EXPECT_LE(DLT_RETURN_OK,dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(&buf,(unsigned char *)&test,size,(unsigned char *)&test,0,NULL,size)); */ /* EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); */ /* EXPECT_LE(DLT_RETURN_OK,dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(&buf,(unsigned char *)&test,size,(unsigned char *)&test,size,NULL,0)); */ /* EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); */ /* EXPECT_LE(DLT_RETURN_OK,dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(&buf,(unsigned char *)&test,size,(unsigned char *)&test,size,NULL,size)); */ /* EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); */ } TEST(t_dlt_buffer_push3, nullpointer) { char *test; int size = sizeof(test); /*Null Pointer, expected -1 */ EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(NULL, NULL, 0, NULL, 0, NULL, 0)); EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(NULL, NULL, 0, NULL, 0, NULL, size)); EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(NULL, NULL, 0, NULL, 0, (unsigned char *)&test, 0)); EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(NULL, NULL, 0, NULL, 0, (unsigned char *)&test, size)); EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(NULL, NULL, 0, NULL, size, NULL, 0)); EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(NULL, NULL, 0, NULL, size, NULL, size)); EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(NULL, NULL, 0, NULL, size, (unsigned char *)&test, 0)); EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(NULL, NULL, 0, NULL, size, (unsigned char *)&test, size)); EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(NULL, NULL, 0, (unsigned char *)&test, 0, NULL, 0)); EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(NULL, NULL, 0, (unsigned char *)&test, 0, NULL, size)); EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(NULL, NULL, 0, (unsigned char *)&test, 0, (unsigned char *)&test, 0)); EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(NULL, NULL, 0, (unsigned char *)&test, 0, (unsigned char *)&test, size)); EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(NULL, NULL, 0, (unsigned char *)&test, size, NULL, 0)); EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(NULL, NULL, 0, (unsigned char *)&test, size, NULL, size)); EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(NULL, NULL, 0, (unsigned char *)&test, size, (unsigned char *)&test, 0)); EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(NULL, NULL, 0, (unsigned char *)&test, size, (unsigned char *)&test, size)); EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(NULL, NULL, size, NULL, 0, NULL, 0)); EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(NULL, NULL, size, NULL, 0, NULL, size)); EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(NULL, NULL, size, NULL, 0, (unsigned char *)&test, 0)); EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(NULL, NULL, size, NULL, 0, (unsigned char *)&test, size)); EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(NULL, NULL, size, NULL, size, NULL, 0)); EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(NULL, NULL, size, NULL, size, NULL, size)); EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(NULL, NULL, size, NULL, size, (unsigned char *)&test, 0)); EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(NULL, NULL, size, NULL, size, (unsigned char *)&test, size)); EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(NULL, NULL, size, (unsigned char *)&test, 0, NULL, 0)); EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(NULL, NULL, size, (unsigned char *)&test, 0, NULL, size)); EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(NULL, NULL, size, (unsigned char *)&test, 0, (unsigned char *)&test, 0)); EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(NULL, NULL, size, (unsigned char *)&test, 0, (unsigned char *)&test, size)); EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(NULL, NULL, size, (unsigned char *)&test, size, NULL, 0)); EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(NULL, NULL, size, (unsigned char *)&test, size, NULL, size)); EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(NULL, NULL, size, (unsigned char *)&test, size, (unsigned char *)&test, 0)); EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(NULL, NULL, size, (unsigned char *)&test, size, (unsigned char *)&test, size)); EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(NULL, (unsigned char *)&test, 0, NULL, 0, NULL, 0)); EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(NULL, (unsigned char *)&test, 0, NULL, 0, NULL, size)); EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(NULL, (unsigned char *)&test, 0, NULL, 0, (unsigned char *)&test, 0)); EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(NULL, (unsigned char *)&test, 0, NULL, 0, (unsigned char *)&test, size)); EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(NULL, (unsigned char *)&test, 0, NULL, size, NULL, 0)); EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(NULL, (unsigned char *)&test, 0, NULL, size, NULL, size)); EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(NULL, (unsigned char *)&test, 0, NULL, size, (unsigned char *)&test, 0)); EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(NULL, (unsigned char *)&test, 0, NULL, size, (unsigned char *)&test, size)); EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(NULL, (unsigned char *)&test, 0, (unsigned char *)&test, 0, NULL, 0)); EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(NULL, (unsigned char *)&test, 0, (unsigned char *)&test, 0, NULL, size)); EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(NULL, (unsigned char *)&test, 0, (unsigned char *)&test, 0, (unsigned char *)&test, 0)); EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(NULL, (unsigned char *)&test, 0, (unsigned char *)&test, 0, (unsigned char *)&test, size)); EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(NULL, (unsigned char *)&test, 0, (unsigned char *)&test, size, NULL, 0)); EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(NULL, (unsigned char *)&test, 0, (unsigned char *)&test, size, NULL, size)); EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(NULL, (unsigned char *)&test, 0, (unsigned char *)&test, size, (unsigned char *)&test, 0)); EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(NULL, (unsigned char *)&test, 0, (unsigned char *)&test, size, (unsigned char *)&test, size)); EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(NULL, (unsigned char *)&test, size, NULL, 0, NULL, 0)); EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(NULL, (unsigned char *)&test, size, NULL, 0, NULL, size)); EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(NULL, (unsigned char *)&test, size, NULL, 0, (unsigned char *)&test, 0)); EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(NULL, (unsigned char *)&test, size, NULL, 0, (unsigned char *)&test, size)); EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(NULL, (unsigned char *)&test, size, NULL, size, NULL, 0)); EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(NULL, (unsigned char *)&test, size, NULL, size, NULL, size)); EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(NULL, (unsigned char *)&test, size, NULL, size, (unsigned char *)&test, 0)); EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(NULL, (unsigned char *)&test, size, NULL, size, (unsigned char *)&test, size)); EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(NULL, (unsigned char *)&test, size, (unsigned char *)&test, 0, NULL, 0)); EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(NULL, (unsigned char *)&test, size, (unsigned char *)&test, 0, NULL, size)); EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(NULL, (unsigned char *)&test, size, (unsigned char *)&test, 0, (unsigned char *)&test, 0)); EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(NULL, (unsigned char *)&test, size, (unsigned char *)&test, 0, (unsigned char *)&test, size)); EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(NULL, (unsigned char *)&test, size, (unsigned char *)&test, size, NULL, 0)); EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(NULL, (unsigned char *)&test, size, (unsigned char *)&test, size, NULL, size)); EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(NULL, (unsigned char *)&test, size, (unsigned char *)&test, size, (unsigned char *)&test, 0)); EXPECT_GE(DLT_RETURN_ERROR, dlt_buffer_push3(NULL, (unsigned char *)&test, size, (unsigned char *)&test, size, (unsigned char *)&test, size)); } /* End Method: dlt_common::dlt_buffer_push3 */ /* Begin Method: dlt_common::dlt_buffer_pull */ TEST(t_dlt_buffer_pull, normal) { /*Normal Use Cases, expected 0 or -1 in return */ DltBuffer buf; DltUserHeader header; int size = sizeof(DltUserHeader); /* Normal Use-Case, empty pull, expected -1 */ EXPECT_LE(DLT_RETURN_OK, dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); EXPECT_GE(-1, dlt_buffer_pull(&buf, (unsigned char *)&header, size)); EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); /* Normal Use-Case, expected > 0 */ EXPECT_LE(DLT_RETURN_OK, dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); EXPECT_LE(DLT_RETURN_OK, dlt_buffer_push(&buf, (unsigned char *)&header, sizeof(DltUserHeader))); EXPECT_LE(1, dlt_buffer_pull(&buf, (unsigned char *)&header, size)); EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); } TEST(t_dlt_buffer_pull, abnormal) { /* DltBuffer buf; */ /* DltUserHeader header; */ /* Uninizialised, expected -1 */ /* EXPECT_GE(-1, dlt_buffer_pull(&buf, (unsigned char*)&header, sizeof(DltUserHeader))); */ /* data == 0 and max_size == 0, expected -1 */ /* EXPECT_LE(DLT_RETURN_OK, dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); */ /* EXPECT_LE(DLT_RETURN_OK, dlt_buffer_push(&buf,(unsigned char *)&header,sizeof(DltUserHeader))); */ /* EXPECT_GE(-1, dlt_buffer_pull(&buf, 0, 0)); */ /* EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); */ /* no push before pull, expected -1 */ /* EXPECT_LE(DLT_RETURN_OK, dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); */ /* EXPECT_GE(-1, dlt_buffer_pull(&buf, 0, 0)); */ /* EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); */ } TEST(t_dlt_buffer_pull, nullpointer) { DltBuffer buf; DltUserHeader header; /* NULL-Point, expected -1 */ EXPECT_GE(-1, dlt_buffer_pull(NULL, NULL, 0)); EXPECT_GE(-1, dlt_buffer_pull(NULL, NULL, sizeof(DltUserHeader))); EXPECT_GE(-1, dlt_buffer_pull(NULL, (unsigned char *)&header, 0)); EXPECT_GE(-1, dlt_buffer_pull(NULL, (unsigned char *)&header, sizeof(DltUserHeader))); EXPECT_LE(DLT_RETURN_OK, dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); EXPECT_GE(-1, dlt_buffer_pull(&buf, NULL, 0)); EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); EXPECT_LE(DLT_RETURN_OK, dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); EXPECT_GE(-1, dlt_buffer_pull(&buf, NULL, sizeof(DltUserHeader))); EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); } /* End Method: dlt_common::dlt_buffer_pull */ /* Begin Method: dlt_common::dlt_buffer_remove */ TEST(t_dlt_buffer_remove, normal) { DltBuffer buf; DltUserHeader header; int size = sizeof(DltUserHeader); /* Normal Use-Case, empty pull, expected -1 */ EXPECT_LE(DLT_RETURN_OK, dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); EXPECT_GE(-1, dlt_buffer_remove(&buf)); EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); /* Normal Use-Case, expected > 0 */ EXPECT_LE(DLT_RETURN_OK, dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); EXPECT_LE(DLT_RETURN_OK, dlt_buffer_push(&buf, (unsigned char *)&header, size)); EXPECT_LE(0, dlt_buffer_remove(&buf)); EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); } TEST(t_dlt_buffer_remove, abnormal) { /* DltBuffer buf; */ /* DltUserHeader header; */ /* int size = sizeof(DltUserHeader); */ /* Uninizialised, expected -1 */ /* EXPECT_GE(-1, dlt_buffer_remove(&buf)); */ /* no push before remove, expected -1 */ /* EXPECT_LE(DLT_RETURN_OK, dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); */ /* EXPECT_GE(-1, dlt_buffer_remove(&buf)); */ /* EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); */ /* Call remove 10 time, expected > 1 till buffer is empty */ /* pushed one time so expect one > 1 and 9 times < 0 */ /* EXPECT_LE(DLT_RETURN_OK, dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); */ /* EXPECT_LE(DLT_RETURN_OK, dlt_buffer_push(&buf,(unsigned char *)&header,size)); */ /* for(int i=0; i<10;i++) */ /* { */ /* if(i == 0) */ /* EXPECT_LE(1, dlt_buffer_remove(&buf)); */ /* else */ /* EXPECT_GE(-1, dlt_buffer_remove(&buf)); */ /* } */ /* EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); */ } TEST(t_dlt_buffer_remove, nullpointer) { /* NULL_Pointer, expected -1 */ EXPECT_GE(-1, dlt_buffer_remove(NULL)); } /* End Method: dlt_common::dlt_buffer_remove*/ /* Begin Method: dlt_common::dlt_buffer_copy */ TEST(t_dlt_buffer_copy, normal) { DltBuffer buf; DltUserHeader header; int size = sizeof(DltUserHeader); /* Normal Use-Case, empty pull, expected -1 */ EXPECT_LE(DLT_RETURN_OK, dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); EXPECT_GE(-1, dlt_buffer_copy(&buf, (unsigned char *)&header, size)); EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); /* Normal Use-Case, expected > 0 */ EXPECT_LE(DLT_RETURN_OK, dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); EXPECT_LE(DLT_RETURN_OK, dlt_buffer_push(&buf, (unsigned char *)&header, sizeof(DltUserHeader))); EXPECT_LE(1, dlt_buffer_copy(&buf, (unsigned char *)&header, size)); EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); } TEST(t_dlt_buffer_copy, abnormal) { /* DltBuffer buf; */ /* DltUserHeader header; */ /* int size = sizeof(DltUserHeader); */ /* Uninizialised buffer , expected -1 */ /* EXPECT_LE(-1, dlt_buffer_copy(&buf, (unsigned char *)&header, size)); */ /* no push before copy, expected -1 */ /* EXPECT_LE(DLT_RETURN_OK, dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); */ /* EXPECT_LE(-1, dlt_buffer_copy(&buf, (unsigned char *)&header, size)); */ /* EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); */ } TEST(t_dlt_buffer_copy, nullpointer) { DltBuffer buf; DltUserHeader header; int size = sizeof(DltUserHeader); /* NULL-Pointer, expected -1 */ EXPECT_LE(DLT_RETURN_WRONG_PARAMETER, dlt_buffer_copy(NULL, NULL, size)); EXPECT_LE(DLT_RETURN_WRONG_PARAMETER, dlt_buffer_copy(NULL, NULL, 0)); EXPECT_LE(DLT_RETURN_WRONG_PARAMETER, dlt_buffer_copy(NULL, (unsigned char *)&header, size)); EXPECT_LE(DLT_RETURN_WRONG_PARAMETER, dlt_buffer_copy(NULL, (unsigned char *)&header, 0)); EXPECT_LE(DLT_RETURN_OK, dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); EXPECT_LE(DLT_RETURN_WRONG_PARAMETER, dlt_buffer_copy(&buf, NULL, size)); EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); EXPECT_LE(DLT_RETURN_OK, dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); EXPECT_LE(DLT_RETURN_WRONG_PARAMETER, dlt_buffer_copy(&buf, NULL, 0)); EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); } /* End Method: dlt_common::dlt_buffer_copy */ /* Begin Method: dlt_common::dlt_buffer_get */ TEST(t_dlt_buffer_get, normal) { DltBuffer buf; DltUserHeader header; int size = sizeof(DltUserHeader); /* Normal Use-Case */ EXPECT_LE(DLT_RETURN_OK, dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); EXPECT_LE(DLT_RETURN_OK, dlt_buffer_push(&buf, (unsigned char *)&header, size)); printf("#### %i\n", dlt_buffer_get(&buf, (unsigned char *)&header, size, 0)); EXPECT_LE(0, dlt_buffer_get(&buf, (unsigned char *)&header, size, 0)); EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); EXPECT_LE(DLT_RETURN_OK, dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); EXPECT_LE(DLT_RETURN_OK, dlt_buffer_push(&buf, (unsigned char *)&header, size)); printf("#### %i\n", dlt_buffer_get(&buf, (unsigned char *)&header, size, 0)); EXPECT_LE(0, dlt_buffer_get(&buf, (unsigned char *)&header, size, 1)); EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); EXPECT_LE(DLT_RETURN_OK, dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); printf("#### %i\n", dlt_buffer_get(&buf, (unsigned char *)&header, size, 0)); EXPECT_GE(-1, dlt_buffer_get(&buf, (unsigned char *)&header, size, 1)); EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); EXPECT_LE(DLT_RETURN_OK, dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); printf("#### %i\n", dlt_buffer_get(&buf, (unsigned char *)&header, size, 0)); ((int *)(buf.shm))[0] = 50000; EXPECT_GE(-1, dlt_buffer_get(&buf, (unsigned char *)&header, size, 1)); EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); EXPECT_LE(DLT_RETURN_OK, dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); printf("#### %i\n", dlt_buffer_get(&buf, (unsigned char *)&header, size, 0)); ((int *)(buf.shm))[1] = 50000; EXPECT_GE(-1, dlt_buffer_get(&buf, (unsigned char *)&header, size, 1)); EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); EXPECT_LE(DLT_RETURN_OK, dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); printf("#### %i\n", dlt_buffer_get(&buf, (unsigned char *)&header, size, 0)); ((int *)(buf.shm))[2] = -50000; EXPECT_GE(-1, dlt_buffer_get(&buf, (unsigned char *)&header, size, 1)); EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); EXPECT_LE(DLT_RETURN_OK, dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); printf("#### %i\n", dlt_buffer_get(&buf, (unsigned char *)&header, size, 0)); ((int *)(buf.shm))[2] = 0; EXPECT_GE(-1, dlt_buffer_get(&buf, (unsigned char *)&header, size, 1)); EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); EXPECT_LE(DLT_RETURN_OK, dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); printf("#### %i\n", dlt_buffer_get(&buf, (unsigned char *)&header, size, 0)); ((int *)(buf.shm))[0] = 4000; ((int *)(buf.shm))[1] = 5000; ((int *)(buf.shm))[2] = 0; EXPECT_GE(-1, dlt_buffer_get(&buf, (unsigned char *)&header, size, 1)); EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); EXPECT_LE(DLT_RETURN_OK, dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); printf("#### %i\n", dlt_buffer_get(&buf, (unsigned char *)&header, size, 0)); ((int *)(buf.shm))[0] = 10; ((int *)(buf.shm))[1] = 5; ((int *)(buf.shm))[2] = 5; EXPECT_GE(-1, dlt_buffer_get(&buf, (unsigned char *)&header, size, 1)); EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); EXPECT_LE(DLT_RETURN_OK, dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); printf("#### %i\n", dlt_buffer_get(&buf, (unsigned char *)&header, size, 0)); ((int *)(buf.shm))[2] = 50000; EXPECT_GE(-1, dlt_buffer_get(&buf, (unsigned char *)&header, size, 1)); EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); EXPECT_LE(DLT_RETURN_OK, dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); EXPECT_LE(DLT_RETURN_OK, dlt_buffer_push(&buf, (unsigned char *)&header, size)); printf("#### %i\n", dlt_buffer_get(&buf, (unsigned char *)&header, size, 0)); ((int *)(buf.shm))[0] = 19; EXPECT_GE(-1, dlt_buffer_get(&buf, (unsigned char *)&header, size, 1)); EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); EXPECT_LE(DLT_RETURN_OK, dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); EXPECT_LE(DLT_RETURN_OK, dlt_buffer_push(&buf, (unsigned char *)&header, size)); printf("#### %i\n", dlt_buffer_get(&buf, (unsigned char *)&header, size, 0)); ((int *)(buf.shm))[2] = 19; EXPECT_LE(0, dlt_buffer_get(&buf, (unsigned char *)&header, 5, 1)); EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); } TEST(t_dlt_buffer_get, abnormal) { /* DltBuffer buf; */ /* DltUserHeader header; */ /* int size = sizeof(DltUserHeader); */ /* Uninizialsied, expected -1 */ /* EXPECT_GE(-1, dlt_buffer_get(&buf,(unsigned char *)&header,size, 0)); */ /* Integer with 12345678 */ /* EXPECT_LE(DLT_RETURN_OK, dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); */ /* EXPECT_LE(DLT_RETURN_OK, dlt_buffer_push(&buf,(unsigned char *)&header,size)); */ /* printf("#### %i\n", dlt_buffer_get(&buf,(unsigned char*)&header,size,0)); */ /* EXPECT_LE(0, dlt_buffer_get(&buf,(unsigned char*)&header,size,12345678)); */ /* EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); */ } TEST(t_dlt_buffer_get, nullpointer) { DltBuffer buf; DltUserHeader header; int size = sizeof(DltUserHeader); /* NULL-Pointer */ EXPECT_GE(-1, dlt_buffer_get(NULL, NULL, 0, 0)); EXPECT_GE(-1, dlt_buffer_get(NULL, NULL, 0, 1)); EXPECT_GE(-1, dlt_buffer_get(NULL, NULL, size, 0)); EXPECT_GE(-1, dlt_buffer_get(NULL, NULL, size, 1)); EXPECT_GE(-1, dlt_buffer_get(NULL, (unsigned char *)&header, 0, 0)); EXPECT_GE(-1, dlt_buffer_get(NULL, (unsigned char *)&header, 0, 1)); EXPECT_GE(-1, dlt_buffer_get(NULL, (unsigned char *)&header, size, 0)); EXPECT_GE(-1, dlt_buffer_get(NULL, (unsigned char *)&header, size, 1)); EXPECT_LE(DLT_RETURN_OK, dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); EXPECT_GE(-1, dlt_buffer_get(&buf, NULL, 0, 0)); EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); EXPECT_LE(DLT_RETURN_OK, dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); EXPECT_GE(-1, dlt_buffer_get(&buf, NULL, 0, 1)); EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); EXPECT_LE(DLT_RETURN_OK, dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); EXPECT_GE(-1, dlt_buffer_get(&buf, NULL, size, 0)); EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); EXPECT_LE(DLT_RETURN_OK, dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); EXPECT_GE(-1, dlt_buffer_get(&buf, NULL, size, 1)); EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); } /* End Method: dlt_common::dlt_buffer_get */ /* Begin MEthod: dlt_common::dlt_buffer_get_message_count */ TEST(t_dlt_buffer_get_message_count, normal) { DltBuffer buf; DltUserHeader header; /* Normal Usce-Case without pushing data, expected 0 */ EXPECT_LE(DLT_RETURN_OK, dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); /*printf("##### %i\n", dlt_buffer_get_message_count(&buf)); */ EXPECT_LE(0, dlt_buffer_get_message_count(&buf)); EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); /* Normal Use-Case, with pushing data, expected > 0 */ EXPECT_LE(DLT_RETURN_OK, dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); EXPECT_LE(DLT_RETURN_OK, dlt_buffer_push(&buf, (unsigned char *)&header, sizeof(DltUserHeader))); /*printf("#### %i\n", dlt_buffer_get_message_count(&buf)); */ EXPECT_LE(0, dlt_buffer_get_message_count(&buf)); EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); /* Pushing 1000 mesages, expected 10000 */ EXPECT_LE(DLT_RETURN_OK, dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); for (int i = 1; i <= 10000; i++) { EXPECT_LE(DLT_RETURN_OK, dlt_buffer_push(&buf, (unsigned char *)&header, sizeof(DltUserHeader))); /*printf("#### %i\n", dlt_buffer_get_message_count(&buf)); */ EXPECT_LE(i, dlt_buffer_get_message_count(&buf)); } EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); } TEST(t_dlt_buffer_get_message_count, abnormal) { /* DltBuffer buf; */ /* Uninizialised, expected -1 */ /* EXPECT_GE(-1, dlt_buffer_get_message_count(&buf)); */ } TEST(t_dlt_buffer_get_message_count, nullpointer) { /*NULL-Pointer, expected -1 */ /* EXPECT_GE(-1, dlt_buffer_get_message_count(NULL)); */ } /* Begin MEthod: dlt_common::dlt_buffer_get_message_count */ /* Begin Method: dlt_common::dlt_buffer_get_total_size*/ TEST(t_dlt_buffer_get_total_size, normal) { DltBuffer buf; DltUserHeader header; /* Normal Use-Case, expected max buffer size (DLT_USER_RINGBUFFER_MAX_SIZE) */ EXPECT_LE(DLT_RETURN_OK, dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); /*printf("##### %i\n", dlt_buffer_get_total_size(&buf)); */ EXPECT_LE(DLT_USER_RINGBUFFER_MAX_SIZE, dlt_buffer_get_total_size(&buf)); EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); /* Normal Use-Case, 1st pushing data, expected max buffer size (DLT_USER_RINGBUFFER_MAX_SIZE) */ EXPECT_LE(DLT_RETURN_OK, dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); EXPECT_LE(DLT_RETURN_OK, dlt_buffer_push(&buf, (unsigned char *)&header, sizeof(DltUserHeader))); /*printf("##### %i\n", dlt_buffer_get_total_size(&buf)); */ EXPECT_LE(DLT_USER_RINGBUFFER_MAX_SIZE, dlt_buffer_get_total_size(&buf)); EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); } TEST(t_dlt_buffer_get_total_size, abnormal) { /* DltBuffer buf; */ /* Uninizialised, expected -1 */ /* EXPECT_GE(-1, dlt_buffer_get_total_size(&buf)); */ } TEST(t_dlt_buffer_get_total_size, nullpointer) { /* NULL-Pointer, expect -1 */ EXPECT_GE(-1, dlt_buffer_get_total_size(NULL)); } /* End Method: dlt_common::dlt_buffer_get_total_size*/ /* Begin Method: dlt_common::dlt_buffer_get_used_size*/ TEST(t_dlt_buffer_get_used_size, normal) { DltBuffer buf; DltUserHeader header; /* Normal Use Cas buffer empty, expected 0 */ EXPECT_LE(DLT_RETURN_OK, dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); /*printf("##### %i\n", dlt_buffer_get_used_size(&buf)); */ EXPECT_LE(0, dlt_buffer_get_used_size(&buf)); EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); /* Normal Use-Case with pushing data, expected > 0 */ EXPECT_LE(DLT_RETURN_OK, dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); EXPECT_LE(DLT_RETURN_OK, dlt_buffer_push(&buf, (unsigned char *)&header, sizeof(DltUserHeader))); /*printf("##### %i\n", dlt_buffer_get_used_size(&buf)); */ EXPECT_LE(0, dlt_buffer_get_used_size(&buf)); EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); /* Normal Use-Case with pushing 10000 data, expected > 0 */ EXPECT_LE(DLT_RETURN_OK, dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); for (int i = 1; i <= 10000; i++) { EXPECT_LE(DLT_RETURN_OK, dlt_buffer_push(&buf, (unsigned char *)&header, sizeof(DltUserHeader))); /*printf("#### %i\n", dlt_buffer_get_used_size(&buf)); */ EXPECT_LE(1, dlt_buffer_get_used_size(&buf)); } EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); } TEST(t_dlt_buffer_get_used_size, abnormal) { /* DltBuffer buf; */ /* Uninizialised, expected -1 */ /* EXPECT_GE(-1, dlt_buffer_get_used_size(&buf)); */ } TEST(t_dlt_buffer_get_used_size, nullpointer) { /*NULL-Pointer, expcted -1 */ EXPECT_GE(-1, dlt_buffer_get_used_size(NULL)); } /* End Method: dlt_common::dlt_buffer_get_used_size*/ /* Begin Method: dlt_common::dlt_buffer_write_block */ TEST(t_dlt_buffer_write_block, normal) { DltBuffer buf; unsigned char *data = NULL; int write; int size1 = 516; int size2 = 1024; /* Normal Use-Case, void method, expected no error */ EXPECT_LE(DLT_RETURN_OK, dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); EXPECT_NO_THROW(dlt_buffer_write_block(&buf, &write, data, size1)); EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); EXPECT_LE(DLT_RETURN_OK, dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); EXPECT_NO_THROW(dlt_buffer_write_block(&buf, &write, data, size2)); EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); EXPECT_LE(DLT_RETURN_OK, dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); int tmp = 0; for (int i = 0; i <= 10000; i += 10) { tmp += i; EXPECT_NO_THROW(dlt_buffer_write_block(&buf, &write, data, i)); } EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); } TEST(t_dlt_buffer_write_block, abnormal) { /* actual no abnormal test cases */ /* because of void funktion and missing gtest tools for that */ } TEST(t_dlt_buffer_write_block, nullpointer) { DltBuffer buf; char *data; int write; int test1 = 1000; /* NULL-Pointer, expected < 0 */ EXPECT_NO_THROW(dlt_buffer_write_block(NULL, NULL, NULL, 0)); EXPECT_NO_THROW(dlt_buffer_write_block(NULL, NULL, NULL, test1)); EXPECT_NO_THROW(dlt_buffer_write_block(NULL, NULL, (unsigned char *)&data, 0)); EXPECT_NO_THROW(dlt_buffer_write_block(NULL, NULL, (unsigned char *)&data, test1)); EXPECT_NO_THROW(dlt_buffer_write_block(NULL, &write, NULL, 0)); EXPECT_NO_THROW(dlt_buffer_write_block(NULL, &write, NULL, test1)); EXPECT_NO_THROW(dlt_buffer_write_block(NULL, &write, (unsigned char *)&data, 0)); EXPECT_NO_THROW(dlt_buffer_write_block(NULL, &write, (unsigned char *)&data, test1)); EXPECT_LE(DLT_RETURN_OK, dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); EXPECT_NO_THROW(dlt_buffer_write_block(&buf, NULL, NULL, 0)); EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); EXPECT_LE(DLT_RETURN_OK, dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); EXPECT_NO_THROW(dlt_buffer_write_block(&buf, NULL, NULL, test1)); EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); EXPECT_LE(DLT_RETURN_OK, dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); EXPECT_NO_THROW(dlt_buffer_write_block(&buf, NULL, (unsigned char *)&data, 0)); EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); EXPECT_LE(DLT_RETURN_OK, dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); EXPECT_NO_THROW(dlt_buffer_write_block(&buf, NULL, (unsigned char *)&data, test1)); EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); EXPECT_LE(DLT_RETURN_OK, dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); EXPECT_NO_THROW(dlt_buffer_write_block(&buf, &write, NULL, 0)); EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); EXPECT_LE(DLT_RETURN_OK, dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); EXPECT_NO_THROW(dlt_buffer_write_block(&buf, &write, NULL, test1)); EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); } /* End Method: dlt_common::dlt_buffer_write_block */ /* Begin Method: dlt_common::dlt_buffer_read_block */ TEST(t_dlt_buffer_read_block, normal) { DltBuffer buf; unsigned char *data = NULL; int write, read; int size1 = 516; int size2 = 1024; /* Normal Use-Case, void method, expected no error */ EXPECT_LE(DLT_RETURN_OK, dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); EXPECT_NO_THROW(dlt_buffer_write_block(&buf, &write, data, size1)); EXPECT_NO_THROW(dlt_buffer_read_block(&buf, &write, data, size1)); EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); EXPECT_LE(DLT_RETURN_OK, dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); EXPECT_NO_THROW(dlt_buffer_write_block(&buf, &read, data, size2)); EXPECT_NO_THROW(dlt_buffer_read_block(&buf, &write, data, size2)); EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); } TEST(t_dlt_buffer_read_block, abnormal) { /* actual no abnormal test cases */ /* because of void funktion and missing gtest tools for that */ } TEST(t_dlt_buffer_read_block, nullpointer) { DltBuffer buf; char *data; int read = -1; int test1 = 1000; /* NULL-Pointer, expected < 0 */ EXPECT_NO_THROW(dlt_buffer_read_block(NULL, NULL, NULL, 0)); EXPECT_NO_THROW(dlt_buffer_read_block(NULL, NULL, NULL, test1)); EXPECT_NO_THROW(dlt_buffer_read_block(NULL, NULL, (unsigned char *)&data, 0)); EXPECT_NO_THROW(dlt_buffer_read_block(NULL, NULL, (unsigned char *)&data, test1)); EXPECT_NO_THROW(dlt_buffer_read_block(NULL, &read, NULL, 0)); EXPECT_NO_THROW(dlt_buffer_read_block(NULL, &read, NULL, test1)); EXPECT_NO_THROW(dlt_buffer_read_block(NULL, &read, (unsigned char *)&data, 0)); EXPECT_NO_THROW(dlt_buffer_read_block(NULL, &read, (unsigned char *)&data, test1)); EXPECT_LE(DLT_RETURN_OK, dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); EXPECT_NO_THROW(dlt_buffer_read_block(&buf, NULL, NULL, 0)); EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); EXPECT_LE(DLT_RETURN_OK, dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); EXPECT_NO_THROW(dlt_buffer_read_block(&buf, NULL, NULL, test1)); EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); EXPECT_LE(DLT_RETURN_OK, dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); EXPECT_NO_THROW(dlt_buffer_read_block(&buf, NULL, (unsigned char *)&data, 0)); EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); EXPECT_LE(DLT_RETURN_OK, dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); EXPECT_NO_THROW(dlt_buffer_read_block(&buf, NULL, (unsigned char *)&data, test1)); EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); EXPECT_LE(DLT_RETURN_OK, dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); EXPECT_NO_THROW(dlt_buffer_read_block(&buf, &read, NULL, 0)); EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); EXPECT_LE(DLT_RETURN_OK, dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); EXPECT_NO_THROW(dlt_buffer_read_block(&buf, &read, NULL, test1)); EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); EXPECT_LE(DLT_RETURN_OK, dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); EXPECT_NO_THROW(dlt_buffer_read_block(&buf, &read, (unsigned char *)&data, 0)); EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); } /* End Method: dlt_common::dlt_buffer_read_block */ /* Begin Method: dlt_common::dlt_buffer_info */ TEST(t_dlt_buffer_info, normal) { DltBuffer buf; /* Normal Use-Case */ EXPECT_LE(DLT_RETURN_OK, dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); EXPECT_NO_THROW(dlt_buffer_info(&buf)); } TEST(t_dlt_buffer_info, abnormal) { /* actually no abnormal test cases */ /* because of void function and missing gtest tools for that */ } TEST(t_dlt_buffer_info, nullpointer) { /* NULL-Pointer, no throw */ EXPECT_NO_THROW(dlt_buffer_info(NULL)); } /* End Method: dlt_common::dlt_buffer_info */ /* Begin Method: dlt_common::dlt_buffer_status */ TEST(t_dlt_buffer_status, normal) { DltBuffer buf; /* Normal Use-Case */ EXPECT_LE(DLT_RETURN_OK, dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); EXPECT_NO_THROW(dlt_buffer_status(&buf)); } TEST(t_dlt_buffer_status, abnormal) { /* actual no abnormal test cases */ /* because of void funktion and missing gtest tools for that */ } TEST(t_dlt_buffer_status, nullpointer) { /* NULL-Pointer, expected -1 */ EXPECT_NO_THROW(dlt_buffer_status(NULL)); } /* End Method: dlt_common::dlt_buffer_status */ /*##############################################################################################################################*/ /*##############################################################################################################################*/ /*##############################################################################################################################*/ /* Begin Method: dlt_common::dlt_message_init*/ TEST(t_dlt_message_init, normal) { DltMessage msg; /* Normal Use-Case, expected 0 */ EXPECT_LE(DLT_RETURN_OK, dlt_message_init(&msg, 0)); EXPECT_LE(DLT_RETURN_OK, dlt_message_free(&msg, 0)); EXPECT_LE(DLT_RETURN_OK, dlt_message_init(&msg, 1)); EXPECT_LE(DLT_RETURN_OK, dlt_message_free(&msg, 0)); } TEST(t_dlt_message_init, abnormal) { /* DltMessage msg; */ /* Double use init, expected -1 */ /* EXPECT_LE(DLT_RETURN_OK, dlt_message_init(&msg,0)); */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_message_init(&msg,0)); */ /* EXPECT_LE(DLT_RETURN_OK, dlt_message_free(&msg,0)); */ /* EXPECT_LE(DLT_RETURN_OK, dlt_message_init(&msg,1)); */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_message_init(&msg,1)); */ /* EXPECT_LE(DLT_RETURN_OK, dlt_message_free(&msg,1)); */ /* set Verbose to 12345678, expected -1 */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_message_init(&msg,12345678)); */ } TEST(t_dlt_message_init, nullpointer) { /*NULL-Pointer, expected -1 */ EXPECT_GE(DLT_RETURN_ERROR, dlt_message_init(NULL, 0)); EXPECT_GE(DLT_RETURN_ERROR, dlt_message_init(NULL, 1)); } /* End Method: dlt_common::dlt_message_init*/ /* Begin Method: dlt_common::dlt_message_free */ TEST(t_dlt_message_free, normal) { DltMessage msg; /* Normal Use Case, expected 0 */ EXPECT_LE(DLT_RETURN_OK, dlt_message_init(&msg, 0)); EXPECT_LE(DLT_RETURN_OK, dlt_message_free(&msg, 0)); EXPECT_LE(DLT_RETURN_OK, dlt_message_init(&msg, 0)); EXPECT_LE(DLT_RETURN_OK, dlt_message_free(&msg, 1)); } TEST(t_dlt_message_free, abnormal) { /* DltMessage msg; */ /* Double use free, expected -1 */ /* EXPECT_LE(DLT_RETURN_OK, dlt_message_init(&msg,0)); */ /* EXPECT_LE(DLT_RETURN_OK, dlt_message_free(&msg,0)); */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_message_free(&msg,0)); */ /* EXPECT_LE(DLT_RETURN_OK, dlt_message_init(&msg,0)); */ /* EXPECT_LE(DLT_RETURN_OK, dlt_message_free(&msg,1)); */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_message_free(&msg,1)); */ /* set Verbose to 12345678, expected -1 */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_message_free(&msg,12345678)); */ } TEST(t_dlt_message_free, nullpointer) { /*NULL-Pointer, expected -1 */ EXPECT_GE(DLT_RETURN_ERROR, dlt_message_free(NULL, 0)); EXPECT_GE(DLT_RETURN_ERROR, dlt_message_free(NULL, 1)); } /* End Method: dlt_common::dlt_message_free */ /* Begin Method: dlt_common::dlt_file_open */ TEST(t_dlt_file_open, normal) { DltFile file; /* Get PWD so file can be used*/ char pwd[100]; char openfile[114]; /* ignore returned value from getcwd */ if (getcwd(pwd, 100) == NULL) {} sprintf(openfile, "%s/testfile.dlt", pwd); /*---------------------------------------*/ /* Normal Use-Case, expected 0 */ EXPECT_LE(DLT_RETURN_OK, dlt_file_init(&file, 0)); EXPECT_LE(DLT_RETURN_OK, dlt_file_open(&file, openfile, 0)); EXPECT_LE(DLT_RETURN_OK, dlt_file_free(&file, 0)); EXPECT_LE(DLT_RETURN_OK, dlt_file_init(&file, 0)); EXPECT_LE(DLT_RETURN_OK, dlt_file_open(&file, openfile, 1)); EXPECT_LE(DLT_RETURN_OK, dlt_file_free(&file, 0)); } TEST(t_dlt_file_open, abnormal) { /* DltFile file; */ /* / * Get PWD so file can be used* / */ /* char pwd[100]; */ /* getcwd(pwd, 100); */ /* char openfile[114]; */ /* sprintf(openfile, "%s/testfile.dlt", pwd); */ /*---------------------------------------*/ /* Uninizialsied, expected -1 */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_file_open(&file, openfile, 0)); */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_file_open(&file, openfile, 1)); */ /* Verbose set to 12345678 */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_file_open(&file, openfile, 12345678)); */ /* Path doesn't exist, expected -1 */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_file_open(&file, "This Path doesn't exist!!", 0)); */ } TEST(t_dlt_file_open, nullpointer) { DltFile file; /* Get PWD so file can be used*/ char pwd[100]; char openfile[114]; /* ignore returned value from getcwd */ if (getcwd(pwd, 100) == NULL) {} sprintf(openfile, "%s/testfile.dlt", pwd); /*---------------------------------------*/ /* NULL-Pointer, expected -1 */ EXPECT_GE(DLT_RETURN_ERROR, dlt_file_open(NULL, NULL, 0)); EXPECT_GE(DLT_RETURN_ERROR, dlt_file_open(NULL, NULL, 1)); EXPECT_GE(DLT_RETURN_ERROR, dlt_file_open(NULL, openfile, 0)); EXPECT_GE(DLT_RETURN_ERROR, dlt_file_open(NULL, openfile, 1)); EXPECT_GE(DLT_RETURN_ERROR, dlt_file_open(&file, NULL, 0)); EXPECT_GE(DLT_RETURN_ERROR, dlt_file_open(&file, NULL, 1)); } /* End Method: dlt_common::dlt_file_open */ /* Begin Method: dlt_common::dlt_message_print_ascii*/ TEST(t_dlt_message_print_ascii, normal) { DltFile file; static char text[DLT_DAEMON_TEXTSIZE]; /* Get PWD so file can be used*/ char pwd[100]; char openfile[114]; /* ignore returned value from getcwd */ if (getcwd(pwd, 100) == NULL) {} sprintf(openfile, "%s/testfile.dlt", pwd); /*---------------------------------------*/ /* Normal Use-Case, expected 0 */ EXPECT_LE(DLT_RETURN_OK, dlt_file_init(&file, 0)); EXPECT_LE(DLT_RETURN_OK, dlt_file_open(&file, openfile, 0)); while (dlt_file_read(&file, 0) >= 0) {} for (int i = 0; i < file.counter; i++) { EXPECT_LE(DLT_RETURN_OK, dlt_file_message(&file, i, 0)); EXPECT_LE(DLT_RETURN_OK, dlt_message_print_ascii(&file.msg, text, DLT_DAEMON_TEXTSIZE, 0)); } for (int i = 0; i < file.counter; i++) { EXPECT_LE(DLT_RETURN_OK, dlt_file_message(&file, i, 0)); EXPECT_LE(DLT_RETURN_OK, dlt_message_print_ascii(&file.msg, text, DLT_DAEMON_TEXTSIZE, 1)); } EXPECT_LE(DLT_RETURN_OK, dlt_file_free(&file, 0)); } TEST(t_dlt_message_print_ascii, abnormal) { /* DltFile file; */ /* static char text[DLT_DAEMON_TEXTSIZE]; */ /* / * Get PWD so file and filter can be used* / */ /* char pwd[100]; */ /* getcwd(pwd, 100); */ /* char openfile[114]; */ /* sprintf(openfile, "%s/testfile.dlt", pwd); */ /*---------------------------------------*/ /* No messages read, expected -1 */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_message_print_ascii(&file.msg, text, DLT_DAEMON_TEXTSIZE, 0)); */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_message_print_ascii(&file.msg, text, DLT_DAEMON_TEXTSIZE, 1)); */ /* Set verbose to 12345678 */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_message_print_ascii(&file.msg, text, DLT_DAEMON_TEXTSIZE, 12345678)); */ /* EXPECT_LE(DLT_RETURN_OK, dlt_file_init(&file, 0)); */ /* EXPECT_LE(DLT_RETURN_OK, dlt_file_open(&file, openfile, 0)); */ /* while (dlt_file_read(&file,0)>=0){} */ /* for(int i=0;i= 0) {} for (int i = 0; i < file.counter; i++) { EXPECT_LE(DLT_RETURN_OK, dlt_file_message(&file, i, 0)); EXPECT_LE(DLT_RETURN_OK, dlt_message_print_ascii(&file.msg, text, DLT_DAEMON_TEXTSIZE, 0)); } for (int i = 0; i < file.counter; i++) { EXPECT_LE(DLT_RETURN_OK, dlt_file_message(&file, i, 0)); EXPECT_LE(DLT_RETURN_OK, dlt_message_print_ascii(&file.msg, text, DLT_DAEMON_TEXTSIZE, 1)); } EXPECT_LE(DLT_RETURN_OK, dlt_file_free(&file, 0)); } TEST(t_dlt_message_print_ascii_with_filter, abnormal) { /* equal with t_dlt_message_print_ascii */ } TEST(t_dlt_message_print_ascii_with_filter, nullpointer) { /* equal with t_dlt_message_print_ascii */ } /* End Method: dlt_common::dlt_message_print_ascii with filter*/ /* Begin Method: dlt_common::dlt_message_print_header */ TEST(t_dlt_message_print_header, normal) { DltFile file; static char text[DLT_DAEMON_TEXTSIZE]; /* Get PWD so file can be used*/ char pwd[100]; char openfile[114]; /* ignore returned value from getcwd */ if (getcwd(pwd, 100) == NULL) {} sprintf(openfile, "%s/testfile.dlt", pwd); /*---------------------------------------*/ /* Normal Use-Case, expected 0 */ EXPECT_LE(DLT_RETURN_OK, dlt_file_init(&file, 0)); EXPECT_LE(DLT_RETURN_OK, dlt_file_open(&file, openfile, 0)); while (dlt_file_read(&file, 0) >= 0) {} for (int i = 0; i < file.counter; i++) { EXPECT_LE(DLT_RETURN_OK, dlt_file_message(&file, i, 0)); EXPECT_LE(DLT_RETURN_OK, dlt_message_print_header(&file.msg, text, DLT_DAEMON_TEXTSIZE, 0)); } for (int i = 0; i < file.counter; i++) { EXPECT_LE(DLT_RETURN_OK, dlt_file_message(&file, i, 0)); EXPECT_LE(DLT_RETURN_OK, dlt_message_print_header(&file.msg, text, DLT_DAEMON_TEXTSIZE, 1)); } EXPECT_LE(DLT_RETURN_OK, dlt_file_free(&file, 0)); } TEST(t_dlt_message_print_header, abnormal) { /* DltFile file; */ /* static char text[DLT_DAEMON_TEXTSIZE]; */ /* / * Get PWD so file and filter can be used* / */ /* char pwd[100]; */ /* getcwd(pwd, 100); */ /* char openfile[114]; */ /* sprintf(openfile, "%s/testfile.dlt", pwd); */ /*---------------------------------------*/ /* No messages read, expected -1 */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_message_print_header(&file.msg, text, DLT_DAEMON_TEXTSIZE, 0)); */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_message_print_header(&file.msg, text, DLT_DAEMON_TEXTSIZE, 1)); */ /* Set verbose to 12345678 */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_message_print_header(&file.msg, text, DLT_DAEMON_TEXTSIZE, 12345678)); */ /* EXPECT_LE(DLT_RETURN_OK, dlt_file_init(&file, 0)); */ /* EXPECT_LE(DLT_RETURN_OK, dlt_file_open(&file, openfile, 0)); */ /* while (dlt_file_read(&file,0)>=0){} */ /* for(int i=0;i= 0) {} for (int i = 0; i < file.counter; i++) { EXPECT_LE(DLT_RETURN_OK, dlt_file_message(&file, i, 0)); EXPECT_LE(DLT_RETURN_OK, dlt_message_print_header(&file.msg, text, DLT_DAEMON_TEXTSIZE, 0)); } for (int i = 0; i < file.counter; i++) { EXPECT_LE(DLT_RETURN_OK, dlt_file_message(&file, i, 0)); EXPECT_LE(DLT_RETURN_OK, dlt_message_print_header(&file.msg, text, DLT_DAEMON_TEXTSIZE, 1)); } EXPECT_LE(DLT_RETURN_OK, dlt_file_free(&file, 0)); } TEST(t_dlt_message_print_header_with_filter, abnormal) { /* equal with t_dlt_message_print_header */ } TEST(t_dlt_message_print_header_with_filter, nullpointer) { /* equal with t_dlt_message_print_header */ } /* End Method: dlt_common::dlt_message_print_header with filter */ /* Begin Method: dlt_common::dlt_message_print_hex */ TEST(t_dlt_message_print_hex, normal) { DltFile file; static char text[DLT_DAEMON_TEXTSIZE]; /* Get PWD so file can be used*/ char pwd[100]; char openfile[114]; /* ignore returned value from getcwd */ if (getcwd(pwd, 100) == NULL) {} sprintf(openfile, "%s/testfile.dlt", pwd); /*---------------------------------------*/ /* Normal Use-Case, expected 0 */ EXPECT_LE(DLT_RETURN_OK, dlt_file_init(&file, 0)); EXPECT_LE(DLT_RETURN_OK, dlt_file_open(&file, openfile, 0)); while (dlt_file_read(&file, 0) >= 0) {} for (int i = 0; i < file.counter; i++) { EXPECT_LE(DLT_RETURN_OK, dlt_file_message(&file, i, 0)); EXPECT_LE(DLT_RETURN_OK, dlt_message_print_hex(&file.msg, text, DLT_DAEMON_TEXTSIZE, 0)); } for (int i = 0; i < file.counter; i++) { EXPECT_LE(DLT_RETURN_OK, dlt_file_message(&file, i, 0)); EXPECT_LE(DLT_RETURN_OK, dlt_message_print_hex(&file.msg, text, DLT_DAEMON_TEXTSIZE, 1)); } EXPECT_LE(DLT_RETURN_OK, dlt_file_free(&file, 0)); } TEST(t_dlt_message_print_hex, abnormal) { /* DltFile file; */ /* static char text[DLT_DAEMON_TEXTSIZE]; */ /* / * Get PWD so file and filter can be used* / */ /* char pwd[100]; */ /* getcwd(pwd, 100); */ /* char openfile[114]; */ /* sprintf(openfile, "%s/testfile.dlt", pwd); */ /*---------------------------------------*/ /* No messages read, expected -1 */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_message_print_hex(&file.msg, text, DLT_DAEMON_TEXTSIZE, 0)); */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_message_print_hex(&file.msg, text, DLT_DAEMON_TEXTSIZE, 1)); */ /* Set verbose to 12345678 */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_message_print_hex(&file.msg, text, DLT_DAEMON_TEXTSIZE, 12345678)); */ /* EXPECT_LE(DLT_RETURN_OK, dlt_file_init(&file, 0)); */ /* EXPECT_LE(DLT_RETURN_OK, dlt_file_open(&file, openfile, 0)); */ /* while (dlt_file_read(&file,0)>=0){} */ /* for(int i=0;i= 0) {} for (int i = 0; i < file.counter; i++) { EXPECT_LE(DLT_RETURN_OK, dlt_file_message(&file, i, 0)); EXPECT_LE(DLT_RETURN_OK, dlt_message_print_hex(&file.msg, text, DLT_DAEMON_TEXTSIZE, 0)); } for (int i = 0; i < file.counter; i++) { EXPECT_LE(DLT_RETURN_OK, dlt_file_message(&file, i, 0)); EXPECT_LE(DLT_RETURN_OK, dlt_message_print_hex(&file.msg, text, DLT_DAEMON_TEXTSIZE, 1)); } EXPECT_LE(DLT_RETURN_OK, dlt_file_free(&file, 0)); } TEST(t_dlt_message_print_hex_with_filter, abnormal) { /* equal with t_dlt_message_print_hex */ } TEST(t_dlt_message_print_hex_with_filter, nullpointer) { /* equal with t_dlt_message_print_hex */ } /* End Method: dlt_common::dlt_message_print_hex with filter */ /* Begin Method: dlt_common::dlt_message_print_mixed_plain */ TEST(t_dlt_message_print_mixed_plain, normal) { DltFile file; static char text[DLT_DAEMON_TEXTSIZE]; /* Get PWD so file can be used*/ char pwd[100]; char openfile[114]; /* ignore returned value from getcwd */ if (getcwd(pwd, 100) == NULL) {} sprintf(openfile, "%s/testfile.dlt", pwd); /*---------------------------------------*/ /* Normal Use-Case, expected 0 */ EXPECT_LE(DLT_RETURN_OK, dlt_file_init(&file, 0)); EXPECT_LE(DLT_RETURN_OK, dlt_file_open(&file, openfile, 0)); while (dlt_file_read(&file, 0) >= 0) {} for (int i = 0; i < file.counter; i++) { EXPECT_LE(DLT_RETURN_OK, dlt_file_message(&file, i, 0)); EXPECT_LE(DLT_RETURN_OK, dlt_message_print_mixed_plain(&file.msg, text, DLT_DAEMON_TEXTSIZE, 0)); } for (int i = 0; i < file.counter; i++) { EXPECT_LE(DLT_RETURN_OK, dlt_file_message(&file, i, 0)); EXPECT_LE(DLT_RETURN_OK, dlt_message_print_mixed_plain(&file.msg, text, DLT_DAEMON_TEXTSIZE, 1)); } EXPECT_LE(DLT_RETURN_OK, dlt_file_free(&file, 0)); } TEST(t_dlt_message_print_mixed_plain, abnormal) { /* DltFile file; */ /* static char text[DLT_DAEMON_TEXTSIZE]; */ /* / * Get PWD so file and filter can be used* / */ /* char pwd[100]; */ /* getcwd(pwd, 100); */ /* char openfile[114]; */ /* sprintf(openfile, "%s/testfile.dlt", pwd); */ /*---------------------------------------*/ /* No messages read, expected -1 */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_message_print_mixed_plain(&file.msg, text, DLT_DAEMON_TEXTSIZE, 0)); */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_message_print_mixed_plain(&file.msg, text, DLT_DAEMON_TEXTSIZE, 1)); */ /* Set verbose to 12345678 */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_message_print_mixed_plain(&file.msg, text, DLT_DAEMON_TEXTSIZE, 12345678)); */ /* EXPECT_LE(DLT_RETURN_OK, dlt_file_init(&file, 0)); */ /* EXPECT_LE(DLT_RETURN_OK, dlt_file_open(&file, openfile, 0)); */ /* while (dlt_file_read(&file,0)>=0){} */ /* for(int i=0;i= 0) {} for (int i = 0; i < file.counter; i++) { EXPECT_LE(DLT_RETURN_OK, dlt_file_message(&file, i, 0)); EXPECT_LE(DLT_RETURN_OK, dlt_message_print_mixed_plain(&file.msg, text, DLT_DAEMON_TEXTSIZE, 0)); } for (int i = 0; i < file.counter; i++) { EXPECT_LE(DLT_RETURN_OK, dlt_file_message(&file, i, 0)); EXPECT_LE(DLT_RETURN_OK, dlt_message_print_mixed_plain(&file.msg, text, DLT_DAEMON_TEXTSIZE, 1)); } EXPECT_LE(DLT_RETURN_OK, dlt_file_free(&file, 0)); } TEST(t_dlt_message_print_mixed_plain_with_filter, abnormal) { /* equal with t_dlt_message_print_mixed_plain */ } TEST(t_dlt_message_print_mixed_plain_with_filter, nullpointer) { /* equal with t_dlt_message_print_mixed_plain */ } /* End Method: dlt_common::dlt_message_print_mixed_pain with filter */ /* Begin Method: dlt_common::dlt_message_print_mixed_html */ TEST(t_dlt_message_print_mixed_html, normal) { DltFile file; static char text[DLT_DAEMON_TEXTSIZE]; /* Get PWD so file can be used*/ char pwd[100]; char openfile[114]; /* ignore returned value from getcwd */ if (getcwd(pwd, 100) == NULL) {} sprintf(openfile, "%s/testfile.dlt", pwd); /*---------------------------------------*/ /* Normal Use-Case, expected 0 */ EXPECT_LE(DLT_RETURN_OK, dlt_file_init(&file, 0)); EXPECT_LE(DLT_RETURN_OK, dlt_file_open(&file, openfile, 0)); while (dlt_file_read(&file, 0) >= 0) {} for (int i = 0; i < file.counter; i++) { EXPECT_LE(DLT_RETURN_OK, dlt_file_message(&file, i, 0)); EXPECT_LE(DLT_RETURN_OK, dlt_message_print_mixed_html(&file.msg, text, DLT_DAEMON_TEXTSIZE, 0)); } for (int i = 0; i < file.counter; i++) { EXPECT_LE(DLT_RETURN_OK, dlt_file_message(&file, i, 0)); EXPECT_LE(DLT_RETURN_OK, dlt_message_print_mixed_html(&file.msg, text, DLT_DAEMON_TEXTSIZE, 1)); } EXPECT_LE(DLT_RETURN_OK, dlt_file_free(&file, 0)); } TEST(t_dlt_message_print_mixed_html, abnormal) { /* DltFile file; */ /* static char text[DLT_DAEMON_TEXTSIZE]; */ /* / * Get PWD so file and filter can be used* / */ /* char pwd[100]; */ /* getcwd(pwd, 100); */ /* char openfile[114]; */ /* sprintf(openfile, "%s/testfile.dlt", pwd); */ /*---------------------------------------*/ /* No messages read, expected -1 */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_message_print_mixed_html(&file.msg, text, DLT_DAEMON_TEXTSIZE, 0)); */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_message_print_mixed_html(&file.msg, text, DLT_DAEMON_TEXTSIZE, 1)); */ /* Set verbose to 12345678 */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_message_print_mixed_html(&file.msg, text, DLT_DAEMON_TEXTSIZE, 12345678)); */ /* EXPECT_LE(DLT_RETURN_OK, dlt_file_init(&file, 0)); */ /* EXPECT_LE(DLT_RETURN_OK, dlt_file_open(&file, openfile, 0)); */ /* while (dlt_file_read(&file,0)>=0){} */ /* for(int i=0;i= 0) {} for (int i = 0; i < file.counter; i++) { EXPECT_LE(DLT_RETURN_OK, dlt_file_message(&file, i, 0)); EXPECT_LE(DLT_RETURN_OK, dlt_message_print_mixed_html(&file.msg, text, DLT_DAEMON_TEXTSIZE, 0)); } for (int i = 0; i < file.counter; i++) { EXPECT_LE(DLT_RETURN_OK, dlt_file_message(&file, i, 0)); EXPECT_LE(DLT_RETURN_OK, dlt_message_print_mixed_html(&file.msg, text, DLT_DAEMON_TEXTSIZE, 1)); } EXPECT_LE(DLT_RETURN_OK, dlt_file_free(&file, 0)); } TEST(t_dlt_message_print_mixed_html_with_filter, abnormal) { /* equal with t_dlt_message_print_mixed_html */ } TEST(t_dlt_message_print_mixed_html_with_filter, nullpointer) { /* equal with t_dlt_message_print_mixed_html */ } /* End Method: dlt_common::dlt_message_print_mixed_html_with filter */ /* Begin Method:dlt_common::dlt_message_filter_check */ TEST(t_dlt_message_filter_check, normal) { DltFile file; DltFilter filter; /* Get PWD so file can be used*/ char pwd[100]; char openfile[114]; /* ignore returned value from getcwd */ if (getcwd(pwd, 100) == NULL) {} char openfilter[117]; sprintf(openfile, "%s/testfile.dlt", pwd); sprintf(openfilter, "%s/testfilter.txt", pwd); /*---------------------------------------*/ /* Normal Use-Case, expected > 0 */ EXPECT_LE(DLT_RETURN_OK, dlt_file_init(&file, 0)); EXPECT_LE(DLT_RETURN_OK, dlt_filter_init(&filter, 0)); EXPECT_LE(DLT_RETURN_OK, dlt_filter_load(&filter, openfilter, 0)); EXPECT_LE(DLT_RETURN_OK, dlt_file_set_filter(&file, &filter, 0)); EXPECT_LE(DLT_RETURN_OK, dlt_file_open(&file, openfile, 0)); while (dlt_file_read(&file, 0) >= 0) {} for (int i = 0; i < file.counter; i++) { EXPECT_LE(DLT_RETURN_OK, dlt_file_message(&file, i, 0)); EXPECT_LE(DLT_RETURN_OK, dlt_message_filter_check(&file.msg, &filter, 0)); } for (int i = 0; i < file.counter; i++) { EXPECT_LE(DLT_RETURN_OK, dlt_file_message(&file, i, 0)); EXPECT_LE(DLT_RETURN_OK, dlt_message_filter_check(&file.msg, &filter, 1)); } EXPECT_LE(DLT_RETURN_OK, dlt_file_free(&file, 0)); } TEST(t_dlt_message_filter_check, abnormal) { /* DltFile file; */ /* DltFilter filter; */ /* Get PWD so file and filter can be used*/ /* char pwd[100]; */ /* getcwd(pwd, 100); */ /* char openfile[114]; */ /* char openfilter[117]; */ /* sprintf(openfile, "%s/testfile.dlt", pwd); */ /* sprintf(openfilter, "%s/testfilter.txt", pwd); */ /*---------------------------------------*/ /* No messages read, expected -1 */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_message_filter_check(&file.msg, &filter, 0)); */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_message_filter_check(&file.msg, &filter, 1)); */ /* Set verbose to 12345678 */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_message_filter_check(&file.msg, &filter, 12345678)); */ /* EXPECT_LE(DLT_RETURN_OK, dlt_file_init(&file, 0)); */ /* EXPECT_LE(DLT_RETURN_OK, dlt_file_open(&file, openfile, 0)); */ /* while (dlt_file_read(&file,0)>=0){} */ /* for(int i=0;i0 */ EXPECT_LE(DLT_RETURN_OK, dlt_file_init(&file, 0)); EXPECT_LE(DLT_RETURN_OK, dlt_file_open(&file, openfile, 0)); while (dlt_file_read(&file, 0) >= 0) {} for (int i = 0; i < file.counter; i++) { EXPECT_LE(DLT_RETURN_OK, dlt_file_message(&file, i, 0)); EXPECT_LE(DLT_RETURN_OK, dlt_message_get_extraparameters(&file.msg, 0)); } for (int i = 0; i < file.counter; i++) { EXPECT_LE(DLT_RETURN_OK, dlt_file_message(&file, i, 0)); EXPECT_LE(DLT_RETURN_OK, dlt_message_get_extraparameters(&file.msg, 1)); } EXPECT_LE(DLT_RETURN_OK, dlt_file_free(&file, 0)); } TEST(t_dlt_message_get_extraparamters, abnormal) { /* DltFile file; */ /* Get PWD so file and filter can be used*/ /* char pwd[100]; */ /* getcwd(pwd, 100); */ /* char openfile[114]; */ /* sprintf(openfile, "%s/testfile.dlt", pwd); */ /*---------------------------------------*/ /* Uninizialised, expected -1 */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_message_get_extraparameters(&file.msg, 0)); */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_message_get_extraparameters(&file.msg, 1)); */ /* set verbose to 12345678, expected -1 */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_message_get_extraparameters(&file.msg, 12345678)); */ /* EXPECT_LE(DLT_RETURN_OK, dlt_file_init(&file, 0)); */ /* EXPECT_LE(DLT_RETURN_OK, dlt_file_open(&file, openfile, 0)); */ /* while (dlt_file_read(&file,0)>=0){} */ /* for(int i=0;i= 0) {} for (int i = 0; i < file.counter; i++) { EXPECT_LE(DLT_RETURN_OK, dlt_file_message(&file, i, 0)); EXPECT_LE(DLT_RETURN_OK, dlt_message_header(&file.msg, text, DLT_DAEMON_TEXTSIZE, 0)); printf("%s \n", text); } for (int i = 0; i < file.counter; i++) { EXPECT_LE(DLT_RETURN_OK, dlt_file_message(&file, i, 0)); EXPECT_LE(DLT_RETURN_OK, dlt_message_header(&file.msg, text, DLT_DAEMON_TEXTSIZE, 1)); printf("%s \n", text); } EXPECT_LE(DLT_RETURN_OK, dlt_file_free(&file, 0)); } TEST(t_dlt_message_header, abnormal) { /* DltFile file; */ /* static char text[DLT_DAEMON_TEXTSIZE]; */ /* Get PWD so file and filter can be used*/ /* char pwd[100]; */ /* getcwd(pwd, 100); */ /* char openfile[114]; */ /* sprintf(openfile, "%s/testfile.dlt", pwd); */ /*---------------------------------------*/ /* Uninizialised, expected -1 */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_message_header(&file.msg, text, DLT_DAEMON_TEXTSIZE, 0)); */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_message_header(&file.msg, text, DLT_DAEMON_TEXTSIZE, 1)); */ /* set verbose to 12345678, expected -1 */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_message_header(&file.msg, text, DLT_DAEMON_TEXTSIZE, 12345678)); */ /* EXPECT_LE(DLT_RETURN_OK, dlt_file_init(&file, 0)); */ /* EXPECT_LE(DLT_RETURN_OK, dlt_file_open(&file, openfile, 0)); */ /* while (dlt_file_read(&file,0)>=0){} */ /* for(int i=0;i= 0) {} for (int i = 0; i < file.counter; i++) { EXPECT_LE(DLT_RETURN_OK, dlt_file_message(&file, i, 0)); EXPECT_LE(DLT_RETURN_OK, dlt_message_header_flags(&file.msg, text, DLT_DAEMON_TEXTSIZE, DLT_HEADER_SHOW_NONE, 0)); printf("%s \n", text); EXPECT_LE(DLT_RETURN_OK, dlt_message_header_flags(&file.msg, text, DLT_DAEMON_TEXTSIZE, DLT_HEADER_SHOW_TIME, 0)); printf("%s \n", text); EXPECT_LE(DLT_RETURN_OK, dlt_message_header_flags(&file.msg, text, DLT_DAEMON_TEXTSIZE, DLT_HEADER_SHOW_TMSTP, 0)); printf("%s \n", text); EXPECT_LE(DLT_RETURN_OK, dlt_message_header_flags(&file.msg, text, DLT_DAEMON_TEXTSIZE, DLT_HEADER_SHOW_MSGCNT, 0)); printf("%s \n", text); EXPECT_LE(DLT_RETURN_OK, dlt_message_header_flags(&file.msg, text, DLT_DAEMON_TEXTSIZE, DLT_HEADER_SHOW_ECUID, 0)); printf("%s \n", text); EXPECT_LE(DLT_RETURN_OK, dlt_message_header_flags(&file.msg, text, DLT_DAEMON_TEXTSIZE, DLT_HEADER_SHOW_APID, 0)); printf("%s \n", text); EXPECT_LE(DLT_RETURN_OK, dlt_message_header_flags(&file.msg, text, DLT_DAEMON_TEXTSIZE, DLT_HEADER_SHOW_CTID, 0)); printf("%s \n", text); EXPECT_LE(DLT_RETURN_OK, dlt_message_header_flags(&file.msg, text, DLT_DAEMON_TEXTSIZE, DLT_HEADER_SHOW_MSGTYPE, 0)); printf("%s \n", text); EXPECT_LE(DLT_RETURN_OK, dlt_message_header_flags(&file.msg, text, DLT_DAEMON_TEXTSIZE, DLT_HEADER_SHOW_MSGSUBTYPE, 0)); printf("%s \n", text); EXPECT_LE(DLT_RETURN_OK, dlt_message_header_flags(&file.msg, text, DLT_DAEMON_TEXTSIZE, DLT_HEADER_SHOW_VNVSTATUS, 0)); printf("%s \n", text); EXPECT_LE(DLT_RETURN_OK, dlt_message_header_flags(&file.msg, text, DLT_DAEMON_TEXTSIZE, DLT_HEADER_SHOW_NOARG, 0)); printf("%s \n", text); EXPECT_LE(DLT_RETURN_OK, dlt_message_header_flags(&file.msg, text, DLT_DAEMON_TEXTSIZE, DLT_HEADER_SHOW_ALL, 0)); printf("%s \n", text); } for (int i = 0; i < file.counter; i++) { EXPECT_LE(DLT_RETURN_OK, dlt_file_message(&file, i, 0)); EXPECT_LE(DLT_RETURN_OK, dlt_message_header_flags(&file.msg, text, DLT_DAEMON_TEXTSIZE, DLT_HEADER_SHOW_NONE, 1)); printf("%s \n", text); EXPECT_LE(DLT_RETURN_OK, dlt_message_header_flags(&file.msg, text, DLT_DAEMON_TEXTSIZE, DLT_HEADER_SHOW_TIME, 1)); printf("%s \n", text); EXPECT_LE(DLT_RETURN_OK, dlt_message_header_flags(&file.msg, text, DLT_DAEMON_TEXTSIZE, DLT_HEADER_SHOW_TMSTP, 1)); printf("%s \n", text); EXPECT_LE(DLT_RETURN_OK, dlt_message_header_flags(&file.msg, text, DLT_DAEMON_TEXTSIZE, DLT_HEADER_SHOW_MSGCNT, 1)); printf("%s \n", text); EXPECT_LE(DLT_RETURN_OK, dlt_message_header_flags(&file.msg, text, DLT_DAEMON_TEXTSIZE, DLT_HEADER_SHOW_ECUID, 1)); printf("%s \n", text); EXPECT_LE(DLT_RETURN_OK, dlt_message_header_flags(&file.msg, text, DLT_DAEMON_TEXTSIZE, DLT_HEADER_SHOW_APID, 1)); printf("%s \n", text); EXPECT_LE(DLT_RETURN_OK, dlt_message_header_flags(&file.msg, text, DLT_DAEMON_TEXTSIZE, DLT_HEADER_SHOW_CTID, 1)); printf("%s \n", text); EXPECT_LE(DLT_RETURN_OK, dlt_message_header_flags(&file.msg, text, DLT_DAEMON_TEXTSIZE, DLT_HEADER_SHOW_MSGTYPE, 1)); printf("%s \n", text); EXPECT_LE(DLT_RETURN_OK, dlt_message_header_flags(&file.msg, text, DLT_DAEMON_TEXTSIZE, DLT_HEADER_SHOW_MSGSUBTYPE, 1)); printf("%s \n", text); EXPECT_LE(DLT_RETURN_OK, dlt_message_header_flags(&file.msg, text, DLT_DAEMON_TEXTSIZE, DLT_HEADER_SHOW_VNVSTATUS, 1)); printf("%s \n", text); EXPECT_LE(DLT_RETURN_OK, dlt_message_header_flags(&file.msg, text, DLT_DAEMON_TEXTSIZE, DLT_HEADER_SHOW_NOARG, 1)); printf("%s \n", text); EXPECT_LE(DLT_RETURN_OK, dlt_message_header_flags(&file.msg, text, DLT_DAEMON_TEXTSIZE, DLT_HEADER_SHOW_ALL, 1)); printf("%s \n", text); } EXPECT_LE(DLT_RETURN_OK, dlt_file_free(&file, 0)); } TEST(t_dlt_message_header_flags, abnormal) { /* DltFile file; */ /* static char text[DLT_DAEMON_TEXTSIZE]; */ /* / * Get PWD so file and filter can be used* / */ /* char pwd[100]; */ /* getcwd(pwd, 100); */ /* char openfile[114];; */ /* sprintf(openfile, "%s/testfile.dlt", pwd); */ /*---------------------------------------*/ /* Uninizialised, expected -1 */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_message_header_flags(&file.msg, text, DLT_DAEMON_TEXTSIZE, DLT_HEADER_SHOW_NONE, 0)); */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_message_header_flags(&file.msg, text, DLT_DAEMON_TEXTSIZE, DLT_HEADER_SHOW_TIME, 0)); */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_message_header_flags(&file.msg, text, DLT_DAEMON_TEXTSIZE, DLT_HEADER_SHOW_TMSTP, 0)); */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_message_header_flags(&file.msg, text, DLT_DAEMON_TEXTSIZE, DLT_HEADER_SHOW_MSGCNT, 0)); */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_message_header_flags(&file.msg, text, DLT_DAEMON_TEXTSIZE, DLT_HEADER_SHOW_ECUID, 0)); */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_message_header_flags(&file.msg, text, DLT_DAEMON_TEXTSIZE, DLT_HEADER_SHOW_APID, 0)); */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_message_header_flags(&file.msg, text, DLT_DAEMON_TEXTSIZE, DLT_HEADER_SHOW_CTID, 0)); */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_message_header_flags(&file.msg, text, DLT_DAEMON_TEXTSIZE, DLT_HEADER_SHOW_MSGTYPE, 0)); */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_message_header_flags(&file.msg, text, DLT_DAEMON_TEXTSIZE, DLT_HEADER_SHOW_MSGSUBTYPE, 0)); */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_message_header_flags(&file.msg, text, DLT_DAEMON_TEXTSIZE, DLT_HEADER_SHOW_VNVSTATUS, 0)); */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_message_header_flags(&file.msg, text, DLT_DAEMON_TEXTSIZE, DLT_HEADER_SHOW_NOARG, 0)); */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_message_header_flags(&file.msg, text, DLT_DAEMON_TEXTSIZE, DLT_HEADER_SHOW_ALL, 0)); */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_message_header_flags(&file.msg, text, DLT_DAEMON_TEXTSIZE, DLT_HEADER_SHOW_NONE, 1)); */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_message_header_flags(&file.msg, text, DLT_DAEMON_TEXTSIZE, DLT_HEADER_SHOW_TIME, 1)); */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_message_header_flags(&file.msg, text, DLT_DAEMON_TEXTSIZE, DLT_HEADER_SHOW_TMSTP, 1)); */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_message_header_flags(&file.msg, text, DLT_DAEMON_TEXTSIZE, DLT_HEADER_SHOW_MSGCNT, 1)); */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_message_header_flags(&file.msg, text, DLT_DAEMON_TEXTSIZE, DLT_HEADER_SHOW_ECUID, 1)); */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_message_header_flags(&file.msg, text, DLT_DAEMON_TEXTSIZE, DLT_HEADER_SHOW_APID, 1)); */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_message_header_flags(&file.msg, text, DLT_DAEMON_TEXTSIZE, DLT_HEADER_SHOW_CTID, 1)); */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_message_header_flags(&file.msg, text, DLT_DAEMON_TEXTSIZE, DLT_HEADER_SHOW_MSGTYPE, 1)); */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_message_header_flags(&file.msg, text, DLT_DAEMON_TEXTSIZE, DLT_HEADER_SHOW_MSGSUBTYPE, 1)); */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_message_header_flags(&file.msg, text, DLT_DAEMON_TEXTSIZE, DLT_HEADER_SHOW_VNVSTATUS, 1)); */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_message_header_flags(&file.msg, text, DLT_DAEMON_TEXTSIZE, DLT_HEADER_SHOW_NOARG, 1)); */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_message_header_flags(&file.msg, text, DLT_DAEMON_TEXTSIZE, DLT_HEADER_SHOW_ALL, 1)); */ /* USE own DLT_HEADER_SHOW , expected -1 */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_message_header_flags(&file.msg, text, DLT_DAEMON_TEXTSIZE, 0x1234, 0)); */ /* EXPECT_LE(DLT_RETURN_OK, dlt_file_init(&file, 0)); */ /* EXPECT_LE(DLT_RETURN_OK, dlt_file_open(&file, openfile, 0)); */ /* while (dlt_file_read(&file,0)>=0){} */ /* for(int i=0;i= 0) {} for (int i = 0; i < file.counter; i++) { EXPECT_LE(DLT_RETURN_OK, dlt_file_message(&file, i, 0)); EXPECT_LE(DLT_RETURN_OK, dlt_message_payload(&file.msg, text, DLT_DAEMON_TEXTSIZE, DLT_OUTPUT_HEX, 0)); printf("%s \n", text); EXPECT_LE(DLT_RETURN_OK, dlt_message_payload(&file.msg, text, DLT_DAEMON_TEXTSIZE, DLT_OUTPUT_ASCII, 0)); printf("%s \n", text); EXPECT_LE(DLT_RETURN_OK, dlt_message_payload(&file.msg, text, DLT_DAEMON_TEXTSIZE, DLT_OUTPUT_MIXED_FOR_PLAIN, 0)); printf("%s \n", text); EXPECT_LE(DLT_RETURN_OK, dlt_message_payload(&file.msg, text, DLT_DAEMON_TEXTSIZE, DLT_OUTPUT_MIXED_FOR_HTML, 0)); printf("%s \n", text); EXPECT_LE(DLT_RETURN_OK, dlt_message_payload(&file.msg, text, DLT_DAEMON_TEXTSIZE, DLT_OUTPUT_ASCII_LIMITED, 0)); printf("%s \n", text); } for (int i = 0; i < file.counter; i++) { EXPECT_LE(DLT_RETURN_OK, dlt_file_message(&file, i, 0)); EXPECT_LE(DLT_RETURN_OK, dlt_message_payload(&file.msg, text, DLT_DAEMON_TEXTSIZE, DLT_OUTPUT_HEX, 1)); printf("%s \n", text); EXPECT_LE(DLT_RETURN_OK, dlt_message_payload(&file.msg, text, DLT_DAEMON_TEXTSIZE, DLT_OUTPUT_ASCII, 1)); printf("%s \n", text); EXPECT_LE(DLT_RETURN_OK, dlt_message_payload(&file.msg, text, DLT_DAEMON_TEXTSIZE, DLT_OUTPUT_MIXED_FOR_PLAIN, 1)); printf("%s \n", text); EXPECT_LE(DLT_RETURN_OK, dlt_message_payload(&file.msg, text, DLT_DAEMON_TEXTSIZE, DLT_OUTPUT_MIXED_FOR_HTML, 1)); printf("%s \n", text); EXPECT_LE(DLT_RETURN_OK, dlt_message_payload(&file.msg, text, DLT_DAEMON_TEXTSIZE, DLT_OUTPUT_ASCII_LIMITED, 1)); printf("%s \n", text); } EXPECT_LE(DLT_RETURN_OK, dlt_file_free(&file, 0)); } TEST(t_dlt_message_payload, abnormal) { /* DltFile file; */ /* static char text[DLT_DAEMON_TEXTSIZE]; */ /* Get PWD so file and filter can be used*/ /* char pwd[100]; */ /* getcwd(pwd, 100); */ /* char openfile[114]; */ /* sprintf(openfile, "%s/testfile.dlt", pwd); */ /*---------------------------------------*/ /* Uninizialised, expected -1 */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_message_payload(&file.msg, text, DLT_DAEMON_TEXTSIZE, DLT_OUTPUT_HEX, 0)); */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_message_payload(&file.msg, text, DLT_DAEMON_TEXTSIZE, DLT_OUTPUT_ASCII, 0)); */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_message_payload(&file.msg, text, DLT_DAEMON_TEXTSIZE, DLT_OUTPUT_MIXED_FOR_PLAIN, 0)); */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_message_payload(&file.msg, text, DLT_DAEMON_TEXTSIZE, DLT_OUTPUT_MIXED_FOR_HTML, 0)); */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_message_payload(&file.msg, text, DLT_DAEMON_TEXTSIZE, DLT_OUTPUT_ASCII_LIMITED, 0)); */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_message_payload(&file.msg, text, DLT_DAEMON_TEXTSIZE, DLT_OUTPUT_HEX, 1)); */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_message_payload(&file.msg, text, DLT_DAEMON_TEXTSIZE, DLT_OUTPUT_ASCII, 1)); */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_message_payload(&file.msg, text, DLT_DAEMON_TEXTSIZE, DLT_OUTPUT_MIXED_FOR_PLAIN, 1)); */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_message_payload(&file.msg, text, DLT_DAEMON_TEXTSIZE, DLT_OUTPUT_MIXED_FOR_HTML, 1)); */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_message_payload(&file.msg, text, DLT_DAEMON_TEXTSIZE, DLT_OUTPUT_ASCII_LIMITED, 1)); */ /* USE own DLT_HEADER_SHOW , expected -1 */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_message_payload(&file.msg, text, DLT_DAEMON_TEXTSIZE, 99, 0)); */ /* EXPECT_LE(DLT_RETURN_OK, dlt_file_init(&file, 0)); */ /* EXPECT_LE(DLT_RETURN_OK, dlt_file_open(&file, openfile, 0)); */ /* while (dlt_file_read(&file,0)>=0){} */ /* for(int i=0;i=0){} */ /* for(int i=0;i 0 but */ /* we don't have text: */ /* dlt_common.c line 943: ptr = msg->databuffer; */ /* (gdb) p ptr */ /* $28 = (uint8_t *) 0x5124010337d46c00 */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_message_payload(&file.msg, text, DLT_DAEMON_TEXTSIZE, 0, 0)); */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_message_payload(&file.msg, text, DLT_DAEMON_TEXTSIZE, 0, 1)); */ } /* End Method:dlt_common::dlt_message_payload */ /* Begin Method:dlt_common::dlt_message_set_extraparameters */ TEST(t_dlt_message_set_extraparamters, normal) { DltFile file; /* Get PWD so file can be used*/ char pwd[100]; char openfile[114]; /* ignore returned value from getcwd */ if (getcwd(pwd, 100) == NULL) {} sprintf(openfile, "%s/testfile.dlt", pwd); /*---------------------------------------*/ /* Normal Use-Case, expect 0 */ EXPECT_LE(DLT_RETURN_OK, dlt_file_init(&file, 0)); EXPECT_LE(DLT_RETURN_OK, dlt_file_open(&file, openfile, 0)); while (dlt_file_read(&file, 0) >= 0) {} for (int i = 0; i < file.counter; i++) { EXPECT_LE(DLT_RETURN_OK, dlt_file_message(&file, i, 0)); EXPECT_LE(DLT_RETURN_OK, dlt_message_set_extraparameters(&file.msg, 0)); } for (int i = 0; i < file.counter; i++) { EXPECT_LE(DLT_RETURN_OK, dlt_file_message(&file, i, 0)); EXPECT_LE(DLT_RETURN_OK, dlt_message_set_extraparameters(&file.msg, 1)); } EXPECT_LE(DLT_RETURN_OK, dlt_file_free(&file, 0)); } TEST(t_dlt_message_set_extraparamters, abnormal) { /* DltFile file; */ /* // Get PWD so file and filter can be used */ /* char pwd[100]; */ /* getcwd(pwd, 100); */ /* char openfile[114]; */ /* sprintf(openfile, "%s/testfile.dlt", pwd); */ /*---------------------------------------*/ /* Uninizialised, expected -1 */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_message_set_extraparameters(&file.msg, 0)); */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_message_set_extraparameters(&file.msg, 1)); */ /* set verbos to 12345678 */ /* EXPECT_LE(DLT_RETURN_OK, dlt_file_init(&file, 0)); */ /* EXPECT_LE(DLT_RETURN_OK, dlt_file_open(&file, openfile, 0)); */ /* while (dlt_file_read(&file,0)>=0){} */ /* for(int i=0;i= 0) {} for (int i = 0; i < file.counter; i++) { EXPECT_LE(DLT_RETURN_OK, dlt_file_message(&file, i, 0)); EXPECT_LE(DLT_RETURN_ERROR, dlt_message_read(&file.msg, (unsigned char *)buffer, 255, 0, 1)); } EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); EXPECT_LE(DLT_RETURN_OK, dlt_buffer_init_dynamic(&buf, DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)); EXPECT_LE(DLT_RETURN_OK, dlt_file_init(&file, 0)); EXPECT_LE(DLT_RETURN_OK, dlt_file_open(&file, openfile, 0)); while (dlt_file_read(&file, 0) >= 0) {} for (int i = 0; i < file.counter; i++) { EXPECT_LE(DLT_RETURN_OK, dlt_file_message(&file, i, 0)); EXPECT_LE(DLT_RETURN_ERROR, dlt_message_read(&file.msg, (unsigned char *)buffer, 255, 1, 1)); } EXPECT_LE(DLT_RETURN_OK, dlt_buffer_free_dynamic(&buf)); } TEST(t_dlt_message_read, abnormal) {} TEST(t_dlt_message_read, nullpointer) { DltFile file; /* Get PWD so file can be used*/ char pwd[100]; char openfile[114]; /* ignore returned value from getcwd */ if (getcwd(pwd, 100) == NULL) {} sprintf(openfile, "%s/testfile.dlt", pwd); /*---------------------------------------*/ DltBuffer buf; /* NULL_Pointer, expected -1 */ EXPECT_GE(DLT_RETURN_ERROR, dlt_message_read(NULL, NULL, 0, 0, 0)); EXPECT_GE(DLT_RETURN_ERROR, dlt_message_read(NULL, (uint8_t *)&buf, 0, 0, 0)); EXPECT_GE(DLT_RETURN_ERROR, dlt_message_read(&file.msg, NULL, 0, 0, 0)); EXPECT_GE(DLT_RETURN_ERROR, dlt_message_read(&file.msg, (uint8_t *)&buf, 0, 0, 0)); } /* End Method:dlt_common::dlt_message_read */ /* Begin Method:dlt_common::dlt_message_argument_print */ TEST(t_dlt_message_argument_print, normal) { DltFile file; /* Get PWD so file can be used*/ char pwd[100]; char openfile[114]; /* ignore returned value from getcwd */ if (getcwd(pwd, 100) == NULL) {} sprintf(openfile, "%s/testfile.dlt", pwd); static char text[DLT_DAEMON_TEXTSIZE]; /*---------------------------------------*/ uint8_t *ptr; int32_t datalength; uint8_t **pptr; int32_t *pdatalength; /* Normal Use-Case, expect 0 */ EXPECT_LE(DLT_RETURN_OK, dlt_file_init(&file, 0)); EXPECT_LE(DLT_RETURN_OK, dlt_file_open(&file, openfile, 0)); while (dlt_file_read(&file, 0) >= 0) {} for (int i = 0; i < file.counter; i++) { EXPECT_LE(DLT_RETURN_OK, dlt_file_message(&file, i, 0)); ptr = file.msg.databuffer; datalength = file.msg.datasize; pptr = &ptr; pdatalength = &datalength; EXPECT_GE(DLT_RETURN_OK, dlt_message_argument_print(&file.msg, DLT_TYPE_INFO_BOOL, pptr, pdatalength, text, DLT_DAEMON_TEXTSIZE, 0, 1)); /*printf("### ARGUMENT:%s\n", text); */ } EXPECT_LE(DLT_RETURN_OK, dlt_file_free(&file, 0)); EXPECT_LE(DLT_RETURN_OK, dlt_file_init(&file, 0)); EXPECT_LE(DLT_RETURN_OK, dlt_file_open(&file, openfile, 0)); while (dlt_file_read(&file, 0) >= 0) {} for (int i = 0; i < file.counter; i++) { EXPECT_LE(DLT_RETURN_OK, dlt_file_message(&file, i, 0)); ptr = file.msg.databuffer; datalength = file.msg.datasize; pptr = &ptr; pdatalength = &datalength; EXPECT_GE(DLT_RETURN_OK, dlt_message_argument_print(&file.msg, DLT_TYPE_INFO_RAWD, pptr, pdatalength, text, DLT_DAEMON_TEXTSIZE, 0, 1)); /*printf("### ARGUMENT:%s\n", text); */ } EXPECT_LE(DLT_RETURN_OK, dlt_file_free(&file, 0)); } TEST(t_dlt_message_argument_print, abnormal) { /* DltFile file; */ /* Get PWD so file and filter can be used */ /* char pwd[100]; */ /* getcwd(pwd, 100); */ /* char openfile[114]; */ /* sprintf(openfile, "%s/testfile.dlt", pwd); */ /* static char text[DLT_DAEMON_TEXTSIZE]; */ /*---------------------------------------*/ /* uint8_t *ptr; */ /* int32_t datalength; */ /* uint8_t **pptr; */ /* int32_t *pdatalength; */ /* Uninizialised, expected -1 */ /* EXPECT_GE(DLT_RETURN_ERROR, dlt_message_argument_print(&file.msg,12345678,pptr,pdatalength,text,DLT_DAEMON_TEXTSIZE,0,1)); */ /* Use a non defined type_info, expected -1 */ /* EXPECT_LE(DLT_RETURN_OK, dlt_file_init(&file, 0)); */ /* EXPECT_LE(DLT_RETURN_OK, dlt_file_open(&file, openfile, 0)); */ /* while (dlt_file_read(&file,0)>=0){} */ /* for(int i=0;i|"; */ /* char text3[DLT_DAEMON_TEXTSIZE]; */ /* EXPECT_LE(DLT_RETURN_OK, dlt_print_hex_string(text3,DLT_DAEMON_TEXTSIZE,(unsigned char *)test3, strlen(test3))); */ /*printf("text:%s\n", text3); */ /* convert text3 to an ascii string to compare with the original */ /* char * converted = (char*) malloc(strlen(test3) +1); */ /* int t = 0; */ /* for(unsigned int i=0;i|"; */ /* char text5[DLT_DAEMON_TEXTSIZE]; */ /* EXPECT_LE(DLT_RETURN_OK, dlt_print_mixed_string(text5,DLT_DAEMON_TEXTSIZE,(unsigned char *)test5,strlen(test5),0)); */ /* printf("%s\n", text5); */ /* const char * test6 = "^°!\"§$%&/()=?`´¹²³¼½¬{[]}\\¸@€üöä+#*'~`,.-;:_·…–<>|"; */ /* char text6[DLT_DAEMON_TEXTSIZE]; */ /* EXPECT_LE(DLT_RETURN_OK, dlt_print_mixed_string(text6,DLT_DAEMON_TEXTSIZE,(unsigned char *)test6,strlen(test6),1)); */ /* printf("%s\n", text6); */ /* const char * test7 = ""; */ /* char text7[DLT_DAEMON_TEXTSIZE]; */ /* EXPECT_LE(DLT_RETURN_OK, dlt_print_mixed_string(text7,DLT_DAEMON_TEXTSIZE,(unsigned char *)test7,strlen(test7),0)); */ /* printf("%s\n", text7); */ /* const char * test8 = ""; */ /* char text8[DLT_DAEMON_TEXTSIZE]; */ /* EXPECT_LE(DLT_RETURN_OK, dlt_print_mixed_string(text8,DLT_DAEMON_TEXTSIZE,(unsigned char *)test8,strlen(test8),1)); */ /* printf("%s\n", text8); */ } TEST(t_dlt_print_mixed_string, nullpointer) { const char *test9 = ""; char text9[DLT_DAEMON_TEXTSIZE]; EXPECT_GE(DLT_RETURN_ERROR, dlt_print_mixed_string(NULL, 0, 0, 0, 0)); EXPECT_GE(DLT_RETURN_ERROR, dlt_print_mixed_string(NULL, 0, 0, 0, 1)); EXPECT_GE(DLT_RETURN_ERROR, dlt_print_mixed_string(NULL, 0, (unsigned char *)test9, 0, 0)); EXPECT_GE(DLT_RETURN_ERROR, dlt_print_mixed_string(NULL, 0, (unsigned char *)test9, 0, 1)); EXPECT_GE(DLT_RETURN_ERROR, dlt_print_mixed_string(text9, 0, NULL, 0, 0)); EXPECT_GE(DLT_RETURN_ERROR, dlt_print_mixed_string(text9, 0, NULL, 0, 1)); } /* End Method:dlt_common::dlt_print_mixed_string */ /* Begin Method:dlt_common::dlt_print_char_string */ TEST(t_dlt_print_char_string, normal) { /* Normal Use-Case, expect 0 */ const char *test1 = "HELLO"; char text1[DLT_DAEMON_TEXTSIZE]; char *ptr1 = text1; EXPECT_LE(DLT_RETURN_OK, dlt_print_char_string(&ptr1, DLT_DAEMON_TEXTSIZE, (unsigned char *)test1, strlen(test1))); printf("text:%s\n", text1); EXPECT_STREQ(text1, test1); const char *test2 = "qwertzuiopasdfghjklyxcvbnm1234567890"; char text2[DLT_DAEMON_TEXTSIZE]; char *ptr2 = text2; EXPECT_LE(DLT_RETURN_OK, dlt_print_char_string(&ptr2, DLT_DAEMON_TEXTSIZE, (unsigned char *)test2, strlen(test2))); printf("text:%s\n", text2); EXPECT_STREQ(text2, test2); } TEST(t_dlt_print_char_string, abnormal) { /* print special characters, expected 0 */ /* const char * test3 = "^°!\"§$%&/()=?`´¹²³¼½¬{[]}\\¸@€üöä+#*'~`,.-;:_·…–<>|"; */ /* char text3[DLT_DAEMON_TEXTSIZE]; */ /* char * ptr3 = text3; */ /* EXPECT_LE(DLT_RETURN_OK, dlt_print_char_string(&ptr3,DLT_DAEMON_TEXTSIZE,(unsigned char *)test3, strlen(test3))); */ /* printf("text:%s\n", text3); */ /* EXPECT_STREQ(text3, test3); */ /* Empty char *, expect 0 */ /* const char * test4 = ""; */ /* char text4[DLT_DAEMON_TEXTSIZE]; */ /* char * ptr4 = text4; */ /* EXPECT_LE(DLT_RETURN_OK, dlt_print_char_string(&ptr4,DLT_DAEMON_TEXTSIZE,(unsigned char *)test4, strlen(test4))); */ /* printf("text:%s\n", text4); */ /* EXPECT_STREQ(text4, test4); */ } TEST(t_dlt_print_char_string, nullpointer) { const char *test5 = "HELLO"; char text5[DLT_DAEMON_TEXTSIZE]; char *ptr5 = text5; EXPECT_GE(DLT_RETURN_ERROR, dlt_print_char_string(NULL, 0, NULL, 0)); EXPECT_GE(DLT_RETURN_ERROR, dlt_print_char_string(NULL, 0, (unsigned char *)test5, 0)); EXPECT_GE(DLT_RETURN_ERROR, dlt_print_char_string(&ptr5, 0, NULL, 0)); } /* End Method:dlt_common::dlt_print_char_string */ /* Begin Method:dlt_common::dlt_print_id */ TEST(t_dlt_print_id, normal) { /* Normal Use-Case, expect text==id */ const char *id = "DLTD"; char text[DLT_DAEMON_TEXTSIZE]; dlt_print_id(text, id); EXPECT_STREQ(text, id); } TEST(t_dlt_print_id, abnormal) { /* id to long, expect only first 4 chars */ /* const char* id = "DLTD123456789"; */ /* char text[DLT_DAEMON_TEXTSIZE]; */ /* dlt_print_id(text,id); */ /* EXPECT_STREQ(text,"DLTD"); */ /* id to short, expect expend with "-" to 4 chars */ /* id = "DL"; */ /* dlt_print_id(text,id); */ /* EXPECT_STREQ(text,"DL--"); */ } TEST(t_dlt_print_id, nullpointer) { const char *id = "DLTD"; char text[DLT_DAEMON_TEXTSIZE]; /* NULL-Pointer, expected nothing in return */ EXPECT_NO_THROW(dlt_print_id(NULL, NULL)); EXPECT_NO_THROW(dlt_print_id(NULL, id)); EXPECT_NO_THROW(dlt_print_id(text, NULL)); } /* End Method:dlt_common::dlt_print_id */ /* Begin Method:dlt_common::dlt_get_version */ TEST(t_dlt_get_version, normal) { /* Normal Use-Case */ char ver[255]; dlt_get_version(ver, 255); printf("%s\n", ver); } TEST(t_dlt_get_version, abnormal) { /* Change default length of ver to 1 */ /* char ver[1]; */ /* dlt_get_version(ver, DLT_USER_MAX_LIB_VERSION_LENGTH); */ /* printf("%s\n", ver); */ /* Change default length of ver to 1 and reduce second para to 1, too */ /* dlt_get_version(ver, 1); */ /* printf("%s\n", ver); */ } TEST(t_dlt_get_version, nullpointer) { EXPECT_NO_THROW(dlt_get_version(NULL, 0)); } /* End Method:dlt_common::dlt_get_version */ /* Begin Method:dlt_common::dlt_get_major_version */ TEST(dlt_get_major_version, normal) { char ver[DLT_USER_MAX_LIB_VERSION_LENGTH]; dlt_get_major_version(ver, DLT_USER_MAX_LIB_VERSION_LENGTH); EXPECT_STREQ(ver, _DLT_PACKAGE_MAJOR_VERSION); } TEST(dlt_get_major_version, abnormal) { /* Change default length of ver to 1 */ /* char ver[1]; */ /* dlt_get_major_version(ver, DLT_USER_MAX_LIB_VERSION_LENGTH); */ /* EXPECT_STREQ(ver, _DLT_PACKAGE_MAJOR_VERSION); */ /* Change default length of ver to 1 and reduce second para to 1, too */ /* dlt_get_major_version(ver, 1); */ /* EXPECT_STREQ(ver, _DLT_PACKAGE_MAJOR_VERSION); */ } TEST(dlt_get_major_version, nullpointer) { /* NULL-Pointer, expect exeption */ EXPECT_NO_THROW(dlt_get_major_version(NULL, 0)); } /* End Method:dlt_common::dlt_get_major_version */ /* Begin Method:dlt_common::dlt_get_minor_version */ TEST(dlt_get_minor_version, normal) { char ver[DLT_USER_MAX_LIB_VERSION_LENGTH]; dlt_get_minor_version(ver, DLT_USER_MAX_LIB_VERSION_LENGTH); EXPECT_STREQ(ver, _DLT_PACKAGE_MINOR_VERSION); } TEST(dlt_get_minor_version, abnormal) { /* Change default length of ver to 1 */ /* char ver[1]; */ /* dlt_get_minor_version(ver, DLT_USER_MAX_LIB_VERSION_LENGTH); */ /* EXPECT_STREQ(ver, _DLT_PACKAGE_MINOR_VERSION); */ /* Change default length of ver to 1 and reduce second para to 1, too */ /* dlt_get_minor_version(ver, 1); */ /* EXPECT_STREQ(ver, _DLT_PACKAGE_MINOR_VERSION); */ } TEST(dlt_get_minor_version, nullpointer) { /* NULL-Pointer, expect exeption */ EXPECT_NO_THROW(dlt_get_minor_version(NULL, 0)); } /* End Method:dlt_common::dlt_get_minor_version */ /*##############################################################################################################################*/ /*##############################################################################################################################*/ /*##############################################################################################################################*/ int main(int argc, char **argv) { ::testing::InitGoogleTest(&argc, argv); ::testing::FLAGS_gtest_break_on_failure = true; /*::testing::FLAGS_gtest_filter = "*.normal"; */ return RUN_ALL_TESTS(); } dlt-daemon-2.18.4/tests/gtest_dlt_daemon_common.cpp000066400000000000000000002337161353342203500224000ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2011-2015, BMW AG * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author * Stefan Held * * \copyright Copyright © 2011-2015 BMW AG. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file gtest_dlt_common.cpp */ #include #include extern "C" { #include "dlt_daemon_common.h" #include "dlt_daemon_common_cfg.h" #include "dlt_user_shared_cfg.h" #include "errno.h" #include #include "dlt_types.h" #include "dlt-daemon.h" #include "dlt-daemon_cfg.h" #include "dlt_daemon_common_cfg.h" #include "dlt_daemon_socket.h" #include "dlt_daemon_serial.h" #include "dlt_daemon_client.h" #include "dlt_offline_trace.h" #include "dlt_gateway_types.h" } #ifndef DLT_USER_DIR # define DLT_USER_DIR "/tmp/dltpipes" #endif /* Name of named pipe to DLT daemon */ #ifndef DLT_USER_FIFO # define DLT_USER_FIFO "/tmp/dlt" #endif /* Begin Method:dlt_daemon_common::dlt_daemon_init_user_information */ TEST(t_dlt_daemon_init_user_information, normal_one_list) { DltDaemon daemon; DltGateway gateway; char ecu[] = "ECU1"; EXPECT_EQ(0, dlt_daemon_init(&daemon, DLT_DAEMON_RINGBUFFER_MIN_SIZE, DLT_DAEMON_RINGBUFFER_MAX_SIZE, DLT_DAEMON_RINGBUFFER_STEP_SIZE, DLT_RUNTIME_DEFAULT_DIRECTORY, DLT_LOG_INFO, DLT_TRACE_STATUS_OFF, 0, 0)); dlt_set_id(daemon.ecuid, ecu); EXPECT_EQ(0, dlt_daemon_init_user_information(&daemon, &gateway, 0, 0)); EXPECT_EQ(DLT_RETURN_OK, strncmp(daemon.ecuid, daemon.user_list[0].ecu, DLT_ID_SIZE)); EXPECT_EQ(0, dlt_daemon_free(&daemon, 0)); } /* Begin Method:dlt_daemon_common::dlt_daemon_init_user_information */ TEST(t_dlt_daemon_init_user_information, normal_multiple_lists) { DltDaemon daemon; DltGateway gateway; char ecu[] = "ECU1"; char ecu2[] = "ECU2"; char ecu3[] = "ECU3"; gateway.connections = (DltGatewayConnection *)calloc(2, sizeof(DltGatewayConnection)); gateway.connections[0].ecuid = &ecu2[0]; gateway.connections[1].ecuid = &ecu3[0]; gateway.num_connections = 2; /* Normal Use-Case */ EXPECT_EQ(0, dlt_daemon_init(&daemon, DLT_DAEMON_RINGBUFFER_MIN_SIZE, DLT_DAEMON_RINGBUFFER_MAX_SIZE, DLT_DAEMON_RINGBUFFER_STEP_SIZE, DLT_RUNTIME_DEFAULT_DIRECTORY, DLT_LOG_INFO, DLT_TRACE_STATUS_OFF, 0, 0)); dlt_set_id(daemon.ecuid, ecu); EXPECT_EQ(0, dlt_daemon_init_user_information(&daemon, &gateway, 1, 0)); EXPECT_EQ(3, daemon.num_user_lists); EXPECT_EQ(DLT_RETURN_OK, strncmp(daemon.ecuid, daemon.user_list[0].ecu, DLT_ID_SIZE)); EXPECT_EQ(DLT_RETURN_OK, strncmp(gateway.connections[0].ecuid, daemon.user_list[1].ecu, DLT_ID_SIZE)); EXPECT_EQ(DLT_RETURN_OK, strncmp(gateway.connections[1].ecuid, daemon.user_list[2].ecu, DLT_ID_SIZE)); EXPECT_EQ(0, dlt_daemon_free(&daemon, 0)); free(gateway.connections); } TEST(t_dlt_daemon_init_user_information, nullpointer) { DltDaemon daemon; DltGateway gateway; EXPECT_EQ(-1, dlt_daemon_init_user_information(NULL, NULL, 0, 0)); EXPECT_EQ(-1, dlt_daemon_init_user_information(NULL, &gateway, 0, 0)); EXPECT_EQ(0, dlt_daemon_init_user_information(&daemon, NULL, 0, 0)); EXPECT_EQ(-1, dlt_daemon_init_user_information(&daemon, NULL, 1, 0)); } /* Begin Method:dlt_daemon_common::dlt_daemon_find_users_list */ TEST(t_dlt_daemon_find_users_list, normal_one_list) { DltDaemon daemon; DltGateway gateway; DltDaemonRegisteredUsers *user_list; char ecu[] = "ECU1"; EXPECT_EQ(0, dlt_daemon_init(&daemon, DLT_DAEMON_RINGBUFFER_MIN_SIZE, DLT_DAEMON_RINGBUFFER_MAX_SIZE, DLT_DAEMON_RINGBUFFER_STEP_SIZE, DLT_RUNTIME_DEFAULT_DIRECTORY, DLT_LOG_INFO, DLT_TRACE_STATUS_OFF, 0, 0)); dlt_set_id(daemon.ecuid, ecu); EXPECT_EQ(0, dlt_daemon_init_user_information(&daemon, &gateway, 0, 0)); user_list = dlt_daemon_find_users_list(&daemon, &ecu[0], 0); EXPECT_NE(user_list, nullptr); EXPECT_EQ(DLT_RETURN_OK, strncmp(user_list->ecu, daemon.ecuid, DLT_ID_SIZE)); EXPECT_EQ(0, dlt_daemon_free(&daemon, 0)); } /* Begin Method:dlt_daemon_common::dlt_daemon_find_users_list */ TEST(t_dlt_daemon_find_users_list, abnormal) { DltDaemon daemon; DltGateway gateway; DltDaemonRegisteredUsers *user_list; char ecu[] = "ECU1"; char bla[] = "BLAH"; EXPECT_EQ(0, dlt_daemon_init(&daemon, DLT_DAEMON_RINGBUFFER_MIN_SIZE, DLT_DAEMON_RINGBUFFER_MAX_SIZE, DLT_DAEMON_RINGBUFFER_STEP_SIZE, DLT_RUNTIME_DEFAULT_DIRECTORY, DLT_LOG_INFO, DLT_TRACE_STATUS_OFF, 0, 0)); dlt_set_id(daemon.ecuid, ecu); EXPECT_EQ(0, dlt_daemon_init_user_information(&daemon, &gateway, 0, 0)); user_list = dlt_daemon_find_users_list(&daemon, bla, 0); EXPECT_EQ(user_list, nullptr); EXPECT_EQ(0, dlt_daemon_free(&daemon, 0)); } /* Begin Method:dlt_daemon_common::dlt_daemon_init_user_information */ TEST(t_dlt_daemon_find_users_list, normal_multiple_lists) { DltDaemon daemon; DltGateway gateway; char ecu[] = "ECU1"; char ecu2[] = "ECU2"; char ecu3[] = "ECU3"; DltDaemonRegisteredUsers *user_list; gateway.connections = (DltGatewayConnection *)calloc(2, sizeof(DltGatewayConnection)); gateway.connections[0].ecuid = &ecu2[0]; gateway.connections[1].ecuid = &ecu3[0]; gateway.num_connections = 2; /* Normal Use-Case */ EXPECT_EQ(0, dlt_daemon_init(&daemon, DLT_DAEMON_RINGBUFFER_MIN_SIZE, DLT_DAEMON_RINGBUFFER_MAX_SIZE, DLT_DAEMON_RINGBUFFER_STEP_SIZE, DLT_RUNTIME_DEFAULT_DIRECTORY, DLT_LOG_INFO, DLT_TRACE_STATUS_OFF, 0, 0)); dlt_set_id(daemon.ecuid, ecu); EXPECT_EQ(0, dlt_daemon_init_user_information(&daemon, &gateway, 1, 0)); EXPECT_EQ(3, daemon.num_user_lists); EXPECT_EQ(DLT_RETURN_OK, strncmp(daemon.ecuid, daemon.user_list[0].ecu, DLT_ID_SIZE)); EXPECT_EQ(DLT_RETURN_OK, strncmp(gateway.connections[0].ecuid, daemon.user_list[1].ecu, DLT_ID_SIZE)); EXPECT_EQ(DLT_RETURN_OK, strncmp(gateway.connections[1].ecuid, daemon.user_list[2].ecu, DLT_ID_SIZE)); user_list = dlt_daemon_find_users_list(&daemon, &ecu[0], 0); EXPECT_NE(user_list, nullptr); EXPECT_EQ(DLT_RETURN_OK, strncmp(user_list->ecu, daemon.ecuid, DLT_ID_SIZE)); user_list = dlt_daemon_find_users_list(&daemon, &ecu2[0], 0); EXPECT_NE(user_list, nullptr); EXPECT_EQ(DLT_RETURN_OK, strncmp(user_list->ecu, gateway.connections[0].ecuid, DLT_ID_SIZE)); user_list = dlt_daemon_find_users_list(&daemon, &ecu3[0], 0); EXPECT_NE(user_list, nullptr); EXPECT_EQ(DLT_RETURN_OK, strncmp(user_list->ecu, gateway.connections[1].ecuid, DLT_ID_SIZE)); EXPECT_EQ(0, dlt_daemon_free(&daemon, 0)); free(gateway.connections); } TEST(t_dlt_daemon_find_users_list, nullpointer) { DltDaemon daemon; char ecu[] = "ECU1"; EXPECT_EQ(NULL, dlt_daemon_find_users_list(NULL, NULL, 0)); EXPECT_EQ(NULL, dlt_daemon_find_users_list(&daemon, NULL, 0)); EXPECT_EQ(NULL, dlt_daemon_find_users_list(NULL, &ecu[0], 0)); } /* Begin Method:dlt_daemon_common::dlt_daemon_application_add */ TEST(t_dlt_daemon_application_add, normal) { DltDaemon daemon; DltGateway gateway; const char *apid = "TEST"; pid_t pid = 0; const char *desc = "HELLO_TEST"; DltDaemonApplication *app = NULL; char ecu[] = "ECU1"; int fd = 15; /* Normal Use-Case */ EXPECT_EQ(0, dlt_daemon_init(&daemon, DLT_DAEMON_RINGBUFFER_MIN_SIZE, DLT_DAEMON_RINGBUFFER_MAX_SIZE, DLT_DAEMON_RINGBUFFER_STEP_SIZE, DLT_RUNTIME_DEFAULT_DIRECTORY, DLT_LOG_INFO, DLT_TRACE_STATUS_OFF, 0, 0)); dlt_set_id(daemon.ecuid, ecu); EXPECT_EQ(0, dlt_daemon_init_user_information(&daemon, &gateway, 0, 0)); EXPECT_EQ(DLT_RETURN_OK, strncmp(daemon.ecuid, daemon.user_list[0].ecu, DLT_ID_SIZE)); app = dlt_daemon_application_add(&daemon, (char *)apid, pid, (char *)desc, fd, ecu, 0); /*printf("### APP: APID=%s DESCR=%s NUMCONTEXT=%i PID=%i USERHANDLE=%i\n", app->apid,app->application_description, app->num_contexts, app->pid, app->user_handle); */ EXPECT_STREQ(apid, app->apid); EXPECT_STREQ(desc, app->application_description); EXPECT_EQ(pid, app->pid); EXPECT_LE(0, dlt_daemon_application_del(&daemon, app, ecu, 0)); EXPECT_LE(0, dlt_daemon_applications_clear(&daemon, ecu, 0)); /* Apid > 4, expected truncate to 4 char or error */ apid = "TO_LONG"; app = dlt_daemon_application_add(&daemon, (char *)apid, pid, (char *)desc, fd, ecu, 0); char tmp[5]; strncpy(tmp, apid, 4); tmp[4] = '\0'; EXPECT_STREQ(tmp, app->apid); EXPECT_LE(0, dlt_daemon_application_del(&daemon, app, ecu, 0)); EXPECT_LE(0, dlt_daemon_applications_clear(&daemon, ecu, 0)); EXPECT_EQ(0, dlt_daemon_free(&daemon, 0)); } TEST(t_dlt_daemon_application_add, abnormal) { /* DltDaemon daemon; */ /* const char * apid = "TEST"; */ /* pid_t pid = 0; */ /* const char * desc = "HELLO_TEST"; */ /* DltDaemonApplication *app = NULL; */ /* Add the same application with same pid twice */ /* EXPECT_EQ(0, dlt_daemon_init(&daemon, DLT_DAEMON_RINGBUFFER_MIN_SIZE, DLT_DAEMON_RINGBUFFER_MAX_SIZE, DLT_DAEMON_RINGBUFFER_STEP_SIZE, DLT_RUNTIME_DEFAULT_DIRECTORY,DLT_LOG_INFO, DLT_TRACE_STATUS_OFF,0,0)); */ /* app = dlt_daemon_application_add(&daemon,(char *) apid, pid, (char *) desc, 0); */ /* EXPECT_LE((DltDaemonApplication *) 0, app); */ /* app = dlt_daemon_application_add(&daemon,(char *) apid, pid, (char *) desc, 0); */ /* EXPECT_EQ((DltDaemonApplication *) 0, app); */ /* dlt_daemon_application_del(&daemon,app, 0); */ /* dlt_daemon_applications_clear(&daemon, 0); */ /* Add the same applicaiotn with different pid */ /* app = dlt_daemon_application_add(&daemon,(char *) apid, 0, (char *) desc, 0); */ /* EXPECT_LE((DltDaemonApplication *) 0, app); */ /* app = dlt_daemon_application_add(&daemon,(char *) apid, 123, (char *) desc, 0); */ /* EXPECT_EQ((DltDaemonApplication *) 0, app); */ /* dlt_daemon_application_del(&daemon,app, 0); */ /* dlt_daemon_applications_clear(&daemon, 0); */ /* verbose value != 0 or 1 */ /* app = dlt_daemon_application_add(&daemon,(char *) apid, pid, (char *) desc, 0); */ /* EXPECT_EQ((DltDaemonApplication *)0, dlt_daemon_application_add(&daemon,(char *) apid, pid, (char *) desc, 12345678)); */ /* dlt_daemon_application_del(&daemon, app, 0); */ /* dlt_daemon_applications_clear(&daemon, 0); */ /* Apid < 4, expected fill to 4 chars or error */ /* apid = "SH"; */ /* app = dlt_daemon_application_add(&daemon,(char *) apid, pid, (char *) desc, 0); */ /* char tmp[5]; */ /* strncpy(tmp, apid, 4); */ /* tmp[4] = '\0'; */ /* EXPECT_STREQ(tmp, app->apid); */ /* dlt_daemon_application_del(&daemon, app, 0); */ /* dlt_daemon_applications_clear(&daemon, 0); */ /* EXPECT_EQ(0, dlt_daemon_free(&daemon, 0)); */ } TEST(t_dlt_daemon_application_add, nullpointer) { DltDaemon daemon; const char *apid = "TEST"; const char *desc = "HELLO_TEST"; int fd = 42; char ecu[] = "ECU1"; /* NULL-Pointer test */ EXPECT_EQ((DltDaemonApplication *)0, dlt_daemon_application_add(NULL, NULL, 0, NULL, 0, NULL, 0)); EXPECT_EQ((DltDaemonApplication *)0, dlt_daemon_application_add(NULL, NULL, 0, (char *)desc, 0, NULL, 0)); EXPECT_EQ((DltDaemonApplication *)0, dlt_daemon_application_add(NULL, (char *)apid, 0, NULL, 0, NULL, 0)); EXPECT_EQ((DltDaemonApplication *)0, dlt_daemon_application_add(NULL, (char *)apid, 0, (char *)desc, 0, NULL, 0)); EXPECT_EQ((DltDaemonApplication *)0, dlt_daemon_application_add(&daemon, NULL, 0, NULL, 0, NULL, 0)); EXPECT_EQ((DltDaemonApplication *)0, dlt_daemon_application_add(&daemon, NULL, 0, (char *)desc, 0, NULL, 0)); EXPECT_EQ((DltDaemonApplication *)0, dlt_daemon_application_add(NULL, NULL, 0, NULL, fd, NULL, 0)); EXPECT_EQ((DltDaemonApplication *)0, dlt_daemon_application_add(NULL, NULL, 0, NULL, 0, ecu, 0)); } /* End Method:dlt_daemon_common::dlt_daemon_application_add */ /* Begin Method: dlt_daemon_common::dlt_daemon_application_del */ TEST(t_dlt_daemon_application_del, normal) { DltDaemon daemon; DltGateway gateway; const char *apid = "TEST"; pid_t pid = 0; const char *desc = "HELLO_TEST"; DltDaemonApplication *app = NULL; char ecu[] = "ECU1"; int fd = 42; /* Normal Use-Case, retrun type cannot be tested, only apid and desc */ EXPECT_EQ(0, dlt_daemon_init(&daemon, DLT_DAEMON_RINGBUFFER_MIN_SIZE, DLT_DAEMON_RINGBUFFER_MAX_SIZE, DLT_DAEMON_RINGBUFFER_STEP_SIZE, DLT_RUNTIME_DEFAULT_DIRECTORY, DLT_LOG_INFO, DLT_TRACE_STATUS_OFF, 0, 0)); dlt_set_id(daemon.ecuid, ecu); EXPECT_EQ(0, dlt_daemon_init_user_information(&daemon, &gateway, 0, 0)); EXPECT_EQ(DLT_RETURN_OK, strncmp(daemon.ecuid, daemon.user_list[0].ecu, DLT_ID_SIZE)); app = dlt_daemon_application_add(&daemon, (char *)apid, pid, (char *)desc, fd, ecu, 0); EXPECT_LE(0, dlt_daemon_application_del(&daemon, app, ecu, 0)); EXPECT_LE(0, dlt_daemon_applications_clear(&daemon, ecu, 0)); EXPECT_EQ(0, dlt_daemon_free(&daemon, 0)); } TEST(t_dlt_daemon_application_del, abnormal) { /* DltDaemon daemon; */ /* const char * apid = "TEST"; */ /* pid_t pid = 0; */ /* const char * desc = "HELLO_TEST"; */ /* DltDaemonApplication *app = NULL; */ /* no application exists, expect < 0 */ /* EXPECT_EQ(0, dlt_daemon_init(&daemon, DLT_DAEMON_RINGBUFFER_MIN_SIZE, DLT_DAEMON_RINGBUFFER_MAX_SIZE, DLT_DAEMON_RINGBUFFER_STEP_SIZE, DLT_RUNTIME_DEFAULT_DIRECTORY,DLT_LOG_INFO, DLT_TRACE_STATUS_OFF,0,0)); */ /* EXPECT_GE(-1, dlt_daemon_application_del(&daemon, app, 0)); */ /* Call delete two times */ /* app = dlt_daemon_application_add(&daemon,(char *) apid, pid, (char *) desc, 0); */ /* EXPECT_LE(0, dlt_daemon_application_del(&daemon,app, 0)); */ /* EXPECT_GE(-1, dlt_daemon_application_del(&daemon,app, 0)); */ /* dlt_daemon_applications_clear(&daemon, 0); */ /* Verbose parameter != 0 or 1 */ /* app = dlt_daemon_application_add(&daemon,(char *) apid, pid, (char *) desc, 0); */ /* EXPECT_GE(-1, dlt_daemon_application_del(&daemon,app, 123456789)); */ /* dlt_daemon_applications_clear(&daemon, 0); */ /* EXPECT_EQ(0, dlt_daemon_free(&daemon, 0)); */ } TEST(t_dlt_daemon_application_del, nullpointer) { DltDaemon daemon; DltDaemonApplication app; char ecu[] = "ECU1"; /* NULL-Pointer */ EXPECT_GE(-1, dlt_daemon_application_del(NULL, NULL, NULL, 0)); EXPECT_GE(-1, dlt_daemon_application_del(NULL, &app, NULL, 0)); EXPECT_GE(-1, dlt_daemon_application_del(&daemon, NULL, ecu, 0)); } /* End Method: dlt_daemon_common::dlt_daemon_application_del */ /* Begin Method: dlt_daemon_common::dlt_daemon_applikation_find */ TEST(t_dlt_daemon_application_find, normal) { DltDaemon daemon; DltGateway gateway; const char *apid = "TEST"; pid_t pid = 0; const char *desc = "HELLO_TEST"; DltDaemonApplication *app = NULL; char ecu[] = "ECU1"; int fd = 42; /* Normal Use-Case */ EXPECT_EQ(0, dlt_daemon_init(&daemon, DLT_DAEMON_RINGBUFFER_MIN_SIZE, DLT_DAEMON_RINGBUFFER_MAX_SIZE, DLT_DAEMON_RINGBUFFER_STEP_SIZE, DLT_RUNTIME_DEFAULT_DIRECTORY, DLT_LOG_INFO, DLT_TRACE_STATUS_OFF, 0, 0)); dlt_set_id(daemon.ecuid, ecu); EXPECT_EQ(0, dlt_daemon_init_user_information(&daemon, &gateway, 0, 0)); EXPECT_EQ(DLT_RETURN_OK, strncmp(daemon.ecuid, daemon.user_list[0].ecu, DLT_ID_SIZE)); app = dlt_daemon_application_add(&daemon, (char *)apid, pid, (char *)desc, fd, ecu, 0); EXPECT_STREQ(apid, app->apid); EXPECT_STREQ(desc, app->application_description); EXPECT_EQ(pid, app->pid); EXPECT_LE(0, dlt_daemon_application_del(&daemon, app, ecu, 0)); EXPECT_LE(0, dlt_daemon_applications_clear(&daemon, ecu, 0)); /* Application doesn't exist, expect NULL */ EXPECT_EQ((DltDaemonApplication *)0, dlt_daemon_application_find(&daemon, ecu, (char *)apid, 0)); /* Use a different apid, expect NULL */ app = dlt_daemon_application_add(&daemon, (char *)apid, pid, (char *)desc, fd, ecu, 0); EXPECT_LE((DltDaemonApplication *)0, dlt_daemon_application_find(&daemon, ecu, (char *)apid, 0)); EXPECT_EQ((DltDaemonApplication *)0, dlt_daemon_application_find(&daemon, ecu, (char *)"NEXI", 0)); EXPECT_LE(0, dlt_daemon_application_del(&daemon, app, ecu, 0)); EXPECT_LE(0, dlt_daemon_applications_clear(&daemon, ecu, 0)); EXPECT_EQ(0, dlt_daemon_free(&daemon, 0)); } TEST(t_dlt_daemon_application_find, abnormal) { /* DltDaemon daemon; */ /* const char * apid = "TEST"; */ /* pid_t pid = 0; */ /* const char * desc = "HELLO_TEST"; */ /* DltDaemonApplication *app = NULL; */ /* Verbose != 0 or 1, expect error */ /* EXPECT_EQ(0, dlt_daemon_init(&daemon, DLT_DAEMON_RINGBUFFER_MIN_SIZE, DLT_DAEMON_RINGBUFFER_MAX_SIZE, DLT_DAEMON_RINGBUFFER_STEP_SIZE, DLT_RUNTIME_DEFAULT_DIRECTORY,DLT_LOG_INFO, DLT_TRACE_STATUS_OFF,0,0)); */ /* app = dlt_daemon_application_add(&daemon,(char *) apid, pid, (char *) desc, 0); */ /* dlt_daemon_application_find(&daemon, (char *) apid, 0); */ /* EXPECT_EQ((DltDaemonApplication *) 0, dlt_daemon_application_find(&daemon, (char *) apid, 123456789)); */ /* dlt_daemon_application_del(&daemon, app, 0); */ /* dlt_daemon_applications_clear(&daemon, 0); */ /* EXPECT_EQ(0, dlt_daemon_free(&daemon, 0)); */ } TEST(t_dlt_daemon_application_find, nullpointer) { DltDaemon daemon; const char *apid = "TEST"; /* NULL-Pointer, expected NULL */ EXPECT_EQ((DltDaemonApplication *)0, dlt_daemon_application_find(NULL, NULL, NULL, 0)); EXPECT_EQ((DltDaemonApplication *)0, dlt_daemon_application_find(NULL, (char *)apid, NULL, 0)); EXPECT_EQ((DltDaemonApplication *)0, dlt_daemon_application_find(&daemon, NULL, NULL, 0)); } /* End Method: dlt_daemon_common::dlt_daemon_applikation_find */ /* Begin Method: dlt_daemon_common::dlt_daemon_applications_clear */ TEST(t_dlt_daemon_applications_clear, normal) { DltDaemon daemon; DltGateway gateway; pid_t pid = 0; char ecu[] = "ECU1"; int fd = 42; /* Normal Use Case, expect >= 0 */ EXPECT_EQ(0, dlt_daemon_init(&daemon, DLT_DAEMON_RINGBUFFER_MIN_SIZE, DLT_DAEMON_RINGBUFFER_MAX_SIZE, DLT_DAEMON_RINGBUFFER_STEP_SIZE, DLT_RUNTIME_DEFAULT_DIRECTORY, DLT_LOG_INFO, DLT_TRACE_STATUS_OFF, 0, 0)); dlt_set_id(daemon.ecuid, ecu); EXPECT_EQ(0, dlt_daemon_init_user_information(&daemon, &gateway, 0, 0)); EXPECT_EQ(DLT_RETURN_OK, strncmp(daemon.ecuid, daemon.user_list[0].ecu, DLT_ID_SIZE)); EXPECT_LE((DltDaemonApplication *)0, dlt_daemon_application_add(&daemon, (char *)"TES1", pid, (char *)"Test clear 1", fd, ecu, 0)); dlt_daemon_application_add(&daemon, (char *)"TES2", pid, (char *)"Test clear 2", fd, ecu, 0); EXPECT_LE(0, dlt_daemon_applications_clear(&daemon, ecu, 0)); EXPECT_EQ(0, dlt_daemon_free(&daemon, 0)); } TEST(t_dlt_daemon_applications_clear, abnormal) { /* DltDaemon daemon; */ /* pid_t pid = 0; */ /* No applications added, expect < -1 */ /* EXPECT_EQ(0, dlt_daemon_init(&daemon, DLT_DAEMON_RINGBUFFER_MIN_SIZE, DLT_DAEMON_RINGBUFFER_MAX_SIZE, DLT_DAEMON_RINGBUFFER_STEP_SIZE, DLT_RUNTIME_DEFAULT_DIRECTORY,DLT_LOG_INFO, DLT_TRACE_STATUS_OFF,0,0)); */ /* EXPECT_GE(-1, dlt_daemon_applications_clear(&daemon, 0)); */ /* Verbose != 0 or 1, expect error */ /* dlt_daemon_application_add(&daemon, (char *) "TEST", pid, (char *) "Test clear", 0); */ /* EXPECT_GE(-1, dlt_daemon_applications_clear(&daemon, 123456789)); */ /* dlt_daemon_applications_clear(&daemon, 0); */ /* EXPECT_EQ(0, dlt_daemon_free(&daemon, 0)); */ } TEST(t_dlt_daemon_applications_clear, nullpointer) { /* NULL-Pointer, expect < 0 */ EXPECT_GE(-1, dlt_daemon_applications_clear(NULL, NULL, 0)); } /* End Method: dlt_daemon_common::dlt_daemon_applications_clear */ /* Begin Method: dlt_daemon_common::dlt_daemon_applications_invalidate_fd */ TEST(t_dlt_daemon_applications_invalidate_fd, normal) { DltDaemon daemon; DltGateway gateway; const char *apid = "TEST"; pid_t pid = 0; const char *desc = "HELLO_TEST"; DltDaemonApplication *app = NULL; char ecu[] = "ECU1"; int fd = 42; /* Normal Use-Case */ EXPECT_EQ(0, dlt_daemon_init(&daemon, DLT_DAEMON_RINGBUFFER_MIN_SIZE, DLT_DAEMON_RINGBUFFER_MAX_SIZE, DLT_DAEMON_RINGBUFFER_STEP_SIZE, DLT_RUNTIME_DEFAULT_DIRECTORY, DLT_LOG_INFO, DLT_TRACE_STATUS_OFF, 0, 0)); dlt_set_id(daemon.ecuid, ecu); EXPECT_EQ(0, dlt_daemon_init_user_information(&daemon, &gateway, 0, 0)); EXPECT_EQ(DLT_RETURN_OK, strncmp(daemon.ecuid, daemon.user_list[0].ecu, DLT_ID_SIZE)); app = dlt_daemon_application_add(&daemon, (char *)apid, pid, (char *)desc, fd, ecu, 0); EXPECT_LE(0, dlt_daemon_applications_invalidate_fd(&daemon, ecu, app->user_handle, 0)); EXPECT_LE(0, dlt_daemon_application_del(&daemon, app, ecu, 0)); EXPECT_LE(0, dlt_daemon_applications_clear(&daemon, ecu, 0)); EXPECT_EQ(0, dlt_daemon_free(&daemon, 0)); } TEST(t_dlt_daemon_applications_invalidate_fd, abnormal) { /* DltDaemon daemon; */ /* const char * apid = "TEST"; */ /* pid_t pid = 0; */ /* const char * desc = "HELLO_TEST"; */ /* DltDaemonApplication *app = NULL; */ /* Daemon isn't initialized, expected error */ /* EXPECT_EQ(0, dlt_daemon_init(&daemon, DLT_DAEMON_RINGBUFFER_MIN_SIZE, DLT_DAEMON_RINGBUFFER_MAX_SIZE, DLT_DAEMON_RINGBUFFER_STEP_SIZE, DLT_RUNTIME_DEFAULT_DIRECTORY,DLT_LOG_INFO, DLT_TRACE_STATUS_OFF,0,0)); */ /* EXPECT_GE(-1, dlt_daemon_applications_invalidate_fd(&daemon, 0, 0)); */ /* Verbose != 0 or 1, expect error */ /* app = dlt_daemon_application_add(&daemon,(char *) apid, pid, (char *) desc, 0); */ /* EXPECT_GE(-1, dlt_daemon_applications_invalidate_fd(&daemon, app->user_handle, 123456789)); */ /* dlt_daemon_application_del(&daemon, app, 0); */ /* dlt_daemon_applications_clear(&daemon, 0); */ /* EXPECT_EQ(0, dlt_daemon_free(&daemon, 0)); */ } TEST(t_dlt_daemon_applications_invalidate_fd, nullpointer) { /* NULL-Pointer */ EXPECT_GE(-1, dlt_daemon_applications_invalidate_fd(NULL, NULL, 0, 0)); } /* End Method: dlt_daemon_common::dlt_daemon_applications_invalidate_fd */ /* Begin Method: dlt_daemon_common::dlt_daemon_applications_save */ TEST(t_dlt_daemon_applications_save, normal) { DltDaemon daemon; DltGateway gateway; const char *apid = "TEST"; pid_t pid = 0; const char *desc = "HELLO_TEST"; DltDaemonApplication *app = NULL; const char *filename = "/tmp/dlt-runtime.cfg"; char ecu[] = "ECU1"; int fd = 42; /* Normal Use-Case */ EXPECT_EQ(0, dlt_daemon_init(&daemon, DLT_DAEMON_RINGBUFFER_MIN_SIZE, DLT_DAEMON_RINGBUFFER_MAX_SIZE, DLT_DAEMON_RINGBUFFER_STEP_SIZE, DLT_RUNTIME_DEFAULT_DIRECTORY, DLT_LOG_INFO, DLT_TRACE_STATUS_OFF, 0, 0)); dlt_set_id(daemon.ecuid, ecu); EXPECT_EQ(0, dlt_daemon_init_user_information(&daemon, &gateway, 0, 0)); EXPECT_EQ(DLT_RETURN_OK, strncmp(daemon.ecuid, daemon.user_list[0].ecu, DLT_ID_SIZE)); app = dlt_daemon_application_add(&daemon, (char *)apid, pid, (char *)desc, fd, ecu, 0); EXPECT_LE(0, dlt_daemon_applications_save(&daemon, (char *)filename, 0)); EXPECT_LE(0, dlt_daemon_application_del(&daemon, app, ecu, 0)); EXPECT_LE(0, dlt_daemon_applications_clear(&daemon, ecu, 0)); EXPECT_EQ(0, dlt_daemon_free(&daemon, 0)); } TEST(t_dlt_daemon_applications_save, abnormal) { /* DltDaemon daemon; */ /* const char * apid = "TEST"; */ /* pid_t pid = 0; */ /* const char * desc = "HELLO_TEST"; */ /* DltDaemonApplication *app = NULL; */ /* const char * filename = "/tmp/dlt-runtime.cfg"; */ /* Uninitialized */ /* EXPECT_EQ(0, dlt_daemon_init(&daemon, DLT_DAEMON_RINGBUFFER_MIN_SIZE, DLT_DAEMON_RINGBUFFER_MAX_SIZE, DLT_DAEMON_RINGBUFFER_STEP_SIZE, DLT_RUNTIME_DEFAULT_DIRECTORY,DLT_LOG_INFO, DLT_TRACE_STATUS_OFF,0,0)); */ /* EXPECT_GE(-1, dlt_daemon_applications_save(&daemon, (char *) filename, 0)); */ /* Verbose != 1 or 0, expect error */ /* app = dlt_daemon_application_add(&daemon,(char *) apid, pid, (char *) desc, 0); */ /* EXPECT_GE(-1, dlt_daemon_applications_save(&daemon, (char *) filename, 123456789)); */ /* dlt_daemon_application_del(&daemon, app, 0); */ /* dlt_daemon_applications_clear(&daemon, 0); */ /* Wrong path filename */ /* app = dlt_daemon_application_add(&daemon,(char *) apid, pid, (char *) desc, 0); */ /* EXPECT_GE(-1, dlt_daemon_applications_save(&daemon, (char *) "PATH_DONT_EXIST", 0)); */ /* dlt_daemon_application_del(&daemon, app, 0); */ /* dlt_daemon_applications_clear(&daemon, 0); */ /* EXPECT_EQ(0, dlt_daemon_free(&daemon, 0)); */ } TEST(t_dlt_daemon_applications_save, nullpointer) { DltDaemon daemon; const char *filename = "/tmp/dlt-runtime.cfg"; /* NULL-Pointer */ EXPECT_GE(-1, dlt_daemon_applications_save(NULL, NULL, 0)); EXPECT_GE(-1, dlt_daemon_applications_save(NULL, (char *)filename, 0)); EXPECT_GE(-1, dlt_daemon_applications_save(&daemon, NULL, 0)); } /* End Method: dlt_daemon_common::dlt_daemon_applications_save */ /* Begin Method: dlt_daemon_common::dlt_daemon_applications_load */ TEST(t_dlt_daemon_applications_load, normal) { DltDaemon daemon; DltGateway gateway; char ecu[] = "ECU1"; const char *filename = "/tmp/dlt-runtime.cfg"; /* Normal Use-Case, first execute t_dlt_daemon_applications_save !! */ EXPECT_EQ(0, dlt_daemon_init(&daemon, DLT_DAEMON_RINGBUFFER_MIN_SIZE, DLT_DAEMON_RINGBUFFER_MAX_SIZE, DLT_DAEMON_RINGBUFFER_STEP_SIZE, DLT_RUNTIME_DEFAULT_DIRECTORY, DLT_LOG_INFO, DLT_TRACE_STATUS_OFF, 0, 0)); dlt_set_id(daemon.ecuid, ecu); EXPECT_EQ(0, dlt_daemon_init_user_information(&daemon, &gateway, 0, 0)); EXPECT_EQ(DLT_RETURN_OK, strncmp(daemon.ecuid, daemon.user_list[0].ecu, DLT_ID_SIZE)); EXPECT_LE(0, dlt_daemon_applications_load(&daemon, (char *)filename, 0)); EXPECT_EQ(0, dlt_daemon_free(&daemon, 0)); } TEST(t_dlt_daemon_applications_load, abnormal) { /* DltDaemon daemon; */ /* const char * apid = "TEST"; */ /* pid_t pid = 0; */ /* const char * desc = "HELLO_TEST"; */ /* DltDaemonApplication *app = NULL; */ /* const char * filename = "/tmp/dlt-runtime.cfg"; */ /* Uninitialized */ /* EXPECT_EQ(0, dlt_daemon_init(&daemon, DLT_DAEMON_RINGBUFFER_MIN_SIZE, DLT_DAEMON_RINGBUFFER_MAX_SIZE, DLT_DAEMON_RINGBUFFER_STEP_SIZE, DLT_RUNTIME_DEFAULT_DIRECTORY,DLT_LOG_INFO, DLT_TRACE_STATUS_OFF,0,0)); */ /* EXPECT_GE(-1, dlt_daemon_applications_load(&daemon, (char *) filename, 0)); */ /* Verbose != 1 or 0, expect error */ /* app = dlt_daemon_application_add(&daemon,(char *) apid, pid, (char *) desc, 0); */ /* EXPECT_GE(-1, dlt_daemon_applications_load(&daemon, (char *) filename, 123456789)); */ /* dlt_daemon_application_del(&daemon, app, 0); */ /* dlt_daemon_applications_clear(&daemon, 0); */ /* Wrong path filename */ /* app = dlt_daemon_application_add(&daemon,(char *) apid, pid, (char *) desc, 0); */ /* EXPECT_GE(-1, dlt_daemon_applications_load(&daemon, (char *) "PATH_DONT_EXIST", 0)); */ /* dlt_daemon_application_del(&daemon, app, 0); */ /* dlt_daemon_applications_clear(&daemon, 0); */ /* EXPECT_EQ(0, dlt_daemon_free(&daemon, 0)); */ } TEST(t_dlt_daemon_applications_load, nullpointer) { DltDaemon daemon; const char *filename = "/tmp/dlt-runtime.cfg"; /* NULL-Pointer */ EXPECT_GE(-1, dlt_daemon_applications_load(NULL, NULL, 0)); EXPECT_GE(-1, dlt_daemon_applications_load(NULL, (char *)filename, 0)); EXPECT_GE(-1, dlt_daemon_applications_load(&daemon, NULL, 0)); } /* End Method: dlt_daemon_common::dlt_daemon_applications_load */ /*##############################################################################################################################*/ /*##############################################################################################################################*/ /*##############################################################################################################################*/ /* Begin Method: dlt_daemon_common::dlt_daemon_context_add */ TEST(t_dlt_daemon_context_add, normal) { /* Log Level */ /* DLT_LOG_DEFAULT = -1, / **< Default log level * / */ /* DLT_LOG_OFF = 0x00, / **< Log level off * / */ /* DLT_LOG_FATAL = 0x01, / **< fatal system error * / */ /* DLT_LOG_ERROR = 0x02, / **< error with impact to correct functionality * / */ /* DLT_LOG_WARN = 0x03, / **< warning, correct behaviour could not be ensured * / */ /* DLT_LOG_INFO = 0x04, / **< informational * / */ /* DLT_LOG_DEBUG = 0x05, / **< debug * / */ /* DLT_LOG_VERBOSE = 0x06 / **< highest grade of information * / */ /* Trace Status */ /* DLT_TRACE_STATUS_DEFAULT = -1, / **< Default trace status * / */ /* DLT_TRACE_STATUS_OFF = 0x00, / **< Trace status: Off * / */ /* DLT_TRACE_STATUS_ON = 0x01 / **< Trace status: On * / */ DltDaemon daemon; DltGateway gateway; ID4 apid = "TES"; ID4 ctid = "CON"; char desc[255] = "TEST dlt_daemon_context_add"; DltDaemonContext *daecontext = NULL; DltDaemonApplication *app = NULL; char ecu[] = "ECU1"; int fd = 42; /* Normal Use-Case */ EXPECT_EQ(0, dlt_daemon_init(&daemon, DLT_DAEMON_RINGBUFFER_MIN_SIZE, DLT_DAEMON_RINGBUFFER_MAX_SIZE, DLT_DAEMON_RINGBUFFER_STEP_SIZE, DLT_RUNTIME_DEFAULT_DIRECTORY, DLT_LOG_INFO, DLT_TRACE_STATUS_OFF, 0, 0)); dlt_set_id(daemon.ecuid, ecu); EXPECT_EQ(0, dlt_daemon_init_user_information(&daemon, &gateway, 0, 0)); EXPECT_EQ(DLT_RETURN_OK, strncmp(daemon.ecuid, daemon.user_list[0].ecu, DLT_ID_SIZE)); app = dlt_daemon_application_add(&daemon, apid, 0, desc, fd, ecu, 0); daecontext = dlt_daemon_context_add(&daemon, apid, ctid, DLT_LOG_DEFAULT, DLT_TRACE_STATUS_DEFAULT, 0, 0, desc, ecu, 0); /*printf("### CONTEXT: APID=%s\tCTID=%s\n", daecontext->apid,daecontext->ctid); */ EXPECT_STREQ(apid, daecontext->apid); EXPECT_STREQ(ctid, daecontext->ctid); EXPECT_STREQ(desc, daecontext->context_description); EXPECT_EQ(DLT_LOG_DEFAULT, daecontext->log_level); EXPECT_EQ(DLT_TRACE_STATUS_DEFAULT, daecontext->trace_status); EXPECT_LE(0, dlt_daemon_context_del(&daemon, daecontext, ecu, 0)); EXPECT_LE(0, dlt_daemon_application_del(&daemon, app, ecu, 0)); EXPECT_LE(0, dlt_daemon_contexts_clear(&daemon, ecu, 0)); EXPECT_LE(0, dlt_daemon_applications_clear(&daemon, ecu, 0)); EXPECT_EQ(0, dlt_daemon_free(&daemon, 0)); } TEST(t_dlt_daemon_context_add, abnormal) { DltDaemon daemon; DltGateway gateway; ID4 apid = "TES"; ID4 ctid = "CON"; char desc[255] = "TEST dlt_daemon_context_add"; DltDaemonContext *daecontext = NULL; DltDaemonApplication *app = NULL; char ecu[] = "ECU1"; int fd = 42; /* Log Level dont exists */ EXPECT_EQ(0, dlt_daemon_init(&daemon, DLT_DAEMON_RINGBUFFER_MIN_SIZE, DLT_DAEMON_RINGBUFFER_MAX_SIZE, DLT_DAEMON_RINGBUFFER_STEP_SIZE, DLT_RUNTIME_DEFAULT_DIRECTORY, DLT_LOG_INFO, DLT_TRACE_STATUS_OFF, 0, 0)); dlt_set_id(daemon.ecuid, ecu); EXPECT_EQ(0, dlt_daemon_init_user_information(&daemon, &gateway, 0, 0)); EXPECT_EQ(DLT_RETURN_OK, strncmp(daemon.ecuid, daemon.user_list[0].ecu, DLT_ID_SIZE)); DltLogLevelType DLT_LOG_NOT_EXIST = (DltLogLevelType) - 100; app = dlt_daemon_application_add(&daemon, apid, 0, desc, fd, ecu, 0); daecontext = dlt_daemon_context_add(&daemon, apid, ctid, DLT_LOG_NOT_EXIST, DLT_TRACE_STATUS_DEFAULT, 0, 0, desc, ecu, 0); /*printf("### CONTEXT: APID=%s\tCTID=%s\n", daecontext->apid,daecontext->ctid); */ EXPECT_EQ((DltDaemonContext *)0, daecontext); EXPECT_GE(-1, dlt_daemon_context_del(&daemon, daecontext, ecu, 0)); EXPECT_LE(0, dlt_daemon_application_del(&daemon, app, ecu, 0)); EXPECT_LE(0, dlt_daemon_contexts_clear(&daemon, ecu, 0)); EXPECT_LE(0, dlt_daemon_applications_clear(&daemon, ecu, 0)); /* Trace Status dont exists */ DltTraceStatusType DLT_TRACE_TYPE_NOT_EXIST = (DltTraceStatusType) - 100; app = dlt_daemon_application_add(&daemon, apid, 0, desc, fd, ecu, 0); daecontext = dlt_daemon_context_add(&daemon, apid, ctid, DLT_LOG_DEFAULT, DLT_TRACE_TYPE_NOT_EXIST, 0, 0, desc, ecu, 0); /*printf("### CONTEXT: APID=%s\tCTID=%s\n", daecontext->apid,daecontext->ctid); */ EXPECT_EQ((DltDaemonContext *)0, daecontext); EXPECT_GE(-1, dlt_daemon_context_del(&daemon, daecontext, ecu, 0)); EXPECT_LE(0, dlt_daemon_application_del(&daemon, app, ecu, 0)); EXPECT_LE(0, dlt_daemon_contexts_clear(&daemon, ecu, 0)); EXPECT_LE(0, dlt_daemon_applications_clear(&daemon, ecu, 0)); /* Apid to long */ /* char apid_tl[8] = "TO_LONG"; */ /* app = dlt_daemon_application_add(&daemon, apid_tl, 0, desc, 0); */ /* daecontext = dlt_daemon_context_add(&daemon,apid_tl,ctid,DLT_LOG_DEFAULT,DLT_TRACE_STATUS_DEFAULT,0,0,desc,0); */ /* printf("### CONTEXT: APID=%s\tCTID=%s\n", daecontext->apid,daecontext->ctid); */ /* EXPECT_STREQ(apid_tl, daecontext->apid); */ /* EXPECT_STREQ(ctid, daecontext->ctid); */ /* EXPECT_STREQ(desc, daecontext->context_description); */ /* EXPECT_EQ(DLT_LOG_DEFAULT, daecontext->log_level); */ /* EXPECT_EQ(DLT_TRACE_STATUS_DEFAULT, daecontext->trace_status); */ /* dlt_daemon_context_del(&daemon, daecontext, 0); */ /* dlt_daemon_application_del(&daemon, app, 0); */ /* dlt_daemon_contexts_clear(&daemon, 0); */ /* dlt_daemon_applications_clear(&daemon, 0); */ /* Apid to short */ /* char apid_ts[3] = "TS"; */ /* app = dlt_daemon_application_add(&daemon, apid_ts, 0, desc, 0); */ /* daecontext = dlt_daemon_context_add(&daemon,apid_ts,ctid,DLT_LOG_DEFAULT,DLT_TRACE_STATUS_DEFAULT,0,0,desc,0); */ /* //printf("### CONTEXT: APID=%s\tCTID=%s\n", daecontext->apid,daecontext->ctid); */ /* EXPECT_STREQ(apid_ts, daecontext->apid); */ /* EXPECT_STREQ(ctid, daecontext->ctid); */ /* EXPECT_STREQ(desc, daecontext->context_description); */ /* EXPECT_EQ(DLT_LOG_DEFAULT, daecontext->log_level); */ /* EXPECT_EQ(DLT_TRACE_STATUS_DEFAULT, daecontext->trace_status); */ /* //EXPECT_EQ(4, strlen(apid_ts)); */ /* dlt_daemon_context_del(&daemon, daecontext, 0); */ /* dlt_daemon_application_del(&daemon, app, 0); */ /* dlt_daemon_contexts_clear(&daemon, 0); */ /* dlt_daemon_applications_clear(&daemon, 0); */ /* Ctid to long */ /* char ctid_tl[8] = "TO_LONG"; */ /* app = dlt_daemon_application_add(&daemon, apid, 0, desc, 0); */ /* daecontext = dlt_daemon_context_add(&daemon,apid,ctid_tl,DLT_LOG_DEFAULT,DLT_TRACE_STATUS_DEFAULT,0,0,desc,0); */ /* //printf("### CONTEXT: APID=%s\tCTID=%s\n", daecontext->apid,daecontext->ctid); */ /* EXPECT_STREQ(apid, daecontext->apid); */ /* EXPECT_STREQ(ctid_tl, daecontext->ctid); */ /* EXPECT_STREQ(desc, daecontext->context_description); */ /* EXPECT_EQ(DLT_LOG_DEFAULT, daecontext->log_level); */ /* EXPECT_EQ(DLT_TRACE_STATUS_DEFAULT, daecontext->trace_status); */ /* dlt_daemon_context_del(&daemon, daecontext, 0); */ /* dlt_daemon_application_del(&daemon, app, 0); */ /* dlt_daemon_contexts_clear(&daemon, 0); */ /* dlt_daemon_applications_clear(&daemon, 0); */ /* Ctid to short */ /* char ctid_ts[4] = "TS"; */ /* app = dlt_daemon_application_add(&daemon, apid, 0, desc, 0); */ /* daecontext = dlt_daemon_context_add(&daemon,apid,ctid_ts,DLT_LOG_DEFAULT,DLT_TRACE_STATUS_DEFAULT,0,0,desc,0); */ /* //printf("### CONTEXT: APID=%s\tCTID=%s\n", daecontext->apid,daecontext->ctid); */ /* EXPECT_STREQ(apid, daecontext->apid); */ /* EXPECT_STREQ(ctid_ts, daecontext->ctid); */ /* EXPECT_STREQ(desc, daecontext->context_description); */ /* EXPECT_EQ(DLT_LOG_DEFAULT, daecontext->log_level); */ /* EXPECT_EQ(DLT_TRACE_STATUS_DEFAULT, daecontext->trace_status); */ /* dlt_daemon_context_del(&daemon, daecontext, 0); */ /* dlt_daemon_application_del(&daemon, app, 0); */ /* dlt_daemon_contexts_clear(&daemon, 0); */ /* dlt_daemon_applications_clear(&daemon, 0); */ /* Verbose != 0 or 1 */ /* app = dlt_daemon_application_add(&daemon, apid, 0, desc, 0); */ /* daecontext = dlt_daemon_context_add(&daemon,apid,ctid,DLT_LOG_DEFAULT,DLT_TRACE_STATUS_DEFAULT,0,0,desc,123456789); */ /* //printf("### CONTEXT: APID=%s\tCTID=%s\n", daecontext->apid,daecontext->ctid); */ /* EXPECT_EQ((DltDaemonContext *) 0, daecontext); */ /* dlt_daemon_context_del(&daemon, daecontext, 0); */ /* dlt_daemon_application_del(&daemon, app, 0); */ /* dlt_daemon_contexts_clear(&daemon, 0); */ /* dlt_daemon_applications_clear(&daemon, 0); */ EXPECT_EQ(0, dlt_daemon_free(&daemon, 0)); } TEST(t_dlt_daemon_context_add, nullpointer) { DltDaemon daemon; DltGateway gateway; ID4 apid = "TES"; ID4 ctid = "CON"; char ecu[] = "ECU1"; char desc[255] = "TEST dlt_daemon_context_add"; /* NULL-Pointer */ EXPECT_EQ(0, dlt_daemon_init(&daemon, DLT_DAEMON_RINGBUFFER_MIN_SIZE, DLT_DAEMON_RINGBUFFER_MAX_SIZE, DLT_DAEMON_RINGBUFFER_STEP_SIZE, DLT_RUNTIME_DEFAULT_DIRECTORY, DLT_LOG_INFO, DLT_TRACE_STATUS_OFF, 0, 0)); dlt_set_id(daemon.ecuid, ecu); EXPECT_EQ(0, dlt_daemon_init_user_information(&daemon, &gateway, 0, 0)); EXPECT_EQ(DLT_RETURN_OK, strncmp(daemon.ecuid, daemon.user_list[0].ecu, DLT_ID_SIZE)); EXPECT_EQ((DltDaemonContext *)0, dlt_daemon_context_add(NULL, NULL, NULL, 0, 0, 0, 0, NULL, NULL, 0)); EXPECT_EQ((DltDaemonContext *)0, dlt_daemon_context_add(NULL, NULL, NULL, 0, 0, 0, 0, desc, NULL, 0)); EXPECT_EQ((DltDaemonContext *)0, dlt_daemon_context_add(NULL, NULL, ctid, 0, 0, 0, 0, NULL, NULL, 0)); EXPECT_EQ((DltDaemonContext *)0, dlt_daemon_context_add(NULL, NULL, ctid, 0, 0, 0, 0, desc, NULL, 0)); EXPECT_EQ((DltDaemonContext *)0, dlt_daemon_context_add(NULL, apid, NULL, 0, 0, 0, 0, NULL, NULL, 0)); EXPECT_EQ((DltDaemonContext *)0, dlt_daemon_context_add(NULL, apid, NULL, 0, 0, 0, 0, desc, NULL, 0)); EXPECT_EQ((DltDaemonContext *)0, dlt_daemon_context_add(NULL, apid, ctid, 0, 0, 0, 0, NULL, NULL, 0)); EXPECT_EQ((DltDaemonContext *)0, dlt_daemon_context_add(NULL, apid, ctid, 0, 0, 0, 0, desc, NULL, 0)); EXPECT_EQ((DltDaemonContext *)0, dlt_daemon_context_add(&daemon, NULL, NULL, 0, 0, 0, 0, NULL, NULL, 0)); EXPECT_EQ((DltDaemonContext *)0, dlt_daemon_context_add(&daemon, NULL, NULL, 0, 0, 0, 0, desc, NULL, 0)); EXPECT_EQ((DltDaemonContext *)0, dlt_daemon_context_add(&daemon, NULL, ctid, 0, 0, 0, 0, NULL, NULL, 0)); EXPECT_EQ((DltDaemonContext *)0, dlt_daemon_context_add(&daemon, NULL, ctid, 0, 0, 0, 0, desc, NULL, 0)); EXPECT_EQ((DltDaemonContext *)0, dlt_daemon_context_add(&daemon, apid, NULL, 0, 0, 0, 0, NULL, NULL, 0)); EXPECT_EQ((DltDaemonContext *)0, dlt_daemon_context_add(&daemon, apid, NULL, 0, 0, 0, 0, desc, NULL, 0)); EXPECT_EQ((DltDaemonContext *)0, dlt_daemon_context_add(&daemon, apid, ctid, 0, 0, 0, 0, NULL, NULL, 0)); EXPECT_EQ(0, dlt_daemon_free(&daemon, 0)); } /* End Method: dlt_daemon_common::dlt_daemon_context_add */ /* Begin Method: dlt_daemon_common::dlt_daemon_context_del */ TEST(t_dlt_daemon_context_del, normal) { DltDaemon daemon; DltGateway gateway; ID4 apid = "TES"; ID4 ctid = "CON"; char desc[255] = "TEST dlt_daemon_context_add"; DltDaemonContext *daecontext = NULL; DltDaemonApplication *app = NULL; char ecu[] = "ECU1"; int fd = 42; /* Normal Use-Case */ EXPECT_EQ(0, dlt_daemon_init(&daemon, DLT_DAEMON_RINGBUFFER_MIN_SIZE, DLT_DAEMON_RINGBUFFER_MAX_SIZE, DLT_DAEMON_RINGBUFFER_STEP_SIZE, DLT_RUNTIME_DEFAULT_DIRECTORY, DLT_LOG_INFO, DLT_TRACE_STATUS_OFF, 0, 0)); dlt_set_id(daemon.ecuid, ecu); EXPECT_EQ(0, dlt_daemon_init_user_information(&daemon, &gateway, 0, 0)); EXPECT_EQ(DLT_RETURN_OK, strncmp(daemon.ecuid, daemon.user_list[0].ecu, DLT_ID_SIZE)); app = dlt_daemon_application_add(&daemon, apid, 0, desc, fd, ecu, 0); daecontext = dlt_daemon_context_add(&daemon, apid, ctid, DLT_LOG_DEFAULT, DLT_TRACE_STATUS_DEFAULT, 0, 0, desc, ecu, 0); EXPECT_LE(0, dlt_daemon_context_del(&daemon, daecontext, ecu, 0)); EXPECT_LE(0, dlt_daemon_application_del(&daemon, app, ecu, 0)); EXPECT_LE(0, dlt_daemon_contexts_clear(&daemon, ecu, 0)); EXPECT_LE(0, dlt_daemon_applications_clear(&daemon, ecu, 0)); EXPECT_EQ(0, dlt_daemon_free(&daemon, 0)); } TEST(t_dlt_daemon_context_del, abnormal) { /* DltDaemon daemon; */ /* ID4 apid = "TES"; */ /* ID4 ctid = "CON"; */ /* char desc[255] = "TEST dlt_daemon_context_add"; */ /* DltDaemonContext *daecontext; */ /* DltDaemonApplication *app; */ /* Context uninitialized */ /* EXPECT_EQ(0, dlt_daemon_init(&daemon, DLT_DAEMON_RINGBUFFER_MIN_SIZE, DLT_DAEMON_RINGBUFFER_MAX_SIZE, DLT_DAEMON_RINGBUFFER_STEP_SIZE, DLT_RUNTIME_DEFAULT_DIRECTORY,DLT_LOG_INFO, DLT_TRACE_STATUS_OFF,0,0)); */ /* EXPECT_GE(-1, dlt_daemon_context_del(&daemon, daecontext, 0)); */ /* No application used */ /* daecontext = dlt_daemon_context_add(&daemon,apid,ctid,DLT_LOG_DEFAULT,DLT_TRACE_STATUS_DEFAULT,0,0,desc,0); */ /* EXPECT_GE(-1, dlt_daemon_context_del(&daemon, daecontext, 0)); */ /* EXPECT_GE(-1, dlt_daemon_application_del(&daemon, app, 0)); */ /* EXPECT_LE(0, dlt_daemon_contexts_clear(&daemon, 0)); */ /* EXPECT_LE(0, dlt_daemon_applications_clear(&daemon, 0)); */ /* No contex added */ /* app = dlt_daemon_application_add(&daemon, apid, 0, desc, 0); */ /* EXPECT_GE(-1, dlt_daemon_context_del(&daemon, daecontext, 0)); */ /* EXPECT_LE(0, dlt_daemon_application_del(&daemon, app, 0)); */ /* EXPECT_LE(0, dlt_daemon_contexts_clear(&daemon, 0)); */ /* EXPECT_LE(0, dlt_daemon_applications_clear(&daemon, 0)); */ /* Verbose != 0 or 1 */ /* app = dlt_daemon_application_add(&daemon, apid, 0, desc, 0); */ /* daecontext = dlt_daemon_context_add(&daemon,apid,ctid,DLT_LOG_DEFAULT,DLT_TRACE_STATUS_DEFAULT,0,0,desc,0); */ /* EXPECT_GE(-1, dlt_daemon_context_del(&daemon, daecontext, 123456789)); */ /* dlt_daemon_application_del(&daemon, app, 0); */ /* dlt_daemon_contexts_clear(&daemon, 0); */ /* dlt_daemon_applications_clear(&daemon, 0); */ /* EXPECT_EQ(0, dlt_daemon_free(&daemon, 0)); */ } TEST(t_dlt_daemon_context_del, nullpointer) { DltDaemon daemon; DltDaemonContext daecontext; char ecu[] = "ECU1"; /*NULL-Pointer */ EXPECT_GE(-1, dlt_daemon_context_del(NULL, NULL, ecu, 0)); EXPECT_GE(-1, dlt_daemon_context_del(NULL, &daecontext, NULL, 0)); EXPECT_GE(-1, dlt_daemon_context_del(&daemon, NULL, NULL, 0)); } /* End Method: dlt_daemon_common::dlt_daemon_context_del */ /* Begin Method: dlt_daemon_common::dlt_daemon_context_find */ TEST(t_dlt_daemon_context_find, normal) { DltDaemon daemon; DltGateway gateway; ID4 apid = "TES"; ID4 ctid = "CON"; char desc[255] = "TEST dlt_daemon_context_add"; DltDaemonContext *daecontext = NULL; DltDaemonApplication *app = NULL; char ecu[] = "ECU1"; int fd = 42; /* Normal Use-Case */ EXPECT_EQ(0, dlt_daemon_init(&daemon, DLT_DAEMON_RINGBUFFER_MIN_SIZE, DLT_DAEMON_RINGBUFFER_MAX_SIZE, DLT_DAEMON_RINGBUFFER_STEP_SIZE, DLT_RUNTIME_DEFAULT_DIRECTORY, DLT_LOG_INFO, DLT_TRACE_STATUS_OFF, 0, 0)); dlt_set_id(daemon.ecuid, ecu); EXPECT_EQ(0, dlt_daemon_init_user_information(&daemon, &gateway, 0, 0)); EXPECT_EQ(DLT_RETURN_OK, strncmp(daemon.ecuid, daemon.user_list[0].ecu, DLT_ID_SIZE)); app = dlt_daemon_application_add(&daemon, apid, 0, desc, fd, ecu, 0); daecontext = dlt_daemon_context_add(&daemon, apid, ctid, DLT_LOG_DEFAULT, DLT_TRACE_STATUS_DEFAULT, 0, 0, desc, ecu, 0); EXPECT_STREQ(apid, daecontext->apid); EXPECT_STREQ(ctid, daecontext->ctid); EXPECT_STREQ(desc, daecontext->context_description); EXPECT_EQ(DLT_LOG_DEFAULT, daecontext->log_level); EXPECT_EQ(DLT_TRACE_STATUS_DEFAULT, daecontext->trace_status); EXPECT_LE(0, dlt_daemon_context_del(&daemon, daecontext, ecu, 0)); EXPECT_LE(0, dlt_daemon_application_del(&daemon, app, ecu, 0)); EXPECT_LE(0, dlt_daemon_contexts_clear(&daemon, ecu, 0)); EXPECT_LE(0, dlt_daemon_applications_clear(&daemon, ecu, 0)); EXPECT_EQ(0, dlt_daemon_free(&daemon, 0)); } TEST(t_dlt_daemon_context_find, abnormal) { DltDaemon daemon; DltGateway gateway; ID4 apid = "TES"; ID4 ctid = "CON"; char desc[255] = "TEST dlt_daemon_context_add"; DltDaemonContext *daecontext = NULL; DltDaemonApplication *app = NULL; char ecu[] = "ECU1"; int fd = 42; /* Uninitialized */ EXPECT_EQ(0, dlt_daemon_init(&daemon, DLT_DAEMON_RINGBUFFER_MIN_SIZE, DLT_DAEMON_RINGBUFFER_MAX_SIZE, DLT_DAEMON_RINGBUFFER_STEP_SIZE, DLT_RUNTIME_DEFAULT_DIRECTORY, DLT_LOG_INFO, DLT_TRACE_STATUS_OFF, 0, 0)); dlt_set_id(daemon.ecuid, ecu); EXPECT_EQ(0, dlt_daemon_init_user_information(&daemon, &gateway, 0, 0)); EXPECT_EQ(DLT_RETURN_OK, strncmp(daemon.ecuid, daemon.user_list[0].ecu, DLT_ID_SIZE)); EXPECT_EQ((DltDaemonContext *)0, dlt_daemon_context_find(&daemon, apid, ctid, ecu, 0)); /* No apid */ char no_apid[1] = ""; app = dlt_daemon_application_add(&daemon, no_apid, 0, desc, fd, ecu, 0); daecontext = dlt_daemon_context_add(&daemon, no_apid, ctid, DLT_LOG_DEFAULT, DLT_TRACE_STATUS_DEFAULT, 0, 0, desc, ecu, 0); EXPECT_EQ((DltDaemonContext *)0, dlt_daemon_context_find(&daemon, no_apid, ctid, ecu, 0)); EXPECT_GE(-1, dlt_daemon_context_del(&daemon, daecontext, ecu, 0)); EXPECT_GE(-1, dlt_daemon_application_del(&daemon, app, ecu, 0)); EXPECT_LE(0, dlt_daemon_contexts_clear(&daemon, ecu, 0)); EXPECT_LE(0, dlt_daemon_applications_clear(&daemon, ecu, 0)); /* No ctid */ char no_ctid[1] = ""; app = dlt_daemon_application_add(&daemon, apid, 0, desc, fd, ecu, 0); daecontext = dlt_daemon_context_add(&daemon, apid, no_ctid, DLT_LOG_DEFAULT, DLT_TRACE_STATUS_DEFAULT, 0, 0, desc, ecu, 0); EXPECT_EQ((DltDaemonContext *)0, dlt_daemon_context_find(&daemon, apid, no_ctid, ecu, 0)); EXPECT_GE(-1, dlt_daemon_context_del(&daemon, daecontext, ecu, 0)); EXPECT_LE(0, dlt_daemon_application_del(&daemon, app, ecu, 0)); EXPECT_LE(0, dlt_daemon_contexts_clear(&daemon, ecu, 0)); EXPECT_LE(0, dlt_daemon_applications_clear(&daemon, ecu, 0)); /* No application added */ daecontext = dlt_daemon_context_add(&daemon, no_apid, ctid, DLT_LOG_DEFAULT, DLT_TRACE_STATUS_DEFAULT, 0, 0, desc, ecu, 0); EXPECT_EQ((DltDaemonContext *)0, dlt_daemon_context_find(&daemon, no_apid, ctid, ecu, 0)); EXPECT_GE(-1, dlt_daemon_context_del(&daemon, daecontext, ecu, 0)); EXPECT_LE(0, dlt_daemon_contexts_clear(&daemon, ecu, 0)); EXPECT_LE(0, dlt_daemon_applications_clear(&daemon, ecu, 0)); /* Verbose != 0 or 1 */ /* app = dlt_daemon_application_add(&daemon, apid, 0, desc, 0); */ /* daecontext = dlt_daemon_context_add(&daemon,apid,ctid,DLT_LOG_DEFAULT,DLT_TRACE_STATUS_DEFAULT,0,0,desc,0); */ /* EXPECT_EQ((DltDaemonContext *) 0 ,dlt_daemon_context_find(&daemon, apid, ctid, 123456789)); */ /* dlt_daemon_context_del(&daemon, daecontext, 0); */ /* dlt_daemon_application_del(&daemon, app, 0); */ /* dlt_daemon_contexts_clear(&daemon, 0); */ /* dlt_daemon_applications_clear(&daemon, 0); */ EXPECT_EQ(0, dlt_daemon_free(&daemon, 0)); } TEST(t_dlt_daemon_context_find, nullpointer) { DltDaemon daemon; ID4 apid = "TES"; ID4 ctid = "CON"; ID4 ecu = "ECU"; EXPECT_EQ((DltDaemonContext *)0, dlt_daemon_context_find(NULL, NULL, NULL, NULL, 0)); EXPECT_EQ((DltDaemonContext *)0, dlt_daemon_context_find(NULL, NULL, ctid, NULL, 0)); EXPECT_EQ((DltDaemonContext *)0, dlt_daemon_context_find(NULL, apid, NULL, NULL, 0)); EXPECT_EQ((DltDaemonContext *)0, dlt_daemon_context_find(NULL, apid, ctid, NULL, 0)); EXPECT_EQ((DltDaemonContext *)0, dlt_daemon_context_find(&daemon, NULL, NULL, NULL, 0)); EXPECT_EQ((DltDaemonContext *)0, dlt_daemon_context_find(&daemon, NULL, ctid, NULL, 0)); EXPECT_EQ((DltDaemonContext *)0, dlt_daemon_context_find(&daemon, apid, NULL, NULL, 0)); EXPECT_EQ((DltDaemonContext *)0, dlt_daemon_context_find(&daemon, NULL, NULL, ecu, 0)); } /* End Method: dlt_daemon_common::dlt_daemon_context_find */ /* Begin Method: dlt_daemon_common::dlt_daemon_contexts_clear */ TEST(t_dlt_daemon_contexts_clear, normal) { DltDaemon daemon; DltGateway gateway; ID4 apid = "TES"; ID4 ctid = "CON"; char desc[255] = "TEST dlt_daemon_context_add"; DltDaemonContext *daecontext = NULL; DltDaemonApplication *app = NULL; char ecu[] = "ECU1"; int fd = 42; /* Normal Use-Case */ EXPECT_EQ(0, dlt_daemon_init(&daemon, DLT_DAEMON_RINGBUFFER_MIN_SIZE, DLT_DAEMON_RINGBUFFER_MAX_SIZE, DLT_DAEMON_RINGBUFFER_STEP_SIZE, DLT_RUNTIME_DEFAULT_DIRECTORY, DLT_LOG_INFO, DLT_TRACE_STATUS_OFF, 0, 0)); dlt_set_id(daemon.ecuid, ecu); EXPECT_EQ(0, dlt_daemon_init_user_information(&daemon, &gateway, 0, 0)); EXPECT_EQ(DLT_RETURN_OK, strncmp(daemon.ecuid, daemon.user_list[0].ecu, DLT_ID_SIZE)); app = dlt_daemon_application_add(&daemon, apid, 0, desc, fd, ecu, 0); daecontext = dlt_daemon_context_add(&daemon, apid, ctid, DLT_LOG_DEFAULT, DLT_TRACE_STATUS_DEFAULT, 0, 0, desc, ecu, 0); EXPECT_LE(0, dlt_daemon_context_del(&daemon, daecontext, ecu, 0)); EXPECT_LE(0, dlt_daemon_application_del(&daemon, app, ecu, 0)); EXPECT_LE(0, dlt_daemon_contexts_clear(&daemon, ecu, 0)); EXPECT_LE(0, dlt_daemon_applications_clear(&daemon, ecu, 0)); EXPECT_EQ(0, dlt_daemon_free(&daemon, 0)); } TEST(t_dlt_daemon_contexts_clear, abnormal) { /* DltDaemon daemon; */ /* ID4 apid = "TES"; */ /* ID4 ctid = "CON"; */ /* char desc[255] = "TEST dlt_daemon_context_add"; */ /* DltDaemonContext *daecontext = NULL; */ /* DltDaemonApplication *app = NULL; */ /* No context added */ /* EXPECT_EQ(0, dlt_daemon_init(&daemon, DLT_DAEMON_RINGBUFFER_MIN_SIZE, DLT_DAEMON_RINGBUFFER_MAX_SIZE, DLT_DAEMON_RINGBUFFER_STEP_SIZE, DLT_RUNTIME_DEFAULT_DIRECTORY,DLT_LOG_INFO, DLT_TRACE_STATUS_OFF,0,0)); */ /* EXPECT_GE(-1, dlt_daemon_contexts_clear(&daemon, 0)); */ /* Verbose != 0 or 1 */ /* app = dlt_daemon_application_add(&daemon, apid, 0, desc, 0); */ /* daecontext = dlt_daemon_context_add(&daemon,apid,ctid,DLT_LOG_DEFAULT,DLT_TRACE_STATUS_DEFAULT,0,0,desc,0); */ /* dlt_daemon_context_del(&daemon, daecontext, 0); */ /* dlt_daemon_application_del(&daemon, app, 0); */ /* EXPECT_LE(0, dlt_daemon_contexts_clear(&daemon, 123456789)); */ /* dlt_daemon_applications_clear(&daemon, 0); */ /* EXPECT_EQ(0, dlt_daemon_free(&daemon, 0)); */ } TEST(t_dlt_daemon_contexts_clear, nullpointer) { /* NULL-Pointer */ EXPECT_GE(-1, dlt_daemon_contexts_clear(NULL, NULL, 0)); } /* End Method: dlt_daemon_common::dlt_daemon_contexts_clear */ /* Begin Method: dlt_daemon_common::dlt_daemon_contexts_invalidate_fd */ TEST(t_dlt_daemon_contexts_invalidate_fd, normal) { DltDaemon daemon; DltGateway gateway; ID4 apid = "TES"; ID4 ctid = "CON"; char desc[255] = "TEST dlt_daemon_context_add"; DltDaemonContext *daecontext = NULL; DltDaemonApplication *app = NULL; char ecu[] = "ECU1"; int fd = 42; /* Normal Use-Case */ EXPECT_EQ(0, dlt_daemon_init(&daemon, DLT_DAEMON_RINGBUFFER_MIN_SIZE, DLT_DAEMON_RINGBUFFER_MAX_SIZE, DLT_DAEMON_RINGBUFFER_STEP_SIZE, DLT_RUNTIME_DEFAULT_DIRECTORY, DLT_LOG_INFO, DLT_TRACE_STATUS_OFF, 0, 0)); dlt_set_id(daemon.ecuid, ecu); EXPECT_EQ(0, dlt_daemon_init_user_information(&daemon, &gateway, 0, 0)); EXPECT_EQ(DLT_RETURN_OK, strncmp(daemon.ecuid, daemon.user_list[0].ecu, DLT_ID_SIZE)); app = dlt_daemon_application_add(&daemon, apid, 0, desc, fd, ecu, 0); daecontext = dlt_daemon_context_add(&daemon, apid, ctid, DLT_LOG_DEFAULT, DLT_TRACE_STATUS_DEFAULT, 0, 0, desc, ecu, 0); EXPECT_LE(0, dlt_daemon_contexts_invalidate_fd(&daemon, ecu, app->user_handle, 0)); EXPECT_LE(0, dlt_daemon_context_del(&daemon, daecontext, ecu, 0)); EXPECT_LE(0, dlt_daemon_application_del(&daemon, app, ecu, 0)); EXPECT_LE(0, dlt_daemon_contexts_clear(&daemon, ecu, 0)); EXPECT_LE(0, dlt_daemon_applications_clear(&daemon, ecu, 0)); EXPECT_EQ(0, dlt_daemon_free(&daemon, 0)); } TEST(t_dlt_daemon_contexts_invalidate_fd, abnormal) { /* DltDaemon daemon; */ /* ID4 apid = "TES"; */ /* ID4 ctid = "CON"; */ /* char desc[255] = "TEST dlt_daemon_context_add"; */ /* DltDaemonContext *daecontext = NULL; */ /* DltDaemonApplication *app = NULL; */ /* Uninitialized */ /* EXPECT_EQ(0, dlt_daemon_init(&daemon, DLT_DAEMON_RINGBUFFER_MIN_SIZE, DLT_DAEMON_RINGBUFFER_MAX_SIZE, DLT_DAEMON_RINGBUFFER_STEP_SIZE, DLT_RUNTIME_DEFAULT_DIRECTORY,DLT_LOG_INFO, DLT_TRACE_STATUS_OFF,0,0)); */ /* EXPECT_GE(-1, dlt_daemon_contexts_invalidate_fd(&daemon, app->user_handle, 0)); */ /* Verbose != 0 or 1 */ /* app = dlt_daemon_application_add(&daemon, apid, 0, desc, 0); */ /* daecontext = dlt_daemon_context_add(&daemon,apid,ctid,DLT_LOG_DEFAULT,DLT_TRACE_STATUS_DEFAULT,0,0,desc,0); */ /* EXPECT_GE(-1, dlt_daemon_contexts_invalidate_fd(&daemon, app->user_handle, 123456789)); */ /* dlt_daemon_context_del(&daemon, daecontext, 0); */ /* dlt_daemon_application_del(&daemon, app, 0); */ /* dlt_daemon_contexts_clear(&daemon, 0); */ /* dlt_daemon_applications_clear(&daemon, 0); */ /* EXPECT_EQ(0, dlt_daemon_free(&daemon, 0)); */ } TEST(t_dlt_daemon_contexts_invalidate_fd, nullpointer) { /* NULL-Pointer */ EXPECT_GE(-1, dlt_daemon_contexts_invalidate_fd(NULL, NULL, 0, 0)); } /* End Method: dlt_daemon_common::dlt_daemon_contexts_invalidate_fd */ /* Begin Method: dlt_daemon_common::dlt_daemon_contexts_save */ TEST(t_dlt_daemon_contexts_save, normal) { DltDaemon daemon; DltGateway gateway; ID4 apid = "TES"; ID4 ctid = "CON"; char desc[255] = "TEST dlt_daemon_context_add"; DltDaemonContext *daecontext = NULL; DltDaemonApplication *app = NULL; const char *filename = "/tmp/dlt-runtime-context.cfg"; char ecu[] = "ECU1"; int fd = 42; /* Normal Use-Case */ EXPECT_EQ(0, dlt_daemon_init(&daemon, DLT_DAEMON_RINGBUFFER_MIN_SIZE, DLT_DAEMON_RINGBUFFER_MAX_SIZE, DLT_DAEMON_RINGBUFFER_STEP_SIZE, DLT_RUNTIME_DEFAULT_DIRECTORY, DLT_LOG_INFO, DLT_TRACE_STATUS_OFF, 0, 0)); dlt_set_id(daemon.ecuid, ecu); EXPECT_EQ(0, dlt_daemon_init_user_information(&daemon, &gateway, 0, 0)); EXPECT_EQ(DLT_RETURN_OK, strncmp(daemon.ecuid, daemon.user_list[0].ecu, DLT_ID_SIZE)); app = dlt_daemon_application_add(&daemon, apid, 0, desc, fd, ecu, 0); daecontext = dlt_daemon_context_add(&daemon, apid, ctid, DLT_LOG_DEFAULT, DLT_TRACE_STATUS_DEFAULT, 0, 0, desc, ecu, 0); EXPECT_LE(0, dlt_daemon_contexts_save(&daemon, filename, 0)); EXPECT_LE(0, dlt_daemon_context_del(&daemon, daecontext, ecu, 0)); EXPECT_LE(0, dlt_daemon_application_del(&daemon, app, ecu, 0)); EXPECT_LE(0, dlt_daemon_contexts_clear(&daemon, ecu, 0)); EXPECT_LE(0, dlt_daemon_applications_clear(&daemon, ecu, 0)); EXPECT_EQ(0, dlt_daemon_free(&daemon, 0)); } TEST(t_dlt_daemon_contexts_save, abnormal) { /* DltDaemon daemon; */ /* ID4 apid = "TES"; */ /* ID4 ctid = "CON"; */ /* char desc[255] = "TEST dlt_daemon_context_add"; */ /* DltDaemonContext *daecontext = NULL; */ /* DltDaemonApplication *app = NULL; */ /* const char * filename = "/tmp/dlt-runtime-context.cfg"; */ /* Uninitialized */ /* EXPECT_EQ(0, dlt_daemon_init(&daemon, DLT_DAEMON_RINGBUFFER_MIN_SIZE, DLT_DAEMON_RINGBUFFER_MAX_SIZE, DLT_DAEMON_RINGBUFFER_STEP_SIZE, DLT_RUNTIME_DEFAULT_DIRECTORY,DLT_LOG_INFO, DLT_TRACE_STATUS_OFF,0,0)); */ /* EXPECT_GE(-1, dlt_daemon_contexts_save(&daemon, filename, 0)); */ /* Verbose != 1 or 0, expect error */ /* app = dlt_daemon_application_add(&daemon, apid, 0, desc, 0); */ /* daecontext = dlt_daemon_context_add(&daemon,apid,ctid,DLT_LOG_DEFAULT,DLT_TRACE_STATUS_DEFAULT,0,0,desc,0); */ /* EXPECT_GE(-1, dlt_daemon_contexts_save(&daemon, filename, 123456789)); */ /* dlt_daemon_context_del(&daemon, daecontext, 0); */ /* dlt_daemon_application_del(&daemon, app, 0); */ /* dlt_daemon_contexts_clear(&daemon, 0); */ /* dlt_daemon_applications_clear(&daemon, 0); */ /* Wrong path filename */ /* app = dlt_daemon_application_add(&daemon, apid, 0, desc, 0); */ /* daecontext = dlt_daemon_context_add(&daemon,apid,ctid,DLT_LOG_DEFAULT,DLT_TRACE_STATUS_DEFAULT,0,0,desc,0); */ /* EXPECT_GE(-1, dlt_daemon_contexts_save(&daemon, (char *) "PATCH_NOT_EXISTS", 0)); */ /* dlt_daemon_context_del(&daemon, daecontext, 0); */ /* dlt_daemon_application_del(&daemon, app, 0); */ /* dlt_daemon_contexts_clear(&daemon, 0); */ /* dlt_daemon_applications_clear(&daemon, 0); */ /* EXPECT_EQ(0, dlt_daemon_free(&daemon, 0)); */ } TEST(t_dlt_daemon_contexts_save, nullpointer) { DltDaemon daemon; const char *filename = "/tmp/dlt-runtime-context.cfg"; /* NULL-Pointer */ EXPECT_GE(-1, dlt_daemon_contexts_save(NULL, NULL, 0)); EXPECT_GE(-1, dlt_daemon_contexts_save(NULL, filename, 0)); EXPECT_GE(-1, dlt_daemon_contexts_save(&daemon, NULL, 0)); } /* End Method: dlt_daemon_common::dlt_daemon_contexts_save */ /* Begin Method: dlt_daemon_common::dlt_daemon_contexts_load */ TEST(t_dlt_daemon_contexts_load, normal) { DltDaemon daemon; DltGateway gateway; ID4 apid = "TES"; ID4 ctid = "CON"; char desc[255] = "TEST dlt_daemon_context_add"; DltDaemonContext *daecontext = NULL; DltDaemonApplication *app = NULL; const char *filename = "/tmp/dlt-runtime-context.cfg"; char ecu[] = "ECU1"; int fd = 42; /* Normal Use-Case */ EXPECT_EQ(0, dlt_daemon_init(&daemon, DLT_DAEMON_RINGBUFFER_MIN_SIZE, DLT_DAEMON_RINGBUFFER_MAX_SIZE, DLT_DAEMON_RINGBUFFER_STEP_SIZE, DLT_RUNTIME_DEFAULT_DIRECTORY, DLT_LOG_INFO, DLT_TRACE_STATUS_OFF, 0, 0)); dlt_set_id(daemon.ecuid, ecu); EXPECT_EQ(0, dlt_daemon_init_user_information(&daemon, &gateway, 0, 0)); EXPECT_EQ(DLT_RETURN_OK, strncmp(daemon.ecuid, daemon.user_list[0].ecu, DLT_ID_SIZE)); app = dlt_daemon_application_add(&daemon, apid, 0, desc, fd, ecu, 0); daecontext = dlt_daemon_context_add(&daemon, apid, ctid, DLT_LOG_DEFAULT, DLT_TRACE_STATUS_DEFAULT, 0, 0, desc, ecu, 0); EXPECT_LE(0, dlt_daemon_contexts_load(&daemon, filename, 0)); EXPECT_LE(0, dlt_daemon_context_del(&daemon, daecontext, ecu, 0)); EXPECT_LE(0, dlt_daemon_application_del(&daemon, app, ecu, 0)); EXPECT_LE(0, dlt_daemon_contexts_clear(&daemon, ecu, 0)); EXPECT_LE(0, dlt_daemon_applications_clear(&daemon, ecu, 0)); EXPECT_EQ(0, dlt_daemon_free(&daemon, 0)); } TEST(t_dlt_daemon_contexts_load, abnormal) { /* DltDaemon daemon; */ /* ID4 apid = "TES"; */ /* ID4 ctid = "CON"; */ /* char desc[255] = "TEST dlt_daemon_context_add"; */ /* DltDaemonContext *daecontext = NULL; */ /* DltDaemonApplication *app = NULL; */ /* const char * filename = "/tmp/dlt-runtime-context.cfg"; */ /* Uninitialized */ /* EXPECT_EQ(0, dlt_daemon_init(&daemon, DLT_DAEMON_RINGBUFFER_MIN_SIZE, DLT_DAEMON_RINGBUFFER_MAX_SIZE, DLT_DAEMON_RINGBUFFER_STEP_SIZE, DLT_RUNTIME_DEFAULT_DIRECTORY,DLT_LOG_INFO, DLT_TRACE_STATUS_OFF,0,0)); */ /* EXPECT_GE(-1, dlt_daemon_contexts_load(&daemon, filename, 0)); */ /* Verbose != 1 or 0, expect error */ /* app = dlt_daemon_application_add(&daemon, apid, 0, desc, 0); */ /* daecontext = dlt_daemon_context_add(&daemon,apid,ctid,DLT_LOG_DEFAULT,DLT_TRACE_STATUS_DEFAULT,0,0,desc,0); */ /* EXPECT_GE(-1, dlt_daemon_contexts_load(&daemon, filename, 123456789)); */ /* dlt_daemon_context_del(&daemon, daecontext, 0); */ /* dlt_daemon_application_del(&daemon, app, 0); */ /* dlt_daemon_contexts_clear(&daemon, 0); */ /* dlt_daemon_applications_clear(&daemon, 0); */ /* Wrong path filename */ /* app = dlt_daemon_application_add(&daemon, apid, 0, desc, 0); */ /* daecontext = dlt_daemon_context_add(&daemon,apid,ctid,DLT_LOG_DEFAULT,DLT_TRACE_STATUS_DEFAULT,0,0,desc,0); */ /* EXPECT_GE(-1, dlt_daemon_contexts_load(&daemon, (char *) "PATCH_NOT_EXISTS", 0)); */ /* dlt_daemon_context_del(&daemon, daecontext, 0); */ /* dlt_daemon_application_del(&daemon, app, 0); */ /* dlt_daemon_contexts_clear(&daemon, 0); */ /* dlt_daemon_applications_clear(&daemon, 0); */ /* EXPECT_EQ(0, dlt_daemon_free(&daemon, 0)); */ } TEST(t_dlt_daemon_contexts_load, nullpointer) { DltDaemon daemon; const char *filename = "/tmp/dlt-runtime-context.cfg"; /* NULL-Pointer */ EXPECT_GE(-1, dlt_daemon_contexts_load(NULL, NULL, 0)); EXPECT_GE(-1, dlt_daemon_contexts_load(NULL, filename, 0)); EXPECT_GE(-1, dlt_daemon_contexts_load(&daemon, NULL, 0)); } /* End Method: dlt_daemon_common::dlt_daemon_contexts_load */ /*##############################################################################################################################*/ /*##############################################################################################################################*/ /*##############################################################################################################################*/ /* Begin Method: dlt_daemon_common::dlt_daemon_user_send_all_log_state */ /* Can't test this Method, maybe a return value would be a better solution */ TEST(t_dlt_daemon_user_send_all_log_state, normal) { DltDaemon daemon; DltGateway gateway; char ecu[] = "ECU1"; /* Normal Use-Case */ EXPECT_EQ(0, dlt_daemon_init(&daemon, DLT_DAEMON_RINGBUFFER_MIN_SIZE, DLT_DAEMON_RINGBUFFER_MAX_SIZE, DLT_DAEMON_RINGBUFFER_STEP_SIZE, DLT_RUNTIME_DEFAULT_DIRECTORY, DLT_LOG_INFO, DLT_TRACE_STATUS_OFF, 0, 0)); dlt_set_id(daemon.ecuid, ecu); EXPECT_EQ(0, dlt_daemon_init_user_information(&daemon, &gateway, 0, 0)); EXPECT_EQ(DLT_RETURN_OK, strncmp(daemon.ecuid, daemon.user_list[0].ecu, DLT_ID_SIZE)); EXPECT_NO_FATAL_FAILURE(dlt_daemon_user_send_all_log_state(&daemon, 0)); EXPECT_EQ(0, dlt_daemon_free(&daemon, 0)); } TEST(t_dlt_daemon_user_send_all_log_state, abnormal) {} TEST(t_dlt_daemon_user_send_all_log_state, nullpointer) { EXPECT_NO_FATAL_FAILURE(dlt_daemon_user_send_all_log_state(NULL, 0)); } /* End Method: dlt_daemon_common::dlt_daemon_user_send_all_log_state */ /* Begin Method: dlt_daemon_common::dlt_daemon_user_send_default_update */ /* Can't test this Method, maybe a return value would be a better solution */ TEST(t_dlt_daemon_user_send_default_update, normal) { DltDaemon daemon; DltGateway gateway; char ecu[] = "ECU1"; /* Normal Use-Case */ EXPECT_EQ(0, dlt_daemon_init(&daemon, DLT_DAEMON_RINGBUFFER_MIN_SIZE, DLT_DAEMON_RINGBUFFER_MAX_SIZE, DLT_DAEMON_RINGBUFFER_STEP_SIZE, DLT_RUNTIME_DEFAULT_DIRECTORY, DLT_LOG_INFO, DLT_TRACE_STATUS_OFF, 0, 0)); dlt_set_id(daemon.ecuid, ecu); EXPECT_EQ(0, dlt_daemon_init_user_information(&daemon, &gateway, 0, 0)); EXPECT_EQ(DLT_RETURN_OK, strncmp(daemon.ecuid, daemon.user_list[0].ecu, DLT_ID_SIZE)); EXPECT_NO_FATAL_FAILURE(dlt_daemon_user_send_default_update(&daemon, 0)); EXPECT_EQ(0, dlt_daemon_free(&daemon, 0)); } TEST(t_dlt_daemon_user_send_default_update, abnormal) {} TEST(t_dlt_daemon_user_send_default_update, nullpointer) { EXPECT_NO_FATAL_FAILURE(dlt_daemon_user_send_default_update(NULL, 0)); } /* End Method: dlt_daemon_common::dlt_daemon_user_send_default_update */ /* Begin Method: dlt_daemon_common::dlt_daemon_user_send_log_level */ TEST(t_dlt_daemon_user_send_log_level, normal) { DltDaemon daemon; DltGateway gateway; ID4 apid = "TES"; ID4 ctid = "CON"; char desc[255] = "TEST dlt_daemon_context_add"; DltDaemonContext *daecontext = NULL; DltDaemonApplication *app = NULL; char ecu[] = "ECU1"; int fd = 42; /* Normal Use-Case */ EXPECT_EQ(0, dlt_daemon_init(&daemon, DLT_DAEMON_RINGBUFFER_MIN_SIZE, DLT_DAEMON_RINGBUFFER_MAX_SIZE, DLT_DAEMON_RINGBUFFER_STEP_SIZE, DLT_RUNTIME_DEFAULT_DIRECTORY, DLT_LOG_INFO, DLT_TRACE_STATUS_OFF, 0, 0)); dlt_set_id(daemon.ecuid, ecu); EXPECT_EQ(0, dlt_daemon_init_user_information(&daemon, &gateway, 0, 0)); EXPECT_EQ(DLT_RETURN_OK, strncmp(daemon.ecuid, daemon.user_list[0].ecu, DLT_ID_SIZE)); app = dlt_daemon_application_add(&daemon, apid, 0, desc, fd, ecu, 0); daecontext = dlt_daemon_context_add(&daemon, apid, ctid, DLT_LOG_DEFAULT, DLT_TRACE_STATUS_DEFAULT, 0, 1, desc, ecu, 0); EXPECT_LE(0, dlt_daemon_user_send_log_level(&daemon, daecontext, 0)); EXPECT_LE(0, dlt_daemon_context_del(&daemon, daecontext, ecu, 0)); EXPECT_LE(0, dlt_daemon_application_del(&daemon, app, ecu, 0)); EXPECT_LE(0, dlt_daemon_contexts_clear(&daemon, ecu, 0)); EXPECT_LE(0, dlt_daemon_applications_clear(&daemon, ecu, 0)); EXPECT_EQ(0, dlt_daemon_free(&daemon, 0)); } TEST(t_dlt_daemon_user_send_log_level, abnormal) { /* DltDaemon daemon; */ /* ID4 apid = "TES"; */ /* ID4 ctid = "CON"; */ /* char desc[255] = "TEST dlt_daemon_context_add"; */ /* DltDaemonContext *daecontext = NULL; */ /* DltDaemonApplication *app = NULL; */ /* Uninitialized */ /* EXPECT_EQ(0, dlt_daemon_init(&daemon, DLT_DAEMON_RINGBUFFER_MIN_SIZE, DLT_DAEMON_RINGBUFFER_MAX_SIZE, DLT_DAEMON_RINGBUFFER_STEP_SIZE, DLT_RUNTIME_DEFAULT_DIRECTORY,DLT_LOG_INFO, DLT_TRACE_STATUS_OFF,0,0)); */ /* EXPECT_GE(-1, dlt_daemon_user_send_log_level(&daemon, daecontext, 0)); */ /* File Handler <= 0 */ /* app = dlt_daemon_application_add(&daemon, apid, 0, desc, 0); */ /* daecontext = dlt_daemon_context_add(&daemon,apid,ctid,DLT_LOG_DEFAULT,DLT_TRACE_STATUS_DEFAULT,0,-1,desc,0); */ /* EXPECT_GE(-1, dlt_daemon_user_send_log_level(&daemon, daecontext, 0)); */ /* EXPECT_LE(0, dlt_daemon_context_del(&daemon, daecontext, 0)); */ /* EXPECT_LE(0, dlt_daemon_application_del(&daemon, app, 0)); */ /* EXPECT_LE(0, dlt_daemon_contexts_clear(&daemon, 0)); */ /* EXPECT_LE(0, dlt_daemon_applications_clear(&daemon, 0)); */ /* Verbose != 0 or 1 */ /* app = dlt_daemon_application_add(&daemon, apid, 0, desc, 0); */ /* daecontext = dlt_daemon_context_add(&daemon,apid,ctid,DLT_LOG_DEFAULT,DLT_TRACE_STATUS_DEFAULT,0,1,desc,0); */ /* EXPECT_GE(-1, dlt_daemon_user_send_log_level(&daemon, daecontext, 123456789)); */ /* dlt_daemon_context_del(&daemon, daecontext, 0); */ /* dlt_daemon_application_del(&daemon, app, 0); */ /* dlt_daemon_contexts_clear(&daemon, 0); */ /* dlt_daemon_applications_clear(&daemon, 0); */ /* EXPECT_EQ(0, dlt_daemon_free(&daemon, 0)); */ } TEST(t_dlt_daemon_user_send_log_level, nullpointer) { DltDaemon daemon; DltDaemonContext daecontext; /* NULL-Pointer */ EXPECT_GE(-1, dlt_daemon_user_send_log_level(NULL, NULL, 0)); EXPECT_GE(-1, dlt_daemon_user_send_log_level(NULL, &daecontext, 0)); EXPECT_GE(-1, dlt_daemon_user_send_log_level(&daemon, NULL, 0)); } /* End Method: dlt_daemon_common::dlt_daemon_user_send_log_level */ /* Begin Method: dlt_daemon_common::dlt_daemon_user_send_log_state */ TEST(t_dlt_daemon_user_send_log_state, normal) { DltDaemon daemon; DltGateway gateway; /* ID4 apid = "TES"; */ /* ID4 ctid = "CON"; */ /* char desc[255] = "TEST dlt_daemon_context_add"; */ /* DltDaemonContext *daecontext; */ /* DltDaemonApplication *app; */ pid_t pid = 18166; char ecu[] = "ECU1"; char filename[DLT_DAEMON_COMMON_TEXTBUFSIZE + 1]; snprintf(filename, DLT_DAEMON_COMMON_TEXTBUFSIZE, "%s/dlt%d", DLT_USER_DIR, pid); /* Normal Use-Case */ EXPECT_EQ(0, dlt_daemon_init(&daemon, DLT_DAEMON_RINGBUFFER_MIN_SIZE, DLT_DAEMON_RINGBUFFER_MAX_SIZE, DLT_DAEMON_RINGBUFFER_STEP_SIZE, DLT_RUNTIME_DEFAULT_DIRECTORY, DLT_LOG_INFO, DLT_TRACE_STATUS_OFF, 0, 0)); dlt_set_id(daemon.ecuid, ecu); EXPECT_EQ(0, dlt_daemon_init_user_information(&daemon, &gateway, 0, 0)); EXPECT_EQ(DLT_RETURN_OK, strncmp(daemon.ecuid, daemon.user_list[0].ecu, DLT_ID_SIZE)); /* open(filename, O_RDWR |O_NONBLOCK); */ /* dlt_daemon_init(&daemon, DLT_DAEMON_RINGBUFFER_MIN_SIZE, DLT_DAEMON_RINGBUFFER_MAX_SIZE, DLT_DAEMON_RINGBUFFER_STEP_SIZE, "",0); */ /* app = dlt_daemon_application_add(&daemon, apid, pid, desc, 0); */ /* //printf("### USERHANDLE=%i\n", app->user_handle); */ /* daecontext = dlt_daemon_context_add(&daemon,apid,ctid,DLT_LOG_DEFAULT,DLT_TRACE_STATUS_DEFAULT,0,0,desc,0); */ /* EXPECT_GE(0, dlt_daemon_user_send_log_state(&daemon, app, 0)); */ /* EXPECT_LE(0, dlt_daemon_context_del(&daemon, daecontext, 0)); */ /* EXPECT_LE(0, dlt_daemon_application_del(&daemon, app, 0)); */ /* EXPECT_LE(0, dlt_daemon_contexts_clear(&daemon, 0)); */ /* EXPECT_LE(0, dlt_daemon_applications_clear(&daemon, 0)); */ /* EXPECT_LE(0, close(app->user_handle)); */ EXPECT_EQ(0, dlt_daemon_free(&daemon, 0)); } TEST(t_dlt_daemon_user_send_log_state, abnormal) { /* DltDaemon daemon; */ /* ID4 apid = "TES"; */ /* ID4 ctid = "CON"; */ /* char desc[255] = "TEST dlt_daemon_context_add"; */ /* DltDaemonContext *daecontext = NULL; */ /* DltDaemonApplication *app = NULL; */ /* pid_t pid = 18166; */ /* char filename[DLT_DAEMON_COMMON_TEXTBUFSIZE+1]; */ /* snprintf(filename,DLT_DAEMON_COMMON_TEXTBUFSIZE,"%s/dlt%d",DLT_USER_DIR,pid); */ /*Uninitialized */ /* EXPECT_EQ(0, dlt_daemon_init(&daemon, DLT_DAEMON_RINGBUFFER_MIN_SIZE, DLT_DAEMON_RINGBUFFER_MAX_SIZE, DLT_DAEMON_RINGBUFFER_STEP_SIZE, DLT_RUNTIME_DEFAULT_DIRECTORY,DLT_LOG_INFO, DLT_TRACE_STATUS_OFF,0,0)); */ /* EXPECT_GE(-1, dlt_daemon_user_send_log_state(&daemon, app, 0)); */ /* No Pipe open */ /*open(filename, O_RDWR |O_NONBLOCK); */ /* dlt_daemon_init(&daemon, DLT_DAEMON_RINGBUFFER_MIN_SIZE, DLT_DAEMON_RINGBUFFER_MAX_SIZE, DLT_DAEMON_RINGBUFFER_STEP_SIZE, "",0); */ /* app = dlt_daemon_application_add(&daemon, apid, pid, desc, 0); */ /*printf("### USERHANDLE=%i\n", app->user_handle); */ /* daecontext = dlt_daemon_context_add(&daemon,apid,ctid,DLT_LOG_DEFAULT,DLT_TRACE_STATUS_DEFAULT,0,0,desc,0); */ /* EXPECT_GE(-1, dlt_daemon_user_send_log_state(&daemon, app, 0)); */ /* EXPECT_LE(0, dlt_daemon_context_del(&daemon, daecontext, 0)); */ /* EXPECT_LE(0, dlt_daemon_application_del(&daemon, app, 0)); */ /* EXPECT_LE(0, dlt_daemon_contexts_clear(&daemon, 0)); */ /* EXPECT_LE(0, dlt_daemon_applications_clear(&daemon, 0)); */ /* EXPECT_LE(0, close(app->user_handle)); */ /* Verbose != 1 or 0 */ /* open(filename, O_RDWR |O_NONBLOCK); */ /* dlt_daemon_init(&daemon, DLT_DAEMON_RINGBUFFER_MIN_SIZE, DLT_DAEMON_RINGBUFFER_MAX_SIZE, DLT_DAEMON_RINGBUFFER_STEP_SIZE, "",0); */ /* app = dlt_daemon_application_add(&daemon, apid, pid, desc, 0); */ /* //printf("### USERHANDLE=%i\n", app->user_handle); */ /* daecontext = dlt_daemon_context_add(&daemon,apid,ctid,DLT_LOG_DEFAULT,DLT_TRACE_STATUS_DEFAULT,0,0,desc,0); */ /* EXPECT_GE(-1, dlt_daemon_user_send_log_state(&daemon, app, 123456789)); */ /* dlt_daemon_context_del(&daemon, daecontext, 0); */ /* dlt_daemon_application_del(&daemon, app, 0); */ /* dlt_daemon_contexts_clear(&daemon, 0); */ /* dlt_daemon_applications_clear(&daemon, 0); */ /* close(app->user_handle); */ /* EXPECT_EQ(0, dlt_daemon_free(&daemon, 0)); */ } TEST(t_dlt_daemon_user_send_log_state, nullpointer) { DltDaemon daemon; DltDaemonApplication app; EXPECT_GE(0, dlt_daemon_user_send_log_state(NULL, NULL, 0)); EXPECT_GE(0, dlt_daemon_user_send_log_state(NULL, &app, 0)); EXPECT_GE(0, dlt_daemon_user_send_log_state(&daemon, NULL, 0)); } /* End Method: dlt_daemon_common::dlt_daemon_user_send_log_state */ /*##############################################################################################################################*/ /*##############################################################################################################################*/ /*##############################################################################################################################*/ int main(int argc, char **argv) { ::testing::InitGoogleTest(&argc, argv); ::testing::FLAGS_gtest_break_on_failure = true; /*::testing::FLAGS_gtest_filter = "*.normal"; */ /*::testing::FLAGS_gtest_repeat = 10000; */ return RUN_ALL_TESTS(); } dlt-daemon-2.18.4/tests/gtest_dlt_daemon_event_handler.cpp000066400000000000000000000601111353342203500237110ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2016 Advanced Driver Information Technology. * This code is developed by Advanced Driver Information Technology. * Copyright of Advanced Driver Information Technology, Bosch and DENSO. * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author Onkar Palkar onkar.palkar@wipro.com * * \copyright Copyright © 2016 Advanced Driver Information Technology. * * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file gtest_dlt_daemon_event_handler.cpp */ /******************************************************************************* ** ** ** SRC-MODULE: gtest_dlt_daemon_event_handler.cpp ** ** ** ** TARGET : linux ** ** ** ** PROJECT : DLT ** ** ** ** AUTHOR : Onkar Palkar onkar.palkar@wipro.com ** ** PURPOSE : Unit test connection and event handling ** ** ** ** REMARKS : ** ** ** ** PLATFORM DEPENDANT [yes/no]: yes ** ** ** ** TO BE CHANGED BY USER [yes/no]: no ** ** ** *******************************************************************************/ /******************************************************************************* ** Author Identity ** ******************************************************************************** ** ** ** Initials Name Company ** ** -------- ------------------------- ---------------------------------- ** ** op Onkar Palkar Wipro ** *******************************************************************************/ #include int connectServer(void); extern "C" { #include "dlt_daemon_event_handler.h" #include "dlt_daemon_connection.h" #include #include #include #include } /* Begin Method: dlt_daemon_event_handler::t_dlt_daemon_prepare_event_handling*/ TEST(t_dlt_daemon_prepare_event_handling, normal) { DltEventHandler ev; EXPECT_EQ(DLT_RETURN_OK, dlt_daemon_prepare_event_handling(&ev)); } TEST(t_dlt_daemon_prepare_event_handling, nullpointer) { /* NULL-Pointer, expect -1 */ EXPECT_EQ(DLT_RETURN_ERROR, dlt_daemon_prepare_event_handling(NULL)); } /* Begin Method: dlt_daemon_event_handler::t_dlt_daemon_handle_event*/ TEST(t_dlt_daemon_handle_event, normal) { DltDaemonLocal daemon_local; DltDaemon daemon; EXPECT_EQ(DLT_RETURN_OK, dlt_daemon_prepare_event_handling(&daemon_local.pEvent)); EXPECT_EQ(DLT_RETURN_OK, dlt_daemon_handle_event(&daemon_local.pEvent, &daemon, &daemon_local)); } TEST(t_dlt_daemon_handle_event, nullpointer) { EXPECT_EQ(DLT_RETURN_ERROR, dlt_daemon_handle_event(NULL, NULL, NULL)); } /* Begin Method: dlt_daemon_event_handler::dlt_event_handler_find_connection*/ TEST(t_dlt_event_handler_find_connection, normal) { int fd = 10; DltEventHandler ev; DltConnection connections; DltConnection *ret = nullptr; DltReceiver receiver; memset(&ev, 0, sizeof(DltEventHandler)); memset(&connections, 0, sizeof(DltConnection)); memset(&receiver, 0, sizeof(DltReceiver)); receiver.fd = fd; ev.connections = &connections; ev.connections->receiver = &receiver; ret = dlt_event_handler_find_connection(&ev, fd); EXPECT_EQ(10, ret->receiver->fd); } /* Begin Method: dlt_daemon_event_handler::dlt_daemon_add_connection*/ TEST(t_dlt_daemon_add_connection, normal) { DltEventHandler ev1; DltConnection *head = nullptr; DltConnection *connections1 = nullptr; DltReceiver receiver; memset(&ev1, 0, sizeof(DltEventHandler)); memset(&receiver, 0, sizeof(DltReceiver)); ev1.connections = (DltConnection *)malloc(sizeof(DltConnection)); head = (DltConnection *)ev1.connections; memset(ev1.connections, 0, sizeof(DltConnection)); ev1.connections->next = 0; ev1.connections->type = DLT_CONNECTION_CLIENT_MSG_SERIAL; connections1 = (DltConnection *)malloc(sizeof(DltConnection)); memset(connections1, 0, sizeof(DltConnection)); connections1->next = 0; connections1->type = DLT_CONNECTION_GATEWAY; connections1->receiver = &receiver; EXPECT_EQ(DLT_CONNECTION_CLIENT_MSG_SERIAL, ev1.connections->type); dlt_daemon_add_connection(&ev1, connections1); head = (DltConnection *)ev1.connections->next; EXPECT_EQ(DLT_CONNECTION_GATEWAY, head->type); free(ev1.connections); free(connections1); } /* Begin Method: dlt_daemon_event_handler::dlt_daemon_remove_connection*/ TEST(t_dlt_daemon_remove_connection, normal) { DltEventHandler ev1; DltConnection *head = nullptr; DltConnection *connections1 = nullptr; memset(&ev1, 0, sizeof(DltEventHandler)); ev1.connections = (DltConnection *)malloc(sizeof(DltConnection)); head = (DltConnection *)ev1.connections; memset(ev1.connections, 0, sizeof(DltConnection)); ev1.connections->next = 0; ev1.connections->type = DLT_CONNECTION_CLIENT_MSG_SERIAL; connections1 = (DltConnection *)malloc(sizeof(DltConnection)); memset(connections1, 0, sizeof(DltConnection)); connections1->next = 0; connections1->type = DLT_CONNECTION_GATEWAY; DltReceiver receiver; connections1->receiver = &receiver; EXPECT_EQ(DLT_CONNECTION_CLIENT_MSG_SERIAL, ev1.connections->type); dlt_daemon_add_connection(&ev1, connections1); head = (DltConnection *)ev1.connections->next; EXPECT_EQ(DLT_CONNECTION_GATEWAY, head->type); EXPECT_EQ(DLT_RETURN_OK, dlt_daemon_remove_connection(&ev1, connections1)); } /* Begin Method: dlt_daemon_event_handler::dlt_event_handler_cleanup_connections*/ TEST(t_dlt_event_handler_cleanup_connections, normal) { DltEventHandler ev1; DltReceiver receiver1; memset(&ev1, 0, sizeof(DltEventHandler)); memset(&receiver1, 0, sizeof(DltReceiver)); ev1.connections = (DltConnection *)malloc(sizeof(DltConnection)); memset(ev1.connections, 0, sizeof(DltConnection)); ev1.connections->next = 0; ev1.connections->type = DLT_CONNECTION_GATEWAY; ev1.connections->receiver = &receiver1; dlt_event_handler_cleanup_connections(&ev1); } /* Begin Method: dlt_daemon_event_handler::dlt_connection_check_activate*/ TEST(t_dlt_connection_check_activate, normal) { int ret; DltEventHandler evhdl; DltReceiver receiver; DltConnection con; memset(&evhdl, 0, sizeof(DltEventHandler)); memset(&receiver, 0, sizeof(DltReceiver)); memset(&con, 0, sizeof(DltConnection)); receiver.fd = 1; con.receiver = &receiver; con.status = INACTIVE; con.type = DLT_CONNECTION_CLIENT_MSG_TCP; EXPECT_EQ(DLT_RETURN_OK, dlt_daemon_prepare_event_handling(&evhdl)); ret = dlt_connection_check_activate(&evhdl, &con, ACTIVATE); EXPECT_EQ(DLT_RETURN_OK, ret); ret = dlt_connection_check_activate(&evhdl, &con, DEACTIVATE); EXPECT_EQ(DLT_RETURN_OK, ret); free(evhdl.pfd); } TEST(t_dlt_connection_check_activate, nullpointer) { EXPECT_EQ(DLT_RETURN_ERROR, dlt_connection_check_activate(NULL, NULL, DEACTIVATE)); } /* Begin Method: dlt_daemon_event_handler::dlt_event_handler_register_connection*/ TEST(t_dlt_event_handler_register_connection, normal) { int ret = 0; DltDaemonLocal daemon_local; int mask = 0; DltEventHandler ev1; DltConnection *connections1 = nullptr; DltReceiver receiver; memset(&daemon_local, 0, sizeof(DltDaemonLocal)); memset(&ev1, 0, sizeof(DltEventHandler)); memset(&receiver, 0, sizeof(DltReceiver)); EXPECT_EQ(DLT_RETURN_OK, dlt_daemon_prepare_event_handling(&ev1)); connections1 = (DltConnection *)malloc(sizeof(DltConnection)); memset(connections1, 0, sizeof(DltConnection)); connections1->next = 0; connections1->type = DLT_CONNECTION_GATEWAY; connections1->receiver = &receiver; ret = dlt_event_handler_register_connection(&ev1, &daemon_local, connections1, mask); EXPECT_EQ(DLT_RETURN_OK, ret); EXPECT_EQ(DLT_CONNECTION_GATEWAY, ev1.connections->type); free(ev1.pfd); free(connections1); } TEST(t_dlt_event_handler_register_connection, nullpointer) { EXPECT_EQ(DLT_RETURN_ERROR, dlt_event_handler_register_connection(NULL, NULL, NULL, 1)); } /* Begin Method: dlt_daemon_event_handler::dlt_event_handler_unregister_connection*/ TEST(t_dlt_event_handler_unregister_connection, normal) { int ret = 0; DltDaemonLocal daemon_local; int mask = 0; DltEventHandler ev1; DltConnection *connections1 = nullptr; DltReceiver receiver; memset(&daemon_local, 0, sizeof(DltDaemonLocal)); memset(&ev1, 0, sizeof(DltEventHandler)); memset(&receiver, 0, sizeof(DltReceiver)); EXPECT_EQ(DLT_RETURN_OK, dlt_daemon_prepare_event_handling(&ev1)); connections1 = (DltConnection *)malloc(sizeof(DltConnection)); memset(connections1, 0, sizeof(DltConnection)); connections1->next = 0; connections1->type = DLT_CONNECTION_GATEWAY; connections1->receiver = &receiver; receiver.fd = 100; ret = dlt_event_handler_register_connection(&ev1, &daemon_local, connections1, mask); EXPECT_EQ(DLT_RETURN_OK, ret); EXPECT_EQ(DLT_CONNECTION_GATEWAY, ev1.connections->type); ret = dlt_event_handler_unregister_connection(&ev1, &daemon_local, receiver.fd); EXPECT_EQ(DLT_RETURN_OK, ret); free(ev1.pfd); } /* Begin Method: dlt_daemon_connections::dlt_connection_create*/ TEST(t_dlt_connection_create, normal) { int fd = 100; int ret = 0; DltDaemonLocal daemon_local; memset(&daemon_local, 0, sizeof(DltDaemonLocal)); EXPECT_EQ(DLT_RETURN_OK, dlt_daemon_prepare_event_handling(&daemon_local.pEvent)); ret = dlt_connection_create(&daemon_local, &daemon_local.pEvent, fd, POLLIN, DLT_CONNECTION_CLIENT_MSG_SERIAL); EXPECT_EQ(DLT_RETURN_OK, ret); dlt_event_handler_unregister_connection(&daemon_local.pEvent, &daemon_local, fd); free(daemon_local.pEvent.pfd); } /* Begin Method: dlt_daemon_connections::dlt_connection_destroy*/ TEST(t_dlt_connection_destroy, normal) { DltConnection *to_destroy = (DltConnection *)malloc(sizeof(DltConnection)); memset(to_destroy, 0, sizeof(DltConnection)); to_destroy->next = 0; to_destroy->type = DLT_CONNECTION_CLIENT_MSG_SERIAL; to_destroy->receiver = (DltReceiver *)malloc(sizeof(DltReceiver)); memset(to_destroy->receiver, 0, sizeof(DltReceiver)); to_destroy->receiver->fd = -1; to_destroy->receiver->buffer = nullptr; dlt_connection_destroy(to_destroy); } /* Begin Method: dlt_daemon_connections::t_dlt_connection_destroy_receiver*/ TEST(t_dlt_connection_destroy_receiver, normal) { DltConnection to_destroy; memset(&to_destroy, 0, sizeof(DltConnection)); to_destroy.receiver = (DltReceiver *)malloc(sizeof(DltReceiver)); memset(to_destroy.receiver, 0, sizeof(DltReceiver)); to_destroy.receiver->fd = -1; to_destroy.receiver->buffer = nullptr; dlt_connection_destroy_receiver(&to_destroy); } /* Begin Method: dlt_daemon_connections::t_dlt_connection_get_receiver*/ TEST(t_dlt_connection_get_receiver, normal) { int fd = 10; DltReceiver *ret; DltDaemonLocal daemon_local; memset(&daemon_local, 0, sizeof(DltDaemonLocal)); ret = dlt_connection_get_receiver(&daemon_local, DLT_CONNECTION_CLIENT_MSG_TCP, fd); ASSERT_NE(ret, nullptr); EXPECT_EQ(fd, ret->fd); } /* Begin Method: dlt_daemon_connections::(t_dlt_connection_get_next*/ TEST(t_dlt_connection_get_next, normal) { int type_mask = (DLT_CON_MASK_CLIENT_MSG_TCP | DLT_CON_MASK_CLIENT_MSG_SERIAL); DltConnection *ret = nullptr; DltConnection node; DltConnection current; memset(&node, 0, sizeof(DltConnection)); memset(¤t, 0, sizeof(DltConnection)); node.type = DLT_CONNECTION_CLIENT_MSG_TCP; current.type = DLT_CONNECTION_ONE_S_TIMER; current.next = &node; ret = dlt_connection_get_next(¤t, type_mask); ASSERT_NE(ret, nullptr); EXPECT_EQ(DLT_CONNECTION_CLIENT_MSG_TCP, ret->type); EXPECT_NE(DLT_CONNECTION_ONE_S_TIMER, ret->type); } /* Begin Method: dlt_daemon_connections::(t_dlt_connection_get_next*/ TEST(t_dlt_connection_get_next, abnormal) { int type_mask = (DLT_CON_MASK_CLIENT_MSG_TCP | DLT_CON_MASK_CLIENT_MSG_SERIAL); DltConnection *ret; DltConnection node; DltConnection current; memset(&node, 0, sizeof(DltConnection)); memset(¤t, 0, sizeof(DltConnection)); node.type = DLT_CONNECTION_CLIENT_MSG_TCP; current.type = DLT_CONNECTION_CLIENT_MSG_SERIAL; current.next = &node; ret = dlt_connection_get_next(¤t, type_mask); ASSERT_NE(ret, nullptr); EXPECT_NE(DLT_CONNECTION_CLIENT_MSG_TCP, ret->type); EXPECT_EQ(DLT_CONNECTION_CLIENT_MSG_SERIAL, ret->type); } /* Begin Method: dlt_daemon_connections::t_dlt_connection_send*/ TEST(t_dlt_connection_send, normal_1) { int ret = 0; DltConnection conn; DltReceiver receiver; void *data1 = nullptr; int size1 = 0; DltDaemonLocal daemon_local; memset(&conn, 0, sizeof(DltConnection)); memset(&receiver, 0, sizeof(DltReceiver)); memset(&daemon_local, 0, sizeof(DltDaemonLocal)); receiver.fd = connectServer(); EXPECT_NE(-1, receiver.fd); conn.receiver = &receiver; conn.type = DLT_CONNECTION_CLIENT_MSG_TCP; daemon_local.msg.databuffer = (uint8_t *)malloc(sizeof(uint8_t)); if (daemon_local.msg.databuffer == NULL) close(receiver.fd); EXPECT_NE((uint8_t *)NULL, daemon_local.msg.databuffer); memset(daemon_local.msg.databuffer, 1, sizeof(uint8_t)); daemon_local.msg.datasize = sizeof(uint8_t); data1 = daemon_local.msg.databuffer; size1 = daemon_local.msg.datasize; ret = dlt_connection_send(&conn, data1, size1); EXPECT_EQ(DLT_RETURN_OK, ret); close(receiver.fd); free(daemon_local.msg.databuffer); } TEST(t_dlt_connection_send, normal_2) { int ret = 0; DltConnection conn; DltReceiver receiver; memset(&conn, 0, sizeof(DltConnection)); memset(&receiver, 0, sizeof(DltReceiver)); receiver.fd = 1; conn.receiver = &receiver; conn.type = DLT_CONNECTION_CLIENT_MSG_SERIAL; ret = dlt_connection_send(&conn, (void *)dltSerialHeader, sizeof(dltSerialHeader)); EXPECT_EQ(DLT_RETURN_OK, ret); } TEST(t_dlt_connection_send, abnormal) { int ret = 0; DltConnection conn; DltReceiver receiver; memset(&conn, 0, sizeof(DltConnection)); memset(&receiver, 0, sizeof(DltReceiver)); receiver.fd = -1; conn.receiver = &receiver; conn.type = DLT_CONNECTION_TYPE_MAX; ret = dlt_connection_send(&conn, (void *)dltSerialHeader, sizeof(dltSerialHeader)); EXPECT_EQ(DLT_RETURN_ERROR, ret); } /* Begin Method: dlt_daemon_connections::t_dlt_connection_send_multiple*/ TEST(t_dlt_connection_send_multiple, normal_1) { int ret = 0; void *data1 = nullptr; void *data2 = nullptr; int size1 = 0; int size2 = 0; DltConnection conn; DltReceiver receiver; DltDaemonLocal daemon_local; memset(&conn, 0, sizeof(DltConnection)); memset(&receiver, 0, sizeof(DltReceiver)); memset(&daemon_local, 0, sizeof(DltDaemonLocal)); data1 = daemon_local.msg.headerbuffer + sizeof(DltStorageHeader); size1 = daemon_local.msg.headersize - sizeof(DltStorageHeader); data2 = daemon_local.msg.databuffer; size2 = daemon_local.msg.datasize; receiver.fd = connectServer(); EXPECT_NE(-1, receiver.fd); conn.receiver = &receiver; conn.type = DLT_CONNECTION_CLIENT_MSG_TCP; daemon_local.msg.headersize = sizeof(DltStorageHeader) + sizeof(DltStandardHeader) + sizeof(DltStandardHeaderExtra) + sizeof(DltExtendedHeader); memset(daemon_local.msg.headerbuffer, 0, daemon_local.msg.headersize); data1 = daemon_local.msg.headerbuffer + sizeof(DltStorageHeader); size1 = daemon_local.msg.headersize - sizeof(DltStorageHeader); daemon_local.msg.databuffer = (uint8_t *)malloc(sizeof(uint8_t)); if (daemon_local.msg.databuffer == NULL) close(receiver.fd); EXPECT_NE((uint8_t *)NULL, daemon_local.msg.databuffer); memset(daemon_local.msg.databuffer, 0, sizeof(uint8_t)); daemon_local.msg.datasize = sizeof(uint8_t); data2 = daemon_local.msg.databuffer; size2 = daemon_local.msg.datasize; ret = dlt_connection_send_multiple(&conn, data1, size1, data2, size2, 1); EXPECT_EQ(DLT_RETURN_OK, ret); close(receiver.fd); free(daemon_local.msg.databuffer); } TEST(t_dlt_connection_send_multiple, normal_2) { int ret = 0; void *data1 = nullptr; void *data2 = nullptr; int size1 = 0; int size2 = 0; DltConnection conn; DltReceiver receiver; DltDaemonLocal daemon_local; memset(&conn, 0, sizeof(DltConnection)); memset(&receiver, 0, sizeof(DltReceiver)); memset(&daemon_local, 0, sizeof(DltDaemonLocal)); data1 = daemon_local.msg.headerbuffer + sizeof(DltStorageHeader); size1 = daemon_local.msg.headersize - sizeof(DltStorageHeader); data2 = daemon_local.msg.databuffer; size2 = daemon_local.msg.datasize; receiver.fd = connectServer(); EXPECT_NE(-1, receiver.fd); conn.receiver = &receiver; conn.type = DLT_CONNECTION_CLIENT_MSG_TCP; daemon_local.msg.headersize = sizeof(DltStorageHeader) + sizeof(DltStandardHeader) + sizeof(DltStandardHeaderExtra) + sizeof(DltExtendedHeader); memset(daemon_local.msg.headerbuffer, 0, daemon_local.msg.headersize); data1 = daemon_local.msg.headerbuffer + sizeof(DltStorageHeader); size1 = daemon_local.msg.headersize - sizeof(DltStorageHeader); daemon_local.msg.databuffer = (uint8_t *)malloc(sizeof(uint8_t)); if (daemon_local.msg.databuffer == NULL) close(receiver.fd); EXPECT_NE((uint8_t *)NULL, daemon_local.msg.databuffer); memset(daemon_local.msg.databuffer, 0, sizeof(uint8_t)); daemon_local.msg.datasize = sizeof(uint8_t); data2 = daemon_local.msg.databuffer; size2 = daemon_local.msg.datasize; ret = dlt_connection_send_multiple(&conn, data1, size1, data2, size2, 0); EXPECT_EQ(DLT_RETURN_OK, ret); close(receiver.fd); free(daemon_local.msg.databuffer); } TEST(t_dlt_connection_send_multiple, nullpointer) { int ret = 0; void *data1 = nullptr; void *data2 = nullptr; int size1 = 0; int size2 = 0; DltDaemonLocal daemon_local; memset(&daemon_local, 0, sizeof(DltDaemonLocal)); data1 = daemon_local.msg.headerbuffer + sizeof(DltStorageHeader); size1 = daemon_local.msg.headersize - sizeof(DltStorageHeader); data2 = daemon_local.msg.databuffer; size2 = daemon_local.msg.datasize; ret = dlt_connection_send_multiple(NULL, data1, size1, data2, size2, 0); EXPECT_EQ(DLT_RETURN_ERROR, ret); } int connectServer(void) { int sockfd = 0, portno = 0; struct sockaddr_in serv_addr; struct hostent *server = nullptr; portno = 8080; sockfd = socket(AF_INET, SOCK_STREAM, 0); server = gethostbyname("127.0.0.1"); memset((char *)&serv_addr, 0, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; memcpy((char *)&serv_addr.sin_addr.s_addr, (char *)server->h_addr, server->h_length); serv_addr.sin_port = htons(portno); if (connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) { printf("Error: %s (%d) occured in connect socket\n", strerror(errno), errno); close(sockfd); return -1; } return sockfd; } #define GTEST_SOCKS_ACCEPTED 3 int main(int argc, char **argv) { pid_t cpid = fork(); if (cpid == -1) { printf("fork fail\n"); return -1; } if (cpid) { int i = GTEST_SOCKS_ACCEPTED; int j = 0, optval = 1; char buffer[256] = {}; int sockfd = 0, newsockfd[GTEST_SOCKS_ACCEPTED] = {}, portno = 0; socklen_t clilen = {}; struct sockaddr_in serv_addr, cli_addr; sockfd = socket(AF_INET, SOCK_STREAM, 0); if (sockfd == -1) { printf("Error in creating socket\n"); return -1; } memset((char *) &serv_addr, 0, sizeof(serv_addr)); memset((char *) &cli_addr, 0, sizeof(cli_addr)); portno = 8080; serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = INADDR_ANY; serv_addr.sin_port = htons(portno); if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)) == -1) { perror("setsockopt"); close(sockfd); exit(1); } j = bind(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)); if (j == -1) { perror("Bind Error\n"); close(sockfd); return -1; } listen(sockfd, 5); while (i) { clilen = sizeof(cli_addr); newsockfd[i - 1] = accept(sockfd, (struct sockaddr *)&cli_addr, &clilen); if (newsockfd[i - 1] == -1) { printf("Error in accept"); return -1; } memset(buffer, 0, 256); (void)(read(newsockfd[i - 1], buffer, 255) + 1); /* just ignore result */ i--; } for (j = 0; j < GTEST_SOCKS_ACCEPTED; j++) close(newsockfd[i]); close(sockfd); } else { ::testing::InitGoogleTest(&argc, argv); ::testing::FLAGS_gtest_break_on_failure = false; /* ::testing::FLAGS_gtest_filter = "t_dlt_event_handler_register_connection*"; */ return RUN_ALL_TESTS(); } return 0; } dlt-daemon-2.18.4/tests/gtest_dlt_daemon_gateway.cpp000066400000000000000000000576051353342203500225520ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2016 Advanced Driver Information Technology. * This code is developed by Advanced Driver Information Technology. * Copyright of Advanced Driver Information Technology, Bosch and DENSO. * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author Onkar Palkar onkar.palkar@wipro.com * * \copyright Copyright © 2015 Advanced Driver Information Technology. * * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file gtest_dlt_daemon_gateway.cpp */ /******************************************************************************* ** ** ** SRC-MODULE: gtest_dlt_daemon_gateway.cpp ** ** ** ** TARGET : linux ** ** ** ** PROJECT : DLT ** ** ** ** AUTHOR : Onkar Palkar onkar.palkar@wipro.com ** ** PURPOSE : Unit test for dlt_gateway.c ** ** ** ** REMARKS : ** ** ** ** PLATFORM DEPENDANT [yes/no]: yes ** ** ** ** TO BE CHANGED BY USER [yes/no]: no ** ** ** *******************************************************************************/ /******************************************************************************* ** Author Identity ** ******************************************************************************** ** ** ** Initials Name Company ** ** -------- ------------------------- ---------------------------------- ** ** op Onkar Palkar Wipro ** *******************************************************************************/ #include #include #include extern "C" { #include "dlt_gateway.h" #include "dlt_gateway_internal.h" } /* Begin Method: dlt_gateway::t_dlt_gateway_init*/ TEST(t_dlt_gateway_init, normal) { DltDaemonLocal daemon_local; DltGatewayConnection connections; daemon_local.pGateway.connections = &connections; daemon_local.pGateway.num_connections = 1; daemon_local.flags.lflag = 0; DltConnection connections1; DltReceiver receiver; daemon_local.pEvent.connections = &connections1; daemon_local.pEvent.pfd = 0; daemon_local.pEvent.nfds = 0; daemon_local.pEvent.max_nfds = 0; daemon_local.pEvent.connections->receiver = &receiver; daemon_local.pEvent.connections->next = NULL; memset(daemon_local.flags.gatewayConfigFile, 0, DLT_DAEMON_FLAG_MAX); strncpy(daemon_local.flags.gatewayConfigFile, "/tmp/dlt_gateway.conf", DLT_DAEMON_FLAG_MAX - 1); EXPECT_EQ(DLT_RETURN_OK, dlt_gateway_init(&daemon_local, 1)); dlt_gateway_deinit(&daemon_local.pGateway, 0); } TEST(t_dlt_gateway_init, nullpointer) { EXPECT_EQ(DLT_RETURN_WRONG_PARAMETER, dlt_gateway_init(NULL, 0)); } /* Begin Method: dlt_gateway::t_dlt_gateway_send_control_message*/ TEST(t_dlt_gateway_send_control_message, Normal) { int ret = 0; DltDaemonLocal daemon_local; DltGatewayConnection connections; DltConnection connections1; DltReceiver receiver1; daemon_local.pGateway.connections = &connections; daemon_local.pEvent.connections = &connections1; daemon_local.pEvent.connections->next = NULL; daemon_local.pEvent.pfd = 0; daemon_local.pEvent.nfds = 0; daemon_local.pEvent.max_nfds = 0; daemon_local.pEvent.connections->receiver = &receiver1; memset(daemon_local.flags.gatewayConfigFile, 0, DLT_DAEMON_FLAG_MAX); strncpy(daemon_local.flags.gatewayConfigFile, "/tmp/dlt_gateway.conf", DLT_DAEMON_FLAG_MAX - 1); ret = dlt_gateway_init(&daemon_local, 0); EXPECT_EQ(DLT_RETURN_OK, ret); dlt_gateway_send_control_message(daemon_local.pGateway.connections, daemon_local.pGateway.connections->p_control_msgs, NULL, 0); dlt_gateway_deinit(&daemon_local.pGateway, 0); } TEST(t_dlt_gateway_send_control_message, nullpointer) { EXPECT_EQ(DLT_RETURN_WRONG_PARAMETER, dlt_gateway_send_control_message(NULL, NULL, NULL, 0)); } /* Begin Method: dlt_gateway::t_dlt_gateway_store_connection*/ TEST(t_dlt_gateway_store_connection, normal) { char ip_address[DLT_CONFIG_FILE_ENTRY_MAX_LEN] = "10.113.100.100"; char ecuid[] = "1234"; DltGateway gateway; DltGatewayConnection tmp; DltGatewayConnection tmp1; gateway.num_connections = 1; gateway.connections = &tmp1; gateway.connections->status = DLT_GATEWAY_UNINITIALIZED; tmp.ip_address = ip_address; tmp.ecuid = ecuid; tmp.sock_domain = 1; tmp.sock_type = 2; tmp.sock_protocol = 1; tmp.port = 1; tmp.trigger = DLT_GATEWAY_ON_STARTUP; tmp.timeout = 500; EXPECT_EQ(DLT_RETURN_OK, dlt_gateway_store_connection(&gateway, &tmp, 0)); EXPECT_EQ(gateway.connections->sock_domain, tmp.sock_domain); EXPECT_EQ(gateway.connections->sock_type, tmp.sock_type); EXPECT_EQ(gateway.connections->port, tmp.port); } TEST(t_dlt_gateway_store_connection, nullpointer) { DltGateway gateway; EXPECT_EQ(DLT_RETURN_WRONG_PARAMETER, dlt_gateway_store_connection(NULL, NULL, 0)); EXPECT_EQ(DLT_RETURN_WRONG_PARAMETER, dlt_gateway_store_connection(&gateway, NULL, 0)); } /* Begin Method: dlt_gateway::t_dlt_gateway_check_ip*/ TEST(t_dlt_gateway_check_ip, normal) { DltGatewayConnection tmp; DltGatewayConnection *con; char value[DLT_CONFIG_FILE_ENTRY_MAX_LEN] = "10.113.100.100"; con = &tmp; EXPECT_EQ(DLT_RETURN_OK, dlt_gateway_check_ip(con, value)); } TEST(t_dlt_gateway_check_ip, nullpointer) { EXPECT_EQ(DLT_RETURN_WRONG_PARAMETER, dlt_gateway_check_ip(NULL, NULL)); } /* Begin Method: dlt_gateway::t_dlt_gateway_check_send_serial*/ TEST(t_dlt_gateway_check_send_serial, normal) { DltGatewayConnection tmp; DltGatewayConnection *con; char value[DLT_CONFIG_FILE_ENTRY_MAX_LEN] = "134dltgatway"; con = &tmp; EXPECT_EQ(DLT_RETURN_OK, dlt_gateway_check_send_serial(con, value)); } TEST(t_dlt_gateway_check_send_serial, nullpointer) { EXPECT_EQ(DLT_RETURN_WRONG_PARAMETER, dlt_gateway_check_send_serial(NULL, NULL)); } /* Begin Method: dlt_gateway::t_dlt_gateway_allocate_control_messages*/ TEST(t_dlt_gateway_allocate_control_messages, normal) { DltGatewayConnection tmp; DltGatewayConnection *con; tmp.p_control_msgs = NULL; con = &tmp; EXPECT_EQ(DLT_RETURN_OK, dlt_gateway_allocate_control_messages(con)); } TEST(t_dlt_gateway_allocate_control_messages, nullpointer) { EXPECT_EQ(DLT_RETURN_WRONG_PARAMETER, dlt_gateway_allocate_control_messages(NULL)); } /* Begin Method: dlt_gateway::t_dlt_gateway_check_control_messages*/ TEST(t_dlt_gateway_check_control_messages, normal) { DltGatewayConnection tmp; DltGatewayConnection *con; char value[DLT_CONFIG_FILE_ENTRY_MAX_LEN] = "1,2,3,4,5"; tmp.p_control_msgs = NULL; con = &tmp; EXPECT_EQ(DLT_RETURN_OK, dlt_gateway_check_control_messages(con, value)); } TEST(t_dlt_gateway_check_control_messages, nullpointer) { EXPECT_EQ(DLT_RETURN_WRONG_PARAMETER, dlt_gateway_check_control_messages(NULL, NULL)); } /* Begin Method: dlt_gateway::t_dlt_gateway_check_periodic_control_messages*/ TEST(t_dlt_gateway_check_periodic_control_messages, normal) { DltGatewayConnection tmp; DltGatewayConnection *con; char value[DLT_CONFIG_FILE_ENTRY_MAX_LEN] = "1:5,2:10"; tmp.p_control_msgs = NULL; con = &tmp; EXPECT_EQ(DLT_RETURN_OK, dlt_gateway_check_periodic_control_messages(con, value)); } TEST(t_dlt_gateway_check_periodic_control_messages, nullpointer) { EXPECT_EQ(DLT_RETURN_WRONG_PARAMETER, dlt_gateway_check_periodic_control_messages(NULL, NULL)); } /* Begin Method: dlt_gateway::t_dlt_gateway_check_port*/ TEST(t_dlt_gateway_check_port, normal) { DltGatewayConnection tmp; DltGatewayConnection *con; char value[DLT_CONFIG_FILE_ENTRY_MAX_LEN] = "3490"; con = &tmp; EXPECT_EQ(DLT_RETURN_OK, dlt_gateway_check_port(con, value)); } TEST(t_dlt_gateway_check_port, abnormal) { DltGatewayConnection tmp; DltGatewayConnection *con; char value[DLT_CONFIG_FILE_ENTRY_MAX_LEN] = "9999999999"; con = &tmp; EXPECT_EQ(DLT_RETURN_ERROR, dlt_gateway_check_port(con, value)); } TEST(t_dlt_gateway_check_port, nullpointer) { EXPECT_EQ(DLT_RETURN_WRONG_PARAMETER, dlt_gateway_check_port(NULL, NULL)); } /* Begin Method: dlt_gateway::t_dlt_gateway_check_ecu*/ TEST(t_dlt_gateway_check_ecu, normal) { DltGatewayConnection tmp; DltGatewayConnection *con; char value[DLT_CONFIG_FILE_ENTRY_MAX_LEN] = "ECU2"; con = &tmp; EXPECT_EQ(DLT_RETURN_OK, dlt_gateway_check_ecu(con, value)); } TEST(t_dlt_gateway_check_ecu, nullpointer) { EXPECT_EQ(DLT_RETURN_WRONG_PARAMETER, dlt_gateway_check_ecu(NULL, NULL)); } /* Begin Method: dlt_gateway::t_dlt_gateway_check_connect_trigger*/ TEST(t_dlt_gateway_check_connect_trigger, normal) { DltGatewayConnection tmp; DltGatewayConnection *con; char value[DLT_CONFIG_FILE_ENTRY_MAX_LEN] = "OnStartup"; con = &tmp; EXPECT_EQ(DLT_RETURN_OK, dlt_gateway_check_connect_trigger(con, value)); } TEST(t_dlt_gateway_check_connect_trigger, abnormal) { DltGatewayConnection tmp; DltGatewayConnection *con; char value[DLT_CONFIG_FILE_ENTRY_MAX_LEN] = "wrong_parameter"; con = &tmp; EXPECT_EQ(DLT_RETURN_ERROR, dlt_gateway_check_connect_trigger(con, value)); } TEST(t_dlt_gateway_check_connect_trigger, nullpointer) { EXPECT_EQ(DLT_RETURN_WRONG_PARAMETER, dlt_gateway_check_connect_trigger(NULL, NULL)); } /* Begin Method: dlt_gateway::t_dlt_gateway_check_timeout*/ TEST(t_dlt_gateway_check_timeout, normal) { DltGatewayConnection tmp; DltGatewayConnection *con; char value[DLT_CONFIG_FILE_ENTRY_MAX_LEN] = "10"; con = &tmp; EXPECT_EQ(DLT_RETURN_OK, dlt_gateway_check_timeout(con, value)); } TEST(t_dlt_gateway_check_timeout, abnormal) { DltGatewayConnection tmp; DltGatewayConnection *con; char value[DLT_CONFIG_FILE_ENTRY_MAX_LEN] = "0"; con = &tmp; EXPECT_EQ(DLT_RETURN_ERROR, dlt_gateway_check_timeout(con, value)); } TEST(t_dlt_gateway_check_timeout, nullpointer) { EXPECT_EQ(DLT_RETURN_WRONG_PARAMETER, dlt_gateway_check_timeout(NULL, NULL)); } /* Begin Method: dlt_gateway::t_dlt_gateway_establish_connections*/ TEST(t_dlt_gateway_establish_connections, normal) { char ip[] = "127.0.0.1"; int port = 3491; DltDaemonLocal daemon_local; DltGateway *gateway = &daemon_local.pGateway; DltGatewayConnection connections; gateway->num_connections = 1; gateway->connections = &connections; gateway->connections->status = DLT_GATEWAY_INITIALIZED; gateway->connections->trigger = DLT_GATEWAY_ON_STARTUP; gateway->connections->client.mode = DLT_CLIENT_MODE_TCP; gateway->connections->client.servIP = ip; gateway->connections->client.port = port; EXPECT_EQ(DLT_RETURN_OK, dlt_gateway_establish_connections(gateway, &daemon_local, 0)); } TEST(t_dlt_gateway_establish_connections, nullpointer) { EXPECT_EQ(DLT_RETURN_WRONG_PARAMETER, dlt_gateway_establish_connections(NULL, NULL, 0)); } /* Begin Method: dlt_gateway::t_dlt_gateway_get_connection_receiver*/ TEST(t_dlt_gateway_get_connection_receiver, normal) { DltReceiver *ret = NULL; DltGateway gateway; DltGatewayConnection connections; gateway.connections = &connections; int fd = 10; gateway.num_connections = 1; gateway.connections->client.sock = fd; gateway.connections->client.receiver.fd = 12; gateway.connections->status = DLT_GATEWAY_CONNECTED; ret = dlt_gateway_get_connection_receiver(&gateway, fd); EXPECT_EQ(12, ret->fd); } TEST(t_dlt_gateway_get_connection_receiver, abnormal) { DltReceiver *ret = NULL; DltGateway gateway; DltGatewayConnection connections; gateway.connections = &connections; int fd = 10; gateway.num_connections = 1; gateway.connections->client.sock = fd; gateway.connections->client.receiver.fd = 12; ret = dlt_gateway_get_connection_receiver(&gateway, fd); EXPECT_EQ(NULL, ret); } TEST(t_dlt_gateway_get_connection_receiver, nullpointer) { DltReceiver *ret; ret = dlt_gateway_get_connection_receiver(NULL, 0); EXPECT_EQ(NULL, ret); } /* Begin Method: dlt_gateway::t_dlt_gateway_parse_get_log_info*/ TEST(t_dlt_gateway_parse_get_log_info, normal) { int32_t len; int32_t ret = DLT_RETURN_ERROR; DltDaemon daemon; DltGateway gateway; DltMessage msg; char ecuid[] = "ECU2"; uint32_t sid = DLT_SERVICE_ID_GET_LOG_INFO; uint8_t status = 7; uint16_t count_app_ids = 1; uint16_t count_context_ids = 1; const char *apid = "LOG"; const char *ctid = "TEST"; const char *com = "remo"; char app_description[] = "Test Application for Logging"; char context_description[] = "Test Context for Logging"; uint16_t len_app = 0; uint16_t len_con = 0; int8_t log_level = -1; int8_t trace_status = -1; int offset = 0; memset(&daemon, 0, sizeof(DltDaemon)); dlt_set_id(daemon.ecuid, ecuid); EXPECT_EQ(0, dlt_daemon_init_user_information(&daemon, &gateway, 0, 0)); ret = strncmp(daemon.ecuid, daemon.user_list[0].ecu, DLT_ID_SIZE); ASSERT_EQ(DLT_RETURN_OK, ret); /* create response message */ msg.datasize = sizeof(DltServiceGetLogInfoResponse) + sizeof(AppIDsType) + sizeof(ContextIDsInfoType) + strlen(app_description) + strlen(context_description); msg.databuffer = (uint8_t *)malloc(msg.datasize); msg.databuffersize = msg.datasize; memset(msg.databuffer, 0, msg.datasize); memcpy(msg.databuffer, &sid, sizeof(uint32_t)); offset += sizeof(uint32_t); memcpy(msg.databuffer + offset, &status, sizeof(int8_t)); offset += sizeof(int8_t); memcpy(msg.databuffer + offset, &count_app_ids, sizeof(uint16_t)); offset += sizeof(uint16_t); dlt_set_id((char *)(msg.databuffer + offset), apid); offset += sizeof(ID4); memcpy(msg.databuffer + offset, &count_context_ids, sizeof(uint16_t)); offset += sizeof(uint16_t); dlt_set_id((char *)(msg.databuffer + offset), ctid); offset += sizeof(ID4); memcpy(msg.databuffer + offset, &log_level, sizeof(int8_t)); offset += sizeof(int8_t); memcpy(msg.databuffer + offset, &trace_status, sizeof(int8_t)); offset += sizeof(int8_t); len_con = strlen(context_description); memcpy(msg.databuffer + offset, &len_con, sizeof(uint16_t)); offset += sizeof(uint16_t); memcpy(msg.databuffer + offset, context_description, strlen(context_description)); offset += strlen(context_description); len_app = strlen(app_description); memcpy(msg.databuffer + offset, &len_app, sizeof(uint16_t)); offset += sizeof(uint16_t); memcpy(msg.databuffer + offset, app_description, strlen(app_description)); offset += strlen(app_description); dlt_set_id((char *)(msg.databuffer + offset), com); msg.storageheader = (DltStorageHeader *)msg.headerbuffer; dlt_set_storageheader(msg.storageheader, ""); msg.standardheader = (DltStandardHeader *)(msg.headerbuffer + sizeof(DltStorageHeader)); msg.standardheader->htyp = DLT_HTYP_WEID | DLT_HTYP_WTMS | DLT_HTYP_UEH | DLT_HTYP_PROTOCOL_VERSION1; msg.standardheader->mcnt = 0; dlt_set_id(msg.headerextra.ecu, ecuid); msg.headerextra.tmsp = dlt_uptime(); dlt_message_set_extraparameters(&msg, 0); msg.extendedheader = (DltExtendedHeader *)(msg.headerbuffer + sizeof(DltStorageHeader) + sizeof(DltStandardHeader) + DLT_STANDARD_HEADER_EXTRA_SIZE(msg.standardheader->htyp)); msg.extendedheader->msin = DLT_MSIN_CONTROL_RESPONSE; msg.extendedheader->noar = 1; dlt_set_id(msg.extendedheader->apid, ""); dlt_set_id(msg.extendedheader->ctid, ""); msg.headersize = sizeof(DltStorageHeader) + sizeof(DltStandardHeader) + sizeof(DltExtendedHeader) + DLT_STANDARD_HEADER_EXTRA_SIZE(msg.standardheader->htyp); len = msg.headersize - sizeof(DltStorageHeader) + msg.datasize; msg.standardheader->len = DLT_HTOBE_16(len); EXPECT_EQ(DLT_RETURN_OK, dlt_gateway_parse_get_log_info(&daemon, ecuid, &msg, CONTROL_MESSAGE_NOT_REQUESTED, 0)); } TEST(t_dlt_gateway_parse_get_log_info, nullpointer) { EXPECT_EQ(DLT_RETURN_WRONG_PARAMETER, dlt_gateway_parse_get_log_info(NULL, NULL, NULL, 0, 0)); } /* Begin Method: dlt_gateway::t_dlt_gateway_process_passive_node_messages*/ TEST(t_dlt_gateway_process_passive_node_messages, normal) { DltDaemon daemon; DltDaemonLocal daemon_local; DltReceiver receiver; DltGatewayConnection connections; memset(&daemon, 0, sizeof(DltDaemon)); memset(&daemon_local, 0, sizeof(DltDaemonLocal)); memset(&receiver, 0, sizeof(DltReceiver)); memset(&connections, 0, sizeof(DltGatewayConnection)); daemon_local.pGateway.connections = &connections; daemon_local.pGateway.num_connections = 1; daemon_local.pGateway.connections->status = DLT_GATEWAY_CONNECTED; EXPECT_EQ(DLT_RETURN_OK, dlt_gateway_process_passive_node_messages(&daemon, &daemon_local, &receiver, 1)); } TEST(t_dlt_gateway_process_passive_node_messages, nullpointer) { EXPECT_EQ(DLT_RETURN_WRONG_PARAMETER, dlt_gateway_process_passive_node_messages(NULL, NULL, NULL, 0)); } /* Begin Method: dlt_gateway::t_dlt_gateway_process_gateway_timer*/ TEST(t_dlt_gateway_process_gateway_timer, normal) { char ECUVersionString[] = "12.34"; char ip[] = "127.0.0.1"; int port = 3491; DltDaemon daemon; DltDaemonLocal daemon_local; DltReceiver receiver; DltGatewayConnection connections; DltConnection connections1; daemon_local.pGateway.connections = &connections; daemon_local.pGateway.num_connections = 1; DltLogStorage storage_handle; daemon_local.pGateway.connections->status = DLT_GATEWAY_INITIALIZED; daemon_local.pGateway.connections->trigger = DLT_GATEWAY_ON_STARTUP; daemon_local.pGateway.connections->client.mode = DLT_CLIENT_MODE_TCP; daemon_local.pGateway.connections->client.servIP = ip; daemon_local.pGateway.connections->client.port = port; daemon_local.pEvent.connections = &connections1; daemon_local.pEvent.connections->receiver = &receiver; daemon.ECUVersionString = ECUVersionString; daemon.storage_handle = &storage_handle; daemon_local.pEvent.connections->receiver->fd = -1; EXPECT_EQ(DLT_RETURN_OK, dlt_gateway_process_gateway_timer(&daemon, &daemon_local, daemon_local.pEvent.connections->receiver, 1)); } TEST(t_dlt_gateway_process_gateway_timer, nullpointer) { EXPECT_EQ(DLT_RETURN_WRONG_PARAMETER, dlt_gateway_process_gateway_timer(NULL, NULL, NULL, 0)); } /* Begin Method: dlt_gateway::t_dlt_gateway_process_on_demand_request*/ TEST(t_dlt_gateway_process_on_demand_request, normal) { char node_id[DLT_ID_SIZE] = "123"; uint32_t connection_status = 1; DltDaemonLocal daemon_local; DltGatewayConnection connections; daemon_local.pGateway.connections = &connections; daemon_local.pGateway.num_connections = 1; connections.status = DLT_GATEWAY_CONNECTED; connections.trigger = DLT_GATEWAY_ON_STARTUP; connections.ecuid = node_id; EXPECT_EQ(DLT_RETURN_OK, dlt_gateway_process_on_demand_request(&daemon_local.pGateway, &daemon_local, node_id, connection_status, 1)); } TEST(t_dlt_gateway_process_on_demand_request, abnormal) { char node_id[DLT_ID_SIZE] = "123"; uint32_t connection_status = 1; DltDaemonLocal daemon_local; DltGatewayConnection connections; daemon_local.pGateway.connections = &connections; daemon_local.pGateway.num_connections = 1; connections.status = DLT_GATEWAY_INITIALIZED; connections.ecuid = node_id; EXPECT_EQ(DLT_RETURN_ERROR, dlt_gateway_process_on_demand_request(&daemon_local.pGateway, &daemon_local, node_id, connection_status, 0)); } TEST(t_dlt_gateway_process_on_demand_request, nullpointer) { char node_id[DLT_ID_SIZE] = "123"; EXPECT_EQ(DLT_RETURN_WRONG_PARAMETER, dlt_gateway_process_on_demand_request(NULL, NULL, node_id, 1, 0)); } /* Begin Method: dlt_gateway::t_dlt_gateway_check_param*/ TEST(t_dlt_gateway_check_param, normal) { char value_1[DLT_CONFIG_FILE_ENTRY_MAX_LEN] = "10.11.22.33"; char value_2[DLT_CONFIG_FILE_ENTRY_MAX_LEN] = "3490"; DltGateway gateway; DltGatewayConnection tmp; gateway.connections = &tmp; EXPECT_EQ(DLT_RETURN_OK, dlt_gateway_check_param(&gateway, &tmp, GW_CONF_IP_ADDRESS, value_1)); EXPECT_EQ(DLT_RETURN_OK, dlt_gateway_check_param(&gateway, &tmp, GW_CONF_PORT, value_2)); } TEST(t_dlt_gateway_check_param, abnormal) { char value_1[DLT_CONFIG_FILE_ENTRY_MAX_LEN] = "10.11.22.33"; DltGateway gateway; DltGatewayConnection tmp; gateway.connections = &tmp; EXPECT_EQ(DLT_RETURN_ERROR, dlt_gateway_check_param(&gateway, &tmp, GW_CONF_PORT, value_1)); } TEST(t_dlt_gateway_check_param, nullpointer) { EXPECT_EQ(DLT_RETURN_WRONG_PARAMETER, dlt_gateway_check_param(NULL, NULL, GW_CONF_PORT, 0)); } /* Begin Method: dlt_gateway::t_dlt_gateway_configure*/ TEST(t_dlt_gateway_configure, Normal) { DltGateway gateway; DltGatewayConnection tmp; gateway.connections = &tmp; gateway.num_connections = 1; char gatewayConfigFile[DLT_DAEMON_FLAG_MAX]; strncpy(gatewayConfigFile, "/tmp/dlt_gateway.conf", DLT_DAEMON_FLAG_MAX - 1); EXPECT_EQ(DLT_RETURN_OK, dlt_gateway_configure(&gateway, gatewayConfigFile, 0)); } TEST(t_dlt_gateway_configure, nullpointer) { EXPECT_EQ(DLT_RETURN_WRONG_PARAMETER, dlt_gateway_configure(NULL, NULL, 0)); } int main(int argc, char **argv) { ::testing::InitGoogleTest(&argc, argv); /* ::testing::FLAGS_gtest_break_on_failure = true; */ /* ::testing::FLAGS_gtest_filter = "t_dlt_gateway_process_passive_node_messages*"; */ return RUN_ALL_TESTS(); } dlt-daemon-2.18.4/tests/gtest_dlt_daemon_gateway.sh000077500000000000000000000137341353342203500224000ustar00rootroot00000000000000#!/bin/sh ################################################################################ # SPDX license identifier: MPL-2.0 # # Copyright (C) 2016, Advanced Driver Information Technology # This code is developed by Advanced Driver Information Technology. # Copyright of Advanced Driver Information Technology, Bosch and DENSO. # # This file is part of GENIVI Project DLT - Diagnostic Log and Trace. # # This Source Code Form is subject to the terms of the # Mozilla Public License (MPL), v. 2.0. # If a copy of the MPL was not distributed with this file, # You can obtain one at http://mozilla.org/MPL/2.0/. # # For further information see http://www.genivi.org/. ################################################################################ ################################################################################ #file : g_test_dlt_daemon_gateway.sh # #Description : gateway unit test preparation # #Author Name : Onkar Palkar # Jeevan Ramakant Nagvekar #Email Id : onkar.palkar@wipro.com # jeevan.nagvekar1@wipro.com # #History : Last modified date : 31/07/2018 ipaddr=127.0.0.1 ################################################################################ # Function: -getOSname() # # Description -Retrieves OS name # getOSname() { OS="`uname`" } ################################################################################ # # Function: -cleanup() # # Description -Delete the dlt_test folder if it already present # -Check weather required binaries are avaiable or not # -Restore dlt_gateway.conf file # # Return -Zero on success # -Non zero on failure # cleanup() { tmpPath=/tmp if [ "$OS" = "QNX" ] then PIDOF() { slay -p $1 > /dev/null if [ $? -eq '0' ] then return 1 else return 0 fi } KILLALL() { slay -9 -f $1 > /dev/null if [ $? -eq '0' ] then return 1 else return 0 fi } else PIDOF() { pidof $1 > /dev/null return $? } KILLALL() { killall $1 > /dev/null return $? } fi cd $tmpPath PIDOF dlt-daemon if [ $? -eq '0' ] then KILLALL dlt-daemon if [ $? -eq '1' ] then echo "Failed to kill daemons" return 1 fi fi rm -f $tmpPath/dlt.conf rm -f $tmpPath/dlt_gateway.conf rm -f /dev/shm/dlt-shm rm -f /dev/shm/sem.dlt-shm rm -f /dev/shm/dlt-shm-passive rm -f /dev/shm/sem.dlt-shm-passive return 0 } # # Function: -setupTest() # # Description -Create gateway folder # -Create and add dlt.conf and dlt_gateway.conf file in the gateway folder # # Return -Zero on success # -Non zero on failure # setupTest() { which dlt-daemon > /dev/null if [ $? -eq '1' ] then echo "dlt-daemon is not available" return 1 fi touch $tmpPath/dlt.conf if [ $? -eq '1' ] then echo "Error in creating dlt.conf file" return 1 fi echo "SendContextRegistration = 1" >>$tmpPath/dlt.conf echo "ECUId = ECU2" >>$tmpPath/dlt.conf echo "GatewayMode = 1" >>$tmpPath/dlt.conf echo "SharedMemorySize = 100000" >>$tmpPath/dlt.conf echo "LoggingMode = 0" >>$tmpPath/dlt.conf echo "LoggingLevel = 6" >>$tmpPath/dlt.conf echo "LoggingFilename = /tmp/dlt.log" >>$tmpPath/dlt.conf echo "TimeOutOnSend = 4" >>$tmpPath/dlt.conf echo "RingbufferMinSize = 500000" >>$tmpPath/dlt.conf echo "RingbufferMaxSize = 10000000" >>$tmpPath/dlt.conf echo "RingbufferStepSize = 500000" >>$tmpPath/dlt.conf echo "ControlSocketPath = /tmp/dlt-ctrl.sock" >>$tmpPath/dlt.conf echo "GatewayConfigFile = /tmp/dlt_gateway.conf" >>$tmpPath/dlt.conf touch $tmpPath/dlt_gateway.conf if [ $? -eq '1' ] then echo "Error in creating dlt_gateway file" return 1 fi echo "[PassiveNode1]" >>$tmpPath/dlt_gateway.conf echo "IPaddress=$ipaddr">>$tmpPath/dlt_gateway.conf echo "Port=3490" >>$tmpPath/dlt_gateway.conf echo "EcuID=ECU1" >>$tmpPath/dlt_gateway.conf echo "Connect=OnStartup" >>$tmpPath/dlt_gateway.conf echo "Timeout=10" >>$tmpPath/dlt_gateway.conf echo "SendControl=0x03,0x13" >>$tmpPath/dlt_gateway.conf echo "SendSerialHeader=0" >>$tmpPath/dlt_gateway.conf echo "NOFiles=1" >>$tmpPath/dlt_gateway.conf return 0 } # # Function: -startDaemons() # # Description -Start dlt-daemon as passive node # -Start dlt-daemon as gateway node # # Return -Zero on success # -Non zero on failure # startDaemons() { DLT_PASSIVE_SHM_NAME="" tmpPath=/tmp dlt-daemon -d sleep 1 # Check if the dlt shm file exist (DLT_SHM_ENABLE=ON) if [ -f /dev/shm/dlt-shm ]; then DLT_PASSIVE_SHM_NAME="-s dlt-shm-passive" fi dlt-daemon -d -p 3495 -c $tmpPath/dlt.conf $DLT_PASSIVE_SHM_NAME return 0 } # # Function: -checkDaemonStart # # Description -Check if dlt-daemon instances started successfully # checkDaemonStart() { if [ "$OS" = "QNX" ]; then slay -p dlt-daemon > /dev/null total=$? else total=`pgrep -c dlt-daemon` fi if [ $total -ne '2' ]; then echo "Initialization of dlt-daemon instances failed" exit fi } help() { echo "Usage: " echo "sh ./gtest_dlt_daemon_gateway.sh" } executeTests() { echo "Execute: gtest_dlt_daemon_gateway unit test" } #main function ######################################################################################## getOSname echo "Cleaning up dlt-daemon instances" cleanup if [ $? -ne '0' ] then help exit fi echo "Initializing test" setupTest if [ $? -ne '0' ] then help exit fi echo "Restarting dlt-daemons" startDaemons checkDaemonStart executeTests dlt-daemon-2.18.4/tests/gtest_dlt_daemon_logstorage.sh000077500000000000000000000030101353342203500230670ustar00rootroot00000000000000#!/bin/sh ######################################################################################## #file : g_test_dlt_daemon_logstorage.sh # #Description : logstorage unit test preparation # #Author Name : Onkar Palkar #Email Id : onkar.palkar@wipro.com # #History : Last modified date : 02/09/2016 ######################################################################################## # # Function: -cleanup() # # Description -Delete dlt_logstorage.conf file from tmp folder if present # # Return -Zero on success # -Non zero on failure # cleanup() { tmpPath=/tmp cd $tmpPath rm -rf $tmpPath/dlt_logstorage.conf return 0 } # # Function: -setupTest() # # Description -create logstorage.conf file # # Return -Zero on success # -Non zero on failure # setupTest() { touch $tmpPath/dlt_logstorage.conf if [ $? -eq '1' ] then echo "Error in creating dlt_logstorage.conf file" return 1 fi echo "[FILTER1]" >>$tmpPath/dlt_logstorage.conf echo "LogAppName=DLST" >>$tmpPath/dlt_logstorage.conf echo "ContextName=.*" >>$tmpPath/dlt_logstorage.conf echo "LogLevel=DLT_LOG_ERROR" >>$tmpPath/dlt_logstorage.conf echo "File=Test" >>$tmpPath/dlt_logstorage.conf echo "FileSize=1000000" >>$tmpPath/dlt_logstorage.conf echo "NOFiles=1" >>$tmpPath/dlt_logstorage.conf return 0 } #main function ######################################################################################## cleanup setupTest dlt-daemon-2.18.4/tests/gtest_dlt_daemon_offline_log.cpp000066400000000000000000001642201353342203500233640ustar00rootroot00000000000000/*! * file gtest_dlt_daemon_logstorage.cpp * * Descriptiom : Unit test for dlt_logstorage.c * * Author : Onkar Palkar * * Email : onkar.palkar@wipro.com * * History : 30-Jun-2016 */ #include int connectServer(void); extern "C" { #include "dlt_offline_logstorage.h" #include "dlt_offline_logstorage_internal.h" #include "dlt_offline_logstorage_behavior.h" #include "dlt_offline_logstorage_behavior_internal.h" #include "dlt_daemon_offline_logstorage.h" #include "dlt_daemon_offline_logstorage_internal.h" #include "dlt_daemon_common_cfg.h" #include #include #include #include } #ifndef DLT_DAEMON_BLOCKING_TEST # define DLT_DAEMON_BLOCKING_TEST 1 #endif /* Begin Method: dlt_logstorage::t_dlt_logstorage_list_add*/ TEST(t_dlt_logstorage_list_add, normal) { DltLogStorageFilterList *list = NULL; DltLogStorageFilterConfig *data = NULL; DltLogStorageUserConfig file_config; char *path = (char*)"/tmp"; char key = 1; int num_keys = 1; data = (DltLogStorageFilterConfig *)calloc(1, sizeof(DltLogStorageFilterConfig)); if (data != NULL) { dlt_logstorage_filter_set_strategy(data, DLT_LOGSTORAGE_SYNC_ON_MSG); EXPECT_EQ(DLT_RETURN_OK, dlt_logstorage_list_add(&key, num_keys, data, &list)); EXPECT_EQ(DLT_RETURN_OK, dlt_logstorage_list_destroy(&list, &file_config, path, 0)); } } /* Begin Method: dlt_logstorage::t_dlt_logstorage_list_add_config*/ TEST(t_dlt_logstorage_list_add_config, normal) { DltLogStorageFilterConfig *data = NULL; DltLogStorageFilterConfig *listdata = NULL; data = (DltLogStorageFilterConfig *)calloc(1, sizeof(DltLogStorageFilterConfig)); listdata = (DltLogStorageFilterConfig *)calloc(1, sizeof(DltLogStorageFilterConfig)); if ((data != NULL) && (listdata != NULL)) { dlt_logstorage_list_add_config(data, &listdata); free(data); free(listdata); } } /* Begin Method: dlt_logstorage::t_dlt_logstorage_list_destroy*/ TEST(t_dlt_logstorage_list_destroy, normal) { DltLogStorageFilterList *list = NULL; DltLogStorageFilterConfig *data = NULL; DltLogStorageUserConfig file_config; char *path = (char*)"/tmp"; char key = 1; int num_keys = 1; data = (DltLogStorageFilterConfig *)calloc(1, sizeof(DltLogStorageFilterConfig)); if (data != NULL) { dlt_logstorage_filter_set_strategy(data, DLT_LOGSTORAGE_SYNC_ON_MSG); EXPECT_EQ(DLT_RETURN_OK, dlt_logstorage_list_add(&key, num_keys, data, &list)); EXPECT_EQ(DLT_RETURN_OK, dlt_logstorage_list_destroy(&list, &file_config, path, 0)); } } /* Begin Method: dlt_logstorage::t_dlt_logstorage_list_find*/ TEST(t_dlt_logstorage_list_find, normal) { DltLogStorageFilterList *list = NULL; DltLogStorageFilterConfig *data = NULL; int num_configs = 0; DltLogStorageUserConfig file_config; char *path = (char*)"/tmp"; char key[] = ":1234:5678"; char apid[] = "1234"; char ctid[] = "5678"; int num_keys = 1; DltLogStorageFilterConfig *config[DLT_CONFIG_FILE_SECTIONS_MAX] = { 0 }; data = (DltLogStorageFilterConfig *)calloc(1, sizeof(DltLogStorageFilterConfig)); if (data != NULL) { data->apids = strdup(apid); data->ctids = strdup(ctid); dlt_logstorage_filter_set_strategy(data, DLT_LOGSTORAGE_SYNC_ON_MSG); ASSERT_EQ(DLT_RETURN_OK, dlt_logstorage_list_add(key, num_keys, data, &list)); num_configs = dlt_logstorage_list_find(key, &list, config); ASSERT_EQ(1, num_configs); ASSERT_NE((DltLogStorageFilterConfig *)NULL, config[0]); EXPECT_STREQ(apid, config[0]->apids); EXPECT_STREQ(ctid, config[0]->ctids); EXPECT_EQ(DLT_RETURN_OK, dlt_logstorage_list_destroy(&list, &file_config, path, 0)); } } /* Begin Method: dlt_logstorage::t_dlt_logstorage_free*/ TEST(t_dlt_logstorage_free, normal) { char key = 1; DltLogStorage handle; DltLogStorageFilterConfig *data = NULL; int reason = 0; handle.num_configs = 0; handle.config_list = NULL; int num_keys = 1; data = (DltLogStorageFilterConfig *)calloc(1, sizeof(DltLogStorageFilterConfig)); if (data != NULL) { dlt_logstorage_filter_set_strategy(data, DLT_LOGSTORAGE_SYNC_ON_MSG); EXPECT_EQ(DLT_RETURN_OK, dlt_logstorage_list_add(&key, num_keys, data, &handle.config_list)); dlt_logstorage_free(&handle, reason); } } /* Begin Method: dlt_logstorage::t_dlt_logstorage_count_ids*/ TEST(t_dlt_logstorage_count_ids, normal) { char const *str = "a,b,c,d"; EXPECT_EQ(4, dlt_logstorage_count_ids(str)); } TEST(t_dlt_logstorage_count_ids, null) { EXPECT_EQ(DLT_RETURN_ERROR, dlt_logstorage_count_ids(NULL)); } /* Begin Method: dlt_logstorage::t_dlt_logstorage_read_number*/ TEST(t_dlt_logstorage_read_number, normal) { char str[] = "100"; unsigned int number; EXPECT_EQ(DLT_RETURN_OK, dlt_logstorage_read_number(&number, str)); EXPECT_EQ(100, number); } TEST(t_dlt_logstorage_read_number, null) { unsigned int number; EXPECT_EQ(DLT_RETURN_ERROR, dlt_logstorage_read_number(&number, NULL)); } /* Begin Method: dlt_logstorage::t_dlt_logstorage_create_keys*/ TEST(t_dlt_logstorage_create_keys, normal) { DltLogStorageFilterConfig data; char *keys = NULL; int num_keys = 0; char apids[] = "1234"; char ctids[] = "5678"; char ecuid[] = "ECU1"; data.apids = apids; data.ctids = ctids; EXPECT_EQ(DLT_RETURN_OK, dlt_logstorage_create_keys(data.apids, data.ctids, ecuid, &keys, &num_keys)); } /* Begin Method: dlt_logstorage::t_dlt_logstorage_prepare_table*/ TEST(t_dlt_logstorage_prepare_table, normal) { DltLogStorage handle; DltLogStorageFilterConfig data; DltLogStorageUserConfig file_config; char *path = (char*)"/tmp"; memset(&handle, 0, sizeof(DltLogStorage)); memset(&data, 0, sizeof(DltLogStorageFilterConfig)); char apids[] = "1234"; char ctids[] = "5678"; data.apids = apids; data.ctids = ctids; data.records = NULL; data.log = NULL; data.cache = NULL; dlt_logstorage_filter_set_strategy(&data, DLT_LOGSTORAGE_SYNC_ON_MSG); EXPECT_EQ(DLT_RETURN_OK, dlt_logstorage_prepare_table(&handle, &data)); EXPECT_EQ(DLT_RETURN_OK, dlt_logstorage_list_destroy(&handle.config_list, &file_config, path, 0)); } TEST(t_dlt_logstorage_prepare_table, null) { EXPECT_EQ(DLT_RETURN_ERROR, dlt_logstorage_prepare_table(NULL, NULL)); } /* Begin Method: dlt_logstorage::t_dlt_logstorage_validate_filter_name*/ TEST(t_dlt_logstorage_validate_filter_name, normal) { char name[] = "FILTER100"; EXPECT_EQ(DLT_RETURN_OK, dlt_logstorage_validate_filter_name(name)); } TEST(t_dlt_logstorage_validate_filter_name, null) { EXPECT_EQ(DLT_RETURN_ERROR, dlt_logstorage_validate_filter_name(NULL)); } /* Begin Method: dlt_logstorage::t_dlt_logstorage_filter_set_strategy*/ TEST(t_dlt_logstorage_filter_set_strategy, normal) { DltLogStorageFilterConfig config; dlt_logstorage_filter_set_strategy(&config, DLT_LOGSTORAGE_SYNC_ON_MSG); EXPECT_EQ(&dlt_logstorage_prepare_on_msg, config.dlt_logstorage_prepare); dlt_logstorage_filter_set_strategy(&config, 2); EXPECT_EQ(&dlt_logstorage_prepare_msg_cache, config.dlt_logstorage_prepare); } /* Begin Method: dlt_logstorage::t_dlt_logstorage_read_list_of_names*/ TEST(t_dlt_logstorage_read_list_of_names, normal) { char *namesPtr = NULL; char value[] = "a,b,c,d"; namesPtr = (char *)calloc (1, sizeof(char)); if (namesPtr != NULL) { EXPECT_EQ(DLT_RETURN_OK, dlt_logstorage_read_list_of_names(&namesPtr, value)); free(namesPtr); } } TEST(t_dlt_logstorage_read_list_of_names, null) { EXPECT_EQ(DLT_RETURN_ERROR, dlt_logstorage_read_list_of_names(NULL, NULL)); } /* Begin Method: dlt_logstorage::t_dlt_logstorage_check_apids*/ TEST(t_dlt_logstorage_check_apids, normal) { char value[] = "a,b,c,d"; DltLogStorageFilterConfig config; config.apids = (char *)calloc (1, sizeof(char)); if (config.apids != NULL) { EXPECT_EQ(DLT_RETURN_OK, dlt_logstorage_check_apids(&config, value)); free(config.apids); } } TEST(t_dlt_logstorage_check_apids, null) { EXPECT_EQ(DLT_RETURN_ERROR, dlt_logstorage_check_apids(NULL, NULL)); } /* Begin Method: dlt_logstorage::t_dlt_logstorage_check_ctids*/ TEST(t_dlt_logstorage_check_ctids, normal) { char value[] = "a,b,c,d"; DltLogStorageFilterConfig config; config.ctids = (char *)calloc (1, sizeof(char)); if (config.ctids != NULL) { EXPECT_EQ(DLT_RETURN_OK, dlt_logstorage_check_ctids(&config, value)); free(config.ctids); } } TEST(t_dlt_logstorage_check_ctids, null) { EXPECT_EQ(DLT_RETURN_ERROR, dlt_logstorage_check_ctids(NULL, NULL)); } /* Begin Method: dlt_logstorage::t_dlt_logstorage_check_loglevel*/ TEST(t_dlt_logstorage_check_loglevel, normal) { char value[] = "DLT_LOG_FATAL"; DltLogStorageFilterConfig config; EXPECT_EQ(DLT_RETURN_OK, dlt_logstorage_check_loglevel(&config, value)); EXPECT_EQ(1, config.log_level); } TEST(t_dlt_logstorage_check_loglevel, null) { EXPECT_EQ(DLT_RETURN_ERROR, dlt_logstorage_check_loglevel(NULL, NULL)); } /* Begin Method: dlt_logstorage::t_dlt_logstorage_check_filename*/ TEST(t_dlt_logstorage_check_filename, normal) { char value[] = "file_name"; DltLogStorageFilterConfig config; config.file_name = (char *)calloc (1, sizeof(char)); if (config.file_name != NULL) { EXPECT_EQ(DLT_RETURN_OK, dlt_logstorage_check_filename(&config, value)); free(config.file_name); } } TEST(t_dlt_logstorage_check_filename, abnormal) { char value[] = "../file_name"; DltLogStorageFilterConfig config; config.file_name = (char *)calloc (1, sizeof(char)); if (config.file_name != NULL) { EXPECT_EQ(DLT_RETURN_ERROR, dlt_logstorage_check_filename(&config, value)); free(config.file_name); } } TEST(t_dlt_logstorage_check_filename, null) { EXPECT_EQ(DLT_RETURN_ERROR, dlt_logstorage_check_filename(NULL, NULL)); } /* Begin Method: dlt_logstorage::t_dlt_logstorage_check_filesize*/ TEST(t_dlt_logstorage_check_filesize, normal) { char value[] = "100"; DltLogStorageFilterConfig config; EXPECT_EQ(DLT_RETURN_OK, dlt_logstorage_check_filesize(&config, value)); EXPECT_EQ(100, config.file_size); } TEST(t_dlt_logstorage_check_filesize, null) { EXPECT_EQ(DLT_RETURN_ERROR, dlt_logstorage_check_filesize(NULL, NULL)); } /* Begin Method: dlt_logstorage::t_dlt_logstorage_check_nofiles*/ TEST(t_dlt_logstorage_check_nofiles, normal) { char value[] = "100"; DltLogStorageFilterConfig config; EXPECT_EQ(DLT_RETURN_OK, dlt_logstorage_check_nofiles(&config, value)); EXPECT_EQ(100, config.num_files); } TEST(t_dlt_logstorage_check_nofiles, null) { EXPECT_EQ(DLT_RETURN_ERROR, dlt_logstorage_check_nofiles(NULL, NULL)); } /* Begin Method: dlt_logstorage::t_dlt_logstorage_check_sync_strategy*/ TEST(t_dlt_logstorage_check_sync_strategy, normal) { char value[] = "ON_MSG"; DltLogStorageFilterConfig config; config.sync = 0; EXPECT_EQ(DLT_RETURN_OK, dlt_logstorage_check_sync_strategy(&config, value)); EXPECT_EQ(DLT_LOGSTORAGE_SYNC_ON_MSG, config.sync); } TEST(t_dlt_logstorage_check_sync_strategy, abnormal) { char value[] = "UNKNOWN"; DltLogStorageFilterConfig config; config.sync = 0; EXPECT_EQ(DLT_RETURN_TRUE, dlt_logstorage_check_sync_strategy(&config, value)); EXPECT_EQ(DLT_LOGSTORAGE_SYNC_ON_MSG, config.sync); } TEST(t_dlt_logstorage_check_sync_strategy, null) { EXPECT_EQ(DLT_RETURN_ERROR, dlt_logstorage_check_sync_strategy(NULL, NULL)); } /* Begin Method: dlt_logstorage::t_dlt_logstorage_check_ecuid*/ TEST(t_dlt_logstorage_check_ecuid, normal) { char value[] = "213"; DltLogStorageFilterConfig config; config.ecuid = (char *)calloc (1, sizeof(char)); if (config.ecuid != NULL) { EXPECT_EQ(DLT_RETURN_OK, dlt_logstorage_check_ecuid(&config, value)); EXPECT_EQ('2', *config.ecuid); EXPECT_EQ('1', *(config.ecuid + 1)); EXPECT_EQ('3', *(config.ecuid + 2)); free(config.ecuid); } } TEST(t_dlt_logstorage_check_ecuid, null) { EXPECT_EQ(DLT_RETURN_ERROR, dlt_logstorage_check_ecuid(NULL, NULL)); } /* Begin Method: dlt_logstorage::t_dlt_logstorage_check_param*/ TEST(t_dlt_logstorage_check_param, normal) { char value[] = "100"; DltLogStorageFilterConfig config; EXPECT_EQ(DLT_RETURN_OK, dlt_logstorage_check_param(&config, DLT_LOGSTORAGE_FILTER_CONF_FILESIZE, value)); EXPECT_EQ(100, config.file_size); } TEST(t_dlt_logstorage_check_param, null) { EXPECT_EQ(DLT_RETURN_ERROR, dlt_logstorage_check_param(NULL, DLT_LOGSTORAGE_FILTER_CONF_FILESIZE, NULL)); } /* Begin Method: dlt_logstorage::t_dlt_logstorage_store_filters*/ TEST(t_dlt_logstorage_store_filters, normal) { DltLogStorage handle; DltLogStorageUserConfig file_config; char *path = (char*)"/tmp"; char config_file_name[] = "/tmp/dlt_logstorage.conf"; handle.connection_type = DLT_OFFLINE_LOGSTORAGE_DEVICE_CONNECTED; handle.config_status = 0; handle.write_errors = 0; handle.config_list = NULL; EXPECT_EQ(DLT_RETURN_OK, dlt_logstorage_store_filters(&handle, config_file_name)); EXPECT_EQ(DLT_RETURN_OK, dlt_logstorage_list_destroy(&handle.config_list, &file_config, path, 0)); } TEST(t_dlt_logstorage_store_filters, null) { EXPECT_EQ(DLT_RETURN_ERROR, dlt_logstorage_store_filters(NULL, NULL)); } /* Begin Method: dlt_logstorage::t_dlt_logstorage_load_config*/ TEST(t_dlt_logstorage_load_config, normal) { DltLogStorage handle; DltLogStorageUserConfig file_config; char *path = (char*)"/tmp"; handle.connection_type = DLT_OFFLINE_LOGSTORAGE_DEVICE_CONNECTED; handle.config_status = 0; handle.write_errors = 0; handle.config_list = NULL; strncpy(handle.device_mount_point, "/tmp", DLT_MOUNT_PATH_MAX); EXPECT_EQ(DLT_RETURN_OK, dlt_logstorage_load_config(&handle)); EXPECT_EQ(DLT_RETURN_OK, dlt_logstorage_list_destroy(&handle.config_list, &file_config, path, 0)); } TEST(t_dlt_logstorage_load_config, null) { EXPECT_EQ(DLT_RETURN_ERROR, dlt_logstorage_load_config(NULL)); } /* Begin Method: dlt_logstorage::t_dlt_logstorage_device_connected*/ TEST(t_dlt_logstorage_device_connected, normal) { DltLogStorage handle; handle.connection_type = DLT_OFFLINE_LOGSTORAGE_DEVICE_DISCONNECTED; handle.config_status = 0; handle.write_errors = 0; handle.config_list = NULL; strncpy(handle.device_mount_point, "/tmp", DLT_MOUNT_PATH_MAX); EXPECT_EQ(DLT_RETURN_OK, dlt_logstorage_device_connected(&handle, handle.device_mount_point)); } TEST(t_dlt_logstorage_device_connected, null) { EXPECT_EQ(DLT_RETURN_ERROR, dlt_logstorage_device_connected(NULL, NULL)); } /* Begin Method: dlt_logstorage::t_dlt_logstorage_device_disconnected*/ TEST(t_dlt_logstorage_device_disconnected, normal) { DltLogStorage handle; int reason = 0; handle.config_status = 0; EXPECT_EQ(DLT_RETURN_OK, dlt_logstorage_device_disconnected(&handle, reason)); } TEST(t_dlt_logstorage_device_disconnected, null) { EXPECT_EQ(DLT_RETURN_ERROR, dlt_logstorage_device_disconnected(NULL, 1)); } TEST(t_dlt_logstorage_get_loglevel_by_key, normal) { char arr[] = "abc"; char *key = arr; DltLogStorageFilterConfig *config = NULL; DltLogStorage handle; handle.config_status = 0; handle.connection_type = DLT_OFFLINE_LOGSTORAGE_DEVICE_CONNECTED; handle.config_status = DLT_OFFLINE_LOGSTORAGE_CONFIG_DONE; handle.config_list = NULL; int num_keys = 1; config = (DltLogStorageFilterConfig *)calloc(1, sizeof(DltLogStorageFilterConfig)); if (config != NULL) { config->log_level = DLT_LOG_ERROR; EXPECT_EQ(DLT_RETURN_OK, dlt_logstorage_list_add(key, num_keys, config, &(handle.config_list))); EXPECT_GE(DLT_LOG_ERROR, dlt_logstorage_get_loglevel_by_key(&handle, key)); free(config); } } TEST(t_dlt_logstorage_get_loglevel_by_key, null) { EXPECT_EQ(DLT_RETURN_ERROR, dlt_logstorage_get_loglevel_by_key(NULL, NULL)); } /* Begin Method: dlt_logstorage::t_dlt_logstorage_get_config*/ TEST(t_dlt_logstorage_get_config, normal) { char apid[] = "1234"; char ctid[] = "5678"; char ecuid[] = "12"; char file_name[] = "file_name"; int num_config = 0; DltLogStorageFilterConfig value; value.log_level = 0; value.apids = apid; value.ctids = ctid; value.ecuid = ecuid; value.file_name = file_name; char key0[] = ":1234:\000\000\000\000"; char key1[] = "::5678\000\000\000\000"; char key2[] = ":1234:5678"; DltLogStorageFilterConfig *config[3] = { 0 }; DltLogStorage handle; handle.connection_type = DLT_OFFLINE_LOGSTORAGE_DEVICE_CONNECTED; handle.config_status = DLT_OFFLINE_LOGSTORAGE_CONFIG_DONE; handle.config_list = NULL; int num_keys = 1; EXPECT_EQ(DLT_RETURN_OK, dlt_logstorage_list_add(key0, num_keys, &value, &(handle.config_list))); EXPECT_EQ(DLT_RETURN_OK, dlt_logstorage_list_add(key1, num_keys, &value, &(handle.config_list))); EXPECT_EQ(DLT_RETURN_OK, dlt_logstorage_list_add(key2, num_keys, &value, &(handle.config_list))); num_config = dlt_logstorage_get_config(&handle, config, apid, ctid, ecuid); EXPECT_EQ(num_config, 3); } TEST(t_dlt_logstorage_get_config, null) { int num = -1; num = dlt_logstorage_get_config(NULL, NULL, NULL, NULL, NULL); EXPECT_EQ(num, 0); } /* Begin Method: dlt_logstorage::t_dlt_logstorage_filter*/ TEST(t_dlt_logstorage_filter, normal) { char apid[] = "1234"; char ctid[] = "5678"; char ecuid[] = "12"; char filename[] = "file_name"; int num = 1; DltLogStorageFilterConfig value; value.apids = apid; value.ctids = ctid; value.ecuid = ecuid; value.file_name = filename; value.log_level = DLT_LOG_VERBOSE; char key0[] = ":1234:\000\000\000\000"; char key1[] = "::5678\000\000\000\000"; char key2[] = ":1234:5678"; DltLogStorageFilterConfig *config[DLT_CONFIG_FILE_SECTIONS_MAX] = { 0 }; DltLogStorage handle; handle.connection_type = DLT_OFFLINE_LOGSTORAGE_DEVICE_CONNECTED; handle.config_status = DLT_OFFLINE_LOGSTORAGE_CONFIG_DONE; handle.config_list = NULL; int num_keys = 1; EXPECT_EQ(DLT_RETURN_OK, dlt_logstorage_list_add(key0, num_keys, &value, &(handle.config_list))); EXPECT_EQ(DLT_RETURN_OK, dlt_logstorage_list_add(key1, num_keys, &value, &(handle.config_list))); EXPECT_EQ(DLT_RETURN_OK, dlt_logstorage_list_add(key2, num_keys, &value, &(handle.config_list))); num = dlt_logstorage_filter(&handle, config, apid, ctid, ecuid, 0); EXPECT_EQ(num, 3); } TEST(t_dlt_logstorage_filter, null) { DltLogStorageFilterConfig *config[3] = { 0 }; int num = dlt_logstorage_filter(NULL, config, NULL, NULL, NULL, 0); EXPECT_EQ(DLT_RETURN_ERROR, num); } /* Begin Method: dlt_logstorage::t_dlt_logstorage_write*/ TEST(t_dlt_logstorage_write, normal) { char apid[] = "1234"; char ctid[] = "5678"; char ecuid[] = "12"; char file_name[] = "file_name"; DltLogStorage handle; DltLogStorageUserConfig uconfig; unsigned char data1[] = "123"; int size1 = 3; unsigned char data2[] = "123"; int size2 = 3; unsigned char data3[] = "123"; int size3 = 3; handle.connection_type = DLT_OFFLINE_LOGSTORAGE_DEVICE_CONNECTED; handle.config_status = DLT_OFFLINE_LOGSTORAGE_CONFIG_DONE; handle.config_list = NULL; DltLogStorageFilterConfig value; value.apids = apid; value.ctids = ctid; value.ecuid = ecuid; value.file_name = file_name; char key0[] = ":1234:\000\000\000\000"; char key1[] = "::5678\000\000\000\000"; char key2[] = ":1234:5678"; int num_keys = 1; EXPECT_EQ(DLT_RETURN_OK, dlt_logstorage_list_add(key0, num_keys, &value, &(handle.config_list))); EXPECT_EQ(DLT_RETURN_OK, dlt_logstorage_list_add(key1, num_keys, &value, &(handle.config_list))); EXPECT_EQ(DLT_RETURN_OK, dlt_logstorage_list_add(key2, num_keys, &value, &(handle.config_list))); EXPECT_EQ(DLT_RETURN_OK, dlt_logstorage_write(&handle, &uconfig, data1, size1, data2, size2, data3, size3)); } TEST(t_dlt_logstorage_write, null) { EXPECT_EQ(0, dlt_logstorage_write(NULL, NULL, NULL, 1, NULL, 1, NULL, 1)); } /* Begin Method: dlt_logstorage::t_dlt_logstorage_sync_caches*/ TEST(t_dlt_logstorage_sync_caches, normal) { char apid[] = "1234"; char ctid[] = "5678"; char ecuid[] = "12"; char filename[] = "file_name"; char key[] = "12:1234:5678"; DltLogStorage handle; handle.num_configs = 1; handle.config_list = NULL; DltLogStorageFilterConfig configs; configs.apids = apid; configs.ctids = ctid; configs.ecuid = ecuid; configs.file_name = filename; int num_keys = 1; dlt_logstorage_filter_set_strategy(&configs, DLT_LOGSTORAGE_SYNC_ON_MSG); EXPECT_EQ(DLT_RETURN_OK, dlt_logstorage_list_add(key, num_keys, &configs, &(handle.config_list))); EXPECT_EQ(DLT_RETURN_OK, dlt_logstorage_sync_caches(&handle)); } /* Begin Method: dlt_logstorage::t_dlt_logstorage_log_file_name*/ TEST(t_dlt_logstorage_log_file_name, normal) { char log_file_name[DLT_MOUNT_PATH_MAX] = { '\0' }; DltLogStorageUserConfig file_config; file_config.logfile_delimiter = '/'; file_config.logfile_maxcounter = 0; file_config.logfile_timestamp = 1; file_config.logfile_counteridxlen = 10; int cmpRes = 0; char name[] = "log"; dlt_logstorage_log_file_name(log_file_name, &file_config, name, 0); cmpRes = strncmp(log_file_name, "log/0000000000", 14); EXPECT_EQ(0, cmpRes); } TEST(t_dlt_logstorage_log_file_name, null) { char name[] = "log"; dlt_logstorage_log_file_name(NULL, NULL, name, 0); } /* Begin Method: dlt_logstorage::t_dlt_logstorage_sort_file_name*/ TEST(t_dlt_logstorage_sort_file_name, normal) { DltLogStorageFileList *node1, *node2, *node3; DltLogStorageFileList **head; node1 = (DltLogStorageFileList *)calloc (1, sizeof(DltLogStorageFileList)); node2 = (DltLogStorageFileList *)calloc (1, sizeof(DltLogStorageFileList)); node3 = (DltLogStorageFileList *)calloc (1, sizeof(DltLogStorageFileList)); if ((node1 != NULL) && (node2 != NULL) && (node3 != NULL)) { node1->next = node2; node2->next = node3; node3->next = NULL; head = &node1; node1->idx = 8; node2->idx = 4; node3->idx = 1; EXPECT_EQ(8, (*head)->idx); EXPECT_EQ(4, ((*head)->next)->idx); EXPECT_EQ(1, ((((*head)->next)->next)->idx)); dlt_logstorage_sort_file_name(head); EXPECT_EQ(1, (*head)->idx); EXPECT_EQ(4, ((*head)->next)->idx); EXPECT_EQ(8, ((((*head)->next)->next)->idx)); free((((*head)->next)->next)); free(((*head)->next)); free(*head); node1 = NULL; node2 = NULL; node3 = NULL; } if (node1 != NULL) free(node1); if (node2 != NULL) free(node2); if (node3 != NULL) free(node3); } TEST(t_dlt_logstorage_sort_file_name, null) { dlt_logstorage_sort_file_name(NULL); } /* Begin Method: dlt_logstorage::t_dlt_logstorage_rearrange_file_name*/ TEST(t_dlt_logstorage_rearrange_file_name, normal) { DltLogStorageFileList *node1, *node2, *node3; DltLogStorageFileList **head; node1 = (DltLogStorageFileList *)calloc (1, sizeof(DltLogStorageFileList)); node2 = (DltLogStorageFileList *)calloc (1, sizeof(DltLogStorageFileList)); node3 = (DltLogStorageFileList *)calloc (1, sizeof(DltLogStorageFileList)); if ((node1 != NULL) && (node2 != NULL) && (node3 != NULL)) { node1->next = node2; node2->next = node3; node3->next = NULL; head = &node1; node1->idx = 8; node2->idx = 4; node3->idx = 1; EXPECT_EQ(8, (*head)->idx); EXPECT_EQ(4, ((*head)->next)->idx); EXPECT_EQ(1, ((((*head)->next)->next)->idx)); dlt_logstorage_rearrange_file_name(head); EXPECT_EQ(1, (*head)->idx); EXPECT_EQ(8, ((*head)->next)->idx); EXPECT_EQ(4, ((((*head)->next)->next)->idx)); free((((*head)->next)->next)); free(((*head)->next)); free(*head); node1 = NULL; node2 = NULL; node3 = NULL; } if (node1 != NULL) free(node1); if (node2 != NULL) free(node2); if (node3 != NULL) free(node3); } TEST(t_dlt_logstorage_rearrange_file_name, null) { dlt_logstorage_rearrange_file_name(NULL); } /* Begin Method: dlt_logstorage::t_dlt_logstorage_get_idx_of_log_file*/ TEST(t_dlt_logstorage_get_idx_of_log_file, normal) { DltLogStorageUserConfig file_config; file_config.logfile_timestamp = 191132; file_config.logfile_delimiter = { '_' }; file_config.logfile_maxcounter = 2; file_config.logfile_counteridxlen = 2; char *file = (char *)"Test_002_20160509_191132.dlt"; EXPECT_EQ(2, dlt_logstorage_get_idx_of_log_file(&file_config, file)); } TEST(t_dlt_logstorage_get_idx_of_log_file, null) { EXPECT_EQ(DLT_RETURN_ERROR, dlt_logstorage_get_idx_of_log_file(NULL, NULL)); } /* Begin Method: dlt_logstorage::t_dlt_logstorage_storage_dir_info*/ TEST(t_dlt_logstorage_storage_dir_info, normal) { DltLogStorageUserConfig file_config; file_config.logfile_timestamp = 191132; file_config.logfile_delimiter = { '_' }; file_config.logfile_maxcounter = 2; file_config.logfile_counteridxlen = 2; char *path = (char *)"/tmp"; DltLogStorageFilterConfig config; char apids; char ctids; config.apids = &apids; config.ctids = &ctids; config.file_name = (char *)"Test_002_20160509_191132.dlt"; config.records = NULL; EXPECT_EQ(DLT_RETURN_OK, dlt_logstorage_storage_dir_info(&file_config, path, &config)); } TEST(t_dlt_logstorage_storage_dir_info, null) { EXPECT_EQ(DLT_RETURN_ERROR, dlt_logstorage_storage_dir_info(NULL, NULL, NULL)); } /* Begin Method: dlt_logstorage::t_dlt_logstorage_open_log_file*/ TEST(t_dlt_logstorage_open_log_file, normal) { DltLogStorageUserConfig file_config; file_config.logfile_timestamp = 191132; file_config.logfile_delimiter = { '_' }; file_config.logfile_maxcounter = 2; file_config.logfile_counteridxlen = 2; char *path = (char *)"/tmp"; DltLogStorageFilterConfig config; char apids; char ctids; config.apids = &apids; config.ctids = &ctids; config.file_name = (char *)"Test"; config.records = NULL; EXPECT_EQ(DLT_RETURN_OK, dlt_logstorage_open_log_file(&config, &file_config, path, 1)); } TEST(t_dlt_logstorage_open_log_file, null) { EXPECT_EQ(DLT_RETURN_ERROR, dlt_logstorage_open_log_file(NULL, NULL, NULL, 0)); } /* Begin Method: dlt_logstorage::t_dlt_logstorage_prepare_on_msg*/ TEST(t_dlt_logstorage_prepare_on_msg, normal) { DltLogStorageUserConfig file_config; file_config.logfile_timestamp = 191132; file_config.logfile_delimiter = { '_' }; file_config.logfile_maxcounter = 2; file_config.logfile_counteridxlen = 2; char *path = (char *)"/tmp"; DltLogStorageFilterConfig config; char apids; char ctids; config.apids = &apids; config.ctids = &ctids; config.file_name = (char *)"Test"; config.records = NULL; config.log = NULL; EXPECT_EQ(DLT_RETURN_OK, dlt_logstorage_prepare_on_msg(&config, &file_config, path, 1)); } TEST(t_dlt_logstorage_prepare_on_msg, null) { EXPECT_EQ(DLT_RETURN_ERROR, dlt_logstorage_prepare_on_msg(NULL, NULL, NULL, 0)); } /* Begin Method: dlt_logstorage::t_dlt_logstorage_write_on_msg*/ TEST(t_dlt_logstorage_write_on_msg, normal) { DltLogStorageUserConfig file_config; file_config.logfile_timestamp = 191132; file_config.logfile_delimiter = { '_' }; file_config.logfile_maxcounter = 2; file_config.logfile_counteridxlen = 2; char *path = (char *)"/tmp"; DltLogStorageFilterConfig config; char apids; char ctids; config.apids = &apids; config.ctids = &ctids; config.file_name = (char *)"Test"; config.records = NULL; config.log = NULL; unsigned int size = 8; unsigned char data1[] = "dlt_data"; unsigned char data2[] = "dlt_data"; unsigned char data3[] = "dlt_data"; EXPECT_EQ(DLT_RETURN_OK, dlt_logstorage_prepare_on_msg(&config, &file_config, path, 1)); EXPECT_EQ(DLT_RETURN_OK, dlt_logstorage_write_on_msg(&config, &file_config, path, data1, size, data2, size, data3, size)); } TEST(t_dlt_logstorage_write_on_msg, null) { EXPECT_EQ(DLT_RETURN_ERROR, dlt_logstorage_write_on_msg(NULL, NULL, NULL, NULL, 0, NULL, 0, NULL, 0)); } /* Begin Method: dlt_logstorage::t_dlt_logstorage_sync_on_msg*/ TEST(t_dlt_logstorage_sync_on_msg, normal) { DltLogStorageFilterConfig config; DltLogStorageUserConfig file_config; char apids; char ctids; memset(&config, 0, sizeof(DltLogStorageFilterConfig)); config.apids = &apids; config.ctids = &ctids; config.file_name = (char *)"Test"; config.records = NULL; config.log = NULL; char *path = NULL; EXPECT_EQ(DLT_RETURN_OK, dlt_logstorage_sync_on_msg(&config, &file_config, path, DLT_LOGSTORAGE_SYNC_ON_MSG)); } TEST(t_dlt_logstorage_sync_on_msg, null) { EXPECT_EQ(DLT_RETURN_ERROR, dlt_logstorage_sync_on_msg(NULL, NULL, NULL, 0)); } /* Begin Method: dlt_logstorage::t_dlt_logstorage_prepare_msg_cache*/ TEST(t_dlt_logstorage_prepare_msg_cache, normal) { DltLogStorageUserConfig file_config; file_config.logfile_timestamp = 191132; file_config.logfile_delimiter = { '_' }; file_config.logfile_maxcounter = 2; file_config.logfile_counteridxlen = 2; char *path = (char *)"/tmp"; DltLogStorageFilterConfig config; char apids; char ctids; config.apids = &apids; config.ctids = &ctids; config.file_name = (char *)"Test"; config.records = NULL; config.log = NULL; config.cache = NULL; config.file_size = 0; config.sync = DLT_LOGSTORAGE_SYNC_ON_DEMAND; g_logstorage_cache_max = 16; EXPECT_EQ(DLT_RETURN_OK, dlt_logstorage_prepare_msg_cache(&config, &file_config, path, 1)); free(config.cache); } TEST(t_dlt_logstorage_prepare_msg_cache, null) { EXPECT_EQ(DLT_RETURN_ERROR, dlt_logstorage_prepare_msg_cache(NULL, NULL, NULL, 0)); } /* Begin Method: dlt_logstorage::t_dlt_logstorage_write_msg_cache*/ TEST(t_dlt_logstorage_write_msg_cache, normal) { unsigned int size = 10; unsigned char data1[10] = "dlt_data1"; unsigned char data2[10] = "dlt_data2"; unsigned char data3[10] = "dlt_dat3"; DltLogStorageFilterConfig config; memset(&config, 0, sizeof(DltLogStorageFilterConfig)); DltLogStorageUserConfig file_config; char *path = (char*)"/tmp"; config.cache = calloc(1, 50 + sizeof(DltLogStorageCacheFooter)); if (config.cache != NULL) { config.file_size = 50; EXPECT_EQ(DLT_RETURN_OK, dlt_logstorage_write_msg_cache(&config, &file_config, path, data1, size, data2, size, data3, size)); free(config.cache); config.cache = NULL; } } TEST(t_dlt_logstorage_write_msg_cache, null) { EXPECT_EQ(DLT_RETURN_ERROR, dlt_logstorage_write_msg_cache(NULL, NULL, NULL, NULL, 0, NULL, 0, NULL, 0)); } /* Begin Method: dlt_logstorage::t_dlt_logstorage_split_key*/ TEST(t_dlt_logstorage_split_key, normal) { char key[] = "dlt:1020:"; char apid[] = ":2345:"; char ctid[] = "::6789"; char ecuid[] = "ECU1"; EXPECT_EQ(DLT_RETURN_OK, dlt_logstorage_split_key(key, apid, ctid, ecuid)); } TEST(t_dlt_logstorage_split_key, null) { char key[] = "dlt:1020:"; char apid[] = "2345"; char ctid[] = "6789"; char ecuid[] = "ECU1"; EXPECT_EQ(DLT_RETURN_WRONG_PARAMETER, dlt_logstorage_split_key(NULL, NULL, NULL, NULL)); EXPECT_EQ(DLT_RETURN_WRONG_PARAMETER, dlt_logstorage_split_key(NULL, apid, ctid, ecuid)); EXPECT_EQ(DLT_RETURN_WRONG_PARAMETER, dlt_logstorage_split_key(key, NULL, ctid, ecuid)); EXPECT_EQ(DLT_RETURN_WRONG_PARAMETER, dlt_logstorage_split_key(key, apid, NULL, ecuid)); EXPECT_EQ(DLT_RETURN_WRONG_PARAMETER, dlt_logstorage_split_key(key, apid, ctid, NULL)); } /* Begin Method: dlt_logstorage::t_dlt_logstorage_update_all_contexts*/ TEST(t_dlt_logstorage_update_all_contexts, normal) { DltDaemon daemon; DltDaemonLocal daemon_local; memset(&daemon, 0, sizeof(DltDaemon)); memset(&daemon_local.pGateway, 0, sizeof(DltGateway)); char ecu[] = "ECU1"; char apid[] = "123"; daemon_local.RingbufferMinSize = DLT_DAEMON_RINGBUFFER_MIN_SIZE; daemon_local.RingbufferMaxSize = DLT_DAEMON_RINGBUFFER_MAX_SIZE; daemon_local.RingbufferStepSize = DLT_DAEMON_RINGBUFFER_STEP_SIZE; EXPECT_EQ(0, dlt_daemon_init(&daemon, daemon_local.RingbufferMinSize, daemon_local.RingbufferMaxSize, daemon_local.RingbufferStepSize, DLT_RUNTIME_DEFAULT_DIRECTORY, DLT_LOG_INFO, DLT_TRACE_STATUS_OFF, 0, 0)); dlt_set_id(daemon.ecuid, ecu); EXPECT_EQ(0, dlt_daemon_init_user_information(&daemon, &daemon_local.pGateway, 0, 0)); EXPECT_EQ(DLT_RETURN_OK, dlt_logstorage_update_all_contexts(&daemon, &daemon_local, apid, 1, 1, ecu, 0)); EXPECT_EQ(DLT_RETURN_OK, dlt_logstorage_update_all_contexts(&daemon, &daemon_local, apid, 0, 1, ecu, 0)); } TEST(t_dlt_logstorage_update_all_contexts, null) { EXPECT_EQ(DLT_RETURN_WRONG_PARAMETER, dlt_logstorage_update_all_contexts(NULL, NULL, NULL, 0, 0, NULL, 0)); } /* Begin Method: dlt_logstorage::t_dlt_logstorage_update_context*/ TEST(t_dlt_logstorage_update_context, normal) { DltDaemon daemon; DltDaemonLocal daemon_local; DltDaemonContext *daecontext = NULL; DltDaemonApplication *app = NULL; memset(&daemon, 0, sizeof(DltDaemon)); memset(&daemon_local, 0, sizeof(DltDaemonLocal)); memset(&daemon_local.pGateway, 0, sizeof(DltGateway)); int fd = connectServer(); EXPECT_NE(-1, fd); daemon_local.RingbufferMinSize = DLT_DAEMON_RINGBUFFER_MIN_SIZE; daemon_local.RingbufferMaxSize = DLT_DAEMON_RINGBUFFER_MAX_SIZE; daemon_local.RingbufferStepSize = DLT_DAEMON_RINGBUFFER_STEP_SIZE; char apid[] = "123"; char ctid[] = "456"; char desc[255] = "TEST dlt_logstorage_update_context"; char ecu[] = "ECU1"; EXPECT_EQ(0, dlt_daemon_init(&daemon, daemon_local.RingbufferMinSize, daemon_local.RingbufferMaxSize, daemon_local.RingbufferStepSize, DLT_RUNTIME_DEFAULT_DIRECTORY, DLT_LOG_INFO, DLT_TRACE_STATUS_OFF, 0, 0)); dlt_set_id(daemon.ecuid, ecu); EXPECT_EQ(0, dlt_daemon_init_user_information(&daemon, &daemon_local.pGateway, 0, 0)); app = dlt_daemon_application_add(&daemon, apid, getpid(), desc, fd, ecu, 0); daecontext = dlt_daemon_context_add(&daemon, apid, ctid, DLT_LOG_DEFAULT, DLT_TRACE_STATUS_DEFAULT, 0, app->user_handle, desc, daemon.ecuid, 0); EXPECT_NE((DltDaemonContext *)(NULL), daecontext); EXPECT_EQ(DLT_RETURN_OK, dlt_logstorage_update_context(&daemon, &daemon_local, apid, ctid, ecu, 1, 0)); EXPECT_EQ(DLT_RETURN_OK, dlt_logstorage_update_context(&daemon, &daemon_local, apid, ctid, ecu, 0, 0)); } TEST(t_dlt_logstorage_update_context, null) { EXPECT_EQ(DLT_RETURN_WRONG_PARAMETER, dlt_logstorage_update_context(NULL, NULL, NULL, NULL, NULL, 0, 0)); } /* Begin Method: dlt_logstorage::t_dlt_logstorage_update_context_loglevel*/ TEST(t_dlt_logstorage_update_context_loglevel, normal) { DltDaemon daemon; DltDaemonLocal daemon_local; DltDaemonContext *daecontext = NULL; DltDaemonApplication *app = NULL; memset(&daemon, 0, sizeof(DltDaemon)); memset(&daemon_local, 0, sizeof(DltDaemonLocal)); memset(&daemon_local.pGateway, 0, sizeof(DltGateway)); int fd = connectServer(); EXPECT_NE(-1, fd); daemon_local.RingbufferMinSize = DLT_DAEMON_RINGBUFFER_MIN_SIZE; daemon_local.RingbufferMaxSize = DLT_DAEMON_RINGBUFFER_MAX_SIZE; daemon_local.RingbufferStepSize = DLT_DAEMON_RINGBUFFER_STEP_SIZE; char apid[] = "123"; char ctid[] = "456"; char key[] = ":123:456"; char desc[255] = "TEST dlt_logstorage_update_context_loglevel"; char ecu[] = "ECU1"; EXPECT_EQ(0, dlt_daemon_init(&daemon, daemon_local.RingbufferMinSize, daemon_local.RingbufferMaxSize, daemon_local.RingbufferStepSize, DLT_RUNTIME_DEFAULT_DIRECTORY, DLT_LOG_INFO, DLT_TRACE_STATUS_OFF, 0, 0)); dlt_set_id(daemon.ecuid, ecu); EXPECT_EQ(0, dlt_daemon_init_user_information(&daemon, &daemon_local.pGateway, 0, 0)); app = dlt_daemon_application_add(&daemon, apid, getpid(), desc, fd, ecu, 0); daecontext = dlt_daemon_context_add(&daemon, apid, ctid, DLT_LOG_DEFAULT, DLT_TRACE_STATUS_DEFAULT, 0, app->user_handle, desc, daemon.ecuid, 0); EXPECT_NE((DltDaemonContext *)(NULL), daecontext); EXPECT_EQ(DLT_RETURN_OK, dlt_logstorage_update_context_loglevel (&daemon, &daemon_local, key, 1, 0)); } TEST(t_dlt_logstorage_update_context_loglevel, null) { EXPECT_EQ(DLT_RETURN_WRONG_PARAMETER, dlt_logstorage_update_context_loglevel(NULL, NULL, NULL, 0, 0)); } /* Begin Method: dlt_logstorage::t_dlt_daemon_logstorage_reset_application_loglevel*/ TEST(t_dlt_daemon_logstorage_reset_application_loglevel, normal) { DltDaemon daemon; DltDaemonLocal daemon_local; memset(&daemon, 0, sizeof(DltDaemon)); memset(&daemon_local, 0, sizeof(daemon_local)); memset(&daemon_local.pGateway, 0, sizeof(DltGateway)); daemon_local.RingbufferMinSize = DLT_DAEMON_RINGBUFFER_MIN_SIZE; daemon_local.RingbufferMaxSize = DLT_DAEMON_RINGBUFFER_MAX_SIZE; daemon_local.RingbufferStepSize = DLT_DAEMON_RINGBUFFER_STEP_SIZE; char ecu[] = "ECU1"; int device_index = 0; EXPECT_EQ(0, dlt_daemon_init(&daemon, daemon_local.RingbufferMinSize, daemon_local.RingbufferMaxSize, daemon_local.RingbufferStepSize, DLT_RUNTIME_DEFAULT_DIRECTORY, DLT_LOG_INFO, DLT_TRACE_STATUS_OFF, 0, 0)); dlt_set_id(daemon.ecuid, ecu); EXPECT_EQ(0, dlt_daemon_init_user_information(&daemon, &daemon_local.pGateway, 0, 0)); EXPECT_NO_THROW(dlt_daemon_logstorage_reset_application_loglevel(&daemon, &daemon_local, device_index, 1, 0)); } TEST(t_dlt_daemon_logstorage_reset_application_loglevel, null) { EXPECT_NO_THROW(dlt_daemon_logstorage_reset_application_loglevel(NULL, NULL, 0, 0, 0)); } /* Begin Method: dlt_logstorage::t_dlt_daemon_logstorage_get_loglevel*/ TEST(t_dlt_daemon_logstorage_get_loglevel, normal) { char ecu[] = "ECU1"; char apid[] = "1234"; char ctid[] = "5678"; char file_name[] = "file_name"; char key[] = "ECU1:1234:5678"; int device_index = 0; DltDaemon daemon; DltDaemonLocal daemon_local; memset(&daemon, 0, sizeof(DltDaemon)); memset(&daemon_local, 0, sizeof(DltDaemonLocal)); memset(&daemon_local.pGateway, 0, sizeof(DltGateway)); DltLogStorageFilterConfig value; value.log_level = 4; value.apids = apid; value.ctids = ctid; value.ecuid = ecu; value.file_name = file_name; DltLogStorage storage_handle; daemon_local.RingbufferMinSize = DLT_DAEMON_RINGBUFFER_MIN_SIZE; daemon_local.RingbufferMaxSize = DLT_DAEMON_RINGBUFFER_MAX_SIZE; daemon_local.RingbufferStepSize = DLT_DAEMON_RINGBUFFER_STEP_SIZE; EXPECT_EQ(0, dlt_daemon_init(&daemon, daemon_local.RingbufferMinSize, daemon_local.RingbufferMaxSize, daemon_local.RingbufferStepSize, DLT_RUNTIME_DEFAULT_DIRECTORY, DLT_LOG_INFO, DLT_TRACE_STATUS_OFF, 0, 0)); dlt_set_id(daemon.ecuid, ecu); EXPECT_EQ(0, dlt_daemon_init_user_information(&daemon, &daemon_local.pGateway, 0, 0)); daemon.storage_handle = &storage_handle; daemon.storage_handle->connection_type = DLT_OFFLINE_LOGSTORAGE_DEVICE_CONNECTED; daemon.storage_handle->config_status = DLT_OFFLINE_LOGSTORAGE_CONFIG_DONE; daemon.storage_handle->config_list = NULL; daemon.storage_handle->num_configs = 1; int num_keys = 1; EXPECT_EQ(DLT_RETURN_OK, dlt_logstorage_list_add(key, num_keys, &value, &(daemon.storage_handle->config_list))); EXPECT_NO_THROW(dlt_daemon_logstorage_update_application_loglevel(&daemon, &daemon_local, device_index, 0)); EXPECT_EQ(4, dlt_daemon_logstorage_get_loglevel(&daemon, 1, apid, ctid)); } TEST(t_dlt_daemon_logstorage_get_loglevel, null) { EXPECT_EQ(DLT_RETURN_WRONG_PARAMETER, dlt_daemon_logstorage_get_loglevel(NULL, 0, NULL, NULL)); } /* Begin Method: dlt_logstorage::t_dlt_daemon_logstorage_update_application_loglevel*/ TEST(t_dlt_daemon_logstorage_update_application_loglevel, normal) { char ecu[] = "key"; char apid[] = "1234"; char ctid[] = "5678"; char file_name[] = "file_name"; char key[] = "key:1234:5678"; int device_index = 0; DltDaemon daemon; DltDaemonLocal daemon_local; memset(&daemon, 0, sizeof(DltDaemon)); memset(&daemon_local, 0, sizeof(DltDaemonLocal)); memset(&daemon_local.pGateway, 0, sizeof(DltGateway)); DltLogStorageFilterConfig value; value.log_level = 5; value.apids = apid; value.ctids = ctid; value.ecuid = ecu; value.file_name = file_name; DltLogStorage storage_handle; daemon_local.RingbufferMinSize = DLT_DAEMON_RINGBUFFER_MIN_SIZE; daemon_local.RingbufferMaxSize = DLT_DAEMON_RINGBUFFER_MAX_SIZE; daemon_local.RingbufferStepSize = DLT_DAEMON_RINGBUFFER_STEP_SIZE; EXPECT_EQ(0, dlt_daemon_init(&daemon, daemon_local.RingbufferMinSize, daemon_local.RingbufferMaxSize, daemon_local.RingbufferStepSize, DLT_RUNTIME_DEFAULT_DIRECTORY, DLT_LOG_INFO, DLT_TRACE_STATUS_OFF, 0, 0)); dlt_set_id(daemon.ecuid, ecu); EXPECT_EQ(0, dlt_daemon_init_user_information(&daemon, &daemon_local.pGateway, 0, 0)); daemon.storage_handle = &storage_handle; daemon.storage_handle->connection_type = DLT_OFFLINE_LOGSTORAGE_DEVICE_CONNECTED; daemon.storage_handle->config_status = DLT_OFFLINE_LOGSTORAGE_CONFIG_DONE; daemon.storage_handle->config_list = NULL; int num_keys = 1; EXPECT_EQ(DLT_RETURN_OK, dlt_logstorage_list_add(key, num_keys, &value, &(daemon.storage_handle->config_list))); EXPECT_NO_THROW(dlt_daemon_logstorage_update_application_loglevel(&daemon, &daemon_local, device_index, 0)); } TEST(t_dlt_daemon_logstorage_update_application_loglevel, null) { EXPECT_NO_THROW(dlt_daemon_logstorage_update_application_loglevel(NULL, NULL, 0, 0)); } /* Begin Method: dlt_logstorage::t_dlt_daemon_logstorage_write*/ TEST(t_dlt_daemon_logstorage_write, normal) { DltDaemon daemon; DltGateway gateway; memset(&daemon, 0, sizeof(DltDaemon)); memset(&gateway, 0, sizeof(DltGateway)); char ecu[] = "ECU1"; DltLogStorage storage_handle; EXPECT_EQ(0, dlt_daemon_init(&daemon, DLT_DAEMON_RINGBUFFER_MIN_SIZE, DLT_DAEMON_RINGBUFFER_MAX_SIZE, DLT_DAEMON_RINGBUFFER_STEP_SIZE, DLT_RUNTIME_DEFAULT_DIRECTORY, DLT_LOG_INFO, DLT_TRACE_STATUS_OFF, 0, 0)); dlt_set_id(daemon.ecuid, ecu); EXPECT_EQ(0, dlt_daemon_init_user_information(&daemon, &gateway, 0, 0)); daemon.storage_handle = &storage_handle; char apid[] = "1234"; char ctid[] = "5678"; char ecuid[] = "12"; char file_name[] = "file_name"; DltDaemonFlags uconfig; uconfig.offlineLogstorageTimestamp = 1; uconfig.offlineLogstorageDelimiter = '/'; uconfig.offlineLogstorageMaxCounter = 5; uconfig.offlineLogstorageMaxCounterIdx = 1; uconfig.offlineLogstorageMaxDevices = 1; unsigned char data1[] = "123"; unsigned char data2[] = "123"; unsigned char data3[] = "123"; int size = 10 * sizeof(uint32_t); daemon.storage_handle->connection_type = DLT_OFFLINE_LOGSTORAGE_DEVICE_CONNECTED; daemon.storage_handle->config_status = DLT_OFFLINE_LOGSTORAGE_CONFIG_DONE; daemon.storage_handle->config_list = NULL; DltLogStorageFilterConfig value; value.apids = apid; value.ctids = ctid; value.ecuid = ecuid; value.file_name = file_name; char key0[] = "1234:\000\000\000\000"; char key1[] = ":5678\000\000\000\000"; char key2[] = "1234:5678"; int num_keys = 1; EXPECT_EQ(DLT_RETURN_OK, dlt_logstorage_list_add(key0, num_keys, &value, &(daemon.storage_handle->config_list))); EXPECT_EQ(DLT_RETURN_OK, dlt_logstorage_list_add(key1, num_keys, &value, &(daemon.storage_handle->config_list))); EXPECT_EQ(DLT_RETURN_OK, dlt_logstorage_list_add(key2, num_keys, &value, &(daemon.storage_handle->config_list))); EXPECT_NO_THROW(dlt_daemon_logstorage_write(&daemon, &uconfig, data1, size, data2, size, data3, size)); } TEST(t_dlt_daemon_logstorage_write, null) { EXPECT_NO_THROW(dlt_daemon_logstorage_write(NULL, NULL, NULL, 0, NULL, 0, NULL, 0)); } /* Begin Method: dlt_logstorage::t_dlt_daemon_logstorage_setup_internal_storage*/ TEST(t_dlt_daemon_logstorage_setup_internal_storage, normal) { DltDaemon daemon; DltDaemonLocal daemon_local; memset(&daemon, 0, sizeof(DltDaemon)); memset(&daemon_local, 0, sizeof(DltDaemonLocal)); memset(&daemon_local.pGateway, 0, sizeof(DltGateway)); daemon_local.RingbufferMinSize = DLT_DAEMON_RINGBUFFER_MIN_SIZE; daemon_local.RingbufferMaxSize = DLT_DAEMON_RINGBUFFER_MAX_SIZE; daemon_local.RingbufferStepSize = DLT_DAEMON_RINGBUFFER_STEP_SIZE; char ecu[] = "ECU1"; char path[] = "/tmp"; EXPECT_EQ(0, dlt_daemon_init(&daemon, daemon_local.RingbufferMinSize, daemon_local.RingbufferMaxSize, daemon_local.RingbufferStepSize, DLT_RUNTIME_DEFAULT_DIRECTORY, DLT_LOG_INFO, DLT_TRACE_STATUS_OFF, 0, 0)); dlt_set_id(daemon.ecuid, ecu); EXPECT_EQ(0, dlt_daemon_init_user_information(&daemon, &daemon_local.pGateway, 0, 0)); DltLogStorage storage_handle; daemon.storage_handle = &storage_handle; daemon.storage_handle->config_status = 0; daemon.storage_handle->connection_type = DLT_OFFLINE_LOGSTORAGE_DEVICE_DISCONNECTED; daemon.storage_handle->config_list = NULL; EXPECT_EQ(DLT_RETURN_OK, dlt_daemon_logstorage_setup_internal_storage(&daemon, &daemon_local, path, 1)); } TEST(t_dlt_daemon_logstorage_setup_internal_storage, null) { EXPECT_EQ(DLT_RETURN_WRONG_PARAMETER, dlt_daemon_logstorage_setup_internal_storage(NULL, NULL, NULL, 0)); } /* Begin Method: dlt_logstorage::dlt_daemon_logstorage_set_logstorage_cache_size*/ TEST(t_dlt_daemon_logstorage_set_logstorage_cache_size, normal) { EXPECT_NO_THROW(dlt_daemon_logstorage_set_logstorage_cache_size(1)); } /* Begin Method: dlt_logstorage::t_dlt_daemon_logstorage_cleanup*/ TEST(t_dlt_daemon_logstorage_cleanup, normal) { DltDaemon daemon; DltDaemonLocal daemon_local; daemon_local.flags.offlineLogstorageMaxDevices = 1; DltLogStorage storage_handle; daemon.storage_handle = &storage_handle; daemon.storage_handle->config_status = 0; EXPECT_EQ(DLT_RETURN_OK, dlt_daemon_logstorage_cleanup(&daemon, &daemon_local, 0)); } TEST(t_dlt_daemon_logstorage_cleanup, null) { EXPECT_EQ(DLT_RETURN_WRONG_PARAMETER, dlt_daemon_logstorage_cleanup(NULL, NULL, 0)); } /* Begin Method: dlt_logstorage::t_dlt_daemon_logstorage_sync_cache*/ TEST(t_dlt_daemon_logstorage_sync_cache, normal) { DltDaemon daemon; DltDaemonLocal daemon_local; daemon_local.flags.offlineLogstorageMaxDevices = 1; DltLogStorage storage_handle; daemon.storage_handle = &storage_handle; daemon.storage_handle->config_status = 0; char path[] = "/tmp"; char apid[] = "1234"; char ctid[] = "5678"; char ecuid[] = "12"; char file_name[] = "file_name"; char key[] = "12:1234:5678"; daemon.storage_handle->num_configs = 1; daemon.storage_handle->config_list = NULL; strncpy(daemon.storage_handle->device_mount_point, "/tmp", 5); DltLogStorageFilterConfig configs; configs.apids = apid; configs.ctids = ctid; configs.ecuid = ecuid; configs.file_name = file_name; dlt_logstorage_filter_set_strategy(&configs, DLT_LOGSTORAGE_SYNC_ON_MSG); int num_keys = 1; EXPECT_EQ(DLT_RETURN_OK, dlt_logstorage_list_add(key, num_keys, &configs, &(daemon.storage_handle->config_list))); EXPECT_EQ(DLT_RETURN_OK, dlt_daemon_logstorage_sync_cache(&daemon, &daemon_local, path, 0)); } TEST(t_dlt_daemon_logstorage_sync_cache, null) { EXPECT_EQ(DLT_RETURN_WRONG_PARAMETER, dlt_daemon_logstorage_sync_cache(NULL, NULL, NULL, 0)); } /* Begin Method: dlt_logstorage::t_dlt_daemon_logstorage_get_device*/ TEST(t_dlt_daemon_logstorage_get_device, normal) { DltDaemon daemon; DltDaemonLocal daemon_local; daemon_local.flags.offlineLogstorageMaxDevices = 1; DltLogStorage storage_handle; daemon.storage_handle = &storage_handle; daemon.storage_handle->config_status = 0; char path[] = "/tmp"; strncpy(daemon.storage_handle->device_mount_point, "/tmp", 5); EXPECT_NE((DltLogStorage *)NULL, dlt_daemon_logstorage_get_device(&daemon, &daemon_local, path, 0)); } TEST(t_dlt_daemon_logstorage_get_device, null) { EXPECT_EQ((DltLogStorage *)NULL, dlt_daemon_logstorage_get_device(NULL, NULL, NULL, 0)); } /* Begin Method: dlt_logstorage::t_dlt_logstorage_find_dlt_header*/ TEST(t_dlt_logstorage_find_dlt_header, normal) { char data[] = { 'a', 'b', 'D', 'L', 'T', 0x01 }; DltLogStorageFilterConfig config; memset(&config, 0, sizeof(DltLogStorageFilterConfig)); config.cache = calloc(1, sizeof(data)); if (config.cache != NULL) { strncpy((char *)config.cache, data, sizeof(data)); /* DLT header starts from index 2 */ EXPECT_EQ(2, dlt_logstorage_find_dlt_header(config.cache, 0, sizeof(data))); free(config.cache); } } TEST(t_dlt_logstorage_find_dlt_header, null) { char data[] = { 'N', 'o', 'H', 'e', 'a', 'd', 'e', 'r' }; DltLogStorageFilterConfig config; memset(&config, 0, sizeof(DltLogStorageFilterConfig)); config.cache = calloc(1, sizeof(data)); if (config.cache != NULL) { /* config.cache =(void *) "a,b,D,L,T,0x01"; */ strncpy((char *)config.cache, data, sizeof(data)); EXPECT_EQ(DLT_RETURN_ERROR, dlt_logstorage_find_dlt_header(config.cache, 0, sizeof(data))); free(config.cache); } } /* Begin Method: dlt_logstorage::t_dlt_logstorage_find_last_dlt_header*/ TEST(t_dlt_logstorage_find_last_dlt_header, normal) { char data[] = {'a','b','D','L','T',0x01}; DltLogStorageFilterConfig config; memset(&config, 0, sizeof(DltLogStorageFilterConfig)); config.cache = calloc(1, sizeof(data)); if (config.cache != NULL) { strncpy((char *)config.cache, data, sizeof(data)); /* DLT header starts from index 2 */ EXPECT_EQ(2, dlt_logstorage_find_last_dlt_header(config.cache, 0, sizeof(data))); free(config.cache); } } TEST(t_dlt_logstorage_find_last_dlt_header, null) { char data[] = {'N','o','H','e','a','d','e','r'}; DltLogStorageFilterConfig config; memset(&config, 0, sizeof(DltLogStorageFilterConfig)); config.cache = calloc(1, sizeof(data)); if (config.cache != NULL) { /* config.cache =(void *) "a,b,D,L,T,0x01"; */ strncpy((char *)config.cache, data, sizeof(data)); EXPECT_EQ(-1, dlt_logstorage_find_last_dlt_header(config.cache, 0, sizeof(data))); free(config.cache); } } /* Begin Method: dlt_logstorage::t_dlt_logstorage_sync_to_file*/ TEST(t_dlt_logstorage_sync_to_file, normal) { DltLogStorageUserConfig file_config; memset(&file_config, 0, sizeof(DltLogStorageUserConfig)); file_config.logfile_timestamp = 191132; file_config.logfile_delimiter = { '_' }; file_config.logfile_maxcounter = 6; file_config.logfile_counteridxlen = 2; char *path = (char *)"/tmp"; DltLogStorageFilterConfig config; memset(&config, 0, sizeof(DltLogStorageFilterConfig)); char apids; char ctids; config.apids = &apids; config.ctids = &ctids; config.file_name = (char *)"Test"; config.records = NULL; config.log = NULL; config.cache = NULL; config.sync = DLT_LOGSTORAGE_SYNC_ON_DEMAND; config.num_files = 6; config.file_size = 50; g_logstorage_cache_max = 16; unsigned int size = 10; unsigned char data1[10] = "dlt_data0"; unsigned char data2[10] = "dlt_data1"; unsigned char data3[10] = "dlt_data2"; DltLogStorageCacheFooter *footer = NULL; config.cache = calloc(1, config.file_size + sizeof(DltLogStorageCacheFooter)); if (config.cache != NULL) { EXPECT_EQ(DLT_RETURN_OK, dlt_logstorage_prepare_msg_cache(&config, &file_config, path, 1)); EXPECT_EQ(DLT_RETURN_OK, dlt_logstorage_write_msg_cache(&config, &file_config, path, data1, size, data2, size, data3, size)); footer = (DltLogStorageCacheFooter *)((uint8_t*)config.cache + config.file_size); EXPECT_EQ(DLT_RETURN_OK, dlt_logstorage_sync_to_file(&config, &file_config, path, footer, footer->last_sync_offset, footer->offset)); free(config.cache); config.cache = NULL; } } TEST(t_dlt_logstorage_sync_to_file, null) { EXPECT_EQ(-1, dlt_logstorage_sync_to_file(NULL, NULL, NULL, NULL, 0, 1)); } /* Begin Method: dlt_logstorage::t_dlt_logstorage_sync_msg_cache*/ TEST(t_dlt_logstorage_sync_msg_cache, normal) { DltLogStorageUserConfig file_config; memset(&file_config, 0, sizeof(DltLogStorageUserConfig)); file_config.logfile_timestamp = 191132; file_config.logfile_delimiter = { '_' }; file_config.logfile_maxcounter = 8; file_config.logfile_counteridxlen = 2; char *path = (char *)"/tmp"; DltLogStorageFilterConfig config; memset(&config, 0, sizeof(DltLogStorageFilterConfig)); char apids; char ctids; config.apids = &apids; config.ctids = &ctids; config.file_name = (char *)"Test"; config.records = NULL; config.log = NULL; config.cache = NULL; config.file_size = 50; config.sync = DLT_LOGSTORAGE_SYNC_ON_DEMAND; config.num_files = 8; g_logstorage_cache_max = 16; unsigned int size = 10; unsigned char data1[10] = "dlt_dataA"; unsigned char data2[10] = "dlt_dataB"; unsigned char data3[10] = "dlt_dataC"; config.cache = calloc(1, 50 + sizeof(DltLogStorageCacheFooter)); if (config.cache != NULL) { EXPECT_EQ(DLT_RETURN_OK, dlt_logstorage_prepare_msg_cache(&config, &file_config, path, 1)); EXPECT_EQ(DLT_RETURN_OK, dlt_logstorage_write_msg_cache(&config, &file_config, path, data1, size, data2, size, data3, size)); EXPECT_EQ(DLT_RETURN_OK, dlt_logstorage_sync_msg_cache(&config, &file_config, path, DLT_LOGSTORAGE_SYNC_ON_DEMAND)); free(config.cache); config.cache = NULL; } } TEST(t_dlt_logstorage_sync_msg_cache, null) { EXPECT_EQ(DLT_RETURN_ERROR, dlt_logstorage_sync_msg_cache(NULL, NULL, NULL, 0)); } int connectServer(void) { #ifdef DLT_USE_UNIX_SOCKET_IPC int sockfd, portno; struct sockaddr_in serv_addr; struct hostent *server; portno = 8080; sockfd = socket(AF_INET, SOCK_STREAM, 0); server = gethostbyname("127.0.0.1"); memset((char *) &serv_addr, 0, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; memcpy((char *)&serv_addr.sin_addr.s_addr, (char *)server->h_addr, server->h_length); serv_addr.sin_port = htons(portno); if (connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) { printf("Error: %s (%d) occured in connect socket\n", strerror(errno), errno); close(sockfd); return -1; } #else char filename[1024]; int sockfd; snprintf(filename, 1024, "/tmp/dltpipes/dlt%d", getpid()); /* Try to delete existing pipe, ignore result of unlink */ unlink(filename); mkfifo(filename, S_IRUSR | S_IWUSR | S_IWGRP | S_IRGRP); chmod(filename, S_IRUSR | S_IWUSR | S_IWGRP | S_IRGRP); sockfd = open(filename, O_RDWR | O_CLOEXEC); #endif return sockfd; } #define GTEST_SOCKS_ACCEPTED 2 int main(int argc, char **argv) { #ifdef DLT_USE_UNIX_SOCKET_IPC pid_t cpid; cpid = fork(); if (cpid == -1) { printf("fork fail\n"); return -1; } if (cpid) { int i = GTEST_SOCKS_ACCEPTED; int j, optval = 1; char buffer[256]; int sockfd, newsockfd[GTEST_SOCKS_ACCEPTED], portno; socklen_t clilen; struct sockaddr_in serv_addr, cli_addr; sockfd = socket(AF_INET, SOCK_STREAM, 0); if (sockfd == -1) { printf("Error in creating socket\n"); return -1; } memset((char *) &serv_addr, 0, sizeof(serv_addr)); portno = 8080; serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = INADDR_ANY; serv_addr.sin_port = htons(portno); if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)) == -1) { perror("setsockopt"); close(sockfd); exit(1); } j = bind(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)); if (j == -1) { perror("Bind Error\n"); close(sockfd); return -1; } listen(sockfd, 5); while (i) { clilen = sizeof(cli_addr); newsockfd[i - 1] = accept(sockfd, (struct sockaddr *)&cli_addr, &clilen); if (newsockfd[i - 1] == -1) { printf("Error in accept"); return -1; } memset(buffer, 0, 256); (void)(read(newsockfd[i - 1], buffer, 255) + 1); /* just ignore result */ i--; } for (j = 0; j < GTEST_SOCKS_ACCEPTED; j++) close(newsockfd[i]); close(sockfd); } else { #endif ::testing::InitGoogleTest(&argc, argv); ::testing::FLAGS_gtest_break_on_failure = false; /* ::testing::FLAGS_gtest_filter = "t_dlt_event_handler_register_connection*"; */ return RUN_ALL_TESTS(); #ifdef DLT_USE_UNIX_SOCKET_IPC } #endif return 0; } dlt-daemon-2.18.4/tests/gtest_dlt_shm.cpp000066400000000000000000000033001353342203500203340ustar00rootroot00000000000000#include extern "C" { #include "dlt_shm.h" } DltShm *server_buf = (DltShm *)calloc(1, sizeof(DltShm)); DltShm *client_buf = (DltShm *)calloc(1, sizeof(DltShm)); char *dltShmNameTest = (char *)"dlt-shm-test"; int size = 1000; /* Method: dlt_shm::t_dlt_shm_init_server */ TEST(t_dlt_shm_init_server, normal) { EXPECT_EQ(DLT_RETURN_OK, dlt_shm_init_server(server_buf, dltShmNameTest, size)); } /* Method: dlt_shm::t_dlt_shm_init_server */ TEST(t_dlt_shm_init_server, nullpointer) { EXPECT_EQ(DLT_RETURN_WRONG_PARAMETER, dlt_shm_init_server(NULL, NULL, size)); } /* Method: dlt_shm::t_dlt_shm_init_client */ TEST(t_dlt_shm_init_client, normal) { EXPECT_EQ(DLT_RETURN_OK, dlt_shm_init_client(client_buf, dltShmNameTest)); } /* Method: dlt_shm::t_dlt_shm_init_client */ TEST(t_dlt_shm_init_client, nullpointer) { EXPECT_EQ(DLT_RETURN_WRONG_PARAMETER, dlt_shm_init_client(NULL, NULL)); } /* Method: dlt_shm::t_dlt_shm_free_client */ TEST(t_dlt_shm_free_client, normal) { EXPECT_EQ(DLT_RETURN_OK, dlt_shm_free_client(client_buf)); } /* Method: dlt_shm::t_dlt_shm_free_client */ TEST(t_dlt_shm_free_client, nullpointer) { EXPECT_EQ(DLT_RETURN_WRONG_PARAMETER, dlt_shm_free_client(NULL)); } /* Method: dlt_shm::t_dlt_shm_free_server */ TEST(t_dlt_shm_free_server, normal) { EXPECT_EQ(DLT_RETURN_OK, dlt_shm_free_server(server_buf, dltShmNameTest)); } /* Method: dlt_shm::t_dlt_shm_free_server */ TEST(t_dlt_shm_free_server, nullpointer) { EXPECT_EQ(DLT_RETURN_WRONG_PARAMETER, dlt_shm_free_server(NULL, NULL)); } int main(int argc, char **argv) { ::testing::InitGoogleTest(&argc, argv); ::testing::FLAGS_gtest_break_on_failure = false; return RUN_ALL_TESTS(); } dlt-daemon-2.18.4/tests/gtest_dlt_user.cpp000066400000000000000000005772141353342203500205470ustar00rootroot00000000000000/* * SPDX license identifier: MPL-2.0 * * Copyright (C) 2011-2015, BMW AG * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. */ /*! * \author Jens Bocklage * \author Stefan Held * * \copyright Copyright © 2011-2015 BMW AG. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file gtest_dlt_common.cpp */ #include #include "gtest/gtest.h" #include #include extern "C" { #include "dlt_user.h" #include "dlt_user_cfg.h" } /* TEST COMMENTED OUT WITH */ /* TODO: */ /* DO FAIL! */ /* tested functions */ /* * int dlt_user_log_write_start(DltContext *handle, DltContextData *log, DltLogLevelType loglevel); * int dlt_user_log_write_start_id(DltContext *handle, DltContextData *log, DltLogLevelType loglevel, uint32_t messageid); * int dlt_user_log_write_finish(DltContextData *log); * int dlt_user_log_write_bool(DltContextData *log, uint8_t data); * int dlt_user_log_write_float32(DltContextData *log, float32_t data); * int dlt_user_log_write_float64(DltContextData *log, double data); * int dlt_user_log_write_uint(DltContextData *log, unsigned int data); * int dlt_user_log_write_uint8(DltContextData *log, uint8_t data); * int dlt_user_log_write_uint16(DltContextData *log, uint16_t data); * int dlt_user_log_write_uint32(DltContextData *log, uint32_t data); * int dlt_user_log_write_uint64(DltContextData *log, uint64_t data); * int dlt_user_log_write_uint8_formatted(DltContextData *log, uint8_t data, DltFormatType type); * int dlt_user_log_write_uint16_formatted(DltContextData *log, uint16_t data, DltFormatType type); * int dlt_user_log_write_uint32_formatted(DltContextData *log, uint32_t data, DltFormatType type); * int dlt_user_log_write_uint64_formatted(DltContextData *log, uint64_t data, DltFormatType type); * int dlt_user_log_write_int(DltContextData *log, int data); * int dlt_user_log_write_int8(DltContextData *log, int8_t data); * int dlt_user_log_write_int16(DltContextData *log, int16_t data); * int dlt_user_log_write_int32(DltContextData *log, int32_t data); * int dlt_user_log_write_int64(DltContextData *log, int64_t data); * int dlt_user_log_write_string( DltContextData *log, const char *text); * int dlt_user_log_write_constant_string( DltContextData *log, const char *text); * int dlt_user_log_write_utf8_string(DltContextData *log, const char *text); * int dlt_user_log_write_raw(DltContextData *log,void *data,uint16_t length); * int dlt_user_log_write_raw_formatted(DltContextData *log,void *data,uint16_t length,DltFormatType type); */ /* * int dlt_log_string(DltContext *handle,DltLogLevelType loglevel, const char *text); * int dlt_log_string_int(DltContext *handle,DltLogLevelType loglevel, const char *text, int data); * int dlt_log_string_uint(DltContext *handle,DltLogLevelType loglevel, const char *text, unsigned int data); * int dlt_log_int(DltContext *handle,DltLogLevelType loglevel, int data); * int dlt_log_uint(DltContext *handle,DltLogLevelType loglevel, unsigned int data); * int dlt_log_raw(DltContext *handle,DltLogLevelType loglevel, void *data,uint16_t length); * int dlt_log_marker(); */ /* * int dlt_register_app(const char *apid, const char * description); * int dlt_unregister_app(void); * int dlt_register_context(DltContext *handle, const char *contextid, const char * description); * int dlt_register_context_ll_ts(DltContext *handle, const char *contextid, const char * description, int loglevel, int tracestatus); * int dlt_unregister_context(DltContext *handle); * int dlt_register_injection_callback(DltContext *handle, uint32_t service_id, int (*dlt_injection_callback)(uint32_t service_id, void *data, uint32_t length)); * int dlt_register_log_level_changed_callback(DltContext *handle, void (*dlt_log_level_changed_callback)(char context_id[DLT_ID_SIZE],uint8_t log_level, uint8_t trace_status)); */ /* * int dlt_user_trace_network(DltContext *handle, DltNetworkTraceType nw_trace_type, uint16_t header_len, void *header, uint16_t payload_len, void *payload); * int dlt_user_trace_network_truncated(DltContext *handle, DltNetworkTraceType nw_trace_type, uint16_t header_len, void *header, uint16_t payload_len, void *payload, int allow_truncate); * int dlt_user_trace_network_segmented(DltContext *handle, DltNetworkTraceType nw_trace_type, uint16_t header_len, void *header, uint16_t payload_len, void *payload); */ /* * int dlt_set_log_mode(DltUserLogMode mode); * int dlt_get_log_state(); */ /* * int dlt_verbose_mode(void); * int dlt_nonverbose_mode(void); */ /* define some min and max values (if not present in ) */ #ifndef UINT8_MIN # define UINT8_MIN 0 #endif #ifndef UINT16_MIN # define UINT16_MIN 0 #endif #ifndef UINT32_MIN # define UINT32_MIN 0 #endif #ifndef UINT64_MIN # define UINT64_MIN 0 #endif #ifndef UINT8_MAX # define UINT8_MAX 255 #endif #ifndef UINT16_MAX # define UINT16_MAX 65535 #endif #ifndef UINT32_MAX # define UINT32_MAX 4294967295 #endif #ifndef UINT64_MAX # define UINT64_MAX 18446744073709551615UL #endif #ifndef INT8_MIN # define INT8_MIN -128 #endif #ifndef INT16_MIN # define INT16_MIN -32768 #endif #ifndef INT32_MIN # define INT32_MIN -2147483648 #endif #ifndef INT64_MIN # define INT64_MIN -9223372036854775807 #endif #ifndef INT8_MAX # define INT8_MAX 127 #endif #ifndef INT16_MAX # define INT16_MAX 32767 #endif #ifndef INT32_MAX # define INT32_MAX 2147483647 #endif #ifndef INT64_MAX # define INT64_MAX 9223372036854775807 #endif #ifndef UINT_MIN # define UINT_MIN UINT32_MIN #endif #ifndef UINT_MAX # define UINT_MAX UINT32_MAX #endif #ifndef INT_MIN # define INT_MIN INT32_MIN #endif #ifndef INT_MAX # define INT_MAX INT32_MAX #endif static const char *STR_TRUNCATED_MESSAGE = "... <>"; /*/////////////////////////////////////// */ /* start initial dlt */ TEST(t_dlt_init, onetime) { /** * Unset DLT_USER_ENV_LOG_MSG_BUF_LEN environment variable * to make sure the dlt user buffer initialized with default value */ unsetenv(DLT_USER_ENV_LOG_MSG_BUF_LEN); EXPECT_EQ(DLT_RETURN_OK, dlt_init()); } /*/////////////////////////////////////// */ /* t_dlt_user_log_write_start */ TEST(t_dlt_user_log_write_start, normal) { DltContext context; DltContextData contextData; EXPECT_LE(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_LE(DLT_RETURN_OK, dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_user_log_write_start normal")); /* the defined enum values for log level */ EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_start(&context, &contextData, DLT_LOG_DEFAULT)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_finish(&contextData)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_start(&context, &contextData, DLT_LOG_OFF)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_finish(&contextData)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_start(&context, &contextData, DLT_LOG_FATAL)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_finish(&contextData)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_start(&context, &contextData, DLT_LOG_ERROR)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_finish(&contextData)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_start(&context, &contextData, DLT_LOG_WARN)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_finish(&contextData)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_start(&context, &contextData, DLT_LOG_INFO)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_finish(&contextData)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_start(&context, &contextData, DLT_LOG_DEBUG)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_finish(&contextData)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_start(&context, &contextData, DLT_LOG_VERBOSE)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_finish(&contextData)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_app()); } TEST(t_dlt_user_log_write_start, abnormal) { DltContext context; DltContextData contextData; EXPECT_LE(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_LE(DLT_RETURN_OK, dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_user_log_write_start abnormal")); /* undefined values for DltLogLevelType */ /* shouldn't it return -1? */ EXPECT_EQ(DLT_RETURN_WRONG_PARAMETER, dlt_user_log_write_start(&context, &contextData, (DltLogLevelType) - 100)); EXPECT_EQ(DLT_RETURN_WRONG_PARAMETER, dlt_user_log_write_start(&context, &contextData, (DltLogLevelType) - 10)); EXPECT_EQ(DLT_RETURN_WRONG_PARAMETER, dlt_user_log_write_start(&context, &contextData, (DltLogLevelType)10)); EXPECT_EQ(DLT_RETURN_WRONG_PARAMETER, dlt_user_log_write_start(&context, &contextData, (DltLogLevelType)100)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_app()); } TEST(t_dlt_user_log_write_start, startstartfinish) { DltContext context; DltContextData contextData; EXPECT_LE(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_LE(DLT_RETURN_OK, dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_user_log_write_start startstartfinish")); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_start(&context, &contextData, DLT_LOG_DEFAULT)); /* shouldn't it return -1, because it is already started? */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_user_log_write_start(&context, &contextData, DLT_LOG_DEFAULT)); */ EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_finish(&contextData)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_app()); } TEST(t_dlt_user_log_write_start, nullpointer) { DltContext context; DltContextData contextData; EXPECT_LE(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_LE(DLT_RETURN_OK, dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_user_log_write_start nullpointer")); /* NULL's */ EXPECT_GE(DLT_RETURN_ERROR, dlt_user_log_write_start(NULL, &contextData, DLT_LOG_DEFAULT)); /*EXPECT_GE(DLT_RETURN_ERROR,dlt_user_log_write_finish(&contextData)); */ EXPECT_GE(DLT_RETURN_ERROR, dlt_user_log_write_start(NULL, NULL, DLT_LOG_DEFAULT)); EXPECT_GE(DLT_RETURN_ERROR, dlt_user_log_write_start(&context, NULL, DLT_LOG_DEFAULT)); /*EXPECT_GE(DLT_RETURN_ERROR,dlt_user_log_write_finish(&contextData)); */ EXPECT_LE(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_app()); } /*/////////////////////////////////////// */ /* t_dlt_user_log_write_start_id */ TEST(t_dlt_user_log_write_start_id, normal) { DltContext context; DltContextData contextData; uint32_t messageid; EXPECT_LE(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_LE(DLT_RETURN_OK, dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_user_log_write_start_id normal")); /* the defined enum values for log level */ messageid = UINT32_MIN; EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_start_id(&context, &contextData, DLT_LOG_DEFAULT, messageid)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_finish(&contextData)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_start_id(&context, &contextData, DLT_LOG_OFF, messageid)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_finish(&contextData)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_start_id(&context, &contextData, DLT_LOG_FATAL, messageid)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_finish(&contextData)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_start_id(&context, &contextData, DLT_LOG_ERROR, messageid)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_finish(&contextData)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_start_id(&context, &contextData, DLT_LOG_WARN, messageid)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_finish(&contextData)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_start_id(&context, &contextData, DLT_LOG_INFO, messageid)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_finish(&contextData)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_start_id(&context, &contextData, DLT_LOG_DEBUG, messageid)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_finish(&contextData)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_start_id(&context, &contextData, DLT_LOG_VERBOSE, messageid)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_finish(&contextData)); messageid = UINT32_MAX; EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_start_id(&context, &contextData, DLT_LOG_DEFAULT, messageid)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_finish(&contextData)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_start_id(&context, &contextData, DLT_LOG_OFF, messageid)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_finish(&contextData)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_start_id(&context, &contextData, DLT_LOG_FATAL, messageid)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_finish(&contextData)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_start_id(&context, &contextData, DLT_LOG_ERROR, messageid)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_finish(&contextData)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_start_id(&context, &contextData, DLT_LOG_WARN, messageid)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_finish(&contextData)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_start_id(&context, &contextData, DLT_LOG_INFO, messageid)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_finish(&contextData)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_start_id(&context, &contextData, DLT_LOG_DEBUG, messageid)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_finish(&contextData)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_start_id(&context, &contextData, DLT_LOG_VERBOSE, messageid)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_finish(&contextData)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_app()); } TEST(t_dlt_user_log_write_start_id, abnormal) { DltContext context; /* TODO: DltContextData contextData; */ /* TODO: uint32_t messageid; */ EXPECT_LE(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_LE(DLT_RETURN_OK, dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_user_log_write_start_id abnormal")); /* undefined values for DltLogLevelType */ /* shouldn't it return -1? */ /* TODO: messageid = UINT32_MIN; */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_user_log_write_start_id(&context, &contextData, (DltLogLevelType)-100, messageid)); */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_user_log_write_start_id(&context, &contextData, (DltLogLevelType)-10, messageid)); */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_user_log_write_start_id(&context, &contextData, (DltLogLevelType)10, messageid)); */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_user_log_write_start_id(&context, &contextData, (DltLogLevelType)100, messageid)); */ EXPECT_LE(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_app()); } TEST(t_dlt_user_log_write_start_id, startstartfinish) { DltContext context; DltContextData contextData; uint32_t messageid; EXPECT_LE(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_LE(DLT_RETURN_OK, dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_user_log_write_start_id startstartfinish")); messageid = UINT32_MIN; EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_start_id(&context, &contextData, DLT_LOG_DEFAULT, messageid)); /* shouldn't it return -1, because it is already started? */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_user_log_write_start_id(&context, &contextData, DLT_LOG_DEFAULT, messageid)); */ EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_finish(&contextData)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_app()); } TEST(t_dlt_user_log_write_start_id, nullpointer) { DltContext context; uint32_t messageid; DltContextData contextData; EXPECT_LE(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_LE(DLT_RETURN_OK, dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_user_log_write_start_id nullpointer")); /* NULL's */ messageid = UINT32_MIN; EXPECT_GE(DLT_RETURN_ERROR, dlt_user_log_write_start_id(NULL, &contextData, DLT_LOG_DEFAULT, messageid)); /*EXPECT_GE(DLT_RETURN_ERROR,dlt_user_log_write_finish(&contextData)); */ EXPECT_GE(DLT_RETURN_ERROR, dlt_user_log_write_start_id(NULL, NULL, DLT_LOG_DEFAULT, messageid)); EXPECT_GE(DLT_RETURN_ERROR, dlt_user_log_write_start_id(&context, NULL, DLT_LOG_DEFAULT, messageid)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_app()); } /*/////////////////////////////////////// */ /* t_dlt_user_log_write_finish */ TEST(t_dlt_user_log_write_finish, finish) { DltContext context; DltContextData contextData; EXPECT_LE(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_LE(DLT_RETURN_OK, dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_user_log_write_start finish")); /* finish without start */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_user_log_write_finish(NULL)); */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_user_log_write_finish(&contextData)); */ EXPECT_LE(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_LE(DLT_RETURN_OK, dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_user_log_write_finish finish")); /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_user_log_write_finish(&contextData)); */ /* finish with start and initialized context */ EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_start(&context, &contextData, DLT_LOG_DEFAULT)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_finish(&contextData)); /* 2nd finish */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_user_log_write_finish(&contextData)); */ EXPECT_LE(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_app()); } /*/////////////////////////////////////// */ /* t_dlt_user_log_write_bool */ TEST(t_dlt_user_log_write_bool, normal) { DltContext context; DltContextData contextData; uint8_t data; EXPECT_LE(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_LE(DLT_RETURN_OK, dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_user_log_write_bool normal")); /* normal values */ EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_start(&context, &contextData, DLT_LOG_DEFAULT)); data = true; EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_bool(&contextData, data)); data = false; EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_bool(&contextData, data)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_finish(&contextData)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_app()); } TEST(t_dlt_user_log_write_bool, abnormal) { DltContext context; DltContextData contextData; /* TODO: uint8_t data; */ EXPECT_LE(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_LE(DLT_RETURN_OK, dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_user_log_write_bool abnormal")); /* abnormal values */ EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_start(&context, &contextData, DLT_LOG_DEFAULT)); /* TODO: data = 2; */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_user_log_write_bool(&contextData, data)); */ /* TODO: data = 100; */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_user_log_write_bool(&contextData, data)); */ /* TODO: data = UINT8_MAX; */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_user_log_write_bool(&contextData, data)); */ EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_finish(&contextData)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_app()); } TEST(t_dlt_user_log_write_bool, nullpointer) { DltContext context; uint8_t data; EXPECT_LE(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_LE(DLT_RETURN_OK, dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_user_log_write_bool nullpointer")); /* NULL */ data = true; EXPECT_GE(DLT_RETURN_ERROR, dlt_user_log_write_bool(NULL, data)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_app()); } /*/////////////////////////////////////// */ /* t_dlt_user_log_write_float32 */ TEST(t_dlt_user_log_write_float32, normal) { DltContext context; DltContextData contextData; float32_t data; EXPECT_LE(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_LE(DLT_RETURN_OK, dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_user_log_write_float32 normal")); /* normal values */ EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_start(&context, &contextData, DLT_LOG_DEFAULT)); data = 3.141592653589793238; EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_float32(&contextData, data)); data = -3.141592653589793238; EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_float32(&contextData, data)); data = 0.; EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_float32(&contextData, data)); data = -0.; EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_float32(&contextData, data)); data = FLT_MIN; EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_float32(&contextData, data)); data = FLT_MAX; EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_float32(&contextData, data)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_finish(&contextData)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_app()); } TEST(t_dlt_user_log_write_float32, nullpointer) { DltContext context; float32_t data; EXPECT_LE(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_LE(DLT_RETURN_OK, dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_user_log_write_float32 nullpointer")); /* NULL */ data = 1.; EXPECT_GE(DLT_RETURN_ERROR, dlt_user_log_write_float32(NULL, data)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_app()); } /*/////////////////////////////////////// */ /* t_dlt_user_log_write_float64 */ TEST(t_dlt_user_log_write_float64, normal) { DltContext context; DltContextData contextData; double data; EXPECT_LE(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_LE(DLT_RETURN_OK, dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_user_log_write_float64 normal")); /* normal values */ EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_start(&context, &contextData, DLT_LOG_DEFAULT)); data = 3.14159265358979323846; EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_float64(&contextData, data)); data = -3.14159265358979323846; EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_float64(&contextData, data)); data = 0.; EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_float64(&contextData, data)); data = -0.; EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_float64(&contextData, data)); data = DBL_MIN; EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_float64(&contextData, data)); data = DBL_MAX; EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_float64(&contextData, data)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_finish(&contextData)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_app()); } TEST(t_dlt_user_log_write_float64, nullpointer) { DltContext context; double data; EXPECT_LE(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_LE(DLT_RETURN_OK, dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_user_log_write_float64 nullpointer")); /* NULL */ data = 1.; EXPECT_GE(DLT_RETURN_ERROR, dlt_user_log_write_float64(NULL, data)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_app()); } /*/////////////////////////////////////// */ /* t_dlt_user_log_write_uint */ TEST(t_dlt_user_log_write_uint, normal) { DltContext context; DltContextData contextData; unsigned int data; EXPECT_LE(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_LE(DLT_RETURN_OK, dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_user_log_write_uint normal")); /* normal values */ EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_start(&context, &contextData, DLT_LOG_DEFAULT)); data = UINT_MIN; EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_uint(&contextData, data)); data = 1; EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_uint(&contextData, data)); data = UINT_MAX; EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_uint(&contextData, data)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_finish(&contextData)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_app()); } TEST(t_dlt_user_log_write_uint, abnormal) { DltContext context; DltContextData contextData; /* TODO: unsigned int data; */ EXPECT_LE(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_LE(DLT_RETURN_OK, dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_user_log_write_uint abnormal")); /* abnormal values */ EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_start(&context, &contextData, DLT_LOG_DEFAULT)); /* TODO: data = -1; */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_user_log_write_uint(&contextData, data)); */ EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_finish(&contextData)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_app()); } TEST(t_dlt_user_log_write_uint, nullpointer) { DltContext context; unsigned int data; EXPECT_LE(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_LE(DLT_RETURN_OK, dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_user_log_write_uint nullpointer")); /* NULL */ data = 1; EXPECT_GE(DLT_RETURN_ERROR, dlt_user_log_write_uint(NULL, data)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_app()); } /*/////////////////////////////////////// */ /* t_dlt_user_log_write_uint8 */ TEST(t_dlt_user_log_write_uint8, normal) { DltContext context; DltContextData contextData; uint8_t data; EXPECT_LE(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_LE(DLT_RETURN_OK, dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_user_log_write_uint8 normal")); /* normal values */ EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_start(&context, &contextData, DLT_LOG_DEFAULT)); data = UINT8_MIN; EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_uint8(&contextData, data)); data = 1; EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_uint8(&contextData, data)); data = UINT8_MAX; EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_uint8(&contextData, data)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_finish(&contextData)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_app()); } TEST(t_dlt_user_log_write_uint8, nullpointer) { DltContext context; uint8_t data; EXPECT_LE(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_LE(DLT_RETURN_OK, dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_user_log_write_uint8 nullpointer")); /* NULL */ data = 1; EXPECT_GE(DLT_RETURN_ERROR, dlt_user_log_write_uint8(NULL, data)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_app()); } /*/////////////////////////////////////// */ /* t_dlt_user_log_write_uint16 */ TEST(t_dlt_user_log_write_uint16, normal) { DltContext context; DltContextData contextData; uint16_t data; EXPECT_LE(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_LE(DLT_RETURN_OK, dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_user_log_write_uint16 normal")); /* normal values */ EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_start(&context, &contextData, DLT_LOG_DEFAULT)); data = UINT16_MIN; EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_uint16(&contextData, data)); data = 1; EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_uint16(&contextData, data)); data = UINT16_MAX; EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_uint16(&contextData, data)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_finish(&contextData)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_app()); } TEST(t_dlt_user_log_write_uint16, nullpointer) { DltContext context; uint16_t data; EXPECT_LE(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_LE(DLT_RETURN_OK, dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_user_log_write_uint16 nullpointer")); /* NULL */ data = 1; EXPECT_GE(DLT_RETURN_ERROR, dlt_user_log_write_uint16(NULL, data)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_app()); } /*/////////////////////////////////////// */ /* t_dlt_user_log_write_uint32 */ TEST(t_dlt_user_log_write_uint32, normal) { DltContext context; DltContextData contextData; uint32_t data; EXPECT_LE(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_LE(DLT_RETURN_OK, dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_user_log_write_uint32 normal")); /* normal values */ EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_start(&context, &contextData, DLT_LOG_DEFAULT)); data = UINT32_MIN; EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_uint32(&contextData, data)); data = 1; EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_uint32(&contextData, data)); data = UINT32_MAX; EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_uint32(&contextData, data)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_finish(&contextData)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_app()); } TEST(t_dlt_user_log_write_uint32, nullpointer) { DltContext context; uint32_t data; EXPECT_LE(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_LE(DLT_RETURN_OK, dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_user_log_write_uint32 nullpointer")); /* NULL */ data = 1; EXPECT_GE(DLT_RETURN_ERROR, dlt_user_log_write_uint32(NULL, data)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_app()); } /*/////////////////////////////////////// */ /* t_dlt_user_log_write_uint64 */ TEST(t_dlt_user_log_write_uint64, normal) { DltContext context; DltContextData contextData; uint64_t data; EXPECT_LE(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_LE(DLT_RETURN_OK, dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_user_log_write_uint64 normal")); /* normal values */ EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_start(&context, &contextData, DLT_LOG_DEFAULT)); data = UINT64_MIN; EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_uint64(&contextData, data)); data = 1; EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_uint64(&contextData, data)); data = UINT64_MAX; EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_uint64(&contextData, data)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_finish(&contextData)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_app()); } TEST(t_dlt_user_log_write_uint64, nullpointer) { DltContext context; uint64_t data; EXPECT_LE(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_LE(DLT_RETURN_OK, dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_user_log_write_uint64 nullpointer")); /* NULL */ data = 1; EXPECT_GE(DLT_RETURN_ERROR, dlt_user_log_write_uint64(NULL, data)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_app()); } /*/////////////////////////////////////// */ /* t_dlt_user_log_write_uint8_formatted */ TEST(t_dlt_user_log_write_uint8_formatted, normal) { DltContext context; DltContextData contextData; uint8_t data; EXPECT_LE(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_LE(DLT_RETURN_OK, dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_user_log_write_uint8_formatted normal")); /* normal values */ EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_start(&context, &contextData, DLT_LOG_DEFAULT)); data = UINT8_MIN; EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_uint8_formatted(&contextData, data, DLT_FORMAT_DEFAULT)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_uint8_formatted(&contextData, data, DLT_FORMAT_HEX8)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_uint8_formatted(&contextData, data, DLT_FORMAT_HEX16)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_uint8_formatted(&contextData, data, DLT_FORMAT_HEX32)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_uint8_formatted(&contextData, data, DLT_FORMAT_HEX64)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_uint8_formatted(&contextData, data, DLT_FORMAT_BIN8)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_uint8_formatted(&contextData, data, DLT_FORMAT_BIN16)); data = 1; EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_uint8_formatted(&contextData, data, DLT_FORMAT_DEFAULT)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_uint8_formatted(&contextData, data, DLT_FORMAT_HEX8)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_uint8_formatted(&contextData, data, DLT_FORMAT_HEX16)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_uint8_formatted(&contextData, data, DLT_FORMAT_HEX32)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_uint8_formatted(&contextData, data, DLT_FORMAT_HEX64)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_uint8_formatted(&contextData, data, DLT_FORMAT_BIN8)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_uint8_formatted(&contextData, data, DLT_FORMAT_BIN16)); data = UINT8_MAX; EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_uint8_formatted(&contextData, data, DLT_FORMAT_DEFAULT)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_uint8_formatted(&contextData, data, DLT_FORMAT_HEX8)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_uint8_formatted(&contextData, data, DLT_FORMAT_HEX16)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_uint8_formatted(&contextData, data, DLT_FORMAT_HEX32)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_uint8_formatted(&contextData, data, DLT_FORMAT_HEX64)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_uint8_formatted(&contextData, data, DLT_FORMAT_BIN8)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_uint8_formatted(&contextData, data, DLT_FORMAT_BIN16)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_finish(&contextData)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_app()); } TEST(t_dlt_user_log_write_uint8_formatted, abnormal) { DltContext context; DltContextData contextData; /* TODO: uint8_t data; */ EXPECT_LE(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_LE(DLT_RETURN_OK, dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_user_log_write_uint8_formatted abnormal")); /* abnormal values */ EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_start(&context, &contextData, DLT_LOG_DEFAULT)); /* TODO: data = 1; */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_user_log_write_uint8_formatted(&contextData, data, (DltFormatType)-100)); */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_user_log_write_uint8_formatted(&contextData, data, (DltFormatType)-10)); */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_user_log_write_uint8_formatted(&contextData, data, (DltFormatType)10)); */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_user_log_write_uint8_formatted(&contextData, data, (DltFormatType)100)); */ EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_finish(&contextData)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_app()); } TEST(t_dlt_user_log_write_uint8_formatted, nullpointer) { DltContext context; uint8_t data; EXPECT_LE(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_LE(DLT_RETURN_OK, dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_user_log_write_uint8_formatted nullpointer")); /* NULL */ data = 1; EXPECT_GE(DLT_RETURN_ERROR, dlt_user_log_write_uint8_formatted(NULL, data, DLT_FORMAT_DEFAULT)); EXPECT_GE(DLT_RETURN_ERROR, dlt_user_log_write_uint8_formatted(NULL, data, DLT_FORMAT_HEX8)); EXPECT_GE(DLT_RETURN_ERROR, dlt_user_log_write_uint8_formatted(NULL, data, DLT_FORMAT_HEX16)); EXPECT_GE(DLT_RETURN_ERROR, dlt_user_log_write_uint8_formatted(NULL, data, DLT_FORMAT_HEX32)); EXPECT_GE(DLT_RETURN_ERROR, dlt_user_log_write_uint8_formatted(NULL, data, DLT_FORMAT_HEX64)); EXPECT_GE(DLT_RETURN_ERROR, dlt_user_log_write_uint8_formatted(NULL, data, DLT_FORMAT_BIN8)); EXPECT_GE(DLT_RETURN_ERROR, dlt_user_log_write_uint8_formatted(NULL, data, DLT_FORMAT_BIN16)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_app()); } /*/////////////////////////////////////// */ /* t_dlt_user_log_write_uint16_formatted */ TEST(t_dlt_user_log_write_uint16_formatted, normal) { DltContext context; DltContextData contextData; uint16_t data; EXPECT_LE(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_LE(DLT_RETURN_OK, dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_user_log_write_uint16_formatted normal")); /* normal values */ EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_start(&context, &contextData, DLT_LOG_DEFAULT)); data = UINT16_MIN; EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_uint16_formatted(&contextData, data, DLT_FORMAT_DEFAULT)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_uint16_formatted(&contextData, data, DLT_FORMAT_HEX8)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_uint16_formatted(&contextData, data, DLT_FORMAT_HEX16)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_uint16_formatted(&contextData, data, DLT_FORMAT_HEX32)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_uint16_formatted(&contextData, data, DLT_FORMAT_HEX64)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_uint16_formatted(&contextData, data, DLT_FORMAT_BIN8)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_uint16_formatted(&contextData, data, DLT_FORMAT_BIN16)); data = 1; EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_uint16_formatted(&contextData, data, DLT_FORMAT_DEFAULT)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_uint16_formatted(&contextData, data, DLT_FORMAT_HEX8)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_uint16_formatted(&contextData, data, DLT_FORMAT_HEX16)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_uint16_formatted(&contextData, data, DLT_FORMAT_HEX32)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_uint16_formatted(&contextData, data, DLT_FORMAT_HEX64)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_uint16_formatted(&contextData, data, DLT_FORMAT_BIN8)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_uint16_formatted(&contextData, data, DLT_FORMAT_BIN16)); data = UINT16_MAX; EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_uint16_formatted(&contextData, data, DLT_FORMAT_DEFAULT)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_uint16_formatted(&contextData, data, DLT_FORMAT_HEX8)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_uint16_formatted(&contextData, data, DLT_FORMAT_HEX16)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_uint16_formatted(&contextData, data, DLT_FORMAT_HEX32)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_uint16_formatted(&contextData, data, DLT_FORMAT_HEX64)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_uint16_formatted(&contextData, data, DLT_FORMAT_BIN8)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_uint16_formatted(&contextData, data, DLT_FORMAT_BIN16)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_finish(&contextData)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_app()); } TEST(t_dlt_user_log_write_uint16_formatted, abnormal) { DltContext context; DltContextData contextData; /* TODO: uint16_t data; */ EXPECT_LE(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_LE(DLT_RETURN_OK, dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_user_log_write_uint16_formatted abnormal")); /* abnormal values */ EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_start(&context, &contextData, DLT_LOG_DEFAULT)); /* TODO: data = 1; */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_user_log_write_uint16_formatted(&contextData, data, (DltFormatType)-100)); */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_user_log_write_uint16_formatted(&contextData, data, (DltFormatType)-10)); */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_user_log_write_uint16_formatted(&contextData, data, (DltFormatType)10)); */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_user_log_write_uint16_formatted(&contextData, data, (DltFormatType)100)); */ EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_finish(&contextData)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_app()); } TEST(t_dlt_user_log_write_uint16_formatted, nullpointer) { DltContext context; uint16_t data; EXPECT_LE(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_LE(DLT_RETURN_OK, dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_user_log_write_uint16_formatted nullpointer")); /* NULL */ data = 1; EXPECT_GE(DLT_RETURN_ERROR, dlt_user_log_write_uint16_formatted(NULL, data, DLT_FORMAT_DEFAULT)); EXPECT_GE(DLT_RETURN_ERROR, dlt_user_log_write_uint16_formatted(NULL, data, DLT_FORMAT_HEX8)); EXPECT_GE(DLT_RETURN_ERROR, dlt_user_log_write_uint16_formatted(NULL, data, DLT_FORMAT_HEX16)); EXPECT_GE(DLT_RETURN_ERROR, dlt_user_log_write_uint16_formatted(NULL, data, DLT_FORMAT_HEX32)); EXPECT_GE(DLT_RETURN_ERROR, dlt_user_log_write_uint16_formatted(NULL, data, DLT_FORMAT_HEX64)); EXPECT_GE(DLT_RETURN_ERROR, dlt_user_log_write_uint16_formatted(NULL, data, DLT_FORMAT_BIN8)); EXPECT_GE(DLT_RETURN_ERROR, dlt_user_log_write_uint16_formatted(NULL, data, DLT_FORMAT_BIN16)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_app()); } /*/////////////////////////////////////// */ /* t_dlt_user_log_write_uint32_formatted */ TEST(t_dlt_user_log_write_uint32_formatted, normal) { DltContext context; DltContextData contextData; uint32_t data; EXPECT_LE(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_LE(DLT_RETURN_OK, dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_user_log_write_uint32_formatted normal")); /* normal values */ EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_start(&context, &contextData, DLT_LOG_DEFAULT)); data = UINT32_MIN; EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_uint32_formatted(&contextData, data, DLT_FORMAT_DEFAULT)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_uint32_formatted(&contextData, data, DLT_FORMAT_HEX8)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_uint32_formatted(&contextData, data, DLT_FORMAT_HEX16)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_uint32_formatted(&contextData, data, DLT_FORMAT_HEX32)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_uint32_formatted(&contextData, data, DLT_FORMAT_HEX64)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_uint32_formatted(&contextData, data, DLT_FORMAT_BIN8)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_uint32_formatted(&contextData, data, DLT_FORMAT_BIN16)); data = 1; EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_uint32_formatted(&contextData, data, DLT_FORMAT_DEFAULT)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_uint32_formatted(&contextData, data, DLT_FORMAT_HEX8)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_uint32_formatted(&contextData, data, DLT_FORMAT_HEX16)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_uint32_formatted(&contextData, data, DLT_FORMAT_HEX32)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_uint32_formatted(&contextData, data, DLT_FORMAT_HEX64)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_uint32_formatted(&contextData, data, DLT_FORMAT_BIN8)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_uint32_formatted(&contextData, data, DLT_FORMAT_BIN16)); data = UINT32_MAX; EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_uint32_formatted(&contextData, data, DLT_FORMAT_DEFAULT)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_uint32_formatted(&contextData, data, DLT_FORMAT_HEX8)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_uint32_formatted(&contextData, data, DLT_FORMAT_HEX16)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_uint32_formatted(&contextData, data, DLT_FORMAT_HEX32)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_uint32_formatted(&contextData, data, DLT_FORMAT_HEX64)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_uint32_formatted(&contextData, data, DLT_FORMAT_BIN8)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_uint32_formatted(&contextData, data, DLT_FORMAT_BIN16)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_finish(&contextData)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_app()); } TEST(t_dlt_user_log_write_uint32_formatted, abnormal) { DltContext context; DltContextData contextData; /* TODO: uint32_t data; */ EXPECT_LE(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_LE(DLT_RETURN_OK, dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_user_log_write_uint32_formatted abnormal")); /* abnormal values */ EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_start(&context, &contextData, DLT_LOG_DEFAULT)); /* TODO: data = 1; */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_user_log_write_uint32_formatted(&contextData, data, (DltFormatType)-100)); */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_user_log_write_uint32_formatted(&contextData, data, (DltFormatType)-10)); */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_user_log_write_uint32_formatted(&contextData, data, (DltFormatType)10)); */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_user_log_write_uint32_formatted(&contextData, data, (DltFormatType)100)); */ EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_finish(&contextData)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_app()); } TEST(t_dlt_user_log_write_uint32_formatted, nullpointer) { DltContext context; uint32_t data; EXPECT_LE(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_LE(DLT_RETURN_OK, dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_user_log_write_uint32_formatted nullpointer")); /* NULL */ data = 1; EXPECT_GE(DLT_RETURN_ERROR, dlt_user_log_write_uint32_formatted(NULL, data, DLT_FORMAT_DEFAULT)); EXPECT_GE(DLT_RETURN_ERROR, dlt_user_log_write_uint32_formatted(NULL, data, DLT_FORMAT_HEX8)); EXPECT_GE(DLT_RETURN_ERROR, dlt_user_log_write_uint32_formatted(NULL, data, DLT_FORMAT_HEX16)); EXPECT_GE(DLT_RETURN_ERROR, dlt_user_log_write_uint32_formatted(NULL, data, DLT_FORMAT_HEX32)); EXPECT_GE(DLT_RETURN_ERROR, dlt_user_log_write_uint32_formatted(NULL, data, DLT_FORMAT_HEX64)); EXPECT_GE(DLT_RETURN_ERROR, dlt_user_log_write_uint32_formatted(NULL, data, DLT_FORMAT_BIN8)); EXPECT_GE(DLT_RETURN_ERROR, dlt_user_log_write_uint32_formatted(NULL, data, DLT_FORMAT_BIN16)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_app()); } /*/////////////////////////////////////// */ /* t_dlt_user_log_write_uint64_formatted */ TEST(t_dlt_user_log_write_uint64_formatted, normal) { DltContext context; DltContextData contextData; uint64_t data; EXPECT_LE(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_LE(DLT_RETURN_OK, dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_user_log_write_uint64_formatted normal")); /* normal values */ EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_start(&context, &contextData, DLT_LOG_DEFAULT)); data = UINT64_MIN; EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_uint64_formatted(&contextData, data, DLT_FORMAT_DEFAULT)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_uint64_formatted(&contextData, data, DLT_FORMAT_HEX8)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_uint64_formatted(&contextData, data, DLT_FORMAT_HEX16)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_uint64_formatted(&contextData, data, DLT_FORMAT_HEX32)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_uint64_formatted(&contextData, data, DLT_FORMAT_HEX64)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_uint64_formatted(&contextData, data, DLT_FORMAT_BIN8)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_uint64_formatted(&contextData, data, DLT_FORMAT_BIN16)); data = 1; EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_uint64_formatted(&contextData, data, DLT_FORMAT_DEFAULT)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_uint64_formatted(&contextData, data, DLT_FORMAT_HEX8)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_uint64_formatted(&contextData, data, DLT_FORMAT_HEX16)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_uint64_formatted(&contextData, data, DLT_FORMAT_HEX32)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_uint64_formatted(&contextData, data, DLT_FORMAT_HEX64)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_uint64_formatted(&contextData, data, DLT_FORMAT_BIN8)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_uint64_formatted(&contextData, data, DLT_FORMAT_BIN16)); data = UINT64_MAX; EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_uint64_formatted(&contextData, data, DLT_FORMAT_DEFAULT)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_uint64_formatted(&contextData, data, DLT_FORMAT_HEX8)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_uint64_formatted(&contextData, data, DLT_FORMAT_HEX16)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_uint64_formatted(&contextData, data, DLT_FORMAT_HEX32)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_uint64_formatted(&contextData, data, DLT_FORMAT_HEX64)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_uint64_formatted(&contextData, data, DLT_FORMAT_BIN8)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_uint64_formatted(&contextData, data, DLT_FORMAT_BIN16)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_finish(&contextData)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_app()); } TEST(t_dlt_user_log_write_uint64_formatted, abnormal) { DltContext context; DltContextData contextData; /* TODO: uint64_t data; */ EXPECT_LE(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_LE(DLT_RETURN_OK, dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_user_log_write_uint64_formatted abnormal")); /* abnormal values */ EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_start(&context, &contextData, DLT_LOG_DEFAULT)); /* TODO: data = 1; */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_user_log_write_uint64_formatted(&contextData, data, (DltFormatType)-100)); */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_user_log_write_uint64_formatted(&contextData, data, (DltFormatType)-10)); */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_user_log_write_uint64_formatted(&contextData, data, (DltFormatType)10)); */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_user_log_write_uint64_formatted(&contextData, data, (DltFormatType)100)); */ EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_finish(&contextData)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_app()); } TEST(t_dlt_user_log_write_uint64_formatted, nullpointer) { DltContext context; uint64_t data; EXPECT_LE(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_LE(DLT_RETURN_OK, dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_user_log_write_uint64_formatted nullpointer")); /* NULL */ data = 1; EXPECT_GE(DLT_RETURN_ERROR, dlt_user_log_write_uint64_formatted(NULL, data, DLT_FORMAT_DEFAULT)); EXPECT_GE(DLT_RETURN_ERROR, dlt_user_log_write_uint64_formatted(NULL, data, DLT_FORMAT_HEX8)); EXPECT_GE(DLT_RETURN_ERROR, dlt_user_log_write_uint64_formatted(NULL, data, DLT_FORMAT_HEX16)); EXPECT_GE(DLT_RETURN_ERROR, dlt_user_log_write_uint64_formatted(NULL, data, DLT_FORMAT_HEX32)); EXPECT_GE(DLT_RETURN_ERROR, dlt_user_log_write_uint64_formatted(NULL, data, DLT_FORMAT_HEX64)); EXPECT_GE(DLT_RETURN_ERROR, dlt_user_log_write_uint64_formatted(NULL, data, DLT_FORMAT_BIN8)); EXPECT_GE(DLT_RETURN_ERROR, dlt_user_log_write_uint64_formatted(NULL, data, DLT_FORMAT_BIN16)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_app()); } /*/////////////////////////////////////// */ /* t_dlt_user_log_write_int */ TEST(t_dlt_user_log_write_int, normal) { DltContext context; DltContextData contextData; int data; EXPECT_LE(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_LE(DLT_RETURN_OK, dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_user_log_write_int normal")); /* normal values */ EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_start(&context, &contextData, DLT_LOG_DEFAULT)); data = -1; EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_int(&contextData, data)); data = 0; EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_int(&contextData, data)); data = 1; EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_int(&contextData, data)); data = INT_MIN; EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_int(&contextData, data)); data = INT_MAX; EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_int(&contextData, data)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_finish(&contextData)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_app()); } TEST(t_dlt_user_log_write_int, nullpointer) { DltContext context; int data; EXPECT_LE(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_LE(DLT_RETURN_OK, dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_user_log_write_int nullpointer")); /* NULL */ data = 1; EXPECT_GE(DLT_RETURN_ERROR, dlt_user_log_write_int(NULL, data)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_app()); } /*/////////////////////////////////////// */ /* t_dlt_user_log_write_int8 */ TEST(t_dlt_user_log_write_int8, normal) { DltContext context; DltContextData contextData; int8_t data; EXPECT_LE(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_LE(DLT_RETURN_OK, dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_user_log_write_int8 normal")); /* normal values */ EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_start(&context, &contextData, DLT_LOG_DEFAULT)); data = -1; EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_int8(&contextData, data)); data = 0; EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_int8(&contextData, data)); data = 1; EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_int8(&contextData, data)); data = INT8_MIN; EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_int8(&contextData, data)); data = INT8_MAX; EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_int8(&contextData, data)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_finish(&contextData)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_app()); } TEST(t_dlt_user_log_write_int8, nullpointer) { DltContext context; int8_t data; EXPECT_LE(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_LE(DLT_RETURN_OK, dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_user_log_write_int8 nullpointer")); /* NULL */ data = 1; EXPECT_GE(DLT_RETURN_ERROR, dlt_user_log_write_int8(NULL, data)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_app()); } /*/////////////////////////////////////// */ /* t_dlt_user_log_write_int16 */ TEST(t_dlt_user_log_write_int16, normal) { DltContext context; DltContextData contextData; int16_t data; EXPECT_LE(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_LE(DLT_RETURN_OK, dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_user_log_write_int16 normal")); /* normal values */ EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_start(&context, &contextData, DLT_LOG_DEFAULT)); data = -1; EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_int16(&contextData, data)); data = 0; EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_int16(&contextData, data)); data = 1; EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_int16(&contextData, data)); data = INT16_MIN; EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_int16(&contextData, data)); data = INT16_MAX; EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_int16(&contextData, data)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_finish(&contextData)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_app()); } TEST(t_dlt_user_log_write_int16, nullpointer) { DltContext context; int16_t data; EXPECT_LE(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_LE(DLT_RETURN_OK, dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_user_log_write_int16 nullpointer")); /* NULL */ data = 1; EXPECT_GE(DLT_RETURN_ERROR, dlt_user_log_write_int16(NULL, data)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_app()); } /*/////////////////////////////////////// */ /* t_dlt_user_log_write_int32 */ TEST(t_dlt_user_log_write_int32, normal) { DltContext context; DltContextData contextData; int32_t data; EXPECT_LE(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_LE(DLT_RETURN_OK, dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_user_log_write_int32 normal")); /* normal values */ EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_start(&context, &contextData, DLT_LOG_DEFAULT)); data = -1; EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_int32(&contextData, data)); data = 0; EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_int32(&contextData, data)); data = 1; EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_int32(&contextData, data)); data = INT32_MIN; EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_int32(&contextData, data)); data = INT32_MAX; EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_int32(&contextData, data)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_finish(&contextData)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_app()); } TEST(t_dlt_user_log_write_int32, nullpointer) { DltContext context; int32_t data; EXPECT_LE(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_LE(DLT_RETURN_OK, dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_user_log_write_int32 nullpointer")); /* NULL */ data = 1; EXPECT_GE(DLT_RETURN_ERROR, dlt_user_log_write_int32(NULL, data)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_app()); } /*/////////////////////////////////////// */ /* t_dlt_user_log_write_int64 */ TEST(t_dlt_user_log_write_int64, normal) { DltContext context; DltContextData contextData; int64_t data; EXPECT_LE(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_LE(DLT_RETURN_OK, dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_user_log_write_int64 normal")); /* normal values */ EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_start(&context, &contextData, DLT_LOG_DEFAULT)); data = -1; EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_int64(&contextData, data)); data = 0; EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_int64(&contextData, data)); data = 1; EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_int64(&contextData, data)); data = INT64_MIN; EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_int64(&contextData, data)); data = INT64_MAX; EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_int64(&contextData, data)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_finish(&contextData)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_app()); } TEST(t_dlt_user_log_write_int64, nullpointer) { DltContext context; int64_t data; EXPECT_LE(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_LE(DLT_RETURN_OK, dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_user_log_write_int64 nullpointer")); /* NULL */ data = 1; EXPECT_GE(DLT_RETURN_ERROR, dlt_user_log_write_int64(NULL, data)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_app()); } /*/////////////////////////////////////// */ /* t_dlt_user_log_write_string */ TEST(t_dlt_user_log_write_string, normal) { DltContext context; DltContextData contextData; EXPECT_LE(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_LE(DLT_RETURN_OK, dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_user_log_write_string normal")); /* normal values */ EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_start(&context, &contextData, DLT_LOG_DEFAULT)); const char *text1 = "test1"; EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_string(&contextData, text1)); const char *text2 = ""; EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_string(&contextData, text2)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_finish(&contextData)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_app()); } /** * Send a message which has the length exceed DLT_USER_ENV_LOG_MSG_BUF_LEN * Expectation: dlt_user_log_write_string() will be returned DLT_RETURN_USER_BUFFER_FULL and * message will be truncated and appended STR_TRUNCATED_MESSAGE at * the end of received message. */ TEST(t_dlt_user_log_write_string, normal_dlt_log_msg_truncated_because_exceed_the_buffer_length_in_verbose_mode) { DltContext context; DltContextData contextData; uint16_t index = 0; uint16_t package_description_size = 0; uint16_t user_message_after_truncated_size = 0; uint16_t send_message_length = 0; uint16_t str_truncate_message_length = 0; uint16_t expected_message_length = 0; char *message = NULL; char *expected_message = NULL; EXPECT_EQ(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_EQ(DLT_RETURN_OK, dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_user_log_write_string normal_dlt_log_msg_truncated_because_exceed_the_buffer_length_in_verbose_mode")); /* Normal values */ EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_start(&context, &contextData, DLT_LOG_DEFAULT)); /* Create the message exceed buffer length 10 bytes */ send_message_length = DLT_USER_BUF_MAX_SIZE + 10; message = (char *)(malloc(send_message_length)); ASSERT_TRUE(message != NULL) << "Failed to allocate memory."; for (index = 0; index < send_message_length; index++) { message[index] = '#'; } message[send_message_length - 1] = '\0'; /** * In Verbose Mode: * package_description_size = Type info (32 bits) + Description of data payload of type string (16 bits) */ package_description_size = sizeof(uint32_t) + sizeof(uint16_t); str_truncate_message_length = strlen(STR_TRUNCATED_MESSAGE) + 1; /* Create the expected message */ expected_message_length = DLT_USER_BUF_MAX_SIZE - package_description_size; expected_message = (char *)(malloc(expected_message_length)); ASSERT_TRUE(expected_message != NULL) << "Failed to allocate memory."; user_message_after_truncated_size = expected_message_length - str_truncate_message_length; for (index = 0; index < user_message_after_truncated_size; index++) { expected_message[index] = '#'; } strncpy(expected_message + user_message_after_truncated_size, STR_TRUNCATED_MESSAGE, str_truncate_message_length); EXPECT_EQ(DLT_RETURN_USER_BUFFER_FULL, dlt_user_log_write_string(&contextData, message)); ASSERT_STREQ(expected_message, (char *)(contextData.buffer + package_description_size)); free(message); message = NULL; free(expected_message); expected_message = NULL; EXPECT_EQ(DLT_RETURN_OK, dlt_user_log_write_finish(&contextData)); EXPECT_EQ(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_EQ(DLT_RETURN_OK, dlt_unregister_app()); } /** * In Non-Verbose mode, send a message which has the length exceed DLT_USER_ENV_LOG_MSG_BUF_LEN * Expectation: dlt_user_log_write_string() will be returned DLT_RETURN_USER_BUFFER_FULL and * message will be truncated and appended STR_TRUNCATED_MESSAGE at * the end of received message. */ TEST(t_dlt_user_log_write_string, normal_dlt_log_msg_truncated_because_exceed_the_buffer_length_in_non_verbose_mode) { DltContext context; DltContextData contextData; uint16_t index = 0; uint16_t package_description_size = 0; uint16_t user_message_after_truncated_size = 0; uint16_t send_message_length = 0; uint16_t str_truncate_message_length = 0; uint16_t expected_message_length = 0; char *message = NULL; char *expected_message = NULL; dlt_nonverbose_mode(); EXPECT_EQ(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_EQ(DLT_RETURN_OK, dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_user_log_write_string normal_dlt_log_msg_truncated_because_exceed_the_buffer_length_in_non_verbose_mode")); /* Normal values */ EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_start(&context, &contextData, DLT_LOG_DEFAULT)); /* Create the message exceed buffer length 10 bytes */ send_message_length = DLT_USER_BUF_MAX_SIZE + 10; message = (char *)(malloc(send_message_length)); ASSERT_TRUE(message != NULL) << "Failed to allocate memory."; for (index = 0; index < send_message_length; index++) { message[index] = '#'; } message[send_message_length - 1] = '\0'; /** * In Non-Verbose Mode: * package_description_size = Message ID (32 bits) + Description of data payload of type string (16 bits) */ package_description_size = sizeof(uint32_t) + sizeof(uint16_t); str_truncate_message_length = strlen(STR_TRUNCATED_MESSAGE) + 1; /* Create the expected message */ expected_message_length = DLT_USER_BUF_MAX_SIZE - package_description_size; expected_message = (char *)(malloc(expected_message_length)); ASSERT_TRUE(expected_message != NULL) << "Failed to allocate memory."; user_message_after_truncated_size = expected_message_length - str_truncate_message_length; for (index = 0; index < user_message_after_truncated_size; index++) { expected_message[index] = '#'; } strncpy(expected_message + user_message_after_truncated_size, STR_TRUNCATED_MESSAGE, str_truncate_message_length); EXPECT_EQ(DLT_RETURN_USER_BUFFER_FULL, dlt_user_log_write_string(&contextData, message)); ASSERT_STREQ(expected_message, (char *)(contextData.buffer + package_description_size)); free(message); message = NULL; free(expected_message); expected_message = NULL; EXPECT_EQ(DLT_RETURN_OK, dlt_user_log_write_finish(&contextData)); EXPECT_EQ(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_EQ(DLT_RETURN_OK, dlt_unregister_app()); /* Restore verbose mode */ dlt_verbose_mode(); } /** * Set the DLT_USER_ENV_LOG_MSG_BUF_LEN to 46, send a message which has the length exceed DLT_USER_ENV_LOG_MSG_BUF_LEN * Expectation: dlt_user_log_write_string() will be returned DLT_RETURN_USER_BUFFER_FULL and * message will be truncated and appended STR_TRUNCATED_MESSAGE at * the end of received message. * Note: dlt_init() will be called after testcase is finished to restore environment for other test cases */ TEST(t_dlt_user_log_write_string, normal_message_truncated_because_exceed_buffer_length_and_reduce_msg_buf_len_by_env_variable) { DltContext context; DltContextData contextData; uint16_t index = 0; uint16_t package_description_size = 0; uint16_t str_truncate_message_length = 0; uint16_t expected_message_length = 0; uint16_t user_message_after_truncated_size = 0; const char *message = "$$$$###############################################"; char *expected_message = NULL; /** * Re-initialize the dlt with dlt user buffer size from DLT_USER_ENV_LOG_MSG_BUF_LEN environment variable * to simulate use case the dlt user buffer size only available 4 bytes for store user message. * Note: 46 bytes = package_description_size (6 bytes) + str_truncated_message_length (35 bytes) + 4 bytes user message + 1 byte NULL terminator. */ user_message_after_truncated_size = 4; EXPECT_EQ(DLT_RETURN_OK, dlt_free()); setenv(DLT_USER_ENV_LOG_MSG_BUF_LEN, "46", 1); EXPECT_EQ(DLT_RETURN_OK, dlt_init()); EXPECT_EQ(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_EQ(DLT_RETURN_OK, dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_user_log_write_string normal_message_truncated_because_exceed_buffer_length_and_reduce_msg_buf_len_by_env_variable")); /* Normal values */ EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_start(&context, &contextData, DLT_LOG_DEFAULT)); EXPECT_EQ(DLT_RETURN_USER_BUFFER_FULL, dlt_user_log_write_string(&contextData, message)); /** * In Verbose Mode: * package_description_size = Type info (32 bits) + Description of data payload of type string (16 bits) */ package_description_size = sizeof(uint32_t) + sizeof(uint16_t); str_truncate_message_length = strlen(STR_TRUNCATED_MESSAGE) + 1; /* Create the expected message */ expected_message_length = user_message_after_truncated_size + str_truncate_message_length; expected_message = (char *)(malloc(expected_message_length)); ASSERT_TRUE(expected_message != NULL) << "Failed to allocate memory."; for (index = 0; index < user_message_after_truncated_size; index++) { expected_message[index] = '$'; } strncpy(expected_message + user_message_after_truncated_size, STR_TRUNCATED_MESSAGE, str_truncate_message_length); ASSERT_STREQ(expected_message, (char *)(contextData.buffer + package_description_size)); EXPECT_EQ(DLT_RETURN_OK, dlt_user_log_write_finish(&contextData)); EXPECT_EQ(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_EQ(DLT_RETURN_OK, dlt_unregister_app()); /* Restore the dlt with dlt user buffer size as default */ EXPECT_EQ(DLT_RETURN_OK, dlt_free()); unsetenv(DLT_USER_ENV_LOG_MSG_BUF_LEN); EXPECT_EQ(DLT_RETURN_OK, dlt_init()); } /** * Set DLT_USER_ENV_LOG_MSG_BUF_LEN to 35 bytes and send a message which has the length exceed DLT_USER_ENV_LOG_MSG_BUF_LEN * Expectation: dlt_user_log_write_string() will be returned DLT_RETURN_USER_BUFFER_FULL because the DLT_USER_ENV_LOG_MSG_BUF_LEN * does not have enough space to store truncate message STR_TRUNCATED_MESSAGE * Note: dlt_init() will be called after testcase is finished to restore environment for other test cases */ TEST(t_dlt_user_log_write_string, normal_DLT_USER_ENV_LOG_MSG_BUF_LEN_does_not_enough_space_for_truncated_message) { DltContext context; DltContextData contextData; uint16_t package_description_size = 0; const char *message = "################################################################################"; /** * Re-initialize the dlt with dlt user buffer size from DLT_USER_ENV_LOG_MSG_BUF_LEN environment variable * to simulate use case the dlt user buffer size not enough minimum space to store data even the truncate notice message. * Note: The minimum buffer to store the truncate notice message is 42 bytes. */ EXPECT_EQ(DLT_RETURN_OK, dlt_free()); setenv(DLT_USER_ENV_LOG_MSG_BUF_LEN, "35", 1); EXPECT_EQ(DLT_RETURN_OK, dlt_init()); EXPECT_EQ(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_EQ(DLT_RETURN_OK, dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_user_log_write_string normal_DLT_USER_ENV_LOG_MSG_BUF_LEN_does_not_enough_space_for_truncated_message")); /* Normal values */ EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_start(&context, &contextData, DLT_LOG_DEFAULT)); EXPECT_EQ(DLT_RETURN_USER_BUFFER_FULL, dlt_user_log_write_string(&contextData, message)); /** * In Verbose Mode: * package_description_size = Type info (32 bits) + Description of data payload of type string (16 bits) */ package_description_size = sizeof(uint32_t) + sizeof(uint16_t); ASSERT_STREQ("", (char *)(contextData.buffer + package_description_size)); EXPECT_EQ(DLT_RETURN_OK, dlt_user_log_write_finish(&contextData)); EXPECT_EQ(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_EQ(DLT_RETURN_OK, dlt_unregister_app()); /* Restore the dlt with dlt user buffer size as default */ EXPECT_EQ(DLT_RETURN_OK, dlt_free()); unsetenv(DLT_USER_ENV_LOG_MSG_BUF_LEN); EXPECT_EQ(DLT_RETURN_OK, dlt_init()); } /** * Set DLT_USER_ENV_LOG_MSG_BUF_LEN to 42 bytes and send a message which has the length exceed DLT_USER_ENV_LOG_MSG_BUF_LEN * Expectation: dlt_user_log_write_string() will be returned DLT_RETURN_USER_BUFFER_FULL and * receive message will be STR_TRUNCATED_MESSAGE * Note: dlt_init() will be called after testcase is finished to restore environment for other test cases */ TEST(t_dlt_user_log_write_string, normal_DLT_USER_ENV_LOG_MSG_BUF_LEN_fix_truncate_message) { DltContext context; DltContextData contextData; uint16_t package_description_size = 0; const char *message = "################################################################################"; /** * Re-initialize the dlt with dlt user buffer size from DLT_USER_ENV_LOG_MSG_BUF_LEN environment variable * to simulate use case the dlt user buffer size just fixed to truncate message STR_TRUNCATED_MESSAGE * Note: 42 bytes = package_description_size (6 bytes) + str_truncated_message_length (35 bytes) + 1 byte NULL terminator. */ EXPECT_EQ(DLT_RETURN_OK, dlt_free()); setenv(DLT_USER_ENV_LOG_MSG_BUF_LEN, "42", 1); EXPECT_EQ(DLT_RETURN_OK, dlt_init()); EXPECT_EQ(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_EQ(DLT_RETURN_OK, dlt_register_context(&context, "TEST", "dlt_user.c normal_DLT_USER_ENV_LOG_MSG_BUF_LEN_fix_truncate_message")); /* Normal values */ EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_start(&context, &contextData, DLT_LOG_DEFAULT)); EXPECT_EQ(DLT_RETURN_USER_BUFFER_FULL, dlt_user_log_write_string(&contextData, message)); /** * In Verbose Mode: * package_description_size = Type info (32 bits) + Description of data payload of type string (16 bits) */ package_description_size = sizeof(uint32_t) + sizeof(uint16_t); ASSERT_STREQ(STR_TRUNCATED_MESSAGE, (char *)(contextData.buffer + package_description_size)); EXPECT_EQ(DLT_RETURN_OK, dlt_user_log_write_finish(&contextData)); EXPECT_EQ(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_EQ(DLT_RETURN_OK, dlt_unregister_app()); /* Restore the dlt with dlt user buffer size as default */ EXPECT_EQ(DLT_RETURN_OK, dlt_free()); unsetenv(DLT_USER_ENV_LOG_MSG_BUF_LEN); EXPECT_EQ(DLT_RETURN_OK, dlt_init()); } TEST(t_dlt_user_log_write_string, nullpointer) { DltContext context; DltContextData contextData; EXPECT_LE(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_LE(DLT_RETURN_OK, dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_user_log_write_string nullpointer")); /* NULL */ const char *text1 = "test1"; EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_start(&context, &contextData, DLT_LOG_DEFAULT)); EXPECT_GE(DLT_RETURN_ERROR, dlt_user_log_write_string(NULL, text1)); EXPECT_GE(DLT_RETURN_ERROR, dlt_user_log_write_string(NULL, NULL)); EXPECT_GE(DLT_RETURN_ERROR, dlt_user_log_write_string(&contextData, NULL)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_finish(&contextData)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_app()); } /*/////////////////////////////////////// */ /* t_dlt_user_log_write_constant_string */ TEST(t_dlt_user_log_write_constant_string, normal) { DltContext context; DltContextData contextData; EXPECT_LE(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_LE(DLT_RETURN_OK, dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_user_log_write_constant_string normal")); /* normal values */ EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_start(&context, &contextData, DLT_LOG_DEFAULT)); const char *text1 = "test1"; EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_constant_string(&contextData, text1)); const char *text2 = ""; EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_constant_string(&contextData, text2)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_finish(&contextData)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_app()); } /** * Send a message which has the length exceed DLT_USER_ENV_LOG_MSG_BUF_LEN * Expectation: dlt_user_log_write_constant_string() will be returned DLT_RETURN_USER_BUFFER_FULL and * message will be truncated and appended STR_TRUNCATED_MESSAGE at * the end of received message. */ TEST(t_dlt_user_log_write_constant_string, normal_too_long_message_is_truncated_and_appended_notice_message_in_verbose_mode) { DltContext context; DltContextData contextData; uint16_t index = 0; uint16_t package_description_size = 0; uint16_t user_message_after_truncated_size = 0; uint16_t send_message_length = 0; uint16_t str_truncate_message_length = 0; uint16_t expected_message_length = 0; char *message = NULL; char *expected_message = NULL; EXPECT_EQ(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_EQ(DLT_RETURN_OK, dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_user_log_write_constant_string normal_too_long_message_is_truncated_and_appended_notice_message_in_verbose_mode")); /* Normal values */ EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_start(&context, &contextData, DLT_LOG_DEFAULT)); /** * In Verbose Mode: * package_description_size = Type info (32 bits) + Description of data payload of type string (16 bits) */ package_description_size = sizeof(uint32_t) + sizeof(uint16_t); str_truncate_message_length = strlen(STR_TRUNCATED_MESSAGE) + 1; /* Create the message exceed DLT_USER_ENV_LOG_MSG_BUF_LEN 10 bytes */ send_message_length = DLT_USER_BUF_MAX_SIZE + 10; message = (char *)(malloc(send_message_length)); ASSERT_TRUE(message != NULL) << "Failed to allocate memory."; for (index = 0; index < send_message_length; index++) { message[index] = '#'; } message[send_message_length - 1] = '\0'; /* Create the expected message */ expected_message_length = DLT_USER_BUF_MAX_SIZE - package_description_size; expected_message = (char *)(malloc(expected_message_length)); ASSERT_TRUE(expected_message != NULL) << "Failed to allocate memory."; user_message_after_truncated_size = expected_message_length - str_truncate_message_length; for (index = 0; index < user_message_after_truncated_size; index++) { expected_message[index] = '#'; } strncpy(expected_message + user_message_after_truncated_size, STR_TRUNCATED_MESSAGE, str_truncate_message_length); EXPECT_EQ(DLT_RETURN_USER_BUFFER_FULL, dlt_user_log_write_constant_string(&contextData, message)); ASSERT_STREQ(expected_message, (char *)(contextData.buffer + package_description_size)); free(message); message = NULL; free(expected_message); expected_message = NULL; EXPECT_EQ(DLT_RETURN_OK, dlt_user_log_write_finish(&contextData)); EXPECT_EQ(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_EQ(DLT_RETURN_OK, dlt_unregister_app()); } /** * In Non-Verbose Mode * Expectation: dlt_user_log_write_constant_string() will not package and send message. Return DLT_RETURN_OK */ TEST(t_dlt_user_log_write_constant_string, normal_do_nothing_in_non_verbose_mode) { DltContext context; DltContextData contextData; const char *message = "message"; dlt_nonverbose_mode(); EXPECT_EQ(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_EQ(DLT_RETURN_OK, dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_user_log_write_constant_string normal_do_nothing_in_non_verbose_mode")); /* Normal values */ EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_start(&context, &contextData, DLT_LOG_DEFAULT)); EXPECT_EQ(DLT_RETURN_OK, dlt_user_log_write_constant_string(&contextData, message)); EXPECT_EQ(DLT_RETURN_OK, dlt_user_log_write_finish(&contextData)); EXPECT_EQ(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_EQ(DLT_RETURN_OK, dlt_unregister_app()); /* Restore verbose mode */ dlt_verbose_mode(); } TEST(t_dlt_user_log_write_constant_string, nullpointer) { DltContext context; DltContextData contextData; EXPECT_LE(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_LE(DLT_RETURN_OK, dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_user_log_write_constant_string nullpointer")); /* NULL */ const char *text1 = "test1"; EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_start(&context, &contextData, DLT_LOG_DEFAULT)); EXPECT_GE(DLT_RETURN_ERROR, dlt_user_log_write_constant_string(NULL, text1)); EXPECT_GE(DLT_RETURN_ERROR, dlt_user_log_write_constant_string(NULL, NULL)); EXPECT_GE(DLT_RETURN_ERROR, dlt_user_log_write_constant_string(&contextData, NULL)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_finish(&contextData)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_app()); } /*/////////////////////////////////////// */ /* t_dlt_user_log_write_utf8_string */ TEST(t_dlt_user_log_write_utf8_string, normal) { DltContext context; DltContextData contextData; EXPECT_LE(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_LE(DLT_RETURN_OK, dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_user_log_write_utf8_string normal")); /* normal values */ EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_start(&context, &contextData, DLT_LOG_DEFAULT)); const char *text1 = "test1"; EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_utf8_string(&contextData, text1)); const char *text2 = ""; EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_utf8_string(&contextData, text2)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_finish(&contextData)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_app()); } /** * Send a message which has the length exceed DLT_USER_ENV_LOG_MSG_BUF_LEN * Expectation: dlt_user_log_write_utf8_string() will be returned DLT_RETURN_USER_BUFFER_FULL and * message will be truncated at one byte utf-8 and appended STR_TRUNCATED_MESSAGE at * the end of received message. */ TEST(t_dlt_user_log_write_utf8_string, normal_message_truncated_at_utf8_1byte_in_verbose_mode) { DltContext context; DltContextData contextData; uint16_t index = 0; uint16_t package_description_size = 0; uint16_t user_message_after_truncated_size = 0; uint16_t send_message_length = 0; uint16_t str_truncate_message_length = 0; uint16_t expected_message_length = 0; char *message = NULL; char *expected_message = NULL; EXPECT_EQ(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_EQ(DLT_RETURN_OK, dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_user_log_write_utf8_string normal_message_truncated_at_utf8_1byte_in_verbose_mode")); /* Normal values */ EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_start(&context, &contextData, DLT_LOG_DEFAULT)); /* Create the message exceed buffer length 10 bytes which have '$' character (utf-8 1 byte) right before truncate position */ send_message_length = DLT_USER_BUF_MAX_SIZE + 10; message = (char *)(malloc(send_message_length)); ASSERT_TRUE(message != NULL) << "Failed to allocate memory."; for (index = 0; index < send_message_length; index++) { message[index] = '#'; } message[send_message_length - 1] = '\0'; /** * In Verbose Mode: * package_description_size = Type info (32 bits) + Description of data payload of type string (16 bits) */ package_description_size = sizeof(uint32_t) + sizeof(uint16_t); /* Fill '$' before truncate position */ str_truncate_message_length = strlen(STR_TRUNCATED_MESSAGE) + 1; index = (DLT_USER_BUF_MAX_SIZE - package_description_size - str_truncate_message_length - 1); message[index] = '$'; /* Create the expected message */ expected_message_length = DLT_USER_BUF_MAX_SIZE - package_description_size; expected_message = (char *)(malloc(expected_message_length)); ASSERT_TRUE(expected_message != NULL) << "Failed to allocate memory."; user_message_after_truncated_size = expected_message_length - str_truncate_message_length; for (index = 0; index < (user_message_after_truncated_size - 1); index++) { expected_message[index] = '#'; } expected_message[user_message_after_truncated_size - 1] = '$'; strncpy(expected_message + user_message_after_truncated_size, STR_TRUNCATED_MESSAGE, str_truncate_message_length); EXPECT_EQ(DLT_RETURN_USER_BUFFER_FULL, dlt_user_log_write_utf8_string(&contextData, message)); ASSERT_STREQ(expected_message, (char *)(contextData.buffer + package_description_size)); free(message); message = NULL; free(expected_message); message = NULL; EXPECT_EQ(DLT_RETURN_OK, dlt_user_log_write_finish(&contextData)); EXPECT_EQ(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_EQ(DLT_RETURN_OK, dlt_unregister_app()); } /** * In Non-Verbose Mode, send a message which has the length exceed DLT_USER_ENV_LOG_MSG_BUF_LEN * Expectation: dlt_user_log_write_utf8_string() will be returned DLT_RETURN_USER_BUFFER_FULL and * message will be truncated at one byte utf-8 and appended STR_TRUNCATED_MESSAGE at * the end of received message. */ TEST(t_dlt_user_log_write_utf8_string, normal_message_truncated_at_utf8_1byte_in_non_verbose_mode) { DltContext context; DltContextData contextData; uint16_t index = 0; uint16_t package_description_size = 0; uint16_t user_message_after_truncated_size = 0; uint16_t send_message_length = 0; uint16_t str_truncate_message_length = 0; uint16_t expected_message_length = 0; char *message = NULL; char *expected_message = NULL; dlt_nonverbose_mode(); EXPECT_EQ(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_EQ(DLT_RETURN_OK, dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_user_log_write_utf8_string normal_message_truncated_at_utf8_1byte_in_non_verbose_mode")); /* Normal values */ EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_start(&context, &contextData, DLT_LOG_DEFAULT)); /* Create the message exceed buffer length 10 bytes which have '$' character (utf-8 1 byte) right before truncate position */ send_message_length = DLT_USER_BUF_MAX_SIZE + 10; message = (char *)(malloc(send_message_length)); ASSERT_TRUE(message != NULL) << "Failed to allocate memory."; for (index = 0; index < send_message_length; index++) { message[index] = '#'; } message[send_message_length - 1] = '\0'; str_truncate_message_length = strlen(STR_TRUNCATED_MESSAGE) + 1; /** * In Non-Verbose Mode: * package_description_size = Message ID (32 bits) + Description of data payload of type string (16 bits) */ package_description_size = sizeof(uint32_t) + sizeof(uint16_t); /* Fill '$' before truncate position */ index = (DLT_USER_BUF_MAX_SIZE - package_description_size - str_truncate_message_length - 1); message[index] = '$'; /* Create the expected message */ expected_message_length = DLT_USER_BUF_MAX_SIZE - package_description_size; expected_message = (char *)(malloc(expected_message_length)); ASSERT_TRUE(expected_message != NULL) << "Failed to allocate memory."; user_message_after_truncated_size = expected_message_length - str_truncate_message_length; for (index = 0; index < (user_message_after_truncated_size - 1); index++) { expected_message[index] = '#'; } expected_message[user_message_after_truncated_size - 1] = '$'; strncpy(expected_message + user_message_after_truncated_size, STR_TRUNCATED_MESSAGE, str_truncate_message_length); EXPECT_EQ(DLT_RETURN_USER_BUFFER_FULL, dlt_user_log_write_utf8_string(&contextData, message)); ASSERT_STREQ(expected_message, (char *)(contextData.buffer + package_description_size)); free(message); message = NULL; free(expected_message); message = NULL; EXPECT_EQ(DLT_RETURN_OK, dlt_user_log_write_finish(&contextData)); EXPECT_EQ(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_EQ(DLT_RETURN_OK, dlt_unregister_app()); /* Restore verbose mode */ dlt_verbose_mode(); } /** * Set the DLT_USER_ENV_LOG_MSG_BUF_LEN to 46, send a message which has the length exceed DLT_USER_ENV_LOG_MSG_BUF_LEN * Expectation: dlt_user_log_write_utf8_string() will be returned DLT_RETURN_USER_BUFFER_FULL and * message will be truncated at the whole utf-8 1 bytes and appended * STR_TRUNCATED_MESSAGE at the end of received message. * Note: dlt_init() will be called after testcase is finished to restore environment for other testcases */ TEST(t_dlt_user_log_write_utf8_string, normal_message_truncated_at_utf8_1bytes_and_reduce_msg_buf_len_by_env_variable) { DltContext context; DltContextData contextData; uint16_t index = 0; uint16_t package_description_size = 0; uint16_t expected_message_length = 0; uint16_t str_truncate_message_length = 0; uint16_t user_message_after_truncated_size = 0; const char *message = "$$$$###############################################"; char *expected_message = NULL; /** * Re-initialize the dlt with dlt user buffer size from DLT_USER_ENV_LOG_MSG_BUF_LEN environment variable * to simulate use case the dlt user buffer size only available 4 bytes for store user message. * Note: 46 bytes = package_description_size (6 bytes) + str_truncated_message_length (35 bytes) + 4 bytes user message + 1 byte NULL terminator. */ user_message_after_truncated_size = 4; EXPECT_EQ(DLT_RETURN_OK, dlt_free()); setenv(DLT_USER_ENV_LOG_MSG_BUF_LEN, "46", 1); EXPECT_EQ(DLT_RETURN_OK, dlt_init()); EXPECT_EQ(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_EQ(DLT_RETURN_OK, dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_user_log_write_utf8_string normal_message_truncated_at_utf8_1bytes_and_reduce_msg_buf_len_by_env_variable")); /* Normal values */ EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_start(&context, &contextData, DLT_LOG_DEFAULT)); EXPECT_EQ(DLT_RETURN_USER_BUFFER_FULL, dlt_user_log_write_utf8_string(&contextData, message)); /** * In Verbose Mode: * package_description_size = Type info (32 bits) + Description of data payload of type string (16 bits) */ package_description_size = sizeof(uint32_t) + sizeof(uint16_t); str_truncate_message_length = strlen(STR_TRUNCATED_MESSAGE) + 1; /* Create the expected message */ expected_message_length = user_message_after_truncated_size + str_truncate_message_length; expected_message = (char *)(malloc(expected_message_length)); ASSERT_TRUE(expected_message != NULL) << "Failed to allocate memory."; for (index = 0; index < user_message_after_truncated_size; index++) { expected_message[index] = '$'; } strncpy(expected_message + user_message_after_truncated_size, STR_TRUNCATED_MESSAGE, str_truncate_message_length); ASSERT_STREQ(expected_message, (char *)(contextData.buffer + package_description_size)); EXPECT_EQ(DLT_RETURN_OK, dlt_user_log_write_finish(&contextData)); EXPECT_EQ(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_EQ(DLT_RETURN_OK, dlt_unregister_app()); /* Restore the dlt with dlt user buffer size as default */ EXPECT_EQ(DLT_RETURN_OK, dlt_free()); unsetenv(DLT_USER_ENV_LOG_MSG_BUF_LEN); EXPECT_EQ(DLT_RETURN_OK, dlt_init()); } /** * In Non-Verbose Mode, send a message which has the length exceed DLT_USER_ENV_LOG_MSG_BUF_LEN * Expectation: dlt_user_log_write_utf8_string() will be returned DLT_RETURN_USER_BUFFER_FULL and * message will be truncated at the middle of utf-8 2 bytes, the rest of this utf-8 character will * be removed completely, after that appended STR_TRUNCATED_MESSAGE at * the end of received message. */ TEST(t_dlt_user_log_write_utf8_string, normal_message_truncated_at_utf8_2bytes_in_verbose_mode) { DltContext context; DltContextData contextData; uint16_t index = 0; uint16_t package_description_size = 0; uint16_t user_message_after_truncated_size = 0; uint16_t send_message_length = 0; uint16_t str_truncate_message_length = 0; uint16_t expected_message_length = 0; uint16_t remaining_byte_truncated_utf8_character = 0; const char *utf8_2byte_character = "¢"; char *message = NULL; char *expected_message = NULL; EXPECT_EQ(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_EQ(DLT_RETURN_OK, dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_user_log_write_utf8_string normal_message_truncated_at_utf8_2bytes_in_verbose_mode")); /* Normal values */ EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_start(&context, &contextData, DLT_LOG_DEFAULT)); /* Create the message contain the '¢' (2 bytes utf-8 character) and last byte of this character is exceed buffer length */ send_message_length = DLT_USER_BUF_MAX_SIZE + 10; message = (char *)(malloc(send_message_length)); ASSERT_TRUE(message != NULL) << "Failed to allocate memory."; for (index = 0; index < send_message_length; index++) { message[index] = '#'; } message[send_message_length - 1] = '\0'; /** * In Verbose Mode: * package_description_size = Type info (32 bits) + Description of data payload of type string (16 bits) */ package_description_size = sizeof(uint32_t) + sizeof(uint16_t); /** * Fill the "¢" character at the position which the last byte of this character is exceed the buffer length and * expectation is it will be truncated 1 more bytes in the character sequence */ str_truncate_message_length = strlen(STR_TRUNCATED_MESSAGE) + 1; remaining_byte_truncated_utf8_character = 1; index = (DLT_USER_BUF_MAX_SIZE - package_description_size - str_truncate_message_length - remaining_byte_truncated_utf8_character); strncpy(message + index, utf8_2byte_character, strlen(utf8_2byte_character)); /* Create the expected message */ expected_message_length = DLT_USER_BUF_MAX_SIZE - package_description_size; expected_message = (char *)(malloc(expected_message_length)); ASSERT_TRUE(expected_message != NULL) << "Failed to allocate memory."; user_message_after_truncated_size = expected_message_length - str_truncate_message_length - remaining_byte_truncated_utf8_character; for (index = 0; index < user_message_after_truncated_size; index++) { expected_message[index] = '#'; } strncpy(expected_message + user_message_after_truncated_size, STR_TRUNCATED_MESSAGE, str_truncate_message_length); EXPECT_EQ(DLT_RETURN_USER_BUFFER_FULL, dlt_user_log_write_utf8_string(&contextData, message)); ASSERT_STREQ(expected_message, (char *)(contextData.buffer + package_description_size)); free(message); message = NULL; free(expected_message); expected_message = NULL; EXPECT_EQ(DLT_RETURN_OK, dlt_user_log_write_finish(&contextData)); EXPECT_EQ(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_EQ(DLT_RETURN_OK, dlt_unregister_app()); } /** * In Non-Verbose Mode, send a message which has the length exceed DLT_USER_ENV_LOG_MSG_BUF_LEN * Expectation: dlt_user_log_write_utf8_string() will be returned DLT_RETURN_USER_BUFFER_FULL and * message will be truncated at the middle of utf-8 2 bytes, the rest of this utf-8 character will * be removed completely, after that appended STR_TRUNCATED_MESSAGE at * the end of received message. */ TEST(t_dlt_user_log_write_utf8_string, normal_message_truncated_at_utf8_2bytes_in_non_verbose_mode) { DltContext context; DltContextData contextData; uint16_t index = 0; uint16_t package_description_size = 0; uint16_t user_message_after_truncated_size = 0; uint16_t send_message_length = 0; uint16_t str_truncate_message_length = 0; uint16_t expected_message_length = 0; uint16_t remaining_byte_truncated_utf8_character = 0; const char *utf8_2byte_character = "¢"; char *message = NULL; char *expected_message = NULL; dlt_nonverbose_mode(); EXPECT_EQ(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_EQ(DLT_RETURN_OK, dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_user_log_write_utf8_string normal_message_truncated_at_utf8_2bytes_in_non_verbose_mode")); /* Normal values */ EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_start(&context, &contextData, DLT_LOG_DEFAULT)); /* Create the message contain the '¢' (2 bytes utf-8 character) and last byte of this character is exceed buffer length */ send_message_length = DLT_USER_BUF_MAX_SIZE + 10; message = (char *)(malloc(send_message_length)); ASSERT_TRUE(message != NULL) << "Failed to allocate memory."; for (index = 0; index < send_message_length; index++) { message[index] = '#'; } message[send_message_length - 1] = '\0'; /** * In Non-Verbose Mode: * package_description_size = Message ID (32 bits) + Description of data payload of type string (16 bits) */ package_description_size = sizeof(uint32_t) + sizeof(uint16_t); /** * Fill the "¢" character at the position which the last byte of this character is exceed the buffer length and * expectation is it will be truncated 1 more bytes in the character sequence */ str_truncate_message_length = strlen(STR_TRUNCATED_MESSAGE) + 1; remaining_byte_truncated_utf8_character = 1; index = (DLT_USER_BUF_MAX_SIZE - package_description_size - str_truncate_message_length - remaining_byte_truncated_utf8_character); strncpy(message + index, utf8_2byte_character, strlen(utf8_2byte_character)); /* Create the expected message */ expected_message_length = DLT_USER_BUF_MAX_SIZE - package_description_size; expected_message = (char *)(malloc(DLT_USER_BUF_MAX_SIZE)); ASSERT_TRUE(expected_message != NULL) << "Failed to allocate memory."; user_message_after_truncated_size = expected_message_length - str_truncate_message_length - remaining_byte_truncated_utf8_character; for (index = 0; index < user_message_after_truncated_size; index++) { expected_message[index] = '#'; } strncpy(expected_message + user_message_after_truncated_size, STR_TRUNCATED_MESSAGE, str_truncate_message_length); EXPECT_EQ(DLT_RETURN_USER_BUFFER_FULL, dlt_user_log_write_utf8_string(&contextData, message)); ASSERT_STREQ(expected_message, (char *)(contextData.buffer + package_description_size)); free(message); message = NULL; free(expected_message); expected_message = NULL; EXPECT_EQ(DLT_RETURN_OK, dlt_user_log_write_finish(&contextData)); EXPECT_EQ(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_EQ(DLT_RETURN_OK, dlt_unregister_app()); /* Restore verbose mode */ dlt_verbose_mode(); } /** * Set the DLT_USER_ENV_LOG_MSG_BUF_LEN to 46, send a message which has the length exceed DLT_USER_ENV_LOG_MSG_BUF_LEN * Expectation: dlt_user_log_write_utf8_string() will be returned DLT_RETURN_USER_BUFFER_FULL and * message will be truncated at the middle of utf-8 2 bytes, the rest of this utf-8 character will * be removed completely, after that appended STR_TRUNCATED_MESSAGE at * the end of received message. * Note: dlt_init() will be called after testcase is finished to restore environment for other testcases */ TEST(t_dlt_user_log_write_utf8_string, normal_message_truncated_at_utf8_2bytes_and_reduce_msg_buf_len_by_env_variable) { DltContext context; DltContextData contextData; uint16_t index = 0; uint16_t str_truncate_message_length = 0; uint16_t expected_message_length = 0; uint16_t package_description_size = 0; uint16_t user_message_after_truncated_size = 0; uint16_t remaining_byte_truncated_utf8_character = 0; const char *message = "$$$¢###############################################"; char *expected_message = NULL; /** * Re-initialize the dlt with dlt user buffer size from DLT_USER_ENV_LOG_MSG_BUF_LEN environment variable * to simulate use case the dlt user buffer size only available 4 bytes for store user message. * Note: 46 bytes = package_description_size (6 bytes) + str_truncated_message_length (35 bytes) + 4 bytes user message + 1 byte NULL terminator. */ user_message_after_truncated_size = 4; EXPECT_EQ(DLT_RETURN_OK, dlt_free()); setenv(DLT_USER_ENV_LOG_MSG_BUF_LEN, "46", 1); EXPECT_EQ(DLT_RETURN_OK, dlt_init()); EXPECT_EQ(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_EQ(DLT_RETURN_OK, dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_user_log_write_utf8_string normal_message_truncated_at_utf8_2bytes_and_reduce_msg_buf_len_by_env_variable")); /* Normal values */ EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_start(&context, &contextData, DLT_LOG_DEFAULT)); EXPECT_EQ(DLT_RETURN_USER_BUFFER_FULL, dlt_user_log_write_utf8_string(&contextData, message)); /** * In Verbose Mode: * package_description_size = Type info (32 bits) + Description of data payload of type string (16 bits) */ package_description_size = sizeof(uint32_t) + sizeof(uint16_t); str_truncate_message_length = strlen(STR_TRUNCATED_MESSAGE) + 1; /* Create the expected message */ remaining_byte_truncated_utf8_character = 1; expected_message_length = user_message_after_truncated_size - remaining_byte_truncated_utf8_character + str_truncate_message_length; expected_message = (char *)(malloc(expected_message_length)); ASSERT_TRUE(expected_message != NULL) << "Failed to allocate memory."; user_message_after_truncated_size -= remaining_byte_truncated_utf8_character; for (index = 0; index < user_message_after_truncated_size; index++) { expected_message[index] = '$'; } strncpy(expected_message + user_message_after_truncated_size, STR_TRUNCATED_MESSAGE, str_truncate_message_length); ASSERT_STREQ(expected_message, (char *)(contextData.buffer + package_description_size)); EXPECT_EQ(DLT_RETURN_OK, dlt_user_log_write_finish(&contextData)); EXPECT_EQ(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_EQ(DLT_RETURN_OK, dlt_unregister_app()); /* Restore the dlt with dlt user buffer size as default */ EXPECT_EQ(DLT_RETURN_OK, dlt_free()); unsetenv(DLT_USER_ENV_LOG_MSG_BUF_LEN); EXPECT_EQ(DLT_RETURN_OK, dlt_init()); } /** * In Non-Verbose Mode, send a message which has the length exceed DLT_USER_ENV_LOG_MSG_BUF_LEN * Expectation: dlt_user_log_write_utf8_string() will be returned DLT_RETURN_USER_BUFFER_FULL and * message will be truncated at the middle of utf-8 3 bytes, the rest of this utf-8 character will * be removed completely, after that appended STR_TRUNCATED_MESSAGE at * the end of received message. */ TEST(t_dlt_user_log_write_utf8_string, normal_message_truncated_at_utf8_3bytes_in_verbose_mode) { DltContext context; DltContextData contextData; uint16_t index = 0; uint16_t package_description_size = 0; uint16_t user_message_after_truncated_size = 0; uint16_t send_message_length = 0; uint16_t str_truncate_message_length = 0; uint16_t expected_message_length = 0; uint16_t remaining_byte_truncated_utf8_character = 0; const char *utf8_3byte_character = "€"; char *message = NULL; char *expected_message = NULL; EXPECT_EQ(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_EQ(DLT_RETURN_OK, dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_user_log_write_utf8_string normal_message_truncated_at_utf8_3bytes_in_verbose_mode")); /* normal values */ EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_start(&context, &contextData, DLT_LOG_DEFAULT)); /* Create the message contain the '€' (3 bytes utf-8 character) and last byte of this character is exceed buffer length */ send_message_length = DLT_USER_BUF_MAX_SIZE + 10; message = (char *)(malloc(send_message_length)); ASSERT_TRUE(message != NULL) << "Failed to allocate memory."; for (index = 0; index < send_message_length; index++) { message[index] = '#'; } message[send_message_length - 1] = '\0'; /** * In Verbose Mode: * package_description_size = Type info (32 bits) + Description of data payload of type string (16 bits) */ package_description_size = sizeof(uint32_t) + sizeof(uint16_t); /** * Fill the "€" character at the position which the last byte of this character is exceed the buffer length and * expectation is it will be truncated 2 more bytes in the character sequence */ str_truncate_message_length = strlen(STR_TRUNCATED_MESSAGE) + 1; remaining_byte_truncated_utf8_character = 2; index = (DLT_USER_BUF_MAX_SIZE - package_description_size - str_truncate_message_length - remaining_byte_truncated_utf8_character); strncpy(message + index, utf8_3byte_character, strlen(utf8_3byte_character)); /* Create the expected message */ expected_message_length = DLT_USER_BUF_MAX_SIZE - package_description_size; expected_message = (char *)(malloc(expected_message_length)); ASSERT_TRUE(expected_message != NULL) << "Failed to allocate memory."; user_message_after_truncated_size = expected_message_length - str_truncate_message_length - remaining_byte_truncated_utf8_character; for (index = 0; index < user_message_after_truncated_size; index++) { expected_message[index] = '#'; } strncpy(expected_message + user_message_after_truncated_size, STR_TRUNCATED_MESSAGE, str_truncate_message_length); EXPECT_EQ(DLT_RETURN_USER_BUFFER_FULL, dlt_user_log_write_utf8_string(&contextData, message)); ASSERT_STREQ(expected_message, (char *)(contextData.buffer + package_description_size)); free(message); message = NULL; free(expected_message); expected_message = NULL; EXPECT_EQ(DLT_RETURN_OK, dlt_user_log_write_finish(&contextData)); EXPECT_EQ(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_EQ(DLT_RETURN_OK, dlt_unregister_app()); } /** * In Non-Verbose Mode, send a message which has the length exceed DLT_USER_ENV_LOG_MSG_BUF_LEN * Expectation: dlt_user_log_write_utf8_string() will be returned DLT_RETURN_USER_BUFFER_FULL and * message will be truncated at the middle of utf-8 3 bytes, the rest of this utf-8 character will * be removed completely, after that appended STR_TRUNCATED_MESSAGE at * the end of received message. */ TEST(t_dlt_user_log_write_utf8_string, normal_message_truncated_at_utf8_3bytes_in_non_verbose_mode) { DltContext context; DltContextData contextData; uint16_t index = 0; uint16_t package_description_size = 0; uint16_t user_message_after_truncated_size = 0; uint16_t send_message_length = 0; uint16_t str_truncate_message_length = 0; uint16_t expected_message_length = 0; uint16_t remaining_byte_truncated_utf8_character = 0; const char *utf8_3byte_character = "€"; char *message = NULL; char *expected_message = NULL; dlt_nonverbose_mode(); EXPECT_EQ(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_EQ(DLT_RETURN_OK, dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_user_log_write_utf8_string normal_message_truncated_at_utf8_3bytes_in_non_verbose_mode")); /* Normal values */ EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_start(&context, &contextData, DLT_LOG_DEFAULT)); /* Create the message contain the '€' (3 bytes utf-8 character) and last byte of this character is exceed buffer length */ send_message_length = DLT_USER_BUF_MAX_SIZE + 10; message = (char *)(malloc(send_message_length)); ASSERT_TRUE(message != NULL) << "Failed to allocate memory."; for (index = 0; index < send_message_length; index++) { message[index] = '#'; } message[send_message_length - 1] = '\0'; /** * In Verbose Mode: * package_description_size = Type info (32 bits) + Description of data payload of type string (16 bits) */ package_description_size = sizeof(uint32_t) + sizeof(uint16_t); /** * Fill the "€" character at the position which the last byte of this character is exceed the buffer length and * expectation is it will be truncated 2 more bytes in the character sequence */ str_truncate_message_length = strlen(STR_TRUNCATED_MESSAGE) + 1; remaining_byte_truncated_utf8_character = 2; index = (DLT_USER_BUF_MAX_SIZE - package_description_size - str_truncate_message_length - remaining_byte_truncated_utf8_character); strncpy(message + index, utf8_3byte_character, strlen(utf8_3byte_character)); /* Create the expected message */ expected_message_length = DLT_USER_BUF_MAX_SIZE - package_description_size; expected_message = (char *)(malloc(expected_message_length)); ASSERT_TRUE(expected_message != NULL) << "Failed to allocate memory."; user_message_after_truncated_size = expected_message_length - str_truncate_message_length - remaining_byte_truncated_utf8_character; for (index = 0; index < user_message_after_truncated_size; index++) { expected_message[index] = '#'; } strncpy(expected_message + user_message_after_truncated_size, STR_TRUNCATED_MESSAGE, str_truncate_message_length); EXPECT_EQ(DLT_RETURN_USER_BUFFER_FULL, dlt_user_log_write_utf8_string(&contextData, message)); ASSERT_STREQ(expected_message, (char *)(contextData.buffer + package_description_size)); free(message); message = NULL; free(expected_message); expected_message = NULL; EXPECT_EQ(DLT_RETURN_OK, dlt_user_log_write_finish(&contextData)); EXPECT_EQ(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_EQ(DLT_RETURN_OK, dlt_unregister_app()); /* Restore verbose mode */ dlt_verbose_mode(); } /** * Set the DLT_USER_ENV_LOG_MSG_BUF_LEN to 46, send a message which has the length exceed DLT_USER_ENV_LOG_MSG_BUF_LEN * Expectation: dlt_user_log_write_utf8_string() will be returned DLT_RETURN_USER_BUFFER_FULL and * message will be truncated at the middle of utf-8 3 bytes, the rest of this utf-8 character will * be removed completely, after that appended STR_TRUNCATED_MESSAGE at * the end of received message. * Note: dlt_init() will be called after testcase is finished to restore environment for other testcases */ TEST(t_dlt_user_log_write_utf8_string, normal_message_truncated_at_utf8_3bytes_and_reduce_msg_buf_len_by_env_variable) { DltContext context; DltContextData contextData; uint16_t index = 0; uint16_t str_truncate_message_length = 0; uint16_t expected_message_length = 0; uint16_t package_description_size = 0; uint16_t user_message_after_truncated_size = 0; uint16_t remaining_byte_truncated_utf8_character = 0; const char *message = "$$€###############################################"; char *expected_message = NULL; /** * Re-initialize the dlt with dlt user buffer size from DLT_USER_ENV_LOG_MSG_BUF_LEN environment variable * to simulate use case the dlt user buffer size only available 4 bytes for store user message. * Note: 46 bytes = package_description_size (6 bytes) + str_truncated_message_length (35 bytes) + 4 bytes user message + 1 byte NULL terminator. */ user_message_after_truncated_size = 4; EXPECT_EQ(DLT_RETURN_OK, dlt_free()); setenv(DLT_USER_ENV_LOG_MSG_BUF_LEN, "46", 1); EXPECT_EQ(DLT_RETURN_OK, dlt_init()); EXPECT_EQ(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_EQ(DLT_RETURN_OK, dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_user_log_write_utf8_string normal_message_truncated_at_utf8_3bytes_and_reduce_msg_buf_len_by_env_variable")); /* Normal values */ EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_start(&context, &contextData, DLT_LOG_DEFAULT)); EXPECT_EQ(DLT_RETURN_USER_BUFFER_FULL, dlt_user_log_write_utf8_string(&contextData, message)); /** * In Verbose Mode: * package_description_size = Type info (32 bits) + Description of data payload of type string (16 bits) */ package_description_size = sizeof(uint32_t) + sizeof(uint16_t); str_truncate_message_length = strlen(STR_TRUNCATED_MESSAGE) + 1; /* Create the expected message */ remaining_byte_truncated_utf8_character = 2; expected_message_length = user_message_after_truncated_size - remaining_byte_truncated_utf8_character + str_truncate_message_length; expected_message = (char *)(malloc(expected_message_length)); ASSERT_TRUE(expected_message != NULL) << "Failed to allocate memory."; user_message_after_truncated_size -= remaining_byte_truncated_utf8_character; for (index = 0; index < user_message_after_truncated_size; index++) { expected_message[index] = '$'; } strncpy(expected_message + user_message_after_truncated_size, STR_TRUNCATED_MESSAGE, str_truncate_message_length); ASSERT_STREQ(expected_message, (char *)(contextData.buffer + package_description_size)); EXPECT_EQ(DLT_RETURN_OK, dlt_user_log_write_finish(&contextData)); EXPECT_EQ(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_EQ(DLT_RETURN_OK, dlt_unregister_app()); /* Restore the dlt with dlt user buffer size as default */ EXPECT_EQ(DLT_RETURN_OK, dlt_free()); unsetenv(DLT_USER_ENV_LOG_MSG_BUF_LEN); EXPECT_EQ(DLT_RETURN_OK, dlt_init()); } /** * In Non-Verbose Mode, send a message which has the length exceed DLT_USER_ENV_LOG_MSG_BUF_LEN * Expectation: dlt_user_log_write_utf8_string() will be returned DLT_RETURN_USER_BUFFER_FULL and * message will be truncated at the middle of utf-8 4 bytes, the rest of this utf-8 character will * be removed completely, after that appended STR_TRUNCATED_MESSAGE at * the end of received message. */ TEST(t_dlt_user_log_write_utf8_string, normal_message_truncated_at_utf8_4bytes_in_verbose_mode) { DltContext context; DltContextData contextData; uint16_t index = 0; uint16_t package_description_size = 0; uint16_t user_message_after_truncated_size = 0; uint16_t send_message_length = 0; uint16_t str_truncate_message_length = 0; uint16_t expected_message_length = 0; uint16_t remaining_byte_truncated_utf8_character = 0; const char *utf8_4byte_character = "𐍈"; char *message = NULL; char *expected_message = NULL; EXPECT_EQ(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_EQ(DLT_RETURN_OK, dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_user_log_write_utf8_string normal_message_truncated_at_utf8_4bytes_in_verbose_mode")); /* Normal values */ EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_start(&context, &contextData, DLT_LOG_DEFAULT)); /* Create the message contain the '𐍈' (4 bytes utf-8 character) and last byte of this character is exceed buffer length */ send_message_length = DLT_USER_BUF_MAX_SIZE + 10; message = (char *)(malloc(send_message_length)); ASSERT_TRUE(message != NULL) << "Failed to allocate memory."; for (index = 0; index < send_message_length; index++) { message[index] = '#'; } message[send_message_length - 1] = '\0'; /** * In Verbose Mode: * package_description_size = Type info (32 bits) + Description of data payload of type string (16 bits) */ package_description_size = sizeof(uint32_t) + sizeof(uint16_t); /** * Fill the "𐍈" character at the position which the last byte of this character is exceed the buffer length and * expectation is it will be truncated 3 more bytes in the character sequence */ str_truncate_message_length = strlen(STR_TRUNCATED_MESSAGE) + 1; remaining_byte_truncated_utf8_character = 3; index = (DLT_USER_BUF_MAX_SIZE - package_description_size - str_truncate_message_length - remaining_byte_truncated_utf8_character); strncpy(message + index, utf8_4byte_character, strlen(utf8_4byte_character)); /* Create the expected message */ expected_message_length = DLT_USER_BUF_MAX_SIZE - package_description_size; expected_message = (char *)(malloc(expected_message_length)); ASSERT_TRUE(expected_message != NULL) << "Failed to allocate memory."; user_message_after_truncated_size = expected_message_length - str_truncate_message_length - remaining_byte_truncated_utf8_character; for (index = 0; index < user_message_after_truncated_size; index++) { expected_message[index] = '#'; } strncpy(expected_message + user_message_after_truncated_size, STR_TRUNCATED_MESSAGE, str_truncate_message_length); EXPECT_EQ(DLT_RETURN_USER_BUFFER_FULL, dlt_user_log_write_utf8_string(&contextData, message)); ASSERT_STREQ(expected_message, (char *)(contextData.buffer + package_description_size)); free(message); message = NULL; free(expected_message); expected_message = NULL; EXPECT_EQ(DLT_RETURN_OK, dlt_user_log_write_finish(&contextData)); EXPECT_EQ(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_EQ(DLT_RETURN_OK, dlt_unregister_app()); } /** * In Non-Verbose Mode, send a message which has the length exceed DLT_USER_ENV_LOG_MSG_BUF_LEN * Expectation: dlt_user_log_write_utf8_string() will be returned DLT_RETURN_USER_BUFFER_FULL and * message will be truncated at the middle of utf-8 4 bytes, the rest of this utf-8 character will * be removed completely, after that appended STR_TRUNCATED_MESSAGE at * the end of received message. */ TEST(t_dlt_user_log_write_utf8_string, normal_message_truncated_at_utf8_4bytes_in_non_verbose_mode) { DltContext context; DltContextData contextData; uint16_t index = 0; uint16_t package_description_size = 0; uint16_t user_message_after_truncated_size = 0; uint16_t send_message_length = 0; uint16_t str_truncate_message_length = 0; uint16_t expected_message_length = 0; uint16_t remaining_byte_truncated_utf8_character = 0; const char *utf8_4byte_character = "𐍈"; char *message = NULL; char *expected_message = NULL; dlt_nonverbose_mode(); EXPECT_EQ(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_EQ(DLT_RETURN_OK, dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_user_log_write_utf8_string normal_message_truncated_at_utf8_4bytes_in_non_verbose_mode")); /* Normal values */ EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_start(&context, &contextData, DLT_LOG_DEFAULT)); /* Create the message contain the '𐍈' (4 bytes utf-8 character) and last byte of this character is exceed buffer length */ send_message_length = DLT_USER_BUF_MAX_SIZE + 10; message = (char *)(malloc(send_message_length)); ASSERT_TRUE(message != NULL) << "Failed to allocate memory."; for (index = 0; index < send_message_length; index++) { message[index] = '#'; } message[send_message_length - 1] = '\0'; /** * In Non-Verbose Mode: * package_description_size = Message ID (32 bits) + Description of data payload of type string (16 bits) */ package_description_size = sizeof(uint32_t) + sizeof(uint16_t); /** * Fill the "𐍈" character at the position which the last byte of this character is exceed the buffer length and * expectation is it will be truncated 3 more bytes in the character sequence */ str_truncate_message_length = strlen(STR_TRUNCATED_MESSAGE) + 1; remaining_byte_truncated_utf8_character = 3; index = (DLT_USER_BUF_MAX_SIZE - package_description_size - str_truncate_message_length - remaining_byte_truncated_utf8_character); strncpy(message + index, utf8_4byte_character, strlen(utf8_4byte_character)); /* Create the expected message */ expected_message_length = DLT_USER_BUF_MAX_SIZE - package_description_size; expected_message = (char *)(malloc(expected_message_length)); ASSERT_TRUE(expected_message != NULL) << "Failed to allocate memory."; user_message_after_truncated_size = expected_message_length - str_truncate_message_length - remaining_byte_truncated_utf8_character; for (index = 0; index < user_message_after_truncated_size; index++) { expected_message[index] = '#'; } strncpy(expected_message + user_message_after_truncated_size, STR_TRUNCATED_MESSAGE, str_truncate_message_length); EXPECT_EQ(DLT_RETURN_USER_BUFFER_FULL, dlt_user_log_write_utf8_string(&contextData, message)); ASSERT_STREQ(expected_message, (char *)(contextData.buffer + package_description_size)); free(message); message = NULL; free(expected_message); expected_message = NULL; EXPECT_EQ(DLT_RETURN_OK, dlt_user_log_write_finish(&contextData)); EXPECT_EQ(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_EQ(DLT_RETURN_OK, dlt_unregister_app()); /* Restore verbose mode */ dlt_verbose_mode(); } /** * Set the DLT_USER_ENV_LOG_MSG_BUF_LEN to 46, send a message which has the length exceed DLT_USER_ENV_LOG_MSG_BUF_LEN * Expectation: dlt_user_log_write_utf8_string() will be returned DLT_RETURN_USER_BUFFER_FULL and * message will be truncated at the middle of utf-8 4 bytes, the rest of this utf-8 character will * be removed completely, after that appended STR_TRUNCATED_MESSAGE at * the end of received message. * Note: dlt_init() will be called after testcase is finished to restore environment for other testcases */ TEST(t_dlt_user_log_write_utf8_string, normal_message_truncated_at_utf8_4bytes_and_reduce_msg_buf_len_by_env_variable) { DltContext context; DltContextData contextData; uint16_t str_truncate_message_length = 0; uint16_t expected_message_length = 0; uint16_t package_description_size = 0; uint16_t user_message_after_truncated_size = 0; uint16_t remaining_byte_truncated_utf8_character = 0; const char *message = "$𐍈###############################################"; char *expected_message = NULL; /** * Re-initialize the dlt with dlt user buffer size from DLT_USER_ENV_LOG_MSG_BUF_LEN environment variable * to simulate use case the dlt user buffer size only available 4 bytes for store user message. * Note: 46 bytes = package_description_size (6 bytes) + str_truncated_message_length (35 bytes) + 4 bytes user message + 1 byte NULL terminator. */ user_message_after_truncated_size = 4; EXPECT_EQ(DLT_RETURN_OK, dlt_free()); setenv(DLT_USER_ENV_LOG_MSG_BUF_LEN, "46", 1); EXPECT_EQ(DLT_RETURN_OK, dlt_init()); EXPECT_EQ(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_EQ(DLT_RETURN_OK, dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_user_log_write_utf8_string normal_message_truncated_at_utf8_4bytes_and_reduce_msg_buf_len_by_env_variable")); /* Normal values */ EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_start(&context, &contextData, DLT_LOG_DEFAULT)); EXPECT_EQ(DLT_RETURN_USER_BUFFER_FULL, dlt_user_log_write_utf8_string(&contextData, message)); /** * In Verbose Mode: * package_description_size = Type info (32 bits) + Description of data payload of type string (16 bits) */ package_description_size = sizeof(uint32_t) + sizeof(uint16_t); str_truncate_message_length = strlen(STR_TRUNCATED_MESSAGE) + 1; /* Create the expected message */ remaining_byte_truncated_utf8_character = 3; expected_message_length = user_message_after_truncated_size - remaining_byte_truncated_utf8_character + str_truncate_message_length; expected_message = (char *)(malloc(expected_message_length)); ASSERT_TRUE(expected_message != NULL) << "Failed to allocate memory."; expected_message[0] = '$'; strncpy(expected_message + 1, STR_TRUNCATED_MESSAGE, str_truncate_message_length); ASSERT_STREQ(expected_message, (char *)(contextData.buffer + package_description_size)); EXPECT_EQ(DLT_RETURN_OK, dlt_user_log_write_finish(&contextData)); EXPECT_EQ(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_EQ(DLT_RETURN_OK, dlt_unregister_app()); /* Restore the dlt with dlt user buffer size as default */ EXPECT_EQ(DLT_RETURN_OK, dlt_free()); unsetenv(DLT_USER_ENV_LOG_MSG_BUF_LEN); EXPECT_EQ(DLT_RETURN_OK, dlt_init()); } TEST(t_dlt_user_log_write_utf8_string, nullpointer) { DltContext context; DltContextData contextData; EXPECT_LE(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_LE(DLT_RETURN_OK, dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_user_log_write_utf8_string nullpointer")); /* NULL */ const char *text1 = "test1"; EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_start(&context, &contextData, DLT_LOG_DEFAULT)); EXPECT_GE(DLT_RETURN_ERROR, dlt_user_log_write_utf8_string(NULL, text1)); EXPECT_GE(DLT_RETURN_ERROR, dlt_user_log_write_utf8_string(NULL, NULL)); EXPECT_GE(DLT_RETURN_ERROR, dlt_user_log_write_utf8_string(&contextData, NULL)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_finish(&contextData)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_app()); } /*/////////////////////////////////////// */ /* t_dlt_user_log_write_raw */ TEST(t_dlt_user_log_write_raw, normal) { DltContext context; DltContextData contextData; EXPECT_LE(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_LE(DLT_RETURN_OK, dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_user_log_write_raw normal")); /* normal values */ EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_start(&context, &contextData, DLT_LOG_DEFAULT)); char text1[6] = "test1"; EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_raw(&contextData, text1, 6)); char text2[1] = ""; EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_raw(&contextData, text2, 0)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_finish(&contextData)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_app()); } TEST(t_dlt_user_log_write_raw, nullpointer) { DltContext context; DltContextData contextData; EXPECT_LE(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_LE(DLT_RETURN_OK, dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_user_log_write_raw nullpointer")); /* NULL */ char text1[6] = "test1"; EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_start(&context, &contextData, DLT_LOG_DEFAULT)); EXPECT_GE(DLT_RETURN_ERROR, dlt_user_log_write_raw(NULL, text1, 6)); EXPECT_GE(DLT_RETURN_ERROR, dlt_user_log_write_raw(NULL, NULL, 0)); EXPECT_GE(DLT_RETURN_OK, dlt_user_log_write_raw(&contextData, NULL, 0)); EXPECT_GE(DLT_RETURN_ERROR, dlt_user_log_write_raw(&contextData, NULL, 1)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_finish(&contextData)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_app()); } /*/////////////////////////////////////// */ /* t_dlt_user_log_write_raw_formatted */ TEST(t_dlt_user_log_write_raw_formatted, normal) { DltContext context; DltContextData contextData; EXPECT_LE(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_LE(DLT_RETURN_OK, dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_user_log_write_raw_formatted normal")); /* normal values */ EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_start(&context, &contextData, DLT_LOG_DEFAULT)); char text1[6] = "test1"; EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_raw_formatted(&contextData, text1, 6, DLT_FORMAT_DEFAULT)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_raw_formatted(&contextData, text1, 6, DLT_FORMAT_HEX8)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_raw_formatted(&contextData, text1, 6, DLT_FORMAT_HEX16)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_raw_formatted(&contextData, text1, 6, DLT_FORMAT_HEX32)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_raw_formatted(&contextData, text1, 6, DLT_FORMAT_HEX64)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_raw_formatted(&contextData, text1, 6, DLT_FORMAT_BIN8)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_raw_formatted(&contextData, text1, 6, DLT_FORMAT_BIN16)); char text2[1] = ""; EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_raw_formatted(&contextData, text2, 0, DLT_FORMAT_DEFAULT)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_raw_formatted(&contextData, text2, 0, DLT_FORMAT_HEX8)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_raw_formatted(&contextData, text2, 0, DLT_FORMAT_HEX16)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_raw_formatted(&contextData, text2, 0, DLT_FORMAT_HEX32)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_raw_formatted(&contextData, text2, 0, DLT_FORMAT_HEX64)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_raw_formatted(&contextData, text2, 0, DLT_FORMAT_BIN8)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_raw_formatted(&contextData, text2, 0, DLT_FORMAT_BIN16)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_finish(&contextData)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_app()); } TEST(t_dlt_user_log_write_raw_formatted, abnormal) { DltContext context; DltContextData contextData; uint16_t length = DLT_USER_BUF_MAX_SIZE + 10; char buffer[length]; memset(buffer, '\000', length); for (int i = 0; i < length; i++) buffer[i] = 'X'; EXPECT_EQ(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_EQ(DLT_RETURN_OK, dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_user_log_write_raw_formatted abnormal")); EXPECT_EQ(DLT_RETURN_USER_BUFFER_FULL, dlt_user_log_write_raw_formatted(&contextData, buffer, length, DLT_FORMAT_DEFAULT)); /* undefined values for DltFormatType */ /* shouldn't it return -1? */ /* char text1[6] = "test1"; */ /* EXPECT_GE(DLT_RETURN_ERROR,dlt_user_log_write_raw_formatted(&contextData, text1, 6, (DltFormatType)-100)); */ /* EXPECT_GE(DLT_RETURN_ERROR,dlt_user_log_write_raw_formatted(&contextData, text1, 6, (DltFormatType)-10)); */ /* EXPECT_GE(DLT_RETURN_ERROR,dlt_user_log_write_raw_formatted(&contextData, text1, 6, (DltFormatType)10)); */ /* EXPECT_GE(DLT_RETURN_ERROR,dlt_user_log_write_raw_formatted(&contextData, text1, 6, (DltFormatType)100)); */ EXPECT_EQ(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_EQ(DLT_RETURN_OK, dlt_unregister_app()); } TEST(t_dlt_user_log_write_raw_formatted, nullpointer) { DltContext context; DltContextData contextData; EXPECT_LE(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_LE(DLT_RETURN_OK, dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_user_log_write_raw_formatted nullpointer")); /* NULL */ char text1[6] = "test1"; EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_start(&context, &contextData, DLT_LOG_DEFAULT)); EXPECT_GE(DLT_RETURN_ERROR, dlt_user_log_write_raw_formatted(NULL, text1, 6, DLT_FORMAT_DEFAULT)); EXPECT_GE(DLT_RETURN_ERROR, dlt_user_log_write_raw_formatted(NULL, NULL, 0, DLT_FORMAT_DEFAULT)); EXPECT_GE(DLT_RETURN_OK, dlt_user_log_write_raw_formatted(&contextData, NULL, 0, DLT_FORMAT_DEFAULT)); EXPECT_GE(DLT_RETURN_ERROR, dlt_user_log_write_raw_formatted(&contextData, NULL, 1, DLT_FORMAT_DEFAULT)); EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_finish(&contextData)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_app()); } /* * int dlt_log_string(DltContext *handle,DltLogLevelType loglevel, const char *text); * int dlt_log_string_int(DltContext *handle,DltLogLevelType loglevel, const char *text, int data); * int dlt_log_string_uint(DltContext *handle,DltLogLevelType loglevel, const char *text, unsigned int data); * int dlt_log_int(DltContext *handle,DltLogLevelType loglevel, int data); * int dlt_log_uint(DltContext *handle,DltLogLevelType loglevel, unsigned int data); * int dlt_log_raw(DltContext *handle,DltLogLevelType loglevel, void *data,uint16_t length); * int dlt_log_marker(); */ /*/////////////////////////////////////// */ /* t_dlt_log_string */ TEST(t_dlt_log_string, normal) { DltContext context; EXPECT_LE(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_LE(DLT_RETURN_OK, dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_log_string normal")); /* normal values */ const char text1[6] = "test1"; EXPECT_LE(DLT_RETURN_OK, dlt_log_string(&context, DLT_LOG_DEFAULT, text1)); EXPECT_LE(DLT_RETURN_OK, dlt_log_string(&context, DLT_LOG_OFF, text1)); EXPECT_LE(DLT_RETURN_OK, dlt_log_string(&context, DLT_LOG_FATAL, text1)); EXPECT_LE(DLT_RETURN_OK, dlt_log_string(&context, DLT_LOG_ERROR, text1)); EXPECT_LE(DLT_RETURN_OK, dlt_log_string(&context, DLT_LOG_WARN, text1)); EXPECT_LE(DLT_RETURN_OK, dlt_log_string(&context, DLT_LOG_INFO, text1)); EXPECT_LE(DLT_RETURN_OK, dlt_log_string(&context, DLT_LOG_VERBOSE, text1)); const char text2[1] = ""; EXPECT_LE(DLT_RETURN_OK, dlt_log_string(&context, DLT_LOG_DEFAULT, text2)); EXPECT_LE(DLT_RETURN_OK, dlt_log_string(&context, DLT_LOG_OFF, text2)); EXPECT_LE(DLT_RETURN_OK, dlt_log_string(&context, DLT_LOG_FATAL, text2)); EXPECT_LE(DLT_RETURN_OK, dlt_log_string(&context, DLT_LOG_ERROR, text2)); EXPECT_LE(DLT_RETURN_OK, dlt_log_string(&context, DLT_LOG_WARN, text2)); EXPECT_LE(DLT_RETURN_OK, dlt_log_string(&context, DLT_LOG_INFO, text2)); EXPECT_LE(DLT_RETURN_OK, dlt_log_string(&context, DLT_LOG_VERBOSE, text2)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_app()); } TEST(t_dlt_log_string, abnormal) { DltContext context; EXPECT_EQ(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_EQ(DLT_RETURN_OK, dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_log_string abnormal")); uint16_t length = DLT_USER_BUF_MAX_SIZE + 10; char buffer[length]; memset(buffer, '\000', length); for (int i = 0; i < length - 1; i++) buffer[i] = 'X'; EXPECT_EQ(DLT_RETURN_USER_BUFFER_FULL, dlt_log_string(&context, DLT_LOG_INFO, buffer)); /* undefined values for DltLogLevelType */ /* shouldn't it return -1? */ /* TODO: const char text1[6] = "test1"; */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_log_string(&context, (DltLogLevelType)-100, text1)); */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_log_string(&context, (DltLogLevelType)-10, text1)); */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_log_string(&context, (DltLogLevelType)10, text1)); */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_log_string(&context, (DltLogLevelType)100, text1)); */ EXPECT_EQ(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_EQ(DLT_RETURN_OK, dlt_unregister_app()); } TEST(t_dlt_log_string, nullpointer) { DltContext context; EXPECT_LE(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_LE(DLT_RETURN_OK, dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_log_string nullpointer")); /* NULL */ char text1[6] = "test1"; EXPECT_GE(DLT_RETURN_ERROR, dlt_log_string(NULL, DLT_LOG_DEFAULT, text1)); EXPECT_GE(DLT_RETURN_ERROR, dlt_log_string(NULL, DLT_LOG_DEFAULT, NULL)); EXPECT_GE(DLT_RETURN_ERROR, dlt_log_string(&context, DLT_LOG_DEFAULT, NULL)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_app()); } /*/////////////////////////////////////// */ /* t_dlt_log_string_int */ TEST(t_dlt_log_string_int, normal) { DltContext context; EXPECT_LE(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_LE(DLT_RETURN_OK, dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_log_string_int normal")); /* normal values */ const char text1[6] = "test1"; int data = INT_MIN; EXPECT_LE(DLT_RETURN_OK, dlt_log_string_int(&context, DLT_LOG_DEFAULT, text1, data)); EXPECT_LE(DLT_RETURN_OK, dlt_log_string_int(&context, DLT_LOG_OFF, text1, data)); EXPECT_LE(DLT_RETURN_OK, dlt_log_string_int(&context, DLT_LOG_FATAL, text1, data)); EXPECT_LE(DLT_RETURN_OK, dlt_log_string_int(&context, DLT_LOG_ERROR, text1, data)); EXPECT_LE(DLT_RETURN_OK, dlt_log_string_int(&context, DLT_LOG_WARN, text1, data)); EXPECT_LE(DLT_RETURN_OK, dlt_log_string_int(&context, DLT_LOG_INFO, text1, data)); EXPECT_LE(DLT_RETURN_OK, dlt_log_string_int(&context, DLT_LOG_VERBOSE, text1, data)); const char text2[1] = ""; data = 0; EXPECT_LE(DLT_RETURN_OK, dlt_log_string_int(&context, DLT_LOG_DEFAULT, text2, data)); EXPECT_LE(DLT_RETURN_OK, dlt_log_string_int(&context, DLT_LOG_OFF, text2, data)); EXPECT_LE(DLT_RETURN_OK, dlt_log_string_int(&context, DLT_LOG_FATAL, text2, data)); EXPECT_LE(DLT_RETURN_OK, dlt_log_string_int(&context, DLT_LOG_ERROR, text2, data)); EXPECT_LE(DLT_RETURN_OK, dlt_log_string_int(&context, DLT_LOG_WARN, text2, data)); EXPECT_LE(DLT_RETURN_OK, dlt_log_string_int(&context, DLT_LOG_INFO, text2, data)); EXPECT_LE(DLT_RETURN_OK, dlt_log_string_int(&context, DLT_LOG_VERBOSE, text2, data)); data = INT_MAX; EXPECT_LE(DLT_RETURN_OK, dlt_log_string_int(&context, DLT_LOG_DEFAULT, text2, data)); EXPECT_LE(DLT_RETURN_OK, dlt_log_string_int(&context, DLT_LOG_OFF, text2, data)); EXPECT_LE(DLT_RETURN_OK, dlt_log_string_int(&context, DLT_LOG_FATAL, text2, data)); EXPECT_LE(DLT_RETURN_OK, dlt_log_string_int(&context, DLT_LOG_ERROR, text2, data)); EXPECT_LE(DLT_RETURN_OK, dlt_log_string_int(&context, DLT_LOG_WARN, text2, data)); EXPECT_LE(DLT_RETURN_OK, dlt_log_string_int(&context, DLT_LOG_INFO, text2, data)); EXPECT_LE(DLT_RETURN_OK, dlt_log_string_int(&context, DLT_LOG_VERBOSE, text2, data)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_app()); } TEST(t_dlt_log_string_int, abnormal) { DltContext context; EXPECT_EQ(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_EQ(DLT_RETURN_OK, dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_log_string_int abnormal")); uint16_t length = DLT_USER_BUF_MAX_SIZE + 10; char buffer[length]; memset(buffer, '\000', length); for (int i = 0; i < length - 1; i++) buffer[i] = 'X'; EXPECT_EQ(DLT_RETURN_USER_BUFFER_FULL, dlt_log_string_int(&context, DLT_LOG_INFO, buffer, 1)); /* undefined values for DltLogLevelType */ /* shouldn't it return -1? */ /* TODO: const char text1[6] = "test1"; */ /* TODO: int data = 1; */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_log_string_int(&context, (DltLogLevelType)-100, text1, data)); */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_log_string_int(&context, (DltLogLevelType)-10, text1, data)); */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_log_string_int(&context, (DltLogLevelType)10, text1, data)); */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_log_string_int(&context, (DltLogLevelType)100, text1, data)); */ EXPECT_EQ(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_EQ(DLT_RETURN_OK, dlt_unregister_app()); } TEST(t_dlt_log_string_int, nullpointer) { DltContext context; EXPECT_LE(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_LE(DLT_RETURN_OK, dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_log_string_int nullpointer")); /* NULL */ char text1[6] = "test1"; int data = 0; EXPECT_GE(DLT_RETURN_ERROR, dlt_log_string_int(NULL, DLT_LOG_DEFAULT, text1, data)); EXPECT_GE(DLT_RETURN_ERROR, dlt_log_string_int(NULL, DLT_LOG_DEFAULT, NULL, data)); EXPECT_GE(DLT_RETURN_ERROR, dlt_log_string_int(&context, DLT_LOG_DEFAULT, NULL, data)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_app()); } /*/////////////////////////////////////// */ /* t_dlt_log_string_uint */ TEST(t_dlt_log_string_uint, normal) { DltContext context; EXPECT_LE(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_LE(DLT_RETURN_OK, dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_log_string_uint normal")); /* normal values */ const char text1[6] = "test1"; unsigned int data = UINT_MIN; EXPECT_LE(DLT_RETURN_OK, dlt_log_string_uint(&context, DLT_LOG_DEFAULT, text1, data)); EXPECT_LE(DLT_RETURN_OK, dlt_log_string_uint(&context, DLT_LOG_OFF, text1, data)); EXPECT_LE(DLT_RETURN_OK, dlt_log_string_uint(&context, DLT_LOG_FATAL, text1, data)); EXPECT_LE(DLT_RETURN_OK, dlt_log_string_uint(&context, DLT_LOG_ERROR, text1, data)); EXPECT_LE(DLT_RETURN_OK, dlt_log_string_uint(&context, DLT_LOG_WARN, text1, data)); EXPECT_LE(DLT_RETURN_OK, dlt_log_string_uint(&context, DLT_LOG_INFO, text1, data)); EXPECT_LE(DLT_RETURN_OK, dlt_log_string_uint(&context, DLT_LOG_VERBOSE, text1, data)); const char text2[1] = ""; data = 0; EXPECT_LE(DLT_RETURN_OK, dlt_log_string_uint(&context, DLT_LOG_DEFAULT, text2, data)); EXPECT_LE(DLT_RETURN_OK, dlt_log_string_uint(&context, DLT_LOG_OFF, text2, data)); EXPECT_LE(DLT_RETURN_OK, dlt_log_string_uint(&context, DLT_LOG_FATAL, text2, data)); EXPECT_LE(DLT_RETURN_OK, dlt_log_string_uint(&context, DLT_LOG_ERROR, text2, data)); EXPECT_LE(DLT_RETURN_OK, dlt_log_string_uint(&context, DLT_LOG_WARN, text2, data)); EXPECT_LE(DLT_RETURN_OK, dlt_log_string_uint(&context, DLT_LOG_INFO, text2, data)); EXPECT_LE(DLT_RETURN_OK, dlt_log_string_uint(&context, DLT_LOG_VERBOSE, text2, data)); data = UINT_MAX; EXPECT_LE(DLT_RETURN_OK, dlt_log_string_uint(&context, DLT_LOG_DEFAULT, text2, data)); EXPECT_LE(DLT_RETURN_OK, dlt_log_string_uint(&context, DLT_LOG_OFF, text2, data)); EXPECT_LE(DLT_RETURN_OK, dlt_log_string_uint(&context, DLT_LOG_FATAL, text2, data)); EXPECT_LE(DLT_RETURN_OK, dlt_log_string_uint(&context, DLT_LOG_ERROR, text2, data)); EXPECT_LE(DLT_RETURN_OK, dlt_log_string_uint(&context, DLT_LOG_WARN, text2, data)); EXPECT_LE(DLT_RETURN_OK, dlt_log_string_uint(&context, DLT_LOG_INFO, text2, data)); EXPECT_LE(DLT_RETURN_OK, dlt_log_string_uint(&context, DLT_LOG_VERBOSE, text2, data)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_app()); } TEST(t_dlt_log_string_uint, abnormal) { DltContext context; EXPECT_EQ(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_EQ(DLT_RETURN_OK, dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_log_string_uint abnormal")); uint16_t length = DLT_USER_BUF_MAX_SIZE + 10; char buffer[length]; memset(buffer, '\000', DLT_USER_BUF_MAX_SIZE + 10); for (int i = 0; i < length - 1; i++) buffer[i] = 'X'; EXPECT_EQ(DLT_RETURN_USER_BUFFER_FULL, dlt_log_string_uint(&context, DLT_LOG_INFO, buffer, 1)); /* undefined values for DltLogLevelType */ /* shouldn't it return -1? */ /* TODO: const char text1[6] = "test1"; */ /* TODO: unsigned int data = 1; */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_log_string_uint(&context, (DltLogLevelType)-100, text1, data)); */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_log_string_uint(&context, (DltLogLevelType)-10, text1, data)); */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_log_string_uint(&context, (DltLogLevelType)10, text1, data)); */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_log_string_uint(&context, (DltLogLevelType)100, text1, data)); */ EXPECT_EQ(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_EQ(DLT_RETURN_OK, dlt_unregister_app()); } TEST(t_dlt_log_string_uint, nullpointer) { DltContext context; EXPECT_LE(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_LE(DLT_RETURN_OK, dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_log_string_uint nullpointer")); /* NULL */ char text1[6] = "test1"; unsigned int data = 0; EXPECT_GE(DLT_RETURN_ERROR, dlt_log_string_uint(NULL, DLT_LOG_DEFAULT, text1, data)); EXPECT_GE(DLT_RETURN_ERROR, dlt_log_string_uint(NULL, DLT_LOG_DEFAULT, NULL, data)); EXPECT_GE(DLT_RETURN_ERROR, dlt_log_string_uint(&context, DLT_LOG_DEFAULT, NULL, data)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_app()); } /*/////////////////////////////////////// */ /* t_dlt_log_int */ TEST(t_dlt_log_int, normal) { DltContext context; EXPECT_LE(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_LE(DLT_RETURN_OK, dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_log_int normal")); /* normal values */ int data = INT_MIN; EXPECT_LE(DLT_RETURN_OK, dlt_log_int(&context, DLT_LOG_DEFAULT, data)); EXPECT_LE(DLT_RETURN_OK, dlt_log_int(&context, DLT_LOG_OFF, data)); EXPECT_LE(DLT_RETURN_OK, dlt_log_int(&context, DLT_LOG_FATAL, data)); EXPECT_LE(DLT_RETURN_OK, dlt_log_int(&context, DLT_LOG_ERROR, data)); EXPECT_LE(DLT_RETURN_OK, dlt_log_int(&context, DLT_LOG_WARN, data)); EXPECT_LE(DLT_RETURN_OK, dlt_log_int(&context, DLT_LOG_INFO, data)); EXPECT_LE(DLT_RETURN_OK, dlt_log_int(&context, DLT_LOG_VERBOSE, data)); data = 0; EXPECT_LE(DLT_RETURN_OK, dlt_log_int(&context, DLT_LOG_DEFAULT, data)); EXPECT_LE(DLT_RETURN_OK, dlt_log_int(&context, DLT_LOG_OFF, data)); EXPECT_LE(DLT_RETURN_OK, dlt_log_int(&context, DLT_LOG_FATAL, data)); EXPECT_LE(DLT_RETURN_OK, dlt_log_int(&context, DLT_LOG_ERROR, data)); EXPECT_LE(DLT_RETURN_OK, dlt_log_int(&context, DLT_LOG_WARN, data)); EXPECT_LE(DLT_RETURN_OK, dlt_log_int(&context, DLT_LOG_INFO, data)); EXPECT_LE(DLT_RETURN_OK, dlt_log_int(&context, DLT_LOG_VERBOSE, data)); data = INT_MAX; EXPECT_LE(DLT_RETURN_OK, dlt_log_int(&context, DLT_LOG_DEFAULT, data)); EXPECT_LE(DLT_RETURN_OK, dlt_log_int(&context, DLT_LOG_OFF, data)); EXPECT_LE(DLT_RETURN_OK, dlt_log_int(&context, DLT_LOG_FATAL, data)); EXPECT_LE(DLT_RETURN_OK, dlt_log_int(&context, DLT_LOG_ERROR, data)); EXPECT_LE(DLT_RETURN_OK, dlt_log_int(&context, DLT_LOG_WARN, data)); EXPECT_LE(DLT_RETURN_OK, dlt_log_int(&context, DLT_LOG_INFO, data)); EXPECT_LE(DLT_RETURN_OK, dlt_log_int(&context, DLT_LOG_VERBOSE, data)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_app()); } TEST(t_dlt_log_int, abnormal) { DltContext context; EXPECT_LE(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_LE(DLT_RETURN_OK, dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_log_int abnormal")); /* undefined values for DltLogLevelType */ /* shouldn't it return -1? */ /* TODO: int data = 1; */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_log_int(&context, (DltLogLevelType)-100, data)); */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_log_int(&context, (DltLogLevelType)-10, data)); */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_log_int(&context, (DltLogLevelType)10, data)); */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_log_int(&context, (DltLogLevelType)100, data)); */ EXPECT_LE(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_app()); } TEST(t_dlt_log_int, nullpointer) { DltContext context; EXPECT_LE(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_LE(DLT_RETURN_OK, dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_log_int nullpointer")); /* NULL */ int data = 0; EXPECT_GE(DLT_RETURN_ERROR, dlt_log_int(NULL, DLT_LOG_DEFAULT, data)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_app()); } /*/////////////////////////////////////// */ /* t_dlt_log_uint */ TEST(t_dlt_log_uint, normal) { DltContext context; EXPECT_LE(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_LE(DLT_RETURN_OK, dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_log_uint normal")); /* normal values */ unsigned int data = UINT_MIN; EXPECT_LE(DLT_RETURN_OK, dlt_log_uint(&context, DLT_LOG_DEFAULT, data)); EXPECT_LE(DLT_RETURN_OK, dlt_log_uint(&context, DLT_LOG_OFF, data)); EXPECT_LE(DLT_RETURN_OK, dlt_log_uint(&context, DLT_LOG_FATAL, data)); EXPECT_LE(DLT_RETURN_OK, dlt_log_uint(&context, DLT_LOG_ERROR, data)); EXPECT_LE(DLT_RETURN_OK, dlt_log_uint(&context, DLT_LOG_WARN, data)); EXPECT_LE(DLT_RETURN_OK, dlt_log_uint(&context, DLT_LOG_INFO, data)); EXPECT_LE(DLT_RETURN_OK, dlt_log_uint(&context, DLT_LOG_VERBOSE, data)); data = 0; EXPECT_LE(DLT_RETURN_OK, dlt_log_uint(&context, DLT_LOG_DEFAULT, data)); EXPECT_LE(DLT_RETURN_OK, dlt_log_uint(&context, DLT_LOG_OFF, data)); EXPECT_LE(DLT_RETURN_OK, dlt_log_uint(&context, DLT_LOG_FATAL, data)); EXPECT_LE(DLT_RETURN_OK, dlt_log_uint(&context, DLT_LOG_ERROR, data)); EXPECT_LE(DLT_RETURN_OK, dlt_log_uint(&context, DLT_LOG_WARN, data)); EXPECT_LE(DLT_RETURN_OK, dlt_log_uint(&context, DLT_LOG_INFO, data)); EXPECT_LE(DLT_RETURN_OK, dlt_log_uint(&context, DLT_LOG_VERBOSE, data)); data = UINT_MAX; EXPECT_LE(DLT_RETURN_OK, dlt_log_uint(&context, DLT_LOG_DEFAULT, data)); EXPECT_LE(DLT_RETURN_OK, dlt_log_uint(&context, DLT_LOG_OFF, data)); EXPECT_LE(DLT_RETURN_OK, dlt_log_uint(&context, DLT_LOG_FATAL, data)); EXPECT_LE(DLT_RETURN_OK, dlt_log_uint(&context, DLT_LOG_ERROR, data)); EXPECT_LE(DLT_RETURN_OK, dlt_log_uint(&context, DLT_LOG_WARN, data)); EXPECT_LE(DLT_RETURN_OK, dlt_log_uint(&context, DLT_LOG_INFO, data)); EXPECT_LE(DLT_RETURN_OK, dlt_log_uint(&context, DLT_LOG_VERBOSE, data)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_app()); } TEST(t_dlt_log_uint, abnormal) { DltContext context; EXPECT_LE(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_LE(DLT_RETURN_OK, dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_log_uint abnormal")); /* undefined values for DltLogLevelType */ /* shouldn't it return -1? */ /* TODO: unsigned int data = 1; */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_log_uint(&context, (DltLogLevelType)-100, data)); */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_log_uint(&context, (DltLogLevelType)-10, data)); */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_log_uint(&context, (DltLogLevelType)10, data)); */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_log_uint(&context, (DltLogLevelType)100, data)); */ EXPECT_LE(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_app()); } TEST(t_dlt_log_uint, nullpointer) { DltContext context; EXPECT_LE(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_LE(DLT_RETURN_OK, dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_log_uint nullpointer")); /* NULL */ unsigned int data = 0; EXPECT_GE(DLT_RETURN_ERROR, dlt_log_uint(NULL, DLT_LOG_DEFAULT, data)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_app()); } /*/////////////////////////////////////// */ /* t_dlt_log_raw */ TEST(t_dlt_log_raw, normal) { DltContext context; EXPECT_LE(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_LE(DLT_RETURN_OK, dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_log_raw normal")); /* normal values */ char data[5] = "test"; uint16_t length = 4; EXPECT_LE(DLT_RETURN_OK, dlt_log_raw(&context, DLT_LOG_DEFAULT, data, length)); EXPECT_LE(DLT_RETURN_OK, dlt_log_raw(&context, DLT_LOG_OFF, data, length)); EXPECT_LE(DLT_RETURN_OK, dlt_log_raw(&context, DLT_LOG_FATAL, data, length)); EXPECT_LE(DLT_RETURN_OK, dlt_log_raw(&context, DLT_LOG_ERROR, data, length)); EXPECT_LE(DLT_RETURN_OK, dlt_log_raw(&context, DLT_LOG_WARN, data, length)); EXPECT_LE(DLT_RETURN_OK, dlt_log_raw(&context, DLT_LOG_INFO, data, length)); EXPECT_LE(DLT_RETURN_OK, dlt_log_raw(&context, DLT_LOG_VERBOSE, data, length)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_app()); } TEST(t_dlt_log_raw, abnormal) { DltContext context; EXPECT_EQ(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_EQ(DLT_RETURN_OK, dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_log_raw abnormal")); uint16_t length = DLT_USER_BUF_MAX_SIZE + 10; char buffer[length]; memset(buffer, '\000', length); for (int i = 0; i < length; i++) buffer[i] = 'X'; EXPECT_EQ(DLT_RETURN_USER_BUFFER_FULL, dlt_log_raw(&context, DLT_LOG_INFO, buffer, length)); /* undefined values for DltLogLevelType */ /* shouldn't it return -1? */ /* char data[5] = "test"; */ /* TODO: uint16_t length = 4; */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_log_raw(&context, (DltLogLevelType)-100, data, length)); */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_log_raw(&context, (DltLogLevelType)-10, data, length)); */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_log_raw(&context, (DltLogLevelType)10, data, length)); */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_log_raw(&context, (DltLogLevelType)100, data, length)); */ /* zero length */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_log_raw(&context, DLT_LOG_DEFAULT, data, 0)); */ /* negative length */ /* EXPECT_GE(DLT_RETURN_ERROR,dlt_log_raw(&context, DLT_LOG_DEFAULT, data, -1)); */ /* EXPECT_GE(DLT_RETURN_ERROR,dlt_log_raw(&context, DLT_LOG_DEFAULT, data, -100)); */ EXPECT_EQ(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_EQ(DLT_RETURN_OK, dlt_unregister_app()); } TEST(t_dlt_log_raw, nullpointer) { DltContext context; EXPECT_LE(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_LE(DLT_RETURN_OK, dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_log_raw nullpointer")); /* NULL */ char data[5] = "test"; uint16_t length = 4; EXPECT_GE(DLT_RETURN_ERROR, dlt_log_raw(NULL, DLT_LOG_DEFAULT, data, length)); EXPECT_GE(DLT_RETURN_ERROR, dlt_log_raw(NULL, DLT_LOG_DEFAULT, NULL, length)); EXPECT_GE(DLT_RETURN_ERROR, dlt_log_raw(&context, DLT_LOG_DEFAULT, NULL, length)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_app()); } /*/////////////////////////////////////// */ /* t_dlt_log_marker */ TEST(t_dlt_log_marker, normal) { DltContext context; EXPECT_LE(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_LE(DLT_RETURN_OK, dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_log_marker normal")); /* normal */ EXPECT_LE(DLT_RETURN_OK, dlt_log_marker()); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_app()); } /*/////////////////////////////////////// */ /* t_dlt_register_app */ TEST(t_dlt_register_app, normal) { EXPECT_LE(DLT_RETURN_OK, dlt_register_app("T", "dlt_user.c tests")); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_app()); EXPECT_LE(DLT_RETURN_OK, dlt_register_app("TU", "dlt_user.c tests")); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_app()); EXPECT_LE(DLT_RETURN_OK, dlt_register_app("TUS", "dlt_user.c tests")); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_app()); EXPECT_LE(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_app()); } TEST(t_dlt_register_app, abnormal) { EXPECT_GE(DLT_RETURN_ERROR, dlt_register_app("", "dlt_user.c tests")); EXPECT_GE(DLT_RETURN_ERROR, dlt_unregister_app()); /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_register_app("TUSR1", "dlt_user.c tests")); */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_unregister_app()); */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_register_app("TUSR123445667", "dlt_user.c tests")); */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_unregister_app()); */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_register_app("TUSR", "")); */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_unregister_app()); */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_register_app("TUSR", NULL)); */ } TEST(t_dlt_register_app, nullpointer) { EXPECT_GE(DLT_RETURN_ERROR, dlt_register_app(NULL, NULL)); EXPECT_GE(DLT_RETURN_ERROR, dlt_register_app(NULL, "dlt_user.c tests")); } /*/////////////////////////////////////// */ /* t_dlt_unregister_app */ TEST(t_dlt_unregister_app, normal) { EXPECT_LE(DLT_RETURN_OK, dlt_register_app("T", "dlt_user.c tests")); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_app()); EXPECT_LE(DLT_RETURN_OK, dlt_register_app("TU", "dlt_user.c tests")); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_app()); EXPECT_LE(DLT_RETURN_OK, dlt_register_app("TUS", "dlt_user.c tests")); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_app()); EXPECT_LE(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_app()); } TEST(t_dlt_unregister_app, abnormal) { EXPECT_GE(DLT_RETURN_ERROR, dlt_unregister_app()); EXPECT_GE(DLT_RETURN_ERROR, dlt_register_app("", "dlt_user.c tests")); EXPECT_GE(DLT_RETURN_ERROR, dlt_unregister_app()); /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_register_app("TUSR1", "dlt_user.c tests")); */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_unregister_app()); */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_register_app("TUSR123445667", "dlt_user.c tests")); */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_unregister_app()); */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_register_app("TUSR", "")); */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_unregister_app()); */ } /*/////////////////////////////////////// */ /* t_dlt_register_context */ TEST(t_dlt_register_context, normal) { DltContext context; EXPECT_LE(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_LE(DLT_RETURN_OK, dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_register_context normal")); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_app()); } TEST(t_dlt_register_context, abnormal) { DltContext context; EXPECT_LE(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_GE(DLT_RETURN_ERROR, dlt_register_context(&context, "", "d")); /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_unregister_context(&context)); */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_register_context(&context, "T", "")); */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_unregister_context(&context)); */ EXPECT_GE(DLT_RETURN_ERROR, dlt_register_context(&context, "", "")); /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_unregister_context(&context)); */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_register_context(&context, "TEST1", "")); */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_unregister_context(&context)); */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_register_context(&context, "TEST1", "1")); */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_unregister_context(&context)); */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_register_context(&context, "TEST1234567890", "")); */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_unregister_context(&context)); */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_register_context(&context, "TEST1234567890", "1")); */ EXPECT_LE(DLT_RETURN_OK, dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_register_context normal")); /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_register_context normal")); */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_register_context normal")); */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_register_context normal")); */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_register_context normal")); */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_register_context(&context, "TEST", NULL)); */ EXPECT_LE(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_app()); } TEST(t_dlt_register_context, nullpointer) { DltContext context; EXPECT_LE(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_GE(DLT_RETURN_ERROR, dlt_register_context(&context, NULL, "dlt_user.c t_dlt_register_context normal")); EXPECT_GE(DLT_RETURN_ERROR, dlt_register_context(&context, NULL, NULL)); EXPECT_GE(DLT_RETURN_ERROR, dlt_register_context(NULL, "TEST", NULL)); EXPECT_GE(DLT_RETURN_ERROR, dlt_register_context(NULL, NULL, "dlt_user.c t_dlt_register_context normal")); EXPECT_GE(DLT_RETURN_ERROR, dlt_register_context(NULL, NULL, NULL)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_app()); } /*/////////////////////////////////////// */ /* t_dlt_register_context_ll_ts */ TEST(t_dlt_register_context_ll_ts, normal) { DltContext context; EXPECT_LE(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_LE(DLT_RETURN_OK, dlt_register_context_ll_ts(&context, "TEST", "dlt_user.c t_dlt_register_context_ll_ts normal", DLT_LOG_OFF, DLT_TRACE_STATUS_OFF)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_LE(DLT_RETURN_OK, dlt_register_context_ll_ts(&context, "TEST", "dlt_user.c t_dlt_register_context_ll_ts normal", DLT_LOG_FATAL, DLT_TRACE_STATUS_OFF)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_LE(DLT_RETURN_OK, dlt_register_context_ll_ts(&context, "TEST", "dlt_user.c t_dlt_register_context_ll_ts normal", DLT_LOG_ERROR, DLT_TRACE_STATUS_OFF)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_LE(DLT_RETURN_OK, dlt_register_context_ll_ts(&context, "TEST", "dlt_user.c t_dlt_register_context_ll_ts normal", DLT_LOG_WARN, DLT_TRACE_STATUS_OFF)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_LE(DLT_RETURN_OK, dlt_register_context_ll_ts(&context, "TEST", "dlt_user.c t_dlt_register_context_ll_ts normal", DLT_LOG_INFO, DLT_TRACE_STATUS_OFF)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_LE(DLT_RETURN_OK, dlt_register_context_ll_ts(&context, "TEST", "dlt_user.c t_dlt_register_context_ll_ts normal", DLT_LOG_DEBUG, DLT_TRACE_STATUS_OFF)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_LE(DLT_RETURN_OK, dlt_register_context_ll_ts(&context, "TEST", "dlt_user.c t_dlt_register_context_ll_ts normal", DLT_LOG_VERBOSE, DLT_TRACE_STATUS_OFF)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_LE(DLT_RETURN_OK, dlt_register_context_ll_ts(&context, "TEST", "dlt_user.c t_dlt_register_context_ll_ts normal", DLT_LOG_OFF, DLT_TRACE_STATUS_ON)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_LE(DLT_RETURN_OK, dlt_register_context_ll_ts(&context, "TEST", "dlt_user.c t_dlt_register_context_ll_ts normal", DLT_LOG_FATAL, DLT_TRACE_STATUS_ON)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_LE(DLT_RETURN_OK, dlt_register_context_ll_ts(&context, "TEST", "dlt_user.c t_dlt_register_context_ll_ts normal", DLT_LOG_ERROR, DLT_TRACE_STATUS_ON)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_LE(DLT_RETURN_OK, dlt_register_context_ll_ts(&context, "TEST", "dlt_user.c t_dlt_register_context_ll_ts normal", DLT_LOG_WARN, DLT_TRACE_STATUS_ON)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_LE(DLT_RETURN_OK, dlt_register_context_ll_ts(&context, "TEST", "dlt_user.c t_dlt_register_context_ll_ts normal", DLT_LOG_INFO, DLT_TRACE_STATUS_ON)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_LE(DLT_RETURN_OK, dlt_register_context_ll_ts(&context, "TEST", "dlt_user.c t_dlt_register_context_ll_ts normal", DLT_LOG_DEBUG, DLT_TRACE_STATUS_ON)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_LE(DLT_RETURN_OK, dlt_register_context_ll_ts(&context, "TEST", "dlt_user.c t_dlt_register_context_ll_ts normal", DLT_LOG_VERBOSE, DLT_TRACE_STATUS_ON)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_app()); } TEST(t_dlt_register_context_ll_ts, abnormal) { DltContext context; EXPECT_LE(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_GE(DLT_RETURN_ERROR, dlt_register_context_ll_ts(&context, "", "d", DLT_LOG_OFF, DLT_TRACE_STATUS_ON)); /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_unregister_context(&context)); */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_register_context_ll_ts(&context, "T", "", DLT_LOG_OFF, DLT_TRACE_STATUS_ON)); */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_unregister_context(&context)); */ EXPECT_GE(DLT_RETURN_ERROR, dlt_register_context_ll_ts(&context, "", "", DLT_LOG_OFF, DLT_TRACE_STATUS_ON)); /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_unregister_context(&context)); */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_register_context_ll_ts(&context, "TEST1", "", DLT_LOG_OFF, DLT_TRACE_STATUS_ON)); */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_unregister_context(&context)); */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_register_context_ll_ts(&context, "TEST1", "1", DLT_LOG_OFF, DLT_TRACE_STATUS_ON)); */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_unregister_context(&context)); */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_register_context_ll_ts(&context, "TEST1234567890", "", DLT_LOG_OFF, DLT_TRACE_STATUS_ON)); */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_unregister_context(&context)); */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_register_context_ll_ts(&context, "TEST1234567890", "1", DLT_LOG_OFF, DLT_TRACE_STATUS_ON)); */ EXPECT_LE(DLT_RETURN_OK, dlt_register_context_ll_ts(&context, "TEST", "dlt_user.c t_dlt_register_context_ll_ts normal", DLT_LOG_OFF, DLT_TRACE_STATUS_ON)); /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_register_context_ll_ts(&context, "TEST", "dlt_user.c t_dlt_register_context_ll_ts normal", DLT_LOG_OFF, DLT_TRACE_STATUS_ON)); */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_register_context_ll_ts(&context, "TEST", "dlt_user.c t_dlt_register_context_ll_ts normal", DLT_LOG_OFF, DLT_TRACE_STATUS_ON)); */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_register_context_ll_ts(&context, "TEST", "dlt_user.c t_dlt_register_context_ll_ts normal", DLT_LOG_OFF, DLT_TRACE_STATUS_ON)); */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_register_context_ll_ts(&context, "TEST", "dlt_user.c t_dlt_register_context_ll_ts normal", DLT_LOG_OFF, DLT_TRACE_STATUS_ON)); */ EXPECT_LE(DLT_RETURN_OK, dlt_unregister_context(&context)); /* DLT_LOG_DEFAULT and DLT_TRACE_STATUS_DEFAULT not allowed */ /* TODO: Why not? */ /* EXPECT_GE(DLT_RETURN_ERROR,dlt_register_context_ll_ts(&context, "TEST", "dlt_user.c t_dlt_register_context_ll_ts normal", DLT_LOG_DEFAULT, DLT_TRACE_STATUS_OFF)); */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_unregister_context(&context)); */ /* EXPECT_GE(DLT_RETURN_ERROR,dlt_register_context_ll_ts(&context, "TEST", "dlt_user.c t_dlt_register_context_ll_ts normal", DLT_LOG_DEFAULT, DLT_TRACE_STATUS_DEFAULT)); */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_unregister_context(&context)); */ /* EXPECT_GE(DLT_RETURN_ERROR,dlt_register_context_ll_ts(&context, "TEST", "dlt_user.c t_dlt_register_context_ll_ts normal", DLT_LOG_OFF, DLT_TRACE_STATUS_DEFAULT)); */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_unregister_context(&context)); */ /* abnormal values for loglevel and tracestatus */ EXPECT_EQ(DLT_RETURN_WRONG_PARAMETER, dlt_register_context_ll_ts(&context, "TEST", "dlt_user.c t_dlt_register_context_ll_ts normal", -3, DLT_TRACE_STATUS_OFF)); /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_unregister_context(&context)); */ EXPECT_EQ(DLT_RETURN_WRONG_PARAMETER, dlt_register_context_ll_ts(&context, "TEST", "dlt_user.c t_dlt_register_context_ll_ts normal", 100, DLT_TRACE_STATUS_OFF)); /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_unregister_context(&context)); */ EXPECT_EQ(DLT_RETURN_WRONG_PARAMETER, dlt_register_context_ll_ts(&context, "TEST", "dlt_user.c t_dlt_register_context_ll_ts normal", DLT_LOG_OFF, -3)); /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_unregister_context(&context)); */ EXPECT_EQ(DLT_RETURN_WRONG_PARAMETER, dlt_register_context_ll_ts(&context, "TEST", "dlt_user.c t_dlt_register_context_ll_ts normal", DLT_LOG_OFF, 100)); /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_unregister_context(&context)); */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_register_context_ll_ts(&context, "TEST", NULL, DLT_LOG_OFF, DLT_TRACE_STATUS_OFF)); */ EXPECT_LE(DLT_RETURN_OK, dlt_unregister_app()); } TEST(t_dlt_register_context_ll_ts, nullpointer) { DltContext context; EXPECT_LE(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_GE(DLT_RETURN_ERROR, dlt_register_context_ll_ts(&context, NULL, "dlt_user.c t_dlt_register_context_ll_ts normal", DLT_LOG_OFF, DLT_TRACE_STATUS_OFF)); EXPECT_GE(DLT_RETURN_ERROR, dlt_register_context_ll_ts(&context, NULL, NULL, DLT_LOG_OFF, DLT_TRACE_STATUS_OFF)); EXPECT_GE(DLT_RETURN_ERROR, dlt_register_context_ll_ts(NULL, "TEST", NULL, DLT_LOG_OFF, DLT_TRACE_STATUS_OFF)); EXPECT_GE(DLT_RETURN_ERROR, dlt_register_context_ll_ts(NULL, NULL, "dlt_user.c t_dlt_register_context_ll_ts normal", DLT_LOG_OFF, DLT_TRACE_STATUS_OFF)); EXPECT_GE(DLT_RETURN_ERROR, dlt_register_context_ll_ts(NULL, NULL, NULL, DLT_LOG_OFF, DLT_TRACE_STATUS_OFF)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_app()); } /*/////////////////////////////////////// */ /* t_dlt_unregister_context */ TEST(t_dlt_unregister_context, normal) { DltContext context; EXPECT_LE(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_LE(DLT_RETURN_OK, dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_unregister_context normal")); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_app()); } TEST(t_dlt_unregister_context, abnormal) { DltContext context; EXPECT_LE(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_GE(DLT_RETURN_ERROR, dlt_register_context(&context, "", "d")); /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_unregister_context(&context)); */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_register_context(&context, "T", "")); */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_unregister_context(&context)); */ EXPECT_GE(DLT_RETURN_ERROR, dlt_register_context(&context, "", "")); /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_unregister_context(&context)); */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_register_context(&context, "TEST1", "")); */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_unregister_context(&context)); */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_register_context(&context, "TEST1", "1")); */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_unregister_context(&context)); */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_register_context(&context, "TEST1234567890", "")); */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_unregister_context(&context)); */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_register_context(&context, "TEST1234567890", "1")); */ EXPECT_LE(DLT_RETURN_OK, dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_unregister_context normal")); /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_unregister_context normal")); */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_unregister_context normal")); */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_unregister_context normal")); */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_unregister_context normal")); */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_register_context(&context, "TEST", NULL)); */ EXPECT_LE(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_app()); } TEST(t_dlt_unregister_context, nullpointer) { DltContext context; EXPECT_LE(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_GE(DLT_RETURN_ERROR, dlt_register_context(&context, NULL, "dlt_user.c t_dlt_unregister_context normal")); EXPECT_GE(DLT_RETURN_ERROR, dlt_register_context(&context, NULL, NULL)); EXPECT_GE(DLT_RETURN_ERROR, dlt_register_context(NULL, "TEST", NULL)); EXPECT_GE(DLT_RETURN_ERROR, dlt_register_context(NULL, NULL, "dlt_user.c t_dlt_unregister_context normal")); EXPECT_GE(DLT_RETURN_ERROR, dlt_register_context(NULL, NULL, NULL)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_app()); } /*/////////////////////////////////////// */ /* t_dlt_register_injection_callback */ int dlt_user_injection_callback(uint32_t /*service_id*/, void */*data*/, uint32_t /*length*/) { return 0; } TEST(t_dlt_register_injection_callback, normal) { DltContext context; /* TODO: uint32_t service_id; */ EXPECT_LE(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_LE(DLT_RETURN_OK, dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_register_injection_callback normal")); /* TODO: service_id = 0x123; */ /* TODO: EXPECT_LE(DLT_RETURN_OK,dlt_register_injection_callback(&context, service_id, dlt_user_injection_callback)); */ EXPECT_LE(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_app()); } /*/////////////////////////////////////// */ /* t_dlt_register_log_level_changed_callback */ void dlt_user_log_level_changed_callback(char /*context_id*/[DLT_ID_SIZE], uint8_t /*log_level*/, uint8_t /*trace_status*/) {} TEST(t_dlt_register_log_level_changed_callback, normal) { DltContext context; EXPECT_LE(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_LE(DLT_RETURN_OK, dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_register_log_level_changed_callback normal")); EXPECT_LE(DLT_RETURN_OK, dlt_register_log_level_changed_callback(&context, dlt_user_log_level_changed_callback)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_app()); } /*/////////////////////////////////////// */ /* t_dlt_user_trace_network */ TEST(t_dlt_user_trace_network, normal) { DltContext context; EXPECT_LE(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_LE(DLT_RETURN_OK, dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_user_trace_network normal")); char header[16]; for (char i = 0; i < 16; ++i) header[(int)i] = i; char payload[32]; for (char i = 0; i < 32; ++i) payload[(int)i] = i; EXPECT_LE(DLT_RETURN_OK, dlt_user_trace_network(&context, DLT_NW_TRACE_IPC, 16, header, 32, payload)); EXPECT_LE(DLT_RETURN_OK, dlt_user_trace_network(&context, DLT_NW_TRACE_CAN, 16, header, 32, payload)); EXPECT_LE(DLT_RETURN_OK, dlt_user_trace_network(&context, DLT_NW_TRACE_FLEXRAY, 16, header, 32, payload)); EXPECT_LE(DLT_RETURN_OK, dlt_user_trace_network(&context, DLT_NW_TRACE_MOST, 16, header, 32, payload)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_app()); } TEST(t_dlt_user_trace_network, abnormal) { DltContext context; EXPECT_LE(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_LE(DLT_RETURN_OK, dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_user_trace_network abnormal")); /* TODO: char header[16]; */ /* TODO: for(char i = 0; i < 16; ++i) */ /* TODO: { */ /* TODO: header[(int)i] = i; */ /* TODO: } */ /* TODO: char payload[32]; */ /* TODO: for(char i = 0; i < 32; ++i) */ /* TODO: { */ /* TODO: payload[(int)i] = i; */ /* TODO: } */ /* data length = 0. Does this make sense? */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_user_trace_network(&context, DLT_NW_TRACE_IPC, 0, header, 32, payload)); */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_user_trace_network(&context, DLT_NW_TRACE_CAN, 0, header, 0, payload)); */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_user_trace_network(&context, DLT_NW_TRACE_FLEXRAY, 16, header, 0, payload)); */ /* invalid DltNetworkTraceType value */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_user_trace_network(&context, (DltNetworkTraceType)-100, 16, header, 32, payload)); */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_user_trace_network(&context, (DltNetworkTraceType)-10, 16, header, 32, payload)); */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_user_trace_network(&context, (DltNetworkTraceType)10, 16, header, 32, payload)); */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_user_trace_network(&context, (DltNetworkTraceType)100, 16, header, 32, payload)); */ EXPECT_LE(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_app()); } TEST(t_dlt_user_trace_network, nullpointer) { DltContext context; EXPECT_LE(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_LE(DLT_RETURN_OK, dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_user_trace_network nullpointer")); char header[16]; for (char i = 0; i < 16; ++i) header[(int)i] = i; char payload[32]; for (char i = 0; i < 32; ++i) payload[(int)i] = i; /* what to expect when giving in NULL pointer? */ EXPECT_LE(DLT_RETURN_OK, dlt_user_trace_network(&context, DLT_NW_TRACE_IPC, 16, NULL, 32, payload)); EXPECT_LE(DLT_RETURN_WRONG_PARAMETER, dlt_user_trace_network(&context, DLT_NW_TRACE_CAN, 16, header, 32, NULL)); EXPECT_LE(DLT_RETURN_WRONG_PARAMETER, dlt_user_trace_network(&context, DLT_NW_TRACE_FLEXRAY, 16, NULL, 32, NULL)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_app()); } /*/////////////////////////////////////// */ /* t_dlt_user_trace_network_truncated */ TEST(t_dlt_user_trace_network_truncated, normal) { DltContext context; EXPECT_LE(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_LE(DLT_RETURN_OK, dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_user_trace_network_truncated normal")); char header[16]; for (char i = 0; i < 16; ++i) header[(int)i] = i; char payload[32]; for (char i = 0; i < 32; ++i) payload[(int)i] = i; EXPECT_LE(DLT_RETURN_OK, dlt_user_trace_network_truncated(&context, DLT_NW_TRACE_IPC, 16, header, 32, payload, 0)); EXPECT_LE(DLT_RETURN_OK, dlt_user_trace_network_truncated(&context, DLT_NW_TRACE_CAN, 16, header, 32, payload, 1)); EXPECT_LE(DLT_RETURN_OK, dlt_user_trace_network_truncated(&context, DLT_NW_TRACE_FLEXRAY, 16, header, 32, payload, -1)); EXPECT_LE(DLT_RETURN_OK, dlt_user_trace_network_truncated(&context, DLT_NW_TRACE_MOST, 16, header, 32, payload, 10)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_app()); } TEST(t_dlt_user_trace_network_truncated, abnormal) { DltContext context; EXPECT_LE(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_LE(DLT_RETURN_OK, dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_user_trace_network_truncated abnormal")); /* TODO: char header[16]; */ /* TODO: for(char i = 0; i < 16; ++i) */ /* TODO: { */ /* TODO: header[(int)i] = i; */ /* TODO: } */ /* TODO: char payload[32]; */ /* TODO: for(char i = 0; i < 32; ++i) */ /* TODO: { */ /* TODO: payload[(int)i] = i; */ /* TODO: } */ /* data length = 0. Does this make sense? */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_user_trace_network_truncated(&context, DLT_NW_TRACE_IPC, 0, header, 32, payload, 0)); */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_user_trace_network_truncated(&context, DLT_NW_TRACE_CAN, 0, header, 0, payload, 0)); */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_user_trace_network_truncated(&context, DLT_NW_TRACE_FLEXRAY, 16, header, 0, payload, 0)); */ /* invalid DltNetworkTraceType value */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_user_trace_network_truncated(&context, (DltNetworkTraceType)-100, 16, header, 32, payload, 0)); */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_user_trace_network_truncated(&context, (DltNetworkTraceType)-10, 16, header, 32, payload, 0)); */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_user_trace_network_truncated(&context, (DltNetworkTraceType)10, 16, header, 32, payload, 0)); */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_user_trace_network_truncated(&context, (DltNetworkTraceType)100, 16, header, 32, payload, 0)); */ EXPECT_LE(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_app()); } TEST(t_dlt_user_trace_network_truncated, nullpointer) { DltContext context; EXPECT_LE(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_LE(DLT_RETURN_OK, dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_user_trace_network_truncated nullpointer")); char header[16]; for (char i = 0; i < 16; ++i) header[(int)i] = i; char payload[32]; for (char i = 0; i < 32; ++i) payload[(int)i] = i; /* what to expect when giving in NULL pointer? */ EXPECT_LE(DLT_RETURN_OK, dlt_user_trace_network_truncated(&context, DLT_NW_TRACE_IPC, 16, NULL, 32, payload, 0)); EXPECT_LE(DLT_RETURN_WRONG_PARAMETER, dlt_user_trace_network_truncated(&context, DLT_NW_TRACE_CAN, 16, header, 32, NULL, 0)); EXPECT_LE(DLT_RETURN_WRONG_PARAMETER, dlt_user_trace_network_truncated(&context, DLT_NW_TRACE_FLEXRAY, 16, NULL, 32, NULL, 0)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_app()); } /*/////////////////////////////////////// */ /* t_dlt_user_trace_network_segmented */ TEST(t_dlt_user_trace_network_segmented, normal) { DltContext context; EXPECT_LE(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_LE(DLT_RETURN_OK, dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_user_trace_network_segmented normal")); char header[16]; for (char i = 0; i < 16; ++i) header[(int)i] = i; char payload[32]; for (char i = 0; i < 32; ++i) payload[(int)i] = i; EXPECT_LE(DLT_RETURN_OK, dlt_user_trace_network_segmented(&context, DLT_NW_TRACE_IPC, 16, header, 32, payload)); EXPECT_LE(DLT_RETURN_OK, dlt_user_trace_network_segmented(&context, DLT_NW_TRACE_CAN, 16, header, 32, payload)); EXPECT_LE(DLT_RETURN_OK, dlt_user_trace_network_segmented(&context, DLT_NW_TRACE_FLEXRAY, 16, header, 32, payload)); EXPECT_LE(DLT_RETURN_OK, dlt_user_trace_network_segmented(&context, DLT_NW_TRACE_MOST, 16, header, 32, payload)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_app()); } TEST(t_dlt_user_trace_network_segmented, abnormal) { DltContext context; EXPECT_LE(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_LE(DLT_RETURN_OK, dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_user_trace_network_segmented abnormal")); /* TODO: char header[16]; */ /* TODO: for(char i = 0; i < 16; ++i) */ /* TODO: { */ /* TODO: header[(int)i] = i; */ /* TODO: } */ /* TODO: char payload[32]; */ /* TODO: for(char i = 0; i < 32; ++i) */ /* TODO: { */ /* TODO: payload[(int)i] = i; */ /* TODO: } */ /* data length = 0. Does this make sense? */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_user_trace_network_segmented(&context, DLT_NW_TRACE_IPC, 0, header, 32, payload)); */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_user_trace_network_segmented(&context, DLT_NW_TRACE_CAN, 0, header, 0, payload)); */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_user_trace_network_segmented(&context, DLT_NW_TRACE_FLEXRAY, 16, header, 0, payload)); */ /* invalid DltNetworkTraceType value */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_user_trace_network_segmented(&context, (DltNetworkTraceType)-100, 16, header, 32, payload)); */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_user_trace_network_segmented(&context, (DltNetworkTraceType)-10, 16, header, 32, payload)); */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_user_trace_network_segmented(&context, (DltNetworkTraceType)10, 16, header, 32, payload)); */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_user_trace_network_segmented(&context, (DltNetworkTraceType)100, 16, header, 32, payload)); */ EXPECT_LE(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_app()); } TEST(t_dlt_user_trace_network_segmented, nullpointer) { DltContext context; EXPECT_LE(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_LE(DLT_RETURN_OK, dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_user_trace_network_segmented nullpointer")); char header[16]; for (char i = 0; i < 16; ++i) header[(int)i] = i; char payload[32]; for (char i = 0; i < 32; ++i) payload[(int)i] = i; /* what to expect when giving in NULL pointer? */ EXPECT_LE(DLT_RETURN_OK, dlt_user_trace_network_segmented(&context, DLT_NW_TRACE_IPC, 16, NULL, 32, payload)); EXPECT_LE(DLT_RETURN_WRONG_PARAMETER, dlt_user_trace_network_segmented(&context, DLT_NW_TRACE_CAN, 16, header, 32, NULL)); EXPECT_LE(DLT_RETURN_WRONG_PARAMETER, dlt_user_trace_network_segmented(&context, DLT_NW_TRACE_FLEXRAY, 16, NULL, 32, NULL)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_app()); } /*/////////////////////////////////////// */ /* t_dlt_set_log_mode */ TEST(t_dlt_set_log_mode, normal) { EXPECT_LE(DLT_RETURN_OK, dlt_set_log_mode(DLT_USER_MODE_OFF)); EXPECT_LE(DLT_RETURN_OK, dlt_set_log_mode(DLT_USER_MODE_EXTERNAL)); EXPECT_LE(DLT_RETURN_OK, dlt_set_log_mode(DLT_USER_MODE_INTERNAL)); EXPECT_LE(DLT_RETURN_OK, dlt_set_log_mode(DLT_USER_MODE_BOTH)); } TEST(t_dlt_set_log_mode, abnormal) { /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_set_log_mode(DLT_USER_MODE_UNDEFINED)); */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_set_log_mode((DltUserLogMode)-100)); */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_set_log_mode((DltUserLogMode)-10)); */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_set_log_mode((DltUserLogMode)10)); */ /* TODO: EXPECT_GE(DLT_RETURN_ERROR,dlt_set_log_mode((DltUserLogMode)100)); */ } /*/////////////////////////////////////// */ /* t_dlt_get_log_state */ TEST(t_dlt_get_log_state, normal) { sleep(1); dlt_init_common(); EXPECT_EQ(-1, dlt_get_log_state()); } /*/////////////////////////////////////// */ /* t_dlt_verbose_mode */ TEST(t_dlt_verbose_mode, normal) { EXPECT_LE(DLT_RETURN_OK, dlt_verbose_mode()); } /*/////////////////////////////////////// */ /* t_dlt_nonverbose_mode */ TEST(t_dlt_nonverbose_mode, normal) { EXPECT_LE(DLT_RETURN_OK, dlt_nonverbose_mode()); } /*/////////////////////////////////////// */ /* free dlt */ TEST(t_dlt_free, onetime) { EXPECT_EQ(DLT_RETURN_OK, dlt_free()); } /*/////////////////////////////////////// */ /* dlt_user_is_logLevel_enabled */ TEST(t_dlt_user_is_logLevel_enabled, normal) { DltContext context; EXPECT_LE(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); EXPECT_LE(DLT_RETURN_OK, dlt_register_context_ll_ts(&context, "ILLE", "t_dlt_user_is_logLevel_enabled context", DLT_LOG_INFO, -2)); /* DLT_USER_TRACE_STATUS_NOT_SET */ EXPECT_LE(DLT_RETURN_TRUE, dlt_user_is_logLevel_enabled(&context, DLT_LOG_FATAL)); EXPECT_LE(DLT_RETURN_TRUE, dlt_user_is_logLevel_enabled(&context, DLT_LOG_ERROR)); EXPECT_LE(DLT_RETURN_TRUE, dlt_user_is_logLevel_enabled(&context, DLT_LOG_WARN)); EXPECT_LE(DLT_RETURN_TRUE, dlt_user_is_logLevel_enabled(&context, DLT_LOG_INFO)); EXPECT_LE(DLT_RETURN_LOGGING_DISABLED, dlt_user_is_logLevel_enabled(&context, DLT_LOG_DEBUG)); EXPECT_LE(DLT_RETURN_LOGGING_DISABLED, dlt_user_is_logLevel_enabled(&context, DLT_LOG_VERBOSE)); EXPECT_LE(DLT_RETURN_LOGGING_DISABLED, dlt_user_is_logLevel_enabled(&context, DLT_LOG_OFF)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_context(&context)); EXPECT_LE(DLT_RETURN_OK, dlt_unregister_app()); } TEST(t_dlt_user_is_logLevel_enabled, nullpointer) { EXPECT_LE(DLT_RETURN_WRONG_PARAMETER, dlt_user_is_logLevel_enabled(NULL, DLT_LOG_FATAL)); } /*/////////////////////////////////////// */ /* main */ int main(int argc, char **argv) { ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } dlt-daemon-2.18.4/tests/mod_system_logger/000077500000000000000000000000001353342203500205165ustar00rootroot00000000000000dlt-daemon-2.18.4/tests/mod_system_logger/Makefile000066400000000000000000000003021353342203500221510ustar00rootroot00000000000000obj-m := mod_system_logger.o KDIR := /lib/modules/$(shell uname -r)/build PWD := $(shell pwd) default: $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules clean: $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) clean dlt-daemon-2.18.4/tests/mod_system_logger/mod_system_logger.c000066400000000000000000000015471353342203500244130ustar00rootroot00000000000000#include #include #include int i; static int system_proc_show(struct seq_file *m, void *v) { for (i = 0; i < 1000; i++) seq_printf(m, "Test Systemlogger %i\n", i); return 0; } static int system_proc_open(struct inode *inode, struct file *file) { return single_open(file, system_proc_show, NULL); } static const struct file_operations system_proc_fops = { .owner = THIS_MODULE, .open = system_proc_open, .read = seq_read, .llseek = seq_lseek, .release = single_release, }; static int __init system_proc_init(void) { proc_create("systemlogger", 0, NULL, &system_proc_fops); return 0; } static void __exit system_proc_exit(void) { remove_proc_entry("systemlogger", NULL); } MODULE_LICENSE("GPL"); module_init(system_proc_init); module_exit(system_proc_exit); dlt-daemon-2.18.4/tests/start_filetransfer_test.sh000077500000000000000000000010561353342203500222750ustar00rootroot00000000000000#!/bin/bash file="testfile_filetransfer.txt" fullpath="$(pwd)/testfile_filetransfer.txt" #start dlt-daemon dlt-daemon & sleep 1 #start dlt-test-receiver ./../build/tests/dlt_test_receiver -f localhost & sleep 1 #send file to daemon dlt-example-filetransfer $fullpath & sleep 1 #create md5 sum md5_1=($(md5sum $file)) md5_2=($(md5sum /tmp/$file)) echo $md5_1 echo $md5_2 #verify the sums tput setaf 1 if [ $md5_1 == $md5_2 ] then echo "Files are equal. Transfer succuess." else echo "File not equal. Error on transmission" fi tput setaf 7 pkill dlt-daemon dlt-daemon-2.18.4/tests/start_logstorage_test.sh000077500000000000000000000136311353342203500217610ustar00rootroot00000000000000#!/bin/sh ################################################################################ # SPDX license identifier: MPL-2.0 # # Copyright (C) 2016, Advanced Driver Information Technology # This code is developed by Advanced Driver Information Technology. # Copyright of Advanced Driver Information Technology, Bosch and DENSO. # # This file is part of GENIVI Project DLT - Diagnostic Log and Trace. # # This Source Code Form is subject to the terms of the # Mozilla Public License (MPL), v. 2.0. # If a copy of the MPL was not distributed with this file, # You can obtain one at http://mozilla.org/MPL/2.0/. # # For further information see http://www.genivi.org/. ################################################################################ ################################################################################ #file : dlt_logstorage_test.sh # #Descriptiom : Smoke testing for logstorage feature of DLT # #Author : Onkar Palkar #Email : onkar.palkar@wipro.com # #History : 8/6/2016 ################################################################################ # # Function: -cleanup() # # Description -Delete the tmpDltLog folder if it already present # # Return -Zero on success # -Non zero on failure # cleanup() { pathTmp=/tmp folderName=tmpDltLog ls $pathTmp | grep $folderName > /dev/null if [ $? -eq '0' ] then rm -rf $pathTmp/$folderName fi pidof dlt-daemon > /dev/null if [ $? -eq '0' ] then killall dlt-daemon if [ $? -ne '0' ] then echo "Failed to kill dlt-daemon" return 1 fi fi return 0 } # # Function: -setup() # # Description -Create tmpDltLog folder # -Add dlt.conf file in the tmpDltLog folder # -Add dlt_logstorage.conf file in the tmpDltLog folder # # Return -Zero on success # -Non zero on failure # setup() { which dlt-daemon > /dev/null if [ $? -ne '0' ] then echo "dlt-daemon not available" return 1 fi which dlt-example-user > /dev/null if [ $? -ne '0' ] then echo "dlt-example-user not available" return 1 fi which dlt-convert > /dev/null if [ $? -ne '0' ] then echo "dlt-convert not available" return 1 fi mkdir $pathTmp/$folderName if [ $? -ne '0' ] then echo "Error while creating folder tmpDltLog" return 1 fi touch $pathTmp/$folderName/dlt.conf if [ $? -ne '0' ] then echo "Error while creating dlt.conf file" return 1 fi echo "SendContextRegistration = 1" >>$pathTmp/$folderName/dlt.conf echo "ECUId = ECU1" >>$pathTmp/$folderName/dlt.conf echo "SharedMemorySize = 100000" >>$pathTmp/$folderName/dlt.conf echo "LoggingMode = 0" >>$pathTmp/$folderName/dlt.conf echo "LoggingLevel = 6" >>$pathTmp/$folderName/dlt.conf echo "LoggingFilename = /tmp/dlt.log" >>$pathTmp/$folderName/dlt.conf echo "TimeOutOnSend = 4" >>$pathTmp/$folderName/dlt.conf echo "RingbufferMinSize = 500000" >>$pathTmp/$folderName/dlt.conf echo "RingbufferMaxSize = 10000000" >>$pathTmp/$folderName/dlt.conf echo "RingbufferStepSize = 500000" >>$pathTmp/$folderName/dlt.conf echo "ControlSocketPath = /tmp/dlt-ctrl.sock" >>$pathTmp/$folderName/dlt.conf echo "OfflineLogstorageMaxDevices = 2" >>$pathTmp/$folderName/dlt.conf echo "OfflineLogstorageDirPath = $pathTmp/$folderName" >>$pathTmp/$folderName/dlt.conf echo "OfflineLogstorageTimestamp = 1" >>$pathTmp/$folderName/dlt.conf echo "OfflineLogstorageDelimiter = _" >>$pathTmp/$folderName/dlt.conf echo "OfflineLogstorageMaxCounter = 999" >>$pathTmp/$folderName/dlt.conf echo "OfflineLogstorageCacheSize = 30000" >>$pathTmp/$folderName/dlt.conf touch $pathTmp/$folderName/dlt_logstorage.conf if [ $? -ne '0' ] then echo "Error while creating dlt_logstorage.conf file" return 1 fi echo "[FILTER1]" >>$pathTmp/$folderName/dlt_logstorage.conf echo "LogAppName=LOG" >>$pathTmp/$folderName/dlt_logstorage.conf echo "ContextName=TEST" >>$pathTmp/$folderName/dlt_logstorage.conf echo "LogLevel=DLT_LOG_INFO" >>$pathTmp/$folderName/dlt_logstorage.conf echo "File=Test" >>$pathTmp/$folderName/dlt_logstorage.conf echo "FileSize=10000" >>$pathTmp/$folderName/dlt_logstorage.conf echo "NOFiles=1" >>$pathTmp/$folderName/dlt_logstorage.conf return 0 } # # Function: -startDaemonAndApp() # # Description -Kill daemon if it is already running # -Start dlt-daemon # -Start dlt-example-user # # Return -Zero on success # -Non zero on failure # startDaemonAndApp() { dlt-daemon -c $pathTmp/$folderName/dlt.conf -d > /dev/null dlt-example-user test_msg > /dev/null return 0 } # # Function: -verifyTest() # # Description -Verify count of messages # # Return -Zero on success # -Non zero on failure # verifyTest() { ls $pathTmp/$folderName | grep .dlt > /dev/null if [ $? -ne '0' ] then echo "Log file is not present" return 1 fi msgCount=`dlt-convert -c $pathTmp/$folderName/*.dlt` if [ $? -ne '0' ] then echo "Error while reading count in log file" return 1 fi echo $msgCount | grep 10 > /dev/null if [ $? -ne '0' ] then echo "Message count is incorrect" return 1 fi return 0 } ######################################################################################## #main function ######################################################################################## cleanup setup if [ $? -ne '0' ] then echo "Error in function setup()" cleanup return 1 fi startDaemonAndApp if [ $? -ne '0' ] then echo "Error in function startDaemonAndApp()" cleanup return 1 fi verifyTest if [ $? -eq '0' ] then echo "Test Passed" else echo "Test Failed" fi cleanup dlt-daemon-2.18.4/tests/start_multinode_test.sh000077500000000000000000000234671353342203500216230ustar00rootroot00000000000000#!/bin/sh ################################################################################ # SPDX license identifier: MPL-2.0 # # Copyright (C) 2016, Advanced Driver Information Technology # This code is developed by Advanced Driver Information Technology. # Copyright of Advanced Driver Information Technology, Bosch and DENSO. # # This file is part of GENIVI Project DLT - Diagnostic Log and Trace. # # This Source Code Form is subject to the terms of the # Mozilla Public License (MPL), v. 2.0. # If a copy of the MPL was not distributed with this file, # You can obtain one at http://mozilla.org/MPL/2.0/. # # For further information see http://www.genivi.org/. ################################################################################ ################################################################################ #file : dlt_multinode_test.sh # #Description : Smoke testing for multinode feature of DLT # #Author Name : Onkar Palkar # Jeevan Ramakant Nagvekar #Email Id : onkar.palkar@wipro.com # jeevan.nagvekar1@wipro.com # #History : 31/07/2018 ################################################################################ ipaddr=127.0.0.1 # # Function: -getOSname() # # Description -Retrieves OS name # getOSname() { OS="`uname`" } # # Function: -cleanup() # # Description -Delete the dlt_test folder if it already present # -Check weather required binaries are avaiable or not # -Restore dlt_gateway.conf file # # Return -Zero on success # -Non zero on failure # cleanup() { tmpPath=/tmp tmpFolder=dlt_test gatewayFolderName=gateway passiveFolderName=passive tmpPassiveDIR=tmpPassive tmpLogFile=log_multinode.txt tmpLogAsciFile=log_multinode_a.txt if [ "$OS" = "QNX" ] then PIDOF() { slay -p $1 > /dev/null if [ $? -eq '0' ] then return 1 else return 0 fi } KILLALL() { slay -9 -f $1 > /dev/null if [ $? -eq '0' ] then return 1 else return 0 fi } else PIDOF() { pidof $1 > /dev/null return $? } KILLALL() { killall $1 > /dev/null return $? } fi cd $tmpPath PIDOF "dlt-daemon" if [ $? -eq '0' ] then KILLALL "dlt-daemon" if [ $? -ne '0' ] then echo "Failed to kill daemons" return 1 fi fi PIDOF "dlt-receive" if [ $? -eq '0' ] then KILLALL "dlt-receive" if [ $? -ne '0' ] then echo "Failed to kill dlt-receive" return 1 fi fi PIDOF "dlt-convert" if [ $? -eq '0' ] then KILLALL "dlt-convert" if [ $? -ne '0' ] then echo "Failed to kill dlt-convert" return 1 fi fi rm -rf $tmpPath/$tmpFolder >/dev/null return 0 } # # Function: -setupTest() # # Description -Create one gateway and passive folder # -Create and add dlt.conf and dlt_gateway.conf file in the gateway folder # -Create and add dlt.conf file in the passive folder # # Return -Zero on success # -Non zero on failure # setupTest() { which dlt-daemon > /dev/null if [ $? -ne '0' ] then echo "dlt-daemon is not available" return 1 fi which dlt-example-user > /dev/null if [ $? -ne '0' ] then echo "dlt-example-user is not available" return 1 fi which dlt-receive > /dev/null if [ $? -ne '0' ] then echo "dlt-receive is not available" return 1 fi mkdir -p $tmpPath/$tmpFolder if [ $? -ne '0' ] then echo "Error in creating dlt_test folder" return 1 fi mkdir -p $tmpPath/$tmpFolder/$gatewayFolderName if [ $? -ne '0' ] then echo "Error in creating gateway folder" return 1 fi touch $tmpPath/$tmpFolder/$gatewayFolderName/dlt.conf if [ $? -ne '0' ] then echo "Error in creating dlt.conf file" return 1 fi echo "SendContextRegistration = 1" >>$tmpPath/$tmpFolder/$gatewayFolderName/dlt.conf echo "ECUId = ECU1" >>$tmpPath/$tmpFolder/$gatewayFolderName/dlt.conf echo "GatewayMode = 1" >>$tmpPath/$tmpFolder/$gatewayFolderName/dlt.conf echo "SharedMemorySize = 100000" >>$tmpPath/$tmpFolder/$gatewayFolderName/dlt.conf echo "LoggingMode = 0" >>$tmpPath/$tmpFolder/$gatewayFolderName/dlt.conf echo "LoggingLevel = 6" >>$tmpPath/$tmpFolder/$gatewayFolderName/dlt.conf echo "LoggingFilename = /tmp/dlt.log" >>$tmpPath/$tmpFolder/$gatewayFolderName/dlt.conf echo "TimeOutOnSend = 4" >>$tmpPath/$tmpFolder/$gatewayFolderName/dlt.conf echo "RingbufferMinSize = 500000" >>$tmpPath/$tmpFolder/$gatewayFolderName/dlt.conf echo "RingbufferMaxSize = 10000000" >>$tmpPath/$tmpFolder/$gatewayFolderName/dlt.conf echo "RingbufferStepSize = 500000" >>$tmpPath/$tmpFolder/$gatewayFolderName/dlt.conf echo "ControlSocketPath = /tmp/dlt-ctrl.sock" >>$tmpPath/$tmpFolder/$gatewayFolderName/dlt.conf echo "GatewayConfigFile = $tmpPath/$tmpFolder/$gatewayFolderName/dlt_gateway.conf" >> $tmpPath/$tmpFolder/$gatewayFolderName/dlt.conf touch $tmpPath/$tmpFolder/$gatewayFolderName/dlt_gateway.conf if [ $? -ne '0' ] then echo "Error in creating dlt_gateway file" return 1 fi echo "[PassiveNode1]" >>$tmpPath/$tmpFolder/$gatewayFolderName/dlt_gateway.conf echo "IPaddress=$ipaddr">>$tmpPath/$tmpFolder/$gatewayFolderName/dlt_gateway.conf echo "Port=3495" >>$tmpPath/$tmpFolder/$gatewayFolderName/dlt_gateway.conf echo "EcuID=ECU2" >>$tmpPath/$tmpFolder/$gatewayFolderName/dlt_gateway.conf echo "Connect=OnStartup" >>$tmpPath/$tmpFolder/$gatewayFolderName/dlt_gateway.conf echo "Timeout=10" >>$tmpPath/$tmpFolder/$gatewayFolderName/dlt_gateway.conf echo "NOFiles=1" >>$tmpPath/$tmpFolder/$gatewayFolderName/dlt_gateway.conf mkdir -p $tmpPath/$tmpFolder/$passiveFolderName if [ $? -ne '0' ] then echo "Error in creating passive folder" return 1 fi touch $tmpPath/$tmpFolder/$passiveFolderName/dlt.conf if [ $? -ne '0' ] then echo "Error in creating dlt.conf file" return 1 fi echo "SendContextRegistration = 1" >>$tmpPath/$tmpFolder/$passiveFolderName/dlt.conf echo "ECUId = ECU2" >>$tmpPath/$tmpFolder/$passiveFolderName/dlt.conf echo "SharedMemorySize = 100000" >>$tmpPath/$tmpFolder/$passiveFolderName/dlt.conf echo "LoggingMode = 0" >>$tmpPath/$tmpFolder/$passiveFolderName/dlt.conf echo "LoggingLevel = 6" >>$tmpPath/$tmpFolder/$passiveFolderName/dlt.conf echo "LoggingFilename = /tmp/dlt.log" >>$tmpPath/$tmpFolder/$passiveFolderName/dlt.conf echo "TimeOutOnSend = 4" >>$tmpPath/$tmpFolder/$passiveFolderName/dlt.conf echo "RingbufferMinSize = 500000" >>$tmpPath/$tmpFolder/$passiveFolderName/dlt.conf echo "RingbufferMaxSize = 10000000" >>$tmpPath/$tmpFolder/$passiveFolderName/dlt.conf echo "RingbufferStepSize = 500000" >>$tmpPath/$tmpFolder/$passiveFolderName/dlt.conf echo "ControlSocketPath = /tmp/dlt-ctrl.sock" >>$tmpPath/$tmpFolder/$passiveFolderName/dlt.conf mkdir -p $tmpPath/$tmpFolder/$tmpPassiveDIR if [ $? -ne '0' ] then echo "Error while creating tempPassive folder" return 1 fi return 0 } # # Function: -startDaemons() # # Description -Start dlt-daemon as passive node # -Start dlt-daemon as gateway node # # Return -Zero on success # -Non zero on failure # startDaemons() { dlt-daemon -c $tmpPath/$tmpFolder/$passiveFolderName/dlt.conf -p 3495 -t $tmpPath/$tmpFolder/$tmpPassiveDIR -d > /dev/null dlt-daemon -c $tmpPath/$tmpFolder/$gatewayFolderName/dlt.conf -p 3490 -d > /dev/null return 0 } # # Function: -startExample() # # Description -Start dlt-example-user on passive node # # Return -Zero on success # -Non zero on failure # startExample() { export DLT_PIPE_DIR=$tmpPath/$tmpFolder/$tmpPassiveDIR dlt-example-user MultiNodeTesting > /dev/null & return 0 } # # Function: -starReceive() # # Description -Start dlt-receive # # Return -Zero on success # -Non zero on failure # startReceive() { dlt-receive -o $tmpPath/$tmpFolder/$tmpLogFile localhost & return 0 } # # Function: -verifyTest() # # Description -Start dlt-convert # -check weather msg sent by passive node are available in logs or not # # Return -Zero on success # -Non zero on failure # verifyTest() { dlt-convert -a $tmpPath/$tmpFolder/$tmpLogFile > $tmpPath/$tmpFolder/$tmpLogAsciFile cat $tmpPath/$tmpFolder/$tmpLogAsciFile | grep -F "ECU2" > /dev/null if [ $? -eq '0' ] then return 0 else return 1 fi } #main function ######################################################################################## getOSname cleanup if [ $? -ne '0' ] then echo "getIpAdd() failed" cleanup return 1 fi setupTest if [ $? -ne '0' ] then echo "setupTest() failed" cleanup return 1 fi startDaemons if [ $? -ne '0' ] then echo "startDaemons() failed" cleanup return 1 fi startExample if [ $? -ne '0' ] then echo "startExample() failed" cleanup return 1 fi #wait for 1 sec before starting dlt-receive to start dlt-example-user application properly sleep 1 startReceive if [ $? -ne '0' ] then echo "startReceive() failed" cleanup return 1 fi #Wait for 1 sec to collect messages sent by application at gateway sleep 1 verifyTest if [ $? -eq '0' ] then echo "Test Passed" else echo "Test Failed" fi cleanup dlt-daemon-2.18.4/tests/start_system_logger_test.sh000077500000000000000000000023401353342203500224710ustar00rootroot00000000000000#!/bin/bash #enable logging of files and setup sudo sed -i 's/LogFileEnable = 0/LogFileEnable = 1/g' /usr/local/etc/dlt-system.conf echo "# TEST LOG TO SYSTEMLOGGER_PROC" | sudo tee -a /usr/local/etc/dlt-system.conf echo "LogFileFilename = /proc/systemlogger" | sudo tee -a /usr/local/etc/dlt-system.conf echo "LogFileMode = 1" | sudo tee -a /usr/local/etc/dlt-system.conf echo "LogFileTimeDelay = 3" | sudo tee -a /usr/local/etc/dlt-system.conf echo "LogFileContextId = PROC" | sudo tee -a /usr/local/etc/dlt-system.conf #comile the kernel module for system logging cd mod_system_logger make cd .. #enable mod sudo insmod mod_system_logger/mod_system_logger.ko #start dlt-daemon dlt-daemon & sleep 1 #start dlt-system dlt-system & sleep 1 #start dlt-receiver ../build/tests/dlt_test_receiver -l localhost & sleep 1 pid=$! wait $pid exitcode=$? #kill processes and remove mod pkill dlt-daemon pkill dlt-system sudo rmmod mod_system_logger cd mod_system_logger make clean cd .. # if exit code == 159 , test successfull tput setaf 1 if [ $exitcode == 159 ]; then echo "System Logger tests successfull." else echo "System Logger tests failed." echo "Maybe missing kernel-heaers" echo "for compiling the test module" fi tput setaf 7 dlt-daemon-2.18.4/tests/start_systemd_journal_test.sh000077500000000000000000000015731353342203500230370ustar00rootroot00000000000000#!/bin/bash #build and install with SYSTEMD_JOURNAL=ON mkdir ../build cd ../build/ cmake -DWITH_SYSTEMD_JOURNAL=ON -DWITH_DLT_UNIT_TESTS=ON .. make sudo make install #enable SYSTEMD_JOURNAL in config file sudo vim -esnc '%s/JournalEnable = 0/JournalEnable = 1/g|:wq' /usr/local/etc/dlt-system.conf #start dlt-daemon dlt-daemon & sleep 1 #start dlt_system sudo dlt-system & sleep 1 #send 10 times "DLT SYSTEM JOURNAL TEST" for i in {1..1000} do logger DLT SYSTEM JOURNAL TEST done #start receiver ./../build/tests/dlt_test_receiver -s localhost & sleep 1 pid=$! wait $pid exitcode=$? # kill processes, receiver automatically killed with daemon pkill dlt-daemon sudo pkill dlt-system # if exit code == 159 , test successfull tput setaf 1 if [ $exitcode == 159 ]; then echo "Systemd Journal tests successfull." else echo "Systemd Journal tests failed." fi tput setaf 7 dlt-daemon-2.18.4/tests/testfile.dlt000066400000000000000000000105721353342203500173250ustar00rootroot00000000000000DLT&,Mآ ECU5ECU?b:APPCONremoDLT&,Mآ ECU5ECU?b:APPCONremoDLT&,Mآ ECU5ECU?b:APPCON DLT&,Mآ ECU5ECU?b:APPCON DLT+,MzECU!ALOGTES1DLT+,MzECU!ALOGTES1BDLT+,MzECU!ALOGTES1 Hello BMWDLT+,MzECU!ALOGTES2AeDLT+,MzECU!ALOGTES2BfDLT+,MzECU!ALOGTES2CgDLT+,MzECU!ALOGTES2DhDLT+,MzECU!ALOGTES2!iDLT+,MzECU!ALOGTES2"jDLT+,MzECU!ALOGTES2#kDLT+,MzECU!ALOGTES2$lDLT+,MzECU!ALOGTES2#mDLT+,MzECU! ALOGTES2CnDLT+,MzECU! ALOGTES2oDLT+,MzECU! 'ALOGTES2STRING 112 messageDLT+,MzECU! (ALOGTES2CSTRING 113 messageDLT+,MzECU! ALOGTES2̌?DLT+,MzECU!ALOGTES2333333?DLT+,MzECU! ALOGTES2 Hello worldDLT,,MHECU!ALOGTES3DLT,,MHECU!ALOGTES3#DLT,,MHECU!ALOGTES3## DLT,,MHECU!&ALOGTES3#)#*#+DLT,,MHECU!.ALOGTES3#3#4#5#6DLT,,MHECU!6ALOGTES3#=#>#?#@#ADLT,,MHECU!>ALOGTES3#G#H#I#J#K#LDLT-,MECU!(ALOGTES4# Hello worldDLT-,MECU!(ALOGTES4# Hello worldDLT-,MECU!(ALOGTES4# Hello worldDLT-,MECU!(ALOGTES4# Hello worldDLT-,MECU!(ALOGTES4# Hello worldDLT-,MECU!(ALOGTES4# Hello worldDLT-,MECU!(ALOGTES4# Hello worldDLT-,MECU!(ALOGTES4# Hello worldDLT-,MECU!(ALOGTES4# Hello worldDLT-,MECU! (ALOGTES4#  Hello worldDLT-,MECU! (ALOGTES4#  Hello worldDLT-,MECU! (ALOGTES4#  Hello worldDLT-,MECU! (ALOGTES4#  Hello worldDLT-,MECU! (ALOGTES4#  Hello worldDLT-,MECU!(ALOGTES4# Hello worldDLT-,MECU!(ALOGTES4# Hello worldDLT-,MECU!(ALOGTES4# Hello worldDLT-,MECU!(ALOGTES4# Hello worldDLT4,M@ECU5ECU?o&APPCONremoDLT4,M@ECU5ECU?o&APPCONremoDLT4,M@ECU5ECU?o&APPCON DLT4,M@ECU5ECU?o&APPCON DLT7,M1ECU eDLT7,M1ECU  fDLT7,M1ECU g Hello BMWDLT7,M1ECU eDLT7,M1ECU  fDLT7,M1ECU  gDLT7,M1ECU hDLT7,M1ECU  iDLT7,M1ECU  jDLT7,M1ECU  kDLT7,M1ECU lDLT7,M1ECU  mDLT7,M1ECU nDLT7,M1ECU oDLT7,M1ECU STRING 112 messageDLT7,M1ECU CSTRING 113 messageDLT7,M1ECU ̌?DLT7,M1ECU 333333?DLT7,M1ECU  Hello worldDLT8,M3cECU -DLT8,M3cECU  .DLT8,M3cECU / DLT8,M3cECU 0)*+DLT8,M3cECU 13456DLT8,M3cECU 1=>?@ADLT8,M3cECU  1GHIJKLDLT9,MECU  Hello worldDLT9,MECU  Hello worldDLT9,MECU  Hello worldDLT9,MECU  Hello worldDLT9,MECU  Hello worldDLT9,MECU  Hello worldDLT9,MECU  Hello worldDLT9,MECU  Hello worldDLT9,MECU  Hello worldDLT9,MECU  Hello worldDLT9,MECU  Hello worldDLT9,MECU  Hello worldDLT9,MECU  Hello worldDLT9,MECU  Hello worldDLT9,MECU  Hello worldDLT9,MECU  Hello worldDLT9,MECU  Hello worldDLT9,MECU  Hello worldDLT9,MECU  Hello worldDLT9,MECU  Hello worldDLT9,MECU  Hello worldDLT9,MECU  Hello worldDLT9,MECU  Hello worldDLT9,MECU  Hello worldDLT9,MECU  Hello worldDLT9,MECU  Hello worldDLT9,MECU  Hello worlddlt-daemon-2.18.4/tests/testfile_filetransfer.txt000066400000000000000000000001161353342203500221160ustar00rootroot00000000000000TEST DATEI. 123. qwertzuiopü+ asdfghjklöä# # Description: # <...> # <...> ### END INIT INFO # Author: root # PATH should only include /usr/* if it runs after the mountnfs.sh script PATH=/sbin:/usr/sbin:/bin:/usr/bin DESC=dlt-daemon # Introduce a short description here NAME=dlt-daemon # Introduce the short server's name here DAEMON=@CMAKE_INSTALL_PREFIX@/bin/dlt-daemon # Introduce the server's location here DAEMON_ARGS="-d" # Arguments to run the daemon with PIDFILE=/tmp/dltd.lock # Path is configured with DLT configuration of DLT_USER_DIR/DLT_DAEMON_LOCK_FILE SCRIPTNAME=/etc/init.d/$NAME # Exit if the package is not installed [ -x $DAEMON ] || exit 0 # Read configuration variable file if it is present [ -r /etc/default/$NAME ] && . /etc/default/$NAME # Load the VERBOSE setting and other rcS variables . /lib/init/vars.sh # Define LSB log_* functions. # Depend on lsb-base (>= 3.0-6) to ensure that this file is present. . /lib/lsb/init-functions # # Function that starts the daemon/service # do_start() { # Return # 0 if daemon has been started # 1 if daemon was already running # 2 if daemon could not be started start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON --test > /dev/null \ || return 1 start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON -- \ $DAEMON_ARGS \ || return 2 # Add code here, if necessary, that waits for the process to be ready # to handle requests from services started subsequently which depend # on this one. As a last resort, sleep for some time. } # # Function that stops the daemon/service # do_stop() { # Return # 0 if daemon has been stopped # 1 if daemon was already stopped # 2 if daemon could not be stopped # other if a failure occurred # default: --retry=TERM/30/KILL/5 start-stop-daemon --stop --quiet --retry=TERM/1/KILL/1 --pidfile $PIDFILE --name $NAME RETVAL="$?" [ "$RETVAL" = 2 ] && return 2 # Wait for children to finish too if this is a daemon that forks # and if the daemon is only ever run from this initscript. # If the above conditions are not satisfied then add some other code # that waits for the process to drop all resources that could be # needed by services started subsequently. A last resort is to # sleep for some time. # default: --retry=0/30/KILL/5 start-stop-daemon --stop --quiet --oknodo --retry=0/1/KILL/1 --exec $DAEMON [ "$?" = 2 ] && return 2 # Many daemons don't delete their pidfiles when they exit. rm -f $PIDFILE return "$RETVAL" } # # Function that sends a SIGHUP to the daemon/service # do_reload() { # # If the daemon can reload its configuration without # restarting (for example, when it is sent a SIGHUP), # then implement that here. # start-stop-daemon --stop --signal 1 --quiet --pidfile $PIDFILE --name $NAME return 0 } case "$1" in start) [ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC " "$NAME" do_start case "$?" in 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;; 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;; esac ;; stop) [ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME" do_stop case "$?" in 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;; 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;; esac ;; status) if [ -f /var/log/messages ] then log_daemon_msg "------- messages ----------------" cat /var/log/messages | grep -a DLT | tail fi if [ -f /var/log/syslog ] then log_daemon_msg "------- SYSLOG -------------------" cat /var/log/syslog | grep -a DLT | tail fi pidofdlt=`pidof $DESC` if [ $pidofdlt ] then log_daemon_msg "$NAME has the PID:$pidofdlt" fi status_of_proc "$DAEMON" "$NAME" || exit $? ;; #reload|force-reload) # # If do_reload() is not implemented then leave this commented out # and leave 'force-reload' as an alias for 'restart'. # #log_daemon_msg "Reloading $DESC" "$NAME" #do_reload #log_end_msg $? #;; restart|force-reload) # # If the "reload" option is implemented then remove the # 'force-reload' alias # log_daemon_msg "Restarting $DESC" "$NAME" do_stop case "$?" in 0|1) do_start case "$?" in 0) log_end_msg 0 ;; 1) log_end_msg 1 ;; # Old process is still running *) log_end_msg 1 ;; # Failed to start esac ;; *) # Failed to stop log_end_msg 1 ;; esac ;; *) #echo "Usage: $SCRIPTNAME {start|stop|restart|reload|force-reload}" >&2 echo "Usage: $SCRIPTNAME {start|stop|status|restart|force-reload}" >&2 exit 3 ;; esac : dlt-daemon-2.18.4/util/000077500000000000000000000000001353342203500146075ustar00rootroot00000000000000dlt-daemon-2.18.4/util/uncrustify.cfg000066400000000000000000003226711353342203500175160ustar00rootroot00000000000000# Uncrustify-0.68_f # # General options # # The type of line endings. # # Default: auto newlines = auto # lf/crlf/cr/auto # The original size of tabs in the input. # # Default: 8 input_tab_size = 4 # unsigned number # The size of tabs in the output (only used if align_with_tabs=true). # # Default: 8 output_tab_size = 4 # unsigned number # The ASCII value of the string escape char, usually 92 (\) or (Pawn) 94 (^). # # Default: 92 string_escape_char = 92 # unsigned number # Alternate string escape char (usually only used for Pawn). # Only works right before the quote char. string_escape_char2 = 0 # unsigned number # Replace tab characters found in string literals with the escape sequence \t # instead. string_replace_tab_chars = false # true/false # Allow interpreting '>=' and '>>=' as part of a template in code like # 'void f(list>=val);'. If true, 'assert(x<0 && y>=3)' will be broken. # Improvements to template detection may make this option obsolete. tok_split_gte = false # true/false # Specify the marker used in comments to disable processing of part of the # file. # # Default: *INDENT-OFF* disable_processing_cmt = "" # string # Specify the marker used in comments to (re)enable processing in a file. # # Default: *INDENT-ON* enable_processing_cmt = "" # string # Enable parsing of digraphs. enable_digraphs = false # true/false # Add or remove the UTF-8 BOM (recommend 'remove'). utf8_bom = ignore # ignore/add/remove/force # If the file contains bytes with values between 128 and 255, but is not # UTF-8, then output as UTF-8. utf8_byte = false # true/false # Force the output encoding to UTF-8. utf8_force = false # true/false # # Spacing options # # Add or remove space around non-assignment symbolic operators ('+', '/', '%', # '<<', and so forth). sp_arith = force # ignore/add/remove/force # Add or remove space around arithmetic operators '+' and '-'. # # Overrides sp_arith. sp_arith_additive = ignore # ignore/add/remove/force # Add or remove space around assignment operator '=', '+=', etc. sp_assign = force # ignore/add/remove/force # Add or remove space around '=' in C++11 lambda capture specifications. # # Overrides sp_assign. sp_cpp_lambda_assign = ignore # ignore/add/remove/force # Add or remove space after the capture specification in C++11 lambda. sp_cpp_lambda_paren = ignore # ignore/add/remove/force # Add or remove space around assignment operator '=' in a prototype. sp_assign_default = ignore # ignore/add/remove/force # Add or remove space before assignment operator '=', '+=', etc. # # Overrides sp_assign. sp_before_assign = ignore # ignore/add/remove/force # Add or remove space after assignment operator '=', '+=', etc. # # Overrides sp_assign. sp_after_assign = ignore # ignore/add/remove/force # Add or remove space in 'NS_ENUM ('. sp_enum_paren = ignore # ignore/add/remove/force # Add or remove space around assignment '=' in enum. sp_enum_assign = force # ignore/add/remove/force # Add or remove space before assignment '=' in enum. # # Overrides sp_enum_assign. sp_enum_before_assign = ignore # ignore/add/remove/force # Add or remove space after assignment '=' in enum. # # Overrides sp_enum_assign. sp_enum_after_assign = ignore # ignore/add/remove/force # Add or remove space around assignment ':' in enum. sp_enum_colon = ignore # ignore/add/remove/force # Add or remove space around preprocessor '##' concatenation operator. # # Default: add sp_pp_concat = ignore # ignore/add/remove/force # Add or remove space after preprocessor '#' stringify operator. # Also affects the '#@' charizing operator. sp_pp_stringify = ignore # ignore/add/remove/force # Add or remove space before preprocessor '#' stringify operator # as in '#define x(y) L#y'. sp_before_pp_stringify = ignore # ignore/add/remove/force # Add or remove space around boolean operators '&&' and '||'. sp_bool = force # ignore/add/remove/force # Add or remove space around compare operator '<', '>', '==', etc. sp_compare = force # ignore/add/remove/force # Add or remove space inside '(' and ')'. sp_inside_paren = remove # ignore/add/remove/force # Add or remove space between nested parentheses, i.e. '((' vs. ') )'. sp_paren_paren = remove # ignore/add/remove/force # Add or remove space between back-to-back parentheses, i.e. ')(' vs. ') ('. sp_cparen_oparen = ignore # ignore/add/remove/force # Whether to balance spaces inside nested parentheses. sp_balance_nested_parens = false # true/false # Add or remove space between ')' and '{'. sp_paren_brace = force # ignore/add/remove/force # Add or remove space between nested braces, i.e. '{{' vs '{ {'. sp_brace_brace = ignore # ignore/add/remove/force # Add or remove space before pointer star '*'. sp_before_ptr_star = force # ignore/add/remove/force # Add or remove space before pointer star '*' that isn't followed by a # variable name. If set to 'ignore', sp_before_ptr_star is used instead. sp_before_unnamed_ptr_star = force # ignore/add/remove/force # Add or remove space between pointer stars '*'. sp_between_ptr_star = remove # ignore/add/remove/force # Add or remove space after pointer star '*', if followed by a word. sp_after_ptr_star = remove # ignore/add/remove/force # Add or remove space after pointer caret '^', if followed by a word. sp_after_ptr_block_caret = ignore # ignore/add/remove/force # Add or remove space after pointer star '*', if followed by a qualifier. sp_after_ptr_star_qualifier = ignore # ignore/add/remove/force # Add or remove space after a pointer star '*', if followed by a function # prototype or function definition. sp_after_ptr_star_func = remove # ignore/add/remove/force # Add or remove space after a pointer star '*', if followed by an open # parenthesis, as in 'void* (*)(). sp_ptr_star_paren = ignore # ignore/add/remove/force # Add or remove space before a pointer star '*', if followed by a function # prototype or function definition. sp_before_ptr_star_func = add # ignore/add/remove/force # Add or remove space before a reference sign '&'. sp_before_byref = add # ignore/add/remove/force # Add or remove space before a reference sign '&' that isn't followed by a # variable name. If set to 'ignore', sp_before_byref is used instead. sp_before_unnamed_byref = add # ignore/add/remove/force # Add or remove space after reference sign '&', if followed by a word. sp_after_byref = remove # ignore/add/remove/force # Add or remove space after a reference sign '&', if followed by a function # prototype or function definition. sp_after_byref_func = remove # ignore/add/remove/force # Add or remove space before a reference sign '&', if followed by a function # prototype or function definition. sp_before_byref_func = add # ignore/add/remove/force # Add or remove space between type and word. # # Default: force sp_after_type = force # ignore/add/remove/force # Add or remove space between 'decltype(...)' and word. sp_after_decltype = ignore # ignore/add/remove/force # (D) Add or remove space before the parenthesis in the D constructs # 'template Foo(' and 'class Foo('. sp_before_template_paren = ignore # ignore/add/remove/force # Add or remove space between 'template' and '<'. # If set to ignore, sp_before_angle is used. sp_template_angle = ignore # ignore/add/remove/force # Add or remove space before '<'. sp_before_angle = ignore # ignore/add/remove/force # Add or remove space inside '<' and '>'. sp_inside_angle = ignore # ignore/add/remove/force # Add or remove space between '>' and ':'. sp_angle_colon = ignore # ignore/add/remove/force # Add or remove space after '<>'. sp_after_angle = ignore # ignore/add/remove/force # Add or remove space between '>' and '(' as found in 'new List(foo);'. sp_angle_paren = ignore # ignore/add/remove/force # Add or remove space between '>' and '()' as found in 'new List();'. sp_angle_paren_empty = ignore # ignore/add/remove/force # Add or remove space between '>' and a word as in 'List m;' or # 'template static ...'. sp_angle_word = ignore # ignore/add/remove/force # Add or remove space between '>' and '>' in '>>' (template stuff). # # Default: add sp_angle_shift = add # ignore/add/remove/force # (C++11) Permit removal of the space between '>>' in 'foo >'. Note # that sp_angle_shift cannot remove the space without this option. sp_permit_cpp11_shift = false # true/false # Add or remove space before '(' of control statements ('if', 'for', 'switch', # 'while', etc.). sp_before_sparen = force # ignore/add/remove/force # Add or remove space inside '(' and ')' of control statements. sp_inside_sparen = remove # ignore/add/remove/force # Add or remove space after '(' of control statements. # # Overrides sp_inside_sparen. sp_inside_sparen_open = ignore # ignore/add/remove/force # Add or remove space before ')' of control statements. # # Overrides sp_inside_sparen. sp_inside_sparen_close = ignore # ignore/add/remove/force # Add or remove space after ')' of control statements. sp_after_sparen = force # ignore/add/remove/force # Add or remove space between ')' and '{' of of control statements. sp_sparen_brace = force # ignore/add/remove/force # (D) Add or remove space between 'invariant' and '('. sp_invariant_paren = ignore # ignore/add/remove/force # (D) Add or remove space after the ')' in 'invariant (C) c'. sp_after_invariant_paren = ignore # ignore/add/remove/force # Add or remove space before empty statement ';' on 'if', 'for' and 'while'. sp_special_semi = remove # ignore/add/remove/force # Add or remove space before ';'. # # Default: remove sp_before_semi = remove # ignore/add/remove/force # Add or remove space before ';' in non-empty 'for' statements. sp_before_semi_for = remove # ignore/add/remove/force # Add or remove space before a semicolon of an empty part of a for statement. sp_before_semi_for_empty = ignore # ignore/add/remove/force # Add or remove space after ';', except when followed by a comment. # # Default: add sp_after_semi = add # ignore/add/remove/force # Add or remove space after ';' in non-empty 'for' statements. # # Default: force sp_after_semi_for = force # ignore/add/remove/force # Add or remove space after the final semicolon of an empty part of a for # statement, as in 'for ( ; ; )'. sp_after_semi_for_empty = ignore # ignore/add/remove/force # Add or remove space before '[' (except '[]'). sp_before_square = ignore # ignore/add/remove/force # Add or remove space before '[]'. sp_before_squares = remove # ignore/add/remove/force # Add or remove space before C++17 structured bindings. sp_cpp_before_struct_binding = ignore # ignore/add/remove/force # Add or remove space inside a non-empty '[' and ']'. sp_inside_square = remove # ignore/add/remove/force # (OC) Add or remove space inside a non-empty Objective-C boxed array '@[' and # ']'. If set to ignore, sp_inside_square is used. sp_inside_square_oc_array = ignore # ignore/add/remove/force # Add or remove space after ',', i.e. 'a,b' vs. 'a, b'. sp_after_comma = force # ignore/add/remove/force # Add or remove space before ','. # # Default: remove sp_before_comma = remove # ignore/add/remove/force # (C#) Add or remove space between ',' and ']' in multidimensional array type # like 'int[,,]'. sp_after_mdatype_commas = ignore # ignore/add/remove/force # (C#) Add or remove space between '[' and ',' in multidimensional array type # like 'int[,,]'. sp_before_mdatype_commas = ignore # ignore/add/remove/force # (C#) Add or remove space between ',' in multidimensional array type # like 'int[,,]'. sp_between_mdatype_commas = ignore # ignore/add/remove/force # Add or remove space between an open parenthesis and comma, # i.e. '(,' vs. '( ,'. # # Default: force sp_paren_comma = force # ignore/add/remove/force # Add or remove space before the variadic '...' when preceded by a # non-punctuator. sp_before_ellipsis = ignore # ignore/add/remove/force # Add or remove space between a type and '...'. sp_type_ellipsis = ignore # ignore/add/remove/force # Add or remove space between ')' and '...'. sp_paren_ellipsis = ignore # ignore/add/remove/force # Add or remove space after class ':'. sp_after_class_colon = ignore # ignore/add/remove/force # Add or remove space before class ':'. sp_before_class_colon = ignore # ignore/add/remove/force # Add or remove space after class constructor ':'. sp_after_constr_colon = ignore # ignore/add/remove/force # Add or remove space before class constructor ':'. sp_before_constr_colon = ignore # ignore/add/remove/force # Add or remove space before case ':'. # # Default: remove sp_before_case_colon = remove # ignore/add/remove/force # Add or remove space between 'operator' and operator sign. sp_after_operator = ignore # ignore/add/remove/force # Add or remove space between the operator symbol and the open parenthesis, as # in 'operator ++('. sp_after_operator_sym = ignore # ignore/add/remove/force # Overrides sp_after_operator_sym when the operator has no arguments, as in # 'operator *()'. sp_after_operator_sym_empty = ignore # ignore/add/remove/force # Add or remove space after C/D cast, i.e. 'cast(int)a' vs. 'cast(int) a' or # '(int)a' vs. '(int) a'. sp_after_cast = remove # ignore/add/remove/force # Add or remove spaces inside cast parentheses. sp_inside_paren_cast = remove # ignore/add/remove/force # Add or remove space between the type and open parenthesis in a C++ cast, # i.e. 'int(exp)' vs. 'int (exp)'. sp_cpp_cast_paren = ignore # ignore/add/remove/force # Add or remove space between 'sizeof' and '('. sp_sizeof_paren = ignore # ignore/add/remove/force # Add or remove space between 'sizeof' and '...'. sp_sizeof_ellipsis = ignore # ignore/add/remove/force # Add or remove space between 'sizeof...' and '('. sp_sizeof_ellipsis_paren = ignore # ignore/add/remove/force # Add or remove space between 'decltype' and '('. sp_decltype_paren = ignore # ignore/add/remove/force # (Pawn) Add or remove space after the tag keyword. sp_after_tag = ignore # ignore/add/remove/force # Add or remove space inside enum '{' and '}'. sp_inside_braces_enum = ignore # ignore/add/remove/force # Add or remove space inside struct/union '{' and '}'. sp_inside_braces_struct = ignore # ignore/add/remove/force # (OC) Add or remove space inside Objective-C boxed dictionary '{' and '}' sp_inside_braces_oc_dict = ignore # ignore/add/remove/force # Add or remove space after open brace in an unnamed temporary # direct-list-initialization. sp_after_type_brace_init_lst_open = ignore # ignore/add/remove/force # Add or remove space before close brace in an unnamed temporary # direct-list-initialization. sp_before_type_brace_init_lst_close = ignore # ignore/add/remove/force # Add or remove space inside an unnamed temporary direct-list-initialization. sp_inside_type_brace_init_lst = ignore # ignore/add/remove/force # Add or remove space inside '{' and '}'. sp_inside_braces = force # ignore/add/remove/force # Add or remove space inside '{}'. sp_inside_braces_empty = remove # ignore/add/remove/force # Add or remove space between return type and function name. A minimum of 1 # is forced except for pointer return types. sp_type_func = ignore # ignore/add/remove/force # Add or remove space between type and open brace of an unnamed temporary # direct-list-initialization. sp_type_brace_init_lst = ignore # ignore/add/remove/force # Add or remove space between function name and '(' on function declaration. sp_func_proto_paren = ignore # ignore/add/remove/force # Add or remove space between function name and '()' on function declaration # without parameters. sp_func_proto_paren_empty = ignore # ignore/add/remove/force # Add or remove space between function name and '(' on function definition. sp_func_def_paren = ignore # ignore/add/remove/force # Add or remove space between function name and '()' on function definition # without parameters. sp_func_def_paren_empty = ignore # ignore/add/remove/force # Add or remove space inside empty function '()'. sp_inside_fparens = remove # ignore/add/remove/force # Add or remove space inside function '(' and ')'. sp_inside_fparen = remove # ignore/add/remove/force # Add or remove space inside the first parentheses in a function type, as in # 'void (*x)(...)'. sp_inside_tparen = ignore # ignore/add/remove/force # Add or remove space between the ')' and '(' in a function type, as in # 'void (*x)(...)'. sp_after_tparen_close = ignore # ignore/add/remove/force # Add or remove space between ']' and '(' when part of a function call. sp_square_fparen = ignore # ignore/add/remove/force # Add or remove space between ')' and '{' of function. sp_fparen_brace = force # ignore/add/remove/force # Add or remove space between ')' and '{' of s function call in object # initialization. # # Overrides sp_fparen_brace. sp_fparen_brace_initializer = ignore # ignore/add/remove/force # (Java) Add or remove space between ')' and '{{' of double brace initializer. sp_fparen_dbrace = ignore # ignore/add/remove/force # Add or remove space between function name and '(' on function calls. sp_func_call_paren = ignore # ignore/add/remove/force # Add or remove space between function name and '()' on function calls without # parameters. If set to 'ignore' (the default), sp_func_call_paren is used. sp_func_call_paren_empty = ignore # ignore/add/remove/force # Add or remove space between the user function name and '(' on function # calls. You need to set a keyword to be a user function in the config file, # like: # set func_call_user tr _ i18n sp_func_call_user_paren = ignore # ignore/add/remove/force # Add or remove space inside user function '(' and ')'. sp_func_call_user_inside_fparen = ignore # ignore/add/remove/force # Add or remove space between nested parentheses with user functions, # i.e. '((' vs. '( ('. sp_func_call_user_paren_paren = ignore # ignore/add/remove/force # Add or remove space between a constructor/destructor and the open # parenthesis. sp_func_class_paren = ignore # ignore/add/remove/force # Add or remove space between a constructor without parameters or destructor # and '()'. sp_func_class_paren_empty = ignore # ignore/add/remove/force # Add or remove space between 'return' and '('. sp_return_paren = ignore # ignore/add/remove/force # Add or remove space between 'return' and '{'. sp_return_brace = ignore # ignore/add/remove/force # Add or remove space between '__attribute__' and '('. sp_attribute_paren = ignore # ignore/add/remove/force # Add or remove space between 'defined' and '(' in '#if defined (FOO)'. sp_defined_paren = ignore # ignore/add/remove/force # Add or remove space between 'throw' and '(' in 'throw (something)'. sp_throw_paren = ignore # ignore/add/remove/force # Add or remove space between 'throw' and anything other than '(' as in # '@throw [...];'. sp_after_throw = ignore # ignore/add/remove/force # Add or remove space between 'catch' and '(' in 'catch (something) { }'. # If set to ignore, sp_before_sparen is used. sp_catch_paren = ignore # ignore/add/remove/force # (OC) Add or remove space between '@catch' and '(' # in '@catch (something) { }'. If set to ignore, sp_catch_paren is used. sp_oc_catch_paren = ignore # ignore/add/remove/force # (D) Add or remove space between 'version' and '(' # in 'version (something) { }'. If set to ignore, sp_before_sparen is used. sp_version_paren = ignore # ignore/add/remove/force # (D) Add or remove space between 'scope' and '(' # in 'scope (something) { }'. If set to ignore, sp_before_sparen is used. sp_scope_paren = ignore # ignore/add/remove/force # Add or remove space between 'super' and '(' in 'super (something)'. # # Default: remove sp_super_paren = remove # ignore/add/remove/force # Add or remove space between 'this' and '(' in 'this (something)'. # # Default: remove sp_this_paren = remove # ignore/add/remove/force # Add or remove space between a macro name and its definition. sp_macro = ignore # ignore/add/remove/force # Add or remove space between a macro function ')' and its definition. sp_macro_func = ignore # ignore/add/remove/force # Add or remove space between 'else' and '{' if on the same line. sp_else_brace = force # ignore/add/remove/force # Add or remove space between '}' and 'else' if on the same line. sp_brace_else = force # ignore/add/remove/force # Add or remove space between '}' and the name of a typedef on the same line. sp_brace_typedef = force # ignore/add/remove/force # Add or remove space before the '{' of a 'catch' statement, if the '{' and # 'catch' are on the same line, as in 'catch (decl) {'. sp_catch_brace = force # ignore/add/remove/force # (OC) Add or remove space before the '{' of a '@catch' statement, if the '{' # and '@catch' are on the same line, as in '@catch (decl) {'. # If set to ignore, sp_catch_brace is used. sp_oc_catch_brace = ignore # ignore/add/remove/force # Add or remove space between '}' and 'catch' if on the same line. sp_brace_catch = force # ignore/add/remove/force # (OC) Add or remove space between '}' and '@catch' if on the same line. # If set to ignore, sp_brace_catch is used. sp_oc_brace_catch = ignore # ignore/add/remove/force # Add or remove space between 'finally' and '{' if on the same line. sp_finally_brace = ignore # ignore/add/remove/force # Add or remove space between '}' and 'finally' if on the same line. sp_brace_finally = ignore # ignore/add/remove/force # Add or remove space between 'try' and '{' if on the same line. sp_try_brace = ignore # ignore/add/remove/force # Add or remove space between get/set and '{' if on the same line. sp_getset_brace = ignore # ignore/add/remove/force # Add or remove space between a variable and '{' for C++ uniform # initialization. # # Default: add sp_word_brace = add # ignore/add/remove/force # Add or remove space between a variable and '{' for a namespace. # # Default: add sp_word_brace_ns = add # ignore/add/remove/force # Add or remove space before the '::' operator. sp_before_dc = ignore # ignore/add/remove/force # Add or remove space after the '::' operator. sp_after_dc = ignore # ignore/add/remove/force # (D) Add or remove around the D named array initializer ':' operator. sp_d_array_colon = ignore # ignore/add/remove/force # Add or remove space after the '!' (not) unary operator. # # Default: remove sp_not = remove # ignore/add/remove/force # Add or remove space after the '~' (invert) unary operator. # # Default: remove sp_inv = remove # ignore/add/remove/force # Add or remove space after the '&' (address-of) unary operator. This does not # affect the spacing after a '&' that is part of a type. # # Default: remove sp_addr = remove # ignore/add/remove/force # Add or remove space around the '.' or '->' operators. # # Default: remove sp_member = remove # ignore/add/remove/force # Add or remove space after the '*' (dereference) unary operator. This does # not affect the spacing after a '*' that is part of a type. # # Default: remove sp_deref = remove # ignore/add/remove/force # Add or remove space after '+' or '-', as in 'x = -5' or 'y = +7'. # # Default: remove sp_sign = remove # ignore/add/remove/force # Add or remove space between '++' and '--' the word to which it is being # applied, as in '(--x)' or 'y++;'. # # Default: remove sp_incdec = remove # ignore/add/remove/force # Add or remove space before a backslash-newline at the end of a line. # # Default: add sp_before_nl_cont = add # ignore/add/remove/force # (OC) Add or remove space after the scope '+' or '-', as in '-(void) foo;' # or '+(int) bar;'. sp_after_oc_scope = ignore # ignore/add/remove/force # (OC) Add or remove space after the colon in message specs, # i.e. '-(int) f:(int) x;' vs. '-(int) f: (int) x;'. sp_after_oc_colon = ignore # ignore/add/remove/force # (OC) Add or remove space before the colon in message specs, # i.e. '-(int) f: (int) x;' vs. '-(int) f : (int) x;'. sp_before_oc_colon = ignore # ignore/add/remove/force # (OC) Add or remove space after the colon in immutable dictionary expression # 'NSDictionary *test = @{@"foo" :@"bar"};'. sp_after_oc_dict_colon = ignore # ignore/add/remove/force # (OC) Add or remove space before the colon in immutable dictionary expression # 'NSDictionary *test = @{@"foo" :@"bar"};'. sp_before_oc_dict_colon = ignore # ignore/add/remove/force # (OC) Add or remove space after the colon in message specs, # i.e. '[object setValue:1];' vs. '[object setValue: 1];'. sp_after_send_oc_colon = ignore # ignore/add/remove/force # (OC) Add or remove space before the colon in message specs, # i.e. '[object setValue:1];' vs. '[object setValue :1];'. sp_before_send_oc_colon = ignore # ignore/add/remove/force # (OC) Add or remove space after the (type) in message specs, # i.e. '-(int)f: (int) x;' vs. '-(int)f: (int)x;'. sp_after_oc_type = ignore # ignore/add/remove/force # (OC) Add or remove space after the first (type) in message specs, # i.e. '-(int) f:(int)x;' vs. '-(int)f:(int)x;'. sp_after_oc_return_type = ignore # ignore/add/remove/force # (OC) Add or remove space between '@selector' and '(', # i.e. '@selector(msgName)' vs. '@selector (msgName)'. # Also applies to '@protocol()' constructs. sp_after_oc_at_sel = ignore # ignore/add/remove/force # (OC) Add or remove space between '@selector(x)' and the following word, # i.e. '@selector(foo) a:' vs. '@selector(foo)a:'. sp_after_oc_at_sel_parens = ignore # ignore/add/remove/force # (OC) Add or remove space inside '@selector' parentheses, # i.e. '@selector(foo)' vs. '@selector( foo )'. # Also applies to '@protocol()' constructs. sp_inside_oc_at_sel_parens = ignore # ignore/add/remove/force # (OC) Add or remove space before a block pointer caret, # i.e. '^int (int arg){...}' vs. ' ^int (int arg){...}'. sp_before_oc_block_caret = ignore # ignore/add/remove/force # (OC) Add or remove space after a block pointer caret, # i.e. '^int (int arg){...}' vs. '^ int (int arg){...}'. sp_after_oc_block_caret = ignore # ignore/add/remove/force # (OC) Add or remove space between the receiver and selector in a message, # as in '[receiver selector ...]'. sp_after_oc_msg_receiver = ignore # ignore/add/remove/force # (OC) Add or remove space after '@property'. sp_after_oc_property = ignore # ignore/add/remove/force # (OC) Add or remove space between '@synchronized' and the open parenthesis, # i.e. '@synchronized(foo)' vs. '@synchronized (foo)'. sp_after_oc_synchronized = ignore # ignore/add/remove/force # Add or remove space around the ':' in 'b ? t : f'. sp_cond_colon = ignore # ignore/add/remove/force # Add or remove space before the ':' in 'b ? t : f'. # # Overrides sp_cond_colon. sp_cond_colon_before = ignore # ignore/add/remove/force # Add or remove space after the ':' in 'b ? t : f'. # # Overrides sp_cond_colon. sp_cond_colon_after = ignore # ignore/add/remove/force # Add or remove space around the '?' in 'b ? t : f'. sp_cond_question = ignore # ignore/add/remove/force # Add or remove space before the '?' in 'b ? t : f'. # # Overrides sp_cond_question. sp_cond_question_before = ignore # ignore/add/remove/force # Add or remove space after the '?' in 'b ? t : f'. # # Overrides sp_cond_question. sp_cond_question_after = ignore # ignore/add/remove/force # In the abbreviated ternary form '(a ?: b)', add or remove space between '?' # and ':'. # # Overrides all other sp_cond_* options. sp_cond_ternary_short = ignore # ignore/add/remove/force # Fix the spacing between 'case' and the label. Only 'ignore' and 'force' make # sense here. sp_case_label = ignore # ignore/add/remove/force # (D) Add or remove space around the D '..' operator. sp_range = ignore # ignore/add/remove/force # Add or remove space after ':' in a Java/C++11 range-based 'for', # as in 'for (Type var : expr)'. sp_after_for_colon = ignore # ignore/add/remove/force # Add or remove space before ':' in a Java/C++11 range-based 'for', # as in 'for (Type var : expr)'. sp_before_for_colon = ignore # ignore/add/remove/force # (D) Add or remove space between 'extern' and '(' as in 'extern (C)'. sp_extern_paren = ignore # ignore/add/remove/force # Add or remove space after the opening of a C++ comment, # i.e. '// A' vs. '//A'. sp_cmt_cpp_start = ignore # ignore/add/remove/force # If true, space is added with sp_cmt_cpp_start will be added after doxygen # sequences like '///', '///<', '//!' and '//!<'. sp_cmt_cpp_doxygen = false # true/false # If true, space is added with sp_cmt_cpp_start will be added after Qt # translator or meta-data comments like '//:', '//=', and '//~'. sp_cmt_cpp_qttr = false # true/false # Add or remove space between #else or #endif and a trailing comment. sp_endif_cmt = ignore # ignore/add/remove/force # Add or remove space after 'new', 'delete' and 'delete[]'. sp_after_new = ignore # ignore/add/remove/force # Add or remove space between 'new' and '(' in 'new()'. sp_between_new_paren = ignore # ignore/add/remove/force # Add or remove space between ')' and type in 'new(foo) BAR'. sp_after_newop_paren = ignore # ignore/add/remove/force # Add or remove space inside parenthesis of the new operator # as in 'new(foo) BAR'. sp_inside_newop_paren = ignore # ignore/add/remove/force # Add or remove space after the open parenthesis of the new operator, # as in 'new(foo) BAR'. # # Overrides sp_inside_newop_paren. sp_inside_newop_paren_open = ignore # ignore/add/remove/force # Add or remove space before the close parenthesis of the new operator, # as in 'new(foo) BAR'. # # Overrides sp_inside_newop_paren. sp_inside_newop_paren_close = ignore # ignore/add/remove/force # Add or remove space before a trailing or embedded comment. sp_before_tr_emb_cmt = ignore # ignore/add/remove/force # Number of spaces before a trailing or embedded comment. sp_num_before_tr_emb_cmt = 0 # unsigned number # (Java) Add or remove space between an annotation and the open parenthesis. sp_annotation_paren = ignore # ignore/add/remove/force # If true, vbrace tokens are dropped to the previous token and skipped. sp_skip_vbrace_tokens = false # true/false # Add or remove space after 'noexcept'. sp_after_noexcept = ignore # ignore/add/remove/force # If true, a is inserted after #define. force_tab_after_define = false # true/false # # Indenting options # # The number of columns to indent per level. Usually 2, 3, 4, or 8. # # Default: 8 indent_columns = 4 # unsigned number # The continuation indent. If non-zero, this overrides the indent of '(' and # '=' continuation indents. Negative values are OK; negative value is absolute # and not increased for each '(' level. # # For FreeBSD, this is set to 4. indent_continue = 0 # number # The continuation indent, only for class header line(s). If non-zero, this # overrides the indent of 'class' continuation indents. indent_continue_class_head = 0 # unsigned number # Whether to indent empty lines (i.e. lines which contain only spaces before # the newline character). indent_single_newlines = false # true/false # The continuation indent for func_*_param if they are true. If non-zero, this # overrides the indent. indent_param = 0 # unsigned number # How to use tabs when indenting code. # # 0: Spaces only # 1: Indent with tabs to brace level, align with spaces (default) # 2: Indent and align with tabs, using spaces when not on a tabstop # # Default: 1 indent_with_tabs = 0 # unsigned number # Whether to indent comments that are not at a brace level with tabs on a # tabstop. Requires indent_with_tabs=2. If false, will use spaces. indent_cmt_with_tabs = false # true/false # Whether to indent strings broken by '\' so that they line up. indent_align_string = false # true/false # The number of spaces to indent multi-line XML strings. # Requires indent_align_string=true. indent_xml_string = 0 # unsigned number # Spaces to indent '{' from level. indent_brace = 0 # unsigned number # Whether braces are indented to the body level. indent_braces = false # true/false # Whether to disable indenting function braces if indent_braces=true. indent_braces_no_func = false # true/false # Whether to disable indenting class braces if indent_braces=true. indent_braces_no_class = false # true/false # Whether to disable indenting struct braces if indent_braces=true. indent_braces_no_struct = false # true/false # Whether to indent based on the size of the brace parent, # i.e. 'if' → 3 spaces, 'for' → 4 spaces, etc. indent_brace_parent = false # true/false # Whether to indent based on the open parenthesis instead of the open brace # in '({\n'. indent_paren_open_brace = false # true/false # (C#) Whether to indent the brace of a C# delegate by another level. indent_cs_delegate_brace = false # true/false # (C#) Whether to indent a C# delegate (to handle delegates with no brace) by # another level. indent_cs_delegate_body = false # true/false # Whether to indent the body of a 'namespace'. indent_namespace = false # true/false # Whether to indent only the first namespace, and not any nested namespaces. # Requires indent_namespace=true. indent_namespace_single_indent = false # true/false # The number of spaces to indent a namespace block. indent_namespace_level = 0 # unsigned number # If the body of the namespace is longer than this number, it won't be # indented. Requires indent_namespace=true. 0 means no limit. indent_namespace_limit = 0 # unsigned number # Whether the 'extern "C"' body is indented. indent_extern = false # true/false # Whether the 'class' body is indented. indent_class = false # true/false # Whether to indent the stuff after a leading base class colon. indent_class_colon = false # true/false # Whether to indent based on a class colon instead of the stuff after the # colon. Requires indent_class_colon=true. indent_class_on_colon = false # true/false # Whether to indent the stuff after a leading class initializer colon. indent_constr_colon = false # true/false # Virtual indent from the ':' for member initializers. # # Default: 2 indent_ctor_init_leading = 2 # unsigned number # Additional indent for constructor initializer list. # Negative values decrease indent down to the first column. indent_ctor_init = 0 # number # Whether to indent 'if' following 'else' as a new block under the 'else'. # If false, 'else\nif' is treated as 'else if' for indenting purposes. indent_else_if = false # true/false # Amount to indent variable declarations after a open brace. # # <0: Relative # ≥0: Absolute indent_var_def_blk = 0 # number # Whether to indent continued variable declarations instead of aligning. indent_var_def_cont = false # true/false # Whether to indent continued shift expressions ('<<' and '>>') instead of # aligning. Set align_left_shift=false when enabling this. indent_shift = false # true/false # Whether to force indentation of function definitions to start in column 1. indent_func_def_force_col1 = false # true/false # Whether to indent continued function call parameters one indent level, # rather than aligning parameters under the open parenthesis. indent_func_call_param = false # true/false # Same as indent_func_call_param, but for function definitions. indent_func_def_param = false # true/false # Same as indent_func_call_param, but for function prototypes. indent_func_proto_param = false # true/false # Same as indent_func_call_param, but for class declarations. indent_func_class_param = false # true/false # Same as indent_func_call_param, but for class variable constructors. indent_func_ctor_var_param = false # true/false # Same as indent_func_call_param, but for template parameter lists. indent_template_param = false # true/false # Double the indent for indent_func_xxx_param options. # Use both values of the options indent_columns and indent_param. indent_func_param_double = false # true/false # Indentation column for standalone 'const' qualifier on a function # prototype. indent_func_const = 0 # unsigned number # Indentation column for standalone 'throw' qualifier on a function # prototype. indent_func_throw = 0 # unsigned number # The number of spaces to indent a continued '->' or '.'. # Usually set to 0, 1, or indent_columns. indent_member = 0 # unsigned number # Whether lines broken at '.' or '->' should be indented by a single indent. # The indent_member option will not be effective if this is set to true. indent_member_single = false # true/false # Spaces to indent single line ('//') comments on lines before code. indent_sing_line_comments = 0 # unsigned number # Whether to indent trailing single line ('//') comments relative to the code # instead of trying to keep the same absolute column. indent_relative_single_line_comments = false # true/false # Spaces to indent 'case' from 'switch'. Usually 0 or indent_columns. indent_switch_case = 0 # unsigned number # Whether to indent preprocessor statements inside of switch statements. # # Default: true indent_switch_pp = true # true/false # Spaces to shift the 'case' line, without affecting any other lines. # Usually 0. indent_case_shift = 0 # unsigned number # Spaces to indent '{' from 'case'. By default, the brace will appear under # the 'c' in case. Usually set to 0 or indent_columns. Negative values are OK. indent_case_brace = 0 # number # Whether to indent comments found in first column. indent_col1_comment = false # true/false # How to indent goto labels. # # >0: Absolute column where 1 is the leftmost column # ≤0: Subtract from brace indent # # Default: 1 indent_label = 1 # number # Same as indent_label, but for access specifiers that are followed by a # colon. # # Default: 1 indent_access_spec = 1 # number # Whether to indent the code after an access specifier by one level. # If true, this option forces 'indent_access_spec=0'. indent_access_spec_body = false # true/false # If an open parenthesis is followed by a newline, whether to indent the next # line so that it lines up after the open parenthesis (not recommended). indent_paren_nl = false # true/false # How to indent a close parenthesis after a newline. # # 0: Indent to body level (default) # 1: Align under the open parenthesis # 2: Indent to the brace level indent_paren_close = 0 # unsigned number # Whether to indent the open parenthesis of a function definition, # if the parenthesis is on its own line. indent_paren_after_func_def = false # true/false # Whether to indent the open parenthesis of a function declaration, # if the parenthesis is on its own line. indent_paren_after_func_decl = false # true/false # Whether to indent the open parenthesis of a function call, # if the parenthesis is on its own line. indent_paren_after_func_call = false # true/false # Whether to indent a comma when inside a parenthesis. # If true, aligns under the open parenthesis. indent_comma_paren = false # true/false # Whether to indent a Boolean operator when inside a parenthesis. # If true, aligns under the open parenthesis. indent_bool_paren = false # true/false # Whether to indent a semicolon when inside a for parenthesis. # If true, aligns under the open for parenthesis. indent_semicolon_for_paren = false # true/false # Whether to align the first expression to following ones # if indent_bool_paren=true. indent_first_bool_expr = false # true/false # Whether to align the first expression to following ones # if indent_semicolon_for_paren=true. indent_first_for_expr = false # true/false # If an open square is followed by a newline, whether to indent the next line # so that it lines up after the open square (not recommended). indent_square_nl = false # true/false # (ESQL/C) Whether to preserve the relative indent of 'EXEC SQL' bodies. indent_preserve_sql = false # true/false # Whether to align continued statements at the '='. If false or if the '=' is # followed by a newline, the next line is indent one tab. # # Default: true indent_align_assign = false # true/false # Whether to align continued statements at the '('. If false or the '(' is not # followed by a newline, the next line indent is one tab. # # Default: true indent_align_paren = true # true/false # (OC) Whether to indent Objective-C blocks at brace level instead of usual # rules. indent_oc_block = false # true/false # (OC) Indent for Objective-C blocks in a message relative to the parameter # name. # # =0: Use indent_oc_block rules # >0: Use specified number of spaces to indent indent_oc_block_msg = 0 # unsigned number # (OC) Minimum indent for subsequent parameters indent_oc_msg_colon = 0 # unsigned number # (OC) Whether to prioritize aligning with initial colon (and stripping spaces # from lines, if necessary). # # Default: true indent_oc_msg_prioritize_first_colon = true # true/false # (OC) Whether to indent blocks the way that Xcode does by default # (from the keyword if the parameter is on its own line; otherwise, from the # previous indentation level). Requires indent_oc_block_msg=true. indent_oc_block_msg_xcode_style = false # true/false # (OC) Whether to indent blocks from where the brace is, relative to a # message keyword. Requires indent_oc_block_msg=true. indent_oc_block_msg_from_keyword = false # true/false # (OC) Whether to indent blocks from where the brace is, relative to a message # colon. Requires indent_oc_block_msg=true. indent_oc_block_msg_from_colon = false # true/false # (OC) Whether to indent blocks from where the block caret is. # Requires indent_oc_block_msg=true. indent_oc_block_msg_from_caret = false # true/false # (OC) Whether to indent blocks from where the brace caret is. # Requires indent_oc_block_msg=true. indent_oc_block_msg_from_brace = false # true/false # When indenting after virtual brace open and newline add further spaces to # reach this minimum indent. indent_min_vbrace_open = 0 # unsigned number # Whether to add further spaces after regular indent to reach next tabstop # when identing after virtual brace open and newline. indent_vbrace_open_on_tabstop = false # true/false # How to indent after a brace followed by another token (not a newline). # true: indent all contained lines to match the token # false: indent all contained lines to match the brace # # Default: true indent_token_after_brace = true # true/false # Whether to indent the body of a C++11 lambda. indent_cpp_lambda_body = false # true/false # (C#) Whether to indent a 'using' block if no braces are used. # # Default: true indent_using_block = true # true/false # How to indent the continuation of ternary operator. # # 0: Off (default) # 1: When the `if_false` is a continuation, indent it under `if_false` # 2: When the `:` is a continuation, indent it under `?` indent_ternary_operator = 0 # unsigned number # If true, the indentation of the chunks after a `return new` sequence will be set at return indentation column. indent_off_after_return_new = false # true/false # If true, the tokens after return are indented with regular single indentation. By default (false) the indentation is after the return token. indent_single_after_return = false # true/false # Whether to ignore indent and alignment for 'asm' blocks (i.e. assume they # have their own indentation). indent_ignore_asm_block = false # true/false # # Newline adding and removing options # # Whether to collapse empty blocks between '{' and '}'. nl_collapse_empty_body = true # true/false # Don't split one-line braced assignments, as in 'foo_t f = { 1, 2 };'. nl_assign_leave_one_liners = false # true/false # Don't split one-line braced statements inside a 'class xx { }' body. nl_class_leave_one_liners = false # true/false # Don't split one-line enums, as in 'enum foo { BAR = 15 };' nl_enum_leave_one_liners = false # true/false # Don't split one-line get or set functions. nl_getset_leave_one_liners = false # true/false # (C#) Don't split one-line property get or set functions. nl_cs_property_leave_one_liners = false # true/false # Don't split one-line function definitions, as in 'int foo() { return 0; }'. nl_func_leave_one_liners = false # true/false # Don't split one-line C++11 lambdas, as in '[]() { return 0; }'. nl_cpp_lambda_leave_one_liners = false # true/false # Don't split one-line if/else statements, as in 'if(...) b++;'. nl_if_leave_one_liners = false # true/false # Don't split one-line while statements, as in 'while(...) b++;'. nl_while_leave_one_liners = false # true/false # Don't split one-line for statements, as in 'for(...) b++;'. nl_for_leave_one_liners = false # true/false # (OC) Don't split one-line Objective-C messages. nl_oc_msg_leave_one_liner = false # true/false # (OC) Add or remove newline between method declaration and '{'. nl_oc_mdef_brace = ignore # ignore/add/remove/force # (OC) Add or remove newline between Objective-C block signature and '{'. nl_oc_block_brace = ignore # ignore/add/remove/force # (OC) Add or remove newline between '@interface' and '{'. nl_oc_interface_brace = ignore # ignore/add/remove/force # (OC) Add or remove newline between '@implementation' and '{'. nl_oc_implementation_brace = ignore # ignore/add/remove/force # Add or remove newlines at the start of the file. nl_start_of_file = ignore # ignore/add/remove/force # The minimum number of newlines at the start of the file (only used if # nl_start_of_file is 'add' or 'force'). nl_start_of_file_min = 0 # unsigned number # Add or remove newline at the end of the file. nl_end_of_file = ignore # ignore/add/remove/force # The minimum number of newlines at the end of the file (only used if # nl_end_of_file is 'add' or 'force'). nl_end_of_file_min = 0 # unsigned number # Add or remove newline between '=' and '{'. nl_assign_brace = remove # ignore/add/remove/force # (D) Add or remove newline between '=' and '['. nl_assign_square = ignore # ignore/add/remove/force # Add or remove newline between '[]' and '{'. nl_tsquare_brace = ignore # ignore/add/remove/force # (D) Add or remove newline after '= ['. Will also affect the newline before # the ']'. nl_after_square_assign = ignore # ignore/add/remove/force # The number of blank lines after a block of variable definitions at the top # of a function body. # # 0 = No change (default). nl_func_var_def_blk = 0 # unsigned number # The number of newlines before a block of typedefs. If nl_after_access_spec # is non-zero, that option takes precedence. # # 0 = No change (default). nl_typedef_blk_start = 0 # unsigned number # The number of newlines after a block of typedefs. # # 0 = No change (default). nl_typedef_blk_end = 0 # unsigned number # The maximum number of consecutive newlines within a block of typedefs. # # 0 = No change (default). nl_typedef_blk_in = 0 # unsigned number # The number of newlines before a block of variable definitions not at the top # of a function body. If nl_after_access_spec is non-zero, that option takes # precedence. # # 0 = No change (default). nl_var_def_blk_start = 0 # unsigned number # The number of newlines after a block of variable definitions not at the top # of a function body. # # 0 = No change (default). nl_var_def_blk_end = 0 # unsigned number # The maximum number of consecutive newlines within a block of variable # definitions. # # 0 = No change (default). nl_var_def_blk_in = 0 # unsigned number # Add or remove newline between a function call's ')' and '{', as in # 'list_for_each(item, &list) { }'. nl_fcall_brace = ignore # ignore/add/remove/force # Add or remove newline between 'enum' and '{'. nl_enum_brace = ignore # ignore/add/remove/force # Add or remove newline between 'enum' and 'class'. nl_enum_class = ignore # ignore/add/remove/force # Add or remove newline between 'enum class' and the identifier. nl_enum_class_identifier = ignore # ignore/add/remove/force # Add or remove newline between 'enum class' type and ':'. nl_enum_identifier_colon = ignore # ignore/add/remove/force # Add or remove newline between 'enum class identifier :' and type. nl_enum_colon_type = ignore # ignore/add/remove/force # Add or remove newline between 'struct and '{'. nl_struct_brace = ignore # ignore/add/remove/force # Add or remove newline between 'union' and '{'. nl_union_brace = ignore # ignore/add/remove/force # Add or remove newline between 'if' and '{'. nl_if_brace = remove # ignore/add/remove/force # Add or remove newline between '}' and 'else'. nl_brace_else = add # ignore/add/remove/force # Add or remove newline between 'else if' and '{'. If set to ignore, # nl_if_brace is used instead. nl_elseif_brace = add # ignore/add/remove/force # Add or remove newline between 'else' and '{'. nl_else_brace = remove # ignore/add/remove/force # Add or remove newline between 'else' and 'if'. nl_else_if = ignore # ignore/add/remove/force # Add or remove newline before 'if'/'else if' closing parenthesis. nl_before_if_closing_paren = ignore # ignore/add/remove/force # Add or remove newline between '}' and 'finally'. nl_brace_finally = ignore # ignore/add/remove/force # Add or remove newline between 'finally' and '{'. nl_finally_brace = ignore # ignore/add/remove/force # Add or remove newline between 'try' and '{'. nl_try_brace = ignore # ignore/add/remove/force # Add or remove newline between get/set and '{'. nl_getset_brace = ignore # ignore/add/remove/force # Add or remove newline between 'for' and '{'. nl_for_brace = remove # ignore/add/remove/force # Add or remove newline before the '{' of a 'catch' statement, as in # 'catch (decl) {'. nl_catch_brace = ignore # ignore/add/remove/force # (OC) Add or remove newline before the '{' of a '@catch' statement, as in # '@catch (decl) {'. If set to ignore, nl_catch_brace is used. nl_oc_catch_brace = ignore # ignore/add/remove/force # Add or remove newline between '}' and 'catch'. nl_brace_catch = ignore # ignore/add/remove/force # (OC) Add or remove newline between '}' and '@catch'. If set to ignore, # nl_brace_catch is used. nl_oc_brace_catch = ignore # ignore/add/remove/force # Add or remove newline between '}' and ']'. nl_brace_square = ignore # ignore/add/remove/force # Add or remove newline between '}' and ')' in a function invocation. nl_brace_fparen = ignore # ignore/add/remove/force # Add or remove newline between 'while' and '{'. nl_while_brace = remove # ignore/add/remove/force # (D) Add or remove newline between 'scope (x)' and '{'. nl_scope_brace = ignore # ignore/add/remove/force # (D) Add or remove newline between 'unittest' and '{'. nl_unittest_brace = ignore # ignore/add/remove/force # (D) Add or remove newline between 'version (x)' and '{'. nl_version_brace = ignore # ignore/add/remove/force # (C#) Add or remove newline between 'using' and '{'. nl_using_brace = ignore # ignore/add/remove/force # Add or remove newline between two open or close braces. Due to general # newline/brace handling, REMOVE may not work. nl_brace_brace = ignore # ignore/add/remove/force # Add or remove newline between 'do' and '{'. nl_do_brace = remove # ignore/add/remove/force # Add or remove newline between '}' and 'while' of 'do' statement. nl_brace_while = remove # ignore/add/remove/force # Add or remove newline between 'switch' and '{'. nl_switch_brace = remove # ignore/add/remove/force # Add or remove newline between 'synchronized' and '{'. nl_synchronized_brace = ignore # ignore/add/remove/force # Add a newline between ')' and '{' if the ')' is on a different line than the # if/for/etc. # # Overrides nl_for_brace, nl_if_brace, nl_switch_brace, nl_while_switch and # nl_catch_brace. nl_multi_line_cond = false # true/false # Force a newline in a define after the macro name for multi-line defines. nl_multi_line_define = false # true/false # Whether to add a newline before 'case', and a blank line before a 'case' # statement that follows a ';' or '}'. nl_before_case = false # true/false # Whether to add a newline after a 'case' statement. nl_after_case = false # true/false # Add or remove newline between a case ':' and '{'. # # Overrides nl_after_case. nl_case_colon_brace = ignore # ignore/add/remove/force # Add or remove newline between ')' and 'throw'. nl_before_throw = ignore # ignore/add/remove/force # Add or remove newline between 'namespace' and '{'. nl_namespace_brace = ignore # ignore/add/remove/force # Add or remove newline between 'template<>' and whatever follows. nl_template_class = ignore # ignore/add/remove/force # Add or remove newline between 'class' and '{'. nl_class_brace = ignore # ignore/add/remove/force # Add or remove newline before or after (depending on pos_class_comma) each # ',' in the base class list. nl_class_init_args = ignore # ignore/add/remove/force # Add or remove newline after each ',' in the constructor member # initialization. Related to nl_constr_colon, pos_constr_colon and # pos_constr_comma. nl_constr_init_args = ignore # ignore/add/remove/force # Add or remove newline before first element, after comma, and after last # element, in 'enum'. nl_enum_own_lines = ignore # ignore/add/remove/force # Add or remove newline between return type and function name in a function # definition. nl_func_type_name = ignore # ignore/add/remove/force # Add or remove newline between return type and function name inside a class # definition. If set to ignore, nl_func_type_name or nl_func_proto_type_name # is used instead. nl_func_type_name_class = ignore # ignore/add/remove/force # Add or remove newline between class specification and '::' # in 'void A::f() { }'. Only appears in separate member implementation (does # not appear with in-line implementation). nl_func_class_scope = ignore # ignore/add/remove/force # Add or remove newline between function scope and name, as in # 'void A :: f() { }'. nl_func_scope_name = ignore # ignore/add/remove/force # Add or remove newline between return type and function name in a prototype. nl_func_proto_type_name = ignore # ignore/add/remove/force # Add or remove newline between a function name and the opening '(' in the # declaration. nl_func_paren = ignore # ignore/add/remove/force # Overrides nl_func_paren for functions with no parameters. nl_func_paren_empty = ignore # ignore/add/remove/force # Add or remove newline between a function name and the opening '(' in the # definition. nl_func_def_paren = ignore # ignore/add/remove/force # Overrides nl_func_def_paren for functions with no parameters. nl_func_def_paren_empty = ignore # ignore/add/remove/force # Add or remove newline between a function name and the opening '(' in the # call. nl_func_call_paren = ignore # ignore/add/remove/force # Overrides nl_func_call_paren for functions with no parameters. nl_func_call_paren_empty = ignore # ignore/add/remove/force # Add or remove newline after '(' in a function declaration. nl_func_decl_start = ignore # ignore/add/remove/force # Add or remove newline after '(' in a function definition. nl_func_def_start = ignore # ignore/add/remove/force # Overrides nl_func_decl_start when there is only one parameter. nl_func_decl_start_single = ignore # ignore/add/remove/force # Overrides nl_func_def_start when there is only one parameter. nl_func_def_start_single = ignore # ignore/add/remove/force # Whether to add a newline after '(' in a function declaration if '(' and ')' # are in different lines. If false, nl_func_decl_start is used instead. nl_func_decl_start_multi_line = false # true/false # Whether to add a newline after '(' in a function definition if '(' and ')' # are in different lines. If false, nl_func_def_start is used instead. nl_func_def_start_multi_line = false # true/false # Add or remove newline after each ',' in a function declaration. nl_func_decl_args = ignore # ignore/add/remove/force # Add or remove newline after each ',' in a function definition. nl_func_def_args = ignore # ignore/add/remove/force # Whether to add a newline after each ',' in a function declaration if '(' # and ')' are in different lines. If false, nl_func_decl_args is used instead. nl_func_decl_args_multi_line = false # true/false # Whether to add a newline after each ',' in a function definition if '(' # and ')' are in different lines. If false, nl_func_def_args is used instead. nl_func_def_args_multi_line = false # true/false # Add or remove newline before the ')' in a function declaration. nl_func_decl_end = ignore # ignore/add/remove/force # Add or remove newline before the ')' in a function definition. nl_func_def_end = ignore # ignore/add/remove/force # Overrides nl_func_decl_end when there is only one parameter. nl_func_decl_end_single = ignore # ignore/add/remove/force # Overrides nl_func_def_end when there is only one parameter. nl_func_def_end_single = ignore # ignore/add/remove/force # Whether to add a newline before ')' in a function declaration if '(' and ')' # are in different lines. If false, nl_func_decl_end is used instead. nl_func_decl_end_multi_line = false # true/false # Whether to add a newline before ')' in a function definition if '(' and ')' # are in different lines. If false, nl_func_def_end is used instead. nl_func_def_end_multi_line = false # true/false # Add or remove newline between '()' in a function declaration. nl_func_decl_empty = ignore # ignore/add/remove/force # Add or remove newline between '()' in a function definition. nl_func_def_empty = ignore # ignore/add/remove/force # Add or remove newline between '()' in a function call. nl_func_call_empty = ignore # ignore/add/remove/force # Whether to add a newline after '(' in a function call if '(' and ')' are in # different lines. nl_func_call_start_multi_line = false # true/false # Whether to add a newline after each ',' in a function call if '(' and ')' # are in different lines. nl_func_call_args_multi_line = false # true/false # Whether to add a newline before ')' in a function call if '(' and ')' are in # different lines. nl_func_call_end_multi_line = false # true/false # (OC) Whether to put each Objective-C message parameter on a separate line. # See nl_oc_msg_leave_one_liner. nl_oc_msg_args = false # true/false # Add or remove newline between function signature and '{'. nl_fdef_brace = force # ignore/add/remove/force # Add or remove newline between C++11 lambda signature and '{'. nl_cpp_ldef_brace = ignore # ignore/add/remove/force # Add or remove newline between 'return' and the return expression. nl_return_expr = ignore # ignore/add/remove/force # Whether to add a newline after semicolons, except in 'for' statements. nl_after_semicolon = false # true/false # (Java) Add or remove newline between the ')' and '{{' of the double brace # initializer. nl_paren_dbrace_open = ignore # ignore/add/remove/force # Whether to add a newline after the type in an unnamed temporary # direct-list-initialization. nl_type_brace_init_lst = ignore # ignore/add/remove/force # Whether to add a newline after the open brace in an unnamed temporary # direct-list-initialization. nl_type_brace_init_lst_open = ignore # ignore/add/remove/force # Whether to add a newline before the close brace in an unnamed temporary # direct-list-initialization. nl_type_brace_init_lst_close = ignore # ignore/add/remove/force # Whether to add a newline after '{'. This also adds a newline before the # matching '}'. nl_after_brace_open = false # true/false # Whether to add a newline between the open brace and a trailing single-line # comment. Requires nl_after_brace_open=true. nl_after_brace_open_cmt = false # true/false # Whether to add a newline after a virtual brace open with a non-empty body. # These occur in un-braced if/while/do/for statement bodies. nl_after_vbrace_open = false # true/false # Whether to add a newline after a virtual brace open with an empty body. # These occur in un-braced if/while/do/for statement bodies. nl_after_vbrace_open_empty = false # true/false # Whether to add a newline after '}'. Does not apply if followed by a # necessary ';'. nl_after_brace_close = false # true/false # Whether to add a newline after a virtual brace close, # as in 'if (foo) a++; return;'. nl_after_vbrace_close = false # true/false # Add or remove newline between the close brace and identifier, # as in 'struct { int a; } b;'. Affects enumerations, unions and # structures. If set to ignore, uses nl_after_brace_close. nl_brace_struct_var = ignore # ignore/add/remove/force # Whether to alter newlines in '#define' macros. nl_define_macro = false # true/false # Whether to alter newlines between consecutive parenthesis closes. The number # of closing parentheses in a line will depend on respective open parenthesis # lines. nl_squeeze_paren_close = false # true/false # Whether to remove blanks after '#ifxx' and '#elxx', or before '#elxx' and # '#endif'. Does not affect top-level #ifdefs. nl_squeeze_ifdef = false # true/false # Makes the nl_squeeze_ifdef option affect the top-level #ifdefs as well. nl_squeeze_ifdef_top_level = false # true/false # Add or remove blank line before 'if'. nl_before_if = force # ignore/add/remove/force # Add or remove blank line after 'if' statement. Add/Force work only if the # next token is not a closing brace. nl_after_if = force # ignore/add/remove/force # Add or remove blank line before 'for'. nl_before_for = force # ignore/add/remove/force # Add or remove blank line after 'for' statement. nl_after_for = force # ignore/add/remove/force # Add or remove blank line before 'while'. nl_before_while = force # ignore/add/remove/force # Add or remove blank line after 'while' statement. nl_after_while = force # ignore/add/remove/force # Add or remove blank line before 'switch'. nl_before_switch = force # ignore/add/remove/force # Add or remove blank line after 'switch' statement. nl_after_switch = force # ignore/add/remove/force # Add or remove blank line before 'synchronized'. nl_before_synchronized = ignore # ignore/add/remove/force # Add or remove blank line after 'synchronized' statement. nl_after_synchronized = ignore # ignore/add/remove/force # Add or remove blank line before 'do'. nl_before_do = force # ignore/add/remove/force # Add or remove blank line after 'do/while' statement. nl_after_do = force # ignore/add/remove/force # Whether to double-space commented-entries in 'struct'/'union'/'enum'. nl_ds_struct_enum_cmt = false # true/false # Whether to force a newline before '}' of a 'struct'/'union'/'enum'. # (Lower priority than eat_blanks_before_close_brace.) nl_ds_struct_enum_close_brace = false # true/false # Add or remove newline before or after (depending on pos_class_colon) a class # colon, as in 'class Foo : public Bar'. nl_class_colon = ignore # ignore/add/remove/force # Add or remove newline around a class constructor colon. The exact position # depends on nl_constr_init_args, pos_constr_colon and pos_constr_comma. nl_constr_colon = ignore # ignore/add/remove/force # Whether to collapse a two-line namespace, like 'namespace foo\n{ decl; }' # into a single line. If true, prevents other brace newline rules from turning # such code into four lines. nl_namespace_two_to_one_liner = false # true/false # Whether to remove a newline in simple unbraced if statements, turning them # into one-liners, as in 'if(b)\n i++;' → 'if(b) i++;'. nl_create_if_one_liner = false # true/false # Whether to remove a newline in simple unbraced for statements, turning them # into one-liners, as in 'for (...)\n stmt;' → 'for (...) stmt;'. nl_create_for_one_liner = false # true/false # Whether to remove a newline in simple unbraced while statements, turning # them into one-liners, as in 'while (expr)\n stmt;' → 'while (expr) stmt;'. nl_create_while_one_liner = false # true/false # Whether to collapse a function definition whose body (not counting braces) # is only one line so that the entire definition (prototype, braces, body) is # a single line. nl_create_func_def_one_liner = false # true/false # Whether to split one-line simple unbraced if statements into two lines by # adding a newline, as in 'if(b) i++;'. nl_split_if_one_liner = false # true/false # Whether to split one-line simple unbraced for statements into two lines by # adding a newline, as in 'for (...) stmt;'. nl_split_for_one_liner = false # true/false # Whether to split one-line simple unbraced while statements into two lines by # adding a newline, as in 'while (expr) stmt;'. nl_split_while_one_liner = false # true/false # # Blank line options # # The maximum number of consecutive newlines (3 = 2 blank lines). nl_max = 0 # unsigned number # The maximum number of consecutive newlines in a function. nl_max_blank_in_func = 0 # unsigned number # The number of newlines before a function prototype. nl_before_func_body_proto = 0 # unsigned number # The number of newlines before a multi-line function definition. nl_before_func_body_def = 0 # unsigned number # The number of newlines before a class constructor/destructor prototype. nl_before_func_class_proto = 0 # unsigned number # The number of newlines before a class constructor/destructor definition. nl_before_func_class_def = 0 # unsigned number # The number of newlines after a function prototype. nl_after_func_proto = 0 # unsigned number # The number of newlines after a function prototype, if not followed by # another function prototype. nl_after_func_proto_group = 0 # unsigned number # The number of newlines after a class constructor/destructor prototype. nl_after_func_class_proto = 0 # unsigned number # The number of newlines after a class constructor/destructor prototype, # if not followed by another constructor/destructor prototype. nl_after_func_class_proto_group = 0 # unsigned number # Whether one-line method definitions inside a class body should be treated # as if they were prototypes for the purposes of adding newlines. # # Requires nl_class_leave_one_liners=true. Overrides nl_before_func_body_def # and nl_before_func_class_def for one-liners. nl_class_leave_one_liner_groups = false # true/false # The number of newlines after '}' of a multi-line function body. nl_after_func_body = 0 # unsigned number # The number of newlines after '}' of a multi-line function body in a class # declaration. Also affects class constructors/destructors. # # Overrides nl_after_func_body. nl_after_func_body_class = 0 # unsigned number # The number of newlines after '}' of a single line function body. Also # affects class constructors/destructors. # # Overrides nl_after_func_body and nl_after_func_body_class. nl_after_func_body_one_liner = 0 # unsigned number # The minimum number of newlines before a multi-line comment. # Doesn't apply if after a brace open or another multi-line comment. nl_before_block_comment = 0 # unsigned number # The minimum number of newlines before a single-line C comment. # Doesn't apply if after a brace open or other single-line C comments. nl_before_c_comment = 0 # unsigned number # The minimum number of newlines before a CPP comment. # Doesn't apply if after a brace open or other CPP comments. nl_before_cpp_comment = 0 # unsigned number # Whether to force a newline after a multi-line comment. nl_after_multiline_comment = false # true/false # Whether to force a newline after a label's colon. nl_after_label_colon = false # true/false # The number of newlines after '}' or ';' of a struct/enum/union definition. nl_after_struct = 0 # unsigned number # The number of newlines before a class definition. nl_before_class = 0 # unsigned number # The number of newlines after '}' or ';' of a class definition. nl_after_class = 0 # unsigned number # The number of newlines before an access specifier label. This also includes # the Qt-specific 'signals:' and 'slots:'. Will not change the newline count # if after a brace open. # # 0 = No change (default). nl_before_access_spec = 0 # unsigned number # The number of newlines after an access specifier label. This also includes # the Qt-specific 'signals:' and 'slots:'. Will not change the newline count # if after a brace open. # # 0 = No change (default). # # Overrides nl_typedef_blk_start and nl_var_def_blk_start. nl_after_access_spec = 0 # unsigned number # The number of newlines between a function definition and the function # comment, as in '// comment\n void foo() {...}'. # # 0 = No change (default). nl_comment_func_def = 0 # unsigned number # The number of newlines after a try-catch-finally block that isn't followed # by a brace close. # # 0 = No change (default). nl_after_try_catch_finally = 0 # unsigned number # (C#) The number of newlines before and after a property, indexer or event # declaration. # # 0 = No change (default). nl_around_cs_property = 0 # unsigned number # (C#) The number of newlines between the get/set/add/remove handlers. # # 0 = No change (default). nl_between_get_set = 0 # unsigned number # (C#) Add or remove newline between property and the '{'. nl_property_brace = ignore # ignore/add/remove/force # The number of newlines after '{' of a namespace. This also adds newlines # before the matching '}'. # # 0 = Apply eat_blanks_after_open_brace or eat_blanks_before_close_brace if # applicable, otherwise no change. # # Overrides eat_blanks_after_open_brace and eat_blanks_before_close_brace. nl_inside_namespace = 0 # unsigned number # Whether to remove blank lines after '{'. eat_blanks_after_open_brace = false # true/false # Whether to remove blank lines before '}'. eat_blanks_before_close_brace = false # true/false # How aggressively to remove extra newlines not in preprocessor. # # 0: No change (default) # 1: Remove most newlines not handled by other config # 2: Remove all newlines and reformat completely by config nl_remove_extra_newlines = 0 # unsigned number # Whether to put a blank line before 'return' statements, unless after an open # brace. nl_before_return = false # true/false # Whether to put a blank line after 'return' statements, unless followed by a # close brace. nl_after_return = false # true/false # (Java) Add or remove newline after an annotation statement. Only affects # annotations that are after a newline. nl_after_annotation = ignore # ignore/add/remove/force # (Java) Add or remove newline between two annotations. nl_between_annotation = ignore # ignore/add/remove/force # # Positioning options # # The position of arithmetic operators in wrapped expressions. pos_arith = ignore # ignore/break/force/lead/trail/join/lead_break/lead_force/trail_break/trail_force # The position of assignment in wrapped expressions. Do not affect '=' # followed by '{'. pos_assign = ignore # ignore/break/force/lead/trail/join/lead_break/lead_force/trail_break/trail_force # The position of Boolean operators in wrapped expressions. pos_bool = ignore # ignore/break/force/lead/trail/join/lead_break/lead_force/trail_break/trail_force # The position of comparison operators in wrapped expressions. pos_compare = ignore # ignore/break/force/lead/trail/join/lead_break/lead_force/trail_break/trail_force # The position of conditional operators, as in the '?' and ':' of # 'expr ? stmt : stmt', in wrapped expressions. pos_conditional = ignore # ignore/break/force/lead/trail/join/lead_break/lead_force/trail_break/trail_force # The position of the comma in wrapped expressions. pos_comma = ignore # ignore/break/force/lead/trail/join/lead_break/lead_force/trail_break/trail_force # The position of the comma in enum entries. pos_enum_comma = ignore # ignore/break/force/lead/trail/join/lead_break/lead_force/trail_break/trail_force # The position of the comma in the base class list if there is more than one # line. Affects nl_class_init_args. pos_class_comma = ignore # ignore/break/force/lead/trail/join/lead_break/lead_force/trail_break/trail_force # The position of the comma in the constructor initialization list. # Related to nl_constr_colon, nl_constr_init_args and pos_constr_colon. pos_constr_comma = ignore # ignore/break/force/lead/trail/join/lead_break/lead_force/trail_break/trail_force # The position of trailing/leading class colon, between class and base class # list. Affects nl_class_colon. pos_class_colon = ignore # ignore/break/force/lead/trail/join/lead_break/lead_force/trail_break/trail_force # The position of colons between constructor and member initialization. # Related to nl_constr_colon, nl_constr_init_args and pos_constr_comma. pos_constr_colon = ignore # ignore/break/force/lead/trail/join/lead_break/lead_force/trail_break/trail_force # # Line splitting options # # Try to limit code width to N columns. code_width = 120 # unsigned number # Whether to fully split long 'for' statements at semi-colons. ls_for_split_full = true # true/false # Whether to fully split long function prototypes/calls at commas. ls_func_split_full = true # true/false # Whether to split lines as close to code_width as possible and ignore some # groupings. ls_code_width = false # true/false # # Code alignment options (not left column spaces/tabs) # # Whether to keep non-indenting tabs. align_keep_tabs = false # true/false # Whether to use tabs for aligning. align_with_tabs = false # true/false # Whether to bump out to the next tab when aligning. align_on_tabstop = false # true/false # Whether to right-align numbers. align_number_right = false # true/false # Whether to keep whitespace not required for alignment. align_keep_extra_space = false # true/false # Whether to align variable definitions in prototypes and functions. align_func_params = false # true/false # The span for aligning parameter definitions in function on parameter name. # # 0 = Don't align (default). align_func_params_span = 0 # unsigned number # The threshold for aligning function parameter definitions. # # 0 = No limit (default). align_func_params_thresh = 0 # unsigned number # The gap for aligning function parameter definitions. align_func_params_gap = 0 # unsigned number # Whether to align parameters in single-line functions that have the same # name. The function names must already be aligned with each other. align_same_func_call_params = false # true/false # The span for aligning function-call parameters for single line functions. # # 0 = Don't align (default). align_same_func_call_params_span = 0 # unsigned number # The threshold for aligning function-call parameters for single line # functions. # # 0 = No limit (default). align_same_func_call_params_thresh = 0 # unsigned number # The span for aligning variable definitions. # # 0 = Don't align (default). align_var_def_span = 0 # unsigned number # How to align the '*' in variable definitions. # # 0: Part of the type 'void * foo;' (default) # 1: Part of the variable 'void *foo;' # 2: Dangling 'void *foo;' align_var_def_star_style = 0 # unsigned number # How to align the '&' in variable definitions. # # 0: Part of the type 'long & foo;' (default) # 1: Part of the variable 'long &foo;' # 2: Dangling 'long &foo;' align_var_def_amp_style = 0 # unsigned number # The threshold for aligning variable definitions. # # 0 = No limit (default). align_var_def_thresh = 0 # unsigned number # The gap for aligning variable definitions. align_var_def_gap = 0 # unsigned number # Whether to align the colon in struct bit fields. align_var_def_colon = false # true/false # The gap for aligning the colon in struct bit fields. align_var_def_colon_gap = 0 # unsigned number # Whether to align any attribute after the variable name. align_var_def_attribute = false # true/false # Whether to align inline struct/enum/union variable definitions. align_var_def_inline = false # true/false # The span for aligning on '=' in assignments. # # 0 = Don't align (default). align_assign_span = 0 # unsigned number # The threshold for aligning on '=' in assignments. # # 0 = No limit (default). align_assign_thresh = 0 # unsigned number # How to apply align_assign_span to function declaration "assignments", i.e. # 'virtual void foo() = 0' or '~foo() = {default|delete}'. # # 0: Align with other assignments (default) # 1: Align with each other, ignoring regular assignments # 2: Don't align align_assign_decl_func = 0 # unsigned number # The span for aligning on '=' in enums. # # 0 = Don't align (default). align_enum_equ_span = 0 # unsigned number # The threshold for aligning on '=' in enums. # # 0 = no limit (default). align_enum_equ_thresh = 0 # unsigned number # The span for aligning class member definitions. # # 0 = Don't align (default). align_var_class_span = 0 # unsigned number # The threshold for aligning class member definitions. # # 0 = No limit (default). align_var_class_thresh = 0 # unsigned number # The gap for aligning class member definitions. align_var_class_gap = 0 # unsigned number # The span for aligning struct/union member definitions. # # 0 = Don't align (default). align_var_struct_span = 0 # unsigned number # The threshold for aligning struct/union member definitions. # # 0 = No limit (default). align_var_struct_thresh = 0 # unsigned number # The gap for aligning struct/union member definitions. align_var_struct_gap = 0 # unsigned number # The span for aligning struct initializer values. # # 0 = Don't align (default). align_struct_init_span = 0 # unsigned number # The minimum space between the type and the synonym of a typedef. align_typedef_gap = 0 # unsigned number # The span for aligning single-line typedefs. # # 0 = Don't align (default). align_typedef_span = 0 # unsigned number # How to align typedef'd functions with other typedefs. # # 0: Don't mix them at all (default) # 1: Align the open parenthesis with the types # 2: Align the function type name with the other type names align_typedef_func = 0 # unsigned number # How to align the '*' in typedefs. # # 0: Align on typedef type, ignore '*' (default) # 1: The '*' is part of type name: 'typedef int *pint;' # 2: The '*' is part of the type, but dangling: 'typedef int *pint;' align_typedef_star_style = 0 # unsigned number # How to align the '&' in typedefs. # # 0: Align on typedef type, ignore '&' (default) # 1: The '&' is part of type name: 'typedef int &pint;' # 2: The '&' is part of the type, but dangling: 'typedef int &pint;' align_typedef_amp_style = 0 # unsigned number # The span for aligning comments that end lines. # # 0 = Don't align (default). align_right_cmt_span = 0 # unsigned number # If aligning comments, whether to mix with comments after '}' and #endif with # less than three spaces before the comment. align_right_cmt_mix = false # true/false # Whether to only align trailing comments that are at the same brace level. align_right_cmt_same_level = false # true/false # Minimum number of columns between preceding text and a trailing comment in # order for the comment to qualify for being aligned. Must be non-zero to have # an effect. align_right_cmt_gap = 0 # unsigned number # Minimum column at which to align trailing comments. Comments which are # aligned beyond this column, but which can be aligned in a lesser column, # may be "pulled in". # # 0 = Ignore (default). align_right_cmt_at_col = 0 # unsigned number # The span for aligning function prototypes. # # 0 = Don't align (default). align_func_proto_span = 0 # unsigned number # Minimum gap between the return type and the function name. align_func_proto_gap = 0 # unsigned number # Whether to align function prototypes on the 'operator' keyword instead of # what follows. align_on_operator = false # true/false # Whether to mix aligning prototype and variable declarations. If true, # align_var_def_XXX options are used instead of align_func_proto_XXX options. align_mix_var_proto = false # true/false # Whether to align single-line functions with function prototypes. # Uses align_func_proto_span. align_single_line_func = false # true/false # Whether to align the open brace of single-line functions. # Requires align_single_line_func=true. Uses align_func_proto_span. align_single_line_brace = false # true/false # Gap for align_single_line_brace. align_single_line_brace_gap = 0 # unsigned number # (OC) The span for aligning Objective-C message specifications. # # 0 = Don't align (default). align_oc_msg_spec_span = 0 # unsigned number # Whether to align macros wrapped with a backslash and a newline. This will # not work right if the macro contains a multi-line comment. align_nl_cont = false # true/false # Whether to align macro functions and variables together. align_pp_define_together = false # true/false # The minimum space between label and value of a preprocessor define. align_pp_define_gap = 0 # unsigned number # The span for aligning on '#define' bodies. # # =0: Don't align (default) # >0: Number of lines (including comments) between blocks align_pp_define_span = 0 # unsigned number # Whether to align lines that start with '<<' with previous '<<'. # # Default: true align_left_shift = true # true/false # Whether to align text after 'asm volatile ()' colons. align_asm_colon = false # true/false # (OC) Span for aligning parameters in an Objective-C message call # on the ':'. # # 0 = Don't align. align_oc_msg_colon_span = 0 # unsigned number # (OC) Whether to always align with the first parameter, even if it is too # short. align_oc_msg_colon_first = false # true/false # (OC) Whether to align parameters in an Objective-C '+' or '-' declaration # on the ':'. align_oc_decl_colon = false # true/false # # Comment modification options # # Try to wrap comments at N columns. cmt_width = 0 # unsigned number # How to reflow comments. # # 0: No reflowing (apart from the line wrapping due to cmt_width) (default) # 1: No touching at all # 2: Full reflow cmt_reflow_mode = 0 # unsigned number # Whether to convert all tabs to spaces in comments. If false, tabs in # comments are left alone, unless used for indenting. cmt_convert_tab_to_spaces = true # true/false # Whether to apply changes to multi-line comments, including cmt_width, # keyword substitution and leading chars. # # Default: true cmt_indent_multi = true # true/false # Whether to group c-comments that look like they are in a block. cmt_c_group = false # true/false # Whether to put an empty '/*' on the first line of the combined c-comment. cmt_c_nl_start = false # true/false # Whether to add a newline before the closing '*/' of the combined c-comment. cmt_c_nl_end = false # true/false # Whether to change cpp-comments into c-comments. cmt_cpp_to_c = true # true/false # Whether to group cpp-comments that look like they are in a block. Only # meaningful if cmt_cpp_to_c=true. cmt_cpp_group = false # true/false # Whether to put an empty '/*' on the first line of the combined cpp-comment # when converting to a c-comment. # # Requires cmt_cpp_to_c=true and cmt_cpp_group=true. cmt_cpp_nl_start = false # true/false # Whether to add a newline before the closing '*/' of the combined cpp-comment # when converting to a c-comment. # # Requires cmt_cpp_to_c=true and cmt_cpp_group=true. cmt_cpp_nl_end = false # true/false # Whether to put a star on subsequent comment lines. cmt_star_cont = true # true/false # The number of spaces to insert at the start of subsequent comment lines. cmt_sp_before_star_cont = 0 # unsigned number # The number of spaces to insert after the star on subsequent comment lines. cmt_sp_after_star_cont = 0 # unsigned number # For multi-line comments with a '*' lead, remove leading spaces if the first # and last lines of the comment are the same length. # # Default: true cmt_multi_check_last = true # true/false # For multi-line comments with a '*' lead, remove leading spaces if the first # and last lines of the comment are the same length AND if the length is # bigger as the first_len minimum. # # Default: 4 cmt_multi_first_len_minimum = 4 # unsigned number # Path to a file that contains text to insert at the beginning of a file if # the file doesn't start with a C/C++ comment. If the inserted text contains # '$(filename)', that will be replaced with the current file's name. cmt_insert_file_header = "" # string # Path to a file that contains text to insert at the end of a file if the # file doesn't end with a C/C++ comment. If the inserted text contains # '$(filename)', that will be replaced with the current file's name. cmt_insert_file_footer = "" # string # Path to a file that contains text to insert before a function definition if # the function isn't preceded by a C/C++ comment. If the inserted text # contains '$(function)', '$(javaparam)' or '$(fclass)', these will be # replaced with, respectively, the name of the function, the javadoc '@param' # and '@return' stuff, or the name of the class to which the member function # belongs. cmt_insert_func_header = "" # string # Path to a file that contains text to insert before a class if the class # isn't preceded by a C/C++ comment. If the inserted text contains '$(class)', # that will be replaced with the class name. cmt_insert_class_header = "" # string # Path to a file that contains text to insert before an Objective-C message # specification, if the method isn't preceded by a C/C++ comment. If the # inserted text contains '$(message)' or '$(javaparam)', these will be # replaced with, respectively, the name of the function, or the javadoc # '@param' and '@return' stuff. cmt_insert_oc_msg_header = "" # string # Whether a comment should be inserted if a preprocessor is encountered when # stepping backwards from a function name. # # Applies to cmt_insert_oc_msg_header, cmt_insert_func_header and # cmt_insert_class_header. cmt_insert_before_preproc = false # true/false # Whether a comment should be inserted if a function is declared inline to a # class definition. # # Applies to cmt_insert_func_header. # # Default: true cmt_insert_before_inlines = true # true/false # Whether a comment should be inserted if the function is a class constructor # or destructor. # # Applies to cmt_insert_func_header. cmt_insert_before_ctor_dtor = false # true/false # # Code modifying options (non-whitespace) # # Add or remove braces on a single-line 'do' statement. mod_full_brace_do = remove # ignore/add/remove/force # Add or remove braces on a single-line 'for' statement. mod_full_brace_for = remove # ignore/add/remove/force # (Pawn) Add or remove braces on a single-line function definition. mod_full_brace_function = force # ignore/add/remove/force # Add or remove braces on a single-line 'if' statement. Braces will not be # removed if the braced statement contains an 'else'. mod_full_brace_if = remove # ignore/add/remove/force # Whether to enforce that all blocks of an 'if'/'else if'/'else' chain either # have, or do not have, braces. If true, braces will be added if any block # needs braces, and will only be removed if they can be removed from all # blocks. # # Overrides mod_full_brace_if. mod_full_brace_if_chain = true # true/false # Whether to add braces to all blocks of an 'if'/'else if'/'else' chain. # If true, mod_full_brace_if_chain will only remove braces from an 'if' that # does not have an 'else if' or 'else'. mod_full_brace_if_chain_only = false # true/false # Add or remove braces on single-line 'while' statement. mod_full_brace_while = remove # ignore/add/remove/force # Add or remove braces on single-line 'using ()' statement. mod_full_brace_using = ignore # ignore/add/remove/force # Don't remove braces around statements that span N newlines mod_full_brace_nl = 0 # unsigned number # Whether to prevent removal of braces from 'if'/'for'/'while'/etc. blocks # which span multiple lines. # # Affects: # mod_full_brace_for # mod_full_brace_if # mod_full_brace_if_chain # mod_full_brace_if_chain_only # mod_full_brace_while # mod_full_brace_using # # Does not affect: # mod_full_brace_do # mod_full_brace_function mod_full_brace_nl_block_rem_mlcond = false # true/false # Add or remove unnecessary parenthesis on 'return' statement. mod_paren_on_return = remove # ignore/add/remove/force # (Pawn) Whether to change optional semicolons to real semicolons. mod_pawn_semicolon = false # true/false # Whether to fully parenthesize Boolean expressions in 'while' and 'if' # statement, as in 'if (a && b > c)' → 'if (a && (b > c))'. mod_full_paren_if_bool = true # true/false # Whether to remove superfluous semicolons. mod_remove_extra_semicolon = true # true/false # If a function body exceeds the specified number of newlines and doesn't have # a comment after the close brace, a comment will be added. mod_add_long_function_closebrace_comment = 0 # unsigned number # If a namespace body exceeds the specified number of newlines and doesn't # have a comment after the close brace, a comment will be added. mod_add_long_namespace_closebrace_comment = 0 # unsigned number # If a class body exceeds the specified number of newlines and doesn't have a # comment after the close brace, a comment will be added. mod_add_long_class_closebrace_comment = 0 # unsigned number # If a switch body exceeds the specified number of newlines and doesn't have a # comment after the close brace, a comment will be added. mod_add_long_switch_closebrace_comment = 0 # unsigned number # If an #ifdef body exceeds the specified number of newlines and doesn't have # a comment after the #endif, a comment will be added. mod_add_long_ifdef_endif_comment = 0 # unsigned number # If an #ifdef or #else body exceeds the specified number of newlines and # doesn't have a comment after the #else, a comment will be added. mod_add_long_ifdef_else_comment = 0 # unsigned number # Whether to sort consecutive single-line 'import' statements. mod_sort_import = false # true/false # (C#) Whether to sort consecutive single-line 'using' statements. mod_sort_using = false # true/false # Whether to sort consecutive single-line '#include' statements (C/C++) and # '#import' statements (Objective-C). Be aware that this has the potential to # break your code if your includes/imports have ordering dependencies. mod_sort_include = false # true/false # Whether to move a 'break' that appears after a fully braced 'case' before # the close brace, as in 'case X: { ... } break;' → 'case X: { ... break; }'. mod_move_case_break = false # true/false # Add or remove braces around a fully braced case statement. Will only remove # braces if there are no variable declarations in the block. mod_case_brace = ignore # ignore/add/remove/force # Whether to remove a void 'return;' that appears as the last statement in a # function. mod_remove_empty_return = false # true/false # Add or remove the comma after the last value of an enumeration. mod_enum_last_comma = ignore # ignore/add/remove/force # (OC) Whether to organize the properties. If true, properties will be # rearranged according to the mod_sort_oc_property_*_weight factors. mod_sort_oc_properties = false # true/false # (OC) Weight of a class property modifier. mod_sort_oc_property_class_weight = 0 # number # (OC) Weight of 'atomic' and 'nonatomic'. mod_sort_oc_property_thread_safe_weight = 0 # number # (OC) Weight of 'readwrite' when organizing properties. mod_sort_oc_property_readwrite_weight = 0 # number # (OC) Weight of a reference type specifier ('retain', 'copy', 'assign', # 'weak', 'strong') when organizing properties. mod_sort_oc_property_reference_weight = 0 # number # (OC) Weight of getter type ('getter=') when organizing properties. mod_sort_oc_property_getter_weight = 0 # number # (OC) Weight of setter type ('setter=') when organizing properties. mod_sort_oc_property_setter_weight = 0 # number # (OC) Weight of nullability type ('nullable', 'nonnull', 'null_unspecified', # 'null_resettable') when organizing properties. mod_sort_oc_property_nullability_weight = 0 # number # # Preprocessor options # # Add or remove indentation of preprocessor directives inside #if blocks # at brace level 0 (file-level). pp_indent = ignore # ignore/add/remove/force # Whether to indent #if/#else/#endif at the brace level. If false, these are # indented from column 1. pp_indent_at_level = false # true/false # Specifies the number of columns to indent preprocessors per level # at brace level 0 (file-level). If pp_indent_at_level=false, also specifies # the number of columns to indent preprocessors per level # at brace level > 0 (function-level). # # Default: 1 pp_indent_count = 1 # unsigned number # Add or remove space after # based on pp_level of #if blocks. pp_space = force # ignore/add/remove/force # Sets the number of spaces per level added with pp_space. pp_space_count = 3 # unsigned number # The indent for '#region' and '#endregion' in C# and '#pragma region' in # C/C++. Negative values decrease indent down to the first column. pp_indent_region = 0 # number # Whether to indent the code between #region and #endregion. pp_region_indent_code = false # true/false # If pp_indent_at_level=true, sets the indent for #if, #else and #endif when # not at file-level. Negative values decrease indent down to the first column. # # =0: Indent preprocessors using output_tab_size # >0: Column at which all preprocessors will be indented pp_indent_if = 0 # number # Whether to indent the code between #if, #else and #endif. pp_if_indent_code = false # true/false # Whether to indent '#define' at the brace level. If false, these are # indented from column 1. pp_define_at_level = false # true/false # Whether to ignore the '#define' body while formatting. pp_ignore_define_body = false # true/false # Whether to indent case statements between #if, #else, and #endif. # Only applies to the indent of the preprocesser that the case statements # directly inside of. # # Default: true pp_indent_case = true # true/false # Whether to indent whole function definitions between #if, #else, and #endif. # Only applies to the indent of the preprocesser that the function definition # is directly inside of. # # Default: true pp_indent_func_def = true # true/false # Whether to indent extern C blocks between #if, #else, and #endif. # Only applies to the indent of the preprocesser that the extern block is # directly inside of. # # Default: true pp_indent_extern = true # true/false # Whether to indent braces directly inside #if, #else, and #endif. # Only applies to the indent of the preprocesser that the braces are directly # inside of. # # Default: true pp_indent_brace = true # true/false # # Sort includes options # # The regex for include category with priority 0. include_category_0 = "" # string # The regex for include category with priority 1. include_category_1 = "" # string # The regex for include category with priority 2. include_category_2 = "" # string # # Use or Do not Use options # # true: indent_func_call_param will be used (default) # false: indent_func_call_param will NOT be used # # Default: true use_indent_func_call_param = true # true/false # The value of the indentation for a continuation line is calculated # differently if the statement is: # - a declaration: your case with QString fileName ... # - an assignment: your case with pSettings = new QSettings( ... # # At the second case the indentation value might be used twice: # - at the assignment # - at the function call (if present) # # To prevent the double use of the indentation value, use this option with the # value 'true'. # # true: indent_continue will be used only once # false: indent_continue will be used every time (default) use_indent_continue_only_once = false # true/false # The value might be used twice: # - at the assignment # - at the opening brace # # To prevent the double use of the indentation value, use this option with the # value 'true'. # # true: indentation will be used only once # false: indentation will be used every time (default) indent_cpp_lambda_only_once = false # true/false # Whether to apply special formatting for Qt SIGNAL/SLOT macros. Essentially, # this tries to format these so that they match Qt's normalized form (i.e. the # result of QMetaObject::normalizedSignature), which can slightly improve the # performance of the QObject::connect call, rather than how they would # otherwise be formatted. # # See options_for_QT.cpp for details. # # Default: true use_options_overriding_for_qt_macros = true # true/false # # Warn levels - 1: error, 2: warning (default), 3: note # # (C#) Warning is given if doing tab-to-\t replacement and we have found one # in a C# verbatim string literal. # # Default: 2 warn_level_tabs_found_in_verbatim_string_literals = 2 # unsigned number # Meaning of the settings: # Ignore - do not do any changes # Add - makes sure there is 1 or more space/brace/newline/etc # Force - makes sure there is exactly 1 space/brace/newline/etc, # behaves like Add in some contexts # Remove - removes space/brace/newline/etc # # # - Token(s) can be treated as specific type(s) with the 'set' option: # `set tokenType tokenString [tokenString...]` # # Example: # `set BOOL __AND__ __OR__` # # tokenTypes are defined in src/token_enum.h, use them without the # 'CT_' prefix: 'CT_BOOL' → 'BOOL' # # # - Token(s) can be treated as type(s) with the 'type' option. # `type tokenString [tokenString...]` # # Example: # `type int c_uint_8 Rectangle` # # This can also be achieved with `set TYPE int c_uint_8 Rectangle` # # # To embed whitespace in tokenStrings use the '\' escape character, or quote # the tokenStrings. These quotes are supported: "'` # # # - Support for the auto detection of languages through the file ending can be # added using the 'file_ext' command. # `file_ext langType langString [langString..]` # # Example: # `file_ext CPP .ch .cxx .cpp.in` # # langTypes are defined in uncrusify_types.h in the lang_flag_e enum, use # them without the 'LANG_' prefix: 'LANG_CPP' → 'CPP' # # # - Custom macro-based indentation can be set up using 'macro-open', # 'macro-else' and 'macro-close'. # `(macro-open | macro-else | macro-close) tokenString` # # Example: # `macro-open BEGIN_TEMPLATE_MESSAGE_MAP` # `macro-open BEGIN_MESSAGE_MAP` # `macro-close END_MESSAGE_MAP` # # # option(s) with 'not default' value: 87 #